summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2015-10-25 00:06:51 +0300
committerRobert Mustacchi <rm@joyent.com>2016-09-22 11:43:37 -0700
commit199767f8919635c4928607450d9e0abb932109ce (patch)
treee6c3078959e4b1dc4a59d04b9fac0a2fdf2c0711
parent0cc5983c8a077e6396dc7c492ee928b40bf0fed1 (diff)
downloadillumos-joyent-199767f8919635c4928607450d9e0abb932109ce.tar.gz
5061 freebsd boot loader integration (loader project)
Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Cody Mello <melloc@joyent.com> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--exception_lists/copyright1
-rw-r--r--exception_lists/cstyle1
-rw-r--r--exception_lists/hdrchk1
-rw-r--r--exception_lists/keywords1
-rw-r--r--exception_lists/manlint14
-rw-r--r--exception_lists/mapfilechk2
-rw-r--r--usr/src/Makefile3
-rw-r--r--usr/src/boot/COPYRIGHT126
-rw-r--r--usr/src/boot/COPYRIGHT.descrip1
-rw-r--r--usr/src/boot/Makefile32
-rw-r--r--usr/src/boot/Readme.txt60
-rw-r--r--usr/src/boot/contrib/bzip2/CHANGES327
-rw-r--r--usr/src/boot/contrib/bzip2/FREEBSD-Xlist26
-rw-r--r--usr/src/boot/contrib/bzip2/FREEBSD-upgrade27
-rw-r--r--usr/src/boot/contrib/bzip2/FREEBSD-vendor5
-rw-r--r--usr/src/boot/contrib/bzip2/LICENSE42
-rw-r--r--usr/src/boot/contrib/bzip2/README215
-rw-r--r--usr/src/boot/contrib/bzip2/README.COMPILATION.PROBLEMS58
-rw-r--r--usr/src/boot/contrib/bzip2/blocksort.c1094
-rw-r--r--usr/src/boot/contrib/bzip2/bzip2.1453
-rw-r--r--usr/src/boot/contrib/bzip2/bzip2.c2034
-rw-r--r--usr/src/boot/contrib/bzip2/bzip2recover.c514
-rw-r--r--usr/src/boot/contrib/bzip2/bzlib.c1581
-rw-r--r--usr/src/boot/contrib/bzip2/bzlib.h282
-rw-r--r--usr/src/boot/contrib/bzip2/bzlib_private.h509
-rw-r--r--usr/src/boot/contrib/bzip2/compress.c672
-rw-r--r--usr/src/boot/contrib/bzip2/crctable.c104
-rw-r--r--usr/src/boot/contrib/bzip2/decompress.c646
-rw-r--r--usr/src/boot/contrib/bzip2/huffman.c205
-rw-r--r--usr/src/boot/contrib/bzip2/libbz2.def27
-rw-r--r--usr/src/boot/contrib/bzip2/randtable.c84
-rw-r--r--usr/src/boot/contrib/bzip2/sample1.bz2.uu722
-rw-r--r--usr/src/boot/contrib/bzip2/sample1.ref.gz.uu850
-rw-r--r--usr/src/boot/contrib/bzip2/sample2.bz2.uu1642
-rw-r--r--usr/src/boot/contrib/bzip2/sample2.ref.gz.uu1934
-rw-r--r--usr/src/boot/contrib/bzip2/sample3.bz2.uu9
-rw-r--r--usr/src/boot/contrib/bzip2/sample3.ref.gz.uu11
-rw-r--r--usr/src/boot/contrib/bzip2/spewG.c54
-rw-r--r--usr/src/boot/contrib/bzip2/unzcrash.c141
-rw-r--r--usr/src/boot/contrib/bzip2/words09
-rw-r--r--usr/src/boot/contrib/bzip2/words14
-rw-r--r--usr/src/boot/contrib/bzip2/words25
-rw-r--r--usr/src/boot/contrib/bzip2/words330
-rw-r--r--usr/src/boot/include/_ctype.h187
-rw-r--r--usr/src/boot/include/a.out.h45
-rw-r--r--usr/src/boot/include/arpa/inet.h178
-rw-r--r--usr/src/boot/include/arpa/tftp.h81
-rw-r--r--usr/src/boot/include/assert.h78
-rw-r--r--usr/src/boot/include/bitstring.h35
-rw-r--r--usr/src/boot/include/bzlib.h282
-rw-r--r--usr/src/boot/include/ctype.h135
-rw-r--r--usr/src/boot/include/dev/ic/ns16550.h240
-rw-r--r--usr/src/boot/include/dev/pci/pcireg.h945
-rw-r--r--usr/src/boot/include/elf.h41
-rw-r--r--usr/src/boot/include/errno.h3
-rw-r--r--usr/src/boot/include/inttypes.h62
-rw-r--r--usr/src/boot/include/isofs/cd9660/cd9660_rrip.h137
-rw-r--r--usr/src/boot/include/isofs/cd9660/iso.h359
-rw-r--r--usr/src/boot/include/limits.h147
-rw-r--r--usr/src/boot/include/link.h33
-rw-r--r--usr/src/boot/include/math.h507
-rw-r--r--usr/src/boot/include/net/ethernet.h424
-rw-r--r--usr/src/boot/include/net/if.h548
-rw-r--r--usr/src/boot/include/net/if_arp.h133
-rw-r--r--usr/src/boot/include/netinet/if_ether.h125
-rw-r--r--usr/src/boot/include/netinet/in.h669
-rw-r--r--usr/src/boot/include/netinet/in_pcb.h733
-rw-r--r--usr/src/boot/include/netinet/in_systm.h61
-rw-r--r--usr/src/boot/include/netinet/ip.h222
-rw-r--r--usr/src/boot/include/netinet/ip_var.h306
-rw-r--r--usr/src/boot/include/netinet/udp.h69
-rw-r--r--usr/src/boot/include/netinet/udp_var.h186
-rw-r--r--usr/src/boot/include/netinet6/in6.h733
-rw-r--r--usr/src/boot/include/nlist.h49
-rw-r--r--usr/src/boot/include/runetype.h106
-rw-r--r--usr/src/boot/include/setjmp.h62
-rw-r--r--usr/src/boot/include/stdarg.h6
-rw-r--r--usr/src/boot/include/stdbool.h43
-rw-r--r--usr/src/boot/include/stddef.h67
-rw-r--r--usr/src/boot/include/stdio.h527
-rw-r--r--usr/src/boot/include/stdlib.h329
-rw-r--r--usr/src/boot/include/string.h144
-rw-r--r--usr/src/boot/include/strings.h71
-rw-r--r--usr/src/boot/include/time.h204
-rw-r--r--usr/src/boot/include/ufs/ufs/dinode.h191
-rw-r--r--usr/src/boot/include/ufs/ufs/dir.h154
-rw-r--r--usr/src/boot/include/unistd.h592
-rw-r--r--usr/src/boot/include/uuid.h63
-rw-r--r--usr/src/boot/include/xlocale/_ctype.h203
-rw-r--r--usr/src/boot/include/xlocale/_string.h59
-rw-r--r--usr/src/boot/include/xlocale/_strings.h48
-rw-r--r--usr/src/boot/include/xlocale/_time.h58
-rw-r--r--usr/src/boot/lib/libc/net/ntoh.c60
-rw-r--r--usr/src/boot/lib/libc/string/bcmp.c55
-rw-r--r--usr/src/boot/lib/libc/string/bcopy.c137
-rw-r--r--usr/src/boot/lib/libc/string/bzero.c5
-rw-r--r--usr/src/boot/lib/libc/string/ffs.c51
-rw-r--r--usr/src/boot/lib/libc/string/fls.c48
-rw-r--r--usr/src/boot/lib/libc/string/memccpy.c52
-rw-r--r--usr/src/boot/lib/libc/string/memchr.c53
-rw-r--r--usr/src/boot/lib/libc/string/memcmp.c56
-rw-r--r--usr/src/boot/lib/libc/string/memcpy.c5
-rw-r--r--usr/src/boot/lib/libc/string/memmove.c5
-rw-r--r--usr/src/boot/lib/libc/string/memset.c128
-rw-r--r--usr/src/boot/lib/libc/string/strcat.c46
-rw-r--r--usr/src/boot/lib/libc/string/strchr.c54
-rw-r--r--usr/src/boot/lib/libc/string/strcmp.c51
-rw-r--r--usr/src/boot/lib/libc/string/strcpy.c45
-rw-r--r--usr/src/boot/lib/libc/string/strcspn.c72
-rw-r--r--usr/src/boot/lib/libc/string/strlcat.c58
-rw-r--r--usr/src/boot/lib/libc/string/strlcpy.c53
-rw-r--r--usr/src/boot/lib/libc/string/strlen.c130
-rw-r--r--usr/src/boot/lib/libc/string/strncat.c62
-rw-r--r--usr/src/boot/lib/libc/string/strncmp.c52
-rw-r--r--usr/src/boot/lib/libc/string/strncpy.c62
-rw-r--r--usr/src/boot/lib/libc/string/strpbrk.c53
-rw-r--r--usr/src/boot/lib/libc/string/strrchr.c55
-rw-r--r--usr/src/boot/lib/libc/string/strsep.c75
-rw-r--r--usr/src/boot/lib/libc/string/strspn.c71
-rw-r--r--usr/src/boot/lib/libc/string/strstr.c61
-rw-r--r--usr/src/boot/lib/libc/string/strtok.c136
-rw-r--r--usr/src/boot/lib/libc/string/swab.c61
-rw-r--r--usr/src/boot/lib/libc/uuid/uuid_create_nil.c46
-rw-r--r--usr/src/boot/lib/libc/uuid/uuid_equal.c55
-rw-r--r--usr/src/boot/lib/libc/uuid/uuid_is_nil.c54
-rw-r--r--usr/src/boot/lib/libstand/Makefile.inc197
-rw-r--r--usr/src/boot/lib/libstand/__main.c43
-rw-r--r--usr/src/boot/lib/libstand/amd64/_setjmp.S93
-rw-r--r--usr/src/boot/lib/libstand/arp.c309
-rw-r--r--usr/src/boot/lib/libstand/assert.c44
-rw-r--r--usr/src/boot/lib/libstand/bcd.c38
-rw-r--r--usr/src/boot/lib/libstand/bootp.c749
-rw-r--r--usr/src/boot/lib/libstand/bootp.h145
-rw-r--r--usr/src/boot/lib/libstand/bootparam.c452
-rw-r--r--usr/src/boot/lib/libstand/bootparam.h5
-rw-r--r--usr/src/boot/lib/libstand/bswap.c57
-rw-r--r--usr/src/boot/lib/libstand/bzipfs.c390
-rw-r--r--usr/src/boot/lib/libstand/cd9660.c594
-rw-r--r--usr/src/boot/lib/libstand/close.c98
-rw-r--r--usr/src/boot/lib/libstand/closeall.c76
-rw-r--r--usr/src/boot/lib/libstand/dev.c61
-rw-r--r--usr/src/boot/lib/libstand/dosfs.c864
-rw-r--r--usr/src/boot/lib/libstand/dosfs.h121
-rw-r--r--usr/src/boot/lib/libstand/environment.c223
-rw-r--r--usr/src/boot/lib/libstand/ether.c150
-rw-r--r--usr/src/boot/lib/libstand/ext2fs.c908
-rw-r--r--usr/src/boot/lib/libstand/fstat.c61
-rw-r--r--usr/src/boot/lib/libstand/getopt.c108
-rw-r--r--usr/src/boot/lib/libstand/gets.c112
-rw-r--r--usr/src/boot/lib/libstand/globals.c36
-rw-r--r--usr/src/boot/lib/libstand/gzipfs.c352
-rw-r--r--usr/src/boot/lib/libstand/i386/_setjmp.S77
-rw-r--r--usr/src/boot/lib/libstand/in_cksum.c94
-rw-r--r--usr/src/boot/lib/libstand/inet_ntoa.c64
-rw-r--r--usr/src/boot/lib/libstand/ioctl.c88
-rw-r--r--usr/src/boot/lib/libstand/iodesc.h52
-rw-r--r--usr/src/boot/lib/libstand/libstand.3676
-rw-r--r--usr/src/boot/lib/libstand/lseek.c142
-rw-r--r--usr/src/boot/lib/libstand/mips/_setjmp.S108
-rw-r--r--usr/src/boot/lib/libstand/nandfs.c1061
-rw-r--r--usr/src/boot/lib/libstand/net.c283
-rw-r--r--usr/src/boot/lib/libstand/net.h121
-rw-r--r--usr/src/boot/lib/libstand/netif.c335
-rw-r--r--usr/src/boot/lib/libstand/netif.h67
-rw-r--r--usr/src/boot/lib/libstand/nfs.c1474
-rw-r--r--usr/src/boot/lib/libstand/nfsv2.h164
-rw-r--r--usr/src/boot/lib/libstand/nullfs.c105
-rw-r--r--usr/src/boot/lib/libstand/open.c159
-rw-r--r--usr/src/boot/lib/libstand/pager.c161
-rw-r--r--usr/src/boot/lib/libstand/pkgfs.c791
-rw-r--r--usr/src/boot/lib/libstand/powerpc/_setjmp.S115
-rw-r--r--usr/src/boot/lib/libstand/powerpc/syncicache.c103
-rw-r--r--usr/src/boot/lib/libstand/printf.c526
-rw-r--r--usr/src/boot/lib/libstand/qdivrem.c348
-rw-r--r--usr/src/boot/lib/libstand/quad.h114
-rw-r--r--usr/src/boot/lib/libstand/random.c70
-rw-r--r--usr/src/boot/lib/libstand/rarp.c225
-rw-r--r--usr/src/boot/lib/libstand/read.c127
-rw-r--r--usr/src/boot/lib/libstand/readdir.c51
-rw-r--r--usr/src/boot/lib/libstand/rpc.c438
-rw-r--r--usr/src/boot/lib/libstand/rpc.h66
-rw-r--r--usr/src/boot/lib/libstand/rpcv2.h87
-rw-r--r--usr/src/boot/lib/libstand/saioctl.h50
-rw-r--r--usr/src/boot/lib/libstand/sbrk.c64
-rw-r--r--usr/src/boot/lib/libstand/sparc64/_setjmp.S94
-rw-r--r--usr/src/boot/lib/libstand/splitfs.c313
-rw-r--r--usr/src/boot/lib/libstand/stand.h429
-rw-r--r--usr/src/boot/lib/libstand/stat.c52
-rw-r--r--usr/src/boot/lib/libstand/strcasecmp.c73
-rw-r--r--usr/src/boot/lib/libstand/strdup.c55
-rw-r--r--usr/src/boot/lib/libstand/strerror.c87
-rw-r--r--usr/src/boot/lib/libstand/strtol.c132
-rw-r--r--usr/src/boot/lib/libstand/strtoul.c121
-rw-r--r--usr/src/boot/lib/libstand/tftp.c763
-rw-r--r--usr/src/boot/lib/libstand/tftp.h36
-rw-r--r--usr/src/boot/lib/libstand/twiddle.c69
-rw-r--r--usr/src/boot/lib/libstand/udp.c272
-rw-r--r--usr/src/boot/lib/libstand/ufs.c857
-rw-r--r--usr/src/boot/lib/libstand/uuid_from_string.c132
-rw-r--r--usr/src/boot/lib/libstand/uuid_to_string.c111
-rw-r--r--usr/src/boot/lib/libstand/write.c95
-rw-r--r--usr/src/boot/lib/libstand/zalloc.c316
-rw-r--r--usr/src/boot/lib/libstand/zalloc_defs.h78
-rw-r--r--usr/src/boot/lib/libstand/zalloc_malloc.c200
-rw-r--r--usr/src/boot/lib/libstand/zalloc_mem.h53
-rw-r--r--usr/src/boot/lib/libstand/zalloc_protos.h35
-rw-r--r--usr/src/boot/lib/libz/ChangeLog1472
-rw-r--r--usr/src/boot/lib/libz/FAQ368
-rw-r--r--usr/src/boot/lib/libz/FREEBSD-upgrade44
-rw-r--r--usr/src/boot/lib/libz/Makefile78
-rw-r--r--usr/src/boot/lib/libz/README115
-rw-r--r--usr/src/boot/lib/libz/Symbol.map108
-rw-r--r--usr/src/boot/lib/libz/Versions.def17
-rw-r--r--usr/src/boot/lib/libz/adler32.c179
-rw-r--r--usr/src/boot/lib/libz/compress.c80
-rw-r--r--usr/src/boot/lib/libz/contrib/README.contrib78
-rw-r--r--usr/src/boot/lib/libz/contrib/asm686/README.68651
-rw-r--r--usr/src/boot/lib/libz/contrib/asm686/match.S357
-rw-r--r--usr/src/boot/lib/libz/contrib/gcc_gvmat64/gvmat64.S574
-rw-r--r--usr/src/boot/lib/libz/crc32.c425
-rw-r--r--usr/src/boot/lib/libz/crc32.h441
-rw-r--r--usr/src/boot/lib/libz/deflate.c1967
-rw-r--r--usr/src/boot/lib/libz/deflate.h346
-rw-r--r--usr/src/boot/lib/libz/doc/algorithm.txt209
-rw-r--r--usr/src/boot/lib/libz/doc/rfc1950.txt619
-rw-r--r--usr/src/boot/lib/libz/doc/rfc1951.txt955
-rw-r--r--usr/src/boot/lib/libz/doc/rfc1952.txt675
-rw-r--r--usr/src/boot/lib/libz/doc/txtvsbin.txt107
-rw-r--r--usr/src/boot/lib/libz/gzclose.c25
-rw-r--r--usr/src/boot/lib/libz/gzguts.h209
-rw-r--r--usr/src/boot/lib/libz/gzlib.c637
-rw-r--r--usr/src/boot/lib/libz/gzread.c597
-rw-r--r--usr/src/boot/lib/libz/gzwrite.c580
-rw-r--r--usr/src/boot/lib/libz/infback.c640
-rw-r--r--usr/src/boot/lib/libz/inffast.c340
-rw-r--r--usr/src/boot/lib/libz/inffast.h11
-rw-r--r--usr/src/boot/lib/libz/inffixed.h94
-rw-r--r--usr/src/boot/lib/libz/inflate.c1512
-rw-r--r--usr/src/boot/lib/libz/inflate.h122
-rw-r--r--usr/src/boot/lib/libz/inftrees.c306
-rw-r--r--usr/src/boot/lib/libz/inftrees.h62
-rw-r--r--usr/src/boot/lib/libz/test/example.c601
-rw-r--r--usr/src/boot/lib/libz/test/infcover.c671
-rw-r--r--usr/src/boot/lib/libz/test/minigzip.c651
-rw-r--r--usr/src/boot/lib/libz/trees.c1226
-rw-r--r--usr/src/boot/lib/libz/trees.h128
-rw-r--r--usr/src/boot/lib/libz/uncompr.c59
-rw-r--r--usr/src/boot/lib/libz/zconf.h519
-rw-r--r--usr/src/boot/lib/libz/zlib.3151
-rw-r--r--usr/src/boot/lib/libz/zlib.h1768
-rw-r--r--usr/src/boot/lib/libz/zlib.pc14
-rw-r--r--usr/src/boot/lib/libz/zopen.396
-rw-r--r--usr/src/boot/lib/libz/zopen.c49
-rw-r--r--usr/src/boot/lib/libz/zutil.c324
-rw-r--r--usr/src/boot/lib/libz/zutil.h253
-rw-r--r--usr/src/boot/sys/amd64/include/_align.h6
-rw-r--r--usr/src/boot/sys/amd64/include/_inttypes.h6
-rw-r--r--usr/src/boot/sys/amd64/include/_limits.h6
-rw-r--r--usr/src/boot/sys/amd64/include/_stdint.h6
-rw-r--r--usr/src/boot/sys/amd64/include/_types.h6
-rw-r--r--usr/src/boot/sys/amd64/include/asm.h99
-rw-r--r--usr/src/boot/sys/amd64/include/asmacros.h240
-rw-r--r--usr/src/boot/sys/amd64/include/cpufunc.h871
-rw-r--r--usr/src/boot/sys/amd64/include/elf.h6
-rw-r--r--usr/src/boot/sys/amd64/include/endian.h6
-rw-r--r--usr/src/boot/sys/amd64/include/exec.h38
-rw-r--r--usr/src/boot/sys/amd64/include/metadata.h6
-rw-r--r--usr/src/boot/sys/amd64/include/param.h155
-rw-r--r--usr/src/boot/sys/amd64/include/pc/bios.h121
-rw-r--r--usr/src/boot/sys/amd64/include/psl.h6
-rw-r--r--usr/src/boot/sys/amd64/include/setjmp.h6
-rw-r--r--usr/src/boot/sys/amd64/include/signal.h6
-rw-r--r--usr/src/boot/sys/amd64/include/specialreg.h6
-rw-r--r--usr/src/boot/sys/amd64/include/stdarg.h6
-rw-r--r--usr/src/boot/sys/amd64/include/trap.h6
-rw-r--r--usr/src/boot/sys/boot/Makefile35
-rw-r--r--usr/src/boot/sys/boot/Makefile.amd6412
-rw-r--r--usr/src/boot/sys/boot/Makefile.arm7
-rw-r--r--usr/src/boot/sys/boot/Makefile.arm647
-rw-r--r--usr/src/boot/sys/boot/Makefile.i3865
-rw-r--r--usr/src/boot/sys/boot/Makefile.inc11
-rw-r--r--usr/src/boot/sys/boot/Makefile.sparc644
-rw-r--r--usr/src/boot/sys/boot/README238
-rw-r--r--usr/src/boot/sys/boot/arm/Makefile5
-rw-r--r--usr/src/boot/sys/boot/arm/Makefile.inc3
-rw-r--r--usr/src/boot/sys/boot/arm/at91/Makefile5
-rw-r--r--usr/src/boot/sys/boot/arm/at91/Makefile.inc57
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0/Makefile14
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0/README7
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0/linker.cfg84
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0/main.c45
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0iic/Makefile14
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0iic/main.c52
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0spi/Makefile14
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot0spi/main.c65
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/Makefile22
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/board.h29
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/boot2.c361
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/bwct_board.c125
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/centipad_board.c68
-rw-r--r--usr/src/boot/sys/boot/arm/at91/boot2/kb920x_board.c66
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/Makefile14
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/README35
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.c207
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.h54
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.c387
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.h55
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootiic/main.c55
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/Makefile19
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/README34
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/ee.c160
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/ee.h6
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.c130
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.h54
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.c363
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.h62
-rw-r--r--usr/src/boot/sys/boot/arm/at91/bootspi/main.c65
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/Makefile22
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/arm_init.S129
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200.h2411
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c223
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h74
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/delay.c43
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/eeprom.c185
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/emac.c575
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/emac.h135
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/emac_init.c117
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/getc.c64
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/lib.h65
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/lib_AT91RM9200.h277
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/mci_device.h434
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/memcmp.c38
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/memcpy.c39
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/memset.c36
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/p_string.c57
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/printf.c70
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/putchar.c62
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/reset.c57
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/sd-card.c517
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/sd-card.h64
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.c267
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.h58
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/strcmp.c36
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/strcpy.c38
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/strcvt.c132
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/strlen.c68
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/tag_list.c81
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/tag_list.h28
-rw-r--r--usr/src/boot/sys/boot/arm/at91/libat91/xmodem.c128
-rw-r--r--usr/src/boot/sys/boot/arm/at91/linker.cfg56
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/Makefile.inc42
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/Makefile78
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/arm_init.S58
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/boot2.c446
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/cf_ata.h62
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/ixp425_board.c771
-rw-r--r--usr/src/boot/sys/boot/arm/ixp425/boot2/lib.h67
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/Makefile159
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/conf.c94
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/help.uboot27
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/ldscript.arm133
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/loader.conf13
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/start.S130
-rw-r--r--usr/src/boot/sys/boot/arm/uboot/version9
-rw-r--r--usr/src/boot/sys/boot/arm64/Makefile3
-rw-r--r--usr/src/boot/sys/boot/arm64/libarm64/cache.c95
-rw-r--r--usr/src/boot/sys/boot/arm64/libarm64/cache.h38
-rw-r--r--usr/src/boot/sys/boot/common/Makefile10
-rw-r--r--usr/src/boot/sys/boot/common/Makefile.inc72
-rw-r--r--usr/src/boot/sys/boot/common/bcache.c470
-rw-r--r--usr/src/boot/sys/boot/common/boot.c398
-rw-r--r--usr/src/boot/sys/boot/common/bootstrap.h336
-rw-r--r--usr/src/boot/sys/boot/common/commands.c525
-rw-r--r--usr/src/boot/sys/boot/common/console.c315
-rw-r--r--usr/src/boot/sys/boot/common/crc32.c108
-rw-r--r--usr/src/boot/sys/boot/common/crc32.h13
-rw-r--r--usr/src/boot/sys/boot/common/dev_net.c380
-rw-r--r--usr/src/boot/sys/boot/common/dev_net.h36
-rw-r--r--usr/src/boot/sys/boot/common/devopen.c67
-rw-r--r--usr/src/boot/sys/boot/common/disk.c534
-rw-r--r--usr/src/boot/sys/boot/common/disk.h122
-rw-r--r--usr/src/boot/sys/boot/common/gpt.c381
-rw-r--r--usr/src/boot/sys/boot/common/gpt.h39
-rw-r--r--usr/src/boot/sys/boot/common/help.common434
-rw-r--r--usr/src/boot/sys/boot/common/install.c339
-rw-r--r--usr/src/boot/sys/boot/common/interp.c310
-rw-r--r--usr/src/boot/sys/boot/common/interp_backslash.c167
-rw-r--r--usr/src/boot/sys/boot/common/interp_forth.c370
-rw-r--r--usr/src/boot/sys/boot/common/interp_parse.c224
-rw-r--r--usr/src/boot/sys/boot/common/isapnp.c313
-rw-r--r--usr/src/boot/sys/boot/common/isapnp.h313
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/LICENSE25
-rw-r--r--usr/src/boot/sys/boot/common/linenoise/LICENSE.descrip1
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/Makefile7
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/README.markdown52
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/example.c64
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/linenoise.c854
-rwxr-xr-xusr/src/boot/sys/boot/common/linenoise/linenoise.h68
-rw-r--r--usr/src/boot/sys/boot/common/load_elf.c1090
-rw-r--r--usr/src/boot/sys/boot/common/load_elf32.c7
-rw-r--r--usr/src/boot/sys/boot/common/load_elf32_obj.c7
-rw-r--r--usr/src/boot/sys/boot/common/load_elf64.c6
-rw-r--r--usr/src/boot/sys/boot/common/load_elf64_obj.c6
-rw-r--r--usr/src/boot/sys/boot/common/load_elf_obj.c535
-rw-r--r--usr/src/boot/sys/boot/common/loader.81097
-rw-r--r--usr/src/boot/sys/boot/common/ls.c204
-rw-r--r--usr/src/boot/sys/boot/common/md.c151
-rw-r--r--usr/src/boot/sys/boot/common/merge_help.awk104
-rw-r--r--usr/src/boot/sys/boot/common/misc.c219
-rw-r--r--usr/src/boot/sys/boot/common/module.c1072
-rwxr-xr-xusr/src/boot/sys/boot/common/newvers.sh47
-rw-r--r--usr/src/boot/sys/boot/common/panic.c59
-rw-r--r--usr/src/boot/sys/boot/common/part.c983
-rw-r--r--usr/src/boot/sys/boot/common/part.h95
-rw-r--r--usr/src/boot/sys/boot/common/paths.h39
-rw-r--r--usr/src/boot/sys/boot/common/pnp.c184
-rw-r--r--usr/src/boot/sys/boot/common/rbx.h61
-rw-r--r--usr/src/boot/sys/boot/common/reloc_elf.c231
-rw-r--r--usr/src/boot/sys/boot/common/reloc_elf32.c6
-rw-r--r--usr/src/boot/sys/boot/common/reloc_elf64.c6
-rw-r--r--usr/src/boot/sys/boot/common/self_reloc.c125
-rw-r--r--usr/src/boot/sys/boot/common/ufsread.c366
-rw-r--r--usr/src/boot/sys/boot/common/util.c177
-rw-r--r--usr/src/boot/sys/boot/common/util.h53
-rw-r--r--usr/src/boot/sys/boot/common/zfsloader.8106
-rw-r--r--usr/src/boot/sys/boot/efi/Makefile39
-rw-r--r--usr/src/boot/sys/boot/efi/Makefile.inc31
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/Makefile126
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/boot1.c748
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/boot_module.h114
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/ufs_module.c180
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/zfs_module.c196
-rw-r--r--usr/src/boot/sys/boot/efi/fdt/Makefile37
-rw-r--r--usr/src/boot/sys/boot/efi/fdt/efi_fdt.c62
-rw-r--r--usr/src/boot/sys/boot/efi/include/README36
-rw-r--r--usr/src/boot/sys/boot/efi/include/amd64/efibind.h268
-rw-r--r--usr/src/boot/sys/boot/efi/include/amd64/pe.h591
-rw-r--r--usr/src/boot/sys/boot/efi/include/arm/efibind.h165
-rw-r--r--usr/src/boot/sys/boot/efi/include/arm64/efibind.h217
-rw-r--r--usr/src/boot/sys/boot/efi/include/efi.h70
-rw-r--r--usr/src/boot/sys/boot/efi/include/efi_nii.h86
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiapi.h1204
-rw-r--r--usr/src/boot/sys/boot/efi/include/eficon.h313
-rw-r--r--usr/src/boot/sys/boot/efi/include/eficonsctl.h134
-rw-r--r--usr/src/boot/sys/boot/efi/include/efidebug.h118
-rw-r--r--usr/src/boot/sys/boot/efi/include/efidef.h218
-rw-r--r--usr/src/boot/sys/boot/efi/include/efidevp.h428
-rw-r--r--usr/src/boot/sys/boot/efi/include/efierr.h68
-rw-r--r--usr/src/boot/sys/boot/efi/include/efifpswa.h40
-rw-r--r--usr/src/boot/sys/boot/efi/include/efifs.h123
-rw-r--r--usr/src/boot/sys/boot/efi/include/efigop.h121
-rw-r--r--usr/src/boot/sys/boot/efi/include/efigpt.h68
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiip.h459
-rw-r--r--usr/src/boot/sys/boot/efi/include/efilib.h51
-rw-r--r--usr/src/boot/sys/boot/efi/include/efinet.h348
-rw-r--r--usr/src/boot/sys/boot/efi/include/efipart.h69
-rw-r--r--usr/src/boot/sys/boot/efi/include/efipciio.h560
-rw-r--r--usr/src/boot/sys/boot/efi/include/efipoint.h115
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiprot.h558
-rw-r--r--usr/src/boot/sys/boot/efi/include/efipxebc.h472
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiser.h139
-rw-r--r--usr/src/boot/sys/boot/efi/include/efistdarg.h39
-rw-r--r--usr/src/boot/sys/boot/efi/include/efitcp.h391
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiudp.h272
-rw-r--r--usr/src/boot/sys/boot/efi/include/efiuga.h168
-rw-r--r--usr/src/boot/sys/boot/efi/include/i386/efibind.h267
-rw-r--r--usr/src/boot/sys/boot/efi/include/i386/pe.h630
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/Makefile68
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/delay.c49
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efi_console.c589
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efinet.c340
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efipart.c372
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/errno.c94
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/handles.c118
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/libefi.c200
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/time.c224
-rw-r--r--usr/src/boot/sys/boot/efi/loader/Makefile154
-rw-r--r--usr/src/boot/sys/boot/efi/loader/Makefile.common36
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/Makefile.inc21
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/amd64_tramp.S64
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c188
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.c568
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.h36
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/ldscript.amd6466
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/amd64/start.S76
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm/Makefile.inc6
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm/exec.c100
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm/ldscript.arm62
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm/start.S189
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm64/Makefile.inc24
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm64/exec.c141
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm64/ldscript.arm6480
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/arm64/start.S165
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/Makefile.inc13
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/bootinfo.c275
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/efimd.c139
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/elf32_freebsd.c93
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/exec.c49
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/i386_copy.c59
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/ldscript.i38672
-rw-r--r--usr/src/boot/sys/boot/efi/loader/arch/i386/start.S68
-rw-r--r--usr/src/boot/sys/boot/efi/loader/autoload.c37
-rw-r--r--usr/src/boot/sys/boot/efi/loader/bootinfo.c463
-rw-r--r--usr/src/boot/sys/boot/efi/loader/conf.c87
-rw-r--r--usr/src/boot/sys/boot/efi/loader/copy.c141
-rw-r--r--usr/src/boot/sys/boot/efi/loader/devicename.c198
-rw-r--r--usr/src/boot/sys/boot/efi/loader/loader_efi.h51
-rw-r--r--usr/src/boot/sys/boot/efi/loader/main.c1050
-rw-r--r--usr/src/boot/sys/boot/efi/loader/reloc.c128
-rw-r--r--usr/src/boot/sys/boot/efi/loader/version7
-rw-r--r--usr/src/boot/sys/boot/fdt/Makefile30
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/Makefile5
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/Makefile.inc10
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/Makefile7
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/am335x-evm.dts29
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/am335x.dtsi349
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/annapurna-alpine.dts244
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/apalis-imx6.dts102
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/armada-380.dtsi154
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/armada-385.dtsi81
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/armada-388-gp.dts393
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/armada-388.dtsi72
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/armada-38x.dtsi630
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/bananapi.dts93
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/bcm2835.dtsi497
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/bcm2836.dtsi479
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-black.dts83
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-common.dtsi45
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/beaglebone.dts30
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/cubieboard.dts81
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/cubieboard2.dts50
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/db78100.dts331
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/db78460.dts323
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/db88f5182.dts223
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/db88f5281.dts227
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/db88f6281.dts298
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/digi-ccwmx53.dts153
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/dockstar.dts240
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001.dts319
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001N.dts340
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/ea3250.dts270
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/efikamx.dts128
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5.dtsi337
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-arndale.dts57
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-snow.dts82
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-spring.dts78
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5250.dtsi79
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-arndale-octa.dts70
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-peach-pit.dts87
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/exynos5420.dtsi112
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/hl201.dts44
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/imx51x.dtsi622
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/imx53-qsb.dts134
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/imx53x.dtsi714
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/imx6.dtsi464
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/meson3.dtsi77
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/meson8b.dtsi79
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/odroidc1.dts396
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts40
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/olinuxino-lime.dts40
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-common.dtsi53
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-es.dts31
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/pandaboard.dts31
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts63
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa.dts63
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/rk3188.dtsi254
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/rpi.dts395
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/rpi2.dts406
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/sam9260ek.dts37
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/sheevaplug.dts252
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts177
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit.dts90
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/socfpga.dtsi200
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/sun4i-a10.dtsi153
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20-hdmi.dtsi48
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20.dtsi217
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/tegra20-paz00.dts58
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/tegra20.dtsi74
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/trimslice.dts143
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/ts7800.dts161
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/versatilepb.dts118
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/vsatv102-m6.dts309
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/vybrid-colibri-vf50.dts82
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/vybrid-cosmic.dts86
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/vybrid-quartz.dts115
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/vybrid.dtsi497
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/wandboard-dual.dts83
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/wandboard-quad.dts83
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/wandboard-solo.dts83
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/yyhd18-m3.dts237
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/zedboard.dts217
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/arm/zybo.dts216
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/bindings-gpio.txt101
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/bindings-localbus.txt83
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/bindings-mpp.txt50
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/Makefile7
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/beri-netfpga.dts158
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/beri-sim.dts156
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/beripad-de4.dts258
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/beripad-sockit.dts219
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/mips/xlp-basic.dts80
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/Makefile7
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8555cds.dts443
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8572ds.dts895
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p1020rdb.dts627
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p2020ds.dts754
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p2041rdb.dts490
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p2041si.dtsi1296
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p3041ds.dts587
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p3041si.dtsi1339
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p5020ds.dts583
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/powerpc/p5020si.dtsi1389
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/riscv/qemu.dts92
-rw-r--r--usr/src/boot/sys/boot/fdt/dts/riscv/spike.dts109
-rw-r--r--usr/src/boot/sys/boot/fdt/fdt_loader_cmd.c1589
-rw-r--r--usr/src/boot/sys/boot/fdt/fdt_platform.h54
-rw-r--r--usr/src/boot/sys/boot/fdt/help.fdt93
-rw-r--r--usr/src/boot/sys/boot/ficl/Makefile31
-rw-r--r--usr/src/boot/sys/boot/ficl/Makefile.inc66
-rw-r--r--usr/src/boot/sys/boot/ficl/amd64/Makefile26
-rw-r--r--usr/src/boot/sys/boot/ficl/ficllocal.h11
-rw-r--r--usr/src/boot/sys/boot/ficl/i386/Makefile27
-rw-r--r--usr/src/boot/sys/boot/ficl/softcore/Makefile46
-rw-r--r--usr/src/boot/sys/boot/forth/Makefile14
-rw-r--r--usr/src/boot/sys/boot/forth/Makefile.inc25
-rw-r--r--usr/src/boot/sys/boot/forth/beadm.4th428
-rw-r--r--usr/src/boot/sys/boot/forth/beastie.4th110
-rw-r--r--usr/src/boot/sys/boot/forth/beastie.4th.8173
-rw-r--r--usr/src/boot/sys/boot/forth/brand-fbsd.4th46
-rw-r--r--usr/src/boot/sys/boot/forth/brand-illumos.4th44
-rw-r--r--usr/src/boot/sys/boot/forth/brand.4th74
-rw-r--r--usr/src/boot/sys/boot/forth/brand.4th.8125
-rw-r--r--usr/src/boot/sys/boot/forth/check-password.4th179
-rw-r--r--usr/src/boot/sys/boot/forth/check-password.4th.8167
-rw-r--r--usr/src/boot/sys/boot/forth/color.4th49
-rw-r--r--usr/src/boot/sys/boot/forth/color.4th.8116
-rw-r--r--usr/src/boot/sys/boot/forth/delay.4th119
-rw-r--r--usr/src/boot/sys/boot/forth/delay.4th.8126
-rw-r--r--usr/src/boot/sys/boot/forth/frames.4th165
-rw-r--r--usr/src/boot/sys/boot/forth/loader.4th621
-rw-r--r--usr/src/boot/sys/boot/forth/loader.4th.8233
-rw-r--r--usr/src/boot/sys/boot/forth/loader.conf94
-rw-r--r--usr/src/boot/sys/boot/forth/loader.conf.5305
-rw-r--r--usr/src/boot/sys/boot/forth/loader.rc20
-rw-r--r--usr/src/boot/sys/boot/forth/logo-beastie.4th61
-rw-r--r--usr/src/boot/sys/boot/forth/logo-beastiebw.4th59
-rw-r--r--usr/src/boot/sys/boot/forth/logo-fbsdbw.4th53
-rw-r--r--usr/src/boot/sys/boot/forth/logo-illumos.4th61
-rw-r--r--usr/src/boot/sys/boot/forth/logo-orb.4th55
-rw-r--r--usr/src/boot/sys/boot/forth/logo-orbbw.4th54
-rw-r--r--usr/src/boot/sys/boot/forth/menu-commands.4th611
-rw-r--r--usr/src/boot/sys/boot/forth/menu.4th1394
-rw-r--r--usr/src/boot/sys/boot/forth/menu.4th.8352
-rw-r--r--usr/src/boot/sys/boot/forth/menu.rc222
-rw-r--r--usr/src/boot/sys/boot/forth/menusets.4th630
-rw-r--r--usr/src/boot/sys/boot/forth/menusets.4th.8372
-rw-r--r--usr/src/boot/sys/boot/forth/pcibios.4th47
-rw-r--r--usr/src/boot/sys/boot/forth/pnp.4th205
-rw-r--r--usr/src/boot/sys/boot/forth/screen.4th74
-rw-r--r--usr/src/boot/sys/boot/forth/shortcuts.4th50
-rw-r--r--usr/src/boot/sys/boot/forth/support.4th1945
-rw-r--r--usr/src/boot/sys/boot/forth/version.4th96
-rw-r--r--usr/src/boot/sys/boot/forth/version.4th.8128
-rw-r--r--usr/src/boot/sys/boot/i386/Makefile39
-rw-r--r--usr/src/boot/sys/boot/i386/Makefile.inc39
-rw-r--r--usr/src/boot/sys/boot/i386/boot0/Makefile83
-rw-r--r--usr/src/boot/sys/boot/i386/boot0/boot0.S682
-rw-r--r--usr/src/boot/sys/boot/i386/boot0sio/Makefile8
-rw-r--r--usr/src/boot/sys/boot/i386/boot2/Makefile118
-rw-r--r--usr/src/boot/sys/boot/i386/btx/Makefile36
-rw-r--r--usr/src/boot/sys/boot/i386/btx/Makefile.inc3
-rw-r--r--usr/src/boot/sys/boot/i386/btx/btx/Makefile62
-rw-r--r--usr/src/boot/sys/boot/i386/btx/btx/btx.S1082
-rw-r--r--usr/src/boot/sys/boot/i386/btx/btxldr/Makefile46
-rw-r--r--usr/src/boot/sys/boot/i386/btx/btxldr/btxldr.S415
-rw-r--r--usr/src/boot/sys/boot/i386/btx/lib/Makefile45
-rw-r--r--usr/src/boot/sys/boot/i386/btx/lib/btxcsu.S49
-rw-r--r--usr/src/boot/sys/boot/i386/btx/lib/btxsys.s40
-rw-r--r--usr/src/boot/sys/boot/i386/btx/lib/btxv86.h67
-rw-r--r--usr/src/boot/sys/boot/i386/btx/lib/btxv86.s85
-rw-r--r--usr/src/boot/sys/boot/i386/cdboot/Makefile55
-rw-r--r--usr/src/boot/sys/boot/i386/cdboot/cdboot.S602
-rw-r--r--usr/src/boot/sys/boot/i386/common/bootargs.h69
-rw-r--r--usr/src/boot/sys/boot/i386/common/cons.c156
-rw-r--r--usr/src/boot/sys/boot/i386/common/cons.h35
-rw-r--r--usr/src/boot/sys/boot/i386/common/drv.c119
-rw-r--r--usr/src/boot/sys/boot/i386/common/drv.h48
-rw-r--r--usr/src/boot/sys/boot/i386/common/edd.h110
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/Makefile144
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/gptldr.S146
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/gptzfsboot.8193
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/lib.h24
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/multiboot.S39
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/sio.S84
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c699
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/Makefile30
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/dconsole.c127
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/firewire.c474
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/fwohci.c479
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/fwohci.h162
-rw-r--r--usr/src/boot/sys/boot/i386/libfirewire/fwohcireg.h369
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/Makefile112
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/amd64_tramp.S113
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biosacpi.c130
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/bioscd.c448
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biosdisk.c734
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biosmem.c244
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biospci.c428
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biospnp.c292
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biossmap.c159
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/bootinfo.c175
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/bootinfo32.c274
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/bootinfo64.c262
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/comconsole.c607
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/devicename.c206
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/elf32_freebsd.c84
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/elf64_freebsd.c126
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/i386_copy.c73
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/i386_module.c44
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/libi386.h155
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/linux.c438
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/linux.h97
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/multiboot.c706
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/multiboot.h225
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/multiboot_tramp.S51
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/nullconsole.c90
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pread.c80
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pxe.c710
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pxe.h513
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pxetramp.s38
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/relocater_tramp.S345
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/smbios.c447
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/smbios.h34
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/spinconsole.c120
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/time.c109
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vidconsole.c759
-rw-r--r--usr/src/boot/sys/boot/i386/loader/Makefile174
-rw-r--r--usr/src/boot/sys/boot/i386/loader/chain.c124
-rw-r--r--usr/src/boot/sys/boot/i386/loader/conf.c169
-rw-r--r--usr/src/boot/sys/boot/i386/loader/help.i38645
-rw-r--r--usr/src/boot/sys/boot/i386/loader/loader.rc20
-rw-r--r--usr/src/boot/sys/boot/i386/loader/main.c444
-rw-r--r--usr/src/boot/sys/boot/i386/loader/version14
-rw-r--r--usr/src/boot/sys/boot/i386/pmbr/Makefile52
-rw-r--r--usr/src/boot/sys/boot/i386/pmbr/pmbr.s188
-rw-r--r--usr/src/boot/sys/boot/i386/pxeldr/Makefile84
-rw-r--r--usr/src/boot/sys/boot/i386/pxeldr/pxeboot.8121
-rw-r--r--usr/src/boot/sys/boot/i386/pxeldr/pxeldr.S301
-rw-r--r--usr/src/boot/sys/boot/libstand/Makefile34
-rw-r--r--usr/src/boot/sys/boot/libstand/Makefile.com70
-rw-r--r--usr/src/boot/sys/boot/libstand/amd64/Makefile30
-rw-r--r--usr/src/boot/sys/boot/libstand/i386/Makefile30
-rw-r--r--usr/src/boot/sys/boot/ofw/Makefile5
-rw-r--r--usr/src/boot/sys/boot/ofw/Makefile.inc8
-rw-r--r--usr/src/boot/sys/boot/ofw/common/Makefile.inc3
-rw-r--r--usr/src/boot/sys/boot/ofw/common/main.c190
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/Makefile35
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/devicename.c147
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/elf_freebsd.c104
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/libofw.h90
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_console.c120
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_copy.c173
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_disk.c168
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_memory.c146
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_module.c49
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_net.c260
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_reboot.c37
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_time.c61
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/openfirm.c785
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/openfirm.h122
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ppc64_elf_freebsd.c110
-rw-r--r--usr/src/boot/sys/boot/sparc64/Makefile5
-rw-r--r--usr/src/boot/sys/boot/sparc64/Makefile.inc7
-rw-r--r--usr/src/boot/sys/boot/sparc64/boot1/Makefile30
-rw-r--r--usr/src/boot/sys/boot/sparc64/boot1/_start.s8
-rw-r--r--usr/src/boot/sys/boot/sparc64/boot1/boot1.c751
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/Makefile104
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/help.sparc640
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/locore.S42
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/main.c994
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/metadata.c345
-rw-r--r--usr/src/boot/sys/boot/sparc64/loader/version6
-rw-r--r--usr/src/boot/sys/boot/sparc64/zfsboot/Makefile9
-rw-r--r--usr/src/boot/sys/boot/sparc64/zfsloader/Makefile9
-rw-r--r--usr/src/boot/sys/boot/uboot/Makefile11
-rw-r--r--usr/src/boot/sys/boot/uboot/Makefile.inc8
-rw-r--r--usr/src/boot/sys/boot/uboot/common/Makefile.inc3
-rw-r--r--usr/src/boot/sys/boot/uboot/common/main.c680
-rw-r--r--usr/src/boot/sys/boot/uboot/common/metadata.c366
-rw-r--r--usr/src/boot/sys/boot/uboot/fdt/Makefile34
-rw-r--r--usr/src/boot/sys/boot/uboot/fdt/uboot_fdt.c180
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/Makefile52
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/api_public.h160
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/console.c89
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/copy.c166
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/devicename.c201
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/disk.c304
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/elf_freebsd.c100
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/glue.c529
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/glue.h106
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/libuboot.h77
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/module.c57
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/net.c362
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/reboot.c38
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/time.c65
-rw-r--r--usr/src/boot/sys/boot/usb/Makefile58
-rw-r--r--usr/src/boot/sys/boot/usb/Makefile.test61
-rw-r--r--usr/src/boot/sys/boot/usb/bsd_usbloader_test.c95
-rw-r--r--usr/src/boot/sys/boot/usb/storage/umass_common.c90
-rw-r--r--usr/src/boot/sys/boot/usb/storage/umass_common.h41
-rw-r--r--usr/src/boot/sys/boot/usb/storage/umass_loader.c222
-rw-r--r--usr/src/boot/sys/boot/usb/tools/Makefile10
-rw-r--r--usr/src/boot/sys/boot/usb/tools/sysinit.c331
-rw-r--r--usr/src/boot/sys/boot/usb/usb_busdma_loader.c619
-rw-r--r--usr/src/boot/sys/boot/usb/usbcore.mk175
-rw-r--r--usr/src/boot/sys/boot/userboot/Makefile8
-rw-r--r--usr/src/boot/sys/boot/userboot/ficl/Makefile60
-rw-r--r--usr/src/boot/sys/boot/userboot/libstand/Makefile136
-rw-r--r--usr/src/boot/sys/boot/userboot/test/Makefile15
-rw-r--r--usr/src/boot/sys/boot/userboot/test/test.c475
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot.h213
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/Makefile67
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/autoload.c35
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/biossmap.c74
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/bootinfo.c170
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/bootinfo32.c262
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/bootinfo64.c257
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/conf.c107
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/copy.c73
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/devicename.c224
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/elf32_freebsd.c114
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/elf64_freebsd.c172
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/host.c198
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/libuserboot.h68
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/main.c294
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c130
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c196
-rw-r--r--usr/src/boot/sys/boot/userboot/userboot/version4
-rw-r--r--usr/src/boot/sys/boot/userboot/zfs/Makefile18
-rw-r--r--usr/src/boot/sys/boot/zfs/Makefile34
-rw-r--r--usr/src/boot/sys/boot/zfs/Makefile.com58
-rw-r--r--usr/src/boot/sys/boot/zfs/amd64/Makefile20
-rw-r--r--usr/src/boot/sys/boot/zfs/devicename_stubs.c47
-rw-r--r--usr/src/boot/sys/boot/zfs/gzip.c66
-rw-r--r--usr/src/boot/sys/boot/zfs/i386/Makefile21
-rw-r--r--usr/src/boot/sys/boot/zfs/libzfs.h76
-rw-r--r--usr/src/boot/sys/boot/zfs/zfs.c971
-rw-r--r--usr/src/boot/sys/boot/zfs/zfsimpl.c2299
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/README16
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/blkptr.c73
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/fletcher.c96
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/lz4.c328
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/lzjb.c74
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/sha256.c325
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h1518
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/zfssubr.c1767
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/zle.c54
-rwxr-xr-xusr/src/boot/sys/contrib/dev/acpica/acpica_prep.sh92
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/changes.txt15924
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/acgetline.c440
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/adfile.c358
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/adisasm.c984
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/adwalk.c1075
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/ahids.c240
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/ahpredef.c369
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/ahtable.c150
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/ahuuids.c132
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/cmfsize.c113
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/dmextern.c1390
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/dmrestag.c1048
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/dmtable.c1518
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/dmtbdump.c3630
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/dmtbinfo.c2918
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/common/getopt.c271
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslanalyze.c618
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslascii.c370
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslbtypes.c566
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslcodegen.c606
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompile.c834
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.h1286
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.l738
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asldefine.h179
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslerror.c929
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslfileio.c400
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslfiles.c905
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslfold.c789
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslglobal.h283
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslhex.c402
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asllength.c456
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asllisting.c657
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asllistsup.c710
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslload.c925
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asllookup.c314
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmain.c424
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmap.c483
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapenter.c348
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapoutput.c642
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmaputils.c402
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.c414
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.h278
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslmethod.c726
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslnamesp.c422
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asloffset.c472
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslopcodes.c1536
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asloperands.c1199
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslopt.c806
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asloptions.c873
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslparser.y131
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslpredef.c787
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslprepkg.c779
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslprintf.c380
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslprune.c239
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslresource.c1090
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1.c642
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1i.c665
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2.c455
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2d.c737
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2e.c571
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2q.c716
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2s.c1197
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2w.c697
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslrules.y2991
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslstartup.c524
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslstubs.c272
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.l848
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.y120
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asltokens.y468
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asltransform.c775
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asltree.c1570
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.h320
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.y393
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslutils.c1144
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/asluuid.c154
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslwalks.c692
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/aslxref.c1269
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompile.c677
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompiler.h627
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtexpress.c424
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtfield.c586
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtio.c1144
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.l133
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.y284
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtsubtable.c384
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dttable.c3524
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.c423
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.h1299
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/dtutils.c1001
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/preprocess.h292
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prexpress.c305
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prmacros.c581
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.l236
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.y294
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prscan.c1251
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/compiler/prutils.c475
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbcmds.c1350
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbconvert.c529
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbdisply.c1201
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbexec.c827
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbfileio.c284
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbhistry.c271
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbinput.c1365
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbmethod.c416
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbnames.c1071
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbobject.c527
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbstats.c557
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbtest.c1141
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbutils.c512
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbxface.c543
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c1027
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c826
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c263
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmnames.c449
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmopcode.c978
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrc.c445
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c1079
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c734
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c368
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmutils.c330
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmwalk.c1067
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsargs.c436
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c414
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c249
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsfield.c834
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsinit.c278
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c884
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c768
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsobject.c862
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c817
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsutils.c940
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswexec.c782
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload.c589
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload2.c755
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswscope.c235
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswstate.c841
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evevent.c336
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evglock.c378
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evgpe.c843
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeblk.c554
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeinit.c466
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeutil.c397
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evhandler.c582
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evmisc.c331
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evregion.c859
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evrgnini.c730
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evsci.c282
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evxface.c1259
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evxfevnt.c428
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evxfgpe.c1101
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/events/evxfregn.c313
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exconfig.c680
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exconvrt.c744
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/excreate.c568
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exdebug.c688
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exdump.c1272
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exfield.c566
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exfldio.c1054
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exmisc.c794
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exmutex.c554
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exnames.c478
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg1.c1116
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg2.c635
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg3.c307
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg6.c355
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exprep.c651
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exregion.c577
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exresnte.c292
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exresolv.c575
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exresop.c722
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exstore.c582
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exstoren.c303
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exstorob.c239
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exsystem.c351
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/executer/exutils.c500
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwacpi.c221
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwesleep.c258
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwgpe.c601
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwpci.c463
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwregs.c728
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwsleep.c354
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwtimer.c233
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwvalid.c363
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxface.c653
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c500
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsaccess.c704
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsalloc.c594
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsarguments.c303
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsconvert.c482
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdump.c937
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c157
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nseval.c525
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsinit.c656
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsload.c367
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsnames.c343
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsobject.c515
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsparse.c225
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nspredef.c435
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsprepkg.c684
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair.c630
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair2.c1074
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nssearch.c453
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsutils.c863
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nswalk.c381
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfeval.c1074
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfname.c752
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfobj.c283
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psargs.c932
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psloop.c637
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psobject.c685
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psopcode.c343
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psopinfo.c284
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psparse.c707
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psscope.c300
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/pstree.c353
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psutils.c280
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/pswalk.c120
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/parser/psxface.c309
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsaddr.c403
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rscalc.c752
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rscreate.c505
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdump.c668
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c359
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsinfo.c263
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsio.c300
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsirq.c318
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rslist.c281
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmemory.c247
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmisc.c812
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsserial.c427
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsutils.c863
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/resources/rsxface.c740
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbdata.c868
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfadt.c778
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfind.c156
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbinstal.c525
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbprint.c271
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbutils.c477
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxface.c527
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfload.c500
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfroot.c319
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utaddress.c324
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utalloc.c364
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utbuffer.c362
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcache.c353
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcopy.c1072
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdebug.c704
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdecode.c619
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdelete.c810
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/uterror.c325
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/uteval.c379
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utexcep.c179
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utfileio.c359
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utglobal.c188
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/uthex.c111
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utids.c545
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utinit.c342
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utlock.c202
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmath.c374
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmisc.c457
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmutex.c403
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utnonansi.c432
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utobject.c776
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utosi.c532
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utownerid.c238
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utpredef.c450
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utprint.c814
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utresrc.c924
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstate.c351
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstring.c347
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/uttrack.c780
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utuuid.c103
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxface.c664
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxferror.c310
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfinit.c370
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfmutex.c211
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acapps.h233
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acbuffer.h255
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acclib.h167
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/accommon.h67
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acconfig.h252
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acdebug.h492
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acdisasm.h1060
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acdispat.h474
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acevents.h356
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acexcep.h350
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acglobal.h396
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/achware.h227
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acinterp.h756
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/aclocal.h1415
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acmacros.h435
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acnames.h92
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acnamesp.h546
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acobject.h590
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acopcode.h331
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acoutput.h496
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acparser.h359
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acpi.h67
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acpiosxf.h612
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acpixf.h1219
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acpredef.h1119
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acresrc.h442
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acrestyp.h714
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acstruct.h269
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actables.h265
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actbl.h452
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actbl1.h1420
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actbl2.h1693
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actbl3.h894
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/actypes.h1406
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acutils.h1095
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/acuuid.h90
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/amlcode.h512
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/amlresrc.h631
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/platform/acenv.h405
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/platform/acenvex.h75
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/platform/acfreebsd.h115
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/include/platform/acgcc.h82
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/oslibcfs.c255
-rw-r--r--usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c1540
-rw-r--r--usr/src/boot/sys/i386/include/_align.h6
-rw-r--r--usr/src/boot/sys/i386/include/_inttypes.h6
-rw-r--r--usr/src/boot/sys/i386/include/_limits.h6
-rw-r--r--usr/src/boot/sys/i386/include/_stdint.h6
-rw-r--r--usr/src/boot/sys/i386/include/_types.h6
-rw-r--r--usr/src/boot/sys/i386/include/asm.h120
-rw-r--r--usr/src/boot/sys/i386/include/bootinfo.h119
-rw-r--r--usr/src/boot/sys/i386/include/cpufunc.h796
-rw-r--r--usr/src/boot/sys/i386/include/elf.h6
-rw-r--r--usr/src/boot/sys/i386/include/endian.h6
-rw-r--r--usr/src/boot/sys/i386/include/exec.h38
-rw-r--r--usr/src/boot/sys/i386/include/metadata.h6
-rw-r--r--usr/src/boot/sys/i386/include/param.h168
-rw-r--r--usr/src/boot/sys/i386/include/pc/bios.h350
-rw-r--r--usr/src/boot/sys/i386/include/psl.h6
-rw-r--r--usr/src/boot/sys/i386/include/reloc.h49
-rw-r--r--usr/src/boot/sys/i386/include/setjmp.h6
-rw-r--r--usr/src/boot/sys/i386/include/signal.h67
-rw-r--r--usr/src/boot/sys/i386/include/specialreg.h6
-rw-r--r--usr/src/boot/sys/i386/include/stdarg.h6
-rw-r--r--usr/src/boot/sys/i386/include/trap.h6
-rw-r--r--usr/src/boot/sys/sys/_iovec.h48
-rw-r--r--usr/src/boot/sys/sys/_lock.h41
-rw-r--r--usr/src/boot/sys/sys/_mutex.h64
-rw-r--r--usr/src/boot/sys/sys/_null.h47
-rw-r--r--usr/src/boot/sys/sys/_pthreadtypes.h98
-rw-r--r--usr/src/boot/sys/sys/_rwlock.h62
-rw-r--r--usr/src/boot/sys/sys/_sigset.h59
-rw-r--r--usr/src/boot/sys/sys/_sockaddr_storage.h54
-rw-r--r--usr/src/boot/sys/sys/_stdint.h90
-rw-r--r--usr/src/boot/sys/sys/_timespec.h49
-rw-r--r--usr/src/boot/sys/sys/_timeval.h52
-rw-r--r--usr/src/boot/sys/sys/_types.h117
-rw-r--r--usr/src/boot/sys/sys/bitstring.h146
-rw-r--r--usr/src/boot/sys/sys/boot.h55
-rw-r--r--usr/src/boot/sys/sys/bsm/audit.h328
-rw-r--r--usr/src/boot/sys/sys/cdefs.h858
-rw-r--r--usr/src/boot/sys/sys/dirent.h100
-rw-r--r--usr/src/boot/sys/sys/disk.h139
-rw-r--r--usr/src/boot/sys/sys/disklabel.h305
-rw-r--r--usr/src/boot/sys/sys/diskmbr.h92
-rw-r--r--usr/src/boot/sys/sys/efi.h155
-rw-r--r--usr/src/boot/sys/sys/elf.h41
-rw-r--r--usr/src/boot/sys/sys/elf32.h257
-rw-r--r--usr/src/boot/sys/sys/elf64.h260
-rw-r--r--usr/src/boot/sys/sys/elf_common.h1321
-rw-r--r--usr/src/boot/sys/sys/elf_generic.h88
-rw-r--r--usr/src/boot/sys/sys/endian.h205
-rw-r--r--usr/src/boot/sys/sys/errno.h195
-rw-r--r--usr/src/boot/sys/sys/exec.h131
-rw-r--r--usr/src/boot/sys/sys/fcntl.h332
-rw-r--r--usr/src/boot/sys/sys/gpt.h217
-rw-r--r--usr/src/boot/sys/sys/imgact_aout.h157
-rw-r--r--usr/src/boot/sys/sys/ioccom.h80
-rw-r--r--usr/src/boot/sys/sys/limits.h100
-rw-r--r--usr/src/boot/sys/sys/link_elf.h105
-rw-r--r--usr/src/boot/sys/sys/linker.h353
-rw-r--r--usr/src/boot/sys/sys/linker_set.h110
-rw-r--r--usr/src/boot/sys/sys/module.h268
-rw-r--r--usr/src/boot/sys/sys/mount.h949
-rw-r--r--usr/src/boot/sys/sys/nlist_aout.h111
-rw-r--r--usr/src/boot/sys/sys/param.h363
-rw-r--r--usr/src/boot/sys/sys/queue.h753
-rw-r--r--usr/src/boot/sys/sys/reboot.h67
-rw-r--r--usr/src/boot/sys/sys/select.h108
-rw-r--r--usr/src/boot/sys/sys/signal.h443
-rw-r--r--usr/src/boot/sys/sys/socket.h690
-rw-r--r--usr/src/boot/sys/sys/stat.h361
-rw-r--r--usr/src/boot/sys/sys/stddef.h43
-rw-r--r--usr/src/boot/sys/sys/stdint.h69
-rw-r--r--usr/src/boot/sys/sys/syslimits.h76
-rw-r--r--usr/src/boot/sys/sys/time.h498
-rw-r--r--usr/src/boot/sys/sys/timespec.h63
-rw-r--r--usr/src/boot/sys/sys/types.h399
-rw-r--r--usr/src/boot/sys/sys/ucred.h119
-rw-r--r--usr/src/boot/sys/sys/unistd.h197
-rw-r--r--usr/src/boot/sys/sys/uuid.h85
-rw-r--r--usr/src/boot/sys/sys/vtoc.h163
-rw-r--r--usr/src/boot/sys/ufs/ffs/fs.h778
-rw-r--r--usr/src/boot/sys/x86/include/_align.h52
-rw-r--r--usr/src/boot/sys/x86/include/_inttypes.h221
-rw-r--r--usr/src/boot/sys/x86/include/_limits.h101
-rw-r--r--usr/src/boot/sys/x86/include/_stdint.h189
-rw-r--r--usr/src/boot/sys/x86/include/_types.h172
-rw-r--r--usr/src/boot/sys/x86/include/elf.h215
-rw-r--r--usr/src/boot/sys/x86/include/endian.h131
-rw-r--r--usr/src/boot/sys/x86/include/metadata.h57
-rw-r--r--usr/src/boot/sys/x86/include/psl.h92
-rw-r--r--usr/src/boot/sys/x86/include/setjmp.h50
-rw-r--r--usr/src/boot/sys/x86/include/signal.h167
-rw-r--r--usr/src/boot/sys/x86/include/specialreg.h862
-rw-r--r--usr/src/boot/sys/x86/include/stdarg.h77
-rw-r--r--usr/src/boot/sys/x86/include/trap.h94
-rw-r--r--usr/src/pkg/manifests/SUNWcs.mf5
-rw-r--r--usr/src/pkg/manifests/system-boot-loader.mf78
1273 files changed, 417413 insertions, 1 deletions
diff --git a/exception_lists/copyright b/exception_lists/copyright
index 654287d670..ebe2005d28 100644
--- a/exception_lists/copyright
+++ b/exception_lists/copyright
@@ -30,6 +30,7 @@ exception_lists/closed-bins
exception_lists/copyright
exception_lists/cstyle
exception_lists/hdrchk
+usr/src/boot/*
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 32097d775a..cca385650d 100644
--- a/exception_lists/cstyle
+++ b/exception_lists/cstyle
@@ -1,3 +1,4 @@
+usr/src/boot/*
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 1d3e7f192a..8e155ae31e 100644
--- a/exception_lists/hdrchk
+++ b/exception_lists/hdrchk
@@ -1,3 +1,4 @@
+usr/src/boot/*
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
diff --git a/exception_lists/keywords b/exception_lists/keywords
index f0be882342..6037b93c21 100644
--- a/exception_lists/keywords
+++ b/exception_lists/keywords
@@ -25,6 +25,7 @@
#
syntax: glob
+usr/src/boot/*
usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
usr/src/cmd/boot/common/bblk_einfo.c
usr/src/cmd/localedef/data/zh_CN.UTF-8.src
diff --git a/exception_lists/manlint b/exception_lists/manlint
new file mode 100644
index 0000000000..f6ced61996
--- /dev/null
+++ b/exception_lists/manlint
@@ -0,0 +1,14 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+usr/src/boot/*
diff --git a/exception_lists/mapfilechk b/exception_lists/mapfilechk
index b0122708b9..7a316b7306 100644
--- a/exception_lists/mapfilechk
+++ b/exception_lists/mapfilechk
@@ -20,6 +20,7 @@
#
#
+# Copyright 2016 Toomas Soome <tsoome@me.com>
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
@@ -36,6 +37,7 @@
syntax: glob
exception_lists/mapfilechk
+usr/src/boot/*
usr/src/cmd/lp/filter/postscript/font/devpost/charlib/*
usr/src/cmd/mdb/common/kmdb/mapfile_skel
usr/src/cmd/sgs/libconv/common/map.msg
diff --git a/usr/src/Makefile b/usr/src/Makefile
index b71c3485c8..213f8823c2 100644
--- a/usr/src/Makefile
+++ b/usr/src/Makefile
@@ -24,6 +24,7 @@
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
# Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2016 Toomas Soome <tsoome@me.com>
#
#
@@ -38,7 +39,7 @@ include Targetdirs
COMMON_SUBDIRS= uts lib cmd ucblib ucbcmd psm man test
sparc_SUBDIRS= stand
-i386_SUBDIRS= grub
+i386_SUBDIRS= grub boot
#
# sparc needs to build stand before psm
diff --git a/usr/src/boot/COPYRIGHT b/usr/src/boot/COPYRIGHT
new file mode 100644
index 0000000000..1d7198f722
--- /dev/null
+++ b/usr/src/boot/COPYRIGHT
@@ -0,0 +1,126 @@
+# $FreeBSD$
+# @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94
+
+The compilation of software known as FreeBSD is distributed under the
+following terms:
+
+Copyright (c) 1992-2015 The FreeBSD Project. 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.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+
+The 4.4BSD and 4.4BSD-Lite software is distributed under the following
+terms:
+
+All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite
+Releases is copyrighted by The Regents of the University of California.
+
+Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
+ The Regents of the University of California. 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.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+This product includes software developed by the University of
+California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+
+The Institute of Electrical and Electronics Engineers and the American
+National Standards Committee X3, on Information Processing Systems have
+given us permission to reprint portions of their documentation.
+
+In the following statement, the phrase ``this text'' refers to portions
+of the system documentation.
+
+Portions of this text are reprinted and reproduced in electronic form in
+the second BSD Networking Software Release, from IEEE Std 1003.1-1988, IEEE
+Standard Portable Operating System Interface for Computer Environments
+(POSIX), copyright C 1988 by the Institute of Electrical and Electronics
+Engineers, Inc. In the event of any discrepancy between these versions
+and the original IEEE Standard, the original IEEE Standard is the referee
+document.
+
+In the following statement, the phrase ``This material'' refers to portions
+of the system documentation.
+
+This material is reproduced with permission from American National
+Standards Committee X3, on Information Processing Systems. Computer and
+Business Equipment Manufacturers Association (CBEMA), 311 First St., NW,
+Suite 500, Washington, DC 20001-2178. The developmental work of
+Programming Language C was completed by the X3J11 Technical Committee.
+
+The views and conclusions contained in the software and documentation are
+those of the authors and should not be interpreted as representing official
+policies, either expressed or implied, of the Regents of the University
+of California.
+
+
+NOTE: The copyright of UC Berkeley's Berkeley Software Distribution ("BSD")
+source has been updated. The copyright addendum may be found at
+ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change and is
+included below.
+
+July 22, 1999
+
+To All Licensees, Distributors of Any Version of BSD:
+
+As you know, certain of the Berkeley Software Distribution ("BSD") source
+code files require that further distributions of products containing all or
+portions of the software, acknowledge within their advertising materials
+that such products contain software developed by UC Berkeley and its
+contributors.
+
+Specifically, the provision reads:
+
+" * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors."
+
+Effective immediately, licensees and distributors are no longer required to
+include the acknowledgement within advertising materials. Accordingly, the
+foregoing paragraph of those BSD Unix files containing it is hereby deleted
+in its entirety.
+
+William Hoskins
+Director, Office of Technology Licensing
+University of California, Berkeley
diff --git a/usr/src/boot/COPYRIGHT.descrip b/usr/src/boot/COPYRIGHT.descrip
new file mode 100644
index 0000000000..5873eb0512
--- /dev/null
+++ b/usr/src/boot/COPYRIGHT.descrip
@@ -0,0 +1 @@
+$FreeBSD$
diff --git a/usr/src/boot/Makefile b/usr/src/boot/Makefile
new file mode 100644
index 0000000000..f7a0b29fad
--- /dev/null
+++ b/usr/src/boot/Makefile
@@ -0,0 +1,32 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+.KEEP_STATE:
+
+include ../Makefile.master
+
+SUBDIRS = sys/boot
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+
+all install clean clobber: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/boot/Readme.txt b/usr/src/boot/Readme.txt
new file mode 100644
index 0000000000..aee46ced01
--- /dev/null
+++ b/usr/src/boot/Readme.txt
@@ -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 Toomas Soome <tsoome@me.com>
+#
+# Please update the svn revision number on source refresh.
+
+Current snapshot from freebsd revision 296191.
+
+This is source tree snapshot of loader and related parts from
+freebsd source.
+
+Directory tree layout:
+
+usr/src/boot is the root directory of the imported snapshot,
+containing Makefile and licence notes for build and packaging.
+
+Directories from freebsd userland (freebsd /usr/src tree):
+contrib
+include
+lib
+
+Directories from freebsd kernel tree, including boot loader itself
+are located in sys subdirectory (freebsd /usr/src/sys tree):
+
+platform specific include files:
+
+sys/amd64
+sys/i386
+sys/x86
+
+sys and ufs include files:
+sys/sys
+sys/ufs
+
+zfs boot module import in freebsd:
+sys/cddl
+
+acpica module import in freebsd:
+sys/contrib
+
+boot loader sources are in:
+sys/boot
+
+Note, some of the directories are not 1:1 mapping in this source import,
+because of differences of build systems used in illumos and freebsd.
+Also some differences are due to fact, we do not need all the variants of
+stage1/stage2 boot blocks which are built in freebsd due to the historical
+or technical reasons.
+
+Mar, 2016
diff --git a/usr/src/boot/contrib/bzip2/CHANGES b/usr/src/boot/contrib/bzip2/CHANGES
new file mode 100644
index 0000000000..81e97ca6fa
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/CHANGES
@@ -0,0 +1,327 @@
+ ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------
+
+
+0.9.0
+~~~~~
+First version.
+
+
+0.9.0a
+~~~~~~
+Removed 'ranlib' from Makefile, since most modern Unix-es
+don't need it, or even know about it.
+
+
+0.9.0b
+~~~~~~
+Fixed a problem with error reporting in bzip2.c. This does not effect
+the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
+program proper) compress and decompress correctly, but give misleading
+error messages (internal panics) when an I/O error occurs, instead of
+reporting the problem correctly. This shouldn't give any data loss
+(as far as I can see), but is confusing.
+
+Made the inline declarations disappear for non-GCC compilers.
+
+
+0.9.0c
+~~~~~~
+Fixed some problems in the library pertaining to some boundary cases.
+This makes the library behave more correctly in those situations. The
+fixes apply only to features (calls and parameters) not used by
+bzip2.c, so the non-fixedness of them in previous versions has no
+effect on reliability of bzip2.c.
+
+In bzlib.c:
+ * made zero-length BZ_FLUSH work correctly in bzCompress().
+ * fixed bzWrite/bzRead to ignore zero-length requests.
+ * fixed bzread to correctly handle read requests after EOF.
+ * wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+
+In compress.c:
+ * changed setting of nGroups in sendMTFValues() so as to
+ do a bit better on small files. This _does_ effect
+ bzip2.c.
+
+
+0.9.5a
+~~~~~~
+Major change: add a fallback sorting algorithm (blocksort.c)
+to give reasonable behaviour even for very repetitive inputs.
+Nuked --repetitive-best and --repetitive-fast since they are
+no longer useful.
+
+Minor changes: mostly a whole bunch of small changes/
+bugfixes in the driver (bzip2.c). Changes pertaining to the
+user interface are:
+
+ allow decompression of symlink'd files to stdout
+ decompress/test files even without .bz2 extension
+ give more accurate error messages for I/O errors
+ when compressing/decompressing to stdout, don't catch control-C
+ read flags from BZIP2 and BZIP environment variables
+ decline to break hard links to a file unless forced with -f
+ allow -c flag even with no filenames
+ preserve file ownerships as far as possible
+ make -s -1 give the expected block size (100k)
+ add a flag -q --quiet to suppress nonessential warnings
+ stop decoding flags after --, so files beginning in - can be handled
+ resolved inconsistent naming: bzcat or bz2cat ?
+ bzip2 --help now returns 0
+
+Programming-level changes are:
+
+ fixed syntax error in GET_LL4 for Borland C++ 5.02
+ let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
+ fix overshoot of mode-string end in bzopen_or_bzdopen
+ wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
+ close file handles under all error conditions
+ added minor mods so it compiles with DJGPP out of the box
+ fixed Makefile so it doesn't give problems with BSD make
+ fix uninitialised memory reads in dlltest.c
+
+0.9.5b
+~~~~~~
+Open stdin/stdout in binary mode for DJGPP.
+
+0.9.5c
+~~~~~~
+Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
+version could cause the sorted order to be wrong in some extremely
+obscure cases. Also changed setting of quadrant in blocksort.c.
+
+0.9.5d
+~~~~~~
+The only functional change is to make bzlibVersion() in the library
+return the correct string. This has no effect whatsoever on the
+functioning of the bzip2 program or library. Added a couple of casts
+so the library compiles without warnings at level 3 in MS Visual
+Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
+changes are minor documentation changes.
+
+1.0
+~~~
+Several minor bugfixes and enhancements:
+
+* Large file support. The library uses 64-bit counters to
+ count the volume of data passing through it. bzip2.c
+ is now compiled with -D_FILE_OFFSET_BITS=64 to get large
+ file support from the C library. -v correctly prints out
+ file sizes greater than 4 gigabytes. All these changes have
+ been made without assuming a 64-bit platform or a C compiler
+ which supports 64-bit ints, so, except for the C library
+ aspect, they are fully portable.
+
+* Decompression robustness. The library/program should be
+ robust to any corruption of compressed data, detecting and
+ handling _all_ corruption, instead of merely relying on
+ the CRCs. What this means is that the program should
+ never crash, given corrupted data, and the library should
+ always return BZ_DATA_ERROR.
+
+* Fixed an obscure race-condition bug only ever observed on
+ Solaris, in which, if you were very unlucky and issued
+ control-C at exactly the wrong time, both input and output
+ files would be deleted.
+
+* Don't run out of file handles on test/decompression when
+ large numbers of files have invalid magic numbers.
+
+* Avoid library namespace pollution. Prefix all exported
+ symbols with BZ2_.
+
+* Minor sorting enhancements from my DCC2000 paper.
+
+* Advance the version number to 1.0, so as to counteract the
+ (false-in-this-case) impression some people have that programs
+ with version numbers less than 1.0 are in some way, experimental,
+ pre-release versions.
+
+* Create an initial Makefile-libbz2_so to build a shared library.
+ Yes, I know I should really use libtool et al ...
+
+* Make the program exit with 2 instead of 0 when decompression
+ fails due to a bad magic number (ie, an invalid bzip2 header).
+ Also exit with 1 (as the manual claims :-) whenever a diagnostic
+ message would have been printed AND the corresponding operation
+ is aborted, for example
+ bzip2: Output file xx already exists.
+ When a diagnostic message is printed but the operation is not
+ aborted, for example
+ bzip2: Can't guess original name for wurble -- using wurble.out
+ then the exit value 0 is returned, unless some other problem is
+ also detected.
+
+ I think it corresponds more closely to what the manual claims now.
+
+
+1.0.1
+~~~~~
+* Modified dlltest.c so it uses the new BZ2_ naming scheme.
+* Modified makefile-msc to fix minor build probs on Win2k.
+* Updated README.COMPILATION.PROBLEMS.
+
+There are no functionality changes or bug fixes relative to version
+1.0.0. This is just a documentation update + a fix for minor Win32
+build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
+utterly pointless. Don't bother.
+
+
+1.0.2
+~~~~~
+A bug fix release, addressing various minor issues which have appeared
+in the 18 or so months since 1.0.1 was released. Most of the fixes
+are to do with file-handling or documentation bugs. To the best of my
+knowledge, there have been no data-loss-causing bugs reported in the
+compression/decompression engine of 1.0.0 or 1.0.1.
+
+Note that this release does not improve the rather crude build system
+for Unix platforms. The general plan here is to autoconfiscate/
+libtoolise 1.0.2 soon after release, and release the result as 1.1.0
+or perhaps 1.2.0. That, however, is still just a plan at this point.
+
+Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
+parentheses.
+
+* Fix an infinite segfault loop in 1.0.1 when a directory is
+ encountered in -f (force) mode.
+ (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
+
+* Avoid double fclose() of output file on certain I/O error paths.
+ (Solar Designer)
+
+* Don't fail with internal error 1007 when fed a long stream (> 48MB)
+ of byte 251. Also print useful message suggesting that 1007s may be
+ caused by bad memory.
+ (noticed by Juan Pedro Vallejo, fixed by me)
+
+* Fix uninitialised variable silly bug in demo prog dlltest.c.
+ (Jorj Bauer)
+
+* Remove 512-MB limitation on recovered file size for bzip2recover
+ on selected platforms which support 64-bit ints. At the moment
+ all GCC supported platforms, and Win32.
+ (me, Alson van der Meulen)
+
+* Hard-code header byte values, to give correct operation on platforms
+ using EBCDIC as their native character set (IBM's OS/390).
+ (Leland Lucius)
+
+* Copy file access times correctly.
+ (Marty Leisner)
+
+* Add distclean and check targets to Makefile.
+ (Michael Carmack)
+
+* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
+ (Rich Ireland, Bo Thorsen)
+
+* Pass -p (create parent dirs as needed) to mkdir during make install.
+ (Jeremy Fusco)
+
+* Dereference symlinks when copying file permissions in -f mode.
+ (Volker Schmidt)
+
+* Majorly simplify implementation of uInt64_qrm10.
+ (Bo Lindbergh)
+
+* Check the input file still exists before deleting the output one,
+ when aborting in cleanUpAndFail().
+ (Joerg Prante, Robert Linden, Matthias Krings)
+
+Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
+of bzip2:
+
+* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
+
+* Spelling changes and minor enhancements in bzip2.1.
+
+* Avoid race condition between creating the output file and setting its
+ interim permissions safely, by using fopen_output_safely().
+ No changes to bzip2recover since there is no issue with file
+ permissions there.
+
+* do not print senseless report with -v when compressing an empty
+ file.
+
+* bzcat -f works on non-bzip2 files.
+
+* do not try to escape shell meta-characters on unix (the shell takes
+ care of these).
+
+* added --fast and --best aliases for -1 -9 for gzip compatibility.
+
+
+1.0.3 (15 Feb 05)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.2.
+
+* Further robustification against corrupted compressed data.
+ There are currently no known bitstreams which can cause the
+ decompressor to crash, loop or access memory which does not
+ belong to it. If you are using bzip2 or the library to
+ decompress bitstreams from untrusted sources, an upgrade
+ to 1.0.3 is recommended. This fixes CAN-2005-1260.
+
+* The documentation has been converted to XML, from which html
+ and pdf can be derived.
+
+* Various minor bugs in the documentation have been fixed.
+
+* Fixes for various compilation warnings with newer versions of
+ gcc, and on 64-bit platforms.
+
+* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
+ This has been fixed.
+
+
+1.0.4 (20 Dec 06)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.3.
+
+* Fix file permissions race problem (CAN-2005-0953).
+
+* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD
+ scan.
+
+* 'const'/prototype cleanups in the C code.
+
+* Change default install location to /usr/local, and handle multiple
+ 'make install's without error.
+
+* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758
+ to the extent that applies to bzgrep.
+
+* Use 'mktemp' rather than 'tempfile' in bzdiff.
+
+* Tighten up a couple of assertions in blocksort.c following automated
+ analysis.
+
+* Fix minor doc/comment bugs.
+
+
+1.0.5 (10 Dec 07)
+~~~~~~~~~~~~~~~~~
+Security fix only. Fixes CERT-FI 20469 as it applies to bzip2.
+
+
+1.0.6 (6 Sept 10)
+~~~~~~~~~~~~~~~~~
+
+* Security fix for CVE-2010-0405. This was reported by Mikolaj
+ Izdebski.
+
+* Make the documentation build on Ubuntu 10.04
diff --git a/usr/src/boot/contrib/bzip2/FREEBSD-Xlist b/usr/src/boot/contrib/bzip2/FREEBSD-Xlist
new file mode 100644
index 0000000000..6c3c9b2fce
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/FREEBSD-Xlist
@@ -0,0 +1,26 @@
+# $FreeBSD$
+*Makefile*
+*README.XML.STUFF
+*bz-common.xsl
+*bz-fo.xsl
+*bz-html.xsl
+*bzdiff
+*bzdiff.1
+*bzgrep
+*bzgrep.1
+*bzip.css
+*bzip2.1.preformatted
+*bzip2.txt
+*bzmore
+*bzmore.1
+*dlltest.*
+*entities.xml
+*format.pl
+*libbz2.dsp
+*makefile.msc
+*manual.html
+*manual.pdf
+*manual.ps
+*manual.xml
+*mk251.c
+*xmlproc.sh
diff --git a/usr/src/boot/contrib/bzip2/FREEBSD-upgrade b/usr/src/boot/contrib/bzip2/FREEBSD-upgrade
new file mode 100644
index 0000000000..48e788a329
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/FREEBSD-upgrade
@@ -0,0 +1,27 @@
+$FreeBSD$
+
+Julian Seward's bzip2
+ originals can be found at: http://www.bzip.org/downloads.html
+
+Imported by:
+
+ cvs import -m "Virgin import (trimmed) of Bzip2 version 1.0.5." \
+ src/contrib/bzip2 BZIP2 v1_0_5
+
+Notes:
+ The following log shows details of trimming:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ tar xvfz bzip2-1.0.4.tar.gz -X FREEBSD-Xlist
+ cd bzip2-1.0.4
+ uuencode sample1.bz2 sample1.bz2 > sample1.bz2.uu
+ uuencode sample2.bz2 sample2.bz2 > sample2.bz2.uu
+ uuencode sample3.bz2 sample3.bz2 > sample3.bz2.uu
+ gzip -9 sample1.ref sample2.ref sample3.ref
+ uuencode sample1.ref.gz sample1.ref.gz > sample1.ref.gz.uu
+ uuencode sample2.ref.gz sample2.ref.gz > sample2.ref.gz.uu
+ uuencode sample3.ref.gz sample3.ref.gz > sample3.ref.gz.uu
+ rm sample1.bz2 sample1.ref.gz sample2.bz2 sample2.ref.gz
+ rm sample3.bz2 sample3.ref.gz
+
+obrien@FreeBSD.org
+15 May 2005
diff --git a/usr/src/boot/contrib/bzip2/FREEBSD-vendor b/usr/src/boot/contrib/bzip2/FREEBSD-vendor
new file mode 100644
index 0000000000..6847c8b9a4
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/FREEBSD-vendor
@@ -0,0 +1,5 @@
+# $FreeBSD$
+Project: bzip2
+ProjectURL: http://www.bzip.org/
+Version: 1.0.5
+License: BSD
diff --git a/usr/src/boot/contrib/bzip2/LICENSE b/usr/src/boot/contrib/bzip2/LICENSE
new file mode 100644
index 0000000000..cc614178cf
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/LICENSE
@@ -0,0 +1,42 @@
+
+--------------------------------------------------------------------------
+
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2010 Julian R Seward. 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.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
+
+--------------------------------------------------------------------------
diff --git a/usr/src/boot/contrib/bzip2/README b/usr/src/boot/contrib/bzip2/README
new file mode 100644
index 0000000000..9fb0f63601
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/README
@@ -0,0 +1,215 @@
+
+This is the README for bzip2/libzip2.
+This version is fully compatible with the previous public releases.
+
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
+Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+Complete documentation is available in Postscript form (manual.ps),
+PDF (manual.pdf) or html (manual.html). A plain-text version of the
+manual page is available as bzip2.txt.
+
+
+HOW TO BUILD -- UNIX
+
+Type 'make'. This builds the library libbz2.a and then the programs
+bzip2 and bzip2recover. Six self-tests are run. If the self-tests
+complete ok, carry on to installation:
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
+
+ make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
+ make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+ make -n install or
+ make -n install PREFIX=/xxx/yyy respectively.
+
+The -n instructs make to show the commands it would execute, but not
+actually execute them.
+
+
+HOW TO BUILD -- UNIX, shared library libbz2.so.
+
+Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
+Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims
+that it works for any other platform, though I suspect it probably
+will work for most platforms employing both ELF and gcc.
+
+bzip2-shared, a client of the shared library, is also built, but not
+self-tested. So I suggest you also build using the normal Makefile,
+since that conducts a self-test. A second reason to prefer the
+version statically linked to the library is that, on x86 platforms,
+building shared objects makes a valuable register (%ebx) unavailable
+to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
+
+Important note for people upgrading .so's from 0.9.0/0.9.5 to version
+1.0.X. All the functions in the library have been renamed, from (eg)
+bzCompress to BZ2_bzCompress, to avoid namespace pollution.
+Unfortunately this means that the libbz2.so created by
+Makefile-libbz2_so will not work with any program which used an older
+version of the library. I do encourage library clients to make the
+effort to upgrade to use version 1.0, since it is both faster and more
+robust than previous versions.
+
+
+HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
+
+It's difficult for me to support compilation on all these platforms.
+My approach is to collect binaries for these platforms, and put them
+on the master web site (http://www.bzip.org). Look there. However
+(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
+unmodified with MS Visual C. If you have difficulties building, you
+might want to read README.COMPILATION.PROBLEMS.
+
+At least using MS Visual C++ 6, you can build from the unmodified
+sources by issuing, in a command shell:
+
+ nmake -f makefile.msc
+
+(you may need to first run the MSVC-provided script VCVARS32.BAT
+ so as to set up paths to the MSVC tools correctly).
+
+
+VALIDATION
+
+Correct operation, in the sense that a compressed file can always be
+decompressed to reproduce the original, is obviously of paramount
+importance. To validate bzip2, I used a modified version of Mark
+Nelson's churn program. Churn is an automated test driver which
+recursively traverses a directory structure, using bzip2 to compress
+and then decompress each file it encounters, and checking that the
+decompressed data is the same as the original.
+
+
+
+Please read and be aware of the following:
+
+WARNING:
+
+ This program and library (attempts to) compress data by
+ performing several non-trivial transformations on it.
+ Unless you are 100% familiar with *all* the algorithms
+ contained herein, and with the consequences of modifying them,
+ you should NOT meddle with the compression or decompression
+ machinery. Incorrect changes can and very likely *will*
+ lead to disastrous loss of data.
+
+
+DISCLAIMER:
+
+ I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
+ USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
+
+ Every compression of a file implies an assumption that the
+ compressed file can be decompressed to reproduce the original.
+ Great efforts in design, coding and testing have been made to
+ ensure that this program works correctly. However, the complexity
+ of the algorithms, and, in particular, the presence of various
+ special cases in the code which occur with very low but non-zero
+ probability make it impossible to rule out the possibility of bugs
+ remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS
+ PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
+ SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
+
+ That is not to say this program is inherently unreliable.
+ Indeed, I very much hope the opposite is true. bzip2/libbzip2
+ has been carefully constructed and extensively tested.
+
+
+PATENTS:
+
+ To the best of my knowledge, bzip2/libbzip2 does not use any
+ patented algorithms. However, I do not have the resources
+ to carry out a patent search. Therefore I cannot give any
+ guarantee of the above statement.
+
+
+
+WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
+
+ * Approx 10% faster compression, 30% faster decompression
+ * -t (test mode) is a lot quicker
+ * Can decompress concatenated compressed files
+ * Programming interface, so programs can directly read/write .bz2 files
+ * Less restrictive (BSD-style) licensing
+ * Flag handling more compatible with GNU gzip
+ * Much more documentation, i.e., a proper user manual
+ * Hopefully, improved portability (at least of the library)
+
+WHAT'S NEW IN 0.9.5 ?
+
+ * Compression speed is much less sensitive to the input
+ data than in previous versions. Specifically, the very
+ slow performance caused by repetitive data is fixed.
+ * Many small improvements in file and flag handling.
+ * A Y2K statement.
+
+WHAT'S NEW IN 1.0.0 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.2 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.3 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.4 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.5 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.6 ?
+
+ See the CHANGES file.
+
+
+I hope you find bzip2 useful. Feel free to contact me at
+ jseward@bzip.org
+if you have any suggestions or queries. Many people mailed me with
+comments, suggestions and patches after the releases of bzip-0.15,
+bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
+feedback. I thank you for your comments.
+
+bzip2's "home" is http://www.bzip.org/
+
+Julian Seward
+jseward@bzip.org
+Cambridge, UK.
+
+18 July 1996 (version 0.15)
+25 August 1996 (version 0.21)
+ 7 August 1997 (bzip2, version 0.1)
+29 August 1997 (bzip2, version 0.1pl2)
+23 August 1998 (bzip2, version 0.9.0)
+ 8 June 1999 (bzip2, version 0.9.5)
+ 4 Sept 1999 (bzip2, version 0.9.5d)
+ 5 May 2000 (bzip2, version 1.0pre8)
+30 December 2001 (bzip2, version 1.0.2pre1)
+15 February 2005 (bzip2, version 1.0.3)
+20 December 2006 (bzip2, version 1.0.4)
+10 December 2007 (bzip2, version 1.0.5)
+ 6 Sept 2010 (bzip2, version 1.0.6)
diff --git a/usr/src/boot/contrib/bzip2/README.COMPILATION.PROBLEMS b/usr/src/boot/contrib/bzip2/README.COMPILATION.PROBLEMS
new file mode 100644
index 0000000000..667d0d6dfe
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/README.COMPILATION.PROBLEMS
@@ -0,0 +1,58 @@
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
+Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+bzip2-1.0.6 should compile without problems on the vast majority of
+platforms. Using the supplied Makefile, I've built and tested it
+myself for x86-linux and amd64-linux. With makefile.msc, Visual C++
+6.0 and nmake, you can build a native Win32 version too. Large file
+support seems to work correctly on at least on amd64-linux.
+
+When I say "large file" I mean a file of size 2,147,483,648 (2^31)
+bytes or above. Many older OSs can't handle files above this size,
+but many newer ones can. Large files are pretty huge -- most files
+you'll encounter are not Large Files.
+
+Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
+of platforms without difficulty, and I hope this version will continue
+in that tradition. However, in order to support large files, I've had
+to include the define -D_FILE_OFFSET_BITS=64 in the Makefile. This
+can cause problems.
+
+The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
+support is, as far as I know, the Recommended Way to get correct large
+file support. For more details, see the Large File Support
+Specification, published by the Large File Summit, at
+
+ http://ftp.sas.com/standards/large.file
+
+As a general comment, if you get compilation errors which you think
+are related to large file support, try removing the above define from
+the Makefile, ie, delete the line
+
+ BIGFILES=-D_FILE_OFFSET_BITS=64
+
+from the Makefile, and do 'make clean ; make'. This will give you a
+version of bzip2 without large file support, which, for most
+applications, is probably not a problem.
+
+Alternatively, try some of the platform-specific hints listed below.
+
+You can use the spewG.c program to generate huge files to test bzip2's
+large file support, if you are feeling paranoid. Be aware though that
+any compilation problems which affect bzip2 will also affect spewG.c,
+alas.
+
+AIX: I have reports that for large file support, you need to specify
+-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64. I have not tested
+this myself.
diff --git a/usr/src/boot/contrib/bzip2/blocksort.c b/usr/src/boot/contrib/bzip2/blocksort.c
new file mode 100644
index 0000000000..d0d662cd4e
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery ---*/
+/*--- blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting ---*/
+/*--- algorithm, for repetitive blocks ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+void fallbackSimpleSort ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 lo,
+ Int32 hi )
+{
+ Int32 i, j, tmp;
+ UInt32 ec_tmp;
+
+ if (lo == hi) return;
+
+ if (hi - lo > 3) {
+ for ( i = hi-4; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+ fmap[j-4] = fmap[j];
+ fmap[j-4] = tmp;
+ }
+ }
+
+ for ( i = hi-1; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+ fmap[j-1] = fmap[j];
+ fmap[j-1] = tmp;
+ }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ fswap(fmap[yyp1], fmap[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ sp++; }
+
+#define fpop(lz,hz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE 100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 loSt,
+ Int32 hiSt )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m;
+ Int32 sp, lo, hi;
+ UInt32 med, r, r3;
+ Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+ Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+ r = 0;
+
+ sp = 0;
+ fpush ( loSt, hiSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+ fpop ( lo, hi );
+ if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+ fallbackSimpleSort ( fmap, eclass, lo, hi );
+ continue;
+ }
+
+ /* Random partitioning. Median of 3 sometimes fails to
+ avoid bad cases. Median of 9 seems to help but
+ looks rather expensive. This too seems to work but
+ is cheaper. Guidance for the magic constants
+ 7621 and 32768 is taken from Sedgewick's algorithms
+ book, chapter 35.
+ */
+ r = ((r * 7621) + 1) % 32768;
+ r3 = r % 3;
+ if (r3 == 0) med = eclass[fmap[lo]]; else
+ if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+ med = eclass[fmap[hi]];
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (1) {
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unLo], fmap[ltLo]);
+ ltLo++; unLo++;
+ continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unHi], fmap[gtHi]);
+ gtHi--; unHi--;
+ continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+ if (gtHi < ltLo) continue;
+
+ n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+ m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ if (n - lo > hi - m) {
+ fpush ( lo, n );
+ fpush ( m, hi );
+ } else {
+ fpush ( m, hi );
+ fpush ( lo, n );
+ }
+ }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ eclass exists for [0 .. nblock-1]
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ All other areas of eclass destroyed
+ fmap [0 .. nblock-1] holds sorted order
+ bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define WORD_BH(zz) bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz) ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap,
+ UInt32* eclass,
+ UInt32* bhtab,
+ Int32 nblock,
+ Int32 verb )
+{
+ Int32 ftab[257];
+ Int32 ftabCopy[256];
+ Int32 H, i, j, k, l, r, cc, cc1;
+ Int32 nNotDone;
+ Int32 nBhtab;
+ UChar* eclass8 = (UChar*)eclass;
+
+ /*--
+ Initial 1-char radix sort to generate
+ initial fmap and initial BH bits.
+ --*/
+ if (verb >= 4)
+ VPrintf0 ( " bucket sorting ...\n" );
+ for (i = 0; i < 257; i++) ftab[i] = 0;
+ for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+ for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
+ for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
+
+ for (i = 0; i < nblock; i++) {
+ j = eclass8[i];
+ k = ftab[j] - 1;
+ ftab[j] = k;
+ fmap[k] = i;
+ }
+
+ nBhtab = 2 + (nblock / 32);
+ for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+ for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+ /*--
+ Inductively refine the buckets. Kind-of an
+ "exponential radix sort" (!), inspired by the
+ Manber-Myers suffix array construction algorithm.
+ --*/
+
+ /*-- set sentinel bits for block-end detection --*/
+ for (i = 0; i < 32; i++) {
+ SET_BH(nblock + 2*i);
+ CLEAR_BH(nblock + 2*i + 1);
+ }
+
+ /*-- the log(N) loop --*/
+ H = 1;
+ while (1) {
+
+ if (verb >= 4)
+ VPrintf1 ( " depth %6d has ", H );
+
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ if (ISSET_BH(i)) j = i;
+ k = fmap[i] - H; if (k < 0) k += nblock;
+ eclass[k] = j;
+ }
+
+ nNotDone = 0;
+ r = -1;
+ while (1) {
+
+ /*-- find the next non-singleton bucket --*/
+ k = r + 1;
+ while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (ISSET_BH(k)) {
+ while (WORD_BH(k) == 0xffffffff) k += 32;
+ while (ISSET_BH(k)) k++;
+ }
+ l = k - 1;
+ if (l >= nblock) break;
+ while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (!ISSET_BH(k)) {
+ while (WORD_BH(k) == 0x00000000) k += 32;
+ while (!ISSET_BH(k)) k++;
+ }
+ r = k - 1;
+ if (r >= nblock) break;
+
+ /*-- now [l, r] bracket current bucket --*/
+ if (r > l) {
+ nNotDone += (r - l + 1);
+ fallbackQSort3 ( fmap, eclass, l, r );
+
+ /*-- scan bucket and generate header bits-- */
+ cc = -1;
+ for (i = l; i <= r; i++) {
+ cc1 = eclass[fmap[i]];
+ if (cc != cc1) { SET_BH(i); cc = cc1; };
+ }
+ }
+ }
+
+ if (verb >= 4)
+ VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+ H *= 2;
+ if (H > nblock || nNotDone == 0) break;
+ }
+
+ /*--
+ Reconstruct the original block in
+ eclass8 [0 .. nblock-1], since the
+ previous phase destroyed it.
+ --*/
+ if (verb >= 4)
+ VPrintf0 ( " reconstructing block ...\n" );
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ while (ftabCopy[j] == 0) j++;
+ ftabCopy[j]--;
+ eclass8[fmap[i]] = (UChar)j;
+ }
+ AssertH ( j < 256, 1005 );
+}
+
+#undef SET_BH
+#undef CLEAR_BH
+#undef ISSET_BH
+#undef WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting ---*/
+/*--- algorithm. Faster for "normal" ---*/
+/*--- non-repetitive blocks. ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32 i1,
+ UInt32 i2,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32 nblock,
+ Int32* budget )
+{
+ Int32 k;
+ UChar c1, c2;
+ UInt16 s1, s2;
+
+ AssertD ( i1 != i2, "mainGtU" );
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 9 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 10 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 11 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 12 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+
+ k = nblock + 8;
+
+ do {
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+
+ if (i1 >= nblock) i1 -= nblock;
+ if (i2 >= nblock) i2 -= nblock;
+
+ k -= 8;
+ (*budget)--;
+ }
+ while (k >= 0);
+
+ return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+ Knuth's increments seem to work better
+ than Incerpi-Sedgewick here. Possibly
+ because the number of elems to sort is
+ usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ 9841, 29524, 88573, 265720,
+ 797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 lo,
+ Int32 hi,
+ Int32 d,
+ Int32* budget )
+{
+ Int32 i, j, h, bigN, hp;
+ UInt32 v;
+
+ bigN = hi - lo + 1;
+ if (bigN < 2) return;
+
+ hp = 0;
+ while (incs[hp] < bigN) hp++;
+ hp--;
+
+ for (; hp >= 0; hp--) {
+ h = incs[hp];
+
+ i = lo + h;
+ while (True) {
+
+ /*-- copy 1 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 2 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 3 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ if (*budget < 0) return;
+ }
+ }
+}
+
+
+/*---------------------------------------------*/
+/*--
+ The following is an implementation of
+ an elegant 3-way quicksort for strings,
+ described in a paper "Fast Algorithms for
+ Sorting and Searching Strings", by Robert
+ Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ mswap(ptr[yyp1], ptr[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+static
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+ UChar t;
+ if (a > b) { t = a; a = b; b = t; };
+ if (b > c) {
+ b = c;
+ if (a > b) b = a;
+ }
+ return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ stackD [sp] = dz; \
+ sp++; }
+
+#define mpop(lz,hz,dz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; \
+ dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz) \
+ { Int32 tz; \
+ tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+ tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+ tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 loSt,
+ Int32 hiSt,
+ Int32 dSt,
+ Int32* budget )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+ Int32 sp, lo, hi, d;
+
+ Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+ Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+ Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+ Int32 nextLo[3];
+ Int32 nextHi[3];
+ Int32 nextD [3];
+
+ sp = 0;
+ mpush ( loSt, hiSt, dSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+ mpop ( lo, hi, d );
+ if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
+ d > MAIN_QSORT_DEPTH_THRESH) {
+ mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+ if (*budget < 0) return;
+ continue;
+ }
+
+ med = (Int32)
+ mmed3 ( block[ptr[ lo ]+d],
+ block[ptr[ hi ]+d],
+ block[ptr[ (lo+hi)>>1 ]+d] );
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (True) {
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unLo]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unLo], ptr[ltLo]);
+ ltLo++; unLo++; continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unHi]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unHi], ptr[gtHi]);
+ gtHi--; unHi--; continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+ if (gtHi < ltLo) {
+ mpush(lo, hi, d+1 );
+ continue;
+ }
+
+ n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+ m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
+ nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
+ nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+ if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+ AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+ AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+ mpush (nextLo[0], nextHi[0], nextD[0]);
+ mpush (nextLo[1], nextHi[1], nextD[1]);
+ mpush (nextLo[2], nextHi[2], nextD[2]);
+ }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > N_OVERSHOOT
+ block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ All other areas of block32 destroyed
+ ftab [0 .. 65536 ] destroyed
+ ptr [0 .. nblock-1] holds sorted order
+ if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32* ftab,
+ Int32 nblock,
+ Int32 verb,
+ Int32* budget )
+{
+ Int32 i, j, k, ss, sb;
+ Int32 runningOrder[256];
+ Bool bigDone[256];
+ Int32 copyStart[256];
+ Int32 copyEnd [256];
+ UChar c1;
+ Int32 numQSorted;
+ UInt16 s;
+ if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
+
+ /*-- set up the 2-byte frequency table --*/
+ for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+ j = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ quadrant[i-1] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+ ftab[j]++;
+ quadrant[i-2] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+ ftab[j]++;
+ quadrant[i-3] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+ ftab[j]++;
+ }
+ for (; i >= 0; i--) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ }
+
+ /*-- (emphasises close relationship of block & quadrant) --*/
+ for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+ block [nblock+i] = block[i];
+ quadrant[nblock+i] = 0;
+ }
+
+ if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
+
+ /*-- Complete the initial radix sort --*/
+ for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+ s = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ s = (s >> 8) | (block[i-1] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-1;
+ s = (s >> 8) | (block[i-2] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-2;
+ s = (s >> 8) | (block[i-3] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-3;
+ }
+ for (; i >= 0; i--) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ }
+
+ /*--
+ Now ftab contains the first loc of every small bucket.
+ Calculate the running order, from smallest to largest
+ big bucket.
+ --*/
+ for (i = 0; i <= 255; i++) {
+ bigDone [i] = False;
+ runningOrder[i] = i;
+ }
+
+ {
+ Int32 vv;
+ Int32 h = 1;
+ do h = 3 * h + 1; while (h <= 256);
+ do {
+ h = h / 3;
+ for (i = h; i <= 255; i++) {
+ vv = runningOrder[i];
+ j = i;
+ while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+ runningOrder[j] = runningOrder[j-h];
+ j = j - h;
+ if (j <= (h - 1)) goto zero;
+ }
+ zero:
+ runningOrder[j] = vv;
+ }
+ } while (h != 1);
+ }
+
+ /*--
+ The main sorting loop.
+ --*/
+
+ numQSorted = 0;
+
+ for (i = 0; i <= 255; i++) {
+
+ /*--
+ Process big buckets, starting with the least full.
+ Basically this is a 3-step process in which we call
+ mainQSort3 to sort the small buckets [ss, j], but
+ also make a big effort to avoid the calls if we can.
+ --*/
+ ss = runningOrder[i];
+
+ /*--
+ Step 1:
+ Complete the big bucket [ss] by quicksorting
+ any unsorted small buckets [ss, j], for j != ss.
+ Hopefully previous pointer-scanning phases have already
+ completed many of the small buckets [ss, j], so
+ we don't have to sort them at all.
+ --*/
+ for (j = 0; j <= 255; j++) {
+ if (j != ss) {
+ sb = (ss << 8) + j;
+ if ( ! (ftab[sb] & SETMASK) ) {
+ Int32 lo = ftab[sb] & CLEARMASK;
+ Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+ if (hi > lo) {
+ if (verb >= 4)
+ VPrintf4 ( " qsort [0x%x, 0x%x] "
+ "done %d this %d\n",
+ ss, j, numQSorted, hi - lo + 1 );
+ mainQSort3 (
+ ptr, block, quadrant, nblock,
+ lo, hi, BZ_N_RADIX, budget
+ );
+ numQSorted += (hi - lo + 1);
+ if (*budget < 0) return;
+ }
+ }
+ ftab[sb] |= SETMASK;
+ }
+ }
+
+ AssertH ( !bigDone[ss], 1006 );
+
+ /*--
+ Step 2:
+ Now scan this big bucket [ss] so as to synthesise the
+ sorted order for small buckets [t, ss] for all t,
+ including, magically, the bucket [ss,ss] too.
+ This will avoid doing Real Work in subsequent Step 1's.
+ --*/
+ {
+ for (j = 0; j <= 255; j++) {
+ copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
+ copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+ }
+ for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyStart[c1]++ ] = k;
+ }
+ for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyEnd[c1]-- ] = k;
+ }
+ }
+
+ AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+ ||
+ /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+ Necessity for this case is demonstrated by compressing
+ a sequence of approximately 48.5 million of character
+ 251; 1.0.0/1.0.1 will then die here. */
+ (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+ 1007 )
+
+ for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+ /*--
+ Step 3:
+ The [ss] big bucket is now done. Record this fact,
+ and update the quadrant descriptors. Remember to
+ update quadrants in the overshoot area too, if
+ necessary. The "if (i < 255)" test merely skips
+ this updating for the last bucket processed, since
+ updating for the last bucket is pointless.
+
+ The quadrant array provides a way to incrementally
+ cache sort orderings, as they appear, so as to
+ make subsequent comparisons in fullGtU() complete
+ faster. For repetitive blocks this makes a big
+ difference (but not big enough to be able to avoid
+ the fallback sorting mechanism, exponential radix sort).
+
+ The precise meaning is: at all times:
+
+ for 0 <= i < nblock and 0 <= j <= nblock
+
+ if block[i] != block[j],
+
+ then the relative values of quadrant[i] and
+ quadrant[j] are meaningless.
+
+ else {
+ if quadrant[i] < quadrant[j]
+ then the string starting at i lexicographically
+ precedes the string starting at j
+
+ else if quadrant[i] > quadrant[j]
+ then the string starting at j lexicographically
+ precedes the string starting at i
+
+ else
+ the relative ordering of the strings starting
+ at i and j has not yet been determined.
+ }
+ --*/
+ bigDone[ss] = True;
+
+ if (i < 255) {
+ Int32 bbStart = ftab[ss << 8] & CLEARMASK;
+ Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+ Int32 shifts = 0;
+
+ while ((bbSize >> shifts) > 65534) shifts++;
+
+ for (j = bbSize-1; j >= 0; j--) {
+ Int32 a2update = ptr[bbStart + j];
+ UInt16 qVal = (UInt16)(j >> shifts);
+ quadrant[a2update] = qVal;
+ if (a2update < BZ_N_OVERSHOOT)
+ quadrant[a2update + nblock] = qVal;
+ }
+ AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+ }
+
+ }
+
+ if (verb >= 4)
+ VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
+ nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ arr1 exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ All other areas of block destroyed
+ ftab [ 0 .. 65536 ] destroyed
+ arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt32* ftab = s->ftab;
+ Int32 nblock = s->nblock;
+ Int32 verb = s->verbosity;
+ Int32 wfact = s->workFactor;
+ UInt16* quadrant;
+ Int32 budget;
+ Int32 budgetInit;
+ Int32 i;
+
+ if (nblock < 10000) {
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+ } else {
+ /* Calculate the location for quadrant, remembering to get
+ the alignment right. Assumes that &(block[0]) is at least
+ 2-byte aligned -- this should be ok since block is really
+ the first section of arr2.
+ */
+ i = nblock+BZ_N_OVERSHOOT;
+ if (i & 1) i++;
+ quadrant = (UInt16*)(&(block[i]));
+
+ /* (wfact-1) / 3 puts the default-factor-30
+ transition point at very roughly the same place as
+ with v0.1 and v0.9.0.
+ Not that it particularly matters any more, since the
+ resulting compressed stream is now the same regardless
+ of whether or not we use the main sort or fallback sort.
+ */
+ if (wfact < 1 ) wfact = 1;
+ if (wfact > 100) wfact = 100;
+ budgetInit = nblock * ((wfact-1) / 3);
+ budget = budgetInit;
+
+ mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+ if (verb >= 3)
+ VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
+ budgetInit - budget,
+ nblock,
+ (float)(budgetInit - budget) /
+ (float)(nblock==0 ? 1 : nblock) );
+ if (budget < 0) {
+ if (verb >= 2)
+ VPrintf0 ( " too repetitive; using fallback"
+ " sorting algorithm\n" );
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+ }
+ }
+
+ s->origPtr = -1;
+ for (i = 0; i < s->nblock; i++)
+ if (ptr[i] == 0)
+ { s->origPtr = i; break; };
+
+ AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/bzip2.1 b/usr/src/boot/contrib/bzip2/bzip2.1
new file mode 100644
index 0000000000..7bd45f0eaf
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzip2.1
@@ -0,0 +1,453 @@
+.TH bzip2 1
+.SH NAME
+bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6
+.br
+bzcat \- decompresses files to stdout
+.br
+bzip2recover \- recovers data from damaged bzip2 files
+
+.SH SYNOPSIS
+.ll +8
+.B bzip2
+.RB [ " \-cdfkqstvzVL123456789 " ]
+[
+.I "filenames \&..."
+]
+.ll -8
+.br
+.B bunzip2
+.RB [ " \-fkvsVL " ]
+[
+.I "filenames \&..."
+]
+.br
+.B bzcat
+.RB [ " \-s " ]
+[
+.I "filenames \&..."
+]
+.br
+.B bzip2recover
+.I "filename"
+
+.SH DESCRIPTION
+.I bzip2
+compresses files using the Burrows-Wheeler block sorting
+text compression algorithm, and Huffman coding. Compression is
+generally considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of the PPM
+family of statistical compressors.
+
+The command-line options are deliberately very similar to
+those of
+.I GNU gzip,
+but they are not identical.
+
+.I bzip2
+expects a list of file names to accompany the
+command-line flags. Each file is replaced by a compressed version of
+itself, with the name "original_name.bz2".
+Each compressed file
+has the same modification date, permissions, and, when possible,
+ownership as the corresponding original, so that these properties can
+be correctly restored at decompression time. File name handling is
+naive in the sense that there is no mechanism for preserving original
+file names, permissions, ownerships or dates in filesystems which lack
+these concepts, or have serious file name length restrictions, such as
+MS-DOS.
+
+.I bzip2
+and
+.I bunzip2
+will by default not overwrite existing
+files. If you want this to happen, specify the \-f flag.
+
+If no file names are specified,
+.I bzip2
+compresses from standard
+input to standard output. In this case,
+.I bzip2
+will decline to
+write compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.
+
+.I bunzip2
+(or
+.I bzip2 \-d)
+decompresses all
+specified files. Files which were not created by
+.I bzip2
+will be detected and ignored, and a warning issued.
+.I bzip2
+attempts to guess the filename for the decompressed file
+from that of the compressed file as follows:
+
+ filename.bz2 becomes filename
+ filename.bz becomes filename
+ filename.tbz2 becomes filename.tar
+ filename.tbz becomes filename.tar
+ anyothername becomes anyothername.out
+
+If the file does not end in one of the recognised endings,
+.I .bz2,
+.I .bz,
+.I .tbz2
+or
+.I .tbz,
+.I bzip2
+complains that it cannot
+guess the name of the original file, and uses the original name
+with
+.I .out
+appended.
+
+As with compression, supplying no
+filenames causes decompression from
+standard input to standard output.
+
+.I bunzip2
+will correctly decompress a file which is the
+concatenation of two or more compressed files. The result is the
+concatenation of the corresponding uncompressed files. Integrity
+testing (\-t)
+of concatenated
+compressed files is also supported.
+
+You can also compress or decompress files to the standard output by
+giving the \-c flag. Multiple files may be compressed and
+decompressed like this. The resulting outputs are fed sequentially to
+stdout. Compression of multiple files
+in this manner generates a stream
+containing multiple compressed file representations. Such a stream
+can be decompressed correctly only by
+.I bzip2
+version 0.9.0 or
+later. Earlier versions of
+.I bzip2
+will stop after decompressing
+the first file in the stream.
+
+.I bzcat
+(or
+.I bzip2 -dc)
+decompresses all specified files to
+the standard output.
+
+.I bzip2
+will read arguments from the environment variables
+.I BZIP2
+and
+.I BZIP,
+in that order, and will process them
+before any arguments read from the command line. This gives a
+convenient way to supply default arguments.
+
+Compression is always performed, even if the compressed
+file is slightly
+larger than the original. Files of less than about one hundred bytes
+tend to get larger, since the compression mechanism has a constant
+overhead in the region of 50 bytes. Random data (including the output
+of most file compressors) is coded at about 8.05 bits per byte, giving
+an expansion of around 0.5%.
+
+As a self-check for your protection,
+.I
+bzip2
+uses 32-bit CRCs to
+make sure that the decompressed version of a file is identical to the
+original. This guards against corruption of the compressed data, and
+against undetected bugs in
+.I bzip2
+(hopefully very unlikely). The
+chances of data corruption going undetected is microscopic, about one
+chance in four billion for each file processed. Be aware, though, that
+the check occurs upon decompression, so it can only tell you that
+something is wrong. It can't help you
+recover the original uncompressed
+data. You can use
+.I bzip2recover
+to try to recover data from
+damaged files.
+
+Return values: 0 for a normal exit, 1 for environmental problems (file
+not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
+compressed file, 3 for an internal consistency error (eg, bug) which
+caused
+.I bzip2
+to panic.
+
+.SH OPTIONS
+.TP
+.B \-c --stdout
+Compress or decompress to standard output.
+.TP
+.B \-d --decompress
+Force decompression.
+.I bzip2,
+.I bunzip2
+and
+.I bzcat
+are
+really the same program, and the decision about what actions to take is
+done on the basis of which name is used. This flag overrides that
+mechanism, and forces
+.I bzip2
+to decompress.
+.TP
+.B \-z --compress
+The complement to \-d: forces compression, regardless of the
+invocation name.
+.TP
+.B \-t --test
+Check integrity of the specified file(s), but don't decompress them.
+This really performs a trial decompression and throws away the result.
+.TP
+.B \-f --force
+Force overwrite of output files. Normally,
+.I bzip2
+will not overwrite
+existing output files. Also forces
+.I bzip2
+to break hard links
+to files, which it otherwise wouldn't do.
+
+bzip2 normally declines to decompress files which don't have the
+correct magic header bytes. If forced (-f), however, it will pass
+such files through unmodified. This is how GNU gzip behaves.
+.TP
+.B \-k --keep
+Keep (don't delete) input files during compression
+or decompression.
+.TP
+.B \-s --small
+Reduce memory usage, for compression, decompression and testing. Files
+are decompressed and tested using a modified algorithm which only
+requires 2.5 bytes per block byte. This means any file can be
+decompressed in 2300k of memory, albeit at about half the normal speed.
+
+During compression, \-s selects a block size of 200k, which limits
+memory use to around the same figure, at the expense of your compression
+ratio. In short, if your machine is low on memory (8 megabytes or
+less), use \-s for everything. See MEMORY MANAGEMENT below.
+.TP
+.B \-q --quiet
+Suppress non-essential warning messages. Messages pertaining to
+I/O errors and other critical events will not be suppressed.
+.TP
+.B \-v --verbose
+Verbose mode -- show the compression ratio for each file processed.
+Further \-v's increase the verbosity level, spewing out lots of
+information which is primarily of interest for diagnostic purposes.
+.TP
+.B \-L --license -V --version
+Display the software version, license terms and conditions.
+.TP
+.B \-1 (or \-\-fast) to \-9 (or \-\-best)
+Set the block size to 100 k, 200 k .. 900 k when compressing. Has no
+effect when decompressing. See MEMORY MANAGEMENT below.
+The \-\-fast and \-\-best aliases are primarily for GNU gzip
+compatibility. In particular, \-\-fast doesn't make things
+significantly faster.
+And \-\-best merely selects the default behaviour.
+.TP
+.B \--
+Treats all subsequent arguments as file names, even if they start
+with a dash. This is so you can handle files with names beginning
+with a dash, for example: bzip2 \-- \-myfilename.
+.TP
+.B \--repetitive-fast --repetitive-best
+These flags are redundant in versions 0.9.5 and above. They provided
+some coarse control over the behaviour of the sorting algorithm in
+earlier versions, which was sometimes useful. 0.9.5 and above have an
+improved algorithm which renders these flags irrelevant.
+
+.SH MEMORY MANAGEMENT
+.I bzip2
+compresses large files in blocks. The block size affects
+both the compression ratio achieved, and the amount of memory needed for
+compression and decompression. The flags \-1 through \-9
+specify the block size to be 100,000 bytes through 900,000 bytes (the
+default) respectively. At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+.I bunzip2
+then allocates itself just enough memory to decompress
+the file. Since block sizes are stored in compressed files, it follows
+that the flags \-1 to \-9 are irrelevant to and so ignored
+during decompression.
+
+Compression and decompression requirements,
+in bytes, can be estimated as:
+
+ Compression: 400k + ( 8 x block size )
+
+ Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )
+
+Larger block sizes give rapidly diminishing marginal returns. Most of
+the compression comes from the first two or three hundred k of block
+size, a fact worth bearing in mind when using
+.I bzip2
+on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block size.
+
+For files compressed with the default 900k block size,
+.I bunzip2
+will require about 3700 kbytes to decompress. To support decompression
+of any file on a 4 megabyte machine,
+.I bunzip2
+has an option to
+decompress using approximately half this amount of memory, about 2300
+kbytes. Decompression speed is also halved, so you should use this
+option only where necessary. The relevant flag is -s.
+
+In general, try and use the largest block size memory constraints allow,
+since that maximises the compression achieved. Compression and
+decompression speed are virtually unaffected by block size.
+
+Another significant point applies to files which fit in a single block
+-- that means most files you'd encounter using a large block size. The
+amount of real memory touched is proportional to the size of the file,
+since the file is smaller than a block. For example, compressing a file
+20,000 bytes long with the flag -9 will cause the compressor to
+allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
+kbytes of it. Similarly, the decompressor will allocate 3700k but only
+touch 100k + 20000 * 4 = 180 kbytes.
+
+Here is a table which summarises the maximum memory usage for different
+block sizes. Also recorded is the total compressed size for 14 files of
+the Calgary Text Compression Corpus totalling 3,141,622 bytes. This
+column gives some feel for how compression varies with block size.
+These figures tend to understate the advantage of larger block sizes for
+larger files, since the Corpus is dominated by smaller files.
+
+ Compress Decompress Decompress Corpus
+ Flag usage usage -s usage Size
+
+ -1 1200k 500k 350k 914704
+ -2 2000k 900k 600k 877703
+ -3 2800k 1300k 850k 860338
+ -4 3600k 1700k 1100k 846899
+ -5 4400k 2100k 1350k 845160
+ -6 5200k 2500k 1600k 838626
+ -7 6100k 2900k 1850k 834096
+ -8 6800k 3300k 2100k 828642
+ -9 7600k 3700k 2350k 828642
+
+.SH RECOVERING DATA FROM DAMAGED FILES
+.I bzip2
+compresses files in blocks, usually 900kbytes long. Each
+block is handled independently. If a media or transmission error causes
+a multi-block .bz2
+file to become damaged, it may be possible to
+recover data from the undamaged blocks in the file.
+
+The compressed representation of each block is delimited by a 48-bit
+pattern, which makes it possible to find the block boundaries with
+reasonable certainty. Each block also carries its own 32-bit CRC, so
+damaged blocks can be distinguished from undamaged ones.
+
+.I bzip2recover
+is a simple program whose purpose is to search for
+blocks in .bz2 files, and write each block out into its own .bz2
+file. You can then use
+.I bzip2
+\-t
+to test the
+integrity of the resulting files, and decompress those which are
+undamaged.
+
+.I bzip2recover
+takes a single argument, the name of the damaged file,
+and writes a number of files "rec00001file.bz2",
+"rec00002file.bz2", etc, containing the extracted blocks.
+The output filenames are designed so that the use of
+wildcards in subsequent processing -- for example,
+"bzip2 -dc rec*file.bz2 > recovered_data" -- processes the files in
+the correct order.
+
+.I bzip2recover
+should be of most use dealing with large .bz2
+files, as these will contain many blocks. It is clearly
+futile to use it on damaged single-block files, since a
+damaged block cannot be recovered. If you wish to minimise
+any potential data loss through media or transmission errors,
+you might consider compressing with a smaller
+block size.
+
+.SH PERFORMANCE NOTES
+The sorting phase of compression gathers together similar strings in the
+file. Because of this, files containing very long runs of repeated
+symbols, like "aabaabaabaab ..." (repeated several hundred times) may
+compress more slowly than normal. Versions 0.9.5 and above fare much
+better than previous versions in this respect. The ratio between
+worst-case and average-case compression time is in the region of 10:1.
+For previous versions, this figure was more like 100:1. You can use the
+\-vvvv option to monitor progress in great detail, if you want.
+
+Decompression speed is unaffected by these phenomena.
+
+.I bzip2
+usually allocates several megabytes of memory to operate
+in, and then charges all over it in a fairly random fashion. This means
+that performance, both for compressing and decompressing, is largely
+determined by the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss rate have
+been observed to give disproportionately large performance improvements.
+I imagine
+.I bzip2
+will perform best on machines with very large caches.
+
+.SH CAVEATS
+I/O error messages are not as helpful as they could be.
+.I bzip2
+tries hard to detect I/O errors and exit cleanly, but the details of
+what the problem is sometimes seem rather misleading.
+
+This manual page pertains to version 1.0.6 of
+.I bzip2.
+Compressed data created by this version is entirely forwards and
+backwards compatible with the previous public releases, versions
+0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and above, but with the following
+exception: 0.9.0 and above can correctly decompress multiple
+concatenated compressed files. 0.1pl2 cannot do this; it will stop
+after decompressing just the first file in the stream.
+
+.I bzip2recover
+versions prior to 1.0.2 used 32-bit integers to represent
+bit positions in compressed files, so they could not handle compressed
+files more than 512 megabytes long. Versions 1.0.2 and above use
+64-bit ints on some platforms which support them (GNU supported
+targets, and Windows). To establish whether or not bzip2recover was
+built with such a limitation, run it without arguments. In any event
+you can build yourself an unlimited version if you can recompile it
+with MaybeUInt64 set to be an unsigned 64-bit integer.
+
+
+
+.SH AUTHOR
+Julian Seward, jsewardbzip.org.
+
+http://www.bzip.org
+
+The ideas embodied in
+.I bzip2
+are due to (at least) the following
+people: Michael Burrows and David Wheeler (for the block sorting
+transformation), David Wheeler (again, for the Huffman coder), Peter
+Fenwick (for the structured coding model in the original
+.I bzip,
+and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+.I bzip).
+I am much
+indebted for their help, support and advice. See the manual in the
+source distribution for pointers to sources of documentation. Christian
+von Roques encouraged me to look for faster sorting algorithms, so as to
+speed up compression. Bela Lubkin encouraged me to improve the
+worst-case compression performance.
+Donna Robinson XMLised the documentation.
+The bz* scripts are derived from those of GNU gzip.
+Many people sent patches, helped
+with portability problems, lent machines, gave advice and were generally
+helpful.
diff --git a/usr/src/boot/contrib/bzip2/bzip2.c b/usr/src/boot/contrib/bzip2/bzip2.c
new file mode 100644
index 0000000000..6de9d1d148
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzip2.c
@@ -0,0 +1,2034 @@
+
+/*-----------------------------------------------------------*/
+/*--- A block-sorting, lossless compressor bzip2.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+/* Place a 1 beside your platform, and 0 elsewhere.
+ Generic 32-bit Unix.
+ Also works on 64-bit Unix boxes.
+ This is the default.
+*/
+#define BZ_UNIX 1
+
+/*--
+ Win32, as seen by Jacob Navia's excellent
+ port of (Chris Fraser & David Hanson)'s excellent
+ lcc compiler. Or with MS Visual C.
+ This is selected automatically if compiled by a compiler which
+ defines _WIN32, not including the Cygwin GCC.
+--*/
+#define BZ_LCCWIN32 0
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef BZ_LCCWIN32
+#define BZ_LCCWIN32 1
+#undef BZ_UNIX
+#define BZ_UNIX 0
+#endif
+
+
+/*---------------------------------------------*/
+/*--
+ Some stuff for all platforms.
+--*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <ctype.h>
+#include "bzlib.h"
+
+#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
+#define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
+#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
+
+
+/*---------------------------------------------*/
+/*--
+ Platform-specific stuff.
+--*/
+
+#if BZ_UNIX
+# include <fcntl.h>
+# include <sys/types.h>
+# include <utime.h>
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/times.h>
+
+# define PATH_SEP '/'
+# define MY_LSTAT lstat
+# define MY_STAT stat
+# define MY_S_ISREG S_ISREG
+# define MY_S_ISDIR S_ISDIR
+
+# define APPEND_FILESPEC(root, name) \
+ root=snocString((root), (name))
+
+# define APPEND_FLAG(root, name) \
+ root=snocString((root), (name))
+
+# define SET_BINARY_MODE(fd) /**/
+
+# ifdef __GNUC__
+# define NORETURN __attribute__ ((noreturn))
+# else
+# define NORETURN /**/
+# endif
+
+# ifdef __DJGPP__
+# include <io.h>
+# include <fcntl.h>
+# undef MY_LSTAT
+# undef MY_STAT
+# define MY_LSTAT stat
+# define MY_STAT stat
+# undef SET_BINARY_MODE
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+# endif
+
+# ifdef __CYGWIN__
+# include <io.h>
+# include <fcntl.h>
+# undef SET_BINARY_MODE
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+# endif
+#endif /* BZ_UNIX */
+
+
+
+#if BZ_LCCWIN32
+# include <io.h>
+# include <fcntl.h>
+# include <sys\stat.h>
+
+# define NORETURN /**/
+# define PATH_SEP '\\'
+# define MY_LSTAT _stat
+# define MY_STAT _stat
+# define MY_S_ISREG(x) ((x) & _S_IFREG)
+# define MY_S_ISDIR(x) ((x) & _S_IFDIR)
+
+# define APPEND_FLAG(root, name) \
+ root=snocString((root), (name))
+
+# define APPEND_FILESPEC(root, name) \
+ root = snocString ((root), (name))
+
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+
+#endif /* BZ_LCCWIN32 */
+
+
+/*---------------------------------------------*/
+/*--
+ Some more stuff for all platforms :-)
+--*/
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef unsigned char UChar;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+/*--
+ IntNative is your platform's `native' int size.
+ Only here to avoid probs with 64-bit platforms.
+--*/
+typedef int IntNative;
+
+
+/*---------------------------------------------------*/
+/*--- Misc (file handling) data decls ---*/
+/*---------------------------------------------------*/
+
+Int32 verbosity;
+Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
+Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
+Int32 numFileNames, numFilesProcessed, blockSize100k;
+Int32 exitValue;
+
+/*-- source modes; F==file, I==stdin, O==stdout --*/
+#define SM_I2O 1
+#define SM_F2O 2
+#define SM_F2F 3
+
+/*-- operation modes --*/
+#define OM_Z 1
+#define OM_UNZ 2
+#define OM_TEST 3
+
+Int32 opMode;
+Int32 srcMode;
+
+#define FILE_NAME_LEN 1034
+
+Int32 longestFileName;
+Char inName [FILE_NAME_LEN];
+Char outName[FILE_NAME_LEN];
+Char tmpName[FILE_NAME_LEN];
+Char *progName;
+Char progNameReally[FILE_NAME_LEN];
+FILE *outputHandleJustInCase;
+Int32 workFactor;
+
+static void panic ( const Char* ) NORETURN;
+static void ioError ( void ) NORETURN;
+static void outOfMemory ( void ) NORETURN;
+static void configError ( void ) NORETURN;
+static void crcError ( void ) NORETURN;
+static void cleanUpAndFail ( Int32 ) NORETURN;
+static void compressedStreamEOF ( void ) NORETURN;
+
+static void copyFileName ( Char*, Char* );
+static void* myMalloc ( Int32 );
+static void applySavedFileAttrToOutputFile ( IntNative fd );
+
+
+
+/*---------------------------------------------------*/
+/*--- An implementation of 64-bit ints. Sigh. ---*/
+/*--- Roll on widespread deployment of ANSI C9X ! ---*/
+/*---------------------------------------------------*/
+
+typedef
+ struct { UChar b[8]; }
+ UInt64;
+
+
+static
+void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
+{
+ n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
+ n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
+ n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
+ n->b[4] = (UChar) (hi32 & 0xFF);
+ n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
+ n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
+ n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
+ n->b[0] = (UChar) (lo32 & 0xFF);
+}
+
+
+static
+double uInt64_to_double ( UInt64* n )
+{
+ Int32 i;
+ double base = 1.0;
+ double sum = 0.0;
+ for (i = 0; i < 8; i++) {
+ sum += base * (double)(n->b[i]);
+ base *= 256.0;
+ }
+ return sum;
+}
+
+
+static
+Bool uInt64_isZero ( UInt64* n )
+{
+ Int32 i;
+ for (i = 0; i < 8; i++)
+ if (n->b[i] != 0) return 0;
+ return 1;
+}
+
+
+/* Divide *n by 10, and return the remainder. */
+static
+Int32 uInt64_qrm10 ( UInt64* n )
+{
+ UInt32 rem, tmp;
+ Int32 i;
+ rem = 0;
+ for (i = 7; i >= 0; i--) {
+ tmp = rem * 256 + n->b[i];
+ n->b[i] = tmp / 10;
+ rem = tmp % 10;
+ }
+ return rem;
+}
+
+
+/* ... and the Whole Entire Point of all this UInt64 stuff is
+ so that we can supply the following function.
+*/
+static
+void uInt64_toAscii ( char* outbuf, UInt64* n )
+{
+ Int32 i, q;
+ UChar buf[32];
+ Int32 nBuf = 0;
+ UInt64 n_copy = *n;
+ do {
+ q = uInt64_qrm10 ( &n_copy );
+ buf[nBuf] = q + '0';
+ nBuf++;
+ } while (!uInt64_isZero(&n_copy));
+ outbuf[nBuf] = 0;
+ for (i = 0; i < nBuf; i++)
+ outbuf[i] = buf[nBuf-i-1];
+}
+
+
+/*---------------------------------------------------*/
+/*--- Processing of complete files and streams ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+Bool myfeof ( FILE* f )
+{
+ Int32 c = fgetc ( f );
+ if (c == EOF) return True;
+ ungetc ( c, f );
+ return False;
+}
+
+
+/*---------------------------------------------*/
+static
+void compressStream ( FILE *stream, FILE *zStream )
+{
+ BZFILE* bzf = NULL;
+ UChar ibuf[5000];
+ Int32 nIbuf;
+ UInt32 nbytes_in_lo32, nbytes_in_hi32;
+ UInt32 nbytes_out_lo32, nbytes_out_hi32;
+ Int32 bzerr, bzerr_dummy, ret;
+
+ SET_BINARY_MODE(stream);
+ SET_BINARY_MODE(zStream);
+
+ if (ferror(stream)) goto errhandler_io;
+ if (ferror(zStream)) goto errhandler_io;
+
+ bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
+ blockSize100k, verbosity, workFactor );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ if (verbosity >= 2) fprintf ( stderr, "\n" );
+
+ while (True) {
+
+ if (myfeof(stream)) break;
+ nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
+ if (ferror(stream)) goto errhandler_io;
+ if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ }
+
+ BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
+ &nbytes_in_lo32, &nbytes_in_hi32,
+ &nbytes_out_lo32, &nbytes_out_hi32 );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ if (ferror(zStream)) goto errhandler_io;
+ ret = fflush ( zStream );
+ if (ret == EOF) goto errhandler_io;
+ if (zStream != stdout) {
+ Int32 fd = fileno ( zStream );
+ if (fd < 0) goto errhandler_io;
+ applySavedFileAttrToOutputFile ( fd );
+ ret = fclose ( zStream );
+ outputHandleJustInCase = NULL;
+ if (ret == EOF) goto errhandler_io;
+ }
+ outputHandleJustInCase = NULL;
+ if (ferror(stream)) goto errhandler_io;
+ ret = fclose ( stream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (verbosity >= 1) {
+ if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
+ fprintf ( stderr, " no data compressed.\n");
+ } else {
+ Char buf_nin[32], buf_nout[32];
+ UInt64 nbytes_in, nbytes_out;
+ double nbytes_in_d, nbytes_out_d;
+ uInt64_from_UInt32s ( &nbytes_in,
+ nbytes_in_lo32, nbytes_in_hi32 );
+ uInt64_from_UInt32s ( &nbytes_out,
+ nbytes_out_lo32, nbytes_out_hi32 );
+ nbytes_in_d = uInt64_to_double ( &nbytes_in );
+ nbytes_out_d = uInt64_to_double ( &nbytes_out );
+ uInt64_toAscii ( buf_nin, &nbytes_in );
+ uInt64_toAscii ( buf_nout, &nbytes_out );
+ fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+ "%5.2f%% saved, %s in, %s out.\n",
+ nbytes_in_d / nbytes_out_d,
+ (8.0 * nbytes_out_d) / nbytes_in_d,
+ 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
+ buf_nin,
+ buf_nout
+ );
+ }
+ }
+
+ return;
+
+ errhandler:
+ BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
+ &nbytes_in_lo32, &nbytes_in_hi32,
+ &nbytes_out_lo32, &nbytes_out_hi32 );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_MEM_ERROR:
+ outOfMemory (); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ default:
+ panic ( "compress:unexpected error" );
+ }
+
+ panic ( "compress:end" );
+ /*notreached*/
+}
+
+
+
+/*---------------------------------------------*/
+static
+Bool uncompressStream ( FILE *zStream, FILE *stream )
+{
+ BZFILE* bzf = NULL;
+ Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
+ UChar obuf[5000];
+ UChar unused[BZ_MAX_UNUSED];
+ Int32 nUnused;
+ void* unusedTmpV;
+ UChar* unusedTmp;
+
+ nUnused = 0;
+ streamNo = 0;
+
+ SET_BINARY_MODE(stream);
+ SET_BINARY_MODE(zStream);
+
+ if (ferror(stream)) goto errhandler_io;
+ if (ferror(zStream)) goto errhandler_io;
+
+ while (True) {
+
+ bzf = BZ2_bzReadOpen (
+ &bzerr, zStream, verbosity,
+ (int)smallMode, unused, nUnused
+ );
+ if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+ streamNo++;
+
+ while (bzerr == BZ_OK) {
+ nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+ if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
+ if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
+ fwrite ( obuf, sizeof(UChar), nread, stream );
+ if (ferror(stream)) goto errhandler_io;
+ }
+ if (bzerr != BZ_STREAM_END) goto errhandler;
+
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+ if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+ unusedTmp = (UChar*)unusedTmpV;
+ for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+ BZ2_bzReadClose ( &bzerr, bzf );
+ if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+ if (nUnused == 0 && myfeof(zStream)) break;
+ }
+
+ closeok:
+ if (ferror(zStream)) goto errhandler_io;
+ if (stream != stdout) {
+ Int32 fd = fileno ( stream );
+ if (fd < 0) goto errhandler_io;
+ applySavedFileAttrToOutputFile ( fd );
+ }
+ ret = fclose ( zStream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (ferror(stream)) goto errhandler_io;
+ ret = fflush ( stream );
+ if (ret != 0) goto errhandler_io;
+ if (stream != stdout) {
+ ret = fclose ( stream );
+ outputHandleJustInCase = NULL;
+ if (ret == EOF) goto errhandler_io;
+ }
+ outputHandleJustInCase = NULL;
+ if (verbosity >= 2) fprintf ( stderr, "\n " );
+ return True;
+
+ trycat:
+ if (forceOverwrite) {
+ rewind(zStream);
+ while (True) {
+ if (myfeof(zStream)) break;
+ nread = fread ( obuf, sizeof(UChar), 5000, zStream );
+ if (ferror(zStream)) goto errhandler_io;
+ if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
+ if (ferror(stream)) goto errhandler_io;
+ }
+ goto closeok;
+ }
+
+ errhandler:
+ BZ2_bzReadClose ( &bzerr_dummy, bzf );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ case BZ_DATA_ERROR:
+ crcError();
+ case BZ_MEM_ERROR:
+ outOfMemory();
+ case BZ_UNEXPECTED_EOF:
+ compressedStreamEOF();
+ case BZ_DATA_ERROR_MAGIC:
+ if (zStream != stdin) fclose(zStream);
+ if (stream != stdout) fclose(stream);
+ if (streamNo == 1) {
+ return False;
+ } else {
+ if (noisy)
+ fprintf ( stderr,
+ "\n%s: %s: trailing garbage after EOF ignored\n",
+ progName, inName );
+ return True;
+ }
+ default:
+ panic ( "decompress:unexpected error" );
+ }
+
+ panic ( "decompress:end" );
+ return True; /*notreached*/
+}
+
+
+/*---------------------------------------------*/
+static
+Bool testStream ( FILE *zStream )
+{
+ BZFILE* bzf = NULL;
+ Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
+ UChar obuf[5000];
+ UChar unused[BZ_MAX_UNUSED];
+ Int32 nUnused;
+ void* unusedTmpV;
+ UChar* unusedTmp;
+
+ nUnused = 0;
+ streamNo = 0;
+
+ SET_BINARY_MODE(zStream);
+ if (ferror(zStream)) goto errhandler_io;
+
+ while (True) {
+
+ bzf = BZ2_bzReadOpen (
+ &bzerr, zStream, verbosity,
+ (int)smallMode, unused, nUnused
+ );
+ if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+ streamNo++;
+
+ while (bzerr == BZ_OK) {
+ nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+ if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
+ }
+ if (bzerr != BZ_STREAM_END) goto errhandler;
+
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+ if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+
+ unusedTmp = (UChar*)unusedTmpV;
+ for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+ BZ2_bzReadClose ( &bzerr, bzf );
+ if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+ if (nUnused == 0 && myfeof(zStream)) break;
+
+ }
+
+ if (ferror(zStream)) goto errhandler_io;
+ ret = fclose ( zStream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (verbosity >= 2) fprintf ( stderr, "\n " );
+ return True;
+
+ errhandler:
+ BZ2_bzReadClose ( &bzerr_dummy, bzf );
+ if (verbosity == 0)
+ fprintf ( stderr, "%s: %s: ", progName, inName );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ case BZ_DATA_ERROR:
+ fprintf ( stderr,
+ "data integrity (CRC) error in data\n" );
+ return False;
+ case BZ_MEM_ERROR:
+ outOfMemory();
+ case BZ_UNEXPECTED_EOF:
+ fprintf ( stderr,
+ "file ends unexpectedly\n" );
+ return False;
+ case BZ_DATA_ERROR_MAGIC:
+ if (zStream != stdin) fclose(zStream);
+ if (streamNo == 1) {
+ fprintf ( stderr,
+ "bad magic number (file not created by bzip2)\n" );
+ return False;
+ } else {
+ if (noisy)
+ fprintf ( stderr,
+ "trailing garbage after EOF ignored\n" );
+ return True;
+ }
+ default:
+ panic ( "test:unexpected error" );
+ }
+
+ panic ( "test:end" );
+ return True; /*notreached*/
+}
+
+
+/*---------------------------------------------------*/
+/*--- Error [non-] handling grunge ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+void setExit ( Int32 v )
+{
+ if (v > exitValue) exitValue = v;
+}
+
+
+/*---------------------------------------------*/
+static
+void cadvise ( void )
+{
+ if (noisy)
+ fprintf (
+ stderr,
+ "\nIt is possible that the compressed file(s) have become corrupted.\n"
+ "You can use the -tvv option to test integrity of such files.\n\n"
+ "You can use the `bzip2recover' program to attempt to recover\n"
+ "data from undamaged sections of corrupted files.\n\n"
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void showFileNames ( void )
+{
+ if (noisy)
+ fprintf (
+ stderr,
+ "\tInput file = %s, output file = %s\n",
+ inName, outName
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void cleanUpAndFail ( Int32 ec )
+{
+ IntNative retVal;
+ struct MY_STAT statBuf;
+
+ if ( srcMode == SM_F2F
+ && opMode != OM_TEST
+ && deleteOutputOnInterrupt ) {
+
+ /* Check whether input file still exists. Delete output file
+ only if input exists to avoid loss of data. Joerg Prante, 5
+ January 2002. (JRS 06-Jan-2002: other changes in 1.0.2 mean
+ this is less likely to happen. But to be ultra-paranoid, we
+ do the check anyway.) */
+ retVal = MY_STAT ( inName, &statBuf );
+ if (retVal == 0) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Deleting output file %s, if it exists.\n",
+ progName, outName );
+ if (outputHandleJustInCase != NULL)
+ fclose ( outputHandleJustInCase );
+ retVal = remove ( outName );
+ if (retVal != 0)
+ fprintf ( stderr,
+ "%s: WARNING: deletion of output file "
+ "(apparently) failed.\n",
+ progName );
+ } else {
+ fprintf ( stderr,
+ "%s: WARNING: deletion of output file suppressed\n",
+ progName );
+ fprintf ( stderr,
+ "%s: since input file no longer exists. Output file\n",
+ progName );
+ fprintf ( stderr,
+ "%s: `%s' may be incomplete.\n",
+ progName, outName );
+ fprintf ( stderr,
+ "%s: I suggest doing an integrity test (bzip2 -tv)"
+ " of it.\n",
+ progName );
+ }
+ }
+
+ if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
+ fprintf ( stderr,
+ "%s: WARNING: some files have not been processed:\n"
+ "%s: %d specified on command line, %d not processed yet.\n\n",
+ progName, progName,
+ numFileNames, numFileNames - numFilesProcessed );
+ }
+ setExit(ec);
+ exit(exitValue);
+}
+
+
+/*---------------------------------------------*/
+static
+void panic ( const Char* s )
+{
+ fprintf ( stderr,
+ "\n%s: PANIC -- internal consistency error:\n"
+ "\t%s\n"
+ "\tThis is a BUG. Please report it to me at:\n"
+ "\tjseward@bzip.org\n",
+ progName, s );
+ showFileNames();
+ cleanUpAndFail( 3 );
+}
+
+
+/*---------------------------------------------*/
+static
+void crcError ( void )
+{
+ fprintf ( stderr,
+ "\n%s: Data integrity error when decompressing.\n",
+ progName );
+ showFileNames();
+ cadvise();
+ cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static
+void compressedStreamEOF ( void )
+{
+ if (noisy) {
+ fprintf ( stderr,
+ "\n%s: Compressed file ends unexpectedly;\n\t"
+ "perhaps it is corrupted? *Possible* reason follows.\n",
+ progName );
+ perror ( progName );
+ showFileNames();
+ cadvise();
+ }
+ cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static
+void ioError ( void )
+{
+ fprintf ( stderr,
+ "\n%s: I/O or other error, bailing out. "
+ "Possible reason follows.\n",
+ progName );
+ perror ( progName );
+ showFileNames();
+ cleanUpAndFail( 1 );
+}
+
+
+/*---------------------------------------------*/
+static
+void mySignalCatcher ( IntNative n )
+{
+ fprintf ( stderr,
+ "\n%s: Control-C or similar caught, quitting.\n",
+ progName );
+ cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static
+void mySIGSEGVorSIGBUScatcher ( IntNative n )
+{
+ if (opMode == OM_Z)
+ fprintf (
+ stderr,
+ "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
+ "\n"
+ " Possible causes are (most likely first):\n"
+ " (1) This computer has unreliable memory or cache hardware\n"
+ " (a surprisingly common problem; try a different machine.)\n"
+ " (2) A bug in the compiler used to create this executable\n"
+ " (unlikely, if you didn't compile bzip2 yourself.)\n"
+ " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
+ " The user's manual, Section 4.3, has more info on (1) and (2).\n"
+ " \n"
+ " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
+ " or (2), feel free to report it to me at: jseward@bzip.org.\n"
+ " Section 4.3 of the user's manual describes the info a useful\n"
+ " bug report should have. If the manual is available on your\n"
+ " system, please try and read it before mailing me. If you don't\n"
+ " have the manual or can't be bothered to read it, mail me anyway.\n"
+ "\n",
+ progName );
+ else
+ fprintf (
+ stderr,
+ "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
+ "\n"
+ " Possible causes are (most likely first):\n"
+ " (1) The compressed data is corrupted, and bzip2's usual checks\n"
+ " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
+ " (2) This computer has unreliable memory or cache hardware\n"
+ " (a surprisingly common problem; try a different machine.)\n"
+ " (3) A bug in the compiler used to create this executable\n"
+ " (unlikely, if you didn't compile bzip2 yourself.)\n"
+ " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
+ " The user's manual, Section 4.3, has more info on (2) and (3).\n"
+ " \n"
+ " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
+ " or (3), feel free to report it to me at: jseward@bzip.org.\n"
+ " Section 4.3 of the user's manual describes the info a useful\n"
+ " bug report should have. If the manual is available on your\n"
+ " system, please try and read it before mailing me. If you don't\n"
+ " have the manual or can't be bothered to read it, mail me anyway.\n"
+ "\n",
+ progName );
+
+ showFileNames();
+ if (opMode == OM_Z)
+ cleanUpAndFail( 3 ); else
+ { cadvise(); cleanUpAndFail( 2 ); }
+}
+
+
+/*---------------------------------------------*/
+static
+void outOfMemory ( void )
+{
+ fprintf ( stderr,
+ "\n%s: couldn't allocate enough memory\n",
+ progName );
+ showFileNames();
+ cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static
+void configError ( void )
+{
+ fprintf ( stderr,
+ "bzip2: I'm not configured correctly for this platform!\n"
+ "\tI require Int32, Int16 and Char to have sizes\n"
+ "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
+ "\tProbably you can fix this by defining them correctly,\n"
+ "\tand recompiling. Bye!\n" );
+ setExit(3);
+ exit(exitValue);
+}
+
+
+/*---------------------------------------------------*/
+/*--- The main driver machinery ---*/
+/*---------------------------------------------------*/
+
+/* All rather crufty. The main problem is that input files
+ are stat()d multiple times before use. This should be
+ cleaned up.
+*/
+
+/*---------------------------------------------*/
+static
+void pad ( Char *s )
+{
+ Int32 i;
+ if ( (Int32)strlen(s) >= longestFileName ) return;
+ for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
+ fprintf ( stderr, " " );
+}
+
+
+/*---------------------------------------------*/
+static
+void copyFileName ( Char* to, Char* from )
+{
+ if ( strlen(from) > FILE_NAME_LEN-10 ) {
+ fprintf (
+ stderr,
+ "bzip2: file name\n`%s'\n"
+ "is suspiciously (more than %d chars) long.\n"
+ "Try using a reasonable file name instead. Sorry! :-)\n",
+ from, FILE_NAME_LEN-10
+ );
+ setExit(1);
+ exit(exitValue);
+ }
+
+ strncpy(to,from,FILE_NAME_LEN-10);
+ to[FILE_NAME_LEN-10]='\0';
+}
+
+
+/*---------------------------------------------*/
+static
+Bool fileExists ( Char* name )
+{
+ FILE *tmp = fopen ( name, "rb" );
+ Bool exists = (tmp != NULL);
+ if (tmp != NULL) fclose ( tmp );
+ return exists;
+}
+
+
+/*---------------------------------------------*/
+/* Open an output file safely with O_EXCL and good permissions.
+ This avoids a race condition in versions < 1.0.2, in which
+ the file was first opened and then had its interim permissions
+ set safely. We instead use open() to create the file with
+ the interim permissions required. (--- --- rw-).
+
+ For non-Unix platforms, if we are not worrying about
+ security issues, simple this simply behaves like fopen.
+*/
+static
+FILE* fopen_output_safely ( Char* name, const char* mode )
+{
+# if BZ_UNIX
+ FILE* fp;
+ IntNative fh;
+ fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
+ if (fh == -1) return NULL;
+ fp = fdopen(fh, mode);
+ if (fp == NULL) close(fh);
+ return fp;
+# else
+ return fopen(name, mode);
+# endif
+}
+
+
+/*---------------------------------------------*/
+/*--
+ if in doubt, return True
+--*/
+static
+Bool notAStandardFile ( Char* name )
+{
+ IntNative i;
+ struct MY_STAT statBuf;
+
+ i = MY_LSTAT ( name, &statBuf );
+ if (i != 0) return True;
+ if (MY_S_ISREG(statBuf.st_mode)) return False;
+ return True;
+}
+
+
+/*---------------------------------------------*/
+/*--
+ rac 11/21/98 see if file has hard links to it
+--*/
+static
+Int32 countHardLinks ( Char* name )
+{
+ IntNative i;
+ struct MY_STAT statBuf;
+
+ i = MY_LSTAT ( name, &statBuf );
+ if (i != 0) return 0;
+ return (statBuf.st_nlink - 1);
+}
+
+
+/*---------------------------------------------*/
+/* Copy modification date, access date, permissions and owner from the
+ source to destination file. We have to copy this meta-info off
+ into fileMetaInfo before starting to compress / decompress it,
+ because doing it afterwards means we get the wrong access time.
+
+ To complicate matters, in compress() and decompress() below, the
+ sequence of tests preceding the call to saveInputFileMetaInfo()
+ involves calling fileExists(), which in turn establishes its result
+ by attempting to fopen() the file, and if successful, immediately
+ fclose()ing it again. So we have to assume that the fopen() call
+ does not cause the access time field to be updated.
+
+ Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
+ to imply that merely doing open() will not affect the access time.
+ Therefore we merely need to hope that the C library only does
+ open() as a result of fopen(), and not any kind of read()-ahead
+ cleverness.
+
+ It sounds pretty fragile to me. Whether this carries across
+ robustly to arbitrary Unix-like platforms (or even works robustly
+ on this one, RedHat 7.2) is unknown to me. Nevertheless ...
+*/
+#if BZ_UNIX
+static
+struct MY_STAT fileMetaInfo;
+#endif
+
+static
+void saveInputFileMetaInfo ( Char *srcName )
+{
+# if BZ_UNIX
+ IntNative retVal;
+ /* Note use of stat here, not lstat. */
+ retVal = MY_STAT( srcName, &fileMetaInfo );
+ ERROR_IF_NOT_ZERO ( retVal );
+# endif
+}
+
+
+static
+void applySavedTimeInfoToOutputFile ( Char *dstName )
+{
+# if BZ_UNIX
+ IntNative retVal;
+ struct utimbuf uTimBuf;
+
+ uTimBuf.actime = fileMetaInfo.st_atime;
+ uTimBuf.modtime = fileMetaInfo.st_mtime;
+
+ retVal = utime ( dstName, &uTimBuf );
+ ERROR_IF_NOT_ZERO ( retVal );
+# endif
+}
+
+static
+void applySavedFileAttrToOutputFile ( IntNative fd )
+{
+# if BZ_UNIX
+ IntNative retVal;
+
+ retVal = fchmod ( fd, fileMetaInfo.st_mode );
+ ERROR_IF_NOT_ZERO ( retVal );
+
+ (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+ /* chown() will in many cases return with EPERM, which can
+ be safely ignored.
+ */
+# endif
+}
+
+
+/*---------------------------------------------*/
+static
+Bool containsDubiousChars ( Char* name )
+{
+# if BZ_UNIX
+ /* On unix, files can contain any characters and the file expansion
+ * is performed by the shell.
+ */
+ return False;
+# else /* ! BZ_UNIX */
+ /* On non-unix (Win* platforms), wildcard characters are not allowed in
+ * filenames.
+ */
+ for (; *name != '\0'; name++)
+ if (*name == '?' || *name == '*') return True;
+ return False;
+# endif /* BZ_UNIX */
+}
+
+
+/*---------------------------------------------*/
+#define BZ_N_SUFFIX_PAIRS 4
+
+const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
+ = { ".bz2", ".bz", ".tbz2", ".tbz" };
+const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
+ = { "", "", ".tar", ".tar" };
+
+static
+Bool hasSuffix ( Char* s, const Char* suffix )
+{
+ Int32 ns = strlen(s);
+ Int32 nx = strlen(suffix);
+ if (ns < nx) return False;
+ if (strcmp(s + ns - nx, suffix) == 0) return True;
+ return False;
+}
+
+static
+Bool mapSuffix ( Char* name,
+ const Char* oldSuffix,
+ const Char* newSuffix )
+{
+ if (!hasSuffix(name,oldSuffix)) return False;
+ name[strlen(name)-strlen(oldSuffix)] = 0;
+ strcat ( name, newSuffix );
+ return True;
+}
+
+
+/*---------------------------------------------*/
+static
+void compress ( Char *name )
+{
+ FILE *inStr;
+ FILE *outStr;
+ Int32 n, i;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "compress: bad modes\n" );
+
+ switch (srcMode) {
+ case SM_I2O:
+ copyFileName ( inName, (Char*)"(stdin)" );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ case SM_F2F:
+ copyFileName ( inName, name );
+ copyFileName ( outName, name );
+ strcat ( outName, ".bz2" );
+ break;
+ case SM_F2O:
+ copyFileName ( inName, name );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ }
+
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
+ if (hasSuffix(inName, zSuffix[i])) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Input file %s already has %s suffix.\n",
+ progName, inName, zSuffix[i] );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+ if (noisy)
+ fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+ if (forceOverwrite) {
+ remove(outName);
+ } else {
+ fprintf ( stderr, "%s: Output file %s already exists.\n",
+ progName, outName );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite &&
+ (n=countHardLinks ( inName )) > 0) {
+ fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+ progName, inName, n, n > 1 ? "s" : "" );
+ setExit(1);
+ return;
+ }
+
+ if ( srcMode == SM_F2F ) {
+ /* Save the file's meta-info before we open it. Doing it later
+ means we mess up the access times. */
+ saveInputFileMetaInfo ( inName );
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ inStr = stdin;
+ outStr = stdout;
+ if ( isatty ( fileno ( stdout ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't write compressed data to a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2O:
+ inStr = fopen ( inName, "rb" );
+ outStr = stdout;
+ if ( isatty ( fileno ( stdout ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't write compressed data to a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ };
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ outStr = fopen_output_safely ( outName, "wb" );
+ if ( outStr == NULL) {
+ fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+ progName, outName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ }
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ if ( outStr != NULL ) fclose ( outStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "compress: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input and output handles are sane. Do the Biz. ---*/
+ outputHandleJustInCase = outStr;
+ deleteOutputOnInterrupt = True;
+ compressStream ( inStr, outStr );
+ outputHandleJustInCase = NULL;
+
+ /*--- If there was an I/O error, we won't get here. ---*/
+ if ( srcMode == SM_F2F ) {
+ applySavedTimeInfoToOutputFile ( outName );
+ deleteOutputOnInterrupt = False;
+ if ( !keepInputFiles ) {
+ IntNative retVal = remove ( inName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+
+ deleteOutputOnInterrupt = False;
+}
+
+
+/*---------------------------------------------*/
+static
+void uncompress ( Char *name )
+{
+ FILE *inStr;
+ FILE *outStr;
+ Int32 n, i;
+ Bool magicNumberOK;
+ Bool cantGuess;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "uncompress: bad modes\n" );
+
+ cantGuess = False;
+ switch (srcMode) {
+ case SM_I2O:
+ copyFileName ( inName, (Char*)"(stdin)" );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ case SM_F2F:
+ copyFileName ( inName, name );
+ copyFileName ( outName, name );
+ for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
+ if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
+ goto zzz;
+ cantGuess = True;
+ strcat ( outName, ".out" );
+ break;
+ case SM_F2O:
+ copyFileName ( inName, name );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ }
+
+ zzz:
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+ if (noisy)
+ fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Can't guess original name for %s -- using %s\n",
+ progName, inName, outName );
+ /* just a warning, no return */
+ }
+ if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+ if (forceOverwrite) {
+ remove(outName);
+ } else {
+ fprintf ( stderr, "%s: Output file %s already exists.\n",
+ progName, outName );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite &&
+ (n=countHardLinks ( inName ) ) > 0) {
+ fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+ progName, inName, n, n > 1 ? "s" : "" );
+ setExit(1);
+ return;
+ }
+
+ if ( srcMode == SM_F2F ) {
+ /* Save the file's meta-info before we open it. Doing it later
+ means we mess up the access times. */
+ saveInputFileMetaInfo ( inName );
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ inStr = stdin;
+ outStr = stdout;
+ if ( isatty ( fileno ( stdin ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't read compressed data from a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2O:
+ inStr = fopen ( inName, "rb" );
+ outStr = stdout;
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+ progName, inName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ outStr = fopen_output_safely ( outName, "wb" );
+ if ( outStr == NULL) {
+ fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+ progName, outName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ }
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ if ( outStr != NULL ) fclose ( outStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "uncompress: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input and output handles are sane. Do the Biz. ---*/
+ outputHandleJustInCase = outStr;
+ deleteOutputOnInterrupt = True;
+ magicNumberOK = uncompressStream ( inStr, outStr );
+ outputHandleJustInCase = NULL;
+
+ /*--- If there was an I/O error, we won't get here. ---*/
+ if ( magicNumberOK ) {
+ if ( srcMode == SM_F2F ) {
+ applySavedTimeInfoToOutputFile ( outName );
+ deleteOutputOnInterrupt = False;
+ if ( !keepInputFiles ) {
+ IntNative retVal = remove ( inName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+ } else {
+ unzFailsExist = True;
+ deleteOutputOnInterrupt = False;
+ if ( srcMode == SM_F2F ) {
+ IntNative retVal = remove ( outName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+ deleteOutputOnInterrupt = False;
+
+ if ( magicNumberOK ) {
+ if (verbosity >= 1)
+ fprintf ( stderr, "done\n" );
+ } else {
+ setExit(2);
+ if (verbosity >= 1)
+ fprintf ( stderr, "not a bzip2 file.\n" ); else
+ fprintf ( stderr,
+ "%s: %s is not a bzip2 file.\n",
+ progName, inName );
+ }
+
+}
+
+
+/*---------------------------------------------*/
+static
+void testf ( Char *name )
+{
+ FILE *inStr;
+ Bool allOK;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "testf: bad modes\n" );
+
+ copyFileName ( outName, (Char*)"(none)" );
+ switch (srcMode) {
+ case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
+ case SM_F2F: copyFileName ( inName, name ); break;
+ case SM_F2O: copyFileName ( inName, name ); break;
+ }
+
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ if ( isatty ( fileno ( stdin ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't read compressed data from a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ inStr = stdin;
+ break;
+
+ case SM_F2O: case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "testf: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input handle is sane. Do the Biz. ---*/
+ outputHandleJustInCase = NULL;
+ allOK = testStream ( inStr );
+
+ if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
+ if (!allOK) testFailsExist = True;
+}
+
+
+/*---------------------------------------------*/
+static
+void license ( void )
+{
+ fprintf ( stderr,
+
+ "bzip2, a block-sorting file compressor. "
+ "Version %s.\n"
+ " \n"
+ " Copyright (C) 1996-2010 by Julian Seward.\n"
+ " \n"
+ " This program is free software; you can redistribute it and/or modify\n"
+ " it under the terms set out in the LICENSE file, which is included\n"
+ " in the bzip2-1.0.6 source distribution.\n"
+ " \n"
+ " This program is distributed in the hope that it will be useful,\n"
+ " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ " LICENSE file for more details.\n"
+ " \n",
+ BZ2_bzlibVersion()
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void usage ( Char *fullProgName )
+{
+ fprintf (
+ stderr,
+ "bzip2, a block-sorting file compressor. "
+ "Version %s.\n"
+ "\n usage: %s [flags and input files in any order]\n"
+ "\n"
+ " -h --help print this message\n"
+ " -d --decompress force decompression\n"
+ " -z --compress force compression\n"
+ " -k --keep keep (don't delete) input files\n"
+ " -f --force overwrite existing output files\n"
+ " -t --test test compressed file integrity\n"
+ " -c --stdout output to standard out\n"
+ " -q --quiet suppress noncritical error messages\n"
+ " -v --verbose be verbose (a 2nd -v gives more)\n"
+ " -L --license display software version & license\n"
+ " -V --version display software version & license\n"
+ " -s --small use less memory (at most 2500k)\n"
+ " -1 .. -9 set block size to 100k .. 900k\n"
+ " --fast alias for -1\n"
+ " --best alias for -9\n"
+ "\n"
+ " If invoked as `bzip2', default action is to compress.\n"
+ " as `bunzip2', default action is to decompress.\n"
+ " as `bzcat', default action is to decompress to stdout.\n"
+ "\n"
+ " If no file names are given, bzip2 compresses or decompresses\n"
+ " from standard input to standard output. You can combine\n"
+ " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
+# if BZ_UNIX
+ "\n"
+# endif
+ ,
+
+ BZ2_bzlibVersion(),
+ fullProgName
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void redundant ( Char* flag )
+{
+ fprintf (
+ stderr,
+ "%s: %s is redundant in versions 0.9.5 and above\n",
+ progName, flag );
+}
+
+
+/*---------------------------------------------*/
+/*--
+ All the garbage from here to main() is purely to
+ implement a linked list of command-line arguments,
+ into which main() copies argv[1 .. argc-1].
+
+ The purpose of this exercise is to facilitate
+ the expansion of wildcard characters * and ? in
+ filenames for OSs which don't know how to do it
+ themselves, like MSDOS, Windows 95 and NT.
+
+ The actual Dirty Work is done by the platform-
+ specific macro APPEND_FILESPEC.
+--*/
+
+typedef
+ struct zzzz {
+ Char *name;
+ struct zzzz *link;
+ }
+ Cell;
+
+
+/*---------------------------------------------*/
+static
+void *myMalloc ( Int32 n )
+{
+ void* p;
+
+ p = malloc ( (size_t)n );
+ if (p == NULL) outOfMemory ();
+ return p;
+}
+
+
+/*---------------------------------------------*/
+static
+Cell *mkCell ( void )
+{
+ Cell *c;
+
+ c = (Cell*) myMalloc ( sizeof ( Cell ) );
+ c->name = NULL;
+ c->link = NULL;
+ return c;
+}
+
+
+/*---------------------------------------------*/
+static
+Cell *snocString ( Cell *root, Char *name )
+{
+ if (root == NULL) {
+ Cell *tmp = mkCell();
+ tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
+ strcpy ( tmp->name, name );
+ return tmp;
+ } else {
+ Cell *tmp = root;
+ while (tmp->link != NULL) tmp = tmp->link;
+ tmp->link = snocString ( tmp->link, name );
+ return root;
+ }
+}
+
+
+/*---------------------------------------------*/
+static
+void addFlagsFromEnvVar ( Cell** argList, Char* varName )
+{
+ Int32 i, j, k;
+ Char *envbase, *p;
+
+ envbase = getenv(varName);
+ if (envbase != NULL) {
+ p = envbase;
+ i = 0;
+ while (True) {
+ if (p[i] == 0) break;
+ p += i;
+ i = 0;
+ while (isspace((Int32)(p[0]))) p++;
+ while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
+ if (i > 0) {
+ k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
+ for (j = 0; j < k; j++) tmpName[j] = p[j];
+ tmpName[k] = 0;
+ APPEND_FLAG(*argList, tmpName);
+ }
+ }
+ }
+}
+
+
+/*---------------------------------------------*/
+#define ISFLAG(s) (strcmp(aa->name, (s))==0)
+
+IntNative main ( IntNative argc, Char *argv[] )
+{
+ Int32 i, j;
+ Char *tmp;
+ Cell *argList;
+ Cell *aa;
+ Bool decode;
+
+ /*-- Be really really really paranoid :-) --*/
+ if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
+ sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
+ sizeof(Char) != 1 || sizeof(UChar) != 1)
+ configError();
+
+ /*-- Initialise --*/
+ outputHandleJustInCase = NULL;
+ smallMode = False;
+ keepInputFiles = False;
+ forceOverwrite = False;
+ noisy = True;
+ verbosity = 0;
+ blockSize100k = 9;
+ testFailsExist = False;
+ unzFailsExist = False;
+ numFileNames = 0;
+ numFilesProcessed = 0;
+ workFactor = 30;
+ deleteOutputOnInterrupt = False;
+ exitValue = 0;
+ i = j = 0; /* avoid bogus warning from egcs-1.1.X */
+
+ /*-- Set up signal handlers for mem access errors --*/
+ signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
+# if BZ_UNIX
+# ifndef __DJGPP__
+ signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
+# endif
+# endif
+
+ copyFileName ( inName, (Char*)"(none)" );
+ copyFileName ( outName, (Char*)"(none)" );
+
+ copyFileName ( progNameReally, argv[0] );
+ progName = &progNameReally[0];
+ for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
+ if (*tmp == PATH_SEP) progName = tmp + 1;
+
+
+ /*-- Copy flags from env var BZIP2, and
+ expand filename wildcards in arg list.
+ --*/
+ argList = NULL;
+ addFlagsFromEnvVar ( &argList, (Char*)"BZIP2" );
+ addFlagsFromEnvVar ( &argList, (Char*)"BZIP" );
+ for (i = 1; i <= argc-1; i++)
+ APPEND_FILESPEC(argList, argv[i]);
+
+
+ /*-- Find the length of the longest filename --*/
+ longestFileName = 7;
+ numFileNames = 0;
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFileNames++;
+ if (longestFileName < (Int32)strlen(aa->name) )
+ longestFileName = (Int32)strlen(aa->name);
+ }
+
+
+ /*-- Determine source modes; flag handling may change this too. --*/
+ if (numFileNames == 0)
+ srcMode = SM_I2O; else srcMode = SM_F2F;
+
+
+ /*-- Determine what to do (compress/uncompress/test/cat). --*/
+ /*-- Note that subsequent flag handling may change this. --*/
+ opMode = OM_Z;
+
+ if ( (strstr ( progName, "unzip" ) != 0) ||
+ (strstr ( progName, "UNZIP" ) != 0) )
+ opMode = OM_UNZ;
+
+ if ( (strstr ( progName, "z2cat" ) != 0) ||
+ (strstr ( progName, "Z2CAT" ) != 0) ||
+ (strstr ( progName, "zcat" ) != 0) ||
+ (strstr ( progName, "ZCAT" ) != 0) ) {
+ opMode = OM_UNZ;
+ srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
+ }
+
+
+ /*-- Look at the flags. --*/
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) break;
+ if (aa->name[0] == '-' && aa->name[1] != '-') {
+ for (j = 1; aa->name[j] != '\0'; j++) {
+ switch (aa->name[j]) {
+ case 'c': srcMode = SM_F2O; break;
+ case 'd': opMode = OM_UNZ; break;
+ case 'z': opMode = OM_Z; break;
+ case 'f': forceOverwrite = True; break;
+ case 't': opMode = OM_TEST; break;
+ case 'k': keepInputFiles = True; break;
+ case 's': smallMode = True; break;
+ case 'q': noisy = False; break;
+ case '1': blockSize100k = 1; break;
+ case '2': blockSize100k = 2; break;
+ case '3': blockSize100k = 3; break;
+ case '4': blockSize100k = 4; break;
+ case '5': blockSize100k = 5; break;
+ case '6': blockSize100k = 6; break;
+ case '7': blockSize100k = 7; break;
+ case '8': blockSize100k = 8; break;
+ case '9': blockSize100k = 9; break;
+ case 'V':
+ case 'L': license(); break;
+ case 'v': verbosity++; break;
+ case 'h': usage ( progName );
+ exit ( 0 );
+ break;
+ default: fprintf ( stderr, "%s: Bad flag `%s'\n",
+ progName, aa->name );
+ usage ( progName );
+ exit ( 1 );
+ break;
+ }
+ }
+ }
+ }
+
+ /*-- And again ... --*/
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) break;
+ if (ISFLAG("--stdout")) srcMode = SM_F2O; else
+ if (ISFLAG("--decompress")) opMode = OM_UNZ; else
+ if (ISFLAG("--compress")) opMode = OM_Z; else
+ if (ISFLAG("--force")) forceOverwrite = True; else
+ if (ISFLAG("--test")) opMode = OM_TEST; else
+ if (ISFLAG("--keep")) keepInputFiles = True; else
+ if (ISFLAG("--small")) smallMode = True; else
+ if (ISFLAG("--quiet")) noisy = False; else
+ if (ISFLAG("--version")) license(); else
+ if (ISFLAG("--license")) license(); else
+ if (ISFLAG("--exponential")) workFactor = 1; else
+ if (ISFLAG("--repetitive-best")) redundant(aa->name); else
+ if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
+ if (ISFLAG("--fast")) blockSize100k = 1; else
+ if (ISFLAG("--best")) blockSize100k = 9; else
+ if (ISFLAG("--verbose")) verbosity++; else
+ if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
+ else
+ if (strncmp ( aa->name, "--", 2) == 0) {
+ fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
+ usage ( progName );
+ exit ( 1 );
+ }
+ }
+
+ if (verbosity > 4) verbosity = 4;
+ if (opMode == OM_Z && smallMode && blockSize100k > 2)
+ blockSize100k = 2;
+
+ if (opMode == OM_TEST && srcMode == SM_F2O) {
+ fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
+ progName );
+ exit ( 1 );
+ }
+
+ if (srcMode == SM_F2O && numFileNames == 0)
+ srcMode = SM_I2O;
+
+ if (opMode != OM_Z) blockSize100k = 0;
+
+ if (srcMode == SM_F2F) {
+ signal (SIGINT, mySignalCatcher);
+ signal (SIGTERM, mySignalCatcher);
+# if BZ_UNIX
+ signal (SIGHUP, mySignalCatcher);
+# endif
+ }
+
+ if (opMode == OM_Z) {
+ if (srcMode == SM_I2O) {
+ compress ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ compress ( aa->name );
+ }
+ }
+ }
+ else
+
+ if (opMode == OM_UNZ) {
+ unzFailsExist = False;
+ if (srcMode == SM_I2O) {
+ uncompress ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ uncompress ( aa->name );
+ }
+ }
+ if (unzFailsExist) {
+ setExit(2);
+ exit(exitValue);
+ }
+ }
+
+ else {
+ testFailsExist = False;
+ if (srcMode == SM_I2O) {
+ testf ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ testf ( aa->name );
+ }
+ }
+ if (testFailsExist && noisy) {
+ fprintf ( stderr,
+ "\n"
+ "You can use the `bzip2recover' program to attempt to recover\n"
+ "data from undamaged sections of corrupted files.\n\n"
+ );
+ setExit(2);
+ exit(exitValue);
+ }
+ }
+
+ /* Free the argument list memory to mollify leak detectors
+ (eg) Purify, Checker. Serves no other useful purpose.
+ */
+ aa = argList;
+ while (aa != NULL) {
+ Cell* aa2 = aa->link;
+ if (aa->name != NULL) free(aa->name);
+ free(aa);
+ aa = aa2;
+ }
+
+ return exitValue;
+}
+
+
+/*-----------------------------------------------------------*/
+/*--- end bzip2.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/bzip2recover.c b/usr/src/boot/contrib/bzip2/bzip2recover.c
new file mode 100644
index 0000000000..bf3bca5b2e
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzip2recover.c
@@ -0,0 +1,514 @@
+/*-----------------------------------------------------------*/
+/*--- Block recoverer program for bzip2 ---*/
+/*--- bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+/* This program is a complete hack and should be rewritten properly.
+ It isn't very complicated. */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* This program records bit locations in the file to be recovered.
+ That means that if 64-bit ints are not supported, we will not
+ be able to recover .bz2 files over 512MB (2^32 bits) long.
+ On GNU supported platforms, we take advantage of the 64-bit
+ int support to circumvent this problem. Ditto MSVC.
+
+ This change occurred in version 1.0.2; all prior versions have
+ the 512MB limitation.
+*/
+#ifdef __GNUC__
+ typedef unsigned long long int MaybeUInt64;
+# define MaybeUInt64_FMT "%llu"
+#else
+#ifdef _MSC_VER
+ typedef unsigned __int64 MaybeUInt64;
+# define MaybeUInt64_FMT "%I64u"
+#else
+ typedef unsigned int MaybeUInt64;
+# define MaybeUInt64_FMT "%u"
+#endif
+#endif
+
+typedef unsigned int UInt32;
+typedef int Int32;
+typedef unsigned char UChar;
+typedef char Char;
+typedef unsigned char Bool;
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+
+#define BZ_MAX_FILENAME 2000
+
+Char inFileName[BZ_MAX_FILENAME];
+Char outFileName[BZ_MAX_FILENAME];
+Char progName[BZ_MAX_FILENAME];
+
+MaybeUInt64 bytesOut = 0;
+MaybeUInt64 bytesIn = 0;
+
+
+/*---------------------------------------------------*/
+/*--- Header bytes ---*/
+/*---------------------------------------------------*/
+
+#define BZ_HDR_B 0x42 /* 'B' */
+#define BZ_HDR_Z 0x5a /* 'Z' */
+#define BZ_HDR_h 0x68 /* 'h' */
+#define BZ_HDR_0 0x30 /* '0' */
+
+
+/*---------------------------------------------------*/
+/*--- I/O errors ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static void readError ( void )
+{
+ fprintf ( stderr,
+ "%s: I/O error reading `%s', possible reason follows.\n",
+ progName, inFileName );
+ perror ( progName );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void writeError ( void )
+{
+ fprintf ( stderr,
+ "%s: I/O error reading `%s', possible reason follows.\n",
+ progName, inFileName );
+ perror ( progName );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void mallocFail ( Int32 n )
+{
+ fprintf ( stderr,
+ "%s: malloc failed on request for %d bytes.\n",
+ progName, n );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void tooManyBlocks ( Int32 max_handled_blocks )
+{
+ fprintf ( stderr,
+ "%s: `%s' appears to contain more than %d blocks\n",
+ progName, inFileName, max_handled_blocks );
+ fprintf ( stderr,
+ "%s: and cannot be handled. To fix, increase\n",
+ progName );
+ fprintf ( stderr,
+ "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O ---*/
+/*---------------------------------------------------*/
+
+typedef
+ struct {
+ FILE* handle;
+ Int32 buffer;
+ Int32 buffLive;
+ Char mode;
+ }
+ BitStream;
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenReadStream ( FILE* stream )
+{
+ BitStream *bs = malloc ( sizeof(BitStream) );
+ if (bs == NULL) mallocFail ( sizeof(BitStream) );
+ bs->handle = stream;
+ bs->buffer = 0;
+ bs->buffLive = 0;
+ bs->mode = 'r';
+ return bs;
+}
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenWriteStream ( FILE* stream )
+{
+ BitStream *bs = malloc ( sizeof(BitStream) );
+ if (bs == NULL) mallocFail ( sizeof(BitStream) );
+ bs->handle = stream;
+ bs->buffer = 0;
+ bs->buffLive = 0;
+ bs->mode = 'w';
+ return bs;
+}
+
+
+/*---------------------------------------------*/
+static void bsPutBit ( BitStream* bs, Int32 bit )
+{
+ if (bs->buffLive == 8) {
+ Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
+ if (retVal == EOF) writeError();
+ bytesOut++;
+ bs->buffLive = 1;
+ bs->buffer = bit & 0x1;
+ } else {
+ bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
+ bs->buffLive++;
+ };
+}
+
+
+/*---------------------------------------------*/
+/*--
+ Returns 0 or 1, or 2 to indicate EOF.
+--*/
+static Int32 bsGetBit ( BitStream* bs )
+{
+ if (bs->buffLive > 0) {
+ bs->buffLive --;
+ return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
+ } else {
+ Int32 retVal = getc ( bs->handle );
+ if ( retVal == EOF ) {
+ if (errno != 0) readError();
+ return 2;
+ }
+ bs->buffLive = 7;
+ bs->buffer = retVal;
+ return ( ((bs->buffer) >> 7) & 0x1 );
+ }
+}
+
+
+/*---------------------------------------------*/
+static void bsClose ( BitStream* bs )
+{
+ Int32 retVal;
+
+ if ( bs->mode == 'w' ) {
+ while ( bs->buffLive < 8 ) {
+ bs->buffLive++;
+ bs->buffer <<= 1;
+ };
+ retVal = putc ( (UChar) (bs->buffer), bs->handle );
+ if (retVal == EOF) writeError();
+ bytesOut++;
+ retVal = fflush ( bs->handle );
+ if (retVal == EOF) writeError();
+ }
+ retVal = fclose ( bs->handle );
+ if (retVal == EOF) {
+ if (bs->mode == 'w') writeError(); else readError();
+ }
+ free ( bs );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUChar ( BitStream* bs, UChar c )
+{
+ Int32 i;
+ for (i = 7; i >= 0; i--)
+ bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUInt32 ( BitStream* bs, UInt32 c )
+{
+ Int32 i;
+
+ for (i = 31; i >= 0; i--)
+ bsPutBit ( bs, (c >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static Bool endsInBz2 ( Char* name )
+{
+ Int32 n = strlen ( name );
+ if (n <= 4) return False;
+ return
+ (name[n-4] == '.' &&
+ name[n-3] == 'b' &&
+ name[n-2] == 'z' &&
+ name[n-1] == '2');
+}
+
+
+/*---------------------------------------------------*/
+/*--- ---*/
+/*---------------------------------------------------*/
+
+/* This logic isn't really right when it comes to Cygwin. */
+#ifdef _WIN32
+# define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
+#else
+# define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
+#endif
+
+#define BLOCK_HEADER_HI 0x00003141UL
+#define BLOCK_HEADER_LO 0x59265359UL
+
+#define BLOCK_ENDMARK_HI 0x00001772UL
+#define BLOCK_ENDMARK_LO 0x45385090UL
+
+/* Increase if necessary. However, a .bz2 file with > 50000 blocks
+ would have an uncompressed size of at least 40GB, so the chances
+ are low you'll need to up this.
+*/
+#define BZ_MAX_HANDLED_BLOCKS 50000
+
+MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
+
+Int32 main ( Int32 argc, Char** argv )
+{
+ FILE* inFile;
+ FILE* outFile;
+ BitStream* bsIn, *bsWr;
+ Int32 b, wrBlock, currBlock, rbCtr;
+ MaybeUInt64 bitsRead;
+
+ UInt32 buffHi, buffLo, blockCRC;
+ Char* p;
+
+ strcpy ( progName, argv[0] );
+ inFileName[0] = outFileName[0] = 0;
+
+ fprintf ( stderr,
+ "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
+
+ if (argc != 2) {
+ fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
+ progName, progName );
+ switch (sizeof(MaybeUInt64)) {
+ case 8:
+ fprintf(stderr,
+ "\trestrictions on size of recovered file: None\n");
+ break;
+ case 4:
+ fprintf(stderr,
+ "\trestrictions on size of recovered file: 512 MB\n");
+ fprintf(stderr,
+ "\tto circumvent, recompile with MaybeUInt64 as an\n"
+ "\tunsigned 64-bit int.\n");
+ break;
+ default:
+ fprintf(stderr,
+ "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
+ "configuration error.\n");
+ break;
+ }
+ exit(1);
+ }
+
+ if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
+ fprintf ( stderr,
+ "%s: supplied filename is suspiciously (>= %d chars) long. Bye!\n",
+ progName, (int)strlen(argv[1]) );
+ exit(1);
+ }
+
+ strcpy ( inFileName, argv[1] );
+
+ inFile = fopen ( inFileName, "rb" );
+ if (inFile == NULL) {
+ fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
+ exit(1);
+ }
+
+ bsIn = bsOpenReadStream ( inFile );
+ fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
+
+ bitsRead = 0;
+ buffHi = buffLo = 0;
+ currBlock = 0;
+ bStart[currBlock] = 0;
+
+ rbCtr = 0;
+
+ while (True) {
+ b = bsGetBit ( bsIn );
+ bitsRead++;
+ if (b == 2) {
+ if (bitsRead >= bStart[currBlock] &&
+ (bitsRead - bStart[currBlock]) >= 40) {
+ bEnd[currBlock] = bitsRead-1;
+ if (currBlock > 0)
+ fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
+ " to " MaybeUInt64_FMT " (incomplete)\n",
+ currBlock, bStart[currBlock], bEnd[currBlock] );
+ } else
+ currBlock--;
+ break;
+ }
+ buffHi = (buffHi << 1) | (buffLo >> 31);
+ buffLo = (buffLo << 1) | (b & 1);
+ if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
+ && buffLo == BLOCK_HEADER_LO)
+ ||
+ ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
+ && buffLo == BLOCK_ENDMARK_LO)
+ ) {
+ if (bitsRead > 49) {
+ bEnd[currBlock] = bitsRead-49;
+ } else {
+ bEnd[currBlock] = 0;
+ }
+ if (currBlock > 0 &&
+ (bEnd[currBlock] - bStart[currBlock]) >= 130) {
+ fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
+ " to " MaybeUInt64_FMT "\n",
+ rbCtr+1, bStart[currBlock], bEnd[currBlock] );
+ rbStart[rbCtr] = bStart[currBlock];
+ rbEnd[rbCtr] = bEnd[currBlock];
+ rbCtr++;
+ }
+ if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
+ tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
+ currBlock++;
+
+ bStart[currBlock] = bitsRead;
+ }
+ }
+
+ bsClose ( bsIn );
+
+ /*-- identified blocks run from 1 to rbCtr inclusive. --*/
+
+ if (rbCtr < 1) {
+ fprintf ( stderr,
+ "%s: sorry, I couldn't find any block boundaries.\n",
+ progName );
+ exit(1);
+ };
+
+ fprintf ( stderr, "%s: splitting into blocks\n", progName );
+
+ inFile = fopen ( inFileName, "rb" );
+ if (inFile == NULL) {
+ fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
+ exit(1);
+ }
+ bsIn = bsOpenReadStream ( inFile );
+
+ /*-- placate gcc's dataflow analyser --*/
+ blockCRC = 0; bsWr = 0;
+
+ bitsRead = 0;
+ outFile = NULL;
+ wrBlock = 0;
+ while (True) {
+ b = bsGetBit(bsIn);
+ if (b == 2) break;
+ buffHi = (buffHi << 1) | (buffLo >> 31);
+ buffLo = (buffLo << 1) | (b & 1);
+ if (bitsRead == 47+rbStart[wrBlock])
+ blockCRC = (buffHi << 16) | (buffLo >> 16);
+
+ if (outFile != NULL && bitsRead >= rbStart[wrBlock]
+ && bitsRead <= rbEnd[wrBlock]) {
+ bsPutBit ( bsWr, b );
+ }
+
+ bitsRead++;
+
+ if (bitsRead == rbEnd[wrBlock]+1) {
+ if (outFile != NULL) {
+ bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
+ bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
+ bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
+ bsPutUInt32 ( bsWr, blockCRC );
+ bsClose ( bsWr );
+ }
+ if (wrBlock >= rbCtr) break;
+ wrBlock++;
+ } else
+ if (bitsRead == rbStart[wrBlock]) {
+ /* Create the output file name, correctly handling leading paths.
+ (31.10.2001 by Sergey E. Kusikov) */
+ Char* split;
+ Int32 ofs, k;
+ for (k = 0; k < BZ_MAX_FILENAME; k++)
+ outFileName[k] = 0;
+ strcpy (outFileName, inFileName);
+ split = strrchr (outFileName, BZ_SPLIT_SYM);
+ if (split == NULL) {
+ split = outFileName;
+ } else {
+ ++split;
+ }
+ /* Now split points to the start of the basename. */
+ ofs = split - outFileName;
+ sprintf (split, "rec%5d", wrBlock+1);
+ for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
+ strcat (outFileName, inFileName + ofs);
+
+ if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
+
+ fprintf ( stderr, " writing block %d to `%s' ...\n",
+ wrBlock+1, outFileName );
+
+ outFile = fopen ( outFileName, "wb" );
+ if (outFile == NULL) {
+ fprintf ( stderr, "%s: can't write `%s'\n",
+ progName, outFileName );
+ exit(1);
+ }
+ bsWr = bsOpenWriteStream ( outFile );
+ bsPutUChar ( bsWr, BZ_HDR_B );
+ bsPutUChar ( bsWr, BZ_HDR_Z );
+ bsPutUChar ( bsWr, BZ_HDR_h );
+ bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
+ bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
+ bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
+ bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
+ }
+ }
+
+ fprintf ( stderr, "%s: finished\n", progName );
+ return 0;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/*--- end bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/bzlib.c b/usr/src/boot/contrib/bzip2/bzlib.c
new file mode 100644
index 0000000000..c02d076ccd
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzlib.c
@@ -0,0 +1,1581 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions. ---*/
+/*--- bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
+ fixed bzWrite/bzRead to ignore zero-length requests.
+ fixed bzread to correctly handle read requests after EOF.
+ wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "bzlib_private.h"
+
+#ifndef BZ_NO_COMPRESS
+
+/*---------------------------------------------------*/
+/*--- Compression stuff ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+ fprintf(stderr,
+ "\n\nbzip2/libbzip2: internal error number %d.\n"
+ "This is a bug in bzip2/libbzip2, %s.\n"
+ "Please report it to me at: jseward@bzip.org. If this happened\n"
+ "when you were using some program which uses libbzip2 as a\n"
+ "component, you should also report this bug to the author(s)\n"
+ "of that program. Please make an effort to report this bug;\n"
+ "timely and accurate bug reports eventually lead to higher\n"
+ "quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
+ errcode,
+ BZ2_bzlibVersion()
+ );
+
+ if (errcode == 1007) {
+ fprintf(stderr,
+ "\n*** A special note about internal error number 1007 ***\n"
+ "\n"
+ "Experience suggests that a common cause of i.e. 1007\n"
+ "is unreliable memory or other hardware. The 1007 assertion\n"
+ "just happens to cross-check the results of huge numbers of\n"
+ "memory reads/writes, and so acts (unintendedly) as a stress\n"
+ "test of your memory system.\n"
+ "\n"
+ "I suggest the following: try compressing the file again,\n"
+ "possibly monitoring progress in detail with the -vv flag.\n"
+ "\n"
+ "* If the error cannot be reproduced, and/or happens at different\n"
+ " points in compression, you may have a flaky memory system.\n"
+ " Try a memory-test program. I have used Memtest86\n"
+ " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
+ " Memtest86 tests memory much more thorougly than your BIOSs\n"
+ " power-on test, and may find failures that the BIOS doesn't.\n"
+ "\n"
+ "* If the error can be repeatably reproduced, this is a bug in\n"
+ " bzip2, and I would very much like to hear about it. Please\n"
+ " let me know, and, ideally, save a copy of the file causing the\n"
+ " problem -- without which I will be unable to investigate it.\n"
+ "\n"
+ );
+ }
+
+ exit(3);
+}
+#endif
+
+#endif /* BZ_NO_COMPRESS */
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+ if (sizeof(int) != 4) return 0;
+ if (sizeof(short) != 2) return 0;
+ if (sizeof(char) != 1) return 0;
+ return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+ void* v = malloc ( items * size );
+ return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+ if (addr != NULL) free ( addr );
+}
+
+#ifndef BZ_NO_COMPRESS
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+ Int32 i;
+ s->nblock = 0;
+ s->numZ = 0;
+ s->state_out_pos = 0;
+ BZ_INITIALISE_CRC ( s->blockCRC );
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+ s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+ s->state_in_ch = 256;
+ s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+ if (s->state_in_ch < 256 && s->state_in_len > 0)
+ return False; else
+ return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit)
+ ( bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ Int32 n;
+ EState* s;
+
+ if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+ if (strm == NULL ||
+ blockSize100k < 1 || blockSize100k > 9 ||
+ workFactor < 0 || workFactor > 250)
+ return BZ_PARAM_ERROR;
+
+ if (workFactor == 0) workFactor = 30;
+ if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+ if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+ s = BZALLOC( sizeof(EState) );
+ if (s == NULL) return BZ_MEM_ERROR;
+ s->strm = strm;
+
+ s->arr1 = NULL;
+ s->arr2 = NULL;
+ s->ftab = NULL;
+
+ n = 100000 * blockSize100k;
+ s->arr1 = BZALLOC( n * sizeof(UInt32) );
+ s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+ s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
+
+ if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+ if (s->arr1 != NULL) BZFREE(s->arr1);
+ if (s->arr2 != NULL) BZFREE(s->arr2);
+ if (s->ftab != NULL) BZFREE(s->ftab);
+ if (s != NULL) BZFREE(s);
+ return BZ_MEM_ERROR;
+ }
+
+ s->blockNo = 0;
+ s->state = BZ_S_INPUT;
+ s->mode = BZ_M_RUNNING;
+ s->combinedCRC = 0;
+ s->blockSize100k = blockSize100k;
+ s->nblockMAX = 100000 * blockSize100k - 19;
+ s->verbosity = verbosity;
+ s->workFactor = workFactor;
+
+ s->block = (UChar*)s->arr2;
+ s->mtfv = (UInt16*)s->arr1;
+ s->zbits = NULL;
+ s->ptr = (UInt32*)s->arr1;
+
+ strm->state = s;
+ strm->total_in_lo32 = 0;
+ strm->total_in_hi32 = 0;
+ strm->total_out_lo32 = 0;
+ strm->total_out_hi32 = 0;
+ init_RL ( s );
+ prepare_new_block ( s );
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+ Int32 i;
+ UChar ch = (UChar)(s->state_in_ch);
+ for (i = 0; i < s->state_in_len; i++) {
+ BZ_UPDATE_CRC( s->blockCRC, ch );
+ }
+ s->inUse[s->state_in_ch] = True;
+ switch (s->state_in_len) {
+ case 1:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 2:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 3:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ default:
+ s->inUse[s->state_in_len-4] = True;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+ s->nblock++;
+ break;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+ if (s->state_in_ch < 256) add_pair_to_block ( s );
+ init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
+{ \
+ UInt32 zchh = (UInt32)(zchh0); \
+ /*-- fast track the common case --*/ \
+ if (zchh != zs->state_in_ch && \
+ zs->state_in_len == 1) { \
+ UChar ch = (UChar)(zs->state_in_ch); \
+ BZ_UPDATE_CRC( zs->blockCRC, ch ); \
+ zs->inUse[zs->state_in_ch] = True; \
+ zs->block[zs->nblock] = (UChar)ch; \
+ zs->nblock++; \
+ zs->state_in_ch = zchh; \
+ } \
+ else \
+ /*-- general, uncommon cases --*/ \
+ if (zchh != zs->state_in_ch || \
+ zs->state_in_len == 255) { \
+ if (zs->state_in_ch < 256) \
+ add_pair_to_block ( zs ); \
+ zs->state_in_ch = zchh; \
+ zs->state_in_len = 1; \
+ } else { \
+ zs->state_in_len++; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+ Bool progress_in = False;
+
+ if (s->mode == BZ_M_RUNNING) {
+
+ /*-- fast track the common case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ s->strm->total_in_lo32++;
+ if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ }
+
+ } else {
+
+ /*-- general, uncommon case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ /*-- flush/finish end? --*/
+ if (s->avail_in_expect == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ s->strm->total_in_lo32++;
+ if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ s->avail_in_expect--;
+ }
+ }
+ return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+ Bool progress_out = False;
+
+ while (True) {
+
+ /*-- no output space? --*/
+ if (s->strm->avail_out == 0) break;
+
+ /*-- block done? --*/
+ if (s->state_out_pos >= s->numZ) break;
+
+ progress_out = True;
+ *(s->strm->next_out) = s->zbits[s->state_out_pos];
+ s->state_out_pos++;
+ s->strm->avail_out--;
+ s->strm->next_out++;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+ Bool progress_in = False;
+ Bool progress_out = False;
+ EState* s = strm->state;
+
+ while (True) {
+
+ if (s->state == BZ_S_OUTPUT) {
+ progress_out |= copy_output_until_stop ( s );
+ if (s->state_out_pos < s->numZ) break;
+ if (s->mode == BZ_M_FINISHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ prepare_new_block ( s );
+ s->state = BZ_S_INPUT;
+ if (s->mode == BZ_M_FLUSHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ }
+
+ if (s->state == BZ_S_INPUT) {
+ progress_in |= copy_input_until_stop ( s );
+ if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+ flush_RL ( s );
+ BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->nblock >= s->nblockMAX) {
+ BZ2_compressBlock ( s, False );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->strm->avail_in == 0) {
+ break;
+ }
+ }
+
+ }
+
+ return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+ Bool progress;
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ preswitch:
+ switch (s->mode) {
+
+ case BZ_M_IDLE:
+ return BZ_SEQUENCE_ERROR;
+
+ case BZ_M_RUNNING:
+ if (action == BZ_RUN) {
+ progress = handle_compress ( strm );
+ return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+ }
+ else
+ if (action == BZ_FLUSH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FLUSHING;
+ goto preswitch;
+ }
+ else
+ if (action == BZ_FINISH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FINISHING;
+ goto preswitch;
+ }
+ else
+ return BZ_PARAM_ERROR;
+
+ case BZ_M_FLUSHING:
+ if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+ s->mode = BZ_M_RUNNING;
+ return BZ_RUN_OK;
+
+ case BZ_M_FINISHING:
+ if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (!progress) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+ s->mode = BZ_M_IDLE;
+ return BZ_STREAM_END;
+ }
+ return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
+{
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ if (s->arr1 != NULL) BZFREE(s->arr1);
+ if (s->arr2 != NULL) BZFREE(s->arr2);
+ if (s->ftab != NULL) BZFREE(s->ftab);
+ BZFREE(strm->state);
+
+ strm->state = NULL;
+
+ return BZ_OK;
+}
+
+#endif /* BZ_NO_COMPRESS */
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit)
+ ( bz_stream* strm,
+ int verbosity,
+ int small )
+{
+ DState* s;
+
+ if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+ if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+ if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+ if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+ s = BZALLOC( sizeof(DState) );
+ if (s == NULL) return BZ_MEM_ERROR;
+ s->strm = strm;
+ strm->state = s;
+ s->state = BZ_X_MAGIC_1;
+ s->bsLive = 0;
+ s->bsBuff = 0;
+ s->calculatedCombinedCRC = 0;
+ strm->total_in_lo32 = 0;
+ strm->total_in_hi32 = 0;
+ strm->total_out_lo32 = 0;
+ strm->total_out_hi32 = 0;
+ s->smallDecompress = (Bool)small;
+ s->ll4 = NULL;
+ s->ll16 = NULL;
+ s->tt = NULL;
+ s->currBlockNo = 0;
+ s->verbosity = verbosity;
+
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+ UChar k1;
+
+ if (s->blockRandomised) {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
+ s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+ }
+
+ } else {
+
+ /* restore */
+ UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
+ UChar c_state_out_ch = s->state_out_ch;
+ Int32 c_state_out_len = s->state_out_len;
+ Int32 c_nblock_used = s->nblock_used;
+ Int32 c_k0 = s->k0;
+ UInt32* c_tt = s->tt;
+ UInt32 c_tPos = s->tPos;
+ char* cs_next_out = s->strm->next_out;
+ unsigned int cs_avail_out = s->strm->avail_out;
+ Int32 ro_blockSize100k = s->blockSize100k;
+ /* end restore */
+
+ UInt32 avail_out_INIT = cs_avail_out;
+ Int32 s_save_nblockPP = s->save_nblock+1;
+ unsigned int total_out_lo32_old;
+
+ while (True) {
+
+ /* try to finish existing run */
+ if (c_state_out_len > 0) {
+ while (True) {
+ if (cs_avail_out == 0) goto return_notr;
+ if (c_state_out_len == 1) break;
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+ c_state_out_len--;
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ s_state_out_len_eq_one:
+ {
+ if (cs_avail_out == 0) {
+ c_state_out_len = 1; goto return_notr;
+ };
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ }
+ /* Only caused by corrupt data stream? */
+ if (c_nblock_used > s_save_nblockPP)
+ return True;
+
+ /* can a new run be started? */
+ if (c_nblock_used == s_save_nblockPP) {
+ c_state_out_len = 0; goto return_notr;
+ };
+ c_state_out_ch = c_k0;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (k1 != c_k0) {
+ c_k0 = k1; goto s_state_out_len_eq_one;
+ };
+ if (c_nblock_used == s_save_nblockPP)
+ goto s_state_out_len_eq_one;
+
+ c_state_out_len = 2;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ c_state_out_len = 3;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ c_state_out_len = ((Int32)k1) + 4;
+ BZ_GET_FAST_C(c_k0); c_nblock_used++;
+ }
+
+ return_notr:
+ total_out_lo32_old = s->strm->total_out_lo32;
+ s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+ if (s->strm->total_out_lo32 < total_out_lo32_old)
+ s->strm->total_out_hi32++;
+
+ /* save */
+ s->calculatedBlockCRC = c_calculatedBlockCRC;
+ s->state_out_ch = c_state_out_ch;
+ s->state_out_len = c_state_out_len;
+ s->nblock_used = c_nblock_used;
+ s->k0 = c_k0;
+ s->tt = c_tt;
+ s->tPos = c_tPos;
+ s->strm->next_out = cs_next_out;
+ s->strm->avail_out = cs_avail_out;
+ /* end save */
+ }
+ return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+ Int32 nb, na, mid;
+ nb = 0;
+ na = 256;
+ do {
+ mid = (nb + na) >> 1;
+ if (indx >= cftab[mid]) nb = mid; else na = mid;
+ }
+ while (na - nb != 1);
+ return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+ UChar k1;
+
+ if (s->blockRandomised) {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
+ s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+ }
+
+ } else {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+ Bool corrupt;
+ DState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ while (True) {
+ if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+ if (s->state == BZ_X_OUTPUT) {
+ if (s->smallDecompress)
+ corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+ corrupt = unRLE_obuf_to_output_FAST ( s );
+ if (corrupt) return BZ_DATA_ERROR;
+ if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+ BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+ if (s->verbosity >= 3)
+ VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
+ s->calculatedBlockCRC );
+ if (s->verbosity >= 2) VPrintf0 ( "]" );
+ if (s->calculatedBlockCRC != s->storedBlockCRC)
+ return BZ_DATA_ERROR;
+ s->calculatedCombinedCRC
+ = (s->calculatedCombinedCRC << 1) |
+ (s->calculatedCombinedCRC >> 31);
+ s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+ s->state = BZ_X_BLKHDR_1;
+ } else {
+ return BZ_OK;
+ }
+ }
+ if (s->state >= BZ_X_MAGIC_1) {
+ Int32 r = BZ2_decompress ( s );
+ if (r == BZ_STREAM_END) {
+ if (s->verbosity >= 3)
+ VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
+ s->storedCombinedCRC, s->calculatedCombinedCRC );
+ if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+ return BZ_DATA_ERROR;
+ return r;
+ }
+ if (s->state != BZ_X_OUTPUT) return r;
+ }
+ }
+
+ AssertH ( 0, 6001 );
+
+ return 0; /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
+{
+ DState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ if (s->tt != NULL) BZFREE(s->tt);
+ if (s->ll16 != NULL) BZFREE(s->ll16);
+ if (s->ll4 != NULL) BZFREE(s->ll4);
+
+ BZFREE(strm->state);
+ strm->state = NULL;
+
+ return BZ_OK;
+}
+
+#ifndef BZ_NO_COMPRESS
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee) \
+{ \
+ if (bzerror != NULL) *bzerror = eee; \
+ if (bzf != NULL) bzf->lastErr = eee; \
+}
+
+typedef
+ struct {
+ FILE* handle;
+ Char buf[BZ_MAX_UNUSED];
+ Int32 bufN;
+ Bool writing;
+ bz_stream strm;
+ Int32 lastErr;
+ Bool initialisedOk;
+ }
+ bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+ Int32 c = fgetc ( f );
+ if (c == EOF) return True;
+ ungetc ( c, f );
+ return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen)
+ ( int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ Int32 ret;
+ bzFile* bzf = NULL;
+
+ BZ_SETERR(BZ_OK);
+
+ if (f == NULL ||
+ (blockSize100k < 1 || blockSize100k > 9) ||
+ (workFactor < 0 || workFactor > 250) ||
+ (verbosity < 0 || verbosity > 4))
+ { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+ if (ferror(f))
+ { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+ bzf = malloc ( sizeof(bzFile) );
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+ BZ_SETERR(BZ_OK);
+ bzf->initialisedOk = False;
+ bzf->bufN = 0;
+ bzf->handle = f;
+ bzf->writing = True;
+ bzf->strm.bzalloc = NULL;
+ bzf->strm.bzfree = NULL;
+ bzf->strm.opaque = NULL;
+
+ if (workFactor == 0) workFactor = 30;
+ ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
+ verbosity, workFactor );
+ if (ret != BZ_OK)
+ { BZ_SETERR(ret); free(bzf); return NULL; };
+
+ bzf->strm.avail_in = 0;
+ bzf->initialisedOk = True;
+ return bzf;
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+ ( int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len )
+{
+ Int32 n, n2, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+ if (bzf == NULL || buf == NULL || len < 0)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+ if (!(bzf->writing))
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+
+ if (len == 0)
+ { BZ_SETERR(BZ_OK); return; };
+
+ bzf->strm.avail_in = len;
+ bzf->strm.next_in = buf;
+
+ while (True) {
+ bzf->strm.avail_out = BZ_MAX_UNUSED;
+ bzf->strm.next_out = bzf->buf;
+ ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+ if (ret != BZ_RUN_OK)
+ { BZ_SETERR(ret); return; };
+
+ if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+ n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+ n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
+ n, bzf->handle );
+ if (n != n2 || ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (bzf->strm.avail_in == 0)
+ { BZ_SETERR(BZ_OK); return; };
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+ ( int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out )
+{
+ BZ2_bzWriteClose64 ( bzerror, b, abandon,
+ nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+ ( int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32 )
+{
+ Int32 n, n2, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_OK); return; };
+ if (!(bzf->writing))
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+
+ if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+ if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+ if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+ if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+ if ((!abandon) && bzf->lastErr == BZ_OK) {
+ while (True) {
+ bzf->strm.avail_out = BZ_MAX_UNUSED;
+ bzf->strm.next_out = bzf->buf;
+ ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+ if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+ { BZ_SETERR(ret); return; };
+
+ if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+ n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+ n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
+ n, bzf->handle );
+ if (n != n2 || ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (ret == BZ_STREAM_END) break;
+ }
+ }
+
+ if ( !abandon && !ferror ( bzf->handle ) ) {
+ fflush ( bzf->handle );
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (nbytes_in_lo32 != NULL)
+ *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+ if (nbytes_in_hi32 != NULL)
+ *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+ if (nbytes_out_lo32 != NULL)
+ *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+ if (nbytes_out_hi32 != NULL)
+ *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+ BZ_SETERR(BZ_OK);
+ BZ2_bzCompressEnd ( &(bzf->strm) );
+ free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen)
+ ( int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused )
+{
+ bzFile* bzf = NULL;
+ int ret;
+
+ BZ_SETERR(BZ_OK);
+
+ if (f == NULL ||
+ (small != 0 && small != 1) ||
+ (verbosity < 0 || verbosity > 4) ||
+ (unused == NULL && nUnused != 0) ||
+ (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+ { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+ if (ferror(f))
+ { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+ bzf = malloc ( sizeof(bzFile) );
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+ BZ_SETERR(BZ_OK);
+
+ bzf->initialisedOk = False;
+ bzf->handle = f;
+ bzf->bufN = 0;
+ bzf->writing = False;
+ bzf->strm.bzalloc = NULL;
+ bzf->strm.bzfree = NULL;
+ bzf->strm.opaque = NULL;
+
+ while (nUnused > 0) {
+ bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+ unused = ((void*)( 1 + ((UChar*)(unused)) ));
+ nUnused--;
+ }
+
+ ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+ if (ret != BZ_OK)
+ { BZ_SETERR(ret); free(bzf); return NULL; };
+
+ bzf->strm.avail_in = bzf->bufN;
+ bzf->strm.next_in = bzf->buf;
+
+ bzf->initialisedOk = True;
+ return bzf;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_OK); return; };
+
+ if (bzf->writing)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+ if (bzf->initialisedOk)
+ (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+ free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead)
+ ( int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len )
+{
+ Int32 n, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+
+ if (bzf == NULL || buf == NULL || len < 0)
+ { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+ if (bzf->writing)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+ if (len == 0)
+ { BZ_SETERR(BZ_OK); return 0; };
+
+ bzf->strm.avail_out = len;
+ bzf->strm.next_out = buf;
+
+ while (True) {
+
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+ if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+ n = fread ( bzf->buf, sizeof(UChar),
+ BZ_MAX_UNUSED, bzf->handle );
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return 0; };
+ bzf->bufN = n;
+ bzf->strm.avail_in = bzf->bufN;
+ bzf->strm.next_in = bzf->buf;
+ }
+
+ ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+ if (ret != BZ_OK && ret != BZ_STREAM_END)
+ { BZ_SETERR(ret); return 0; };
+
+ if (ret == BZ_OK && myfeof(bzf->handle) &&
+ bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+ { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+ if (ret == BZ_STREAM_END)
+ { BZ_SETERR(BZ_STREAM_END);
+ return len - bzf->strm.avail_out; };
+ if (bzf->strm.avail_out == 0)
+ { BZ_SETERR(BZ_OK); return len; };
+
+ }
+
+ return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused)
+ ( int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused )
+{
+ bzFile* bzf = (bzFile*)b;
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+ if (bzf->lastErr != BZ_STREAM_END)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (unused == NULL || nUnused == NULL)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+ BZ_SETERR(BZ_OK);
+ *nUnused = bzf->strm.avail_in;
+ *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress)
+ ( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ bz_stream strm;
+ int ret;
+
+ if (dest == NULL || destLen == NULL ||
+ source == NULL ||
+ blockSize100k < 1 || blockSize100k > 9 ||
+ verbosity < 0 || verbosity > 4 ||
+ workFactor < 0 || workFactor > 250)
+ return BZ_PARAM_ERROR;
+
+ if (workFactor == 0) workFactor = 30;
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+ strm.opaque = NULL;
+ ret = BZ2_bzCompressInit ( &strm, blockSize100k,
+ verbosity, workFactor );
+ if (ret != BZ_OK) return ret;
+
+ strm.next_in = source;
+ strm.next_out = dest;
+ strm.avail_in = sourceLen;
+ strm.avail_out = *destLen;
+
+ ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+ if (ret == BZ_FINISH_OK) goto output_overflow;
+ if (ret != BZ_STREAM_END) goto errhandler;
+
+ /* normal termination */
+ *destLen -= strm.avail_out;
+ BZ2_bzCompressEnd ( &strm );
+ return BZ_OK;
+
+ output_overflow:
+ BZ2_bzCompressEnd ( &strm );
+ return BZ_OUTBUFF_FULL;
+
+ errhandler:
+ BZ2_bzCompressEnd ( &strm );
+ return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress)
+ ( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity )
+{
+ bz_stream strm;
+ int ret;
+
+ if (dest == NULL || destLen == NULL ||
+ source == NULL ||
+ (small != 0 && small != 1) ||
+ verbosity < 0 || verbosity > 4)
+ return BZ_PARAM_ERROR;
+
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+ strm.opaque = NULL;
+ ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+ if (ret != BZ_OK) return ret;
+
+ strm.next_in = source;
+ strm.next_out = dest;
+ strm.avail_in = sourceLen;
+ strm.avail_out = *destLen;
+
+ ret = BZ2_bzDecompress ( &strm );
+ if (ret == BZ_OK) goto output_overflow_or_eof;
+ if (ret != BZ_STREAM_END) goto errhandler;
+
+ /* normal termination */
+ *destLen -= strm.avail_out;
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_OK;
+
+ output_overflow_or_eof:
+ if (strm.avail_out > 0) {
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_UNEXPECTED_EOF;
+ } else {
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_OUTBUFF_FULL;
+ };
+
+ errhandler:
+ BZ2_bzDecompressEnd ( &strm );
+ return ret;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+ return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+ return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+ ( const char *path, /* no use when bzdopen */
+ int fd, /* no use when bzdopen */
+ const char *mode,
+ int open_mode) /* bzopen: 0, bzdopen:1 */
+{
+ int bzerr;
+ char unused[BZ_MAX_UNUSED];
+ int blockSize100k = 9;
+ int writing = 0;
+ char mode2[10] = "";
+ FILE *fp = NULL;
+ BZFILE *bzfp = NULL;
+ int verbosity = 0;
+ int workFactor = 30;
+ int smallMode = 0;
+ int nUnused = 0;
+
+ if (mode == NULL) return NULL;
+ while (*mode) {
+ switch (*mode) {
+ case 'r':
+ writing = 0; break;
+ case 'w':
+ writing = 1; break;
+ case 's':
+ smallMode = 1; break;
+ default:
+ if (isdigit((int)(*mode))) {
+ blockSize100k = *mode-BZ_HDR_0;
+ }
+ }
+ mode++;
+ }
+ strcat(mode2, writing ? "w" : "r" );
+ strcat(mode2,"b"); /* binary mode */
+
+ if (open_mode==0) {
+ if (path==NULL || strcmp(path,"")==0) {
+ fp = (writing ? stdout : stdin);
+ SET_BINARY_MODE(fp);
+ } else {
+ fp = fopen(path,mode2);
+ }
+ } else {
+#ifdef BZ_STRICT_ANSI
+ fp = NULL;
+#else
+ fp = fdopen(fd,mode2);
+#endif
+ }
+ if (fp == NULL) return NULL;
+
+ if (writing) {
+ /* Guard against total chaos and anarchy -- JRS */
+ if (blockSize100k < 1) blockSize100k = 1;
+ if (blockSize100k > 9) blockSize100k = 9;
+ bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+ verbosity,workFactor);
+ } else {
+ bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+ unused,nUnused);
+ }
+ if (bzfp == NULL) {
+ if (fp != stdin && fp != stdout) fclose(fp);
+ return NULL;
+ }
+ return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ open file for read or write.
+ ex) bzopen("file","w9")
+ case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+ ( const char *path,
+ const char *mode )
+{
+ return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+ ( int fd,
+ const char *mode )
+{
+ return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+ int bzerr, nread;
+ if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+ nread = BZ2_bzRead(&bzerr,b,buf,len);
+ if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+ return nread;
+ } else {
+ return -1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+ int bzerr;
+
+ BZ2_bzWrite(&bzerr,b,buf,len);
+ if(bzerr == BZ_OK){
+ return len;
+ }else{
+ return -1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+ /* do nothing now... */
+ return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+ int bzerr;
+ FILE *fp;
+
+ if (b==NULL) {return;}
+ fp = ((bzFile *)b)->handle;
+ if(((bzFile*)b)->writing){
+ BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+ if(bzerr != BZ_OK){
+ BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+ }
+ }else{
+ BZ2_bzReadClose(&bzerr,b);
+ }
+ if(fp!=stdin && fp!=stdout){
+ fclose(fp);
+ }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ return last error code
+--*/
+static const char *bzerrorstrings[] = {
+ "OK"
+ ,"SEQUENCE_ERROR"
+ ,"PARAM_ERROR"
+ ,"MEM_ERROR"
+ ,"DATA_ERROR"
+ ,"DATA_ERROR_MAGIC"
+ ,"IO_ERROR"
+ ,"UNEXPECTED_EOF"
+ ,"OUTBUFF_FULL"
+ ,"CONFIG_ERROR"
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+ int err = ((bzFile *)b)->lastErr;
+
+ if(err>0) err = 0;
+ *errnum = err;
+ return bzerrorstrings[err*-1];
+}
+#endif
+
+#endif /* BZ_NO_COMPRESS */
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/bzlib.h b/usr/src/boot/contrib/bzip2/bzlib.h
new file mode 100644
index 0000000000..8277123da8
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library. ---*/
+/*--- bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN 0
+#define BZ_FLUSH 1
+#define BZ_FINISH 2
+
+#define BZ_OK 0
+#define BZ_RUN_OK 1
+#define BZ_FLUSH_OK 2
+#define BZ_FINISH_OK 3
+#define BZ_STREAM_END 4
+#define BZ_SEQUENCE_ERROR (-1)
+#define BZ_PARAM_ERROR (-2)
+#define BZ_MEM_ERROR (-3)
+#define BZ_DATA_ERROR (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR (-6)
+#define BZ_UNEXPECTED_EOF (-7)
+#define BZ_OUTBUFF_FULL (-8)
+#define BZ_CONFIG_ERROR (-9)
+
+typedef
+ struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+ }
+ bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# ifdef small
+ /* windows.h define small to char */
+# undef small
+# endif
+# ifdef BZ_EXPORT
+# define BZ_API(func) WINAPI func
+# define BZ_EXTERN extern
+# else
+ /* import windows dll dynamically */
+# define BZ_API(func) (WINAPI * func)
+# define BZ_EXTERN
+# endif
+#else
+# define BZ_API(func) func
+# define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
+ bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) (
+ bz_stream* strm,
+ int action
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
+ bz_stream *strm,
+ int verbosity,
+ int small
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
+ bz_stream *strm
+ );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
+ int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
+ int* bzerror,
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
+ int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
+ int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32
+ );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity
+ );
+
+
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+ void
+ );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+ const char *path,
+ const char *mode
+ );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+ int fd,
+ const char *mode
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+ BZFILE* b
+ );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+ BZFILE *b,
+ int *errnum
+ );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/bzlib_private.h b/usr/src/boot/contrib/bzip2/bzlib_private.h
new file mode 100644
index 0000000000..5d0217f463
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/bzlib_private.h
@@ -0,0 +1,509 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library. ---*/
+/*--- bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION "1.0.6, 6-Sept-2010"
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef unsigned char UChar;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__ /* */
+#endif
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+ { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+ { if (!(cond)) { \
+ fprintf ( stderr, \
+ "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+ exit(1); \
+ }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+ fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+ fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+ fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+ fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+ fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+ fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+ { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg) do { } while (0)
+#define VPrintf0(zf) do { } while (0)
+#define VPrintf1(zf,za1) do { } while (0)
+#define VPrintf2(zf,za1,za2) do { } while (0)
+#define VPrintf3(zf,za1,za2,za3) do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42 /* 'B' */
+#define BZ_HDR_Z 0x5a /* 'Z' */
+#define BZ_HDR_h 0x68 /* 'h' */
+#define BZ_HDR_0 0x30 /* '0' */
+
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN 23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE 50
+#define BZ_N_ITERS 4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS \
+ Int32 rNToGo; \
+ Int32 rTPos \
+
+#define BZ_RAND_INIT_MASK \
+ s->rNToGo = 0; \
+ s->rTPos = 0 \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK \
+ if (s->rNToGo == 0) { \
+ s->rNToGo = BZ2_rNums[s->rTPos]; \
+ s->rTPos++; \
+ if (s->rTPos == 512) s->rTPos = 0; \
+ } \
+ s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar) \
+{ \
+ crcVar = 0xffffffffL; \
+}
+
+#define BZ_FINALISE_CRC(crcVar) \
+{ \
+ crcVar = ~(crcVar); \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha) \
+{ \
+ crcVar = (crcVar << 8) ^ \
+ BZ2_crc32Table[(crcVar >> 24) ^ \
+ ((UChar)cha)]; \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE 1
+#define BZ_M_RUNNING 2
+#define BZ_M_FLUSHING 3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT 1
+#define BZ_S_INPUT 2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+ struct {
+ /* pointer back to the struct bz_stream */
+ bz_stream* strm;
+
+ /* mode this stream is in, and whether inputting */
+ /* or outputting data */
+ Int32 mode;
+ Int32 state;
+
+ /* remembers avail_in when flush/finish requested */
+ UInt32 avail_in_expect;
+
+ /* for doing the block sorting */
+ UInt32* arr1;
+ UInt32* arr2;
+ UInt32* ftab;
+ Int32 origPtr;
+
+ /* aliases for arr1 and arr2 */
+ UInt32* ptr;
+ UChar* block;
+ UInt16* mtfv;
+ UChar* zbits;
+
+ /* for deciding when to use the fallback sorting algorithm */
+ Int32 workFactor;
+
+ /* run-length-encoding of the input */
+ UInt32 state_in_ch;
+ Int32 state_in_len;
+ BZ_RAND_DECLS;
+
+ /* input and output limits and current posns */
+ Int32 nblock;
+ Int32 nblockMAX;
+ Int32 numZ;
+ Int32 state_out_pos;
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ UChar unseqToSeq[256];
+
+ /* the buffer for bit stream creation */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* block and combined CRCs */
+ UInt32 blockCRC;
+ UInt32 combinedCRC;
+
+ /* misc administratium */
+ Int32 verbosity;
+ Int32 blockNo;
+ Int32 blockSize100k;
+
+ /* stuff for coding the MTF values */
+ Int32 nMTF;
+ Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ /* second dimension: only 3 needed; 4 makes index calculations faster */
+ UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+ }
+ EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void
+BZ2_blockSort ( EState* );
+
+extern void
+BZ2_compressBlock ( EState*, Bool );
+
+extern void
+BZ2_bsInitWrite ( EState* );
+
+extern void
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE 1
+#define BZ_X_OUTPUT 2
+
+#define BZ_X_MAGIC_1 10
+#define BZ_X_MAGIC_2 11
+#define BZ_X_MAGIC_3 12
+#define BZ_X_MAGIC_4 13
+#define BZ_X_BLKHDR_1 14
+#define BZ_X_BLKHDR_2 15
+#define BZ_X_BLKHDR_3 16
+#define BZ_X_BLKHDR_4 17
+#define BZ_X_BLKHDR_5 18
+#define BZ_X_BLKHDR_6 19
+#define BZ_X_BCRC_1 20
+#define BZ_X_BCRC_2 21
+#define BZ_X_BCRC_3 22
+#define BZ_X_BCRC_4 23
+#define BZ_X_RANDBIT 24
+#define BZ_X_ORIGPTR_1 25
+#define BZ_X_ORIGPTR_2 26
+#define BZ_X_ORIGPTR_3 27
+#define BZ_X_MAPPING_1 28
+#define BZ_X_MAPPING_2 29
+#define BZ_X_SELECTOR_1 30
+#define BZ_X_SELECTOR_2 31
+#define BZ_X_SELECTOR_3 32
+#define BZ_X_CODING_1 33
+#define BZ_X_CODING_2 34
+#define BZ_X_CODING_3 35
+#define BZ_X_MTF_1 36
+#define BZ_X_MTF_2 37
+#define BZ_X_MTF_3 38
+#define BZ_X_MTF_4 39
+#define BZ_X_MTF_5 40
+#define BZ_X_MTF_6 41
+#define BZ_X_ENDHDR_2 42
+#define BZ_X_ENDHDR_3 43
+#define BZ_X_ENDHDR_4 44
+#define BZ_X_ENDHDR_5 45
+#define BZ_X_ENDHDR_6 46
+#define BZ_X_CCRC_1 47
+#define BZ_X_CCRC_2 48
+#define BZ_X_CCRC_3 49
+#define BZ_X_CCRC_4 50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+ struct {
+ /* pointer back to the struct bz_stream */
+ bz_stream* strm;
+
+ /* state indicator for this stream */
+ Int32 state;
+
+ /* for doing the final run-length decoding */
+ UChar state_out_ch;
+ Int32 state_out_len;
+ Bool blockRandomised;
+ BZ_RAND_DECLS;
+
+ /* the buffer for bit stream reading */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* misc administratium */
+ Int32 blockSize100k;
+ Bool smallDecompress;
+ Int32 currBlockNo;
+ Int32 verbosity;
+
+ /* for undoing the Burrows-Wheeler transform */
+ Int32 origPtr;
+ UInt32 tPos;
+ Int32 k0;
+ Int32 unzftab[256];
+ Int32 nblock_used;
+ Int32 cftab[257];
+ Int32 cftabCopy[257];
+
+ /* for undoing the Burrows-Wheeler transform (FAST) */
+ UInt32 *tt;
+
+ /* for undoing the Burrows-Wheeler transform (SMALL) */
+ UInt16 *ll16;
+ UChar *ll4;
+
+ /* stored and calculated CRCs */
+ UInt32 storedBlockCRC;
+ UInt32 storedCombinedCRC;
+ UInt32 calculatedBlockCRC;
+ UInt32 calculatedCombinedCRC;
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ Bool inUse16[16];
+ UChar seqToUnseq[256];
+
+ /* for decoding the MTF values */
+ UChar mtfa [MTFA_SIZE];
+ Int32 mtfbase[256 / MTFL_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+ Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 minLens[BZ_N_GROUPS];
+
+ /* save area for scalars in the main decompress code */
+ Int32 save_i;
+ Int32 save_j;
+ Int32 save_t;
+ Int32 save_alphaSize;
+ Int32 save_nGroups;
+ Int32 save_nSelectors;
+ Int32 save_EOB;
+ Int32 save_groupNo;
+ Int32 save_groupPos;
+ Int32 save_nextSym;
+ Int32 save_nblockMAX;
+ Int32 save_nblock;
+ Int32 save_es;
+ Int32 save_N;
+ Int32 save_curr;
+ Int32 save_zt;
+ Int32 save_zn;
+ Int32 save_zvec;
+ Int32 save_zj;
+ Int32 save_gSel;
+ Int32 save_gMinlen;
+ Int32* save_gLimit;
+ Int32* save_gBase;
+ Int32* save_gPerm;
+
+ }
+ DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+ s->tPos = s->tt[s->tPos]; \
+ cccc = (UChar)(s->tPos & 0xff); \
+ s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+ c_tPos = c_tt[c_tPos]; \
+ cccc = (UChar)(c_tPos & 0xff); \
+ c_tPos >>= 8;
+
+#define SET_LL4(i,n) \
+ { if (((i) & 0x1) == 0) \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
+ }
+
+#define GET_LL4(i) \
+ ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n) \
+ { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
+ SET_LL4(i, n >> 16); \
+ }
+
+#define GET_LL(i) \
+ (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+ cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
+ s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32
+BZ2_decompress ( DState* );
+
+extern void
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+ Int32, Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/compress.c b/usr/src/boot/contrib/bzip2/compress.c
new file mode 100644
index 0000000000..caf7696011
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/compress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting) ---*/
+/*--- compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- changed setting of nGroups in sendMTFValues()
+ so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+ s->bsLive = 0;
+ s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+ while (s->bsLive > 0) {
+ s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+ s->numZ++;
+ s->bsBuff <<= 8;
+ s->bsLive -= 8;
+ }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz) \
+{ \
+ while (s->bsLive >= 8) { \
+ s->zbits[s->numZ] \
+ = (UChar)(s->bsBuff >> 24); \
+ s->numZ++; \
+ s->bsBuff <<= 8; \
+ s->bsLive -= 8; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+ bsNEEDW ( n );
+ s->bsBuff |= (v << (32 - s->bsLive - n));
+ s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+ bsW ( s, 8, (u >> 24) & 0xffL );
+ bsW ( s, 8, (u >> 16) & 0xffL );
+ bsW ( s, 8, (u >> 8) & 0xffL );
+ bsW ( s, 8, u & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+ bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+ Int32 i;
+ s->nInUse = 0;
+ for (i = 0; i < 256; i++)
+ if (s->inUse[i]) {
+ s->unseqToSeq[i] = s->nInUse;
+ s->nInUse++;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+ UChar yy[256];
+ Int32 i, j;
+ Int32 zPend;
+ Int32 wr;
+ Int32 EOB;
+
+ /*
+ After sorting (eg, here),
+ s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+ and
+ ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
+ holds the original block data.
+
+ The first thing to do is generate the MTF values,
+ and put them in
+ ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+ Because there are strictly fewer or equal MTF values
+ than block values, ptr values in this area are overwritten
+ with MTF values only when they are no longer needed.
+
+ The final compressed bitstream is generated into the
+ area starting at
+ (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+ These storage aliases are set up in bzCompressInit(),
+ except for the last one, which is arranged in
+ compressBlock().
+ */
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt16* mtfv = s->mtfv;
+
+ makeMaps_e ( s );
+ EOB = s->nInUse+1;
+
+ for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+ wr = 0;
+ zPend = 0;
+ for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+ for (i = 0; i < s->nblock; i++) {
+ UChar ll_i;
+ AssertD ( wr <= i, "generateMTFValues(1)" );
+ j = ptr[i]-1; if (j < 0) j += s->nblock;
+ ll_i = s->unseqToSeq[block[j]];
+ AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+ if (yy[0] == ll_i) {
+ zPend++;
+ } else {
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+ {
+ register UChar rtmp;
+ register UChar* ryy_j;
+ register UChar rll_i;
+ rtmp = yy[1];
+ yy[1] = yy[0];
+ ryy_j = &(yy[1]);
+ rll_i = ll_i;
+ while ( rll_i != rtmp ) {
+ register UChar rtmp2;
+ ryy_j++;
+ rtmp2 = rtmp;
+ rtmp = *ryy_j;
+ *ryy_j = rtmp2;
+ };
+ yy[0] = rtmp;
+ j = ryy_j - &(yy[0]);
+ mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+ }
+
+ }
+ }
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+
+ mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+ s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST 0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+ Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+ Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+ Int32 nGroups, nBytes;
+
+ /*--
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ is a global since the decoder also needs it.
+
+ Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ are also globals only used in this proc.
+ Made global to keep stack frame size small.
+ --*/
+
+
+ UInt16 cost[BZ_N_GROUPS];
+ Int32 fave[BZ_N_GROUPS];
+
+ UInt16* mtfv = s->mtfv;
+
+ if (s->verbosity >= 3)
+ VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
+ "%d+2 syms in use\n",
+ s->nblock, s->nMTF, s->nInUse );
+
+ alphaSize = s->nInUse+2;
+ for (t = 0; t < BZ_N_GROUPS; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->len[t][v] = BZ_GREATER_ICOST;
+
+ /*--- Decide how many coding tables to use ---*/
+ AssertH ( s->nMTF > 0, 3001 );
+ if (s->nMTF < 200) nGroups = 2; else
+ if (s->nMTF < 600) nGroups = 3; else
+ if (s->nMTF < 1200) nGroups = 4; else
+ if (s->nMTF < 2400) nGroups = 5; else
+ nGroups = 6;
+
+ /*--- Generate an initial set of coding tables ---*/
+ {
+ Int32 nPart, remF, tFreq, aFreq;
+
+ nPart = nGroups;
+ remF = s->nMTF;
+ gs = 0;
+ while (nPart > 0) {
+ tFreq = remF / nPart;
+ ge = gs-1;
+ aFreq = 0;
+ while (aFreq < tFreq && ge < alphaSize-1) {
+ ge++;
+ aFreq += s->mtfFreq[ge];
+ }
+
+ if (ge > gs
+ && nPart != nGroups && nPart != 1
+ && ((nGroups-nPart) % 2 == 1)) {
+ aFreq -= s->mtfFreq[ge];
+ ge--;
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf5( " initial group %d, [%d .. %d], "
+ "has %d syms (%4.1f%%)\n",
+ nPart, gs, ge, aFreq,
+ (100.0 * (float)aFreq) / (float)(s->nMTF) );
+
+ for (v = 0; v < alphaSize; v++)
+ if (v >= gs && v <= ge)
+ s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+ s->len[nPart-1][v] = BZ_GREATER_ICOST;
+
+ nPart--;
+ gs = ge+1;
+ remF -= aFreq;
+ }
+ }
+
+ /*---
+ Iterate up to BZ_N_ITERS times to improve the tables.
+ ---*/
+ for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+ for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+ for (t = 0; t < nGroups; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->rfreq[t][v] = 0;
+
+ /*---
+ Set up an auxiliary length table which is used to fast-track
+ the common case (nGroups == 6).
+ ---*/
+ if (nGroups == 6) {
+ for (v = 0; v < alphaSize; v++) {
+ s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+ s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+ s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+ }
+ }
+
+ nSelectors = 0;
+ totc = 0;
+ gs = 0;
+ while (True) {
+
+ /*--- Set group start & end marks. --*/
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+
+ /*--
+ Calculate the cost of this group as coded
+ by each of the coding tables.
+ --*/
+ for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ register UInt32 cost01, cost23, cost45;
+ register UInt16 icv;
+ cost01 = cost23 = cost45 = 0;
+
+# define BZ_ITER(nn) \
+ icv = mtfv[gs+(nn)]; \
+ cost01 += s->len_pack[icv][0]; \
+ cost23 += s->len_pack[icv][1]; \
+ cost45 += s->len_pack[icv][2]; \
+
+ BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
+ BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
+ BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+ BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+ BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+ BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+ BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+ BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+ BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+ BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+# undef BZ_ITER
+
+ cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+ cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+ cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ UInt16 icv = mtfv[i];
+ for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+ }
+ }
+
+ /*--
+ Find the coding table which is best for this group,
+ and record its identity in the selector table.
+ --*/
+ bc = 999999999; bt = -1;
+ for (t = 0; t < nGroups; t++)
+ if (cost[t] < bc) { bc = cost[t]; bt = t; };
+ totc += bc;
+ fave[bt]++;
+ s->selector[nSelectors] = bt;
+ nSelectors++;
+
+ /*--
+ Increment the symbol frequencies for the selected table.
+ --*/
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+
+# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+ BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
+ BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
+ BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+ BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+ BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+ BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+ BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+ BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+ BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+ BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+# undef BZ_ITUR
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++)
+ s->rfreq[bt][ mtfv[i] ]++;
+ }
+
+ gs = ge+1;
+ }
+ if (s->verbosity >= 3) {
+ VPrintf2 ( " pass %d: size is %d, grp uses are ",
+ iter+1, totc/8 );
+ for (t = 0; t < nGroups; t++)
+ VPrintf1 ( "%d ", fave[t] );
+ VPrintf0 ( "\n" );
+ }
+
+ /*--
+ Recompute the tables based on the accumulated frequencies.
+ --*/
+ /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
+ comment in huffman.c for details. */
+ for (t = 0; t < nGroups; t++)
+ BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
+ alphaSize, 17 /*20*/ );
+ }
+
+
+ AssertH( nGroups < 8, 3002 );
+ AssertH( nSelectors < 32768 &&
+ nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+ 3003 );
+
+
+ /*--- Compute MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+ for (i = 0; i < nGroups; i++) pos[i] = i;
+ for (i = 0; i < nSelectors; i++) {
+ ll_i = s->selector[i];
+ j = 0;
+ tmp = pos[j];
+ while ( ll_i != tmp ) {
+ j++;
+ tmp2 = tmp;
+ tmp = pos[j];
+ pos[j] = tmp2;
+ };
+ pos[0] = tmp;
+ s->selectorMtf[i] = j;
+ }
+ };
+
+ /*--- Assign actual codes for the tables. --*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+ AssertH ( !(minLen < 1), 3005 );
+ BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
+ minLen, maxLen, alphaSize );
+ }
+
+ /*--- Transmit the mapping table. ---*/
+ {
+ Bool inUse16[16];
+ for (i = 0; i < 16; i++) {
+ inUse16[i] = False;
+ for (j = 0; j < 16; j++)
+ if (s->inUse[i * 16 + j]) inUse16[i] = True;
+ }
+
+ nBytes = s->numZ;
+ for (i = 0; i < 16; i++)
+ if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+ for (i = 0; i < 16; i++)
+ if (inUse16[i])
+ for (j = 0; j < 16; j++) {
+ if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
+ }
+
+ /*--- Now the selectors. ---*/
+ nBytes = s->numZ;
+ bsW ( s, 3, nGroups );
+ bsW ( s, 15, nSelectors );
+ for (i = 0; i < nSelectors; i++) {
+ for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+ bsW(s,1,0);
+ }
+ if (s->verbosity >= 3)
+ VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+ /*--- Now the coding tables. ---*/
+ nBytes = s->numZ;
+
+ for (t = 0; t < nGroups; t++) {
+ Int32 curr = s->len[t][0];
+ bsW ( s, 5, curr );
+ for (i = 0; i < alphaSize; i++) {
+ while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+ while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+ bsW ( s, 1, 0 );
+ }
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+ /*--- And finally, the block data proper ---*/
+ nBytes = s->numZ;
+ selCtr = 0;
+ gs = 0;
+ while (True) {
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+ AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ UInt16 mtfv_i;
+ UChar* s_len_sel_selCtr
+ = &(s->len[s->selector[selCtr]][0]);
+ Int32* s_code_sel_selCtr
+ = &(s->code[s->selector[selCtr]][0]);
+
+# define BZ_ITAH(nn) \
+ mtfv_i = mtfv[gs+(nn)]; \
+ bsW ( s, \
+ s_len_sel_selCtr[mtfv_i], \
+ s_code_sel_selCtr[mtfv_i] )
+
+ BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
+ BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
+ BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+ BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+ BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+ BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+ BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+ BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+ BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+ BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+# undef BZ_ITAH
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ bsW ( s,
+ s->len [s->selector[selCtr]] [mtfv[i]],
+ s->code [s->selector[selCtr]] [mtfv[i]] );
+ }
+ }
+
+
+ gs = ge+1;
+ selCtr++;
+ }
+ AssertH( selCtr == nSelectors, 3007 );
+
+ if (s->verbosity >= 3)
+ VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+ if (s->nblock > 0) {
+
+ BZ_FINALISE_CRC ( s->blockCRC );
+ s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+ s->combinedCRC ^= s->blockCRC;
+ if (s->blockNo > 1) s->numZ = 0;
+
+ if (s->verbosity >= 2)
+ VPrintf4( " block %d: crc = 0x%08x, "
+ "combined CRC = 0x%08x, size = %d\n",
+ s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+ BZ2_blockSort ( s );
+ }
+
+ s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+ /*-- If this is the first block, create the stream header. --*/
+ if (s->blockNo == 1) {
+ BZ2_bsInitWrite ( s );
+ bsPutUChar ( s, BZ_HDR_B );
+ bsPutUChar ( s, BZ_HDR_Z );
+ bsPutUChar ( s, BZ_HDR_h );
+ bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+ }
+
+ if (s->nblock > 0) {
+
+ bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+ bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+ bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+ /*-- Now the block's CRC, so it is in a known place. --*/
+ bsPutUInt32 ( s, s->blockCRC );
+
+ /*--
+ Now a single bit indicating (non-)randomisation.
+ As of version 0.9.5, we use a better sorting algorithm
+ which makes randomisation unnecessary. So always set
+ the randomised bit to 'no'. Of course, the decoder
+ still needs to be able to handle randomised blocks
+ so as to maintain backwards compatibility with
+ older versions of bzip2.
+ --*/
+ bsW(s,1,0);
+
+ bsW ( s, 24, s->origPtr );
+ generateMTFValues ( s );
+ sendMTFValues ( s );
+ }
+
+
+ /*-- If this is the last block, add the stream trailer. --*/
+ if (is_last_block) {
+
+ bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+ bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+ bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+ bsPutUInt32 ( s, s->combinedCRC );
+ if (s->verbosity >= 2)
+ VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
+ bsFinishWrite ( s );
+ }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/crctable.c b/usr/src/boot/contrib/bzip2/crctable.c
new file mode 100644
index 0000000000..1fea7e946c
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs ---*/
+/*--- crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+ I think this is an implementation of the AUTODIN-II,
+ Ethernet & FDDI 32-bit CRC standard. Vaguely derived
+ from code by Rob Warnock, in Section 51 of the
+ comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+ /*-- Ugly, innit? --*/
+
+ 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+ 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+ 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+ 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+ 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+ 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+ 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+ 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+ 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+ 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+ 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+ 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+ 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+ 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+ 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+ 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+ 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+ 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+ 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+ 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+ 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+ 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+ 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+ 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+ 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+ 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+ 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+ 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+ 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+ 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+ 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+ 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+ 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+ 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+ 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+ 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+ 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+ 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+ 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+ 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+ 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+ 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+ 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+ 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+ 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+ 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+ 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+ 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+ 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+ 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+ 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+ 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+ 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+ 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+ 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+ 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+ 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+ 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+ 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+ 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+ 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+ 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+ 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+ 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/decompress.c b/usr/src/boot/contrib/bzip2/decompress.c
new file mode 100644
index 0000000000..311f5668f9
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/decompress.c
@@ -0,0 +1,646 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery ---*/
+/*--- decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+ Int32 i;
+ s->nInUse = 0;
+ for (i = 0; i < 256; i++)
+ if (s->inUse[i]) {
+ s->seqToUnseq[s->nInUse] = i;
+ s->nInUse++;
+ }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr) \
+ { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn) \
+ case lll: s->state = lll; \
+ while (True) { \
+ if (s->bsLive >= nnn) { \
+ UInt32 v; \
+ v = (s->bsBuff >> \
+ (s->bsLive-nnn)) & ((1 << nnn)-1); \
+ s->bsLive -= nnn; \
+ vvv = v; \
+ break; \
+ } \
+ if (s->strm->avail_in == 0) RETURN(BZ_OK); \
+ s->bsBuff \
+ = (s->bsBuff << 8) | \
+ ((UInt32) \
+ (*((UChar*)(s->strm->next_in)))); \
+ s->bsLive += 8; \
+ s->strm->next_in++; \
+ s->strm->avail_in--; \
+ s->strm->total_in_lo32++; \
+ if (s->strm->total_in_lo32 == 0) \
+ s->strm->total_in_hi32++; \
+ }
+
+#define GET_UCHAR(lll,uuu) \
+ GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu) \
+ GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval) \
+{ \
+ if (groupPos == 0) { \
+ groupNo++; \
+ if (groupNo >= nSelectors) \
+ RETURN(BZ_DATA_ERROR); \
+ groupPos = BZ_G_SIZE; \
+ gSel = s->selector[groupNo]; \
+ gMinlen = s->minLens[gSel]; \
+ gLimit = &(s->limit[gSel][0]); \
+ gPerm = &(s->perm[gSel][0]); \
+ gBase = &(s->base[gSel][0]); \
+ } \
+ groupPos--; \
+ zn = gMinlen; \
+ GET_BITS(label1, zvec, zn); \
+ while (1) { \
+ if (zn > 20 /* the longest code */) \
+ RETURN(BZ_DATA_ERROR); \
+ if (zvec <= gLimit[zn]) break; \
+ zn++; \
+ GET_BIT(label2, zj); \
+ zvec = (zvec << 1) | zj; \
+ }; \
+ if (zvec - gBase[zn] < 0 \
+ || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
+ RETURN(BZ_DATA_ERROR); \
+ lval = gPerm[zvec - gBase[zn]]; \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+ UChar uc;
+ Int32 retVal;
+ Int32 minLen, maxLen;
+ bz_stream* strm = s->strm;
+
+ /* stuff that needs to be saved/restored */
+ Int32 i;
+ Int32 j;
+ Int32 t;
+ Int32 alphaSize;
+ Int32 nGroups;
+ Int32 nSelectors;
+ Int32 EOB;
+ Int32 groupNo;
+ Int32 groupPos;
+ Int32 nextSym;
+ Int32 nblockMAX;
+ Int32 nblock;
+ Int32 es;
+ Int32 N;
+ Int32 curr;
+ Int32 zt;
+ Int32 zn;
+ Int32 zvec;
+ Int32 zj;
+ Int32 gSel;
+ Int32 gMinlen;
+ Int32* gLimit;
+ Int32* gBase;
+ Int32* gPerm;
+
+ if (s->state == BZ_X_MAGIC_1) {
+ /*initialise the save area*/
+ s->save_i = 0;
+ s->save_j = 0;
+ s->save_t = 0;
+ s->save_alphaSize = 0;
+ s->save_nGroups = 0;
+ s->save_nSelectors = 0;
+ s->save_EOB = 0;
+ s->save_groupNo = 0;
+ s->save_groupPos = 0;
+ s->save_nextSym = 0;
+ s->save_nblockMAX = 0;
+ s->save_nblock = 0;
+ s->save_es = 0;
+ s->save_N = 0;
+ s->save_curr = 0;
+ s->save_zt = 0;
+ s->save_zn = 0;
+ s->save_zvec = 0;
+ s->save_zj = 0;
+ s->save_gSel = 0;
+ s->save_gMinlen = 0;
+ s->save_gLimit = NULL;
+ s->save_gBase = NULL;
+ s->save_gPerm = NULL;
+ }
+
+ /*restore from the save area*/
+ i = s->save_i;
+ j = s->save_j;
+ t = s->save_t;
+ alphaSize = s->save_alphaSize;
+ nGroups = s->save_nGroups;
+ nSelectors = s->save_nSelectors;
+ EOB = s->save_EOB;
+ groupNo = s->save_groupNo;
+ groupPos = s->save_groupPos;
+ nextSym = s->save_nextSym;
+ nblockMAX = s->save_nblockMAX;
+ nblock = s->save_nblock;
+ es = s->save_es;
+ N = s->save_N;
+ curr = s->save_curr;
+ zt = s->save_zt;
+ zn = s->save_zn;
+ zvec = s->save_zvec;
+ zj = s->save_zj;
+ gSel = s->save_gSel;
+ gMinlen = s->save_gMinlen;
+ gLimit = s->save_gLimit;
+ gBase = s->save_gBase;
+ gPerm = s->save_gPerm;
+
+ retVal = BZ_OK;
+
+ switch (s->state) {
+
+ GET_UCHAR(BZ_X_MAGIC_1, uc);
+ if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_UCHAR(BZ_X_MAGIC_2, uc);
+ if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_UCHAR(BZ_X_MAGIC_3, uc)
+ if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+ if (s->blockSize100k < (BZ_HDR_0 + 1) ||
+ s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+ s->blockSize100k -= BZ_HDR_0;
+
+ if (s->smallDecompress) {
+ s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+ s->ll4 = BZALLOC(
+ ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
+ );
+ if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+ } else {
+ s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+ if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+ }
+
+ GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+ if (uc == 0x17) goto endhdr_2;
+ if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_2, uc);
+ if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_3, uc);
+ if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_4, uc);
+ if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_5, uc);
+ if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_6, uc);
+ if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+ s->currBlockNo++;
+ if (s->verbosity >= 2)
+ VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
+
+ s->storedBlockCRC = 0;
+ GET_UCHAR(BZ_X_BCRC_1, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_2, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_3, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_4, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+ GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+ s->origPtr = 0;
+ GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+ if (s->origPtr < 0)
+ RETURN(BZ_DATA_ERROR);
+ if (s->origPtr > 10 + 100000*s->blockSize100k)
+ RETURN(BZ_DATA_ERROR);
+
+ /*--- Receive the mapping table ---*/
+ for (i = 0; i < 16; i++) {
+ GET_BIT(BZ_X_MAPPING_1, uc);
+ if (uc == 1)
+ s->inUse16[i] = True; else
+ s->inUse16[i] = False;
+ }
+
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+ for (i = 0; i < 16; i++)
+ if (s->inUse16[i])
+ for (j = 0; j < 16; j++) {
+ GET_BIT(BZ_X_MAPPING_2, uc);
+ if (uc == 1) s->inUse[i * 16 + j] = True;
+ }
+ makeMaps_d ( s );
+ if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+ alphaSize = s->nInUse+2;
+
+ /*--- Now the selectors ---*/
+ GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+ if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+ GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+ if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+ for (i = 0; i < nSelectors; i++) {
+ j = 0;
+ while (True) {
+ GET_BIT(BZ_X_SELECTOR_3, uc);
+ if (uc == 0) break;
+ j++;
+ if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+ }
+ s->selectorMtf[i] = j;
+ }
+
+ /*--- Undo the MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], tmp, v;
+ for (v = 0; v < nGroups; v++) pos[v] = v;
+
+ for (i = 0; i < nSelectors; i++) {
+ v = s->selectorMtf[i];
+ tmp = pos[v];
+ while (v > 0) { pos[v] = pos[v-1]; v--; }
+ pos[0] = tmp;
+ s->selector[i] = tmp;
+ }
+ }
+
+ /*--- Now the coding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ GET_BITS(BZ_X_CODING_1, curr, 5);
+ for (i = 0; i < alphaSize; i++) {
+ while (True) {
+ if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+ GET_BIT(BZ_X_CODING_2, uc);
+ if (uc == 0) break;
+ GET_BIT(BZ_X_CODING_3, uc);
+ if (uc == 0) curr++; else curr--;
+ }
+ s->len[t][i] = curr;
+ }
+ }
+
+ /*--- Create the Huffman decoding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ BZ2_hbCreateDecodeTables (
+ &(s->limit[t][0]),
+ &(s->base[t][0]),
+ &(s->perm[t][0]),
+ &(s->len[t][0]),
+ minLen, maxLen, alphaSize
+ );
+ s->minLens[t] = minLen;
+ }
+
+ /*--- Now the MTF values ---*/
+
+ EOB = s->nInUse+1;
+ nblockMAX = 100000 * s->blockSize100k;
+ groupNo = -1;
+ groupPos = 0;
+
+ for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+ /*-- MTF init --*/
+ {
+ Int32 ii, jj, kk;
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ /*-- end MTF init --*/
+
+ nblock = 0;
+ GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+ while (True) {
+
+ if (nextSym == EOB) break;
+
+ if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+ es = -1;
+ N = 1;
+ do {
+ /* Check that N doesn't get too big, so that es doesn't
+ go negative. The maximum value that can be
+ RUNA/RUNB encoded is equal to the block size (post
+ the initial RLE), viz, 900k, so bounding N at 2
+ million should guard against overflow without
+ rejecting any legitimate inputs. */
+ if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
+ if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+ if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+ N = N * 2;
+ GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+ }
+ while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+ es++;
+ uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+ s->unzftab[uc] += es;
+
+ if (s->smallDecompress)
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->ll16[nblock] = (UInt16)uc;
+ nblock++;
+ es--;
+ }
+ else
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->tt[nblock] = (UInt32)uc;
+ nblock++;
+ es--;
+ };
+
+ continue;
+
+ } else {
+
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+ /*-- uc = MTF ( nextSym-1 ) --*/
+ {
+ Int32 ii, jj, kk, pp, lno, off;
+ UInt32 nn;
+ nn = (UInt32)(nextSym - 1);
+
+ if (nn < MTFL_SIZE) {
+ /* avoid general-case expense */
+ pp = s->mtfbase[0];
+ uc = s->mtfa[pp+nn];
+ while (nn > 3) {
+ Int32 z = pp+nn;
+ s->mtfa[(z) ] = s->mtfa[(z)-1];
+ s->mtfa[(z)-1] = s->mtfa[(z)-2];
+ s->mtfa[(z)-2] = s->mtfa[(z)-3];
+ s->mtfa[(z)-3] = s->mtfa[(z)-4];
+ nn -= 4;
+ }
+ while (nn > 0) {
+ s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
+ };
+ s->mtfa[pp] = uc;
+ } else {
+ /* general case */
+ lno = nn / MTFL_SIZE;
+ off = nn % MTFL_SIZE;
+ pp = s->mtfbase[lno] + off;
+ uc = s->mtfa[pp];
+ while (pp > s->mtfbase[lno]) {
+ s->mtfa[pp] = s->mtfa[pp-1]; pp--;
+ };
+ s->mtfbase[lno]++;
+ while (lno > 0) {
+ s->mtfbase[lno]--;
+ s->mtfa[s->mtfbase[lno]]
+ = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+ lno--;
+ }
+ s->mtfbase[0]--;
+ s->mtfa[s->mtfbase[0]] = uc;
+ if (s->mtfbase[0] == 0) {
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ }
+ }
+ /*-- end uc = MTF ( nextSym-1 ) --*/
+
+ s->unzftab[s->seqToUnseq[uc]]++;
+ if (s->smallDecompress)
+ s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+ s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
+ nblock++;
+
+ GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+ continue;
+ }
+ }
+
+ /* Now we know what nblock is, we can do a better sanity
+ check on s->origPtr.
+ */
+ if (s->origPtr < 0 || s->origPtr >= nblock)
+ RETURN(BZ_DATA_ERROR);
+
+ /*-- Set up cftab to facilitate generation of T^(-1) --*/
+ /* Check: unzftab entries in range. */
+ for (i = 0; i <= 255; i++) {
+ if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+ RETURN(BZ_DATA_ERROR);
+ }
+ /* Actually generate cftab. */
+ s->cftab[0] = 0;
+ for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+ for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+ /* Check: cftab entries in range. */
+ for (i = 0; i <= 256; i++) {
+ if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+ /* s->cftab[i] can legitimately be == nblock */
+ RETURN(BZ_DATA_ERROR);
+ }
+ }
+ /* Check: cftab entries non-descending. */
+ for (i = 1; i <= 256; i++) {
+ if (s->cftab[i-1] > s->cftab[i]) {
+ RETURN(BZ_DATA_ERROR);
+ }
+ }
+
+ s->state_out_len = 0;
+ s->state_out_ch = 0;
+ BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+ s->state = BZ_X_OUTPUT;
+ if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+ if (s->smallDecompress) {
+
+ /*-- Make a copy of cftab, used in generation of T --*/
+ for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+ /*-- compute the T vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->ll16[i]);
+ SET_LL(i, s->cftabCopy[uc]);
+ s->cftabCopy[uc]++;
+ }
+
+ /*-- Compute T^(-1) by pointer reversal on T --*/
+ i = s->origPtr;
+ j = GET_LL(i);
+ do {
+ Int32 tmp = GET_LL(j);
+ SET_LL(j, i);
+ i = j;
+ j = tmp;
+ }
+ while (i != s->origPtr);
+
+ s->tPos = s->origPtr;
+ s->nblock_used = 0;
+ if (s->blockRandomised) {
+ BZ_RAND_INIT_MASK;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
+ } else {
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+
+ } else {
+
+ /*-- compute the T^(-1) vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->tt[i] & 0xff);
+ s->tt[s->cftab[uc]] |= (i << 8);
+ s->cftab[uc]++;
+ }
+
+ s->tPos = s->tt[s->origPtr] >> 8;
+ s->nblock_used = 0;
+ if (s->blockRandomised) {
+ BZ_RAND_INIT_MASK;
+ BZ_GET_FAST(s->k0); s->nblock_used++;
+ BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
+ } else {
+ BZ_GET_FAST(s->k0); s->nblock_used++;
+ }
+
+ }
+
+ RETURN(BZ_OK);
+
+
+
+ endhdr_2:
+
+ GET_UCHAR(BZ_X_ENDHDR_2, uc);
+ if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_3, uc);
+ if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_4, uc);
+ if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_5, uc);
+ if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_6, uc);
+ if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+ s->storedCombinedCRC = 0;
+ GET_UCHAR(BZ_X_CCRC_1, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_2, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_3, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_4, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+ s->state = BZ_X_IDLE;
+ RETURN(BZ_STREAM_END);
+
+ default: AssertH ( False, 4001 );
+ }
+
+ AssertH ( False, 4002 );
+
+ save_state_and_return:
+
+ s->save_i = i;
+ s->save_j = j;
+ s->save_t = t;
+ s->save_alphaSize = alphaSize;
+ s->save_nGroups = nGroups;
+ s->save_nSelectors = nSelectors;
+ s->save_EOB = EOB;
+ s->save_groupNo = groupNo;
+ s->save_groupPos = groupPos;
+ s->save_nextSym = nextSym;
+ s->save_nblockMAX = nblockMAX;
+ s->save_nblock = nblock;
+ s->save_es = es;
+ s->save_N = N;
+ s->save_curr = curr;
+ s->save_zt = zt;
+ s->save_zn = zn;
+ s->save_zvec = zvec;
+ s->save_zj = zj;
+ s->save_gSel = gSel;
+ s->save_gMinlen = gMinlen;
+ s->save_gLimit = gLimit;
+ s->save_gBase = gBase;
+ s->save_gPerm = gPerm;
+
+ return retVal;
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/huffman.c b/usr/src/boot/contrib/bzip2/huffman.c
new file mode 100644
index 0000000000..2283fdbc5a
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff ---*/
+/*--- huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2) \
+ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
+ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z) \
+{ \
+ Int32 zz, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (weight[tmp] < weight[heap[zz >> 1]]) { \
+ heap[zz] = heap[zz >> 1]; \
+ zz >>= 1; \
+ } \
+ heap[zz] = tmp; \
+}
+
+#define DOWNHEAP(z) \
+{ \
+ Int32 zz, yy, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (True) { \
+ yy = zz << 1; \
+ if (yy > nHeap) break; \
+ if (yy < nHeap && \
+ weight[heap[yy+1]] < weight[heap[yy]]) \
+ yy++; \
+ if (weight[tmp] < weight[heap[yy]]) break; \
+ heap[zz] = heap[yy]; \
+ zz = yy; \
+ } \
+ heap[zz] = tmp; \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len,
+ Int32 *freq,
+ Int32 alphaSize,
+ Int32 maxLen )
+{
+ /*--
+ Nodes and heap entries run from 1. Entry 0
+ for both the heap and nodes is a sentinel.
+ --*/
+ Int32 nNodes, nHeap, n1, n2, i, j, k;
+ Bool tooLong;
+
+ Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
+ Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+ Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
+
+ for (i = 0; i < alphaSize; i++)
+ weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+ while (True) {
+
+ nNodes = alphaSize;
+ nHeap = 0;
+
+ heap[0] = 0;
+ weight[0] = 0;
+ parent[0] = -2;
+
+ for (i = 1; i <= alphaSize; i++) {
+ parent[i] = -1;
+ nHeap++;
+ heap[nHeap] = i;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+
+ while (nHeap > 1) {
+ n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ nNodes++;
+ parent[n1] = parent[n2] = nNodes;
+ weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+ parent[nNodes] = -1;
+ nHeap++;
+ heap[nHeap] = nNodes;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+ tooLong = False;
+ for (i = 1; i <= alphaSize; i++) {
+ j = 0;
+ k = i;
+ while (parent[k] >= 0) { k = parent[k]; j++; }
+ len[i-1] = j;
+ if (j > maxLen) tooLong = True;
+ }
+
+ if (! tooLong) break;
+
+ /* 17 Oct 04: keep-going condition for the following loop used
+ to be 'i < alphaSize', which missed the last element,
+ theoretically leading to the possibility of the compressor
+ looping. However, this count-scaling step is only needed if
+ one of the generated Huffman code words is longer than
+ maxLen, which up to and including version 1.0.2 was 20 bits,
+ which is extremely unlikely. In version 1.0.3 maxLen was
+ changed to 17 bits, which has minimal effect on compression
+ ratio, but does mean this scaling step is used from time to
+ time, enough to verify that it works.
+
+ This means that bzip2-1.0.3 and later will only produce
+ Huffman codes with a maximum length of 17 bits. However, in
+ order to preserve backwards compatibility with bitstreams
+ produced by versions pre-1.0.3, the decompressor must still
+ handle lengths of up to 20. */
+
+ for (i = 1; i <= alphaSize; i++) {
+ j = weight[i] >> 8;
+ j = 1 + (j / 2);
+ weight[i] = j << 8;
+ }
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 n, vec, i;
+
+ vec = 0;
+ for (n = minLen; n <= maxLen; n++) {
+ for (i = 0; i < alphaSize; i++)
+ if (length[i] == n) { code[i] = vec; vec++; };
+ vec <<= 1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+ Int32 *base,
+ Int32 *perm,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 pp, i, j, vec;
+
+ pp = 0;
+ for (i = minLen; i <= maxLen; i++)
+ for (j = 0; j < alphaSize; j++)
+ if (length[j] == i) { perm[pp] = j; pp++; };
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+ for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+ for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+ vec = 0;
+
+ for (i = minLen; i <= maxLen; i++) {
+ vec += (base[i+1] - base[i]);
+ limit[i] = vec-1;
+ vec <<= 1;
+ }
+ for (i = minLen + 1; i <= maxLen; i++)
+ base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/libbz2.def b/usr/src/boot/contrib/bzip2/libbz2.def
new file mode 100644
index 0000000000..4f83fcc610
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/libbz2.def
@@ -0,0 +1,27 @@
+LIBRARY LIBBZ2
+DESCRIPTION "libbzip2: library for data compression"
+EXPORTS
+ BZ2_bzCompressInit
+ BZ2_bzCompress
+ BZ2_bzCompressEnd
+ BZ2_bzDecompressInit
+ BZ2_bzDecompress
+ BZ2_bzDecompressEnd
+ BZ2_bzReadOpen
+ BZ2_bzReadClose
+ BZ2_bzReadGetUnused
+ BZ2_bzRead
+ BZ2_bzWriteOpen
+ BZ2_bzWrite
+ BZ2_bzWriteClose
+ BZ2_bzWriteClose64
+ BZ2_bzBuffToBuffCompress
+ BZ2_bzBuffToBuffDecompress
+ BZ2_bzlibVersion
+ BZ2_bzopen
+ BZ2_bzdopen
+ BZ2_bzread
+ BZ2_bzwrite
+ BZ2_bzflush
+ BZ2_bzclose
+ BZ2_bzerror
diff --git a/usr/src/boot/contrib/bzip2/randtable.c b/usr/src/boot/contrib/bzip2/randtable.c
new file mode 100644
index 0000000000..6d62459906
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks ---*/
+/*--- randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = {
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
+ 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
+ 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
+ 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
+ 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
+ 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
+ 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
+ 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
+ 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
+ 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
+ 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
+ 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
+ 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
+ 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
+ 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
+ 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
+ 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
+ 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
+ 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
+ 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
+ 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
+ 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
+ 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
+ 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
+ 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
+ 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
+ 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
+ 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
+ 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
+ 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
+ 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
+ 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
+ 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
+ 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
+ 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
+ 936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/contrib/bzip2/sample1.bz2.uu b/usr/src/boot/contrib/bzip2/sample1.bz2.uu
new file mode 100644
index 0000000000..544568031a
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample1.bz2.uu
@@ -0,0 +1,722 @@
+begin 644 sample1.bz2
+M0EIH,3%!62936<SQM:4`OJ;_____________________________________
+M________X)3?>``^"5D```4[8=N[8K7,-JP,#+WT`WUMF`[!Z#H>Z]G#Z!`$
+M``&]F(!NO=V[[M9NCTWNY[8+SDJPX]LV]K.-S+;KAZ-ZL2V8*;.;77MW;VVY
+M<Z=;<KNX=;`!B(0#3707KV-OK'VU;'D[L^AH#L\MTTF[Q[5O>![U3J;CKVY>
+M\YVVWMWO&V7L-Y[M$'&]!PCH&04`HUY\]VFG;-C"?8WPIWN^ONQOM?6^^^/1
+MO*SK10%$ADGQ7`:;'-UKT/24A0V\]MZ?7OC;Y];=[SO;W<NO>=U-O.57L]5/
+M=N>K8(O1\OO;P^M\^0LKXN=W6^`!YY0>;#);![[YOO7VNVSU#H^@*`Q5;8S'
+MUIUUT((&@Z``&]M7#[83W@`6P'U0KW6XQ8:T%="V!09>]R3<%]5![-K&A-C`
+M`"]C4^]W,$;9@)6UCTU="4TB!`$TTT`":!HT$P$TT&F09$PTT9#0"9,"8FFR
+M4ST4\`*GY,3*>:%/3313\(T4_(:1Z8B9B:9/13::,4\B/(GJ;31IHF:-$84&
+MIZ`@(($@!`D>A4]Z2>)ZC$8*;5,U/4_43U-J'J``&@#$T`-``>H`>HT::`&@
+M'J`````````#1D```TQ$$(")IJ8(;5--&DGH;4/29-(T,T&D>IF:IIIZFCTF
+MGZIB&T33U/2,@-&GI,``"9,:$8AH9&3$80R8F`3333$T-`&C33$T&02:2(A`
+M01H"3$IXD_3(:!JF]4\HTT]3TTTCR>BFC$/U(]3R@>HVH:::9&CU&F@_5&F0
+M>B::>H`-#0;4`!Z@/4T/4#0`]0>H>H:::8CTF@`(E(FA">DPFJG^FJ>U,)IH
+MTD_0--39-$\B:GHT](]3U)@--,RFGI/4]3:*9/R3U,DVIX2'J;:1Z3TIZFT,
+MRIO2-1XB>D]&C3U#330:`T:>IM)/4]/34TT)ZC1[13-,U$$B(0(!`"$\DP!-
+M&43RI^FD]&IZ:IX-&)I3TG^JFQ,1/:DT\2>4-'HRF90/%/4&T-1M1^I-'I/4
+M>4/0TT8AJ'J9E--`TR:>4&3]34-,AH/4R>HVH:=\9D)$$ZM>S:PQRS9]&G5H
+MU[-K:V(2/Y"8\C(Q)9!V$HB&:-'42&;`39!PD30DX(`'VXR!]S]4?EFN`3TR
+MZI#2Y485N#3[NW+I<E%2FDQP0S`QA,A+"2I#,Q5%%:UI2HL&*(NFBD8P4BQI
+M:+&*BJ*L1%5AF88*Q"TI]`.(2&&0059NRL%%&;MAEJ+EH@C$MRY<N4JMM2T*
+M(9:L6*1BJP55&**I6I!<:CEHQ1;*VHXT5%@L5'&IF%Q10&(QK1MJY:HJKBT*
+MHHJ8U54&VL%/0=B14:8+JE&I=W!2T2I<18BQ6(B(L%4:(F9BQ9Q]V>^(*P8*
+M+%6+"?N\S$"NN6K^!G2+PF?**'^9`UY!,:(7CH3J3[A6#WQZ4J-T5H'2G.&>
+M-2=B7#IC:(I<#LF+;AA'-E`S4$.`0-1%;3`.JA(I(#(C(FAB`!=^50!=C)$:
+MH"I;(BF^4A`6*AN8B7("'&P6M5@%N,HM`DI;!"0/Q)*,&`L!$0()&04("@A_
+MOV%D2$D5[-%(JQ108Q09(10D"1A(WT%.P>Q6B\E!>^K6O^R""3OW/_[ZS0'#
+M4-22"H@",@XDJ31#1\`)/HDQN>')A%TJ]$V1+&-)*&>W?PP0?X?+7I+[+[VP
+M3PC6GVWGC>+*F46#Z6^(-:L&)_:@J<*EMI^3EQ&(A^YY(&L#0Q8JL3K^4S]I
+M#>_8,KJU:*E_<Y@(P51<:BR?;M%9EO\P$+1<9;041%)6+;1K6TJGUE*JHJ*N
+M4K:4L6V148*7L@2Y22%HE98HJBHE*H51E:EJ-!0BQ5A;:(B%I45J2E1LC%1$
+ME:H,Z#146*>@DB8.E4=-4ME5J(UBE%1&VPK5&,MA1506(BHQ+;+8(V*U610J
+M+6*VHA4H*T?UR5$9@Q1JREI2L6L+:-**1+18I4JH*%&#4L6I4%B4=X8F);0J
+M5K1$48%92T;0:T4$9*Q&VR5@H)0MHB6+`:-%X,IE6@K2UH:$S/VUS+:N[1$1
+M$14RRB6MK4&,;8VE+%;:E%*E$1JVJM8I6*"4A&D4JMLJV86IBN$2X5:,LME&
+M4M:U:WTY`PQ$:E11:J6V5;449+,+\U,1-62]1+/N;K$*VCQEF)RU3/\+6]?@
+M[X)#"F_D^[8!_T6KS/*A2S_2##C82P;;N0TM7XA(!X3^(([YDGIB5D`1#U]`
+MZ?3G,`]G$@<H2=`$2`DBDA!$A)4K)*A`4(*`-GPG[!'$4#C;CIT34HBXJI&H
+M(Q/7F7JN&&:IP=3L,8QM1&@8OK>Y^6Y,_MO@S(;S-8F)M-B(&`-RB0J*L*D[
+MX2=IW3O.[H:?RO,DZ2(2-IU8"))B!1`EM"L`;8H12$%!&$@R`R`L(H`L@2H"
+MR5@19%(L%)$C(H2*0K(L"02,"0)$)"2<[:WY?BIW:8'Q_`]W\82"<2#X(X38
+MTW)^-;\@+GF2)/(-P_R>>J:4:4E,.N)1M%VF%>$DEAF*Z&1TGC@])U7NFCU+
+MN>`[7?^W3>OO'<3HB]U2E#[5*?*_?.[/3N@K(B@OW%#YF82H^O80Z.&^PU"7
+MW?_R[Z6Q?@$YES!1'*,-Q:OO\]#N,$&6I9_/F;*6,T@9!,3_1(URE_OYGI_"
+MY<5`;Z@-S2I$*GA,L]#XW4S2?!DU_O]QO_9AI!Y\>Y1!J>"31EX>WE4+!V$\
+M>613_ON\Q']NN^YSVZYS[UJ[O+#'=(J=:GX5$K*#,P97R/#:USLO6?(H@>/M
+MWIF_9J'IG<$7^F$E]%@/WG=R&)]J%Q!C>'ZU#IS>Y'(F-W92NO[];">J.WPY
+M>:CX^4,,2G](D8=DW.N`>)OM%+S&;1)4X:`R3_Q9%63GFS$DTD6#$0!!FTPT
+M(C^`FFR:$.)W9]47GR3R96]+1^%[M'![K+?@<:(D`)`&09%9$0UJ0:1"D615
+MD0&D4D0H0&0$B,$)BY6X\Z&:PLYX?M_C>@!&$)"?F4%BD6+"*H*L%BR180%D
+MD!@H`P@**1!6"PBD%(I!2"P4$!@Q$(L404$9%%"10!818HLD$3"9@8"6E=LC
+M=ZY$MR2016]73O"\R>!Y:>K[G^FHFKA?H)!21$R`"(4DB%SE4]R9>JY?E4X&
+MI\XGESTX-"[H/;_T,"%:]7P,3@-S5ZTXV'+3TZX^BX)@?N13"Q]R<6\>WJ2J
+ME=AB28A3W4U`3K>S\+9S=EPX0#/1D#A8LBR((R06I(5"%10HDJ+!MJ$4%6$0
+M18"@I%50B@H2I(*2H5A*P%DBQ0BP*J2LA*0@RHLE$*P(LK`44(H419)1JI%@
+MB(R4+)81C&("P1("A*J*L$9$8"?@!^+Y6,K1(3B'3Z'IN*\WM_1.)S9:QJ#V
+M.UX(P-9-;H6^$I0T`0W9>9]S#+.@--Q^NL4@RVBR1W]!.:.+^0H9W.2O'GTT
+M#,`&83,V914O]3MOSE7G(<NLZ[MSCG])IB18(G?%E@*-WYDA)(F.!\V>#1\0
+M*($#9<1&-`[,Z.F3H`4'!R759LB%L+C7R@9Q,?8/(<QUO#KRH20"*AY<G71P
+M\;ON<*10B7!A=YVV_FDOE9+ZJ<HI5H$JS&\[SG.SFJ3!OM['=9J\<W;W2C0+
+M7SN!="RQH=*CH>&Z@T&L!$X91X.2"9^*%((2(C(B$B#)2"R)<QSO#!-\<2>T
+MY/?['L,W\PE4_\NZ$[_H=_CG'(`!W4NY<XOW<;A/PY?.$<G.$'T$9-!H#.S<
+M^DIVE3R4::!G,=#]U-);]+51]*)Q7]MAV+?[(MNV#]*?EE_KG\-U^VE=OU?;
+M]3]5OT+<.,\OL--?VV.S?CD#95.L@CN@!>[Z>IS^)YMA'WF+CCR584:K[\+[
+MNWNE?U'YVR>\7?&/T?A7%?'#R;1?/H]UW!VYCE])@;%D/K[Q?:R;62DEJA&1
+MU3=%4)4^XQ+Y-(?*ZFZP7CEQ#LZ[L,Q\4L9;):%S'2$FXK<ZLDD3HDSAU=B!
+M8:E0\>_BU^\16NQ))N=?`@(NB\EAP;YC&WJ5^<0NFM$;/LFN9F9L1V!#U:\U
+M(5H?SO]&9_M??V\["^4:W!77DH<\;](V?F]5I<1VDHW[#LD0.RJ)L[:*6")Y
+M*)DL7V)(\H0#](ZFBD&:I8DTQE#M*^A-;;*$?T`R>72#AEPSH^>V'F0M6#?G
+MAUYBGV06[9Z6TW']6,^:-#7U\MGU=F`:BWF+VUA7=.XSX9E2POZK2TLW/+P7
+M;1A<Z7S3NGWM=3S7K8DQC'X_S.OD:.S&;7Z'&53.9E1.U9;N3<Y=&T11:IUW
+MP*2+JM6K5"Q2NZDTQX:+^I.*E"\HT.9A4MW]GZFO&_`F<*N_K]:8\6Z5YQJ(
+MKOQJ^^`]G1.B-6RQB;C'#%NF-;Z]/C]'RTCQFCQ:K/T$+U30+O$D'YG<\_H]
+M^A8L=7JI"$DCN\DF];2225)$E$E$GA[3\)E+>N1P).,)2(^DZA\O??]XKL;O
+M'&WO(R*^!FM//G(39;-4I:,_"G//K=7/4C3HU>+8F?'6-=3+%/O/AK\5H$4L
+MM98SGJ@\'QQT3QR7[D?4;6+X3`M]Z+#YB4C+??UJ]+/:3A%M1]_)N,/FNRPM
+M4P:9(^S3['^Q[_W/*+V^/RTK[%(?Y54,4\*%6RA$L@^7C$#X.WK7Y*[PTE`9
+M+A=+OGSTHNWHO,N4].&@X+Y$NW!M"6=?0PGX4#%[]9C_*F?6#KR#><\9^YYE
+MU9.8G[+H:;3=/4WZP.V.OGCZN?=GSCB/*R*5?G*J>ZW6'J^NIF`?+B<G+Q:Z
+M`QZ*4H/L1Y-'LSP;)X?N6^?91^[FG'\Y&F07TO<L0I'"('+>KJ]!:F3M*?2O
+M+/R!CC;QWG1>/IPZY'B<T)I8S+EJ.-6@*G\335\BU3GTLM.Q'#EQ/P]MC:3-
+MK9%_[?WOOU;W=Y.VWKH^TK59<(>OK23*U&M4@L[JM0CRM!OE$YO"TF-B'@PE
+MJRF\H6CF47?M;OPF*J;YI;I'*2&NIU)!JON`FYA#%^'88!SA&_M51OR0;8[O
+MOVSANL(J,8P?'^%@O/4WJ4^S$]8N?P,M*2=CY\F8[[#@2SW!X9Q^83.(=).O
+M@)TD"A\Z%$S8_P\TRPQG&/1_?_B^V>I/O.<VR#,%,8H9:R\Z7-V:#-YSBMGH
+M$$]Y!3G`B*2`!(*R,.A"&&2&82&`YLU.MQ#0Y%FH5:^FU.E)$==(Q)@O-F51
+M'=8W(YC-9M/E3RYMU-NUU+-/<+P8QRP''IMOEMV5BU<,QF!IV1)=-E[W<8C8
+MAA[D8),17*]6FH5R=)1B,D*4DP*7XH0KRWT"_P<*0N%0#/\HL`^2>X"LY[`P
+M4P4`UUA9ZR5VPZ1?8`P<-ECJ:G1]55S.FQBFIJBK63-X./#&=5)S\5!+)<O9
+MI&%-JY'CX8VXX%*>X5^;C`5L?JL-''I3OW]VTT_EZ_ZN;>&V_`N_ZS'Q*DDD
+M]PBJ6<CEHYJ>SH,G]4\Q\#?I^4Z;T:Q>&%@W=Z484,:,R,8?@2Y<H>^?+8V)
+MPLF;5DO9+''%(L7O\N3]+^G_$8U3PJ&JU![?#;%:1H/!6;V?!O[13VPM@(XV
+MX(?,3\=^;BV;T7IMP'P)N7R-T+INPM9P/H,S:-E#$G2X*^M\PR&YLUOQ.NYM
+MR$&BT>,V,S%&7YA2@[F6EE`QRKF]?QY_9ER<6H5M=Y6!T-;8*9,VKTW%WV]T
+MV)+@/H=UG^/I4OL2*R(LBI)"$C(DD(C(@V#:$VOH,3<-)7*SZ73W_(['F.S2
+ME*4T>4;QC[/<_EGB#7S_[+V_V78B`B1@<NSB(Q;XU(*RY_&>?>E1#<^0IFS=
+M=/!Z]!-QCG^QZ40T7/XWWC^W8\=4&4(.;SAOK]-IQR='][GO./,,[EKJK?EW
+M]?(3,&Z@Y\XED)))(4/^+AQX7\ZTJ/G=Y/U9D_C^WY4^W5-@^-R]9V$QI%)Q
+M!T2@C92_ZF^CN9G==UIR5,]Z'XPB,'JG99HL?E.O#:LP<E=#'?C%S\':?1OH
+MYPVB,#I_8XG9=<<1ZN@Z^2,'<?NNSKZ,W,I+"Q(\YNO#S$1NTX[K]9U,F-T;
+M%:@J\E].QFO@='+-@H?U*O\54I,^AV[T<PYXV/@0:UX%;D_BB9C>!,[)2H2H
+M%85@L*P*PA6?G?D'0\.Z]'(7<-PC`^UV7/7.(_?,47>[0@D;S7_?OAJH$I+A
+MU-&>&;=7EYBT4+F.AR=EF42;C-L\]=Q/8=X.[F?OWM1'.D3$J8AX=U=#R1].
+MF0S<Y)NA&!!#IQ/V1?D)N,?LL$-G\2CZ-/_TDT5S,24_$HA"/]7;VOQ/FE=3
+M>\N1TY6U9\L#`5U8Y#*3&!IC_[8/+_#PMJ-*Z3YJ.[0T\H[2K(VNE)MA:T)%
+MKJBC*RFZLA&^?=U7@_[Y+2T$2F7UO?#LWI];]3?*&"G4E7]DY%G75>QUD.YW
+M1R[G?U_:<A4U;J#N.4)SX/^;[8/MYZ:M8`5K)4`MM&MB%:"%&(P%6"@I&,%6
+M$8,4BJQD%J,8(A$8L!4%2+$$60J%:R`I&V!4@LA4%@5"VV-9"H*"A61I48`P
+M:R01%)4D*@QA59&T+!@H$MI4@I1%BBD*@LA1)6QC$"I6I6)!)4BP615%B*JJ
+MHP1((J!$19!$)4%BBR*0$F!EC:BGM2]IF"=W/"RIK#OTD+V%WJU$U\S!M,":
+M&F%1!YBS)T8PZ&*F=R+<]LMQY(Z4+G8AE97T!W5E/Y8]3RT$BV"]Q%:+[W[,
+M,%,T6`ZE-*E`<7)5(PT6#+\/X^@S\8/U>-)L`:W>%0J\=3#ZD9?=X_LL,8;1
+M&7$_7?\Y?XW!U"L>&GN+SNN_OYW#DFSV1>-)4_]X6SV]ML'(J5O0<K^,YQN(
+MYF;7`]UYM0U);Z#EN!]ZIKLCC\;Z+YF^."G+R.:AX5WSK9&@DZ5??%_LFN8J
+MFFXV-C-S-P$^`H&>%=<YQK,?G.9;N;%C].RYJZU`+>OMQ4*Y;]@F.4,$S"FP
+MVF1P@VWQR7T?!JX&)3\:W(\-TZF->+_DQ<:Q))[:!Z3OQR;<P[)NO:V,S7R+
+M4WTB](Y&^:BF>.I/&M:QC*J2U4ST/Y^3DP/#5+Y>A@<NBDJ2J0>WR)7Z:(G;
+M[\"U`9="@Z0SW]Q!CO\XV$7+F2=.@A`J^I-G(78]Y"_4(F%"A43=73!@T/L?
+MS+KJ"@X*7ZGBD?R6!V[&T0.5C#AMR\.=K-+^V^R][>N[U=QSQG*53?KF\/QH
+M1S*ZV?R=-$MWM&=#PHDC;'HMZ6;V%5B5OX)NC3',UL?.X5+KY'7.Y>R:[_-\
+M>K>6^<O>`-1QB]#<>3:O^$?/5L*@S1Q/5&V`&`VY$Y;!V=]H_3^7<EW,MA0R
+M/R^#\^3,:U['<YO=<Q44\N'[;F;!73<%=<K2^M&-;.)''IMSY5Y*!0CO4.R!
+MK.B>_O+;)`U[Y6#?M2\YZ*:\[G)8;OX[UN6>JDM2RXSDM1;*R-T7/UOK+$I3
+M0$/66BLW?"XEE-21P+YC@VZRJ(S";ZZ!DF$O61B8-?F,#:"L!Z>""ME>%#BL
+M7`QMO4T2PHXL&V?\BL^,[^!T=D$-BYL=J5[>:]:ZJ9+S#JL&,;:$($O_B*AR
+M\U6)XZ-1LI*2ILZ5-KN;K.U]R.O4IB8D&Q,$':/W#41:,S)2\++WRK6;)#)3
+M1XO@M;`/\)LUDXLGU;-62J?X[]-<FCM'J9;$$@/^0!&`1=NHA"`J$B*!&C(*
+M"2(H#$(K-S<MF#=765EBW\'.0]M>HM^,(H1#8_V4#C>D[1Q>6W^]R/V^B#WF
+M0UUOASW&>+K?$3?SP\,1'_]"_6'K_0,2E<)2PF)M=L2K`[WVJ".&]SO.$K7@
+MQO>==F9CPL&SS6+QP2_#](ENQ'`=`^5W])JFDWW^U9M.FKGSW^0Q^2"=G=D(
+M2H-7N=$PUC#(P!NU46KTLB!3EIU*90#-H$))"$S84]Z:_)SOQ.4NR5$UO^<8
+M#7_>O5]AY=E8GBD;/Y;^Y&K6!@Q/CU+/Z:/T%]0=/N$!TD3Z^ETLDD2.^Q_7
+MC^W:CJY.=\)"27&[1=U'LOD^!!^J[Y_@TGHE)/!BH3J!\O\<%"2W$L^K2Z2-
+M06FP'@][+)/XWO8/^%2F55-#T*FTEIS3'KY!6O9,#\!(7-7I_!B:)CSSZIQY
+MH-4FX#2TNSAQZZXWK1'T9F!JYT7W3GO2JU/]80%Z<YBG<-4^Z^3YI7_U\WD0
+M?()E2QL41"APS\[WUV*[59PHON*Q"L`_$&3YS"!M%-IPBSA1?P+^%^\_$Z?:
+M^X>A.Z-H<IEFBA<#K(J/:OL6/M(%F_G$+VE-FNXOL2@0Y(Q@5_>D5<>#ASI7
+MKY[AM$6/UZ5=O01+ZND-^Q71\K'STG&N#67*:F5:'S(-"<>;X4TY:%5%":D>
+M0T4+,U&/T5&TY_X=CDOQM:%M]UZ$3EFZ7BG-XL$ZF,"VT`R+^4E%E))'416%
+MDDHHR%0[ID8PIOPIT8[SQV7R8\&'#!\8FOO\@JAA?HY@R-'P\P'M7\VO]+(^
+MASL%!$)THNPQS'QY\=>E5(J'!""\(AR)W:O?NFQ;"P2_H.AQT5&?46B<TZ^F
+M<:=NM7$CYK4Z<HM2%]TSW+)6@W`AB5F!F_M\BSI'"HL#HA,4@@2LBN>>>M-I
+MUX\.X]/7CD0K_IE_IUK:Z,*6L'CYBL*&!JJ44H?',`5:&VO#P%CEM]MGL7LD
+M?[Y#!X>S2`0:@$1I,$>XB4/W['-;EDTJ\0SG_?4O0&IESL!1BZ3!_A-0@/1P
+M8B8]6@(<#FA7'I3X@8UZDQ'(T>DT^#FR'5B\W=,5"R&,QVQ<&DJ[[3[/!)2/
+MJZU"8^#DPMH?R5[S+85MA39CH"";(QBM3KNZFRTR@H$X83IK5M=[P05XX5>=
+M7?)/?U,XPQ:J_I,]CV:7T8T>@A'`Y*0.'"IGWGQ8,T/`SSL&L40220A&4G+#
+M7R9\)EJ,.7B?S_[U@EG,0HS3-R?4XNU=3V<(/CM+V;+/F,O>+#C:?-@7JGZ]
+MEY;F-=+0MY>MIDS94]C,%[?FLK)TJ/1/84EG=V$Q$R:ICUZJ_?X8N>X0J(,2
+M'>3T]H2-C'/!0_V?Q*3HS^+9/UK\]-)!9.HJATOT9X8>IT[N6D\UEWL='R/&
+MS-=(WE',9&)`L]G4O['P;!^C\U#&]JX7(47EUAZ?NYO27U97&A.F>,YV5]*U
+M5Z^=[J%YU].X^\QBE;T8%!-I=C,5IFGP)V]_SF4>G,V:CBE%'/:"K2,?.$8#
+M!L8%AN98RB:5,B?S';Y#D@"U**:2I^_2#!`(-7E&O1"BZ6_(Z%7%TZ)T9"9)
+M6'*$?J1&ZI@%IDFBB/*__<4V:/F\HC<W^1F2;"EVC2<IBO/$M2B-YB5!]3Q<
+M7P\Q&W'&SLEK]7@`M#M9E;PK;AT5OK!BM+SJ'^7G+/%7W;=*#[$5<F-/2:</
+M=SNHN2#<$5:8P%@"RV?@<K9V_IWO:;M6OZO:SEGIU7D.Y46/%L2F>FYNI`V2
+MQT9Z6O=,XN81D3$<$>SOPRLJW0H9^AT()I6"5CXM`.0BD@2:NE*\&4RA`>]C
+M'8W^178I+B50750'[[^+O_0L.1\CQJ?+O-ATF4CW4$+45$,BA-@(];ZBU`$P
+M2)W0(],.=5WY'LWM7FM&WAWF=]$DR4/.GLL(6GTIWH-$4)H/DFG!%<DR(#1"
+MGV(WR0E.F[BPK<7%D9+NM@[&LH"`;L??="-B0]K61T"0;(Q":%6=0A()19Y@
+MN59NZHJVKL=CC!)&!9NX-TF"_)::(N<YUH>K5B.Y];P=Z;6(R21Y1UUGHG#=
+M!62:?,1:#JT^':71*Z9F4)A-X1T*$T)G)N8<I"D:I6JQO*(L:+L\8`.^B@@2
+MIFF&PTJ0408I9$E+]58BSWP/A]GLND?$T'6%$B.RY%R:6R4YW2KA:R*6`K]'
+M^*Z)4Q>L](9L03'D;YUFAX#\\N4BS;PD[.+M+<5&PH/F9KA@KA9#NT$Z/>7P
+MTV),..N_1(CHNMUD.W3#%JO42$M9%N)1A>^[6[#EY!D\%/F'=9.=@9,<]@/%
+M`A5V7OH;==0^9JW<)M)8T9`B<VGTMC2TFT5C27DP5OPH]!,!WKZK0+@K5D1J
+M?3A:*?].7M<!C@=!@CE-(VDPPRZFR^U":.*[."^],!C#A_AE*+=-LYF66Y'X
+M^1GW2BFZ[\J=>W?&3YQKX_6KX8R7#;&P:&-IM(L1@B@B**B*,$145%%T[,0X
+MIKRW@E;HK/F&TG;?-O->IL`II,%\=%[<-J;++)H$_I/`[EYG:_(HJ\LY<DDC
+MC$'HT(C=^TE7:5&K#>#.M.)1MFMA"YM(_^ZZGVV?59%'SW'KI\<#AI4&O1C(
+M1O.'V]**9"#4C3/1#2'E[+Q\[?+_.?;8]+['_*XCI'LONL`X&[BQTKC_%4E1
+M-[NUC+W%U*U=2(,@')=9'!"ZBB/BC$3!]B:-[4"`N4Y@R?KRHZP$98<6^1:^
+M^^E[:%XJQ/(AEZU[\JF8T3#:8Z$I:<.B8IECP3(]$".]XL@6-\KMJ0P1=#&Y
+M=3'LF>JM@J<[A.@L;2+0NQS\"+2G3.5W:ZHG(!66U1/-2@#P<52:':)J<#Z^
+M\>?U)O'[A`P>(;N;\07TU2^5G#Q'B><YMI?T]I6W\7BMN;C(96R%$^])XFH:
+M;I3J0:AGK6MC%7E0'Q?RO+S^Z9HN1MQ,C7Y<<Q$KRU:)RMN8.$-Z6MC2C:%M
+M#3&-H>V$&Y6]\-QUH57,?L_>TOS),A%%+1!Q_)QI(GS:89,7-HV"`LKL>"Z!
+MABCITF]V[RF1%L$7CVNV;U2O;BBE3-4$0[<^';@O'&-/V]G5.C,RX5NQ$2]<
+MN3B(56G!DD[R%[P1A9%FS"Z4XP%FO%5A]58\JZ/9-$7?42KU>_*%\$8,.D*"
+M`8P8SX6"N^)RHGPOWCO]NV&OT5A<@_Q.7/Z_*(?(M=?U>&*FF5DHP20>4-:^
+M1(\J1Y/^T'ZS,VSZJ7(\<NO*<!?^.EVM$-_4Q`%DXO!^)-&J?J,ZAS"ZMGT2
+M8"8@\.+6H023*L[>=`U<\0X28SR:)'BLP9THK=[39B]1E?P6M6=T+WC,B&C4
+M!(9G80P&Q#[KU^OW5;T8800\(E"J"JX-'!^9^>.[6N.O3/LVNBC"70]9UUK`
+MZ;+E+$ME#4.%;.([)D=R7"IIF]!4A-3HYDMPLHL,:6Q+BY#"%@8%29);6HF#
+M)TV!][T0^9M/A-=:D'G1*=@/?ZAX?-M9I]5!#!JHDCBC**FE2TBE9#43SZB"
+M==FB;3KE[R\7CG'H=+:BJE:(HM3J]'8JCB+)[77IN?Q^=7M#P<Z0X`?%?O^3
+MN^)OUOCXTCVO8T6WSJ8M:)1**J9)^97FY$:$X6NY8-H'>S.U.,*!HV^]#Z[_
+M5N[9'OV8R^DON%0=Z@<7C$B8P@5*9@EX^.[5$@9!#!HJ[%[O#&B^UST0_TLA
+M>QHW?R(=+U!WC.7H(/>S#+)(H`^N00CN:#GRY!QAI^PJ\50MOOOJFD>FI.)\
+MWUDZX;M7AI[=\G)W]IB&5.UHBI^NI.<LYM11^BLZLP\V6?N'R#+/+"&>`:\*
+M9;*SI2E*K5/!-M>.I3$VG]/]Q.I.A\_G&-(;H$RM$E3+)&E%R6Y":(!`_!8G
+MV]1CM&]]2/Z?.\,"F6(1WF;A<Z5@D)C$Q)]RM;\FR&S@I:QL'\NEF1HO0WXR
+MR+Y\&!BW,"6-O)T])^AT\3%E;!AQ1N.H\VU/F_<Q^N[/3DARPN>.(B$SNN$?
+MF$_QOE:'Q/YRQMAIC0`.`Q,EB9!0(],FXW'HL&)6PL!]06*71A"ZI@@A@H8'
+MGES+8SC68AIL<4RZHVVVX9C+<<.:C41<-7(K6H<X^AUKG=Y71RXB?2WIG"F%
+M'C1AB<.QPHX\'&MM=9"CB\&LU:5<XPT")%QAK"PX2?S/[+>]3NXIUM#6Q%Z(
+M57PYW4,RL^M?!G"^#QB\+A?!\J43)V;:5@F;)$@I27)",FY%]$S`QJN14Y2L
+MB**HZ:]6&GT6ZB#-VQ446=UO.:>=[NKB,RS5UCJX[5QDRQ=G)GK,II2P(!L8
+MZLCV'7@6;YE=*S93:)P>BTZW*O?9;FB[*V*>#%??>8)'D>GX6@2O3Q_(X(Z&
+MOC9])U^EMROT+"6UQSFB6`B>JS81_52!(ZITFM,,4;A593^[(ZIB`T!:(NTF
+MTCZ^Z6T_'W&5W&%35H$##=)KG90\J0<W2_JJE:U&"JE[Q=X)W(N6PD5)PFYT
+M^N_7\J[T3T'DIH;/+99S132T7*J3V.)"L/N-@I$CY/E]EO5,(=0)M42YH8!'
+MVLO]+U2#B^(@X9$P4128P1\I@?7_TB"]$#TF=TIF>Q:J#4,+#91.%%55?&YZ
+M$O%/4HX*UG;`Z;4]UE70A6D"!Y-+/A"R'CC#7W\+#`MJ"Y5:5=G>LRB!WV6V
+M%1M[J9._6B""E*8-,L74U<G%FDVX@*([7TIF;M:P7A!M%B@Y[B:9B(O2;C%#
+MD!*&D1L#%=*I2ZIEJ1+J$U/GGJS>K=5E,R^UT+=9^"\P7%\G+P<D4=\,B(DU
+MYTLZ!LP*7<S+.ML+)JZ&]'PP#H<=)K9L52)KMETV$[=ZH'&/CQ[=<]!2V=(B
+MBJ`D!"NOG%0<T;'F"B=R_HZ.+JW2R[#I(]!24'4KFVRKSZ`DR]QN$[^!;<AO
+M:I87M[7$Y6<\"N4PF>\Z3*)2\TQS-F:)5C*!"SD)67`)`9S*@A`!$DHXF1_N
+MV<#/=2\!`7680(GCW<S3@`_F/4=<CDTN5R$<9A2(Q;A-RRT0D%!N5*)VMRR@
+M<9CQ9`SP6C)*L560IS6@&_Y;UF@0@FI3'F%E":<*.TS)J,[>V##+Q#+5K(-A
+MUF'+$7Z$N'$WRYP@H=5,UW4',Q"U?85SEG3.!K-%[5827G8M;G<YKTR7''GY
+M#F&YN>JXBG9GNWR8<??_K_/I.+Q.GP)\)V=\GL)RUSG5&)&UQ0*.]N*SS_6<
+M7)8N$@P#`[C/PCZ>@T4M@8`56/V\EC"R)^J:1A6N!@32Y%N+6O+S4=2]=Q2]
+MUY]_8N+FWT)^+8'K.Q3M'Y:&\>3M8H;^T,15I/QSGP]_,]%V!NYUMYMM`<WE
+M5ZFH25K#*5;8-[+V36O3X+ND7!`OP^K9\313X4/F&%7W/67`8IL5]U,8BO^;
+M?<_A/1UL0,'OW1[ACY0ORZ`W1T3Z0]=X))KW%-F20/+Q/@]7SOO8S6WMQ1/I
+MHRE@B^(:3YW"!G6(2)64$O+-]-D!?\4;R\U5(OO%I#PJMC5M8(Z'Y2LGWEHO
+M2/8H84OL4/"YLH$FND,40!Y)$O21>-MAU`Z!\.E*I)M"-KI#+R[-:J`H0J*#
+M#KU,4<*5@EW(*):G?X[0:6P,*X#PPV.A5E8&.I"@)&,,DI0LU)/JC,V71-HL
+M!2&V;'&2>P9`1`C2;F>/5`RH%S0M91!"0)$M'1&F.!M5F@9XR"Y,L2@2:Q6_
+MEI46UT0P,6X1*!$#O&+!U!+PF1<B9G<'J*AG8TKA-)64[2)Q08W7:-K7M6$3
+M%II`R5H`2"43*1B9D^YR*!*M8*RE&1=\+OOA0PBJ?:'=T@V^>WF=#\ODM!=K
+M^8"HVD2&W9RWZ(OB*@A$,L&+3:E1F9CET!:$RCIO$#6C(VY.7*6>*)F=IX9Y
+M_'OZE.WKOYO.&UY(]TJC>[VQ`@FCK`8ED)([4]KVQ298Y]3+01%+>0[K`7LB
+M&[IXE]F]2AB)$H_F2HG%&K6>/4*JV4N'&5B+PD/13=$JP6!.Y&U@E9265((:
+ME2V1%'U=EA-LLBAPZ7,Q8+'LA5D'"A2E("XH*W@PY7#3E02Q+(A6`U[&Z.S(
+M_:-U*;X:];VNJV%F1$!;+7@:NFKO<-05(%&P#%JDHLX>M18-(4+?"BVAFH"W
+M`<$HP(-"`RI:BD7"L*`DA0XM"LQRQ3;&G:V)-3#M!!!4ARIA@F8DXTE2J0+)
+M#J:JQ4,UQ=G>(7-2$+ULZ_:OF]GBUY0DEX3,IIXLP.U,V#0^+-B&A6H#:SS`
+M@+$76JUV%AS?T_;^KZK`?(/PO2/&=]^G=N>_D\#OJ_3?P]R$Z7:`M+1,O1[6
+M5X]0FT-3`O[B-)%YHG082Q*WP)=TN%-[]KT,T+`$>3UZ3.3IB:.73JD`X(&K
+MH7FC%TI*.AA60P/(L]MXN&)"L](/$Q?S5C-R;F6'44PDB(6VGJ8+DRB,Q]J5
+M]ZL+B;(=B&'!P+I06,I4/85-$)()*-H47?F**"]SNQ!:EDN4&'*B5>,/]XBQ
+M".C37WXH)6%B&N2(,BG&C*X2\#%6=(WLA9.%('`W!(LJI*SJ1=MD8F]"KV=3
+M!(<4R*-]X\6O&ID2)LB<!T':A63<AY4`D@Y,9!@;.;$F1=*U-@KA,B20;88O
+MQ'/6;P=%'`L@[:%#N@("3"Z@$>-)T('L!H$,'Q@;>K:QT*@^%31=74="2U#U
+M(10@Y7F&*N5R"4)V5VL4`MR\Q2%2U@B%\-&F-F!#"$!O1*DV%65FPS3$0A#L
+M"TNYJ.LGJ&KXE05%RER`40KC"8I(<$AH#59V2L*O?->7K+&68`_P_XGI*VO6
+M5K9%8+AX`GIZ/(@J'"FA(GA18@5ZQ3%!Y=/P)T^+P!L,RGQ*OQ(CYVO4T'@K
+M`N"(>C@*@H("!"Y\\S/4P$M[6=W(Q9%+!%22[QMZW4S>PGWG>R-9:N^V&[M0
+M;D*7'JO/5^(=CQ0Y.^E9/!^@F*]/-OX>SWL/$[4O"6M%-F#;-0FEU0(26(#%
+MB![#D&*O'#T?41T<9SE;K922:+@D@UQ!:)A#(%^$'V(F0P4B_N0#!T(HV.@6
+M.K:@S$D!;T,84304!F2,2$CN5JE((+7"G>JO6WP3B(1-LRH5[H[9(I@X$&JE
+M\M72-A-VR;)O#&#53?VE"PMG#,U?0RUS<)7.O+E#^4F8O(.Z!)A`C,:8P45H
+M6&@L^:*CH(!8$/U(J+Y5+0M&2R+8PX)6!<J"4(E4@`N@90`HU:G67.HJUC[2
+MI`Y^'N%(WYW'7TIP.5-!0+T4G(9*,"3WUE@&K[!Q!U&!@<]==KNN6@2J6RLN
+MC\)G(1DO+"<KWM/=\5)IG%GC'KM3M:0NCT;8XB&L,\9-NV?9(0Y:[EQ=S3?V
+MWVZ]%GKI[5+`58-J;7<;M5X_D7Z#/X7$77$O9K21D8(:WF9B(A2MS87P>!=#
+ML)&DC[;VJ6U'A1%%NZ:3(T3KZ9H7*S4Y+!28D`D]<55!0+<1!NL,]?^9QOV^
+M(%07\TP/WJ9NH62OSIN<00W]P_6FL#>738;"0Q<WZ6`BQ@OK,0PQHE'%^2XQ
+MFN%[&5HY>6#QUD@32&U@QET2S2XY7QKI\>)W25[+T\DFAG:6<'(H&A#:H8YC
+M[NND_EDRPG-2CB/JQQD2@UZ]XZGS/C]C@$DPJN6A&\):,!L9EJFCHO<,^:_:
+MT5N2D'0V=.Z2/@?^J\>.3Y&SDJM_6,#!`G\-#D8;LC9I2B'1$1<6+)@0)%"D
+M73P!N)"H]Y.GMZ`]!T+B2;2&T#HR0L2'+0%6B=T<!)^>)G@^^:L61I\V6-F?
+MUC[MEZ=XX(</T;KURLR:H4.J/`L%G;:F_JEPZ[&11K`=\$$0FHO[G"PR3+\&
+MB*`KA1C:@YP)PCQNYO%9@7D4S2A466FGH&4Z*(+:+W&%N<$G]_)F",D2((C%
+M8J"$8L.QTS?=F=3`EY51+8>::)ZE$&@QOO11BS&(QH1/YUN7`^M#7?WX9A83
+MN`-,,T+UM/-E>DSUY=0[B0O8*<ZC=%LE0*2-405US/>##;32"=)H?@_N::7%
+MR(&I?)`-RRJ;'>="11B`3#(1!"`HC%%445&%K9!]NXR*'P)-/+*)+HI3+>U*
+MDKUZ;PF[25)4+&"QM+TI58JBS2:>:V%8?IN@?II`E&\GH,>D5BMC8=_C:.#S
+M#JR5_BC5CO,QP!3\AG"IOHRJU"HEH58QVB?=LR-#S$-4LH%3EB)"697$,H:O
+MSGD4NRXF:!W[]$#"DQE42MC'"'>P81!@B$8D8>VT<UZN+,-&Z&"XE$1!:;NG
+M<4%=QZ9*B:P>3''/`T(OLD9U)F"7\TPOH90OI(\.PW8O!.BLXX`Q8A"4OQU%
+M53B"R4",%(*.7G*N6KDCB)HJU*.6SC"FJ:\._4-+L]G8*`DZ],AL0ZL35V%<
+M("2*?T'X,-\XC<\)-O>--'!/MBM.'J#%"Y[]79R/'-GI8?JV'6>0L8/?<58I
+M^*]>U-'JNG#2')H,')J:#G#-)8&+UH7<LGXV_CO/V'7S$S7,[I;9NXDG9/RS
+M(5\DJ1210%@H*:0HB4O'.8/AE+E'$;-)BA35JDT`H(FS0<"V5V7%,W'NUM#7
+M!=RK_Y+#T'?71.AV\7,:E4K+T[72C!6.YQ[=USOR?C>_==CBX(N2^D,A^Z<#
+MN860=E*]4S*ARF2^/'BS#8LAWX4.;2!8<[V65T8Q0F"+%""@HI(+%@LK(%B*
+M"V>^A=]7U.998Q51=9A7"Q42VVO$M^TLZOQ'L=S>7:(G/T=VQW2L4*E&+44H
+MQ46I:-54*[L"YY=M2DY0W?4F2.'J!YE);6LN"2=N4^^=%ZLI[*/47-MLQYPC
+MVW0?9#2/8=*U7-'LI2#Z]`$LAS(0MO`XB@EMBW$7*LT\P+B@+(@H,Y\YV55)
+M`#$#U2+?#LU%-H.1S21E5;%,L9AQZE#<U6CBS+H\2-I(*32.DA0A*J+;2-!4
+MFMQ<JD9YI:CQ1F.EYX)QC!2S.GORLQ@T[$5P(WSW&8?GBMK/:RM7-H7N_!,A
+M&(_Y$1`Z1[X+^<1ES<T22O::FQ-I\\A'NS9*DHQ>=G.S66Q,>43+Q]6458?S
+M_AU`['K3N#XTH()E+[P%\6$)&)C;45N069CF.VWF2^Y/L<L09R-'3V_LGD^V
+MZ&P]CCHQ;TO=6..XD6)/><'+]H42J--^T<+WK(+<[\68V&#8HA@G3_"O&MYC
+M\TP[SH8E#CU6'13`)%`IM#:.G:S32>W/TQ`_-6(DL9:FV=DP\_S/'Q6=X==B
+MA&\1!'1ZXF-B[QE*PCF:A^0C"W'I,C"EY?&`(DD^0E[2PF]$PS40BB0?<#[P
+M_25&J5>BS:=Q7^.S=!F`48]:PW\PD#N]@PS[O+`'BF!_Q_>S80/K.>L<NDE*
+M4\!((R+!23`Q7UVBS\XW0"3`G=B^V+M&)L<:%B0:2"N&GP0C%\*.$DV9S.HR
+M:+!/A^$59?</O1)^`S,I$S%[LWX'V;<?B6D*RG5'?-959"K]8KFWUI2\54$S
+M7AL]\9JASC-VQ#(BSD(A#/C;CW,[&HP\+1XNJ'*,^R<D007,K8'"=%#F`QX2
+M0]#,VMN+JEW<J+\NRIJHQW*9;+'5CJ>YIV6O!9B?2>FLS\[-0+`MO[KAHU(I
+M*X\"["_;'3PDJ7Y-%2R86"8IQ4=>7AGNS<7&6M??G]=EH$?DM<OR8/E70+@:
+M7N-$?\'CLX9K^"1C1=#)E\DM9J#7U[?3/?306#,!4#(5M93NQE<!B05:4(;S
+M@$T0ZGQL)'M=V\,>7ST"*EA$7B#4#.*4/R)0.!TPE!E`-$GL'$<3KO]`=PX;
+MPLT]IW\J>*]JWB.FI/+Z3.(+E$7$/!+S=XS2;?L8&Z.K30J;HN)K55@YQEAJ
+MAJ88V("(,;F1((P453CBF.RF]X:TTJT$-EJ.+6V[LIQHL51W:@LI;%!8JG#"
+MHZ9QA6$1`>%%1&5O%*I)IA59P*E8`LFZ;=[G;Q!?5]0>:T7D[NL6J2=2T6>=
+MV\^D0Z1"G/WW#AA:R//^7%9[;-'P,-$N_N5+>&Q;8H:]&36D`%1#7E[4A*8;
+M7RJ;M$>7XSW:%TP%R*0#&4YS@SZ)=R=M\7-GNJG->498T5""1=14@K&'B>-)
+M)7G-T_MZ,.P38"OT=)2?$5YD.7QFF(I[3`]5YN&[FWB$2F5"LD%P85E;40Q8
+M-781BZP#*E!DF6"6%L;',+9O4G5[=7K3(7<%_35':-F8+>4[V-@=[9/_DS9(
+MY7(WE2,\/9T3(!=@.D7(JB^HMDJB;K#9=?%"QU!0E@Q&K\'$V=#-7U._!;JX
+M_DXG<OLZ75L8LUWC#:#2Z)'>G)`)-1C@9-AN(T0"**#_LK@=3EC4G9+(&/*_
+M"V#]N(GV?H*D$D@E*+L/NR@K,6^5JWBQ(DX[.M(F[E'I\L[47=MJ%`>APHJ"
+MJ!IOUZGX=/I/7>KDO"9CGN:P]S1]&Z+V/@9)HUSTQ<!J)8FC:.LYXD)^Q32.
+MA'DXZZ=M=M3&$K\C3K[31>+P,,VYSHN,8!2.PP*M7!FLNF-UXT#9_HK%UJD:
+M&9F?(_*"JK!DV^&?@]-?1TLT/Z-DZ*G1C^9I_WL`D&GU'"*:0V/3=CP-]U+>
+MG"`T(45\*I#5KWEV85=HR*%6-JF,Q,#;&^QY'U&WGLXRQO*GSXA+U+CL8.&]
+M41S9XQ9_>C+[DS*<W>B6I$(<//@0)/L?2_B=1^P]33=+1B<OCJJU7(DEB%P[
+M_OL]SVJ1UE#505"80[4H5&JQDD=D?8M343MY'U*+R*>E&9?JK9@T-F('LO$4
+MOL>8QE&.CY$MQG?+Y&010@2S;T^HW&8C0T,('/;0'^4ZUG+,@&2C`U;0JM[\
+MPU#74+G[;UFSY?ZLM%.:4$8EI4%N7!7,ORM'I7>MS17ZL0W#95M'4.J895BN
+MBF3/3T-$JC*2[_>]/P9*6=.SFZ\OJJA%)JKEXP3$XXMBS!7FU<SA@PHBUGCZ
+M4WYY.6NW]>1F<S!<X>@=+5WJI*O*1RJT1OB3@T6A.("1BEF0_9=U),-U9>ZR
+M=IR(+//G4G\JPWW4"U!V<51E)/.H\UJR!G_8G`HZEK]KBUD[RMBK><WS!>0!
+M%!I:V!6^]=%J#:NNZ)W:PD9N-5.!MK>##J30?]=6-B-3_#SI,]OK3P^Z[S->
+MJKT9RPH_3M`5#RH2D3OI][250BZ4T+8<2>QJ9-"22Q`"(T.(L7.3`:I?B6<P
+M`Z*2Y^WKM6"D0=#U?$K=H8H0":\7S?$N>)X\C>$B*QGS/!1U)@O&1RM>28%^
+M7ZO*5#7]\M8KVK4@YK*-E.$(D&`NYWA<,4+#0,&Z)>B"D/B<S2S7%H]`.4%H
+M@B;O,*LOCJB)/QQAM6`:9`T*-M>$A8BB-1$HF6N/TES(L1!RT5!B5@F3IXQ'
+M8@L,.>5GK*"F)JM5*?EWKB2]7-W1H;#,X2=-*#N#%$FJES*C;7BP%S($,!F"
+M"+-)*[I(:AWBK2<^F8T\F!L=G3IE\\SQ3P9]4R!UB?*>L)/>0DB@=CKW5$[T
+MJ=Y?6.N0U*7B*QIK0FZ2FRGMU4D2W9^%SQG`FPHF:.6;"N0Y?PH8@V=?%79I
+M<J-6-PA4DRDCHKJW6O>9Y*OD][CQ2QG6EV7V4#0F9;'-<:E1!DRML-4JBKPU
+M$CJPJAJFG6J,5)C15%`=1NG"."@C1E1;:I+;!NKD%!!$QM2L),%*QA%TG#`;
+M1)^6BV[@D2#3<#J+R_0N2UG,MS,1$?6]%:BG"!;-!\SP@W@[[?6P.&J1-1_0
+M>FSQ;S.Z34]FBQ<)L;4M.I%_TM(4!5&,4D\'4'L]P4]52+%AQ.Z31F$1/_(L
+M=0M[0=Y(3[6_'\BP%6**1$%@C/5Z/1'VCMSUS6ARGRL;2M^JP)S5(HT0VT%!
+MQ*Z+,Z21B;$KH')"?W>JP/+,\@#4)0B440+!W$TF-+32*'L`YQ.!^-A0RS1'
+MC5=%E"H(EIF5F6E9MNJKK3BALA^T_B#C^6/H+=-T&&;+.:N!_A3_/8;5%65B
+M\E>U2KXZ!7\RI#3L#:]V\*+]/\V+>=:A+#%(S`0,`O-:"PR(@"P<5-%#?O_8
+MN/T7SG?BHL++5!#:;#=[,2,4E"%56Y))&.A8GJF<T3$5>$!0(0R%A<]=B*5'
+M:Q3QO+72PN],XVO#A5K$U>=G:HPTUS*]BSII=*A/Y"'`1DC^$@B1A$HJ,44<
+M+G(D\[52<H5[A-A-"+)!@('\2[VE+=U.`C50#';Z7FDE&+Z2*VV0J+BBAO/\
+M":JC0ZRJ@CIILR$%LM\4H/.^\-&PG9>G3J6=="<7;.!!=-;=/&'?H\6I@H)$
+MK\I8UXDB/7%:9=:P%@X_6]K?&?TIRD#\O8T;9^C\/@<X54%**A2V*`],P#XF
+ML>=!*XJH&7/N=>Q/2AEUDE?P/?]K`V1>J,K>J8)BL59;6(BJ8A;4_"+F4K+8
+MT+#63&K]7=86<@=W;JB^QE<&3;%AH3,LF,FHDU>>4-=;K,-C.?NKSD)V0K:$
+MJB8*]/MB["A3XK1#]#6+UM16+K-TX>67.)1BZUES.V)89EAD&(2*YCH7S**@
+M,=@<4K4/.#M:SKOQW_C^5(+UUM6Z>J^SI-'B]HIGDV?`@H/3&Y)K5P:`E48Q
+MHDK`'@1+0R8'%W:IX8;RX^0AA-025]SDATLO=,94E[]8$+"+?@;,\T#ADB10
+M614B+G$R85LA084?CI@S$.-S,MI/CLE=:*`8DJ4,$@('`$.TIP^(?KHM&AN4
+M9&4!>B9W4Q4L3?@<';7$^1F!G"S;4PK1G?T*9-(*-X32'#"<(`;XE%E+0H6F
+MV2C(H@K';555BBCHMK601;*"B:RY010L+85WE9EE(&C5DP,?L2V!FRM+"H@9
+M-FB:D=!:,*QK;!+2JHI\:DJ%I5$$2&].4A+`8S!D%-ZIE1:97NEIUWT=C1%K
+M%`@J8H=8#HT"F<YMJ%C"0M*0M#`1(EJ>HJM*<K,AQ)$X\KOJ\90!M"LE.)9`
+M@8DO\.TD].I-^PU@[$+55@O/HNA6"S5&E`WSE,L9WM7<+5*]&9S=!JVZF#%<
+M(8U!,,U6W#14\M.M:FGC5AA=69";U9AQ:D,8LE9)>L]]GU+TZ<<&%TSDF!%-
+M3UJKQMD704#;9OUI)>=)RVWOJ"$,QC":AF8Q)!MH4,K<I.KFM;RKFRX[A)T;
+MOT#F-V7%RY:.#W95R5S=47$VURW+CA643'!@7%Z)@\5*713!1R1<XPN[M0?V
+M$XWK7,S434U84AXY,.F\3NU@H8<2+3Z+-&J!3IOR>]TK.$X*RF&-Q'BVE'+6
+M"\-3U.F;-728\:,AF;89E9;BYAEN#3%\&FM88(U;1'*LQAE>F33(54`TXD%E
+M9,4J&N@;R.7W.X3OVN4J^_A[.8"][SOL9V%$MZA.X6O2E$6':/0P,PA+AA>Y
+MA=:Q&LG"!B9J^>C6(A2VVQU3,@KZ*&W0,=;RAB*+SJZFJFYK2>IKKDF8R<57
+MWQT1N[=6HID(2"B`&1`3H:#JX1@32O`%^-L#7$L9"H%:UI[;SR7=WXY\0]W2
+MCQ]\GX/RZ](5/?%V=@C!]@Y!5/L]M!CRC`&P%!IE>X4(#"?RH'GZEJ,>N4<5
+M-K_DQA4=-53MS2<0FZA?`1EDQOJ-%=>A`Y],<KN*<C'?QT5TI2(];!+G?T$K
+MG!03*0^W'Q8!UTZ"<U^BC^OU.YY2L<*'H8'CPW,VL3O=O0-O`Y:(</'-HWTS
+MJ!!$-^7Z72&A#7L0+@N8V_2]'L^W,%5@W9E&+(+*J`5A4DHJ.1/F9)?KNQ<D
+MW.<%L[?2>]MF)I1BE5$D)$A%&0A"2,&"*K(&H>GQR?Q0]0,VTWH&&X?3H6`D
+MU0IH9IDP9G!M68@?-9UBP-FJXU!2-+%;A`BP9--E&,VJ9!V;![EX[]>D:>YD
+M_9JP[2$,@=Z105C0!21KYY`K!!%D%@:>4.KJ=M45E.R>?Z_SY(%D!-T][0H,
+MT4#$Y:7$(A%,^'K(P/[=W*-8.33>_B1]3KVEN466MPA(_YO0Y::64$VBC6ZU
+MP-318U+@KN>E.B>#[B3&"G1B^UK,-%I,.W3W!WO1TG:4P\4-HLZVD!2*B'+[
+M$,PX//7*`T7"61!Q]C+5'$^7<L5*M8ET&^P)'X?2[_$U5_?S3LFV3N/Z,'GI
+MB]+<ND-.G\";.W2[8<6D38'3B):\3E[_Q$61?RW`F`P$GRKTDC0*.'L[/\NO
+MI6/CW%':'"N[]NTDLY^?&E$K]$+#S/OCX1@D;FMKGLGO<H10(RZ"GV:_+M)[
+M.G'C[?",4L9UN,7`K#R-Z^F[R.[.:UM.C*XN[1G`AI[/+MBPV4I\[BAVZ4WQ
+M94Q#JG<PQ.;3:'#,:SXNL\3GV_MJ=1Z@O^1]+H)[,NW/A&\6?>NR]U/>M!.Z
+ME0#C<-'J&J,#U#[9Y6,<,J\CJ8,O$W?$-YY<#+G#:<QNU6RX1V-N]7;LX$]U
+M1/-C0)YZ?&T_]E5V<,HZBN*!"5-$Y8%98?GV3T?WT"XOTQ(ND8M[P##A%Z*S
+MO8*LH]4^7'WSO4\(K.<[^''O%%'?A^*R>Z=/=[SVWGY*>#%/%>^EB=+/,++/
+M#Q_-_-_1>!V.XE*=O4>,3JGV7=,9IJ(J)2^8KASUZV;E+(T<:UH7K'>VZ\D2
+MVUJ9#"(F031IW/3&1>P\1H'=RLVQLT-5;!3*)2UB`>V6:("!.G3,Q-U43,DR
+M+`$>ERXUFP,19*!20+4(DD&$EDQM(]@0.!&)H0]MNV3$QZ,[OJMRJ58DX<!4
+MAO@3!G92->E"[C<8@/QO2@CPC,A?FGZTSOYO3.C28CW>'BSHZ3*900R&NW9F
+MRALS:X&C8IE'0:*.")F7?@@&3O%=/&I!O032[7O*"K#BB//RHX\$38'>1?4*
+M@=TA`@-K3;0!XB>L91L8B$M<T>E&9FL0JI3-EYSR#0102$P$DWP"GN<F-:<2
+M2Y(]8ROW7E*2.@]+Y%H;+5-.9?2E10_9N<2;Z1?)N\AYU+)@Q"7K&=*4A^;2
+MU&-*<-I\*DJ[VE80P83]S.Y@'X]:0A<R*'>Y)L:[RJ0;9EJ+[B7Z"5EZA3V^
+MD,!X^5G6ON&Z4B/W;W.I'(_0[=\OZQQHV)"*M=NT*O&9ZS<;#\9*ZX/]7@V/
+M\&U1#=*>-O^O2OX-I]ZV<-F0=H(W[?'+<>9NHP17OX-G?=DB$KRIFNR8Z&J.
+ME&GV%S-A14]+0"[DR7&>_OTFBM1P\Y$.LMO)^AH3J@Y!-"\$;AA`0Y<2X,.?
+MGZ!W:H=;-GOI![4*I=NU$:D$S2UP:9/O]D8XCB]W59(!BT49ML*5A1PUR=#F
+M;?K;^]X\NW,)\S1PF"ZM8GY_5@_?6320H]=0>\\]"%+B&V!AH..\0,_SE8&"
+M/["1%@:/N67G$Z[H,W]PA"5FA/1"&T<0VS(I&F:QPR`W00=1,Z1)!A$D1W16
+M1C:X8F-A<2IF9"&!%".8@+`_FS6F0#0&D0FLN]1/#Y"%""+#7$#0A&Y>$/98
+M4<!W;;::W@CSD.99)CE:S.]5^9W4!5F<`LUDS;H:]";,9V07YK<&&37\;ZA>
+M'[O[`$EP.I5RW='\]I54O%G<T%,G$(PA**\/AV25`[1*6O/F><,P'K?MPB[V
+M(4N!;IL=X,H01B&!&(A$CC[S&E#SH4\T*.W;O1K#2>IPU"GQF?"3J1+S]GKC
+MZZ2SZDL`6!#AHA>,,G1UCO/A$"AX<N_BL.C.6JS\Y`_8Q`],<ZP&2RXS+`B3
+MN)?F;"`3'PRAU1OCRR,B()^%O>-(V(1,.#,G7775#U904R8A9UC1YXIZ>7,-
+MA2I:VB+)Y@^9!]8A\E#N8C`BH$%)TL-,F((HGS^[NZ:[%T:UQJGM0/D=9S,E
+MC8Z@S^1"Z"IO+G)P20D^>>$:"?V]#3B%JP\+B:J0@B(]6C8]HS[%%CTG>7FU
+M5N[.U0^NA7O=<-%&1L^]CP:TTG>;*6XH+8:9+_10KDV_1TGU9``J,%<XH-MN
+MV=P0E<0XTJAK7>8Q17M^$',M*4(6D=TS\K`E&2P9M<17BS\OH9\'HQF6QWD=
+M7#,F-A\F*LWV1]M?`RPZGJOMR3N.PQJ[)G''@L892ZNL*:3C)K87;J"9;K]U
+M9H].CCAY.(B''RU'.8+W^5\<#AL!C&A4+<#"25E&"R00*H2K4B:COWT?9S>#
+MF!W,GT;`/U">]).X@\6BL9(/%JDI!1"0AQ7?-Z!4-`,+[7CDT.&DRR>KRY'E
+MNKSNF:LH,HA=V!EL%A57&`1@TH4I:8X1,;&D0LM$[F0D.]5(<(3L99W(10O+
+MTHI%/JD+J!F=*!P]6FQ@&.)#9ACU0T;BQ#65M-R$,Z`IQ$ZL=`2H'>DAY.#(
+M8PE!.YA8.J'K>-`%8*`(K)$>?"F#$ZMAU\))#T^K(2B1&!60J07ZCUGL(\.+
+M?:RAM/5G'\[Q=SL9NAB<A@8U#`R,RRL5]?0JD6"PRU2VEM*B%TW"55I8LL:T
+M25J7BFAFH:HIA:Q!SMD+%#*VU$=(89,IC\0\?4>$[>U!C4,\'7&Y%KA7-$D0
+M((*QL,R#6UH`,^MR>IUJ]C+MT6'3333A2MK?2F"8<6H,[<X8)MKZ3LU<"G,5
+M)R<TZ.CAU2'1ED.46XP.,H:RRCBD8<\]4WZ/`,.;W57O*Y(G)%6E.H1AGPJJ
+MW$*UV8'@6JC36^2"T$-SA$X"[`DL9DG`.2R%4=<*H03$*(CCTT^2ZXDG*BL%
+MA&(CYAT/0ZU+W]WIFH>IZ0&>[(>'0Z.DY\^QK2"BO\EA0Q_6YF"/)QXPT!IF
+M--(G3"O&CPWK:;FZ\-&"LTV&D^(AIGP[YSG"CE.69$%^&E<I12N60C)F>#HP
+M-^*?%`9@F(DP$8$<M_.!C<`!D:'9!9*0.Q.7)!DM.99E7I14M\(4NH\4?#-7
+MKKTIP^2+RQK<$K%MJ\V7!.XRJ[]H\\U[3/(XT8=*4.CC,[K.R.1XM&260)R)
+M`9W$3@3\XN#VROB"!BLN*,Z((8J/3+O_2_#'UJXF/(/D#LXSCU`5[H\OB=D*
+M'.W<S\Z<XT[KOH@C2>E0OX+=*M0)%(*L<W07-?_4;"\949WU9J%"X/[&59M[
+M.Q#ET7='<,MX3$*(6!G:,)"3[-S\2+AYNSU[>7+L+;H!Q5`T#F]:L"H0(BP9
+M_<ZPSN4.,IV4H*'E-\7<Z&`9!'&S8TKIH,O?91!+0KT^[TRTP"4^/O9L>2[*
+M4C(JK`)0T'0#%%9A^7`H%+1U,?2>/R<-&&E"SD)!E/IT:-`:+H(1ZY^9E6/Y
+MFJJ^X@J&7N^@6W5I`1S)N6[A+6YLK1B]3"JEPE"3\CPH7SG0WH4)*[7S.CJ`
+MX-1:8I,09X5^+1+,65;?]VE9U>XL2QC;^!ZB">)A#3Q38VM#D;]9Y'4FG:BV
+MC.U-2`\Y,OS?.Z)YL,GXEC=7!G7*SE<WC1C)ODH=8D@7(U+4_]V'L.89#V[H
+MJ0)_OXAE5'*?T6N]^C'P[A&TS(Z8H6M[+IDAGI9CZ8/+W='S&)=^+&\L'T)B
+MYQ?U6F5@[OV'HA:ULO8MII_:U@]:O0DK76>R5;<W3D;:"=]^/11AWR?;"WW&
+MSFD6'X.U1X;`068(V.-0I@^$\++[+]:+7.+2MN`ZK)"D`VS[MT/1>]J!ZIC5
+MA1L-]N/HIX%*E)7:EDJQ"FM@KHL4;PX8W%KPI"PAF`<I*IPK"D0TW?2U_U]I
+MSFSMW2&`8#C7+TDC`((-F\,ZSNNE^Y]H)[@'O'=P,9-`0=@([=;@8F03'*\E
+MQ`;3!#,F`)NSZ\CQ3VL!GU/5DG)#/$#64ZC<.T;8GMY111$\..?4PX=L.>G3
+MBID%)2T%W#0H@IOU9QX<\[5![#2%EV=NFD)(0H!LVVOR2O^E_X+1022.D`3)
+MEP&;$ILL7RB!NF=%[1#&V.GY]2"ZH?.FX/1-^,:&%%PE[%&`%1%*U1E50+)*
+ML8ARY<.)*AA;-I[]YZ<<B:YMS.V36FQ=M5Z!8B&='-H,,%=VA`B%%"`EIF9+
+MB_[!8*QM%#C4A#H0/LIG\!4^U07D[JJF5)QX<'@V(246X0P'RJI)G[Z]OIBU
+M+:X^0H/Q.ZMO3N:7?W6ZT)`]U!]<<\V?<)\"H0>V1XX[>J,"-E8[LD$2DE.0
+MQ]*A;49:/URREEL9!G=;?HDQ7LOCO=0QS,E5?Z:IWZ(O'$I9+IRLTCA>2+:0
+M=F2BGI>R(@D9[(N&4WLDFR/!D%6RQ=W+M!EBDJQ=VU&;S&ZO?N?OO5-]Z0W!
+MG3I79M=QNI/*C[S>Z_D]K@#RMCK\HXCR=(8X\,WEI1%YY5JD(22"*FGG9+S#
+M6K7Y?164U-F164..B.OF0+2VR:W#<\]K3E40)E#A118102R%1<H:Z=ZPI\=,
+M8\:8`FTME4DHCM@DR&%M:TQVMU@&$EP5\(8G(:J5ACX\D`&Q".@)`OU*4V+K
+M[+1.%R[5(V5H)W=%/&T8T>!-NLOKYH5*VT5(2S0TX]L1N$!7P'`%B"\,0&8`
+M'5;=936B<ZXTGATH2.:4:&_D[LE:<)9MX2FVO>UF.MZB46]H""W-F+2M+`B4
+M9F=M^'4"Z6L/*_X)UK4+MAE'.SM6(]'#\T8\E/8!S6QDH2KA2E?=#JF54B]V
+M5F7S^QPM+(8PS4PU^R"3`AVAU8'">N:>=4!#R@)`NJ5:S65^6"T1PY`*$H?9
+MFU1>_#06H<N;O*5WU\:8(W\+$%P=TJ7A94,&Z*DCPCC*;+:""R*$DH-VW+\F
+M=,M*3Z%L":,R`BZ6*AKIM+<(E1)1-\U:O",9D,C:=,MFU*D38H,-:H1G%M,P
+M]24>=YAG7]%=,:\\M57-?<Z.X05(A1ZK3VJJ^L+(:M2W7W/OM=)9>"2M=S;1
+M@EF?7M?Y")'R1M4#?J.8M9!IY\(ADD,"-NU*G<7P?QG<_79MI^><#S;JM`SJ
+MHCVO6A1%#M:'&%/989TT8G3K3)FY,,JLWS?W8*FM6TBQYGDU%1]/@-%W[[3A
+MZC;UG7NS;N?+M'6%ELNC"0(^L8KVI!!AJWSQ_)V<=`[M@0G5D]QFD(:B`L4]
+M3]PR7G$_:N?/MZ?&]D*=)ZXJQ/8/E\6'P%"U\<WV7`!(@<"(#']1A2L&!4WD
+MB:L(:00-.)OAT8Z+B%$;^]P<00>W/\',G4+N`:$C6/H1"CA$W56[<D,Q'NF"
+M[$O^52^>"/IB['XC7689TF+[-^8?]5ZL1?(G47JBE3+<1E-*+[-_DLH_&:.J
+M_V'@56#F.U2F896<B/U?GQ7AM8#U5$$)7A16<QE*L"N0A1D?M^;1<M&SGJ!:
+MCW4W\+(AU<1?+?2TP+Q&'1?LF>VU;0#V04VW2D"D#94W1C^2P+Q0_9LA?<H=
+M9-]#>(AH)":/I<H^+35^L5'$TGI3'8P/$\1]8F]]?*34_'?9IO43<XOKK&\G
+M>8-9O;I-!:9+3*]=R'6R2&O^YZD<>1:Q2*.H3-D?6>L5PH$&(DZ=H.[,\!P$
+M/-N(=.2ODO`GM41E'<'0;WY-9O@WF]J=FFKFI*^+A(,\-3K4(TR.SF;%QAH5
+MV$MC;/[JS!D6+JH]Q[VM37W]?NK/X%.TV5HSB2.(`#$:':-NAP`3%4)J5B6J
+MI&RC9E`6!XMV,@D03<>I0M8Y32N&DE8*'\\\`&1L8PU892D,@Z)97=`-&6`8
+M(%/_HU8MJ9N)?5,8DR"Y39HY<U.UG._%'``1@(X(0-B,6`-`Q5YH=;Y7\W+W
+M:[]!\_)EA[VGZX84?@]"X7D=#[/8_7?I!IAM/3<T7CLU.L`;O3J>V!94"0#7
+M](B"40'?.&Y&0B&ON6"W&'>?"CF]?K3>FO\S02SE,%DI'L`F!N[[AP"18"4C
+M6BV8;,_9X6#.245!L%-?N_*)!E60;"-("2YMW:EJJ)*D27)@*94M!Q(6J"+0
+M0I(D`F`DN1DUA#>9MKLU%Y[Y2)JQ896UTHS1(9P:)G\P_X<R2-O>1*+>+!K;
+M%3BC?]/OS5%$$4&(CY\4Y,Y[9GQ_+1T[^W+4JX0,R:F=$IFMIN]+.[?H<8(:
+MC'-!7&X1YC0N<U)3*]Y.]?HOWS7,:YC1AJQO1@P@Q/4/G$Q5V45IH4_<DZ2\
+MX+2:4%L,\(02Z,\QV0EQCXT^5B]>0/<N9#JXA^?=Y8B=Z5(/L;S:D8JAL2CT
+M9I#3J-:SPM!RV)+JAX%2'J:+2$NIH''IAG$\#R%%,AG(J''*TE_H68SN81#]
+M<=*,3W>%&,ZBV;HX(0IW@ZHTVW"F;`HI4)E&V/JJ'FDVIV9[/=`TB5*%H<]X
+M=J4"CD:A([0>>6L0AC3-,$5F4UZFV.VL\/,S55?6'XP@QQN[O;L\-.T:*-#9
+MD=*5F0<OK[^[I;K=@1-YG0-I&9/(=WR\%4O8V%N;PT*ZL489B(6IF:E+2J1$
+MOC@W<FA>Q&2$"##!@ZU(3D:;0QK(0F?`.^MY'R7^^/<C-`<@8.>H"MRE/=LA
+MXL=-9'Z6DF*<FLJ;R74J_6'F>:Q%LQ1%A*\,QR-K#2\.&#`&V4"[1=Y7^992
+M"""0(1"-@G;J*BHNB#!MC(R(RPJB&MK6F@(>W>R1"4=0%ZIX5`'&8P"-[/2B
+MNW[W'ZGB46%A(P%+T,0XPUNAI(+(TO9,8`*PQ;8*TQ-*AS)W["B,YLS`D\T@
+M2D@2(E*#V2HLG#VR@J,8L%'BE;UMRQBL2U3O9SS>Z"G`<-UUWJIZ9-]T3-G1
+MR:W>L""E;46%`JVN:O-JK\-J#WR)(%.Y""N%L@VI;)40"8DE$EWW*+`FH>*S
+M,E5BM%""A!+TT;'CCOV<2>SDNGO2%5"L[B'1ZO@DON7@=3D']>:#\@T64(S8
+M48X56#L:?`1?B.S):DQ0>?;M-\3X>+>>4F!G:%1:T0&C>7IA6)`+N&+JSQ86
+M%CMWZX6R&F%UAA_@:S0D?L1H`XOR56<ISU$38<DBBE+@/`2>PV0<YR;8G$G"
+M^ISK-D,S2[:Q=)7^:T=Y[?X6SH>W[0F>`#.ZRC&"(P=4BPYNLT`];+S3#+HM
+M,:W])..</F(?%DV,$3!M5-[<^7AUE_<8H0&#&@8CV'"<257JZOXNJFD@;]Q\
+MP&BBL:T]*?;2U5-6'Q;D_SYKP#!$D:B6@I$HR**7(F0SD*^K1F9LXI,M,;K,
+MY.I-BT[&ZX0I?3-EQX;%]YH:/AUJ32MTEROXJ:=#33W0]_9"JFV<'WC,;9_Q
+MKO:C11E^F,<\-MH_#>L&L;.2_Y4;Y".CD%NW[ON)_48<>&:5I("_EW52(0:1
+M1)_H)!H(HH)`76G&CF5LW$BDL>O!=]&D+!:17N$F:TFBR6'WTN']F4+%V%B]
+M",71U<UX@Y&"-1J,7RLMN6/63`RL%$Z-QARI2\S:'BXNF*_%3'%:S/9HSK>]
+MUY>,^UI]-.Q#J_9'K]P\D5]#1^"W":/)41?;/`-=>R>3`IN>6U^<P)K08[LA
+M-_3OM38"HW/"X9!L%I3OW"+2OM4Z^)Y2Q8C(7R3VVB'(/<!W\&Z7M*)/FUA2
+M#WL@Q6XM?=XLYLI,Z]#_0_B#\[[:?844Q_6&GDJ&LR(X*!#ZQ-*UI:U_A=U6
+M?`/_<=Q=5L/)<#.#*)S,HF'QR<%\#Q,#86\0%)7853P@V<4+/J*4ZG[[^LZ:
+M[%C-=)F*-UB+57"CR&5PH)?##>:*(S.EP58B>EH;:@C:(O-N<?"ECT2@O*?G
+MD._1>L2QC3MAGCSG<DXV85,S-3+:6"O#*,8;I9L@>-I4L9N>X.CHH/3"`_U_
+MLN,P9F-\O=E+HM&S46!>@?<?K\=;BJ/)?::E9V]XA>P>CPH-%R#&!S*8TT[G
+M::LD\RU1C[4'DM?XOMX1_9^GC-B(AI0H#TJ>A,?&?#Q/AU&HI1L?M.->N2;0
+M"[,$^)7'[@4XRB+T/7&FNT0VD1UWN/+5#^J1&LK;AD@XH5FCY3GT*?5?>7\Z
+M]>YY$<C2B"7P_GLDT)BB"*(J)K$9D<*Q>C/T'RK./J?5ST/0CO[!F>GIZ2QE
+M$I2Z^^0/`Z\\&I'I9/U22I5$8,2Z%_\V]6]3J*6IQFM.XO!R9(/$;CL[_=V(
+M!ESCYR!KEO)BF/4N/90N$2)R,H#$:@;L0((2P:4"P09&#,.GZ3PIL.4)S^XT
+M>7Y*<3JEZSQ]!.S1;T844$@Z934^?T*\,Y#&NUBB6;N.98;3$V\;M&;Z?QN5
+MA%UY1GI,4@'DO#&4SVP<H;$R`H5+(B(7^%G4Z<@<,ZD(:]JRB2$9YXS<Z7B?
+M5B;,&^"8Y95<VP+'UBGK]K=`D92$$XPV"#$ILC2R,B<0;V6:`1<64;38@9AH
+M?MZ1N4`O,*@ZW>F=7)>-$Q&(89H,#@;$`D5:$2E#(HVJJ431DS-4A-7-550,
+M%G;NJM\T7,D'"W!"D8A#5E0/!V16I(U8+.9N&$$:$R@+;D,5E0FB"19%0L2B
+M6!?#3%%@VS,30ET/&4Q;2Z\G!XM3A^`.1D.K[FP>OV&+Z;X&G??_A;ME?.E)
+MO.G!,$_%`-'<R%^3U'U8:Q%P!/.Z2E6O/]7EOJ3\6"?]'*:)1(81K9M]OO+O
+MD],I:!#<X<5T6D,1">\B?7V=CM+HUWOS=C^OA)XF)XI>G"$^#OIX%!1FFO3\
+M^R#YX)A,)A,)`$GUM?SY8C]BR<(5:8=-H57N?']'C9@T5-\0\K!J]S9^I9)(
+MR'\DA0`XC7<+Q8I3M###9B-^&,8&FUW(&H+&UW.Z\3FSRMUMY,$N[SE]P@>'
+MM;6U.U*')>7V%1W!QB!D');WNZ^[!/R*)F(:4!_A&?QHHB&>I1$1+`$\$\K-
+M:+H>(M38RCQ7`VE3M<:&KM`&RY^B-WKMQ5;Q[H&""S7P2[@2;9Y8,/[ZV?Q%
+MJ.1BQ^U]R3EI2,BD-VZ^^SS^=8>Z\PC`J2"D(H*$4!8L!9(LFDDJ`H5@+4%!
+M1M%(?X>OY_61OT(XR>$DDLTW^TK4N=Y#ZLN/].TT^MKNA"+*[Y>7:[:>8/^-
+M)T819#S0GT3+"(`8A!9`46DAL20V@2YE<3]J^_?P:QLN:;B!S-:S3Z79OQPR
+M/"T2@*,`IFH<O&K:8QM^.U^=\:DN[T<)29].-%F8D1UX!*?1^]TE+!`XK[:A
+M2?%]?/S[H&RQXL2"#,_896"L?E_5O])]64_MC]0112"'[RA;<&ZW?;E`^5S`
+M(:KW"RPFJN+^T$4-@ZH/KP``J@B,4`\S=71#$Y*AA\7(58A!D65T0(PQ<.X'
+M.PZ;HFB[G^7S'P3"<7FKO08UW<:S82\&GA"T6!C]!"\5P(S0DG]#NL;M^[FO
+MM99F.2']\7&BKRW(E1%@P7F^]Z25#8PXUP_8V?H?T-Y.KZK@>B!I%6"#,4^Y
+MI@5-KX&$<&F^-W=V"(K"!:VDJ08YQZK@EGQ-A;[C%FW]SME?;124**R*(22'
+M?2P3!55"9V0PRRZK?%^K^#7E7YF74<D!H_3))KLZ[^;=-F59$I#Q&.)8G4(D
+M54>CB&1V]N9S.5S7US.]0[85ZL=D=6EJ+O(_HF#'.;"J-BL+-MGPP=2*I5?9
+MRSVF5FARC(89)Y[51=6&TVPZZL\,&1-533*N%OI'][Y>O6_`QX`?KG.(XLG:
+M]'Z]/1LW3&D4'IH0PSV5^0BS#5-,[WM$WX0(^TY9;'=LVUY)6VL+:_YCM1YT
+MEL[).(>M2$X5E;HFKO>&E(-E9)IN6?.=]"+/DKN>M[!7Q&&S&%):]0E""^B7
+MERBK,R[,7*MH**S:TC`=:Z/)%;;NUA"_;@;+8WO5;IMLXP2;O4)GZF&7:39!
+M:K;OV\-RM=9-J?FID@G!B:4'_L/2@6H?JE/@Z]R^-%#.]6:>^V,IV<7K'5-+
+M1)-/!_N3MM/^A];T!/]I!\?S>E/A/HOXWZ^7`=VX0-UCT_%BA(HU8\51FKV\
+MLQYSUP`/5\Q!2FPQ0"C":D]-W_BZ[H\OU>PKKT9HO/".*J$16`H!(Y<44#IH
+M-`R\<RA"D`S,"0K`%B&(8E1&6FB0C(J"81EI:2ED%R@"RH%RQ=5$QTM*@Q-$
+MC8:E`SRI66A($"`1$BD0(`045(I.!B@LHH"K((E:,48HQ1$M`:<2!)P!P0D@
+MR2<3#,@$AD`'"`@R``<7@Y`,`Y90),(A!204(BQ3#'"2&"I$2"@`@K!$`R0`
+MJ&,D1C(-L0F.1`"&=MX5:+YQQ],.W#'N;8N)DZGOQ!<"0`<Z\,`<-"@Z-542
+M4JKA`B@(A*%"`:`J\"TUNZK413K<&V7+!`$A:1"@<J!J,J`B:(:@!T0?KIPK
+MO'N#68J&6%1V+K)BB8W>8)FZ(N9JY2S$T(.J5CLHL*)%)I*A1"I!-6%-9AI#
+M0AA2KGD3I"2)Q)W>@TA<6.@)/"J1`1N*8F<I<H!>`[L,8+`;NB-%(0U@G`-S
+M$:#`1>9JYZ9[GY;4A(2--,P(4@(JB00@"L&#$%@R2140$5(1!D1&""V3H22.
+M@`Z7U5DDQIL8--CL'RB@%>OLS4-]%02$L'&*DJ0+V/1$P;!!2P52V(B2^C"$
+M6*((C!&(P162*([#4"60U`$)KMVZ20-R!)ULE)J9H;`54$5@C(P1`62(HB+!
+MB(UHE:D5C!61140A9!A6R0+"L64L**#*$^#X6>U$D@10@?!))$:Z#(PX<$[,
+MWV`<-#INCQXWV!4^A:DZI8&+KO7OL>G@V*V(J]/#5=Z!R2(\7RX<^-2F.^6.
+M\8\]D7[%&?<];[5J;R-G@'+?2+$-;V*WK+ITXTP=_+SL%OOMC$<UK@[^-I_"
+MM==\&O1#OXK.-];6B*[AJR\+[VR<6NOX.ANOLJF*I;3W[@2\8W]]`CB)FQ$7
+M=5QJ%45J;?X5^0GMU'KWD*<FNU>NWXW_?=;?1EUQ)WEL'QW6\]3:-[1U5$Y'
+M;5FG#N[O-07\5O+[_%P.SS\AI'(+(*'TPWQ[\G;+D4[6H(@A\"`VQOBVC@(X
+MB7%BJ436M$58=(.NQP$O-YWSLH#I$4-+%*XUY2@VQ`605H32B5448P@,C^:2
+M0DE&$#"#"Q$1&(**))((!!)K9<_977T>D.KL+5MD822+&,&#V3Y.XYLT\WVC
+M:DX9:GR8A:AF&T0/T#1A!$($(`Z(!2(&@/L[HV;P8*,_(#4S%@?3'2(`0T*G
+M"1J:E-'@`IEHI#&NGZ/=5:LX@-/Z+34\]>;X3:?1O+G)'G>73E&FG8GV;R44
+MT[.+35;XC)K:^@H,"M8W3B[#:`J3V'NKN[L$M6>W/6*^O%&ETP.A*LA/J8)"
+M/'%LJ>"3X5!+SGS5(^MY^WT_0G=`":_70(H-$.^L#GL$993L4M5J9;LG5JE>
+M7=[*F"FL+`LD(JQ4<LH.\4N%5IPNXBV\^<R'($G+4DO694A2`T@HD+3L-D%X
+M2@HZ7$EJ'SU_&=]1((Q3A_G;?'`8:O[@UN-PY%C10V"'@MIKW,:NM$(H$0*@
+M1/?W6C"L05+7%N4>76D2O8MFQBJH38@?EFGYMT%K(*JP;N=TH%W;O7>W7Q`3
+MHG/%GLT4,4J5/)@'*`9SZNF*:D)1(#MI_VMP.FD;\7X=_3Y*.9SL=P?A1VY?
+MNK=T@]V\O'T/#O?L0J$`D`>@V]#HOL6.W`9KP,F:50^20QR`6&4`N*"#6B4_
+M1T%1RS6-/2F,#G>):V/19K?,?:@9:UK-$PW3IIFTP@C'?.F\S%-[.A)TUR\5
+M3CFVFKLR:T@=#(9&R65!)B)H[$T(9*=%051,`O&'L\J@^9=%T^L#"DR=LL2E
+M69Q`W6W2@HQ&J@!BSI<@-E'&<SX'.RM$_2=7&Z4W5$3D+OC&J5<4XH:$Z&+L
+M`'KYSP-[\U*BV*;$,[H*"CAA0:6B/8[2KT1&WT'65DR,M>-_6ER)G:TFJ6K-
+M=LUT17`6W6MEOM>K4H][UO14M4G+NJ!Z'P@%S8FAN0^.BWO>K4\W1QZM^E9"
+MJ;<,.AIH^NF#.\Q4\1;2-I@1'*IW'3CDQO*I>][;R.,#WQ!,85Y20KH=LRH`
+M'8TX!H+3:+,BZV\8[M$GO902%#'&,,4*%DHCIU7JS1>8Y;)@-MV:31Q;ML:4
+MD$%UN-O!Q</2!!I@*;K3+59:\Z\+*<BW)W!D';&Q"M5=XU!LE+5F$M"#8$:G
+M`J+,8.Z7AA)X`I^15<KP*/2@A1L^I&B22(1=NI=1"7*F"*$#664M9:/#.I>8
+MEN2I%C4%]WHVY0D82FD>?"U-T#$PB%AZ%JI%_J+#[*,DBT]=%<U4S%<,%7,.
+M:?$N_DZ.CWEOAF96UI%)8LJ3@3"M11#&>]E@H8R%5DC!/'OS6L]'ENY[WUY?
+M:&WGPYP\N=(LS9WI//RY#WN58+*=IZMTM5<^&XVBU*01)J:5;3"(46%&-*,B
+M9E*&;4JC2'#FLSH9.._?;?:F'%K*^K0F>=ZL&=4!48'.U2VF7P\-:+`#FS"2
+M2)-,(B79&7)L&5G7'.]^9<P^$Y/0^8A4J4;%>XHST.==%A&+4Q.P(%$6N0@2
+MYWPQ5BA22JZ!81@.4E3F,N\<W:E=MFV#\`0E#0&MH46Q!(>$LW/)HH[&&3(8
+M/CVN:U=RMT=Y/;)U\CH(P[^W7D377J-WG!FD#LP\DTZRE-CX.*1YYN,UF-S-
+MM'33PNDTE8+I%.N/H;SN@)*(`Z2Z1,J<"*H"34RE``8L"-N*@57+$ZTF2J(8
+M@DM20C)4\NR((S;P;;XXT@-EH^#3RV/0=_59:7!1.E1!O3NG4UP;$P@MZT@\
+M\+L<6J%Z&NFJP^^,$!2&0R8OLCWQB1TJJ@SLE>F1V`GM&]85XH*@-YG4_@,N
+MV5':_JJQZU#Y+$CU!A!?LFKUM1A$[,9OSQ<7I$`QK4-(&:T8WUVL-/A^%JY%
+M,T-`-"VD8@#4#&V%O7.V:4#[[)D`-)#/"7+F.6^AQ\>UYO`QC=/6#411`',]
+MM)Q'(B^KU-R]-J$,J"40><(G9[LRVJ>;-%$JDP:``LRG#[M)-)*RF8021)JT
+M2CSRRFM4[)+T0V1%KE,4\V=7:*046+O>!9??Z8=YN<>-)=%*D66%COU?/AK"
+M+6M<O5`D4"$[T1.B[RPM$,23:!`V"+M='KRV6,L*WVBLEV6FS*N7&<\'0@H`
+M",DIBZ,+A*M/&SA4(0-95-48R]2P(%:I1BZ+0MB0RI0L=])<K+I4L#<.'1:0
+M+O;S5NZ$YZC'4;<;UJ2AIZCGT!T(+!RKJEE>A)F_XWXX_/5ZR$YY7G'FEN:C
+MP:*)&D?J.%N#VE>?+,P)#NE52-JY=9AKM/1>MC.5V*U2B#,WB8"(36=F1T*1
+M!6!^0O4WF(X0;B?A"ALI`8#NWIZQ*;=5;8\<*S2!&^D.\0\+@0&#@JY*0H<=
+M[=KY[HP.]?IJ5S#.](TIE2`>N7:UHFTT9<,-U'5423:11`HS2!!2!JN4RR*.
+MJ"82&"*)1D2I2,'FJU7H?$0O8VQ5,QA4/#$=T#=(KDK*[Q<2T&;[[X(T:*;3
+MH8G,9E"^(@\ICM*X(@`XSXNKWE4H,;)7`]4YOG`MC;`Q`2Y"]+8A.*9^`\_J
+MDQPE>+$>>NE:HADHC4R0@T17P$W`Z*%4GS=5B.O%=9`NC("=O5WQS;H-Z\0@
+M#VKNU-CG;W4S=Z;LFRPBH+IMT2Y#T:UZZCS)1@=FZIMRSD;F^LIR;X`)V-#7
+M]!9`\5II+77='8\FU(@)BM58AYF-E>:[6MBTT$3AF'3&E9=**+:!2[7-4'9!
+MBJ6Y:M=14*!DZ,PNB;0*MVG/1%F<_1?X=!"KT@(;&-C8R*;C06@XI?96Z&]%
+M*Z"C+I%L7*[PA7QA>-%GAA?K"`32T+91.R"#0Q!S.VS[-\6V*Q[<(%VVZLA&
+MJPN=MPMC7:U46KBI'3)`F+/]WTU?P\T!-\8V9:S..Z,NWE5]P0T8"C!I1!09
+M57ZI4'D.LN,12FQWPE;GJ;5KXVSD;>)\^>-MSK`/OG//6TR""-;+45NS5"HZ
+MRA@L1]%#5N^._@UPA6+)5"#"*5)!!I%54^^'H`>Z<#?/35OGEV::Y0#\5$FR
+M;V[EBF0ET3H1Q+,R*;<GMNMG60F<BUY:@0YLK]8BR9NH@,;`M684RLLRRMK0
+ML`@&^DK/?+8BJ,:)9V4,5%<$KIFAI#*0L72L&Y@U&T35M;7BP.:J,LI&"P35
+MZRXM*25;2(]W5:UVQ#7N:)?4+;>*:NB[3CYW3#+9^QY#VNV9F.CQB->W4'<'
+MG9`Q:;!'9*IAG/#89I98,E51]L)@M@V$JZCKO1!?CJ5`O*@)9--8VD;5"4)4
+MG*0ZJY=<1UO:;#/W97.M<,+8E8=+5F'>Z!25#'6Y<$:&[HE:9WTJ!2B%`;LU
+M6@GA9S9:DS1,LF>PC4.2\IGA!LV=TK6\:X06I;;56%1C%"L]BS./GL*#GZ*!
+MH-!0C-B-[.*J(2`$#;[\7%WD[B3@X@0(@BZ8L*-/-46)JKH,\\FD/I<30M1+
+M606@TH'1`:4))H$BKQ7'WM-IQJ;B]W'A0$UB.$:=A/%W"ETM`=@M<WE#0NJB
+MR/=/5&/77#,NPS0)5*:K7I7I%!(<!#2ZD+9U)9-6;,`\:XR.2$)^ZFH9F666
+MN:3GSQ6@K[%91K6M+7NL#S;1M\:V2%\P(%;3NG=W23)/5DK9%610:VL^<KSI
+M=3X=[6&HWLU;%/Q]+Q[.IL_V)^<GS>OX5?'S7J*_/$0MO9Z=4?T];^KU?`Z]
+M4GL?Q/,]LL\'GGE0];>NQL[$!J[W"_/GY*V],D>%>3H(U1%U(ZKFO4.OU_G;
+M^_-?-;)!`-0ULW@7%:RRU'Q>_4"X)O]OC]#_R*#[$!!P<JNQ"5X,U($0<C7&
+MA-`;1/&,:>$D/I20YKLL#B<Q8Q$C",$03D#G*##)"'A]U]`/NV"A1*R5!5%D
+M4`*#6,K8EI6I%K`1D6"U!96,M60*R$`24*2I`62%@`A"+&(C)"`4@D@)H,W9
+ME?D;S!'15?Z<@'-O\#%<@A<WDYLQC',$TDJ_F_D]]0N:0UC&::$6#!AS)W$H
+M,.L@?9/S?L,#F8343#&P'##IAF%T7$<W<<*0T[T6&A,M(LRU2H>`0Z0A$(GE
+MQ..[WO?@BITG/H/]1`WW>0^"9%%P+0XB"1C?A$1Z9#",V1(7%0OS$7$&@+)-
+MHC'..^Z,B184:(>9!STU0%K!&('4@!L"GJZDAEED';A0&3H=(9RW@UH7N8?,
+MRV#03EO3SJ$^.^`^`IYJHI2S(4U)2>9)$O,(?EF1(E%6$\\\/F,/A?"MMTV'
+MT4N!OOZOI5##>`AIQE&W?P\PG1?$VZ:K$Z12[\Y1D=KWM/5'C!I:@M-Y?/U[
+M8&XN$%?J%\5ZLU3K6;P_5YSL94XG\?27$/DYM*""^$7`51)#U;FP\Q>Y:U2L
+MVP_W#N:*-)YHMM!>LIF<Y=>+(IG9L*)M./9*VFTO7=L94.]:B8M5%L3!.5N2
+MWCT]K5U5<[JYUIEVJ)'"!,SMS=\;Z:-0.)V2J2]994B04RH*S/-LG&(C`6AV
+M:^)"Z'7=HNF>-*PUPNWU3K6EJ<[5=VP/5"CI>S&5TS>,I$^HR)KNLXZJV2_2
+MO3?',/G90J'#\POH@9G:\7#4@Z1%;";6=5<($0X>RTVL/57RO$2GAL+SC[M5
+MO2=)5=L)8Q^'7'X=;_G[H+RM_SN7\[=O7H/;*56_?,W8KA&>#YE_&(D6D=?-
+MK(\V<_H`/<B"U+_8@>L]O='LFU9G-5QF[>]J3=^(C-IM)O[Y_T:OF(,SM^J]
+MZ6V+1R?ULT%>;#1@/F(9]+JS"K/2D[#*.W7BU"#DK,EN^IA@5=G'1KT\>:7&
+MBO8BPWQ/Y3R0QMGXI;YYI\A%3*;60]+D_?!8#.CC]ZFJF\U*BS^\/QV5ZZ7Z
+M#?16/OT^3C6#`<C"A]DP]&V61K4"323P0UF5R$2"L,@]'=*4H&L1PJ"0)+^!
+MYJL8N@6`#W27+^#2@VS(6@^N]5/TDTG+%;+<P#7-!I@AUI!/Y.@F&<@F@&S&
+MP2OBG90M=*YRZ00]MUX(RZ6&LC![RH^TR$`[[+07O4I9@%(&2HZ5<;[NOA%!
+MK9+6>P89S3FL3\^2B;\4H!$;#A2@CHM[A,'8[M`*S58H200"?$2MPAJGI49)
+MP+Z*.EE&4H`E`!4WW<A0,'0Y5!@N4-C2^2WB)/0V]L(1B3E,YP%8HC$[VK8O
+M.\W&Y+4US0"(@31O-+-N%JST^<G-1:OS:I05I04G;&DC(<EG;BX=91N4M021
+M2BJ75B"((6L#+O@B13[-_L*_2Q(J-I<[#LF8P%K4[,&*[N6LHYX2"8@MPZ8B
+M[#JSU?/$U([$2;F>FX%!I%4"B8Q0091=)%]>+XSOLU(Q1OA-2'<U02R%-"`B
+M!:!A#D/%DU693H5(4(^*"]S%4<2/A^R$@DDTH"7;T:JP7*6(@*`H"J$M)VU=
+M,W&UR@K>X<QYJ#1;<.!7(,FBQ%J58-A6(&XJ)TFD'N9PQ>-%#T*7OZR&V2(@
+M=YBQTDA2A2G.#KA:C)H`;H/M#:WFW[Y[<TRFS!F4H\COU:?`M6"VY$'B@3RR
+MHY$/6E$,,]`;@F`P`[,Q,F#`2B6#:6$8EST:T*-2A5]S\L@5E6]`^YSH1F#.
+MKU)!<H,F9D3Q<F6Q/(Q/#8<8B^?#$T/1LK`J'F[\;HYYP,8<I4=V3?;G.C=<
+M9!5#$J<%:8S&YF8S-U93-[=&*NJ&V8BFT-(8,.ML'-7G)"(JF7%&)*("N$FH
+M)LI8%ZWM+1C%;)%O;Y^O<-O>Y[^I,XZ;,(3HO%T@YRC#KUQ@1U\O*O7"09[&
+MDMV?10NVEM'3[4K'5PQ`S\:"V-M>A0X&B,[5\FU,;FIQQ-&H(2E!11:_:JZ:
+MB.!:L.!3@VAE2]4CFZ]!U%N>E6Q,L+5:@Y\BE.J-JPJ8I0F**+JT`20,Q-=>
+MMU/6SB'J;ZD*3IDL`A4L*`@RE[J%;HY8<E*QG,J*D))"@"3&BK$Q%B#HHD&(
+M`(W4X]H:8SQO"!V._@A*\-F7.BMD5:P$-!04HVSM;A.]:N;A*X2_A+&:4Q7^
+M/O773OI_'..])PO729%TH*$@4)&X)7%X5@'.[1([6,9ZW5J4%?.V9JY\Q\;"
+M0=\+?T(X9.5_(Z#Z\;SKG;KPNJTS%1CK/3+KT_;+M$G*[;)ZVAOA`=37`.R]
+MUWX&3)AET>)$`8%!@BE=*EC@F):Z9-[0FFO<:QQ2!?;0&QF#Q-QDZ66K,*EL
+M4X11EE;GVGY+R4TE1>H:PA_N*E8<UJJ&I0-^H^)>C^]%RKCWQO\0EOEJYGCH
+M++:;IOTF2KB=POSK`,`H@[@=<<C:;/D7KCSU5CD)LE*2HH&))!`W[$6O[;K%
+MJ'<;'=XM'EA%""J+&/0>L9$Y&*CH&2I#Q1,KY+;5*CQ[+\<9&PR*X1"-T1P3
+MEN_JB5'+M=QAUL`+W..:7*BS>EL"E,H@R(I"REDS9W;HH":'MMQ5(I;N1CA<
+ML+5HQS#O>:0-!P3)<RZ($68D&71@@4D8<R1K5*Z'"X2XYY3C&6@DL\CP(:&:
+M`X&F-.J(B'.*JZH3H$AK2J4\96)NG<L-K99`R4C[B4POE47\0"=S.V%8;3<%
+MB8*9"4>Z!2"!*('2RTJ0IH"=I10:%R*("!:U2(WOS/8R)ZEWLE5#QZD7VX"W
+MQ>.T<O%Z!>?3I\53:U;XP9B):=X570XO-=WS+DA;>9@YV==;KNS0V%SAY$.&
+M;97K!<W>K?"D5;2U?CMF^R2!9.40,=GZ#L*]%6'TCRX8-3EGBIO5JJ$+34R%
+MS4LK%L35(FI:XRP1D&-)9D+U?X]+=^U>%;968:,^^J,+3VWHS5$F>*L-V0@2
+MK$=SR7L$=H45="`H<H4%0!Z?3:K@`);5WLEDXPRBR63O(HX[S2)*ABE*FSHL
+MO021)"$@F@)"8#2E3)7I"WX?,DO";6N=9MH7O(9)91L4S"]Y45`%R*.+H`+Z
+M?4YF:C1$&[D1+,IU796H[:2,\H(=>"**I#29VVN02A.D$%T74M-4B2(<$$#"
+ME3+BFGF0Z!EX/'A;<UX?:V\>4<MJ]6,&W=K8/T%[18GODSI\+.J]_$?0'TQ9
+M<Y+#_BV?$7W0_:7A=OX+,US25YZQ<NV2"NS,S8CWUJ$,Z0+D60S=A45=R<G$
+M)'JDYT3\QU.C/U/8HQA$3::<@V8Q$@(]3/#9^]C]%)6NS?-0%_77-`#K,RYJ
+MXP"4@?<$)$\]#;;A@Q525Q9(A\F&_KSJTL2V:R!AE#I930:LQTFT4Q,0TDAL
+M=:L4FF;VZR!65Q=63ZP1@DDM#Z0#>=!`;A>R(AD+/`LGEEEWXZ,,]"\1CW[4
+M><,@5KT-L7=X%-'&Q%D"V"P`;*9P("("%3LW2,4*,HJ4YKZNLC1R8$1]'H[+
+MOF+N6!6THB?"B2BNR6U*NYTCCOZGQ6XNG?$+1T%6RT2UY_.&S`SLNNEN/9A[
+MY0'YF=\;G#6;B[6$#S/JMF2S-;.$0CZUTSB>TUU*XBBX1B(:P^I6#:<=:WDM
+M*L&O=VP5>)7QSA36O%\Y#1OB`W+MWKC'!X/`N]D=510<%-'1ZB-1-[O]OG,Q
+M:^E0V#WQBVS5KX+MUWM35J2G24]U`GK4Z+%$*=B[YG_I?PRJAQ'!Y@B;GX7%
+M;LJ9)_X)M&!K()K(H:#S3U7G];#'OZ:O^CR6HGSZ7CU0CWA`/06*Z8$S&H[D
+MLFKY%_EL[,%^@-R@8>1ZH8-T<_+$KOM7OX52,NA\N@U@&8@`2!DP#OSF*5&\
+M$/C[#MNG_A\[=L78?L_\]2&KX#%\SSL"EN<*EY1MC^TN$#!DFXYC,L##-Q2$
+M@00DA!`.$8E=[9WCLCMSK/V3YE]Q>[ZREV^RB)D;,\;F]/Y6]ZRG^`H<R(6_
+M:WV3A]=4'P?"</['X<V7+>C2SM?D=%_%])D*!?1`M_+NA\X_+@'D;T+>O/6T
+M^Z9[_W1_PVEI,D,#"5O>P^'XF:I7M/7=`83?>]QP-3RJ+@Z#]WOJQ3I^VS-K
+M5%H0D/)`BTRENBU#P?KU\C7WL..J$ZJGH*A&Z`J;+>5.UHH&D4D8&622P8`L
+M"`,@)(!!X^UP^[[/2\T-M[58O-BZ?]U[=DB*'"YWIT)O49>+FA`1D!R222RX
+M@7\N77FVIV/"5"#=.^X48.JC#A=/&%@O24G:'8P/6&.8#[XS!VT0?YLDT691
+M9Y)RYQN2@&3%#@H(-9*P&)%!$J0*DJ`L"H$&*D8*0@I2(B<G>>0Z@W'VM-O.
+M=,QX^K[NO@7U-G#7PAW(YVVIGKL1)P^\&\F9[MQ_M=^_9^*_<<3R<DLC0I\5
+MVD6DB[NL[E;OW7:WKT5/6IT>,\RO"9YJU,[RBI(_7E7XD2$>ADC-^Z17<?IV
+MIMC?UV:XQGO/LUIY;ON:MA/WD>UM=E4UWY=21X/0UD)""\0Z%%/S"4RA41(/
+MS_VMQ404%/RO_UA].PB)!A'7(P3V]'\K\;G`2<1^YPZ!7WLO66V7#6*:A(JJ
+M:DC>;$L"93&MB.=A&$B<VZ_ZV3R:'/4-$2IT,Z@O(0%SIGHS><2@3HBHQ'-A
+MYWXJ<2:=T)*`/Y'%<6FZWF'#ZY^O4K\Q]/D+UIN\A[7(\E])S<\\:`H;AM^\
+M%N!O7'6M>!]5,&GPW5+"A_W;))]X,)]X@L4D4D%""@%0*RJ1"I`*D`J"@5(+
+M%B,*,D*0"0`D5:*$3LC\=V%LAJ]E*_6VOR3;:BEJ72C\"2@R;^-B!=FLX&63
+M`ZLM6CE31ZV]_;H->V7,RKKJ*U0&PTP,\\C8M>')[>W&4/,306L,)'L0/=OV
+M=-%#M?NW%VNS^I*4LFIG0^TJ=WON.<KP_.\9[3=J8Y;PG,+%PDFQ73CN@<=,
+M.ZP9198-@TL1M*U*B+0EJ5C!I+"L1E4L;:HVRU+1"M@L@HC0JPMA046*Q6*B
+ML!%C!L09!6M:BUE!J%H-06MLM5L"Q0JHM%**@-8@++&VU8V5M8VT2B6-JC1M
+M65+$;+*A5)9"HB"(C%5BBL4!2((BBJ(H@H,$$58@Q%1$BQ@H"*`HHA04&(Q%
+M&(P55$8L8R)(L@RV(K!1E$I6`VMC:P1+1(C0K(D*MBE"E&%%24*#2U*4:@B*
+M"Q1$"E240I4$2M8H4!0$BL4!K1$1$6VTI:#%6`M@5"L`HV6U9:LHD+4LM&M5
+M*RP46"-(>H_@#\@,<GMG10/:XQ;.'BHO_T4?*6Q\#FO(Q+;4O[G!FMWCC`XF
+MO@T!O?I0ET$0#%\@DYS7CS\P]WMNZ`1N5XSP#94^<0O@]VU_M?4>L8J*3VK!
+M446A;&V5M&HT%1@(HRJ((6B6K1*UK6RQDHVV):,2E:_D?DOX_X__7Y<=C^;.
+M.QGL/U1]W_/Q3])['QO9*"YR8?'''<<9V'5@&+RN.`,Z<8LA1`J(R5E10BR0
+MD6!"5`;_(_YP?^1^[$5S2\IYF7-?E.4GUGVX_]"AW"=D2/QZZ%1\ER*@CZ3O
+M6UG7QY[+NE,M-.SKW%)(YBP]F6*5=-M8=O+$M)2VC'Y?W'NCJN@L'VU+_V@J
+M4+Y)LO1_`>Z+OC\7UD>Q)/I>K_%5C%9]'0W=T>=.)%XJ`2#Q<0&2$$9`&161
+M82I`M*18!619!%96!`=,PD,D`-T1L*4^QX@N<)H;\_+>WW0;8G]&@:4Y#R+X
+M(2[_RM2EML0[SM[XP$8"!FX&6_//Q_X8I];YO,G.HFHZ4G]5\ALW(#H.9`4<
+MKX)\8G@2T>.\UK:C8$;X#A\R:3![4`9$2?6MPD1UD7T*"-<5!*-*B@JT@O:B
+M%]%44MX>'=:"N;BE`[3I?HTY7V7.?6XSA6'K"_/%PLKS]LSS8!VV%G-[SV];
+M[QO1^`;CRSF<KR>G#A0[?[L4-\(9W6XL?3Y!I>S=02`!,9Q_-L+O>['-5X1U
+M_1VSE,YU56VO"NLZ5O6[,#;]E\7>/\L(X/C1QQ*7O8=A"+KL-+^3^,#J(RV"
+M9']V?7^OWG]_U),8GXTX&=^._)'R-GS+S3^][UCS:E7]/VTNUCLSOC/:&^/"
+M,"UW7VCK'4NWSQGNT43>KL/H<+UOZU#S]E+?\6FYKW:ER/4URR*1.X(`XY(1
+M?HE9)&E(LA"L"H"P`K`K"5*0"15I!2I?![G@2IMPT1INOWW?6BPZ9I?I5P^A
+M\,VC#!,^3_I1.7AS\"\(]5TKUAF%4#3X<.P>K]-=O5NQRE-/6RWS7^<=8M'!
+MB[2FRH4M3UZ-3O>NV$Q2Q<UPG`;@ON7W#REC/('4(C)4K"L1HP6"PK`%4BQ0
+M%D%@*`L!BJ,D4$%0"I!8LB@H+(L%1BA%!2I0MD@-EEM%E2"R451DK(H6E)60
+ME15@H*"K%(C"(R*+)$&1&25B@"Q06`LK"L%BLB2L6%I0$8V6%$BDL2+&DXQ@
+M,2I3XKBN<N9].]]QUV2]/^5*\XZ[2T%_[.]?[^%_6;:SG0\WND-WE9U=N;3U
+M1F&*?,<42EQN+?+-D))C+H'$`Z8'0Z5K(I!8*06J_.3C^A,Y.?]8^D.2$AU0
+M`$2?,>CO&\DGZ$C,TBB?Q/E9J+#:.CR<DG@%488JH406100P3QKH8T5,.`D@
+M#2`E(BDE9%4(`H`5@:GQ3H?C?I?P[ZO'(`5Q6120#FJ44,G;:DZ"^P$\)`AM
+MNNY<W>#AHMC\+3/N>K^R5N_CW=?>-_M>?BL-BH4=Q_PX5!'5KGJSE1L6DT($
+MQA1JM;O/GZ`Z;^:CYE,C_3[^?\I/9[J;/G?'V>RBS\->6B,KN8\$ND:0DD-^
+M],VR&9A)B1K^1G;Q4^T=>R9[W'P#4:OCI_P?;X?11/D'$8]#5I/M#&\H60+P
+M&(#2P%#$D$#24,9A)F/DR-[)R'X]#ODAASL,%@(QZOYG6^'+"$-E"X1C]SX6
+MVAOZV"VU%6CD_Y+<<G8Z7HY-`N15(_G\WAMVCNS_,AP_-YHA^:;R+9ZBZVOJ
+MLY^JGP>PH<,*[+@3I*9WZN)\X?A7.P\_S-F8!-?XU$[+/]%[OMZOW[:^XS2&
+M/_N;0^1F)GVW3)?_9,CJ?,A%],5ZI6ZKRX;`KQ^R4V*K,(;Z,@O$EOCU#?,X
+M(O7&I3N+30.D@<WP?WU`O=7]+R*>RM96[&_-)0)/\49"=6$!810*A/^FW$`K
+F"+`&FNP%5J%=[MCO,A9%D0D'L8&%51TCE#9?_B[DBG"A(9GC:TH`
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/sample1.ref.gz.uu b/usr/src/boot/contrib/bzip2/sample1.ref.gz.uu
new file mode 100644
index 0000000000..6c36f44d14
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample1.ref.gz.uu
@@ -0,0 +1,850 @@
+begin 644 sample1.ref.gz
+M'XL("%<.FT4"`W-A;7!L93$N<F5F`)R]"9QD574_WE35L$CC;E"!"(-*MU07
+ML[#-($P&D!F$`61F)(89X^O:NIC:J&5Z2O3O%C6)F4X7-_6X5AD;C1I!Q%!Q
+MS"!1;&7QI]'@@N)N$"6_N$5'?R9&?_S.=I?WJGJ`/Q^%F>ZWW'?ON>>>Y7N^
+MYS>)(]YRXZ=./&\"_DG^^PDG[\C_\<FU=JO>;IV\=L.&LS)KSLFL6;MQ[5EK
+MSWD'7''$Q!/XYS'XY^9$\5]V[;_Y]Q]9_[Z;$^OHCX]\N[^_N^N*^J&G'?$/
+M/[ELXJF%`OW_R&QE=M_:,S]^8;[36_AYK:IR@U67?_ZJ1JVU>/]\K:4Z]<5S
+M_SRO+ZW4%[]\7SE?4?GJXEN66BI8[%_04J5:M;EQX7U/_Y<O[.\6?G_!5?@(
+MO*Y3J37J<Z7%_YW-RN.Z$P^?<ET^2[?HS=7%I4>"<J?9._?/2ZJY\)[]-T[\
+MS<LRA5HCA*NWE(-FL=9?^/F\VAHT]^A\N;RPM/I;+X*+/G;2^D-/?_XO5[]R
+MXBGPI?A_'O^:NU[>+I>":C?YX([M^?G%VS<$C=S"+9,3$W#3^Y_VLT-_\+W_
+M>.D^_Z96:^V:Y69^'JZ[[H^RS4PEJ&:";*:]9V'IV;\NP5WAOM<>>E'MH^^X
+M?^(8N`/_G\I6&AL>N#A?#QJMWB<WT%3\T_M:8?(Y.VH%=5&M4F\O?N^$UN+'
+M?Y9?/.:[#;4]6\I7L_F%]QU+P^BM>M$K2XN__'JV!5?5&HNG[2L%`[AW9[6T
+M%QY']RP>^3?-Q9,?*<&\ZUI!;PNJ636G\HN;[V_"K^RC:<+>^N,_N7(?3%D.
+M!W!U+<BE%5X/CQIS!UZS;>UZM>&JR]-JYV69A:475/;LW[^_N[7YZ*$7MR;_
+M8J/]S%4XHQN^M+G[V-Q?S"[^X67-Q:-N;#6";"NSL-#==^#8!RYLE\JY4A6^
+MHCA(Y7Z;/Q:6%=Y:VJOR.E"SB\^_@EZ-M^@235$/1M&'4=0;^19<1)\9PJV-
+M_/7M4H,&J[)!(U]HET&P[OE":P:^$(=&XZ='+,(+:M4P=?6W:?K@-9OOK[7Z
+M?[MC3K7T7!_FK];HJ*"J<[`L/1A:J:KS/*<PT555Q%M+,+=-'%^;WIE1.^9T
+M7K46_Q;_B_?#.@8Z\@4R$/X.,YOX'?#%-%04Z#!Y^X/T;#6/(RF756[QH;?G
+M]X+HUG0=?H&O@_69)0$Q+UQIH/`P$@)ZAIK305,5^B?#?BGGJVI6Y\WDS)6J
+M,(C<('']6YLUD,;Y.9Z\M(9I:/>_=T(5I*.EVKJZ^-GCZ3<X?KP\OU=D5Q=Q
+MU:J:1L1WK["$_J<K^^&:OEK&4Z<EL2L&,U&",7?"Y"U?"Q1LXXZB7V;U7+6V
+M^,,[RK5B1\$(>:ZRY:#![R_!M*ER0/+5#HIYE86=52K++VM57+7(:P.>893R
+MU.(SFW/PM35X^7S33C3]MU3=PT(+WX?7/W@!_`C$Q5Q$PZ!]`W-?K+(LE4#O
+MP5#S%2T39H=!LB)#F&ST0*)5:P9V(SX%93T=)G_P19H2?(!1B+#]51VUX5L6
+M4!NR5,.K<(5`'RYFCH7M0;."JH^%*0U[HXYBB0/!U]([(EN$-R!OR>3P3:@`
+MGG]%D-.\BBA8I'BJHAA@>5%(5$X6GB8O#V_-ZV8;E`^*`+Y,PX_@)W5%WP&R
+MQ*_0L*QZ3[6FYJLRB/A[X+OR/7G33"-?#OHB?2H7)FZ]$P2KVH1G5_"S-4D*
+M'"09=;'9,F:Z5;9=KI0B\HL["<8!8VRV=39K/\C,!^B0,'755W@T01DN;?9A
+M<+A=RV6W8^$2>,C>15&\FE8=EF)-9NT&G&.:&)Q_Q<>1=H<1J?I2F>Y+RUL#
+MWHK)C[]?9E0W.U8!5S3LK:8FL8/-UF[V8)GQ.S3I,FV7'Q6H;K#HY_$`P%<N
+MDA!HD)IB(Z@TTU8C9<MM4<.HW8,J+WJC7"+YXV_3]DAAB2VU%A\ND)B5"VFU
+M=OV:-6M4N43K15JX7*,'POFP^JX']G?3$Q.'IC[]M2MNGH"CE/[/Y^VZKZSM
+M'O?&B4NKBV&AU:@MOF8BU[MYHJWX?%]8>NZ^!-]\U&6_>$W'GKMPM#36KAG"
+MQ![\03Y,G?J6>@"GRTDME>L]N".?#4!WXT])Y347U]X/LP7KG(//7OS,0K#X
+MJ0G8>8N_N"^+V[)1TR`L)"AWW(^2"4O6VXD;N;YXZO[\XE,^U"`)@QOA$,9O
+M+P>O[2Q\@,95:/>^W:C"_COX`Q@O7E,>)&]?`*VC2.<L;CD)=DBUUNH=_`%N
+MAA\LE#NT&`KW(PQ/HV*`G[)!!`-8_'8#SO2C3FKB6BL\"G.+\$WPAW)-1K3E
+MI!Q(4=!I:KI:AD(CK`^2W_E-LPUO@_->H_+[=L,.1.>?BI9$#]_2VPD#@:5L
+MP?AKFB>O!A=EX=8].FC`[;#$!W:BI=5NT.T9?04.`R>$9@A&1#]?//%Z^$;Y
+M44>>50);B\?5:,,8JF'BWGMA4D"O]>%K\!DXDS3F8K6$\]?.P90WRS48P#R_
+M90#W\&.#JGD^O+#4H$F3M:'55&0S9&OT*II%&#G^%DVLQ>]/B)9*P[3QY*),
+MI&6`);"\OOJ*,GY];0](;FD/2M7AI6!$;O`E"BP/,"*"$FX$F'=5.S:C+ND^
+M]I);VPUY&GTX[#B8T1.O#V@8.(7P(QE,O3?ZMD'RE1\E(:CC27_P!SE8.#T)
+MW\.O\65!-_(D3D$6IT/554>NF05#L%U'T8&_TISA%,V4JC/F>IXB&0:*>)A\
+MUT?S>[N/77]_4&[3+7V2<C`=.HI6N;'XD@_1/@)C+'(AGFMI-0\?7%7XTEH/
+M9`3N.75_B?9`/H,/W]Q-ONN]67J([$=0L_GRZ%XL]4_=#W.DFS(Z^B%,!,S,
+MSITTB3Q5?%,/'H2J$#=CQTZQGI\K*93N.9TKP4":B[_>`3,D`@V_1?.E"9H'
+M]HT[5D1;D'\"NR*OY3-+.=!LD\^=V-\];^*([6V8&#Q!9#/@R9&\ZHHVO1O%
+M/#998*>92]DX:(*BHE^SV`35?G3L.!%9.2M@L"C`B@2B@M\)`L%6[XQ52N4P
+M,3PI"V/&&:<K[5:1-:23B04<9`K>RM8C/AW'`=:C>0(./2@Y(0?1[\&*XNCI
+M^W)X)8L$_!4V7-`7Z3(&EQ;U:#9<0$(,4OTCE$K9V+I<JK#&(?V&M[;[WR93
+M01?QVD8>7MNLM1NP_6`MX!&\%O`")4*EMXMCV$U.3*S#<X_%!_944X-Y)VN=
+MWQ=4S%R5<"PTR8/DJWXIZS_NNS7:>#B38-646'4'M//P-<5\5?G:B/<<"P"L
+MA@;ESNN/L@FB6.*Y)Y&$N9FS<@U;>)#ZZ?%!LR?32\L/@^_#E"NSA4#!T)2"
+M<1#"U6:;+*+:HC%JN@YLSV8==G9&7<BJ!D0-57X?YP2W`&Q1NH?T9DNCVL*_
+MPO-@(LT,X=$E4[I^D-KZ-;->]")<$GX53D.@ZW"(X!DG5BI\;5K/!G2HP%PU
+M<DT=WPO*[H78GL650K/1G)89&8\<^LD/OWWD>C6/!WZ)%P^-2Y(E_)Y1VPOM
+ML[39?O`<^"7N1D5'"#@GM)WI&ZMV)HQTAHD[U];M-^1GQAX1WG;+X'R24L19
+M/!,,=_YH&+;;5V8[\N_:95P2^H79JJP%\_OJVN[3"DX%JSW\$ADGB"^:=+3M
+M\=P.DU=_?C,_#QX#NJ76+L[!HC<4?P1H$7!9\2YZ,+RFBLIV1&TMRDX1Q263
+MK_%2&"/Y&7`%^AGFM)./-'N-AX0''PC2^7-D$^'!/>]TE`[020`1XO-`D:R3
+MEL#3#?T%W.VX.6A_9ELSI>B!SVZEZ&R0O6:/=U'.B1>+'`K7PL+"7V$\+#'Q
+MQ/YYR4KQL*LG)H;C;,'$PS5K"_;(%F2%K5GFVN6<CHX_S[/.B@LO,7I6V_4!
+M8>-]FM.S,(5.@[*E6V'M`^8=>,+%_,+[,'B%`RRB=;ASYRP*:XNMK+RUJ\Q_
+M:XT..W1UG%S%`DY[.SKM^G#3GEFX97*^M[\;3!QQ-:UW&9S8Z2^UFP$(".MJ
+M-7)`@SES+._B`HA<HU9!_Y:6O:4[M,.4M97%0-#6V*`CDAZUEW<'6!*@##K-
+M#'HY5Z/6P"D;)*XXP[X83H42J%;\!2AS-H0;;55%32_V&2]CSPQ:P]=5T+?"
+M"8(_@);KH'F7UA0($2.BSB>5V]UX%.:,TI?QD*Q$WK)HWC)(K:N5JO6VHNU_
+MG@;CR$G+KLG6:G3AX&JK=6"I>35435O3"$XY-G/(&N<#R;,A-$UR`!\Q(R/"
+MHP",X^]/[$D/DOL>VDNGYDPPLQ<GR9[M/3G;Y5F!DN-!P@"1L>9@P^IB#:T%
+M^-5UM5G2Y["(8(3C+F&#35[O^2IAHCY3H*D1#2H.2%JA.<^68AN$NPPV!ZKK
+MRDRM,(-S@KL<?'G1IR(U?;Y31PXF^+0*VEFP%<'1*8IE;J8"HR^BC\+$R^XM
+MT)F0%=.IF5'7X*+GY=QHL#.ET*I`(\HJ<K(B8-JN;V/TED3<65U&-:KQ-A8(
+M<PVD7,;#=@?.6(F/0=A8+-!A*O];.G'@C@+Y;^WX@0%VC_$[4%&#,BK79H.R
+MLN>#1D,!WD\_J!W;M.8"'9XU9US0<I@AD7B@#=WF\P!E($P5_W.^[RP*G!B:
+MDF!TY2C:RS$Z\A!B9@,'MQ;.O4X.3C5RV,M`,-:?>N_-_ND3.=1Y(D=/5:-D
+M2BV)WHZ\X#1027V9(S&GP$6592!G3X8PBQ).DS1(?/_'8_4Y;A+>@[1-]K*9
+MA$H`9*;6AG-A%O8[!@K@`(2+X>OE<+:^F@;ETL,GIG43_;P"?I0(EAR/,'UF
+M3/;\:.!A/TAN/J[5L%L*7F###6C:HF-C`K@]N(_NH5U,=N$-H/=(VO1DHX>^
+M1TO3DL&OX&#(XJ%,.PKUTJS5EO9<DA$%BTN/T?/Z9F2G-4,XCZZ:NQ@C[\:X
+M8*V,=M*U^[?GYS><N=`]X=Q'=X.[=?+._TT/NFMS(]N[?0/&)VY=S?&)H-Q-
+M??N"*]&9F[RXL;>4G^\>.?/9X0XV_0>I#;]RUG^NM+?D9)^]QY[Q'O'L7F3_
+M47EG!,;@8!5Q&2I-<_1AZ$4FFT[3VB"Q];UT2M=A3$%9F^##1HRCCS\_>_#$
+MOCD_\[J1#N$9\[P%0)SG%'@6VGD68H`V8>6S;0YDP`!Q#X&6<8>A46/H(YE0
+MRFO>2;%]4,JB+TSD-M"3^V@YHX*;UC(,\(<:<-*1IXPS%GDUF%BRD:PA849"
+M/G/:S%!?CB7:$S#[X/F%B:^?16/9(WXOYE_@DHJRCI.B68[[OAFUN0G7P!2#
+M`T-[F[(_5O&Z3Y3[R>0QDU((DXFS)ZNE5A_/Y3EQ_^`,4"W\#=\!YU"#)0*\
+M8A@8O1LM*PD(."\Z,GF:OT144"$:]A&C/QHWD0LJ=MO"VW%7S/;1X,F5/']I
+MEG8/:A)8"K3DRBP32X\9.\U7!32QL!R1\1E#0*)/L(`T-'.F;,_OQ6W8(_MI
+MD'S@A6B2H9:A;R-MCP$4A<'*GIC0^`(ECW=:SL0N:>;))@)]%@T;9/0.-E0H
+M0M:HR0#M*ANU42[6.$2$,U4)$[.G9<OYO7V1)3IXR2JLE5BQ5VI5-ANK-"E@
+MD72,&&"^434[8CMF;=`)'D)'?`F.:OC<N'NF@QF[/&P"I`>)6R9(58(<:EZ>
+MO:6@3.K&3+(SQ>3\YF@J[AE0FW9=>J*%,_I2/(9K8*_DX*ZV`KL[A^_!(,E%
+MY2"K]O"&O4KE._R!,JJ7UVP0@_7F51>=>\Y"][E'G;P;!OKNMYF=&9M*DTS@
+M%:K`SR3ZQ9.AV&MR(3+S&)AQ%!]:)'[?MJ"Q8=U"]\3G_$EZO]Y*=V]8N]!]
+MP?&UW48!2,PG]=1/<AJ(C@\Z?-#\XI--B]VE&E&IM6*5T9N[J:<NT,ID$6*`
+M(0M%[DF^BCJ@(P>11(U)(<(O*6#/XQC_8+!XS_X;M-Y)/=DOA8M[WMZF1]>J
+M<+)1=(I,";'MG6[3,"#<'/PEN33&:CE61X$!G`64?'LL8JB!#77XJ##UWVMY
+MB8JHO237$-4Q?3-H"C=3PD/-\J=B;@\]B#0^A]4%Z*YY6$->,9#S4=F.GQKP
+MU##U3_?FT.[.R\XQFO4B,%5JM&R\\!===,ZY(&C7?VXW:SR^&N21#5S^X;9.
+MME$KM/B.EV\[]VRXXXKS=V?4R_;1_%7E)&GZ.G"0_,\/HF08?33S>+)!1@P;
+M?6J^2O%N4BRT*D48=I5WSU:,?7A[Y9*M&];C7CEEMYR'<*<,Y.I:7[05^>Q@
+MK`5JKLRW75W33;SQ^==]>'<F3'SQ;1R6@O.(?2B.B&"FF"?A\KS:II_5_9\M
+M)^9ASCMR)(`,[Z(5-LX*CFLUOV'K-K1]GG_K1W;+<$A*\&P(RLV:PF2H9Q+D
+MC`Z_M!JFSOWZ6/N?37-X_1XRR?F:1D[!!:"?@ZR>VZBL9#O!P$_!'Y-HL<1'
+M+080!V,)PSQUPM29_Z=-:RIBJNBHI1,4ACTO`7^PC-FJ@M//B)F)NRLOJ-_W
+MS#)2U7C:2Q@>#59E39:*G/<R&%#T?980&\G`^[O)<U_'!B#>+#\.X8=5"=Z5
+M,6U>`2OC(G'@Q%<BIQZ.0#Z,Z7QNXGV!<ED\]WUF4)2#%P/1'".>5ADDO]EV
+MY[CY3HQP2_H``T3Z52C)\+D4#.V1FR,;L$::]H3[K?BZ>`X>-VJ.#C4,5#=U
+M7O:;=?URVI^OFCVPV&+\\>?'&QBEZHAUGK:1=WU61E_MS\',+#N3J!)]6P%_
+MUY.C'GR(*AS::?S48IZ#6V"!F+.C2<[27I/P<0>&IQ2,U=F3`UJS^J,X_3S&
+MQN`X`#^%0V22K62%3L9_AUROBG(K(<O'YR+G4\T6NP+/:(II\X'!TW%%36=1
+M(YQP[K_O'J2^]#&CBSA/P%K!^H`F!"6N)@;)FXKG".9P%P>#?'>!5#U9!33-
+MJ\W<S)/:(;^PFWKSN;P]&Y49M\]*U3Z\,X1?TO>*<4V^?0M/AGU@S[.T>%D$
+M`0DHV<>ZB&XTJ0\\8[R!\4XU@NW2<$:2FYEPU8FY"SND08)&'PU?&`6F!S$`
+M[?8NC5AS7H-&K,8.-V)*C:@A-+Q154><8',RAZF9O:P2`P4F))V(UL*F<T22
+M1W#=+#CZB@*D`_B;-:">1`R4=^,XZ]N<LUFVY4MD]&*<WD9V&-6@CXW8!LHZ
+M'[K=R!N$F;\4H\.)!$AI.MW\B4=#)W4N'7DZJ4F,:V*JU\3(DT\L1/ZLC2O%
+MR-,3$T.7N4U]LC\VS2K^"YFE#!GJL:U(EE9&7TFV+OG6RHLGD0:F"Y7X;0AX
+M#'!>S,<NBNR!-<\Q<4SIL",7IO[D'IX?8^DXU:=+?:/ZY)@"QUBS=VY"UI*#
+M\4]QLLX8DZ$M;".C+G7P$MI:<FX8SU!E`\$FO(=3I64XFJY>JM:J,]$H)!]4
+M^,*^>6$6@ZZ(ZY/78HA88_C3V&6!/8?JVAX_5R^-:/DTQJK1N;%QGS&G/2([
+M1CPE:YO"H.M5V:VL%,`&HG_-L_.Y1\WQ'W(*S]V^/7?5U#5;K[ADNIN\NA9)
+M<8O[3%.995PGII3($2R#S?&>/F4`#I-HCX3],W@'&8AP/`>1M1A-QT?N3..=
+M&':H8-RX)0H*GK'>#,J;K<&J4QYAGSDH5=/L",!)8US$*@?R6(2R@A;*[T.A
+M-0"=?.0*<\B#;JJ!I6DC?K0:T0=EPN3=A[;;C^*X7$1=@%88P#7ETAZ7_S'+
+M2>9T@P.`&(Z&.=9.%>-!/2:_8%*U,J)8V"9NL:3W=Q.W_?:JEY/]_>Y[T8R^
+M[;=B1GOKX;QX#[,04WVLX3CFH<U6M7'V/JV/S5?2S\P0.9Z!@DC),9I=,*U+
+M!E-`P5;/@$`S801882:OHDW(1TE<96GR]`\11F1S-WG;K;A:@^1MRPR)L3@G
+M1`C$LU(H7'"%:'!CD53J+=&/%*[U``EF64;4*7X(O(T64CXZFJAL#A++FVQF
+M%AWJH@4H\`23^6-@8"A\3LL9Q`Q8664K#@RX:C7R(M`U@M=8;\7$$\3&,+NF
+M8D(Z*"MA\IQ79PE.19J+AC<),I=1EWN*V=JDH_+`6Q>1G7HNJI>+#5Q0],NR
+M6;0?P:O#=#U\,L8H32C:$V&2@WTE5&Z@9X*Z$4,_.QMY11J,)>5%_O**S0Y0
+MB$%CM@0CQ'0[+D)+U8[%1_I&`BCP#DPXAC>Z\"L;A?5/A,LOYI7ONUR$*A5!
+MD;I3IN:''M$KS373XP85^``M;;$E'7P)09?08,8`J8DY\`>@>BQWC$"!T`:-
+M0?)=O]J%80O>&*NUA9JA"V9D2?F`0@*XYM!A)[EG[`J*/QT_)N6$QY`)<)%N
+M&N^79`,QNG*P/?)&V&VD$+[HQ?=32MQ?G[AV[\)%LRJ?Q:01!PE>?']^'P+O
+MX+OV:@2NO?A^<XBSR4!6//PZG\:+X;\NG<`B.H`?1_,)7*M"RQDF_^85:,ST
+MQ6"6]!@+`\DRR':?5#BF5W0Y7TES0#L;])<>D]/'6>YEF;*^<R515[W6"\B8
+MP"6^.J@XT"0H6!E5_E@PI,+D2RZ3T#H9$5D$,E#F>9Y0*!QU%,N6`?HON4PT
+MAXIO'%+>WAX18"0<OI@WY4O3JF0&$%1AGA?9@ZRPXH>'D*VCEJ<NK;;2X:I-
+MO\?_@JRWIO'B(:8W*S43>BN7$9H&/Y^EUP=J@_)W63FN1M)J:EUXQ+>N.73<
+M*:O3?;_"I]E9N^9@0@W7*?KW]/ZE(][PV*')*T]Y^*T31\$E1S$@N=DYYY\V
+M+72/_-010VN]Y7+&^[KP'Z]K"\J6_5L\"]0R#%X-T:]A:`['9]IR9+L4*0A$
+MKM8&_31KK463+1G]$K/@:06'A#64:/L.4M<6X#,3C_:\#_(_RWR!#<YG:T:O
+M4K"V5A@?KWV<-)H%8:)5$90K]J$RNG*^Z&)L@JD8).?W4%*4DQ)5EWSTTO-1
+MS%C/J`'>'[7*(@,A:$[@C;C[Z&%@S+A-C3_(Z"UY:U2ZH.(@\=9G14`:8A7H
+M<8@O30DVAHCT.%/&>:FFWC7?,^`*QCF*Q;0:<ZN+E'&%`TB"`P@JE)&PEN^1
+MED?SQ*7DGI0K"L8BXC%JGFDR;_U*7>=G[@&Y`X/EE#_Z!+WZ*^L0F$\AL&/>
+MR>B$L-!:_.KGFV'JC1-P.NTM!8LW3\PN?N.=N-,6[P/K\S43S<4U$W`0-1>6
+MGOO-:^@Y=ZW+K.T>^X;?;6?XR,<*E+7%^KJ+#()D\?8-!/9_MMPRO*A-YTNM
+MW43+?ND0F,SMXESZ<`A32<A%G;C94K%(^`_:>"XDB38^`TFI",8#3-ICWX$R
+M^B8_TTU>>0N8<5?^?98T'Z;+2QA#',#/"0C*$"+,/H/.IKA1F>$Q,Q7"IJ@V
+M2@Y;/9)-(!1I#H0D:P.Y1GDT:@PK(+\W/4C\]K=U)<=TS^"H.SK;R;*%K.&I
+M];FT-=V"1A8E\+@\VWDL6]9)UH1LL'AR\!DX!D'O,>&.Y6WP^3*:(7\")@7*
+M^3"YY8<L76:F=[%56E^=-HD`_KF%6RY?!59U.Y=7P^B-9)RR?0L/J.S?O_2[
+M5S]VZ,AOJ)NOMLH5ZR7/N6/MPD(W];KF,"-E,Y'X=&",2-;_-,I!\A\SR]NZ
+MR7_\@V&6P`=\5#KC(A\!1!G\/#FEQN30+"<<']M'R21Y),.=(KNN`$N*P/M)
+MUM#:'J<\*IX[-#'>\4"I@J"4G$-WX.GYC@=(;Y71/EW>-I2IS*.ZR-8,&E7*
+MR5@LHR]6\F(*.<,#T`[4\8MD2'`I;HPP\;FCT7AL&WPPGY8.PF3G1[7ZDHHG
+MR=:<7;7CMP`;;4&K?";TXV<"?D`$]Q=D&R+78Z:KFSSI@5E07^BQ8`B!%(/Q
+M;T]ZP`NG&!<`C3'>V5%OB%%$8$L9;PCAA%HB2U3M:?))&)#3S32^VM.89N8X
+M#9-X^"=!&1,J00=MZ&90@!'0(4.(M#J_3O0UN"!H/''.@`9$2TD%B%J@2$$%
+MY<T$B@?P_#C07L`J>TU`,S!^-ITH/3&6I91ZZ=FWW[8?ZW+7_5'BKAL68.^<
+M#YO8A!9;)XZ57"M`J&XQL]*WZ`D5@>=3*#90D:/103NM_>'[(.[`,2N&HS\_
+M$B4($[L*-#T=Q8$>!N@%JEQKL0%9$BP7[E&#&A$$Q7B+<@3X+6]%^/=IL(RW
+MG^$T4VQ.^CPGN$(<CT?!H9*$M6O6[,$*-UTT`6<W)EU4)3EKBM729%:$GR""
+MS3)9S\W1+^="%HY#8V2S7>>224Y(E76%8`%T@#0S"[CH2\<<^8V_`->K,''N
+MH_^Z])3+OX"+G9@X8NEW,^<?FKYS<_#!B2/1?A7]>?9747\>L^EW#UQ*A>9<
+M98PGV2<WR$EF:M!;?:R+#KB^65>H=A'&@+8UEAJ2#L-Z<P%R<NDGU0@>6ON]
+M]UTQX1>`MUH;OBWS^T#&1))33Q!L_>H5(LGXI7]LQ#H+8GUI9*.;D*[^.N;J
+MU7&$[(<)A5-9G&!4]/PW16?<T,G.]6T;B^6@DA=TPI=(Z!C>NHL"`/"R^3#Q
+MBK/9\)"<.D6K_KB;N.I7Q9HD,W##\$9R4;1-<%IR3I8RNE2`P_4*(WJ+/P(<
+MV_DJCQQ%"`8AX*LNB(]\"?QB9'YVT,>%R7L>%I&#+>6?YWS:H-@:[*YJMI^:
+M-=$7D6T[#V-U1]\</)6:E@-8-V64<-J)_QXY\0;)KSTJ)YZ:UWA@:4;6:@:Z
+M8V`+T1;S)J0O10!JKZJ5<CJB!J@TP!@N8P=HHGXX'O`N/_$FYW)Y\ZJR9=*X
+MDF*!06V4XQ1GUT106--RP!TT4A_&457HVD24$CW;B`2?'_!R6OX6YO'IB%IA
+MI)F%6TY<^!_&.VYK+W[]A%;O]@UM]+('J7]_D#%X1\\T%Z<>H4`@Z(=7W"_Z
+MH7OD2\\;OLQ%9YTWD[KX1_%R4^75M[D@H$T`5!3#7&`]\=V2NHJB#W%INZGL
+M?;Z."N'O6)8DP$CX&Q4I8OH&UT=`.KB:(I$ZKN7D"0&&'-IUED239BSF[?Q2
+M]C1,/?TS-J>'T&D"UQ**@0H1@Z8R<0F32;?GP6E-M2L;,R@9#$:&S&I!!_M'
+M612/\<YZ!*3(P61.#U4$DE[.^V7%_$'6EW'[@5-N-ARC2V5U^&-:ZIPT!NW,
+MZ9KV,>.(A+,IF=3[+P_4Y#X.YM@,$+,@H/+B`"S.H/&@R,\"FZFERH(8Y`!&
+MGP,8]N/F2W`\P.58$#L&<FG..:R<2FVZPBS%:^F;:BI6P&D"5VI/%;8EWU;,
+M^WK87PN4PG0\>!NQ6SDK8$3'[(0_NX'K'3BD,"-I-QTQX01+(&'*=AU_10JR
+M%2LMI(BE9#9I/=-\>L<K4Q?'5J;:D9%3R5@'/C50K<<SR!K!:CMWCH6H48B&
+M3YD2%74R4(VS[`0N8.O*9E?A(6!<(]X<K6$:%V6AKR:_?1WZ[>AL+7[OY8C\
+M`;\]!+\==7RI"I=__/68LT/EA,D$<N(5>:'-30M+SQ3M-;RD-!:O-5BU=C>"
+MM/A1^&9M,IP4L^`'L3]XQSJT73[\P'!JVR5J2W-:$Y*S:?6]]PS6KN)Z$9JM
+M2"A[6R@W8QP5A/M^[:_J08GK:0\]Y=B;9R_PXWZ5TMHU![:H(9[+#M"'-[&(
+M1TN>'8!"Q_!1HF(#L6FS8!0J'!8*F10RR6`/[./8XO-;K]_U.3^VV"J=<R]\
+M8VNA>]R=QP\S82)[AB3*\*<:Z2EHOB3^<;`PG))GN=L.G-<]XM8/'KQ@.'VP
+M*-.ZWKK4FV&/L^("7\6!E[QB;C-M?5M`@8E3V/?X*9HB;7$T&!ZSZDQW%,*A
+M83+E/-H#6_A[CUF3OZGA?V^E=,Y'J[#DJ>$0O=-&?F9TLAFV4"SME2-7'O;1
+MZAVGKUWH/JW[)OBL:Z@"'8.0F(2W585>Y,"(29CX[\T%M.YM7HQ,MB;'$.,?
+MJ0[L`W=!3#XP`W2TYH.'YMD`[C`VF:G(!."W'GW=W?)$5@R(3H'%8'B&5^N2
+M;'X+CKI:@XO,ZAQ.SAE]T?P6QAO1"\_@E9<6N-K79%*\<6,6.IZ^3]N@LE\N
+M8X)JA!NLXF%Z\`(UI'I3#V;#CN4_;\`-I4#ZK+3)[:6J+:QQ;J2KI!B[?'3R
+MUBD0AB%<#!(,X!7(<8`ZCD4!=9X],U&]E/6!+7K(9Q47D)JSD2)<$>`4+1?Q
+M(B#YTLZ=![:,V3GP#9Q2*.UUAXY7K\O<4_@]1DCS5**`3"J>*SJ2-MZX<,OI
+M%_\>]N*C=X+)?N/$7YZZ[]#S?C]QVL8(OQAHH7L*"_C[_B>_--RX<6$!J<BN
+MONO:N]:!G?]_W_NG$K??WTW^V=U+R4/K-L&N/NX=#QT\I9NX_[F'N^@I]WQJ
+MN'MA86GR5>'2<Y_W01G"/85NZH>W[5N0%YX/K]Z_].,W_(K?>FCBMW>TG^D/
+M,+]O[9H/G;NP=,S$D7S)2T'Y3TSRGW&T2X=^E,-G?^1=_W!P$W[($>=\KGE/
+MJ;!PXQ$7?GG3@7TA#'-XOH+?D>]"%]Y3+A5:X<0O'QI.T1_5<.JN-</IZ84;
+M)QZ^\[,'V]WD#_Y\.+6??K?0G?SUAX93!S<-I\/$N=\_B!<?*'23W_Q[_-'T
+MBF_<K^3VI_WS9_AV&L"-$P\=_#Y<`V\XV%:/_Y)]_CMJK;E\8[[4S"^8?_@T
+M'6YAI`H(V?X?107LZ=_="V/I)E_TI_*BIY_P%'X15[<8NTHVR!UK%KI'O>?+
+MP_/Q#E3T(^/S%3ULHI?%F#E8_\#@]W=3Y_Y,;GY&YIU\\S1J5.W;);XJV-]-
+M+/_'BFO3/?,3.:ZI#.&R`!W:><7ZX."F`^<-9%24?C5?`WO]J(O>`5\#2X)?
+M@Q=JO`K^,_;;]$JOIZ^5,5\:/<$<+&G5F=\.BE@L:;_2CF0=;(C93\)(5OWH
+M,C.2$(=,KU5C!Z,.,QA\%VE)^X;UWAN\M^()C'-BC(#Q*@AE-B:RD0&MF9ZF
+MKQ<(^,4G.)J'B!9R&MZI+;#XY[7'H%";118;@082W4M^K!#!!EAUS:TFHH^%
+M!@9*3'&R,'G?\4P5Q?9"N^&?HQC`-BE9#AKC>4V;Q,5THV;2:*Y3@&]2RF")
+M,#"(T<2Y;WI57[L_/((6=4<T5XMR@ADC?N8W_&T42`HP_EB%R<"230'7,M.?
+MV)AZC(4)+S46IHWO^*!KLL31SH^4E#"@GU=SVR5PJ&UI#I)S%P3(RH3X&4U5
+M`ZO'%W<).,!F/!PUDRT*DY(I`ZVRE!Z4%*+`JZ*D4-X?I>4,`"?N&5B@3K%0
+MB7_6$$/\N5OK\!\5F^:,NJ+FP1%,7:Y=XVA5DI@+L7`SF0@F`;R`0UHZ:NE#
+M*\4_O[I.8IV;,9Y90+)$!$X2.]QI36LJ8P2T6N-,/)/WH:6(N98?WE$NF\)C
+ML\#?.\&0R<TPTR0O\'-VT`(C;1]:Q*569F'IV(F$/YKU/)I#Z5ON6/R<'QUM
+M=C9\_0)\Q`.E@JKT/GM\L*]445B-\)P=L+3]S??7A#3QX0*#?)I4F?O)#6"J
+M?7V3>J!@?3'D?4.W0WMWV(#KJB<6</VC#QX.NALIBK_U[%A1_$8IH^]360M?
+MJALK52Z!IL#0F4F0,S:<$)<4+(U5FQ3`OL[ZH%UVS`>)M[QY%(+J!;3\$E;A
+M`$)`-1O8&%>T_CI5B(W?37PC?0^%.$M%PF]H../>\F;!U;+C7N(M"P.\(K_7
+ME%&,,J4-$F^_%QU?5XWAUPO"+B1\*!<)CFS(#MU-NY'AZ1HWHBEJ9_@3)<MX
+M,S*%A,DHQ^JAPN2)QP@%`A9%Z;%%4=;\$))$1W$%&M$5)T=L[)S:=HG>8M'2
+MIB+*A<!D/'Y]UR"YXT8')S$H:"HNEU"&A3A5B`JED3>)N\-!S/3411=O;TX+
+M;/9JFTR#OTDYE\,R]VU-8DC9&$2@ELH!%NYJCSG`U'_AHVP%&#[EO(DCF.R-
+M-T;/IP1,G!U!3<;1&QP*S=4(00.>D@-@UK`HI4HT+S&U&BER')7?*/`G3-4_
+MC2E(/@$XYP#>"4*OX:3T<.Q92G.,W\RC$.KZIUFF-$N45WT!;T:A<N1:.W<R
+M9'6R:)8&0V1&YBFRB4/1RX5:.=<8SBSC(@<M/73&"_A+S^C^(TSTW;_AJQ`#
+MMG&CF@K4S`5JEOXU;?]X;;";_KSPGO?0+?8.T.?JVMWJ?`8-Q'\SM6_CON8T
+M_+:@]JDI^I7"G\,/S9-X9/+R:^$]N^5]"_'?PU/H`5.GGSX-[Q0>I*'G>X;)
+MI:N6Z=?#*';%(B>XJ!A%90:C&$C2D.O"735=]SC',%/;R.#/=S8I2H@/#M2%
+M6S?/T+V8UB_3VG*:(]"S1D*L&`Z2'S@PBB/R$\LL^_#0<\]:Z)[\G&MW:V=&
+M-CDJ9TN<M/!P*<)&(7""YD(/2XYT*%>SZ%^NV!^DSO_JM7>=&:9>WCMXBKKK
+M3$7_'NY6[F]GR\\P+,N)A"+G('AG5;4Q&DWJ900M2G1&HR"TL]>L2:]9LR9,
+M/;16]I&%_@@I-Y??V]G`*RT8F',]#$1JX)G%6D#;H*@$4#B_[DQ<[UB5<:"M
+MVML"VY/MV(;RBRF=Q<JI/\D4N+!$S)P:*7(E5D:.4F%$WR9&4$]R]6>/\B8P
+M:AF/`!?#Y+M.'<4]&XX+1:<BQ4G[$B?%RPF\K2,%1Q%R39<=B\5,,??&^PCQ
+MD0[53]7,-3-5C)W+Y\/$;<>8JO`^\2'2]&L[M<I3Y]E2(TL"(ND34R]A<\!D
+M$#H`:W0MB5'/KS`P4#U0H7U1H7A^B.?%V$60`$N^0J=6PYP86UAV0?!7/\=@
+MZ:NNZ!YKTLO"Z#4>=!CDV#43XZ<(AV:I93-L7#-@L@%($`7WFCU7S+?"U,3?
+MNM*=!@)-$4=C(3(!^CL1*/DXO@M%=;$8K*P@1)]R;'F_'JW8B*"U0-:ZJ8GK
+M9QW-D$$E[:-3.)8JZ"8SIR.!!!X?3?Q+"PM3#!B689<#^#'3;R'^3K@+"CVF
+M)@DB#',%%0/;<(*'J_<#B_,QN<ODGW\S:,Z`"]SB,".AH:4D%558"!>P]8.9
+M(\1GJ$M*XJD0[(/2>B$]1CGJ4:9-,J@KSH(CF"`:]`F8@BA?QUUDB(C<$*E2
+M/O'=5U@+5"/[A6-1&D.#BKJO"N8G5J;G,AJW/:(05R`M`_N#CN8&(7?K;900
+MB]+RWY0)D^=]Y$+?[;09.]KPZ/QZI6B296=#G-'DCAFD9XU><BT)G*C!A#CO
+M(S'N.DY@V;*KP%AOM]P=>;<QD848BG#4,U9Q$:YH3EBK/,LYC<\IF>@W&N6V
+M:#3FPG:4@)9LTA-&PY.`GQPF?Y^F3':,@PP=$TQ"!IT!2`A(#1C*UL>=\<Z%
+M+CQ@VR4PPBTS1&N&`,S?I\<3S\2XM*P5B#9$99!XQ9V8JR2:*6)K8BS`1GT9
+MUA;C9):"/7QD7+;U<N+P>/OJW4P4,D)4;7**XU@_M4??Q>D4"^R/L6RAKC1G
+M$'_D>!7C)=!'R3R]?*]1K)N[B9L^BYH\3-ST7Z4*Q9SZ$0"*<A-@3T%#MZ%'
+M7%86`[?RMBR)`!/V`8Q=9)"4<0<W=Y.Y[=D&,W(.DKEKHDPZ$3A$?I]!Z(XM
+MF1*AM?GG,47)HUE4P\8CPQ'&ES!YP_:@"`=3,9)20\QB66I1:58-@"G*,#M9
+M):@;@P`8[I-1EQ;2]B:O9#R.G2#EL2@T-^5\>I!:_`_S-3XB%YE4\#(S-]0I
+MP"=G\:2$SQ>FN/)_7J#B,Q,%J-:L5S0&,9;\\M&\RH&VU,*&445934!\<HQ$
+MI(``R$J<W1J?Q!+"_A:G$!DDFF<O%3>%?3])HV?E>1HVPF2$;J"M4G1@IY&:
+M/_?!]Y2:>ABH$:9DWU_%I.(O3_%CQ,+,*HEZ^F6D"EL?V!(F_^4Z3-JX3/,=
+M:Q?"U.N:'.<O=%/?^V_[<R7A?'/EN@4%?_>O68?7'"SB0(;,22PJE6&C<RYF
+M"O,"<D"PNY1^#>9@5OUZ<I\-L&,P?=I7%A)*<&:O.N"N/F;W?Q[<VTW]V^O=
+M-W2/>?97)&Q_F.O6F<3Y]A*ZS#B*#_U</+C8LAF)`UMKRY8"*4H^Z9L1,-F!
+M0KBJ\K![Y=%?NP]?^2?;#X`C:@=W]&<^3H,;P+/<+\9?;E(+EG*VIL??@IDL
+M[QU'O?+=!]O=Q#=/'WG4M-%H5S6(6\[RZ.4&R3-^C56R:"7$R"Y`%02.;=3\
+M4CNV)6OLNBKX4E2>.0:'V\<P=RCR^@QGH#U;:',8_L1]T0VF;7*6E((D[R*"
+M8P.F1SZQ@.DKG[=2P#28.&)X4=FP+K$%F/C=3TTR7DI3&%<OF*78'L/+#VP9
+MINWOV?;QN4FLW<*F&Z$+HCJE22_U(8L(0U^,PM`=0["@2</45W<@+>:%PB!E
+M#:EY]OVX&+'=8%O#F&U@1W'8S\0Q4/_!\0RV*Z)HL!.'H)D10C"V*T#:`L:,
+M`Q"4J@:Q]3_/M_X/G&=U9@S'HPV4(590PY$8CY`)?Z4Y+$U:2.6:3%R)L==(
+M/P13E4J?8#A-I"+67D1U$ZGU5U(BD>4U0F,(IDD-PY)CY)#"TAF\^1K6O+87
+M!1F8.#<>!XNN12EA#VR1(0VIJJ(3)D_HQ3'%>!TX/'M&P@5,\J2]P:`WMM%7
+ME>X(,$X@^B#LD&#R(9*3L=271-:U<Z<<7ZHXL@IT1G1ZUWZ#\M*T[3J*$YH'
+MU\%'A:L6UAR\SE>W1UWT#M!,\/L#G<5KOV'RN@$:=:D+?N@[^NDPM>D4Y/XA
+M#C\J$F&8<:&#8^G";P4-JNA[\7*13ZIML.86S3^E^6C3S;9URUN*AF6X\8&O
+MS$/_\RV6;S+"PFD99JD-!A82X/;#^H4;%!8I[-5>HE/*T:3,R-6-^/FW(L$Q
+MPV3N""_B!"\TQ6^,E[%]-W#3,:^2Y'<IFAL@PEU+B:4S:DPR`N?4Z/1T+&)O
+M^7VJI@)ED-KXWV.HL4@DP2_`BA#%,A3"E4'33SJCM;@2G</C,-D4\Y@)QD)N
+M@W5%&#MF8.O2]^P,4Q1B"J5PK4M^,50_BJ05:P,G:Y8P1T'6(QTSA3I1NQW?
+M0\!]9A#G<#).$K$\=/<UVSUPJ!`[J['\DU#B>Z3?@6YF\!+P#+IS6<Q8E((R
+M!4RQ;`1#A:,\AI.CF:*H"4P-&*PLRF"BO%B#Y&T/F"0P<WFUM`G2*J*>*HGF
+M5//5C?C;:DUC*R=X*Y?\QGB')37A5Y9&"&`-(..B./8I3'SA)B^6*6:1GO?U
+M5B.?C_A3>(]U/NBR$1I</U375,L%V,K+10:KJ>4Y-8R2L$=@=#V"T;'%NW-G
+MA,56+Q=.!3MJN7BJYKJ_Y;E3AQL7;GG6^RJ@EN[^S7*EEL.RR%6;?G_)5&$:
+M-F`>U.4-W8LW?:.@SE>93$85\-_=%][]X]>3*KO[-^Z6+5-%>PO6I*$VNN2\
+M[M/N_DU1;BZZ1ZC1^[=.S8W<OX7NGY/[Y[RGO-X@DB[V=XP`BFDQ:`HEP"40
+MD/$:KKGB[A*<^M1R9JX$YK@4&RHQV71S(U%=P<1=`A=LQ*$63N5\"7WHJ?@?
+M^<XMYHJB=T7QU-$+MYH+Y[P+YT[UKC=??LT<AUR3AV[U"G.7MW:3A]XT9%O3
+M@ZSC+C"P:<S.XKTN$1HT.M9S-_E<E]4:<<5](.<5OP*!(I0CJ7(,:MH*?XNY
+M--C\15$@U6:DSF1\?0!-JQJ:X+-EW&X7'43>'#46`ALIG4W<^5N8C\2=7QGF
+M:J3..6@DE<K$382:H.<*9Y<O&6Z,\_?1U!DB&\:<@P3QY/4BDP>R&^2P!L3!
+M],?7Q82)A_:;8^GQ:G>V(K"Y2IV)7'C:J\FTA[\86(>394,?6R9],4@^^"Z?
+M;TF9_A&%MK*I7VH9%-&,D?H6>$2S?6P,3\KD1V0EN.A41FV#8?'+;`U.J5I&
+MVYC8)9*;=L?9GPB]7(N4R<3V+B\L78O''LQ.N4ZE,AZUR3A&)778ZJJX]4ZZ
+M5/R[#C_90RF5O8!.17N)P3G.:%$?.B4]-DCS8H@_"[Z</)%[G#PQ=;*"/BGG
+M6R#4>)5_>?>,33\$.1NC;%;0-H=[#+79??]C#_`U>'W17!9Y>/<I;_AM]*5S
+M$<5EX^M]X@K^S.?\["-W^`,;X:E9`2M@ARCN?A$/:]JB()$"S3(@#60,W*K%
+M[:'*96)+LA8%U:F4&K6JB00S,X5QYQ^W54C$MD&X2Z.265@Z"<]2KCM9CW4G
+M5RW>OJ&&A2<25>[__/U9J3[99C,/.KO)S,U55#D;V$Y;N,?#Q/_WRGASB3ZU
+M_J"BWJJR?`A]TXTDTG_.JSDR3'LJT@J`>AC:TGP.6AH5/ZXS)'*V>YTA,]JD
+M_S"([H^^)V2U.CY\E;6GBFF\,L^M#\NYC29\<=03"U_L>?EA"FPC=>-7TTE8
+M"U.?_H[G44;A(/A+A([8,I(8.:)MRR5A_4A&T);8>O8;6=VV\Q\'*<XGB];1
+M_^*CPN3W;K+>7"#E$+I(D,0QE*;&6F:D'YJ=-D?!R^FGM:126\9./6OD'#(<
+M_=CL-MH,"[L?W?N-T4G<[*<^PM2+/^K9OWZ&&3M("/>#9-+&-DB!;^1IX#8A
+MU'(L7J-C&5,I22$?([6=*(VQ):)&0K8,W3`[F;@'&^*&B\!CGR8J(##UE_[@
+M%>_@A$<U3+SS1[5":^;Z=LUE%CCY&4E8X[Z+%O=A,%M2S8Z7.L+KPG;YV#F)
+MF/^65XYB)8D?7,R.:91^`NMW"037$78!)G!S1@*_&6'19ML7VN4(CR<"W#AI
+MAR\QT#7[ZRK292#<H/O8ZZZ?-2$LQ[45E2TFY?C^?A>H&T.UA1>4JLI%$W$G
+M@#8'V\Y/9XK$9]05IBN6C,E#(QJ*/'J7R1::^'^M#7Y:JY"K]7U+P3"+<BZ4
+M=QZU'@)?#$P5:2X!1I@KNB-A1!SYMH"Q@(XBGHA"0('L4YS--7$`IR<,1,\T
+M+@Z39]\0,0&7J[5":58-L>4T+I`T0=#<E>!YUW]^-SR[6'3AY8!Q).QUYF+]
+M6/V(V..MW2S!67*&\S3U$:KMQ4\0MOM:%8$WS[OC7W:/ZP2;YHA3L^^1CY:%
+MD'B&%@%,'L$_#N#I4>N2>3N7*[!-R"N5,3',:I#<_L&AZ[`7L*&DQW\0A@Y\
+MM-:B=*I#``!C4GQ/AEF\8'>3NZ/)$!7`A7#GI[GW#!65^BTQPL0__#3>QY0C
+M"%@=CM.3P4NVUV):V'5$E:,&+H)MR_&:@##('`%$G:B-YVJ199;`>Y!\VHM`
+MJ<8J`0W8UL%!KK1,,CA,FK]RLQ:)QG"T,YO7_W^XH3UJ(.:U,Y9XF/CZK\W$
+M*E)<)$R^CO*8+*.]&=AK&,-KY\TEJE]W[#HYQS:)-+,>!,WTE^G[O/1<;Q%H
+MBVYP$"=T:FBP=`I+3P<R7<^;.&(;)N*3UR?Y-B%C1N2I]"'%,T]10#WM'=EN
+M#G4CR'I-=U;Z))>%1W$TZJS-X8=,F'SUU8[RU_%4**1T>O650]*T#<\X'@O9
+MB`+?.<8T3XE&W@4E'RT5@3O8#1HF?O:_I&K&AOP%J>(P:8PV;W%Q/88\+4<3
+MEYAC$)G90_#-<$"56E'N`.%LL>&S+KPUT!*1Q;\L;S/D7MCS(_'/_^A%/4QS
+M/%:,_E?`%ZMAC:MJFS/1XN@!/,3*4D9?6#,TLG[<U!(!\FA-O@K$C/IY6F9G
+M//+2@\2/_M6&.PT!X$B%2ZD5`:)B&!1!0C`MV'163Q%[AQY*I$((:8;3NL[U
+M_E[7,T-Y;5/P?1L4"1,_*0J2D^N_=;,OIA*GU3E5W87+$,)MB,C%@E+2-^@G
+MQ4B[3FYC,_)!'K[#H"`,7T;0:!@E&S!!,Y?<(05,87A:<S27@-D``\L@N8Y(
+M!:9,K500C\S0[-JKD"(A)O^#U*ZOQ,F*+:)2:/$\+@+3&<]#&\&/>['/#;0Y
+M(I`)Q/9I=0K)Z@V;\PV3G[T6)9S2&7U#"I:VZF@4JEK0F(V)F;Q1:K8,/M6D
+MYM!.09OE0G#,]I327I&$S3=S3Z/*\R\WS>VJ&*^8;3<Z@I0&$P1+!"9686.D
+MRS>LFUWHGG+7'^_64]*ER["P4*]:Z;NB"_GY:<9<.?+"B(@A[+`+KS4]/LR>
+MH5X?G)Y<<RKZ8K,F_H2X;[2U&\+"/@M6]1X.FHTXR*CD')&ZEL:__1$B=5HY
+MZA:)/:SWF$'(>\+D1UXTVN,5.[98(J$*X_],(>9(B\AYPG;Q9A,S54KY3;<:
+MTU99G64/KI'>)(/D,S^_4I(*^:O9-"#@>$RL065D*<I-B$2&VMM6L#EEB#E!
+MSY&$G-:T)@3"IW/T*696(BGF,/G@_[7L4=*@TB'S1[J_DZDC67O-.?NQ[L_&
+MT;XL-$/BW*[W247'34;(T"(+]',^AY?/^8`/'!JDWI4;2\L:C5&`,3ENO-$>
+M-:2YN4;$:D@,B.AXZTYPQ<9"4`>I<]?%EG"CXWKLT)%#W/JP8$(.5+4\CV-9
+M;6T94H"^39#M1%W*Y"-?$&X\6TK@0.1^UW.\,L9Z:%U,(@HB_NZJ5-SD/<:X
+M.!P4.T3"P^(AVHX/[1LD[W\F##A?]XZF?$;+P*(1Z9$=FG:D*OB;8A6M"GZU
+MY;RQO3ZE&3.I*@)(>[T[9$37MQW[XZ34M2Z=\IV7&F[8,S'6MQ4+P6[?D.]/
+M7MR0&!]\^-&(=NW27W.+7_P9?/NFA:7CY=;AUDCQV"<F5^@/1L8<@=]YV!P>
+M=39$+UHE2^FILA0T]XS5JST*;0(/11([MB+`P.J9(SM,G/L#[-,5U$NYL@_Q
+MC1!>C_:LZ(_MLFYZ3\!#<8MZQ-BF.?;RM9=66[LQN(S%2/AG2]TJ*9A!\FUW
+MK%AYQOD]C<4WR>?MDK(;6T&)QANO\_JSX@"/C-Z<LV4_OE6#$<T(N[]UA\)$
+M[4->S(==%_LE5)M/YJ_+.^*X$##B%P6E\3'&Y%]W9OKL#6='03-IBO%&O'M[
+M3@R2G_RFUR!5G[-FC;3W]JCI5W:7XR`7,W5[?^T-T0Q49$]8[3@Q4N[8)(8)
+MVQ[]Q,*VKSOF<%WHR<\'.^;3M6WB,_I!,6X;0Z%FKRJ''''+W^7US8Z6PD09
+M7_$<-]PR59NIM!V8+*@L&Y2STN+,:P_#!>^':RGGQ6%@**4&LM5H2^\JI#*5
+M.%)#@$(KD4XE_^MK6'OKZI&T;91E"GX]%F_>[YC@*I6;?GK*+SKF>C)?(]`D
+MFU9O.-41V:<.MF'B_2=[(42OD-9V`!I?@VER>%)VK03A(R>XG[2W70*LF1WO
+MBM7#:1TD?_1<ORT;"C.]C"LPB!ZZ5AT/.8E#T4<FP28U(A\O?&K8P-?DGGF&
+MC,5.11,/#D!#^&W,V"7/70?:5JR2L9`V`^V*MO-39AE'NXC9S):G#JC+QHFO
+MB=:D^?-)/65<Q%)3E_<^CVH%W%\7'IC%J524%SWQ-8Q6]V01)-X1P/FMPL)D
+MZ_^,Z_\4W\B.YTIBVYR<T/(GAUIWK'_@40J&)DV5O][IY-%XQ7CH7%F$,5N;
+MXUOR8!J>"WHW+MSRS*W?X#0M_>34J>KTX&EW_^9\/+)V<8DMUM$RU&6JT'WV
+M8[_"/T\5U,NF\:=ZVD_`FF><OG::$[!C'H'_BSQ"3:MI/Z'J%^*F3GS!\LNZ
+MJ1-^//1P_E[#%K=.DIQQGV$`1MZ8U-`2,!(QG$>.XHGP(+GVXRO*BYS-8W=>
+M1F_E8:?U<D$/A4S^"6Q`MGML/Q=#A@56"LR$[5,6)O_NS6-E1SJ;U:2\4BV_
+M;!CM*H.MO74G"H@=Z;@<V7]Q(K;DO;^-E`$R37<<*IS!ZZ[$QJ1M#T1;\JMQ
+MQW<=I6UB08^2I`!+&YM*F]\23MKGT92AALD/G!HAAN$MPY*"V0?3JZ7#^$1U
+MH#I,[P>Y6-C?/?I')R_];E<=J=Z>\?Y98GS:=L\]D_O@5\]\YGO@DN[Q5[^;
+M>(#D_=B(&DS1;)X>T)U<_P@R_M`-3[WG._BC9Z>^.9Q6U',5B:MPM/S[UURP
+M%G\_]Z'O#R5&D9P9^E3FW(`=L3HJVEQ>6ZVIJ0FJ5TKB'0I8C!AAD#'=RC1%
+MH&*B*A/),*<PU:W[U$-U[N7@H=KA#<)3H%OLFQL*@VZ=T\'.6L:X0T?=P."%
+M&O=AY5XYN"XYKA+5L!Q1H*`)\-%A:)O'ALF'_O0&$_?$B&Z4L(?K$K.E'"(_
+M'_I3C(#:->?4S8&JX:RSI0:H``]411GPY.F<7_]MT0*^<@]3W_XP>15H`\48
+MJ>%KL]'"@NA8$>#+WO6>$6H=G!1'F&CPJD5J-*%`2-[\%]X1.*X:@T1DA0.?
+M_2!8?>XB1S#6C+ZBE"_;WLOF+V6,JM;V4!@+7DJ/-NMA6:O"Y+M_YYQ,Z;%Z
+M!67T)E*[$:(M_:WGQ&,J-1S7"/4J(D0H=G\Q[I2@1.WV/$S=!+R<&RUXE0"8
+M%;GOVB@S$6MO9QT3WV!+23(++M_<3=YW`6E01H0PH[V!F&@D^[GO6OS./E<B
+MLFJB_:-ML`0Q*PZJ;XH1#-Y*#,8P^8-/HJQYJ`#6UQX[;BS+$$-B1!IC(=[/
+MZ_[L:`'P/4&TFXJ5=Q_?N'.G5SU;M5VRC(DN)#G]L20Y8>*^YQH>$O+)#V<#
+MNV1]KD:J(++;_#S72GVK8653>JU#RY$PK>PW]3UK%@MTY)21>G;"^(VM(37B
+MV930)DF8S?1'S',I52$R@S#QID=L]P/.P&GIGFE+8@PVHAIABQC/$9%1VSF:
+M&@4$.LB!<T<B9*O>XB8>?+<?QC"E#CZB^W'MPDI0MX93J=S*-]1P:DST4DOQ
+M,+SYS,SZS%G3F86E$]&21+`84MW=\^-<_XL_RQ=,VP\3.L+?@-#`ETQ>3)DX
+MY"ON-'M3CV"?MR.?E1CN8/[F0>I%'ZK#8#C\A_0ADD:R!3[:R*'RPH/&8O%#
+M:";/>.\U<YR&\-GP*<Q'%0,4`P#]5\5+14J(22IKR633'KRCJET0HN]`"+:/
+M-YQ[14SQ5$V5RDCSHC!QZ._]IE@D125IMMNCGF*XW%2Q@<857'X1,JE+U%U1
+MI@L%H2XB<EV[R74G'-3;I)BYOUQ.6Z)8JGGWB!>B\%#.3J7#U(:-',*DYV:4
+MB>O%_%ZS&:5G)7]ZP9)J*(LJRDJSNAH;+"C+AHO+T=C`2R.YDZLE=T(1T##U
+M)W];+@E)DN7YHRU'ARI"#$JY/O>-3"M8+XX.88#[X`_V$?9,6/'&<"/CM#3R
+M1;)D>C*IS%"2[L*+,<R0'?'4.V'R]G>.X3I#C&#3=>;QXBE8#J6K>ZH4BJPR
+MA9J9O(S:',)<M8MMV]@-=ZBA]]FLVD5J9/[&5;N[\-YFN^B(]XU10$*5NN"F
+M*$\BTW5)[ISXVZM1;%NTG1S&G,H%Q!QS3R&2M:8\I<^]=_W/,-J:$E+F'-DA
+M_:1?\*LITW]V.E)&;EH6,:D_FKTUVWL@5I4"QS=M!FT81A#5(`U7\RU-PI!S
+MY.(T_5P\@2LP]X1$=UR?&@0PCW3ML+U[P\1@`CM`DQ';]XU87'02OI++HR,1
+ME$8"19;@Y:F,]4];<_GJ]FZB_Z4A)QS*EN-S"J32T"I(GPJ<3(;_3MNZV&.>
+M6(2R^ZDG"BSE5#Q.5)AJ7QSC%/0.=DG4/]%89E"NL?R@V'/[9:Q,H%.L"R\B
+MZ)2#E.)1A,LXE&TK(8LT*6PB!1>HF"F-HR`2A96:=<IEEX*R\`IR-?3.G;9-
+M$PV(_'F89&WZ3^C(]-YRW%$O&YV<*RV+8+D6>*76O\N/PK%&QL'4'-P+U`%J
+M&MH@)B*H0X5P+R:2<XT>#`D=UY*=CZ>*,_D&J6]^UJ\8`=]KB@4(@1=L[E^$
+M+9,KRL["M*/LDAXN&+,H-O(]T>*BLH.R*]D53^W\&%M@JKW%)7SH_*!E+E5-
+M78#'_$@OK!5:/8*KL2"A`Y(58`9R^,#S3"+A<.G/9A=?7)`1><X2+A!/#5@G
+MQS_G7X4&LAR(3H4_(IO*<P]B/OHG_[5R/MKR6%!6TN`ZR;8;S986O,[*:,YY
+ML40!Y-TSV6BV2I,N#=V"KQAN#),_*GM`;HQH<C=B+Y)*`'JXKI$'&T8,?#0Z
+MQH:EH]3Y>,*4O9KKXIRR/1.-,#`^K`LOL%@X?X4QX4E$8N!(E(XRT,\8$>P,
+MF7=]8I$I'27Y!W11N`9)8PV2P?B/U)I[S^4^H6+.FW@*(SP86G/N>FD<+/!G
+MG@,S3A9#C%NX?O-X#XQ$4CY$35S*E>+SB["MCJ_G[@D:W<=>?QJV2207$:,@
+M$EWP&3#,!&!B8]*A&,/$[R]N$YJ4SV`2P-,D1QS=(`*V_/W%7-FZPA7I`5SA
+MSAC%6L6VF$3V&.4\:P\W)=5)Q$D4)C_:=;Y%@SNBD!\$'VW;QG6\=K=(6HX6
+MI+R(9(C(AL6W`0-KA1E(#^!E=-H3;-6#67)WECRJYIIB9*JA+*6/RDJ`!X$=
+MA)8GA(#Y5"G-A=]I3\L9>T-T#--CC>U3&\%-(,5"\H'-P4CJ=SS.1C"O<(=U
+M*7$?(L]9VLX#_MI[W[B[R4PS%'JT",309,GT(L#\10+FHS1O7%AZ[DG/'CV=
+MHBDVK\W0P:]RF(Y/$O$[,3#V)&@+58.K4*,M!K5(BHUPP9\+//[SW:8($[^X
+MVI\*9V89@MMQ;J;`.==/FPZF8Z/'*_GX]O--P0A'L'[V;\4VV"?6X1'C@>QU
+M[C]$@&.FE]3\%#V>_]B@>+@OCM1M]0TFOUS3M3WR[NL%!A^F4I\#7W,VR*D(
+M7-[.$_S>GR>;>*3OS]5,]+YFRP`E)>QYM&(M@(R9*(0HJ?,E<DY;J>LXOC)B
+MZ4:MP-XXG.'9GW7QZ;(#^G(Q+>*$J,DR(7HT=STQ"*&,WK8"#9X@NQQ/+:Z5
+MY?RU0%3'A?!M63T/,PEVN"M^402\],"-7AA%/$5K-#JR2X[<@JGPHK^\F[LM
+MK\=NR^#*W#P!IM4;)R[.+SZUT%C<\$[ZSM=,Y/3%J&FIN?+"TDDO?!7C9]9S
+M;^4K]R)Z!L,<J!06EIXGOQ_:LON^+#)Q;',&?NDFC])+D(;4M%+YW8\=E*(D
+M4D:NA3!:C6.K2^.CQ^"F>0V,(6+78I#X^3-L?)$V@.*V56X#Z,E]K*.C6>H*
+MFPO$\84<CW5TW23;C<<\^FX6C$RV4J#=IHLP;?E%?3#^1_>8.*BM/U/SSLN=
+MPQX)PJ+F)@O<5]891&ZQ&57I.%(+O0*Q[J-[0(BX/%AEI75B.IJ?2'SXX1+V
+ME%UT[K9I*INE<F.[!G[:`ODL$#9)!ZT_GG)0,8$+DO,91FJTFZ(!#D<GG?CU
+M5H[LYJ2=O;&>L<K3C'C&82OR`[A#9AE+?7U8$8RFVN1LT]B.:50'.5+U-V9^
+MK"/>[%#@"R<XZST$U1#/$2;AY<=X5Q0JT#2'M73+3?[Q7XVP%O*%!%GUB]<.
+MRTPHTUIS/*X14"C&J8,X1+-=1!<4=,Q'_\XYC.QY<A+%8]$T)>`-@N8P,WT3
+MCI9&/D/_QH(`[C]KEU[3PGNI;<L5'\]K.`A[F/AI4/9:A)6QOICJOV#^(@51
+M5->A\S.462T_F50?O&)J&<ZC_+`Y;6)I)KQI&:L)N<OQCD'JMB\'=35NO.!S
+M"O/Z.*:\9MO<90N8$-R#I6_-2!"ICI$IOV,?8MIZMF'B('5BP23%#-.[GO(K
+MUKTZH9X?#K<0MVG4*DWJ=>5Q5.9L*T[7^+F#55FD?_99[M.&]3QZY%@-4E.[
+M4.WMJ7(EA(!N4`Y@P^4-Z:3P`_EA?OM"VP(]9J4J^ZHQ,RKC<1K=)`\&R>57
+M&U0`:'C,FZ)#&",FE&";5PH(4X[0&N[_:C1%9`TE-N00K$*/Z($GK/+JB2'6
+M=\P%,W4^%95/.#S['/:(%/E#AB\IA)\W#:V"I*6B!01X!6IEBGU&J90MV#$V
+MG<YG='6%L4`8Y=*J/C$#[BL;E7O*$XO*?6#V,+A!,"6HW2.8(&!*#)(/[L`E
+M.?E`<_'H&5O0]H%CJ0DD&AI2T/:Q`J_ZTG.0F!\A-:,'WR!UX_3A:>6;TBYS
+M13F+VV^NL''.LN.3(C!WTYDQ2R3!#K%81.IKBTN,=*P(D\^_,&CZ91(,X98B
+M"0[B;&T7-ZQ9Z)[XU`O`9V`',<:L8IG62,-CCCZ0I)2Q&3%P2?A^JD,V<74/
+M@!TF_T>;I"F5!]#&:#><Z18I@\[YG05-W?R%KKICM`3#)??Z1LFX;:P]ME[,
+M;?5-WW/<R]WD=_^-2U`UF2S?_3?,;RB3RV8K^KO_1GGWZFC[5H;)(&+/'H#2
+M0,G2@(WMTFC&`@;0=P>!D!!2MCP62M>8BO1Q]P.XX4E(%5%CZP/5X8SIZ&0S
+M-T+L$ID<L=>0Q)8LMC"Y=3WFWVDBZWVJKA;KB(!U.C!@_TA3JS2?@/#IAI(#
+M#W\V@CA[O7+_2K^3E'<;MV#[Q5VUJF-CB+V5&A1Z+<(DZFFJJ(PL,V9!QQ`+
+M\.@X8YOK?%XR(#&3Q?*P7)PU>@'""%RAZJ*#V:?9NN4R""K5`L]N3*<P%0'7
+MN9(NW5*Q:6CB1MX5K5*T*3\?:K\Z3-WXUP[-96DAM0G3H'VOVVA,76I@#01A
+M%5-KBO>CWRBYSM5OZ$N:4O9R9YK,,"3MD)4QRQ>I2PN3+WG4ZW*CJ'\'H^,E
+MUR1H;6FN1IFVD=I?ZET56ZB(='&XU`\">+K%8`/9"-ZYD_@R#796PZ'-49!8
+M/9CU!.P,HD*-S:%T.)^\ZAJF=21=VG.Z=)#Z\+>D$-.%TWS@%\?*>B,[6<@I
+MYDWB)(I6`NV.:J%I3;1TG,:"/L[(!Z5?RC55MT0WJ1MV$).`P0V)B>;KG%&U
+M8OU4I`^3T!5>;DMPX`E<]Q1PH8F)5KF<><NUCX`[S7#"Y`O/@14>*:U"M%#:
+M`-GJ#0N[1)IR`Y`2JA\346=8`1,ZD)4!L\UVRYAXF0S*1<W"Y$\?/FM:L&\%
+M:OIH53Q%]YK"FRX:SK"H'\84BEJ6G#NV@16/[M37@!+V[QO/"AW1;BK[8L><
+MBZ9<"#_)<EDOK+5P1;P<$][/^<7GT_O!=2OC7TZZ=<MN*J'&ZF++L42)>I0`
+MH4W$CF^\7)U8RT!G/+AVR&,XQU.79(1AQ)SH0D&.&X593>ECB71D!R4/]S!Q
+M*'QW,1\ADXA37E,%J.O)8P%_$7$ERN0GP5V@C>2,;U)"OC-LZ>T(!ARD'IDE
+MN%S4V,,N;)+UU2Y6GV-+SK;&,+0,-G3_I"@6#.IT>_NIV(_EDW>46J:2-.A$
+M873$@DIQ'CC_2UAX:I-5MCB7=O3&`3S'*!/[];!(L<9CAJ]:<<,9[<MHY,V#
+MY!MN6J'QQBSQ:KZ\-E?56'=LZ#JKHY:H#N+:TWINH"BP'CFHLDX@*]M%9:,(
+M<!;R,''PH<=3W-S)N&=^3'8W<G(<?$CP;"Q]UL^J&$IH<YY;^\,&C7#?=I1K
+M+Q(3TD'BMJ?$*^%T/%LHR>"1(EY&!8]-`2(E.AT5FFY"'0QN`[N3TD+*)_TP
+MAFB9@D:4\8P!;`QPP<<A6DO.[%4"%\;,,3K$+2.$V43;F!QED'A3':9#\60\
+M2:81"W8Y3*8]TDY'*M,MJUG9VI<B%KB9!XD;WS*FV]X\9L-L":D/-<>":(QL
+M2I'5RL@;C!PHS\XUG''5:&&J>.9</V<Z>MN"VC!Y]->=H(^Q2?0XP49H=22:
+M2Y(=75D&TG!H"MR/D-R/5HS*@O%7:7_+<^[Q6:]:N5TE\I$S,X)VYOBDA*5(
+M&UC5$Z6GH1"*?8HGKVE-79-<!F(%LIH9B[WF,REQ5Y7:;]%'"DCU\>:E1H=L
+MIQG)>*^82'#<D]73A#T=!SP3!^6'R9M?2FXJG<0<^492-X.,[*";D5';:]9A
+M\8[=<<A3+V3>K.M\5B8XDFE&;6IPE$%'V)=2I8M92PDD1A6U1RQ$$VK<Y,=I
+M29G1V\='MT9JY=`N\K->38<\*X$MNNGGL+R+G@<:S9JD+1L!IME-?.U)*0\)
+MI45=$SM.LUJC@S5AJ]2?G8/S+</4(#OYQZ/VMM4)>QG8T8F<&N!>$>MZN6GA
+MK^2)F"SPB)I*O>GCT17H^0S_H.44-Z'!!E=U1;P2Q`5!K:^HE\P3612*9EI_
+MEX9E?0=74H4QO!48&B3Y?-9Y5,O!(H@U-8C/HUB?0>*.H-W\X7!_.A+BAFL]
+M9@Z3S6!L+ITVAO'2H6BU,.>N0,M.SQ]EXHL6P3SN")MCPR=AXM%WC28-A=1K
+MT02*A>JPSWR2>N6`8F8`S[MJM"T55EA&21.YOC=;*L_8K85:!LE+)9O7[";T
+M-RRK*<+]!_"#&*EI&INHC>ONQA3258W+;%IHKLNLEZV%,U>F)J^22'#<%TPY
+MX)6>_.7-ODGE,$Z1[DVS5/(]Q2T'/)?`XFYA?;L3]Y\T_:0X][TF:'[RV^\#
+M@59#F/C,V>/(K&)E)A%B3VI8T;>((([(Y$Q/]X:$4NCQ(P6J##H/<NPKGX:Q
+M'ES6(K:<,68+`F>/H^7L)M_[DM&/)"-7`IJX-^61YYZST/W#B56[TR'=Y4&T
+MQFT*<UPJY!!K1.J-J+("V5D/YZ0FW[:'?%-,8KYMSWR4MT@D@1G4F5MB'"ED
+MN4/WNEH?BCS*S3XMY`KKXGL#458ZHT$NC/J-J1M&8ZLK1V1LXCW-'8%L/5!:
+MK)M(3;:8B=3`,6]:]S202LL0\(@_9'(@QSZQ',B=_W6X%N=V\?IN\3)A\M?O
+MBC8VK-3$^_=52=\?F'$`3"J@3Y$5@C[EJ:C//L*^4IL7IL%/MZW.J]00FC)_
+M@^1W'L9(L'-MD!F.=2"7Z1N@^DA1)[L@8(7/H<E2]'&B?H4G+^5>DB4M&`(R
+M+'SHX<%-0]@3<[>[?>Z7R)NXK"G7?RV]I1;UA,!@0X*Z<CI6:*0C^0UK)TN8
+MVJ2418RKS'9+5D4$RV'-[4IZD'AP%2R":7:1/Q;./:=XI:4H_<H4L+D"`)I+
+M\$1DET2X.S0\L>.8(YB@L&UETGDV(^C#1-`?;X'U1+.3!891*KB28[N4W2^8
+MX(5]=-\+0=:C-,<Z:Z@8;T`\AEU5@FX9M*28'!$.29N\-;'RS"#YL[==6LW"
+M`0JZU?ICLCEK[88?7G4-E9D=!?QYM*O\D.9*<Y8#F\'E=,W);X9C^]N'R6=^
+MVJ/)=ZHM*D<&A6,K\YHF&-H4CFBLP35'8R.@4@%)41%U7J1:QMB6:>MA(FKE
+M28?-R+LC6$`.TS*H!"/81IL`)^:1S,+2']:?Q2"O'7/]VS?DPU5?NV9K?O'D
+M`T%N9CNLZ=IGE!9__GY0E<ASRQ:7I&;I5U./-"D[2P?;49=_:WAENS%8]:SJ
+MX=#M4AO08PI%6'%NM$HL_^VRZ[+*W7,C%E[?-XF[R4\<&RU-$POX$\>RN!6Y
+M=])(*@'K&!R*CTY[M]R\1;U^6X)>-05:Y!!8]]X'TF1!#*-^R2\_'SB(C@&!
+M2_4_'=;C<:<\/R/F2]16,7L>O>0P^<4ONZUI:A!F*"9J)N6+7VY0<0H=T7W_
+MW/6,CD@+9KN&-B47+>(<;4MJ4#U25^#8;<+DQ3^]KDW5?:IL>/EA[B7,N!6+
+M%KC<>NRM`6R5,EM?D7V$S9\^159$H-P2:*^P1^@BK,8QX84^8GJPE4:CF_B7
+M_QC-+\,/_6:[[!S%>/KI%_[9K-W)3+2IP6CCH&Q@J0:CRM"90G#L[3IFEH'H
+MU9K$`711@3>*8N$E2M:.\>W.-OF1QW?A6+@L!@QW$*,TNS``_RR.<E-\+,/%
+MR[#PN<.D5C)2JHFU!TYA.;Q@I<:=I[$T(5K8R]E[NLI.LYB21:8*,<L9[7;.
+M]'>CD/1'ON!SX$VMG>:2?1)]F_48EPF"'Z2]<@'#@T#-RJ>J#B<692'DYH.=
+M&9/\PT-N>I"\X::LV"?2I;+H=*,8"U/KICVSJN>!]CP$E&UO82!,=65:^4I?
+M&VY=2G"L0>K:R96MYQC">!3W9"C`;XBCRRQ9+(;ZX0=H>.9FQF,@M&U0;(".
+M.U?Y7(MC7'TK!H\OPW2OV*!.=8VG$F.ZJF:-HA_$=]QJ="("91(RU/[6?*SS
+MLVPTE=JH6?W7=*4J5>W\1CA<)__@.H%X<O%H_F./&^C1-E9-]I1E!^,6\Q>V
+M"<UX6M-[/1I'>6M9N@BM64U7#&46(J(^PM2E=?$6!0/?]Q!++D\;+R>@<S-2
+M>:W<"2,U@>+UNK.&P:DCX2F[D1K6AJ7&?\FC/^+Z7?5,>+ED^0259?>9,ZWO
+M#B.&(3SN<F*XII!QWT\,6$)\`O:KRTO,NBP)$\$T:S+`K,:FDS>\SS:1B_?Y
+MH.AA#):RD<EREQZCZ:RHJ>4+A]-I!S21THPJ6)"1)67UGO;@?;!`+;5\S;7!
+M[F':5]3P%(^([C_/&2<:-'N"#=E#3"HX<S%6'HMPI&U0!8<:._\1!#SK52,U
+M:D8/FB`;`S%37WS=F%=[AKQ%7.1].]'NI>5@&!T!IX1;>GD[?/.UL_#9VGRP
+MBKAFXV8N3)TY],[O6.E+-$GC'_1E"WQ+QU8DWE/&?$X7WN1U]S$V/0=,PM0S
+MGK,<*%,!3-:`-LT_+1,.7`R+LCP[I.Z5TJC:9<J\&%K1@1_X)A-]X?*KZ(@9
+MNHC7+J\QI)UPCLWD]P[HJFEFYN7:Y+5J.)7?"V?*=-JSCD>Q/Z@%F!-4#0WU
+M@S857<]^U2W[;YSXQJ:_A35;NQO^1RVJOO+8S6=@C\)=]+<[[_X(_7+-[N[S
+M-_UB._S77/?)QVX[`^G9=G5?\(:?G4$_NN6Q@]?`K^V5:^R5N_!*ONB>3;=<
+M8W[SQ;O_[G7F#Q?"@"[:1`IY:%J2)[YUHA_I6\:G*Z%F"Q@:M#A.JR@S:=[4
+MHH1H^Q/<@]S2'MM<&I-ICQ)*E9QC#C3:#_=<F'K*;O$BC6#9&Y9AEA6SRZ-2
+M(1ZRL9QE\(QEF4@UK)A75^/B0(@OTY37%@UY(C\&!X_)#=C;[??1SD10`HYJ
+MB`522`4\LKDSL%V[J?:KAE/;_4=,ZQ5$4PM,G5U&EX[U6L:PFC\##3!*,F)7
+M\%MPQYF/<&!59&45.$DMFK)$P\5;>.H3CO'"L@7Z:L&U4^)=8E,2!9Q\8E'`
+M+__N<`RJ3**<>DF6#C:I1L%UYR*D6>.,23<!%$PM/&O:K.Z0VW+!*,&FH09=
+M@1@0$HMSRM.MJGR+12B;O1DFOGS_<,JWE>F6_;PIP$$[\DT'6_N[1ZR_S[Q^
+MH?NB0W<,IZE-4<1U1/P7HOY\`FDMJ8<1N9Z):<L(ADG\.T)_96X@-K3E:^"/
+MUP^GKMEZQ273GDSS=S7P.I='F"+#QF^DB5L8\9%<2E>R=428\15?.7/#O/#J
+M&&HI2RIC>3`D@Q"ZFD,$T"YOQWZ8(Y*-(,1GO-#G$4E.W$H9',7-*G2\!K$G
+M.&H,X&#S$TLN4Y;NF%)U<G7$P_3*0A@H(346%:K'X`["CMZ$;=+,YVTEB>_,
+MVDQN`T-N)E('UHT:4[I!!.I@R9RQ?`W\'S9\1@V=-60._A@I5EI'V^2Z\&5J
+MZN#R-=W4U)NE#>YV^K/<WC.%>5F**TKS=N+>IE1YF3TDB02.L[>]5D&C8Y+P
+MHX?$LQ.GKVM;M>@F,-D\ES>:FE<U89&GZ<0/-U`?:]6X;<@5I)?;`U6YUC>D
+MG2P5RXJK6ZN46KY^I+W<3=[9-E-E:)G28?+.OQ8B.RSTJD60AO.V1$'9LK6^
+MUY3ZHG$P+'B@[2!D0,*[3'Q%//[5$=-?1GA#F'K3"T>[9N!>]8*%(#%BP>+5
+MAY%/FH@;N.Q2L$Y>9Y"T)O]4FE.-_E[;!M9^S#7QO6>.%%FM]&I:^I%EBG>Y
+M\LU>^TA$`O0,'E;/MBV5'B9RF\J%]A$,9OAAP]3;_CZ"3M@5#0=C303/7'3V
+M,VH;Q2TLQ041A.7Y_*L1E2IS%PD>5-YKOPR=)5)"W63S`?P$;4C(F@]L-LV%
+MN.LR<19G35L1#T]K6XWE=2Z--ZY8W-*QM>!>2"B?M8(:(4WM4WN,9IAZZ5<\
+M<_SQ8P=/(FK@>(P?][%I&U!`E89Z!/Q-"B>(LASCW^<.&]-/&T]K3&\+RJ'%
+MT09,A[KTASL_:FJNJ-4I,2F\XOZ:5%C=O@'^\/43BF`4RX7#*ZN(D+AI!_=[
+M:N2+6-IC)I111XN?N[7>1O*#FW:LC.!0*R6;;MJ!#>R5I&4JU)>@1@:JVA5[
+MABE9BE4/AZE7O=`4$*].^S2J7`M'H1W1/Q)IQ&4-&A;;XB4EF58W6@RL;4-.
+M:6L/)@*&RZ4R[_Z/E5H.U6ZQ>.`VVA(-Z@[GD:D61ZWM.$X4R3QU!Y\.DQK!
+M4H\?7G/&HEML_I)VO^G4_/UWC@3SA-@ACZP&5))B([3,8$H]`EVG-L\=99`J
+M\ZETE(FIJQLB<"AO)Z;1*.(Y6@&(1/OO3$3481&,!0OI8%P1#@P%7<F+%T>Y
+MRPBI;NNR%T['9<;IHY/.!)5A#MG/*O-DEO-^C[<(Y%`SJ]#E,:$#2W:%.+^0
+MF`G]<>+"9Z]0'BP;O%%SV6XY.0IB8Y"5O\(I(W$0\^S."+PN0M0E8S*Z)TQ=
+M^E<H!U*%!+ILUT7Q;Z;I61W9&O$4.R;DO:A(P?["EMSY'H`9@WU@F-SV[\:O
+MU=(:4;CW&M%*"_"6:0<XME=N45>EMTI+"'&5,`LM4:=6%]Y0CEM3NIGNTINY
+M;V56K$Q'QYYXP_E$EPERT&#87AV3/:;7)OQ:(FUXU-ILX^--GLNH6737(N>^
+M"BVFPIL94Y@F(XR9I&'R#_\']10M@.W#5O/7P%`I6/'FHPP>4_6!WS;+(@L@
+MAL$E)9.SX/S&=?#RF&##?@:S*>]U8G#`#G00L-9,S2MIO#.&9%!"_ZG+<_XT
+MD5:FN:PQWUMGQC3`YEA]&S<.28E'1Q%4#'FI;3X\EGA">-8="YA\$X+<?O9K
+M%]/:5BI+6G]F*R@=,$]<`\Q('^Z,91^=D?;!'"!W'T1&%"\UFSQ$P#OC&6),
+M;TLSBQ(<IIZ^N=*W-Y%1)BVX:E7.@56%PHO">U'W0A*)VC1F1S;A/H-_1)/H
+M&&)(DH-F0#(6^4@\KRO=Y+7K2P3%P!A3PW#7@1A>NSY`,]VI3F,+V:C8^!HQ
+M>>>HC3!C-=6(H?#5GPCS>TTJ#[U(`F,/8]6L8]_L]]@5S(5ISRWLL)+D-+LN
+M_H`P=>SG(Z1&\8_P*2V\7>]:"ZW(4&,3E%UX!\ROF0RO1`<FFO%V.W>B`A!<
+MUV'WUZO61Z`O9-92*;3E\V4*%Y?KH.)-Y;7.Y!-*RG:Z\$17WJ.;E?0`?N*P
+M7%;CD&9HY,U7D*;<QPG\U-D]T?RN;0C-362HJL%43UYRO$_H*N57M8RY1WK4
+MCFGUEY'!F)#+,P,;<I&/9"IFE]]6C4J)>7S1:3,>F\.H22C#8R'R<&W4MRK0
+M/FA$VF"@@V?KZK551)P>1MB+F&E@?F<&B7]ZV@Z3$6#EVC/5\>2>31:07-9\
+M>=JA[DR(P>8V]FF'XZ)H2:XD82,9P'8D`0Z3MP\=>*0A76Q)-QMV8TW47HAD
+M(;^S;`V!#GEW;5.)):W5VXAV(6;Y>6U)I`T.QGP[Y[=C+"TS+L5M65HR@V3J
+MISMX'63M3<C.-+P:\=O$JQ(PB>6NY)Y,8_N=FC26T01%#U80[!#YE0_E#I)@
+M[T>Y!Z9*V!H$@TMG$.X@V(%!#3BVI_TTD;5J;%MR*M/P%(D,@_OA1(NF<6LP
+MZ`%[4LS%F@]9IH[CGEA\^M'$85"J=VVCQBK@((;)9\"KW\KX,-Z`:Y]1LC@P
+M+O;]UKH]?-AU4X7/B2/YH1.#>'LD(0<TK%:NUP7%4N$.XB'0.0=-1=B_UV`P
+M3&8>M7+0C^@`/XE-RRU&1-3B$\B`^&8F<J'EYU221PE`4SQL%8]Y#6X,J6;V
+M&A!RMWJKW'*9,/'N3YN@P:RN84NH'#%M&#!D@(IY%@X41()V9DI@?F(I?JF,
+M;7*1C?G=GX:_'R?I)BXNQ@U%E.=BL#@LY$R,LA-\R:Q(K=1Y&/FB6S">-S,)
+MSB]?&>]_E5'24UG,,\=M8GH]F`)O[C#@>+4C&"EL)&!RTQQ^#%/O_[_<K9?@
+MXV3O--O'"MF5V*=U89JE`"':`$535QX-DP2N+BPR/8Y3L:GRV$4#TY52M^"Q
+MKGH%<_^P_PG"9?%*@_&L1"%AXT\FRHUX2&,7'&,XA+O+IW9$+$I0':3J#QD*
+M?X2RBQ?KM_(*I$F.`1OGF4RMJGS`OJO,+!5]QC/YR'Z4S%>`^OD1YK,P>6^5
+MYKF`+%\F=(C&F*5PC+N!-`V"'&G.\1FX!Y,J;+2[.#3Q_%HWW<2'T'+TV%X)
+MBA4F;OT%?)\U:+RSDX"2.?A7($Y%&Z9_2]XZ6>Q)--![<`E6">M99D7E=?C&
+M#+#NS#(?NPRBD7?E1,*&^ZH'XKND8VQ!TM)L(#OCAABID)=Z`+=2[@[9I4PP
+M<D3J37_8Q4A-F:FZ,]6P1@^5>US493DNDJ?=PMC(4H[J"4WQ)@=K667%^YJO
+M5,++EA+W(S:!2P-NYWQKT4$]2A$3.RU-=Q:%YB,2SU6Y#AG%%8YN^64D#GXO
+MA6>>0X;$<[%6=/X9Z:4\#0TRSQG2:!,QR*</$1J`BW$$\68-CT%B_EYG`L:L
+M:@'#VD[,C?Q>(?3E\1KAEFX?3G%Y.`_;-#:M9]NJE6:P-@:)0!.)CV?6E<K`
+MF^U&W<]@Z>(@>=_;"\CBL/%Q"0SBNNRT)MZ\:R^1HB*MGII%('UG==3!GQGE
+M_K=1)MR3HE\-&#Y,ZK?:2+D-;4BG;0(D:QM19W@]-66U6]]E#0V^AOBL021P
+MC)*,X"[R)L[D6J0GM;)\"=Q6):.W4WVER[^8<*GFYTJ[9NS01JDZ[.*`(7?I
+MDBXW=23*T:S9?L-L?83)XW\]6\+SLH1`#U,UQR$E3O-$-%2Y1-8\-V\Z;P!W
+M$\D!.8+&!7=]F3V5KTRXA3B0;!F.Z07,N9E!\K:_=DP75.0=,;%U75F=V1-_
+M0^^PD14-&VJ/]7Y*`OC&![##SCVSJ:-%4&<*BB:_BN?2TM^%R:\^)@)<0FYT
+M"C?/1YUE\NJ"G*14'\^_PXXU#0G*2;VIA<=S*2JBZ6?MJ96K51EK^N#/FW7/
+M^3(Q+B;XSCJGY3!=_$8:VHSZ&]JOBJ1TJ(?]<3AYAP7#V.P@\955%<4@6"]C
+M/:;_2K0*.-JVW$TJR#I<A,0(LCS.Y919EAPUR[A9+5JZ,/66/S.M/+QCD2AH
+MA6C-4NWX\DRMBTRDK8-G:W$.-KK7"\MW8&`WKSO+'`;XR1;CSQ&.)D\R:+:Z
+M+<8Q+*DOH^HT$*TC-GG%AX(=MA$H1WC$"]V%RZEGP0#^\$1MO",VH5<[IA+A
+MB$VH[JQY@CR:AF<8>?O!D[[5.AL=U9S70:4^7K*9J]R8AB+'FCP=!Y;$YZ''
+M#H8#'9OE.@+5I4L@57^7.`"#,%S<Q)T(>W^]8:+%,+)W/NK'*;W^:\Z%B.1A
+MV$H<Q<0+X)K*::K&PP)CI\R/\"NL=+S"REJ`)DMUZW]Z;32='*N1AIOTM9-5
+M@L9R))C8&GQ"00E+.IJYR)>0MA&7SHPF*%#&J@,NY1N-%6A)<B27CIRXF3?&
+MVBKZ!-N^J#^94F?'*>AMMSTEAT6O%<+$95]^DEW;+_NR[86'GV>M(5(MV.B1
+M,`!>^PYLHDJ)!:L0#VY20VQ"%5#'ZUB6V[([[JI&BD-8'^`9O#HS2'[NESL8
+MKNOAFXR[H#H2FQ'I%'"V8W.&$[G0,D>X-J?()(/B>"%XOD$35J7VV%*DR9@0
+M(?;-<X>UQB#YS6L1DN62?(Q`)%5*\3HZ)/.&;HKX:Q'WY[UH9C9P%?8P:F0J
+M1$.:0G\L]CK;8)XI2=4;0"<%;`WQ!IWH@\0C0W)C4/OMI:ID-C0<58G&I)NU
+M*\FX)WC+7MMSIB3O:LXI3KSX^9B,)L%J-SQV',=+R[U1QECK8,B\S^L0AVUJ
+M#>L1-4<Y_GWPZ9IWX/B8@$W&1PB(?$+2YERI;LH(!&F$STO;Z@LXP_$HD-0)
+M&J;R%3C36$]QRA<_91CIST1(PZ41LMC"XM0C0=8$K1[<X8)6N#,]DEG%$(@>
+MW-<W)+.D^1_<`7OJ]@U,2NZ@$G"=;BPL'2]O'VXNEP?)?WWI88L<YU&Z;`VF
+M16$&K^V,:9^,Y;^@$=M!,6^[?63T5<Y:LXUU*&![UF7@KTZ:%F@-H6PFYT.X
+M$KF;<81^@_@G6AMM8(LC-S8]$G>KA`"5V39L1TE_T[O.[>!)5-XN501J;XE[
+M]-+M<*??)F4%9J##N2B5MT>`)Y[O&NVR*1M`!CA%GA!R4PR2GZBLZ,5-VS"P
+M:8/->B"C+RVLT(L^&GJVFQ(WC&@M,!RY=A`KZFJV^-`=M&'J?WV@YK>07O'K
+M\4+_ZS/Z0IP#HZRU'SL"U][-S0JF#3Q/`OE,\6Z&AL08AA0#;,'5WRD95C'-
+M:GTF9^!*U?0`?N\^E\C5'=EMK7KX>3NMJ2E\W@QL4?SX<(,[!I/Y*0QKH;`)
+M2M'/R!V>3X1,R#Z5MA.A:E,3;L<['(FGK^_S])F"C'$&KPT"]6S]&KYAD&IO
+MA5-6U1J66`]O+G/_'E)L*&E&0@PB4<+@FFC&\H(%2V,9CL:_53VR(/F=B?`_
+M]8E%^'__WL,AT`F/!U[SGG/,DJUD$>\YQT3LYQM]DCC3O83;;_)&UA*K+G.)
+M+FJSM-J^[?(XH8K8/FT=@:$Z0'H4UH<U*0WJ<F)(W`T'T(H\1P(O6KAE\GF_
+M\4'7B8=.1M_'!X":XBT""G/3&TTD>)KA;^)`F6"!CZAW-HOV.E!X=*HL`Z5\
+MF/K=IP)UV.;,<(4#EW![E..">2^CS.V@,5_+3!]1L=S(T`_N'%EK-Y7K/(,H
+M-BFA8W@JS\0K[D3KP7,1RP:/)J7Y$AB0.,D,PF)HU1TQ@Y?WW\/,LK2=9TM%
+MS;C6Z!C!EA-=BVU]ZJ@M+(BM!P]B?!DXL)TP<?#/V.GVV%!@;FW<M#F`*W*J
+M/09I1>S:`I9EI+\FWTR/I-DR>ANE3=VI%&UTS2[?^5\RFGIL_G_\AAG`;?*5
+ML;2D%\BA&@)'Y42CK7A!-M.]1V\N2Y,[#P8ZTEI:JA&_^=F`HRT<D.!]YT:!
+MV$4T[1W).^E2.R<;U2CJ?(QCLUS.MY"7<!O!V4J%3HS5QX1Y$Y_Y_&'B*B,%
+MI::.@A^/B`TMY-JN9;=K0&TH_Y"(U+2!INI>^,@*_=3?AF'RM6U:0M^)IDQ4
+M@THA]V`RVROI'2E)1T=V!MRE&23Y)BLKUMW$H%*ER#O6<]%"@HW2VGS)MOU+
+MOWOU8W><OM`]\N\6AQO.6NB>]N#NW88%:0O67-30_[S@]'%;WD2I;5,7Z4"L
+M3?]AZ;]TP>DC:17+4P(?G:]'V7`J-A3K0Y@IKF-9"P?),UXJM-EDY/NP16QH
+M(MX@AMO0+(&==JF+@4D$3ML2"T-!1AM1/;D(MJG$B$"34Y>\K3G7-R%!\B7@
+M$*4^,Q03(#6!.O>2MPGFE1`GM@UVE,N*?Q0!#T68.1S-W"P#-3";.TCI+Y&1
+M'T]$<.(MHZ\PMH#M26^*\J6H5<DQT//:NY)N>U*LK.!&.DHPXJ,,4\D+YJ6_
+M3Y`S`22O7YR+.'#KWY9F?A8DX\*;O7!%L8;E(9M1G")T:5>!M[8"9YKM\%SB
+M]A1A,EC-U&G,\3>F4Z$7[M`NV#&`&SW0$ISI8WG5]/]K[5J@(ZWJ>W9FLNO"
+MRDN@+4LMT*.[E,F8F3QGU=HAV279379#DF51UAZ^3+Y)ALPCSF,WXTK5:D&/
+M$#->,GS.%(,M*@\+9>&`V'8K8L4JUBB<8BL-?:REQZ,42=MC?=#^'_?>[W[S
+MR,:>XEEA9[ZYWWW\[__]__UG9.U'9F/8'-A90E:3TVN*KU;QV4-F=9R&^%%!
+M5\<$X!>&E[(>1V@C:#1A9$!2NIY+8SG9+$[5#P!)5'S_L)PDSYT'?YU*\^&$
+MI[P]8?`=2=?\U[4@NUOI4#VA_BM#XE`QUQS2^_MO8"@+V'WML/@_U"H00#*&
+M&U2W7J-2DZP%H8-(<AX,/HDEMQ7_\_\I5YF4](.>0%@[^:Z9)'F;";NG2;,$
+MVJVL,X_Y"G4E(D6W%W$K(2AG-"DEWK'OF#AE2G>0G2KU'1$,J&!8'4&9X&F)
+ME$Q82*',R<%U2CL2_A5'-R*C1X'NENOHCC`\J<^$5F8RKDN%V_PFI8*@&[@1
+M!@O'15Q@5*,WDH=44\U#[U,.9]_LD$[[E<O^K8\F\&PWMAP<MY=N;$.#:174
+M@^>^D5]<^=4/?INK4[JYN>!P1KMLL,L@BJ$OWHQB:.5"^>1)A:+1>USW*):1
+M<@GKUZ35,4($`5?FB&$%?GH<R<*3]$]HE[@/)J0:AN^*.<S>E!5J';JN@%WO
+MQ$,5.R/IXK9OZ+BQX5[(QEBM[HNE.C:(N0XT,CJFDSE,\],N)M'@8&K06XV6
+MIY7`F_]*-8VS5'.XJFPHA^Q:]I1VC([2'3*_%'_K;8Q54/E[*OO/W6R24>@F
+M+\.O3`#ZQ#+#G5+QC'85E@,K/P6JY:`X*;P-V%(A?"8&_W</=S\6!NIZ!;[R
+M](EN*')AJS_C[8+EE%(FP.DC(\T[9AN-ZYHUG,0?6BRUC#9'R%(4&TT[UES3
+MV[.LO7!)[%+ZR$C1K&++)FKM;WRR!<Z\%ULHS]9`0[<E1^*G*=2WM*<OJ:%T
+M,>@ZU=:Y]@[51RD7/T)E//8]M\^BT:MJ0U<+^1<Q@X0B6Y[@AE.'EUT_^Z!Q
+M.".O>2,_'A>!+3&K,EDY%S9DP):JXM718&I2I=,XFFHSG(;DZQ"^D2=;S'GB
+MCJHN5+\;VSJZ=2I8D33SO89$[">M8ZE)N$38^QR!F'4LR4B;9_=C.B_<!!F\
+MDK'R:_]R^W4C`MOFB=W=W2(E`VSY*YNE?#^92B;@-37?]<^-D)E,=$+:T%0Q
+M5]J5/P/O&(#)@!S'!X_B4%=(!$4JH7:?W-T5#CNII'3Q-9])(E&`];9O>X4V
+M4F+G(6QCE0I:R=93%S4H$@Z:54/`G=`T3.V2R7L9RI5RFW8SWK/4ZH9&HA%K
+ML7SIE]K?#5L3"<L4V92NPV\QL^2TQ2<Q08+BF`J?:;H,]W3,%]_[7M1:*1=1
+M67WF]'@B8G=?I%]XW[ARX>AI,M;X,$`9&?TD[@;BNY"!A1.`OU#Q82MQZ@EV
+MBVN+65<@*<M()I0D-#"SD)3EY%19GX9L;\B737X;;JKL@R+J.OYQ:891;=MZ
+MFO(R869LDZ[T97B-&IM"/=I3>>ZF')5;+OIPHZ?RM9N>:KM]Y:[;O@GGNG+Z
+M':_!OS[1=N<#MWP;Z.S29X`O+3TZ0(UO%O&+?_Q3WUZ0"[,?M5*3^#U2''VS
+MY;*/'1^RE]YXP)I&1,N.]R277OG[>`$F>,_9;6U`,N_ZQF.K8\S$RX&A6U?\
+M(]_Z,"/])A+E+9^LZK\LPFN6CE8FX9:<BMH-S^+77YAY!G2=V-/YI<M.)Z?/
+M/-P+]_QDH^%^\;HG?IGAMER^]_L;#+<E=M]GC>'@DKS3'EOQ/]+S47Q@2]OA
+M+2O;'@GC+?+-V2](5K98WOU,^T9O+;_UNAM7HZ&>_B:O+,>#?QWN"7>?>2-N
+M_=27.T.1KJ:[\/DK_FN]Z\]O*C_1MAT^PS_M\70A&5T+1_O.//(S[WAH%8;N
+M:SKT*T_]RUJDLW,1;@\L>_L'O_H"7N4SKSER\?1J5T\T%.ELMNK?O>T;X7"D
+MLVM3RXZ$.L/-EYU^M#?2OZD%1D+1UNOK#??(]9V]5GX!^-.9E]?[V-1JI#_4
+MU]ML=5-_??E:N+MO<ZM;[0UU]3>=VN=N.F>3P^`)]K<:YH=G_6PMW!/I-I8(
+M7'=S2XQ&.J]JML(C-VSKZ>[L;/)ELR5&0UV1UBOLB_1L;H5]H;[.UBOLZX(5
+MPC\K>Q[IHAC4MXG+6<`#IY;^Z=$42,H+;PF'*K[/O[@Z5@4&L+1]C2VTK_V*
+MZ@Z*)NPE!_-+6^_0WNO'[RDL?_%ENPH/*[<:?)VOP3"["\NGHIC\1!@T2Z&S
+M;:HA0HP4>UGQD*7OW@JB.XG8Z_#4@2E@/:7"$HPH4$`2@\7)#A?@"_2#O?I\
+M/`D_I.%@D.F:[\'(CAD$72./^*GH-#UC+7WEFS2,,P]/VS!K"R,RHN&E]-\[
+M\(<<=8/78^,O!-V.X^.X7/A)9NG%G3/._"S.@MXM&.H%WK)\UR1^3/M%4"_P
+MB$J.LV`'/%M6\_WHMWG7<')+:M=H(%D;1G'/&.4.P&."7RW-OWK)Y:R"A(7S
+M07T49LG-09%\G=7IY#1E@E"RX?<?1J0Z>*-&N,,3!HOYHDE0S7JZ$5UI!D[7
+MX;U'#D^2VJ&=FP\!V5QQWCHG+WB03MYZK!ZP"PV-'3I,F==8@=)<Q<17<B//
+M4I,H_A9M,D'9+!0@<TOBC`".IZ(.=1[J80.FI5OJ8^"7G^[;+'[YZ;YY:E8@
+MDVW-1H-FNWINA*#\LV(JB<WU<JX/)J/=*MQCB8"6665U=`,*@C9&3[!J+/G9
+M'Y@=W`/S!QL[N)._0<7IS:BITK`X?`#FE4:*#H<B0=W1W6@;I/N^R[FX)GDE
+M,#71&0I'Q=$G.PZ=O$)FU\H,*P+-@G.#'>OM[C`H!2/5$Y18+B;``HR+<.=;
+MNL("\WPH,4>^9H*&.311"1QK[PZ%0UVA6N#8H9@*..AZ*S>=9<;*36$JBP&(
+MB;!!G!/CVE"27&3BR+P*!'@,6@U!AWZ(BK]D2V\]`;>Z00PA7UF?/^XV)*'8
+MJ8S*P^CASC>IYLI&L02Y1RA>R-4K-)<.G2E+*4OQI`P-_DW(\.UQZ<DY\6(*
+M@9M!KTZZ^<(RC*738&F="^B0I&7%L^1%ED%N"3`_PR>O$]WEC^29UD'JEBJ^
+M`XED1G4[-#%S,/)QS:_'I5=0>S/+\`.NS\*6>@<27,VM8GX4OI=N'@+JG9$A
+M0P<^10[!U>.4EA"GK,69((Z(EG:'3G=15=0&E'#-/_,I.G,/MXD;4#<R'0Z&
+MS&15X8LSK3NLJ_1,@AM$CA_I?).W>R/C1L/1ZBTBHU2%9LB@#".@05XF*-75
+M^>:+7$%#Z%'2_ZM2:S!/P.U2M<Q^JSK8`<>,J#8T#-JSN')Q[5XR5"/*4'T[
+MW&1&W#<!]]%N+>^T1&NP[:#'J[*A<X:*;12L+[`_R\#]=AVFCLR@?+LJ/C7H
+M>Q[N)_MVI)UM3A_MKJ,YLKN0=C-YG/R?5U0-C*J]W/1\*6$DK;*++;>QWA#O
+MQ(2Y"W+&AJN^XM\UYX;L==.&JLI62#BRMX"2:F7X@7<_'.4^QJ\,#W(0QY;@
+M[/*-#J/TN-TGR$!G3XQ.HG5R'6IGZ4J8L(8[)U1/`:=9+\PJY5;*5ANZ)J`J
+MP0'@W6Y7BE1=^`+&O<;.GBTT:K38J\J/U72,RXD.+KHLS8"C&P]]'QXVJC(/
+M1O%`X<@#EW[)]!?FQ=5#L0[M@6V1*Q'$GZGSU0AA,D,<OJH#D]9[HQ:`VRAW
+MJ>)[NF"UC+][TH4D]K6N0C):.G34@0$3JO>T2K9T&_L9RH4.I7AN#TQ6-1^B
+M2NZ$.(I%=O($;`F19R8[>3H#,-.`7ZDSTV<36ERYZ#].$7/;RX7@95_E_%8*
+M4N7\XUQT+1$X\[Q;KE9A>4L35+ZS0UFP3EW^GMY=\OQ3_!X8DZ[UT;G^"<36
+M??#A9$%O<4/R)55RH=33Y2-\B["9K=1@,#W=C,%IMSX5C5&Z/.Y0T^"=68YT
+M^#`7S5/<%B'".`G6['3>`#A7[Q9OWJM#NKU5E0J'J%3U3LWW=V'9<@UWW9-X
+MIISPF#G*"("J2$?#%6#`>YH/7SIP9UP(?K=3:[XNM-VAZS_JA$_-?\Y;5.KA
+M"3U0`WDU]+;%X#AZ19R34OMPK)31A:=`^0%9[OI$&N>T+-IT:V=T1CSLEDXT
+MYJA*[WU-E'"5T-.DR`%^0+1!B8<<3XLW@''GL2^T!)YI(C0T:=3+('._*OZ.
+MG2K>@)FC0.^HJS#[Q61^D4\9O6O*\#A%<#/JOVP<H6%[Q;$E(Z>C2KD%,LXO
+MC"HS98'F*X$MN\`82LI@GJX!5>(\2)8S&O@4UY6Y3T*FS,8I+LXD[FF0Z9;L
+M4V*BVR,GZ*VI#*3^DGM;.1Z$+,I=XQR?DI.B]"/2#ISAC"I=9?F&U),M"I6=
+M(W%B&,^6NN9ZHOU)LQ(BLZN@JYJQ&L`J8=K'_`["0FM>HTQ`MZVR2$1>9QT!
+M!<D,IC/3?\B)<<6ELGV5:_N\S;FV?RNT41+N\5GNO7S7274AF]!KPY74-8].
+M0YF:;/^DX\DRYW@WUI!00.1*&7-.BY+G*LKTK:";B-NLG37!$4T#I15M;R,;
+M45?1K0F*7!'U9=Q<[XX7GZ#=5*)5ZW1!5D/NV_F>M$H;B#1+&R#C;7'E?/G8
+MR5A"I^G6_(L?MQ>P?M9-A`4JT`4]ND[#A>E$^%ZX-QI9O"%\KYM0.[N;I;Q<
+MJ0Y3)0J8AUH.E&YNE:=?NEDBW,FDWX9<>B?'?0'0*2;3B5#*IZ3'`-:CG`6N
+M7X$\!&:0WLHON^U#\X3J>Y71"0N1#AF9DG%JB%NT[OC3V'GGB:N.&K%X.IHK
+ML.I1=R_(N;JJ-:W[1ZO954W<HXK_H7M[^CH[*4.5*-'*S`7I;YC3[:C.O1@T
+MK<K(O,(ODJEME*;FXB_+5AL%)\M;ISRDZHUR&CV=\$^HXG_W3F][1G>CE*N&
+M`G.4&<>U-4W2)((X3K+I!I"C*&>[$5#LIZS4#*DD9%2H7)40^[_V.L7'5-XF
+MOQ$%,W!>[#RL#&S5S8=]=L9."-TM7;68D.[*)L\T)K"X(*#D,9-X`$8+DK=W
+MS&.W(V_C/<=;6TJ^4P9Q01Q!L&C2U+97$"@8CD&^([<9C-%KG+!-N`X.H:=T
+MGJTIVV7W#.S!#%K9IX[6D>I;'5E![U:O&&C1&G%\GNT,,L)D-NUT!48#(G=;
+M<%'G71<J4\KAI;J$%W6.6.0&;!P=$O55(71?0+H>%[(,SLV"1C5#%B(0%H0S
+M17N63;L^1H9B_#2%IP>(0!6DY=VGF#4@&-&N_`9MWDR%2C.1)\<HFFR?#')R
+M73'?`O[3;4++MFD'YE-AOIJR8VO^X9^DDE,R49\\\M22C3#=4Y0Z+-TK>"/A
+MGF)$!G,1E(H-S[M=-[F/-C6+9-DH4V8SW*1O7/DQ:_[''R!OYX1'V7.&QZX/
+M.K)^';2+Z6QQ&2/AA%/*L&T)K3)DLAWU`EF5LX.R4/8_7J[W:1H9+E.3D6Z&
+M.I\!M4Z45+@_7X:O9+-0("OX"REFBLT@Q"51_7O<[AUL)<F#8#-#VTH*Z<`X
+M%9MY3"8K,(?=[*K,302_\@A[P#!'&H$+C.+LG&UWN`6@+9/M<(R&R]`5Z@J)
+M6(9W))>2&2$-Z)P&M2D!4.],1]#P#R2QK*N*0M';`5T)Z3(\X^%2SEP0/U,Y
+M?Z@/LP,'UX(CAKN`L%1JAP*;C?13'U-F&8[.4:(Z>V!('WLPSP0BB5E5^0K&
+M$$%Y@!7+(2?20TR8QY$=BN5%<U/K$;M/S*++TP4BRAL%QF9E!:;H`;=P`7L0
+M!E<K,>K*7UVJ!`I]Y"(O-80:\D$ES5MP)X,'*"^!S&0WA1T;\!1ID%\J%#V\
+M^Y@25PG,G)>R91&'"8PHXCQU!7U=ITK:9%DDB4REYP[65H;1&MQT528\^$JI
+M&FA(N>Y*<6A*3<DM[">-WV@.Y3]Z@<'K6E7!';U`*F7-M#&L'=,0<!*S5FX=
+MZBAPGQ!ZC+)])*YU2KIUX2LY05U&7ZH%>H9R-E@ZMK>=@2Q`0Y&G84"*,S-&
+M23=*>%3U$YX*\.;J+&^Z=")XDTGYT*3?2N6#\VWN)F<'Z^`$+#^0Q=!#?FGW
+M:7*[N,JW2MB]\<\V&<W#)SFJX]EBE1H/Y$G0!!D)[RJ1[<`65U@42H&C?A2J
+M+X44J"94N>8:"I:WYK_X>MG&P\4EF";$2+Y<&3<,0%V?'0-IB*HTQ4+2Q5K'
+MU+$2P:U(MB"!)TDRY>E%.JG.D`W7_H5;FZN*3N*D")%6)F):87>D328=WM?^
+M14N]'7;F...[.EC?XZB"(<:NT,5!]H*Z)BI)G:)<OML^#K>U2'X*B;2KKE9C
+M(B=[1Q%4!.Z@)&^^"R&AZYE@1,:@7U)9Z#*TY$%>RV3=-BNI4LV_KYPOSILU
+M/+(&D8DVFRLY)U!"&UW&55S;1B-9QWJ`Q?)?<NQ..Z$B3IC^I_5+C:\ORR4#
+M%_:#V)4IO#J1D@M+ZGQEJM]R2B(Z*0BL#I`J[U68:4;&G\.7Q%%`"3QLBDI0
+ML;'CV:J/C)K1!J`#8'(-;T-3;6/4$'2:FB!]35L,-#E=#(YJ/1"S`%/D:O)4
+M(6I(Q<.'/4U"Z]B1"WZN*C&X,>$RF29PT^K)`\USZHM$`)VJ,Q*IAV*C:BA3
+MQU.R\;!Q<WSO?,D%(52=X-G!EHDK2";$MFB&Y`RWGN29VU"@,?[OW33'!3]5
+MV=?>)K:DME?\3Y\KO>:-`[*%Z;:E#0I0&8JR12%0D>Y/@#WLBSFXN!E2:&;D
+M!2S#X/(&FP4<6L-1?K\'[F2`%&F-N&%[L_/L,J/LY&1#2M+P*"+!IP/&,@93
+M1=;3A6(9[3^71D6\/@R,A*]@,-SZ.M(H;N>BR>[%Q7+@??F3L%6/7CLL@=-3
+M5BDO98*PW.AUE>NIE32NB]NX^.@M:X-0$#O:/E+[U(AO5_'_Z#%#73*!VLG_
+M(!M[`*<CS1X#_]FT*MEJQ*_?*$)JG!;!R/NN^0J_8\<"0[20DU-S5D.K]*(G
+M;$;,JG+]G,DS6(HZF$PQ7V?3,O@%J@ZE)#!?*D[SU-(=JVK8GE:.)`PJ>0N5
+M-V9'H45\\\JV\TY3*FM;_TO?6CEKY)N4RMJV9>7G'6]_#DEF^SM^OCIH9R@#
+MK>:_:'(HNWPJ>AP3EP9MJI<AU>CQ>PJ<(9^>+U9?W,F&0A"3K8;3G(ZV?2VW
+MM&L!Z6,@B\E9*1NA#D:RE,"&C$9ZB,_?G(<XMGT#(.9GQ[%'R#F)',*98!75
+MXLK%OYG`E<&7JS=P'3&L#^N(+\VL1GO>#0M]U_K"NVQ*+:OX5G?%:+8T4RLH
+M1CFY[G-=A:6[)F>3P)'@?/<\@+W=EF)/)ZLR.R\3%/NSLQEX/&=A-]RM=Q3P
+MMSG,Y`,:.D29=Y0TEY\KX0!HC>+ZJ?XS.2^3_ZZW3A[!;ZD4%)X.E0/^T5C9
+M]]TL5U3#`90Z4%1P-N!WWY^RTDNWC$T!A;VXTW)4537];#CCK$4B&5!++SX\
+M48*SN'5G-I\L(IJ_&,L1PT[9)(O@K=E$S=_[D;'<,CP$VKFPTNED9L89@5D2
+M-$5^-5CQ_>RC$Z"RT/ISP`9Y\?]U>3P;%`,@PJD/6Q+V;#\L[:[)(O:_"4>C
+M/:")P4H'1N6KQG*<5'W)04K,X:.Y(5;^G_?EBC/1+CP0>&K$SM")8`'U0R/R
+MVR*E%B[]<X)^C>5/[:?_:%BF_*67,<O/2".DE#QBBU+]A`V5%5R89$B_A3V2
+MBXX+8#("OIS)E_W?>X)+!&`BA5F[XGOLWV'5^^\O9N(%X"=`R?4[58-'W,T"
+M;C#--Z)@YYP8W$6PX6:3!=!/"\4<:"Q@!"1LCCW"*X!6831$WSGXMH'L/-RJ
+M61@E@_<LD[9R<ZMTG?878=J<NPF[VF7LW=563N_;-390VI3<8B#,E*73.NVR
+M[Z^^"\]:<\E0V?_SF36<V%2^@$O!;$U_>W@X`Q.>AQD6K((4+6-9)<7CSA"H
+M,##M0\#1[)R<O+DQ^=50^76+'QZ;'2P'Q)_1C:'D6I@+9VP&*X$[WLC<PR%&
+MB*<%.ACM%2Q/)XJ*B7B2$(G$X0SUGT<FLO4.6@>KZO+UTCL'C`D+2EX:2:9*
+M4U9F3EP#9AIEOH(ZHIW[UX0CHO_::V'0`T%YCVFW%*EVP<7Y<B(FD4MA=$QI
+M/8:TAT@JH(L@G>%9$.:3^VHQ26.ACV#<IGQ6X([[QCJB71V=?>9!#<7Z>]1!
+MA49"%5_F"YAN<MEIX!\#\`&P:`3\(W0P9`X3(;0BB?JG4*`S[X`/7[B*6Y/@
+M%CNHT5/0@1)OD7MA5C`)"7G11%WFK%Q>`D'??NUFJJ:#<UJ&3:8J%=@WKJ8#
+M@HL3"\/REW+@S=W-+TS%/WXNN@1F;7$DFYO+SV;GF<NXEP0NU?BYEGKQH%6P
+MRO[3KQZ:NLD&OA0O('_Q/W%X'E/Y,!^W.W*B-Q(4@\,'#L/.H."9!VX#%T/0
+MS<!G\7(0AP!^,!<4X;X3X:@X!--]<6=VBBE&OBT<[>\)H02;F*?=H?O/J[V.
+M#D[D4A8PNX,#$TXD;![8P$!?OSRO`3!%LX6*[TOGR[/A#^`L?CHP@<H&B`F'
+M-E[0!FI21I@2F"9_SYX[!'"&C]+\.+4<49(2GM$9R0PM(JG^&'OZ8":8I1A[
+M.HY1PU-12@8/E;?N/H;!O:^>NS>T/R0.VL59>`')L.F@P`&GD[0QN:!8HQL+
+MRBP""KSRQX-V/IY+SA?DU.H9FWPG>BW@H.QY.*D0WH"#Z&8'XNL88IG.T@R.
+M(=K7;VY@-A,-JQVD;/$<"4ZPE>]=H\Y:R*-@$W_\(-U'BT0GNH@-.D;:K+:@
+M9!P';'B1+Y$@=&@VO*\J(8<D@CX.EN=$TO3:PQG%AH$#W34YQ;\'R:98%U@8
+M@9LO?2?-#O3>IOR()?I&C*W:P-@FL`.T3;-6AZ_I-1HV]G#?D.;NL92]4/%]
+M_EK)N^`G(!/)DB*2)!5D"%VDM,>POE?_4VXKLH86)0UF<K[CTFG1K040=$SH
+MM55[13N(!'3T(U9J)DN'1?201C[QHU\,9T13/O'Q^R6?&)BU4FD[EV\@N#(\
+M,VH79L'XRJ;@\Y)B]+DJ/%><K_@?^L*1),HI,6H[=@%^@KSC_3=YM0Y@Y>V'
+M?\PG`MQ#J:KXX$;R!K<MJ&A^=AG+,."G57G:92!\/']5^$&G+TIX'V#0R0H)
+M`=@9++4',LK.E(1QCD-62A_D@&2S8(`BA[\.[E3E7?``7(7VZH'#^:JQ]5ZF
+MOB0%JO<R8),B-%8(V0)H@1[F?O.D&M*I6G(PE:U'-"(7"]PC<.)B)""<SV1(
+M'-HUF,T@61'X"=H8!QS[&`'B(2"R4\=7<#N`M[!,/%X.5%Y3DD!IF,">+OCT
+M&=0HU#*?.TXJ<);X>I[X&,QBGM8+KZ>C6X:C<PA7%)^/E8"M3<2S2(`I#O+L
+M+Z9*[FT"8C@3]S?/:4BSK`G2#_CVX*XB/L3M7QQB30RO.&W,P"R?#S`-*<#A
+M%#_PR7W)!61;TX+84!5O&FBN2N]/P$]RZ,7!<34_V0-Z!?D@M4!0-RY/G\2I
+MS`@($&[9ZY]:VY\MYC)X#3LQ+783F_L?3X=WAZ_<$PV+$R(<Z:S7U4VV0V7$
+M<A_&DC95/N&$D#Z&0C7?2S_!NE]0KQ'U$%;D',CB#(E^KL%>S9DJ;G0&[C%]
+M#C/>OO5JN&1BUI7;:"R68:BD4N+E/76+A%P+I1+8G4!(4)%`0U,K)G0#$$;/
+M(>6[2HQOV^B'I4Y&UY'+I%(([HM`GXI5FXP!!F_&&.3;)TIL>L"G:<0._L$I
+MYJM@;A%W![L,V?VHM8S2A90R6J20.D$>?\+$\LNKNB*6UE2@9H'T2S<['43-
+M9M".NZ($=#<XRTC=64[)L\0[7@G\ZV4H)Y1VSG1,XF/$`F.7-3]G%ALM2Y5S
+M^^^_-(8>O`\MWB0#'.Q4('47ST[Y^DCTYI9A!:*@IBVY'2ZMXGOMU<WQ-!;P
+M0#;GWS*<*<//UD8M$!UI,$W07K)2-7_T_@E@9VQ4D8]3&UV\J<)>5=S\&!PV
+MS1/7)A&0(F18::6SJS-\HBO2BTJ,=_=&H]V*;X,>V=8&FKO_ZBA?=76?!X'D
+M;3&Z=.K^-Y1_]NGK;20NJR3HH!"FX\Y!.)=E6/(QYD`U&(%$IU""TP&-+YMV
+MD*Q+=-DQ[8/VS)9@FD@`)B'NJ04JN\DZF$<-6:L^;H4=,6>G?K^%WFVG8;=?
+M=\>=+93\P$-KJ"`>&AO9%>W6^PI[U6WN%=CPG0:EU?S.'R*E+<LC!L[XZ:V<
+M8F%W<!Z>TZ2L3]D>R^X5=Y17DX:`.0XB?.XT&4A*BM&=9X-*52D&*^WK9]5I
+MP.-H;N=M8:%97FE_96&RABKQ?#).(F:?LP$3A;>OGQ6;GB9VG]4*T9$::62P
+MPI0-"L&]@V-UVJ04Y[ATHIB20W36">-]Z\%]#J/GR>I*^**_3[R3"Q)SK);3
+MVM,\BMI[9!C+<IW51GV$&.`"-N1E_TG>87=4T/W*<W*XY4U%'RE[&2#BBUS1
+M!Y3R4*3>A1#XP@5-7`A>N60XE?;P5[#"M#K`61O5/&S=_HY$(0OK=F#<9-RQ
+M8>.W[5HCU\+.#^B=,EP+M<#.KPRGY_G&L</1,1R.#FX6\CMA<M<*_`BV:@05
+MFFPFZ%'`I5OR@LVY)8]<U<(M>3OY>5=OV#_:WXM[^WO6R8/HOTNFD'0'09+>
+MO7-_EAT[>25+8RC/1DOQ7#:!)N;+\X-\IRWG]5ENV5U_8ZRF+`!5575OI(\1
+MWB]5>Y3/8$T\#E253+,8312=#"N0F*5,"*][A/0_X)Y.$ZN<%G5RBFRI]4M0
+MZY^<3>8*:-3;F<)LV??R)4@B`Z/P7[Z)$LLQF,%\57HC*_YGW^)Q2#*U.UEG
+M!HZ>KIP8<13!@)I7"(DQ&T@L#Z()*^SVI;*YY+3%_`A'EMP<+T$DVGNBJY,8
+M>G^O)'4XBQM@NUD3A^='61'!LQ@C25?S/3`"#[@,R__J'6."@-6`HFQV!Z6*
+M+H]%OR<78G-5)^HVI0[2[VR[N>L1AI3JB=#*B9R_=B!5`N<_/S[>$>V)-E57
+MSG^^7EVI>I0)C\&*B_&8+&2P@F1]GJ4'G:V:@>%=Q,TZ`,I#6&[6.`B^MK8#
+M0!_$W9(69@O=^M3^D&%U@DR]]2G6)\A[Q0K%<H-"T9[Y3@Q^_-EYK$#,4I-=
+MD'GX8ZT,2D/:,9TGZIA=78350*K$`2L5R;/F_]RWM`IBZ!Y.,V7%H98H3761
+M1NG8_C?C('G&:6%#=HHTL)0B/8^4*0?&?[@V2(PQ`8PQ=_$8L#E3GA)GK*#<
+M*>8*L^0ESF2*0&+2AG*4`85A\GT"^*>Z/,Q'R_Z#;VNBXGL4FDCD1%=W%]R:
+MN1*N2PD"Z4@7X:X3X1Y3[\?SA@L1C<CS-BP;D@.P,N0RLT);`@-8M\<NG;*_
+MT#M*]P3MG^Z/K\6J3RVBAI,LS&+'^<^D45_<E\S@\N'?"Q22`%.>A&[,03FR
+M1')$KE.*$N0E+$Q`!FS]HW-1!OA?_DQ3&>!_^1]^>1D`/S)D@&!'.[O;^#I$
+MC.TA##2Y/=?8V=P,:9*@%_HF/T%0:7!%OO/^M7W)7+Z0W(%.,SEU@?/V35K-
+MYNUPT.F]S#V<"5(>-:H#NQP\=H&\P4[=V1T\J(]N']'HP:2=(I2RP5^7/J*A
+MT'A(R(]!I-Y]"1P(>\=,?S&562<--7^':<O6N]0T82Y+OUK[^S[;P-\J_MMF
+M<HJY!5NSKD9F%\2?QJS<+%JJ^0T8FIR&US.,-Z*)K]]SIEF855R+A+VYJF0'
+M9=_?"OX27C@G5$S.=^<$`;C7*=,U>+I>,A?S*AK5`(_AY%B6JMZ(-'"KB-2%
+M9<WZ]HT-Q*)=L"Z*%I&DY7B1V$2\")<[1GY832E'DJE4+?"6SXPAT6$V`-[?
+M;?%+*:O]A4PVD9QR5LFP]-KN#J)G$8$")W-C;:Z:#F/@<O8E$X59.7?-Y7#V
+MDM%Y8@9G\&$$D>O%2KG5('ITZHYQ;*"_3ZYI(IE&AU/Y24)W*1'GRH"!*VF\
+MT6\SD,)R:Z#<VYQ]6"DIU74//`FY;]#BV]"-JE6<G*VO,1^O_]G0<*;BNVZN
+M,:RCK$A/$*B)?\VK;Y=]G_IFG;XM7YY-U`+C-P[:\%P\!28$?'?,]H9S`YUS
+M#;X(?(MR)D^R/$_F6&A@YTB/<LF9%8*2'^;U"(08$#:5L:I2QKI[3T1Z>T)B
+M;RHE?658$`U6.2A[%#GH[S,/<[^^CT2@_LP;#`+EW$XZ96>$=G-,J&-V]F?E
+MI83CO&+O**@>9$CEB^S_H\Q$X,'$0]R4,=,J1GU:+H$8C%1(*KY_LNIMZ6I3
+MWP5I(LPLME:&,Z+!L>J<P:VJJ,@\_IK_=]ZL/*P5?W'YE[@WJT&GP:NZ)+VJ
+MTF^BZ9:\JU7*6^!$CA;^568K8C-N53S0\2R^S-"[IX&M??6G_#'E4"#9P;LM
+M,9L"07]59(BQ\SQ1R0K\A$@NJZ)M=:$=[GNJXA5Q20<P&H4D1H9'QG9%NYI:
+M"UU=J"WU2.N8BBK@$NYEYR\2%N8V>-?L-*X8^1)&$OO"W<;BJ8Q>KASV+HG]
+MBJ]Z%CXEDIX&7GGDB_1:G6%L;<IKH^B,C!#-@_<X8Y2+@VDKE(]3AI<1S5/V
+MIR(M9ENPLDI@^05OY`"L>_'XJ*5]3?B.77D5;S8TES+\U.NW%&Q7+[]`_E!2
+M^GGBQE#-8F5R5@T\J>*O/:.M&M)WRNWWWQ+38?DJBE6\G8A]T=*%VFHF;NB^
+ME1U&09_1@8F.:*0#_E=WJ-V>0RW[JU?"ITOR4-L_<T]#DL771NHX]AXL@OE:
+MQ[5%*U-(%IA1Q_)Y.Y]/@PF]2J.`ZJA4K&9)%?ZV>_Y_DBHV.+!#"T!BTVIS
+MP)8EOS,^#R0\*SR_P#OAC(:[G.C8""C=!X*.BLN[[FGS=LB<)RV]QS"2!I*P
+MYON3#QX1;C*4?]V>V*RMAE:3!,M'KC"=)<4%\6]W4QH5-0<PM;'&8*CBB(Q\
+M1JIMS7_'&[1%[^R0FK,Q^I5P7N)#H/8TRGB662CA'2GAG08)[S"]J#<;=/.]
+MJYIXU@9MT4*\U_P//LPG4R^<(T%'<3TGT@LRN:\G)%^G)#-G^[%P7H9+`-,>
+M*4R'@LX`F\Q\XLOU-,(BQN8HHS-1S"O.OA!T]I)\4&D"#@O[E0-=,Q(0GMY+
+MJ34YS852L@9+)SSH`;%XZJ)),T(M.9,8N7WE%^L]MY=__L"MS\6`FMKN.WMU
+M\O;R:\78RI9__Y^]BV6_LW*]H-.*8Y4_:GWP+D3#.LZ.>#&"[%LN`L&P%Q=O
+M^TG;EKDO;_G0)[YTZ5O1V>?_-W3U;?F3W[B[;4?;!4W1-M?#+]YSL,WS82&Z
+M'KSOX:6OFQ_F2]'U*Y^(6?>V;84/\$\@GL[UKN_^\M\>Q,';Z,_6>'IJ(1Q9
+M?W-AQT?WF#^?6HBNORG[Z,>>UA_BSZ/KEQ1N/OKUMFWP]VUJ1GWKO_:+MEU[
+MVLZ"#\[B,0O)<.?ZQ2_^X&T+GD\+\.EYE[QZQ77FI_#^SO5SM_SI#P^TG9-(
+MT!_^M'O]]9=?$:R:S^9+\.R.0Y?_\Q^84\B7^M;/.OONJ=\V'TWC%+9WVG?F
+MS$?3,-MM!WY\8TD_"A_FX,FM?R?N'M=/XEK[UMM^^G#Q`G-,&Z;ZWVU;WO]U
+.WXO\S_\")"$UH(B!`0``
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/sample2.bz2.uu b/usr/src/boot/contrib/bzip2/sample2.bz2.uu
new file mode 100644
index 0000000000..b0610ea63c
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample2.bz2.uu
@@ -0,0 +1,1642 @@
+begin 644 sample2.bz2
+M0EIH,C%!629367PQR6$!@_U_____________________________________
+M________X3T-[WV#SN>48``!H*!H`-``'3:NO$JCVP/<L%=``>N!K+L'U2AE
+M@`!.QH[YW>@&]ZXY```0:`^@``,G'WQSWQ[NC('@`0T7L!W84*!XU@`/30*N
+M[JV[@.%Z`#H\>Z*W8>[/KW+>DO>7W.S?!J:CLQ5(AJVW.\ZI5//IW?;X/OMW
+MAWKSFQML]N[8.%BXM6SU/6TFS%+WG3TWOH^0<J^R&MK?<^`^[[PE7>``9SF^
+MWO>C8-E5;-@)@H+)@#>YWOMW=KZ\#D`4`.@38`4`!3M[>V9!6#K@EUWW>O8Z
+M:F;U<NT`761K@Z/<9`V]RAW;?``8'>P?`)][?1J[,$OM<9SNJF]:\'RTI'V5
+MN1HG8^4YY53O*^..*#[.OO;;17-W-:^[`D&TW'?=O?6K[W9W!K2@&5&@!KWW
+MM\4/ON\\];WMWL68NW1UZA!VP/MB35DV^V]\[UIU2ANWKK7VMMY]U>^5&J>S
+M#JL'J[N3AS#NT<[@[(RM[X!U\:\K70[CW&-TF/O;HQ\WW9N`Z[9)5````=V!
+MS1C6W1J^)OGJ[G="J#1>\^^C<#UC=?>WN^NVU:[X3.YZZ#T*`]4#M>]8B(AH
+MJGWO/KW61]*=T-A=.AV+5?7+.>^TP$M?&OH"@%%SOM%MWW."O6]FWROE=]N(
+M`"0``5IT5WP.WN=GUO(>*G;.M[W<WNMO=.O7=L'UV^W=Z]U62&@```!Z*H`!
+M0'0FP!TZ````=`"@HT``"@`&E````````"S7&D``CO???```````E/7W=-\C
+M`X/K4`4?:;'A[VPYX.'R/M\<Q4``*>JK)>85X````!$````1T4%``+```80C
+MH'U><KJ```6>AII"`@`(`!,FAH`"8`33`$PADR9&@#3(R::-----`T:``:``
+M*>T```&4S0&0#30`$P"8``*#4\@0(00@(!$Q,@$:--$]$RG@2>IY(-'HC3-)
+MY(\H]$9&GJ:>IZAH!H!Z@,@``T,F@``]1H:`!H``#0``:`2"2(3("`FF@(0/
+M53S:2>U3&B-/1-/2GXDFGE,GZD/*?J3U-'J>D_5/4>4/49J>D#1ILIZ0-I&3
+M1C4`T!ZFU#3TFFGJ'J&C)Y-0#/5'J>H]1IM08FC0T:"3U2D4342>TI[2IM(>
+MI^J>I^E/2/4>D:8CU#0T`TT`&TGJ9!H-`9`!H`:````!H``#U`:``T:9``:`
+M`````!$DA"`(&*8$T-)F0T`3``$:#30R384P&FH;4VA-IH&J?H---5/P&J>3
+M!H5/>ADGD3">IZ:3!-HTTI^4S1-3VA4_T)M*>:4_28F,@!JH)-1(($`FAHF$
+M$T------3!3PFFF)3>3":,4T]3T:-";13:GJGXJ?J>J>&F:-3-4],(GZ:3&I
+MM)J)[U34?DGHQ%/8(]0U3]3TGH9/1":;*GZ>E3TU/]*GY-333(Q-,'&@1`@5
+MDB3*ES)LZ?0HTJ=14U5765M=45-55UE;75E=6H$0(->A?#APWS"&_JVK-LT7
+M9QZ$Y(D&XDA+]"T@>I>G@/M3AKE!**H13./4!UB#^^MC$S1)/N7V_G%;+2^[
+M=K[K:W=38BF8P**,;JEC&3HV!1ZV$CC>=D@$8'S_U=*?`B<Y$.V\-F]O\F_F
+MMT11*Y.2>\]3ZFVMG]Q#4]_0NL@KRI7R-*M[QONOP>HR*`/YLW%D]-`U.0\/
+MKCW0@>[/H<\\E8UQGB@.,Q7=6*&0\TED]U(^#C1<$6Y*T916G0DE$/@00,S\
+MYQ%E1%;X#B@"B:J*@W16KMCBN$DX>.>13W\#%`YZ/[8F=+CMX8V!.5J%3OJ:
+M($3ZV#P(BO'`S[7T_.SSD$)2$XXBG`BVEBE=5P7^Q1$#Z!E2%2%%IMFVS&B_
+M.JH$@"+!8?O`^ZP`%41Z5S8U%Z7]OYU8N!=+7GG5O&B*JC*8&J%BL%PTGX*<
+M-*#1M,DMH*HIC5!0,/XJ4@VSXS9^<S"7L?^SNX17_X0GHD1N_']]E;;QSU*3
+M\C/FL_\VN]ZV<)(VTR==K&4<;\H@%%!UMP8$DTXR.A[OD>T+QWZK1J+25&10
+M*>J$B2MN"U;@HP;0V>NIRI&GD;FR$H7SS+&Y&1.LEDC4<CEL0Q=[(F#,D8R.
+M$A&W(H(;X.#>0F.200]2??L@VL9(Y2;D2Z=;FE&7*YSEF<XY=7=UW;L)$3*Y
+M>O.%=W"*3/-W307=N^"Y@'G:+D83D;H^';O+K=<[^%_E.KP!Z1CF3.ZY&I-(
+M`IG=<LYQ+NVY)!G<[NZ^*YY.<^K^9M6O\&IIO5[>QDN[M=UVYNW=TDN[HMW;
+ML&.:[#&P*69<N-+,W+K0T!MC:Z[HK7,DE=&8LE&N;:Z'9NS5$V6C14;G8%"F
+M-%-LVV38HHYTM)#9(2YSNN:Y7*+E<***33(U]Y5ENEYW'(N5.7)SI8USN=27
+MZ(WB\7*Z&+$"4A&=NG=O_ES)CQ=W',01HI)=VYB(.[N;D[B.E%(+NNE7#HXZ
+MSNC,T;)<JG=&Q):<NRFYP^JUYYU^27C>`(@"-O2Z">0*1C*9*::2**-(4/_E
+M_TXOXV_?<QH4A%NZZ.ZZ?CYQ@A,/.WS?+U>7[Z]KP!UW4F_B&[^[_T?/&3>V
+MY;<N'+<B<ZSN(W-!H^AWEUOF>,1$,HO.Z,<NF[OT#SH_UWW7Z[ZKQ3/@X;$9
+MG+<CH[NZ['.ZBF*GX]4JH750%B[+JXZ_1U+3:T(2]N2C1R[NW*C7=T[K<VZ7
+M9I+EN.Z=UN;I&)'U.N\[7VJ\>=?-Y=2,A#SM7*Y73)DT0YNP9-SH@D[M%V3G
+M/'(09>+J9G+DF(5W=E)=W+NX29$4*,<NS"1$&-@V2(@QA)'YDA`2#?GRHO.[
+ME&,0([M=DI).7(G=N821$C&,-%AD3/F[;L4"3SN\[DR"]=PF11DAE>ER1LYQ
+M(7=T85$(RQ3[9U%*&)FKQ<MW;LRI@A(7=T26M-FBD5S=!.!W=[47@\[D7=V%
+M&^.=><=SJ*8SG*=VZ[J=V(EMM.7"^;NH7CD@J:^_[L>=O\+SME4LH&;X]CAH
+MWKNW?8\O`%\%R+U\W7+SF-^@):L6_AZ8P?O_P*S<<0-?NU0C^<T954B)579"
+M@DY=S@NZ\_*^>KU,A^Z=7-]9V]=WS]U/.T[B)SN="8DS1)G.CNN8)?.N9S>-
+MX>=]%YR!&`DO2XGQ\Z\9&D31]'<B\ZXCNW`TRN[FUJ*TFVLV;4EBQ6YK6XHF
+MBQL4FC%$)1$S)4B)MI)"YU#:=*Y*Q2EM2);G*R4FC;1IFDJ3<UN8M3+9ELLK
+MES;&U)DUDTEC5--1K8HW.?*=9*^/<*``?)K@++VN[MZ\W/.N8(QW=>.>*X;F
+MYC[33<J*OK*Y!=ZXKS.[IW6MC25V`1_T_B?//2W31<Y:5[%L1!"1ZQB`&.MF
+M>AYZ\*9`!^J/EF#<\8\P#<,_ZUI,PA6G?^_<WU_73:2^A79N;<U]7KBBP>^X
+MP7I%<-BWGUM__>5Z1KTU24TJ*O835M%!Y:U8?`Q^IG@_L-)_*2:??J.9_S/Y
+M7A+.>C[H%^<I/)F(OCEQ"`4C**!P*"-\*$)!>NF'E2LZ*2"BPR=#TYPEF>5&
+M:6@E2"0^U4?SKF?":F2O"`H(",E\"AASQA&X]3YSO_R7L,[+D<%R2YM+R,;Y
+MLK"L/'(%8O)]]<P)%#S;>>FB!SA#S%@L<0&0$)&4)&0(JO\B8G,\,LL^D;/N
+MGF5\M43[+++LFKCH0M]P-47[_Q?98G%-$7"@DMJ4<7Z;]VLN$UY,\"(@4D1T
+M\GV>)N_[AR_$9,]ROBX6R@WRBTA;D]6H*:M'FX"LB0TRL$%VV.JJM.O,\1EY
+MF!F_=[JVQ\AO^TWIPRVW[G26?T]8_-)H?T5#%SOF+6I6>-N;[A`%O%+OX>$S
+M[VZ:1$'GB6B`W3Y?.^NY/@/3(N8W'G_^#SB*(?.747IG4ROM@""DA?>J"+:S
+M0^M;H$1"<?0M?)Q9)VNX\S_#,!#VW30ID1DSH)ZQ9[]Z(X3/+NK53/[]:,KS
+ML2TO&(@8X@+D6^,T-+`4)&@+:(U"=:TIQ>KU]^,Q4'VO0U7U?9\O<&*9L?\(
+M'G($]LA!\Y`#R#M\MHVIHYB/",%6FYK5[]E?\J7=C=5[H_R4$<E4*:10!J]4
+MN(/@D(/X@X.R]R_RQE&LS/6.:UQ"\!4.=A\8]IW<N1>L.B([Y!/J;)2*#>O-
+M?X?4]CF*C62.0DH!%-A_A=R]V4&5B&\:*LIG<Q"9HE&(V9"1I$FDX#/J'UI;
+M[4V>57+XCHAB!(`_>Z'#^7(WW>6[!L_.K]$-$(0"3!NH02Q4S(,1,Q^UWKEO
+M`UE)Q109Z)$5O4IDD4G`FM8G-_=]T+SOC]/2X?K/@'A`(C\NV,076YG`-G4/
+M-H\'GM?94N__>/LLK1];O>%V=0!`:B:N/;4TOLK%#JA?.#T(@(4-'`YBY_/N
+M=;PH`YK%R)'T:OGO\;RD.HLKI59FI7W#==:*J1K+>">&UV2^/)@``.TA>DK)
+MP^0W[\G3,J_YFZ<)<(@H0:SP\7V=11'=4.TAKS("!,F0GFSFQ5M'PP&]A61N
+MQ[ALV>F;+"XWZH?)\UX80!`("`.5D?\RHY=DON88"E2$1PB:U9YIUP:98?].
+MG<S`UZLS36I0:;=OOOR/_C[#/9K[Z?IP1$%$:2*3&*8C)+)_7?[GBZF\\Y=>
+M>-TOX9P\[7K0:$$TE5[_/]OB-O)CHY2N&53N5DYX$9E54QH5E4TP4[XV@Q1_
+MOX0`(@`1>'\ME2S$?O(]OH.I@3%'_!*3VY^[<S^3[PJ$I,>/]H6K+P7Z1MO&
+MMO_?^UZ7GV$D32$,:"4:W/\.YI%Z2U9"8*&^1TX6E@00'.*T?L[&;YG\KEK2
+M"Y;;,LQGLR,C-"N5``OD*EJPM%!6M3Q%1%#%RWO>'EN$\W;[&3[?>_[D9;AO
+M^80D("9@[HM<%^*!<BW4@/#FJA0TWE7T`+!]/-P->\3:_57?P8^*OW:56<AO
+M_D6N49,%^TLE;?+\_[;3.?IY7U:6%CE)Z;+&#MH6,'[^O3L%!:T+(.S7@5`3
+ML)KW>^_]LO['1X9$1`9AE`S\TB`>@`P`)#0D4($7V%.3%BF\T;GH7Z/B:>D@
+M^\ZK%]JKENTOFYVP0,[/AHA"HYB\#ZP8'4:V"!HFGX^NS>RZUP@`"88A_)]-
+M.E;;%:S9X40\/M7VCMS1"(!BFXZ'((@`$V@_5"C6X%&@,>`GL83Q+_IEX!KA
+MH>5RW??CXWD7/0K=NEYS]&.QH@NV9XTS^7H)00&29:($N8;I$,FI]7BX-M\_
+M;>BV=[_@_&&MDJ)2)/4,!_L>P$ZSH.?V-S@AVO7'<M-7[_+S8$/AB\7ODWG`
+M[24C,.WN_:;FM(HQW_N)O=G^N*?'%=3J^>J^MH`3X"<`J7_TB78MI1`%`K/_
+M70!W_T7_LUZW(_;J.G]=Z`7+GE[NARHGA!P8YG!TMYJ>G&^U`JY2^/TI(\D)
+M/1)O,-[YSQ>7KTBW'.;1CR)!!KJ$7KZT>,4,U1E>1R.)#1I"@&=YYH1^XW:?
+M57*JUE)K)C>21KEJ&/EE%M0W0.?C8\1G@RYFQ3Y@5:@$H6Q%-&[$"DC$4`J"
+M":Z`^OSO.[;[;[A>0Y?Z+Q_'%VN[9J<?UP,^IHU-8`UX)W3=S+\[Q'XM%VU7
+MF^[RVZXB_\YUGP>=3O92@/^T?(ZFC=P_F8.V,#5]S@;C&Q=3=V_%GI*[_XVY
+M2.PNV"04;_NHX.\`41O/R+,J`I$8%^^,)K6[GU59VH;U$I$Y#C6O2>:%R(EL
+MLGM`;DT*WXCJL.O\.&P1*^<)`N>ZO?;[IPLD7KYX\,(<Q[N[9K`L=N[0TE@4
+M>W>VL>W+L8;;Y?E3CK*S;*7AJ']+M%K5H?M/XOX&R/VG(7V;@2QSN5Y,)N`"
+M"02:T8'[TWRYSZ@,$J?)%YB%DSX+D+H0"![<HB100]**T;648_@V7+1$:K8U
+M#)AL9<F2D5):%TE6U"C_QHL/S_6W\S@^$)]N?"J3^[^[WG7?E7KU:"/GT/^Q
+MM$R&@Y9Z$\[.ME=O[%;SQBC!XIIHQ%B[13:)61F::+J:&#&@9Z%3*H_0M6D%
+M@H(K)[?_9B6!@H_O_"7\D^V,?)3I>438I[)*'^H">$76^RA,TLL88X3VFO-[
+MI!X#GQ=@6-4GZIDOJW]]3+(048>9?2GLPT^639\;[DJ_9G:W^/-TX#!LHBGF
+M$+6Q%O%J&AM&UM7[)S[!A`>$LPY&1$50F>[*:XW,/4.4#>HZ2-A`(1YQ*2$%
+MTKD=JK-\I5<.[,E/*Z11.'_>^9XDD+5&O*.Q-^L;M=W.OF90WTHJK0.S9XUX
+MSHZR'?NJ]D[+4&$"XJ0*(O&9\X7)NOKOG^1#RIS>4/OYJL?KEA?0O0&2UFA+
+M`I&2!"OWL/^:6J[I&0<I)?#2(+5T+7!7+&W>3&Y`F7R["-S42=[OE_,UD@?"
+M_VUV4**2@R8F/+-#'Q(`;=2%EVY#$NHWKNV.2X(Z;49Y@A>+ZK)M[#KJSU8]
+MRYO@O*>%$6*`RE0@1CZ/5QN]Z80BYD1>-5L;9.D!ZR>S&Z7-@%6^+O/4-1(+
+M*S8^'3`R4>1->1TO`J+F8+A9,+62+HMTC6F(G@_-NCT;^;>`:CZA0";00WK,
+MM>)2_WG(0US7'[5=<\C&%M;&5;^%Z_7\??VG+5>E1S'G$T77IC9=YD:!PF0J
+M(XXV89)X<2)E.-*\I`"`GV(2*Z&A]7/T_3L>?8#7?*&2!&L]J[$U$GD"`X`D
+M".ZP0U268!$(P\H4+W(ER8'63I8J@QI?0A7"]ZL3U,)5Y2C)*JJT6!X3;9]M
+ME$&*ZU#4AG`:Z=45;U7(G4[6.LF!T@)SV/;3\?7_<<>Y_?C%=?>'GY9^`5[E
+M.?8M^57BD@SY@SN(+$"#%.FPR)]QQ.$1!A94NIC\NA+E2IU2M.A&9[U"?+=*
+M,="YULT,=<I?Z5SW+/S>VF21,G,NLJE7T73)<B,LHN8R)*J[]VN$-@5K\T!A
+MQ6D'RWZ[N=CS>XW7\_CZ?EN[\K850%#%B>!B]XH@*!BMCP\&(YBRF54E$DB0
+M+@@$%!72KTG'X[VI<"[3VL[UVFP8NFC\#BWKQ2%`417!4W.E.(#4OOM`@2'(
+M:W<X?T6^O\/[Q;%G<8CEN=0/)<S"0C4*)0@]E\;M['61?'$?.PZV#K/4TG[_
+M,=OR5QJH%V^5R8>+BIL_;*/4UX0AUY4[EE`\F1>"A]F]MWHQ/*=`QC&ZMC(3
+M"QC0WY/5PB1NW.?ZPU)+<L?Z5_Z$QU(XUQG^J,%JK<#;]VS<Q)_KU?E1CC]J
+M')MB%U_?F6#VRW`N^;<]JES/2R4T,T!$/Y!_T'[V&XWD._G^(W?RL[N;^.7>
+M:G\>''51X=N_4.,],PY+/MC$GOW>\Y_IT[1Z*_?X51MUS?A[WYX#T6][2QS.
+MZ[UXD9UF2#&:O6W6.F#G4D+5?R,/.Q,UIZI?PS`E#++=1A[Y1-2[\O'/)R9$
+M1@PX1.)PP>F=\L":+3ZJ'6),TH993>E5=X<OK].'^&E[G9N8*?!*6<T7X<*6
+M9:BT14=0P?"EE>G]3F/\!BH':%/.A/&L7O'%1(BLWO'%ZM=^&SSJNC&LEF\%
+MC8[!/&M\<1."KYJN?SX%1V:S#UQAXB60S+Y/:IATE)-4&4`5+L9EI*Y8?!_=
+MC&K@YEBE<*5K2J]]WD^]FNHN-7R<"[*9`48U#PAW0JHE,F=W9F+R+]IA_'/C
+MO7HV7U.=0^L][VWBIP'."B0CSS#]T=XMP1?Y[U>=Z=*F]9ZI"NVFH9*&%V:F
+M?H<@?O;=O-Q^V,5A,R#9U$;2D;ID'W41?N?-[@SXU61-AK,.KVB`RCOR^Z$X
+M-]<4XP7GTB-2)C[SP1B4P*J>7M#8T9R-C")40&`DN1]@97]96VZ`2D`F*,^R
+M&!(9--!0>8T(7GO^\$\C@\YC`#/JX33E7.RO)>(ZMO>>UWN;N8XQ=NS9KPJM
+M#(Y9.4F=O5:058'1-B`,VYO]GC#F"W9#(O]Q8<_/D+7C[OPW&QK/[:&G3MS)
+MW=^T(V)^]S2VC;PO7D"P^WO[O4Z`%&WYOO9NPG^Y3ET.P\.G!21HN/5"#XFO
+M>]%P\,/)?41Z.<6MA%B0IKA2M2!3AHAZF8?A6-Z&+KI-07W@JDW."C0>H*:&
+MF"_)Z>V;?6;Q[>[&(Q&?IC'V)#FS(<AR7HZ:#G*`RWUW?\3X:^4Q+2%C/ON]
+M:CZGQ"NR.;L&72#*?+K<LY31$A!JGT2U[M9Q!"/W`?G?E_W/\[_,%@+./[<V
+MW`DG':H=G$S7FNT<3N#D#E>$`\TAO^XRJX5[<C[;%-;6/\E]*WPHDDPPB:6C
+M&E13`B4O+=RA#)8@W3B&@IPP*,U_.$X82;,.6S`L/,W]WW?X\-+:BZG"1BX#
+MUW0XE@^VC?\V?O3B9OX`[0+9)U]MQ_:^@_NGF+39$0L.%<?PSW&?I:>2<T)J
+M@+#EUYYM^5,+M)#=Y>7!]%E1O*\I@9P5V-N0"#[7XL]O]%_P.^(ROY_S#LNP
+MC.42?Q\E^T+77B^<\?N@?"CK\S=]]?X_MQ(>4V"D.XR/I[17048Q8P,>+X99
+M(]]_IUU!"M65;7[U7+Q;T5*PY\/9)@RGN<CS%9CQH&S'J7,(=6(CIVBGLX>U
+M-G0)()))(<VV+A!]B[?#.?47[>PQCM%MB5W[T*'?M8>?%X<]`-D'-Y];MA,V
+M_/H,[UL`VW#@^'C47$^NJM@6'<JV`MC&)>.UY[JFMW+BR"!"S3S'7A"TX];6
+MS8%2/'<G->(MOS?]BS\\4TWMVMX5:NRZZ`+OZ8[EDF"`3'H*="@9!;>QBJS\
+MKLFNLA@AUZ_3\E9S#7CJP,.$*`80HAENZ0AO])ZN120O=^NU+^KGN8.\\3>=
+M:8F_U<4RWC49,II-BF1J*9;7R^GX4S<X$0X#F,Q=_C!M0;$\8>-/&8GFHXQQ
+M1D&^6_@XP]V.(="07!%,3)5A90+6JQ$*<5!H@$$`3%!"\W4,9M_9W9Z5&8)`
+ML&:Q$(-:GEX):`6MAU-C,96?C4&JDAP4K6`<5:(9R4"2PL(?<QC7,<R-JNS3
+MY/9^WWGSZG,GJ-WS-(`"\?V_\.CNHPU3UFWN,1OZ+_ZZ/8U.S=V'0_!B\6E(
+M!KVCAW,/2\1!BW7>M6\&ZW%TNUQ=K@J]GM_%[_?._W'@?O]?NV\75E?*]7L2
+M3F(^$57I=Y9V]&_?0\9CF/XLB)77-VYND?/\3$]>-=KY83>\6;GX645`0,@U
+MMD0W;)3O=OX^M0^--D7'$KNXB=M>D<`>YU87XK6KC6T*'KQ#2<T[9ODCJ+^Q
+M1=R(/4<;Y5?P<5^3&<1TY&_<T<>[M>.>W345RFGLX?QQS:'SXK$B(=Z0?E.P
+M^0^,ONN6N.#S\AU??;-8G,_L;^Y_X'\8>.V8Q\OS[\=_HZU\8TW7?BF'%JGF
+M$^%4S$&0S_JWS*_P:R/E2],=3HCLNFW]+X+.VI&>O::!'1^#<M)M'YT-KE!?
+MN%W?W3V=>&EO75ZW/)]/O:88UC*=]:'*^Z_I%S<_+.#CZXD=;;L:.C+-#CEN
+M=0U^-^BZ;.G88^EHM[<VDL=(?>;1Q=9O3\9/4O'5^EUR\$3BM,_'`-ZQ,2AG
+MZ\:VA)G+LYSB@\U$<1]#*V/FNL#0OJ[3&F=Q"Q=@Y%.0U,[-+=-?;8J8HGI\
+M^[-/OU'R=Z$<+6=J>Q]L=NW9C>4RM?*2=MP.34<9QQBY;B&[G?96*VVCK$\7
+M>^*W>R]-14:E[RVNG^9AJO.KBN)NZ\[P^JRR[ZX%#;R^/7`K?N58&4L7ASC$
+MC*TT]$=<%%\:?DZSIE?&'&2'?/EGA.F@LX-^DF](#R._51P9'@ZY7/:0_VU+
+M[*//2S'G&Z\'E[RRXH(>E(E\-MIPS/-]3_!E=]YQTOFWC?))0PKETEY4F_37
+M-E9H@\9@J;/'26U+ZE$0#(%$:0@03(JTAX1V>Y/B;)?LI\^@^(V/"_--V)XH
+MCD\J`,)X;SL;C#R@`]+=7:F\_-#-Y#7<;NWQ7NSY/,OV\OB!P^(X5LPBD%K5
+M8S;HN;3AB!>.BV1SNF(N`[XAIQ:;3Z7#%B[7IX*VIT!NW%T1I"**)1))^3A&
+MI9CKNOZ@:18-;7WR72,^=/0<%;UU`INV7JH4CZ`4\2UP,B$#=`UYY\;V(!;8
+MO-L%'D;AF[@#F`0.(('&SBS?J]T3"@-9??.2+.%C=5T].XUAB-7Y`;;@0++&
+M0&_B0X#.RA>X/#<UC&=3:GB,FU\@F=15GB;-Y&I+F9R^0#_?IFAI)#?)ZEY^
+M!W&<;)N.5@Z9]9EJ_4.6:YXY1PK*4I@ZLO/P0;I7]T.=U%2@QU8IN>"8`1=;
+M);FC0IN8<GA?G!U7`VL"`FSL['*\[^%8B`5IL3:6D?8;=P2H0)>5"*[%F)HH
+M71M2CB)$BS@+P0<"^'X4`LB--:($OX$A#Q`J@+(8O%R@'S!#/)!F]+,$D.1]
+MPHB:%>Q3M-A@@&"<VA$=(_0AFT7IU**_"&K#@'@0B$5,(I48Y*8D/T!4U-4)
+M@ED"<)\0G22Y%B&,Q#:9YNU<F?T`9W#5\`\[#B->YTN?'FO3K5SS,CSK+V^0
+M*O?.B7B?[OAGU#;FTDR2H)W<J6O,7TB%)(`J<:J"QJ5O^'_J-<0<AIWX]Z51
+M;B<^L->S1%]Z*>@ID5-5B`,-W_=\)_?&(!U/(OU><FH@E%$9,'XT\,_B,1`B
+M8<!+14$:$UBA1N5U&':VI+)C;M)LBLB\XJ$"(HQ`)%O*9@HGT`9*$&$E*`@O
+M>&#-[,8>:&/$3P-BM^?*$IB5>DR0#A&/V[@)01XC$8BAB9<2)1EV^$:DH5MZ
+M9-,12&6LN8),-F(F2.*#MYWI$$VE!-25>E"`=)AK4OX[K;-V^N12&+=F*:M5
+M3V,#"QI1B^IS:M(,,++OA<5-O!0=_7"'-]]4U^Y^C#P80`#M@-YCPE"1FH*,
+MD>&_]_/^?1M/\SGX=GA?2Q','PIGQ=5>KSA*:'(5E2U!01!;J*VP;@V/X/&,
+M+\+!B[S<W6(``$M8W4'=F^S0\[A>\GNC1)6#440I81)*7QP#G*#'F^XIMH\?
+MO<'AZ=(BE#R?:^-^?R>ZX;(HG_W:Z/1=(+)!;U%.4E:0,G;J@]#W\;0V0R^P
+M8I&O5<8$2W6ZWWG)6PN8OTV[$<M14`5.O5CZ@*4*E*F\.<(6U;-]NZBZ6T$.
+M0UWI=7YE0GX9#BNHJZT2*%SG),`IK<F552_<VQ#?JR%ED:JARR\31P]M]$`@
+M&CW>%II2I0I$9[9XNDYP>4OJM4U(67%-MH155:C7=7-Z*RPS/Q\A?IJJ%XI+
+M)$T4E#)K>1MDIR#:6C`P2>%R^'<GJI[A?\&XEV,RA:3Z^C-_N1HM:OT1B[,B
+MZ-[91>)9TOVP'T4,/)M&2I@1*!9NS%JO_<-9SM3:`87>N6N=OC98Q#+7*XO(
+M!9UM1U<^WAY5EXCQC![P<!SR,KMG8_S6_)Q]QQ-YX#MN3[+X%QDD<U=[B=6Y
+M`AEY,_#W)=T8L>T+`20]VUD/V[/_M?F;*:^&]3:(O&)X$0#'QRS!]#Y<,[!!
+M;U,B2UP"B6!?G![IKUAZ2.*!QI[Q\V!JZ=>B670O[^I%.[BH'RXH@/NO@T*H
+MZ6?0B3ON*QW(JO"=G2@/<Q10,414`T>:UVIZRM?N:TION5O$J-G2:JGB"T?*
+M7AQ`20+/7*A0(4YK@P_KMU\Z?R?->#]8N]1R+!W'J]']U4@050!`J+>'H-RK
+MF[EV&>\F`=<7X8"Z"N"O!LD^`Q\R&@VMQN`_XU^LIIYXAQ)_FSGI5`HX29*Y
+M#.7#MU,DUJZY?M-'&5%M<=G>%;7[5"\`K6'MR,I\*"/^5N_0?.[S]2!_)NC.
+M&HBS'@.&=V2[X/\]`1_A1OVL/8)!6`SEZQZDX>+^G_<]Q))`.W@/R%41!$&,
+MLAL23("*$L$L9HH9BA-%$2R)-!A2`HDT@V$6("`A(0$@\?I6W9N\_)WN[9+2
+MSL3==MO%M_%_F<-]*I?8EG&]$*-=H\1:TUPXM!NWO:3M*<GC#AY<O'U9=Q[N
+M6#!H6!8^T^+N*'JWH<B./"/(@T@=,DA2F7P.;[$M_/H.8^7L_X\GH>*WG,3C
+MVX360[2,#5'@'A]PL*8T.$48AHP;)%$L/N&JR8(T3]UK0?N=%WWRJCK3S[DL
+M&Q9MOPPW\^M_6-?*NAK#CK=8XRT*O5X<JEC9MP+H?8?XAV(#M8OQ1#3.K<"-
+MU\=A8RZJ?XD]VSJZ>[/-^V\K\/Y?P-#YF`<$]RG#(]=8&;1E9^MTQG3_QXWV
+M!.'F?E+^7PZ/*,]:G5U%U(0$`H`$81D&$4)$.BRKYLO-HM6Y.O_%N@_[ZOV_
+MJ.K\-[3*]S#XF5W4;_HL%PHX0;L17N=HR'C1$@GW[Z-U`!O8X'+V8['3PX"-
+M3H%9Z*-C][RL%S/\^?N.0ZW]=-L<;,$L2^\]3_:NII7Y^#1#I$3>+^-X48M5
+M"A55(:GD'.#E`RRY@AAC5P9YOQ[N'!P<KY15W4"'9.#P:D1D/CP^?N4*52TB
+MK>)J?.LNPP"-SWN1I<]N'Q-9JXJA1J@K4OK?T;_>Y&<<PI0:H4$=N9#$DH7/
+MC?P0="T`,*(U7V(.UCQ(PE0X-WR3^5B_884>[*PF)ZO"YRL]&$7CQ5/@6D6+
+MYR1L,[#">:!Z*)N_ZYPN5F32)LP2BV"L#@;*W_^8G[>DJ7M>08DHZBU[V0R2
+M9.2NWY]/H_XJ(C:J(P!21,QO![U0I"@HH*`E"5=Q=?4WBPYS6RA`"$ZF53O^
+M?%I>"7]=^UA6"'<QCM7]3WT!Y9L8_LC=V8;XE3@GERFKYF^_S5O?;@EXS`>)
+M_$[NWORSJUO5>)V0?@>/,%K24-J"@6D46[$/O+@`X!0@KM9QKP;[_"?D_/'W
+MWYO^$X,J9K^':9JW-$:B#;ENN<[M<C3-%S7-&P4FC4%7-<JYJNE%HT45C9-W
+M=;'9P3%N[M8T4FJ*(J3%8HVQBC:YRBL41MG=R#260`DQ$;G2+EM<VDM,V+1@
+MQ6-H-0FC6*-J+:-%&BYL%<R`F9C&W*U<H-8VC4RHU,HUL42:-E+&B2I),8R6
+M(W.9*C1U:7=NK?#\G\RE%6UIA,8@'$7N]P"AN?\WIY[SJ=1!^_S+I-^JD84\
+MN#,"LPEYM'5*<)VO81BA009"#JZ_A&)7:&WU-+/^7PW-U?;/3AQ.>\[Z\#;^
+M=`P_'/&3'$#!6-[:+S>PU:TXKE-!^NG"CS(K(FY9L,B\FY[P_7`N8`MX)0PA
+M%5&`@,`X&ZM0,`7J5;&H_Q_@8KD+\@S^;V_P[I&!-C$T,0<<A:4*),4.*(6.
+M"H4L12>\BL]4/QKXO_.Q].QDR/.-64221CN/E(JHK^\;B\9^?1M!`RTD57<+
+M]G+\!?FAY>)[NZ_@\DKRUJ<;:%31%VV`DT!:(*60`J,H)(!*5RJ%!KWD"FX$
+M7HS,-W,UA[>E$`TA!#5@\YG<';`"XF4(5%N6*H(**H"D^3F'>S[GE^A=/E'T
+M_CT6(*?/2@60108`:].D6&AZ;$UB\>?>A0B7YOXD^[W.CO'IUZ-9^?VAL[&1
+M.$:)*#%01$!$]3GL'SC[4'@*+*UNPVN78VS[^8)57%=VH&M**!WMMD&/V_Q.
+MS[$\XBHMP)O+?EL8P$E@`D%!F>QI082S>HZB@048&1!B%-ER_^L0/`>YDORI
+M8I)E.ZCJ]_N#,1N`>8EVHOEYQ$%PUI]N"D9Q?(BV]UZNI1$>V?W[*GT513\;
+MV/W9?-/WK>RJ^#P=_P(R[_M15M;6C4>>S4WB>*@_=49IFJ%^NRA`O9W77Z47
+M%&L6X[4MV+DK*(`J20H*D/+4DX_3!S?Q_[X><1->0$B>J*KIN(5AVQW;V6HS
+M_.)7JV]KR'<=+ELGP'PQ0CR2MWKA64LF"48"4(()10J,(`4&E-LEAY=7Z'UN
+M]->LUXV@M+W'ZEP])FM98[OQ+_R^)GHR8-R5+0*4NBBRC<?1$J%"!A5`T(XA
+M92[YA?IS7-[*XX*KF`"[R,/T%6/;GY_SV_+-X+N,?/];M=XV.@Z;W]QH[JFM
+ME?9^?+;+P.]XCKZE(SU=BI('9_+ST%B]RW8,'2&W_\"+EFK#5[W=WNXU"BOU
+M'5Q@AM]D9G3*HSR!0TD9UO*)/Q!(>'5_?_,?9>A6[?Y_"O'85N/'`X[^?GNU
+MW(WV4D--2$]7`JFD>6Y97+&9NS"J`\/PWB3W7F)YOPKGF*_051%8HB@B+KGA
+M/F,4_4:V.Q&E`9FA:>+0`P@&0BR;?1`(C``,8$G`02N:W3UJWHBEGE3UC+4L
+M*(16,%Z:`!HC\%!0_:X2H[JS>NR?=?K*J#0Z@!PU3U6RK_CX*#BO96,;J]#`
+M@<GM^C4-W36"\Z[,7JD*".IR&#WO2[7F^M`[G#\%]?I_]PP&+>E_YWW*_M66
+M0!VY5*@WW5+O\#W$[WRV]/Y?FI^E^YUU0-1""4&7)3!2B'MY"CXV_^0]7R^1
+MJSMZE`7C\AL"T5!(#R!2\D2A&EI0@DD%)G[8#E?9Y6^>]T-M^^AWCV_9V&`Z
+MRY?=MNX]RT[^Z`7.Y]#I-C873[,-#>SRG?S.;>^[GW^NXS5VT/=>Q[FC]_PU
+MM_DPDH#S>)>8*OS<S?:ZNR/O]9NV0X)(<]Y%_<XSZ_F,_UH&R>/^KQ\H3]OL
+M80P0H$6RU#4&C@X&C@M5^LJ#)\LR$5LZ+0`?6YH.Q7)OON55$\#I<+NN0N4B
+MQX:_XVXS_E?#+XM'Q0&23-R,)]L%WO.F(JL`B.`K_K0`5'6<NA4$$`DD'`?N
+M6M1H^GXM]<`+I+@K&CMKRW,ESA<:&J"*(B@<4:T"%U$+"6]8M^`=GP?N-IY7
+MC>-Q<3?L,[^%BCN?REN#OHP1':_11`-WADB?`O*%`X*`@.$$6\B"#NM>^LJ5
+M_QSNN+C7WZ^QNG)T"!VL4?@1"[L-0/7104520QX/9H`)N9`33\#U..\PQZKE
+M\U]?LS75%2:LLB\_Y^OQY?BYH^OZ3E,9?C5`\[`$]+%^]%"`48EWXH*90(EX
+MJL($%M=+94S/E(1XNR>O)+P\P^5QLJ-KXZ,*T)FRB8U(B$4%$T-(/"#)=X_4
+M8=$_"X:!1/@GX/RNMXEIE+;J/)QV$RGOS[Y+X24)0K`VY^C@P$F19)B#EB$1
+M"42(H`*E?OOV@OT)FO&\,',\[[G_.JP<0NI$`^H][4$WTAW`@?"G?5MZO1/C
+M*`N\Q1#?<T`]>Z&AO?'[E73[CP-Q=>C=L=_L<1L(W\K84QI_19O7\ZG*>^[@
+M84$Z_J@_J]ZG':>MYB,7L7(72J%VU*!`&^LAN,1^!RE+L]6+:F@`$.7093E>
+M,4#&&/"-%E<MYP^+R&ME2PPC?N;N=YRUC9$%I]=?^,>_^3@^*WN&2G\6\&"B
+MZ=^M1P;CM!=J>2KT1F(\C(R_CZ"$1MXS8#@?'[1_%\R_^W;.`B.R];@V-J:]
+M"4G]CY#>*MGAK?&=89`=%@)N!<+N?8\;A<%'HB$VB*`JJ2"4*`!"4(!!0G1E
+M)0#!TEXG2>+CVVSI)_.HRTS^;"PO9.F[G<KU:Y,O7.$1\WAN<XO3?AP\?T0Z
+M^R&3_WM;KWCZ?FRT!&?]#[=%(D@PA+FH9P@%X8&J5`:P*.1**LA_*`#+LX.1
+M@)C>`[AE\TW!\1U&ZO0H=5J,)ZW`/4>!S-0)C75<F[^C,NO(O_S<:#0TG#,8
+M'S]IU_`\Q@;>L]^ZS=/W8JP0I'#3*-MV!`:82&8,=N1[^YW_[H?E6_A_I;X$
+M?`%\E%%4`A200I(&(^#>8?]K*#,Q"OP/XO%8Y:'$LN@[?4L8]T)QH`4(VP47
+MNE,8@*J(M4(GQ$[.ZI`450Z&%L,QQ27[W;[N5>V(0&$'CH@8XIF1%[#QW9V!
+M!GS`4L8!+!8B(.1*(*_I=RNV/;Y!_?7VD(&<YWV>.]BQO.FTG;:[WY(!Z;+8
+M#E.NU^!\N9UM3Z\D=V4R77XKMK#H/3[[']=/_G,8/\L9U']_#S&5Y'K;W]_4
+M1=SQ6]YG!:+3]=T?H7K]-+E=9_&(S^8E?%=[6W]C]>\PW=<_?[3#\!I_E[78
+MSO4^OT>>^S%4R23DE4X@KC.=4=FT*"(2H,A0BS*CABQ-$Y2;/7*.:^17=80J
+M2EY'EVLY@W4HPE#S/CVS-3DLH^T;V%\O-_![^/\3>O"[#^_<[?\/T_;@?$PO
+M)^+2V>LSOZ?3PN&ZGG.D\#`<3DMM\>XM0)R'F/N7/:)W<%+(N(*$&RO6)]OU
+M5>O-?I\9]&X3OYVD$/W1?#0?90`]%Z^A<7<CIQ2PW/-*`B*40D!`E]*42DVZ
+M=`.@V`NQ2++3;MY$CB]SY&]_/\737OMNG\[79F[P]_.VR:WWCKM0U]T1*N]5
+M264[Z/GMI2FXCNLQ\":_9_0X?#4A\Q[VC^W50^?^C54?]G90L+*N[;$+!B)&
+MI6V2D*S_L_;?L?;X<[^%LLS#^1+@+\'1]4T:_$-:7GDH*%)3C),XM3+\GE<_
+M<O?Y'89'S[MTU,#$RD:"!+ZHU*/7#X'FM-M;`Y23V$-B%1?T5F!#4C&]OM"J
+M\\L`43NPD7WR[K6YC0XEHBN8>)((MP0MT"A2QC*+4)%=`)091*`Y\[;/I],2
+M7FTBMHI0FTV4H#0/&HT&\#9R7ZSS&Q5_*_,_(IH^>^XVBOR4!\;>07ENTT;;
+M.N5MBNTI)+7!+BRV+%HT<QVWU/)>I[`"7*+&\WOV1N8Q5OMV=$*G#\-QL4C.
+M2\7`/GMHNBXX5U$?4771`I`COV"\_D_SV5;ONWJZWM%6J4==^P\&GIOJ@U4>
+MWBN7<U/0;[Q<.MU/\"S2#@C[VQU'67+78A_,\;W74?!\^]8?>\I\OXX#^L_G
+M?*M*)MA^NBQN]MY#D?,]SKO#M17\AZVR9QGPO,Y?0(,>"#P"\-EFJ@1B[%B9
+M@@#HSH'[Y]#&@=8<+X_O>@T6\J7@D^96V9#@Q1K+TV:X;+L=IX]/8^SWG4:_
+MW+EUOE<9+F>BB!/N9;2/UM\#5^=S206]AI*UOZ&9XS9G(8W6V\`RVQZ$4^5U
+MFM3\NW_/IZ0WF?(K_/G=NLZHE(']4B<7/:B!Z36;\&-CO`[X$$!"2,I-\(J(
+MZE-[W4JP).C"DC+ISSB?Q7[>J#)LAN9"[145-GH/3V</.J7Z%-/['J=FL.,6
+M)D^T2A)Y/`+B%E1'X=$A3W,2@BO;Q8%I&*G0@6B[/'/Y6)@5$,PR'EHJ<F-K
+MSIHHJGXWQ*N'@IMVT=@?89RIVTX,OK,DP#G/0].<V%5!H:N-J1AY6(&*$6RM
+MM<U$3^/45$%L</06P_FN_-?8YZZ_[%S%?U[;U\]R!-,(0>>[$=O,N_43V,F!
+M:X!O1V/:F^8R'^.UA9=0@M@0!2GW@L0%"`$*8R0Q`(%;[!%Y[W-,`_O=JQB#
+MTGU&[Q*+_=]%=NKC>FD2"J;>NP^^+8X(A7]F5##N0^$$#TML!=O7#?;:T^R&
+MH`00%#Z\<H_SMF^.U@E#'JO?>+\,SC<=Q&ZM^7-2Z)`3;'P99FL'X%)F]\76
+M>W(;+G3.T'B>"Y<MZWAQ0?!$SWVRL/92/\;0Q?RJ*@HF)K:QB`DDVRUE:I#5
+M&NVF%\VYZX_SCX88UD!]]GS>J>.@W:??4@$50B[(OQT!`W@:MF`?-0P,K[[)
+MB+O\>41J(4%XP&GKGA,IP7`:%3VJ*QB0X2J08P@Q.>8.^48L/O/YTT&*8!#]
+M5.1+;(P$+H(S+'ES]Q"@`E&&HGR(9)LGFB,X:_S3>ZR\RDHB84?<Z]G`W>OD
+M81NL?C%6*D,H_?42;23.%5'55,52%(1]C)116QPU0(*7*DZXTU]9,)?BE$++
+M=)E.89,#T'';+&C/M67@DK&$L_@JGN;WR+R-R7)>OR&LB!E9IFKAO#EH:%M_
+M>6]\%KO=[H\8>#O*<&QL;^I9W<B[J^5^IS^_W36]FCX:@#4`W7RJ(Y_7E1H^
+MGW:JXSS7D1E@:U>5TR-)KVI7W";!MDY1TJA="2,Y@<K7\YDH'-\[@KETG#SI
+M0\+NF1[!S"#5+)09+(-_4`W\[NQ2`"&,5!%6JT.NK3E\JEW*#:S5/;-8KN3O
+M5027[T^9O<VVDV>OL_%R[?\)GLG>=$H'Q!^'K)&2,-L_,F`9%X'Z?Z/B+D:Y
+M`<N$++O#6?HV@\'V+Q#=O=^"[/NO)`\6TFLX7%LTA5B/N]IPG?7`[3RTSSO;
+MS]9O'=Q.NNH8WG!OCTXC6-$SOW%UJ83^0/-_!^DO_N0GI(GQXNSBOOH=U/VP
+M-T()R47+)\6'<130@W1#S[9/3B'*=?#`OJ+)]C\:@,.2>Q0YSX'T-[$L0TKJ
+MOX7T'^BPG]GPMAY)K4$3N64*KL*2JB*M-?-77-R^$;C[WDW:B0/$&>%GK?M5
+M#.%95C):,"E\4#-L4JEHJ2".7-[-\,^O8PJ41*3CE5;&PR3&-L\?,N9!_B5T
+MTQQK1J;"[-70$9"0C'ND=[FV((UML2:RA&&[7B[2%O('77]X=SE1IV!M\ER5
+MB8@8`I!(=&@M+9E61IB^+X:/LDHGG11$5@=#0P.=ZB3[3J-/V/NZ^LX_"O/9
+M)W/W-X&7-_;HIV,^\?R.\>*!,T`5?!GJ#L=)6%$.NGG<RHKW`[/0;:K+$Z/*
+MZS_G]5KK`VD>3SEPL2&IS_WJ-\#CCDE"`*M&:+A`M`3EJNM>^ZO7=@I)YU[:
+MYS>`%!%?>U6QHI`D<'!@9J8-+!MBQ,+8&8;$/\C*5.@]2S>=1R$*@44//9NH
+MW;H>'EC=EE"UE%5ZJ\8A2"H(G.TN[IVA1"-7PT(%(A6O^!8H=Y4*/P9_FVL`
+M/YMOG\[[SSJUN>7/D[!@-C[?O>DV2>`D]5ODX0+1=S(5=M;<!2(2&()QH*DA
+M'ON?8!.F*8IBA$<$`8C7VTR--IG7/QZ"T\O3@A=W:3OM3=?>C&5UG;(GD)HL
+M'+JDN&$6,J(Y3'1E3['9K.W(]'BZH<7!YDJP%\I*([\A7!U<UXC;'PRGE/!]
+M.-;>6*))4I'DU36(8DW^%ZBSV/2<!"V,W64M#4[H>D^!N.HFM0_@=VM][5]W
+MWUNZYPK?D6YS7Z4USIA-X0I`4DI!XFTV?;%>$A_M9Q"I[5#<G#/:9^"3I?(R
+MT-$_'8'ZG_KTV?F;(=@#@D!?>UPN0I-O@MO--XUNFX:Q<YKI6W]7*C6O%25O
+M):Y5%NE7*KHPEZY'_>SK!"3QO&7<Z]]R,D>>2O-(=[@2&>1BUSC*Q^2Q1J)M
+MJ(LLH2\SEW9K"&)!%6`!`WM3J-MZK^@^%HV-]&PJQ*M;O;;'3C%K>_2ZV>#U
+MK,-J9DR9U79W9(VXW71<VXXTS15R:9D)*G.(,09+L][08HN#&)>AI7<$BX'\
+M"Q3B^`RR0L1#6\\4MD0+L^'%182HW$0M((CT$V!@<P]GUO$3N][BT@6BP6`&
+M$G3K"%IZ+.?_PMF"@IZ[%"A3%4P7\-H"T37SUQ-BPX&D]WY_'E];6QM4GK9_
+M?OYO9,;9^&T6C_SZ^@;%[1G\1_39_%$PPZ:Q^6Z@Y2J`D#VT3W7!X[/UIU\X
+M2/)3\4?ZH.6^BAD-0V<WY@[`I'8QJ!&WS=4E)2(L2+"\9><(5U.09'/IM<1%
+M'.L6A4%DY22QQ5F1NDQ/-T*Y&=][--<(D;!C)/;LJ'EL7V!AH1JBE<5^H,EY
+M^O6L*!_8KR;(KQ?G7@['4;NP#)'T(5']'0<I_5ZX5]ZC-O#.B[GH=[:.!^;W
+MV"M*5)3#'_>8_YY;9J9.%@%#?:+*#X>9INS>9#T_^L$%S&/9HNMJ6>.8[C/=
+MOH9'B/J@*<[_Y:+4]3U.>=ZUR4?>4U6._3W_%=WY3"'D]QI]_[QW4XJN#.N[
+M96=U_-7I+5=^\N`9O@['6L;S<"G6?"R[F#6_0U0;&^E&020D&3I,*5YJ1F55
+M<37AK5?5-4/?9F#?3:[3J^9Y-T)B/%[-K6G9RD#=M/8XQ%.]>1(",M"J,W[1
+M<$G1,:8Y9YQ\=,ZJ'WWB8X8>D1A2&P):PYOG,H.N(.??5PD#_3]-_U==E.BP
+M@(:4'&%@-8UG0RS2K6RE#'0S1X'A9Y99)[^J5<8SY=2E8*])CMN(Y9I48OB4
+MY3G4G]5J.NJH8XJR$JO.T>E@V?JVO/?J7<%_JU#K[,+<:&--0*>\A<6CK]?/
+M,Z4T2VOU/;\T]ID>K3>[NV(;>Z;G)#,NO`O&.UEU:=K@9IK5<LY2<"CM\1*3
+M-V:!IPBK!BL%1FP:/L<.%1MDT_VV^[3?TWXT^3F=Q'G8_^W%UU#@J?C0S`+D
+MYV?%O;H0C8.T@/,1S([U&H9IJZ[V!J$]#6'#7)WL;O`JLA2;["!'[=O^^<N`
+MUTP9#Z]&J@P^Q9#[5Y1#T/_'=RN1D3V;A[/9:[@J6.E6AX@-(H1J49/9`Y%:
+ME"01A9=%H%!WW.3Q3)/@IM#Z?/WV?FO9'*7EM`<(!#QACE+M\L\_[.M9Z.8L
+ML9#@\W"3)K<ZCD+[R,M*P81J!E\A\KQ<\P8HWI=Y":04^"P[2<\G%Q&RFZ`J
+MTD+E/S0T\FY\#'>/Y)E0/,13Q6.OK[Y2<[`*@JQ8/[?5<L>Y5'Z5=?^1@^A3
+M"?5I3Q,V)]^F&?8>BHMG>]%IC$WMW\"SK%UW*0\-I)XB>S3,V$.U=C6AR")F
+M4#APNKX4Z03JBH1T-UC_.!FPR1]E&OU4.A,["'N,#J/?4881371![CRE<1/S
+M1P=9CXH)/>U1?$L0;07XI)MJ"HR/"=7P&80X76\'PA6TMD<6GGF!,<5FGS]9
+M&D%G<E4?]=T;]^H*HI^34U.MZCY2SM,=:M\V"AP@:OBY/T)CS64),2)%/5(4
+MIV*/3<I@#U2'4=CH&D<&MF2N`<8[6F6F_U/-W"(DS[F7RP8AH&B&";DH8AB-
+M#0&J"5><4UK?9&^M;;!X9XS/4GE'Y5R8WLPGYX20>JEX,P3""E5U98@8$PJM
+MCG@JK*4%@+-0-5(G)"T(VT-OQKU!!R81B,:%I#=IAK"J'6K#U\7*-F4G\\,4
+M=UC]#M*,4FWVN'A\H#<D7I.R:^5RY&=9U0=U"FQ+24]_[*@#BVO^I`Z,/+]8
+M^MU[>^E&K#9E]>$M\,G_[JAP@IO^GC:*HYW&*S_XYIRDM(Z_=E$J3[DA]P7Z
+M%69F&1M58%#&/CM]S5P<1_'77F4\XD`$W,B*-1(+@4B<QBJH#BCY3.[E3#".
+M%5CM:JPJ<OM[&4;E<U<8/D?ETG%967NQ=NH?I@6'YP_4('L#^(?I7Z_9O^8F
+MIWD<IJ!*=A,M+Q"8M^1I@)2TN)L;,]2+2IEY3)V5FA&#5A@L019\%K87[AX9
+MQ$N7+7*-C9PR7*RAF$C'.L39X2<L!MK@L3>1(B`C=+6J9S9S+D2R!+WDX;E+
+M(9YM"-&/5/[(V,2#X+YAS;?-=?/1P#:=AF$G!&BL>V).&=N"J691=28<LR3M
+M3"'9PB()=$2F#L!.9F"0BS8:9IE`HP[R9CS1.+<S-+1".V[9O'DA(G@X/1;#
+M,&5I>T"`&U">"S)#,LYN8+R20Q8DNN&T-:<9MJ.G+>/+9FK4Z]JJZR5LT]/$
+M"0(#W50)-LQ+S1)JB1@B"`\2^*E73U2J7*RPQ-8>L*6L.<085H=.202`R0;]
+MD,0R04GX?3\JUV-G-)U<LL8F_3\6CF5G3`I,,4IE<]!74E"SWJ3P4A;"88%(
+M`^K3^I9SUW:B^?Y=O%%=V[4[N:(MM]NK))]_LHF0PFYA#5`Z[#XB!6"MB"@O
+M98@&F6/O-V#S/;Z-L@B!Z5`.PP+_$K0-\]83B%YU?77#[MFM^9^_]''-"]F!
+MG@XVNJPUU,G:X'\F<;TP$$4K?/^3_HV@BBC7[=='UB=?2(M[^]N8M;!%AW&'
+MQO"CF3OTY%((WG4/LLBGK%YJK(4#>?N5)+P5XD^N6(*`02,:^P:06BB`_?,M
+M@P^CBZ23\;_WJ\'CX&)_E#=)^/JJ4XB&*`\1.RCG1'A(B?;FI!V,0_=K"AXJ
+M@S[&9!Z_\?<6&Z`?=C^&`=Q`W2*_LWJ@]_!^?'<$4SY[OH:;0?7^&I]O/03G
+M9WTU<,?=T];=2>^JCS,.?@[Y,)[6='!.)CP;)DH.JB;"?NB?2Y+`LAB@$(%1
+MX8R4'B8>/N78SDK@]O!_/-.'(PJ)P.1.?K4VX&+MUU?+\)^CKHL`Q*]0#V/)
+MR&!20Q[1\"JGS.Z6>`]KR:FKUJJ*%[:#.&C$Y3NIH2&-?N[HCW67I:/4Z],V
+M(>:E0D4RO)0=&SS>$!-@MN*+Z\#Z?S<-.M>9QK,,14S(AA5:ZKA$93LX=Y,0
+MB0`FI%_?`B(J"+"8QB:_=R?`'X3^`8(D1!FLF-O2`)"$Q>Q'VA']PCNN/A8,
+MN1+09113(YPB[%`&&ZUK&7B("\^MHG"^$/R2T,"E*5[KO^_/WM<^&I_]VJ5[
+M8R,T4D(@(OI'TD<*0,)3=/T+F1(5)1:8%"I`&B=O$*J5_%XYA51]!S6-U%&(
+MM-.[3P``L(&]F4J,A9\.KF()YV[SNSQKD+%V:T:8H!9*_#&>]\D]-.YCRCB/
+MK+/-7Q692`&AH#-%(R0E)G%U(E*E,%D19`!.IL6+AT;`0Q!(ZJ)E6KV,"UCK
+M[.NVWC^_TWK.DX7_/_]E\49'^_#U>"ZWG,7F;/$\]]WT_5VO6S,7LM8OX[#I
+M=1II[^8S`C1`*N]`D@A=R/.FRNW(:]J=T?_?E?Y#1ON*BWSSG)]C52;>D`40
+ME!H"/X*<H4'S&M!G?3>&'I&?`?ZVVO[V>MTB[."!4)_XI@_ET&.?H"Z=/'50
+M.'@='`.OAUL^O$<J)]Z"G*_5HTO:4CAG#`)'Q1RWG;SX7E-/]^/(3R^*<'FV
+M#O85AAAFB._P\UX['TM-U@X?64G(1T(<C`.MF?,\,KF9(,@267=,ZH0$HF6G
+MWDL:R@DUH2"4_X)Z-GP,&WT"2V7<25$T@&5),F>Z<OP39SF#Z<=!^M3<)X["
+M<Z!W'L,D-)TE+"7DH]Y2><Y:E#)CI3S?TJ\]KBB9QN?H7'WIL8&G+D1L2-<4
+M"2HYM\"AHAY[G6TD%-'E/W%*^@HQY$D_Q]B_:?HJU22$-EZ=R800;6QO/PW\
+M/#7E$!(!(%GA>5XC@JJ\E0'`JKVS&BR-3,-T@^'_8+I?;2.Y,9^OJ6S39I=?
+M7I<2&(DNNOU.:T`#+B($U-XSE-OEW:!\Z#K-71Q>[?1)%_GOV*7I4W/3$.O-
+MDAWTLIS9\TE#`(#Z.0#WGNY>#KFHI%.L8MR(?*">/=SG+ON:5('O%+Z1[V`_
+M3B=QET'Y(^)B9)VD,GUZ3LH]1,CK35:T+7&TJMFZ[^J2F+?+=6OS7P;N?GN7
+M?K#!5IGBDB_T1DXW][)WX&HF?)4G*"J.E4+`6(QB14!>^T(@HQF`RAEX-?YJ
+M_)2V$F*)Y?C1(D-H8:X!_FV^A<(2JHBQ3>;=,;$1CAH1?1XS"G#U;=2T,8]?
+MPQEHP_[XM)C/!0?5>X@4Z/D2`YQJYD!=O4'BS#F0UJ5FM@[&^#1VV--IC*,+
+M8.,Y58WD1&QCP)"BDD"W,2Q5IMNM`[`98JZTKD5N4C`;QIDM(WDSXT5L6I"R
+M*(_`[4&_'%Q<VZ@D-CF<)*-'[$X`==AQX,DV<NT*<*%SGP,W^W1#7^QR!A@;
+M&EH.#L]GG7<)-M%UO%U?),6@)4.MY,.,#_"UF2_I0G)3VO:5HW9EC.E1<V)I
+M:L*A[>!A-"7&$'%">IIPAT<J'\IF=!3=`WCQM?ZP-2)>G,A]\A;.'J*L$\RG
+MJT#(0_&_D7<<S]6SQ'K8R8GWQ*@#03>WF)7D-/:7G1&>U(]*J:YEE7A8L"P"
+MZ$(`^ED(E1_P5&,/RGY#\F6DVK0IU'9K&"B6!0<*6%$MZM%08DI"<X4]<OD"
+MD^K'E"E!S)^;$J@>>"J?+KX.>:DY_?AMJ`?[;H?=I+8%H4)/_PP/T&'TJ?]J
+M>&Z?TDX%G51U/.4^U[GQ=CR<R^XHW3,S#AJHEJ-[F^Q"T"0![^>^@3PG&E;*
+M.>Z[%%?'NS-#]=/T7P4M#@S\S8;683$Y*</5,G"'-$+<*7:$GSZK&49<$U\3
+MG()JH_[QZKLJ/$8]!*FH"'_A5%3L2*Z1K9S0'IRWHY^DBE"/55=Z?"B(FR\H
+M!?N<Y1ZK'XGS\\#-]W56@4*("-(TI#^U["@P&!JJ@[I2*19:`9L+22&';FM>
+M)W:O2N;$>EO2W2N&W47?HZ`A1;`60I8F3):"A<3)@>96\YNFYR2T=ZNK%O.X
+MIZNKB[A;&K^^OM/AMO:Q[&+EMTW(VQM*1LDB>T-F8F_U^@@D60,<VU_E+7E?
+M"D5F+WD[7P6W*UY%R\=92@@`*10@LC5%PA\KZ"`ONOFCN;EOCS[[GJ0FD@*T
+M@;0BK$*[06OQ/*:O!`?R]E[,7[YX@3V^*`S4>7E/J\3=D#7B\?TR30KO55;=
+M33>9CN24*)H`TD5@BM42RF[!N0VV1LTH<V%9Y,C/@BPG*9QP22=1OA3(-3/U
+M!-:\U)I8>?.?/_+Y+L.P-&S3>UD'6G-W.9SWU><1UWTLO)HRU^FOQO<SIJJ5
+M,BROXFAV>GD6^&ZILX7:(KPJF`KM3E0S/.(3A#K3YWKXP2,002#,VJW;=V#A
+MF.(8/`Z">/=ANU=!L;/;?:&[5I!R)MLK5JC9(X4OEQ1K%&HV#A(-QP<R`5(8
+MFWO`V\.NEQKMY+<G5QV6MS88WM4JED4111@[JI,V8EU5%17+3[#WQZ>OJ\GB
+MMC6\B/ZC[69\SARYYHT^^]SL?MV";1&1LV@X11K7:+;:&QI[*2+V]Z2AB"L0
+MV$T93*04*9%!?(,!0I;#Z?_#E/3;=D#%*2@?%_CS[&Z9M!R.>:TBP-E&0/A)
+MM<RD(0*C<2A/7BL_2`#2$<=/(&OEJ@S)"DF.<HV!\0VYA]I>A-:<-(E6\F8K
+MU$-"M<YC'=`P:B:H!*3X5`_3%JFJ(#84I0?6/0M,^M?:R_`.'J!Q:[KWZUGM
+M:VUHN92MK4M(D`!0C(_*H'W9E1(?IJ:WKW(&D3CN;%`T9&Q+Y0?>0^CU";(#
+ML8<80*A/X4*08>'8KZ(*3(P4%EHU>+70,-4C%?-MT[U3>5#>%$+6^H\EGG0$
+ME\H%*,+OB(Y4BOY*/SXG):D98[Z4X@N.LGA910-I\E._-R2BA*5Y?-(A.IV"
+MIKL9]D/,.&(%Q?770**];`3@"05V:NKCN9:V644FL]^'%>7\'PJZGQ@,+5^U
+M?V+HF>S80VPPI-AQ9T<)PXM!G45":QVIDP\_\Q1%&(#D,4@D=PJRI8H$V%J(
+MHL27LTL+T=AV/R*A^*PXGY=/9)-FE>4S\9O[:M6'82<-8XNY'BX[&"!GCCLT
+M'+GEFNG-K#U@G;?X[/;R/L=*]I'M_>;B\DZZ6VGQT_:9?F:GODWI/UTGE,GS
+M;)IE-IJ[JTJ>U@W1NTQY&R=S`Y&<?EA\3%<^7@_RF$'*XVJQE-$#=[5O8I/"
+MWE'QX/57@&\ZR$)Y>/F8:$#8S//Q<LL>9S,X3*J*SNP43)BT@RMMGVG[GG_\
+M^7CP5;)L2;-]W2<S##A;6J1CA\N7=U'`F3ABF`3R&D11Z^PTP4)^17)#CJMM
+M4"/WWX`83*M,JYEO[&Z!NJ!4$8H-541$8B"TTJN**8EWR7+0MQFTY4%>F\'#
+M:QCUQM'M$MG55-75*]F\(VQE==8P:&/:0;)L1T:B9";Y:`RQH!<-0!8*F:5T
+M54<TI$R2@<[@BI*LB3`&L(#GWEHJ0C;3[-15.N5EC!NNX64`F=0I'/.[16D&
+M@INGS>=&J-6Y7*(B:YN:\[AIIEWFLTTW656TD-LP49CPVA!C;8:<>11-H;C(
+M3:D:J:81QV<71H,43UUZO+KWO5YX])-P1$0]^O+QZ]=Z:](P0E#WU<F?!X\H
+MM"5&W*W+&R<U<WCX-MWF[%&2KWW)&2UUW'=>[WL8O&/'N@SNL\B*!$8+%`60
+M4455BG?#KS3#X=<2EW<DH9.<F\AO)LPCDXTB7!A!I[N`QQO5HVNE%&N5V(@J
+MI3#/Z%"@FD&&=F=FE!(QK)6,T3>J%@QHDX0HV8XWLX,(J+7OKFOW-O7OU7B;
+MNZ'C=RQ-(IP@?$:37I3`&N>X#X560.#8J7\_X1UG++2E$(DTHA.W5D$N^,RG
+M@8H?J">37-[V:SL.'=_J[!K#,/Y^XIFN*ACN-4AZ@S)ZP3-K^+5_I?#O<SB6
+M]/K.&12+,BZ'9?;43(*_Q261/BA>>G?,[QK[FF[\7R(N*,J8884"$X=<AA>[
+MQ.A+')]2AB_^D8AV,D#DB`4W*TW(Q*>>?S(<AK7P[=]*])EWV[Z!B,NT:IFH
+MVZ^-*2ZC;.:`(%-W&DXJ41RK6$GF*.M:I9\:<71(N0TTQ&;L)1!'8J!76=16
+M6Q&V8@X+:FL-4YWC099Q+F?,Y=]I].;9;-/+MC<?>M-J$#S;V8@_V$^!P1X]
+M;"O[*SFVI/GCENR)IW\5W9SHR["^_"IBMF3#%M;9"SW=Q<O2+LOW<EGBH;:[
+M#3=`TT%:VJ(LJ*#<$;TW_U$^<Q]"'N6(4H!_7=JFW/V'Y3Z,,U!=`GR1Z6*Q
+M6*,_\F+,)/RP/8]OVS)XFH_G%[C92$Q8L#Z1O)JLZ";<;]A(B2/FVMYADN=\
+M#P-EF^N:Q>7&-/'JV?"3.6U'BW&PA=0B$.'!28DPH:,@;Q*VUNUV54JCS6+C
+MRSD\7[;_%STPTS`W\W,2FD!&+R)4=P9"<<D^KQIH52-H.<(@K@U1BXIDNX8D
+M8(T^1U#2!YI<_KYM!NV,C'"=P9V1L;.!MJ"2X,:L+@AED5A8N&HB4VUF!IMK
+M:R[YMLC8<`.7#&;W7[.YYVC2WRK=\3.&C&5.@=S"$4DXRAH*)U@V&+$0P(4D
+MA%D0O=:E"6",B08D8+=@M^`86IPOAA"2#W]_7[#!OZ^Y#C0_!Z_YEWBKRQRJ
+M?KA[J?Q,_>,,/T/?(C42)[1PJ['&R-8O"=C=\V<PECKN[]#LV,[GC@BPQD#(
+ML.\W]ESH8'0`^D@=K`$-BNA_5H#K/3=FMYX]('CQRUAF?(],CJG,]JN*M*&,
+M[XE\<XOVG'9\RMF6"*6L+%G4(+1)'/F,;@[?DUU*(;*H@G/2M,0S=.&+(2;D
+M+N-OE0+M=ASF'41N8#$8ZLGK+=K4,N_72/>99.#8UA,S)G-D0K<"</3HF+M6
+M2.3(?IT_64.N'Z;$`CM%PS\X_39X[@-XD=,N*=PK!(=<[SOCHAL#39[:>+XJ
+M!AD=BAW:CXGFXMFQ#04>$'L1@@9(32+:(KRE(HA@QV5;!&!;9LF:NBSQYEGY
+M[,&-I-N3;F(+:0@T\D,Z`X]4=W@.*6+\18]NGX\R*R'HO@XOOA\&H9A7#&87
+M:0]T=PU5%QR:EXY]&WA>C;)%^\##+A;*[(/T<-P4SH4;6U?:-AT0"<%RI@9#
+M8PBPT.?*B`H9[6<ZML^UK6R84R,(MBO.:&5WKWI('R>+1#NM,VHC`W(HHW!#
+M>6`-F/C#SI`SU,0E^1UD3.SLBK'(-D[P_G/)STT=;VY^0)LFA\3<I3>4F5(R
+M(<*9_DKKF1A#ZVM1.FOPY?4H>&K>\G+.=^/=30UCLB]V"`?.S3/+MA$=CK=K
+MO`8G+7*B5^:#T/_O67HFTZH&\.$AB$.DK8)X!!RG2="KRM)6=5CK%MGG==B)
+M7TN[,S#R;W;GQ>1?X'O*)$Q+T/1R:_89/X:09,O5YN&J3/3>L5)BE2Z6"0;(
+M?F'P9=1"#EKB&@N&>G^]#EE4.T0QQ9?1;+^VF*^A1R>OH\='&X^JT;LG4!FP
+ME[]H3&`NMR)@,C.&MG=V<G:T)DXZ:G!CBE%,.0Z,1@<4@Y\]+.J7P-SNP2Z,
+MWT_)^5#H/]<]7CU.-G124C<(@DD)6<S]7<R+6CIJX-Z=2;L;;I6U(%EUHZIQ
+MW\S#=;'?VNC-M."D^3[2X%^W<AW_IO@M?J#D'5TK*PX('YZMTU@JSCUB>)NF
+MK-_CY>"GZ/)9"ZC7"-ST+6-"BHO4XG5CMWR!/TA(0Z-,V;#/O!Z/KY',2#^"
+M\OQJ^`G)Z/AU1BB'!!G$):JN9E=G@3/PZF9X)UO9%%TE!/2>YJ'A>'V*K.[>
+M"8B<>-P;^%+!51.L:X?"$QD_)W3N\O?U&G&9HR+`3CJ-9WS[:FYNO`L#1Z[4
+MNX[B%K.YX7$X9)29BRXYA'*K(.6<$((HF+`FT,T((@LLXU6P>;95H(&8-BK<
+ME5TU@&_F?\[_B\6UUTS7&0,6&@PX!??P^VA'6[=0R$?4:@Y%),QXX]'!\6(C
+M%'?(4[QX!8&X"\0;\XY(`N022!U9T*)--3>2@:>&LB6F\AMF+D+!:9Q:Y,+Q
+M@V]8K1A8H3.!$R11LBB$;43!5CHJUO4UQT5]O\[7_@O;PM/GHZ+WW(J$QI+Z
+M9]AVM"D0GVK5A791RN*0Z'I?EZJ#'QW&^:H%T$$G\#/C-G7T-YC&R^Q_2\A/
+M[0TFI4X.V'N.I>7P!](<3@6%L3HL;8\X8-M64(G^@`([D/_AT((D:"DV5R]<
+M]IX(>:Q>.:X,XOT/?KU.&P<-CBKLRE2[V+M.:&!%@BQUJ&B!FD,*512*LIIP
+M4/,F=66:^LW0\946!X^9Z3@;<B>+NTYP46*PP(ZR#)FDY1`U84@"U50HTJ%H
+M*`.&B90X3-!]3G9:(Q&9W5H;/?XX]LF_TVDN=.=S,K;MXN'$Z@R&@:;30I$V
+M96P"<P"0D.VA$14>I4(ZRH><W<7;LAB0AS$WT'8,ZNZ!&8>78]L0XGIJE!U*
+MKDT=(97MMGHA!V%=&];%OU,-FC-IV<R-KIQBO%\A^B:X]Q_9NV!&%\@9V;;P
+M;-S@],PV7(N=QB$<2;B!ZI6)-B,L;!GQE=J]-A..Q)%#:9JK+Q$7+`PG:.<.
+M,78L##I2'L1HKQ$,YA\&$(B$;E@X$F+OV+_0>@6/1Z.7'AB4<V)%@386R.&L
+M($.SLB&WPT.KEHQ`Y,4;;QHC!>GEGV=M;0T14;2RZ4JUK',"-WF0*=V$-IJ"
+M-5FG[-[-YMI$\6^&(<Y871IKK3&W`Z4F==Y/U:DMEDQ%%B,=W&2X\B]))*+\
+M!S0>1!BE*%,S!8W5#L3.0PI7+.\D0\7>27LGL6#0&ET\$RL3$NM'P)_`0W:N
+M^^#,(4\+54FPWEXA\/=[M=U+MJ7<=EJC$-*$7PS@$OFE;M<0=PMSAB[0^/>L
+M<=5TRS>LF^VKF_#+J!?#U=7(;KB<&]<C;3Y/N`.AR0(W@DC"X)4UK#ZIFO$G
+MD6`&IP9'B2DJA";G'*%$Y+D`*AQ:!3":52Q1$&B9726E:!SZF*=8TAV=9TTE
+MI]JW@'TK#CX]O6N#0V>'1PE.5PVD\;EVAZ+L!N))?F<.G#J7<WG>SS<_#S+4
+MXXR.GC\7%8C7HV>V<2+W1?UE@].(NXOH%7-FU&YMD3)LD05Y#-W0=LL6%Z6\
+M5GAB0;G#UEEH&ZA-B,K.'CBH8[S40'310>,-MX>]32WAZXM0=UK.,7%RU&&:
+M`]70RT>'4QS-$<O+/3YO%KD$<)P+W,OVQ$HB4@MUU+SN,S6KG>#C*SOE"^NL
+MM-XOJ\TPGX\M<0E$A8G@7BG.8*=8XS&DP8@F\MQ$]1Q<XX6H".I+ZNP%"^,&
+MAF\AEGOQ<3NY>(Y<46OLT<X?1=X@L6:@M:9GB95=JSKM>=">RS8QG2%-L0[S
+MJJ&+JXUQAV:C4M&G'Z86`3=>;-QSA&$-E3J89AC?%BQ&(J&,1K;;R?3[DA)D
+M3,KWM\V^JS&S]ATA:79#9(O-&S:ZI'TS1V^)H;;-=F30A/?UL+7:>7(4XR`G
+M37R^7BQ>31!+'!,V/1>KB,M*5?OSR>E$D_-4;@6#]GM(':9<:';G]L/;V^($
+MEY#4T#"P%@N(;+P,CJLK(FKGX85/@^@IPNI#H9\^Y6D#`$(QB+B2!C+XZ:`2
+M@Y"@)XXZ*$3O[6RH00!L8IN9)&W%?+\,?X@C@<*V<@*^-D:H1;Y"@.+Z@5`M
+M]1CXX'K_?7FD`>NPV5V?SJJ7`:3JM16(I'UVJUQU<S%\KFT9^K**X'[UO/S,
+M@7Q_=#Z<'B"*^XGPYED"R(Y4@>06ZAW?_CN[VB(#BB&A,_[-YYY!(*`N*J7P
+M3)4QR=TB6,^NDZ\BU[TUYH:'6C[*1[-1IX(6=`WQ"&G*$!YFY,@[90XI?-6O
+M*=B+P$2Q*`1N`$!32_'4\GBHR=`@:H120(B+`@C`.U#9@@G&WU$8R\OM"#%%
+M%>?#'F*^U7E]S2W>+`QZ5D+MV.Y"^O!VCU*%T4_(8.X_?=;:R/>+]YS@_O%-
+MT0Z-?LVU//%^^_WVF'1Q(YE9+[1A7=6Z!`+3P]NMQG/?%X_G([L7&M#KE7?S
+MU,`UG;COI6Z:'KD;IR!G=8#VR-(E'(I6OS1LQ-=L5$6H][OQAT\#M.N'HVMK
+M1SI";Z-Q<8?#`10SEMZYH9G)P>B?(83D@UTQ-]UJLYK*?`_HFR6UVOG.'S><
+M+HU_45W!$7%LX#6)V,75Q.<K:0-W:$87Z_FSPUW]1PZ9Q+U4E(^UBK\'I\>,
+MW:[<@9W=5X\I>,1V;00%9R:21L*TNJ;`9RKW<]OY]G`(UU'?VO)MM6$FPHN-
+M((X(`WPZI<<TWD:P3[D$MS,,N_:&<U=(6H<D'3,G89_OE5`ZI"ZY8>6VVNC8
+M2;FTFS""LC)M,W:KM$/QZ-UV\D>H[5=^.Q<QO"HEJ7$*JU@7QR;1'IVS%,,$
+M8KL_=Q`V\:?A"RJ0B8U9FR*5A!XW+($*-2^3DR:WJ2`G2`8XWL7>#!LB204S
+M<O?4#)29@USA.`RB(@(Z(9AQ$Q1`<VM;9%G(`%1MK+.^089V@$UK,1#\R6#$
+M.A3;/)"!H809!"<%6L((7:UZ#C.5;'776S-R`-J3ER,742#L?(M1LVS0S'-Q
+M09ZKRXHAH2-,D;#5]0YB0EZ)F3V/?#5S:7<"3:UNYL.#8D6YX6M.[8>V#AG>
+MPX:W0DR.^;.>IN&MND!DAT$;LUK5FVTU@.;6-JO"TE6M.:%K239ATLU4NQ2-
+MG2N>&NV81W8]2`XV"^T+1WZAR&C`YYWJXV16'8(PI+`4=L@+C2%9=J)&!P[N
+M7W=S(WSC9W5+MOG,7D7KAM(*Y"`+<Z;>HP.=3:#;B#?2M`69P1$B9<,7-+OQ
+MALWN,'-=6YK'!8.23*)C-V)#&UAP09:+,.(%K8*:Z:"!AM[M5HNRKHV0UO)F
+MK]GXN`YWRL&VP8()&Y*09@UDI?(=Z5E*(91&2YE4;>)-JI-][VR9Z5-DUV48
+M$QR,-KQXR5N'#+4&/'%XSPJ%,UU4/+@,[MPT'M/:(+!JQMP)P*+O1@J"QFS3
+M`M1'K+%[Q3/MGF,M8(@,<LCSPE7963XOWUS1-J96MAAM@.C8,Z`X>&`7*T>^
+M'F<S:YR""2;,62V=&&L@";FPAG+`38S%,),&PKAJBJNCT(P+20($U+C1$L#M
+MB54L2$0V45QM,<A(<380>L(`4@,U+:TJY.(0YDAN9P:9J)3K.<GW5[]V5@<0
+M".MWK@*8QWXTY>+,`I(9[Z-=E!Q,)QJ\@ZC%W9RITZ&;;Z.5QHK6\",K-[SU
+M@&$/'AHP@+9OC+@9S+7#0]X`(?+79&Q$B$QNAAD<-MJ,88-:PD$"70O*%[.A
+M9S+(`Y\,+D`9Q)`NKUO=5;CCGCC.BAR4>&3E87&7J(%93@N;IM&81RD\4FE0
+M@(W`>Y2A-E,9Q>0T8+.X))9N6K(.I-T&C4D(HJZO9BB!B\43-Z$I!GU(4DQ%
+M&,K`VNBP(WO1;/L+3D@4D+00C)LN6TX-B92!9)(,UM4$>CK0QP'!I(/SIF?!
+M<,UAGBP]]<'%56&Y)>SD#TJTR@_<(@SM,]B2#$C%^SY5C,UA:7<INPX-\*:X
+M5`9X!'I;VMH-;8Y:M#B78VP\6Q;&7L/3I`7GYL#:A#QM=B[NPZ6&NA5J860C
+M2?&03L2'Y#,"#Q%Q+1F;D$%.I#TY=H1AIB"0#CL&#&VEUC8S(CEX<=M;UE$X
+MG)LT(<JFL^>$V\M0V(MW-F,I!IEK06(P1WUEL@S<:E&(T#1V1Q=F&>8S5Z:F
+MX6WH,*.7#[OI]M0$#,!-:"+DXIN#L@46-J,S=WJ-\II,$X(:LLCCA,896"#!
+M7]`A)L=8!WRECJ<W"D9;@\&3P<0B4Y2G)AVA$2%<T<0S,RN4P0',QA\8PRO@
+MM2EI(=7%W]3K'B):_+!3J_1LY&L8:Y<AD8Y3N;F".79J-&@H*87N888-YF#<
+M9@1-Z6MM.($EJ6NN6@Y-8X'M'M;S9><,:%T(`(86["`N1I?T%_1[D>>[O$6?
+MTQY;SJ^;L0Y8CR6TA;0J<A^7'E@[TW%0^&MQ(0,0K,1LAWOEU+M$GC5@[G8K
+MAJWO3B1Q*P_$0SJ![^[=.80R:)&.-Y)T:Z;F(S;5,R$6<]+`YLFK:QSK<M4:
+MSQ/<]35WE$91)HZG#;,X09WNXY-D@CA9I[<'!@$D92:Q5OW=7/N7"UO#$VX+
+MZ6S8@Q>K_J^46M"`7UO?9^ETHTX$V8.0`./+@E%6#MF!]/IN2$!*`Y?`&*D8
+M3Q1030:&K>0?`F_VLZ:PY'>Q'VY$(14.HUWR+(^LGK9M?IUK%"U&5L]FFA^;
+M-HVL;R`5GZW]@B-^-6<-WBICW*-[+X&JR>3;Y:)8%1T)HBH$+!+!30/%\'HT
+M@;4E)**HBS%AD9PX]<84F7Y)]\`;`S.];`(WD`0D98^DHN9L@W+S=8;T=UUG
+M>ZOXY\F,AHMLI5-J,E=;O`040WE$**E]4!A1&/5JI]5LJ#USY/6>8P/D('MF
+MH8;29>1(2D1;//V`12``I41$2B!S[YLETZ@34;F%DM:*$!B(P^HK!4RLB)E1
+M6&CU*&:8$R3=5&;/=U09;JEJO];Z#0M0<<Y89A()D!A&CX5@&0&%F#8,A(P;
+MR*#M>8[-D_I\`P)'Y*H@\<@#>R."//D7T[`H@_PB00!F^T9`U-_5G.M%T,_G
+M[IL6V!""`$)Q!'/<&H\'6JGN2?N_QJ<IE%`D%"1K2I3G2ET.'(ID`#KB`+H/
+MM]!43NBELGSE`\-=D-]>'V]'FGVXP+"Q1V!Q`R:G&6K$[0C^):U1"#<HYXDM
+MA-00$'RGU#Z90"042-%A^_W2OYB3;[-^HOWR![4^@/%]T`-`GU(EI2%1`,+P
+MW3AH")@"$?@5*Z9E'I**5J5'T.UKGSJR("TA=7C5\_,>R*7=HMH>XBVC<0'J
+MH'U>GK'$,;@4&A`[.%3E85)I5X&W*60`V?S*/!@=%MJ_ZSDW;,+C/@=M#IO[
+M*/+Q3OHZD0Q0XV6@<YP5'^T?5WU(^XCH)GUI0=7TGF-XAMA?E=KU^^"[W&0X
+M`$.CW=]'`$=_9#@"";W,4!ZBU6@W:JC#=J?21Q7*+6RH#&J:X,Q9P^>3H(9&
+MU#>QT@E!I+?(88J1+H5=02('4L5L1NB)0R7DI2\A@9(INHK+CNP!13.;LKF3
+M"9)(I(L1@!FA(31D-4DI(3`9ZD4BAC?O83,@&K`#16-%!;=R@4%J,*5JJ@+J
+MG099F[=KA/^>N)XHFP";\Z4RGP#*%;*=W7Y@_J?[WK%SK">I--ZH?Y,'2?`0
+MP!*]+09\5>COK&0U[#1TK6&Z$(ML6I%&(92'J+`79^:S7>7L>%?M'8Z89,PY
+M"2(VWN&>>!NVSNNB:H#$II$(?@949H"A]OST=6SY:SB%,+2;L6;`V"!RYZ`I
+M)*`7DB]F\D)@';VSA2B/CN\%"V&#>L;.G@$ID#.2H4-2RRE*-?,R:U<X*SXU
+MRH1C@<].M8V!9!C0VPLE/'Y$-E9&?.H@)$$.S6*S2TT!1J9]/>GR\\;221`H
+M6`$LJ$#Y1_Y;G.3>.;G3:HAT"=R6?1A7@TH6F^?A!"GZHW[*?@AM8<IEE,B]
+M)DXW-NFDJ5^?44+K!2[%"LK4`*?PJ78@##CV-;"!R30EC(L@&8Q[?M@H@(JR
+M(.'*C`XHUPR'I_(WR9,,DD1(",2I`S.'/<#$U(U!?1QHPHXTGP\KQ-D_7!>\
+MARVQ#/]K0!GQ/J'W>YOS-V<#)%,H-'M;ZATEVZZF*\0PB*R#(Z9X@<(26WAY
+M;G]EPFN#)XG1!7-,D!,^"!T$=I&S(OL3FJDK:^JV+&VO+SM5;YVU)<15D+-T
+MD:>#XJJB*["(EHBAR8P1M!;0=W^Q_`()"X\6?XQT^4/@,)R.]\9<:$XB^%4Y
+M(E6]GM&=;=/>>^_&Z3AZ?7B).(2!Q'<.!A-C.DOHWCX(4XUO=MACT^OQ.]3<
+M0V^(Q,9&$A)#=M<J;\S+U/AG&!C7)8T4\7)DLAK"8/1[*5%^]Y["6_\?G?J;
+M-QOX^1/8U*%A_34C"V12E549M@4DA*32YU8,ESO.M<B(U);&QKSKML5;SNUK
+M5:!9M&H1M$DMO:;[H(,8IBKS7T.PN;I>@0YG/M@J,NN7[?^I^+3B(W]CBB`C
+MQ,,'^QRI&WW8@:M<'GV&5'CY8W)PEC=6,U?`9ER7&L";<)`GH]OK$EK9*"U7
+M&2/9A+!OZO1B0=C&<*L^VTP=U,E(4E+%*::$6A#.I#FD(K"O0T<.;:IH(9S*
+M=@=F4*5!,(I5?^%*JL-O2U#$?BR5B@:/%5*I!HF-'1@5S:[6:V*QE]3J]TL1
+M!0H#`91<Y^:MYK`U,.>FJL!2"R*M&QK%HVQ:-%L15%J"J+:HVMC46T6L:B-J
+M-K4;;&*VBHU)L:350:B@UBC5):BM&QM%HM$:T5K%1;)M%45:BHVP;%HHU8VH
+MT6E&"2!HAB@1HT9($@*620S,A(A"8A1((DL"*$%""Q02>^Z.^<P;(`(D&,B"
+M10R.,S,I7J8Y4SB\K[$#=8-_:5AA7%Y:-LMDT&(Q#5XVV!A2FB5-*@\*`G$2
+M#-%&S-_PN:OO5MTB$C0E12)B+%BDTI1%8"*`H15D$45%0=G['6,3;NHF\,\8
+M45/3'GY`L9Q9AI<+XI9,(4,D&$0-B&0,,]3(_B.I^:Z3ZE@;4R_N.Q;@9-]&
+MZH:P8D*P[2R7/XMC6+=[\CY7@^.S!=+`H6H&NQ*FXU\`^1\KY!]F#Y([#K(B
+MSM"4H/;0I.BI1PHK`LIIN3(.%;;,DE"JLD8QPD<;HR,*Y7;(W)&2RM.5M1T(
+M2#8.0&-#0[*#5&-N".QE,DF1UDS,S'76F5QR*0@V[)TC6$KN3(R9"21DDAJ7
+M,I&-.M1I24R%K<6%5;B<CN;EN9.>9>E\#WS4NZZ]+ITB)6.RUEI+(W;*W-84
+ML&X/!DK(-MJ(<DDC2(3U"40R>31IH;&SZS3]/UY.G_##ZU_:)';^>]U<B,'C
+M(Y'&[8K(F%J%0Q9TY06!2U`H4(-I#E!B.QNVLAKH52(>-+9*57M3)_*QW>D]
+MUY6L-S)`4%A]=4TXNF0"B-E*"R@:0$2+2I,CC4R1?-OUF#/1`:,U!092.DJN
+M8[$`+D#CRP[`$[Z!SM-5/%8-XVVER!C8@*PJG*3W2QWEI950-F@#=E0CBVD!
+M)&N#(D4_2;TY:T6)DKY:BU$DA89MUG9B`#9Z@G4>%R[CD.+C.?FGP_\%Z=`[
+M**'Q73=)E\&OML0ADL8B<KGRFPR<=>Y./OG(W?@Z&4B[YV"4)ZMGK63B,"]2
+M4^9922"_9A]\%\TAX`@C3^_UFG.5#(JJ1;%'NU.BQ9H-Y+*YFJJ[KL^7GEWH
+M/3(?A;#7BR\<-?S@"X#"&Q@5>=:(BJ56E5USPC^*"+6,85(&@U>EO[3O#S$R
+MAX10O14^UNZCHY21S*V<%%Y%1HB@0%H1ZV/X([#Y\#/:NFB6YGYQT%I!\7P(
+M!?YTRQV/!;?,1<QRXWPI'-WDWY0HHVK+Y&2,@DM`R]H)@L#=X:0Y.?RBCTJ=
+MI+GP7L*Q0%BP59S!Q$-_)`ZQXW7!Y2NAX933LIOBQ)CIK.,20,:8BYUB$2C6
+MPI34BQB)X<=9.P&28AIJW#`>#\3=+TU)<>.OK^Z7<_HL^XS"!]*WZM]_K@AR
+MH068/]'/06/.D]^V!&,Z2=;*\'W.4#TZ>92'@Y-!7JTXG5P"R=]H_7=>GT]'
+MC21#P4M*BP.TDV];^M12(K%!%!-E:`1$2)5U^]C42[1K-Q27'9-$4N@P1-#P
+M0!Q`XIR#8O7D/.&RWV)/+B^"-%%D8YD$FPGRW[ONA_-3L4=5JAJCR,Z',R.S
+M+KU#*#P!^Q\7D/]J'DO7IH/X1#B!X!%.4)%O7$WTAMDL['P4V*T$K4O,#[6A
+MD!:JPT%^G^PEL+<H7A$)%ORN(/+#1!Y-N;"U[E>Y2=G1L!19-=[+5V7Q/%9;
+M,U+RP5G/'W\5S-=S<*1S/$#NE6PW8K/;JM+'4BCS6`6XAVN28)<W/!XBN16R
+MZ4?DJ!VEN-JAOOUM/#K+&X4![L!)F[,W#I@_`*K,,(+]=S+YI</>\1)Q73OI
+M+%<'(<;([=3/$/PA@="7B!D[-JGAKH<89]9BCM1FFLU%"[KB>1+\5;G<<NJX
+MGE]FULEEGF5#]M:<8-JS?%<DYG$M<4=OI[M,XQ.AQF1OBNSL1BF$2#G#XUB+
+M==!W&/S9R+,_(TY#PP(Y0EN-W3/)4=KX=:\-COJ/&M&]Q=F+!E+K1B%P8ZAK
+MDMWO-\30C'+;!AGZ.Y/%(MA1G",:8PY'3U;$ZO1ZZA[["1P2S7+J]4XD^#6X
+M3"6NX<</MLW&ZXCG<Q!<<\._%XE.>:TP?&YO7I_:?&1^$V'H/J`1`'UH5PUD
+MZ)S'-G#YZ>LS\#\6C7O4:&X/RKAA,0ZAE3H0T_'K\1^[Q1P%0]F]9^?2@^31
+M\E)HGQ'@<3/%8!9VDH%0_6HYBQ7S]EOK2J[E=RH7X%&(<&&OZ;1,2)VT#>YC
+M#YG((;+KT0'\EQ?KJR=E!Z?^-1O^_K4THJ/P'B,%`O70_QI/M4F/FZ,V=2?M
+M)D*<25IZ.IR/L,@J(/:^B^TLPI\&J2?BLJ"?TDXNL8_6^Q_@U?:-+P8?J=Y>
+M$*_/./HQC6L(]H?(8%HVB<)5+]^5"Z)[R=_`_VFE/^H=;Y?AO,7(:I,OK/@<
+M_.S)S_7;AI/5">IY]"X>E_K_J;#`9C%*YVS?5??529'II\I.+Z7*B_?>TQ9H
+M@O<92I_03SMTPU*GD\^$=:I%#*%0UQ)#\Y#+B89A=H?PF:,Q3/7,IBEPS+M0
+M2_T'_J8>EZU![KW%!J'C)E9^BPYIQM&$,H&_"L*17_/]]WY[9D$8JB,1L:"3
+M&VBQC8T;:I+$;!HBQ1L&L;04:V+%),,1$%1M)HHVC%HVDK0;16T:IFPE5&BP
+M:C19-1):*U^IMR0WT+EC4:DM@U3\QU<C8HM&HK%BJ9526DJ-7U+[[6+NY+[Y
+M<<[1]<?P)DIAU*/8]NR89QG+B?J[@-">Y>`Z,O9*`4$B8?&RR>()Y>Z_>2'A
+M-$[0*HH*"A($<H6#_"5BY%TP@D@@UA5ODJUK1IC^[(V40^_9J\'%L+)1CB9T
+MDY[1?IEP/*/]2T7$WYE/0Y2#54%BMX[22&;#Z`P^!6;HQ%@['`X'1$%7^0;+
+MEFZ>\)R#47:3WMI#5+.$$4;6+M[U&R?>!F@9G#;GO9<:HH84/+/A9DW:1\_X
+MO/IMGO9R4>2AK1T<V#C&;W(RK:PNY4V(%""@6PL1_$Z^1J*&]JBNQ%Q1:(L2
+MJ*&3)&AG&F29X>&LS:N1R3UY/O8&5O^GG_CGPKHLBION4Q/N&A0?Q_-T0OW-
+M2'Y26@?H_5[?EG#1W5V/\2U7_^<U\UQ-U'N,*UM^EFFK(TSZ=AP8BH/4\#D&
+MM`(=]Q%LT7PN((B7]#WF35SDX,0D%6#%-#%4.VA_*?^#A^-7<;=5UH`4BM-?
+MI\>1;]#1DF:&+JC<_!9HF$S8LH0,WZ>Z/I$CR"?X?U.9B(09O0I1J<(5+'^K
+M:*_NF8ZMHH^;_[[!ZD9I351^__#V/>^LT<,@P^2T1)L;=XOCGUS#&E^=:(>[
+M)^7.%BB9_%J_@7_(L]Z(_D/IPFB>2$*23ZC69?CZNB8,8V0<:82$C3<&-DD;
+M3D"#'8IVB,^\F/654;#1H3"4HOIV],C_W:RTB-:>KR]=/6O"]*J4:R>O@PE9
+MSYCKL`UR2&/;-S4W=O,9Z[$PBF(&W]!#F[PB=C+"LIWN-_5:M`)+22*,A),U
+M#E$8?)O0KKHJR*`Y^4)=GR<O/%UXHN#<G.J$TXLSI+@*%[30$]D&7UX&]>@[
+M0])$)"Z`:$?RRV',VV!EZ.0H-$7%1%#/=!T0!&L2<9KU@?$$-2JBL>Z`CI2-
+MZ*3"@TO;JE^.V*=AR.],'MF;I^P8,>97M\?PC1Z=;VM,-Z:QMV`5`(%MP?=L
+MUO^O6<FL>3!;VJ<L0X\>1=0E9:BVOC+L9+;_=WZ*IV&_:E@N]7-(O)$(CT>`
+M8P`SEF%6OG[Q=Y857F7_5GX./J;`J0]&0])";3"XE0*2R?QQ5=J2Q,!DEL@C
+M;-$\23+(RT81L>B21O;JAC,8QC>R:CJ1D(*HU;5&K"5IIH@T--S8X%*#P;1I
+MUH;0J>%MADW0+B]U\#`@%>;^&<?EG.D/8^2/"&[!<HP@,8$8!R`C<@,!*GN"
+M+DD/":7N!=3+.3K,\_?G"P?V7P0;Y_V!I0W$20T8N9M]0TRY,(ENRCN(?\\!
+M0=IF[]9R4F-WZ@E;\U@(+TKA/JE79@#IFHRYWI'I2^"H46T2A2?;VLP1E/4?
+MKQGA3,[OW';^F\?BS^)/)ZCQ+$@)+R_>G"5#@KK1;9I>NCX2M9D2++.U:4&C
+M0&"[*$ZC^864EE)IM=/`82`+&,T&L:I[6>(QY]H@4DAD\`&]QL:20JN]#.V&
+M-N4H0D3*Y%$SMZ"#2-).9["-E;\\ZB]GQL6<"<M@N=KWBY-J3`BA%JEP_HK,
+M1]9`+W)9!TN0SFXP9S#'>-&+5>UNW(`UI8C#]PY@VT-39O>;@8Z04'Z.4-*`
+MO[S+6%;2[Y?F,>U+Q0`D=68BPU,T`*"%8I1MH?8V0,8JV&/3KNIC%6%6*,E2
+ML4U1E53)%D51`1800A\FHF7=T,I[.$.?F.^9F)BF>&P3Q]UG0^>ZO1V=O@<Q
+M-TG\/(GU7B5\=_DH<>FO1(]>)2"B,7FJCVI)D&DX!@8K1GTT?S=?"#,'2I;=
+M:7@E9FCK.O49EZGL??W7:K;NMBQ62`EC8+:6QN@):!MIQO(:7CMKQK\9^0?2
+MA&'BO:\7-S'BYL4/+KXWX%UZO;E7.=W.X=EV9S?V8\1O5AX`DTQ_Z)/]*!S=
+ML^GJ^3DB+;""8R/LZ\/ZP(H?);D#U)&T=\4VA>.'![+J`>6Y$R3CA1\>J01B
+MD1<S`$J$-@&-T=-O/G0'3G0LR8IFDZ=B(**BW"&SK?"'#W6+LY2<UA"]_`-^
+M2\U(ZHR0&E;JH+J"T+(P4JJ:HKZ[VVN1!FSRCW`SA*"OAM%G,)F0723D#=RW
+MM*K@)S?CU5@]%>YR#&Y$[QN^MB\7OQ(:,C&%M"2FT,1'F,9BTJ\SCI/*5IEB
+M@WIZ"@V3AG#<?I9LBKAO<9&/A%NR[%M88R9([66MJL98F7SE5%D8AVMX#?;(
+ME@5I&`!TL.-#0KO@J-@?9<QXF2>E*AFG:GZ_];OX#-AW;WJ%\6M3GC_?0Y>S
+MTZ7.0MJRL726L60V,"1*B%YNE%T$BXD*2#E=O2?V1.C@.<:9GF<!KN.N%P,O
+MN*GSO^'W>6[6:NP6(;HB4J#!C"1L8STU$LE5_V>Y!H-,C`PD2UY-.W-01@V$
+MJ6NL-Y>^V-K&L;:C%X\=R[OSW>+EUX:A%!1D1E"$ECE8&5%LC(E&20;8FB)@
+MW;$HTHQ1@162P>6V1$:C4'C;K+F3,=9!D@H-(@;^^SK]@]JP\,-W!-L&.P#9
+M*UB#^+13Y_<3,S^RS+!.[(C\7;U>_/?#]IAP'V,G\3[S,XG$2^<D;?3A0MBV
+M>N5#X=S@EO$C<J_'>&&FC>2%C.\$),&*2-)^>!!(C2\XC"9945P:34D<>2&$
+MDH`\KT_)J3#'*`L!GHZD-$P,I8D)@/$JT1M0('W^[K@I+)"$XZ\6L\[C.-@H
+M<K%,D9`ADE!N>/N&[#76PWRZX5UMRFD@2^-]$<-V<+>#QPO;<L)GT-)LSW\H
+M]]Z.X49-_!PX:TV]M2ZU8S'[^&7&%4U0^4\Y/>[%]5UAK()RE)(:><1Z-&0Q
+MY*\'EGLZ3D2[Y&6T]'#MBAI!ZAJ-RT2@&.KAZ+ZSG#/BZ#F[A0TO!O,RG3&A
+M+0@8@/9G9++U3&86DN;'"9CW'A#-L>I";S*YI:N%F#*XP&@%KXH,Z-8P`QN%
+M37!I*I(=$N$KU!8G]I350B]"'D680Q8IB[/=,U2)IF:9YY8+SATG'<TH4%;J
+MD8HJU4"D;H*S:\OK79((<WH;,T,)C2[%08H(D[-NU=J:!3>=9VZ+NWR\YRU<
+MIB,A7E-X\2EQ\.WG->E>+U6(YN+N6L+@"R*C$48JB(8Q=XF4D"25>_.-7G77
+MIO/;;C$9$,"$H5,55UHW2&;(XJ841"%[[F7I>><)H90\[L#>E>,-47L:+24H
+ME51HA2J*(F?K>M>3#=]EW/8YZ>J<Y^U)(=8X`]G<4WO;ME*=A&N4<I3-#.S:
+M1H96&K'F/;=YL!FH8[(5HNIB66')N//_TO>88:4D9EQV?L:?;30]G*=$3Q:1
+M#%'*2`R,(5)'NX\EAL;"FVL4%Y?28%54>`TB:<,MU&V9_S_B3WMXGP<0F^\[
+MPK4!'8B%I(9VCA9!NC<H'#QM"X*G@53W%Q3XV>FL*A`0;"Z/LE%.S`-,=8J9
+M0790T-4-!H'A,&H2IGP8LJJAC;#>]"S$S`H$TA>F4"4,?YK+Z6=^NI0TB@3<
+MY@D22)PG>DX]!:/<GA8["_;=7CBFJ]4=)%%%JC$")JN2'<A>@MV`:4!!6"(`
+ML%,AJM%.V_LW6Z?#K+MTIEQM'YK+GXO361@F:K]]_2L/SLO8'/[_EZ+`:Z+*
+MJ-%6:D-R.OS_+C#RH4/&K/CL\7Z+%R?D[N'9.P'%5,Y&8];0^ZR\5OHG)S9;
+M#A-2<6<,Q/]$0]?01IC336-$&C+GO:_0[0VZB4VA)ID<BT^'#:C^TD&MY!:A
+MU[F!65ZD"-LHR,1>6%&([V9FRC]VN+,Z-V:WDA3*5&N2R\YB+88_1)AS<80?
+M5P?<^&\,P8^%ER$(XS#)6$$DH+[_8Y=\,-);M[DD'$V.T&K&#(-Q6$L;'7;'
+M$TW+*F!&1U\)1NC3')"8.J16H;&26MM\IR-S@,7FY;\4)HWANQC:*.%6R6GA
+M=$"<8<3+5E,G_ET/Q?X1"^,6;CQP`(<;:P]"`_Y?$,;">QQUN2MD-`Q=]VY@
+M##/E==J<R?K,_/Z*PJ&1.?5N0[K`[[/\">O^14/>/Y^[K&XW*2RB2CK>!VI!
+MUB_@$9SJF^;J(Q#OU6$C;/C4$6DS+L\8VT"V.>6B)0`C8B*"4--3*=]RA+B$
+MA?$$F!&,5GM\44@([R2KRJ<C),HD16NJB2T#2`LT-&(6%U4JDV(8TBL4<M/"
+M)MFCI5+*%1*:%918:5@F&/[QI+>=W(S[V\\+QP=VZY=NG9S=0B9(XX;+YQ?S
+M/F_$#[+N]SGR[7U<RPK(YTE8_X\XY&:SOXY'E\?JZTZ1/-&?!T-H5:<#D+*K
+M!P$R*T52LHV`SF)M.]O;ML/#3CPL+(\9A2-L>#@S)9#B-5F:A(S6,N&[$M\C
+MU(;N;Q*#$-DS(L9Z/]AEU#;@Z;1\=HL/"QE\A-,Y)B"?:8Z#E#U?/^O96W70
+M^MX;N;!QW58ILALHK)J*)=8/PVW=#%&#ZU;L:L\?1+57Q*(>8E,H$<R*2`5`
+M@*J_R<5*'B3Z)$B@3D)0KJXRQ0:J3&,8X.W1-\())_-NBS]!*33""(A(6H1H
+M7ZGT#0ZWV()2`N!-)Z\U.L(_.)64-*"9LT6JDKMU.):<[>NY`W?2G6]]>LSR
+M-<QS:^)EJ"2$32%N,1-C)LH:PUK4C%,N4R6$8$CA&1E:C3>G)(ZXXR?%BA2(
+MPMD*%2A:J=(!R5)).GSWR-OP6#L9]O9=WV%/XQU"YHUL-BCW^V\`S,1",`^S
+M?W/K7-JKA:T;U>I1H9ZE;=N#)!HC"31_M,X><9[,*O.P^8]?Q^'7U3CKSH*`
+M:@70"6QFI'&.$%D&Z?V4#UZ(DR!E)RA2J:+5"+:I0)=P,8Q`4!48JXUC;^#*
+M9A&AUP8TVBLE%D"%:)(QDD*\96\<L@E!HJ_6M0NP($HM&)MC31N1I)FEEQB1
+M$]%TZFH-NM:>LBQ-J"&X3&LN,:OU&$5D-,5'2314-UH6,:<BGBC9AA`S1K*R
+M0QMM-+1D"*C;8R+3RV&IK6F--ZU9C!AEH*+,BJD*<.3"U8"F&0BAD(!DA8G6
+M<T#-R210"V%I,\5`-@R98"N(C8VL&((Q9C,I"P1K:&VMJMF-B;,);,>5-A&!
+M6@"L05H58C36-*LQB(Q-HS(LR1AIY@E&800VHX]LM0,:6,9K>:33V<D,L!G1
+M=GN?2U=[6?Q)OOIG$&I`D<'60;XYX%S="Q"I>78#E0FXH.R^Y1\:!]_HJ3^$
+M/">1KT.K,P+]=Y'-RD,^:IV.Z>P#KU!DA$#(9E-&U/G8N(KIQ/#%5=659S4H
+MNQ1CC@<1^7SF+,CKMEE<]]N222\M04I="X;%'^/KJZ2/Q/3UJS1T4U4J;S:K
+M03;R25B$U+0HW(QA?C:T80A]NQ"]$5Q:WO6VYHOK_#73R3+<I5%NFK=K-MRV
+MBY5%MQ*K%;4;4;5C;5&VHQNFVURM7M:)+28/''W-GFYG1GK+X=+M/YNW":9]
+MSZAVDMF`.-$X;N&M(,.(:`9/!#PC-,,$#]&XD'FUBXXZ:`;W-)(XI?1&X$-F
+ME!G-:,_8>!Q-X+4J5.(KH:%D%D)AAN$)EW^V"^2`?@,,U1Q!C4A+48F*R"6U
+M9$R"&N^_WE&A.2OKS9ZX@7%%=ZQZHCULHBTZI]!A)/![NN5R'K,2HE@*$',^
+M.H''D,[U^+4Y"_7B82B0FZU@%0#:3JHEB<3?M$.-K[.^5-KI&>P^3U>"9F0O
+MS2%3/NW=42E0/G?H:GIOV<[_<8?X3]'NM2M.LS0:U0G"CC;J"H=E0EHD@6)5
+M-X49V!A^!4J8_`LN/F&=YLU>O@#R@H\!G!F%7G7<KQ7C>9<*,:N:N<KU>M$8
+MB)&`@L!@BB^NS#!,%!9?IW``C()(G$A02JB\[`0*B8&/$%AXN)N6UV]NUR-&
+M]MMRO3Q;>[WWM[5SS<\.]+TDEYW>VWBC:Y7C4$4'+QFK%-9(9L#,9((X,$@>
+MPQ_3^YSE&;L!#>UB`/UL`#YG0Y&P+KX6H@TVICVS'7^<JKR1<96FWV3Y;NB;
+MNLM==LD6U4=[(:>9ITS1":P<L^7=8:!ULD8S60QZ^RX9OJ,_44B+P=<:A%",
+ME5J&-M#0B``1!5#DC$8-HQIM#B1C!C7AM%DV0[O/.[N4N>;RNGA3(6C(VG!D
+M(R+R_G]:Q)/871[YTKT'PV3)8.-+OYX^Y:<MVPXFT_YIR%FQ@35@.321P_70
+M(^C.=BZN/>8N&HT22"@N+E4YC-QX=FHJENQ2C<W).4+3)"(<DB;\,ERKEQ6-
+M%6VF,5!0+7%52@HLM(.$%2F.4X\3]WQX`;;0F[)87Y.(C"M,?3A/5'OI$:<9
+M-KSJRC5MK#'6CI%#''EE9&I"R#8VW.C95>K./`T7-S:LWIHL>M9<*YP<5-K&
+MV-YD;`--(C`@P>,=NGC,>;&.YF"Y4P&4R%@-+&CDVQ"TP8T-Z)I&M:6<7JFM
+M[<U&#"LWQ1L=:++EA5@X-K,BSR&LJ`P+2ZP67&JW&6Q6,/\7,QXG)85C23;4
+M*[//)W04MUW2)<\>'OM;IMZ7<W4^;N*D1HQYUUP[:AJPC;,QK548TN3-B<HL
+MVY55-C2KE\+?%RA7CO2-RZ3NBN';R77VVEF-,R'&T96QF[)608TQLAJ':=:E
+M1MU;]XV22;:VX/9A1D&XT;PJQLF4&)@\@2R#*R,#'\ATJ:::AKS0P%B+2&%!
+ML5VA]`_Y$L,YP=$9IL+,M0Q^%F9HILS-3M=V)&DVFPT_,\LQEVN/!Y&Z,+(N
+M%AFB`QJ,".:PK.RTPRRO4VD,U;4\REC[]0Y,TV,>XX`WLQM:+!L3;;7J:AXC
+M-G69(VI+*5R.(ML@16LCC%8R*O9E9D)(8XAIA7&E"-A`;542%S>(0NK5*VQ\
+M9'O@C<;#)N:(QK!I0#&8X-IE2=A&VQI&I-#;3D"-IC(3+:22-%I)(@KKB8QA
+M*0O1!A18;&T1-DA1<+H*T,:>3T$Q8T\!4A-X)L2Q)*\]1/7K<D5XHNVR]=;D
+M+%>I!R+!.L(TZX4:C`]GCYK-M"#?&]TPJFR'!24#4>*5!4RWU817/B"LR\D9
+M.2J58>T5D$PY;O5EQH/W!(R6=@X6'/^-JUH^G^D_0?!M@#"$Q#3\Q-T(R[P/
+M<:W##Q?<>NZ<!./8&I`X$./;+L$`*/AHW*)0D)080B443\6KY>RZK]H0$P*5
+M`P5N@AY&KG,38UBA.++H3Y%!4609!,D?03RN\T>$CIQ>:B-HK]7PE!?`]%#S
+M$?B_"K_[#\<0Q0#OX.S@AW$-*/`S"'_$3GX\A`_%K*WJ'=SCOD4G:Q3G(?D_
+MA0\#/ZHG)^!2=CMJ1DC]Q3Q"@TI\HVQNAUN7K&(/>*2J:A!/(R)'&>&H3/%*
+MZJ5#Z$_A'IHGK)Q/;TH;?<T]A$?WQ/AP0WSMZ3MHG]<1_Z@7SVLX>![.!Q4]
+M+Q/D+?/F3T=`^;C^*'[H!N9Y2;.=O$R3C9=!,[*IJ"D(>'4/2Q'?YP@#.=?(
+M+SB',*ISU!P0<\78\N$-$E/.91QS`V<JK&3J]@?&"FC$0-^9]6\V\E?)Y-:(
+M"LBZ`=%TS3;-BJ5IL")A&V2M$)XJJ<.?G4$<0`@A+H7-3-Q+%$.#(1JP@"(A
+M`CGI6=FR;V`(_1O`12&F%9+^E-]ABKXN(XD,F2^DD#K,)"C:;C+X+`L"VD!0
+M*24B$#P<TU\;.7$D3/<(C(4HVBDB,8`D8R*9V5&1$A`&$4IM,-ITV:4H6KY*
+M]*KEBKY:K]O4:W>=7:5CQK49!R2Y<6%#(`9T`M$Q:E)D576X@-,$A-8:\538
+MP_3^ZRZ,!E$J=,44F+A](EL%Z&0U$:[F_VLZF7PG0/1Q2HUX$]/52V)[E@T.
+M(^[U%C>4@H-JJ*C"<RH'`L"H&D@$7J%G>Z6G13N<@J#!10[P];P-YY">@9#Z
+M-A[5/UWRV>?^_H-F_EY0USH@[RIZ"!)[N.J`77.N*HJ0(1"36*M@VP)EE=J^
+MNJ+5&@19"%A<&0$8*:7(&&9,WI%%)LJD4923,T%`%(LA#0RHH,3>P^O80,C_
+MR[%[E<,-SYR),*DPBG&E!_K2[:BV_%MKVKQ3X]M5RI^:=HJVM"B(>2@YD;9=
+M%?QI.-B:)+J5H*`W$'Q71TO,SU,-VG%:/#\I=OL_)$S7"./GZ'/(A?#953A)
+M"A\-J,TNR77ZM6?Y6?$89(8-D@P.A.^R*+!2"D62/8J$/1N$6';0U2'#PZIE
+M,BP/#VA.1(*22\&:9;\9$Q523-(`QH-V_Y>B4SE,D(D%"(K!<LQ&YTV-^7`@
+MOB3I0[(AB3GH8.PA1(8.2*,`$R4N9,+(9_I,#[E1X*#+6Y>.N(':0^F>3&CZ
+M]G[Q>U*V.D%E\^N54UZJ_PWTJ^N[/@Y0^_<R$R0HF>J&$=)\N95Y>^%<U<76
+M:X^U,N35I$R,[H%2-R5"F"-44"(4P:6EH32N/!IM_VI\LS\WEY+XN#ZPGLSP
+MT.?1BA\A-66BBK'L6#?F6]`7+DD$)&"*2(CK`77(!?FH!J\H2>&FS4,Q+#N'
+MQ;#@.MFK9,($Y>GAOP+EZ\4^=QU'@PJ=[#G3-L;WS/V$,:,:#$%UM@E"!WGV
+M*9LS0F6V[A<46144F>1@LR#<TY^]_DS3SR,I3^9P)P>AA&:R*9`K?&E`,8!/
+M4<3&`^A#L*P@<I$?DR";6-3>5DDXSU<PI"W5EAG;:8-F6TL(V'D_"@9N1[^<
+M]IJ.,/4779\=K6B)CR`P3AY[2R&:*BI,7,A[,)3W!A/$%+_5AW.L$-6;6G3;
+MA"P[:11&1%<AZU5[&O&_:K_4Y,]904?Y$U+%W1-J#-UB`JPN750-_IKEG1Y-
+MZ(LYL@YD1DA0G33BY(F3)089*3:UG*!RZ?+5U,B@2J1E%!0BU*.""WVOOG7=
+M=+[H[G>7,W=YY#QJIUIE8KVJS7H7(@SUF&UQED7"A+A98G=YC:LC,!"A"0>_
+MHT;)^^204\.X;1RS$>&.;=64,FM6[AX#NXSN8P/%5.3#S3)3,;J79/$YJS9_
+MB?\:?E/@9UTIR,*IY!2Z0:&D%,795%3UR8DMS4K+H1<MQV">+UGJ9'JKGQ*,
+M.;"VC.I.PX3=$I4KCUV[M@&D-IGUC/LRAAO$:DT(1.RANAJ0WS?)%4VXB&@`
+M<#`NUKH?"6$YJK/\[9L+-%M,-`C/[*G<20?RX5%X%:76<WI03_HYLTH,*SJ!
+MKO:[L`HA3G5#T\]EU4T+E`IJ*"!:6R19QM#L84P60+HSL(;A7H0QYJ;3GP38
+M.F\J`Y%04D9)14-$"JH-4-B%L63"::74Q<F=&BLTPV869"I&ZX:RX&Q(),:C
+M:L.&/(V9SWV[-UM5PG5OA@T+&"P4^SY.L7+83><=0T9."%(IJR&5$J<*H!9!
+M0I@$I,LQ+O;14BA3"GB=_X\]R'],:OMB1%N]G23C0+,/0,%XBB+\#&#5K#,,
+MDBR!B9\1)NY<=.XJH)S]E\W[BISL1<44/,W-PE*6;'L!R.R`N;#X!B%YH'L*
+M'L;>'7-K/$:N?+U5KQZMC'/59CTPQFF=K4:?&&F'H&;L6[4?2]QP)#/!^!RL
+M1MB[]A=BH8]W9F5XP+>4]I(UQ3"UB8UGD-DR+<`V$V@NBI]]7,%R"-'E)W#M
+M+)W<N#XA$E6#.S\()@ZW4L2A4V]!LFIKJ'T5_X^(S.8XSDN2M_(&W8&^;!GT
+M_HA0]?BIX=_+SD(DWR9'SO78GDV4<('UH,4$D"`*I!GA]X+/$,DU#%##O^*_
+M>--3XC>F*+%U]_4;/P._(=<X"W]>BQ1_)K(,F=&1Y-U3DLR0H;>"B]Q>J1%`
+MXF!:O\83'&APB(2#ENLZYQ&PFU=UVNE<;\/?/\VKWA0&"$.\AZZ.)#&JP"]"
+MQ643=QU\'.L(EW+^UI-_A]B#UWR9Q=D]Q]?H>$ND7.APT+0#5SA$EH+]S^%7
+M>^%4#))RLG\M"QU?Y+]<A^RG[GB3MG;&R`!%<0!&*%MN@9*CN8:/`8.P\]7P
+M^J#'E`C&#_.`F\*\9L'/^%?=$BDZLJ/]SFJ'SS#Z;(H@Z_N^L\^`8+KS38B-
+M":9OPNOW-@$SLU\U`Y_9-X*&9T'JPG,R1&;S<3A.FK-F;!$BDC&`+[3L^#"T
+MI#*ZYYZ))R3UF@=JZ!5>Y1N?**QDFT+Q1J_45HVYXY:N7T*\;E<L8F$B(L+6
+MN!9"DI,,@L#@`S)EMY8Q%>-RH\AWS.U&VC(@;X7)*"PDPE+MHI58,-64EI*(
+MH)@:D1AK-D\?TI*%.4)A(3\5)%G!$;:-=MFKD1A-%JIL71*0WSGVZ;^L4'4_
+M&:TA7_T?S.7_-8?!VTJNKDEJQ8TZD@4A#<D[V\@8F24*`*-3@E:U7)`;OZ+L
+M%$\$T[_[./R]Q03J%@&W=9$:Q18P.C_=1[I#-/\*&:>$P/HDXD.3L43,$3BH
+M>3]/3A!^7.!Q%).:SO][G6(3'A4@[*#4V?_-'0%V[K.*",8799W_7)*#RYTA
+M;9HLICFA54%(RB*4<G'+_-^1IJ8][LK$U\8#Q&>1Y",X>/KB<_V>86Q&+$/.
+ML7Q&1L9Y\&Y/WGMXCJ;,)(M**"HR0]XZIR)_3>SZ0=<M0/4,,@_]DT#2"GU,
+M-^YT7CE'6^/QH&A$XLU!@G#04W2`Q+ANORJ*U:-%^KA*T.3]SAK/!$#^NF4.
+MX[6>V3LH:/%PFNNW*X,HX6-E9V(0JTDNK=O7\">U>J@UK,/MM(@.DAAM85_H
+MNU\BC:S^&GK_G.F0YIJAM[6EA;.QSDP6'R)JR:3;?>@23_;GR0Y`OZK]^[>P
+MM$9V-5L?NNAKEV*!*:UJXQ=H:WU-@?;^%TG'K:Y/J37SM;`C;(*P$`A_*OQL
+M33C[:OW_>KS*X,DD<$60SH1+:44*1-OSW'Q&*_M/O>&#7=1R.XWJ)E+)1%G/
+M;BO$9S$0AX'$[P.J0CFX%?+26CUI&Q_)_HU;5@?>*&V9E;\\VX-ARN+<\V&!
+MD<!*9=WO4+G#8L2%`A($`K'*O6]<P3VQHR4&/H0?+G.#)U1AC4,EE1%_]I-,
+M;WZN#BN-Q*3>0T4`/5^]G8?[<^^G:N,(-)D-X>O%S`1Y!+1,[5?=JSLJ]=?T
+M7V?<!C8M^7>O&SW0/?_K->KZD/2>1^/TFU]&IAZ+U"]P]H]Q*=2U=#>F2^CK
+MR5XHY>.&/!N,?E^W96I7!N$B/1IPJD#!U)A7&.D$1UI%ML@JRF6EH+)55'PX
+M63`I6`O.KKZ)[>X$\AZ;*\9B>5R>J/J7!$EP-P&@46@JAU.6YQA<AB@;O$MB
+M6Y)`2+0GDXN%A;E"2/)5$S1<64.DFIH!W$D(^QDP!N&*%WG#%4S+SMLK,X&;
+M6*.7`#1R+?E-)"9B\?AQC,$D.U<E/H$H-X=#;*1K99!8-E%I,Y\-@?@_=_E?
+M$]MV-FPVL#<#O84(N22^S,SKHUS]!3K`T>J$B%>CJ3<Q1``45BARH'F=8JTF
+MTHP/;:C4;D2/Q]:W1PV-J6Q4;53!;`[B?\&O5'%?U+A'79J[+:**&*3T?*\1
+M$?O/5GQT8=GCQ?]%AC`ZV'[)JY#S/WA^EPR$]>^'EF(T25*"^C,^UOJP%=A[
+M$,W)&%5*+/7#$^ERNZH_B?@XL6?9)ERS%-BBJ#%!7W_#8$:"2"1M%F!.E-<E
+MC8S`D<[A5$KS),)006=&)C([-G"6Z,>D%L:UDIS/9^6AD^%2-66IJIL&D[9+
+M0:MY+V6OZ9AULW[CMS%67[;.L64F,J+8\5!XI]UBU`PF:?[.[YOT76LZW6.*
+MG7XSOW5U,OCZQL)CE&9)HD%-DY&0KRV[.(%8HB7VD,TU0?:-.RL72Q.2C"=3
+MD(B10^1GM)PFL&,-4`T2#T5%-3G363)XB'XS<1+1P4=:14-!2\<KAZ_HB;.'
+M"[%S?(W!JC)1]OD?J7C1_RW],P)QO\-^$S9IV(==8HQ7DHU,V=$`9$#@+V[@
+M;BE-,AD/_%!WWC<S=#V)Q)E;.#C>IDW<WG"_>[(4?7I,NS5<M2*L.IA<M^#>
+MU#[U[?ET;&HO\GP\[]ED4AZ80I:0J;AY;C>9+70:'6BI,,9&&9"-L]$@/TZH
+M5C8Y(FFA[.4@R,BV5@W4*P",N2M5B),2HTX-8S+$_DP"LJ8$<>(9&F$FE88U
+M'E4I71UIE:K"S"0J;;ATKDT7.\73+X7=YUZO(ZF[H5EL1"1Z<+(1N$8XXD(D
+M@S'!MY*US9R[;;VUK7%\MKZ\^L'7#O<-=^>E-;`O6)^0]+1A&H%B)E;"(CEP
+MJ0?)GA`%T20P,B]Z)YPYN;4V<V68FOYF7974_5-!OQ1S.`=('F89A#75>FB>
+M5ZIK0V3CJMVNY\0X?(88M-CX)E:577PL69:07P1)+0<J<AQY923V#`,@OC0I
+M5V;I!G%08PI,,XVU3>-0&"R*(BBQP=G\+`8,2.L^2[/!<MN9DYTJKZC;16UU
+M#:FV;X];<@TQ-)44:318Y73*2F824)C&V7YANHI&F+VVZ&^5(,/9T%2-U,@M
+M0D6,`T2IF0'F<JD#;P%J.J@+:($PW;!'-,9M!361)%"130Z,07K7(8`R]IOW
+ML^A@"0#>"%[LK@*`4PZ\.;?U<LJ9_-]J!XK#34<F+O-@`'3UCGX=-R@.$C(Q
+M56.R3*Y<W)R),X,PD,)8R9L+V-!/S/S<MF)L<TZ@#<(3:!#>?=5QV0PA5`51
+MYC"I!D:SZ2EM"F/`UH6!AM/+KEZT7CKKNVI6U=7;[_[%G!A<$"AB"`I)!9*R
+MXM+9DT1JM>G'G!M\>Z>=<HLA;FZ9,7KMQO4J-7:D#BG:O-7%O-;>:NNC<G=)
+MHE3N[9=W-UJATHHI#%O<#4U7&V^/5!IEU26V])P$/6S1A\V/^T="!WWDOV6?
+MNS,F;G%!7!4F[Q/*:W20]O#.B,U*8B]?>(#X&@'Z-C9F*LC4RNK5B;!C;EO%
+MF+$PDH48)/ESZ*@R\FJ&,8*(B"@Q[U1:8@+#.BF=Z_,7A;:2IOW5/49:G?C1
+MF9&C8P?1L+12V49(-0H1/&:7##%PJZ"F#-S4Q1@+7S(%U%%BBB*V;DLSQ]!I
+M@;I9E35+,DI&6E,YUW6G<GQ[KVVW+2,]G'ORX]2),8DV)]45R(Q1P;;TRQA!
+MY!+&#:;&\D)"%<=;D8ZPMQA6AJQ=44;O.VKE$:D^LN,3>VO?7OO7I.;L7D]+
+MRI/.G=B**Q!MW6YS7.5S72NW;O'GCNG`H713+8,FZM.SCS;;O&LKTQ%W8L(L
+MBP4%4#'#=CD!TS*%PK555I2JJ,*&)B;NNN^TZ_`;SO6G#==W2)2-4L46&3"D
+M;AMVW1B5%Y*I1->.;X1*-1C,BC;5LK&K%_5'OON?['[;R\^'208'H'<,9$`T
+MLJ*5FF4I&"<F`1RUY=PZZP9A`"4)1.9B"ITA_46%A:2/5<B<([=B&.S"AB>?
+MY*HT54D,1]"_'733E3=75S#B^/LQ+7:=0&-.H=!)I(N7F##B'0M)=2TM*33W
+MVPJ$%=OB[5S+MA'^1=@Y4:Q&)NSFNJD,>^)$#K,N01S.J@X>7?.,3%[W$)`D
+MOK#5,6K@9P@:'OD!A+2SCJ8_+W#SF[Z!)<0-MEW8AR5%CHW:2T%$/*LW-)WI
+MCE7=7F=1#N6;P4:BF<FTDO#)O$,2:+U(R>"HQ%V:A.W0;PD;&]8G4J0@5=)J
+M-L\*(Q%X;59N;K=WAN,MRNN6J7-QX9H,GF$/%/`-W6UW[*&*1T6T=%H*HH%(
+M!=C5R`7OU_79HQ^\L`/]9_2)'C?H]_^G>[T0W@WCP,S,=7X;3#A8<!#_&:<T
+MB&/6R@.OBAC,9<?ZY9C[.&$0O7\WI%H0,AF3><*3Y$782W%XK0X;E;;S05]R
+M.E@NM`);7TH9+!HSO^5H'S>/>N`FXVM4F+IZ#H;AV,RC)KGHD@<I\[]+R'%]
+MH^`(7$?)P[#[.PON#EM2UC8P/51?HQ=_G\89D#ZOMNXRAT`TO.AL]+\XQ^=9
+M6ZTXLJ;EC_.P@%@:(QHKJ(.-5R6Q]0?LW_"^%#[]G_RSLZ_KZ$:?9%X\G.U;
+M,7=V]-XA)O>/>-PQ`XLUV5BL.]Q#>N09J&H;=S2YT6?0(PTPY-<L$C8&!NUG
+MY;.Y^_.$MG%.=WH9[]#\_>;(;MN]4,V7=%,V;DFY(<3#TE9R8_6ZIK&/*)NT
+M<ES?63:J/3![7'$.Z=W,N[Z&B!_7__1NW-<T";$DV$1;]3\IN;B_)3*W%]:.
+M94.N3M>E'H<-8FPKB?;%<Q.M]V$W<Q[M[1EANP>H$:RZA)+K'D,&/133U",U
+M+1UT'#0./#:;L05/6T*4NUMF#;RZNG]-M+JQ4B!JS;A<T]72ZXL"&B%C.-_P
+M1MBN:[_%R5QGD4T6&_;GHN'N4]YX93O/=IRR+.NG$R+R,+2S3B>>PADSP6NJ
+MNB-Y9IK5MVR9$L#Y*9>'7UHR=9[R'S:?IZ5#XZ'190'[]@:I[).1#G='.J-!
+MTW\)?C"5(`>L/3>7Z7+"'F-M[<'Q^/_.BP7NV:6)O)A"#HR+5@(O)+S$*L4O
+MWV;V#>:8G$3W8XMJM.C48TMFMG&D1@H+(1AZ!XRL;1GKTHB#A8MG6B:MV"0^
+M`'OS&1I'$XHT.@%:&T(;26R3&O3O]"V)MSFY'2J(;1`62TI(*%)%E,1,-*DB
+MQJC(FHS_-^W5_/Y'";3TQ1`]W=$DW$TUPGC._F.)F1*LQ\5^S<@#H'C.,0D[
+M<O=?B?HL%Z0H/FV"]X1J"(*"A9:Y]O6,"7IRH'G+3GJ-T\90[F8[4<%_*CH^
+MJI..@9J?EF=INUFT:6Z%H30V&ZQKSG%HA#\QYETB4D8`H`'F72[^1A>9?X0R
+M1(0?:QB'_G]8AH:4'*JI%B=,P*#T"KJ?.4,))J5?T?Z>1T%Z>3D]TQOZ[9ZO
+M?.H^6WH-Q?L"YA6+5CY2'9;T5[`G'F+;DCPMQ+4[B+X,3+NI,('MH;GCK[V0
+M=_OM99'/-S1:K@++)]2J?\CTA^;/5=EMSC_Z6;]2+#B:$!$(_,59<2JJ1&JD
+M0ZXT<C##$L*+@1,(W0K`AA@L4!04%*$''\?K^Y*RR@:1)^8SR?'KI*5@KE<K
+MI=#YE<MX4&G\8]S&;L8S"B)IC4Q1UBL<Y=AH87<A%4,BQ/.-7#7I*@*2SVS/
+M*9[5#4AW4,$,L'-YA2Z`YM)EWW77G[<Y-`BYY65@NW+&PLFVL\Y1&,6:`&@<
+MEY\SE))(L505BHH34I)K([+:MS`PST/C]W(G4G=9]KW,K/IDVY[;?A4&,4;X
+MQEH`H`(R4%_4D/L&+3_&8&R7=XT=YU3Q1P(/RQ>2-UJ:RQELA]#K,<UMF;(S
+M2RT2>/5C:-:6K,I,',-:)K,QQ.A@9HS$:CABP>:0:=)II"+-9$.1*#B$BH>+
+M,ZEY+P$[V-15JBGL:4&I",M=U8HU90'B#3V+"4R;OD"(#S3GKG-Z9GN$A06R
+M+X54?:LI\=-]^-<Z-&CB];5W-$H'$<)#\;!M6)^CP_8NZ$Z0A/N+7Q4X)*H`
+M,<@!+=V"XDVD-@D9[<GB^]<DX+V&O2^&TND4ZFM20["6K]TZ=DFM=[%IGE-<
+M8GT^T_-^<Q`U8/HY#0SP904H_+UR,S'HYNU)_A2<B?(?OTYF3Y7C/V>C=NE,
+MXN["I!PZSB5#&/%E:JE#TC;A_@VS'0F"_8F)3#A)2+9PCM6K'?M3X(KM+/1G
+MBJD6G,\L"]W",KKD?I*W.+0"1&N<9;]=.W7)1ZUILH+)Z(9M0SN6[4T9E27P
+M"0NS"CC4M,)CJ_'?/:;&PO)+;_K<_Q.8YY\-ENXV$1@V$,="G>DFPP$QTULU
+M99QBKVDT<?MN8G/T6M9J-W'L6!/ZT=^-WL_`K5+TG(9*W\4!ADTX`0]Q8Y&?
+M*-/9EV]S6H$0M83#>.&I$88>F;7ZU5G(E0RL#Q96#P_#8>G#@LB86G7F),N9
+M+FS&^.JQAU[0-L7[(XS49,L;5:@SI"!PS3>U(,@K%3N5!].[[Z0[$,:LK+%W
+MVEHOMZ:*FO)2.Q75T3*Z,L%24(IU]*S0S1R[&S!F.$DZ-1U:?&PYN#U$V.0&
+M-LQUKOCER[:3;6CB;6YOR9FKHD"8X;<`<0Y#0ER^B&<I1!C4C_37BK@9,D!7
+M")9:V_)MQ,2Y9,1OA<8WQ8L?1X^3QUJ/):Q\K/%PMU(]2M+&;/4RH\'NUF33
+M1V3J=`>$#RLY9#=QPN"P!(!!A0$,8VP\79A-,7#EEA(=I5A@$(DT+,AC0<EN
+M;984#)&#(*([<**HZ:^UA;LNT;XY3K-N12:9#O8')G`QO19#JK0;=99@Y'I+
+MM?<MB+A)!A#L&'7#?!ZN,Y0&-$)"+:DK-FF^5C9G;`HQCWVXU$PBHBO-A.>T
+MU4NK2Z$04T+NP5KFW8AI/3,02<\,C1)U%M,+P47N@UB2?!<L@EW5@/[WXGL=
+M9%^87?!D+G[\#M*)P>YI-DY@)F6,B\Z97O3!P995C#!Y*3!&6#O26"]S+"X\
+M90[$@@3I3DOH"'"AX&\>.KVOXJ^&RK/PALN0!R82<MM(BV:=N#DW.<(F39FP
+M&(PUF`T14*PEET0YL1I`(TLRLW&:8[9VM6'%$CIVCT(@Y.$I.CCFN:F9/FZ`
+MH\&R32#LP`8]&5P@$Z"/<J4YL&B@\190^4S.$S`]=L)R8E$"2B)>\.P1P@UF
+M4PK07:8D0YRP#AX;.7IY;3L#20=ECAZ`Z@/AQDV#BST4<*'IWN."H#+.+*"@
+M-E/B'97&"I,</FI"$I$4:!(.6A@L*+M#`%J@E(O((;"F58FPX30_0#\E#?,S
+M;23@S?.Q@[@W4V=!*:W"-P?!#6J%K6<TSKA[U9Q=6V]:=_=7J@BO@W9+^$B<
+M>T7P=*X-AV!HGF*D=5)(Z!I*+W=/`B/2*+^3/=VT9NX:3EH+99#;9A[HF2P+
+M,ECV41"<BBY>T,1@B@](3DB#:"?*KI08(]=,&PR8<+C<1!CC2'#KMNY#WNB?
+M7_?2V8Q?@PD.\._A>+\,+\::P[',3=5OMGXX$@Z69<46PK</1*4;YU7<B"">
+M*:^O'%#S>_.DT@R&8J#GI\Z53D\Z@,8(I@V<P-XF_%^O;U`;O;.#SE6!6TW2
+MH-OI!VJ7/'#'NLY2#%>N1-S3>:1HNUFRS6#$$$'T\RVA`]Y&^-IIV4;'DJQ]
+M$,[0<];9B,PW#B3R9P$)CMD9C!EP;YW$/1:<>6F()&Y4103<5IKFKTC>1`\U
+M_L!SU95TXWF0%AO(;,<IQHY?`1<#/ES$2K*)S<B8X--@MFSQN.L>'5YU3/+A
+MN/,<X'J>+%R7Z`?N[-O&FH<6)+U8H4'(.^NS6@@?L'>$X>BU^DTOS<[,W\$W
+M=2Q@.9Q]+"]%T4R:FK0!O4G!#M%@X\$-Q!48P3&=&\9M88Q6BB\$'""F\I3"
+M#6):;.!'W5QB+F[1S+%PY%Q4)F.CK%X5Q-7UEIR'(1DW#V2B@YFQ/ZZ_X1].
+MW(\>+6'JX"L#';MC>O;7`?GM.SV&!Z:`(#D`=NOR15AH$<C`UD=E`Z-G'^1P
+MTO=Q-TFX;L(SHR^%.L[O8UPBX'"AI^:93;`RPS(;9-0<&QNM:T?0##\F_0U=
+M.+?C<(0Z\38J@PB,CH9_^K^T]]AS(&AN8*'C!=K_X-'X^O,/3C`SL5\3ZVJZ
+M6*+;L.6V:]>8]L('?M:FXUP-YQWT>MY@#%^FH"T,8C2D::&UQBFQW>>H.Q!Q
+MWY((C]ZU.)R]/2^UAEA/CPU_HX80=ESPR5U8'2L<Y8#!#FG08J4`:.,2XC1D
+MLE)<Y-H-HRFE?1JF)!-K%],`'FR`N0<K9<OO&V>U'.&P[1;)^HH>FY&'CZ1^
+MCFG5F7)OY=JA++K@AAW;R5.3;9-6"PI.L;OM[5==@;#1F-0X`^WKD!JH`9L;
+M<$&!Q:VK,=D*^OV.HZ6VDF;<2<I%NVPRQ=7#2%P(N`VU41=M;=.B&549;-A]
+MWSTI,44H*NPU?WUGI90/L5Z-I`R_8T:A'H$J\(LH-4W97/X+$L[QRP!4!("D
+MIZZKX]N06V-,7[:B@^._<76]^P^\];9.A@;TW0\]MKMG=E(%0XYVR"R(HJ*C
+M/.:GCSM3O]^@T9J^*P*8"FS%>(X?#\WWK<I0N,C2C&%\PBU(0.R:'4:&MJC;
+M4(UH[+P[=:.$WU"YMD^*T(<J![OU_V&#$,X[6>$R[UN`(X2D47=T[(PX2,8/
+MQHBC1%8*M#[8VI3*UO+E'G>:]=>GFRKH,`!$3&B2I,3-+KMZ\\KUZ\13WPRR
+M4'J]U<'>WQWQ?2.W85<X,\=I6FV/NA`L#GS),'#3K#;::P`TZFS$.,C0P:F2
+M.L<B[7!UZU&,P1PBMW5R4,NL!9-LX![;X?]W0.NG7_(J<W@H^3A]:.[QTG-G
+M*6YZZFZ-]J)`X*"V^W2/C('\>/P\]G7@2'S(.WBZJ"=-V7>_=^Q?UO^E#ZSU
+M/6_L\CZO!-2/Q)KH<K)5`I`'&D9\\#`J"]&HR"]:1:FS`KS7'81"S+Q1[A0G
+M_+D//PZJ!DQ.^H>]NM!A'^,!O[3;6>)]9OOI"JN.H@.6,,87YC]\O#888@*Q
+M>0>E$1%$^/Q5[/Z%$L\R0^/Y(^KUI@P?8=PVRL[OJE:QV1L8TZJ6F#Q0M99*
+M;)BP:PN"M<J0R0RVP/K$G8?^9GIGPV=7\[V%_\$^]3R?6UN?W?55]*G1OHD5
+M8I!0GZR&Y\AGSBM\_U@=)/"PY;*^#97D8O>0.#B:J`:,-7#^,3)$,/?$=(=^
+M(`R1"2B.I/9=(OZ?*O]$4R@X$C#2OU8$N1`%&+[>)^Z'GO[J7S$#HHC[*'-=
+M=0=]/[IA`_KAU'U-X_A=U\/`^K7N9S.YZ2W^<#Z,NB!^6<''GIL8$CDBXX'/
+MXZ+Y_ZB+_\ET+IZ;O;6//;M0?HB'_OO*>4@\U$\I,D7Y4$[3O=?\VYY:+R,'
+MVG54F_Q#TGG:#KXGIX)]3V_RK+M/XTF.('4:]9Y"6AK"`'CROVJ@30E,<0.4
+M('M7C=.#Z)UIL_$8!^>\U(!H07V&[T;7Y_*:=R=Y#P(IZ>?<BGHHO@PV\`ED
+M#^B.I(ZHI[/-ZIF#/A$?">JC461H%*HH.;]!4WHCG2$QIZ*??G>P3YD/2<G0
+M;**'W(&=#V/%4'EH#=SM'QH&PFE"1U('R9O$\?.ZPH/:Q#TL?F1\&![>']$.
+MWUE'+_^:`T(!\>'-0\"!GSF(G_F"_$ET\;'JX;6+[2;UO7JK!H0^U/%9<I^E
+M'Q4'],[6>XAW,3U?P?BT'P>\H'PA%>@GJ(_?@_-C^C?Z_GKZ?%P/53NH=/$V
+M2&[S[,!'?[N_[BGK-2/O!_MMX3#_-7#;5E73?X0D,D';0?4L*3X,"KJ'C8)I
+M_QH[B!U4Z.'Z8/Q\VCHIH]]0["'\H'JX]/N?+=)P?H\!YF?J@ZG-T??CP4.`
+M^M3T\V;T\R#Q&HA_E@A=\/M=*X@2)=*/\YQT<8F]+2;6+F1?4SB;$RJM::$/
+M.(C]'E7XJ8^@HE?,U(4U&8;5D%@LJ6Y6"N1<K>VO/.-Z;E&CWD-QO:?VZ%X=
+M7T@W49_!SA2:-[PUITG[IFRP<>*.C>L"<?[49LWRF[G>9O3HOF/6'%'-I+??
+M@AE%-(,G3N-6N"/9)`JRRK/4D6"`0(F2^(//SBQ5[@NE44BZ,QL^,BYD>^0)
+M!Y4@-?1M\03)HI4=V)]O3X#MQ4Q43<,X-8:3_;0CGWA/?UXK9>U\AFP1[P,J
+MGRDZB=(5P#-+%WO3RUA>,3')#C!X=CEW,EBJPCVB#==1SSC6ZPRY#ET1M,SX
+MR(,O#1`-5J)LC"*-08Q]4C:U)S8M9G/1ZKF&\;C".4[;<U5Y3X_&^%[]04A>
+MWP\NB>-UC>EU)W<@)*1I,D-*69FCEUO3F^=>_+N='/.\B]^N>+I@U&^9790A
+ML/7>O&73:I5\.T[I,5S=Z=L:)$?'MU$P-*QAGI>>!1E5%5!X)2!3%2BIH[NX
+MC=EZ6=N[NE>=<+N\>:@A@VQA(E'PR$LSC%F)D;(W'JQ@V0L*I%(R-QXZ-T@1
+MA)!IEF5$9IS9FU;SD'+LUQI1K9#.9S`(+`X@M/<5N:437%&QF+:*8#&FA*.$
+M@;Y@V)QK08YA$0]Y#N7#EB&02$)$@DVE($$4[&-,!)E_?X!KPYC):8\]>0B^
+MX?R//;9N,="(NK-60<XX73F+`UQE%)G\4*%.9<4Y]O;M@A1B/C\WX-KQ4?@I
+MN0(,DT?%V4D@QBQ!4'(:I#S&#I017NU75=2T''&SRO=A_G_]UX[Z1P[)]-9R
+M)/RF%-HA_@P-?\D^\V^%EO@8HM2$<^)Y^^FT$_A*CWL#QL1V44<N1_PB#!*!
+M^O6*@$1DO*":N^*B8`\/VZO$9TCQ6>UOW8.`S)X,4U,^A.1EY$-VE20Y>(:<
+M>>@GX9\OY]&A`754E"`FZ@_P/FO0^\_-Q"'X+-4G]E@%(H$)`N/!6B7$D?]L
+M)8TGB.80$K2@[?;?6QQD1J.^,YBH75\B+Y>(>EB^%G!0<1"^/PK!28^@K6W'
+MWK%1+Z.JRF?S&>8+RJ&]*2T%*8,932>LV&&22!@1"2$(PIFRMM#`U/#H9+WD
+M%WW"5X>*,I@`*$6`;6!\MG4FAOJX:KX5'\-JZ/-\UPK*1'&\ZM@1HR$T)';G
+MV#E`!.6:!115Y=9I3+9E$4(PYUV->SL)`[B&F7]6B'4W@UNF![=V91*P3=U6
+M8$V:W<7NK-T`+YN5T7<,V]?MU4T>]DUKNO!V_]%SF(S@M9B';+`.8C#!Y^Y"
+M_]"M6`&<BGD\C$F^K+&:!NW---"*9C8T-<0W_FJP3S(?4460NG6"60HFDF7%
+MSJ27!L1@35[)&Y(>7$N2(1A,@[&[B`\,IE$A[90P13RRI\,X2;K(ZW)9(/#6
+MG]F3ZU;`VVA13HT*,&(WF5/&"/J0,,5S=FW,=Z8#MKRZ1KE7.'.K#!^\W&-E
+M,I()BH6-["H6HBE.X,E40]@P*@@NS!N#DV4"BD_;_<)W8$Z%]$"A9%?>$\\+
+M*1,\%J.IV7Q8*D)]72@FL-)JBK5R(\,X6`W$%"O=B2X[/7R^>GD$V0*C?TRI
+MTQW]9=W81):Z"GB4;3EJNP2ID\@,+L$#P[:BUL_9&<R8+9,+4Z5^&)K%6/#'
+MA;/ZN$B[:+T\0VA^+S]A/TSO+]JP7V>3W'8@0._3^P\-?Q\-A_XX'O]_P:UK
+M@;//`][<U\<WNW"-WJ;B'&8,\[)$3+?E5C!D#CP;H20S8<<.]F2M<OP\.%3T
+M6@&9+T#B]KL0;$*3(>&`/>6O2RCR-,.QSQ18;RH@YX/$P+.0C:<AU+LKE[)Z
+MT[C*#T\J(%/9F5B;,@L'+"\2)O%`TKB&,W5F4BA?+2<`[:S8`FLAQ1,@A]:;
+M@)":WLM2.%;+Z)O325<V%EJ#FXR&N$L8[$;8^"*T&_3C.K0YMLC@Q&#%G<"]
+M,`YLB>D2B,8%WW%F&`J13.%:\5G;#6T$@7AW(?2L'#27^6()9-=7OD"2%4!Y
+M4H1IK;AB,Q(:C3C<L_]LHR(MP<-F0>>F</L7-[LL4PI;AKOD@T[V.-F;YO?F
+M\.L7#T]A0Y&<3@@Y,XM<F`&_!BVG5QNN,V3F4K+<:0>>BY:HH,%F`G$)MZ:1
+M*HTDRO3C6FR]\7:M-1#U1"O;L0$\B;<0G!B&6R+PQ;C3/<BRX[<<P!*D=8X+
+M@/H(P194X84ZL)(%N-WAP2!-TQ)%RF:7#D328DB^$'+&P<X.&5CBP>3-,`MR
+M3RUP]"KX:S6?";!9G2,UWF\<WD8-R,70AE6%5`C-D;6DBU&UR+`.;`"801`,
+MV<F(LW1.-XHB3\V<1BS;SV/+B3FA(!1YQ(@?:_G7A(XK89<-R9J7I`2D4C((
+MCGTT:)366I:ZB2YH3WE@C>->'][A$#*Q=T6)8&Q<%(V!:JHE7*0`E+/L_Q8&
+MDWM>B*5L40E2&J6R7GGK"K8\'H*UM/Y.<WG#.)Q<O>`R[X'[?#W];ZJ&E^-5
+MG58!W+>^M!F9FJCD.F&!?;UG>/4J_M?>L[=Q=TYI]$':M.S_J/AG`QAKT<K'
+MCMP[WZNH!-\/J'YF1#C=",F<YF*D&TVR+H?8+8MS)%A`6+6`-)<,6P&L,ZVS
+M7C;/Q'ULSI40#PF%XN-X$49MS>9.\V=ZW*)'%2</KK:N!FP,:PC:."@Q!Q:U
+M3B-%^-X7`,S65"0R82R<J'2PV(;'@:;MAL^4\T*$"G@?P6KB"2R!40K361);
+M01HE!52BQCU#Y`;!^(0@Q*[VMUWHFB7I4_COPO//X/E9^H8?X+.2",A\SS\]
+M'<\/5>T^9_/LGU-;5W>90O^)HD]_&\:A8DM0U5-%I`C:I;!PGS&C0F`;)(8D
+MVS)!$9[-@KR^,^AGI0`[T,7+!"H!`@,$6`A(P7NV&B=!'Q$:4ZKG2K$154H4
+MRXAALIJ+.]]U]'<)R.K(*!N;D.XU)@2DYDJ,);"D%B\[),9W84A_TL,F3%4"
+M2`0@*5$>LB)F>3T=')Q#VY(23-`OB?A-(+Q@J;4P@QMG)G''XAD`D4K-N4<S
+M+N,L;B1?;0TDM0'$;@-LKN8&E*P#*,LEEY@`.Y#B(`I-2I4B@(BJS\#;H?LU
+M`\ZY;C?TU)2&B4'7*`OB&B3"`**`JI[0UA%N$Z($##`6!E,]*RD[[M.U116.
+M]#$7I:ECGY(9,>M0HRP>QU5"AX2'U@@KV$1`P@/E(B!1I!3E59FZM:J!]C+K
+M1P4#4L[6U:V&C#WLV+U)1\_QQXD[L[:S>=C'<Q-@SX/^?BK/J/79@W*YZKQ&
+M2Z;/"HE"?*LZF%H>88=H0M.*N?YTO3F*BS_DZC4[YND-K#B88GUN"@BBGLVD
+M,TA2#UZGX=E+YFN)Y?2F7K//^=OS:5[/T)+G.,)$#F0FA1*#J6+14X-L4Y=F
+M5D,$(R.=?+;6HSW/<YAP;1S:00&D:.8=2(/(!A(%M<#Q_.TLO#-!*3X;"(AM
+MYZ#D3RM;A*3H9/UDT]'4\@Z:VI*34-EU:@K-K0@J"#$B@L`]LZS,TRGO$_;\
+MS0;?][/!T1UG1'H\W7XD([/X8;FQP[Y/>T0>1IMQLD<!E%!=J4RJ.)O^RV&3
+M$WDIB)3/]+3RX-.LCC&IVN(U/57ISK(W:->AF2+L,4#,+2N'&S%@^/60HJB,
+M%BO-G$8&46?Z_QMV\FW<:32MXVJEM'12E2S!9:I;.7)IN$I3SJZ05=W;0\>,
+M(4E%+0U0W=/(E21E[;*B_2+[&H1Y]'QM?96S"":F$%MO%*M":Z>@GA<?"GVK
+M:'?^J_OZ-0,W#]7YER[!"B)>`DL?Q]!ICGCP9K%LD/,X^?A93`*G$5L;L_;S
+M"&G+H1:D?C(!'Y%`F;*?D&!9!%V08A'%T[FC01;B409C*@55%7%@I+-I,#D>
+MDL;"<#Y`['V6G@]]^C=>+VYY4WE#QSG9T',%0BD%,0Z67'7KY8TH`E'R$"$D
+M]NV&QZ^QAWN.J$G$Q*)`1Y4][Q;%@@B]N%(R@3B%212$Y_)U*FA13]]6E]Z"
+M2LJE,/9^Z^WOZ],<Z*><GFIX,>G]A0YKFI3"9(!G$4J!K8A/T<W8/91^A#I8
+MH90F4<3KPX)W1"^89D"TJ/W8\I#_IA\;S=:;Z-4/BWB_JF%GC!Q^9XOJ<&9Z
+M`YBA#)/(:K1NRRL,M/%P6IC$6"BSB;W/\;\K`%CG6R]4&(.VLFT#EK.Y+9:N
+M%*%I:1D'"'-D8:=0>\WKAOMW83K?%E$<%\:R+X?5K_<K70'OB!2&SE??I7$U
+MD535U8C!&!<53MI83,].Y9Y9?,T9')4F1G,XBT)3$Y9&-?%EJ"*.,TT18XVV
+M-O-62.QMI@BDR1YKAR69C<#9]+<VMLPP0V,`S+H*8+!5BXN<>MS]'^A]S>)G
+M_&TOV?7?Q.<KEZAB>@1CW#\+AV-.C\.Z)7S0A$[?UK"$:4+%5@4,@:`&+#C,
+MGEZ(8M?^@L/[,AAF]($,X@?DB]#V_$V#;_;I?$P/:PVALHPQ/$/S8J_L`Y)F
+M]:QJ,B>!6%P4AWMD!A!/BUC`!W[_I,1X=R;`ZF0,"SWB_ZJCGLJJ"<PJ'#JV
+M,$(:#*^#HO79M)7AL3W8$[4C82!O)3Q2FT,LIQI2^D<^4[X@9P@=60GFY*4S
+MQ-EW7X75W:G]K-1ZIW;\E`<9`QM+G6>P<<\.FL=*RN]S!<5\,0ZK(B`#Z"C3
+MU3RI^U1_]?PL$L?ZZ32ZY5.<%BHQ062A^:+[5+M)3W4'UH7!CF*/-QKTG9Y+
+MG=L6.P5X%<S#[=W36^/:CIH</"H'[('!P#A,^LJ!WUU)R$YZ&_;&C-AX$=7"
+MQ/$8_V\U<&Z+AM>E^E:[Z&6;%/?QK)V&\!_?(6O+,D(698YKSO4YF*]Z7"W<
+M5=`62&^2@#\U4)?`:(B)^7W/_;G,&?$*Q^Q_VW:HJ,&*LQ/UMOGC(C;)HTYC
+MQBGPNUHV78^[YD1T^CX:Q9.)RS^>D\?VM>9[U!_,?TV>)YO]SAQ3?])H<E_T
+MKL0V5RIUS,%;+*'^KXV78/K(9HI2*QX8+/:Y!NP4+L0M4A8U'7,<1]#E",**
+M2?,N?<M`SYV^CS__/?BW/L5DI"J!550I6<O8L0Q@NFJ[C?]V@_WY3Y5)JQ89
+MA$36.=HBB,6-50N)/8Y&.UIWS/M?\]GG<>`7NJRQ`[CNRHQB_R[^LR]789>'
+MQSE$VI]0EJ:@\<Y01!FN)"WBC:Q(?^_5I@F`>2INQ@L^60\A_M/COGLWT%@[
+MGAJ.>A[#KZ$['Q=/91-!(.C"0=7%D;`E0J;[4I6`@$]&U.JQ=>.S+=?6KM;/
+M^&#G/=SK!BCC^$HLY\CTNIJ<YL<L\!6G2_`N#R.RX#%=+X'7Z[3]A.N8)0Y;
+MJY=;/V;$'NX[K6#E"+I>@GM;OU-QDR+^RI.>N75Z%HA-N;$)-28@KB#R(TPF
+M*E0)((0C<+=>?[&;06@Y*T;\B#HYJ^^B&3C.2-\N$R9A2F:I\5D`6`'O_BSF
+M(MZ)[\\OG3N4S\F:?7:`9'KF8B#8$S&*+(A%(`89<4*&T*0D0NI^5D>5"')0
+M':15@'OZE11!CVB&@#CB944Y[[-!:"`7110ZG[GS?#_*SPS2QUE9JLA;Y?4[
+M)(BS[*Q/[B=JWBUX\JF^*E$,ZJ"THFI8HVQ+N,JQ9=\[&[,$.'L_^5377%Y!
+M8`]=$_M>Y9SKPWWF@2+?B1(G$$U*7-SX4%<VRD+88&`(:HV(#T+#*!1$-W"H
+MG,3J;:,@398`>KDFSZCB#GNNY/9Z1K?,36:<M;/L6J%1@3GKG./+7J:B'B='
+MJL-)`^;I^`<UW===R;NW$R=NQRFC($0P98H(KK^.KQY=_H=M].PN*H*(L7UX
+M9WN=]L"<S"'!A*2!&,,I(:<VFIK=A13/A7D.GF^C$<:#]N]G'UN?!;I\J;W;
+MT>6F[6FO,UOD,5D.$![54QFJI8"]![RHOU(#`]E)N7`/TA&X=T20(.B&3"+%
+M-6V824PT9DADEN&!:0ME&,H*9_C/#TN)&WER$;$N:F\-=H])8-D_@!`N/T?P
+MH#JM](?S>&_X/I,FQ)?0!8,.0ZH(!V46#YGX#U620CSQQ>+PVMD&]FTW'$'"
+MQ4C@\BK>Y^+J8-VQM#>2#9(Y!F-M6^FX.F<,AD:9(8PKX6%D$WVLTZ^#7.O+
+M623:6CD)-4W>-O&+X^U+(\C*X]W69A!NS:1GCV6L>S-;9;)W$.K&S&(K(,C1
+M(W&=<W8WNWD5U%6K"#D:ECG5D"L;VFL#'7&R/%%&,'9EF8Z]LIEH*+%,442E
+MD/'4"T$!R+I"I3""0WL_ZSPP0-O>9-@U(;["P'D!B1>215.E_8^CW-K\+!D4
+M;WL9*ML(F\89K(6#T],N;9,CO"RW(:+2FZNRU!1W8YMF`F2IZ!RWM<SQ<,IO
+M`<@VVGS9NO@843YS5(/A/N:$,&U4A"0'=C@&Q/*KSS`M[]Z<T`DWAHS^[;O:
+MXYPYB,`8C-8'E/WP=I+Z?T?.B"9R17BS4,)8T`18:OJ/JPE]F#)>G?<;`'>K
+MKI"5+IP03"%#*Q1G.Y1H;6RJMG"6H>8>UC3_@('Z#$`**(,OI,B8O0QQ#Z-A
+MH+(GKV@&)L8'_<R>P_0H]8]Y_$?G/L?@^KU+DH3M"P#$$,08;DZP:6G+S^DO
+M.1]G8=QY/'2_(F_FB!$"#+93OGN@W4(3$!6\02T#6<:4^TV>.^&LU+>;Z_[Z
+M>K"[?3QA\5.GLH(`*1\IQ,AEUA9Q_#YC6>3P]VBY<U72^*W'TT%`\H18V?UO
+M;P[150A(JR54%&O!@>;R)TS/+W\3[2MA>0PD2&O5IO:KRY#3G=PK0U1ZDIFT
+M\:7#Z&_;I=*>BK8SQFT_6?YKM\F;7.<\*@)I\H*I'NBF9ZMW(/)JB)1<]N?I
+MVV]_\[[LY.LS?8F3J/VX4>_,]TAZ+<(.M:-T-$]S]HZO\`@"6833]!)$'6H#
+MW"CFMX\AW[Q<S[4"<G^>^R9,3P&+?4"LVOU9#SOHP<AV.QHM$;*'M<RGU9W4
+ML2YT<FOX?G_D4WY90]/S/BU5"1/)3/D5\/<X6PX'A?&W?H\SEONT?H=QC9OL
+M?%.8314`D@VG2,J,=6_*/7ZN'&=&)&:"`!E!Q+1)F;]WH\B],-)&X7]9%I"`
+M1""0`BA$(`%;BR?,,2<D!&0$$D%=M:>=&X8K?OK]#Z_2DX#U<#G.;[+S+_!>
+M)2I_'1KP'ZU72]!69WJX!U7@V;'M]$H,NHG1^M>K("^$/XF<F(&H=V7>=W-T
+M.U?Y_HEY[Q&\)M&3<V)?2R<WP*(H>=GB&%GRI8;,E02"5(#!<\X\-5_>S>QN
+MMXJC`Y;E0Z.@X3O$&2"%"00004)0@A1:\$%='TC%H6S':_&ZV+>^#OU3DL+5
+M8)L9T$T2DEDF_YD^=Q/A'-+;.&9S(C'O(TA/.'6MK]VF20&Y*NXR??MQE]=*
+M%^NCXDFV'G?/UW9L[J=%8:+_G&R)*/^C=V"1?.*P(")O@A$+ZV0+W'NX?MK3
+M9<-IB\)D6.D21T=JH?+W6F4_V_;Z)US%[?TOK;K,/SKJLH^;'TYR2?;1`BK<
+M>M=Z;=TT#&;EOWHP0-G<>N]7S:/@Q#T\%#UL0Z7SWL^J-L9_]%TU^EH@(`,O
+MM<I"4!5BX\MR.I6YE,J19D./J+`Q5$"`)CB:[/._47P>_#0&>[RRF>_*PE,#
+MJ#F6WOTR&H&:CB4EUKF:;/OU&SP;R!OVZ#H_*;'QH,V:LP?^C/P?SQ5]\EX?
+M41S\*C^3+D5XKBC"E^50&"GP59R*+N,GTB[&'31,J(R(DDBCND<^9D"G%?95
+MQ@#:(-)1B'P40OR\"&-(R1(;2!M*C"--CD05MH)U!!DRA`JHP,//70G[E%1R
+M:@S-"DI`S#!^]OY"BCSC=V2Y-NDF[O//T7U=Z`X=')(X*$D(0(,>B@&S2$V"
+M3:#8V+8T:L;:>N,6MRUBUS1;7-K<VN:UBUKE:Q5<J2K1;8VU&T7=UL;1JRH2
+M_1Y[7L\W6,_TIP=0_\"\<^1J9_Z4E(U&Y!_X\+1L4KS#;;LJA\&J8J:5LO.Y
+MN3B;6*B>^HP[KX/$_X^KO3M6Y]5K%\5-0+0NFE1F6&X(+(K:(N_3MOR9"?EQ
+M73%/D4MFU[]BP;_DH:-$N!]3#U=4;RK,0/Y)'Q?W0XY2BG;DZ<ZJI%J2;9`1
+M`2B4BX0P?[+QTS+W.#)M<1:%H'6RPMJG.ZBW&FFH^->0V3SL@[X]:KQ5O2W-
+M6Z8U4:YM<JOLN;45&O$:L6URT:Q5S&Q:BUSEN<U<T15W=M5W=K=+;<T8T6N6
+MW*N8VW3:YM7+8JN;:Y4R4A%D6"E(+`/O$,B0;#M,RNK"`<YYSK^M>FO3Y-XG
+MG>U^5\N9>I))Z''7RXU%9[W"*L(R-#)#C3TN@#4:C5XWU:>=VN;>VHL<Q+N)
+M*&+(54?098<%/]]M!5BSC8;,JTH<K?IE$+JID*JO)>#9L?<E]H?K]S5T/3R1
+M5<J,C6O%J"K<M=ES;7SS%?N4O29J\IO37C&O%J\5URZ29MXW1B+!3F`.?V11
+MG]F8+GC0D8$Q&+CI[WO#^WG3+`#D^OY?\]O=^?_;V(@<Q?MNSHZWTYUWW,\!
+M=:()``&\^?O7)>UV.^^7K=K#################$$"8@A`!T^7%L4RWK/-'
+MS[;<>QZO>Q+SSI$@;0NO>_)`])]50^6CL^#AJ]U\][00SY$%<KR9@H>."0!V
+M^Z;WL$<>>2_/;D&&\=QJ=S>W!^R(>OCAR&H$BM;:VN;9:M5A<U7:(/CHK:KK
+MHH3"1&R-MLD255=`+J?QKM>S@FV,RYM,S^25*L0HD,7(9*@V;,),@1('T_0[
+M<UZ;OFP%ID-(6;U^112$EB8N/VH_%'\+^7'B'Q=2+K.0`<R0B(IMR+-ZSL:Y
+MI+2:^MV5V<"YQ82\\@&(^\0OS%'YZ>_Z$?5V_K.Z'<`@_C0S1SLHRH5K40T5
+M`ID.A282'GMF[+SVW(\7RM_29_RMN,9:>+SUJZ'\:'T'HRM>H^NQKJR2NU;Z
+M^'0C.DY60YWQ_K,Z_#W#CW?^B4$#W.`$B1[5W@4#]_\0@/:(7Q[`*V+?G#2%
+MJ>%(IU%&`V`C$0W$8+ZR'TJ&JFCD!RA4FS)[XIN1M>5JUFBYM:^J5`J9E3U$
+MBK]F`3I0_6\&J\EX58^Q^!MN46J%30IOO&K%)$M2E;3M;-J6!1%(2"2D=K)K
+MY-20PO*\XL8X&Y*5>B@KQ+(,6/9V%XKF/NFQ=*<BA-\AAA_Q'TSRQRNEQXVI
+MKHW+A5T9#,\<-S%Y0;+!JYO(4#ZBFPFT"+K6]W&>VZZ:+YW(',:(%#$SQJ;6
+M[J6YP*>%+7:@+Z6M)B_/IS$`,E8E^D`%7C?]=6>_;K#=$8+-B2;NRFYAQF6G
+M0SU39HTP5*TSTRZD)K?!J_3<6;#LQ[^7@\0,$0X3*WFZ#4UMWEW45U_&[>65
+M_.[DV9I-_KC.KB!8@@&TG)?SQ-_120*-G),=TF[X>A$*'5]87$1:W.S;5M7X
+MJ=H7[I[Y+`"([%-ET+)D*3-=N&%@ZG#1Z&;9OET1<@G!Z'-#33S*C&C?LM(E
+MMWO`TP>P`3,UDSXXF.T_G9IKFCA.5V-K*SK)HS6H[Q@=Z)SQA^RR8,9AD>CM
+ML3J]U:GRWP^5OE"X^3=2<+Y3NYGW,6_`WY__C.F)^-\>[QRWM\&XGV9I^AY+
+MB<85C?'ME19>[TELYQB&&KDO287I2B,AQ>8E)(BCKB;-I$TZ>!:&"V#15)4$
+M]V\R0YCSU&8JD5)9.E6Q-M08E<E`TZ3(*GX['^Z\32'U>8,.9I2P[KK[A<<G
+MH/TOK,^D=\<F0?H@61SB=0[7Q]@>#_'AK-A?9L*[2A).N='JZK?&L';P"AAK
+M^(IJ!M/7-Y[:9MN@YMG-F2Z+])F)N\[VRF50!A@!3(.2[??WO$16/DF-2L+8
+MYJ!![)*#</9\)ON9PR3@IF7N3OVKZ=S8">NE?!N,IP0K*KU!![RN6YP+X!!I
+M!9Y=[!\\L.V5&[A@&)9:-,[!V9W`N,XG@:%V#Z036?CE4^<WAJWEW`#$6#$5
+M<&'>BYPUW<-):X5DYT0_@.Q''6FO+,,NCQS7$>6G50&+EF5K.1S=^N/,ANKZ
+MW#FVS9C!`&*CM&CZ5'<7SWSVAHA.(V^NWYSIL8FI&&XCR?%S$<FI=[6'!9!X
+M*LX;U5MQ\>7(DV5C7;%=-R:A3TUWQU6]5(ZBS>_V]?K_1S\.Q](7=O;Z/,^?
+ML^Z+X0W2/HKC??GV?BBO[`^:]T^Z']^M(//90-8&ZB:#<?F]Q^D6!(/S\?`M
+M<>]_;W(50\V)%[6^C@V#=_;Y>']8BLU0Z-/=@B%[GD0]&4SH83GZ7VP^6<T'
+M]B-_0[<9/!:;NUOA4M!;7,._*RW#:!`$XS+N,[GQ?UD./PY[E_<MTX@<>R_1
+M'<XM8\H`\@IC:'"MX]7ME]2,1P'5$+ICRN$H&Y2$K[&@XF(C:")8704ZCK'J
+MB*&=4"68F-OD"5/+^Q/M'.8]U`\>[A^%=U]!S]B5F/ZOZGZ[GM\NW>S.?3,(
+ME\FV>E^!%PRC,%[$EC;DCG&*<B>'3SLXSA/6]J]<HQ*)1!HG\!M^5]B!^R>*
+M9_O3CZC>I9H@H@B4UMUCW]<P.]WC7?UTWWLCY0_VJUS;UNKD$]_75>^V=EP-
+M!(SN<5PW9<RDN233N<M:/2=K.^<V=?IZKP=KG[_9XOI??Q[?"SU8_+EG+S=L
+M=7O$!/P1ZV!-A]9<@,41X/!^9LCG%"V"+`>['T>L7P.@?D_O(JH=EC7@57Q^
+M_''OJC\"\+MA@2!^W>5`?V,`GY&3ASA/YZQ1S00IM`V@W=$T9A$=AVL>CVG/
+MEU:XX':V=?3[=J%[``<V"[+HHOH%6/R2@I_*<N"C:WQ+`8+-C5@8[FR.F;=#
+MA/H'2<._D>HS7&RJW$0]])^#U<%)O,4]]N]4%^DA[@+[OM_36OPNIK;><L6-
+M(9M3;94M9DB@VT6V;1BU&VHBP:E(44UW5U7:1,W6PRQFE$6**A38FAJ:6HT6
+MC&FREJ0%1CMVK96N=J[IVVF5MRM=(4""`TA(U*@H5LJR60H_8?L,8/6Z=!B.
+M\^*'$O8U]<+W>!PXX>]SSA;PB!F$E3Q0#`0I"GI3>D#LI$B+]O[('Q[T(H$D
+MBC;;&(&D#8C*)Q+=-7B3?K+QYW2NNYR[2HQERNG=)=$'=WZE;5O.MO7SV_&*
+MVU&$`^;:5D6212;&J"A(T5PG'#A*R:T@::$I.L2_2-`&VVNZ!,4#:P@Q.0<W
+MA1W"T9;=LAF4&P;5G%'7=L_A^WZGOM\TK9N8$&(YHG(`KQ>?JYQDG(]WQZMT
+MTHK42HMVEC$9VD2F\#VF'AUQ?8-`<6$L0+RM*TU2129I*?!:23U/RE$+2/N*
+MT8*2TDT@(Z`*``^1GMTWG#K7HS/N-L7GF[Q0H76>9E552WTJV3LLZ$-,+<Y.
+MEXAC;I+MB#(BETIDUH?;.HR0"9<H47-F0"&9=*`[@5WCUYSU.]?7YMW?>G?O
+MA:3N,#_M[U0+9Z+*@\E\-A-[6A1R/.]I#/*HLRXSAV]33CT`T0V)JP]HP/#3
+MVXAGYC@6>X3G9P<-I+N@\-DV-\E0U9,T+V4&K/,L#1G0\C?AM0.1ID4FW\JH
+M&Q@>E]#?4U\_=#V[YUU#$?;+OV/JZ%%\NN&?@^Y"`/H7"]]S#N]>>/(YV*?B
+M77BZ69K^S=+\+W9$V.Y59-(E5"D46<-E%M-,WU4R0I%`WBY&,\=8C&Y'*`J%
+MID1(*+)AH$N'+=6P1CP7DO#,#%55A2=8/FI%&0@,6N+#SWFM<US5F-;@&H%.
+MJ&G6-^2>6J,79$1Z9#J1.R;QND:?8YW(WS\<_0GN\NV(YFRU5VU5IU[I1.)I
+M$0=U4D%72JF=-5@/$>'-?[ST7$'[[N;\>Z[P(KY519R%T'$2BGI7B"PR;JA!
+M,(:+RR&.TK[)K<'4L3>*%D%D3D>HAX)DV79KT3X5GY?,=O3/O)W$511C.ZTB
+MO*A0]ZL-AZ[;IEW5TB,?<7:Y$UZNMP^YVJ;+>4WJBR0B<%LN!X$NX-,,:8^>
+M'5ZT#;:[.V6@;S![_)%V6-IM&R7BKH$(Y9#3%,@>JS&8X"BX9UZHMBQ5PDEL
+M(U1)=XLA3KQMZ\Z-7A-H"BKFOM7W"KTU/?;VVYO;TN7ZPKTJ],:T6V-9V(1#
+MQ=R7K?/KV/9]KLQ?*^!Y2E/B.(^4/\U[[>YFJBTU`9%'-I`7`GC.BMH[[$(;
+ML*+J^W<RI5H:%#90%97H@1#3ZFK.[0<B9$$GBL*CQ'8Z3N%Z'%R'B%P\YRG3
+MZ*\BV"!KP-)L$Q)Z)-4@JB"C8BUO$^0!.4A4D5-Y6MFD=K('02ZW[4%!-)AM
+M#X'N^<]&NOM[O@9,Z>3T=W0.M1))VZI1@=%!T=;F/=I#KLZVSG3BZ_SWG.(.
+M$'AT-!QV37W:J\388PT,_/T,%Q\CAA<O/%K:UVMZ;-G=U0NXNUXADV%:^`R,
+M8<L3=Y:9^<^Y$NP*5)1X@#O_<J<PYR)0!'Q('<[I0G%][TEG-OK6>+MUD/[(
+MEOA8*B@[L1`5^I_2C0B!8,/$==XS>>++BD!/(1%*?+]4M5B38S&B4N8@#`;$
+MD42@V$2-3='QVR(JA,M!Z&"`(YD5`<U!BB!4HJMELLI*TVK2I520B1VANXYY
+ML=Q=X2\_!#VD,6RI3T6OH/M0,G,8CI=`[#E>$P521EA<E"WQ4`:+T&AS4OU+
+M"Q8O-Y9\0$`@V$3&(((WJ=!^[RZ%`^D^IUV\=6++R?*0X#NF\=?5#.NF6UUQ
+M=7YC+''Q)7$Q?$,7DLG#G+&CHYF:.,OFK=%Y7E,F&9=+$("B4'`.`H#*S8#`
+M5F7<8F$Z<9L5LD"[BH?I0@HJ1"ORF4GY!`,HH6C4,],1,!@>O[&(D(+S"78%
+M>8($E+6IJFLK*1!`+%K`8J8:V=1GMM2M1/GBQJ!3(0"RM;*T;+M)E(9."ED[
+M(48XU#T$L.:;NZ155,D(U^D'EDBG,IT$(7>Q1:]83!)I!:%519/SEM,%O$!,
+M*,FC>!3><(B%`S(LZ;#7!\"6%D0O'$4)%0!$O\+$0#0MP0$W(;[@@^FIZZ3J
+M;U#.`5D(61(CL35D/@V*U]GEYDBP@$U(N&$B$4<>*^C/!0(IR.4.>"T,>A0@
+MP[P1/2;!ML>IR]\NSJXR[W\/>?=ZX'RRP;?Y8#\<=A)L.`!_2\O>T"FFUM\H
+M`)GX;O#S.76B')65;.SMZO.<P'$)I1W"RIY`L[S)IU8S[OA<?4]?T6\NMW7/
+MET/!]P7HX&^*YAX_0@](F@\J@5+*=4&:X?,\DJ$/&)E\+"%S9H2+F(WI:,EQ
+MSE3>1*"J8C;Z!^#0MDZWY[<O^9X["2/0@8WZ^$9_,]/%H>/''7FV1Z=:N[)>
+M(9RX:_,WH\(>$U"49[BQF?IT#<$6!\/*T="K@WP';PH]"_IIZV7FTG/CX"2`
+M3,$I4WN0K9K1]YR3E:"FF4+4V(>.,3!R,6=_+*37'D<M<.WJELSY*Q')*FS9
+MLR6],KEJ`_,@B?=1GU\-Q0BG0Y4Q(+,EPK'A*FDTOAQ@>,G);N=.K=6SL;39
+M`\(?-(;;G@^$MD->R%(ZB7-IL=+=/>KRA;8"98HE.-U$5ZJCJH/@"D%<T(@'
+M0BD7G(;:X:)V)>W4V3:;6PPXG=,]QX&KNV90T4[,%^5]GV4"&Z]&9+V8^9\-
+M`]_"O1-9(;]%9REA!7M\!7Z;<=4.Q\?6`=?+WKR1QQ\GC[N8POH\30\Y56UK
+MSSP3V4*5W,I45[?:ZW=./FY#RV-]MU:@]GPO->:;W[_(]SW->KI[$IE=?N=&
+M&Z.O59IKUN6[3+*L3.B:L$TD!:BOLRU$8N]XO/SIL?1"-@`0;LK<1]E:OJ@G
+M(^FDSY0$[N&U-OC]KZ<38K&>G4RUA"S&'SV"K*X8/EBKO]0E`?F@?8/YY^#'
+MZ'C0;OP..,(-R#'=69\`W2>B&9I@%W.-&1FYPX'AOF1\OD0M0(DUD9E3@!6J
+MEJ'+(D5Q8()-[99,<;4"I?F3B7&B:%%HGMI_-E$_.K>?I-1AINWQ^5,>#K1#
+M_+[0OE:<ELW3#A($D$(JZ3I<]G+BZ$F2Y!1,)RZ08Q")R1)`:/LAGRA%U1ZE
+MVCU2)^\%%2PC?2"@.I0.??]D3/64QQI9L2<]D#C<.R9O5\XJNM_@Q61C^.U[
+M9-B>9#%D<-VP/=QZO]PUG26O=@7`SXOEJK<YC/=VLDJ+Z9IPR9E*GW"`TI.E
+M6PT7!G%U0F-O49C(P[9$JC@V-NGE&_4P*XSL.3`A),S#)HV^\FAUQ66G)[#$
+MMMQC.",(0X:Q>BCJ7:.RD;W3:"J7@7X]8?F;]Q:PP&)(_*!5S?0?DV=DC9](
+M,;?PR!!;[O/-1!'?"<AFS3@2"3:5+"TD-"`"!`D_![OTJH1]!08R3<.6L2-K
+M0-T\/B/@8Q4)O,6M1+>A@KZ-15H&,UUD<;;8P-%]:)HNUZ^+-1F!NO6\;F,Y
+M889('+HU*N[F7MD]B.#>93?UH_D1L9"^"E^+<9:+9@F.@FOSFJ/18'66EQ$%
+MQVVYL;,V9O?\K<S20N6^"S@M\AZEC'63^O'T!GUUVPW>(!P]/]7+$#U?[06<
+MLQ.3[UXG$6F(AGO=_/V[Z&[0&''S'W?0+3S@8';OQOX/!+4[ADGB6XB&[&Q@
+M5+J(:!U<BL$M%V6*9@)MX7SRL14N()>"R8*3B[Y+ZUR68UL3I]N&EY6Z=SO3
+M@7>US;92BGM:,K)&+84$2L2-/$FWH9/R"AL`CA.6&-.PRVM[4,S,E)85EE3V
+MX;5YN%55`6:Q3!VRRPZ)94<EVRUD&PR&<,S)BSJV)0P6Z'O'-K-P.3).GQP]
+MFX3?1T_C`[$/(KCX^UA;Y&UAGQ=8?#!SW+GDAYE:8?9Z7;U\RPN1!&65@[[\
+M]QEY]"?D.[6^&L=\!$9&Q0(^RNF'GW9ZL!_3GX'HV-_CO.C;W'T,Q[)F-B=I
+M$CL1TVRW6<W@:\9\%8GU`%6%W5C?@U5V=)V=NO9/>0TJR=(T73%.[,6HNT0X
+M9[1=NQ#@F(FBRB!LN6$,;G'C6-S?:15DX6K=QA'V(Y-'=&>2H^DCYD6UH#Z&
+M"UHZ8J2Q((9#P)0\^DSW[X[LBZ(210203,YB]KL&$AR&21CX(02'WNE`\?0K
+M#'/NR*^7MH:@WP.Q/!)%G]SB9S'^&B(7P*-^?.=/GVXSH8>SJTQE(@K`S4#O
+M8[%['BX=G6SH).L]PG/EPB1[NR&+$L@)..J;NE!NBG9[E<A&V>*UW7BUAC#3
+M.IIR.R/;Y_A=:Y%J!PR-:V0R8IB_I#GC+9PZ5W]_\X-#MO8QK$Z$\1>13EVB
+MVU1NOP_4,1P-XPGT-<L=W\G$$@H-?/*U.;D+/QZU+ABMD7XW9;0K]&[7'&*6
+M+O;BGR'EN!$-`2P&99:V#B]5Q'.WVXPZOC=R9RH$C&[EG*9WK[%>.O+":9B0
+M;L^.H&\1`<UGA8OKG4[H;$$O^SG4$7F8W?-\\94A"V901%9-QM^&.KZU$[,`
+MJD;^[6HP,<)G.SW(V"C9C`@:TQQ#VX"VX5`VR)5F+@_F%@3A<3SEYM,$$.[W
+MVH>UC$;9ZF]@QI7K39C`IPC\"*9'7W?25WC4U?M[ACFP-6Z:]R,YY/;=Y%_7
+M(H00>\)A>D0M+KV7I"G^44=>G3CM\I#2;LUK9_'C<$@=7HZ+V[=4)]8OBXY]
+M[5XH=%OKEKD':"AB56X!L_TKIP\@-U!B(0')`46NFHQQ-\A&P:E..<IALAM1
+M?;7!Q5J0YNVG@5_57::XFUYN#X\_O\QE&5[AQECVTUU,[:/;&/S6EXL6]KWM
+MN)L.31V7OY&#^CX&`@;,&[YNXN<=XL]V:T.K"1\#.=T,EQ<%,\.&B&QBP^1M
+M80)6!V/5Y9/^/\0,_C!;N_U`V;[O<DKNP]7;\(]/8]A]/9F\+H>$!Z-#$L'\
+M^H)!9F:E)MO[/HL2K6DR?@8*'4LQ-@&^&=9UJP<C8]%T.;T-:(()V-N@UT+]
+MQP\[;L<'0Z^%L.3V-R(/C=MG<?+GOGFE].-9R!\^H$XU;R1C4DZ#@=V#W[.)
+M$6,\X]-5.K8^CT?010RN*8A]C8(L.Q00)5@WK1;0J+$3#30D::M-,YGS8)DF
+MC-]=.M;[XJ-Z+@TSP-W/2<'DH=C,JO59%[;T?T+TU[WK%O==0@@I96<Z@!R+
+M?7*`?E*X7*]<""("UO1<&,9[09@.[MEF)9S1MP2<(!*D!=Y87+6,"]4_:D8%
+MV1J5PU2(U(4&WGR3GIFQ\6M3E[6O`\\[ILG7>"UUO>31=";MDBD4(H(K,TJ:
+MU*B@PVH<'?XW:D\!(]\\+K\WA=NITG6RO(P#\WR-]=-IZ>!ZG&.>CI[-[#XH
+MQC.*7(X^L.AY<RG0L"(X`0[\*W-7D`NFEA<N(-D21]2%O2JP]PV&8<^6#6T"
+MC]>[M+?:]?!2)!N8Q`=X2#WPT;FX57'[GD7%'./9T2=%X1O"1#`Z+%,%9F36
+MPS$M`.61(9+"$-M;=[+/;KMA&49,F"A''?_&9R7X5I-@3L>$_43Q.VJ*)+EK
+MQ(:!"VUEOZ_?^43^#\9'F]R-]=V0Z2\J@_="7L@>NS8+^,ID%17>FB\-IMM!
+M&L$0&@ZQ#"[X#0D#D@?9D.'=B!ETUZ8<8?+R6$\<7,&3;#LU@Q@V;(AFA)I?
+MB&;+:8%V8YKX,\\`Z^O]SC=C[>W/SMTXW:WI<D8D#P`PE>HI!*\(`%DQ3*-*
+M@*!W*<*@SZ<9E-60"5:C\CZTN=67I<-?4AN#&OPKP,]R%+YK,[=7-#2#5`+"
+MA+G2"D2PQ<`H!L4PM]6%[8NP1)))4-SNUK##M.U/0,Q&)BJQF7J//TQ.N=:N
+M[@[,#Z1Y^WO\M6].R=@NO1V@87;O*PVM3"NTX5.S#)7P-SN%\3/O0R4S>Y_;
+M6#A<,TJX?F[>^W7MZO:>$/-N!@<;+AOASX\O3"FZS1;%NMN5O@8<D9N]6T%'
+MAY;L1E:P))/?TH<N#%,!3$``=^=3&&O?Q`!'4,O,=,M=W[5<]7N?+B&#JE8N
+M]T/K,D=AA3>F0)"\ZZN\#3U)>$CY2M`*_5^+N!NI^6%`]66F<@IZ:+=$D'U7
+M$K5^S$[+]+(-&?RUQ2_QUU(-KK/V4,N$_"M-(*=U:"95@.)Y;U,X&3/CR(9[
+M&Z]5PSPR3+"1#+160X08F0S!D#N[U]^&X3TAC"(Q4GF$B55M&P!*U[E)ME7(
+MP:RJQ?#E$&"TA%C`AU#^LPY)?V5RPFKL]C@7BDK#8IJ\H8D<$`5(9@L\5>L'
+MAX+>J1G`1`-*^#;*\:O>U#9)#F7''Z_+ZZKYM=B1I$M*64W8^#1A,1\)`4:9
+M@T%I*<]\(/6MYP.\BAD@@Z5EDH%+Q#\1`+`%PS%@Q0^S'4U,@-EF>_<L23==
+M3-\'HBJ"$J](+H/9C**N5`\&"]X7=L=COM5?(VQXQO8H2Y;#6*J[+F+\%5Q@
+MI@Q)1%V;,L&A`JW:T:IP9ZOM!QKD3H<8TV$HP#A(B5+6X[XUNKH8XSG]D:KC
+MC3:YW]>FA6X1OM5A\N:SK'4T.*S7QO](*!!T-T$MEJR%GJ<-N-O'U:C%Y9>E
+M.&M5K`KN&!AL'UTH-O0DDZY0OI;+!*$KNK1<0W"5K&Q!-&US=Q7Z->1+D#/N
+MS8>_*@^]MIMP%'Z\_R$X'L;?&MW[Z?45;T7=D2(/&'8EAI6!(#FW;V"N;P/1
+MK"0^QRVL):,8J=TS+U_5%N8Q@\?FI'N3E#A;(1OL$-P`X#!(8A<3!O:F&EV<
+M\2UZ*FWR8_E>;&`R-C\?2\6P]FP#>^MS7!<%-33.:89P))-V6D1S?7:=M,C#
+MK@7J<2,=^U/@CQ9-]N:NGK7CE@Q1Y/U]?.,8%LBLK+2P0OPH:\,_:7:\+&&E
+MXC%54VP<-QEVRI09-9LX@%^&CJ+ZUMM[B^@QRF/9L^Y2#"!7'S>BQMR'Z%6^
+MCT&@QXW*PR;E/)]Q94_(21ZFS"Y"`[ER(-S8.XK\S+//E7H&Z,G!!LP4&U[C
+MLUT[R!YD4XR1$LVVR'&5?F]0\$39(!C$K?YL2^B!C#YA!KTU&-*SFY%KF8)4
+M^7YA1:^/L33DR&T$#GXX,?5[J8^OX+>PQ$`D==^/1ZI"2*Y]1Z@/W,O+$V!L
+M;QW-O3.9?MY8%M;UXE/@T)J)6$SQ#?QRNX@207O"7VEA<N7R<_U%QBG$M\DW
+M'C5LX3AV<[9E>H4=R0MEML,S@\-&,U&<KT+\(0Z%5=K"'L]EM[28=8DN(PG$
+M!#64[RD/1L,MJ2'VUC1<)TD;(C*$!D'9J=5*AI9&"'1)!<IA!!9$]R'HA.8,
+M@B'HLR6C9<*YMHN"5-.(=(AT8M>7N)P0IEK*T*S0HO-WMP:N$`DI!G!L]&2P
+M.YFGF3@SK2NVRE)(..LJCG&U&/&6\<.-QZP^B#CX`5E&8DYXWAA>GO<Y@2[A
+MR?$^_#@G*RW5]^Q0=79M)/1>G'4RRBTLN"Y[,G\PJ([3Y-3]DH:U+S`[AA&5
+M@U)EA9C::AQ>`B&X9B293AA(9M4Y98R;-DQKR8#)6*,3!X''MAES$X_%W^6#
+M;'B^@PZFX_T/NKW^_SLN&\Y9^K?K[=Y-QE7KT\AL@&_/>/;$RM>"<0R@E:8<
+M@%R-Q[-0ZJULD"(DV[_/)WSQ6+#W6^P<C[I^8\\VCX.P)SZ$>[E$@]H'S=>1
+MZ5@;+^AXE"$[OXHTP)N;FP4&#*Q`V<FSD3T769`=]+S*P:L>6HD-#I[&\+;*
+M=L9D,LH>U2:"RS5)&2(LS3$8O5_2WH!+6QR%8-Z=\C4?BWQ=^65W':-P.O>I
+MA6ICRUMM=M&R+\&F`-($[5J9I<+:=P19]JSLJN1EZ$.0J_&XIQE$4*4;;#,0
+MQ9(KS-W=-+4(]YGVE-CI/TLXFI2[R)!O*'JZH4R;9L%EY:8LG_-*#"Z0DIX+
+M#W7@=O$,`=0@,+LX<\%"4NNZ!/5YKTCTTADB]JRRMU7Z(MZ=Q:1/2\T5XXE@
+MZ&>L]#Y6II0\I$$7:S!NVEKS'=VJ6X/@C%VRYJ<"O,7IRD6#6%7Q,B`3VANG
+MG`O8D2"#I,Z[<U4",:C3J$C(:K$>*Y(88@<]B(B3DNJ.>*9R>9#"S$N*YN(;
+MA(OE5$7L^(DRZ'.:FY[4.96\!'"3GK(6/K.:1?85]V3\9##)TZ%H(P1BZ<P;
+M$R=E$$@9Q(+`DAI%8$&(X;[_'YYHD@''>6T1N1WIPXDV!AF4UC'K\HW/&Y<#
+MV^Z&714R1\4,./</-OT?ST6"#,NWG0^!/P'L!Z/\1[JER;`F??&'N>C:P)MD
+MV`^.$&5Z"][:GZI6[?.WXAA_@8XZ;B58`D"P[3W%*(IK-=/)'<L0.\YZ=FY=
+MP_S.]`OS]B8VMX(QA:U.+'RN39I.V7%,(($3VZG4(BFL"#,6:W!QA\Q?BGRK
+MO68A.,S,ODC5\@00(;W31#>-H9T^%M9"FQW3-`CK[G^D3KLL\2W;CJJN;_1R
+M^;9ZJ@$LU!P$!1`,S'6@):2U-7,B0_Q[?(=IX_!U:S`AATS=M?9N?2IZ>`SH
+MW[*<*"&#N@>_AX9)""R"?M4K+>N,7&CDY(UKGV4$7,&P113MY;^4_&^O-=LK
+M%VT!=.</W:X.>O+"LJPN0.Y'7=`E@BOK-3OU9KQW=F22[JS-T6"R7[W!'FA!
+M<JG*$K@UX5SI\5F+XG&2SU*9#)#E&;S^OFY,A&Q.4K,RP2D;PQ\?/+B^<!W'
+M"R#=[0ZDJ3P*D&.+^FS=Q[V_*%;-/G5Y=YT>Y%&]VH<V&-<V>QH77IX2&Z=&
+M.\^-T+U?5A>IQ="JRE;O8(^>MO9R3-#\ZU=^]0A1NPBX3\$K=5*8'!9W0:L:
+MX=+C><0)+/IG-U8:(NJ(8]D<6?DL];KAU;P?.EZ[45B'U^S)K>6MN%Z_5N?4
+M1-H/JAWGIH\-'CQ&*G>`8Z=7/1K]3#7*>[LPU?%#4H7S3NQ"!Q36T+K,HF[=
+M,*XN36(#76,A`J,]<3;75][LHNM0%QJ(G$CN[0^.,W0ZE!MRX-*[:VR@',R6
+M#G4&5J<DL-0L<#7.-%U?"+D46"!%^GX6V<1K.X8\8L3O3-E#?$L^[FU\;F%E
+M-=IO]6-/BA,/0BZ#,SEA@GEY-[PT7DW$,(HJI0,N*TU7G$.EF]\.PN3/`A\P
+M<-ES3`H&)GE]5<[,D88NP=L3O<]-.WT<L@<((&YLA4EH;(BJN-XQ@BZ^DXR!
+MQFZHCF!4Z64G!.'$PS\0T<+F=8H;/)%2\U$XQHC!P[;XW4QJ^UK3YJ^<305W
+MJ:-[M(JYU4;@':#D21BZD&UI,7IC2$7_!0CYN.<7O5AJXRQ>*ETUQ(0D$GE,
+MQ,FYI4"V`CS3V-U*4Q$1#-=8,-><LF?G(_E->Y.,EYAVS9W;+L\>8IX#(A*F
+MF-8H)0W9KR0\/D7`=[<B<B.`;GQ57R<!3F8&75F-=*S7HLPS?@W!6(>I=5>[
+M!PI+0';-Z@E<$RS23-<Q$FM:U%^]]<.FFLH0[7X9LN&8BBQ;1$L2$^`F9G=N
+M;RYA8=L9B,!Z?6AB7-7K@L\;9`OH-A(S="&[[EKQ9NG&>W6:NHNUQC$LX?DQ
+M7H(5RZN>+\UV-ANIT0D35QS,6:*?SR@8%VV.*NCC)LT-C]!6;C5\\W63"LQ1
+MK*IVAR1QXP\UPRK.(D$=AQ0H214L;K(-NHXAG<1(=EL@$[E6-%0+#9M\7C2M
+MP.7Z:H5_Q#`^L2P^UP^-VE>W`YZ3GS0Y<AY;EK.`2V"I/=B&8,)+2@'/L4"2
+M1Z9IXP@U_1D;Y5LLY"RG/MZ0Z<K3:(U2@97Z23X;3H@$I3DA[I3L$)B9XN\0
+MDQ288PG8%/^6[VR:D8WVAQ!2V6R]!VQ%P1+%$@WW-.%`Y98P<,Q%![749IAI
+M20EW+7H'E.RSO#VU":;AN$&:<TU2=56*BEV:[)5!^^MY1)F0Q16<LPABUV1.
+M(DHW-R#%DVRP:\HX5J+Q!LH#-9[<2L9P+2@2%%&6O!(PP!V"1H%WTL@W(6E]
+MQV?>-%2#Q>&)$*^8.Y0V;`?U9L*E98Y:2#%"WZYVM[/<;0)5TBHA$8+O/#1=
+MV?FF'$C%.";W1I&,MB<XL+9!L+9/;%WRS!70R02BC!AD/.:88GT(:*[[J+FM
+ME6U$-?M3BH@AR-G-UQL,=!RL,,^+2!\DKR?T"`@W(ZPV2G+'?Q"Z&.;NV6/9
+MN,B02"/E+1'OV1CB'3>KVJWH0B2X21L2G0\</P7$GOA70(Z:UX810N;GD-KE
+M/.0%V-N388KBTYL19]`YPG!$0$&SWMW_/9_A=?([VNHWL.5TG:DY#@^QM8^%
+MWO%!!.C1`6%9BB`YP.^+O0N@`2>$++)0)HV3%"^89WPAG:L.2-D6]Q%1>GMH
+M*+BQ%AP98A&VZ%R-&&2#P%/)9'TPK+<:B)DM?F]/GDE!8&/L#"(*CY@^XM&&
+MWF\B=-WHE3&S;N7.GTVL7+8+7&VS/=A!/`5'!NT$]\0].$P8'*1:0AR11YKN
+M,"6QNLI$!PN.YB,WAWF:[.)XOF'8"1.6V_ZE7BBS*`^G!!5V7PUD6Q!$*U&Q
+M9P&>(W@3,B.\!USL.IC!$0.L!6_#`LC)&=N,/V,8_SU/*FJOX]NW.ZT"S<G#
+M(P\*=>M\G8GACVP&G/FB_@S$*S0=7N]"W,35PE1\FS=Q")-[7NS/(8F7MHCL
+M_;&'Q<@=@/RSGG0^5K?($8UZ)^;_3YG\+FWO6/F\_V+-=1=YGWBBKAY_$CA3
+MB?"X:ZU]29+Y9MONRI<>)V"#\T!.[-D.G.$,LWSYZ0\EG3Q[,SF]!VC'43J[
+M?<D.MW$"NGJ=\Z,L397F-"E,'3OHV7.N7MHJ3LFFJ148IY[F&W9@S=F:`.O2
+M7,6@H(H7`&>\SS]8FUNP;9Z`]BCC^8Z%!5%$$%&(7Y#,30Z.QQY>N[?G.[X:
+MR91Q#^2&U7?$'8%$%XKHIF;`KE;;(+,7HW.NFSZF*SLJM\+<*RX1L924);+8
+M9..39+)BC$#895S%:)"6MLRYX^&^&-L<$^KHAC#:T)D4$G`0VAJ[W6ULNWIS
+M7"6:B*:'EJ#,HD4JDB4)#*VE`ZH@@@9[KX>XK.CC,`@6Z/TGX/T?HW>5V[+X
+M_H1L3\CU^M#^?*B)^!@?MS+91@8605-07WYX*3:%&E7U>HAO$R*M-;3FRZ0J
+MWFARJ#!-HF!^A)?%E2FP4WJ=A##'16NF*9053.HLDMBKZ^M>HTK&F_GZ^*^>
+M?5>@]_EQ]7(&^BGPWSKS/:*KE-]6/?/P$B.\>^^^V=+MX<$3UR/HZT++'7]Z
+MF/:O4;WRO5)N(UV7Q_2O]+\8/YGY+9'L?BO;O@1[)23*$3]'HXCXXP/:!+)\
+M4[2>S156448AR3""LIO1N79)`4D"9P[DO]],-9C-[S2>,^BP05(G+,*-ZMEM
+M%K!FRWK.WWN[PU00_X>FE[%&M].G?GG32C>`I5;(ZQ<BQ>8B%>T'#)\/C[_7
+MYU>N[COXUWW$NFWSSU#F0\=S=[-C@%R^P;AUE,P<2A>>[9&Y!JFPE>]5J1)P
+MD2Y4-<.@])SCJ]Y@7HC$N-QO,$FL!EV@(\N"1(I!\76>RQ8B.;IQ?#Q;'#-<
+M$(@=,\"(%)&"%H9P&$98WJ]*,R':E,D0KDD2'*HPXK\@[R]#0K&-S9-DT&B-
+MX#5&]:FV1ACFN$L'`;9:[G#+[RW5Z/G'C<Q=DQ%9$*&<47":!V01>J3S",$J
+MI=6W@7%W`T6GL.EH17>Q,3X@9&+K`K@886-(IARRGJ8W,T".'8.L.TX=W=-7
+M.>E^`'-^'I/WJZUWR1ID@*H2;.IQ#.)?%+_4#4P0%BE4BH"%4!2I!!`*("BP
+MZK?7F5.$JM!)A?TO%=T\_)N@M2IP!`CBE3U=>-0<M,HDX(2P`/77T\?PF(C1
+M"1MN.*.'$2")O8!N6`O#0Q(026RK!'?X!050-09VNZ[I&-@R:-V=N;=3?AM#
+M"(09$E!Y1R?%^<X]=KY78/0'F-]GEWE;:5CR[U'ZG6+T;M^K><P:P=?K"!B^
+MX'TB$5YA[MQ^I+M4OZIA<,IS5:<-%=D%5"^(>/T"Q+]F"VINI[*0RC8;.UU\
+M>)>Y^6;D.\'ATX=F(XWP;Y%Z-$E8_:<4&Q*H5&%'E,Z`?M.V#@LL$X=W7`/9
+MD,YB7">2W[2H.`<I;D(@DFH8:R_4F-G-C*0$.61+79G1>R\.U&8IJ*9,6NSO
+MZ2_IWJ<WJGY2QQ+.>UQ&\D7P])7M-X6IUB`Q2?0?5(9;,.KRA=Q#\,8%TPGS
+MG4$1._GWK<[.^,57+_N_2_&,B1WZF9Q=^[AT.&OSQ5?MU!@D.N+:C[&B,EEE
+MB=:NUSG'C7,1;>NO5/&$MZF-R3*TV+>6Q*RJ,\WY9_/7H9>EFN&AM(Q/:-XE
+MK/WRL16`6^O.L%S1;E;B+->[Z]$!Q=+67G]9^>!?9YCEA[LL;9/@53QQ<(D@
+MZ1OJ\2%6GNUYOX51FJ?$Y+1"R&S=GB1?G,=9&B&RM8.-&%HN"3GQG+8Q?.%#
+M25M-FX\),YXNM:JUR+PZR6"-#"+-EKPAQL1P]X3D3NKYOTT\5=7Q@>;V5YLN
+M5RY,8V?L<(:<D30=?N/B5?]S[_2<W'CD+I+N==NT4_:?G>\7[Y^@XQ[Z15VB
+M+RUXV[!;Q[WR#LBXT5?W-HOOHLPXIF/<WU-/BCGK<:X77P.",H?ONZ$CX'O/
+M(YF&@P&ZAW?OT\/%VH_NKB>SSAP[W7T]5P_G..'2$NFC1^(W$>6P]*+\*2/H
+M/8LDKTOW[K@JUU#`*<R$7#Q;YN"_T"1,.`0!I!R0_JU_J[MS*#'?ATP7*/QI
+MW]QVRUD^67'D-=U26MY:/G[>GGOV[[V,9Y\G&ID410Z/(:]F:-[O6*KQQ.KW
+M[AUW=,<!BOKG,$%Q":7U&FKS<=1V&*'S:7QA],ZURYK`AY[[8W#\.C-[MK3N
+M_#:/3J^6OO'>(9Z-/=?7Q.QS5QQ><YXIKH-XKKW4_'ICQES(Q]+ZZE<N:3^(
+M5XE>6[=1#*93UX@-F>/&I!^KX-KGSB]P7,CMUOQS&7&'T8=QS=\E&.VE4X&.
+MT\X$M=HI`FW&-']SJ\OG>/7'?SG/9\:SU+$[;LG=:=WX![R':3VPT<1>I8*E
+MW6=-?F?<UVV=L1GA/RDQK,\-N\LBA@AW5N3D=V47W@.:3]V9\T)C,\%XZ;.,
+M8%%C:^F;DSI-EWO'GNALB<IDJV1`X?!Q>*I/@7WC,XR+D:RL5,W>!C:M-NJ]
+MLAXH(XI[1B6N41HY[NPZZEAML[P^SU=LY-<(ZDWOW^:N\4]8W7>_!WEX7)<"
+ME@T,NW2^303"Q>0R==NS89HB9NVY0X,<9P_3/<5E//?.)S%M7X&^QO/G"#OP
+MW&7'=]5E1L0F]<OK,L.,NPQ1]=1.IQ>\AHG`B07<*]/%[UX?NRSEJW</G#7%
+MR$Z"^&';=U+G;R;/DP89O)^LCOB_GC(E=MJ:G*;W<SBBI]-)_7MG7T]Y=')%
+M\/>7R^;\\7A^%<1"N^NWQN_5+*X&YT0XGUD/T:'CB^9JHSYS5_-IL0!]OO'Q
+M^EHM\G&VGY7M%"Y!/S_NP3$FKW[>]]0T1$;MLK<;^F8ASGA0Q#NY9')9ZW:=
+MIEC$<^H.4QL9.O8&$[)VO.[:>5V'9K;('-.Q$1>OO[YVW1W=J;(91QO`:P^$
+M^7S]`P!$5D?>&+V]A'I8[OOF6_B@?`@&WZJ#J%W\W6\PN)8L9X&[BY%RS',:
+MZ-`\2_!K:(\*U#+4I4[$U+IAXC-KNY^*"I6X[1>##-U16K-6D(C9<6QD]L.O
+MGOYA#/H>"UKS^;CFO6X'-MHR[A.M89O$99Z^WF.Q??UH[Z<WAPJ&U#FESF8*
+M@4@]:6*/LHP"H%-Z>@G)*`@#"`P*L++:T$RD"E`Z#F[9['P.!](.!8XW/.O4
+M>\:<6]0NY8W]?;U'TN!/P[_,8,6*'G[:%/"\MCP%OXHC`.PW6^'M<.KM[=LI
+M>N1\N6?V:_T.HBH;`GYKJ;L,33:]'G$$L#5(,KL_XO1HB\Z>_OGQ?,WZ?[-\
+M_E/;;\X8]H6&UJ/Z/RA$+Q-)D%*V<QZ09T4F.*C`MM;B5/MXI4%!H(=-62Y>
+ML&D(0(B"\D17L8@FI$':0.9B`9(`CT</ZX?.BH<!!#@XK:()Y;T-*B>2_;29
+MT1/P1$>-.+T\<M!FAQ<FN0#!B<C\#ZWMB]E4X'N[[V+F-$JOAT3(F-(9O@"W
+M(F[W5+L%8PT+Q>+DN8I2+]6W$(O8P061>!(%W%]F3)XO3[IT0O;?L9#@I*XM
+MDA\-A?61&X@]!NM5:##B>E+`X1FMP($H,(IOJE28+NVQG^IF?S!UX=S;UBUK
+M+^`[GA_</]TS7M:&!C?UL_QP:WB#.&7[H#AVGYQ_`!L`,1:T$'#']MSK0#C<
+MC%K##^<YF*SE,KGAKM%W_;^CL)AY?![=A'/V3F@XL!];<#F9IH^6OY?=@#%V
+ML!=PWCI7#&;17)\?;R&DVTWGJ/XLC!%<<76%:2,1$;N&@!"2BQ_ICSF/7UC^
+MT[<9TC%\K>M.XE^._T#_?Q>]VUA!@?;Q[X@^)Y('1P6/84-VYU8.3DQ>[U'J
+M'</N83PGL.#Z;0V\^ZM((FSYR&VF9:\T3'K36H"D;0-H;A13G=C!C$'3Q[7&
+M-BW1`(AL5BC:49=LK809$VQ](DS2K*&+B-=G.WOX\^<.AP[>_K[^&E[CSCZ>
+MT;.WFT^LI:V[".QP=EC;0N[<N:)8O.Z\Y+\"\]=N>INN$1./(W59'"1J-&#&
+MT,:@PLF.)@[687%J[+Z.R/GR8\=I>_M=_)]UP@3XRAK"^F!K&^EXA/C$'1AQ
+MZGXSCORV2(Q2;42V[8@2.A`Q'5W9O9=GTU^<?ZMG8=IK10OS34LE@NG84[`B
+M`V1:D(Z*$63DR_9V(<NVD\*6/\;LSN,TU=[,P5A;^IZ0#D!^2,X&^G'\#NNW
+M-4Z=#K^2SG',A\0&!NSV\"(WJ+7>!=X[\L*<=N;PM`?$P8SJO^DLMO,L;J=J
+MF!09?&Z^(MP+`<"WR!:S!ASIK"1G>PBM(,=B]#!6[K-K/:_00`V8&<"W'^5P
+M+`,_E#H#<6HVL2+^U+-_C_9WO[5O>T>SV@AW/>YF/!CT5H+F*,/</$E/C%84
+MS*P</)YS%>5EOOZQ>P?77NOB(0.Q*X?++F=6;#\75V\-UUSQD?\W^URP.>SI
+MPY:R/*^Q)'6P11@MGNWRYU`!L$Z7B/[CRU\^..()[Q#KQ#92^IK##R5T\W'5
+M(M#5TAY3"(2Q=<),:H31O.Z[1B%UWQAU#;X9M<\F'?C;7S86'W&UK.0\%9/1
+MR;6)Q9NHHY#M>EU-G9.\-F,M>MIMQOT[6>?&D@9*BD4@HL%@BA>LT$:C0KRR
+M\.?7K%W@,8-C2Z:V(\JY/G;D--#8:8)UMS)U&9*V8O7DZU<7#!+R<]41C94(
+MC*1@LBD6"R45->;GO;LVZ;';^DE6L;T,,CZ=389UX:UAR;6'(!%HU3"%++'.
+MG<BZWT[M5(ZG-N'(,(#30'.+X9>0^[8\=$DHE3W^H[",(TYB@P;=3+(ZR!41
+M&L)6W,L4;9,9W9-2:I&R6=,$W,P90JPL4ABA809LAEL-ED1"_8RAA+ZZWM:S
+M!I8MF;QFY&"5_(%:]D3()@O!?#;`BF<>UA'$41BK&KLK2?+%HVRD*(*J&BTD
+MOV2ODB""R"P-<X0O*Z"%KS'JX6.K3*=)9BAI[[C]7E)NM1[_,SZ&3O[)$?9\
+MH^X.^-0@2JH=.UJ`4[Y)RR0U(PRJ\M>1@#P#:8"!J8$X49DFTMC)7$QUC!(D
+M52JD$&1IH"B4#`?9GQ>Q^CW-FSV?6]=S_L[P].*@Y@3;&H'.7RZ/E85IP"D0
+M4WJY($RI1,*@0XM`3K];W-NLB'96N)7KKEYPQSIL8Q08MW=N75S:[<W%.[EW
+M<R'WEJU^G]JD^G;?>-;;$6UBS$VQK\;*^4B&UY?3K\7D^SD$DVA-@)_FRL$/
+M8BA2VE18VX[;2RUC9&3:`86#R*[/!JK+C^B\73IRX\?`_(W[#L/P#]BT+^<=
+M_/:B]R#^I<?JN(N4CX:[R=)/AJ_6A]J&A$>S)NV'//KP&JU:5,&;.#9.EMVF
+MK<FHACC]G..<8PV"\7:69)YFS&2V-5,:5J:6]V';G>&@X(P^*=0[.NP_>/KQ
+M=NBM,W-]-.BF2'1M^U(:CR0QMR^4U+M+XVP%]LW%_C?]W`HYUG+-2W,0-<&R
+M&*[$KN@JBZ8VF91:8HUIH9,UZX+7B_4T9.YC?ECQXG5MRL>T9X&*P>ROWY]U
+M%=#'ABHCYY@T.]#*[O>4"!_T2(;]#\F,_YS71:F#K,IJ+'N_(P(BF_!;_+)?
+MVE"C3&D4"F1/8RM1``&>KZ/D/ZKRM5[FEHVKKSB_=\S82*)$PZN=0I#\F.`)
+M?*M4.*=HV^$<7Y/6]#R'CPK%>1E=7NTC%-J_?QVS/.^3Q<D/2D7D"?D_T*'E
+MR<R1/.$'H&#S?5E/O(_3/%49D?[9YB=9?S1I>]3?J_]5VN%BV_,%!,I=A"$#
+M!D`*06:4'X-16]SB>,,'U\-?,_[GRO:SS?(N^/\:Z;#A.`X3HJGK;*I55L&5
+MY\]C6.JN>\M``U.H&#NJ(.KE2HE64)!HK\'>?G\F]V/9>M=_>N=Y_"_=[WVR
+M_?%[?S<IPFTJKGF50(E\K,/]G-MA_NTW.^RWMMF]L,-*QB<M3D0U:B]().B(
+M@I`8$55%/+?HO<X#Z;YZ;+X?0?<8GNO>_A=IUW2^G[O[/*?*\CS?(%''/!SR
+M,"05#FXK"`$DD(V&4A6MJREK6(DQ9*33-OP3H-+6VVB0@Q1,#&QB:5:HM636
+MH@@2MPJHB(E0/H;Z3:Z[;W]'@?*S2\OI]592<1<<*?'O/0;4TL!U/]YO^/)E
+M2\!;,OS;]=5"(E^*7+HEJM/F(6]5'MJGQ*>O(SD"W/((@NFF!840(#51\1$'
+M%'-H[Q9%71[#IN/N9K:PAQD3;0/#S"$A(Z/L90N9!_UBMHWA!D7X4!/Y9?ML
+M*[&%X`8H(1C"(LBJW6(9-U_?];==G_AF:WJ/'^TS>SW?/8FY3&,-@&!F`;U_
+MH0\NF`_FXP%3D.0F$_-CY0Z_XU[/1NXO_?ZY/C]5_F^W;`(H!YN2`H$82`)(
+MASD7/VDTB=<6-K8/L^UY3G??R.?Z;Z-%^/WY_@MG6WO-W_RJKP>_N='1U13=
+M34)X+OHQ&N\G&_I^/)>#W&_=#^5KZ$L3<IYM)K?[O(1`@\L,QVOCR^4Y#R'Y
+M&YX&5M(YK[=]O$+1+?>];2;GHO@_/$=WO^Q_7SZ7<>AU7ISZ&\/<F!RC12(-
+MW[%17M4ZH`(`-P&?YH:UCD1!\1`1!M['N6(`$'^X_+,23;;XL8OQ"FR7!:W@
+MG;YO75OY7GW6%K!>1UL#-2O="I:-,#,[JXX'C<]V$=1X7\[;RL]X79V7>/^G
+M/O^.[2H\%PF[DHK?B:R_JBO]@NFU"^_FN2]/Y+(<?[^N_:XSCTW2ZS'LH3%F
+M[TJH3LI*^`W_M].3UC.H[7`<'Z\8Q;&Q@-'[D*#M=30$EP=P'@=.EW=3>]ET
+M+)6UY!@]#SGOG=OCPT7N<*L?R7C#>0/=%11NF<X/OMG<A?7^_F^!V.M]S]NH
+MT+>KW$-8M;Z6-&ELV>E60`-VF]C-`4K#SNLF-@AFL^W\<)?L0,G^#XBOI681
+MT0_[DG-R9695]@QOU#DF:G';%X>Y[?X;&MKM(X?4V_-^.?&+Y,77E00TYZK:
+MPV.0Z;QA!-&`(03#FYGUU:>HA!!!)(*02,=NWI,R\X?'P6)OKR1<X1XZ(U:K
+M:Q#V;JX]^U@\W6>?^=5!YVKSTOVN>V?V1?(ZWFYN<HTI$>?>FQ/S?:G<>!!C
+M7HWUX_S-RQG?=[A_PAI;]0Z.5.LVO96'D^#\?!Q492B)F$/G,"M\)448/@]&
+M!R6/OC$[$C!E$2@4_D_P8SW/U:GBH+SJIPTCHNCL\UD><6\;S2@H@2*R^MSA
+M%A7<^&=U?K3M.FD2;]`/@W^1?1BLK5/Z?:R$8*G-+PV33F@`$]*J7B'LDRH(
+MC:.9SO\[]^WS[+L9<V/D?UO@9;R]>H``0!/,!N2:)1(E0HA4IA46\\GE8'_W
+MC>'^=B]GF^C_XGC;NY9[*1XI!QF6PU9W'R_`?L9\EU7",CZG;WFJ[E=ZDTZ7
+MVEP$$5'`G0K*G0S)/B<Y(V-C6294QKQZ;B%$,!L,5603HUI5*B`B3*G0V+(#
+M2?Z<K$N@D+WWV_B._\+PW'QNFB&\\J-=OWWT=]-*]?5F^>=W]\?72QS>F=4;
+MG\VU?L8H:B9\$R51=*@?I-KFNB,57/259!TZPHU44$V.:R.LLJ$FO^SXMJ_G
+MM]9Z[?V7T8'7P5NC/*W/N]U#\'K5NP\?S&^)#\[TY5Z=2:N8S30!L:T[1K(5
+MGTY,\L,,IQA5M&:Z.KM)-6Z@\^OWK$VG^;XO/4MV]5YS#?@]^/2%1S?\$"GF
+MMF[F;SX:WA?9]OY"ODWLNV>!2P`8J%+[VZ@S+";*B),^0M`/B1WWWJ&V-C(?
+MQP0&"GZH!BGUHGZ(Z<#LXOV(JF$<(O6QM)`?HP%J/510U/8%'>.T*P3MO9UM
+MN0T=3W-]0X3\%K.5_Q7ZSX13US[?$\RP#?N\G,&SSF5VK0.,.6(M<=?FX->X
+M>2JXC8,``OQ0?=AMJRM32E!7HG`,ZS@7!X5:J*@\"?0(B.DV"HPIF3`".GIJ
+M!:7S:Q;/;5T,;1];[.K8Y0./W/@V>=A=)%X?J?@6/I$-G\[0LMA3\1/]:?Z6
+M3'S=!^@_\03W>RN8%:9^<SXR?9,-J?6L^*D+='426GZ[[9/.O_^?O6']YYD)
+M^^/7IZ>X9OA'V;90`)9YHI.('IT!=S1!:-^7R.9:P_T0%M54%"**B,C4D7C#
+MJ](VC&>)O5'7N".UL#"1Q1:>HK^F8W6OL&1+3QA7GE4N*GOJ+"QK,AV38BXA
+MQ%UX_4U;<]]\<`X@]>]>B&$01Q[N=9)?_:#(W3<N;:G.D4"30([0VA`CX3\U
+M1]J!2BK_;J?^"?5)_H0/$?G$\%CL#9"X?@LOR:GAJP;I-K^O<VS7!,XH4$E`
+M3;%/#(8"(2O#%4!`(XC45,[-#O\J_3`E$$F62:$4B0EF4D$S"8B21A1%(9$0
+MADD9%(:(DTT$D8D8A"F$DV&B,)$(VE((`3""FD90D4PDJ&***1$,,:DFRP;!
+M)"4:24TAFQ&@%$!$DF`HAI2D%,(PQ("F&DC-HQ6)-!2DB`FQ05D,0"#("C#&
+M*4F4PLB)A2DF,DE-&0$4T8DE`PDI!,HBFL))(RE`0C&0)"&H(QBADJ&:2EF#
+M`&$1$:&E&!,IL1,8@$S$D"&R8V#&B31(Q&R8C$B2114Q(R4,4FPR8HA2::$9
+M%,+0TP9IC#*(3&09#0,H*,,2"`*HC4H&,:4$F2PAE,))2300S3!FS^DUMW-D
+MS,89B))!DA)!#09A&(63&229@&*8B(R`PBF8PIC!HF(PT8F1DH$899)9)*!8
+M:98@)(P$6:$$Q@9,)C)F*%"B$@E$Q#@_JSV6+5OMY1E)J[/QF2L$1V`L6L&T
+M@@[)1)T/7\9I1X\W7_CCC[/'\/1;0^OB>]G=[PVPJMG5J\20*T[E77)W"\'>
+MM=T4GOL]X.<F9[$=QXURE8R]_CXM1YE(=!Z/`NP??`3MUPJ'=4)!!)0*02I*
+M!9NC5NUQ.;D+I<;NX9W;MSMI'=N:YN2)3+I<TCNNRN:ZFZERDN=(KG.<T7.2
+MDBRF=SMNC,!V=EL-H"&FQDB:*6$**$S,9$IEHV+$E1*%+MMUW+NW5<2';KG-
+M=NKN+N*YE-SJ(DPHB$BHHR0@")*7-V31*8)FEVT5+KMUV$29%UV[1S=.<N<+
+MG:2D"[MPQ!&-W;B[76ZF1V1.KJ+"IH3"=W(CFND8Q";*2&B,H"D%,-#$RRZN
+M[5W<DD4[NS!*1UU.Y761R04KIN2:4,DV.[=DA'';K'#LV!!(A(INKJW;"0QA
+M+1J%@#(9$E(C&ZKFI<1!SNU=PR&@[KCNNYT@IDRZNX.VUIQ+ESIT<W1,@I<N
+MI&Z:[&E-U7=IVVB[H7;NNU7:ZDL5=LX=UV)R=<S)D8!18Q;A8JX%DP0C,H83
+M7=TR2C,@F1E2@43"*9J)`)0@DE4[F.#1':,$/^?CA\SV7=9_X/MZWY?8W782
+MY904Y"S@P>D5Z8MYWA?99C_X'+[/IE[R9%!&"A]$!4E%A$5IL1B?X<!4.4ZO
+M$V_,XK<WN2TW3__+UWT?\][E:<O*AVJG>&E"4:K5=/@*F_^MKN#\J[6F@7B-
+MQ['=)439VIZ7CK7!)M20'AL*?6WE`=U$][`MXNA-QDH/(:S**MKNA,.(_R?P
+MK[WXI<E[>G%)(:"2<UQ=X\[T1,$#^PS""(>PV0?+.!,#W?H7KQAN?]K4ZJ!_
+M9<OZDD8V5*_KT=,P6KO-J+.('>-!^.I=E^-4156_LE!O\G>F_-^G493AN.^/
+M2]AJ/ODMD#*Z?A>)GN-&V7;A?L8X^1,WWZP[^>G`#\^`I:*(B?Y>:],>GN#M
+M(BJ'=9?WL\ORG@98-Q5K1_KH+IC=1?(?M=F7-SJQR=982^;;O&1)!)'$54*.
+M,"HL`HB:/5USGNNO_9_KVN[;'LO=>ZK4?US[VK^^6+]-<S;2JRHYCZ/MPQ`@
+MVV^5WT_7M?AP._5VC['D:8CE+*-15M8"&'87CM!B+MDAAM+X%UD3/Z\;/Y3N
+M)KXG0QKZCE#LFR#3VS,OU[];FN'DX#F.8ZH0?CEYH@;Q``WL"8,!<LV$^4=:
+M,#"^+N15_O;I5X;:S?LZ_KE\3EKGV^W;-$S`@U084*Z6]J/"S,>D3H""27;S
+MR\5_8<9>C[F&[P#J.<H\+$_1`T-I0GG88XYN>]@54MU%6=R7*_5<L/=/IW_!
+M>5Y/#+,MY*#`8]6@_`EM8LLK\$)!*(A(0;"MM(84';\KO'6-%K77C(/EP2%>
+M<\GMG#Q?D9B**5$%ZC:"0?Q%S5DR0`5GPL[[C=:]H_YYX]EC;>XF#*36D1"@
+M05665!K0+ZH83^/N/>Y>G;%LR"\E'-J&(P?V\H8/B^I=TU>JWWOO<Y3#?EF)
+MM5(NE^FL!H/?>U1QULOO@:C2ZWN?([;NLE]F@J,`ZD_[N2GTIP*@=P0HO6A_
+M^G<9U."@[_U[1F%Z^XU\OU:2OBY%'>PUFU6AM?TY!E3QWK_GF?ZD1;R?3VVW
+M\*3ZG&>C_$V1P)%'*"%UPUA&BW^M@Y6QO;/V\W;>]YNY]3S<OHHZ/N'V=SWP
+M13/UBT`B4-Y)5JR&U2MQ7/>7Z;Z?%BO^<7Q=]HUNOPW2=_A.3V?R48Z2H8P8
+MV)V[!47H573<5TNQ[K\NOH/7V1D^JD=MTVG9/HC*;?:@QUGBK_PPFI*:\76)
+MCB.3]9YGK;=;E\N_0=1T>JS4Z7-CU>OJ1/;AD+`7VOM#1C^(P+UY]S!8)Z&U
+M^EG_PZW<NF9T4Q(1-4$J#._\ON`#U-QXNK=H#==[W:G?>#W;6-X*&=%/GM]-
+MRH;##R6@;L1I:?5]MVN$^1G=<#S,J,39@W9D]P5RN'IT>0R7'73-?GC(9`,A
+M0I).+\2Z;C=]WV\':'S+E_]_6305/4O_D)HSZ!G<O*TCZ@%9^?2<PR'-P<Q:
+M>SVO$^CV5GFIFA$8')EDE5)-!/<+&#&LS_D.NW,YWH_B[/POHW.__KEXKZL[
+M=<_9X4'?>\%D/?XJ4M$^9%:@>0JF09)`)*2H-&C8-BO@MS1MDK1;^+;EJC:#
+M;\@YLE'W?<;11LE)JBWWJVW+9-HTE^16Y:+18U&VQH@MC\>MN80+?<+:Y1;[
+M3NU!6-43[EVQH36C7[,JY5%16C1:-8,5%%I(VL8HL;;&U&VBH+8U$5@-1C:P
+M:+25&HVL!45%HB-)BT6HQ4141:DVP46DT6(F4$:*M&HQJ_L.[6C&J*LFQ1BB
+MUBQC:U_/K;FQJ+46T62-8T)DV(BU[[M16-016C$8U&^RN:*B$L&U%15&T;_N
+M;?BOY7MJOK?3[;6^#;%DJDQL;%1MC6C5%BL48UL;;&QM4;O.M;Q8MHTE&QL1
+M6WVS7;$!C?_D:47FO@Q_UZD"VZ;`9.$_[`IJL9;?YX%6^.X(%N\)XCD`-._`
+M)M&-S$=1G-V[WIL4O([&5N#Y7D9;2MHRJ"(9[1<-1`BF=Q8S"(!E>%W7$>3>
+M.(QN5N6<G`8;B?+GM.&H;)B=Z"Y-TX?W;>L>\;8(`!N("S\/VJQ.YC.QQI8"
+M8I\[#,8)1Q)T;5O/[X#Y^+_;VY0`[;?+EV<7VY.6+5";(Q139%FE&264RF*:
+M0"11FDTRB408"5(9H2F+-&"T"(`R0$(44HIB"!,!--46FJ!9M9F&YWK?5Y1D
+M'R7ZK^CGK>.7`%M&="P!H*;KAKPS56O4_^;]OY]GSFB^EZ1*$P$E@!+#02EY
+M/EYYMJ]O\7197THX-TZ)1Y-X7PZI9,_T5`96++&N#U(8+3@53N38E,U%^4/$
+M,NO.;!KL=A6)>G_'_\W@V45'_<T6J4BP_O)^OKBQ8BI7FO26*HN('$+#GVAA
+M'J&3S_2JR1`J%7^0WQS2T@D#RR/;/X%P=LC"W&Y%4>,@A.L+WBV,+X=WW0+:
+M$-/4<DJ:'UE3OB(C+*E*TKT)"IN9"QJ%R/8X.'LK%X/0$@.@1M[8K4:`I/LJ
+MF[EM[>40$(WBB/\($)0EI"'AE'?G(WI1IWUL2.U8.*T+0'&,`.[YC-X4.(#N
+M14*[C&;AB@0EQLD)_]"\&_']JLF*.N*0AA%3VO0N?<HXGI<]#_KMN6%+_]RI
+M$"@3\2!&4E*HG.C7R)&VS/NOL+7]6UQVD,C:<A&0?V/&9G\K\G!S9K'\]$V'
+M9Q,:?;+M,H4DDS"I0>HJO'CF+]1^UY4:4&W7*.R+KY[T_<_BS9_PM[NC"O@S
+M';#'9/^*$SZO"P$_G1=+VJ.,YO.M^;O,18Q1]=5))S,#I.K[.V=M,BXRXD>E
+MA4]W<5PT*"-TYK'=8[C<4FF3F('OYYN8H^<9,T-CZ"JM/*8=A#&DG%86_$Q\
+M?OX/NGZ%/V'5_Y.&PF$65@L9X%?JWAA^ZR89W4#CU_L)8*?$2B?3F*,Z^D/,
+M]+1\:7F)*RHLC:J)%JP4'Y8'(A^XG\]S0^3I*1_9Q7Q4/\;D_P4F2#])^I06
+M&5N%VQRI2]&>^%^O=.Z8FHL?M?1O.EK)WGD;F[8%-+&H\=X*1`I2%)550)2+
+M^6[4_G)DPR:8[J^R0N8^OOC:]4]<\GD53RN/JF#?\DQDDIU\I=29Y&Y\6^('
+MW(![A"!\N.3JL[Y'O."69$1\-RH@H$-.2N2WZ9,#P;>E"\:J*+$AXIQ9RA2I
+M$%)CQP0($-W^5G7?](00E``P?G_=[SFUI/:_,;U_OTNDF;>[?U^H\/D^Z^/V
+M7QPN,5($ZVM'M!NW<H*:OR?"\MVSW_K*;V[[5M5X3<[QC_CS*&S"L,LDA.U<
+M;WH$0?M>EWE]=F4'\WKC\:+^)_S<3%-`?RUVZ8!`$``:GDZ_A?;A=\(IE+H4
+M$!3$Z!]]HR!S.+RG>:WY.%N_;]AK-5MM!=-W6&?-GB]L68HN"P&X*]A_\O;>
+M/P#$S]ING!?WJ(?7R+L%?(*F0"9]8L_C>+XO<\-JO'VW[P[);UCN5PSTXL,P
+MDF0VS_KPI;W1VZ_[VWN2/[/:%[L5JC3;+UU/ULY?&0#R_29=N4X;>Y,&1"2M
+M];;URID)&[V+HNJ]@Y?@AU'!/#DX40O,PHRZC()E+!?W7\/V;%ZVHAJM__ZP
+M53E=&:ES4\(?Z20&<E5N#+LM7V&<]ZR_FNY7:=1H&?Q(_;]NLZTY'SO)XZ*3
+MJ(ZTW;AEH<(%K#6(4*UN0X.ST^VD5O\:B1X<R4!@M)U#$P@0!`B).@81N/DI
+M,<X?)NB\WO^F?;[>5:G%;#^=3+W;A^661(*`V'O,D!&ILZ+;8B][#M_GP'=9
+MC=9_L^#757Q3HDL<IQ5.Y)*H4C"A&;IVS&YLJ'M#]W);3`_C]7:`;7R7N:R5
+M"7S>BG(`P#N$,XSQX;R@,'(RA;$7&&U.;K/ZZ:)9RZVY+*C9Z#1";[GGWW_/
+M#WCZM>1?\_'!6]Y?F8"+D^8UU$.YSU(!-,C+`_`.P!'0.:,1VF#!))))!)(M
+MPVZ@/5]!O$GF_:U?5]#[/JQPI+RX_WKGI+XNW'U31/"!``<JQYAJ!M^W"0NY
+MK1_[`\=4H4Z;?[O^?D=P^)DX!44RBLT(ED&F]H$3`<E[\%KRF4TC+UVDO<I`
+M0!,4E^F#EY.'Q"M3$=E#3(:02!,RX8^2+RO2\>8'7.^_J_6MV3T`X(J4&])4
+M3&!LA@B#CZC/@Z!H/-1H3L$HZ=A@)Z5))!&"B(LC"1_7%)!%DH@#41)$6^!Z
+M'T?`W7'^^GZ;\.CSV+$'479W,=I_?AHP'1@,@LBJ0@C)4E=6U%L58),5&QBV
+M*D$9"1$R8M6<PT<)V]_U;N333#VM#KSJO_\Q05DF4UF`3?$F`!#=_____^__
+M__________[_____?________G?^W]___][__^`4OUX"]F/`7,U!IZ`UC@G3
+MN9(%2=MZ=`]/&L#K-'NU[W6]Y>SQVNZ`Z!X>00T00F@"8IM&0#0T4T\IZ-%/
+MR)ZGJ;4\4]`T&TDT]`:*>4\DT_1/5-&U/3U-&IZGJ/(]4>49J>38J:>:93)Z
+MF1/4QY%#VA3R,H]I1^HAIZGZ4]3RF!J>*'ZI^J#00!`$"::GD$31Y(GJ:8-"
+M>0AFIZ:FCTGE&FU&@`-`&F@&@``:`:#3)H&31B&@#0```:#0``!H-`U/0*C$
+M)JF3VJ;R"FU/4-!H-#U'J:`&@`!D`9/4'J:&@TT`-``T!H::`!D`!H#U``#0
+M9``:#0```"4]*4A3U-,F@:``&@&@`T-`]0```/4```T`#0`T&@`&0:'J````
+M```&@```#0`(`T!H`````-````````T````#0```T`````````-````,@``D
+M2)D)D1DCRA,CU&:DVF4:#3U&C0#30T>DTT!A'J:``:&C0!H````TT```````
+M`:``````<H]YQ<6W7X2&8YI25DIECF)ORI5"7#8O5GC50P3[`.[WF06HV:`0
+MOS`TID7.KJ3]N"NRK$&=YZ'H;,1[W^S(HC&_`,A72F0"@#!8&O8^KW2;TR-+
+M6(A#`XN1JRJ@S[,*6N40A+A(TJC2(P8J1B.=VL6$14;Y@BTE"C19H%EI!;!(
+MTJJBBN6(LLP11!57^$BV21A$8P(HT_-*MCY<5%I2TJ22[D+,528BUG)2*-70
+M7\L4TTZ5*)2C>2(IA9+786M6+A+`,6XY.Q"S*;@QTUX5+7*EU:[L7"T_+^Q'
+M5,"J->&RER$$"0",A[1.LF]4'NYV'`Q7D!TT$HHMWNK_LX"..7ZJF*,C@TK^
+ML(A,#Y5:P-M7"\(MBF2WU/?P!DB0"23*2BB(@(*@@*#2+2-"E(TJM-`BM`JB
+MTJ#0(BJJ*&9F1F%`B+^-G(DXLC%2R8R>0[_OCNYLH9``!>`1$";Q/N($6(6H
+MY'UE!9&'\/_"N4<NFU!`@6;E[+>,RFQR::PQ?^_K5/[X:9#;7FW'@49^#VZ?
+MU_T,M..EJMPG\>O>)'P7/`NLUQ>@-W$T)\1$6O5DK!6?93IV@IP<H'K#4SAX
+MF<5A-QKXI:.N?*JGN[HYXP.70]8]6^'SY^H;.GI3II0F9+1UMR5=::.@$9MF
+M6,M,W]70OKHR<<N(PJ).0Z4&UJM&"=GMN?M_RS?J41=4-&JV:,4)C&)=0.CK
+MEI'7E,INZ][8NQ*3!.$*FBD4O=)K7M*FD4/<F+>MIR=3I.3N.ELC3)'M\HD.
+MFHUM%^9ZA6:2WVQRZ^V@Q=K4B]5I-#ZWJ:&YYH`B*O54\E;;5>U5!F-G=Z-:
+MMT\$#NQ-$&/=-HK-14;UZY<:S5#]E4M$-BIX:(*I-8FV-!G&)ZW##J)GZG4)
+M!JMG3'M]&='W5Q=DW-3*6N$ZV(G67#Z5BMO757[TS24!#9_S4,OD*60[1RQU
+MHD`1KME+B5]C=.L:M^QRK.H_[.6,*0N[SMO+T:S'=`B`XY47ARA+%`W>8+!V
+M0NA)0H*+<2U&Y1[5Q:;C;A)7)"D!IQ-0E71>1D&>?](D!MC[DT<`:;+=N@M,
+M;,AAHZ<J!DWGOX@<8E@F(XUNX'0\7@SO*M+]Z=$P,RC$:AXS['8+)PL*JD=L
+MP3JDI%IG3$O/^]36C`)@,(0]FF_NQ;%J4F5#0\J$D>$V@B]K.L5^<C5;(DN:
+M""+GS$2KR'8U6=!S.FXB3NK>]W<#N>Z@0#^I?CEOY<_1',8%DY6V``AVEYD"
+M(D&"(";HDJ<YNPM)H_LR]2(S6C$G2(1!VH(B#6!X5DF:`S!C.X?<6]RXVG&D
+MC86*X?R95Z/J:K>[;T5C?,('I;K2!(T?,0$G>HVM0^7HAS)1D*@G=GK3??K\
+M[@Y_&8%_\!!LQTS!$9D1E.\EAUJ1XGU9"QLN[;^(X<9+ABP<90A!C):J8^`H
+M!?^D"WK6O?4!@&7CJ"`_,+WZ-PJ4N<M7.V0Z,?>/-Y0/,^Y]CMU[7_EH&2A0
+M#_-UYN&T\<&9\V?GTY5WAT_$_G-\WSU1/5G52J'+&0[\@*;89D\`P:7TH@--
+M-9LIJ^O9A<AN?(UX:$8WQA,/8/6R`>B@9`3.*?W7-F+CTZ?)-ZOU\3H3B_5E
+M/^5D).';76]PO]_UNZ7C>1T9;^$]371WYS%,-O+0Z1PD4&3V='4A2TB0_2V0
+MN5I*59/6&N+Z($:_+F>[W-QR]V;I9\2[H=/)L[DT<)5#W=8#C7RQ[)W]_J6Z
+M0L!_$DO%ULX\-J`8B]YR@X?F1&%'+];6>ZM2]?`&]PM=/`MV0:0T9S[:DE*'
+M7?YU#KN&Q'#7]#'";*?-T#/TD<4Q/&U:Q\&.@B6!T/<0'QAUC(!9!\6`C@:Y
+M,'?K<-_0XRB@L:6]P8LYF;7CIH)>EI7;O+(C4EX8`Z1D`.)\36$U?]2/"S-.
+MP324)T%:L*,;0P@R_[5)"1B("4[^A+1\.+SFF0'>@137V<F%<?"LVU0Y!@6<
+M>A8&*`1&S0TVUM_+G0SX+3@:*^2JX?8.B7(,/YZVLX?RVC-7WD5$ZTF;&R[_
+M:*B'U:5$729V$.FU[K,\1KH.1E>'9N&:CT>PGOV@AME"?FNTO'G$3<WL5MOD
+ML-7O/0,5[DI#(D`2)GS>C$;KEL]=9Y<J=G2^\3"\9T53")"J(@*4J-:4!#D9
+MS5(RF/.58N*"IE`K>3`"Q$'[T`'J=XWC-^RL,WZ&S<G=AZ+OH?0;!L8QHO#E
+M2WZ-3*?%][;'/95H>;H_D&!!K8R+1*]ME65OF22)2PB3&ILB<+"E]NNY-MP\
+M24*&$"\7$/7PE9.;AKI^SQ)X."F[OW"N*?/8X)EO.S0"1D7`/H.SY0FWTT*\
+MT50*<`&3#<73(O>-1D).'&XT-&O4..(2O.)0ET_',,TK!J386J@@O?65E`V\
+M((P7>D2@`:N"PQ8*K!\YS$V-C(PA8!5&T.&WT,%[;TXG)PVMH#0T<3:1WM:Y
+M0@9IH0;-#8_*N+I&;.H(XCG:++*A%M&P>KV-DHZG+\]#?:@QY.9"&8*N)-#`
+M/A%`-&_R_!D.(YHR%U42NG$CJFO9I2]O3XDQ>.:RT`A/.U#WBQ=NC<^4:"A=
+M2G-]E#,'F)23>W_'2UE_QM!K(S+7S)*4(8%5KV`3L#_W#OI8#AA(0+V&%1@%
+M4)2"A5DHTE<<&8BEB9F'*.ER*+S^^!AQL4N8V\;3"5PQ%DMJP,M`IK4!\"T4
+MIMW$;II7,2:8P8-OEK\EP;/<(1R/(1CCD$-3TUK\Z#&#%-&!H<^,4N;AM@E&
+M>6Y9CUK:OO9'BM17[BJ'AFE,K98+)-W6[@PG0AGSXS!ZPLSF>45(0\,PAG._
+M1.4J#("JS;!G+:BRGMM4/Q<@)@XF1:9E#!XTQ$BQ$(#"**(">1"C4GF)%-*A
+MLE7/ANEOK:H+MLMS-H--E]\;$YJ4.$TC+CJDV/-;A*9K5FXAED$G)XRSF>8:
+M^C7=N#0V"5H#8$3`L9O#0#,BJB!*5,&-CF<W`5V:I2.VR_E?AXB%^`S:>_JL
+MMH1QZ#$#*")9?&MN5X#.E,$$;AKDT8V!%+L,65V*+"MDBYZG<\Y%)9]W6S%;
+M_BCX7C#@L2038(U!^4A!S32-IH6I6=/J/FXJ*(QE^'_DT9#JT-BWS&P445HR
+M25@A&;!::P&9-[[9EIVJ20Q(GBJI3PEJU&VT,+,TFE\J)"3SJY"AH&R]70!@
+M#$BT\_VDXD^'OC".D@PS([;I8]Z2:4!;KLE6:"@V#;?-J]W=LRE;LA4=O'A?
+M9A&<B39G`:\A`J1!QF9F#&1R*$/+EO)B#<-X,$+KS&8G["5.&+?UP11N!9J&
+M+`X5D5*,<7FR1@@FH-5F[MZO<9,@I)1T@D,)V65<'<]EV'M&GJ&*AR.G0,%@
+MMS%*]$J>`P#*8+$'.48U$08TVFB/,U45F`**Q8-$O>+_HZ.&N"EC2+490RM)
+M)L$-[PW.>KS1NJ[#2K0#8X4RQ9_W2"C3PVV)F\WP<RF\AUKCC8U@Q`,$W2U*
+M'HEHZ2O.AZKP<76+R<?14`@@R&J1>UQL)=R$`.P8FI<D$89+3*QOQC*8"CCL
+MGG,O`/;#>D'+JPGK8DJ&X(9R4X/8*\.`N+,S:>:DE>;;+<8%P&)>K6=,1#L9
+M$.DB_F)J\&)765DKFH1"-4+80B+9(A$EH:HWHU>:!EWMW7$T&2^'N8>S</?T
+MI;DW)(M8T-F;+6U)9&&Q*=K$%U)]O"^8>6)C@`<T5%94(W;6:1"<T9/L2T@S
+MH$=)N,;58A)ZK$(@#@7-9Z4G&'(4@E50*251P_&R!59)6-)-BI!KUVUF45]4
+M6M*A-)2D,<#(5C<VI20N,:`F:7?=4'I5KR-M3-OS6$@QO"3#!AO&A0D,25^^
+M6=%)V=!#L`D#G0DS.$7\GHR]9+EDHJIX#4FKR>4&9PS\92RA`Z$FW6V5BD06
+M1*3"QA;$YCFQIMC181$`Y"(G0F6241!*1.PB4X"Q6--P,S#E-4-@VF37%A5Q
+MN7T^%*BS3"1Y]=F+&X_/A*Z,*7PX"G.<60LC%]\7=T/2M>?KQP<4+2!T21IL
+M:?&Q#'ULT--@%.+-[N^4@;ZBU#8YTR2`79.3OYE6"H2?!J0TK\#$Z-R!]Z\-
+M%%F,ARZH0PUX0I3/C\51[)E40X3.1G+C,N!-V7"(<H\"T"@H"XQ2VN00!IDI
+M)W3O671+P.T/(@QAMP#<K[6]'$"EM1$ABX&$,B"*(UBSIZ8:V0D"S\%XBG=<
+MKVG-]%Z:CJ+*OZY$'Z=!$U^!6"L9*,9"0-`,\P8-R-6X`45D!'7QG:+6A0()
+MNFR//)@$*@FW*RT$5!B^+UWT.RP(.&Z@",#F,02!DUL'O4NUZ'FZU:M&FFD.
+MV`JC94HESG2<#.<$*\CWB!G.<%)M5*-P3O)Q1+$&ER[S;A\2WH"0\J+0K9@"
+MECGF451A7E54GM3)":H#3@*A`ZG`VBV26OF5DIC+0M2:8!:S9W4+)8-6#$0L
+MI."2FR%'AR>S,X5M^2@6,38AZ1*]??E3)2(+(J6;!W>[)SJTWVI7#0LBR/%F
+M$\,BG?=%C::R[4;V]\>;,L9%D-2@J%0L4())#EV106-PW]4W<4Q3;,U*`L1$
+MC(5`CGT655\.JM!M!NI",Y#(RRR(IDLYZX;VTM#M>24T)6*$!%`ZE"$\]PU@
+MA/:`5HXQU=JAI1>4#?(GV>9?EUTIJ:BZ;VK?0@G3`G15\">`Y7(VZ;PCU.@Q
+M#SH2RP[5$5E1$6R@0@AV%!,*Y1$#A"!P(W-(WE,CM*D>OC0Z^(X]H5J%`UJN
+M:O.!O:NQ'*>N062D)'-@L32(VE9(1,$(&*%3-.9D8"HCD^MO9E]2X`<TM<1;
+MTOG;V.;3G0*HN<-(684<PN<?>PZH8C@8:9(1F`22B2F#!$"(7J%LPPA@P+`9
+MN9Z&470-8C#(;$`QX-;IH;4]8SEVM+$(=F^PR3S7IW.XE8T!5>0%[9P=&:((
+M,A&O11.FX@4[R#/RJ'<Z\;[.!N%FG9'#2-^L]>&L^A&@Y)C8T&W9%Y3/K]#B
+M2[5XH;$"H=H%()HMB<8GDW"C!Z:VH1$1F(B!N)O+.XA--B8-@[%2Q5?3U@G`
+M26D$DF5T&@#9,/.UN_QUD5A?PDSR#R>^I5-#DWXB,5\L$F:#9ZS-6ZC;H<#Z
+M+AEL@8B#-['3#2(7F3H@8ZAL4UO:SR5B"]11DBPG5X"D31"PF8M\7+:+S2LW
+MFL$:[C1;[X2N^:J8<4=2>1@D'^W.`40+$DH(^=8Q$CL`>WV%BB<AT7-,L@K4
+M419((P$JB7OC83&[GB_[Q6E[Q[7Y9,QW>WU88P>M`:C_*Y!@."$AM0TI"04^
+MF@L8";24DE":2(!&Y8A*37M"<[%Z]'LPE`*275>#R4@\L/V*H(503$XJ&2UI
+MEQOK22,U_8T"_;C=ZOOM@%7S$7\:<3$)\FH3PKE9*EU1MJ6B1<W#DS<9`3J1
+MS$((PRX7<U,+>OPJYH1#S,8@/8]YZ;6.'D;&@8+3ABY/F'$:NUAQ!:.P\":9
+M0".Z;A',LM-.LV,U:]D4`#-0!:47=W9DI"$7'.*Y&(+EQNZK8(F+X"."+,V(
+M4%4DPMJ5>T[J[L[X\AVK*`A!)(G2NH:K>.)W`0'RB22&-IDO:+-LTIHKJDZ2
+M0T&5>LRN4)(!($:4(QHT4PZ4HE(H@B)0&-U7`M55MPXQM]SZ\']@AO=A+>)S
+M)$3('-@&]1:"#!H6D1!1$%H5%1JJ*QF)TS#&'T+,LKN;EM,BZR:;'<ZX05I;
+M37RZHV@/<T%,]6IM(?(U%2H1[5!7,"94K"AFF1&='C#-*(!@P9"`Y9:0F!I&
+M2T%QC"A,,PDP$(Y;F2F=5!<7&N"10ZE.:BID)@!J!%`:$0S>*B)KE)PK@YZ(
+MQK#D<G![YKA=$<*0P[C5$F<4@(O&45-,4F43K"K<UIHBJB/(*VZ!(INB#'_+
+M\`OI:+'P"O0N&TB"!K30`E0/FQ%]*NN1R9:;F$0N`)>X64:6E?+"DA8"*-BT
+M"J8!E=%**#-]+:H!AF*Z>*"%/C`G/'`MB^C:0KFC114NY1!*]KY0'1L7`,&'
+M`PL0!F2'@4"+!E.IE$2`G_WD$:,`,@9F8W>^V=)\@G;<5C(:[D+![.F5TTD5
+M#<+9041F-FJT&U75&FN1TU196A%T\;HY&)T#]XP/CH/,S5;-4<>97/<PDB@4
+M\YD=$8/1J5R16Q,36V;GLVJ2BU[SBH@QK!,T$J7,:YYZB52E;FDP4O6DT2A'
+ML2"N9@5*(S;!E)QCDT7*>W9P:FU8*Z448<-FZ^DV^U,"X.8.AP<*,06%C6FR
+MV`M,M60#E46C"VYLKZ-')<CF&HPM@1UCH%N-Y-!)I8GF\C.PU`P.SKK1@33!
+M5S`VJW]991H\]#^VF*=+:EFS#%E"!Q!E@`P7#)9C8U2,9$SG4Y%0UI8)+"1$
+M#J9F1CQ\>9GXTR9S'/\=KL\J^8]O-:LMM<S5D+O;G;5%@%@_4IW1```1WI77
+M#K)M3!8V,D)``!]J6#WOLQ1J8R[0KDTS.V'QF"`D@%LC!`!@<W%>XZ^CY+(U
+MA\L^9>(B0K9+^^5J52;!_5*'6.95CGY0;J_#/-5MH>F>*)>;-:30++3H3(/G
+M^2,OVZS((AP2(&M4,$T[<=BP6:5C*O*XZ(U2HDH&H(,9(0(+(,E$I08Q%J4B
+M1A$/*^#-KN2]+;9%Q02['JY[,N9Q#T@^,B"MKI$?#H*J#:$0"3(B_E.-K'<F
+M;JSY,(NL]P##+]"_92.=1AVN2=FT-/T[%*PKJ^QYK=@&$>,^H>.I?7T3LE&=
+MAY6T4D'(:8^7=?7_<"!"UYY,N-:5YL.UK';)LA[)K@/D[5>DA39Z*DM/.\M(
+MCP/<2[?<@'172;O\%SKD:8B*5RN1YZ=]Z>]J%!]1N:86EL$>L?""B&1Y;??$
+M1#Q8OPJS'!FKK$72:[U$:6%N38M[R6T9L_-\?S]GKCP'*"/(M^Z'HE>*F.:1
+6"B*@22E%*JXT83_Q=R13A0D'@N8^0```
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/sample2.ref.gz.uu b/usr/src/boot/contrib/bzip2/sample2.ref.gz.uu
new file mode 100644
index 0000000000..fd78424a8c
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample2.ref.gz.uu
@@ -0,0 +1,1934 @@
+begin 644 sample2.ref.gz
+M'XL("%<.FT4"`W-A;7!L93(N<F5F`+2]"9P<5=4WG%3U)`$"&##L:U`SD9XA
+M,R%``@$F>X1)(!DVDX@UW=4SY717#5W=F4P@""XL2L8T!?44&2#L/(`@"(*,
+M+`HJH.S*PR(*@H`R@DL0?%#@/<O=JF>"?-_W?OP4DNZN6W<Y]ZS_<\Y[UMBO
+M7_CCO0X?`__8?]QSOP[WY/V":J6W6MFO9=:LF<TMTYM;9LUN.7C&]&_#+\:.
+M^03_?`3_7&%=//3*ABL^.&K,F"NLJ\>,V7#%A^/@WYLO^.I[&VKYE_);)CWP
+M/TNO&+-#H3!F(CPR+E?J7-O2>L^*2MG+57PW#..&0J'-=XK]H1?6&I9<LE/M
+MG_;!3K2H[/AY-SK1J\!OW-D#U^P$H];VN>>ZY6Y?V:MX?A<^6.EVHW*UZ(91
+M4(CP+PO6U#[:_1*G6'4J7N!'';4/KRO`2&$A*)?<<AAU.25WX,H-M9GG/+SE
+M4R??=/QV:F8-N5*YI?5'*]Q<X.?CS.T'Y<M.H3)[<-S\(Y?E*D'GQOP\MQRU
+MS,I&M%W)O*!4<OU-@_=4PL@INU%?XA9S0<G--V_8L/G]G\_9LOW^4[*;QFP+
+M0V_+"P_[6Z;_T!X8&-B\9_]%&_"?"\<\//[H+8W'_.W+_6.VW3*#?DCSF/ZK
+M+U2+GN/7[.L**]R^C=_?WRGG!P:NV?Z22S;`Y*=]8;[;ZY0K.('O[U^)X5>P
+M?I@1G"9,<D7.<_V<FXU.\+TU"2S;JR3]N$/MCI]+NMT0?I2-VEMF1+...Q9^
+M=<P`;`G.YM8CC]IRZ$MO'K%6S0:F7:FT3'\E=/M@!E\Y.A<VEQR_V<DU5WL&
+M^)\KQKX/1P/_7/'A%#RCMX9>V;+#WWK:%H_91JQ]`JP]A&.??G=;9U@I.[G*
+MP`V[G','_W3'X(YO/T0_Q?]G8/6SACJZO3"VB_?U.KT;VQZ"%?66W=#U-]XW
+M"S8;CSGOAEZ7CTMRHE"14N00'='OO::!:[85TRDY9:_8'V>JYWO^)AC#!<K*
+M1Y4@<D(@NDKD^30H[*A3++I%+V3B@=$7.V$/G&L1208&ZBT'766G%#;7[-?>
+MZ>AV8^NTE]4[NUS?+3M`KC"[BN,5X14N4.,9946-%:3$)C$64V1LOS+5\_'/
+M_).PZE6<SJ(;P4=1-71Q;HZ:601O[^V.RJX<)%_-X6.Q'88E)P?[T^WY;G.M
+MX9#'YO9'E:H/U\3<+UAR-UPK&!XHM13X8I2<$[JPWXNGPNA>OMA?^VCV3=F:
+MW?&;/M@M-W*`9CP7""GJ"BYN>RB(\H/PV][(+=.\@=*2X.+[9JV!#Q(G@35V
+MP0<%,7;9=6!#*UXNMM\]$S8'=QNH-,S6,LT/PPZ'WCK8L6HO'0?,-:B&,,.H
+M".N`;1YW_]O'P:K<LKEK^,;8WG+0Q*XJD`5=/DT?</]JX^X<LQ#74`Y*4<EU
+MPFI9[D/%X^L/(WF5.+/_BHK3@VL,HT5%)^P*DCYUY!'PP^DX*]BJ7CA-G!N<
+M1P@,!%X7R`D1/<!F?>=&&-#NF^'!A'KAO%RB-'C(J=";%9G`#\+J#GA#DTJQ
+M/SJMZN62'C%8)8CMEZ[MW`0TCZ.4`WFF//O>)/!HD5%?MUM&VL@%9?@0J`Y_
+MXN'>XM>PDV)`7`SN7[$8VY,[Q$IH#DZTQB-"@[?@)0N`20`E-0]LWOZRO>C9
+M9=5RG/GZ6:-=+V"1N#K'\_$ZEETW*CFU,5\?^`H0K>?[0<)TCP.&S6(J"[UR
+M6%&T]7;4!R3C#MH/[N>6>HM!U`^D4_+6NOD$CK@/#C6?`!TDG4XNZJ&_A@F]
+M7NX[7%P@H>+V?=U>#D;J'LQ,_1K<D2#J"Y-JF%2")!\DL#::EDNWA`>`!Q,7
+M:-5//#B!;E==;:0@)*Q[%@)9=GM=L,514,[#OPM5/\=KJ8V;M(`EA%K)ZQ;?
+MDC`HXA71(\*`U2()*ON9N\MNK@I\>`T>1I0/2K!UD7L:\P4@_Q#/#UA9T-M-
+MEP782%[2A%LNQ=9>MY6EW(O"?F#@I6QL+2WBZN'MW5E@9?BC@E.&/Z$LBGK@
+M&/JR-?A1-WSB='I%>-H-Y3UR@/7,.K,3V6L_C``KPDNTQH/[%_&KW*@3^$)>
+M+`QD)[(BP;\CW#M]*^')"BTEMAX>R].#O<I8-R[T8,OE5EG/KA4,)5D#E)P'
+MHO%9+A&+\G;(X7ZI*0:%V#[CG=1!R`.,.F$?^R.G6@F0;^;P'<Q=D3_@'H%F
+M(X8I!6$%B7_T$XWHLL%3KC%XXG9Y2+B;]VS:;0,-<G?+0.W?%YV]Q*^4@XT+
+M"X+M#EQ'7PXMIJ&;:&A8YA?_Y0=^T_9.);:R^1'7!UY0<>G0?.^T*G">;MP.
+MY+)R-X$EE-U\;'_U2@>.`I@EBP:4"#1;8@=!$D3NVM[$]255&1+#X$]20E@/
+MA/+ZX]&,>1)E+#."7J\"TY&']*OQ0(PY5QQ.6`7FK[=+#$IDT^TPTX_M5S\%
+M[RR[19CG&CQ@.(S0@UN-2I&3].-%W>5,)%48*JQV=8$4(#'NP8EVJ@M-A(4G
+M18OL=F!12([(;:K%/)X*T,@:D`OYJ,]#05&)2C"#:B[JKL%3@GXB6H?)QGPW
+M'K?GJX+*Z.+!'TJP\?+R1#`O!U_NECTD>-8%0DE`>3?GY-VI89S9_!TGSYP-
+M-HCN`SR71YIVB'[PKA0J"2P:11)I+E)>2:$#8G;FU2048$(LF]P2RXJFHNOD
+MA:2&$UJ_BDXHA,D%R)^+?%&":E=W(J?628([L]MS4A_R#7G7AV^1&@OPG`AO
+M`@P"ZD]6/`]3CJV3CB\Y/4+$A%(S`'*$PR2.@0RE`-N!_V5)$7H@.(!4UB]W
+MB?2D'@$4GXG_@ML'E(G+]V$\E/'%`!;8A^\`IMSG1T6\#N)%`6]46EATX%3B
+M3/;77A[6`_13O@/("\D.A1V<$>S]8M?':]4??2Y"'<&IP/F%,.#*#8N/FS5]
+MH+;+NO=79P=PM,WC?SSF_#%C0-$_]:,K-D^8<3`HJ[5M#^S<_.]_E;=L=^N+
+MT_TQ#:AYL_8=]L^\$[3TV@ZG7+9EW//1%<O'C(<OQ@OE]-#;VOMC:_V7G-Y-
+MA^X5%(,NW"&\>L3#@JZF,IY05-GX\*O]<#M#MX(\&Q3&,QZ@\^SS0+5`6IZX
+MEI8QL'D":*EP=4`7M&Y[>`T\APH[LB9!LJ@$'[J76P::WKO0/3`@%>T+Q_P#
+M>$]O$:]A?P0,PWK[FTZ48V("?3$J!T57ZK;+EZR85[/>/AU8?!(4J[C9<(#O
+M+D:B%0R(+C6<):G--+A0CD"]?&);T-!`A@FEI1,X`XXJ^0*\3!`:,5\\V:2*
+M%YN&\9F_X-5>N>&XQ7`Z,P9J!_S@GZOAJ(Z#NS*K=:"VZ[D/K6X>N`$O+3US
+M$MYBT*]O^(U6[;*#UOU?A/6P>IU-Z@T!(M)1U!4Y#SBE.'/12UHG`KIZYR=Y
+M5%#QN@!/$6*_J5Y(X"Z!>J]6Y++&%=MK_CF:BL^J??1Q>KT<R?/CC'7""/U>
+M<&TAZD/8J+G5\F&'#@SN-O#J:O[;K):!9#4H)*^&Q[$]0.,5/3@!IPR;/?-;
+MXA*6/<%@PKJ3!AT(6&O9Z2("S:R?1$HSS,]=ZR#WSLI!RU7?I^5NV`VV7XB1
+M?*0W$AF/$ZVH^M$*6$JNJ64Z*$8W;>-$A[0<1JJ\'$E026RO/[D/[ZPZ)+K1
+M!Q\<A:1<@81JZ#AC&=(_JGGV?YU"MPHHK]LI%N1@J$$ZX6!F\H5Y4.@"8`NH
+M]L$$4)N"LSWA*J".:I>#W)"421`.M",@,>#_/?)7[EJU?9)K`5-=/DG)!Y*$
+M2GGN2T@>@9"LEIMKXY_^[S84HKZ#IG8TL4QR@\\6-['$M.OPC<M,^DH%5??8
+M_MU'*'M)2()@[B65'VD#>(82&I%7:C)VCL4M#!A5FD'UH(_)4K9.'JLL9:?<
+M56795&#Y#">,/Z`;,IK`$79&TFU>$_NJT_!VR15LDBL@;NZB:@!:5TJA2:0Z
+M`X^KD11[B*V7K"(8AE6G"\VZS+8GM-6LW[VCK08P`D!-98T$[)>"*^0POD+M
+M`5[FV#[V8?P"3B]/+%)).-J``#<4;4Z@%5)B@7J^>"U<5]3]0.[Z<BP0G432
+MS_U%L!`0\Y[@N\PRJV$5^%H[F1<]D=N/OVT/4,/"^Z$/IHBV\P??#>`(<T`2
+M)'M#6$(9]'L^?)@+*F5.+ZG18OBPVBEM$[C%SZSMH,LG1ZV0!^2R7[I^'E9P
+M_Q\-RSG2BM=EOR1="2G"H:L(IXY&+XX/,L8GZ['DE'ODL,B&<+J3.\BY4:X`
+MSP%Y>2RRX,GO%5<3ISN.%!JT[D8P:$%U*ZIT,>+,4;<XOJ:@"*4+[#UH+4')
+M%38"3!QWI``*!9S\^,$S-9=1>\CLIF8_\X:P"K^7RWMP+2+T*>"U[G83U-P2
+M9&],B8FRY]QRPK3?9%"P<!(<<`]I9V'D!VR&^R##0O:'`9G!9J`Z0;X''W4O
+M(.0*2&9]N+"]PN8&/F3]]SYH9EWP9+=#^BALMQ.&U1+0:B=*.#QV5IOA56!2
+MP!U!5]';?UE.]*?X*7H*G)<%`R1:Z':!/-$5(H4^6GVA<BG!U+0/@U5F/D[6
+MF3.YN<*Q55:66(3WR6VN31AW^-Q^.HHRJI$@6-C4!&NP`E>E!-/4LNAB'*-8
+M]+K0$AZT/UR$VD.0H+Z:T'C`P0[[.LXMP<DF8$KGJI4D#_=/FF%D1<@1NU!?
+M[T)R`\4D*`,MT(;Z>9Q#FM/Y.;BU,&%%8G#21:>LS.SNFTGW+/;#C-%(!AER
+MLN6AK\T!I9^$-Y\!;E&N7,W#VI`K.88:@@_M^1/FA($?B)'$=L%)LF!,&8/`
+MJPZZZSAA&)N")R@#3RB'V4'[DEZ8?+&*:ZK97VTH14"2Q4(V$:0!=EQ#A30_
+M(?"B59T.,C?X_10Y8F/H@K)S_[?@+BX&P5[;==\C^2ZNW+#"[4-]:?>#)JV>
+M!B3XY.WX<:]A_.!S[G9!67M_0!QZR-U25"QW+A?;DZY2G+OD@DF1Y$G#<%"G
+MJ.VVW0F@5F3VG'D*J6!\;0HNF#1Y.,,DK\@%U(MB@!PS&UM/#WJ50>LG;\$R
+M2F&6K;_^)(_N0C=,X/+!0?3V@L*!IN?5[4H,T<52+)FT1&OPB';@6-$7`M\-
+M6;%HF3%]^G32([1W3K#]Z'2^0"#E<FIF.:)TL!\ZY@>L0VC7U>G(I%"K!=[.
+M=I@/[-F)T,71#^OLBP2=*;I1V[;H7*41PK%W?+J@5:5H2_M+URP=H]S8#>@V
+MGS7<7G)ZHR$\L.'V0E#,EX>R9!M64>%QE*+@`"<_!XB]"_@3'FJ)";&,'\,"
+M/#^LD,4)6M$/QLUSB36KBW'_A?6T+(?-HT@";F_U/8[L+^>@[')\<IW`!U[.
+M90>@>0]A6^&SDC1I/'4X<@-A#@?\L*UFE\8H^K-+N])\T0!#V1L*9P6P\*)'
+MEJ6>8:YN/)C=MP]`F2_\I.@YZ/*]B3E'2D[4NXKD$0,**+CH^@0KETY8'5&U
+MR$(-:`PGXI25D`6+!7@*_W,!!K:L,9_LG\^/"&QAA..#L_`/[!%JALN26737
+MLC5N>8WG]H%B\CBJ(Z"(+2R`T;%YY](>[!ZB0,$Y2X#@X=S0L!`\GGFV9,O$
+MA8BA@856$?$)4+A08Z<7Z'@&>L8F=YA>Y2QHM'!\L.L5E,+P_K*,<$1;EE8F
+MGC_;),W.M;.&E[;YOC,D3"X<=(4K0@G11:W$54/FJB`2-Y*S*D=6GBLL#(_(
+M\;\.6H*LLPS$5`4"EGX%<O/%UA4^7@^\MMWH60>A2WIN*(U2OK7J*N/-@`L#
+M](A3ESZ%3ND8VOYA]IN&:6.*^'U`U%)F)XFRIK1M)IU,[.*^3OH8P+`]TW!I
+M;JP3H71-\6J$]1H;Z\$Y<]@XXQXQ`^3MQ*EMM4S^-7YUV6,Z5K9\RB&M%6C0
+M07-ECVX1.06$2TP<22;[YB$X`DB':A=8@;7=MTQ=C4Z1)UE5T-Y$=NB1'SWJ
+M!)6L!WU1^=!P]V0N?1D=[*3BY;5/$D;[\`$^;R0KKT0;J5Q8>(EIO";CA'&`
+MV-[N8$-6[OZIN>@S[`7NCX]\I0I:J^N31V05OI9F,X4M8SE427B.BV\#O5:J
+M9=\PO*5$0[,JRA511N>\"J@>/JIC`Y?I.^"%RET'I!O;#XT)T37:B7;`UBU[
+MX)];>HA^@;B!])#1F(?*7`7XMSFET`/E(N]4*/0(%Q>C4)*HU"UZ]Z&#S:AE
+M=C!ST&?J?!>F1XL4ODCY^"4!D/D?VV<7B11)M`L5%?Y*@LH3IKVX4C+.D,@H
+M@QA)Q1IP05JMU"I3G6<?+P&ZG'A5I+(;QESA*NGN08-&V2/P>3%`YWLGL"3R
+M#.:9L;-LPWTVG/O6NF^)*\'V&W%_#CP`]V<1B#H<<A_'KW?RZ_A(,)AQWY!S
+M`%TC,8\Z,6(W$W9H1*:7D.+B5<($Y5NB.(T,;L;V-\:YV\$N`W%LOCT55<"7
+M],$%Z\??`&LM"6DZ@KC2-&1-]M!WNDGY3M%XJ%,S[8>FS&.'Z(A`11U!YLY0
+MC@G@^4YO6$7OH<&%!<N""RRH`3T/=M\X\N5+5@`#=>VMM)*:??I&9+^5,FCL
+MM-$@K83#(0]\?M*C"S!DAL^@Q2"#-?PFR?5!V!/?MX_[#+G:@5;R:`KR419)
+MDI&?)\<J3`0T64:G+3`V\O<Y>;0T][P_68VR0*Y:'@!R_.;!AFDW+F6O,X@Z
+M%QW),/EOGHT&9VP'.^DH4L3RMCE94<>GK0>"F:B;Y*IAB-[M8I%51'4[44=]
+MG!V0\"W,OT@.^)ZH$Z3>]J`L5HPHGZ%\&??%"'O!Q?^^!SOWWBS!SJ-#0`FD
+MEZ*[75*=AQK,>Q1(`',*UM>'IE>7BX:CY+G`QV+KZ`L=.7OAD"'91)QB:E@7
+M=@`FV;,O\B\BAJ(15D19`*R@4"V3:P2-$S!IF@<V[_["!*7AM(ZFX9AZ![RP
+M4`Y\9/)Y0^/!:Q9GQO62-.++;S@+Q8T'D3/W+I#<",&@D%V!K%'II<&!2/&/
+M[4-W9SC`8.;L^Y<9X0**I9./JCG!5Z+RB3+-4"S,,'ULS^N7>B$HU'F01>Q2
+M`0I:9I%9I38O!,V^HF-K(Y`;@IE:/_J;&%$MRGKLZ=XR<V41E,=(%=",U`@P
+MPBI8=Z+Y(5!("XES\FH"A\$H5BUSVFN"EB*8Y&$86\'?&4YNT\GL&1X#?<P8
+M',,9"72$J?WT7R>=<I&3R[F]%%FA#:P""Z](!`R?&["!)85V+Z18-1B$ZE*A
+M_(NM'??F(!A*E`I#%@*,.I'T92VV&#AY<KI:\[[#&CQ#M]!K6<9`H0S_S'7)
+M6`&[\F4F./0\6"\?&&SGDANDV@M/='IP*F"SC:0LZ83D#6`.&ULWC:6E2=95
+M@<=FU^PW%N%=E/@5,4/\,4;-*X)W`6%A%)PDF@R]<4ACRTX(J`%2_OS7')#A
+M>3K=3HSGP^$TU\;]X";8:+@"H#HQ@6_B59.2E("Z+K46W`[<QO*E:*LI;^\@
+M?%"*T,Q*@D+B),(^@]V(&BE.F\"WP._4=B;L))2K1U>S[;,]CFHRVE&^B*!M
+M(M4*S&R08R'K#(J*[?&6'%+*1]P!W)O,&8\AG=*W>=@9WR'9*&8&'#,0CBI!
+MR12/K4U8_@)>43%6CT\106!Y7SX%UDODPLI0E1T.AIWO%JMY=`Z&>^`5926G
+M*%1[7X5"2;F(K6=VEA9_!;<ZB'R7%2<,N8'J!E+#6#M;8;A?<-7&-[35K&<L
+M<@3(FPY,+]-HIT*49*;(R!C%1,OHE,3MFUT;U_;$<'OC@=.&LG&F^#WX8Q/\
+M$8S_QL]/J\%`Z`H00\-G!\%W@]:F,X$`8^OTAW#BJ$W0R^"9)7XESMP=-QT9
+MP9\B_L]0-D%[&+@(&-EA#9Z"<8Z`<1+\[QSX@QY^#OXUMOS[\%5SQ#R.G!9;
+M"W85+HG&(^?0%/S[_N.[YP9!$9T7:OY`2^+.A*3OSGE+J\C#[;GNLO1[@!X3
+M#6U]_'G=3KD&3Z>V!C_4[X_MZQX;0M\AQ6X4QH#IJN')%]IJ]G77"U//RRMS
+MLI2@]<'&B`)$=7H^7_`?[8C&(WIH/'\(N?;>G4!Z55\H,<`HZEU-]",BK1+P
+M*F8,!E0%[036IA->IN2T\V'FH-3&&>\1?MIUNLIHLX*-FI-!%4E$!$8#=G+?
+MZR30",2C+K.X(*!G-XA8/GOZJUZQTH01<9CQ)N:$RM:&69^_BW)0PC4(DJ#H
+M@C23E,+Z-<,?PFQL=WP#I8O?%68C!.[!%5WT>[IX58QTP#VY8]>V(N,0A)N_
+M1-(,[#F*39.+1(2/Z9K%UHL_`G%!8L+$5+*]S_($9OG'[86-C8('D5RP\(A8
+MAA&0#N+,['G,D@MNG@(]36B*!N5B7G-_>`GI%:!`DYN`7$CN6O3ZI]S33I&&
+M\@AUXA30?44K2CV,O)%#I$9X^CA@=O`M"("N:70$Q+TK2GCCQP'Y>(GMTUEZ
+MA*1P0&%R2J[0MU(QMRN75,K]`KP$?*LO%5_;J`!#0/,_7KJ8`+XU^Z<+M?:G
+M8L!!%UM+L?W9WPH%B]$$9+X$^#&QR]FUS)ROF2:T!`,BC,F>]I'@MSIXU,LG
+M3;'O3/4)7LDFUAQK$^:\W-$MHSX%)R=V!?$P%*%"5P7\.8BT4Y&=A;21UH,G
+MYI`N$8%T#^C<PNSKDE$/GP@H2NF?,.&<$='#M\7V8]4\BK1ZB-`@?%'M[78=
+MH8>!.C-N_J\P?)H(O3PIH$ACJR#17E12N29WI!:?.D,5LE!:R[-3&>?6EZ"`
+M0NGCKG7+.;`03.69G-MI!(5R:!(=QU;'5-+;!8*6`D2P/^M^P3=E:Q-"2N,X
+MEZ-C8@B`MN[Y#2OC>+#B4H#E^>'?E_AY$),P].,;TN3@8%0!=KE:+LM09FI?
+M_GAG6$)?F_)I"A*#S8TO!FH8A%_PU$#+ZP'9A9%*$,.@R4C#1X^(;XOMG^P.
+M0_6Q9Q[Y0U<W.=`$F"%'VSG1SS,PNE`M%IM"(':ZY#ILAX%Z,F^$@Y!0NU+7
+MG3VP^=-/+B/\_5A[CS]L.>Z&VS;^PO2/AOVSAH_;$=C9A6,GSGYEB`.6P)$V
+M,H@ISLS95N#%21<&8Z(+(V/GO*?Q!K3%O81)(DK"@4!+EW#>V)[^JC9LM5Z1
+M`T78`\8&E`N<-MB;<%"*,G"0?#4'HN2W_<-+YX&Q!)*K8=G7T./G>W`0)CDI
+MS9Z##:$<P/'CANV;9+RP!"HK>@]P'M*'-!(*+?<6G^>]M=Z^/(WE0331*F(8
+M*`1[R5NL_-Q)W9O49`CC^81I&05DCBJH(O"A^!8ST((#@GI01,^3'$5;`$US
+M:_:=Z^>)IV/[SNM7;FC3/E,@RS'=;47<)S9[]1FH];%AE]GQ[R"2D7J":#0(
+MIV*4=&QX%$T5?4CX=S2[ZHX8),@D`I\QX9DTUE;+M#^:=QE_D@?3O3_.+-U+
+MOPZ#KU'86_1$`H14<JJ]\IU"IXTS/^B7U``:4*4JO#G*+=A5#JJ]L*\->Y^-
+MQX7H`+61B%N5/V573ON10F,BX44>)"#,GS;C)I*L1HP#\CAI(-,XIH4\-X,[
+MA&`(3\0D4.7:R/#Q*+5D]GDA/QU]BZS'UE%D-[8>NP"U-?+2\4SI"-@9@,$C
+M'=)%/Q8:GVJ-5=PGO!.QO>V07!R0V<3G",`):ZIXE6J%HQ0H/2O$Q.4O%>7Z
+MR%!WFDVW"^PJ%QCISW<BB%^W6^PEVY$$&N4VH-'"&)020A;5()1_!490DP1!
+M,P/!,%OFW_]"<2JP9$*!0F8,;P2V9VQU;!U^>=[MK'8I8:F#=?:O?B?$$G!+
+ML89(:[YRE*$2;0KH:M&?6;TBO=DCH7#SX\1">6_15X001D1ZP+Y4E;,0-UGQ
+M&+1HOGJ'(ATT:4&,L4RGP`VB5(3R#9-\<^.20GV6A!PK!.4AMFIW$^$4)8.#
+M:7UWHO8!$"D*ZT-QG5["@#/3$K@S:^]=M&\9O6A.&5.!A'W,WG`$#6B]HY.E
+M5+_)L:[=6=D-]B-6E7T]119:['4D'!.)1AG^H.GWZ"U2!X9\@E,QMD;XRV%W
+M-R$8&N3&^&80[2':L+#[:[QRX)?P&$(>/#3OI&)H:2846]XM2.E*"V$/&M+*
+MJ[,8A,0&-$&/K`MLH0&:VVA;)\(/MD?QYK.T$GOGB,@LT$D^^D+0[8>@WS6%
+MH'@7U2!%!W4R/(*\TU3T4.T>M,[?>>4&^/UA,P=JN_YT%DJ3:_<O!)3/$;GY
+MI!/S0WR2#4F*96BI)C((T=D%]WYK>XENK\P5OY'L$S4E\D0HJPWSXW()["4L
+MOL&^1V5F"(>A?%^[5_3=<M-B#[.I@%<W?-WS"VX9M?(RW.*R)\(?1.@@KWK1
+MN)@545H4#8`@*[>_@J;S-ZN$=9@J:"WHP8\0>>7VH^#:;?&-(+@:BD\O8(R"
+MS^@&*:WG"00/'[4+/'NGPRGC0TAB(G70GLHN.XSAT!"KA6[]S)[=RI1STD*^
+MZ(+%:N]3<GS8=>5=%#Q,H;N9]\(MV.]VCQ1%S-5$;""J(HP#I"LLB1*YOCPA
+M]V//R/YP*>X\(90P]*=``/DH3<^(2+I`Q%_4'44Q$F<FOR.Y!3$HO$*L^D>-
+MY-8GXYI<.,*UX#E%`T+!(\69W==A]%%*E6F28(@ZP49MKHUO1&^JB/:!J!!0
+M4"^UG2D<Z*!]QEHSY`OVXK-PG")X&,W,)L@^6.&,4-+E`KVZ,B,&+\FU4V;+
+MGZ[U"L1@R8_)O,^,1Y'>HOPOGAH&%+38/OX2931KOI@*_62>.I*S,8^_)+WQ
+M!HLV3B>V[N[7047I?"/L'LE[><TB35C&,&5<F_#L$&1C\SYD^K_QE5=;!7[#
+M_F3PC3WMC\%O;-A0^Y<DN5H&-7PS3<G>O()LFZ\/&5S"#/-@0*SK2A+UI&+`
+M1C`T`X;"=#Y8/EQA:S-R69$5DV!.3"_"=CA@-6X5R<](73[@N&4D;0_U.1RH
+MTDV0Y]C^U<6L&)AZ4CJ9T+A<)(N;Q!"L<8'2^>G=GB=7#Q%,YIRKE78=D?&.
+M:&9MJL*5[Q)Z-JLG@JA4>%UH*+$ULTPQ/`S8YKWM7)GRR#D_.)0,1J@@5PV>
+MR6$0&X3-4T\((*B.(Z!C6IW"4Q/1+W/3V<A5G)#@FJ`*1-U\*49,S]#24YY_
+MM`+>>`/5]4V<29QP\)$F:*I<RG\$=^NB:<O\HG0"*Z_)"'T^ZA+*)RC:"'^M
+MP)&!'$?[<K?G1B&S8QU4LPS)1Y;@KKU"_1"*JE(U67AX/FQB5'37R&-UBR##
+M3_R3F'XEZ,4OR?P!J7D&.6V<?)X"6&5.'2YA+!]CS"^^=Q)&8QPQ$F-`!ZVK
+M.J7D(3/*[66/W-VG>A6$>/9&(FR-\/J>B^D7"8(%HAX,2E`NJAB1=9/8[MVL
+M%L')UM5>.-)SRV'`@("1`2RY.D9/3.XPV5&1L0JD/_:(<RLU#VS^U+-K1]EE
+M,QLOSK14MB8$2(TE]!_>Q;*IQ.(XW:EAEG9H][8*OYOI%#ERA99'A"9@),)H
+MLVO(7G0>(H>`"`UA`TSV]HEH4*&<&9E[HC:7!$R9*`Y8T+9=?2))IJ'Y1#:Q
+M2!>G%2GH-0?<22&1.TP>C'-.WGKBBLYG(MA-'1!!G!&Z(3\SS**AM-X3V%FV
+M-/A:E<@%`A?/Z:+S<W+E@"\G#.'$]D<'C8K)X7@QK$&Q/'*4]77KL'O]Z5A'
+M+U!D'A&8XIF>%90>B3@/2CO3LY&+P%D1N&JGDWEF6TO^*:&W/"I7B<&*_/$,
+M>G-\KQ>A%SA(P[,[P+E^S)9F:^/./0/42+<L@,0XA)*;@N8I_^,_I`+)J,+<
+MJE?D2,;]/V$[WI,YV=)T8<=;(CR"(&,\#&.6T(7XY.^,3'@T<JLE&FO=K1@6
+MA0W\XQ^6^:[(O"1EB?)*!%C"0=,;`<<"TESU)0^7;D=/L?'/GJH)([:G?%X[
+MF$B+4BZFB@N"5EPHJ8Y-;%(%"LB;;7_(N1J<&^)I-Q$[UCLI@82=1?693T6/
+M;2]BZ)14E!F:27BXPC8R=,3ABF*_X5JE-V':?V>9IZ:MN8ICCH@HK2OO`%,_
+M[16#2_*3C4N0]8!LD`$L=-L_2FE`'$ND!'IVA4O9U=<M,^8H=``BE8UH"O70
+M[0Y&NND,N?//\_=I:18,L8V",/83;\@""!'3!-`4#4[GTU5%C-"'WY;(S"I"
+MN]A<P3%:9LUJ@>_W_1]]=%/AXN]]CSJ!1BXT`H-.;Y[>.HVG#*.!Y@RGRS@T
+M4FO(F]Y+J-><4$WS[AJ4*L6@5R0WW2`Y.ZRC5:[C!$I/\(J#F:Z%E(H8J7("
+MF1\]B"DB*A^D#P@B$:I7!+PD*;@NI:S"#\/`F(KU_MU21Z64(Z]BN-M'`Q:@
+M914(W2!#NKA4O-"NP;BLZPN[!B<_0TZ>,,#??(*,&1DPJPAL*!]]-K:N^CKK
+M@]D(\0K??`()=7;-_O7-=$[=3EX*E(LIZ6?0>C.3%Z(?M``PD\E:31`^G[!)
+MF92<,N]M$=A.@J<+&IG!R.G+0>M[1\%V2G="!!1J/7CCHJ!`7H'WO7:WC)X*
+MPM@D,B7$39`6Y$A=:#'T#=H_W@]W#?:\F*#+OYC'_P`32;H=3.9)D)F"$<!D
+M@V-BG$;+A/XWC1BFOMT4A\(4"DZ]@_WR*!>0KB3J@(ZD+R$02E<CV,+I\KT*
+M9H((C(Z;]RI-8M0F8.A1KC]7Y#O1C'>'M>0VV/N?G<578Y.0["%#DXC1XA]Z
+MJ>))'Y9`J:+:]4P?C#\(CR$D`UZ&9*>1A7AK02G:92I5Z&#H`8&5C#5VE=F8
+MS.SSILS,S[L38?XNI2<@J,(H"('$%B@T,CL;L%[!-AL$=JN5ZA5TU#[*/NKF
+M&+Q=LX]]O/?BNR^1$.X(,=P#F[$0#SW3*@#M*V"]^%M\C^=CBG-_'9C=WONC
+M.@`8AVA8PC*<'9%U$0<I8CO^6=CO;[QC7L59&Z&/`AUG^WU>@5-5#0][^:>P
+M-$>Y/Q%.#E0_\W`"!&DB6DD(N"D2.6&[GKZ68GCPOP+E?VJ.'&?&!<-+):ZU
+MEKD*5%*<@P2W1D-&M#,S]P<X"W10LMPN4B4?PN#7(=$',[/FH%2?71N7GSN\
+M5%7VN&,>O/+%W]<7]QAJKHT_+PO;E@POY<PR@JML/.:>0,XGM@;/&D)X#9>B
+M86"@K@Z"V=:<J29052S\NH"`,"VP/NR.V.#8]O]DPH,1([F4L<,X!HY=E$6A
+MG/Q7'$KLYD2^9*TGS!LC\$[U-F)KT^VDCP@%HX1S&5[JH_I>'+0^VD1!I"%V
+MF>%]&UY*J6*,:M:12/1Y7O`+UF>&LA)A+7`M]"A*7!Z6PT6BG(/(>*7\662V
+M;F389BHA5"&97188JB3$#6;4SW`X(97R2:Q%")%K#>5!S%?PND=.*:@J!'^]
+M?D>63#>R).G"X!ATYN43'/:><U6C-%8<\6Y2NVRN;;,^I""?<F26,7%B/NII
+MR)?"^FR.X:6LRX;1$'KQEX)5=/$=\T2)'#D(S+/[?)BG&\)-R_S^NLXJV/W?
+MC$54&@4R"KBDA\%YPTMS:OW1$)<6XD(/REE$YA\8QD_]0M@<]K_+5+.@+HDE
+MA9M1OI[A=MA@'ITN*$=#^887:U28B-&)L/]PU%N)D0TOE=7#:O:\A7J)L?7,
+MNB$Z)ZZX%#"(`RU,]..6^ZD<3A^K(3K,IZ8<6_]\GI#U9!.J5(&1M7\R._V]
+M#2BB6#%<C;XC96AF]P]\!Y7KS,JIR$JB;F1*8&6`MH:R+_#RR,)P=Q.SC(:*
+MWX$^->7"X:68)@&'`<=9LR_=1BT3V$AF_N<[*-FE+,!0(I&R#O9#6ZZ=<\/M
+ML&TG.L6A=,YXPU'WJYQQCT%LI+832!"]AEQEA8(D$AV)-Q>>ZPZB/H4)(:1M
+M;/^V4<6;C=HZZ3(QOVU<XZUK<IK@WY%YXK5QX5M+V;\AJBMH9/=+7:0QWOE!
+MVMDS:M(.KP11`R-39*T%SZ\9Y,LK2[-PR%#?1/O91?/TK$C6J]>L28C4ZC)E
+MT0+R?/1__T\A!";TO4>(ZVEJ9P0<[S_0OO+'<[!?A6<U'$:'7F%7?CJ>A.U[
+M+XZ:FP$B`?-,I:)`,7X3K2,7AKQQN/V+T1`JX\+!/*/YD.86$\]D+#RVSMLS
+MO7;!]'C6V4'KFB\2]@+S:]QL`K\"W013,Q3`+]\L)['`8<%N73V7L!_P`KH5
+MH`?*)$>!:U79"XG)CFKV-E46J$,:M85%:_P5C(!+(3,#WZ0KVF/RAJ#2";0+
+MJEKD%5AZRL'D`,!08^NCPU+P>W*_&6D5(OT,+N+D26UUNZ-3$1''O^Y1PD*C
+MW3SJ]M0:CGU615ZX<`Q'#=%X'26_>X]J_2%D5M[#/C0T5SGID>I9)*8GEA8`
+M.Y+@?NBL4'H5G./5#Z#]#OSOW-7,';M\4G)''+Q>N?W6/DM\D-M./IO0PVH?
+M,1QN1Q](Z)QQ$/)IN":W7[^5-,70K'2!(XWM8%G'CZ*^V-#!'AP7RS>R["53
+MGZ/*LJ8:F]5&VBKY59P2<C:&!4KRR/(-C_27HU"\XIG"5QW;7UP/;R3O7SH$
+MJ!"7,-6>A^0T(I7WG@AFG=<@+TI/J676'[@$+NG,"]E;#M:$/><J?K[D4"1%
+M9$)180%QO.BJ3R0OX<I:>M3>V+[C1>$>)N`3[PU0W;\F=%!4!@Y%L@+B'7@V
+M+]ZGLO+$..ASX9I@/ZVA^35HW?IES,_D>D;O/W(2VCAPH*#@P1BB2`-]G81%
+M@=L"V]M34#J9SPA'TMK<VGPP'P&Y?XL(CB/S2,T,?S(3F-0>,W?;P,_?#1^A
+M+K#HKOE,%YB14@@V@4T#%EDYJ$^K9+.%ZR2UU>RC]V4I!^1U].=%BB/KVBH6
+M[J7C%D9RA;K?A+X`G>-]X6B2+D:C2F>)*81*<6;&+Q\95'_E.E1)C#)`@L[C
+MS*S;==69LL:58OI-PBS>$=,SRY0:;#^MH\;6*W]*>7;KU+4\&1=S,>E2EABJ
+M88DAF/=V5RF]E"X2*]VC/B^P6>3W4`<%UN2%8W=^_ZVY3LCFY,:[+^FGW.C4
+MN>#7L77M><P>.3V8\.%2>B(6'/Z<R@U&9R9K_C5XE,IB1A7\H\IYI,&'VUL1
+M13XG.GUZ-FI9CUSDA<,HB\K^_G/#[=.C(2$9HE7Y@/QKQNZY=&!3(IY%BQQ3
+M/@(BZ*Y5KM0I"-A6A0LS!6[&'UY?XO-I8V%5$D&BMM[&;?%'&&]01H1F5>2/
+MNOX$NK%PSO7&1D#>5F#S43>6[3',HZCQI,5+%TZKV_Y6WOZE!J3+Q?NB[!#8
+MR-&/9)[@X;$U_QF=IVXF1HMR6\`X/3@<$S66N&SH*#9";XKMTEQ]P+-KF4?;
+MA]L;X9!!6[X[AO].&\)PPN$BZ4Z%C;'<1)%=-WHW@G*8@DWO<0VG@+-7S9<>
+M7U4]#4SE$*LEF\'%/?])D2B7M3"X8!+-+X7&@WN"*;R)$_,CCU,=P$"/W/SL
+M6D/?1S![(JVU42M.?=QG?][FXT.I:=:Q_KJ`]@P1T,Y\LH#V$0]N/:!-CAFL
+M'=OVG,A!X+*-*LM,.LXHGB/<9HA*3E.[V*Q<,3!J)V.ACM@^<QA^CE26Q7Q.
+MKR(B`UUN!=50*BJL"AMAX&^-EP?-5L47U-&@VDSUGYY9$0Q:+W^C#T0(QZT2
+M/'10!"<6*MV)F#C(N+++L(JHPD6\9#JSN<^Q]8_S%-<4B521RBHB8`2\<M*S
+M*/LX$<TA6U#JTJF,;V)RR(*.]0J4H]+8&O$IZY*2[%'/+-Q"EUSO,F-@4.'"
+MX+[GBHBZ67P'#62%J-%9:F:=H=AZXS61L,19WXP$X,PHPAQ@#!M6M/TQ'53G
+M*:A44%&5Q8%U3DIF\IUL+.$,A14&GPE5"?VI90\A7"16_*B*Q2G`VBNC$7O"
+MX\/MIZ+O:F_$<<LQ\<K$F7ON*F!=3JIZ+D80<0-B1\/M)ZQ<2S>[?[7T)[!A
+M=((89XC@5+#252>B%%W5%4B4)._[T!1@EF>?*/.]AMO72FG0SZ*@+@O,6#9F
+MSO&U';3W_A&27F02WLQKT1/'A:6`"A*=A8-V2)K+)*JF0`5UF2JH&U\\42YX
+MN/WT4[-('R>LG)Z=OCH;X7];Z+\MXN\M\/?U-7AF2#JYWU+I!`4#3\Z>!OC#
+M;'91U4[=[^^XA_@\/O7%KE4'U?8ZY1NK\"]';O\<OZGVV4=OY7>)WZS"WQR$
+M?X'G>5;XEU+['6>(_YZJ"M92!"?.[+=*7A>B+*58<$4LA:[<&H.7V9_Y0?NS
+M.Z)`%AKI4;7,,5<Q+\<BBW;CA^S499P#YVW!+T`E^^QVYMC`#+1TDN,KL1%;
+M`S\G)`X*!:P_R$6`&9M*F!4!J3"*;23$OT5"09-B'FA@@^28LY#@U$)Q5PFZ
+MB,5DZQ'N5A5I,(#Y7K2(JR`P<)PSQ?E7GH*P&"2)+`($PXQ].^#-&"M[:,"(
+MD*/ZQU42N&1TU%7UR#S`9@9DW$BG,U;N?O4![>L/1Q;2(GW(L%-YRY+T@E(9
+M]2Y!M>Q#_D+ZI-B].G=I+7-V&X?W#_D+S0J#$LS(15D4WN2JK@+-W\7V-S\-
+M.TXN*8*2<*VK,-+9/DA"CH>%;&51$!#_/;>F*\/1\D5AN,D=71SD\&<C#?_K
+MC6N&V]&KBA=P88#K[XSF1.T]XL_X]*R.N6?@U^T];0QXT1_,Q5]<2</(01:5
+M@QX:)4?CZ+_BDXO.SIPA?Q3DO:(['UDELG*'?H0_$S?+B1MN.U,;SK`/H"K`
+MK&+6<S"=<1K^9(C2"+E<$>DZ(P6.4:1W<-R*FV$<?+\Q$`V6@.!/^.&(GQ3B
+MJK;]LV>T!V77$,(2HS=^TND*+R&L",(R4:I[65Q_BG,)3"B=KGRZX:GSE3]@
+MXO$[H`Q*Y7:FIHEK5W,5(XVZCFGQ#MXM0PQ<G=4BA2IYWE.%3.KVR5CWM/1?
+MZ:.4V%Y2B:WWC_$$Z@U=$"SQ4!8QF8I:_7Y2+26=C!?C"I/,1\S=,'5-N*$?
+MH&V'414)*^,Q-LHQE&,VQ61`2.YZ/0HVU]<Z"#`1L%#WN:7J2^23'#)=&VR?
+M6T2M(X9WD5+.Y4B8%\@1D2?$=M=*RF5`[AI@$:^=O@GLMVNAX:9AD8-B`V2L
+M$;X`=5]Q'R/?=<\?;/W4%:7#K\A@PE3#:2TC]$T]<)2*W-EWG<$5?\PIC[/>
+M`%I#\.S+#5Y!*%L.O)JOZU`VJ1]?C(A#Q?;I,Q'"(@`AL`%+=UJ&G+S/P]H"
+M]D4WPWB&*4`#U]UW=2-#N,Z?6S!B-31E1G.8J+OQR^8+NX88K_JI2M&G66VD
+M3-G'-Q`K$`QH2"I`QLC$4>HF)K4J+.KRP_PH#!T_UB@TKK3C4(1=&2B1X3!*
+MB5[.JIS<81(NII([0UFI]>7=7-%A)RQ<-_+7<!`:S-`9`[7MWG]K^2>U0&D=
+M*\"4.?[X@H-9J%\^7D@/`7&KDR"X0MDP`D36D]USJY4:/$RQ<Q4R3^MUL=UR
+M*8HOT]UN%B?C$EJ^.]$M8O'5PV[!^T15KWG_-*%BK,Y=BS/CRI^<`X$!(I]1
+MOZ00)P(E9M2Y03\+U;F!3Q93=MIMF=6R^D5;&&?6_-!#2ZU7`.V!43PQ22K8
+MJ(L6C0IEGJ\3C&4%G_J@L#H]]@I]X1FA(Y%DQ\VH3_W2_D50Q<,3$(2.U;PD
+M#-Z(#7M44PJ])[`)"-4U"O#+B&V<.>!ZI43D^0Y2BJ!D;6D-,\>E1KL.=]=B
+M51*SIC!Y2?[R/RG]F:MJR*D!J]GFMO^L%:IX@M#H8_O:`X7U`2SFD?TPW<'M
+M+3HYI6DZ((D0WRM'S`JYVXK.BU_^8RG-QZQ]NI&+IW.IOM[0K>:#)N.NL+9_
+MX5C;U&96.JM!`UFYFL)WS:4W2?%PHMD1?"&=T4.(C.Z84(>,5N)+V'><Y;42
+M^#`P=&72MM9(=$Y#9UCN3D=[4K!,]/E'&X:H'*?.@0T6,V8R%_LC54##J)NG
+M_3YD2^^^)^N).#.=C5)R\BXY#D\:I-N`^!>X"(EQ+Z@'$`68B>K4L!,QQ6#_
+MW?A`1O-;VK\<OP`K]^15XGA0,?VDJLM)G5,:J'S^::)NX:<.Y3)D]'-5J8>Y
+M'8;;>%\P0*&,P%/!X`.;:[5R$U)]I=_>`D(5I.IJ]#UF=OQIO;[!$`J!-MBZ
+MFTLB4Y"4:,V(AW31'#Y]P71Z_X*6;+2@%;\7=O*"&>N'9H^>7X-V/=R1O7KG
+M!_+BID09>TRB1AAD^M"TK>>LPM)HH$_?O<!X/+8;7J>&$641CXSJ)3G<K@G_
+M)I+PPFRB`0'"O4F]6D9X.&$R+4/3FK>V(MI[7E5Z,GSW6+QZ9==$83`Y(-:/
+MAF_]^.%;</B&7PZEA__S_WZ"X>'HI[S"Y4U4=J2<F$H,"FD2,W`2E)U.![\$
+M6'5'I`)#UNG[.]&H3)K5`C\:,O3![K03.2`5,<5&/]Q.^&N`B@>)BJ6;!1:\
+MMB5I;FY.UOI`O"!9/WUS![MPS&\4M9M8H]A>-BA(VO1AB^M(Z6'F3@$?^E)6
+M*#I82]R,`W(IIL5IK^IP^]H6!)*HT)^A18[`1@@>99;E5UL$YW*2!:.UQIE=
+MOHL#CF)ECQB)&Q2`@J?F*4<;S-P^CQ#%7UX78EDET/P^$'TL!.;&=;.)D>9U
+M<#81/%L'`0A]T8NP`-#9+B-%'G\KY!?>R]3Y"U:48E+B2O$I8T*@=?D!*CD6
+M_9.P\9X6O:)HA"$A1Y2B9#[)M2BM2SM'U*(T3Q\X\#O[UA7OMNX81<B;+1<"
+M!E2$@]8]KY:<J)\-IT0MW\U+V&G4%P6S:_9?#T6B39!:$W(WMB`7!*J,F%X-
+M:`-I'T,[2@<+5D++>>A5&&PXX,B@['6)^FK`EBM*U`LU#003I>+I'96HI;@A
+MJICU-M,J$PFW(K=^D:5CFT;G[9X?-TR=1O<*I@^2VHCTR_P7=H%?S.F#Z,2%
+M)R1_<;'I"0-`5`A0]6R(QVWY(_W0J1C0(%D"3US`YMJ./\PN*6&-&W),R6$4
+M<&?<#<\XS"=QK$V&T;<R%<-9#4)N_,`[HM&3YS,*M"[@/6C?N$9H(F3$FP8\
+M*25/W(>'2GT`DAX_@!E1^?G4[ND`'VP;NT-7Q]:MFX>\4*XM\+'-%"\=<XE"
+MIX`ZBS#NA'G;*#QM0H_-UAKV*(G",7'F=BN/K0S)?$?293RL2`(5EP=WI;DV
+MX1_K6/FKKY2#SK"]'V#87=!)"9`BBYGW$Y4CL5UB*>C/977-++PCEQ-;>[Z$
+M"TGS=;A@[3\E,(,P%PC'+F8H*1SNY2-+3DHM-[;?64PI[ILXR)QFLVKG,!!A
+M^`,XK[./%G"4'&P)[->R]3E*ZA1[['JT3D&G<AIHR5PN.HS1&\I>V!/2_BJF
+MI?<9].JIBPD$Y2\BO`]O)<XJK;(@-,+P@,(-T$0G;&N[6(6M+H8R19\JM^!>
+MDFK,_G*DOZ_-X="@BKW+C:BK,[3KQKI-H1,E_U5?=U"4XS)]TJ%RJ7J"[6JL
+M6U@9M`N/%"6</.$:7W`#@@(A*C0[P,:(])'<RX3J<\$>?>H)S:\T"99*E(X`
+M:NA%*TAO%3TJ*E(8HZ+'LT:ID.Z!M@HXF&Y7`:1RW?,FJXDTCYE""<KHT%:E
+M]EC)#[@O)QH+LW5D-?-?5ZA7;M*5Q^BELJV41#9OA2+5$NE*Q_;\B].WFIQ6
+MM%:>98(9-\>YG''KB9:Q`5WM=(5P46,,#*$E7Q5-YS;5#<RI>Q-SIN8&5^NY
+M,SNZ56]0(6"4(:BB*F%LK?@U%Y11#A`#$T@./-B".M>A5NFTR4J58+^TP=RL
+M)D5#39*&!N$GN4AOL6B<LE$WJDD\?>]4OITK\J!D2II+O5W4-.IZ#^W<*'%3
+ME-EN+?REN&9<5T+VP1`E_G6U9YRV+L16C*V_;J.)2H7O:4L-T46UMTTPM91F
+MZ+9*!]@/%@'VAD\68%]YT7\(L*<+LTZ\;&&$E/+:B[);5LWZRTJO$LGE$I7K
+M/">JNZ*0L;QZ%62G]?_Q,7/]8ETTBMH(2JT6$]@^61C)\?!A*AM:A.^UVXM*
+M<<;63_85A=TIYD#Z#0OGJ-/)PXD]]1[>8+Q-V82;EE*'R"])',CL@6LH+$E1
+M%PQ[D>!>.WMM."V:$ZV50=*A)878OO]+HL4G5UV,A.T4#=5=9?1R-N)8J#RL
+M"TGR_^GE/BES4`U1N^.F3*X+/CO<OBZ,**9Z5*WAK%=/0)!6*GE\T+[A>=P.
+M:;AE$REP7"D:J'2S4)+L*7L0;?+BP+3HIER<R$EHOZD&6<+NK_H.:B3:?#4B
+M".$F0D)FKOTPI3+`X0M0DW&NH#@\7EK`#:,8.Z%ZV^9AH2]C[5L\E8JHIY!0
+M:U:&?88CW07"X8-[0]O+-K'9ZM'^[-O%0->\%LZ-BC!?L02=ZH!-Q<!&,]]2
+MV\=X!7OO`U7U>5V5DE>8F?$.)I)6>\/N0'Q%'=WVW8_0L6@EIBOJ9@Y:;BC?
+MM4SU:=D=1+ATC5N4][A>!`D.46S-Z"H@0'A=<6:;9].U20CC5U%E"?`'BO#'
+M_>_[2T2Z&%]LL^<I-[*$J_Y``UG0-[?H]M\>)>\[LAB`V1(E%+72X52`.:#U
+MJFM<TT>MG`>3YU*A[!GJ=D31'_*8)NPO-1+G5?825CL7V2U\1_$=Y$M<C9"`
+M.='T`0YVRL_Y[M:V";-P?:,#(YH3WF/U,P8WA?RX5ZCM]/K)/B+7^++/?<A'
+M8QT'F"[^[A9#%_^.GAM^EL=MC>B6PX/39(BTK6;]?HL(;<76*V/R;@'-2*&Z
+MPW6A5L7$IA1`4^*CL:B6TXN,WXP6'7,TMK-A%Q^YCO0N`07>-Z.M9A_3:GRA
+M<\TY7\!(0Z.V9M;/CS1YCN'&@L,I<>5!8LS8BX:+!WAI)UIHIJ%-G"I5PX_S
+MBM4R2WY#3<B,A(L0'_:,X)C0/;^]$W(7'TO5-ZR_<7%ZR;I&6"1P^K(Z")(^
+M">6Z*RP*Z=B[3,8LALEOHWK-U<^UVW3D"?#1:-@-%]BH>-R*A]P*HD\B=?82
+M/?5H7MCQ,'&C^N9,$NRK@D<'4_"HG5HN>P5R!R&2U/#JIC,3!R=D?VRBG10>
+M&>M;=_EAPJL0?GORA',`';B>#!5QE%7D%`QN<W>;3#8$MK5=YVQ4P@5C(&5<
+MHB!53J*ZUM*CCZ6304XN!(;G1F=$'65*YAEWQ!'+5)N,V/Y%(D20GAA9@5ZH
+M2MBK/E3?>4?6_F`,;)-PVD<5_$ZXA&3O&FKBK2`AR'ION5276@9+HELK>R'B
+M7/;J;:-*N+`E65+K21/.1MHS):0LFP(#U^R"?">U8A1T<R+TQC3-@!4WM>*_
+M6N!?T^'_^%_\8`;^0$4NN1L!Z0Y3\[)!!);F4&4_':X>VZ3A=D:<PZOLK^/\
+MK)=>]BKLG6P69U0WDMXKKF=7Z#=#)@+9I#0/]D]:=YY).2>7/RQP8'7U9G15
+M2$[)01?8GX7C#R:'DD:6;E;5WO%U<>;RGPRWMV(-S[%[.532E%(K$!AB'MO&
+MK8&B%5M@LADDLL%(P]F_(@LA<]A;!HY"A"N2$U:N7A\-<6R+%9/3IV>3%O3R
+MCC_W<"HL;'0ZJ'1+7S4:_68Q,-Q(\IBKZSJ3KNL*M#PWWGU)V4P;/M:MQ-:[
+MWQYNG]]8`<HV0A[&*7+>GHDJJ*#K>:<F>!K_TM_K+M7AZ2$RSF+[Q)E<'[C$
+MO:9QC%2$F2D?"+]0XLVKN,I;"$RN!@,,=:I2#MQ(!+-+)?K-F)`NHQ;238'E
+MT"U5"5BS!S;OHL3P?/2.3:OMD'U@#KZ//5W3A"R>WXAGR$(X]:W\6JX6OX09
+M1V*Z]/RVGRZHAW"$1OBYVX(`&'*!1OA7?QK]=.=S+_0*-(883X2;J&>MB0V/
+M\`<Z;,SQW;$[&6\"6;[5]UPX=L^/>5'=2S;OLOQV$3B@N@B32H*Y"&"YD,Y-
+MRO>1-].)J,>@+J?I^&9F,:4-RI1B.)FB6Z@0S(<.2-1P*1J)<*V(6-C_"A,Y
+M?P@CYY<+59N[[AS[>.!'_QD[3][F30\X(980I7XD.$G.XQ&V`[?>RYLJ9B@8
+M1+)F%/>K=?DATMP0BY9&`&:2V>_\*-V"#=C5MCXF0;+@+HFZ$3*Z@-%']"0/
+M6L^=J20;R$>L_R6@*,!H423Z47^2`N!D)DR;6ZTD9K@B]"HRT>2!0SW9TYVB
+MYC"1IY\U*_<*Q4?P,=4_H-^(,70Z1<?/B9:AJ<XF$EYL1/VQD(`)/4'T;,_3
+M]?'TMA./[2@35J^3R!0)&N5KV[&N4Y"?4)"];6F0=PFZU&@\-(T0?JE/5!A>
+MI,+%]E\]S`Y/A9V9K36)5"()[63]2:IWVE<GPKO)=8A\0"%]]SK&-XGBG%2@
+MQ,%C0'2>;)(1;"=>2'NJ,R3U2[GUJHA9I3BK6%`K18E'W[/6R!M]VUI'[AO^
+MMC']7'KGY(=R\]3G4F'`+^-][VT<(H4P4L);=8S4KK+8CE:S!T$,PAB)3O(B
+M?/\EIT(_,+U'Y,8#)L^)6@H@:^!*5`T*JW(!9B5PZ*&;X@]!(C/"Z)8(=U<B
+MT^KLUY^;!S0*)VKTFN5XC4HX^=UMZ73!0?O.8ET[<M3WL3MH`I-&C!.56PNQ
+M=KVF$U&<F(M):X1-NGYA_U*&%G,%9W>9!(:(>D.R^Y:.5AEA"*(ZS8+*I);)
+MEK*NR/JE%F:B/U`ZJI6-C!L_"F5I?*X6+0JURV#11O&W:?I/^L91+&#^66%0
+MK'*F7S[HK:0A4**8'LW9+0G[T2L:$8$N*OZ?>4R6,OCA/J(Z-?D9$%_X)!E.
+MQGTQV$PV,1![:#ZFF"OS2I`7[A3<:Q$$X5M<!S!OQ!.!M_5/'FYWN)I#>^?0
+MM&R".<":P>*3L?V3/ZLZ(^A>DRUAC>*'PA_*H];LMW8:;A>X8]A"A!5<J>*A
+M&);ZL*]LR#<2JFBJP9]3YB+CY!Q=`<E,PQY$J(9LO">*$F'&3D25LQ(J#9E@
+MRU/L_)N7'5WADV3EAF,6'XO=AO=N_/7J>@D\@W,\Z:R/?7P>Y7=RPT4B61"Y
+M]1+7GKFS;-?%O6%$%<M\?8O15-5JJD*;UW[_V+[T_+KB`IOJB@LXZM8TB0*F
+M5)#6Q1V_[T2*U.KD;5<V`8NMMQYT)!&,4J(?1.N.1R\@+WM=<5\<6M$7]08`
+MTKIB(?EST=?L&W54FVL-]R[J$+V31#T(JCRBW.=58[EH(OW^SP8,'.LX"[F$
+MWZ!R'8AVH(I?JNX;JG8K2/D_'RRP+4:W#"-*+,MQLP\+ZX>CJAX:S`%U0A(D
+MOK\`%.P1#**Q,QN)[Z:R#+GR2GY6"2SCV[2X.M$IUW;=_+:C)!9].H^N*FK.
+M=5\<ZU7PYR"/TB*NK1==88W&#($]F7]+_QSL%1R&+/^5\+.Y'J6:=ZZN>R@=
+ML!B:*2(6XSY9Q&+=/SXF8@$FPG`[SV8>9N#N]/K)Z>GCO-J*)'=7"XMW6S5_
+MIX3S1RQBW2K9.C%.3"[--$L:'75@6WM,O+G^J49X9?K9:0.;)XU_Q6BD_/!V
+MY#JC8OT2BZ,Q\'@A4+L1(PP9/!SYL<ZX(T)=M+<"HTX4=<:,@M<:$DSX1U5H
+MJRA#,+?]$F-`-1@&)9Y.E$!NL'`R6$/V$2?0_4G=!GT30HX1+\D/T0..K&M@
+MY@NPR=FD(@-DC'SAKN'V#EP@/GCRI_0=W63<N#K<)E4[T0:L&)`KIJ,FQ3M&
+MVE@^HL&GF>VAN=CT[=\B!97V<E0$=L-[.Q-#OOU;J&*2DX+11$8O7!61B.U]
+M?J,.H$!-A_:?(Z*'\#C?4G)5B-+:7$]!B5GB)-*'="R5R"K&]IS=T\4RU,N)
+MF7.4&4:'W^/N+=I6("=D(4X"[RB_"MQ\;%#PFV?,VKVQM>)KN*ST\(DYN%/"
+MIF+K%@JUBMQ/GI\WEFZZ&.HR.R9WP!%R600SDT!U;G0J@YFS0*,1HC<D1R1!
+MHQ*4Z%%/?X+5_YIK$U;?U5;+G+5#T:T<!/I#HH]?YS::\"(W/YC)M6"Q?5R#
+MBQN4N?._136C;C02$U$I&#M;)-L[&$#.T\:IH&-?-_4LC:U_;5,1A>RT`X"4
+M%U$:&%2?,<=H8)%JQ9'0@:@P#O9.G?"D4<#>\W4%7E&<4]8:3GOYX(;N-I_$
+M:EWSM\R*/P@C(R\T';S]F/PLJQ[A_=%97&R*R:BZZCL,2N2/3T7F&MOO7F.X
+MAK*#F>;WV/DA\61(S?!#:M\GR[2B,@TOT]/30P!=1LO))[IN7[U#.K$`P5$(
+M_/C"4[`\[&T%/U-?1E0USU')?AXID)?>)KJBF7<'M9;SS`]3JJUN_T4TB\7A
+M>C&#`)CPX)JR*/#1U$V<V*.:WEN>ZF`G/V&FN/PP;FO()=2-9#1A_*.=%%4D
+MT"#'.'Y$Z57+P+A"W5>[#3&SFPZE/CB(*<,P'$X;J\;*@*/#J`G554)6YY`6
+MCVI]'%9+O<*MT[1GJNTDX6%UH@"7`\_D?M[1+1H1>.D,,%G#,[:RUSMEC<$7
+MII8?R%W@^X2%;*R5TQ527[Q"\>+8/K\P>E,<.*GK>I2`@'%3I(O>6%^!`"E#
+MB]@(IXI4O%XJITPN,`,O06$8[E2X>??^M<J1>S"5@9PG2W2B$MY+#EVN;I*C
+M<(QK.'<7I&N.V+_Z6:KF"`D+A8C+LU<?#T9=#S.Q3KSS]H^H)0U-'F59K\<(
+M&0:CZ#8P]F]NQ-1Q[F.*8:5^0\B[HOR4?5>/+C_E)X*A(=?DV&R"(7Z0N0P[
+MY0)[R#_&63\0.:EU`V8V-\"[(F%Q-XP]3585Q9I]B8P'2.8(')H<":*1:U['
+MWP@O//"\JI*MJM*G\_J(--62,V_-UA&<"@K@:CAH;Q>:[Z!RN-*=ATW.Z1/,
+M&T@,@*T9LLR;(49L3AY;K_^)]`BNGS#Q/5G5!)N"($5:?VVMJ_(M(@/""B*%
+M118LC^V.F\T(*%KJU!:&G/:H<>5T'$4TLS'*Y$DIOZP09[YZ>0ZL.LH0>F&Z
+M;M^-;,$GRPFX1UCU%!)!FC7PTQH\W!4XQ=GJ`-9Z)2\DBG/.=%1U>*](.=,&
+M'@*X[9BWVKBN)QJ/1A%?K/R@-;0JVO2M-P'WC^WL8[+/>#XBNQS!Q-VBX4P0
+MH3\X\/(19CF)!KQP1YN`)2AF9<[`8(7C3FON$R8>[K\$,F1KXQ<?@,4>X7L3
+MWZ$ZLN#E)?N2;J"I5<8-:Z\MNY2?@I$!1T":R68E#)TXW5(O0;URZ$/9;F'G
+MO,!O,E`KH#]N"K4''YA.D0?BGG@2"J$T5*R,X5%;>*GPZOZU1D+IH-5Z02J3
+M.*)OHU0"<3*D-ELR5.!%-[]MUI-JA6-\_<@5"@TD@D^8*J&3CF7%U%]_VI.5
+M4[0,1`T;\VF_6I:USOO9ITOW/YHU/>+F]*'9BRJ'-0M@Q$O^-RAY%9WJBZZ!
+M-]XD94,])++Q9,EZD8TC:JMP%41$?[5C(M#44/&E,H9PS_V.Z,8IO6!<TBTO
+MA0TU:$855?E^J$,Y!BV55A/;6^XLRHZAPK%<RQRX5#H)*>4"9D7B<(;!F25I
+ML4XL%RF:D-3&'>H<C_Z@V'[X?:[E3]W!'?(S5"NR'67$920X4OV/5YE3U^`9
+M3]$9U>RTFQ]4I8;-"G,S]Q6YC"(/4GC*V)VE^H/1^K*&V.4T*.S75M9J-GR1
+MV?W>JH^XR9"][R)-@+2Q[4BQ0953EAPE'Q2ESIG-@?'^KO$8[7+73@S"-?>?
+M>%F1P$.*D/!SPIO)5NSU^9Q8W67*BRD<%S/*B*^;(K^TO&RNC5\P@;*H:YG"
+M'(2OF-UUT;S^Y=NZTJ:3`LI(L<BH$J''8D!.NX^5^SN(K>%[]4SH@LD@EK@J
+M6`?MG1V)]F7E>,YF%7"O^GZ>($%Z'%EU0B&$Q2W!L!\^YIN])_JXGH'VR$E:
+MS-Q\TS+#0[[@7J60P1H"C]VJJ31>C\OOTY77#CXJF#IHS?A4E3KS9F/KR\<#
+M]\W*]NU<\17T<;ED5#Z<A`J%)>QGC9`SRP$I'2&V#W[&`QO"/N).++A4LP]^
+MC-<SS6`2:"09,V2?<(C7DE#:RM-==40I$A?W[[99U(J6@'D-?]UG&=Y9%J3V
+M<ZU$P6F!80@?G<*!]W/03C)]5.2=]8@B\(+9M8;]GZ!P!9H?J&V`L9!S";5N
+MD#OK(<PJ%`@>A5$HBB]Q=3<P,&7[95'$O3ZGQUKX7(YM>FSF@HV123N*K=[/
+M(CB-:^@O?$X8X)+&0I-9UTVC@$'."4N#9;X;9T[O8'!=2+U'`J)@LKO@R*CD
+M#?Q"EL*']8)6T%4"ZDIT]*2=DYHPNK,&:,ZZ6M:0M![Z,RHL[2MR"/;"EO0L
+M6U=N@$=FM0[4=@\NP0YXSW:90]3@,6K_8%0I^_W1P.<WZ71PNK-;[2!20E9`
+M]6HSGSX\?6%U8BHPPW&_YU(#12Z44Q0]&I`&9]<RDP^AZ#++):"<;7[6E\BJ
+M=/K^H^\BMKM^0085/PN_/:.+"CXBDI`_`SK<^:DV5"MD>U@GK^Z744G'Z8)[
+M^GQ1\@8.ZAA9;PPW1M*AVM8Z2J^2V#5&0+1"CZW]?\T]S<UVR$)>;$K+"S,7
+M?OEY));+KG9Y;^+B4/]]%>4\],&U1^PSNY0ZN9Z/'[&\!ILKZ0:%"A;^/RL7
+M^'C_U'JIR[B",/_E,ZY,('_P(G)*A-BDHJ\^XI:81(*_+7#-(B/5A^*&'/;W
+ML%+[_3&5RT;#("@DDEX2U.O68+D(Y%E`RC+HB9SZR7OJ"]UZ>1%AONMSA.%#
+M]P!;1R#LQ[ZV7';HP!]0+0,M`<)J5Q>;Q>8L@9X/^!7FH<-2C<**P/%5$VCV
+M[<"+)E:H"`0?)M;DR\SRC:J*JBIM(;8_.(;33C>-EJ+KF)UQY2G#_3AT"4+B
+M_6#4!!%B5.U7*-TN77@0KOK/5G1T:RO&#T2IY$%[Y>V!XKE&7518^2D=6RW`
+MD(WMKW0$Y6Q*(DD,'KP6'T8MI.QV.65*_7(4#\*XIMA*F09%'!8GCM)%E:+$
+M\3VC:J5*\FBKC6M^5[1+CL<=]%.S9Q&5D!M%E^M-@F)_R:@E2[C%AG-O-HJI
+M;Q>>(2!R`ATCF3+S'LVOT^5-A]O+[AKX"E9]X\0APPWPQ&PCD94*'X_,IU?1
+MTE2U8<RKL[^Y68948:PK;^MD?Y!H.P5KZQ/IM@SSIBC#QV4D4AI?;"WZ?*J2
+MCO2,J45$0^3,\9L([2=GH,?B_,I8YE=&34=&_%'$^99'U<8[;ZZH[H`MP;/K
+M.>DO=$19-.30:I6;E((8V]8D%3_WN)N-*13KS!=YEB820QUC;/_U7IQZ7M@G
+M7KE^QPG61T8D.L_$`L-T+>\'J"@-Y>(1%X&MECTHH@HV9"7M*HS4F\#HS"%(
+M,C1BM]8?OHR>2-&Y<,2>XK6<N.\*H*R5&Q8OQLCSKOL>N3H[:+W]^5!WW33P
+M((X?6T?'C)Q4AH8HQ*K>CYW&SFGO'TV4KW#[\"V['S1IM18]PAL$C.YFT<=0
+M#45FDX9MERB;@4\`N<N(^Q26&.9&&"]ASZ/$DYW-/3F)&3P)=:&7RA2&-^_V
+M"K'U\DZ2B5$;&DD078'(>2<FIFP[JD].4DB7$J#DI2O^4&^'C$((ACU1=H$%
+M4SI'?7TIQ;BG=2J;4,6VX'(V%_JX=@1;/K+J)>DH-.DZ8*[:-/0LQ?8)OU$.
+M?M)#^!W"YST2T')4+?.[!@V(KMGNOTW\FVH[`2,_ZQ`;9$<'UP=T\\JG!4)E
+M_&O$4CB]B'[&"48ZMQS;<TYX0_4"I\P)X;"=B(`!QP^)$6$UK/>F+5%U715>
+M.I6C.FA_X3ELM4PZ.38F)8Q1@G8E.@2Q/U,/]]2A,$I2P!K3Z0J8H`B8!:"M
+M_UHEN@Q*:(1L,0@WX>_A4LJ%4,T;K%L'>#N,1%_4\S7>3Y:.$<I?S3[O5EXU
+MT/:UYZ+.&*$'N*13NTR;)"MZQFA0`^=%Q@<QM#+5I%@J*-B_WO[[#K)]'D$H
+M1K17T+)>>+2[3I:6)SK`,?3D4O.,0`\KT\0HKTED[C-<,^\5=/V:'"P(R&CW
+MPRF\LUM87V`9^ZOSH>HZO;(.@*P]2MO<K_61$IS,);<(M[',@6:_`06<]5E1
+M\Y_TQ>1VYPSE%A+?JJU%<HNMVB5US^9H3IC'R9E',B5D]-:)"G.$%:T.>1%Y
+M%#Q`PI`R%[!E#7[!"EJ>/,&"&;<TM\*-^>H<D&E%Y#U!3SAR'V/[IP=75)_'
+M^NRUK;1S]`I1JG-!'F3'G\Y!ZYX2/#$<!7_'8?TN;&?B^:GNTV;;1Y-=Z`80
+MHJUD\MUT$*2"+20I/@!&YG5KJ;VB(QH6H+L=85;:M<!5SF+KX=]QXT7EH4BM
+M"EN6;M0=3=/M:957(=6^.L[8EYNMI\V*^S-AS=TD+5.>;SG02>2=R'S.'$_5
+M6^;*^6;R$OZ4'?M<7R,HN77*G(9"Q=:#YQDA#T9F;9VP@+?\Z@\&ZLCLWPVJ
+MT`Z'$_#9R>7@.6U3U3+'5@P\KM%M513Z:JH#Y!PB\#CC/QD>)[K^/V00EY2)
+M,.Z8?PH<WA//"BJ0D6N]\SI:)THAD;2@I>@4%5FNPCKL1)TP"!N'K3[+%:G8
+M2>J5)*A\`651K8U=E>VD.U)>13:V?GT=.U(JE$_STW5U_;^Y\Q65AT#@(`9L
+MR]SH52$\*`9)FDRD#!]1+RS0V9?4$%XNFKB,[$^-+>V:9$+8#&YIQZA`@V<C
+MX\3HI"LSPE1'NQFBH]UQLN4=_@R;WEV#H4OY$_S1=N^_)0;6F82%`)OE]:&-
+MF*<$`+3[.YU<3Q]\3A_*1)05;DFX#'*Q_>4W53<)'&0DVD^`+0G1+>J0!T;*
+M$>=T#=J_7I-S2KWA[%K#IMLEO@91^OFD$SLO\]^!DDYYAOM+)#`J.=>09JH>
+M`0%4FA^W+&!@"67@1JI1BZ&4&2B85,YW8X%KW?='ZV0-UZ&V6N:/.^"\8-T(
+M$\[\\5P5OI..@]!LH*%RH,#\*6!9</(_Z76[Q2+L<OM3U;K,5@4ZU).+TE/"
+MIX:0K9.<[_%!M3%!7M>XHXZGR]2G4`^@>3P\;;A][1#6N.S'IT7*U3JL\O?(
+M-4O\5"UT^_E-;'?F4</;]KL,CQ3[8(1US8W8LOR>K]3N'K,-L`S\?T.N5/%F
+M#2_'S73*&\_=4Q.6:@)_XP\,T[GAQ4BX$JG_;CFO^Y=P;YQ`U*T`P9B0`B3D
+M'6=9ZVZ\3]Y%E4!UAR[X(#`H`QN?)E*?E[J:(YM[)2K&PS2+'4GM[U^EH\XP
+MTW=6+O.Y9@GN%FH:Z`9\_MW`1_=2!0%%7!I<Q\19;R:FX"D_C53YV2S!,J,*
+MF`:$^+_7=Y+GB2_%8.;]SVBMNR$\N9,365`\8C$V^$01:)+N\,)M'MF+$5M/
+MO:\HE?M"(HE&(OT/SS;Y6(JJ*S,`+'3Q!418->NTL[F2/1-61,2;"-)E0:E)
+M-ND?Y0;H**EQ#S!7;O>_=9"4WOY92K/?\41LBZSW)L1O1J-/U1G[+>J_!JL:
+MM&XY>'AYY\7G[HDL#]M?A8DDR,2@1OO]3\TUWB";\(:$,Y!$A]CP0:MU,VTD
+MJ,YHAX`)D@]@,T[%\A-()/T)1Q<25*&3+D(RH2612&-*5:<0(3IERKYV-G8"
+ML9Z_0'11EMD,7':M.^#RK:I-.VRD4^:Z,/`H)@ZHO$Q29F+K9U6,<!'BCQ16
+M6:8\$C(@Z9%_Y:V$G1_[9(<@B_0^QIE51RJ\&B4I&-LNQPUEEP>MXZCRP'`O
+M3]\UA4O7^$:L7'RN0$PR%DZ]:GND)3U5<SRK>WL=OL,C?.46T:,(+0;.)P!!
+M!;OSK3M5E?H<EH-C58Y3E9>W;7QP`-:C@M"<TWKM;0C>VG3NGC@;H16Z7`B#
+M?3.="1-4DB<FTNU@.4[9:YJ9]J`]_C)$[@/QY9`(A.349(>D;CW->.!UC%_D
+MJ%U!,\5&;J1&T`3:-Q`4[UUA8$,)F:BC^.X:L+;59><4'+[NW!Q28M<0^HAN
+M[1=6&MTB1Y@^M7$]YR!!"$R"%_AJ;-DKG5LF6^'KE-86]>&5Z4$X)X81$O(9
+M)UX![W\U@<_=7N"6%*).6$E)S#X!G;+1X9RUQA)350S9!ZEE=L@T0A:BXH)9
+M70RA&)*[V""5T<8S2(S&2U6`1O6JE=2K-NK55?7SF-U4P>`BIG4P(H'VD30K
+M6"&.DV[@1:)P;HJ+-3S7/%K^-:$?2"DE57I$EP&U./)Q`O&<FG@5BNQ*\SYU
+MFKZ3*N4I&UQ2L$PA>14#V*N7+Q%ETKNNB;DPU*WA=HI5#:44+/H(&7DA6AO-
+MB>#?4@-8I*H(=[]#@D'$ME&?DNYD>EI$C=:_"#)!#=<5]4\;RB8H/;6FQ2/$
+MF8DK4_WE%%<2[0CZT;L\]ILGL7W!L@F%;[=6KX;;0:?<_;`A@Z&)Z6'7&^K`
+MJ"JN`Z?:HX7+Y:`Q2,Y>/P2I5U8PC,',@G&K,+@XI;DV_J9S%XMZ5J@@@&ZU
+M\>^4DD<]P[$@(+P\&4*,'5HWB+!SHC54ZD'GKI-!#PJ!]?L?;(_8N*!@RGM,
+M79G@D(^K6,0,6-13M&Z=B$>D:.!=$Y4MB$-BDA/1K@$9\;N`X0_=)'P645<9
+M(YME*A0B\`B(K3"\$5S1"A-9-*_B^!3G,9-E.#'LYES>H,J9#R+>"1_-YG*Q
+M3$>4UWX@YH`Y^6AM&#7V']@R;5H]=H1;\@S:][X&ZDB(C\R>'6&=:(PO8+EH
+M+$^QRV>HT3+&\O'DN?85X0BIM[NB*%$Z3&Y.SKA^(RFJ/H9OO[6W"D4(QR*>
+M)9J]G<I!EQ+$:8&F8@CV]YXU^9J^E0W#_Z0P4QD+.8GRZV7GL)D#M3UFSUO-
+ME:@=/DQ=@XE][.+JUNQ3/D)(G7WL?`JP\,$:E5/Q"BX&T>UB?7?X`Y5SWS)U
+MM>HDJ`.\Y)ZPEITOIH&W;VHH0'$:^JD*7,#`HGB<BB9[U+:;&[38+WRM0\^7
+M1R$S[[U$5Z10F?*8S(FOT*'^;)R9/BT,LN(7.IZ-Z0GG/8MV.^*DZ0R0HIJ0
+MZ8"L9`_FM3]D>I:DSEDYG&ROE\PU?*FG5HCZ"F\U*?';12*J7>+:$J(&`!K]
+MNP^](=,!9\B6CPO!>!?7!ML)YKC';BKY?CZ0$.'[F_Y)0^MKIM1IT0TVC&3X
+M@:Z5<$DHYR)ZAG)%6&N<>:"8`[UGG2N:LXJ6-P++'&ZU'[$.U9!/%\3#KN>O
+MD.TOQUW>VMP::6BH*&@C_`Z"A3826M,LB[D6-)C,\0<1ZT^W%`=^^>18V3R/
+M`TN<C9X>VLA4%<441#C8\-@*)S!!)&-[VU\X9ND%<4=U80<Q5TKZ38'`@4`F
+MOF[<)F!R3FS?.3&-*C-`9%S5`7<++1[AL4#M?W:M8?5+#D9@C(`39LA?ST#:
+MV$X>01>:,:PH0&J"FX^J-5SWY-PJ`OA5H=LHKQW]B(V/[7L.&'UR5-43$QG@
+MO:\]2[!544'4//PT;@7TK]A>_H(DD)0D[#Q"=O:0W7D5<6F$K"YT:1A^<6:7
+MG]0!PN'P][MK+J:\]J@9R>M/4#-U[%CS$9>Y9@8%R'T&(M-A#?10J1_'3YO_
+M^@8Y(04DS%H;L?7ZX012)#R0]J%@J/5>;M5B_>5Z(R$<ZUV[)CTA*8_6KQI7
+M*/U@F"<E/0I9SH='82WUJ&PBXP-)T0,M>?;`#3N=<H5,+56U*5'*K9$MF0H>
+M\2H>EAM!8.[FZ#\628;I7^_RV+\%`\+?DO3"8^,T4'BSSEA?4>6:8O;Q-SH2
+M_",C/"#[9/\O"<X%`5\D0:<+@F`3E/N-<JR82B%*HS\Z/YVH)"B#6+%1YMQZ
+MX?>.43B#+ZT9.W__S1$2.Q!>VE3-<UD!M);9^2J"N(P@?=EC/;:^[8PZ&Y1(
+M1#2JA5_"OE/C*@`EI-`VV<',2Y>C#,Y\_=T^F2`YJD&L$!XTXVQBUA4VHPV/
+MW:DF=%0MDZGI9G76B]N("I9E5Z*HT4#@V*`,=^K2N%DNG"6<CUBY2==>;AE1
+MK*J^+8KUZ&\9L5W$?@=HL&\23HH076\4:$*MARM`8OVK2,8Z6/AH6V]KW1Z6
+MSE/=U,/8JMTVU$@12M%"(N4<&H2OU\3:MV!]MP&T;Q4,9G`$#LH4%$X#0CA^
+M,W:OGKI#'S?D+G(56G1,'+B^#WV*4W<("ABT#-G86"6/>4JDQUNE>6V<.?#2
+MP)_"&K/"WYLUA<DJXR*.H8B>TQ@\J2FQ]?*3V%-2&4I3L-_H7XA<==Y9Q$5K
+M7G[2P*6I_@Q<5"*VG_JYT;*/)%>?AYIX8+A,G_JY8H&4Z5K0JQ+]"6IL0Z-N
+M`\<_\5]O\[?SM%D=V^439%=+NBT]'D=#%8$3(K="P'UNFB[?`;<W<^0[J:[9
+M+2`0+CE>]M+#&Z!$FNDXRIR_BOM`,9*1%@XSB<[4>DE=,^Y:0_R6'';4(>W;
+M)^"0:CBPL#.+?\R24SNF4-!P?Q7JH-*XT,]QE8H<U2Z[>!.9)S5X<K@=OI.C
+M#97=DD?XU-<O5FT31`NPI3"MO1ZM+F7M,+/^+DWS..0>KU&%#5U4G6:G/";?
+MFS&"?QCB6C2`SLGG-9\*%,50G&'6MBP$@-S.K2U6?>YA6]K>2U?^(/V)`UVJ
+M';UQ&XS+0/&SWE!B`:;FIHHR2K"A1"E%*C$*=+7C>R^.?OW;Q#IK]C9'PS2Z
+MSZ?#BJVK)Z<Y@?:<A<:APA6WWUVI.H'+8[4&OVL(AE'(574>@U^.$FYN4CM'
+M$G_LFT2VF<GO=0B2A#W"BHV8/UHMNQ*A)DM&U>`)F=`7&E?!GO,E4?F;XKG(
+MM-<D(&2%'4GI$@&WNB5_AJ^SZN0HH937Y[_CJ"K,S'F%C*94M5$*=\']6+>L
+M8S0"FW2@X9(3W034!3*;CN#"G:(PML,:/.C!92^JW3+[W<;6-:\*)#)UDMPD
+M.TDZ*'>2=!,GX.4_^G(?.8A#4?(;QP,%.[86W6HV??($>5+.Z@$8K.A]6NJF
+M%#GF*DI`%L_^H<-4?M.A\T-%Z'S")PN=WW7HB-#Y%1_\X[K\ALT/%!_?P,[$
+MS?>M./C\,6,*A;'O/OKH->,^^G##AHL??6QSW_.;OC'FS.<3_&;#YKMFM.+/
+M#YMTV>87+GB,?W[.O.R5&S9$U]ACK&^,V19?5RC4QA:Z]%\:9LS8_.^//@0#
+MDDH,(\?&/#_B)GM-.?%*]<N!#;7>K]XUWPL1H(#9M7B?&8?7W-Q<FW+O-9O-
+MMPS`9KQT\?8J4TG8PKB7^',GR6S>ZJ0&!FZP"]VI%6S]Q[7NU_=)O?7Y?U7J
+M9S+V&_.R'_<Z<N=\DFTBMMPVB'4'#=Z=S(D<_$7]9@UIO4M(0L'R:OL=O6RT
+MW5+W1C4=',F8<8C:U']<^7'KN?*3+V;>*(O)_5]93-K4#GS#QJL=MWSL__OY
+M#^KY@ZG21@54\$]1+G*P++N3?,S<B6)'*,^T)9_X0(#G4+\MXT0$[@375C_4
+M_X>US1NQMMS_O;6-D+6T)F&$4Q-L6ETR\H!'6='_O_?S.L4+D-,>_NBCZ")+
+M)G50U,$A9/?DCA::_PH7FYH')NRM8/P-=E(4#\``)0P&[P!UX=U"07%2^'#M
+MT6,4NT7F?H6U[2F7$J+IPTG`F6N9V8:YEVG]7%WMSH0+=QK-N5!70X5#*(2-
+M8-&)J`0,1<7"XH9#WTZUO:7;B5W-P&*?EJTU_/@BW7^=2`)I`ZF"Z]S#.`P!
+M_<*53#N1T!I1`:B&HZB,ZC9;5W_%,&9QI!-K'SXUJ>U8KM8\/`?+2V<R;PN_
+M1&*D?6`>#=;M(TV@TITP,IP?$6.AKC9HKXF-IW#_P7@<>!UTRZ$L8<!%;ISD
+M&$G`V`FYIV(L--@//=SP3@FNHD@59';N>E5&!Q1?4B'K/%7IX[-G#H]DL-*,
+MU;<I,5FQR/'-H,Z$6N_X1[8]D4A1J+EQ9NEOE:8[2NPZ0D1XW82TYTPIOM+0
+MFMPQU=FJ]OOI;UL"$8"U56/;GR2S[)7VADIJG<G,NE-2%?7@="J0Q,/1F5]X
+M@5%`(.'L6-F=1]6"1$51`G@Q9H(`E_KX<YR9NUYMN4#0<EDFPY5W]?`"T=:N
+M?MMS.M6><+=QYI9;8'L1-&"BBRJ!=N,H_ZS(AY'0);V>V+KW`\WMP&(E$RU-
+M"PEFPUM/5$4#'5^VT:2@N]$1NOL1@\&8'9`;=GF<+`CEXN<ZE(%?J"+>#RRD
+M]=>%@5F`V3JR56O8W.6%0K*@=OYZ:"&Z[V!&WBRJ:1)ASA@8%<SR0N89;:KQ
+M!0OXH6QL/?<-(2P'K><J`GQ#`@9+P*,[WE#J>)2A,-(_&\)=^,/-R&`,>)GU
+MO4O)LA'@2YI*-YD6,.>.0<&:HQ8$RIRWF*,0G``,HSWX#A,S5<0CM(I1-H,+
+MPX,PXP)*R,94/RVO+%WD!A+J6+<R-8RWN>%\#F>I/`>5?Z.SN<D)CA.;K7;)
+MRXM(H`X$$J#HKQ2HV_Y7%+=%P#%B\>LQY=2C632/(Y`$IL]$;PN?CX'\\_+"
+MCD8\5T4ZV,SZ)R,L;`H.HY/DX*LUI8J?&2S0B#<G:(.O6[TB`,HZHD^5GDE/
+MT1?1@^^<S,Z(/!V:$XF6`3J'S)B-H;T9]1)8H?\XADP^CRZW,GO@FEWZ;Y&H
+MRE6D;L)6YQ2JDH_07OT@^[L([2%2[%ATP<+^<>\2^%$TO!S=DD-F?`:6&[Q$
+MA:_Q!RAK==2??AY;OSQ]R,QX4+P0QK6?IG%I!WCU)O*#[>^$$4,BWCT77;)G
+M/XN'.943Y'5'E;.?9=[47)O@O"]"4Z&#Q4Z<<M%S13<O`WN%B5]D)*%!M=>;
+M%%,8Z=]%S%T]S\S,:%T1R$P]$^$1VS<U*MO+%0U8O/S04;6&WRI/EHC^9@?M
+M)R_C-D&*2K4ZDTWZ#`PEI5QC-[[OGT3%_4W%:N2<9]?L-_]&50E9(T$W(7"#
+M?YVV1'2<%Z.*.`;:%46O!U^'%:U1L!&Y\/V<$[$BS,&'4^&H\.D#IYXEWWLJ
+M!2[H"]%O92EY9(';/+(70JNL.W=0M9#@5_0YHR`X,Z@DG*.4]OO(7J9>HL0/
+MJLO6ZAL)B8M[->J%I*V>FKJ4]DN'MM4%OJ3\`'[QWFWT2';0^N#RCSD)L?NR
+ME6,J8)?P-8`!3#A9;/_S1='IMM[;V'(?>1OQ%Z:/KQ,]SW@$4SDQ`]4#BD%J
+MS0"3R?;Z7!=G%XG"A,PG\/Y0EJ>^X2B"^(WVWB]@DY6]/@<L82J7@U=XFJZ@
+M@E[\4<X;1HKT,%L_<D)ZD'K.T2=.V?CAW[8>,(&GCJJ-&[\8B%'A6_MDL@EJ
+M,!KE(:U`^Q2MQ=`Z^9P%<T:4K@`M;4U[%$_HS#(C=#CNM[<"6\D.9@X_"#&=
+MF3$><SZCX#%326)$2XTJGSHWCVO7@/;A7D?5X[X^*>5W,SOO"?>J,[+K[U9C
+MNZ!/_&.S\)0-6F]]GYQE$=7W4&$?=(*J*N&9'6>O".B:Y0-_:@6S[4GM-,K[
+M@C;QNZ.-S1\MNJ6NQ.DH/S%@2X*Y4Y1U/P!1Q;@;*NPEO(D,&1EG!8P/OJN#
+M8!!`CR_]F@B;=[A8K`]JITE%=R#DTBFG;&;`#XO0=,M/"@819@S>\I7O.T4$
+MDG5U&_$YLQ4INM"*8-H5A=3#MG/4TDI$<C_^.EPX=L;4LQI7.>*Z.;I$\/^C
+MYPXP:OL7XLSG7NFG+D:&NHI<,=.SH`M;E\E<V_UKXX_??8FJ$<E-O\@5@B`3
+ML[YTY2P!KBVK7FB1ZC]O7W",CKUW.4+/%FI>F(9OZ,C1(<^1$WA4:/!1LU@9
+M(*Q[5,484K&NLYDHZD+BADK!$NS4#%.V!R*K2#JPJ/#^@=-&:(OB/SC($#=#
+M,VH\BP?T.;2H@VCDXVCY/[2]"8`<9;4V#%T]280$%)`=KT0T,S`S,),$)-X0
+M)@E+<I/`)8E`DB'4=-?,%.GI'KNZ,S,HBZPJ)J0I*(H,&.%B!#=00*$54#\7
+M1.2"HB+@=5<PX$9`D.T_V[M4=4^2[_[_?[_O7B;=56^_ZWG/\ISG2!V1XWZS
+M/RQ(EQ*<\GBW6;=N?JZZ]&YXKENOG$T2CQOJI[>1NQI!#V.25$3(LLT4UJ9*
+MB7(F>M>M8`UF9%`*D.(5;1<&D`C^I0V&]`2Q=WWEB:JJ)9WVI#V[H>%-D66\
+M:\A'82D,<VHMW\:K+%QC,XS#\],CI_0D$4YB)#-1X@$60V9'!.%1KRTH>*8L
+MMW/%&"\,M%"W-'&+D(2RU5MF']JHW%+(H\P%R952+@X0VVYLF,66JS[K6S-M
+M7YH&8<46NVG&RD$>S[[W*+I9N^RKU>PA51,\O6>PNM%_O+2HWZ#<8).T;,@P
+M[DC+'C3_L-!Y&2PY.$*3CGRACQG?*"G?5P2<?9C08BX:^GEV4ZI^1-G=SQ(;
+MDSY$>G'H!CJD^ED\-&!A;`[UEM/Z*>-;A13W>/BSLDFMD#1H+%UAO8\<&Q3X
+M,<T9F,YXR](OI/:",N_::RU/?TNAT@GI*6!X'\Q3\7"@WI0<*+;S'IKQ\#UA
+M+H=#/>09QI1BCQ*!TDW)38-#2N(5,1G;2Y>+O[,([71'F>MGL>YG[SZ+&CN]
+MP^E-O,JM#'/2_B[\0$K[HW[CY^EN&[G;T'F#%&/?O_3?DI2<CA)EGIZGBEFQ
+M60PW7VG`XW)%:+FX>:E"4(8]!M;!6_UT76(A.0.O0H[!SXT*RBE,,)U\RZTD
+M#WIK8A[:DO*X;E5^0+GXQ$.J(`_6Q'0#7ZK+J-(ZF""-QA?M,[<<)#:^M1-L
+MS#K,Y0$OU(EI"F6L(G/BL"TF*>'N'R7U]T"D,9(@K64#&)P;TN2]_#,Y'YP]
+M;=&6BP>9'K0*@";%;(%23D&R?W05*\"_N84$+`-AL4T_S\1,B-B@`RYCSY=B
+ME<NL]VFI6O&B[.HK4KM"^P<,8B\G^I->M62W^$'!M^4L72N1=&#564[%5-\O
+M,=6W[5I,]6?E':0C)],.&J]E.M\]]MW,GH3RY,5-A!U9),>OF#_1Q4VN^@6A
+MVT57]VXW;MBD3B+_C-SIN]W=<:$M+*G9]=_\M77/4TL]V%+HX@-;]G/.8S.7
+MO()1RZG]Q-U7`-GVTR.U/J65:MM85"O)8M3ROL%AC9S]9W(B(&<S$),R>IQ+
+M<6E=J.SS6O9='2Q5L/:>NW:P1#,6OR?.K>W'FCQMVK,C9N8E]\&TXW/U:DJ3
+M:.4*OH+!:&O4+!0LCJE#.=15CPVP3G`J_,,[$,()_Q7Z;1]ZERN(0M9(FWEQ
+M%<<E230X6;/^>QF=F';M$B@/U9R;EJ6OYH9])'^F]@YEQX,&$#G/?R#M13!G
+M*>V)2R(+E6G>`ZW$8R;4TVPXB!^>[Z/6P9HO,W2%&E?4P,@>969-1?T>"?CX
+MZ+OB(H8;[/&SEI<8U,@%K,V4JR1+M6X#3`/Z6%')MR9]FU?+MHQ9@,3_.;:Y
+MQJF<4;PS(^</?V$C4--[N\$NH21#TSWI0>1\X7X2W`*QK3D_OIX!R[Z%#0I;
+M-:2+W%C&!JVWT=TRJG<K%:#/1\[='^H3<BJ1O7QX>E*J$SQ73^D$SC/OE]V<
+M<$(Y09#8U6FR[,065F=83Y-RMF.5Q<PK@1N$S1VY#;HNV>%J<C)O'B^D8';A
+MB"92TBZG<1*3HX[1>8HR^U^+!92;W,CQ".RO[U]N!];PIT5>417KAKH$4?;3
+MN1TO?/,CT>+,2*4HZKW5,EUYVY)>S.P!>RPOJ5@LB6V4S'5EPY`!ZPZKPD.F
+MRG?F^_D)EPF/!C)-8!`X<>29J-@40[9!H_O<+R&`I/T%2O]^7U@AO6"60L7&
+MEEI_YYFS)T#^C\2N.O@F]I7SN$X!]%J?;:3;A)WZ@<N0SWL89FWF;YCY"#5^
+MCVA56!W25QS.E9000;R:T.'K/923LN`Z*55D.I>U(TDL3MYD`;AMWR.U]YN_
+MG7@'))QUF\E9A[S0M*<[-'WV0)3]X^*)O4$[W$[62<`K6_8&"I-W1.@+>?O6
+M711.#0VZW76=<8?>K=*XT_,N)"8O80V^(1.0M_GC:]DMCY**H&=IR=L3$=RT
+M7,6;\:B]K;E2?F>QE(VT@[:.N3#0G.+*'HZU1U)HM-4%M9Q&IDEIKIZ""KE?
+ME/R.!1=J_J^I15\E!7%0LY9=<(P*7,(>4C=GP,%NN/>J,Z2,=$J_4M<N6FOP
+M$"H'1`U9$VK(6`TK$=9"9`(GM@X2$WQ9`L=4^(WJDW,E&?34H1JV,Z62Q.`N
+MJXJB%:840';TZ')0SH&7#GET.-PB\CZAY97G-+`PE0.6KO-CZ+\SYRTA-1ST
+M+H\UBLJ$B5W"T95(I-.:1RW3]1([$J),]]'D?V*X/N,I)$.'=0WE_RNX\).6
+M248@<T\?02GQ4Z%MW6F*7)\Y2((T>\IFJCL=)MCH&P``1#)CG5.KN@`'Z>?A
+M,ANE@[%MI#N;B(2;SW<QV\1<24!M/0ILO[!++<BB_BBS;;;ZR:`XHV)GE"C>
+M'W5SSFBB:9K+'56TO8ZHL-8\]2RZ[?C(&6Y\"F.Q%G$46YC,J<'E;U%W'-4P
+M`!!SY,-\U^J*;&8Q*.7`X.!(:<8P)N>60P_>?1/E(2C2NXK>,YCE/LW36>XS
+MB6=H:8EXB)B?:-/)_92MJP4<>66MC'8,2F3FE!)!":N*4#CF>X5\V#1:RQ3L
+MU:*?+"C>66OY[YF)M.G(>?C#^JUQ9^N)'*;`^QBYR%$`*IQ%S%%ZWF\P](<_
+M#&IP*G.8LU\CYX=3$5.%J&Z66V02S+U>%1_<),4'3=%,IG]4L1034C+N:I0W
+MFNFMU2T@&6*;,K3HI"3C`9@`227[^H(/LE/)%/U;5BJ>X>6PO-]J_KHW6>4/
+MO\3R=NDOJ4(IK!-^N8`CK*%J/]$`?E;&PMZ+\LG"?WT!ELZC+\)DS]3W/<-8
+MBH^_:]HXR7G3@43/^2;5[R?:7NX5>J1V8?JGJ<]+/:^"K^I1VS55)]_R]FU+
+M<5X4*8W,(>MY4N"\693!XDZ/6EZ9F2`PEJ/8D:)8OHZ)M"?=^6<,M8545D\1
+M&G?6IGYWVB+M"94BE-&DS!>D,/*D!W8GL0QZ?YRCH@JZ/!9TFD969\B0BE_>
+MG`A>3LKNE<3B-R^V8]QKT*-G;U)8`39IA/F3ZORU?.1--VK9_1F20_BR[9=C
+MKMZ:IN^MHXN^J2&GG&HPY;B6JV7V]7][VT/]9V\O:5%7W#^@N2&&]Q8I)H4K
+M:5WQ8EMV<H4J)>0IA;7(--B@&LNI9*,.C#=VO[-V*J<'N]';9KR'BY!5Z`F\
+M;$SEF\T:]$NI[<9^MD45%OI!Z8WBRBTK[6MO!#G$UMA1C\I>^S"E^9UZT*`R
+M7O-8<<+-6XD/2,&A\$.FX)N";^D%ZD,6J4QX(76/-B16`ZD$JA](D`E;$1&9
+MZ.\4E-L7U[L!OL77J<\%7JWD2X)\W7-ITQ*QKE'6<+>&=:H5PA$,L.)>OWB!
+MJ;1FQHWG%H4?WCU4`(.#(,C11@J,!`!!^NUOI!^]!"M4#%M)FN&Y!J.PL[,3
+M5YG^LZZW#27@7,DCQO?LM]1VVL%;(B`(^P8K-GP/*Z&1<\[J.E7_/:<H@#JP
+M1J\C1A7"06K$C;YC8'80&A?$*O5'97;"M#SZ8SFX92J.-HW^!5(TRK1_6`DC
+M%)L@F92'.FE0J;4P=0-4"F-^/'OGA]:'"I`*I_6`]V-T"$M2$*0%SP:JL/BA
+MI1K&%KFQ:EQOZ'S4,G"\@,20QWR?=YE:(KPO1ZA2+H*4L=J/66D>9>3\Y0Q[
+M7/7V\>P1UXP,>HEX+Q$QHS5(\R8U$8TTZRMS29EQ*=[),T:X%J\-X8P4`7-1
+MH?;P#)L@Q0)1ZU#%HV@'\]#(OIJ`0.3F!'%(MO+3B8E#ILS9SFID+`2\.:1J
+M&0VH4Z98M&1<&DU`>3&B[!-'<HY6$[5'&\)X[CD/VBI)WA@?[Y!UBIPY1UAX
+ML4_\^C0TUFCXL+$7G$6Y[]`[\E.569*9:(*/4*^3CY$D7&0"\DAGE\)8L&M+
+MGR*A1PJ_>2"1T*R3S#@J1Y08%3*NEI?:0QNCF%@0GN:YX6H_WQ[Z^=Z0`U9^
+MGHB"1O7*2-WEB3`CL)1UHT+/40*![WRZ<?#4-[?7;J<UVKTG8;-I^<'R0G.<
+MLU'V_'>]/1'Q+[?IMJ6TG^IV-2%8XY&R.QRR+,/;I@M](>3(VFJ%:)U+7\:[
+M%99IRQ:;X4`/=+P!'(,DINMC5<.-)DPUZ5>8BP3,)8\J_,'\(]Q(N!#:,?@E
+MLQ5[94\53>2""DU6A&IGVHN"&ABN"P(?AJ]]%WU/-A-+U5G=Z9K/QTM09X]=
+M"^J\^+V=<,P*,.<K^^,(#7DT!1YS+E+M5!&1_8][3!&T9OS7AI=3W!)C?3DJ
+MC8P7+2K\5<R$]BL8/`>9SP6U:MD?>Y('3PYAMUQ&:FD-Q'/A'-W]<B(,HUW(
+M<);*R(VJPVJDUMFE?XW#CBX;I$H#8=J7I"R?4\M^]56X?W'>$?*0G;N"77!4
+M^RDP+1.J>F2P5-#=*R7*V1OXYL;;]UWUFIC`$Q^7M4T<&PV'Q')<9+LG5X>#
+MP9)4=C5%#"L[QG]Q.=BD!Y2Y2*+L;K=;Q%)!4J)Q:6(CG.RD$BF5]_`#:G;@
+MM+URD,:/#Y=AJU`93B:58=ITMU`:@+VDR^XD:%&SE[W?\%C!I>`?ND@0_`0D
+MAHTA+()@(L.V^=7?7%W2JT/#8=F.+7=0R6&0"^.9.VHEI([D2YKP"GB*Z3YO
+M].,1-^5E&/0VQ8Y'*!S,@&U83;2)I$*U3^@3Y!YZ_O]HLW[6A&9]DGY(5A4U
+M[C]VD@]'`:''X0/0+P4+Z%9T[=$2_.5Y!:4AH=E,/&1D-)MX#.=''_,^KMUH
+M<39F"W]<B5D?E6K1L./7G&.?YF+%G*O!I[[*=7&9E$BG6-`L2,$T93J%=<MF
+M)^&XC(L0*5)_XPQ2]K<Q4ZF0.WZTO%(:[I(/R/9<.=Q5._3LRU;+L[WV=_AP
+M=_+AU#_A`])OTV]';"QCR])[W1?K??*U)\QI\Q7%+"QKVOINP6)8LZ8_2]]J
+M8]I\:W]=&;7]`[JW\+EQ#Z0Z)-^S>T`Y'](#$CM_I;+SF[2!7Z_$-B;X'LM0
+MKVSR&Q,^NQ+[.\'#36=\H=>_<H(9QZ_L'T\(Q.7[4.PF\$?)?L<=KTG@"ES<
+MW29,Z*Q-_NGG07O`S49>"QT?@.T69<9.JU-*/-4H()^H2HFG"VO;TB5^/]W,
+MK0N[0)="XV<T7%A$TSH37X:RKP9M2/O*T6Z7L2>)>^!G"2U.;HH*7%PF[W[;
+MTK5HT)[]$<&`8:?PXAAE>VNTV-N6;G6SM.JT[)?D@8,AP7OXNKR*7OD#6I(A
+MTLB9LH*[VTW<U7*.\`?06,L>4:5>P,?I?L1UNP8\&VS\VQA(D8$,SH4FU\;)
+MB4YU*\H<]KZZQ,BDLBK/<W>SB0;Q_(.O*HH/ZB?*ST]XV@C6JV^22K419N\$
+M6+&M1[M!:!.7Z#PJX90Z];R9R&"2O>>N9*ALY3';EN*N''=.[16KC#9I7*<Z
+MB<3UXA6&;50H"6:JQ2&@V``!@T/MJ%),5%EA5N<L*_C+T9LHT_H'6II,V^&2
+MB`9J)S.3,@6R'A#>$M)43.-P?G3WMJ4DHY(K0H(IRO;.K5>+0154.2+4UY1M
+MUOW/!H?`1M3=F[YZ<70*!1.8U#/TV\7DMQ.F)(5V)350Q>:@-R0'$6;XBS_2
+MO]!(;5FB0E@D[C@`ZHT2;8@=DN*CF@C46HZ"[/0_:$>!\_QK24=!4P:;F9TS
+M.VN3_JM_!3/4J)0C+M,99=ZZU>7Z"NS/$@>#MN$ZM)V1QT0&[5%PG'^1:5XP
+M:@N!`+,?9;R">!C2P2<NAZ":-KN:4H?37G<T5J/LS9O%7FW)?E[6TI4D%<O;
+M$*I9#^U)KK=;EC:Z&J+,7?M.[&VH9;Y79X>#\C.@!)/UHX1KS_@$*J4:.R%T
+MLDO*XW`R8Q<BY]7W4J-<^B4<PP^H#Z7`A-=4G1GE*3.^W()5UQ0S/N$PWS(&
+MX\,[*G)Z7F:7U/R,?+22_47X8S%5Q7$+L?(1AGV,;VUT8_O%<>?8H0DO!P4N
+M)ID6-GQI0[/%]\$N6AWKO;P?*;(_\`,&1F`9]7!"NB78KI.O?M1B^*1#PNS"
+M0U+2.$?S@R;*W75EH/*,*#T,;^_1<(S-SU%EQNIG\%X"VR74CXSIS`F>1M50
+M-U[IQ#/?K"EZ#!6UP_<]V'IHK/$AOH+D)]5SY^M@Q+(2EHA^/:^MH`"N8O;Y
+MI/*V54U9R\JEG8PE:3I,9H-?#,8S5]__OUM2O<DE*8@6]#J]H"!/#G268P?#
+MP<AYX'*KAPP1HTR<L,15H/A"I)WM&R<H@DN=(^X&1=PO%#H([VI?;K#+%]=D
+M3<>=(^Y4IYKF,];1&10(5C7)O[P]G<4*4MO,I!UEA+FC:*F$NPL6WRC7FL3A
+M(IW!/UI[@O'LY'\G!D;8R@N^ZC)ULG0ZUCMOTAMU,,C,.104D2ZX1+V-LL>Y
+M+IQ]^+M4]',J[1:+/OU!T^E)J"$04!MN^[ABZA"RE'!]4]D2=LT&=.!LK.UQ
+M[IW;3E^_H9:I?6_;TK&-M;?]<KKY]_D;:Y/_8TU"2B%J\,+V,2(05Z6\@JI:
+M=1#TL4NN*EB%"]\AJT"Z=DP7F$D_]Q-H\6#8+_L*\\N^+M#.)KZ@B+PC?;JW
+M6F[_E7ABBNKHXNDVJAS_9UTO<J2,VEY_/GK%4`[?A&^H4TB)O8?^H<)N+;1G
+M!:Z&D?$201AD*4*]!C!?^/B<VJ2C0K)!M4PM%+P!)%W\]HQ*28`#,I69;^]3
+MIZ1<F4E*8C`>O6I1U?76V8.F6;F\R=</\KSFG#2)](>0\2P1_)O]R&00(#YW
+M-0RV-^0?I(F(Y9.&2)Q]W#=;QSV[]54&T2^X1*7/G39-@?UAK?I\F(JR`;:'
+MQ.V!#]E5KQ#7MYFY.'%CV*<1MQ+%Q=BMPKX[(QB:;04"DC59ZUPBP)OY^0F4
+M44VH"6A<L@+Q<R[R*.$+9../S:&V/+6)C(KR153W#O1+5`Z2E)1\\,6MPAY=
+M:ACFX>,_`.5S$Z>3)=I#!0+Z'BKK03N#C._++0]9PV<S%L;/*"=81W3M8%55
+M^+,M;,6)"(N4Y-=P!>7"QN=3']!\7OC-7[?:$VHE!X)%L?%YB4Z'$IIVOGB&
+MC6N%-]5[^'!]B.NRH@L5YBZ6E"*^(DPQ6A?92YYX9<@M$_`A'Z[9MC39M_IT
+M$,:K>Y=I%9`=.#1[=MX:D_M'V>[K75;U7=3UXS'V5:.!N\.Y!D$\]B<WF:,9
+M?@1[G[QX:<BE82P63IH.LD!.<H5J1\&:.,G*Y%1(`6CTMKTYPS!]SV:F;Q,F
+M1;^;U(VP0%P47%6QU20#.$4?#HZQ=DC.Z]`5&^!4<KR."'VM\N!6#C!A>+%*
+MI6=G;"[;;M6M8W]:BOH"E<MF/.!Q(PLXS,VRTUA-_3/7)BBC`PZL#F7<43EY
+MF"NO@*`O$#B?Z1*V$WB3\V?;38U`\>)1;952H32@I-2APSW-1\GL?A32("DC
+MN)JM-J@&-VUE;-A;AB#3]7Q1K%\']\."KK#2Q?^N=`VI',R/H%X(G^E_D^,(
+M1M7%ETNE.&2'//YP\._K7<=(S&//70IY[#YM?"<Q#Y;)-\4T-+RMK!$+N^6V
+MI6I,*(\?O)T@'W'"-2YX31/Z2)!V1IE'3]RV%.:C3BB)]>O04?3,*#G)<R:N
+MCUC/!>JA!45TU&0?7)%`E%C`>"WXH\P_WX`N=JDW8=:P_3>>UO$1RF!+DO)8
+M280=B>(16!:^YOQ]*M4.^N[!@R)S"V/FMC:U!=-FB`D(9/?HLNV18^%JGW0D
+M<<9*X1`K\URE?AM54L_GS8V3V3[N^'O@;"KG$4YG7(*S?M825[*ZP@262'%W
+MVBT;[II6M;C$W*WVK#9#B:M$%3V[>*I"7NK)N(Y9V3??Y[FDR5\\U5K1!".6
+MSX3E9D`%/Q]EWO>\P>H:1`H5$/"GPDS+Y`B1#X]JDQ[5MJ5G>#F-4\1)./MJ
+M-TA,I=G.R6FL.>=]:MM2]#733:.S&8M"FE&,M>]?ES%A0JX$K-QNE,2'P3LQ
+MS"F)1V8<G@D#$++M@TM68-UV'RL"V<&`GB6>VV\[E7N6E?+X7&OBE3;\/^G/
+ME'L8YI1P\##[.A;5WE`5UPT2P0F[5ZTPD3-#W"3A>C5Y;;O0RU9TI'2UA1C$
+MH[^[V_B_,^DSU3\&/$1.VQY"J<]P.>'KKE`0U"Y>ZG2\LFTI;"OBS15;HCH,
+MG?;T-L`LCI]LQ`T4Z+0#JY04C9VUR,[:V\X\;)G:8F7VZ5#FN<JXP&<CY\$]
+M?:ET32%#6NI)!UU[!B5%0I^>&Z6C+=6^7#H>F/=2],FU!]O&36>?_?F,O+?>
+MSQ&;]+_5%!DM_1[VNE"HXN`K*J]!;2?XW?'S+#<<B:G/_DAECUNU'XP%D"AM
+MG#B=NMR:J9'``3[F$4:D(#0L6$$2UX1(PW]:XD&O1^0<>'D]R82B\.!2=<,Z
+MC6XHF3^J1WJ&L!S=SY^W::03U"(HN^?4G#>^H=9-E?`V:0/VH;2$0^:-F6Y2
+M--K4*$H\;B;D8G8_+WV2:TYF<A\JG^PK47D^-/`+#^-C;E"[*4AP?#H5Y2NJ
+M1Y/K0/-O;Q'Q"])1PC/EAP4ZY>6VN@4JEVFG[^>&=."P#?C2^JH`7^&!:_C"
+ME7>Z&[_JDZ]F-GY5EN;X_/+1B[*GO*TNB3A<[D/OMQ3NFH!'OD*>6GQP;E&B
+MWY^\PB+6FG+)I$65<"IYT*L5@V$J(-]53I/V58=C[$8B!8CH\:+LU!$]3^CZ
+M7GRBAE:I"N;%@`,'AGN%C1"Y&ORVNJGK!E=$E1B?X8:??^6VI7ZHH8<"NBR4
+MXIR$@"??^C9F-B$GB[[SJ,.!\<NK*=QV8)VF2,S+<?A``MXC(1+%Q'0),_@.
+MV11!WY6!67+O9VLY?TQN1A!P:Z_I$=_WR3?3G(03;+]D;<P=[SS59_QZ^M#8
+M=/*E3(>&I[>'TZ$I_$\`_U&1W[D4-\,GV]'P3#W">\RTZ8;3\Z6!Z01"WWFC
+M\@"^,7&3?>%TN$IVW&3+JL>23<H#^*+&G\RO5IK,0B$<#4>#C>E?+?/'\BK)
+MZG>N4+):?#NAHNN2Q1RGYNISS2=QF?])"YH.<)"#XHB'E;5(6U'UC!1B.9:A
+M*K7+YY".'_FH2I05:$(<WM#PH!M@L2UGP;'Z;IT1<$RU,`9VW#!N2R[PAWZ=
+M_8T]K9ZW@-3CSJ;_-KSL,:5/X+G'@HQF$\;H)J&#"<-%MP?M<YOS@J&$+]]K
+MW0OPX_O\^PJCCO)VQK)=7H=;J6"9;F-H<VH9NOL/O$_9;.EM3(;8(5=>T[H<
+M[$,+<=QL5]"V:=/)$^1*2;T63K#CC3-$KIC(.7</3DYD7Q)&N$!XJG)E<'V4
+M[Q4J+QRI]Z$J%;5P,4\$R[OBF`<QYM9AY114J'J&/U`$PSMONVMA'R%[:7;D
+M<^3AMNV4V;R,&F*V;>G"6G;DM$12:BI$$#F/=**BL#FI*"0N`3;@D.9_THEO
+M\)BK0NB!98W'TF5FP"(=R:&[@:/T<%36D4("QEUI&/,ZK_[3MJ5]I0H%Z^&C
+M_O7X@FB#(X/%?H2OS;_)BO\0B7#FDKL5!3%G[,6JF#'M-N7,(4@S17IC72@!
+MH\BZW)(96929?;O*'W(>_ZUTIG5A6RTS>[AN:GG;OJ(=U;PB/5V'_Q=2KJ;L
+M56B9]A@&6W!'I<(MR9VHW-OP$CS7QMX$_+O8UJO\G7:##=&;='/D^MZ5UA8&
+MB.A;6$F=#"8/HY>"-N-8A#7<M4'9V*B&-W?0>QLFE7AOA_V$AY+]Y#VVR].O
+MP8NR'<R<X;^2LV:UNY-5T-D*N]YJ\U':?&YF2=*$;M)NQ;"#X<FBO?VIRPEO
+M\JG_4J4<$5%*..4B<BD76(=*@$LYNY1VMD'UPP;'/4\BG!PB*4X)0NZ)<I],
+M/<)W+><;]FP7-Q(<"X4GHF666:2_K3E,M+AKQZ-I<UK26]`9'+.I60?&3;X=
+MY"4QLZKT%XNU1V?V24*?&34^BK]/T<G!D\PKG(.!_5M`(QT6W^-PUQ"N>7DP
+MZ%+KK=R/^&R1GV7GXW!1/6MB6T+$<M9[&2@)8K\ZY`FM%[IC$LX\%-@&\@5W
+M]>]_OV+0"FTQ<2$T4395NLA610*B8L>06X'[F[S$@VZ@+;0\7.,#2'&8+@?F
+MO'`8D5G;(2)UMP4A52?/*6(Y:$>5;YY0&`=1]IQ#R&5N%1I2E<8G4)_)QVZV
+M-ZU/YM89UFHBL/;EKRXJ<M1+:47MM4S]82*8O74&6#EAB5+P2RJO`6X-,'A_
+M]Y1=TM*H)F]?E^@!(;]"JQ)N+7M:EV:TMW>7:8NOW*N6*I#'9N;Q1G<Z7*07
+MKNHIFAIN5`6OZE(M54P/"B1B;Y/#@>VSSR,$3-SGL&F<=V27.+*.LO!:4K>L
+M6;(WR:=O`JW`+1;1!ZL4`M'IIDD51@,("I*-TVHE0][BXZ7-!ZN+/IB0<;J!
+MVYERMW=UB;=]ZJYYV]]W]<3>=H6+GMW9146]C9ZX.1VIF5/+]@\FDY_#X5BR
+MP=%*,\#I4P4R=5A7OM1T@FF?JVWKVAMW7FWRK$FH(IGJUMI)%CF?_0'7;U3A
+M]9!K1>=-W(QC9ZUSVDQRBG*)7$>@A7$Q=CPL+QUZL>9`4M4F;]W/&U2$WG.$
+MXW(-6DPH>!A@OGHT:`\IN7;U:&^O`CN:K+$H<]56@_H?!LT,3SB2,3:S5C1Q
+M0-[KM_(T?/;-1ID-M[..[>?%TU>`X_K7X^"X2BUA.*BW/2)^*_0=D(K>4;2G
+MU>`):\YD0E9%SN17+4=X0"0TRGN/]8(GOZJ]SZW$>Z,3"]O".7/"BELUODV.
+M^)J"S:',<,S\^3#`!2'G>^NY76/_FC6U'O^*5]3VLN?S(K@^_MR^5U[CTQVH
+MW*VNKUQ)E@%.B],J!B<\`?]?-(=6Z+AP5%%3>/7:[B=HC;U,H_((S!7>W30%
+MOL(!:8>=1T[HY&^+GO7_Y\_;6=C2!44.7BV`+!J+G,OZ$Q>?D)RX.<J;T5'>
+M"5FH2OU1YMXK=4U/DZVK+(%6X1-,T`G"5OSA`40-H!XKEJS<EDTFM\4)7]0&
+M73#LYKC<X+A)FDER7K%_HE)2>%W!,V.#;8K1A%$'JWO#.DEN9H=?36F,[:%=
+MM3;TK;R'U;V\O=0"4?YC;]C69CMT^,M0U"[\3]C:UA8FGF&!8%*$$ME!F?\S
+M<Z@DX$%R=M@)0B78[JAQ["152#DE(V>_C1/<]90EA.%%*T\(YG6_>VCXZ'MH
+MY.4@1#&YV+4?O#V56Y3B\G$-&8[E<>\)HOW_8S7FI"O7]"$'_MP0(-N%\<P>
+MRU[UIN5^1Q<?1W@BSK$/Y7\17#[EXM("=:'B>ZRL6GVQHP]?^F.^C$%2K`BH
+M$M":(-AE)4%_UG])*Z2SXR-(\U6;]IYO2DQHT@'?T<[:B9:*'1,I]B=%?>"\
+M^8!DZ&"(RJ)GR(,.E#BRB!>*/=L#;&#3*FW-]T%+=V&]^GHCYZ8?:9'M^V$B
+MN2&P5M.NT?-"PM+_SXNH3#7'@DV=IP82==1TFH4U0G8^%RV(MPF31\Z*'AUR
+M;!]W<J_CT`.5\R#GU775E/3U8;#]%\<M+[7'NEZ&%1AGM@)?JI-G/GTFI?)?
+M>D"3!6FXCE+>9D,=A%GYBU5!#UHAE@[IP]T>-O];WUJTH.)[)?&P1ONLX;83
+MSR[=>?+W:B-#_/;:T?.>F>`'Z-+=ZT>O%]0?>B_8+[BI)GIW^+3]=U_MR"M.
+MUH^7I7>]IOB$N7D023KNG'MA)13,#5D(R-9486\J^J>*,<&<"V.Q3C%4&AD!
+M%4"9^?%BY7+,'/M;+3TRN7.5Y(>UVZ2*\6B*#[]L`\OM0!UJT94=4&<3+14R
+M>9!HJ3%7@^W#%HKS=B%)I7_S(B+&F9;OFMVGF?6C?ZQ..%E&FRT`U1F7SQH6
+M88PF7K76"\K2H1\RW/69M;<QEI6)_4$?Q#.-K#QC<:FJ[Y*AN(I"WB7%6XKT
+M8!"+D+B92]_$ARWR[<CYP.%TNG-H"V]XDG.(^7+R`L]414T;<.1/U;8:_$J4
+MV?I7KK5$_G(D^6BXWS/W.Q:?6@K^;;.)Z!ZBGHJ%PRC:S/@`00=8?I;5O00Z
+MI_ENG%CM/&FBS3?<V,JU!DNOGQT+[<S?'1Q[>O-_)S/D717>@M]-28MK=F^[
+M>\5.SZ[=YI:#]YEG(?$ZNS=>L_N^.[?P)`^VB6EG84\/^4\L<*6.X@#^K9#%
+M5,2;+A!%G<K`65,12OO5X5Z.G$N7LC9+/#:DNB;\&-!<H@X4IKKWKUJ$9-N4
+MKF6[TJ6>@='YQ!#T1@?]/E^NP(0G)G$OS%$>)<P80SHRG&IHKW5TSFC0-G[H
+MV9<MU"QEH['UMQ[1A?_W_T.OOM6YU\J5JU?"JM5._M7#\-_:_/?-DD^L!];V
+MUDX_X^6UM?^XX5SZE_YJ;>V<B^ZES]>JS];6<L<ODX^4HZRGEOGG_93DAPU'
+MF7]^MVX18U(@-[#]HY+61/4E,+*#J'@E`/3)[X^<]F$KS;S[.$Z?*H@ICCR)
+M%-[S$<&"$@D$C?O=Y2HC8`@SM/3F,&ZJE:B7QX<S>FY4Z032=UV@B.),TD?L
+M`&B)M_YLA=@.!OSM!B4R.C+'WPC*6P%S2"017N]QQH/0+ZSM)47L.I6PX?QD
+MYC+HKE7Z`'D/SO7)X[MR;7U>S?GU='(7>PKJ3LYE,;D\0KISQ*44GGGJLI/;
+M$]3K/OI],E=!?]I#C@B]\:1U!-K1?1</2-Y&7!U&&,B-RTOQ^5ZY%%N5GT(=
+ML6*`4.:A-RRR/C0R&)I"+G$\6C!WT%;FS31;_Y/SL>DFM0?,&29S'_7JU)-,
+MTL<G)I&-L0A>^<!&SC]PE3N5A,:\6O;J?UO10&S-I!V*/D%,P03$_)FE:6)I
+M_ET\\$C7&HHMA3-><YXY2*??MM>R>^W!SL=$@^^9T=`%ZL&:;4O'ZM,5:(NV
+MR)@8F6BTON]&0U&(`S2%>L#Z`G'UFX<9SOJ%,M/8AR7.8W:%FA;+[:">7_8&
+MD*^20!MYF.GA%*8^6]XM7ZJ"EMU1`-N$4VM^<"3IT)2KHE`43**MBJ^A"!X:
+MCDUXM*C#U-EKR::1O-?,C[Z5+HYG9M0E_U!A>-`EE.P[DD\9UAJYL'GQT&;8
+MG$B:LT9K0'[63;X0ALWH_*Z0?DW=C*O<85I&=)'0YQJX+Q`XG<!=7Z6:&<_>
+M]X*(#7D]KNOZ`B+MAEPR<@Q]EY2$!P-SRUVJ5KQ7'NK0^<$A)P>#H/GZAI,C
+MTEH58T/87FO)++820U3&%+&!61E&87T8B19E6@(+8EKE%"+X!9=S0W;[5V74
+MGI<BSPNBMSD9B_^Y%OX?IS:$\@2GNL';,O9(31TGZ#6\G9S6'E+5Q3/PB>N(
+M89-+DA82\%DP*%6I$G%&AN5JP=,<<Z<(%W&4/7%WXYHD/*M]RZ-?,COO;LY1
+M-7#HI$LR35JU_(@=>"9KV5OLPKNR>>.Z5.!M&K1`L\%RI9A"@T%#(3S7IS,A
+MC-ZPA5,N^FYQT4_;-1?]W#=V6MG!IW7#T<J"RHJQO_C`GM8)?(G*,PJV'+W-
+M6RD<U>=K!^]J/R0\LLMNT,0/_7_U.TW\G5OVO6^&11M\@0_VNJ"#ZPIXA)R"
+M"DPYL6]).?!%&Q2"WFC*D@^I)28R9J8\M5/!^/34#0?YSI!JM[\SZ)4%_:"X
+M3##!EG5)<1;L3%W$9WQ4$)L)2_RR@%\J@0E3:7_G)E_L3KS8E_QR9N++<M-6
+MQ2FPP")N/_Z]ME:%<]:$,G0S9>C`/6"F&UZTP/CB%HJ<95]@-P%<M+V.7.R*
+M+)+(?<-"J3B`958,-S@*)!!'RB5`<)?(:>O5%T&]79@R/;II._@"#;F8;YF4
+M-XK\XY<$W$]ZG3=3>D'FY?>*I(XR?SF;ZAB-Q*C=[EUF[(!IC1[6B2LTQ5A;
+MD*@W"]H7*T+5RQ.57[#Q5MKAK^F+T9+_EA#7,ERER&GQSU54E&?EK>/<9(V4
+MAMU+]WT[_LH8"5+C(L$4&P=Q%28\906@(^?'/TQJFI;&/L9\$-"T'H-LU[8:
+MO)<@NS"/=.M'X.:TDS=-\KWE>5Y!:@Q7&*"0V<!Z1F/(1&N-(#.P.*T1*!)K
+M5NTXT='N$V;].=-^F;JQ-?T81<R'$=:/P%W.C83?9E<S:H=[K]:%L)DO[3,'
+M25109UM2&`M>,JPSEFN$=(.8LGHPZ[K?-9ZN*D/H#GHK8\5Q9W(<%X/\8-N#
+MM8-FO@2P_R]"N"13__B?%62QLDS[J0,4L*Q*892FP7-0!BJFKCD7B<ML?XK+
+MO>@K/Y'WPO#/5+P=#LUK9TM8T_B33<6]%2L;2PPTR8A''W*93,)2H:IB)&5S
+MZ-SRNIJD'$?.N;^W@ODIZS`!N2@UB:Z*YH)V(Z[\.3,I,_"T3],5$HX$L4NY
+M@)ZB#`L&"4&-;&A>W!=ZH*BSRH^-4?4PWRU3<.L430R,5353\[3Q=B,G#/A&
+MXD5[[-?/8!K\*ZDL"9#&>FJK9A>*,DON:\[8V23]8MM2^+DZG;C^8`0-A,J3
+M=F2D,<Y`$)O&9EQ"KIM,`M9Y4.F'=G>L0J35',S+!^5CI^^QZK%5%^N.G)$G
+M=U+&HLD>4Y3%7#U6RPZ<#3O]2@*4%%]D7D<I5#NGT?F<7$EQ0^^S7__J7LS/
+M[#@!IT9#IN!SMM1JY..6[[KA!KGT(E&:%5W^.U=@>4&K`*F08$;P3D<';`G%
+M*=Q%DW>[]G^/!M1X!S?/$TM-3Z16J;JA)#$MAM+DR+9R]\EM6GO_75.@><2H
+MX\C45PVJ%':`-V_WQJUB//H3#$"^+NBOK0_=AG>Z[:_[&KZ>:7]=3C1Y\P20
+M.B[FISG#PUV>$7T5F]%VZ=&.[GBT8Q,,[-:#MM]D^X1GB4]XXMMBY^Y@=&T\
+M_K("Y7@!9J+YP2`6868@E.TK<)M@"971:7F7LNO>P1(V5;>)SEZ<E.Y3#MLJ
+M&=79;UZD+=B@VA?X>1\#"E9I1UFD^TZ^[KX;2F$968O*^6`<ACX<FO$ADY"B
+M@XP9"V9E!83E1(*Z%LV9V>]U)X+@[0A#4\NXK^/U)AU'-!+9G9%S2IQ`.\WN
+M["9M@((^U:;32U$@3*!34VHRZ!;<JQCA&VQ9R\9&<?79\5/!IHV1<!*U[M/^
+M$_ZNP?M4UWRK<B)Y($1/'<#IJ*H:2B30,;O/QP(;Y*\LHP=L\CV?.X73S.`-
+M4IBLJ]0XW7.Z'SGH;W9)O;%WT)W)=X]PV#&[9"2D9/M**9XJJ1D:+$_VO6(=
+MIN+V+SVD-5XR'Q(QI>&JWF+6JL'2O'Z@E6"M]U8I<J;\F\9J6"R>XJQ,+!E*
+MVQQY?\$Z0.\7O-.XYZ/L)'9U)T!8\"%ISXHU!2E7D53-+83)^=*.FQWJRB8W
+MY^^?32)2,2EEB)2\TIZ@[>5AZ*_\@&NGXMV,"A^6P_.G2AJ9^KU%_2SC%I"C
+M-.448`82G=O-EQ%+/%H)CG01Z5VX>N5P=WNX((T!Z]42ST*!;>5\F!UH`ENW
+M6D#H-`Q+@;!VTHYR2N@(K+-IF/!SFTZO-W=,Z/&B=0M;]8YCL:HJMTN>2[\-
+MO<9$N@PJO=GYE"Y./&`E*2%.N,:II$U;]X0]:PUHN?1$_;\:=IK@8:;XL_;:
+M-7_6RD_OA."A&?"\>00P:!=F"XSSUA&>^?9U2C\TTY&S!RB6[TD2NYZ#&I@J
+MK2'\^FX77:YN=X.A&U/F0#S`N(S7FD][B"1KJW-=[9CYL')U;]C;SII2[92/
+M9A60'SYOQRG.=</WTBGXX3GPHQ;3?F]"36KZFWQ`0CPAJ*G"3P@K)/Q(*##_
+M7%<O?3FT].Y<-VXV`FR<,.U)]<L,<]OE'Y5F:9P:XFJ\6G"/N6"CSPS=6:$[
+MFR>QAWQO$VJ`$PX-.WKXW2M6"U<P#>.H&1<W&Z.:;YI7F7=X^O3MQ^2ZU5^&
+M$54OP$Q[G:RG:NJIB)MK#W.SB-=;MSI;3R7T$&/J>V]C4WLEN\:7/,JPJJ$A
+MURX$A5&0K_O"'4#ICI3^*FZ&(2E)/82I9WO=T1,+N,D*4#F__XM?F:&2-'4I
+ML,CY\+T8$:<+1[NGK9*H5*J"Z@($'GY>`%%#&6VD5Q*=I<N5E`_X%9GX#XQ9
+M:74@W!Y8:G+E1<$02(G6,TP)U*U6"50GZ&6RKR0<;)0X+(I-/4^J(>4VDO:8
+M!N>$GQCV+<O0VK;40QTE_LMI:)"#V$5!NV@FL_R']7R)/8LH8DMQ#N2R--J/
+M!@IGLF$33(!ALJS)DUADK@P&^E&`RA.-RFS>!5PO;;77"PIYR7A(B:G?1WC?
+M@QO9E>01$"Z`RQHI%,"6!+5E7>BANPP>*84ZI54EJ<+L/]A7YRB@6GEDFAO:
+M2CPCP1BCOW-(TF;`>9VUEO?V]Z@J\C!U@4&<A[38,$&7?IV:'[JZCC2TTK;R
+M847.VR^C2D+HB?7+I2)5IL-/MRW%,=9U@KODR0=-ZT;)/$L<!78@3GFCFX<6
+MT+CN).U3J/Z:V@<-N49"<G1S4Y_'5O9T3)AAM-7V=NRQH_RBFQ7@#;,SP;I8
+M?AV3)8QG]_VK#KN;P!)F$Y2I3C4\B=XQY+.76!,_2Z8.>P:"D?J\VJ1S73J#
+M/[N5>;(KWK!RLXES.AV/A@$IG0]Z:HIF(E8KXA)_NLXI[#I3Q=;,%MLA.#.K
+M<3YH&VN'+(A!F1EX5CTYU.1)U#;P&7HZ^7B1'B_2X\4=-5P<:O)D.I-<^Z\G
+M+YSKL3-Q`N*0]MJ4TZ@41:GL#U#%;#@"M)\[K$1R2=*.LH^_)+L;SW=U@"*.
+M.DVX"8)4.4WZ3:R8@O+'')S<XDT<6Q4!0IF>9M<_(FFX5HR?^J/7%^<$)=U>
+M'^/5S6R[,068RWMEOEKS!N(\<19OY@^7[<"!!?K^7_?;`=TU>9:%\-HDMVT_
+MM8A;S=ZX2?^PM7]-C#MP^[V"QJI(^"%R1GZ(0E&6.#%;SJ;!=6A\6C01DE;%
+M-IM?-FR_>7^]CXE@D=,YRTYO@9D<>`?5#4;[&J$1:JRQ8<[B>]QD>64O^(5T
+MKWT\^_-_E3",*$#Z3>E>QH:[2WN)^^VR8,FS&[5\Z:`Z51A'>$:U@B;7I!6+
+MV4NGKDAC"N*_BJ9T&V^)[+\/I;8$M(59<L0&AC$PCK<E"EY;[@+3MV"$5#7$
+M8MBUBHP*QMT)35],?2#1A(ZMRO.$S:+:+X(AM?I8]J9Y.07$<W,5B_+:.J-L
+M(D7.D_NL$Q4*;R!$M184AZW2<F1'4?@.D3,\G;XI'845G#IKSEN3R>R]_\"^
+MS<QEA)MPHCI4!+KOJPBIFH6<MT%OF*C'./G^1+\";1LWJ>:1/?(^*8#ZXCR?
+M&<$4U2;60L"+CP'\I'8@W@)C/AJI(.&M[*W3X=L1Y&WMK$UYZ!=GJE)C35W3
+M?L#0-HO+VD)O9Z]Z5J&WH7O/?9*2X&(-H<2/H)?H8,'+#"XU'10I#A`"S<IC
+M%,#<>.8;7R(&'+K]^'Z.K?L\MH`5,=K/"2";GN-BY(P>/G%0IV7ASRG*6BW2
+M4@JFV$@9%(->WF9^_,UQ=#Y5:E!3JYUBTG@"D[0[HK#.M8`]:+FPE8&."Z2=
+M1>_4WH'B]XN<::]IMF/4WX;\H@^J]%"ZDA>7=>"SA(O[E7JJ9CV=6!!45:E<
+M*'D\EO"!7;#]YN6JW+/<353;&67FN%.ZWPV)H5U6!)ERZ[D"F,>XBJ!E,XM/
+M$*.I$"L(E&D*TP%/O,VO8`B-C3D0IY]:UU-S3KR)#A3!VNSX&HKR472D^0BV
+M\A&`EJS!)LHGR/T_WH'%LYEKC\0!00J%HPI%UC@_PCJ4O7=2VT\A$)SGC]N!
+MNWC2S0>SSLFWB9NP1ZR;'1T%5B?T_@1!SP6(XCP>C#Z85$&&)46GXF/7T7EQ
+M'31*4D-*SM>%U<`NMR!AFL7?+[;N2&B;G\I[M-])J8DR"WY92A3YH(W)<#\0
+MGC_[%%Z<N(2,KLA7#3735BT1LX=E)?EVASW`YW2!)C!VP#2N,"/:5H/YSYYX
+M$B,%B=:J(O`^*ME,.]7@]J!;7IF`:7@YJZVK9?!R52[DG2N.[>P*55UU,&TI
+M`=D+!(#,,@-C<24_GR2F(4WG2Z_@O6+RV7WQM?<A>14Z9Y$0%Q3./'IJ03@]
+MMT:L2(5O41W"*Y\T=:GB.H;'";1U)AI3`R`[=(&NUZTW1<$C'@F?_'5CX=QP
+M+"3_"3GTE!WDJ2!2V]TK5O=B-26.J?EY]:G$"BFN)-_<G(CG#+W0Q`Q3=#O&
+MVP`"[[)]]=4I'@Q8#H)8JA$7O`$X'D,P6IB7-^8@$[ESS_6DE-AG_)[K+3LI
+M]BOMD?/+VS3FE&Y[)KZ,=8Q'=2/*[OFP4;O@SEHT0/7*R54!8J;B)2@(,4,A
+M5P91541J8!TOHD%$SF&37%LOX,"TL/7#SF6P(IW->F?8$W-Q>&$,(%K`,@9.
+MP,S6^SERQA:20]=`$&`F3IVW8K`ILT:3:394)SYZ$09KF7,6X(2TCV<N^0W6
+M!8>)JVI_:BSP[W,66-`>G>8.Y_E7YYW))?3P%1UW(FPRELI=+"I/TO@D9#%:
+M57+3JD10*UZB$RC\_BASR`OJ:@?;8NE_PV(0P;K@;!I&3=H<QXST8*`-3M+7
+MD9Q2E/G7;.&G5:3-&*MXZQ;?JD:G&(X2?C'6(/'<PNRJ!C474I2IO4&1*1D=
+M9;%4_*!_3/@]$*`'4_>WVY;C>+XP'U5I+M6"H3#57K[4/N[\XG,P?N<K_;:?
+MR^J)M5-CG&F/.<]X<BW,?0I1.DL\\'OOF@=^<'@G'GBOF'.'8:SDO,M<=C:Y
+M9C3"^^:SRT0CRD$G,Y(*J-K],`_/'WH*R&TQR`PH#,<094;7V"'&*E-M8BO%
+M>@<C@!.SH;V*H&(CG4;>X.V(@"5R'KE\1/B^B0J7*L`YCWRP;FHT,/`*ZZ].
+MFI]=7DH%155SI`^P<F:S]+?3MJ#"&];%AR5$X9*PG4\(U+C]'9\/E2_0U$"A
+MVJK\?SOQ?^1O]FGP1QR8./1?#ZR5_^[TIMZ%ATR&^7CF6U]!#1P43.8'QB@V
+MUZ6JD[I"84/A(\=Z1Y5PC!_1B_[C@J__K;Q?@S#OI"C`K7#4U9*1W'0WPYVU
+M]O#&DQV(0.O0--2@;\S]@R&`IYL3&]Y,[+_8,Y^2!0=?#Y"3DF0!LP**S0<]
+M$-7/U-ZJ4T'NP\C*NWN5)"QOU@G+0UA[:VHND=.D:@YD[NZI"]>*53X31,)U
+M2TI]FTT)I2\]*[<*04/+WA"G$:&DB*7X)8@8]"U0U5_L)Q.[85UD390Q[CS6
+MJ?C>BJ5P)`9-;!-I8D$LX'0\1<9K:!_4V#=DF!Q&0;.='.P[E3;)3'WGN0*F
+MDB)V-CROA-GJ8YJ010P?%$P(0)!*QF4Z[D.:$)8.$B@_Y;$H\X];V/-,$8!<
+MH81>^<RKUP0E(]GRQ-+#"Y`ON_%(0.P])8WWY>MS3BW[L1<H&^<_##_U!&3\
+MS,%/,03:\;`#'VQGO4OA=9DA_)NG@/$4]I5];QI5X:@(HR'N$=0.Q/TC:'X<
+MIDI"-NM&.B23$+GE=6&5L^'-^`@D@$5F*-QH_&;'=FH\FU+0U@<&G&<K:,?(
+M9VGU3./3%A0\*TWKK77;EJZWBW;W1IE7_U97P&9;NX+/E96/HH"S\F"Z]CUM
+M>8DI+PT?!((E/C]5;R?BZ<PK#4"N1RD`I,J9%)/4"DR;8`AJ*2RR\&#SON1M
+M)US;ZP.*ES0A9T#^A>QMWUKNY6PNXBC[R[\2A,D"6%C5,S0+B%Q%;#\'^F*P
+M:DOJ<"''.O'7]GER&1%$P2R_N<SR>$295SYI8"0EFVV(?$"J@^0+8B:@.YX9
+MKE:")ED#*L%,\H*0#C"LMS*T'<7-=V9@1*HMM/AO1P.DD(Q_L4"Y^<CS=NUT
+M-F0(?@[ZQUT_9>`&\^K:'MQ9[8@YQ8$%-B19RN=:E[85EF,B$!0JMO--"%1:
+M5CW6X`JQK=3VD,;%`61%A&`#/OAK]:VJ%KO5K@+QSA4#/)=!<R^F[!W7[E'2
+M^-85:4^8]J1UGR9#W.T87^]M4_0-<W6YU-!J)$STSJW,",8S;[Z3ZPU@/C*<
+MM\)8+`GU(`C>_CC1((`BP1JDDO#Z&.BEQ0,)YM09C]%%-P/&??)E<#VTJ@*@
+M;:*#JH.(G*M#7$@5LUZS=[QU&N?C<\(#IAZ"(73HTP*6>O9]F!]J5]9F=E%\
+M&W4"SI'\T]]:R3E4;Z-W*QS$LACL,__*ZPS#A/\INV^56:7=$"3J)J'-"Y1#
+M@6#L,RH$7=-,V)$S,D]S%&"SF)C:P:5HR*;FZE/97Y^BP!NA,BED,E3/,%0>
+M.1?^TES7%`='9R`%@HN4A6N&K@+QB7%8!!*P$+L]W(><!J]]%AO!H&FJ`?6V
+MI[,/[31DK#JO2F:1/(!^>T/#-#&"QSKHADZ-VC^6JE(OQ.O.@`JLRP[O.JI8
+M#7]8,`/MW#AXL9*$"5Q`/A$MZ9A:3-1>1?T'3-C$?5DDG^&X<\D6#HDAN@Z]
+M7;2+MRU=56]G[5&5YF:]F>_A6!D'+?G3H6FE0,)=2XG+XYG<8IC*L1@9)>-$
+MY.F*/[IVD)3]S.DG=$J&&V4^=@GG60N7?BUSZQ?Q:-A\P!-=-/B=+O?9J8_?
+MJEKFE3NLOK[RM0GZ^N8P'F/YI>1D-&/0^OZ>)-`3V0B9LYAE0]0L19F&(^AS
+M<_&ZD1C_B11Y@2%]DNQ+7N^GG\!@#QR7S5(%AO4A)%TIHCV<G5:!%1AWGKY9
+M9;MP33NZMMFXUF5O3?$2<CHMTCD&7)Z%H'VE,C21AJ@W14(8NI151/7K]3*:
+MN[3Q]OVV_IJ-Y-'(N6LEJZF)D@CCSE-/,&PB4,2CUM3'2077LJ(39"$'[V.%
+M=9N`&@[>1R*YX0XA"GB[ZW9UQLGW?FO7HI_4=5"/9'#IS"V0'"^>I+C4C8V3
+M<\OE,2N%%;I=!MV]\U=,QH5:+&7^JN+$VH-1]$:2B!KDW0@ZK3A$S3GT#$)U
+M1,ZA*_!W?"]H<.6"FA$@D0:)1-VXSD.RJEKYE"IWY<6:;RT1)$,1['GH(*VU
+ME+>S'YVEHZ`W<-7,(-7B19FO[<5W@^MC+MP/GC-YZE**0Y=%$N>3II=BJ=K8
+MIN;*Y$*2&$-@I@KC4S*&P<8M!W>\PP#?C^WL8N#[0F5AH-"EF5K54'QLSM<-
+M'&#<BMRXNH8Y;^58U9-(I7>9@);78;'68<!52+I-_OLJTGLK;K4][%D"RU5L
+MP[/%R7Z&VT6#?3_(A7AYYV+`0GF;8XJ*6^5P8W%CA&!#5H<G^$6$?JZW?A'/
+MT7J3$F[QN4;9B_Y)M5A"\7\2Q@QO;AC:.JE:-F7-V0J8_]26'8,3G#]N5P$W
+M=3LAD1W[R.&DU4XG&`BC')!E,'O(&KO%CH8F.X;<X2BS_1BJ64?/P/%BC9A+
+M<_?4VV$G_NMQ7<?9D/*[?79N.)W\/T]NR`.R2\$D8NT3<?>IR)*=D-!T'7J&
+MP_[0HX5(4FU3,>Q6ZGW8N@H>@B?:VO!/C_[4:[7$)0,!]0`0,Z^/L7-+5DQ!
+M`G&Y8K58DQ[_GR4>62?*(LF%]6096I!%V/6$N)QH[[I#2(W:;!!,\\VEI\,<
+M_!6.<N_7YL1IUBKUKG-M;18#N)0&IT(<:L!K77G@D"NOH;BY(DJBYAABBIOX
+MPZ,(ZH+&>ZS&+[`?=M,/<UWRT+W`HD2(G`.F\.:AZT6Q_,&]>?@G%X&-)^HD
+M!WV+JL`8Q7[=88W129<5B)P;/F>97C3QG#&R9K03)K!N@"7:Y-'7AKD(1CNC
+MK']"?7Z:D9,;),?9@,<6.Q?P1%<-Q>&2$A;5C'''^P'\/DP8S3?<MCE*`1[[
+M$\TR7L5N7/<GTG]B54_':C/*?GHWZ&2[WETY(7?Q&O)1O,ZPOKQQS#;-"&)S
+M-F_MIX$P2;<HMT0DL;FGKFX]!?>L95_[E\1R2#NP$%]@X&K>'%_BH7]=06]S
+M0@98L75EEH]G7OX+?8J;B3:\WD^@&U/BY%]7".C+LV+3FU1L>MKYHH1BUB?8
+M,6/T45+VP=6V]U1&J9+3%A^A'\U1[=F]IZK>F-7'@Y/J3AJME=F^6*Y)M8?3
+M6Y43A)I+,!(,/*M6H?@H<_\]$V=+\E*N$&8ZR[LOU<,8^91`P*TBAR:_2U$_
+MLV1#9-90^3WT%OLT$+5(?%PIR:*N@[^:$K:'T[K)'Z1#@M"?L3FBEC9*,'HC
+M&`E7M^90Y>IJ#UOAT`7P7\1"MI%/GP3(6=N/X4>*E%%`3Q7IJ6);FRG%TB#+
+MV4NRBIIC9"4Z]NG?10+_]2;*_3JCDWC/TE'):VRC9DJ!5_RPE1!C_SXW]$/X
+M/\4V?(TT_Y*YTAC7%&7??0:?'-B6GCH\--&<^0S-YY.P1\2?PN"(X#,=G9HM
+MT:FW[UITZJ)_["0ZM=[W1J+L)Z^4DY':5JL$[@O=Q:/]Y^525NN3Q%>L,^A"
+M3I^S.+55$3.!,VJ'N)V.4LL\<#HQB=YV->X<\@[PWNFL.:]T]A2$'5ZS^!-[
+M.IEO3+.GV([1,$#H5S2IO*=A^B=]H5E>-9/ZL[@CXT^[Z,@K'V4W/I)(BZEE
+M7SB2<XC=`%T[%<DE#BFJ@"$)S%E'%<KXF;0ID^U[S:YM7TH@:<&VF=+2O[SB
+MLLM?,IV$W\>0.:O':TG>G(VW[KMF;QLMKW.4-$X>K4T\F7DO("[J$M-+:HPR
+MBB<I?-*%EW%_%ZL&YQ3#')P]6<]]K[RF55C$\7:7\B'=]$*WO-!:[.AJ"W/=
+MFG$;WNB6-R0O_O@5\Q-_I=JC-/G^HK37%>:XSD:M/'DQM%64IUU6Z%S,\.58
+MW^TT"R^8^A0=?V<Q?8Y?(Y!&G>/A_&'-Z?BS9N(@$ET$+@9L@:,497)Y`DK:
+MGMOS;E%8U&H@AX.;.^^3=47;D(2RF2[DSI/ZHMH+0IEC1X7G81Y8,3PJ[,+K
+MYNLGDV&]>?^@9!&#LD8I#'>L)UJ!5OO&._?09.R@D7W7QA"`,O7Z]\]D=CR*
+M"XF/*WOZ!DZGE"KQ()P"UJUXKU->*P%IQ2G/#%.VKQ^O-S@U;_QSV])^C:SM
+M1Y#UE"]W*%]:]L83^#R;,DEI-4G2'(9T7,>BLE_#M`IF.UB<"N.3COH6!4QT
+M5##F*NJ3_KZF0L[DF"KH\9_*SIZV]MZ>@+QP)C+9\OQ#$IZ'(?:3\(-6;KF5
+M7<?D':DBW`2ZK`A<.VM3;_FA8.D-W\H<E8DFI+A,3:#^4!SIZ>,H%%)=H1WV
+MQH-I';*FQU(Q5\D;<BI/AQO4G,H&3M8V'>66[DL5RO94WQMX?:W*@$U'\+\8
+M`+_7O>,!-&&*I;OWYE/>)Q]1WAF-;,M!S[]JW,!P>2!Y2Z-78H'E]3W=)*H3
+MX6D_>\.,"AUS%+9$Q%<Q7@M$D^3MB3$)/27BOFMP-IB4)L5KWP<&8RN[*CI*
+M_1VC-NH@2AF$H>A8$_V.<3$T_H[?CUEZHRA\ULLZ8-PU06$%GWF%P,//H%L4
+M:&S6,PQP[_\D(0HPD`U2[(#C4\G==.$67&(LCO-,JJ),Y#Y$*YD2EGV;%%*R
+M<Z+I0WMW3-F[C4/31FYW`A@B(])"^'`R1KLM6W1,&Z[TQ@4-Z3&G>C2\XT_3
+M@(#NPR:$`'"\EIR?"=*G-6-@:'9:"'R8P*"*X:6HY<1?B1699G3"R(JNTI#8
+M`ZV6[5.P/!'$6^F5(^>QB[C"4D"1Q3;H_UN+4J:>F&[<-<J:YLX;D[**M]+;
+M_ENGOC3C[M3Y@@?>L%P5M&R"DF@$$4.7+KZ%K3S-.1DYZ]K%K=Q$?Q.`&4V/
+M'V@[VP#0R6%ILGY8V^[N9#23CE76FX+OV"W.\14NUJU0PHEM:#F.+/I,97*H
+M/&+<C/W\_5IR(3$S><^*^=*:)U_2C@U[FWI8Y'7>JC`$XX2R?ED_)Z368)PJ
+M!]8"VX$EC1F#AP1]E/G:CY%+7G*R+/<CZ.@/7U'2Y79"LT,)S$M5'W-$E`[6
+M?:DRF&!Y_=R=^F18=).DEENH)=@`CTT.2A1'Q*N8%8R"2<4`81IE'GQG=;@Q
+MZP=W).@8ZKR@^R'SV$K\QQHW3UYJ!#P->'B#3U<-B@DS^78)J,.NG?0B5C7A
+M\*4`@U'EP1PK2E&PLJR,=4<<?.N_9,A4^(Q;O0%]Y\0+Q7<O;GM;5B2;ROR+
+MJ$_\H!(TH'`F<HEN8GJ\M_XN[ODF&/WL:%="*X0^G33Y5"P6"AK:8\\V^GZ@
+M_T.QAIPD'!]TL2=W'XYQS].IUE=^>[.C%`B+!OO6FG6P,":["GY9B#OTG#:P
+MDD.GOST?1PO;134FN4M1=M(3-E5(<DR^YM5=VT]N+VAIP2S<=$RX;W5.VVZ9
+M%V(.(7#DU?`L<E_994(F<K]8R)F7/B%.<'Q9.I):Y^=7HI/2]I`O$)9$/'F"
+M;V.'&'>7DA._UT-APD*^W<H6`?65=30X[XR.G.#`)QBB%V*2XK8SQ=L)1Z/D
+MYT!I*95YYR5Q++7,B_?3[E%J,(+S37X39Z1C%QB.F"M0UH"N$R\NH*":RV$A
+MA<*8Q4&<%*F[[`?J&UBS4S_0_C]Z'8,KFL1X(NG,K@V9I6#$R&=#B8"/&=<1
+MWQVJ*P/O_H<,0CN3+*'<^\7OL4@_[C?[&Q^3Z!&_G*[6-QB)G'O:)_+10J>(
+MR2JVD8>6O:52N#);OSL!X)MO,UC(;_S6#702I'@&TVX<'8[A3:!<.+-L'R?H
+M?)E[+R?QP#I?YH?OY-]N[AJ#A\4U)IE^_-/L#NLP&:4#D7/CW@G7V":V/R=T
+MCH7HO0K3KBN3/,@<)`DG5DP'C_SI>MR(SI4!Q^*PDM6RXWY1=NH&NOH(J,)@
+M7==<?3O(^,TN7FT5AN1LQJCE?7<H89Y(:JSM<?K%?"V'YDY6;@7D&&CY?$N#
+M4'&^OH_L%I)T>I%=E2F2/M7.[S_*=P97ST[=:GW'6+@TQKJ4J'60G*HRE*P%
+M*W\T!$&L<66BP(J<ZR/BA[1#%`[:>608L3_.9Q_G(NCL9&,`$T%][6Q4W46-
+M^,O.V4+1%I"V#%U.YJC"O%_Z=Q3P?)U5W'42-E3<55K#*+&;`/3E9V?HL(U"
+M=>*'''Q7J[29\_(F7?M<PIM)."Z3"F>ON)H=AHBU_-K4E:9"GS#VF)"$,:HM
+M7GZZ;%*CH&0/6-03&+9[A'G.KO&96U5S9G]<R5U>$Q8!>(XX*`O'C/6JU)&R
+MSUY@5Z7=::)]D[QL?6:2D[+P'DK>GS*EP<4[:?LG>Z1X!:^@U*A?1[2NL/6M
+M>`4-.?/4_UC2,5'9,E'-"PL\8NQ#$`($$C1Q9E-<*W+FW47S-^\VF3^8Z/$-
+MV"G>B:2.YDN:EI45X=A6@\T^+WJT,<I<L,'CVG/%.$&QQ-=\H&EJ5$T'.E!S
+M-FZ9T-Z0F<M-9'$T>@[2O%+'2MS@';L6-]B\:6>E3&=MK+U^[4?),['D4?+;
+MI9G[-V[9_XJ[^>E96/4T>\K7%A41-'=R/Y9+2-+@*O:)[)%[*VH"`B:9#+AL
+M:>X.H>DJ6]4$(5RX%F\^26)6A9"2(3MKSDO?/,/.2!Z`+33,.C>Y6B5A-IPZ
+MJFF"K)0*D%H=YYG4X]8;K-WF&FPZPLT(7:9*;V4_>,(*0I/ZF%ZIH@3#?")'
+M?0&<9=>_Q=SG!IUA%X2O9=??*IHLT7"U@>)HD1[#4@P^!]W>K+$O5#^Y7(J9
+M6S]1AAZ>B^6ISEK+`4?K<(NOW;B2*1!EMO^8<D<T"*5:C"E=A'(R/&]=NF4X
+M-H9BR?;MN.4H\_5K$U%S85*$7LJRJV)Z&&T+5&BDM*>J,BS(Q+;M>1?9R!&"
+MJF]^4$7.GJ(GIY9IN[?.F23*%0`+-2-0=9>Q$4HJZ?<LO"C_`J+SGMB>``VZ
+MA;'`"Y14"2KQ&#M^5V]8[HT<#_O[H*/?T0O;-/LT]XS3;H<[-``P8,9B+S_N
+M+)K3)SGB1'<0RVR%"/2DCPVM]0>1W#C6FS&T@DQCOE?(@^"^ZVA3<M">?*X^
+MTO+R[HN4*'*)Q>FIK5P%5]?[-?A95O,CY\S;W)R;]X;\'#P_>(+<SYOD?@Y!
+M7/I6+E&A%)?6400+-J\B<*`T-7LS@MIXQTHF78#G54A#]%`0APHK:#!U00@G
+M$VXK-8=Y@M3#T@S__<-2KW2,/(GHQD5<XY6_4-%`9&2J^%@,+0;C@S:6*T`<
+M,UHR3FK,HL1*`(-5;]=\YQB>K+59XLW#XJ9DI#,/E%LUQ<F-^V)HF/R;>O$Y
+MEJ*.>1!ELV?EV;=@21G*&9WTW`4B"AO8_%$Z67DR9>A:_46"2OQH,H.YL40V
+MZ7LNKD8[ICVI/E69%4"/`N3@FZ<O\]8;)#M\BUF[H&`>5#-CB[)?.8-\'QXQ
+MC02-##BALI'-8%$D1]G^CR%KA*25@90-`LKFRH-VY8KK(EM_@E9<HZ:":KIT
+M::4491?/UW<+O'/]!0J-F&"6@+.MVPA`ADLEZ*FC'8V5;#'QG#W89U)T[[IW
+MV7,3*G(SYE>H(.$]!?64VF,R]+'G^G(@/3G*?/L"9*ND"B[X%@BEG^P5$+.;
+MD)8.8;3`S]&\X&4C\HN(Q/`-4[9Q.,H>_S<QU,G]:[7;69O\B9,6PE3G5.:6
+M??;IP)E`5O8#3Z&+'Z\H3I`>D@I)J&I5I*91@OB,W#:40JJAT:3)'?A1JP]8
+MZOV]KYP\SAMV$"X,;)/3@VF[UK)G+ZG:]"RQV<'8K=$I7%A<G+T^_")A)2B1
+MNJ"`?H-N05UEG+0_9>%5"3@]'0<T1J/L(1\T9E.B0P8DW$B_E(J!9L[;.AN6
+M[9,_8+`['ZZ02/"$EL/*?L:.58L^;#A9'2MR"2*O[0FE53<<&.U4(NV#0&VI
+MKJK)TDGEJ%U:/`!4;3G!?`,CR_EY%F-;C0Q[_#=)&8;V'=7&"@6^77#!BB6P
+M,BMOAJ@G7=\#QN2VVWM`@&'DO>+,1;QK"`>;0QU!'1\>JCG6SOK/<,07[J@3
+M^XA;!P26("83[UAL,XHFRE9ZEOY>T5SD04T1V))*F$N<F.SW#C])SK"J!>$6
+MU.BL*P!VP$^2?2!3RDH0%7VOU"'%1F1FU36*I9EJDU]\YB0IRY#M?0]^)K:H
+M@K+'Z!).R@.X"+3U!9^J82;ZTEE[V]?OU7'TEPZ82>3'FY(9*:!#>B/J%&.>
+MKTH2%-VUG;<23+HJ:!]RS2YHE`\^[R=-=ZB&2'6GJ,0\6"L2]548/8Q/N&"F
+M('/^W+ES3R#B6T&;:.1<LX=RZB&$W&I79@@/MB%E*#X6NM8S"R9X)J<"DTM+
+M026:W/ISZJRB[.+`1L+YQ;IFCNYP6]705#E6A%6YP"E,F.MJ,]%I\_M=TDDX
+M8&AGYR4XR132<^?"PU90%]GFCAW3I5_]0J&*(D*@%2H20:!]CTD"1&WR^\=,
+M6?$A)):\,$B@B$0A5"5_X/M6'PV1(9B6#I0T;4AP;2%E:=<2=+T299=^J[54
+MK=A/PV;^[M<HLM<^GAU_1BG!#'-4.;RQU11,>^2<_`"%5%PAL_0QQ[F/+WMD
+MU=80U6X.=(I[0A4)X<VK4\\2W8^RWSO>LC?AV`>A)F]EH/7;COZW^543.=75
+MK'%^!\9`J;@G$9MMLJO:\*$Z\^.@[@MZK>"ZT]%AS$!Z^@[RH>L%$GJY=@09
+M%S@;>K#,+&L^G/N8X#0"A/O3<4$I-%-N!8A5N55EC`G\W9!!V;0\MI?V=`7?
+MH5OCJ86DX.C#0`HSE0DL3JNR($*="GZ?4L=!S[)+7%(U]3E76E8:%N2I$-19
+MH_'3^@E25WURRFGB,U'-#8JSC5QKV?AOS$L'_T?<)\H4C"E!!7-U0(=X]><@
+M-T$%0,4%2P"9TK;:2Y<]:`9ELZ#GA1E;LJL.\54.3D&X6B2IAC#992%U1"X[
+MZ+;V$`TA#OBM/_&%,>F9MA5$2Y+SR5"BL@!*V9!+IL_%C*+A:ADGU,2X%8<,
+M#77<^=2-02ZDHC1$;AIP-1I<PG@XM):PUG+OJ2>-XD>^1/A<XYV%+HQG+YP>
+MJ%G,<PI?\K#&^F#$<)MA(5,BH_"*-E5?,)Y9M3#0KD]LIQ@GSU@,?8J1NP;,
+M';Z=XL`_'W_3*QO2,K`1*Q0$NFX>ZP$3.FE@:#=V66X&1=.?@AO@?L.Z%E%F
+M?@F-*38UM:N`$J3%@@_PF0!Y8@HW44H2BEP4YD%U`&R5BF<YW:-,W[N3XPL#
+MWLJP;:4GRECA=14Z9E#0P6BD$@V9R_\9E*PFB>8XU>1UW.2&#5M>[YC[XI'W
+M];BW[39IM]WH?[.YH?*Q/^W:N+$V>=YK=5P<,C[SI6&R2+8<//M`E3LUB\I(
+M3SWE:Z=?=]\-N#W"\I#DK*(.CPQ+BKQ>55&$@V'G5,U7!MR##["G6+G!6.@N
+MD'HC=5*XN:H\B088MOC3&X@,\82VUYR?_9#4KCL/:M0I.=B0"&1CLKS1:&UF
+MQV^?8GY;]T^!N_@?\$RRO_*U_`N#""]<1C1]5L,M'SI$9[D)41;IJ4:(I%?-
+MGDB=HD>")LHLV\JP"-"0JJ-4*<JPZH`5_=2QI+EB-19MO9#G!SOEF7`M$DP/
+M;&<HJB4E"31&^PU5,-H]/DH,3/S;[S1.S!_8KJ(W>3^PEH3ZYSQ]IM"'P\$"
+M([^QDU0/H[P.A%EQ5/D6>,0YK>99P(VQR/G"X2XIX<R<QJ38O.6T.W;<>?P)
+M76</6Q-"?_@ARV_/R#G<?F`AE21'LND^K+>'NKD5L#96<@%C5!S_S2%WU!]"
+M'F^SJ"X!&9R+VK1I#JO&/X.=@MW-:9HE]..;LL9#R-\#XCARGGL<8V2;=45#
+MN&W>]3<$X-)+1"7IB^M$D?[$Z"![[G'XD>1=I)@6X=Z[N&>IYR+P2E4I&W>.
+MW0Q2.Q29[8F2'V`Y:2'84SQ!">E:EG%%SG??8^\:S#<M\F4(P__[_EP8F?&S
+M]HZRTA$4K)GB]425SWYN-K@&Z6+#VY,'E<SM6#+/$/XF[0!6K0M8EV\J645<
+MY$^<ZJWB`)6Q!"JK(LI\]Z]N0!G\09LP7T"#K'^"!3I$UW5)5QRG<4DT$+>H
+M:9*Z`MKI-[Y,()3%#PYY=/#=HA_H5]BP"=)E9ZQXMS049?[V,QZ65U2X.?1]
+MR>8B$X[H9+56R[F,]I+)9O("QAF-/L2NI8+0&G`&4+D4\T"O0U1DJ=!9FW+R
+M(V`LPI:$-]3OZ**5-J,V+Z";0!Z2G-6"%,^/R,FE[EB?%]*!:J^QP5?VDMS#
+M>;="27G\*!8\7E8B7T/XD7`Q6JN:J)G0GE.NLPCP<\B3@V2/Y8J*^#E[3K>B
+M9S`YQ"AM+)A!]HL:#=>43LI^Z&8AT#4;C';SH(L.>$8-[$E4_%.Z/BB\CZ2>
+M&]UM'<=8GS_6P\F,L8F8N>UB3<R3F"'\,T99%(O;-K:@0!5Z[HM[:(`KXW00
+M7)FL7]2RS\M]5=%0V!I!?\J0%6&ELH?9SD_Z16^OG.]):=-LY2G+CZQT=,%L
+MA&MH[H+IG!#NZX@US$GDW'?ND)O'!:-+`T,.(.&G7+M"::>P%+_-@;S!)T$I
+M(L^`A"ZA672D@[0=\$P/(^>NLWFO4G#2HF2G2TW5WB3J!-AE:I?4_7XA#:/:
+M#OIZ,KW*_FPCFP'8F>7G:)"6RNN$QFCS(5X'ER.LF]_&4V!7D'9)GA;&QC.W
+MX6V(L@I$<@&SK2EF[L:G8B5-#XEDD0XYP2GQP'(N8:6OIRKH$YG[[+VI]QQ"
+MEB0S8-+O/VW-:O:$?=P0?X2J/A7T_(E/![M'FV(\\\)&J3^I6"SL,#5&>LK>
+M`$A`#W.,,B]=0HS0NIXWB-0!(0FY?JL>T^H-IR\^OGMC;;\E4WMA@>^=4R3S
+M(E88B)C0;('0#\L26;2WC-6B8UU'^C`DD1=C?M!SA]N1.@`#.$QX0\$^WJXY
+M"8_)K8`%'+/'E[8MK:CD9<G>@/FYI,HW.PE2F+-6+,9G,E>8MP5$+S6T9?*)
+MNWU\M]WZ^W=;^]:GMTSY^9X;-FRH[5&^8,OKKY5?;+G"&5^U6PMHSBVB/<^^
+M$[7GO<Z^Z<NG%6$S[39;4>T/NN7A3<<="JLX@H!!130F`A)N+=!.!\KNT!`S
+ME0P-;7KH=U400U-`#($MO/FAW\$`5WVN/<I\^2'B!G69NZ(8$A,8,JGU5]KI
+M34YGG;-QRYX89][_XMU.+<'K(U'VT/>RKP"N\6I8\"HA>_TQ<Z94S(/"4BTH
+M7PD#[0K]Y&Z")F!SP08#92;*]#P[@'$UZ!`H34A^5P;C(S^OY@S^;5$MT_.(
+MU,FKL`7E4HT09#MEJG]L#%Y9#^][A5(UB+*'S:$#1YTBY[`)"+G%E"8L#8!A
+M]-#OT(J!WGQ&IC*IZRN63XP^G;6O"$2PN@GS.#)8(EYX;`H7!<,1#_VN$F5>
+MV0##[BD6W1D!1]&(2UA^X`QTVY^)BU`JPR3"V41_'(Q2S1'.5VVWJP\[?./-
+M:73#<8)NV&?7T`U?>6@G69%*'7`>NY'5`>O^5CP$$VLL<"HZ2<.FG>\'=BUG
+M!F;)#4X\>,02EG"GRJLJKP'%8I`#6P)ZTEI92RNV%I]IEM9@?X\?'?V;_0DA
+M4N&(""G%MN8R(]`^.<7(97ZKS4ZMD#E9B^VT6F>[/:QH,J_$,U@4"G\Y,9!*
+MTT>IO3G4:%OJ)?QI`C31,R$Z+OMEK"+>Y")O[%\[MP)/HL"C6:#D(C/`;I/R
+MA`0:HL.,9X\]`M:PCEQ7K[O:94FQ1:D7EV^/=04)>\H5?H`IU;+37T2N9KRD
+M:+9]H=(=\JA@)AHITA7,KNU?+:<*90227=MAMTN_42;"2]IKFUAI)+/&8Z>=
+MBNXFU4P1M4VB$YBGUG::Z4#4\IU%=5;]0\M52.B)P,:;AQ7#!VI/.:*?;_B"
+M<GJ-9\[_]D@(QF"`;%6QXL0OL^A2?&A@[7!?%.JB/\ITUT&NE:L8$V-"6U[*
+M6N;<:7Y%@09L`BI!]3SV)_3V*EW$(A?]GT^[U`8T\5R-J:I3-"3<0G:/691!
+M[_FD#-C)7,8''3G_W-<J8:$L0W2D**4=+4YT6AY]"=C9?L6&)F$90V_$\MQ'
+MV1D>;*#N.E@P9]RRC.UX_$`2+$9B+$$JZ<88H,&:D>BM;10\=GR'5^"KOX05
+MP+K7OE;F?*Q4*,F/2(Z'(`O4FF1'.*^_N+QDW(>&7HNT!NP5PT6O(VA16$4H
+MRSM7()1%E$-8[!CTPW`=>ARMW6V7D(?=W/*NH2)<CS2W8JP;F2.9.5BCD&QP
+MN/V\81U=U&@:$=!W7,8[-26060J']2K#H`JXE**P8]B>W\FY14U_C$3>+;-O
+MH6RGSMH>%ZRBO8#8*2JTBC%E+J(&UC]L0!*FM`M0Q0U,")D\8]OWM0ZKMO`F
+MW?LEHP9OW]?D*F@&,#4+8=T".R6/690]=7G=Y[IK.N`A>>5$AE@D7OS)]PRE
+M["/F?L73$V6.NEMT?%Y4-UD6CV%#SJ.;SM1.5_&/HO>*>:-TVK"@F9WWO\`5
+M.!@6(3T63PS^ANWKA=DLP.[&>D!5C'P6]"&R^ZG\<5'FN$?9SY')'V:39>L<
+M.\+?"?2.L_Y-<`4&\N,;EBN154)G-;E1+[R)Y65'0*O(TZZP".02:?2N:HE,
+M>=I(W@:K222(H$G36).Z,OMS&2W9.5.H!PG7BFY<VD(%=Z@/\9!NH#-`5.Z5
+M!8XDU\9S6^Q8);G1EKAHUK><\Q7Z5\^P\JD)ITZ=[RT5&M8H*A1%4<O/YMF8
+M)48#D&\ID:M9R%4+U:!#%81#;$W%UPR.PK&_Y]5'$HZF9=.?C$JCPWX4QE,1
+M,"QJP?3K'28BQVC0()ITY^<HEX7'-?GZB^A?9ES,N0+"<J^_!(N*5GFR=GU6
+M<-6BEH^LK./``H,$H&-?26#J%0^Y`M>;;&V:3(H%\B2C^Z`M=)$?=^KPOLM<
+M.#L&XCQIPR7D\(A:GOXUAH?8\PNRVB#_$)D539K_G$*"]!6J:`_T5;&>A50J
+MF%/;8^2&O+<>O8V)A$D9%TY\J]>^OMUMBYRS/E4G#QYQ!C.Y'L$M<M4R61%R
+M\-:KS$R=K>2JF:K+'O9@DY?(LX)78]'&B)&4--'O"29%A[[M'NH8-\Y,*7)Z
+M+LI[_>2"8UR<E$V$2_?3?[,UKYJSY..!Y(^R_Y:S&3C&9-&COO^Q?`F/_HX<
+M^2@PMJ4I`B454:V-3DF,,O.CA(+'P'F"WF%$2#N`^`3PSD=?\(!?U/K+:=5R
+ME/GBKT`XY7FDJC`I:`1S:LZS]PA9*@KO(9V/`.<MYKS=H^F6L_4#YW=8>*&J
+MNDX+57#/]ZFRZ!6W+BHJB:/H_"0DGV/?$\'>"B[SYG;66HZY"J^U<>=#O2H8
+MR?RN`7%3,W(RMD=(%[L2GCHC`K4!O*2P0AN';<=,BEYG.CC>`R+\C"^[!96)
+M&1;]7&,5(V@,:;,T3ZUL^5#1;%L>0WWY?SW/0)M)>VU95`PJ8+-C9LNS[']$
+M]_:PWD<JAI.@\S$Y*EYQ?92=5S(5.#$_(F!16N^P25"IL\Q!B/?LYF_JLI4?
+M?XDBNS5HAW]5^UW<R+G]HX8J(E6)#,O8//DRP4%"O*!H'1E?K?=S(@0<.>-?
+M*QDL!8SY_M-<1=!%`1#"8W/DVX+E#WD@F$Q3Z"&'G_[,L0AVCGOXHN?`ZCC\
+M>R1$#9'24N#BR8%<8N[8<JD0<PU.4B()L68%WS)O_%S=_M"QS,<E,A%X2*56
+M29T?,3CHJ+"S3;648%RDRU8=SC%5*8(K,E:'D^YLN@"0]Z6X/FR5BW!]6S@W
+MQ`_6ZR4Y#<;\2P?]HE4QRMB8,[*_'P4^+.M>?X%3BP^KJ[)"#*/Y4#2H?CN=
+M7X%`L^^^BPIQ6&QZ*"Y1SS]A`UWG[[ZKU!<K"F4A5LF7=(S;(DM3JB_B\'58
+MBU*-T>9Z;;EV/).P-5H6TBL,D(NHPA!E'PO/]YM-#XOU\]_5??&6N0P^#=T"
+M.K]$><I.?HD9XMB]ZR;V+H6Z0=G'9OAJ,^DPDN/S\6]@Q0SG]T,I?E@IV5J,
+M%?VQEV?N8S>69#^;TLZYZSZXS#""\?09E$&34,UL@P31\/?)78<)V"W__-3\
+M,5;4:=.08],PSN)O19D7?D!7)>?<AEQYR-Y&5+/CI:\PFQ(\30F`Q/PN4+TQ
+M20E0A-IVD'OL`_2=@AI@0:(C5@PR/AU#Y?%@"<0AXVB""7`].CR+Y+,<3TU7
+M,^3,K^3NI5*3OO(M37`^B,K`;4ND$Y'O$B-!M-EH"NC[SJ$_!\)$H+_I5ZP%
+M9`(EZF/U2X`-Z0D2YT!EQ7:<0*F9TM2'UX=ST#OC7A!J]@,JUI5\G(8;Z+97
+MS-ELM=T=>MTJ2SC=>K=IOEN]:MK7+_"<P`\$NOY5'1T3__@6I7UK#T1_-?`L
+M!9.%7@7C-!(#)0&@M?3,JY]7OH9$&*?]'^A@T4XFHW^0[X5$>=%$2MR@PT=@
+M56[Q"NNPH:MIX?F"NA"*!09`8^A-XL:&=P5U8'X`Q-NF!:1P60"`LJ?DK8+C
+M:O,B$?JU<\J1L_/Z#F-YZ$A'R"IQ/U[[H/50(5:\0!,9AFD.#X)G1MFY5X&\
+M`8T6OV+IK&<S>V6,8H\9D4L3L"78YS![[-%<^$VC(D`47Y1IEFE+A/X7]G.V
+MRQJX^PHE-S_=9@@0M2#->9VY\V1VLE9]JK1G\I9ULK3):(*%-FS06IAUUJ9<
+M\(]D!N6S6S!R$F6O.E)[#,B$(G.HWJ%GVD;7N+B&KS]H%EJG+2%(3RYY:?_8
+M&U"JO/Z@NEHTM377SJG!5QYF6ILX/HV7$@Q`(I_Z0Y4S=,+%9);3$G.)]^M?
+MU+0:XKK*>9;_0%5MV_2F,NTXN5K*_O0SX%59A&%=Y^8FF7%K+5<727O2>YA[
+M/IXM_X)ZKA:(TVT'L1<(F\>X'/Q&&1$9);@ED6T5!`4%@\U*Y^`C$J18PX9D
+M;H5Q@X6$E:]06[,8M=6SOB3(RR6/^D5"6\(FN.^&,HAS"LG=BL8]OP4O*9KL
+M'GR^Z/KKR4C"YTMN3D.;3!V"F=TSJ0K!IL8J!+J&WLPCE=5,U;/B>G*G&*7%
+MQ=(V8^A#,?2H>5?L(MAHK#:BML@)^"KL&O?9*;HF-1=9#:N']L`9?5+\(U'V
+M8^]7:&;Q<5L@`FT.6@"=@/QGQ2B[\CNNE._%@Q/8:8MD_[&N"Y^9VI7429ET
+M+5%PX@E<A4E6V4.'3_95:EI8D;P*DRAI%]42SX=%6Z%JGGAA*]<M@1,5CK:9
+M?XV%YQN&:),K^LX5S(:2R/>IE.:D*3[?+\&L?7<MF/63K3L(9KV6ZO%(>+Y$
+MFM`\9Q=AE/GJ[4Q77Y'R;EQQDXQ-9(X<**J"X#8$2;CH37"+-+4]ORPL?EB>
+MU/PNZ*)$;#QM2Y']Z_BD7'JL=15)@>E#QS?_<$DG>SK]/U4EQ)S^;S)G,REW
+M;_^'R&\+.(=/4_^YKW[`2J*@G0(F7M%5J\JX8<#ZZ;<A$6&B6$J::3?D,F`I
+MF+?E5F%*EKZ$TYLQ;-D37U0P`8XB#F(!HNQ53Y%?@%1W`H.FBV0%""4<TE4T
+M3E$$".>\1PEMHB55M4T3-FY[E+WS@_"8!_MM/3+]TOFKP;M(TVC7ZV.<V>6'
+MVKL_\$BA25W#LA:7O960,(&N1`(C739=)C>T"FHD)M8OFZF%N_A[3YW)"6I%
+M!=QEQQ>V'3G!I^O)2MNVY4;5(*Z:J9CWJ\,4LU)$#!:6Q'*G\72`*#CW,Z#<
+M.>UOMVP<*6JGB0)"%BUEY:/J>I`V&/=-<:UH=R8)Z`?'AS;;E;LXI$>(`L--
+M)*(0(TUB="G<GLY(HA%M9M3>]3]#0G[GWO5!R9+T86IBQ"G(]:3X%[!.JN*B
+M=-&I]!S9)*RC\%8$$P89-\CTE$`"6&_Q$0HOJE(\:MEWS5+Y0BI3!G05[214
+MU@7/KQ&).Y"4VEF8\OJW_Y#.6VM">HVVX1=UE70OEI[\6MV8CKS*(-J.OI3M
+M.BSNA"RKF=[S&RW(AA_"?M&[]@^E-D^4.7>)^D55R82JOS;2=0DC[,KA+B*D
+MI!KFG37GUP>N,&RC6A:M/:+IB6$ZK2$*'5/JAJL=[:38,>6"2:Z[LI4<A^QB
+M%(T(/]66!DW+B'*MGQ].I.#46C[T/%)AJ@VN*#$SKST/PYN@KRP1:IG7_J!K
+MAUIZN:+HT.$4MU`:`#U!JU1*;NJY=EISQ`B88.8F/SMY-5RC]K2>8Y<.1O+\
+M<,V`^:UA-ZA,[ZQ-G?>7GEK+#]\M6DG4\L.?H`,%%6PLQ$D\E`'#[M@.&"BA
+MLTI'O<:SO_@1;AG23+5WI[W6LG@;F5-2S>DZ=L@T1F"QYM&ZT!L+X@:A%#D'
+M'%\7;8K#LXW5<]"WC\)K^KO/@'N!W<<<%N.[8UT,3>L3C[;`)+?<YU?(5Y$@
+MW\O._HH=4QM"(9A2KR<]=D6/ZJ0W*G.CJN[]UYDI/^[4`N45DW%6"%NQ)Y+D
+M5#]"[X`V*E`3B'S2<9)^U`M^?2/M3'3W9/<MLG,+F<XT(\\ZOX#1U`M/753!
+MIU%B40C/E>P#R<!G3G#5[Z'A"@<J/WRGD1<([479.*:-#-0J3KN,8K_$).X%
+M2$:$=3;53D^61MQG70J^:66^;-9)OFC\T@\QV5Q#<41K1:+,/[T1+L&:0-%B
+MI#[&_1#J\V0=/;74.<RRCS+77M-H-+EHU('0^?OE#3(]\Z7ER$JK,K"DCYC%
+MVV&2M8L#J->(-FRQSBJA&72%BO27RO*RB`^Z0U.2]WU#?T9^7\,*WOA4(F0Z
+M2VAZ3V%/MA]81=LP5#[D63'2GIISXSA#%B/GQ@>L.N'!(%?XJIJ8`URC#\2P
+M^0I8&,DJI<Z9$EK2<<VS>Q8BC.2F$RMT&_.ZN.M@*K?[$F.G17+95Z+<[MJI
+MJZFT="ZWY`Q'SK;?K#&;T5K.Z:%+VA:<@,,O<^WT9]+'2#.WZ.&Q=CU,C;4H
+MFK[.PVJ+5'V1+D"N`]G5VZONW$7,1Z/#;S]^)^:I?&%E@>RO==K\0>?-(-?W
+M+3,%"!8'-G<PBCNEGF+A^>R[ON3WMX]GW2R;$:+)<,@N-.IHK#F_>)D4M1+<
+M=:06%9/E0_7U2=4K#.\+><FLLI0['[]5?++9`VI^F![B@LJ(E+&E0#8M-VF*
+M:K&-B4S&IUIRNQ2S\Y,53=<:)-D'/R1F#*]Q?Y4(,R1QL9;-/,&_3F1GC`6R
+M[ODS[P@\M\S)3N8'*#3']R-;6&PFL-:,*2;H1/S=Q0KDHK.>00I%SO>^:39<
+MN41).8H$S@XL68/6"3=HX[UX"`8O4D%`ZN0F-L`CY_/?L80P@4=5#VWDEPW8
+M$0";%01DR-+DV=\6*S9[V'<]LND15(3!%#_(F?30P[ZK=C`"\Q.F75"18LO4
+M+F7B\%5QUCV*%`I&Y6_P=7%[<D&K'KL4UK9\?#"S?[P&#@&]U%\J&T]7UOEH
+MH<J5NS`[']9VWIYF(K!F)]JGAF<I88=B1^;46E[Y@:IWR>F79$V/9T\X3^NX
+M4?9C=ZIJINTAUQGE_U(2.IV?&)2D6`Y5J!32R=??M:AH4_AFOO$$A=4Y,8@<
+MR"`/'[W2'%H5PR*'':,13+Z.GR($/F@*X1/'#3Z1XZ@P40>]U"?#9!-6*ZP'
+M39',<%33X,#D8'9G;#B5-%\3:P*+:VRJA'U'APLEG^O=I<U/JBQ/LFI>K>64
+M&Q8@\]XP`^<367",YW`FOU?=OL@F[(:<FUIA('LIY1Q`\XGYP=[V6K]UNZHV
+MUYQ.NNWRSLAI^R\Z=XDD!_$_%`VI4EKDU:=#VYU?0W6=BJSWCR4F%TN=V7E9
+M5O5M-\>GGHN,XP:V1I)PXW.^X9)3474+\`8*-/%KH3H4J%MB55962UG,10^)
+M;>1RU3%<ICZ.LM,^9-@GFW@MMRU=Z/6OK&6G=8DM@O]<6>_DO^K$`E9,E+C*
+M;!E8PS7+0<.#:<E\]0V&=7A*[2+&0]=4K4!I4JF@0"1_2M5*&'4C9\6SJ:5U
+M;==$]ND.IFZSB@_C.RI'@*U''@,8CVTV*^":13.&HLP5!V#L@Y(M1I2*#ONC
+M21DG?!?&<\L#.,&+:IG+7\R7U-X(L?JNG7U\_C^2-J65-P,F3LO21<M+@D"!
+M-;OV;,X?S7%M9\T4H>2/*39%5][H5[4?+Z?N8I8AX^;GR-"B71JG.P"_6-LX
+M(F54)'T-$^0CY]E[U*D:*;O#W#[3V\$,CCO/7LC-TB:()S1*)T5ACTF^H3YG
+MKCF:$:TJW]-')!_5LNH?"W?E=!BO/_YZY,P_E<J)./-72'^P^G5LE9R$S?%?
+MPWAH8K@,-ZFT0T+05(=,_$D.*"CY'/#GZ,BAPPM$>>-H\IR-M^][__-VG+:F
+M/2DJM-JZ:]YGXWY>-%`LE>G.O>2;-D+3PJZR(P#N#>=3AVQ;.DIWQ1@^KUP#
+M>*GC5RJCUBTJEBH9G4]Y[.C*WH&7G&ZG1%_IS""(+.$PM\I?2MF--"8M:/(S
+MU#J6M7##O@1C#)?058_IG[0?Z]._K1CU.,;.59/RPIS>?'#H4%=O*WGWOMW-
+M168<9^>UBP*Q*:FJ*:01.Y!,Z=JT_*\E5%Z[-[NB[<O<<EF(1R_`HS?,CBO:
+MV#7GT:5U-CJ$2-]Y_?O:"XW2AWE6D%8MYS4FS@82WK"V&/=P6E(?YU,TL58N
+MZV7KY:K._7*O0+5P//5XNRI9:9KG9[K-,V'S-M.ZOLP.GD(8^?8_T(%]Z.CD
+M!F`*6.:P!@$T>W=BBB7K"!-4E<PQ"95P9^8YEIY,:45SC5.Q%0,/UW%I6$\U
+M2Z/0U]'NWG:LQB(?C<%'8]V]4C0"@1O"I$3?"W4Y3QR^/::FZZSMQYCV1[M5
+M(VH*YH]%V35;M-14<1_JMBH^;$4*A<Y4L+0VZ7,K;RNZ$-'M^O2I5+/QD>\(
+M#ZA8@L(#ZA&TG$+E=`_RRYE'OI*,Q=+RDNG7"H:PQ6D]JZV=NI6C?#TJ?PCF
+MY"9F17`K#2&VXR7$MM^NA=C^$NPTQ&;63&WQIHO%P;(]=K1<UCZ75<.Z1TWW
+M.+=IXGD]*'UNN(@(N=%R_-?'7:6_@;`9D-PU[;#CRJ1<G%9SZXDEN$+A0&#3
+MJXA^.+5(.!(VJMQ*X@Z;L],8`,8`M=^A/\J\>K(F%$7U:"IJ<)9"Q(@F3Y0#
+MY3"H9=[\G17FKF5>G=<T`/.CZX=<2EMFFB*%T0'-6?%+>9IWP(JT$3\''.Z3
+MYIQLRA+YQ2C[Q"&6Q1K^/^2]>9P<9;D_FG3U)"P1Y;!#5`0A,V1FR,QDUXA#
+M]I@)D0PB)!%JIJM[FO0R='4G,\2P*`('24A3I"PR8$!1A"/[/H(@*+)Z4)'%
+M!450^1%%1607[K.]2_7TA'CNN??^<<_GJ)/NKJJWWN5YG_=YOL_W2YX#1@W7
+M\%%;SH4"[V551^&)WHB_VE3]X"[[;U^^=F.UX;0,O-2FZFX=_QINMLL)_MBH
+M;B3[PYJ8O$V@D@NCNGS0ZDU_7D$R=BH1)SFHT#E\;T+*D);G^]X(+.`1<T61
+MA=$[=+`S\/B:O&[H[/^[80[SV%_:6RT"'Y.3]E91^6'P%_;_G4LUZ@?<[ZI(
+MM4<$Z27X\/COZIP`7/B]:U84AYPE&42D(@]64.:`=X2CB-B-5#'".0J>/A^<
+MHQY-8LPZ<,1'NNM=>28H(G94<`UAUA4+3(*"9H>"YL185#1.(:8`-#ND"6%P
+MCE=E$>-ARVE4Z6$C0-`J#?1O7I!&!5@RF'1*]>,4V(H:*1PW]38^RZK"+_CO
+M(M7M(B6L)NDJ(K;%M9`.]+X(=-C*C00+\-?S)2D<)C??G,652@ZH`F/D*J4U
+M_NSJ^+U:V8+'XO'01IJ9ES1S7$7)UU*\,&">:HRAXB@.'](3"<"I#VS[&B$*
+MP%"'*1ATP^2>AQ++0F^YALGT@[]9(2R]-&#XXED,V%)@W=3YQ:N_X*7NRV$=
+M1*6@0D9Y6.&8R[22\TC'@.0U@T(DP#8B4\#L'[U/Z-R1L"+PL(Z2@]T6_UX>
+M=J:TAW1&2DK#^=VUQ8)>$:ZX#85MS,R_ZGZ=C%IU8PT&A[H9IO0KW^^N@5.4
+M-/4@`Q7"Q#5WZ'Q./5T)93>%*T)A?K5AO.:R84N!4!8>:V-QY6J)B&W$&O"Q
+MR,I7UH3X>4GSG[BB@]X@U01&/1UD5"P5=C3YTUSA!NJ:'OZQ3@28W_2.^DU*
+M?6/KX#U^FB9&%/DI1$O'F9@5PS?\.%X^ASD?G=3`I!#T\]>GE8NBO3/RD&C5
+M%-)QV"XHQ%BX3H+#'C'^$0G@<A'AN'\\L3C-X):LFCMF@,`W&G_!L%`FS.N+
+M-U,+N,+>%3:\_'_LO&_)4SI!GM2UCOM65[GD$1I+0@LC]L.&!]Y#[C8^:+96
+M)[25%I=9;X'PXA1P@DXDY#&\-A%Z"[L[0\:IM)3E9/^`;XN^+DV<6"8=C[:"
+M3;"&40W]<'/-'A(;_M!9\X:LECI3@+X5ZLAC>[:<>Y!'0;8J?NSKI9-C)N,P
+MN>!)!8:)>=ZJ`,L>4K`^-[S6K10]Y4;DGI<&AQ*#)V:*+"`>":-)KQ?A1@1]
+M`,Y(M-'D_[#X->M'1..1&V1F/ORE8#ODSA+,"1/O/.(5B`G/Q>[GM'D/'KS&
+MWDPQ$>Z*%)T*O5R6;+XGP!F4Y(A8D*-VA:-UR3Z#J=$C#Q$H%:-DL5JA*-E4
+M/2LU)M3UU>.G;:''6[8CQ69#"\;`__=YN7ZDL^"<F)6Q7VSAFV@DBH^I:]!8
+M$;03!<$%?/K`*1CH`H.&4"786%JKNTPF(%#]XM>&Q1\?9KYJ7RFJC2`+ZE6T
+M934]4VWHV"SKK>%[/\F6PX:I$R7'2TVSUQB)&E`.NZ`0XK&J8_!=1I].XS:$
+MNAHIN=?'L:!'D9#%Z_`IQ'[1989@P`\T,1E\7DM,EOCN?3@$S":*R`1:I3ZO
+M:;47P;AW?)+;M-5J4W+M)(HYPRR"-E/\6%>VEB1+X@_!I9@M&43*?#LE!"--
+M$P#Z@W[*G@W6?C,>`#V#`(<OTGZ-7^,432>GJ+OZ7O.C@_U;%J2]%K\_\'JA
+M%>@@:5*X.XO]961<<VOD08C$^L\'U\%X!XWJ8G^XB0F=<^0G*:`W/`C3$LR$
+MAC=#<GD_=+Y6I<R"I4_`G,[$JQ9)';0($;16&[[9:#,KW7$P^3^%:%#/,L58
+MN-OG$5=`!S!GPE>S:4LVP29KD)V]J/GN)_GR,,-=X#PXV7X3S`8ZK_[.9%^0
+M.+J21NX?8J8:`2XUDE@UV3@,.X1.TZ>AU2B<J\J&631WN'4H^?F.;EFUJ&<'
+M"QKF')@XF`BM$1.BIFT.KZR2T3VRUZ+X&VX><J;]B:N6F76?H(3ZU-[1'&E,
+MCWQOZ#4E!_.M5GQ1I/4$^Y`>M,0A`C4"BD/\D?=4FRDO;550E=U,A@JHOO"`
+M$I<Q-(1<&6A0>7)W6U3DRTN\`<P4!58V3V*Z=7N0)8Y\!%N2W(5I,X602(,)
+MCS:QS`O<;LO7K:2B$1N4WO15.2EM.5AW2B=8$1R4S;^.PF+BN@9^.KS)?==3
+MH2`B/!B,F"-QE)PZY#$I>3;--+RF0$%%NR?V(_,3O3??LYAN=)L891)[49H&
+M[C"*J,ZXJ#:F[8ZH-G)/ZBT/G"37S@FL>X\L+V+YX@I,.;<T:%W7:-]$7Z>4
+MC?'W)ZW%`:W_.Z5VW"C*],07&?3PH0;!*3J0./+)Y!LOS:;+=(-Y;<$`H5L&
+M@GFL86_>M4ZKY[4U!8<?3A<<?KAJ3;W?%7:J">W!_X<-F.>3>'?9/!.'>P'8
+M9B]V*0_$SG>;5OBV1A&;C3^W/RHTK=[1<]ZG;W`EX]3:F:=H!5WB^>G^&M5>
+MPF$ZF%#PFL/DE1GP:YJ1X!>^HUK>9HRGX"_%>=9)?AVAT'G3Y3939O+P_<5"
+MT?E#`87Q&$VQ=@1"HFUD]FDROO`:IO08HZY;WC#&'=.+UY\:JTG4=#IH!?LY
+M&*).W/1K/C!:.(8UN]&^:=5<*`8,)&*C&HM=/ESMK"9/N='/XX8<\SC$@].U
+M'A6!GN_3+7X0J6YHAI^\5+V!0['?F:;29@97VH##N17K9-9:X#`P9A'U85GC
+M>WN99M:?74VFX;"%2:;!^=TV7[)2(',^4<XSJPGZ;6OAY5HL])*1YJ@Z\]X9
+ME>O:9L?VPX9U>Z.CBE1NFMR^MZ+TNKT2':3PK6&6P4THQQQYUF-M/LK6JO.;
+M^^83GER`N"<LT>)EE$^HIR2BXN$F@3R4>-&7<S+&T'HKY0BFY3K2G\J6B.H;
+MSQ(?.(UH_XDT2+UJ9-ROB.%SICZ=(:MAXG>WJ;H\PQVEAI:R*43U6:>IL1JV
+M1;N)I1'D0??M9551QF@>%?5'@D0-EV&6)YT`J+LI1F_&=)&#N(XS8Z<,IT'5
+M>>6=%95^7G(QS=)$\(M8L$[*LJ^]J^[+X5O_XYAI;W[]D#&[CAE#_VGHS>>S
+ML[8?DT<1!'F>SW>(ZQS38%&=X1?V95Y5\@:4,C5[+_'7H*/X,87A267K973K
+MTZ'C/FUU`0FH(!T$.VJ6V*(HSR(Z=NR_.J-RH"3:8$C*;UEMS+!W`,8-'B<X
+MH)J@DLIR(;$+&7ZCO,!5IHT+O7(GPT/E`U(%"=)LK>]J.=UMXS^_?-I:)<6[
+MYI?GN5G^].-O?;])=BKXLU%4.]Q3^):D/I)G#<4FWMA-J19X:QNK3O#<]J[L
+MIJ'=;VH<GE-U4C="#X:)GG#[\C'!<%L(7T,785C_E$U1[`?#DX,VZ*%H/T8-
+M!L^5+1PQ3DJF7;0\R*'$U=?$^&;4JS<UQ>OU(GS$V.DO<!LB8O#'5>M7A#'$
+M\DG7T;RC-NUQC&KT/NOJJ(G+E-@BI9S[G,E\I?AK.=A)\+4F?]8^1?)G^^Q4
+M_BRQZY,C\F>7OWO5&>]NO/R][)EC-_(A\?+WO'2&J$#'OO;HH]O&O??NQHV;
+M'WWL\K%--T\]>^R4F]OQ*[CN!?@"SO(=V[L6^*?.RZ:%?Z&ZZY\?FF/T.Q06
+MN7'NDF,6+\,CU1?>/*Y1S/ZA4_"'"R8'^H.V8,$1(N<BHBYM34V,6AYY78NY
+M;DK]Z_C*(^\<;%SEM@G>6;>K/=:NB\9<\='_-.W80<-ZV_F^]:ZHWR2Z@MMR
+MZF^OA;8H['6C=JA6RR^NH#Y5/7K%3G7G>EZZY.)-IJ?TWK1=K3?[$;SJ8I_(
+MM<'Z(V1U+SBB*?:+(S:(<_:52T:]9:S3-\#_UVE8R_^P8=">]WU^[$KZ]1GM
+M>S7:0D=J0FR@___W)L5Z8QE-+TVNVTMCOO7,1^NV<F>[><Q[VSIWT,TXD390
+M]X[>LI;_6<NDGW?8@&"4)F&;=FIZ;]N;=&N_<%UI>$$V4^',=MML/,]VCJK*
+M)JAF6A%8.,D,0JR`C%X&59(&QI?<=`5XI*^ET]I8;=IT^=@C#MBJ;1H:T<O'
+M?O[,!*$'WKT?#""%CGB##IUKQH+)WRQ;;M[MA[WDEP,JIL'R?;9BD8C!$Y2'
+MA.Q,*6ZE/W26/4;A+&;#5R=R[#M<%KC%!/&*<)7$YBW%EH52-)$DIWY,'K:5
+MF;BM0+L#V8]&.H:1[?;%%#6QF.*`+PA).A(R@5_`"&+26O7+&&4RY1,B!(XA
+MM3RE9(V"W.Q-5^[UR_L4/1F/`LZ``C*:B$:R1`\1'GCHH82M7''Q*@F9Q-RC
+M>-<K;&2:(SN<<:$=W'0R:\]=;UVHW*1#6L/DC\YB7#I*$3DK'W!SR%+6&B#7
+M4M?U&+-KCM!5G.37:8&E_YCXZR*-:F>VD4B+X%'8FK4-F%Y//1_>\K47"*);
+MM,81G;$AY](7>1;LV"="3^_FR8O+D9Q!_,@M1XHA&A,M62':_]+IF.)`1">Z
+M(X)Y(F*H>H<%:.`IT3!Q@[KY:)C%;DT$E8>PFIRS5;2:QX>3%H1T+%,BAT%S
+M-7G>;H3W3,[Y(X8/540:P0"SJ^/R%U,!'MSDCZ(4H8K@DK/6XE$T=J!(0OO)
+M>X?C$6;"I$RK5KN`@[76S:!I%[UNHOSGW,[ARN0GG]3\,+W@^2O:#>O=/GG^
+M,*MTP)WU.#.)9G+F8O:5?2]8A726F-$[Q#CNOD"N^?E?.88*IN/C&SHO':9)
+MNB<46'K5*^-A*)=B$S#*G,-9#V_RT1,U=*+B>P*%Q.2-B)_0:4\41"B,B)Q0
+MBN]D5:J2S[.T'K3E$'MYJBDWOU0JELRLXW_:SKBI(7=.?T?+^*!BFM!)UO`<
+M1];AAVWF"7V+"\+;6W4N2>/IQ$B"J]F"D959CE\F<*Q(YZ@N5SV^E?WBY%E_
+M11N01L(^`JL9Q5<>_R%GP<$5+D[[Y!>V=_$[<;)2=,<X.6T"]YF*2TWW/'M>
+M4;;7^?HKIA*/HJHH@@:O=><2BE`HP"!VB0"7)!<FW,;P[M@`HT+*X5K5*DIU
+M,P9/S4X;AH"G\H(>0J4A>AS6X+]\`X>79"8[+Z\;9K"'CXD(?8V/7/E4JF&1
+MV!PV#KO0*(E2'A5FU\$$,N4:7BS+IE1-7-Y'G1]%@1NUU#_U4*>A8B462T'9
+M!KR[!VVXGK?JXN@Z(1HM`+/-S%'>ZG&6#@2#P9R@<2"8'`PV!4?@7RWP%Z=1
+M:..6$R,!/A#@,ZI;,-P:'(/A)Q2/Q=*):]?)JH6S]@0[A\(I%.B3"Y_DK7IR
+M$R90KEL+?X)OI5+C1S2Q6*+FT:/#.L^SHJ(U->A<++$(DY-.M$6$R\R",O[8
+MLY:Q)@,EA!OI1$ZPKK;`:V^JPE5Q^*4YI_(O0N>?16J+8K[")/+R]/8NCXH$
+MO/;MRS/2;OST"*\M\MJ/H`\M:;&=8=69R;&^9<4M=UZ"<W4(^IPDT6!?*K`@
+MG43#HOX`9<@6I+T2JIYNNMH$^%;PE*!UNM?K.@-G"1NP"#+)W[HY\D!\K8G(
+M"JI2>Y$*$ZM.[J<4*S/&V+J'L/N>]056[XE@XV*046O5>?8A57GK:I%=JT0*
+MR<".OENMI!J1):;T-.3`K'Z._HRS;#_-,!X/TNYZC44)':-PIYH=;"OOFD'9
+M]5$>[,V2U+/VL9";192GP,S)H6]CQ(T\2]3!+06,E/"5"A$5%+K,)MQ:W>7Z
+M=*=0=/5$7LW-P`+//V"=06>Z1%<O%34C,/]@1*J[N;DB?%U36)8%"S?O3(1$
+M(!Z(0!&$P"RF?8[\6KS8R:M?[59[*`H_FN2DK8/#\']49^&W\K,#Y9&C`I/T
+MH!8]2:?!%$U>?!:QV6H2"S$-"#7,%Y'.J;]/Y[;W/><6N78:T3]A++N`=5$+
+MTD+X:H#I"AGHW'E[W>`NOHW@GI%\-F<D;F'VML2Q^A2TO/9@5JW4\O."UX"Y
+M^X,W8K+9E@+]"!&_C+``8(>5BA5$*=#$C`;[B<(.TY.P1Z5*<0I"^DA("N&(
+M5IUXPMES3*U&[-O&@=D#?A.&">>`4S\0--*WZ-\'\+GNH&5NEK"CN<&AY*K'
+M]$L1M1-3,8CH)FRZR$D%?Q737,@3#&2-,K6>`6.NU:Z')%Y0F#DJYM;:20"4
+ME8&-/.]Q!6N:(#7BG.L,`"^0,+&DD976,'07,#V@#9\'`_'T[=TCA%88Y+>I
+M-@#7)@&X?7<N`'?8ON\C>"+;9>C\XFXVC*3:2!T4Z0ZB::9V$5B/#4^B4)Z9
+M0Y%%!H7HA99+A=IK*TDV*>=:22/":O06'<_<#E)9G2ER3+^&9%YR[1,&++2&
+M.+,T'8937G_D81F-Q/0MEC#E],;.H(AM3QZ<P_?A7()BC#LX1U(5?D2E,#1U
+M8*.<<P=<0L<?XBV%<T[9TQ32+I+S?6B;@+GT\#*FCFK^]%9C-PMI*V"/@I.U
+M)JG`CB%.5>B:\8]_Z7C>+=8,)3][(FHL+,MZ8$L+M..IOU=N7+8,]:#V^^BG
+M5JLY[KMI+RYICA[[:Y<PS,SJI9B@X6N7()M+F13M<:P+2OSJWD\=A_5>AO/=
+M4INO)H_?E^1)]KU+,X.0P\;LW+0;Y+G.CAQ6O);1"C`35*D!.B&4-,BI"A.Z
+M3H2`"?4J+-5B2(T5M37NG:Y90GZM"QPLTB\*)7!D8V2105H`#"W&:8;[;3VL
+MUCJJ"=<<#*NF(D@>@>Q#SO=.R*IC1U1`"&4AHX%C*47[?\^`)'/9QK;$#3GT
+M]H&_-OL33A38LV$J*F]7Z]XZW=\W?,'@!*0N810O%WL4>_Q>K>PE9U=5$*UG
+MFW$@0R=S%.)IZE@U<C3P2K4GZR[!26SS&R1OZV,_A/0R5F[<ONRH3=6&\?[P
+M:G`#WKOVZ$%UUL2"^^9JPT>N12$HYCOCS',-98L(.F!R`L8#EF4I-93L?T&F
+M1=`'9_V?5[$8$76(\A1R\,'+[O4BD?I2\VLY_S-T_KY6_]Q5C#4NEZSUHXH`
+M^M0*C053N_%TU^*:-(,`[LT6RMH..5^[+>7YO:5L3^!%]HA&JB]18X7@=3SC
+MHD:<Y-&:`B9:E?WPP\3CETZPW`:49C?\OC+5FZ!/Y\Z;U;:INN^[+ZRN-EPQ
+M$]:^E]M4_<#7L8N3#>=U4TY_,^?T55O)O]E"4`+2:L&[YK"V`PP9N0`1-)*4
+M>B*T,0L]I&&/X,8N&1?]`%EHL%9#Y]Z)&$>I/UTLY@AY<]*R'3?QQ^+\5N%R
+M/*X9>GI$6/US3^5G,*W07\98ZK6*)HV+(7I[*RCDZY;C.[&AT9*FA,Y!BYG$
+M%@&8:MP)2>E,?`!6!>K<E37KZXBNDZ["'#)6YL[^AIP2Z8"8`5]D3L!()/AK
+M3C!%Z6\)W"B#4=8V^5!ABP;PTB/`>VE<-8CQ?KP+G3`;!UK:-,I=\5D<?!(6
+MM3#HC5*S6+5@I,C%B,,@RF89H[30H26M+DN<NLX)>\)"-GU+UY&W7NS/:8(3
+M=G(5RPM-335<$XALK_L_J3)DX1]J6#3TPP@^H=UXOVS-"^V@@G/HZM(:--QN
+M"1HXYRJ[E!I!N#DLN+21@]-;I\*$WW+*XH*USR@+R0[IC2<H@6-6:J6`1TZE
+MQ/-:G#<JM\`T2%FJ\[I:A?L[=)ZX"ZOF*Z3A)0&3.(6!6.X3KY;3$WD4*H)H
+MRCK4:@B=Y;^JOW9P,U++@#"C!FP2.B?=+8@B>WH2@6J8N"A-0JP($0YYSR69
+M:1HX+H)!&&G]6^MHN@"Y#_CC&0+:G8;T2\F%MX\XTB"1[:"J;+9U:A2$)OEN
+M+W5S40Z<8.X'K@+C/LDGV4'MMA%!0ZE2()(SN5\-R66!X012VR%7#C<SE8<I
+M.:P0"=N`#XN2[]TXN2F8`F<$M:AD7GSD;IR(E0+^:#0W'B^EJ(6@3K$\;'O7
+ME(#"U4;\3%IB%=20NI>!>LA/5O1[O<.S1V\J?H\-%5T\_1D5>\KA:,JF.E_:
+M9R.T(_5?O!.#%7L>H'@@$O,/P]^I4I$>KFT8Q)^8_J4F#0LE_3KEYK!QL#T1
+M6`W_K[V8NIM5"I3LFR:%F.3<]9+GH4A)J!`&>7K(P&OM:+3[QCSBG4-GZD3.
+M/!%N&"S+P(.+"X9_R?G$3U2/D;^@"F9[,-#GD?[V)TC,J19D72B&R:DG<ZB7
+M@#0<RC2Q*O#R!X-%13AJT<$(7(XO'H)6$0TF2@DH2*^)$>I5&SI^E</)FKH<
+M.5`/5C6;=H"Y:&G-X)L8,5VO/W1N.T^WB-AKGGV"ZCP8^49<>FZI-(AV&&S<
+MF-V[Q:!3^PQ8"X][/UNN=R&]!A0+*JF2</0&?0?+Z.F20XUQ\H:<_[AS'9Z/
+MRP1Q(6^+/2$OXI11A"?0J#\H^A0T92U=8]TB##W[=F#MP$'R@77HV]CR6)ZR
+MFIS\VQ'T>,Y!]V4+QO08DGH*N')TW57Q650(@*[T9=>V(=Z+"V'BK)LI]5=-
+M;)O-PT>;Q;K(92YH*ZH;C.:1:YCH"BT&4>/6<MX:3G;#676RKM&`J+M4I\AB
+M-5$8M2!'B]*8[T=?LBXO6@ED51-[#0M)7V*OMWGF%7/%C-)J>^`[W?;TJ=T0
+M258^$`\FIHD#N^#U'2U!.L9K>/_E>JOAKW1Y==V>M9&'B=_<KO7E+$\6/\>3
+M.Q'X<6IO61FA;N6JL_0^:AZ6.N_ZQTZJ9A_13!PQ.0>YF@]8]/_`M-"=Y"W-
+M8UQX"!]MAD>4#!PS8*U&]`DUSZC<3>F1:Z$*8INH)C??KA9JO(&)LQX;9='6
+M=UK@PXB(9%+,K\P]B(FLRTZW?7IZ&23KO^6O-I\C^[8Q83;P[IF3R\0MS10(
+MG?N/52^FC_><Q%)S'[N+D`UN8?,M<\O5Y'$?QD7>8HB(^'/G@M_Z7AF':^)W
+MYL+SF`8^X]:;<EF](:B2Y)B)P79CV/"L2420AY>`W;AT(F$'`FD,2Q.J9"X,
+M"XPTG=?Q_5LL!"65:Q^>M[.0:@/#`XVQ[>1ARKE(Q>74?72,`Z=<3*D+;`PQ
+M4#(/?HVU8R&:@L%IZGS8:2H*.XC_@#6>@?\>4/8@PW:@!P]$<R@^VP/_P1^Y
+M%K^.&R;^^(3@WD<R=$IN&KJRE+(ZB@UK!K^BX'?M8))\F[/%IY"^3MOH,*5S
+MZWKMG\E(1#7CH(>1\UBAD]E]>]?Z=&L':1%G6MLV(!YBS["SZJ1?XPF!FVR?
+MJSSZS.X<V^TC]0ID)BDWV]L/FVE*UTH*2N^P2A"<^V#VR([G;L>CXN"(SI81
+ML;MX+K\B'OF'DOF_RGO"5@IM\K%J5;@3E!1U1/E*Z#0"+NCIHU*F8>*13XU$
+M1DG4`\^->)"38S),*.?[)!I:F_W2BC=$*G+P8G5B91*!V'J+V4`31^V/5#"D
+MQR+50SN3^'M/?<LD&SS?*4[';L\#L_+T:H/!_M<^<SDZ&SJW?I4KB1DM13R\
+M/M?4$BPH9)+L?^US/)8CW_I5KES0-E5MTK['";,1%AQ7IS4OU'SH@8U[#;/6
+MHEZ>T@"P)@C"@RA-HC;GE:O5!-%?U>9/9C.XR=[IW51J&:.FR!_`[QLG!X4F
+M>]]F*Y%+B5(&ERHHKY@DZ-$9XM50Y0-18--TC7R&=3A0+:X]&\1>I][9H'%@
+M,C1SMGT[6W6#BTI^=0YNI'@\IL`&;F86)&-[5X&\)-3CG"!A!NI9.K5I5XL`
+MW<FC3HES,C/%7.TNB529).FX!24=6WH"6]DHIB08)GYZA]+EL<)]V*=,C$F'
+M431!A28Z+./QTDSPYGC*T@U\"KM0&`?%!OQ>3T@?C<)D2RZ;+A-7<$U"J5T2
+M2OOM7$)IYM?>CQ%IE"''?]*!AL]]UL@6XO-XQ+<[&GFZZ]5[_6$?/APND[T.
+M>C:'C+:)Y4^3F\%<0*Z`9C@I@,8&%]F:`A[K(C$<+F;`LGY9*Y,7PF3JL!%&
+MO-%-L31I;I!12"7</9$80].^W?X,GLE0S5O'NI"E@%`KK#2^O2M;Z!4RQ8P$
+M1=C=8[5!\>UI\S/';;8]M,@']/J6?M/[`_OLDO7H42?Q+$.Q!OGK#"[WMB;8
+M7>1H/:\HRSS#^VV&+;-?\VPU,O)T=^33#WOT!GDZ#=+(Y],/1CR?!36'G/R/
+MXM!"E)[<PH"+"%=9%..IQX0NG0RIK%S6D6)SL'TA/JR)%KL5^&'\I&KM\"AO
+MZP:CO^^11_W:?M]Z/4X_&?'&Q^.^6&&.G3!1V9PM*SPBQE]Q,>L<*EDRG7J:
+MQ!'Q"*5O(LT%0=2B.#DVWBNDQQ^K[O*56X^!69Z'.2V\ER@,R10?.!_-G$MK
+M[)@QHG]ZJZZ1&E)I-.2_T_7V;+M2HEH0P0#9A.H8+XEV(XQFZ&SX@PC'JSJ_
+M&A-7,RB:UPK#FV'BTG]:WY$9EP4^6G;->75Y-\4E2SI?@(&+GF[J53@4W78J
+MIX/UFN,^\?7AD1`!9`:TF6>[:@G)H[T/DS\KQ37N)!AN'!GJ0:L4AS,5TG(E
+MN8LOT%H==]"/P/6\9RN'R4/GG@>*J/7*9**66X+G/QE%.I[42:,G[MF/SIMJ
+M?C&K?(54A#?S%%/H8G+.K'-?BVYMJDZRA1&A=+NU66*LL#+N&/J8]M=U[/+E
+M."N-.*F>K\,2QZ]@%E3RDBDO8&DC!MO\R@C!0LUZ7V+4LZB4=L]!7/6DERU%
+M\*K3?+$>J/A0H'TOU,[F$:8B\9/-:J-G'[3D0<O8WTVSM^\-ZB0))MV)8LJ'
+M;4=W$/O^-7-:SP3S?$^=UF,)[9NFNKD,9E/Z\MP$=K/CYUY)=BIH.$Z%,H)O
+M=&I6!&G'O($^`8+4]/G:QO:0EXP@JT\\1_$_0H!A9(9AG%J[`%^NM3K^L-U4
+MEFK_=B-9Q:+%K,<*#B#B;U`D8_]V'1B4UMJ+;[%"#\(S6^`@S'&U<C$/0U@Y
+M1ZHN*)\DPD,Z.L3R?6;L<.V&B6H1N@(%H&B7+JC3>.*_'L^FK3>F3_!5^<W%
+MA:6C=!;1>G]##C`%S&`N%4::QL268+42FD->KR>BEJM17%&;Q`V38QMQ^*TS
+M#@(D!%O&19@%YE7B+RVS@LD>VIBW/%XI(%2$DF0(WY-:!:S2P'/J9<^SEK3<
+MWNPDII[#)&8;_C(53,L-^^<)\G##IU/9/7JE')8XMJPZVJ+,;MXYE8`Z]V[R
+M[<>X_00%V/HE:M*('#:CB\$Y$IP?7UP[4W</[7GM$P]#3`$EY3'4).46>A4=
+M]'LS%I>)XTBKE5=@O`[^&\\\@??`OT6'4E$(]KD!$<VQ-*3%7@M&Y:CYBSG8
+M3--:$WWY7K,ZT./"YN/E*A]L9MD_A,H1"$)$!SL&:WO**--O9V_:1HXJ^18Y
+MKUQBTH'ZI[GJY$EG[M1A3MR,*O-IR)7^J14J?$`GC>XY$!RAW9;Z/UX*0Z-C
+MPWA[_KCV&5AV6Y/N&*8Z\3"Y]+I1K9LY6B$".*TW>'X&"OYL_0ISAIN4A^*P
+M3)Y[&>L+8"F`DHS@ZUJKN_B?(0D-9G9D^)`.\+`YL&K`>W,5(D5+O#-?P\31
+M29>5PH\A9AD>UC*584@@,&^%GH0N*E3`"K4MU(RW'7J'_JY^;*\#[9$A+UB-
+M#/U,#TV)F1R0Y'CT`W+\2WN2J+$+9M,/SYLZ07Y8I1$>\3AU.[XNIZ<"$M7&
+M3^WVA3@7U+E[!?M+=5@&5YU2I(#W(2/-`F_RQ*Q'2\V*<;S?^E!OOQ,+9-2>
+M-1/?ZI;.[J.I_)7"(7V>FVHU/VO%$J*F'?;#(@\Q88G3=R>?Z_,S6:V`&?((
+MW-_:-(P%8'AGE3K"NS*V'_YB=@^-'E=S[FB.6X3C/CI<UR/7_B0\HFZK-3$(
+MK[_0.4WQ--ASEK<4G2W)(N(XFQ$8?-6Y>`_&=1@,OUA^Y_?/U37ZM.X#HC/D
+MR)FE[FM:.!Q'V/_^,US64F#N.L8T\%MOK7F$=5K*>V!I4B8T0EK<6C4]MBYK
+M9IGB@JDUA'5G/_QN]!49_S(6N!AE*LD*S1S\R@Y6:&RA\0%J_>TBEFPE6NR7
+M]"W];1[G/)SW,*]O-.6M_"HOQZ&&"X\6#<R`%3`I#\M+&W.MM6@2'4&E1[++
+M*R5,WD!?MB<KD$YC`V(LK_%JCVFM':*A7*@B?AY<8$3.HQ=LT[40(]SR-[D(
+MH]=+(=Y11Z)%"#-B)L!:SDXK1];(;]5LZ$MPGVH*G9]]C17J#&Y)L7IVS^KT
+M57E1@5!,A)8+++0<;&1C7[1X1^@8%SI-$T4!0)TBP3+R4ZB@A\[AT%S*UF-)
+MB1'-UNO_.#:2F(@,?Z$3?'T6BV?*0Q1E"MS;&PXAB?0,\8XAKUG$:G9P?WO0
+MI/@0!LUH=&.-$J6'.NL@=(C)"%F4(XY&CWFO=8_8&OK`B8_#+&YCFYQ!JSPX
+M>V`P;I@SP2";YW;X$SX:].M=>A('3%8*JQ-_V\X`O'3MC3-TX[2Z<1ORAM;<
+M6%]JW9A?(+X'PJ_=5"I?R>'O^X-38=7CKCV'[]LX.>AO"AJ/"$ZE36#;OK"]
+MP_]=-';,?WYDN`T=(YB_LW^/#.)A\O!;7!4HT3E9=29)KIG`&4(,F613L95+
+M[8"[F"`,*OPHGXGU6\V]8`GM_>AC<,6!&;!GW?0-O2M^R09L/;:]F;J<"OGQ
+MI[Q=U_Z07WU#<V">A]?6A(R'VSLD9KS_SL6,CWUQ])@Q<H"\`;W7CKU73<[^
+M/8KRGINJ?4U>U\;6P5[TS3]))HO.?#JQ(Y4(<"<KC1HZ=S^.:;`@)A\PK75J
+M$ZSK?9Y?7""T!`*^A&[H3R^3W8(G4$0&[@9/DI/<0Q_O<RVD/Q@;*EG$?'TY
+M0&Q-T-@&]]UUQG.+TX2_DSNH]F^A]B?O^7@>$6G"XA@FLV^[P:HT+U'PE9"Y
+MVBOC%@=](/51<B-*LN_3'8MUQ8';*@M.'L35>U]STL;J?^#\H!PA12U+R(]=
+M]GD!K><YTBJSI+5]`YW-^O^TBC]O;Q:/J+VU;4.P`=:^&K8./6SFZ`_G_DZ.
+ML6+3P0G`Z(FO.5/K'A#DS61*?UN:N\Q;1RD`O%Y:BNW!;9);BG_9S9FJFC-/
+M$6Z".?S36&*]3/PJAX\?-2=/O]39=C5H!B,4)NXY025M3*@-!JKLF?J8^FZ9
+MNEF%A.MNFCB?:0C"Y,*93.NK@HKPH%CV"'\1#V%Q729/)^P7TUG'L*.60X>B
+MNM_'9OO]IB$D5,NLJ="'9,::V8YMD%]C"_A7\B3V:];W-P>G;J!H-CSD6`Z$
+M[=P38`+(0_"O]WT._*B9?FJ/YS0UGL=Z5',>.M?>73L`2JX>5HL"-XYP1:7+
+M=-P:0Y`_*G!4@\KB;BR;H+5T](BL&UYBNE_I*)'W>^]DFEJ,VM%A*@E'X6T*
+MC$AXZ3D$&WIJ/L@<39'<1D%L1T>3&5-^;5JQUBOS4E`K(>!MRNJUZ:K7CJ8^
+M2[2O'?U@KH)D)ST)JX(Z(]"\J/U*;A1N54R'R8]O)0XVF6?Q;:@Z?DFGAI0(
+MU:H5922M<+X3B1&@CMIS-F0F]4.CV$7>/XTM)>3\;#Z+11I2`U/%*XMR,U6]
+M%O/RZ5+*<L@])PB,G/IW&O<O7!SK7_MM9JL)K_J8O`$<1YR@QOW`1AQ\,7-(
+M4LTX37KP0AH'`YGWY-]7,^4IRES%;X48KDT[>M9)ZADDV+'::EC[SC=,MP4;
+MIEMI&M;V?@UK?_^&F>DW8X01#A,G9L"S%+7I'4Y%\6EE>"D*$SICOP>S"H\0
+M,%$:OLT+?@+KKV/A_6BWCBU]S442)H.T4=G&7;M`T-NTN,!U3L6M<I-.S5C,
+MJFX<J+1DX501NUJ_*_KC06"RD7Z-!4;T\235V:R%C?.Q:/EC<'`V(4>..(+C
+MM^^UO]<2R*>^J<\VH5/:TSZH;1V!KLE'B(@A!6%?^!C9WU`D#>19A,ZBIVL3
+M:<G;WH:'+7K8'*1&Q_`0'-:4C_A<ZI<+:M7%9EL!1?*FG0-?V+[\@\J;)G&C
+MQ"]#4[L2P_=H+!;\1-?V(!3+JA#BH"+>3)MS<(OVW']FW>?-9_,5.E?FZA8*
+MQ!Y/R'"CQ*Z<=S"7CA](/M86SJ*K)OFCNR$,\\5[,,/L'E^D@A9/\=Z35=Q*
+MY70M"I&&&3\>4YW6:U%WP?P>IY"I_PV/E";ZJ\5X&MJ95E[5]7H(RU6'$M_^
+MO;Q'4(YB@+,H'Z`N3UY209'T1`0]H1H6<\^O_+$1+M;[I]W1K=6&AQ]F>798
+M33G]>@S)@+DUZ9=256OC,6#4RGTJF<4ZMD:R2>P,CQ<:D'59GX`"6"C.Q%2:
+M>D$TWE56KG73E7MO/9Z/T9UXB5D/(WQ#6@83)&D7G_=7U.U=`8?1Q32]#$ZX
+M%N,;:(=YM!LECNYWC:ZB1L,)=E3ROS8L4A7,MMBK1B8/RE#;%`&-,6L+;E-3
+M'%4_2KM4M5##KV8H5Z'V1J8]S=5Q%UQ?L%80.FIZ]%WBTHV[S(=/C+O,",'A
+MA8%BC,N*)9XAQ(L._[;`VGA+["9$LA$C#1Z>]#@K+H;DD0U9,#1**!U%+3#_
+M#OW,M1R54[.BA;%9JH<Y+P&3QS`RX"P*DWX')NI+%!A:(X#"7:9/Z`XHGT'?
+MQU6IN(A-R6_[-B\]DRN3.[J]IZYY83H1G4ZCED6#S/B!;`,6EZ\P'2<__!B5
+MX+_XXB+7)_0(FA]YNT@PH;J$#OJZ;=J4*0'6[>FT2S%=)>@[.F(>!OR.^*8)
+M^$WE@-]<.L@+C[,T'=J-T3]J.AM&.PC864W\\]L,7`T3_[S.XOG96H-8S?K"
+MHY3<\_GY<?LB3JF"TB76_'?<KLM-:\TE)2DMM"GCY<T;$R1P]O]#0.KE?24L
+MWJ7E*.V3DGR>9:8ZT&[!;-+;H7TB':P\M+TYH/]TZ*@U?<<QLI6'=L!7;89/
+M/5-S=9M<W5;_:OK:\*0+J"OQXB<0U,4\`Z3=YD83!KQ4I!D[X!#R]T\S+IYQ
+MR:HPG/83(SQ*B95SB[:FK24*`D9"V12;Q/DO'^\VHM4830GT?J/UI65:8&CI
+MRU3E>NY>ZE9TA;(:!-/CR,8HC;!6I3`[8`FVWB`IP+J8*4!D\"(/*]NM/13Q
+MVACA%]`VBTA90[J`&&GG!"N#]>G6-G`1X7_:^7\Z-@0:0+O0_"S#/\O`SRS=
+MST["BR?^<"<W0/-`P&C\]2CP.6NY4BA=KB'D6#E>B=-B)^<_%&/>,C1!?A"O
+M0"XJ&QK`>NN/I!]-+8[E'JSZ$$7OQ"'0,((X30ETZ]^^A:Q#,(+Y>_B'IFE^
+M66&8\2)HE+J,U*(I=Q10E+X(>X:;L_'6"]JX$Q=,"8[C#F^OW^%-MW0?QY*>
+M=F\W\[\LQ5;Y31H#;G"7YB"CAQ#_5K?ESRTEVX72D(6Z(1W\4_I5;91VJD1I
+M#]BY*&UVX@Z0O1^[I7M[5YUWBRF;ZM?JL-ZHC=^(WP)Q!`O:I3?;=&]:+SU*
+M!Q!0827QSM:]_<C?[U:OG]5OY"+\W<2WOD\_H,S#Z/V/+5\H+5^H6U[3$CV6
+MW(2/F>DP:I_LN.?4#?7OK][[@!/XS#>?XLB8(D4C$CJ93S(%EZ3%?,1$NCU9
+M/&%CYG;];9*6'Z'MC"O/2,;!"@R-K2*(DS%L!AH+K1N"S:P7?6AL?)^[%BP@
+M\;^.TMNJWK>U_7]Z8<?H%_+/%2QW1VVK^>6_W1@![JXHAKO,[XCQ_S-S$MCM
+M5#:%!X912H[\V;J0/#[OXG,S3'[I6H$'U-8C[9):+X0#)0\92VRNI)//(.0V
+MP\:HT$$E``EDJO39BH7:LY8<T#2@KA>!4'N<,<]C=KDPL?U,H0O<8:OA9\-\
+M9BD:S4U5E91XZ)+X(3'K1P+HA.WFZ7MZ*F7>\[`HHT0(+(2]9F-T!="(YJ'$
+MPW]'?LO$'9^WQ:@E9$B)?W-R)+K=5K:<<W!(`_J?#BU*B'((7SB.*G@1@^2J
+M\DM8-?U;&)RO+X>7Q!\/LP15_,D$:LA@6>'K?K<AILAY$J'PP\37]JD93@*D
+M<[@IMX/<A"1/]#WMH`N5W4@J4,%NP3T^]%N9'"FRA(E#?_\!=ZLDQ[F_R#"4
+MF6=9[]0QO[A&$C95#)T)>W'&F/4W3-T;U<'4+0R%KCC@Q,4%N^4$HZLFMG_#
+M#1//33/'OAB"Y;C"FD)QG13H^%)SXQ4T9Z465E-3#+X*$]?NKZ(?R$P9YT7!
+M^RJ6PC@A(CB';]Y84PQIS)SA!"42NL');4U8Y`R?#"A3H/K/KQ(4VEP[TFV6
+M]U)F7[O-RB<G27HNQ:CPT.WYISI$??,?MKH(#F[9OFR.A#\HDLDU:Y8WBD%T
+M78*"SN>%CQO)FX=,M?O\-/NUUA+/X!*71VW`7^.(Q,3FI,B/-X\\5::,VX-6
+MPGIU':R(<2]_W6IRR>O70D?$6VOF>E%)CL(D4F5XJQ[FE`,J[7X'Y:F9_@##
+M0%C/PV\]>H$GP\:MRFL<IVP9CZ)[?DLSGK!V,PDPE;2B$-*=$*4H'8_E5&S1
+MG@CP,?,A8K322E#,+&2?K,L$1YF+2\82'&Z.RZO^Z!4%.\\4.=RC"F:98C%>
+M%,3,N'AK3=#&_!`MF3*YU3#0J6LZ:99S-4\.276A$SMRM`Q$1#*7I8PSYUFP
+M_A"\8HQRZI'($]DIT\F$B05])KV%<?A^W%HP\*$C"D6KU,'*ANFW[2'42>*A
+MK29E!UVUE:12D'+3OGB$A)!.V=GTU]0.ND&8O`@ED>I`_WLBJNBGDWH*DWM$
+M!5_#KJ!YZI,?;,5*5MB&O%2@MZADUY7$K2Z2L6P!BX0:'[_KN\=ZO1+=-A1<
+M5*A!"!L%`[3);.@<2,R/6_`-R!0&??"?-8%7HEE:0!B&Y74IALS9LX-&%XFD
+M>NB_FO2?*]W5]+>R(PMYCRB$*YN6:J"^M`]#.L2\FPN3']M<T\+&R9.;AOA)
+M*WM71RV?BLS_(%XWM4T;84V;-*$0TYODPQ/";MTR.\Z*J&9R$P)PKB1T;$W5
+M)@;>K.00'A-GJ\.L15)32TXAL<KWY:<805"ACE8CFDD_@59N,ZWL\E!K+4Q\
+M_APWQ06P,"/U++8.K'KQ^X%PZ5A-MQ3:PO&%DRVF3&,SMG?UB**%&E#H\UW.
+M_@;OR7@9<2?@QH#T!/J4BSP%K=4)'_J8%&DT?.\%95,J!:6B:=9+?+W%<*06
+M^?-DY*.NCO_IOMN[8/!5NWJI7?C!N&?O'M9D:GSSS7+SNDP3;BX<]_RU5CZE
+MK$0H_>:A\4\=O;W+E8?TR*LC\V45KG%K-8\:KIBOJP\,A0IS,*UW35.;977T
+MKMZ`UPQK>00!PFGC'HY[Y>(:!J?6Z@=OF4*9!U4/:7]=I36B[F3U#_RI>DA4
+ME#5O14H*I)C,I2(!H@LF8R"8UOY@Q%G0"-J%P18O<OU80*Q2ZD=X=6NUX<S7
+M.M,MEDI<Z&S[`4O0WK<*>[\KFRMXI99%6>1>&[2'APFFQ9&U<P0FU"8.$%J;
+M;E(!ZD;N[Y:/#7-UGGS7W4&?R<OA1--TAFA)X,IAF[@9/NE0I@\I8*FX9G>+
+M!YQ]-^QO10J+!E<C8"D]LOI>-:_[><OF)&?-GLO90LK0*8:ZH!!5P'.`G5#'
+M_4@2]^T;R#.V1*SY%=9FO76(DR666[![TQ;V!`+%AFLTL6^0]>.TYARX:LB<
+M"M[7A`%\#V0UT&:!'&?%85?+XV/$5YF.NP0^ZN^V'3_$K+!APOT][CIYK=^,
+MGWB4R.D=%&K+4E8Q_T5T<2U%I&0,B,P!4<"I(:=OK-L3R!WQ9.8*[ZUT2<`=
+M@BA@%@M31S<]^Y`3"P=3.+6H;RPX.V4OL`A(6LJ9\JMC`.#IG`_HJD>;;8+_
+M1X,-WOP;7`VPO?LP2&1];")-K/%:5<L9BUWC6V4<R#DW-/X3KW?5_"Y,?O1)
+M)OSBZJ&6_CXXM."GAN>4Q9!%%X7O!IY%F%R"T`*D!O0MZ1KV<\FC2WG]Y;X6
+M\L=\SRW1$1SFGUD;K*B:NAJ7&-(/RH"4\#-T+Y0)04^H3%H*K=5==BO0^#()
+M+C9$U[SDB@7TBG[PE"1@FJL-S:\KZ!(N?^7,,48/\TPEW-JP&I04&PW2OPSC
+M*;Z,587%F4#*].E!)%;SO=[ZR]QB+J=24JS/J1MM#^?BJO//GR--ZVL?0(^K
+M1Q(N76YI3;`$VT]&RJ]DH,'E>B$LDWA1Z=GJ+@M/4'6*`Z\SD9DZW.@VL"8&
+MLHHBM#HG25Y#WVWB:^#B?Y'W&;``=S4P=!?N0FD[N&6Y^#G8/LMXLI'^XUHB
+MWU9Q1(,5)GZV%!Z*=;)X$!NW_WR=)Y3Z$*MU'/W1]R;1<@2-F\Q:F+SXM,;8
+M$$+[7IUK;?#FM-$D.SW30KJ!5,SJ\<VYL'?,_9IZ/J-"+.#'53/)4]VJ]P_K
+M(!/8##RZ2DHOJUZ;^H3/3`U'[\9S/1C.NU3CV:-\!E;V%DL)\_6QZ80Z9]8<
+MF)=R7[.,^RAM_\W3LACWPEL91X!\-.MV-8<"LAO;NQ87D`RJX8'G)&JC*.YI
+MLP^=CURCX#$ZWE/+(RV#!&Z2\[$Q<E=K).$RRP.B>&URT:Z:9LS+]].0<47C
+M^%LN)-M2B#VG=G*(,)@Q'&1.^AKU3RC$).U"_PT-,^ZCLRV/]GVN4GXWA:>9
+M\G:EFHX8!X!F#ZY6L'G%?VN6N'SAY5CY$O_&(K@]FN\KH!`KN=I4!B7W5#\"
+M`PA/RJ8#];.3P<7.GQS$[[S@`T^O/-Z;M);0I$H<N<?SV%L8T:P1+\J8OVPN
+MB+VMM!>O6+F0D?0Q6D."O*810=,S2.UCM$YK_B4&_=\9,B"-RI?48,'845!F
+M1(9FFF1H#MRY#,WI]^T@0W-X_B5PUS1-)&&\%22U%=^G,Y7BTA/)V,`%NHD"
+M.&N,=4B@U9_QM_)I9R5#74>UXBAHDRJNEE](%Z_';MF`OSG.]$%S8*YOVG3E
+M7J?]($X<:TOYR,HK2)`>IGW*HAL9D.9C2H`_IMJ%;$K7MZ)9H=_2M$T%4]N#
+MR;A-!8WI8%+O)/OQHB]@JNU+%2HU*S&E/Q7J^!B\X:C];GNGK458/>&!0]34
+MU?('I__;_R?'Y_4;JJ<]\\F5C7G&I=P9@E5B47/ZEC\/Y?,-U06_?7AE8S;5
+MC&\/GZ!SCE]0D&7MO;]K3#?C<IW;YY;D0()_CGJ_9KZ?N2BPKMA8?:4\8#U+
+M;DCMV/']Y)I_XX;-ZMOZ[:]]7C7VO)V\M=4J^][O^^AM>MI0C,@9?XG(H/B2
+M^S$KGG>%;`K/.?O]6FHWZRE2M9A8D927)&ZY``_.)J:%0&^?"`9DKU*>`77K
+ML*H)8E^U"I>3U$10UI%[Z:G$MX@FP?EYJP93(9K%-#JKM!_D4(BJ6SINWP]'
+M3M$%ABWJK8.1%^FD69HK-WGC34;D##R#7#$KA+`LM^AB]5E!4R%)P1EEA9Q/
+M'UL.Y%Q$Z`(DALD4D/Q'\;WR.R!HA'6M(CO()AS_6VZ$Q\(IBA,8E#5@H/`(
+MZ8AJPV7GD-UQ2ZJ<0@3BN'X_\>(%PB&<10)S@9W3QUIY(6#NRG@XUCI<QU(3
+M$EI(_+U`-R"WQSZAFA+RVK8V:T4^"KZ^^2\CVLW!4JED:F]M;YT&<VVO%=VF
+M#36%(UAI2!%ZG4,B'S7%1>Q40\%-BUV'Q."O;-=A\NE(#;X[N/9PL*!0.N*U
+M4+C(L\+BO#R^\R+T41H<5N+5(>\-NOZIR?/=.!,KJ8]7!&:9"C#U*$)PEMJ>
+MA*Y_?1L+K]WRI`6ZU@462-_WUC]C/+)"<ZWU*CQ_*'GH*H49%L5[W"0CA%OZ
+MD2D8X-F6QCQD,8I!O-7`8BE,Z)S4;JV@0J""OHI79<@Y]1K>*[,HO^(U1XJ,
+MQ.3<R8B@DL,J:#M8@,</L!BZLY@W?/P`B^QS%&>6P3'9DH;R46Q<S;T_/6_K
+MQL7>1T&A".DD*S,R_HN>+A*[JC;<YE$,YK*W!>%8,J0=5#7+97&E8H0G98;5
+MU`#,:QE?T#O%<VM<JR=L./\1JG+V<UDF#.6I1"S<%D])B8N#F+%7E9S8-"7@
+MWUP\)<8G(NC_.*.(X"\O22X`=Z$*E]@H>GU'/E,W#S4<N6>9<@7W?R7+*%!&
+M<F&*P"(:E"@H89;4P:K7&'YLQ9#3_D/FSL%U$L#<4P^%*6KR)U5G]L&T0"75
+M$L4:KQ=+Z/SCO]A,Q#AX?<\J:3:X9BQLOGVMX`EPCA6SRDW4!A;[&1;T(2D^
+M7N4J^?ZLD!Y2V1-U2("Q&%+F0`8!=^1(J!<)G?>^JKAU.56OCU>JF!@3#+/W
+M=R68H8[\T)(6/:IH\I'ZD#EC*03'\%Q16+1#%%I`4K(B\SR_'U9[.&YF'[MX
+M,86]YNKXL<VL8J"-,4:I?8&3T:BAA@2>XMQG855P&("2`44.[R'6`A<`L;0%
+MN)UA9`I752Z;SY9U80I!+6CRQY0O;8H5":M,9Y6Y>:Q(H77D5$D\&MQG?J*V
+M@U3)%0W,8L:4QJ0\=.\QN((`X@)!XL'5A8.3;]&N",X5(1BIL.&`<P5SI^T:
+M7J%+:*&S&K;*J9MSNE'9"L@@GU'HO+"&50&UKJ=L8##(^[=AKU$FDF849@)R
+MM`V0\&K%G/*)&]EY<$"2K#!KI_WZZ`KK$]"<SF2Y)E\PA7([8E12%;IVU)=)
+MQG!W*Y^O^UC)\2VOE%74*LLE%ZHCXT0$)16!"I,WC*<*8E_43V',3V,U0IRJ
+MOJ*)4C/1#JS1`G5SJ(IX=S^W-RZ#JE:@J5Q`)"MZD10HT_&E;*]7IMWB\^]H
+MN1)&0Z>1UX9Z"1U53V1(ZXBC>LHCTAD6Q#38NG1VZF(Y03M5.\/$*R7=5",U
+MJU5/1\IM6GD+6,V59O07B/4\D\TP"B;;RY=A4IG*8-**=?<3;Q[G,Y<9V,6-
+MA_@5Z)DJW*.>"JK3<BG>`+J6H2NP9,N>\4F2WJ+%BKG8YEYA%1=*0YH><<NA
+MLV%*3?<9EF3H0.(Z8<>X3+]"43+<9E'PW'`(46+XK>-8++B:[`@]D_C$/9EX
+MM(0,%"6.-2=+'Y60>E8F#*QO&6.+1S]<`^&!?9U_&?!/P,#21C!L@Q"JB=P?
+M1=+`BBPZCYREGXBN(_<9&,H\:=Y\ZO61:@EO3B"W)9O)8#UZR6(VQR40)MHO
+M-/"S6EV?=MUC*=$2YLF.E:DOK;,"7=C)E"YO`?<%)A:Z8(?NK>JR%0]N16OV
+ML"HI+2AHXN%G]Y)1Q@!Z3FGY*4+I09[LC%/NG`K793Q?IYTZY3P4.C=]GV*C
+MRN5120$O147#.C"-WNBKUY*&#CSYE_M;6YCNE3"Y=(LP"7.#L5Z8ST7@5<&Q
+M"']@A2-&3KH6NV/P'1NFG"5=27;IA__E!D+I@F/,19.]$ICG%%T]0A=P]L1S
+M3*[Z9R."SW!0FN#H]X]N)IG3OZ#I@61XE8Q'C#2IBDE(IW@IA<F3B7)/'T*D
+M)#<%2S!5L>2B;[Y.J2G;!9D6F)XJ\Y*XP?:1SFSX_079@G6#5UZ-B=5%MK0O
+M]!P.?DY8FVTSESSI+:'-P0("]6IPOYN^21F"K9PAX(`RC%"T-ELJ%BS,$MUI
+M%:QU2AND#AERHD?U?6`F?/NISJH378,_0`=/?86)-D3VM_06V:_S4K.K#8>>
+ME-5Y)7$IPF3[*^A5V(P^P0[*7E0@G0./-24.K55G^Z,K6-,T3'PY,T(DR@PN
+M)<)BR"#+2"0>7A6+M6<+P:B6T=4D6`Q0&RGD`6>EB3.H\.+`)Y6U)[WJ9/-K
+MRMJ,HI(5"<LSK%@K$ZL91P/1P`L&H[A$K%[=S/,][G'102M5L,RCQFW)LE]G
+M:7D2'"\YMU500:8,@K($8?*LMV2RFWRX,6YD6CVJ/`@T7Z#;8R7<B"/">=&S
+M1Y=88;=<V2U8;SH"4:E[#@L",6T'2WLM:R'W1(-6-H,<FG77C#IO<.]7B#/.
+MW:);D(.CE\>'[\U'&9V/LB*P)^7XV9NV?>CE\F@UB$,-AWZ=0R.8:6YAGN8)
+MO='VKLX>_W-N+AH6Y\*/M*AB"O/,L#V,*,N;VCH=G+8/'KV@?JEP-7G&]C4L
+M>04>5086]IF+H=?71!Y*><TM%F@O'8[+.5=W6;U\,>)82];CA$PV>?HLL@_3
+M)QB\A-I%*3*LTW=ZRZ>14#>R=MHAYZ,#6:9)X:4'/3"WR_/*B`\Y9"S\8PG,
+MJ^%FN/\*.""W11CGB_@?[<.Z+!C>\8EQJ*671I:B)P;1@E/3/%4+B;I>9/R?
+M&)25BU$X/R`GB87DZ$[R>"H^:&UM#>A!`?RU&B'2]"\<9$)%DS1I"H5A-VV;
+M<,6A?(.C/0X[>ABU..$E)!F##?N,#.W%X`#[9L:;[5W=#?TQJ[]1SR[YS)=Z
+M*RJ+QS%52B_3??(NG*+*%<IA+]E(AT/E)^O;L"-J81`B>F7"2J#IQ]9_Z.6*
+M[.C51/X<859.Y&^L[W4'`@G7[G9@(\[C<`(CE==UDWYQ6N'Z7+P#QU%3?='^
+M&CISOLLWB.^9];;'0#AAV;+J^RR&D?WK+XD:E6@2-&-13^25A?A<V5DE=LVJ
+M5):_);I<?Q\@Z5(16^4]S$",%04[/3^B9D?9,H?/4#8Y)ITEZ)GDYRZ6A2KG
+M>S]60B=<:&65":76\7!J`YE'6P?VL.&G9R(+]%5)%N&M.H_TJQ@M5]]E/9)P
+M@E]P!%0BP\4\4WPJ?#K?U;;8H7/4\2+SH$Z`L!UM/4UM1S'"@6RAOX)/7_PT
+M'O/TO&"G$3Q+C%'(O*19CC*8M#*+B+8-)I`R<HTZPW3)$!ZT<QG"*#4B0WCY
+MN[M^.[5QVQVYGVSD*.ZV6U9,_<\Q8]+IL:\]^NB5X]Y[=^/&+8\^=OF8KSZS
+M]>PQ%ST3X5<;MUW;T8Z_W_O"WVU[_(+'^/>/+;CJBHT;@VW.F,398W;#!Z;3
+MU;'IC/G'].A?^A^;-E8__^V%H_\8OC^MX^]V!M!H`6,>KOK1$]?MZ.J+QOSK
+MTL7**\>M`>=N=>_H<SN\:.SQTY[#<N.LJ#YU2[8^T]?;,J6U;4IUPH9]=W"#
+M35<ZZ3[HEQ._O?!LZI/2Y2?#@(V[)(*.N7+TCFGHZ-CVSGOO#HLD<76/13=?
+M8??$I]K#I5@U33_<49>MR1S>#1-IQ.^P/RX;\\NY.3>;K_OEPU^\9066M+_?
+M$RX:\V9UVVB/&#MY\HKZCQC1SRL7K!OU+NL/>\'5QRE9&;`J#GN?NVZZ0L_#
+M;31O__>FXD5COO+=MT;TV?#*CX[X[(^/W[OC%]_K*7_$"R_Z2K3CBRH7?&;$
+M18_`:^YH)F+(;F<F'4.;J_M-.3,VY8[Z\YCMQWP2%\XP3/OWFW?9I5=/:9W:
+M3LP(=>?7Q>=<V-8Z=>8T_$57W5\\-/66J3-:Z19KWG\6OK[N$%B/,T=]X-A#
+M;MQE2NNTF=/K/W!$#Y\P^:TIK;-&?X&Q-^WRL[99^/7[3\.=ZO;3LOT=U8-?
+MW>W_;J=/>[].GS&K8X>=/FUZ:]N_U>DSWJ_39TS9^4YO:YTR9<>=/N-_L=/)
+M6RMDJA.W_#S6[_.#`SM@;KY?AZ>^^U_M':W3=]#C%_ZQ.G-::\>LZ:-W^0\O
+MOFW6E)FM,W>^SV>UMDT;O8\^LN=N;=-:9TYOV\E.[_[J.U/A)=IVV.OM;?\+
+MO3ZD>IU2Y.!C3:4\?6W/3X=UM1,]#XV>.OI4&?/5!4%;V_36]BDS1N_Z>UZ]
+MHWWFK!FM,W:R[U]YZN/M;3L:;^Q\:%=[QZR=[/QCMK_;-FM6:_NL'<_YMO_%
+M.>]FVOO\ZH%WS8[U^Z?_,;%MRM09[]OQ)T^XMAUFZZQI.^SY]AG36MNG3MMA
+MS\^:/JUCIV?]RS,.;VN?OJ,=9>P!ITYHZX"UUC'MW^C[*5-:I^]@T[BV[PEX
+M[$YW_O^?_8MMX.EJ?PM/)?,??10S9=ON.)(E%X0JH'TVUG*LJ).XFI"IE%3(
+M9!F62,)-X/:;+AK[6CJMSQJ;-ET^YH)/C]%'$CP!73[VM1,N)7#CNX?!Z871
+M)]-%EKY34BJ8GJ/J3'@BU@K$DHNV.#WGP$/GO>/+".C123E.I#$[T+A?#BA$
+M/T<>FJO)64^I\C6"7!F0W_8NW-PQ2WWB^:3F<,`9%3Q1&Z0+Y2]5I".+PA,I
+M+CLT50L*=X0TW7XY='[U9^DO3J12:(!R`BLWKO#6S>K85#W@R#U70TO[9VSO
+M6@>;G,*!K7/7LN%5*EDD8WSN(M'[*G#D87F60GR+W%+9RTT2T!%6:N<19^]3
+M>F?EQD5+9T$G[_-Z;C62YNQGE'`HK>.7AYR;AA#%$CK/_&5[%UF>X68X:$?]
+M6-2KJB.*I0@&/7*C%'0%',DQ/F"J#=6+:S)%/)J?]S>F'2U#!_8@J3,.$30-
+MVK2DV#=SQJ;J?C^<M1J/RUBYGB5.BV\]B5$\G9/W"F'R_CTX>#0/&>93P;$5
+MOX\$;W<]C$I@=/Z50J:]=`Z4H(K<92[\/D_Z",^\;)K<<G35>>9[X#^":9\*
+MP[[[/M3:#[@9+`9K2??W5!"*V'(,=`;5350*,>26\^*?,&T@*)8@[V5<./[#
+M6_9YJ%,A>EO>0*_7CR4*TJ_5Y(<?B57A*PQ.Z)S^#8S*#Y0QETMWPX"&W*^U
+MVO#Y$SJKSNGGJD00T?IEW%*/F]$H%DX!X<'[^*<D*N'!X;L8#494N/_\&[3*
+M8<S50H&7PF(L#!)G^B+$XN2*;DH+3JVH%,+$>=^!0V:I-VB;<F1'6W,U<>4C
+MV!T*7$3+C[K>6`JFS>8H"F$+=#4S`;JP3(QB@T1*0JNU%,Q=?IQ4N]B(H15<
+M?YZX_\-YN!L5T*MZIA+IQ=[_87P%NK$*YAO=,'B=/B_7WZ+1*EA#E_\/*V+E
+MK#R',8Z2)##B[1Y2K>2R?E^`6KY"%>85F/K6(C]0TR],GO\-`C(8);9LVNI^
+M1DSA](N0<$WF*::[OGCB8EUNC^K>86+M3=`<,">N5(@3JV=*(!^K2)8.0ZB'
+M4-3/1&O7WL1<>D6[@M]#"/O%8P3;;58+LT\%0E5A\1$$5%(00Z6I#J3`F]0R
+MAXFG?\#$-)B/I](JJ1UOJ:F.+\,$:`X3+SQ+.H&PF,I5N)9FAP$X)4^]<6'.
+M]3,4/=3=!,OEP0>9X9N[2S*S_$A6&T?H"J;%5",5I3"+R>U[YHKBD.-\&8G*
+MV`C#6[%1IDI,XB9APZ9+,6%&P3P9OQ?8+#7(.;\8.KM?I?C.5:0CH#*RP"KJ
+M2QXP'8U2C@ON$8V5*9:0R@`Z9ZUJ(MBBH<2/3XI5MX6))U\;`175<>5H1-I-
+M3[]4F/C07748)>;]"NU/,6VKC>>\#!C:/($8U"OHF<V)<<+I4?PN=,9,)!(\
+M7[/Q8JTEK#!>,E0@I'@"%:"K1'8DZ(%GMQAAP370GKE7T65AXH.?P.6:"GB\
+M(S/:`0;K9*@M@!AM['JFB`3,=4?,9;/,FR^&\0GZS)9`ER['!\HR0V'BN2\@
+M)``\&!BTW3_2;4^R8C\G-M5F#]O!,>VT&<P=;@WFRL_TFLUGB5@R="ZX@C,D
+M]*)P78?9%2RN_#R!C]@?<:[Q\25F*EX&_#GQL:!UO.,*=0WLU&Q(9U<;>G?G
+M>5\I(>)")0'(X,#T!>L521GF%1ISF;CL&]PO)4_0,`((K[/D:%C5<WOCKZKG
+M.<S6;S8B<&8H<<ZE6:P$@;\C-+PJ;:"NC%1:%+/B;'.BVAW>V2\-QM&P44*W
+M[+>=G"V>N83(9C84(BNOE/LK907"/('\UMY>,]G0&!/1`B,1Y\9F-7NX]]S;
+M'MA\)922(*.`^IRWDJZH.Y#-1Q6$-Z'M1<SAA(QJ-?XR3-S]0370Q1[AG2;7
+M@(G6HT$+EH&*HS@GR3>@26+86T+G^C,H1W,*L?W"4'L%!(?`GO_2WR@I?&J%
+MV9:RB!Z!7R/LF*6*U4C%-J.LWT)E`<E=;A#W<R1V5:0!LYS/2WF]V92MO1@Z
+MNSYHI`()TH$\W(@Y`WNQ5>Q%?/^!2^S]!]XB96'Q55E.;$&JH=$)@^O7QZ9[
+M\Y#S9`-/79B6S1$3#PX&!)Y1-(O<NA0!'(RZ)4/CS.;X^_?J-:[&0*!SLOO5
+MXJP%PWVD+%SRM"ES=4%[Z#Q]'B6%S1VX9KQ@'0>46@`..$RL]`<L"BD,DQ\T
+MU1J8+(GY<.V)VO#)`9!1R[FG#2+W,6P"!81MP,K0$'C"+"QX0,D1A<E=;[`7
+M#?'.4&-Q)D5EHHE"S#+M>`.T33,\E8YF"C.JDMRMU?$__S-G,)/';E`27CHW
+M3OA&NCTTXHH?RTTM^"DRI(7)QM-L&(XV,;&=2Q*8112U@J<>AXGQQ@[!MIYJ
+M&"QLT%F8G/7G&.YL:I#G30A]/^89J(X_?Y;*[Y7[I+4EJR:?$([-0XFO?8--
+M>6)@*HY!)=^ORAFHNY#`")$V+WZHJT)6C:#_N"5:4!'-2Y`EZ)JHSUS]:43@
+M??6_F-`>%Q(#VGP-CX4WQ^D9E5MP<IJ3ETW%"3<:FDQXFC/3*"R-_B+2_6QE
+ME@4MS:HGI;AYZC'HO1J0(4T6L$BA<]FS5`B)],C5AMOVH+ZJE&C/SQ8PRPZ>
+M2H8!+R(E098,&CDA9SJ2<W8%#UOMEA0;@,:6TE:TYXU6K8LL%4)@V:M(GD&G
+MD[3L4FB,U(/,7A$FCO.*@A1T\Z9HP16P"_@C%0(<.;]>2\7.=/@AUT7#L<@5
+M#1-O[(.5+0KPY*.%XPX5)"4Y"X%RI,U!4BD*\5S"32]TQO\0'Z'$<&5WVZQV
+MM]W6$_D_*\:3D2D$E0(]W4UQPKQ@$3=G8%"<O_]N"2IG)K9\4Z`4EOI;-7%]
+M"]?O:K1/I<!*IX$P_&7Z>H/AVH;"--KZF+9V>$#)Y8O$))[C78)-6EEH:=8(
+M4D8')X9M7$+BHLFQLF\]%V&F1&L'E1F#=L%9/-L;,&@3CYL",^,(B$6E`TO[
+M_%NMQ[%!]@W^"[Y.%8-UA8C>+QIV":*`8-VHCV+7\#\&^5P,$R^_;4"\,([H
+MY^51TM(81X*`Z6TQR_SYL./T62.2HCQSHB>E&+"KSN\>T2=\<(E:&8M@-@(P
+M$TB>X>,!&QQZ?&%$^^2$,5ZCX6&+_/6CR./%@ZA.NM))]&6!N*G&E9ZAV<@[
+M5,$5]!PRFP1Q6F7G\<]8/-_8^R)KX`?K20L2/8\U!?##E6QRI2SU\S!3W]O%
+MQRV,`-`:FEPL#R6;7M4%5V"$"G!L#@8COX(<(C"7:82C8F`U'FSPB9]=7(CH
+MY!H9_*?L>:'SP>_P^NJE@`F#1Q@OI,X`T)X//8+%`7U48$X]V8_N8.Q]JR]X
+M`V4ZJ,?Y8[!BPRV3.R1^)=Z&^@*6*-?-,0^8AJ;R%DB[_=H!C`E@I4>!RM,0
+M/%IG'H/U/.HW#*9E%(BA3L#N&AQ*S+P=IJZ9H+C+]&/\!TO2,E0=A-T`Q]&2
+MAU$\,@8]<$;-%!D%%HD[P@CG,DN/#3GG'^KWP5)`!!J>9GDM*;296;#0A5<=
+M[PKK/2X6\,K[W)*]2)S[7J1.R64]Z4&41M=L]2JPQ4ZDTAB,%2*TM1VF[M=H
+M/[R)'<!4T-8^_;"@4:V8)HW85(*HN]S]H5'"H4R9D6=L%'C<+1J#9F\-VM`N
+M74)3HG.I36S!!IZW"!UG&52`6*M6@DYJX!&><_O1,`-F_L!:SU6G\U*NO_$K
+M&3I^&DYLYG40HRJ<J6+)61BJLI5<)N7,LO&)46\44NQ5:81^?\ZP35")5YAL
+MN1'F?X6$YE+"-D>UQ;#0O'.H^`M\Q*"/0(,M-[*@N=>'\N2DTQG(Z5=#?\%'
+M?O9F.EIJ^'_B_US.VTIO#LL^M$6W/!P&7:5C3H=!`.,Y>\E?$<;+9P9F+HR!
+M;4VE&/<#EY$AU+DGHL,M&WL8LV"P%O,,9[!;[]4:G&X)`P`:DJ>L0%37@S;+
+MLBQS"4')I]\+&YDS_0#VJ\`F5)@'7MZ<8/TJN"@M3653EF$,G4N?9W=>9.Z5
+MT)6<MYB>E;8K7(O?_S$1()99SX+$=&DEZ4UZJ^:B#YV!;YJ]?'B2K^<>WAPK
+M;!0$\)1B#[,RX?!.\BTU!.?4N>I8H.,KUH%BB^J'ABF?7(;P.G0`<S`IH:7G
+M?0K^KL(-4EGCD.)J*#/UXY\:L@7C8NJI<*3$`6`.H]\5,Q-ZC=24)R5>>8+A
+MY%+_CA_0J9BGI>#7*;Y=8GI*XH\UFM\P#J9:R$V%B2M6":]>'NZ(>]00?(1F
+MH!C1/A-Q<)DIL7S>'U'_@\O5.>31Y_;KK@2/I@23B[;D5U8;$7)IB8Z."=ED
+M;9#,"(9D^I3P%`;,,%!FU>ECM'-$"6$<2CA#H(03=PY*>,LY.Q#ME'Q<!^7C
+MCN4S"=:"K]MRYR7%H+3&RKYU#?:6BFGD>4N\\F&M'2=E?,'*C?#]S"F;J@?>
+M\<75`8N)Y)BAJ)8H06??+*Z$MQ]3E1#J2&!)#*!HDTKU^=A?:$/!D=M=GX0Q
+M3H*N^U!BY?^!R5-:$\&1"GIP'8Q(*I*>18;@9[_164VLO%-_A=Y$;QD)SR*%
+M]<0[,J!MS1J$S2-SL91=3@!+CK^-<RK%./=LSA,)@"1NO"=^*;VG+:]3==[^
+MU%)8$)3!4U5.ODHWVK<Z8MS1<`QO6>06UF0++9T]V"=K!JU1.'I1Y\QIFZH?
+M_F[/:N7Q8-R,U7Y4I(?$C)-[GVTZ&],4$YC]H`BC0B6E:5H^4AO1O1R-%N\P
+M*3CM3-)\$M+<T'GTYRLWR@\PS7?0/=%JHY7L8T(%,R*46$&4K9S74Q["K]%H
+M]^@P#G$#)).M<!1O*:9;=,8!@W9;A*L6W.$7_[58<]J!TX57Y-V4IQ=\%3[0
+M[+<L,Q<FKMPG%GSP)7J'8T('8#J,9TE^59')P)XX?%?>A>,MX;^S.LLBFXT$
+MAQ+Y%XG>&E<%A?ULA24CE[%RXZ)%L]HV5??[Z*=6PYTO]/`MU<C0RVZ1EQUR
+M3C^4\RN!YT></6[C[#$2:4:P8^8&)760CVJRRPV?^_4\G</A,NG$3^]FWFP\
+M!;&QA=F_!6N>P27!KZEM[=PV25>W\PVAI;\]6@72J'O25(.L>0#`A9R8`O^1
+M'1SH50ICU0`)T,YAM[08DEJS`FO"F6&B_P6VBYLU5[FT&O<YE9\GL#:>AJL/
+MRBF]1'98%9B+!QTZW_VG/;G9!^2(E/9\M>QHMLP1*ZRTYXU%1Q>)SM=0-J;L
+MO*4(;X:)]7LA96`)BZ]-E`(](VCG)7]QN>@M\&EIT"K+"8\+.NAE.Z?E#R7>
+M?3R%^W*NB,7Z48_;&ZPAX^4WAX[S6?#[H3'DFG$PK#DP]BZY]U_!WKW[<`_Y
+MSFMTMHRVT11T\>W[:1M`*]3G]<FQD#R%#7OM^"'LGZ=6,"ZD<U$MH;.D'SL=
+M_(7C;T_A11R@]E01`/=D"R7,W`P%)X5:0"T*-?+&CH:)3^^G2S14<6&MT?S%
+MJD707QXMJ4IF%FP^!_QCTFJE^8N#CRJ1SEV_XH`.E1!(U^&GJIMDU\9W$($]
+M+IOR1%+-"!:`,W7<2MP[N/\"XH^H.MYJ*Z);PS+&Y(%H#F(``#+FU]^KFT!6
+M@PI$N!9"!:1BC:["%5BP!*_^UL7+]:#;M.&A\]+S>D3QID1HD<4D-[:AGD%5
+MY-]@Y`]>:$+WO6X_G9O#Y!,G*D$^G0HBW,90P[R#_(I4%OO$`-=B5C.6\KEV
+MBCMTOCZ>CM.PI>$$(81G*67-UH;;SNNL.I<];];LU\>;\AB<4Q9SA,SVT'EV
+M;Q/WQ*EP_"+<?0ZX,8D0F[77+W6IEELVR/@V1"P^*@O'@MUA<O);6$7Y`9?P
+M1=:ZLK(&M&+%\O;R[-M4_=#-D\%*)D^]TJ(B"IU?_AVZ"$.CZ4HND!O#KR8<
+M7W.3NL_"AE/5DC)`I'%+::ZME.8:F4U=N?$SBY;B+O'AQB=6U_)D.,\_(51H
+MW"8:]/W*]9_M&T5.N(X6:TI3U.>YMMG-#25W/53)4`2#&,_`61?A;(MX`Y3@
+MC]X`851>?Y;C\MK?RJGZH=!YA([8.:03!)-(_D0)STGB6Y1<=&\.G#UW-1:J
+MMXH!8/\*Z8&S`WI/,I4)KWY1^R$$6L'9%^&*T@F)V%[=DRW[5A*KQG"L.)^M
+M&V4!95]"JD&>!S3WP`J![7WJ/^85M6B@T(>[A1&-*TW61:2\8"WG@37A"YR-
+MS^9\+!<3TAC;D)S[@F6^-"\O]A^T/5I#[ZJG+^+!/G.LUXNF355;)ZYL5?7%
+M:N?!U4*0A4<_*U$KXA?.5(B^BYC!2L2[%/$!$$:V+]L?]00F_Q9)19^UY83.
+MSQ["#:).N]!YK930BN^_Z?G5#&&;PA`V^,>\Z'@R\)N7X;+N?KQ[1/HS3-S\
+M`RD[Q;!#C#8@8MX7F!\P/^TJ7IX_D[1CS*<:7&(TDTRGR4KJ\B@IBX.!&]ZX
+M.60/B^"%#CF)`;NCX/5SQ8#X2R*W+!5U`E.A.CM,>%FYO-!9^YM84;20>-FU
+MYYV[L_@=!H!5#-,E=F&8)#I=27&#)5^&X4AC$)_IT&CJ+ODRUP:61$K6/J:2
+MN_"]=VAA>K#/^F0)U!K@?@J3KQT*O@CYN[P3I()5>!+&NL<@Y9:13%?"4_XA
+M0>/<>2O\)AB\[<N.VE1M&.\/K]9+"J4/DS.^`@^96\'F3/*UC<9]$]Z:*&AP
+M5U1N.,X0^/',Z3!#KO_G:H5UP(>$SI=^4NMX6VN'(_,E+^,RIZ]KUGN+%CV`
+M$\RAAYDS'>5CMVJM$;@&'E1U#OU8C&0E+G9K[\0XBZZ;8F2*JPU_:NB68D;!
+MG='092HDD*'(Z>`:I(.C8GQ].Y;43)R;@/E03\G8YWI08IZ+!]I@L?_YO>,9
+MR*,G>>@<="&F+['GB$N*_':R9RA-2S1DM<P+1JM4*&]XS\PBL43#NQJ,@FD!
+M5(G)SR<@W@@:=A]CDU&9L8+D'=6P4S57&_8^LZ=2#I/7S>.]2O)+F*Q0"EUJ
+M[G/.."7^7X=87GM>)(^\'5_0!-DH6\+Q`\JBV'-%LMNVX/A?F$/E!S^@""C,
+MA+QK))81VMK?9^C8`V4_X,W%$M$:T<<'#)HEYU^US,OFA!![Y<8E73BA]SWM
+M+;!KXZ\]I:ON,]A'Q=RQ`<\US/DA-FH%>MR4%X<E8_R&F!\0D.,0L`2M\AE&
+MB(?@R6;EQN6+%BW'KCSTUC>T_X`YW.0[M<0_M(AQGFRE><)0-?7BY&.AK6('
+MIMG6$U&!R4M_A(%5C(A>D96$B"Q59,3$H-]<F#$$<C9^I05F+%AP`PKY+[R'
+M@4&YVDPM([Q6;EQ8*N*!=O][E^,&??.-^OXJBH$FIEB@4_:-=ZW6Y<X:8^&,
+M_0F'B:$C93(*YPM5`7,FM8)GQFPO"8\UW%HS$SB%`[;O4.,8-@\ESPBS:<E&
+M-$?UWM9GJ@&S+@7N6</RXFPY05+%L<$"\W/I&8L+*E?([N\Z\AA52$#=2_5)
+MF-CPG/"MB&4&/^'29LX-F/`H$NBP`AD>LI9'WF`99BW-;MTZ\%D_<2%,:HK.
+MI!`X5^)0"J>[,`>YE7.0V.H6/;&4(8OIDI+[*PR)",-#2Q@+3%ACN7PN^F/[
+MSKIP-:I$&8&"Z4JP>,&6.R]AR`-%/0,3\Q1558JFA\EEWZ^)9&#&I-!;K/"+
+MP-)]\-IEO#.:^'GRLOU%8LA0@61SL"^\=(\;('&-L?HOW<-J489!M.;XK`E*
+M:>*G;0(J*7`_^AG#V6A(&MQ*N8B_8#(S/L-%>/*CZ$8MAD%PVHC"(J%;]O\+
+M@5`#J#@$"_\AQRSZ@N3N1/WH+5:(F`%IR>N0>FQ?-K_0AYV'&\(M<\MAXA0/
+M`ZE\ZA<AN^I[$Q^%3>O!U:KK$P<<1(L*[4BQ5!K4%!&T)5[G&AX^'!/&KO#-
+MR)*,&I%3M['22I?]2GOB'/>1WF3(+H+IG5<OZZPF+KM;B]QR:HB4F.AN5-!"
+M\8N'NIA95H22);?=6"PU#R6>_A(%&,"'Z,UBIIDA;80$E$P!WJO@,@U6Z-RW
+M#H\D3;ACY9D&G]%Q0O4KR!L2'*NX"D9";!P>G`X6PN$M%O.$]WCJ;XB+61>1
+MOY4.EF7A!,,.G_Y[Y<9ERU0L4-U/\22'B1D>YP0S<':U\`5X,RT]K&B(X7D_
+M6ZN06(H]F.['-&1A\J)).+5]L(-_7TGV")WL2IZ70PF_9Z])I6V9F(ODA/1T
+M`)=A_(ELG.-`>L$Z]THR3SQ>&F;X=A!>5]^$#SX<K,E1J$]P2QCENV0K_PAA
+M+[=[)`1/B!ZK^\&>:2F7VSW*YFK:4/R9N/8EPY?"IIY-]Q*<Q%@7T2+G6?*H
+M#1FQ3ZY^15&,U;+JA,E5KR)_\'0D]_HL^9JIXE9-8PGO'5%"MXA)PUC!A+J+
+MY"OA^E?^XS.5GJR[!NYYOH?,B34.!8RBF_&$#9<2UOJ%]*Z6$RS8MCT[IKZ?
+M/=B,]L#9(T-2W)^YRTI_59W7GQDF$-E5FTK8+9;,AGZFQ(*2<RZ8WMIFXA;P
+M[Q2F&M#:$F+:UMJ!+RG,25O<),VE4Y-]JXZ_8I]E<M@WAOV"B!@QDYU?M6O0
+M,";MZ;E4PB/V9HHGALFA)UMPR'@6</H(H[V$`\\A7T300L`WM`OZK3@J@D"4
+ME^^EF#>^"ZQ93'?FLFL0+3GN.[<NCD/UV%54DA2&3R?%PDOXCP59VX<@K,#2
+MNZU$?(V^-ZGJ$@XRZZW5,P[78>B,_QM[U0C@R<F6HTY;+#AK]%L9DKHJKT0T
+MN%TY13]U"-E9VH!J*0E-5NWJO1]]#*X\,'.ER%;-09HCN"W^=P_^-]T9ON\Q
+MW_;:G_?6?!ZD[&]3-?=4738L90PG7X>;+"YS\OVV=_4HM$HJ&$87,$:C1H@3
+M]KJAN3KGS91-O:$SX0_#)<4666;3FE,U+`=<3BNXSR6T'_5BC9TU(\1T7F0'
+MT`U^KYW[FW8O\1F5*\4EDKL?0X1#+%=;T3+NT$AU(T+B)1[(03L1@:>,V@,Y
+M=?;2+@9XA4].90U!1L3;[#^,'>RI>76B*A\6C1?P;"@3J()R'!MJL47@4'9&
+M6=]EQ3(LO(43##JC[)%O3EAAQE3PG%3<D;1C4DHG9BZ'$M^Z)\[B%:>4B_)!
+MA36Y;19G7B"1L3UV?.;6!YA/^X$L^!P!VA65ZN"H:C$SJ*M4U/4+73#H+4O`
+M)\'TPMG?06Y30ABR6))X_7`R(&VCLEOPD+P7;89;JM.&Y&E_00JEJ3^GKF&1
+M7N>3-[MQPCV>'[UD4G*#!G["=@L+K6#P%X^7#,S(.C$/T6^#.C:ELA5T6W.?
+M-)5?OG9I*HOR8KE!0<8C-'D];$E("\Q$3./N7=29+G-F#Z/CK2]/&&BQ#;*I
+M<0J=@5U13+@@%->XR4//S]M\?+Q:B5Z_Y*'^M#;M;ICXZ#8&)<$[]B.Y=`2_
+MH/0W$VWG%-9?H"LZ%,/SL%G=J8<5HTCETA8K1%,0#YR,((*:*>B-#^\<>N/7
+M/]T!>F/CQNK;:DNM)G%'G8<TM]!+#6=]FR9:O@B[:0I9Y89;J[M..ZN+"^ER
+M&,M[\$1"1",*&5SHK`)FP'TR!#9+G/-C0CRRRAY-1_8^UV2IT]+D3_/LB-8Q
+M%RLE#2D\E"3NO3`YT&7R;`9]JZ;K+O-7,6&?X>G[Z>[,W:_NPHW]X$\YO8:8
+M(*N,Q22(J55<^0:&84FQKR#7GT!R>Q6<.HT'XOF2@Y9*T:P.M^4AX.R<`-OL
+MS%F;J@>T_`Q#!=WW=<KMS)5ALMH]DJ\3#X:^+\%+"O)E<L4>*B07?`G<A./P
+MNZY]HXL;'R:?;5:@*8)?Q[J)J_CPG,/Q'[B!Q)(^?A;SF\N@FN@K^"V+WQC!
+M[)OLZ[)\4KD5NAQAPP^SY*_0&O<Q')R7WC65>7'LMI=6+S,!TPWBZ#1,W`/K
+MO`L80:(Z[Y4;.TUH3HG>V5U"H7]XD-P,_<8P^?`<^U2X54MJ[?J)YFYCD(BR
+M57"IHN0A8$7]:C6"@`V3+Z4E:M5@UD@V^FK6^2RHD2U(!0#Z^JKY>DPQG((\
+MBK]:0Q=U,YK[XD.RC.X'CXK1CTKC$@[0B#SWB]BDL@AER"D<;]"?S<EI_JEU
+M[)CZ!D+#TBF4$Z!2,0%4Z='7$S1/++>%K*:^NX3$$L!AC'>\)ZE,/LK"+!\Z
+M2B`C<!N"&*NS?ICX7IILH8`N85=S\QX?'\4A91H";T*9S"]N*W(C$\P*G>(U
+M:LAA5SKGTTBWFI?EZRH_2->(J,4@][&7!%C\J[^SHB(QN4ON<DV03V!%W#;T
+MR%*5?+]Z*=I`OO`&GP?PJ%K0`Q^HG*IKUM,D7_J8>-<GP!*2^_``A$[GEUA)
+M!FV.IR+HJF_Q1(`##QU[^5ODS'%7R3TX"1`FKSZ;2P!%;D9!6(5EUI;[]-FE
+M,6:$M-)"Q_V`[+^*\X`LK57FJ3H'>]U_VP`1X!;8.V'BS?4F\2'H3J$_2&6)
+M&QG/MU944D>@:)6)V.9EUZLNC'<:FOE;S\)UJZ`CJFB_I&<;=\6G#U8UQZ)!
+MI$X>;-<4[ZF<V<">G?]S*=>&6\BEH7/>]>4^KZ9\\KSK:T8;WWNSI`DW2Z/U
+MOL5M#YV.M[#YT@P>(#'#T)0]C-GCHW]!BO75O%?#1K(0B(#$(!P*I5YR*^,N
+M.WO7%)#PA!ENH9^1[03%($1\QRVL@34S"Z&11R,7?5>68<L8M:6-+[4VBSHD
+MA4#+IEA1WUAN<;<OB3F!&3#ANP24@INZI8(W&"S*YA2_"&L(8_&7"C[VD%BB
+MG[5P23J/%B:3%_H>!G/+JFJ8.U>>!8[=2P=;ZI\6>H.*-\/$W_?*"V2:IXSH
+M@J()PUEG%:?4FG*K$MXYYK2X9*SSA22Y&I5RCNIS;<'2%FOGQ\RB:A!E&,/$
+M;W&>K!`@!"F@PNK=;=-"K[A[";H*P9>T,.9Y!9C#BZ0HJ0K7P?]HT)E,CBTT
+M.8:2,Y_L*7%FF#/G=(++<A"5@!*81:^1YVVV7Q#G#ZYD+GD%(X!@DC28%CHJ
+MB2@G`SV@64.)7]VL6A:AB4!Z"P_C/%&JY*:15B""0SB<;KR(I43@'7>=O2CK
+M1V1[:O2,PL3-7U2U"1)WS$<$FMRX<=L[+7-^T0[.Y[AG#QTVHZ9(>@,^)F!)
+M)K38$K;9IQNV(U/MKVAR!'.'=0=&Y.7.8Q4$"%;'/C]RA/UT>&4GHBU6P\,/
+MVCN]M+7J[/E%^`1,J>^3SNE>YV\_UB((77++TJWG'H3%`.`6+;G&9%&71N*Q
+MPFTR%90*@!F4NV@Y^*15)WWFXL6H_=9WYO*^>57GR-LPC$N[U_3CE;6%C^]B
+MBI4UT/M<O"/W6W1&^/;)B6*&<E'%G-N,4?6%9P1PAJ6)7<HT1RLX'>D5FJ.V
+M63-G@('XX&U/RDNN).=)O:,'CD@)]N(K7[)?U.G9O-A*LW*9F:"!V&53;V>*
+MLEK^MKA037[XL>W'+B]M.?>@8M`;P*$NP&_!U^Z<+SM/34\M+VV&W^J^PBO=
+M/,RDS%!BR\E+85UP]Q$V%7L>)E@IZMQ\_R;P(ONHI@5<T\"3Z^<6"S"N<`\8
+MV@"+OI=]<FZQ'WR;/K@)=`;,94P.L>;ZDDK!"]IFS>H@@6+N&S!?L]JD;Q:V
+MALF;WX)/8%K!=O.72F<U>?,FV&/(/([.8R]M007>%SY;`\FR$$N[;C@;CBG'
+MMBYI[6H5S$BS7.JELN4B2E*\_I>ZO>F\^E/IS0EI+">%[IC;575>O:H7?XI=
+M$%`'J);`1CK].[53%&>N]"Z9']6[=+M2!+VK1J7LP6VYGY%WZ.P%-9'TV<]/
+M:^_`\_I2CPX*`<93J#QJKKBA<!.Z=^BL#U<0D@@'9\OAI*(1=$R?L;YCQLSF
+M:*Z+$8F>4A:VKN:HR_75Q3Y3-:.9*I=]&KWVZ>L[I@0\:7$4VUJ#%:CZD8&Y
+M^3D&G.1<."H3JW'#_=\@"K$Q)[UW^;9=GMH=AWNWTH9M[[Q=N@%-S1XG7';C
+M"LQKW$C,`R)"4-P\8V*QC`,>TUR2--Y*@L6OQL#SH3A9EK:&XPZ:@M:\>6C<
+MKZ^:"Q\$C*FGG$*PHC50V'J.87.B&2^F4'3U=X0E)HC5B&0MGV=BR`**&\#%
+MUI3:I>L"7(.G?[;^&KSDGS)KC@<_UN^#A<%R\G@7^7T&-FN4\WKP==</YF&J
+MX)B>4[S-./P^KIJ[%M"059VMOY_:OGYZ>W,P;_%GCFM6=X'%1N59O-S"<;]\
+M0U9<<]`V8WW;K'#<`4\?TULN]B!X"BS3M%9U99VQPU%>NFSNBJ"]C2S8+SZG
+M^GXE]#*9:=WUU<2?W\&N!]/U].[;C\4IC.L3K4EO><AI:EI<H"4:R!HE>X);
+MY'+%ZP\W<G.;!U[(>;G0>??/\]?J-"ET6NW:V6S6#ECR<9][""RYNHM8\S!Y
+MQG\OSLN^C)C&&<M)\AQF=G!<@:LM2SX!'(OI:&FQD%*Q(+@'.#CDE:&;QP;\
+MV_:[SYH2FW;.AOOYW1L^V]!9=39\QT;/!37\%?!CRW3I=[<-6)A8L]YEYH!Z
+M6%7HX^0K8+JV']LVH]Q73=S4A-UM;E5`471GP5/*+"WXQ8K!?#^8FZ*?K>15
+M8&PYC'=OELJPH(.7EZ*BOH&U"U2=36O,+H`S,/<-FH%#SLKFMFEMZ]NF36\.
+M5H`SPH46KFE&;];O+9*IH*D7+"&OL(*G#C`74V`U1G.[:CNV+3ZI!HLRJ0ZZ
+M8?NQLM>'B>^_56>[YQ;.KCIO]*C9%T$?J];(_(.)HSLY^*0RN^+CPE1*_&2_
+M8SW22J;A3RQ^HJM8L'L&@3MA\J`#P;@N)[`S0KN947!>UA=^/&7,*5:H%GBV
+M#'YQF/C-@QB^AFT>22&R%A-#U^+N:N(WP\M+E(Y*O/@',JI5YYZYS.*D5XE2
+M[[+[;NX\TW6L%YAM69;!Y]TQ?FY?EAU<#*"!42FA\U0F-^.L.X[U\L1HI?)*
+M<+UMY,+$\G?M@E;.`REN!A-F,?.8!>EW^0@^%<XHIV5)7VW9<2M@FL!#7.8M
+MXK)]TQ;]<N70^>07K74+V]2"!;PZ6ZG'.;(!;:@0J9N7:N:IY_64*L:2E`9Y
+MZ4(/VKV$,"#538)'"AO^\M\,CVFM3KCX.M:>A2VMWA:P-NNJ)_B#6M`CE^VM
+M)I<<-V$`[#D>>4+XA\Z7@V-VTY7'%71K6P,%9U)WBALCQNZ.FS5Q'A["RARI
+M:8A6PAK5#H+:P;7M]OKA:(8[-_5:W3='C*5Z\^6T_[6@?WUBQ%!-&+(79X)O
+M[9*O@>#,7CA*59V-S\-3>[!4ODB1ALL>6T%'?LMPH9A.P]?>[-QZ_R:#ZNR,
+M_J_*K@4XBOJ,A]V]``*B4ZF/6E^HD'HY<Y=WQ.J9$$)"XI$'\34C1^Y"3I*[
+M>)>0Q%2G:JVO<63=LETYRV"IBE9!JYT1!JT5.W1:6AW?]87MU.H4&;5I%2UJ
+MO^_[/_:_>Q>U[3B.F[W_[O_[?\_?]U@XW@)7TS5QJ%MV2=E01,X.7+9;NB_=
+M2G./NGOY\"1]VNZG^1SP2C('#$)"9L48M=%M7L%B>Q"HAY_R*7E0[#4JC9K@
+M^;VN:F]+IFSMP9XFUFC-?+38`$0>PTK+')`PO:VKD%7$,T`&M)^_487E$I?7
+MDLY>GLYK[\P=+G`/Q+PMU(T.PWG&G.B$=#.:8S9XT])S6'S>>678>$Q'7:%N
+M@^KAQ"8H=]7ZIJ>$CD^06(:)'3CWG;T(XTPX^&<99&#%@MS$$*$NHR2,"[JQ
+MG1B5@3,1"564,^L6#SK,$\37CZAO@WUQXF6ZDFM`LE*8$SON5RVC#)@F'3R0
+MQ<B;G#5XHX6O-E.AMH2$Y9O0*)%W_X&E89MX:5B#.?.W.#DC.6;1)XRR]`DC
+M:EX&'_^FLP]TMF;`A@`S&Y\=YBD^)*>'-TWM7^4%[!G,:[^K""\.ES74A\$S
+M/7/2"D<J@DXK@9MHQUQ&\@H;]ML5[EE[O';Z/>O7S8QB#8LS3D/]Q,ISQQ%1
+MV?RDI[DQE2[V=4BN;?2+KB4VH_UE,!DGUEHZ2AL$ZL#S\WIZ$KT"BWP"[*R-
+M92UE\\!9ZV_MA"@FS:(BEV;D&V!PPX(X.F_3./[/Y"E6UWD/?X4K3BS0LO7J
+M@[R_@RQ2R%H1AU.@X&+-:)9_0-*X:JK;<HO<3?B1**^!E5C3NZWM?\1MVV++
+MN1T(.:4%27]Z-9'$#769?X)AJAO2';V*.^?=`RF\,4%Q6!J=*0Z[CDF_72R!
+M0/S%^[].S0&=SEC,W?93/P]758/35`U.Z*"RHV'JCLH,$DV[^C(C@[`?<-HK
+MX5XER*KP45>R&1L@;)?VWM02XF.$B2)M5"R4MI8AH<&_!P7H@+87#[X@R6B/
+M(0+&_*4WG^3#K$@OX;P%1WX33IAY]#*OVCHH7"]P?Y<]QC`3GKMG/9E\4"%P
+ME/6Q-&J.=,PP3&\><+6[@#2-.QYBMAC3@F(X17L<RR^P]-&C$@*S]A881S-P
+MPU:O:<7;<%;&4$Y\FA%_GX@/$=&;DGV*#;68'O/E>>MYGO>D;Y;G_>+VK\KS
+M,L"K)48B@D$VNF>VUK4!XU82O-P$]Y(83&A%P<`Y-.:!0"+MS?\0&B:2O"+(
+MSP>NWD08`J(&"D;38,[:_)NH&;AZSLK1>'J$*BS7)QW4.R#Z\;X!,LBX3'LF
+MB[ZC7EG3%A]%]2]-*N8;;+UA^_)T7XC\?A-N@E-)9@1VTAA5K-+]K$R,H!T0
+M>\]&*P>8(H"-W']+S!/JL&#;!]TPATP@$BSWM'*Q&Q09^X[C!M;6;Z@5\:RU
+M"J63XED+592IWU!665<OMTJ6$9P/,=&FC^`;:D[$;(8<'HQ%L/<J6Y$H)6XF
+MK]N;Q68"^6]?H#:7.>(-49#<1@^!RO!2,W`3CQ[APK-!"(]M'//]3B$_5F-7
+MX]EUM6=W5H)L=!WJ24MX2&5QX_K+Y)PUU)]P[UMOJJXDNT&&)WP)(31(!1'[
+M6F[@*S;M957CK1/$IF=?\04?IEK.OA?DF_@@D2RF-DJ//\G=^+P%3R['L&2#
+M9/)N-K0NC5],+7UM?C+A(F&(RFEMS0<Z.U%[XW06Q"%MK?_T[CP:O&'0#&@@
+MFYVO\3MQM6@B@3.`RGOS-$M[,#EASXK^5W$><4\LE>D$S=FW+61,S7[<G*?!
+M`D.V]MQ-:#:06M;%5(U)\31MCYE2[:TVKR9R$4J@=S<]?3R>"X*BQUQ)T.IV
+M\+]]M*]4::_7[A&T-WZX#F)YEMSA7P'>H*2*W18I_M2^!,V!(1%5H5=L6N&/
+MP&866]LTHRG$LSPH&5'0]!8?&`)&-;:7X*EY;+:H+(2`7[/&O6=GNG7@H@!'
+M%E:R^0QJ[XW*(;;V[XTLTFXPC;E'11D@J4YF@N?_?8BDO2>]+IT9PP1131G/
+M&\(J;!0!S?OJ6$+1+P=IK4+'6WC1(AA@Q,@,$+:(BW6'[)E&+9*=@?/SG^]9
+M$1>F(H&#^OI1E!K,.9_5=',4A*)BL2=*J^WMD+NGS&*Q#[J"("V:#]MJ#97'
+MY.A?.G)0V.GX:")H!^H,CDY;Q4'&MT_C?@S#XL4[@'AO`HFQM8_W`4\4N"Q.
+MQEF;=1C#*G"*Z!8D:)\96-.X[V`QZP)NCG'@=N;F&+?]*%Q?,1FIJ`Q:'>`L
+MLJA6"`XG$5<WON"5HY*>@ZAU#\(X?()[$+.?2401^_=]E2#'NL"*Z!U]U<)A
+M5S"IURZ16CL$,O3:!\O)26J+#R`O]:]*)N3I,:5SZ/3BJ8#@KZ=+K'BU#E]-
+MA?UMXX6[BB/_(TD'J>H4.45$L(!EM6>/)5K;VA,WA:NK)L.UE44!>&;TM">N
+MC-16B1,HBA=X=#U5^W"J8[+7-BKN)DT`=JI_+@.^J)'3U]&"9MN=M2C>NA];
+M3XPYE_NF(&+3N*Y`(RR3&7)$L.H4MW'$2WE][1S5K.FK'BV&D(!SDTT)6^O3
+M=U3ZSO?8&;*U15M8>3R$?;UGM<J4D%,T3F&E2YJ]*FIJB_I$$IPL%)MF@Y3-
+MZZ=O][G3Z`1X85W6&>5@MENLP9&W>W87]8`\.`,HPKYW*8T%/J/4P(DX!A*O
+MG.]JBB8*V_I'\OH;^RC2\R$/;KCHR+"'+\:#'ULONUW)6WPMN".8C7$IL%AE
+M)#)9604:H6O=!*J]H(QK*,AQ@V@ZG?94FJ(;XE<J529&RVL;?]:.E3%]UD!R
+M/>Q^^18X@8U7#W,@ULF-K"T?BM.XO"3]N3V.[CX;;?0=F1W(&V_42/YA'T&_
+M=DE1#IK&T<)/6F(\DF:C=_$9$-*UP>Y(N!Q/&.'N"N=I\5U%(1C>-4L:U%)C
+M2S?+/S'HGVI+6%E?,7NB-QR![5_E5'!=3K5HK"B=774FRF7%-JBW&ZO(6%:-
+M#)AZYA!AX=*1YI\@L;4/#OOS!%Z[@%IGSS*FX;7M>R(U]7R)R4A=&+3_X"A3
+M##A&GN3.-A:]!(JE8GK%Q!>H4^6R(SDH$L!`CK5)6S^KN3%DP>5X&@S`I57-
+M*:4R)(19LJ0)]XRB)X#.2%JP'K8<:ZMO('=(5F/AB6!!<1Q3+B'K`NI+A+W2
+M^HMR%LLDN:P2PJ..9E-7`9&L+OP:AE6(V!;)3UZ*G58B/&^&5?8=5#NR6D(@
+MLOP"'/Z2@\WXV>(D"3=^.T64[LIH&V2H^7/4KW,5:(S0)`5K-A[:QX,(IR#^
+M=G.$0SP7?-_[G,LM*0I8W@+V;Y\9C6<QW6O"3;A=2XF8<ZP-#]U6'CGS%&.S
+M@R`\3_!$9/3'R,%XPR5)+W9-EF[?'",`!TL@0^:1+T01BSS0GL[TI]98NXI\
+M!DF!#0+/'QYP.X+=@&)NTU,,`@._;,`.O&!X@1PWF0-*39O,_A]*#03@GGQT
+M(KM+P9"]<"<VITKH+X5]</K;I^(6E19:!?YK'*1B'[-T_9G-J71"2<)X!YK9
+MVMF__TK83]MZ-^Q9I+C=HUHW86N?[J,'*OEP6_NR@]F&'!H';[;6U*L^E-E:
+M%_#A=:=U^,7V)BI(P&F8!"&8<%5-$IJZ5B>X#%3%YU>*1A$&2*>`]0XMBKJ#
+MH5`=5[Q.06=\&)5O.!QT6&E"I*IF,E+CIJF7#H*O@"AT"QLVQ*<*B3*;>SWL
+MEIQ0#@,3M5JVB5V79P$FXJ@9!SJI`.#QI*BY&2E(//N`K[R6V.9G#D<A`1S(
+MY%@LRTP+J/'R%M#*IG;LZ<L]&5]7]YYZ3!>E,'C1AL<&A2QU)?%S7!&E;SDO
+M?Q%K68M[VLJL%2.)H,7S'58!;6@<@)<R.Y;Z*`-NT)X=C>B*#*;BUBI3VW$6
+M/C+HM.%,->`DE\N`S1-!TWCL$X+GXR^C:%NJ7,\\M`/E>JV8;"32#!**Y;6L
+M#:;^VJ:XK9GWC:@8(JMXHKIL4V\\BX.Y?E?<U%Y:XN+[-$/GBZ:>-E/[HJ(5
+M^W^:$2!`9!>KG#-\0.=RI7P4HFXLM!C(N,!L!I-A$\#0'4O:X$&#R5V^R)D3
+MM%4!_(F<-][H$WIX\\C]@K_8^`V:8NM!A#@8+,(#O6\K#=.C5#'VIE@XX1GQ
+M[20$QCOGL2\0@*.#'8S@8*YU`66X`/1H75;>+B<LPQL\LDYF0VS]6WV%A14J
+M3[O'RT'L!=V1Q9&RAG"D%B*["+?QEE\#TD!#08S646">=%Y[.0V7-Q)2#Z_Q
+MZ#*6T;8$0N8?V8G#$1S6/\`RTC)KU6`&\@MCHR.L;>C%AWC)#G-]A-.$PX1*
+M%;]/+0O)ZPOO\,'"^BD[N2NW4;IRCA)<F'1#@?G4[IHAL6;ML:4\6]]]1)0Y
+M7JE!JK.%4+0`^Q$&C,`VQ8&T?+;;Q?YZVAN[RNLCY?!_/ZTC?EK?^[9*Z^33
+M,7>B9!^\Z>Y//".\7%25U8X@K*K]("4!/(;4J+,88-%3;E'"-CF;85JC2#,L
+M?:^IOSA'><W2SH7J:Q;R@YM19=_L,UZ]SOM.LR_IG$8OV,;[K_`0'?U;3PX(
+M'5U;G_\Z^KH\HE4*CZAJ#)N?,-]@K4'SF(-%BY5LF<;(7^$L4\.C@_PK8,:3
+MM\26QMKK(>!IS.!31566^/E7U4(RNLG!JS++0^FQ%:&\GGB@U^()Z$!I0U<A
+MN3"EQT?3.0EWPVRZC_[=#Q:S3LWI/`JN<RV"T2S_`F7PU&??1J!]6X]25F?Y
+M_0Q3_],"CMXR&61%!.4?%E:(K>[R5XA!5-J4M%PO@^RKZ[R)@J3`59;K.>2-
+M+P^&0361\^!$:L!YJ*T..>0U."T9UX>EZ2?,=S"-W`M@+D-P9'_,-5(?!0_G
+M>ODW%O&.+FS1'P]:2]-K*36G%!'4%CDS)3-')0.VT:>I50,S#Y>C1:2N,A;E
+M>0<CJQ5'Y%V$S%GGGH/%A>.O%&?RGQSD3!ZNYR6I(HAG9DD)[6S]Y2LINO-7
+M@/DP0!^Q@PBF=H$TQ)G9@`B^(SEFM2?'4XA*9:1M]`@_CF[T\F]>/ZV,<R^5
+M`7:&G-:0TQYR)*)]_AQ?/D@U!FKO4=GY2OZG)ZA@>+8>.F<ZH+3<K<Y`RIU;
+M^<T0/!/N='T\3_XQ>XT7P_-AHR;=X-8%`Z4"7QX_K"Y365<]6551"W%BQ^II
+M83R]8R7">*9^V58?AN=E1V_:LK*"IRU/_D9I2_W$L:]/6\JYC0*B`9_GN`,0
+MIO?:]`=*V((7?,UE45,[[H%T<@S_K@!8B>2(*&L454,A-X\)C*XO>K\XX'IY
+M9V$5K>5Z[BKD"Z;LFH^+E(]N=#%8<'.W71'%FI%T/(>%^S@3/"TS1'"8Z[DI
+M1^X':R[[L6+MRRPJ=8<7P+:"CB7A6IE+J)8C,@C3($@3FT]%#B?4`L1Y,,ZO
+MTTRW]&X>AQS<!_]"6>584(P*&4$OD9[HDMVXM,F^?."9.U5.9?@=-P+X!9$6
+M5LYW(8[QRCIJ0.,BXWG]C'E?'<_HSSV%W1+:>V.B6T+[:()W%A+*1\[2)AJ"
+MWWUG,23-U!-7R#HD](D<\H@<3W*@G3B'$[&^@)/#P,F'2O3ZT(SK[WCJQ'.(
+M7=]#9IWQSJZ_E<PO.7FJ<_<5YLZ2V?`'_"?0-S22JI^*W?_(AC^H%W,3]5,7
+M5G^Z^33UXA#<V3$R]^8&]>*:\?JI]OV_Z"CQK#E2/U6[_Y]+QDN.F*JDCW*7
+MXL5PQ=3W=D;CVTI*\0K\8_0-96NF%K=]M'I"W@D_S\*-1S_]<L>6DB/[^TOF
+MLI^O&0]'IHZZZ)<KY\BK=&MD:G[FL5OWRL?CFO531WZT+MI"_XUKSH(=Y6"!
+MBJEYIYX6W$37^%OE)N#JG(??J$B7!'!)L?_JJ=*_6%LZ2V;"A9E\V=JIP(_U
+:_"7R1KQ6_6F)?LXA;3_[W_\`7L0<'W0]`P``
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/sample3.bz2.uu b/usr/src/boot/contrib/bzip2/sample3.bz2.uu
new file mode 100644
index 0000000000..a2378a3cc1
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample3.bz2.uu
@@ -0,0 +1,9 @@
+begin 644 sample3.bz2
+M0EIH,S%!62936;K-,\D`.K;?@``00&4P```@!``_[][@,`#:VT-3`IDGZIFF
+MHT](;4T&@H]-0R`!HT`BD%'I--&)H&C32IEOWIG15$$195,\[7SNV^DXEM\G
+M0\ZRK;7W3[@]P7B>KPBU87N[XI5>!/TRY1JZE9UN&;!6ZH,60K?O=56)J;1@
+MAMLR":K)YTDE0*\.``1`$""QGH`*"(N^C.#]!@VC7I&-,2#+KPCP^J.FQY.Z
+MF8"5*83K]+=A;.A$:#-(KY':7&T/24RT:&EIR)5"L%+S'``4$1985NZ$GE_%
+*W)%.%"0NLTSR0```
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/sample3.ref.gz.uu b/usr/src/boot/contrib/bzip2/sample3.ref.gz.uu
new file mode 100644
index 0000000000..8552ba60f2
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/sample3.ref.gz.uu
@@ -0,0 +1,11 @@
+begin 644 sample3.ref.gz
+M'XL("%<.FT4"`W-A;7!L93,N<F5F`.W/08[;,`P%T+U/P>4$"`)T;M%]+Z!F
+MZ-B(8P>2@S:W'R7HNB=XBP=1$#\E_9KF%N.\9/0U_YXSO^;ULCSC]U9[<8KX
+M.<9S>_2>]>M5U);+.-0LK[Z8]V/<ERPMX^/'(?9R[8/V&.MVBUO&/I7]G3Z7
+M-5H9<WD.ET>V%G]>)_N44;/ML8WO^OV.5I[M&*7?]O%YB)9YC7O=QAZ:M[4L
+MPY3+_30,]];?UD,UHW3K%N.COO9]0#V7ML_G/OM6ZK7%O/;.?__LT<=E`@``
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+C``````````````````````````````#@/[X!M4V7,;35`0``
+`
+end
diff --git a/usr/src/boot/contrib/bzip2/spewG.c b/usr/src/boot/contrib/bzip2/spewG.c
new file mode 100644
index 0000000000..14a364938d
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/spewG.c
@@ -0,0 +1,54 @@
+
+/* spew out a thoroughly gigantic file designed so that bzip2
+ can compress it reasonably rapidly. This is to help test
+ support for large files (> 2GB) in a reasonable amount of time.
+ I suggest you use the undocumented --exponential option to
+ bzip2 when compressing the resulting file; this saves a bit of
+ time. Note: *don't* bother with --exponential when compressing
+ Real Files; it'll just waste a lot of CPU time :-)
+ (but is otherwise harmless).
+*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#define _FILE_OFFSET_BITS 64
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* The number of megabytes of junk to spew out (roughly) */
+#define MEGABYTES 5000
+
+#define N_BUF 1000000
+char buf[N_BUF];
+
+int main ( int argc, char** argv )
+{
+ int ii, kk, p;
+ srandom(1);
+ setbuffer ( stdout, buf, N_BUF );
+ for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
+ p = 25+random()%50;
+ for (ii = 0; ii < p; ii++)
+ printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
+ for (ii = 0; ii < p-1; ii++)
+ printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
+ for (ii = 0; ii < p+1; ii++)
+ printf ( "ccccccccccccccccccccccccccccccccccccc" );
+ }
+ fflush(stdout);
+ return 0;
+}
diff --git a/usr/src/boot/contrib/bzip2/unzcrash.c b/usr/src/boot/contrib/bzip2/unzcrash.c
new file mode 100644
index 0000000000..7041da51c9
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/unzcrash.c
@@ -0,0 +1,141 @@
+
+/* A test program written to test robustness to decompression of
+ corrupted data. Usage is
+ unzcrash filename
+ and the program will read the specified file, compress it (in memory),
+ and then repeatedly decompress it, each time with a different bit of
+ the compressed data inverted, so as to test all possible one-bit errors.
+ This should not cause any invalid memory accesses. If it does,
+ I want to know about it!
+
+ PS. As you can see from the above description, the process is
+ incredibly slow. A file of size eg 5KB will cause it to run for
+ many hours.
+*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include <stdio.h>
+#include <assert.h>
+#include "bzlib.h"
+
+#define M_BLOCK 1000000
+
+typedef unsigned char uchar;
+
+#define M_BLOCK_OUT (M_BLOCK + 1000000)
+uchar inbuf[M_BLOCK];
+uchar outbuf[M_BLOCK_OUT];
+uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
+
+int nIn, nOut, nZ;
+
+static char *bzerrorstrings[] = {
+ "OK"
+ ,"SEQUENCE_ERROR"
+ ,"PARAM_ERROR"
+ ,"MEM_ERROR"
+ ,"DATA_ERROR"
+ ,"DATA_ERROR_MAGIC"
+ ,"IO_ERROR"
+ ,"UNEXPECTED_EOF"
+ ,"OUTBUFF_FULL"
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+};
+
+void flip_bit ( int bit )
+{
+ int byteno = bit / 8;
+ int bitno = bit % 8;
+ uchar mask = 1 << bitno;
+ //fprintf ( stderr, "(byte %d bit %d mask %d)",
+ // byteno, bitno, (int)mask );
+ zbuf[byteno] ^= mask;
+}
+
+int main ( int argc, char** argv )
+{
+ FILE* f;
+ int r;
+ int bit;
+ int i;
+
+ if (argc != 2) {
+ fprintf ( stderr, "usage: unzcrash filename\n" );
+ return 1;
+ }
+
+ f = fopen ( argv[1], "r" );
+ if (!f) {
+ fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
+ return 1;
+ }
+
+ nIn = fread ( inbuf, 1, M_BLOCK, f );
+ fprintf ( stderr, "%d bytes read\n", nIn );
+
+ nZ = M_BLOCK;
+ r = BZ2_bzBuffToBuffCompress (
+ zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
+
+ assert (r == BZ_OK);
+ fprintf ( stderr, "%d after compression\n", nZ );
+
+ for (bit = 0; bit < nZ*8; bit++) {
+ fprintf ( stderr, "bit %d ", bit );
+ flip_bit ( bit );
+ nOut = M_BLOCK_OUT;
+ r = BZ2_bzBuffToBuffDecompress (
+ outbuf, &nOut, zbuf, nZ, 0, 0 );
+ fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] );
+
+ if (r != BZ_OK) {
+ fprintf ( stderr, "\n" );
+ } else {
+ if (nOut != nIn) {
+ fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
+ return 1;
+ } else {
+ for (i = 0; i < nOut; i++)
+ if (inbuf[i] != outbuf[i]) {
+ fprintf(stderr, "mismatch at %d\n", i );
+ return 1;
+ }
+ if (i == nOut) fprintf(stderr, "really ok!\n" );
+ }
+ }
+
+ flip_bit ( bit );
+ }
+
+#if 0
+ assert (nOut == nIn);
+ for (i = 0; i < nOut; i++) {
+ if (inbuf[i] != outbuf[i]) {
+ fprintf ( stderr, "difference at %d !\n", i );
+ return 1;
+ }
+ }
+#endif
+
+ fprintf ( stderr, "all ok\n" );
+ return 0;
+}
diff --git a/usr/src/boot/contrib/bzip2/words0 b/usr/src/boot/contrib/bzip2/words0
new file mode 100644
index 0000000000..fbf442ad6b
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/words0
@@ -0,0 +1,9 @@
+
+If compilation produces errors, or a large number of warnings,
+please read README.COMPILATION.PROBLEMS -- you might be able to
+adjust the flags in this Makefile to improve matters.
+
+Also in README.COMPILATION.PROBLEMS are some hints that may help
+if your build produces an executable which is unable to correctly
+handle so-called 'large files' -- files of size 2GB or more.
+
diff --git a/usr/src/boot/contrib/bzip2/words1 b/usr/src/boot/contrib/bzip2/words1
new file mode 100644
index 0000000000..2e83de9f08
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/words1
@@ -0,0 +1,4 @@
+
+Doing 6 tests (3 compress, 3 uncompress) ...
+If there's a problem, things might stop at this point.
+
diff --git a/usr/src/boot/contrib/bzip2/words2 b/usr/src/boot/contrib/bzip2/words2
new file mode 100644
index 0000000000..caddcf4226
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/words2
@@ -0,0 +1,5 @@
+
+Checking test results. If any of the four "cmp"s which follow
+report any differences, something is wrong. If you can't easily
+figure out what, please let me know (jseward@bzip.org).
+
diff --git a/usr/src/boot/contrib/bzip2/words3 b/usr/src/boot/contrib/bzip2/words3
new file mode 100644
index 0000000000..6972669906
--- /dev/null
+++ b/usr/src/boot/contrib/bzip2/words3
@@ -0,0 +1,30 @@
+
+If you got this far and the 'cmp's didn't complain, it looks
+like you're in business.
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
+
+ make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
+ make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+ make -n install or
+ make -n install PREFIX=/xxx/yyy respectively.
+
+The -n instructs make to show the commands it would execute, but
+not actually execute them.
+
+Instructions for use are in the preformatted manual page, in the file
+bzip2.txt. For more detailed documentation, read the full manual.
+It is available in Postscript form (manual.ps), PDF form (manual.pdf),
+and HTML form (manual.html).
+
+You can also do "bzip2 --help" to see some helpful information.
+"bzip2 -L" displays the software license.
+
diff --git a/usr/src/boot/include/_ctype.h b/usr/src/boot/include/_ctype.h
new file mode 100644
index 0000000000..8a43409e0a
--- /dev/null
+++ b/usr/src/boot/include/_ctype.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * From @(#)ctype.h 8.4 (Berkeley) 1/21/94
+ * From FreeBSD: src/include/ctype.h,v 1.27 2004/06/23 07:11:39 tjr Exp
+ * $FreeBSD$
+ */
+
+#ifndef __CTYPE_H_
+#define __CTYPE_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#define _CTYPE_A 0x00000100L /* Alpha */
+#define _CTYPE_C 0x00000200L /* Control */
+#define _CTYPE_D 0x00000400L /* Digit */
+#define _CTYPE_G 0x00000800L /* Graph */
+#define _CTYPE_L 0x00001000L /* Lower */
+#define _CTYPE_P 0x00002000L /* Punct */
+#define _CTYPE_S 0x00004000L /* Space */
+#define _CTYPE_U 0x00008000L /* Upper */
+#define _CTYPE_X 0x00010000L /* X digit */
+#define _CTYPE_B 0x00020000L /* Blank */
+#define _CTYPE_R 0x00040000L /* Print */
+#define _CTYPE_I 0x00080000L /* Ideogram */
+#define _CTYPE_T 0x00100000L /* Special */
+#define _CTYPE_Q 0x00200000L /* Phonogram */
+#define _CTYPE_N 0x00400000L /* Number (superset of digit) */
+#define _CTYPE_SW0 0x20000000L /* 0 width character */
+#define _CTYPE_SW1 0x40000000L /* 1 width character */
+#define _CTYPE_SW2 0x80000000L /* 2 width character */
+#define _CTYPE_SW3 0xc0000000L /* 3 width character */
+#define _CTYPE_SWM 0xe0000000L /* Mask for screen width data */
+#define _CTYPE_SWS 30 /* Bits to shift to get width */
+
+/* See comments in <sys/_types.h> about __ct_rune_t. */
+__BEGIN_DECLS
+unsigned long ___runetype(__ct_rune_t) __pure;
+__ct_rune_t ___tolower(__ct_rune_t) __pure;
+__ct_rune_t ___toupper(__ct_rune_t) __pure;
+__END_DECLS
+
+/*
+ * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
+ * to generate code for extern versions of all our inline functions.
+ */
+#ifdef _EXTERNALIZE_CTYPE_INLINES_
+#define _USE_CTYPE_INLINE_
+#define static
+#define __inline
+#endif
+
+extern int __mb_sb_limit;
+
+/*
+ * Use inline functions if we are allowed to and the compiler supports them.
+ */
+#if !defined(_DONT_USE_CTYPE_INLINE_) && \
+ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
+
+#include <runetype.h>
+
+static __inline int
+__maskrune(__ct_rune_t _c, unsigned long _f)
+{
+ return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) :
+ _CurrentRuneLocale->__runetype[_c]) & _f;
+}
+
+static __inline int
+__sbmaskrune(__ct_rune_t _c, unsigned long _f)
+{
+ return (_c < 0 || _c >= __mb_sb_limit) ? 0 :
+ _CurrentRuneLocale->__runetype[_c] & _f;
+}
+
+static __inline int
+__istype(__ct_rune_t _c, unsigned long _f)
+{
+ return (!!__maskrune(_c, _f));
+}
+
+static __inline int
+__sbistype(__ct_rune_t _c, unsigned long _f)
+{
+ return (!!__sbmaskrune(_c, _f));
+}
+
+static __inline int
+__isctype(__ct_rune_t _c, unsigned long _f)
+{
+ return (_c < 0 || _c >= 128) ? 0 :
+ !!(_DefaultRuneLocale.__runetype[_c] & _f);
+}
+
+static __inline __ct_rune_t
+__toupper(__ct_rune_t _c)
+{
+ return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) :
+ _CurrentRuneLocale->__mapupper[_c];
+}
+
+static __inline __ct_rune_t
+__sbtoupper(__ct_rune_t _c)
+{
+ return (_c < 0 || _c >= __mb_sb_limit) ? _c :
+ _CurrentRuneLocale->__mapupper[_c];
+}
+
+static __inline __ct_rune_t
+__tolower(__ct_rune_t _c)
+{
+ return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) :
+ _CurrentRuneLocale->__maplower[_c];
+}
+
+static __inline __ct_rune_t
+__sbtolower(__ct_rune_t _c)
+{
+ return (_c < 0 || _c >= __mb_sb_limit) ? _c :
+ _CurrentRuneLocale->__maplower[_c];
+}
+
+static __inline int
+__wcwidth(__ct_rune_t _c)
+{
+ unsigned int _x;
+
+ if (_c == 0)
+ return (0);
+ _x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R);
+ if ((_x & _CTYPE_SWM) != 0)
+ return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
+ return ((_x & _CTYPE_R) != 0 ? 1 : -1);
+}
+
+#else /* not using inlines */
+
+__BEGIN_DECLS
+int __maskrune(__ct_rune_t, unsigned long);
+int __sbmaskrune(__ct_rune_t, unsigned long);
+int __istype(__ct_rune_t, unsigned long);
+int __sbistype(__ct_rune_t, unsigned long);
+int __isctype(__ct_rune_t, unsigned long);
+__ct_rune_t __toupper(__ct_rune_t);
+__ct_rune_t __sbtoupper(__ct_rune_t);
+__ct_rune_t __tolower(__ct_rune_t);
+__ct_rune_t __sbtolower(__ct_rune_t);
+int __wcwidth(__ct_rune_t);
+__END_DECLS
+#endif /* using inlines */
+
+#endif /* !__CTYPE_H_ */
diff --git a/usr/src/boot/include/a.out.h b/usr/src/boot/include/a.out.h
new file mode 100644
index 0000000000..23f80aa79f
--- /dev/null
+++ b/usr/src/boot/include/a.out.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)a.out.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _AOUT_H_
+#define _AOUT_H_
+
+#include <sys/types.h>
+#include <machine/exec.h>
+#include <sys/endian.h>
+#include <sys/imgact_aout.h>
+#include <machine/reloc.h>
+
+#define _AOUT_INCLUDE_
+#include <nlist.h>
+
+#endif /* !_AOUT_H_ */
diff --git a/usr/src/boot/include/arpa/inet.h b/usr/src/boot/include/arpa/inet.h
new file mode 100644
index 0000000000..1078521c47
--- /dev/null
+++ b/usr/src/boot/include/arpa/inet.h
@@ -0,0 +1,178 @@
+/*
+ * ++Copyright++ 1983, 1993
+ * -
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*%
+ * @(#)inet.h 8.1 (Berkeley) 6/2/93
+ * $Id: inet.h,v 1.3 2005/04/27 04:56:16 sra Exp $
+ * $FreeBSD$
+ */
+
+#ifndef _ARPA_INET_H_
+#define _ARPA_INET_H_
+
+/* External definitions for functions in inet(3). */
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/* Required for byteorder(3) functions. */
+#include <machine/endian.h>
+
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+#ifndef _UINT16_T_DECLARED
+typedef __uint16_t uint16_t;
+#define _UINT16_T_DECLARED
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef uint32_t in_addr_t;
+#define _IN_ADDR_T_DECLARED
+#endif
+
+#ifndef _IN_PORT_T_DECLARED
+typedef uint16_t in_port_t;
+#define _IN_PORT_T_DECLARED
+#endif
+
+#if __BSD_VISIBLE
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+#endif
+
+/*
+ * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by
+ * POSIX.1-2001.
+ */
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#ifndef _STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+ in_addr_t s_addr;
+};
+#define _STRUCT_IN_ADDR_DECLARED
+#endif
+
+/* XXX all new diversions!! argh!! */
+#if __BSD_VISIBLE
+#define inet_addr __inet_addr
+#define inet_aton __inet_aton
+#define inet_lnaof __inet_lnaof
+#define inet_makeaddr __inet_makeaddr
+#define inet_neta __inet_neta
+#define inet_netof __inet_netof
+#define inet_network __inet_network
+#define inet_net_ntop __inet_net_ntop
+#define inet_net_pton __inet_net_pton
+#define inet_cidr_ntop __inet_cidr_ntop
+#define inet_cidr_pton __inet_cidr_pton
+#define inet_ntoa __inet_ntoa
+#define inet_ntoa_r __inet_ntoa_r
+#define inet_pton __inet_pton
+#define inet_ntop __inet_ntop
+#define inet_nsap_addr __inet_nsap_addr
+#define inet_nsap_ntoa __inet_nsap_ntoa
+#endif /* __BSD_VISIBLE */
+
+__BEGIN_DECLS
+#ifndef _BYTEORDER_PROTOTYPED
+#define _BYTEORDER_PROTOTYPED
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+#endif
+
+in_addr_t inet_addr(const char *);
+/*const*/ char *inet_ntoa(struct in_addr);
+const char *inet_ntop(int, const void * __restrict, char * __restrict,
+ socklen_t);
+int inet_pton(int, const char * __restrict, void * __restrict);
+
+#if __BSD_VISIBLE
+int inet_aton(const char *, struct in_addr *);
+in_addr_t inet_lnaof(struct in_addr);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+char * inet_neta(in_addr_t, char *, size_t);
+in_addr_t inet_netof(struct in_addr);
+in_addr_t inet_network(const char *);
+char *inet_net_ntop(int, const void *, int, char *, size_t);
+int inet_net_pton(int, const char *, void *, size_t);
+char *inet_ntoa_r(struct in_addr, char *buf, socklen_t size);
+char *inet_cidr_ntop(int, const void *, int, char *, size_t);
+int inet_cidr_pton(int, const char *, void *, int *);
+unsigned inet_nsap_addr(const char *, unsigned char *, int);
+char *inet_nsap_ntoa(int, const unsigned char *, char *);
+#endif /* __BSD_VISIBLE */
+__END_DECLS
+
+#ifndef _BYTEORDER_FUNC_DEFINED
+#define _BYTEORDER_FUNC_DEFINED
+#define htonl(x) __htonl(x)
+#define htons(x) __htons(x)
+#define ntohl(x) __ntohl(x)
+#define ntohs(x) __ntohs(x)
+#endif
+
+#endif /* !_ARPA_INET_H_ */
+
+/*! \file */
diff --git a/usr/src/boot/include/arpa/tftp.h b/usr/src/boot/include/arpa/tftp.h
new file mode 100644
index 0000000000..20733ec69e
--- /dev/null
+++ b/usr/src/boot/include/arpa/tftp.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)tftp.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _ARPA_TFTP_H_
+#define _ARPA_TFTP_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * Trivial File Transfer Protocol (IEN-133)
+ */
+#define SEGSIZE 512 /* data segment size */
+
+/*
+ * Packet types.
+ */
+#define RRQ 01 /* read request */
+#define WRQ 02 /* write request */
+#define DATA 03 /* data packet */
+#define ACK 04 /* acknowledgement */
+#define ERROR 05 /* error code */
+#define OACK 06 /* option acknowledgement */
+
+struct tftphdr {
+ unsigned short th_opcode; /* packet type */
+ union {
+ unsigned short tu_block; /* block # */
+ unsigned short tu_code; /* error code */
+ char tu_stuff[1]; /* request packet stuff */
+ } __packed th_u;
+ char th_data[1]; /* data or error string */
+} __packed;
+
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+
+/*
+ * Error codes.
+ */
+#define EUNDEF 0 /* not defined */
+#define ENOTFOUND 1 /* file not found */
+#define EACCESS 2 /* access violation */
+#define ENOSPACE 3 /* disk full or allocation exceeded */
+#define EBADOP 4 /* illegal TFTP operation */
+#define EBADID 5 /* unknown transfer ID */
+#define EEXISTS 6 /* file already exists */
+#define ENOUSER 7 /* no such user */
+#define EOPTNEG 8 /* option negotiation failed */
+
+#endif /* !_TFTP_H_ */
diff --git a/usr/src/boot/include/assert.h b/usr/src/boot/include/assert.h
new file mode 100644
index 0000000000..c880a782b9
--- /dev/null
+++ b/usr/src/boot/include/assert.h
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)assert.h 8.2 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * Unlike other ANSI header files, <assert.h> may usefully be included
+ * multiple times, with and without NDEBUG defined.
+ */
+
+#undef assert
+#undef _assert
+
+#ifdef NDEBUG
+#define assert(e) ((void)0)
+#define _assert(e) ((void)0)
+#else
+#define _assert(e) assert(e)
+
+#define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \
+ __LINE__, #e))
+#endif /* NDEBUG */
+
+#ifndef _ASSERT_H_
+#define _ASSERT_H_
+
+/*
+ * Static assertions. In principle we could define static_assert for
+ * C++ older than C++11, but this breaks if _Static_assert is
+ * implemented as a macro.
+ *
+ * C++ template parameters may contain commas, even if not enclosed in
+ * parentheses, causing the _Static_assert macro to be invoked with more
+ * than two parameters.
+ */
+#if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus)
+#define static_assert _Static_assert
+#endif
+
+__BEGIN_DECLS
+void __assert(const char *, const char *, int, const char *) __dead2;
+__END_DECLS
+
+#endif /* !_ASSERT_H_ */
diff --git a/usr/src/boot/include/bitstring.h b/usr/src/boot/include/bitstring.h
new file mode 100644
index 0000000000..cef9d0248d
--- /dev/null
+++ b/usr/src/boot/include/bitstring.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BITSTRING_H_
+#define _BITSTRING_H_
+
+#include <sys/bitstring.h>
+
+#endif /* _BITSTRING_H_ */
+
diff --git a/usr/src/boot/include/bzlib.h b/usr/src/boot/include/bzlib.h
new file mode 100644
index 0000000000..8277123da8
--- /dev/null
+++ b/usr/src/boot/include/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library. ---*/
+/*--- bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN 0
+#define BZ_FLUSH 1
+#define BZ_FINISH 2
+
+#define BZ_OK 0
+#define BZ_RUN_OK 1
+#define BZ_FLUSH_OK 2
+#define BZ_FINISH_OK 3
+#define BZ_STREAM_END 4
+#define BZ_SEQUENCE_ERROR (-1)
+#define BZ_PARAM_ERROR (-2)
+#define BZ_MEM_ERROR (-3)
+#define BZ_DATA_ERROR (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR (-6)
+#define BZ_UNEXPECTED_EOF (-7)
+#define BZ_OUTBUFF_FULL (-8)
+#define BZ_CONFIG_ERROR (-9)
+
+typedef
+ struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+ }
+ bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# ifdef small
+ /* windows.h define small to char */
+# undef small
+# endif
+# ifdef BZ_EXPORT
+# define BZ_API(func) WINAPI func
+# define BZ_EXTERN extern
+# else
+ /* import windows dll dynamically */
+# define BZ_API(func) (WINAPI * func)
+# define BZ_EXTERN
+# endif
+#else
+# define BZ_API(func) func
+# define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
+ bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) (
+ bz_stream* strm,
+ int action
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
+ bz_stream *strm,
+ int verbosity,
+ int small
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
+ bz_stream *strm
+ );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
+ int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
+ int* bzerror,
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
+ int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
+ int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32
+ );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity
+ );
+
+
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+ void
+ );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+ const char *path,
+ const char *mode
+ );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+ int fd,
+ const char *mode
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+ BZFILE* b
+ );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+ BZFILE *b,
+ int *errnum
+ );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/usr/src/boot/include/ctype.h b/usr/src/boot/include/ctype.h
new file mode 100644
index 0000000000..0ca422c263
--- /dev/null
+++ b/usr/src/boot/include/ctype.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ctype.h 8.4 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <_ctype.h>
+
+__BEGIN_DECLS
+int isalnum(int);
+int isalpha(int);
+int iscntrl(int);
+int isdigit(int);
+int isgraph(int);
+int islower(int);
+int isprint(int);
+int ispunct(int);
+int isspace(int);
+int isupper(int);
+int isxdigit(int);
+int tolower(int);
+int toupper(int);
+
+#if __XSI_VISIBLE
+int isascii(int);
+int toascii(int);
+#endif
+
+#if __ISO_C_VISIBLE >= 1999
+int isblank(int);
+#endif
+
+#if __BSD_VISIBLE
+int digittoint(int);
+int ishexnumber(int);
+int isideogram(int);
+int isnumber(int);
+int isphonogram(int);
+int isrune(int);
+int isspecial(int);
+#endif
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_ctype.h>
+#endif
+__END_DECLS
+
+#ifndef __cplusplus
+#define isalnum(c) __sbistype((c), _CTYPE_A|_CTYPE_D|_CTYPE_N)
+#define isalpha(c) __sbistype((c), _CTYPE_A)
+#define iscntrl(c) __sbistype((c), _CTYPE_C)
+#define isdigit(c) __sbistype((c), _CTYPE_D)
+#define isgraph(c) __sbistype((c), _CTYPE_G)
+#define islower(c) __sbistype((c), _CTYPE_L)
+#define isprint(c) __sbistype((c), _CTYPE_R)
+#define ispunct(c) __sbistype((c), _CTYPE_P)
+#define isspace(c) __sbistype((c), _CTYPE_S)
+#define isupper(c) __sbistype((c), _CTYPE_U)
+#define isxdigit(c) __sbistype((c), _CTYPE_X)
+#define tolower(c) __sbtolower(c)
+#define toupper(c) __sbtoupper(c)
+#endif /* !__cplusplus */
+
+#if __XSI_VISIBLE
+/*
+ * POSIX.1-2001 specifies _tolower() and _toupper() to be macros equivalent to
+ * tolower() and toupper() respectively, minus extra checking to ensure that
+ * the argument is a lower or uppercase letter respectively. We've chosen to
+ * implement these macros with the same error checking as tolower() and
+ * toupper() since this doesn't violate the specification itself, only its
+ * intent. We purposely leave _tolower() and _toupper() undocumented to
+ * discourage their use.
+ *
+ * XXX isascii() and toascii() should similarly be undocumented.
+ */
+#define _tolower(c) __sbtolower(c)
+#define _toupper(c) __sbtoupper(c)
+#define isascii(c) (((c) & ~0x7F) == 0)
+#define toascii(c) ((c) & 0x7F)
+#endif
+
+#if __ISO_C_VISIBLE >= 1999 && !defined(__cplusplus)
+#define isblank(c) __sbistype((c), _CTYPE_B)
+#endif
+
+#if __BSD_VISIBLE
+#define digittoint(c) __sbmaskrune((c), 0xFF)
+#define ishexnumber(c) __sbistype((c), _CTYPE_X)
+#define isideogram(c) __sbistype((c), _CTYPE_I)
+#define isnumber(c) __sbistype((c), _CTYPE_D|_CTYPE_N)
+#define isphonogram(c) __sbistype((c), _CTYPE_Q)
+#define isrune(c) __sbistype((c), 0xFFFFFF00L)
+#define isspecial(c) __sbistype((c), _CTYPE_T)
+#endif
+
+#endif /* !_CTYPE_H_ */
diff --git a/usr/src/boot/include/dev/ic/ns16550.h b/usr/src/boot/include/dev/ic/ns16550.h
new file mode 100644
index 0000000000..33a7dd14b8
--- /dev/null
+++ b/usr/src/boot/include/dev/ic/ns16550.h
@@ -0,0 +1,240 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)ns16550.h 7.1 (Berkeley) 5/9/91
+ * $FreeBSD$
+ */
+
+/*
+ * NS8250... UART registers.
+ */
+
+/* 8250 registers #[0-6]. */
+
+#define com_data 0 /* data register (R/W) */
+#define REG_DATA com_data
+
+#define com_ier 1 /* interrupt enable register (W) */
+#define REG_IER com_ier
+#define IER_ERXRDY 0x1
+#define IER_ETXRDY 0x2
+#define IER_ERLS 0x4
+#define IER_EMSC 0x8
+
+#define IER_BITS "\20\1ERXRDY\2ETXRDY\3ERLS\4EMSC"
+
+#define com_iir 2 /* interrupt identification register (R) */
+#define REG_IIR com_iir
+#define IIR_IMASK 0xf
+#define IIR_RXTOUT 0xc
+#define IIR_BUSY 0x7
+#define IIR_RLS 0x6
+#define IIR_RXRDY 0x4
+#define IIR_TXRDY 0x2
+#define IIR_NOPEND 0x1
+#define IIR_MLSC 0x0
+#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */
+
+#define IIR_BITS "\20\1NOPEND\2TXRDY\3RXRDY"
+
+#define com_lcr 3 /* line control register (R/W) */
+#define com_cfcr com_lcr /* character format control register (R/W) */
+#define REG_LCR com_lcr
+#define LCR_DLAB 0x80
+#define CFCR_DLAB LCR_DLAB
+#define LCR_EFR_ENABLE 0xbf /* magic to enable EFR on 16650 up */
+#define CFCR_EFR_ENABLE LCR_EFR_ENABLE
+#define LCR_SBREAK 0x40
+#define CFCR_SBREAK LCR_SBREAK
+#define LCR_PZERO 0x30
+#define CFCR_PZERO LCR_PZERO
+#define LCR_PONE 0x20
+#define CFCR_PONE LCR_PONE
+#define LCR_PEVEN 0x10
+#define CFCR_PEVEN LCR_PEVEN
+#define LCR_PODD 0x00
+#define CFCR_PODD LCR_PODD
+#define LCR_PENAB 0x08
+#define CFCR_PENAB LCR_PENAB
+#define LCR_STOPB 0x04
+#define CFCR_STOPB LCR_STOPB
+#define LCR_8BITS 0x03
+#define CFCR_8BITS LCR_8BITS
+#define LCR_7BITS 0x02
+#define CFCR_7BITS LCR_7BITS
+#define LCR_6BITS 0x01
+#define CFCR_6BITS LCR_6BITS
+#define LCR_5BITS 0x00
+#define CFCR_5BITS LCR_5BITS
+
+#define com_mcr 4 /* modem control register (R/W) */
+#define REG_MCR com_mcr
+#define MCR_PRESCALE 0x80 /* only available on 16650 up */
+#define MCR_LOOPBACK 0x10
+#define MCR_IE 0x08
+#define MCR_IENABLE MCR_IE
+#define MCR_DRS 0x04
+#define MCR_RTS 0x02
+#define MCR_DTR 0x01
+
+#define MCR_BITS "\20\1DTR\2RTS\3DRS\4IE\5LOOPBACK\10PRESCALE"
+
+#define com_lsr 5 /* line status register (R/W) */
+#define REG_LSR com_lsr
+#define LSR_RCV_FIFO 0x80
+#define LSR_TEMT 0x40
+#define LSR_TSRE LSR_TEMT
+#define LSR_THRE 0x20
+#define LSR_TXRDY LSR_THRE
+#define LSR_BI 0x10
+#define LSR_FE 0x08
+#define LSR_PE 0x04
+#define LSR_OE 0x02
+#define LSR_RXRDY 0x01
+#define LSR_RCV_MASK 0x1f
+
+#define LSR_BITS "\20\1RXRDY\2OE\3PE\4FE\5BI\6THRE\7TEMT\10RCV_FIFO"
+
+#define com_msr 6 /* modem status register (R/W) */
+#define REG_MSR com_msr
+#define MSR_DCD 0x80
+#define MSR_RI 0x40
+#define MSR_DSR 0x20
+#define MSR_CTS 0x10
+#define MSR_DDCD 0x08
+#define MSR_TERI 0x04
+#define MSR_DDSR 0x02
+#define MSR_DCTS 0x01
+
+#define MSR_BITS "\20\1DCTS\2DDSR\3TERI\4DDCD\5CTS\6DSR\7RI\10DCD"
+
+/* 8250 multiplexed registers #[0-1]. Access enabled by LCR[7]. */
+#define com_dll 0 /* divisor latch low (R/W) */
+#define com_dlbl com_dll
+#define com_dlm 1 /* divisor latch high (R/W) */
+#define com_dlbh com_dlm
+#define REG_DLL com_dll
+#define REG_DLH com_dlm
+
+/* 16450 register #7. Not multiplexed. */
+#define com_scr 7 /* scratch register (R/W) */
+
+/* 16550 register #2. Not multiplexed. */
+#define com_fcr 2 /* FIFO control register (W) */
+#define com_fifo com_fcr
+#define REG_FCR com_fcr
+#define FCR_ENABLE 0x01
+#define FIFO_ENABLE FCR_ENABLE
+#define FCR_RCV_RST 0x02
+#define FIFO_RCV_RST FCR_RCV_RST
+#define FCR_XMT_RST 0x04
+#define FIFO_XMT_RST FCR_XMT_RST
+#define FCR_DMA 0x08
+#define FIFO_DMA_MODE FCR_DMA
+#define FCR_RX_LOW 0x00
+#define FIFO_RX_LOW FCR_RX_LOW
+#define FCR_RX_MEDL 0x40
+#define FIFO_RX_MEDL FCR_RX_MEDL
+#define FCR_RX_MEDH 0x80
+#define FIFO_RX_MEDH FCR_RX_MEDH
+#define FCR_RX_HIGH 0xc0
+#define FIFO_RX_HIGH FCR_RX_HIGH
+
+#define FCR_BITS "\20\1ENABLE\2RCV_RST\3XMT_RST\4DMA"
+
+/* 16650 registers #2,[4-7]. Access enabled by LCR_EFR_ENABLE. */
+
+#define com_efr 2 /* enhanced features register (R/W) */
+#define REG_EFR com_efr
+#define EFR_CTS 0x80
+#define EFR_AUTOCTS EFR_CTS
+#define EFR_RTS 0x40
+#define EFR_AUTORTS EFR_RTS
+#define EFR_EFE 0x10 /* enhanced functions enable */
+
+#define com_xon1 4 /* XON 1 character (R/W) */
+#define com_xon2 5 /* XON 2 character (R/W) */
+#define com_xoff1 6 /* XOFF 1 character (R/W) */
+#define com_xoff2 7 /* XOFF 2 character (R/W) */
+
+#define DW_REG_USR 31 /* DesignWare derived Uart Status Reg */
+#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */
+#define REG_USR com_usr
+#define USR_BUSY 1 /* Uart Busy. Serial transfer in progress */
+#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */
+
+/* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */
+#define com_asr 1 /* additional status register (R[0-7]/W[0-1]) */
+
+/* 16950 register #3. R/W access enabled by ACR[7]. */
+#define com_rfl 3 /* receiver fifo level (R) */
+
+/*
+ * 16950 register #4. Access enabled by ACR[7]. Also requires
+ * !LCR_EFR_ENABLE.
+ */
+#define com_tfl 4 /* transmitter fifo level (R) */
+
+/*
+ * 16950 register #5. Accessible if !LCR_EFR_ENABLE. Read access also
+ * requires ACR[6].
+ */
+#define com_icr 5 /* index control register (R/W) */
+
+/*
+ * 16950 register #7. It is the same as com_scr except it has a different
+ * abbreviation in the manufacturer's data sheet and it also serves as an
+ * index into the Indexed Control register set.
+ */
+#define com_spr com_scr /* scratch pad (and index) register (R/W) */
+#define REG_SPR com_scr
+
+/*
+ * 16950 indexed control registers #[0-0x13]. Access is via index in SPR,
+ * data in ICR (if ICR is accessible).
+ */
+
+#define com_acr 0 /* additional control register (R/W) */
+#define ACR_ASE 0x80 /* ASR/RFL/TFL enable */
+#define ACR_ICRE 0x40 /* ICR enable */
+#define ACR_TLE 0x20 /* TTL/RTL enable */
+
+#define com_cpr 1 /* clock prescaler register (R/W) */
+#define com_tcr 2 /* times clock register (R/W) */
+#define com_ttl 4 /* transmitter trigger level (R/W) */
+#define com_rtl 5 /* receiver trigger level (R/W) */
+/* ... */
+
+/* Hardware extension mode register for RSB-2000/3000. */
+#define com_emr com_msr
+#define EMR_EXBUFF 0x04
+#define EMR_CTSFLW 0x08
+#define EMR_DSRFLW 0x10
+#define EMR_RTSFLW 0x20
+#define EMR_DTRFLW 0x40
+#define EMR_EFMODE 0x80
diff --git a/usr/src/boot/include/dev/pci/pcireg.h b/usr/src/boot/include/dev/pci/pcireg.h
new file mode 100644
index 0000000000..c48b269789
--- /dev/null
+++ b/usr/src/boot/include/dev/pci/pcireg.h
@@ -0,0 +1,945 @@
+/*-
+ * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
+ * 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 unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * PCIM_xxx: mask to locate subfield in register
+ * PCIR_xxx: config register offset
+ * PCIC_xxx: device class
+ * PCIS_xxx: device subclass
+ * PCIP_xxx: device programming interface
+ * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
+ * PCID_xxx: device ID
+ * PCIY_xxx: capability identification number
+ * PCIZ_xxx: extended capability identification number
+ */
+
+/* some PCI bus constants */
+#define PCI_DOMAINMAX 65535 /* highest supported domain number */
+#define PCI_BUSMAX 255 /* highest supported bus number */
+#define PCI_SLOTMAX 31 /* highest supported slot number */
+#define PCI_FUNCMAX 7 /* highest supported function number */
+#define PCI_REGMAX 255 /* highest supported config register addr. */
+#define PCIE_REGMAX 4095 /* highest supported config register addr. */
+#define PCI_MAXHDRTYPE 2
+
+#define PCIE_ARI_SLOTMAX 0
+#define PCIE_ARI_FUNCMAX 255
+
+#define PCI_RID_DOMAIN_SHIFT 16
+#define PCI_RID_BUS_SHIFT 8
+#define PCI_RID_SLOT_SHIFT 3
+#define PCI_RID_FUNC_SHIFT 0
+
+#define PCI_RID(bus, slot, func) \
+ ((((bus) & PCI_BUSMAX) << PCI_RID_BUS_SHIFT) | \
+ (((slot) & PCI_SLOTMAX) << PCI_RID_SLOT_SHIFT) | \
+ (((func) & PCI_FUNCMAX) << PCI_RID_FUNC_SHIFT))
+
+#define PCI_ARI_RID(bus, func) \
+ ((((bus) & PCI_BUSMAX) << PCI_RID_BUS_SHIFT) | \
+ (((func) & PCIE_ARI_FUNCMAX) << PCI_RID_FUNC_SHIFT))
+
+#define PCI_RID2BUS(rid) (((rid) >> PCI_RID_BUS_SHIFT) & PCI_BUSMAX)
+#define PCI_RID2SLOT(rid) (((rid) >> PCI_RID_SLOT_SHIFT) & PCI_SLOTMAX)
+#define PCI_RID2FUNC(rid) (((rid) >> PCI_RID_FUNC_SHIFT) & PCI_FUNCMAX)
+
+#define PCIE_ARI_RID2SLOT(rid) (0)
+#define PCIE_ARI_RID2FUNC(rid) \
+ (((rid) >> PCI_RID_FUNC_SHIFT) & PCIE_ARI_FUNCMAX)
+
+#define PCIE_ARI_SLOT(func) (((func) >> PCI_RID_SLOT_SHIFT) & PCI_SLOTMAX)
+#define PCIE_ARI_FUNC(func) (((func) >> PCI_RID_FUNC_SHIFT) & PCI_FUNCMAX)
+
+/* PCI config header registers for all devices */
+
+#define PCIR_DEVVENDOR 0x00
+#define PCIR_VENDOR 0x00
+#define PCIR_DEVICE 0x02
+#define PCIR_COMMAND 0x04
+#define PCIM_CMD_PORTEN 0x0001
+#define PCIM_CMD_MEMEN 0x0002
+#define PCIM_CMD_BUSMASTEREN 0x0004
+#define PCIM_CMD_SPECIALEN 0x0008
+#define PCIM_CMD_MWRICEN 0x0010
+#define PCIM_CMD_PERRESPEN 0x0040
+#define PCIM_CMD_SERRESPEN 0x0100
+#define PCIM_CMD_BACKTOBACK 0x0200
+#define PCIM_CMD_INTxDIS 0x0400
+#define PCIR_STATUS 0x06
+#define PCIM_STATUS_INTxSTATE 0x0008
+#define PCIM_STATUS_CAPPRESENT 0x0010
+#define PCIM_STATUS_66CAPABLE 0x0020
+#define PCIM_STATUS_BACKTOBACK 0x0080
+#define PCIM_STATUS_MDPERR 0x0100
+#define PCIM_STATUS_SEL_FAST 0x0000
+#define PCIM_STATUS_SEL_MEDIMUM 0x0200
+#define PCIM_STATUS_SEL_SLOW 0x0400
+#define PCIM_STATUS_SEL_MASK 0x0600
+#define PCIM_STATUS_STABORT 0x0800
+#define PCIM_STATUS_RTABORT 0x1000
+#define PCIM_STATUS_RMABORT 0x2000
+#define PCIM_STATUS_SERR 0x4000
+#define PCIM_STATUS_PERR 0x8000
+#define PCIR_REVID 0x08
+#define PCIR_PROGIF 0x09
+#define PCIR_SUBCLASS 0x0a
+#define PCIR_CLASS 0x0b
+#define PCIR_CACHELNSZ 0x0c
+#define PCIR_LATTIMER 0x0d
+#define PCIR_HDRTYPE 0x0e
+#define PCIM_HDRTYPE 0x7f
+#define PCIM_HDRTYPE_NORMAL 0x00
+#define PCIM_HDRTYPE_BRIDGE 0x01
+#define PCIM_HDRTYPE_CARDBUS 0x02
+#define PCIM_MFDEV 0x80
+#define PCIR_BIST 0x0f
+
+/* Capability Register Offsets */
+
+#define PCICAP_ID 0x0
+#define PCICAP_NEXTPTR 0x1
+
+/* Capability Identification Numbers */
+
+#define PCIY_PMG 0x01 /* PCI Power Management */
+#define PCIY_AGP 0x02 /* AGP */
+#define PCIY_VPD 0x03 /* Vital Product Data */
+#define PCIY_SLOTID 0x04 /* Slot Identification */
+#define PCIY_MSI 0x05 /* Message Signaled Interrupts */
+#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */
+#define PCIY_PCIX 0x07 /* PCI-X */
+#define PCIY_HT 0x08 /* HyperTransport */
+#define PCIY_VENDOR 0x09 /* Vendor Unique */
+#define PCIY_DEBUG 0x0a /* Debug port */
+#define PCIY_CRES 0x0b /* CompactPCI central resource control */
+#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */
+#define PCIY_SUBVENDOR 0x0d /* PCI-PCI bridge subvendor ID */
+#define PCIY_AGP8X 0x0e /* AGP 8x */
+#define PCIY_SECDEV 0x0f /* Secure Device */
+#define PCIY_EXPRESS 0x10 /* PCI Express */
+#define PCIY_MSIX 0x11 /* MSI-X */
+#define PCIY_SATA 0x12 /* SATA */
+#define PCIY_PCIAF 0x13 /* PCI Advanced Features */
+
+/* Extended Capability Register Fields */
+
+#define PCIR_EXTCAP 0x100
+#define PCIM_EXTCAP_ID 0x0000ffff
+#define PCIM_EXTCAP_VER 0x000f0000
+#define PCIM_EXTCAP_NEXTPTR 0xfff00000
+#define PCI_EXTCAP_ID(ecap) ((ecap) & PCIM_EXTCAP_ID)
+#define PCI_EXTCAP_VER(ecap) (((ecap) & PCIM_EXTCAP_VER) >> 16)
+#define PCI_EXTCAP_NEXTPTR(ecap) (((ecap) & PCIM_EXTCAP_NEXTPTR) >> 20)
+
+/* Extended Capability Identification Numbers */
+
+#define PCIZ_AER 0x0001 /* Advanced Error Reporting */
+#define PCIZ_VC 0x0002 /* Virtual Channel if MFVC Ext Cap not set */
+#define PCIZ_SERNUM 0x0003 /* Device Serial Number */
+#define PCIZ_PWRBDGT 0x0004 /* Power Budgeting */
+#define PCIZ_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */
+#define PCIZ_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */
+#define PCIZ_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */
+#define PCIZ_MFVC 0x0008 /* Multi-Function Virtual Channel */
+#define PCIZ_VC2 0x0009 /* Virtual Channel if MFVC Ext Cap set */
+#define PCIZ_RCRB 0x000a /* RCRB Header */
+#define PCIZ_VENDOR 0x000b /* Vendor Unique */
+#define PCIZ_CAC 0x000c /* Configuration Access Correction -- obsolete */
+#define PCIZ_ACS 0x000d /* Access Control Services */
+#define PCIZ_ARI 0x000e /* Alternative Routing-ID Interpretation */
+#define PCIZ_ATS 0x000f /* Address Translation Services */
+#define PCIZ_SRIOV 0x0010 /* Single Root IO Virtualization */
+#define PCIZ_MRIOV 0x0011 /* Multiple Root IO Virtualization */
+#define PCIZ_MULTICAST 0x0012 /* Multicast */
+#define PCIZ_PAGE_REQ 0x0013 /* Page Request */
+#define PCIZ_AMD 0x0014 /* Reserved for AMD */
+#define PCIZ_RESIZE_BAR 0x0015 /* Resizable BAR */
+#define PCIZ_DPA 0x0016 /* Dynamic Power Allocation */
+#define PCIZ_TPH_REQ 0x0017 /* TPH Requester */
+#define PCIZ_LTR 0x0018 /* Latency Tolerance Reporting */
+#define PCIZ_SEC_PCIE 0x0019 /* Secondary PCI Express */
+#define PCIZ_PMUX 0x001a /* Protocol Multiplexing */
+#define PCIZ_PASID 0x001b /* Process Address Space ID */
+#define PCIZ_LN_REQ 0x001c /* LN Requester */
+#define PCIZ_DPC 0x001d /* Downstream Porto Containment */
+#define PCIZ_L1PM 0x001e /* L1 PM Substates */
+
+/* config registers for header type 0 devices */
+
+#define PCIR_BARS 0x10
+#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
+#define PCIR_MAX_BAR_0 5
+#define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4)
+#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE)
+#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE)
+#define PCIM_BAR_SPACE 0x00000001
+#define PCIM_BAR_MEM_SPACE 0
+#define PCIM_BAR_IO_SPACE 1
+#define PCIM_BAR_MEM_TYPE 0x00000006
+#define PCIM_BAR_MEM_32 0
+#define PCIM_BAR_MEM_1MB 2 /* Locate below 1MB in PCI <= 2.1 */
+#define PCIM_BAR_MEM_64 4
+#define PCIM_BAR_MEM_PREFETCH 0x00000008
+#define PCIM_BAR_MEM_BASE 0xfffffffffffffff0ULL
+#define PCIM_BAR_IO_RESERVED 0x00000002
+#define PCIM_BAR_IO_BASE 0xfffffffc
+#define PCIR_CIS 0x28
+#define PCIM_CIS_ASI_MASK 0x00000007
+#define PCIM_CIS_ASI_CONFIG 0
+#define PCIM_CIS_ASI_BAR0 1
+#define PCIM_CIS_ASI_BAR1 2
+#define PCIM_CIS_ASI_BAR2 3
+#define PCIM_CIS_ASI_BAR3 4
+#define PCIM_CIS_ASI_BAR4 5
+#define PCIM_CIS_ASI_BAR5 6
+#define PCIM_CIS_ASI_ROM 7
+#define PCIM_CIS_ADDR_MASK 0x0ffffff8
+#define PCIM_CIS_ROM_MASK 0xf0000000
+#define PCIM_CIS_CONFIG_MASK 0xff
+#define PCIR_SUBVEND_0 0x2c
+#define PCIR_SUBDEV_0 0x2e
+#define PCIR_BIOS 0x30
+#define PCIM_BIOS_ENABLE 0x01
+#define PCIM_BIOS_ADDR_MASK 0xfffff800
+#define PCIR_CAP_PTR 0x34
+#define PCIR_INTLINE 0x3c
+#define PCIR_INTPIN 0x3d
+#define PCIR_MINGNT 0x3e
+#define PCIR_MAXLAT 0x3f
+
+/* config registers for header type 1 (PCI-to-PCI bridge) devices */
+
+#define PCIR_MAX_BAR_1 1
+#define PCIR_SECSTAT_1 0x1e
+
+#define PCIR_PRIBUS_1 0x18
+#define PCIR_SECBUS_1 0x19
+#define PCIR_SUBBUS_1 0x1a
+#define PCIR_SECLAT_1 0x1b
+
+#define PCIR_IOBASEL_1 0x1c
+#define PCIR_IOLIMITL_1 0x1d
+#define PCIR_IOBASEH_1 0x30
+#define PCIR_IOLIMITH_1 0x32
+#define PCIM_BRIO_16 0x0
+#define PCIM_BRIO_32 0x1
+#define PCIM_BRIO_MASK 0xf
+
+#define PCIR_MEMBASE_1 0x20
+#define PCIR_MEMLIMIT_1 0x22
+
+#define PCIR_PMBASEL_1 0x24
+#define PCIR_PMLIMITL_1 0x26
+#define PCIR_PMBASEH_1 0x28
+#define PCIR_PMLIMITH_1 0x2c
+#define PCIM_BRPM_32 0x0
+#define PCIM_BRPM_64 0x1
+#define PCIM_BRPM_MASK 0xf
+
+#define PCIR_BIOS_1 0x38
+#define PCIR_BRIDGECTL_1 0x3e
+
+/* config registers for header type 2 (CardBus) devices */
+
+#define PCIR_MAX_BAR_2 0
+#define PCIR_CAP_PTR_2 0x14
+#define PCIR_SECSTAT_2 0x16
+
+#define PCIR_PRIBUS_2 0x18
+#define PCIR_SECBUS_2 0x19
+#define PCIR_SUBBUS_2 0x1a
+#define PCIR_SECLAT_2 0x1b
+
+#define PCIR_MEMBASE0_2 0x1c
+#define PCIR_MEMLIMIT0_2 0x20
+#define PCIR_MEMBASE1_2 0x24
+#define PCIR_MEMLIMIT1_2 0x28
+#define PCIR_IOBASE0_2 0x2c
+#define PCIR_IOLIMIT0_2 0x30
+#define PCIR_IOBASE1_2 0x34
+#define PCIR_IOLIMIT1_2 0x38
+
+#define PCIR_BRIDGECTL_2 0x3e
+
+#define PCIR_SUBVEND_2 0x40
+#define PCIR_SUBDEV_2 0x42
+
+#define PCIR_PCCARDIF_2 0x44
+
+/* PCI device class, subclass and programming interface definitions */
+
+#define PCIC_OLD 0x00
+#define PCIS_OLD_NONVGA 0x00
+#define PCIS_OLD_VGA 0x01
+
+#define PCIC_STORAGE 0x01
+#define PCIS_STORAGE_SCSI 0x00
+#define PCIS_STORAGE_IDE 0x01
+#define PCIP_STORAGE_IDE_MODEPRIM 0x01
+#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02
+#define PCIP_STORAGE_IDE_MODESEC 0x04
+#define PCIP_STORAGE_IDE_PROGINDSEC 0x08
+#define PCIP_STORAGE_IDE_MASTERDEV 0x80
+#define PCIS_STORAGE_FLOPPY 0x02
+#define PCIS_STORAGE_IPI 0x03
+#define PCIS_STORAGE_RAID 0x04
+#define PCIS_STORAGE_ATA_ADMA 0x05
+#define PCIS_STORAGE_SATA 0x06
+#define PCIP_STORAGE_SATA_AHCI_1_0 0x01
+#define PCIS_STORAGE_SAS 0x07
+#define PCIS_STORAGE_NVM 0x08
+#define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01
+#define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02
+#define PCIS_STORAGE_OTHER 0x80
+
+#define PCIC_NETWORK 0x02
+#define PCIS_NETWORK_ETHERNET 0x00
+#define PCIS_NETWORK_TOKENRING 0x01
+#define PCIS_NETWORK_FDDI 0x02
+#define PCIS_NETWORK_ATM 0x03
+#define PCIS_NETWORK_ISDN 0x04
+#define PCIS_NETWORK_WORLDFIP 0x05
+#define PCIS_NETWORK_PICMG 0x06
+#define PCIS_NETWORK_OTHER 0x80
+
+#define PCIC_DISPLAY 0x03
+#define PCIS_DISPLAY_VGA 0x00
+#define PCIS_DISPLAY_XGA 0x01
+#define PCIS_DISPLAY_3D 0x02
+#define PCIS_DISPLAY_OTHER 0x80
+
+#define PCIC_MULTIMEDIA 0x04
+#define PCIS_MULTIMEDIA_VIDEO 0x00
+#define PCIS_MULTIMEDIA_AUDIO 0x01
+#define PCIS_MULTIMEDIA_TELE 0x02
+#define PCIS_MULTIMEDIA_HDA 0x03
+#define PCIS_MULTIMEDIA_OTHER 0x80
+
+#define PCIC_MEMORY 0x05
+#define PCIS_MEMORY_RAM 0x00
+#define PCIS_MEMORY_FLASH 0x01
+#define PCIS_MEMORY_OTHER 0x80
+
+#define PCIC_BRIDGE 0x06
+#define PCIS_BRIDGE_HOST 0x00
+#define PCIS_BRIDGE_ISA 0x01
+#define PCIS_BRIDGE_EISA 0x02
+#define PCIS_BRIDGE_MCA 0x03
+#define PCIS_BRIDGE_PCI 0x04
+#define PCIP_BRIDGE_PCI_SUBTRACTIVE 0x01
+#define PCIS_BRIDGE_PCMCIA 0x05
+#define PCIS_BRIDGE_NUBUS 0x06
+#define PCIS_BRIDGE_CARDBUS 0x07
+#define PCIS_BRIDGE_RACEWAY 0x08
+#define PCIS_BRIDGE_PCI_TRANSPARENT 0x09
+#define PCIS_BRIDGE_INFINIBAND 0x0a
+#define PCIS_BRIDGE_OTHER 0x80
+
+#define PCIC_SIMPLECOMM 0x07
+#define PCIS_SIMPLECOMM_UART 0x00
+#define PCIP_SIMPLECOMM_UART_8250 0x00
+#define PCIP_SIMPLECOMM_UART_16450A 0x01
+#define PCIP_SIMPLECOMM_UART_16550A 0x02
+#define PCIP_SIMPLECOMM_UART_16650A 0x03
+#define PCIP_SIMPLECOMM_UART_16750A 0x04
+#define PCIP_SIMPLECOMM_UART_16850A 0x05
+#define PCIP_SIMPLECOMM_UART_16950A 0x06
+#define PCIS_SIMPLECOMM_PAR 0x01
+#define PCIS_SIMPLECOMM_MULSER 0x02
+#define PCIS_SIMPLECOMM_MODEM 0x03
+#define PCIS_SIMPLECOMM_GPIB 0x04
+#define PCIS_SIMPLECOMM_SMART_CARD 0x05
+#define PCIS_SIMPLECOMM_OTHER 0x80
+
+#define PCIC_BASEPERIPH 0x08
+#define PCIS_BASEPERIPH_PIC 0x00
+#define PCIP_BASEPERIPH_PIC_8259A 0x00
+#define PCIP_BASEPERIPH_PIC_ISA 0x01
+#define PCIP_BASEPERIPH_PIC_EISA 0x02
+#define PCIP_BASEPERIPH_PIC_IO_APIC 0x10
+#define PCIP_BASEPERIPH_PIC_IOX_APIC 0x20
+#define PCIS_BASEPERIPH_DMA 0x01
+#define PCIS_BASEPERIPH_TIMER 0x02
+#define PCIS_BASEPERIPH_RTC 0x03
+#define PCIS_BASEPERIPH_PCIHOT 0x04
+#define PCIS_BASEPERIPH_SDHC 0x05
+#define PCIS_BASEPERIPH_IOMMU 0x06
+#define PCIS_BASEPERIPH_OTHER 0x80
+
+#define PCIC_INPUTDEV 0x09
+#define PCIS_INPUTDEV_KEYBOARD 0x00
+#define PCIS_INPUTDEV_DIGITIZER 0x01
+#define PCIS_INPUTDEV_MOUSE 0x02
+#define PCIS_INPUTDEV_SCANNER 0x03
+#define PCIS_INPUTDEV_GAMEPORT 0x04
+#define PCIS_INPUTDEV_OTHER 0x80
+
+#define PCIC_DOCKING 0x0a
+#define PCIS_DOCKING_GENERIC 0x00
+#define PCIS_DOCKING_OTHER 0x80
+
+#define PCIC_PROCESSOR 0x0b
+#define PCIS_PROCESSOR_386 0x00
+#define PCIS_PROCESSOR_486 0x01
+#define PCIS_PROCESSOR_PENTIUM 0x02
+#define PCIS_PROCESSOR_ALPHA 0x10
+#define PCIS_PROCESSOR_POWERPC 0x20
+#define PCIS_PROCESSOR_MIPS 0x30
+#define PCIS_PROCESSOR_COPROC 0x40
+
+#define PCIC_SERIALBUS 0x0c
+#define PCIS_SERIALBUS_FW 0x00
+#define PCIS_SERIALBUS_ACCESS 0x01
+#define PCIS_SERIALBUS_SSA 0x02
+#define PCIS_SERIALBUS_USB 0x03
+#define PCIP_SERIALBUS_USB_UHCI 0x00
+#define PCIP_SERIALBUS_USB_OHCI 0x10
+#define PCIP_SERIALBUS_USB_EHCI 0x20
+#define PCIP_SERIALBUS_USB_XHCI 0x30
+#define PCIP_SERIALBUS_USB_DEVICE 0xfe
+#define PCIS_SERIALBUS_FC 0x04
+#define PCIS_SERIALBUS_SMBUS 0x05
+#define PCIS_SERIALBUS_INFINIBAND 0x06
+#define PCIS_SERIALBUS_IPMI 0x07
+#define PCIP_SERIALBUS_IPMI_SMIC 0x00
+#define PCIP_SERIALBUS_IPMI_KCS 0x01
+#define PCIP_SERIALBUS_IPMI_BT 0x02
+#define PCIS_SERIALBUS_SERCOS 0x08
+#define PCIS_SERIALBUS_CANBUS 0x09
+
+#define PCIC_WIRELESS 0x0d
+#define PCIS_WIRELESS_IRDA 0x00
+#define PCIS_WIRELESS_IR 0x01
+#define PCIS_WIRELESS_RF 0x10
+#define PCIS_WIRELESS_BLUETOOTH 0x11
+#define PCIS_WIRELESS_BROADBAND 0x12
+#define PCIS_WIRELESS_80211A 0x20
+#define PCIS_WIRELESS_80211B 0x21
+#define PCIS_WIRELESS_OTHER 0x80
+
+#define PCIC_INTELLIIO 0x0e
+#define PCIS_INTELLIIO_I2O 0x00
+
+#define PCIC_SATCOM 0x0f
+#define PCIS_SATCOM_TV 0x01
+#define PCIS_SATCOM_AUDIO 0x02
+#define PCIS_SATCOM_VOICE 0x03
+#define PCIS_SATCOM_DATA 0x04
+
+#define PCIC_CRYPTO 0x10
+#define PCIS_CRYPTO_NETCOMP 0x00
+#define PCIS_CRYPTO_ENTERTAIN 0x10
+#define PCIS_CRYPTO_OTHER 0x80
+
+#define PCIC_DASP 0x11
+#define PCIS_DASP_DPIO 0x00
+#define PCIS_DASP_PERFCNTRS 0x01
+#define PCIS_DASP_COMM_SYNC 0x10
+#define PCIS_DASP_MGMT_CARD 0x20
+#define PCIS_DASP_OTHER 0x80
+
+#define PCIC_OTHER 0xff
+
+/* Bridge Control Values. */
+#define PCIB_BCR_PERR_ENABLE 0x0001
+#define PCIB_BCR_SERR_ENABLE 0x0002
+#define PCIB_BCR_ISA_ENABLE 0x0004
+#define PCIB_BCR_VGA_ENABLE 0x0008
+#define PCIB_BCR_MASTER_ABORT_MODE 0x0020
+#define PCIB_BCR_SECBUS_RESET 0x0040
+#define PCIB_BCR_SECBUS_BACKTOBACK 0x0080
+#define PCIB_BCR_PRI_DISCARD_TIMEOUT 0x0100
+#define PCIB_BCR_SEC_DISCARD_TIMEOUT 0x0200
+#define PCIB_BCR_DISCARD_TIMER_STATUS 0x0400
+#define PCIB_BCR_DISCARD_TIMER_SERREN 0x0800
+
+/* PCI power manangement */
+#define PCIR_POWER_CAP 0x2
+#define PCIM_PCAP_SPEC 0x0007
+#define PCIM_PCAP_PMEREQCLK 0x0008
+#define PCIM_PCAP_DEVSPECINIT 0x0020
+#define PCIM_PCAP_AUXPWR_0 0x0000
+#define PCIM_PCAP_AUXPWR_55 0x0040
+#define PCIM_PCAP_AUXPWR_100 0x0080
+#define PCIM_PCAP_AUXPWR_160 0x00c0
+#define PCIM_PCAP_AUXPWR_220 0x0100
+#define PCIM_PCAP_AUXPWR_270 0x0140
+#define PCIM_PCAP_AUXPWR_320 0x0180
+#define PCIM_PCAP_AUXPWR_375 0x01c0
+#define PCIM_PCAP_AUXPWRMASK 0x01c0
+#define PCIM_PCAP_D1SUPP 0x0200
+#define PCIM_PCAP_D2SUPP 0x0400
+#define PCIM_PCAP_D0PME 0x0800
+#define PCIM_PCAP_D1PME 0x1000
+#define PCIM_PCAP_D2PME 0x2000
+#define PCIM_PCAP_D3PME_HOT 0x4000
+#define PCIM_PCAP_D3PME_COLD 0x8000
+
+#define PCIR_POWER_STATUS 0x4
+#define PCIM_PSTAT_D0 0x0000
+#define PCIM_PSTAT_D1 0x0001
+#define PCIM_PSTAT_D2 0x0002
+#define PCIM_PSTAT_D3 0x0003
+#define PCIM_PSTAT_DMASK 0x0003
+#define PCIM_PSTAT_NOSOFTRESET 0x0008
+#define PCIM_PSTAT_PMEENABLE 0x0100
+#define PCIM_PSTAT_D0POWER 0x0000
+#define PCIM_PSTAT_D1POWER 0x0200
+#define PCIM_PSTAT_D2POWER 0x0400
+#define PCIM_PSTAT_D3POWER 0x0600
+#define PCIM_PSTAT_D0HEAT 0x0800
+#define PCIM_PSTAT_D1HEAT 0x0a00
+#define PCIM_PSTAT_D2HEAT 0x0c00
+#define PCIM_PSTAT_D3HEAT 0x0e00
+#define PCIM_PSTAT_DATASELMASK 0x1e00
+#define PCIM_PSTAT_DATAUNKN 0x0000
+#define PCIM_PSTAT_DATADIV10 0x2000
+#define PCIM_PSTAT_DATADIV100 0x4000
+#define PCIM_PSTAT_DATADIV1000 0x6000
+#define PCIM_PSTAT_DATADIVMASK 0x6000
+#define PCIM_PSTAT_PME 0x8000
+
+#define PCIR_POWER_BSE 0x6
+#define PCIM_PMCSR_BSE_D3B3 0x00
+#define PCIM_PMCSR_BSE_D3B2 0x40
+#define PCIM_PMCSR_BSE_BPCCE 0x80
+
+#define PCIR_POWER_DATA 0x7
+
+/* VPD capability registers */
+#define PCIR_VPD_ADDR 0x2
+#define PCIR_VPD_DATA 0x4
+
+/* PCI Message Signalled Interrupts (MSI) */
+#define PCIR_MSI_CTRL 0x2
+#define PCIM_MSICTRL_VECTOR 0x0100
+#define PCIM_MSICTRL_64BIT 0x0080
+#define PCIM_MSICTRL_MME_MASK 0x0070
+#define PCIM_MSICTRL_MME_1 0x0000
+#define PCIM_MSICTRL_MME_2 0x0010
+#define PCIM_MSICTRL_MME_4 0x0020
+#define PCIM_MSICTRL_MME_8 0x0030
+#define PCIM_MSICTRL_MME_16 0x0040
+#define PCIM_MSICTRL_MME_32 0x0050
+#define PCIM_MSICTRL_MMC_MASK 0x000E
+#define PCIM_MSICTRL_MMC_1 0x0000
+#define PCIM_MSICTRL_MMC_2 0x0002
+#define PCIM_MSICTRL_MMC_4 0x0004
+#define PCIM_MSICTRL_MMC_8 0x0006
+#define PCIM_MSICTRL_MMC_16 0x0008
+#define PCIM_MSICTRL_MMC_32 0x000A
+#define PCIM_MSICTRL_MSI_ENABLE 0x0001
+#define PCIR_MSI_ADDR 0x4
+#define PCIR_MSI_ADDR_HIGH 0x8
+#define PCIR_MSI_DATA 0x8
+#define PCIR_MSI_DATA_64BIT 0xc
+#define PCIR_MSI_MASK 0x10
+#define PCIR_MSI_PENDING 0x14
+
+/* PCI-X definitions */
+
+/* For header type 0 devices */
+#define PCIXR_COMMAND 0x2
+#define PCIXM_COMMAND_DPERR_E 0x0001 /* Data Parity Error Recovery */
+#define PCIXM_COMMAND_ERO 0x0002 /* Enable Relaxed Ordering */
+#define PCIXM_COMMAND_MAX_READ 0x000c /* Maximum Burst Read Count */
+#define PCIXM_COMMAND_MAX_READ_512 0x0000
+#define PCIXM_COMMAND_MAX_READ_1024 0x0004
+#define PCIXM_COMMAND_MAX_READ_2048 0x0008
+#define PCIXM_COMMAND_MAX_READ_4096 0x000c
+#define PCIXM_COMMAND_MAX_SPLITS 0x0070 /* Maximum Split Transactions */
+#define PCIXM_COMMAND_MAX_SPLITS_1 0x0000
+#define PCIXM_COMMAND_MAX_SPLITS_2 0x0010
+#define PCIXM_COMMAND_MAX_SPLITS_3 0x0020
+#define PCIXM_COMMAND_MAX_SPLITS_4 0x0030
+#define PCIXM_COMMAND_MAX_SPLITS_8 0x0040
+#define PCIXM_COMMAND_MAX_SPLITS_12 0x0050
+#define PCIXM_COMMAND_MAX_SPLITS_16 0x0060
+#define PCIXM_COMMAND_MAX_SPLITS_32 0x0070
+#define PCIXM_COMMAND_VERSION 0x3000
+#define PCIXR_STATUS 0x4
+#define PCIXM_STATUS_DEVFN 0x000000FF
+#define PCIXM_STATUS_BUS 0x0000FF00
+#define PCIXM_STATUS_64BIT 0x00010000
+#define PCIXM_STATUS_133CAP 0x00020000
+#define PCIXM_STATUS_SC_DISCARDED 0x00040000
+#define PCIXM_STATUS_UNEXP_SC 0x00080000
+#define PCIXM_STATUS_COMPLEX_DEV 0x00100000
+#define PCIXM_STATUS_MAX_READ 0x00600000
+#define PCIXM_STATUS_MAX_READ_512 0x00000000
+#define PCIXM_STATUS_MAX_READ_1024 0x00200000
+#define PCIXM_STATUS_MAX_READ_2048 0x00400000
+#define PCIXM_STATUS_MAX_READ_4096 0x00600000
+#define PCIXM_STATUS_MAX_SPLITS 0x03800000
+#define PCIXM_STATUS_MAX_SPLITS_1 0x00000000
+#define PCIXM_STATUS_MAX_SPLITS_2 0x00800000
+#define PCIXM_STATUS_MAX_SPLITS_3 0x01000000
+#define PCIXM_STATUS_MAX_SPLITS_4 0x01800000
+#define PCIXM_STATUS_MAX_SPLITS_8 0x02000000
+#define PCIXM_STATUS_MAX_SPLITS_12 0x02800000
+#define PCIXM_STATUS_MAX_SPLITS_16 0x03000000
+#define PCIXM_STATUS_MAX_SPLITS_32 0x03800000
+#define PCIXM_STATUS_MAX_CUM_READ 0x1C000000
+#define PCIXM_STATUS_RCVD_SC_ERR 0x20000000
+#define PCIXM_STATUS_266CAP 0x40000000
+#define PCIXM_STATUS_533CAP 0x80000000
+
+/* For header type 1 devices (PCI-X bridges) */
+#define PCIXR_SEC_STATUS 0x2
+#define PCIXM_SEC_STATUS_64BIT 0x0001
+#define PCIXM_SEC_STATUS_133CAP 0x0002
+#define PCIXM_SEC_STATUS_SC_DISC 0x0004
+#define PCIXM_SEC_STATUS_UNEXP_SC 0x0008
+#define PCIXM_SEC_STATUS_SC_OVERRUN 0x0010
+#define PCIXM_SEC_STATUS_SR_DELAYED 0x0020
+#define PCIXM_SEC_STATUS_BUS_MODE 0x03c0
+#define PCIXM_SEC_STATUS_VERSION 0x3000
+#define PCIXM_SEC_STATUS_266CAP 0x4000
+#define PCIXM_SEC_STATUS_533CAP 0x8000
+#define PCIXR_BRIDGE_STATUS 0x4
+#define PCIXM_BRIDGE_STATUS_DEVFN 0x000000FF
+#define PCIXM_BRIDGE_STATUS_BUS 0x0000FF00
+#define PCIXM_BRIDGE_STATUS_64BIT 0x00010000
+#define PCIXM_BRIDGE_STATUS_133CAP 0x00020000
+#define PCIXM_BRIDGE_STATUS_SC_DISCARDED 0x00040000
+#define PCIXM_BRIDGE_STATUS_UNEXP_SC 0x00080000
+#define PCIXM_BRIDGE_STATUS_SC_OVERRUN 0x00100000
+#define PCIXM_BRIDGE_STATUS_SR_DELAYED 0x00200000
+#define PCIXM_BRIDGE_STATUS_DEVID_MSGCAP 0x20000000
+#define PCIXM_BRIDGE_STATUS_266CAP 0x40000000
+#define PCIXM_BRIDGE_STATUS_533CAP 0x80000000
+
+/* HT (HyperTransport) Capability definitions */
+#define PCIR_HT_COMMAND 0x2
+#define PCIM_HTCMD_CAP_MASK 0xf800 /* Capability type. */
+#define PCIM_HTCAP_SLAVE 0x0000 /* 000xx */
+#define PCIM_HTCAP_HOST 0x2000 /* 001xx */
+#define PCIM_HTCAP_SWITCH 0x4000 /* 01000 */
+#define PCIM_HTCAP_INTERRUPT 0x8000 /* 10000 */
+#define PCIM_HTCAP_REVISION_ID 0x8800 /* 10001 */
+#define PCIM_HTCAP_UNITID_CLUMPING 0x9000 /* 10010 */
+#define PCIM_HTCAP_EXT_CONFIG_SPACE 0x9800 /* 10011 */
+#define PCIM_HTCAP_ADDRESS_MAPPING 0xa000 /* 10100 */
+#define PCIM_HTCAP_MSI_MAPPING 0xa800 /* 10101 */
+#define PCIM_HTCAP_DIRECT_ROUTE 0xb000 /* 10110 */
+#define PCIM_HTCAP_VCSET 0xb800 /* 10111 */
+#define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */
+#define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */
+#define PCIM_HTCAP_GEN3 0xd000 /* 11010 */
+#define PCIM_HTCAP_FLE 0xd800 /* 11011 */
+#define PCIM_HTCAP_PM 0xe000 /* 11100 */
+#define PCIM_HTCAP_HIGH_NODE_COUNT 0xe800 /* 11101 */
+
+/* HT MSI Mapping Capability definitions. */
+#define PCIM_HTCMD_MSI_ENABLE 0x0001
+#define PCIM_HTCMD_MSI_FIXED 0x0002
+#define PCIR_HTMSI_ADDRESS_LO 0x4
+#define PCIR_HTMSI_ADDRESS_HI 0x8
+
+/* PCI Vendor capability definitions */
+#define PCIR_VENDOR_LENGTH 0x2
+#define PCIR_VENDOR_DATA 0x3
+
+/* PCI EHCI Debug Port definitions */
+#define PCIR_DEBUG_PORT 0x2
+#define PCIM_DEBUG_PORT_OFFSET 0x1FFF
+#define PCIM_DEBUG_PORT_BAR 0xe000
+
+/* PCI-PCI Bridge Subvendor definitions */
+#define PCIR_SUBVENDCAP_ID 0x4
+
+/* PCI Express definitions */
+#define PCIER_FLAGS 0x2
+#define PCIEM_FLAGS_VERSION 0x000F
+#define PCIEM_FLAGS_TYPE 0x00F0
+#define PCIEM_TYPE_ENDPOINT 0x0000
+#define PCIEM_TYPE_LEGACY_ENDPOINT 0x0010
+#define PCIEM_TYPE_ROOT_PORT 0x0040
+#define PCIEM_TYPE_UPSTREAM_PORT 0x0050
+#define PCIEM_TYPE_DOWNSTREAM_PORT 0x0060
+#define PCIEM_TYPE_PCI_BRIDGE 0x0070
+#define PCIEM_TYPE_PCIE_BRIDGE 0x0080
+#define PCIEM_TYPE_ROOT_INT_EP 0x0090
+#define PCIEM_TYPE_ROOT_EC 0x00a0
+#define PCIEM_FLAGS_SLOT 0x0100
+#define PCIEM_FLAGS_IRQ 0x3e00
+#define PCIER_DEVICE_CAP 0x4
+#define PCIEM_CAP_MAX_PAYLOAD 0x00000007
+#define PCIEM_CAP_PHANTHOM_FUNCS 0x00000018
+#define PCIEM_CAP_EXT_TAG_FIELD 0x00000020
+#define PCIEM_CAP_L0S_LATENCY 0x000001c0
+#define PCIEM_CAP_L1_LATENCY 0x00000e00
+#define PCIEM_CAP_ROLE_ERR_RPT 0x00008000
+#define PCIEM_CAP_SLOT_PWR_LIM_VAL 0x03fc0000
+#define PCIEM_CAP_SLOT_PWR_LIM_SCALE 0x0c000000
+#define PCIEM_CAP_FLR 0x10000000
+#define PCIER_DEVICE_CTL 0x8
+#define PCIEM_CTL_COR_ENABLE 0x0001
+#define PCIEM_CTL_NFER_ENABLE 0x0002
+#define PCIEM_CTL_FER_ENABLE 0x0004
+#define PCIEM_CTL_URR_ENABLE 0x0008
+#define PCIEM_CTL_RELAXED_ORD_ENABLE 0x0010
+#define PCIEM_CTL_MAX_PAYLOAD 0x00e0
+#define PCIEM_CTL_EXT_TAG_FIELD 0x0100
+#define PCIEM_CTL_PHANTHOM_FUNCS 0x0200
+#define PCIEM_CTL_AUX_POWER_PM 0x0400
+#define PCIEM_CTL_NOSNOOP_ENABLE 0x0800
+#define PCIEM_CTL_MAX_READ_REQUEST 0x7000
+#define PCIEM_CTL_BRDG_CFG_RETRY 0x8000 /* PCI-E - PCI/PCI-X bridges */
+#define PCIEM_CTL_INITIATE_FLR 0x8000 /* FLR capable endpoints */
+#define PCIER_DEVICE_STA 0xa
+#define PCIEM_STA_CORRECTABLE_ERROR 0x0001
+#define PCIEM_STA_NON_FATAL_ERROR 0x0002
+#define PCIEM_STA_FATAL_ERROR 0x0004
+#define PCIEM_STA_UNSUPPORTED_REQ 0x0008
+#define PCIEM_STA_AUX_POWER 0x0010
+#define PCIEM_STA_TRANSACTION_PND 0x0020
+#define PCIER_LINK_CAP 0xc
+#define PCIEM_LINK_CAP_MAX_SPEED 0x0000000f
+#define PCIEM_LINK_CAP_MAX_WIDTH 0x000003f0
+#define PCIEM_LINK_CAP_ASPM 0x00000c00
+#define PCIEM_LINK_CAP_L0S_EXIT 0x00007000
+#define PCIEM_LINK_CAP_L1_EXIT 0x00038000
+#define PCIEM_LINK_CAP_CLOCK_PM 0x00040000
+#define PCIEM_LINK_CAP_SURPRISE_DOWN 0x00080000
+#define PCIEM_LINK_CAP_DL_ACTIVE 0x00100000
+#define PCIEM_LINK_CAP_LINK_BW_NOTIFY 0x00200000
+#define PCIEM_LINK_CAP_ASPM_COMPLIANCE 0x00400000
+#define PCIEM_LINK_CAP_PORT 0xff000000
+#define PCIER_LINK_CTL 0x10
+#define PCIEM_LINK_CTL_ASPMC_DIS 0x0000
+#define PCIEM_LINK_CTL_ASPMC_L0S 0x0001
+#define PCIEM_LINK_CTL_ASPMC_L1 0x0002
+#define PCIEM_LINK_CTL_ASPMC 0x0003
+#define PCIEM_LINK_CTL_RCB 0x0008
+#define PCIEM_LINK_CTL_LINK_DIS 0x0010
+#define PCIEM_LINK_CTL_RETRAIN_LINK 0x0020
+#define PCIEM_LINK_CTL_COMMON_CLOCK 0x0040
+#define PCIEM_LINK_CTL_EXTENDED_SYNC 0x0080
+#define PCIEM_LINK_CTL_ECPM 0x0100
+#define PCIEM_LINK_CTL_HAWD 0x0200
+#define PCIEM_LINK_CTL_LBMIE 0x0400
+#define PCIEM_LINK_CTL_LABIE 0x0800
+#define PCIER_LINK_STA 0x12
+#define PCIEM_LINK_STA_SPEED 0x000f
+#define PCIEM_LINK_STA_WIDTH 0x03f0
+#define PCIEM_LINK_STA_TRAINING_ERROR 0x0400
+#define PCIEM_LINK_STA_TRAINING 0x0800
+#define PCIEM_LINK_STA_SLOT_CLOCK 0x1000
+#define PCIEM_LINK_STA_DL_ACTIVE 0x2000
+#define PCIEM_LINK_STA_LINK_BW_MGMT 0x4000
+#define PCIEM_LINK_STA_LINK_AUTO_BW 0x8000
+#define PCIER_SLOT_CAP 0x14
+#define PCIEM_SLOT_CAP_APB 0x00000001
+#define PCIEM_SLOT_CAP_PCP 0x00000002
+#define PCIEM_SLOT_CAP_MRLSP 0x00000004
+#define PCIEM_SLOT_CAP_AIP 0x00000008
+#define PCIEM_SLOT_CAP_PIP 0x00000010
+#define PCIEM_SLOT_CAP_HPS 0x00000020
+#define PCIEM_SLOT_CAP_HPC 0x00000040
+#define PCIEM_SLOT_CAP_SPLV 0x00007f80
+#define PCIEM_SLOT_CAP_SPLS 0x00018000
+#define PCIEM_SLOT_CAP_EIP 0x00020000
+#define PCIEM_SLOT_CAP_NCCS 0x00040000
+#define PCIEM_SLOT_CAP_PSN 0xfff80000
+#define PCIER_SLOT_CTL 0x18
+#define PCIEM_SLOT_CTL_ABPE 0x0001
+#define PCIEM_SLOT_CTL_PFDE 0x0002
+#define PCIEM_SLOT_CTL_MRLSCE 0x0004
+#define PCIEM_SLOT_CTL_PDCE 0x0008
+#define PCIEM_SLOT_CTL_CCIE 0x0010
+#define PCIEM_SLOT_CTL_HPIE 0x0020
+#define PCIEM_SLOT_CTL_AIC 0x00c0
+#define PCIEM_SLOT_CTL_PIC 0x0300
+#define PCIEM_SLOT_CTL_PCC 0x0400
+#define PCIEM_SLOT_CTL_EIC 0x0800
+#define PCIEM_SLOT_CTL_DLLSCE 0x1000
+#define PCIER_SLOT_STA 0x1a
+#define PCIEM_SLOT_STA_ABP 0x0001
+#define PCIEM_SLOT_STA_PFD 0x0002
+#define PCIEM_SLOT_STA_MRLSC 0x0004
+#define PCIEM_SLOT_STA_PDC 0x0008
+#define PCIEM_SLOT_STA_CC 0x0010
+#define PCIEM_SLOT_STA_MRLSS 0x0020
+#define PCIEM_SLOT_STA_PDS 0x0040
+#define PCIEM_SLOT_STA_EIS 0x0080
+#define PCIEM_SLOT_STA_DLLSC 0x0100
+#define PCIER_ROOT_CTL 0x1c
+#define PCIEM_ROOT_CTL_SERR_CORR 0x0001
+#define PCIEM_ROOT_CTL_SERR_NONFATAL 0x0002
+#define PCIEM_ROOT_CTL_SERR_FATAL 0x0004
+#define PCIEM_ROOT_CTL_PME 0x0008
+#define PCIEM_ROOT_CTL_CRS_VIS 0x0010
+#define PCIER_ROOT_CAP 0x1e
+#define PCIEM_ROOT_CAP_CRS_VIS 0x0001
+#define PCIER_ROOT_STA 0x20
+#define PCIEM_ROOT_STA_PME_REQID_MASK 0x0000ffff
+#define PCIEM_ROOT_STA_PME_STATUS 0x00010000
+#define PCIEM_ROOT_STA_PME_PEND 0x00020000
+#define PCIER_DEVICE_CAP2 0x24
+#define PCIEM_CAP2_ARI 0x20
+#define PCIER_DEVICE_CTL2 0x28
+#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f
+#define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010
+#define PCIEM_CTL2_ARI 0x0020
+#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040
+#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080
+#define PCIEM_CTL2_ID_ORDERED_REQ_EN 0x0100
+#define PCIEM_CTL2_ID_ORDERED_CMP_EN 0x0200
+#define PCIEM_CTL2_LTR_ENABLE 0x0400
+#define PCIEM_CTL2_OBFF 0x6000
+#define PCIEM_OBFF_DISABLE 0x0000
+#define PCIEM_OBFF_MSGA_ENABLE 0x2000
+#define PCIEM_OBFF_MSGB_ENABLE 0x4000
+#define PCIEM_OBFF_WAKE_ENABLE 0x6000
+#define PCIEM_CTL2_END2END_TLP 0x8000
+#define PCIER_DEVICE_STA2 0x2a
+#define PCIER_LINK_CAP2 0x2c
+#define PCIER_LINK_CTL2 0x30
+#define PCIER_LINK_STA2 0x32
+#define PCIER_SLOT_CAP2 0x34
+#define PCIER_SLOT_CTL2 0x38
+#define PCIER_SLOT_STA2 0x3a
+
+/* MSI-X definitions */
+#define PCIR_MSIX_CTRL 0x2
+#define PCIM_MSIXCTRL_MSIX_ENABLE 0x8000
+#define PCIM_MSIXCTRL_FUNCTION_MASK 0x4000
+#define PCIM_MSIXCTRL_TABLE_SIZE 0x07FF
+#define PCIR_MSIX_TABLE 0x4
+#define PCIR_MSIX_PBA 0x8
+#define PCIM_MSIX_BIR_MASK 0x7
+#define PCIM_MSIX_BIR_BAR_10 0
+#define PCIM_MSIX_BIR_BAR_14 1
+#define PCIM_MSIX_BIR_BAR_18 2
+#define PCIM_MSIX_BIR_BAR_1C 3
+#define PCIM_MSIX_BIR_BAR_20 4
+#define PCIM_MSIX_BIR_BAR_24 5
+#define PCIM_MSIX_VCTRL_MASK 0x1
+
+/* PCI Advanced Features definitions */
+#define PCIR_PCIAF_CAP 0x3
+#define PCIM_PCIAFCAP_TP 0x01
+#define PCIM_PCIAFCAP_FLR 0x02
+#define PCIR_PCIAF_CTRL 0x4
+#define PCIR_PCIAFCTRL_FLR 0x01
+#define PCIR_PCIAF_STATUS 0x5
+#define PCIR_PCIAFSTATUS_TP 0x01
+
+/* Advanced Error Reporting */
+#define PCIR_AER_UC_STATUS 0x04
+#define PCIM_AER_UC_TRAINING_ERROR 0x00000001
+#define PCIM_AER_UC_DL_PROTOCOL_ERROR 0x00000010
+#define PCIM_AER_UC_SURPRISE_LINK_DOWN 0x00000020
+#define PCIM_AER_UC_POISONED_TLP 0x00001000
+#define PCIM_AER_UC_FC_PROTOCOL_ERROR 0x00002000
+#define PCIM_AER_UC_COMPLETION_TIMEOUT 0x00004000
+#define PCIM_AER_UC_COMPLETER_ABORT 0x00008000
+#define PCIM_AER_UC_UNEXPECTED_COMPLETION 0x00010000
+#define PCIM_AER_UC_RECEIVER_OVERFLOW 0x00020000
+#define PCIM_AER_UC_MALFORMED_TLP 0x00040000
+#define PCIM_AER_UC_ECRC_ERROR 0x00080000
+#define PCIM_AER_UC_UNSUPPORTED_REQUEST 0x00100000
+#define PCIM_AER_UC_ACS_VIOLATION 0x00200000
+#define PCIM_AER_UC_INTERNAL_ERROR 0x00400000
+#define PCIM_AER_UC_MC_BLOCKED_TLP 0x00800000
+#define PCIM_AER_UC_ATOMIC_EGRESS_BLK 0x01000000
+#define PCIM_AER_UC_TLP_PREFIX_BLOCKED 0x02000000
+#define PCIR_AER_UC_MASK 0x08 /* Shares bits with UC_STATUS */
+#define PCIR_AER_UC_SEVERITY 0x0c /* Shares bits with UC_STATUS */
+#define PCIR_AER_COR_STATUS 0x10
+#define PCIM_AER_COR_RECEIVER_ERROR 0x00000001
+#define PCIM_AER_COR_BAD_TLP 0x00000040
+#define PCIM_AER_COR_BAD_DLLP 0x00000080
+#define PCIM_AER_COR_REPLAY_ROLLOVER 0x00000100
+#define PCIM_AER_COR_REPLAY_TIMEOUT 0x00001000
+#define PCIM_AER_COR_ADVISORY_NF_ERROR 0x00002000
+#define PCIM_AER_COR_INTERNAL_ERROR 0x00004000
+#define PCIM_AER_COR_HEADER_LOG_OVFLOW 0x00008000
+#define PCIR_AER_COR_MASK 0x14 /* Shares bits with COR_STATUS */
+#define PCIR_AER_CAP_CONTROL 0x18
+#define PCIM_AER_FIRST_ERROR_PTR 0x0000001f
+#define PCIM_AER_ECRC_GEN_CAPABLE 0x00000020
+#define PCIM_AER_ECRC_GEN_ENABLE 0x00000040
+#define PCIM_AER_ECRC_CHECK_CAPABLE 0x00000080
+#define PCIM_AER_ECRC_CHECK_ENABLE 0x00000100
+#define PCIM_AER_MULT_HDR_CAPABLE 0x00000200
+#define PCIM_AER_MULT_HDR_ENABLE 0x00000400
+#define PCIM_AER_TLP_PREFIX_LOG_PRESENT 0x00000800
+#define PCIR_AER_HEADER_LOG 0x1c
+#define PCIR_AER_ROOTERR_CMD 0x2c /* Only for root complex ports */
+#define PCIM_AER_ROOTERR_COR_ENABLE 0x00000001
+#define PCIM_AER_ROOTERR_NF_ENABLE 0x00000002
+#define PCIM_AER_ROOTERR_F_ENABLE 0x00000004
+#define PCIR_AER_ROOTERR_STATUS 0x30 /* Only for root complex ports */
+#define PCIM_AER_ROOTERR_COR_ERR 0x00000001
+#define PCIM_AER_ROOTERR_MULTI_COR_ERR 0x00000002
+#define PCIM_AER_ROOTERR_UC_ERR 0x00000004
+#define PCIM_AER_ROOTERR_MULTI_UC_ERR 0x00000008
+#define PCIM_AER_ROOTERR_FIRST_UC_FATAL 0x00000010
+#define PCIM_AER_ROOTERR_NF_ERR 0x00000020
+#define PCIM_AER_ROOTERR_F_ERR 0x00000040
+#define PCIM_AER_ROOTERR_INT_MESSAGE 0xf8000000
+#define PCIR_AER_COR_SOURCE_ID 0x34 /* Only for root complex ports */
+#define PCIR_AER_ERR_SOURCE_ID 0x36 /* Only for root complex ports */
+#define PCIR_AER_TLP_PREFIX_LOG 0x38 /* Only for TLP prefix functions */
+
+/* Virtual Channel definitions */
+#define PCIR_VC_CAP1 0x04
+#define PCIM_VC_CAP1_EXT_COUNT 0x00000007
+#define PCIM_VC_CAP1_LOWPRI_EXT_COUNT 0x00000070
+#define PCIR_VC_CAP2 0x08
+#define PCIR_VC_CONTROL 0x0C
+#define PCIR_VC_STATUS 0x0E
+#define PCIR_VC_RESOURCE_CAP(n) (0x10 + (n) * 0x0C)
+#define PCIR_VC_RESOURCE_CTL(n) (0x14 + (n) * 0x0C)
+#define PCIR_VC_RESOURCE_STA(n) (0x18 + (n) * 0x0C)
+
+/* Serial Number definitions */
+#define PCIR_SERIAL_LOW 0x04
+#define PCIR_SERIAL_HIGH 0x08
+
+/* SR-IOV definitions */
+#define PCIR_SRIOV_CTL 0x08
+#define PCIM_SRIOV_VF_EN 0x01
+#define PCIM_SRIOV_VF_MSE 0x08 /* Memory space enable. */
+#define PCIM_SRIOV_ARI_EN 0x10
+#define PCIR_SRIOV_TOTAL_VFS 0x0E
+#define PCIR_SRIOV_NUM_VFS 0x10
+#define PCIR_SRIOV_VF_OFF 0x14
+#define PCIR_SRIOV_VF_STRIDE 0x16
+#define PCIR_SRIOV_VF_DID 0x1A
+#define PCIR_SRIOV_PAGE_CAP 0x1C
+#define PCIR_SRIOV_PAGE_SIZE 0x20
+
+#define PCI_SRIOV_BASE_PAGE_SHIFT 12
+
+#define PCIR_SRIOV_BARS 0x24
+#define PCIR_SRIOV_BAR(x) (PCIR_SRIOV_BARS + (x) * 4)
+
diff --git a/usr/src/boot/include/elf.h b/usr/src/boot/include/elf.h
new file mode 100644
index 0000000000..c094a1c788
--- /dev/null
+++ b/usr/src/boot/include/elf.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2001 David E. O'Brien.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This is a Solaris compatibility header
+ */
+
+#ifndef _ELF_H_
+#define _ELF_H_
+
+#include <sys/types.h>
+#include <machine/elf.h>
+#include <sys/elf32.h>
+#include <sys/elf64.h>
+
+#endif /* !_ELF_H_ */
diff --git a/usr/src/boot/include/errno.h b/usr/src/boot/include/errno.h
new file mode 100644
index 0000000000..cb739ca691
--- /dev/null
+++ b/usr/src/boot/include/errno.h
@@ -0,0 +1,3 @@
+
+
+#include <sys/errno.h>
diff --git a/usr/src/boot/include/inttypes.h b/usr/src/boot/include/inttypes.h
new file mode 100644
index 0000000000..510939680f
--- /dev/null
+++ b/usr/src/boot/include/inttypes.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _INTTYPES_H_
+#define _INTTYPES_H_
+
+#include <machine/_inttypes.h>
+#include <sys/stdint.h>
+
+#ifndef __cplusplus
+#ifndef _WCHAR_T_DECLARED
+typedef ___wchar_t wchar_t;
+#define _WCHAR_T_DECLARED
+#endif
+#endif
+
+typedef struct {
+ intmax_t quot; /* Quotient. */
+ intmax_t rem; /* Remainder. */
+} imaxdiv_t;
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_inttypes.h>
+#endif
+intmax_t imaxabs(intmax_t) __pure2;
+imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2;
+
+intmax_t strtoimax(const char * __restrict, char ** __restrict, int);
+uintmax_t strtoumax(const char * __restrict, char ** __restrict, int);
+intmax_t wcstoimax(const wchar_t * __restrict,
+ wchar_t ** __restrict, int);
+uintmax_t wcstoumax(const wchar_t * __restrict,
+ wchar_t ** __restrict, int);
+__END_DECLS
+
+#endif /* !_INTTYPES_H_ */
diff --git a/usr/src/boot/include/isofs/cd9660/cd9660_rrip.h b/usr/src/boot/include/isofs/cd9660/cd9660_rrip.h
new file mode 100644
index 0000000000..f6fa050368
--- /dev/null
+++ b/usr/src/boot/include/isofs/cd9660/cd9660_rrip.h
@@ -0,0 +1,137 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley
+ * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
+ * Support code is derived from software contributed to Berkeley
+ * by Atsushi Murai (amurai@spec.co.jp).
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
+ * $FreeBSD$
+ */
+
+typedef struct {
+ char type [ISODCL ( 0, 1)];
+ u_char length [ISODCL ( 2, 2)]; /* 711 */
+ u_char version [ISODCL ( 3, 3)];
+} ISO_SUSP_HEADER;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char mode [ISODCL ( 4, 11)]; /* 733 */
+ char links [ISODCL ( 12, 19)]; /* 733 */
+ char uid [ISODCL ( 20, 27)]; /* 733 */
+ char gid [ISODCL ( 28, 35)]; /* 733 */
+} ISO_RRIP_ATTR;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char dev_t_high [ISODCL ( 4, 11)]; /* 733 */
+ char dev_t_low [ISODCL ( 12, 19)]; /* 733 */
+} ISO_RRIP_DEVICE;
+
+#define ISO_SUSP_CFLAG_CONTINUE 0x01
+#define ISO_SUSP_CFLAG_CURRENT 0x02
+#define ISO_SUSP_CFLAG_PARENT 0x04
+#define ISO_SUSP_CFLAG_ROOT 0x08
+#define ISO_SUSP_CFLAG_VOLROOT 0x10
+#define ISO_SUSP_CFLAG_HOST 0x20
+
+typedef struct {
+ u_char cflag [ISODCL ( 1, 1)];
+ u_char clen [ISODCL ( 2, 2)];
+ u_char name [1]; /* XXX */
+} ISO_RRIP_SLINK_COMPONENT;
+#define ISO_RRIP_SLSIZ 2
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ u_char flags [ISODCL ( 4, 4)];
+ u_char component [ISODCL ( 5, 5)];
+} ISO_RRIP_SLINK;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char flags [ISODCL ( 4, 4)];
+} ISO_RRIP_ALTNAME;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char dir_loc [ISODCL ( 4, 11)]; /* 733 */
+} ISO_RRIP_CLINK;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char dir_loc [ISODCL ( 4, 11)]; /* 733 */
+} ISO_RRIP_PLINK;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+} ISO_RRIP_RELDIR;
+
+#define ISO_SUSP_TSTAMP_FORM17 0x80
+#define ISO_SUSP_TSTAMP_FORM7 0x00
+#define ISO_SUSP_TSTAMP_CREAT 0x01
+#define ISO_SUSP_TSTAMP_MODIFY 0x02
+#define ISO_SUSP_TSTAMP_ACCESS 0x04
+#define ISO_SUSP_TSTAMP_ATTR 0x08
+#define ISO_SUSP_TSTAMP_BACKUP 0x10
+#define ISO_SUSP_TSTAMP_EXPIRE 0x20
+#define ISO_SUSP_TSTAMP_EFFECT 0x40
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ u_char flags [ISODCL ( 4, 4)];
+ u_char time [ISODCL ( 5, 5)];
+} ISO_RRIP_TSTAMP;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ u_char flags [ISODCL ( 4, 4)];
+} ISO_RRIP_IDFLAG;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char len_id [ISODCL ( 4, 4)];
+ char len_des [ISODCL ( 5, 5)];
+ char len_src [ISODCL ( 6, 6)];
+ char version [ISODCL ( 7, 7)];
+} ISO_RRIP_EXTREF;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char check [ISODCL ( 4, 5)];
+ char skip [ISODCL ( 6, 6)];
+} ISO_RRIP_OFFSET;
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ char location [ISODCL ( 4, 11)];
+ char offset [ISODCL ( 12, 19)];
+ char length [ISODCL ( 20, 27)];
+} ISO_RRIP_CONT;
diff --git a/usr/src/boot/include/isofs/cd9660/iso.h b/usr/src/boot/include/isofs/cd9660/iso.h
new file mode 100644
index 0000000000..a831d7b881
--- /dev/null
+++ b/usr/src/boot/include/isofs/cd9660/iso.h
@@ -0,0 +1,359 @@
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley
+ * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
+ * Support code is derived from software contributed to Berkeley
+ * by Atsushi Murai (amurai@spec.co.jp).
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)iso.h 8.6 (Berkeley) 5/10/95
+ * $FreeBSD$
+ */
+
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_volume_descriptor {
+ char type[ISODCL(1,1)]; /* 711 */
+ char id[ISODCL(2,6)];
+ char version[ISODCL(7,7)];
+ char unused[ISODCL(8,8)];
+ char type_sierra[ISODCL(9,9)]; /* 711 */
+ char id_sierra[ISODCL(10,14)];
+ char version_sierra[ISODCL(15,15)];
+ char data[ISODCL(16,2048)];
+};
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_SUPPLEMENTARY 2
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+#define ISO_ECMA_ID "CDW01"
+
+#define ISO_SIERRA_ID "CDROM"
+
+struct iso_primary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char unused1 [ISODCL ( 8, 8)];
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char unused3 [ISODCL ( 89, 120)];
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+#define ISO_DEFAULT_BLOCK_SIZE 2048
+
+/*
+ * Used by Microsoft Joliet extension to ISO9660. Almost the same
+ * as PVD, but byte position 8 is a flag, and 89-120 is for escape.
+ */
+
+struct iso_supplementary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char flags [ISODCL ( 8, 8)]; /* 711? */
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char escape [ISODCL ( 89, 120)];
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+
+struct iso_sierra_primary_descriptor {
+ char unknown1 [ISODCL ( 1, 8)]; /* 733 */
+ char type [ISODCL ( 9, 9)]; /* 711 */
+ char id [ISODCL ( 10, 14)];
+ char version [ISODCL ( 15, 15)]; /* 711 */
+ char unused1 [ISODCL ( 16, 16)];
+ char system_id [ISODCL ( 17, 48)]; /* achars */
+ char volume_id [ISODCL ( 49, 80)]; /* dchars */
+ char unused2 [ISODCL ( 81, 88)];
+ char volume_space_size [ISODCL ( 89, 96)]; /* 733 */
+ char unused3 [ISODCL ( 97, 128)];
+ char volume_set_size [ISODCL (129, 132)]; /* 723 */
+ char volume_sequence_number [ISODCL (133, 136)]; /* 723 */
+ char logical_block_size [ISODCL (137, 140)]; /* 723 */
+ char path_table_size [ISODCL (141, 148)]; /* 733 */
+ char type_l_path_table [ISODCL (149, 152)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (153, 156)]; /* 731 */
+ char unknown2 [ISODCL (157, 160)]; /* 731 */
+ char unknown3 [ISODCL (161, 164)]; /* 731 */
+ char type_m_path_table [ISODCL (165, 168)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (169, 172)]; /* 732 */
+ char unknown4 [ISODCL (173, 176)]; /* 732 */
+ char unknown5 [ISODCL (177, 180)]; /* 732 */
+ char root_directory_record [ISODCL (181, 214)]; /* 9.1 */
+ char volume_set_id [ISODCL (215, 342)]; /* dchars */
+ char publisher_id [ISODCL (343, 470)]; /* achars */
+ char preparer_id [ISODCL (471, 598)]; /* achars */
+ char application_id [ISODCL (599, 726)]; /* achars */
+ char copyright_id [ISODCL (727, 790)]; /* achars */
+ char creation_date [ISODCL (791, 806)]; /* ? */
+ char modification_date [ISODCL (807, 822)]; /* ? */
+ char expiration_date [ISODCL (823, 838)]; /* ? */
+ char effective_date [ISODCL (839, 854)]; /* ? */
+ char file_structure_version [ISODCL (855, 855)]; /* 711 */
+ char unused4 [ISODCL (856, 2048)];
+};
+
+struct iso_directory_record {
+ char length [ISODCL (1, 1)]; /* 711 */
+ char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ u_char extent [ISODCL (3, 10)]; /* 733 */
+ u_char size [ISODCL (11, 18)]; /* 733 */
+ char date [ISODCL (19, 25)]; /* 7 by 711 */
+ char flags [ISODCL (26, 26)];
+ char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ char interleave [ISODCL (28, 28)]; /* 711 */
+ char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ char name_len [ISODCL (33, 33)]; /* 711 */
+ char name [1]; /* XXX */
+};
+/* can't take sizeof(iso_directory_record), because of possible alignment
+ of the last entry (34 instead of 33) */
+#define ISO_DIRECTORY_RECORD_SIZE 33
+
+struct iso_extended_attributes {
+ u_char owner [ISODCL (1, 4)]; /* 723 */
+ u_char group [ISODCL (5, 8)]; /* 723 */
+ u_char perm [ISODCL (9, 10)]; /* 9.5.3 */
+ char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
+ char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
+ char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
+ char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
+ char recfmt [ISODCL (79, 79)]; /* 711 */
+ char recattr [ISODCL (80, 80)]; /* 711 */
+ u_char reclen [ISODCL (81, 84)]; /* 723 */
+ char system_id [ISODCL (85, 116)]; /* achars */
+ char system_use [ISODCL (117, 180)];
+ char version [ISODCL (181, 181)]; /* 711 */
+ char len_esc [ISODCL (182, 182)]; /* 711 */
+ char reserved [ISODCL (183, 246)];
+ u_char len_au [ISODCL (247, 250)]; /* 723 */
+};
+
+#ifdef _KERNEL
+
+/* CD-ROM Format type */
+enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP,
+ ISO_FTYPE_JOLIET, ISO_FTYPE_ECMA, ISO_FTYPE_HIGH_SIERRA };
+
+#ifndef ISOFSMNT_ROOT
+#define ISOFSMNT_ROOT 0
+#endif
+
+struct iso_mnt {
+ uint64_t im_flags;
+
+ struct mount *im_mountp;
+ struct cdev *im_dev;
+ struct vnode *im_devvp;
+
+ struct g_consumer *im_cp;
+ struct bufobj *im_bo;
+
+ int logical_block_size;
+ int im_bshift;
+ int im_bmask;
+
+ int volume_space_size;
+
+ char root[ISODCL (157, 190)];
+ int root_extent;
+ int root_size;
+ enum ISO_FTYPE iso_ftype;
+
+ int rr_skip;
+ int rr_skip0;
+
+ int joliet_level;
+
+ void *im_d2l;
+ void *im_l2d;
+};
+
+struct ifid {
+ u_short ifid_len;
+ u_short ifid_pad;
+ int ifid_ino;
+ long ifid_start;
+};
+
+#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
+
+#define blkoff(imp, loc) ((loc) & (imp)->im_bmask)
+#define lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
+#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
+#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
+
+int cd9660_vget_internal(struct mount *, ino_t, int, struct vnode **, int,
+ struct iso_directory_record *);
+#define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
+ size_t, struct proc *))eopnotsupp)
+
+extern struct vop_vector cd9660_vnodeops;
+extern struct vop_vector cd9660_fifoops;
+
+int isochar(u_char *, u_char *, int, u_short *, int *, int, void *);
+int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *);
+void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *);
+ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
+u_short sgetrune(const char *, size_t, char const **, int, void *);
+
+#endif /* _KERNEL */
+
+/*
+ * The isonum_xxx functions are inlined anyway, and could come handy even
+ * outside the kernel. Thus we don't hide them here.
+ */
+
+/*
+ * 7xy
+ * x -> 1 = 8 bits, 2 = 16 bits, 3 = 32 bits
+ * y -> 1 = little-endian, 2 = big-endian, 3 = both (le then be)
+ */
+
+static __inline uint8_t
+isonum_711(const unsigned char *p)
+{
+
+ return (p[0]);
+}
+
+static __inline int8_t
+isonum_712(const unsigned char *p)
+{
+
+ return ((signed char)p[0]);
+}
+
+static __inline uint8_t
+isonum_713(const unsigned char *p)
+{
+
+ return (p[0]);
+}
+
+static __inline uint16_t
+isonum_721(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8);
+}
+
+static __inline uint16_t
+isonum_722(const unsigned char *p)
+{
+
+ return (p[1] | p[0] << 8);
+}
+
+static __inline uint16_t
+isonum_723(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8);
+}
+
+static __inline uint32_t
+isonum_731(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
+}
+
+static __inline uint32_t
+isonum_732(const unsigned char *p)
+{
+
+ return (p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24);
+}
+
+static __inline uint32_t
+isonum_733(const unsigned char *p)
+{
+
+ return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
+}
+
+/*
+ * Associated files have a leading '='.
+ */
+#define ASSOCCHAR '='
diff --git a/usr/src/boot/include/limits.h b/usr/src/boot/include/limits.h
new file mode 100644
index 0000000000..a1e1b98208
--- /dev/null
+++ b/usr/src/boot/include/limits.h
@@ -0,0 +1,147 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)limits.h 8.2 (Berkeley) 1/4/94
+ * $FreeBSD$
+ */
+
+#ifndef _LIMITS_H_
+#define _LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#if __POSIX_VISIBLE
+#define _POSIX_ARG_MAX 4096
+#define _POSIX_LINK_MAX 8
+#define _POSIX_MAX_CANON 255
+#define _POSIX_MAX_INPUT 255
+#define _POSIX_NAME_MAX 14
+#define _POSIX_PIPE_BUF 512
+#define _POSIX_SSIZE_MAX 32767
+#define _POSIX_STREAM_MAX 8
+
+#if __POSIX_VISIBLE >= 200112
+#define _POSIX_CHILD_MAX 25
+#define _POSIX_NGROUPS_MAX 8
+#define _POSIX_OPEN_MAX 20
+#define _POSIX_PATH_MAX 256
+#define _POSIX_TZNAME_MAX 6
+#else
+#define _POSIX_CHILD_MAX 6
+#define _POSIX_NGROUPS_MAX 0
+#define _POSIX_OPEN_MAX 16
+#define _POSIX_PATH_MAX 255
+#define _POSIX_TZNAME_MAX 3
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+#define BC_BASE_MAX 99 /* max ibase/obase values in bc(1) */
+#define BC_DIM_MAX 2048 /* max array elements in bc(1) */
+#define BC_SCALE_MAX 99 /* max scale value in bc(1) */
+#define BC_STRING_MAX 1000 /* max const string length in bc(1) */
+#define CHARCLASS_NAME_MAX 14 /* max character class name size */
+#define COLL_WEIGHTS_MAX 10 /* max weights for order keyword */
+#define EXPR_NEST_MAX 32 /* max expressions nested in expr(1) */
+#define LINE_MAX 2048 /* max bytes in an input line */
+#define RE_DUP_MAX 255 /* max RE's in interval notation */
+
+#define _POSIX2_BC_BASE_MAX 99
+#define _POSIX2_BC_DIM_MAX 2048
+#define _POSIX2_BC_SCALE_MAX 99
+#define _POSIX2_BC_STRING_MAX 1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EQUIV_CLASS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX 32
+#define _POSIX2_LINE_MAX 2048
+#define _POSIX2_RE_DUP_MAX 255
+#endif
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+#define _POSIX_AIO_LISTIO_MAX 2
+#define _POSIX_AIO_MAX 1
+#define _POSIX_DELAYTIMER_MAX 32
+#define _POSIX_MQ_OPEN_MAX 8
+#define _POSIX_MQ_PRIO_MAX 32
+#define _POSIX_RTSIG_MAX 8
+#define _POSIX_SEM_NSEMS_MAX 256
+#define _POSIX_SEM_VALUE_MAX 32767
+#define _POSIX_SIGQUEUE_MAX 32
+#define _POSIX_TIMER_MAX 32
+
+#define _POSIX_CLOCKRES_MIN 20000000
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX 128
+#define _POSIX_THREAD_THREADS_MAX 64
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+#define _POSIX_HOST_NAME_MAX 255
+#define _POSIX_LOGIN_NAME_MAX 9
+#define _POSIX_SS_REPL_MAX 4
+#define _POSIX_SYMLINK_MAX 255
+#define _POSIX_SYMLOOP_MAX 8
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX 8
+#define _POSIX_TRACE_SYS_MAX 8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX 9
+
+#define _POSIX_RE_DUP_MAX _POSIX2_RE_DUP_MAX
+#endif
+
+#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
+#define NL_ARGMAX 99 /* max # of position args for printf */
+#define NL_MSGMAX 32767
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+#endif
+
+#if __XSI_VISIBLE
+#define _XOPEN_IOV_MAX 16
+#define _XOPEN_NAME_MAX 255
+#define _XOPEN_PATH_MAX 1024
+#define PASS_MAX 128 /* _PASSWORD_LEN from <pwd.h> */
+
+#define NL_LANGMAX 31 /* max LANG name length */
+#define NL_NMAX 1
+#endif
+
+#define MB_LEN_MAX 6 /* 31-bit UTF-8 */
+
+#include <sys/limits.h>
+
+#if __POSIX_VISIBLE
+#include <sys/syslimits.h>
+#endif
+
+#endif /* !_LIMITS_H_ */
diff --git a/usr/src/boot/include/link.h b/usr/src/boot/include/link.h
new file mode 100644
index 0000000000..f95bbe8872
--- /dev/null
+++ b/usr/src/boot/include/link.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/link_elf.h>
diff --git a/usr/src/boot/include/math.h b/usr/src/boot/include/math.h
new file mode 100644
index 0000000000..2ff1731054
--- /dev/null
+++ b/usr/src/boot/include/math.h
@@ -0,0 +1,507 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $FreeBSD$
+ */
+
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <machine/_limits.h>
+
+/*
+ * ANSI/POSIX
+ */
+extern const union __infinity_un {
+ unsigned char __uc[8];
+ double __ud;
+} __infinity;
+
+extern const union __nan_un {
+ unsigned char __uc[sizeof(float)];
+ float __uf;
+} __nan;
+
+#if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
+#define __MATH_BUILTIN_CONSTANTS
+#endif
+
+#if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER)
+#define __MATH_BUILTIN_RELOPS
+#endif
+
+#ifdef __MATH_BUILTIN_CONSTANTS
+#define HUGE_VAL __builtin_huge_val()
+#else
+#define HUGE_VAL (__infinity.__ud)
+#endif
+
+#if __ISO_C_VISIBLE >= 1999
+#define FP_ILOGB0 (-__INT_MAX)
+#define FP_ILOGBNAN __INT_MAX
+
+#ifdef __MATH_BUILTIN_CONSTANTS
+#define HUGE_VALF __builtin_huge_valf()
+#define HUGE_VALL __builtin_huge_vall()
+#define INFINITY __builtin_inff()
+#define NAN __builtin_nanf("")
+#else
+#define HUGE_VALF (float)HUGE_VAL
+#define HUGE_VALL (long double)HUGE_VAL
+#define INFINITY HUGE_VALF
+#define NAN (__nan.__uf)
+#endif /* __MATH_BUILTIN_CONSTANTS */
+
+#define MATH_ERRNO 1
+#define MATH_ERREXCEPT 2
+#define math_errhandling MATH_ERREXCEPT
+
+#define FP_FAST_FMAF 1
+
+/* Symbolic constants to classify floating point numbers. */
+#define FP_INFINITE 0x01
+#define FP_NAN 0x02
+#define FP_NORMAL 0x04
+#define FP_SUBNORMAL 0x08
+#define FP_ZERO 0x10
+
+#if (__STDC_VERSION__ >= 201112L && defined(__clang__)) || \
+ __has_extension(c_generic_selections)
+#define __fp_type_select(x, f, d, ld) _Generic((x), \
+ float: f(x), \
+ double: d(x), \
+ long double: ld(x), \
+ volatile float: f(x), \
+ volatile double: d(x), \
+ volatile long double: ld(x), \
+ volatile const float: f(x), \
+ volatile const double: d(x), \
+ volatile const long double: ld(x), \
+ const float: f(x), \
+ const double: d(x), \
+ const long double: ld(x))
+#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
+#define __fp_type_select(x, f, d, ld) __builtin_choose_expr( \
+ __builtin_types_compatible_p(__typeof(x), long double), ld(x), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(__typeof(x), double), d(x), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(__typeof(x), float), f(x), (void)0)))
+#else
+#define __fp_type_select(x, f, d, ld) \
+ ((sizeof(x) == sizeof(float)) ? f(x) \
+ : (sizeof(x) == sizeof(double)) ? d(x) \
+ : ld(x))
+#endif
+
+#define fpclassify(x) \
+ __fp_type_select(x, __fpclassifyf, __fpclassifyd, __fpclassifyl)
+#define isfinite(x) __fp_type_select(x, __isfinitef, __isfinite, __isfinitel)
+#define isinf(x) __fp_type_select(x, __isinff, __isinf, __isinfl)
+#define isnan(x) \
+ __fp_type_select(x, __inline_isnanf, __inline_isnan, __inline_isnanl)
+#define isnormal(x) __fp_type_select(x, __isnormalf, __isnormal, __isnormall)
+
+#ifdef __MATH_BUILTIN_RELOPS
+#define isgreater(x, y) __builtin_isgreater((x), (y))
+#define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
+#define isless(x, y) __builtin_isless((x), (y))
+#define islessequal(x, y) __builtin_islessequal((x), (y))
+#define islessgreater(x, y) __builtin_islessgreater((x), (y))
+#define isunordered(x, y) __builtin_isunordered((x), (y))
+#else
+#define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
+#define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
+#define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
+#define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
+#define islessgreater(x, y) (!isunordered((x), (y)) && \
+ ((x) > (y) || (y) > (x)))
+#define isunordered(x, y) (isnan(x) || isnan(y))
+#endif /* __MATH_BUILTIN_RELOPS */
+
+#define signbit(x) __fp_type_select(x, __signbitf, __signbit, __signbitl)
+
+typedef __double_t double_t;
+typedef __float_t float_t;
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * XOPEN/SVID
+ */
+#if __BSD_VISIBLE || __XSI_VISIBLE
+#define M_E 2.7182818284590452354 /* e */
+#define M_LOG2E 1.4426950408889634074 /* log 2e */
+#define M_LOG10E 0.43429448190325182765 /* log 10e */
+#define M_LN2 0.69314718055994530942 /* log e2 */
+#define M_LN10 2.30258509299404568402 /* log e10 */
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
+#define M_1_PI 0.31830988618379067154 /* 1/pi */
+#define M_2_PI 0.63661977236758134308 /* 2/pi */
+#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+extern int signgam;
+#endif /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+#if __BSD_VISIBLE
+#if 0
+/* Old value from 4.4BSD-Lite math.h; this is probably better. */
+#define HUGE HUGE_VAL
+#else
+#define HUGE MAXFLOAT
+#endif
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Most of these functions depend on the rounding mode and have the side
+ * effect of raising floating-point exceptions, so they are not declared
+ * as __pure2. In C99, FENV_ACCESS affects the purity of these functions.
+ */
+__BEGIN_DECLS
+/*
+ * ANSI/POSIX
+ */
+int __fpclassifyd(double) __pure2;
+int __fpclassifyf(float) __pure2;
+int __fpclassifyl(long double) __pure2;
+int __isfinitef(float) __pure2;
+int __isfinite(double) __pure2;
+int __isfinitel(long double) __pure2;
+int __isinff(float) __pure2;
+int __isinf(double) __pure2;
+int __isinfl(long double) __pure2;
+int __isnormalf(float) __pure2;
+int __isnormal(double) __pure2;
+int __isnormall(long double) __pure2;
+int __signbit(double) __pure2;
+int __signbitf(float) __pure2;
+int __signbitl(long double) __pure2;
+
+static __inline int
+__inline_isnan(__const double __x)
+{
+
+ return (__x != __x);
+}
+
+static __inline int
+__inline_isnanf(__const float __x)
+{
+
+ return (__x != __x);
+}
+
+static __inline int
+__inline_isnanl(__const long double __x)
+{
+
+ return (__x != __x);
+}
+
+/*
+ * Version 2 of the Single UNIX Specification (UNIX98) defined isnan() and
+ * isinf() as functions taking double. C99, and the subsequent POSIX revisions
+ * (SUSv3, POSIX.1-2001, define it as a macro that accepts any real floating
+ * point type. If we are targeting SUSv2 and C99 or C11 (or C++11) then we
+ * expose the newer definition, assuming that the language spec takes
+ * precedence over the operating system interface spec.
+ */
+#if __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600 && __ISO_C_VISIBLE < 1999
+#undef isinf
+#undef isnan
+int isinf(double);
+int isnan(double);
+#endif
+
+double acos(double);
+double asin(double);
+double atan(double);
+double atan2(double, double);
+double cos(double);
+double sin(double);
+double tan(double);
+
+double cosh(double);
+double sinh(double);
+double tanh(double);
+
+double exp(double);
+double frexp(double, int *); /* fundamentally !__pure2 */
+double ldexp(double, int);
+double log(double);
+double log10(double);
+double modf(double, double *); /* fundamentally !__pure2 */
+
+double pow(double, double);
+double sqrt(double);
+
+double ceil(double);
+double fabs(double) __pure2;
+double floor(double);
+double fmod(double, double);
+
+/*
+ * These functions are not in C90.
+ */
+#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE
+double acosh(double);
+double asinh(double);
+double atanh(double);
+double cbrt(double);
+double erf(double);
+double erfc(double);
+double exp2(double);
+double expm1(double);
+double fma(double, double, double);
+double hypot(double, double);
+int ilogb(double) __pure2;
+double lgamma(double);
+long long llrint(double);
+long long llround(double);
+double log1p(double);
+double log2(double);
+double logb(double);
+long lrint(double);
+long lround(double);
+double nan(const char *) __pure2;
+double nextafter(double, double);
+double remainder(double, double);
+double remquo(double, double, int *);
+double rint(double);
+#endif /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */
+
+#if __BSD_VISIBLE || __XSI_VISIBLE
+double j0(double);
+double j1(double);
+double jn(int, double);
+double y0(double);
+double y1(double);
+double yn(int, double);
+
+#if __XSI_VISIBLE <= 500 || __BSD_VISIBLE
+double gamma(double);
+#endif
+
+#if __XSI_VISIBLE <= 600 || __BSD_VISIBLE
+double scalb(double, double);
+#endif
+#endif /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999
+double copysign(double, double) __pure2;
+double fdim(double, double);
+double fmax(double, double) __pure2;
+double fmin(double, double) __pure2;
+double nearbyint(double);
+double round(double);
+double scalbln(double, long);
+double scalbn(double, int);
+double tgamma(double);
+double trunc(double);
+#endif
+
+/*
+ * BSD math library entry points
+ */
+#if __BSD_VISIBLE
+double drem(double, double);
+int finite(double) __pure2;
+int isnanf(float) __pure2;
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+double gamma_r(double, int *);
+double lgamma_r(double, int *);
+
+/*
+ * IEEE Test Vector
+ */
+double significand(double);
+#endif /* __BSD_VISIBLE */
+
+/* float versions of ANSI/POSIX functions */
+#if __ISO_C_VISIBLE >= 1999
+float acosf(float);
+float asinf(float);
+float atanf(float);
+float atan2f(float, float);
+float cosf(float);
+float sinf(float);
+float tanf(float);
+
+float coshf(float);
+float sinhf(float);
+float tanhf(float);
+
+float exp2f(float);
+float expf(float);
+float expm1f(float);
+float frexpf(float, int *); /* fundamentally !__pure2 */
+int ilogbf(float) __pure2;
+float ldexpf(float, int);
+float log10f(float);
+float log1pf(float);
+float log2f(float);
+float logf(float);
+float modff(float, float *); /* fundamentally !__pure2 */
+
+float powf(float, float);
+float sqrtf(float);
+
+float ceilf(float);
+float fabsf(float) __pure2;
+float floorf(float);
+float fmodf(float, float);
+float roundf(float);
+
+float erff(float);
+float erfcf(float);
+float hypotf(float, float);
+float lgammaf(float);
+float tgammaf(float);
+
+float acoshf(float);
+float asinhf(float);
+float atanhf(float);
+float cbrtf(float);
+float logbf(float);
+float copysignf(float, float) __pure2;
+long long llrintf(float);
+long long llroundf(float);
+long lrintf(float);
+long lroundf(float);
+float nanf(const char *) __pure2;
+float nearbyintf(float);
+float nextafterf(float, float);
+float remainderf(float, float);
+float remquof(float, float, int *);
+float rintf(float);
+float scalblnf(float, long);
+float scalbnf(float, int);
+float truncf(float);
+
+float fdimf(float, float);
+float fmaf(float, float, float);
+float fmaxf(float, float) __pure2;
+float fminf(float, float) __pure2;
+#endif
+
+/*
+ * float versions of BSD math library entry points
+ */
+#if __BSD_VISIBLE
+float dremf(float, float);
+int finitef(float) __pure2;
+float gammaf(float);
+float j0f(float);
+float j1f(float);
+float jnf(int, float);
+float scalbf(float, float);
+float y0f(float);
+float y1f(float);
+float ynf(int, float);
+
+/*
+ * Float versions of reentrant version of gamma & lgamma; passes
+ * signgam back by reference as the second argument; user must
+ * allocate space for signgam.
+ */
+float gammaf_r(float, int *);
+float lgammaf_r(float, int *);
+
+/*
+ * float version of IEEE Test Vector
+ */
+float significandf(float);
+#endif /* __BSD_VISIBLE */
+
+/*
+ * long double versions of ISO/POSIX math functions
+ */
+#if __ISO_C_VISIBLE >= 1999
+long double acoshl(long double);
+long double acosl(long double);
+long double asinhl(long double);
+long double asinl(long double);
+long double atan2l(long double, long double);
+long double atanhl(long double);
+long double atanl(long double);
+long double cbrtl(long double);
+long double ceill(long double);
+long double copysignl(long double, long double) __pure2;
+long double coshl(long double);
+long double cosl(long double);
+long double erfcl(long double);
+long double erfl(long double);
+long double exp2l(long double);
+long double expl(long double);
+long double expm1l(long double);
+long double fabsl(long double) __pure2;
+long double fdiml(long double, long double);
+long double floorl(long double);
+long double fmal(long double, long double, long double);
+long double fmaxl(long double, long double) __pure2;
+long double fminl(long double, long double) __pure2;
+long double fmodl(long double, long double);
+long double frexpl(long double value, int *); /* fundamentally !__pure2 */
+long double hypotl(long double, long double);
+int ilogbl(long double) __pure2;
+long double ldexpl(long double, int);
+long double lgammal(long double);
+long long llrintl(long double);
+long long llroundl(long double);
+long double log10l(long double);
+long double log1pl(long double);
+long double log2l(long double);
+long double logbl(long double);
+long double logl(long double);
+long lrintl(long double);
+long lroundl(long double);
+long double modfl(long double, long double *); /* fundamentally !__pure2 */
+long double nanl(const char *) __pure2;
+long double nearbyintl(long double);
+long double nextafterl(long double, long double);
+double nexttoward(double, long double);
+float nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+long double powl(long double, long double);
+long double remainderl(long double, long double);
+long double remquol(long double, long double, int *);
+long double rintl(long double);
+long double roundl(long double);
+long double scalblnl(long double, long);
+long double scalbnl(long double, int);
+long double sinhl(long double);
+long double sinl(long double);
+long double sqrtl(long double);
+long double tanhl(long double);
+long double tanl(long double);
+long double tgammal(long double);
+long double truncl(long double);
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+#if __BSD_VISIBLE
+long double lgammal_r(long double, int *);
+#endif
+
+__END_DECLS
+
+#endif /* !_MATH_H_ */
diff --git a/usr/src/boot/include/net/ethernet.h b/usr/src/boot/include/net/ethernet.h
new file mode 100644
index 0000000000..438028d156
--- /dev/null
+++ b/usr/src/boot/include/net/ethernet.h
@@ -0,0 +1,424 @@
+/*
+ * Fundamental constants relating to ethernet.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _NET_ETHERNET_H_
+#define _NET_ETHERNET_H_
+
+/*
+ * Some basic Ethernet constants.
+ */
+#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
+#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */
+#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */
+#define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */
+#define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */
+
+#define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */
+
+/*
+ * Compute the maximum frame size based on ethertype (i.e. possible
+ * encapsulation) and whether or not an FCS is present.
+ */
+#define ETHER_MAX_FRAME(ifp, etype, hasfcs) \
+ ((ifp)->if_mtu + ETHER_HDR_LEN + \
+ ((hasfcs) ? ETHER_CRC_LEN : 0) + \
+ (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+
+/*
+ * Ethernet-specific mbuf flags.
+ */
+#define M_HASFCS M_PROTO5 /* FCS included at end of frame */
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define ETHER_CRC_POLY_LE 0xedb88320
+#define ETHER_CRC_POLY_BE 0x04c11db6
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+ u_char ether_dhost[ETHER_ADDR_LEN];
+ u_char ether_shost[ETHER_ADDR_LEN];
+ u_short ether_type;
+} __packed;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[ETHER_ADDR_LEN];
+} __packed;
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+/*
+ * 802.1q Virtual LAN header.
+ */
+struct ether_vlan_header {
+ uint8_t evl_dhost[ETHER_ADDR_LEN];
+ uint8_t evl_shost[ETHER_ADDR_LEN];
+ uint16_t evl_encap_proto;
+ uint16_t evl_tag;
+ uint16_t evl_proto;
+} __packed;
+
+#define EVL_VLID_MASK 0x0FFF
+#define EVL_PRI_MASK 0xE000
+#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
+#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7)
+#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1)
+#define EVL_MAKETAG(vlid, pri, cfi) \
+ ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK))
+
+/*
+ * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
+ * However, there are some conflicts.
+ */
+
+#define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */
+ /* 0x0101 .. 0x1FF Experimental */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */
+#define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */
+#define ETHERTYPE_SPRITE 0x0500 /* ??? */
+ /* 0x0400 Nixdorf */
+#define ETHERTYPE_NS 0x0600 /* XNS */
+#define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */
+#define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */
+#define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_X75 0x0801 /* X.75 Internet */
+#define ETHERTYPE_NBS 0x0802 /* NBS Internet */
+#define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */
+#define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */
+#define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */
+#define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */
+#define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */
+ /* 0x081C Symbolics Private */
+ /* 0x0888 - 0x088A Xyplex */
+#define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */
+#define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */
+#define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */
+#define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */
+#define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */
+#define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */
+
+/* 0x1000 - 0x100F Berkeley Trailer */
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */
+#define ETHERTYPE_VALID 0x1600 /* VALID system protocol */
+#define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */
+#define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */
+
+ /* The following 3C0x types
+ are unregistered: */
+#define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */
+#define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */
+#define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */
+#define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect response not registered */
+#define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */
+#define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */
+#define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */
+#define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */
+#define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */
+#define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */
+#define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete NetBIOS name not registered */
+#define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */
+#define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */
+#define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */
+
+#define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */
+#define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */
+#define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */
+#define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */
+#define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */
+#define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */
+#define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */
+#define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */
+#define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */
+#define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */
+#define ETHERTYPE_LAT 0x6004 /* DEC LAT */
+#define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */
+#define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */
+#define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */
+#define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */
+#define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */
+ /* 0x6010 - 0x6014 3Com Corporation */
+#define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/
+#define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */
+#define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */
+#define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */
+#define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */
+#define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */
+#define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */
+#define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */
+#define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */
+ /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */
+#define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */
+#define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */
+#define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */
+#define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */
+#define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */
+#define ETHERTYPE_HP 0x8005 /* HP Probe */
+#define ETHERTYPE_NESTAR 0x8006 /* Nestar */
+#define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */
+#define ETHERTYPE_EXCELAN 0x8010 /* Excelan */
+#define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */
+#define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */
+#define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */
+#define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */
+#define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */
+#define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */
+#define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */
+#define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */
+#define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */
+#define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */
+#define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */
+#define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */
+#define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */
+#define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */
+#define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */
+#define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */
+#define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */
+#define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */
+#define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */
+ /* 0x8042 DEC Unassigned */
+#define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */
+ /* 0x8046 - 0x8047 AT&T */
+#define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */
+#define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */
+#define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */
+#define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */
+#define ETHERTYPE_ES 0x805D /* Evans & Sutherland */
+#define ETHERTYPE_LITTLE 0x8060 /* Little Machines */
+#define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */
+ /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */
+#define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */
+#define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */
+#define ETHERTYPE_ATT 0x8069 /* AT&T */
+#define ETHERTYPE_AUTOPHON 0x806A /* Autophon */
+#define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */
+#define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */
+ /* 0x806E - 0x8077 Landmark Graphics Corp. */
+#define ETHERTYPE_MATRA 0x807A /* Matra */
+#define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */
+#define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */
+ /* 0x807D - 0x807F Vitalink Communications */
+#define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */
+ /* 0x8081 - 0x8083 Counterpoint Computers */
+ /* 0x8088 - 0x808A Xyplex */
+#define ETHERTYPE_ATALK 0x809B /* AppleTalk */
+#define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */
+#define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */
+ /* 0x809C - 0x809E Datability */
+#define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */
+ /* 0x80A3 Nixdorf */
+ /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */
+ /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */
+ /* 0x80C4 - 0x80C5 Banyan Systems */
+#define ETHERTYPE_PACER 0x80C6 /* Pacer Software */
+#define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */
+ /* 0x80C8 - 0x80CC Intergraph Corporation */
+ /* 0x80CD - 0x80CE Harris Corporation */
+ /* 0x80CF - 0x80D2 Taylor Instrument */
+ /* 0x80D3 - 0x80D4 Rosemount Corporation */
+#define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */
+#define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */
+ /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */
+ /* 0x80E0 - 0x80E3 Allen-Bradley */
+ /* 0x80E4 - 0x80F0 Datability */
+#define ETHERTYPE_RETIX 0x80F2 /* Retix */
+#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */
+ /* 0x80F4 - 0x80F5 Kinetics */
+#define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */
+#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+ /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */
+#define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */
+#define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */
+ /* 0x8107 - 0x8109 Symbolics Private */
+#define ETHERTYPE_TALARIS 0x812B /* Talaris */
+#define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */
+#define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */
+#define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */
+ /* 0x8132 - 0x8137 Bridge Communications */
+#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */
+#define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */
+ /* 0x8139 - 0x813D KTI */
+#define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */
+#define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */
+#define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */
+#define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */
+#define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */
+#define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */
+#define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */
+#define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */
+ /* 0x814D - 0x814E BIIN */
+#define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */
+#define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */
+ /* 0x8151 - 0x8153 Qualcomm */
+ /* 0x815C - 0x815E Computer Protocol Pty Ltd */
+ /* 0x8164 - 0x8166 Charles River Data Systems */
+#define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */
+#define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */
+#define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */
+#define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */
+ /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */
+ /* 0x8184 - 0x818C SGI prop. */
+#define ETHERTYPE_MOTOROLA 0x818D /* Motorola */
+#define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */
+ /* 0x819A - 0x81A3 RAD Network Devices */
+ /* 0x81B7 - 0x81B9 Xyplex */
+ /* 0x81CC - 0x81D5 Apricot Computers */
+ /* 0x81D6 - 0x81DD Artisoft Lantastic */
+ /* 0x81E6 - 0x81EF Polygon */
+ /* 0x81F0 - 0x81F2 Comsat Labs */
+ /* 0x81F3 - 0x81F5 SAIC */
+ /* 0x81F6 - 0x81F8 VG Analytical */
+ /* 0x8203 - 0x8205 QNX Software Systems Ltd. */
+ /* 0x8221 - 0x8222 Ascom Banking Systems */
+ /* 0x823E - 0x8240 Advanced Encryption Systems */
+ /* 0x8263 - 0x826A Charles River Data Systems */
+ /* 0x827F - 0x8282 Athena Programming */
+ /* 0x829A - 0x829B Inst Ind Info Tech */
+ /* 0x829C - 0x82AB Taurus Controls */
+ /* 0x82AC - 0x8693 Walker Richer & Quinn */
+#define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */
+#define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */
+#define ETHERTYPE_KALPANA 0x8582 /* Kalpana */
+ /* 0x8694 - 0x869D Idea Courier */
+ /* 0x869E - 0x86A1 Computer Network Tech */
+ /* 0x86A3 - 0x86AC Gateway Communications */
+#define ETHERTYPE_SECTRA 0x86DB /* SECTRA */
+#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */
+#define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */
+#define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */
+ /* 0x86E0 - 0x86EF Landis & Gyr Powers */
+ /* 0x8700 - 0x8710 Motorola */
+#define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */
+#define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */
+ /* 0x873B - 0x873C Control Technology Inc. Proprietary */
+#define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */
+#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */
+#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */
+#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */
+#define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */
+#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPoE) */
+#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */
+#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */
+#define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */
+#define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */
+#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
+#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
+#define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */
+#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
+#define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */
+#define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */
+#define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */
+#define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */
+#define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */
+#define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */
+#define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */
+#define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */
+ /* 0xFF00 - 0xFFOF ISC Bunker Ramo */
+
+#define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
+/*
+ * The ETHER_BPF_MTAP macro should be used by drivers which support hardware
+ * offload for VLAN tag processing. It will check the mbuf to see if it has
+ * M_VLANTAG set, and if it does, will pass the packet along to
+ * ether_vlan_mtap. This function will re-insert VLAN tags for the duration
+ * of the tap, so they show up properly for network analyzers.
+ */
+#define ETHER_BPF_MTAP(_ifp, _m) do { \
+ if (bpf_peers_present((_ifp)->if_bpf)) { \
+ M_ASSERTVALID(_m); \
+ if (((_m)->m_flags & M_VLANTAG) != 0) \
+ ether_vlan_mtap((_ifp)->if_bpf, (_m), NULL, 0); \
+ else \
+ bpf_mtap((_ifp)->if_bpf, (_m)); \
+ } \
+} while (0)
+
+#ifdef _KERNEL
+
+struct ifnet;
+struct mbuf;
+struct route;
+struct sockaddr;
+struct bpf_if;
+
+extern uint32_t ether_crc32_le(const uint8_t *, size_t);
+extern uint32_t ether_crc32_be(const uint8_t *, size_t);
+extern void ether_demux(struct ifnet *, struct mbuf *);
+extern void ether_ifattach(struct ifnet *, const u_int8_t *);
+extern void ether_ifdetach(struct ifnet *);
+extern int ether_ioctl(struct ifnet *, u_long, caddr_t);
+extern int ether_output(struct ifnet *, struct mbuf *,
+ const struct sockaddr *, struct route *);
+extern int ether_output_frame(struct ifnet *, struct mbuf *);
+extern char *ether_sprintf(const u_int8_t *);
+void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
+ void *, u_int);
+struct mbuf *ether_vlanencap(struct mbuf *, uint16_t);
+
+#else /* _KERNEL */
+
+#include <sys/cdefs.h>
+
+/*
+ * Ethernet address conversion/parsing routines.
+ */
+__BEGIN_DECLS
+struct ether_addr *ether_aton(const char *);
+struct ether_addr *ether_aton_r(const char *, struct ether_addr *);
+int ether_hostton(const char *, struct ether_addr *);
+int ether_line(const char *, struct ether_addr *, char *);
+char *ether_ntoa(const struct ether_addr *);
+char *ether_ntoa_r(const struct ether_addr *, char *);
+int ether_ntohost(char *, const struct ether_addr *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_NET_ETHERNET_H_ */
diff --git a/usr/src/boot/include/net/if.h b/usr/src/boot/include/net/if.h
new file mode 100644
index 0000000000..792704afd2
--- /dev/null
+++ b/usr/src/boot/include/net/if.h
@@ -0,0 +1,548 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)if.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NET_IF_H_
+#define _NET_IF_H_
+
+#include <sys/cdefs.h>
+
+#if __BSD_VISIBLE
+/*
+ * <net/if.h> does not depend on <sys/time.h> on most other systems. This
+ * helps userland compatibility. (struct timeval ifi_lastchange)
+ * The same holds for <sys/socket.h>. (struct sockaddr ifru_addr)
+ */
+#ifndef _KERNEL
+#include <sys/time.h>
+#include <sys/socket.h>
+#endif
+#endif
+
+/*
+ * Length of interface external name, including terminating '\0'.
+ * Note: this is the same size as a generic device's external name.
+ */
+#define IF_NAMESIZE 16
+#if __BSD_VISIBLE
+#define IFNAMSIZ IF_NAMESIZE
+#define IF_MAXUNIT 0x7fff /* historical value */
+#endif
+#if __BSD_VISIBLE
+
+/*
+ * Structure used to query names of interface cloners.
+ */
+
+struct if_clonereq {
+ int ifcr_total; /* total cloners (out) */
+ int ifcr_count; /* room for this many in user buffer */
+ char *ifcr_buffer; /* buffer for cloner names */
+};
+
+/*
+ * Structure describing information about an interface
+ * which may be of interest to management entities.
+ */
+struct if_data {
+ /* generic interface information */
+ uint8_t ifi_type; /* ethernet, tokenring, etc */
+ uint8_t ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */
+ uint8_t ifi_addrlen; /* media address length */
+ uint8_t ifi_hdrlen; /* media header length */
+ uint8_t ifi_link_state; /* current link state */
+ uint8_t ifi_vhid; /* carp vhid */
+ uint16_t ifi_datalen; /* length of this data struct */
+ uint32_t ifi_mtu; /* maximum transmission unit */
+ uint32_t ifi_metric; /* routing metric (external only) */
+ uint64_t ifi_baudrate; /* linespeed */
+ /* volatile statistics */
+ uint64_t ifi_ipackets; /* packets received on interface */
+ uint64_t ifi_ierrors; /* input errors on interface */
+ uint64_t ifi_opackets; /* packets sent on interface */
+ uint64_t ifi_oerrors; /* output errors on interface */
+ uint64_t ifi_collisions; /* collisions on csma interfaces */
+ uint64_t ifi_ibytes; /* total number of octets received */
+ uint64_t ifi_obytes; /* total number of octets sent */
+ uint64_t ifi_imcasts; /* packets received via multicast */
+ uint64_t ifi_omcasts; /* packets sent via multicast */
+ uint64_t ifi_iqdrops; /* dropped on input */
+ uint64_t ifi_oqdrops; /* dropped on output */
+ uint64_t ifi_noproto; /* destined for unsupported protocol */
+ uint64_t ifi_hwassist; /* HW offload capabilities, see IFCAP */
+
+ /* Unions are here to make sizes MI. */
+ union { /* uptime at attach or stat reset */
+ time_t tt;
+ uint64_t ph;
+ } __ifi_epoch;
+#define ifi_epoch __ifi_epoch.tt
+ union { /* time of last administrative change */
+ struct timeval tv;
+ struct {
+ uint64_t ph1;
+ uint64_t ph2;
+ } ph;
+ } __ifi_lastchange;
+#define ifi_lastchange __ifi_lastchange.tv
+};
+
+/*-
+ * Interface flags are of two types: network stack owned flags, and driver
+ * owned flags. Historically, these values were stored in the same ifnet
+ * flags field, but with the advent of fine-grained locking, they have been
+ * broken out such that the network stack is responsible for synchronizing
+ * the stack-owned fields, and the device driver the device-owned fields.
+ * Both halves can perform lockless reads of the other half's field, subject
+ * to accepting the involved races.
+ *
+ * Both sets of flags come from the same number space, and should not be
+ * permitted to conflict, as they are exposed to user space via a single
+ * field.
+ *
+ * The following symbols identify read and write requirements for fields:
+ *
+ * (i) if_flags field set by device driver before attach, read-only there
+ * after.
+ * (n) if_flags field written only by the network stack, read by either the
+ * stack or driver.
+ * (d) if_drv_flags field written only by the device driver, read by either
+ * the stack or driver.
+ */
+#define IFF_UP 0x1 /* (n) interface is up */
+#define IFF_BROADCAST 0x2 /* (i) broadcast address valid */
+#define IFF_DEBUG 0x4 /* (n) turn on debugging */
+#define IFF_LOOPBACK 0x8 /* (i) is a loopback net */
+#define IFF_POINTOPOINT 0x10 /* (i) is a point-to-point link */
+/* 0x20 was IFF_SMART */
+#define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */
+#define IFF_NOARP 0x80 /* (n) no address resolution protocol */
+#define IFF_PROMISC 0x100 /* (n) receive all packets */
+#define IFF_ALLMULTI 0x200 /* (n) receive all multicast packets */
+#define IFF_DRV_OACTIVE 0x400 /* (d) tx hardware queue is full */
+#define IFF_SIMPLEX 0x800 /* (i) can't hear own transmissions */
+#define IFF_LINK0 0x1000 /* per link layer defined bit */
+#define IFF_LINK1 0x2000 /* per link layer defined bit */
+#define IFF_LINK2 0x4000 /* per link layer defined bit */
+#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
+#define IFF_MULTICAST 0x8000 /* (i) supports multicast */
+#define IFF_CANTCONFIG 0x10000 /* (i) unconfigurable using ioctl(2) */
+#define IFF_PPROMISC 0x20000 /* (n) user-requested promisc mode */
+#define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */
+#define IFF_STATICARP 0x80000 /* (n) static ARP */
+#define IFF_DYING 0x200000 /* (n) interface is winding down */
+#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */
+/*
+ * Old names for driver flags so that user space tools can continue to use
+ * the old (portable) names.
+ */
+#ifndef _KERNEL
+#define IFF_RUNNING IFF_DRV_RUNNING
+#define IFF_OACTIVE IFF_DRV_OACTIVE
+#endif
+
+/* flags set internally only: */
+#define IFF_CANTCHANGE \
+ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\
+ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC|\
+ IFF_DYING|IFF_CANTCONFIG)
+
+/*
+ * Values for if_link_state.
+ */
+#define LINK_STATE_UNKNOWN 0 /* link invalid/unknown */
+#define LINK_STATE_DOWN 1 /* link is down */
+#define LINK_STATE_UP 2 /* link is up */
+
+/*
+ * Some convenience macros used for setting ifi_baudrate.
+ * XXX 1000 vs. 1024? --thorpej@netbsd.org
+ */
+#define IF_Kbps(x) ((uintmax_t)(x) * 1000) /* kilobits/sec. */
+#define IF_Mbps(x) (IF_Kbps((x) * 1000)) /* megabits/sec. */
+#define IF_Gbps(x) (IF_Mbps((x) * 1000)) /* gigabits/sec. */
+
+/*
+ * Capabilities that interfaces can advertise.
+ *
+ * struct ifnet.if_capabilities
+ * contains the optional features & capabilities a particular interface
+ * supports (not only the driver but also the detected hw revision).
+ * Capabilities are defined by IFCAP_* below.
+ * struct ifnet.if_capenable
+ * contains the enabled (either by default or through ifconfig) optional
+ * features & capabilities on this interface.
+ * Capabilities are defined by IFCAP_* below.
+ * struct if_data.ifi_hwassist in mbuf CSUM_ flag form, controlled by above
+ * contains the enabled optional feature & capabilites that can be used
+ * individually per packet and are specified in the mbuf pkthdr.csum_flags
+ * field. IFCAP_* and CSUM_* do not match one to one and CSUM_* may be
+ * more detailed or differenciated than IFCAP_*.
+ * Hwassist features are defined CSUM_* in sys/mbuf.h
+ *
+ * Capabilities that cannot be arbitrarily changed with ifconfig/ioctl
+ * are listed in IFCAP_CANTCHANGE, similar to IFF_CANTCHANGE.
+ * This is not strictly necessary because the common code never
+ * changes capabilities, and it is left to the individual driver
+ * to do the right thing. However, having the filter here
+ * avoids replication of the same code in all individual drivers.
+ */
+#define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */
+#define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */
+#define IFCAP_NETCONS 0x00004 /* can be a network console */
+#define IFCAP_VLAN_MTU 0x00008 /* VLAN-compatible MTU */
+#define IFCAP_VLAN_HWTAGGING 0x00010 /* hardware VLAN tag support */
+#define IFCAP_JUMBO_MTU 0x00020 /* 9000 byte MTU supported */
+#define IFCAP_POLLING 0x00040 /* driver supports polling */
+#define IFCAP_VLAN_HWCSUM 0x00080 /* can do IFCAP_HWCSUM on VLANs */
+#define IFCAP_TSO4 0x00100 /* can do TCP Segmentation Offload */
+#define IFCAP_TSO6 0x00200 /* can do TCP6 Segmentation Offload */
+#define IFCAP_LRO 0x00400 /* can do Large Receive Offload */
+#define IFCAP_WOL_UCAST 0x00800 /* wake on any unicast frame */
+#define IFCAP_WOL_MCAST 0x01000 /* wake on any multicast frame */
+#define IFCAP_WOL_MAGIC 0x02000 /* wake on any Magic Packet */
+#define IFCAP_TOE4 0x04000 /* interface can offload TCP */
+#define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */
+#define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */
+#define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */
+#define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */
+#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */
+#define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */
+#define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */
+#define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */
+#define IFCAP_HWSTATS 0x800000 /* manages counters internally */
+
+#define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6)
+
+#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM)
+#define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6)
+#define IFCAP_WOL (IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC)
+#define IFCAP_TOE (IFCAP_TOE4 | IFCAP_TOE6)
+
+#define IFCAP_CANTCHANGE (IFCAP_NETMAP)
+
+#define IFQ_MAXLEN 50
+#define IFNET_SLOWHZ 1 /* granularity is 1 second */
+
+/*
+ * Message format for use in obtaining information about interfaces
+ * from getkerninfo and the routing socket
+ * For the new, extensible interface see struct if_msghdrl below.
+ */
+struct if_msghdr {
+ u_short ifm_msglen; /* to skip over non-understood messages */
+ u_char ifm_version; /* future binary compatibility */
+ u_char ifm_type; /* message type */
+ int ifm_addrs; /* like rtm_addrs */
+ int ifm_flags; /* value of if_flags */
+ u_short ifm_index; /* index for associated ifp */
+ struct if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifm_data_off or within ifm_data. Both the if_msghdr and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct if_msghdrl given a pointer to struct if_msghdrl.
+ */
+#define IF_MSGHDRL_IFM_DATA(_l) \
+ (struct if_data *)((char *)(_l) + (_l)->ifm_data_off)
+#define IF_MSGHDRL_RTA(_l) \
+ (void *)((uintptr_t)(_l) + (_l)->ifm_len)
+struct if_msghdrl {
+ u_short ifm_msglen; /* to skip over non-understood messages */
+ u_char ifm_version; /* future binary compatibility */
+ u_char ifm_type; /* message type */
+ int ifm_addrs; /* like rtm_addrs */
+ int ifm_flags; /* value of if_flags */
+ u_short ifm_index; /* index for associated ifp */
+ u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */
+ u_short ifm_len; /* length of if_msghdrl incl. if_data */
+ u_short ifm_data_off; /* offset of if_data from beginning */
+ struct if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
+ * Message format for use in obtaining information about interface addresses
+ * from getkerninfo and the routing socket
+ * For the new, extensible interface see struct ifa_msghdrl below.
+ */
+struct ifa_msghdr {
+ u_short ifam_msglen; /* to skip over non-understood messages */
+ u_char ifam_version; /* future binary compatibility */
+ u_char ifam_type; /* message type */
+ int ifam_addrs; /* like rtm_addrs */
+ int ifam_flags; /* value of ifa_flags */
+ u_short ifam_index; /* index for associated ifp */
+ int ifam_metric; /* value of ifa_ifp->if_metric */
+};
+
+/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifam_metric or within ifam_data. Both the ifa_msghdrl and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct ifa_msghdrl given a pointer to struct ifa_msghdrl.
+ */
+#define IFA_MSGHDRL_IFAM_DATA(_l) \
+ (struct if_data *)((char *)(_l) + (_l)->ifam_data_off)
+#define IFA_MSGHDRL_RTA(_l) \
+ (void *)((uintptr_t)(_l) + (_l)->ifam_len)
+struct ifa_msghdrl {
+ u_short ifam_msglen; /* to skip over non-understood messages */
+ u_char ifam_version; /* future binary compatibility */
+ u_char ifam_type; /* message type */
+ int ifam_addrs; /* like rtm_addrs */
+ int ifam_flags; /* value of ifa_flags */
+ u_short ifam_index; /* index for associated ifp */
+ u_short _ifam_spare1; /* spare space to grow if_index, see if_var.h */
+ u_short ifam_len; /* length of ifa_msghdrl incl. if_data */
+ u_short ifam_data_off; /* offset of if_data from beginning */
+ int ifam_metric; /* value of ifa_ifp->if_metric */
+ struct if_data ifam_data;/* statistics and other data about if or
+ * address */
+};
+
+/*
+ * Message format for use in obtaining information about multicast addresses
+ * from the routing socket
+ */
+struct ifma_msghdr {
+ u_short ifmam_msglen; /* to skip over non-understood messages */
+ u_char ifmam_version; /* future binary compatibility */
+ u_char ifmam_type; /* message type */
+ int ifmam_addrs; /* like rtm_addrs */
+ int ifmam_flags; /* value of ifa_flags */
+ u_short ifmam_index; /* index for associated ifp */
+};
+
+/*
+ * Message format announcing the arrival or departure of a network interface.
+ */
+struct if_announcemsghdr {
+ u_short ifan_msglen; /* to skip over non-understood messages */
+ u_char ifan_version; /* future binary compatibility */
+ u_char ifan_type; /* message type */
+ u_short ifan_index; /* index for associated ifp */
+ char ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ u_short ifan_what; /* what type of announcement */
+};
+
+#define IFAN_ARRIVAL 0 /* interface arrival */
+#define IFAN_DEPARTURE 1 /* interface departure */
+
+/*
+ * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests
+ */
+struct ifreq_buffer {
+ size_t length;
+ void *buffer;
+};
+
+/*
+ * Interface request structure used for socket
+ * ioctl's. All interface ioctl's must have parameter
+ * definitions which begin with ifr_name. The
+ * remainder may be interface specific.
+ */
+struct ifreq {
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct ifreq_buffer ifru_buffer;
+ short ifru_flags[2];
+ short ifru_index;
+ int ifru_jid;
+ int ifru_metric;
+ int ifru_mtu;
+ int ifru_phys;
+ int ifru_media;
+ caddr_t ifru_data;
+ int ifru_cap[2];
+ u_int ifru_fib;
+ } ifr_ifru;
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_buffer ifr_ifru.ifru_buffer /* user supplied buffer with its length */
+#define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */
+#define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */
+#define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
+#define ifr_media ifr_ifru.ifru_media /* physical media */
+#define ifr_data ifr_ifru.ifru_data /* for use by interface */
+#define ifr_reqcap ifr_ifru.ifru_cap[0] /* requested capabilities */
+#define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */
+#define ifr_index ifr_ifru.ifru_index /* interface index */
+#define ifr_fib ifr_ifru.ifru_fib /* interface fib */
+};
+
+#define _SIZEOF_ADDR_IFREQ(ifr) \
+ ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
+ (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
+ (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))
+
+struct ifaliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr ifra_addr;
+ struct sockaddr ifra_broadaddr;
+ struct sockaddr ifra_mask;
+ int ifra_vhid;
+};
+
+/* 9.x compat */
+struct oifaliasreq {
+ char ifra_name[IFNAMSIZ];
+ struct sockaddr ifra_addr;
+ struct sockaddr ifra_broadaddr;
+ struct sockaddr ifra_mask;
+};
+
+struct ifmediareq {
+ char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ int ifm_current; /* current media options */
+ int ifm_mask; /* don't care mask */
+ int ifm_status; /* media status */
+ int ifm_active; /* active options */
+ int ifm_count; /* # entries in ifm_ulist array */
+ int *ifm_ulist; /* media words */
+};
+
+struct ifdrv {
+ char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ unsigned long ifd_cmd;
+ size_t ifd_len;
+ void *ifd_data;
+};
+
+/*
+ * Structure used to retrieve aux status data from interfaces.
+ * Kernel suppliers to this interface should respect the formatting
+ * needed by ifconfig(8): each line starts with a TAB and ends with
+ * a newline. The canonical example to copy and paste is in if_tun.c.
+ */
+
+#define IFSTATMAX 800 /* 10 lines of text */
+struct ifstat {
+ char ifs_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ char ascii[IFSTATMAX + 1];
+};
+
+/*
+ * Structure used in SIOCGIFCONF request.
+ * Used to retrieve interface configuration
+ * for machine (useful for programs which
+ * must know all networks accessible).
+ */
+struct ifconf {
+ int ifc_len; /* size of associated buffer */
+ union {
+ caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
+};
+
+/*
+ * interface groups
+ */
+
+#define IFG_ALL "all" /* group contains all interfaces */
+/* XXX: will we implement this? */
+#define IFG_EGRESS "egress" /* if(s) default route(s) point to */
+
+struct ifg_req {
+ union {
+ char ifgrqu_group[IFNAMSIZ];
+ char ifgrqu_member[IFNAMSIZ];
+ } ifgrq_ifgrqu;
+#define ifgrq_group ifgrq_ifgrqu.ifgrqu_group
+#define ifgrq_member ifgrq_ifgrqu.ifgrqu_member
+};
+
+/*
+ * Used to lookup groups for an interface
+ */
+struct ifgroupreq {
+ char ifgr_name[IFNAMSIZ];
+ u_int ifgr_len;
+ union {
+ char ifgru_group[IFNAMSIZ];
+ struct ifg_req *ifgru_groups;
+ } ifgr_ifgru;
+#define ifgr_group ifgr_ifgru.ifgru_group
+#define ifgr_groups ifgr_ifgru.ifgru_groups
+};
+
+/*
+ * Structure used to request i2c data
+ * from interface transceivers.
+ */
+struct ifi2creq {
+ uint8_t dev_addr; /* i2c address (0xA0, 0xA2) */
+ uint8_t offset; /* read offset */
+ uint8_t len; /* read length */
+ uint8_t spare0;
+ uint32_t spare1;
+ uint8_t data[8]; /* read buffer */
+};
+
+#endif /* __BSD_VISIBLE */
+
+#ifdef _KERNEL
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_IFADDR);
+MALLOC_DECLARE(M_IFMADDR);
+#endif
+#endif
+
+#ifndef _KERNEL
+struct if_nameindex {
+ unsigned int if_index; /* 1, 2, ... */
+ char *if_name; /* null terminated name: "le0", ... */
+};
+
+__BEGIN_DECLS
+void if_freenameindex(struct if_nameindex *);
+char *if_indextoname(unsigned int, char *);
+struct if_nameindex *if_nameindex(void);
+unsigned int if_nametoindex(const char *);
+__END_DECLS
+#endif
+#endif /* !_NET_IF_H_ */
diff --git a/usr/src/boot/include/net/if_arp.h b/usr/src/boot/include/net/if_arp.h
new file mode 100644
index 0000000000..7d141f3771
--- /dev/null
+++ b/usr/src/boot/include/net/if_arp.h
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)if_arp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NET_IF_ARP_H_
+#define _NET_IF_ARP_H_
+
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified. Field names used correspond to RFC 826.
+ */
+struct arphdr {
+ u_short ar_hrd; /* format of hardware address */
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+#define ARPHRD_IEEE802 6 /* token-ring hardware format */
+#define ARPHRD_ARCNET 7 /* arcnet hardware format */
+#define ARPHRD_FRELAY 15 /* frame relay hardware format */
+#define ARPHRD_IEEE1394 24 /* firewire hardware format */
+#define ARPHRD_INFINIBAND 32 /* infiniband hardware format */
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol address */
+ u_short ar_op; /* one of: */
+#define ARPOP_REQUEST 1 /* request to resolve address */
+#define ARPOP_REPLY 2 /* response to previous request */
+#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* response giving protocol address */
+#define ARPOP_INVREQUEST 8 /* request to identify peer */
+#define ARPOP_INVREPLY 9 /* response identifying peer */
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_char ar_sha[]; /* sender hardware address */
+ u_char ar_spa[]; /* sender protocol address */
+ u_char ar_tha[]; /* target hardware address */
+ u_char ar_tpa[]; /* target protocol address */
+#endif
+};
+
+#define ar_sha(ap) (((caddr_t)((ap)+1)) + 0)
+#define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln)
+#define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln)
+#define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)
+
+#define arphdr_len2(ar_hln, ar_pln) \
+ (sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln))
+#define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln))
+
+/*
+ * ARP ioctl request
+ */
+struct arpreq {
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+};
+/* arp_flags and at_flags field values */
+#define ATF_INUSE 0x01 /* entry in use */
+#define ATF_COM 0x02 /* completed entry (enaddr valid) */
+#define ATF_PERM 0x04 /* permanent entry */
+#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
+#define ATF_USETRAILERS 0x10 /* has requested trailers */
+
+struct arpstat {
+ /* Normal things that happen: */
+ uint64_t txrequests; /* # of ARP requests sent by this host. */
+ uint64_t txreplies; /* # of ARP replies sent by this host. */
+ uint64_t rxrequests; /* # of ARP requests received by this host. */
+ uint64_t rxreplies; /* # of ARP replies received by this host. */
+ uint64_t received; /* # of ARP packets received by this host. */
+
+ uint64_t arp_spares[4]; /* For either the upper or lower half. */
+ /* Abnormal event and error counting: */
+ uint64_t dropped; /* # of packets dropped waiting for a reply. */
+ uint64_t timeouts; /* # of times with entries removed */
+ /* due to timeout. */
+ uint64_t dupips; /* # of duplicate IPs detected. */
+};
+
+#ifdef _KERNEL
+#include <sys/counter.h>
+#include <net/vnet.h>
+
+VNET_PCPUSTAT_DECLARE(struct arpstat, arpstat);
+/*
+ * In-kernel consumers can use these accessor macros directly to update
+ * stats.
+ */
+#define ARPSTAT_ADD(name, val) \
+ VNET_PCPUSTAT_ADD(struct arpstat, arpstat, name, (val))
+#define ARPSTAT_SUB(name, val) ARPSTAT_ADD(name, -(val))
+#define ARPSTAT_INC(name) ARPSTAT_ADD(name, 1)
+#define ARPSTAT_DEC(name) ARPSTAT_SUB(name, 1)
+
+#endif /* _KERNEL */
+
+#endif /* !_NET_IF_ARP_H_ */
diff --git a/usr/src/boot/include/netinet/if_ether.h b/usr/src/boot/include/netinet/if_ether.h
new file mode 100644
index 0000000000..f23da5b2e5
--- /dev/null
+++ b/usr/src/boot/include/netinet/if_ether.h
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ /* struct in_addr *ipaddr; */ \
+ /* u_char enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((const u_char *)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((const u_char *)ipaddr)[2]; \
+ (enaddr)[5] = ((const u_char *)ipaddr)[3]; \
+}
+/*
+ * Macro to map an IP6 multicast address to an Ethernet multicast address.
+ * The high-order 16 bits of the Ethernet address are statically assigned,
+ * and the low-order 32 bits are taken from the low end of the IP6 address.
+ */
+#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \
+/* struct in6_addr *ip6addr; */ \
+/* u_char enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x33; \
+ (enaddr)[1] = 0x33; \
+ (enaddr)[2] = ((const u_char *)ip6addr)[12]; \
+ (enaddr)[3] = ((const u_char *)ip6addr)[13]; \
+ (enaddr)[4] = ((const u_char *)ip6addr)[14]; \
+ (enaddr)[5] = ((const u_char *)ip6addr)[15]; \
+}
+
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_char arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
+ u_char arp_spa[4]; /* sender protocol address */
+ u_char arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
+ u_char arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+#ifndef BURN_BRIDGES /* Can be used by third party software. */
+struct sockaddr_inarp {
+ u_char sin_len;
+ u_char sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ struct in_addr sin_srcaddr;
+ u_short sin_tos;
+ u_short sin_other;
+#define SIN_PROXY 1
+};
+#endif /* !BURN_BRIDGES */
+
+/*
+ * IP and ethernet specific routing flags
+ */
+#define RTF_USETRAILERS RTF_PROTO1 /* use trailers */
+#define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */
+
+#ifdef _KERNEL
+extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN];
+extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
+
+struct ifaddr;
+
+int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
+ const struct sockaddr *dst, u_char *desten, uint32_t *pflags);
+void arprequest(struct ifnet *, const struct in_addr *,
+ const struct in_addr *, u_char *);
+void arp_ifinit(struct ifnet *, struct ifaddr *);
+void arp_ifinit2(struct ifnet *, struct ifaddr *, u_char *);
+#endif
+
+#endif
diff --git a/usr/src/boot/include/netinet/in.h b/usr/src/boot/include/netinet/in.h
new file mode 100644
index 0000000000..325b523320
--- /dev/null
+++ b/usr/src/boot/include/netinet/in.h
@@ -0,0 +1,669 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IN_H_
+#define _NETINET_IN_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <machine/endian.h>
+
+/* Protocols common to RFC 1700, POSIX, and X/Open. */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+
+#define INADDR_ANY ((in_addr_t)0x00000000)
+#define INADDR_BROADCAST ((in_addr_t)0xffffffff) /* must be masked */
+
+#ifndef _UINT8_T_DECLARED
+typedef __uint8_t uint8_t;
+#define _UINT8_T_DECLARED
+#endif
+
+#ifndef _UINT16_T_DECLARED
+typedef __uint16_t uint16_t;
+#define _UINT16_T_DECLARED
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef uint32_t in_addr_t;
+#define _IN_ADDR_T_DECLARED
+#endif
+
+#ifndef _IN_PORT_T_DECLARED
+typedef uint16_t in_port_t;
+#define _IN_PORT_T_DECLARED
+#endif
+
+#ifndef _SA_FAMILY_T_DECLARED
+typedef __sa_family_t sa_family_t;
+#define _SA_FAMILY_T_DECLARED
+#endif
+
+/* Internet address (a structure for historical reasons). */
+#ifndef _STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+ in_addr_t s_addr;
+};
+#define _STRUCT_IN_ADDR_DECLARED
+#endif
+
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#include <sys/_sockaddr_storage.h>
+
+/* Socket address, internet style. */
+struct sockaddr_in {
+ uint8_t sin_len;
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+#if !defined(_KERNEL) && __POSIX_VISIBLE >= 200112
+
+#ifndef _BYTEORDER_PROTOTYPED
+#define _BYTEORDER_PROTOTYPED
+__BEGIN_DECLS
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+__END_DECLS
+#endif
+
+#ifndef _BYTEORDER_FUNC_DEFINED
+#define _BYTEORDER_FUNC_DEFINED
+#define htonl(x) __htonl(x)
+#define htons(x) __htons(x)
+#define ntohl(x) __ntohl(x)
+#define ntohs(x) __ntohs(x)
+#endif
+
+#endif /* !_KERNEL && __POSIX_VISIBLE >= 200112 */
+
+#if __POSIX_VISIBLE >= 200112
+#define IPPROTO_IPV6 41 /* IP6 header */
+#define IPPROTO_RAW 255 /* raw IP packet */
+#define INET_ADDRSTRLEN 16
+#endif
+
+#if __BSD_VISIBLE
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981, and numerous additions.
+ */
+
+/*
+ * Protocols (RFC 1700)
+ */
+#define IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */
+#define IPPROTO_IGMP 2 /* group mgmt protocol */
+#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
+#define IPPROTO_IPV4 4 /* IPv4 encapsulation */
+#define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */
+#define IPPROTO_ST 7 /* Stream protocol II */
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#define IPPROTO_PIGP 9 /* private interior gateway */
+#define IPPROTO_RCCMON 10 /* BBN RCC Monitoring */
+#define IPPROTO_NVPII 11 /* network voice protocol*/
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_ARGUS 13 /* Argus */
+#define IPPROTO_EMCON 14 /* EMCON */
+#define IPPROTO_XNET 15 /* Cross Net Debugger */
+#define IPPROTO_CHAOS 16 /* Chaos*/
+#define IPPROTO_MUX 18 /* Multiplexing */
+#define IPPROTO_MEAS 19 /* DCN Measurement Subsystems */
+#define IPPROTO_HMP 20 /* Host Monitoring */
+#define IPPROTO_PRM 21 /* Packet Radio Measurement */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_TRUNK1 23 /* Trunk-1 */
+#define IPPROTO_TRUNK2 24 /* Trunk-2 */
+#define IPPROTO_LEAF1 25 /* Leaf-1 */
+#define IPPROTO_LEAF2 26 /* Leaf-2 */
+#define IPPROTO_RDP 27 /* Reliable Data */
+#define IPPROTO_IRTP 28 /* Reliable Transaction */
+#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
+#define IPPROTO_BLT 30 /* Bulk Data Transfer */
+#define IPPROTO_NSP 31 /* Network Services */
+#define IPPROTO_INP 32 /* Merit Internodal */
+#define IPPROTO_SEP 33 /* Sequential Exchange */
+#define IPPROTO_3PC 34 /* Third Party Connect */
+#define IPPROTO_IDPR 35 /* InterDomain Policy Routing */
+#define IPPROTO_XTP 36 /* XTP */
+#define IPPROTO_DDP 37 /* Datagram Delivery */
+#define IPPROTO_CMTP 38 /* Control Message Transport */
+#define IPPROTO_TPXX 39 /* TP++ Transport */
+#define IPPROTO_IL 40 /* IL transport protocol */
+#define IPPROTO_SDRP 42 /* Source Demand Routing */
+#define IPPROTO_ROUTING 43 /* IP6 routing header */
+#define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */
+#define IPPROTO_IDRP 45 /* InterDomain Routing*/
+#define IPPROTO_RSVP 46 /* resource reservation */
+#define IPPROTO_GRE 47 /* General Routing Encap. */
+#define IPPROTO_MHRP 48 /* Mobile Host Routing */
+#define IPPROTO_BHA 49 /* BHA */
+#define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */
+#define IPPROTO_AH 51 /* IP6 Auth Header */
+#define IPPROTO_INLSP 52 /* Integ. Net Layer Security */
+#define IPPROTO_SWIPE 53 /* IP with encryption */
+#define IPPROTO_NHRP 54 /* Next Hop Resolution */
+#define IPPROTO_MOBILE 55 /* IP Mobility */
+#define IPPROTO_TLSP 56 /* Transport Layer Security */
+#define IPPROTO_SKIP 57 /* SKIP */
+#define IPPROTO_ICMPV6 58 /* ICMP6 */
+#define IPPROTO_NONE 59 /* IP6 no next header */
+#define IPPROTO_DSTOPTS 60 /* IP6 destination option */
+#define IPPROTO_AHIP 61 /* any host internal protocol */
+#define IPPROTO_CFTP 62 /* CFTP */
+#define IPPROTO_HELLO 63 /* "hello" routing protocol */
+#define IPPROTO_SATEXPAK 64 /* SATNET/Backroom EXPAK */
+#define IPPROTO_KRYPTOLAN 65 /* Kryptolan */
+#define IPPROTO_RVD 66 /* Remote Virtual Disk */
+#define IPPROTO_IPPC 67 /* Pluribus Packet Core */
+#define IPPROTO_ADFS 68 /* Any distributed FS */
+#define IPPROTO_SATMON 69 /* Satnet Monitoring */
+#define IPPROTO_VISA 70 /* VISA Protocol */
+#define IPPROTO_IPCV 71 /* Packet Core Utility */
+#define IPPROTO_CPNX 72 /* Comp. Prot. Net. Executive */
+#define IPPROTO_CPHB 73 /* Comp. Prot. HeartBeat */
+#define IPPROTO_WSN 74 /* Wang Span Network */
+#define IPPROTO_PVP 75 /* Packet Video Protocol */
+#define IPPROTO_BRSATMON 76 /* BackRoom SATNET Monitoring */
+#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */
+#define IPPROTO_WBMON 78 /* WIDEBAND Monitoring */
+#define IPPROTO_WBEXPAK 79 /* WIDEBAND EXPAK */
+#define IPPROTO_EON 80 /* ISO cnlp */
+#define IPPROTO_VMTP 81 /* VMTP */
+#define IPPROTO_SVMTP 82 /* Secure VMTP */
+#define IPPROTO_VINES 83 /* Banyon VINES */
+#define IPPROTO_TTP 84 /* TTP */
+#define IPPROTO_IGP 85 /* NSFNET-IGP */
+#define IPPROTO_DGP 86 /* dissimilar gateway prot. */
+#define IPPROTO_TCF 87 /* TCF */
+#define IPPROTO_IGRP 88 /* Cisco/GXS IGRP */
+#define IPPROTO_OSPFIGP 89 /* OSPFIGP */
+#define IPPROTO_SRPC 90 /* Strite RPC protocol */
+#define IPPROTO_LARP 91 /* Locus Address Resoloution */
+#define IPPROTO_MTP 92 /* Multicast Transport */
+#define IPPROTO_AX25 93 /* AX.25 Frames */
+#define IPPROTO_IPEIP 94 /* IP encapsulated in IP */
+#define IPPROTO_MICP 95 /* Mobile Int.ing control */
+#define IPPROTO_SCCSP 96 /* Semaphore Comm. security */
+#define IPPROTO_ETHERIP 97 /* Ethernet IP encapsulation */
+#define IPPROTO_ENCAP 98 /* encapsulation header */
+#define IPPROTO_APES 99 /* any private encr. scheme */
+#define IPPROTO_GMTP 100 /* GMTP*/
+#define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */
+#define IPPROTO_SCTP 132 /* SCTP */
+#define IPPROTO_MH 135 /* IPv6 Mobility Header */
+#define IPPROTO_UDPLITE 136 /* UDP-Lite */
+#define IPPROTO_HIP 139 /* IP6 Host Identity Protocol */
+#define IPPROTO_SHIM6 140 /* IP6 Shim6 Protocol */
+/* 101-254: Partly Unassigned */
+#define IPPROTO_PIM 103 /* Protocol Independent Mcast */
+#define IPPROTO_CARP 112 /* CARP */
+#define IPPROTO_PGM 113 /* PGM */
+#define IPPROTO_MPLS 137 /* MPLS-in-IP */
+#define IPPROTO_PFSYNC 240 /* PFSYNC */
+#define IPPROTO_RESERVED_253 253 /* Reserved */
+#define IPPROTO_RESERVED_254 254 /* Reserved */
+/* 255: Reserved */
+/* BSD Private, local use, namespace incursion, no longer used */
+#define IPPROTO_OLD_DIVERT 254 /* OLD divert pseudo-proto */
+#define IPPROTO_MAX 256
+
+/* last return value of *_input(), meaning "all job for this pkt is done". */
+#define IPPROTO_DONE 257
+
+/* Only used internally, so can be outside the range of valid IP protocols. */
+#define IPPROTO_DIVERT 258 /* divert pseudo-protocol */
+#define IPPROTO_SEND 259 /* SeND pseudo-protocol */
+
+/*
+ * Defined to avoid confusion. The master value is defined by
+ * PROTO_SPACER in sys/protosw.h.
+ */
+#define IPPROTO_SPACER 32767 /* spacer for loadable protos */
+
+/*
+ * Local port number conventions:
+ *
+ * When a user does a bind(2) or connect(2) with a port number of zero,
+ * a non-conflicting local port address is chosen.
+ * The default range is IPPORT_HIFIRSTAUTO through
+ * IPPORT_HILASTAUTO, although that is settable by sysctl.
+ *
+ * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
+ * default assignment range.
+ *
+ * The value IP_PORTRANGE_DEFAULT causes the default behavior.
+ *
+ * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
+ * into the "high" range. These are reserved for client outbound connections
+ * which do not want to be filtered by any firewalls.
+ *
+ * The value IP_PORTRANGE_LOW changes the range to the "low" are
+ * that is (by convention) restricted to privileged processes. This
+ * convention is based on "vouchsafe" principles only. It is only secure
+ * if you trust the remote host to restrict these ports.
+ *
+ * The default range of ports and the high range can be changed by
+ * sysctl(3). (net.inet.ip.port{hi,low}{first,last}_auto)
+ *
+ * Changing those values has bad security implications if you are
+ * using a stateless firewall that is allowing packets outside of that
+ * range in order to allow transparent outgoing connections.
+ *
+ * Such a firewall configuration will generally depend on the use of these
+ * default values. If you change them, you may find your Security
+ * Administrator looking for you with a heavy object.
+ *
+ * For a slightly more orthodox text view on this:
+ *
+ * ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers
+ *
+ * port numbers are divided into three ranges:
+ *
+ * 0 - 1023 Well Known Ports
+ * 1024 - 49151 Registered Ports
+ * 49152 - 65535 Dynamic and/or Private Ports
+ *
+ */
+
+/*
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root). (IP_PORTRANGE_LOW)
+ */
+#define IPPORT_RESERVED 1024
+
+/*
+ * Default local port range, used by IP_PORTRANGE_DEFAULT
+ */
+#define IPPORT_EPHEMERALFIRST 10000
+#define IPPORT_EPHEMERALLAST 65535
+
+/*
+ * Dynamic port range, used by IP_PORTRANGE_HIGH.
+ */
+#define IPPORT_HIFIRSTAUTO 49152
+#define IPPORT_HILASTAUTO 65535
+
+/*
+ * Scanning for a free reserved port return a value below IPPORT_RESERVED,
+ * but higher than IPPORT_RESERVEDSTART. Traditionally the start value was
+ * 512, but that conflicts with some well-known-services that firewalls may
+ * have a fit if we use.
+ */
+#define IPPORT_RESERVEDSTART 600
+
+#define IPPORT_MAX 65535
+
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((in_addr_t)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((in_addr_t)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((in_addr_t)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define IN_CLASSD(i) (((in_addr_t)(i) & 0xf0000000) == 0xe0000000)
+#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
+#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
+#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
+#define IN_MULTICAST(i) IN_CLASSD(i)
+
+#define IN_EXPERIMENTAL(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000)
+#define IN_BADCLASS(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000)
+
+#define IN_LINKLOCAL(i) (((in_addr_t)(i) & 0xffff0000) == 0xa9fe0000)
+#define IN_LOOPBACK(i) (((in_addr_t)(i) & 0xff000000) == 0x7f000000)
+#define IN_ZERONET(i) (((in_addr_t)(i) & 0xff000000) == 0)
+
+#define IN_PRIVATE(i) ((((in_addr_t)(i) & 0xff000000) == 0x0a000000) || \
+ (((in_addr_t)(i) & 0xfff00000) == 0xac100000) || \
+ (((in_addr_t)(i) & 0xffff0000) == 0xc0a80000))
+
+#define IN_LOCAL_GROUP(i) (((in_addr_t)(i) & 0xffffff00) == 0xe0000000)
+
+#define IN_ANY_LOCAL(i) (IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i))
+
+#define INADDR_LOOPBACK ((in_addr_t)0x7f000001)
+#ifndef _KERNEL
+#define INADDR_NONE ((in_addr_t)0xffffffff) /* -1 return */
+#endif
+
+#define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000) /* 224.0.0.0 */
+#define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001) /* 224.0.0.1 */
+#define INADDR_ALLRTRS_GROUP ((in_addr_t)0xe0000002) /* 224.0.0.2 */
+#define INADDR_ALLRPTS_GROUP ((in_addr_t)0xe0000016) /* 224.0.0.22, IGMPv3 */
+#define INADDR_CARP_GROUP ((in_addr_t)0xe0000012) /* 224.0.0.18 */
+#define INADDR_PFSYNC_GROUP ((in_addr_t)0xe00000f0) /* 224.0.0.240 */
+#define INADDR_ALLMDNS_GROUP ((in_addr_t)0xe00000fb) /* 224.0.0.251 */
+#define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff) /* 224.0.0.255 */
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+#define IN_RFC3021_MASK ((in_addr_t)0xfffffffe)
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ * First word of comment is data type; bool is stored in int.
+ */
+#define IP_OPTIONS 1 /* buf/ip_opts; set/get IP options */
+#define IP_HDRINCL 2 /* int; header is included with data */
+#define IP_TOS 3 /* int; IP type of service and preced. */
+#define IP_TTL 4 /* int; IP time to live */
+#define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */
+#define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */
+#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */
+#define IP_SENDSRCADDR IP_RECVDSTADDR /* cmsg_type to set src addr */
+#define IP_RETOPTS 8 /* ip_opts; set/get IP options */
+#define IP_MULTICAST_IF 9 /* struct in_addr *or* struct ip_mreqn;
+ * set/get IP multicast i/f */
+#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */
+#define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */
+#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */
+#define IP_MULTICAST_VIF 14 /* set/get IP mcast virt. iface */
+#define IP_RSVP_ON 15 /* enable RSVP in kernel */
+#define IP_RSVP_OFF 16 /* disable RSVP in kernel */
+#define IP_RSVP_VIF_ON 17 /* set RSVP per-vif socket */
+#define IP_RSVP_VIF_OFF 18 /* unset RSVP per-vif socket */
+#define IP_PORTRANGE 19 /* int; range to choose for unspec port */
+#define IP_RECVIF 20 /* bool; receive reception if w/dgram */
+/* for IPSEC */
+#define IP_IPSEC_POLICY 21 /* int; set/get security policy */
+ /* unused; was IP_FAITH */
+#define IP_ONESBCAST 23 /* bool: send all-ones broadcast */
+#define IP_BINDANY 24 /* bool: allow bind to any address */
+#define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */
+#define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */
+
+/*
+ * Options for controlling the firewall and dummynet.
+ * Historical options (from 40 to 64) will eventually be
+ * replaced by only two options, IP_FW3 and IP_DUMMYNET3.
+ */
+#define IP_FW_TABLE_ADD 40 /* add entry */
+#define IP_FW_TABLE_DEL 41 /* delete entry */
+#define IP_FW_TABLE_FLUSH 42 /* flush table */
+#define IP_FW_TABLE_GETSIZE 43 /* get table size */
+#define IP_FW_TABLE_LIST 44 /* list table contents */
+
+#define IP_FW3 48 /* generic ipfw v.3 sockopts */
+#define IP_DUMMYNET3 49 /* generic dummynet v.3 sockopts */
+
+#define IP_FW_ADD 50 /* add a firewall rule to chain */
+#define IP_FW_DEL 51 /* delete a firewall rule from chain */
+#define IP_FW_FLUSH 52 /* flush firewall rule chain */
+#define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */
+#define IP_FW_GET 54 /* get entire firewall rule chain */
+#define IP_FW_RESETLOG 55 /* reset logging counters */
+
+#define IP_FW_NAT_CFG 56 /* add/config a nat rule */
+#define IP_FW_NAT_DEL 57 /* delete a nat rule */
+#define IP_FW_NAT_GET_CONFIG 58 /* get configuration of a nat rule */
+#define IP_FW_NAT_GET_LOG 59 /* get log of a nat rule */
+
+#define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */
+#define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */
+#define IP_DUMMYNET_FLUSH 62 /* flush dummynet */
+#define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */
+
+#define IP_RECVTTL 65 /* bool; receive IP TTL w/dgram */
+#define IP_MINTTL 66 /* minimum TTL for packet or drop */
+#define IP_DONTFRAG 67 /* don't fragment packet */
+#define IP_RECVTOS 68 /* bool; receive IP TOS w/dgram */
+
+/* IPv4 Source Filter Multicast API [RFC3678] */
+#define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */
+#define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */
+#define IP_BLOCK_SOURCE 72 /* block a source */
+#define IP_UNBLOCK_SOURCE 73 /* unblock a source */
+
+/* The following option is private; do not use it from user applications. */
+#define IP_MSFILTER 74 /* set/get filter list */
+
+/* Protocol Independent Multicast API [RFC3678] */
+#define MCAST_JOIN_GROUP 80 /* join an any-source group */
+#define MCAST_LEAVE_GROUP 81 /* leave all sources for group */
+#define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */
+#define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */
+#define MCAST_BLOCK_SOURCE 84 /* block a source */
+#define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */
+
+/* Flow and RSS definitions */
+#define IP_FLOWID 90 /* get flow id for the given socket/inp */
+#define IP_FLOWTYPE 91 /* get flow type (M_HASHTYPE) */
+#define IP_RSSBUCKETID 92 /* get RSS flowid -> bucket mapping */
+#define IP_RECVFLOWID 93 /* bool; receive IP flowid/flowtype w/ datagram */
+#define IP_RECVRSSBUCKETID 94 /* bool; receive IP RSS bucket id w/ datagram */
+
+/*
+ * Defaults and limits for options
+ */
+#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
+#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+
+/*
+ * The imo_membership vector for each socket is now dynamically allocated at
+ * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized
+ * according to a power-of-two increment.
+ */
+#define IP_MIN_MEMBERSHIPS 31
+#define IP_MAX_MEMBERSHIPS 4095
+#define IP_MAX_SOURCE_FILTER 1024 /* XXX to be unused */
+
+/*
+ * Default resource limits for IPv4 multicast source filtering.
+ * These may be modified by sysctl.
+ */
+#define IP_MAX_GROUP_SRC_FILTER 512 /* sources per group */
+#define IP_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */
+#define IP_MAX_SOCK_MUTE_FILTER 128 /* XXX no longer used */
+
+/*
+ * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
+ */
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+/*
+ * Modified argument structure for IP_MULTICAST_IF, obtained from Linux.
+ * This is used to specify an interface index for multicast sends, as
+ * the IPv4 legacy APIs do not support this (unless IP_SENDIF is available).
+ */
+struct ip_mreqn {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_address; /* local IP address of interface */
+ int imr_ifindex; /* Interface index; cast to uint32_t */
+};
+
+/*
+ * Argument structure for IPv4 Multicast Source Filter APIs. [RFC3678]
+ */
+struct ip_mreq_source {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_sourceaddr; /* IP address of source */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+/*
+ * Argument structures for Protocol-Independent Multicast Source
+ * Filter APIs. [RFC3678]
+ */
+struct group_req {
+ uint32_t gr_interface; /* interface index */
+ struct sockaddr_storage gr_group; /* group address */
+};
+
+struct group_source_req {
+ uint32_t gsr_interface; /* interface index */
+ struct sockaddr_storage gsr_group; /* group address */
+ struct sockaddr_storage gsr_source; /* source address */
+};
+
+#ifndef __MSFILTERREQ_DEFINED
+#define __MSFILTERREQ_DEFINED
+/*
+ * The following structure is private; do not use it from user applications.
+ * It is used to communicate IP_MSFILTER/IPV6_MSFILTER information between
+ * the RFC 3678 libc functions and the kernel.
+ */
+struct __msfilterreq {
+ uint32_t msfr_ifindex; /* interface index */
+ uint32_t msfr_fmode; /* filter mode for group */
+ uint32_t msfr_nsrcs; /* # of sources in msfr_srcs */
+ struct sockaddr_storage msfr_group; /* group address */
+ struct sockaddr_storage *msfr_srcs; /* pointer to the first member
+ * of a contiguous array of
+ * sources to filter in full.
+ */
+};
+#endif
+
+struct sockaddr;
+
+/*
+ * Advanced (Full-state) APIs [RFC3678]
+ * The RFC specifies uint_t for the 6th argument to [sg]etsourcefilter().
+ * We use uint32_t here to be consistent.
+ */
+int setipv4sourcefilter(int, struct in_addr, struct in_addr, uint32_t,
+ uint32_t, struct in_addr *);
+int getipv4sourcefilter(int, struct in_addr, struct in_addr, uint32_t *,
+ uint32_t *, struct in_addr *);
+int setsourcefilter(int, uint32_t, struct sockaddr *, socklen_t,
+ uint32_t, uint32_t, struct sockaddr_storage *);
+int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t,
+ uint32_t *, uint32_t *, struct sockaddr_storage *);
+
+/*
+ * Filter modes; also used to represent per-socket filter mode internally.
+ */
+#define MCAST_UNDEFINED 0 /* fmode: not yet defined */
+#define MCAST_INCLUDE 1 /* fmode: include these source(s) */
+#define MCAST_EXCLUDE 2 /* fmode: exclude these source(s) */
+
+/*
+ * Argument for IP_PORTRANGE:
+ * - which range to search when port is unspecified at bind() or connect()
+ */
+#define IP_PORTRANGE_DEFAULT 0 /* default range */
+#define IP_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */
+#define IP_PORTRANGE_LOW 2 /* "low" - vouchsafe security */
+
+/*
+ * Identifiers for IP sysctl nodes
+ */
+#define IPCTL_FORWARDING 1 /* act as router */
+#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */
+#define IPCTL_DEFTTL 3 /* default TTL */
+#ifdef notyet
+#define IPCTL_DEFMTU 4 /* default MTU */
+#endif
+/* IPCTL_RTEXPIRE 5 deprecated */
+/* IPCTL_RTMINEXPIRE 6 deprecated */
+/* IPCTL_RTMAXCACHE 7 deprecated */
+#define IPCTL_SOURCEROUTE 8 /* may perform source routes */
+#define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */
+#define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */
+#define IPCTL_INTRQDROPS 11 /* number of netisr q drops */
+#define IPCTL_STATS 12 /* ipstat structure */
+#define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */
+#define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */
+ /* 15, unused, was: IPCTL_KEEPFAITH */
+#define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */
+
+#endif /* __BSD_VISIBLE */
+
+#ifdef _KERNEL
+
+struct ifnet; struct mbuf; /* forward declarations for Standard C */
+
+int in_broadcast(struct in_addr, struct ifnet *);
+int in_canforward(struct in_addr);
+int in_localaddr(struct in_addr);
+int in_localip(struct in_addr);
+int in_ifhasaddr(struct ifnet *, struct in_addr);
+int inet_aton(const char *, struct in_addr *); /* in libkern */
+char *inet_ntoa(struct in_addr); /* in libkern */
+char *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
+char *inet_ntop(int, const void *, char *, socklen_t); /* in libkern */
+int inet_pton(int af, const char *, void *); /* in libkern */
+void in_ifdetach(struct ifnet *);
+
+#define in_hosteq(s, t) ((s).s_addr == (t).s_addr)
+#define in_nullhost(x) ((x).s_addr == INADDR_ANY)
+#define in_allhosts(x) ((x).s_addr == htonl(INADDR_ALLHOSTS_GROUP))
+
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+#define sintosa(sin) ((struct sockaddr *)(sin))
+#define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
+#endif /* _KERNEL */
+
+/* INET6 stuff */
+#if __POSIX_VISIBLE >= 200112
+#define __KAME_NETINET_IN_H_INCLUDED_
+#include <netinet6/in6.h>
+#undef __KAME_NETINET_IN_H_INCLUDED_
+#endif
+
+#endif /* !_NETINET_IN_H_*/
diff --git a/usr/src/boot/include/netinet/in_pcb.h b/usr/src/boot/include/netinet/in_pcb.h
new file mode 100644
index 0000000000..54eab8832d
--- /dev/null
+++ b/usr/src/boot/include/netinet/in_pcb.h
@@ -0,0 +1,733 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California.
+ * Copyright (c) 2010-2011 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Robert N. M. Watson under
+ * contract to Juniper Networks, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)in_pcb.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IN_PCB_H_
+#define _NETINET_IN_PCB_H_
+
+#include <sys/queue.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_rwlock.h>
+
+#ifdef _KERNEL
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <net/vnet.h>
+#include <vm/uma.h>
+#endif
+
+#define in6pcb inpcb /* for KAME src sync over BSD*'s */
+#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
+struct inpcbpolicy;
+
+/*
+ * struct inpcb is the common protocol control block structure used in most
+ * IP transport protocols.
+ *
+ * Pointers to local and foreign host table entries, local and foreign socket
+ * numbers, and pointers up (to a socket structure) and down (to a
+ * protocol-specific control block) are stored here.
+ */
+LIST_HEAD(inpcbhead, inpcb);
+LIST_HEAD(inpcbporthead, inpcbport);
+typedef u_quad_t inp_gen_t;
+
+/*
+ * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
+ * So, AF_INET6 null laddr is also used as AF_INET null laddr, by utilizing
+ * the following structure.
+ */
+struct in_addr_4in6 {
+ u_int32_t ia46_pad32[3];
+ struct in_addr ia46_addr4;
+};
+
+/*
+ * NOTE: ipv6 addrs should be 64-bit aligned, per RFC 2553. in_conninfo has
+ * some extra padding to accomplish this.
+ * NOTE 2: tcp_syncache.c uses first 5 32-bit words, which identify fport,
+ * lport, faddr to generate hash, so these fields shouldn't be moved.
+ */
+struct in_endpoints {
+ u_int16_t ie_fport; /* foreign port */
+ u_int16_t ie_lport; /* local port */
+ /* protocol dependent part, local and foreign addr */
+ union {
+ /* foreign host table entry */
+ struct in_addr_4in6 ie46_foreign;
+ struct in6_addr ie6_foreign;
+ } ie_dependfaddr;
+ union {
+ /* local host table entry */
+ struct in_addr_4in6 ie46_local;
+ struct in6_addr ie6_local;
+ } ie_dependladdr;
+ u_int32_t ie6_zoneid; /* scope zone id */
+};
+#define ie_faddr ie_dependfaddr.ie46_foreign.ia46_addr4
+#define ie_laddr ie_dependladdr.ie46_local.ia46_addr4
+#define ie6_faddr ie_dependfaddr.ie6_foreign
+#define ie6_laddr ie_dependladdr.ie6_local
+
+/*
+ * XXX The defines for inc_* are hacks and should be changed to direct
+ * references.
+ */
+struct in_conninfo {
+ u_int8_t inc_flags;
+ u_int8_t inc_len;
+ u_int16_t inc_fibnum; /* XXX was pad, 16 bits is plenty */
+ /* protocol dependent part */
+ struct in_endpoints inc_ie;
+};
+
+/*
+ * Flags for inc_flags.
+ */
+#define INC_ISIPV6 0x01
+
+#define inc_isipv6 inc_flags /* temp compatability */
+#define inc_fport inc_ie.ie_fport
+#define inc_lport inc_ie.ie_lport
+#define inc_faddr inc_ie.ie_faddr
+#define inc_laddr inc_ie.ie_laddr
+#define inc6_faddr inc_ie.ie6_faddr
+#define inc6_laddr inc_ie.ie6_laddr
+#define inc6_zoneid inc_ie.ie6_zoneid
+
+struct icmp6_filter;
+
+/*-
+ * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and
+ * IPv6 sockets. In the case of TCP and UDP, further per-connection state is
+ * hung off of inp_ppcb most of the time. Almost all fields of struct inpcb
+ * are static after creation or protected by a per-inpcb rwlock, inp_lock. A
+ * few fields are protected by multiple locks as indicated in the locking notes
+ * below. For these fields, all of the listed locks must be write-locked for
+ * any modifications. However, these fields can be safely read while any one of
+ * the listed locks are read-locked. This model can permit greater concurrency
+ * for read operations. For example, connections can be looked up while only
+ * holding a read lock on the global pcblist lock. This is important for
+ * performance when attempting to find the connection for a packet given its IP
+ * and port tuple.
+ *
+ * One noteworthy exception is that the global pcbinfo lock follows a different
+ * set of rules in relation to the inp_list field. Rather than being
+ * write-locked for modifications and read-locked for list iterations, it must
+ * be read-locked during modifications and write-locked during list iterations.
+ * This ensures that the relatively rare global list iterations safely walk a
+ * stable snapshot of connections while allowing more common list modifications
+ * to safely grab the pcblist lock just while adding or removing a connection
+ * from the global list.
+ *
+ * Key:
+ * (c) - Constant after initialization
+ * (g) - Protected by the pcbgroup lock
+ * (i) - Protected by the inpcb lock
+ * (p) - Protected by the pcbinfo lock for the inpcb
+ * (l) - Protected by the pcblist lock for the inpcb
+ * (h) - Protected by the pcbhash lock for the inpcb
+ * (s) - Protected by another subsystem's locks
+ * (x) - Undefined locking
+ *
+ * A few other notes:
+ *
+ * When a read lock is held, stability of the field is guaranteed; to write
+ * to a field, a write lock must generally be held.
+ *
+ * netinet/netinet6-layer code should not assume that the inp_socket pointer
+ * is safe to dereference without inp_lock being held, even for protocols
+ * other than TCP (where the inpcb persists during TIMEWAIT even after the
+ * socket has been freed), or there may be close(2)-related races.
+ *
+ * The inp_vflag field is overloaded, and would otherwise ideally be (c).
+ *
+ * TODO: Currently only the TCP stack is leveraging the global pcbinfo lock
+ * read-lock usage during modification, this model can be applied to other
+ * protocols (especially SCTP).
+ */
+struct inpcb {
+ LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */
+ LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */
+ LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */
+ /* (p[w]) for list iteration */
+ /* (p[r]/l) for addition/removal */
+ void *inp_ppcb; /* (i) pointer to per-protocol pcb */
+ struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */
+ struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */
+ LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */
+ struct socket *inp_socket; /* (i) back pointer to socket */
+ struct ucred *inp_cred; /* (c) cache of socket cred */
+ u_int32_t inp_flow; /* (i) IPv6 flow information */
+ int inp_flags; /* (i) generic IP/datagram flags */
+ int inp_flags2; /* (i) generic IP/datagram flags #2*/
+ u_char inp_vflag; /* (i) IP version flag (v4/v6) */
+ u_char inp_ip_ttl; /* (i) time to live proto */
+ u_char inp_ip_p; /* (c) protocol proto */
+ u_char inp_ip_minttl; /* (i) minimum TTL or drop */
+ uint32_t inp_flowid; /* (x) flow id / queue id */
+ u_int inp_refcount; /* (i) refcount */
+ void *inp_pspare[5]; /* (x) route caching / general use */
+ uint32_t inp_flowtype; /* (x) M_HASHTYPE value */
+ uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */
+ u_int inp_ispare[4]; /* (x) route caching / user cookie /
+ * general use */
+
+ /* Local and foreign ports, local and foreign addr. */
+ struct in_conninfo inp_inc; /* (i) list for PCB's local port */
+
+ /* MAC and IPSEC policy information. */
+ struct label *inp_label; /* (i) MAC label */
+ struct inpcbpolicy *inp_sp; /* (s) for IPSEC */
+
+ /* Protocol-dependent part; options. */
+ struct {
+ u_char inp4_ip_tos; /* (i) type of service proto */
+ struct mbuf *inp4_options; /* (i) IP options */
+ struct ip_moptions *inp4_moptions; /* (i) IP mcast options */
+ } inp_depend4;
+ struct {
+ /* (i) IP options */
+ struct mbuf *inp6_options;
+ /* (i) IP6 options for outgoing packets */
+ struct ip6_pktopts *inp6_outputopts;
+ /* (i) IP multicast options */
+ struct ip6_moptions *inp6_moptions;
+ /* (i) ICMPv6 code type filter */
+ struct icmp6_filter *inp6_icmp6filt;
+ /* (i) IPV6_CHECKSUM setsockopt */
+ int inp6_cksum;
+ short inp6_hops;
+ } inp_depend6;
+ LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */
+ struct inpcbport *inp_phd; /* (i/h) head of this list */
+#define inp_zero_size offsetof(struct inpcb, inp_gencnt)
+ inp_gen_t inp_gencnt; /* (c) generation count */
+ struct llentry *inp_lle; /* cached L2 information */
+ struct rtentry *inp_rt; /* cached L3 information */
+ struct rwlock inp_lock;
+};
+#define inp_fport inp_inc.inc_fport
+#define inp_lport inp_inc.inc_lport
+#define inp_faddr inp_inc.inc_faddr
+#define inp_laddr inp_inc.inc_laddr
+#define inp_ip_tos inp_depend4.inp4_ip_tos
+#define inp_options inp_depend4.inp4_options
+#define inp_moptions inp_depend4.inp4_moptions
+
+#define in6p_faddr inp_inc.inc6_faddr
+#define in6p_laddr inp_inc.inc6_laddr
+#define in6p_zoneid inp_inc.inc6_zoneid
+#define in6p_hops inp_depend6.inp6_hops /* default hop limit */
+#define in6p_flowinfo inp_flow
+#define in6p_options inp_depend6.inp6_options
+#define in6p_outputopts inp_depend6.inp6_outputopts
+#define in6p_moptions inp_depend6.inp6_moptions
+#define in6p_icmp6filt inp_depend6.inp6_icmp6filt
+#define in6p_cksum inp_depend6.inp6_cksum
+
+#define inp_vnet inp_pcbinfo->ipi_vnet
+
+/*
+ * The range of the generation count, as used in this implementation, is 9e19.
+ * We would have to create 300 billion connections per second for this number
+ * to roll over in a year. This seems sufficiently unlikely that we simply
+ * don't concern ourselves with that possibility.
+ */
+
+/*
+ * Interface exported to userland by various protocols which use inpcbs. Hack
+ * alert -- only define if struct xsocket is in scope.
+ */
+#ifdef _SYS_SOCKETVAR_H_
+struct xinpcb {
+ size_t xi_len; /* length of this structure */
+ struct inpcb xi_inp;
+ struct xsocket xi_socket;
+ u_quad_t xi_alignment_hack;
+};
+
+struct xinpgen {
+ size_t xig_len; /* length of this structure */
+ u_int xig_count; /* number of PCBs at this time */
+ inp_gen_t xig_gen; /* generation count at this time */
+ so_gen_t xig_sogen; /* socket generation count at this time */
+};
+#endif /* _SYS_SOCKETVAR_H_ */
+
+struct inpcbport {
+ LIST_ENTRY(inpcbport) phd_hash;
+ struct inpcbhead phd_pcblist;
+ u_short phd_port;
+};
+
+/*-
+ * Global data structure for each high-level protocol (UDP, TCP, ...) in both
+ * IPv4 and IPv6. Holds inpcb lists and information for managing them.
+ *
+ * Each pcbinfo is protected by three locks: ipi_lock, ipi_hash_lock and
+ * ipi_list_lock:
+ * - ipi_lock covering the global pcb list stability during loop iteration,
+ * - ipi_hash_lock covering the hashed lookup tables,
+ * - ipi_list_lock covering mutable global fields (such as the global
+ * pcb list)
+ *
+ * The lock order is:
+ *
+ * ipi_lock (before)
+ * inpcb locks (before)
+ * ipi_list locks (before)
+ * {ipi_hash_lock, pcbgroup locks}
+ *
+ * Locking key:
+ *
+ * (c) Constant or nearly constant after initialisation
+ * (g) Locked by ipi_lock
+ * (l) Locked by ipi_list_lock
+ * (h) Read using either ipi_hash_lock or inpcb lock; write requires both
+ * (p) Protected by one or more pcbgroup locks
+ * (x) Synchronisation properties poorly defined
+ */
+struct inpcbinfo {
+ /*
+ * Global lock protecting full inpcb list traversal
+ */
+ struct rwlock ipi_lock;
+
+ /*
+ * Global list of inpcbs on the protocol.
+ */
+ struct inpcbhead *ipi_listhead; /* (g/l) */
+ u_int ipi_count; /* (l) */
+
+ /*
+ * Generation count -- incremented each time a connection is allocated
+ * or freed.
+ */
+ u_quad_t ipi_gencnt; /* (l) */
+
+ /*
+ * Fields associated with port lookup and allocation.
+ */
+ u_short ipi_lastport; /* (x) */
+ u_short ipi_lastlow; /* (x) */
+ u_short ipi_lasthi; /* (x) */
+
+ /*
+ * UMA zone from which inpcbs are allocated for this protocol.
+ */
+ struct uma_zone *ipi_zone; /* (c) */
+
+ /*
+ * Connection groups associated with this protocol. These fields are
+ * constant, but pcbgroup structures themselves are protected by
+ * per-pcbgroup locks.
+ */
+ struct inpcbgroup *ipi_pcbgroups; /* (c) */
+ u_int ipi_npcbgroups; /* (c) */
+ u_int ipi_hashfields; /* (c) */
+
+ /*
+ * Global lock protecting non-pcbgroup hash lookup tables.
+ */
+ struct rwlock ipi_hash_lock;
+
+ /*
+ * Global hash of inpcbs, hashed by local and foreign addresses and
+ * port numbers.
+ */
+ struct inpcbhead *ipi_hashbase; /* (h) */
+ u_long ipi_hashmask; /* (h) */
+
+ /*
+ * Global hash of inpcbs, hashed by only local port number.
+ */
+ struct inpcbporthead *ipi_porthashbase; /* (h) */
+ u_long ipi_porthashmask; /* (h) */
+
+ /*
+ * List of wildcard inpcbs for use with pcbgroups. In the past, was
+ * per-pcbgroup but is now global. All pcbgroup locks must be held
+ * to modify the list, so any is sufficient to read it.
+ */
+ struct inpcbhead *ipi_wildbase; /* (p) */
+ u_long ipi_wildmask; /* (p) */
+
+ /*
+ * Pointer to network stack instance
+ */
+ struct vnet *ipi_vnet; /* (c) */
+
+ /*
+ * general use 2
+ */
+ void *ipi_pspare[2];
+
+ /*
+ * Global lock protecting global inpcb list, inpcb count, etc.
+ */
+ struct rwlock ipi_list_lock;
+};
+
+#ifdef _KERNEL
+/*
+ * Connection groups hold sets of connections that have similar CPU/thread
+ * affinity. Each connection belongs to exactly one connection group.
+ */
+struct inpcbgroup {
+ /*
+ * Per-connection group hash of inpcbs, hashed by local and foreign
+ * addresses and port numbers.
+ */
+ struct inpcbhead *ipg_hashbase; /* (c) */
+ u_long ipg_hashmask; /* (c) */
+
+ /*
+ * Notional affinity of this pcbgroup.
+ */
+ u_int ipg_cpu; /* (p) */
+
+ /*
+ * Per-connection group lock, not to be confused with ipi_lock.
+ * Protects the hash table hung off the group, but also the global
+ * wildcard list in inpcbinfo.
+ */
+ struct mtx ipg_lock;
+} __aligned(CACHE_LINE_SIZE);
+
+#define INP_LOCK_INIT(inp, d, t) \
+ rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK)
+#define INP_LOCK_DESTROY(inp) rw_destroy(&(inp)->inp_lock)
+#define INP_RLOCK(inp) rw_rlock(&(inp)->inp_lock)
+#define INP_WLOCK(inp) rw_wlock(&(inp)->inp_lock)
+#define INP_TRY_RLOCK(inp) rw_try_rlock(&(inp)->inp_lock)
+#define INP_TRY_WLOCK(inp) rw_try_wlock(&(inp)->inp_lock)
+#define INP_RUNLOCK(inp) rw_runlock(&(inp)->inp_lock)
+#define INP_WUNLOCK(inp) rw_wunlock(&(inp)->inp_lock)
+#define INP_TRY_UPGRADE(inp) rw_try_upgrade(&(inp)->inp_lock)
+#define INP_DOWNGRADE(inp) rw_downgrade(&(inp)->inp_lock)
+#define INP_WLOCKED(inp) rw_wowned(&(inp)->inp_lock)
+#define INP_LOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_LOCKED)
+#define INP_RLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_RLOCKED)
+#define INP_WLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_WLOCKED)
+#define INP_UNLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_UNLOCKED)
+
+/*
+ * These locking functions are for inpcb consumers outside of sys/netinet,
+ * more specifically, they were added for the benefit of TOE drivers. The
+ * macros are reserved for use by the stack.
+ */
+void inp_wlock(struct inpcb *);
+void inp_wunlock(struct inpcb *);
+void inp_rlock(struct inpcb *);
+void inp_runlock(struct inpcb *);
+
+#ifdef INVARIANTS
+void inp_lock_assert(struct inpcb *);
+void inp_unlock_assert(struct inpcb *);
+#else
+static __inline void
+inp_lock_assert(struct inpcb *inp __unused)
+{
+}
+
+static __inline void
+inp_unlock_assert(struct inpcb *inp __unused)
+{
+}
+
+#endif
+
+void inp_apply_all(void (*func)(struct inpcb *, void *), void *arg);
+int inp_ip_tos_get(const struct inpcb *inp);
+void inp_ip_tos_set(struct inpcb *inp, int val);
+struct socket *
+ inp_inpcbtosocket(struct inpcb *inp);
+struct tcpcb *
+ inp_inpcbtotcpcb(struct inpcb *inp);
+void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
+ uint32_t *faddr, uint16_t *fp);
+short inp_so_options(const struct inpcb *inp);
+
+#endif /* _KERNEL */
+
+#define INP_INFO_LOCK_INIT(ipi, d) \
+ rw_init_flags(&(ipi)->ipi_lock, (d), RW_RECURSE)
+#define INP_INFO_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_lock)
+#define INP_INFO_RLOCK(ipi) rw_rlock(&(ipi)->ipi_lock)
+#define INP_INFO_WLOCK(ipi) rw_wlock(&(ipi)->ipi_lock)
+#define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock)
+#define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock)
+#define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock)
+#define INP_INFO_WLOCKED(ipi) rw_wowned(&(ipi)->ipi_lock)
+#define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock)
+#define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock)
+#define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED)
+#define INP_INFO_RLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_RLOCKED)
+#define INP_INFO_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_WLOCKED)
+#define INP_INFO_UNLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_UNLOCKED)
+
+#define INP_LIST_LOCK_INIT(ipi, d) \
+ rw_init_flags(&(ipi)->ipi_list_lock, (d), 0)
+#define INP_LIST_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_list_lock)
+#define INP_LIST_RLOCK(ipi) rw_rlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_WLOCK(ipi) rw_wlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_list_lock)
+#define INP_LIST_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_list_lock)
+#define INP_LIST_LOCK_ASSERT(ipi) \
+ rw_assert(&(ipi)->ipi_list_lock, RA_LOCKED)
+#define INP_LIST_RLOCK_ASSERT(ipi) \
+ rw_assert(&(ipi)->ipi_list_lock, RA_RLOCKED)
+#define INP_LIST_WLOCK_ASSERT(ipi) \
+ rw_assert(&(ipi)->ipi_list_lock, RA_WLOCKED)
+#define INP_LIST_UNLOCK_ASSERT(ipi) \
+ rw_assert(&(ipi)->ipi_list_lock, RA_UNLOCKED)
+
+#define INP_HASH_LOCK_INIT(ipi, d) \
+ rw_init_flags(&(ipi)->ipi_hash_lock, (d), 0)
+#define INP_HASH_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_hash_lock)
+#define INP_HASH_RLOCK(ipi) rw_rlock(&(ipi)->ipi_hash_lock)
+#define INP_HASH_WLOCK(ipi) rw_wlock(&(ipi)->ipi_hash_lock)
+#define INP_HASH_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_hash_lock)
+#define INP_HASH_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_hash_lock)
+#define INP_HASH_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \
+ RA_LOCKED)
+#define INP_HASH_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \
+ RA_WLOCKED)
+
+#define INP_GROUP_LOCK_INIT(ipg, d) mtx_init(&(ipg)->ipg_lock, (d), NULL, \
+ MTX_DEF | MTX_DUPOK)
+#define INP_GROUP_LOCK_DESTROY(ipg) mtx_destroy(&(ipg)->ipg_lock)
+
+#define INP_GROUP_LOCK(ipg) mtx_lock(&(ipg)->ipg_lock)
+#define INP_GROUP_LOCK_ASSERT(ipg) mtx_assert(&(ipg)->ipg_lock, MA_OWNED)
+#define INP_GROUP_UNLOCK(ipg) mtx_unlock(&(ipg)->ipg_lock)
+
+#define INP_PCBHASH(faddr, lport, fport, mask) \
+ (((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask))
+#define INP_PCBPORTHASH(lport, mask) \
+ (ntohs((lport)) & (mask))
+#define INP6_PCBHASHKEY(faddr) ((faddr)->s6_addr32[3])
+
+/*
+ * Flags for inp_vflags -- historically version flags only
+ */
+#define INP_IPV4 0x1
+#define INP_IPV6 0x2
+#define INP_IPV6PROTO 0x4 /* opened under IPv6 protocol */
+
+/*
+ * Flags for inp_flags.
+ */
+#define INP_RECVOPTS 0x00000001 /* receive incoming IP options */
+#define INP_RECVRETOPTS 0x00000002 /* receive IP options for reply */
+#define INP_RECVDSTADDR 0x00000004 /* receive IP dst address */
+#define INP_HDRINCL 0x00000008 /* user supplies entire IP header */
+#define INP_HIGHPORT 0x00000010 /* user wants "high" port binding */
+#define INP_LOWPORT 0x00000020 /* user wants "low" port binding */
+#define INP_ANONPORT 0x00000040 /* port chosen for user */
+#define INP_RECVIF 0x00000080 /* receive incoming interface */
+#define INP_MTUDISC 0x00000100 /* user can do MTU discovery */
+ /* 0x000200 unused: was INP_FAITH */
+#define INP_RECVTTL 0x00000400 /* receive incoming IP TTL */
+#define INP_DONTFRAG 0x00000800 /* don't fragment packet */
+#define INP_BINDANY 0x00001000 /* allow bind to any address */
+#define INP_INHASHLIST 0x00002000 /* in_pcbinshash() has been called */
+#define INP_RECVTOS 0x00004000 /* receive incoming IP TOS */
+#define IN6P_IPV6_V6ONLY 0x00008000 /* restrict AF_INET6 socket for v6 */
+#define IN6P_PKTINFO 0x00010000 /* receive IP6 dst and I/F */
+#define IN6P_HOPLIMIT 0x00020000 /* receive hoplimit */
+#define IN6P_HOPOPTS 0x00040000 /* receive hop-by-hop options */
+#define IN6P_DSTOPTS 0x00080000 /* receive dst options after rthdr */
+#define IN6P_RTHDR 0x00100000 /* receive routing header */
+#define IN6P_RTHDRDSTOPTS 0x00200000 /* receive dstoptions before rthdr */
+#define IN6P_TCLASS 0x00400000 /* receive traffic class value */
+#define IN6P_AUTOFLOWLABEL 0x00800000 /* attach flowlabel automatically */
+#define INP_TIMEWAIT 0x01000000 /* in TIMEWAIT, ppcb is tcptw */
+#define INP_ONESBCAST 0x02000000 /* send all-ones broadcast */
+#define INP_DROPPED 0x04000000 /* protocol drop flag */
+#define INP_SOCKREF 0x08000000 /* strong socket reference */
+#define INP_RESERVED_0 0x10000000 /* reserved field */
+#define INP_RESERVED_1 0x20000000 /* reserved field */
+#define IN6P_RFC2292 0x40000000 /* used RFC2292 API on the socket */
+#define IN6P_MTU 0x80000000 /* receive path MTU */
+
+#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
+ INP_RECVIF|INP_RECVTTL|INP_RECVTOS|\
+ IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
+ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
+ IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\
+ IN6P_MTU)
+
+/*
+ * Flags for inp_flags2.
+ */
+#define INP_LLE_VALID 0x00000001 /* cached lle is valid */
+#define INP_RT_VALID 0x00000002 /* cached rtentry is valid */
+#define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */
+#define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */
+#define INP_FREED 0x00000010 /* inp itself is not valid */
+#define INP_REUSEADDR 0x00000020 /* SO_REUSEADDR option is set */
+#define INP_BINDMULTI 0x00000040 /* IP_BINDMULTI option is set */
+#define INP_RSS_BUCKET_SET 0x00000080 /* IP_RSS_LISTEN_BUCKET is set */
+#define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */
+#define INP_RECVRSSBUCKETID 0x00000200 /* populate recv datagram with bucket id */
+
+/*
+ * Flags passed to in_pcblookup*() functions.
+ */
+#define INPLOOKUP_WILDCARD 0x00000001 /* Allow wildcard sockets. */
+#define INPLOOKUP_RLOCKPCB 0x00000002 /* Return inpcb read-locked. */
+#define INPLOOKUP_WLOCKPCB 0x00000004 /* Return inpcb write-locked. */
+
+#define INPLOOKUP_MASK (INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB | \
+ INPLOOKUP_WLOCKPCB)
+
+#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
+#define sotoin6pcb(so) sotoinpcb(so) /* for KAME src sync over BSD*'s */
+
+#define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family
+
+#define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af)
+
+/*
+ * Constants for pcbinfo.ipi_hashfields.
+ */
+#define IPI_HASHFIELDS_NONE 0
+#define IPI_HASHFIELDS_2TUPLE 1
+#define IPI_HASHFIELDS_4TUPLE 2
+
+#ifdef _KERNEL
+VNET_DECLARE(int, ipport_reservedhigh);
+VNET_DECLARE(int, ipport_reservedlow);
+VNET_DECLARE(int, ipport_lowfirstauto);
+VNET_DECLARE(int, ipport_lowlastauto);
+VNET_DECLARE(int, ipport_firstauto);
+VNET_DECLARE(int, ipport_lastauto);
+VNET_DECLARE(int, ipport_hifirstauto);
+VNET_DECLARE(int, ipport_hilastauto);
+VNET_DECLARE(int, ipport_randomized);
+VNET_DECLARE(int, ipport_randomcps);
+VNET_DECLARE(int, ipport_randomtime);
+VNET_DECLARE(int, ipport_stoprandom);
+VNET_DECLARE(int, ipport_tcpallocs);
+
+#define V_ipport_reservedhigh VNET(ipport_reservedhigh)
+#define V_ipport_reservedlow VNET(ipport_reservedlow)
+#define V_ipport_lowfirstauto VNET(ipport_lowfirstauto)
+#define V_ipport_lowlastauto VNET(ipport_lowlastauto)
+#define V_ipport_firstauto VNET(ipport_firstauto)
+#define V_ipport_lastauto VNET(ipport_lastauto)
+#define V_ipport_hifirstauto VNET(ipport_hifirstauto)
+#define V_ipport_hilastauto VNET(ipport_hilastauto)
+#define V_ipport_randomized VNET(ipport_randomized)
+#define V_ipport_randomcps VNET(ipport_randomcps)
+#define V_ipport_randomtime VNET(ipport_randomtime)
+#define V_ipport_stoprandom VNET(ipport_stoprandom)
+#define V_ipport_tcpallocs VNET(ipport_tcpallocs)
+
+void in_pcbinfo_destroy(struct inpcbinfo *);
+void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *,
+ int, int, char *, uma_init, uma_fini, uint32_t, u_int);
+
+int in_pcbbind_check_bindmulti(const struct inpcb *ni,
+ const struct inpcb *oi);
+
+struct inpcbgroup *
+ in_pcbgroup_byhash(struct inpcbinfo *, u_int, uint32_t);
+struct inpcbgroup *
+ in_pcbgroup_byinpcb(struct inpcb *);
+struct inpcbgroup *
+ in_pcbgroup_bytuple(struct inpcbinfo *, struct in_addr, u_short,
+ struct in_addr, u_short);
+void in_pcbgroup_destroy(struct inpcbinfo *);
+int in_pcbgroup_enabled(struct inpcbinfo *);
+void in_pcbgroup_init(struct inpcbinfo *, u_int, int);
+void in_pcbgroup_remove(struct inpcb *);
+void in_pcbgroup_update(struct inpcb *);
+void in_pcbgroup_update_mbuf(struct inpcb *, struct mbuf *);
+
+void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
+int in_pcballoc(struct socket *, struct inpcbinfo *);
+int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
+int in_pcb_lport(struct inpcb *, struct in_addr *, u_short *,
+ struct ucred *, int);
+int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
+ u_short *, struct ucred *);
+int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
+int in_pcbconnect_mbuf(struct inpcb *, struct sockaddr *, struct ucred *,
+ struct mbuf *);
+int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
+ u_short *, in_addr_t *, u_short *, struct inpcb **,
+ struct ucred *);
+void in_pcbdetach(struct inpcb *);
+void in_pcbdisconnect(struct inpcb *);
+void in_pcbdrop(struct inpcb *);
+void in_pcbfree(struct inpcb *);
+int in_pcbinshash(struct inpcb *);
+int in_pcbinshash_nopcbgroup(struct inpcb *);
+int in_pcbladdr(struct inpcb *, struct in_addr *, struct in_addr *,
+ struct ucred *);
+struct inpcb *
+ in_pcblookup_local(struct inpcbinfo *,
+ struct in_addr, u_short, int, struct ucred *);
+struct inpcb *
+ in_pcblookup(struct inpcbinfo *, struct in_addr, u_int,
+ struct in_addr, u_int, int, struct ifnet *);
+struct inpcb *
+ in_pcblookup_mbuf(struct inpcbinfo *, struct in_addr, u_int,
+ struct in_addr, u_int, int, struct ifnet *, struct mbuf *);
+void in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr,
+ int, struct inpcb *(*)(struct inpcb *, int));
+void in_pcbref(struct inpcb *);
+void in_pcbrehash(struct inpcb *);
+void in_pcbrehash_mbuf(struct inpcb *, struct mbuf *);
+int in_pcbrele(struct inpcb *);
+int in_pcbrele_rlocked(struct inpcb *);
+int in_pcbrele_wlocked(struct inpcb *);
+void in_pcbsetsolabel(struct socket *so);
+int in_getpeeraddr(struct socket *so, struct sockaddr **nam);
+int in_getsockaddr(struct socket *so, struct sockaddr **nam);
+struct sockaddr *
+ in_sockaddr(in_port_t port, struct in_addr *addr);
+void in_pcbsosetlabel(struct socket *so);
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_IN_PCB_H_ */
diff --git a/usr/src/boot/include/netinet/in_systm.h b/usr/src/boot/include/netinet/in_systm.h
new file mode 100644
index 0000000000..acd2e62a2e
--- /dev/null
+++ b/usr/src/boot/include/netinet/in_systm.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)in_systm.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IN_SYSTM_H_
+#define _NETINET_IN_SYSTM_H_
+
+/*
+ * Miscellaneous internetwork
+ * definitions for kernel.
+ */
+
+/*
+ * Network types.
+ *
+ * Internally the system keeps counters in the headers with the bytes
+ * swapped so that VAX instructions will work on them. It reverses
+ * the bytes before transmission at each protocol level. The n_ types
+ * represent the types with the bytes in ``high-ender'' order. Network
+ * byte order is usually referered to as big-endian these days rather
+ * than high-ender, which sadly invokes an Orson Scott Card novel, or
+ * worse, the movie.
+ */
+typedef u_int16_t n_short; /* short as received from the net */
+typedef u_int32_t n_long; /* long as received from the net */
+
+typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */
+
+#ifdef _KERNEL
+uint32_t iptime(void);
+#endif
+
+#endif
diff --git a/usr/src/boot/include/netinet/ip.h b/usr/src/boot/include/netinet/ip.h
new file mode 100644
index 0000000000..92693965c7
--- /dev/null
+++ b/usr/src/boot/include/netinet/ip.h
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ip.h 8.2 (Berkeley) 6/1/94
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IP_H_
+#define _NETINET_IP_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * Definitions for internet protocol version 4.
+ *
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_char ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#endif
+ u_char ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_char ip_ttl; /* time to live */
+ u_char ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+} __packed __aligned(2);
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos).
+ */
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_MINCOST 0x02
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (deprecated).
+ */
+#define IPTOS_PREC_NETCONTROL IPTOS_DSCP_CS7
+#define IPTOS_PREC_INTERNETCONTROL IPTOS_DSCP_CS6
+#define IPTOS_PREC_CRITIC_ECP IPTOS_DSCP_CS5
+#define IPTOS_PREC_FLASHOVERRIDE IPTOS_DSCP_CS4
+#define IPTOS_PREC_FLASH IPTOS_DSCP_CS3
+#define IPTOS_PREC_IMMEDIATE IPTOS_DSCP_CS2
+#define IPTOS_PREC_PRIORITY IPTOS_DSCP_CS1
+#define IPTOS_PREC_ROUTINE IPTOS_DSCP_CS0
+
+/*
+ * Definitions for DiffServ Codepoints as per RFC2474 and RFC5865.
+ */
+#define IPTOS_DSCP_CS0 0x00
+#define IPTOS_DSCP_CS1 0x20
+#define IPTOS_DSCP_AF11 0x28
+#define IPTOS_DSCP_AF12 0x30
+#define IPTOS_DSCP_AF13 0x38
+#define IPTOS_DSCP_CS2 0x40
+#define IPTOS_DSCP_AF21 0x48
+#define IPTOS_DSCP_AF22 0x50
+#define IPTOS_DSCP_AF23 0x58
+#define IPTOS_DSCP_CS3 0x60
+#define IPTOS_DSCP_AF31 0x68
+#define IPTOS_DSCP_AF32 0x70
+#define IPTOS_DSCP_AF33 0x78
+#define IPTOS_DSCP_CS4 0x80
+#define IPTOS_DSCP_AF41 0x88
+#define IPTOS_DSCP_AF42 0x90
+#define IPTOS_DSCP_AF43 0x98
+#define IPTOS_DSCP_CS5 0xa0
+#define IPTOS_DSCP_VA 0xb0
+#define IPTOS_DSCP_EF 0xb8
+#define IPTOS_DSCP_CS6 0xc0
+#define IPTOS_DSCP_CS7 0xe0
+
+/*
+ * ECN (Explicit Congestion Notification) codepoints in RFC3168 mapped to the
+ * lower 2 bits of the TOS field.
+ */
+#define IPTOS_ECN_NOTECT 0x00 /* not-ECT */
+#define IPTOS_ECN_ECT1 0x01 /* ECN-capable transport (1) */
+#define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */
+#define IPTOS_ECN_CE 0x03 /* congestion experienced */
+#define IPTOS_ECN_MASK 0x03 /* ECN field mask */
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_ESO 133 /* extended security */
+#define IPOPT_CIPSO 134 /* commerical security */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router alert */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_char ipt_code; /* IPOPT_TS */
+ u_char ipt_len; /* size of structure (variable) */
+ u_char ipt_ptr; /* index of current entry */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_char ipt_flg:4, /* flags, see below */
+ ipt_oflw:4; /* overflow counter */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char ipt_oflw:4, /* overflow counter */
+ ipt_flg:4; /* flags, see below */
+#endif
+ union ipt_timestamp {
+ uint32_t ipt_time[1]; /* network format */
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ uint32_t ipt_time; /* network format */
+ } ipt_ta[1];
+ } ipt_timestamp;
+};
+
+/* Flag bits for ipt_flg. */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* Bits for security (not byte swapped). */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+#define IP_MSS 576 /* default maximum segment size */
+
+/*
+ * This is the real IPv4 pseudo header, used for computing the TCP and UDP
+ * checksums. For the Internet checksum, struct ipovly can be used instead.
+ * For stronger checksums, the real thing must be used.
+ */
+struct ippseudo {
+ struct in_addr ippseudo_src; /* source internet address */
+ struct in_addr ippseudo_dst; /* destination internet address */
+ u_char ippseudo_pad; /* pad, must be zero */
+ u_char ippseudo_p; /* protocol */
+ u_short ippseudo_len; /* protocol length */
+};
+#endif
diff --git a/usr/src/boot/include/netinet/ip_var.h b/usr/src/boot/include/netinet/ip_var.h
new file mode 100644
index 0000000000..34168054ee
--- /dev/null
+++ b/usr/src/boot/include/netinet/ip_var.h
@@ -0,0 +1,306 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ip_var.h 8.2 (Berkeley) 1/9/95
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_IP_VAR_H_
+#define _NETINET_IP_VAR_H_
+
+#include <sys/queue.h>
+
+/*
+ * Overlay for ip header used by other protocols (tcp, udp).
+ */
+struct ipovly {
+ u_char ih_x1[9]; /* (unused) */
+ u_char ih_pr; /* protocol */
+ u_short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+
+#ifdef _KERNEL
+/*
+ * Ip reassembly queue structure. Each fragment
+ * being reassembled is attached to one of these structures.
+ * They are timed out after ipq_ttl drops to 0, and may also
+ * be reclaimed if memory becomes tight.
+ */
+struct ipq {
+ TAILQ_ENTRY(ipq) ipq_list; /* to other reass headers */
+ u_char ipq_ttl; /* time for reass q to live */
+ u_char ipq_p; /* protocol of this fragment */
+ u_short ipq_id; /* sequence id for reassembly */
+ struct mbuf *ipq_frags; /* to ip headers of fragments */
+ struct in_addr ipq_src,ipq_dst;
+ u_char ipq_nfrags; /* # frags in this packet */
+ struct label *ipq_label; /* MAC label */
+};
+#endif /* _KERNEL */
+
+/*
+ * Structure stored in mbuf in inpcb.ip_options
+ * and passed to ip_output when ip options are in use.
+ * The actual length of the options (including ipopt_dst)
+ * is in m_len.
+ */
+#define MAX_IPOPTLEN 40
+
+struct ipoption {
+ struct in_addr ipopt_dst; /* first-hop dst if source routed */
+ char ipopt_list[MAX_IPOPTLEN]; /* options proper */
+};
+
+/*
+ * Structure attached to inpcb.ip_moptions and
+ * passed to ip_output when IP multicast options are in use.
+ * This structure is lazy-allocated.
+ */
+struct ip_moptions {
+ struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
+ struct in_addr imo_multicast_addr; /* ifindex/addr on MULTICAST_IF */
+ u_long imo_multicast_vif; /* vif num outgoing multicasts */
+ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */
+ u_char imo_multicast_loop; /* 1 => hear sends if a member */
+ u_short imo_num_memberships; /* no. memberships this socket */
+ u_short imo_max_memberships; /* max memberships this socket */
+ struct in_multi **imo_membership; /* group memberships */
+ struct in_mfilter *imo_mfilters; /* source filters */
+ STAILQ_ENTRY(ip_moptions) imo_link;
+};
+
+struct ipstat {
+ uint64_t ips_total; /* total packets received */
+ uint64_t ips_badsum; /* checksum bad */
+ uint64_t ips_tooshort; /* packet too short */
+ uint64_t ips_toosmall; /* not enough data */
+ uint64_t ips_badhlen; /* ip header length < data size */
+ uint64_t ips_badlen; /* ip length < ip header length */
+ uint64_t ips_fragments; /* fragments received */
+ uint64_t ips_fragdropped; /* frags dropped (dups, out of space) */
+ uint64_t ips_fragtimeout; /* fragments timed out */
+ uint64_t ips_forward; /* packets forwarded */
+ uint64_t ips_fastforward; /* packets fast forwarded */
+ uint64_t ips_cantforward; /* packets rcvd for unreachable dest */
+ uint64_t ips_redirectsent; /* packets forwarded on same net */
+ uint64_t ips_noproto; /* unknown or unsupported protocol */
+ uint64_t ips_delivered; /* datagrams delivered to upper level*/
+ uint64_t ips_localout; /* total ip packets generated here */
+ uint64_t ips_odropped; /* lost packets due to nobufs, etc. */
+ uint64_t ips_reassembled; /* total packets reassembled ok */
+ uint64_t ips_fragmented; /* datagrams successfully fragmented */
+ uint64_t ips_ofragments; /* output fragments created */
+ uint64_t ips_cantfrag; /* don't fragment flag was set, etc. */
+ uint64_t ips_badoptions; /* error in option processing */
+ uint64_t ips_noroute; /* packets discarded due to no route */
+ uint64_t ips_badvers; /* ip version != 4 */
+ uint64_t ips_rawout; /* total raw ip packets generated */
+ uint64_t ips_toolong; /* ip length > max ip packet size */
+ uint64_t ips_notmember; /* multicasts for unregistered grps */
+ uint64_t ips_nogif; /* no match gif found */
+ uint64_t ips_badaddr; /* invalid address on header */
+};
+
+#ifdef _KERNEL
+
+#include <sys/counter.h>
+#include <net/vnet.h>
+
+VNET_PCPUSTAT_DECLARE(struct ipstat, ipstat);
+/*
+ * In-kernel consumers can use these accessor macros directly to update
+ * stats.
+ */
+#define IPSTAT_ADD(name, val) \
+ VNET_PCPUSTAT_ADD(struct ipstat, ipstat, name, (val))
+#define IPSTAT_SUB(name, val) IPSTAT_ADD(name, -(val))
+#define IPSTAT_INC(name) IPSTAT_ADD(name, 1)
+#define IPSTAT_DEC(name) IPSTAT_SUB(name, 1)
+
+/*
+ * Kernel module consumers must use this accessor macro.
+ */
+void kmod_ipstat_inc(int statnum);
+#define KMOD_IPSTAT_INC(name) \
+ kmod_ipstat_inc(offsetof(struct ipstat, name) / sizeof(uint64_t))
+void kmod_ipstat_dec(int statnum);
+#define KMOD_IPSTAT_DEC(name) \
+ kmod_ipstat_dec(offsetof(struct ipstat, name) / sizeof(uint64_t))
+
+/* flags passed to ip_output as last parameter */
+#define IP_FORWARDING 0x1 /* most of ip header exists */
+#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
+#define IP_SENDONES 0x4 /* send all-ones broadcast */
+#define IP_SENDTOIF 0x8 /* send on specific ifnet */
+#define IP_ROUTETOIF SO_DONTROUTE /* 0x10 bypass routing tables */
+#define IP_ALLOWBROADCAST SO_BROADCAST /* 0x20 can send broadcast packets */
+#define IP_NODEFAULTFLOWID 0x40 /* Don't set the flowid from inp */
+
+#ifdef __NO_STRICT_ALIGNMENT
+#define IP_HDR_ALIGNED_P(ip) 1
+#else
+#define IP_HDR_ALIGNED_P(ip) ((((intptr_t) (ip)) & 3) == 0)
+#endif
+
+struct ip;
+struct inpcb;
+struct route;
+struct sockopt;
+
+VNET_DECLARE(int, ip_defttl); /* default IP ttl */
+VNET_DECLARE(int, ipforwarding); /* ip forwarding */
+#ifdef IPSTEALTH
+VNET_DECLARE(int, ipstealth); /* stealth forwarding */
+#endif
+extern u_char ip_protox[];
+VNET_DECLARE(struct socket *, ip_rsvpd); /* reservation protocol daemon*/
+VNET_DECLARE(struct socket *, ip_mrouter); /* multicast routing daemon */
+extern int (*legal_vif_num)(int);
+extern u_long (*ip_mcast_src)(int);
+VNET_DECLARE(int, rsvp_on);
+VNET_DECLARE(int, drop_redirect);
+extern struct pr_usrreqs rip_usrreqs;
+
+#define V_ip_id VNET(ip_id)
+#define V_ip_defttl VNET(ip_defttl)
+#define V_ipforwarding VNET(ipforwarding)
+#ifdef IPSTEALTH
+#define V_ipstealth VNET(ipstealth)
+#endif
+#define V_ip_rsvpd VNET(ip_rsvpd)
+#define V_ip_mrouter VNET(ip_mrouter)
+#define V_rsvp_on VNET(rsvp_on)
+#define V_drop_redirect VNET(drop_redirect)
+
+void inp_freemoptions(struct ip_moptions *);
+int inp_getmoptions(struct inpcb *, struct sockopt *);
+int inp_setmoptions(struct inpcb *, struct sockopt *);
+
+int ip_ctloutput(struct socket *, struct sockopt *sopt);
+void ip_drain(void);
+int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
+ u_long if_hwassist_flags);
+void ip_forward(struct mbuf *m, int srcrt);
+void ip_init(void);
+#ifdef VIMAGE
+void ip_destroy(void);
+#endif
+extern int
+ (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
+ struct ip_moptions *);
+int ip_output(struct mbuf *,
+ struct mbuf *, struct route *, int, struct ip_moptions *,
+ struct inpcb *);
+int ipproto_register(short);
+int ipproto_unregister(short);
+struct mbuf *
+ ip_reass(struct mbuf *);
+struct in_ifaddr *
+ ip_rtaddr(struct in_addr, u_int fibnum);
+void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
+ struct mbuf *);
+void ip_slowtimo(void);
+void ip_fillid(struct ip *);
+int rip_ctloutput(struct socket *, struct sockopt *);
+void rip_ctlinput(int, struct sockaddr *, void *);
+void rip_init(void);
+#ifdef VIMAGE
+void rip_destroy(void);
+#endif
+int rip_input(struct mbuf **, int *, int);
+int rip_output(struct mbuf *, struct socket *, ...);
+int ipip_input(struct mbuf **, int *, int);
+int rsvp_input(struct mbuf **, int *, int);
+int ip_rsvp_init(struct socket *);
+int ip_rsvp_done(void);
+extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
+extern void (*ip_rsvp_force_done)(struct socket *);
+extern int (*rsvp_input_p)(struct mbuf **, int *, int);
+
+VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */
+#define V_inet_pfil_hook VNET(inet_pfil_hook)
+
+void in_delayed_cksum(struct mbuf *m);
+
+/* Hooks for ipfw, dummynet, divert etc. Most are declared in raw_ip.c */
+/*
+ * Reference to an ipfw or packet filter rule that can be carried
+ * outside critical sections.
+ * A rule is identified by rulenum:rule_id which is ordered.
+ * In version chain_id the rule can be found in slot 'slot', so
+ * we don't need a lookup if chain_id == chain->id.
+ *
+ * On exit from the firewall this structure refers to the rule after
+ * the matching one (slot points to the new rule; rulenum:rule_id-1
+ * is the matching rule), and additional info (e.g. info often contains
+ * the insn argument or tablearg in the low 16 bits, in host format).
+ * On entry, the structure is valid if slot>0, and refers to the starting
+ * rules. 'info' contains the reason for reinject, e.g. divert port,
+ * divert direction, and so on.
+ */
+struct ipfw_rule_ref {
+ uint32_t slot; /* slot for matching rule */
+ uint32_t rulenum; /* matching rule number */
+ uint32_t rule_id; /* matching rule id */
+ uint32_t chain_id; /* ruleset id */
+ uint32_t info; /* see below */
+};
+
+enum {
+ IPFW_INFO_MASK = 0x0000ffff,
+ IPFW_INFO_OUT = 0x00000000, /* outgoing, just for convenience */
+ IPFW_INFO_IN = 0x80000000, /* incoming, overloads dir */
+ IPFW_ONEPASS = 0x40000000, /* One-pass, do not reinject */
+ IPFW_IS_MASK = 0x30000000, /* which source ? */
+ IPFW_IS_DIVERT = 0x20000000,
+ IPFW_IS_DUMMYNET =0x10000000,
+ IPFW_IS_PIPE = 0x08000000, /* pipe=1, queue = 0 */
+};
+#define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */
+#define MTAG_IPFW_RULE 1262273568 /* rule reference */
+#define MTAG_IPFW_CALL 1308397630 /* call stack */
+
+struct ip_fw_args;
+typedef int (*ip_fw_chk_ptr_t)(struct ip_fw_args *args);
+typedef int (*ip_fw_ctl_ptr_t)(struct sockopt *);
+VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr);
+#define V_ip_fw_ctl_ptr VNET(ip_fw_ctl_ptr)
+
+/* Divert hooks. */
+extern void (*ip_divert_ptr)(struct mbuf *m, int incoming);
+/* ng_ipfw hooks -- XXX make it the same as divert and dummynet */
+extern int (*ng_ipfw_input_p)(struct mbuf **, int,
+ struct ip_fw_args *, int);
+
+extern int (*ip_dn_ctl_ptr)(struct sockopt *);
+extern int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *);
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_IP_VAR_H_ */
diff --git a/usr/src/boot/include/netinet/udp.h b/usr/src/boot/include/netinet/udp.h
new file mode 100644
index 0000000000..c2d638dde3
--- /dev/null
+++ b/usr/src/boot/include/netinet/udp.h
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)udp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_UDP_H_
+#define _NETINET_UDP_H_
+
+/*
+ * UDP protocol header.
+ * Per RFC 768, September, 1981.
+ */
+struct udphdr {
+ u_short uh_sport; /* source port */
+ u_short uh_dport; /* destination port */
+ u_short uh_ulen; /* udp length */
+ u_short uh_sum; /* udp checksum */
+};
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define UDP_ENCAP 1
+
+/* Start of reserved space for third-party user-settable options. */
+#define UDP_VENDOR SO_VENDOR
+
+/*
+ * UDP Encapsulation of IPsec Packets options.
+ */
+/* Encapsulation types. */
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
+#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-02+ */
+
+/* Default ESP in UDP encapsulation port. */
+#define UDP_ENCAP_ESPINUDP_PORT 500
+
+/* Maximum UDP fragment size for ESP over UDP. */
+#define UDP_ENCAP_ESPINUDP_MAXFRAGLEN 552
+
+#endif
diff --git a/usr/src/boot/include/netinet/udp_var.h b/usr/src/boot/include/netinet/udp_var.h
new file mode 100644
index 0000000000..40d35ef438
--- /dev/null
+++ b/usr/src/boot/include/netinet/udp_var.h
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_UDP_VAR_H_
+#define _NETINET_UDP_VAR_H_
+
+/*
+ * UDP kernel structures and variables.
+ */
+struct udpiphdr {
+ struct ipovly ui_i; /* overlaid ip structure */
+ struct udphdr ui_u; /* udp header */
+};
+#define ui_x1 ui_i.ih_x1
+#define ui_v ui_i.ih_x1[0]
+#define ui_pr ui_i.ih_pr
+#define ui_len ui_i.ih_len
+#define ui_src ui_i.ih_src
+#define ui_dst ui_i.ih_dst
+#define ui_sport ui_u.uh_sport
+#define ui_dport ui_u.uh_dport
+#define ui_ulen ui_u.uh_ulen
+#define ui_sum ui_u.uh_sum
+
+struct inpcb;
+struct mbuf;
+
+typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *,
+ const struct sockaddr *, void *);
+
+/*
+ * UDP control block; one per udp.
+ */
+struct udpcb {
+ udp_tun_func_t u_tun_func; /* UDP kernel tunneling callback. */
+ u_int u_flags; /* Generic UDP flags. */
+ uint16_t u_rxcslen; /* Coverage for incoming datagrams. */
+ uint16_t u_txcslen; /* Coverage for outgoing datagrams. */
+ void *u_tun_ctx; /* Tunneling callback context. */
+};
+
+#define intoudpcb(ip) ((struct udpcb *)(ip)->inp_ppcb)
+#define sotoudpcb(so) (intoudpcb(sotoinpcb(so)))
+
+ /* IPsec: ESP in UDP tunneling: */
+#define UF_ESPINUDP_NON_IKE 0x00000001 /* w/ non-IKE marker .. */
+ /* .. per draft-ietf-ipsec-nat-t-ike-0[01],
+ * and draft-ietf-ipsec-udp-encaps-(00/)01.txt */
+#define UF_ESPINUDP 0x00000002 /* w/ non-ESP marker. */
+
+struct udpstat {
+ /* input statistics: */
+ uint64_t udps_ipackets; /* total input packets */
+ uint64_t udps_hdrops; /* packet shorter than header */
+ uint64_t udps_badsum; /* checksum error */
+ uint64_t udps_nosum; /* no checksum */
+ uint64_t udps_badlen; /* data length larger than packet */
+ uint64_t udps_noport; /* no socket on port */
+ uint64_t udps_noportbcast; /* of above, arrived as broadcast */
+ uint64_t udps_fullsock; /* not delivered, input socket full */
+ uint64_t udpps_pcbcachemiss; /* input packets missing pcb cache */
+ uint64_t udpps_pcbhashmiss; /* input packets not for hashed pcb */
+ /* output statistics: */
+ uint64_t udps_opackets; /* total output packets */
+ uint64_t udps_fastout; /* output packets on fast path */
+ /* of no socket on port, arrived as multicast */
+ uint64_t udps_noportmcast;
+ uint64_t udps_filtermcast; /* blocked by multicast filter */
+};
+
+#ifdef _KERNEL
+#include <sys/counter.h>
+
+VNET_PCPUSTAT_DECLARE(struct udpstat, udpstat);
+/*
+ * In-kernel consumers can use these accessor macros directly to update
+ * stats.
+ */
+#define UDPSTAT_ADD(name, val) \
+ VNET_PCPUSTAT_ADD(struct udpstat, udpstat, name, (val))
+#define UDPSTAT_INC(name) UDPSTAT_ADD(name, 1)
+
+/*
+ * Kernel module consumers must use this accessor macro.
+ */
+void kmod_udpstat_inc(int statnum);
+#define KMOD_UDPSTAT_INC(name) \
+ kmod_udpstat_inc(offsetof(struct udpstat, name) / sizeof(uint64_t))
+#endif
+
+/*
+ * Identifiers for UDP sysctl nodes.
+ */
+#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
+#define UDPCTL_STATS 2 /* statistics (read-only) */
+#define UDPCTL_MAXDGRAM 3 /* max datagram size */
+#define UDPCTL_RECVSPACE 4 /* default receive buffer space */
+#define UDPCTL_PCBLIST 5 /* list of PCBs for UDP sockets */
+
+#ifdef _KERNEL
+#include <netinet/in_pcb.h>
+SYSCTL_DECL(_net_inet_udp);
+
+extern struct pr_usrreqs udp_usrreqs;
+VNET_DECLARE(struct inpcbhead, udb);
+VNET_DECLARE(struct inpcbinfo, udbinfo);
+VNET_DECLARE(struct inpcbhead, ulitecb);
+VNET_DECLARE(struct inpcbinfo, ulitecbinfo);
+#define V_udb VNET(udb)
+#define V_udbinfo VNET(udbinfo)
+#define V_ulitecb VNET(ulitecb)
+#define V_ulitecbinfo VNET(ulitecbinfo)
+
+extern u_long udp_sendspace;
+extern u_long udp_recvspace;
+VNET_DECLARE(int, udp_cksum);
+VNET_DECLARE(int, udp_blackhole);
+#define V_udp_cksum VNET(udp_cksum)
+#define V_udp_blackhole VNET(udp_blackhole)
+extern int udp_log_in_vain;
+
+static __inline struct inpcbinfo *
+udp_get_inpcbinfo(int protocol)
+{
+ return (protocol == IPPROTO_UDP) ? &V_udbinfo : &V_ulitecbinfo;
+}
+
+static __inline struct inpcbhead *
+udp_get_pcblist(int protocol)
+{
+ return (protocol == IPPROTO_UDP) ? &V_udb : &V_ulitecb;
+}
+
+int udp_newudpcb(struct inpcb *);
+void udp_discardcb(struct udpcb *);
+
+void udp_ctlinput(int, struct sockaddr *, void *);
+void udplite_ctlinput(int, struct sockaddr *, void *);
+int udp_ctloutput(struct socket *, struct sockopt *);
+void udp_init(void);
+void udplite_init(void);
+#ifdef VIMAGE
+void udp_destroy(void);
+void udplite_destroy(void);
+#endif
+int udp_input(struct mbuf **, int *, int);
+void udplite_input(struct mbuf *, int);
+struct inpcb *udp_notify(struct inpcb *inp, int errno);
+int udp_shutdown(struct socket *so);
+
+int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f,
+ void *ctx);
+
+#endif /* _KERNEL */
+
+#endif /* _NETINET_UDP_VAR_H_ */
diff --git a/usr/src/boot/include/netinet6/in6.h b/usr/src/boot/include/netinet6/in6.h
new file mode 100644
index 0000000000..81d8d318cd
--- /dev/null
+++ b/usr/src/boot/include/netinet6/in6.h
@@ -0,0 +1,733 @@
+/*-
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $KAME: in6.h,v 1.89 2001/05/27 13:28:35 itojun Exp $
+ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ * $FreeBSD$
+ */
+
+#ifndef __KAME_NETINET_IN_H_INCLUDED_
+#error "do not include netinet6/in6.h directly, include netinet/in.h. see RFC2553"
+#endif
+
+#ifndef _NETINET6_IN6_H_
+#define _NETINET6_IN6_H_
+
+/*
+ * Identification of the network protocol stack
+ * for *BSD-current/release: http://www.kame.net/dev/cvsweb.cgi/kame/COVERAGE
+ * has the table of implementation/integration differences.
+ */
+#define __KAME__
+#define __KAME_VERSION "FreeBSD"
+
+/*
+ * IPv6 port allocation rules should mirror the IPv4 rules and are controlled
+ * by the net.inet.ip.portrange sysctl tree. The following defines exist
+ * for compatibility with userland applications that need them.
+ */
+#if __BSD_VISIBLE
+#define IPV6PORT_RESERVED 1024
+#define IPV6PORT_ANONMIN 49152
+#define IPV6PORT_ANONMAX 65535
+#define IPV6PORT_RESERVEDMIN 600
+#define IPV6PORT_RESERVEDMAX (IPV6PORT_RESERVED-1)
+#endif
+
+/*
+ * IPv6 address
+ */
+struct in6_addr {
+ union {
+ uint8_t __u6_addr8[16];
+ uint16_t __u6_addr16[8];
+ uint32_t __u6_addr32[4];
+ } __u6_addr; /* 128-bit IP6 address */
+};
+
+#define s6_addr __u6_addr.__u6_addr8
+#ifdef _KERNEL /* XXX nonstandard */
+#define s6_addr8 __u6_addr.__u6_addr8
+#define s6_addr16 __u6_addr.__u6_addr16
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+#define INET6_ADDRSTRLEN 46
+
+/*
+ * XXX missing POSIX.1-2001 macro IPPROTO_IPV6.
+ */
+
+/*
+ * Socket address for IPv6
+ */
+#if __BSD_VISIBLE
+#define SIN6_LEN
+#endif
+
+struct sockaddr_in6 {
+ uint8_t sin6_len; /* length of this struct */
+ sa_family_t sin6_family; /* AF_INET6 */
+ in_port_t sin6_port; /* Transport layer port # */
+ uint32_t sin6_flowinfo; /* IP6 flow information */
+ struct in6_addr sin6_addr; /* IP6 address */
+ uint32_t sin6_scope_id; /* scope zone index */
+};
+
+/*
+ * Local definition for masks
+ */
+#ifdef _KERNEL /* XXX nonstandard */
+#define IN6MASK0 {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}}
+#define IN6MASK32 {{{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK64 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK96 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK128 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
+#endif
+
+#ifdef _KERNEL
+extern const struct sockaddr_in6 sa6_any;
+
+extern const struct in6_addr in6mask0;
+extern const struct in6_addr in6mask32;
+extern const struct in6_addr in6mask64;
+extern const struct in6_addr in6mask96;
+extern const struct in6_addr in6mask128;
+#endif /* _KERNEL */
+
+/*
+ * Macros started with IPV6_ADDR is KAME local
+ */
+#ifdef _KERNEL /* XXX nonstandard */
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define IPV6_ADDR_INT32_ONE 1
+#define IPV6_ADDR_INT32_TWO 2
+#define IPV6_ADDR_INT32_MNL 0xff010000
+#define IPV6_ADDR_INT32_MLL 0xff020000
+#define IPV6_ADDR_INT32_SMP 0x0000ffff
+#define IPV6_ADDR_INT16_ULL 0xfe80
+#define IPV6_ADDR_INT16_USL 0xfec0
+#define IPV6_ADDR_INT16_MLL 0xff02
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define IPV6_ADDR_INT32_ONE 0x01000000
+#define IPV6_ADDR_INT32_TWO 0x02000000
+#define IPV6_ADDR_INT32_MNL 0x000001ff
+#define IPV6_ADDR_INT32_MLL 0x000002ff
+#define IPV6_ADDR_INT32_SMP 0xffff0000
+#define IPV6_ADDR_INT16_ULL 0x80fe
+#define IPV6_ADDR_INT16_USL 0xc0fe
+#define IPV6_ADDR_INT16_MLL 0x02ff
+#endif
+#endif
+
+/*
+ * Definition of some useful macros to handle IP6 addresses
+ */
+#if __BSD_VISIBLE
+#define IN6ADDR_ANY_INIT \
+ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6ADDR_LOOPBACK_INIT \
+ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_NODELOCAL_ALLNODES_INIT \
+ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_INTFACELOCAL_ALLNODES_INIT \
+ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
+ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
+ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
+#define IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT \
+ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 }}}
+#endif
+
+extern const struct in6_addr in6addr_any;
+extern const struct in6_addr in6addr_loopback;
+#if __BSD_VISIBLE
+extern const struct in6_addr in6addr_nodelocal_allnodes;
+extern const struct in6_addr in6addr_linklocal_allnodes;
+extern const struct in6_addr in6addr_linklocal_allrouters;
+extern const struct in6_addr in6addr_linklocal_allv2routers;
+#endif
+
+/*
+ * Equality
+ * NOTE: Some of kernel programming environment (for example, openbsd/sparc)
+ * does not supply memcmp(). For userland memcmp() is preferred as it is
+ * in ANSI standard.
+ */
+#ifdef _KERNEL
+#define IN6_ARE_ADDR_EQUAL(a, b) \
+ (bcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+#else
+#if __BSD_VISIBLE
+#define IN6_ARE_ADDR_EQUAL(a, b) \
+ (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+#endif
+#endif
+
+/*
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ ((a)->__u6_addr.__u6_addr32[0] == 0 && \
+ (a)->__u6_addr.__u6_addr32[1] == 0 && \
+ (a)->__u6_addr.__u6_addr32[2] == 0 && \
+ (a)->__u6_addr.__u6_addr32[3] == 0)
+
+/*
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ ((a)->__u6_addr.__u6_addr32[0] == 0 && \
+ (a)->__u6_addr.__u6_addr32[1] == 0 && \
+ (a)->__u6_addr.__u6_addr32[2] == 0 && \
+ (a)->__u6_addr.__u6_addr32[3] == ntohl(1))
+
+/*
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ ((a)->__u6_addr.__u6_addr32[0] == 0 && \
+ (a)->__u6_addr.__u6_addr32[1] == 0 && \
+ (a)->__u6_addr.__u6_addr32[2] == 0 && \
+ (a)->__u6_addr.__u6_addr32[3] != 0 && \
+ (a)->__u6_addr.__u6_addr32[3] != ntohl(1))
+
+/*
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ((a)->__u6_addr.__u6_addr32[0] == 0 && \
+ (a)->__u6_addr.__u6_addr32[1] == 0 && \
+ (a)->__u6_addr.__u6_addr32[2] == ntohl(0x0000ffff))
+
+/*
+ * KAME Scope Values
+ */
+
+#ifdef _KERNEL /* XXX nonstandard */
+#define IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */
+#define IPV6_ADDR_SCOPE_GLOBAL 0x0e
+#else
+#define __IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define __IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
+#define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define __IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */
+#define __IPV6_ADDR_SCOPE_GLOBAL 0x0e
+#endif
+
+/*
+ * Unicast Scope
+ * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
+ */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+
+/*
+ * Multicast
+ */
+#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
+
+#ifdef _KERNEL /* XXX nonstandard */
+#define IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+#else
+#define __IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+#endif
+
+/*
+ * Multicast Scope
+ */
+#ifdef _KERNEL /* refers nonstandard items */
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_INTFACELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_INTFACELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
+#else
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL))
+#endif
+
+#ifdef _KERNEL /* nonstandard */
+/*
+ * KAME Scope
+ */
+#define IN6_IS_SCOPE_LINKLOCAL(a) \
+ ((IN6_IS_ADDR_LINKLOCAL(a)) || \
+ (IN6_IS_ADDR_MC_LINKLOCAL(a)))
+#define IN6_IS_SCOPE_EMBED(a) \
+ ((IN6_IS_ADDR_LINKLOCAL(a)) || \
+ (IN6_IS_ADDR_MC_LINKLOCAL(a)) || \
+ (IN6_IS_ADDR_MC_INTFACELOCAL(a)))
+
+#define IFA6_IS_DEPRECATED(a) \
+ ((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \
+ (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
+ (a)->ia6_lifetime.ia6t_pltime)
+#define IFA6_IS_INVALID(a) \
+ ((a)->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME && \
+ (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
+ (a)->ia6_lifetime.ia6t_vltime)
+#endif /* _KERNEL */
+
+/*
+ * IP6 route structure
+ */
+#if __BSD_VISIBLE
+struct route_in6 {
+ struct rtentry *ro_rt;
+ struct llentry *ro_lle;
+ struct in6_addr *ro_ia6;
+ int ro_flags;
+ struct sockaddr_in6 ro_dst;
+};
+#endif
+
+/*
+ * Options for use with [gs]etsockopt at the IPV6 level.
+ * First word of comment is data type; bool is stored in int.
+ */
+/* no hdrincl */
+#if 0 /* the followings are relic in IPv4 and hence are disabled */
+#define IPV6_OPTIONS 1 /* buf/ip6_opts; set/get IP6 options */
+#define IPV6_RECVOPTS 5 /* bool; receive all IP6 opts w/dgram */
+#define IPV6_RECVRETOPTS 6 /* bool; receive IP6 opts for response */
+#define IPV6_RECVDSTADDR 7 /* bool; receive IP6 dst addr w/dgram */
+#define IPV6_RETOPTS 8 /* ip6_opts; set/get IP6 options */
+#endif
+#define IPV6_SOCKOPT_RESERVED1 3 /* reserved for future use */
+#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */
+#define IPV6_MULTICAST_IF 9 /* u_int; set/get IP6 multicast i/f */
+#define IPV6_MULTICAST_HOPS 10 /* int; set/get IP6 multicast hops */
+#define IPV6_MULTICAST_LOOP 11 /* u_int; set/get IP6 multicast loopback */
+#define IPV6_JOIN_GROUP 12 /* ipv6_mreq; join a group membership */
+#define IPV6_LEAVE_GROUP 13 /* ipv6_mreq; leave a group membership */
+#define IPV6_PORTRANGE 14 /* int; range to choose for unspec port */
+#define ICMP6_FILTER 18 /* icmp6_filter; icmp6 filter */
+/* RFC2292 options */
+#ifdef _KERNEL
+#define IPV6_2292PKTINFO 19 /* bool; send/recv if, src/dst addr */
+#define IPV6_2292HOPLIMIT 20 /* bool; hop limit */
+#define IPV6_2292NEXTHOP 21 /* bool; next hop addr */
+#define IPV6_2292HOPOPTS 22 /* bool; hop-by-hop option */
+#define IPV6_2292DSTOPTS 23 /* bool; destinaion option */
+#define IPV6_2292RTHDR 24 /* bool; routing header */
+#define IPV6_2292PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */
+#endif
+
+#define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */
+#define IPV6_V6ONLY 27 /* bool; make AF_INET6 sockets v6 only */
+#ifndef _KERNEL
+#define IPV6_BINDV6ONLY IPV6_V6ONLY
+#endif
+
+#if 1 /* IPSEC */
+#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
+#endif /* IPSEC */
+
+ /* 29; unused; was IPV6_FAITH */
+#if 1 /* IPV6FIREWALL */
+#define IPV6_FW_ADD 30 /* add a firewall rule to chain */
+#define IPV6_FW_DEL 31 /* delete a firewall rule from chain */
+#define IPV6_FW_FLUSH 32 /* flush firewall rule chain */
+#define IPV6_FW_ZERO 33 /* clear single/all firewall counter(s) */
+#define IPV6_FW_GET 34 /* get entire firewall rule chain */
+#endif
+
+/* new socket options introduced in RFC3542 */
+#define IPV6_RTHDRDSTOPTS 35 /* ip6_dest; send dst option before rthdr */
+
+#define IPV6_RECVPKTINFO 36 /* bool; recv if, dst addr */
+#define IPV6_RECVHOPLIMIT 37 /* bool; recv hop limit */
+#define IPV6_RECVRTHDR 38 /* bool; recv routing header */
+#define IPV6_RECVHOPOPTS 39 /* bool; recv hop-by-hop option */
+#define IPV6_RECVDSTOPTS 40 /* bool; recv dst option after rthdr */
+#ifdef _KERNEL
+#define IPV6_RECVRTHDRDSTOPTS 41 /* bool; recv dst option before rthdr */
+#endif
+
+#define IPV6_USE_MIN_MTU 42 /* bool; send packets at the minimum MTU */
+#define IPV6_RECVPATHMTU 43 /* bool; notify an according MTU */
+
+#define IPV6_PATHMTU 44 /* mtuinfo; get the current path MTU (sopt),
+ 4 bytes int; MTU notification (cmsg) */
+#if 0 /*obsoleted during 2292bis -> 3542*/
+#define IPV6_REACHCONF 45 /* no data; ND reachability confirm
+ (cmsg only/not in of RFC3542) */
+#endif
+
+/* more new socket options introduced in RFC3542 */
+#define IPV6_PKTINFO 46 /* in6_pktinfo; send if, src addr */
+#define IPV6_HOPLIMIT 47 /* int; send hop limit */
+#define IPV6_NEXTHOP 48 /* sockaddr; next hop addr */
+#define IPV6_HOPOPTS 49 /* ip6_hbh; send hop-by-hop option */
+#define IPV6_DSTOPTS 50 /* ip6_dest; send dst option befor rthdr */
+#define IPV6_RTHDR 51 /* ip6_rthdr; send routing header */
+#if 0
+#define IPV6_PKTOPTIONS 52 /* buf/cmsghdr; set/get IPv6 options */
+ /* obsoleted by RFC3542 */
+#endif
+
+#define IPV6_RECVTCLASS 57 /* bool; recv traffic class values */
+
+#define IPV6_AUTOFLOWLABEL 59 /* bool; attach flowlabel automagically */
+
+#define IPV6_TCLASS 61 /* int; send traffic class value */
+#define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */
+
+#define IPV6_PREFER_TEMPADDR 63 /* int; prefer temporary addresses as
+ * the source address.
+ */
+
+#define IPV6_BINDANY 64 /* bool: allow bind to any address */
+
+#define IPV6_BINDMULTI 65 /* bool; allow multibind to same addr/port */
+#define IPV6_RSS_LISTEN_BUCKET 66 /* int; set RSS listen bucket */
+#define IPV6_FLOWID 67 /* int; flowid of given socket */
+#define IPV6_FLOWTYPE 68 /* int; flowtype of given socket */
+#define IPV6_RSSBUCKETID 69 /* int; RSS bucket ID of given socket */
+#define IPV6_RECVFLOWID 70 /* bool; receive IP6 flowid/flowtype w/ datagram */
+#define IPV6_RECVRSSBUCKETID 71 /* bool; receive IP6 RSS bucket id w/ datagram */
+
+/*
+ * The following option is private; do not use it from user applications.
+ * It is deliberately defined to the same value as IP_MSFILTER.
+ */
+#define IPV6_MSFILTER 74 /* struct __msfilterreq;
+ * set/get multicast source filter list.
+ */
+
+/* to define items, should talk with KAME guys first, for *BSD compatibility */
+
+#define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */
+#define IPV6_RTHDR_STRICT 1 /* this hop must be a neighbor. XXX old spec */
+#define IPV6_RTHDR_TYPE_0 0 /* IPv6 routing header type 0 */
+
+/*
+ * Defaults and limits for options
+ */
+#define IPV6_DEFAULT_MULTICAST_HOPS 1 /* normally limit m'casts to 1 hop */
+#define IPV6_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+
+/*
+ * The im6o_membership vector for each socket is now dynamically allocated at
+ * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized
+ * according to a power-of-two increment.
+ */
+#define IPV6_MIN_MEMBERSHIPS 31
+#define IPV6_MAX_MEMBERSHIPS 4095
+
+/*
+ * Default resource limits for IPv6 multicast source filtering.
+ * These may be modified by sysctl.
+ */
+#define IPV6_MAX_GROUP_SRC_FILTER 512 /* sources per group */
+#define IPV6_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */
+
+/*
+ * Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP.
+ */
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ unsigned int ipv6mr_interface;
+};
+
+/*
+ * IPV6_PKTINFO: Packet information(RFC2292 sec 5)
+ */
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /* send/recv interface index */
+};
+
+/*
+ * Control structure for IPV6_RECVPATHMTU socket option.
+ */
+struct ip6_mtuinfo {
+ struct sockaddr_in6 ip6m_addr; /* or sockaddr_storage? */
+ uint32_t ip6m_mtu;
+};
+
+/*
+ * Argument for IPV6_PORTRANGE:
+ * - which range to search when port is unspecified at bind() or connect()
+ */
+#define IPV6_PORTRANGE_DEFAULT 0 /* default range */
+#define IPV6_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */
+#define IPV6_PORTRANGE_LOW 2 /* "low" - vouchsafe security */
+
+#if __BSD_VISIBLE
+/*
+ * Definitions for inet6 sysctl operations.
+ *
+ * Third level is protocol number.
+ * Fourth level is desired variable within that protocol.
+ */
+#define IPV6PROTO_MAXID (IPPROTO_PIM + 1) /* don't list to IPV6PROTO_MAX */
+
+/*
+ * Names for IP sysctl objects
+ */
+#define IPV6CTL_FORWARDING 1 /* act as router */
+#define IPV6CTL_SENDREDIRECTS 2 /* may send redirects when forwarding*/
+#define IPV6CTL_DEFHLIM 3 /* default Hop-Limit */
+#ifdef notyet
+#define IPV6CTL_DEFMTU 4 /* default MTU */
+#endif
+#define IPV6CTL_FORWSRCRT 5 /* forward source-routed dgrams */
+#define IPV6CTL_STATS 6 /* stats */
+#define IPV6CTL_MRTSTATS 7 /* multicast forwarding stats */
+#define IPV6CTL_MRTPROTO 8 /* multicast routing protocol */
+#define IPV6CTL_MAXFRAGPACKETS 9 /* max packets reassembly queue */
+#define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */
+#define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */
+#define IPV6CTL_ACCEPT_RTADV 12
+ /* 13; unused; was: IPV6CTL_KEEPFAITH */
+#define IPV6CTL_LOG_INTERVAL 14
+#define IPV6CTL_HDRNESTLIMIT 15
+#define IPV6CTL_DAD_COUNT 16
+#define IPV6CTL_AUTO_FLOWLABEL 17
+#define IPV6CTL_DEFMCASTHLIM 18
+#define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */
+#define IPV6CTL_KAME_VERSION 20
+#define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */
+#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */
+#if 0 /* obsolete */
+#define IPV6CTL_MAPPED_ADDR 23
+#endif
+#define IPV6CTL_V6ONLY 24
+/* IPV6CTL_RTEXPIRE 25 deprecated */
+/* IPV6CTL_RTMINEXPIRE 26 deprecated */
+/* IPV6CTL_RTMAXCACHE 27 deprecated */
+
+#define IPV6CTL_USETEMPADDR 32 /* use temporary addresses (RFC3041) */
+#define IPV6CTL_TEMPPLTIME 33 /* preferred lifetime for tmpaddrs */
+#define IPV6CTL_TEMPVLTIME 34 /* valid lifetime for tmpaddrs */
+#define IPV6CTL_AUTO_LINKLOCAL 35 /* automatic link-local addr assign */
+#define IPV6CTL_RIP6STATS 36 /* raw_ip6 stats */
+#define IPV6CTL_PREFER_TEMPADDR 37 /* prefer temporary addr as src */
+#define IPV6CTL_ADDRCTLPOLICY 38 /* get/set address selection policy */
+#define IPV6CTL_USE_DEFAULTZONE 39 /* use default scope zone */
+
+#define IPV6CTL_MAXFRAGS 41 /* max fragments */
+#if 0
+#define IPV6CTL_IFQ 42 /* ip6intrq node */
+#define IPV6CTL_ISATAPRTR 43 /* isatap router */
+#endif
+#define IPV6CTL_MCAST_PMTU 44 /* enable pMTU discovery for multicast? */
+
+/* New entries should be added here from current IPV6CTL_MAXID value. */
+/* to define items, should talk with KAME guys first, for *BSD compatibility */
+#define IPV6CTL_STEALTH 45
+
+#define ICMPV6CTL_ND6_ONLINKNSRFC4861 47
+#define IPV6CTL_NO_RADR 48 /* No defroute from RA */
+#define IPV6CTL_NORBIT_RAIF 49 /* Disable R-bit in NA on RA
+ * receiving IF. */
+#define IPV6CTL_RFC6204W3 50 /* Accept defroute even when forwarding
+ enabled */
+#define IPV6CTL_MAXID 51
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Since both netinet/ and netinet6/ call into netipsec/ and netpfil/,
+ * the protocol specific mbuf flags are shared between them.
+ */
+#define M_FASTFWD_OURS M_PROTO1 /* changed dst to local */
+#define M_IP6_NEXTHOP M_PROTO2 /* explicit ip nexthop */
+#define M_IP_NEXTHOP M_PROTO2 /* explicit ip nexthop */
+#define M_SKIP_FIREWALL M_PROTO3 /* skip firewall processing */
+#define M_AUTHIPHDR M_PROTO4
+#define M_DECRYPTED M_PROTO5
+#define M_LOOP M_PROTO6
+#define M_AUTHIPDGM M_PROTO7
+#define M_RTALERT_MLD M_PROTO8
+
+#ifdef _KERNEL
+struct cmsghdr;
+struct ip6_hdr;
+
+int in6_cksum_pseudo(struct ip6_hdr *, uint32_t, uint8_t, uint16_t);
+int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t);
+int in6_cksum_partial(struct mbuf *, u_int8_t, u_int32_t, u_int32_t,
+ u_int32_t);
+int in6_localaddr(struct in6_addr *);
+int in6_localip(struct in6_addr *);
+int in6_ifhasaddr(struct ifnet *, struct in6_addr *);
+int in6_addrscope(const struct in6_addr *);
+char *ip6_sprintf(char *, const struct in6_addr *);
+struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *);
+extern void in6_if_up(struct ifnet *);
+struct sockaddr;
+extern u_char ip6_protox[];
+
+void in6_sin6_2_sin(struct sockaddr_in *sin,
+ struct sockaddr_in6 *sin6);
+void in6_sin_2_v4mapsin6(struct sockaddr_in *sin,
+ struct sockaddr_in6 *sin6);
+void in6_sin6_2_sin_in_sock(struct sockaddr *nam);
+void in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam);
+extern void addrsel_policy_init(void);
+
+#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
+#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
+#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
+
+#endif /* _KERNEL */
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#if __BSD_VISIBLE
+
+__BEGIN_DECLS
+struct cmsghdr;
+
+extern int inet6_option_space(int);
+extern int inet6_option_init(void *, struct cmsghdr **, int);
+extern int inet6_option_append(struct cmsghdr *, const uint8_t *,
+ int, int);
+extern uint8_t *inet6_option_alloc(struct cmsghdr *, int, int, int);
+extern int inet6_option_next(const struct cmsghdr *, uint8_t **);
+extern int inet6_option_find(const struct cmsghdr *, uint8_t **, int);
+
+extern size_t inet6_rthdr_space(int, int);
+extern struct cmsghdr *inet6_rthdr_init(void *, int);
+extern int inet6_rthdr_add(struct cmsghdr *, const struct in6_addr *,
+ unsigned int);
+extern int inet6_rthdr_lasthop(struct cmsghdr *, unsigned int);
+#if 0 /* not implemented yet */
+extern int inet6_rthdr_reverse(const struct cmsghdr *, struct cmsghdr *);
+#endif
+extern int inet6_rthdr_segments(const struct cmsghdr *);
+extern struct in6_addr *inet6_rthdr_getaddr(struct cmsghdr *, int);
+extern int inet6_rthdr_getflags(const struct cmsghdr *, int);
+
+extern int inet6_opt_init(void *, socklen_t);
+extern int inet6_opt_append(void *, socklen_t, int, uint8_t, socklen_t,
+ uint8_t, void **);
+extern int inet6_opt_finish(void *, socklen_t, int);
+extern int inet6_opt_set_val(void *, int, void *, socklen_t);
+
+extern int inet6_opt_next(void *, socklen_t, int, uint8_t *, socklen_t *,
+ void **);
+extern int inet6_opt_find(void *, socklen_t, int, uint8_t, socklen_t *,
+ void **);
+extern int inet6_opt_get_val(void *, int, void *, socklen_t);
+extern socklen_t inet6_rth_space(int, int);
+extern void *inet6_rth_init(void *, socklen_t, int, int);
+extern int inet6_rth_add(void *, const struct in6_addr *);
+extern int inet6_rth_reverse(const void *, void *);
+extern int inet6_rth_segments(const void *);
+extern struct in6_addr *inet6_rth_getaddr(const void *, int);
+__END_DECLS
+
+#endif /* __BSD_VISIBLE */
+
+#endif /* !_NETINET6_IN6_H_ */
diff --git a/usr/src/boot/include/nlist.h b/usr/src/boot/include/nlist.h
new file mode 100644
index 0000000000..a4965fd969
--- /dev/null
+++ b/usr/src/boot/include/nlist.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)nlist.h 8.2 (Berkeley) 1/21/94
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _NLIST_H_
+#define _NLIST_H_
+
+#include <sys/nlist_aout.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int nlist(const char *, struct nlist *);
+__END_DECLS
+
+#endif /* !_NLIST_H_ */
diff --git a/usr/src/boot/include/runetype.h b/usr/src/boot/include/runetype.h
new file mode 100644
index 0000000000..6aad915b56
--- /dev/null
+++ b/usr/src/boot/include/runetype.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)runetype.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _RUNETYPE_H_
+#define _RUNETYPE_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */
+#define _CRMASK (~(_CACHED_RUNES - 1))
+
+/*
+ * The lower 8 bits of runetype[] contain the digit value of the rune.
+ */
+typedef struct {
+ __rune_t __min; /* First rune of the range */
+ __rune_t __max; /* Last rune (inclusive) of the range */
+ __rune_t __map; /* What first maps to in maps */
+ unsigned long *__types; /* Array of types in range */
+} _RuneEntry;
+
+typedef struct {
+ int __nranges; /* Number of ranges stored */
+ _RuneEntry *__ranges; /* Pointer to the ranges */
+} _RuneRange;
+
+typedef struct {
+ char __magic[8]; /* Magic saying what version we are */
+ char __encoding[32]; /* ASCII name of this encoding */
+
+ __rune_t (*__sgetrune)(const char *, __size_t, char const **);
+ int (*__sputrune)(__rune_t, char *, __size_t, char **);
+ __rune_t __invalid_rune;
+
+ unsigned long __runetype[_CACHED_RUNES];
+ __rune_t __maplower[_CACHED_RUNES];
+ __rune_t __mapupper[_CACHED_RUNES];
+
+ /*
+ * The following are to deal with Runes larger than _CACHED_RUNES - 1.
+ * Their data is actually contiguous with this structure so as to make
+ * it easier to read/write from/to disk.
+ */
+ _RuneRange __runetype_ext;
+ _RuneRange __maplower_ext;
+ _RuneRange __mapupper_ext;
+
+ void *__variable; /* Data which depends on the encoding */
+ int __variable_len; /* how long that data is */
+} _RuneLocale;
+
+#define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */
+__BEGIN_DECLS
+extern const _RuneLocale _DefaultRuneLocale;
+extern const _RuneLocale *_CurrentRuneLocale;
+#if defined(__NO_TLS) || defined(__RUNETYPE_INTERNAL)
+extern const _RuneLocale *__getCurrentRuneLocale(void);
+#else
+extern _Thread_local const _RuneLocale *_ThreadRuneLocale;
+static __inline const _RuneLocale *__getCurrentRuneLocale(void)
+{
+
+ if (_ThreadRuneLocale)
+ return _ThreadRuneLocale;
+ if (_CurrentRuneLocale)
+ return _CurrentRuneLocale;
+ return &_DefaultRuneLocale;
+}
+#endif /* __NO_TLS || __RUNETYPE_INTERNAL */
+#define _CurrentRuneLocale (__getCurrentRuneLocale())
+__END_DECLS
+
+#endif /* !_RUNETYPE_H_ */
diff --git a/usr/src/boot/include/setjmp.h b/usr/src/boot/include/setjmp.h
new file mode 100644
index 0000000000..598e07a77b
--- /dev/null
+++ b/usr/src/boot/include/setjmp.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)setjmp.h 8.2 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+#include <sys/cdefs.h>
+
+/* The size of the jmp_buf is machine dependent: */
+#include <machine/setjmp.h>
+
+__BEGIN_DECLS
+#if __XSI_VISIBLE >= 600
+void _longjmp(jmp_buf, int) __dead2;
+int _setjmp(jmp_buf) __returns_twice;
+#endif
+void longjmp(jmp_buf, int) __dead2;
+#if __BSD_VISIBLE
+void longjmperror(void);
+#endif
+int setjmp(jmp_buf) __returns_twice;
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+void siglongjmp(sigjmp_buf, int) __dead2;
+int sigsetjmp(sigjmp_buf, int) __returns_twice;
+#endif
+__END_DECLS
+
+#endif /* !_SETJMP_H_ */
diff --git a/usr/src/boot/include/stdarg.h b/usr/src/boot/include/stdarg.h
new file mode 100644
index 0000000000..1f80090356
--- /dev/null
+++ b/usr/src/boot/include/stdarg.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/stdarg.h>
diff --git a/usr/src/boot/include/stdbool.h b/usr/src/boot/include/stdbool.h
new file mode 100644
index 0000000000..48070c18df
--- /dev/null
+++ b/usr/src/boot/include/stdbool.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2000 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __bool_true_false_are_defined
+#define __bool_true_false_are_defined 1
+
+#ifndef __cplusplus
+
+#define false 0
+#define true 1
+
+#define bool _Bool
+#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER)
+typedef int _Bool;
+#endif
+
+#endif /* !__cplusplus */
+#endif /* __bool_true_false_are_defined */
diff --git a/usr/src/boot/include/stddef.h b/usr/src/boot/include/stddef.h
new file mode 100644
index 0000000000..7898da251a
--- /dev/null
+++ b/usr/src/boot/include/stddef.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stddef.h 8.1 (Berkeley) 6/2/93
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#ifndef _PTRDIFF_T_DECLARED
+typedef __ptrdiff_t ptrdiff_t;
+#define _PTRDIFF_T_DECLARED
+#endif
+
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef __rune_t rune_t;
+#define _RUNE_T_DECLARED
+#endif
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#ifndef __cplusplus
+#ifndef _WCHAR_T_DECLARED
+typedef ___wchar_t wchar_t;
+#define _WCHAR_T_DECLARED
+#endif
+#endif
+
+#define offsetof(type, member) __offsetof(type, member)
+
+#endif /* _STDDEF_H_ */
diff --git a/usr/src/boot/include/stdio.h b/usr/src/boot/include/stdio.h
new file mode 100644
index 0000000000..f55aaf7c72
--- /dev/null
+++ b/usr/src/boot/include/stdio.h
@@ -0,0 +1,527 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stdio.h 8.5 (Berkeley) 4/29/95
+ * $FreeBSD$
+ */
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+typedef __off_t fpos_t;
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#if __POSIX_VISIBLE >= 200809
+#ifndef _OFF_T_DECLARED
+#define _OFF_T_DECLARED
+typedef __off_t off_t;
+#endif
+#ifndef _SSIZE_T_DECLARED
+#define _SSIZE_T_DECLARED
+typedef __ssize_t ssize_t;
+#endif
+#endif
+
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#ifndef _VA_LIST_DECLARED
+typedef __va_list va_list;
+#define _VA_LIST_DECLARED
+#endif
+#endif
+
+#define _FSTDIO /* Define for new stdio with functions. */
+
+/*
+ * NB: to fit things in six character monocase externals, the stdio
+ * code uses the prefix `__s' for stdio objects, typically followed
+ * by a three-character attempt at a mnemonic.
+ */
+
+/* stdio buffers */
+struct __sbuf {
+ unsigned char *_base;
+ int _size;
+};
+
+/*
+ * stdio state variables.
+ *
+ * The following always hold:
+ *
+ * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
+ * _lbfsize is -_bf._size, else _lbfsize is 0
+ * if _flags&__SRD, _w is 0
+ * if _flags&__SWR, _r is 0
+ *
+ * This ensures that the getc and putc macros (or inline functions) never
+ * try to write or read from a file that is in `read' or `write' mode.
+ * (Moreover, they can, and do, automatically switch from read mode to
+ * write mode, and back, on "r+" and "w+" files.)
+ *
+ * _lbfsize is used only to make the inline line-buffered output stream
+ * code as compact as possible.
+ *
+ * _ub, _up, and _ur are used when ungetc() pushes back more characters
+ * than fit in the current _bf, or when ungetc() pushes back a character
+ * that does not match the previous one in _bf. When this happens,
+ * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
+ * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
+ *
+ * Certain members of __sFILE are accessed directly via macros or
+ * inline functions. To preserve ABI compat, these members must not
+ * be disturbed. These members are marked below with (*).
+ */
+struct __sFILE {
+ unsigned char *_p; /* (*) current position in (some) buffer */
+ int _r; /* (*) read space left for getc() */
+ int _w; /* (*) write space left for putc() */
+ short _flags; /* (*) flags, below; this FILE is free if 0 */
+ short _file; /* (*) fileno, if Unix descriptor, else -1 */
+ struct __sbuf _bf; /* (*) the buffer (at least 1 byte, if !NULL) */
+ int _lbfsize; /* (*) 0 or -_bf._size, for inline putc */
+
+ /* operations */
+ void *_cookie; /* (*) cookie passed to io functions */
+ int (*_close)(void *);
+ int (*_read)(void *, char *, int);
+ fpos_t (*_seek)(void *, fpos_t, int);
+ int (*_write)(void *, const char *, int);
+
+ /* separate buffer for long sequences of ungetc() */
+ struct __sbuf _ub; /* ungetc buffer */
+ unsigned char *_up; /* saved _p when _p is doing ungetc data */
+ int _ur; /* saved _r when _r is counting ungetc data */
+
+ /* tricks to meet minimum requirements even when malloc() fails */
+ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
+ unsigned char _nbuf[1]; /* guarantee a getc() buffer */
+
+ /* separate buffer for fgetln() when line crosses buffer boundary */
+ struct __sbuf _lb; /* buffer for fgetln() */
+
+ /* Unix stdio files get aligned to block boundaries on fseek() */
+ int _blksize; /* stat.st_blksize (may be != _bf._size) */
+ fpos_t _offset; /* current lseek offset */
+
+ struct pthread_mutex *_fl_mutex; /* used for MT-safety */
+ struct pthread *_fl_owner; /* current owner */
+ int _fl_count; /* recursive lock count */
+ int _orientation; /* orientation for fwide() */
+ __mbstate_t _mbstate; /* multibyte conversion state */
+ int _flags2; /* additional flags */
+};
+#ifndef _STDFILE_DECLARED
+#define _STDFILE_DECLARED
+typedef struct __sFILE FILE;
+#endif
+#ifndef _STDSTREAM_DECLARED
+__BEGIN_DECLS
+extern FILE *__stdinp;
+extern FILE *__stdoutp;
+extern FILE *__stderrp;
+__END_DECLS
+#define _STDSTREAM_DECLARED
+#endif
+
+#define __SLBF 0x0001 /* line buffered */
+#define __SNBF 0x0002 /* unbuffered */
+#define __SRD 0x0004 /* OK to read */
+#define __SWR 0x0008 /* OK to write */
+ /* RD and WR are never simultaneously asserted */
+#define __SRW 0x0010 /* open for reading & writing */
+#define __SEOF 0x0020 /* found EOF */
+#define __SERR 0x0040 /* found error */
+#define __SMBF 0x0080 /* _bf._base is from malloc */
+#define __SAPP 0x0100 /* fdopen()ed in append mode */
+#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
+#define __SOPT 0x0400 /* do fseek() optimization */
+#define __SNPT 0x0800 /* do not do fseek() optimization */
+#define __SOFF 0x1000 /* set iff _offset is in fact correct */
+#define __SMOD 0x2000 /* true => fgetln modified _p text */
+#define __SALC 0x4000 /* allocate string space dynamically */
+#define __SIGN 0x8000 /* ignore this file in _fwalk */
+
+#define __S2OAP 0x0001 /* O_APPEND mode is set */
+
+/*
+ * The following three definitions are for ANSI C, which took them
+ * from System V, which brilliantly took internal interface macros and
+ * made them official arguments to setvbuf(), without renaming them.
+ * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
+ *
+ * Although numbered as their counterparts above, the implementation
+ * does not rely on this.
+ */
+#define _IOFBF 0 /* setvbuf should set fully buffered */
+#define _IOLBF 1 /* setvbuf should set line buffered */
+#define _IONBF 2 /* setvbuf should set unbuffered */
+
+#define BUFSIZ 1024 /* size of buffer used by setbuf */
+#define EOF (-1)
+
+/*
+ * FOPEN_MAX is a minimum maximum, and is the number of streams that
+ * stdio can provide without attempting to allocate further resources
+ * (which could fail). Do not use this for anything.
+ */
+ /* must be == _POSIX_STREAM_MAX <limits.h> */
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
+#endif
+#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
+
+/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
+#if __XSI_VISIBLE
+#define P_tmpdir "/tmp/"
+#endif
+#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
+#define TMP_MAX 308915776
+
+#ifndef SEEK_SET
+#define SEEK_SET 0 /* set file offset to offset */
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+#endif
+
+#define stdin __stdinp
+#define stdout __stdoutp
+#define stderr __stderrp
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_stdio.h>
+#endif
+/*
+ * Functions defined in ANSI C standard.
+ */
+void clearerr(FILE *);
+int fclose(FILE *);
+int feof(FILE *);
+int ferror(FILE *);
+int fflush(FILE *);
+int fgetc(FILE *);
+int fgetpos(FILE * __restrict, fpos_t * __restrict);
+char *fgets(char * __restrict, int, FILE * __restrict);
+FILE *fopen(const char * __restrict, const char * __restrict);
+int fprintf(FILE * __restrict, const char * __restrict, ...);
+int fputc(int, FILE *);
+int fputs(const char * __restrict, FILE * __restrict);
+size_t fread(void * __restrict, size_t, size_t, FILE * __restrict);
+FILE *freopen(const char * __restrict, const char * __restrict, FILE * __restrict);
+int fscanf(FILE * __restrict, const char * __restrict, ...);
+int fseek(FILE *, long, int);
+int fsetpos(FILE *, const fpos_t *);
+long ftell(FILE *);
+size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
+int getc(FILE *);
+int getchar(void);
+char *gets(char *);
+void perror(const char *);
+int printf(const char * __restrict, ...);
+int putc(int, FILE *);
+int putchar(int);
+int puts(const char *);
+int remove(const char *);
+int rename(const char *, const char *);
+void rewind(FILE *);
+int scanf(const char * __restrict, ...);
+void setbuf(FILE * __restrict, char * __restrict);
+int setvbuf(FILE * __restrict, char * __restrict, int, size_t);
+int sprintf(char * __restrict, const char * __restrict, ...);
+int sscanf(const char * __restrict, const char * __restrict, ...);
+FILE *tmpfile(void);
+char *tmpnam(char *);
+int ungetc(int, FILE *);
+int vfprintf(FILE * __restrict, const char * __restrict,
+ __va_list);
+int vprintf(const char * __restrict, __va_list);
+int vsprintf(char * __restrict, const char * __restrict,
+ __va_list);
+
+#if __ISO_C_VISIBLE >= 1999
+int snprintf(char * __restrict, size_t, const char * __restrict,
+ ...) __printflike(3, 4);
+int vfscanf(FILE * __restrict, const char * __restrict, __va_list)
+ __scanflike(2, 0);
+int vscanf(const char * __restrict, __va_list) __scanflike(1, 0);
+int vsnprintf(char * __restrict, size_t, const char * __restrict,
+ __va_list) __printflike(3, 0);
+int vsscanf(const char * __restrict, const char * __restrict, __va_list)
+ __scanflike(2, 0);
+#endif
+
+/*
+ * Functions defined in all versions of POSIX 1003.1.
+ */
+#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 199506)
+#define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, legacy */
+#endif
+
+#if __POSIX_VISIBLE
+#define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */
+
+char *ctermid(char *);
+FILE *fdopen(int, const char *);
+int fileno(FILE *);
+#endif /* __POSIX_VISIBLE */
+
+#if __POSIX_VISIBLE >= 199209
+int pclose(FILE *);
+FILE *popen(const char *, const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+int ftrylockfile(FILE *);
+void flockfile(FILE *);
+void funlockfile(FILE *);
+
+/*
+ * These are normally used through macros as defined below, but POSIX
+ * requires functions as well.
+ */
+int getc_unlocked(FILE *);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE *);
+int putchar_unlocked(int);
+#endif
+#if __BSD_VISIBLE
+void clearerr_unlocked(FILE *);
+int feof_unlocked(FILE *);
+int ferror_unlocked(FILE *);
+int fileno_unlocked(FILE *);
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+int fseeko(FILE *, __off_t, int);
+__off_t ftello(FILE *);
+#endif
+
+#if __BSD_VISIBLE || __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600
+int getw(FILE *);
+int putw(int, FILE *);
+#endif /* BSD or X/Open before issue 6 */
+
+#if __XSI_VISIBLE
+char *tempnam(const char *, const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 200809
+FILE *fmemopen(void * __restrict, size_t, const char * __restrict);
+ssize_t getdelim(char ** __restrict, size_t * __restrict, int,
+ FILE * __restrict);
+FILE *open_memstream(char **, size_t *);
+int renameat(int, const char *, int, const char *);
+int vdprintf(int, const char * __restrict, __va_list);
+
+/*
+ * Every programmer and his dog wrote functions called getline() and dprintf()
+ * before POSIX.1-2008 came along and decided to usurp the names, so we
+ * don't prototype them by default unless one of the following is true:
+ * a) the app has requested them specifically by defining _WITH_GETLINE or
+ * _WITH_DPRINTF, respectively
+ * b) the app has requested a POSIX.1-2008 environment via _POSIX_C_SOURCE
+ * c) the app defines a GNUism such as _BSD_SOURCE or _GNU_SOURCE
+ */
+#ifndef _WITH_GETLINE
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define _WITH_GETLINE
+#elif defined(_POSIX_C_SOURCE)
+#if _POSIX_C_SOURCE >= 200809
+#define _WITH_GETLINE
+#endif
+#endif
+#endif
+
+#ifdef _WITH_GETLINE
+ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
+#endif
+
+#ifndef _WITH_DPRINTF
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define _WITH_DPRINTF
+#elif defined(_POSIX_C_SOURCE)
+#if _POSIX_C_SOURCE >= 200809
+#define _WITH_DPRINTF
+#endif
+#endif
+#endif
+
+#ifdef _WITH_DPRINTF
+int (dprintf)(int, const char * __restrict, ...);
+#endif
+
+#endif /* __POSIX_VISIBLE >= 200809 */
+
+/*
+ * Routines that are purely local.
+ */
+#if __BSD_VISIBLE
+int asprintf(char **, const char *, ...) __printflike(2, 3);
+char *ctermid_r(char *);
+void fcloseall(void);
+int fdclose(FILE *, int *);
+char *fgetln(FILE *, size_t *);
+const char *fmtcheck(const char *, const char *) __format_arg(2);
+int fpurge(FILE *);
+void setbuffer(FILE *, char *, int);
+int setlinebuf(FILE *);
+int vasprintf(char **, const char *, __va_list)
+ __printflike(2, 0);
+
+/*
+ * The system error table contains messages for the first sys_nerr
+ * positive errno values. Use strerror() or strerror_r() from <string.h>
+ * instead.
+ */
+extern const int sys_nerr;
+extern const char * const sys_errlist[];
+
+/*
+ * Stdio function-access interface.
+ */
+FILE *funopen(const void *,
+ int (*)(void *, char *, int),
+ int (*)(void *, const char *, int),
+ fpos_t (*)(void *, fpos_t, int),
+ int (*)(void *));
+#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
+#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
+
+/*
+ * Portability hacks. See <sys/types.h>.
+ */
+#ifndef _FTRUNCATE_DECLARED
+#define _FTRUNCATE_DECLARED
+int ftruncate(int, __off_t);
+#endif
+#ifndef _LSEEK_DECLARED
+#define _LSEEK_DECLARED
+__off_t lseek(int, __off_t, int);
+#endif
+#ifndef _MMAP_DECLARED
+#define _MMAP_DECLARED
+void *mmap(void *, size_t, int, int, int, __off_t);
+#endif
+#ifndef _TRUNCATE_DECLARED
+#define _TRUNCATE_DECLARED
+int truncate(const char *, __off_t);
+#endif
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Functions internal to the implementation.
+ */
+int __srget(FILE *);
+int __swbuf(int, FILE *);
+
+/*
+ * The __sfoo macros are here so that we can
+ * define function versions in the C library.
+ */
+#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
+#if defined(__GNUC__) && defined(__STDC__)
+static __inline int __sputc(int _c, FILE *_p) {
+ if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+ return (*_p->_p++ = _c);
+ else
+ return (__swbuf(_c, _p));
+}
+#else
+/*
+ * This has been tuned to generate reasonable code on the vax using pcc.
+ */
+#define __sputc(c, p) \
+ (--(p)->_w < 0 ? \
+ (p)->_w >= (p)->_lbfsize ? \
+ (*(p)->_p = (c)), *(p)->_p != '\n' ? \
+ (int)*(p)->_p++ : \
+ __swbuf('\n', p) : \
+ __swbuf((int)(c), p) : \
+ (*(p)->_p = (c), (int)*(p)->_p++))
+#endif
+
+extern int __isthreaded;
+
+#ifndef __cplusplus
+
+#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
+#define __sferror(p) (((p)->_flags & __SERR) != 0)
+#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
+#define __sfileno(p) ((p)->_file)
+
+
+#define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
+#define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p))
+#define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p))
+
+#if __POSIX_VISIBLE
+#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p))
+#endif
+
+#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp))
+#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
+
+#define getchar() getc(stdin)
+#define putchar(x) putc(x, stdout)
+
+#if __BSD_VISIBLE
+/*
+ * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12
+ * B.8.2.7 for the rationale behind the *_unlocked() macros.
+ */
+#define feof_unlocked(p) __sfeof(p)
+#define ferror_unlocked(p) __sferror(p)
+#define clearerr_unlocked(p) __sclearerr(p)
+#define fileno_unlocked(p) __sfileno(p)
+#endif
+#if __POSIX_VISIBLE >= 199506
+#define getc_unlocked(fp) __sgetc(fp)
+#define putc_unlocked(x, fp) __sputc(x, fp)
+
+#define getchar_unlocked() getc_unlocked(stdin)
+#define putchar_unlocked(x) putc_unlocked(x, stdout)
+#endif
+#endif /* __cplusplus */
+
+__END_DECLS
+#endif /* !_STDIO_H_ */
diff --git a/usr/src/boot/include/stdlib.h b/usr/src/boot/include/stdlib.h
new file mode 100644
index 0000000000..d5506ff65e
--- /dev/null
+++ b/usr/src/boot/include/stdlib.h
@@ -0,0 +1,329 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stdlib.h 8.5 (Berkeley) 5/19/95
+ * $FreeBSD$
+ */
+
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef __rune_t rune_t;
+#define _RUNE_T_DECLARED
+#endif
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#ifndef __cplusplus
+#ifndef _WCHAR_T_DECLARED
+typedef ___wchar_t wchar_t;
+#define _WCHAR_T_DECLARED
+#endif
+#endif
+
+typedef struct {
+ int quot; /* quotient */
+ int rem; /* remainder */
+} div_t;
+
+typedef struct {
+ long quot;
+ long rem;
+} ldiv_t;
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+#define RAND_MAX 0x7ffffffd
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_stdlib.h>
+#endif
+extern int __mb_cur_max;
+extern int ___mb_cur_max(void);
+#define MB_CUR_MAX (___mb_cur_max())
+
+_Noreturn void abort(void);
+int abs(int) __pure2;
+int atexit(void (*)(void));
+double atof(const char *);
+int atoi(const char *);
+long atol(const char *);
+void *bsearch(const void *, const void *, size_t,
+ size_t, int (*)(const void *, const void *));
+void *calloc(size_t, size_t) __malloc_like __result_use_check
+ __alloc_size(1) __alloc_size(2);
+div_t div(int, int) __pure2;
+_Noreturn void exit(int);
+void free(void *);
+char *getenv(const char *);
+long labs(long) __pure2;
+ldiv_t ldiv(long, long) __pure2;
+void *malloc(size_t) __malloc_like __result_use_check __alloc_size(1);
+int mblen(const char *, size_t);
+size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
+int mbtowc(wchar_t * __restrict, const char * __restrict, size_t);
+void qsort(void *, size_t, size_t,
+ int (*)(const void *, const void *));
+int rand(void);
+void *realloc(void *, size_t) __result_use_check __alloc_size(2);
+void srand(unsigned);
+double strtod(const char * __restrict, char ** __restrict);
+float strtof(const char * __restrict, char ** __restrict);
+long strtol(const char * __restrict, char ** __restrict, int);
+long double
+ strtold(const char * __restrict, char ** __restrict);
+unsigned long
+ strtoul(const char * __restrict, char ** __restrict, int);
+int system(const char *);
+int wctomb(char *, wchar_t);
+size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
+
+/*
+ * Functions added in C99 which we make conditionally available in the
+ * BSD^C89 namespace if the compiler supports `long long'.
+ * The #if test is more complicated than it ought to be because
+ * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long'
+ * is not supported in the compilation environment (which therefore means
+ * that it can't really be ISO C99).
+ *
+ * (The only other extension made by C99 in thie header is _Exit().)
+ */
+#if __ISO_C_VISIBLE >= 1999
+#ifdef __LONG_LONG_SUPPORTED
+/* LONGLONG */
+typedef struct {
+ long long quot;
+ long long rem;
+} lldiv_t;
+
+/* LONGLONG */
+long long
+ atoll(const char *);
+/* LONGLONG */
+long long
+ llabs(long long) __pure2;
+/* LONGLONG */
+lldiv_t lldiv(long long, long long) __pure2;
+/* LONGLONG */
+long long
+ strtoll(const char * __restrict, char ** __restrict, int);
+/* LONGLONG */
+unsigned long long
+ strtoull(const char * __restrict, char ** __restrict, int);
+#endif /* __LONG_LONG_SUPPORTED */
+
+_Noreturn void _Exit(int);
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * If we're in a mode greater than C99, expose C11 functions.
+ */
+#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
+void * aligned_alloc(size_t, size_t) __malloc_like __alloc_align(1)
+ __alloc_size(2);
+int at_quick_exit(void (*)(void));
+_Noreturn void
+ quick_exit(int);
+#endif /* __ISO_C_VISIBLE >= 2011 */
+/*
+ * Extensions made by POSIX relative to C.
+ */
+#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
+char *realpath(const char * __restrict, char * __restrict);
+#endif
+#if __POSIX_VISIBLE >= 199506
+int rand_r(unsigned *); /* (TSF) */
+#endif
+#if __POSIX_VISIBLE >= 200112
+int posix_memalign(void **, size_t, size_t) __nonnull(1) __alloc_align(2)
+ __alloc_size(3); /* (ADV) */
+int setenv(const char *, const char *, int);
+int unsetenv(const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE
+int getsubopt(char **, char *const *, char **);
+#ifndef _MKDTEMP_DECLARED
+char *mkdtemp(char *);
+#define _MKDTEMP_DECLARED
+#endif
+#ifndef _MKSTEMP_DECLARED
+int mkstemp(char *);
+#define _MKSTEMP_DECLARED
+#endif
+#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */
+
+/*
+ * The only changes to the XSI namespace in revision 6 were the deletion
+ * of the ttyslot() and valloc() functions, which FreeBSD never declared
+ * in this header. For revision 7, ecvt(), fcvt(), and gcvt(), which
+ * FreeBSD also does not have, and mktemp(), are to be deleted.
+ */
+#if __XSI_VISIBLE
+/* XXX XSI requires pollution from <sys/wait.h> here. We'd rather not. */
+long a64l(const char *);
+double drand48(void);
+/* char *ecvt(double, int, int * __restrict, int * __restrict); */
+double erand48(unsigned short[3]);
+/* char *fcvt(double, int, int * __restrict, int * __restrict); */
+/* char *gcvt(double, int, int * __restrict, int * __restrict); */
+int grantpt(int);
+char *initstate(unsigned long /* XSI requires u_int */, char *, long);
+long jrand48(unsigned short[3]);
+char *l64a(long);
+void lcong48(unsigned short[7]);
+long lrand48(void);
+#if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600)
+char *mktemp(char *);
+#define _MKTEMP_DECLARED
+#endif
+long mrand48(void);
+long nrand48(unsigned short[3]);
+int posix_openpt(int);
+char *ptsname(int);
+int putenv(char *);
+long random(void);
+unsigned short
+ *seed48(unsigned short[3]);
+#ifndef _SETKEY_DECLARED
+int setkey(const char *);
+#define _SETKEY_DECLARED
+#endif
+char *setstate(/* const */ char *);
+void srand48(long);
+void srandom(unsigned long);
+int unlockpt(int);
+#endif /* __XSI_VISIBLE */
+
+#if __BSD_VISIBLE
+extern const char *malloc_conf;
+extern void (*malloc_message)(void *, const char *);
+
+/*
+ * The alloca() function can't be implemented in C, and on some
+ * platforms it can't be implemented at all as a callable function.
+ * The GNU C compiler provides a built-in alloca() which we can use;
+ * in all other cases, provide a prototype, mainly to pacify various
+ * incarnations of lint. On platforms where alloca() is not in libc,
+ * programs which use it will fail to link when compiled with non-GNU
+ * compilers.
+ */
+#if __GNUC__ >= 2 || defined(__INTEL_COMPILER)
+#undef alloca /* some GNU bits try to get cute and define this on their own */
+#define alloca(sz) __builtin_alloca(sz)
+#elif defined(lint)
+void *alloca(size_t);
+#endif
+
+void abort2(const char *, int, void **) __dead2;
+__uint32_t
+ arc4random(void);
+void arc4random_addrandom(unsigned char *, int);
+void arc4random_buf(void *, size_t);
+void arc4random_stir(void);
+__uint32_t
+ arc4random_uniform(__uint32_t);
+#ifdef __BLOCKS__
+int atexit_b(void (^)(void));
+void *bsearch_b(const void *, const void *, size_t,
+ size_t, int (^)(const void *, const void *));
+#endif
+char *getbsize(int *, long *);
+ /* getcap(3) functions */
+char *cgetcap(char *, const char *, int);
+int cgetclose(void);
+int cgetent(char **, char **, const char *);
+int cgetfirst(char **, char **);
+int cgetmatch(const char *, const char *);
+int cgetnext(char **, char **);
+int cgetnum(char *, const char *, long *);
+int cgetset(const char *);
+int cgetstr(char *, const char *, char **);
+int cgetustr(char *, const char *, char **);
+
+int daemon(int, int);
+char *devname(__dev_t, __mode_t);
+char *devname_r(__dev_t, __mode_t, char *, int);
+char *fdevname(int);
+char *fdevname_r(int, char *, int);
+int getloadavg(double [], int);
+const char *
+ getprogname(void);
+
+int heapsort(void *, size_t, size_t, int (*)(const void *, const void *));
+#ifdef __BLOCKS__
+int heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *));
+void qsort_b(void *, size_t, size_t,
+ int (^)(const void *, const void *));
+#endif
+int l64a_r(long, char *, int);
+int mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
+#ifdef __BLOCKS__
+int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *));
+#endif
+int mkostemp(char *, int);
+int mkostemps(char *, int, int);
+void qsort_r(void *, size_t, size_t, void *,
+ int (*)(void *, const void *, const void *));
+int radixsort(const unsigned char **, int, const unsigned char *,
+ unsigned);
+void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
+ __alloc_size(3);
+void *reallocf(void *, size_t) __alloc_size(2);
+int rpmatch(const char *);
+void setprogname(const char *);
+int sradixsort(const unsigned char **, int, const unsigned char *,
+ unsigned);
+void sranddev(void);
+void srandomdev(void);
+long long
+ strtonum(const char *, long long, long long, const char **);
+
+/* Deprecated interfaces, to be removed in FreeBSD 6.0. */
+__int64_t
+ strtoq(const char *, char **, int);
+__uint64_t
+ strtouq(const char *, char **, int);
+
+extern char *suboptarg; /* getsubopt(3) external variable */
+#endif /* __BSD_VISIBLE */
+__END_DECLS
+
+#endif /* !_STDLIB_H_ */
diff --git a/usr/src/boot/include/string.h b/usr/src/boot/include/string.h
new file mode 100644
index 0000000000..af8b0d46c8
--- /dev/null
+++ b/usr/src/boot/include/string.h
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)string.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+/*
+ * Prototype functions which were historically defined in <string.h>, but
+ * are required by POSIX to be prototyped in <strings.h>.
+ */
+#if __BSD_VISIBLE
+#include <strings.h>
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+__BEGIN_DECLS
+#if __XSI_VISIBLE >= 600
+void *memccpy(void * __restrict, const void * __restrict, int, size_t);
+#endif
+void *memchr(const void *, int, size_t) __pure;
+#if __BSD_VISIBLE
+void *memrchr(const void *, int, size_t) __pure;
+#endif
+int memcmp(const void *, const void *, size_t) __pure;
+void *memcpy(void * __restrict, const void * __restrict, size_t);
+#if __BSD_VISIBLE
+void *memmem(const void *, size_t, const void *, size_t) __pure;
+#endif
+void *memmove(void *, const void *, size_t);
+void *memset(void *, int, size_t);
+#if __POSIX_VISIBLE >= 200809
+char *stpcpy(char * __restrict, const char * __restrict);
+char *stpncpy(char * __restrict, const char * __restrict, size_t);
+#endif
+#if __BSD_VISIBLE
+char *strcasestr(const char *, const char *) __pure;
+#endif
+char *strcat(char * __restrict, const char * __restrict);
+char *strchr(const char *, int) __pure;
+#if __BSD_VISIBLE
+char *strchrnul(const char*, int) __pure;
+#endif
+int strcmp(const char *, const char *) __pure;
+int strcoll(const char *, const char *);
+char *strcpy(char * __restrict, const char * __restrict);
+size_t strcspn(const char *, const char *) __pure;
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+char *strdup(const char *) __malloc_like;
+#endif
+char *strerror(int);
+#if __POSIX_VISIBLE >= 200112
+int strerror_r(int, char *, size_t);
+#endif
+#if __BSD_VISIBLE
+size_t strlcat(char * __restrict, const char * __restrict, size_t);
+size_t strlcpy(char * __restrict, const char * __restrict, size_t);
+#endif
+size_t strlen(const char *) __pure;
+#if __BSD_VISIBLE
+void strmode(int, char *);
+#endif
+char *strncat(char * __restrict, const char * __restrict, size_t);
+int strncmp(const char *, const char *, size_t) __pure;
+char *strncpy(char * __restrict, const char * __restrict, size_t);
+#if __POSIX_VISIBLE >= 200809
+char *strndup(const char *, size_t) __malloc_like;
+size_t strnlen(const char *, size_t) __pure;
+#endif
+#if __BSD_VISIBLE
+char *strnstr(const char *, const char *, size_t) __pure;
+#endif
+char *strpbrk(const char *, const char *) __pure;
+char *strrchr(const char *, int) __pure;
+#if __BSD_VISIBLE
+char *strsep(char **, const char *);
+#endif
+#if __POSIX_VISIBLE >= 200809
+char *strsignal(int);
+#endif
+size_t strspn(const char *, const char *) __pure;
+char *strstr(const char *, const char *) __pure;
+char *strtok(char * __restrict, const char * __restrict);
+#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500
+char *strtok_r(char *, const char *, char **);
+#endif
+size_t strxfrm(char * __restrict, const char * __restrict, size_t);
+#if __BSD_VISIBLE
+
+#ifndef _SWAB_DECLARED
+#define _SWAB_DECLARED
+
+#ifndef _SSIZE_T_DECLARED
+typedef __ssize_t ssize_t;
+#define _SSIZE_T_DECLARED
+#endif /* _SIZE_T_DECLARED */
+
+void swab(const void * __restrict, void * __restrict, ssize_t);
+#endif /* _SWAB_DECLARED */
+
+#endif /* __BSD_VISIBLE */
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_string.h>
+#endif
+__END_DECLS
+
+#endif /* _STRING_H_ */
diff --git a/usr/src/boot/include/strings.h b/usr/src/boot/include/strings.h
new file mode 100644
index 0000000000..2210df04f0
--- /dev/null
+++ b/usr/src/boot/include/strings.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STRINGS_H_
+#define _STRINGS_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+__BEGIN_DECLS
+#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
+int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */
+void bcopy(const void *, void *, size_t); /* LEGACY */
+void bzero(void *, size_t); /* LEGACY */
+#endif
+#if __BSD_VISIBLE
+void explicit_bzero(void *, size_t);
+#endif
+#if __XSI_VISIBLE
+int ffs(int) __pure2;
+#endif
+#if __BSD_VISIBLE
+int ffsl(long) __pure2;
+int ffsll(long long) __pure2;
+int fls(int) __pure2;
+int flsl(long) __pure2;
+int flsll(long long) __pure2;
+#endif
+#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
+char *index(const char *, int) __pure; /* LEGACY */
+char *rindex(const char *, int) __pure; /* LEGACY */
+#endif
+int strcasecmp(const char *, const char *) __pure;
+int strncasecmp(const char *, const char *, size_t) __pure;
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_strings.h>
+#endif
+__END_DECLS
+
+#endif /* _STRINGS_H_ */
diff --git a/usr/src/boot/include/time.h b/usr/src/boot/include/time.h
new file mode 100644
index 0000000000..14d6044ae7
--- /dev/null
+++ b/usr/src/boot/include/time.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)time.h 8.3 (Berkeley) 1/21/94
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifndef _TIME_H_
+#define _TIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE
+/*
+ * Frequency of the clock ticks reported by times(). Deprecated - use
+ * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.)
+ */
+#define CLK_TCK 128
+#endif
+
+/* Frequency of the clock ticks reported by clock(). */
+#define CLOCKS_PER_SEC 128
+
+#ifndef _CLOCK_T_DECLARED
+typedef __clock_t clock_t;
+#define _CLOCK_T_DECLARED
+#endif
+
+#ifndef _TIME_T_DECLARED
+typedef __time_t time_t;
+#define _TIME_T_DECLARED
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+/*
+ * New in POSIX 1003.1b-1993.
+ */
+#ifndef _CLOCKID_T_DECLARED
+typedef __clockid_t clockid_t;
+#define _CLOCKID_T_DECLARED
+#endif
+
+#ifndef _TIMER_T_DECLARED
+typedef __timer_t timer_t;
+#define _TIMER_T_DECLARED
+#endif
+
+#include <sys/timespec.h>
+#endif /* __POSIX_VISIBLE >= 199309 */
+
+#if __POSIX_VISIBLE >= 200112
+#ifndef _PID_T_DECLARED
+typedef __pid_t pid_t;
+#define _PID_T_DECLARED
+#endif
+#endif
+
+/* These macros are also in sys/time.h. */
+#if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112
+#define CLOCK_REALTIME 0
+#ifdef __BSD_VISIBLE
+#define CLOCK_VIRTUAL 1
+#define CLOCK_PROF 2
+#endif
+#define CLOCK_MONOTONIC 4
+#define CLOCK_UPTIME 5 /* FreeBSD-specific. */
+#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */
+#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */
+#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */
+#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */
+#define CLOCK_SECOND 13 /* FreeBSD-specific. */
+#define CLOCK_THREAD_CPUTIME_ID 14
+#define CLOCK_PROCESS_CPUTIME_ID 15
+#endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */
+
+#if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112
+#if __BSD_VISIBLE
+#define TIMER_RELTIME 0x0 /* relative timer */
+#endif
+#define TIMER_ABSTIME 0x1 /* absolute timer */
+#endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */
+
+struct tm {
+ int tm_sec; /* seconds after the minute [0-60] */
+ int tm_min; /* minutes after the hour [0-59] */
+ int tm_hour; /* hours since midnight [0-23] */
+ int tm_mday; /* day of the month [1-31] */
+ int tm_mon; /* months since January [0-11] */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* days since Sunday [0-6] */
+ int tm_yday; /* days since January 1 [0-365] */
+ int tm_isdst; /* Daylight Savings Time flag */
+ long tm_gmtoff; /* offset from UTC in seconds */
+ char *tm_zone; /* timezone abbreviation */
+};
+
+#if __POSIX_VISIBLE
+extern char *tzname[];
+#endif
+
+__BEGIN_DECLS
+char *asctime(const struct tm *);
+clock_t clock(void);
+char *ctime(const time_t *);
+double difftime(time_t, time_t);
+/* XXX missing: getdate() */
+struct tm *gmtime(const time_t *);
+struct tm *localtime(const time_t *);
+time_t mktime(struct tm *);
+size_t strftime(char * __restrict, size_t, const char * __restrict,
+ const struct tm * __restrict);
+time_t time(time_t *);
+#if __POSIX_VISIBLE >= 200112
+struct sigevent;
+int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict);
+int timer_delete(timer_t);
+int timer_gettime(timer_t, struct itimerspec *);
+int timer_getoverrun(timer_t);
+int timer_settime(timer_t, int, const struct itimerspec *__restrict,
+ struct itimerspec *__restrict);
+#endif
+#if __POSIX_VISIBLE
+void tzset(void);
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+int clock_getres(clockid_t, struct timespec *);
+int clock_gettime(clockid_t, struct timespec *);
+int clock_settime(clockid_t, const struct timespec *);
+/* XXX missing: clock_nanosleep() */
+int nanosleep(const struct timespec *, struct timespec *);
+#endif /* __POSIX_VISIBLE >= 199309 */
+
+#if __POSIX_VISIBLE >= 200112
+int clock_getcpuclockid(pid_t, clockid_t *);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+char *asctime_r(const struct tm *, char *);
+char *ctime_r(const time_t *, char *);
+struct tm *gmtime_r(const time_t *, struct tm *);
+struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+
+#if __XSI_VISIBLE
+char *strptime(const char * __restrict, const char * __restrict,
+ struct tm * __restrict);
+#endif
+
+#if __BSD_VISIBLE
+char *timezone(int, int); /* XXX XSI conflict */
+void tzsetwall(void);
+time_t timelocal(struct tm * const);
+time_t timegm(struct tm * const);
+#endif /* __BSD_VISIBLE */
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_time.h>
+#endif
+__END_DECLS
+
+#endif /* !_TIME_H_ */
diff --git a/usr/src/boot/include/ufs/ufs/dinode.h b/usr/src/boot/include/ufs/ufs/dinode.h
new file mode 100644
index 0000000000..afe9d4e06c
--- /dev/null
+++ b/usr/src/boot/include/ufs/ufs/dinode.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Copyright (c) 1982, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)dinode.h 8.3 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _UFS_UFS_DINODE_H_
+#define _UFS_UFS_DINODE_H_
+
+/*
+ * The root inode is the root of the filesystem. Inode 0 can't be used for
+ * normal purposes and historically bad blocks were linked to inode 1, thus
+ * the root inode is 2. (Inode 1 is no longer used for this purpose, however
+ * numerous dump tapes make this assumption, so we are stuck with it).
+ */
+#define ROOTINO ((ino_t)2)
+
+/*
+ * The Whiteout inode# is a dummy non-zero inode number which will
+ * never be allocated to a real file. It is used as a place holder
+ * in the directory entry which has been tagged as a DT_WHT entry.
+ * See the comments about ROOTINO above.
+ */
+#define WINO ((ino_t)1)
+
+/*
+ * The size of physical and logical block numbers and time fields in UFS.
+ */
+typedef int32_t ufs1_daddr_t;
+typedef int64_t ufs2_daddr_t;
+typedef int64_t ufs_lbn_t;
+typedef int64_t ufs_time_t;
+
+/* File permissions. */
+#define IEXEC 0000100 /* Executable. */
+#define IWRITE 0000200 /* Writeable. */
+#define IREAD 0000400 /* Readable. */
+#define ISVTX 0001000 /* Sticky bit. */
+#define ISGID 0002000 /* Set-gid. */
+#define ISUID 0004000 /* Set-uid. */
+
+/* File types. */
+#define IFMT 0170000 /* Mask of file type. */
+#define IFIFO 0010000 /* Named pipe (fifo). */
+#define IFCHR 0020000 /* Character device. */
+#define IFDIR 0040000 /* Directory file. */
+#define IFBLK 0060000 /* Block device. */
+#define IFREG 0100000 /* Regular file. */
+#define IFLNK 0120000 /* Symbolic link. */
+#define IFSOCK 0140000 /* UNIX domain socket. */
+#define IFWHT 0160000 /* Whiteout. */
+
+/*
+ * A dinode contains all the meta-data associated with a UFS2 file.
+ * This structure defines the on-disk format of a dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+
+#define NXADDR 2 /* External addresses in inode. */
+#define NDADDR 12 /* Direct addresses in inode. */
+#define NIADDR 3 /* Indirect addresses in inode. */
+
+struct ufs2_dinode {
+ u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
+ int16_t di_nlink; /* 2: File link count. */
+ u_int32_t di_uid; /* 4: File owner. */
+ u_int32_t di_gid; /* 8: File group. */
+ u_int32_t di_blksize; /* 12: Inode blocksize. */
+ u_int64_t di_size; /* 16: File byte count. */
+ u_int64_t di_blocks; /* 24: Blocks actually held. */
+ ufs_time_t di_atime; /* 32: Last access time. */
+ ufs_time_t di_mtime; /* 40: Last modified time. */
+ ufs_time_t di_ctime; /* 48: Last inode change time. */
+ ufs_time_t di_birthtime; /* 56: Inode creation time. */
+ int32_t di_mtimensec; /* 64: Last modified time. */
+ int32_t di_atimensec; /* 68: Last access time. */
+ int32_t di_ctimensec; /* 72: Last inode change time. */
+ int32_t di_birthnsec; /* 76: Inode creation time. */
+ u_int32_t di_gen; /* 80: Generation number. */
+ u_int32_t di_kernflags; /* 84: Kernel flags. */
+ u_int32_t di_flags; /* 88: Status flags (chflags). */
+ u_int32_t di_extsize; /* 92: External attributes size. */
+ ufs2_daddr_t di_extb[NXADDR];/* 96: External attributes block. */
+ ufs2_daddr_t di_db[NDADDR]; /* 112: Direct disk blocks. */
+ ufs2_daddr_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */
+ u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */
+ uint32_t di_freelink; /* 240: SUJ: Next unlinked inode. */
+ uint32_t di_spare[3]; /* 244: Reserved; currently unused */
+};
+
+/*
+ * The di_db fields may be overlaid with other information for
+ * file types that do not have associated disk storage. Block
+ * and character devices overlay the first data block with their
+ * dev_t value. Short symbolic links place their path in the
+ * di_db area.
+ */
+#define di_rdev di_db[0]
+
+/*
+ * A UFS1 dinode contains all the meta-data associated with a UFS1 file.
+ * This structure defines the on-disk format of a UFS1 dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+struct ufs1_dinode {
+ u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
+ int16_t di_nlink; /* 2: File link count. */
+ u_int16_t di_suid; /* 4: File owner. */
+ u_int16_t di_sgid; /* 6: File group. */
+ u_int64_t di_size; /* 8: File byte count. */
+ int32_t di_atime; /* 16: Last access time. */
+ int32_t di_atimensec; /* 20: Last access time. */
+ int32_t di_mtime; /* 24: Last modified time. */
+ int32_t di_mtimensec; /* 28: Last modified time. */
+ int32_t di_ctime; /* 32: Last inode change time. */
+ int32_t di_ctimensec; /* 36: Last inode change time. */
+ ufs1_daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */
+ ufs1_daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */
+ u_int32_t di_flags; /* 100: Status flags (chflags). */
+ u_int32_t di_blocks; /* 104: Blocks actually held. */
+ u_int32_t di_gen; /* 108: Generation number. */
+ u_int32_t di_shadow; /* 112: shadow inode */
+ u_int32_t di_uid; /* 116: long EFT version of uid */
+ u_int32_t di_gid; /* 120: long EFT version of gid */
+ u_int32_t di_oeftflag; /* 124: extended attr directory ino, 0 = none */
+};
+
+#endif /* _UFS_UFS_DINODE_H_ */
diff --git a/usr/src/boot/include/ufs/ufs/dir.h b/usr/src/boot/include/ufs/ufs/dir.h
new file mode 100644
index 0000000000..3d399617b6
--- /dev/null
+++ b/usr/src/boot/include/ufs/ufs/dir.h
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)dir.h 8.2 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _UFS_UFS_DIR_H_
+#define _UFS_UFS_DIR_H_
+
+/*
+ * Theoretically, directories can be more than 2Gb in length, however, in
+ * practice this seems unlikely. So, we define the type doff_t as a 32-bit
+ * quantity to keep down the cost of doing lookup on a 32-bit machine.
+ */
+#define doff_t int32_t
+#define MAXDIRSIZE (0x7fffffff)
+
+/*
+ * A directory consists of some number of blocks of DIRBLKSIZ
+ * bytes, where DIRBLKSIZ is chosen such that it can be transferred
+ * to disk in a single atomic operation (e.g. 512 bytes on most machines).
+ *
+ * Each DIRBLKSIZ byte block contains some number of directory entry
+ * structures, which are of variable length. Each directory entry has
+ * a struct direct at the front of it, containing its inode number,
+ * the length of the entry, and the length of the name contained in
+ * the entry. These are followed by the name padded to a 4 byte boundary
+ * with null bytes. All names are guaranteed null terminated.
+ * The maximum length of a name in a directory is MAXNAMLEN.
+ *
+ * The macro DIRSIZ(fmt, dp) gives the amount of space required to represent
+ * a directory entry. Free space in a directory is represented by
+ * entries which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes
+ * in a directory block are claimed by the directory entries. This
+ * usually results in the last entry in a directory having a large
+ * dp->d_reclen. When entries are deleted from a directory, the
+ * space is returned to the previous entry in the same directory
+ * block by increasing its dp->d_reclen. If the first entry of
+ * a directory block is free, then its dp->d_ino is set to 0.
+ * Entries other than the first in a directory do not normally have
+ * dp->d_ino set to 0.
+ */
+#define DIRBLKSIZ DEV_BSIZE
+#define MAXNAMLEN 255
+
+struct direct {
+ u_int32_t d_ino; /* inode number of entry */
+ u_int16_t d_reclen; /* length of this record */
+ u_int16_t d_namlen; /* length of string in d_name */
+ char d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
+};
+
+/*
+ * File types
+ */
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+
+/*
+ * Convert between stat structure types and directory types.
+ */
+#define IFTODT(mode) (((mode) & 0170000) >> 12)
+#define DTTOIF(dirtype) ((dirtype) << 12)
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This requires the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ *
+ *
+ */
+#define DIRECTSIZ(namlen) \
+ ((__offsetof(struct direct, d_name) + \
+ ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3)
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define DIRSIZ(oldfmt, dp) \
+ ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
+#else
+#define DIRSIZ(oldfmt, dp) \
+ DIRECTSIZ((dp)->d_namlen)
+#endif
+#define OLDDIRFMT 1
+#define NEWDIRFMT 0
+
+/*
+ * Template for manipulating directories. Should use struct direct's,
+ * but the name field is MAXNAMLEN - 1, and this just won't do.
+ */
+struct dirtemplate {
+ u_int32_t dot_ino;
+ int16_t dot_reclen;
+ u_int8_t dot_type;
+ u_int8_t dot_namlen;
+ char dot_name[4]; /* must be multiple of 4 */
+ u_int32_t dotdot_ino;
+ int16_t dotdot_reclen;
+ u_int8_t dotdot_type;
+ u_int8_t dotdot_namlen;
+ char dotdot_name[4]; /* ditto */
+};
+
+/*
+ * This is the old format of directories, sanz type element.
+ */
+struct odirtemplate {
+ u_int32_t dot_ino;
+ int16_t dot_reclen;
+ u_int16_t dot_namlen;
+ char dot_name[4]; /* must be multiple of 4 */
+ u_int32_t dotdot_ino;
+ int16_t dotdot_reclen;
+ u_int16_t dotdot_namlen;
+ char dotdot_name[4]; /* ditto */
+};
+#endif /* !_DIR_H_ */
diff --git a/usr/src/boot/include/unistd.h b/usr/src/boot/include/unistd.h
new file mode 100644
index 0000000000..4c26a04267
--- /dev/null
+++ b/usr/src/boot/include/unistd.h
@@ -0,0 +1,592 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)unistd.h 8.12 (Berkeley) 4/27/95
+ * $FreeBSD$
+ */
+
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h> /* XXX adds too much pollution. */
+#include <sys/unistd.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#ifndef _GID_T_DECLARED
+typedef __gid_t gid_t;
+#define _GID_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
+#ifndef _PID_T_DECLARED
+typedef __pid_t pid_t;
+#define _PID_T_DECLARED
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#ifndef _SSIZE_T_DECLARED
+typedef __ssize_t ssize_t;
+#define _SSIZE_T_DECLARED
+#endif
+
+#ifndef _UID_T_DECLARED
+typedef __uid_t uid_t;
+#define _UID_T_DECLARED
+#endif
+
+#ifndef _USECONDS_T_DECLARED
+typedef __useconds_t useconds_t;
+#define _USECONDS_T_DECLARED
+#endif
+
+#define STDIN_FILENO 0 /* standard input file descriptor */
+#define STDOUT_FILENO 1 /* standard output file descriptor */
+#define STDERR_FILENO 2 /* standard error file descriptor */
+
+#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
+#define F_ULOCK 0 /* unlock locked section */
+#define F_LOCK 1 /* lock a section for exclusive use */
+#define F_TLOCK 2 /* test and lock a section for exclusive use */
+#define F_TEST 3 /* test a section for locks by other procs */
+#endif
+
+/*
+ * POSIX options and option groups we unconditionally do or don't
+ * implement. This list includes those options which are exclusively
+ * implemented (or not) in user mode. Please keep this list in
+ * alphabetical order.
+ *
+ * Anything which is defined as zero below **must** have an
+ * implementation for the corresponding sysconf() which is able to
+ * determine conclusively whether or not the feature is supported.
+ * Anything which is defined as other than -1 below **must** have
+ * complete headers, types, and function declarations as specified by
+ * the POSIX standard; however, if the relevant sysconf() function
+ * returns -1, the functions may be stubbed out.
+ */
+#define _POSIX_BARRIERS 200112L
+#define _POSIX_CPUTIME 200112L
+#define _POSIX_READER_WRITER_LOCKS 200112L
+#define _POSIX_REGEXP 1
+#define _POSIX_SHELL 1
+#define _POSIX_SPAWN 200112L
+#define _POSIX_SPIN_LOCKS 200112L
+#define _POSIX_THREAD_ATTR_STACKADDR 200112L
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
+#define _POSIX_THREAD_CPUTIME 200112L
+#define _POSIX_THREAD_PRIO_INHERIT 200112L
+#define _POSIX_THREAD_PRIO_PROTECT 200112L
+#define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L
+#define _POSIX_THREAD_PROCESS_SHARED -1
+#define _POSIX_THREAD_SAFE_FUNCTIONS -1
+#define _POSIX_THREAD_SPORADIC_SERVER -1
+#define _POSIX_THREADS 200112L
+#define _POSIX_TRACE -1
+#define _POSIX_TRACE_EVENT_FILTER -1
+#define _POSIX_TRACE_INHERIT -1
+#define _POSIX_TRACE_LOG -1
+#define _POSIX2_C_BIND 200112L /* mandatory */
+#define _POSIX2_C_DEV -1 /* need c99 utility */
+#define _POSIX2_CHAR_TERM 1
+#define _POSIX2_FORT_DEV -1 /* need fort77 utility */
+#define _POSIX2_FORT_RUN 200112L
+#define _POSIX2_LOCALEDEF -1
+#define _POSIX2_PBS -1
+#define _POSIX2_PBS_ACCOUNTING -1
+#define _POSIX2_PBS_CHECKPOINT -1
+#define _POSIX2_PBS_LOCATE -1
+#define _POSIX2_PBS_MESSAGE -1
+#define _POSIX2_PBS_TRACK -1
+#define _POSIX2_SW_DEV -1 /* XXX ??? */
+#define _POSIX2_UPE 200112L
+#define _V6_ILP32_OFF32 -1
+#define _V6_ILP32_OFFBIG 0
+#define _V6_LP64_OFF64 0
+#define _V6_LPBIG_OFFBIG -1
+
+#if __XSI_VISIBLE
+#define _XOPEN_CRYPT -1 /* XXX ??? */
+#define _XOPEN_ENH_I18N -1 /* mandatory in XSI */
+#define _XOPEN_LEGACY -1
+#define _XOPEN_REALTIME -1
+#define _XOPEN_REALTIME_THREADS -1
+#define _XOPEN_UNIX -1
+#endif
+
+/* Define the POSIX.2 version we target for compliance. */
+#define _POSIX2_VERSION 199212L
+
+/*
+ * POSIX-style system configuration variable accessors (for the
+ * sysconf function). The kernel does not directly implement the
+ * sysconf() interface; rather, a C library stub translates references
+ * to sysconf() into calls to sysctl() using a giant switch statement.
+ * Those that are marked `user' are implemented entirely in the C
+ * library and never query the kernel. pathconf() is implemented
+ * directly by the kernel so those are not defined here.
+ */
+#define _SC_ARG_MAX 1
+#define _SC_CHILD_MAX 2
+#define _SC_CLK_TCK 3
+#define _SC_NGROUPS_MAX 4
+#define _SC_OPEN_MAX 5
+#define _SC_JOB_CONTROL 6
+#define _SC_SAVED_IDS 7
+#define _SC_VERSION 8
+#define _SC_BC_BASE_MAX 9 /* user */
+#define _SC_BC_DIM_MAX 10 /* user */
+#define _SC_BC_SCALE_MAX 11 /* user */
+#define _SC_BC_STRING_MAX 12 /* user */
+#define _SC_COLL_WEIGHTS_MAX 13 /* user */
+#define _SC_EXPR_NEST_MAX 14 /* user */
+#define _SC_LINE_MAX 15 /* user */
+#define _SC_RE_DUP_MAX 16 /* user */
+#define _SC_2_VERSION 17 /* user */
+#define _SC_2_C_BIND 18 /* user */
+#define _SC_2_C_DEV 19 /* user */
+#define _SC_2_CHAR_TERM 20 /* user */
+#define _SC_2_FORT_DEV 21 /* user */
+#define _SC_2_FORT_RUN 22 /* user */
+#define _SC_2_LOCALEDEF 23 /* user */
+#define _SC_2_SW_DEV 24 /* user */
+#define _SC_2_UPE 25 /* user */
+#define _SC_STREAM_MAX 26 /* user */
+#define _SC_TZNAME_MAX 27 /* user */
+
+#if __POSIX_VISIBLE >= 199309
+#define _SC_ASYNCHRONOUS_IO 28
+#define _SC_MAPPED_FILES 29
+#define _SC_MEMLOCK 30
+#define _SC_MEMLOCK_RANGE 31
+#define _SC_MEMORY_PROTECTION 32
+#define _SC_MESSAGE_PASSING 33
+#define _SC_PRIORITIZED_IO 34
+#define _SC_PRIORITY_SCHEDULING 35
+#define _SC_REALTIME_SIGNALS 36
+#define _SC_SEMAPHORES 37
+#define _SC_FSYNC 38
+#define _SC_SHARED_MEMORY_OBJECTS 39
+#define _SC_SYNCHRONIZED_IO 40
+#define _SC_TIMERS 41
+#define _SC_AIO_LISTIO_MAX 42
+#define _SC_AIO_MAX 43
+#define _SC_AIO_PRIO_DELTA_MAX 44
+#define _SC_DELAYTIMER_MAX 45
+#define _SC_MQ_OPEN_MAX 46
+#define _SC_PAGESIZE 47
+#define _SC_RTSIG_MAX 48
+#define _SC_SEM_NSEMS_MAX 49
+#define _SC_SEM_VALUE_MAX 50
+#define _SC_SIGQUEUE_MAX 51
+#define _SC_TIMER_MAX 52
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+#define _SC_2_PBS 59 /* user */
+#define _SC_2_PBS_ACCOUNTING 60 /* user */
+#define _SC_2_PBS_CHECKPOINT 61 /* user */
+#define _SC_2_PBS_LOCATE 62 /* user */
+#define _SC_2_PBS_MESSAGE 63 /* user */
+#define _SC_2_PBS_TRACK 64 /* user */
+#define _SC_ADVISORY_INFO 65
+#define _SC_BARRIERS 66 /* user */
+#define _SC_CLOCK_SELECTION 67
+#define _SC_CPUTIME 68
+#define _SC_FILE_LOCKING 69
+#define _SC_GETGR_R_SIZE_MAX 70 /* user */
+#define _SC_GETPW_R_SIZE_MAX 71 /* user */
+#define _SC_HOST_NAME_MAX 72
+#define _SC_LOGIN_NAME_MAX 73
+#define _SC_MONOTONIC_CLOCK 74
+#define _SC_MQ_PRIO_MAX 75
+#define _SC_READER_WRITER_LOCKS 76 /* user */
+#define _SC_REGEXP 77 /* user */
+#define _SC_SHELL 78 /* user */
+#define _SC_SPAWN 79 /* user */
+#define _SC_SPIN_LOCKS 80 /* user */
+#define _SC_SPORADIC_SERVER 81
+#define _SC_THREAD_ATTR_STACKADDR 82 /* user */
+#define _SC_THREAD_ATTR_STACKSIZE 83 /* user */
+#define _SC_THREAD_CPUTIME 84 /* user */
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS 85 /* user */
+#define _SC_THREAD_KEYS_MAX 86 /* user */
+#define _SC_THREAD_PRIO_INHERIT 87 /* user */
+#define _SC_THREAD_PRIO_PROTECT 88 /* user */
+#define _SC_THREAD_PRIORITY_SCHEDULING 89 /* user */
+#define _SC_THREAD_PROCESS_SHARED 90 /* user */
+#define _SC_THREAD_SAFE_FUNCTIONS 91 /* user */
+#define _SC_THREAD_SPORADIC_SERVER 92 /* user */
+#define _SC_THREAD_STACK_MIN 93 /* user */
+#define _SC_THREAD_THREADS_MAX 94 /* user */
+#define _SC_TIMEOUTS 95 /* user */
+#define _SC_THREADS 96 /* user */
+#define _SC_TRACE 97 /* user */
+#define _SC_TRACE_EVENT_FILTER 98 /* user */
+#define _SC_TRACE_INHERIT 99 /* user */
+#define _SC_TRACE_LOG 100 /* user */
+#define _SC_TTY_NAME_MAX 101 /* user */
+#define _SC_TYPED_MEMORY_OBJECTS 102
+#define _SC_V6_ILP32_OFF32 103 /* user */
+#define _SC_V6_ILP32_OFFBIG 104 /* user */
+#define _SC_V6_LP64_OFF64 105 /* user */
+#define _SC_V6_LPBIG_OFFBIG 106 /* user */
+#define _SC_IPV6 118
+#define _SC_RAW_SOCKETS 119
+#define _SC_SYMLOOP_MAX 120
+#endif
+
+#if __XSI_VISIBLE
+#define _SC_ATEXIT_MAX 107 /* user */
+#define _SC_IOV_MAX 56
+#define _SC_PAGE_SIZE _SC_PAGESIZE
+#define _SC_XOPEN_CRYPT 108 /* user */
+#define _SC_XOPEN_ENH_I18N 109 /* user */
+#define _SC_XOPEN_LEGACY 110 /* user */
+#define _SC_XOPEN_REALTIME 111
+#define _SC_XOPEN_REALTIME_THREADS 112
+#define _SC_XOPEN_SHM 113
+#define _SC_XOPEN_STREAMS 114
+#define _SC_XOPEN_UNIX 115
+#define _SC_XOPEN_VERSION 116
+#define _SC_XOPEN_XCU_VERSION 117 /* user */
+#endif
+
+#if __BSD_VISIBLE
+#define _SC_NPROCESSORS_CONF 57
+#define _SC_NPROCESSORS_ONLN 58
+#define _SC_CPUSET_SIZE 122
+#endif
+
+/* Extensions found in Solaris and Linux. */
+#define _SC_PHYS_PAGES 121
+
+/* Keys for the confstr(3) function. */
+#if __POSIX_VISIBLE >= 199209
+#define _CS_PATH 1 /* default value of PATH */
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS 4
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9
+#define _CS_POSIX_V6_LP64_OFF64_LIBS 10
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14
+#endif
+
+__BEGIN_DECLS
+/* 1003.1-1990 */
+void _exit(int) __dead2;
+int access(const char *, int);
+unsigned int alarm(unsigned int);
+int chdir(const char *);
+int chown(const char *, uid_t, gid_t);
+int close(int);
+void closefrom(int);
+int dup(int);
+int dup2(int, int);
+int execl(const char *, const char *, ...) __null_sentinel;
+int execle(const char *, const char *, ...);
+int execlp(const char *, const char *, ...) __null_sentinel;
+int execv(const char *, char * const *);
+int execve(const char *, char * const *, char * const *);
+int execvp(const char *, char * const *);
+pid_t fork(void);
+long fpathconf(int, int);
+char *getcwd(char *, size_t);
+gid_t getegid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+int getgroups(int, gid_t []);
+char *getlogin(void);
+pid_t getpgrp(void);
+pid_t getpid(void);
+pid_t getppid(void);
+uid_t getuid(void);
+int isatty(int);
+int link(const char *, const char *);
+#ifndef _LSEEK_DECLARED
+#define _LSEEK_DECLARED
+off_t lseek(int, off_t, int);
+#endif
+long pathconf(const char *, int);
+int pause(void);
+int pipe(int *);
+ssize_t read(int, void *, size_t);
+int rmdir(const char *);
+int setgid(gid_t);
+int setpgid(pid_t, pid_t);
+pid_t setsid(void);
+int setuid(uid_t);
+unsigned int sleep(unsigned int);
+long sysconf(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+char *ttyname(int);
+int ttyname_r(int, char *, size_t);
+int unlink(const char *);
+ssize_t write(int, const void *, size_t);
+
+/* 1003.2-1992 */
+#if __POSIX_VISIBLE >= 199209 || __XSI_VISIBLE
+size_t confstr(int, char *, size_t);
+#ifndef _GETOPT_DECLARED
+#define _GETOPT_DECLARED
+int getopt(int, char * const [], const char *);
+
+extern char *optarg; /* getopt(3) external variables */
+extern int optind, opterr, optopt;
+#endif /* _GETOPT_DECLARED */
+#endif
+
+/* ISO/IEC 9945-1: 1996 */
+#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
+int fsync(int);
+
+/*
+ * ftruncate() was in the POSIX Realtime Extension (it's used for shared
+ * memory), but truncate() was not.
+ */
+#ifndef _FTRUNCATE_DECLARED
+#define _FTRUNCATE_DECLARED
+int ftruncate(int, off_t);
+#endif
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+int getlogin_r(char *, int);
+#endif
+
+/* 1003.1-2001 */
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+int fchown(int, uid_t, gid_t);
+ssize_t readlink(const char * __restrict, char * __restrict, size_t);
+#endif
+#if __POSIX_VISIBLE >= 200112
+int gethostname(char *, size_t);
+int setegid(gid_t);
+int seteuid(uid_t);
+#endif
+
+/* 1003.1-2008 */
+#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE
+int getsid(pid_t _pid);
+int fchdir(int);
+int getpgid(pid_t _pid);
+int lchown(const char *, uid_t, gid_t);
+ssize_t pread(int, void *, size_t, off_t);
+ssize_t pwrite(int, const void *, size_t, off_t);
+
+/* See comment at ftruncate() above. */
+#ifndef _TRUNCATE_DECLARED
+#define _TRUNCATE_DECLARED
+int truncate(const char *, off_t);
+#endif
+#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */
+
+#if __POSIX_VISIBLE >= 200809
+int faccessat(int, const char *, int, int);
+int fchownat(int, const char *, uid_t, gid_t, int);
+int fexecve(int, char *const [], char *const []);
+int linkat(int, const char *, int, const char *, int);
+ssize_t readlinkat(int, const char * __restrict, char * __restrict, size_t);
+int symlinkat(const char *, int, const char *);
+int unlinkat(int, const char *, int);
+#endif /* __POSIX_VISIBLE >= 200809 */
+
+/*
+ * symlink() was originally in POSIX.1a, which was withdrawn after
+ * being overtaken by events (1003.1-2001). It was in XPG4.2, and of
+ * course has been in BSD since 4.2.
+ */
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 402
+int symlink(const char * __restrict, const char * __restrict);
+#endif
+
+/* X/Open System Interfaces */
+#if __XSI_VISIBLE
+char *crypt(const char *, const char *);
+/* char *ctermid(char *); */ /* XXX ??? */
+int encrypt(char *, int);
+long gethostid(void);
+int lockf(int, int, off_t);
+int nice(int);
+int setregid(gid_t, gid_t);
+int setreuid(uid_t, uid_t);
+
+#ifndef _SWAB_DECLARED
+#define _SWAB_DECLARED
+void swab(const void * __restrict, void * __restrict, ssize_t);
+#endif /* _SWAB_DECLARED */
+
+void sync(void);
+
+#endif /* __XSI_VISIBLE */
+
+#if (__XSI_VISIBLE && __XSI_VISIBLE <= 500) || __BSD_VISIBLE
+int brk(const void *);
+int chroot(const char *);
+int getdtablesize(void);
+int getpagesize(void) __pure2;
+char *getpass(const char *);
+void *sbrk(intptr_t);
+#endif
+
+#if (__XSI_VISIBLE && __XSI_VISIBLE <= 600) || __BSD_VISIBLE
+char *getwd(char *); /* obsoleted by getcwd() */
+useconds_t
+ ualarm(useconds_t, useconds_t);
+int usleep(useconds_t);
+pid_t vfork(void) __returns_twice;
+#endif
+
+#if __BSD_VISIBLE
+struct timeval; /* select(2) */
+int acct(const char *);
+int async_daemon(void);
+int check_utility_compat(const char *);
+const char *
+ crypt_get_format(void);
+int crypt_set_format(const char *);
+int des_cipher(const char *, char *, long, int);
+int des_setkey(const char *key);
+int dup3(int, int, int);
+int eaccess(const char *, int);
+void endusershell(void);
+int exect(const char *, char * const *, char * const *);
+int execvP(const char *, const char *, char * const *);
+int feature_present(const char *);
+char *fflagstostr(u_long);
+int getdomainname(char *, int);
+int getgrouplist(const char *, gid_t, gid_t *, int *);
+int getloginclass(char *, size_t);
+mode_t getmode(const void *, mode_t);
+int getosreldate(void);
+int getpeereid(int, uid_t *, gid_t *);
+int getresgid(gid_t *, gid_t *, gid_t *);
+int getresuid(uid_t *, uid_t *, uid_t *);
+char *getusershell(void);
+int initgroups(const char *, gid_t);
+int iruserok(unsigned long, int, const char *, const char *);
+int iruserok_sa(const void *, int, int, const char *, const char *);
+int issetugid(void);
+void __FreeBSD_libc_enter_restricted_mode(void);
+long lpathconf(const char *, int);
+#ifndef _MKDTEMP_DECLARED
+char *mkdtemp(char *);
+#define _MKDTEMP_DECLARED
+#endif
+#ifndef _MKNOD_DECLARED
+int mknod(const char *, mode_t, dev_t);
+#define _MKNOD_DECLARED
+#endif
+#ifndef _MKSTEMP_DECLARED
+int mkstemp(char *);
+#define _MKSTEMP_DECLARED
+#endif
+int mkstemps(char *, int);
+#ifndef _MKTEMP_DECLARED
+char *mktemp(char *);
+#define _MKTEMP_DECLARED
+#endif
+int nfssvc(int, void *);
+int nlm_syscall(int, int, int, char **);
+int pipe2(int *, int);
+int profil(char *, size_t, vm_offset_t, int);
+int rcmd(char **, int, const char *, const char *, const char *, int *);
+int rcmd_af(char **, int, const char *,
+ const char *, const char *, int *, int);
+int rcmdsh(char **, int, const char *,
+ const char *, const char *, const char *);
+char *re_comp(const char *);
+int re_exec(const char *);
+int reboot(int);
+int revoke(const char *);
+pid_t rfork(int);
+pid_t rfork_thread(int, void *, int (*)(void *), void *);
+int rresvport(int *);
+int rresvport_af(int *, int);
+int ruserok(const char *, int, const char *, const char *);
+#if __BSD_VISIBLE
+#ifndef _SELECT_DECLARED
+#define _SELECT_DECLARED
+int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#endif
+#endif
+int setdomainname(const char *, int);
+int setgroups(int, const gid_t *);
+void sethostid(long);
+int sethostname(const char *, int);
+#ifndef _SETKEY_DECLARED
+int setkey(const char *);
+#define _SETKEY_DECLARED
+#endif
+int setlogin(const char *);
+int setloginclass(const char *);
+void *setmode(const char *);
+int setpgrp(pid_t, pid_t); /* obsoleted by setpgid() */
+void setproctitle(const char *_fmt, ...) __printf0like(1, 2);
+int setresgid(gid_t, gid_t, gid_t);
+int setresuid(uid_t, uid_t, uid_t);
+int setrgid(gid_t);
+int setruid(uid_t);
+void setusershell(void);
+int strtofflags(char **, u_long *, u_long *);
+int swapon(const char *);
+int swapoff(const char *);
+int syscall(int, ...);
+off_t __syscall(quad_t, ...);
+int undelete(const char *);
+int unwhiteout(const char *);
+void *valloc(size_t); /* obsoleted by malloc() */
+
+#ifndef _OPTRESET_DECLARED
+#define _OPTRESET_DECLARED
+extern int optreset; /* getopt(3) external variable */
+#endif
+#endif /* __BSD_VISIBLE */
+__END_DECLS
+
+#endif /* !_UNISTD_H_ */
diff --git a/usr/src/boot/include/uuid.h b/usr/src/boot/include/uuid.h
new file mode 100644
index 0000000000..79ab76b3b2
--- /dev/null
+++ b/usr/src/boot/include/uuid.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _UUID_H_
+#define _UUID_H_
+
+#include <sys/types.h>
+#include <sys/uuid.h>
+
+/*
+ * This implementation mostly conforms to the DCE 1.1 specification.
+ * See Also:
+ * uuidgen(1), uuidgen(2), uuid(3)
+ */
+
+/* Status codes returned by the functions. */
+#define uuid_s_ok 0
+#define uuid_s_bad_version 1
+#define uuid_s_invalid_string_uuid 2
+#define uuid_s_no_memory 3
+
+__BEGIN_DECLS
+int32_t uuid_compare(const uuid_t *, const uuid_t *, uint32_t *);
+void uuid_create(uuid_t *, uint32_t *);
+void uuid_create_nil(uuid_t *, uint32_t *);
+int32_t uuid_equal(const uuid_t *, const uuid_t *, uint32_t *);
+void uuid_from_string(const char *, uuid_t *, uint32_t *);
+uint16_t uuid_hash(const uuid_t *, uint32_t *);
+int32_t uuid_is_nil(const uuid_t *, uint32_t *);
+void uuid_to_string(const uuid_t *, char **, uint32_t *);
+void uuid_enc_le(void *, const uuid_t *);
+void uuid_dec_le(const void *, uuid_t *);
+void uuid_enc_be(void *, const uuid_t *);
+void uuid_dec_be(const void *, uuid_t *);
+__END_DECLS
+
+#endif /* _UUID_H_ */
diff --git a/usr/src/boot/include/xlocale/_ctype.h b/usr/src/boot/include/xlocale/_ctype.h
new file mode 100644
index 0000000000..25a9c723c9
--- /dev/null
+++ b/usr/src/boot/include/xlocale/_ctype.h
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by David Chisnall under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#if (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
+ (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H))
+
+#ifdef _XLOCALE_WCTYPES
+#define _XLOCALE_WCTYPE_H
+#else
+#define _XLOCALE_CTYPE_H
+#endif
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct _xlocale *locale_t;
+#endif
+
+#ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED
+#define _XLOCALE_RUN_FUNCTIONS_DEFINED 1
+unsigned long ___runetype_l(__ct_rune_t, locale_t) __pure;
+__ct_rune_t ___tolower_l(__ct_rune_t, locale_t) __pure;
+__ct_rune_t ___toupper_l(__ct_rune_t, locale_t) __pure;
+_RuneLocale *__runes_for_locale(locale_t, int*);
+#endif
+
+#ifndef _XLOCALE_INLINE
+#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
+/* GNU89 inline has nonstandard semantics. */
+#define _XLOCALE_INLINE extern __inline
+#else
+/* Hack to work around people who define inline away */
+#ifdef inline
+#define _XLOCALE_INLINE static __inline
+#else
+/* Define with C++ / C99 compatible semantics */
+#define _XLOCALE_INLINE inline
+#endif
+#endif
+#endif /* _XLOCALE_INLINE */
+
+#ifdef _XLOCALE_WCTYPES
+_XLOCALE_INLINE int
+__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
+_XLOCALE_INLINE int
+__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
+
+_XLOCALE_INLINE int
+__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
+{
+ int __limit;
+ _RuneLocale *runes = __runes_for_locale(__loc, &__limit);
+ return ((__c < 0 || __c >= _CACHED_RUNES) ? ___runetype_l(__c, __loc) :
+ runes->__runetype[__c]) & __f;
+}
+
+_XLOCALE_INLINE int
+__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
+{
+ return (!!__maskrune_l(__c, __f, __loc));
+}
+
+#define XLOCALE_ISCTYPE(fname, cat) \
+ _XLOCALE_INLINE int isw##fname##_l(int, locale_t);\
+ _XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\
+ { return __istype_l(__c, cat, __l); }
+#else
+_XLOCALE_INLINE int
+__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
+_XLOCALE_INLINE int
+__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
+
+_XLOCALE_INLINE int
+__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
+{
+ int __limit;
+ _RuneLocale *runes = __runes_for_locale(__loc, &__limit);
+ return (__c < 0 || __c >= __limit) ? 0 :
+ runes->__runetype[__c] & __f;
+}
+
+_XLOCALE_INLINE int
+__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
+{
+ return (!!__sbmaskrune_l(__c, __f, __loc));
+}
+
+#define XLOCALE_ISCTYPE(__fname, __cat) \
+ _XLOCALE_INLINE int is##__fname##_l(int, locale_t); \
+ _XLOCALE_INLINE int is##__fname##_l(int __c, locale_t __l)\
+ { return __sbistype_l(__c, __cat, __l); }
+#endif
+
+XLOCALE_ISCTYPE(alnum, _CTYPE_A|_CTYPE_D|_CTYPE_N)
+XLOCALE_ISCTYPE(alpha, _CTYPE_A)
+XLOCALE_ISCTYPE(blank, _CTYPE_B)
+XLOCALE_ISCTYPE(cntrl, _CTYPE_C)
+XLOCALE_ISCTYPE(digit, _CTYPE_D)
+XLOCALE_ISCTYPE(graph, _CTYPE_G)
+XLOCALE_ISCTYPE(hexnumber, _CTYPE_X)
+XLOCALE_ISCTYPE(ideogram, _CTYPE_I)
+XLOCALE_ISCTYPE(lower, _CTYPE_L)
+XLOCALE_ISCTYPE(number, _CTYPE_D|_CTYPE_N)
+XLOCALE_ISCTYPE(phonogram, _CTYPE_Q)
+XLOCALE_ISCTYPE(print, _CTYPE_R)
+XLOCALE_ISCTYPE(punct, _CTYPE_P)
+XLOCALE_ISCTYPE(rune, 0xFFFFFF00L)
+XLOCALE_ISCTYPE(space, _CTYPE_S)
+XLOCALE_ISCTYPE(special, _CTYPE_T)
+XLOCALE_ISCTYPE(upper, _CTYPE_U)
+XLOCALE_ISCTYPE(xdigit, _CTYPE_X)
+#undef XLOCALE_ISCTYPE
+
+#ifdef _XLOCALE_WCTYPES
+_XLOCALE_INLINE int towlower_l(int, locale_t);
+_XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t);
+_XLOCALE_INLINE int towupper_l(int, locale_t);
+
+_XLOCALE_INLINE int towlower_l(int __c, locale_t __l)
+{
+ int __limit;
+ _RuneLocale *__runes = __runes_for_locale(__l, &__limit);
+ return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) :
+ __runes->__maplower[__c];
+}
+_XLOCALE_INLINE int towupper_l(int __c, locale_t __l)
+{
+ int __limit;
+ _RuneLocale *__runes = __runes_for_locale(__l, &__limit);
+ return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) :
+ __runes->__mapupper[__c];
+}
+_XLOCALE_INLINE int
+__wcwidth_l(__ct_rune_t _c, locale_t __l)
+{
+ unsigned int _x;
+
+ if (_c == 0)
+ return (0);
+ _x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l);
+ if ((_x & _CTYPE_SWM) != 0)
+ return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
+ return ((_x & _CTYPE_R) != 0 ? 1 : -1);
+}
+int iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l);
+wctype_t wctype_l(const char *property, locale_t __l);
+wint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l);
+wint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l);
+wctrans_t wctrans_l(const char *__charclass, locale_t __l);
+#undef _XLOCALE_WCTYPES
+#else
+_XLOCALE_INLINE int digittoint_l(int, locale_t);
+_XLOCALE_INLINE int tolower_l(int, locale_t);
+_XLOCALE_INLINE int toupper_l(int, locale_t);
+
+_XLOCALE_INLINE int digittoint_l(int __c, locale_t __l)
+{ return __sbmaskrune_l((__c), 0xFF, __l); }
+
+_XLOCALE_INLINE int tolower_l(int __c, locale_t __l)
+{
+ int __limit;
+ _RuneLocale *__runes = __runes_for_locale(__l, &__limit);
+ return (__c < 0 || __c >= __limit) ? __c :
+ __runes->__maplower[__c];
+}
+_XLOCALE_INLINE int toupper_l(int __c, locale_t __l)
+{
+ int __limit;
+ _RuneLocale *__runes = __runes_for_locale(__l, &__limit);
+ return (__c < 0 || __c >= __limit) ? __c :
+ __runes->__mapupper[__c];
+}
+#endif
+#endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
+ (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) */
diff --git a/usr/src/boot/include/xlocale/_string.h b/usr/src/boot/include/xlocale/_string.h
new file mode 100644
index 0000000000..a7c146efc9
--- /dev/null
+++ b/usr/src/boot/include/xlocale/_string.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2011, 2012 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct _xlocale *locale_t;
+#endif
+
+/*
+ * This file is included from both string.h and xlocale.h. We need to expose
+ * the declarations unconditionally if we are included from xlocale.h, but only
+ * if we are in POSIX2008 mode if included from string.h.
+ */
+
+#ifndef _XLOCALE_STRING1_H
+#define _XLOCALE_STRING1_H
+
+/*
+ * POSIX2008 functions
+ */
+int strcoll_l(const char *, const char *, locale_t);
+size_t strxfrm_l(char *, const char *, size_t, locale_t);
+#endif /* _XLOCALE_STRING1_H */
+
+/*
+ * xlocale extensions
+ */
+#ifdef _XLOCALE_H_
+#ifndef _XLOCALE_STRING2_H
+#define _XLOCALE_STRING2_H
+char *strcasestr_l(const char *, const char *, locale_t);
+
+#endif /* _XLOCALE_STRING2_H */
+#endif /* _XLOCALE_H_ */
diff --git a/usr/src/boot/include/xlocale/_strings.h b/usr/src/boot/include/xlocale/_strings.h
new file mode 100644
index 0000000000..da1cff3e70
--- /dev/null
+++ b/usr/src/boot/include/xlocale/_strings.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2011, 2012 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct _xlocale *locale_t;
+#endif
+
+/*
+ * This file is included from both strings.h and xlocale.h. We need to expose
+ * the declarations unconditionally if we are included from xlocale.h, but only
+ * if we are in POSIX2008 mode if included from string.h.
+ */
+
+#ifndef _XLOCALE_STRINGS1_H
+#define _XLOCALE_STRINGS1_H
+
+/*
+ * POSIX2008 functions
+ */
+int strcasecmp_l(const char *, const char *, locale_t);
+int strncasecmp_l(const char *, const char *, size_t, locale_t);
+#endif /* _XLOCALE_STRINGS1_H */
diff --git a/usr/src/boot/include/xlocale/_time.h b/usr/src/boot/include/xlocale/_time.h
new file mode 100644
index 0000000000..4493fdd449
--- /dev/null
+++ b/usr/src/boot/include/xlocale/_time.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2011, 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by David Chisnall under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct _xlocale *locale_t;
+#endif
+
+/*
+ * This file is included from both locale.h and xlocale.h. We need to expose
+ * the declarations unconditionally if we are included from xlocale.h, but only
+ * if we are in POSIX2008 mode if included from locale.h.
+ */
+#ifndef _XLOCALE_LOCALE1_H
+#define _XLOCALE_LOCALE1_H
+
+size_t strftime_l(char * __restrict, size_t, const char * __restrict,
+ const struct tm * __restrict, locale_t) __strftimelike(3, 0);
+
+#endif /* _XLOCALE_LOCALE1_H */
+
+#ifdef _XLOCALE_H_
+#ifndef _XLOCALE_LOCALE2_H
+#define _XLOCALE_LOCALE2_H
+
+char *strptime_l(const char * __restrict, const char * __restrict,
+ struct tm * __restrict, locale_t);
+
+#endif /* _XLOCALE_LOCALE2_H */
+#endif /* _XLOCALE_H_ */
diff --git a/usr/src/boot/lib/libc/net/ntoh.c b/usr/src/boot/lib/libc/net/ntoh.c
new file mode 100644
index 0000000000..d658c90b68
--- /dev/null
+++ b/usr/src/boot/lib/libc/net/ntoh.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/endian.h>
+#define _BYTEORDER_FUNC_DEFINED
+#include <arpa/inet.h>
+
+uint32_t
+htonl(uint32_t hl)
+{
+
+ return (__htonl(hl));
+}
+
+uint16_t
+htons(uint16_t hs)
+{
+
+ return (__htons(hs));
+}
+
+uint32_t
+ntohl(uint32_t nl)
+{
+
+ return (__ntohl(nl));
+}
+
+uint16_t
+ntohs(uint16_t ns)
+{
+
+ return (__ntohs(ns));
+}
diff --git a/usr/src/boot/lib/libc/string/bcmp.c b/usr/src/boot/lib/libc/string/bcmp.c
new file mode 100644
index 0000000000..f1178a660b
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/bcmp.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <strings.h>
+
+/*
+ * bcmp -- vax cmpc3 instruction
+ */
+int
+bcmp(const void *b1, const void *b2, size_t length)
+{
+ char *p1, *p2;
+
+ if (length == 0)
+ return (0);
+ p1 = (char *)b1;
+ p2 = (char *)b2;
+ do
+ if (*p1++ != *p2++)
+ break;
+ while (--length);
+ return (length);
+}
diff --git a/usr/src/boot/lib/libc/string/bcopy.c b/usr/src/boot/lib/libc/string/bcopy.c
new file mode 100644
index 0000000000..c424de560f
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/bcopy.c
@@ -0,0 +1,137 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef int word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+#if defined(MEMCOPY) || defined(MEMMOVE)
+#include <string.h>
+
+void *
+#ifdef MEMCOPY
+memcpy
+#else
+memmove
+#endif
+(void *dst0, const void *src0, size_t length)
+#else
+#include <strings.h>
+
+void
+bcopy(const void *src0, void *dst0, size_t length)
+#endif
+{
+ char *dst = dst0;
+ const char *src = src0;
+ size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (uintptr_t)src; /* only need low bits */
+ if ((t | (uintptr_t)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (uintptr_t)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (uintptr_t)src;
+ if ((t | (uintptr_t)dst) & wmask) {
+ if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ return (dst0);
+#else
+ return;
+#endif
+}
diff --git a/usr/src/boot/lib/libc/string/bzero.c b/usr/src/boot/lib/libc/string/bzero.c
new file mode 100644
index 0000000000..201bd64f80
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/bzero.c
@@ -0,0 +1,5 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define BZERO
+#include "memset.c"
diff --git a/usr/src/boot/lib/libc/string/ffs.c b/usr/src/boot/lib/libc/string/ffs.c
new file mode 100644
index 0000000000..42a94ef738
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/ffs.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <strings.h>
+
+/*
+ * Find First Set bit
+ */
+int
+ffs(int mask)
+{
+ int bit;
+
+ if (mask == 0)
+ return(0);
+ for (bit = 1; !(mask & 1); bit++)
+ mask = (unsigned int)mask >> 1;
+ return (bit);
+}
diff --git a/usr/src/boot/lib/libc/string/fls.c b/usr/src/boot/lib/libc/string/fls.c
new file mode 100644
index 0000000000..7145b909f0
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/fls.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <strings.h>
+
+/*
+ * Find Last Set bit
+ */
+int
+fls(int mask)
+{
+ int bit;
+
+ if (mask == 0)
+ return (0);
+ for (bit = 1; mask != 1; bit++)
+ mask = (unsigned int)mask >> 1;
+ return (bit);
+}
diff --git a/usr/src/boot/lib/libc/string/memccpy.c b/usr/src/boot/lib/libc/string/memccpy.c
new file mode 100644
index 0000000000..6102a5bded
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memccpy.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+void *
+memccpy(void *t, const void *f, int c, size_t n)
+{
+
+ if (n) {
+ unsigned char *tp = t;
+ const unsigned char *fp = f;
+ unsigned char uc = c;
+ do {
+ if ((*tp++ = *fp++) == uc)
+ return (tp);
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/usr/src/boot/lib/libc/string/memchr.c b/usr/src/boot/lib/libc/string/memchr.c
new file mode 100644
index 0000000000..8020333dec
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memchr.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+void *
+memchr(const void *s, int c, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *p = s;
+
+ do {
+ if (*p++ == (unsigned char)c)
+ return ((void *)(p - 1));
+ } while (--n != 0);
+ }
+ return (NULL);
+}
diff --git a/usr/src/boot/lib/libc/string/memcmp.c b/usr/src/boot/lib/libc/string/memcmp.c
new file mode 100644
index 0000000000..d2d0f27d35
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memcmp.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Compare memory regions.
+ */
+int
+memcmp(const void *s1, const void *s2, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *p1 = s1, *p2 = s2;
+
+ do {
+ if (*p1++ != *p2++)
+ return (*--p1 - *--p2);
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/usr/src/boot/lib/libc/string/memcpy.c b/usr/src/boot/lib/libc/string/memcpy.c
new file mode 100644
index 0000000000..ed03856e54
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memcpy.c
@@ -0,0 +1,5 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define MEMCOPY
+#include "bcopy.c"
diff --git a/usr/src/boot/lib/libc/string/memmove.c b/usr/src/boot/lib/libc/string/memmove.c
new file mode 100644
index 0000000000..05cf75a2ce
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memmove.c
@@ -0,0 +1,5 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define MEMMOVE
+#include "bcopy.c"
diff --git a/usr/src/boot/lib/libc/string/memset.c b/usr/src/boot/lib/libc/string/memset.c
new file mode 100644
index 0000000000..ad0d513933
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/memset.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Hibler and Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <limits.h>
+
+#define wsize sizeof(u_int)
+#define wmask (wsize - 1)
+
+#ifdef BZERO
+#include <strings.h>
+
+#define RETURN return
+#define VAL 0
+#define WIDEVAL 0
+
+void
+bzero(void *dst0, size_t length)
+#else
+#include <string.h>
+
+#define RETURN return (dst0)
+#define VAL c0
+#define WIDEVAL c
+
+void *
+memset(void *dst0, int c0, size_t length)
+#endif
+{
+ size_t t;
+#ifndef BZERO
+ u_int c;
+#endif
+ u_char *dst;
+
+ dst = dst0;
+ /*
+ * If not enough words, just fill bytes. A length >= 2 words
+ * guarantees that at least one of them is `complete' after
+ * any necessary alignment. For instance:
+ *
+ * |-----------|-----------|-----------|
+ * |00|01|02|03|04|05|06|07|08|09|0A|00|
+ * ^---------------------^
+ * dst dst+length-1
+ *
+ * but we use a minimum of 3 here since the overhead of the code
+ * to do word writes is substantial.
+ */
+ if (length < 3 * wsize) {
+ while (length != 0) {
+ *dst++ = VAL;
+ --length;
+ }
+ RETURN;
+ }
+
+#ifndef BZERO
+ if ((c = (u_char)c0) != 0) { /* Fill the word. */
+ c = (c << 8) | c; /* u_int is 16 bits. */
+#if UINT_MAX > 0xffff
+ c = (c << 16) | c; /* u_int is 32 bits. */
+#endif
+#if UINT_MAX > 0xffffffff
+ c = (c << 32) | c; /* u_int is 64 bits. */
+#endif
+ }
+#endif
+ /* Align destination by filling in bytes. */
+ if ((t = (long)dst & wmask) != 0) {
+ t = wsize - t;
+ length -= t;
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ }
+
+ /* Fill words. Length was >= 2*words so we know t >= 1 here. */
+ t = length / wsize;
+ do {
+ *(u_int *)dst = WIDEVAL;
+ dst += wsize;
+ } while (--t != 0);
+
+ /* Mop up trailing bytes, if any. */
+ t = length & wmask;
+ if (t != 0)
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ RETURN;
+}
diff --git a/usr/src/boot/lib/libc/string/strcat.c b/usr/src/boot/lib/libc/string/strcat.c
new file mode 100644
index 0000000000..07a3c08c1a
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strcat.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcat.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+char *
+strcat(char * __restrict s, const char * __restrict append)
+{
+ char *save = s;
+
+ for (; *s; ++s);
+ while ((*s++ = *append++));
+ return(save);
+}
diff --git a/usr/src/boot/lib/libc/string/strchr.c b/usr/src/boot/lib/libc/string/strchr.c
new file mode 100644
index 0000000000..ab83b3995a
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strchr.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)index.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strchr(const char *p, int ch)
+{
+ char c;
+
+ c = ch;
+ for (;; ++p) {
+ if (*p == c)
+ return ((char *)p);
+ if (*p == '\0')
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+__weak_reference(strchr, index);
diff --git a/usr/src/boot/lib/libc/string/strcmp.c b/usr/src/boot/lib/libc/string/strcmp.c
new file mode 100644
index 0000000000..9daf624acc
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strcmp.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Compare strings.
+ */
+int
+strcmp(const char *s1, const char *s2)
+{
+ while (*s1 == *s2++)
+ if (*s1++ == '\0')
+ return (0);
+ return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
+}
diff --git a/usr/src/boot/lib/libc/string/strcpy.c b/usr/src/boot/lib/libc/string/strcpy.c
new file mode 100644
index 0000000000..8a48d0d0d7
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strcpy.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+char *
+strcpy(char * __restrict to, const char * __restrict from)
+{
+ char *save = to;
+
+ for (; (*to = *from); ++from, ++to);
+ return(save);
+}
diff --git a/usr/src/boot/lib/libc/string/strcspn.c b/usr/src/boot/lib/libc/string/strcspn.c
new file mode 100644
index 0000000000..3879a3b085
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strcspn.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <limits.h>
+#include <string.h>
+
+#define IDX(c) ((u_char)(c) / LONG_BIT)
+#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT))
+
+size_t
+strcspn(const char *s, const char *charset)
+{
+ /*
+ * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to
+ * generate better code. Without them, gcc gets a little confused.
+ */
+ const char *s1;
+ u_long bit;
+ u_long tbl[(UCHAR_MAX + 1) / LONG_BIT];
+ int idx;
+
+ if(*s == '\0')
+ return (0);
+
+#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */
+ tbl[0] = 1;
+ tbl[3] = tbl[2] = tbl[1] = 0;
+#else
+ for (tbl[0] = idx = 1; idx < sizeof(tbl) / sizeof(tbl[0]); idx++)
+ tbl[idx] = 0;
+#endif
+ for (; *charset != '\0'; charset++) {
+ idx = IDX(*charset);
+ bit = BIT(*charset);
+ tbl[idx] |= bit;
+ }
+
+ for(s1 = s; ; s1++) {
+ idx = IDX(*s1);
+ bit = BIT(*s1);
+ if ((tbl[idx] & bit) != 0)
+ break;
+ }
+ return (s1 - s);
+}
diff --git a/usr/src/boot/lib/libc/string/strlcat.c b/usr/src/boot/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..f5ed6c6cf7
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strlcat.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left). At most dsize-1 characters
+ * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char * __restrict dst, const char * __restrict src, size_t dsize)
+{
+ const char *odst = dst;
+ const char *osrc = src;
+ size_t n = dsize;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end. */
+ while (n-- != 0 && *dst != '\0')
+ dst++;
+ dlen = dst - odst;
+ n = dsize - dlen;
+
+ if (n-- == 0)
+ return(dlen + strlen(src));
+ while (*src != '\0') {
+ if (n != 0) {
+ *dst++ = *src;
+ n--;
+ }
+ src++;
+ }
+ *dst = '\0';
+
+ return(dlen + (src - osrc)); /* count does not include NUL */
+}
diff --git a/usr/src/boot/lib/libc/string/strlcpy.c b/usr/src/boot/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000000..019d2316a0
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strlcpy.c
@@ -0,0 +1,53 @@
+/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize. At most dsize-1
+ * chars will be copied. Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize)
+{
+ const char *osrc = src;
+ size_t nleft = dsize;
+
+ /* Copy as many bytes as will fit. */
+ if (nleft != 0) {
+ while (--nleft != 0) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src. */
+ if (nleft == 0) {
+ if (dsize != 0)
+ *dst = '\0'; /* NUL-terminate dst */
+ while (*src++)
+ ;
+ }
+
+ return(src - osrc - 1); /* count does not include NUL */
+}
diff --git a/usr/src/boot/lib/libc/string/strlen.c b/usr/src/boot/lib/libc/string/strlen.c
new file mode 100644
index 0000000000..2bc1f2b1fe
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strlen.c
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 2009, 2010 Xin LI <delphij@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/limits.h>
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Portable strlen() for 32-bit and 64-bit systems.
+ *
+ * Rationale: it is generally much more efficient to do word length
+ * operations and avoid branches on modern computer systems, as
+ * compared to byte-length operations with a lot of branches.
+ *
+ * The expression:
+ *
+ * ((x - 0x01....01) & ~x & 0x80....80)
+ *
+ * would evaluate to a non-zero value iff any of the bytes in the
+ * original word is zero.
+ *
+ * On multi-issue processors, we can divide the above expression into:
+ * a) (x - 0x01....01)
+ * b) (~x & 0x80....80)
+ * c) a & b
+ *
+ * Where, a) and b) can be partially computed in parallel.
+ *
+ * The algorithm above is found on "Hacker's Delight" by
+ * Henry S. Warren, Jr.
+ */
+
+/* Magic numbers for the algorithm */
+#if LONG_BIT == 32
+static const unsigned long mask01 = 0x01010101;
+static const unsigned long mask80 = 0x80808080;
+#elif LONG_BIT == 64
+static const unsigned long mask01 = 0x0101010101010101;
+static const unsigned long mask80 = 0x8080808080808080;
+#else
+#error Unsupported word size
+#endif
+
+#define LONGPTR_MASK (sizeof(long) - 1)
+
+/*
+ * Helper macro to return string length if we caught the zero
+ * byte.
+ */
+#define testbyte(x) \
+ do { \
+ if (p[x] == '\0') \
+ return (p - str + x); \
+ } while (0)
+
+size_t
+strlen(const char *str)
+{
+ const char *p;
+ const unsigned long *lp;
+ long va, vb;
+
+ /*
+ * Before trying the hard (unaligned byte-by-byte access) way
+ * to figure out whether there is a nul character, try to see
+ * if there is a nul character is within this accessible word
+ * first.
+ *
+ * p and (p & ~LONGPTR_MASK) must be equally accessible since
+ * they always fall in the same memory page, as long as page
+ * boundaries is integral multiple of word size.
+ */
+ lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK);
+ va = (*lp - mask01);
+ vb = ((~*lp) & mask80);
+ lp++;
+ if (va & vb)
+ /* Check if we have \0 in the first part */
+ for (p = str; p < (const char *)lp; p++)
+ if (*p == '\0')
+ return (p - str);
+
+ /* Scan the rest of the string using word sized operation */
+ for (; ; lp++) {
+ va = (*lp - mask01);
+ vb = ((~*lp) & mask80);
+ if (va & vb) {
+ p = (const char *)(lp);
+ testbyte(0);
+ testbyte(1);
+ testbyte(2);
+ testbyte(3);
+#if (LONG_BIT >= 64)
+ testbyte(4);
+ testbyte(5);
+ testbyte(6);
+ testbyte(7);
+#endif
+ }
+ }
+
+ /* NOTREACHED */
+ return (0);
+}
diff --git a/usr/src/boot/lib/libc/string/strncat.c b/usr/src/boot/lib/libc/string/strncat.c
new file mode 100644
index 0000000000..6a0e553daa
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strncat.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
+ * are written at dst (at most n+1 bytes being appended). Return dst.
+ */
+char *
+strncat(char * __restrict dst, const char * __restrict src, size_t n)
+{
+ if (n != 0) {
+ char *d = dst;
+ const char *s = src;
+
+ while (*d != 0)
+ d++;
+ do {
+ if ((*d = *s++) == 0)
+ break;
+ d++;
+ } while (--n != 0);
+ *d = 0;
+ }
+ return (dst);
+}
diff --git a/usr/src/boot/lib/libc/string/strncmp.c b/usr/src/boot/lib/libc/string/strncmp.c
new file mode 100644
index 0000000000..4967a9483e
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strncmp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+
+ if (n == 0)
+ return (0);
+ do {
+ if (*s1 != *s2++)
+ return (*(const unsigned char *)s1 -
+ *(const unsigned char *)(s2 - 1));
+ if (*s1++ == '\0')
+ break;
+ } while (--n != 0);
+ return (0);
+}
diff --git a/usr/src/boot/lib/libc/string/strncpy.c b/usr/src/boot/lib/libc/string/strncpy.c
new file mode 100644
index 0000000000..3907403508
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strncpy.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+char *
+strncpy(char * __restrict dst, const char * __restrict src, size_t n)
+{
+ if (n != 0) {
+ char *d = dst;
+ const char *s = src;
+
+ do {
+ if ((*d++ = *s++) == '\0') {
+ /* NUL pad the remaining n-1 bytes */
+ while (--n != 0)
+ *d++ = '\0';
+ break;
+ }
+ } while (--n != 0);
+ }
+ return (dst);
+}
diff --git a/usr/src/boot/lib/libc/string/strpbrk.c b/usr/src/boot/lib/libc/string/strpbrk.c
new file mode 100644
index 0000000000..565ef82f11
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strpbrk.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strpbrk.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Find the first occurrence in s1 of a character in s2 (excluding NUL).
+ */
+char *
+strpbrk(const char *s1, const char *s2)
+{
+ const char *scanp;
+ int c, sc;
+
+ while ((c = *s1++) != 0) {
+ for (scanp = s2; (sc = *scanp++) != '\0';)
+ if (sc == c)
+ return ((char *)(s1 - 1));
+ }
+ return (NULL);
+}
diff --git a/usr/src/boot/lib/libc/string/strrchr.c b/usr/src/boot/lib/libc/string/strrchr.c
new file mode 100644
index 0000000000..f84ffb78c4
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strrchr.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rindex.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strrchr(const char *p, int ch)
+{
+ char *save;
+ char c;
+
+ c = ch;
+ for (save = NULL;; ++p) {
+ if (*p == c)
+ save = (char *)p;
+ if (*p == '\0')
+ return (save);
+ }
+ /* NOTREACHED */
+}
+
+__weak_reference(strrchr, rindex);
diff --git a/usr/src/boot/lib/libc/string/strsep.c b/usr/src/boot/lib/libc/string/strsep.c
new file mode 100644
index 0000000000..73c61af811
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strsep.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(char **stringp, const char *delim)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/usr/src/boot/lib/libc/string/strspn.c b/usr/src/boot/lib/libc/string/strspn.c
new file mode 100644
index 0000000000..5dbac0a678
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strspn.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <limits.h>
+#include <string.h>
+
+#define IDX(c) ((u_char)(c) / LONG_BIT)
+#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT))
+
+size_t
+strspn(const char *s, const char *charset)
+{
+ /*
+ * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to
+ * generate better code. Without them, gcc gets a little confused.
+ */
+ const char *s1;
+ u_long bit;
+ u_long tbl[(UCHAR_MAX + 1) / LONG_BIT];
+ int idx;
+
+ if(*s == '\0')
+ return (0);
+
+#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */
+ tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0;
+#else
+ for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++)
+ tbl[idx] = 0;
+#endif
+ for (; *charset != '\0'; charset++) {
+ idx = IDX(*charset);
+ bit = BIT(*charset);
+ tbl[idx] |= bit;
+ }
+
+ for(s1 = s; ; s1++) {
+ idx = IDX(*s1);
+ bit = BIT(*s1);
+ if ((tbl[idx] & bit) == 0)
+ break;
+ }
+ return (s1 - s);
+}
diff --git a/usr/src/boot/lib/libc/string/strstr.c b/usr/src/boot/lib/libc/string/strstr.c
new file mode 100644
index 0000000000..18e60d5798
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strstr.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Find the first occurrence of find in s.
+ */
+char *
+strstr(const char *s, const char *find)
+{
+ char c, sc;
+ size_t len;
+
+ if ((c = *find++) != '\0') {
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == '\0')
+ return (NULL);
+ } while (sc != c);
+ } while (strncmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
diff --git a/usr/src/boot/lib/libc/string/strtok.c b/usr/src/boot/lib/libc/string/strtok.c
new file mode 100644
index 0000000000..063a554339
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/strtok.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 1998 Softweyr LLC. All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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
+ * notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notices, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtok.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stddef.h>
+#ifdef DEBUG_STRTOK
+#include <stdio.h>
+#endif
+#include <string.h>
+
+char *__strtok_r(char *, const char *, char **);
+
+__weak_reference(__strtok_r, strtok_r);
+
+char *
+__strtok_r(char *s, const char *delim, char **last)
+{
+ char *spanp, *tok;
+ int c, sc;
+
+ if (s == NULL && (s = *last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ *last = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = '\0';
+ *last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
+char *
+strtok(char *s, const char *delim)
+{
+ static char *last;
+
+ return (__strtok_r(s, delim, &last));
+}
+
+#ifdef DEBUG_STRTOK
+/*
+ * Test the tokenizer.
+ */
+int
+main(void)
+{
+ char blah[80], test[80];
+ char *brkb, *brkt, *phrase, *sep, *word;
+
+ sep = "\\/:;=-";
+ phrase = "foo";
+
+ printf("String tokenizer test:\n");
+ strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
+ for (word = strtok(test, sep); word; word = strtok(NULL, sep))
+ printf("Next word is \"%s\".\n", word);
+ strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
+
+ for (word = strtok_r(test, sep, &brkt); word;
+ word = strtok_r(NULL, sep, &brkt)) {
+ strcpy(blah, "blah:blat:blab:blag");
+
+ for (phrase = strtok_r(blah, sep, &brkb); phrase;
+ phrase = strtok_r(NULL, sep, &brkb))
+ printf("So far we're at %s:%s\n", word, phrase);
+ }
+
+ return (0);
+}
+
+#endif /* DEBUG_STRTOK */
diff --git a/usr/src/boot/lib/libc/string/swab.c b/usr/src/boot/lib/libc/string/swab.c
new file mode 100644
index 0000000000..84633094be
--- /dev/null
+++ b/usr/src/boot/lib/libc/string/swab.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jeffrey Mogul.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <unistd.h>
+
+void
+swab(const void * __restrict from, void * __restrict to, ssize_t len)
+{
+ unsigned long temp;
+ int n;
+ char *fp, *tp;
+
+ if (len <= 0)
+ return;
+ n = len >> 1;
+ fp = (char *)from;
+ tp = (char *)to;
+#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp
+ /* round to multiple of 8 */
+ for (; n & 0x7; --n)
+ STEP;
+ for (n >>= 3; n > 0; --n) {
+ STEP; STEP; STEP; STEP;
+ STEP; STEP; STEP; STEP;
+ }
+}
diff --git a/usr/src/boot/lib/libc/uuid/uuid_create_nil.c b/usr/src/boot/lib/libc/uuid/uuid_create_nil.c
new file mode 100644
index 0000000000..6e85ae7fb7
--- /dev/null
+++ b/usr/src/boot/lib/libc/uuid/uuid_create_nil.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <strings.h>
+#include <uuid.h>
+
+/*
+ * uuid_create_nil() - create a nil UUID.
+ * See also:
+ * http://www.opengroup.org/onlinepubs/009629399/uuid_create_nil.htm
+ */
+void
+uuid_create_nil(uuid_t *u, uint32_t *status)
+{
+
+ if (status)
+ *status = uuid_s_ok;
+
+ bzero(u, sizeof(*u));
+}
diff --git a/usr/src/boot/lib/libc/uuid/uuid_equal.c b/usr/src/boot/lib/libc/uuid/uuid_equal.c
new file mode 100644
index 0000000000..e4c48e5253
--- /dev/null
+++ b/usr/src/boot/lib/libc/uuid/uuid_equal.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <string.h>
+#include <uuid.h>
+
+/*
+ * uuid_equal() - compare for equality.
+ * See also:
+ * http://www.opengroup.org/onlinepubs/009629399/uuid_equal.htm
+ */
+int32_t
+uuid_equal(const uuid_t *a, const uuid_t *b, uint32_t *status)
+{
+
+ if (status != NULL)
+ *status = uuid_s_ok;
+
+ /* Deal with equal or NULL pointers. */
+ if (a == b)
+ return (1);
+ if (a == NULL)
+ return (uuid_is_nil(b, NULL));
+ if (b == NULL)
+ return (uuid_is_nil(a, NULL));
+
+ /* Do a byte for byte comparison. */
+ return ((memcmp(a, b, sizeof(uuid_t))) ? 0 : 1);
+}
diff --git a/usr/src/boot/lib/libc/uuid/uuid_is_nil.c b/usr/src/boot/lib/libc/uuid/uuid_is_nil.c
new file mode 100644
index 0000000000..ee1865349d
--- /dev/null
+++ b/usr/src/boot/lib/libc/uuid/uuid_is_nil.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <uuid.h>
+
+/*
+ * uuid_is_nil() - return whether the UUID is a nil UUID.
+ * See also:
+ * http://www.opengroup.org/onlinepubs/009629399/uuid_is_nil.htm
+ */
+int32_t
+uuid_is_nil(const uuid_t *u, uint32_t *status)
+{
+ const uint32_t *p;
+
+ if (status)
+ *status = uuid_s_ok;
+
+ if (!u)
+ return (1);
+
+ /*
+ * Pick the largest type that has equivalent alignment constraints
+ * as an UUID and use it to test if the UUID consists of all zeroes.
+ */
+ p = (const uint32_t*)u;
+ return ((p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0) ? 1 : 0);
+}
diff --git a/usr/src/boot/lib/libstand/Makefile.inc b/usr/src/boot/lib/libstand/Makefile.inc
new file mode 100644
index 0000000000..579088831d
--- /dev/null
+++ b/usr/src/boot/lib/libstand/Makefile.inc
@@ -0,0 +1,197 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+#
+# Notes:
+# - We don't use the libc strerror/sys_errlist because the string table is
+# quite large.
+#
+
+# standalone components and stuff we have modified locally
+SRCS= $(LIB_BASE)/libz/gzguts.h $(LIB_BASE)/libz/zutil.h
+SRCS += $(LIBSTAND_SRC)/__main.c $(LIBSTAND_SRC)/assert.c
+SRCS += $(LIBSTAND_SRC)/bcd.c $(LIBSTAND_SRC)/bswap.c
+SRCS += $(LIBSTAND_SRC)/environment.c $(LIBSTAND_SRC)/getopt.c
+SRCS += $(LIBSTAND_SRC)/strtol.c $(LIBSTAND_SRC)/strtoul.c
+SRCS += $(LIBSTAND_SRC)/random.c $(LIBSTAND_SRC)/sbrk.c
+SRCS += $(LIBSTAND_SRC)/twiddle.c $(LIBSTAND_SRC)/zalloc.c
+SRCS += $(LIBSTAND_SRC)/zalloc_malloc.c
+
+OBJS= __main.o assert.o bcd.o bswap.o environment.o \
+ getopt.o gets.o globals.o pager.o printf.o \
+ strdup.o strerror.o strtol.o strtoul.o random.o \
+ sbrk.o twiddle.o zalloc.o zalloc_malloc.o
+
+# private (pruned) versions of libc string functions
+SRCS += $(LIBSTAND_SRC)/strcasecmp.c
+OBJS += strcasecmp.o
+
+# from libc
+SRCS += $(LIB_BASE)/libc/net/ntoh.c
+OBJS += ntoh.o
+
+# string functions from libc
+SRCS += $(LIB_BASE)/libc/string/bcmp.c $(LIB_BASE)/libc/string/bcopy.c
+SRCS += $(LIB_BASE)/libc/string/bzero.c $(LIB_BASE)/libc/string/ffs.c
+SRCS += $(LIB_BASE)/libc/string/fls.c $(LIB_BASE)/libc/string/memccpy.c
+SRCS += $(LIB_BASE)/libc/string/memchr.c $(LIB_BASE)/libc/string/memcmp.c
+SRCS += $(LIB_BASE)/libc/string/memcpy.c $(LIB_BASE)/libc/string/memmove.c
+SRCS += $(LIB_BASE)/libc/string/memset.c $(LIB_BASE)/libc/string/strcat.c
+SRCS += $(LIB_BASE)/libc/string/strchr.c $(LIB_BASE)/libc/string/strcmp.c
+SRCS += $(LIB_BASE)/libc/string/strcpy.c $(LIB_BASE)/libc/string/strcspn.c
+SRCS += $(LIB_BASE)/libc/string/strlcat.c $(LIB_BASE)/libc/string/strlcpy.c
+SRCS += $(LIB_BASE)/libc/string/strlen.c $(LIB_BASE)/libc/string/strncat.c
+SRCS += $(LIB_BASE)/libc/string/strncmp.c $(LIB_BASE)/libc/string/strncpy.c
+SRCS += $(LIB_BASE)/libc/string/strpbrk.c $(LIB_BASE)/libc/string/strrchr.c
+SRCS += $(LIB_BASE)/libc/string/strsep.c $(LIB_BASE)/libc/string/strspn.c
+SRCS += $(LIB_BASE)/libc/string/strstr.c $(LIB_BASE)/libc/string/strtok.c
+SRCS += $(LIB_BASE)/libc/string/swab.c
+
+SRCS += $(LIBSTAND_SRC)/qdivrem.c
+
+OBJS += bcmp.o bcopy.o bzero.o ffs.o fls.o \
+ memccpy.o memchr.o memcmp.o memcpy.o memmove.o memset.o \
+ qdivrem.o strcat.o strchr.o strcmp.o strcpy.o \
+ strcspn.o strlcat.o strlcpy.o strlen.o strncat.o strncmp.o strncpy.o \
+ strpbrk.o strrchr.o strsep.o strspn.o strstr.o strtok.o swab.o
+
+# uuid functions from libc
+SRCS += $(LIB_BASE)/libc/uuid/uuid_create_nil.c
+SRCS += $(LIB_BASE)/libc/uuid/uuid_equal.c
+SRCS += $(LIB_BASE)/libc/uuid/uuid_is_nil.c
+
+SRCS += $(LIBSTAND_SRC)/uuid_from_string.c
+SRCS += $(LIBSTAND_SRC)/uuid_to_string.c
+
+OBJS += uuid_create_nil.o uuid_equal.o uuid_from_string.o uuid_is_nil.o \
+ uuid_to_string.o
+
+# decompression functionality from libbz2
+# NOTE: to actually test this functionality after libbz2 upgrade compile
+# loader(8) with LOADER_BZIP2_SUPPORT defined
+CFLAGS += -DBZ_NO_STDIO -DBZ_NO_COMPRESS
+SRCS += libstand_bzlib_private.h
+
+SRCS += _bzlib.c _crctable.c _decompress.c _huffman.c _randtable.c
+OBJS += _bzlib.o _crctable.o _decompress.o _huffman.o _randtable.o
+CLEANFILES += _bzlib.c _crctable.c _decompress.c _huffman.c _randtable.c
+
+_bzlib.c: $(LIB_BASE)/../contrib/bzip2/bzlib.c
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" $^ > $@
+
+_crctable.c: $(LIB_BASE)/../contrib/bzip2/crctable.c
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" $^ > $@
+
+_decompress.c: $(LIB_BASE)/../contrib/bzip2/decompress.c
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" $^ > $@
+
+_huffman.c: $(LIB_BASE)/../contrib/bzip2/huffman.c
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" $^ > $@
+
+_randtable.c: $(LIB_BASE)/../contrib/bzip2/randtable.c
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" $^ > $@
+
+CLEANFILES += libstand_bzlib_private.h
+libstand_bzlib_private.h: $(LIB_BASE)/../contrib/bzip2/bzlib_private.h
+ sed -e 's|<stdlib.h>|"stand.h"|' $^ > $@
+
+# decompression functionality from libz
+CFLAGS += -DHAVE_MEMCPY -I$(LIB_BASE)/libz
+SRCS += $(LIB_BASE)/libz/adler32.c $(LIB_BASE)/libz/crc32.c \
+ libstand_zutil.h libstand_gzguts.h
+OBJS += adler32.o crc32.o
+
+_infback.c: $(LIB_BASE)/libz/infback.c
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ $^ > $@
+_inffast.c: $(LIB_BASE)/libz/inffast.c
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ $^ > $@
+_inflate.c: $(LIB_BASE)/libz/inflate.c
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ $^ > $@
+_inftrees.c: $(LIB_BASE)/libz/inftrees.c
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ $^ > $@
+_zutil.c: $(LIB_BASE)/libz/zutil.c
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ $^ > $@
+
+SRCS += _infback.c _inffast.c _inflate.c _inftrees.c _zutil.c
+OBJS += _infback.o _inffast.o _inflate.o _inftrees.o _zutil.o
+CLEANFILES += _infback.c _inffast.c _inflate.c _inftrees.c _zutil.c
+
+# depend on stand.h being able to be included multiple times
+libstand_zutil.h: $(LIB_BASE)/libz/zutil.h
+ sed -e 's|<fcntl.h>|"stand.h"|' \
+ -e 's|<stddef.h>|"stand.h"|' \
+ -e 's|<string.h>|"stand.h"|' \
+ -e 's|<stdio.h>|"stand.h"|' \
+ -e 's|<stdlib.h>|"stand.h"|' \
+ $^ > $@
+
+libstand_gzguts.h: $(LIB_BASE)/libz/gzguts.h
+ sed -e 's|<fcntl.h>|"stand.h"|' \
+ -e 's|<stddef.h>|"stand.h"|' \
+ -e 's|<string.h>|"stand.h"|' \
+ -e 's|<stdio.h>|"stand.h"|' \
+ -e 's|<stdlib.h>|"stand.h"|' \
+ $^ > $@
+
+CLEANFILES += libstand_zutil.h libstand_gzguts.h
+
+# io routines
+SRCS += $(LIBSTAND_SRC)/closeall.c $(LIBSTAND_SRC)/dev.c \
+ $(LIBSTAND_SRC)/ioctl.c $(LIBSTAND_SRC)/nullfs.c \
+ $(LIBSTAND_SRC)/stat.c $(LIBSTAND_SRC)/fstat.c $(LIBSTAND_SRC)/close.c \
+ $(LIBSTAND_SRC)/lseek.c $(LIBSTAND_SRC)/open.c $(LIBSTAND_SRC)/read.c \
+ $(LIBSTAND_SRC)/write.c $(LIBSTAND_SRC)/readdir.c
+
+OBJS += closeall.o dev.o ioctl.o nullfs.o stat.o fstat.o close.o lseek.o \
+ open.o read.o write.o readdir.o
+
+# network routines
+SRCS += $(LIBSTAND_SRC)/arp.c $(LIBSTAND_SRC)/ether.c \
+ $(LIBSTAND_SRC)/inet_ntoa.c $(LIBSTAND_SRC)/in_cksum.c \
+ $(LIBSTAND_SRC)/net.c $(LIBSTAND_SRC)/udp.c $(LIBSTAND_SRC)/netif.c \
+ $(LIBSTAND_SRC)/rpc.c
+OBJS += arp.o ether.o inet_ntoa.o in_cksum.o net.o udp.o netif.o rpc.o
+
+# network info services:
+SRCS += $(LIBSTAND_SRC)/bootp.c $(LIBSTAND_SRC)/rarp.c \
+ $(LIBSTAND_SRC)/bootparam.c
+OBJS += bootp.o rarp.o bootparam.o
+
+# boot filesystems
+SRCS += $(LIBSTAND_SRC)/ufs.c
+SRCS += $(LIBSTAND_SRC)/nfs.c
+SRCS += $(LIBSTAND_SRC)/cd9660.c
+SRCS += $(LIBSTAND_SRC)/tftp.c
+SRCS += $(LIBSTAND_SRC)/gzipfs.c
+SRCS += $(LIBSTAND_SRC)/bzipfs.c
+SRCS += $(LIBSTAND_SRC)/dosfs.c
+OBJS += ufs.o
+OBJS += nfs.o
+OBJS += cd9660.o
+OBJS += tftp.o
+OBJS += gzipfs.o
+OBJS += bzipfs.o
+OBJS += dosfs.o
+#
diff --git a/usr/src/boot/lib/libstand/__main.c b/usr/src/boot/lib/libstand/__main.c
new file mode 100644
index 0000000000..e38f33865c
--- /dev/null
+++ b/usr/src/boot/lib/libstand/__main.c
@@ -0,0 +1,43 @@
+/* $NetBSD: __main.c,v 1.4 1996/03/14 18:52:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1993 Christopher G. Demetriou
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+void __main(void);
+
+void
+__main(void)
+{
+}
diff --git a/usr/src/boot/lib/libstand/amd64/_setjmp.S b/usr/src/boot/lib/libstand/amd64/_setjmp.S
new file mode 100644
index 0000000000..e841f493f6
--- /dev/null
+++ b/usr/src/boot/lib/libstand/amd64/_setjmp.S
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+ .asciz "@(#)_setjmp.s 5.1 (Berkeley) 4/23/90"
+#endif /* LIBC_SCCS and not lint */
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is NOT restored.
+ */
+
+ENTRY(_setjmp)
+ movq %rdi,%rax
+ movq 0(%rsp),%rdx /* retval */
+ movq %rdx, 0(%rax) /* 0; retval */
+ movq %rbx, 8(%rax) /* 1; rbx */
+ movq %rsp,16(%rax) /* 2; rsp */
+ movq %rbp,24(%rax) /* 3; rbp */
+ movq %r12,32(%rax) /* 4; r12 */
+ movq %r13,40(%rax) /* 5; r13 */
+ movq %r14,48(%rax) /* 6; r14 */
+ movq %r15,56(%rax) /* 7; r15 */
+ fnstcw 64(%rax) /* 8; fpu cw */
+ stmxcsr 68(%rax) /* and mxcsr */
+ xorq %rax,%rax
+ ret
+END(_setjmp)
+
+ .weak CNAME(_longjmp)
+ENTRY(_longjmp)
+ movq %rdi,%rdx
+ /* Restore the mxcsr, but leave exception flags intact. */
+ stmxcsr -4(%rsp)
+ movl 68(%rdx),%eax
+ andl $0xffffffc0,%eax
+ movl -4(%rsp),%edi
+ andl $0x3f,%edi
+ xorl %eax,%edi
+ movl %edi,-4(%rsp)
+ ldmxcsr -4(%rsp)
+ movq %rsi,%rax /* retval */
+ movq 0(%rdx),%rcx
+ movq 8(%rdx),%rbx
+ movq 16(%rdx),%rsp
+ movq 24(%rdx),%rbp
+ movq 32(%rdx),%r12
+ movq 40(%rdx),%r13
+ movq 48(%rdx),%r14
+ movq 56(%rdx),%r15
+ fldcw 64(%rdx)
+ testq %rax,%rax
+ jnz 1f
+ incq %rax
+1: movq %rcx,0(%rsp)
+ ret
+END(_longjmp)
diff --git a/usr/src/boot/lib/libstand/arp.c b/usr/src/boot/lib/libstand/arp.c
new file mode 100644
index 0000000000..e6175325f3
--- /dev/null
+++ b/usr/src/boot/lib/libstand/arp.c
@@ -0,0 +1,309 @@
+/* $NetBSD: arp.c,v 1.18 1997/07/07 15:52:49 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+
+/* Cache stuff */
+#define ARP_NUM 8 /* need at most 3 arp entries */
+
+struct arp_list {
+ struct in_addr addr;
+ u_char ea[6];
+} arp_list[ARP_NUM] = {
+ /* XXX - net order `INADDR_BROADCAST' must be a constant */
+ { {0xffffffff}, BA }
+};
+int arp_num = 1;
+
+/* Local forwards */
+static ssize_t arpsend(struct iodesc *, void *, size_t);
+static ssize_t arprecv(struct iodesc *, void *, size_t, time_t);
+
+/* Broadcast an ARP packet, asking who has addr on interface d */
+u_char *
+arpwhohas(d, addr)
+ struct iodesc *d;
+ struct in_addr addr;
+{
+ int i;
+ struct ether_arp *ah;
+ struct arp_list *al;
+ struct {
+ struct ether_header eh;
+ struct {
+ struct ether_arp arp;
+ u_char pad[18]; /* 60 - sizeof(...) */
+ } data;
+ } wbuf;
+ struct {
+ struct ether_header eh;
+ struct {
+ struct ether_arp arp;
+ u_char pad[24]; /* extra space */
+ } data;
+ } rbuf;
+
+ /* Try for cached answer first */
+ for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
+ if (addr.s_addr == al->addr.s_addr)
+ return (al->ea);
+
+ /* Don't overflow cache */
+ if (arp_num > ARP_NUM - 1) {
+ arp_num = 1; /* recycle */
+ printf("arpwhohas: overflowed arp_list!\n");
+ }
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arpwhohas: send request for %s\n", inet_ntoa(addr));
+#endif
+
+ bzero((char*)&wbuf.data, sizeof(wbuf.data));
+ ah = &wbuf.data.arp;
+ ah->arp_hrd = htons(ARPHRD_ETHER);
+ ah->arp_pro = htons(ETHERTYPE_IP);
+ ah->arp_hln = sizeof(ah->arp_sha); /* hardware address length */
+ ah->arp_pln = sizeof(ah->arp_spa); /* protocol address length */
+ ah->arp_op = htons(ARPOP_REQUEST);
+ MACPY(d->myea, ah->arp_sha);
+ bcopy(&d->myip, ah->arp_spa, sizeof(ah->arp_spa));
+ /* Leave zeros in arp_tha */
+ bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa));
+
+ /* Store ip address in cache (incomplete entry). */
+ al->addr = addr;
+
+ i = sendrecv(d,
+ arpsend, &wbuf.data, sizeof(wbuf.data),
+ arprecv, &rbuf.data, sizeof(rbuf.data));
+ if (i == -1) {
+ panic("arp: no response for %s\n",
+ inet_ntoa(addr));
+ }
+
+ /* Store ethernet address in cache */
+ ah = &rbuf.data.arp;
+#ifdef ARP_DEBUG
+ if (debug) {
+ printf("arp: response from %s\n",
+ ether_sprintf(rbuf.eh.ether_shost));
+ printf("arp: cacheing %s --> %s\n",
+ inet_ntoa(addr), ether_sprintf(ah->arp_sha));
+ }
+#endif
+ MACPY(ah->arp_sha, al->ea);
+ ++arp_num;
+
+ return (al->ea);
+}
+
+static ssize_t
+arpsend(d, pkt, len)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+{
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arpsend: called\n");
+#endif
+
+ return (sendether(d, pkt, len, bcea, ETHERTYPE_ARP));
+}
+
+/*
+ * Returns 0 if this is the packet we're waiting for
+ * else -1 (and errno == 0)
+ */
+static ssize_t
+arprecv(d, pkt, len, tleft)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ time_t tleft;
+{
+ ssize_t n;
+ struct ether_arp *ah;
+ u_int16_t etype; /* host order */
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arprecv: ");
+#endif
+
+ n = readether(d, pkt, len, tleft, &etype);
+ errno = 0; /* XXX */
+ if (n == -1 || n < sizeof(struct ether_arp)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("bad len=%d\n", n);
+#endif
+ return (-1);
+ }
+
+ if (etype != ETHERTYPE_ARP) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("not arp type=%d\n", etype);
+#endif
+ return (-1);
+ }
+
+ /* Ethernet address now checked in readether() */
+
+ ah = (struct ether_arp *)pkt;
+ if (ah->arp_hrd != htons(ARPHRD_ETHER) ||
+ ah->arp_pro != htons(ETHERTYPE_IP) ||
+ ah->arp_hln != sizeof(ah->arp_sha) ||
+ ah->arp_pln != sizeof(ah->arp_spa) )
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("bad hrd/pro/hln/pln\n");
+#endif
+ return (-1);
+ }
+
+ if (ah->arp_op == htons(ARPOP_REQUEST)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("is request\n");
+#endif
+ arp_reply(d, ah);
+ return (-1);
+ }
+
+ if (ah->arp_op != htons(ARPOP_REPLY)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("not ARP reply\n");
+#endif
+ return (-1);
+ }
+
+ /* Is the reply from the source we want? */
+ if (bcmp(&arp_list[arp_num].addr,
+ ah->arp_spa, sizeof(ah->arp_spa)))
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("unwanted address\n");
+#endif
+ return (-1);
+ }
+ /* We don't care who the reply was sent to. */
+
+ /* We have our answer. */
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("got it\n");
+#endif
+ return (n);
+}
+
+/*
+ * Convert an ARP request into a reply and send it.
+ * Notes: Re-uses buffer. Pad to length = 46.
+ */
+void
+arp_reply(d, pkt)
+ struct iodesc *d;
+ void *pkt; /* the request */
+{
+ struct ether_arp *arp = pkt;
+
+ if (arp->arp_hrd != htons(ARPHRD_ETHER) ||
+ arp->arp_pro != htons(ETHERTYPE_IP) ||
+ arp->arp_hln != sizeof(arp->arp_sha) ||
+ arp->arp_pln != sizeof(arp->arp_spa) )
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arp_reply: bad hrd/pro/hln/pln\n");
+#endif
+ return;
+ }
+
+ if (arp->arp_op != htons(ARPOP_REQUEST)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arp_reply: not request!\n");
+#endif
+ return;
+ }
+
+ /* If we are not the target, ignore the request. */
+ if (bcmp(arp->arp_tpa, &d->myip, sizeof(arp->arp_tpa)))
+ return;
+
+#ifdef ARP_DEBUG
+ if (debug) {
+ printf("arp_reply: to %s\n", ether_sprintf(arp->arp_sha));
+ }
+#endif
+
+ arp->arp_op = htons(ARPOP_REPLY);
+ /* source becomes target */
+ bcopy(arp->arp_sha, arp->arp_tha, sizeof(arp->arp_tha));
+ bcopy(arp->arp_spa, arp->arp_tpa, sizeof(arp->arp_tpa));
+ /* here becomes source */
+ bcopy(d->myea, arp->arp_sha, sizeof(arp->arp_sha));
+ bcopy(&d->myip, arp->arp_spa, sizeof(arp->arp_spa));
+
+ /*
+ * No need to get fancy here. If the send fails, the
+ * requestor will just ask again.
+ */
+ (void) sendether(d, pkt, sizeof(*arp) + 18,
+ arp->arp_tha, ETHERTYPE_ARP);
+}
diff --git a/usr/src/boot/lib/libstand/assert.c b/usr/src/boot/lib/libstand/assert.c
new file mode 100644
index 0000000000..8eec63a472
--- /dev/null
+++ b/usr/src/boot/lib/libstand/assert.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1998 Michael Smith.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+
+#include "stand.h"
+
+void
+__assert(const char *func, const char *file, int line, const char *expression)
+{
+ if (func == NULL)
+ panic("Assertion failed: (%s), file %s, line %d.\n",
+ expression, file, line);
+ else
+ panic(
+ "Assertion failed: (%s), function %s, file %s, line %d.\n",
+ expression, func, file, line);
+}
diff --git a/usr/src/boot/lib/libstand/bcd.c b/usr/src/boot/lib/libstand/bcd.c
new file mode 100644
index 0000000000..7bd67c9162
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bcd.c
@@ -0,0 +1,38 @@
+/*
+ * Some data-tables that are often used.
+ * Cannot be copyrighted.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+u_char const bcd2bin_data[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
+};
+
+u_char const bin2bcd_data[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
+};
+
+/* This is actually used with radix [2..36] */
+char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
diff --git a/usr/src/boot/lib/libstand/bootp.c b/usr/src/boot/lib/libstand/bootp.c
new file mode 100644
index 0000000000..1af7bd5da1
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bootp.c
@@ -0,0 +1,749 @@
+/* $NetBSD: bootp.c,v 1.14 1998/02/16 11:10:54 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#define BOOTP_DEBUGxx
+#define SUPPORT_DHCP
+
+#define DHCP_ENV_NOVENDOR 1 /* do not parse vendor options */
+#define DHCP_ENV_PXE 10 /* assume pxe vendor options */
+#define DHCP_ENV_FREEBSD 11 /* assume freebsd vendor options */
+/* set DHCP_ENV to one of the values above to export dhcp options to kenv */
+#define DHCP_ENV DHCP_ENV_NO_VENDOR
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "bootp.h"
+
+
+struct in_addr servip;
+
+static n_long nmask, smask;
+
+static time_t bot;
+
+static char vm_rfc1048[4] = VM_RFC1048;
+#ifdef BOOTP_VEND_CMU
+static char vm_cmu[4] = VM_CMU;
+#endif
+
+/* Local forwards */
+static ssize_t bootpsend(struct iodesc *, void *, size_t);
+static ssize_t bootprecv(struct iodesc *, void *, size_t, time_t);
+static int vend_rfc1048(u_char *, u_int);
+#ifdef BOOTP_VEND_CMU
+static void vend_cmu(u_char *);
+#endif
+
+#ifdef DHCP_ENV /* export the dhcp response to kenv */
+struct dhcp_opt;
+static void setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts);
+#else
+#define setenv_(a, b, c)
+#endif
+
+#ifdef SUPPORT_DHCP
+static char expected_dhcpmsgtype = -1, dhcp_ok;
+struct in_addr dhcp_serverip;
+#endif
+
+/* Fetch required bootp infomation */
+void
+bootp(sock, flag)
+ int sock;
+ int flag;
+{
+ struct iodesc *d;
+ struct bootp *bp;
+ struct {
+ u_char header[HEADER_SIZE];
+ struct bootp wbootp;
+ } wbuf;
+ struct {
+ u_char header[HEADER_SIZE];
+ struct bootp rbootp;
+ } rbuf;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootp: socket=%d\n", sock);
+#endif
+ if (!bot)
+ bot = getsecs();
+
+ if (!(d = socktodesc(sock))) {
+ printf("bootp: bad socket. %d\n", sock);
+ return;
+ }
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootp: d=%lx\n", (long)d);
+#endif
+
+ bp = &wbuf.wbootp;
+ bzero(bp, sizeof(*bp));
+
+ bp->bp_op = BOOTREQUEST;
+ bp->bp_htype = 1; /* 10Mb Ethernet (48 bits) */
+ bp->bp_hlen = 6;
+ bp->bp_xid = htonl(d->xid);
+ MACPY(d->myea, bp->bp_chaddr);
+ strncpy(bp->bp_file, bootfile, sizeof(bp->bp_file));
+ bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
+#ifdef SUPPORT_DHCP
+ bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
+ bp->bp_vend[5] = 1;
+ bp->bp_vend[6] = DHCPDISCOVER;
+
+ /*
+ * If we are booting from PXE, we want to send the string
+ * 'PXEClient' to the DHCP server so you have the option of
+ * only responding to PXE aware dhcp requests.
+ */
+ if (flag & BOOTP_PXE) {
+ bp->bp_vend[7] = TAG_CLASSID;
+ bp->bp_vend[8] = 9;
+ bcopy("PXEClient", &bp->bp_vend[9], 9);
+ bp->bp_vend[18] = TAG_END;
+ } else
+ bp->bp_vend[7] = TAG_END;
+#else
+ bp->bp_vend[4] = TAG_END;
+#endif
+
+ d->myip.s_addr = INADDR_ANY;
+ d->myport = htons(IPPORT_BOOTPC);
+ d->destip.s_addr = INADDR_BROADCAST;
+ d->destport = htons(IPPORT_BOOTPS);
+
+#ifdef SUPPORT_DHCP
+ expected_dhcpmsgtype = DHCPOFFER;
+ dhcp_ok = 0;
+#endif
+
+ if(sendrecv(d,
+ bootpsend, bp, sizeof(*bp),
+ bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
+ == -1) {
+ printf("bootp: no reply\n");
+ return;
+ }
+
+#ifdef SUPPORT_DHCP
+ if(dhcp_ok) {
+ u_int32_t leasetime;
+ bp->bp_vend[6] = DHCPREQUEST;
+ bp->bp_vend[7] = TAG_REQ_ADDR;
+ bp->bp_vend[8] = 4;
+ bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
+ bp->bp_vend[13] = TAG_SERVERID;
+ bp->bp_vend[14] = 4;
+ bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
+ bp->bp_vend[19] = TAG_LEASETIME;
+ bp->bp_vend[20] = 4;
+ leasetime = htonl(300);
+ bcopy(&leasetime, &bp->bp_vend[21], 4);
+ if (flag & BOOTP_PXE) {
+ bp->bp_vend[25] = TAG_CLASSID;
+ bp->bp_vend[26] = 9;
+ bcopy("PXEClient", &bp->bp_vend[27], 9);
+ bp->bp_vend[36] = TAG_END;
+ } else
+ bp->bp_vend[25] = TAG_END;
+
+ expected_dhcpmsgtype = DHCPACK;
+
+ if(sendrecv(d,
+ bootpsend, bp, sizeof(*bp),
+ bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
+ == -1) {
+ printf("DHCPREQUEST failed\n");
+ return;
+ }
+ }
+#endif
+
+ myip = d->myip = rbuf.rbootp.bp_yiaddr;
+ servip = rbuf.rbootp.bp_siaddr;
+ if(rootip.s_addr == INADDR_ANY) rootip = servip;
+ bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
+ bootfile[sizeof(bootfile) - 1] = '\0';
+
+ if (IN_CLASSA(ntohl(myip.s_addr)))
+ nmask = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(ntohl(myip.s_addr)))
+ nmask = htonl(IN_CLASSB_NET);
+ else
+ nmask = htonl(IN_CLASSC_NET);
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("'native netmask' is %s\n", intoa(nmask));
+#endif
+
+ /* Check subnet mask against net mask; toss if bogus */
+ if ((nmask & smask) != nmask) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("subnet mask (%s) bad\n", intoa(smask));
+#endif
+ smask = 0;
+ }
+
+ /* Get subnet (or natural net) mask */
+ netmask = nmask;
+ if (smask)
+ netmask = smask;
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("mask: %s\n", intoa(netmask));
+#endif
+
+ /* We need a gateway if root is on a different net */
+ if (!SAMENET(myip, rootip, netmask)) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("need gateway for root ip\n");
+#endif
+ }
+
+ /* Toss gateway if on a different net */
+ if (!SAMENET(myip, gateip, netmask)) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
+#endif
+ gateip.s_addr = 0;
+ }
+
+ /* Bump xid so next request will be unique. */
+ ++d->xid;
+}
+
+/* Transmit a bootp request */
+static ssize_t
+bootpsend(d, pkt, len)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+{
+ struct bootp *bp;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootpsend: d=%lx called.\n", (long)d);
+#endif
+
+ bp = pkt;
+ bp->bp_secs = htons((u_short)(getsecs() - bot));
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootpsend: calling sendudp\n");
+#endif
+
+ return (sendudp(d, pkt, len));
+}
+
+static ssize_t
+bootprecv(d, pkt, len, tleft)
+struct iodesc *d;
+void *pkt;
+size_t len;
+time_t tleft;
+{
+ ssize_t n;
+ struct bootp *bp;
+
+#ifdef BOOTP_DEBUGx
+ if (debug)
+ printf("bootp_recvoffer: called\n");
+#endif
+
+ n = readudp(d, pkt, len, tleft);
+ if (n == -1 || n < sizeof(struct bootp) - BOOTP_VENDSIZE)
+ goto bad;
+
+ bp = (struct bootp *)pkt;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootprecv: checked. bp = 0x%lx, n = %d\n",
+ (long)bp, (int)n);
+#endif
+ if (bp->bp_xid != htonl(d->xid)) {
+#ifdef BOOTP_DEBUG
+ if (debug) {
+ printf("bootprecv: expected xid 0x%lx, got 0x%x\n",
+ d->xid, ntohl(bp->bp_xid));
+ }
+#endif
+ goto bad;
+ }
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootprecv: got one!\n");
+#endif
+
+ /* Suck out vendor info */
+ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) {
+ if(vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0)
+ goto bad;
+ }
+#ifdef BOOTP_VEND_CMU
+ else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0)
+ vend_cmu(bp->bp_vend);
+#endif
+ else
+ printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend);
+
+ return(n);
+bad:
+ errno = 0;
+ return (-1);
+}
+
+static int
+vend_rfc1048(cp, len)
+ u_char *cp;
+ u_int len;
+{
+ u_char *ep;
+ int size;
+ u_char tag;
+ const char *val;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("vend_rfc1048 bootp info. len=%d\n", len);
+#endif
+ ep = cp + len;
+
+ /* Step over magic cookie */
+ cp += sizeof(int);
+
+ setenv_(cp, ep, NULL);
+
+ while (cp < ep) {
+ tag = *cp++;
+ size = *cp++;
+ if (tag == TAG_END)
+ break;
+
+ if (tag == TAG_SUBNET_MASK) {
+ bcopy(cp, &smask, sizeof(smask));
+ }
+ if (tag == TAG_GATEWAY) {
+ bcopy(cp, &gateip.s_addr, sizeof(gateip.s_addr));
+ }
+ if (tag == TAG_SWAPSERVER) {
+ /* let it override bp_siaddr */
+ bcopy(cp, &rootip.s_addr, sizeof(rootip.s_addr));
+ }
+ if (tag == TAG_ROOTPATH) {
+ if ((val = getenv("dhcp.root-path")) == NULL)
+ val = (const char *)cp;
+ strlcpy(rootpath, val, sizeof(rootpath));
+ }
+ if (tag == TAG_HOSTNAME) {
+ if ((val = getenv("dhcp.host-name")) == NULL)
+ val = (const char *)cp;
+ strlcpy(hostname, val, sizeof(hostname));
+ }
+#ifdef SUPPORT_DHCP
+ if (tag == TAG_DHCP_MSGTYPE) {
+ if(*cp != expected_dhcpmsgtype)
+ return(-1);
+ dhcp_ok = 1;
+ }
+ if (tag == TAG_SERVERID) {
+ bcopy(cp, &dhcp_serverip.s_addr,
+ sizeof(dhcp_serverip.s_addr));
+ }
+#endif
+ cp += size;
+ }
+ return(0);
+}
+
+#ifdef BOOTP_VEND_CMU
+static void
+vend_cmu(cp)
+ u_char *cp;
+{
+ struct cmu_vend *vp;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("vend_cmu bootp info.\n");
+#endif
+ vp = (struct cmu_vend *)cp;
+
+ if (vp->v_smask.s_addr != 0) {
+ smask = vp->v_smask.s_addr;
+ }
+ if (vp->v_dgate.s_addr != 0) {
+ gateip = vp->v_dgate;
+ }
+}
+#endif
+
+#ifdef DHCP_ENV
+/*
+ * Parse DHCP options and store them into kenv variables.
+ * Original code from Danny Braniss, modifications by Luigi Rizzo.
+ *
+ * The parser is driven by tables which specify the type and name of
+ * each dhcp option and how it appears in kenv.
+ * The first entry in the list contains the prefix used to set the kenv
+ * name (including the . if needed), the last entry must have a 0 tag.
+ * Entries do not need to be sorted though it helps for readability.
+ *
+ * Certain vendor-specific tables can be enabled according to DHCP_ENV.
+ * Set it to 0 if you don't want any.
+ */
+enum opt_fmt { __NONE = 0,
+ __8 = 1, __16 = 2, __32 = 4, /* Unsigned fields, value=size */
+ __IP, /* IPv4 address */
+ __TXT, /* C string */
+ __BYTES, /* byte sequence, printed %02x */
+ __INDIR, /* name=value */
+ __ILIST, /* name=value;name=value ... */
+ __VE, /* vendor specific, recurse */
+};
+
+struct dhcp_opt {
+ uint8_t tag;
+ uint8_t fmt;
+ const char *desc;
+};
+
+static struct dhcp_opt vndr_opt[] = { /* Vendor Specific Options */
+#if DHCP_ENV == DHCP_ENV_FREEBSD /* FreeBSD table in the original code */
+ {0, 0, "FreeBSD"}, /* prefix */
+ {1, __TXT, "kernel"},
+ {2, __TXT, "kernelname"},
+ {3, __TXT, "kernel_options"},
+ {4, __IP, "usr-ip"},
+ {5, __TXT, "conf-path"},
+ {6, __TXT, "rc.conf0"},
+ {7, __TXT, "rc.conf1"},
+ {8, __TXT, "rc.conf2"},
+ {9, __TXT, "rc.conf3"},
+ {10, __TXT, "rc.conf4"},
+ {11, __TXT, "rc.conf5"},
+ {12, __TXT, "rc.conf6"},
+ {13, __TXT, "rc.conf7"},
+ {14, __TXT, "rc.conf8"},
+ {15, __TXT, "rc.conf9"},
+
+ {20, __TXT, "boot.nfsroot.options"},
+
+ {245, __INDIR, ""},
+ {246, __INDIR, ""},
+ {247, __INDIR, ""},
+ {248, __INDIR, ""},
+ {249, __INDIR, ""},
+ {250, __INDIR, ""},
+ {251, __INDIR, ""},
+ {252, __INDIR, ""},
+ {253, __INDIR, ""},
+ {254, __INDIR, ""},
+
+#elif DHCP_ENV == DHCP_ENV_PXE /* some pxe options, RFC4578 */
+ {0, 0, "pxe"}, /* prefix */
+ {93, __16, "system-architecture"},
+ {94, __BYTES, "network-interface"},
+ {97, __BYTES, "machine-identifier"},
+#else /* default (empty) table */
+ {0, 0, "dhcp.vendor."}, /* prefix */
+#endif
+ {0, __TXT, "%soption-%d"}
+};
+
+static struct dhcp_opt dhcp_opt[] = {
+ /* DHCP Option names, formats and codes, from RFC2132. */
+ {0, 0, "dhcp."}, // prefix
+ {1, __IP, "subnet-mask"},
+ {2, __32, "time-offset"}, /* this is signed */
+ {3, __IP, "routers"},
+ {4, __IP, "time-servers"},
+ {5, __IP, "ien116-name-servers"},
+ {6, __IP, "domain-name-servers"},
+ {7, __IP, "log-servers"},
+ {8, __IP, "cookie-servers"},
+ {9, __IP, "lpr-servers"},
+ {10, __IP, "impress-servers"},
+ {11, __IP, "resource-location-servers"},
+ {12, __TXT, "host-name"},
+ {13, __16, "boot-size"},
+ {14, __TXT, "merit-dump"},
+ {15, __TXT, "domain-name"},
+ {16, __IP, "swap-server"},
+ {17, __TXT, "root-path"},
+ {18, __TXT, "extensions-path"},
+ {19, __8, "ip-forwarding"},
+ {20, __8, "non-local-source-routing"},
+ {21, __IP, "policy-filter"},
+ {22, __16, "max-dgram-reassembly"},
+ {23, __8, "default-ip-ttl"},
+ {24, __32, "path-mtu-aging-timeout"},
+ {25, __16, "path-mtu-plateau-table"},
+ {26, __16, "interface-mtu"},
+ {27, __8, "all-subnets-local"},
+ {28, __IP, "broadcast-address"},
+ {29, __8, "perform-mask-discovery"},
+ {30, __8, "mask-supplier"},
+ {31, __8, "perform-router-discovery"},
+ {32, __IP, "router-solicitation-address"},
+ {33, __IP, "static-routes"},
+ {34, __8, "trailer-encapsulation"},
+ {35, __32, "arp-cache-timeout"},
+ {36, __8, "ieee802-3-encapsulation"},
+ {37, __8, "default-tcp-ttl"},
+ {38, __32, "tcp-keepalive-interval"},
+ {39, __8, "tcp-keepalive-garbage"},
+ {40, __TXT, "nis-domain"},
+ {41, __IP, "nis-servers"},
+ {42, __IP, "ntp-servers"},
+ {43, __VE, "vendor-encapsulated-options"},
+ {44, __IP, "netbios-name-servers"},
+ {45, __IP, "netbios-dd-server"},
+ {46, __8, "netbios-node-type"},
+ {47, __TXT, "netbios-scope"},
+ {48, __IP, "x-font-servers"},
+ {49, __IP, "x-display-managers"},
+ {50, __IP, "dhcp-requested-address"},
+ {51, __32, "dhcp-lease-time"},
+ {52, __8, "dhcp-option-overload"},
+ {53, __8, "dhcp-message-type"},
+ {54, __IP, "dhcp-server-identifier"},
+ {55, __8, "dhcp-parameter-request-list"},
+ {56, __TXT, "dhcp-message"},
+ {57, __16, "dhcp-max-message-size"},
+ {58, __32, "dhcp-renewal-time"},
+ {59, __32, "dhcp-rebinding-time"},
+ {60, __TXT, "vendor-class-identifier"},
+ {61, __TXT, "dhcp-client-identifier"},
+ {64, __TXT, "nisplus-domain"},
+ {65, __IP, "nisplus-servers"},
+ {66, __TXT, "tftp-server-name"},
+ {67, __TXT, "bootfile-name"},
+ {68, __IP, "mobile-ip-home-agent"},
+ {69, __IP, "smtp-server"},
+ {70, __IP, "pop-server"},
+ {71, __IP, "nntp-server"},
+ {72, __IP, "www-server"},
+ {73, __IP, "finger-server"},
+ {74, __IP, "irc-server"},
+ {75, __IP, "streettalk-server"},
+ {76, __IP, "streettalk-directory-assistance-server"},
+ {77, __TXT, "user-class"},
+ {85, __IP, "nds-servers"},
+ {86, __TXT, "nds-tree-name"},
+ {87, __TXT, "nds-context"},
+ {210, __TXT, "authenticate"},
+
+ /* use the following entries for arbitrary variables */
+ {246, __ILIST, ""},
+ {247, __ILIST, ""},
+ {248, __ILIST, ""},
+ {249, __ILIST, ""},
+ {250, __INDIR, ""},
+ {251, __INDIR, ""},
+ {252, __INDIR, ""},
+ {253, __INDIR, ""},
+ {254, __INDIR, ""},
+ {0, __TXT, "%soption-%d"}
+};
+
+/*
+ * parse a dhcp response, set environment variables translating options
+ * names and values according to the tables above. Also set dhcp.tags
+ * to the list of selected tags.
+ */
+static void
+setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts)
+{
+ u_char *ncp;
+ u_char tag;
+ char tags[512], *tp; /* the list of tags */
+
+#define FLD_SEP ',' /* separator in list of elements */
+ ncp = cp;
+ tp = tags;
+ if (opts == NULL)
+ opts = dhcp_opt;
+
+ while (ncp < ep) {
+ unsigned int size; /* option size */
+ char *vp, *endv, buf[256]; /* the value buffer */
+ struct dhcp_opt *op;
+
+ tag = *ncp++; /* extract tag and size */
+ size = *ncp++;
+ cp = ncp; /* current payload */
+ ncp += size; /* point to the next option */
+
+ if (tag == TAG_END)
+ break;
+ if (tag == 0)
+ continue;
+
+ for (op = opts+1; op->tag && op->tag != tag; op++)
+ ;
+ /* if not found we end up on the default entry */
+
+ /*
+ * Copy data into the buffer. libstand does not have snprintf so we
+ * need to be careful with sprintf(). With strings, the source is
+ * always <256 char so shorter than the buffer so we are safe; with
+ * other arguments, the longest string is inet_ntoa which is 16 bytes
+ * so we make sure to have always enough room in the string before
+ * trying an sprint.
+ */
+ vp = buf;
+ *vp = '\0';
+ endv = buf + sizeof(buf) - 1 - 16; /* last valid write position */
+
+ switch(op->fmt) {
+ case __NONE:
+ break; /* should not happen */
+
+ case __VE: /* recurse, vendor specific */
+ setenv_(cp, cp+size, vndr_opt);
+ break;
+
+ case __IP: /* ip address */
+ for (; size > 0 && vp < endv; size -= 4, cp += 4) {
+ struct in_addr in_ip; /* ip addresses */
+ if (vp != buf)
+ *vp++ = FLD_SEP;
+ bcopy(cp, &in_ip.s_addr, sizeof(in_ip.s_addr));
+ sprintf(vp, "%s", inet_ntoa(in_ip));
+ vp += strlen(vp);
+ }
+ break;
+
+ case __BYTES: /* opaque byte string */
+ for (; size > 0 && vp < endv; size -= 1, cp += 1) {
+ sprintf(vp, "%02x", *cp);
+ vp += strlen(vp);
+ }
+ break;
+
+ case __TXT:
+ bcopy(cp, buf, size); /* cannot overflow */
+ buf[size] = 0;
+ break;
+
+ case __32:
+ case __16:
+ case __8: /* op->fmt is also the length of each field */
+ for (; size > 0 && vp < endv; size -= op->fmt, cp += op->fmt) {
+ uint32_t v;
+ if (op->fmt == __32)
+ v = (cp[0]<<24) + (cp[1]<<16) + (cp[2]<<8) + cp[3];
+ else if (op->fmt == __16)
+ v = (cp[0]<<8) + cp[1];
+ else
+ v = cp[0];
+ if (vp != buf)
+ *vp++ = FLD_SEP;
+ sprintf(vp, "%u", v);
+ vp += strlen(vp);
+ }
+ break;
+
+ case __INDIR: /* name=value */
+ case __ILIST: /* name=value;name=value... */
+ bcopy(cp, buf, size); /* cannot overflow */
+ buf[size] = '\0';
+ for (endv = buf; endv; endv = vp) {
+ u_char *s = NULL; /* semicolon ? */
+
+ /* skip leading whitespace */
+ while (*endv && strchr(" \t\n\r", *endv))
+ endv++;
+ vp = strchr(endv, '='); /* find name=value separator */
+ if (!vp)
+ break;
+ *vp++ = 0;
+ if (op->fmt == __ILIST && (s = strchr(vp, ';')))
+ *s++ = '\0';
+ setenv(endv, vp, 1);
+ vp = s; /* prepare for next round */
+ }
+ buf[0] = '\0'; /* option already done */
+ }
+
+ if (tp - tags < sizeof(tags) - 5) { /* add tag to the list */
+ if (tp != tags)
+ *tp++ = FLD_SEP;
+ sprintf(tp, "%d", tag);
+ tp += strlen(tp);
+ }
+ if (buf[0]) {
+ char env[128]; /* the string name */
+
+ if (op->tag == 0)
+ sprintf(env, op->desc, opts[0].desc, tag);
+ else
+ sprintf(env, "%s%s", opts[0].desc, op->desc);
+ /*
+ * Do not replace existing values in the environment, so that
+ * locally-obtained values can override server-provided values.
+ */
+ setenv(env, buf, 0);
+ }
+ }
+ if (tp != tags) {
+ char env[128]; /* the string name */
+ sprintf(env, "%stags", opts[0].desc);
+ setenv(env, tags, 1);
+ }
+}
+#endif /* additional dhcp */
diff --git a/usr/src/boot/lib/libstand/bootp.h b/usr/src/boot/lib/libstand/bootp.h
new file mode 100644
index 0000000000..ed9101f3ea
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bootp.h
@@ -0,0 +1,145 @@
+/* $NetBSD: bootp.h,v 1.4 1997/09/06 13:55:57 drochner Exp $ */
+
+/*
+ * Bootstrap Protocol (BOOTP). RFC951 and RFC1048.
+ *
+ * This file specifies the "implementation-independent" BOOTP protocol
+ * information which is common to both client and server.
+ *
+ * Copyright 1988 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * $FreeBSD$
+ */
+
+
+struct bootp {
+ unsigned char bp_op; /* packet opcode type */
+ unsigned char bp_htype; /* hardware addr type */
+ unsigned char bp_hlen; /* hardware addr length */
+ unsigned char bp_hops; /* gateway hops */
+ unsigned int bp_xid; /* transaction ID */
+ unsigned short bp_secs; /* seconds since boot began */
+ unsigned short bp_flags;
+ struct in_addr bp_ciaddr; /* client IP address */
+ struct in_addr bp_yiaddr; /* 'your' IP address */
+ struct in_addr bp_siaddr; /* server IP address */
+ struct in_addr bp_giaddr; /* gateway IP address */
+ unsigned char bp_chaddr[16]; /* client hardware address */
+ unsigned char bp_sname[64]; /* server host name */
+ unsigned char bp_file[128]; /* boot file name */
+#ifdef SUPPORT_DHCP
+#define BOOTP_VENDSIZE 312
+#else
+#define BOOTP_VENDSIZE 64
+#endif
+ unsigned char bp_vend[BOOTP_VENDSIZE]; /* vendor-specific area */
+};
+
+/*
+ * UDP port numbers, server and client.
+ */
+#define IPPORT_BOOTPS 67
+#define IPPORT_BOOTPC 68
+
+#define BOOTREPLY 2
+#define BOOTREQUEST 1
+
+
+/*
+ * Vendor magic cookie (v_magic) for CMU
+ */
+#define VM_CMU "CMU"
+
+/*
+ * Vendor magic cookie (v_magic) for RFC1048
+ */
+#define VM_RFC1048 { 99, 130, 83, 99 }
+
+
+
+/*
+ * RFC1048 tag values used to specify what information is being supplied in
+ * the vendor field of the packet.
+ */
+
+#define TAG_PAD ((unsigned char) 0)
+#define TAG_SUBNET_MASK ((unsigned char) 1)
+#define TAG_TIME_OFFSET ((unsigned char) 2)
+#define TAG_GATEWAY ((unsigned char) 3)
+#define TAG_TIME_SERVER ((unsigned char) 4)
+#define TAG_NAME_SERVER ((unsigned char) 5)
+#define TAG_DOMAIN_SERVER ((unsigned char) 6)
+#define TAG_LOG_SERVER ((unsigned char) 7)
+#define TAG_COOKIE_SERVER ((unsigned char) 8)
+#define TAG_LPR_SERVER ((unsigned char) 9)
+#define TAG_IMPRESS_SERVER ((unsigned char) 10)
+#define TAG_RLP_SERVER ((unsigned char) 11)
+#define TAG_HOSTNAME ((unsigned char) 12)
+#define TAG_BOOTSIZE ((unsigned char) 13)
+#define TAG_DUMPFILE ((unsigned char) 14)
+#define TAG_DOMAINNAME ((unsigned char) 15)
+#define TAG_SWAPSERVER ((unsigned char) 16)
+#define TAG_ROOTPATH ((unsigned char) 17)
+
+#ifdef SUPPORT_DHCP
+#define TAG_REQ_ADDR ((unsigned char) 50)
+#define TAG_LEASETIME ((unsigned char) 51)
+#define TAG_OVERLOAD ((unsigned char) 52)
+#define TAG_DHCP_MSGTYPE ((unsigned char) 53)
+#define TAG_SERVERID ((unsigned char) 54)
+#define TAG_PARAM_REQ ((unsigned char) 55)
+#define TAG_MSG ((unsigned char) 56)
+#define TAG_MAXSIZE ((unsigned char) 57)
+#define TAG_T1 ((unsigned char) 58)
+#define TAG_T2 ((unsigned char) 59)
+#define TAG_CLASSID ((unsigned char) 60)
+#define TAG_CLIENTID ((unsigned char) 61)
+#endif
+
+#define TAG_END ((unsigned char) 255)
+
+#ifdef SUPPORT_DHCP
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+#endif
+
+/*
+ * bootp flags
+ */
+#define BOOTP_NONE 0x0000 /* No flags */
+#define BOOTP_PXE 0x0001 /* Booting from PXE. */
+
+/*
+ * "vendor" data permitted for CMU bootp clients.
+ */
+
+struct cmu_vend {
+ unsigned char v_magic[4]; /* magic number */
+ unsigned int v_flags; /* flags/opcodes, etc. */
+ struct in_addr v_smask; /* Subnet mask */
+ struct in_addr v_dgate; /* Default gateway */
+ struct in_addr v_dns1, v_dns2; /* Domain name servers */
+ struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
+ struct in_addr v_ts1, v_ts2; /* Time servers */
+ unsigned char v_unused[25]; /* currently unused */
+};
+
+
+/* v_flags values */
+#define VF_SMASK 1 /* Subnet mask field contains valid data */
diff --git a/usr/src/boot/lib/libstand/bootparam.c b/usr/src/boot/lib/libstand/bootparam.c
new file mode 100644
index 0000000000..e4d2f1022c
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bootparam.c
@@ -0,0 +1,452 @@
+/* $NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * RPC/bootparams
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "rpcv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+#include "bootparam.h"
+
+#ifdef DEBUG_RPC
+#define RPC_PRINTF(a) printf a
+#else
+#define RPC_PRINTF(a)
+#endif
+
+struct in_addr bp_server_addr; /* net order */
+n_short bp_server_port; /* net order */
+
+/*
+ * RPC definitions for bootparamd
+ */
+#define BOOTPARAM_PROG 100026
+#define BOOTPARAM_VERS 1
+#define BOOTPARAM_WHOAMI 1
+#define BOOTPARAM_GETFILE 2
+
+/*
+ * Inet address in RPC messages
+ * (Note, really four ints, NOT chars. Blech.)
+ */
+struct xdr_inaddr {
+ u_int32_t atype;
+ int32_t addr[4];
+};
+
+int xdr_inaddr_encode(char **p, struct in_addr ia);
+int xdr_inaddr_decode(char **p, struct in_addr *ia);
+
+int xdr_string_encode(char **p, char *str, int len);
+int xdr_string_decode(char **p, char *str, int *len_p);
+
+
+/*
+ * RPC: bootparam/whoami
+ * Given client IP address, get:
+ * client name (hostname)
+ * domain name (domainname)
+ * gateway address
+ *
+ * The hostname and domainname are set here for convenience.
+ *
+ * Note - bpsin is initialized to the broadcast address,
+ * and will be replaced with the bootparam server address
+ * after this call is complete. Have to use PMAP_PROC_CALL
+ * to make sure we get responses only from a servers that
+ * know about us (don't want to broadcast a getport call).
+ */
+int
+bp_whoami(sockfd)
+ int sockfd;
+{
+ /* RPC structures for PMAPPROC_CALLIT */
+ struct args {
+ u_int32_t prog;
+ u_int32_t vers;
+ u_int32_t proc;
+ u_int32_t arglen;
+ struct xdr_inaddr xina;
+ } *args;
+ struct repl {
+ u_int16_t _pad;
+ u_int16_t port;
+ u_int32_t encap_len;
+ /* encapsulated data here */
+ n_long capsule[64];
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ char *send_tail, *recv_head;
+ struct iodesc *d;
+ int len, x;
+
+ RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
+
+ if (!(d = socktodesc(sockfd))) {
+ RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
+ return (-1);
+ }
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ /*
+ * Build request args for PMAPPROC_CALLIT.
+ */
+ args->prog = htonl(BOOTPARAM_PROG);
+ args->vers = htonl(BOOTPARAM_VERS);
+ args->proc = htonl(BOOTPARAM_WHOAMI);
+ args->arglen = htonl(sizeof(struct xdr_inaddr));
+ send_tail = (char*) &args->xina;
+
+ /*
+ * append encapsulated data (client IP address)
+ */
+ if (xdr_inaddr_encode(&send_tail, myip))
+ return (-1);
+
+ /* RPC: portmap/callit */
+ d->myport = htons(--rpc_port);
+ d->destip.s_addr = INADDR_BROADCAST; /* XXX: subnet bcast? */
+ /* rpc_call will set d->destport */
+
+ len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
+ args, send_tail - (char*)args,
+ repl, sizeof(*repl));
+ if (len < 8) {
+ printf("bootparamd: 'whoami' call failed\n");
+ return (-1);
+ }
+
+ /* Save bootparam server address (from IP header). */
+ rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
+
+ /*
+ * Note that bp_server_port is now 111 due to the
+ * indirect call (using PMAPPROC_CALLIT), so get the
+ * actual port number from the reply data.
+ */
+ bp_server_port = repl->port;
+
+ RPC_PRINTF(("bp_whoami: server at %s:%d\n",
+ inet_ntoa(bp_server_addr), ntohs(bp_server_port)));
+
+ /* We have just done a portmap call, so cache the portnum. */
+ rpc_pmap_putcache(bp_server_addr,
+ BOOTPARAM_PROG,
+ BOOTPARAM_VERS,
+ (int)ntohs(bp_server_port));
+
+ /*
+ * Parse the encapsulated results from bootparam/whoami
+ */
+ x = ntohl(repl->encap_len);
+ if (len < x) {
+ printf("bp_whoami: short reply, %d < %d\n", len, x);
+ return (-1);
+ }
+ recv_head = (char*) repl->capsule;
+
+ /* client name */
+ hostnamelen = MAXHOSTNAMELEN-1;
+ if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
+ RPC_PRINTF(("bp_whoami: bad hostname\n"));
+ return (-1);
+ }
+
+ /* domain name */
+ domainnamelen = MAXHOSTNAMELEN-1;
+ if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
+ RPC_PRINTF(("bp_whoami: bad domainname\n"));
+ return (-1);
+ }
+
+ /* gateway address */
+ if (xdr_inaddr_decode(&recv_head, &gateip)) {
+ RPC_PRINTF(("bp_whoami: bad gateway\n"));
+ return (-1);
+ }
+
+ /* success */
+ return(0);
+}
+
+
+/*
+ * RPC: bootparam/getfile
+ * Given client name and file "key", get:
+ * server name
+ * server IP address
+ * server pathname
+ */
+int
+bp_getfile(sockfd, key, serv_addr, pathname)
+ int sockfd;
+ char *key;
+ char *pathname;
+ struct in_addr *serv_addr;
+{
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ n_long d[64];
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ n_long d[128];
+ } rdata;
+ char serv_name[FNAME_SIZE];
+ char *send_tail, *recv_head;
+ /* misc... */
+ struct iodesc *d;
+ int sn_len, path_len, rlen;
+
+ if (!(d = socktodesc(sockfd))) {
+ RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
+ return (-1);
+ }
+
+ send_tail = (char*) sdata.d;
+ recv_head = (char*) rdata.d;
+
+ /*
+ * Build request message.
+ */
+
+ /* client name (hostname) */
+ if (xdr_string_encode(&send_tail, hostname, hostnamelen)) {
+ RPC_PRINTF(("bp_getfile: bad client\n"));
+ return (-1);
+ }
+
+ /* key name (root or swap) */
+ if (xdr_string_encode(&send_tail, key, strlen(key))) {
+ RPC_PRINTF(("bp_getfile: bad key\n"));
+ return (-1);
+ }
+
+ /* RPC: bootparam/getfile */
+ d->myport = htons(--rpc_port);
+ d->destip = bp_server_addr;
+ /* rpc_call will set d->destport */
+
+ rlen = rpc_call(d,
+ BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
+ sdata.d, send_tail - (char*)sdata.d,
+ rdata.d, sizeof(rdata.d));
+ if (rlen < 4) {
+ RPC_PRINTF(("bp_getfile: short reply\n"));
+ errno = EBADRPC;
+ return (-1);
+ }
+ recv_head = (char*) rdata.d;
+
+ /*
+ * Parse result message.
+ */
+
+ /* server name */
+ sn_len = FNAME_SIZE-1;
+ if (xdr_string_decode(&recv_head, serv_name, &sn_len)) {
+ RPC_PRINTF(("bp_getfile: bad server name\n"));
+ return (-1);
+ }
+
+ /* server IP address (mountd/NFS) */
+ if (xdr_inaddr_decode(&recv_head, serv_addr)) {
+ RPC_PRINTF(("bp_getfile: bad server addr\n"));
+ return (-1);
+ }
+
+ /* server pathname */
+ path_len = MAXPATHLEN-1;
+ if (xdr_string_decode(&recv_head, pathname, &path_len)) {
+ RPC_PRINTF(("bp_getfile: bad server path\n"));
+ return (-1);
+ }
+
+ /* success */
+ return(0);
+}
+
+
+/*
+ * eXternal Data Representation routines.
+ * (but with non-standard args...)
+ */
+
+
+int
+xdr_string_encode(pkt, str, len)
+ char **pkt;
+ char *str;
+ int len;
+{
+ u_int32_t *lenp;
+ char *datap;
+ int padlen = (len + 3) & ~3; /* padded length */
+
+ /* The data will be int aligned. */
+ lenp = (u_int32_t*) *pkt;
+ *pkt += sizeof(*lenp);
+ *lenp = htonl(len);
+
+ datap = *pkt;
+ *pkt += padlen;
+ bcopy(str, datap, len);
+
+ return (0);
+}
+
+int
+xdr_string_decode(pkt, str, len_p)
+ char **pkt;
+ char *str;
+ int *len_p; /* bufsize - 1 */
+{
+ u_int32_t *lenp;
+ char *datap;
+ int slen; /* string length */
+ int plen; /* padded length */
+
+ /* The data will be int aligned. */
+ lenp = (u_int32_t*) *pkt;
+ *pkt += sizeof(*lenp);
+ slen = ntohl(*lenp);
+ plen = (slen + 3) & ~3;
+
+ if (slen > *len_p)
+ slen = *len_p;
+ datap = *pkt;
+ *pkt += plen;
+ bcopy(datap, str, slen);
+
+ str[slen] = '\0';
+ *len_p = slen;
+
+ return (0);
+}
+
+
+int
+xdr_inaddr_encode(pkt, ia)
+ char **pkt;
+ struct in_addr ia; /* network order */
+{
+ struct xdr_inaddr *xi;
+ u_char *cp;
+ int32_t *ip;
+ union {
+ n_long l; /* network order */
+ u_char c[4];
+ } uia;
+
+ /* The data will be int aligned. */
+ xi = (struct xdr_inaddr *) *pkt;
+ *pkt += sizeof(*xi);
+ xi->atype = htonl(1);
+ uia.l = ia.s_addr;
+ cp = uia.c;
+ ip = xi->addr;
+ /*
+ * Note: the htonl() calls below DO NOT
+ * imply that uia.l is in host order.
+ * In fact this needs it in net order.
+ */
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+
+ return (0);
+}
+
+int
+xdr_inaddr_decode(pkt, ia)
+ char **pkt;
+ struct in_addr *ia; /* network order */
+{
+ struct xdr_inaddr *xi;
+ u_char *cp;
+ int32_t *ip;
+ union {
+ n_long l; /* network order */
+ u_char c[4];
+ } uia;
+
+ /* The data will be int aligned. */
+ xi = (struct xdr_inaddr *) *pkt;
+ *pkt += sizeof(*xi);
+ if (xi->atype != htonl(1)) {
+ RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n",
+ ntohl(xi->atype)));
+ return(-1);
+ }
+
+ cp = uia.c;
+ ip = xi->addr;
+ /*
+ * Note: the ntohl() calls below DO NOT
+ * imply that uia.l is in host order.
+ * In fact this needs it in net order.
+ */
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ ia->s_addr = uia.l;
+
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/bootparam.h b/usr/src/boot/lib/libstand/bootparam.h
new file mode 100644
index 0000000000..6f0c773a07
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bootparam.h
@@ -0,0 +1,5 @@
+/* $NetBSD: bootparam.h,v 1.3 1998/01/05 19:19:41 perry Exp $ */
+
+int bp_whoami(int sock);
+int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path);
+
diff --git a/usr/src/boot/lib/libstand/bswap.c b/usr/src/boot/lib/libstand/bswap.c
new file mode 100644
index 0000000000..308edda630
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bswap.c
@@ -0,0 +1,57 @@
+/*
+ * Written by Manuel Bouyer <bouyer@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$NetBSD: bswap32.c,v 1.1 1997/10/09 15:42:33 bouyer Exp $";
+static char *rcsid = "$NetBSD: bswap64.c,v 1.3 2009/03/16 05:59:21 cegger Exp $";
+#endif
+
+#include <sys/types.h>
+
+#undef bswap32
+#undef bswap64
+
+u_int32_t bswap32(u_int32_t x);
+u_int64_t bswap64(u_int64_t x);
+
+u_int32_t
+bswap32(u_int32_t x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+
+u_int64_t
+bswap64(u_int64_t x)
+{
+#ifdef __LP64__
+ /*
+ * Assume we have wide enough registers to do it without touching
+ * memory.
+ */
+ return ( (x << 56) & 0xff00000000000000UL ) |
+ ( (x << 40) & 0x00ff000000000000UL ) |
+ ( (x << 24) & 0x0000ff0000000000UL ) |
+ ( (x << 8) & 0x000000ff00000000UL ) |
+ ( (x >> 8) & 0x00000000ff000000UL ) |
+ ( (x >> 24) & 0x0000000000ff0000UL ) |
+ ( (x >> 40) & 0x000000000000ff00UL ) |
+ ( (x >> 56) & 0x00000000000000ffUL );
+#else
+ /*
+ * Split the operation in two 32bit steps.
+ */
+ u_int32_t tl, th;
+
+ th = bswap32((u_int32_t)(x & 0x00000000ffffffffULL));
+ tl = bswap32((u_int32_t)((x >> 32) & 0x00000000ffffffffULL));
+ return ((u_int64_t)th << 32) | tl;
+#endif
+}
diff --git a/usr/src/boot/lib/libstand/bzipfs.c b/usr/src/boot/lib/libstand/bzipfs.c
new file mode 100644
index 0000000000..b0176080da
--- /dev/null
+++ b/usr/src/boot/lib/libstand/bzipfs.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * Copyright (c) 2000 Maxim Sobolev
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef REGRESSION
+#include "stand.h"
+#else
+#include <stdlib.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/unistd.h>
+
+struct open_file {
+ int f_flags; /* see F_* below */
+ void *f_fsdata; /* file system specific data */
+};
+#define F_READ 0x0001 /* file opened for reading */
+#define EOFFSET (ELAST+8) /* relative seek not supported */
+static inline u_int min(u_int a, u_int b) { return(a < b ? a : b); }
+#define panic(x, y) abort()
+#endif
+
+#include <sys/stat.h>
+#include <string.h>
+#include <bzlib.h>
+
+#define BZ_BUFSIZE 2048 /* XXX larger? */
+
+struct bz_file
+{
+ int bzf_rawfd;
+ bz_stream bzf_bzstream;
+ char bzf_buf[BZ_BUFSIZE];
+ int bzf_endseen;
+};
+
+static int bzf_fill(struct bz_file *z);
+static int bzf_open(const char *path, struct open_file *f);
+static int bzf_close(struct open_file *f);
+static int bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t bzf_seek(struct open_file *f, off_t offset, int where);
+static int bzf_stat(struct open_file *f, struct stat *sb);
+
+#ifndef REGRESSION
+struct fs_ops bzipfs_fsops = {
+ "bzip",
+ bzf_open,
+ bzf_close,
+ bzf_read,
+ null_write,
+ bzf_seek,
+ bzf_stat,
+ null_readdir
+};
+#endif
+
+static int
+bzf_fill(struct bz_file *bzf)
+{
+ int result;
+ int req;
+
+ req = BZ_BUFSIZE - bzf->bzf_bzstream.avail_in;
+ result = 0;
+
+ /* If we need more */
+ if (req > 0) {
+ /* move old data to bottom of buffer */
+ if (req < BZ_BUFSIZE)
+ bcopy(bzf->bzf_buf + req, bzf->bzf_buf, BZ_BUFSIZE - req);
+
+ /* read to fill buffer and update availibility data */
+ result = read(bzf->bzf_rawfd, bzf->bzf_buf + bzf->bzf_bzstream.avail_in, req);
+ bzf->bzf_bzstream.next_in = bzf->bzf_buf;
+ if (result >= 0)
+ bzf->bzf_bzstream.avail_in += result;
+ }
+ return(result);
+}
+
+/*
+ * Adapted from get_byte/check_header in libz
+ *
+ * Returns 0 if the header is OK, nonzero if not.
+ */
+static int
+get_byte(struct bz_file *bzf)
+{
+ if ((bzf->bzf_bzstream.avail_in == 0) && (bzf_fill(bzf) == -1))
+ return(-1);
+ bzf->bzf_bzstream.avail_in--;
+ return(*(bzf->bzf_bzstream.next_in)++);
+}
+
+static int bz_magic[3] = {'B', 'Z', 'h'}; /* bzip2 magic header */
+
+static int
+check_header(struct bz_file *bzf)
+{
+ unsigned int len;
+ int c;
+
+ /* Check the bzip2 magic header */
+ for (len = 0; len < 3; len++) {
+ c = get_byte(bzf);
+ if (c != bz_magic[len]) {
+ return(1);
+ }
+ }
+ /* Check that the block size is valid */
+ c = get_byte(bzf);
+ if (c < '1' || c > '9')
+ return(1);
+
+ /* Put back bytes that we've took from the input stream */
+ bzf->bzf_bzstream.next_in -= 4;
+ bzf->bzf_bzstream.avail_in += 4;
+
+ return(0);
+}
+
+static int
+bzf_open(const char *fname, struct open_file *f)
+{
+ static char *bzfname;
+ int rawfd;
+ struct bz_file *bzf;
+ char *cp;
+ int error;
+ struct stat sb;
+
+ /* Have to be in "just read it" mode */
+ if (f->f_flags != F_READ)
+ return(EPERM);
+
+ /* If the name already ends in .gz or .bz2, ignore it */
+ if ((cp = strrchr(fname, '.')) && (!strcmp(cp, ".gz")
+ || !strcmp(cp, ".bz2") || !strcmp(cp, ".split")))
+ return(ENOENT);
+
+ /* Construct new name */
+ bzfname = malloc(strlen(fname) + 5);
+ if (bzfname == NULL)
+ return(ENOMEM);
+ sprintf(bzfname, "%s.bz2", fname);
+
+ /* Try to open the compressed datafile */
+ rawfd = open(bzfname, O_RDONLY);
+ free(bzfname);
+ if (rawfd == -1)
+ return(ENOENT);
+
+ if (fstat(rawfd, &sb) < 0) {
+ printf("bzf_open: stat failed\n");
+ close(rawfd);
+ return(ENOENT);
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ printf("bzf_open: not a file\n");
+ close(rawfd);
+ return(EISDIR); /* best guess */
+ }
+
+ /* Allocate a bz_file structure, populate it */
+ bzf = malloc(sizeof(struct bz_file));
+ if (bzf == NULL)
+ return(ENOMEM);
+ bzero(bzf, sizeof(struct bz_file));
+ bzf->bzf_rawfd = rawfd;
+
+ /* Verify that the file is bzipped */
+ if (check_header(bzf)) {
+ close(bzf->bzf_rawfd);
+ free(bzf);
+ return(EFTYPE);
+ }
+
+ /* Initialise the inflation engine */
+ if ((error = BZ2_bzDecompressInit(&(bzf->bzf_bzstream), 0, 1)) != BZ_OK) {
+ printf("bzf_open: BZ2_bzDecompressInit returned %d\n", error);
+ close(bzf->bzf_rawfd);
+ free(bzf);
+ return(EIO);
+ }
+
+ /* Looks OK, we'll take it */
+ f->f_fsdata = bzf;
+ return(0);
+}
+
+static int
+bzf_close(struct open_file *f)
+{
+ struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
+
+ BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
+ close(bzf->bzf_rawfd);
+ free(bzf);
+ return(0);
+}
+
+static int
+bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
+ int error;
+
+ bzf->bzf_bzstream.next_out = buf; /* where and how much */
+ bzf->bzf_bzstream.avail_out = size;
+
+ while (bzf->bzf_bzstream.avail_out && bzf->bzf_endseen == 0) {
+ if ((bzf->bzf_bzstream.avail_in == 0) && (bzf_fill(bzf) == -1)) {
+ printf("bzf_read: fill error\n");
+ return(EIO);
+ }
+ if (bzf->bzf_bzstream.avail_in == 0) { /* oops, unexpected EOF */
+ printf("bzf_read: unexpected EOF\n");
+ if (bzf->bzf_bzstream.avail_out == size)
+ return(EIO);
+ break;
+ }
+
+ error = BZ2_bzDecompress(&bzf->bzf_bzstream); /* decompression pass */
+ if (error == BZ_STREAM_END) { /* EOF, all done */
+ bzf->bzf_endseen = 1;
+ break;
+ }
+ if (error != BZ_OK) { /* argh, decompression error */
+ printf("bzf_read: BZ2_bzDecompress returned %d\n", error);
+ return(EIO);
+ }
+ }
+ if (resid != NULL)
+ *resid = bzf->bzf_bzstream.avail_out;
+ return(0);
+}
+
+static int
+bzf_rewind(struct open_file *f)
+{
+ struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
+ struct bz_file *bzf_tmp;
+
+ /*
+ * Since bzip2 does not have an equivalent inflateReset function a crude
+ * one needs to be provided. The functions all called in such a way that
+ * at any time an error occurs a roll back can be done (effectively making
+ * this rewind 'atomic', either the reset occurs successfully or not at all,
+ * with no 'undefined' state happening).
+ */
+
+ /* Allocate a bz_file structure, populate it */
+ bzf_tmp = malloc(sizeof(struct bz_file));
+ if (bzf_tmp == NULL)
+ return(-1);
+ bzero(bzf_tmp, sizeof(struct bz_file));
+ bzf_tmp->bzf_rawfd = bzf->bzf_rawfd;
+
+ /* Initialise the inflation engine */
+ if (BZ2_bzDecompressInit(&(bzf_tmp->bzf_bzstream), 0, 1) != BZ_OK) {
+ free(bzf_tmp);
+ return(-1);
+ }
+
+ /* Seek back to the beginning of the file */
+ if (lseek(bzf->bzf_rawfd, 0, SEEK_SET) == -1) {
+ BZ2_bzDecompressEnd(&(bzf_tmp->bzf_bzstream));
+ free(bzf_tmp);
+ return(-1);
+ }
+
+ /* Free old bz_file data */
+ BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
+ free(bzf);
+
+ /* Use the new bz_file data */
+ f->f_fsdata = bzf_tmp;
+
+ return(0);
+}
+
+static off_t
+bzf_seek(struct open_file *f, off_t offset, int where)
+{
+ struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
+ off_t target;
+ char discard[16];
+
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = offset + bzf->bzf_bzstream.total_out_lo32;
+ break;
+ case SEEK_END:
+ target = -1;
+ default:
+ errno = EINVAL;
+ return(-1);
+ }
+
+ /* Can we get there from here? */
+ if (target < bzf->bzf_bzstream.total_out_lo32 && bzf_rewind(f) != 0) {
+ errno = EOFFSET;
+ return -1;
+ }
+
+ /* if bzf_rewind was called then bzf has changed */
+ bzf = (struct bz_file *)f->f_fsdata;
+
+ /* skip forwards if required */
+ while (target > bzf->bzf_bzstream.total_out_lo32) {
+ errno = bzf_read(f, discard, min(sizeof(discard),
+ target - bzf->bzf_bzstream.total_out_lo32), NULL);
+ if (errno)
+ return(-1);
+ }
+ /* This is where we are (be honest if we overshot) */
+ return(bzf->bzf_bzstream.total_out_lo32);
+}
+
+static int
+bzf_stat(struct open_file *f, struct stat *sb)
+{
+ struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
+ int result;
+
+ /* stat as normal, but indicate that size is unknown */
+ if ((result = fstat(bzf->bzf_rawfd, sb)) == 0)
+ sb->st_size = -1;
+ return(result);
+}
+
+void
+bz_internal_error(int errorcode)
+{
+ panic("bzipfs: critical error %d in bzip2 library occured\n", errorcode);
+}
+
+#ifdef REGRESSION
+/* Small test case, open and decompress test.bz2 */
+int main()
+{
+ struct open_file f;
+ char buf[1024];
+ size_t resid;
+ int err;
+
+ memset(&f, '\0', sizeof(f));
+ f.f_flags = F_READ;
+ err = bzf_open("test", &f);
+ if (err != 0)
+ exit(1);
+ do {
+ err = bzf_read(&f, buf, sizeof(buf), &resid);
+ } while (err == 0 && resid != sizeof(buf));
+
+ if (err != 0)
+ exit(2);
+ exit(0);
+}
+#endif
diff --git a/usr/src/boot/lib/libstand/cd9660.c b/usr/src/boot/lib/libstand/cd9660.c
new file mode 100644
index 0000000000..8f9db3fa71
--- /dev/null
+++ b/usr/src/boot/lib/libstand/cd9660.c
@@ -0,0 +1,594 @@
+/* $NetBSD: cd9660.c,v 1.5 1997/06/26 19:11:33 drochner Exp $ */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Stand-alone ISO9660 file reading package.
+ *
+ * Note: This doesn't support Rock Ridge extensions, extended attributes,
+ * blocksizes other than 2048 bytes, multi-extent files, etc.
+ */
+#include <sys/param.h>
+#include <string.h>
+#include <sys/dirent.h>
+#include <isofs/cd9660/iso.h>
+#include <isofs/cd9660/cd9660_rrip.h>
+
+#include "stand.h"
+
+#define SUSP_CONTINUATION "CE"
+#define SUSP_PRESENT "SP"
+#define SUSP_STOP "ST"
+#define SUSP_EXTREF "ER"
+#define RRIP_NAME "NM"
+
+typedef struct {
+ ISO_SUSP_HEADER h;
+ u_char signature [ISODCL ( 5, 6)];
+ u_char len_skp [ISODCL ( 7, 7)]; /* 711 */
+} ISO_SUSP_PRESENT;
+
+static int buf_read_file(struct open_file *f, char **buf_p,
+ size_t *size_p);
+static int cd9660_open(const char *path, struct open_file *f);
+static int cd9660_close(struct open_file *f);
+static int cd9660_read(struct open_file *f, void *buf, size_t size,
+ size_t *resid);
+static int cd9660_write(struct open_file *f, void *buf, size_t size,
+ size_t *resid);
+static off_t cd9660_seek(struct open_file *f, off_t offset, int where);
+static int cd9660_stat(struct open_file *f, struct stat *sb);
+static int cd9660_readdir(struct open_file *f, struct dirent *d);
+static int dirmatch(struct open_file *f, const char *path,
+ struct iso_directory_record *dp, int use_rrip, int lenskip);
+static int rrip_check(struct open_file *f, struct iso_directory_record *dp,
+ int *lenskip);
+static char *rrip_lookup_name(struct open_file *f,
+ struct iso_directory_record *dp, int lenskip, size_t *len);
+static ISO_SUSP_HEADER *susp_lookup_record(struct open_file *f,
+ const char *identifier, struct iso_directory_record *dp,
+ int lenskip);
+
+struct fs_ops cd9660_fsops = {
+ "cd9660",
+ cd9660_open,
+ cd9660_close,
+ cd9660_read,
+ cd9660_write,
+ cd9660_seek,
+ cd9660_stat,
+ cd9660_readdir
+};
+
+#define F_ISDIR 0x0001 /* Directory */
+#define F_ROOTDIR 0x0002 /* Root directory */
+#define F_RR 0x0004 /* Rock Ridge on this volume */
+
+struct file {
+ int f_flags; /* file flags */
+ off_t f_off; /* Current offset within file */
+ daddr_t f_bno; /* Starting block number */
+ off_t f_size; /* Size of file */
+ daddr_t f_buf_blkno; /* block number of data block */
+ char *f_buf; /* buffer for data block */
+ int f_susp_skip; /* len_skip for SUSP records */
+};
+
+struct ptable_ent {
+ char namlen [ISODCL( 1, 1)]; /* 711 */
+ char extlen [ISODCL( 2, 2)]; /* 711 */
+ char block [ISODCL( 3, 6)]; /* 732 */
+ char parent [ISODCL( 7, 8)]; /* 722 */
+ char name [1];
+};
+#define PTFIXSZ 8
+#define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)
+
+#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE)
+
+static ISO_SUSP_HEADER *
+susp_lookup_record(struct open_file *f, const char *identifier,
+ struct iso_directory_record *dp, int lenskip)
+{
+ static char susp_buffer[ISO_DEFAULT_BLOCK_SIZE];
+ ISO_SUSP_HEADER *sh;
+ ISO_RRIP_CONT *shc;
+ char *p, *end;
+ int error;
+ size_t read;
+
+ p = dp->name + isonum_711(dp->name_len) + lenskip;
+ /* Names of even length have a padding byte after the name. */
+ if ((isonum_711(dp->name_len) & 1) == 0)
+ p++;
+ end = (char *)dp + isonum_711(dp->length);
+ while (p + 3 < end) {
+ sh = (ISO_SUSP_HEADER *)p;
+ if (bcmp(sh->type, identifier, 2) == 0)
+ return (sh);
+ if (bcmp(sh->type, SUSP_STOP, 2) == 0)
+ return (NULL);
+ if (bcmp(sh->type, SUSP_CONTINUATION, 2) == 0) {
+ shc = (ISO_RRIP_CONT *)sh;
+ error = f->f_dev->dv_strategy(f->f_devdata, F_READ,
+ cdb2devb(isonum_733(shc->location)), 0,
+ ISO_DEFAULT_BLOCK_SIZE, susp_buffer, &read);
+
+ /* Bail if it fails. */
+ if (error != 0 || read != ISO_DEFAULT_BLOCK_SIZE)
+ return (NULL);
+ p = susp_buffer + isonum_733(shc->offset);
+ end = p + isonum_733(shc->length);
+ } else {
+ /* Ignore this record and skip to the next. */
+ p += isonum_711(sh->length);
+
+ /* Avoid infinite loops with corrupted file systems */
+ if (isonum_711(sh->length) == 0)
+ return (NULL);
+ }
+ }
+ return (NULL);
+}
+
+static char *
+rrip_lookup_name(struct open_file *f, struct iso_directory_record *dp,
+ int lenskip, size_t *len)
+{
+ ISO_RRIP_ALTNAME *p;
+
+ if (len == NULL)
+ return (NULL);
+
+ p = (ISO_RRIP_ALTNAME *)susp_lookup_record(f, RRIP_NAME, dp, lenskip);
+ if (p == NULL)
+ return (NULL);
+ switch (*p->flags) {
+ case ISO_SUSP_CFLAG_CURRENT:
+ *len = 1;
+ return (".");
+ case ISO_SUSP_CFLAG_PARENT:
+ *len = 2;
+ return ("..");
+ case 0:
+ *len = isonum_711(p->h.length) - 5;
+ return ((char *)p + 5);
+ default:
+ /*
+ * We don't handle hostnames or continued names as they are
+ * too hard, so just bail and use the default name.
+ */
+ return (NULL);
+ }
+}
+
+static int
+rrip_check(struct open_file *f, struct iso_directory_record *dp, int *lenskip)
+{
+ ISO_SUSP_PRESENT *sp;
+ ISO_RRIP_EXTREF *er;
+ char *p;
+
+ /* First, see if we can find a SP field. */
+ p = dp->name + isonum_711(dp->name_len);
+ if (p > (char *)dp + isonum_711(dp->length))
+ return (0);
+ sp = (ISO_SUSP_PRESENT *)p;
+ if (bcmp(sp->h.type, SUSP_PRESENT, 2) != 0)
+ return (0);
+ if (isonum_711(sp->h.length) != sizeof(ISO_SUSP_PRESENT))
+ return (0);
+ if (sp->signature[0] != 0xbe || sp->signature[1] != 0xef)
+ return (0);
+ *lenskip = isonum_711(sp->len_skp);
+
+ /*
+ * Now look for an ER field. If RRIP is present, then there must
+ * be at least one of these. It would be more pedantic to walk
+ * through the list of fields looking for a Rock Ridge ER field.
+ */
+ er = (ISO_RRIP_EXTREF *)susp_lookup_record(f, SUSP_EXTREF, dp, 0);
+ if (er == NULL)
+ return (0);
+ return (1);
+}
+
+static int
+dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
+ int use_rrip, int lenskip)
+{
+ size_t len;
+ char *cp;
+ int i, icase;
+
+ if (use_rrip)
+ cp = rrip_lookup_name(f, dp, lenskip, &len);
+ else
+ cp = NULL;
+ if (cp == NULL) {
+ len = isonum_711(dp->name_len);
+ cp = dp->name;
+ icase = 1;
+ } else
+ icase = 0;
+ for (i = len; --i >= 0; path++, cp++) {
+ if (!*path || *path == '/')
+ break;
+ if (*path == *cp)
+ continue;
+ if (!icase && toupper(*path) == *cp)
+ continue;
+ return 0;
+ }
+ if (*path && *path != '/')
+ return 0;
+ /*
+ * Allow stripping of trailing dots and the version number.
+ * Note that this will find the first instead of the last version
+ * of a file.
+ */
+ if (i >= 0 && (*cp == ';' || *cp == '.')) {
+ /* This is to prevent matching of numeric extensions */
+ if (*cp == '.' && cp[1] != ';')
+ return 0;
+ while (--i >= 0)
+ if (*++cp != ';' && (*cp < '0' || *cp > '9'))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+cd9660_open(const char *path, struct open_file *f)
+{
+ struct file *fp = 0;
+ void *buf;
+ struct iso_primary_descriptor *vd;
+ size_t buf_size, read, dsize, off;
+ daddr_t bno, boff;
+ struct iso_directory_record rec;
+ struct iso_directory_record *dp = 0;
+ int rc, first, use_rrip, lenskip;
+
+ /* First find the volume descriptor */
+ buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
+ vd = buf;
+ for (bno = 16;; bno++) {
+ twiddle(1);
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
+ 0, ISO_DEFAULT_BLOCK_SIZE, buf, &read);
+ if (rc)
+ goto out;
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ rc = EINVAL;
+ if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_END)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_PRIMARY)
+ break;
+ }
+ if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE)
+ goto out;
+
+ rec = *(struct iso_directory_record *) vd->root_directory_record;
+ if (*path == '/') path++; /* eat leading '/' */
+
+ first = 1;
+ use_rrip = 0;
+ while (*path) {
+ bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
+ dsize = isonum_733(rec.size);
+ off = 0;
+ boff = 0;
+
+ while (off < dsize) {
+ if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) {
+ twiddle(1);
+ rc = f->f_dev->dv_strategy
+ (f->f_devdata, F_READ,
+ cdb2devb(bno + boff),
+ 0, ISO_DEFAULT_BLOCK_SIZE,
+ buf, &read);
+ if (rc)
+ goto out;
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ boff++;
+ dp = (struct iso_directory_record *) buf;
+ }
+ if (isonum_711(dp->length) == 0) {
+ /* skip to next block, if any */
+ off = boff * ISO_DEFAULT_BLOCK_SIZE;
+ continue;
+ }
+
+ /* See if RRIP is in use. */
+ if (first)
+ use_rrip = rrip_check(f, dp, &lenskip);
+
+ if (dirmatch(f, path, dp, use_rrip,
+ first ? 0 : lenskip)) {
+ first = 0;
+ break;
+ } else
+ first = 0;
+
+ dp = (struct iso_directory_record *)
+ ((char *) dp + isonum_711(dp->length));
+ off += isonum_711(dp->length);
+ }
+ if (off >= dsize) {
+ rc = ENOENT;
+ goto out;
+ }
+
+ rec = *dp;
+ while (*path && *path != '/') /* look for next component */
+ path++;
+ if (*path) path++; /* skip '/' */
+ }
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ if ((isonum_711(rec.flags) & 2) != 0) {
+ fp->f_flags = F_ISDIR;
+ }
+ if (first) {
+ fp->f_flags |= F_ROOTDIR;
+
+ /* Check for Rock Ridge since we didn't in the loop above. */
+ bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
+ twiddle(1);
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
+ 0, ISO_DEFAULT_BLOCK_SIZE, buf, &read);
+ if (rc)
+ goto out;
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ dp = (struct iso_directory_record *)buf;
+ use_rrip = rrip_check(f, dp, &lenskip);
+ }
+ if (use_rrip) {
+ fp->f_flags |= F_RR;
+ fp->f_susp_skip = lenskip;
+ }
+ fp->f_off = 0;
+ fp->f_bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
+ fp->f_size = isonum_733(rec.size);
+ free(buf);
+
+ return 0;
+
+out:
+ if (fp)
+ free(fp);
+ free(buf);
+
+ return rc;
+}
+
+static int
+cd9660_close(struct open_file *f)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ f->f_fsdata = 0;
+ free(fp);
+
+ return 0;
+}
+
+static int
+buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ daddr_t blkno, blkoff;
+ int rc = 0;
+ size_t read;
+
+ blkno = fp->f_off / ISO_DEFAULT_BLOCK_SIZE + fp->f_bno;
+ blkoff = fp->f_off % ISO_DEFAULT_BLOCK_SIZE;
+
+ if (blkno != fp->f_buf_blkno) {
+ if (fp->f_buf == (char *)0)
+ fp->f_buf = malloc(ISO_DEFAULT_BLOCK_SIZE);
+
+ twiddle(16);
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ,
+ cdb2devb(blkno), 0, ISO_DEFAULT_BLOCK_SIZE,
+ fp->f_buf, &read);
+ if (rc)
+ return (rc);
+ if (read != ISO_DEFAULT_BLOCK_SIZE)
+ return (EIO);
+
+ fp->f_buf_blkno = blkno;
+ }
+
+ *buf_p = fp->f_buf + blkoff;
+ *size_p = ISO_DEFAULT_BLOCK_SIZE - blkoff;
+
+ if (*size_p > fp->f_size - fp->f_off)
+ *size_p = fp->f_size - fp->f_off;
+ return (rc);
+}
+
+static int
+cd9660_read(struct open_file *f, void *start, size_t size, size_t *resid)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ char *buf, *addr;
+ size_t buf_size, csize;
+ int rc = 0;
+
+ addr = start;
+ while (size) {
+ if (fp->f_off < 0 || fp->f_off >= fp->f_size)
+ break;
+
+ rc = buf_read_file(f, &buf, &buf_size);
+ if (rc)
+ break;
+
+ csize = size > buf_size ? buf_size : size;
+ bcopy(buf, addr, csize);
+
+ fp->f_off += csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (rc);
+}
+
+static int
+cd9660_readdir(struct open_file *f, struct dirent *d)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct iso_directory_record *ep;
+ size_t buf_size, reclen, namelen;
+ int error = 0;
+ int lenskip;
+ char *buf, *name;
+
+again:
+ if (fp->f_off >= fp->f_size)
+ return (ENOENT);
+ error = buf_read_file(f, &buf, &buf_size);
+ if (error)
+ return (error);
+ ep = (struct iso_directory_record *)buf;
+
+ if (isonum_711(ep->length) == 0) {
+ daddr_t blkno;
+
+ /* skip to next block, if any */
+ blkno = fp->f_off / ISO_DEFAULT_BLOCK_SIZE;
+ fp->f_off = (blkno + 1) * ISO_DEFAULT_BLOCK_SIZE;
+ goto again;
+ }
+
+ if (fp->f_flags & F_RR) {
+ if (fp->f_flags & F_ROOTDIR && fp->f_off == 0)
+ lenskip = 0;
+ else
+ lenskip = fp->f_susp_skip;
+ name = rrip_lookup_name(f, ep, lenskip, &namelen);
+ } else
+ name = NULL;
+ if (name == NULL) {
+ namelen = isonum_711(ep->name_len);
+ name = ep->name;
+ if (namelen == 1) {
+ if (ep->name[0] == 0)
+ name = ".";
+ else if (ep->name[0] == 1) {
+ namelen = 2;
+ name = "..";
+ }
+ }
+ }
+ reclen = sizeof(struct dirent) - (MAXNAMLEN+1) + namelen + 1;
+ reclen = (reclen + 3) & ~3;
+
+ d->d_fileno = isonum_733(ep->extent);
+ d->d_reclen = reclen;
+ if (isonum_711(ep->flags) & 2)
+ d->d_type = DT_DIR;
+ else
+ d->d_type = DT_REG;
+ d->d_namlen = namelen;
+
+ bcopy(name, d->d_name, d->d_namlen);
+ d->d_name[d->d_namlen] = 0;
+
+ fp->f_off += isonum_711(ep->length);
+ return (0);
+}
+
+static int
+cd9660_write(struct open_file *f __unused, void *start __unused, size_t size __unused, size_t *resid __unused)
+{
+ return EROFS;
+}
+
+static off_t
+cd9660_seek(struct open_file *f, off_t offset, int where)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_off = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_off += offset;
+ break;
+ case SEEK_END:
+ fp->f_off = fp->f_size - offset;
+ break;
+ default:
+ return -1;
+ }
+ return fp->f_off;
+}
+
+static int
+cd9660_stat(struct open_file *f, struct stat *sb)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if (fp->f_flags & F_ISDIR)
+ sb->st_mode |= S_IFDIR;
+ else
+ sb->st_mode |= S_IFREG;
+ sb->st_uid = sb->st_gid = 0;
+ sb->st_size = fp->f_size;
+ return 0;
+}
diff --git a/usr/src/boot/lib/libstand/close.c b/usr/src/boot/lib/libstand/close.c
new file mode 100644
index 0000000000..939f025b8f
--- /dev/null
+++ b/usr/src/boot/lib/libstand/close.c
@@ -0,0 +1,98 @@
+/* $NetBSD: close.c,v 1.7 1997/01/22 00:38:09 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)close.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+int
+close(int fd)
+{
+ struct open_file *f = &files[fd];
+ int err1 = 0, err2 = 0;
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_rabuf != NULL) {
+ free(f->f_rabuf);
+ f->f_rabuf = NULL;
+ }
+ if (!(f->f_flags & F_RAW) && f->f_ops)
+ err1 = (f->f_ops->fo_close)(f);
+ if (!(f->f_flags & F_NODEV) && f->f_dev)
+ err2 = (f->f_dev->dv_close)(f);
+ if (f->f_devdata != NULL)
+ devclose(f);
+ f->f_flags = 0;
+ if (err1) {
+ errno = err1;
+ return (-1);
+ }
+ if (err2) {
+ errno = err2;
+ return (-1);
+ }
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/closeall.c b/usr/src/boot/lib/libstand/closeall.c
new file mode 100644
index 0000000000..a661426763
--- /dev/null
+++ b/usr/src/boot/lib/libstand/closeall.c
@@ -0,0 +1,76 @@
+/* $NetBSD: closeall.c,v 1.1 1996/01/13 22:25:36 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)close.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+void
+closeall()
+{
+ int i;
+
+ for (i = 0; i < SOPEN_MAX; i++)
+ if (files[i].f_flags != 0)
+ (void)close(i);
+}
diff --git a/usr/src/boot/lib/libstand/dev.c b/usr/src/boot/lib/libstand/dev.c
new file mode 100644
index 0000000000..482c082117
--- /dev/null
+++ b/usr/src/boot/lib/libstand/dev.c
@@ -0,0 +1,61 @@
+/* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)dev.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+
+#include "stand.h"
+
+int
+nodev()
+{
+ return (ENXIO);
+}
+
+void
+nullsys()
+{
+}
+
+/* ARGSUSED */
+int
+noioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EINVAL);
+}
diff --git a/usr/src/boot/lib/libstand/dosfs.c b/usr/src/boot/lib/libstand/dosfs.c
new file mode 100644
index 0000000000..652ac92cae
--- /dev/null
+++ b/usr/src/boot/lib/libstand/dosfs.c
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 1996, 1998 Robert Nordier
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Readonly filesystem for Microsoft FAT12/FAT16/FAT32 filesystems,
+ * also supports VFAT.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "stand.h"
+
+#include "dosfs.h"
+
+
+static int dos_open(const char *path, struct open_file *fd);
+static int dos_close(struct open_file *fd);
+static int dos_read(struct open_file *fd, void *buf, size_t size, size_t *resid);
+static off_t dos_seek(struct open_file *fd, off_t offset, int whence);
+static int dos_stat(struct open_file *fd, struct stat *sb);
+static int dos_readdir(struct open_file *fd, struct dirent *d);
+
+struct fs_ops dosfs_fsops = {
+ "dosfs",
+ dos_open,
+ dos_close,
+ dos_read,
+ null_write,
+ dos_seek,
+ dos_stat,
+ dos_readdir
+};
+
+#define SECSIZ 512 /* sector size */
+#define SSHIFT 9 /* SECSIZ shift */
+#define DEPSEC 16 /* directory entries per sector */
+#define DSHIFT 4 /* DEPSEC shift */
+#define LOCLUS 2 /* lowest cluster number */
+
+/* DOS "BIOS Parameter Block" */
+typedef struct {
+ u_char secsiz[2]; /* sector size */
+ u_char spc; /* sectors per cluster */
+ u_char ressec[2]; /* reserved sectors */
+ u_char fats; /* FATs */
+ u_char dirents[2]; /* root directory entries */
+ u_char secs[2]; /* total sectors */
+ u_char media; /* media descriptor */
+ u_char spf[2]; /* sectors per FAT */
+ u_char spt[2]; /* sectors per track */
+ u_char heads[2]; /* drive heads */
+ u_char hidsec[4]; /* hidden sectors */
+ u_char lsecs[4]; /* huge sectors */
+ u_char lspf[4]; /* huge sectors per FAT */
+ u_char xflg[2]; /* flags */
+ u_char vers[2]; /* filesystem version */
+ u_char rdcl[4]; /* root directory start cluster */
+ u_char infs[2]; /* filesystem info sector */
+ u_char bkbs[2]; /* backup boot sector */
+} DOS_BPB;
+
+/* Initial portion of DOS boot sector */
+typedef struct {
+ u_char jmp[3]; /* usually 80x86 'jmp' opcode */
+ u_char oem[8]; /* OEM name and version */
+ DOS_BPB bpb; /* BPB */
+} DOS_BS;
+
+/* Supply missing "." and ".." root directory entries */
+static const char *const dotstr[2] = {".", ".."};
+static DOS_DE dot[2] = {
+ {". ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}},
+ {".. ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}}
+};
+
+/* The usual conversion macros to avoid multiplication and division */
+#define bytsec(n) ((n) >> SSHIFT)
+#define secbyt(s) ((s) << SSHIFT)
+#define entsec(e) ((e) >> DSHIFT)
+#define bytblk(fs, n) ((n) >> (fs)->bshift)
+#define blkbyt(fs, b) ((b) << (fs)->bshift)
+#define secblk(fs, s) ((s) >> ((fs)->bshift - SSHIFT))
+#define blksec(fs, b) ((b) << ((fs)->bshift - SSHIFT))
+
+/* Convert cluster number to offset within filesystem */
+#define blkoff(fs, b) (secbyt((fs)->lsndta) + blkbyt(fs, (b) - LOCLUS))
+
+/* Convert cluster number to logical sector number */
+#define blklsn(fs, b) ((fs)->lsndta + blksec(fs, (b) - LOCLUS))
+
+/* Convert cluster number to offset within FAT */
+#define fatoff(sz, c) ((sz) == 12 ? (c) + ((c) >> 1) : \
+ (sz) == 16 ? (c) << 1 : \
+ (c) << 2)
+
+/* Does cluster number reference a valid data cluster? */
+#define okclus(fs, c) ((c) >= LOCLUS && (c) <= (fs)->xclus)
+
+/* Get start cluster from directory entry */
+#define stclus(sz, de) ((sz) != 32 ? cv2((de)->clus) : \
+ ((u_int)cv2((de)->dex.h_clus) << 16) | \
+ cv2((de)->clus))
+
+/*
+ * fat cache metadata
+ */
+struct fatcache {
+ int unit; /* disk unit number */
+ int size; /* buffer (and fat) size in sectors */
+ u_char *buf;
+};
+
+static struct fatcache fat;
+
+static int dosunmount(DOS_FS *);
+static int parsebs(DOS_FS *, DOS_BS *);
+static int namede(DOS_FS *, const char *, DOS_DE **);
+static int lookup(DOS_FS *, u_int, const char *, DOS_DE **);
+static void cp_xdnm(u_char *, DOS_XDE *);
+static void cp_sfn(u_char *, DOS_DE *);
+static off_t fsize(DOS_FS *, DOS_DE *);
+static int fatcnt(DOS_FS *, u_int);
+static int fatget(DOS_FS *, u_int *);
+static int fatend(u_int, u_int);
+static int ioread(DOS_FS *, u_int, void *, u_int);
+static int ioget(struct open_file *, daddr_t, size_t, void *, u_int);
+
+static void
+dos_read_fat(DOS_FS *fs, struct open_file *fd)
+{
+ struct devdesc *dd = fd->f_devdata;
+
+ if (fat.buf != NULL) { /* can we reuse old buffer? */
+ if (fat.size != fs->spf) {
+ free(fat.buf); /* no, free old buffer */
+ fat.buf = NULL;
+ }
+ }
+
+ if (fat.buf == NULL)
+ fat.buf = malloc(secbyt(fs->spf));
+
+ if (fat.buf != NULL) {
+ if (ioget(fd, fs->lsnfat, 0, fat.buf, secbyt(fs->spf)) == 0) {
+ fat.size = fs->spf;
+ fat.unit = dd->d_unit;
+ return;
+ }
+ }
+ if (fat.buf != NULL) /* got IO error */
+ free(fat.buf);
+ fat.buf = NULL;
+ fat.unit = -1; /* impossible unit */
+ fat.size = 0;
+}
+
+/*
+ * Mount DOS filesystem
+ */
+static int
+dos_mount(DOS_FS *fs, struct open_file *fd)
+{
+ int err;
+ struct devdesc *dd = fd->f_devdata;
+ u_char *buf;
+
+ bzero(fs, sizeof(DOS_FS));
+ fs->fd = fd;
+
+ if ((err = !(buf = malloc(secbyt(1))) ? errno : 0) ||
+ (err = ioget(fs->fd, 0, 0, buf, secbyt(1))) ||
+ (err = parsebs(fs, (DOS_BS *)buf))) {
+ if (buf != NULL)
+ free(buf);
+ (void)dosunmount(fs);
+ return(err);
+ }
+ free(buf);
+
+ if (fat.buf == NULL || fat.unit != dd->d_unit)
+ dos_read_fat(fs, fd);
+
+ fs->root = dot[0];
+ fs->root.name[0] = ' ';
+ if (fs->fatsz == 32) {
+ fs->root.clus[0] = fs->rdcl & 0xff;
+ fs->root.clus[1] = (fs->rdcl >> 8) & 0xff;
+ fs->root.dex.h_clus[0] = (fs->rdcl >> 16) & 0xff;
+ fs->root.dex.h_clus[1] = (fs->rdcl >> 24) & 0xff;
+ }
+ return 0;
+}
+
+/*
+ * Unmount mounted filesystem
+ */
+static int
+dos_unmount(DOS_FS *fs)
+{
+ int err;
+
+ if (fs->links)
+ return(EBUSY);
+ if ((err = dosunmount(fs)))
+ return(err);
+ return 0;
+}
+
+/*
+ * Common code shared by dos_mount() and dos_unmount()
+ */
+static int
+dosunmount(DOS_FS *fs)
+{
+ free(fs);
+ return(0);
+}
+
+/*
+ * Open DOS file
+ */
+static int
+dos_open(const char *path, struct open_file *fd)
+{
+ DOS_DE *de;
+ DOS_FILE *f;
+ DOS_FS *fs;
+ u_int size, clus;
+ int err = 0;
+
+ /* Allocate mount structure, associate with open */
+ fs = malloc(sizeof(DOS_FS));
+
+ if ((err = dos_mount(fs, fd)))
+ goto out;
+
+ if ((err = namede(fs, path, &de)))
+ goto out;
+
+ clus = stclus(fs->fatsz, de);
+ size = cv4(de->size);
+
+ if ((!(de->attr & FA_DIR) && (!clus != !size)) ||
+ ((de->attr & FA_DIR) && size) ||
+ (clus && !okclus(fs, clus))) {
+ err = EINVAL;
+ goto out;
+ }
+ f = malloc(sizeof(DOS_FILE));
+ bzero(f, sizeof(DOS_FILE));
+ f->fs = fs;
+ fs->links++;
+ f->de = *de;
+ fd->f_fsdata = (void *)f;
+
+ out:
+ return(err);
+}
+
+/*
+ * Read from file
+ */
+static int
+dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid)
+{
+ off_t size;
+ u_int nb, off, clus, c, cnt, n;
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+ int err = 0;
+
+ /*
+ * as ioget() can be called *a lot*, use twiddle here.
+ * also 4 seems to be good value not to slow loading down too much:
+ * with 270MB file (~540k ioget() calls, twiddle can easily waste 4-5sec.
+ */
+ twiddle(4);
+ nb = (u_int)nbyte;
+ if ((size = fsize(f->fs, &f->de)) == -1)
+ return EINVAL;
+ if (nb > (n = size - f->offset))
+ nb = n;
+ off = f->offset;
+ if ((clus = stclus(f->fs->fatsz, &f->de)))
+ off &= f->fs->bsize - 1;
+ c = f->c;
+ cnt = nb;
+ while (cnt) {
+ n = 0;
+ if (!c) {
+ if ((c = clus))
+ n = bytblk(f->fs, f->offset);
+ } else if (!off)
+ n++;
+ while (n--) {
+ if ((err = fatget(f->fs, &c)))
+ goto out;
+ if (!okclus(f->fs, c)) {
+ err = EINVAL;
+ goto out;
+ }
+ }
+ if (!clus || (n = f->fs->bsize - off) > cnt)
+ n = cnt;
+ if ((err = ioread(f->fs, (c ? blkoff(f->fs, c) :
+ secbyt(f->fs->lsndir)) + off, buf, n)))
+ goto out;
+ f->offset += n;
+ f->c = c;
+ off = 0;
+ buf = (char *)buf + n;
+ cnt -= n;
+ }
+ out:
+ if (resid)
+ *resid = nbyte - nb + cnt;
+ return(err);
+}
+
+/*
+ * Reposition within file
+ */
+static off_t
+dos_seek(struct open_file *fd, off_t offset, int whence)
+{
+ off_t off;
+ u_int size;
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+
+ size = cv4(f->de.size);
+ switch (whence) {
+ case SEEK_SET:
+ off = 0;
+ break;
+ case SEEK_CUR:
+ off = f->offset;
+ break;
+ case SEEK_END:
+ off = size;
+ break;
+ default:
+ errno = EINVAL;
+ return(-1);
+ }
+ off += offset;
+ if (off < 0 || off > size) {
+ errno = EINVAL;
+ return(-1);
+ }
+ f->offset = (u_int)off;
+ f->c = 0;
+ return(off);
+}
+
+/*
+ * Close open file
+ */
+static int
+dos_close(struct open_file *fd)
+{
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+ DOS_FS *fs = f->fs;
+
+ f->fs->links--;
+ free(f);
+ dos_unmount(fs);
+ return 0;
+}
+
+/*
+ * Return some stat information on a file.
+ */
+static int
+dos_stat(struct open_file *fd, struct stat *sb)
+{
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = f->de.attr & FA_DIR ? S_IFDIR | 0555 : S_IFREG | 0444;
+ sb->st_nlink = 1;
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ if ((sb->st_size = fsize(f->fs, &f->de)) == -1)
+ return EINVAL;
+ return (0);
+}
+
+static int
+dos_checksum(char *name, char *ext)
+{
+ int x, i;
+ char buf[11];
+
+ bcopy(name, buf, 8);
+ bcopy(ext, buf+8, 3);
+ x = 0;
+ for (i = 0; i < 11; i++) {
+ x = ((x & 1) << 7) | (x >> 1);
+ x += buf[i];
+ x &= 0xff;
+ }
+ return (x);
+}
+
+static int
+dos_readdir(struct open_file *fd, struct dirent *d)
+{
+ /* DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; */
+ u_char fn[261];
+ DOS_DIR dd;
+ size_t res;
+ u_int chk, x, xdn;
+ int err;
+
+ x = chk = 0;
+ while (1) {
+ xdn = x;
+ x = 0;
+ err = dos_read(fd, &dd, sizeof(dd), &res);
+ if (err)
+ return (err);
+ if (res == sizeof(dd))
+ return (ENOENT);
+ if (dd.de.name[0] == 0)
+ return (ENOENT);
+
+ /* Skip deleted entries */
+ if (dd.de.name[0] == 0xe5)
+ continue;
+
+ /* Check if directory entry is volume label */
+ if (dd.de.attr & FA_LABEL) {
+ /*
+ * If volume label set, check if the current entry is
+ * extended entry (FA_XDE) for long file names.
+ */
+ if ((dd.de.attr & FA_MASK) == FA_XDE) {
+ /*
+ * Read through all following extended entries
+ * to get the long file name. 0x40 marks the
+ * last entry containing part of long file name.
+ */
+ if (dd.xde.seq & 0x40)
+ chk = dd.xde.chk;
+ else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
+ continue;
+ x = dd.xde.seq & ~0x40;
+ if (x < 1 || x > 20) {
+ x = 0;
+ continue;
+ }
+ cp_xdnm(fn, &dd.xde);
+ } else {
+ /* skip only volume label entries */
+ continue;
+ }
+ } else {
+ if (xdn == 1) {
+ x = dos_checksum(dd.de.name, dd.de.ext);
+ if (x == chk)
+ break;
+ } else {
+ cp_sfn(fn, &dd.de);
+ break;
+ }
+ x = 0;
+ }
+ }
+
+ d->d_fileno = (dd.de.clus[1] << 8) + dd.de.clus[0];
+ d->d_reclen = sizeof(*d);
+ d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG;
+ memcpy(d->d_name, fn, sizeof(d->d_name));
+ return(0);
+}
+
+/*
+ * Parse DOS boot sector
+ */
+static int
+parsebs(DOS_FS *fs, DOS_BS *bs)
+{
+ u_int sc;
+
+ if ((bs->jmp[0] != 0x69 &&
+ bs->jmp[0] != 0xe9 &&
+ (bs->jmp[0] != 0xeb || bs->jmp[2] != 0x90)) ||
+ bs->bpb.media < 0xf0)
+ return EINVAL;
+ if (cv2(bs->bpb.secsiz) != SECSIZ)
+ return EINVAL;
+ if (!(fs->spc = bs->bpb.spc) || fs->spc & (fs->spc - 1))
+ return EINVAL;
+ fs->bsize = secbyt(fs->spc);
+ fs->bshift = ffs(fs->bsize) - 1;
+ if ((fs->spf = cv2(bs->bpb.spf))) {
+ if (bs->bpb.fats != 2)
+ return EINVAL;
+ if (!(fs->dirents = cv2(bs->bpb.dirents)))
+ return EINVAL;
+ } else {
+ if (!(fs->spf = cv4(bs->bpb.lspf)))
+ return EINVAL;
+ if (!bs->bpb.fats || bs->bpb.fats > 16)
+ return EINVAL;
+ if ((fs->rdcl = cv4(bs->bpb.rdcl)) < LOCLUS)
+ return EINVAL;
+ }
+ if (!(fs->lsnfat = cv2(bs->bpb.ressec)))
+ return EINVAL;
+ fs->lsndir = fs->lsnfat + fs->spf * bs->bpb.fats;
+ fs->lsndta = fs->lsndir + entsec(fs->dirents);
+ if (!(sc = cv2(bs->bpb.secs)) && !(sc = cv4(bs->bpb.lsecs)))
+ return EINVAL;
+ if (fs->lsndta > sc)
+ return EINVAL;
+ if ((fs->xclus = secblk(fs, sc - fs->lsndta) + 1) < LOCLUS)
+ return EINVAL;
+ fs->fatsz = fs->dirents ? fs->xclus < 0xff6 ? 12 : 16 : 32;
+ sc = (secbyt(fs->spf) << 1) / (fs->fatsz >> 2) - 1;
+ if (fs->xclus > sc)
+ fs->xclus = sc;
+ return 0;
+}
+
+/*
+ * Return directory entry from path
+ */
+static int
+namede(DOS_FS *fs, const char *path, DOS_DE **dep)
+{
+ char name[256];
+ DOS_DE *de;
+ char *s;
+ size_t n;
+ int err;
+
+ err = 0;
+ de = &fs->root;
+ while (*path) {
+ while (*path == '/')
+ path++;
+ if (*path == '\0')
+ break;
+ if (!(s = strchr(path, '/')))
+ s = strchr(path, 0);
+ if ((n = s - path) > 255)
+ return ENAMETOOLONG;
+ memcpy(name, path, n);
+ name[n] = 0;
+ path = s;
+ if (!(de->attr & FA_DIR))
+ return ENOTDIR;
+ if ((err = lookup(fs, stclus(fs->fatsz, de), name, &de)))
+ return err;
+ }
+ *dep = de;
+ return 0;
+}
+
+/*
+ * Lookup path segment
+ */
+static int
+lookup(DOS_FS *fs, u_int clus, const char *name, DOS_DE **dep)
+{
+ static DOS_DIR dir[DEPSEC];
+ u_char lfn[261];
+ u_char sfn[13];
+ u_int nsec, lsec, xdn, chk, sec, ent, x;
+ int err, ok;
+
+ if (!clus)
+ for (ent = 0; ent < 2; ent++)
+ if (!strcasecmp(name, dotstr[ent])) {
+ *dep = dot + ent;
+ return 0;
+ }
+ if (!clus && fs->fatsz == 32)
+ clus = fs->rdcl;
+ nsec = !clus ? entsec(fs->dirents) : fs->spc;
+ lsec = 0;
+ xdn = chk = 0;
+ for (;;) {
+ if (!clus && !lsec)
+ lsec = fs->lsndir;
+ else if (okclus(fs, clus))
+ lsec = blklsn(fs, clus);
+ else
+ return EINVAL;
+ for (sec = 0; sec < nsec; sec++) {
+ if ((err = ioget(fs->fd, lsec + sec, 0, dir, secbyt(1))))
+ return err;
+ for (ent = 0; ent < DEPSEC; ent++) {
+ if (!*dir[ent].de.name)
+ return ENOENT;
+ if (*dir[ent].de.name != 0xe5) {
+ if ((dir[ent].de.attr & FA_MASK) == FA_XDE) {
+ x = dir[ent].xde.seq;
+ if (x & 0x40 || (x + 1 == xdn &&
+ dir[ent].xde.chk == chk)) {
+ if (x & 0x40) {
+ chk = dir[ent].xde.chk;
+ x &= ~0x40;
+ }
+ if (x >= 1 && x <= 20) {
+ cp_xdnm(lfn, &dir[ent].xde);
+ xdn = x;
+ continue;
+ }
+ }
+ } else if (!(dir[ent].de.attr & FA_LABEL)) {
+ if ((ok = xdn == 1)) {
+ x = dos_checksum(dir[ent].de.name, dir[ent].de.ext);
+ ok = chk == x &&
+ !strcasecmp(name, (const char *)lfn);
+ }
+ if (!ok) {
+ cp_sfn(sfn, &dir[ent].de);
+ ok = !strcasecmp(name, (const char *)sfn);
+ }
+ if (ok) {
+ *dep = &dir[ent].de;
+ return 0;
+ }
+ }
+ }
+ xdn = 0;
+ }
+ }
+ if (!clus)
+ break;
+ if ((err = fatget(fs, &clus)))
+ return err;
+ if (fatend(fs->fatsz, clus))
+ break;
+ }
+ return ENOENT;
+}
+
+/*
+ * Copy name from extended directory entry
+ */
+static void
+cp_xdnm(u_char *lfn, DOS_XDE *xde)
+{
+ static struct {
+ u_int off;
+ u_int dim;
+ } ix[3] = {
+ {offsetof(DOS_XDE, name1), sizeof(xde->name1) / 2},
+ {offsetof(DOS_XDE, name2), sizeof(xde->name2) / 2},
+ {offsetof(DOS_XDE, name3), sizeof(xde->name3) / 2}
+ };
+ u_char *p;
+ u_int n, x, c;
+
+ lfn += 13 * ((xde->seq & ~0x40) - 1);
+ for (n = 0; n < 3; n++)
+ for (p = (u_char *)xde + ix[n].off, x = ix[n].dim; x;
+ p += 2, x--) {
+ if ((c = cv2(p)) && (c < 32 || c > 127))
+ c = '?';
+ if (!(*lfn++ = c))
+ return;
+ }
+ if (xde->seq & 0x40)
+ *lfn = 0;
+}
+
+/*
+ * Copy short filename
+ */
+static void
+cp_sfn(u_char *sfn, DOS_DE *de)
+{
+ u_char *p;
+ int j, i;
+
+ p = sfn;
+ if (*de->name != ' ') {
+ for (j = 7; de->name[j] == ' '; j--);
+ for (i = 0; i <= j; i++)
+ *p++ = de->name[i];
+ if (*de->ext != ' ') {
+ *p++ = '.';
+ for (j = 2; de->ext[j] == ' '; j--);
+ for (i = 0; i <= j; i++)
+ *p++ = de->ext[i];
+ }
+ }
+ *p = 0;
+ if (*sfn == 5)
+ *sfn = 0xe5;
+}
+
+/*
+ * Return size of file in bytes
+ */
+static off_t
+fsize(DOS_FS *fs, DOS_DE *de)
+{
+ u_long size;
+ u_int c;
+ int n;
+
+ if (!(size = cv4(de->size)) && de->attr & FA_DIR) {
+ if (!(c = cv2(de->clus)))
+ size = fs->dirents * sizeof(DOS_DE);
+ else {
+ if ((n = fatcnt(fs, c)) == -1)
+ return n;
+ size = blkbyt(fs, n);
+ }
+ }
+ return size;
+}
+
+/*
+ * Count number of clusters in chain
+ */
+static int
+fatcnt(DOS_FS *fs, u_int c)
+{
+ int n;
+
+ for (n = 0; okclus(fs, c); n++)
+ if (fatget(fs, &c))
+ return -1;
+ return fatend(fs->fatsz, c) ? n : -1;
+}
+
+/*
+ * Get next cluster in cluster chain. Use in core fat cache unless another
+ * device replaced it.
+ */
+static int
+fatget(DOS_FS *fs, u_int *c)
+{
+ u_char buf[4];
+ u_char *s;
+ u_int x, offset, off, n, nbyte, lsec;
+ struct devdesc *dd = fs->fd->f_devdata;
+ int err = 0;
+
+ if (fat.unit != dd->d_unit) {
+ /* fat cache was changed to another device, don't use it */
+ err = ioread(fs, secbyt(fs->lsnfat) + fatoff(fs->fatsz, *c), buf,
+ fs->fatsz != 32 ? 2 : 4);
+ if (err)
+ return (err);
+ } else {
+ offset = fatoff(fs->fatsz, *c);
+ nbyte = fs->fatsz != 32 ? 2 : 4;
+
+ s = buf;
+ if ((off = offset & (SECSIZ - 1))) {
+ offset -= off;
+ lsec = bytsec(offset);
+ offset += SECSIZ;
+ if ((n = SECSIZ - off) > nbyte)
+ n = nbyte;
+ memcpy(s, fat.buf + secbyt(lsec) + off, n);
+ s += n;
+ nbyte -= n;
+ }
+ n = nbyte & (SECSIZ - 1);
+ if (nbyte -= n) {
+ memcpy(s, fat.buf + secbyt(bytsec(offset)), nbyte);
+ offset += nbyte;
+ s += nbyte;
+ }
+ if (n)
+ memcpy(s, fat.buf + secbyt(bytsec(offset)), n);
+ }
+
+ x = fs->fatsz != 32 ? cv2(buf) : cv4(buf);
+ *c = fs->fatsz == 12 ? *c & 1 ? x >> 4 : x & 0xfff : x;
+ return (0);
+}
+
+/*
+ * Is cluster an end-of-chain marker?
+ */
+static int
+fatend(u_int sz, u_int c)
+{
+ return c > (sz == 12 ? 0xff7U : sz == 16 ? 0xfff7U : 0xffffff7);
+}
+
+/*
+ * Offset-based I/O primitive
+ */
+static int
+ioread(DOS_FS *fs, u_int offset, void *buf, u_int nbyte)
+{
+ char *s;
+ u_int off, n;
+ int err;
+
+ s = buf;
+ if ((off = offset & (SECSIZ - 1))) {
+ offset -= off;
+ if ((n = SECSIZ - off) > nbyte)
+ n = nbyte;
+ if ((err = ioget(fs->fd, bytsec(offset), off, s, n)))
+ return err;
+ offset += SECSIZ;
+ s += n;
+ nbyte -= n;
+ }
+ n = nbyte & (SECSIZ - 1);
+ if (nbyte -= n) {
+ if ((err = ioget(fs->fd, bytsec(offset), 0, s, nbyte)))
+ return err;
+ offset += nbyte;
+ s += nbyte;
+ }
+ if (n) {
+ if ((err = ioget(fs->fd, bytsec(offset), 0, s, n)))
+ return err;
+ }
+ return 0;
+}
+
+/*
+ * Sector-based I/O primitive
+ */
+static int
+ioget(struct open_file *fd, daddr_t lsec, size_t offset, void *buf, u_int size)
+{
+ return ((fd->f_dev->dv_strategy)(fd->f_devdata, F_READ, lsec, offset,
+ size, buf, NULL));
+}
diff --git a/usr/src/boot/lib/libstand/dosfs.h b/usr/src/boot/lib/libstand/dosfs.h
new file mode 100644
index 0000000000..f2370ee502
--- /dev/null
+++ b/usr/src/boot/lib/libstand/dosfs.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1996, 1998 Robert Nordier
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef DOSIO_H
+#define DOSIO_H
+
+/*
+ * DOS file attributes
+ */
+
+#define FA_RDONLY 001 /* read-only */
+#define FA_HIDDEN 002 /* hidden file */
+#define FA_SYSTEM 004 /* system file */
+#define FA_LABEL 010 /* volume label */
+#define FA_DIR 020 /* directory */
+#define FA_ARCH 040 /* archive (file modified) */
+#define FA_XDE 017 /* extended directory entry */
+#define FA_MASK 077 /* all attributes */
+
+/*
+ * Macros to convert DOS-format 16-bit and 32-bit quantities
+ */
+
+#define cv2(p) ((u_int16_t)(p)[0] | \
+ ((u_int16_t)(p)[1] << 010))
+#define cv4(p) ((u_int32_t)(p)[0] | \
+ ((u_int32_t)(p)[1] << 010) | \
+ ((u_int32_t)(p)[2] << 020) | \
+ ((u_int32_t)(p)[3] << 030))
+
+/*
+ * Directory, filesystem, and file structures.
+ */
+
+typedef struct {
+ u_char x_case; /* case */
+ u_char c_hsec; /* created: secs/100 */
+ u_char c_time[2]; /* created: time */
+ u_char c_date[2]; /* created: date */
+ u_char a_date[2]; /* accessed: date */
+ u_char h_clus[2]; /* clus[hi] */
+} DOS_DEX;
+
+typedef struct {
+ u_char name[8]; /* name */
+ u_char ext[3]; /* extension */
+ u_char attr; /* attributes */
+ DOS_DEX dex; /* VFAT/FAT32 only */
+ u_char time[2]; /* modified: time */
+ u_char date[2]; /* modified: date */
+ u_char clus[2]; /* starting cluster */
+ u_char size[4]; /* size */
+} DOS_DE;
+
+typedef struct {
+ u_char seq; /* flags */
+ u_char name1[5][2]; /* 1st name area */
+ u_char attr; /* (see fat_de) */
+ u_char res; /* reserved */
+ u_char chk; /* checksum */
+ u_char name2[6][2]; /* 2nd name area */
+ u_char clus[2]; /* (see fat_de) */
+ u_char name3[2][2]; /* 3rd name area */
+} DOS_XDE;
+
+typedef union {
+ DOS_DE de; /* standard directory entry */
+ DOS_XDE xde; /* extended directory entry */
+} DOS_DIR;
+
+typedef struct {
+ struct open_file *fd; /* file descriptor */
+ u_int links; /* active links to structure */
+ u_int spc; /* sectors per cluster */
+ u_int bsize; /* cluster size in bytes */
+ u_int bshift; /* cluster conversion shift */
+ u_int dirents; /* root directory entries */
+ u_int spf; /* sectors per fat */
+ u_int rdcl; /* root directory start cluster */
+ u_int lsnfat; /* start of fat */
+ u_int lsndir; /* start of root dir */
+ u_int lsndta; /* start of data area */
+ u_int fatsz; /* FAT entry size */
+ u_int xclus; /* maximum cluster number */
+ DOS_DE root;
+} DOS_FS;
+
+typedef struct {
+ DOS_FS *fs; /* associated filesystem */
+ DOS_DE de; /* directory entry */
+ u_int offset; /* current offset */
+ u_int c; /* last cluster read */
+} DOS_FILE;
+
+#endif /* !DOSIO_H */
diff --git a/usr/src/boot/lib/libstand/environment.c b/usr/src/boot/lib/libstand/environment.c
new file mode 100644
index 0000000000..291e330044
--- /dev/null
+++ b/usr/src/boot/lib/libstand/environment.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Manage an environment-like space in which string variables may be stored.
+ * Provide support for some method-like operations for setting/retrieving
+ * variables in order to allow some type strength.
+ */
+
+#include "stand.h"
+
+#include <string.h>
+
+static void env_discard(struct env_var *ev);
+
+struct env_var *environ = NULL;
+
+/*
+ * Look up (name) and return it's env_var structure.
+ */
+struct env_var *
+env_getenv(const char *name)
+{
+ struct env_var *ev;
+
+ for (ev = environ; ev != NULL; ev = ev->ev_next)
+ if (!strcmp(ev->ev_name, name))
+ break;
+ return(ev);
+}
+
+/*
+ * Some notes:
+ *
+ * If the EV_VOLATILE flag is set, a copy of the variable is made.
+ * If EV_DYNAMIC is set, the variable has been allocated with
+ * malloc and ownership transferred to the environment.
+ * If (value) is NULL, the variable is set but has no value.
+ */
+int
+env_setenv(const char *name, int flags, const void *value,
+ ev_sethook_t sethook, ev_unsethook_t unsethook)
+{
+ struct env_var *ev, *curr, *last;
+
+ if ((ev = env_getenv(name)) != NULL) {
+ /*
+ * If there's a set hook, let it do the work (unless we are working
+ * for one already.
+ */
+ if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK))
+ return (ev->ev_sethook(ev, flags, value));
+
+ /* If there is data in the variable, discard it. */
+ if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0)
+ free(ev->ev_value);
+ ev->ev_value = NULL;
+ ev->ev_flags &= ~EV_DYNAMIC;
+
+ } else {
+
+ /*
+ * New variable; create and sort into list
+ */
+ ev = malloc(sizeof(struct env_var));
+ ev->ev_name = strdup(name);
+ ev->ev_value = NULL;
+ ev->ev_flags = 0;
+ /* hooks can only be set when the variable is instantiated */
+ ev->ev_sethook = sethook;
+ ev->ev_unsethook = unsethook;
+
+ /* Sort into list */
+ ev->ev_prev = NULL;
+ ev->ev_next = NULL;
+ /* Search for the record to insert before */
+ for (last = NULL, curr = environ;
+ curr != NULL;
+ last = curr, curr = curr->ev_next) {
+
+ if (strcmp(ev->ev_name, curr->ev_name) < 0) {
+ if (curr->ev_prev) {
+ curr->ev_prev->ev_next = ev;
+ } else {
+ environ = ev;
+ }
+ ev->ev_next = curr;
+ ev->ev_prev = curr->ev_prev;
+ curr->ev_prev = ev;
+ break;
+ }
+ }
+ if (curr == NULL) {
+ if (last == NULL) {
+ environ = ev;
+ } else {
+ last->ev_next = ev;
+ ev->ev_prev = last;
+ }
+ }
+ }
+
+ /* If we have a new value, use it */
+ if (flags & EV_VOLATILE) {
+ ev->ev_value = strdup(value);
+ ev->ev_flags |= EV_DYNAMIC;
+ } else {
+ ev->ev_value = (char *)value;
+ ev->ev_flags |= flags & EV_DYNAMIC;
+ }
+
+ return(0);
+}
+
+char *
+getenv(const char *name)
+{
+ struct env_var *ev;
+
+ /* Set but no value gives empty string */
+ if ((ev = env_getenv(name)) != NULL) {
+ if (ev->ev_value != NULL)
+ return(ev->ev_value);
+ return("");
+ }
+ return(NULL);
+}
+
+int
+setenv(const char *name, const char *value, int overwrite)
+{
+ /* No guarantees about state, always assume volatile */
+ if (overwrite || (env_getenv(name) == NULL))
+ return(env_setenv(name, EV_VOLATILE, value, NULL, NULL));
+ return(0);
+}
+
+int
+putenv(const char *string)
+{
+ char *value, *copy;
+ int result;
+
+ copy = strdup(string);
+ if ((value = strchr(copy, '=')) != NULL)
+ *(value++) = 0;
+ result = setenv(copy, value, 1);
+ free(copy);
+ return(result);
+}
+
+int
+unsetenv(const char *name)
+{
+ struct env_var *ev;
+ int err;
+
+ err = 0;
+ if ((ev = env_getenv(name)) == NULL) {
+ err = ENOENT;
+ } else {
+ if (ev->ev_unsethook != NULL)
+ err = ev->ev_unsethook(ev);
+ if (err == 0) {
+ env_discard(ev);
+ }
+ }
+ return(err);
+}
+
+static void
+env_discard(struct env_var *ev)
+{
+ if (ev->ev_prev)
+ ev->ev_prev->ev_next = ev->ev_next;
+ if (ev->ev_next)
+ ev->ev_next->ev_prev = ev->ev_prev;
+ if (environ == ev)
+ environ = ev->ev_next;
+ free(ev->ev_name);
+ if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0)
+ free(ev->ev_value);
+ free(ev);
+}
+
+int
+env_noset(struct env_var *ev __unused, int flags __unused,
+ const void *value __unused)
+{
+ return(EPERM);
+}
+
+int
+env_nounset(struct env_var *ev __unused)
+{
+ return(EPERM);
+}
diff --git a/usr/src/boot/lib/libstand/ether.c b/usr/src/boot/lib/libstand/ether.c
new file mode 100644
index 0000000000..50a8934ca1
--- /dev/null
+++ b/usr/src/boot/lib/libstand/ether.c
@@ -0,0 +1,150 @@
+/* $NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+/* Caller must leave room for ethernet header in front!! */
+ssize_t
+sendether(d, pkt, len, dea, etype)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ u_char *dea;
+ int etype;
+{
+ ssize_t n;
+ struct ether_header *eh;
+
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("sendether: called\n");
+#endif
+
+ eh = (struct ether_header *)pkt - 1;
+ len += sizeof(*eh);
+
+ MACPY(d->myea, eh->ether_shost); /* by byte */
+ MACPY(dea, eh->ether_dhost); /* by byte */
+ eh->ether_type = htons(etype);
+
+ n = netif_put(d, eh, len);
+ if (n == -1 || n < sizeof(*eh))
+ return (-1);
+
+ n -= sizeof(*eh);
+ return (n);
+}
+
+/*
+ * Get a packet of any Ethernet type, with our address or
+ * the broadcast address. Save the Ether type in arg 5.
+ * NOTE: Caller must leave room for the Ether header.
+ */
+ssize_t
+readether(d, pkt, len, tleft, etype)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ time_t tleft;
+ u_int16_t *etype;
+{
+ ssize_t n;
+ struct ether_header *eh;
+
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("readether: called\n");
+#endif
+
+ eh = (struct ether_header *)pkt - 1;
+ len += sizeof(*eh);
+
+ n = netif_get(d, eh, len, tleft);
+ if (n == -1 || n < sizeof(*eh))
+ return (-1);
+
+ /* Validate Ethernet address. */
+ if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
+ bcmp(bcea, eh->ether_dhost, 6) != 0) {
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("readether: not ours (ea=%s)\n",
+ ether_sprintf(eh->ether_dhost));
+#endif
+ return (-1);
+ }
+ *etype = ntohs(eh->ether_type);
+
+ n -= sizeof(*eh);
+ return (n);
+}
+
+/*
+ * Convert Ethernet address to printable (loggable) representation.
+ */
+static char digits[] = "0123456789abcdef";
+char *
+ether_sprintf(ap)
+ u_char *ap;
+{
+ int i;
+ static char etherbuf[18];
+ char *cp = etherbuf;
+
+ for (i = 0; i < 6; i++) {
+ *cp++ = digits[*ap >> 4];
+ *cp++ = digits[*ap++ & 0xf];
+ *cp++ = ':';
+ }
+ *--cp = 0;
+ return (etherbuf);
+}
diff --git a/usr/src/boot/lib/libstand/ext2fs.c b/usr/src/boot/lib/libstand/ext2fs.c
new file mode 100644
index 0000000000..d0b91e0446
--- /dev/null
+++ b/usr/src/boot/lib/libstand/ext2fs.c
@@ -0,0 +1,908 @@
+/*-
+ * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ *
+ * Copyright (c) 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: David Golub
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include "stand.h"
+#include "string.h"
+
+static int ext2fs_open(const char *path, struct open_file *f);
+static int ext2fs_close(struct open_file *f);
+static int ext2fs_read(struct open_file *f, void *buf,
+ size_t size, size_t *resid);
+static off_t ext2fs_seek(struct open_file *f, off_t offset, int where);
+static int ext2fs_stat(struct open_file *f, struct stat *sb);
+static int ext2fs_readdir(struct open_file *f, struct dirent *d);
+
+static int dtmap[] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR,
+ DT_BLK, DT_FIFO, DT_SOCK, DT_LNK };
+#define EXTFTODT(x) (x) > sizeof(dtmap) / sizeof(dtmap[0]) ? \
+ DT_UNKNOWN : dtmap[x]
+
+struct fs_ops ext2fs_fsops = {
+ "ext2fs",
+ ext2fs_open,
+ ext2fs_close,
+ ext2fs_read,
+ null_write,
+ ext2fs_seek,
+ ext2fs_stat,
+ ext2fs_readdir
+};
+
+#define EXT2_SBSIZE 1024
+#define EXT2_SBLOCK (1024 / DEV_BSIZE) /* block offset of superblock */
+#define EXT2_MAGIC 0xef53
+#define EXT2_ROOTINO 2
+
+#define EXT2_REV0 0 /* original revision of ext2 */
+#define EXT2_R0_ISIZE 128 /* inode size */
+#define EXT2_R0_FIRSTINO 11 /* first inode */
+
+#define EXT2_MINBSHIFT 10 /* mininum block shift */
+#define EXT2_MINFSHIFT 10 /* mininum frag shift */
+
+#define NDADDR 12 /* # of direct blocks */
+#define NIADDR 3 /* # of indirect blocks */
+
+/*
+ * file system block to disk address
+ */
+#define fsb_to_db(fs, blk) ((blk) << (fs)->fs_fsbtodb)
+
+/*
+ * inode to block group offset
+ * inode to block group
+ * inode to disk address
+ * inode to block offset
+ */
+#define ino_to_bgo(fs, ino) (((ino) - 1) % (fs)->fs_ipg)
+#define ino_to_bg(fs, ino) (((ino) - 1) / (fs)->fs_ipg)
+#define ino_to_db(fs, bg, ino) \
+ fsb_to_db(fs, ((bg)[ino_to_bg(fs, ino)].bg_inotbl + \
+ ino_to_bgo(fs, ino) / (fs)->fs_ipb))
+#define ino_to_bo(fs, ino) (ino_to_bgo(fs, ino) % (fs)->fs_ipb)
+
+#define nindir(fs) \
+ ((fs)->fs_bsize / sizeof(u_int32_t))
+#define lblkno(fs, loc) /* loc / bsize */ \
+ ((loc) >> (fs)->fs_bshift)
+#define smalllblktosize(fs, blk) /* blk * bsize */ \
+ ((blk) << (fs)->fs_bshift)
+#define blkoff(fs, loc) /* loc % bsize */ \
+ ((loc) & (fs)->fs_bmask)
+#define fragroundup(fs, size) /* roundup(size, fsize) */ \
+ (((size) + (fs)->fs_fmask) & ~(fs)->fs_fmask)
+#define dblksize(fs, dip, lbn) \
+ (((lbn) >= NDADDR || (dip)->di_size >= smalllblktosize(fs, (lbn) + 1)) \
+ ? (fs)->fs_bsize \
+ : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
+
+/*
+ * superblock describing ext2fs
+ */
+struct ext2fs_disk {
+ u_int32_t fd_inodes; /* # of inodes */
+ u_int32_t fd_blocks; /* # of blocks */
+ u_int32_t fd_resblk; /* # of reserved blocks */
+ u_int32_t fd_freeblk; /* # of free blocks */
+ u_int32_t fd_freeino; /* # of free inodes */
+ u_int32_t fd_firstblk; /* first data block */
+ u_int32_t fd_bsize; /* block size */
+ u_int32_t fd_fsize; /* frag size */
+ u_int32_t fd_bpg; /* blocks per group */
+ u_int32_t fd_fpg; /* frags per group */
+ u_int32_t fd_ipg; /* inodes per group */
+ u_int32_t fd_mtime; /* mount time */
+ u_int32_t fd_wtime; /* write time */
+ u_int16_t fd_mount; /* # of mounts */
+ int16_t fd_maxmount; /* max # of mounts */
+ u_int16_t fd_magic; /* magic number */
+ u_int16_t fd_state; /* state */
+ u_int16_t fd_eflag; /* error flags */
+ u_int16_t fd_mnrrev; /* minor revision */
+ u_int32_t fd_lastchk; /* last check */
+ u_int32_t fd_chkintvl; /* maximum check interval */
+ u_int32_t fd_os; /* os */
+ u_int32_t fd_revision; /* revision */
+ u_int16_t fd_uid; /* uid for reserved blocks */
+ u_int16_t fd_gid; /* gid for reserved blocks */
+
+ u_int32_t fd_firstino; /* first non-reserved inode */
+ u_int16_t fd_isize; /* inode size */
+ u_int16_t fd_nblkgrp; /* block group # of superblock */
+ u_int32_t fd_fcompat; /* compatible features */
+ u_int32_t fd_fincompat; /* incompatible features */
+ u_int32_t fd_frocompat; /* read-only compatibilties */
+ u_int8_t fd_uuid[16]; /* volume uuid */
+ char fd_volname[16]; /* volume name */
+ char fd_fsmnt[64]; /* name last mounted on */
+ u_int32_t fd_bitmap; /* compression bitmap */
+
+ u_int8_t fd_nblkpa; /* # of blocks to preallocate */
+ u_int8_t fd_ndblkpa; /* # of dir blocks to preallocate */
+};
+
+struct ext2fs_core {
+ int fc_bsize; /* block size */
+ int fc_bshift; /* block shift amount */
+ int fc_bmask; /* block mask */
+ int fc_fsize; /* frag size */
+ int fc_fshift; /* frag shift amount */
+ int fc_fmask; /* frag mask */
+ int fc_isize; /* inode size */
+ int fc_imask; /* inode mask */
+ int fc_firstino; /* first non-reserved inode */
+ int fc_ipb; /* inodes per block */
+ int fc_fsbtodb; /* fsb to ds shift */
+};
+
+struct ext2fs {
+ struct ext2fs_disk fs_fd;
+ char fs_pad[EXT2_SBSIZE - sizeof(struct ext2fs_disk)];
+ struct ext2fs_core fs_fc;
+
+#define fs_magic fs_fd.fd_magic
+#define fs_revision fs_fd.fd_revision
+#define fs_blocks fs_fd.fd_blocks
+#define fs_firstblk fs_fd.fd_firstblk
+#define fs_bpg fs_fd.fd_bpg
+#define fs_ipg fs_fd.fd_ipg
+
+#define fs_bsize fs_fc.fc_bsize
+#define fs_bshift fs_fc.fc_bshift
+#define fs_bmask fs_fc.fc_bmask
+#define fs_fsize fs_fc.fc_fsize
+#define fs_fshift fs_fc.fc_fshift
+#define fs_fmask fs_fc.fc_fmask
+#define fs_isize fs_fc.fc_isize
+#define fs_imask fs_fc.fc_imask
+#define fs_firstino fs_fc.fc_firstino
+#define fs_ipb fs_fc.fc_ipb
+#define fs_fsbtodb fs_fc.fc_fsbtodb
+};
+
+struct ext2blkgrp {
+ u_int32_t bg_blkmap; /* block bitmap */
+ u_int32_t bg_inomap; /* inode bitmap */
+ u_int32_t bg_inotbl; /* inode table */
+ u_int16_t bg_nfblk; /* # of free blocks */
+ u_int16_t bg_nfino; /* # of free inodes */
+ u_int16_t bg_ndirs; /* # of dirs */
+ char bg_pad[14];
+};
+
+struct ext2dinode {
+ u_int16_t di_mode; /* mode */
+ u_int16_t di_uid; /* uid */
+ u_int32_t di_size; /* byte size */
+ u_int32_t di_atime; /* access time */
+ u_int32_t di_ctime; /* creation time */
+ u_int32_t di_mtime; /* modification time */
+ u_int32_t di_dtime; /* deletion time */
+ u_int16_t di_gid; /* gid */
+ u_int16_t di_nlink; /* link count */
+ u_int32_t di_nblk; /* block count */
+ u_int32_t di_flags; /* file flags */
+
+ u_int32_t di_osdep1; /* os dependent stuff */
+
+ u_int32_t di_db[NDADDR]; /* direct blocks */
+ u_int32_t di_ib[NIADDR]; /* indirect blocks */
+ u_int32_t di_version; /* version */
+ u_int32_t di_facl; /* file acl */
+ u_int32_t di_dacl; /* dir acl */
+ u_int32_t di_faddr; /* fragment addr */
+
+ u_int8_t di_frag; /* fragment number */
+ u_int8_t di_fsize; /* fragment size */
+
+ char di_pad[10];
+
+#define di_shortlink di_db
+};
+
+#define EXT2_MAXNAMLEN 255
+
+struct ext2dirent {
+ u_int32_t d_ino; /* inode */
+ u_int16_t d_reclen; /* directory entry length */
+ u_int8_t d_namlen; /* name length */
+ u_int8_t d_type; /* file type */
+ char d_name[EXT2_MAXNAMLEN];
+};
+
+struct file {
+ off_t f_seekp; /* seek pointer */
+ struct ext2fs *f_fs; /* pointer to super-block */
+ struct ext2blkgrp *f_bg; /* pointer to blkgrp map */
+ struct ext2dinode f_di; /* copy of on-disk inode */
+ int f_nindir[NIADDR]; /* number of blocks mapped by
+ indirect block at level i */
+ char *f_blk[NIADDR]; /* buffer for indirect block
+ at level i */
+ size_t f_blksize[NIADDR]; /* size of buffer */
+ daddr_t f_blkno[NIADDR]; /* disk address of block in
+ buffer */
+ char *f_buf; /* buffer for data block */
+ size_t f_buf_size; /* size of data block */
+ daddr_t f_buf_blkno; /* block number of data block */
+};
+
+/* forward decls */
+static int read_inode(ino_t inumber, struct open_file *f);
+static int block_map(struct open_file *f, daddr_t file_block,
+ daddr_t *disk_block_p);
+static int buf_read_file(struct open_file *f, char **buf_p,
+ size_t *size_p);
+static int search_directory(char *name, struct open_file *f,
+ ino_t *inumber_p);
+
+/*
+ * Open a file.
+ */
+static int
+ext2fs_open(const char *upath, struct open_file *f)
+{
+ struct file *fp;
+ struct ext2fs *fs;
+ size_t buf_size;
+ ino_t inumber, parent_inumber;
+ int i, len, groups, bg_per_blk, blkgrps, mult;
+ int nlinks = 0;
+ int error = 0;
+ char *cp, *ncp, *path = NULL, *buf = NULL;
+ char namebuf[MAXPATHLEN+1];
+ char c;
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ if (fp == NULL)
+ return (ENOMEM);
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ /* allocate space and read super block */
+ fs = (struct ext2fs *)malloc(sizeof(*fs));
+ fp->f_fs = fs;
+ twiddle(1);
+ error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ EXT2_SBLOCK, EXT2_SBSIZE, (char *)fs, &buf_size);
+ if (error)
+ goto out;
+
+ if (buf_size != EXT2_SBSIZE || fs->fs_magic != EXT2_MAGIC) {
+ error = EINVAL;
+ goto out;
+ }
+
+ /*
+ * compute in-core values for the superblock
+ */
+ fs->fs_bshift = EXT2_MINBSHIFT + fs->fs_fd.fd_bsize;
+ fs->fs_bsize = 1 << fs->fs_bshift;
+ fs->fs_bmask = fs->fs_bsize - 1;
+
+ fs->fs_fshift = EXT2_MINFSHIFT + fs->fs_fd.fd_fsize;
+ fs->fs_fsize = 1 << fs->fs_fshift;
+ fs->fs_fmask = fs->fs_fsize - 1;
+
+ if (fs->fs_revision == EXT2_REV0) {
+ fs->fs_isize = EXT2_R0_ISIZE;
+ fs->fs_firstino = EXT2_R0_FIRSTINO;
+ } else {
+ fs->fs_isize = fs->fs_fd.fd_isize;
+ fs->fs_firstino = fs->fs_fd.fd_firstino;
+ }
+ fs->fs_imask = fs->fs_isize - 1;
+ fs->fs_ipb = fs->fs_bsize / fs->fs_isize;
+ fs->fs_fsbtodb = (fs->fs_bsize / DEV_BSIZE) - 1;
+
+ /*
+ * we have to load in the "group descriptors" here
+ */
+ groups = howmany(fs->fs_blocks - fs->fs_firstblk, fs->fs_bpg);
+ bg_per_blk = fs->fs_bsize / sizeof(struct ext2blkgrp);
+ blkgrps = howmany(groups, bg_per_blk);
+ len = blkgrps * fs->fs_bsize;
+
+ fp->f_bg = malloc(len);
+ twiddle(1);
+ error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ EXT2_SBLOCK + EXT2_SBSIZE / DEV_BSIZE, len,
+ (char *)fp->f_bg, &buf_size);
+ if (error)
+ goto out;
+
+ /*
+ * XXX
+ * validation of values? (blocksize, descriptors, etc?)
+ */
+
+ /*
+ * Calculate indirect block levels.
+ */
+ mult = 1;
+ for (i = 0; i < NIADDR; i++) {
+ mult *= nindir(fs);
+ fp->f_nindir[i] = mult;
+ }
+
+ inumber = EXT2_ROOTINO;
+ if ((error = read_inode(inumber, f)) != 0)
+ goto out;
+
+ path = strdup(upath);
+ if (path == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ cp = path;
+ while (*cp) {
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+ if (*cp == '\0')
+ break;
+
+ /*
+ * Check that current node is a directory.
+ */
+ if (! S_ISDIR(fp->f_di.di_mode)) {
+ error = ENOTDIR;
+ goto out;
+ }
+
+ /*
+ * Get next component of path name.
+ */
+ len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > EXT2_MAXNAMLEN) {
+ error = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+
+ /*
+ * Look up component in current directory.
+ * Save directory inumber in case we find a
+ * symbolic link.
+ */
+ parent_inumber = inumber;
+ error = search_directory(ncp, f, &inumber);
+ *cp = c;
+ if (error)
+ goto out;
+
+ /*
+ * Open next component.
+ */
+ if ((error = read_inode(inumber, f)) != 0)
+ goto out;
+
+ /*
+ * Check for symbolic link.
+ */
+ if (S_ISLNK(fp->f_di.di_mode)) {
+ int link_len = fp->f_di.di_size;
+ int len;
+
+ len = strlen(cp);
+ if (link_len + len > MAXPATHLEN ||
+ ++nlinks > MAXSYMLINKS) {
+ error = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+ if (fp->f_di.di_nblk == 0) {
+ bcopy(fp->f_di.di_shortlink,
+ namebuf, link_len);
+ } else {
+ /*
+ * Read file for symbolic link
+ */
+ struct ext2fs *fs = fp->f_fs;
+ daddr_t disk_block;
+ size_t buf_size;
+
+ if (! buf)
+ buf = malloc(fs->fs_bsize);
+ error = block_map(f, (daddr_t)0, &disk_block);
+ if (error)
+ goto out;
+
+ twiddle(1);
+ error = (f->f_dev->dv_strategy)(f->f_devdata,
+ F_READ, fsb_to_db(fs, disk_block),
+ fs->fs_bsize, buf, &buf_size);
+ if (error)
+ goto out;
+
+ bcopy((char *)buf, namebuf, link_len);
+ }
+
+ /*
+ * If relative pathname, restart at parent directory.
+ * If absolute pathname, restart at root.
+ */
+ cp = namebuf;
+ if (*cp != '/')
+ inumber = parent_inumber;
+ else
+ inumber = (ino_t)EXT2_ROOTINO;
+
+ if ((error = read_inode(inumber, f)) != 0)
+ goto out;
+ }
+ }
+
+ /*
+ * Found terminal component.
+ */
+ error = 0;
+ fp->f_seekp = 0;
+out:
+ if (buf)
+ free(buf);
+ if (path)
+ free(path);
+ if (error) {
+ if (fp->f_buf)
+ free(fp->f_buf);
+ free(fp->f_fs);
+ free(fp);
+ }
+ return (error);
+}
+
+/*
+ * Read a new inode into a file structure.
+ */
+static int
+read_inode(ino_t inumber, struct open_file *f)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct ext2fs *fs = fp->f_fs;
+ struct ext2dinode *dp;
+ char *buf;
+ size_t rsize;
+ int level, error = 0;
+
+ /*
+ * Read inode and save it.
+ */
+ buf = malloc(fs->fs_bsize);
+ twiddle(1);
+ error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ ino_to_db(fs, fp->f_bg, inumber), fs->fs_bsize, buf, &rsize);
+ if (error)
+ goto out;
+ if (rsize != fs->fs_bsize) {
+ error = EIO;
+ goto out;
+ }
+
+ dp = (struct ext2dinode *)buf;
+ fp->f_di = dp[ino_to_bo(fs, inumber)];
+
+ /* clear out old buffers */
+ for (level = 0; level < NIADDR; level++)
+ fp->f_blkno[level] = -1;
+ fp->f_buf_blkno = -1;
+ fp->f_seekp = 0;
+
+out:
+ free(buf);
+ return (error);
+}
+
+/*
+ * Given an offset in a file, find the disk block number that
+ * contains that block.
+ */
+static int
+block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct ext2fs *fs = fp->f_fs;
+ daddr_t ind_block_num;
+ int32_t *ind_p;
+ int idx, level;
+ int error;
+
+ /*
+ * Index structure of an inode:
+ *
+ * di_db[0..NDADDR-1] hold block numbers for blocks
+ * 0..NDADDR-1
+ *
+ * di_ib[0] index block 0 is the single indirect block
+ * holds block numbers for blocks
+ * NDADDR .. NDADDR + NINDIR(fs)-1
+ *
+ * di_ib[1] index block 1 is the double indirect block
+ * holds block numbers for INDEX blocks for blocks
+ * NDADDR + NINDIR(fs) ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
+ *
+ * di_ib[2] index block 2 is the triple indirect block
+ * holds block numbers for double-indirect
+ * blocks for blocks
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2
+ * + NINDIR(fs)**3 - 1
+ */
+
+ if (file_block < NDADDR) {
+ /* Direct block. */
+ *disk_block_p = fp->f_di.di_db[file_block];
+ return (0);
+ }
+
+ file_block -= NDADDR;
+
+ /*
+ * nindir[0] = NINDIR
+ * nindir[1] = NINDIR**2
+ * nindir[2] = NINDIR**3
+ * etc
+ */
+ for (level = 0; level < NIADDR; level++) {
+ if (file_block < fp->f_nindir[level])
+ break;
+ file_block -= fp->f_nindir[level];
+ }
+ if (level == NIADDR) {
+ /* Block number too high */
+ return (EFBIG);
+ }
+
+ ind_block_num = fp->f_di.di_ib[level];
+
+ for (; level >= 0; level--) {
+ if (ind_block_num == 0) {
+ *disk_block_p = 0; /* missing */
+ return (0);
+ }
+
+ if (fp->f_blkno[level] != ind_block_num) {
+ if (fp->f_blk[level] == (char *)0)
+ fp->f_blk[level] =
+ malloc(fs->fs_bsize);
+ twiddle(1);
+ error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsb_to_db(fp->f_fs, ind_block_num), fs->fs_bsize,
+ fp->f_blk[level], &fp->f_blksize[level]);
+ if (error)
+ return (error);
+ if (fp->f_blksize[level] != fs->fs_bsize)
+ return (EIO);
+ fp->f_blkno[level] = ind_block_num;
+ }
+
+ ind_p = (int32_t *)fp->f_blk[level];
+
+ if (level > 0) {
+ idx = file_block / fp->f_nindir[level - 1];
+ file_block %= fp->f_nindir[level - 1];
+ } else {
+ idx = file_block;
+ }
+ ind_block_num = ind_p[idx];
+ }
+
+ *disk_block_p = ind_block_num;
+
+ return (0);
+}
+
+/*
+ * Read a portion of a file into an internal buffer. Return
+ * the location in the buffer and the amount in the buffer.
+ */
+static int
+buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct ext2fs *fs = fp->f_fs;
+ long off;
+ daddr_t file_block;
+ daddr_t disk_block;
+ size_t block_size;
+ int error = 0;
+
+ off = blkoff(fs, fp->f_seekp);
+ file_block = lblkno(fs, fp->f_seekp);
+ block_size = dblksize(fs, &fp->f_di, file_block);
+
+ if (file_block != fp->f_buf_blkno) {
+ error = block_map(f, file_block, &disk_block);
+ if (error)
+ goto done;
+
+ if (fp->f_buf == (char *)0)
+ fp->f_buf = malloc(fs->fs_bsize);
+
+ if (disk_block == 0) {
+ bzero(fp->f_buf, block_size);
+ fp->f_buf_size = block_size;
+ } else {
+ twiddle(4);
+ error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsb_to_db(fs, disk_block), block_size,
+ fp->f_buf, &fp->f_buf_size);
+ if (error)
+ goto done;
+ }
+ fp->f_buf_blkno = file_block;
+ }
+
+ /*
+ * Return address of byte in buffer corresponding to
+ * offset, and size of remainder of buffer after that
+ * byte.
+ */
+ *buf_p = fp->f_buf + off;
+ *size_p = block_size - off;
+
+ /*
+ * But truncate buffer at end of file.
+ */
+ if (*size_p > fp->f_di.di_size - fp->f_seekp)
+ *size_p = fp->f_di.di_size - fp->f_seekp;
+done:
+ return (error);
+}
+
+/*
+ * Search a directory for a name and return its
+ * i_number.
+ */
+static int
+search_directory(char *name, struct open_file *f, ino_t *inumber_p)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct ext2dirent *dp, *edp;
+ char *buf;
+ size_t buf_size;
+ int namlen, length;
+ int error;
+
+ length = strlen(name);
+ fp->f_seekp = 0;
+ while (fp->f_seekp < fp->f_di.di_size) {
+ error = buf_read_file(f, &buf, &buf_size);
+ if (error)
+ return (error);
+ dp = (struct ext2dirent *)buf;
+ edp = (struct ext2dirent *)(buf + buf_size);
+ while (dp < edp) {
+ if (dp->d_ino == (ino_t)0)
+ goto next;
+ namlen = dp->d_namlen;
+ if (namlen == length &&
+ strncmp(name, dp->d_name, length) == 0) {
+ /* found entry */
+ *inumber_p = dp->d_ino;
+ return (0);
+ }
+ next:
+ dp = (struct ext2dirent *)((char *)dp + dp->d_reclen);
+ }
+ fp->f_seekp += buf_size;
+ }
+ return (ENOENT);
+}
+
+static int
+ext2fs_close(struct open_file *f)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ int level;
+
+ f->f_fsdata = (void *)0;
+ if (fp == (struct file *)0)
+ return (0);
+
+ for (level = 0; level < NIADDR; level++) {
+ if (fp->f_blk[level])
+ free(fp->f_blk[level]);
+ }
+ if (fp->f_buf)
+ free(fp->f_buf);
+ if (fp->f_bg)
+ free(fp->f_bg);
+ free(fp->f_fs);
+ free(fp);
+ return (0);
+}
+
+static int
+ext2fs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ size_t csize, buf_size;
+ char *buf;
+ int error = 0;
+
+ while (size != 0) {
+ if (fp->f_seekp >= fp->f_di.di_size)
+ break;
+
+ error = buf_read_file(f, &buf, &buf_size);
+ if (error)
+ break;
+
+ csize = size;
+ if (csize > buf_size)
+ csize = buf_size;
+
+ bcopy(buf, addr, csize);
+
+ fp->f_seekp += csize;
+ addr = (char *)addr + csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (error);
+}
+
+static off_t
+ext2fs_seek(struct open_file *f, off_t offset, int where)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seekp = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seekp += offset;
+ break;
+ case SEEK_END:
+ fp->f_seekp = fp->f_di.di_size - offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (fp->f_seekp);
+}
+
+static int
+ext2fs_stat(struct open_file *f, struct stat *sb)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = fp->f_di.di_mode;
+ sb->st_uid = fp->f_di.di_uid;
+ sb->st_gid = fp->f_di.di_gid;
+ sb->st_size = fp->f_di.di_size;
+ return (0);
+}
+
+static int
+ext2fs_readdir(struct open_file *f, struct dirent *d)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct ext2dirent *ed;
+ char *buf;
+ size_t buf_size;
+ int error;
+
+ /*
+ * assume that a directory entry will not be split across blocks
+ */
+again:
+ if (fp->f_seekp >= fp->f_di.di_size)
+ return (ENOENT);
+ error = buf_read_file(f, &buf, &buf_size);
+ if (error)
+ return (error);
+ ed = (struct ext2dirent *)buf;
+ fp->f_seekp += ed->d_reclen;
+ if (ed->d_ino == (ino_t)0)
+ goto again;
+ d->d_type = EXTFTODT(ed->d_type);
+ strncpy(d->d_name, ed->d_name, ed->d_namlen);
+ d->d_name[ed->d_namlen] = '\0';
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/fstat.c b/usr/src/boot/lib/libstand/fstat.c
new file mode 100644
index 0000000000..13bed08d08
--- /dev/null
+++ b/usr/src/boot/lib/libstand/fstat.c
@@ -0,0 +1,61 @@
+/* $NetBSD: fstat.c,v 1.1 1996/01/13 22:25:38 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stat.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+int
+fstat(fd, sb)
+ int fd;
+ struct stat *sb;
+{
+ struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ /* operation not defined on raw devices */
+ if (f->f_flags & F_RAW) {
+ errno = EOPNOTSUPP;
+ return (-1);
+ }
+
+ errno = (f->f_ops->fo_stat)(f, sb);
+ if (errno)
+ return (-1);
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/getopt.c b/usr/src/boot/lib/libstand/getopt.c
new file mode 100644
index 0000000000..cfe405a85d
--- /dev/null
+++ b/usr/src/boot/lib/libstand/getopt.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <string.h>
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(int nargc, char * const *nargv, const char *ostr)
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)printf("illegal option -- %c\n", optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)printf("option requires an argument -- %c\n", optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
diff --git a/usr/src/boot/lib/libstand/gets.c b/usr/src/boot/lib/libstand/gets.c
new file mode 100644
index 0000000000..7d54b00017
--- /dev/null
+++ b/usr/src/boot/lib/libstand/gets.c
@@ -0,0 +1,112 @@
+/* $NetBSD: gets.c,v 1.6 1995/10/11 21:16:57 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)gets.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+/* gets() with constrained input length */
+
+void
+ngets(char *buf, int n)
+{
+ int c;
+ char *lp;
+
+ for (lp = buf;;)
+ switch (c = getchar() & 0177) {
+ case '\n':
+ case '\r':
+ *lp = '\0';
+ putchar('\n');
+ return;
+ case '\b':
+ case '\177':
+ if (lp > buf) {
+ lp--;
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ }
+ break;
+ case 'r'&037: {
+ char *p;
+
+ putchar('\n');
+ for (p = buf; p < lp; ++p)
+ putchar(*p);
+ break;
+ }
+ case 'u'&037:
+ case 'w'&037:
+ lp = buf;
+ putchar('\n');
+ break;
+ default:
+ if ((n < 1) || ((lp - buf) < n - 1)) {
+ *lp++ = c;
+ putchar(c);
+ }
+ }
+ /*NOTREACHED*/
+}
+
+int
+fgetstr(char *buf, int size, int fd)
+{
+ char c;
+ int err, len;
+
+ size--; /* leave space for terminator */
+ len = 0;
+ while (size != 0) {
+ err = read(fd, &c, sizeof(c));
+ if (err < 0) /* read error */
+ return(-1);
+ if (err == 0) { /* EOF */
+ if (len == 0)
+ return(-1); /* nothing to read */
+ break;
+ }
+ if ((c == '\r') || /* line terminators */
+ (c == '\n'))
+ break;
+ *buf++ = c; /* keep char */
+ size--;
+ len++;
+ }
+ *buf = 0;
+ return(len);
+}
+
diff --git a/usr/src/boot/lib/libstand/globals.c b/usr/src/boot/lib/libstand/globals.c
new file mode 100644
index 0000000000..03108232ff
--- /dev/null
+++ b/usr/src/boot/lib/libstand/globals.c
@@ -0,0 +1,36 @@
+/* $NetBSD: globals.c,v 1.3 1995/09/18 21:19:27 pk Exp $ */
+
+/*
+ * globals.c:
+ *
+ * global variables should be separate, so nothing else
+ * must be included extraneously.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+
+u_char bcea[6] = BA; /* broadcast ethernet address */
+
+char rootpath[FNAME_SIZE] = "/"; /* root mount path */
+char bootfile[FNAME_SIZE]; /* bootp says to boot this */
+char hostname[FNAME_SIZE]; /* our hostname */
+int hostnamelen;
+char domainname[FNAME_SIZE]; /* our DNS domain */
+int domainnamelen;
+char ifname[IFNAME_SIZE]; /* name of interface (e.g. "le0") */
+struct in_addr myip; /* my ip address */
+struct in_addr nameip; /* DNS server ip address */
+struct in_addr rootip; /* root ip address */
+struct in_addr swapip; /* swap ip address */
+struct in_addr gateip; /* swap ip address */
+n_long netmask = 0xffffff00; /* subnet or net mask */
+int errno; /* our old friend */
+
diff --git a/usr/src/boot/lib/libstand/gzipfs.c b/usr/src/boot/lib/libstand/gzipfs.c
new file mode 100644
index 0000000000..1db7ad095b
--- /dev/null
+++ b/usr/src/boot/lib/libstand/gzipfs.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include <zlib.h>
+
+#define Z_BUFSIZE 2048 /* XXX larger? */
+
+struct z_file
+{
+ int zf_rawfd;
+ off_t zf_dataoffset;
+ z_stream zf_zstream;
+ char zf_buf[Z_BUFSIZE];
+ int zf_endseen;
+};
+
+static int zf_fill(struct z_file *z);
+static int zf_open(const char *path, struct open_file *f);
+static int zf_close(struct open_file *f);
+static int zf_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t zf_seek(struct open_file *f, off_t offset, int where);
+static int zf_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops gzipfs_fsops = {
+ "zip",
+ zf_open,
+ zf_close,
+ zf_read,
+ null_write,
+ zf_seek,
+ zf_stat,
+ null_readdir
+};
+
+static int
+zf_fill(struct z_file *zf)
+{
+ int result;
+ int req;
+
+ req = Z_BUFSIZE - zf->zf_zstream.avail_in;
+ result = 0;
+
+ /* If we need more */
+ if (req > 0) {
+ /* move old data to bottom of buffer */
+ if (req < Z_BUFSIZE)
+ bcopy(zf->zf_buf + req, zf->zf_buf, Z_BUFSIZE - req);
+
+ /* read to fill buffer and update availibility data */
+ result = read(zf->zf_rawfd, zf->zf_buf + zf->zf_zstream.avail_in, req);
+ zf->zf_zstream.next_in = zf->zf_buf;
+ if (result >= 0)
+ zf->zf_zstream.avail_in += result;
+ }
+ return(result);
+}
+
+/*
+ * Adapted from get_byte/check_header in libz
+ *
+ * Returns 0 if the header is OK, nonzero if not.
+ */
+static int
+get_byte(struct z_file *zf, off_t *curoffp)
+{
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1))
+ return(-1);
+ zf->zf_zstream.avail_in--;
+ ++*curoffp;
+ return(*(zf->zf_zstream.next_in)++);
+}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int
+check_header(struct z_file *zf)
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ zf->zf_dataoffset = 0;
+ /* Check the gzip magic header */
+ for (len = 0; len < 2; len++) {
+ c = get_byte(zf, &zf->zf_dataoffset);
+ if (c != gz_magic[len]) {
+ return(1);
+ }
+ }
+ method = get_byte(zf, &zf->zf_dataoffset);
+ flags = get_byte(zf, &zf->zf_dataoffset);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ return(1);
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(zf, &zf->zf_dataoffset);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(zf, &zf->zf_dataoffset);
+ len += ((uInt)get_byte(zf, &zf->zf_dataoffset))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(zf, &zf->zf_dataoffset) != -1) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(zf, &zf->zf_dataoffset)) != 0 && c != -1) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(zf, &zf->zf_dataoffset)) != 0 && c != -1) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) c = get_byte(zf, &zf->zf_dataoffset);
+ }
+ /* if there's data left, we're in business */
+ return((c == -1) ? 1 : 0);
+}
+
+static int
+zf_open(const char *fname, struct open_file *f)
+{
+ char *zfname;
+ int rawfd;
+ struct z_file *zf;
+ char *cp;
+ int error;
+ struct stat sb;
+
+ /* Have to be in "just read it" mode */
+ if (f->f_flags != F_READ)
+ return(EPERM);
+
+ /* If the name already ends in .gz or .bz2, ignore it */
+ if ((cp = strrchr(fname, '.')) && (!strcmp(cp, ".gz")
+ || !strcmp(cp, ".bz2") || !strcmp(cp, ".split")))
+ return(ENOENT);
+
+ /* Try to open the compressed datafile */
+ rawfd = open(fname, O_RDONLY | F_GZIP);
+ if (rawfd == -1) {
+ /* add .gz sufix and try again */
+ zfname = malloc(strlen(fname) + 4);
+ if (zfname == NULL)
+ return(ENOMEM);
+ sprintf(zfname, "%s.gz", fname);
+ rawfd = open(zfname, O_RDONLY);
+ free(zfname);
+ if (rawfd == -1)
+ return(ENOENT);
+ }
+
+ if (fstat(rawfd, &sb) < 0) {
+ printf("zf_open: stat failed\n");
+ close(rawfd);
+ return(ENOENT);
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ close(rawfd);
+ return(EISDIR); /* best guess */
+ }
+
+ /* Allocate a z_file structure, populate it */
+ zf = malloc(sizeof(struct z_file));
+ if (zf == NULL)
+ return(ENOMEM);
+ bzero(zf, sizeof(struct z_file));
+ zf->zf_rawfd = rawfd;
+
+ /* Verify that the file is gzipped */
+ if (check_header(zf)) {
+ close(zf->zf_rawfd);
+ free(zf);
+ return(EFTYPE);
+ }
+
+ /* Initialise the inflation engine */
+ if ((error = inflateInit2(&(zf->zf_zstream), -15)) != Z_OK) {
+ printf("zf_open: inflateInit returned %d : %s\n", error, zf->zf_zstream.msg);
+ close(zf->zf_rawfd);
+ free(zf);
+ return(EIO);
+ }
+
+ /* Looks OK, we'll take it */
+ f->f_fsdata = zf;
+ return(0);
+}
+
+static int
+zf_close(struct open_file *f)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+
+ inflateEnd(&(zf->zf_zstream));
+ close(zf->zf_rawfd);
+ free(zf);
+ return(0);
+}
+
+static int
+zf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int error;
+
+ zf->zf_zstream.next_out = buf; /* where and how much */
+ zf->zf_zstream.avail_out = size;
+
+ while (zf->zf_zstream.avail_out && zf->zf_endseen == 0) {
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1)) {
+ printf("zf_read: fill error\n");
+ return(EIO);
+ }
+ if (zf->zf_zstream.avail_in == 0) { /* oops, unexpected EOF */
+ printf("zf_read: unexpected EOF\n");
+ if (zf->zf_zstream.avail_out == size)
+ return(EIO);
+ break;
+ }
+
+ error = inflate(&zf->zf_zstream, Z_SYNC_FLUSH); /* decompression pass */
+ if (error == Z_STREAM_END) { /* EOF, all done */
+ zf->zf_endseen = 1;
+ break;
+ }
+ if (error != Z_OK) { /* argh, decompression error */
+ printf("inflate: %s\n", zf->zf_zstream.msg);
+ return(EIO);
+ }
+ }
+ if (resid != NULL)
+ *resid = zf->zf_zstream.avail_out;
+ return(0);
+}
+
+static int
+zf_rewind(struct open_file *f)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+
+ if (lseek(zf->zf_rawfd, zf->zf_dataoffset, SEEK_SET) == -1)
+ return(-1);
+ zf->zf_zstream.avail_in = 0;
+ zf->zf_zstream.next_in = NULL;
+ zf->zf_endseen = 0;
+ (void)inflateReset(&zf->zf_zstream);
+
+ return(0);
+}
+
+static off_t
+zf_seek(struct open_file *f, off_t offset, int where)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ off_t target;
+ char discard[16];
+
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = offset + zf->zf_zstream.total_out;
+ break;
+ case SEEK_END:
+ target = -1;
+ default:
+ errno = EINVAL;
+ return(-1);
+ }
+
+ /* rewind if required */
+ if (target < zf->zf_zstream.total_out && zf_rewind(f) != 0)
+ return(-1);
+
+ /* skip forwards if required */
+ while (target > zf->zf_zstream.total_out) {
+ errno = zf_read(f, discard, min(sizeof(discard),
+ target - zf->zf_zstream.total_out), NULL);
+ if (errno)
+ return(-1);
+ }
+ /* This is where we are (be honest if we overshot) */
+ return(zf->zf_zstream.total_out);
+}
+
+
+static int
+zf_stat(struct open_file *f, struct stat *sb)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int result, res;
+ off_t pos1, pos2;
+ uint32_t size;
+
+ /* stat as normal, but indicate that size is unknown */
+ if ((result = fstat(zf->zf_rawfd, sb)) == 0) {
+ if (sb->st_size == -1)
+ return (result);
+ pos1 = lseek(zf->zf_rawfd, 0, SEEK_CUR);
+ pos2 = lseek(zf->zf_rawfd, sb->st_size - 4, SEEK_SET);
+ if (pos2 != -1) {
+ if (read(zf->zf_rawfd, &size, 4) == 4)
+ sb->st_size = (off_t) size;
+ else
+ sb->st_size = -1;
+ } else
+ sb->st_size = -1;
+
+ pos1 = lseek(zf->zf_rawfd, pos1, SEEK_SET);
+ }
+ return(result);
+}
diff --git a/usr/src/boot/lib/libstand/i386/_setjmp.S b/usr/src/boot/lib/libstand/i386/_setjmp.S
new file mode 100644
index 0000000000..cc9de5cdb8
--- /dev/null
+++ b/usr/src/boot/lib/libstand/i386/_setjmp.S
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is NOT restored.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(_setjmp)
+ movl 4(%esp),%eax
+ movl 0(%esp),%edx
+ movl %edx, 0(%eax) /* rta */
+ movl %ebx, 4(%eax)
+ movl %esp, 8(%eax)
+ movl %ebp,12(%eax)
+ movl %esi,16(%eax)
+ movl %edi,20(%eax)
+ xorl %eax,%eax
+ ret
+END(_setjmp)
+
+ENTRY(_longjmp)
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
+END(_longjmp)
diff --git a/usr/src/boot/lib/libstand/in_cksum.c b/usr/src/boot/lib/libstand/in_cksum.c
new file mode 100644
index 0000000000..e6051bf166
--- /dev/null
+++ b/usr/src/boot/lib/libstand/in_cksum.c
@@ -0,0 +1,94 @@
+/* $NetBSD: in_cksum.c,v 1.6 2000/03/31 19:55:09 castor Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: in_cksum.c,v 1.1 92/09/11 01:15:55 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+#include "stand.h"
+
+/*
+ * Checksum routine for Internet Protocol family headers.
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ * In particular, it should not be this one.
+ */
+int
+in_cksum(p, len)
+ void *p;
+ int len;
+{
+ int sum = 0, oddbyte = 0, v = 0;
+ u_char *cp = p;
+
+ /* we assume < 2^16 bytes being summed */
+ while (len > 0) {
+ if (oddbyte) {
+ sum += v + *cp++;
+ len--;
+ }
+ if (((long)cp & 1) == 0) {
+ while ((len -= 2) >= 0) {
+ sum += *(u_short *)cp;
+ cp += 2;
+ }
+ } else {
+ while ((len -= 2) >= 0) {
+#if BYTE_ORDER == BIG_ENDIAN
+ sum += *cp++ << 8;
+ sum += *cp++;
+#else
+ sum += *cp++;
+ sum += *cp++ << 8;
+#endif
+ }
+ }
+ if ((oddbyte = len & 1) != 0)
+#if BYTE_ORDER == BIG_ENDIAN
+ v = *cp << 8;
+#else
+ v = *cp;
+#endif
+ }
+ if (oddbyte)
+ sum += v;
+ sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
+ sum += sum >> 16; /* add potential last carry */
+ return (0xffff & ~sum);
+}
diff --git a/usr/src/boot/lib/libstand/inet_ntoa.c b/usr/src/boot/lib/libstand/inet_ntoa.c
new file mode 100644
index 0000000000..5bc8533541
--- /dev/null
+++ b/usr/src/boot/lib/libstand/inet_ntoa.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "stand.h"
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+char *
+inet_ntoa(in)
+ struct in_addr in;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ static char ret[sizeof "255.255.255.255"];
+ unsigned char *src = (unsigned char *) &in;
+
+ sprintf(ret, fmt, src[0], src[1], src[2], src[3]);
+ return (ret);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_ntoa
+__weak_reference(__inet_ntoa, inet_ntoa);
diff --git a/usr/src/boot/lib/libstand/ioctl.c b/usr/src/boot/lib/libstand/ioctl.c
new file mode 100644
index 0000000000..a4512af05e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/ioctl.c
@@ -0,0 +1,88 @@
+/* $NetBSD: ioctl.c,v 1.4 1994/10/30 21:48:24 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ioctl.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+int
+ioctl(fd, cmd, arg)
+ int fd;
+ u_long cmd;
+ char *arg;
+{
+ struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ errno = (f->f_dev->dv_ioctl)(f, cmd, arg);
+ if (errno)
+ return (-1);
+ return (0);
+ }
+ errno = EIO;
+ return (-1);
+}
diff --git a/usr/src/boot/lib/libstand/iodesc.h b/usr/src/boot/lib/libstand/iodesc.h
new file mode 100644
index 0000000000..0da1946dbf
--- /dev/null
+++ b/usr/src/boot/lib/libstand/iodesc.h
@@ -0,0 +1,52 @@
+/* $NetBSD: iodesc.h,v 1.4 1995/09/23 03:31:50 gwr Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __SYS_LIBNETBOOT_IODESC_H
+#define __SYS_LIBNETBOOT_IODESC_H
+
+struct iodesc {
+ struct in_addr destip; /* dest. ip addr, net order */
+ struct in_addr myip; /* local ip addr, net order */
+ u_short destport; /* dest. port, net order */
+ u_short myport; /* local port, net order */
+ u_long xid; /* transaction identification */
+ u_char myea[6]; /* my ethernet address */
+ struct netif *io_netif;
+};
+
+#endif /* __SYS_LIBNETBOOT_IODESC_H */
diff --git a/usr/src/boot/lib/libstand/libstand.3 b/usr/src/boot/lib/libstand/libstand.3
new file mode 100644
index 0000000000..42289c1bce
--- /dev/null
+++ b/usr/src/boot/lib/libstand/libstand.3
@@ -0,0 +1,676 @@
+.\" Copyright (c) Michael Smith
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 6, 2004
+.Dt LIBSTAND 3
+.Os
+.Sh NAME
+.Nm libstand
+.Nd support library for standalone executables
+.Sh SYNOPSIS
+.In stand.h
+.Sh DESCRIPTION
+The
+.Nm
+library provides a set of supporting functions for standalone
+applications, mimicking where possible the standard
+.Bx
+programming
+environment.
+The following sections group these functions by kind.
+Unless specifically described here, see the corresponding section 3
+manpages for the given functions.
+.Sh STRING FUNCTIONS
+String functions are available as documented in
+.Xr string 3
+and
+.Xr bstring 3 .
+.Sh MEMORY ALLOCATION
+.Bl -hang -width 10n
+.It Xo
+.Ft "void *"
+.Fn malloc "size_t size"
+.Xc
+.Pp
+Allocate
+.Fa size
+bytes of memory from the heap using a best-fit algorithm.
+.It Xo
+.Ft void
+.Fn free "void *ptr"
+.Xc
+.Pp
+Free the allocated object at
+.Fa ptr .
+.It Xo
+.Ft void
+.Fn setheap "void *start" "void *limit"
+.Xc
+.Pp
+Initialise the heap.
+This function must be called before calling
+.Fn alloc
+for the first time.
+The region between
+.Fa start
+and
+.Fa limit
+will be used for the heap; attempting to allocate beyond this will result
+in a panic.
+.It Xo
+.Ft "char *"
+.Fn sbrk "int junk"
+.Xc
+.Pp
+Provides the behaviour of
+.Fn sbrk 0 ,
+i.e., returns the highest point that the heap has reached.
+This value can
+be used during testing to determine the actual heap usage.
+The
+.Fa junk
+argument is ignored.
+.El
+.Sh ENVIRONMENT
+A set of functions are provided for manipulating a flat variable space similar
+to the traditional shell-supported environment.
+Major enhancements are support
+for set/unset hook functions.
+.Bl -hang -width 10n
+.It Xo
+.Ft "char *"
+.Fn getenv "const char *name"
+.Xc
+.It Xo
+.Ft int
+.Fn setenv "const char *name" "const char *value" "int overwrite"
+.Xc
+.It Xo
+.Ft int
+.Fn putenv "const char *string"
+.Xc
+.It Xo
+.Ft int
+.Fn unsetenv "const char *name"
+.Xc
+.Pp
+These functions behave similarly to their standard library counterparts.
+.It Xo
+.Ft "struct env_var *"
+.Fn env_getenv "const char *name"
+.Xc
+.Pp
+Looks up a variable in the environment and returns its entire
+data structure.
+.It Xo
+.Ft int
+.Fn env_setenv "const char *name" "int flags" "const void *value" "ev_sethook_t sethook" "ev_unsethook_t unsethook"
+.Xc
+.Pp
+Creates a new or sets an existing environment variable called
+.Fa name .
+If creating a new variable, the
+.Fa sethook
+and
+.Fa unsethook
+arguments may be specified.
+.Pp
+The set hook is invoked whenever an attempt
+is made to set the variable, unless the EV_NOHOOK flag is set.
+Typically
+a set hook will validate the
+.Fa value
+argument, and then call
+.Fn env_setenv
+again with EV_NOHOOK set to actually save the value.
+The predefined function
+.Fn env_noset
+may be specified to refuse all attempts to set a variable.
+.Pp
+The unset hook is invoked when an attempt is made to unset a variable.
+If it
+returns zero, the variable will be unset.
+The predefined function
+.Fa env_nounset
+may be used to prevent a variable being unset.
+.El
+.Sh STANDARD LIBRARY SUPPORT
+.Bl -hang -width 10n
+.It Xo
+.Ft int
+.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Xc
+.It Xo
+.Ft long
+.Fn strtol "const char *nptr" "char **endptr" "int base"
+.Xc
+.It Xo
+.Ft void
+.Fn srandom "unsigned long seed"
+.Xc
+.It Xo
+.Ft "unsigned long"
+.Fn random void
+.Xc
+.It Xo
+.Ft "char *"
+.Fn strerror "int error"
+.Xc
+.Pp
+Returns error messages for the subset of errno values supported by
+.Nm .
+.It Fn assert expression
+.Pp
+Requires
+.In assert.h .
+.It Xo
+.Ft int
+.Fn setjmp "jmp_buf env"
+.Xc
+.It Xo
+.Ft void
+.Fn longjmp "jmp_buf env" "int val"
+.Xc
+.Pp
+Defined as
+.Fn _setjmp
+and
+.Fn _longjmp
+respectively as there is no signal state to manipulate.
+Requires
+.In setjmp.h .
+.El
+.Sh CHARACTER I/O
+.Bl -hang -width 10n
+.It Xo
+.Ft void
+.Fn gets "char *buf"
+.Xc
+.Pp
+Read characters from the console into
+.Fa buf .
+All of the standard cautions apply to this function.
+.It Xo
+.Ft void
+.Fn ngets "char *buf" "int size"
+.Xc
+.Pp
+Read at most
+.Fa size
+- 1 characters from the console into
+.Fa buf .
+If
+.Fa size
+is less than 1, the function's behaviour is as for
+.Fn gets .
+.It Xo
+.Ft int
+.Fn fgetstr "char *buf" "int size" "int fd"
+.Xc
+.Pp
+Read a line of at most
+.Fa size
+characters into
+.Fa buf .
+Line terminating characters are stripped, and the buffer is always
+.Dv NUL
+terminated.
+Returns the number of characters in
+.Fa buf
+if successful, or -1 if a read error occurs.
+.It Xo
+.Ft int
+.Fn printf "const char *fmt" "..."
+.Xc
+.It Xo
+.Ft void
+.Fn vprintf "const char *fmt" "va_list ap"
+.Xc
+.It Xo
+.Ft int
+.Fn sprintf "char *buf" "const char *fmt" "..."
+.Xc
+.It Xo
+.Ft void
+.Fn vsprintf "char *buf" "const char *fmt" "va_list ap"
+.Xc
+.Pp
+The *printf functions implement a subset of the standard
+.Fn printf
+family functionality and some extensions.
+The following standard conversions
+are supported: c,d,n,o,p,s,u,x.
+The following modifiers are supported:
++,-,#,*,0,field width,precision,l.
+.Pp
+The
+.Li b
+conversion is provided to decode error registers.
+Its usage is:
+.Bd -ragged -offset indent
+printf(
+.Qq reg=%b\en ,
+regval,
+.Qq <base><arg>*
+);
+.Ed
+.Pp
+where <base> is the output expressed as a control character, e.g.\& \e10 gives
+octal, \e20 gives hex.
+Each <arg> is a sequence of characters, the first of
+which gives the bit number to be inspected (origin 1) and the next characters
+(up to a character less than 32) give the text to be displayed if the bit is set.
+Thus
+.Bd -ragged -offset indent
+printf(
+.Qq reg=%b\en ,
+3,
+.Qq \e10\e2BITTWO\e1BITONE
+);
+.Ed
+.Pp
+would give the output
+.Bd -ragged -offset indent
+reg=3<BITTWO,BITONE>
+.Ed
+.Pp
+The
+.Li D
+conversion provides a hexdump facility, e.g.
+.Bd -ragged -offset indent
+printf(
+.Qq %6D ,
+ptr,
+.Qq \&:
+); gives
+.Qq XX:XX:XX:XX:XX:XX
+.Ed
+.Bd -ragged -offset indent
+printf(
+.Qq %*D ,
+len,
+ptr,
+.Qq "\ "
+); gives
+.Qq XX XX XX ...
+.Ed
+.El
+.Sh CHARACTER TESTS AND CONVERSIONS
+.Bl -hang -width 10n
+.It Xo
+.Ft int
+.Fn isupper "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn islower "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isspace "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isdigit "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isxdigit "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isascii "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isalpha "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn toupper "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn tolower "int c"
+.Xc
+.El
+.Sh FILE I/O
+.Bl -hang -width 10n
+.It Xo
+.Ft int
+.Fn open "const char *path" "int flags"
+.Xc
+.Pp
+Similar to the behaviour as specified in
+.Xr open 2 ,
+except that file creation is not supported, so the mode parameter is not
+required.
+The
+.Fa flags
+argument may be one of O_RDONLY, O_WRONLY and O_RDWR (although no file systems
+currently support writing).
+.It Xo
+.Ft int
+.Fn close "int fd"
+.Xc
+.It Xo
+.Ft void
+.Fn closeall void
+.Xc
+.Pp
+Close all open files.
+.It Xo
+.Ft ssize_t
+.Fn read "int fd" "void *buf" "size_t len"
+.Xc
+.It Xo
+.Ft ssize_t
+.Fn write "int fd" "void *buf" "size_t len"
+.Xc
+.Pp
+(No file systems currently support writing.)
+.It Xo
+.Ft off_t
+.Fn lseek "int fd" "off_t offset" "int whence"
+.Xc
+.Pp
+Files being automatically uncompressed during reading cannot seek backwards
+from the current point.
+.It Xo
+.Ft int
+.Fn stat "const char *path" "struct stat *sb"
+.Xc
+.It Xo
+.Ft int
+.Fn fstat "int fd" "struct stat *sb"
+.Xc
+.Pp
+The
+.Fn stat
+and
+.Fn fstat
+functions only fill out the following fields in the
+.Fa sb
+structure: st_mode,st_nlink,st_uid,st_gid,st_size.
+The
+.Nm tftp
+file system cannot provide meaningful values for this call, and the
+.Nm cd9660
+file system always reports files having uid/gid of zero.
+.El
+.Sh PAGER
+The
+.Nm
+library supplies a simple internal pager to ease reading the output of large
+commands.
+.Bl -hang -width 10n
+.It Xo
+.Ft void
+.Fn pager_open
+.Xc
+.Pp
+Initialises the pager and tells it that the next line output will be the top of the
+display.
+The environment variable LINES is consulted to determine the number of
+lines to be displayed before pausing.
+.It Xo
+.Ft void
+.Fn pager_close void
+.Xc
+.Pp
+Closes the pager.
+.It Xo
+.Ft int
+.Fn pager_output "const char *lines"
+.Xc
+.Pp
+Sends the lines in the
+.Dv NUL Ns
+-terminated buffer at
+.Fa lines
+to the pager.
+Newline characters are counted in order to determine the number
+of lines being output (wrapped lines are not accounted for).
+The
+.Fn pager_output
+function will return zero when all of the lines have been output, or nonzero
+if the display was paused and the user elected to quit.
+.It Xo
+.Ft int
+.Fn pager_file "const char *fname"
+.Xc
+.Pp
+Attempts to open and display the file
+.Fa fname .
+Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading.
+.El
+.Sh MISC
+.Bl -hang -width 10n
+.It Xo
+.Ft void
+.Fn twiddle void
+.Xc
+.Pp
+Successive calls emit the characters in the sequence |,/,-,\\ followed by a
+backspace in order to provide reassurance to the user.
+.El
+.Sh REQUIRED LOW-LEVEL SUPPORT
+The following resources are consumed by
+.Nm
+- stack, heap, console and devices.
+.Pp
+The stack must be established before
+.Nm
+functions can be invoked.
+Stack requirements vary depending on the functions
+and file systems used by the consumer and the support layer functions detailed
+below.
+.Pp
+The heap must be established before calling
+.Fn alloc
+or
+.Fn open
+by calling
+.Fn setheap .
+Heap usage will vary depending on the number of simultaneously open files,
+as well as client behaviour.
+Automatic decompression will allocate more
+than 64K of data per open file.
+.Pp
+Console access is performed via the
+.Fn getchar ,
+.Fn putchar
+and
+.Fn ischar
+functions detailed below.
+.Pp
+Device access is initiated via
+.Fn devopen
+and is performed through the
+.Fn dv_strategy ,
+.Fn dv_ioctl
+and
+.Fn dv_close
+functions in the device switch structure that
+.Fn devopen
+returns.
+.Pp
+The consumer must provide the following support functions:
+.Bl -hang -width 10n
+.It Xo
+.Ft int
+.Fn getchar void
+.Xc
+.Pp
+Return a character from the console, used by
+.Fn gets ,
+.Fn ngets
+and pager functions.
+.It Xo
+.Ft int
+.Fn ischar void
+.Xc
+.Pp
+Returns nonzero if a character is waiting from the console.
+.It Xo
+.Ft void
+.Fn putchar int
+.Xc
+.Pp
+Write a character to the console, used by
+.Fn gets ,
+.Fn ngets ,
+.Fn *printf ,
+.Fn panic
+and
+.Fn twiddle
+and thus by many other functions for debugging and informational output.
+.It Xo
+.Ft int
+.Fn devopen "struct open_file *of" "const char *name" "const char **file"
+.Xc
+.Pp
+Open the appropriate device for the file named in
+.Fa name ,
+returning in
+.Fa file
+a pointer to the remaining body of
+.Fa name
+which does not refer to the device.
+The
+.Va f_dev
+field in
+.Fa of
+will be set to point to the
+.Vt devsw
+structure for the opened device if successful.
+Device identifiers must
+always precede the path component, but may otherwise be arbitrarily formatted.
+Used by
+.Fn open
+and thus for all device-related I/O.
+.It Xo
+.Ft int
+.Fn devclose "struct open_file *of"
+.Xc
+.Pp
+Close the device allocated for
+.Fa of .
+The device driver itself will already have been called for the close; this call
+should clean up any allocation made by devopen only.
+.It Xo
+.Ft void
+.Fn panic "const char *msg" "..."
+.Xc
+.Pp
+Signal a fatal and unrecoverable error condition.
+The
+.Fa msg ...
+arguments are as for
+.Fn printf .
+.El
+.Sh INTERNAL FILE SYSTEMS
+Internal file systems are enabled by the consumer exporting the array
+.Vt struct fs_ops *file_system[] ,
+which should be initialised with pointers
+to
+.Vt struct fs_ops
+structures.
+The following file system handlers are supplied by
+.Nm ,
+the consumer may supply other file systems of their own:
+.Bl -hang -width ".Va cd9660_fsops"
+.It Va ufs_fsops
+The
+.Bx
+UFS.
+.It Va ext2fs_fsops
+Linux ext2fs file system.
+.It Va tftp_fsops
+File access via TFTP.
+.It Va nfs_fsops
+File access via NFS.
+.It Va cd9660_fsops
+ISO 9660 (CD-ROM) file system.
+.It Va gzipfs_fsops
+Stacked file system supporting gzipped files.
+When trying the gzipfs file system,
+.Nm
+appends
+.Li .gz
+to the end of the filename, and then tries to locate the file using the other
+file systems.
+Placement of this file system in the
+.Va file_system[]
+array determines whether gzipped files will be opened in preference to non-gzipped
+files.
+It is only possible to seek a gzipped file forwards, and
+.Fn stat
+and
+.Fn fstat
+on gzipped files will report an invalid length.
+.It Va bzipfs_fsops
+The same as
+.Va gzipfs_fsops ,
+but for
+.Xr bzip2 1 Ns -compressed
+files.
+.El
+.Pp
+The array of
+.Vt struct fs_ops
+pointers should be terminated with a NULL.
+.Sh DEVICES
+Devices are exported by the supporting code via the array
+.Vt struct devsw *devsw[]
+which is a NULL terminated array of pointers to device switch structures.
+.Sh HISTORY
+The
+.Nm
+library contains contributions from many sources, including:
+.Bl -bullet -compact
+.It
+.Nm libsa
+from
+.Nx
+.It
+.Nm libc
+and
+.Nm libkern
+from
+.Fx 3.0 .
+.It
+.Nm zalloc
+from
+.An Matthew Dillon Aq Mt dillon@backplane.com
+.El
+.Pp
+The reorganisation and port to
+.Fx 3.0 ,
+the environment functions and this manpage were written by
+.An Mike Smith Aq Mt msmith@FreeBSD.org .
+.Sh BUGS
+The lack of detailed memory usage data is unhelpful.
diff --git a/usr/src/boot/lib/libstand/lseek.c b/usr/src/boot/lib/libstand/lseek.c
new file mode 100644
index 0000000000..f656d59865
--- /dev/null
+++ b/usr/src/boot/lib/libstand/lseek.c
@@ -0,0 +1,142 @@
+/* $NetBSD: lseek.c,v 1.4 1997/01/22 00:38:10 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)lseek.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+off_t
+lseek(int fd, off_t offset, int where)
+{
+ off_t bufpos, filepos, target;
+ struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ if (f->f_flags & F_RAW) {
+ /*
+ * On RAW devices, update internal offset.
+ */
+ switch (where) {
+ case SEEK_SET:
+ f->f_offset = offset;
+ break;
+ case SEEK_CUR:
+ f->f_offset += offset;
+ break;
+ case SEEK_END:
+ default:
+ errno = EOFFSET;
+ return (-1);
+ }
+ return (f->f_offset);
+ }
+
+ /*
+ * If there is some unconsumed data in the readahead buffer and it
+ * contains the desired offset, simply adjust the buffer offset and
+ * length. We don't bother with SEEK_END here, since the code to
+ * handle it would fail in the same cases where the non-readahead
+ * code fails (namely, for streams which cannot seek backward and whose
+ * size isn't known in advance).
+ */
+ if (f->f_ralen != 0 && where != SEEK_END) {
+ if ((filepos = (f->f_ops->fo_seek)(f, (off_t)0, SEEK_CUR)) == -1)
+ return (-1);
+ bufpos = filepos - f->f_ralen;
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = bufpos + offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ if (bufpos <= target && target < filepos) {
+ f->f_raoffset += target - bufpos;
+ f->f_ralen -= target - bufpos;
+ return (target);
+ }
+ }
+
+ /*
+ * If this is a relative seek, we need to correct the offset for
+ * bytes that we have already read but the caller doesn't know
+ * about.
+ */
+ if (where == SEEK_CUR)
+ offset -= f->f_ralen;
+
+ /*
+ * Invalidate the readahead buffer.
+ */
+ f->f_ralen = 0;
+
+ return (f->f_ops->fo_seek)(f, offset, where);
+}
diff --git a/usr/src/boot/lib/libstand/mips/_setjmp.S b/usr/src/boot/lib/libstand/mips/_setjmp.S
new file mode 100644
index 0000000000..0289b0ec92
--- /dev/null
+++ b/usr/src/boot/lib/libstand/mips/_setjmp.S
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/regnum.h>
+#include <machine/asm.h>
+
+#if 0
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD: _setjmp.S,v 1.6 1996/09/23 21:27:53 imp Exp $"
+#endif /* LIBC_SCCS */
+#endif
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * _setjmp(a)
+ * by restoring registers from the stack,
+ * The previous signal state is NOT restored.
+ */
+
+LEAF(_setjmp)
+ .set noreorder
+ REG_LI v0, 0xACEDBADE # sigcontext magic number
+ REG_S ra, (2 * SZREG)(a0) # sc_pc = return address
+ REG_S v0, (3 * SZREG)(a0) # saved in sc_regs[0]
+ REG_S s0, ((S0 + 3) * SZREG)(a0)
+ REG_S s1, ((S1 + 3) * SZREG)(a0)
+ REG_S s2, ((S2 + 3) * SZREG)(a0)
+ REG_S s3, ((S3 + 3) * SZREG)(a0)
+ REG_S s4, ((S4 + 3) * SZREG)(a0)
+ REG_S s5, ((S5 + 3) * SZREG)(a0)
+ REG_S s6, ((S6 + 3) * SZREG)(a0)
+ REG_S s7, ((S7 + 3) * SZREG)(a0)
+ REG_S sp, ((SP + 3) * SZREG)(a0)
+ REG_S s8, ((S8 + 3) * SZREG)(a0)
+ j ra
+ move v0, zero
+END(_setjmp)
+
+LEAF(_longjmp)
+#ifdef ABICALLS
+ subu sp, sp, 32
+ .cprestore 16
+#endif
+ .set noreorder
+ REG_L v0, (3 * SZREG)(a0) # get magic number
+ REG_L ra, (2 * SZREG)(a0)
+ bne v0, 0xACEDBADE, botch # jump if error
+
+ addu sp, sp, 32 # does not matter, sanity
+ REG_L s0, ((S0 + 3) * SZREG)(a0)
+ REG_L s1, ((S1 + 3) * SZREG)(a0)
+ REG_L s2, ((S2 + 3) * SZREG)(a0)
+ REG_L s3, ((S3 + 3) * SZREG)(a0)
+ REG_L s4, ((S4 + 3) * SZREG)(a0)
+ REG_L s5, ((S5 + 3) * SZREG)(a0)
+ REG_L s6, ((S6 + 3) * SZREG)(a0)
+ REG_L s7, ((S7 + 3) * SZREG)(a0)
+ REG_L sp, ((SP + 3) * SZREG)(a0)
+ REG_L s8, ((S8 + 3) * SZREG)(a0)
+
+ j ra
+ move v0, a1
+botch:
+ jal _C_LABEL(longjmperror)
+ nop
+ jal _C_LABEL(abort)
+ nop
+END(_longjmp)
diff --git a/usr/src/boot/lib/libstand/nandfs.c b/usr/src/boot/lib/libstand/nandfs.c
new file mode 100644
index 0000000000..b8c51e3b5a
--- /dev/null
+++ b/usr/src/boot/lib/libstand/nandfs.c
@@ -0,0 +1,1061 @@
+/*-
+ * Copyright (c) 2010-2012 Semihalf.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/stdint.h>
+#include <ufs/ufs/dinode.h>
+#include <fs/nandfs/nandfs_fs.h>
+#include "stand.h"
+#include "string.h"
+#include "zlib.h"
+
+#define DEBUG
+#undef DEBUG
+#ifdef DEBUG
+#define NANDFS_DEBUG(fmt, args...) do { \
+ printf("NANDFS_DEBUG:" fmt "\n", ##args); } while (0)
+#else
+#define NANDFS_DEBUG(fmt, args...)
+#endif
+
+struct nandfs_mdt {
+ uint32_t entries_per_block;
+ uint32_t entries_per_group;
+ uint32_t blocks_per_group;
+ uint32_t groups_per_desc_block; /* desc is super group */
+ uint32_t blocks_per_desc_block; /* desc is super group */
+};
+
+struct bmap_buf {
+ LIST_ENTRY(bmap_buf) list;
+ nandfs_daddr_t blknr;
+ uint64_t *map;
+};
+
+struct nandfs_node {
+ struct nandfs_inode *inode;
+ LIST_HEAD(, bmap_buf) bmap_bufs;
+};
+struct nandfs {
+ int nf_blocksize;
+ int nf_sectorsize;
+ int nf_cpno;
+
+ struct open_file *nf_file;
+ struct nandfs_node *nf_opened_node;
+ u_int nf_offset;
+ uint8_t *nf_buf;
+ int64_t nf_buf_blknr;
+
+ struct nandfs_fsdata *nf_fsdata;
+ struct nandfs_super_block *nf_sb;
+ struct nandfs_segment_summary nf_segsum;
+ struct nandfs_checkpoint nf_checkpoint;
+ struct nandfs_super_root nf_sroot;
+ struct nandfs_node nf_ifile;
+ struct nandfs_node nf_datfile;
+ struct nandfs_node nf_cpfile;
+ struct nandfs_mdt nf_datfile_mdt;
+ struct nandfs_mdt nf_ifile_mdt;
+
+ int nf_nindir[NIADDR];
+};
+
+static int nandfs_open(const char *, struct open_file *);
+static int nandfs_close(struct open_file *);
+static int nandfs_read(struct open_file *, void *, size_t, size_t *);
+static off_t nandfs_seek(struct open_file *, off_t, int);
+static int nandfs_stat(struct open_file *, struct stat *);
+static int nandfs_readdir(struct open_file *, struct dirent *);
+
+static int nandfs_buf_read(struct nandfs *, void **, size_t *);
+static struct nandfs_node *nandfs_lookup_path(struct nandfs *, const char *);
+static int nandfs_read_inode(struct nandfs *, struct nandfs_node *,
+ nandfs_lbn_t, u_int, void *, int);
+static int nandfs_read_blk(struct nandfs *, nandfs_daddr_t, void *, int);
+static int nandfs_bmap_lookup(struct nandfs *, struct nandfs_node *,
+ nandfs_lbn_t, nandfs_daddr_t *, int);
+static int nandfs_get_checkpoint(struct nandfs *, uint64_t,
+ struct nandfs_checkpoint *);
+static nandfs_daddr_t nandfs_vtop(struct nandfs *, nandfs_daddr_t);
+static void nandfs_calc_mdt_consts(int, struct nandfs_mdt *, int);
+static void nandfs_mdt_trans(struct nandfs_mdt *, uint64_t,
+ nandfs_daddr_t *, uint32_t *);
+static int ioread(struct open_file *, off_t, void *, u_int);
+static int nandfs_probe_sectorsize(struct open_file *);
+
+struct fs_ops nandfs_fsops = {
+ "nandfs",
+ nandfs_open,
+ nandfs_close,
+ nandfs_read,
+ null_write,
+ nandfs_seek,
+ nandfs_stat,
+ nandfs_readdir
+};
+
+#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t))
+
+/* from NetBSD's src/sys/net/if_ethersubr.c */
+static uint32_t
+nandfs_crc32(uint32_t crc, const uint8_t *buf, size_t len)
+{
+ static const uint32_t crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ size_t i;
+
+ crc = crc ^ ~0U;
+ for (i = 0; i < len; i++) {
+ crc ^= buf[i];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+ return (crc ^ ~0U);
+}
+
+static int
+nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
+{
+ uint32_t fsdata_crc, comp_crc;
+
+ if (fsdata->f_magic != NANDFS_FSDATA_MAGIC)
+ return (0);
+
+ /* Preserve crc */
+ fsdata_crc = fsdata->f_sum;
+
+ /* Calculate */
+ fsdata->f_sum = (0);
+ comp_crc = nandfs_crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
+
+ /* Restore */
+ fsdata->f_sum = fsdata_crc;
+
+ /* Check CRC */
+ return (fsdata_crc == comp_crc);
+}
+
+static int
+nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata,
+ struct nandfs_super_block *super)
+{
+ uint32_t super_crc, comp_crc;
+
+ /* Check super block magic */
+ if (super->s_magic != NANDFS_SUPER_MAGIC)
+ return (0);
+
+ /* Preserve CRC */
+ super_crc = super->s_sum;
+
+ /* Calculate */
+ super->s_sum = (0);
+ comp_crc = nandfs_crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
+
+ /* Restore */
+ super->s_sum = super_crc;
+
+ /* Check CRC */
+ return (super_crc == comp_crc);
+}
+
+static int
+nandfs_find_super_block(struct nandfs *fs, struct open_file *f)
+{
+ struct nandfs_super_block *sb;
+ int i, j, n, s;
+ int sectors_to_read, error;
+
+ sb = malloc(fs->nf_sectorsize);
+ if (sb == NULL)
+ return (ENOMEM);
+
+ memset(fs->nf_sb, 0, sizeof(*fs->nf_sb));
+
+ sectors_to_read = (NANDFS_NFSAREAS * fs->nf_fsdata->f_erasesize) /
+ fs->nf_sectorsize;
+ for (i = 0; i < sectors_to_read; i++) {
+ NANDFS_DEBUG("reading i %d offset %d\n", i,
+ i * fs->nf_sectorsize);
+ error = ioread(f, i * fs->nf_sectorsize, (char *)sb,
+ fs->nf_sectorsize);
+ if (error) {
+ NANDFS_DEBUG("error %d\n", error);
+ continue;
+ }
+ n = fs->nf_sectorsize / sizeof(struct nandfs_super_block);
+ s = 0;
+ if ((i * fs->nf_sectorsize) % fs->nf_fsdata->f_erasesize == 0) {
+ if (fs->nf_sectorsize == sizeof(struct nandfs_fsdata))
+ continue;
+ else {
+ s += (sizeof(struct nandfs_fsdata) /
+ sizeof(struct nandfs_super_block));
+ }
+ }
+
+ for (j = s; j < n; j++) {
+ if (!nandfs_check_superblock_crc(fs->nf_fsdata, &sb[j]))
+ continue;
+ NANDFS_DEBUG("magic %x wtime %jd, lastcp 0x%jx\n",
+ sb[j].s_magic, sb[j].s_wtime, sb[j].s_last_cno);
+ if (sb[j].s_last_cno > fs->nf_sb->s_last_cno)
+ memcpy(fs->nf_sb, &sb[j], sizeof(*fs->nf_sb));
+ }
+ }
+
+ free(sb);
+
+ return (fs->nf_sb->s_magic != 0 ? 0 : EINVAL);
+}
+
+static int
+nandfs_find_fsdata(struct nandfs *fs, struct open_file *f)
+{
+ int offset, error, i;
+
+ NANDFS_DEBUG("starting\n");
+
+ offset = 0;
+ for (i = 0; i < 64 * NANDFS_NFSAREAS; i++) {
+ error = ioread(f, offset, (char *)fs->nf_fsdata,
+ sizeof(struct nandfs_fsdata));
+ if (error)
+ return (error);
+ if (fs->nf_fsdata->f_magic == NANDFS_FSDATA_MAGIC) {
+ NANDFS_DEBUG("found at %x, volume %s\n", offset,
+ fs->nf_fsdata->f_volume_name);
+ if (nandfs_check_fsdata_crc(fs->nf_fsdata))
+ break;
+ }
+ offset += fs->nf_sectorsize;
+ }
+
+ return (error);
+}
+
+static int
+nandfs_read_structures(struct nandfs *fs, struct open_file *f)
+{
+ int error;
+
+ error = nandfs_find_fsdata(fs, f);
+ if (error)
+ return (error);
+
+ error = nandfs_find_super_block(fs, f);
+
+ if (error == 0)
+ NANDFS_DEBUG("selected sb with w_time %jd last_pseg %jx\n",
+ fs->nf_sb->s_wtime, fs->nf_sb->s_last_pseg);
+
+ return (error);
+}
+
+static int
+nandfs_mount(struct nandfs *fs, struct open_file *f)
+{
+ int err = 0, level;
+ uint64_t last_pseg;
+
+ fs->nf_fsdata = malloc(sizeof(struct nandfs_fsdata));
+ fs->nf_sb = malloc(sizeof(struct nandfs_super_block));
+
+ err = nandfs_read_structures(fs, f);
+ if (err) {
+ free(fs->nf_fsdata);
+ free(fs->nf_sb);
+ return (err);
+ }
+
+ fs->nf_blocksize = 1 << (fs->nf_fsdata->f_log_block_size + 10);
+
+ NANDFS_DEBUG("using superblock with wtime %jd\n", fs->nf_sb->s_wtime);
+
+ fs->nf_cpno = fs->nf_sb->s_last_cno;
+ last_pseg = fs->nf_sb->s_last_pseg;
+
+ /*
+ * Calculate indirect block levels.
+ */
+ nandfs_daddr_t mult;
+
+ mult = 1;
+ for (level = 0; level < NIADDR; level++) {
+ mult *= NINDIR(fs);
+ fs->nf_nindir[level] = mult;
+ }
+
+ nandfs_calc_mdt_consts(fs->nf_blocksize, &fs->nf_datfile_mdt,
+ fs->nf_fsdata->f_dat_entry_size);
+
+ nandfs_calc_mdt_consts(fs->nf_blocksize, &fs->nf_ifile_mdt,
+ fs->nf_fsdata->f_inode_size);
+
+ err = ioread(f, last_pseg * fs->nf_blocksize, &fs->nf_segsum,
+ sizeof(struct nandfs_segment_summary));
+ if (err) {
+ free(fs->nf_sb);
+ free(fs->nf_fsdata);
+ return (err);
+ }
+
+ err = ioread(f, (last_pseg + fs->nf_segsum.ss_nblocks - 1) *
+ fs->nf_blocksize, &fs->nf_sroot, sizeof(struct nandfs_super_root));
+ if (err) {
+ free(fs->nf_sb);
+ free(fs->nf_fsdata);
+ return (err);
+ }
+
+ fs->nf_datfile.inode = &fs->nf_sroot.sr_dat;
+ LIST_INIT(&fs->nf_datfile.bmap_bufs);
+ fs->nf_cpfile.inode = &fs->nf_sroot.sr_cpfile;
+ LIST_INIT(&fs->nf_cpfile.bmap_bufs);
+
+ err = nandfs_get_checkpoint(fs, fs->nf_cpno, &fs->nf_checkpoint);
+ if (err) {
+ free(fs->nf_sb);
+ free(fs->nf_fsdata);
+ return (err);
+ }
+
+ NANDFS_DEBUG("checkpoint cp_cno=%lld\n", fs->nf_checkpoint.cp_cno);
+ NANDFS_DEBUG("checkpoint cp_inodes_count=%lld\n",
+ fs->nf_checkpoint.cp_inodes_count);
+ NANDFS_DEBUG("checkpoint cp_ifile_inode.i_blocks=%lld\n",
+ fs->nf_checkpoint.cp_ifile_inode.i_blocks);
+
+ fs->nf_ifile.inode = &fs->nf_checkpoint.cp_ifile_inode;
+ LIST_INIT(&fs->nf_ifile.bmap_bufs);
+ return (0);
+}
+
+#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t))
+
+static int
+nandfs_open(const char *path, struct open_file *f)
+{
+ struct nandfs *fs;
+ struct nandfs_node *node;
+ int err, bsize, level;
+
+ NANDFS_DEBUG("nandfs_open('%s', %p)\n", path, f);
+
+ fs = malloc(sizeof(struct nandfs));
+ f->f_fsdata = fs;
+ fs->nf_file = f;
+
+ bsize = nandfs_probe_sectorsize(f);
+ if (bsize < 0) {
+ printf("Cannot probe medium sector size\n");
+ return (EINVAL);
+ }
+
+ fs->nf_sectorsize = bsize;
+
+ /*
+ * Calculate indirect block levels.
+ */
+ nandfs_daddr_t mult;
+
+ mult = 1;
+ for (level = 0; level < NIADDR; level++) {
+ mult *= NINDIR(fs);
+ fs->nf_nindir[level] = mult;
+ }
+
+ NANDFS_DEBUG("fs %p nf_sectorsize=%x\n", fs, fs->nf_sectorsize);
+
+ err = nandfs_mount(fs, f);
+ if (err) {
+ NANDFS_DEBUG("Cannot mount nandfs: %s\n", strerror(err));
+ return (err);
+ }
+
+ node = nandfs_lookup_path(fs, path);
+ if (node == NULL)
+ return (EINVAL);
+
+ fs->nf_offset = 0;
+ fs->nf_buf = NULL;
+ fs->nf_buf_blknr = -1;
+ fs->nf_opened_node = node;
+ LIST_INIT(&fs->nf_opened_node->bmap_bufs);
+ return (0);
+}
+
+static void
+nandfs_free_node(struct nandfs_node *node)
+{
+ struct bmap_buf *bmap, *tmp;
+
+ free(node->inode);
+ LIST_FOREACH_SAFE(bmap, &node->bmap_bufs, list, tmp) {
+ LIST_REMOVE(bmap, list);
+ free(bmap->map);
+ free(bmap);
+ }
+ free(node);
+}
+
+static int
+nandfs_close(struct open_file *f)
+{
+ struct nandfs *fs = f->f_fsdata;
+
+ NANDFS_DEBUG("nandfs_close(%p)\n", f);
+
+ if (fs->nf_buf != NULL)
+ free(fs->nf_buf);
+
+ nandfs_free_node(fs->nf_opened_node);
+ free(fs->nf_sb);
+ free(fs);
+ return (0);
+}
+
+static int
+nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
+{
+ struct nandfs *fs = (struct nandfs *)f->f_fsdata;
+ size_t csize, buf_size;
+ void *buf;
+ int error = 0;
+
+ NANDFS_DEBUG("nandfs_read(file=%p, addr=%p, size=%d)\n", f, addr, size);
+
+ while (size != 0) {
+ if (fs->nf_offset >= fs->nf_opened_node->inode->i_size)
+ break;
+
+ error = nandfs_buf_read(fs, &buf, &buf_size);
+ if (error)
+ break;
+
+ csize = size;
+ if (csize > buf_size)
+ csize = buf_size;
+
+ bcopy(buf, addr, csize);
+
+ fs->nf_offset += csize;
+ addr = (char *)addr + csize;
+ size -= csize;
+ }
+
+ if (resid)
+ *resid = size;
+ return (error);
+}
+
+static off_t
+nandfs_seek(struct open_file *f, off_t offset, int where)
+{
+ struct nandfs *fs = f->f_fsdata;
+ off_t off;
+ u_int size;
+
+ NANDFS_DEBUG("nandfs_seek(file=%p, offset=%lld, where=%d)\n", f,
+ offset, where);
+
+ size = fs->nf_opened_node->inode->i_size;
+
+ switch (where) {
+ case SEEK_SET:
+ off = 0;
+ break;
+ case SEEK_CUR:
+ off = fs->nf_offset;
+ break;
+ case SEEK_END:
+ off = size;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ off += offset;
+ if (off < 0 || off > size) {
+ errno = EINVAL;
+ return(-1);
+ }
+
+ fs->nf_offset = (u_int)off;
+
+ return (off);
+}
+
+static int
+nandfs_stat(struct open_file *f, struct stat *sb)
+{
+ struct nandfs *fs = f->f_fsdata;
+
+ NANDFS_DEBUG("nandfs_stat(file=%p, stat=%p)\n", f, sb);
+
+ sb->st_size = fs->nf_opened_node->inode->i_size;
+ sb->st_mode = fs->nf_opened_node->inode->i_mode;
+ sb->st_uid = fs->nf_opened_node->inode->i_uid;
+ sb->st_gid = fs->nf_opened_node->inode->i_gid;
+ return (0);
+}
+
+static int
+nandfs_readdir(struct open_file *f, struct dirent *d)
+{
+ struct nandfs *fs = f->f_fsdata;
+ struct nandfs_dir_entry *dirent;
+ void *buf;
+ size_t buf_size;
+
+ NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)\n", f, d);
+
+ if (fs->nf_offset >= fs->nf_opened_node->inode->i_size) {
+ NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) ENOENT\n",
+ f, d);
+ return (ENOENT);
+ }
+
+ if (nandfs_buf_read(fs, &buf, &buf_size)) {
+ NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)"
+ "buf_read failed\n", f, d);
+ return (EIO);
+ }
+
+ NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) moving forward\n",
+ f, d);
+
+ dirent = (struct nandfs_dir_entry *)buf;
+ fs->nf_offset += dirent->rec_len;
+ strncpy(d->d_name, dirent->name, dirent->name_len);
+ d->d_name[dirent->name_len] = '\0';
+ d->d_type = dirent->file_type;
+ return (0);
+}
+
+static int
+nandfs_buf_read(struct nandfs *fs, void **buf_p, size_t *size_p)
+{
+ nandfs_daddr_t blknr, blkoff;
+
+ blknr = fs->nf_offset / fs->nf_blocksize;
+ blkoff = fs->nf_offset % fs->nf_blocksize;
+
+ if (blknr != fs->nf_buf_blknr) {
+ if (fs->nf_buf == NULL)
+ fs->nf_buf = malloc(fs->nf_blocksize);
+
+ if (nandfs_read_inode(fs, fs->nf_opened_node, blknr, 1,
+ fs->nf_buf, 0))
+ return (EIO);
+
+ fs->nf_buf_blknr = blknr;
+ }
+
+ *buf_p = fs->nf_buf + blkoff;
+ *size_p = fs->nf_blocksize - blkoff;
+
+ NANDFS_DEBUG("nandfs_buf_read buf_p=%p size_p=%d\n", *buf_p, *size_p);
+
+ if (*size_p > fs->nf_opened_node->inode->i_size - fs->nf_offset)
+ *size_p = fs->nf_opened_node->inode->i_size - fs->nf_offset;
+
+ return (0);
+}
+
+static struct nandfs_node *
+nandfs_lookup_node(struct nandfs *fs, uint64_t ino)
+{
+ uint64_t blocknr;
+ int entrynr;
+ struct nandfs_inode *buffer;
+ struct nandfs_node *node;
+ struct nandfs_inode *inode;
+
+ NANDFS_DEBUG("nandfs_lookup_node ino=%lld\n", ino);
+
+ if (ino == 0) {
+ printf("nandfs_lookup_node: invalid inode requested\n");
+ return (NULL);
+ }
+
+ buffer = malloc(fs->nf_blocksize);
+ inode = malloc(sizeof(struct nandfs_inode));
+ node = malloc(sizeof(struct nandfs_node));
+
+ nandfs_mdt_trans(&fs->nf_ifile_mdt, ino, &blocknr, &entrynr);
+
+ if (nandfs_read_inode(fs, &fs->nf_ifile, blocknr, 1, buffer, 0))
+ return (NULL);
+
+ memcpy(inode, &buffer[entrynr], sizeof(struct nandfs_inode));
+ node->inode = inode;
+ free(buffer);
+ return (node);
+}
+
+static struct nandfs_node *
+nandfs_lookup_path(struct nandfs *fs, const char *path)
+{
+ struct nandfs_node *node;
+ struct nandfs_dir_entry *dirent;
+ char *namebuf;
+ uint64_t i, done, pinode, inode;
+ int nlinks = 0, counter, len, link_len, nameidx;
+ uint8_t *buffer, *orig;
+ char *strp, *lpath;
+
+ buffer = malloc(fs->nf_blocksize);
+ orig = buffer;
+
+ namebuf = malloc(2 * MAXPATHLEN + 2);
+ strncpy(namebuf, path, MAXPATHLEN);
+ namebuf[MAXPATHLEN] = '\0';
+ done = nameidx = 0;
+ lpath = namebuf;
+
+ /* Get the root inode */
+ node = nandfs_lookup_node(fs, NANDFS_ROOT_INO);
+ inode = NANDFS_ROOT_INO;
+
+ while ((strp = strsep(&lpath, "/")) != NULL) {
+ if (*strp == '\0')
+ continue;
+ if ((node->inode->i_mode & IFMT) != IFDIR) {
+ nandfs_free_node(node);
+ node = NULL;
+ goto out;
+ }
+
+ len = strlen(strp);
+ NANDFS_DEBUG("%s: looking for %s\n", __func__, strp);
+ for (i = 0; i < node->inode->i_blocks; i++) {
+ if (nandfs_read_inode(fs, node, i, 1, orig, 0)) {
+ node = NULL;
+ goto out;
+ }
+
+ buffer = orig;
+ done = counter = 0;
+ while (1) {
+ dirent =
+ (struct nandfs_dir_entry *)(void *)buffer;
+ NANDFS_DEBUG("%s: dirent.name = %s\n",
+ __func__, dirent->name);
+ NANDFS_DEBUG("%s: dirent.rec_len = %d\n",
+ __func__, dirent->rec_len);
+ NANDFS_DEBUG("%s: dirent.inode = %lld\n",
+ __func__, dirent->inode);
+ if (len == dirent->name_len &&
+ (strncmp(strp, dirent->name, len) == 0) &&
+ dirent->inode != 0) {
+ nandfs_free_node(node);
+ node = nandfs_lookup_node(fs,
+ dirent->inode);
+ pinode = inode;
+ inode = dirent->inode;
+ done = 1;
+ break;
+ }
+
+ counter += dirent->rec_len;
+ buffer += dirent->rec_len;
+
+ if (counter == fs->nf_blocksize)
+ break;
+ }
+
+ if (done)
+ break;
+ }
+
+ if (!done) {
+ node = NULL;
+ goto out;
+ }
+
+ NANDFS_DEBUG("%s: %.*s has mode %o\n", __func__,
+ dirent->name_len, dirent->name, node->inode->i_mode);
+
+ if ((node->inode->i_mode & IFMT) == IFLNK) {
+ NANDFS_DEBUG("%s: %.*s is symlink\n",
+ __func__, dirent->name_len, dirent->name);
+ link_len = node->inode->i_size;
+
+ if (++nlinks > MAXSYMLINKS) {
+ nandfs_free_node(node);
+ node = NULL;
+ goto out;
+ }
+
+ if (nandfs_read_inode(fs, node, 0, 1, orig, 0)) {
+ nandfs_free_node(node);
+ node = NULL;
+ goto out;
+ }
+
+ NANDFS_DEBUG("%s: symlink is %.*s\n",
+ __func__, link_len, (char *)orig);
+
+ nameidx = (nameidx == 0) ? MAXPATHLEN + 1 : 0;
+ bcopy((char *)orig, namebuf + nameidx,
+ (unsigned)link_len);
+ if (lpath != NULL) {
+ namebuf[nameidx + link_len++] = '/';
+ strncpy(namebuf + nameidx + link_len, lpath,
+ MAXPATHLEN - link_len);
+ namebuf[nameidx + MAXPATHLEN] = '\0';
+ } else
+ namebuf[nameidx + link_len] = '\0';
+
+ NANDFS_DEBUG("%s: strp=%s, lpath=%s, namebuf0=%s, "
+ "namebuf1=%s, idx=%d\n", __func__, strp, lpath,
+ namebuf + 0, namebuf + MAXPATHLEN + 1, nameidx);
+
+ lpath = namebuf + nameidx;
+
+ nandfs_free_node(node);
+
+ /*
+ * If absolute pathname, restart at root. Otherwise
+ * continue with out parent inode.
+ */
+ inode = (orig[0] == '/') ? NANDFS_ROOT_INO : pinode;
+ node = nandfs_lookup_node(fs, inode);
+ }
+ }
+
+out:
+ free(namebuf);
+ free(orig);
+ return (node);
+}
+
+static int
+nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node,
+ nandfs_daddr_t blknr, u_int nblks, void *buf, int raw)
+{
+ uint64_t *pblks;
+ uint64_t *vblks;
+ u_int i;
+ int error;
+
+ pblks = malloc(nblks * sizeof(uint64_t));
+ vblks = malloc(nblks * sizeof(uint64_t));
+
+ NANDFS_DEBUG("nandfs_read_inode fs=%p node=%p blknr=%lld nblks=%d\n",
+ fs, node, blknr, nblks);
+ for (i = 0; i < nblks; i++) {
+ error = nandfs_bmap_lookup(fs, node, blknr + i, &vblks[i], raw);
+ if (error) {
+ free(pblks);
+ free(vblks);
+ return (error);
+ }
+ if (raw == 0)
+ pblks[i] = nandfs_vtop(fs, vblks[i]);
+ else
+ pblks[i] = vblks[i];
+ }
+
+ for (i = 0; i < nblks; i++) {
+ if (ioread(fs->nf_file, pblks[i] * fs->nf_blocksize, buf,
+ fs->nf_blocksize)) {
+ free(pblks);
+ free(vblks);
+ return (EIO);
+ }
+
+ buf = (void *)((uintptr_t)buf + fs->nf_blocksize);
+ }
+
+ free(pblks);
+ free(vblks);
+ return (0);
+}
+
+static int
+nandfs_read_blk(struct nandfs *fs, nandfs_daddr_t blknr, void *buf, int phys)
+{
+ uint64_t pblknr;
+
+ pblknr = (phys ? blknr : nandfs_vtop(fs, blknr));
+
+ return (ioread(fs->nf_file, pblknr * fs->nf_blocksize, buf,
+ fs->nf_blocksize));
+}
+
+static int
+nandfs_get_checkpoint(struct nandfs *fs, uint64_t cpno,
+ struct nandfs_checkpoint *cp)
+{
+ uint64_t blocknr;
+ int blockoff, cp_per_block, dlen;
+ uint8_t *buf;
+
+ NANDFS_DEBUG("nandfs_get_checkpoint(fs=%p cpno=%lld)\n", fs, cpno);
+
+ buf = malloc(fs->nf_blocksize);
+
+ cpno += NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET - 1;
+ dlen = fs->nf_fsdata->f_checkpoint_size;
+ cp_per_block = fs->nf_blocksize / dlen;
+ blocknr = cpno / cp_per_block;
+ blockoff = (cpno % cp_per_block) * dlen;
+
+ if (nandfs_read_inode(fs, &fs->nf_cpfile, blocknr, 1, buf, 0)) {
+ free(buf);
+ return (EINVAL);
+ }
+
+ memcpy(cp, buf + blockoff, sizeof(struct nandfs_checkpoint));
+ free(buf);
+
+ return (0);
+}
+
+static uint64_t *
+nandfs_get_map(struct nandfs *fs, struct nandfs_node *node, nandfs_daddr_t blknr,
+ int phys)
+{
+ struct bmap_buf *bmap;
+ uint64_t *map;
+
+ LIST_FOREACH(bmap, &node->bmap_bufs, list) {
+ if (bmap->blknr == blknr)
+ return (bmap->map);
+ }
+
+ map = malloc(fs->nf_blocksize);
+ if (nandfs_read_blk(fs, blknr, map, phys)) {
+ free(map);
+ return (NULL);
+ }
+
+ bmap = malloc(sizeof(struct bmap_buf));
+ bmap->blknr = blknr;
+ bmap->map = map;
+
+ LIST_INSERT_HEAD(&node->bmap_bufs, bmap, list);
+
+ NANDFS_DEBUG("%s:(node=%p, map=%p)\n", __func__, node, map);
+ return (map);
+}
+
+static int
+nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node,
+ nandfs_lbn_t lblknr, nandfs_daddr_t *vblknr, int phys)
+{
+ struct nandfs_inode *ino;
+ nandfs_daddr_t ind_block_num;
+ uint64_t *map;
+ int idx;
+ int level;
+
+ ino = node->inode;
+
+ if (lblknr < NDADDR) {
+ *vblknr = ino->i_db[lblknr];
+ return (0);
+ }
+
+ lblknr -= NDADDR;
+
+ /*
+ * nindir[0] = NINDIR
+ * nindir[1] = NINDIR**2
+ * nindir[2] = NINDIR**3
+ * etc
+ */
+ for (level = 0; level < NIADDR; level++) {
+ NANDFS_DEBUG("lblknr=%jx fs->nf_nindir[%d]=%d\n", lblknr, level, fs->nf_nindir[level]);
+ if (lblknr < fs->nf_nindir[level])
+ break;
+ lblknr -= fs->nf_nindir[level];
+ }
+
+ if (level == NIADDR) {
+ /* Block number too high */
+ NANDFS_DEBUG("lblknr %jx too high\n", lblknr);
+ return (EFBIG);
+ }
+
+ ind_block_num = ino->i_ib[level];
+
+ for (; level >= 0; level--) {
+ if (ind_block_num == 0) {
+ *vblknr = 0; /* missing */
+ return (0);
+ }
+
+ twiddle(1);
+ NANDFS_DEBUG("calling get_map with %jx\n", ind_block_num);
+ map = nandfs_get_map(fs, node, ind_block_num, phys);
+ if (map == NULL)
+ return (EIO);
+
+ if (level > 0) {
+ idx = lblknr / fs->nf_nindir[level - 1];
+ lblknr %= fs->nf_nindir[level - 1];
+ } else
+ idx = lblknr;
+
+ ind_block_num = ((nandfs_daddr_t *)map)[idx];
+ }
+
+ *vblknr = ind_block_num;
+
+ return (0);
+}
+
+static nandfs_daddr_t
+nandfs_vtop(struct nandfs *fs, nandfs_daddr_t vblocknr)
+{
+ nandfs_lbn_t blocknr;
+ nandfs_daddr_t pblocknr;
+ int entrynr;
+ struct nandfs_dat_entry *dat;
+
+ dat = malloc(fs->nf_blocksize);
+ nandfs_mdt_trans(&fs->nf_datfile_mdt, vblocknr, &blocknr, &entrynr);
+
+ if (nandfs_read_inode(fs, &fs->nf_datfile, blocknr, 1, dat, 1)) {
+ free(dat);
+ return (0);
+ }
+
+ NANDFS_DEBUG("nandfs_vtop entrynr=%d vblocknr=%lld pblocknr=%lld\n",
+ entrynr, vblocknr, dat[entrynr].de_blocknr);
+
+ pblocknr = dat[entrynr].de_blocknr;
+ free(dat);
+ return (pblocknr);
+}
+
+static void
+nandfs_calc_mdt_consts(int blocksize, struct nandfs_mdt *mdt, int entry_size)
+{
+
+ mdt->entries_per_group = blocksize * 8; /* bits in sector */
+ mdt->entries_per_block = blocksize / entry_size;
+ mdt->blocks_per_group =
+ (mdt->entries_per_group -1) / mdt->entries_per_block + 1 + 1;
+ mdt->groups_per_desc_block =
+ blocksize / sizeof(struct nandfs_block_group_desc);
+ mdt->blocks_per_desc_block =
+ mdt->groups_per_desc_block * mdt->blocks_per_group + 1;
+}
+
+static void
+nandfs_mdt_trans(struct nandfs_mdt *mdt, uint64_t index,
+ nandfs_daddr_t *blocknr, uint32_t *entry_in_block)
+{
+ nandfs_daddr_t blknr;
+ uint64_t group, group_offset, blocknr_in_group;
+ uint64_t desc_block, desc_offset;
+
+ /* Calculate our offset in the file */
+ group = index / mdt->entries_per_group;
+ group_offset = index % mdt->entries_per_group;
+ desc_block = group / mdt->groups_per_desc_block;
+ desc_offset = group % mdt->groups_per_desc_block;
+ blocknr_in_group = group_offset / mdt->entries_per_block;
+
+ /* To descgroup offset */
+ blknr = 1 + desc_block * mdt->blocks_per_desc_block;
+
+ /* To group offset */
+ blknr += desc_offset * mdt->blocks_per_group;
+
+ /* To actual file block */
+ blknr += 1 + blocknr_in_group;
+
+ *blocknr = blknr;
+ *entry_in_block = group_offset % mdt->entries_per_block;
+}
+
+static int
+ioread(struct open_file *f, off_t pos, void *buf, u_int length)
+{
+ void *buffer;
+ int err;
+ int bsize = ((struct nandfs *)f->f_fsdata)->nf_sectorsize;
+ u_int off, nsec;
+
+ off = pos % bsize;
+ pos /= bsize;
+ nsec = (length + (bsize - 1)) / bsize;
+
+ NANDFS_DEBUG("pos=%lld length=%d off=%d nsec=%d\n", pos, length,
+ off, nsec);
+
+ buffer = malloc(nsec * bsize);
+
+ err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, pos,
+ nsec * bsize, buffer, NULL);
+
+ memcpy(buf, (void *)((uintptr_t)buffer + off), length);
+ free(buffer);
+
+ return (err);
+}
+
+static int
+nandfs_probe_sectorsize(struct open_file *f)
+{
+ void *buffer;
+ int i, err;
+
+ buffer = malloc(16 * 1024);
+
+ NANDFS_DEBUG("probing for sector size: ");
+
+ for (i = 512; i < (16 * 1024); i <<= 1) {
+ NANDFS_DEBUG("%d ", i);
+ err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0, i,
+ buffer, NULL);
+
+ if (err == 0) {
+ NANDFS_DEBUG("found");
+ free(buffer);
+ return (i);
+ }
+ }
+
+ free(buffer);
+ NANDFS_DEBUG("not found\n");
+ return (-1);
+}
diff --git a/usr/src/boot/lib/libstand/net.c b/usr/src/boot/lib/libstand/net.c
new file mode 100644
index 0000000000..24593e6d2e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/net.c
@@ -0,0 +1,283 @@
+/* $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <string.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <netinet/in_pcb.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include "stand.h"
+#include "net.h"
+
+/*
+ * Send a packet and wait for a reply, with exponential backoff.
+ *
+ * The send routine must return the actual number of bytes written,
+ * or -1 on error.
+ *
+ * The receive routine can indicate success by returning the number of
+ * bytes read; it can return 0 to indicate EOF; it can return -1 with a
+ * non-zero errno to indicate failure; finally, it can return -1 with a
+ * zero errno to indicate it isn't done yet.
+ */
+ssize_t
+sendrecv(struct iodesc *d,
+ ssize_t (*sproc)(struct iodesc *, void *, size_t),
+ void *sbuf, size_t ssize,
+ ssize_t (*rproc)(struct iodesc *, void *, size_t, time_t),
+ void *rbuf, size_t rsize)
+{
+ ssize_t cc;
+ time_t t, tmo, tlast;
+ long tleft;
+
+#ifdef NET_DEBUG
+ if (debug)
+ printf("sendrecv: called\n");
+#endif
+
+ tmo = MINTMO;
+ tlast = 0;
+ tleft = 0;
+ t = getsecs();
+ for (;;) {
+ if (tleft <= 0) {
+ if (tmo >= MAXTMO) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ cc = (*sproc)(d, sbuf, ssize);
+ if (cc != -1 && cc < ssize)
+ panic("sendrecv: short write! (%zd < %zd)",
+ cc, ssize);
+
+ tleft = tmo;
+ tmo += MINTMO;
+ if (tmo > MAXTMO)
+ tmo = MAXTMO;
+
+ if (cc == -1) {
+ /* Error on transmit; wait before retrying */
+ while ((getsecs() - t) < tmo)
+ ;
+ tleft = 0;
+ continue;
+ }
+
+ tlast = t;
+ }
+
+ /* Try to get a packet and process it. */
+ cc = (*rproc)(d, rbuf, rsize, tleft);
+ /* Return on data, EOF or real error. */
+ if (cc != -1 || errno != 0)
+ return (cc);
+
+ /* Timed out or didn't get the packet we're waiting for */
+ t = getsecs();
+ tleft -= t - tlast;
+ tlast = t;
+ }
+}
+
+/*
+ * Like inet_addr() in the C library, but we only accept base-10.
+ * Return values are in network order.
+ */
+n_long
+inet_addr(char *cp)
+{
+ u_long val;
+ int n;
+ char c;
+ u_int parts[4];
+ u_int *pp = parts;
+
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0;
+ while ((c = *cp) != '\0') {
+ if (c >= '0' && c <= '9') {
+ val = (val * 10) + (c - '0');
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ goto bad;
+ *pp++ = val, cp++;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (*cp != '\0')
+ goto bad;
+
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ goto bad;
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ goto bad;
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ goto bad;
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ return (htonl(val));
+ bad:
+ return (htonl(INADDR_NONE));
+}
+
+char *
+inet_ntoa(struct in_addr ia)
+{
+ return (intoa(ia.s_addr));
+}
+
+/* Similar to inet_ntoa() */
+char *
+intoa(n_long addr)
+{
+ char *cp;
+ u_int byte;
+ int n;
+ static char buf[17]; /* strlen(".255.255.255.255") + 1 */
+
+ addr = ntohl(addr);
+ cp = &buf[sizeof buf];
+ *--cp = '\0';
+
+ n = 4;
+ do {
+ byte = addr & 0xff;
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0) {
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0)
+ *--cp = byte + '0';
+ }
+ *--cp = '.';
+ addr >>= 8;
+ } while (--n > 0);
+
+ return (cp+1);
+}
+
+static char *
+number(char *s, int *n)
+{
+ for (*n = 0; isdigit(*s); s++)
+ *n = (*n * 10) + *s - '0';
+ return s;
+}
+
+n_long
+ip_convertaddr(char *p)
+{
+#define IP_ANYADDR 0
+ n_long addr = 0, n;
+
+ if (p == (char *)0 || *p == '\0')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 24) & 0xff000000;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 16) & 0xff0000;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 8) & 0xff00;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= n & 0xff;
+ if (*p != '\0')
+ return IP_ANYADDR;
+
+ return htonl(addr);
+}
diff --git a/usr/src/boot/lib/libstand/net.h b/usr/src/boot/lib/libstand/net.h
new file mode 100644
index 0000000000..94f2aabf81
--- /dev/null
+++ b/usr/src/boot/lib/libstand/net.h
@@ -0,0 +1,121 @@
+/* $NetBSD: net.h,v 1.10 1995/10/20 00:46:30 cgd Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _KERNEL /* XXX - see <netinet/in.h> */
+#undef __IPADDR
+#define __IPADDR(x) htonl((u_int32_t)(x))
+#endif
+
+#include "iodesc.h"
+
+#define BA { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
+
+/* Returns true if n_long's on the same net */
+#define SAMENET(a1, a2, m) ((a1.s_addr & m) == (a2.s_addr & m))
+
+#define MACPY(s, d) bcopy((char *)s, (char *)d, 6)
+
+#define MAXTMO 120 /* seconds */
+#define MINTMO 2 /* seconds */
+
+#define FNAME_SIZE 128
+#define IFNAME_SIZE 16
+#define RECV_SIZE 1536 /* XXX delete this */
+
+/*
+ * How much room to leave for headers:
+ * 14: struct ether_header
+ * 20: struct ip
+ * 8: struct udphdr
+ * That's 42 but let's pad it out to 48 bytes.
+ */
+#define ETHER_SIZE 14
+#define HEADER_SIZE 48
+
+extern u_char bcea[6];
+extern char rootpath[FNAME_SIZE];
+extern char bootfile[FNAME_SIZE];
+extern char hostname[FNAME_SIZE];
+extern int hostnamelen;
+extern char domainname[FNAME_SIZE];
+extern int domainnamelen;
+extern char ifname[IFNAME_SIZE];
+
+/* All of these are in network order. */
+extern struct in_addr myip;
+extern struct in_addr rootip;
+extern struct in_addr swapip;
+extern struct in_addr gateip;
+extern struct in_addr nameip;
+extern n_long netmask;
+
+extern int debug; /* defined in the machdep sources */
+
+extern struct iodesc sockets[SOPEN_MAX];
+
+/* ARP/RevARP functions: */
+u_char *arpwhohas(struct iodesc *, struct in_addr);
+void arp_reply(struct iodesc *, void *);
+int rarp_getipaddress(int);
+
+/* Link functions: */
+ssize_t sendether(struct iodesc *d, void *pkt, size_t len,
+ u_char *dea, int etype);
+ssize_t readether(struct iodesc *d, void *pkt, size_t len,
+ time_t tleft, u_int16_t *etype);
+
+ssize_t sendudp(struct iodesc *, void *, size_t);
+ssize_t readudp(struct iodesc *, void *, size_t, time_t);
+ssize_t sendrecv(struct iodesc *,
+ ssize_t (*)(struct iodesc *, void *, size_t),
+ void *, size_t,
+ ssize_t (*)(struct iodesc *, void *, size_t, time_t),
+ void *, size_t);
+
+/* bootp/DHCP */
+void bootp(int, int);
+
+/* Utilities: */
+char *ether_sprintf(u_char *);
+int in_cksum(void *, int);
+char *inet_ntoa(struct in_addr);
+char *intoa(n_long); /* similar to inet_ntoa */
+n_long inet_addr(char *);
+
+/* Machine-dependent functions: */
+time_t getsecs(void);
diff --git a/usr/src/boot/lib/libstand/netif.c b/usr/src/boot/lib/libstand/netif.c
new file mode 100644
index 0000000000..c260690c50
--- /dev/null
+++ b/usr/src/boot/lib/libstand/netif.c
@@ -0,0 +1,335 @@
+/* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Glass.
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/mount.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+struct iodesc sockets[SOPEN_MAX];
+#ifdef NETIF_DEBUG
+int netif_debug = 0;
+#endif
+
+/*
+ * netif_init:
+ *
+ * initialize the generic network interface layer
+ */
+
+void
+netif_init()
+{
+ struct netif_driver *drv;
+ int d, i;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_init: called\n");
+#endif
+ for (d = 0; netif_drivers[d]; d++) {
+ drv = netif_drivers[d];
+ for (i = 0; i < drv->netif_nifs; i++)
+ drv->netif_ifs[i].dif_used = 0;
+ }
+}
+
+int
+netif_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#if 0
+ if (netif_debug)
+ printf("%s%d: netif_match (%d)\n", drv->netif_bname,
+ nif->nif_unit, nif->nif_sel);
+#endif
+ return drv->netif_match(nif, machdep_hint);
+}
+
+struct netif *
+netif_select(machdep_hint)
+ void *machdep_hint;
+{
+ int d, u, unit_done, s;
+ struct netif_driver *drv;
+ struct netif cur_if;
+ static struct netif best_if;
+ int best_val;
+ int val;
+
+ best_val = 0;
+ best_if.nif_driver = NULL;
+
+ for (d = 0; netif_drivers[d] != NULL; d++) {
+ cur_if.nif_driver = netif_drivers[d];
+ drv = cur_if.nif_driver;
+
+ for (u = 0; u < drv->netif_nifs; u++) {
+ cur_if.nif_unit = u;
+ unit_done = 0;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("\t%s%d:", drv->netif_bname,
+ cur_if.nif_unit);
+#endif
+
+ for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
+ cur_if.nif_sel = s;
+
+ if (drv->netif_ifs[u].dif_used & (1 << s)) {
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf(" [%d used]", s);
+#endif
+ continue;
+ }
+
+ val = netif_match(&cur_if, machdep_hint);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf(" [%d -> %d]", s, val);
+#endif
+ if (val > best_val) {
+ best_val = val;
+ best_if = cur_if;
+ }
+ }
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("\n");
+#endif
+ }
+ }
+
+ if (best_if.nif_driver == NULL)
+ return NULL;
+
+ best_if.nif_driver->
+ netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_select: %s%d(%d) wins\n",
+ best_if.nif_driver->netif_bname,
+ best_if.nif_unit, best_if.nif_sel);
+#endif
+ return &best_if;
+}
+
+int
+netif_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
+#endif
+ return drv->netif_probe(nif, machdep_hint);
+}
+
+void
+netif_attach(nif, desc, machdep_hint)
+ struct netif *nif;
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
+#endif
+ desc->io_netif = nif;
+#ifdef PARANOID
+ if (drv->netif_init == NULL)
+ panic("%s%d: no netif_init support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ drv->netif_init(desc, machdep_hint);
+ bzero(drv->netif_ifs[nif->nif_unit].dif_stats,
+ sizeof(struct netif_stats));
+}
+
+void
+netif_detach(nif)
+ struct netif *nif;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_end == NULL)
+ panic("%s%d: no netif_end support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ drv->netif_end(nif);
+}
+
+ssize_t
+netif_get(desc, pkt, len, timo)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timo;
+{
+#ifdef NETIF_DEBUG
+ struct netif *nif = desc->io_netif;
+#endif
+ struct netif_driver *drv = desc->io_netif->nif_driver;
+ ssize_t rv;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_get == NULL)
+ panic("%s%d: no netif_get support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ rv = drv->netif_get(desc, pkt, len, timo);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_get returning %d\n", drv->netif_bname,
+ nif->nif_unit, (int)rv);
+#endif
+ return rv;
+}
+
+ssize_t
+netif_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+#ifdef NETIF_DEBUG
+ struct netif *nif = desc->io_netif;
+#endif
+ struct netif_driver *drv = desc->io_netif->nif_driver;
+ ssize_t rv;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_put == NULL)
+ panic("%s%d: no netif_put support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ rv = drv->netif_put(desc, pkt, len);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_put returning %d\n", drv->netif_bname,
+ nif->nif_unit, (int)rv);
+#endif
+ return rv;
+}
+
+struct iodesc *
+socktodesc(sock)
+ int sock;
+{
+ if (sock >= SOPEN_MAX) {
+ errno = EBADF;
+ return (NULL);
+ }
+ return (&sockets[sock]);
+}
+
+int
+netif_open(machdep_hint)
+ void *machdep_hint;
+{
+ int fd;
+ struct iodesc *s;
+ struct netif *nif;
+
+ /* find a free socket */
+ for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
+ if (s->io_netif == (struct netif *)0)
+ goto fnd;
+ errno = EMFILE;
+ return (-1);
+
+fnd:
+ bzero(s, sizeof(*s));
+ netif_init();
+ nif = netif_select(machdep_hint);
+ if (!nif)
+ panic("netboot: no interfaces left untried");
+ if (netif_probe(nif, machdep_hint)) {
+ printf("netboot: couldn't probe %s%d\n",
+ nif->nif_driver->netif_bname, nif->nif_unit);
+ errno = EINVAL;
+ return(-1);
+ }
+ netif_attach(nif, s, machdep_hint);
+
+ return(fd);
+}
+
+int
+netif_close(sock)
+ int sock;
+{
+ if (sock >= SOPEN_MAX) {
+ errno = EBADF;
+ return(-1);
+ }
+ netif_detach(sockets[sock].io_netif);
+ sockets[sock].io_netif = (struct netif *)0;
+
+ return(0);
+}
diff --git a/usr/src/boot/lib/libstand/netif.h b/usr/src/boot/lib/libstand/netif.h
new file mode 100644
index 0000000000..dac285107a
--- /dev/null
+++ b/usr/src/boot/lib/libstand/netif.h
@@ -0,0 +1,67 @@
+/* $NetBSD: netif.h,v 1.4 1995/09/14 23:45:30 pk Exp $ */
+
+/* $FreeBSD$ */
+
+#ifndef __SYS_LIBNETBOOT_NETIF_H
+#define __SYS_LIBNETBOOT_NETIF_H
+#include "iodesc.h"
+
+#define NENTS(x) sizeof(x)/sizeof(x[0])
+
+struct netif_driver {
+ const char *netif_bname;
+ int (*netif_match)(struct netif *, void *);
+ int (*netif_probe)(struct netif *, void *);
+ void (*netif_init)(struct iodesc *, void *);
+ int (*netif_get)(struct iodesc *, void *, size_t, time_t);
+ int (*netif_put)(struct iodesc *, void *, size_t);
+ void (*netif_end)(struct netif *);
+ struct netif_dif *netif_ifs;
+ int netif_nifs;
+};
+
+struct netif_dif {
+ int dif_unit;
+ int dif_nsel;
+ struct netif_stats *dif_stats;
+ void *dif_private;
+ /* the following fields are used internally by the netif layer */
+ u_long dif_used;
+};
+
+struct netif_stats {
+ int collisions;
+ int collision_error;
+ int missed;
+ int sent;
+ int received;
+ int deferred;
+ int overflow;
+};
+
+struct netif {
+ struct netif_driver *nif_driver;
+ int nif_unit;
+ int nif_sel;
+ void *nif_devdata;
+};
+
+extern struct netif_driver *netif_drivers[]; /* machdep */
+extern int n_netif_drivers;
+
+extern int netif_debug;
+
+void netif_init(void);
+struct netif *netif_select(void *);
+int netif_probe(struct netif *, void *);
+void netif_attach(struct netif *, struct iodesc *, void *);
+void netif_detach(struct netif *);
+ssize_t netif_get(struct iodesc *, void *, size_t, time_t);
+ssize_t netif_put(struct iodesc *, void *, size_t);
+
+int netif_open(void *);
+int netif_close(int);
+
+struct iodesc *socktodesc(int);
+
+#endif /* __SYS_LIBNETBOOT_NETIF_H */
diff --git a/usr/src/boot/lib/libstand/nfs.c b/usr/src/boot/lib/libstand/nfs.c
new file mode 100644
index 0000000000..a0b726cde3
--- /dev/null
+++ b/usr/src/boot/lib/libstand/nfs.c
@@ -0,0 +1,1474 @@
+/* $NetBSD: nfs.c,v 1.2 1998/01/24 12:43:09 drochner Exp $ */
+
+/*-
+ * Copyright (c) 1993 John Brezak
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "rpcv2.h"
+#include "nfsv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+
+#define NFS_DEBUGxx
+
+#define NFSREAD_SIZE 1024
+
+/* Define our own NFS attributes without NQNFS stuff. */
+#ifdef OLD_NFSV2
+struct nfsv2_fattrs {
+ n_long fa_type;
+ n_long fa_mode;
+ n_long fa_nlink;
+ n_long fa_uid;
+ n_long fa_gid;
+ n_long fa_size;
+ n_long fa_blocksize;
+ n_long fa_rdev;
+ n_long fa_blocks;
+ n_long fa_fsid;
+ n_long fa_fileid;
+ struct nfsv2_time fa_atime;
+ struct nfsv2_time fa_mtime;
+ struct nfsv2_time fa_ctime;
+};
+
+struct nfs_read_args {
+ u_char fh[NFS_FHSIZE];
+ n_long off;
+ n_long len;
+ n_long xxx; /* XXX what's this for? */
+};
+
+/* Data part of nfs rpc reply (also the largest thing we receive) */
+struct nfs_read_repl {
+ n_long errno;
+ struct nfsv2_fattrs fa;
+ n_long count;
+ u_char data[NFSREAD_SIZE];
+};
+
+#ifndef NFS_NOSYMLINK
+struct nfs_readlnk_repl {
+ n_long errno;
+ n_long len;
+ char path[NFS_MAXPATHLEN];
+};
+#endif
+
+struct nfs_readdir_args {
+ u_char fh[NFS_FHSIZE];
+ n_long cookie;
+ n_long count;
+};
+
+struct nfs_readdir_data {
+ n_long fileid;
+ n_long len;
+ char name[0];
+};
+
+struct nfs_readdir_off {
+ n_long cookie;
+ n_long follows;
+};
+
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ u_char fh[NFS_FHSIZE];
+ struct nfsv2_fattrs fa; /* all in network order */
+};
+#else /* !OLD_NFSV2 */
+
+/* NFSv3 definitions */
+#define NFS_V3MAXFHSIZE 64
+#define NFS_VER3 3
+#define RPCMNT_VER3 3
+#define NFSPROCV3_LOOKUP 3
+#define NFSPROCV3_READLINK 5
+#define NFSPROCV3_READ 6
+#define NFSPROCV3_READDIR 16
+
+typedef struct {
+ uint32_t val[2];
+} n_quad;
+
+struct nfsv3_time {
+ uint32_t nfs_sec;
+ uint32_t nfs_nsec;
+};
+
+struct nfsv3_fattrs {
+ uint32_t fa_type;
+ uint32_t fa_mode;
+ uint32_t fa_nlink;
+ uint32_t fa_uid;
+ uint32_t fa_gid;
+ n_quad fa_size;
+ n_quad fa_used;
+ n_quad fa_rdev;
+ n_quad fa_fsid;
+ n_quad fa_fileid;
+ struct nfsv3_time fa_atime;
+ struct nfsv3_time fa_mtime;
+ struct nfsv3_time fa_ctime;
+};
+
+/*
+ * For NFSv3, the file handle is variable in size, so most fixed sized
+ * structures for arguments won't work. For most cases, a structure
+ * that starts with any fixed size section is followed by an array
+ * that covers the maximum size required.
+ */
+struct nfsv3_readdir_repl {
+ uint32_t errno;
+ uint32_t ok;
+ struct nfsv3_fattrs fa;
+ uint32_t cookiev0;
+ uint32_t cookiev1;
+};
+
+struct nfsv3_readdir_entry {
+ uint32_t follows;
+ uint32_t fid0;
+ uint32_t fid1;
+ uint32_t len;
+ uint32_t nameplus[0];
+};
+
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ uint32_t fhsize;
+ u_char fh[NFS_V3MAXFHSIZE];
+ struct nfsv3_fattrs fa; /* all in network order */
+ uint64_t cookie;
+};
+#endif /* OLD_NFSV2 */
+
+/*
+ * XXX interactions with tftp? See nfswrapper.c for a confusing
+ * issue.
+ */
+int nfs_open(const char *path, struct open_file *f);
+static int nfs_close(struct open_file *f);
+static int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t nfs_seek(struct open_file *f, off_t offset, int where);
+static int nfs_stat(struct open_file *f, struct stat *sb);
+static int nfs_readdir(struct open_file *f, struct dirent *d);
+
+struct nfs_iodesc nfs_root_node;
+
+struct fs_ops nfs_fsops = {
+ "nfs",
+ nfs_open,
+ nfs_close,
+ nfs_read,
+ nfs_write,
+ nfs_seek,
+ nfs_stat,
+ nfs_readdir
+};
+
+#ifdef OLD_NFSV2
+/*
+ * Fetch the root file handle (call mount daemon)
+ * Return zero or error number.
+ */
+int
+nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp)
+{
+ int len;
+ struct args {
+ n_long len;
+ char path[FNAME_SIZE];
+ } *args;
+ struct repl {
+ n_long errno;
+ u_char fh[NFS_FHSIZE];
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ size_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_getrootfh: %s\n", path);
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ len = strlen(path);
+ if (len > sizeof(args->path))
+ len = sizeof(args->path);
+ args->len = htonl(len);
+ bcopy(path, args->path, len);
+ len = 4 + roundup(len, 4);
+
+ cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT,
+ args, len, repl, sizeof(*repl));
+ if (cc == -1) {
+ /* errno was set by rpc_call */
+ return (errno);
+ }
+ if (cc < 4)
+ return (EBADRPC);
+ if (repl->errno)
+ return (ntohl(repl->errno));
+ bcopy(repl->fh, fhp, sizeof(repl->fh));
+ return (0);
+}
+
+/*
+ * Lookup a file. Store handle and attributes.
+ * Return zero or error number.
+ */
+int
+nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
+{
+ int len, rlen;
+ struct args {
+ u_char fh[NFS_FHSIZE];
+ n_long len;
+ char name[FNAME_SIZE];
+ } *args;
+ struct repl {
+ n_long errno;
+ u_char fh[NFS_FHSIZE];
+ struct nfsv2_fattrs fa;
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("lookupfh: called\n");
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ bcopy(d->fh, args->fh, sizeof(args->fh));
+ len = strlen(name);
+ if (len > sizeof(args->name))
+ len = sizeof(args->name);
+ bcopy(name, args->name, len);
+ args->len = htonl(len);
+ len = 4 + roundup(len, 4);
+ len += NFS_FHSIZE;
+
+ rlen = sizeof(*repl);
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP,
+ args, len, repl, rlen);
+ if (cc == -1)
+ return (errno); /* XXX - from rpc_call */
+ if (cc < 4)
+ return (EIO);
+ if (repl->errno) {
+ /* saerrno.h now matches NFS error numbers. */
+ return (ntohl(repl->errno));
+ }
+ bcopy( repl->fh, &newfd->fh, sizeof(newfd->fh));
+ bcopy(&repl->fa, &newfd->fa, sizeof(newfd->fa));
+ return (0);
+}
+
+#ifndef NFS_NOSYMLINK
+/*
+ * Get the destination of a symbolic link.
+ */
+int
+nfs_readlink(struct nfs_iodesc *d, char *buf)
+{
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ u_char fh[NFS_FHSIZE];
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_readlnk_repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("readlink: called\n");
+#endif
+
+ bcopy(d->fh, sdata.fh, NFS_FHSIZE);
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READLINK,
+ sdata.fh, NFS_FHSIZE,
+ &rdata.d, sizeof(rdata.d));
+ if (cc == -1)
+ return (errno);
+
+ if (cc < 4)
+ return (EIO);
+
+ if (rdata.d.errno)
+ return (ntohl(rdata.d.errno));
+
+ rdata.d.len = ntohl(rdata.d.len);
+ if (rdata.d.len > NFS_MAXPATHLEN)
+ return (ENAMETOOLONG);
+
+ bcopy(rdata.d.path, buf, rdata.d.len);
+ buf[rdata.d.len] = 0;
+ return (0);
+}
+#endif
+
+/*
+ * Read data from a file.
+ * Return transfer count or -1 (and set errno)
+ */
+ssize_t
+nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
+{
+ struct nfs_read_args *args;
+ struct nfs_read_repl *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_read_args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_read_repl d;
+ } rdata;
+ size_t cc;
+ long x;
+ int hlen, rlen;
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bcopy(d->fh, args->fh, NFS_FHSIZE);
+ args->off = htonl((n_long)off);
+ if (len > NFSREAD_SIZE)
+ len = NFSREAD_SIZE;
+ args->len = htonl((n_long)len);
+ args->xxx = htonl((n_long)0);
+ hlen = sizeof(*repl) - NFSREAD_SIZE;
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ,
+ args, sizeof(*args),
+ repl, sizeof(*repl));
+ if (cc == -1) {
+ /* errno was already set by rpc_call */
+ return (-1);
+ }
+ if (cc < hlen) {
+ errno = EBADRPC;
+ return (-1);
+ }
+ if (repl->errno) {
+ errno = ntohl(repl->errno);
+ return (-1);
+ }
+ rlen = cc - hlen;
+ x = ntohl(repl->count);
+ if (rlen < x) {
+ printf("nfsread: short packet, %d < %ld\n", rlen, x);
+ errno = EBADRPC;
+ return(-1);
+ }
+ bcopy(repl->data, addr, x);
+ return (x);
+}
+
+/*
+ * Open a file.
+ * return zero or error number
+ */
+int
+nfs_open(const char *upath, struct open_file *f)
+{
+ struct iodesc *desc;
+ struct nfs_iodesc *currfd;
+ char buf[2 * NFS_FHSIZE + 3];
+ u_char *fh;
+ char *cp;
+ int i;
+#ifndef NFS_NOSYMLINK
+ struct nfs_iodesc *newfd;
+ struct nfsv2_fattrs *fa;
+ char *ncp;
+ int c;
+ char namebuf[NFS_MAXPATHLEN + 1];
+ char linkbuf[NFS_MAXPATHLEN + 1];
+ int nlinks = 0;
+#endif
+ int error;
+ char *path;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);
+#endif
+ if (!rootpath[0]) {
+ printf("no rootpath, no nfs\n");
+ return (ENXIO);
+ }
+
+ /*
+ * This is silly - we should look at dv_type but that value is
+ * arch dependant and we can't use it here.
+ */
+#ifndef __i386__
+ if (strcmp(f->f_dev->dv_name, "net") != 0)
+ return(EINVAL);
+#else
+ if (strcmp(f->f_dev->dv_name, "pxe") != 0)
+ return(EINVAL);
+#endif
+
+ if (!(desc = socktodesc(*(int *)(f->f_devdata))))
+ return(EINVAL);
+
+ /* Bind to a reserved port. */
+ desc->myport = htons(--rpc_port);
+ desc->destip = rootip;
+ if ((error = nfs_getrootfh(desc, rootpath, nfs_root_node.fh)))
+ return (error);
+ nfs_root_node.fa.fa_type = htonl(NFDIR);
+ nfs_root_node.fa.fa_mode = htonl(0755);
+ nfs_root_node.fa.fa_nlink = htonl(2);
+ nfs_root_node.iodesc = desc;
+
+ fh = &nfs_root_node.fh[0];
+ buf[0] = 'X';
+ cp = &buf[1];
+ for (i = 0; i < NFS_FHSIZE; i++, cp += 2)
+ sprintf(cp, "%02x", fh[i]);
+ sprintf(cp, "X");
+ setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
+ setenv("boot.nfsroot.path", rootpath, 1);
+ setenv("boot.nfsroot.nfshandle", buf, 1);
+
+ /* Allocate file system specific data structure */
+ currfd = malloc(sizeof(*newfd));
+ if (currfd == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+
+#ifndef NFS_NOSYMLINK
+ bcopy(&nfs_root_node, currfd, sizeof(*currfd));
+ newfd = 0;
+
+ cp = path = strdup(upath);
+ if (path == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ while (*cp) {
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+
+ if (*cp == '\0')
+ break;
+ /*
+ * Check that current node is a directory.
+ */
+ if (currfd->fa.fa_type != htonl(NFDIR)) {
+ error = ENOTDIR;
+ goto out;
+ }
+
+ /* allocate file system specific data structure */
+ newfd = malloc(sizeof(*newfd));
+ newfd->iodesc = currfd->iodesc;
+
+ /*
+ * Get next component of path name.
+ */
+ {
+ int len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > NFS_MAXNAMLEN) {
+ error = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+ }
+
+ /* lookup a file handle */
+ error = nfs_lookupfh(currfd, ncp, newfd);
+ *cp = c;
+ if (error)
+ goto out;
+
+ /*
+ * Check for symbolic link
+ */
+ if (newfd->fa.fa_type == htonl(NFLNK)) {
+ int link_len, len;
+
+ error = nfs_readlink(newfd, linkbuf);
+ if (error)
+ goto out;
+
+ link_len = strlen(linkbuf);
+ len = strlen(cp);
+
+ if (link_len + len > MAXPATHLEN
+ || ++nlinks > MAXSYMLINKS) {
+ error = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+ bcopy(linkbuf, namebuf, link_len);
+
+ /*
+ * If absolute pathname, restart at root.
+ * If relative pathname, restart at parent directory.
+ */
+ cp = namebuf;
+ if (*cp == '/')
+ bcopy(&nfs_root_node, currfd, sizeof(*currfd));
+
+ free(newfd);
+ newfd = 0;
+
+ continue;
+ }
+
+ free(currfd);
+ currfd = newfd;
+ newfd = 0;
+ }
+
+ error = 0;
+
+out:
+ free(newfd);
+ free(path);
+#else
+ currfd->iodesc = desc;
+
+ error = nfs_lookupfh(&nfs_root_node, upath, currfd);
+#endif
+ if (!error) {
+ currfd->off = 0;
+ f->f_fsdata = (void *)currfd;
+ return (0);
+ }
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s lookupfh failed: %s\n",
+ path, strerror(error));
+#endif
+ free(currfd);
+
+ return (error);
+}
+
+int
+nfs_close(struct open_file *f)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_close: fp=0x%lx\n", (u_long)fp);
+#endif
+
+ if (fp)
+ free(fp);
+ f->f_fsdata = (void *)0;
+
+ return (0);
+}
+
+/*
+ * read a portion of a file
+ */
+int
+nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ ssize_t cc;
+ char *addr = buf;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: size=%lu off=%d\n", (u_long)size,
+ (int)fp->off);
+#endif
+ while ((int)size > 0) {
+ twiddle(16);
+ cc = nfs_readdata(fp, fp->off, (void *)addr, size);
+ /* XXX maybe should retry on certain errors */
+ if (cc == -1) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: read: %s", strerror(errno));
+#endif
+ return (errno); /* XXX - from nfs_readdata */
+ }
+ if (cc == 0) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: hit EOF unexpectantly");
+#endif
+ goto ret;
+ }
+ fp->off += cc;
+ addr += cc;
+ size -= cc;
+ }
+ret:
+ if (resid)
+ *resid = size;
+
+ return (0);
+}
+
+/*
+ * Not implemented.
+ */
+int
+nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ return (EROFS);
+}
+
+off_t
+nfs_seek(struct open_file *f, off_t offset, int where)
+{
+ struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata;
+ n_long size = ntohl(d->fa.fa_size);
+
+ switch (where) {
+ case SEEK_SET:
+ d->off = offset;
+ break;
+ case SEEK_CUR:
+ d->off += offset;
+ break;
+ case SEEK_END:
+ d->off = size - offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ return (d->off);
+}
+
+/* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 */
+int nfs_stat_types[8] = {
+ 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, 0 };
+
+int
+nfs_stat(struct open_file *f, struct stat *sb)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ n_long ftype, mode;
+
+ ftype = ntohl(fp->fa.fa_type);
+ mode = ntohl(fp->fa.fa_mode);
+ mode |= nfs_stat_types[ftype & 7];
+
+ sb->st_mode = mode;
+ sb->st_nlink = ntohl(fp->fa.fa_nlink);
+ sb->st_uid = ntohl(fp->fa.fa_uid);
+ sb->st_gid = ntohl(fp->fa.fa_gid);
+ sb->st_size = ntohl(fp->fa.fa_size);
+
+ return (0);
+}
+
+static int
+nfs_readdir(struct open_file *f, struct dirent *d)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ struct nfs_readdir_args *args;
+ struct nfs_readdir_data *rd;
+ struct nfs_readdir_off *roff = NULL;
+ static char *buf;
+ static struct nfs_iodesc *pfp = NULL;
+ static n_long cookie = 0;
+ size_t cc;
+ n_long eof;
+
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_readdir_args d;
+ } sdata;
+ static struct {
+ n_long h[RPC_HEADER_WORDS];
+ u_char d[NFS_READDIRSIZE];
+ } rdata;
+
+ if (fp != pfp || fp->off != cookie) {
+ pfp = NULL;
+ refill:
+ args = &sdata.d;
+ bzero(args, sizeof(*args));
+
+ bcopy(fp->fh, args->fh, NFS_FHSIZE);
+ args->cookie = htonl(fp->off);
+ args->count = htonl(NFS_READDIRSIZE);
+
+ cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READDIR,
+ args, sizeof(*args),
+ rdata.d, sizeof(rdata.d));
+ buf = rdata.d;
+ roff = (struct nfs_readdir_off *)buf;
+ if (ntohl(roff->cookie) != 0)
+ return EIO;
+ pfp = fp;
+ cookie = fp->off;
+ }
+ roff = (struct nfs_readdir_off *)buf;
+
+ if (ntohl(roff->follows) == 0) {
+ eof = ntohl((roff+1)->cookie);
+ if (eof) {
+ cookie = 0;
+ return ENOENT;
+ }
+ goto refill;
+ }
+
+ buf += sizeof(struct nfs_readdir_off);
+ rd = (struct nfs_readdir_data *)buf;
+ d->d_namlen = ntohl(rd->len);
+ bcopy(rd->name, d->d_name, d->d_namlen);
+ d->d_name[d->d_namlen] = '\0';
+
+ buf += (sizeof(struct nfs_readdir_data) + roundup(htonl(rd->len),4));
+ roff = (struct nfs_readdir_off *)buf;
+ fp->off = cookie = ntohl(roff->cookie);
+ return 0;
+}
+#else /* !OLD_NFSV2 */
+/*
+ * Fetch the root file handle (call mount daemon)
+ * Return zero or error number.
+ */
+int
+nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
+{
+ int len;
+ struct args {
+ uint32_t len;
+ char path[FNAME_SIZE];
+ } *args;
+ struct repl {
+ uint32_t errno;
+ uint32_t fhsize;
+ u_char fh[NFS_V3MAXFHSIZE];
+ uint32_t authcnt;
+ uint32_t auth[7];
+ } *repl;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ size_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_getrootfh: %s\n", path);
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ len = strlen(path);
+ if (len > sizeof(args->path))
+ len = sizeof(args->path);
+ args->len = htonl(len);
+ bcopy(path, args->path, len);
+ len = sizeof(uint32_t) + roundup(len, sizeof(uint32_t));
+
+ cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT,
+ args, len, repl, sizeof(*repl));
+ if (cc == -1)
+ /* errno was set by rpc_call */
+ return (errno);
+ if (cc < 2 * sizeof (uint32_t))
+ return (EBADRPC);
+ if (repl->errno != 0)
+ return (ntohl(repl->errno));
+ *fhlenp = ntohl(repl->fhsize);
+ bcopy(repl->fh, fhp, *fhlenp);
+ return (0);
+}
+
+/*
+ * Lookup a file. Store handle and attributes.
+ * Return zero or error number.
+ */
+int
+nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
+{
+ int len, rlen, pos;
+ struct args {
+ uint32_t fhsize;
+ uint32_t fhplusname[1 +
+ (NFS_V3MAXFHSIZE + FNAME_SIZE) / sizeof(uint32_t)];
+ } *args;
+ struct repl {
+ uint32_t errno;
+ uint32_t fhsize;
+ uint32_t fhplusattr[(NFS_V3MAXFHSIZE +
+ 2 * (sizeof(uint32_t) +
+ sizeof(struct nfsv3_fattrs))) / sizeof(uint32_t)];
+ } *repl;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("lookupfh: called\n");
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ args->fhsize = htonl(d->fhsize);
+ bcopy(d->fh, args->fhplusname, d->fhsize);
+ len = strlen(name);
+ if (len > FNAME_SIZE)
+ len = FNAME_SIZE;
+ pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
+ args->fhplusname[pos++] = htonl(len);
+ bcopy(name, &args->fhplusname[pos], len);
+ len = sizeof(uint32_t) + pos * sizeof(uint32_t) +
+ roundup(len, sizeof(uint32_t));
+
+ rlen = sizeof(*repl);
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_LOOKUP,
+ args, len, repl, rlen);
+ if (cc == -1)
+ return (errno); /* XXX - from rpc_call */
+ if (cc < 2 * sizeof(uint32_t))
+ return (EIO);
+ if (repl->errno != 0)
+ /* saerrno.h now matches NFS error numbers. */
+ return (ntohl(repl->errno));
+ newfd->fhsize = ntohl(repl->fhsize);
+ bcopy(repl->fhplusattr, &newfd->fh, newfd->fhsize);
+ pos = roundup(newfd->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
+ if (repl->fhplusattr[pos++] == 0)
+ return (EIO);
+ bcopy(&repl->fhplusattr[pos], &newfd->fa, sizeof(newfd->fa));
+ return (0);
+}
+
+#ifndef NFS_NOSYMLINK
+/*
+ * Get the destination of a symbolic link.
+ */
+int
+nfs_readlink(struct nfs_iodesc *d, char *buf)
+{
+ struct args {
+ uint32_t fhsize;
+ u_char fh[NFS_V3MAXFHSIZE];
+ } *args;
+ struct repl {
+ uint32_t errno;
+ uint32_t ok;
+ struct nfsv3_fattrs fa;
+ uint32_t len;
+ u_char path[NFS_MAXPATHLEN];
+ } *repl;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("readlink: called\n");
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ args->fhsize = htonl(d->fhsize);
+ bcopy(d->fh, args->fh, d->fhsize);
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READLINK,
+ args, sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
+ repl, sizeof(*repl));
+ if (cc == -1)
+ return (errno);
+
+ if (cc < 2 * sizeof(uint32_t))
+ return (EIO);
+
+ if (repl->errno != 0)
+ return (ntohl(repl->errno));
+
+ if (repl->ok == 0)
+ return (EIO);
+
+ repl->len = ntohl(repl->len);
+ if (repl->len > NFS_MAXPATHLEN)
+ return (ENAMETOOLONG);
+
+ bcopy(repl->path, buf, repl->len);
+ buf[repl->len] = 0;
+ return (0);
+}
+#endif
+
+/*
+ * Read data from a file.
+ * Return transfer count or -1 (and set errno)
+ */
+ssize_t
+nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
+{
+ struct args {
+ uint32_t fhsize;
+ uint32_t fhoffcnt[NFS_V3MAXFHSIZE / sizeof(uint32_t) + 3];
+ } *args;
+ struct repl {
+ uint32_t errno;
+ uint32_t ok;
+ struct nfsv3_fattrs fa;
+ uint32_t count;
+ uint32_t eof;
+ uint32_t len;
+ u_char data[NFSREAD_SIZE];
+ } *repl;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ size_t cc;
+ long x;
+ int hlen, rlen, pos;
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ args->fhsize = htonl(d->fhsize);
+ bcopy(d->fh, args->fhoffcnt, d->fhsize);
+ pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
+ args->fhoffcnt[pos++] = 0;
+ args->fhoffcnt[pos++] = htonl((uint32_t)off);
+ if (len > NFSREAD_SIZE)
+ len = NFSREAD_SIZE;
+ args->fhoffcnt[pos] = htonl((uint32_t)len);
+ hlen = sizeof(*repl) - NFSREAD_SIZE;
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ,
+ args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
+ repl, sizeof(*repl));
+ if (cc == -1)
+ /* errno was already set by rpc_call */
+ return (-1);
+ if (cc < hlen) {
+ errno = EBADRPC;
+ return (-1);
+ }
+ if (repl->errno != 0) {
+ errno = ntohl(repl->errno);
+ return (-1);
+ }
+ rlen = cc - hlen;
+ x = ntohl(repl->count);
+ if (rlen < x) {
+ printf("nfsread: short packet, %d < %ld\n", rlen, x);
+ errno = EBADRPC;
+ return (-1);
+ }
+ bcopy(repl->data, addr, x);
+ return (x);
+}
+
+/*
+ * Open a file.
+ * return zero or error number
+ */
+int
+nfs_open(const char *upath, struct open_file *f)
+{
+ struct iodesc *desc;
+ struct nfs_iodesc *currfd;
+ char buf[2 * NFS_V3MAXFHSIZE + 3];
+ u_char *fh;
+ char *cp;
+ int i;
+#ifndef NFS_NOSYMLINK
+ struct nfs_iodesc *newfd;
+ struct nfsv3_fattrs *fa;
+ char *ncp;
+ int c;
+ char namebuf[NFS_MAXPATHLEN + 1];
+ char linkbuf[NFS_MAXPATHLEN + 1];
+ int nlinks = 0;
+#endif
+ int error;
+ char *path;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);
+#endif
+ if (!rootpath[0]) {
+ printf("no rootpath, no nfs\n");
+ return (ENXIO);
+ }
+
+ /*
+ * This is silly - we should look at dv_type but that value is
+ * arch dependant and we can't use it here.
+ */
+#ifndef __i386__
+ if (strcmp(f->f_dev->dv_name, "net") != 0)
+ return (EINVAL);
+#else
+ if (strcmp(f->f_dev->dv_name, "pxe") != 0)
+ return (EINVAL);
+#endif
+
+ if (!(desc = socktodesc(*(int *)(f->f_devdata))))
+ return (EINVAL);
+
+ /* Bind to a reserved port. */
+ desc->myport = htons(--rpc_port);
+ desc->destip = rootip;
+ if ((error = nfs_getrootfh(desc, rootpath, &nfs_root_node.fhsize,
+ nfs_root_node.fh)))
+ return (error);
+ nfs_root_node.fa.fa_type = htonl(NFDIR);
+ nfs_root_node.fa.fa_mode = htonl(0755);
+ nfs_root_node.fa.fa_nlink = htonl(2);
+ nfs_root_node.iodesc = desc;
+
+ fh = &nfs_root_node.fh[0];
+ buf[0] = 'X';
+ cp = &buf[1];
+ for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2)
+ sprintf(cp, "%02x", fh[i]);
+ sprintf(cp, "X");
+ setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
+ setenv("boot.nfsroot.path", rootpath, 1);
+ setenv("boot.nfsroot.nfshandle", buf, 1);
+ sprintf(buf, "%d", nfs_root_node.fhsize);
+ setenv("boot.nfsroot.nfshandlelen", buf, 1);
+
+ /* Allocate file system specific data structure */
+ currfd = malloc(sizeof(*newfd));
+ if (currfd == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+#ifndef NFS_NOSYMLINK
+ bcopy(&nfs_root_node, currfd, sizeof(*currfd));
+ newfd = 0;
+
+ cp = path = strdup(upath);
+ if (path == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ while (*cp) {
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+
+ if (*cp == '\0')
+ break;
+ /*
+ * Check that current node is a directory.
+ */
+ if (currfd->fa.fa_type != htonl(NFDIR)) {
+ error = ENOTDIR;
+ goto out;
+ }
+
+ /* allocate file system specific data structure */
+ newfd = malloc(sizeof(*newfd));
+ if (newfd == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ newfd->iodesc = currfd->iodesc;
+
+ /*
+ * Get next component of path name.
+ */
+ {
+ int len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > NFS_MAXNAMLEN) {
+ error = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+ }
+
+ /* lookup a file handle */
+ error = nfs_lookupfh(currfd, ncp, newfd);
+ *cp = c;
+ if (error)
+ goto out;
+
+ /*
+ * Check for symbolic link
+ */
+ if (newfd->fa.fa_type == htonl(NFLNK)) {
+ int link_len, len;
+
+ error = nfs_readlink(newfd, linkbuf);
+ if (error)
+ goto out;
+
+ link_len = strlen(linkbuf);
+ len = strlen(cp);
+
+ if (link_len + len > MAXPATHLEN
+ || ++nlinks > MAXSYMLINKS) {
+ error = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+ bcopy(linkbuf, namebuf, link_len);
+
+ /*
+ * If absolute pathname, restart at root.
+ * If relative pathname, restart at parent directory.
+ */
+ cp = namebuf;
+ if (*cp == '/')
+ bcopy(&nfs_root_node, currfd, sizeof(*currfd));
+
+ free(newfd);
+ newfd = 0;
+
+ continue;
+ }
+
+ free(currfd);
+ currfd = newfd;
+ newfd = 0;
+ }
+
+ error = 0;
+
+out:
+ free(newfd);
+ free(path);
+#else
+ currfd->iodesc = desc;
+
+ error = nfs_lookupfh(&nfs_root_node, upath, currfd);
+#endif
+ if (!error) {
+ currfd->off = 0;
+ currfd->cookie = 0;
+ f->f_fsdata = (void *)currfd;
+ return (0);
+ }
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s lookupfh failed: %s\n",
+ path, strerror(error));
+#endif
+ free(currfd);
+
+ return (error);
+}
+
+int
+nfs_close(struct open_file *f)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_close: fp=0x%lx\n", (u_long)fp);
+#endif
+
+ if (fp)
+ free(fp);
+ f->f_fsdata = (void *)0;
+
+ return (0);
+}
+
+/*
+ * read a portion of a file
+ */
+int
+nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ ssize_t cc;
+ char *addr = buf;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: size=%lu off=%d\n", (u_long)size,
+ (int)fp->off);
+#endif
+ while ((int)size > 0) {
+ twiddle(16);
+ cc = nfs_readdata(fp, fp->off, (void *)addr, size);
+ /* XXX maybe should retry on certain errors */
+ if (cc == -1) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: read: %s", strerror(errno));
+#endif
+ return (errno); /* XXX - from nfs_readdata */
+ }
+ if (cc == 0) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: hit EOF unexpectantly");
+#endif
+ goto ret;
+ }
+ fp->off += cc;
+ addr += cc;
+ size -= cc;
+ }
+ret:
+ if (resid)
+ *resid = size;
+
+ return (0);
+}
+
+/*
+ * Not implemented.
+ */
+int
+nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ return (EROFS);
+}
+
+off_t
+nfs_seek(struct open_file *f, off_t offset, int where)
+{
+ struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata;
+ uint32_t size = ntohl(d->fa.fa_size.val[1]);
+
+ switch (where) {
+ case SEEK_SET:
+ d->off = offset;
+ break;
+ case SEEK_CUR:
+ d->off += offset;
+ break;
+ case SEEK_END:
+ d->off = size - offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ return (d->off);
+}
+
+/* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5, NFSOCK=6, NFFIFO=7 */
+int nfs_stat_types[9] = {
+ 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO, 0 };
+
+int
+nfs_stat(struct open_file *f, struct stat *sb)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ uint32_t ftype, mode;
+
+ ftype = ntohl(fp->fa.fa_type);
+ mode = ntohl(fp->fa.fa_mode);
+ mode |= nfs_stat_types[ftype & 7];
+
+ sb->st_mode = mode;
+ sb->st_nlink = ntohl(fp->fa.fa_nlink);
+ sb->st_uid = ntohl(fp->fa.fa_uid);
+ sb->st_gid = ntohl(fp->fa.fa_gid);
+ sb->st_size = ntohl(fp->fa.fa_size.val[1]);
+
+ return (0);
+}
+
+static int
+nfs_readdir(struct open_file *f, struct dirent *d)
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ struct nfsv3_readdir_repl *repl;
+ struct nfsv3_readdir_entry *rent;
+ static char *buf;
+ static struct nfs_iodesc *pfp = NULL;
+ static uint64_t cookie = 0;
+ size_t cc;
+ int pos;
+
+ struct args {
+ uint32_t fhsize;
+ uint32_t fhpluscookie[5 + NFS_V3MAXFHSIZE];
+ } *args;
+ struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ static struct {
+ uint32_t h[RPC_HEADER_WORDS];
+ u_char d[NFS_READDIRSIZE];
+ } rdata;
+
+ if (fp != pfp || fp->off != cookie) {
+ pfp = NULL;
+ refill:
+ args = &sdata.d;
+ bzero(args, sizeof(*args));
+
+ args->fhsize = htonl(fp->fhsize);
+ bcopy(fp->fh, args->fhpluscookie, fp->fhsize);
+ pos = roundup(fp->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
+ args->fhpluscookie[pos++] = htonl(fp->off >> 32);
+ args->fhpluscookie[pos++] = htonl(fp->off);
+ args->fhpluscookie[pos++] = htonl(fp->cookie >> 32);
+ args->fhpluscookie[pos++] = htonl(fp->cookie);
+ args->fhpluscookie[pos] = htonl(NFS_READDIRSIZE);
+
+ cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READDIR,
+ args, 6 * sizeof(uint32_t) +
+ roundup(fp->fhsize, sizeof(uint32_t)),
+ rdata.d, sizeof(rdata.d));
+ buf = rdata.d;
+ repl = (struct nfsv3_readdir_repl *)buf;
+ if (repl->errno != 0)
+ return (ntohl(repl->errno));
+ pfp = fp;
+ cookie = fp->off;
+ fp->cookie = ((uint64_t)ntohl(repl->cookiev0) << 32) |
+ ntohl(repl->cookiev1);
+ buf += sizeof (struct nfsv3_readdir_repl);
+ }
+ rent = (struct nfsv3_readdir_entry *)buf;
+
+ if (rent->follows == 0) {
+ /* fid0 is actually eof */
+ if (rent->fid0 != 0) {
+ cookie = 0;
+ return (ENOENT);
+ }
+ goto refill;
+ }
+
+ d->d_namlen = ntohl(rent->len);
+ bcopy(rent->nameplus, d->d_name, d->d_namlen);
+ d->d_name[d->d_namlen] = '\0';
+
+ pos = roundup(d->d_namlen, sizeof(uint32_t)) / sizeof(uint32_t);
+ fp->off = cookie = ((uint64_t)ntohl(rent->nameplus[pos]) << 32) |
+ ntohl(rent->nameplus[pos + 1]);
+ pos += 2;
+ buf = (u_char *)&rent->nameplus[pos];
+ return (0);
+}
+#endif /* OLD_NFSV2 */
diff --git a/usr/src/boot/lib/libstand/nfsv2.h b/usr/src/boot/lib/libstand/nfsv2.h
new file mode 100644
index 0000000000..a6f1c4f770
--- /dev/null
+++ b/usr/src/boot/lib/libstand/nfsv2.h
@@ -0,0 +1,164 @@
+/* $FreeBSD$ */
+/* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)nfsv2.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * nfs definitions as per the version 2 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 spec.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_MAXDGRAMDATA 8192
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_FHSIZE 32
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+#define NFS_READDIRSIZE 1024
+
+/* Stat numbers for rpc returns */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_WFLUSH 99
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_FH 32
+#define NFSX_UNSIGNED 4
+#define NFSX_FATTR 68
+#define NFSX_SATTR 32
+#define NFSX_STATFS 20
+#define NFSX_COOKIE 4
+
+/* nfs rpc procedure numbers */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_NOOP 3
+#define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+#define NFS_NPROCS 18
+
+
+/* File types */
+typedef enum {
+ NFNON=0,
+ NFREG=1,
+ NFDIR=2,
+ NFBLK=3,
+ NFCHR=4,
+ NFLNK=5
+} nfstype;
+
+/* Structs for common parts of the rpc's */
+struct nfsv2_time {
+ n_long nfs_sec;
+ n_long nfs_usec;
+};
+
+/*
+ * File attributes and setable attributes.
+ */
+struct nfsv2_fattr {
+ n_long fa_type;
+ n_long fa_mode;
+ n_long fa_nlink;
+ n_long fa_uid;
+ n_long fa_gid;
+ n_long fa_size;
+ n_long fa_blocksize;
+ n_long fa_rdev;
+ n_long fa_blocks;
+ n_long fa_fsid;
+ n_long fa_fileid;
+ struct nfsv2_time fa_atime;
+ struct nfsv2_time fa_mtime;
+ struct nfsv2_time fa_ctime;
+};
+
+struct nfsv2_sattr {
+ n_long sa_mode;
+ n_long sa_uid;
+ n_long sa_gid;
+ n_long sa_size;
+ struct nfsv2_time sa_atime;
+ struct nfsv2_time sa_mtime;
+};
+
+struct nfsv2_statfs {
+ n_long sf_tsize;
+ n_long sf_bsize;
+ n_long sf_blocks;
+ n_long sf_bfree;
+ n_long sf_bavail;
+};
diff --git a/usr/src/boot/lib/libstand/nullfs.c b/usr/src/boot/lib/libstand/nullfs.c
new file mode 100644
index 0000000000..e4c0b7cbc4
--- /dev/null
+++ b/usr/src/boot/lib/libstand/nullfs.c
@@ -0,0 +1,105 @@
+/* $NetBSD: nullfs.c,v 1.1 1996/01/13 22:25:39 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)open.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+/*
+ * Null filesystem
+ */
+int null_open (const char *path, struct open_file *f)
+{
+ return EINVAL;
+}
+
+int null_close(struct open_file *f)
+{
+ return 0;
+}
+
+int null_read (struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ return EIO;
+}
+
+int null_write (struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ return EIO;
+}
+
+off_t null_seek (struct open_file *f, off_t offset, int where)
+{
+ errno = EIO;
+ return -1;
+}
+
+int null_stat (struct open_file *f, struct stat *sb)
+{
+ return EIO;
+}
+
+int null_readdir(struct open_file *f, struct dirent *d)
+{
+ return EIO;
+}
diff --git a/usr/src/boot/lib/libstand/open.c b/usr/src/boot/lib/libstand/open.c
new file mode 100644
index 0000000000..0d90433800
--- /dev/null
+++ b/usr/src/boot/lib/libstand/open.c
@@ -0,0 +1,159 @@
+/* $NetBSD: open.c,v 1.16 1997/01/28 09:41:03 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)open.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+struct fs_ops *exclusive_file_system;
+
+struct open_file files[SOPEN_MAX];
+
+static int
+o_gethandle(void)
+{
+ int fd;
+
+ for (fd = 0; fd < SOPEN_MAX; fd++)
+ if (files[fd].f_flags == 0)
+ return(fd);
+ return(-1);
+}
+
+static void
+o_rainit(struct open_file *f)
+{
+ f->f_rabuf = malloc(SOPEN_RASIZE);
+ f->f_ralen = 0;
+ f->f_raoffset = 0;
+}
+
+int
+open(const char *fname, int mode)
+{
+ struct fs_ops *fs;
+ struct open_file *f;
+ int fd, i, error, besterror;
+ const char *file;
+
+ if ((fd = o_gethandle()) == -1) {
+ errno = EMFILE;
+ return(-1);
+ }
+
+ f = &files[fd];
+ f->f_flags = mode + 1;
+ f->f_dev = (struct devsw *)0;
+ f->f_ops = (struct fs_ops *)0;
+ f->f_offset = 0;
+ f->f_devdata = NULL;
+ file = (char *)0;
+
+ if (exclusive_file_system != NULL) {
+ fs = exclusive_file_system;
+ error = (fs->fo_open)(fname, f);
+ if (error == 0)
+ goto ok;
+ goto fail;
+ }
+
+ error = devopen(f, fname, &file);
+ if (error ||
+ (((f->f_flags & F_NODEV) == 0) && f->f_dev == (struct devsw *)0))
+ goto err;
+
+ /* see if we opened a raw device; otherwise, 'file' is the file name. */
+ if (file == (char *)0 || *file == '\0') {
+ f->f_flags |= F_RAW;
+ f->f_rabuf = NULL;
+ return (fd);
+ }
+
+ /* pass file name to the different filesystem open routines */
+ besterror = ENOENT;
+ for (i = 0; file_system[i] != NULL; i++) {
+ fs = file_system[i];
+ error = (fs->fo_open)(file, f);
+ if (error == 0)
+ goto ok;
+ if (error != EINVAL)
+ besterror = error;
+ }
+ error = besterror;
+
+ fail:
+ if ((f->f_flags & F_NODEV) == 0 && f->f_dev != NULL)
+ f->f_dev->dv_close(f);
+ if (error)
+ devclose(f);
+
+ err:
+ f->f_flags = 0;
+ errno = error;
+ return (-1);
+
+ ok:
+ f->f_ops = fs;
+ o_rainit(f);
+ return (fd);
+}
diff --git a/usr/src/boot/lib/libstand/pager.c b/usr/src/boot/lib/libstand/pager.c
new file mode 100644
index 0000000000..a966b0bd79
--- /dev/null
+++ b/usr/src/boot/lib/libstand/pager.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/*
+ * Simple paged-output and paged-viewing functions
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+#include <string.h>
+
+static int p_maxlines = -1;
+static int p_freelines;
+
+static char *pager_prompt1 = " --more-- <space> page down <enter> line down <q> quit ";
+static char *pager_blank = " ";
+
+/*
+ * 'open' the pager
+ */
+void
+pager_open(void)
+{
+ int nlines;
+ char *cp, *lp;
+
+ nlines = 24; /* sensible default */
+ if ((cp = getenv("LINES")) != NULL) {
+ nlines = strtol(cp, &lp, 0);
+ }
+
+ p_maxlines = nlines - 1;
+ if (p_maxlines < 1)
+ p_maxlines = 1;
+ p_freelines = p_maxlines;
+}
+
+/*
+ * 'close' the pager
+ */
+void
+pager_close(void)
+{
+ p_maxlines = -1;
+}
+
+/*
+ * Emit lines to the pager; may not return until the user
+ * has responded to the prompt.
+ *
+ * Will return nonzero if the user enters 'q' or 'Q' at the prompt.
+ *
+ * XXX note that this watches outgoing newlines (and eats them), but
+ * does not handle wrap detection (req. count of columns).
+ */
+
+int
+pager_output(const char *cp)
+{
+ int action;
+
+ if (cp == NULL)
+ return(0);
+
+ for (;;) {
+ if (*cp == 0)
+ return(0);
+
+ putchar(*cp); /* always emit character */
+
+ if (*(cp++) == '\n') { /* got a newline? */
+ p_freelines--;
+ if (p_freelines <= 0) {
+ printf("%s", pager_prompt1);
+ action = 0;
+ while (action == 0) {
+ switch(getchar()) {
+ case '\r':
+ case '\n':
+ p_freelines = 1;
+ action = 1;
+ break;
+ case ' ':
+ p_freelines = p_maxlines;
+ action = 1;
+ break;
+ case 'q':
+ case 'Q':
+ action = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ printf("\r%s\r", pager_blank);
+ if (action == 2)
+ return(1);
+ }
+ }
+ }
+}
+
+/*
+ * Display from (fd).
+ */
+int
+pager_file(const char *fname)
+{
+ char buf[80];
+ size_t hmuch;
+ int fd;
+ int result;
+
+ if ((fd = open(fname, O_RDONLY)) == -1) {
+ printf("can't open '%s': %s\n", fname, strerror(errno));
+ return(-1);
+ }
+
+ for (;;) {
+ hmuch = read(fd, buf, sizeof(buf) - 1);
+ if (hmuch == -1) {
+ result = -1;
+ break;
+ }
+ if (hmuch == 0) {
+ result = 0;
+ break;
+ }
+ buf[hmuch] = 0;
+ if (pager_output(buf)) {
+ result = 1;
+ break;
+ }
+ }
+ close(fd);
+ return(result);
+}
diff --git a/usr/src/boot/lib/libstand/pkgfs.c b/usr/src/boot/lib/libstand/pkgfs.c
new file mode 100644
index 0000000000..fda7f60708
--- /dev/null
+++ b/usr/src/boot/lib/libstand/pkgfs.c
@@ -0,0 +1,791 @@
+/*-
+ * Copyright (c) 2007-2014, Juniper Networks, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+#include <sys/stat.h>
+#include <sys/stdint.h>
+#include <string.h>
+#include <zlib.h>
+
+#ifdef PKGFS_DEBUG
+#define DBG(x) printf x
+#else
+#define DBG(x)
+#endif
+
+static int pkg_open(const char *, struct open_file *);
+static int pkg_close(struct open_file *);
+static int pkg_read(struct open_file *, void *, size_t, size_t *);
+static off_t pkg_seek(struct open_file *, off_t, int);
+static int pkg_stat(struct open_file *, struct stat *);
+static int pkg_readdir(struct open_file *, struct dirent *);
+
+struct fs_ops pkgfs_fsops = {
+ "pkg",
+ pkg_open,
+ pkg_close,
+ pkg_read,
+ null_write,
+ pkg_seek,
+ pkg_stat,
+ pkg_readdir
+};
+
+#define PKG_BUFSIZE 512
+#define PKG_MAXCACHESZ 4096
+
+#define PKG_FILEEXT ".tgz"
+
+/*
+ * Layout of POSIX 'ustar' header.
+ */
+struct ustar_hdr {
+ char ut_name[100];
+ char ut_mode[8];
+ char ut_uid[8];
+ char ut_gid[8];
+ char ut_size[12];
+ char ut_mtime[12];
+ char ut_checksum[8];
+ char ut_typeflag[1];
+ char ut_linkname[100];
+ char ut_magic[6]; /* For POSIX: "ustar\0" */
+ char ut_version[2]; /* For POSIX: "00" */
+ char ut_uname[32];
+ char ut_gname[32];
+ char ut_rdevmajor[8];
+ char ut_rdevminor[8];
+ union {
+ struct {
+ char prefix[155];
+ } posix;
+ struct {
+ char atime[12];
+ char ctime[12];
+ char offset[12];
+ char longnames[4];
+ char unused[1];
+ struct gnu_sparse {
+ char offset[12];
+ char numbytes[12];
+ } sparse[4];
+ char isextended[1];
+ char realsize[12];
+ } gnu;
+ } u;
+ u_char __padding[12];
+};
+
+struct package;
+
+struct tarfile
+{
+ struct package *tf_pkg;
+ struct tarfile *tf_next;
+ struct ustar_hdr tf_hdr;
+ off_t tf_ofs;
+ off_t tf_size;
+ off_t tf_fp;
+ size_t tf_cachesz;
+ void *tf_cache;
+};
+
+struct package
+{
+ struct package *pkg_chain;
+ int pkg_fd;
+ off_t pkg_ofs;
+ z_stream pkg_zs;
+ struct tarfile *pkg_first;
+ struct tarfile *pkg_last;
+ u_char pkg_buf[PKG_BUFSIZE];
+};
+
+static struct package *package = NULL;
+
+static int new_package(int, struct package **);
+
+void
+pkgfs_cleanup(void)
+{
+ struct package *chain;
+ struct tarfile *tf, *tfn;
+
+ while (package != NULL) {
+ inflateEnd(&package->pkg_zs);
+ close(package->pkg_fd);
+
+ tf = package->pkg_first;
+ while (tf != NULL) {
+ tfn = tf->tf_next;
+ if (tf->tf_cachesz > 0)
+ free(tf->tf_cache);
+ free(tf);
+ tf = tfn;
+ }
+
+ chain = package->pkg_chain;
+ free(package);
+ package = chain;
+ }
+}
+
+int
+pkgfs_init(const char *pkgname, struct fs_ops *proto)
+{
+ struct package *pkg;
+ int error, fd;
+
+ if (proto != &pkgfs_fsops)
+ pkgfs_cleanup();
+
+ exclusive_file_system = proto;
+
+ fd = open(pkgname, O_RDONLY);
+
+ exclusive_file_system = NULL;
+
+ if (fd == -1)
+ return (errno);
+
+ error = new_package(fd, &pkg);
+ if (error) {
+ close(fd);
+ return (error);
+ }
+
+ if (pkg == NULL)
+ return (EDOOFUS);
+
+ pkg->pkg_chain = package;
+ package = pkg;
+ exclusive_file_system = &pkgfs_fsops;
+ return (0);
+}
+
+static int get_mode(struct tarfile *);
+static int get_zipped(struct package *, void *, size_t);
+static int new_package(int, struct package **);
+static struct tarfile *scan_tarfile(struct package *, struct tarfile *);
+
+static int
+pkg_open(const char *fn, struct open_file *f)
+{
+ struct tarfile *tf;
+
+ if (fn == NULL || f == NULL)
+ return (EINVAL);
+
+ if (package == NULL)
+ return (ENXIO);
+
+ /*
+ * We can only read from a package, so reject request to open
+ * for write-only or read-write.
+ */
+ if (f->f_flags != F_READ)
+ return (EPERM);
+
+ /*
+ * Scan the file headers for the named file. We stop scanning
+ * at the first filename that has the .pkg extension. This is
+ * a package within a package. We assume we have all the files
+ * we need up-front and without having to dig within nested
+ * packages.
+ *
+ * Note that we preserve streaming properties as much as possible.
+ */
+ while (*fn == '/')
+ fn++;
+
+ /*
+ * Allow opening of the root directory for use by readdir()
+ * to support listing files in the package.
+ */
+ if (*fn == '\0') {
+ f->f_fsdata = NULL;
+ return (0);
+ }
+
+ tf = scan_tarfile(package, NULL);
+ while (tf != NULL) {
+ if (strcmp(fn, tf->tf_hdr.ut_name) == 0) {
+ f->f_fsdata = tf;
+ tf->tf_fp = 0; /* Reset the file pointer. */
+ return (0);
+ }
+ tf = scan_tarfile(package, tf);
+ }
+ return (errno);
+}
+
+static int
+pkg_close(struct open_file *f)
+{
+ struct tarfile *tf;
+
+ tf = (struct tarfile *)f->f_fsdata;
+ if (tf == NULL)
+ return (0);
+
+ /*
+ * Free up the cache if we read all of the file.
+ */
+ if (tf->tf_fp == tf->tf_size && tf->tf_cachesz > 0) {
+ free(tf->tf_cache);
+ tf->tf_cachesz = 0;
+ }
+ return (0);
+}
+
+static int
+pkg_read(struct open_file *f, void *buf, size_t size, size_t *res)
+{
+ struct tarfile *tf;
+ char *p;
+ off_t fp;
+ size_t sz;
+
+ tf = (struct tarfile *)f->f_fsdata;
+ if (tf == NULL) {
+ if (res != NULL)
+ *res = size;
+ return (EBADF);
+ }
+
+ fp = tf->tf_fp;
+ p = buf;
+ sz = 0;
+ while (size > 0) {
+ sz = tf->tf_size - fp;
+ if (fp < tf->tf_cachesz && tf->tf_cachesz < tf->tf_size)
+ sz = tf->tf_cachesz - fp;
+ if (size < sz)
+ sz = size;
+ if (sz == 0)
+ break;
+
+ if (fp < tf->tf_cachesz) {
+ /* Satisfy the request from cache. */
+ memcpy(p, tf->tf_cache + fp, sz);
+ fp += sz;
+ p += sz;
+ size -= sz;
+ continue;
+ }
+
+ if (get_zipped(tf->tf_pkg, p, sz) == -1) {
+ sz = -1;
+ break;
+ }
+
+ fp += sz;
+ p += sz;
+ size -= sz;
+
+ if (tf->tf_cachesz != 0)
+ continue;
+
+ tf->tf_cachesz = (sz <= PKG_MAXCACHESZ) ? sz : PKG_MAXCACHESZ;
+ tf->tf_cache = malloc(tf->tf_cachesz);
+ if (tf->tf_cache != NULL)
+ memcpy(tf->tf_cache, buf, tf->tf_cachesz);
+ else
+ tf->tf_cachesz = 0;
+ }
+
+ tf->tf_fp = fp;
+ if (res != NULL)
+ *res = size;
+ return ((sz == -1) ? errno : 0);
+}
+
+static off_t
+pkg_seek(struct open_file *f, off_t ofs, int whence)
+{
+ char buf[512];
+ struct tarfile *tf;
+ off_t delta;
+ size_t sz, res;
+ int error;
+
+ tf = (struct tarfile *)f->f_fsdata;
+ if (tf == NULL) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ switch (whence) {
+ case SEEK_SET:
+ delta = ofs - tf->tf_fp;
+ break;
+ case SEEK_CUR:
+ delta = ofs;
+ break;
+ case SEEK_END:
+ delta = tf->tf_size - tf->tf_fp + ofs;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (delta < 0) {
+ DBG(("%s: negative file seek (%jd)\n", __func__,
+ (intmax_t)delta));
+ errno = ESPIPE;
+ return (-1);
+ }
+
+ while (delta > 0 && tf->tf_fp < tf->tf_size) {
+ sz = (delta > sizeof(buf)) ? sizeof(buf) : delta;
+ error = pkg_read(f, buf, sz, &res);
+ if (error != 0) {
+ errno = error;
+ return (-1);
+ }
+ delta -= sz - res;
+ }
+
+ return (tf->tf_fp);
+}
+
+static int
+pkg_stat(struct open_file *f, struct stat *sb)
+{
+ struct tarfile *tf;
+
+ tf = (struct tarfile *)f->f_fsdata;
+ if (tf == NULL)
+ return (EBADF);
+ memset(sb, 0, sizeof(*sb));
+ sb->st_mode = get_mode(tf);
+ sb->st_size = tf->tf_size;
+ sb->st_blocks = (tf->tf_size + 511) / 512;
+ return (0);
+}
+
+static int
+pkg_readdir(struct open_file *f, struct dirent *d)
+{
+ struct tarfile *tf;
+
+ tf = (struct tarfile *)f->f_fsdata;
+ if (tf != NULL)
+ return (EBADF);
+
+ tf = scan_tarfile(package, NULL);
+ if (tf == NULL)
+ return (ENOENT);
+
+ d->d_fileno = 0;
+ d->d_reclen = sizeof(*d);
+ d->d_type = DT_REG;
+ memcpy(d->d_name, tf->tf_hdr.ut_name, sizeof(d->d_name));
+ return (0);
+}
+
+/*
+ * Low-level support functions.
+ */
+
+static int
+get_byte(struct package *pkg, off_t *op)
+{
+ int c;
+
+ if (pkg->pkg_zs.avail_in == 0) {
+ c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE);
+ if (c <= 0)
+ return (-1);
+ pkg->pkg_zs.avail_in = c;
+ pkg->pkg_zs.next_in = pkg->pkg_buf;
+ }
+
+ c = *pkg->pkg_zs.next_in;
+ pkg->pkg_zs.next_in++;
+ pkg->pkg_zs.avail_in--;
+ (*op)++;
+ return (c);
+}
+
+static int
+get_zipped(struct package *pkg, void *buf, size_t bufsz)
+{
+ int c;
+
+ pkg->pkg_zs.next_out = buf;
+ pkg->pkg_zs.avail_out = bufsz;
+
+ while (pkg->pkg_zs.avail_out) {
+ if (pkg->pkg_zs.avail_in == 0) {
+ c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE);
+ if (c <= 0) {
+ errno = EIO;
+ return (-1);
+ }
+ pkg->pkg_zs.avail_in = c;
+ pkg->pkg_zs.next_in = pkg->pkg_buf;
+ }
+
+ c = inflate(&pkg->pkg_zs, Z_SYNC_FLUSH);
+ if (c != Z_OK && c != Z_STREAM_END) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ pkg->pkg_ofs += bufsz;
+ return (0);
+}
+
+static int
+cache_data(struct tarfile *tf)
+{
+ struct package *pkg;
+ size_t sz;
+
+ if (tf == NULL) {
+ DBG(("%s: no file to cache data for?\n", __func__));
+ errno = EINVAL;
+ return (-1);
+ }
+
+ pkg = tf->tf_pkg;
+ if (pkg == NULL) {
+ DBG(("%s: no package associated with file?\n", __func__));
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (tf->tf_ofs != pkg->pkg_ofs) {
+ DBG(("%s: caching after partial read of file %s?\n",
+ __func__, tf->tf_hdr.ut_name));
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* We don't cache everything... */
+ if (tf->tf_size > PKG_MAXCACHESZ) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ /* All files are padded to a multiple of 512 bytes. */
+ sz = (tf->tf_size + 0x1ff) & ~0x1ff;
+
+ tf->tf_cache = malloc(sz);
+ if (tf->tf_cache == NULL) {
+ DBG(("%s: could not allocate %d bytes\n", __func__, (int)sz));
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ tf->tf_cachesz = sz;
+ return (get_zipped(pkg, tf->tf_cache, sz));
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static off_t
+pkg_atol8(const char *p, unsigned char_cnt)
+{
+ int64_t l, limit, last_digit_limit;
+ int digit, sign, base;
+
+ base = 8;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '-') {
+ sign = -1;
+ p++;
+ } else
+ sign = 1;
+
+ l = 0;
+ digit = *p - '0';
+ while (digit >= 0 && digit < base && char_cnt-- > 0) {
+ if (l>limit || (l == limit && digit > last_digit_limit)) {
+ l = UINT64_MAX; /* Truncate on overflow. */
+ break;
+ }
+ l = (l * base) + digit;
+ digit = *++p - '0';
+ }
+ return (sign < 0) ? -l : l;
+}
+
+/*
+ * Parse a base-256 integer. This is just a straight signed binary
+ * value in big-endian order, except that the high-order bit is
+ * ignored. Remember that "int64_t" may or may not be exactly 64
+ * bits; the implementation here tries to avoid making any assumptions
+ * about the actual size of an int64_t. It does assume we're using
+ * twos-complement arithmetic, though.
+ */
+static int64_t
+pkg_atol256(const char *_p, unsigned char_cnt)
+{
+ int64_t l, upper_limit, lower_limit;
+ const unsigned char *p = (const unsigned char *)_p;
+
+ upper_limit = INT64_MAX / 256;
+ lower_limit = INT64_MIN / 256;
+
+ /* Pad with 1 or 0 bits, depending on sign. */
+ if ((0x40 & *p) == 0x40)
+ l = (int64_t)-1;
+ else
+ l = 0;
+ l = (l << 6) | (0x3f & *p++);
+ while (--char_cnt > 0) {
+ if (l > upper_limit) {
+ l = INT64_MAX; /* Truncate on overflow */
+ break;
+ } else if (l < lower_limit) {
+ l = INT64_MIN;
+ break;
+ }
+ l = (l << 8) | (0xff & (int64_t)*p++);
+ }
+ return (l);
+}
+
+static off_t
+pkg_atol(const char *p, unsigned char_cnt)
+{
+ /*
+ * Technically, GNU pkg considers a field to be in base-256
+ * only if the first byte is 0xff or 0x80.
+ */
+ if (*p & 0x80)
+ return (pkg_atol256(p, char_cnt));
+ return (pkg_atol8(p, char_cnt));
+}
+
+static int
+get_mode(struct tarfile *tf)
+{
+ return (pkg_atol(tf->tf_hdr.ut_mode, sizeof(tf->tf_hdr.ut_mode)));
+}
+
+/* GZip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int
+new_package(int fd, struct package **pp)
+{
+ struct package *pkg;
+ off_t ofs;
+ int flags, i, error;
+
+ pkg = malloc(sizeof(*pkg));
+ if (pkg == NULL)
+ return (ENOMEM);
+
+ bzero(pkg, sizeof(*pkg));
+ pkg->pkg_fd = fd;
+
+ /*
+ * Parse the header.
+ */
+ error = EFTYPE;
+ ofs = 0;
+
+ /* Check megic. */
+ if (get_byte(pkg, &ofs) != 0x1f || get_byte(pkg, &ofs) != 0x8b)
+ goto fail;
+ /* Check method. */
+ if (get_byte(pkg, &ofs) != Z_DEFLATED)
+ goto fail;
+ /* Check flags. */
+ flags = get_byte(pkg, &ofs);
+ if (flags & RESERVED)
+ goto fail;
+
+ /* Skip time, xflags and OS code. */
+ for (i = 0; i < 6; i++) {
+ if (get_byte(pkg, &ofs) == -1)
+ goto fail;
+ }
+
+ /* Skip extra field. */
+ if (flags & EXTRA_FIELD) {
+ i = (get_byte(pkg, &ofs) & 0xff) |
+ ((get_byte(pkg, &ofs) << 8) & 0xff);
+ while (i-- > 0) {
+ if (get_byte(pkg, &ofs) == -1)
+ goto fail;
+ }
+ }
+
+ /* Skip original file name. */
+ if (flags & ORIG_NAME) {
+ do {
+ i = get_byte(pkg, &ofs);
+ } while (i != 0 && i != -1);
+ if (i == -1)
+ goto fail;
+ }
+
+ /* Print the comment if it's there. */
+ if (flags & COMMENT) {
+ while (1) {
+ i = get_byte(pkg, &ofs);
+ if (i == -1)
+ goto fail;
+ if (i == 0)
+ break;
+ putchar(i);
+ }
+ }
+
+ /* Skip the CRC. */
+ if (flags & HEAD_CRC) {
+ if (get_byte(pkg, &ofs) == -1)
+ goto fail;
+ if (get_byte(pkg, &ofs) == -1)
+ goto fail;
+ }
+
+ /*
+ * Done parsing the ZIP header. Spkgt the inflation engine.
+ */
+ error = inflateInit2(&pkg->pkg_zs, -15);
+ if (error != Z_OK)
+ goto fail;
+
+ *pp = pkg;
+ return (0);
+
+ fail:
+ free(pkg);
+ return (error);
+}
+
+static struct tarfile *
+scan_tarfile(struct package *pkg, struct tarfile *last)
+{
+ char buf[512];
+ struct tarfile *cur;
+ off_t ofs;
+ size_t sz;
+
+ cur = (last != NULL) ? last->tf_next : pkg->pkg_first;
+ if (cur == NULL) {
+ ofs = (last != NULL) ? last->tf_ofs + last->tf_size :
+ pkg->pkg_ofs;
+ ofs = (ofs + 0x1ff) & ~0x1ff;
+
+ /* Check if we've reached EOF. */
+ if (ofs < pkg->pkg_ofs) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+
+ if (ofs != pkg->pkg_ofs) {
+ if (last != NULL && pkg->pkg_ofs == last->tf_ofs) {
+ if (cache_data(last) == -1)
+ return (NULL);
+ } else {
+ sz = ofs - pkg->pkg_ofs;
+ while (sz != 0) {
+ if (sz > sizeof(buf))
+ sz = sizeof(buf);
+ if (get_zipped(pkg, buf, sz) == -1)
+ return (NULL);
+ sz = ofs - pkg->pkg_ofs;
+ }
+ }
+ }
+
+ cur = malloc(sizeof(*cur));
+ if (cur == NULL)
+ return (NULL);
+ memset(cur, 0, sizeof(*cur));
+ cur->tf_pkg = pkg;
+
+ while (1) {
+ if (get_zipped(pkg, &cur->tf_hdr,
+ sizeof(cur->tf_hdr)) == -1) {
+ free(cur);
+ return (NULL);
+ }
+
+ /*
+ * There are always 2 empty blocks appended to
+ * a PKG. It marks the end of the archive.
+ */
+ if (strncmp(cur->tf_hdr.ut_magic, "ustar", 5) != 0) {
+ free(cur);
+ errno = ENOSPC;
+ return (NULL);
+ }
+
+ cur->tf_ofs = pkg->pkg_ofs;
+ cur->tf_size = pkg_atol(cur->tf_hdr.ut_size,
+ sizeof(cur->tf_hdr.ut_size));
+
+ if (cur->tf_hdr.ut_name[0] != '+')
+ break;
+
+ /*
+ * Skip package meta-files.
+ */
+ ofs = cur->tf_ofs + cur->tf_size;
+ ofs = (ofs + 0x1ff) & ~0x1ff;
+ while (pkg->pkg_ofs < ofs) {
+ if (get_zipped(pkg, buf, sizeof(buf)) == -1) {
+ free(cur);
+ return (NULL);
+ }
+ }
+ }
+
+ if (last != NULL)
+ last->tf_next = cur;
+ else
+ pkg->pkg_first = cur;
+ pkg->pkg_last = cur;
+ }
+
+ return (cur);
+}
diff --git a/usr/src/boot/lib/libstand/powerpc/_setjmp.S b/usr/src/boot/lib/libstand/powerpc/_setjmp.S
new file mode 100644
index 0000000000..7c7c24b123
--- /dev/null
+++ b/usr/src/boot/lib/libstand/powerpc/_setjmp.S
@@ -0,0 +1,115 @@
+/* $FreeBSD$ */
+/* from: NetBSD: setjmp.S,v 1.1 1998/01/27 15:13:12 sakamoto Exp $ */
+/* from: OpenBSD: setjmp.S,v 1.2 1996/12/28 06:22:18 rahnds Exp */
+/* kernel version of this file, does not have signal goop */
+/* int setjmp(jmp_buf env) */
+
+#include <machine/asm.h>
+
+#ifdef __powerpc64__
+#define LD_REG ld
+#define ST_REG std
+#define REGWIDTH 8
+#else
+#define LD_REG lwz
+#define ST_REG stw
+#define REGWIDTH 4
+#endif
+
+#define JMP_r1 1*REGWIDTH
+#define JMP_r2 2*REGWIDTH
+#define JMP_r14 3*REGWIDTH
+#define JMP_r15 4*REGWIDTH
+#define JMP_r16 5*REGWIDTH
+#define JMP_r17 6*REGWIDTH
+#define JMP_r18 7*REGWIDTH
+#define JMP_r19 8*REGWIDTH
+#define JMP_r20 9*REGWIDTH
+#define JMP_r21 10*REGWIDTH
+#define JMP_r22 11*REGWIDTH
+#define JMP_r23 12*REGWIDTH
+#define JMP_r24 13*REGWIDTH
+#define JMP_r25 14*REGWIDTH
+#define JMP_r26 15*REGWIDTH
+#define JMP_r27 16*REGWIDTH
+#define JMP_r28 17*REGWIDTH
+#define JMP_r29 18*REGWIDTH
+#define JMP_r30 19*REGWIDTH
+#define JMP_r31 20*REGWIDTH
+#define JMP_lr 21*REGWIDTH
+#define JMP_cr 22*REGWIDTH
+#define JMP_ctr 23*REGWIDTH
+#define JMP_xer 24*REGWIDTH
+#define JMP_sig 25*REGWIDTH
+
+ASENTRY_NOPROF(_setjmp)
+ ST_REG 31, JMP_r31(3)
+ /* r1, r2, r14-r30 */
+ ST_REG 1, JMP_r1 (3)
+ ST_REG 2, JMP_r2 (3)
+ ST_REG 14, JMP_r14(3)
+ ST_REG 15, JMP_r15(3)
+ ST_REG 16, JMP_r16(3)
+ ST_REG 17, JMP_r17(3)
+ ST_REG 18, JMP_r18(3)
+ ST_REG 19, JMP_r19(3)
+ ST_REG 20, JMP_r20(3)
+ ST_REG 21, JMP_r21(3)
+ ST_REG 22, JMP_r22(3)
+ ST_REG 23, JMP_r23(3)
+ ST_REG 24, JMP_r24(3)
+ ST_REG 25, JMP_r25(3)
+ ST_REG 26, JMP_r26(3)
+ ST_REG 27, JMP_r27(3)
+ ST_REG 28, JMP_r28(3)
+ ST_REG 29, JMP_r29(3)
+ ST_REG 30, JMP_r30(3)
+ /* cr, lr, ctr, xer */
+ mfcr 0
+ ST_REG 0, JMP_cr(3)
+ mflr 0
+ ST_REG 0, JMP_lr(3)
+ mfctr 0
+ ST_REG 0, JMP_ctr(3)
+ mfxer 0
+ ST_REG 0, JMP_xer(3)
+ /* f14-f31, fpscr */
+ li 3, 0
+ blr
+
+
+.extern sigsetmask
+ASENTRY_NOPROF(_longjmp)
+ LD_REG 31, JMP_r31(3)
+ /* r1, r2, r14-r30 */
+ LD_REG 1, JMP_r1 (3)
+ LD_REG 2, JMP_r2 (3)
+ LD_REG 14, JMP_r14(3)
+ LD_REG 15, JMP_r15(3)
+ LD_REG 16, JMP_r16(3)
+ LD_REG 17, JMP_r17(3)
+ LD_REG 18, JMP_r18(3)
+ LD_REG 19, JMP_r19(3)
+ LD_REG 20, JMP_r20(3)
+ LD_REG 21, JMP_r21(3)
+ LD_REG 22, JMP_r22(3)
+ LD_REG 23, JMP_r23(3)
+ LD_REG 24, JMP_r24(3)
+ LD_REG 25, JMP_r25(3)
+ LD_REG 26, JMP_r26(3)
+ LD_REG 27, JMP_r27(3)
+ LD_REG 28, JMP_r28(3)
+ LD_REG 29, JMP_r29(3)
+ LD_REG 30, JMP_r30(3)
+ /* cr, lr, ctr, xer */
+ LD_REG 0, JMP_cr(3)
+ mtcr 0
+ LD_REG 0, JMP_lr(3)
+ mtlr 0
+ LD_REG 0, JMP_ctr(3)
+ mtctr 0
+ LD_REG 0, JMP_xer(3)
+ mtxer 0
+ /* f14-f31, fpscr */
+ mr 3, 4
+ blr
diff --git a/usr/src/boot/lib/libstand/powerpc/syncicache.c b/usr/src/boot/lib/libstand/powerpc/syncicache.c
new file mode 100644
index 0000000000..434dcec634
--- /dev/null
+++ b/usr/src/boot/lib/libstand/powerpc/syncicache.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank.
+ * Copyright (C) 1995-1997, 1999 TooLs GmbH.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ *
+ * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#if defined(_KERNEL) || defined(_STANDALONE)
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <vm/vm.h>
+#endif
+#include <sys/sysctl.h>
+
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+
+#ifdef _STANDALONE
+int cacheline_size = 32;
+#endif
+
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+#include <stdlib.h>
+
+int cacheline_size = 0;
+
+static void getcachelinesize(void);
+
+static void
+getcachelinesize()
+{
+ static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
+ int clen;
+
+ clen = sizeof(cacheline_size);
+
+ if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
+ &cacheline_size, &clen, NULL, 0) < 0 || !cacheline_size) {
+ abort();
+ }
+}
+#endif
+
+void
+__syncicache(void *from, int len)
+{
+ int l, off;
+ char *p;
+
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+ if (!cacheline_size)
+ getcachelinesize();
+#endif
+
+ off = (u_int)from & (cacheline_size - 1);
+ l = len += off;
+ p = (char *)from - off;
+
+ do {
+ __asm __volatile ("dcbst 0,%0" :: "r"(p));
+ p += cacheline_size;
+ } while ((l -= cacheline_size) > 0);
+ __asm __volatile ("sync");
+ p = (char *)from - off;
+ do {
+ __asm __volatile ("icbi 0,%0" :: "r"(p));
+ p += cacheline_size;
+ } while ((len -= cacheline_size) > 0);
+ __asm __volatile ("sync; isync");
+}
+
diff --git a/usr/src/boot/lib/libstand/printf.c b/usr/src/boot/lib/libstand/printf.c
new file mode 100644
index 0000000000..d91f705d75
--- /dev/null
+++ b/usr/src/boot/lib/libstand/printf.c
@@ -0,0 +1,526 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Standaloneified version of the FreeBSD kernel printf family.
+ */
+
+#include <sys/types.h>
+#include <sys/stddef.h>
+#include <sys/stdint.h>
+#include <limits.h>
+#include <string.h>
+#include "stand.h"
+
+/*
+ * Note that stdarg.h and the ANSI style va_start macro is used for both
+ * ANSI and traditional C compilers.
+ */
+#include <machine/stdarg.h>
+
+#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
+
+typedef void (kvprintf_fn_t)(int, void *);
+
+static char *ksprintn (char *buf, uintmax_t num, int base, int *len, int upper);
+static int kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap);
+
+static void
+putchar_wrapper(int cc, void *arg)
+{
+
+ putchar(cc);
+}
+
+int
+printf(const char *fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ va_start(ap, fmt);
+ retval = kvprintf(fmt, putchar_wrapper, NULL, 10, ap);
+ va_end(ap);
+ return retval;
+}
+
+void
+vprintf(const char *fmt, va_list ap)
+{
+
+ kvprintf(fmt, putchar_wrapper, NULL, 10, ap);
+}
+
+int
+sprintf(char *buf, const char *cfmt, ...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, cfmt);
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+ va_end(ap);
+ return retval;
+}
+
+struct print_buf {
+ char *buf;
+ size_t size;
+};
+
+static void
+snprint_func(int ch, void *arg)
+{
+ struct print_buf *pbuf = arg;
+
+ if (pbuf->size < 2) {
+ /*
+ * Reserve last buffer position for the terminating
+ * character:
+ */
+ return;
+ }
+ *(pbuf->buf)++ = ch;
+ pbuf->size--;
+}
+
+int
+snprintf(char *buf, size_t size, const char *cfmt, ...)
+{
+ int retval;
+ va_list ap;
+ struct print_buf arg;
+
+ arg.buf = buf;
+ arg.size = size;
+
+ va_start(ap, cfmt);
+ retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap);
+ va_end(ap);
+
+ if (arg.size >= 1)
+ *(arg.buf)++ = 0;
+ return retval;
+}
+
+void
+vsprintf(char *buf, const char *cfmt, va_list ap)
+{
+ int retval;
+
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+}
+
+void
+vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap)
+{
+ int retval;
+ struct print_buf arg;
+
+ arg.buf = buf;
+ arg.size = size;
+
+ retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap);
+ buf[retval] = '\0';
+}
+
+/*
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
+ */
+static char *
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
+{
+ char *p, c;
+
+ p = nbuf;
+ *p = '\0';
+ do {
+ c = hex2ascii(num % base);
+ *++p = upper ? toupper(c) : c;
+ } while (num /= base);
+ if (lenp)
+ *lenp = p - nbuf;
+ return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ *
+ * XXX: %D -- Hexdump, takes pointer and separator string:
+ * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
+ * ("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+static int
+kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc, arg); else *d++ = cc; retval++; }
+ char nbuf[MAXNBUF];
+ char *d;
+ const char *p, *percent, *q;
+ u_char *up;
+ int ch, n;
+ uintmax_t num;
+ int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int cflag, hflag, jflag, tflag, zflag;
+ int dwidth, upper;
+ char padc;
+ int stop = 0, retval = 0;
+
+ num = 0;
+ if (!func)
+ d = (char *) arg;
+ else
+ d = NULL;
+
+ if (fmt == NULL)
+ fmt = "(fmt null)\n";
+
+ if (radix < 2 || radix > 36)
+ radix = 10;
+
+ for (;;) {
+ padc = ' ';
+ width = 0;
+ while ((ch = (u_char)*fmt++) != '%' || stop) {
+ if (ch == '\0')
+ return (retval);
+ PCHAR(ch);
+ }
+ percent = fmt - 1;
+ qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ sign = 0; dot = 0; dwidth = 0; upper = 0;
+ cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
+reswitch: switch (ch = (u_char)*fmt++) {
+ case '.':
+ dot = 1;
+ goto reswitch;
+ case '#':
+ sharpflag = 1;
+ goto reswitch;
+ case '+':
+ sign = 1;
+ goto reswitch;
+ case '-':
+ ladjust = 1;
+ goto reswitch;
+ case '%':
+ PCHAR(ch);
+ break;
+ case '*':
+ if (!dot) {
+ width = va_arg(ap, int);
+ if (width < 0) {
+ ladjust = !ladjust;
+ width = -width;
+ }
+ } else {
+ dwidth = va_arg(ap, int);
+ }
+ goto reswitch;
+ case '0':
+ if (!dot) {
+ padc = '0';
+ goto reswitch;
+ }
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ for (n = 0;; ++fmt) {
+ n = n * 10 + ch - '0';
+ ch = *fmt;
+ if (ch < '0' || ch > '9')
+ break;
+ }
+ if (dot)
+ dwidth = n;
+ else
+ width = n;
+ goto reswitch;
+ case 'b':
+ num = (u_int)va_arg(ap, int);
+ p = va_arg(ap, char *);
+ for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
+ PCHAR(*q--);
+
+ if (num == 0)
+ break;
+
+ for (tmp = 0; *p;) {
+ n = *p++;
+ if (num & (1 << (n - 1))) {
+ PCHAR(tmp ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ PCHAR(n);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ PCHAR('>');
+ break;
+ case 'c':
+ PCHAR(va_arg(ap, int));
+ break;
+ case 'D':
+ up = va_arg(ap, u_char *);
+ p = va_arg(ap, char *);
+ if (!width)
+ width = 16;
+ while(width--) {
+ PCHAR(hex2ascii(*up >> 4));
+ PCHAR(hex2ascii(*up & 0x0f));
+ up++;
+ if (width)
+ for (q=p;*q;q++)
+ PCHAR(*q);
+ }
+ break;
+ case 'd':
+ case 'i':
+ base = 10;
+ sign = 1;
+ goto handle_sign;
+ case 'h':
+ if (hflag) {
+ hflag = 0;
+ cflag = 1;
+ } else
+ hflag = 1;
+ goto reswitch;
+ case 'j':
+ jflag = 1;
+ goto reswitch;
+ case 'l':
+ if (lflag) {
+ lflag = 0;
+ qflag = 1;
+ } else
+ lflag = 1;
+ goto reswitch;
+ case 'n':
+ if (jflag)
+ *(va_arg(ap, intmax_t *)) = retval;
+ else if (qflag)
+ *(va_arg(ap, quad_t *)) = retval;
+ else if (lflag)
+ *(va_arg(ap, long *)) = retval;
+ else if (zflag)
+ *(va_arg(ap, size_t *)) = retval;
+ else if (hflag)
+ *(va_arg(ap, short *)) = retval;
+ else if (cflag)
+ *(va_arg(ap, char *)) = retval;
+ else
+ *(va_arg(ap, int *)) = retval;
+ break;
+ case 'o':
+ base = 8;
+ goto handle_nosign;
+ case 'p':
+ base = 16;
+ sharpflag = (width == 0);
+ sign = 0;
+ num = (uintptr_t)va_arg(ap, void *);
+ goto number;
+ case 'q':
+ qflag = 1;
+ goto reswitch;
+ case 'r':
+ base = radix;
+ if (sign)
+ goto handle_sign;
+ goto handle_nosign;
+ case 's':
+ p = va_arg(ap, char *);
+ if (p == NULL)
+ p = "(null)";
+ if (!dot)
+ n = strlen (p);
+ else
+ for (n = 0; n < dwidth && p[n]; n++)
+ continue;
+
+ width -= n;
+
+ if (!ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ while (n--)
+ PCHAR(*p++);
+ if (ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ break;
+ case 't':
+ tflag = 1;
+ goto reswitch;
+ case 'u':
+ base = 10;
+ goto handle_nosign;
+ case 'X':
+ upper = 1;
+ case 'x':
+ base = 16;
+ goto handle_nosign;
+ case 'y':
+ base = 16;
+ sign = 1;
+ goto handle_sign;
+ case 'z':
+ zflag = 1;
+ goto reswitch;
+handle_nosign:
+ sign = 0;
+ if (jflag)
+ num = va_arg(ap, uintmax_t);
+ else if (qflag)
+ num = va_arg(ap, u_quad_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, u_long);
+ else if (zflag)
+ num = va_arg(ap, size_t);
+ else if (hflag)
+ num = (u_short)va_arg(ap, int);
+ else if (cflag)
+ num = (u_char)va_arg(ap, int);
+ else
+ num = va_arg(ap, u_int);
+ goto number;
+handle_sign:
+ if (jflag)
+ num = va_arg(ap, intmax_t);
+ else if (qflag)
+ num = va_arg(ap, quad_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, long);
+ else if (zflag)
+ num = va_arg(ap, ssize_t);
+ else if (hflag)
+ num = (short)va_arg(ap, int);
+ else if (cflag)
+ num = (char)va_arg(ap, int);
+ else
+ num = va_arg(ap, int);
+number:
+ if (sign && (intmax_t)num < 0) {
+ neg = 1;
+ num = -(intmax_t)num;
+ }
+ p = ksprintn(nbuf, num, base, &n, upper);
+ tmp = 0;
+ if (sharpflag && num != 0) {
+ if (base == 8)
+ tmp++;
+ else if (base == 16)
+ tmp += 2;
+ }
+ if (neg)
+ tmp++;
+
+ if (!ladjust && padc == '0')
+ dwidth = width - tmp;
+ width -= tmp + imax(dwidth, n);
+ dwidth -= n;
+ if (!ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+ if (neg)
+ PCHAR('-');
+ if (sharpflag && num != 0) {
+ if (base == 8) {
+ PCHAR('0');
+ } else if (base == 16) {
+ PCHAR('0');
+ PCHAR('x');
+ }
+ }
+ while (dwidth-- > 0)
+ PCHAR('0');
+
+ while (*p)
+ PCHAR(*p--);
+
+ if (ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+
+ break;
+ default:
+ while (percent < fmt)
+ PCHAR(*percent++);
+ /*
+ * Since we ignore a formatting argument it is no
+ * longer safe to obey the remaining formatting
+ * arguments as the arguments will no longer match
+ * the format specs.
+ */
+ stop = 1;
+ break;
+ }
+ }
+#undef PCHAR
+}
diff --git a/usr/src/boot/lib/libstand/qdivrem.c b/usr/src/boot/lib/libstand/qdivrem.c
new file mode 100644
index 0000000000..bde3b0d56e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/qdivrem.c
@@ -0,0 +1,348 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * From: Id: qdivrem.c,v 1.7 1997/11/07 09:20:40 phk Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
+ * section 4.3.1, pp. 257--259.
+ */
+
+#include "quad.h"
+
+#define B (1 << HALF_BITS) /* digit base */
+
+/* Combine two `digits' to make a single two-digit number. */
+#define COMBINE(a, b) (((u_int)(a) << HALF_BITS) | (b))
+
+_Static_assert(sizeof(int) / 2 == sizeof(short),
+ "Bitwise functions in libstand are broken on this architecture\n");
+
+/* select a type for digits in base B: use unsigned short if they fit */
+typedef unsigned short digit;
+
+/*
+ * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
+ * `fall out' the left (there never will be any such anyway).
+ * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
+ */
+static void
+shl(digit *p, int len, int sh)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
+ p[i] = LHALF(p[i] << sh);
+}
+
+/*
+ * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
+ *
+ * We do this in base 2-sup-HALF_BITS, so that all intermediate products
+ * fit within u_int. As a consequence, the maximum length dividend and
+ * divisor are 4 `digits' in this base (they are shorter if they have
+ * leading zeros).
+ */
+u_quad_t
+__qdivrem(uq, vq, arq)
+ u_quad_t uq, vq, *arq;
+{
+ union uu tmp;
+ digit *u, *v, *q;
+ digit v1, v2;
+ u_int qhat, rhat, t;
+ int m, n, d, j, i;
+ digit uspace[5], vspace[5], qspace[5];
+
+ /*
+ * Take care of special cases: divide by zero, and u < v.
+ */
+ if (vq == 0) {
+ /* divide by zero. */
+ static volatile const unsigned int zero = 0;
+
+ tmp.ul[H] = tmp.ul[L] = 1 / zero;
+ if (arq)
+ *arq = uq;
+ return (tmp.q);
+ }
+ if (uq < vq) {
+ if (arq)
+ *arq = uq;
+ return (0);
+ }
+ u = &uspace[0];
+ v = &vspace[0];
+ q = &qspace[0];
+
+ /*
+ * Break dividend and divisor into digits in base B, then
+ * count leading zeros to determine m and n. When done, we
+ * will have:
+ * u = (u[1]u[2]...u[m+n]) sub B
+ * v = (v[1]v[2]...v[n]) sub B
+ * v[1] != 0
+ * 1 < n <= 4 (if n = 1, we use a different division algorithm)
+ * m >= 0 (otherwise u < v, which we already checked)
+ * m + n = 4
+ * and thus
+ * m = 4 - n <= 2
+ */
+ tmp.uq = uq;
+ u[0] = 0;
+ u[1] = HHALF(tmp.ul[H]);
+ u[2] = LHALF(tmp.ul[H]);
+ u[3] = HHALF(tmp.ul[L]);
+ u[4] = LHALF(tmp.ul[L]);
+ tmp.uq = vq;
+ v[1] = HHALF(tmp.ul[H]);
+ v[2] = LHALF(tmp.ul[H]);
+ v[3] = HHALF(tmp.ul[L]);
+ v[4] = LHALF(tmp.ul[L]);
+ for (n = 4; v[1] == 0; v++) {
+ if (--n == 1) {
+ u_int rbj; /* r*B+u[j] (not root boy jim) */
+ digit q1, q2, q3, q4;
+
+ /*
+ * Change of plan, per exercise 16.
+ * r = 0;
+ * for j = 1..4:
+ * q[j] = floor((r*B + u[j]) / v),
+ * r = (r*B + u[j]) % v;
+ * We unroll this completely here.
+ */
+ t = v[2]; /* nonzero, by definition */
+ q1 = u[1] / t;
+ rbj = COMBINE(u[1] % t, u[2]);
+ q2 = rbj / t;
+ rbj = COMBINE(rbj % t, u[3]);
+ q3 = rbj / t;
+ rbj = COMBINE(rbj % t, u[4]);
+ q4 = rbj / t;
+ if (arq)
+ *arq = rbj % t;
+ tmp.ul[H] = COMBINE(q1, q2);
+ tmp.ul[L] = COMBINE(q3, q4);
+ return (tmp.q);
+ }
+ }
+
+ /*
+ * By adjusting q once we determine m, we can guarantee that
+ * there is a complete four-digit quotient at &qspace[1] when
+ * we finally stop.
+ */
+ for (m = 4 - n; u[1] == 0; u++)
+ m--;
+ for (i = 4 - m; --i >= 0;)
+ q[i] = 0;
+ q += 4 - m;
+
+ /*
+ * Here we run Program D, translated from MIX to C and acquiring
+ * a few minor changes.
+ *
+ * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
+ */
+ d = 0;
+ for (t = v[1]; t < B / 2; t <<= 1)
+ d++;
+ if (d > 0) {
+ shl(&u[0], m + n, d); /* u <<= d */
+ shl(&v[1], n - 1, d); /* v <<= d */
+ }
+ /*
+ * D2: j = 0.
+ */
+ j = 0;
+ v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
+ v2 = v[2]; /* for D3 */
+ do {
+ digit uj0, uj1, uj2;
+
+ /*
+ * D3: Calculate qhat (\^q, in TeX notation).
+ * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
+ * let rhat = (u[j]*B + u[j+1]) mod v[1].
+ * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
+ * decrement qhat and increase rhat correspondingly.
+ * Note that if rhat >= B, v[2]*qhat < rhat*B.
+ */
+ uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
+ uj1 = u[j + 1]; /* for D3 only */
+ uj2 = u[j + 2]; /* for D3 only */
+ if (uj0 == v1) {
+ qhat = B;
+ rhat = uj1;
+ goto qhat_too_big;
+ } else {
+ u_int nn = COMBINE(uj0, uj1);
+ qhat = nn / v1;
+ rhat = nn % v1;
+ }
+ while (v2 * qhat > COMBINE(rhat, uj2)) {
+ qhat_too_big:
+ qhat--;
+ if ((rhat += v1) >= B)
+ break;
+ }
+ /*
+ * D4: Multiply and subtract.
+ * The variable `t' holds any borrows across the loop.
+ * We split this up so that we do not require v[0] = 0,
+ * and to eliminate a final special case.
+ */
+ for (t = 0, i = n; i > 0; i--) {
+ t = u[i + j] - v[i] * qhat - t;
+ u[i + j] = LHALF(t);
+ t = (B - HHALF(t)) & (B - 1);
+ }
+ t = u[j] - t;
+ u[j] = LHALF(t);
+ /*
+ * D5: test remainder.
+ * There is a borrow if and only if HHALF(t) is nonzero;
+ * in that (rare) case, qhat was too large (by exactly 1).
+ * Fix it by adding v[1..n] to u[j..j+n].
+ */
+ if (HHALF(t)) {
+ qhat--;
+ for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
+ t += u[i + j] + v[i];
+ u[i + j] = LHALF(t);
+ t = HHALF(t);
+ }
+ u[j] = LHALF(u[j] + t);
+ }
+ q[j] = qhat;
+ } while (++j <= m); /* D7: loop on j. */
+
+ /*
+ * If caller wants the remainder, we have to calculate it as
+ * u[m..m+n] >> d (this is at most n digits and thus fits in
+ * u[m+1..m+n], but we may need more source digits).
+ */
+ if (arq) {
+ if (d) {
+ for (i = m + n; i > m; --i)
+ u[i] = (u[i] >> d) |
+ LHALF(u[i - 1] << (HALF_BITS - d));
+ u[i] = 0;
+ }
+ tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
+ tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
+ *arq = tmp.q;
+ }
+
+ tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
+ tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
+ return (tmp.q);
+}
+
+/*
+ * Divide two unsigned quads.
+ */
+
+u_quad_t
+__udivdi3(a, b)
+ u_quad_t a, b;
+{
+
+ return (__qdivrem(a, b, (u_quad_t *)0));
+}
+
+/*
+ * Return remainder after dividing two unsigned quads.
+ */
+u_quad_t
+__umoddi3(a, b)
+ u_quad_t a, b;
+{
+ u_quad_t r;
+
+ (void)__qdivrem(a, b, &r);
+ return (r);
+}
+
+/*
+ * Divide two signed quads.
+ * ??? if -1/2 should produce -1 on this machine, this code is wrong
+ */
+quad_t
+__divdi3(a, b)
+ quad_t a, b;
+{
+ u_quad_t ua, ub, uq;
+ int neg;
+
+ if (a < 0)
+ ua = -(u_quad_t)a, neg = 1;
+ else
+ ua = a, neg = 0;
+ if (b < 0)
+ ub = -(u_quad_t)b, neg ^= 1;
+ else
+ ub = b;
+ uq = __qdivrem(ua, ub, (u_quad_t *)0);
+ return (neg ? -uq : uq);
+}
+
+/*
+ * Return remainder after dividing two signed quads.
+ *
+ * XXX
+ * If -1/2 should produce -1 on this machine, this code is wrong.
+ */
+quad_t
+__moddi3(a, b)
+ quad_t a, b;
+{
+ u_quad_t ua, ub, ur;
+ int neg;
+
+ if (a < 0)
+ ua = -(u_quad_t)a, neg = 1;
+ else
+ ua = a, neg = 0;
+ if (b < 0)
+ ub = -(u_quad_t)b;
+ else
+ ub = b;
+ (void)__qdivrem(ua, ub, &ur);
+ return (neg ? -ur : ur);
+}
diff --git a/usr/src/boot/lib/libstand/quad.h b/usr/src/boot/lib/libstand/quad.h
new file mode 100644
index 0000000000..349540a1e9
--- /dev/null
+++ b/usr/src/boot/lib/libstand/quad.h
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)quad.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
+ */
+
+/*
+ * Quad arithmetic.
+ *
+ * This library makes the following assumptions:
+ *
+ * - The type long long (aka quad_t) exists.
+ *
+ * - A quad variable is exactly twice as long as `long'.
+ *
+ * - The machine's arithmetic is two's complement.
+ *
+ * This library can provide 128-bit arithmetic on a machine with 128-bit
+ * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines
+ * with 48-bit longs.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <limits.h>
+
+_Static_assert(sizeof(quad_t) == sizeof(int) * 2,
+ "Bitwise function in libstand are broken on this architecture\n");
+
+/*
+ * Depending on the desired operation, we view a `long long' (aka quad_t) in
+ * one or more of the following formats.
+ */
+union uu {
+ quad_t q; /* as a (signed) quad */
+ quad_t uq; /* as an unsigned quad */
+ int sl[2]; /* as two signed ints */
+ u_int ul[2]; /* as two unsigned ints */
+};
+
+/*
+ * Define high and low longwords.
+ */
+#define H _QUAD_HIGHWORD
+#define L _QUAD_LOWWORD
+
+/*
+ * Total number of bits in a quad_t and in the pieces that make it up.
+ * These are used for shifting, and also below for halfword extraction
+ * and assembly.
+ */
+#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT)
+#define HALF_BITS (sizeof(int) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from longword, and move low shortword of
+ * longword to upper half of long, i.e., produce the upper longword of
+ * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.)
+ *
+ * These are used in the multiply code, to split a longword into upper
+ * and lower halves, and to reassemble a product as a quad_t, shifted left
+ * (sizeof(long)*CHAR_BIT/2).
+ */
+#define HHALF(x) ((x) >> HALF_BITS)
+#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1))
+#define LHUP(x) ((x) << HALF_BITS)
+
+quad_t __divdi3(quad_t a, quad_t b);
+quad_t __moddi3(quad_t a, quad_t b);
+u_quad_t __qdivrem(u_quad_t u, u_quad_t v, u_quad_t *rem);
+u_quad_t __udivdi3(u_quad_t a, u_quad_t b);
+u_quad_t __umoddi3(u_quad_t a, u_quad_t b);
+
+/*
+ * XXX
+ * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument
+ * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use
+ * both compilers.
+ */
+#if __GNUC__ >= 2
+typedef unsigned int qshift_t;
+#else
+typedef u_quad_t qshift_t;
+#endif
diff --git a/usr/src/boot/lib/libstand/random.c b/usr/src/boot/lib/libstand/random.c
new file mode 100644
index 0000000000..4cd6dd4d4e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/random.c
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)random.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+static u_long randseed = 1;
+
+void
+srandom(seed)
+ u_long seed;
+{
+ randseed = seed;
+}
+
+/*
+ * Pseudo-random number generator for randomizing the profiling clock,
+ * and whatever else we might use it for. The result is uniform on
+ * [0, 2^31 - 1].
+ */
+u_long
+random()
+{
+ long x, hi, lo, t;
+
+ /*
+ * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+ */
+ x = randseed;
+ hi = x / 127773;
+ lo = x % 127773;
+ t = 16807 * lo - 2836 * hi;
+ if (t <= 0)
+ t += 0x7fffffff;
+ randseed = t;
+ return (t);
+}
diff --git a/usr/src/boot/lib/libstand/rarp.c b/usr/src/boot/lib/libstand/rarp.c
new file mode 100644
index 0000000000..07ec1ccd4c
--- /dev/null
+++ b/usr/src/boot/lib/libstand/rarp.c
@@ -0,0 +1,225 @@
+/* $NetBSD: rarp.c,v 1.16 1997/07/07 15:52:52 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+
+static ssize_t rarpsend(struct iodesc *, void *, size_t);
+static ssize_t rarprecv(struct iodesc *, void *, size_t, time_t);
+
+/*
+ * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
+ */
+int
+rarp_getipaddress(sock)
+ int sock;
+{
+ struct iodesc *d;
+ struct ether_arp *ap;
+ struct {
+ u_char header[ETHER_SIZE];
+ struct {
+ struct ether_arp arp;
+ u_char pad[18]; /* 60 - sizeof(arp) */
+ } data;
+ } wbuf;
+ struct {
+ u_char header[ETHER_SIZE];
+ struct {
+ struct ether_arp arp;
+ u_char pad[24]; /* extra space */
+ } data;
+ } rbuf;
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarp: socket=%d\n", sock);
+#endif
+ if (!(d = socktodesc(sock))) {
+ printf("rarp: bad socket. %d\n", sock);
+ return (-1);
+ }
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarp: d=%x\n", (u_int)d);
+#endif
+
+ bzero((char*)&wbuf.data, sizeof(wbuf.data));
+ ap = &wbuf.data.arp;
+ ap->arp_hrd = htons(ARPHRD_ETHER);
+ ap->arp_pro = htons(ETHERTYPE_IP);
+ ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */
+ ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */
+ ap->arp_op = htons(ARPOP_REVREQUEST);
+ bcopy(d->myea, ap->arp_sha, 6);
+ bcopy(d->myea, ap->arp_tha, 6);
+
+ if (sendrecv(d,
+ rarpsend, &wbuf.data, sizeof(wbuf.data),
+ rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0)
+ {
+ printf("No response for RARP request\n");
+ return (-1);
+ }
+
+ ap = &rbuf.data.arp;
+ bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip));
+#if 0
+ /* XXX - Can NOT assume this is our root server! */
+ bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip));
+#endif
+
+ /* Compute our "natural" netmask. */
+ if (IN_CLASSA(myip.s_addr))
+ netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(myip.s_addr))
+ netmask = IN_CLASSB_NET;
+ else
+ netmask = IN_CLASSC_NET;
+
+ d->myip = myip;
+ return (0);
+}
+
+/*
+ * Broadcast a RARP request (i.e. who knows who I am)
+ */
+static ssize_t
+rarpsend(d, pkt, len)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+{
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarpsend: called\n");
+#endif
+
+ return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP));
+}
+
+/*
+ * Returns 0 if this is the packet we're waiting for
+ * else -1 (and errno == 0)
+ */
+static ssize_t
+rarprecv(d, pkt, len, tleft)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ time_t tleft;
+{
+ ssize_t n;
+ struct ether_arp *ap;
+ u_int16_t etype; /* host order */
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarprecv: ");
+#endif
+
+ n = readether(d, pkt, len, tleft, &etype);
+ errno = 0; /* XXX */
+ if (n == -1 || n < sizeof(struct ether_arp)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad len=%d\n", n);
+#endif
+ return (-1);
+ }
+
+ if (etype != ETHERTYPE_REVARP) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad type=0x%x\n", etype);
+#endif
+ return (-1);
+ }
+
+ ap = (struct ether_arp *)pkt;
+ if (ap->arp_hrd != htons(ARPHRD_ETHER) ||
+ ap->arp_pro != htons(ETHERTYPE_IP) ||
+ ap->arp_hln != sizeof(ap->arp_sha) ||
+ ap->arp_pln != sizeof(ap->arp_spa) )
+ {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad hrd/pro/hln/pln\n");
+#endif
+ return (-1);
+ }
+
+ if (ap->arp_op != htons(ARPOP_REVREPLY)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad op=0x%x\n", ntohs(ap->arp_op));
+#endif
+ return (-1);
+ }
+
+ /* Is the reply for our Ethernet address? */
+ if (bcmp(ap->arp_tha, d->myea, 6)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("unwanted address\n");
+#endif
+ return (-1);
+ }
+
+ /* We have our answer. */
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("got it\n");
+#endif
+ return (n);
+}
diff --git a/usr/src/boot/lib/libstand/read.c b/usr/src/boot/lib/libstand/read.c
new file mode 100644
index 0000000000..32f7084a8b
--- /dev/null
+++ b/usr/src/boot/lib/libstand/read.c
@@ -0,0 +1,127 @@
+/* $NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)read.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include "stand.h"
+
+ssize_t
+read(int fd, void *dest, size_t bcount)
+{
+ struct open_file *f = &files[fd];
+ size_t resid;
+
+ if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ twiddle(8);
+ errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ btodb(f->f_offset), 0, bcount, dest, &resid);
+ if (errno)
+ return (-1);
+ f->f_offset += resid;
+ return (resid);
+ }
+
+ /*
+ * Optimise reads from regular files using a readahead buffer.
+ * If the request can't be satisfied from the current buffer contents,
+ * check to see if it should be bypassed, or refill the buffer and complete
+ * the request.
+ */
+ resid = bcount;
+ for (;;) {
+ size_t ccount, cresid;
+ /* how much can we supply? */
+ ccount = imin(f->f_ralen, resid);
+ if (ccount > 0) {
+ bcopy(f->f_rabuf + f->f_raoffset, dest, ccount);
+ f->f_raoffset += ccount;
+ f->f_ralen -= ccount;
+ resid -= ccount;
+ if (resid == 0)
+ return(bcount);
+ dest = (char *)dest + ccount;
+ }
+
+ /* will filling the readahead buffer again not help? */
+ if (resid >= SOPEN_RASIZE) {
+ /* bypass the rest of the request and leave the buffer empty */
+ if ((errno = (f->f_ops->fo_read)(f, dest, resid, &cresid)))
+ return (-1);
+ return(bcount - cresid);
+ }
+
+ /* fetch more data */
+ if ((errno = (f->f_ops->fo_read)(f, f->f_rabuf, SOPEN_RASIZE, &cresid)))
+ return (-1);
+ f->f_raoffset = 0;
+ f->f_ralen = SOPEN_RASIZE - cresid;
+ /* no more data, return what we had */
+ if (f->f_ralen == 0)
+ return(bcount - resid);
+ }
+}
diff --git a/usr/src/boot/lib/libstand/readdir.c b/usr/src/boot/lib/libstand/readdir.c
new file mode 100644
index 0000000000..e49d93d15e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/readdir.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include "stand.h"
+
+struct dirent *
+readdirfd(int fd)
+{
+ static struct dirent dir; /* XXX not thread safe */
+ struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
+ errno = EBADF;
+ return (NULL);
+ }
+ if (f->f_flags & F_RAW) {
+ errno = EIO;
+ return (NULL);
+ }
+ errno = (f->f_ops->fo_readdir)(f, &dir);
+ if (errno)
+ return (NULL);
+ return (&dir);
+}
diff --git a/usr/src/boot/lib/libstand/rpc.c b/usr/src/boot/lib/libstand/rpc.c
new file mode 100644
index 0000000000..ee155f6ee0
--- /dev/null
+++ b/usr/src/boot/lib/libstand/rpc.c
@@ -0,0 +1,438 @@
+/* $NetBSD: rpc.c,v 1.18 1998/01/23 19:27:45 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: rpc.c,v 1.12 93/09/28 08:31:56 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * RPC functions used by NFS and bootparams.
+ * Note that bootparams requires the ability to find out the
+ * address of the server from which its response has come.
+ * This is supported by keeping the IP/UDP headers in the
+ * buffer space provided by the caller. (See rpc_fromaddr)
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "rpcv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+
+struct auth_info {
+ int32_t authtype; /* auth type */
+ u_int32_t authlen; /* auth length */
+};
+
+struct auth_unix {
+ int32_t ua_time;
+ int32_t ua_hostname; /* null */
+ int32_t ua_uid;
+ int32_t ua_gid;
+ int32_t ua_gidlist; /* null */
+};
+
+struct rpc_call {
+ u_int32_t rp_xid; /* request transaction id */
+ int32_t rp_direction; /* call direction (0) */
+ u_int32_t rp_rpcvers; /* rpc version (2) */
+ u_int32_t rp_prog; /* program */
+ u_int32_t rp_vers; /* version */
+ u_int32_t rp_proc; /* procedure */
+};
+
+struct rpc_reply {
+ u_int32_t rp_xid; /* request transaction id */
+ int32_t rp_direction; /* call direction (1) */
+ int32_t rp_astatus; /* accept status (0: accepted) */
+ union {
+ u_int32_t rpu_errno;
+ struct {
+ struct auth_info rok_auth;
+ u_int32_t rok_status;
+ } rpu_rok;
+ } rp_u;
+};
+
+/* Local forwards */
+static ssize_t recvrpc(struct iodesc *, void *, size_t, time_t);
+static int rpc_getport(struct iodesc *, n_long, n_long);
+
+int rpc_xid;
+int rpc_port = 0x400; /* predecrement */
+
+/*
+ * Make a rpc call; return length of answer
+ * Note: Caller must leave room for headers.
+ */
+ssize_t
+rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
+ void *sdata, size_t slen, void *rdata, size_t rlen)
+{
+ ssize_t cc;
+ struct auth_info *auth;
+ struct rpc_call *call;
+ struct rpc_reply *reply;
+ char *send_head, *send_tail;
+ char *recv_head, *recv_tail;
+ n_long x;
+ int port; /* host order */
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
+ prog, vers, proc);
+#endif
+
+ port = rpc_getport(d, prog, vers);
+ if (port == -1)
+ return (-1);
+
+ d->destport = htons(port);
+
+ /*
+ * Prepend authorization stuff and headers.
+ * Note, must prepend things in reverse order.
+ */
+ send_head = sdata;
+ send_tail = (char *)sdata + slen;
+
+ /* Auth verifier is always auth_null */
+ send_head -= sizeof(*auth);
+ auth = (struct auth_info *)send_head;
+ auth->authtype = htonl(RPCAUTH_NULL);
+ auth->authlen = 0;
+
+#if 1
+ /* Auth credentials: always auth unix (as root) */
+ send_head -= sizeof(struct auth_unix);
+ bzero(send_head, sizeof(struct auth_unix));
+ send_head -= sizeof(*auth);
+ auth = (struct auth_info *)send_head;
+ auth->authtype = htonl(RPCAUTH_UNIX);
+ auth->authlen = htonl(sizeof(struct auth_unix));
+#else
+ /* Auth credentials: always auth_null (XXX OK?) */
+ send_head -= sizeof(*auth);
+ auth = send_head;
+ auth->authtype = htonl(RPCAUTH_NULL);
+ auth->authlen = 0;
+#endif
+
+ /* RPC call structure. */
+ send_head -= sizeof(*call);
+ call = (struct rpc_call *)send_head;
+ rpc_xid++;
+ call->rp_xid = htonl(rpc_xid);
+ call->rp_direction = htonl(RPC_CALL);
+ call->rp_rpcvers = htonl(RPC_VER2);
+ call->rp_prog = htonl(prog);
+ call->rp_vers = htonl(vers);
+ call->rp_proc = htonl(proc);
+
+ /* Make room for the rpc_reply header. */
+ recv_head = rdata;
+ recv_tail = (char *)rdata + rlen;
+ recv_head -= sizeof(*reply);
+
+ cc = sendrecv(d,
+ sendudp, send_head, send_tail - send_head,
+ recvrpc, recv_head, recv_tail - recv_head);
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("callrpc: cc=%ld rlen=%lu\n", (long)cc, (u_long)rlen);
+#endif
+ if (cc == -1)
+ return (-1);
+
+ if (cc <= sizeof(*reply)) {
+ errno = EBADRPC;
+ return (-1);
+ }
+
+ recv_tail = recv_head + cc;
+
+ /*
+ * Check the RPC reply status.
+ * The xid, dir, astatus were already checked.
+ */
+ reply = (struct rpc_reply *)recv_head;
+ auth = &reply->rp_u.rpu_rok.rok_auth;
+ x = ntohl(auth->authlen);
+ if (x != 0) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("callrpc: reply auth != NULL\n");
+#endif
+ errno = EBADRPC;
+ return(-1);
+ }
+ x = ntohl(reply->rp_u.rpu_rok.rok_status);
+ if (x != 0) {
+ printf("callrpc: error = %ld\n", (long)x);
+ errno = EBADRPC;
+ return(-1);
+ }
+ recv_head += sizeof(*reply);
+
+ return (ssize_t)(recv_tail - recv_head);
+}
+
+/*
+ * Returns true if packet is the one we're waiting for.
+ * This just checks the XID, direction, acceptance.
+ * Remaining checks are done by callrpc
+ */
+static ssize_t
+recvrpc(struct iodesc *d, void *pkt, size_t len, time_t tleft)
+{
+ struct rpc_reply *reply;
+ ssize_t n;
+ int x;
+
+ errno = 0;
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: called len=%lu\n", (u_long)len);
+#endif
+
+ n = readudp(d, pkt, len, tleft);
+ if (n <= (4 * 4))
+ return -1;
+
+ reply = (struct rpc_reply *)pkt;
+
+ x = ntohl(reply->rp_xid);
+ if (x != rpc_xid) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: rp_xid %d != xid %d\n", x, rpc_xid);
+#endif
+ return -1;
+ }
+
+ x = ntohl(reply->rp_direction);
+ if (x != RPC_REPLY) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: rp_direction %d != REPLY\n", x);
+#endif
+ return -1;
+ }
+
+ x = ntohl(reply->rp_astatus);
+ if (x != RPC_MSGACCEPTED) {
+ errno = ntohl(reply->rp_u.rpu_errno);
+ printf("recvrpc: reject, astat=%d, errno=%d\n", x, errno);
+ return -1;
+ }
+
+ /* Return data count (thus indicating success) */
+ return (n);
+}
+
+/*
+ * Given a pointer to a reply just received,
+ * dig out the IP address/port from the headers.
+ */
+void
+rpc_fromaddr(void *pkt, struct in_addr *addr, u_short *port)
+{
+ struct hackhdr {
+ /* Tail of IP header: just IP addresses */
+ n_long ip_src;
+ n_long ip_dst;
+ /* UDP header: */
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+ /* RPC reply header: */
+ struct rpc_reply rpc;
+ } *hhdr;
+
+ hhdr = ((struct hackhdr *)pkt) - 1;
+ addr->s_addr = hhdr->ip_src;
+ *port = hhdr->uh_sport;
+}
+
+/*
+ * RPC Portmapper cache
+ */
+#define PMAP_NUM 8 /* need at most 5 pmap entries */
+
+int rpc_pmap_num;
+struct pmap_list {
+ struct in_addr addr; /* server, net order */
+ u_int prog; /* host order */
+ u_int vers; /* host order */
+ int port; /* host order */
+} rpc_pmap_list[PMAP_NUM];
+
+/*
+ * return port number in host order, or -1.
+ * arguments are:
+ * addr .. server, net order.
+ * prog .. host order.
+ * vers .. host order.
+ */
+int
+rpc_pmap_getcache(struct in_addr addr, u_int prog, u_int vers)
+{
+ struct pmap_list *pl;
+
+ for (pl = rpc_pmap_list; pl < &rpc_pmap_list[rpc_pmap_num]; pl++) {
+ if (pl->addr.s_addr == addr.s_addr &&
+ pl->prog == prog && pl->vers == vers )
+ {
+ return (pl->port);
+ }
+ }
+ return (-1);
+}
+
+/*
+ * arguments are:
+ * addr .. server, net order.
+ * prog .. host order.
+ * vers .. host order.
+ * port .. host order.
+ */
+void
+rpc_pmap_putcache(struct in_addr addr, u_int prog, u_int vers, int port)
+{
+ struct pmap_list *pl;
+
+ /* Don't overflow cache... */
+ if (rpc_pmap_num >= PMAP_NUM) {
+ /* ... just re-use the last entry. */
+ rpc_pmap_num = PMAP_NUM - 1;
+#ifdef RPC_DEBUG
+ printf("rpc_pmap_putcache: cache overflow\n");
+#endif
+ }
+
+ pl = &rpc_pmap_list[rpc_pmap_num];
+ rpc_pmap_num++;
+
+ /* Cache answer */
+ pl->addr = addr;
+ pl->prog = prog;
+ pl->vers = vers;
+ pl->port = port;
+}
+
+
+/*
+ * Request a port number from the port mapper.
+ * Returns the port in host order.
+ * prog and vers are host order.
+ */
+int
+rpc_getport(struct iodesc *d, n_long prog, n_long vers)
+{
+ struct args {
+ n_long prog; /* call program */
+ n_long vers; /* call version */
+ n_long proto; /* call protocol */
+ n_long port; /* call port (unused) */
+ } *args;
+ struct res {
+ n_long port;
+ } *res;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct res d;
+ n_long pad;
+ } rdata;
+ ssize_t cc;
+ int port;
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("%s: prog=0x%x vers=%d\n", __func__, prog, vers);
+#endif
+
+ /* This one is fixed forever. */
+ if (prog == PMAPPROG) {
+ port = PMAPPORT;
+ goto out;
+ }
+
+ /* Try for cached answer first */
+ port = rpc_pmap_getcache(d->destip, prog, vers);
+ if (port != -1)
+ goto out;
+
+ args = &sdata.d;
+ args->prog = htonl(prog);
+ args->vers = htonl(vers);
+ args->proto = htonl(IPPROTO_UDP);
+ args->port = 0;
+ res = &rdata.d;
+
+ cc = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT,
+ args, sizeof(*args), res, sizeof(*res));
+ if (cc < sizeof(*res)) {
+ printf("getport: %s", strerror(errno));
+ errno = EBADRPC;
+ return (-1);
+ }
+ port = (int)ntohl(res->port);
+
+ rpc_pmap_putcache(d->destip, prog, vers, port);
+
+out:
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("%s: port=%u\n", __func__, port);
+#endif
+ return (port);
+}
diff --git a/usr/src/boot/lib/libstand/rpc.h b/usr/src/boot/lib/libstand/rpc.h
new file mode 100644
index 0000000000..e06ce41692
--- /dev/null
+++ b/usr/src/boot/lib/libstand/rpc.h
@@ -0,0 +1,66 @@
+/* $NetBSD: rpc.h,v 1.8 1996/09/26 23:22:03 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* XXX defines we can't easily get from system includes */
+#define PMAPPORT 111
+#define PMAPPROG 100000
+#define PMAPVERS 2
+#define PMAPPROC_NULL 0
+#define PMAPPROC_SET 1
+#define PMAPPROC_UNSET 2
+#define PMAPPROC_GETPORT 3
+#define PMAPPROC_DUMP 4
+#define PMAPPROC_CALLIT 5
+
+/* RPC functions: */
+ssize_t rpc_call(struct iodesc *, n_long, n_long, n_long,
+ void *, size_t, void *, size_t);
+void rpc_fromaddr(void *, struct in_addr *, u_short *);
+int rpc_pmap_getcache(struct in_addr, u_int, u_int);
+void rpc_pmap_putcache(struct in_addr, u_int, u_int, int);
+
+extern int rpc_port; /* decrement before bind */
+
+/*
+ * How much space to leave in front of RPC requests.
+ * In 32-bit words (alignment) we have:
+ * 12: Ether + IP + UDP + padding
+ * 6: RPC call header
+ * 7: Auth UNIX
+ * 2: Auth NULL
+ */
+#define RPC_HEADER_WORDS 28
diff --git a/usr/src/boot/lib/libstand/rpcv2.h b/usr/src/boot/lib/libstand/rpcv2.h
new file mode 100644
index 0000000000..b59a760198
--- /dev/null
+++ b/usr/src/boot/lib/libstand/rpcv2.h
@@ -0,0 +1,87 @@
+/* $NetBSD: rpcv2.h,v 1.1 1996/02/26 23:05:32 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)rpcv2.h 8.1 (Berkeley) 6/10/93
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Definitions for Sun RPC Version 2, from
+ * "RPC: Remote Procedure Call Protocol Specification" RFC1057
+ */
+
+/* Version # */
+#define RPC_VER2 2
+
+/* Authentication */
+#define RPCAUTH_NULL 0
+#define RPCAUTH_UNIX 1
+#define RPCAUTH_SHORT 2
+#define RPCAUTH_MAXSIZ 400
+#define RPCAUTH_UNIXGIDS 16
+
+/* Rpc Constants */
+#define RPC_CALL 0
+#define RPC_REPLY 1
+#define RPC_MSGACCEPTED 0
+#define RPC_MSGDENIED 1
+#define RPC_PROGUNAVAIL 1
+#define RPC_PROGMISMATCH 2
+#define RPC_PROCUNAVAIL 3
+#define RPC_GARBAGE 4 /* I like this one */
+#define RPC_MISMATCH 0
+#define RPC_AUTHERR 1
+
+/* Authentication failures */
+#define AUTH_BADCRED 1
+#define AUTH_REJECTCRED 2
+#define AUTH_BADVERF 3
+#define AUTH_REJECTVERF 4
+#define AUTH_TOOWEAK 5 /* Give em wheaties */
+
+/* Sizes of rpc header parts */
+#define RPC_SIZ 24
+#define RPC_REPLYSIZ 28
+
+/* RPC Prog definitions */
+#define RPCPROG_MNT 100005
+#define RPCMNT_VER1 1
+#define RPCMNT_MOUNT 1
+#define RPCMNT_DUMP 2
+#define RPCMNT_UMOUNT 3
+#define RPCMNT_UMNTALL 4
+#define RPCMNT_EXPORT 5
+#define RPCMNT_NAMELEN 255
+#define RPCMNT_PATHLEN 1024
+#define RPCPROG_NFS 100003
diff --git a/usr/src/boot/lib/libstand/saioctl.h b/usr/src/boot/lib/libstand/saioctl.h
new file mode 100644
index 0000000000..5f888ff855
--- /dev/null
+++ b/usr/src/boot/lib/libstand/saioctl.h
@@ -0,0 +1,50 @@
+/* $NetBSD: saioctl.h,v 1.2 1994/10/26 05:45:04 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)saioctl.h 8.1 (Berkeley) 6/11/93
+ *
+ * $FreeBSD$
+ */
+
+/* ioctl's -- for disks just now */
+#define SAIOHDR (('d'<<8)|1) /* next i/o includes header */
+#define SAIOCHECK (('d'<<8)|2) /* next i/o checks data */
+#define SAIOHCHECK (('d'<<8)|3) /* next i/o checks header & data */
+#define SAIONOBAD (('d'<<8)|4) /* inhibit bad sector forwarding */
+#define SAIODOBAD (('d'<<8)|5) /* enable bad sector forwarding */
+#define SAIOECCLIM (('d'<<8)|6) /* set limit to ecc correction, bits */
+#define SAIOECCUNL (('d'<<8)|7) /* use standard ecc procedures */
+#define SAIORETRIES (('d'<<8)|8) /* set retry count for unit */
+#define SAIODEVDATA (('d'<<8)|9) /* get pointer to pack label */
+#define SAIOSSI (('d'<<8)|10) /* set skip sector inhibit */
+#define SAIONOSSI (('d'<<8)|11) /* inhibit skip sector handling */
+#define SAIOSSDEV (('d'<<8)|12) /* is device skip sector type? */
+#define SAIODEBUG (('d'<<8)|13) /* enable/disable debugging */
+#define SAIOGBADINFO (('d'<<8)|14) /* get bad-sector table */
diff --git a/usr/src/boot/lib/libstand/sbrk.c b/usr/src/boot/lib/libstand/sbrk.c
new file mode 100644
index 0000000000..471e78ecf6
--- /dev/null
+++ b/usr/src/boot/lib/libstand/sbrk.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1998 Michael Smith
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Minimal sbrk() emulation required for malloc support.
+ */
+
+#include <string.h>
+#include "stand.h"
+#include "zalloc_defs.h"
+
+static size_t maxheap, heapsize = 0;
+static void *heapbase;
+
+void
+setheap(void *base, void *top)
+{
+ /* Align start address for the malloc code. Sigh. */
+ heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) &
+ ~MALLOCALIGN_MASK);
+ maxheap = (char *)top - (char *)heapbase;
+}
+
+char *
+sbrk(int incr)
+{
+ char *ret;
+
+ if ((heapsize + incr) <= maxheap) {
+ ret = (char *)heapbase + heapsize;
+ bzero(ret, incr);
+ heapsize += incr;
+ return(ret);
+ }
+ errno = ENOMEM;
+ return((char *)-1);
+}
+
diff --git a/usr/src/boot/lib/libstand/sparc64/_setjmp.S b/usr/src/boot/lib/libstand/sparc64/_setjmp.S
new file mode 100644
index 0000000000..50c924e842
--- /dev/null
+++ b/usr/src/boot/lib/libstand/sparc64/_setjmp.S
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $Header: _setjmp.s,v 1.1 91/07/06 16:45:53 torek Exp
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+ .asciz "@(#)_setjmp.s 8.1 (Berkeley) 6/4/93"
+#else
+ RCSID("$NetBSD: _setjmp.S,v 1.4 1998/10/08 02:27:59 eeh Exp $")
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+#define _JB_FP 0x0
+#define _JB_PC 0x8
+#define _JB_SP 0x10
+
+ .register %g2,#ignore
+ .register %g3,#ignore
+
+/*
+ * C library -- setjmp, longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v?v:1)" from
+ * the last call to
+ * setjmp(a)
+ * by restoring the previous context.
+ */
+
+ENTRY(_setjmp)
+ stx %sp, [%o0 + _JB_SP]
+ stx %o7, [%o0 + _JB_PC]
+ stx %fp, [%o0 + _JB_FP]
+ retl
+ clr %o0
+END(_setjmp)
+
+ENTRY(_longjmp)
+ mov 1, %g1
+ movrnz %o1, %o1, %g1
+ mov %o0, %g2
+ ldx [%g2 + _JB_FP], %g3
+1: cmp %fp, %g3
+ bl,a 1b
+ restore
+ be,a 2f
+ ldx [%g2 + _JB_SP], %o0
+
+.Lbotch:
+ illtrap
+
+2: cmp %o0, %sp
+ bge,a 3f
+ mov %o0, %sp
+ b,a .Lbotch
+ nop
+3: ldx [%g2 + _JB_PC], %o7
+ retl
+ mov %g1, %o0
+END(_longjmp)
diff --git a/usr/src/boot/lib/libstand/splitfs.c b/usr/src/boot/lib/libstand/splitfs.c
new file mode 100644
index 0000000000..af28704bc4
--- /dev/null
+++ b/usr/src/boot/lib/libstand/splitfs.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2002 Maxim Sobolev
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+#define NTRIES (3)
+#define CONF_BUF (512)
+#define SEEK_BUF (512)
+
+struct split_file
+{
+ char **filesv; /* Filenames */
+ char **descsv; /* Descriptions */
+ int filesc; /* Number of parts */
+ int curfile; /* Current file number */
+ int curfd; /* Current file descriptor */
+ off_t tot_pos; /* Offset from the beginning of the sequence */
+ off_t file_pos; /* Offset from the beginning of the slice */
+};
+
+static int split_openfile(struct split_file *sf);
+static int splitfs_open(const char *path, struct open_file *f);
+static int splitfs_close(struct open_file *f);
+static int splitfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t splitfs_seek(struct open_file *f, off_t offset, int where);
+static int splitfs_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops splitfs_fsops = {
+ "split",
+ splitfs_open,
+ splitfs_close,
+ splitfs_read,
+ null_write,
+ splitfs_seek,
+ splitfs_stat,
+ null_readdir
+};
+
+static void
+split_file_destroy(struct split_file *sf)
+{
+ int i;
+
+ if (sf->filesc > 0) {
+ for (i = 0; i < sf->filesc; i++) {
+ free(sf->filesv[i]);
+ free(sf->descsv[i]);
+ }
+ free(sf->filesv);
+ free(sf->descsv);
+ }
+ free(sf);
+}
+
+static int
+split_openfile(struct split_file *sf)
+{
+ int i;
+
+ for (i = 0;; i++) {
+ sf->curfd = open(sf->filesv[sf->curfile], O_RDONLY);
+ if (sf->curfd >= 0)
+ break;
+ if ((sf->curfd == -1) && (errno != ENOENT))
+ return (errno);
+ if (i == NTRIES)
+ return (EIO);
+ printf("\nInsert disk labelled %s and press any key...",
+ sf->descsv[sf->curfile]);
+ getchar();
+ putchar('\n');
+ }
+ sf->file_pos = 0;
+ return (0);
+}
+
+static int
+splitfs_open(const char *fname, struct open_file *f)
+{
+ char *buf, *confname, *cp;
+ int conffd;
+ struct split_file *sf;
+ struct stat sb;
+
+ /* Have to be in "just read it" mode */
+ if (f->f_flags != F_READ)
+ return(EPERM);
+
+ /* If the name already ends in `.split', ignore it */
+ if ((cp = strrchr(fname, '.')) && (!strcmp(cp, ".split")))
+ return(ENOENT);
+
+ /* Construct new name */
+ confname = malloc(strlen(fname) + 7);
+ sprintf(confname, "%s.split", fname);
+
+ /* Try to open the configuration file */
+ conffd = open(confname, O_RDONLY);
+ free(confname);
+ if (conffd == -1)
+ return(ENOENT);
+
+ if (fstat(conffd, &sb) < 0) {
+ printf("splitfs_open: stat failed\n");
+ close(conffd);
+ return(ENOENT);
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ printf("splitfs_open: not a file\n");
+ close(conffd);
+ return(EISDIR); /* best guess */
+ }
+
+ /* Allocate a split_file structure, populate it from the config file */
+ sf = malloc(sizeof(struct split_file));
+ bzero(sf, sizeof(struct split_file));
+ buf = malloc(CONF_BUF);
+ while (fgetstr(buf, CONF_BUF, conffd) > 0) {
+ cp = buf;
+ while ((*cp != '\0') && (isspace(*cp) == 0))
+ cp++;
+ if (*cp != '\0') {
+ *cp = '\0';
+ cp++;
+ }
+ while ((*cp != '\0') && (isspace(*cp) != 0))
+ cp++;
+ if (*cp == '\0')
+ cp = buf;
+ sf->filesc++;
+ sf->filesv = realloc(sf->filesv, sizeof(*(sf->filesv)) * sf->filesc);
+ sf->descsv = realloc(sf->descsv, sizeof(*(sf->descsv)) * sf->filesc);
+ sf->filesv[sf->filesc - 1] = strdup(buf);
+ sf->descsv[sf->filesc - 1] = strdup(cp);
+ }
+ free(buf);
+ close(conffd);
+
+ if (sf->filesc == 0) {
+ split_file_destroy(sf);
+ return(ENOENT);
+ }
+ errno = split_openfile(sf);
+ if (errno != 0) {
+ split_file_destroy(sf);
+ return(ENOENT);
+ }
+
+ /* Looks OK, we'll take it */
+ f->f_fsdata = sf;
+ return (0);
+}
+
+static int
+splitfs_close(struct open_file *f)
+{
+ int fd;
+ struct split_file *sf;
+
+ sf = (struct split_file *)f->f_fsdata;
+ fd = sf->curfd;
+ split_file_destroy(sf);
+ return(close(fd));
+}
+
+static int
+splitfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ ssize_t nread;
+ size_t totread;
+ struct split_file *sf;
+
+ sf = (struct split_file *)f->f_fsdata;
+ totread = 0;
+ do {
+ nread = read(sf->curfd, buf, size - totread);
+
+ /* Error? */
+ if (nread == -1)
+ return (errno);
+
+ sf->tot_pos += nread;
+ sf->file_pos += nread;
+ totread += nread;
+ buf = (char *)buf + nread;
+
+ if (totread < size) { /* EOF */
+ if (sf->curfile == (sf->filesc - 1)) /* Last slice */
+ break;
+
+ /* Close previous slice */
+ if (close(sf->curfd) != 0)
+ return (errno);
+
+ sf->curfile++;
+ errno = split_openfile(sf);
+ if (errno)
+ return (errno);
+ }
+ } while (totread < size);
+
+ if (resid != NULL)
+ *resid = size - totread;
+
+ return (0);
+}
+
+static off_t
+splitfs_seek(struct open_file *f, off_t offset, int where)
+{
+ int nread;
+ size_t resid;
+ off_t new_pos, seek_by;
+ struct split_file *sf;
+
+ sf = (struct split_file *)f->f_fsdata;
+
+ seek_by = offset;
+ switch (where) {
+ case SEEK_SET:
+ seek_by -= sf->tot_pos;
+ break;
+ case SEEK_CUR:
+ break;
+ case SEEK_END:
+ panic("splitfs_seek: SEEK_END not supported");
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (seek_by > 0) {
+ /*
+ * Seek forward - implemented using splitfs_read(), because otherwise we'll be
+ * unable to detect that we have crossed slice boundary and hence
+ * unable to do a long seek crossing that boundary.
+ */
+ void *tmp;
+
+ tmp = malloc(SEEK_BUF);
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ nread = 0;
+ for (; seek_by > 0; seek_by -= nread) {
+ resid = 0;
+ errno = splitfs_read(f, tmp, min(seek_by, SEEK_BUF), &resid);
+ nread = min(seek_by, SEEK_BUF) - resid;
+ if ((errno != 0) || (nread == 0))
+ /* Error or EOF */
+ break;
+ }
+ free(tmp);
+ if (errno != 0)
+ return (-1);
+ }
+
+ if (seek_by != 0) {
+ /* Seek backward or seek past the boundary of the last slice */
+ if (sf->file_pos + seek_by < 0)
+ panic("splitfs_seek: can't seek past the beginning of the slice");
+ new_pos = lseek(sf->curfd, seek_by, SEEK_CUR);
+ if (new_pos < 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+ sf->tot_pos += new_pos - sf->file_pos;
+ sf->file_pos = new_pos;
+ }
+
+ return (sf->tot_pos);
+}
+
+static int
+splitfs_stat(struct open_file *f, struct stat *sb)
+{
+ int result;
+ struct split_file *sf = (struct split_file *)f->f_fsdata;
+
+ /* stat as normal, but indicate that size is unknown */
+ if ((result = fstat(sf->curfd, sb)) == 0)
+ sb->st_size = -1;
+ return (result);
+}
diff --git a/usr/src/boot/lib/libstand/stand.h b/usr/src/boot/lib/libstand/stand.h
new file mode 100644
index 0000000000..fd09f8538e
--- /dev/null
+++ b/usr/src/boot/lib/libstand/stand.h
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stand.h 8.1 (Berkeley) 6/11/93
+ */
+
+#ifndef STAND_H
+#define STAND_H
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+#include <sys/dirent.h>
+
+/* this header intentionally exports NULL from <string.h> */
+#include <string.h>
+
+#define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args)
+#define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args); getchar();}
+
+/* Avoid unwanted userlandish components */
+#define _KERNEL
+#include <sys/errno.h>
+#undef _KERNEL
+
+/* special stand error codes */
+#define EADAPT (ELAST+1) /* bad adaptor */
+#define ECTLR (ELAST+2) /* bad controller */
+#define EUNIT (ELAST+3) /* bad unit */
+#define ESLICE (ELAST+4) /* bad slice */
+#define EPART (ELAST+5) /* bad partition */
+#define ERDLAB (ELAST+6) /* can't read disk label */
+#define EUNLAB (ELAST+7) /* unlabeled disk */
+#define EOFFSET (ELAST+8) /* relative seek not supported */
+#define ESALAST (ELAST+8) /* */
+
+struct open_file;
+
+/*
+ * This structure is used to define file system operations in a file system
+ * independent way.
+ *
+ * XXX note that filesystem providers should export a pointer to their fs_ops
+ * struct, so that consumers can reference this and thus include the
+ * filesystems that they require.
+ */
+struct fs_ops {
+ const char *fs_name;
+ int (*fo_open)(const char *path, struct open_file *f);
+ int (*fo_close)(struct open_file *f);
+ int (*fo_read)(struct open_file *f, void *buf,
+ size_t size, size_t *resid);
+ int (*fo_write)(struct open_file *f, void *buf,
+ size_t size, size_t *resid);
+ off_t (*fo_seek)(struct open_file *f, off_t offset, int where);
+ int (*fo_stat)(struct open_file *f, struct stat *sb);
+ int (*fo_readdir)(struct open_file *f, struct dirent *d);
+};
+
+/*
+ * libstand-supplied filesystems
+ */
+extern struct fs_ops ufs_fsops;
+extern struct fs_ops tftp_fsops;
+extern struct fs_ops nfs_fsops;
+extern struct fs_ops cd9660_fsops;
+extern struct fs_ops nandfs_fsops;
+extern struct fs_ops gzipfs_fsops;
+extern struct fs_ops bzipfs_fsops;
+extern struct fs_ops dosfs_fsops;
+extern struct fs_ops ext2fs_fsops;
+extern struct fs_ops splitfs_fsops;
+extern struct fs_ops pkgfs_fsops;
+
+/* where values for lseek(2) */
+#define SEEK_SET 0 /* set file offset to offset */
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+
+/*
+ * Device switch
+ */
+struct devsw {
+ const char dv_name[8];
+ int dv_type; /* opaque type constant, arch-dependant */
+ int (*dv_init)(void); /* early probe call */
+ int (*dv_strategy)(void *devdata, int rw, daddr_t blk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+ int (*dv_open)(struct open_file *f, ...);
+ int (*dv_close)(struct open_file *f);
+ int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data);
+ int (*dv_print)(int verbose); /* print device information */
+ void (*dv_cleanup)(void);
+};
+
+/*
+ * libstand-supplied device switch
+ */
+extern struct devsw netdev;
+
+extern int errno;
+
+/*
+ * Generic device specifier; architecture-dependent
+ * versions may be larger, but should be allowed to
+ * overlap.
+ */
+struct devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+#define DEVT_NONE 0
+#define DEVT_DISK 1
+#define DEVT_NET 2
+#define DEVT_CD 3
+#define DEVT_ZFS 4
+ int d_unit;
+ void *d_opendata;
+};
+
+struct open_file {
+ int f_flags; /* see F_* below */
+ struct devsw *f_dev; /* pointer to device operations */
+ void *f_devdata; /* device specific data */
+ struct fs_ops *f_ops; /* pointer to file system operations */
+ void *f_fsdata; /* file system specific data */
+ off_t f_offset; /* current file offset */
+ char *f_rabuf; /* readahead buffer pointer */
+ size_t f_ralen; /* valid data in readahead buffer */
+ off_t f_raoffset; /* consumer offset in readahead buffer */
+#define SOPEN_RASIZE 512
+};
+
+#define SOPEN_MAX 64
+extern struct open_file files[];
+
+/* f_flags values */
+#define F_READ 0x0001 /* file opened for reading */
+#define F_WRITE 0x0002 /* file opened for writing */
+#define F_RAW 0x0004 /* raw device open - no file system */
+#define F_NODEV 0x0008 /* network open - no device */
+#define F_GZIP 0x0010 /* file is compressed by gzip */
+#define F_BZIP 0x0020 /* file is compressed by bzip */
+
+#define isascii(c) (((c) & ~0x7F) == 0)
+
+static __inline int isupper(int c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static __inline int islower(int c)
+{
+ return c >= 'a' && c <= 'z';
+}
+
+static __inline int isspace(int c)
+{
+ return c == ' ' || (c >= 0x9 && c <= 0xd);
+}
+
+static __inline int isdigit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static __inline int isxdigit(int c)
+{
+ return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static __inline int isalpha(int c)
+{
+ return isupper(c) || islower(c);
+}
+
+static __inline int isalnum(int c)
+{
+ return isalpha(c) || isdigit(c);
+}
+
+static __inline int toupper(int c)
+{
+ return islower(c) ? c - 'a' + 'A' : c;
+}
+
+static __inline int tolower(int c)
+{
+ return isupper(c) ? c - 'A' + 'a' : c;
+}
+
+/* sbrk emulation */
+extern void setheap(void *base, void *top);
+extern char *sbrk(int incr);
+
+/* Matt Dillon's zalloc/zmalloc */
+extern void *malloc(size_t bytes);
+extern void free(void *ptr);
+/*#define free(p) {CHK("free %p", p); free(p);} */ /* use for catching guard violations */
+extern void *calloc(size_t n1, size_t n2);
+extern void *realloc(void *ptr, size_t size);
+extern void *reallocf(void *ptr, size_t size);
+extern void mallocstats(void);
+
+extern int printf(const char *fmt, ...) __printflike(1, 2);
+extern void vprintf(const char *fmt, __va_list);
+extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3);
+extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4);
+extern void vsprintf(char *buf, const char *cfmt, __va_list);
+extern void vsnprintf(char *buf, size_t size, const char *cfmt, __va_list);
+
+extern void twiddle(u_int callerdiv);
+extern void twiddle_divisor(u_int globaldiv);
+
+extern void ngets(char *, int);
+#define gets(x) ngets((x), 0)
+extern int fgetstr(char *buf, int size, int fd);
+
+extern int open(const char *, int);
+#define O_RDONLY 0x0
+#define O_WRONLY 0x1
+#define O_RDWR 0x2
+extern int close(int);
+extern void closeall(void);
+extern ssize_t read(int, void *, size_t);
+extern ssize_t write(int, void *, size_t);
+extern struct dirent *readdirfd(int);
+
+extern void srandom(u_long seed);
+extern u_long random(void);
+
+/* imports from stdlib, locally modified */
+extern long strtol(const char *, char **, int);
+extern unsigned long strtoul(const char *, char **, int);
+extern char *optarg; /* getopt(3) external variables */
+extern int optind, opterr, optopt, optreset;
+extern int getopt(int, char * const [], const char *);
+
+/* pager.c */
+extern void pager_open(void);
+extern void pager_close(void);
+extern int pager_output(const char *lines);
+extern int pager_file(const char *fname);
+
+/* No signal state to preserve */
+#define setjmp _setjmp
+#define longjmp _longjmp
+
+/* environment.c */
+#define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */
+#define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */
+#define EV_NOHOOK (1<<2) /* don't call hook when setting */
+
+struct env_var;
+typedef char *(ev_format_t)(struct env_var *ev);
+typedef int (ev_sethook_t)(struct env_var *ev, int flags,
+ const void *value);
+typedef int (ev_unsethook_t)(struct env_var *ev);
+
+struct env_var
+{
+ char *ev_name;
+ int ev_flags;
+ void *ev_value;
+ ev_sethook_t *ev_sethook;
+ ev_unsethook_t *ev_unsethook;
+ struct env_var *ev_next, *ev_prev;
+};
+extern struct env_var *environ;
+
+extern struct env_var *env_getenv(const char *name);
+extern int env_setenv(const char *name, int flags,
+ const void *value, ev_sethook_t sethook,
+ ev_unsethook_t unsethook);
+extern char *getenv(const char *name);
+extern int setenv(const char *name, const char *value,
+ int overwrite);
+extern int putenv(const char *string);
+extern int unsetenv(const char *name);
+
+extern ev_sethook_t env_noset; /* refuse set operation */
+extern ev_unsethook_t env_nounset; /* refuse unset operation */
+
+/* BCD conversions (undocumented) */
+extern u_char const bcd2bin_data[];
+extern u_char const bin2bcd_data[];
+extern char const hex2ascii_data[];
+
+#define bcd2bin(bcd) (bcd2bin_data[bcd])
+#define bin2bcd(bin) (bin2bcd_data[bin])
+#define hex2ascii(hex) (hex2ascii_data[hex])
+
+/* min/max (undocumented) */
+static __inline int imax(int a, int b) { return (a > b ? a : b); }
+static __inline int imin(int a, int b) { return (a < b ? a : b); }
+static __inline long lmax(long a, long b) { return (a > b ? a : b); }
+static __inline long lmin(long a, long b) { return (a < b ? a : b); }
+static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
+static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
+static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); }
+static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); }
+static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); }
+static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
+
+/* swaps (undocumented, useful?) */
+#ifdef __i386__
+extern u_int32_t bswap32(u_int32_t x);
+extern u_int64_t bswap64(u_int64_t x);
+#endif
+
+/* null functions for device/filesystem switches (undocumented) */
+extern int nodev(void);
+extern int noioctl(struct open_file *, u_long, void *);
+extern void nullsys(void);
+
+extern int null_open(const char *path, struct open_file *f);
+extern int null_close(struct open_file *f);
+extern int null_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+extern int null_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+extern off_t null_seek(struct open_file *f, off_t offset, int where);
+extern int null_stat(struct open_file *f, struct stat *sb);
+extern int null_readdir(struct open_file *f, struct dirent *d);
+
+
+/*
+ * Machine dependent functions and data, must be provided or stubbed by
+ * the consumer
+ */
+extern int getchar(void);
+extern int ischar(void);
+extern void putchar(int);
+extern int devopen(struct open_file *, const char *, const char **);
+extern int devclose(struct open_file *f);
+extern void panic(const char *, ...) __dead2 __printflike(1, 2);
+extern struct fs_ops *file_system[];
+extern struct fs_ops *exclusive_file_system;
+extern struct devsw *devsw[];
+
+/*
+ * Expose byteorder(3) functions.
+ */
+#ifndef _BYTEORDER_PROTOTYPED
+#define _BYTEORDER_PROTOTYPED
+extern uint32_t htonl(uint32_t);
+extern uint16_t htons(uint16_t);
+extern uint32_t ntohl(uint32_t);
+extern uint16_t ntohs(uint16_t);
+#endif
+
+#ifndef _BYTEORDER_FUNC_DEFINED
+#define _BYTEORDER_FUNC_DEFINED
+#define htonl(x) __htonl(x)
+#define htons(x) __htons(x)
+#define ntohl(x) __ntohl(x)
+#define ntohs(x) __ntohs(x)
+#endif
+
+void *Malloc(size_t, const char *, int);
+void *Calloc(size_t, size_t, const char *, int);
+void *Realloc(void *, size_t, const char *, int);
+void Free(void *, const char *, int);
+
+#if 1
+#define malloc(x) Malloc(x, __FILE__, __LINE__)
+#define calloc(x, y) Calloc(x, y, __FILE__, __LINE__)
+#define free(x) Free(x, __FILE__, __LINE__)
+#define realloc(x, y) Realloc(x, y, __FILE__, __LINE__)
+#else
+#define malloc(x) Malloc(x, NULL, 0)
+#define calloc(x, y) Calloc(x, y, NULL, 0)
+#define free(x) Free(x, NULL, 0)
+#define realloc(x, y) Realloc(x, y, NULL, 0)
+#endif
+
+#endif /* STAND_H */
diff --git a/usr/src/boot/lib/libstand/stat.c b/usr/src/boot/lib/libstand/stat.c
new file mode 100644
index 0000000000..addee5d2f4
--- /dev/null
+++ b/usr/src/boot/lib/libstand/stat.c
@@ -0,0 +1,52 @@
+/* $NetBSD: stat.c,v 1.4 1996/01/13 22:25:43 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stat.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+int
+stat(str, sb)
+ const char *str;
+ struct stat *sb;
+{
+ int fd, rv;
+
+ fd = open(str, O_RDONLY);
+ if (fd < 0)
+ return (-1);
+ rv = fstat(fd, sb);
+ (void)close(fd);
+ return (rv);
+}
diff --git a/usr/src/boot/lib/libstand/strcasecmp.c b/usr/src/boot/lib/libstand/strcasecmp.c
new file mode 100644
index 0000000000..7ef3f59d9d
--- /dev/null
+++ b/usr/src/boot/lib/libstand/strcasecmp.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/cdefs.h>
+#include <string.h>
+#include "stand.h"
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (tolower(*us1) - tolower(*--us2));
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ size_t n;
+{
+ if (n != 0) {
+ const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if (tolower(*us1) != tolower(*us2++))
+ return (tolower(*us1) - tolower(*--us2));
+ if (*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/strdup.c b/usr/src/boot/lib/libstand/strdup.c
new file mode 100644
index 0000000000..45a541432c
--- /dev/null
+++ b/usr/src/boot/lib/libstand/strdup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <stddef.h>
+#include <string.h>
+
+char *
+strdup(str)
+ const char *str;
+{
+ size_t len;
+ char *copy = NULL;
+
+ if (str != NULL) {
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ }
+ return (copy);
+}
diff --git a/usr/src/boot/lib/libstand/strerror.c b/usr/src/boot/lib/libstand/strerror.c
new file mode 100644
index 0000000000..56571efaa0
--- /dev/null
+++ b/usr/src/boot/lib/libstand/strerror.c
@@ -0,0 +1,87 @@
+/* $NetBSD: strerror.c,v 1.12 1997/01/25 00:37:50 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+
+static struct
+{
+ int err;
+ char *msg;
+} errtab[] = {
+ {0, "no error"},
+ /* standard errors */
+ {EPERM, "operation not permitted"},
+ {ENOENT, "no such file or directory"},
+ {EIO, "input/output error"},
+ {ENXIO, "device not configured"},
+ {ENOEXEC, "exec format error"},
+ {EBADF, "bad file descriptor"},
+ {ENOMEM, "cannot allocate memory"},
+ {ENODEV, "operation not supported by device"},
+ {ENOTDIR, "not a directory"},
+ {EISDIR, "is a directory"},
+ {EINVAL, "invalid argument"},
+ {EMFILE, "too many open files"},
+ {EFBIG, "file too large"},
+ {EROFS, "read-only filesystem"},
+ {EOPNOTSUPP, "operation not supported"},
+ {ETIMEDOUT, "operation timed out"},
+ {ESTALE, "stale NFS file handle"},
+ {EBADRPC, "RPC struct is bad"},
+ {EFTYPE, "inappropriate file type or format"},
+
+ {EADAPT, "bad adaptor number"},
+ {ECTLR, "bad controller number"},
+ {EUNIT, "bad unit number"},
+ {ESLICE, "bad slice number"},
+ {EPART, "bad partition"},
+ {ERDLAB, "can't read disk label"},
+ {EUNLAB, "disk unlabelled"},
+ {EOFFSET, "illegal seek"},
+ {0, NULL}
+};
+
+
+char *
+strerror(int err)
+{
+ static char msg[32];
+ int i;
+
+ for (i = 0; errtab[i].msg != NULL; i++)
+ if (errtab[i].err == err)
+ return(errtab[i].msg);
+ sprintf(msg, "unknown error (%d)", err);
+ return(msg);
+}
diff --git a/usr/src/boot/lib/libstand/strtol.c b/usr/src/boot/lib/libstand/strtol.c
new file mode 100644
index 0000000000..ec5daf0bb8
--- /dev/null
+++ b/usr/src/boot/lib/libstand/strtol.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <limits.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ int base;
+{
+ const char *s;
+ unsigned long acc;
+ unsigned char c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /* Be sensible about NULL strings */
+ if (nptr == NULL)
+ nptr = "";
+ s = nptr;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/usr/src/boot/lib/libstand/strtoul.c b/usr/src/boot/lib/libstand/strtoul.c
new file mode 100644
index 0000000000..5735d20d25
--- /dev/null
+++ b/usr/src/boot/lib/libstand/strtoul.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+#include <limits.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ const char *s;
+ unsigned long acc;
+ char c;
+ unsigned long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ cutoff = ULONG_MAX / base;
+ cutlim = ULONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/usr/src/boot/lib/libstand/tftp.c b/usr/src/boot/lib/libstand/tftp.c
new file mode 100644
index 0000000000..cb84970910
--- /dev/null
+++ b/usr/src/boot/lib/libstand/tftp.c
@@ -0,0 +1,763 @@
+/* $NetBSD: tftp.c,v 1.4 1997/09/17 16:57:07 drochner Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Simple TFTP implementation for libsa.
+ * Assumes:
+ * - socket descriptor (int) at open_file->f_devdata
+ * - server host IP in global servip
+ * Restrictions:
+ * - read only
+ * - lseek only with SEEK_SET or SEEK_CUR
+ * - no big time differences between transfers (<tftp timeout)
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+#include <netinet/in_systm.h>
+#include <arpa/tftp.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+#include "tftp.h"
+
+struct tftp_handle;
+
+static int tftp_open(const char *path, struct open_file *f);
+static int tftp_close(struct open_file *f);
+static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len);
+static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int tftp_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t tftp_seek(struct open_file *f, off_t offset, int where);
+static int tftp_set_blksize(struct tftp_handle *h, const char *str);
+static int tftp_stat(struct open_file *f, struct stat *sb);
+static ssize_t sendrecv_tftp(struct tftp_handle *h,
+ ssize_t (*sproc)(struct iodesc *, void *, size_t),
+ void *sbuf, size_t ssize,
+ ssize_t (*rproc)(struct tftp_handle *h, void *, ssize_t, time_t, unsigned short *),
+ void *rbuf, size_t rsize, unsigned short *rtype);
+
+struct fs_ops tftp_fsops = {
+ "tftp",
+ tftp_open,
+ tftp_close,
+ tftp_read,
+ tftp_write,
+ tftp_seek,
+ tftp_stat,
+ null_readdir
+};
+
+extern struct in_addr servip;
+
+static int tftpport = 2000;
+static int is_open = 0;
+
+/*
+ * The legacy TFTP_BLKSIZE value was SEGSIZE(512).
+ * TFTP_REQUESTED_BLKSIZE of 1428 is (Ethernet MTU, less the TFTP, UDP and
+ * IP header lengths).
+ */
+#define TFTP_REQUESTED_BLKSIZE 1428
+
+/*
+ * Choose a blksize big enough so we can test with Ethernet
+ * Jumbo frames in the future.
+ */
+#define TFTP_MAX_BLKSIZE 9008
+
+struct tftp_handle {
+ struct iodesc *iodesc;
+ int currblock; /* contents of lastdata */
+ int islastblock; /* flag */
+ int validsize;
+ int off;
+ char *path; /* saved for re-requests */
+ unsigned int tftp_blksize;
+ unsigned long tftp_tsize;
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ u_char space[TFTP_MAX_BLKSIZE];
+ } __packed __aligned(4) lastdata;
+};
+
+#define TFTP_MAX_ERRCODE EOPTNEG
+static const int tftperrors[TFTP_MAX_ERRCODE + 1] = {
+ 0, /* ??? */
+ ENOENT,
+ EPERM,
+ ENOSPC,
+ EINVAL, /* ??? */
+ EINVAL, /* ??? */
+ EEXIST,
+ EINVAL, /* ??? */
+ EINVAL, /* Option negotiation failed. */
+};
+
+static int tftp_getnextblock(struct tftp_handle *h);
+
+/* send error message back. */
+static void
+tftp_senderr(struct tftp_handle *h, u_short errcode, const char *msg)
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ u_char space[63]; /* +1 from t */
+ } __packed __aligned(4) wbuf;
+ char *wtail;
+ int len;
+
+ len = strlen(msg);
+ if (len > sizeof(wbuf.space))
+ len = sizeof(wbuf.space);
+
+ wbuf.t.th_opcode = htons((u_short) ERROR);
+ wbuf.t.th_code = htons(errcode);
+
+ wtail = wbuf.t.th_msg;
+ bcopy(msg, wtail, len);
+ wtail[len] = '\0';
+ wtail += len + 1;
+
+ sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t);
+}
+
+static void
+tftp_sendack(struct tftp_handle *h)
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ } __packed __aligned(4) wbuf;
+ char *wtail;
+
+ wbuf.t.th_opcode = htons((u_short) ACK);
+ wtail = (char *) &wbuf.t.th_block;
+ wbuf.t.th_block = htons((u_short) h->currblock);
+ wtail += 2;
+
+ sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t);
+}
+
+static ssize_t
+recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
+ unsigned short *rtype)
+{
+ struct iodesc *d = h->iodesc;
+ struct tftphdr *t;
+
+ errno = 0;
+
+ len = readudp(d, pkt, len, tleft);
+
+ if (len < 4)
+ return (-1);
+
+ t = (struct tftphdr *) pkt;
+ *rtype = ntohs(t->th_opcode);
+ switch (ntohs(t->th_opcode)) {
+ case DATA: {
+ int got;
+
+ if (htons(t->th_block) != (u_short) d->xid) {
+ /*
+ * Expected block?
+ */
+ return (-1);
+ }
+ if (d->xid == 1) {
+ /*
+ * First data packet from new port.
+ */
+ struct udphdr *uh;
+ uh = (struct udphdr *) pkt - 1;
+ d->destport = uh->uh_sport;
+ } /* else check uh_sport has not changed??? */
+ got = len - (t->th_data - (char *) t);
+ return got;
+ }
+ case ERROR:
+ if ((unsigned) ntohs(t->th_code) > TFTP_MAX_ERRCODE) {
+ printf("illegal tftp error %d\n", ntohs(t->th_code));
+ errno = EIO;
+ } else {
+#ifdef TFTP_DEBUG
+ printf("tftp-error %d\n", ntohs(t->th_code));
+#endif
+ errno = tftperrors[ntohs(t->th_code)];
+ }
+ return (-1);
+ case OACK: {
+ struct udphdr *uh;
+ int tftp_oack_len;
+
+ /*
+ * Unexpected OACK. TFTP transfer already in progress.
+ * Drop the pkt.
+ */
+ if (d->xid != 1) {
+ return (-1);
+ }
+
+ /*
+ * Remember which port this OACK came from, because we need
+ * to send the ACK or errors back to it.
+ */
+ uh = (struct udphdr *) pkt - 1;
+ d->destport = uh->uh_sport;
+
+ /* Parse options ACK-ed by the server. */
+ tftp_oack_len = len - sizeof(t->th_opcode);
+ if (tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len) != 0) {
+ tftp_senderr(h, EOPTNEG, "Malformed OACK");
+ errno = EIO;
+ return (-1);
+ }
+ return (0);
+ }
+ default:
+#ifdef TFTP_DEBUG
+ printf("tftp type %d not handled\n", ntohs(t->th_opcode));
+#endif
+ return (-1);
+ }
+}
+
+/* send request, expect first block (or error) */
+static int
+tftp_makereq(struct tftp_handle *h)
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ u_char space[FNAME_SIZE + 6];
+ } __packed __aligned(4) wbuf;
+ char *wtail;
+ int l;
+ ssize_t res;
+ struct tftphdr *t;
+ char *tftp_blksize = NULL;
+ int blksize_l;
+ unsigned short rtype = 0;
+
+ /*
+ * Allow overriding default TFTP block size by setting
+ * a tftp.blksize environment variable.
+ */
+ if ((tftp_blksize = getenv("tftp.blksize")) != NULL) {
+ tftp_set_blksize(h, tftp_blksize);
+ }
+
+ wbuf.t.th_opcode = htons((u_short) RRQ);
+ wtail = wbuf.t.th_stuff;
+ l = strlen(h->path);
+#ifdef TFTP_PREPEND_PATH
+ if (l > FNAME_SIZE - (sizeof(TFTP_PREPEND_PATH) - 1))
+ return (ENAMETOOLONG);
+ bcopy(TFTP_PREPEND_PATH, wtail, sizeof(TFTP_PREPEND_PATH) - 1);
+ wtail += sizeof(TFTP_PREPEND_PATH) - 1;
+#else
+ if (l > FNAME_SIZE)
+ return (ENAMETOOLONG);
+#endif
+ bcopy(h->path, wtail, l + 1);
+ wtail += l + 1;
+ bcopy("octet", wtail, 6);
+ wtail += 6;
+ bcopy("blksize", wtail, 8);
+ wtail += 8;
+ blksize_l = sprintf(wtail, "%d", h->tftp_blksize);
+ wtail += blksize_l + 1;
+ bcopy("tsize", wtail, 6);
+ wtail += 6;
+ bcopy("0", wtail, 2);
+ wtail += 2;
+
+ t = &h->lastdata.t;
+
+ /* h->iodesc->myport = htons(--tftpport); */
+ h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
+ h->iodesc->destport = htons(IPPORT_TFTP);
+ h->iodesc->xid = 1; /* expected block */
+
+ h->currblock = 0;
+ h->islastblock = 0;
+ h->validsize = 0;
+
+ res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+ &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype);
+
+ if (rtype == OACK)
+ return (tftp_getnextblock(h));
+
+ /* Server ignored our blksize request, revert to TFTP default. */
+ h->tftp_blksize = SEGSIZE;
+
+ switch (rtype) {
+ case DATA: {
+ h->currblock = 1;
+ h->validsize = res;
+ h->islastblock = 0;
+ if (res < h->tftp_blksize) {
+ h->islastblock = 1; /* very short file */
+ tftp_sendack(h);
+ }
+ return (0);
+ }
+ case ERROR:
+ default:
+ return (errno);
+ }
+
+}
+
+/* ack block, expect next */
+static int
+tftp_getnextblock(struct tftp_handle *h)
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ } __packed __aligned(4) wbuf;
+ char *wtail;
+ int res;
+ struct tftphdr *t;
+ unsigned short rtype = 0;
+ wbuf.t.th_opcode = htons((u_short) ACK);
+ wtail = (char *) &wbuf.t.th_block;
+ wbuf.t.th_block = htons((u_short) h->currblock);
+ wtail += 2;
+
+ t = &h->lastdata.t;
+
+ h->iodesc->xid = h->currblock + 1; /* expected block */
+
+ res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+ &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype);
+
+ if (res == -1) /* 0 is OK! */
+ return (errno);
+
+ h->currblock++;
+ h->validsize = res;
+ if (res < h->tftp_blksize)
+ h->islastblock = 1; /* EOF */
+
+ if (h->islastblock == 1) {
+ /* Send an ACK for the last block */
+ wbuf.t.th_block = htons((u_short) h->currblock);
+ sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t);
+ }
+
+ return (0);
+}
+
+static int
+tftp_open(const char *path, struct open_file *f)
+{
+ struct tftp_handle *tftpfile;
+ struct iodesc *io;
+ int res;
+ size_t pathsize;
+ const char *extraslash;
+
+ if (strcmp(f->f_dev->dv_name, "net") != 0) {
+#ifdef __i386__
+ if (strcmp(f->f_dev->dv_name, "pxe") != 0)
+ return (EINVAL);
+#else
+ return (EINVAL);
+#endif
+ }
+
+ if (is_open)
+ return (EBUSY);
+
+ tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile));
+ if (!tftpfile)
+ return (ENOMEM);
+
+ memset(tftpfile, 0, sizeof(*tftpfile));
+ tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE;
+ tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata));
+ if (io == NULL)
+ return (EINVAL);
+
+ io->destip = servip;
+ tftpfile->off = 0;
+ pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof(char);
+ tftpfile->path = malloc(pathsize);
+ if (tftpfile->path == NULL) {
+ free(tftpfile);
+ return(ENOMEM);
+ }
+ if (rootpath[strlen(rootpath) - 1] == '/' || path[0] == '/')
+ extraslash = "";
+ else
+ extraslash = "/";
+ res = snprintf(tftpfile->path, pathsize, "%s%s%s",
+ rootpath, extraslash, path);
+ if (res < 0 || res > pathsize) {
+ free(tftpfile->path);
+ free(tftpfile);
+ return(ENOMEM);
+ }
+
+ res = tftp_makereq(tftpfile);
+
+ if (res) {
+ free(tftpfile->path);
+ free(tftpfile);
+ return (res);
+ }
+ f->f_fsdata = (void *) tftpfile;
+ is_open = 1;
+ return (0);
+}
+
+static int
+tftp_read(struct open_file *f, void *addr, size_t size,
+ size_t *resid /* out */)
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ while (size > 0) {
+ int needblock, count;
+
+ twiddle(32);
+
+ needblock = tftpfile->off / tftpfile->tftp_blksize + 1;
+
+ if (tftpfile->currblock > needblock) { /* seek backwards */
+ tftp_senderr(tftpfile, 0, "No error: read aborted");
+ tftp_makereq(tftpfile); /* no error check, it worked
+ * for open */
+ }
+
+ while (tftpfile->currblock < needblock) {
+ int res;
+
+ res = tftp_getnextblock(tftpfile);
+ if (res) { /* no answer */
+#ifdef TFTP_DEBUG
+ printf("tftp: read error\n");
+#endif
+ return (res);
+ }
+ if (tftpfile->islastblock)
+ break;
+ }
+
+ if (tftpfile->currblock == needblock) {
+ int offinblock, inbuffer;
+
+ offinblock = tftpfile->off % tftpfile->tftp_blksize;
+
+ inbuffer = tftpfile->validsize - offinblock;
+ if (inbuffer < 0) {
+#ifdef TFTP_DEBUG
+ printf("tftp: invalid offset %d\n",
+ tftpfile->off);
+#endif
+ return (EINVAL);
+ }
+ count = (size < inbuffer ? size : inbuffer);
+ bcopy(tftpfile->lastdata.t.th_data + offinblock,
+ addr, count);
+
+ addr = (char *)addr + count;
+ tftpfile->off += count;
+ size -= count;
+
+ if ((tftpfile->islastblock) && (count == inbuffer))
+ break; /* EOF */
+ } else {
+#ifdef TFTP_DEBUG
+ printf("tftp: block %d not found\n", needblock);
+#endif
+ return (EINVAL);
+ }
+
+ }
+
+ if (resid)
+ *resid = size;
+ return (0);
+}
+
+static int
+tftp_close(struct open_file *f)
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ /* let it time out ... */
+
+ if (tftpfile) {
+ free(tftpfile->path);
+ free(tftpfile);
+ }
+ is_open = 0;
+ return (0);
+}
+
+static int
+tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused,
+ size_t *resid __unused /* out */)
+{
+ return (EROFS);
+}
+
+static int
+tftp_stat(struct open_file *f, struct stat *sb)
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ sb->st_mode = 0444 | S_IFREG;
+ sb->st_nlink = 1;
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ sb->st_size = (off_t) tftpfile->tftp_tsize;
+ return (0);
+}
+
+static off_t
+tftp_seek(struct open_file *f, off_t offset, int where)
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ tftpfile->off = offset;
+ break;
+ case SEEK_CUR:
+ tftpfile->off += offset;
+ break;
+ default:
+ errno = EOFFSET;
+ return (-1);
+ }
+ return (tftpfile->off);
+}
+
+static ssize_t
+sendrecv_tftp(struct tftp_handle *h,
+ ssize_t (*sproc)(struct iodesc *, void *, size_t),
+ void *sbuf, size_t ssize,
+ ssize_t (*rproc)(struct tftp_handle *, void *, ssize_t, time_t, unsigned short *),
+ void *rbuf, size_t rsize, unsigned short *rtype)
+{
+ struct iodesc *d = h->iodesc;
+ ssize_t cc;
+ time_t t, t1, tleft;
+
+#ifdef TFTP_DEBUG
+ if (debug)
+ printf("sendrecv: called\n");
+#endif
+
+ tleft = MINTMO;
+ t = t1 = getsecs();
+ for (;;) {
+ if ((getsecs() - t) > MAXTMO) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ cc = (*sproc)(d, sbuf, ssize);
+ if (cc != -1 && cc < ssize)
+ panic("sendrecv: short write! (%zd < %zu)",
+ cc, ssize);
+
+ if (cc == -1) {
+ /* Error on transmit; wait before retrying */
+ while ((getsecs() - t1) < tleft);
+ continue;
+ }
+
+recvnext:
+ /* Try to get a packet and process it. */
+ cc = (*rproc)(h, rbuf, rsize, tleft, rtype);
+ /* Return on data, EOF or real error. */
+ if (cc != -1 || errno != 0)
+ return (cc);
+ if ((getsecs() - t1) < tleft) {
+ goto recvnext;
+ }
+
+ /* Timed out or didn't get the packet we're waiting for */
+ tleft += MINTMO;
+ if (tleft > (2 * MINTMO)) {
+ tleft = (2 * MINTMO);
+ }
+ t1 = getsecs();
+ }
+}
+
+static int
+tftp_set_blksize(struct tftp_handle *h, const char *str)
+{
+ char *endptr;
+ int new_blksize;
+ int ret = 0;
+
+ if (h == NULL || str == NULL)
+ return (ret);
+
+ new_blksize =
+ (unsigned int)strtol(str, &endptr, 0);
+
+ /*
+ * Only accept blksize value if it is numeric.
+ * RFC2348 specifies that acceptable values are 8-65464.
+ * Let's choose a limit less than MAXRSPACE.
+ */
+ if (*endptr == '\0' && new_blksize >= 8
+ && new_blksize <= TFTP_MAX_BLKSIZE) {
+ h->tftp_blksize = new_blksize;
+ ret = 1;
+ }
+
+ return (ret);
+}
+
+/*
+ * In RFC2347, the TFTP Option Acknowledgement package (OACK)
+ * is used to acknowledge a client's option negotiation request.
+ * The format of an OACK packet is:
+ * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+ * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 |
+ * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+ *
+ * opc
+ * The opcode field contains a 6, for Option Acknowledgment.
+ *
+ * opt1
+ * The first option acknowledgment, copied from the original
+ * request.
+ *
+ * value1
+ * The acknowledged value associated with the first option. If
+ * and how this value may differ from the original request is
+ * detailed in the specification for the option.
+ *
+ * optN, valueN
+ * The final option/value acknowledgment pair.
+ */
+static int
+tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len)
+{
+ /*
+ * We parse the OACK strings into an array
+ * of name-value pairs.
+ */
+ char *tftp_options[128] = { 0 };
+ char *val = buf;
+ int i = 0;
+ int option_idx = 0;
+ int blksize_is_set = 0;
+ int tsize = 0;
+
+ unsigned int orig_blksize;
+
+ while (option_idx < 128 && i < len) {
+ if (buf[i] == '\0') {
+ if (&buf[i] > val) {
+ tftp_options[option_idx] = val;
+ val = &buf[i] + 1;
+ ++option_idx;
+ }
+ }
+ ++i;
+ }
+
+ /* Save the block size we requested for sanity check later. */
+ orig_blksize = h->tftp_blksize;
+
+ /*
+ * Parse individual TFTP options.
+ * * "blksize" is specified in RFC2348.
+ * * "tsize" is specified in RFC2349.
+ */
+ for (i = 0; i < option_idx; i += 2) {
+ if (strcasecmp(tftp_options[i], "blksize") == 0) {
+ if (i + 1 < option_idx)
+ blksize_is_set =
+ tftp_set_blksize(h, tftp_options[i + 1]);
+ } else if (strcasecmp(tftp_options[i], "tsize") == 0) {
+ if (i + 1 < option_idx)
+ tsize = strtol(tftp_options[i + 1], (char **)NULL, 10);
+ if (tsize != 0)
+ h->tftp_tsize = tsize;
+ } else {
+ /* Do not allow any options we did not expect to be ACKed. */
+ printf("unexpected tftp option '%s'\n", tftp_options[i]);
+ return (-1);
+ }
+ }
+
+ if (!blksize_is_set) {
+ /*
+ * If TFTP blksize was not set, try defaulting
+ * to the legacy TFTP blksize of SEGSIZE(512)
+ */
+ h->tftp_blksize = SEGSIZE;
+ } else if (h->tftp_blksize > orig_blksize) {
+ /*
+ * Server should not be proposing block sizes that
+ * exceed what we said we can handle.
+ */
+ printf("unexpected blksize %u\n", h->tftp_blksize);
+ return (-1);
+ }
+
+#ifdef TFTP_DEBUG
+ printf("tftp_blksize: %u\n", h->tftp_blksize);
+ printf("tftp_tsize: %lu\n", h->tftp_tsize);
+#endif
+ return 0;
+}
diff --git a/usr/src/boot/lib/libstand/tftp.h b/usr/src/boot/lib/libstand/tftp.h
new file mode 100644
index 0000000000..cbbbbd7821
--- /dev/null
+++ b/usr/src/boot/lib/libstand/tftp.h
@@ -0,0 +1,36 @@
+/* $NetBSD: tftp.h,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+
+#define IPPORT_TFTP 69
diff --git a/usr/src/boot/lib/libstand/twiddle.c b/usr/src/boot/lib/libstand/twiddle.c
new file mode 100644
index 0000000000..96ebbbec43
--- /dev/null
+++ b/usr/src/boot/lib/libstand/twiddle.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include "stand.h"
+
+/* Extra functions from NetBSD standalone printf.c */
+
+static u_int globaldiv;
+
+void
+twiddle(u_int callerdiv)
+{
+ static u_int callercnt, globalcnt, pos;
+
+ callercnt++;
+ if (callerdiv > 1 && (callercnt % callerdiv) != 0)
+ return;
+
+ globalcnt++;
+ if (globaldiv > 1 && (globalcnt % globaldiv) != 0)
+ return;
+
+ putchar("|/-\\"[pos++ & 3]);
+ putchar('\b');
+}
+
+void
+twiddle_divisor(u_int gdiv)
+{
+
+ globaldiv = gdiv;
+}
diff --git a/usr/src/boot/lib/libstand/udp.c b/usr/src/boot/lib/libstand/udp.c
new file mode 100644
index 0000000000..d41be902a3
--- /dev/null
+++ b/usr/src/boot/lib/libstand/udp.c
@@ -0,0 +1,272 @@
+/* Taken from $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <string.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <netinet/in_pcb.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include "stand.h"
+#include "net.h"
+
+/* Caller must leave room for ethernet, ip and udp headers in front!! */
+ssize_t
+sendudp(d, pkt, len)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+{
+ ssize_t cc;
+ struct ip *ip;
+ struct udphdr *uh;
+ u_char *ea;
+
+#ifdef NET_DEBUG
+ if (debug) {
+ printf("sendudp: d=%lx called.\n", (long)d);
+ if (d) {
+ printf("saddr: %s:%d",
+ inet_ntoa(d->myip), ntohs(d->myport));
+ printf(" daddr: %s:%d\n",
+ inet_ntoa(d->destip), ntohs(d->destport));
+ }
+ }
+#endif
+
+ uh = (struct udphdr *)pkt - 1;
+ ip = (struct ip *)uh - 1;
+ len += sizeof(*ip) + sizeof(*uh);
+
+ bzero(ip, sizeof(*ip) + sizeof(*uh));
+
+ ip->ip_v = IPVERSION; /* half-char */
+ ip->ip_hl = sizeof(*ip) >> 2; /* half-char */
+ ip->ip_len = htons(len);
+ ip->ip_p = IPPROTO_UDP; /* char */
+ ip->ip_ttl = IPDEFTTL; /* char */
+ ip->ip_src = d->myip;
+ ip->ip_dst = d->destip;
+ ip->ip_sum = in_cksum(ip, sizeof(*ip)); /* short, but special */
+
+ uh->uh_sport = d->myport;
+ uh->uh_dport = d->destport;
+ uh->uh_ulen = htons(len - sizeof(*ip));
+
+#ifndef UDP_NO_CKSUM
+ {
+ struct udpiphdr *ui;
+ struct ip tip;
+
+ /* Calculate checksum (must save and restore ip header) */
+ tip = *ip;
+ ui = (struct udpiphdr *)ip;
+ bzero(&ui->ui_x1, sizeof(ui->ui_x1));
+ ui->ui_len = uh->uh_ulen;
+ uh->uh_sum = in_cksum(ui, len);
+ *ip = tip;
+ }
+#endif
+
+ if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
+ netmask == 0 || SAMENET(ip->ip_src, ip->ip_dst, netmask))
+ ea = arpwhohas(d, ip->ip_dst);
+ else
+ ea = arpwhohas(d, gateip);
+
+ cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
+ if (cc == -1)
+ return (-1);
+ if (cc != len)
+ panic("sendudp: bad write (%zd != %zd)", cc, len);
+ return (cc - (sizeof(*ip) + sizeof(*uh)));
+}
+
+/*
+ * Receive a UDP packet and validate it is for us.
+ * Caller leaves room for the headers (Ether, IP, UDP)
+ */
+ssize_t
+readudp(d, pkt, len, tleft)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ time_t tleft;
+{
+ ssize_t n;
+ size_t hlen;
+ struct ip *ip;
+ struct udphdr *uh;
+ u_int16_t etype; /* host order */
+
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: called\n");
+#endif
+
+ uh = (struct udphdr *)pkt - 1;
+ ip = (struct ip *)uh - 1;
+
+ n = readether(d, ip, len + sizeof(*ip) + sizeof(*uh), tleft, &etype);
+ if (n == -1 || n < sizeof(*ip) + sizeof(*uh))
+ return -1;
+
+ /* Ethernet address checks now in readether() */
+
+ /* Need to respond to ARP requests. */
+ if (etype == ETHERTYPE_ARP) {
+ struct arphdr *ah = (void *)ip;
+ if (ah->ar_op == htons(ARPOP_REQUEST)) {
+ /* Send ARP reply */
+ arp_reply(d, ah);
+ }
+ return -1;
+ }
+
+ if (etype != ETHERTYPE_IP) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: not IP. ether_type=%x\n", etype);
+#endif
+ return -1;
+ }
+
+ /* Check ip header */
+ if (ip->ip_v != IPVERSION ||
+ ip->ip_p != IPPROTO_UDP) { /* half char */
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p);
+#endif
+ return -1;
+ }
+
+ hlen = ip->ip_hl << 2;
+ if (hlen < sizeof(*ip) ||
+ in_cksum(ip, hlen) != 0) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: short hdr or bad cksum.\n");
+#endif
+ return -1;
+ }
+ if (n < ntohs(ip->ip_len)) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad length %d < %d.\n",
+ (int)n, ntohs(ip->ip_len));
+#endif
+ return -1;
+ }
+ if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) {
+#ifdef NET_DEBUG
+ if (debug) {
+ printf("readudp: bad saddr %s != ", inet_ntoa(d->myip));
+ printf("%s\n", inet_ntoa(ip->ip_dst));
+ }
+#endif
+ return -1;
+ }
+
+ /* If there were ip options, make them go away */
+ if (hlen != sizeof(*ip)) {
+ bcopy(((u_char *)ip) + hlen, uh, len - hlen);
+ ip->ip_len = htons(sizeof(*ip));
+ n -= hlen - sizeof(*ip);
+ }
+ if (uh->uh_dport != d->myport) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad dport %d != %d\n",
+ d->myport, ntohs(uh->uh_dport));
+#endif
+ return -1;
+ }
+
+#ifndef UDP_NO_CKSUM
+ if (uh->uh_sum) {
+ struct udpiphdr *ui;
+ struct ip tip;
+
+ n = ntohs(uh->uh_ulen) + sizeof(*ip);
+ if (n > RECV_SIZE - ETHER_SIZE) {
+ printf("readudp: huge packet, udp len %d\n", (int)n);
+ return -1;
+ }
+
+ /* Check checksum (must save and restore ip header) */
+ tip = *ip;
+ ui = (struct udpiphdr *)ip;
+ bzero(&ui->ui_x1, sizeof(ui->ui_x1));
+ ui->ui_len = uh->uh_ulen;
+ if (in_cksum(ui, n) != 0) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad cksum\n");
+#endif
+ *ip = tip;
+ return -1;
+ }
+ *ip = tip;
+ }
+#endif
+ if (ntohs(uh->uh_ulen) < sizeof(*uh)) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad udp len %d < %d\n",
+ ntohs(uh->uh_ulen), (int)sizeof(*uh));
+#endif
+ return -1;
+ }
+
+ n = (n > (ntohs(uh->uh_ulen) - sizeof(*uh))) ?
+ ntohs(uh->uh_ulen) - sizeof(*uh) : n;
+ return (n);
+}
diff --git a/usr/src/boot/lib/libstand/ufs.c b/usr/src/boot/lib/libstand/ufs.c
new file mode 100644
index 0000000000..d0a096693d
--- /dev/null
+++ b/usr/src/boot/lib/libstand/ufs.c
@@ -0,0 +1,857 @@
+/* $NetBSD: ufs.c,v 1.20 1998/03/01 07:15:39 ross Exp $ */
+
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * Copyright (c) 1982, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ *
+ * Copyright (c) 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: David Golub
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Stand-alone file reading package.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/time.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+#include "stand.h"
+#include "string.h"
+
+static int ufs_open(const char *path, struct open_file *f);
+static int ufs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int ufs_close(struct open_file *f);
+static int ufs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t ufs_seek(struct open_file *f, off_t offset, int where);
+static int ufs_stat(struct open_file *f, struct stat *sb);
+static int ufs_readdir(struct open_file *f, struct dirent *d);
+
+struct fs_ops ufs_fsops = {
+ "ufs",
+ ufs_open,
+ ufs_close,
+ ufs_read,
+ ufs_write,
+ ufs_seek,
+ ufs_stat,
+ ufs_readdir
+};
+
+/*
+ * In-core open file.
+ */
+struct file {
+ off_t f_seekp; /* seek pointer */
+ struct fs *f_fs; /* pointer to super-block */
+ union dinode {
+ struct ufs1_dinode di1;
+ struct ufs2_dinode di2;
+ } f_di; /* copy of on-disk inode */
+ int f_nindir[NIADDR];
+ /* number of blocks mapped by
+ indirect block at level i */
+ char *f_blk[NIADDR]; /* buffer for indirect block at
+ level i */
+ size_t f_blksize[NIADDR];
+ /* size of buffer */
+ ufs2_daddr_t f_blkno[NIADDR];/* disk address of block in buffer */
+ ufs2_daddr_t f_buf_blkno; /* block number of data block */
+ char *f_buf; /* buffer for data block */
+ size_t f_buf_size; /* size of data block */
+};
+#define DIP(fp, field) \
+ ((fp)->f_fs->fs_magic == FS_UFS1_MAGIC ? \
+ (fp)->f_di.di1.field : (fp)->f_di.di2.field)
+
+static int read_inode(ino_t, struct open_file *);
+static int block_map(struct open_file *, ufs2_daddr_t, ufs2_daddr_t *);
+static int buf_read_file(struct open_file *, char **, size_t *);
+static int buf_write_file(struct open_file *, char *, size_t *);
+static int search_directory(char *, struct open_file *, ino_t *);
+
+/*
+ * Read a new inode into a file structure.
+ */
+static int
+read_inode(inumber, f)
+ ino_t inumber;
+ struct open_file *f;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct fs *fs = fp->f_fs;
+ char *buf;
+ size_t rsize;
+ int rc;
+
+ if (fs == NULL)
+ panic("fs == NULL");
+
+ /*
+ * Read inode and save it.
+ */
+ buf = malloc(fs->fs_bsize);
+ twiddle(1);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fs, ino_to_fsba(fs, inumber)), 0, fs->fs_bsize,
+ buf, &rsize);
+ if (rc)
+ goto out;
+ if (rsize != fs->fs_bsize) {
+ rc = EIO;
+ goto out;
+ }
+
+ if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
+ fp->f_di.di1 = ((struct ufs1_dinode *)buf)
+ [ino_to_fsbo(fs, inumber)];
+ else
+ fp->f_di.di2 = ((struct ufs2_dinode *)buf)
+ [ino_to_fsbo(fs, inumber)];
+
+ /*
+ * Clear out the old buffers
+ */
+ {
+ int level;
+
+ for (level = 0; level < NIADDR; level++)
+ fp->f_blkno[level] = -1;
+ fp->f_buf_blkno = -1;
+ }
+ fp->f_seekp = 0;
+out:
+ free(buf);
+ return (rc);
+}
+
+/*
+ * Given an offset in a file, find the disk block number that
+ * contains that block.
+ */
+static int
+block_map(f, file_block, disk_block_p)
+ struct open_file *f;
+ ufs2_daddr_t file_block;
+ ufs2_daddr_t *disk_block_p; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct fs *fs = fp->f_fs;
+ int level;
+ int idx;
+ ufs2_daddr_t ind_block_num;
+ int rc;
+
+ /*
+ * Index structure of an inode:
+ *
+ * di_db[0..NDADDR-1] hold block numbers for blocks
+ * 0..NDADDR-1
+ *
+ * di_ib[0] index block 0 is the single indirect block
+ * holds block numbers for blocks
+ * NDADDR .. NDADDR + NINDIR(fs)-1
+ *
+ * di_ib[1] index block 1 is the double indirect block
+ * holds block numbers for INDEX blocks for blocks
+ * NDADDR + NINDIR(fs) ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
+ *
+ * di_ib[2] index block 2 is the triple indirect block
+ * holds block numbers for double-indirect
+ * blocks for blocks
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2
+ * + NINDIR(fs)**3 - 1
+ */
+
+ if (file_block < NDADDR) {
+ /* Direct block. */
+ *disk_block_p = DIP(fp, di_db[file_block]);
+ return (0);
+ }
+
+ file_block -= NDADDR;
+
+ /*
+ * nindir[0] = NINDIR
+ * nindir[1] = NINDIR**2
+ * nindir[2] = NINDIR**3
+ * etc
+ */
+ for (level = 0; level < NIADDR; level++) {
+ if (file_block < fp->f_nindir[level])
+ break;
+ file_block -= fp->f_nindir[level];
+ }
+ if (level == NIADDR) {
+ /* Block number too high */
+ return (EFBIG);
+ }
+
+ ind_block_num = DIP(fp, di_ib[level]);
+
+ for (; level >= 0; level--) {
+ if (ind_block_num == 0) {
+ *disk_block_p = 0; /* missing */
+ return (0);
+ }
+
+ if (fp->f_blkno[level] != ind_block_num) {
+ if (fp->f_blk[level] == (char *)0)
+ fp->f_blk[level] =
+ malloc(fs->fs_bsize);
+ twiddle(1);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fp->f_fs, ind_block_num), 0,
+ fs->fs_bsize,
+ fp->f_blk[level],
+ &fp->f_blksize[level]);
+ if (rc)
+ return (rc);
+ if (fp->f_blksize[level] != fs->fs_bsize)
+ return (EIO);
+ fp->f_blkno[level] = ind_block_num;
+ }
+
+ if (level > 0) {
+ idx = file_block / fp->f_nindir[level - 1];
+ file_block %= fp->f_nindir[level - 1];
+ } else
+ idx = file_block;
+
+ if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
+ ind_block_num = ((ufs1_daddr_t *)fp->f_blk[level])[idx];
+ else
+ ind_block_num = ((ufs2_daddr_t *)fp->f_blk[level])[idx];
+ }
+
+ *disk_block_p = ind_block_num;
+
+ return (0);
+}
+
+/*
+ * Write a portion of a file from an internal buffer.
+ */
+static int
+buf_write_file(f, buf_p, size_p)
+ struct open_file *f;
+ char *buf_p;
+ size_t *size_p; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct fs *fs = fp->f_fs;
+ long off;
+ ufs_lbn_t file_block;
+ ufs2_daddr_t disk_block;
+ size_t block_size;
+ int rc;
+
+ /*
+ * Calculate the starting block address and offset.
+ */
+ off = blkoff(fs, fp->f_seekp);
+ file_block = lblkno(fs, fp->f_seekp);
+ block_size = sblksize(fs, DIP(fp, di_size), file_block);
+
+ rc = block_map(f, file_block, &disk_block);
+ if (rc)
+ return (rc);
+
+ if (disk_block == 0)
+ /* Because we can't allocate space on the drive */
+ return (EFBIG);
+
+ /*
+ * Truncate buffer at end of file, and at the end of
+ * this block.
+ */
+ if (*size_p > DIP(fp, di_size) - fp->f_seekp)
+ *size_p = DIP(fp, di_size) - fp->f_seekp;
+ if (*size_p > block_size - off)
+ *size_p = block_size - off;
+
+ /*
+ * If we don't entirely occlude the block and it's not
+ * in memory already, read it in first.
+ */
+ if (((off > 0) || (*size_p + off < block_size)) &&
+ (file_block != fp->f_buf_blkno)) {
+
+ if (fp->f_buf == (char *)0)
+ fp->f_buf = malloc(fs->fs_bsize);
+
+ twiddle(8);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fs, disk_block), 0,
+ block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+
+ fp->f_buf_blkno = file_block;
+ }
+
+ /*
+ * Copy the user data into the cached block.
+ */
+ bcopy(buf_p, fp->f_buf + off, *size_p);
+
+ /*
+ * Write the block out to storage.
+ */
+
+ twiddle(4);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
+ fsbtodb(fs, disk_block), 0,
+ block_size, fp->f_buf, &fp->f_buf_size);
+ return (rc);
+}
+
+/*
+ * Read a portion of a file into an internal buffer. Return
+ * the location in the buffer and the amount in the buffer.
+ */
+static int
+buf_read_file(f, buf_p, size_p)
+ struct open_file *f;
+ char **buf_p; /* out */
+ size_t *size_p; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct fs *fs = fp->f_fs;
+ long off;
+ ufs_lbn_t file_block;
+ ufs2_daddr_t disk_block;
+ size_t block_size;
+ int rc;
+
+ off = blkoff(fs, fp->f_seekp);
+ file_block = lblkno(fs, fp->f_seekp);
+ block_size = sblksize(fs, DIP(fp, di_size), file_block);
+
+ if (file_block != fp->f_buf_blkno) {
+ if (fp->f_buf == (char *)0)
+ fp->f_buf = malloc(fs->fs_bsize);
+
+ rc = block_map(f, file_block, &disk_block);
+ if (rc)
+ return (rc);
+
+ if (disk_block == 0) {
+ bzero(fp->f_buf, block_size);
+ fp->f_buf_size = block_size;
+ } else {
+ twiddle(4);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata,
+ F_READ, fsbtodb(fs, disk_block), 0,
+ block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+ }
+
+ fp->f_buf_blkno = file_block;
+ }
+
+ /*
+ * Return address of byte in buffer corresponding to
+ * offset, and size of remainder of buffer after that
+ * byte.
+ */
+ *buf_p = fp->f_buf + off;
+ *size_p = block_size - off;
+
+ /*
+ * But truncate buffer at end of file.
+ */
+ if (*size_p > DIP(fp, di_size) - fp->f_seekp)
+ *size_p = DIP(fp, di_size) - fp->f_seekp;
+
+ return (0);
+}
+
+/*
+ * Search a directory for a name and return its
+ * i_number.
+ */
+static int
+search_directory(name, f, inumber_p)
+ char *name;
+ struct open_file *f;
+ ino_t *inumber_p; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct direct *dp;
+ struct direct *edp;
+ char *buf;
+ size_t buf_size;
+ int namlen, length;
+ int rc;
+
+ length = strlen(name);
+
+ fp->f_seekp = 0;
+ while (fp->f_seekp < DIP(fp, di_size)) {
+ rc = buf_read_file(f, &buf, &buf_size);
+ if (rc)
+ return (rc);
+
+ dp = (struct direct *)buf;
+ edp = (struct direct *)(buf + buf_size);
+ while (dp < edp) {
+ if (dp->d_ino == (ino_t)0)
+ goto next;
+ namlen = dp->d_namlen;
+ if (namlen == length &&
+ !strcmp(name, dp->d_name)) {
+ /* found entry */
+ *inumber_p = dp->d_ino;
+ return (0);
+ }
+ next:
+ dp = (struct direct *)((char *)dp + dp->d_reclen);
+ }
+ fp->f_seekp += buf_size;
+ }
+ return (ENOENT);
+}
+
+static int sblock_try[] = SBLOCKSEARCH;
+
+/*
+ * Open a file.
+ */
+static int
+ufs_open(upath, f)
+ const char *upath;
+ struct open_file *f;
+{
+ char *cp, *ncp;
+ int c;
+ ino_t inumber, parent_inumber;
+ struct file *fp;
+ struct fs *fs;
+ int i, rc;
+ size_t buf_size;
+ int nlinks = 0;
+ char namebuf[MAXPATHLEN+1];
+ char *buf = NULL;
+ char *path = NULL;
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ /* allocate space and read super block */
+ fs = malloc(SBLOCKSIZE);
+ fp->f_fs = fs;
+ twiddle(1);
+ /*
+ * Try reading the superblock in each of its possible locations.
+ */
+ for (i = 0; sblock_try[i] != -1; i++) {
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ sblock_try[i] / DEV_BSIZE, 0, SBLOCKSIZE,
+ (char *)fs, &buf_size);
+ if (rc)
+ goto out;
+ if ((fs->fs_magic == FS_UFS1_MAGIC ||
+ (fs->fs_magic == FS_UFS2_MAGIC &&
+ fs->fs_sblockloc == sblock_try[i])) &&
+ buf_size == SBLOCKSIZE &&
+ fs->fs_bsize <= MAXBSIZE &&
+ fs->fs_bsize >= sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[i] == -1) {
+ rc = EINVAL;
+ goto out;
+ }
+ /*
+ * Calculate indirect block levels.
+ */
+ {
+ ufs2_daddr_t mult;
+ int level;
+
+ mult = 1;
+ for (level = 0; level < NIADDR; level++) {
+ mult *= NINDIR(fs);
+ fp->f_nindir[level] = mult;
+ }
+ }
+
+ inumber = ROOTINO;
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+
+ cp = path = strdup(upath);
+ if (path == NULL) {
+ rc = ENOMEM;
+ goto out;
+ }
+ while (*cp) {
+
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+ if (*cp == '\0')
+ break;
+
+ /*
+ * Check that current node is a directory.
+ */
+ if ((DIP(fp, di_mode) & IFMT) != IFDIR) {
+ rc = ENOTDIR;
+ goto out;
+ }
+
+ /*
+ * Get next component of path name.
+ */
+ {
+ int len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > MAXNAMLEN) {
+ rc = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+ }
+
+ /*
+ * Look up component in current directory.
+ * Save directory inumber in case we find a
+ * symbolic link.
+ */
+ parent_inumber = inumber;
+ rc = search_directory(ncp, f, &inumber);
+ *cp = c;
+ if (rc)
+ goto out;
+
+ /*
+ * Open next component.
+ */
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+
+ /*
+ * Check for symbolic link.
+ */
+ if ((DIP(fp, di_mode) & IFMT) == IFLNK) {
+ int link_len = DIP(fp, di_size);
+ int len;
+
+ len = strlen(cp);
+
+ if (link_len + len > MAXPATHLEN ||
+ ++nlinks > MAXSYMLINKS) {
+ rc = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+
+ if (link_len < fs->fs_maxsymlinklen) {
+ if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
+ cp = (caddr_t)(fp->f_di.di1.di_db);
+ else
+ cp = (caddr_t)(fp->f_di.di2.di_db);
+ bcopy(cp, namebuf, (unsigned) link_len);
+ } else {
+ /*
+ * Read file for symbolic link
+ */
+ size_t buf_size;
+ ufs2_daddr_t disk_block;
+ struct fs *fs = fp->f_fs;
+
+ if (!buf)
+ buf = malloc(fs->fs_bsize);
+ rc = block_map(f, (ufs2_daddr_t)0, &disk_block);
+ if (rc)
+ goto out;
+
+ twiddle(1);
+ rc = (f->f_dev->dv_strategy)(f->f_devdata,
+ F_READ, fsbtodb(fs, disk_block), 0,
+ fs->fs_bsize, buf, &buf_size);
+ if (rc)
+ goto out;
+
+ bcopy((char *)buf, namebuf, (unsigned)link_len);
+ }
+
+ /*
+ * If relative pathname, restart at parent directory.
+ * If absolute pathname, restart at root.
+ */
+ cp = namebuf;
+ if (*cp != '/')
+ inumber = parent_inumber;
+ else
+ inumber = (ino_t)ROOTINO;
+
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+ }
+ }
+
+ /*
+ * Found terminal component.
+ */
+ rc = 0;
+ fp->f_seekp = 0;
+out:
+ if (buf)
+ free(buf);
+ if (path)
+ free(path);
+ if (rc) {
+ if (fp->f_buf)
+ free(fp->f_buf);
+ free(fp->f_fs);
+ free(fp);
+ }
+ return (rc);
+}
+
+static int
+ufs_close(f)
+ struct open_file *f;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ int level;
+
+ f->f_fsdata = (void *)0;
+ if (fp == (struct file *)0)
+ return (0);
+
+ for (level = 0; level < NIADDR; level++) {
+ if (fp->f_blk[level])
+ free(fp->f_blk[level]);
+ }
+ if (fp->f_buf)
+ free(fp->f_buf);
+ free(fp->f_fs);
+ free(fp);
+ return (0);
+}
+
+/*
+ * Copy a portion of a file into kernel memory.
+ * Cross block boundaries when necessary.
+ */
+static int
+ufs_read(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ size_t csize;
+ char *buf;
+ size_t buf_size;
+ int rc = 0;
+ char *addr = start;
+
+ while (size != 0) {
+ if (fp->f_seekp >= DIP(fp, di_size))
+ break;
+
+ rc = buf_read_file(f, &buf, &buf_size);
+ if (rc)
+ break;
+
+ csize = size;
+ if (csize > buf_size)
+ csize = buf_size;
+
+ bcopy(buf, addr, csize);
+
+ fp->f_seekp += csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (rc);
+}
+
+/*
+ * Write to a portion of an already allocated file.
+ * Cross block boundaries when necessary. Can not
+ * extend the file.
+ */
+static int
+ufs_write(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ size_t csize;
+ int rc = 0;
+ char *addr = start;
+
+ csize = size;
+ while ((size != 0) && (csize != 0)) {
+ if (fp->f_seekp >= DIP(fp, di_size))
+ break;
+
+ if (csize >= 512) csize = 512; /* XXX */
+
+ rc = buf_write_file(f, addr, &csize);
+ if (rc)
+ break;
+
+ fp->f_seekp += csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (rc);
+}
+
+static off_t
+ufs_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seekp = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seekp += offset;
+ break;
+ case SEEK_END:
+ fp->f_seekp = DIP(fp, di_size) - offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (fp->f_seekp);
+}
+
+static int
+ufs_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = DIP(fp, di_mode);
+ sb->st_uid = DIP(fp, di_uid);
+ sb->st_gid = DIP(fp, di_gid);
+ sb->st_size = DIP(fp, di_size);
+ return (0);
+}
+
+static int
+ufs_readdir(struct open_file *f, struct dirent *d)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct direct *dp;
+ char *buf;
+ size_t buf_size;
+ int error;
+
+ /*
+ * assume that a directory entry will not be split across blocks
+ */
+again:
+ if (fp->f_seekp >= DIP(fp, di_size))
+ return (ENOENT);
+ error = buf_read_file(f, &buf, &buf_size);
+ if (error)
+ return (error);
+ dp = (struct direct *)buf;
+ fp->f_seekp += dp->d_reclen;
+ if (dp->d_ino == (ino_t)0)
+ goto again;
+
+ d->d_type = 0; /* illumos ufs does not have type in direct */
+ strcpy(d->d_name, dp->d_name);
+ return (0);
+}
diff --git a/usr/src/boot/lib/libstand/uuid_from_string.c b/usr/src/boot/lib/libstand/uuid_from_string.c
new file mode 100644
index 0000000000..2d5a6dd197
--- /dev/null
+++ b/usr/src/boot/lib/libstand/uuid_from_string.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 2015 M. Warner Losh
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Note: some comments taken from lib/libc/uuid/uuid_from_string.c
+ * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ */
+
+
+#include <stand.h>
+#include <uuid.h>
+
+static int
+hex2int(int ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ if (ch >= 'a' && ch <= 'f')
+ return 10 + ch - 'a';
+ if (ch >= 'A' && ch <= 'F')
+ return 10 + ch - 'A';
+ return 16;
+}
+
+static uint32_t
+fromhex(const char *s, int len, int *ok)
+{
+ uint32_t v;
+ int i, h;
+
+ if (!*ok)
+ return 0;
+ v = 0;
+ for (i = 0; i < 8; i++) {
+ h = hex2int(s[i]);
+ if (h == 16) {
+ *ok = 0;
+ return v;
+ }
+ v = (v << 4) | h;
+ }
+ return v;
+}
+
+/*
+ * uuid_from_string() - convert a string representation of an UUID into
+ * a binary representation.
+ * See also:
+ * http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm
+ *
+ * NOTE: The sequence field is in big-endian, while the time fields are in
+ * native byte order.
+ *
+ * 01234567-89ab-cdef-0123-456789abcdef
+ * 000000000011111111112222222222333333
+ * 012345678901234567890123456789012345
+ * - - - -
+ * hhhhhhhh-hhhh-hhhh-bbbb-bbbbbbbbbbbb
+ *
+ */
+void
+uuid_from_string(const char *s, uuid_t *u, uint32_t *status)
+{
+ int ok = 1;
+ int n;
+
+ if (s == NULL || *s == '\0') {
+ uuid_create_nil(u, status);
+ return;
+ }
+
+ if (status != NULL)
+ *status = uuid_s_invalid_string_uuid;
+ if (strlen(s) != 36)
+ return;
+ /* Only support new format, check for all the right dashes */
+ if (s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-')
+ return;
+ /* native byte order */
+ u->time_low = fromhex(s , 8, &ok);
+ u->time_mid = fromhex(s + 9, 4, &ok);
+ u->time_hi_and_version = fromhex(s + 14, 4, &ok);
+ /* Big endian, but presented as a whole number so decode as such */
+ u->clock_seq_hi_and_reserved = fromhex(s + 19, 2, &ok);
+ u->clock_seq_low = fromhex(s + 21, 2, &ok);
+ u->node[0] = fromhex(s + 24, 2, &ok);
+ u->node[1] = fromhex(s + 26, 2, &ok);
+ u->node[2] = fromhex(s + 28, 2, &ok);
+ u->node[3] = fromhex(s + 30, 2, &ok);
+ u->node[4] = fromhex(s + 32, 2, &ok);
+ u->node[5] = fromhex(s + 34, 2, &ok);
+ if (!ok)
+ return;
+
+ /* We have a successful scan. Check semantics... */
+ n = u->clock_seq_hi_and_reserved;
+ if ((n & 0x80) != 0x00 && /* variant 0? */
+ (n & 0xc0) != 0x80 && /* variant 1? */
+ (n & 0xe0) != 0xc0) { /* variant 2? */
+ if (status != NULL)
+ *status = uuid_s_bad_version;
+ } else {
+ if (status != NULL)
+ *status = uuid_s_ok;
+ }
+}
diff --git a/usr/src/boot/lib/libstand/uuid_to_string.c b/usr/src/boot/lib/libstand/uuid_to_string.c
new file mode 100644
index 0000000000..d878af495a
--- /dev/null
+++ b/usr/src/boot/lib/libstand/uuid_to_string.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2015 M. Warner Losh
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+/*
+ * Note: some comments taken from lib/libc/uuid/uuid_to_string.c
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ */
+
+#include <stand.h>
+#include <uuid.h>
+
+/*
+ * Dump len characters into *buf from val as hex and update *buf
+ */
+static void
+tohex(char **buf, int len, uint32_t val)
+{
+ static const char *hexstr = "0123456789abcdef";
+ char *walker = *buf;
+ int i;
+
+ for (i = len - 1; i >= 0; i--) {
+ walker[i] = hexstr[val & 0xf];
+ val >>= 4;
+ }
+ *buf = walker + len;
+}
+
+/*
+ * uuid_to_string() - Convert a binary UUID into a string representation.
+ * See also:
+ * http://www.opengroup.org/onlinepubs/009629399/uuid_to_string.htm
+ *
+ * NOTE: The references given above do not have a status code for when
+ * the string could not be allocated. The status code has been
+ * taken from the Hewlett-Packard implementation.
+ *
+ * NOTE: we don't support u == NULL for a nil UUID, sorry.
+ *
+ * NOTE: The sequence field is in big-endian, while the time fields are in
+ * native byte order.
+ *
+ * hhhhhhhh-hhhh-hhhh-bbbb-bbbbbbbbbbbb
+ * 01234567-89ab-cdef-0123-456789abcdef
+ */
+void
+uuid_to_string(const uuid_t *u, char **s, uint32_t *status)
+{
+ uuid_t nil;
+ char *w;
+
+ if (status != NULL)
+ *status = uuid_s_ok;
+ if (s == NULL) /* Regular version does this odd-ball behavior too */
+ return;
+ w = *s = malloc(37);
+ if (*s == NULL) {
+ if (status != NULL)
+ *status = uuid_s_no_memory;
+ return;
+ }
+ if (u == NULL) {
+ u = &nil;
+ uuid_create_nil(&nil, NULL);
+ }
+ /* native */
+ tohex(&w, 8, u->time_low);
+ *w++ = '-';
+ tohex(&w, 4, u->time_mid);
+ *w++ = '-';
+ tohex(&w, 4, u->time_hi_and_version);
+ *w++ = '-';
+ /* Big endian, so do a byte at a time */
+ tohex(&w, 2, u->clock_seq_hi_and_reserved);
+ tohex(&w, 2, u->clock_seq_low);
+ *w++ = '-';
+ tohex(&w, 2, u->node[0]);
+ tohex(&w, 2, u->node[1]);
+ tohex(&w, 2, u->node[2]);
+ tohex(&w, 2, u->node[3]);
+ tohex(&w, 2, u->node[4]);
+ tohex(&w, 2, u->node[5]);
+ *w++ = '\0';
+}
diff --git a/usr/src/boot/lib/libstand/write.c b/usr/src/boot/lib/libstand/write.c
new file mode 100644
index 0000000000..daf33cfca1
--- /dev/null
+++ b/usr/src/boot/lib/libstand/write.c
@@ -0,0 +1,95 @@
+/* $NetBSD: write.c,v 1.7 1996/06/21 20:29:30 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)write.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include "stand.h"
+
+ssize_t
+write(fd, dest, bcount)
+ int fd;
+ void *dest;
+ size_t bcount;
+{
+ struct open_file *f = &files[fd];
+ size_t resid;
+
+ if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_WRITE)) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ twiddle(4);
+ errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
+ btodb(f->f_offset), 0, bcount, dest, &resid);
+ if (errno)
+ return (-1);
+ f->f_offset += resid;
+ return (resid);
+ }
+ resid = bcount;
+ if ((errno = (f->f_ops->fo_write)(f, dest, bcount, &resid)))
+ return (-1);
+ return (bcount - resid);
+}
diff --git a/usr/src/boot/lib/libstand/zalloc.c b/usr/src/boot/lib/libstand/zalloc.c
new file mode 100644
index 0000000000..4d1ec62912
--- /dev/null
+++ b/usr/src/boot/lib/libstand/zalloc.c
@@ -0,0 +1,316 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation
+ * subsystem
+ *
+ * This subsystem implements memory pools and memory allocation
+ * routines.
+ *
+ * Pools are managed via a linked list of 'free' areas. Allocating
+ * memory creates holes in the freelist, freeing memory fills them.
+ * Since the freelist consists only of free memory areas, it is possible
+ * to allocate the entire pool without incuring any structural overhead.
+ *
+ * The system works best when allocating similarly-sized chunks of
+ * memory. Care must be taken to avoid fragmentation when
+ * allocating/deallocating dissimilar chunks.
+ *
+ * When a memory pool is first allocated, the entire pool is marked as
+ * allocated. This is done mainly because we do not want to modify any
+ * portion of a pool's data area until we are given permission. The
+ * caller must explicitly deallocate portions of the pool to make them
+ * available.
+ *
+ * z[n]xalloc() works like z[n]alloc() but the allocation is made from
+ * within the specified address range. If the segment could not be
+ * allocated, NULL is returned. WARNING! The address range will be
+ * aligned to an 8 or 16 byte boundry depending on the cpu so if you
+ * give an unaligned address range, unexpected results may occur.
+ *
+ * If a standard allocation fails, the reclaim function will be called
+ * to recover some space. This usually causes other portions of the
+ * same pool to be released. Memory allocations at this low level
+ * should not block but you can do that too in your reclaim function
+ * if you want. Reclaim does not function when z[n]xalloc() is used,
+ * only for z[n]alloc().
+ *
+ * Allocation and frees of 0 bytes are valid operations.
+ */
+
+#include "zalloc_defs.h"
+
+/*
+ * Objects in the pool must be aligned to at least the size of struct MemNode.
+ * They must also be aligned to MALLOCALIGN, which should normally be larger
+ * than the struct, so assert that to be so at compile time.
+ */
+typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1];
+
+#define MEMNODE_SIZE_MASK MALLOCALIGN_MASK
+
+/*
+ * znalloc() - allocate memory (without zeroing) from pool. Call reclaim
+ * and retry if appropriate, return NULL if unable to allocate
+ * memory.
+ */
+
+void *
+znalloc(MemPool *mp, uintptr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ *
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return((void *)-1);
+
+ /*
+ * locate freelist entry big enough to hold the object. If all objects
+ * are the same size, this is a constant-time function.
+ */
+
+ if (bytes <= mp->mp_Size - mp->mp_Used) {
+ MemNode **pmn;
+ MemNode *mn;
+
+ for (pmn = &mp->mp_First; (mn=*pmn) != NULL; pmn = &mn->mr_Next) {
+ if (bytes > mn->mr_Bytes)
+ continue;
+
+ /*
+ * Cut a chunk of memory out of the beginning of this
+ * block and fixup the link appropriately.
+ */
+
+ {
+ char *ptr = (char *)mn;
+
+ if (mn->mr_Bytes == bytes) {
+ *pmn = mn->mr_Next;
+ } else {
+ mn = (MemNode *)((char *)mn + bytes);
+ mn->mr_Next = ((MemNode *)ptr)->mr_Next;
+ mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
+ *pmn = mn;
+ }
+ mp->mp_Used += bytes;
+ return(ptr);
+ }
+ }
+ }
+
+ /*
+ * Memory pool is full, return NULL.
+ */
+
+ return(NULL);
+}
+
+/*
+ * zfree() - free previously allocated memory
+ */
+
+void
+zfree(MemPool *mp, void *ptr, uintptr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return;
+
+ /*
+ * panic if illegal pointer
+ */
+
+ if ((char *)ptr < (char *)mp->mp_Base ||
+ (char *)ptr + bytes > (char *)mp->mp_End ||
+ ((uintptr_t)ptr & MEMNODE_SIZE_MASK) != 0)
+ panic("zfree(%p,%ju): wild pointer", ptr, (uintmax_t)bytes);
+
+ /*
+ * free the segment
+ */
+
+ {
+ MemNode **pmn;
+ MemNode *mn;
+
+ mp->mp_Used -= bytes;
+
+ for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
+ /*
+ * If area between last node and current node
+ * - check range
+ * - check merge with next area
+ * - check merge with previous area
+ */
+ if ((char *)ptr <= (char *)mn) {
+ /*
+ * range check
+ */
+ if ((char *)ptr + bytes > (char *)mn) {
+ panic("zfree(%p,%ju): corrupt memlist1", ptr,
+ (uintmax_t)bytes);
+ }
+
+ /*
+ * merge against next area or create independant area
+ */
+
+ if ((char *)ptr + bytes == (char *)mn) {
+ ((MemNode *)ptr)->mr_Next = mn->mr_Next;
+ ((MemNode *)ptr)->mr_Bytes= bytes + mn->mr_Bytes;
+ } else {
+ ((MemNode *)ptr)->mr_Next = mn;
+ ((MemNode *)ptr)->mr_Bytes= bytes;
+ }
+ *pmn = mn = (MemNode *)ptr;
+
+ /*
+ * merge against previous area (if there is a previous
+ * area).
+ */
+
+ if (pmn != &mp->mp_First) {
+ if ((char*)pmn + ((MemNode*)pmn)->mr_Bytes == (char*)ptr) {
+ ((MemNode *)pmn)->mr_Next = mn->mr_Next;
+ ((MemNode *)pmn)->mr_Bytes += mn->mr_Bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+ return;
+ /* NOT REACHED */
+ }
+ if ((char *)ptr < (char *)mn + mn->mr_Bytes) {
+ panic("zfree(%p,%ju): corrupt memlist2", ptr,
+ (uintmax_t)bytes);
+ }
+ }
+ /*
+ * We are beyond the last MemNode, append new MemNode. Merge against
+ * previous area if possible.
+ */
+ if (pmn == &mp->mp_First ||
+ (char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr
+ ) {
+ ((MemNode *)ptr)->mr_Next = NULL;
+ ((MemNode *)ptr)->mr_Bytes = bytes;
+ *pmn = (MemNode *)ptr;
+ mn = (MemNode *)ptr;
+ } else {
+ ((MemNode *)pmn)->mr_Bytes += bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+}
+
+/*
+ * zextendPool() - extend memory pool to cover additional space.
+ *
+ * Note: the added memory starts out as allocated, you
+ * must free it to make it available to the memory subsystem.
+ *
+ * Note: mp_Size may not reflect (mp_End - mp_Base) range
+ * due to other parts of the system doing their own sbrk()
+ * calls.
+ */
+
+void
+zextendPool(MemPool *mp, void *base, uintptr_t bytes)
+{
+ if (mp->mp_Size == 0) {
+ mp->mp_Base = base;
+ mp->mp_Used = bytes;
+ mp->mp_End = (char *)base + bytes;
+ mp->mp_Size = bytes;
+ } else {
+ void *pend = (char *)mp->mp_Base + mp->mp_Size;
+
+ if (base < mp->mp_Base) {
+ mp->mp_Size += (char *)mp->mp_Base - (char *)base;
+ mp->mp_Used += (char *)mp->mp_Base - (char *)base;
+ mp->mp_Base = base;
+ }
+ base = (char *)base + bytes;
+ if (base > pend) {
+ mp->mp_Size += (char *)base - (char *)pend;
+ mp->mp_Used += (char *)base - (char *)pend;
+ mp->mp_End = (char *)base;
+ }
+ }
+}
+
+#ifdef ZALLOCDEBUG
+
+void
+zallocstats(MemPool *mp)
+{
+ int abytes = 0;
+ int hbytes = 0;
+ int fcount = 0;
+ MemNode *mn;
+
+ printf("%d bytes reserved", (int) mp->mp_Size);
+
+ mn = mp->mp_First;
+
+ if ((void *)mn != (void *)mp->mp_Base) {
+ abytes += (char *)mn - (char *)mp->mp_Base;
+ }
+
+ while (mn) {
+ if ((char *)mn + mn->mr_Bytes != mp->mp_End) {
+ hbytes += mn->mr_Bytes;
+ ++fcount;
+ }
+ if (mn->mr_Next)
+ abytes += (char *)mn->mr_Next - ((char *)mn + mn->mr_Bytes);
+ mn = mn->mr_Next;
+ }
+ printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n",
+ abytes,
+ fcount,
+ hbytes
+ );
+}
+
+#endif
+
diff --git a/usr/src/boot/lib/libstand/zalloc_defs.h b/usr/src/boot/lib/libstand/zalloc_defs.h
new file mode 100644
index 0000000000..7f2cc1202c
--- /dev/null
+++ b/usr/src/boot/lib/libstand/zalloc_defs.h
@@ -0,0 +1,78 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * DEFS.H
+ */
+
+#define USEGUARD /* use stard/end guard bytes */
+#define USEENDGUARD
+#define DMALLOCDEBUG /* add debugging code to gather stats */
+#define ZALLOCDEBUG
+
+#include <sys/stdint.h>
+#include "stand.h"
+#include "zalloc_mem.h"
+
+#define Library extern
+
+/*
+ * block extension for sbrk()
+ */
+
+#define BLKEXTEND (4 * 1024)
+#define BLKEXTENDMASK (BLKEXTEND - 1)
+
+/*
+ * Required malloc alignment.
+ *
+ * Embedded platforms using the u-boot API drivers require that all I/O buffers
+ * be on a cache line sized boundary. The worst case size for that is 64 bytes.
+ * For other platforms, 16 bytes works fine. The alignment also must be at
+ * least sizeof(struct MemNode); this is asserted in zalloc.c.
+ */
+
+#if defined(__arm__) || defined(__mips__) || defined(__powerpc__)
+#define MALLOCALIGN 64
+#else
+#define MALLOCALIGN 16
+#endif
+#define MALLOCALIGN_MASK (MALLOCALIGN - 1)
+
+typedef struct Guard {
+ size_t ga_Bytes;
+ size_t ga_Magic; /* must be at least 32 bits */
+} Guard;
+
+#define GAMAGIC 0x55FF44FD
+#define GAFREE 0x5F54F4DF
+
+#include "zalloc_protos.h"
diff --git a/usr/src/boot/lib/libstand/zalloc_malloc.c b/usr/src/boot/lib/libstand/zalloc_malloc.c
new file mode 100644
index 0000000000..b9a295fb38
--- /dev/null
+++ b/usr/src/boot/lib/libstand/zalloc_malloc.c
@@ -0,0 +1,200 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
+ */
+
+#include "zalloc_defs.h"
+
+static MemPool MallocPool;
+
+#ifdef DMALLOCDEBUG
+static int MallocMax;
+static int MallocCount;
+
+void mallocstats(void);
+#endif
+
+#ifdef malloc
+#undef malloc
+#undef free
+#endif
+
+void *
+Malloc(size_t bytes, const char *file, int line)
+{
+ Guard *res;
+
+#ifdef USEENDGUARD
+ bytes += MALLOCALIGN + 1;
+#else
+ bytes += MALLOCALIGN;
+#endif
+
+ while ((res = znalloc(&MallocPool, bytes)) == NULL) {
+ int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
+ char *base;
+
+ if ((base = sbrk(incr)) == (char *)-1)
+ return(NULL);
+ zextendPool(&MallocPool, base, incr);
+ zfree(&MallocPool, base, incr);
+ }
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+#ifdef USEGUARD
+ res->ga_Magic = GAMAGIC;
+#endif
+ res->ga_Bytes = bytes;
+#ifdef USEENDGUARD
+ *((signed char *)res + bytes - 1) = -2;
+#endif
+
+ return((char *)res + MALLOCALIGN);
+}
+
+void
+Free(void *ptr, const char *file, int line)
+{
+ size_t bytes;
+
+ if (ptr != NULL) {
+ Guard *res = (void *)((char *)ptr - MALLOCALIGN);
+
+ if (file == NULL)
+ file = "unknown";
+#ifdef USEGUARD
+ if (res->ga_Magic == GAFREE) {
+ printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line);
+ return;
+ }
+ if (res->ga_Magic != GAMAGIC)
+ panic("free: guard1 fail @ %p from %s:%d", ptr, file, line);
+ res->ga_Magic = GAFREE;
+#endif
+#ifdef USEENDGUARD
+ if (*((signed char *)res + res->ga_Bytes - 1) == -1) {
+ printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line);
+ return;
+ }
+ if (*((signed char *)res + res->ga_Bytes - 1) != -2)
+ panic("free: guard2 fail @ %p + %zu from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line);
+ *((signed char *)res + res->ga_Bytes - 1) = -1;
+#endif
+
+ bytes = res->ga_Bytes;
+ zfree(&MallocPool, res, bytes);
+#ifdef DMALLOCDEBUG
+ --MallocCount;
+#endif
+ }
+}
+
+
+void *
+Calloc(size_t n1, size_t n2, const char *file, int line)
+{
+ uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2;
+ void *res;
+
+ if ((res = Malloc(bytes, file, line)) != NULL) {
+ bzero(res, bytes);
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+ }
+ return(res);
+}
+
+/*
+ * realloc() - I could be fancier here and free the old buffer before
+ * allocating the new one (saving potential fragmentation
+ * and potential buffer copies). But I don't bother.
+ */
+
+void *
+Realloc(void *ptr, size_t size, const char *file, int line)
+{
+ void *res;
+ size_t old;
+
+ if ((res = Malloc(size, file, line)) != NULL) {
+ if (ptr) {
+ old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
+ if (old < size)
+ bcopy(ptr, res, old);
+ else
+ bcopy(ptr, res, size);
+ Free(ptr, file, line);
+ } else {
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#ifdef EXITSTATS
+ if (DidAtExit == 0) {
+ DidAtExit = 1;
+ atexit(mallocstats);
+ }
+#endif
+#endif
+ }
+ }
+ return(res);
+}
+
+void *
+Reallocf(void *ptr, size_t size, const char *file, int line)
+{
+ void *res;
+
+ if ((res = Realloc(ptr, size, file, line)) == NULL)
+ Free(ptr, file, line);
+ return(res);
+}
+
+#ifdef DMALLOCDEBUG
+
+void
+mallocstats(void)
+{
+ printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
+#ifdef ZALLOCDEBUG
+ zallocstats(&MallocPool);
+#endif
+}
+
+#endif
+
diff --git a/usr/src/boot/lib/libstand/zalloc_mem.h b/usr/src/boot/lib/libstand/zalloc_mem.h
new file mode 100644
index 0000000000..26d388dfc7
--- /dev/null
+++ b/usr/src/boot/lib/libstand/zalloc_mem.h
@@ -0,0 +1,53 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * H/MEM.H
+ *
+ * Basic memory pool / memory node structures.
+ */
+
+typedef struct MemNode {
+ struct MemNode *mr_Next;
+ uintptr_t mr_Bytes;
+} MemNode;
+
+typedef struct MemPool {
+ void *mp_Base;
+ void *mp_End;
+ MemNode *mp_First;
+ uintptr_t mp_Size;
+ uintptr_t mp_Used;
+} MemPool;
+
+#define ZNOTE_FREE 0
+#define ZNOTE_REUSE 1
+
diff --git a/usr/src/boot/lib/libstand/zalloc_protos.h b/usr/src/boot/lib/libstand/zalloc_protos.h
new file mode 100644
index 0000000000..53a40e400d
--- /dev/null
+++ b/usr/src/boot/lib/libstand/zalloc_protos.h
@@ -0,0 +1,35 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+Library void *znalloc(struct MemPool *mpool, uintptr_t bytes);
+Library void zfree(struct MemPool *mpool, void *ptr, uintptr_t bytes);
+Library void zextendPool(MemPool *mp, void *base, uintptr_t bytes);
+Library void zallocstats(struct MemPool *mp);
diff --git a/usr/src/boot/lib/libz/ChangeLog b/usr/src/boot/lib/libz/ChangeLog
new file mode 100644
index 0000000000..f22aabaef5
--- /dev/null
+++ b/usr/src/boot/lib/libz/ChangeLog
@@ -0,0 +1,1472 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Ro§]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix unintialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no libary use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+ Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+ _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+ binary compatibility -- a normal version and a 64-bit offset version,
+ per the Large File Support Extension when _LARGEFILE64_SOURCE is
+ defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+ is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+ [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+ trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+ gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+ Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+ the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+ for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+ doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+ that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+ un-versioned, the patch adds versioning only for symbols introduced in
+ zlib-1.2.0 or later. It also declares as local those symbols which are
+ not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+ NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/usr/src/boot/lib/libz/FAQ b/usr/src/boot/lib/libz/FAQ
new file mode 100644
index 0000000000..99b7cf92e4
--- /dev/null
+++ b/usr/src/boot/lib/libz/FAQ
@@ -0,0 +1,368 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL. See the
+ file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
+ precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://marknelson.us/1997/01/01/zlib-engine/
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress(), the length of the compressed
+ buffer is equal to the available size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not zero.
+ When setting the parameter flush equal to Z_FINISH, also make sure that
+ avail_out is big enough to allow processing all pending input. Note that a
+ Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+ made with more input or output space. A Z_BUF_ERROR may in fact be
+ unavoidable depending on how the functions are used, since it is not
+ possible to tell whether or not there is more output pending when
+ strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
+ heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h . Examples of zlib usage are in the files test/example.c
+ and test/minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of zlib.
+ Please try to reproduce the problem with a small program and send the
+ corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
+ data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ By default a shared (and a static) library is built for Unix. So:
+
+ make distclean
+ ./configure
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to
+ it. You can check the version at the top of zlib.h or with the
+ ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+ http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip formats
+ use the same compressed data format internally, but have different headers
+ and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about a
+ single file, such as the name and last modification date. The zlib format
+ on the other hand was designed for in-memory and communication channel
+ applications, and has a much more compact header and trailer and uses a
+ faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode the
+ gzip format using inflateInit2(). Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's *Init* functions
+ allow for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ Yes. It has been tested on 64-bit machines, and has no dependence on any
+ data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format than
+ does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically use
+ Z_FULL_FLUSH, carefully write all the pending data at those points, and
+ keep an index of those locations, then you can start decompression at those
+ points. You have to be careful to not use Z_FULL_FLUSH too often, since it
+ can significantly degrade compression. Alternatively, you can scan a
+ deflate stream once to generate an index, and then use that index for
+ random access. See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ It has in the past, but we have not heard of any recent evidence. There
+ were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+ If you know of recent, successful applications of zlib on these operating
+ systems, please let us know. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+ understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit only
+ if the compiler's "long" type is 32 bits. If the compiler's "long" type is
+ 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib is
+ compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of an 8K string space (or other value as set by
+ gzbuffer()), other than the caller of gzprintf() assuring that the output
+ will not exceed 8K. On the other hand, if zlib is compiled to use
+ snprintf() or vsnprintf(), which should normally be the case, then there is
+ no vulnerability. The ./configure script will display warnings if an
+ insecure variation of sprintf() will be used by gzprintf(). Also the
+ zlibCompileFlags() function will return information on what variant of
+ sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability, and versions
+ 1.2.1 and 1.2.2 were subject to an access exception when decompressing
+ invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly as well as contradicted each other. So now, we simply
+ make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+
+ No. That is intentional for performance reasons, and the output of deflate
+ is not affected. This only started showing up recently since zlib 1.2.x
+ uses malloc() by default for allocations, whereas earlier versions used
+ calloc(), which zeros out the allocated memory. Even though the code was
+ correct, versions 1.2.4 and later was changed to not stimulate these
+ checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very
+ weak and can be broken with freely available programs. To get strong
+ encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+ compression. For PKZIP compatible "encryption", look at
+ http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion with
+ the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specification in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats. In
+ any case, the compression improvements are so modest compared to other more
+ modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+ There are no zip functions in zlib. You are probably using minizip by
+ Giles Vollant, which is found in the contrib directory of zlib. It is not
+ part of zlib. In fact none of the stuff in contrib is part of zlib. The
+ files in there are not supported by the zlib authors. You need to contact
+ the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+ Since it's part of zlib, doesn't that mean that all of zlib falls under the
+ GNU GPL?
+
+ No. The files in contrib are not part of zlib. They were contributed by
+ other authors and are provided as a convenience to the user within the zlib
+ distribution. Each item in contrib has its own license.
+
+43. Is zlib subject to export controls? What is its ECCN?
+
+ zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/usr/src/boot/lib/libz/FREEBSD-upgrade b/usr/src/boot/lib/libz/FREEBSD-upgrade
new file mode 100644
index 0000000000..4ee4eebedb
--- /dev/null
+++ b/usr/src/boot/lib/libz/FREEBSD-upgrade
@@ -0,0 +1,44 @@
+$FreeBSD$
+
+ZLib 1.2.2
+
+Original distribution from http://www.gzip.org/zlib/
+
+Vendor files removed from distribution before import:
+ INDEX configure qnx/
+ Makefile contrib/ win32/
+ Makefile.in msdos/ zconf.in.h
+ amiga/ old/
+ as400/ projects/
+
+Vendor files imported:
+ ChangeLog example.c minigzip.c
+ FAQ gzio.c trees.c
+ README infback.c trees.h
+ adler32.c inffast.c uncompr.c
+ algorithm.txt inffast.h zconf.h
+ compress.c inffixed.h zlib.3
+ crc32.c inflate.c zlib.h
+ crc32.h inflate.h zutil.c
+ deflate.c inftrees.c zutil.h
+ deflate.h inftrees.h
+
+As of April, 2005, only the following three vendor files
+had non-trivial local changes:
+ gzio.c minigzip.c zconf.h
+
+Added files (not from vendor):
+ Makefile zopen.c FREEBSD-upgrade
+
+To Update:
+ 1) Unpack vendor sources into a clean directory.
+ 2) Delete unnecessary files.
+ 3) Import onto the vendor branch. The 1.2.2 import was done like this:
+ cvs -d <CVSROOT> import -ko -m "ZLib 1.2.2" src/lib/libz ZLIB v1_2_2
+ 4) In a clean directory, check out a fresh copy of HEAD,
+ merging in vendor changes since the last import.
+ cvs -d <CVSROOT> co -jZLIB:yesterday -jZLIB src/lib/libz
+ 5) Resolve any conflicts and commit them.
+ 6) Update this file with any changes to the file list or update procedure.
+
+kientzle@FreeBSD.org
diff --git a/usr/src/boot/lib/libz/Makefile b/usr/src/boot/lib/libz/Makefile
new file mode 100644
index 0000000000..7a80fcbab5
--- /dev/null
+++ b/usr/src/boot/lib/libz/Makefile
@@ -0,0 +1,78 @@
+#
+# $FreeBSD$
+#
+
+LIB= z
+SHLIBDIR?= /lib
+SHLIB_MAJOR= 6
+MAN= zlib.3 zopen.3
+
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+CFLAGS+= -DHAS_snprintf -DHAS_vsnprintf -I${.CURDIR}
+
+WARNS?= 3
+
+CLEANFILES+= example.o example foo.gz minigzip.o minigzip
+
+SRCS+= adler32.c
+SRCS+= compress.c
+SRCS+= crc32.c
+SRCS+= deflate.c
+SRCS+= gzclose.c
+SRCS+= gzlib.c
+SRCS+= gzread.c
+SRCS+= gzwrite.c
+SRCS+= infback.c
+SRCS+= inffast.c
+SRCS+= inflate.c
+SRCS+= inftrees.c
+SRCS+= trees.c
+SRCS+= uncompr.c
+SRCS+= zopen.c
+SRCS+= zutil.c
+
+#.if ${MACHINE_ARCH} == "i386" && ${MACHINE_CPU:M*i686*}
+#.PATH: ${.CURDIR}/contrib/asm686
+#SRCS+= match.S
+#CFLAGS+= -DASMV -DNO_UNDERLINE
+#ACFLAGS+= -Wa,--noexecstack
+#.endif
+
+#.if ${MACHINE_ARCH} == "amd64"
+#.PATH: ${.CURDIR}/contrib/gcc_gvmat64
+#SRCS+= gvmat64.S
+#CFLAGS+= -DASMV -DNO_UNDERLINE
+#ACFLAGS+= -Wa,--noexecstack
+#.endif
+
+VERSION_DEF= ${.CURDIR}/Versions.def
+SYMBOL_MAPS= ${.CURDIR}/Symbol.map
+CFLAGS+= -DSYMBOL_VERSIONING
+
+INCS= zconf.h zlib.h
+
+.PATH: ${.CURDIR}/test
+
+minigzip: all minigzip.o
+ $(CC) -o minigzip minigzip.o -L. -lz
+
+example: all example.o
+ $(CC) -o example example.o -L. -lz
+
+test: example minigzip
+ (export LD_LIBRARY_PATH=. ; ./example )
+ (export LD_LIBRARY_PATH=. ; \
+ echo hello world | ./minigzip | ./minigzip -d )
+
+FILES= zlib.pc
+FILESDIR= ${LIBDATADIR}/pkgconfig
+
+.include <bsd.lib.mk>
+
+## XXX: clang integrated-as doesn't grok .intel_syntax directives yet
+#ACFLAGS.gvmat64.S= ${CLANG_NO_IAS}
+#ACFLAGS+= ${ACFLAGS.${.IMPSRC:T}}
diff --git a/usr/src/boot/lib/libz/README b/usr/src/boot/lib/libz/README
new file mode 100644
index 0000000000..5ca9d127ed
--- /dev/null
+++ b/usr/src/boot/lib/libz/README
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.8 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.8 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/usr/src/boot/lib/libz/Symbol.map b/usr/src/boot/lib/libz/Symbol.map
new file mode 100644
index 0000000000..731ce0ab5b
--- /dev/null
+++ b/usr/src/boot/lib/libz/Symbol.map
@@ -0,0 +1,108 @@
+/*
+ * $FreeBSD$
+ */
+
+ZLIB_1.2.7.1 {
+ inflateGetDictionary;
+ gzvprintf;
+};
+
+ZLIB_1.2.7.0 {
+ deflatePending;
+ deflateResetKeep;
+ gzgetc_;
+ inflateResetKeep;
+};
+
+ZLIB_1.2.4.0 {
+ adler32;
+ adler32_combine;
+ adler32_combine64;
+ compress;
+ compress2;
+ compressBound;
+ crc32;
+ crc32_combine;
+ crc32_combine64;
+ deflate;
+ deflateBound;
+ deflateCopy;
+ deflateEnd;
+ deflateInit2_;
+ deflateInit_;
+ deflateParams;
+ deflatePrime;
+ deflateReset;
+ deflateSetDictionary;
+ deflateSetHeader;
+ deflateTune;
+ get_crc_table;
+ gzbuffer;
+ gzclearerr;
+ gzclose;
+ gzclose_r;
+ gzclose_w;
+ gzdirect;
+ gzdopen;
+ gzeof;
+ gzerror;
+ gzflush;
+ gzgetc;
+ gzgets;
+ gzoffset;
+ gzoffset64;
+ gzopen;
+ gzopen64;
+ gzprintf;
+ gzputc;
+ gzputs;
+ gzread;
+ gzrewind;
+ gzseek;
+ gzseek64;
+ gzsetparams;
+ gztell;
+ gztell64;
+ gzungetc;
+ gzwrite;
+ inflate;
+ inflateBack;
+ inflateBackEnd;
+ inflateBackInit_;
+ inflateCopy;
+ inflateEnd;
+ inflateGetHeader;
+ inflateInit2_;
+ inflateInit_;
+ inflateMark;
+ inflatePrime;
+ inflateReset;
+ inflateReset2;
+ inflateSetDictionary;
+ inflateSync;
+ inflateSyncPoint;
+ inflateUndermine;
+ uncompress;
+ zError;
+ zlibCompileFlags;
+ zlibVersion;
+};
+
+FBSD_1.2 {
+ zopen;
+};
+
+ZLIBprivate_1.0 {
+ _tr_align;
+ _tr_flush_block;
+ _tr_init;
+ _tr_stored_block;
+ _tr_tally;
+ gz_error;
+ inflate_fast;
+ inflate_table;
+ longest_match;
+ match_init;
+ zcalloc;
+ zcfree;
+};
diff --git a/usr/src/boot/lib/libz/Versions.def b/usr/src/boot/lib/libz/Versions.def
new file mode 100644
index 0000000000..4651e776ab
--- /dev/null
+++ b/usr/src/boot/lib/libz/Versions.def
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+ZLIB_1.2.4.0 {
+};
+
+ZLIB_1.2.7.0 {
+} ZLIB_1.2.4.0;
+
+ZLIB_1.2.7.1 {
+} ZLIB_1.2.7.0;
+
+FBSD_1.2 {
+} ZLIB_1.2.4.0;
+
+ZLIBprivate_1.0 {
+} ZLIB_1.2.4.0;
+
diff --git a/usr/src/boot/lib/libz/adler32.c b/usr/src/boot/lib/libz/adler32.c
new file mode 100644
index 0000000000..a868f073d8
--- /dev/null
+++ b/usr/src/boot/lib/libz/adler32.c
@@ -0,0 +1,179 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521 /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
+ do { \
+ CHOP(a); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD(a) \
+ do { \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD28(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/usr/src/boot/lib/libz/compress.c b/usr/src/boot/lib/libz/compress.c
new file mode 100644
index 0000000000..6e9762676a
--- /dev/null
+++ b/usr/src/boot/lib/libz/compress.c
@@ -0,0 +1,80 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
+}
diff --git a/usr/src/boot/lib/libz/contrib/README.contrib b/usr/src/boot/lib/libz/contrib/README.contrib
new file mode 100644
index 0000000000..c66349b7c6
--- /dev/null
+++ b/usr/src/boot/lib/libz/contrib/README.contrib
@@ -0,0 +1,78 @@
+All files under this contrib directory are UNSUPPORTED. There were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+
+
+ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
+ Support for Ada
+ See http://zlib-ada.sourceforge.net/
+
+amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
+ asm code for AMD64
+ See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
+
+asm686/ by Brian Raiter <breadbox@muppetlabs.com>
+ asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+blast/ by Mark Adler <madler@alumni.caltech.edu>
+ Decompressor for output of PKWare Data Compression Library (DCL)
+
+delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ Support for Delphi and C++ Builder
+
+dotzlib/ by Henrik Ravn <henrik@ravn.com>
+ Support for Microsoft .Net and Visual C++ .Net
+
+gcc_gvmat64/by Gilles Vollant <info@winimage.com>
+ GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+ assembler to replace longest_match() and inflate_fast()
+
+infback9/ by Mark Adler <madler@alumni.caltech.edu>
+ Unsupported diffs to infback to decode the deflate64 format
+
+inflate86/ by Chris Anderson <christop@charm.net>
+ Tuned x86 gcc asm code to replace inflate_fast()
+
+iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+
+iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+
+iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
+ and Kevin Ruland <kevin@rodin.wustl.edu>
+ Yet another C++ I/O streams interface
+
+masmx64/ by Gilles Vollant <info@winimage.com>
+ x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+ replace longest_match() and inflate_fast(), also masm x86
+ 64-bits translation of Chris Anderson inflate_fast()
+
+masmx86/ by Gilles Vollant <info@winimage.com>
+ x86 asm code to replace longest_match() and inflate_fast(),
+ for Visual C++ and MASM (32 bits).
+ Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
+
+minizip/ by Gilles Vollant <info@winimage.com>
+ Mini zip and unzip based on zlib
+ Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+ See http://www.winimage.com/zLibDll/unzip.html
+
+pascal/ by Bob Dellaca <bobdl@xtra.co.nz> et al.
+ Support for Pascal
+
+puff/ by Mark Adler <madler@alumni.caltech.edu>
+ Small, low memory usage inflate. Also serves to provide an
+ unambiguous description of the deflate format.
+
+testzlib/ by Gilles Vollant <info@winimage.com>
+ Example of the use of zlib
+
+untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+
+vstudio/ by Gilles Vollant <info@winimage.com>
+ Building a minizip-enhanced zlib with Microsoft Visual Studio
+ Includes vc11 from kreuzerkrieg and vc12 from davispuh
diff --git a/usr/src/boot/lib/libz/contrib/asm686/README.686 b/usr/src/boot/lib/libz/contrib/asm686/README.686
new file mode 100644
index 0000000000..a0bf3bea4a
--- /dev/null
+++ b/usr/src/boot/lib/libz/contrib/asm686/README.686
@@ -0,0 +1,51 @@
+This is a patched version of zlib, modified to use
+Pentium-Pro-optimized assembly code in the deflation algorithm. The
+files changed/added by this patch are:
+
+README.686
+match.S
+
+The speedup that this patch provides varies, depending on whether the
+compiler used to build the original version of zlib falls afoul of the
+PPro's speed traps. My own tests show a speedup of around 10-20% at
+the default compression level, and 20-30% using -9, against a version
+compiled using gcc 2.7.2.3. Your mileage may vary.
+
+Note that this code has been tailored for the PPro/PII in particular,
+and will not perform particuarly well on a Pentium.
+
+If you are using an assembler other than GNU as, you will have to
+translate match.S to use your assembler's syntax. (Have fun.)
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 1998
+
+
+Added for zlib 1.1.3:
+
+The patches come from
+http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+To compile zlib with this asm file, copy match.S to the zlib directory
+then do:
+
+CFLAGS="-O3 -DASMV" ./configure
+make OBJA=match.o
+
+
+Update:
+
+I've been ignoring these assembly routines for years, believing that
+gcc's generated code had caught up with it sometime around gcc 2.95
+and the major rearchitecting of the Pentium 4. However, I recently
+learned that, despite what I believed, this code still has some life
+in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
+faster than the code produced by gcc 4.1.
+
+In acknowledgement of its continuing usefulness, I've altered the
+license to match that of the rest of zlib. Share and Enjoy!
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 2007
diff --git a/usr/src/boot/lib/libz/contrib/asm686/match.S b/usr/src/boot/lib/libz/contrib/asm686/match.S
new file mode 100644
index 0000000000..fa42109278
--- /dev/null
+++ b/usr/src/boot/lib/libz/contrib/asm686/match.S
@@ -0,0 +1,357 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define match_init _match_init
+#define longest_match _longest_match
+#endif
+
+#define MAX_MATCH (258)
+#define MIN_MATCH (3)
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define chainlenwmask 0 /* high word: current chain len */
+ /* low word: s->wmask */
+#define window 4 /* local copy of s->window */
+#define windowbestlen 8 /* s->window + bestlen */
+#define scanstart 16 /* first two bytes of string */
+#define scanend 12 /* last two bytes of string */
+#define scanalign 20 /* dword-misalignment of string */
+#define nicematch 24 /* a good enough match size */
+#define bestlen 28 /* size of best match so far */
+#define scan 32 /* ptr to string wanting match */
+
+#define LocalVarsSize (36)
+/* saved ebx 36 */
+/* saved edi 40 */
+/* saved esi 44 */
+/* saved ebp 48 */
+/* return address 52 */
+#define deflatestate 56 /* the function arguments */
+#define curmatch 60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ * in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add (8)
+
+#define dsWSize (36+zlib1222add)
+#define dsWMask (44+zlib1222add)
+#define dsWindow (48+zlib1222add)
+#define dsPrev (56+zlib1222add)
+#define dsMatchLen (88+zlib1222add)
+#define dsPrevMatch (92+zlib1222add)
+#define dsStrStart (100+zlib1222add)
+#define dsMatchStart (104+zlib1222add)
+#define dsLookahead (108+zlib1222add)
+#define dsPrevLen (112+zlib1222add)
+#define dsMaxChainLen (116+zlib1222add)
+#define dsGoodMatch (132+zlib1222add)
+#define dsNiceMatch (136+zlib1222add)
+
+
+.file "match.S"
+
+.globl match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+.cfi_sections .debug_frame
+
+longest_match:
+
+.cfi_startproc
+/* Save registers that the compiler may be using, and adjust %esp to */
+/* make room for our stack frame. */
+
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset ebp, -8
+ pushl %edi
+ .cfi_def_cfa_offset 12
+ pushl %esi
+ .cfi_def_cfa_offset 16
+ pushl %ebx
+ .cfi_def_cfa_offset 20
+ subl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset LocalVarsSize+20
+
+/* Retrieve the function arguments. %ecx will hold cur_match */
+/* throughout the entire function. %edx will hold the pointer to the */
+/* deflate_state structure during the function's setup (before */
+/* entering the main loop). */
+
+ movl deflatestate(%esp), %edx
+ movl curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask; */
+/* unsigned chain_length = s->max_chain_length; */
+/* if (s->prev_length >= s->good_match) { */
+/* chain_length >>= 2; */
+/* } */
+
+ movl dsPrevLen(%edx), %eax
+ movl dsGoodMatch(%edx), %ebx
+ cmpl %ebx, %eax
+ movl dsWMask(%edx), %eax
+ movl dsMaxChainLen(%edx), %ebx
+ jl LastMatchGood
+ shrl $2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can */
+/* use the sign flag instead of the zero flag for the exit test. */
+/* It is then shifted into the high word, to make room for the wmask */
+/* value, which it will always accompany. */
+
+ decl %ebx
+ shll $16, %ebx
+ orl %eax, %ebx
+ movl %ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
+
+ movl dsNiceMatch(%edx), %eax
+ movl dsLookahead(%edx), %ebx
+ cmpl %eax, %ebx
+ jl LookaheadLess
+ movl %eax, %ebx
+LookaheadLess: movl %ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart; */
+
+ movl dsWindow(%edx), %esi
+ movl %esi, window(%esp)
+ movl dsStrStart(%edx), %ebp
+ lea (%esi,%ebp), %edi
+ movl %edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being */
+/* dword-aligned. */
+
+ movl %edi, %eax
+ negl %eax
+ andl $3, %eax
+ movl %eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
+
+ movl dsWSize(%edx), %eax
+ subl $MIN_LOOKAHEAD, %eax
+ subl %eax, %ebp
+ jg LimitPositive
+ xorl %ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length; */
+
+ movl dsPrevLen(%edx), %eax
+ movl %eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
+
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan; */
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
+/* Posf *prev = s->prev; */
+
+ movzwl (%edi), %ebx
+ movl %ebx, scanstart(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl %ebx, scanend(%esp)
+ movl dsPrev(%edx), %edi
+
+/* Jump into the main loop. */
+
+ movl chainlenwmask(%esp), %edx
+ jmp LoopEntry
+
+.balign 16
+
+/* do {
+ * match = s->window + cur_match;
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
+ * *(ushf*)match != scan_start) continue;
+ * [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ * && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+ andl %edx, %ecx
+ movzwl (%edi,%ecx,2), %ecx
+ cmpl %ebp, %ecx
+ jbe LeaveNow
+ subl $0x00010000, %edx
+ js LeaveNow
+LoopEntry: movzwl -1(%esi,%ecx), %eax
+ cmpl %ebx, %eax
+ jnz LookupLoop
+ movl window(%esp), %eax
+ movzwl (%eax,%ecx), %eax
+ cmpl scanstart(%esp), %eax
+ jnz LookupLoop
+
+/* Store the current value of chainlen. */
+
+ movl %edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we */
+/* are hoping to match it up with. In actuality, %esi and %edi are */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
+/* initialized to -(MAX_MATCH_8 - scanalign). */
+
+ movl window(%esp), %esi
+ movl scan(%esp), %edi
+ addl %ecx, %esi
+ movl scanalign(%esp), %eax
+ movl $(-MAX_MATCH_8), %edx
+ lea MAX_MATCH_8(%edi,%eax), %edi
+ lea MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+ movl (%esi,%edx), %eax
+ xorl (%edi,%edx), %eax
+ jnz LeaveLoopCmps
+ movl 4(%esi,%edx), %eax
+ xorl 4(%edi,%edx), %eax
+ jnz LeaveLoopCmps4
+ addl $8, %edx
+ jnz LoopCmps
+ jmp LenMaximum
+LeaveLoopCmps4: addl $4, %edx
+LeaveLoopCmps: testl $0x0000FFFF, %eax
+ jnz LenLower
+ addl $2, %edx
+ shrl $16, %eax
+LenLower: subb $1, %al
+ adcl $0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
+/* then automatically accept it as the best possible match and leave. */
+
+ lea (%edi,%edx), %eax
+ movl scan(%esp), %edi
+ subl %edi, %eax
+ cmpl $MAX_MATCH, %eax
+ jge LenMaximum
+
+/* If the length of the match is not longer than the best match we */
+/* have so far, then forget it and return to the lookup loop. */
+
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ cmpl %ebx, %eax
+ jg LongerMatch
+ movl windowbestlen(%esp), %esi
+ movl dsPrev(%edx), %edi
+ movl scanend(%esp), %ebx
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* s->match_start = cur_match; */
+/* best_len = len; */
+/* if (len >= nice_match) break; */
+/* scan_end = *(ushf*)(scan+best_len-1); */
+
+LongerMatch: movl nicematch(%esp), %ebx
+ movl %eax, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+ cmpl %ebx, %eax
+ jge LeaveNow
+ movl window(%esp), %esi
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl dsPrev(%edx), %edi
+ movl %ebx, scanend(%esp)
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* Accept the current string, with the maximum possible length. */
+
+LenMaximum: movl deflatestate(%esp), %edx
+ movl $MAX_MATCH, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
+/* return s->lookahead; */
+
+LeaveNow:
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ movl dsLookahead(%edx), %eax
+ cmpl %eax, %ebx
+ jg LookaheadRet
+ movl %ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came. */
+
+ addl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset 20
+ popl %ebx
+ .cfi_def_cfa_offset 16
+ popl %esi
+ .cfi_def_cfa_offset 12
+ popl %edi
+ .cfi_def_cfa_offset 8
+ popl %ebp
+ .cfi_def_cfa_offset 4
+.cfi_endproc
+match_init: ret
diff --git a/usr/src/boot/lib/libz/contrib/gcc_gvmat64/gvmat64.S b/usr/src/boot/lib/libz/contrib/gcc_gvmat64/gvmat64.S
new file mode 100644
index 0000000000..23309fa286
--- /dev/null
+++ b/usr/src/boot/lib/libz/contrib/gcc_gvmat64/gvmat64.S
@@ -0,0 +1,574 @@
+/*
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); // current match
+
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
+; (AMD64 on Athlon 64, Opteron, Phenom
+; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+;
+; This software is provided 'as-is', without any express or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not be
+; misrepresented as being the original software
+; 3. This notice may not be removed or altered from any source distribution.
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for zLib, I use option:
+; gcc -c -arch x86_64 gvmat64.S
+
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; // current match /
+;
+; with XCode for Mac, I had strange error with some jump on intel syntax
+; this is why BEFORE_JMP and AFTER_JMP are used
+ */
+
+
+#define BEFORE_JMP .att_syntax
+#define AFTER_JMP .intel_syntax noprefix
+
+#ifndef NO_UNDERLINE
+# define match_init _match_init
+# define longest_match _longest_match
+#endif
+
+.intel_syntax noprefix
+
+.globl match_init, longest_match
+.text
+longest_match:
+
+
+
+#define LocalVarsSize 96
+/*
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+*/
+
+#define chainlenwmask (rsp + 8 - LocalVarsSize)
+#define nicematch (rsp + 16 - LocalVarsSize)
+
+#define save_rdi (rsp + 24 - LocalVarsSize)
+#define save_rsi (rsp + 32 - LocalVarsSize)
+#define save_rbx (rsp + 40 - LocalVarsSize)
+#define save_rbp (rsp + 48 - LocalVarsSize)
+#define save_r12 (rsp + 56 - LocalVarsSize)
+#define save_r13 (rsp + 64 - LocalVarsSize)
+#define save_r14 (rsp + 72 - LocalVarsSize)
+#define save_r15 (rsp + 80 - LocalVarsSize)
+
+
+/*
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+*/
+
+#define MAX_MATCH 258
+#define MIN_MATCH 3
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+
+/*
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+*/
+
+
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+*/
+
+#define dsWSize 68
+#define dsWMask 76
+#define dsWindow 80
+#define dsPrev 96
+#define dsMatchLen 144
+#define dsPrevMatch 148
+#define dsStrStart 156
+#define dsMatchStart 160
+#define dsLookahead 164
+#define dsPrevLen 168
+#define dsMaxChainLen 172
+#define dsGoodMatch 188
+#define dsNiceMatch 192
+
+#define window_size [ rcx + dsWSize]
+#define WMask [ rcx + dsWMask]
+#define window_ad [ rcx + dsWindow]
+#define prev_ad [ rcx + dsPrev]
+#define strstart [ rcx + dsStrStart]
+#define match_start [ rcx + dsMatchStart]
+#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip
+#define prev_length [ rcx + dsPrevLen]
+#define max_chain_length [ rcx + dsMaxChainLen]
+#define good_match [ rcx + dsGoodMatch]
+#define nice_match [ rcx + dsNiceMatch]
+
+/*
+; windows:
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+;
+; gcc on macosx-linux:
+; see http://www.x86-64.org/documentation/abi-0.99.pdf
+; param 1 in rdi, param 2 in rsi
+; rbx, rsp, rbp, r12 to r15 must be preserved
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+; mac: param 1 in rdi, param 2 rsi
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+*/
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+
+
+ mov rcx,rdi
+
+ mov r8d,esi
+
+
+ mov [save_r12],r12
+ mov [save_r13],r13
+ mov [save_r14],r14
+ mov [save_r15],r15
+
+
+//;;; uInt wmask = s->w_mask;
+//;;; unsigned chain_length = s->max_chain_length;
+//;;; if (s->prev_length >= s->good_match) {
+//;;; chain_length >>= 2;
+//;;; }
+
+
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+//;;; chainlen is decremented once beforehand so that the function can
+//;;; use the sign flag instead of the zero flag for the exit test.
+//;;; It is then shifted into the high word, to make room for the wmask
+//;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+
+//;;; on zlib only
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+
+
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+
+
+
+//;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+
+//;;; Determine how many bytes the scan ptr is off from being
+//;;; dword-aligned.
+
+ mov r9,r13
+ neg r13
+ and r13,3
+
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+//;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+
+
+ xor edi,edi
+ sub ebp, eax
+
+ mov r11d, prev_length
+
+ cmovng ebp,edi
+
+//;;; int best_len = s->prev_length;
+
+
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ lea rsi,[r10+r11]
+
+//;;; register ush scan_start = *(ushf*)scan;
+//;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+//;;; Posf *prev = s->prev;
+
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+
+ mov rdi, prev_ad
+
+//;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+
+
+LookupLoop1:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+
+
+
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry1:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop2:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry2:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop4:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry4:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+ AFTER_JMP
+/*
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+*/
+.balign 16
+LookupLoop:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+
+
+//;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+/*
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+*/
+ lea rsi,[r8+r10]
+ mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
+
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+
+/*
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+*/
+
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+
+
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+
+ add rdx,8+8+8
+
+ BEFORE_JMP
+ jnz LoopCmps
+ jmp LenMaximum
+ AFTER_JMP
+
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+ test eax, 0x0000FFFF
+ jnz LenLower
+
+ test eax,0xffffffff
+
+ jnz LenLower32
+
+ add rdx,4
+ shr rax,32
+ or ax,ax
+ BEFORE_JMP
+ jnz LenLower
+ AFTER_JMP
+
+LenLower32:
+ shr eax,16
+ add rdx,2
+
+LenLower:
+ sub al, 1
+ adc rdx, 0
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+//;;; then automatically accept it as the best possible match and leave.
+
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ BEFORE_JMP
+ jge LenMaximum
+ AFTER_JMP
+/*
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+*/
+ cmp eax, r11d
+ jg LongerMatch
+
+ lea rsi,[r10+r11]
+
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+/*
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+*/
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ BEFORE_JMP
+ jge LeaveNow
+ AFTER_JMP
+
+ lea rsi,[r10+rax]
+
+ movzx ebx, word ptr [r9 + rax - 1]
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+
+//;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+ mov r11d,MAX_MATCH
+ mov match_start, r8d
+
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+//;;; return s->lookahead;
+
+LeaveNow:
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+
+
+
+//;;; Restore the stack and return from whence we came.
+
+
+// mov rsi,[save_rsi]
+// mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+ mov r14,[save_r14]
+ mov r15,[save_r15]
+
+
+ ret 0
+//; please don't remove this string !
+//; Your can freely use gvmat64 in any free or commercial app
+//; but it is far better don't remove the string in the binary!
+ // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+
+
+match_init:
+ ret 0
+
+
diff --git a/usr/src/boot/lib/libz/crc32.c b/usr/src/boot/lib/libz/crc32.c
new file mode 100644
index 0000000000..979a7190a3
--- /dev/null
+++ b/usr/src/boot/lib/libz/crc32.c
@@ -0,0 +1,425 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
+#ifdef BYFOUR
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ z_crc_t c;
+ int n, k;
+ z_crc_t poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (z_crc_t)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = ZSWAP32(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = ZSWAP32(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const z_crc_t FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const z_crc_t FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ z_crc_t endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = (z_crc_t)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = ZSWAP32((z_crc_t)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/usr/src/boot/lib/libz/crc32.h b/usr/src/boot/lib/libz/crc32.h
new file mode 100644
index 0000000000..9e0c778102
--- /dev/null
+++ b/usr/src/boot/lib/libz/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/usr/src/boot/lib/libz/deflate.c b/usr/src/boot/lib/libz/deflate.c
new file mode 100644
index 0000000000..696957705b
--- /dev/null
+++ b/usr/src/boot/lib/libz/deflate.c
@@ -0,0 +1,1967 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://tools.ietf.org/html/rfc1951
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle OF((deflate_state *s, int flush));
+local block_state deflate_huff OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->high_water = 0; /* nothing written to s->window yet */
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt str, n;
+ int wrap;
+ unsigned avail;
+ z_const unsigned char *next;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ wrap = s->wrap;
+ if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+ return Z_STREAM_ERROR;
+
+ /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+ if (wrap == 1)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+ s->wrap = 0; /* avoid computing Adler-32 in read_buf */
+
+ /* if dictionary would fill window, just replace the history */
+ if (dictLength >= s->w_size) {
+ if (wrap == 0) { /* already empty otherwise */
+ CLEAR_HASH(s);
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ dictionary += dictLength - s->w_size; /* use the tail */
+ dictLength = s->w_size;
+ }
+
+ /* insert dictionary into window and hash */
+ avail = strm->avail_in;
+ next = strm->next_in;
+ strm->avail_in = dictLength;
+ strm->next_in = (z_const Bytef *)dictionary;
+ fill_window(s);
+ while (s->lookahead >= MIN_MATCH) {
+ str = s->strstart;
+ n = s->lookahead - (MIN_MATCH-1);
+ do {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ } while (--n);
+ s->strstart = str;
+ s->lookahead = MIN_MATCH-1;
+ fill_window(s);
+ }
+ s->strstart += s->lookahead;
+ s->block_start = (long)s->strstart;
+ s->insert = s->lookahead;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ strm->next_in = next;
+ strm->avail_in = avail;
+ s->wrap = wrap;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ int ret;
+
+ ret = deflateResetKeep(strm);
+ if (ret == Z_OK)
+ lm_init(strm->state);
+ return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+ unsigned *pending;
+ int *bits;
+ z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (pending != Z_NULL)
+ *pending = strm->state->pending;
+ if (bits != Z_NULL)
+ *bits = strm->state->bi_valid;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ deflate_state *s;
+ int put;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ return Z_BUF_ERROR;
+ do {
+ put = Buf_size - s->bi_valid;
+ if (put > bits)
+ put = bits;
+ s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+ s->bi_valid += put;
+ _tr_flush_bits(s);
+ value >>= put;
+ bits -= put;
+ } while (bits);
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if ((strategy != s->strategy || func != configuration_table[level].func) &&
+ strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_BLOCK);
+ if (err == Z_BUF_ERROR && s->pending == 0)
+ err = Z_OK;
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = good_length;
+ s->max_lazy_match = max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = max_chain;
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel. But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong complen, wraplen;
+ Bytef *str;
+
+ /* conservative upper bound for compressed data */
+ complen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+ /* if can't get parameters, return conservative bound plus zlib wrapper */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return complen + 6;
+
+ /* compute wrapper length */
+ s = strm->state;
+ switch (s->wrap) {
+ case 0: /* raw deflate */
+ wraplen = 0;
+ break;
+ case 1: /* zlib wrapper */
+ wraplen = 6 + (s->strstart ? 4 : 0);
+ break;
+ case 2: /* gzip wrapper */
+ wraplen = 18;
+ if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
+ if (s->gzhead->extra != Z_NULL)
+ wraplen += 2 + s->gzhead->extra_len;
+ str = s->gzhead->name;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ str = s->gzhead->comment;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ if (s->gzhead->hcrc)
+ wraplen += 2;
+ }
+ break;
+ default: /* for compiler happiness */
+ wraplen = 6;
+ }
+
+ /* if not default parameters, return conservative bound */
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return complen + wraplen;
+
+ /* default settings: return tight bound for that case */
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len;
+ deflate_state *s = strm->state;
+
+ _tr_flush_bits(s);
+ len = s->pending;
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, s->pending_out, len);
+ strm->next_out += len;
+ s->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ s->pending -= len;
+ if (s->pending == 0) {
+ s->pending_out = s->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_BLOCK || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == Z_NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != Z_NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+#ifdef GZIP
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != Z_NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+
+ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size)
+ break;
+ }
+ put_byte(s, s->gzhead->extra[s->gzindex]);
+ s->gzindex++;
+ }
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (s->gzindex == s->gzhead->extra_len) {
+ s->gzindex = 0;
+ s->status = NAME_STATE;
+ }
+ }
+ else
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != Z_NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0) {
+ s->gzindex = 0;
+ s->status = COMMENT_STATE;
+ }
+ }
+ else
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != Z_NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0)
+ s->status = HCRC_STATE;
+ }
+ else
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size)
+ flush_pending(strm);
+ if (s->pending + 2 <= s->pending_buf_size) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+ }
+ }
+ else
+ s->status = BUSY_STATE;
+ }
+#endif
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush));
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ if (s->lookahead == 0) {
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE &&
+ status != EXTRA_STATE &&
+ status != NAME_STATE &&
+ status != COMMENT_STATE &&
+ status != HCRC_STATE &&
+ status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ zmemcpy(buf, strm->next_in, len);
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, buf, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, buf, len);
+ }
+#endif
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->insert = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) break;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead + s->insert >= MIN_MATCH) {
+ uInt str = s->strstart - s->insert;
+ s->ins_h = s->window[str];
+ UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ while (s->insert) {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ s->insert--;
+ if (s->lookahead + s->insert < MIN_MATCH)
+ break;
+ }
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+ /* If the WIN_INIT bytes after the end of the current data have never been
+ * written, then zero those bytes in order to avoid memory check reports of
+ * the use of uninitialized (or uninitialised as Julian writes) bytes by
+ * the longest match routines. Update the high water mark for the next
+ * time through here. WIN_INIT is set to MAX_MATCH since the longest match
+ * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+ */
+ if (s->high_water < s->window_size) {
+ ulg curr = s->strstart + (ulg)(s->lookahead);
+ ulg init;
+
+ if (s->high_water < curr) {
+ /* Previous high water mark below current data -- zero WIN_INIT
+ * bytes or up to end of window, whichever is less.
+ */
+ init = s->window_size - curr;
+ if (init > WIN_INIT)
+ init = WIN_INIT;
+ zmemzero(s->window + curr, (unsigned)init);
+ s->high_water = curr + init;
+ }
+ else if (s->high_water < (ulg)curr + WIN_INIT) {
+ /* High water mark at or above current data, but below current data
+ * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+ * to end of window, whichever is less.
+ */
+ init = (ulg)curr + WIN_INIT - s->high_water;
+ if (init > s->window_size - s->high_water)
+ init = s->window_size - s->high_water;
+ zmemzero(s->window + s->high_water, (unsigned)init);
+ s->high_water += init;
+ }
+ }
+
+ Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+ "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (last)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+ FLUSH_BLOCK_ONLY(s, last); \
+ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if ((long)s->strstart > s->block_start)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan, *strend; /* scan goes up to strend for length of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest run, plus one for the unrolled loop.
+ */
+ if (s->lookahead <= MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ s->match_length = 0;
+ if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+ scan = s->window + s->strstart - 1;
+ prev = *scan;
+ if (prev == *++scan && prev == *++scan && prev == *++scan) {
+ strend = s->window + s->strstart + MAX_MATCH;
+ do {
+ } while (prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ scan < strend);
+ s->match_length = MAX_MATCH - (int)(strend - scan);
+ if (s->match_length > s->lookahead)
+ s->match_length = s->lookahead;
+ }
+ Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+ _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we have a literal to write. */
+ if (s->lookahead == 0) {
+ fill_window(s);
+ if (s->lookahead == 0) {
+ if (flush == Z_NO_FLUSH)
+ return need_more;
+ break; /* flush the current block */
+ }
+ }
+
+ /* Output a literal byte */
+ s->match_length = 0;
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
diff --git a/usr/src/boot/lib/libz/deflate.h b/usr/src/boot/lib/libz/deflate.h
new file mode 100644
index 0000000000..ce0299edd1
--- /dev/null
+++ b/usr/src/boot/lib/libz/deflate.h
@@ -0,0 +1,346 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE 42
+#define EXTRA_STATE 69
+#define NAME_STATE 73
+#define COMMENT_STATE 91
+#define HCRC_STATE 103
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ uInt pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ uInt gzindex; /* where in extra, name, or comment */
+ Byte method; /* can only be DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to suppress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ uInt insert; /* bytes at end of window left to insert */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+ ulg high_water;
+ /* High water mark offset in window for initialized bytes -- bytes above
+ * this are set to zero in order to avoid memory check warnings when
+ * longest match routines access bytes past the input. This is then
+ * updated to the new high water mark.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+ memory checker errors from longest match routines */
+
+ /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch ZLIB_INTERNAL _length_code[];
+ extern uch ZLIB_INTERNAL _dist_code[];
+#else
+ extern const uch ZLIB_INTERNAL _length_code[];
+ extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/usr/src/boot/lib/libz/doc/algorithm.txt b/usr/src/boot/lib/libz/doc/algorithm.txt
new file mode 100644
index 0000000000..c97f495020
--- /dev/null
+++ b/usr/src/boot/lib/libz/doc/algorithm.txt
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data. The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length). Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes. (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast. The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code. It gets that many bits from the
+stream, and looks it up in the table. The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table. If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code. However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table. What inflate() does is
+simply to make the number of bits in the first table a variable, and then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits. Also the distance trees have 30 possible
+values, and the size of the first table is six bits. Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like. You are correct that it's not a Huffman tree. It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol. The
+symbol could be as short as one bit or as long as 15 bits. If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits. For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits. Again, there are duplicated
+entries as needed. The idea is that most of the time the symbol will be short
+and there will only be one table look up. (That's whole idea behind data
+compression in the first place.) For the less frequent long symbols, there
+will be two lookups. If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient. For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble. Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is? The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols. At the
+other extreme, you could make a new table for every bit in the code. In fact,
+that's essentially a Huffman tree. But then you spend too much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble. Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed. That's compared to 64 entries for a single table. Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table). Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol. That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on. For inflate, the
+meaning of a particular symbol is often more than just a letter. It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value. Or it might be the special end-of-block code. The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://tools.ietf.org/html/rfc1951
diff --git a/usr/src/boot/lib/libz/doc/rfc1950.txt b/usr/src/boot/lib/libz/doc/rfc1950.txt
new file mode 100644
index 0000000000..ce6428a0f2
--- /dev/null
+++ b/usr/src/boot/lib/libz/doc/rfc1950.txt
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1950 Aladdin Enterprises
+Category: Informational J-L. Gailly
+ Info-ZIP
+ May 1996
+
+
+ ZLIB Compressed Data Format Specification version 3.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format. The
+ data can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a priori
+ bounded amount of intermediate storage. The format presently uses
+ the DEFLATE compression method but can be easily extended to use
+ other compression methods. It can be implemented readily in a manner
+ not covered by patents. This specification also defines the ADLER-32
+ checksum (an extension and improvement of the Fletcher checksum),
+ used for detection of data corruption, and provides an algorithm for
+ computing it.
+
+
+
+
+Deutsch & Gailly Informational [Page 1]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................ 3
+ 1.6. Changes from previous versions ............................ 3
+ 2. Detailed specification ......................................... 3
+ 2.1. Overall conventions ....................................... 3
+ 2.2. Data format ............................................... 4
+ 2.3. Compliance ................................................ 7
+ 3. References ..................................................... 7
+ 4. Source code .................................................... 8
+ 5. Security Considerations ........................................ 8
+ 6. Acknowledgements ............................................... 8
+ 7. Authors' Addresses ............................................. 8
+ 8. Appendix: Rationale ............................................ 9
+ 9. Appendix: Sample code ..........................................10
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+
+ * Can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a
+ priori bounded amount of intermediate storage, and hence can
+ be used in data communications or similar structures such as
+ Unix filters;
+
+ * Can use a number of different compression methods;
+
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely.
+
+ The data format defined by this specification does not attempt to
+ allow random access to compressed data.
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 2]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into zlib format and/or decompress data from zlib
+ format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations.
+
+ 1.3. Scope
+
+ The specification specifies a compressed data format that can be
+ used for in-memory compression of a sequence of arbitrary bytes.
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any data set that conforms to all
+ the specifications presented here; a compliant compressor must
+ produce data sets that conform to all the specifications presented
+ here.
+
+ 1.5. Definitions of terms and conventions used
+
+ byte: 8 bits stored or transmitted as a unit (same as an octet).
+ (For this specification, a byte is exactly 8 bits, even on
+ machines which store a character on a number of bits different
+ from 8.) See below, for the numbering of bits within a byte.
+
+ 1.6. Changes from previous versions
+
+ Version 3.1 was the first public release of this specification.
+ In version 3.2, some terminology was changed and the Adler-32
+ sample code was rewritten for clarity. In version 3.3, the
+ support for a preset dictionary was introduced, and the
+ specification was converted to RFC style.
+
+2. Detailed specification
+
+ 2.1. Overall conventions
+
+ In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+
+
+
+Deutsch & Gailly Informational [Page 3]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the MOST-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00000010|00001000|
+ +--------+--------+
+ ^ ^
+ | |
+ | + less significant byte = 8
+ + more significant byte = 2 x 256
+
+ 2.2. Data format
+
+ A zlib stream has the following structure:
+
+ 0 1
+ +---+---+
+ |CMF|FLG| (more-->)
+ +---+---+
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 4]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ (if FLG.FDICT set)
+
+ 0 1 2 3
+ +---+---+---+---+
+ | DICTID | (more-->)
+ +---+---+---+---+
+
+ +=====================+---+---+---+---+
+ |...compressed data...| ADLER32 |
+ +=====================+---+---+---+---+
+
+ Any data which may appear after ADLER32 are not part of the zlib
+ stream.
+
+ CMF (Compression Method and flags)
+ This byte is divided into a 4-bit compression method and a 4-
+ bit information field depending on the compression method.
+
+ bits 0 to 3 CM Compression method
+ bits 4 to 7 CINFO Compression info
+
+ CM (Compression method)
+ This identifies the compression method used in the file. CM = 8
+ denotes the "deflate" compression method with a window size up
+ to 32K. This is the method used by gzip and PNG (see
+ references [1] and [2] in Chapter 3, below, for the reference
+ documents). CM = 15 is reserved. It might be used in a future
+ version of this specification to indicate the presence of an
+ extra field before the compressed data.
+
+ CINFO (Compression info)
+ For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
+ size, minus eight (CINFO=7 indicates a 32K window size). Values
+ of CINFO above 7 are not allowed in this version of the
+ specification. CINFO is not defined in this specification for
+ CM not equal to 8.
+
+ FLG (FLaGs)
+ This flag byte is divided as follows:
+
+ bits 0 to 4 FCHECK (check bits for CMF and FLG)
+ bit 5 FDICT (preset dictionary)
+ bits 6 to 7 FLEVEL (compression level)
+
+ The FCHECK value must be such that CMF and FLG, when viewed as
+ a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
+ is a multiple of 31.
+
+
+
+
+Deutsch & Gailly Informational [Page 5]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ FDICT (Preset dictionary)
+ If FDICT is set, a DICT dictionary identifier is present
+ immediately after the FLG byte. The dictionary is a sequence of
+ bytes which are initially fed to the compressor without
+ producing any compressed output. DICT is the Adler-32 checksum
+ of this sequence of bytes (see the definition of ADLER32
+ below). The decompressor can use this identifier to determine
+ which dictionary has been used by the compressor.
+
+ FLEVEL (Compression level)
+ These flags are available for use by specific compression
+ methods. The "deflate" method (CM = 8) sets these flags as
+ follows:
+
+ 0 - compressor used fastest algorithm
+ 1 - compressor used fast algorithm
+ 2 - compressor used default algorithm
+ 3 - compressor used maximum compression, slowest algorithm
+
+ The information in FLEVEL is not needed for decompression; it
+ is there to indicate if recompression might be worthwhile.
+
+ compressed data
+ For compression method 8, the compressed data is stored in the
+ deflate compressed data format as described in the document
+ "DEFLATE Compressed Data Format Specification" by L. Peter
+ Deutsch. (See reference [3] in Chapter 3, below)
+
+ Other compressed data formats are not specified in this version
+ of the zlib specification.
+
+ ADLER32 (Adler-32 checksum)
+ This contains a checksum value of the uncompressed data
+ (excluding any dictionary data) computed according to Adler-32
+ algorithm. This algorithm is a 32-bit extension and improvement
+ of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+ standard. See references [4] and [5] in Chapter 3, below)
+
+ Adler-32 is composed of two sums accumulated per byte: s1 is
+ the sum of all bytes, s2 is the sum of all s1 values. Both sums
+ are done modulo 65521. s1 is initialized to 1, s2 to zero. The
+ Adler-32 checksum is stored as s2*65536 + s1 in most-
+ significant-byte first (network) order.
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 6]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ 2.3. Compliance
+
+ A compliant compressor must produce streams with correct CMF, FLG
+ and ADLER32, but need not support preset dictionaries. When the
+ zlib data format is used as part of another standard data format,
+ the compressor may use only preset dictionaries that are specified
+ by this other data format. If this other format does not use the
+ preset dictionary feature, the compressor must not set the FDICT
+ flag.
+
+ A compliant decompressor must check CMF, FLG, and ADLER32, and
+ provide an error indication if any of these have incorrect values.
+ A compliant decompressor must give an error indication if CM is
+ not one of the values defined in this specification (only the
+ value 8 is permitted in this version), since another value could
+ indicate the presence of new features that would cause subsequent
+ data to be interpreted incorrectly. A compliant decompressor must
+ give an error indication if FDICT is set and DICTID is not the
+ identifier of a known preset dictionary. A decompressor may
+ ignore FLEVEL and still be compliant. When the zlib data format
+ is being used as a part of another standard format, a compliant
+ decompressor must support all the preset dictionaries specified by
+ the other format. When the other format does not use the preset
+ dictionary feature, a compliant decompressor must reject any
+ stream in which the FDICT flag is set.
+
+3. References
+
+ [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
+ available in ftp://ftp.uu.net/graphics/png/documents/
+
+ [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [4] Fletcher, J. G., "An Arithmetic Checksum for Serial
+ Transmissions," IEEE Transactions on Communications, Vol. COM-30,
+ No. 1, January 1982, pp. 247-252.
+
+ [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
+ November, 1993, pp. 144, 145. (Available from
+ gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 7]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+4. Source code
+
+ Source code for a C language implementation of a "zlib" compliant
+ library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+5. Security Considerations
+
+ A decoder that fails to check the ADLER32 checksum value may be
+ subject to undetected data corruption.
+
+6. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
+ the related software described in this specification. Glenn
+ Randers-Pehrson converted this document to RFC and HTML format.
+
+7. Authors' Addresses
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+
+ Jean-Loup Gailly
+
+ EMail: <gzip@prep.ai.mit.edu>
+
+ Questions about the technical content of this specification can be
+ sent by email to
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 8]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+8. Appendix: Rationale
+
+ 8.1. Preset dictionaries
+
+ A preset dictionary is specially useful to compress short input
+ sequences. The compressor can take advantage of the dictionary
+ context to encode the input in a more compact manner. The
+ decompressor can be initialized with the appropriate context by
+ virtually decompressing a compressed version of the dictionary
+ without producing any output. However for certain compression
+ algorithms such as the deflate algorithm this operation can be
+ achieved without actually performing any decompression.
+
+ The compressor and the decompressor must use exactly the same
+ dictionary. The dictionary may be fixed or may be chosen among a
+ certain number of predefined dictionaries, according to the kind
+ of input data. The decompressor can determine which dictionary has
+ been chosen by the compressor by checking the dictionary
+ identifier. This document does not specify the contents of
+ predefined dictionaries, since the optimal dictionaries are
+ application specific. Standard data formats using this feature of
+ the zlib specification must precisely define the allowed
+ dictionaries.
+
+ 8.2. The Adler-32 algorithm
+
+ The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+ still provides an extremely low probability of undetected errors.
+
+ The modulo on unsigned long accumulators can be delayed for 5552
+ bytes, so the modulo operation time is negligible. If the bytes
+ are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+ and order sensitive, unlike the first sum, which is just a
+ checksum. That 65521 is prime is important to avoid a possible
+ large class of two-byte errors that leave the check unchanged.
+ (The Fletcher checksum uses 255, which is not prime and which also
+ makes the Fletcher check insensitive to single byte changes 0 <->
+ 255.)
+
+ The sum s1 is initialized to 1 instead of zero to make the length
+ of the sequence part of s2, so that the length does not have to be
+ checked separately. (Any sequence of zeroes has a Fletcher
+ checksum of zero.)
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 9]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+9. Appendix: Sample code
+
+ The following C code computes the Adler-32 checksum of a data buffer.
+ It is written for clarity, not for speed. The sample code is in the
+ ANSI C programming language. Non C users may find it easier to read
+ with these hints:
+
+ & Bitwise AND operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero bit(s)
+ at the left.
+ << Bitwise left shift operator. Left shift inserts zero
+ bit(s) at the right.
+ ++ "n++" increments the variable n.
+ % modulo operator: a % b is the remainder of a divided by b.
+
+ #define BASE 65521 /* largest prime smaller than 65536 */
+
+ /*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1]
+ and return the updated checksum. The Adler-32 checksum should be
+ initialized to 1.
+
+ Usage example:
+
+ unsigned long adler = 1L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = update_adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+ */
+ unsigned long update_adler32(unsigned long adler,
+ unsigned char *buf, int len)
+ {
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int n;
+
+ for (n = 0; n < len; n++) {
+ s1 = (s1 + buf[n]) % BASE;
+ s2 = (s2 + s1) % BASE;
+ }
+ return (s2 << 16) + s1;
+ }
+
+ /* Return the adler32 of the bytes buf[0..len-1] */
+
+
+
+
+Deutsch & Gailly Informational [Page 10]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ unsigned long adler32(unsigned char *buf, int len)
+ {
+ return update_adler32(1L, buf, len);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 11]
+
diff --git a/usr/src/boot/lib/libz/doc/rfc1951.txt b/usr/src/boot/lib/libz/doc/rfc1951.txt
new file mode 100644
index 0000000000..403c8c722f
--- /dev/null
+++ b/usr/src/boot/lib/libz/doc/rfc1951.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1951 Aladdin Enterprises
+Category: Informational May 1996
+
+
+ DEFLATE Compressed Data Format Specification version 1.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format that
+ compresses data using a combination of the LZ77 algorithm and Huffman
+ coding, with efficiency comparable to the best currently available
+ general-purpose compression methods. The data can be produced or
+ consumed, even for an arbitrarily long sequentially presented input
+ data stream, using only an a priori bounded amount of intermediate
+ storage. The format can be implemented readily in a manner not
+ covered by patents.
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 1]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................ 3
+ 1.6. Changes from previous versions ............................ 4
+ 2. Compressed representation overview ............................. 4
+ 3. Detailed specification ......................................... 5
+ 3.1. Overall conventions ....................................... 5
+ 3.1.1. Packing into bytes .................................. 5
+ 3.2. Compressed block format ................................... 6
+ 3.2.1. Synopsis of prefix and Huffman coding ............... 6
+ 3.2.2. Use of Huffman coding in the "deflate" format ....... 7
+ 3.2.3. Details of block format ............................. 9
+ 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
+ 3.2.5. Compressed blocks (length and distance codes) ...... 11
+ 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
+ 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
+ 3.3. Compliance ............................................... 14
+ 4. Compression algorithm details ................................. 14
+ 5. References .................................................... 16
+ 6. Security Considerations ....................................... 16
+ 7. Source code ................................................... 16
+ 8. Acknowledgements .............................................. 16
+ 9. Author's Address .............................................. 17
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+ * Can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a
+ priori bounded amount of intermediate storage, and hence
+ can be used in data communications or similar structures
+ such as Unix filters;
+ * Compresses data with efficiency comparable to the best
+ currently available general-purpose compression methods,
+ and in particular considerably better than the "compress"
+ program;
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely;
+
+
+
+Deutsch Informational [Page 2]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ * Is compatible with the file format produced by the current
+ widely used gzip utility, in that conforming decompressors
+ will be able to read data produced by the existing gzip
+ compressor.
+
+ The data format defined by this specification does not attempt to:
+
+ * Allow random access to compressed data;
+ * Compress specialized data (e.g., raster graphics) as well
+ as the best currently available specialized algorithms.
+
+ A simple counting argument shows that no lossless compression
+ algorithm can compress every possible input data set. For the
+ format defined here, the worst case expansion is 5 bytes per 32K-
+ byte block, i.e., a size increase of 0.015% for large data sets.
+ English text usually compresses by a factor of 2.5 to 3;
+ executable files usually compress somewhat less; graphical data
+ such as raster images may compress much more.
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into "deflate" format and/or decompress data from
+ "deflate" format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations. Familiarity with the technique of Huffman coding
+ is helpful but not required.
+
+ 1.3. Scope
+
+ The specification specifies a method for representing a sequence
+ of bytes as a (usually shorter) sequence of bits, and a method for
+ packing the latter bit sequence into bytes.
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any data set that conforms to all
+ the specifications presented here; a compliant compressor must
+ produce data sets that conform to all the specifications presented
+ here.
+
+ 1.5. Definitions of terms and conventions used
+
+ Byte: 8 bits stored or transmitted as a unit (same as an octet).
+ For this specification, a byte is exactly 8 bits, even on machines
+
+
+
+Deutsch Informational [Page 3]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ which store a character on a number of bits different from eight.
+ See below, for the numbering of bits within a byte.
+
+ String: a sequence of arbitrary bytes.
+
+ 1.6. Changes from previous versions
+
+ There have been no technical changes to the deflate format since
+ version 1.1 of this specification. In version 1.2, some
+ terminology was changed. Version 1.3 is a conversion of the
+ specification to RFC style.
+
+2. Compressed representation overview
+
+ A compressed data set consists of a series of blocks, corresponding
+ to successive blocks of input data. The block sizes are arbitrary,
+ except that non-compressible blocks are limited to 65,535 bytes.
+
+ Each block is compressed using a combination of the LZ77 algorithm
+ and Huffman coding. The Huffman trees for each block are independent
+ of those for previous or subsequent blocks; the LZ77 algorithm may
+ use a reference to a duplicated string occurring in a previous block,
+ up to 32K input bytes before.
+
+ Each block consists of two parts: a pair of Huffman code trees that
+ describe the representation of the compressed data part, and a
+ compressed data part. (The Huffman trees themselves are compressed
+ using Huffman encoding.) The compressed data consists of a series of
+ elements of two types: literal bytes (of strings that have not been
+ detected as duplicated within the previous 32K input bytes), and
+ pointers to duplicated strings, where a pointer is represented as a
+ pair <length, backward distance>. The representation used in the
+ "deflate" format limits distances to 32K bytes and lengths to 258
+ bytes, but does not limit the size of a block, except for
+ uncompressible blocks, which are limited as noted above.
+
+ Each type of value (literals, distances, and lengths) in the
+ compressed data is represented using a Huffman code, using one code
+ tree for literals and lengths and a separate code tree for distances.
+ The code trees for each block appear in a compact form just before
+ the compressed data for that block.
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 4]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+3. Detailed specification
+
+ 3.1. Overall conventions In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the least-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00001000|00000010|
+ +--------+--------+
+ ^ ^
+ | |
+ | + more significant byte = 2 x 256
+ + less significant byte = 8
+
+ 3.1.1. Packing into bytes
+
+ This document does not address the issue of the order in which
+ bits of a byte are transmitted on a bit-sequential medium,
+ since the final data format described here is byte- rather than
+
+
+
+Deutsch Informational [Page 5]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ bit-oriented. However, we describe the compressed block format
+ in below, as a sequence of data elements of various bit
+ lengths, not a sequence of bytes. We must therefore specify
+ how to pack these data elements into bytes to form the final
+ compressed byte sequence:
+
+ * Data elements are packed into bytes in order of
+ increasing bit number within the byte, i.e., starting
+ with the least-significant bit of the byte.
+ * Data elements other than Huffman codes are packed
+ starting with the least-significant bit of the data
+ element.
+ * Huffman codes are packed starting with the most-
+ significant bit of the code.
+
+ In other words, if one were to print out the compressed data as
+ a sequence of bytes, starting with the first byte at the
+ *right* margin and proceeding to the *left*, with the most-
+ significant bit of each byte on the left as usual, one would be
+ able to parse the result from right to left, with fixed-width
+ elements in the correct MSB-to-LSB order and Huffman codes in
+ bit-reversed order (i.e., with the first bit of the code in the
+ relative LSB position).
+
+ 3.2. Compressed block format
+
+ 3.2.1. Synopsis of prefix and Huffman coding
+
+ Prefix coding represents symbols from an a priori known
+ alphabet by bit sequences (codes), one code for each symbol, in
+ a manner such that different symbols may be represented by bit
+ sequences of different lengths, but a parser can always parse
+ an encoded string unambiguously symbol-by-symbol.
+
+ We define a prefix code in terms of a binary tree in which the
+ two edges descending from each non-leaf node are labeled 0 and
+ 1 and in which the leaf nodes correspond one-for-one with (are
+ labeled with) the symbols of the alphabet; then the code for a
+ symbol is the sequence of 0's and 1's on the edges leading from
+ the root to the leaf labeled with that symbol. For example:
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 6]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ /\ Symbol Code
+ 0 1 ------ ----
+ / \ A 00
+ /\ B B 1
+ 0 1 C 011
+ / \ D 010
+ A /\
+ 0 1
+ / \
+ D C
+
+ A parser can decode the next symbol from an encoded input
+ stream by walking down the tree from the root, at each step
+ choosing the edge corresponding to the next input bit.
+
+ Given an alphabet with known symbol frequencies, the Huffman
+ algorithm allows the construction of an optimal prefix code
+ (one which represents strings with those symbol frequencies
+ using the fewest bits of any possible prefix codes for that
+ alphabet). Such a code is called a Huffman code. (See
+ reference [1] in Chapter 5, references for additional
+ information on Huffman codes.)
+
+ Note that in the "deflate" format, the Huffman codes for the
+ various alphabets must not exceed certain maximum code lengths.
+ This constraint complicates the algorithm for computing code
+ lengths from symbol frequencies. Again, see Chapter 5,
+ references for details.
+
+ 3.2.2. Use of Huffman coding in the "deflate" format
+
+ The Huffman codes used for each alphabet in the "deflate"
+ format have two additional rules:
+
+ * All codes of a given bit length have lexicographically
+ consecutive values, in the same order as the symbols
+ they represent;
+
+ * Shorter codes lexicographically precede longer codes.
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 7]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ We could recode the example above to follow this rule as
+ follows, assuming that the order of the alphabet is ABCD:
+
+ Symbol Code
+ ------ ----
+ A 10
+ B 0
+ C 110
+ D 111
+
+ I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
+ lexicographically consecutive.
+
+ Given this rule, we can define the Huffman code for an alphabet
+ just by giving the bit lengths of the codes for each symbol of
+ the alphabet in order; this is sufficient to determine the
+ actual codes. In our example, the code is completely defined
+ by the sequence of bit lengths (2, 1, 3, 3). The following
+ algorithm generates the codes as integers, intended to be read
+ from most- to least-significant bit. The code lengths are
+ initially in tree[I].Len; the codes are produced in
+ tree[I].Code.
+
+ 1) Count the number of codes for each code length. Let
+ bl_count[N] be the number of codes of length N, N >= 1.
+
+ 2) Find the numerical value of the smallest code for each
+ code length:
+
+ code = 0;
+ bl_count[0] = 0;
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ code = (code + bl_count[bits-1]) << 1;
+ next_code[bits] = code;
+ }
+
+ 3) Assign numerical values to all codes, using consecutive
+ values for all codes of the same length with the base
+ values determined at step 2. Codes that are never used
+ (which have a bit length of zero) must not be assigned a
+ value.
+
+ for (n = 0; n <= max_code; n++) {
+ len = tree[n].Len;
+ if (len != 0) {
+ tree[n].Code = next_code[len];
+ next_code[len]++;
+ }
+
+
+
+Deutsch Informational [Page 8]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ }
+
+ Example:
+
+ Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
+ 3, 2, 4, 4). After step 1, we have:
+
+ N bl_count[N]
+ - -----------
+ 2 1
+ 3 5
+ 4 2
+
+ Step 2 computes the following next_code values:
+
+ N next_code[N]
+ - ------------
+ 1 0
+ 2 0
+ 3 2
+ 4 14
+
+ Step 3 produces the following code values:
+
+ Symbol Length Code
+ ------ ------ ----
+ A 3 010
+ B 3 011
+ C 3 100
+ D 3 101
+ E 3 110
+ F 2 00
+ G 4 1110
+ H 4 1111
+
+ 3.2.3. Details of block format
+
+ Each block of compressed data begins with 3 header bits
+ containing the following data:
+
+ first bit BFINAL
+ next 2 bits BTYPE
+
+ Note that the header bits do not necessarily begin on a byte
+ boundary, since a block does not necessarily occupy an integral
+ number of bytes.
+
+
+
+
+
+Deutsch Informational [Page 9]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ BFINAL is set if and only if this is the last block of the data
+ set.
+
+ BTYPE specifies how the data are compressed, as follows:
+
+ 00 - no compression
+ 01 - compressed with fixed Huffman codes
+ 10 - compressed with dynamic Huffman codes
+ 11 - reserved (error)
+
+ The only difference between the two compressed cases is how the
+ Huffman codes for the literal/length and distance alphabets are
+ defined.
+
+ In all cases, the decoding algorithm for the actual data is as
+ follows:
+
+ do
+ read block header from input stream.
+ if stored with no compression
+ skip any remaining bits in current partially
+ processed byte
+ read LEN and NLEN (see next section)
+ copy LEN bytes of data to output
+ otherwise
+ if compressed with dynamic Huffman codes
+ read representation of code trees (see
+ subsection below)
+ loop (until end of block code recognized)
+ decode literal/length value from input stream
+ if value < 256
+ copy value (literal byte) to output stream
+ otherwise
+ if value = end of block (256)
+ break from loop
+ otherwise (value = 257..285)
+ decode distance from input stream
+
+ move backwards distance bytes in the output
+ stream, and copy length bytes from this
+ position to the output stream.
+ end loop
+ while not last block
+
+ Note that a duplicated string reference may refer to a string
+ in a previous block; i.e., the backward distance may cross one
+ or more block boundaries. However a distance cannot refer past
+ the beginning of the output stream. (An application using a
+
+
+
+Deutsch Informational [Page 10]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ preset dictionary might discard part of the output stream; a
+ distance can refer to that part of the output stream anyway)
+ Note also that the referenced string may overlap the current
+ position; for example, if the last 2 bytes decoded have values
+ X and Y, a string reference with <length = 5, distance = 2>
+ adds X,Y,X,Y,X to the output stream.
+
+ We now specify each compression method in turn.
+
+ 3.2.4. Non-compressed blocks (BTYPE=00)
+
+ Any bits of input up to the next byte boundary are ignored.
+ The rest of the block consists of the following information:
+
+ 0 1 2 3 4...
+ +---+---+---+---+================================+
+ | LEN | NLEN |... LEN bytes of literal data...|
+ +---+---+---+---+================================+
+
+ LEN is the number of data bytes in the block. NLEN is the
+ one's complement of LEN.
+
+ 3.2.5. Compressed blocks (length and distance codes)
+
+ As noted above, encoded data blocks in the "deflate" format
+ consist of sequences of symbols drawn from three conceptually
+ distinct alphabets: either literal bytes, from the alphabet of
+ byte values (0..255), or <length, backward distance> pairs,
+ where the length is drawn from (3..258) and the distance is
+ drawn from (1..32,768). In fact, the literal and length
+ alphabets are merged into a single alphabet (0..285), where
+ values 0..255 represent literal bytes, the value 256 indicates
+ end-of-block, and values 257..285 represent length codes
+ (possibly in conjunction with extra bits following the symbol
+ code) as follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 11]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ Extra Extra Extra
+ Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
+ ---- ---- ------ ---- ---- ------- ---- ---- -------
+ 257 0 3 267 1 15,16 277 4 67-82
+ 258 0 4 268 1 17,18 278 4 83-98
+ 259 0 5 269 2 19-22 279 4 99-114
+ 260 0 6 270 2 23-26 280 4 115-130
+ 261 0 7 271 2 27-30 281 5 131-162
+ 262 0 8 272 2 31-34 282 5 163-194
+ 263 0 9 273 3 35-42 283 5 195-226
+ 264 0 10 274 3 43-50 284 5 227-257
+ 265 1 11,12 275 3 51-58 285 0 258
+ 266 1 13,14 276 3 59-66
+
+ The extra bits should be interpreted as a machine integer
+ stored with the most-significant bit first, e.g., bits 1110
+ represent the value 14.
+
+ Extra Extra Extra
+ Code Bits Dist Code Bits Dist Code Bits Distance
+ ---- ---- ---- ---- ---- ------ ---- ---- --------
+ 0 0 1 10 4 33-48 20 9 1025-1536
+ 1 0 2 11 4 49-64 21 9 1537-2048
+ 2 0 3 12 5 65-96 22 10 2049-3072
+ 3 0 4 13 5 97-128 23 10 3073-4096
+ 4 1 5,6 14 6 129-192 24 11 4097-6144
+ 5 1 7,8 15 6 193-256 25 11 6145-8192
+ 6 2 9-12 16 7 257-384 26 12 8193-12288
+ 7 2 13-16 17 7 385-512 27 12 12289-16384
+ 8 3 17-24 18 8 513-768 28 13 16385-24576
+ 9 3 25-32 19 8 769-1024 29 13 24577-32768
+
+ 3.2.6. Compression with fixed Huffman codes (BTYPE=01)
+
+ The Huffman codes for the two alphabets are fixed, and are not
+ represented explicitly in the data. The Huffman code lengths
+ for the literal/length alphabet are:
+
+ Lit Value Bits Codes
+ --------- ---- -----
+ 0 - 143 8 00110000 through
+ 10111111
+ 144 - 255 9 110010000 through
+ 111111111
+ 256 - 279 7 0000000 through
+ 0010111
+ 280 - 287 8 11000000 through
+ 11000111
+
+
+
+Deutsch Informational [Page 12]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ The code lengths are sufficient to generate the actual codes,
+ as described above; we show the codes in the table for added
+ clarity. Literal/length values 286-287 will never actually
+ occur in the compressed data, but participate in the code
+ construction.
+
+ Distance codes 0-31 are represented by (fixed-length) 5-bit
+ codes, with possible additional bits as shown in the table
+ shown in Paragraph 3.2.5, above. Note that distance codes 30-
+ 31 will never actually occur in the compressed data.
+
+ 3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
+
+ The Huffman codes for the two alphabets appear in the block
+ immediately after the header bits and before the actual
+ compressed data, first the literal/length code and then the
+ distance code. Each code is defined by a sequence of code
+ lengths, as discussed in Paragraph 3.2.2, above. For even
+ greater compactness, the code length sequences themselves are
+ compressed using a Huffman code. The alphabet for code lengths
+ is as follows:
+
+ 0 - 15: Represent code lengths of 0 - 15
+ 16: Copy the previous code length 3 - 6 times.
+ The next 2 bits indicate repeat length
+ (0 = 3, ... , 3 = 6)
+ Example: Codes 8, 16 (+2 bits 11),
+ 16 (+2 bits 10) will expand to
+ 12 code lengths of 8 (1 + 6 + 5)
+ 17: Repeat a code length of 0 for 3 - 10 times.
+ (3 bits of length)
+ 18: Repeat a code length of 0 for 11 - 138 times
+ (7 bits of length)
+
+ A code length of 0 indicates that the corresponding symbol in
+ the literal/length or distance alphabet will not occur in the
+ block, and should not participate in the Huffman code
+ construction algorithm given earlier. If only one distance
+ code is used, it is encoded using one bit, not zero bits; in
+ this case there is a single code length of one, with one unused
+ code. One distance code of zero bits means that there are no
+ distance codes used at all (the data is all literals).
+
+ We can now define the format of the block:
+
+ 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
+ 5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
+ 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
+
+
+
+Deutsch Informational [Page 13]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ (HCLEN + 4) x 3 bits: code lengths for the code length
+ alphabet given just above, in the order: 16, 17, 18,
+ 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+
+ These code lengths are interpreted as 3-bit integers
+ (0-7); as above, a code length of 0 means the
+ corresponding symbol (literal/length or distance code
+ length) is not used.
+
+ HLIT + 257 code lengths for the literal/length alphabet,
+ encoded using the code length Huffman code
+
+ HDIST + 1 code lengths for the distance alphabet,
+ encoded using the code length Huffman code
+
+ The actual compressed data of the block,
+ encoded using the literal/length and distance Huffman
+ codes
+
+ The literal/length symbol 256 (end of data),
+ encoded using the literal/length Huffman code
+
+ The code length repeat codes can cross from HLIT + 257 to the
+ HDIST + 1 code lengths. In other words, all code lengths form
+ a single sequence of HLIT + HDIST + 258 values.
+
+ 3.3. Compliance
+
+ A compressor may limit further the ranges of values specified in
+ the previous section and still be compliant; for example, it may
+ limit the range of backward pointers to some value smaller than
+ 32K. Similarly, a compressor may limit the size of blocks so that
+ a compressible block fits in memory.
+
+ A compliant decompressor must accept the full range of possible
+ values defined in the previous section, and must accept blocks of
+ arbitrary size.
+
+4. Compression algorithm details
+
+ While it is the intent of this document to define the "deflate"
+ compressed data format without reference to any particular
+ compression algorithm, the format is related to the compressed
+ formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
+ since many variations of LZ77 are patented, it is strongly
+ recommended that the implementor of a compressor follow the general
+ algorithm presented here, which is known not to be patented per se.
+ The material in this section is not part of the definition of the
+
+
+
+Deutsch Informational [Page 14]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ specification per se, and a compressor need not follow it in order to
+ be compliant.
+
+ The compressor terminates a block when it determines that starting a
+ new block with fresh trees would be useful, or when the block size
+ fills up the compressor's block buffer.
+
+ The compressor uses a chained hash table to find duplicated strings,
+ using a hash function that operates on 3-byte sequences. At any
+ given point during compression, let XYZ be the next 3 input bytes to
+ be examined (not necessarily all different, of course). First, the
+ compressor examines the hash chain for XYZ. If the chain is empty,
+ the compressor simply writes out X as a literal byte and advances one
+ byte in the input. If the hash chain is not empty, indicating that
+ the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
+ same hash function value) has occurred recently, the compressor
+ compares all strings on the XYZ hash chain with the actual input data
+ sequence starting at the current point, and selects the longest
+ match.
+
+ The compressor searches the hash chains starting with the most recent
+ strings, to favor small distances and thus take advantage of the
+ Huffman encoding. The hash chains are singly linked. There are no
+ deletions from the hash chains; the algorithm simply discards matches
+ that are too old. To avoid a worst-case situation, very long hash
+ chains are arbitrarily truncated at a certain length, determined by a
+ run-time parameter.
+
+ To improve overall compression, the compressor optionally defers the
+ selection of matches ("lazy matching"): after a match of length N has
+ been found, the compressor searches for a longer match starting at
+ the next input byte. If it finds a longer match, it truncates the
+ previous match to a length of one (thus producing a single literal
+ byte) and then emits the longer match. Otherwise, it emits the
+ original match, and, as described above, advances N bytes before
+ continuing.
+
+ Run-time parameters also control this "lazy match" procedure. If
+ compression ratio is most important, the compressor attempts a
+ complete second search regardless of the length of the first match.
+ In the normal case, if the current match is "long enough", the
+ compressor reduces the search for a longer match, thus speeding up
+ the process. If speed is most important, the compressor inserts new
+ strings in the hash table only when no match was found, or when the
+ match is not "too long". This degrades the compression ratio but
+ saves time since there are both fewer insertions and fewer searches.
+
+
+
+
+
+Deutsch Informational [Page 15]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+5. References
+
+ [1] Huffman, D. A., "A Method for the Construction of Minimum
+ Redundancy Codes", Proceedings of the Institute of Radio
+ Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
+
+ [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
+ Compression", IEEE Transactions on Information Theory, Vol. 23,
+ No. 3, pp. 337-343.
+
+ [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
+ available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
+
+ [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
+ encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
+
+ [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
+ Comm. ACM, 33,4, April 1990, pp. 449-459.
+
+6. Security Considerations
+
+ Any data compression method involves the reduction of redundancy in
+ the data. Consequently, any corruption of the data is likely to have
+ severe effects and be difficult to correct. Uncompressed text, on
+ the other hand, will probably still be readable despite the presence
+ of some corrupted bytes.
+
+ It is recommended that systems using this data format provide some
+ means of validating the integrity of the compressed data. See
+ reference [3], for example.
+
+7. Source code
+
+ Source code for a C language implementation of a "deflate" compliant
+ compressor and decompressor is available within the zlib package at
+ ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+8. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
+ Adler wrote the related software described in this specification.
+ Glenn Randers-Pehrson converted this document to RFC and HTML format.
+
+
+
+Deutsch Informational [Page 16]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+9. Author's Address
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+ Questions about the technical content of this specification can be
+ sent by email to:
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to:
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 17]
+
diff --git a/usr/src/boot/lib/libz/doc/rfc1952.txt b/usr/src/boot/lib/libz/doc/rfc1952.txt
new file mode 100644
index 0000000000..a8e51b4567
--- /dev/null
+++ b/usr/src/boot/lib/libz/doc/rfc1952.txt
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1952 Aladdin Enterprises
+Category: Informational May 1996
+
+
+ GZIP file format specification version 4.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format that is
+ compatible with the widely used GZIP utility. The format includes a
+ cyclic redundancy check value for detecting data corruption. The
+ format presently uses the DEFLATE method of compression but can be
+ easily extended to use other compression methods. The format can be
+ implemented readily in a manner not covered by patents.
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 1]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................. 3
+ 1.6. Changes from previous versions ............................ 3
+ 2. Detailed specification ......................................... 4
+ 2.1. Overall conventions ....................................... 4
+ 2.2. File format ............................................... 5
+ 2.3. Member format ............................................. 5
+ 2.3.1. Member header and trailer ........................... 6
+ 2.3.1.1. Extra field ................................... 8
+ 2.3.1.2. Compliance .................................... 9
+ 3. References .................................................. 9
+ 4. Security Considerations .................................... 10
+ 5. Acknowledgements ........................................... 10
+ 6. Author's Address ........................................... 10
+ 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
+ 8. Appendix: Sample CRC Code .................................. 11
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+ * Can compress or decompress a data stream (as opposed to a
+ randomly accessible file) to produce another data stream,
+ using only an a priori bounded amount of intermediate
+ storage, and hence can be used in data communications or
+ similar structures such as Unix filters;
+ * Compresses data with efficiency comparable to the best
+ currently available general-purpose compression methods,
+ and in particular considerably better than the "compress"
+ program;
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely;
+ * Is compatible with the file format produced by the current
+ widely used gzip utility, in that conforming decompressors
+ will be able to read data produced by the existing gzip
+ compressor.
+
+
+
+
+Deutsch Informational [Page 2]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ The data format defined by this specification does not attempt to:
+
+ * Provide random access to compressed data;
+ * Compress specialized data (e.g., raster graphics) as well as
+ the best currently available specialized algorithms.
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into gzip format and/or decompress data from gzip
+ format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations.
+
+ 1.3. Scope
+
+ The specification specifies a compression method and a file format
+ (the latter assuming only that a file can store a sequence of
+ arbitrary bytes). It does not specify any particular interface to
+ a file system or anything about character sets or encodings
+ (except for file names and comments, which are optional).
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any file that conforms to all the
+ specifications presented here; a compliant compressor must produce
+ files that conform to all the specifications presented here. The
+ material in the appendices is not part of the specification per se
+ and is not relevant to compliance.
+
+ 1.5. Definitions of terms and conventions used
+
+ byte: 8 bits stored or transmitted as a unit (same as an octet).
+ (For this specification, a byte is exactly 8 bits, even on
+ machines which store a character on a number of bits different
+ from 8.) See below for the numbering of bits within a byte.
+
+ 1.6. Changes from previous versions
+
+ There have been no technical changes to the gzip format since
+ version 4.1 of this specification. In version 4.2, some
+ terminology was changed, and the sample CRC code was rewritten for
+ clarity and to eliminate the requirement for the caller to do pre-
+ and post-conditioning. Version 4.3 is a conversion of the
+ specification to RFC style.
+
+
+
+Deutsch Informational [Page 3]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+2. Detailed specification
+
+ 2.1. Overall conventions
+
+ In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ This document does not address the issue of the order in which
+ bits of a byte are transmitted on a bit-sequential medium, since
+ the data format described here is byte- rather than bit-oriented.
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the least-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00001000|00000010|
+ +--------+--------+
+ ^ ^
+ | |
+ | + more significant byte = 2 x 256
+ + less significant byte = 8
+
+
+
+Deutsch Informational [Page 4]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 2.2. File format
+
+ A gzip file consists of a series of "members" (compressed data
+ sets). The format of each member is specified in the following
+ section. The members simply appear one after another in the file,
+ with no additional information before, between, or after them.
+
+ 2.3. Member format
+
+ Each member has the following structure:
+
+ +---+---+---+---+---+---+---+---+---+---+
+ |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+ +---+---+---+---+---+---+---+---+---+---+
+
+ (if FLG.FEXTRA set)
+
+ +---+---+=================================+
+ | XLEN |...XLEN bytes of "extra field"...| (more-->)
+ +---+---+=================================+
+
+ (if FLG.FNAME set)
+
+ +=========================================+
+ |...original file name, zero-terminated...| (more-->)
+ +=========================================+
+
+ (if FLG.FCOMMENT set)
+
+ +===================================+
+ |...file comment, zero-terminated...| (more-->)
+ +===================================+
+
+ (if FLG.FHCRC set)
+
+ +---+---+
+ | CRC16 |
+ +---+---+
+
+ +=======================+
+ |...compressed blocks...| (more-->)
+ +=======================+
+
+ 0 1 2 3 4 5 6 7
+ +---+---+---+---+---+---+---+---+
+ | CRC32 | ISIZE |
+ +---+---+---+---+---+---+---+---+
+
+
+
+
+Deutsch Informational [Page 5]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 2.3.1. Member header and trailer
+
+ ID1 (IDentification 1)
+ ID2 (IDentification 2)
+ These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
+ (0x8b, \213), to identify the file as being in gzip format.
+
+ CM (Compression Method)
+ This identifies the compression method used in the file. CM
+ = 0-7 are reserved. CM = 8 denotes the "deflate"
+ compression method, which is the one customarily used by
+ gzip and which is documented elsewhere.
+
+ FLG (FLaGs)
+ This flag byte is divided into individual bits as follows:
+
+ bit 0 FTEXT
+ bit 1 FHCRC
+ bit 2 FEXTRA
+ bit 3 FNAME
+ bit 4 FCOMMENT
+ bit 5 reserved
+ bit 6 reserved
+ bit 7 reserved
+
+ If FTEXT is set, the file is probably ASCII text. This is
+ an optional indication, which the compressor may set by
+ checking a small amount of the input data to see whether any
+ non-ASCII characters are present. In case of doubt, FTEXT
+ is cleared, indicating binary data. For systems which have
+ different file formats for ascii text and binary data, the
+ decompressor can use FTEXT to choose the appropriate format.
+ We deliberately do not specify the algorithm used to set
+ this bit, since a compressor always has the option of
+ leaving it cleared and a decompressor always has the option
+ of ignoring it and letting some other program handle issues
+ of data conversion.
+
+ If FHCRC is set, a CRC16 for the gzip header is present,
+ immediately before the compressed data. The CRC16 consists
+ of the two least significant bytes of the CRC32 for all
+ bytes of the gzip header up to and not including the CRC16.
+ [The FHCRC bit was never set by versions of gzip up to
+ 1.2.4, even though it was documented with a different
+ meaning in gzip 1.2.4.]
+
+ If FEXTRA is set, optional extra fields are present, as
+ described in a following section.
+
+
+
+Deutsch Informational [Page 6]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ If FNAME is set, an original file name is present,
+ terminated by a zero byte. The name must consist of ISO
+ 8859-1 (LATIN-1) characters; on operating systems using
+ EBCDIC or any other character set for file names, the name
+ must be translated to the ISO LATIN-1 character set. This
+ is the original name of the file being compressed, with any
+ directory components removed, and, if the file being
+ compressed is on a file system with case insensitive names,
+ forced to lower case. There is no original file name if the
+ data was compressed from a source other than a named file;
+ for example, if the source was stdin on a Unix system, there
+ is no file name.
+
+ If FCOMMENT is set, a zero-terminated file comment is
+ present. This comment is not interpreted; it is only
+ intended for human consumption. The comment must consist of
+ ISO 8859-1 (LATIN-1) characters. Line breaks should be
+ denoted by a single line feed character (10 decimal).
+
+ Reserved FLG bits must be zero.
+
+ MTIME (Modification TIME)
+ This gives the most recent modification time of the original
+ file being compressed. The time is in Unix format, i.e.,
+ seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
+ may cause problems for MS-DOS and other systems that use
+ local rather than Universal time.) If the compressed data
+ did not come from a file, MTIME is set to the time at which
+ compression started. MTIME = 0 means no time stamp is
+ available.
+
+ XFL (eXtra FLags)
+ These flags are available for use by specific compression
+ methods. The "deflate" method (CM = 8) sets these flags as
+ follows:
+
+ XFL = 2 - compressor used maximum compression,
+ slowest algorithm
+ XFL = 4 - compressor used fastest algorithm
+
+ OS (Operating System)
+ This identifies the type of file system on which compression
+ took place. This may be useful in determining end-of-line
+ convention for text files. The currently defined values are
+ as follows:
+
+
+
+
+
+
+Deutsch Informational [Page 7]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
+ 1 - Amiga
+ 2 - VMS (or OpenVMS)
+ 3 - Unix
+ 4 - VM/CMS
+ 5 - Atari TOS
+ 6 - HPFS filesystem (OS/2, NT)
+ 7 - Macintosh
+ 8 - Z-System
+ 9 - CP/M
+ 10 - TOPS-20
+ 11 - NTFS filesystem (NT)
+ 12 - QDOS
+ 13 - Acorn RISCOS
+ 255 - unknown
+
+ XLEN (eXtra LENgth)
+ If FLG.FEXTRA is set, this gives the length of the optional
+ extra field. See below for details.
+
+ CRC32 (CRC-32)
+ This contains a Cyclic Redundancy Check value of the
+ uncompressed data computed according to CRC-32 algorithm
+ used in the ISO 3309 standard and in section 8.1.1.6.2 of
+ ITU-T recommendation V.42. (See http://www.iso.ch for
+ ordering ISO documents. See gopher://info.itu.ch for an
+ online version of ITU-T V.42.)
+
+ ISIZE (Input SIZE)
+ This contains the size of the original (uncompressed) input
+ data modulo 2^32.
+
+ 2.3.1.1. Extra field
+
+ If the FLG.FEXTRA bit is set, an "extra field" is present in
+ the header, with total length XLEN bytes. It consists of a
+ series of subfields, each of the form:
+
+ +---+---+---+---+==================================+
+ |SI1|SI2| LEN |... LEN bytes of subfield data ...|
+ +---+---+---+---+==================================+
+
+ SI1 and SI2 provide a subfield ID, typically two ASCII letters
+ with some mnemonic value. Jean-Loup Gailly
+ <gzip@prep.ai.mit.edu> is maintaining a registry of subfield
+ IDs; please send him any subfield ID you wish to use. Subfield
+ IDs with SI2 = 0 are reserved for future use. The following
+ IDs are currently defined:
+
+
+
+Deutsch Informational [Page 8]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ SI1 SI2 Data
+ ---------- ---------- ----
+ 0x41 ('A') 0x70 ('P') Apollo file type information
+
+ LEN gives the length of the subfield data, excluding the 4
+ initial bytes.
+
+ 2.3.1.2. Compliance
+
+ A compliant compressor must produce files with correct ID1,
+ ID2, CM, CRC32, and ISIZE, but may set all the other fields in
+ the fixed-length part of the header to default values (255 for
+ OS, 0 for all others). The compressor must set all reserved
+ bits to zero.
+
+ A compliant decompressor must check ID1, ID2, and CM, and
+ provide an error indication if any of these have incorrect
+ values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
+ at least so it can skip over the optional fields if they are
+ present. It need not examine any other part of the header or
+ trailer; in particular, a decompressor may ignore FTEXT and OS
+ and always produce binary output, and still be compliant. A
+ compliant decompressor must give an error indication if any
+ reserved bit is non-zero, since such a bit could indicate the
+ presence of a new field that would cause subsequent data to be
+ interpreted incorrectly.
+
+3. References
+
+ [1] "Information Processing - 8-bit single-byte coded graphic
+ character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
+ The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
+ ASCII. Files defining this character set are available as
+ iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
+
+ [2] ISO 3309
+
+ [3] ITU-T recommendation V.42
+
+ [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
+ ftp://prep.ai.mit.edu/pub/gnu/
+
+ [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
+ Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
+
+
+
+
+Deutsch Informational [Page 9]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
+ pp.118-133.
+
+ [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
+ describing the CRC concept.
+
+4. Security Considerations
+
+ Any data compression method involves the reduction of redundancy in
+ the data. Consequently, any corruption of the data is likely to have
+ severe effects and be difficult to correct. Uncompressed text, on
+ the other hand, will probably still be readable despite the presence
+ of some corrupted bytes.
+
+ It is recommended that systems using this data format provide some
+ means of validating the integrity of the compressed data, such as by
+ setting and checking the CRC-32 check value.
+
+5. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
+ the related software described in this specification. Glenn
+ Randers-Pehrson converted this document to RFC and HTML format.
+
+6. Author's Address
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+ Questions about the technical content of this specification can be
+ sent by email to:
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to:
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+Deutsch Informational [Page 10]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+7. Appendix: Jean-Loup Gailly's gzip utility
+
+ The most widely used implementation of gzip compression, and the
+ original documentation on which this specification is based, were
+ created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
+ implementation is a de facto standard, we mention some more of its
+ features here. Again, the material in this section is not part of
+ the specification per se, and implementations need not follow it to
+ be compliant.
+
+ When compressing or decompressing a file, gzip preserves the
+ protection, ownership, and modification time attributes on the local
+ file system, since there is no provision for representing protection
+ attributes in the gzip file format itself. Since the file format
+ includes a modification time, the gzip decompressor provides a
+ command line switch that assigns the modification time from the file,
+ rather than the local modification time of the compressed input, to
+ the decompressed output.
+
+8. Appendix: Sample CRC Code
+
+ The following sample code represents a practical implementation of
+ the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
+ for a formal specification.)
+
+ The sample code is in the ANSI C programming language. Non C users
+ may find it easier to read with these hints:
+
+ & Bitwise AND operator.
+ ^ Bitwise exclusive-OR operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero
+ bit(s) at the left.
+ ! Logical NOT operator.
+ ++ "n++" increments the variable n.
+ 0xNNN 0x introduces a hexadecimal (base 16) constant.
+ Suffix L indicates a long value (at least 32 bits).
+
+ /* Table of CRCs of all 8-bit messages. */
+ unsigned long crc_table[256];
+
+ /* Flag: has the table been computed? Initially false. */
+ int crc_table_computed = 0;
+
+ /* Make the table for a fast CRC. */
+ void make_crc_table(void)
+ {
+ unsigned long c;
+
+
+
+Deutsch Informational [Page 11]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ int n, k;
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long) n;
+ for (k = 0; k < 8; k++) {
+ if (c & 1) {
+ c = 0xedb88320L ^ (c >> 1);
+ } else {
+ c = c >> 1;
+ }
+ }
+ crc_table[n] = c;
+ }
+ crc_table_computed = 1;
+ }
+
+ /*
+ Update a running crc with the bytes buf[0..len-1] and return
+ the updated crc. The crc should be initialized to zero. Pre- and
+ post-conditioning (one's complement) is performed within this
+ function so it shouldn't be done by the caller. Usage example:
+
+ unsigned long crc = 0L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = update_crc(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+ */
+ unsigned long update_crc(unsigned long crc,
+ unsigned char *buf, int len)
+ {
+ unsigned long c = crc ^ 0xffffffffL;
+ int n;
+
+ if (!crc_table_computed)
+ make_crc_table();
+ for (n = 0; n < len; n++) {
+ c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+ }
+ return c ^ 0xffffffffL;
+ }
+
+ /* Return the CRC of the bytes buf[0..len-1]. */
+ unsigned long crc(unsigned char *buf, int len)
+ {
+ return update_crc(0L, buf, len);
+ }
+
+
+
+
+Deutsch Informational [Page 12]
+
diff --git a/usr/src/boot/lib/libz/doc/txtvsbin.txt b/usr/src/boot/lib/libz/doc/txtvsbin.txt
new file mode 100644
index 0000000000..3d0f0634f7
--- /dev/null
+++ b/usr/src/boot/lib/libz/doc/txtvsbin.txt
@@ -0,0 +1,107 @@
+A Fast Method for Identifying Plain Text Files
+==============================================
+
+
+Introduction
+------------
+
+Given a file coming from an unknown source, it is sometimes desirable
+to find out whether the format of that file is plain text. Although
+this may appear like a simple task, a fully accurate detection of the
+file type requires heavy-duty semantic analysis on the file contents.
+It is, however, possible to obtain satisfactory results by employing
+various heuristics.
+
+Previous versions of PKZip and other zip-compatible compression tools
+were using a crude detection scheme: if more than 80% (4/5) of the bytes
+found in a certain buffer are within the range [7..127], the file is
+labeled as plain text, otherwise it is labeled as binary. A prominent
+limitation of this scheme is the restriction to Latin-based alphabets.
+Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
+the bytes within the range [128..255], and texts using these alphabets
+are most often misidentified by this scheme; in other words, the rate
+of false negatives is sometimes too high, which means that the recall
+is low. Another weakness of this scheme is a reduced precision, due to
+the false positives that may occur when binary files containing large
+amounts of textual characters are misidentified as plain text.
+
+In this article we propose a new, simple detection scheme that features
+a much increased precision and a near-100% recall. This scheme is
+designed to work on ASCII, Unicode and other ASCII-derived alphabets,
+and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
+and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings
+(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
+
+
+The Algorithm
+-------------
+
+The algorithm works by dividing the set of bytecodes [0..255] into three
+categories:
+- The white list of textual bytecodes:
+ 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
+- The gray list of tolerated bytecodes:
+ 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
+- The black list of undesired, non-textual bytecodes:
+ 0 (NUL) to 6, 14 to 31.
+
+If a file contains at least one byte that belongs to the white list and
+no byte that belongs to the black list, then the file is categorized as
+plain text; otherwise, it is categorized as binary. (The boundary case,
+when the file is empty, automatically falls into the latter category.)
+
+
+Rationale
+---------
+
+The idea behind this algorithm relies on two observations.
+
+The first observation is that, although the full range of 7-bit codes
+[0..127] is properly specified by the ASCII standard, most control
+characters in the range [0..31] are not used in practice. The only
+widely-used, almost universally-portable control codes are 9 (TAB),
+10 (LF) and 13 (CR). There are a few more control codes that are
+recognized on a reduced range of platforms and text viewers/editors:
+7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
+codes are rarely (if ever) used alone, without being accompanied by
+some printable text. Even the newer, portable text formats such as
+XML avoid using control characters outside the list mentioned here.
+
+The second observation is that most of the binary files tend to contain
+control characters, especially 0 (NUL). Even though the older text
+detection schemes observe the presence of non-ASCII codes from the range
+[128..255], the precision rarely has to suffer if this upper range is
+labeled as textual, because the files that are genuinely binary tend to
+contain both control characters and codes from the upper range. On the
+other hand, the upper range needs to be labeled as textual, because it
+is used by virtually all ASCII extensions. In particular, this range is
+used for encoding non-Latin scripts.
+
+Since there is no counting involved, other than simply observing the
+presence or the absence of some byte values, the algorithm produces
+consistent results, regardless what alphabet encoding is being used.
+(If counting were involved, it could be possible to obtain different
+results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
+
+There is an extra category of plain text files that are "polluted" with
+one or more black-listed codes, either by mistake or by peculiar design
+considerations. In such cases, a scheme that tolerates a small fraction
+of black-listed codes would provide an increased recall (i.e. more true
+positives). This, however, incurs a reduced precision overall, since
+false positives are more likely to appear in binary files that contain
+large chunks of textual data. Furthermore, "polluted" plain text should
+be regarded as binary by general-purpose text detection schemes, because
+general-purpose text processing algorithms might not be applicable.
+Under this premise, it is safe to say that our detection method provides
+a near-100% recall.
+
+Experiments have been run on many files coming from various platforms
+and applications. We tried plain text files, system logs, source code,
+formatted office documents, compiled object code, etc. The results
+confirm the optimistic assumptions about the capabilities of this
+algorithm.
+
+
+--
+Cosmin Truta
+Last updated: 2006-May-28
diff --git a/usr/src/boot/lib/libz/gzclose.c b/usr/src/boot/lib/libz/gzclose.c
new file mode 100644
index 0000000000..caeb99a317
--- /dev/null
+++ b/usr/src/boot/lib/libz/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+ That way the other gzclose functions can be used instead to avoid linking in
+ unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+ gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+ gz_statep state;
+
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+ return gzclose_r(file);
+#endif
+}
diff --git a/usr/src/boot/lib/libz/gzguts.h b/usr/src/boot/lib/libz/gzguts.h
new file mode 100644
index 0000000000..d87659d031
--- /dev/null
+++ b/usr/src/boot/lib/libz/gzguts.h
@@ -0,0 +1,209 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+# include <limits.h>
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include <io.h>
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99, yet still not supported by
+ Microsoft more than a decade later!), _snprintf does not guarantee null
+ termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include <windows.h>
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifndef NO_STRERROR
+# include <errno.h>
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ int direct; /* 0 if processing gzip, 1 if transparent */
+ /* just for reading */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/usr/src/boot/lib/libz/gzlib.c b/usr/src/boot/lib/libz/gzlib.c
new file mode 100644
index 0000000000..d8dbb7eefe
--- /dev/null
+++ b/usr/src/boot/lib/libz/gzlib.c
@@ -0,0 +1,637 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $FreeBSD$ */
+
+#include "gzguts.h"
+#include "zutil.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__)
+# define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define LSEEK lseek64
+#else
+# define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+ string and return a pointer to it. Typically, the values for ERROR come
+ from GetLastError.
+
+ The string pointed to shall not be modified by the application, but may be
+ overwritten by a subsequent call to gz_strwinerror
+
+ The gz_strwinerror function does not change the current setting of
+ GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+ gz_statep state;
+{
+ state->x.have = 0; /* no output data available */
+ if (state->mode == GZ_READ) { /* for reading ... */
+ state->eof = 0; /* not at end of file */
+ state->past = 0; /* have not read past end yet */
+ state->how = LOOK; /* look for gzip header */
+ }
+ state->seek = 0; /* no seek request pending */
+ gz_error(state, Z_OK, NULL); /* clear error */
+ state->x.pos = 0; /* no uncompressed data yet */
+ state->strm.avail_in = 0; /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+ const void *path;
+ int fd;
+ const char *mode;
+{
+ gz_statep state;
+ size_t len;
+ int oflag;
+#ifdef O_CLOEXEC
+ int cloexec = 0;
+#endif
+#ifdef O_EXCL
+ int exclusive = 0;
+#endif
+
+ /* check input */
+ if (path == NULL)
+ return NULL;
+
+ /* allocate gzFile structure to return */
+ state = (gz_statep)malloc(sizeof(gz_state));
+ if (state == NULL)
+ return NULL;
+ state->size = 0; /* no buffers allocated yet */
+ state->want = GZBUFSIZE; /* requested buffer size */
+ state->msg = NULL; /* no error message yet */
+
+ /* interpret mode */
+ state->mode = GZ_NONE;
+ state->level = Z_DEFAULT_COMPRESSION;
+ state->strategy = Z_DEFAULT_STRATEGY;
+ state->direct = 0;
+ while (*mode) {
+ if (*mode >= '0' && *mode <= '9')
+ state->level = *mode - '0';
+ else
+ switch (*mode) {
+ case 'r':
+ state->mode = GZ_READ;
+ break;
+#ifndef NO_GZCOMPRESS
+ case 'w':
+ state->mode = GZ_WRITE;
+ break;
+ case 'a':
+ state->mode = GZ_APPEND;
+ break;
+#endif
+ case '+': /* can't read and write at the same time */
+ free(state);
+ return NULL;
+ case 'b': /* ignore -- will request binary anyway */
+ break;
+#ifdef O_CLOEXEC
+ case 'e':
+ cloexec = 1;
+ break;
+#endif
+#ifdef O_EXCL
+ case 'x':
+ exclusive = 1;
+ break;
+#endif
+ case 'f':
+ state->strategy = Z_FILTERED;
+ break;
+ case 'h':
+ state->strategy = Z_HUFFMAN_ONLY;
+ break;
+ case 'R':
+ state->strategy = Z_RLE;
+ break;
+ case 'F':
+ state->strategy = Z_FIXED;
+ break;
+ case 'T':
+ state->direct = 1;
+ break;
+ default: /* could consider as an error, but just ignore */
+ ;
+ }
+ mode++;
+ }
+
+ /* must provide an "r", "w", or "a" */
+ if (state->mode == GZ_NONE) {
+ free(state);
+ return NULL;
+ }
+
+ /* can't force transparent read */
+ if (state->mode == GZ_READ) {
+ if (state->direct) {
+ free(state);
+ return NULL;
+ }
+ state->direct = 1; /* for empty file */
+ }
+
+ /* save the path name for error messages */
+#ifdef _WIN32
+ if (fd == -2) {
+ len = wcstombs(NULL, path, 0);
+ if (len == (size_t)-1)
+ len = 0;
+ }
+ else
+#endif
+ len = strlen((const char *)path);
+ state->path = (char *)malloc(len + 1);
+ if (state->path == NULL) {
+ free(state);
+ return NULL;
+ }
+#ifdef _WIN32
+ if (fd == -2)
+ if (len)
+ wcstombs(state->path, path, len + 1);
+ else
+ *(state->path) = 0;
+ else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+ strcpy(state->path, path);
+#endif
+
+ /* compute the flags for open() */
+ oflag =
+#ifdef O_LARGEFILE
+ O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+ O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+ (cloexec ? O_CLOEXEC : 0) |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+ (exclusive ? O_EXCL : 0) |
+#endif
+ (state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND)));
+
+ /* open the file with the appropriate flags (or just use fd) */
+ state->fd = fd > -1 ? fd : (
+#ifdef _WIN32
+ fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+ open((const char *)path, oflag, 0666));
+ if (state->fd == -1) {
+ free(state->path);
+ free(state);
+ return NULL;
+ }
+ if (state->mode == GZ_APPEND)
+ state->mode = GZ_WRITE; /* simplify later checks */
+
+ /* save the current position for rewinding (only if reading) */
+ if (state->mode == GZ_READ) {
+ state->start = LSEEK(state->fd, 0, SEEK_CUR);
+ if (state->start == -1) state->start = 0;
+ }
+
+ /* initialize stream */
+ gz_reset(state);
+
+ /* return stream */
+ return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ char *path; /* identifier for error messages */
+ gzFile gz;
+
+ if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+ return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
+#else
+ sprintf(path, "<fd:%d>", fd); /* for debugging */
+#endif
+ gz = gz_open(path, fd, mode);
+ free(path);
+ return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef _WIN32
+gzFile ZEXPORT gzopen_w(path, mode)
+ const wchar_t *path;
+ const char *mode;
+{
+ return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+ gzFile file;
+ unsigned size;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* make sure we haven't already allocated memory */
+ if (state->size != 0)
+ return -1;
+
+ /* check and set requested size */
+ if (size < 2)
+ size = 2; /* need two bytes to check magic header */
+ state->want = size;
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* back up and start over */
+ if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+ return -1;
+ gz_reset(state);
+ return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+ gzFile file;
+ z_off64_t offset;
+ int whence;
+{
+ unsigned n;
+ z_off64_t ret;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* check that there's no error */
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* can only seek from start or relative to current position */
+ if (whence != SEEK_SET && whence != SEEK_CUR)
+ return -1;
+
+ /* normalize offset to a SEEK_CUR specification */
+ if (whence == SEEK_SET)
+ offset -= state->x.pos;
+ else if (state->seek)
+ offset += state->skip;
+ state->seek = 0;
+
+ /* if within raw area while reading, just go there */
+ if (state->mode == GZ_READ && state->how == COPY &&
+ state->x.pos + offset >= 0) {
+ ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+ if (ret == -1)
+ return -1;
+ state->x.have = 0;
+ state->eof = 0;
+ state->past = 0;
+ state->seek = 0;
+ gz_error(state, Z_OK, NULL);
+ state->strm.avail_in = 0;
+ state->x.pos += offset;
+ return state->x.pos;
+ }
+
+ /* calculate skip amount, rewinding if needed for back seek when reading */
+ if (offset < 0) {
+ if (state->mode != GZ_READ) /* writing -- can't go backwards */
+ return -1;
+ offset += state->x.pos;
+ if (offset < 0) /* before start of file! */
+ return -1;
+ if (gzrewind(file) == -1) /* rewind, then skip to offset */
+ return -1;
+ }
+
+ /* if reading, skip what's in output buffer (one less gzgetc() check) */
+ if (state->mode == GZ_READ) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+ (unsigned)offset : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ offset -= n;
+ }
+
+ /* request skip (if not zero) */
+ if (offset) {
+ state->seek = 1;
+ state->skip = offset;
+ }
+ return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ z_off64_t ret;
+
+ ret = gzseek64(file, (z_off64_t)offset, whence);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* return position */
+ return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gztell64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+ gzFile file;
+{
+ z_off64_t offset;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* compute and return effective offset in file */
+ offset = LSEEK(state->fd, 0, SEEK_CUR);
+ if (offset == -1)
+ return -1;
+ if (state->mode == GZ_READ) /* reading */
+ offset -= state->strm.avail_in; /* don't count buffered input */
+ return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gzoffset64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return 0;
+
+ /* return end-of-file state */
+ return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return NULL;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return NULL;
+
+ /* return error information */
+ if (errnum != NULL)
+ *errnum = state->err;
+ return state->err == Z_MEM_ERROR ? "out of memory" :
+ (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return;
+
+ /* clear error and end-of-file */
+ if (state->mode == GZ_READ) {
+ state->eof = 0;
+ state->past = 0;
+ }
+ gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+ state->msg accordingly. Free any previous error message already there. Do
+ not try to free or allocate space if the error is Z_MEM_ERROR (out of
+ memory). Simply save the error message as a static string. If there is an
+ allocation failure constructing the error message, then convert the error to
+ out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+ gz_statep state;
+ int err;
+ const char *msg;
+{
+ /* free previously allocated message and clear */
+ if (state->msg != NULL) {
+ if (state->err != Z_MEM_ERROR)
+ free(state->msg);
+ state->msg = NULL;
+ }
+
+ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+ if (err != Z_OK && err != Z_BUF_ERROR)
+ state->x.have = 0;
+
+ /* set error code, and if no message, then done */
+ state->err = err;
+ if (msg == NULL)
+ return;
+
+ /* for an out of memory error, return literal string when requested */
+ if (err == Z_MEM_ERROR)
+ return;
+
+ /* construct error message with path */
+ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+ NULL) {
+ state->err = Z_MEM_ERROR;
+ return;
+ }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+ "%s%s%s", state->path, ": ", msg);
+#else
+ strcpy(state->msg, state->path);
+ strcat(state->msg, ": ");
+ strcat(state->msg, msg);
+#endif
+ return;
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+ available) -- we need to do this to cover cases where 2's complement not
+ used, since C standard permits 1's complement and sign-bit representations,
+ otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+ unsigned p, q;
+
+ p = 1;
+ do {
+ q = p;
+ p <<= 1;
+ p++;
+ } while (p > q);
+ return q >> 1;
+}
+#endif
diff --git a/usr/src/boot/lib/libz/gzread.c b/usr/src/boot/lib/libz/gzread.c
new file mode 100644
index 0000000000..a8292ea263
--- /dev/null
+++ b/usr/src/boot/lib/libz/gzread.c
@@ -0,0 +1,597 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $FreeBSD$ */
+
+#include "gzguts.h"
+#include <unistd.h>
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
+ state->fd, and update state->eof, state->err, and state->msg as appropriate.
+ This function needs to loop on read(), since read() is not guaranteed to
+ read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+ gz_statep state;
+ unsigned char *buf;
+ unsigned len;
+ unsigned *have;
+{
+ int ret;
+
+ *have = 0;
+ do {
+ ret = read(state->fd, buf + *have, len - *have);
+ if (ret <= 0)
+ break;
+ *have += ret;
+ } while (*have < len);
+ if (ret < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (ret == 0)
+ state->eof = 1;
+ return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
+ file is reached, even though there may be unused data in the buffer. Once
+ that data has been used, no more attempts will be made to read the file.
+ If strm->avail_in != 0, then the current data is moved to the beginning of
+ the input buffer, and then the remainder of the buffer is loaded with the
+ available data from the input file. */
+local int gz_avail(state)
+ gz_statep state;
+{
+ unsigned got;
+ z_streamp strm = &(state->strm);
+
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+ if (state->eof == 0) {
+ if (strm->avail_in) { /* copy what's there to the start */
+ unsigned char *p = state->in;
+ unsigned const char *q = strm->next_in;
+ unsigned n = strm->avail_in;
+ do {
+ *p++ = *q++;
+ } while (--n);
+ }
+ if (gz_load(state, state->in + strm->avail_in,
+ state->size - strm->avail_in, &got) == -1)
+ return -1;
+ strm->avail_in += got;
+ strm->next_in = state->in;
+ }
+ return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
+ If this is the first time in, allocate required memory. state->how will be
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression. If direct copying, then leftover input
+ data from the input buffer will be copied to the output buffer. In that
+ case, all further file reads will be directly to either the output buffer or
+ a user buffer. If decompressing, the inflate state will be initialized.
+ gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ /* allocate read buffers and inflate memory */
+ if (state->size == 0) {
+ /* allocate buffers */
+ state->in = (unsigned char *)malloc(state->want);
+ state->out = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL || state->out == NULL) {
+ if (state->out != NULL)
+ free(state->out);
+ if (state->in != NULL)
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ state->size = state->want;
+
+ /* allocate inflate memory */
+ state->strm.zalloc = Z_NULL;
+ state->strm.zfree = Z_NULL;
+ state->strm.opaque = Z_NULL;
+ state->strm.avail_in = 0;
+ state->strm.next_in = Z_NULL;
+ if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
+ free(state->out);
+ free(state->in);
+ state->size = 0;
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* get at least the magic bytes in the input buffer */
+ if (strm->avail_in < 2) {
+ if (gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0)
+ return 0;
+ }
+
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+ a logical dilemma here when considering the case of a partially written
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
+ whether this is a single-byte file, or just a partially written gzip
+ file -- for here we assume that if a gzip file is being written, then
+ the header will be written in a single operation, so that reading a
+ single byte is sufficient indication that it is not a gzip file) */
+ if (strm->avail_in > 1 &&
+ strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+ inflateReset(strm);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
+ garbage. Ignore the trailing garbage and finish. */
+ if (state->direct == 0) {
+ strm->avail_in = 0;
+ state->eof = 1;
+ state->x.have = 0;
+ return 0;
+ }
+
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
+ the output buffer is larger than the input buffer, which also assures
+ space for gzungetc() */
+ state->x.next = state->out;
+ if (strm->avail_in) {
+ memcpy(state->x.next, strm->next_in, strm->avail_in);
+ state->x.have = strm->avail_in;
+ strm->avail_in = 0;
+ }
+ state->how = COPY;
+ state->direct = 1;
+ return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+ On return, state->x.have and state->x.next point to the just decompressed
+ data. If the gzip stream completes, state->how is reset to LOOK to look for
+ the next gzip stream or raw data, once state->x.have is depleted. Returns 0
+ on success, -1 on failure. */
+local int gz_decomp(state)
+ gz_statep state;
+{
+ int ret = Z_OK;
+ unsigned had;
+ z_streamp strm = &(state->strm);
+
+ /* fill output buffer up to end of deflate stream */
+ had = strm->avail_out;
+ do {
+ /* get more input for inflate() */
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0) {
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+ break;
+ }
+
+ /* decompress and handle errors */
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: inflate stream corrupt");
+ return -1;
+ }
+ if (ret == Z_MEM_ERROR) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
+ gz_error(state, Z_DATA_ERROR,
+ strm->msg == NULL ? "compressed data error" : strm->msg);
+ return -1;
+ }
+ } while (strm->avail_out && ret != Z_STREAM_END);
+
+ /* update available output */
+ state->x.have = had - strm->avail_out;
+ state->x.next = strm->next_out - state->x.have;
+
+ /* if the gzip stream completed successfully, look for another */
+ if (ret == Z_STREAM_END)
+ state->how = LOOK;
+
+ /* good decompression */
+ return 0;
+}
+
+/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
+ Data is either copied from the input file or decompressed from the input
+ file depending on state->how. If state->how is LOOK, then a gzip header is
+ looked for to determine whether to copy or decompress. Returns -1 on error,
+ otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
+ end of the input file has been reached and all data has been processed. */
+local int gz_fetch(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ do {
+ switch(state->how) {
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
+ if (gz_look(state) == -1)
+ return -1;
+ if (state->how == LOOK)
+ return 0;
+ break;
+ case COPY: /* -> COPY */
+ if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+ == -1)
+ return -1;
+ state->x.next = state->out;
+ return 0;
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+ return 0;
+}
+
+/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ unsigned n;
+
+ /* skip over len bytes or reach end-of-file, whichever comes first */
+ while (len)
+ /* skip over whatever is in output buffer */
+ if (state->x.have) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+ (unsigned)len : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ len -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0)
+ break;
+
+ /* need more data to skip -- load up output buffer */
+ else {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ unsigned got, n;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids the flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+ return -1;
+ }
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* get len bytes to buf, or less than len if at the end */
+ got = 0;
+ do {
+ /* first just try copying data from the output buffer */
+ if (state->x.have) {
+ n = state->x.have > len ? len : state->x.have;
+ memcpy(buf, state->x.next, n);
+ state->x.next += n;
+ state->x.have -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && strm->avail_in == 0) {
+ state->past = 1; /* tried to read past end */
+ break;
+ }
+
+ /* need output data -- for small len or new stream load up our output
+ buffer */
+ else if (state->how == LOOK || len < (state->size << 1)) {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return -1;
+ continue; /* no progress yet -- go back to copy above */
+ /* the copy above assures that we will leave with space in the
+ output buffer, allowing at least one gzungetc() to succeed */
+ }
+
+ /* large len -- read directly into user buffer */
+ else if (state->how == COPY) { /* read directly */
+ if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
+ return -1;
+ }
+
+ /* large len -- decompress directly into user buffer */
+ else { /* state->how == GZIP */
+ strm->avail_out = len;
+ strm->next_out = (unsigned char *)buf;
+ if (gz_decomp(state) == -1)
+ return -1;
+ n = state->x.have;
+ state->x.have = 0;
+ }
+
+ /* update progress */
+ len -= n;
+ buf = (char *)buf + n;
+ got += n;
+ state->x.pos += n;
+ } while (len);
+
+ /* return number of bytes read into user buffer (will fit in int) */
+ return (int)got;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+#else
+# undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ int ret;
+ unsigned char buf[1];
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* try output buffer (no need to check for skip request) */
+ if (state->x.have) {
+ state->x.have--;
+ state->x.pos++;
+ return *(state->x.next)++;
+ }
+
+ /* nothing there -- try gzread() */
+ ret = gzread(file, buf, 1);
+ return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+ return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* can't push EOF */
+ if (c < 0)
+ return -1;
+
+ /* if output buffer empty, put byte at end (allows more pushing) */
+ if (state->x.have == 0) {
+ state->x.have = 1;
+ state->x.next = state->out + (state->size << 1) - 1;
+ state->x.next[0] = c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+ }
+
+ /* if no room, give up (must have already done a gzungetc()) */
+ if (state->x.have == (state->size << 1)) {
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+ return -1;
+ }
+
+ /* slide output data if needed and insert byte before existing data */
+ if (state->x.next == state->out) {
+ unsigned char *src = state->out + state->x.have;
+ unsigned char *dest = state->out + (state->size << 1);
+ while (src > state->out)
+ *--dest = *--src;
+ state->x.next = dest;
+ }
+ state->x.have++;
+ state->x.next--;
+ state->x.next[0] = c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ unsigned left, n;
+ char *str;
+ unsigned char *eol;
+ gz_statep state;
+
+ /* check parameters and get internal structure */
+ if (file == NULL || buf == NULL || len < 1)
+ return NULL;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return NULL;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return NULL;
+ }
+
+ /* copy output bytes up to new line or len - 1, whichever comes first --
+ append a terminating zero to the string (we don't check for a zero in
+ the contents, let the user worry about that) */
+ str = buf;
+ left = (unsigned)len - 1;
+ if (left) do {
+ /* assure that something is in the output buffer */
+ if (state->x.have == 0 && gz_fetch(state) == -1)
+ return NULL; /* error */
+ if (state->x.have == 0) { /* end of file */
+ state->past = 1; /* read past end */
+ break; /* return what we have */
+ }
+
+ /* look for end-of-line in current output buffer */
+ n = state->x.have > left ? left : state->x.have;
+ eol = (unsigned char *)memchr(state->x.next, '\n', n);
+ if (eol != NULL)
+ n = (unsigned)(eol - state->x.next) + 1;
+
+ /* copy through end-of-line, or remainder if not found */
+ memcpy(buf, state->x.next, n);
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ left -= n;
+ buf += n;
+ } while (left && eol == NULL);
+
+ /* return terminated string, or if nothing, end of file */
+ if (buf == str)
+ return NULL;
+ buf[0] = 0;
+ return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+ (void)gz_look(state);
+
+ /* return 1 if transparent, 0 if processing a gzip stream */
+ return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+ gzFile file;
+{
+ int ret, err;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return Z_STREAM_ERROR;
+
+ /* free memory and close file */
+ if (state->size) {
+ inflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ }
+ err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret = close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : err;
+}
diff --git a/usr/src/boot/lib/libz/gzwrite.c b/usr/src/boot/lib/libz/gzwrite.c
new file mode 100644
index 0000000000..99cb3c213c
--- /dev/null
+++ b/usr/src/boot/lib/libz/gzwrite.c
@@ -0,0 +1,580 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $FreeBSD$ */
+
+#include "gzguts.h"
+#include <unistd.h>
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+
+/* Initialize state for writing a gzip file. Mark initialization by setting
+ state->size to non-zero. Return -1 on failure or 0 on success. */
+local int gz_init(state)
+ gz_statep state;
+{
+ int ret;
+ z_streamp strm = &(state->strm);
+
+ /* allocate input buffer */
+ state->in = (unsigned char *)malloc(state->want);
+ if (state->in == NULL) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* only need output buffer and deflate state if compressing */
+ if (!state->direct) {
+ /* allocate output buffer */
+ state->out = (unsigned char *)malloc(state->want);
+ if (state->out == NULL) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+ if (ret != Z_OK) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* mark state as initialized */
+ state->size = state->want;
+
+ /* initialize write buffer if compressing */
+ if (!state->direct) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = strm->next_out;
+ }
+ return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+ Return -1 if there is an error writing to the output file, otherwise 0.
+ flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
+ then the deflate() state is reset to start a new gzip stream. If gz->direct
+ is true, then simply write to the output file without compressing, and
+ ignore flush. */
+local int gz_comp(state, flush)
+ gz_statep state;
+ int flush;
+{
+ int ret, got;
+ unsigned have;
+ z_streamp strm = &(state->strm);
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return -1;
+
+ /* write directly if requested */
+ if (state->direct) {
+ got = write(state->fd, strm->next_in, strm->avail_in);
+ if (got < 0 || (unsigned)got != strm->avail_in) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ strm->avail_in = 0;
+ return 0;
+ }
+
+ /* run deflate() on provided input until it produces no more output */
+ ret = Z_OK;
+ do {
+ /* write out current buffer contents if full, or if flushing, but if
+ doing Z_FINISH then don't write until we get to Z_STREAM_END */
+ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+ (flush != Z_FINISH || ret == Z_STREAM_END))) {
+ have = (unsigned)(strm->next_out - state->x.next);
+ if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
+ (unsigned)got != have)) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (strm->avail_out == 0) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ }
+ state->x.next = strm->next_out;
+ }
+
+ /* compress */
+ have = strm->avail_out;
+ ret = deflate(strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: deflate stream corrupt");
+ return -1;
+ }
+ have -= strm->avail_out;
+ } while (have);
+
+ /* if that completed a deflate stream, allow another to start */
+ if (flush == Z_FINISH)
+ deflateReset(strm);
+
+ /* all done, no errors */
+ return 0;
+}
+
+/* Compress len zeros to output. Return -1 on error, 0 on success. */
+local int gz_zero(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ int first;
+ unsigned n;
+ z_streamp strm = &(state->strm);
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+
+ /* compress len zeros (len guaranteed > 0) */
+ first = 1;
+ while (len) {
+ n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+ (unsigned)len : state->size;
+ if (first) {
+ memset(state->in, 0, n);
+ first = 0;
+ }
+ strm->avail_in = n;
+ strm->next_in = state->in;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+ len -= n;
+ }
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ unsigned put = len;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids the flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+ return 0;
+ }
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* for small len, copy to input buffer, otherwise compress directly */
+ if (len < state->size) {
+ /* copy to input buffer, compress when full */
+ do {
+ unsigned have, copy;
+
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ copy = state->size - have;
+ if (copy > len)
+ copy = len;
+ memcpy(state->in + have, buf, copy);
+ strm->avail_in += copy;
+ state->x.pos += copy;
+ buf = (const char *)buf + copy;
+ len -= copy;
+ if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ } while (len);
+ }
+ else {
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* directly compress user buffer to file */
+ strm->avail_in = len;
+ strm->next_in = (z_const Bytef *)buf;
+ state->x.pos += len;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ }
+
+ /* input was all buffered or compressed (put will fit in int) */
+ return (int)put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned have;
+ unsigned char buf[1];
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* try writing to input buffer for speed (state->size == 0 if buffer not
+ initialized) */
+ if (state->size) {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ if (have < state->size) {
+ state->in[have] = c;
+ strm->avail_in++;
+ state->x.pos++;
+ return c & 0xff;
+ }
+ }
+
+ /* no room in buffer or not initialized, use gz_write() */
+ buf[0] = c;
+ if (gzwrite(file, buf, 1) != 1)
+ return -1;
+ return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+ gzFile file;
+ const char *str;
+{
+ int ret;
+ unsigned len;
+
+ /* write string */
+ len = (unsigned)strlen(str);
+ ret = gzwrite(file, str, len);
+ return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+ int size, len;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* do the printf() into the input buffer, put length in len */
+ size = (int)(state->size);
+ state->in[size - 1] = 0;
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf((char *)(state->in), format, va);
+ for (len = 0; len < size; len++)
+ if (state->in[len] == 0) break;
+# else
+ len = vsprintf((char *)(state->in), format, va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf((char *)(state->in), size, format, va);
+ len = strlen((char *)(state->in));
+# else
+ len = vsnprintf((char *)(state->in), size, format, va);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, defer compression until needed */
+ strm->avail_in = (unsigned)len;
+ strm->next_in = state->in;
+ state->x.pos += len;
+ return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, format);
+ ret = gzvprintf(file, format, va);
+ va_end(va);
+ return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ int size, len;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that can really pass pointer in ints */
+ if (sizeof(int) != sizeof(void *))
+ return 0;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* do the printf() into the input buffer, put length in len */
+ size = (int)(state->size);
+ state->in[size - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < size; len++)
+ if (state->in[len] == 0) break;
+# else
+ len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen((char *)(state->in));
+# else
+ len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
+ a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
+ a19, a20);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, defer compression until needed */
+ strm->avail_in = (unsigned)len;
+ strm->next_in = state->in;
+ state->x.pos += len;
+ return len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* check flush parameter */
+ if (flush < 0 || flush > Z_FINISH)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* compress remaining data with requested flush */
+ gz_comp(state, flush);
+ return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* if no change is requested, then do nothing */
+ if (level == state->level && strategy == state->strategy)
+ return Z_OK;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* change compression parameters for subsequent input */
+ if (state->size) {
+ /* flush previous input with previous parameters before changing */
+ if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
+ return state->err;
+ deflateParams(strm, level, strategy);
+ }
+ state->level = level;
+ state->strategy = strategy;
+ return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+ gzFile file;
+{
+ int ret = Z_OK;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing */
+ if (state->mode != GZ_WRITE)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ ret = state->err;
+ }
+
+ /* flush, free memory, and close file */
+ if (gz_comp(state, Z_FINISH) == -1)
+ ret = state->err;
+ if (state->size) {
+ if (!state->direct) {
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ }
+ free(state->in);
+ }
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ if (close(state->fd) == -1)
+ ret = Z_ERRNO;
+ free(state);
+ return ret;
+}
diff --git a/usr/src/boot/lib/libz/infback.c b/usr/src/boot/lib/libz/infback.c
new file mode 100644
index 0000000000..f3833c2e43
--- /dev/null
+++ b/usr/src/boot/lib/libz/infback.c
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
+ state->wbits = windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->wnext = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ state->length = (unsigned)here.val;
+
+ /* process literal */
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/usr/src/boot/lib/libz/inffast.c b/usr/src/boot/lib/libz/inffast.c
new file mode 100644
index 0000000000..bda59ceb6a
--- /dev/null
+++ b/usr/src/boot/lib/libz/inffast.c
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code here; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ wnext = state->wnext;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ here = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ PUP(out) = (unsigned char)(here.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ here = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ PUP(out) = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ PUP(out) = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ PUP(out) = PUP(from);
+ } while (--len);
+ continue;
+ }
+#endif
+ }
+ from = window - OFF;
+ if (wnext == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += wnext - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and wnext == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/usr/src/boot/lib/libz/inffast.h b/usr/src/boot/lib/libz/inffast.h
new file mode 100644
index 0000000000..e5c1aa4ca8
--- /dev/null
+++ b/usr/src/boot/lib/libz/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/usr/src/boot/lib/libz/inffixed.h b/usr/src/boot/lib/libz/inffixed.h
new file mode 100644
index 0000000000..d628327769
--- /dev/null
+++ b/usr/src/boot/lib/libz/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/usr/src/boot/lib/libz/inflate.c b/usr/src/boot/lib/libz/inflate.c
new file mode 100644
index 0000000000..b51a8a50ad
--- /dev/null
+++ b/usr/src/boot/lib/libz/inflate.c
@@ -0,0 +1,1512 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+ int wrap;
+ struct inflate_state FAR *state;
+
+ /* get the state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ int ret;
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->window = Z_NULL;
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ }
+ return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+ struct inflate_state FAR *state;
+ unsigned dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->wnext = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, end - state->wsize, state->wsize);
+ state->wnext = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->wnext;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->wnext, end - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, end - copy, copy);
+ state->wnext = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (state->wbits == 0)
+ state->wbits = len;
+ else if (len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = ZSWAP32(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (const code FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
+ break;
+ }
+ state->back = 0;
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ state->mode = LIT;
+ break;
+ }
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
+ state->mode = TYPE;
+ break;
+ }
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->wnext - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ ZSWAP32(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long dictid;
+ int ret;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary identifier */
+ if (state->mode == DICT) {
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ return Z_OK;
+#else
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16);
+ state = (struct inflate_state FAR *)strm->state;
+ return ((long)(state->back) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/usr/src/boot/lib/libz/inflate.h b/usr/src/boot/lib/libz/inflate.h
new file mode 100644
index 0000000000..95f4986d40
--- /dev/null
+++ b/usr/src/boot/lib/libz/inflate.h
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
+ Read deflate blocks:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 10K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
+};
diff --git a/usr/src/boot/lib/libz/inftrees.c b/usr/src/boot/lib/libz/inftrees.c
new file mode 100644
index 0000000000..44d89cf24e
--- /dev/null
+++ b/usr/src/boot/lib/libz/inftrees.c
@@ -0,0 +1,306 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code here; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min < max; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ here.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ here.op = (unsigned char)0;
+ here.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ here.op = (unsigned char)(extra[work[sym]]);
+ here.val = base[work[sym]];
+ }
+ else {
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = here;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/usr/src/boot/lib/libz/inftrees.h b/usr/src/boot/lib/libz/inftrees.h
new file mode 100644
index 0000000000..baa53a0b1a
--- /dev/null
+++ b/usr/src/boot/lib/libz/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/usr/src/boot/lib/libz/test/example.c b/usr/src/boot/lib/libz/test/example.c
new file mode 100644
index 0000000000..138a699bd5
--- /dev/null
+++ b/usr/src/boot/lib/libz/test/example.c
@@ -0,0 +1,601 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+ q = Z_NULL;
+ free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, (int)sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ (int)sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+
+#ifdef Z_SOLO
+ argc = strlen(argv[0]);
+#else
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+#endif
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
diff --git a/usr/src/boot/lib/libz/test/infcover.c b/usr/src/boot/lib/libz/test/infcover.c
new file mode 100644
index 0000000000..fe3d9203a0
--- /dev/null
+++ b/usr/src/boot/lib/libz/test/infcover.c
@@ -0,0 +1,671 @@
+/* infcover.c -- test zlib's inflate routines with full code coverage
+ * Copyright (C) 2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* to use, do: ./configure --cover && make cover */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+/* get definition of internal structure so we can mess with it (see pull()),
+ and so we can call inflate_trees() (see cover5()) */
+#define ZLIB_INTERNAL
+#include "inftrees.h"
+#include "inflate.h"
+
+#define local static
+
+/* -- memory tracking routines -- */
+
+/*
+ These memory tracking routines are provided to zlib and track all of zlib's
+ allocations and deallocations, check for LIFO operations, keep a current
+ and high water mark of total bytes requested, optionally set a limit on the
+ total memory that can be allocated, and when done check for memory leaks.
+
+ They are used as follows:
+
+ z_stream strm;
+ mem_setup(&strm) initializes the memory tracking and sets the
+ zalloc, zfree, and opaque members of strm to use
+ memory tracking for all zlib operations on strm
+ mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
+ request that exceeds this limit will result in an
+ allocation failure (returns NULL) -- setting the
+ limit to zero means no limit, which is the default
+ after mem_setup()
+ mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
+ mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
+ mem_done(&strm, "msg") ends memory tracking, releases all allocations
+ for the tracking as well as leaked zlib blocks, if
+ any. If there was anything unusual, such as leaked
+ blocks, non-FIFO frees, or frees of addresses not
+ allocated, then "msg" and information about the
+ problem is printed to stderr. If everything is
+ normal, nothing is printed. mem_done resets the
+ strm members to Z_NULL to use the default memory
+ allocation routines on the next zlib initialization
+ using strm.
+ */
+
+/* these items are strung together in a linked list, one for each allocation */
+struct mem_item {
+ void *ptr; /* pointer to allocated memory */
+ size_t size; /* requested size of allocation */
+ struct mem_item *next; /* pointer to next item in list, or NULL */
+};
+
+/* this structure is at the root of the linked list, and tracks statistics */
+struct mem_zone {
+ struct mem_item *first; /* pointer to first item in list, or NULL */
+ size_t total, highwater; /* total allocations, and largest total */
+ size_t limit; /* memory allocation limit, or 0 if no limit */
+ int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
+};
+
+/* memory allocation routine to pass to zlib */
+local void *mem_alloc(void *mem, unsigned count, unsigned size)
+{
+ void *ptr;
+ struct mem_item *item;
+ struct mem_zone *zone = mem;
+ size_t len = count * (size_t)size;
+
+ /* induced allocation failure */
+ if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
+ return NULL;
+
+ /* perform allocation using the standard library, fill memory with a
+ non-zero value to make sure that the code isn't depending on zeros */
+ ptr = malloc(len);
+ if (ptr == NULL)
+ return NULL;
+ memset(ptr, 0xa5, len);
+
+ /* create a new item for the list */
+ item = malloc(sizeof(struct mem_item));
+ if (item == NULL) {
+ free(ptr);
+ return NULL;
+ }
+ item->ptr = ptr;
+ item->size = len;
+
+ /* insert item at the beginning of the list */
+ item->next = zone->first;
+ zone->first = item;
+
+ /* update the statistics */
+ zone->total += item->size;
+ if (zone->total > zone->highwater)
+ zone->highwater = zone->total;
+
+ /* return the allocated memory */
+ return ptr;
+}
+
+/* memory free routine to pass to zlib */
+local void mem_free(void *mem, void *ptr)
+{
+ struct mem_item *item, *next;
+ struct mem_zone *zone = mem;
+
+ /* if no zone, just do a free */
+ if (zone == NULL) {
+ free(ptr);
+ return;
+ }
+
+ /* point next to the item that matches ptr, or NULL if not found -- remove
+ the item from the linked list if found */
+ next = zone->first;
+ if (next) {
+ if (next->ptr == ptr)
+ zone->first = next->next; /* first one is it, remove from list */
+ else {
+ do { /* search the linked list */
+ item = next;
+ next = item->next;
+ } while (next != NULL && next->ptr != ptr);
+ if (next) { /* if found, remove from linked list */
+ item->next = next->next;
+ zone->notlifo++; /* not a LIFO free */
+ }
+
+ }
+ }
+
+ /* if found, update the statistics and free the item */
+ if (next) {
+ zone->total -= next->size;
+ free(next);
+ }
+
+ /* if not found, update the rogue count */
+ else
+ zone->rogue++;
+
+ /* in any case, do the requested free with the standard library function */
+ free(ptr);
+}
+
+/* set up a controlled memory allocation space for monitoring, set the stream
+ parameters to the controlled routines, with opaque pointing to the space */
+local void mem_setup(z_stream *strm)
+{
+ struct mem_zone *zone;
+
+ zone = malloc(sizeof(struct mem_zone));
+ assert(zone != NULL);
+ zone->first = NULL;
+ zone->total = 0;
+ zone->highwater = 0;
+ zone->limit = 0;
+ zone->notlifo = 0;
+ zone->rogue = 0;
+ strm->opaque = zone;
+ strm->zalloc = mem_alloc;
+ strm->zfree = mem_free;
+}
+
+/* set a limit on the total memory allocation, or 0 to remove the limit */
+local void mem_limit(z_stream *strm, size_t limit)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ zone->limit = limit;
+}
+
+/* show the current total requested allocations in bytes */
+local void mem_used(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
+}
+
+/* show the high water allocation in bytes */
+local void mem_high(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
+}
+
+/* release the memory allocation zone -- if there are any surprises, notify */
+local void mem_done(z_stream *strm, char *prefix)
+{
+ int count = 0;
+ struct mem_item *item, *next;
+ struct mem_zone *zone = strm->opaque;
+
+ /* show high water mark */
+ mem_high(strm, prefix);
+
+ /* free leftover allocations and item structures, if any */
+ item = zone->first;
+ while (item != NULL) {
+ free(item->ptr);
+ next = item->next;
+ free(item);
+ item = next;
+ count++;
+ }
+
+ /* issue alerts about anything unexpected */
+ if (count || zone->total)
+ fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
+ prefix, zone->total, count);
+ if (zone->notlifo)
+ fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
+ if (zone->rogue)
+ fprintf(stderr, "** %s: %d frees not recognized\n",
+ prefix, zone->rogue);
+
+ /* free the zone and delete from the stream */
+ free(zone);
+ strm->opaque = Z_NULL;
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+}
+
+/* -- inflate test routines -- */
+
+/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
+ decodes liberally, in that hex digits can be adjacent, in which case two in
+ a row writes a byte. Or they can delimited by any non-hex character, where
+ the delimiters are ignored except when a single hex digit is followed by a
+ delimiter in which case that single digit writes a byte. The returned
+ data is allocated and must eventually be freed. NULL is returned if out of
+ memory. If the length is not needed, then len can be NULL. */
+local unsigned char *h2b(const char *hex, unsigned *len)
+{
+ unsigned char *in;
+ unsigned next, val;
+
+ in = malloc((strlen(hex) + 1) >> 1);
+ if (in == NULL)
+ return NULL;
+ next = 0;
+ val = 1;
+ do {
+ if (*hex >= '0' && *hex <= '9')
+ val = (val << 4) + *hex - '0';
+ else if (*hex >= 'A' && *hex <= 'F')
+ val = (val << 4) + *hex - 'A' + 10;
+ else if (*hex >= 'a' && *hex <= 'f')
+ val = (val << 4) + *hex - 'a' + 10;
+ else if (val != 1 && val < 32) /* one digit followed by delimiter */
+ val += 240; /* make it look like two digits */
+ if (val > 255) { /* have two digits */
+ in[next++] = val & 0xff; /* save the decoded byte */
+ val = 1; /* start over */
+ }
+ } while (*hex++); /* go through the loop with the terminating null */
+ if (len != NULL)
+ *len = next;
+ in = reallocf(in, next);
+ return in;
+}
+
+/* generic inflate() run, where hex is the hexadecimal input data, what is the
+ text to include in an error message, step is how much input data to feed
+ inflate() on each call, or zero to feed it all, win is the window bits
+ parameter to inflateInit2(), len is the size of the output buffer, and err
+ is the error code expected from the first inflate() call (the second
+ inflate() call is expected to return Z_STREAM_END). If win is 47, then
+ header information is collected with inflateGetHeader(). If a zlib stream
+ is looking for a dictionary, then an empty dictionary is provided.
+ inflate() is run until all of the input data is consumed. */
+local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
+ int err)
+{
+ int ret;
+ unsigned have;
+ unsigned char *in, *out;
+ z_stream strm, copy;
+ gz_header head;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, win);
+ if (ret != Z_OK) {
+ mem_done(&strm, what);
+ return;
+ }
+ out = malloc(len); assert(out != NULL);
+ if (win == 47) {
+ head.extra = out;
+ head.extra_max = len;
+ head.name = out;
+ head.name_max = len;
+ head.comment = out;
+ head.comm_max = len;
+ ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
+ }
+ in = h2b(hex, &have); assert(in != NULL);
+ if (step == 0 || step > have)
+ step = have;
+ strm.avail_in = step;
+ have -= step;
+ strm.next_in = in;
+ do {
+ strm.avail_out = len;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
+ if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
+ break;
+ if (ret == Z_NEED_DICT) {
+ ret = inflateSetDictionary(&strm, in, 1);
+ assert(ret == Z_DATA_ERROR);
+ mem_limit(&strm, 1);
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ((struct inflate_state *)strm.state)->mode = DICT;
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_OK);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
+ }
+ ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
+ ret = inflateEnd(&copy); assert(ret == Z_OK);
+ err = 9; /* don't care next time around */
+ have += strm.avail_in;
+ strm.avail_in = step > have ? have : step;
+ have -= strm.avail_in;
+ } while (strm.avail_in);
+ free(in);
+ free(out);
+ ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, what);
+}
+
+/* cover all of the lines in inflate.c up to inflate() */
+local void cover_support(void)
+{
+ int ret;
+ z_stream strm;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ mem_used(&strm, "inflate init");
+ ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
+ ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
+ ret = inflateSetDictionary(&strm, Z_NULL, 0);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "prime");
+
+ inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
+ inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
+ inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
+ inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
+ inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+ assert(ret == Z_VERSION_ERROR);
+ mem_done(&strm, "wrong version");
+
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ fputs("inflate built-in memory routines\n", stderr);
+}
+
+/* cover all inflate() header and trailer cases and code after inflate() */
+local void cover_wrap(void)
+{
+ int ret;
+ z_stream strm, copy;
+ unsigned char dict[257];
+
+ ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflate bad parameters\n", stderr);
+
+ inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
+ inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
+ inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
+ inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
+ inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
+ inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
+ inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
+ Z_DATA_ERROR);
+ inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
+ 0, 47, 0, Z_STREAM_END);
+ inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
+ inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
+ inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, -8);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x63";
+ strm.avail_out = 1;
+ strm.next_out = (void *)&ret;
+ mem_limit(&strm, 1);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ memset(dict, 0, 257);
+ ret = inflateSetDictionary(&strm, dict, 257);
+ assert(ret == Z_OK);
+ mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
+ ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x80";
+ ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
+ strm.avail_in = 4;
+ strm.next_in = (void *)"\0\0\xff\xff";
+ ret = inflateSync(&strm); assert(ret == Z_OK);
+ (void)inflateSyncPoint(&strm);
+ ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
+ (void)inflateMark(&strm);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "miscellaneous, force memory errors");
+}
+
+/* input and output functions for inflateBack() */
+local unsigned pull(void *desc, unsigned char **buf)
+{
+ static unsigned int next = 0;
+ static unsigned char dat[] = {0x63, 0, 2, 0};
+ struct inflate_state *state;
+
+ if (desc == Z_NULL) {
+ next = 0;
+ return 0; /* no input (already provided at next_in) */
+ }
+ state = (void *)((z_stream *)desc)->state;
+ if (state != Z_NULL)
+ state->mode = SYNC; /* force an otherwise impossible situation */
+ return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
+}
+
+local int push(void *desc, unsigned char *buf, unsigned len)
+{
+ buf += len;
+ return desc != Z_NULL; /* force error if desc not null */
+}
+
+/* cover inflateBack() up to common deflate data cases and after those */
+local void cover_back(void)
+{
+ int ret;
+ z_stream strm;
+ unsigned char win[32768];
+
+ ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
+ assert(ret == Z_VERSION_ERROR);
+ ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
+ ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflateBack bad parameters\n", stderr);
+
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x03";
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret == Z_STREAM_END);
+ /* force output error */
+ strm.avail_in = 3;
+ strm.next_in = (void *)"\x63\x00";
+ ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
+ assert(ret == Z_BUF_ERROR);
+ /* force mode error by mucking with state */
+ ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "inflateBack bad state");
+
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ fputs("inflateBack built-in memory routines\n", stderr);
+}
+
+/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
+local int try(char *hex, char *id, int err)
+{
+ int ret;
+ unsigned len, size;
+ unsigned char *in, *out, *win;
+ char *prefix;
+ z_stream strm;
+
+ /* convert to hex */
+ in = h2b(hex, &len);
+ assert(in != NULL);
+
+ /* allocate work areas */
+ size = len << 3;
+ out = malloc(size);
+ assert(out != NULL);
+ win = malloc(32768);
+ assert(win != NULL);
+ prefix = malloc(strlen(id) + 6);
+ assert(prefix != NULL);
+
+ /* first with inflate */
+ strcpy(prefix, id);
+ strcat(prefix, "-late");
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, err < 0 ? 47 : -15);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ do {
+ strm.avail_out = size;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_TREES);
+ assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
+ if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
+ break;
+ } while (strm.avail_in || strm.avail_out == 0);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateEnd(&strm);
+ mem_done(&strm, prefix);
+
+ /* then with inflateBack */
+ if (err >= 0) {
+ strcpy(prefix, id);
+ strcat(prefix, "-back");
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret != Z_STREAM_ERROR);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateBackEnd(&strm);
+ mem_done(&strm, prefix);
+ }
+
+ /* clean up */
+ free(prefix);
+ free(win);
+ free(out);
+ free(in);
+ return ret;
+}
+
+/* cover deflate data cases in both inflate() and inflateBack() */
+local void cover_inflate(void)
+{
+ try("0 0 0 0 0", "invalid stored block lengths", 1);
+ try("3 0", "fixed", 0);
+ try("6", "invalid block type", 1);
+ try("1 1 0 fe ff 0", "stored", 0);
+ try("fc 0 0", "too many length or distance symbols", 1);
+ try("4 0 fe ff", "invalid code lengths set", 1);
+ try("4 0 24 49 0", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
+ try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
+ "invalid literal/lengths set", 1);
+ try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
+ try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
+ try("2 7e ff ff", "invalid distance code", 1);
+ try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
+
+ /* also trailer mismatch just in inflate() */
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
+ "incorrect length check", -1);
+ try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
+ try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
+ "long code", 0);
+ try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
+ try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
+ "long distance and extra", 0);
+ try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
+ inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
+ Z_STREAM_END);
+ inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
+}
+
+/* cover remaining lines in inftrees.c */
+local void cover_trees(void)
+{
+ int ret;
+ unsigned bits;
+ unsigned short lens[16], work[16];
+ code *next, table[ENOUGH_DISTS];
+
+ /* we need to call inflate_table() directly in order to manifest not-
+ enough errors, since zlib insures that enough is always enough */
+ for (bits = 0; bits < 15; bits++)
+ lens[bits] = (unsigned short)(bits + 1);
+ lens[15] = 15;
+ next = table;
+ bits = 15;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ next = table;
+ bits = 1;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ fputs("inflate_table not enough errors\n", stderr);
+}
+
+/* cover remaining inffast.c decoding and window copying */
+local void cover_fast(void)
+{
+ inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
+ " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
+ inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
+ " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
+ "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
+ inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
+ inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
+ "contiguous and wrap around window", 6, -8, 259, Z_OK);
+ inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
+ Z_STREAM_END);
+}
+
+int main(void)
+{
+ fprintf(stderr, "%s\n", zlibVersion());
+ cover_support();
+ cover_wrap();
+ cover_back();
+ cover_inflate();
+ cover_trees();
+ cover_fast();
+ return 0;
+}
diff --git a/usr/src/boot/lib/libz/test/minigzip.c b/usr/src/boot/lib/libz/test/minigzip.c
new file mode 100644
index 0000000000..b3025a489a
--- /dev/null
+++ b/usr/src/boot/lib/libz/test/minigzip.c
@@ -0,0 +1,651 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include <fcntl.h>
+# include <io.h>
+# ifdef UNDER_CE
+# include <stdlib.h>
+# endif
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+#ifdef VMS
+# define unlink delete
+# define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+# define unlink remove
+# define GZ_SUFFIX "-gz"
+# define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fileno */
+#endif
+
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
+#endif
+
+#if defined(UNDER_CE)
+# include <windows.h>
+# define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+ message string and return a pointer to it. Typically, the values
+ for ERROR come from GetLastError.
+
+ The string pointed to shall not be modified by the application,
+ but may be overwritten by a subsequent call to strwinerror
+
+ The strwinerror function does not change the current setting
+ of GetLastError. */
+
+static char *strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+static void pwinerror (s)
+ const char *s;
+{
+ if (s && *s)
+ fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+ else
+ fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
+
+#ifndef GZ_SUFFIX
+# define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN 16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+# define local static
+ /* Needed for systems with limitation on stack size. */
+#else
+# define local
+#endif
+
+#ifdef Z_SOLO
+/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
+
+#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
+# include <unistd.h> /* for unlink() */
+#endif
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(q, p)
+ void *q, *p;
+{
+ q = Z_NULL;
+ free(p);
+}
+
+typedef struct gzFile_s {
+ FILE *file;
+ int write;
+ int err;
+ char *msg;
+ z_stream strm;
+} *gzFile;
+
+gzFile gzopen OF((const char *, const char *));
+gzFile gzdopen OF((int, const char *));
+gzFile gz_open OF((const char *, int, const char *));
+
+gzFile gzopen(path, mode)
+const char *path;
+const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+gzFile gzdopen(fd, mode)
+int fd;
+const char *mode;
+{
+ return gz_open(NULL, fd, mode);
+}
+
+gzFile gz_open(path, fd, mode)
+ const char *path;
+ int fd;
+ const char *mode;
+{
+ gzFile gz;
+ int ret;
+
+ gz = malloc(sizeof(struct gzFile_s));
+ if (gz == NULL)
+ return NULL;
+ gz->write = strchr(mode, 'w') != NULL;
+ gz->strm.zalloc = myalloc;
+ gz->strm.zfree = myfree;
+ gz->strm.opaque = Z_NULL;
+ if (gz->write)
+ ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
+ else {
+ gz->strm.next_in = 0;
+ gz->strm.avail_in = Z_NULL;
+ ret = inflateInit2(&(gz->strm), 15 + 16);
+ }
+ if (ret != Z_OK) {
+ free(gz);
+ return NULL;
+ }
+ gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
+ fopen(path, gz->write ? "wb" : "rb");
+ if (gz->file == NULL) {
+ gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
+ free(gz);
+ return NULL;
+ }
+ gz->err = 0;
+ gz->msg = "";
+ return gz;
+}
+
+int gzwrite OF((gzFile, const void *, unsigned));
+
+int gzwrite(gz, buf, len)
+ gzFile gz;
+ const void *buf;
+ unsigned len;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL || !gz->write)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_in = (void *)buf;
+ strm->avail_in = len;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_NO_FLUSH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ return len;
+}
+
+int gzread OF((gzFile, void *, unsigned));
+
+int gzread(gz, buf, len)
+ gzFile gz;
+ void *buf;
+ unsigned len;
+{
+ int ret;
+ unsigned got;
+ unsigned char in[1];
+ z_stream *strm;
+
+ if (gz == NULL || gz->write)
+ return 0;
+ if (gz->err)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_out = (void *)buf;
+ strm->avail_out = len;
+ do {
+ got = fread(in, 1, 1, gz->file);
+ if (got == 0)
+ break;
+ strm->next_in = in;
+ strm->avail_in = 1;
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_DATA_ERROR) {
+ gz->err = Z_DATA_ERROR;
+ gz->msg = strm->msg;
+ return 0;
+ }
+ if (ret == Z_STREAM_END)
+ inflateReset(strm);
+ } while (strm->avail_out);
+ return len - strm->avail_out;
+}
+
+int gzclose OF((gzFile));
+
+int gzclose(gz)
+ gzFile gz;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL)
+ return Z_STREAM_ERROR;
+ strm = &(gz->strm);
+ if (gz->write) {
+ strm->next_in = Z_NULL;
+ strm->avail_in = 0;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_FINISH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ deflateEnd(strm);
+ }
+ else
+ inflateEnd(strm);
+ fclose(gz->file);
+ free(gz);
+ return Z_OK;
+}
+
+const char *gzerror OF((gzFile, int *));
+
+const char *gzerror(gz, err)
+ gzFile gz;
+ int *err;
+{
+ *err = gz->err;
+ return gz->msg;
+}
+
+#endif
+
+char *prog;
+
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+ const char *msg;
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+ FILE *in;
+ gzFile out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+ for (;;) {
+ len = (int)fread(buf, 1, sizeof(buf), in);
+ if (ferror(in)) {
+ perror("fread");
+ exit(1);
+ }
+ if (len == 0) break;
+
+ if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+ }
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+ gzFile in;
+ FILE *out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+ for (;;) {
+ len = gzread(in, buf, sizeof(buf));
+ if (len < 0) error (gzerror(in, &err));
+ if (len == 0) break;
+
+ if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+ error("failed fwrite");
+ }
+ }
+ if (fclose(out)) error("failed fclose");
+
+ if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+ char *file;
+ char *mode;
+{
+ local char outfile[MAX_NAME_LEN];
+ FILE *in;
+ gzFile out;
+
+ if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
+ fprintf(stderr, "%s: filename too long\n", prog);
+ exit(1);
+ }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
+#else
+ strcpy(outfile, file);
+ strcat(outfile, GZ_SUFFIX);
+#endif
+
+ in = fopen(file, "rb");
+ if (in == NULL) {
+ perror(file);
+ exit(1);
+ }
+ out = gzopen(outfile, mode);
+ if (out == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+ exit(1);
+ }
+ gz_compress(in, out);
+
+ unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+ char *file;
+{
+ local char buf[MAX_NAME_LEN];
+ char *infile, *outfile;
+ FILE *out;
+ gzFile in;
+ size_t len = strlen(file);
+
+ if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
+ fprintf(stderr, "%s: filename too long\n", prog);
+ exit(1);
+ }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf, sizeof(buf), "%s", file);
+#else
+ strcpy(buf, file);
+#endif
+
+ if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+ infile = file;
+ outfile = buf;
+ outfile[len-3] = '\0';
+ } else {
+ outfile = file;
+ infile = buf;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
+#else
+ strcat(infile, GZ_SUFFIX);
+#endif
+ }
+ in = gzopen(infile, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+ exit(1);
+ }
+ out = fopen(outfile, "wb");
+ if (out == NULL) {
+ perror(file);
+ exit(1);
+ }
+
+ gz_uncompress(in, out);
+
+ unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ * -c : write to standard output
+ * -d : decompress
+ * -f : compress with Z_FILTERED
+ * -h : compress with Z_HUFFMAN_ONLY
+ * -r : compress with Z_RLE
+ * -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int copyout = 0;
+ int uncompr = 0;
+ gzFile file;
+ char *bname, outmode[20];
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
+#else
+ strcpy(outmode, "wb6 ");
+#endif
+
+ prog = argv[0];
+ bname = strrchr(argv[0], '/');
+ if (bname)
+ bname++;
+ else
+ bname = argv[0];
+ argc--, argv++;
+
+ if (!strcmp(bname, "gunzip"))
+ uncompr = 1;
+ else if (!strcmp(bname, "zcat"))
+ copyout = uncompr = 1;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "-c") == 0)
+ copyout = 1;
+ else if (strcmp(*argv, "-d") == 0)
+ uncompr = 1;
+ else if (strcmp(*argv, "-f") == 0)
+ outmode[3] = 'f';
+ else if (strcmp(*argv, "-h") == 0)
+ outmode[3] = 'h';
+ else if (strcmp(*argv, "-r") == 0)
+ outmode[3] = 'R';
+ else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+ (*argv)[2] == 0)
+ outmode[2] = (*argv)[1];
+ else
+ break;
+ argc--, argv++;
+ }
+ if (outmode[3] == ' ')
+ outmode[3] = 0;
+ if (argc == 0) {
+ SET_BINARY_MODE(stdin);
+ SET_BINARY_MODE(stdout);
+ if (uncompr) {
+ file = gzdopen(fileno(stdin), "rb");
+ if (file == NULL) error("can't gzdopen stdin");
+ gz_uncompress(file, stdout);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+ gz_compress(stdin, file);
+ }
+ } else {
+ if (copyout) {
+ SET_BINARY_MODE(stdout);
+ }
+ do {
+ if (uncompr) {
+ if (copyout) {
+ file = gzopen(*argv, "rb");
+ if (file == NULL)
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+ else
+ gz_uncompress(file, stdout);
+ } else {
+ file_uncompress(*argv);
+ }
+ } else {
+ if (copyout) {
+ FILE * in = fopen(*argv, "rb");
+
+ if (in == NULL) {
+ perror(*argv);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+
+ gz_compress(in, file);
+ }
+
+ } else {
+ file_compress(*argv, outmode);
+ }
+ }
+ } while (argv++, --argc);
+ }
+ return 0;
+}
diff --git a/usr/src/boot/lib/libz/trees.c b/usr/src/boot/lib/libz/trees.c
new file mode 100644
index 0000000000..1fd7759ef0
--- /dev/null
+++ b/usr/src/boot/lib/libz/trees.c
@@ -0,0 +1,1226 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+ const ct_data *dtree));
+local int detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (ush)val << s->bi_valid;\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header,
+ "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+ deflate_state *s;
+{
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+last, 3);
+ compress_block(s, (const ct_data *)static_ltree,
+ (const ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+last, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (const ct_data *)s->dyn_ltree,
+ (const ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (last) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ const ct_data *ltree; /* literal tree */
+ const ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+ deflate_state *s;
+{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
+ int n;
+
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/usr/src/boot/lib/libz/trees.h b/usr/src/boot/lib/libz/trees.h
new file mode 100644
index 0000000000..d35639d82a
--- /dev/null
+++ b/usr/src/boot/lib/libz/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/usr/src/boot/lib/libz/uncompr.c b/usr/src/boot/lib/libz/uncompr.c
new file mode 100644
index 0000000000..242e9493df
--- /dev/null
+++ b/usr/src/boot/lib/libz/uncompr.c
@@ -0,0 +1,59 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/usr/src/boot/lib/libz/zconf.h b/usr/src/boot/lib/libz/zconf.h
new file mode 100644
index 0000000000..13a2e1c71a
--- /dev/null
+++ b/usr/src/boot/lib/libz/zconf.h
@@ -0,0 +1,519 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#if 0 /* was set to #if 0 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+/*
+ * This is hard-configured for FreeBSD.
+ */
+#define z_off_t off_t
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/usr/src/boot/lib/libz/zlib.3 b/usr/src/boot/lib/libz/zlib.3
new file mode 100644
index 0000000000..0160e62b69
--- /dev/null
+++ b/usr/src/boot/lib/libz/zlib.3
@@ -0,0 +1,151 @@
+.TH ZLIB 3 "28 Apr 2013"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms may be added later
+with the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in the case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I test/example.c
+and
+.IR test/minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source.
+.LP
+.I zlib
+is available in Java using the java.util.zip package:
+.IP
+http://java.sun.com/developer/technicalArticles/Programming/compression/
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://docs.python.org/library/zlib.html
+.LP
+.I zlib
+is built into
+.IR tcl:
+.IP
+http://wiki.tcl.tk/4610
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/minizip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+source distribution.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at:
+.IP
+http://zlib.net/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
+.br
+http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
+.br
+http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
+.LP
+Mark Nelson wrote an article about
+.I zlib
+for the Jan. 1997 issue of Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://marknelson.us/1997/01/01/zlib-engine/
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://zlib.net/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.8
+Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/usr/src/boot/lib/libz/zlib.h b/usr/src/boot/lib/libz/zlib.h
new file mode 100644
index 0000000000..3e0c7672ac
--- /dev/null
+++ b/usr/src/boot/lib/libz/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.8, April 28th, 2013
+
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/usr/src/boot/lib/libz/zlib.pc b/usr/src/boot/lib/libz/zlib.pc
new file mode 100644
index 0000000000..63a214f6ba
--- /dev/null
+++ b/usr/src/boot/lib/libz/zlib.pc
@@ -0,0 +1,14 @@
+# $FreeBSD$
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+sharedlibdir=${libdir}
+includedir=${prefix}/include
+
+Name: zlib
+Description: zlib compression library
+Version: 1.2.8
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/usr/src/boot/lib/libz/zopen.3 b/usr/src/boot/lib/libz/zopen.3
new file mode 100644
index 0000000000..d7e631afd3
--- /dev/null
+++ b/usr/src/boot/lib/libz/zopen.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 2014 Xin Li <delphij@FreeBSD.org>
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 5, 2014
+.Dt ZOPEN 3
+.Os
+.Sh NAME
+.Nm zopen
+.Nd open a gzip compressed stream
+.Sh LIBRARY
+.Lb libz
+.Sh SYNOPSIS
+.Ft FILE *
+.Fn zopen "const char *path" "const char *mode"
+.Sh DESCRIPTION
+The
+.Fn zopen
+opens a gzip file whose name is the string pointed to by
+.Fa path
+and associates a stream with it.
+It is a wrapper around
+.Xr zlib 3
+and standard stream I/O APIs.
+.Pp
+The argument
+.Fa mode
+have the same meaning as it does in
+.Xr fopen 3 .
+.Pp
+The
+.Nm
+function will associate read, write, seek and close
+functions of
+.Xr zlib 3
+after successfully opened a file with
+.Xr funopen 3
+so that they will be used to read or write the new stream.
+.Sh RETURN VALUES
+Upon successful completion
+.Nm
+returns a
+.Tn FILE
+pointer.
+Otherwise,
+.Dv NULL
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+In addition to the errors documented for
+.Xr fopen 3 ,
+the
+.Nm
+function may also fail for:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory is available.
+.El
+.Sh COMPATIBILITY
+This implementation of
+.Nm
+function first appeared in
+.Nx 1.6
+and
+.Fx 4.5 .
+The
+.Nm
+function may not be portable to systems other than
+.Fx .
+.Sh SEE ALSO
+.Xr fopen 3 ,
+.Xr funopen 3 ,
+.Xr zlib 3
diff --git a/usr/src/boot/lib/libz/zopen.c b/usr/src/boot/lib/libz/zopen.c
new file mode 100644
index 0000000000..cde022dcf0
--- /dev/null
+++ b/usr/src/boot/lib/libz/zopen.c
@@ -0,0 +1,49 @@
+/*
+ * Public domain stdio wrapper for libz, written by Johan Danielsson.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <zlib.h>
+
+FILE *zopen(const char *fname, const char *mode);
+
+/* convert arguments */
+static int
+xgzread(void *cookie, char *data, int size)
+{
+ return gzread(cookie, data, size);
+}
+
+static int
+xgzwrite(void *cookie, const char *data, int size)
+{
+ return gzwrite(cookie, (void*)data, size);
+}
+
+static int
+xgzclose(void *cookie)
+{
+ return gzclose(cookie);
+}
+
+static fpos_t
+xgzseek(void *cookie, fpos_t offset, int whence)
+{
+ return gzseek(cookie, (z_off_t)offset, whence);
+}
+
+FILE *
+zopen(const char *fname, const char *mode)
+{
+ gzFile gz = gzopen(fname, mode);
+ if(gz == NULL)
+ return NULL;
+
+ if(*mode == 'r')
+ return (funopen(gz, xgzread, NULL, xgzseek, xgzclose));
+ else
+ return (funopen(gz, NULL, xgzwrite, xgzseek, xgzclose));
+}
diff --git a/usr/src/boot/lib/libz/zutil.c b/usr/src/boot/lib/libz/zutil.c
new file mode 100644
index 0000000000..23d2ebef00
--- /dev/null
+++ b/usr/src/boot/lib/libz/zutil.c
@@ -0,0 +1,324 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+# include "gzguts.h"
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+z_const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch ((int)(sizeof(uInt))) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch ((int)(sizeof(uLong))) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch ((int)(sizeof(voidpf))) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch ((int)(sizeof(z_off_t))) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/usr/src/boot/lib/libz/zutil.h b/usr/src/boot/lib/libz/zutil.h
new file mode 100644
index 0000000000..24ab06b1cf
--- /dev/null
+++ b/usr/src/boot/lib/libz/zutil.h
@@ -0,0 +1,253 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# if defined(M_I86) && !defined(Z_SOLO)
+# include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/usr/src/boot/sys/amd64/include/_align.h b/usr/src/boot/sys/amd64/include/_align.h
new file mode 100644
index 0000000000..28c4669ad2
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/_align.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_align.h>
diff --git a/usr/src/boot/sys/amd64/include/_inttypes.h b/usr/src/boot/sys/amd64/include/_inttypes.h
new file mode 100644
index 0000000000..40107cd74a
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/_inttypes.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_inttypes.h>
diff --git a/usr/src/boot/sys/amd64/include/_limits.h b/usr/src/boot/sys/amd64/include/_limits.h
new file mode 100644
index 0000000000..3c7365bb4e
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/_limits.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_limits.h>
diff --git a/usr/src/boot/sys/amd64/include/_stdint.h b/usr/src/boot/sys/amd64/include/_stdint.h
new file mode 100644
index 0000000000..db1affc077
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/_stdint.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_stdint.h>
diff --git a/usr/src/boot/sys/amd64/include/_types.h b/usr/src/boot/sys/amd64/include/_types.h
new file mode 100644
index 0000000000..26803672ff
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/_types.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_types.h>
diff --git a/usr/src/boot/sys/amd64/include/asm.h b/usr/src/boot/sys/amd64/include/asm.h
new file mode 100644
index 0000000000..87272f76fd
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/asm.h
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define _MACHINE_ASM_H_
+
+#include <sys/cdefs.h>
+
+#ifdef PIC
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOTPCREL(%rip)
+#else
+#define PIC_PLT(x) x
+#endif
+
+/*
+ * CNAME and HIDENAME manage the relationship between symbol names in C
+ * and the equivalent assembly language names. CNAME is given a name as
+ * it would be used in a C program. It expands to the equivalent assembly
+ * language name. HIDENAME is given an assembly-language name, and expands
+ * to a possibly-modified form that will be invisible to C programs.
+ */
+#define CNAME(csym) csym
+#define HIDENAME(asmsym) .asmsym
+
+#define _START_ENTRY .text; .p2align 4,0x90
+
+#define _ENTRY(x) _START_ENTRY; \
+ .globl CNAME(x); .type CNAME(x),@function; CNAME(x):
+
+#ifdef PROF
+#define ALTENTRY(x) _ENTRY(x); \
+ pushq %rbp; movq %rsp,%rbp; \
+ call PIC_PLT(HIDENAME(mcount)); \
+ popq %rbp; \
+ jmp 9f
+#define ENTRY(x) _ENTRY(x); \
+ pushq %rbp; movq %rsp,%rbp; \
+ call PIC_PLT(HIDENAME(mcount)); \
+ popq %rbp; \
+ 9:
+#else
+#define ALTENTRY(x) _ENTRY(x)
+#define ENTRY(x) _ENTRY(x)
+#endif
+
+#define END(x) .size x, . - x
+/*
+ * WEAK_REFERENCE(): create a weak reference alias from sym.
+ * The macro is not a general asm macro that takes arbitrary names,
+ * but one that takes only C names. It does the non-null name
+ * translation inside the macro.
+ */
+#define WEAK_REFERENCE(sym, alias) \
+ .weak CNAME(alias); \
+ .equ CNAME(alias),CNAME(sym)
+
+#define RCSID(x) .text; .asciz x
+
+#undef __FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define __FBSDID(s) .ident s
+#else
+#define __FBSDID(s) /* nothing */
+#endif /* not lint and not STRIP_FBSDID */
+
+#endif /* !_MACHINE_ASM_H_ */
diff --git a/usr/src/boot/sys/amd64/include/asmacros.h b/usr/src/boot/sys/amd64/include/asmacros.h
new file mode 100644
index 0000000000..d5652c4a70
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/asmacros.h
@@ -0,0 +1,240 @@
+/*-
+ * Copyright (c) 1993 The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_ASMACROS_H_
+#define _MACHINE_ASMACROS_H_
+
+#include <sys/cdefs.h>
+
+/* XXX too much duplication in various asm*.h's. */
+
+/*
+ * CNAME is used to manage the relationship between symbol names in C
+ * and the equivalent assembly language names. CNAME is given a name as
+ * it would be used in a C program. It expands to the equivalent assembly
+ * language name.
+ */
+#define CNAME(csym) csym
+
+#define ALIGN_DATA .p2align 3 /* 8 byte alignment, zero filled */
+#ifdef GPROF
+#define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */
+#else
+#define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */
+#endif
+#define SUPERALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */
+
+#define GEN_ENTRY(name) ALIGN_TEXT; .globl CNAME(name); \
+ .type CNAME(name),@function; CNAME(name):
+#define NON_GPROF_ENTRY(name) GEN_ENTRY(name)
+#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */
+
+#define END(name) .size name, . - name
+
+#ifdef GPROF
+/*
+ * __mcount is like [.]mcount except that doesn't require its caller to set
+ * up a frame pointer. It must be called before pushing anything onto the
+ * stack. gcc should eventually generate code to call __mcount in most
+ * cases. This would make -pg in combination with -fomit-frame-pointer
+ * useful. gcc has a configuration variable PROFILE_BEFORE_PROLOGUE to
+ * allow profiling before setting up the frame pointer, but this is
+ * inadequate for good handling of special cases, e.g., -fpic works best
+ * with profiling after the prologue.
+ *
+ * [.]mexitcount is a new function to support non-statistical profiling if an
+ * accurate clock is available. For C sources, calls to it are generated
+ * by the FreeBSD extension `-mprofiler-epilogue' to gcc. It is best to
+ * call [.]mexitcount at the end of a function like the MEXITCOUNT macro does,
+ * but gcc currently generates calls to it at the start of the epilogue to
+ * avoid problems with -fpic.
+ *
+ * [.]mcount and __mcount may clobber the call-used registers and %ef.
+ * [.]mexitcount may clobber %ecx and %ef.
+ *
+ * Cross-jumping makes non-statistical profiling timing more complicated.
+ * It is handled in many cases by calling [.]mexitcount before jumping. It
+ * is handled for conditional jumps using CROSSJUMP() and CROSSJUMP_LABEL().
+ * It is handled for some fault-handling jumps by not sharing the exit
+ * routine.
+ *
+ * ALTENTRY() must be before a corresponding ENTRY() so that it can jump to
+ * the main entry point. Note that alt entries are counted twice. They
+ * have to be counted as ordinary entries for gprof to get the call times
+ * right for the ordinary entries.
+ *
+ * High local labels are used in macros to avoid clashes with local labels
+ * in functions.
+ *
+ * Ordinary `ret' is used instead of a macro `RET' because there are a lot
+ * of `ret's. 0xc3 is the opcode for `ret' (`#define ret ... ret' can't
+ * be used because this file is sometimes preprocessed in traditional mode).
+ * `ret' clobbers eflags but this doesn't matter.
+ */
+#define ALTENTRY(name) GEN_ENTRY(name) ; MCOUNT ; MEXITCOUNT ; jmp 9f
+#define CROSSJUMP(jtrue, label, jfalse) \
+ jfalse 8f; MEXITCOUNT; jmp __CONCAT(to,label); 8:
+#define CROSSJUMPTARGET(label) \
+ ALIGN_TEXT; __CONCAT(to,label): ; MCOUNT; jmp label
+#define ENTRY(name) GEN_ENTRY(name) ; 9: ; MCOUNT
+#define FAKE_MCOUNT(caller) pushq caller ; call __mcount ; popq %rcx
+#define MCOUNT call __mcount
+#define MCOUNT_LABEL(name) GEN_ENTRY(name) ; nop ; ALIGN_TEXT
+#ifdef GUPROF
+#define MEXITCOUNT call .mexitcount
+#define ret MEXITCOUNT ; NON_GPROF_RET
+#else
+#define MEXITCOUNT
+#endif
+
+#else /* !GPROF */
+/*
+ * ALTENTRY() has to align because it is before a corresponding ENTRY().
+ * ENTRY() has to align to because there may be no ALTENTRY() before it.
+ * If there is a previous ALTENTRY() then the alignment code for ENTRY()
+ * is empty.
+ */
+#define ALTENTRY(name) GEN_ENTRY(name)
+#define CROSSJUMP(jtrue, label, jfalse) jtrue label
+#define CROSSJUMPTARGET(label)
+#define ENTRY(name) GEN_ENTRY(name)
+#define FAKE_MCOUNT(caller)
+#define MCOUNT
+#define MCOUNT_LABEL(name)
+#define MEXITCOUNT
+#endif /* GPROF */
+
+/*
+ * Convenience for adding frame pointers to hand-coded ASM. Useful for
+ * DTrace, HWPMC, and KDB.
+ */
+#define PUSH_FRAME_POINTER \
+ pushq %rbp ; \
+ movq %rsp, %rbp ;
+#define POP_FRAME_POINTER \
+ popq %rbp
+
+#ifdef LOCORE
+/*
+ * Convenience macro for declaring interrupt entry points.
+ */
+#define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \
+ .type __CONCAT(X,name),@function; __CONCAT(X,name):
+
+/*
+ * Macros to create and destroy a trap frame.
+ */
+#define PUSH_FRAME \
+ subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \
+ testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
+ jz 1f ; /* Yes, dont swapgs again */ \
+ swapgs ; \
+1: movq %rdi,TF_RDI(%rsp) ; \
+ movq %rsi,TF_RSI(%rsp) ; \
+ movq %rdx,TF_RDX(%rsp) ; \
+ movq %rcx,TF_RCX(%rsp) ; \
+ movq %r8,TF_R8(%rsp) ; \
+ movq %r9,TF_R9(%rsp) ; \
+ movq %rax,TF_RAX(%rsp) ; \
+ movq %rbx,TF_RBX(%rsp) ; \
+ movq %rbp,TF_RBP(%rsp) ; \
+ movq %r10,TF_R10(%rsp) ; \
+ movq %r11,TF_R11(%rsp) ; \
+ movq %r12,TF_R12(%rsp) ; \
+ movq %r13,TF_R13(%rsp) ; \
+ movq %r14,TF_R14(%rsp) ; \
+ movq %r15,TF_R15(%rsp) ; \
+ movw %fs,TF_FS(%rsp) ; \
+ movw %gs,TF_GS(%rsp) ; \
+ movw %es,TF_ES(%rsp) ; \
+ movw %ds,TF_DS(%rsp) ; \
+ movl $TF_HASSEGS,TF_FLAGS(%rsp) ; \
+ cld
+
+#define POP_FRAME \
+ movq TF_RDI(%rsp),%rdi ; \
+ movq TF_RSI(%rsp),%rsi ; \
+ movq TF_RDX(%rsp),%rdx ; \
+ movq TF_RCX(%rsp),%rcx ; \
+ movq TF_R8(%rsp),%r8 ; \
+ movq TF_R9(%rsp),%r9 ; \
+ movq TF_RAX(%rsp),%rax ; \
+ movq TF_RBX(%rsp),%rbx ; \
+ movq TF_RBP(%rsp),%rbp ; \
+ movq TF_R10(%rsp),%r10 ; \
+ movq TF_R11(%rsp),%r11 ; \
+ movq TF_R12(%rsp),%r12 ; \
+ movq TF_R13(%rsp),%r13 ; \
+ movq TF_R14(%rsp),%r14 ; \
+ movq TF_R15(%rsp),%r15 ; \
+ testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
+ jz 1f ; /* keep kernel GS.base */ \
+ cli ; \
+ swapgs ; \
+1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
+
+/*
+ * Access per-CPU data.
+ */
+#define PCPU(member) %gs:PC_ ## member
+#define PCPU_ADDR(member, reg) \
+ movq %gs:PC_PRVSPACE, reg ; \
+ addq $PC_ ## member, reg
+
+#endif /* LOCORE */
+
+#ifdef __STDC__
+#define ELFNOTE(name, type, desctype, descdata...) \
+.pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
+ .long 4f - 3f /* descsz */ ; \
+ .long type ; \
+1:.asciz #name ; \
+2:.align 4 ; \
+3:desctype descdata ; \
+4:.align 4 ; \
+.popsection
+#else /* !__STDC__, i.e. -traditional */
+#define ELFNOTE(name, type, desctype, descdata) \
+.pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
+ .long 4f - 3f /* descsz */ ; \
+ .long type ; \
+1:.asciz "name" ; \
+2:.align 4 ; \
+3:desctype descdata ; \
+4:.align 4 ; \
+.popsection
+#endif /* __STDC__ */
+
+#endif /* !_MACHINE_ASMACROS_H_ */
diff --git a/usr/src/boot/sys/amd64/include/cpufunc.h b/usr/src/boot/sys/amd64/include/cpufunc.h
new file mode 100644
index 0000000000..f2348739d6
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/cpufunc.h
@@ -0,0 +1,871 @@
+/*-
+ * Copyright (c) 2003 Peter Wemm.
+ * Copyright (c) 1993 The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Functions to provide access to special i386 instructions.
+ * This in included in sys/systm.h, and that file should be
+ * used in preference to this.
+ */
+
+#ifndef _MACHINE_CPUFUNC_H_
+#define _MACHINE_CPUFUNC_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+struct region_descriptor;
+
+#define readb(va) (*(volatile uint8_t *) (va))
+#define readw(va) (*(volatile uint16_t *) (va))
+#define readl(va) (*(volatile uint32_t *) (va))
+#define readq(va) (*(volatile uint64_t *) (va))
+
+#define writeb(va, d) (*(volatile uint8_t *) (va) = (d))
+#define writew(va, d) (*(volatile uint16_t *) (va) = (d))
+#define writel(va, d) (*(volatile uint32_t *) (va) = (d))
+#define writeq(va, d) (*(volatile uint64_t *) (va) = (d))
+
+#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
+
+static __inline void
+breakpoint(void)
+{
+ __asm __volatile("int $3");
+}
+
+static __inline u_int
+bsfl(u_int mask)
+{
+ u_int result;
+
+ __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
+static __inline u_long
+bsfq(u_long mask)
+{
+ u_long result;
+
+ __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
+static __inline u_int
+bsrl(u_int mask)
+{
+ u_int result;
+
+ __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
+static __inline u_long
+bsrq(u_long mask)
+{
+ u_long result;
+
+ __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
+static __inline void
+clflush(u_long addr)
+{
+
+ __asm __volatile("clflush %0" : : "m" (*(char *)addr));
+}
+
+static __inline void
+clflushopt(u_long addr)
+{
+
+ __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr));
+}
+
+static __inline void
+clts(void)
+{
+
+ __asm __volatile("clts");
+}
+
+static __inline void
+disable_intr(void)
+{
+ __asm __volatile("cli" : : : "memory");
+}
+
+static __inline void
+do_cpuid(u_int ax, u_int *p)
+{
+ __asm __volatile("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax));
+}
+
+static __inline void
+cpuid_count(u_int ax, u_int cx, u_int *p)
+{
+ __asm __volatile("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx));
+}
+
+static __inline void
+enable_intr(void)
+{
+ __asm __volatile("sti");
+}
+
+#ifdef _KERNEL
+
+#define HAVE_INLINE_FFS
+#define ffs(x) __builtin_ffs(x)
+
+#define HAVE_INLINE_FFSL
+
+static __inline int
+ffsl(long mask)
+{
+ return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1);
+}
+
+#define HAVE_INLINE_FFSLL
+
+static __inline int
+ffsll(long long mask)
+{
+ return (ffsl((long)mask));
+}
+
+#define HAVE_INLINE_FLS
+
+static __inline int
+fls(int mask)
+{
+ return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
+}
+
+#define HAVE_INLINE_FLSL
+
+static __inline int
+flsl(long mask)
+{
+ return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1);
+}
+
+#define HAVE_INLINE_FLSLL
+
+static __inline int
+flsll(long long mask)
+{
+ return (flsl((long)mask));
+}
+
+#endif /* _KERNEL */
+
+static __inline void
+halt(void)
+{
+ __asm __volatile("hlt");
+}
+
+static __inline u_char
+inb(u_int port)
+{
+ u_char data;
+
+ __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline u_int
+inl(u_int port)
+{
+ u_int data;
+
+ __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline void
+insb(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insb"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+insw(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insw"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+insl(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insl"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+invd(void)
+{
+ __asm __volatile("invd");
+}
+
+static __inline u_short
+inw(u_int port)
+{
+ u_short data;
+
+ __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline void
+outb(u_int port, u_char data)
+{
+ __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline void
+outl(u_int port, u_int data)
+{
+ __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline void
+outsb(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsb"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outsw(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsw"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outsl(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsl"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outw(u_int port, u_short data)
+{
+ __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline u_long
+popcntq(u_long mask)
+{
+ u_long result;
+
+ __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
+static __inline void
+lfence(void)
+{
+
+ __asm __volatile("lfence" : : : "memory");
+}
+
+static __inline void
+mfence(void)
+{
+
+ __asm __volatile("mfence" : : : "memory");
+}
+
+static __inline void
+ia32_pause(void)
+{
+ __asm __volatile("pause");
+}
+
+static __inline u_long
+read_rflags(void)
+{
+ u_long rf;
+
+ __asm __volatile("pushfq; popq %0" : "=r" (rf));
+ return (rf);
+}
+
+static __inline uint64_t
+rdmsr(u_int msr)
+{
+ uint32_t low, high;
+
+ __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
+ return (low | ((uint64_t)high << 32));
+}
+
+static __inline uint32_t
+rdmsr32(u_int msr)
+{
+ uint32_t low;
+
+ __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx");
+ return (low);
+}
+
+static __inline uint64_t
+rdpmc(u_int pmc)
+{
+ uint32_t low, high;
+
+ __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc));
+ return (low | ((uint64_t)high << 32));
+}
+
+static __inline uint64_t
+rdtsc(void)
+{
+ uint32_t low, high;
+
+ __asm __volatile("rdtsc" : "=a" (low), "=d" (high));
+ return (low | ((uint64_t)high << 32));
+}
+
+static __inline uint32_t
+rdtsc32(void)
+{
+ uint32_t rv;
+
+ __asm __volatile("rdtsc" : "=a" (rv) : : "edx");
+ return (rv);
+}
+
+static __inline void
+wbinvd(void)
+{
+ __asm __volatile("wbinvd");
+}
+
+static __inline void
+write_rflags(u_long rf)
+{
+ __asm __volatile("pushq %0; popfq" : : "r" (rf));
+}
+
+static __inline void
+wrmsr(u_int msr, uint64_t newval)
+{
+ uint32_t low, high;
+
+ low = newval;
+ high = newval >> 32;
+ __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr));
+}
+
+static __inline void
+load_cr0(u_long data)
+{
+
+ __asm __volatile("movq %0,%%cr0" : : "r" (data));
+}
+
+static __inline u_long
+rcr0(void)
+{
+ u_long data;
+
+ __asm __volatile("movq %%cr0,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline u_long
+rcr2(void)
+{
+ u_long data;
+
+ __asm __volatile("movq %%cr2,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_cr3(u_long data)
+{
+
+ __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory");
+}
+
+static __inline u_long
+rcr3(void)
+{
+ u_long data;
+
+ __asm __volatile("movq %%cr3,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_cr4(u_long data)
+{
+ __asm __volatile("movq %0,%%cr4" : : "r" (data));
+}
+
+static __inline u_long
+rcr4(void)
+{
+ u_long data;
+
+ __asm __volatile("movq %%cr4,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline u_long
+rxcr(u_int reg)
+{
+ u_int low, high;
+
+ __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
+ return (low | ((uint64_t)high << 32));
+}
+
+static __inline void
+load_xcr(u_int reg, u_long val)
+{
+ u_int low, high;
+
+ low = val;
+ high = val >> 32;
+ __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
+}
+
+/*
+ * Global TLB flush (except for thise for pages marked PG_G)
+ */
+static __inline void
+invltlb(void)
+{
+
+ load_cr3(rcr3());
+}
+
+#ifndef CR4_PGE
+#define CR4_PGE 0x00000080 /* Page global enable */
+#endif
+
+/*
+ * Perform the guaranteed invalidation of all TLB entries. This
+ * includes the global entries, and entries in all PCIDs, not only the
+ * current context. The function works both on non-PCID CPUs and CPUs
+ * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1
+ * Operations that Invalidate TLBs and Paging-Structure Caches.
+ */
+static __inline void
+invltlb_glob(void)
+{
+ uint64_t cr4;
+
+ cr4 = rcr4();
+ load_cr4(cr4 & ~CR4_PGE);
+ /*
+ * Although preemption at this point could be detrimental to
+ * performance, it would not lead to an error. PG_G is simply
+ * ignored if CR4.PGE is clear. Moreover, in case this block
+ * is re-entered, the load_cr4() either above or below will
+ * modify CR4.PGE flushing the TLB.
+ */
+ load_cr4(cr4 | CR4_PGE);
+}
+
+/*
+ * TLB flush for an individual page (even if it has PG_G).
+ * Only works on 486+ CPUs (i386 does not have PG_G).
+ */
+static __inline void
+invlpg(u_long addr)
+{
+
+ __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
+}
+
+#define INVPCID_ADDR 0
+#define INVPCID_CTX 1
+#define INVPCID_CTXGLOB 2
+#define INVPCID_ALLCTX 3
+
+struct invpcid_descr {
+ uint64_t pcid:12 __packed;
+ uint64_t pad:52 __packed;
+ uint64_t addr;
+} __packed;
+
+static __inline void
+invpcid(struct invpcid_descr *d, int type)
+{
+
+ __asm __volatile("invpcid (%0),%1"
+ : : "r" (d), "r" ((u_long)type) : "memory");
+}
+
+static __inline u_short
+rfs(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%fs,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline u_short
+rgs(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%gs,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline u_short
+rss(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%ss,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline void
+load_ds(u_short sel)
+{
+ __asm __volatile("movw %0,%%ds" : : "rm" (sel));
+}
+
+static __inline void
+load_es(u_short sel)
+{
+ __asm __volatile("movw %0,%%es" : : "rm" (sel));
+}
+
+static __inline void
+cpu_monitor(const void *addr, u_long extensions, u_int hints)
+{
+
+ __asm __volatile("monitor"
+ : : "a" (addr), "c" (extensions), "d" (hints));
+}
+
+static __inline void
+cpu_mwait(u_long extensions, u_int hints)
+{
+
+ __asm __volatile("mwait" : : "a" (hints), "c" (extensions));
+}
+
+#ifdef _KERNEL
+/* This is defined in <machine/specialreg.h> but is too painful to get to */
+#ifndef MSR_FSBASE
+#define MSR_FSBASE 0xc0000100
+#endif
+static __inline void
+load_fs(u_short sel)
+{
+ /* Preserve the fsbase value across the selector load */
+ __asm __volatile("rdmsr; movw %0,%%fs; wrmsr"
+ : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx");
+}
+
+#ifndef MSR_GSBASE
+#define MSR_GSBASE 0xc0000101
+#endif
+static __inline void
+load_gs(u_short sel)
+{
+ /*
+ * Preserve the gsbase value across the selector load.
+ * Note that we have to disable interrupts because the gsbase
+ * being trashed happens to be the kernel gsbase at the time.
+ */
+ __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq"
+ : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx");
+}
+#else
+/* Usable by userland */
+static __inline void
+load_fs(u_short sel)
+{
+ __asm __volatile("movw %0,%%fs" : : "rm" (sel));
+}
+
+static __inline void
+load_gs(u_short sel)
+{
+ __asm __volatile("movw %0,%%gs" : : "rm" (sel));
+}
+#endif
+
+static __inline void
+lidt(struct region_descriptor *addr)
+{
+ __asm __volatile("lidt (%0)" : : "r" (addr));
+}
+
+static __inline void
+lldt(u_short sel)
+{
+ __asm __volatile("lldt %0" : : "r" (sel));
+}
+
+static __inline void
+ltr(u_short sel)
+{
+ __asm __volatile("ltr %0" : : "r" (sel));
+}
+
+static __inline uint64_t
+rdr0(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr0,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr0(uint64_t dr0)
+{
+ __asm __volatile("movq %0,%%dr0" : : "r" (dr0));
+}
+
+static __inline uint64_t
+rdr1(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr1,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr1(uint64_t dr1)
+{
+ __asm __volatile("movq %0,%%dr1" : : "r" (dr1));
+}
+
+static __inline uint64_t
+rdr2(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr2,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr2(uint64_t dr2)
+{
+ __asm __volatile("movq %0,%%dr2" : : "r" (dr2));
+}
+
+static __inline uint64_t
+rdr3(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr3,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr3(uint64_t dr3)
+{
+ __asm __volatile("movq %0,%%dr3" : : "r" (dr3));
+}
+
+static __inline uint64_t
+rdr4(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr4,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr4(uint64_t dr4)
+{
+ __asm __volatile("movq %0,%%dr4" : : "r" (dr4));
+}
+
+static __inline uint64_t
+rdr5(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr5,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr5(uint64_t dr5)
+{
+ __asm __volatile("movq %0,%%dr5" : : "r" (dr5));
+}
+
+static __inline uint64_t
+rdr6(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr6,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr6(uint64_t dr6)
+{
+ __asm __volatile("movq %0,%%dr6" : : "r" (dr6));
+}
+
+static __inline uint64_t
+rdr7(void)
+{
+ uint64_t data;
+ __asm __volatile("movq %%dr7,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr7(uint64_t dr7)
+{
+ __asm __volatile("movq %0,%%dr7" : : "r" (dr7));
+}
+
+static __inline register_t
+intr_disable(void)
+{
+ register_t rflags;
+
+ rflags = read_rflags();
+ disable_intr();
+ return (rflags);
+}
+
+static __inline void
+intr_restore(register_t rflags)
+{
+ write_rflags(rflags);
+}
+
+#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
+
+int breakpoint(void);
+u_int bsfl(u_int mask);
+u_int bsrl(u_int mask);
+void clflush(u_long addr);
+void clts(void);
+void cpuid_count(u_int ax, u_int cx, u_int *p);
+void disable_intr(void);
+void do_cpuid(u_int ax, u_int *p);
+void enable_intr(void);
+void halt(void);
+void ia32_pause(void);
+u_char inb(u_int port);
+u_int inl(u_int port);
+void insb(u_int port, void *addr, size_t count);
+void insl(u_int port, void *addr, size_t count);
+void insw(u_int port, void *addr, size_t count);
+register_t intr_disable(void);
+void intr_restore(register_t rf);
+void invd(void);
+void invlpg(u_int addr);
+void invltlb(void);
+u_short inw(u_int port);
+void lidt(struct region_descriptor *addr);
+void lldt(u_short sel);
+void load_cr0(u_long cr0);
+void load_cr3(u_long cr3);
+void load_cr4(u_long cr4);
+void load_dr0(uint64_t dr0);
+void load_dr1(uint64_t dr1);
+void load_dr2(uint64_t dr2);
+void load_dr3(uint64_t dr3);
+void load_dr4(uint64_t dr4);
+void load_dr5(uint64_t dr5);
+void load_dr6(uint64_t dr6);
+void load_dr7(uint64_t dr7);
+void load_fs(u_short sel);
+void load_gs(u_short sel);
+void ltr(u_short sel);
+void outb(u_int port, u_char data);
+void outl(u_int port, u_int data);
+void outsb(u_int port, const void *addr, size_t count);
+void outsl(u_int port, const void *addr, size_t count);
+void outsw(u_int port, const void *addr, size_t count);
+void outw(u_int port, u_short data);
+u_long rcr0(void);
+u_long rcr2(void);
+u_long rcr3(void);
+u_long rcr4(void);
+uint64_t rdmsr(u_int msr);
+uint32_t rdmsr32(u_int msr);
+uint64_t rdpmc(u_int pmc);
+uint64_t rdr0(void);
+uint64_t rdr1(void);
+uint64_t rdr2(void);
+uint64_t rdr3(void);
+uint64_t rdr4(void);
+uint64_t rdr5(void);
+uint64_t rdr6(void);
+uint64_t rdr7(void);
+uint64_t rdtsc(void);
+u_long read_rflags(void);
+u_int rfs(void);
+u_int rgs(void);
+void wbinvd(void);
+void write_rflags(u_int rf);
+void wrmsr(u_int msr, uint64_t newval);
+
+#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
+
+void reset_dbregs(void);
+
+#ifdef _KERNEL
+int rdmsr_safe(u_int msr, uint64_t *val);
+int wrmsr_safe(u_int msr, uint64_t newval);
+#endif
+
+#endif /* !_MACHINE_CPUFUNC_H_ */
diff --git a/usr/src/boot/sys/amd64/include/elf.h b/usr/src/boot/sys/amd64/include/elf.h
new file mode 100644
index 0000000000..f9323775dc
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/elf.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/elf.h>
diff --git a/usr/src/boot/sys/amd64/include/endian.h b/usr/src/boot/sys/amd64/include/endian.h
new file mode 100644
index 0000000000..2ad27a9069
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/endian.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/endian.h>
diff --git a/usr/src/boot/sys/amd64/include/exec.h b/usr/src/boot/sys/amd64/include/exec.h
new file mode 100644
index 0000000000..8d07887be2
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/exec.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)exec.h 8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_EXEC_H_
+#define _MACHINE_EXEC_H_
+
+#define __LDPGSZ 4096
+
+#endif /* !_MACHINE_EXEC_H_ */
diff --git a/usr/src/boot/sys/amd64/include/metadata.h b/usr/src/boot/sys/amd64/include/metadata.h
new file mode 100644
index 0000000000..98d0272fd4
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/metadata.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/metadata.h>
diff --git a/usr/src/boot/sys/amd64/include/param.h b/usr/src/boot/sys/amd64/include/param.h
new file mode 100644
index 0000000000..5892ae954e
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/param.h
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2002 David E. O'Brien. All rights reserved.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Ralph Campbell.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)param.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+
+#ifndef _AMD64_INCLUDE_PARAM_H_
+#define _AMD64_INCLUDE_PARAM_H_
+
+#include <machine/_align.h>
+
+/*
+ * Machine dependent constants for AMD64.
+ */
+
+
+#define __HAVE_ACPI
+#define __PCI_REROUTE_INTERRUPT
+
+#ifndef MACHINE
+#define MACHINE "amd64"
+#endif
+#ifndef MACHINE_ARCH
+#define MACHINE_ARCH "amd64"
+#endif
+#ifndef MACHINE_ARCH32
+#define MACHINE_ARCH32 "i386"
+#endif
+
+#if defined(SMP) || defined(KLD_MODULE)
+#ifndef MAXCPU
+#define MAXCPU 256
+#endif
+#else
+#define MAXCPU 1
+#endif
+
+#ifndef MAXMEMDOM
+#define MAXMEMDOM 1
+#endif
+
+#define ALIGNBYTES _ALIGNBYTES
+#define ALIGN(p) _ALIGN(p)
+/*
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits).
+ */
+#define ALIGNED_POINTER(p, t) 1
+
+/*
+ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an
+ * architecture. It should be used with appropriate caution.
+ */
+#define CACHE_LINE_SHIFT 7
+#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
+
+/* Size of the level 1 page table units */
+#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
+#define NPTEPGSHIFT 9 /* LOG2(NPTEPG) */
+#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */
+#define PAGE_SIZE (1<<PAGE_SHIFT) /* bytes/page */
+#define PAGE_MASK (PAGE_SIZE-1)
+/* Size of the level 2 page directory units */
+#define NPDEPG (PAGE_SIZE/(sizeof (pd_entry_t)))
+#define NPDEPGSHIFT 9 /* LOG2(NPDEPG) */
+#define PDRSHIFT 21 /* LOG2(NBPDR) */
+#define NBPDR (1<<PDRSHIFT) /* bytes/page dir */
+#define PDRMASK (NBPDR-1)
+/* Size of the level 3 page directory pointer table units */
+#define NPDPEPG (PAGE_SIZE/(sizeof (pdp_entry_t)))
+#define NPDPEPGSHIFT 9 /* LOG2(NPDPEPG) */
+#define PDPSHIFT 30 /* LOG2(NBPDP) */
+#define NBPDP (1<<PDPSHIFT) /* bytes/page dir ptr table */
+#define PDPMASK (NBPDP-1)
+/* Size of the level 4 page-map level-4 table units */
+#define NPML4EPG (PAGE_SIZE/(sizeof (pml4_entry_t)))
+#define NPML4EPGSHIFT 9 /* LOG2(NPML4EPG) */
+#define PML4SHIFT 39 /* LOG2(NBPML4) */
+#define NBPML4 (1UL<<PML4SHIFT)/* bytes/page map lev4 table */
+#define PML4MASK (NBPML4-1)
+
+#define MAXPAGESIZES 3 /* maximum number of supported page sizes */
+
+#define IOPAGES 2 /* pages of i/o permission bitmap */
+/*
+ * I/O permission bitmap has a bit for each I/O port plus an additional
+ * byte at the end with all bits set. See section "I/O Permission Bit Map"
+ * in the Intel SDM for more details.
+ */
+#define IOPERM_BITMAP_SIZE (IOPAGES * PAGE_SIZE + 1)
+
+#ifndef KSTACK_PAGES
+#define KSTACK_PAGES 4 /* pages of kstack (with pcb) */
+#endif
+#define KSTACK_GUARD_PAGES 1 /* pages of kstack guard; 0 disables */
+
+/*
+ * Mach derived conversion macros
+ */
+#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
+#define trunc_page(x) ((unsigned long)(x) & ~(PAGE_MASK))
+#define trunc_2mpage(x) ((unsigned long)(x) & ~PDRMASK)
+#define round_2mpage(x) ((((unsigned long)(x)) + PDRMASK) & ~PDRMASK)
+#define trunc_1gpage(x) ((unsigned long)(x) & ~PDPMASK)
+
+#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#define amd64_btop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define amd64_ptob(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#define pgtok(x) ((unsigned long)(x) * (PAGE_SIZE / 1024))
+
+#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \
+ || ((va) >= VM_MIN_KERNEL_ADDRESS && (va) < VM_MAX_KERNEL_ADDRESS))
+
+#endif /* !_AMD64_INCLUDE_PARAM_H_ */
diff --git a/usr/src/boot/sys/amd64/include/pc/bios.h b/usr/src/boot/sys/amd64/include/pc/bios.h
new file mode 100644
index 0000000000..1dbf110219
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/pc/bios.h
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 1997 Michael Smith
+ * Copyright (c) 1998 Jonathan Lemon
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_PC_BIOS_H_
+#define _MACHINE_PC_BIOS_H_
+
+/*
+ * Int 15:E820 'SMAP' structure
+ */
+#define SMAP_SIG 0x534D4150 /* 'SMAP' */
+
+#define SMAP_TYPE_MEMORY 1
+#define SMAP_TYPE_RESERVED 2
+#define SMAP_TYPE_ACPI_RECLAIM 3
+#define SMAP_TYPE_ACPI_NVS 4
+#define SMAP_TYPE_ACPI_ERROR 5
+
+#define SMAP_XATTR_ENABLED 0x00000001
+#define SMAP_XATTR_NON_VOLATILE 0x00000002
+#define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE)
+
+struct bios_smap {
+ u_int64_t base;
+ u_int64_t length;
+ u_int32_t type;
+} __packed;
+
+/* Structure extended to include extended attribute field in ACPI 3.0. */
+struct bios_smap_xattr {
+ u_int64_t base;
+ u_int64_t length;
+ u_int32_t type;
+ u_int32_t xattr;
+} __packed;
+
+/*
+ * System Management BIOS
+ */
+#define SMBIOS_START 0xf0000
+#define SMBIOS_STEP 0x10
+#define SMBIOS_OFF 0
+#define SMBIOS_LEN 4
+#define SMBIOS_SIG "_SM_"
+
+struct smbios_eps {
+ uint8_t anchor_string[4]; /* '_SM_' */
+ uint8_t checksum;
+ uint8_t length;
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint16_t maximum_structure_size;
+ uint8_t entry_point_revision;
+ uint8_t formatted_area[5];
+ uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
+ uint8_t intermediate_checksum;
+ uint16_t structure_table_length;
+ uint32_t structure_table_address;
+ uint16_t number_structures;
+ uint8_t BCD_revision;
+};
+
+struct smbios_structure_header {
+ uint8_t type;
+ uint8_t length;
+ uint16_t handle;
+};
+
+#ifdef _KERNEL
+#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
+#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
+
+struct bios_oem_signature {
+ char * anchor; /* search anchor string in BIOS memory */
+ size_t offset; /* offset from anchor (may be negative) */
+ size_t totlen; /* total length of BIOS string to copy */
+} __packed;
+
+struct bios_oem_range {
+ u_int from; /* shouldn't be below 0xe0000 */
+ u_int to; /* shouldn't be above 0xfffff */
+} __packed;
+
+struct bios_oem {
+ struct bios_oem_range range;
+ struct bios_oem_signature signature[];
+} __packed;
+
+int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
+uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
+ int sigofs);
+void bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize,
+ vm_paddr_t *physmap, int *physmap_idx);
+#endif
+
+#endif /* _MACHINE_PC_BIOS_H_ */
diff --git a/usr/src/boot/sys/amd64/include/psl.h b/usr/src/boot/sys/amd64/include/psl.h
new file mode 100644
index 0000000000..4d945a1ebb
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/psl.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/psl.h>
diff --git a/usr/src/boot/sys/amd64/include/setjmp.h b/usr/src/boot/sys/amd64/include/setjmp.h
new file mode 100644
index 0000000000..c4101a77fd
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/setjmp.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/setjmp.h>
diff --git a/usr/src/boot/sys/amd64/include/signal.h b/usr/src/boot/sys/amd64/include/signal.h
new file mode 100644
index 0000000000..db9fe6ad59
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/signal.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/signal.h>
diff --git a/usr/src/boot/sys/amd64/include/specialreg.h b/usr/src/boot/sys/amd64/include/specialreg.h
new file mode 100644
index 0000000000..aace4bfd62
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/specialreg.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/specialreg.h>
diff --git a/usr/src/boot/sys/amd64/include/stdarg.h b/usr/src/boot/sys/amd64/include/stdarg.h
new file mode 100644
index 0000000000..1f80090356
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/stdarg.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/stdarg.h>
diff --git a/usr/src/boot/sys/amd64/include/trap.h b/usr/src/boot/sys/amd64/include/trap.h
new file mode 100644
index 0000000000..4d950771dc
--- /dev/null
+++ b/usr/src/boot/sys/amd64/include/trap.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/trap.h>
diff --git a/usr/src/boot/sys/boot/Makefile b/usr/src/boot/sys/boot/Makefile
new file mode 100644
index 0000000000..a8c96ca60a
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile
@@ -0,0 +1,35 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+.KEEP_STATE:
+
+include $(SRC)/Makefile.master
+
+INSTDIRS = i386 # efi
+SUBDIRS = libstand ficl zfs $(INSTDIRS)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+
+all clean clobber: $(SUBDIRS)
+
+install: all $(INSTDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/boot/sys/boot/Makefile.amd64 b/usr/src/boot/sys/boot/Makefile.amd64
new file mode 100644
index 0000000000..384cf7a632
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.amd64
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+SUBDIR+= efi
+SUBDIR+= libstand32
+SUBDIR+= zfs
+SUBDIR+= userboot
+
+.if ${MK_FORTH} != "no"
+SUBDIR+= ficl32
+.endif
+
+SUBDIR+= i386
diff --git a/usr/src/boot/sys/boot/Makefile.arm b/usr/src/boot/sys/boot/Makefile.arm
new file mode 100644
index 0000000000..bb0e01cb5f
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.arm
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.if ${MK_FDT} != "no"
+SUBDIR+= fdt
+.endif
+
+SUBDIR+= efi uboot
diff --git a/usr/src/boot/sys/boot/Makefile.arm64 b/usr/src/boot/sys/boot/Makefile.arm64
new file mode 100644
index 0000000000..116e903020
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.arm64
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.if ${MK_FDT} != "no"
+SUBDIR+= fdt
+.endif
+
+SUBDIR+= efi
diff --git a/usr/src/boot/sys/boot/Makefile.i386 b/usr/src/boot/sys/boot/Makefile.i386
new file mode 100644
index 0000000000..e7de353a56
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.i386
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR+= efi
+SUBDIR+= libstand32
+SUBDIR+= zfs
diff --git a/usr/src/boot/sys/boot/Makefile.inc b/usr/src/boot/sys/boot/Makefile.inc
new file mode 100644
index 0000000000..17088d782d
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.inc
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+SSP_CFLAGS=
+
+.if ${MACHINE_CPUARCH} == "arm"
+# Do not generate movt/movw, because the relocation fixup for them does not
+# translate to the -Bsymbolic -pie format required by self_reloc() in loader(8).
+# Also, the fpu is not available in a standalone environment.
+CFLAGS.clang+= -mllvm -arm-use-movt=0
+CFLAGS.clang+= -mfpu=none
+.endif
diff --git a/usr/src/boot/sys/boot/Makefile.sparc64 b/usr/src/boot/sys/boot/Makefile.sparc64
new file mode 100644
index 0000000000..1064a267db
--- /dev/null
+++ b/usr/src/boot/sys/boot/Makefile.sparc64
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+SUBDIR+= ofw
+SUBDIR+= zfs
diff --git a/usr/src/boot/sys/boot/README b/usr/src/boot/sys/boot/README
new file mode 100644
index 0000000000..22faea26b8
--- /dev/null
+++ b/usr/src/boot/sys/boot/README
@@ -0,0 +1,238 @@
+$FreeBSD$
+
+ README file, for the boot config file setup. This is meant
+ to explain how to manage the loader configuration process.
+ The boot and loading process is either defined, or being
+ defined in boot(8) and loader(8).
+
+ The ongoing development of the FreeBSD bootloader, and its
+ rapid deployment while still in the development phase, has
+ resulted in a large number of installations with outdated
+ configurations. Those installations actively tracking the
+ FreeBSD development should also ensure that their bootloader
+ configurations are updated. If you see files discussed here
+ that your system doesn't yet have, add them yourself.
+
+ This is an effort to give the currently correct method for
+ setting up your boot process. It includes information on
+ setting up screen savers and plug and play information, and
+ also on recording any changes you make in your kernel
+ configuration. This file is temporary, because as I noted,
+ the process is still undergoing development, and will still
+ change. Man pages are coming out, but they're still going
+ to be somewhat fragile for a while. If you note anything in
+ here that's broken, it would be a good idea to report it to
+ the FreeBSD-current list, or to Daniel C. Sobral
+ <dcs@FreeBSD.org> or Mike Smith <msmith@FreeBSD.org>.
+
+ After the first two stages in the booting process (described
+ in boot(8)), the last stage of the booting process, called
+ the loader (see loader(8)) reads in the /boot/loader.rc
+ file. The two lines you should have there are:
+
+ include /boot/loader.4th
+ start
+
+ This reads the ficl (forth) initialization files, then
+ /boot/default/loader.conf. This file, which strongly
+ resembles in form /etc/rc.conf but functions quite
+ differently, has spots for endless user customization but
+ isn't yet completely finished. For one thing, it used to
+ assume a /kernel.config instead of a /boot/kernel.conf.
+ Watch the first few lines of /boot/defaults/loader.conf to
+ see if the file name changes.
+
+ [See the section at the end on loader.conf syntax]
+
+ You don't actually want to make any changes to
+ /boot/defaults/loader.conf, the file that is a hacking-
+ target is:
+
+ /boot/loader.conf
+
+ and might very likely not exist yet on your system). You
+ should copy /boot/defaults/loader.conf to /boot/loader.conf,
+ and then cut out anything you didn't want changed.
+
+ The start command also loads your kernel for you, so don't
+ put any lines in there like "load kernel", they'll fail (but
+ really have already worked for you). Start also reads in
+ the file /boot/defaults/loader.conf and /boot/loader.conf.
+ If you don't have /boot/loader.conf, you'll see a message on
+ boot about it, but it's a warning only, no other effects.
+ See the section on loader.conf syntax at the end of this
+ document, for some more pointers on loader.conf syntax.
+
+ The best way to manage splash screens is with entries in
+ /boot/loader.conf, and this is very clearly illustrated in
+ /boot/defaults/loader.conf (which you could just copy over
+ to /boot/loader.conf). I'm going to illustrate here how you
+ *could* do it in /boot/loader.rc (for information only)
+ but I don't recommend you do this; use the
+ /boot/defaults/loader.conf syntax, it's easier to get it
+ correct.
+
+ You can load your splash screen by putting the following
+ lines into /boot/loader.rc:
+
+ load splash_bmp
+ load -t splash_image_data /path/to/file.bmp
+
+ The top line causes the splash_bmp module to get loaded.
+ The second line has the parameter "-t" which tells the
+ loader that the class of DATA being loaded is not a module,
+ but instead a splash_image_data located in file
+ /path/to/file.bmp.
+
+ To get your plug and play data correctly set, run kget,
+ redirecting the output to /boot/kernel.conf. Note that kget
+ right now adds an extra "q" to it's output (from the q for
+ quit you press when you exit config), and if you want, you
+ can remove that from the file. Kget reports data only, so
+ feel free to run it, just to see the output. Make certain
+ you have the kernel option USERCONFIG set in your kernel, so
+ that you can do a boot -c, to initially set your cards up.
+ Then, edit /boot/loader.conf so that the following line
+ shows up (overwriting, in effect, a similar line in
+ /boot/default/loader.conf):
+
+ userconfig_script_load="YES"
+
+ My own pnp line looks like:
+ pnp 1 0 os irq0 15 irq1 0 drq0 1 drq1 0 port0 1332
+ (kget changes numbers from hexadecimal to decimal). Note
+ that, at this moment, the change from using /kernel.config
+ to using /boot/kernel.conf as the storage place for kernel
+ config changes is going on. Take a look at your
+ /boot/defaults/loader.conf, see what's defined as
+ userconfig_script_name, and if you override, make sure the
+ file exists. Note that the loader only has access to the
+ root filesystem, so be careful where you tell it to read
+ from.
+
+
+ o If you interrupt autoboot, you'll engage interactive
+ mode with loader. Everything you type will have the
+ same effects as if it were lines in /boot/loader.rc.
+
+ o While in interactive mode, you can get help by typing
+ "?", "help [<topic> [<subtopic>]]" and "help index".
+ These are mostly commands one would expect a normal
+ user to use. I recommend you play with them a little,
+ to gain further familiarity with what's going on.
+
+ Note that it is not possible to damage or corrupt your
+ system while experimenting with the loader, as it
+ cannot write to any of your filesystems.
+
+ o The command "unload" will unload everything. This is
+ very useful. Once loader.rc has finished and the
+ system is in the autoboot count-down, you will usually
+ have the kernel and other modules loaded. Now, suppose
+ your new /kernel is broken, how do you load
+ /kernel.old? By typing:
+
+ unload
+ load kernel.old
+ [any other modules you wish to load]
+ boot
+
+ o If you use loader.conf, you can do:
+
+ unload
+ set kernel=kernel.old
+ boot-conf
+
+ this will then load all the modules you have
+ configured, using kernel.old as kernel, and boot.
+
+ o From loader, you can use the command "more" to read the
+ contents of /boot/loader.rc, if you wish. This is not
+ FreeBSD's more. It is one of loader's builtin commands.
+ Useful if you can't quite recall what you have there.
+ :-) Of course, you can use this command to read
+ anything else you want.
+
+ o "boot -flag" works, "boot kernelname" works, "boot
+ -flag kernelname" doesn't. "boot kernelname -flag"
+ might work, but I'm not sure. The problem is that these
+ flags are kernel's flags, not boot's flags.
+
+ o There are a number of variables that can be set. You
+ can see them in loader.conf, but you can get much more
+ detailed information using the "help" command, eg. help
+ set <variablename>.
+
+ o The variable root_disk_unit is particularly important,
+ as it solves a relatively common problem. This problem
+ shows when the BIOS assign disk units in a different
+ way than the kernel. For example, if you have two IDE
+ disks, one on the primary, the other on the secondary
+ controller, and both as master, the default in most
+ kernels is having the first as wd0, and the second as
+ wd2. If your root partition is in wd2, you'll get an
+ error, because the BIOS sees these disks as 0 and 1
+ (well, 1 and 2), and that's what loader tells the
+ kernel. In this case, "set root_disk_unit=2" solves the
+ problem. You use this whenever the kernel fails to
+ mount to root partition because it has a wrong unit
+ number.
+
+ FILE OVERVIEW
+
+
+ o /boot/defaults/loader.conf -- Master configuration
+ file, not to be edited. Overridden by
+ /boot/loader.conf.
+
+ o /boot/loader.conf -- local system customization file,
+ in form very much like /boot/defaults/loader.conf.
+ This file is meant to be used by local users and the
+ sysinstall process.
+
+ o /boot/loader.conf.local -- local installation override
+ file. This is intended for use by installations with
+ large numbers of systems, to allow global policy
+ overrides. No FreeBSD tools should ever write this
+ file.
+
+ o /kernel.config -- old location of kernel configuration
+ changes (like pnp changes).
+
+ o /boot/kernel.conf -- new location for kernel
+ configuration changes.
+
+ o /boot/loader.rc -- loader initial configuration file,
+ chiefly used to source in a forth file, and start the
+ configuration process.
+
+ NOTES ON LOADER.CONF SYNTAX
+
+ I'm copy here from the last 11 lines from
+ /boot/defaults/loader.conf:
+
+ ##############################################################
+ ### Module loading syntax example ##########################
+ ##############################################################
+
+ #module_load="YES" # loads module "module"
+ #module_name="realname" # uses "realname" instead of "module"
+ #module_type="type" # passes "-t type" to load
+ #module_flags="flags" # passes "flags" to the module
+ #module_before="cmd" # executes "cmd" before loading module
+ #module_after="cmd" # executes "cmd" after loading module
+ #module_error="cmd" # executes "cmd" if load fails
+
+ The way this works, the command processor used by the loader
+ (which is a subset of forth) inspects these variables for
+ their suffix, and the 7 lines above illustrate all the
+ currently defined suffixes, and their use. Take the part
+ before the underscore, and customize it i(make it unique)
+ for your particular use, keeping the suffix to allow the
+ particular function you want to activate. Extra underscores
+ are fine, because it's only the sufixes that are scanned
+ for.
+
+
+
+ (authors Chuck Robey and Daniel Sobral).
diff --git a/usr/src/boot/sys/boot/arm/Makefile b/usr/src/boot/sys/boot/arm/Makefile
new file mode 100644
index 0000000000..1d12d98316
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= uboot
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/arm/Makefile.inc b/usr/src/boot/sys/boot/arm/Makefile.inc
new file mode 100644
index 0000000000..265f86d1ed
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/arm/at91/Makefile b/usr/src/boot/sys/boot/arm/at91/Makefile
new file mode 100644
index 0000000000..266c0ad567
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= libat91 boot0 boot0iic boot0spi boot2 bootiic bootspi
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/arm/at91/Makefile.inc b/usr/src/boot/sys/boot/arm/at91/Makefile.inc
new file mode 100644
index 0000000000..3c6f5ca8b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/Makefile.inc
@@ -0,0 +1,57 @@
+# $FreeBSD$
+
+.if !target(__at91_boot_Makefile.inc__)
+.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm
+
+__at91_boot_Makefile.inc__:
+
+# tsc, bwct, kb920x, centipad are the supported flavors
+BOOT_FLAVOR?=kb920x
+
+CFLAGS=-Os -mcpu=arm9 -ffreestanding \
+ -I${.CURDIR}/../libat91 \
+ -I${.CURDIR}/../../../.. \
+ -I${.CURDIR}/../../../../arm \
+ -D_KERNEL \
+ -Wall -Waggregate-return \
+ -Wnested-externs \
+ -Wpointer-arith -Wshadow -Wwrite-strings \
+ -Werror \
+ -Wmissing-prototypes \
+ -Wmissing-declarations
+# -Wstrict-prototypes
+
+CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu}
+
+LIBAT91=${.OBJDIR}/../libat91/libat91.a
+
+LD ?= ld
+OBJCOPY ?= objcopy
+
+.if defined(P)
+${P}: ${P}.out
+ ${OBJCOPY} -S -O binary ${P}.out ${.TARGET}
+ @set -- `ls -l ${.TARGET}`; x=$$((12288-$$5)); \
+ echo "$$x bytes available"; test $$x -ge 0
+
+${P}.out: ${OBJS}
+ ${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LIBAT91}
+
+CLEANFILES+= ${P} ${P}.out
+.endif
+
+.if defined(WITH_TAG_LIST)
+MK_TAG_LIST:=yes
+.else
+MK_TAG_LIST:=no
+.endif
+
+.if defined(WITH_FPGA)
+MK_FPGA:=yes
+.else
+MK_FPGA:=no
+.endif
+
+.endif
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0/Makefile b/usr/src/boot/sys/boot/arm/at91/boot0/Makefile
new file mode 100644
index 0000000000..8c22cc9967
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libat91
+
+P=boot0
+FILES=${P}
+SRCS=arm_init.S main.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+CFLAGS+=-DBOOT_BOOT0
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0/README b/usr/src/boot/sys/boot/arm/at91/boot0/README
new file mode 100644
index 0000000000..1d617d6fd8
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0/README
@@ -0,0 +1,7 @@
+This is a bootstrap bootloader. It is intended to be used when the
+AT91RM9200 is running xmodem over DBGU. It will download the next stage
+of the booting process (or the recovery program) and jump to it. It loads
+the program at a 1MB offset into SDRAM. Programs are expected to be
+smaller than this and copy themselves to the right location.
+
+$FreeBSD$
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0/linker.cfg b/usr/src/boot/sys/boot/arm/at91/boot0/linker.cfg
new file mode 100644
index 0000000000..b231893969
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0/linker.cfg
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ *
+ * Filename: linker.cfg
+ *
+ * linker config file used for internal RAM or eeprom images at address 0.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin move data to SDRAM
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7t) *(.glue_7)
+ }
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .data :
+ {
+ __data_start = . ;
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0/main.c b/usr/src/boot/sys/boot/arm/at91/boot0/main.c
new file mode 100644
index 0000000000..36dfe82144
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0/main.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "lib.h"
+#include "at91rm9200_lowlevel.h"
+
+typedef void fn_t(void);
+
+int main(void);
+
+int
+main(void)
+{
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
+ fn_t *fn = (fn_t *)(SDRAM_BASE + (1 << 20)); /* Load to base + 1MB */
+
+ while (xmodem_rx(addr) == -1)
+ continue;
+ fn();
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0iic/Makefile b/usr/src/boot/sys/boot/arm/at91/boot0iic/Makefile
new file mode 100644
index 0000000000..af93ce2e48
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0iic/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libat91
+
+P=boot0iic
+FILES=${P}
+SRCS=arm_init.S main.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+CFLAGS+=-DBOOT_BOOT0
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0iic/main.c b/usr/src/boot/sys/boot/arm/at91/boot0iic/main.c
new file mode 100644
index 0000000000..2a81b937ae
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0iic/main.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "lib.h"
+#include "at91rm9200_lowlevel.h"
+
+int main(void);
+
+int
+main(void)
+{
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
+ int len, sec;
+
+ printf("\nSend data to be written into EEPROM\n");
+ while ((len = xmodem_rx(addr)) == -1)
+ continue;
+ sec = GetSeconds() + 1;
+ while (sec >= GetSeconds())
+ continue;
+ printf("\nWriting EEPROM from 0x%x to addr 0, 0x%x bytes\n", addr,
+ len);
+ InitEEPROM();
+ printf("init done\n");
+ WriteEEPROM(0, addr, len);
+ printf("\nWrote %d bytes. Press reset\n", len);
+ return (1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0spi/Makefile b/usr/src/boot/sys/boot/arm/at91/boot0spi/Makefile
new file mode 100644
index 0000000000..207d6204cd
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0spi/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libat91
+
+P=boot0spi
+FILES=${P}
+SRCS=arm_init.S main.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+CFLAGS+=-DBOOT_BOOT0
diff --git a/usr/src/boot/sys/boot/arm/at91/boot0spi/main.c b/usr/src/boot/sys/boot/arm/at91/boot0spi/main.c
new file mode 100644
index 0000000000..cac037b5b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot0spi/main.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "lib.h"
+#include "at91rm9200_lowlevel.h"
+#include "spi_flash.h"
+
+#define OFFSET 0
+
+int main(void);
+
+int
+main(void)
+{
+ int len, i, j, off, sec;
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* download at + 1MB */
+ char *addr2 = (char *)SDRAM_BASE + (2 << 20); /* readback to + 2MB */
+
+ SPI_InitFlash();
+ printf("Waiting for data\n");
+ while ((len = xmodem_rx(addr)) == -1)
+ continue;
+ printf("Writing %u bytes at %u\n", len, OFFSET);
+ for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
+ off = i + OFFSET;
+ for (j = 0; j < 10; j++) {
+ SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
+ SPI_ReadFlash(off, addr2 + i, FLASH_PAGE_SIZE);
+ if (p_memcmp(addr + i, addr2 + i, FLASH_PAGE_SIZE) == 0)
+ break;
+ }
+ if (j >= 10)
+ printf("Bad Readback at %u\n", i);
+ }
+ sec = GetSeconds() + 2;
+ while (sec <= GetSeconds())
+ continue;
+ printf("Done\n");
+ reset();
+ return (1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/Makefile b/usr/src/boot/sys/boot/arm/at91/boot2/Makefile
new file mode 100644
index 0000000000..1150969bc4
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libat91 ${.CURDIR}/../bootspi
+
+P=boot2
+FILES=${P}
+SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+.if ${BOOT_FLAVOR} == "kb920x"
+CFLAGS+=-DBOOT_IIC
+.endif
+CFLAGS+= \
+ -I${.CURDIR}/../bootspi \
+ -I${.CURDIR}/../../../common \
+ -I${.CURDIR}/../../../.. \
+ -D_KERNEL \
+ -DUFS1_ONLY
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/board.h b/usr/src/boot/sys/boot/arm/at91/boot2/board.h
new file mode 100644
index 0000000000..823d871f9e
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/board.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+void Update(void);
+void board_init(void);
+int drvread(void *, unsigned, unsigned);
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/boot2.c b/usr/src/boot/sys/boot/arm/at91/boot2/boot2.c
new file mode 100644
index 0000000000..f7510a5a0f
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/boot2.c
@@ -0,0 +1,361 @@
+/*-
+ * Copyright (c) 2008 John Hay
+ * Copyright (c) 2006 M Warner Losh <imp@freebsd.org>
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/diskmbr.h>
+#include <sys/dirent.h>
+#include <sys/reboot.h>
+
+#include <machine/elf.h>
+
+#include <stdarg.h>
+
+#include "lib.h"
+#include "board.h"
+#include "paths.h"
+#include "rbx.h"
+
+#undef PATH_KERNEL
+#define PATH_KERNEL "/boot/kernel/kernel.gz.tramp"
+
+extern uint32_t _end;
+
+#define NOPT 6
+
+static const char optstr[NOPT] = "agnrsv";
+static const unsigned char bootflags[NOPT] = {
+ RBX_ASKNAME,
+ RBX_GDB,
+ RBX_NOINTR,
+ RBX_DFLTROOT,
+ RBX_SINGLE,
+ RBX_VERBOSE
+};
+
+unsigned board_id; /* board type to pass to kernel, if set by board_* code */
+unsigned dsk_start;
+static char cmd[512];
+static char kname[1024];
+static uint32_t opts;
+static uint8_t dsk_meta;
+
+int main(void);
+static void load(void);
+static int parse(void);
+static int dskread(void *, unsigned, unsigned);
+#ifdef FIXUP_BOOT_DRV
+static void fixup_boot_drv(caddr_t, int, int, int);
+#endif
+
+#define UFS_SMALL_CGBASE
+#include "ufsread.c"
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+static inline int
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
+{
+ if ((size_t)fsread(inode, buf, nbyte) != nbyte)
+ return -1;
+ return 0;
+}
+
+static inline void
+getstr(int c)
+{
+ char *s;
+
+ s = cmd;
+ if (c == 0)
+ c = getc(10000);
+ for (;;) {
+ switch (c) {
+ case 0:
+ break;
+ case '\177':
+ case '\b':
+ if (s > cmd) {
+ s--;
+ printf("\b \b");
+ }
+ break;
+ case '\n':
+ case '\r':
+ *s = 0;
+ return;
+ default:
+ if (s - cmd < sizeof(cmd) - 1)
+ *s++ = c;
+ xputchar(c);
+ }
+ c = getc(10000);
+ }
+}
+
+int
+main(void)
+{
+ int autoboot, c = 0;
+ ufs_ino_t ino;
+
+ dmadat = (void *)(0x20000000 + (16 << 20));
+ board_init();
+
+ autoboot = 1;
+
+ /* Process configuration file */
+ if ((ino = lookup(PATH_CONFIG)) ||
+ (ino = lookup(PATH_DOTCONFIG)))
+ fsread(ino, cmd, sizeof(cmd));
+
+ if (*cmd) {
+ if (parse())
+ autoboot = 0;
+ printf("%s: %s\n", PATH_CONFIG, cmd);
+ /* Do not process this command twice */
+ *cmd = 0;
+ }
+
+ if (*kname == '\0')
+ strcpy(kname, PATH_KERNEL);
+
+ /* Present the user with the boot2 prompt. */
+ for (;;) {
+ printf("\nDefault: %s\nboot: ", kname);
+ if (!autoboot ||
+ (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
+ getstr(c);
+ xputchar('\n');
+ autoboot = 0;
+ c = 0;
+ if (parse())
+ xputchar('\a');
+ else
+ load();
+ }
+ return (1);
+}
+
+static void
+load(void)
+{
+ Elf32_Ehdr eh;
+ static Elf32_Phdr ep[2];
+ caddr_t p;
+ ufs_ino_t ino;
+ uint32_t addr;
+ int i, j;
+#ifdef FIXUP_BOOT_DRV
+ caddr_t staddr;
+ int klen;
+
+ staddr = (caddr_t)0xffffffff;
+ klen = 0;
+#endif
+ if (!(ino = lookup(kname))) {
+ if (!ls)
+ printf("No %s\n", kname);
+ return;
+ }
+ if (xfsread(ino, &eh, sizeof(eh)))
+ return;
+ if (!IS_ELF(eh)) {
+ printf("Invalid %s\n", "format");
+ return;
+ }
+ fs_off = eh.e_phoff;
+ for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
+ if (xfsread(ino, ep + j, sizeof(ep[0])))
+ return;
+ if (ep[j].p_type == PT_LOAD)
+ j++;
+ }
+ for (i = 0; i < 2; i++) {
+ p = (caddr_t)ep[i].p_paddr;
+ fs_off = ep[i].p_offset;
+#ifdef FIXUP_BOOT_DRV
+ if (staddr == (caddr_t)0xffffffff)
+ staddr = p;
+ klen += ep[i].p_filesz;
+#endif
+ if (xfsread(ino, p, ep[i].p_filesz))
+ return;
+ }
+ addr = eh.e_entry;
+#ifdef FIXUP_BOOT_DRV
+ fixup_boot_drv(staddr, klen, bootslice, bootpart);
+#endif
+ ((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0);
+}
+
+static int
+parse()
+{
+ char *arg = cmd;
+ char *ep, *p;
+ int c, i;
+
+ while ((c = *arg++)) {
+ if (c == ' ' || c == '\t' || c == '\n')
+ continue;
+ for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
+ ep = p;
+ if (*p)
+ *p++ = 0;
+ if (c == '-') {
+ while ((c = *arg++)) {
+ for (i = 0; c != optstr[i]; i++)
+ if (i == NOPT - 1)
+ return -1;
+ opts ^= OPT_SET(bootflags[i]);
+ }
+ } else {
+ arg--;
+ if ((i = ep - arg)) {
+ if ((size_t)i >= sizeof(kname))
+ return -1;
+ memcpy(kname, arg, i + 1);
+ }
+ }
+ arg = p;
+ }
+ return 0;
+}
+
+static int
+dskread(void *buf, unsigned lba, unsigned nblk)
+{
+ struct dos_partition *dp;
+ struct disklabel *d;
+ char *sec;
+ int i;
+
+ if (!dsk_meta) {
+ sec = dmadat->secbuf;
+ dsk_start = 0;
+ if (drvread(sec, DOSBBSECTOR, 1))
+ return -1;
+ dp = (void *)(sec + DOSPARTOFF);
+ for (i = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == DOSPTYP_386BSD)
+ break;
+ }
+ if (i == NDOSPART)
+ return -1;
+ /*
+ * Although dp_start is aligned within the disk
+ * partition structure, DOSPARTOFF is 446, which is
+ * only word (2) aligned, not longword (4) aligned.
+ * Cope by using memcpy to fetch the start of this
+ * partition.
+ */
+ memcpy(&dsk_start, &dp[1].dp_start, 4);
+ if (drvread(sec, dsk_start + LABELSECTOR, 1))
+ return -1;
+ d = (void *)(sec + LABELOFFSET);
+ if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
+ printf("Invalid %s\n", "label");
+ return -1;
+ }
+ if (!d->d_partitions[0].p_size) {
+ printf("Invalid %s\n", "partition");
+ return -1;
+ }
+ dsk_start += d->d_partitions[0].p_offset;
+ dsk_start -= d->d_partitions[RAW_PART].p_offset;
+ dsk_meta++;
+ }
+ return drvread(buf, dsk_start + lba, nblk);
+}
+
+#ifdef FIXUP_BOOT_DRV
+/*
+ * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
+ * and change it to what was specified on the comandline or /boot.conf
+ * file or to what was encountered on the disk. It will try to handle 3
+ * different disk layouts, raw (dangerously dedicated), slice only and
+ * slice + partition. It will look for the following strings in the
+ * kernel, but if it is one of the first three, the string in the kernel
+ * must use the correct form to match the actual disk layout:
+ * - ufs:ad0a
+ * - ufs:ad0s1
+ * - ufs:ad0s1a
+ * - ufs:ROOTDEVNAME
+ * In the case of the first three strings, only the "a" at the end and
+ * the "1" after the "s" will be modified, if they exist. The string
+ * length will not be changed. In the case of the last string, the
+ * whole string will be built up and nul, '\0' terminated.
+ */
+static void
+fixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
+{
+ const u_int8_t op[] = "ufs:ROOTDEVNAME";
+ const u_int8_t op2[] = "ufs:ad0";
+ u_int8_t *p, *ps;
+
+ DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
+ (int)addr, klen, bs, bp);
+ if (bs > 4)
+ return;
+ if (bp > 7)
+ return;
+ ps = memmem(addr, klen, op, sizeof(op));
+ if (ps != NULL) {
+ p = ps + 4; /* past ufs: */
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
+ p += 3;
+ if (bs > 0) {
+ /* append slice */
+ *p++ = 's';
+ *p++ = bs + '0';
+ }
+ if (disk_layout != DL_SLICE) {
+ /* append partition */
+ *p++ = bp + 'a';
+ }
+ *p = '\0';
+ } else {
+ ps = memmem(addr, klen, op2, sizeof(op2) - 1);
+ if (ps != NULL) {
+ p = ps + sizeof(op2) - 1;
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ if (*p == 's') {
+ /* fix slice */
+ p++;
+ *p++ = bs + '0';
+ }
+ if (*p == 'a')
+ *p = bp + 'a';
+ }
+ }
+ if (ps == NULL) {
+ printf("Could not locate \"%s\" to fix kernel boot device, "
+ "check ROOTDEVNAME is set\n", op);
+ return;
+ }
+ DPRINTF("Changed boot device to %s\n", ps);
+}
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/bwct_board.c b/usr/src/boot/sys/boot/arm/at91/boot2/bwct_board.c
new file mode 100644
index 0000000000..fffdd2a817
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/bwct_board.c
@@ -0,0 +1,125 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "at91rm9200_lowlevel.h"
+#include "at91rm9200.h"
+#include "emac.h"
+#include "lib.h"
+#include "ee.h"
+#include "board.h"
+#include "sd-card.h"
+
+unsigned char mac[6] = { 0x00, 0x0e, 0x42, 0x02, 0x00, 0x28 };
+
+static void USART0_Init();
+static void USART1_Init();
+static void USART2_Init();
+static void USART3_Init();
+static void DS1672_Init();
+
+static void
+DS1672_Init() {
+ char buf[] = {0x00, 0xa9};
+
+ EEWrite(0xd0, buf, sizeof(buf));
+}
+
+static void
+USART0_Init() {
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ // setup GPIO
+ pPio->PIO_ASR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0;
+ pPio->PIO_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0;
+
+ // enable power
+ pPMC->PMC_PCER = 1u << AT91C_ID_US0;
+}
+
+static void
+USART1_Init() {
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ // setup GPIO
+ pPio->PIO_ASR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1;
+ pPio->PIO_PDR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1;
+
+ // enable power
+ pPMC->PMC_PCER = 1u << AT91C_ID_US1;
+}
+
+static void
+USART2_Init() {
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ // setup GPIO
+ pPio->PIO_ASR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2;
+ pPio->PIO_PDR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2;
+
+ // enable power
+ pPMC->PMC_PCER = 1u << AT91C_ID_US2;
+}
+
+static void
+USART3_Init() {
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ // setup GPIO
+ pPio->PIO_BSR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
+ pPio->PIO_PDR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
+
+ // enable power
+ pPMC->PMC_PCER = 1u << AT91C_ID_US3;
+}
+
+void
+board_init(void)
+{
+
+ printf("\n\n");
+ printf("BWCT FSB-A920-1\n");
+ printf("http://www.bwct.de\n");
+ printf("\n");
+#if defined(SDRAM_128M)
+ printf("AT92RM9200 180MHz 128MB\n");
+#else
+ printf("AT92RM9200 180MHz 64MB\n");
+#endif
+ printf("Initialising USART0\n");
+ USART0_Init();
+ printf("Initialising USART1\n");
+ USART1_Init();
+ printf("Initialising USART2\n");
+ USART2_Init();
+ printf("Initialising USART3\n");
+ USART3_Init();
+ printf("Initialising TWI\n");
+ EEInit();
+ printf("Initialising DS1672\n");
+ DS1672_Init();
+ printf("Initialising Ethernet\n");
+ printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
+ mac[1], mac[2], mac[3], mac[4], mac[5]);
+ EMAC_Init();
+ EMAC_SetMACAddress(mac);
+ printf("Initialising SD-card\n");
+ sdcard_init();
+}
+
+#include "../bootspi/ee.c"
+
+int
+drvread(void *buf, unsigned lba, unsigned nblk)
+{
+ return (MCI_read((char *)buf, lba << 9, nblk << 9));
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/centipad_board.c b/usr/src/boot/sys/boot/arm/at91/boot2/centipad_board.c
new file mode 100644
index 0000000000..c1b621e038
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/centipad_board.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "emac.h"
+#include "lib.h"
+#include "board.h"
+#include "sd-card.h"
+
+unsigned char mac[6] = { 0x42, 0x53, 0x44, 0, 1, 1 };
+
+static void
+MacFromEE()
+{
+#if 0
+ uint32_t sig;
+ sig = 0;
+ ReadEEPROM(12 * 1024, (uint8_t *)&sig, sizeof(sig));
+ if (sig != 0x92021054)
+ return;
+ ReadEEPROM(12 * 1024 + 4, mac, 6);
+#endif
+ printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
+ mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+void
+board_init(void)
+{
+ InitEEPROM();
+ MacFromEE();
+ EMAC_Init();
+ EMAC_SetMACAddress(mac);
+ while (sdcard_init() == 0)
+ printf("Looking for SD card\n");
+}
+
+int
+drvread(void *buf, unsigned lba, unsigned nblk)
+{
+ return (MCI_read((char *)buf, lba << 9, nblk << 9));
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/boot2/kb920x_board.c b/usr/src/boot/sys/boot/arm/at91/boot2/kb920x_board.c
new file mode 100644
index 0000000000..52f9676be4
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/boot2/kb920x_board.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "emac.h"
+#include "lib.h"
+#include "board.h"
+#include "sd-card.h"
+
+unsigned char mac[6] = { 0x42, 0x53, 0x44, 0, 0, 1 };
+
+static void
+MacFromEE()
+{
+ uint32_t sig;
+ sig = 0;
+ ReadEEPROM(12 * 1024, (uint8_t *)&sig, sizeof(sig));
+ if (sig != 0x92021054)
+ return;
+ ReadEEPROM(12 * 1024 + 4, mac, 6);
+ printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
+ mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+void
+board_init(void)
+{
+ InitEEPROM();
+ MacFromEE();
+ EMAC_Init();
+ EMAC_SetMACAddress(mac);
+ while (sdcard_init() == 0)
+ printf("Looking for SD card\n");
+}
+
+int
+drvread(void *buf, unsigned lba, unsigned nblk)
+{
+ return (MCI_read((char *)buf, lba << 9, nblk << 9));
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/Makefile b/usr/src/boot/sys/boot/arm/at91/bootiic/Makefile
new file mode 100644
index 0000000000..13f2482e62
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libat91
+
+P=bootiic
+FILES=${P}
+SRCS=arm_init.S main.c loader_prompt.c env_vars.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+CFLAGS += -DBOOT_IIC -DBOOT_COMMANDS
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/README b/usr/src/boot/sys/boot/arm/at91/bootiic/README
new file mode 100644
index 0000000000..1489d7c09c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/README
@@ -0,0 +1,35 @@
+$FreeBSD$
+
+This image is intended to be programmed into boot EEPROM. The image is nearly
+0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or
+later. Alternatively, the KB9200 can be upgraded with larger EEPROM.
+It performs basic functions prior to executing an image at a
+specified address. The pre-boot functions can be modified and saved back into
+EEPROM.
+The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address
+and must be changed to a valid value in order to use the ethernet interface.
+
+Memory usage:
+
+EEPROM = 0x4000
+SDRAM =
+ run stack = 0x21800000
+ variables = 0x21200000
+ ethernet = 0x21000000 (buffers and descriptors)
+
+
+Functions supported:
+
+ c - copy
+ d - display auto command table (in RAM)
+ e - execute image
+ ? - help
+ ip - set local ip
+ m - set mac
+ server_ip - set server ip
+ s - set auto command entry
+ t - create linux boot tag list
+ tftp - download image via tftp
+ w - update auto command table
+ x - download image via xmodem
+
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.c b/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.c
new file mode 100644
index 0000000000..f402a43f2a
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.c
@@ -0,0 +1,207 @@
+/******************************************************************************
+ *
+ * Filename: env_vars.c
+ *
+ * Instantiation of environment variables, structures, and other globals.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "env_vars.h"
+#include "loader_prompt.h"
+#include "lib.h"
+
+/******************************* GLOBALS *************************************/
+char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE];
+
+char env_table[MAX_ENV_SIZE_BYTES];
+
+extern char BootCommandSection;
+
+/************************** PRIVATE FUNCTIONS ********************************/
+
+
+static int currentIndex;
+static int currentOffset;
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int ReadCharFromEnvironment(char *)
+ * This private function reads characters from the enviroment variables
+ * to service the command prompt during auto-boot or just to setup the
+ * default environment. Returns positive value if valid character was
+ * set in the pointer. Returns negative value to signal input stream
+ * terminated. Returns 0 to indicate _wait_ condition.
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+ReadCharFromEnvironment(int timeout)
+{
+ int ch;
+
+ if (currentIndex < MAX_BOOT_COMMANDS) {
+ ch = boot_commands[currentIndex][currentOffset++];
+ if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) {
+ currentOffset = 0;
+ ++currentIndex;
+ ch = '\r';
+ }
+ return (ch);
+ }
+
+ return (-1);
+}
+
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void WriteCommandTable(void)
+ * This global function write the current command table to the non-volatile
+ * memory.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+WriteCommandTable(void)
+{
+ int i, size = MAX_ENV_SIZE_BYTES, copySize;
+ char *cPtr = env_table;
+
+ p_memset(env_table, 0, sizeof(env_table));
+
+ for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
+
+ copySize = p_strlen(boot_commands[i]);
+ size -= copySize + 1;
+
+ if (size < 0) {
+ continue;
+ }
+ memcpy(cPtr, boot_commands[i], copySize);
+ cPtr += copySize;
+ *cPtr++ = 0;
+ }
+
+ /* We're executing in low RAM so addr in ram == offset in eeprom */
+ WriteEEPROM((unsigned)&BootCommandSection, env_table,
+ sizeof(env_table));
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SetBootCommand(int index, char *command)
+ * This global function replaces the specified index with the string residing
+ * at command. Execute this function with a NULL string to clear the
+ * associated command index.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SetBootCommand(int index, char *command)
+{
+ int i;
+
+ if ((unsigned)index < MAX_BOOT_COMMANDS) {
+
+ p_memset(boot_commands[index], 0, MAX_INPUT_SIZE);
+
+ if (!command)
+ return ;
+
+ for (i = 0; i < MAX_INPUT_SIZE; ++i) {
+ boot_commands[index][i] = command[i];
+ if (!(boot_commands[index][i]))
+ return;
+ }
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void DumpBootCommands(void)
+ * This global function displays the current boot commands.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+DumpBootCommands(void)
+{
+ int i, j;
+
+ for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
+ printf("0x%x : ", i);
+ for (j = 0; j < MAX_INPUT_SIZE; ++j) {
+ putchar(boot_commands[i][j]);
+ if (!(boot_commands[i][j]))
+ break;
+ }
+ printf("[E]\n\r");
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void LoadBootCommands(void)
+ * This global function loads the existing boot commands from raw format and
+ * coverts it to the standard, command-index format. Notice, the processed
+ * boot command table has much more space allocated than the actual table
+ * stored in non-volatile memory. This is because the processed table
+ * exists in RAM which is larger than the non-volatile space.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+LoadBootCommands(void)
+{
+ int index, j, size;
+ char *cPtr;
+
+ p_memset((char*)boot_commands, 0, sizeof(boot_commands));
+
+ cPtr = &BootCommandSection;
+
+ size = MAX_ENV_SIZE_BYTES;
+
+ for (index = 0; (index < MAX_BOOT_COMMANDS) && size; ++index) {
+ for (j = 0; (j < MAX_INPUT_SIZE) && size; ++j) {
+ size--;
+ boot_commands[index][j] = *cPtr++;
+ if (!(boot_commands[index][j])) {
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ExecuteEnvironmentFunctions(void)
+ * This global function executes applicable entries in the environment.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+ExecuteEnvironmentFunctions(void)
+{
+ currentIndex = 0;
+ currentOffset = 0;
+
+ DumpBootCommands();
+ Bootloader(ReadCharFromEnvironment);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.h b/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.h
new file mode 100644
index 0000000000..c6e46b4e43
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/env_vars.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Filename: env_vars.h
+ *
+ * Definition of environment variables, structures, and other globals.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#ifndef _ENV_VARS_H_
+#define _ENV_VARS_H_
+
+/* each environment variable is a string following the standard command */
+/* definition used by the interactive loader in the following format: */
+/* <command> <parm1> <parm2> ... */
+/* all environment variables (or commands) are stored in a string */
+/* format: NULL-terminated. */
+/* this implies that commands can never utilize 0-values: actual 0, not */
+/* the string '0'. this is not an issue as the string '0' is handled */
+/* by the command parse routine. */
+
+/* the following defines the maximum size of the environment for */
+/* including variables. */
+/* this value must match that declared in the low-level file that */
+/* actually reserves the space for the non-volatile environment. */
+#define MAX_ENV_SIZE_BYTES 0x100
+
+#define MAX_BOOT_COMMANDS 10
+
+/* C-style reference section */
+#ifndef __ASSEMBLY__
+
+extern void WriteCommandTable(void);
+extern void SetBootCommand(int index, char *command);
+extern void DumpBootCommands(void);
+extern void LoadBootCommands(void);
+extern void ExecuteEnvironmentFunctions(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ENV_VARS_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.c b/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.c
new file mode 100644
index 0000000000..29413b8e6c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.c
@@ -0,0 +1,387 @@
+/******************************************************************************
+ *
+ * Filename: loader_prompt.c
+ *
+ * Instantiation of the interactive loader functions.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin massive changes for tftp, strings, and more
+ * 05JUL2005 kb_admin save tag address, and set registers on boot
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "at91rm9200_lowlevel.h"
+#ifdef SUPPORT_TAG_LIST
+#include "tag_list.h"
+#endif
+#include "emac.h"
+#include "loader_prompt.h"
+#include "env_vars.h"
+#include "lib.h"
+
+
+/******************************* GLOBALS *************************************/
+
+
+/*********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+static char inputBuffer[MAX_INPUT_SIZE];
+static int buffCount;
+
+// argv pointer are either NULL or point to locations in inputBuffer
+static char *argv[MAX_COMMAND_PARAMS];
+
+static const char *backspaceString = "\010 \010";
+
+static const command_entry_t CommandTable[] = {
+ {COMMAND_COPY, "c"},
+ {COMMAND_DUMP, "d"},
+ {COMMAND_EXEC, "e"},
+ {COMMAND_HELP, "?"},
+ {COMMAND_LOCAL_IP, "ip"},
+ {COMMAND_MAC, "m"},
+ {COMMAND_SERVER_IP, "server_ip"},
+ {COMMAND_SET, "s"},
+#ifdef SUPPORT_TAG_LIST
+ {COMMAND_TAG, "t"},
+#endif
+ {COMMAND_TFTP, "tftp"},
+ {COMMAND_WRITE, "w"},
+ {COMMAND_XMODEM, "x"},
+ {COMMAND_FINAL_FLAG, 0}
+};
+
+static unsigned tagAddress;
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned BuildIP(void)
+ * This private function packs the test IP info to an unsigned value.
+ * .KB_C_FN_DEFINITION_END
+ */
+static unsigned
+BuildIP(void)
+{
+ return ((p_ASCIIToDec(argv[1]) << 24) |
+ (p_ASCIIToDec(argv[2]) << 16) |
+ (p_ASCIIToDec(argv[3]) << 8) |
+ p_ASCIIToDec(argv[4]));
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int StringToCommand(char *cPtr)
+ * This private function converts a command string to a command code.
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+StringToCommand(char *cPtr)
+{
+ int i;
+
+ for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
+ if (!strcmp(CommandTable[i].c_string, cPtr))
+ return (CommandTable[i].command);
+
+ return (COMMAND_INVALID);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void RestoreSpace(int)
+ * This private function restores NULL characters to spaces in order to
+ * process the remaining args as a string. The number passed is the argc
+ * of the first entry to begin restoring space in the inputBuffer.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+RestoreSpace(int startArgc)
+{
+ char *cPtr;
+
+ for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) {
+ if ((cPtr = argv[startArgc]))
+ *(cPtr - 1) = ' ';
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int BreakCommand(char *)
+ * This private function splits the buffer into separate strings as pointed
+ * by argv and returns the number of parameters (< 0 on failure).
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+BreakCommand(char *buffer)
+{
+ int pCount, cCount, state;
+
+ state = pCount = 0;
+ p_memset((char*)argv, 0, sizeof(argv));
+
+ for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
+
+ if (!state) {
+ /* look for next command */
+ if (!p_IsWhiteSpace(buffer[cCount])) {
+ argv[pCount++] = &buffer[cCount];
+ state = 1;
+ } else {
+ buffer[cCount] = 0;
+ }
+ } else {
+ /* in command, find next white space */
+ if (p_IsWhiteSpace(buffer[cCount])) {
+ buffer[cCount] = 0;
+ state = 0;
+ }
+ }
+
+ if (pCount >= MAX_COMMAND_PARAMS) {
+ return (-1);
+ }
+ }
+
+ return (pCount);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ParseCommand(char *)
+ * This private function executes matching functions.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+ParseCommand(char *buffer)
+{
+ int argc, i;
+
+ if ((argc = BreakCommand(buffer)) < 1)
+ return;
+
+ switch (StringToCommand(argv[0])) {
+ case COMMAND_COPY:
+ {
+ // "c <to> <from> <size in bytes>"
+ // copy memory
+ char *to, *from;
+ unsigned size;
+
+ if (argc > 3) {
+ to = (char *)p_ASCIIToHex(argv[1]);
+ from = (char *)p_ASCIIToHex(argv[2]);
+ size = p_ASCIIToHex(argv[3]);
+ memcpy(to, from, size);
+ }
+ break;
+ }
+
+ case COMMAND_DUMP:
+ // display boot commands
+ DumpBootCommands();
+ break;
+
+ case COMMAND_EXEC:
+ {
+ // "e <address>"
+ // execute at address
+ void (*execAddr)(unsigned, unsigned, unsigned);
+
+ if (argc > 1) {
+ /* in future, include machtypes (MACH_KB9200 = 612) */
+ execAddr = (void (*)(unsigned, unsigned, unsigned))
+ p_ASCIIToHex(argv[1]);
+ (*execAddr)(0, 612, tagAddress);
+ }
+ break;
+ }
+
+ case COMMAND_TFTP:
+ {
+ // "tftp <local_dest_addr filename>"
+ // tftp download
+ unsigned address = 0;
+
+ if (argc > 2)
+ address = p_ASCIIToHex(argv[1]);
+ TFTP_Download(address, argv[2]);
+ break;
+ }
+
+ case COMMAND_SERVER_IP:
+ // "server_ip <server IP 192 200 1 20>"
+ // set download server address
+ if (argc > 4)
+ SetServerIPAddress(BuildIP());
+ break;
+
+ case COMMAND_HELP:
+ // dump command info
+ printf("Commands:\n"
+ "\tc\n"
+ "\td\n"
+ "\te\n"
+ "\tip\n"
+ "\tserver_ip\n"
+ "\tm\n"
+ "\ttftp\n"
+ "\ts\n"
+#ifdef SUPPORT_TAG_LIST
+ "\tt\n"
+#endif
+ "\tw\n"
+ "\tx\n");
+ break;
+
+ case COMMAND_LOCAL_IP:
+ // "local_ip <local IP 192 200 1 21>
+ // set ip of this module
+ if (argc > 4)
+ SetLocalIPAddress(BuildIP());
+ break;
+
+ case COMMAND_MAC:
+ {
+ // "m <mac address 12 34 56 78 9a bc>
+ // set mac address using 6 byte values
+ unsigned char mac[6];
+
+ if (argc > 6) {
+ for (i = 0; i < 6; i++)
+ mac[i] = p_ASCIIToHex(argv[i + 1]);
+ EMAC_SetMACAddress(mac);
+ }
+ break;
+ }
+
+ case COMMAND_SET:
+ {
+ // s <index> <new boot command>
+ // set the boot command at index (0-based)
+ unsigned index;
+
+ if (argc > 1) {
+ RestoreSpace(2);
+ index = p_ASCIIToHex(argv[1]);
+ SetBootCommand(index, argv[2]);
+ }
+ break;
+ }
+
+#ifdef SUPPORT_TAG_LIST
+ case COMMAND_TAG:
+ // t <address> <boot command line>
+ // create tag-list for linux boot
+ if (argc > 2) {
+ RestoreSpace(2);
+ tagAddress = p_ASCIIToHex(argv[1]);
+ InitTagList(argv[2], (void*)tagAddress);
+ }
+ break;
+#endif
+
+ case COMMAND_WRITE:
+ // write the command table to non-volatile
+ WriteCommandTable();
+ break;
+
+ case COMMAND_XMODEM:
+ {
+ // "x <address>"
+ // download X-modem record at address
+ if (argc > 1)
+ xmodem_rx((char *)p_ASCIIToHex(argv[1]));
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ printf("\n");
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ServicePrompt(char)
+ * This private function process each character checking for valid commands.
+ * This function is only executed if the character is considered valid.
+ * Each command is terminated with NULL (0) or ''.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+ServicePrompt(char p_char)
+{
+ if (p_char == '\r')
+ p_char = 0;
+
+ if (p_char == '\010') {
+ if (buffCount) {
+ /* handle backspace BS */
+ inputBuffer[--buffCount] = 0;
+ printf(backspaceString);
+ }
+ return;
+ }
+ if (buffCount < MAX_INPUT_SIZE - 1) {
+ inputBuffer[buffCount++] = p_char;
+ putchar(p_char);
+ }
+ if (!p_char) {
+ printf("\n");
+ ParseCommand(inputBuffer);
+ p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
+ buffCount = 0;
+ printf("\n>");
+ }
+}
+
+
+/* ************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void Bootloader(void *inputFunction)
+ * This global function is the entry point for the bootloader. If the
+ * inputFunction pointer is NULL, the loader input will be serviced from
+ * the uart. Otherwise, inputFunction is called to get characters which
+ * the loader will parse.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+Bootloader(int(*inputFunction)(int))
+{
+ int ch = 0;
+
+ p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
+
+ buffCount = 0;
+ if (!inputFunction) {
+ inputFunction = getc;
+ }
+
+ printf("\n>");
+
+ while (1)
+ if ((ch = ((*inputFunction)(0))) > 0)
+ ServicePrompt(ch);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.h b/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.h
new file mode 100644
index 0000000000..02233405f9
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/loader_prompt.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ * Filename: loader_prompt.h
+ *
+ * Definition of the interactive loader functions.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#ifndef _LOADER_PROMPT_H_
+#define _LOADER_PROMPT_H_
+
+#define MAX_INPUT_SIZE 256
+#define MAX_COMMAND_PARAMS 10
+
+enum {
+ COMMAND_INVALID = 0,
+ COMMAND_COPY,
+ COMMAND_DUMP,
+ COMMAND_EXEC,
+ COMMAND_HELP,
+ COMMAND_LOCAL_IP,
+ COMMAND_MAC,
+ COMMAND_SERVER_IP,
+ COMMAND_SET,
+ COMMAND_TAG,
+ COMMAND_TFTP,
+ COMMAND_WRITE,
+ COMMAND_XMODEM,
+ COMMAND_FINAL_FLAG
+} e_cmd_t;
+
+
+typedef struct {
+ int command;
+ const char *c_string;
+} command_entry_t;
+
+void EnterInteractiveBootloader(int(*inputFunction)(int));
+void Bootloader(int(*inputFunction)(int));
+
+#endif /* _LOADER_PROMPT_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/bootiic/main.c b/usr/src/boot/sys/boot/arm/at91/bootiic/main.c
new file mode 100644
index 0000000000..86368358ce
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootiic/main.c
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ *
+ * Filename: main.c
+ *
+ * Basic entry points for top-level functions
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin cosmetic changes
+ * 29APR2005 kb_admin modified boot delay
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+
+#include "env_vars.h"
+#include "at91rm9200_lowlevel.h"
+#include "loader_prompt.h"
+#include "emac.h"
+#include "lib.h"
+
+int main(void);
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int main(void)
+ * This global function waits at least one second, but not more than two
+ * seconds, for input from the serial port. If no response is recognized,
+ * it acts according to the parameters specified by the environment. For
+ * example, the function might boot an operating system. Do not return
+ * from this function.
+ * .KB_C_FN_DEFINITION_END
+ */
+int
+main(void)
+{
+ InitEEPROM();
+ EMAC_Init();
+ LoadBootCommands();
+ printf("\n\rKB9202(www.kwikbyte.com)\n\rAuto boot..\n\r");
+ if (getc(1) == -1)
+ ExecuteEnvironmentFunctions();
+ Bootloader(0);
+
+ return (1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/Makefile b/usr/src/boot/sys/boot/arm/at91/bootspi/Makefile
new file mode 100644
index 0000000000..a02d447b48
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+.PATH: ${.CURDIR}/../libat91
+
+P=bootspi
+FILES=${P}
+SRCS=arm_init.S main.c loader_prompt.c env_vars.c ee.c
+MAN=
+LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+.include <bsd.prog.mk>
+
+.if ${MK_FPGA} == "yes"
+CFLAGS += -DTSC_FPGA
+.endif
+CFLAGS += -DBOOT_COMMANDS
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/README b/usr/src/boot/sys/boot/arm/at91/bootspi/README
new file mode 100644
index 0000000000..9a4ffa8824
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/README
@@ -0,0 +1,34 @@
+$FreeBSD$
+
+This image is intended to be programmed into boot EEPROM. The image is nearly
+0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or
+later. Alternatively, the KB9200 can be upgraded with larger EEPROM.
+It performs basic functions prior to executing an image at a
+specified address. The pre-boot functions can be modified and saved back into
+EEPROM.
+The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address
+and must be changed to a valid value in order to use the ethernet interface.
+
+Memory usage:
+
+EEPROM = 0x4000
+SDRAM =
+ run stack = 0x21800000
+ variables = 0x21200000
+ ethernet = 0x21000000 (buffers and descriptors)
+
+
+Functions supported:
+
+ c - copy
+ d - display auto command table (in RAM)
+ e - execute image
+ ? - help
+ ip - set local ip
+ m - set mac
+ server_ip - set server ip
+ s - set auto command entry
+ t - create linux boot tag list
+ tftp - download image via tftp
+ w - update auto command table
+ x - download image via xmodem
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/ee.c b/usr/src/boot/sys/boot/arm/at91/bootspi/ee.c
new file mode 100644
index 0000000000..ef0571924b
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/ee.c
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * Filename: eeprom.c
+ *
+ * Instantiation of eeprom routines
+ *
+ * Revision information:
+ *
+ * 28AUG2004 kb_admin initial creation - adapted from Atmel sources
+ * 12JAN2005 kb_admin fixed clock generation, write polling, init
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "at91rm9200_lowlevel.h"
+#include "at91rm9200.h"
+#include "lib.h"
+#include "ee.h"
+
+/******************************* GLOBALS *************************************/
+
+
+/*********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+
+/* Use a macro to calculate the TWI clock generator value to save code space. */
+#define AT91C_TWSI_CLOCK 100000
+#define TWSI_EEPROM_ADDRESS 0x40
+
+#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
+#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
+
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void InitEEPROM(void)
+ * This global function initializes the EEPROM interface (TWI). Intended
+ * to be called a single time.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+EEInit(void)
+{
+
+ AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+ pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+
+ pPio->PIO_MDDR = ~AT91C_PIO_PA25;
+ pPio->PIO_MDER = AT91C_PIO_PA25;
+
+ pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
+
+ twiPtr->TWI_IDR = 0xffffffffu;
+ twiPtr->TWI_CR = AT91C_TWI_SWRST;
+ twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
+
+ twiPtr->TWI_CWGR = SET_TWI_CLOCK;
+}
+
+static inline unsigned
+iicaddr(unsigned ee_off)
+{
+ return (TWSI_EEPROM_ADDRESS | ((ee_off >> 8) & 0x7));
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
+ * This global function reads data from the eeprom at ee_addr storing data
+ * to data_addr for size bytes. Assume the TWI has been initialized.
+ * This function does not utilize the page read mode to simplify the code.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+EERead(unsigned ee_off, char *data_addr, unsigned size)
+{
+ const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
+ unsigned int status;
+
+ if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
+ printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
+ return;
+ }
+
+ status = twiPtr->TWI_SR;
+ status = twiPtr->TWI_RHR;
+ twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | AT91C_TWI_IADRSZ_1_BYTE |
+ AT91C_TWI_MREAD;
+ twiPtr->TWI_IADR = ee_off & 0xff;
+ twiPtr->TWI_CR = AT91C_TWI_START;
+ while (size-- > 1) {
+ while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
+ continue;
+ *(data_addr++) = twiPtr->TWI_RHR;
+ }
+ twiPtr->TWI_CR = AT91C_TWI_STOP;
+ status = twiPtr->TWI_SR;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+ continue;
+ *data_addr = twiPtr->TWI_RHR;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
+ * This global function writes data to the eeprom at ee_off using data
+ * from data_addr for size bytes. Assume the TWI has been initialized.
+ * This function does not utilize the page write mode as the write time is
+ * much greater than the time required to access the device for byte-write
+ * functionality. This allows the function to be much simpler.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+EEWrite(unsigned ee_off, const char *data_addr, unsigned size)
+{
+ const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
+ unsigned status;
+ char test_data;
+
+ while (size--) {
+ // Set the TWI Master Mode Register
+ twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) |
+ AT91C_TWI_IADRSZ_1_BYTE;
+ twiPtr->TWI_IADR = ee_off++;
+ status = twiPtr->TWI_SR;
+
+ // Load one data byte
+ twiPtr->TWI_THR = *(data_addr++);
+ twiPtr->TWI_CR = AT91C_TWI_START;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
+ continue;
+ twiPtr->TWI_CR = AT91C_TWI_STOP;
+ status = twiPtr->TWI_SR;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+ continue;
+
+ // wait for write operation to complete, it is done once
+ // we can read it back...
+ EERead(ee_off, &test_data, 1);
+ }
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/ee.h b/usr/src/boot/sys/boot/arm/at91/bootspi/ee.h
new file mode 100644
index 0000000000..d4d8b8dc6f
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/ee.h
@@ -0,0 +1,6 @@
+/* $FreeBSD$ */
+
+void EEInit(void);
+void EERead(unsigned ee_off, char *data_addr, unsigned size);
+void EEWrite(unsigned ee_off, const char *data_addr, unsigned size);
+
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.c b/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.c
new file mode 100644
index 0000000000..7ab250e5d7
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.c
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * Filename: env_vars.c
+ *
+ * Instantiation of environment variables, structures, and other globals.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "env_vars.h"
+#include "loader_prompt.h"
+#include "lib.h"
+
+/******************************* GLOBALS *************************************/
+char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE];
+
+char env_table[MAX_ENV_SIZE_BYTES];
+
+extern char BootCommandSection;
+
+/************************** PRIVATE FUNCTIONS ********************************/
+
+
+static int currentIndex;
+static int currentOffset;
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int ReadCharFromEnvironment(char *)
+ * This private function reads characters from the enviroment variables
+ * to service the command prompt during auto-boot or just to setup the
+ * default environment. Returns positive value if valid character was
+ * set in the pointer. Returns negative value to signal input stream
+ * terminated. Returns 0 to indicate _wait_ condition.
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+ReadCharFromEnvironment(int timeout)
+{
+ int ch;
+
+ if (currentIndex < MAX_BOOT_COMMANDS) {
+ ch = boot_commands[currentIndex][currentOffset++];
+ if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) {
+ currentOffset = 0;
+ ++currentIndex;
+ ch = '\r';
+ }
+ return (ch);
+ }
+
+ return (-1);
+}
+
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void DumpBootCommands(void)
+ * This global function displays the current boot commands.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+DumpBootCommands(void)
+{
+ int i;
+
+ for (i = 0; boot_commands[i][0]; i++)
+ printf("0x%x : %s[E]\n", i, boot_commands[i]);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void LoadBootCommands(void)
+ * This global function loads the existing boot commands from raw format and
+ * coverts it to the standard, command-index format. Notice, the processed
+ * boot command table has much more space allocated than the actual table
+ * stored in non-volatile memory. This is because the processed table
+ * exists in RAM which is larger than the non-volatile space.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+LoadBootCommands(void)
+{
+ int index, j;
+ char *cptr;
+
+ p_memset((char*)boot_commands, 0, sizeof(boot_commands));
+ cptr = &BootCommandSection;
+ for (index = 0; *cptr; index++) {
+ for (j = 0; *cptr; j++)
+ boot_commands[index][j] = *cptr++;
+ cptr++;
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ExecuteEnvironmentFunctions(void)
+ * This global function executes applicable entries in the environment.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+ExecuteEnvironmentFunctions(void)
+{
+ currentIndex = 0;
+ currentOffset = 0;
+
+ DumpBootCommands();
+ printf("Autoboot...\n");
+ Bootloader(ReadCharFromEnvironment);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.h b/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.h
new file mode 100644
index 0000000000..c6e46b4e43
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/env_vars.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Filename: env_vars.h
+ *
+ * Definition of environment variables, structures, and other globals.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#ifndef _ENV_VARS_H_
+#define _ENV_VARS_H_
+
+/* each environment variable is a string following the standard command */
+/* definition used by the interactive loader in the following format: */
+/* <command> <parm1> <parm2> ... */
+/* all environment variables (or commands) are stored in a string */
+/* format: NULL-terminated. */
+/* this implies that commands can never utilize 0-values: actual 0, not */
+/* the string '0'. this is not an issue as the string '0' is handled */
+/* by the command parse routine. */
+
+/* the following defines the maximum size of the environment for */
+/* including variables. */
+/* this value must match that declared in the low-level file that */
+/* actually reserves the space for the non-volatile environment. */
+#define MAX_ENV_SIZE_BYTES 0x100
+
+#define MAX_BOOT_COMMANDS 10
+
+/* C-style reference section */
+#ifndef __ASSEMBLY__
+
+extern void WriteCommandTable(void);
+extern void SetBootCommand(int index, char *command);
+extern void DumpBootCommands(void);
+extern void LoadBootCommands(void);
+extern void ExecuteEnvironmentFunctions(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ENV_VARS_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.c b/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.c
new file mode 100644
index 0000000000..63bc50e536
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.c
@@ -0,0 +1,363 @@
+/******************************************************************************
+ *
+ * Filename: loader_prompt.c
+ *
+ * Instantiation of the interactive loader functions.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin massive changes for tftp, strings, and more
+ * 05JUL2005 kb_admin save tag address, and set registers on boot
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "at91rm9200_lowlevel.h"
+#include "at91rm9200.h"
+#include "emac.h"
+#include "loader_prompt.h"
+#include "env_vars.h"
+#include "lib.h"
+#include "spi_flash.h"
+#include "ee.h"
+
+/******************************* GLOBALS *************************************/
+
+
+/*********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+static char inputBuffer[MAX_INPUT_SIZE];
+static int buffCount;
+
+// argv pointer are either NULL or point to locations in inputBuffer
+static char *argv[MAX_COMMAND_PARAMS];
+
+#define FLASH_OFFSET (0 * FLASH_PAGE_SIZE)
+#define KERNEL_OFFSET (220 * FLASH_PAGE_SIZE)
+#define KERNEL_LEN (6 * 1024 * FLASH_PAGE_SIZE)
+static const char *backspaceString = "\010 \010";
+
+static const command_entry_t CommandTable[] = {
+ {COMMAND_DUMP, "d"},
+ {COMMAND_EXEC, "e"},
+ {COMMAND_LOCAL_IP, "ip"},
+ {COMMAND_MAC, "m"},
+ {COMMAND_SERVER_IP, "server_ip"},
+ {COMMAND_TFTP, "tftp"},
+ {COMMAND_XMODEM, "x"},
+ {COMMAND_RESET, "R"},
+ {COMMAND_LOAD_SPI_KERNEL, "k"},
+ {COMMAND_REPLACE_KERNEL_VIA_XMODEM, "K"},
+ {COMMAND_REPLACE_FLASH_VIA_XMODEM, "I"},
+ {COMMAND_REPLACE_ID_EEPROM, "E"},
+ {COMMAND_FINAL_FLAG, 0}
+};
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned BuildIP(void)
+ * This private function packs the test IP info to an unsigned value.
+ * .KB_C_FN_DEFINITION_END
+ */
+static unsigned
+BuildIP(void)
+{
+ return ((p_ASCIIToDec(argv[1]) << 24) |
+ (p_ASCIIToDec(argv[2]) << 16) |
+ (p_ASCIIToDec(argv[3]) << 8) |
+ p_ASCIIToDec(argv[4]));
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int StringToCommand(char *cPtr)
+ * This private function converts a command string to a command code.
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+StringToCommand(char *cPtr)
+{
+ int i;
+
+ for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
+ if (!strcmp(CommandTable[i].c_string, cPtr))
+ return (CommandTable[i].command);
+
+ return (COMMAND_INVALID);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int BreakCommand(char *)
+ * This private function splits the buffer into separate strings as pointed
+ * by argv and returns the number of parameters (< 0 on failure).
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+BreakCommand(char *buffer)
+{
+ int pCount, cCount, state;
+
+ state = pCount = 0;
+ p_memset((char*)argv, 0, sizeof(argv));
+
+ for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
+
+ if (!state) {
+ /* look for next command */
+ if (!p_IsWhiteSpace(buffer[cCount])) {
+ argv[pCount++] = &buffer[cCount];
+ state = 1;
+ } else {
+ buffer[cCount] = 0;
+ }
+ } else {
+ /* in command, find next white space */
+ if (p_IsWhiteSpace(buffer[cCount])) {
+ buffer[cCount] = 0;
+ state = 0;
+ }
+ }
+
+ if (pCount >= MAX_COMMAND_PARAMS) {
+ return (-1);
+ }
+ }
+
+ return (pCount);
+}
+
+#if 0
+static void
+UpdateEEProm(int eeaddr)
+{
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
+ int len;
+
+ while ((len = xmodem_rx(addr)) == -1)
+ continue;
+ printf("\nDownloaded %u bytes.\n", len);
+ WriteEEPROM(eeaddr, 0, addr, len);
+}
+#endif
+
+static void
+UpdateFlash(int offset)
+{
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
+ int len, i, off;
+
+ while ((len = xmodem_rx(addr)) == -1)
+ continue;
+ printf("\nDownloaded %u bytes.\n", len);
+ for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
+ off = i + offset;
+ SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
+ }
+}
+
+static void
+LoadKernelFromSpi(char *addr)
+{
+ int i, off;
+
+ for (i = 0; i < KERNEL_LEN; i+= FLASH_PAGE_SIZE) {
+ off = i + KERNEL_OFFSET;
+ SPI_ReadFlash(off, addr + i, FLASH_PAGE_SIZE);
+ }
+}
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ParseCommand(char *)
+ * This private function executes matching functions.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+ParseCommand(char *buffer)
+{
+ int argc, i;
+
+ if ((argc = BreakCommand(buffer)) < 1)
+ return;
+
+ switch (StringToCommand(argv[0])) {
+ case COMMAND_DUMP:
+ // display boot commands
+ DumpBootCommands();
+ break;
+
+ case COMMAND_EXEC:
+ {
+ // "e <address>"
+ // execute at address
+ void (*execAddr)(unsigned, unsigned);
+
+ if (argc > 1) {
+ /* in future, include machtypes (MACH_KB9200 = 612) */
+ execAddr = (void (*)(unsigned, unsigned))
+ p_ASCIIToHex(argv[1]);
+ (*execAddr)(0, 612);
+ }
+ break;
+ }
+
+ case COMMAND_TFTP:
+ {
+ // "tftp <local_dest_addr filename>"
+ // tftp download
+ unsigned address = 0;
+
+ if (argc > 2)
+ address = p_ASCIIToHex(argv[1]);
+ TFTP_Download(address, argv[2]);
+ break;
+ }
+
+ case COMMAND_SERVER_IP:
+ // "server_ip <server IP 192 200 1 20>"
+ // set download server address
+ if (argc > 4)
+ SetServerIPAddress(BuildIP());
+ break;
+
+ case COMMAND_LOCAL_IP:
+ // "local_ip <local IP 192 200 1 21>
+ // set ip of this module
+ if (argc > 4)
+ SetLocalIPAddress(BuildIP());
+ break;
+
+ case COMMAND_MAC:
+ {
+ // "m <mac address 12 34 56 78 9a bc>
+ // set mac address using 6 byte values
+ unsigned char mac[6];
+
+ if (argc > 6) {
+ for (i = 0; i < 6; i++)
+ mac[i] = p_ASCIIToHex(argv[i + 1]);
+ EMAC_SetMACAddress(mac);
+ }
+ break;
+ }
+
+ case COMMAND_LOAD_SPI_KERNEL:
+ // "k <address>"
+ if (argc > 1)
+ LoadKernelFromSpi((char *)p_ASCIIToHex(argv[1]));
+ break;
+
+ case COMMAND_XMODEM:
+ // "x <address>"
+ // download X-modem record at address
+ if (argc > 1)
+ xmodem_rx((char *)p_ASCIIToHex(argv[1]));
+ break;
+
+ case COMMAND_RESET:
+ printf("Reset\n");
+ reset();
+ while (1) continue;
+ break;
+
+ case COMMAND_REPLACE_KERNEL_VIA_XMODEM:
+ printf("Updating KERNEL image\n");
+ UpdateFlash(KERNEL_OFFSET);
+ break;
+ case COMMAND_REPLACE_FLASH_VIA_XMODEM:
+ printf("Updating FLASH image\n");
+ UpdateFlash(FLASH_OFFSET);
+ break;
+
+ case COMMAND_REPLACE_ID_EEPROM:
+ {
+ char buf[25];
+ printf("Testing Config EEPROM\n");
+ EEWrite(0, "This is a test", 15);
+ EERead(0, buf, 15);
+ printf("Found '%s'\n", buf);
+ break;
+ }
+ default:
+ break;
+ }
+
+ printf("\n");
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ServicePrompt(char)
+ * This private function process each character checking for valid commands.
+ * This function is only executed if the character is considered valid.
+ * Each command is terminated with NULL (0) or ''.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+ServicePrompt(char p_char)
+{
+ if (p_char == '\r')
+ p_char = 0;
+
+ if (p_char == '\010') {
+ if (buffCount) {
+ /* handle backspace BS */
+ inputBuffer[--buffCount] = 0;
+ printf(backspaceString);
+ }
+ return;
+ }
+ if (buffCount < MAX_INPUT_SIZE - 1) {
+ inputBuffer[buffCount++] = p_char;
+ putchar(p_char);
+ }
+ if (!p_char) {
+ printf("\n");
+ ParseCommand(inputBuffer);
+ p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
+ buffCount = 0;
+ printf("\n>");
+ }
+}
+
+
+/* ************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void Bootloader(void *inputFunction)
+ * This global function is the entry point for the bootloader. If the
+ * inputFunction pointer is NULL, the loader input will be serviced from
+ * the uart. Otherwise, inputFunction is called to get characters which
+ * the loader will parse.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+Bootloader(int(*inputFunction)(int))
+{
+ int ch = 0;
+
+ p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
+ buffCount = 0;
+
+ printf("\n>");
+
+ while (1)
+ if ((ch = ((*inputFunction)(0))) > 0)
+ ServicePrompt(ch);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.h b/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.h
new file mode 100644
index 0000000000..70d7514391
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/loader_prompt.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Filename: loader_prompt.h
+ *
+ * Definition of the interactive loader functions.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#ifndef _LOADER_PROMPT_H_
+#define _LOADER_PROMPT_H_
+
+#define MAX_INPUT_SIZE 256
+#define MAX_COMMAND_PARAMS 10
+
+enum {
+ COMMAND_INVALID = 0,
+ COMMAND_COPY,
+ COMMAND_DUMP,
+ COMMAND_EXEC,
+ COMMAND_HELP,
+ COMMAND_LOCAL_IP,
+ COMMAND_MAC,
+ COMMAND_SERVER_IP,
+ COMMAND_SET,
+ COMMAND_TAG,
+ COMMAND_TFTP,
+ COMMAND_WRITE,
+ COMMAND_XMODEM,
+ COMMAND_RESET,
+ COMMAND_LOAD_SPI_KERNEL,
+ COMMAND_REPLACE_KERNEL_VIA_XMODEM,
+ COMMAND_REPLACE_FLASH_VIA_XMODEM,
+ COMMAND_REPLACE_FPGA_VIA_XMODEM,
+ COMMAND_REPLACE_ID_EEPROM,
+ COMMAND_FINAL_FLAG
+} e_cmd_t;
+
+
+typedef struct {
+ int command;
+ const char *c_string;
+} command_entry_t;
+
+void EnterInteractiveBootloader(int(*inputFunction)(int));
+void Bootloader(int(*inputFunction)(int));
+void fpga_load(void);
+
+#endif /* _LOADER_PROMPT_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/bootspi/main.c b/usr/src/boot/sys/boot/arm/at91/bootspi/main.c
new file mode 100644
index 0000000000..cb9d1dbc42
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/bootspi/main.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provided by kwikbyte without
+ * copyright as follows:
+ *
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ *
+ * $FreeBSD$
+ */
+
+#include "env_vars.h"
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+#include "loader_prompt.h"
+#include "emac.h"
+#include "lib.h"
+#include "spi_flash.h"
+#include "ee.h"
+
+int main(void);
+
+int
+main(void)
+{
+ printf("\nBoot\n");
+ EEInit();
+ SPI_InitFlash();
+#ifdef TSC_FPGA
+ fpga_load();
+#endif
+ EMAC_Init();
+ LoadBootCommands();
+ if (getc(1) == -1) {
+ start_wdog(30);
+ ExecuteEnvironmentFunctions();
+ }
+ Bootloader(getc);
+ return (1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/Makefile b/usr/src/boot/sys/boot/arm/at91/libat91/Makefile
new file mode 100644
index 0000000000..b02281dc64
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+.include "${.CURDIR}/../Makefile.inc"
+
+SOC?=at91rm9200
+
+LIB= at91
+INTERNALLIB=
+SRCS=${SOC}_lowlevel.c delay.c eeprom.c emac.c emac_init.c getc.c \
+ putchar.c printf.c reset.c spi_flash.c xmodem.c \
+ sd-card.c strcvt.c strlen.c strcmp.c memcpy.c strcpy.c \
+ memset.c memcmp.c
+SRCS+=ashldi3.c divsi3.S
+MAN=
+
+.if ${MK_TAG_LIST} != "no"
+CFLAGS += -I${.CURDIR}/.. -DSUPPORT_TAG_LIST
+SRCS+=tag_list.c
+.endif
+
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/arm_init.S b/usr/src/boot/sys/boot/arm/at91/libat91/arm_init.S
new file mode 100644
index 0000000000..a15fb540e9
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/arm_init.S
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ *
+ * Filename: arm_init.s
+ *
+ * Initialization for C-environment and basic operation. Adapted from
+ * ATMEL cstartup.s.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin updated for 16KB eeprom
+ * Atmel stack prevents loading full size at once
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+
+ .equ TWI_EEPROM_SIZE, 0x3000
+ .equ ARM_MODE_USER, 0x10
+ .equ ARM_MODE_FIQ, 0x11
+ .equ ARM_MODE_IRQ, 0x12
+ .equ ARM_MODE_SVC, 0x13
+ .equ ARM_MODE_ABORT, 0x17
+ .equ ARM_MODE_UNDEF, 0x1B
+ .equ ARM_MODE_SYS, 0x1F
+ .equ I_BIT, 0x80
+ .equ F_BIT, 0x40
+ .equ T_BIT, 0x20
+
+/*
+ * Stack definitions
+ *
+ * Start near top of internal RAM.
+ */
+ .equ END_INT_SRAM, 0x4000
+ .equ SVC_STACK_START, (END_INT_SRAM - 0x4)
+ .equ SVC_STACK_USE, 0x21800000
+
+start:
+
+/* vectors - must reside at address 0 */
+/* the format of this table is defined in the datasheet */
+ B InitReset @; reset
+undefvec:
+ B undefvec @; Undefined Instruction
+swivec:
+ B swivec @; Software Interrupt
+pabtvec:
+ B pabtvec @; Prefetch Abort
+dabtvec:
+ B dabtvec @; Data Abort
+rsvdvec:
+#ifdef BOOT_IIC
+ .long (TWI_EEPROM_SIZE >> 9)
+#else
+#ifdef BOOT_BWCT
+ .long ((528 << 17) | (13 << 13) | (12 * 2))
+#else
+ .long ((1056 << 17) | (13 << 13) | (12 * 2))
+#endif
+#endif
+irqvec:
+ ldr pc, [pc,#-0xF20] @; IRQ : read the AIC
+fiqvec:
+ B fiqvec @; FIQ
+
+InitReset:
+
+/* Set stack and init for SVC */
+ ldr r1, = SVC_STACK_START
+ mov sp, r1 @; Init stack SYS
+
+ msr cpsr_c, #(ARM_MODE_SVC | I_BIT | F_BIT)
+ mov sp, r1 @ ; Init stack SYS
+
+/* Perform system initialization */
+
+ .extern _init
+ bl _init
+#ifndef BOOT_BOOT0
+ ldr r1, = SVC_STACK_USE
+ mov sp, r1 @ ; Move the stack to SDRAM
+#endif
+
+/* Start execution at main */
+ .extern main
+_main:
+__main:
+ bl main
+/* main should not return. If it does, spin forever */
+infiniteLoop:
+ b infiniteLoop
+
+#ifdef BOOT_COMMANDS
+/* the following section is used to store boot commands in */
+/* non-volatile memory. */
+
+ .global BootCommandSection
+BootCommandSection:
+#ifdef SUPPORT_LINUX
+ .string "Bootloader for KB9202 Evaluation Board."
+ .string "c 0x20210000 0x10100000 0x80000 "
+ .string "m 0 0 0 0 0 0 "
+ .string "t 0x20000100 console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933"
+ .string "e 0x10000000 "
+ .string " "
+#else
+#if 1
+ .string "m 42 53 44 0 0 1"
+ .string "ip 206 168 13 194"
+ .string "server_ip 206 168 13 207"
+ .string "tftp 0x20000000 kernel.bin"
+ .string "e 0x20000000"
+#else
+ .string "m 42 53 44 0 0 1"
+ .string "k 0x20000000"
+ .string "e 0x20000000"
+#endif
+ .word 0
+#endif
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200.h b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200.h
new file mode 100644
index 0000000000..80d44c8243
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200.h
@@ -0,0 +1,2411 @@
+// ----------------------------------------------------------------------------
+// ATMEL Microcontroller Software Support - ROUSSET -
+// ----------------------------------------------------------------------------
+// The software is delivered "AS IS" without warranty or condition of any
+// kind, either express, implied or statutory. This includes without
+// limitation any warranty or condition with respect to merchantability or
+// fitness for any particular purpose, or against the infringements of
+// intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// $FreeBSD$
+//
+// File Name : AT91RM9200.h
+// Object : AT91RM9200 definitions
+// Generated : AT91 SW Application Group 07/04/2003 (11:05:04)
+//
+// CVS Reference : /AT91RM9200.pl/1.16/Fri Feb 07 09:29:50 2003//
+// CVS Reference : /SYS_AT91RM9200.pl/1.2/Fri Jan 17 11:44:36 2003//
+// CVS Reference : /MC_1760A.pl/1.1/Fri Aug 23 13:38:22 2002//
+// CVS Reference : /AIC_1796B.pl/1.1.1.1/Fri Jun 28 08:36:46 2002//
+// CVS Reference : /PMC_2636A.pl/1.1.1.1/Fri Jun 28 08:36:48 2002//
+// CVS Reference : /ST_1763B.pl/1.1/Fri Aug 23 13:41:42 2002//
+// CVS Reference : /RTC_1245D.pl/1.2/Fri Jan 31 11:19:06 2003//
+// CVS Reference : /PIO_1725D.pl/1.1.1.1/Fri Jun 28 08:36:46 2002//
+// CVS Reference : /DBGU_1754A.pl/1.4/Fri Jan 31 11:18:24 2003//
+// CVS Reference : /UDP_1765B.pl/1.3/Fri Aug 02 13:45:38 2002//
+// CVS Reference : /MCI_1764A.pl/1.2/Thu Nov 14 16:48:24 2002//
+// CVS Reference : /US_1739C.pl/1.2/Fri Jul 12 06:49:24 2002//
+// CVS Reference : /SPI_AT91RMxxxx.pl/1.3/Tue Nov 26 09:20:28 2002//
+// CVS Reference : /SSC_1762A.pl/1.2/Fri Nov 08 12:26:38 2002//
+// CVS Reference : /TC_1753B.pl/1.2/Fri Jan 31 11:19:54 2003//
+// CVS Reference : /TWI_1761B.pl/1.4/Fri Feb 07 09:30:06 2003//
+// CVS Reference : /PDC_1734B.pl/1.2/Thu Nov 21 15:38:22 2002//
+// CVS Reference : /UHP_xxxxA.pl/1.1/Mon Jul 22 11:21:58 2002//
+// CVS Reference : /EMAC_1794A.pl/1.4/Fri Jan 17 11:11:54 2003//
+// CVS Reference : /EBI_1759B.pl/1.10/Fri Jan 17 11:44:28 2003//
+// CVS Reference : /SMC_1783A.pl/1.3/Thu Oct 31 13:38:16 2002//
+// CVS Reference : /SDRC_1758B.pl/1.2/Thu Oct 03 12:04:40 2002//
+// CVS Reference : /BFC_1757B.pl/1.3/Thu Oct 31 13:38:00 2002//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_H
+#define AT91RM9200_H
+
+#define ATMEL_ENV
+
+typedef volatile unsigned int AT91_REG;// Hardware register definition
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR System Peripherals
+// *****************************************************************************
+typedef struct _AT91S_SYS {
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+ AT91_REG Reserved2[45]; //
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved3[7]; //
+ AT91_REG DBGU_C1R; // Chip ID1 Register
+ AT91_REG DBGU_C2R; // Chip ID2 Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved4[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+ AT91_REG Reserved5[54]; //
+ AT91_REG PIOA_PER; // PIO Enable Register
+ AT91_REG PIOA_PDR; // PIO Disable Register
+ AT91_REG PIOA_PSR; // PIO Status Register
+ AT91_REG Reserved6[1]; //
+ AT91_REG PIOA_OER; // Output Enable Register
+ AT91_REG PIOA_ODR; // Output Disable Registerr
+ AT91_REG PIOA_OSR; // Output Status Register
+ AT91_REG Reserved7[1]; //
+ AT91_REG PIOA_IFER; // Input Filter Enable Register
+ AT91_REG PIOA_IFDR; // Input Filter Disable Register
+ AT91_REG PIOA_IFSR; // Input Filter Status Register
+ AT91_REG Reserved8[1]; //
+ AT91_REG PIOA_SODR; // Set Output Data Register
+ AT91_REG PIOA_CODR; // Clear Output Data Register
+ AT91_REG PIOA_ODSR; // Output Data Status Register
+ AT91_REG PIOA_PDSR; // Pin Data Status Register
+ AT91_REG PIOA_IER; // Interrupt Enable Register
+ AT91_REG PIOA_IDR; // Interrupt Disable Register
+ AT91_REG PIOA_IMR; // Interrupt Mask Register
+ AT91_REG PIOA_ISR; // Interrupt Status Register
+ AT91_REG PIOA_MDER; // Multi-driver Enable Register
+ AT91_REG PIOA_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOA_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved9[1]; //
+ AT91_REG PIOA_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOA_PPUER; // Pull-up Enable Register
+ AT91_REG PIOA_PPUSR; // Pad Pull-up Status Register
+ AT91_REG Reserved10[1]; //
+ AT91_REG PIOA_ASR; // Select A Register
+ AT91_REG PIOA_BSR; // Select B Register
+ AT91_REG PIOA_ABSR; // AB Select Status Register
+ AT91_REG Reserved11[9]; //
+ AT91_REG PIOA_OWER; // Output Write Enable Register
+ AT91_REG PIOA_OWDR; // Output Write Disable Register
+ AT91_REG PIOA_OWSR; // Output Write Status Register
+ AT91_REG Reserved12[85]; //
+ AT91_REG PIOB_PER; // PIO Enable Register
+ AT91_REG PIOB_PDR; // PIO Disable Register
+ AT91_REG PIOB_PSR; // PIO Status Register
+ AT91_REG Reserved13[1]; //
+ AT91_REG PIOB_OER; // Output Enable Register
+ AT91_REG PIOB_ODR; // Output Disable Registerr
+ AT91_REG PIOB_OSR; // Output Status Register
+ AT91_REG Reserved14[1]; //
+ AT91_REG PIOB_IFER; // Input Filter Enable Register
+ AT91_REG PIOB_IFDR; // Input Filter Disable Register
+ AT91_REG PIOB_IFSR; // Input Filter Status Register
+ AT91_REG Reserved15[1]; //
+ AT91_REG PIOB_SODR; // Set Output Data Register
+ AT91_REG PIOB_CODR; // Clear Output Data Register
+ AT91_REG PIOB_ODSR; // Output Data Status Register
+ AT91_REG PIOB_PDSR; // Pin Data Status Register
+ AT91_REG PIOB_IER; // Interrupt Enable Register
+ AT91_REG PIOB_IDR; // Interrupt Disable Register
+ AT91_REG PIOB_IMR; // Interrupt Mask Register
+ AT91_REG PIOB_ISR; // Interrupt Status Register
+ AT91_REG PIOB_MDER; // Multi-driver Enable Register
+ AT91_REG PIOB_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOB_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved16[1]; //
+ AT91_REG PIOB_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOB_PPUER; // Pull-up Enable Register
+ AT91_REG PIOB_PPUSR; // Pad Pull-up Status Register
+ AT91_REG Reserved17[1]; //
+ AT91_REG PIOB_ASR; // Select A Register
+ AT91_REG PIOB_BSR; // Select B Register
+ AT91_REG PIOB_ABSR; // AB Select Status Register
+ AT91_REG Reserved18[9]; //
+ AT91_REG PIOB_OWER; // Output Write Enable Register
+ AT91_REG PIOB_OWDR; // Output Write Disable Register
+ AT91_REG PIOB_OWSR; // Output Write Status Register
+ AT91_REG Reserved19[85]; //
+ AT91_REG PIOC_PER; // PIO Enable Register
+ AT91_REG PIOC_PDR; // PIO Disable Register
+ AT91_REG PIOC_PSR; // PIO Status Register
+ AT91_REG Reserved20[1]; //
+ AT91_REG PIOC_OER; // Output Enable Register
+ AT91_REG PIOC_ODR; // Output Disable Registerr
+ AT91_REG PIOC_OSR; // Output Status Register
+ AT91_REG Reserved21[1]; //
+ AT91_REG PIOC_IFER; // Input Filter Enable Register
+ AT91_REG PIOC_IFDR; // Input Filter Disable Register
+ AT91_REG PIOC_IFSR; // Input Filter Status Register
+ AT91_REG Reserved22[1]; //
+ AT91_REG PIOC_SODR; // Set Output Data Register
+ AT91_REG PIOC_CODR; // Clear Output Data Register
+ AT91_REG PIOC_ODSR; // Output Data Status Register
+ AT91_REG PIOC_PDSR; // Pin Data Status Register
+ AT91_REG PIOC_IER; // Interrupt Enable Register
+ AT91_REG PIOC_IDR; // Interrupt Disable Register
+ AT91_REG PIOC_IMR; // Interrupt Mask Register
+ AT91_REG PIOC_ISR; // Interrupt Status Register
+ AT91_REG PIOC_MDER; // Multi-driver Enable Register
+ AT91_REG PIOC_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOC_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved23[1]; //
+ AT91_REG PIOC_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOC_PPUER; // Pull-up Enable Register
+ AT91_REG PIOC_PPUSR; // Pad Pull-up Status Register
+ AT91_REG Reserved24[1]; //
+ AT91_REG PIOC_ASR; // Select A Register
+ AT91_REG PIOC_BSR; // Select B Register
+ AT91_REG PIOC_ABSR; // AB Select Status Register
+ AT91_REG Reserved25[9]; //
+ AT91_REG PIOC_OWER; // Output Write Enable Register
+ AT91_REG PIOC_OWDR; // Output Write Disable Register
+ AT91_REG PIOC_OWSR; // Output Write Status Register
+ AT91_REG Reserved26[85]; //
+ AT91_REG PIOD_PER; // PIO Enable Register
+ AT91_REG PIOD_PDR; // PIO Disable Register
+ AT91_REG PIOD_PSR; // PIO Status Register
+ AT91_REG Reserved27[1]; //
+ AT91_REG PIOD_OER; // Output Enable Register
+ AT91_REG PIOD_ODR; // Output Disable Registerr
+ AT91_REG PIOD_OSR; // Output Status Register
+ AT91_REG Reserved28[1]; //
+ AT91_REG PIOD_IFER; // Input Filter Enable Register
+ AT91_REG PIOD_IFDR; // Input Filter Disable Register
+ AT91_REG PIOD_IFSR; // Input Filter Status Register
+ AT91_REG Reserved29[1]; //
+ AT91_REG PIOD_SODR; // Set Output Data Register
+ AT91_REG PIOD_CODR; // Clear Output Data Register
+ AT91_REG PIOD_ODSR; // Output Data Status Register
+ AT91_REG PIOD_PDSR; // Pin Data Status Register
+ AT91_REG PIOD_IER; // Interrupt Enable Register
+ AT91_REG PIOD_IDR; // Interrupt Disable Register
+ AT91_REG PIOD_IMR; // Interrupt Mask Register
+ AT91_REG PIOD_ISR; // Interrupt Status Register
+ AT91_REG PIOD_MDER; // Multi-driver Enable Register
+ AT91_REG PIOD_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOD_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved30[1]; //
+ AT91_REG PIOD_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOD_PPUER; // Pull-up Enable Register
+ AT91_REG PIOD_PPUSR; // Pad Pull-up Status Register
+ AT91_REG Reserved31[1]; //
+ AT91_REG PIOD_ASR; // Select A Register
+ AT91_REG PIOD_BSR; // Select B Register
+ AT91_REG PIOD_ABSR; // AB Select Status Register
+ AT91_REG Reserved32[9]; //
+ AT91_REG PIOD_OWER; // Output Write Enable Register
+ AT91_REG PIOD_OWDR; // Output Write Disable Register
+ AT91_REG PIOD_OWSR; // Output Write Status Register
+ AT91_REG Reserved33[85]; //
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved34[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved35[1]; //
+ AT91_REG CKGR_MOR; // Main Oscillator Register
+ AT91_REG CKGR_MCFR; // Main Clock Frequency Register
+ AT91_REG CKGR_PLLAR; // PLL A Register
+ AT91_REG CKGR_PLLBR; // PLL B Register
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved36[3]; //
+ AT91_REG PMC_PCKR[8]; // Programmable Clock Register
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved37[36]; //
+ AT91_REG ST_CR; // Control Register
+ AT91_REG ST_PIMR; // Period Interval Mode Register
+ AT91_REG ST_WDMR; // Watchdog Mode Register
+ AT91_REG ST_RTMR; // Real-time Mode Register
+ AT91_REG ST_SR; // Status Register
+ AT91_REG ST_IER; // Interrupt Enable Register
+ AT91_REG ST_IDR; // Interrupt Disable Register
+ AT91_REG ST_IMR; // Interrupt Mask Register
+ AT91_REG ST_RTAR; // Real-time Alarm Register
+ AT91_REG ST_CRTR; // Current Real-time Register
+ AT91_REG Reserved38[54]; //
+ AT91_REG RTC_CR; // Control Register
+ AT91_REG RTC_MR; // Mode Register
+ AT91_REG RTC_TIMR; // Time Register
+ AT91_REG RTC_CALR; // Calendar Register
+ AT91_REG RTC_TIMALR; // Time Alarm Register
+ AT91_REG RTC_CALALR; // Calendar Alarm Register
+ AT91_REG RTC_SR; // Status Register
+ AT91_REG RTC_SCCR; // Status Clear Command Register
+ AT91_REG RTC_IER; // Interrupt Enable Register
+ AT91_REG RTC_IDR; // Interrupt Disable Register
+ AT91_REG RTC_IMR; // Interrupt Mask Register
+ AT91_REG RTC_VER; // Valid Entry Register
+ AT91_REG Reserved39[52]; //
+ AT91_REG MC_RCR; // MC Remap Control Register
+ AT91_REG MC_ASR; // MC Abort Status Register
+ AT91_REG MC_AASR; // MC Abort Address Status Register
+ AT91_REG Reserved40[1]; //
+ AT91_REG MC_PUIA[16]; // MC Protection Unit Area
+ AT91_REG MC_PUP; // MC Protection Unit Peripherals
+ AT91_REG MC_PUER; // MC Protection Unit Enable Register
+ AT91_REG Reserved41[2]; //
+ AT91_REG EBI_CSA; // Chip Select Assignment Register
+ AT91_REG EBI_CFGR; // Configuration Register
+ AT91_REG Reserved42[2]; //
+ AT91_REG EBI_SMC2_CSR[8]; // SMC2 Chip Select Register
+ AT91_REG EBI_SDRC_MR; // SDRAM Controller Mode Register
+ AT91_REG EBI_SDRC_TR; // SDRAM Controller Refresh Timer Register
+ AT91_REG EBI_SDRC_CR; // SDRAM Controller Configuration Register
+ AT91_REG EBI_SDRC_SRR; // SDRAM Controller Self Refresh Register
+ AT91_REG EBI_SDRC_LPR; // SDRAM Controller Low Power Register
+ AT91_REG EBI_SDRC_IER; // SDRAM Controller Interrupt Enable Register
+ AT91_REG EBI_SDRC_IDR; // SDRAM Controller Interrupt Disable Register
+ AT91_REG EBI_SDRC_IMR; // SDRAM Controller Interrupt Mask Register
+ AT91_REG EBI_SDRC_ISR; // SDRAM Controller Interrupt Mask Register
+ AT91_REG Reserved43[3]; //
+ AT91_REG EBI_BFC_MR; // BFC Mode Register
+} AT91S_SYS, *AT91PS_SYS;
+
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Memory Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_MC {
+ AT91_REG MC_RCR; // MC Remap Control Register
+ AT91_REG MC_ASR; // MC Abort Status Register
+ AT91_REG MC_AASR; // MC Abort Address Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG MC_PUIA[16]; // MC Protection Unit Area
+ AT91_REG MC_PUP; // MC Protection Unit Peripherals
+ AT91_REG MC_PUER; // MC Protection Unit Enable Register
+} AT91S_MC, *AT91PS_MC;
+
+// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register --------
+#define AT91C_MC_RCB (0x1u << 0) // (MC) Remap Command Bit
+// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register --------
+#define AT91C_MC_UNDADD (0x1u << 0) // (MC) Undefined Addess Abort Status
+#define AT91C_MC_MISADD (0x1u << 1) // (MC) Misaligned Addess Abort Status
+#define AT91C_MC_MPU (0x1u << 2) // (MC) Memory protection Unit Abort Status
+#define AT91C_MC_ABTSZ (0x3u << 8) // (MC) Abort Size Status
+#define AT91C_MC_ABTSZ_BYTE (0x0u << 8) // (MC) Byte
+#define AT91C_MC_ABTSZ_HWORD (0x1u << 8) // (MC) Half-word
+#define AT91C_MC_ABTSZ_WORD (0x2u << 8) // (MC) Word
+#define AT91C_MC_ABTTYP (0x3u << 10) // (MC) Abort Type Status
+#define AT91C_MC_ABTTYP_DATAR (0x0u << 10) // (MC) Data Read
+#define AT91C_MC_ABTTYP_DATAW (0x1u << 10) // (MC) Data Write
+#define AT91C_MC_ABTTYP_FETCH (0x2u << 10) // (MC) Code Fetch
+#define AT91C_MC_MST0 (0x1u << 16) // (MC) Master 0 Abort Source
+#define AT91C_MC_MST1 (0x1u << 17) // (MC) Master 1 Abort Source
+#define AT91C_MC_SVMST0 (0x1u << 24) // (MC) Saved Master 0 Abort Source
+#define AT91C_MC_SVMST1 (0x1u << 25) // (MC) Saved Master 1 Abort Source
+// -------- MC_PUIA : (MC Offset: 0x10) MC Protection Unit Area --------
+#define AT91C_MC_PROT (0x3u << 0) // (MC) Protection
+#define AT91C_MC_PROT_PNAUNA 0x0u // (MC) Privilege: No Access, User: No Access
+#define AT91C_MC_PROT_PRWUNA 0x1u // (MC) Privilege: Read/Write, User: No Access
+#define AT91C_MC_PROT_PRWURO 0x2u // (MC) Privilege: Read/Write, User: Read Only
+#define AT91C_MC_PROT_PRWURW 0x3u // (MC) Privilege: Read/Write, User: Read/Write
+#define AT91C_MC_SIZE (0xFu << 4) // (MC) Internal Area Size
+#define AT91C_MC_SIZE_1KB (0x0u << 4) // (MC) Area size 1KByte
+#define AT91C_MC_SIZE_2KB (0x1u << 4) // (MC) Area size 2KByte
+#define AT91C_MC_SIZE_4KB (0x2u << 4) // (MC) Area size 4KByte
+#define AT91C_MC_SIZE_8KB (0x3u << 4) // (MC) Area size 8KByte
+#define AT91C_MC_SIZE_16KB (0x4u << 4) // (MC) Area size 16KByte
+#define AT91C_MC_SIZE_32KB (0x5u << 4) // (MC) Area size 32KByte
+#define AT91C_MC_SIZE_64KB (0x6u << 4) // (MC) Area size 64KByte
+#define AT91C_MC_SIZE_128KB (0x7u << 4) // (MC) Area size 128KByte
+#define AT91C_MC_SIZE_256KB (0x8u << 4) // (MC) Area size 256KByte
+#define AT91C_MC_SIZE_512KB (0x9u << 4) // (MC) Area size 512KByte
+#define AT91C_MC_SIZE_1MB (0xAu << 4) // (MC) Area size 1MByte
+#define AT91C_MC_SIZE_2MB (0xBu << 4) // (MC) Area size 2MByte
+#define AT91C_MC_SIZE_4MB (0xCu << 4) // (MC) Area size 4MByte
+#define AT91C_MC_SIZE_8MB (0xDu << 4) // (MC) Area size 8MByte
+#define AT91C_MC_SIZE_16MB (0xEu << 4) // (MC) Area size 16MByte
+#define AT91C_MC_SIZE_64MB (0xFu << 4) // (MC) Area size 64MByte
+#define AT91C_MC_BA (0x3FFFFu << 10) // (MC) Internal Area Base Address
+// -------- MC_PUP : (MC Offset: 0x50) MC Protection Unit Peripheral --------
+// -------- MC_PUER : (MC Offset: 0x54) MC Protection Unit Area --------
+#define AT91C_MC_PUEB (0x1u << 0) // (MC) Protection Unit enable Bit
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Real-time Clock Alarm and Parallel Load Interface
+// *****************************************************************************
+typedef struct _AT91S_RTC {
+ AT91_REG RTC_CR; // Control Register
+ AT91_REG RTC_MR; // Mode Register
+ AT91_REG RTC_TIMR; // Time Register
+ AT91_REG RTC_CALR; // Calendar Register
+ AT91_REG RTC_TIMALR; // Time Alarm Register
+ AT91_REG RTC_CALALR; // Calendar Alarm Register
+ AT91_REG RTC_SR; // Status Register
+ AT91_REG RTC_SCCR; // Status Clear Command Register
+ AT91_REG RTC_IER; // Interrupt Enable Register
+ AT91_REG RTC_IDR; // Interrupt Disable Register
+ AT91_REG RTC_IMR; // Interrupt Mask Register
+ AT91_REG RTC_VER; // Valid Entry Register
+} AT91S_RTC, *AT91PS_RTC;
+
+// -------- RTC_CR : (RTC Offset: 0x0) RTC Control Register --------
+#define AT91C_RTC_UPDTIM (0x1u << 0) // (RTC) Update Request Time Register
+#define AT91C_RTC_UPDCAL (0x1u << 1) // (RTC) Update Request Calendar Register
+#define AT91C_RTC_TIMEVSEL (0x3u << 8) // (RTC) Time Event Selection
+#define AT91C_RTC_TIMEVSEL_MINUTE (0x0u << 8) // (RTC) Minute change.
+#define AT91C_RTC_TIMEVSEL_HOUR (0x1u << 8) // (RTC) Hour change.
+#define AT91C_RTC_TIMEVSEL_DAY24 (0x2u << 8) // (RTC) Every day at midnight.
+#define AT91C_RTC_TIMEVSEL_DAY12 (0x3u << 8) // (RTC) Every day at noon.
+#define AT91C_RTC_CALEVSEL (0x3u << 16) // (RTC) Calendar Event Selection
+#define AT91C_RTC_CALEVSEL_WEEK (0x0u << 16) // (RTC) Week change (every Monday at time 00:00:00).
+#define AT91C_RTC_CALEVSEL_MONTH (0x1u << 16) // (RTC) Month change (every 01 of each month at time 00:00:00).
+#define AT91C_RTC_CALEVSEL_YEAR (0x2u << 16) // (RTC) Year change (every January 1 at time 00:00:00).
+// -------- RTC_MR : (RTC Offset: 0x4) RTC Mode Register --------
+#define AT91C_RTC_HRMOD (0x1u << 0) // (RTC) 12-24 hour Mode
+// -------- RTC_TIMR : (RTC Offset: 0x8) RTC Time Register --------
+#define AT91C_RTC_SEC (0x7Fu << 0) // (RTC) Current Second
+#define AT91C_RTC_MIN (0x7Fu << 8) // (RTC) Current Minute
+#define AT91C_RTC_HOUR (0x1Fu << 16) // (RTC) Current Hour
+#define AT91C_RTC_AMPM (0x1u << 22) // (RTC) Ante Meridiem, Post Meridiem Indicator
+// -------- RTC_CALR : (RTC Offset: 0xc) RTC Calendar Register --------
+#define AT91C_RTC_CENT (0x3Fu << 0) // (RTC) Current Century
+#define AT91C_RTC_YEAR (0xFFu << 8) // (RTC) Current Year
+#define AT91C_RTC_MONTH (0x1Fu << 16) // (RTC) Current Month
+#define AT91C_RTC_DAY (0x7u << 21) // (RTC) Current Day
+#define AT91C_RTC_DATE (0x3Fu << 24) // (RTC) Current Date
+// -------- RTC_TIMALR : (RTC Offset: 0x10) RTC Time Alarm Register --------
+#define AT91C_RTC_SECEN (0x1u << 7) // (RTC) Second Alarm Enable
+#define AT91C_RTC_MINEN (0x1u << 15) // (RTC) Minute Alarm
+#define AT91C_RTC_HOUREN (0x1u << 23) // (RTC) Current Hour
+// -------- RTC_CALALR : (RTC Offset: 0x14) RTC Calendar Alarm Register --------
+#define AT91C_RTC_MONTHEN (0x1u << 23) // (RTC) Month Alarm Enable
+#define AT91C_RTC_DATEEN (0x1u << 31) // (RTC) Date Alarm Enable
+// -------- RTC_SR : (RTC Offset: 0x18) RTC Status Register --------
+#define AT91C_RTC_ACKUPD (0x1u << 0) // (RTC) Acknowledge for Update
+#define AT91C_RTC_ALARM (0x1u << 1) // (RTC) Alarm Flag
+#define AT91C_RTC_SECEV (0x1u << 2) // (RTC) Second Event
+#define AT91C_RTC_TIMEV (0x1u << 3) // (RTC) Time Event
+#define AT91C_RTC_CALEV (0x1u << 4) // (RTC) Calendar event
+// -------- RTC_SCCR : (RTC Offset: 0x1c) RTC Status Clear Command Register --------
+// -------- RTC_IER : (RTC Offset: 0x20) RTC Interrupt Enable Register --------
+// -------- RTC_IDR : (RTC Offset: 0x24) RTC Interrupt Disable Register --------
+// -------- RTC_IMR : (RTC Offset: 0x28) RTC Interrupt Mask Register --------
+// -------- RTC_VER : (RTC Offset: 0x2c) RTC Valid Entry Register --------
+#define AT91C_RTC_NVTIM (0x1u << 0) // (RTC) Non valid Time
+#define AT91C_RTC_NVCAL (0x1u << 1) // (RTC) Non valid Calendar
+#define AT91C_RTC_NVTIMALR (0x1u << 2) // (RTC) Non valid time Alarm
+#define AT91C_RTC_NVCALALR (0x1u << 3) // (RTC) Nonvalid Calendar Alarm
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR System Timer Interface
+// *****************************************************************************
+typedef struct _AT91S_ST {
+ AT91_REG ST_CR; // Control Register
+ AT91_REG ST_PIMR; // Period Interval Mode Register
+ AT91_REG ST_WDMR; // Watchdog Mode Register
+ AT91_REG ST_RTMR; // Real-time Mode Register
+ AT91_REG ST_SR; // Status Register
+ AT91_REG ST_IER; // Interrupt Enable Register
+ AT91_REG ST_IDR; // Interrupt Disable Register
+ AT91_REG ST_IMR; // Interrupt Mask Register
+ AT91_REG ST_RTAR; // Real-time Alarm Register
+ AT91_REG ST_CRTR; // Current Real-time Register
+} AT91S_ST, *AT91PS_ST;
+
+// -------- ST_CR : (ST Offset: 0x0) System Timer Control Register --------
+#define AT91C_ST_WDRST (0x1u << 0) // (ST) Watchdog Timer Restart
+// -------- ST_PIMR : (ST Offset: 0x4) System Timer Period Interval Mode Register --------
+#define AT91C_ST_PIV (0xFFFFu << 0) // (ST) Watchdog Timer Restart
+// -------- ST_WDMR : (ST Offset: 0x8) System Timer Watchdog Mode Register --------
+#define AT91C_ST_WDV (0xFFFFu << 0) // (ST) Watchdog Timer Restart
+#define AT91C_ST_RSTEN (0x1u << 16) // (ST) Reset Enable
+#define AT91C_ST_EXTEN (0x1u << 17) // (ST) External Signal Assertion Enable
+// -------- ST_RTMR : (ST Offset: 0xc) System Timer Real-time Mode Register --------
+#define AT91C_ST_RTPRES (0xFFFFu << 0) // (ST) Real-time Timer Prescaler Value
+// -------- ST_SR : (ST Offset: 0x10) System Timer Status Register --------
+#define AT91C_ST_PITS (0x1u << 0) // (ST) Period Interval Timer Interrupt
+#define AT91C_ST_WDOVF (0x1u << 1) // (ST) Watchdog Overflow
+#define AT91C_ST_RTTINC (0x1u << 2) // (ST) Real-time Timer Increment
+#define AT91C_ST_ALMS (0x1u << 3) // (ST) Alarm Status
+// -------- ST_IER : (ST Offset: 0x14) System Timer Interrupt Enable Register --------
+// -------- ST_IDR : (ST Offset: 0x18) System Timer Interrupt Disable Register --------
+// -------- ST_IMR : (ST Offset: 0x1c) System Timer Interrupt Mask Register --------
+// -------- ST_RTAR : (ST Offset: 0x20) System Timer Real-time Alarm Register --------
+#define AT91C_ST_ALMV (0xFFFFFu << 0) // (ST) Alarm Value Value
+// -------- ST_CRTR : (ST Offset: 0x24) System Timer Current Real-time Register --------
+#define AT91C_ST_CRTV (0xFFFFFu << 0) // (ST) Current Real-time Value
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Power Management Controler
+// *****************************************************************************
+typedef struct _AT91S_PMC {
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved1[5]; //
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved2[3]; //
+ AT91_REG PMC_PCKR[8]; // Programmable Clock Register
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+} AT91S_PMC, *AT91PS_PMC;
+
+// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register --------
+#define AT91C_PMC_PCK (0x1u << 0) // (PMC) Processor Clock
+#define AT91C_PMC_UDP (0x1u << 1) // (PMC) USB Device Port Clock
+#define AT91C_PMC_MCKUDP (0x1u << 2) // (PMC) USB Device Port Master Clock Automatic Disable on Suspend
+#define AT91C_PMC_UHP (0x1u << 4) // (PMC) USB Host Port Clock
+#define AT91C_PMC_PCK0 (0x1u << 8) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK1 (0x1u << 9) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK2 (0x1u << 10) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK3 (0x1u << 11) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK4 (0x1u << 12) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK5 (0x1u << 13) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK6 (0x1u << 14) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK7 (0x1u << 15) // (PMC) Programmable Clock Output
+// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register --------
+// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register --------
+// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register --------
+#define AT91C_PMC_CSS (0x3u << 0) // (PMC) Programmable Clock Selection
+#define AT91C_PMC_CSS_SLOW_CLK 0x0u // (PMC) Slow Clock is selected
+#define AT91C_PMC_CSS_MAIN_CLK 0x1u // (PMC) Main Clock is selected
+#define AT91C_PMC_CSS_PLLA_CLK 0x2u // (PMC) Clock from PLL A is selected
+#define AT91C_PMC_CSS_PLLB_CLK 0x3u // (PMC) Clock from PLL B is selected
+#define AT91C_PMC_PRES (0x7u << 2) // (PMC) Programmable Clock Prescaler
+#define AT91C_PMC_PRES_CLK (0x0u << 2) // (PMC) Selected clock
+#define AT91C_PMC_PRES_CLK_2 (0x1u << 2) // (PMC) Selected clock divided by 2
+#define AT91C_PMC_PRES_CLK_4 (0x2u << 2) // (PMC) Selected clock divided by 4
+#define AT91C_PMC_PRES_CLK_8 (0x3u << 2) // (PMC) Selected clock divided by 8
+#define AT91C_PMC_PRES_CLK_16 (0x4u << 2) // (PMC) Selected clock divided by 16
+#define AT91C_PMC_PRES_CLK_32 (0x5u << 2) // (PMC) Selected clock divided by 32
+#define AT91C_PMC_PRES_CLK_64 (0x6u << 2) // (PMC) Selected clock divided by 64
+#define AT91C_PMC_MDIV (0x3u << 8) // (PMC) Master Clock Division
+#define AT91C_PMC_MDIV_1 (0x0u << 8) // (PMC) The master clock and the processor clock are the same
+#define AT91C_PMC_MDIV_2 (0x1u << 8) // (PMC) The processor clock is twice as fast as the master clock
+#define AT91C_PMC_MDIV_3 (0x2u << 8) // (PMC) The processor clock is three times faster than the master clock
+#define AT91C_PMC_MDIV_4 (0x3u << 8) // (PMC) The processor clock is four times faster than the master clock
+// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register --------
+// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register --------
+#define AT91C_PMC_MOSCS (0x1u << 0) // (PMC) MOSC Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCKA (0x1u << 1) // (PMC) PLL A Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCKB (0x1u << 2) // (PMC) PLL B Status/Enable/Disable/Mask
+#define AT91C_PMC_MCKRDY (0x1u << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK0RDY (0x1u << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK1RDY (0x1u << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK2RDY (0x1u << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK3RDY (0x1u << 11) // (PMC) PCK3_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK4RDY (0x1u << 12) // (PMC) PCK4_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK5RDY (0x1u << 13) // (PMC) PCK5_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK6RDY (0x1u << 14) // (PMC) PCK6_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK7RDY (0x1u << 15) // (PMC) PCK7_RDY Status/Enable/Disable/Mask
+// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register --------
+// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register --------
+// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Clock Generator Controler
+// *****************************************************************************
+typedef struct _AT91S_CKGR {
+ AT91_REG CKGR_MOR; // Main Oscillator Register
+ AT91_REG CKGR_MCFR; // Main Clock Frequency Register
+ AT91_REG CKGR_PLLAR; // PLL A Register
+ AT91_REG CKGR_PLLBR; // PLL B Register
+} AT91S_CKGR, *AT91PS_CKGR;
+
+// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register --------
+#define AT91C_CKGR_MOSCEN (0x1u << 0) // (CKGR) Main Oscillator Enable
+#define AT91C_CKGR_OSCTEST (0x1u << 1) // (CKGR) Oscillator Test
+#define AT91C_CKGR_OSCOUNT (0xFFu << 8) // (CKGR) Main Oscillator Start-up Time
+// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register --------
+#define AT91C_CKGR_MAINF (0xFFFFu << 0) // (CKGR) Main Clock Frequency
+#define AT91C_CKGR_MAINRDY (0x1u << 16) // (CKGR) Main Clock Ready
+// -------- CKGR_PLLAR : (CKGR Offset: 0x8) PLL A Register --------
+#define AT91C_CKGR_DIVA (0xFFu << 0) // (CKGR) Divider Selected
+#define AT91C_CKGR_DIVA_0 0x0u // (CKGR) Divider output is 0
+#define AT91C_CKGR_DIVA_BYPASS 0x1u // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLACOUNT (0x3Fu << 8) // (CKGR) PLL A Counter
+#define AT91C_CKGR_OUTA (0x3u << 14) // (CKGR) PLL A Output Frequency Range
+#define AT91C_CKGR_OUTA_0 (0x0u << 14) // (CKGR) Please refer to the PLLA datasheet
+#define AT91C_CKGR_OUTA_1 (0x1u << 14) // (CKGR) Please refer to the PLLA datasheet
+#define AT91C_CKGR_OUTA_2 (0x2u << 14) // (CKGR) Please refer to the PLLA datasheet
+#define AT91C_CKGR_OUTA_3 (0x3u << 14) // (CKGR) Please refer to the PLLA datasheet
+#define AT91C_CKGR_MULA (0x7FFu << 16) // (CKGR) PLL A Multiplier
+#define AT91C_CKGR_SRCA (0x1u << 29) // (CKGR) PLL A Source
+// -------- CKGR_PLLBR : (CKGR Offset: 0xc) PLL B Register --------
+#define AT91C_CKGR_DIVB (0xFFu << 0) // (CKGR) Divider Selected
+#define AT91C_CKGR_DIVB_0 0x0u // (CKGR) Divider output is 0
+#define AT91C_CKGR_DIVB_BYPASS 0x1u // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLBCOUNT (0x3Fu << 8) // (CKGR) PLL B Counter
+#define AT91C_CKGR_OUTB (0x3u << 14) // (CKGR) PLL B Output Frequency Range
+#define AT91C_CKGR_OUTB_0 (0x0u << 14) // (CKGR) Please refer to the PLLB datasheet
+#define AT91C_CKGR_OUTB_1 (0x1u << 14) // (CKGR) Please refer to the PLLB datasheet
+#define AT91C_CKGR_OUTB_2 (0x2u << 14) // (CKGR) Please refer to the PLLB datasheet
+#define AT91C_CKGR_OUTB_3 (0x3u << 14) // (CKGR) Please refer to the PLLB datasheet
+#define AT91C_CKGR_MULB (0x7FFu << 16) // (CKGR) PLL B Multiplier
+#define AT91C_CKGR_USB_96M (0x1u << 28) // (CKGR) Divider for USB Ports
+#define AT91C_CKGR_USB_PLL (0x1u << 29) // (CKGR) PLL Use
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Parallel Input Output Controler
+// *****************************************************************************
+typedef struct _AT91S_PIO {
+ AT91_REG PIO_PER; // PIO Enable Register
+ AT91_REG PIO_PDR; // PIO Disable Register
+ AT91_REG PIO_PSR; // PIO Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PIO_OER; // Output Enable Register
+ AT91_REG PIO_ODR; // Output Disable Registerr
+ AT91_REG PIO_OSR; // Output Status Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG PIO_IFER; // Input Filter Enable Register
+ AT91_REG PIO_IFDR; // Input Filter Disable Register
+ AT91_REG PIO_IFSR; // Input Filter Status Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG PIO_SODR; // Set Output Data Register
+ AT91_REG PIO_CODR; // Clear Output Data Register
+ AT91_REG PIO_ODSR; // Output Data Status Register
+ AT91_REG PIO_PDSR; // Pin Data Status Register
+ AT91_REG PIO_IER; // Interrupt Enable Register
+ AT91_REG PIO_IDR; // Interrupt Disable Register
+ AT91_REG PIO_IMR; // Interrupt Mask Register
+ AT91_REG PIO_ISR; // Interrupt Status Register
+ AT91_REG PIO_MDER; // Multi-driver Enable Register
+ AT91_REG PIO_MDDR; // Multi-driver Disable Register
+ AT91_REG PIO_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved3[1]; //
+ AT91_REG PIO_PPUDR; // Pull-up Disable Register
+ AT91_REG PIO_PPUER; // Pull-up Enable Register
+ AT91_REG PIO_PPUSR; // Pad Pull-up Status Register
+ AT91_REG Reserved4[1]; //
+ AT91_REG PIO_ASR; // Select A Register
+ AT91_REG PIO_BSR; // Select B Register
+ AT91_REG PIO_ABSR; // AB Select Status Register
+ AT91_REG Reserved5[9]; //
+ AT91_REG PIO_OWER; // Output Write Enable Register
+ AT91_REG PIO_OWDR; // Output Write Disable Register
+ AT91_REG PIO_OWSR; // Output Write Status Register
+} AT91S_PIO, *AT91PS_PIO;
+
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Debug Unit
+// *****************************************************************************
+typedef struct _AT91S_DBGU {
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved0[7]; //
+ AT91_REG DBGU_C1R; // Chip ID1 Register
+ AT91_REG DBGU_C2R; // Chip ID2 Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved1[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+} AT91S_DBGU, *AT91PS_DBGU;
+
+// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_RSTRX (0x1u << 2) // (DBGU) Reset Receiver
+#define AT91C_US_RSTTX (0x1u << 3) // (DBGU) Reset Transmitter
+#define AT91C_US_RXEN (0x1u << 4) // (DBGU) Receiver Enable
+#define AT91C_US_RXDIS (0x1u << 5) // (DBGU) Receiver Disable
+#define AT91C_US_TXEN (0x1u << 6) // (DBGU) Transmitter Enable
+#define AT91C_US_TXDIS (0x1u << 7) // (DBGU) Transmitter Disable
+// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_PAR (0x7u << 9) // (DBGU) Parity type
+#define AT91C_US_PAR_EVEN (0x0u << 9) // (DBGU) Even Parity
+#define AT91C_US_PAR_ODD (0x1u << 9) // (DBGU) Odd Parity
+#define AT91C_US_PAR_SPACE (0x2u << 9) // (DBGU) Parity forced to 0 (Space)
+#define AT91C_US_PAR_MARK (0x3u << 9) // (DBGU) Parity forced to 1 (Mark)
+#define AT91C_US_PAR_NONE (0x4u << 9) // (DBGU) No Parity
+#define AT91C_US_PAR_MULTI_DROP (0x6u << 9) // (DBGU) Multi-drop mode
+#define AT91C_US_CHMODE (0x3u << 14) // (DBGU) Channel Mode
+#define AT91C_US_CHMODE_NORMAL (0x0u << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART.
+#define AT91C_US_CHMODE_AUTO (0x1u << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin.
+#define AT91C_US_CHMODE_LOCAL (0x2u << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal.
+#define AT91C_US_CHMODE_REMOTE (0x3u << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin.
+// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXRDY (0x1u << 0) // (DBGU) RXRDY Interrupt
+#define AT91C_US_TXRDY (0x1u << 1) // (DBGU) TXRDY Interrupt
+#define AT91C_US_ENDRX (0x1u << 3) // (DBGU) End of Receive Transfer Interrupt
+#define AT91C_US_ENDTX (0x1u << 4) // (DBGU) End of Transmit Interrupt
+#define AT91C_US_OVRE (0x1u << 5) // (DBGU) Overrun Interrupt
+#define AT91C_US_FRAME (0x1u << 6) // (DBGU) Framing Error Interrupt
+#define AT91C_US_PARE (0x1u << 7) // (DBGU) Parity Error Interrupt
+#define AT91C_US_TXEMPTY (0x1u << 9) // (DBGU) TXEMPTY Interrupt
+#define AT91C_US_TXBUFE (0x1u << 11) // (DBGU) TXBUFE Interrupt
+#define AT91C_US_RXBUFF (0x1u << 12) // (DBGU) RXBUFF Interrupt
+#define AT91C_US_COMM_TX (0x1u << 30) // (DBGU) COMM_TX Interrupt
+#define AT91C_US_COMM_RX (0x1u << 31) // (DBGU) COMM_RX Interrupt
+// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register --------
+// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register --------
+#define AT91C_US_FORCE_NTRST (0x1u << 0) // (DBGU) Force NTRST in JTAG
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Peripheral Data Controller
+// *****************************************************************************
+typedef struct _AT91S_PDC {
+ AT91_REG PDC_RPR; // Receive Pointer Register
+ AT91_REG PDC_RCR; // Receive Counter Register
+ AT91_REG PDC_TPR; // Transmit Pointer Register
+ AT91_REG PDC_TCR; // Transmit Counter Register
+ AT91_REG PDC_RNPR; // Receive Next Pointer Register
+ AT91_REG PDC_RNCR; // Receive Next Counter Register
+ AT91_REG PDC_TNPR; // Transmit Next Pointer Register
+ AT91_REG PDC_TNCR; // Transmit Next Counter Register
+ AT91_REG PDC_PTCR; // PDC Transfer Control Register
+ AT91_REG PDC_PTSR; // PDC Transfer Status Register
+} AT91S_PDC, *AT91PS_PDC;
+
+// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register --------
+#define AT91C_PDC_RXTEN (0x1u << 0) // (PDC) Receiver Transfer Enable
+#define AT91C_PDC_RXTDIS (0x1u << 1) // (PDC) Receiver Transfer Disable
+#define AT91C_PDC_TXTEN (0x1u << 8) // (PDC) Transmitter Transfer Enable
+#define AT91C_PDC_TXTDIS (0x1u << 9) // (PDC) Transmitter Transfer Disable
+// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller
+// *****************************************************************************
+typedef struct _AT91S_AIC {
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+} AT91S_AIC, *AT91PS_AIC;
+
+// -------- AIC_SMR : (AIC Offset: 0x0) Control Register --------
+#define AT91C_AIC_PRIOR (0x7u << 0) // (AIC) Priority Level
+#define AT91C_AIC_PRIOR_LOWEST 0x0u // (AIC) Lowest priority level
+#define AT91C_AIC_PRIOR_HIGHEST 0x7u // (AIC) Highest priority level
+#define AT91C_AIC_SRCTYPE (0x3u << 5) // (AIC) Interrupt Source Type
+#define AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE (0x0u << 5) // (AIC) Internal Sources Code Label Level Sensitive
+#define AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED (0x1u << 5) // (AIC) Internal Sources Code Label Edge triggered
+#define AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL (0x2u << 5) // (AIC) External Sources Code Label High-level Sensitive
+#define AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE (0x3u << 5) // (AIC) External Sources Code Label Positive Edge triggered
+// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register --------
+#define AT91C_AIC_NFIQ (0x1u << 0) // (AIC) NFIQ Status
+#define AT91C_AIC_NIRQ (0x1u << 1) // (AIC) NIRQ Status
+// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) --------
+#define AT91C_AIC_DCR_PROT (0x1u << 0) // (AIC) Protection Mode
+#define AT91C_AIC_DCR_GMSK (0x1u << 1) // (AIC) General Mask
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Serial Parallel Interface
+// *****************************************************************************
+typedef struct _AT91S_SPI {
+ AT91_REG SPI_CR; // Control Register
+ AT91_REG SPI_MR; // Mode Register
+ AT91_REG SPI_RDR; // Receive Data Register
+ AT91_REG SPI_TDR; // Transmit Data Register
+ AT91_REG SPI_SR; // Status Register
+ AT91_REG SPI_IER; // Interrupt Enable Register
+ AT91_REG SPI_IDR; // Interrupt Disable Register
+ AT91_REG SPI_IMR; // Interrupt Mask Register
+ AT91_REG Reserved0[4]; //
+ AT91_REG SPI_CSR[4]; // Chip Select Register
+ AT91_REG Reserved1[48]; //
+ AT91_REG SPI_RPR; // Receive Pointer Register
+ AT91_REG SPI_RCR; // Receive Counter Register
+ AT91_REG SPI_TPR; // Transmit Pointer Register
+ AT91_REG SPI_TCR; // Transmit Counter Register
+ AT91_REG SPI_RNPR; // Receive Next Pointer Register
+ AT91_REG SPI_RNCR; // Receive Next Counter Register
+ AT91_REG SPI_TNPR; // Transmit Next Pointer Register
+ AT91_REG SPI_TNCR; // Transmit Next Counter Register
+ AT91_REG SPI_PTCR; // PDC Transfer Control Register
+ AT91_REG SPI_PTSR; // PDC Transfer Status Register
+} AT91S_SPI, *AT91PS_SPI;
+
+// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register --------
+#define AT91C_SPI_SPIEN (0x1u << 0) // (SPI) SPI Enable
+#define AT91C_SPI_SPIDIS (0x1u << 1) // (SPI) SPI Disable
+#define AT91C_SPI_SWRST (0x1u << 7) // (SPI) SPI Software reset
+// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register --------
+#define AT91C_SPI_MSTR (0x1u << 0) // (SPI) Master/Slave Mode
+#define AT91C_SPI_PS (0x1u << 1) // (SPI) Peripheral Select
+#define AT91C_SPI_PS_FIXED (0x0u << 1) // (SPI) Fixed Peripheral Select
+#define AT91C_SPI_PS_VARIABLE (0x1u << 1) // (SPI) Variable Peripheral Select
+#define AT91C_SPI_PCSDEC (0x1u << 2) // (SPI) Chip Select Decode
+#define AT91C_SPI_DIV32 (0x1u << 3) // (SPI) Clock Selection
+#define AT91C_SPI_MODFDIS (0x1u << 4) // (SPI) Mode Fault Detection
+#define AT91C_SPI_LLB (0x1u << 7) // (SPI) Clock Selection
+#define AT91C_SPI_PCS (0xFu << 16) // (SPI) Peripheral Chip Select
+#define AT91C_SPI_DLYBCS (0xFFu << 24) // (SPI) Delay Between Chip Selects
+// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register --------
+#define AT91C_SPI_RD (0xFFFFu << 0) // (SPI) Receive Data
+#define AT91C_SPI_RPCS (0xFu << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register --------
+#define AT91C_SPI_TD (0xFFFFu << 0) // (SPI) Transmit Data
+#define AT91C_SPI_TPCS (0xFu << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_SR : (SPI Offset: 0x10) Status Register --------
+#define AT91C_SPI_RDRF (0x1u << 0) // (SPI) Receive Data Register Full
+#define AT91C_SPI_TDRE (0x1u << 1) // (SPI) Transmit Data Register Empty
+#define AT91C_SPI_MODF (0x1u << 2) // (SPI) Mode Fault Error
+#define AT91C_SPI_OVRES (0x1u << 3) // (SPI) Overrun Error Status
+#define AT91C_SPI_SPENDRX (0x1u << 4) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_SPENDTX (0x1u << 5) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_RXBUFF (0x1u << 6) // (SPI) RXBUFF Interrupt
+#define AT91C_SPI_TXBUFE (0x1u << 7) // (SPI) TXBUFE Interrupt
+#define AT91C_SPI_SPIENS (0x1u << 16) // (SPI) Enable Status
+// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register --------
+// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register --------
+// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register --------
+// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register --------
+#define AT91C_SPI_CPOL (0x1u << 0) // (SPI) Clock Polarity
+#define AT91C_SPI_NCPHA (0x1u << 1) // (SPI) Clock Phase
+#define AT91C_SPI_BITS (0xFu << 4) // (SPI) Bits Per Transfer
+#define AT91C_SPI_BITS_8 (0x0u << 4) // (SPI) 8 Bits Per transfer
+#define AT91C_SPI_BITS_9 (0x1u << 4) // (SPI) 9 Bits Per transfer
+#define AT91C_SPI_BITS_10 (0x2u << 4) // (SPI) 10 Bits Per transfer
+#define AT91C_SPI_BITS_11 (0x3u << 4) // (SPI) 11 Bits Per transfer
+#define AT91C_SPI_BITS_12 (0x4u << 4) // (SPI) 12 Bits Per transfer
+#define AT91C_SPI_BITS_13 (0x5u << 4) // (SPI) 13 Bits Per transfer
+#define AT91C_SPI_BITS_14 (0x6u << 4) // (SPI) 14 Bits Per transfer
+#define AT91C_SPI_BITS_15 (0x7u << 4) // (SPI) 15 Bits Per transfer
+#define AT91C_SPI_BITS_16 (0x8u << 4) // (SPI) 16 Bits Per transfer
+#define AT91C_SPI_SCBR (0xFFu << 8) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBS (0xFFu << 16) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBCT (0xFFu << 24) // (SPI) Delay Between Consecutive Transfers
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_SSC {
+ AT91_REG SSC_CR; // Control Register
+ AT91_REG SSC_CMR; // Clock Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG SSC_RCMR; // Receive Clock ModeRegister
+ AT91_REG SSC_RFMR; // Receive Frame Mode Register
+ AT91_REG SSC_TCMR; // Transmit Clock Mode Register
+ AT91_REG SSC_TFMR; // Transmit Frame Mode Register
+ AT91_REG SSC_RHR; // Receive Holding Register
+ AT91_REG SSC_THR; // Transmit Holding Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG SSC_RSHR; // Receive Sync Holding Register
+ AT91_REG SSC_TSHR; // Transmit Sync Holding Register
+ AT91_REG SSC_RC0R; // Receive Compare 0 Register
+ AT91_REG SSC_RC1R; // Receive Compare 1 Register
+ AT91_REG SSC_SR; // Status Register
+ AT91_REG SSC_IER; // Interrupt Enable Register
+ AT91_REG SSC_IDR; // Interrupt Disable Register
+ AT91_REG SSC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved2[44]; //
+ AT91_REG SSC_RPR; // Receive Pointer Register
+ AT91_REG SSC_RCR; // Receive Counter Register
+ AT91_REG SSC_TPR; // Transmit Pointer Register
+ AT91_REG SSC_TCR; // Transmit Counter Register
+ AT91_REG SSC_RNPR; // Receive Next Pointer Register
+ AT91_REG SSC_RNCR; // Receive Next Counter Register
+ AT91_REG SSC_TNPR; // Transmit Next Pointer Register
+ AT91_REG SSC_TNCR; // Transmit Next Counter Register
+ AT91_REG SSC_PTCR; // PDC Transfer Control Register
+ AT91_REG SSC_PTSR; // PDC Transfer Status Register
+} AT91S_SSC, *AT91PS_SSC;
+
+// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register --------
+#define AT91C_SSC_RXEN (0x1u << 0) // (SSC) Receive Enable
+#define AT91C_SSC_RXDIS (0x1u << 1) // (SSC) Receive Disable
+#define AT91C_SSC_TXEN (0x1u << 8) // (SSC) Transmit Enable
+#define AT91C_SSC_TXDIS (0x1u << 9) // (SSC) Transmit Disable
+#define AT91C_SSC_SWRST (0x1u << 15) // (SSC) Software Reset
+// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register --------
+#define AT91C_SSC_CKS (0x3u << 0) // (SSC) Receive/Transmit Clock Selection
+#define AT91C_SSC_CKS_DIV 0x0u // (SSC) Divided Clock
+#define AT91C_SSC_CKS_TK 0x1u // (SSC) TK Clock signal
+#define AT91C_SSC_CKS_RK 0x2u // (SSC) RK pin
+#define AT91C_SSC_CKO (0x7u << 2) // (SSC) Receive/Transmit Clock Output Mode Selection
+#define AT91C_SSC_CKO_NONE (0x0u << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only
+#define AT91C_SSC_CKO_CONTINOUS (0x1u << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output
+#define AT91C_SSC_CKO_DATA_TX (0x2u << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output
+#define AT91C_SSC_CKI (0x1u << 5) // (SSC) Receive/Transmit Clock Inversion
+#define AT91C_SSC_CKG (0x3u << 6) // (SSC) Receive/Transmit Clock Gating Selection
+#define AT91C_SSC_CKG_NONE (0x0u << 6) // (SSC) Receive/Transmit Clock Gating: None, continuous clock
+#define AT91C_SSC_CKG_LOW (0x1u << 6) // (SSC) Receive/Transmit Clock enabled only if RF Low
+#define AT91C_SSC_CKG_HIGH (0x2u << 6) // (SSC) Receive/Transmit Clock enabled only if RF High
+#define AT91C_SSC_START (0xFu << 8) // (SSC) Receive/Transmit Start Selection
+#define AT91C_SSC_START_CONTINOUS (0x0u << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data.
+#define AT91C_SSC_START_TX (0x1u << 8) // (SSC) Transmit/Receive start
+#define AT91C_SSC_START_LOW_RF (0x2u << 8) // (SSC) Detection of a low level on RF input
+#define AT91C_SSC_START_HIGH_RF (0x3u << 8) // (SSC) Detection of a high level on RF input
+#define AT91C_SSC_START_FALL_RF (0x4u << 8) // (SSC) Detection of a falling edge on RF input
+#define AT91C_SSC_START_RISE_RF (0x5u << 8) // (SSC) Detection of a rising edge on RF input
+#define AT91C_SSC_START_LEVEL_RF (0x6u << 8) // (SSC) Detection of any level change on RF input
+#define AT91C_SSC_START_EDGE_RF (0x7u << 8) // (SSC) Detection of any edge on RF input
+#define AT91C_SSC_START_0 (0x8u << 8) // (SSC) Compare 0
+#define AT91C_SSC_STOP (0x1u << 12) // (SSC) Receive Stop Selection
+#define AT91C_SSC_STTOUT (0x1u << 15) // (SSC) Receive/Transmit Start Output Selection
+#define AT91C_SSC_STTDLY (0xFFu << 16) // (SSC) Receive/Transmit Start Delay
+#define AT91C_SSC_PERIOD (0xFFu << 24) // (SSC) Receive/Transmit Period Divider Selection
+// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register --------
+#define AT91C_SSC_DATLEN (0x1Fu << 0) // (SSC) Data Length
+#define AT91C_SSC_LOOP (0x1u << 5) // (SSC) Loop Mode
+#define AT91C_SSC_MSBF (0x1u << 7) // (SSC) Most Significant Bit First
+#define AT91C_SSC_DATNB (0xFu << 8) // (SSC) Data Number per Frame
+#define AT91C_SSC_FSLEN (0xFu << 16) // (SSC) Receive/Transmit Frame Sync length
+#define AT91C_SSC_FSOS (0x7u << 20) // (SSC) Receive/Transmit Frame Sync Output Selection
+#define AT91C_SSC_FSOS_NONE (0x0u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only
+#define AT91C_SSC_FSOS_NEGATIVE (0x1u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse
+#define AT91C_SSC_FSOS_POSITIVE (0x2u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse
+#define AT91C_SSC_FSOS_LOW (0x3u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer
+#define AT91C_SSC_FSOS_HIGH (0x4u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer
+#define AT91C_SSC_FSOS_TOGGLE (0x5u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer
+#define AT91C_SSC_FSEDGE (0x1u << 24) // (SSC) Frame Sync Edge Detection
+// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register --------
+// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register --------
+#define AT91C_SSC_DATDEF (0x1u << 5) // (SSC) Data Default Value
+#define AT91C_SSC_FSDEN (0x1u << 23) // (SSC) Frame Sync Data Enable
+// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register --------
+#define AT91C_SSC_TXRDY (0x1u << 0) // (SSC) Transmit Ready
+#define AT91C_SSC_TXEMPTY (0x1u << 1) // (SSC) Transmit Empty
+#define AT91C_SSC_ENDTX (0x1u << 2) // (SSC) End Of Transmission
+#define AT91C_SSC_TXBUFE (0x1u << 3) // (SSC) Transmit Buffer Empty
+#define AT91C_SSC_RXRDY (0x1u << 4) // (SSC) Receive Ready
+#define AT91C_SSC_OVRUN (0x1u << 5) // (SSC) Receive Overrun
+#define AT91C_SSC_ENDRX (0x1u << 6) // (SSC) End of Reception
+#define AT91C_SSC_RXBUFF (0x1u << 7) // (SSC) Receive Buffer Full
+#define AT91C_SSC_CP0 (0x1u << 8) // (SSC) Compare 0
+#define AT91C_SSC_CP1 (0x1u << 9) // (SSC) Compare 1
+#define AT91C_SSC_TXSYN (0x1u << 10) // (SSC) Transmit Sync
+#define AT91C_SSC_RXSYN (0x1u << 11) // (SSC) Receive Sync
+#define AT91C_SSC_TXENA (0x1u << 16) // (SSC) Transmit Enable
+#define AT91C_SSC_RXENA (0x1u << 17) // (SSC) Receive Enable
+// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register --------
+// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register --------
+// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Usart
+// *****************************************************************************
+typedef struct _AT91S_USART {
+ AT91_REG US_CR; // Control Register
+ AT91_REG US_MR; // Mode Register
+ AT91_REG US_IER; // Interrupt Enable Register
+ AT91_REG US_IDR; // Interrupt Disable Register
+ AT91_REG US_IMR; // Interrupt Mask Register
+ AT91_REG US_CSR; // Channel Status Register
+ AT91_REG US_RHR; // Receiver Holding Register
+ AT91_REG US_THR; // Transmitter Holding Register
+ AT91_REG US_BRGR; // Baud Rate Generator Register
+ AT91_REG US_RTOR; // Receiver Time-out Register
+ AT91_REG US_TTGR; // Transmitter Time-guard Register
+ AT91_REG Reserved0[5]; //
+ AT91_REG US_FIDI; // FI_DI_Ratio Register
+ AT91_REG US_NER; // Nb Errors Register
+ AT91_REG US_XXR; // XON_XOFF Register
+ AT91_REG US_IF; // IRDA_FILTER Register
+ AT91_REG Reserved1[44]; //
+ AT91_REG US_RPR; // Receive Pointer Register
+ AT91_REG US_RCR; // Receive Counter Register
+ AT91_REG US_TPR; // Transmit Pointer Register
+ AT91_REG US_TCR; // Transmit Counter Register
+ AT91_REG US_RNPR; // Receive Next Pointer Register
+ AT91_REG US_RNCR; // Receive Next Counter Register
+ AT91_REG US_TNPR; // Transmit Next Pointer Register
+ AT91_REG US_TNCR; // Transmit Next Counter Register
+ AT91_REG US_PTCR; // PDC Transfer Control Register
+ AT91_REG US_PTSR; // PDC Transfer Status Register
+} AT91S_USART, *AT91PS_USART;
+
+// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_RSTSTA (0x1u << 8) // (USART) Reset Status Bits
+#define AT91C_US_STTBRK (0x1u << 9) // (USART) Start Break
+#define AT91C_US_STPBRK (0x1u << 10) // (USART) Stop Break
+#define AT91C_US_STTTO (0x1u << 11) // (USART) Start Time-out
+#define AT91C_US_SENDA (0x1u << 12) // (USART) Send Address
+#define AT91C_US_RSTIT (0x1u << 13) // (USART) Reset Iterations
+#define AT91C_US_RSTNACK (0x1u << 14) // (USART) Reset Non Acknowledge
+#define AT91C_US_RETTO (0x1u << 15) // (USART) Rearm Time-out
+#define AT91C_US_DTREN (0x1u << 16) // (USART) Data Terminal ready Enable
+#define AT91C_US_DTRDIS (0x1u << 17) // (USART) Data Terminal ready Disable
+#define AT91C_US_RTSEN (0x1u << 18) // (USART) Request to Send enable
+#define AT91C_US_RTSDIS (0x1u << 19) // (USART) Request to Send Disable
+// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_USMODE (0xFu << 0) // (USART) Usart mode
+#define AT91C_US_USMODE_NORMAL 0x0u // (USART) Normal
+#define AT91C_US_USMODE_RS485 0x1u // (USART) RS485
+#define AT91C_US_USMODE_HWHSH 0x2u // (USART) Hardware Handshaking
+#define AT91C_US_USMODE_MODEM 0x3u // (USART) Modem
+#define AT91C_US_USMODE_ISO7816_0 0x4u // (USART) ISO7816 protocol: T = 0
+#define AT91C_US_USMODE_ISO7816_1 0x6u // (USART) ISO7816 protocol: T = 1
+#define AT91C_US_USMODE_IRDA 0x8u // (USART) IrDA
+#define AT91C_US_USMODE_SWHSH 0xCu // (USART) Software Handshaking
+#define AT91C_US_CLKS (0x3u << 4) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CLKS_CLOCK (0x0u << 4) // (USART) Clock
+#define AT91C_US_CLKS_FDIV1 (0x1u << 4) // (USART) fdiv1
+#define AT91C_US_CLKS_SLOW (0x2u << 4) // (USART) slow_clock (ARM)
+#define AT91C_US_CLKS_EXT (0x3u << 4) // (USART) External (SCK)
+#define AT91C_US_CHRL (0x3u << 6) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CHRL_5_BITS (0x0u << 6) // (USART) Character Length: 5 bits
+#define AT91C_US_CHRL_6_BITS (0x1u << 6) // (USART) Character Length: 6 bits
+#define AT91C_US_CHRL_7_BITS (0x2u << 6) // (USART) Character Length: 7 bits
+#define AT91C_US_CHRL_8_BITS (0x3u << 6) // (USART) Character Length: 8 bits
+#define AT91C_US_SYNC (0x1u << 8) // (USART) Synchronous Mode Select
+#define AT91C_US_NBSTOP (0x3u << 12) // (USART) Number of Stop bits
+#define AT91C_US_NBSTOP_1_BIT (0x0u << 12) // (USART) 1 stop bit
+#define AT91C_US_NBSTOP_15_BIT (0x1u << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits
+#define AT91C_US_NBSTOP_2_BIT (0x2u << 12) // (USART) 2 stop bits
+#define AT91C_US_MSBF (0x1u << 16) // (USART) Bit Order
+#define AT91C_US_MODE9 (0x1u << 17) // (USART) 9-bit Character length
+#define AT91C_US_CKLO (0x1u << 18) // (USART) Clock Output Select
+#define AT91C_US_OVER (0x1u << 19) // (USART) Over Sampling Mode
+#define AT91C_US_INACK (0x1u << 20) // (USART) Inhibit Non Acknowledge
+#define AT91C_US_DSNACK (0x1u << 21) // (USART) Disable Successive NACK
+#define AT91C_US_MAX_ITER (0x1u << 24) // (USART) Number of Repetitions
+#define AT91C_US_FILTER (0x1u << 28) // (USART) Receive Line Filter
+// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXBRK (0x1u << 2) // (USART) Break Received/End of Break
+#define AT91C_US_TIMEOUT (0x1u << 8) // (USART) Receiver Time-out
+#define AT91C_US_ITERATION (0x1u << 10) // (USART) Max number of Repetitions Reached
+#define AT91C_US_NACK (0x1u << 13) // (USART) Non Acknowledge
+#define AT91C_US_RIIC (0x1u << 16) // (USART) Ring INdicator Input Change Flag
+#define AT91C_US_DSRIC (0x1u << 17) // (USART) Data Set Ready Input Change Flag
+#define AT91C_US_DCDIC (0x1u << 18) // (USART) Data Carrier Flag
+#define AT91C_US_CTSIC (0x1u << 19) // (USART) Clear To Send Input Change Flag
+// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register --------
+#define AT91C_US_RI (0x1u << 20) // (USART) Image of RI Input
+#define AT91C_US_DSR (0x1u << 21) // (USART) Image of DSR Input
+#define AT91C_US_DCD (0x1u << 22) // (USART) Image of DCD Input
+#define AT91C_US_CTS (0x1u << 23) // (USART) Image of CTS Input
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Two-wire Interface
+// *****************************************************************************
+typedef struct _AT91S_TWI {
+ AT91_REG TWI_CR; // Control Register
+ AT91_REG TWI_MMR; // Master Mode Register
+ AT91_REG TWI_SMR; // Slave Mode Register
+ AT91_REG TWI_IADR; // Internal Address Register
+ AT91_REG TWI_CWGR; // Clock Waveform Generator Register
+ AT91_REG Reserved0[3]; //
+ AT91_REG TWI_SR; // Status Register
+ AT91_REG TWI_IER; // Interrupt Enable Register
+ AT91_REG TWI_IDR; // Interrupt Disable Register
+ AT91_REG TWI_IMR; // Interrupt Mask Register
+ AT91_REG TWI_RHR; // Receive Holding Register
+ AT91_REG TWI_THR; // Transmit Holding Register
+} AT91S_TWI, *AT91PS_TWI;
+
+// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
+#define AT91C_TWI_START (0x1u << 0) // (TWI) Send a START Condition
+#define AT91C_TWI_STOP (0x1u << 1) // (TWI) Send a STOP Condition
+#define AT91C_TWI_MSEN (0x1u << 2) // (TWI) TWI Master Transfer Enabled
+#define AT91C_TWI_MSDIS (0x1u << 3) // (TWI) TWI Master Transfer Disabled
+#define AT91C_TWI_SVEN (0x1u << 4) // (TWI) TWI Slave Transfer Enabled
+#define AT91C_TWI_SVDIS (0x1u << 5) // (TWI) TWI Slave Transfer Disabled
+#define AT91C_TWI_SWRST (0x1u << 7) // (TWI) Software Reset
+// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
+#define AT91C_TWI_IADRSZ (0x3u << 8) // (TWI) Internal Device Address Size
+#define AT91C_TWI_IADRSZ_NO (0x0u << 8) // (TWI) No internal device address
+#define AT91C_TWI_IADRSZ_1_BYTE (0x1u << 8) // (TWI) One-byte internal device address
+#define AT91C_TWI_IADRSZ_2_BYTE (0x2u << 8) // (TWI) Two-byte internal device address
+#define AT91C_TWI_IADRSZ_3_BYTE (0x3u << 8) // (TWI) Three-byte internal device address
+#define AT91C_TWI_MREAD (0x1u << 12) // (TWI) Master Read Direction
+#define AT91C_TWI_DADR (0x7Fu << 16) // (TWI) Device Address
+// -------- TWI_SMR : (TWI Offset: 0x8) TWI Slave Mode Register --------
+#define AT91C_TWI_SADR (0x7Fu << 16) // (TWI) Slave Device Address
+// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
+#define AT91C_TWI_CLDIV (0xFFu << 0) // (TWI) Clock Low Divider
+#define AT91C_TWI_CHDIV (0xFFu << 8) // (TWI) Clock High Divider
+#define AT91C_TWI_CKDIV (0x7u << 16) // (TWI) Clock Divider
+// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
+#define AT91C_TWI_TXCOMP (0x1u << 0) // (TWI) Transmission Completed
+#define AT91C_TWI_RXRDY (0x1u << 1) // (TWI) Receive holding register ReaDY
+#define AT91C_TWI_TXRDY (0x1u << 2) // (TWI) Transmit holding register ReaDY
+#define AT91C_TWI_SVREAD (0x1u << 3) // (TWI) Slave Read
+#define AT91C_TWI_SVACC (0x1u << 4) // (TWI) Slave Access
+#define AT91C_TWI_GCACC (0x1u << 5) // (TWI) General Call Access
+#define AT91C_TWI_OVRE (0x1u << 6) // (TWI) Overrun Error
+#define AT91C_TWI_UNRE (0x1u << 7) // (TWI) Underrun Error
+#define AT91C_TWI_NACK (0x1u << 8) // (TWI) Not Acknowledged
+#define AT91C_TWI_ARBLST (0x1u << 9) // (TWI) Arbitration Lost
+// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register --------
+// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register --------
+// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Multimedia Card Interface
+// *****************************************************************************
+typedef struct _AT91S_MCI {
+ AT91_REG MCI_CR; // MCI Control Register
+ AT91_REG MCI_MR; // MCI Mode Register
+ AT91_REG MCI_DTOR; // MCI Data Timeout Register
+ AT91_REG MCI_SDCR; // MCI SD Card Register
+ AT91_REG MCI_ARGR; // MCI Argument Register
+ AT91_REG MCI_CMDR; // MCI Command Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG MCI_RSPR[4]; // MCI Response Register
+ AT91_REG MCI_RDR; // MCI Receive Data Register
+ AT91_REG MCI_TDR; // MCI Transmit Data Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG MCI_SR; // MCI Status Register
+ AT91_REG MCI_IER; // MCI Interrupt Enable Register
+ AT91_REG MCI_IDR; // MCI Interrupt Disable Register
+ AT91_REG MCI_IMR; // MCI Interrupt Mask Register
+ AT91_REG Reserved2[44]; //
+ AT91_REG MCI_RPR; // Receive Pointer Register
+ AT91_REG MCI_RCR; // Receive Counter Register
+ AT91_REG MCI_TPR; // Transmit Pointer Register
+ AT91_REG MCI_TCR; // Transmit Counter Register
+ AT91_REG MCI_RNPR; // Receive Next Pointer Register
+ AT91_REG MCI_RNCR; // Receive Next Counter Register
+ AT91_REG MCI_TNPR; // Transmit Next Pointer Register
+ AT91_REG MCI_TNCR; // Transmit Next Counter Register
+ AT91_REG MCI_PTCR; // PDC Transfer Control Register
+ AT91_REG MCI_PTSR; // PDC Transfer Status Register
+} AT91S_MCI, *AT91PS_MCI;
+
+// -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register --------
+#define AT91C_MCI_MCIEN (0x1u << 0) // (MCI) Multimedia Interface Enable
+#define AT91C_MCI_MCIDIS (0x1u << 1) // (MCI) Multimedia Interface Disable
+#define AT91C_MCI_PWSEN (0x1u << 2) // (MCI) Power Save Mode Enable
+#define AT91C_MCI_PWSDIS (0x1u << 3) // (MCI) Power Save Mode Disable
+// -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register --------
+#define AT91C_MCI_CLKDIV (0x1u << 0) // (MCI) Clock Divider
+#define AT91C_MCI_PWSDIV (0x1u << 8) // (MCI) Power Saving Divider
+#define AT91C_MCI_PDCPADV (0x1u << 14) // (MCI) PDC Padding Value
+#define AT91C_MCI_PDCMODE (0x1u << 15) // (MCI) PDC Oriented Mode
+#define AT91C_MCI_BLKLEN (0x1u << 18) // (MCI) Data Block Length
+// -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register --------
+#define AT91C_MCI_DTOCYC (0x1u << 0) // (MCI) Data Timeout Cycle Number
+#define AT91C_MCI_DTOMUL (0x7u << 4) // (MCI) Data Timeout Multiplier
+#define AT91C_MCI_DTOMUL_1 (0x0u << 4) // (MCI) DTOCYC x 1
+#define AT91C_MCI_DTOMUL_16 (0x1u << 4) // (MCI) DTOCYC x 16
+#define AT91C_MCI_DTOMUL_128 (0x2u << 4) // (MCI) DTOCYC x 128
+#define AT91C_MCI_DTOMUL_256 (0x3u << 4) // (MCI) DTOCYC x 256
+#define AT91C_MCI_DTOMUL_1024 (0x4u << 4) // (MCI) DTOCYC x 1024
+#define AT91C_MCI_DTOMUL_4096 (0x5u << 4) // (MCI) DTOCYC x 4096
+#define AT91C_MCI_DTOMUL_65536 (0x6u << 4) // (MCI) DTOCYC x 65536
+#define AT91C_MCI_DTOMUL_1048576 (0x7u << 4) // (MCI) DTOCYC x 1048576
+// -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register --------
+#define AT91C_MCI_SCDSEL (0x1u << 0) // (MCI) SD Card Selector
+#define AT91C_MCI_SCDBUS (0x1u << 7) // (MCI) SD Card Bus Width
+// -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register --------
+// -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register --------
+#define AT91C_MCI_CMDRDY (0x1u << 0) // (MCI) Command Ready flag
+#define AT91C_MCI_RXRDY (0x1u << 1) // (MCI) RX Ready flag
+#define AT91C_MCI_TXRDY (0x1u << 2) // (MCI) TX Ready flag
+#define AT91C_MCI_BLKE (0x1u << 3) // (MCI) Data Block Transfer Ended flag
+#define AT91C_MCI_DTIP (0x1u << 4) // (MCI) Data Transfer in Progress flag
+#define AT91C_MCI_NOTBUSY (0x1u << 5) // (MCI) Data Line Not Busy flag
+#define AT91C_MCI_ENDRX (0x1u << 6) // (MCI) End of RX Buffer flag
+#define AT91C_MCI_ENDTX (0x1u << 7) // (MCI) End of TX Buffer flag
+#define AT91C_MCI_RXBUFF (0x1u << 14) // (MCI) RX Buffer Full flag
+#define AT91C_MCI_TXBUFE (0x1u << 15) // (MCI) TX Buffer Empty flag
+#define AT91C_MCI_RINDE (0x1u << 16) // (MCI) Response Index Error flag
+#define AT91C_MCI_RDIRE (0x1u << 17) // (MCI) Response Direction Error flag
+#define AT91C_MCI_RCRCE (0x1u << 18) // (MCI) Response CRC Error flag
+#define AT91C_MCI_RENDE (0x1u << 19) // (MCI) Response End Bit Error flag
+#define AT91C_MCI_RTOE (0x1u << 20) // (MCI) Response Time-out Error flag
+#define AT91C_MCI_DCRCE (0x1u << 21) // (MCI) data CRC Error flag
+#define AT91C_MCI_DTOE (0x1u << 22) // (MCI) Data timeout Error flag
+#define AT91C_MCI_OVRE (0x1u << 30) // (MCI) Overrun flag
+#define AT91C_MCI_UNRE (0x1u << 31) // (MCI) Underrun flag
+// -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register --------
+// -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register --------
+// -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR USB Device Interface
+// *****************************************************************************
+typedef struct _AT91S_UDP {
+ AT91_REG UDP_NUM; // Frame Number Register
+ AT91_REG UDP_GLBSTATE; // Global State Register
+ AT91_REG UDP_FADDR; // Function Address Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG UDP_IER; // Interrupt Enable Register
+ AT91_REG UDP_IDR; // Interrupt Disable Register
+ AT91_REG UDP_IMR; // Interrupt Mask Register
+ AT91_REG UDP_ISR; // Interrupt Status Register
+ AT91_REG UDP_ICR; // Interrupt Clear Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG UDP_RSTEP; // Reset Endpoint Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG UDP_CSR[8]; // Endpoint Control and Status Register
+ AT91_REG UDP_FDR[8]; // Endpoint FIFO Data Register
+} AT91S_UDP, *AT91PS_UDP;
+
+// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register --------
+#define AT91C_UDP_FRM_NUM (0x7FFu << 0) // (UDP) Frame Number as Defined in the Packet Field Formats
+#define AT91C_UDP_FRM_ERR (0x1u << 16) // (UDP) Frame Error
+#define AT91C_UDP_FRM_OK (0x1u << 17) // (UDP) Frame OK
+// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register --------
+#define AT91C_UDP_FADDEN (0x1u << 0) // (UDP) Function Address Enable
+#define AT91C_UDP_CONFG (0x1u << 1) // (UDP) Configured
+#define AT91C_UDP_RMWUPE (0x1u << 2) // (UDP) Remote Wake Up Enable
+#define AT91C_UDP_RSMINPR (0x1u << 3) // (UDP) A Resume Has Been Sent to the Host
+// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register --------
+#define AT91C_UDP_FADD (0xFFu << 0) // (UDP) Function Address Value
+#define AT91C_UDP_FEN (0x1u << 8) // (UDP) Function Enable
+// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register --------
+#define AT91C_UDP_EPINT0 (0x1u << 0) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT1 (0x1u << 1) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT2 (0x1u << 2) // (UDP) Endpoint 2 Interrupt
+#define AT91C_UDP_EPINT3 (0x1u << 3) // (UDP) Endpoint 3 Interrupt
+#define AT91C_UDP_EPINT4 (0x1u << 4) // (UDP) Endpoint 4 Interrupt
+#define AT91C_UDP_EPINT5 (0x1u << 5) // (UDP) Endpoint 5 Interrupt
+#define AT91C_UDP_EPINT6 (0x1u << 6) // (UDP) Endpoint 6 Interrupt
+#define AT91C_UDP_EPINT7 (0x1u << 7) // (UDP) Endpoint 7 Interrupt
+#define AT91C_UDP_RXSUSP (0x1u << 8) // (UDP) USB Suspend Interrupt
+#define AT91C_UDP_RXRSM (0x1u << 9) // (UDP) USB Resume Interrupt
+#define AT91C_UDP_EXTRSM (0x1u << 10) // (UDP) USB External Resume Interrupt
+#define AT91C_UDP_SOFINT (0x1u << 11) // (UDP) USB Start Of frame Interrupt
+#define AT91C_UDP_WAKEUP (0x1u << 13) // (UDP) USB Resume Interrupt
+// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register --------
+// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register --------
+// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register --------
+#define AT91C_UDP_ENDBUSRES (0x1u << 12) // (UDP) USB End Of Bus Reset Interrupt
+// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register --------
+// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register --------
+#define AT91C_UDP_EP0 (0x1u << 0) // (UDP) Reset Endpoint 0
+#define AT91C_UDP_EP1 (0x1u << 1) // (UDP) Reset Endpoint 1
+#define AT91C_UDP_EP2 (0x1u << 2) // (UDP) Reset Endpoint 2
+#define AT91C_UDP_EP3 (0x1u << 3) // (UDP) Reset Endpoint 3
+#define AT91C_UDP_EP4 (0x1u << 4) // (UDP) Reset Endpoint 4
+#define AT91C_UDP_EP5 (0x1u << 5) // (UDP) Reset Endpoint 5
+#define AT91C_UDP_EP6 (0x1u << 6) // (UDP) Reset Endpoint 6
+#define AT91C_UDP_EP7 (0x1u << 7) // (UDP) Reset Endpoint 7
+// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register --------
+#define AT91C_UDP_TXCOMP (0x1u << 0) // (UDP) Generates an IN packet with data previously written in the DPR
+#define AT91C_UDP_RX_DATA_BK0 (0x1u << 1) // (UDP) Receive Data Bank 0
+#define AT91C_UDP_RXSETUP (0x1u << 2) // (UDP) Sends STALL to the Host (Control endpoints)
+#define AT91C_UDP_ISOERROR (0x1u << 3) // (UDP) Isochronous error (Isochronous endpoints)
+#define AT91C_UDP_TXPKTRDY (0x1u << 4) // (UDP) Transmit Packet Ready
+#define AT91C_UDP_FORCESTALL (0x1u << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints).
+#define AT91C_UDP_RX_DATA_BK1 (0x1u << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes).
+#define AT91C_UDP_DIR (0x1u << 7) // (UDP) Transfer Direction
+#define AT91C_UDP_EPTYPE (0x7u << 8) // (UDP) Endpoint type
+#define AT91C_UDP_EPTYPE_CTRL (0x0u << 8) // (UDP) Control
+#define AT91C_UDP_EPTYPE_ISO_OUT (0x1u << 8) // (UDP) Isochronous OUT
+#define AT91C_UDP_EPTYPE_BULK_OUT (0x2u << 8) // (UDP) Bulk OUT
+#define AT91C_UDP_EPTYPE_INT_OUT (0x3u << 8) // (UDP) Interrupt OUT
+#define AT91C_UDP_EPTYPE_ISO_IN (0x5u << 8) // (UDP) Isochronous IN
+#define AT91C_UDP_EPTYPE_BULK_IN (0x6u << 8) // (UDP) Bulk IN
+#define AT91C_UDP_EPTYPE_INT_IN (0x7u << 8) // (UDP) Interrupt IN
+#define AT91C_UDP_DTGLE (0x1u << 11) // (UDP) Data Toggle
+#define AT91C_UDP_EPEDS (0x1u << 15) // (UDP) Endpoint Enable Disable
+#define AT91C_UDP_RXBYTECNT (0x7FFu << 16) // (UDP) Number Of Bytes Available in the FIFO
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface
+// *****************************************************************************
+typedef struct _AT91S_TC {
+ AT91_REG TC_CCR; // Channel Control Register
+ AT91_REG TC_CMR; // Channel Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG TC_CV; // Counter Value
+ AT91_REG TC_RA; // Register A
+ AT91_REG TC_RB; // Register B
+ AT91_REG TC_RC; // Register C
+ AT91_REG TC_SR; // Status Register
+ AT91_REG TC_IER; // Interrupt Enable Register
+ AT91_REG TC_IDR; // Interrupt Disable Register
+ AT91_REG TC_IMR; // Interrupt Mask Register
+} AT91S_TC, *AT91PS_TC;
+
+// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register --------
+#define AT91C_TC_CLKEN (0x1u << 0) // (TC) Counter Clock Enable Command
+#define AT91C_TC_CLKDIS (0x1u << 1) // (TC) Counter Clock Disable Command
+#define AT91C_TC_SWTRG (0x1u << 2) // (TC) Software Trigger Command
+// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode --------
+#define AT91C_TC_CPCSTOP (0x1u << 6) // (TC) Counter Clock Stopped with RC Compare
+#define AT91C_TC_CPCDIS (0x1u << 7) // (TC) Counter Clock Disable with RC Compare
+#define AT91C_TC_EEVTEDG (0x3u << 8) // (TC) External Event Edge Selection
+#define AT91C_TC_EEVTEDG_NONE (0x0u << 8) // (TC) Edge: None
+#define AT91C_TC_EEVTEDG_RISING (0x1u << 8) // (TC) Edge: rising edge
+#define AT91C_TC_EEVTEDG_FALLING (0x2u << 8) // (TC) Edge: falling edge
+#define AT91C_TC_EEVTEDG_BOTH (0x3u << 8) // (TC) Edge: each edge
+#define AT91C_TC_EEVT (0x3u << 10) // (TC) External Event Selection
+#define AT91C_TC_EEVT_NONE (0x0u << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input
+#define AT91C_TC_EEVT_RISING (0x1u << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output
+#define AT91C_TC_EEVT_FALLING (0x2u << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output
+#define AT91C_TC_EEVT_BOTH (0x3u << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output
+#define AT91C_TC_ENETRG (0x1u << 12) // (TC) External Event Trigger enable
+#define AT91C_TC_WAVESEL (0x3u << 13) // (TC) Waveform Selection
+#define AT91C_TC_WAVESEL_UP (0x0u << 13) // (TC) UP mode without atomatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UP_AUTO (0x1u << 13) // (TC) UP mode with automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN (0x2u << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN_AUTO (0x3u << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare
+#define AT91C_TC_CPCTRG (0x1u << 14) // (TC) RC Compare Trigger Enable
+#define AT91C_TC_WAVE (0x1u << 15) // (TC)
+#define AT91C_TC_ACPA (0x3u << 16) // (TC) RA Compare Effect on TIOA
+#define AT91C_TC_ACPA_NONE (0x0u << 16) // (TC) Effect: none
+#define AT91C_TC_ACPA_SET (0x1u << 16) // (TC) Effect: set
+#define AT91C_TC_ACPA_CLEAR (0x2u << 16) // (TC) Effect: clear
+#define AT91C_TC_ACPA_TOGGLE (0x3u << 16) // (TC) Effect: toggle
+#define AT91C_TC_ACPC (0x3u << 18) // (TC) RC Compare Effect on TIOA
+#define AT91C_TC_ACPC_NONE (0x0u << 18) // (TC) Effect: none
+#define AT91C_TC_ACPC_SET (0x1u << 18) // (TC) Effect: set
+#define AT91C_TC_ACPC_CLEAR (0x2u << 18) // (TC) Effect: clear
+#define AT91C_TC_ACPC_TOGGLE (0x3u << 18) // (TC) Effect: toggle
+#define AT91C_TC_AEEVT (0x3u << 20) // (TC) External Event Effect on TIOA
+#define AT91C_TC_AEEVT_NONE (0x0u << 20) // (TC) Effect: none
+#define AT91C_TC_AEEVT_SET (0x1u << 20) // (TC) Effect: set
+#define AT91C_TC_AEEVT_CLEAR (0x2u << 20) // (TC) Effect: clear
+#define AT91C_TC_AEEVT_TOGGLE (0x3u << 20) // (TC) Effect: toggle
+#define AT91C_TC_ASWTRG (0x3u << 22) // (TC) Software Trigger Effect on TIOA
+#define AT91C_TC_ASWTRG_NONE (0x0u << 22) // (TC) Effect: none
+#define AT91C_TC_ASWTRG_SET (0x1u << 22) // (TC) Effect: set
+#define AT91C_TC_ASWTRG_CLEAR (0x2u << 22) // (TC) Effect: clear
+#define AT91C_TC_ASWTRG_TOGGLE (0x3u << 22) // (TC) Effect: toggle
+#define AT91C_TC_BCPB (0x3u << 24) // (TC) RB Compare Effect on TIOB
+#define AT91C_TC_BCPB_NONE (0x0u << 24) // (TC) Effect: none
+#define AT91C_TC_BCPB_SET (0x1u << 24) // (TC) Effect: set
+#define AT91C_TC_BCPB_CLEAR (0x2u << 24) // (TC) Effect: clear
+#define AT91C_TC_BCPB_TOGGLE (0x3u << 24) // (TC) Effect: toggle
+#define AT91C_TC_BCPC (0x3u << 26) // (TC) RC Compare Effect on TIOB
+#define AT91C_TC_BCPC_NONE (0x0u << 26) // (TC) Effect: none
+#define AT91C_TC_BCPC_SET (0x1u << 26) // (TC) Effect: set
+#define AT91C_TC_BCPC_CLEAR (0x2u << 26) // (TC) Effect: clear
+#define AT91C_TC_BCPC_TOGGLE (0x3u << 26) // (TC) Effect: toggle
+#define AT91C_TC_BEEVT (0x3u << 28) // (TC) External Event Effect on TIOB
+#define AT91C_TC_BEEVT_NONE (0x0u << 28) // (TC) Effect: none
+#define AT91C_TC_BEEVT_SET (0x1u << 28) // (TC) Effect: set
+#define AT91C_TC_BEEVT_CLEAR (0x2u << 28) // (TC) Effect: clear
+#define AT91C_TC_BEEVT_TOGGLE (0x3u << 28) // (TC) Effect: toggle
+#define AT91C_TC_BSWTRG (0x3u << 30) // (TC) Software Trigger Effect on TIOB
+#define AT91C_TC_BSWTRG_NONE (0x0u << 30) // (TC) Effect: none
+#define AT91C_TC_BSWTRG_SET (0x1u << 30) // (TC) Effect: set
+#define AT91C_TC_BSWTRG_CLEAR (0x2u << 30) // (TC) Effect: clear
+#define AT91C_TC_BSWTRG_TOGGLE (0x3u << 30) // (TC) Effect: toggle
+// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register --------
+#define AT91C_TC_COVFS (0x1u << 0) // (TC) Counter Overflow
+#define AT91C_TC_LOVRS (0x1u << 1) // (TC) Load Overrun
+#define AT91C_TC_CPAS (0x1u << 2) // (TC) RA Compare
+#define AT91C_TC_CPBS (0x1u << 3) // (TC) RB Compare
+#define AT91C_TC_CPCS (0x1u << 4) // (TC) RC Compare
+#define AT91C_TC_LDRAS (0x1u << 5) // (TC) RA Loading
+#define AT91C_TC_LDRBS (0x1u << 6) // (TC) RB Loading
+#define AT91C_TC_ETRCS (0x1u << 7) // (TC) External Trigger
+#define AT91C_TC_ETRGS (0x1u << 16) // (TC) Clock Enabling
+#define AT91C_TC_MTIOA (0x1u << 17) // (TC) TIOA Mirror
+#define AT91C_TC_MTIOB (0x1u << 18) // (TC) TIOA Mirror
+// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register --------
+// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register --------
+// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Interface
+// *****************************************************************************
+typedef struct _AT91S_TCB {
+ AT91S_TC TCB_TC0; // TC Channel 0
+ AT91_REG Reserved0[4]; //
+ AT91S_TC TCB_TC1; // TC Channel 1
+ AT91_REG Reserved1[4]; //
+ AT91S_TC TCB_TC2; // TC Channel 2
+ AT91_REG Reserved2[4]; //
+ AT91_REG TCB_BCR; // TC Block Control Register
+ AT91_REG TCB_BMR; // TC Block Mode Register
+} AT91S_TCB, *AT91PS_TCB;
+
+// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register --------
+#define AT91C_TCB_SYNC (0x1u << 0) // (TCB) Synchro Command
+// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register --------
+#define AT91C_TCB_TC0XC0S (0x1u << 0) // (TCB) External Clock Signal 0 Selection
+#define AT91C_TCB_TC0XC0S_TCLK0 0x0u // (TCB) TCLK0 connected to XC0
+#define AT91C_TCB_TC0XC0S_NONE 0x1u // (TCB) None signal connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA1 0x2u // (TCB) TIOA1 connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA2 0x3u // (TCB) TIOA2 connected to XC0
+#define AT91C_TCB_TC1XC1S (0x1u << 2) // (TCB) External Clock Signal 1 Selection
+#define AT91C_TCB_TC1XC1S_TCLK1 (0x0u << 2) // (TCB) TCLK1 connected to XC1
+#define AT91C_TCB_TC1XC1S_NONE (0x1u << 2) // (TCB) None signal connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA0 (0x2u << 2) // (TCB) TIOA0 connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA2 (0x3u << 2) // (TCB) TIOA2 connected to XC1
+#define AT91C_TCB_TC2XC2S (0x1u << 4) // (TCB) External Clock Signal 2 Selection
+#define AT91C_TCB_TC2XC2S_TCLK2 (0x0u << 4) // (TCB) TCLK2 connected to XC2
+#define AT91C_TCB_TC2XC2S_NONE (0x1u << 4) // (TCB) None signal connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA0 (0x2u << 4) // (TCB) TIOA0 connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA2 (0x3u << 4) // (TCB) TIOA2 connected to XC2
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR USB Host Interface
+// *****************************************************************************
+typedef struct _AT91S_UHP {
+ AT91_REG UHP_HcRevision; // Revision
+ AT91_REG UHP_HcControl; // Operating modes for the Host Controller
+ AT91_REG UHP_HcCommandStatus; // Command & status Register
+ AT91_REG UHP_HcInterruptStatus; // Interrupt Status Register
+ AT91_REG UHP_HcInterruptEnable; // Interrupt Enable Register
+ AT91_REG UHP_HcInterruptDisable; // Interrupt Disable Register
+ AT91_REG UHP_HcHCCA; // Pointer to the Host Controller Communication Area
+ AT91_REG UHP_HcPeriodCurrentED; // Current Isochronous or Interrupt Endpoint Descriptor
+ AT91_REG UHP_HcControlHeadED; // First Endpoint Descriptor of the Control list
+ AT91_REG UHP_HcControlCurrentED; // Endpoint Control and Status Register
+ AT91_REG UHP_HcBulkHeadED; // First endpoint register of the Bulk list
+ AT91_REG UHP_HcBulkCurrentED; // Current endpoint of the Bulk list
+ AT91_REG UHP_HcBulkDoneHead; // Last completed transfer descriptor
+ AT91_REG UHP_HcFmInterval; // Bit time between 2 consecutive SOFs
+ AT91_REG UHP_HcFmRemaining; // Bit time remaining in the current Frame
+ AT91_REG UHP_HcFmNumber; // Frame number
+ AT91_REG UHP_HcPeriodicStart; // Periodic Start
+ AT91_REG UHP_HcLSThreshold; // LS Threshold
+ AT91_REG UHP_HcRhDescriptorA; // Root Hub characteristics A
+ AT91_REG UHP_HcRhDescriptorB; // Root Hub characteristics B
+ AT91_REG UHP_HcRhStatus; // Root Hub Status register
+ AT91_REG UHP_HcRhPortStatus[2]; // Root Hub Port Status Register
+} AT91S_UHP, *AT91PS_UHP;
+
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Ethernet MAC
+// *****************************************************************************
+typedef struct _AT91S_EMAC {
+ AT91_REG EMAC_CTL; // Network Control Register
+ AT91_REG EMAC_CFG; // Network Configuration Register
+ AT91_REG EMAC_SR; // Network Status Register
+ AT91_REG EMAC_TAR; // Transmit Address Register
+ AT91_REG EMAC_TCR; // Transmit Control Register
+ AT91_REG EMAC_TSR; // Transmit Status Register
+ AT91_REG EMAC_RBQP; // Receive Buffer Queue Pointer
+ AT91_REG Reserved0[1]; //
+ AT91_REG EMAC_RSR; // Receive Status Register
+ AT91_REG EMAC_ISR; // Interrupt Status Register
+ AT91_REG EMAC_IER; // Interrupt Enable Register
+ AT91_REG EMAC_IDR; // Interrupt Disable Register
+ AT91_REG EMAC_IMR; // Interrupt Mask Register
+ AT91_REG EMAC_MAN; // PHY Maintenance Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG EMAC_FRA; // Frames Transmitted OK Register
+ AT91_REG EMAC_SCOL; // Single Collision Frame Register
+ AT91_REG EMAC_MCOL; // Multiple Collision Frame Register
+ AT91_REG EMAC_OK; // Frames Received OK Register
+ AT91_REG EMAC_SEQE; // Frame Check Sequence Error Register
+ AT91_REG EMAC_ALE; // Alignment Error Register
+ AT91_REG EMAC_DTE; // Deferred Transmission Frame Register
+ AT91_REG EMAC_LCOL; // Late Collision Register
+ AT91_REG EMAC_ECOL; // Excessive Collision Register
+ AT91_REG EMAC_CSE; // Carrier Sense Error Register
+ AT91_REG EMAC_TUE; // Transmit Underrun Error Register
+ AT91_REG EMAC_CDE; // Code Error Register
+ AT91_REG EMAC_ELR; // Excessive Length Error Register
+ AT91_REG EMAC_RJB; // Receive Jabber Register
+ AT91_REG EMAC_USF; // Undersize Frame Register
+ AT91_REG EMAC_SQEE; // SQE Test Error Register
+ AT91_REG EMAC_DRFC; // Discarded RX Frame Register
+ AT91_REG Reserved2[3]; //
+ AT91_REG EMAC_HSH; // Hash Address High[63:32]
+ AT91_REG EMAC_HSL; // Hash Address Low[31:0]
+ AT91_REG EMAC_SA1L; // Specific Address 1 Low, First 4 bytes
+ AT91_REG EMAC_SA1H; // Specific Address 1 High, Last 2 bytes
+ AT91_REG EMAC_SA2L; // Specific Address 2 Low, First 4 bytes
+ AT91_REG EMAC_SA2H; // Specific Address 2 High, Last 2 bytes
+ AT91_REG EMAC_SA3L; // Specific Address 3 Low, First 4 bytes
+ AT91_REG EMAC_SA3H; // Specific Address 3 High, Last 2 bytes
+ AT91_REG EMAC_SA4L; // Specific Address 4 Low, First 4 bytes
+ AT91_REG EMAC_SA4H; // Specific Address 4 High, Last 2 bytesr
+} AT91S_EMAC, *AT91PS_EMAC;
+
+// -------- EMAC_CTL : (EMAC Offset: 0x0) --------
+#define AT91C_EMAC_LB (0x1u << 0) // (EMAC) Loopback. Optional. When set, loopback signal is at high level.
+#define AT91C_EMAC_LBL (0x1u << 1) // (EMAC) Loopback local.
+#define AT91C_EMAC_RE (0x1u << 2) // (EMAC) Receive enable.
+#define AT91C_EMAC_TE (0x1u << 3) // (EMAC) Transmit enable.
+#define AT91C_EMAC_MPE (0x1u << 4) // (EMAC) Management port enable.
+#define AT91C_EMAC_CSR (0x1u << 5) // (EMAC) Clear statistics registers.
+#define AT91C_EMAC_ISR (0x1u << 6) // (EMAC) Increment statistics registers.
+#define AT91C_EMAC_WES (0x1u << 7) // (EMAC) Write enable for statistics registers.
+#define AT91C_EMAC_BP (0x1u << 8) // (EMAC) Back pressure.
+// -------- EMAC_CFG : (EMAC Offset: 0x4) Network Configuration Register --------
+#define AT91C_EMAC_SPD (0x1u << 0) // (EMAC) Speed.
+#define AT91C_EMAC_FD (0x1u << 1) // (EMAC) Full duplex.
+#define AT91C_EMAC_BR (0x1u << 2) // (EMAC) Bit rate.
+#define AT91C_EMAC_CAF (0x1u << 4) // (EMAC) Copy all frames.
+#define AT91C_EMAC_NBC (0x1u << 5) // (EMAC) No broadcast.
+#define AT91C_EMAC_MTI (0x1u << 6) // (EMAC) Multicast hash enable
+#define AT91C_EMAC_UNI (0x1u << 7) // (EMAC) Unicast hash enable.
+#define AT91C_EMAC_BIG (0x1u << 8) // (EMAC) Receive 1522 bytes.
+#define AT91C_EMAC_EAE (0x1u << 9) // (EMAC) External address match enable.
+#define AT91C_EMAC_CLK (0x3u << 10) // (EMAC)
+#define AT91C_EMAC_CLK_HCLK_8 (0x0u << 10) // (EMAC) HCLK divided by 8
+#define AT91C_EMAC_CLK_HCLK_16 (0x1u << 10) // (EMAC) HCLK divided by 16
+#define AT91C_EMAC_CLK_HCLK_32 (0x2u << 10) // (EMAC) HCLK divided by 32
+#define AT91C_EMAC_CLK_HCLK_64 (0x3u << 10) // (EMAC) HCLK divided by 64
+#define AT91C_EMAC_RTY (0x1u << 12) // (EMAC)
+#define AT91C_EMAC_RMII (0x1u << 13) // (EMAC)
+// -------- EMAC_SR : (EMAC Offset: 0x8) Network Status Register --------
+#define AT91C_EMAC_MDIO (0x1u << 1) // (EMAC)
+#define AT91C_EMAC_IDLE (0x1u << 2) // (EMAC)
+// -------- EMAC_TCR : (EMAC Offset: 0x10) Transmit Control Register --------
+#define AT91C_EMAC_LEN (0x7FFu << 0) // (EMAC)
+#define AT91C_EMAC_NCRC (0x1u << 15) // (EMAC)
+// -------- EMAC_TSR : (EMAC Offset: 0x14) Transmit Control Register --------
+#define AT91C_EMAC_OVR (0x1u << 0) // (EMAC)
+#define AT91C_EMAC_COL (0x1u << 1) // (EMAC)
+#define AT91C_EMAC_RLE (0x1u << 2) // (EMAC)
+#define AT91C_EMAC_TXIDLE (0x1u << 3) // (EMAC)
+#define AT91C_EMAC_BNQ (0x1u << 4) // (EMAC)
+#define AT91C_EMAC_COMP (0x1u << 5) // (EMAC)
+#define AT91C_EMAC_UND (0x1u << 6) // (EMAC)
+// -------- EMAC_RSR : (EMAC Offset: 0x20) Receive Status Register --------
+#define AT91C_EMAC_BNA (0x1u << 0) // (EMAC)
+#define AT91C_EMAC_REC (0x1u << 1) // (EMAC)
+// -------- EMAC_ISR : (EMAC Offset: 0x24) Interrupt Status Register --------
+#define AT91C_EMAC_DONE (0x1u << 0) // (EMAC)
+#define AT91C_EMAC_RCOM (0x1u << 1) // (EMAC)
+#define AT91C_EMAC_RBNA (0x1u << 2) // (EMAC)
+#define AT91C_EMAC_TOVR (0x1u << 3) // (EMAC)
+#define AT91C_EMAC_TUND (0x1u << 4) // (EMAC)
+#define AT91C_EMAC_RTRY (0x1u << 5) // (EMAC)
+#define AT91C_EMAC_TBRE (0x1u << 6) // (EMAC)
+#define AT91C_EMAC_TCOM (0x1u << 7) // (EMAC)
+#define AT91C_EMAC_TIDLE (0x1u << 8) // (EMAC)
+#define AT91C_EMAC_LINK (0x1u << 9) // (EMAC)
+#define AT91C_EMAC_ROVR (0x1u << 10) // (EMAC)
+#define AT91C_EMAC_HRESP (0x1u << 11) // (EMAC)
+// -------- EMAC_IER : (EMAC Offset: 0x28) Interrupt Enable Register --------
+// -------- EMAC_IDR : (EMAC Offset: 0x2c) Interrupt Disable Register --------
+// -------- EMAC_IMR : (EMAC Offset: 0x30) Interrupt Mask Register --------
+// -------- EMAC_MAN : (EMAC Offset: 0x34) PHY Maintenance Register --------
+#define AT91C_EMAC_DATA (0xFFFFu << 0) // (EMAC)
+#define AT91C_EMAC_CODE (0x3u << 16) // (EMAC)
+#define AT91C_EMAC_REGA (0x1Fu << 18) // (EMAC)
+#define AT91C_EMAC_PHYA (0x1Fu << 23) // (EMAC)
+#define AT91C_EMAC_RW (0x3u << 28) // (EMAC)
+#define AT91C_EMAC_HIGH (0x1u << 30) // (EMAC)
+#define AT91C_EMAC_LOW (0x1u << 31) // (EMAC)
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR External Bus Interface
+// *****************************************************************************
+typedef struct _AT91S_EBI {
+ AT91_REG EBI_CSA; // Chip Select Assignment Register
+ AT91_REG EBI_CFGR; // Configuration Register
+} AT91S_EBI, *AT91PS_EBI;
+
+// -------- EBI_CSA : (EBI Offset: 0x0) Chip Select Assignment Register --------
+#define AT91C_EBI_CS0A (0x1u << 0) // (EBI) Chip Select 0 Assignment
+#define AT91C_EBI_CS0A_SMC 0x0u // (EBI) Chip Select 0 is assigned to the Static Memory Controller.
+#define AT91C_EBI_CS0A_BFC 0x1u // (EBI) Chip Select 0 is assigned to the Burst Flash Controller.
+#define AT91C_EBI_CS1A (0x1u << 1) // (EBI) Chip Select 1 Assignment
+#define AT91C_EBI_CS1A_SMC (0x0u << 1) // (EBI) Chip Select 1 is assigned to the Static Memory Controller.
+#define AT91C_EBI_CS1A_SDRAMC (0x1u << 1) // (EBI) Chip Select 1 is assigned to the SDRAM Controller.
+#define AT91C_EBI_CS3A (0x1u << 3) // (EBI) Chip Select 3 Assignment
+#define AT91C_EBI_CS3A_SMC (0x0u << 3) // (EBI) Chip Select 3 is only assigned to the Static Memory Controller and NCS3 behaves as defined by the SMC2.
+#define AT91C_EBI_CS3A_SMC_SmartMedia (0x1u << 3) // (EBI) Chip Select 3 is assigned to the Static Memory Controller and the SmartMedia Logic is activated.
+#define AT91C_EBI_CS4A (0x1u << 4) // (EBI) Chip Select 4 Assignment
+#define AT91C_EBI_CS4A_SMC (0x0u << 4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and NCS4,NCS5 and NCS6 behave as defined by the SMC2.
+#define AT91C_EBI_CS4A_SMC_CompactFlash (0x1u << 4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and the CompactFlash Logic is activated.
+// -------- EBI_CFGR : (EBI Offset: 0x4) Configuration Register --------
+#define AT91C_EBI_DBPUC (0x1u << 0) // (EBI) Data Bus Pull-Up Configuration
+#define AT91C_EBI_EBSEN (0x1u << 1) // (EBI) Bus Sharing Enable
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Static Memory Controller 2 Interface
+// *****************************************************************************
+typedef struct _AT91S_SMC2 {
+ AT91_REG SMC2_CSR[8]; // SMC2 Chip Select Register
+} AT91S_SMC2, *AT91PS_SMC2;
+
+// -------- SMC2_CSR : (SMC2 Offset: 0x0) SMC2 Chip Select Register --------
+#define AT91C_SMC2_NWS (0x7Fu << 0) // (SMC2) Number of Wait States
+#define AT91C_SMC2_WSEN (0x1u << 7) // (SMC2) Wait State Enable
+#define AT91C_SMC2_TDF (0xFu << 8) // (SMC2) Data Float Time
+#define AT91C_SMC2_BAT (0x1u << 12) // (SMC2) Byte Access Type
+#define AT91C_SMC2_DBW (0x1u << 13) // (SMC2) Data Bus Width
+#define AT91C_SMC2_DBW_16 (0x1u << 13) // (SMC2) 16-bit.
+#define AT91C_SMC2_DBW_8 (0x2u << 13) // (SMC2) 8-bit.
+#define AT91C_SMC2_DRP (0x1u << 15) // (SMC2) Data Read Protocol
+#define AT91C_SMC2_ACSS (0x3u << 16) // (SMC2) Address to Chip Select Setup
+#define AT91C_SMC2_ACSS_STANDARD (0x0u << 16) // (SMC2) Standard, asserted at the beginning of the access and deasserted at the end.
+#define AT91C_SMC2_ACSS_1_CYCLE (0x1u << 16) // (SMC2) One cycle less at the beginning and the end of the access.
+#define AT91C_SMC2_ACSS_2_CYCLES (0x2u << 16) // (SMC2) Two cycles less at the beginning and the end of the access.
+#define AT91C_SMC2_ACSS_3_CYCLES (0x3u << 16) // (SMC2) Three cycles less at the beginning and the end of the access.
+#define AT91C_SMC2_RWSETUP (0x7u << 24) // (SMC2) Read and Write Signal Setup Time
+#define AT91C_SMC2_RWHOLD (0x7u << 29) // (SMC2) Read and Write Signal Hold Time
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR SDRAM Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_SDRC {
+ AT91_REG SDRC_MR; // SDRAM Controller Mode Register
+ AT91_REG SDRC_TR; // SDRAM Controller Refresh Timer Register
+ AT91_REG SDRC_CR; // SDRAM Controller Configuration Register
+ AT91_REG SDRC_SRR; // SDRAM Controller Self Refresh Register
+ AT91_REG SDRC_LPR; // SDRAM Controller Low Power Register
+ AT91_REG SDRC_IER; // SDRAM Controller Interrupt Enable Register
+ AT91_REG SDRC_IDR; // SDRAM Controller Interrupt Disable Register
+ AT91_REG SDRC_IMR; // SDRAM Controller Interrupt Mask Register
+ AT91_REG SDRC_ISR; // SDRAM Controller Interrupt Mask Register
+} AT91S_SDRC, *AT91PS_SDRC;
+
+// -------- SDRC_MR : (SDRC Offset: 0x0) SDRAM Controller Mode Register --------
+#define AT91C_SDRC_MODE (0xFu << 0) // (SDRC) Mode
+#define AT91C_SDRC_MODE_NORMAL_CMD 0x0u // (SDRC) Normal Mode
+#define AT91C_SDRC_MODE_NOP_CMD 0x1u // (SDRC) NOP Command
+#define AT91C_SDRC_MODE_PRCGALL_CMD 0x2u // (SDRC) All Banks Precharge Command
+#define AT91C_SDRC_MODE_LMR_CMD 0x3u // (SDRC) Load Mode Register Command
+#define AT91C_SDRC_MODE_RFSH_CMD 0x4u // (SDRC) Refresh Command
+#define AT91C_SDRC_DBW (0x1u << 4) // (SDRC) Data Bus Width
+#define AT91C_SDRC_DBW_32_BITS (0x0u << 4) // (SDRC) 32 Bits datas bus
+#define AT91C_SDRC_DBW_16_BITS (0x1u << 4) // (SDRC) 16 Bits datas bus
+// -------- SDRC_TR : (SDRC Offset: 0x4) SDRC Refresh Timer Register --------
+#define AT91C_SDRC_COUNT (0xFFFu << 0) // (SDRC) Refresh Counter
+// -------- SDRC_CR : (SDRC Offset: 0x8) SDRAM Configuration Register --------
+#define AT91C_SDRC_NC (0x3u << 0) // (SDRC) Number of Column Bits
+#define AT91C_SDRC_NC_8 0x0u // (SDRC) 8 Bits
+#define AT91C_SDRC_NC_9 0x1u // (SDRC) 9 Bits
+#define AT91C_SDRC_NC_10 0x2u // (SDRC) 10 Bits
+#define AT91C_SDRC_NC_11 0x3u // (SDRC) 11 Bits
+#define AT91C_SDRC_NR (0x3u << 2) // (SDRC) Number of Row Bits
+#define AT91C_SDRC_NR_11 (0x0u << 2) // (SDRC) 11 Bits
+#define AT91C_SDRC_NR_12 (0x1u << 2) // (SDRC) 12 Bits
+#define AT91C_SDRC_NR_13 (0x2u << 2) // (SDRC) 13 Bits
+#define AT91C_SDRC_NB (0x1u << 4) // (SDRC) Number of Banks
+#define AT91C_SDRC_NB_2_BANKS (0x0u << 4) // (SDRC) 2 banks
+#define AT91C_SDRC_NB_4_BANKS (0x1u << 4) // (SDRC) 4 banks
+#define AT91C_SDRC_CAS (0x3u << 5) // (SDRC) CAS Latency
+#define AT91C_SDRC_CAS_2 (0x2u << 5) // (SDRC) 2 cycles
+#define AT91C_SDRC_TWR (0xFu << 7) // (SDRC) Number of Write Recovery Time Cycles
+#define AT91C_SDRC_TRC (0xFu << 11) // (SDRC) Number of RAS Cycle Time Cycles
+#define AT91C_SDRC_TRP (0xFu << 15) // (SDRC) Number of RAS Precharge Time Cycles
+#define AT91C_SDRC_TRCD (0xFu << 19) // (SDRC) Number of RAS to CAS Delay Cycles
+#define AT91C_SDRC_TRAS (0xFu << 23) // (SDRC) Number of RAS Active Time Cycles
+#define AT91C_SDRC_TXSR (0xFu << 27) // (SDRC) Number of Command Recovery Time Cycles
+// -------- SDRC_SRR : (SDRC Offset: 0xc) SDRAM Controller Self-refresh Register --------
+#define AT91C_SDRC_SRCB (0x1u << 0) // (SDRC) Self-refresh Command Bit
+// -------- SDRC_LPR : (SDRC Offset: 0x10) SDRAM Controller Low-power Register --------
+#define AT91C_SDRC_LPCB (0x1u << 0) // (SDRC) Low-power Command Bit
+// -------- SDRC_IER : (SDRC Offset: 0x14) SDRAM Controller Interrupt Enable Register --------
+#define AT91C_SDRC_RES (0x1u << 0) // (SDRC) Refresh Error Status
+// -------- SDRC_IDR : (SDRC Offset: 0x18) SDRAM Controller Interrupt Disable Register --------
+// -------- SDRC_IMR : (SDRC Offset: 0x1c) SDRAM Controller Interrupt Mask Register --------
+// -------- SDRC_ISR : (SDRC Offset: 0x20) SDRAM Controller Interrupt Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Burst Flash Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_BFC {
+ AT91_REG BFC_MR; // BFC Mode Register
+} AT91S_BFC, *AT91PS_BFC;
+
+// -------- BFC_MR : (BFC Offset: 0x0) BFC Mode Register --------
+#define AT91C_BFC_BFCOM (0x3u << 0) // (BFC) Burst Flash Controller Operating Mode
+#define AT91C_BFC_BFCOM_DISABLED 0x0u // (BFC) NPCS0 is driven by the SMC or remains high.
+#define AT91C_BFC_BFCOM_ASYNC 0x1u // (BFC) Asynchronous
+#define AT91C_BFC_BFCOM_BURST_READ 0x2u // (BFC) Burst Read
+#define AT91C_BFC_BFCC (0x3u << 2) // (BFC) Burst Flash Controller Operating Mode
+#define AT91C_BFC_BFCC_MCK (0x1u << 2) // (BFC) Master Clock.
+#define AT91C_BFC_BFCC_MCK_DIV_2 (0x2u << 2) // (BFC) Master Clock divided by 2.
+#define AT91C_BFC_BFCC_MCK_DIV_4 (0x3u << 2) // (BFC) Master Clock divided by 4.
+#define AT91C_BFC_AVL (0xFu << 4) // (BFC) Address Valid Latency
+#define AT91C_BFC_PAGES (0x7u << 8) // (BFC) Page Size
+#define AT91C_BFC_PAGES_NO_PAGE (0x0u << 8) // (BFC) No page handling.
+#define AT91C_BFC_PAGES_16 (0x1u << 8) // (BFC) 16 bytes page size.
+#define AT91C_BFC_PAGES_32 (0x2u << 8) // (BFC) 32 bytes page size.
+#define AT91C_BFC_PAGES_64 (0x3u << 8) // (BFC) 64 bytes page size.
+#define AT91C_BFC_PAGES_128 (0x4u << 8) // (BFC) 128 bytes page size.
+#define AT91C_BFC_PAGES_256 (0x5u << 8) // (BFC) 256 bytes page size.
+#define AT91C_BFC_PAGES_512 (0x6u << 8) // (BFC) 512 bytes page size.
+#define AT91C_BFC_PAGES_1024 (0x7u << 8) // (BFC) 1024 bytes page size.
+#define AT91C_BFC_OEL (0x3u << 12) // (BFC) Output Enable Latency
+#define AT91C_BFC_BAAEN (0x1u << 16) // (BFC) Burst Address Advance Enable
+#define AT91C_BFC_BFOEH (0x1u << 17) // (BFC) Burst Flash Output Enable Handling
+#define AT91C_BFC_MUXEN (0x1u << 18) // (BFC) Multiplexed Bus Enable
+#define AT91C_BFC_RDYEN (0x1u << 19) // (BFC) Ready Enable Mode
+
+// *****************************************************************************
+// REGISTER ADDRESS DEFINITION FOR AT91RM9200
+// *****************************************************************************
+// ========== Register definition for SYS peripheral ==========
+// ========== Register definition for MC peripheral ==========
+#define AT91C_MC_PUER ((AT91_REG *) 0xFFFFFF54) // (MC) MC Protection Unit Enable Register
+#define AT91C_MC_ASR ((AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register
+#define AT91C_MC_PUP ((AT91_REG *) 0xFFFFFF50) // (MC) MC Protection Unit Peripherals
+#define AT91C_MC_PUIA ((AT91_REG *) 0xFFFFFF10) // (MC) MC Protection Unit Area
+#define AT91C_MC_AASR ((AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register
+#define AT91C_MC_RCR ((AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register
+// ========== Register definition for RTC peripheral ==========
+#define AT91C_RTC_IMR ((AT91_REG *) 0xFFFFFE28) // (RTC) Interrupt Mask Register
+#define AT91C_RTC_IER ((AT91_REG *) 0xFFFFFE20) // (RTC) Interrupt Enable Register
+#define AT91C_RTC_SR ((AT91_REG *) 0xFFFFFE18) // (RTC) Status Register
+#define AT91C_RTC_TIMALR ((AT91_REG *) 0xFFFFFE10) // (RTC) Time Alarm Register
+#define AT91C_RTC_TIMR ((AT91_REG *) 0xFFFFFE08) // (RTC) Time Register
+#define AT91C_RTC_CR ((AT91_REG *) 0xFFFFFE00) // (RTC) Control Register
+#define AT91C_RTC_VER ((AT91_REG *) 0xFFFFFE2C) // (RTC) Valid Entry Register
+#define AT91C_RTC_IDR ((AT91_REG *) 0xFFFFFE24) // (RTC) Interrupt Disable Register
+#define AT91C_RTC_SCCR ((AT91_REG *) 0xFFFFFE1C) // (RTC) Status Clear Command Register
+#define AT91C_RTC_CALALR ((AT91_REG *) 0xFFFFFE14) // (RTC) Calendar Alarm Register
+#define AT91C_RTC_CALR ((AT91_REG *) 0xFFFFFE0C) // (RTC) Calendar Register
+#define AT91C_RTC_MR ((AT91_REG *) 0xFFFFFE04) // (RTC) Mode Register
+// ========== Register definition for ST peripheral ==========
+#define AT91C_ST_CRTR ((AT91_REG *) 0xFFFFFD24) // (ST) Current Real-time Register
+#define AT91C_ST_IMR ((AT91_REG *) 0xFFFFFD1C) // (ST) Interrupt Mask Register
+#define AT91C_ST_IER ((AT91_REG *) 0xFFFFFD14) // (ST) Interrupt Enable Register
+#define AT91C_ST_RTMR ((AT91_REG *) 0xFFFFFD0C) // (ST) Real-time Mode Register
+#define AT91C_ST_PIMR ((AT91_REG *) 0xFFFFFD04) // (ST) Period Interval Mode Register
+#define AT91C_ST_RTAR ((AT91_REG *) 0xFFFFFD20) // (ST) Real-time Alarm Register
+#define AT91C_ST_IDR ((AT91_REG *) 0xFFFFFD18) // (ST) Interrupt Disable Register
+#define AT91C_ST_SR ((AT91_REG *) 0xFFFFFD10) // (ST) Status Register
+#define AT91C_ST_WDMR ((AT91_REG *) 0xFFFFFD08) // (ST) Watchdog Mode Register
+#define AT91C_ST_CR ((AT91_REG *) 0xFFFFFD00) // (ST) Control Register
+// ========== Register definition for PMC peripheral ==========
+#define AT91C_PMC_SCSR ((AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register
+#define AT91C_PMC_SCER ((AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register
+#define AT91C_PMC_IMR ((AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register
+#define AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register
+#define AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register
+#define AT91C_PMC_SCDR ((AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register
+#define AT91C_PMC_SR ((AT91_REG *) 0xFFFFFC68) // (PMC) Status Register
+#define AT91C_PMC_IER ((AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register
+#define AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register
+#define AT91C_PMC_PCSR ((AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register
+#define AT91C_PMC_PCKR ((AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register
+// ========== Register definition for CKGR peripheral ==========
+#define AT91C_CKGR_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL B Register
+#define AT91C_CKGR_MCFR ((AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register
+#define AT91C_CKGR_PLLAR ((AT91_REG *) 0xFFFFFC28) // (CKGR) PLL A Register
+#define AT91C_CKGR_MOR ((AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register
+// ========== Register definition for PIOD peripheral ==========
+#define AT91C_PIOD_PDSR ((AT91_REG *) 0xFFFFFA3C) // (PIOD) Pin Data Status Register
+#define AT91C_PIOD_CODR ((AT91_REG *) 0xFFFFFA34) // (PIOD) Clear Output Data Register
+#define AT91C_PIOD_OWER ((AT91_REG *) 0xFFFFFAA0) // (PIOD) Output Write Enable Register
+#define AT91C_PIOD_MDER ((AT91_REG *) 0xFFFFFA50) // (PIOD) Multi-driver Enable Register
+#define AT91C_PIOD_IMR ((AT91_REG *) 0xFFFFFA48) // (PIOD) Interrupt Mask Register
+#define AT91C_PIOD_IER ((AT91_REG *) 0xFFFFFA40) // (PIOD) Interrupt Enable Register
+#define AT91C_PIOD_ODSR ((AT91_REG *) 0xFFFFFA38) // (PIOD) Output Data Status Register
+#define AT91C_PIOD_SODR ((AT91_REG *) 0xFFFFFA30) // (PIOD) Set Output Data Register
+#define AT91C_PIOD_PER ((AT91_REG *) 0xFFFFFA00) // (PIOD) PIO Enable Register
+#define AT91C_PIOD_OWDR ((AT91_REG *) 0xFFFFFAA4) // (PIOD) Output Write Disable Register
+#define AT91C_PIOD_PPUER ((AT91_REG *) 0xFFFFFA64) // (PIOD) Pull-up Enable Register
+#define AT91C_PIOD_MDDR ((AT91_REG *) 0xFFFFFA54) // (PIOD) Multi-driver Disable Register
+#define AT91C_PIOD_ISR ((AT91_REG *) 0xFFFFFA4C) // (PIOD) Interrupt Status Register
+#define AT91C_PIOD_IDR ((AT91_REG *) 0xFFFFFA44) // (PIOD) Interrupt Disable Register
+#define AT91C_PIOD_PDR ((AT91_REG *) 0xFFFFFA04) // (PIOD) PIO Disable Register
+#define AT91C_PIOD_ODR ((AT91_REG *) 0xFFFFFA14) // (PIOD) Output Disable Registerr
+#define AT91C_PIOD_OWSR ((AT91_REG *) 0xFFFFFAA8) // (PIOD) Output Write Status Register
+#define AT91C_PIOD_ABSR ((AT91_REG *) 0xFFFFFA78) // (PIOD) AB Select Status Register
+#define AT91C_PIOD_ASR ((AT91_REG *) 0xFFFFFA70) // (PIOD) Select A Register
+#define AT91C_PIOD_PPUSR ((AT91_REG *) 0xFFFFFA68) // (PIOD) Pad Pull-up Status Register
+#define AT91C_PIOD_PPUDR ((AT91_REG *) 0xFFFFFA60) // (PIOD) Pull-up Disable Register
+#define AT91C_PIOD_MDSR ((AT91_REG *) 0xFFFFFA58) // (PIOD) Multi-driver Status Register
+#define AT91C_PIOD_PSR ((AT91_REG *) 0xFFFFFA08) // (PIOD) PIO Status Register
+#define AT91C_PIOD_OER ((AT91_REG *) 0xFFFFFA10) // (PIOD) Output Enable Register
+#define AT91C_PIOD_OSR ((AT91_REG *) 0xFFFFFA18) // (PIOD) Output Status Register
+#define AT91C_PIOD_IFER ((AT91_REG *) 0xFFFFFA20) // (PIOD) Input Filter Enable Register
+#define AT91C_PIOD_BSR ((AT91_REG *) 0xFFFFFA74) // (PIOD) Select B Register
+#define AT91C_PIOD_IFDR ((AT91_REG *) 0xFFFFFA24) // (PIOD) Input Filter Disable Register
+#define AT91C_PIOD_IFSR ((AT91_REG *) 0xFFFFFA28) // (PIOD) Input Filter Status Register
+// ========== Register definition for PIOC peripheral ==========
+#define AT91C_PIOC_IFDR ((AT91_REG *) 0xFFFFF824) // (PIOC) Input Filter Disable Register
+#define AT91C_PIOC_ODR ((AT91_REG *) 0xFFFFF814) // (PIOC) Output Disable Registerr
+#define AT91C_PIOC_ABSR ((AT91_REG *) 0xFFFFF878) // (PIOC) AB Select Status Register
+#define AT91C_PIOC_SODR ((AT91_REG *) 0xFFFFF830) // (PIOC) Set Output Data Register
+#define AT91C_PIOC_IFSR ((AT91_REG *) 0xFFFFF828) // (PIOC) Input Filter Status Register
+#define AT91C_PIOC_CODR ((AT91_REG *) 0xFFFFF834) // (PIOC) Clear Output Data Register
+#define AT91C_PIOC_ODSR ((AT91_REG *) 0xFFFFF838) // (PIOC) Output Data Status Register
+#define AT91C_PIOC_IER ((AT91_REG *) 0xFFFFF840) // (PIOC) Interrupt Enable Register
+#define AT91C_PIOC_IMR ((AT91_REG *) 0xFFFFF848) // (PIOC) Interrupt Mask Register
+#define AT91C_PIOC_OWDR ((AT91_REG *) 0xFFFFF8A4) // (PIOC) Output Write Disable Register
+#define AT91C_PIOC_MDDR ((AT91_REG *) 0xFFFFF854) // (PIOC) Multi-driver Disable Register
+#define AT91C_PIOC_PDSR ((AT91_REG *) 0xFFFFF83C) // (PIOC) Pin Data Status Register
+#define AT91C_PIOC_IDR ((AT91_REG *) 0xFFFFF844) // (PIOC) Interrupt Disable Register
+#define AT91C_PIOC_ISR ((AT91_REG *) 0xFFFFF84C) // (PIOC) Interrupt Status Register
+#define AT91C_PIOC_PDR ((AT91_REG *) 0xFFFFF804) // (PIOC) PIO Disable Register
+#define AT91C_PIOC_OWSR ((AT91_REG *) 0xFFFFF8A8) // (PIOC) Output Write Status Register
+#define AT91C_PIOC_OWER ((AT91_REG *) 0xFFFFF8A0) // (PIOC) Output Write Enable Register
+#define AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register
+#define AT91C_PIOC_PPUSR ((AT91_REG *) 0xFFFFF868) // (PIOC) Pad Pull-up Status Register
+#define AT91C_PIOC_PPUDR ((AT91_REG *) 0xFFFFF860) // (PIOC) Pull-up Disable Register
+#define AT91C_PIOC_MDSR ((AT91_REG *) 0xFFFFF858) // (PIOC) Multi-driver Status Register
+#define AT91C_PIOC_MDER ((AT91_REG *) 0xFFFFF850) // (PIOC) Multi-driver Enable Register
+#define AT91C_PIOC_IFER ((AT91_REG *) 0xFFFFF820) // (PIOC) Input Filter Enable Register
+#define AT91C_PIOC_OSR ((AT91_REG *) 0xFFFFF818) // (PIOC) Output Status Register
+#define AT91C_PIOC_OER ((AT91_REG *) 0xFFFFF810) // (PIOC) Output Enable Register
+#define AT91C_PIOC_PSR ((AT91_REG *) 0xFFFFF808) // (PIOC) PIO Status Register
+#define AT91C_PIOC_PER ((AT91_REG *) 0xFFFFF800) // (PIOC) PIO Enable Register
+#define AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register
+#define AT91C_PIOC_PPUER ((AT91_REG *) 0xFFFFF864) // (PIOC) Pull-up Enable Register
+// ========== Register definition for PIOB peripheral ==========
+#define AT91C_PIOB_OWSR ((AT91_REG *) 0xFFFFF6A8) // (PIOB) Output Write Status Register
+#define AT91C_PIOB_PPUSR ((AT91_REG *) 0xFFFFF668) // (PIOB) Pad Pull-up Status Register
+#define AT91C_PIOB_PPUDR ((AT91_REG *) 0xFFFFF660) // (PIOB) Pull-up Disable Register
+#define AT91C_PIOB_MDSR ((AT91_REG *) 0xFFFFF658) // (PIOB) Multi-driver Status Register
+#define AT91C_PIOB_MDER ((AT91_REG *) 0xFFFFF650) // (PIOB) Multi-driver Enable Register
+#define AT91C_PIOB_IMR ((AT91_REG *) 0xFFFFF648) // (PIOB) Interrupt Mask Register
+#define AT91C_PIOB_OSR ((AT91_REG *) 0xFFFFF618) // (PIOB) Output Status Register
+#define AT91C_PIOB_OER ((AT91_REG *) 0xFFFFF610) // (PIOB) Output Enable Register
+#define AT91C_PIOB_PSR ((AT91_REG *) 0xFFFFF608) // (PIOB) PIO Status Register
+#define AT91C_PIOB_PER ((AT91_REG *) 0xFFFFF600) // (PIOB) PIO Enable Register
+#define AT91C_PIOB_BSR ((AT91_REG *) 0xFFFFF674) // (PIOB) Select B Register
+#define AT91C_PIOB_PPUER ((AT91_REG *) 0xFFFFF664) // (PIOB) Pull-up Enable Register
+#define AT91C_PIOB_IFDR ((AT91_REG *) 0xFFFFF624) // (PIOB) Input Filter Disable Register
+#define AT91C_PIOB_ODR ((AT91_REG *) 0xFFFFF614) // (PIOB) Output Disable Registerr
+#define AT91C_PIOB_ABSR ((AT91_REG *) 0xFFFFF678) // (PIOB) AB Select Status Register
+#define AT91C_PIOB_ASR ((AT91_REG *) 0xFFFFF670) // (PIOB) Select A Register
+#define AT91C_PIOB_IFER ((AT91_REG *) 0xFFFFF620) // (PIOB) Input Filter Enable Register
+#define AT91C_PIOB_IFSR ((AT91_REG *) 0xFFFFF628) // (PIOB) Input Filter Status Register
+#define AT91C_PIOB_SODR ((AT91_REG *) 0xFFFFF630) // (PIOB) Set Output Data Register
+#define AT91C_PIOB_ODSR ((AT91_REG *) 0xFFFFF638) // (PIOB) Output Data Status Register
+#define AT91C_PIOB_CODR ((AT91_REG *) 0xFFFFF634) // (PIOB) Clear Output Data Register
+#define AT91C_PIOB_PDSR ((AT91_REG *) 0xFFFFF63C) // (PIOB) Pin Data Status Register
+#define AT91C_PIOB_OWER ((AT91_REG *) 0xFFFFF6A0) // (PIOB) Output Write Enable Register
+#define AT91C_PIOB_IER ((AT91_REG *) 0xFFFFF640) // (PIOB) Interrupt Enable Register
+#define AT91C_PIOB_OWDR ((AT91_REG *) 0xFFFFF6A4) // (PIOB) Output Write Disable Register
+#define AT91C_PIOB_MDDR ((AT91_REG *) 0xFFFFF654) // (PIOB) Multi-driver Disable Register
+#define AT91C_PIOB_ISR ((AT91_REG *) 0xFFFFF64C) // (PIOB) Interrupt Status Register
+#define AT91C_PIOB_IDR ((AT91_REG *) 0xFFFFF644) // (PIOB) Interrupt Disable Register
+#define AT91C_PIOB_PDR ((AT91_REG *) 0xFFFFF604) // (PIOB) PIO Disable Register
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_IMR ((AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_IER ((AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_OWDR ((AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_ISR ((AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_PPUDR ((AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_MDSR ((AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_MDER ((AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PER ((AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_PSR ((AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register
+#define AT91C_PIOA_OER ((AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register
+#define AT91C_PIOA_BSR ((AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register
+#define AT91C_PIOA_PPUER ((AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_MDDR ((AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_ODR ((AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_IFDR ((AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_ABSR ((AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_ASR ((AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register
+#define AT91C_PIOA_PPUSR ((AT91_REG *) 0xFFFFF468) // (PIOA) Pad Pull-up Status Register
+#define AT91C_PIOA_ODSR ((AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_SODR ((AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_IFSR ((AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_IFER ((AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_OSR ((AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register
+#define AT91C_PIOA_IDR ((AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_PDSR ((AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_CODR ((AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_OWSR ((AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_OWER ((AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register
+// ========== Register definition for DBGU peripheral ==========
+#define AT91C_DBGU_C2R ((AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID2 Register
+#define AT91C_DBGU_THR ((AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register
+#define AT91C_DBGU_CSR ((AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register
+#define AT91C_DBGU_IDR ((AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register
+#define AT91C_DBGU_MR ((AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register
+#define AT91C_DBGU_FNTR ((AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register
+#define AT91C_DBGU_C1R ((AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID1 Register
+#define AT91C_DBGU_BRGR ((AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register
+#define AT91C_DBGU_RHR ((AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register
+#define AT91C_DBGU_IMR ((AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register
+#define AT91C_DBGU_IER ((AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register
+#define AT91C_DBGU_CR ((AT91_REG *) 0xFFFFF200) // (DBGU) Control Register
+// ========== Register definition for PDC_DBGU peripheral ==========
+#define AT91C_DBGU_TNCR ((AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register
+#define AT91C_DBGU_RNCR ((AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register
+#define AT91C_DBGU_PTCR ((AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register
+#define AT91C_DBGU_PTSR ((AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register
+#define AT91C_DBGU_RCR ((AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register
+#define AT91C_DBGU_TCR ((AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register
+#define AT91C_DBGU_RPR ((AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register
+#define AT91C_DBGU_TPR ((AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register
+#define AT91C_DBGU_RNPR ((AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register
+#define AT91C_DBGU_TNPR ((AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register
+// ========== Register definition for AIC peripheral ==========
+#define AT91C_AIC_ICCR ((AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register
+#define AT91C_AIC_IECR ((AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register
+#define AT91C_AIC_SMR ((AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register
+#define AT91C_AIC_ISCR ((AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register
+#define AT91C_AIC_EOICR ((AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register
+#define AT91C_AIC_DCR ((AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect)
+#define AT91C_AIC_FFER ((AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register
+#define AT91C_AIC_SVR ((AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register
+#define AT91C_AIC_SPU ((AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register
+#define AT91C_AIC_FFDR ((AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register
+#define AT91C_AIC_FVR ((AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register
+#define AT91C_AIC_FFSR ((AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register
+#define AT91C_AIC_IMR ((AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register
+#define AT91C_AIC_ISR ((AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register
+#define AT91C_AIC_IVR ((AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register
+#define AT91C_AIC_IDCR ((AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register
+#define AT91C_AIC_CISR ((AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register
+#define AT91C_AIC_IPR ((AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register
+// ========== Register definition for PDC_SPI peripheral ==========
+#define AT91C_SPI_PTCR ((AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register
+#define AT91C_SPI_TNPR ((AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register
+#define AT91C_SPI_RNPR ((AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register
+#define AT91C_SPI_TPR ((AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register
+#define AT91C_SPI_RPR ((AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register
+#define AT91C_SPI_PTSR ((AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register
+#define AT91C_SPI_TNCR ((AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register
+#define AT91C_SPI_RNCR ((AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register
+#define AT91C_SPI_TCR ((AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register
+#define AT91C_SPI_RCR ((AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register
+// ========== Register definition for SPI peripheral ==========
+#define AT91C_SPI_CSR ((AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register
+#define AT91C_SPI_IDR ((AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register
+#define AT91C_SPI_SR ((AT91_REG *) 0xFFFE0010) // (SPI) Status Register
+#define AT91C_SPI_RDR ((AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register
+#define AT91C_SPI_CR ((AT91_REG *) 0xFFFE0000) // (SPI) Control Register
+#define AT91C_SPI_IMR ((AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register
+#define AT91C_SPI_IER ((AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register
+#define AT91C_SPI_TDR ((AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register
+#define AT91C_SPI_MR ((AT91_REG *) 0xFFFE0004) // (SPI) Mode Register
+// ========== Register definition for PDC_SSC2 peripheral ==========
+#define AT91C_SSC2_PTCR ((AT91_REG *) 0xFFFD8120) // (PDC_SSC2) PDC Transfer Control Register
+#define AT91C_SSC2_TNPR ((AT91_REG *) 0xFFFD8118) // (PDC_SSC2) Transmit Next Pointer Register
+#define AT91C_SSC2_RNPR ((AT91_REG *) 0xFFFD8110) // (PDC_SSC2) Receive Next Pointer Register
+#define AT91C_SSC2_TPR ((AT91_REG *) 0xFFFD8108) // (PDC_SSC2) Transmit Pointer Register
+#define AT91C_SSC2_RPR ((AT91_REG *) 0xFFFD8100) // (PDC_SSC2) Receive Pointer Register
+#define AT91C_SSC2_PTSR ((AT91_REG *) 0xFFFD8124) // (PDC_SSC2) PDC Transfer Status Register
+#define AT91C_SSC2_TNCR ((AT91_REG *) 0xFFFD811C) // (PDC_SSC2) Transmit Next Counter Register
+#define AT91C_SSC2_RNCR ((AT91_REG *) 0xFFFD8114) // (PDC_SSC2) Receive Next Counter Register
+#define AT91C_SSC2_TCR ((AT91_REG *) 0xFFFD810C) // (PDC_SSC2) Transmit Counter Register
+#define AT91C_SSC2_RCR ((AT91_REG *) 0xFFFD8104) // (PDC_SSC2) Receive Counter Register
+// ========== Register definition for SSC2 peripheral ==========
+#define AT91C_SSC2_IMR ((AT91_REG *) 0xFFFD804C) // (SSC2) Interrupt Mask Register
+#define AT91C_SSC2_IER ((AT91_REG *) 0xFFFD8044) // (SSC2) Interrupt Enable Register
+#define AT91C_SSC2_RC1R ((AT91_REG *) 0xFFFD803C) // (SSC2) Receive Compare 1 Register
+#define AT91C_SSC2_TSHR ((AT91_REG *) 0xFFFD8034) // (SSC2) Transmit Sync Holding Register
+#define AT91C_SSC2_CMR ((AT91_REG *) 0xFFFD8004) // (SSC2) Clock Mode Register
+#define AT91C_SSC2_IDR ((AT91_REG *) 0xFFFD8048) // (SSC2) Interrupt Disable Register
+#define AT91C_SSC2_TCMR ((AT91_REG *) 0xFFFD8018) // (SSC2) Transmit Clock Mode Register
+#define AT91C_SSC2_RCMR ((AT91_REG *) 0xFFFD8010) // (SSC2) Receive Clock ModeRegister
+#define AT91C_SSC2_CR ((AT91_REG *) 0xFFFD8000) // (SSC2) Control Register
+#define AT91C_SSC2_RFMR ((AT91_REG *) 0xFFFD8014) // (SSC2) Receive Frame Mode Register
+#define AT91C_SSC2_TFMR ((AT91_REG *) 0xFFFD801C) // (SSC2) Transmit Frame Mode Register
+#define AT91C_SSC2_THR ((AT91_REG *) 0xFFFD8024) // (SSC2) Transmit Holding Register
+#define AT91C_SSC2_SR ((AT91_REG *) 0xFFFD8040) // (SSC2) Status Register
+#define AT91C_SSC2_RC0R ((AT91_REG *) 0xFFFD8038) // (SSC2) Receive Compare 0 Register
+#define AT91C_SSC2_RSHR ((AT91_REG *) 0xFFFD8030) // (SSC2) Receive Sync Holding Register
+#define AT91C_SSC2_RHR ((AT91_REG *) 0xFFFD8020) // (SSC2) Receive Holding Register
+// ========== Register definition for PDC_SSC1 peripheral ==========
+#define AT91C_SSC1_PTCR ((AT91_REG *) 0xFFFD4120) // (PDC_SSC1) PDC Transfer Control Register
+#define AT91C_SSC1_TNPR ((AT91_REG *) 0xFFFD4118) // (PDC_SSC1) Transmit Next Pointer Register
+#define AT91C_SSC1_RNPR ((AT91_REG *) 0xFFFD4110) // (PDC_SSC1) Receive Next Pointer Register
+#define AT91C_SSC1_TPR ((AT91_REG *) 0xFFFD4108) // (PDC_SSC1) Transmit Pointer Register
+#define AT91C_SSC1_RPR ((AT91_REG *) 0xFFFD4100) // (PDC_SSC1) Receive Pointer Register
+#define AT91C_SSC1_PTSR ((AT91_REG *) 0xFFFD4124) // (PDC_SSC1) PDC Transfer Status Register
+#define AT91C_SSC1_TNCR ((AT91_REG *) 0xFFFD411C) // (PDC_SSC1) Transmit Next Counter Register
+#define AT91C_SSC1_RNCR ((AT91_REG *) 0xFFFD4114) // (PDC_SSC1) Receive Next Counter Register
+#define AT91C_SSC1_TCR ((AT91_REG *) 0xFFFD410C) // (PDC_SSC1) Transmit Counter Register
+#define AT91C_SSC1_RCR ((AT91_REG *) 0xFFFD4104) // (PDC_SSC1) Receive Counter Register
+// ========== Register definition for SSC1 peripheral ==========
+#define AT91C_SSC1_RFMR ((AT91_REG *) 0xFFFD4014) // (SSC1) Receive Frame Mode Register
+#define AT91C_SSC1_CMR ((AT91_REG *) 0xFFFD4004) // (SSC1) Clock Mode Register
+#define AT91C_SSC1_IDR ((AT91_REG *) 0xFFFD4048) // (SSC1) Interrupt Disable Register
+#define AT91C_SSC1_SR ((AT91_REG *) 0xFFFD4040) // (SSC1) Status Register
+#define AT91C_SSC1_RC0R ((AT91_REG *) 0xFFFD4038) // (SSC1) Receive Compare 0 Register
+#define AT91C_SSC1_RSHR ((AT91_REG *) 0xFFFD4030) // (SSC1) Receive Sync Holding Register
+#define AT91C_SSC1_RHR ((AT91_REG *) 0xFFFD4020) // (SSC1) Receive Holding Register
+#define AT91C_SSC1_TCMR ((AT91_REG *) 0xFFFD4018) // (SSC1) Transmit Clock Mode Register
+#define AT91C_SSC1_RCMR ((AT91_REG *) 0xFFFD4010) // (SSC1) Receive Clock ModeRegister
+#define AT91C_SSC1_CR ((AT91_REG *) 0xFFFD4000) // (SSC1) Control Register
+#define AT91C_SSC1_IMR ((AT91_REG *) 0xFFFD404C) // (SSC1) Interrupt Mask Register
+#define AT91C_SSC1_IER ((AT91_REG *) 0xFFFD4044) // (SSC1) Interrupt Enable Register
+#define AT91C_SSC1_RC1R ((AT91_REG *) 0xFFFD403C) // (SSC1) Receive Compare 1 Register
+#define AT91C_SSC1_TSHR ((AT91_REG *) 0xFFFD4034) // (SSC1) Transmit Sync Holding Register
+#define AT91C_SSC1_THR ((AT91_REG *) 0xFFFD4024) // (SSC1) Transmit Holding Register
+#define AT91C_SSC1_TFMR ((AT91_REG *) 0xFFFD401C) // (SSC1) Transmit Frame Mode Register
+// ========== Register definition for PDC_SSC0 peripheral ==========
+#define AT91C_SSC0_PTCR ((AT91_REG *) 0xFFFD0120) // (PDC_SSC0) PDC Transfer Control Register
+#define AT91C_SSC0_TNPR ((AT91_REG *) 0xFFFD0118) // (PDC_SSC0) Transmit Next Pointer Register
+#define AT91C_SSC0_RNPR ((AT91_REG *) 0xFFFD0110) // (PDC_SSC0) Receive Next Pointer Register
+#define AT91C_SSC0_TPR ((AT91_REG *) 0xFFFD0108) // (PDC_SSC0) Transmit Pointer Register
+#define AT91C_SSC0_RPR ((AT91_REG *) 0xFFFD0100) // (PDC_SSC0) Receive Pointer Register
+#define AT91C_SSC0_PTSR ((AT91_REG *) 0xFFFD0124) // (PDC_SSC0) PDC Transfer Status Register
+#define AT91C_SSC0_TNCR ((AT91_REG *) 0xFFFD011C) // (PDC_SSC0) Transmit Next Counter Register
+#define AT91C_SSC0_RNCR ((AT91_REG *) 0xFFFD0114) // (PDC_SSC0) Receive Next Counter Register
+#define AT91C_SSC0_TCR ((AT91_REG *) 0xFFFD010C) // (PDC_SSC0) Transmit Counter Register
+#define AT91C_SSC0_RCR ((AT91_REG *) 0xFFFD0104) // (PDC_SSC0) Receive Counter Register
+// ========== Register definition for SSC0 peripheral ==========
+#define AT91C_SSC0_IMR ((AT91_REG *) 0xFFFD004C) // (SSC0) Interrupt Mask Register
+#define AT91C_SSC0_IER ((AT91_REG *) 0xFFFD0044) // (SSC0) Interrupt Enable Register
+#define AT91C_SSC0_RC1R ((AT91_REG *) 0xFFFD003C) // (SSC0) Receive Compare 1 Register
+#define AT91C_SSC0_TSHR ((AT91_REG *) 0xFFFD0034) // (SSC0) Transmit Sync Holding Register
+#define AT91C_SSC0_THR ((AT91_REG *) 0xFFFD0024) // (SSC0) Transmit Holding Register
+#define AT91C_SSC0_TFMR ((AT91_REG *) 0xFFFD001C) // (SSC0) Transmit Frame Mode Register
+#define AT91C_SSC0_RFMR ((AT91_REG *) 0xFFFD0014) // (SSC0) Receive Frame Mode Register
+#define AT91C_SSC0_CMR ((AT91_REG *) 0xFFFD0004) // (SSC0) Clock Mode Register
+#define AT91C_SSC0_IDR ((AT91_REG *) 0xFFFD0048) // (SSC0) Interrupt Disable Register
+#define AT91C_SSC0_SR ((AT91_REG *) 0xFFFD0040) // (SSC0) Status Register
+#define AT91C_SSC0_RC0R ((AT91_REG *) 0xFFFD0038) // (SSC0) Receive Compare 0 Register
+#define AT91C_SSC0_RSHR ((AT91_REG *) 0xFFFD0030) // (SSC0) Receive Sync Holding Register
+#define AT91C_SSC0_RHR ((AT91_REG *) 0xFFFD0020) // (SSC0) Receive Holding Register
+#define AT91C_SSC0_TCMR ((AT91_REG *) 0xFFFD0018) // (SSC0) Transmit Clock Mode Register
+#define AT91C_SSC0_RCMR ((AT91_REG *) 0xFFFD0010) // (SSC0) Receive Clock ModeRegister
+#define AT91C_SSC0_CR ((AT91_REG *) 0xFFFD0000) // (SSC0) Control Register
+// ========== Register definition for PDC_US3 peripheral ==========
+#define AT91C_US3_PTSR ((AT91_REG *) 0xFFFCC124) // (PDC_US3) PDC Transfer Status Register
+#define AT91C_US3_TNCR ((AT91_REG *) 0xFFFCC11C) // (PDC_US3) Transmit Next Counter Register
+#define AT91C_US3_RNCR ((AT91_REG *) 0xFFFCC114) // (PDC_US3) Receive Next Counter Register
+#define AT91C_US3_TCR ((AT91_REG *) 0xFFFCC10C) // (PDC_US3) Transmit Counter Register
+#define AT91C_US3_RCR ((AT91_REG *) 0xFFFCC104) // (PDC_US3) Receive Counter Register
+#define AT91C_US3_PTCR ((AT91_REG *) 0xFFFCC120) // (PDC_US3) PDC Transfer Control Register
+#define AT91C_US3_TNPR ((AT91_REG *) 0xFFFCC118) // (PDC_US3) Transmit Next Pointer Register
+#define AT91C_US3_RNPR ((AT91_REG *) 0xFFFCC110) // (PDC_US3) Receive Next Pointer Register
+#define AT91C_US3_TPR ((AT91_REG *) 0xFFFCC108) // (PDC_US3) Transmit Pointer Register
+#define AT91C_US3_RPR ((AT91_REG *) 0xFFFCC100) // (PDC_US3) Receive Pointer Register
+// ========== Register definition for US3 peripheral ==========
+#define AT91C_US3_IF ((AT91_REG *) 0xFFFCC04C) // (US3) IRDA_FILTER Register
+#define AT91C_US3_NER ((AT91_REG *) 0xFFFCC044) // (US3) Nb Errors Register
+#define AT91C_US3_RTOR ((AT91_REG *) 0xFFFCC024) // (US3) Receiver Time-out Register
+#define AT91C_US3_THR ((AT91_REG *) 0xFFFCC01C) // (US3) Transmitter Holding Register
+#define AT91C_US3_CSR ((AT91_REG *) 0xFFFCC014) // (US3) Channel Status Register
+#define AT91C_US3_IDR ((AT91_REG *) 0xFFFCC00C) // (US3) Interrupt Disable Register
+#define AT91C_US3_MR ((AT91_REG *) 0xFFFCC004) // (US3) Mode Register
+#define AT91C_US3_XXR ((AT91_REG *) 0xFFFCC048) // (US3) XON_XOFF Register
+#define AT91C_US3_FIDI ((AT91_REG *) 0xFFFCC040) // (US3) FI_DI_Ratio Register
+#define AT91C_US3_TTGR ((AT91_REG *) 0xFFFCC028) // (US3) Transmitter Time-guard Register
+#define AT91C_US3_BRGR ((AT91_REG *) 0xFFFCC020) // (US3) Baud Rate Generator Register
+#define AT91C_US3_RHR ((AT91_REG *) 0xFFFCC018) // (US3) Receiver Holding Register
+#define AT91C_US3_IMR ((AT91_REG *) 0xFFFCC010) // (US3) Interrupt Mask Register
+#define AT91C_US3_IER ((AT91_REG *) 0xFFFCC008) // (US3) Interrupt Enable Register
+#define AT91C_US3_CR ((AT91_REG *) 0xFFFCC000) // (US3) Control Register
+// ========== Register definition for PDC_US2 peripheral ==========
+#define AT91C_US2_PTSR ((AT91_REG *) 0xFFFC8124) // (PDC_US2) PDC Transfer Status Register
+#define AT91C_US2_TNCR ((AT91_REG *) 0xFFFC811C) // (PDC_US2) Transmit Next Counter Register
+#define AT91C_US2_RNCR ((AT91_REG *) 0xFFFC8114) // (PDC_US2) Receive Next Counter Register
+#define AT91C_US2_TCR ((AT91_REG *) 0xFFFC810C) // (PDC_US2) Transmit Counter Register
+#define AT91C_US2_PTCR ((AT91_REG *) 0xFFFC8120) // (PDC_US2) PDC Transfer Control Register
+#define AT91C_US2_RCR ((AT91_REG *) 0xFFFC8104) // (PDC_US2) Receive Counter Register
+#define AT91C_US2_TNPR ((AT91_REG *) 0xFFFC8118) // (PDC_US2) Transmit Next Pointer Register
+#define AT91C_US2_RPR ((AT91_REG *) 0xFFFC8100) // (PDC_US2) Receive Pointer Register
+#define AT91C_US2_TPR ((AT91_REG *) 0xFFFC8108) // (PDC_US2) Transmit Pointer Register
+#define AT91C_US2_RNPR ((AT91_REG *) 0xFFFC8110) // (PDC_US2) Receive Next Pointer Register
+// ========== Register definition for US2 peripheral ==========
+#define AT91C_US2_XXR ((AT91_REG *) 0xFFFC8048) // (US2) XON_XOFF Register
+#define AT91C_US2_FIDI ((AT91_REG *) 0xFFFC8040) // (US2) FI_DI_Ratio Register
+#define AT91C_US2_TTGR ((AT91_REG *) 0xFFFC8028) // (US2) Transmitter Time-guard Register
+#define AT91C_US2_BRGR ((AT91_REG *) 0xFFFC8020) // (US2) Baud Rate Generator Register
+#define AT91C_US2_RHR ((AT91_REG *) 0xFFFC8018) // (US2) Receiver Holding Register
+#define AT91C_US2_IMR ((AT91_REG *) 0xFFFC8010) // (US2) Interrupt Mask Register
+#define AT91C_US2_IER ((AT91_REG *) 0xFFFC8008) // (US2) Interrupt Enable Register
+#define AT91C_US2_CR ((AT91_REG *) 0xFFFC8000) // (US2) Control Register
+#define AT91C_US2_IF ((AT91_REG *) 0xFFFC804C) // (US2) IRDA_FILTER Register
+#define AT91C_US2_NER ((AT91_REG *) 0xFFFC8044) // (US2) Nb Errors Register
+#define AT91C_US2_RTOR ((AT91_REG *) 0xFFFC8024) // (US2) Receiver Time-out Register
+#define AT91C_US2_THR ((AT91_REG *) 0xFFFC801C) // (US2) Transmitter Holding Register
+#define AT91C_US2_CSR ((AT91_REG *) 0xFFFC8014) // (US2) Channel Status Register
+#define AT91C_US2_IDR ((AT91_REG *) 0xFFFC800C) // (US2) Interrupt Disable Register
+#define AT91C_US2_MR ((AT91_REG *) 0xFFFC8004) // (US2) Mode Register
+// ========== Register definition for PDC_US1 peripheral ==========
+#define AT91C_US1_PTSR ((AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register
+#define AT91C_US1_TNCR ((AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register
+#define AT91C_US1_RNCR ((AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register
+#define AT91C_US1_TCR ((AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register
+#define AT91C_US1_RCR ((AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register
+#define AT91C_US1_PTCR ((AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register
+#define AT91C_US1_TNPR ((AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register
+#define AT91C_US1_RNPR ((AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register
+#define AT91C_US1_TPR ((AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register
+#define AT91C_US1_RPR ((AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register
+// ========== Register definition for US1 peripheral ==========
+#define AT91C_US1_XXR ((AT91_REG *) 0xFFFC4048) // (US1) XON_XOFF Register
+#define AT91C_US1_RHR ((AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register
+#define AT91C_US1_IMR ((AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register
+#define AT91C_US1_IER ((AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register
+#define AT91C_US1_CR ((AT91_REG *) 0xFFFC4000) // (US1) Control Register
+#define AT91C_US1_RTOR ((AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register
+#define AT91C_US1_THR ((AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register
+#define AT91C_US1_CSR ((AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register
+#define AT91C_US1_IDR ((AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register
+#define AT91C_US1_FIDI ((AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register
+#define AT91C_US1_BRGR ((AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register
+#define AT91C_US1_TTGR ((AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register
+#define AT91C_US1_IF ((AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register
+#define AT91C_US1_NER ((AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register
+#define AT91C_US1_MR ((AT91_REG *) 0xFFFC4004) // (US1) Mode Register
+// ========== Register definition for PDC_US0 peripheral ==========
+#define AT91C_US0_PTCR ((AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register
+#define AT91C_US0_TNPR ((AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register
+#define AT91C_US0_RNPR ((AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register
+#define AT91C_US0_TPR ((AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register
+#define AT91C_US0_RPR ((AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register
+#define AT91C_US0_PTSR ((AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register
+#define AT91C_US0_TNCR ((AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register
+#define AT91C_US0_RNCR ((AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register
+#define AT91C_US0_TCR ((AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register
+#define AT91C_US0_RCR ((AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register
+// ========== Register definition for US0 peripheral ==========
+#define AT91C_US0_TTGR ((AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register
+#define AT91C_US0_BRGR ((AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register
+#define AT91C_US0_RHR ((AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register
+#define AT91C_US0_IMR ((AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register
+#define AT91C_US0_NER ((AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register
+#define AT91C_US0_RTOR ((AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register
+#define AT91C_US0_XXR ((AT91_REG *) 0xFFFC0048) // (US0) XON_XOFF Register
+#define AT91C_US0_FIDI ((AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register
+#define AT91C_US0_CR ((AT91_REG *) 0xFFFC0000) // (US0) Control Register
+#define AT91C_US0_IER ((AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register
+#define AT91C_US0_IF ((AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register
+#define AT91C_US0_MR ((AT91_REG *) 0xFFFC0004) // (US0) Mode Register
+#define AT91C_US0_IDR ((AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register
+#define AT91C_US0_CSR ((AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register
+#define AT91C_US0_THR ((AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register
+// ========== Register definition for TWI peripheral ==========
+#define AT91C_TWI_RHR ((AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register
+#define AT91C_TWI_IDR ((AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register
+#define AT91C_TWI_SR ((AT91_REG *) 0xFFFB8020) // (TWI) Status Register
+#define AT91C_TWI_CWGR ((AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register
+#define AT91C_TWI_SMR ((AT91_REG *) 0xFFFB8008) // (TWI) Slave Mode Register
+#define AT91C_TWI_CR ((AT91_REG *) 0xFFFB8000) // (TWI) Control Register
+#define AT91C_TWI_THR ((AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register
+#define AT91C_TWI_IMR ((AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register
+#define AT91C_TWI_IER ((AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register
+#define AT91C_TWI_IADR ((AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register
+#define AT91C_TWI_MMR ((AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register
+// ========== Register definition for PDC_MCI peripheral ==========
+#define AT91C_MCI_PTCR ((AT91_REG *) 0xFFFB4120) // (PDC_MCI) PDC Transfer Control Register
+#define AT91C_MCI_TNPR ((AT91_REG *) 0xFFFB4118) // (PDC_MCI) Transmit Next Pointer Register
+#define AT91C_MCI_RNPR ((AT91_REG *) 0xFFFB4110) // (PDC_MCI) Receive Next Pointer Register
+#define AT91C_MCI_TPR ((AT91_REG *) 0xFFFB4108) // (PDC_MCI) Transmit Pointer Register
+#define AT91C_MCI_RPR ((AT91_REG *) 0xFFFB4100) // (PDC_MCI) Receive Pointer Register
+#define AT91C_MCI_PTSR ((AT91_REG *) 0xFFFB4124) // (PDC_MCI) PDC Transfer Status Register
+#define AT91C_MCI_TNCR ((AT91_REG *) 0xFFFB411C) // (PDC_MCI) Transmit Next Counter Register
+#define AT91C_MCI_RNCR ((AT91_REG *) 0xFFFB4114) // (PDC_MCI) Receive Next Counter Register
+#define AT91C_MCI_TCR ((AT91_REG *) 0xFFFB410C) // (PDC_MCI) Transmit Counter Register
+#define AT91C_MCI_RCR ((AT91_REG *) 0xFFFB4104) // (PDC_MCI) Receive Counter Register
+// ========== Register definition for MCI peripheral ==========
+#define AT91C_MCI_IDR ((AT91_REG *) 0xFFFB4048) // (MCI) MCI Interrupt Disable Register
+#define AT91C_MCI_SR ((AT91_REG *) 0xFFFB4040) // (MCI) MCI Status Register
+#define AT91C_MCI_RDR ((AT91_REG *) 0xFFFB4030) // (MCI) MCI Receive Data Register
+#define AT91C_MCI_RSPR ((AT91_REG *) 0xFFFB4020) // (MCI) MCI Response Register
+#define AT91C_MCI_ARGR ((AT91_REG *) 0xFFFB4010) // (MCI) MCI Argument Register
+#define AT91C_MCI_DTOR ((AT91_REG *) 0xFFFB4008) // (MCI) MCI Data Timeout Register
+#define AT91C_MCI_CR ((AT91_REG *) 0xFFFB4000) // (MCI) MCI Control Register
+#define AT91C_MCI_IMR ((AT91_REG *) 0xFFFB404C) // (MCI) MCI Interrupt Mask Register
+#define AT91C_MCI_IER ((AT91_REG *) 0xFFFB4044) // (MCI) MCI Interrupt Enable Register
+#define AT91C_MCI_TDR ((AT91_REG *) 0xFFFB4034) // (MCI) MCI Transmit Data Register
+#define AT91C_MCI_CMDR ((AT91_REG *) 0xFFFB4014) // (MCI) MCI Command Register
+#define AT91C_MCI_SDCR ((AT91_REG *) 0xFFFB400C) // (MCI) MCI SD Card Register
+#define AT91C_MCI_MR ((AT91_REG *) 0xFFFB4004) // (MCI) MCI Mode Register
+// ========== Register definition for UDP peripheral ==========
+#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register
+#define AT91C_UDP_IDR ((AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register
+#define AT91C_UDP_GLBSTATE ((AT91_REG *) 0xFFFB0004) // (UDP) Global State Register
+#define AT91C_UDP_FDR ((AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register
+#define AT91C_UDP_CSR ((AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register
+#define AT91C_UDP_RSTEP ((AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register
+#define AT91C_UDP_ICR ((AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register
+#define AT91C_UDP_IMR ((AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register
+#define AT91C_UDP_IER ((AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register
+#define AT91C_UDP_FADDR ((AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register
+#define AT91C_UDP_NUM ((AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register
+// ========== Register definition for TC5 peripheral ==========
+#define AT91C_TC5_CMR ((AT91_REG *) 0xFFFA4084) // (TC5) Channel Mode Register
+#define AT91C_TC5_IDR ((AT91_REG *) 0xFFFA40A8) // (TC5) Interrupt Disable Register
+#define AT91C_TC5_SR ((AT91_REG *) 0xFFFA40A0) // (TC5) Status Register
+#define AT91C_TC5_RB ((AT91_REG *) 0xFFFA4098) // (TC5) Register B
+#define AT91C_TC5_CV ((AT91_REG *) 0xFFFA4090) // (TC5) Counter Value
+#define AT91C_TC5_CCR ((AT91_REG *) 0xFFFA4080) // (TC5) Channel Control Register
+#define AT91C_TC5_IMR ((AT91_REG *) 0xFFFA40AC) // (TC5) Interrupt Mask Register
+#define AT91C_TC5_IER ((AT91_REG *) 0xFFFA40A4) // (TC5) Interrupt Enable Register
+#define AT91C_TC5_RC ((AT91_REG *) 0xFFFA409C) // (TC5) Register C
+#define AT91C_TC5_RA ((AT91_REG *) 0xFFFA4094) // (TC5) Register A
+// ========== Register definition for TC4 peripheral ==========
+#define AT91C_TC4_IMR ((AT91_REG *) 0xFFFA406C) // (TC4) Interrupt Mask Register
+#define AT91C_TC4_IER ((AT91_REG *) 0xFFFA4064) // (TC4) Interrupt Enable Register
+#define AT91C_TC4_RC ((AT91_REG *) 0xFFFA405C) // (TC4) Register C
+#define AT91C_TC4_RA ((AT91_REG *) 0xFFFA4054) // (TC4) Register A
+#define AT91C_TC4_CMR ((AT91_REG *) 0xFFFA4044) // (TC4) Channel Mode Register
+#define AT91C_TC4_IDR ((AT91_REG *) 0xFFFA4068) // (TC4) Interrupt Disable Register
+#define AT91C_TC4_SR ((AT91_REG *) 0xFFFA4060) // (TC4) Status Register
+#define AT91C_TC4_RB ((AT91_REG *) 0xFFFA4058) // (TC4) Register B
+#define AT91C_TC4_CV ((AT91_REG *) 0xFFFA4050) // (TC4) Counter Value
+#define AT91C_TC4_CCR ((AT91_REG *) 0xFFFA4040) // (TC4) Channel Control Register
+// ========== Register definition for TC3 peripheral ==========
+#define AT91C_TC3_IMR ((AT91_REG *) 0xFFFA402C) // (TC3) Interrupt Mask Register
+#define AT91C_TC3_CV ((AT91_REG *) 0xFFFA4010) // (TC3) Counter Value
+#define AT91C_TC3_CCR ((AT91_REG *) 0xFFFA4000) // (TC3) Channel Control Register
+#define AT91C_TC3_IER ((AT91_REG *) 0xFFFA4024) // (TC3) Interrupt Enable Register
+#define AT91C_TC3_CMR ((AT91_REG *) 0xFFFA4004) // (TC3) Channel Mode Register
+#define AT91C_TC3_RA ((AT91_REG *) 0xFFFA4014) // (TC3) Register A
+#define AT91C_TC3_RC ((AT91_REG *) 0xFFFA401C) // (TC3) Register C
+#define AT91C_TC3_IDR ((AT91_REG *) 0xFFFA4028) // (TC3) Interrupt Disable Register
+#define AT91C_TC3_RB ((AT91_REG *) 0xFFFA4018) // (TC3) Register B
+#define AT91C_TC3_SR ((AT91_REG *) 0xFFFA4020) // (TC3) Status Register
+// ========== Register definition for TCB1 peripheral ==========
+#define AT91C_TCB1_BCR ((AT91_REG *) 0xFFFA4140) // (TCB1) TC Block Control Register
+#define AT91C_TCB1_BMR ((AT91_REG *) 0xFFFA4144) // (TCB1) TC Block Mode Register
+// ========== Register definition for TC2 peripheral ==========
+#define AT91C_TC2_IMR ((AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register
+#define AT91C_TC2_IER ((AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register
+#define AT91C_TC2_RC ((AT91_REG *) 0xFFFA009C) // (TC2) Register C
+#define AT91C_TC2_RA ((AT91_REG *) 0xFFFA0094) // (TC2) Register A
+#define AT91C_TC2_CMR ((AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register
+#define AT91C_TC2_IDR ((AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register
+#define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register
+#define AT91C_TC2_RB ((AT91_REG *) 0xFFFA0098) // (TC2) Register B
+#define AT91C_TC2_CV ((AT91_REG *) 0xFFFA0090) // (TC2) Counter Value
+#define AT91C_TC2_CCR ((AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register
+// ========== Register definition for TC1 peripheral ==========
+#define AT91C_TC1_IMR ((AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register
+#define AT91C_TC1_IER ((AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register
+#define AT91C_TC1_RC ((AT91_REG *) 0xFFFA005C) // (TC1) Register C
+#define AT91C_TC1_RA ((AT91_REG *) 0xFFFA0054) // (TC1) Register A
+#define AT91C_TC1_CMR ((AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register
+#define AT91C_TC1_IDR ((AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register
+#define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register
+#define AT91C_TC1_RB ((AT91_REG *) 0xFFFA0058) // (TC1) Register B
+#define AT91C_TC1_CV ((AT91_REG *) 0xFFFA0050) // (TC1) Counter Value
+#define AT91C_TC1_CCR ((AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register
+// ========== Register definition for TC0 peripheral ==========
+#define AT91C_TC0_IMR ((AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register
+#define AT91C_TC0_IER ((AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register
+#define AT91C_TC0_RC ((AT91_REG *) 0xFFFA001C) // (TC0) Register C
+#define AT91C_TC0_RA ((AT91_REG *) 0xFFFA0014) // (TC0) Register A
+#define AT91C_TC0_CMR ((AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register
+#define AT91C_TC0_IDR ((AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register
+#define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register
+#define AT91C_TC0_RB ((AT91_REG *) 0xFFFA0018) // (TC0) Register B
+#define AT91C_TC0_CV ((AT91_REG *) 0xFFFA0010) // (TC0) Counter Value
+#define AT91C_TC0_CCR ((AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register
+// ========== Register definition for TCB0 peripheral ==========
+#define AT91C_TCB0_BMR ((AT91_REG *) 0xFFFA00C4) // (TCB0) TC Block Mode Register
+#define AT91C_TCB0_BCR ((AT91_REG *) 0xFFFA00C0) // (TCB0) TC Block Control Register
+// ========== Register definition for UHP peripheral ==========
+#define AT91C_UHP_HcRhDescriptorA ((AT91_REG *) 0x00300048) // (UHP) Root Hub characteristics A
+#define AT91C_UHP_HcRhPortStatus ((AT91_REG *) 0x00300054) // (UHP) Root Hub Port Status Register
+#define AT91C_UHP_HcRhDescriptorB ((AT91_REG *) 0x0030004C) // (UHP) Root Hub characteristics B
+#define AT91C_UHP_HcControl ((AT91_REG *) 0x00300004) // (UHP) Operating modes for the Host Controller
+#define AT91C_UHP_HcInterruptStatus ((AT91_REG *) 0x0030000C) // (UHP) Interrupt Status Register
+#define AT91C_UHP_HcRhStatus ((AT91_REG *) 0x00300050) // (UHP) Root Hub Status register
+#define AT91C_UHP_HcRevision ((AT91_REG *) 0x00300000) // (UHP) Revision
+#define AT91C_UHP_HcCommandStatus ((AT91_REG *) 0x00300008) // (UHP) Command & status Register
+#define AT91C_UHP_HcInterruptEnable ((AT91_REG *) 0x00300010) // (UHP) Interrupt Enable Register
+#define AT91C_UHP_HcHCCA ((AT91_REG *) 0x00300018) // (UHP) Pointer to the Host Controller Communication Area
+#define AT91C_UHP_HcControlHeadED ((AT91_REG *) 0x00300020) // (UHP) First Endpoint Descriptor of the Control list
+#define AT91C_UHP_HcInterruptDisable ((AT91_REG *) 0x00300014) // (UHP) Interrupt Disable Register
+#define AT91C_UHP_HcPeriodCurrentED ((AT91_REG *) 0x0030001C) // (UHP) Current Isochronous or Interrupt Endpoint Descriptor
+#define AT91C_UHP_HcControlCurrentED ((AT91_REG *) 0x00300024) // (UHP) Endpoint Control and Status Register
+#define AT91C_UHP_HcBulkCurrentED ((AT91_REG *) 0x0030002C) // (UHP) Current endpoint of the Bulk list
+#define AT91C_UHP_HcFmInterval ((AT91_REG *) 0x00300034) // (UHP) Bit time between 2 consecutive SOFs
+#define AT91C_UHP_HcBulkHeadED ((AT91_REG *) 0x00300028) // (UHP) First endpoint register of the Bulk list
+#define AT91C_UHP_HcBulkDoneHead ((AT91_REG *) 0x00300030) // (UHP) Last completed transfer descriptor
+#define AT91C_UHP_HcFmRemaining ((AT91_REG *) 0x00300038) // (UHP) Bit time remaining in the current Frame
+#define AT91C_UHP_HcPeriodicStart ((AT91_REG *) 0x00300040) // (UHP) Periodic Start
+#define AT91C_UHP_HcLSThreshold ((AT91_REG *) 0x00300044) // (UHP) LS Threshold
+#define AT91C_UHP_HcFmNumber ((AT91_REG *) 0x0030003C) // (UHP) Frame number
+// ========== Register definition for EMAC peripheral ==========
+#define AT91C_EMAC_RSR ((AT91_REG *) 0xFFFBC020) // (EMAC) Receive Status Register
+#define AT91C_EMAC_MAN ((AT91_REG *) 0xFFFBC034) // (EMAC) PHY Maintenance Register
+#define AT91C_EMAC_HSH ((AT91_REG *) 0xFFFBC090) // (EMAC) Hash Address High[63:32]
+#define AT91C_EMAC_MCOL ((AT91_REG *) 0xFFFBC048) // (EMAC) Multiple Collision Frame Register
+#define AT91C_EMAC_IER ((AT91_REG *) 0xFFFBC028) // (EMAC) Interrupt Enable Register
+#define AT91C_EMAC_SA2H ((AT91_REG *) 0xFFFBC0A4) // (EMAC) Specific Address 2 High, Last 2 bytes
+#define AT91C_EMAC_HSL ((AT91_REG *) 0xFFFBC094) // (EMAC) Hash Address Low[31:0]
+#define AT91C_EMAC_LCOL ((AT91_REG *) 0xFFFBC05C) // (EMAC) Late Collision Register
+#define AT91C_EMAC_OK ((AT91_REG *) 0xFFFBC04C) // (EMAC) Frames Received OK Register
+#define AT91C_EMAC_CFG ((AT91_REG *) 0xFFFBC004) // (EMAC) Network Configuration Register
+#define AT91C_EMAC_SA3L ((AT91_REG *) 0xFFFBC0A8) // (EMAC) Specific Address 3 Low, First 4 bytes
+#define AT91C_EMAC_SEQE ((AT91_REG *) 0xFFFBC050) // (EMAC) Frame Check Sequence Error Register
+#define AT91C_EMAC_ECOL ((AT91_REG *) 0xFFFBC060) // (EMAC) Excessive Collision Register
+#define AT91C_EMAC_ELR ((AT91_REG *) 0xFFFBC070) // (EMAC) Excessive Length Error Register
+#define AT91C_EMAC_SR ((AT91_REG *) 0xFFFBC008) // (EMAC) Network Status Register
+#define AT91C_EMAC_RBQP ((AT91_REG *) 0xFFFBC018) // (EMAC) Receive Buffer Queue Pointer
+#define AT91C_EMAC_CSE ((AT91_REG *) 0xFFFBC064) // (EMAC) Carrier Sense Error Register
+#define AT91C_EMAC_RJB ((AT91_REG *) 0xFFFBC074) // (EMAC) Receive Jabber Register
+#define AT91C_EMAC_USF ((AT91_REG *) 0xFFFBC078) // (EMAC) Undersize Frame Register
+#define AT91C_EMAC_IDR ((AT91_REG *) 0xFFFBC02C) // (EMAC) Interrupt Disable Register
+#define AT91C_EMAC_SA1L ((AT91_REG *) 0xFFFBC098) // (EMAC) Specific Address 1 Low, First 4 bytes
+#define AT91C_EMAC_IMR ((AT91_REG *) 0xFFFBC030) // (EMAC) Interrupt Mask Register
+#define AT91C_EMAC_FRA ((AT91_REG *) 0xFFFBC040) // (EMAC) Frames Transmitted OK Register
+#define AT91C_EMAC_SA3H ((AT91_REG *) 0xFFFBC0AC) // (EMAC) Specific Address 3 High, Last 2 bytes
+#define AT91C_EMAC_SA1H ((AT91_REG *) 0xFFFBC09C) // (EMAC) Specific Address 1 High, Last 2 bytes
+#define AT91C_EMAC_SCOL ((AT91_REG *) 0xFFFBC044) // (EMAC) Single Collision Frame Register
+#define AT91C_EMAC_ALE ((AT91_REG *) 0xFFFBC054) // (EMAC) Alignment Error Register
+#define AT91C_EMAC_TAR ((AT91_REG *) 0xFFFBC00C) // (EMAC) Transmit Address Register
+#define AT91C_EMAC_SA4L ((AT91_REG *) 0xFFFBC0B0) // (EMAC) Specific Address 4 Low, First 4 bytes
+#define AT91C_EMAC_SA2L ((AT91_REG *) 0xFFFBC0A0) // (EMAC) Specific Address 2 Low, First 4 bytes
+#define AT91C_EMAC_TUE ((AT91_REG *) 0xFFFBC068) // (EMAC) Transmit Underrun Error Register
+#define AT91C_EMAC_DTE ((AT91_REG *) 0xFFFBC058) // (EMAC) Deferred Transmission Frame Register
+#define AT91C_EMAC_TCR ((AT91_REG *) 0xFFFBC010) // (EMAC) Transmit Control Register
+#define AT91C_EMAC_CTL ((AT91_REG *) 0xFFFBC000) // (EMAC) Network Control Register
+#define AT91C_EMAC_SA4H ((AT91_REG *) 0xFFFBC0B4) // (EMAC) Specific Address 4 High, Last 2 bytesr
+#define AT91C_EMAC_CDE ((AT91_REG *) 0xFFFBC06C) // (EMAC) Code Error Register
+#define AT91C_EMAC_SQEE ((AT91_REG *) 0xFFFBC07C) // (EMAC) SQE Test Error Register
+#define AT91C_EMAC_TSR ((AT91_REG *) 0xFFFBC014) // (EMAC) Transmit Status Register
+#define AT91C_EMAC_DRFC ((AT91_REG *) 0xFFFBC080) // (EMAC) Discarded RX Frame Register
+// ========== Register definition for EBI peripheral ==========
+#define AT91C_EBI_CFGR ((AT91_REG *) 0xFFFFFF64) // (EBI) Configuration Register
+#define AT91C_EBI_CSA ((AT91_REG *) 0xFFFFFF60) // (EBI) Chip Select Assignment Register
+// ========== Register definition for SMC2 peripheral ==========
+#define AT91C_SMC2_CSR ((AT91_REG *) 0xFFFFFF70) // (SMC2) SMC2 Chip Select Register
+// ========== Register definition for SDRC peripheral ==========
+#define AT91C_SDRC_IMR ((AT91_REG *) 0xFFFFFFAC) // (SDRC) SDRAM Controller Interrupt Mask Register
+#define AT91C_SDRC_IER ((AT91_REG *) 0xFFFFFFA4) // (SDRC) SDRAM Controller Interrupt Enable Register
+#define AT91C_SDRC_SRR ((AT91_REG *) 0xFFFFFF9C) // (SDRC) SDRAM Controller Self Refresh Register
+#define AT91C_SDRC_TR ((AT91_REG *) 0xFFFFFF94) // (SDRC) SDRAM Controller Refresh Timer Register
+#define AT91C_SDRC_ISR ((AT91_REG *) 0xFFFFFFB0) // (SDRC) SDRAM Controller Interrupt Mask Register
+#define AT91C_SDRC_IDR ((AT91_REG *) 0xFFFFFFA8) // (SDRC) SDRAM Controller Interrupt Disable Register
+#define AT91C_SDRC_LPR ((AT91_REG *) 0xFFFFFFA0) // (SDRC) SDRAM Controller Low Power Register
+#define AT91C_SDRC_CR ((AT91_REG *) 0xFFFFFF98) // (SDRC) SDRAM Controller Configuration Register
+#define AT91C_SDRC_MR ((AT91_REG *) 0xFFFFFF90) // (SDRC) SDRAM Controller Mode Register
+// ========== Register definition for BFC peripheral ==========
+#define AT91C_BFC_MR ((AT91_REG *) 0xFFFFFFC0) // (BFC) BFC Mode Register
+
+#include <at91/at91_pioreg.h>
+
+// *****************************************************************************
+// PERIPHERAL ID DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_ID_FIQ 0u // Advanced Interrupt Controller (FIQ)
+#define AT91C_ID_SYS 1u // System Peripheral
+#define AT91C_ID_PIOA 2u // Parallel IO Controller A
+#define AT91C_ID_PIOB 3u // Parallel IO Controller B
+#define AT91C_ID_PIOC 4u // Parallel IO Controller C
+#define AT91C_ID_PIOD 5u // Parallel IO Controller D
+#define AT91C_ID_US0 6u // USART 0
+#define AT91C_ID_US1 7u // USART 1
+#define AT91C_ID_US2 8u // USART 2
+#define AT91C_ID_US3 9u // USART 3
+#define AT91C_ID_MCI 10u // Multimedia Card Interface
+#define AT91C_ID_UDP 11u // USB Device Port
+#define AT91C_ID_TWI 12u // Two-Wire Interface
+#define AT91C_ID_SPI 13u // Serial Peripheral Interface
+#define AT91C_ID_SSC0 14u // Serial Synchronous Controller 0
+#define AT91C_ID_SSC1 15u // Serial Synchronous Controller 1
+#define AT91C_ID_SSC2 16u // Serial Synchronous Controller 2
+#define AT91C_ID_TC0 17u // Timer Counter 0
+#define AT91C_ID_TC1 18u // Timer Counter 1
+#define AT91C_ID_TC2 19u // Timer Counter 2
+#define AT91C_ID_TC3 20u // Timer Counter 3
+#define AT91C_ID_TC4 21u // Timer Counter 4
+#define AT91C_ID_TC5 22u // Timer Counter 5
+#define AT91C_ID_UHP 23u // USB Host port
+#define AT91C_ID_EMAC 24u // Ethernet MAC
+#define AT91C_ID_IRQ0 25u // Advanced Interrupt Controller (IRQ0)
+#define AT91C_ID_IRQ1 26u // Advanced Interrupt Controller (IRQ1)
+#define AT91C_ID_IRQ2 27u // Advanced Interrupt Controller (IRQ2)
+#define AT91C_ID_IRQ3 28u // Advanced Interrupt Controller (IRQ3)
+#define AT91C_ID_IRQ4 29u // Advanced Interrupt Controller (IRQ4)
+#define AT91C_ID_IRQ5 30u // Advanced Interrupt Controller (IRQ5)
+#define AT91C_ID_IRQ6 31u // Advanced Interrupt Controller (IRQ6)
+
+// *****************************************************************************
+// BASE ADDRESS DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_BASE_SYS ((AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address
+#define AT91C_BASE_MC ((AT91PS_MC) 0xFFFFFF00) // (MC) Base Address
+#define AT91C_BASE_RTC ((AT91PS_RTC) 0xFFFFFE00) // (RTC) Base Address
+#define AT91C_BASE_ST ((AT91PS_ST) 0xFFFFFD00) // (ST) Base Address
+#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
+#define AT91C_BASE_CKGR ((AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address
+#define AT91C_BASE_PIOD ((AT91PS_PIO) 0xFFFFFA00) // (PIOD) Base Address
+#define AT91C_BASE_PIOC ((AT91PS_PIO) 0xFFFFF800) // (PIOC) Base Address
+#define AT91C_BASE_PIOB ((AT91PS_PIO) 0xFFFFF600) // (PIOB) Base Address
+#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address
+#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address
+#define AT91C_BASE_PDC_DBGU ((AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address
+#define AT91C_BASE_AIC ((AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address
+#define AT91C_BASE_PDC_SPI ((AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address
+#define AT91C_BASE_SPI ((AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address
+#define AT91C_BASE_PDC_SSC2 ((AT91PS_PDC) 0xFFFD8100) // (PDC_SSC2) Base Address
+#define AT91C_BASE_SSC2 ((AT91PS_SSC) 0xFFFD8000) // (SSC2) Base Address
+#define AT91C_BASE_PDC_SSC1 ((AT91PS_PDC) 0xFFFD4100) // (PDC_SSC1) Base Address
+#define AT91C_BASE_SSC1 ((AT91PS_SSC) 0xFFFD4000) // (SSC1) Base Address
+#define AT91C_BASE_PDC_SSC0 ((AT91PS_PDC) 0xFFFD0100) // (PDC_SSC0) Base Address
+#define AT91C_BASE_SSC0 ((AT91PS_SSC) 0xFFFD0000) // (SSC0) Base Address
+#define AT91C_BASE_PDC_US3 ((AT91PS_PDC) 0xFFFCC100) // (PDC_US3) Base Address
+#define AT91C_BASE_US3 ((AT91PS_USART) 0xFFFCC000) // (US3) Base Address
+#define AT91C_BASE_PDC_US2 ((AT91PS_PDC) 0xFFFC8100) // (PDC_US2) Base Address
+#define AT91C_BASE_US2 ((AT91PS_USART) 0xFFFC8000) // (US2) Base Address
+#define AT91C_BASE_PDC_US1 ((AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address
+#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) // (US1) Base Address
+#define AT91C_BASE_PDC_US0 ((AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address
+#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) // (US0) Base Address
+#define AT91C_BASE_TWI ((AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address
+#define AT91C_BASE_PDC_MCI ((AT91PS_PDC) 0xFFFB4100) // (PDC_MCI) Base Address
+#define AT91C_BASE_MCI ((AT91PS_MCI) 0xFFFB4000) // (MCI) Base Address
+#define AT91C_BASE_UDP ((AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address
+#define AT91C_BASE_TC5 ((AT91PS_TC) 0xFFFA4080) // (TC5) Base Address
+#define AT91C_BASE_TC4 ((AT91PS_TC) 0xFFFA4040) // (TC4) Base Address
+#define AT91C_BASE_TC3 ((AT91PS_TC) 0xFFFA4000) // (TC3) Base Address
+#define AT91C_BASE_TCB1 ((AT91PS_TCB) 0xFFFA4080) // (TCB1) Base Address
+#define AT91C_BASE_TC2 ((AT91PS_TC) 0xFFFA0080) // (TC2) Base Address
+#define AT91C_BASE_TC1 ((AT91PS_TC) 0xFFFA0040) // (TC1) Base Address
+#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) // (TC0) Base Address
+#define AT91C_BASE_TCB0 ((AT91PS_TCB) 0xFFFA0000) // (TCB0) Base Address
+#define AT91C_BASE_UHP ((AT91PS_UHP) 0x00300000) // (UHP) Base Address
+#define AT91C_BASE_EMAC ((AT91PS_EMAC) 0xFFFBC000) // (EMAC) Base Address
+#define AT91C_BASE_EBI ((AT91PS_EBI) 0xFFFFFF60) // (EBI) Base Address
+#define AT91C_BASE_SMC2 ((AT91PS_SMC2) 0xFFFFFF70) // (SMC2) Base Address
+#define AT91C_BASE_SDRC ((AT91PS_SDRC) 0xFFFFFF90) // (SDRC) Base Address
+#define AT91C_BASE_BFC ((AT91PS_BFC) 0xFFFFFFC0) // (BFC) Base Address
+
+// *****************************************************************************
+// MEMORY MAPPING DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address
+#define AT91C_ISRAM_SIZE 0x00004000u // Internal SRAM size in byte (16 Kbyte)
+#define AT91C_IROM ((char *) 0x00100000) // Internal ROM base address
+#define AT91C_IROM_SIZE 0x00020000u // Internal ROM size in byte (128 Kbyte)
+
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
new file mode 100644
index 0000000000..1d54cfdad4
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+
+extern int __bss_start__[];
+extern int __bss_end__[];
+
+#define BAUD 115200
+#define AT91C_US_ASYNC_MODE (AT91C_US_USMODE_NORMAL | AT91C_US_NBSTOP_1_BIT | \
+ AT91C_US_PAR_NONE | AT91C_US_CHRL_8_BITS | AT91C_US_CLKS_CLOCK)
+
+/*
+ * void DefaultSystemInit(void)
+ * Load the system with sane values based on how the system is configured.
+ * at91rm9200_lowlevel.h is expected to define the necessary parameters.
+ */
+void
+_init(void)
+{
+ int *i;
+
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+ AT91PS_PDC pPDC = (AT91PS_PDC)&(pUSART->US_RPR);
+
+ register unsigned value;
+ volatile sdram_size_t *p = (sdram_size_t *)SDRAM_BASE;
+
+ AT91C_BASE_ST->ST_RTMR = 1;
+#ifdef BOOT_TSC
+ // For the TSC board, we turn ON the one LED we have while
+ // early in boot.
+ AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC10;
+ AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC10;
+ AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC10;
+#endif
+
+#if defined(BOOT_KB920X)
+ AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
+ AT91C_PIO_PC20;
+ AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
+ AT91C_PIO_PC20;
+ AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
+ AT91C_PIO_PC20;
+ AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC18;
+#endif
+
+ // configure clocks
+ // assume:
+ // main osc = 10Mhz
+ // PLLB configured for 96MHz (48MHz after div)
+ // CSS = PLLB
+ // set PLLA = 180MHz
+ // assume main osc = 10Mhz
+ // div = 5 , out = 2 (150MHz = 240MHz)
+ value = AT91C_BASE_CKGR->CKGR_PLLAR;
+ value &= ~(AT91C_CKGR_DIVA | AT91C_CKGR_OUTA | AT91C_CKGR_MULA);
+ value |= OSC_MAIN_FREQ_DIV | AT91C_CKGR_OUTA_2 | AT91C_CKGR_SRCA |
+ ((OSC_MAIN_MULT - 1) << 16);
+ AT91C_BASE_CKGR->CKGR_PLLAR = value;
+
+ // wait for lock
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA))
+ continue;
+
+ // change divider = 3, pres = 1
+ value = AT91C_BASE_PMC->PMC_MCKR;
+ value &= ~(AT91C_PMC_MDIV | AT91C_PMC_PRES);
+ value |= AT91C_PMC_MDIV_3 | AT91C_PMC_PRES_CLK;
+ AT91C_BASE_PMC->PMC_MCKR = value;
+
+ // wait for update
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
+ continue;
+
+ // change CSS = PLLA
+ value &= ~AT91C_PMC_CSS;
+ value |= AT91C_PMC_CSS_PLLA_CLK;
+ AT91C_BASE_PMC->PMC_MCKR = value;
+
+ // wait for update
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
+ continue;
+
+#ifdef BOOT_KB920X
+ // setup flash access (allow ample margin)
+ // 9 wait states, 1 setup, 1 hold, 1 float for 8-bit device
+ ((AT91PS_SMC2)AT91C_BASE_SMC2)->SMC2_CSR[0] =
+ AT91C_SMC2_WSEN |
+ (9 & AT91C_SMC2_NWS) |
+ ((1 << 8) & AT91C_SMC2_TDF) |
+ AT91C_SMC2_DBW_8 |
+ ((1 << 24) & AT91C_SMC2_RWSETUP) |
+ ((1 << 29) & AT91C_SMC2_RWHOLD);
+#endif
+
+ // setup SDRAM access
+ // EBI chip-select register (CS1 = SDRAM controller)
+ // 9 col, 13row, 4 bank, CAS2
+ // write recovery = 2 (Twr)
+ // row cycle = 5 (Trc)
+ // precharge delay = 2 (Trp)
+ // row to col delay 2 (Trcd)
+ // active to precharge = 4 (Tras)
+ // exit self refresh to active = 6 (Txsr)
+ value = ((AT91PS_EBI)AT91C_BASE_EBI)->EBI_CSA;
+ value &= ~AT91C_EBI_CS1A;
+ value |= AT91C_EBI_CS1A_SDRAMC;
+ AT91C_BASE_EBI->EBI_CSA = value;
+
+ AT91C_BASE_SDRC->SDRC_CR =
+#if defined(KB9202_B) || defined(SDRAM_128M)
+ AT91C_SDRC_NC_10 |
+#else
+ AT91C_SDRC_NC_9 |
+#endif
+ AT91C_SDRC_NR_13 |
+ AT91C_SDRC_NB_4_BANKS |
+ AT91C_SDRC_CAS_2 |
+ ((2 << 7) & AT91C_SDRC_TWR) |
+ ((5 << 11) & AT91C_SDRC_TRC) |
+ ((2 << 15) & AT91C_SDRC_TRP) |
+ ((2 << 19) & AT91C_SDRC_TRCD) |
+ ((4 << 23) & AT91C_SDRC_TRAS) |
+ ((6 << 27) & AT91C_SDRC_TXSR);
+
+ // Step 1: We assume 200us of idle time.
+ // Step 2: Issue an all banks precharge command
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_PRCGALL_CMD;
+ *p = 0;
+
+ // Step 3: Issue 8 Auto-refresh (CBR) cycles
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_RFSH_CMD;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+
+ // Step 4: Issue an Mode Set Register (MRS) cycle to program in
+ // the parameters that we setup in the SDRC_CR register above.
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_LMR_CMD;
+ *p = 0;
+
+ // Step 5: set the refresh timer and access memory to start it
+ // running. We have to wait 3 clocks after the LMR_CMD above,
+ // and this fits the bill nicely.
+ AT91C_BASE_SDRC->SDRC_TR = 7 * AT91C_MASTER_CLOCK / 1000000;
+ *p = 0;
+
+ // Step 6: Set normal mode.
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_NORMAL_CMD;
+ *p = 0;
+
+#if SDRAM_WIDTH == AT91C_SDRC_DBW_32_BITS
+ // Turn on the upper 16 bits on the SDRAM bus.
+ AT91C_BASE_PIOC->PIO_ASR = 0xffff0000;
+ AT91C_BASE_PIOC->PIO_PDR = 0xffff0000;
+#endif
+ // Configure DBGU -use local routine optimized for space
+ AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
+ AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
+ pUSART->US_IDR = (unsigned int) -1;
+ pUSART->US_CR =
+ AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
+ pUSART->US_BRGR = ((((AT91C_MASTER_CLOCK*10)/(BAUD*16))+5)/10);
+ pUSART->US_TTGR = 0;
+ pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
+ pPDC->PDC_TNPR = 0;
+ pPDC->PDC_TNCR = 0;
+
+ pPDC->PDC_RNPR = 0;
+ pPDC->PDC_RNCR = 0;
+
+ pPDC->PDC_TPR = 0;
+ pPDC->PDC_TCR = 0;
+
+ pPDC->PDC_RPR = 0;
+ pPDC->PDC_RCR = 0;
+
+ pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
+ pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
+
+ pUSART->US_MR = AT91C_US_ASYNC_MODE;
+ pUSART->US_CR = AT91C_US_TXEN;
+ pUSART->US_CR = AT91C_US_RXEN;
+
+ /* Zero BSS now that we have memory setup */
+ i = (int *)__bss_start__;
+ while (i < (int *)__bss_end__)
+ *i++ = 0;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h
new file mode 100644
index 0000000000..9d9b12736f
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AT91RM9200_LOWLEVEL_H_
+#define _AT91RM9200_LOWLEVEL_H_
+
+/* default system config parameters */
+
+#define SDRAM_BASE 0x20000000
+
+#ifdef BOOT_KB920X
+/* The following divisor sets PLLA frequency: e.g. 10/5 * 90 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 5 /* for 10MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS
+typedef unsigned short sdram_size_t;
+#define OSC_MAIN_MULT 90
+#endif
+
+#ifdef BOOT_CENTIPAD
+/* The following divisor sets PLLA frequency: e.g. 10/5 * 90 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 5 /* for 10MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS
+typedef unsigned short sdram_size_t;
+#define OSC_MAIN_MULT 90
+#endif
+
+#ifdef BOOT_BWCT
+/* The following divisor sets PLLA frequency: e.g. 16/4 * 45 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 4 /* for 16MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_32_BITS
+typedef unsigned int sdram_size_t;
+#define OSC_MAIN_MULT 45
+#endif
+
+#ifdef BOOT_TSC
+/* The following divisor sets PLLA frequency: e.g. 16/4 * 45 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 4 /* for 16MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_32_BITS
+typedef unsigned int sdram_size_t;
+#define OSC_MAIN_MULT 45
+#endif
+
+/* Master clock frequency at power-up */
+#define AT91C_MASTER_CLOCK 60000000
+
+/* #define GetSeconds() (AT91C_BASE_RTC->RTC_TIMR & AT91C_RTC_SEC) */
+#define GetSeconds() (AT91C_BASE_ST->ST_CRTR >> 15)
+
+extern void _init(void);
+
+#endif /* _AT91RM9200_LOWLEVEL_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/delay.c b/usr/src/boot/sys/boot/arm/at91/libat91/delay.c
new file mode 100644
index 0000000000..390e06790c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/delay.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "spi_flash.h"
+#include "lib.h"
+
+void
+Delay(int us)
+{
+ unsigned later, now;
+
+ now = AT91C_BASE_ST->ST_CRTR;
+ later = (now + us / 25 + 1) & AT91C_ST_CRTV;
+ while (later != AT91C_BASE_ST->ST_CRTR)
+ continue;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/eeprom.c b/usr/src/boot/sys/boot/arm/at91/libat91/eeprom.c
new file mode 100644
index 0000000000..e08996bed8
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/eeprom.c
@@ -0,0 +1,185 @@
+/******************************************************************************
+ *
+ * Filename: eeprom.c
+ *
+ * Instantiation of eeprom routines
+ *
+ * Revision information:
+ *
+ * 28AUG2004 kb_admin initial creation - adapted from Atmel sources
+ * 12JAN2005 kb_admin fixed clock generation, write polling, init
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "at91rm9200_lowlevel.h"
+#include "at91rm9200.h"
+#include "lib.h"
+
+/******************************* GLOBALS *************************************/
+
+
+/*********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+
+/* Use a macro to calculate the TWI clock generator value to save code space. */
+#define AT91C_TWSI_CLOCK 100000
+#define TWSI_EEPROM_ADDRESS 0x50
+
+#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
+#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
+
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void InitEEPROM(void)
+ * This global function initializes the EEPROM interface (TWI). Intended
+ * to be called a single time.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+InitEEPROM(void)
+{
+
+ AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
+
+ AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
+
+ pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+ pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+
+ pPio->PIO_MDDR = ~AT91C_PIO_PA25;
+ pPio->PIO_MDER = AT91C_PIO_PA25;
+
+ pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
+
+ twiPtr->TWI_IDR = 0xffffffffu;
+ twiPtr->TWI_CR = AT91C_TWI_SWRST;
+ twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
+
+ twiPtr->TWI_CWGR = SET_TWI_CLOCK;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
+ * This global function reads data from the eeprom at ee_addr storing data
+ * to data_addr for size bytes. Assume the TWI has been initialized.
+ * This function does not utilize the page read mode to simplify the code.
+ * .KB_C_FN_DEFINITION_END
+ */
+int
+ReadEEPROM(unsigned ee_off, unsigned char *data_addr, unsigned size)
+{
+ const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
+ unsigned int status;
+ unsigned int count;
+
+ status = twiPtr->TWI_SR;
+ status = twiPtr->TWI_RHR;
+
+ // Set the TWI Master Mode Register
+ twiPtr->TWI_MMR = (TWSI_EEPROM_ADDRESS << 16) |
+ AT91C_TWI_IADRSZ_2_BYTE | AT91C_TWI_MREAD;
+
+ // Set TWI Internal Address Register
+ twiPtr->TWI_IADR = ee_off;
+
+ // Start transfer
+ twiPtr->TWI_CR = AT91C_TWI_START;
+
+ status = twiPtr->TWI_SR;
+
+ while (size-- > 1){
+ // Wait RHR Holding register is full
+ count = 1000000;
+ while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
+ continue;
+ if (count <= 0)
+ return -1;
+
+ // Read byte
+ *(data_addr++) = twiPtr->TWI_RHR;
+ }
+
+ twiPtr->TWI_CR = AT91C_TWI_STOP;
+
+ status = twiPtr->TWI_SR;
+
+ // Wait transfer is finished
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+ continue;
+
+ // Read last byte
+ *data_addr = twiPtr->TWI_RHR;
+ return 0;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
+ * This global function writes data to the eeprom at ee_off using data
+ * from data_addr for size bytes. Assume the TWI has been initialized.
+ * This function does not utilize the page write mode as the write time is
+ * much greater than the time required to access the device for byte-write
+ * functionality. This allows the function to be much simpler.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
+{
+ const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
+ unsigned status;
+ unsigned char test_data;
+
+ while (size--) {
+ if (!(ee_off & 0x3f))
+ putchar('.');
+
+ // Set the TWI Master Mode Register
+ twiPtr->TWI_MMR = ((TWSI_EEPROM_ADDRESS << 16) |
+ AT91C_TWI_IADRSZ_2_BYTE) & ~AT91C_TWI_MREAD;
+
+ // Set TWI Internal Address Register
+ twiPtr->TWI_IADR = ee_off++;
+
+ status = twiPtr->TWI_SR;
+
+ twiPtr->TWI_THR = *(data_addr++);
+
+ twiPtr->TWI_CR = AT91C_TWI_START;
+
+ // Wait transfer is finished
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
+ continue;
+
+ twiPtr->TWI_CR = AT91C_TWI_STOP;
+
+ status = twiPtr->TWI_SR;
+
+ // Wait transfer is finished
+ while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+ continue;
+
+ // wait for write operation to complete
+ ReadEEPROM(ee_off, &test_data, 1);
+ }
+
+ putchar('\r');
+ putchar('\n');
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/emac.c b/usr/src/boot/sys/boot/arm/at91/libat91/emac.c
new file mode 100644
index 0000000000..509d535ed9
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/emac.c
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ *
+ * Filename: emac.c
+ *
+ * Instantiation of routines for MAC/ethernet functions supporting tftp.
+ *
+ * Revision information:
+ *
+ * 28AUG2004 kb_admin initial creation
+ * 08JAN2005 kb_admin added tftp download
+ * also adapted from external sources
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+#include "emac.h"
+#include "lib.h"
+
+/* ****************************** GLOBALS *************************************/
+
+/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+static receive_descriptor_t *p_rxBD;
+static unsigned short localPort;
+static unsigned short serverPort;
+static unsigned serverMACSet;
+static unsigned localIPSet, serverIPSet;
+static unsigned lastSize;
+static unsigned char serverMACAddr[6];
+static unsigned char localIPAddr[4], serverIPAddr[4];
+static int ackBlock;
+static char *dlAddress;
+
+static unsigned transmitBuffer[1024 / sizeof(unsigned)];
+static unsigned tftpSendPacket[256 / sizeof(unsigned)];
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned short IP_checksum(unsigned short *p, int len)
+ * This private function calculates the IP checksum for various headers.
+ * .KB_C_FN_DEFINITION_END
+ */
+static unsigned short
+IP_checksum(unsigned short *p, int len)
+{
+ unsigned i, t;
+
+ len &= ~1;
+
+ for (i=0,t=0; i<len; i+=2, ++p)
+ t += SWAP16(*p);
+
+ t = (t & 0xffff) + (t >> 16);
+ return (~t);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void GetServerAddress(void)
+ * This private function sends an ARP request to determine the server MAC.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+GetServerAddress(void)
+{
+ arp_header_t *p_ARP;
+
+ p_ARP = (arp_header_t*)transmitBuffer;
+
+ p_memset((char*)p_ARP->dest_mac, 0xFF, 6);
+
+ memcpy(p_ARP->src_mac, localMACAddr, 6);
+
+ p_ARP->frame_type = SWAP16(PROTOCOL_ARP);
+ p_ARP->hard_type = SWAP16(1);
+ p_ARP->prot_type = SWAP16(PROTOCOL_IP);
+ p_ARP->hard_size = 6;
+ p_ARP->prot_size = 4;
+ p_ARP->operation = SWAP16(ARP_REQUEST);
+
+ memcpy(p_ARP->sender_mac, localMACAddr, 6);
+ memcpy(p_ARP->sender_ip, localIPAddr, 4);
+ p_memset((char*)p_ARP->target_mac, 0, 6);
+ memcpy(p_ARP->target_ip, serverIPAddr, 4);
+
+ // wait until transmit is available
+ while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ))
+ continue;
+
+ *AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
+ *AT91C_EMAC_TAR = (unsigned)transmitBuffer;
+ *AT91C_EMAC_TCR = 0x40;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void Send_TFTP_Packet(char *tftpData, unsigned tftpLength)
+ * This private function initializes and send a TFTP packet.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+Send_TFTP_Packet(char *tftpData, unsigned tftpLength)
+{
+ transmit_header_t *macHdr = (transmit_header_t*)tftpSendPacket;
+ ip_header_t *ipHdr;
+ udp_header_t *udpHdr;
+ unsigned t_checksum;
+
+ memcpy(macHdr->dest_mac, serverMACAddr, 6);
+ memcpy(macHdr->src_mac, localMACAddr, 6);
+ macHdr->proto_mac = SWAP16(PROTOCOL_IP);
+
+ ipHdr = (ip_header_t*)&macHdr->packet_length;
+
+ ipHdr->ip_v_hl = 0x45;
+ ipHdr->ip_tos = 0;
+ ipHdr->ip_len = SWAP16(28 + tftpLength);
+ ipHdr->ip_id = 0;
+ ipHdr->ip_off = SWAP16(0x4000);
+ ipHdr->ip_ttl = 64;
+ ipHdr->ip_p = PROTOCOL_UDP;
+ ipHdr->ip_sum = 0;
+
+ memcpy(ipHdr->ip_src, localIPAddr, 4);
+ memcpy(ipHdr->ip_dst, serverIPAddr, 4);
+
+ ipHdr->ip_sum = SWAP16(IP_checksum((unsigned short*)ipHdr, 20));
+
+ udpHdr = (udp_header_t*)(ipHdr + 1);
+
+ udpHdr->src_port = localPort;
+ udpHdr->dst_port = serverPort;
+ udpHdr->udp_len = SWAP16(8 + tftpLength);
+ udpHdr->udp_cksum = 0;
+
+ memcpy((char *)udpHdr+8, tftpData, tftpLength);
+
+ t_checksum = IP_checksum((unsigned short*)ipHdr + 6, (16 + tftpLength));
+
+ t_checksum = (~t_checksum) & 0xFFFF;
+ t_checksum += 25 + tftpLength;
+
+ t_checksum = (t_checksum & 0xffff) + (t_checksum >> 16);
+ t_checksum = (~t_checksum) & 0xFFFF;
+
+ udpHdr->udp_cksum = SWAP16(t_checksum);
+
+ while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ))
+ continue;
+
+ *AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
+ *AT91C_EMAC_TAR = (unsigned)tftpSendPacket;
+ *AT91C_EMAC_TCR = 42 + tftpLength;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void TFTP_RequestFile(char *filename)
+ * This private function sends a RRQ packet to the server.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+TFTP_RequestFile(char *filename)
+{
+ tftp_header_t tftpHeader;
+ char *cPtr, *ePtr, *mPtr;
+ unsigned length;
+
+ tftpHeader.opcode = TFTP_RRQ_OPCODE;
+
+ cPtr = (char*)&(tftpHeader.block_num);
+
+ ePtr = strcpy(cPtr, filename);
+ mPtr = strcpy(ePtr, "octet");
+
+ length = mPtr - cPtr;
+ length += 2;
+
+ Send_TFTP_Packet((char*)&tftpHeader, length);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len)
+ * This private function sends an ACK packet to the server.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+TFTP_ACK_Data(unsigned char *data, unsigned short block_num, unsigned short len)
+{
+ tftp_header_t tftpHeader;
+
+ if (block_num == (ackBlock + 1)) {
+ ++ackBlock;
+ memcpy(dlAddress, data, len);
+ dlAddress += len;
+ lastSize += len;
+ if (ackBlock % 128 == 0)
+ printf("tftp: %u kB\r", lastSize / 1024);
+ }
+ tftpHeader.opcode = TFTP_ACK_OPCODE;
+ tftpHeader.block_num = SWAP16(ackBlock);
+ Send_TFTP_Packet((char*)&tftpHeader, 4);
+ if (len < 512) {
+ ackBlock = -2;
+ printf("tftp: %u byte\n", lastSize);
+ }
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void CheckForNewPacket(ip_header_t *pHeader)
+ * This private function polls for received ethernet packets and handles
+ * any here.
+ * .KB_C_FN_DEFINITION_END
+ */
+static int
+CheckForNewPacket(ip_header_t *pHeader)
+{
+ unsigned short *pFrameType;
+ unsigned i;
+ char *pData;
+ ip_header_t *pIpHeader;
+ arp_header_t *p_ARP;
+ int process = 0;
+
+ process = 0;
+ for (i = 0; i < MAX_RX_PACKETS; ++i) {
+ if(p_rxBD[i].address & 0x1) {
+ process = 1;
+ (*AT91C_EMAC_RSR) |= (*AT91C_EMAC_RSR);
+ break;
+ }
+ }
+
+ if (!process)
+ return (0);
+ process = i;
+
+ pFrameType = (unsigned short *)((p_rxBD[i].address & 0xFFFFFFFC) + 12);
+ pData = (char *)(p_rxBD[i].address & 0xFFFFFFFC);
+
+ switch (*pFrameType) {
+
+ case SWAP16(PROTOCOL_ARP):
+ p_ARP = (arp_header_t*)pData;
+ if (p_ARP->operation == SWAP16(ARP_REPLY)) {
+ // check if new server info is available
+ if ((!serverMACSet) &&
+ (!(p_memcmp((char*)p_ARP->sender_ip,
+ (char*)serverIPAddr, 4)))) {
+
+ serverMACSet = 1;
+ memcpy(serverMACAddr, p_ARP->sender_mac, 6);
+ }
+ } else if (p_ARP->operation == SWAP16(ARP_REQUEST)) {
+ // ARP REPLY operation
+ p_ARP->operation = SWAP16(ARP_REPLY);
+
+ // Fill the dest address and src address
+ for (i = 0; i <6; i++) {
+ // swap ethernet dest address and ethernet src address
+ pData[i] = pData[i+6];
+ pData[i+6] = localMACAddr[i];
+ // swap sender ethernet address and target ethernet address
+ pData[i+22] = localMACAddr[i];
+ pData[i+32] = pData[i+6];
+ }
+
+ // swap sender IP address and target IP address
+ for (i = 0; i<4; i++) {
+ pData[i+38] = pData[i+28];
+ pData[i+28] = localIPAddr[i];
+ }
+
+ if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) break;
+
+ *AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
+ *AT91C_EMAC_TAR = (unsigned)pData;
+ *AT91C_EMAC_TCR = 0x40;
+ }
+ break;
+ case SWAP16(PROTOCOL_IP):
+ pIpHeader = (ip_header_t*)(pData + 14);
+ memcpy(pHeader, pIpHeader, sizeof(ip_header_t));
+
+ if (pIpHeader->ip_p == PROTOCOL_UDP) {
+ udp_header_t *udpHdr;
+ tftp_header_t *tftpHdr;
+
+ udpHdr = (udp_header_t*)((char*)pIpHeader+20);
+ tftpHdr = (tftp_header_t*)((char*)udpHdr + 8);
+
+ if (udpHdr->dst_port != localPort)
+ break;
+
+ if (tftpHdr->opcode != TFTP_DATA_OPCODE)
+ break;
+
+ if (ackBlock == -1) {
+ if (tftpHdr->block_num != SWAP16(1))
+ break;
+ serverPort = udpHdr->src_port;
+ ackBlock = 0;
+ }
+
+ if (serverPort != udpHdr->src_port)
+ break;
+
+ TFTP_ACK_Data(tftpHdr->data,
+ SWAP16(tftpHdr->block_num),
+ SWAP16(udpHdr->udp_len) - 12);
+ }
+ }
+ p_rxBD[process].address &= ~0x01;
+ return (1);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned short AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr)
+ * This private function reads the PHY device.
+ * .KB_C_FN_DEFINITION_END
+ */
+#ifndef BOOT_BWCT
+static unsigned short
+AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr)
+{
+ unsigned value = 0x60020000 | (addr << 18);
+
+ pEmac->EMAC_CTL |= AT91C_EMAC_MPE;
+ pEmac->EMAC_MAN = value;
+ while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE));
+ pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE;
+ return (pEmac->EMAC_MAN & 0x0000ffff);
+}
+#endif
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned short AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s)
+ * This private function writes the PHY device.
+ * .KB_C_FN_DEFINITION_END
+ */
+#ifdef BOOT_TSC
+static unsigned short
+AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s)
+{
+ unsigned value = 0x50020000 | (addr << 18) | s;
+
+ pEmac->EMAC_CTL |= AT91C_EMAC_MPE;
+ pEmac->EMAC_MAN = value;
+ while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE));
+ pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE;
+ return (pEmac->EMAC_MAN & 0x0000ffff);
+}
+#endif
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void MII_GetLinkSpeed(AT91PS_EMAC pEmac)
+ * This private function determines the link speed set by the PHY.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+MII_GetLinkSpeed(AT91PS_EMAC pEmac)
+{
+#if defined(BOOT_TSC) || defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
+ unsigned short stat2;
+#endif
+ unsigned update;
+#ifdef BOOT_TSC
+ unsigned sec;
+ int i;
+#endif
+#ifdef BOOT_BWCT
+ /* hardcoded link speed since we connect a switch via MII */
+ update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ update |= AT91C_EMAC_SPD;
+ update |= AT91C_EMAC_FD;
+#endif
+#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
+ stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG);
+ if (!(stat2 & MII_STS2_LINK))
+ return ;
+ update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ if (stat2 & MII_STS2_100TX)
+ update |= AT91C_EMAC_SPD;
+ if (stat2 & MII_STS2_FDX)
+ update |= AT91C_EMAC_FD;
+#endif
+#ifdef BOOT_TSC
+ while (1) {
+ for (i = 0; i < 10; i++) {
+ stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG);
+ if (stat2 & MII_STS_LINK_STAT)
+ break;
+ printf(".");
+ sec = GetSeconds();
+ while (GetSeconds() == sec)
+ continue;
+ }
+ if (stat2 & MII_STS_LINK_STAT)
+ break;
+ printf("Resetting MII...");
+ AT91F_MII_WritePhy(pEmac, 0x0, 0x8000);
+ while (AT91F_MII_ReadPhy(pEmac, 0x0) & 0x8000) continue;
+ }
+ printf("emac: link");
+ stat2 = AT91F_MII_ReadPhy(pEmac, MII_SPEC_STS_REG);
+ update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ if (stat2 & (MII_SSTS_100FDX | MII_SSTS_100HDX)) {
+ printf(" 100TX");
+ update |= AT91C_EMAC_SPD;
+ }
+ if (stat2 & (MII_SSTS_100FDX | MII_SSTS_10FDX)) {
+ printf(" FDX");
+ update |= AT91C_EMAC_FD;
+ }
+ printf("\n");
+#endif
+ pEmac->EMAC_CFG = update;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void AT91F_EmacEntry(void)
+ * This private function initializes the EMAC on the chip.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+AT91F_EmacEntry(void)
+{
+ unsigned i;
+ char *pRxPacket = (char*)RX_DATA_START;
+ AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
+
+ p_rxBD = (receive_descriptor_t*)RX_BUFFER_START;
+ localPort = SWAP16(0x8002);
+
+ for (i = 0; i < MAX_RX_PACKETS; ++i) {
+
+ p_rxBD[i].address = (unsigned)pRxPacket;
+ p_rxBD[i].size = 0;
+ pRxPacket += RX_PACKET_SIZE;
+ }
+
+ // Set the WRAP bit at the end of the list descriptor
+ p_rxBD[MAX_RX_PACKETS-1].address |= 0x02;
+
+ if (!(pEmac->EMAC_SR & AT91C_EMAC_LINK))
+ MII_GetLinkSpeed(pEmac);
+
+ pEmac->EMAC_RBQP = (unsigned) p_rxBD;
+ pEmac->EMAC_RSR |= (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+ pEmac->EMAC_CTL = AT91C_EMAC_TE | AT91C_EMAC_RE;
+
+ pEmac->EMAC_TAR = (unsigned)transmitBuffer;
+}
+
+
+/* ************************** GLOBAL FUNCTIONS ********************************/
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SetServerIPAddress(unsigned address)
+ * This global function sets the IP of the TFTP download server.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SetServerIPAddress(unsigned address)
+{
+ // force update in case the IP has changed
+ serverMACSet = 0;
+
+ serverIPAddr[0] = (address >> 24) & 0xFF;
+ serverIPAddr[1] = (address >> 16) & 0xFF;
+ serverIPAddr[2] = (address >> 8) & 0xFF;
+ serverIPAddr[3] = (address >> 0) & 0xFF;
+
+ serverIPSet = 1;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SetLocalIPAddress(unsigned address)
+ * This global function sets the IP of this module.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SetLocalIPAddress(unsigned address)
+{
+ // force update in case the IP has changed
+ serverMACSet = 0;
+
+ localIPAddr[0] = (address >> 24) & 0xFF;
+ localIPAddr[1] = (address >> 16) & 0xFF;
+ localIPAddr[2] = (address >> 8) & 0xFF;
+ localIPAddr[3] = (address >> 0) & 0xFF;
+
+ localIPSet = 1;
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void TFTP_Download(unsigned address, char *filename)
+ * This global function initiates and processes a tftp download request.
+ * The server IP, local IP, local MAC must be set before this function is
+ * executed.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+TFTP_Download(unsigned address, char *filename)
+{
+ ip_header_t IpHeader;
+ unsigned thisSeconds;
+ int timeout;
+
+ if ((!localMACSet) || (!localIPSet) || (!serverIPSet))
+ return ;
+
+ AT91F_EmacEntry();
+ GetServerAddress();
+ dlAddress = (char*)address;
+ lastSize = 0;
+ timeout = 10;
+ thisSeconds = (GetSeconds() + 2) % 32;
+ serverPort = SWAP16(69);
+ ++localPort;
+ ackBlock = -1;
+
+ while (timeout) {
+ if (CheckForNewPacket(&IpHeader)) {
+ if (ackBlock == -2)
+ break;
+ timeout = 10;
+ thisSeconds = (GetSeconds() + 2) % 32;
+ } else if (GetSeconds() == thisSeconds) {
+ --timeout;
+ thisSeconds = (GetSeconds() + 2) % 32;
+ if (!serverMACSet)
+ GetServerAddress();
+ else if (ackBlock == -1)
+ TFTP_RequestFile(filename);
+ else {
+ // Be sure to send a NAK, which is done by
+ // ACKing the last block we got.
+ TFTP_ACK_Data(0, ackBlock, 512);
+ printf("\nNAK %u\n", ackBlock);
+ }
+ }
+ }
+ if (timeout == 0)
+ printf("TFTP TIMEOUT!\n");
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/emac.h b/usr/src/boot/sys/boot/arm/at91/libat91/emac.h
new file mode 100644
index 0000000000..fea08f8efc
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/emac.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ * Filename: emac.h
+ *
+ * Definition of routine to set the MAC address.
+ *
+ * Revision information:
+ *
+ * 28AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+
+#ifndef _EMAC_H_
+#define _EMAC_H_
+
+extern void EMAC_SetMACAddress(unsigned char addr[6]);
+extern void SetServerIPAddress(unsigned address);
+extern void SetLocalIPAddress(unsigned address);
+extern void EMAC_Init(void);
+extern void TFTP_Download(unsigned address, char *filename);
+
+#define MAX_RX_PACKETS 8
+#define RX_PACKET_SIZE 1536
+#define RX_BUFFER_START 0x21000000
+#define RX_DATA_START (RX_BUFFER_START + (8 * MAX_RX_PACKETS))
+
+#define ARP_REQUEST 0x0001
+#define ARP_REPLY 0x0002
+#define PROTOCOL_ARP 0x0806
+#define PROTOCOL_IP 0x0800
+#define PROTOCOL_UDP 0x11
+
+#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8))
+
+typedef struct {
+ unsigned address;
+ unsigned size;
+} receive_descriptor_t;
+
+typedef struct {
+
+ unsigned char dest_mac[6];
+
+ unsigned char src_mac[6];
+
+ unsigned short frame_type;
+ unsigned short hard_type;
+ unsigned short prot_type;
+ unsigned char hard_size;
+ unsigned char prot_size;
+
+ unsigned short operation;
+
+ unsigned char sender_mac[6];
+ unsigned char sender_ip[4];
+
+ unsigned char target_mac[6];
+ unsigned char target_ip[4];
+
+} __attribute__((__packed__)) arp_header_t;
+
+typedef struct {
+ unsigned char ip_v_hl;
+ unsigned char ip_tos;
+ unsigned short ip_len;
+ unsigned short ip_id;
+ unsigned short ip_off;
+ unsigned char ip_ttl;
+ unsigned char ip_p;
+ unsigned short ip_sum;
+ unsigned char ip_src[4];
+ unsigned char ip_dst[4];
+} __attribute__((__packed__)) ip_header_t;
+
+typedef struct {
+ unsigned char dest_mac[6];
+ unsigned char src_mac[6];
+ unsigned short proto_mac;
+ unsigned short packet_length;
+ ip_header_t iphdr;
+} __attribute__((__packed__)) transmit_header_t;
+
+typedef struct {
+ unsigned short src_port;
+ unsigned short dst_port;
+ unsigned short udp_len;
+ unsigned short udp_cksum;
+} __attribute__((__packed__)) udp_header_t;
+
+typedef struct {
+ unsigned short opcode;
+ unsigned short block_num;
+ unsigned char data[512];
+} __attribute__((__packed__)) tftp_header_t;
+
+// Preswap bytes
+#define TFTP_RRQ_OPCODE 0x0100
+#define TFTP_WRQ_OPCODE 0x0200
+#define TFTP_DATA_OPCODE 0x0300
+#define TFTP_ACK_OPCODE 0x0400
+#define TFTP_ERROR_OPCODE 0x0500
+
+/* MII registers definition */
+#define MII_STS_REG 0x01
+#define MII_STS_LINK_STAT 0x04
+#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
+#define MII_STS2_REG 0x11
+#define MII_STS2_LINK 0x400
+#define MII_STS2_100TX 0x4000
+#define MII_STS2_FDX 0x200
+#else
+#define MII_SPEC_STS_REG 0x11
+#define MII_SSTS_100FDX 0x8000
+#define MII_SSTS_100HDX 0x4000
+#define MII_SSTS_10FDX 0x2000
+#define MII_SSTS_10HDX 0x1000
+#endif
+
+extern unsigned char localMACAddr[6];
+extern unsigned localMAClow, localMAChigh;
+extern unsigned localMACSet;
+#define EMAC_Init()
+
+#endif /* _EMAC_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/emac_init.c b/usr/src/boot/sys/boot/arm/at91/libat91/emac_init.c
new file mode 100644
index 0000000000..a3869b67de
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/emac_init.c
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+/******************************************************************************
+ *
+ * Filename: emac.c
+ *
+ * Instantiation of routines for MAC/ethernet functions supporting tftp.
+ *
+ * Revision information:
+ *
+ * 28AUG2004 kb_admin initial creation
+ * 08JAN2005 kb_admin added tftp download
+ * also adapted from external sources
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ ******************************************************************************/
+
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+#include "emac.h"
+#include "lib.h"
+
+/* ****************************** GLOBALS *************************************/
+
+unsigned localMACSet;
+unsigned char localMACAddr[6];
+unsigned localMAClow, localMAChigh;
+
+/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void EMAC_SetMACAddress(unsigned low_address, unsigned high_address)
+ * This global function sets the MAC address. low_address is the first
+ * four bytes while high_address is the last 2 bytes of the 48-bit value.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+EMAC_SetMACAddress(unsigned char mac[6])
+{
+ AT91PS_PMC pPMC = AT91C_BASE_PMC;
+ AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
+
+ /* enable the peripheral clock before using EMAC */
+ pPMC->PMC_PCER = ((unsigned) 1 << AT91C_ID_EMAC);
+
+ memcpy(localMACAddr, mac, 6);
+ localMAClow = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
+ localMAChigh = (mac[5] << 8) | mac[4];
+ localMACSet = 1;
+
+ AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_EMAC;
+ AT91C_BASE_PIOA->PIO_ASR =
+ AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
+ AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
+ AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
+ AT91C_PIO_PA7;
+ AT91C_BASE_PIOA->PIO_PDR =
+ AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
+ AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
+ AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
+ AT91C_PIO_PA7;
+#if defined(BOOT_KB920X) | defined(BOOT_BWCT) /* Really !RMII */
+ AT91C_BASE_PIOB->PIO_BSR =
+ AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
+ AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
+ AT91C_PIO_PB18 | AT91C_PIO_PB19;
+ AT91C_BASE_PIOB->PIO_PDR =
+ AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
+ AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
+ AT91C_PIO_PB18 | AT91C_PIO_PB19;
+#endif
+ pEmac->EMAC_CTL = 0;
+
+ pEmac->EMAC_CFG = (pEmac->EMAC_CFG & ~(AT91C_EMAC_CLK)) |
+#ifdef BOOT_TSC
+ AT91C_EMAC_RMII |
+#endif
+ AT91C_EMAC_CLK_HCLK_32 | AT91C_EMAC_CAF;
+ // the sequence write EMAC_SA1L and write EMAC_SA1H must be respected
+ pEmac->EMAC_SA1L = localMAClow;
+ pEmac->EMAC_SA1H = localMAChigh;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/getc.c b/usr/src/boot/sys/boot/arm/at91/libat91/getc.c
new file mode 100644
index 0000000000..59e27a40e8
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/getc.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provided by kwikbyte without
+ * copyright as follows:
+ *
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+#include "lib.h"
+
+/*
+ * int getc(int seconds)
+ *
+ * Reads a character from the DBGU port, if one is available within about
+ * seconds seconds. It assumes that DBGU has already been initialized.
+ */
+int
+getc(int seconds)
+{
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+ unsigned thisSecond;
+
+ // Clamp to 20s
+ if (seconds > 20)
+ seconds = 20;
+ thisSecond = GetSeconds();
+ seconds = thisSecond + seconds;
+ do {
+ if ((pUSART->US_CSR & AT91C_US_RXRDY))
+ return (pUSART->US_RHR & 0xFF);
+ thisSecond = GetSeconds();
+ } while (thisSecond != seconds);
+ return (-1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/lib.h b/usr/src/boot/sys/boot/arm/at91/libat91/lib.h
new file mode 100644
index 0000000000..24ac49fd32
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/lib.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ARM_BOOT_LIB_H
+#define ARM_BOOT_LIB_H
+
+int getc(int);
+void putchar(int);
+void xputchar(int);
+void printf(const char *fmt,...);
+
+/* The following function write eeprom at ee_addr using data */
+/* from data_add for size bytes. */
+int ReadEEPROM(unsigned eeoff, unsigned char *data_addr, unsigned size);
+void WriteEEPROM(unsigned eeoff, char *data_addr, unsigned size);
+void InitEEPROM(void);
+
+/* XMODEM protocol */
+int xmodem_rx(char *dst);
+
+/* */
+void start_wdog(int n);
+void reset(void);
+
+/* Delay us */
+void Delay(int us);
+
+#define ToASCII(x) ((x > 9) ? (x + 'A' - 0xa) : (x + '0'))
+
+int p_IsWhiteSpace(char cValue);
+unsigned p_HexCharValue(char cValue);
+unsigned p_ASCIIToHex(const char *buf);
+unsigned p_ASCIIToDec(const char *buf);
+
+void p_memset(char *buffer, char value, int size);
+int p_strlen(const char *buffer);
+char *strcpy(char *to, const char *from);
+void memcpy(void *to, const void *from, unsigned size);
+int p_memcmp(const char *to, const char *from, unsigned size);
+int strcmp(const char *to, const char *from);
+
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/lib_AT91RM9200.h b/usr/src/boot/sys/boot/arm/at91/libat91/lib_AT91RM9200.h
new file mode 100644
index 0000000000..c87512f9b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/lib_AT91RM9200.h
@@ -0,0 +1,277 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBAT91RM9200_H
+#define __LIBAT91RM9200_H
+
+#include "at91rm9200.h"
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_EnablePeriphClock
+//* \brief Enable peripheral clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_EnablePeriphClock (
+ AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int periphIds) // \arg IDs of peripherals to enable
+{
+ pPMC->PMC_PCER = periphIds;
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR PIO
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgPeriph
+//* \brief Enable pins to be drived by peripheral
+//*----------------------------------------------------------------------------
+static inline
+void AT91F_PIO_CfgPeriph(
+ AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int periphAEnable, // \arg PERIPH A to enable
+ unsigned int periphBEnable) // \arg PERIPH B to enable
+
+{
+ if (periphAEnable)
+ pPio->PIO_ASR = periphAEnable;
+ if (periphBEnable)
+ pPio->PIO_BSR = periphBEnable;
+ pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR MCI
+ ***************************************************************************** */
+//* Classic MCI Data Timeout Register Configuration with 1048576 MCK cycles between 2 data transfer
+#define AT91C_MCI_DTOR_1MEGA_CYCLES (AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL)
+
+//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot A
+#define AT91C_MCI_MMC_SLOTA (AT91C_MCI_SCDSEL & 0x0)
+
+//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot B
+#define AT91C_MCI_MMC_SLOTB (AT91C_MCI_SCDSEL)
+
+//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot A
+#define AT91C_MCI_SDCARD_4BITS_SLOTA ( (AT91C_MCI_SCDSEL & 0x0) | AT91C_MCI_SCDBUS )
+
+//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot B
+#define AT91C_MCI_SDCARD_4BITS_SLOTB (AT91C_MCI_SCDSEL | AT91C_MCI_SCDBUS)
+
+
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MCI_Configure
+//* \brief Configure the MCI
+//*----------------------------------------------------------------------------
+static inline
+void AT91F_MCI_Configure(
+ AT91PS_MCI pMCI, // \arg pointer to a MCI controller
+ unsigned int DTOR_register, // \arg Data Timeout Register to be programmed
+ unsigned int MR_register, // \arg Mode Register to be programmed
+ unsigned int SDCR_register) // \arg SDCard Register to be programmed
+{
+ //* Reset the MCI
+ pMCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
+
+ //* Disable all the interrupts
+ pMCI->MCI_IDR = 0xFFFFFFFF;
+
+ //* Set the Data Timeout Register
+ pMCI->MCI_DTOR = DTOR_register;
+
+ //* Set the Mode Register
+ pMCI->MCI_MR = MR_register;
+
+ //* Set the SDCard Register
+ pMCI->MCI_SDCR = SDCR_register;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MCI_CfgPMC
+//* \brief Enable Peripheral clock in PMC for MCI
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MCI_CfgPMC(void)
+{
+ AT91F_PMC_EnablePeriphClock(
+ AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_MCI));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MCI_CfgPIO
+//* \brief Configure PIO controllers to drive MCI signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MCI_CfgPIO(void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph(
+ AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PIO_PA28 ) |
+ ((unsigned int) AT91C_PIO_PA29 ) |
+ ((unsigned int) AT91C_PIO_PA27 ), // Peripheral A
+ 0); // Peripheral B
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph(
+ AT91C_BASE_PIOB, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PIO_PB5 ) |
+ ((unsigned int) AT91C_PIO_PB3 ) |
+ ((unsigned int) AT91C_PIO_PB4 )); // Peripheral B
+}
+
+
+/* *****************************************************************************
+ SOFTWARE API FOR PDC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetNextRx
+//* \brief Set the next receive transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetNextRx (
+ AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ char *address, // \arg address to the next bloc to be received
+ unsigned int bytes) // \arg number of bytes to be received
+{
+ pPDC->PDC_RNPR = (unsigned int) address;
+ pPDC->PDC_RNCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetNextTx
+//* \brief Set the next transmit transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetNextTx(
+ AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ char *address, // \arg address to the next bloc to be transmitted
+ unsigned int bytes) // \arg number of bytes to be transmitted
+{
+ pPDC->PDC_TNPR = (unsigned int) address;
+ pPDC->PDC_TNCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetRx
+//* \brief Set the receive transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetRx(
+ AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ char *address, // \arg address to the next bloc to be received
+ unsigned int bytes) // \arg number of bytes to be received
+{
+ pPDC->PDC_RPR = (unsigned int) address;
+ pPDC->PDC_RCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetTx
+//* \brief Set the transmit transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetTx(
+ AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ char *address, // \arg address to the next bloc to be transmitted
+ unsigned int bytes) // \arg number of bytes to be transmitted
+{
+ pPDC->PDC_TPR = (unsigned int) address;
+ pPDC->PDC_TCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_EnableTx
+//* \brief Enable transmit
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_EnableTx(
+ AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_EnableRx
+//* \brief Enable receive
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_EnableRx(
+ AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_DisableTx
+//* \brief Disable transmit
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_DisableTx(
+ AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_DisableRx
+//* \brief Disable receive
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_DisableRx(
+ AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_Open
+//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_Open(
+ AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ //* Disable the RX and TX PDC transfer requests
+ AT91F_PDC_DisableRx(pPDC);
+ AT91F_PDC_DisableTx(pPDC);
+
+ //* Reset all Counter register Next buffer first
+ AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
+ AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
+ AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
+ AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
+
+ //* Enable the RX and TX PDC transfer requests
+ AT91F_PDC_EnableRx(pPDC);
+ AT91F_PDC_EnableTx(pPDC);
+}
+
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/mci_device.h b/usr/src/boot/sys/boot/arm/at91/libat91/mci_device.h
new file mode 100644
index 0000000000..c2b75ad70b
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/mci_device.h
@@ -0,0 +1,434 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+//*---------------------------------------------------------------------------
+//* ATMEL Microcontroller Software Support - ROUSSET -
+//*---------------------------------------------------------------------------
+//* The software is delivered "AS IS" without warranty or condition of any
+//* kind, either express, implied or statutory. This includes without
+//* limitation any warranty or condition with respect to merchantability or
+//* fitness for any particular purpose, or against the infringements of
+//* intellectual property rights of others.
+//*---------------------------------------------------------------------------
+//* File Name : AT91C_MCI_Device.h
+//* Object : Data Flash Atmel Description File
+//* Translator :
+//*
+//* 1.0 26/11/02 FB : Creation
+//*---------------------------------------------------------------------------
+
+#ifndef __MCI_Device_h
+#define __MCI_Device_h
+
+#include <sys/types.h>
+
+typedef unsigned int AT91S_MCIDeviceStatus;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define AT91C_CARD_REMOVED 0
+#define AT91C_MMC_CARD_INSERTED 1
+#define AT91C_SD_CARD_INSERTED 2
+
+#define AT91C_NO_ARGUMENT 0x0
+
+#define AT91C_FIRST_RCA 0xCAFE
+#define AT91C_MAX_MCI_CARDS 10
+
+#define AT91C_BUS_WIDTH_1BIT 0x00
+#define AT91C_BUS_WIDTH_4BITS 0x02
+
+/* Driver State */
+#define AT91C_MCI_IDLE 0x0
+#define AT91C_MCI_TIMEOUT_ERROR 0x1
+#define AT91C_MCI_RX_SINGLE_BLOCK 0x2
+#define AT91C_MCI_RX_MULTIPLE_BLOCK 0x3
+#define AT91C_MCI_RX_STREAM 0x4
+#define AT91C_MCI_TX_SINGLE_BLOCK 0x5
+#define AT91C_MCI_TX_MULTIPLE_BLOCK 0x6
+#define AT91C_MCI_TX_STREAM 0x7
+
+/* TimeOut */
+#define AT91C_TIMEOUT_CMDRDY 30
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// MMC & SDCard Structures
+///////////////////////////////////////////////////////////////////////////////
+
+/*---------------------------------------------*/
+/* MCI Device Structure Definition */
+/*---------------------------------------------*/
+typedef struct _AT91S_MciDevice
+{
+ volatile unsigned char state;
+ unsigned char SDCard_bus_width;
+ unsigned char IsSDv2;
+ unsigned char IsSDHC;
+ unsigned int RCA; // RCA
+ unsigned int READ_BL_LEN;
+#ifdef REPORT_SIZE
+ unsigned int Memory_Capacity;
+#endif
+} AT91S_MciDevice;
+
+#include <dev/mmc/mmcreg.h>
+
+///////////////////////////////////////////////////////////////////////////////
+// Functions returnals
+///////////////////////////////////////////////////////////////////////////////
+#define AT91C_CMD_SEND_OK 0 // Command ok
+#define AT91C_CMD_SEND_ERROR -1 // Command failed
+#define AT91C_INIT_OK 2 // Init Successfull
+#define AT91C_INIT_ERROR 3 // Init Failed
+#define AT91C_READ_OK 4 // Read Successfull
+#define AT91C_READ_ERROR 5 // Read Failed
+#define AT91C_WRITE_OK 6 // Write Successfull
+#define AT91C_WRITE_ERROR 7 // Write Failed
+#define AT91C_ERASE_OK 8 // Erase Successfull
+#define AT91C_ERASE_ERROR 9 // Erase Failed
+#define AT91C_CARD_SELECTED_OK 10 // Card Selection Successfull
+#define AT91C_CARD_SELECTED_ERROR 11 // Card Selection Failed
+
+#define AT91C_MCI_SR_ERROR (AT91C_MCI_UNRE | AT91C_MCI_OVRE | AT91C_MCI_DTOE | \
+ AT91C_MCI_DCRCE | AT91C_MCI_RTOE | AT91C_MCI_RENDE | AT91C_MCI_RCRCE | \
+ AT91C_MCI_RDIRE | AT91C_MCI_RINDE)
+
+#define MMC_CMDNB (0x1Fu << 0) // Command Number
+#define MMC_RSPTYP (0x3u << 6) // Response Type
+#define MMC_RSPTYP_NO (0x0u << 6) // No response
+#define MMC_RSPTYP_48 (0x1u << 6) // 48-bit response
+#define MMC_RSPTYP_136 (0x2u << 6) // 136-bit response
+#define MMC_SPCMD (0x7u << 8) // Special CMD
+#define MMC_SPCMD_NONE (0x0u << 8) // Not a special CMD
+#define MMC_SPCMD_INIT (0x1u << 8) // Initialization CMD
+#define MMC_SPCMD_SYNC (0x2u << 8) // Synchronized CMD
+#define MMC_SPCMD_IT_CMD (0x4u << 8) // Interrupt command
+#define MMC_SPCMD_IT_REP (0x5u << 8) // Interrupt response
+#define MMC_OPDCMD (0x1u << 11) // Open Drain Command
+#define MMC_MAXLAT (0x1u << 12) // Maximum Latency for Command to respond
+#define MMC_TRCMD (0x3u << 16) // Transfer CMD
+#define MMC_TRCMD_NO (0x0u << 16) // No transfer
+#define MMC_TRCMD_START (0x1u << 16) // Start transfer
+#define MMC_TRCMD_STOP (0x2u << 16) // Stop transfer
+#define MMC_TRDIR (0x1u << 18) // Transfer Direction
+#define MMC_TRTYP (0x3u << 19) // Transfer Type
+#define MMC_TRTYP_BLOCK (0x0u << 19) // Block Transfer type
+#define MMC_TRTYP_MULTIPLE (0x1u << 19) // Multiple Block transfer type
+#define MMC_TRTYP_STREAM (0x2u << 19) // Stream transfer type
+
+///////////////////////////////////////////////////////////////////////////////
+// MCI_CMD Register Value
+///////////////////////////////////////////////////////////////////////////////
+#define POWER_ON_INIT \
+ (0 | MMC_TRCMD_NO | MMC_SPCMD_INIT | MMC_OPDCMD)
+
+/////////////////////////////////////////////////////////////////
+// Class 0 & 1 commands: Basic commands and Read Stream commands
+/////////////////////////////////////////////////////////////////
+
+#define GO_IDLE_STATE_CMD \
+ (0 | MMC_TRCMD_NO | MMC_SPCMD_NONE )
+#define MMC_GO_IDLE_STATE_CMD \
+ (0 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_OPDCMD)
+#define MMC_SEND_OP_COND_CMD \
+ (1 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_OPDCMD)
+
+#define ALL_SEND_CID_CMD \
+ (2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136)
+#define MMC_ALL_SEND_CID_CMD \
+ (2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
+ MMC_OPDCMD)
+
+#define SET_RELATIVE_ADDR_CMD \
+ (3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+#define MMC_SET_RELATIVE_ADDR_CMD \
+ (3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT | MMC_OPDCMD)
+
+#define SET_DSR_CMD \
+ (4 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_NO | \
+ MMC_MAXLAT) // no tested
+
+#define SEL_DESEL_CARD_CMD \
+ (7 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+#define SEND_CSD_CMD \
+ (9 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
+ MMC_MAXLAT)
+#define SEND_CID_CMD \
+ (10 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
+ MMC_MAXLAT)
+#define MMC_READ_DAT_UNTIL_STOP_CMD \
+ (11 | MMC_TRTYP_STREAM | MMC_SPCMD_NONE | \
+ MMC_RSPTYP_48 | MMC_TRDIR | MMC_TRCMD_START | \
+ MMC_MAXLAT)
+
+#define STOP_TRANSMISSION_CMD \
+ (12 | MMC_TRCMD_STOP | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+#define STOP_TRANSMISSION_SYNC_CMD \
+ (12 | MMC_TRCMD_STOP | MMC_SPCMD_SYNC | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+#define SEND_STATUS_CMD \
+ (13 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+#define GO_INACTIVE_STATE_CMD \
+ (15 | MMC_RSPTYP_NO)
+#define SD_SEND_IF_COND_CMD \
+ (8 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
+ MMC_MAXLAT)
+//*------------------------------------------------
+//* Class 2 commands: Block oriented Read commands
+//*------------------------------------------------
+
+#define SET_BLOCKLEN_CMD (16 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT )
+#define READ_SINGLE_BLOCK_CMD (17 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_BLOCK | MMC_TRDIR | MMC_MAXLAT)
+#define READ_MULTIPLE_BLOCK_CMD (18 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_MULTIPLE | MMC_TRDIR | MMC_MAXLAT)
+
+//*--------------------------------------------
+//* Class 3 commands: Sequential write commands
+//*--------------------------------------------
+
+#define MMC_WRITE_DAT_UNTIL_STOP_CMD (20 | MMC_TRTYP_STREAM| MMC_SPCMD_NONE | MMC_RSPTYP_48 & ~(MMC_TRDIR) | MMC_TRCMD_START | MMC_MAXLAT ) // MMC
+
+//*------------------------------------------------
+//* Class 4 commands: Block oriented write commands
+//*------------------------------------------------
+
+#define WRITE_BLOCK_CMD (24 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_BLOCK & ~(MMC_TRDIR)) | MMC_MAXLAT)
+#define WRITE_MULTIPLE_BLOCK_CMD (25 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_MULTIPLE & ~(MMC_TRDIR)) | MMC_MAXLAT)
+#define PROGRAM_CSD_CMD (27 | MMC_RSPTYP_48 )
+
+
+//*----------------------------------------
+//* Class 6 commands: Group Write protect
+//*----------------------------------------
+
+#define SET_WRITE_PROT_CMD (28 | MMC_RSPTYP_48 )
+#define CLR_WRITE_PROT_CMD (29 | MMC_RSPTYP_48 )
+#define SEND_WRITE_PROT_CMD (30 | MMC_RSPTYP_48 )
+
+
+//*----------------------------------------
+//* Class 5 commands: Erase commands
+//*----------------------------------------
+
+#define TAG_SECTOR_START_CMD (32 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define TAG_SECTOR_END_CMD (33 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define MMC_UNTAG_SECTOR_CMD (34 | MMC_RSPTYP_48 )
+#define MMC_TAG_ERASE_GROUP_START_CMD (35 | MMC_RSPTYP_48 )
+#define MMC_TAG_ERASE_GROUP_END_CMD (36 | MMC_RSPTYP_48 )
+#define MMC_UNTAG_ERASE_GROUP_CMD (37 | MMC_RSPTYP_48 )
+#define ERASE_CMD (38 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT )
+
+//*----------------------------------------
+//* Class 7 commands: Lock commands
+//*----------------------------------------
+
+#define LOCK_UNLOCK (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested
+
+//*-----------------------------------------------
+// Class 8 commands: Application specific commands
+//*-----------------------------------------------
+
+#define APP_CMD (55 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define GEN_CMD (56 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested
+
+#define SDCARD_SET_BUS_WIDTH_CMD (6 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_STATUS_CMD (13 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_SEND_NUM_WR_BLOCKS_CMD (22 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_SET_WR_BLK_ERASE_COUNT_CMD (23 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_APP_OP_COND_CMD (41 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_SET_CLR_CARD_DETECT_CMD (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+#define SDCARD_SEND_SCR_CMD (51 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+
+#define SDCARD_APP_ALL_CMD (SDCARD_SET_BUS_WIDTH_CMD +\
+ SDCARD_STATUS_CMD +\
+ SDCARD_SEND_NUM_WR_BLOCKS_CMD +\
+ SDCARD_SET_WR_BLK_ERASE_COUNT_CMD +\
+ SDCARD_APP_OP_COND_CMD +\
+ SDCARD_SET_CLR_CARD_DETECT_CMD +\
+ SDCARD_SEND_SCR_CMD)
+
+//*----------------------------------------
+//* Class 9 commands: IO Mode commands
+//*----------------------------------------
+
+#define MMC_FAST_IO_CMD (39 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT)
+#define MMC_GO_IRQ_STATE_CMD (40 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
+
+///////////////////////////////////////////////////////////////////////////////
+// OCR Register
+///////////////////////////////////////////////////////////////////////////////
+#define AT91C_VDD_16_17 (1 << 4)
+#define AT91C_VDD_17_18 (1 << 5)
+#define AT91C_VDD_18_19 (1 << 6)
+#define AT91C_VDD_19_20 (1 << 7)
+#define AT91C_VDD_20_21 (1 << 8)
+#define AT91C_VDD_21_22 (1 << 9)
+#define AT91C_VDD_22_23 (1 << 10)
+#define AT91C_VDD_23_24 (1 << 11)
+#define AT91C_VDD_24_25 (1 << 12)
+#define AT91C_VDD_25_26 (1 << 13)
+#define AT91C_VDD_26_27 (1 << 14)
+#define AT91C_VDD_27_28 (1 << 15)
+#define AT91C_VDD_28_29 (1 << 16)
+#define AT91C_VDD_29_30 (1 << 17)
+#define AT91C_VDD_30_31 (1 << 18)
+#define AT91C_VDD_31_32 (1 << 19)
+#define AT91C_VDD_32_33 (1 << 20)
+#define AT91C_VDD_33_34 (1 << 21)
+#define AT91C_VDD_34_35 (1 << 22)
+#define AT91C_VDD_35_36 (1 << 23)
+#define AT91C_CCS (1 << 30)
+#define AT91C_CARD_POWER_UP_DONE (1U << 31)
+
+#define AT91C_MMC_HOST_VOLTAGE_RANGE (AT91C_VDD_27_28 | AT91C_VDD_28_29 | \
+ AT91C_VDD_29_30 | AT91C_VDD_30_31 | AT91C_VDD_31_32 | AT91C_VDD_32_33)
+
+///////////////////////////////////////////////////////////////////////////////
+// CURRENT_STATE & READY_FOR_DATA in SDCard Status Register definition (response type R1)
+///////////////////////////////////////////////////////////////////////////////
+#define AT91C_SR_READY_FOR_DATA (1 << 8) // corresponds to buffer empty signalling on the bus
+#define AT91C_SR_IDLE (0 << 9)
+#define AT91C_SR_READY (1 << 9)
+#define AT91C_SR_IDENT (2 << 9)
+#define AT91C_SR_STBY (3 << 9)
+#define AT91C_SR_TRAN (4 << 9)
+#define AT91C_SR_DATA (5 << 9)
+#define AT91C_SR_RCV (6 << 9)
+#define AT91C_SR_PRG (7 << 9)
+#define AT91C_SR_DIS (8 << 9)
+
+#define AT91C_SR_CARD_SELECTED (AT91C_SR_READY_FOR_DATA + AT91C_SR_TRAN)
+
+#define MMC_FIRST_RCA 0xCAFE
+
+///////////////////////////////////////////////////////////////////////////////
+// MMC CSD register header File
+// CSD_x_xxx_S for shift value for word x
+// CSD_x_xxx_M for mask value for word x
+///////////////////////////////////////////////////////////////////////////////
+
+// First Response INT <=> CSD[3] : bits 0 to 31
+#define CSD_3_BIT0_S 0 // [0:0]
+#define CSD_3_BIT0_M 0x01
+#define CSD_3_CRC_S 1 // [7:1]
+#define CSD_3_CRC_M 0x7F
+#define CSD_3_MMC_ECC_S 8 // [9:8] reserved for MMC compatibility
+#define CSD_3_MMC_ECC_M 0x03
+#define CSD_3_FILE_FMT_S 10 // [11:10]
+#define CSD_3_FILE_FMT_M 0x03
+#define CSD_3_TMP_WP_S 12 // [12:12]
+#define CSD_3_TMP_WP_M 0x01
+#define CSD_3_PERM_WP_S 13 // [13:13]
+#define CSD_3_PERM_WP_M 0x01
+#define CSD_3_COPY_S 14 // [14:14]
+#define CSD_3_COPY_M 0x01
+#define CSD_3_FILE_FMT_GRP_S 15 // [15:15]
+#define CSD_3_FILE_FMT_GRP_M 0x01
+// reserved 16 // [20:16]
+// reserved 0x1F
+#define CSD_3_WBLOCK_P_S 21 // [21:21]
+#define CSD_3_WBLOCK_P_M 0x01
+#define CSD_3_WBLEN_S 22 // [25:22]
+#define CSD_3_WBLEN_M 0x0F
+#define CSD_3_R2W_F_S 26 // [28:26]
+#define CSD_3_R2W_F_M 0x07
+#define CSD_3_MMC_DEF_ECC_S 29 // [30:29] reserved for MMC compatibility
+#define CSD_3_MMC_DEF_ECC_M 0x03
+#define CSD_3_WP_GRP_EN_S 31 // [31:31]
+#define CSD_3_WP_GRP_EN_M 0x01
+
+// Seconde Response INT <=> CSD[2] : bits 32 to 63
+#define CSD_2_v21_WP_GRP_SIZE_S 0 // [38:32]
+#define CSD_2_v21_WP_GRP_SIZE_M 0x7F
+#define CSD_2_v21_SECT_SIZE_S 7 // [45:39]
+#define CSD_2_v21_SECT_SIZE_M 0x7F
+#define CSD_2_v21_ER_BLEN_EN_S 14 // [46:46]
+#define CSD_2_v21_ER_BLEN_EN_M 0x01
+
+#define CSD_2_v22_WP_GRP_SIZE_S 0 // [36:32]
+#define CSD_2_v22_WP_GRP_SIZE_M 0x1F
+#define CSD_2_v22_ER_GRP_SIZE_S 5 // [41:37]
+#define CSD_2_v22_ER_GRP_SIZE_M 0x1F
+#define CSD_2_v22_SECT_SIZE_S 10 // [46:42]
+#define CSD_2_v22_SECT_SIZE_M 0x1F
+
+#define CSD_2_C_SIZE_M_S 15 // [49:47]
+#define CSD_2_C_SIZE_M_M 0x07
+#define CSD_2_VDD_WMAX_S 18 // [52:50]
+#define CSD_2_VDD_WMAX_M 0x07
+#define CSD_2_VDD_WMIN_S 21 // [55:53]
+#define CSD_2_VDD_WMIN_M 0x07
+#define CSD_2_RCUR_MAX_S 24 // [58:56]
+#define CSD_2_RCUR_MAX_M 0x07
+#define CSD_2_RCUR_MIN_S 27 // [61:59]
+#define CSD_2_RCUR_MIN_M 0x07
+#define CSD_2_CSIZE_L_S 30 // [63:62] <=> 2 LSB of CSIZE
+#define CSD_2_CSIZE_L_M 0x03
+
+// Third Response INT <=> CSD[1] : bits 64 to 95
+#define CSD_1_CSIZE_H_S 0 // [73:64] <=> 10 MSB of CSIZE
+#define CSD_1_CSIZE_H_M 0x03FF
+// reserved 10 // [75:74]
+// reserved 0x03
+#define CSD_1_DSR_I_S 12 // [76:76]
+#define CSD_1_DSR_I_M 0x01
+#define CSD_1_RD_B_MIS_S 13 // [77:77]
+#define CSD_1_RD_B_MIS_M 0x01
+#define CSD_1_WR_B_MIS_S 14 // [78:78]
+#define CSD_1_WR_B_MIS_M 0x01
+#define CSD_1_RD_B_PAR_S 15 // [79:79]
+#define CSD_1_RD_B_PAR_M 0x01
+#define CSD_1_RD_B_LEN_S 16 // [83:80]
+#define CSD_1_RD_B_LEN_M 0x0F
+#define CSD_1_CCC_S 20 // [95:84]
+#define CSD_1_CCC_M 0x0FFF
+
+// Fourth Response INT <=> CSD[0] : bits 96 to 127
+#define CSD_0_TRANS_SPEED_S 0 // [103:96]
+#define CSD_0_TRANS_SPEED_M 0xFF
+#define CSD_0_NSAC_S 8 // [111:104]
+#define CSD_0_NSAC_M 0xFF
+#define CSD_0_TAAC_S 16 // [119:112]
+#define CSD_0_TAAC_M 0xFF
+// reserved 24 // [121:120]
+// reserved 0x03
+#define CSD_0_MMC_SPEC_VERS_S 26 // [125:122] reserved for MMC compatibility
+#define CSD_0_MMC_SPEC_VERS_M 0x0F
+#define CSD_0_STRUCT_S 30 // [127:126]
+#define CSD_0_STRUCT_M 0x03
+
+///////////////////////////////////////////////////////////////////////////////
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/memcmp.c b/usr/src/boot/sys/boot/arm/at91/libat91/memcmp.c
new file mode 100644
index 0000000000..322042f23c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/memcmp.c
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lib.h"
+
+int
+p_memcmp(const char *to, const char *from, unsigned size)
+{
+ while ((--size) && (*to++ == *from++))
+ continue;
+
+ return (size || (*to != *from));
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/memcpy.c b/usr/src/boot/sys/boot/arm/at91/libat91/memcpy.c
new file mode 100644
index 0000000000..f7544fee64
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/memcpy.c
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lib.h"
+
+void
+memcpy(void *dst, const void *src, unsigned len)
+{
+ const char *s = src;
+ char *d = dst;
+
+ while (len--)
+ *d++ = *s++;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/memset.c b/usr/src/boot/sys/boot/arm/at91/libat91/memset.c
new file mode 100644
index 0000000000..3432e640cd
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/memset.c
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lib.h"
+
+void
+p_memset(char *buffer, char value, int size)
+{
+ while (size--)
+ *buffer++ = value;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/p_string.c b/usr/src/boot/sys/boot/arm/at91/libat91/p_string.c
new file mode 100644
index 0000000000..8e7bbabb8c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/p_string.c
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Filename: p_string.c
+ *
+ * Instantiation of basic string operations to prevent inclusion of full
+ * string library. These are simple implementations not necessarily optimized
+ * for speed, but rather to show intent.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin minor updates
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "lib.h"
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void p_memset(char *buffer, char value, int size)
+ * This global function sets memory at the pointer for the specified
+ * number of bytes to value.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+p_memset(char *buffer, char value, int size)
+{
+ while (size--)
+ *buffer++ = value;
+}
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int p_memcmp(char *to, char *from, unsigned size)
+ * This global function compares data at to against data at from for
+ * size bytes. Returns 0 if the locations are equal. size must be
+ * greater than 0.
+ * .KB_C_FN_DEFINITION_END
+ */
+int
+p_memcmp(const char *to, const char *from, unsigned size)
+{
+ while ((--size) && (*to++ == *from++))
+ continue;
+
+ return (*to != *from);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/printf.c b/usr/src/boot/sys/boot/arm/at91/libat91/printf.c
new file mode 100644
index 0000000000..f2622b8590
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/printf.c
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ * Copyright (c) 2006 M. Warner Losh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdarg.h>
+#include "lib.h"
+
+void
+printf(const char *fmt,...)
+{
+ va_list ap;
+ const char *hex = "0123456789abcdef";
+ char buf[10];
+ char *s;
+ unsigned u;
+ int c;
+
+ va_start(ap, fmt);
+ while ((c = *fmt++)) {
+ if (c == '%') {
+ c = *fmt++;
+ switch (c) {
+ case 'c':
+ xputchar(va_arg(ap, int));
+ continue;
+ case 's':
+ for (s = va_arg(ap, char *); *s; s++)
+ xputchar(*s);
+ continue;
+ case 'd': /* A lie, always prints unsigned */
+ case 'u':
+ u = va_arg(ap, unsigned);
+ s = buf;
+ do
+ *s++ = '0' + u % 10U;
+ while (u /= 10U);
+ dumpbuf:;
+ while (--s >= buf)
+ xputchar(*s);
+ continue;
+ case 'x':
+ u = va_arg(ap, unsigned);
+ s = buf;
+ do
+ *s++ = hex[u & 0xfu];
+ while (u >>= 4);
+ goto dumpbuf;
+ }
+ }
+ xputchar(c);
+ }
+ va_end(ap);
+
+ return;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/putchar.c b/usr/src/boot/sys/boot/arm/at91/libat91/putchar.c
new file mode 100644
index 0000000000..2b805c98c2
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/putchar.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provided by kwikbyte without
+ * copyright as follows:
+ *
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "at91rm9200_lowlevel.h"
+#include "lib.h"
+
+/*
+ * void putchar(int ch)
+ * Writes a character to the DBGU port. It assumes that DBGU has
+ * already been initialized.
+ */
+void
+putchar(int ch)
+{
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+
+ while (!(pUSART->US_CSR & AT91C_US_TXRDY))
+ continue;
+ pUSART->US_THR = (ch & 0xFF);
+}
+
+void
+xputchar(int ch)
+{
+ if (ch == '\n')
+ putchar('\r');
+ putchar(ch);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/reset.c b/usr/src/boot/sys/boot/arm/at91/libat91/reset.c
new file mode 100644
index 0000000000..b1f083a6e7
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/reset.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "at91rm9200.h"
+#include "lib.h"
+
+/*
+ * void reset()
+ *
+ * Forces a reset of the system. Uses watchdog timer of '1', which
+ * corresponds to 128 / SLCK seconds (SLCK is 32,768 Hz, so 128/32768 is
+ * 1 / 256 ~= 5.4ms
+ */
+void
+reset(void)
+{
+ // The following should effect a reset.
+ AT91C_BASE_ST->ST_WDMR = 1 | AT91C_ST_RSTEN;
+ AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST;
+}
+
+/*
+ * void start_wdog()
+ *
+ * Starts a watchdog timer. We force the boot process to get to the point
+ * it can kick the watch dog part of the ST part for the OS's driver.
+ */
+void
+start_wdog(int n)
+{
+ // The following should effect a reset after N seconds.
+ AT91C_BASE_ST->ST_WDMR = (n * (32768 / 128)) | AT91C_ST_RSTEN;
+ AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.c b/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.c
new file mode 100644
index 0000000000..803d782d97
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.c
@@ -0,0 +1,517 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+//*----------------------------------------------------------------------------
+//* ATMEL Microcontroller Software Support - ROUSSET -
+//*----------------------------------------------------------------------------
+//* The software is delivered "AS IS" without warranty or condition of any
+//* kind, either express, implied or statutory. This includes without
+//* limitation any warranty or condition with respect to merchantability or
+//* fitness for any particular purpose, or against the infringements of
+//* intellectual property rights of others.
+//*----------------------------------------------------------------------------
+//* File Name : main.c
+//* Object : main application written in C
+//* Creation : FB 21/11/2002
+//*
+//*----------------------------------------------------------------------------
+#include "at91rm9200.h"
+#include "lib_AT91RM9200.h"
+#include "mci_device.h"
+#include "lib.h"
+#include "sd-card.h"
+
+#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
+#define SD_BLOCK_SIZE 512
+
+//* Global Variables
+static AT91S_MciDevice MCI_Device;
+
+/******************************************************************************
+**Error return codes
+******************************************************************************/
+#define MCI_UNSUPP_SIZE_ERROR 5
+#define MCI_UNSUPP_OFFSET_ERROR 6
+
+//*----------------------------------------------------------------------------
+//* \fn MCIDeviceWaitReady
+//* \brief Wait for MCI Device ready
+//*----------------------------------------------------------------------------
+static unsigned int
+MCIDeviceWaitReady(unsigned int timeout)
+{
+ volatile unsigned int status;
+ int waitfor;
+
+ if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK)
+ waitfor = AT91C_MCI_RXBUFF;
+ else
+ waitfor = AT91C_MCI_NOTBUSY;
+ do
+ {
+ status = AT91C_BASE_MCI->MCI_SR;
+ timeout--;
+ }
+ while( !(status & waitfor) && (timeout>0) );
+
+ status = AT91C_BASE_MCI->MCI_SR;
+
+ // If End of Tx Buffer Empty interrupt occurred
+ if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) {
+ AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE;
+ AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS;
+ MCI_Device.state = AT91C_MCI_IDLE;
+ } // End of if AT91C_MCI_TXBUFF
+
+ // If End of Rx Buffer Full interrupt occurred
+ if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) {
+ AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF;
+ AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS;
+ MCI_Device.state = AT91C_MCI_IDLE;
+ } // End of if AT91C_MCI_RXBUFF
+
+ //printf("WaitReady returning status %x\n", status);
+
+ return status;
+}
+
+static inline unsigned int
+swap(unsigned int v)
+{
+ unsigned int t1;
+
+ __asm __volatile("eor %1, %0, %0, ror #16\n"
+ "bic %1, %1, #0x00ff0000\n"
+ "mov %0, %0, ror #8\n"
+ "eor %0, %0, %1, lsr #8\n"
+ : "+r" (v), "=r" (t1));
+
+ return (v);
+}
+
+inline static unsigned int
+wait_ready()
+{
+ int status;
+ int timeout = AT91C_MCI_TIMEOUT;
+
+ // wait for CMDRDY Status flag to read the response
+ do
+ {
+ status = AT91C_BASE_MCI->MCI_SR;
+ } while( !(status & AT91C_MCI_CMDRDY) && (--timeout > 0) );
+
+ return status;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_SendCommand
+//* \brief Generic function to send a command to the MMC or SDCard
+//*----------------------------------------------------------------------------
+static int
+MCI_SendCommand(
+ unsigned int Cmd,
+ unsigned int Arg)
+{
+ unsigned int error;
+ unsigned int errorMask = AT91C_MCI_SR_ERROR;
+ unsigned int opcode = Cmd & 0x3F;
+
+ //printf("SendCmd %d (%x) arg %x\n", opcode, Cmd, Arg);
+
+ // Don't check response CRC on ACMD41 (R3 response type).
+
+ if (opcode == 41)
+ errorMask &= ~AT91C_MCI_RCRCE;
+
+ AT91C_BASE_MCI->MCI_ARGR = Arg;
+ AT91C_BASE_MCI->MCI_CMDR = Cmd;
+
+ error = wait_ready();
+
+ if ((error & errorMask) != 0) {
+ return (1);
+ }
+ return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_GetStatus
+//* \brief Addressed card sends its status register
+//*----------------------------------------------------------------------------
+static unsigned int
+MCI_GetStatus()
+{
+ if (MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16))
+ return 0;
+ return (AT91C_BASE_MCI->MCI_RSPR[0]);
+
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_ReadBlock
+//* \brief Start the read for a single 512-byte block
+//*----------------------------------------------------------------------------
+static int
+MCI_StartReadBlock(unsigned blknum, void *dataBuffer)
+{
+ // Init Mode Register
+ AT91C_BASE_MCI->MCI_MR |= ((SD_BLOCK_SIZE << 16) | AT91C_MCI_PDCMODE);
+
+ // (PDC) Receiver Transfer Enable
+ AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
+ AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer;
+ AT91C_BASE_PDC_MCI->PDC_RCR = SD_BLOCK_SIZE / 4;;
+ AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN;
+
+ // SDHC wants block offset, non-HC wants byte offset.
+ if (!MCI_Device.IsSDHC)
+ blknum *= SD_BLOCK_SIZE;
+
+ // Send the Read single block command
+ if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, blknum)) {
+ return AT91C_READ_ERROR;
+ }
+ MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK;
+
+ return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_readblocks
+//* \brief Read one or more blocks
+//*----------------------------------------------------------------------------
+int
+MCI_readblocks(char* dest, unsigned blknum, unsigned blkcount)
+{
+ unsigned int status;
+ unsigned int *walker;
+
+ if (MCI_Device.state != AT91C_MCI_IDLE) {
+ return 1;
+ }
+
+ if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0) {
+ return 1;
+ }
+
+ // As long as there is data to read
+ while (blkcount)
+ {
+ //Do the reading
+ if (MCI_StartReadBlock(blknum, dest))
+ return -1;
+
+ // Wait MCI Device Ready
+ status = MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
+ if (status & AT91C_MCI_SR_ERROR)
+ return 1;
+
+ // Fix erratum in MCI part - endian-swap all data.
+ for (walker = (unsigned int *)dest;
+ walker < (unsigned int *)(dest + SD_BLOCK_SIZE); walker++)
+ *walker = swap(*walker);
+
+ // Update counters & pointers
+ ++blknum;
+ --blkcount;
+ dest += SD_BLOCK_SIZE;
+ }
+
+
+ return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_read
+//* \brief Legacy read function, takes byte offset and length but was always
+//* used to read full blocks; interface preserved for existing boot code.
+//*----------------------------------------------------------------------------
+int
+MCI_read(char* dest, unsigned byteoffset, unsigned length)
+{
+ return MCI_readblocks(dest,
+ byteoffset/SD_BLOCK_SIZE, length/SD_BLOCK_SIZE);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_SDCard_SendAppCommand
+//* \brief Specific function to send a specific command to the SDCard
+//*----------------------------------------------------------------------------
+static int
+MCI_SDCard_SendAppCommand(
+ unsigned int Cmd_App,
+ unsigned int Arg)
+{
+ int status;
+
+ if ((status = MCI_SendCommand(APP_CMD, (MCI_Device.RCA << 16))) == 0)
+ status = MCI_SendCommand(Cmd_App,Arg);
+ return status;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_GetCSD
+//* \brief Asks to the specified card to send its CSD
+//*----------------------------------------------------------------------------
+static int
+MCI_GetCSD(unsigned int rca, unsigned int *response)
+{
+ if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16)))
+ return 1;
+
+ response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
+ response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
+ response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
+ response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
+
+ return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_SDCard_GetOCR
+//* \brief Wait for card to power up and determine whether it's SDHC or not.
+//*----------------------------------------------------------------------------
+static int
+MCI_SDCard_GetOCR()
+{
+ unsigned int response;
+ unsigned int arg = AT91C_MMC_HOST_VOLTAGE_RANGE;
+ int timeout = AT91C_MCI_TIMEOUT;
+
+ // Force card to idle state.
+
+ MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
+
+ // Begin probe for SDHC by sending CMD8; only v2.0 cards respond to it.
+ //
+ // Arg is vvpp where vv is voltage range and pp is an arbitrary bit
+ // pattern that gets echoed back in the response. The only voltage
+ // ranges defined are:
+ // 0x01 = 2.7 - 3.6
+ // 0x02 = "reserved for low voltage" whatever that means.
+ //
+ // If the card fails to respond then it's not v2.0. If it responds by
+ // echoing back exactly the arg we sent, then it's a v2.0 card and can
+ // run at our voltage. That means that when we send the ACMD41 (in
+ // MCI_SDCard_GetOCR) we can include the HCS bit to inquire about SDHC.
+
+ if (MCI_SendCommand(SD_SEND_IF_COND_CMD, 0x01AA) == 0) {
+ MCI_Device.IsSDv2 = (AT91C_BASE_MCI->MCI_RSPR[0] == 0x01AA);
+ }
+
+ // If we've determined the card supports v2.0 functionality, set the
+ // HCS/CCS bit to indicate that we support SDHC. This will cause a
+ // v2.0 card to report whether it is SDHC in the ACMD41 response.
+
+ if (MCI_Device.IsSDv2) {
+ arg |= AT91C_CCS;
+ }
+
+ // The RCA to be used for CMD55 in Idle state shall be the card's
+ // default RCA=0x0000.
+
+ MCI_Device.RCA = 0x0;
+
+ // Repeat ACMD41 until the card comes out of power-up-busy state.
+
+ do {
+ if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD, arg)) {
+ return 1;
+ }
+ response = AT91C_BASE_MCI->MCI_RSPR[0];
+ } while (!(response & AT91C_CARD_POWER_UP_DONE) && (--timeout > 0));
+
+ // A v2.0 card sets CCS (card capacity status) in the response if it's SDHC.
+
+ if (MCI_Device.IsSDv2) {
+ MCI_Device.IsSDHC = ((response & AT91C_CCS) == AT91C_CCS);
+ }
+
+ return (0);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn MCI_SDCard_GetCID
+//* \brief Asks to the SDCard on the chosen slot to send its CID
+//*----------------------------------------------------------------------------
+static int
+MCI_SDCard_GetCID(unsigned int *response)
+{
+ if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
+ return 1;
+
+ response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
+ response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
+ response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
+ response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
+
+ return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn sdcard_4wire
+//* \brief Set bus width to 1-bit or 4-bit according to the parm.
+//*
+//* Unlike most functions in this file, the return value from this one is
+//* bool-ish; returns 0 on failure, 1 on success.
+//*----------------------------------------------------------------------------
+int
+sdcard_use4wire(int use4wire)
+{
+ volatile int ret_value;
+
+ do {
+ ret_value=MCI_GetStatus();
+ }
+ while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0));
+
+ // If going to 4-wire mode, ask the card to turn off the DAT3 card detect
+ // pullup resistor, if going to 1-wire ask it to turn it back on.
+
+ ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_CLR_CARD_DETECT_CMD,
+ use4wire ? 0 : 1);
+ if (ret_value != AT91C_CMD_SEND_OK)
+ return 0;
+
+ // Ask the card to go into the requested mode.
+
+ ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_BUS_WIDTH_CMD,
+ use4wire ? AT91C_BUS_WIDTH_4BITS :
+ AT91C_BUS_WIDTH_1BIT);
+ if (ret_value != AT91C_CMD_SEND_OK)
+ return 0;
+
+ // Set the MCI device to match the mode we set in the card.
+
+ if (use4wire) {
+ MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_4BITS;
+ AT91C_BASE_MCI->MCI_SDCR |= AT91C_MCI_SCDBUS;
+ } else {
+ MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_1BIT;
+ AT91C_BASE_MCI->MCI_SDCR &= ~AT91C_MCI_SCDBUS;
+ }
+
+ return 1;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn sdcard_init
+//* \brief get the mci device ready to read from an SD or SDHC card.
+//*
+//* Unlike most functions in this file, the return value from this one is
+//* bool-ish; returns 0 on failure, 1 on success.
+//*----------------------------------------------------------------------------
+int
+sdcard_init(void)
+{
+ unsigned int tab_response[4];
+ int i;
+
+ // Init MCI for MMC and SDCard interface
+ AT91F_MCI_CfgPIO();
+ AT91F_MCI_CfgPMC();
+ AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
+
+ // Init Device Structure
+ MCI_Device.state = AT91C_MCI_IDLE;
+ MCI_Device.SDCard_bus_width = 0;
+ MCI_Device.IsSDv2 = 0;
+ MCI_Device.IsSDHC = 0;
+
+ // Reset the MCI and set the bus speed.
+ // Using MCK/230 gives a legal (under 400khz) bus speed for the card id
+ // sequence for all reasonable master clock speeds.
+
+ AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIDIS | 0x80;
+ AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF;
+ AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES;
+ AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 114; /* clkdiv 114 = MCK/230 */
+ AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_MMC_SLOTA;
+ AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN|AT91C_MCI_PWSEN;
+
+ // Wait for the card to come out of power-up-busy state by repeatedly
+ // sending ACMD41. This also probes for SDHC versus standard cards.
+
+ for (i = 0; i < 100; i++) {
+ if (MCI_SDCard_GetOCR() == 0)
+ break;
+ if ((i & 0x01) == 0) {
+ printf(".");
+ }
+ }
+ if (i >= 100)
+ return 0;
+
+ if (MCI_SDCard_GetCID(tab_response))
+ return 0;
+
+ // Tell the card to set its address, and remember the result.
+
+ if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
+ return 0;
+ MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
+
+ // After sending CMD3 (set addr) we can increase the clock to full speed.
+ // Using MCK/4 gives a legal (under 25mhz) bus speed for all reasonable
+ // master clock speeds.
+
+ AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 1; /* clkdiv 1 = MCK/4 */
+
+ if (MCI_GetCSD(MCI_Device.RCA,tab_response))
+ return 0;
+ MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) &
+ CSD_1_RD_B_LEN_M;
+
+#ifdef REPORT_SIZE
+ {
+ unsigned int mult,blocknr;
+ // compute MULT
+ mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
+ CSD_2_C_SIZE_M_M) + 2 );
+ // compute MSB of C_SIZE
+ blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
+ CSD_1_CSIZE_H_M) << 2;
+ // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR
+ blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) &
+ CSD_2_CSIZE_L_M)) + 1);
+ MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr;
+ printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);
+ }
+#endif
+
+ // Select card and set block length for following transfers.
+
+ if (MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16))
+ return 0;
+ if (MCI_SendCommand(SET_BLOCKLEN_CMD, SD_BLOCK_SIZE))
+ return 0;
+
+ return 1;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.h b/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.h
new file mode 100644
index 0000000000..378ad01789
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/sd-card.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __SD_CARD_H
+#define __SD_CARD_H
+
+/* MCI_read() is the original read function, taking a byte offset and byte
+ * count. It is preserved to support existing customized boot code that still
+ * refers to it; it will work fine even on SDHC cards as long as the kernel and
+ * the metadata for locating it all exist within the first 4GB of the card.
+ *
+ * MCI_readblocks() is the new read function, taking offset and length in terms
+ * of block counts (where the SD spec defines a block as 512 bytes), allowing
+ * the kernel and filesystem metadata to be located anywhere on an SDHC card.
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+int MCI_read (char* dest, unsigned bytenum, unsigned length);
+int MCI_readblocks (char* dest, unsigned blknum, unsigned blkcount);
+
+/* sdcard_init() - get things set up to read from an SD or SDHC card.
+ *
+ * Returns 0 on failure, non-zero on success.
+ */
+
+int sdcard_init(void);
+
+/* By default sdcard_init() sets things up for a 1-wire interface to the
+ * SD card. Calling sdcard_4wire(true) after sdcard_init() allows customized
+ * boot code to change to 4-bit transfers when the hardware supports it.
+ *
+ * Returns 0 on failure, non-zero on success.
+ */
+int sdcard_use4wire(int use4wire);
+
+#endif
+
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.c b/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.c
new file mode 100644
index 0000000000..388e64e202
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.c
@@ -0,0 +1,267 @@
+/******************************************************************************
+ *
+ * Filename: spi_flash.c
+ *
+ * Instantiation of SPI flash control routines supporting AT45DB161B
+ *
+ * Revision information:
+ *
+ * 17JAN2005 kb_admin initial creation
+ * adapted from external sources
+ * tested for basic operation only!!!
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+#include "at91rm9200.h"
+#include "spi_flash.h"
+#include "lib.h"
+
+/*********************** PRIVATE FUNCTIONS/DATA ******************************/
+
+
+static spiCommand_t spi_command;
+static char tx_commandBuffer[8], rx_commandBuffer[8];
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SendCommand(spiCommand_t *pCommand)
+ * Private function sends 8-bit value to the device and returns the 8-bit
+ * value in response.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+SendCommand(spiCommand_t *pCommand)
+{
+ AT91PS_SPI pSPI = AT91C_BASE_SPI;
+
+ pSPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
+
+ pSPI->SPI_RPR = (unsigned)pCommand->rx_cmd;
+ pSPI->SPI_RCR = pCommand->rx_cmd_size;
+ pSPI->SPI_TPR = (unsigned)pCommand->tx_cmd;
+ pSPI->SPI_TCR = pCommand->tx_cmd_size;
+
+ pSPI->SPI_TNPR = (unsigned)pCommand->tx_data;
+ pSPI->SPI_TNCR = pCommand->tx_data_size;
+ pSPI->SPI_RNPR = (unsigned)pCommand->rx_data;
+ pSPI->SPI_RNCR = pCommand->rx_data_size;
+
+ pSPI->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
+
+ // wait for completion
+ while (!(pSPI->SPI_SR & AT91C_SPI_SPENDRX))
+ Delay(700);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * char GetFlashStatus(void)
+ * Private function to return device status.
+ * .KB_C_FN_DEFINITION_END
+ */
+static char
+GetFlashStatus(void)
+{
+ p_memset((char *)&spi_command, 0, sizeof(spi_command));
+ p_memset(tx_commandBuffer, 0, 8);
+ tx_commandBuffer[0] = STATUS_REGISTER_READ;
+ p_memset(rx_commandBuffer, 0, 8);
+ spi_command.tx_cmd = tx_commandBuffer;
+ spi_command.rx_cmd = rx_commandBuffer;
+ spi_command.rx_cmd_size = 2;
+ spi_command.tx_cmd_size = 2;
+ SendCommand(&spi_command);
+ return (rx_commandBuffer[1]);
+}
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void WaitForDeviceReady(void)
+ * Private function to poll until the device is ready for next operation.
+ * .KB_C_FN_DEFINITION_END
+ */
+static void
+WaitForDeviceReady(void)
+{
+ while (!(GetFlashStatus() & 0x80)) ;
+}
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SPI_ReadFlash(unsigned flash_addr, unsigned dest_addr, unsigned size)
+ * Global function to read the SPI flash device using the continuous read
+ * array command.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size)
+{
+ unsigned pageAddress, byteAddress;
+
+ // determine page address
+ pageAddress = flash_addr / FLASH_PAGE_SIZE;
+
+ // determine byte address
+ byteAddress = flash_addr % FLASH_PAGE_SIZE;
+
+ p_memset(tx_commandBuffer, 0, 8);
+#ifdef BOOT_BWCT
+ tx_commandBuffer[0] = 0xd2;
+ tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF);
+ tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) |
+ ((byteAddress >> 8) & 0x3);
+ tx_commandBuffer[3] = byteAddress & 0xFF;
+ spi_command.tx_cmd = tx_commandBuffer;
+ spi_command.tx_cmd_size = 8;
+ spi_command.tx_data_size = size;
+ spi_command.tx_data = dest_addr;
+
+ p_memset(rx_commandBuffer, 0, 8);
+ spi_command.rx_cmd = rx_commandBuffer;
+ spi_command.rx_cmd_size = 8;
+ spi_command.rx_data_size = size;
+ spi_command.rx_data = dest_addr;
+#else
+ tx_commandBuffer[0] = CONTINUOUS_ARRAY_READ_HF;
+ tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF);
+ tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) |
+ ((byteAddress >> 8) & 0x7);
+ tx_commandBuffer[3] = byteAddress & 0xFF;
+ spi_command.tx_cmd = tx_commandBuffer;
+ spi_command.tx_cmd_size = 5;
+ spi_command.tx_data_size = size;
+ spi_command.tx_data = dest_addr;
+
+ p_memset(rx_commandBuffer, 0, 8);
+ spi_command.rx_cmd = rx_commandBuffer;
+ spi_command.rx_cmd_size = 5;
+ spi_command.rx_data_size = size;
+ spi_command.rx_data = dest_addr;
+#endif
+
+ SendCommand(&spi_command);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SPI_WriteFlash(unsigned flash_addr, unsigned src_addr, unsigned size)
+ * Global function to program the SPI flash device. Notice the warning
+ * provided in lower-level functions regarding corruption of data in non-
+ * page aligned write operations.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SPI_WriteFlash(unsigned flash_addr, char *src_addr, unsigned size)
+{
+ unsigned pageAddress, byteAddress;
+
+ // determine page address
+ pageAddress = flash_addr / FLASH_PAGE_SIZE;
+
+ // determine byte address
+ byteAddress = flash_addr % FLASH_PAGE_SIZE;
+
+ p_memset(tx_commandBuffer, 0, 8);
+#ifdef BOOT_BWCT
+ tx_commandBuffer[0] = 0x82;
+ tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF);
+ tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) |
+ ((byteAddress >> 8) & 0x3);
+ tx_commandBuffer[3] = (byteAddress & 0xFF);
+#else
+ tx_commandBuffer[0] = PROGRAM_THROUGH_BUFFER;
+ tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF);
+ tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) |
+ ((byteAddress >> 8) & 0x7);
+ tx_commandBuffer[3] = (byteAddress & 0xFF);
+#endif
+
+ p_memset(rx_commandBuffer, 0, 8);
+
+ spi_command.tx_cmd = tx_commandBuffer;
+ spi_command.rx_cmd = rx_commandBuffer;
+ spi_command.rx_cmd_size = 4;
+ spi_command.tx_cmd_size = 4;
+
+ spi_command.tx_data_size = size;
+ spi_command.tx_data = src_addr;
+ spi_command.rx_data_size = size;
+ spi_command.rx_data = src_addr;
+
+ SendCommand(&spi_command);
+
+ WaitForDeviceReady();
+}
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void SPI_InitFlash(void)
+ * Global function to initialize the SPI flash device/accessor functions.
+ * .KB_C_FN_DEFINITION_END
+ */
+void
+SPI_InitFlash(void)
+{
+ AT91PS_PIO pPio;
+ AT91PS_SPI pSPI = AT91C_BASE_SPI;
+ unsigned value;
+
+ // enable CS0, CLK, MOSI, MISO
+ pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
+ pPio->PIO_ASR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
+ AT91C_PIO_PA2;
+ pPio->PIO_PDR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
+ AT91C_PIO_PA2;
+
+ // enable clocks to SPI
+ AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_SPI;
+
+ // reset the SPI
+ pSPI->SPI_CR = AT91C_SPI_SWRST;
+
+ pSPI->SPI_MR = (0xf << 24) | AT91C_SPI_MSTR | AT91C_SPI_MODFDIS |
+ (0xE << 16);
+
+ pSPI->SPI_CSR[0] = AT91C_SPI_CPOL | (4 << 16) | (2 << 8);
+ pSPI->SPI_CR = AT91C_SPI_SPIEN;
+
+ pSPI->SPI_PTCR = AT91C_PDC_TXTDIS;
+ pSPI->SPI_PTCR = AT91C_PDC_RXTDIS;
+ pSPI->SPI_RNPR = 0;
+ pSPI->SPI_RNCR = 0;
+ pSPI->SPI_TNPR = 0;
+ pSPI->SPI_TNCR = 0;
+ pSPI->SPI_RPR = 0;
+ pSPI->SPI_RCR = 0;
+ pSPI->SPI_TPR = 0;
+ pSPI->SPI_TCR = 0;
+ pSPI->SPI_PTCR = AT91C_PDC_RXTEN;
+ pSPI->SPI_PTCR = AT91C_PDC_TXTEN;
+
+ value = pSPI->SPI_RDR;
+ value = pSPI->SPI_SR;
+
+ value = GetFlashStatus() & 0xFC;
+#ifdef BOOT_BWCT
+ if (value != 0xB4 && value != 0xAC)
+ printf(" Bad SPI status: 0x%x\n", value);
+#else
+ if (value != 0xBC)
+ printf(" Bad SPI status: 0x%x\n", value);
+#endif
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.h b/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.h
new file mode 100644
index 0000000000..90247e1577
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/spi_flash.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ *
+ * Filename: spi_flash.h
+ *
+ * Definition of flash control routines supporting AT45DB161B
+ *
+ * Revision information:
+ *
+ * 17JAN2005 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+
+#ifndef _SPI_FLASH_H_
+#define _SPI_FLASH_H_
+
+typedef struct {
+ char *tx_cmd;
+ unsigned tx_cmd_size;
+ char *rx_cmd;
+ unsigned rx_cmd_size;
+ char *tx_data;
+ unsigned tx_data_size;
+ char *rx_data;
+ unsigned rx_data_size;
+} spiCommand_t;
+
+void SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size);
+void SPI_WriteFlash(unsigned flash_addr, char *dest_addr, unsigned size);
+void SPI_InitFlash(void);
+
+void SPI_GetId(unsigned *id);
+
+#ifdef BOOT_BWCT
+#define FLASH_PAGE_SIZE 528
+#else
+#define FLASH_PAGE_SIZE 1056
+#endif
+
+// Flash commands
+
+#define CONTINUOUS_ARRAY_READ 0xE8
+#define CONTINUOUS_ARRAY_READ_HF 0x0B
+#define CONTINUOUS_ARRAY_READ_LF 0x03
+#define STATUS_REGISTER_READ 0xD7
+#define PROGRAM_THROUGH_BUFFER 0x82
+#define MANUFACTURER_ID 0x9F
+
+#endif
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/strcmp.c b/usr/src/boot/sys/boot/arm/at91/libat91/strcmp.c
new file mode 100644
index 0000000000..de1d9e0c1e
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/strcmp.c
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lib.h"
+
+int
+strcmp(const char *s1, const char *s2)
+{
+ for (; *s1 == *s2 && *s1; s1++, s2++);
+ return (unsigned char)*s1 - (unsigned char)*s2;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/strcpy.c b/usr/src/boot/sys/boot/arm/at91/libat91/strcpy.c
new file mode 100644
index 0000000000..0bdd3a596d
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/strcpy.c
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lib.h"
+
+char *
+strcpy(char *to, const char *from)
+{
+ while (*from)
+ *to++ = *from++;
+ *to++ = '\0';
+ return (to);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/strcvt.c b/usr/src/boot/sys/boot/arm/at91/libat91/strcvt.c
new file mode 100644
index 0000000000..64442cc91b
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/strcvt.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/******************************************************************************
+ *
+ * Filename: p_string.c
+ *
+ * Instantiation of basic string operations to prevent inclusion of full
+ * string library. These are simple implementations not necessarily optimized
+ * for speed, but rather to show intent.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin minor updates
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *****************************************************************************/
+
+#include "lib.h"
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int p_IsWhiteSpace(char)
+ * This global function returns true if the character is not considered
+ * a non-space character.
+ * .KB_C_FN_DEFINITION_END
+ */
+int
+p_IsWhiteSpace(char cValue)
+{
+ return ((cValue == ' ') ||
+ (cValue == '\t') ||
+ (cValue == 0) ||
+ (cValue == '\r') ||
+ (cValue == '\n'));
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned p_HexCharValue(char)
+ * This global function returns the decimal value of the validated hex char.
+ * .KB_C_FN_DEFINITION_END
+ */
+unsigned
+p_HexCharValue(char cValue)
+{
+ if (cValue < ('9' + 1))
+ return (cValue - '0');
+ if (cValue < ('F' + 1))
+ return (cValue - 'A' + 10);
+ return (cValue - 'a' + 10);
+}
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned p_ASCIIToHex(char *)
+ * This global function set the unsigned value equal to the converted
+ * hex number passed as a string. No error checking is performed; the
+ * string must be valid hex value, point at the start of string, and be
+ * NULL-terminated.
+ * .KB_C_FN_DEFINITION_END
+ */
+unsigned
+p_ASCIIToHex(const char *buf)
+{
+ unsigned lValue = 0;
+
+ if ((*buf == '0') && ((buf[1] == 'x') || (buf[1] == 'X')))
+ buf += 2;
+
+ while (*buf) {
+ lValue <<= 4;
+ lValue += p_HexCharValue(*buf++);
+ }
+ return (lValue);
+}
+
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * unsigned p_ASCIIToDec(char *)
+ * This global function set the unsigned value equal to the converted
+ * decimal number passed as a string. No error checking is performed; the
+ * string must be valid decimal value, point at the start of string, and be
+ * NULL-terminated.
+ * .KB_C_FN_DEFINITION_END
+ */
+unsigned
+p_ASCIIToDec(const char *buf)
+{
+ unsigned v = 0;
+
+ while (*buf) {
+ v *= 10;
+ v += (*buf++) - '0';
+ }
+ return (v);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/strlen.c b/usr/src/boot/sys/boot/arm/at91/libat91/strlen.c
new file mode 100644
index 0000000000..35de89262a
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/strlen.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/******************************************************************************
+ *
+ * Filename: p_string.c
+ *
+ * Instantiation of basic string operations to prevent inclusion of full
+ * string library. These are simple implementations not necessarily optimized
+ * for speed, but rather to show intent.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin minor updates
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *****************************************************************************/
+
+#include "lib.h"
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * int p_strlen(char *)
+ * This global function returns the number of bytes starting at the pointer
+ * before (not including) the string termination character ('/0').
+ * .KB_C_FN_DEFINITION_END
+ */
+int
+p_strlen(const char *buffer)
+{
+ const char *ptr = buffer;
+ while (*ptr++)
+ continue;
+ return (ptr - buffer - 1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.c b/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.c
new file mode 100644
index 0000000000..c6a9bba823
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.c
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ * Filename: tag_list.c
+ *
+ * Instantiation of basic routines that create linux-boot tag list.
+ *
+ * Revision information:
+ *
+ * 22AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ *****************************************************************************/
+
+/******************************* GLOBALS *************************************/
+
+/********************** PRIVATE FUNCTIONS/DATA/DEFINES ***********************/
+
+#define u32 unsigned
+#define u16 unsigned short
+#define u8 unsigned char
+
+// #include "/usr/src/arm/linux/include/asm/setup.h"
+#include <linux/asm/setup.h>
+#include "tag_list.h"
+
+#define PAGE_SIZE 0x1000
+#define MEM_SIZE 0x2000000
+#define PHYS_OFFSET 0x20000000
+
+/*************************** GLOBAL FUNCTIONS ********************************/
+
+/*
+ * .KB_C_FN_DEFINITION_START
+ * void InitTagList(char*, void *)
+ * This global function populates a linux-boot style tag list from the
+ * string passed in the pointer at the location specified.
+ * .KB_C_FN_DEFINITION_END
+ */
+void InitTagList(char *parms, void *output) {
+
+ char *src, *dst;
+ struct tag *tagList = (struct tag*)output;
+
+ tagList->hdr.size = tag_size(tag_core);
+ tagList->hdr.tag = ATAG_CORE;
+ tagList->u.core.flags = 1;
+ tagList->u.core.pagesize = PAGE_SIZE;
+ tagList->u.core.rootdev = 0xff;
+ tagList = tag_next(tagList);
+
+ tagList->hdr.size = tag_size(tag_mem32);
+ tagList->hdr.tag = ATAG_MEM;
+ tagList->u.mem.size = MEM_SIZE;
+ tagList->u.mem.start = PHYS_OFFSET;
+ tagList = tag_next(tagList);
+
+ tagList->hdr.size = tag_size(tag_cmdline);
+ tagList->hdr.tag = ATAG_CMDLINE;
+
+ src = parms;
+ dst = tagList->u.cmdline.cmdline;
+ while (*src) {
+ *dst++ = *src++;
+ }
+ *dst = 0;
+
+ tagList->hdr.size += ((unsigned)(src - parms) + 1) / sizeof(unsigned);
+ tagList = tag_next(tagList);
+
+ tagList->hdr.size = 0;
+ tagList->hdr.tag = ATAG_NONE;
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.h b/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.h
new file mode 100644
index 0000000000..f98016510d
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/tag_list.h
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ *
+ * Filename: tag_list.h
+ *
+ * Definition of basic routines that create linux-boot tag list.
+ *
+ * Revision information:
+ *
+ * 22AUG2004 kb_admin initial creation
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ****************************************************************************/
+
+#ifndef _TAG_LIST_H_
+#define _TAG_LIST_H_
+
+extern void InitTagList(char *parms, void*);
+
+#endif /* _TAG_LIST_H_ */
diff --git a/usr/src/boot/sys/boot/arm/at91/libat91/xmodem.c b/usr/src/boot/sys/boot/arm/at91/libat91/xmodem.c
new file mode 100644
index 0000000000..0c4b1387dc
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/libat91/xmodem.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code. This version of xmodem has been nearly
+ * completely rewritten, but the CRC is from the original.
+ *
+ * $FreeBSD$
+ */
+
+#include "lib.h"
+
+#define PACKET_SIZE 128
+
+/* Line control codes */
+#define SOH 0x01 /* start of header */
+#define ACK 0x06 /* Acknowledge */
+#define NAK 0x15 /* Negative acknowledge */
+#define CAN 0x18 /* Cancel */
+#define EOT 0x04 /* end of text */
+
+#define TO 10
+/*
+ * int GetRecord(char , char *)
+ * This private function receives a x-modem record to the pointer and
+ * returns non-zero on success.
+ */
+static int
+GetRecord(char blocknum, char *dest)
+{
+ int size;
+ int ch;
+ unsigned chk, j;
+
+ chk = 0;
+
+ if ((ch = getc(TO)) == -1)
+ goto err;
+ if (ch != blocknum)
+ goto err;
+ if ((ch = getc(TO)) == -1)
+ goto err;
+ if (ch != (~blocknum & 0xff))
+ goto err;
+
+ for (size = 0; size < PACKET_SIZE; ++size) {
+ if ((ch = getc(TO)) == -1)
+ goto err;
+ chk = chk ^ ch << 8;
+ for (j = 0; j < 8; ++j) {
+ if (chk & 0x8000)
+ chk = chk << 1 ^ 0x1021;
+ else
+ chk = chk << 1;
+ }
+ *dest++ = ch;
+ }
+
+ chk &= 0xFFFF;
+
+ if (((ch = getc(TO)) == -1) || ((ch & 0xff) != ((chk >> 8) & 0xFF)))
+ goto err;
+ if (((ch = getc(TO)) == -1) || ((ch & 0xff) != (chk & 0xFF)))
+ goto err;
+ putchar(ACK);
+
+ return (1);
+err:;
+ putchar(CAN);
+ // We should allow for resend, but we don't.
+ return (0);
+}
+
+/*
+ * int xmodem_rx(char *)
+ * This global function receives a x-modem transmission consisting of
+ * (potentially) several blocks. Returns the number of bytes received or
+ * -1 on error.
+ */
+int
+xmodem_rx(char *dest)
+{
+ int starting, ch;
+ char packetNumber, *startAddress = dest;
+
+ packetNumber = 1;
+ starting = 1;
+
+ while (1) {
+ if (starting)
+ putchar('C');
+ if (((ch = getc(1)) == -1) || (ch != SOH && ch != EOT))
+ continue;
+ if (ch == EOT) {
+ putchar(ACK);
+ return (dest - startAddress);
+ }
+ starting = 0;
+ // Xmodem packets: SOH PKT# ~PKT# 128-bytes CRC16
+ if (!GetRecord(packetNumber, dest))
+ return (-1);
+ dest += PACKET_SIZE;
+ packetNumber++;
+ }
+
+ // the loop above should return in all cases
+ return (-1);
+}
diff --git a/usr/src/boot/sys/boot/arm/at91/linker.cfg b/usr/src/boot/sys/boot/arm/at91/linker.cfg
new file mode 100644
index 0000000000..2065ed7193
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/at91/linker.cfg
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *
+ * Filename: linker.cfg
+ *
+ * linker config file used for internal RAM or eeprom images at address 0.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin move data to SDRAM
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ .text :
+ {
+ *(.text)
+ }
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .data :
+ {
+ __data_start = . ;
+ *(.data)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.bss)
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+}
diff --git a/usr/src/boot/sys/boot/arm/ixp425/Makefile.inc b/usr/src/boot/sys/boot/arm/ixp425/Makefile.inc
new file mode 100644
index 0000000000..031b7afa61
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/Makefile.inc
@@ -0,0 +1,42 @@
+# $FreeBSD$
+
+.if !target(__ixp425_boot_Makefile.inc__)
+.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm
+
+__ixp425_boot_Makefile.inc__:
+
+# Both Avila and Pronghorn Metro are supported by ixp425
+BOOT_FLAVOR=ixp425
+
+CFLAGS+=-Os -ffreestanding \
+ -I${.CURDIR}/../../../.. \
+ -I${.CURDIR}/../../../../arm \
+ -DCPU_XSCALE_IXP425 \
+ -Wall -Waggregate-return \
+ -Werror \
+ -Wnested-externs \
+ -Wpointer-arith -Wshadow -Wwrite-strings \
+ -Wmissing-prototypes \
+ -Wmissing-declarations
+
+# -Wstrict-prototypes
+
+CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu}
+
+LD ?= ld
+OBJCOPY ?= objcopy
+
+.if defined(P)
+${P}: ${OBJS}
+ ${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS}
+
+CLEANFILES+= ${P}
+.endif
+
+.if defined(WITH_TAG_LIST)
+MK_TAG_LIST:=yes
+.else
+MK_TAG_LIST:=no
+.endif
+
+.endif
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/Makefile b/usr/src/boot/sys/boot/arm/ixp425/boot2/Makefile
new file mode 100644
index 0000000000..fe1068faef
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/Makefile
@@ -0,0 +1,78 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+# We get a lot of the std lib functions from here.
+.PATH: ${.CURDIR}/../../at91/libat91
+
+# Enable to get debug msgs
+#DEBUG=yes
+
+# Hack to search through the kernel for ufs:ad0s1a and replace it with
+# the correct one for the active slice/partition.
+FIXUP_BOOT_DRV=yes
+
+P=boot2
+FILES=${P}
+SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c
+SRCS+=memchr.c memcmp.c memcpy.c memmem.c memset.c printf.c strcmp.c strcpy.c
+SRCS+=strlen.c ashldi3.c divsi3.S muldi3.c
+SRCS+=aeabi_unwind.c
+MAN=
+
+KERNPHYSADDR=0x180000
+KERNVIRTADDR=${KERNPHYSADDR}
+BOOT_STACK=0x200000-4
+M=${MACHINE}
+LDFLAGS=-e ${KERNPHYSADDR} -EB -T ldscript.${M}
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+S=${.CURDIR}/../../../..
+
+CFLAGS+= \
+ -DBOOT_STACK=${BOOT_STACK} \
+ -I${.CURDIR}/../../../common \
+ -I${.CURDIR}
+
+.if defined(FIXUP_BOOT_DRV)
+CFLAGS+=-DFIXUP_BOOT_DRV
+.endif
+.if defined(DEBUG)
+CFLAGS+=-DDEBUG
+.endif
+
+ldscript.$M: $S/conf/ldscript.$M
+ cat $S/conf/ldscript.$M|sed s/KERNPHYSADDR/${KERNPHYSADDR}/g| \
+ sed s/KERNVIRTADDR/${KERNVIRTADDR}/g | \
+ sed s/" + SIZEOF_HEADERS"// > ldscript.$M
+
+${P}: ldscript.$M
+
+CLEANFILES+=ldscript.$M
+
+memchr.c: $S/../lib/libc/string/memchr.c
+ sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memchr.c > \
+ ${.TARGET}
+
+memmem.c: $S/../lib/libc/string/memmem.c
+ sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memmem.c > \
+ ${.TARGET}
+
+CLEANFILES+=memchr.c memmem.c
+
+ashldi3.o: $S/libkern/ashldi3.c
+ ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
+
+divsi3.o: $S/libkern/${M}/divsi3.S
+ ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
+
+muldi3.o: $S/libkern/${M}/muldi3.c
+ ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
+
+inflate.c: $S/kern/inflate.c
+ sed -e 's/extern void putstr (char/extern void putstr (const char/' < \
+ $S/kern/inflate.c > ${.TARGET}
+
+CLEANFILES+=inflate.c
+
+.include <bsd.prog.mk>
+
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/arm_init.S b/usr/src/boot/sys/boot/arm/ixp425/boot2/arm_init.S
new file mode 100644
index 0000000000..15e1e6c87e
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/arm_init.S
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2008 John Hay. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+ASENTRY_NP(start)
+/* Initialise bss and sp */
+ nop
+ adr r1, .Lstart
+ ldmia r1, {r1, r2, sp} /* Set initial stack and */
+ sub r2, r2, r1 /* get zero init data */
+ mov r3, #0
+.L1:
+ str r3, [r1], #0x0004 /* get zero init data */
+ subs r2, r2, #4
+ bgt .L1
+
+ .extern main
+ bl main
+/* main should not return. If it does, spin forever */
+infiniteLoop:
+ b infiniteLoop
+END(start)
+
+.Lstart:
+ .word _edata
+ .word _end
+ .word BOOT_STACK
+
+ENTRY(cpu_id)
+ mrc p15, 0, r0, c0, c0, 0
+ RET
+END(cpu_id)
+
+/* End */
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/boot2.c b/usr/src/boot/sys/boot/arm/ixp425/boot2/boot2.c
new file mode 100644
index 0000000000..93c4fe1aff
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/boot2.c
@@ -0,0 +1,446 @@
+/*-
+ * Copyright (c) 2008 John Hay
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/diskmbr.h>
+#include <sys/dirent.h>
+#include <sys/reboot.h>
+
+#include <machine/elf.h>
+
+#include <stdarg.h>
+
+#include "lib.h"
+#include "paths.h"
+#include "rbx.h"
+
+extern uint32_t _end;
+
+#define NOPT 6
+
+static const char optstr[NOPT] = "agnrsv";
+static const unsigned char flags[NOPT] = {
+ RBX_ASKNAME,
+ RBX_GDB,
+ RBX_NOINTR,
+ RBX_DFLTROOT,
+ RBX_SINGLE,
+ RBX_VERBOSE
+};
+
+static unsigned dsk_start;
+static char cmd[512];
+static char kname[1024];
+static uint32_t opts;
+static uint8_t dsk_meta;
+static int bootslice;
+static int bootpart;
+static int disk_layout;
+#define DL_UNKNOWN 0
+#define DL_RAW 1 /* Dangerously dedicated */
+#define DL_SLICE 2 /* Use only slices (DOS partitions) */
+#define DL_SLICEPART 3 /* Use slices and partitions */
+
+static void load(void);
+static int parse(void);
+static int dskread(void *, unsigned, unsigned);
+static int drvread(void *, unsigned, unsigned);
+#ifdef FIXUP_BOOT_DRV
+static void fixup_boot_drv(caddr_t, int, int, int);
+#endif
+
+#include "ufsread.c"
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+static inline int
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
+{
+ if ((size_t)fsread(inode, buf, nbyte) != nbyte)
+ return -1;
+ return 0;
+}
+
+static inline void
+getstr(int c)
+{
+ char *s;
+
+ s = cmd;
+ if (c == 0)
+ c = getc(10000);
+ for (;;) {
+ switch (c) {
+ case 0:
+ break;
+ case '\177':
+ case '\b':
+ if (s > cmd) {
+ s--;
+ printf("\b \b");
+ }
+ break;
+ case '\n':
+ case '\r':
+ *s = 0;
+ return;
+ default:
+ if (s - cmd < sizeof(cmd) - 1)
+ *s++ = c;
+ xputchar(c);
+ }
+ c = getc(10000);
+ }
+}
+
+int
+main(void)
+{
+ const char *bt;
+ int autoboot, c = 0;
+ ufs_ino_t ino;
+
+ dmadat = (void *)(0x1c0000);
+ p_memset((char *)dmadat, 0, 32 * 1024);
+ bt = board_init();
+
+ printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 4);
+
+ autoboot = 1;
+
+ /* Process configuration file */
+ if ((ino = lookup(PATH_CONFIG)) ||
+ (ino = lookup(PATH_DOTCONFIG)))
+ fsread(ino, cmd, sizeof(cmd));
+
+ if (*cmd) {
+ if (parse())
+ autoboot = 0;
+ printf("%s: %s\n", PATH_CONFIG, cmd);
+ /* Do not process this command twice */
+ *cmd = 0;
+ }
+
+ if (*kname == '\0')
+ strcpy(kname, PATH_KERNEL);
+
+ /* Present the user with the boot2 prompt. */
+ for (;;) {
+ printf("\nDefault: %s\nboot: ", kname);
+ if (!autoboot ||
+ (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
+ getstr(c);
+ xputchar('\n');
+ autoboot = 0;
+ c = 0;
+ DPRINTF("cmd is '%s'\n", cmd);
+ if (parse())
+ xputchar('\a');
+ else
+ load();
+ }
+}
+
+static void
+load(void)
+{
+ Elf32_Ehdr eh;
+ static Elf32_Phdr ep[2];
+ caddr_t p;
+ ufs_ino_t ino;
+ uint32_t addr;
+ int i, j;
+#ifdef FIXUP_BOOT_DRV
+ caddr_t staddr;
+ int klen;
+
+ staddr = (caddr_t)0xffffffff;
+ klen = 0;
+#endif
+ if (!(ino = lookup(kname))) {
+ if (!ls)
+ printf("No %s\n", kname);
+ return;
+ }
+ DPRINTF("Found %s\n", kname);
+ if (xfsread(ino, &eh, sizeof(eh)))
+ return;
+ if (!IS_ELF(eh)) {
+ printf("Invalid %s\n", "format");
+ return;
+ }
+ fs_off = eh.e_phoff;
+ for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
+ if (xfsread(ino, ep + j, sizeof(ep[0])))
+ return;
+ if (ep[j].p_type == PT_LOAD)
+ j++;
+ }
+ for (i = 0; i < 2; i++) {
+ p = (caddr_t)(ep[i].p_paddr & 0x0fffffff);
+ fs_off = ep[i].p_offset;
+#ifdef FIXUP_BOOT_DRV
+ if (staddr == (caddr_t)0xffffffff)
+ staddr = p;
+ klen += ep[i].p_filesz;
+#endif
+ if (xfsread(ino, p, ep[i].p_filesz))
+ return;
+ }
+ addr = eh.e_entry & 0x0fffffff;
+ DPRINTF("Entry point %x for %s\n", addr, kname);
+ clr_board();
+#ifdef FIXUP_BOOT_DRV
+ fixup_boot_drv(staddr, klen, bootslice, bootpart);
+#endif
+ ((void(*)(int))addr)(RB_BOOTINFO /* XXX | (opts & RBX_MASK) */);
+}
+
+static int
+parse()
+{
+ char *arg = cmd;
+ char *ep, *p;
+ int c, i;
+
+ while ((c = *arg++)) {
+ if (c == ' ' || c == '\t' || c == '\n')
+ continue;
+ for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
+ ep = p;
+ if (*p)
+ *p++ = 0;
+ if (c == '-') {
+ while ((c = *arg++)) {
+ for (i = 0; c != optstr[i]; i++)
+ if (i == NOPT - 1)
+ return -1;
+ opts ^= OPT_SET(flags[i]);
+ }
+ } else {
+ arg--;
+ /* look for ad0s1a:... | ad0s1:... */
+ if (strlen(arg) > 6 && arg[0] == 'a' &&
+ arg[1] == 'd' && arg[3] == 's' &&
+ (arg[5] == ':' || arg[6] == ':')) {
+ /* XXX Should also handle disk. */
+ bootslice = arg[4] - '0';
+ if (bootslice < 1 || bootslice > 4)
+ return (-1);
+ bootpart = 0;
+ if (arg[5] != ':')
+ bootpart = arg[5] - 'a';
+ if (bootpart < 0 || bootpart > 7)
+ return (-1);
+ dsk_meta = 0;
+ if (arg[5] == ':')
+ arg += 6;
+ else
+ arg += 7;
+ /* look for ad0a:... */
+ } else if (strlen(arg) > 4 && arg[0] == 'a' &&
+ arg[1] == 'd' && arg[2] == '0' && arg[4] == ':') {
+ bootslice = 0;
+ bootpart = arg[3] - 'a';
+ if (bootpart < 0 || bootpart > 7)
+ return (-1);
+ dsk_meta = 0;
+ arg += 5;
+ }
+ if ((i = ep - arg)) {
+ if ((size_t)i >= sizeof(kname))
+ return -1;
+ memcpy(kname, arg, i + 1);
+ }
+ }
+ arg = p;
+ }
+ return 0;
+}
+
+/*
+ * dskread() will try to handle the disk layouts that are typically
+ * encountered.
+ * - raw or "Dangerously Dedicated" mode. No real slice table, just the
+ * default one that is included with bsdlabel -B. Typically this is
+ * used with ROOTDEVNAME=\"ufs:ad0a\".
+ * - slice only. Only a slice table is installed with no bsd label or
+ * bsd partition table. This is typically used with
+ * ROOTDEVNAME=\"ufs:ad0s1\".
+ * - slice + bsd label + partition table. This is typically done with
+ * with fdisk + bsdlabel and is used with ROOTDEVNAME=\"ufs:ad0s1a\".
+ */
+static int
+dskread(void *buf, unsigned lba, unsigned nblk)
+{
+ struct dos_partition *dp;
+ struct disklabel *d;
+ char *sec;
+ int i;
+
+ if (!dsk_meta) {
+ sec = dmadat->secbuf;
+ dsk_start = 0;
+ if (drvread(sec, DOSBBSECTOR, 1))
+ return -1;
+ dp = (void *)(sec + DOSPARTOFF);
+ if (bootslice != 0) {
+ i = bootslice - 1;
+ if (dp[i].dp_typ != DOSPTYP_386BSD)
+ return -1;
+ } else {
+ for (i = 0; i < NDOSPART; i++) {
+ if ((dp[i].dp_typ == DOSPTYP_386BSD) &&
+ (dp[i].dp_flag == 0x80))
+ break;
+ }
+ }
+ if (i != NDOSPART) {
+ bootslice = i + 1;
+ DPRINTF("Found an active fbsd slice. (%d)\n", i + 1);
+ /*
+ * Although dp_start is aligned within the disk
+ * partition structure, DOSPARTOFF is 446, which
+ * is only word (2) aligned, not longword (4)
+ * aligned. Cope by using memcpy to fetch the
+ * start of this partition.
+ */
+ memcpy(&dsk_start, &dp[i].dp_start, 4);
+ dsk_start = swap32(dsk_start);
+ DPRINTF("dsk_start %x\n", dsk_start);
+ if ((bootslice == 4) && (dsk_start == 0)) {
+ disk_layout = DL_RAW;
+ bootslice = 0;
+ }
+ }
+ if (drvread(sec, dsk_start + LABELSECTOR, 1))
+ return -1;
+ d = (void *)(sec + LABELOFFSET);
+ if ((d->d_magic == DISKMAGIC && d->d_magic2 == DISKMAGIC) ||
+ (swap32(d->d_magic) == DISKMAGIC &&
+ swap32(d->d_magic2) == DISKMAGIC)) {
+ DPRINTF("p_size = %x\n",
+ !d->d_partitions[bootpart].p_size);
+ if (!d->d_partitions[bootpart].p_size) {
+ printf("Invalid partition\n");
+ return -1;
+ }
+ DPRINTF("p_offset %x, RAW %x\n",
+ swap32(d->d_partitions[bootpart].p_offset),
+ swap32(d->d_partitions[RAW_PART].p_offset));
+ dsk_start += swap32(d->d_partitions[bootpart].p_offset);
+ dsk_start -= swap32(d->d_partitions[RAW_PART].p_offset);
+ if ((disk_layout == DL_UNKNOWN) && (bootslice == 0))
+ disk_layout = DL_RAW;
+ else if (disk_layout == DL_UNKNOWN)
+ disk_layout = DL_SLICEPART;
+ } else {
+ disk_layout = DL_SLICE;
+ DPRINTF("Invalid %s\n", "label");
+ }
+ DPRINTF("bootslice %d, bootpart %d, dsk_start %u\n", bootslice,
+ bootpart, dsk_start);
+ dsk_meta++;
+ }
+ return drvread(buf, dsk_start + lba, nblk);
+}
+
+static int
+drvread(void *buf, unsigned lba, unsigned nblk)
+{
+ static unsigned c = 0x2d5c7c2f;
+
+ printf("%c\b", c = c << 8 | c >> 24);
+ return (avila_read((char *)buf, lba, nblk));
+}
+
+#ifdef FIXUP_BOOT_DRV
+/*
+ * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
+ * and change it to what was specified on the comandline or /boot.conf
+ * file or to what was encountered on the disk. It will try to handle 3
+ * different disk layouts, raw (dangerously dedicated), slice only and
+ * slice + partition. It will look for the following strings in the
+ * kernel, but if it is one of the first three, the string in the kernel
+ * must use the correct form to match the actual disk layout:
+ * - ufs:ad0a
+ * - ufs:ad0s1
+ * - ufs:ad0s1a
+ * - ufs:ROOTDEVNAME
+ * In the case of the first three strings, only the "a" at the end and
+ * the "1" after the "s" will be modified, if they exist. The string
+ * length will not be changed. In the case of the last string, the
+ * whole string will be built up and nul, '\0' terminated.
+ */
+static void
+fixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
+{
+ const u_int8_t op[] = "ufs:ROOTDEVNAME";
+ const u_int8_t op2[] = "ufs:ad0";
+ u_int8_t *p, *ps;
+
+ DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
+ (int)addr, klen, bs, bp);
+ if (bs > 4)
+ return;
+ if (bp > 7)
+ return;
+ ps = memmem(addr, klen, op, sizeof(op));
+ if (ps != NULL) {
+ p = ps + 4; /* past ufs: */
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
+ p += 3;
+ if (bs > 0) {
+ /* append slice */
+ *p++ = 's';
+ *p++ = bs + '0';
+ }
+ if (disk_layout != DL_SLICE) {
+ /* append partition */
+ *p++ = bp + 'a';
+ }
+ *p = '\0';
+ } else {
+ ps = memmem(addr, klen, op2, sizeof(op2) - 1);
+ if (ps != NULL) {
+ p = ps + sizeof(op2) - 1;
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ if (*p == 's') {
+ /* fix slice */
+ p++;
+ *p++ = bs + '0';
+ }
+ if (*p == 'a')
+ *p = bp + 'a';
+ }
+ }
+ if (ps == NULL) {
+ printf("Could not locate \"%s\" to fix kernel boot device, "
+ "check ROOTDEVNAME is set\n", op);
+ return;
+ }
+ DPRINTF("Changed boot device to %s\n", ps);
+}
+#endif
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/cf_ata.h b/usr/src/boot/sys/boot/arm/ixp425/boot2/cf_ata.h
new file mode 100644
index 0000000000..3c9e9e5fac
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/cf_ata.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2008 John Hay. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ARM_BOOT_CF_ATA_H
+#define ARM_BOOT_CF_ATA_H
+
+#define CF_DATA 0x00
+#define CF_ERROR 0x01
+#define CF_FEATURE 0x01
+#define CF_SECT_CNT 0x02
+#define CF_SECT_NUM 0x03
+#define CF_CYL_L 0x04
+#define CF_CYL_H 0x05
+#define CF_DRV_HEAD 0x06
+#define CF_D_MASTER 0x00
+#define CF_D_LBA 0x40
+#define CF_D_IBM 0xa0
+#define CF_STATUS 0x07
+#define CF_S_ERROR 0x01
+#define CF_S_INDEX 0x02
+#define CF_S_CORR 0x04
+#define CF_S_DRQ 0x08
+#define CF_S_DSC 0x10
+#define CF_S_DWF 0x20
+#define CF_S_READY 0x40
+#define CF_S_BUSY 0x80
+#define CF_COMMAND 0x07
+
+/* This is according to the appnote, but Sam use 0x1e in avila_ata.c */
+#define CF_ALT_STATUS 0x16
+#define CF_ALT_DEV_CTR 0x16
+#define CF_ALT_DEV_CTR2 0x1e
+#define CF_A_IDS 0x02
+#define CF_A_RESET 0x04
+#define CF_A_4BIT 0x08
+
+#define AVILA_IDE_GPIN 12
+
+#endif /* !ARM_BOOT_CF_ATA_H */
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/ixp425_board.c b/usr/src/boot/sys/boot/arm/ixp425/boot2/ixp425_board.c
new file mode 100644
index 0000000000..c13f8ed526
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/ixp425_board.c
@@ -0,0 +1,771 @@
+/*-
+ * Copyright (c) 2008 John Hay. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/ata.h>
+#include <sys/linker_set.h>
+
+#include <stdarg.h>
+
+#include "lib.h"
+#include "cf_ata.h"
+
+#include <machine/armreg.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <dev/ic/ns16550.h>
+
+struct board_config {
+ const char *desc;
+ int (*probe)(int boardtype_hint);
+ void (*init)(void);
+};
+/* set of registered boards */
+SET_DECLARE(boards, struct board_config);
+#define BOARD_CONFIG(name, _desc) \
+static struct board_config name##config = { \
+ .desc = _desc, \
+ .probe = name##_probe, \
+ .init = name##_init, \
+}; \
+DATA_SET(boards, name##config)
+
+static u_int cputype;
+#define cpu_is_ixp43x() (cputype == CPU_ID_IXP435)
+static u_int8_t *ubase;
+
+static u_int8_t uart_getreg(u_int8_t *, int);
+static void uart_setreg(u_int8_t *, int, u_int8_t);
+
+static void cf_init(void);
+static void cf_clr(void);
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+const char *
+board_init(void)
+{
+ struct board_config **pbp;
+
+ cputype = cpu_id() & CPU_ID_CPU_MASK;
+
+ SET_FOREACH(pbp, boards)
+ /* XXX pass down redboot board type */
+ if ((*pbp)->probe(0)) {
+ (*pbp)->init();
+ return (*pbp)->desc;
+ }
+ /* XXX panic, unknown board type */
+ return "???";
+}
+
+/*
+ * This should be called just before starting the kernel. This is so
+ * that one can undo incompatible hardware settings.
+ */
+void
+clr_board(void)
+{
+ cf_clr();
+}
+
+/*
+ * General support functions.
+ */
+
+/*
+ * DELAY should delay for the number of microseconds.
+ * The idea is that the inner loop should take 1us, so val is the
+ * number of usecs to delay.
+ */
+void
+DELAY(int val)
+{
+ volatile int sub;
+ volatile int subsub;
+
+ sub = val;
+ while(sub) {
+ subsub = 3;
+ while(subsub)
+ subsub--;
+ sub--;
+ }
+}
+
+u_int32_t
+swap32(u_int32_t a)
+{
+ return (((a & 0xff) << 24) | ((a & 0xff00) << 8) |
+ ((a & 0xff0000) >> 8) | ((a & 0xff000000) >> 24));
+}
+
+u_int16_t
+swap16(u_int16_t val)
+{
+ return (val << 8) | (val >> 8);
+}
+
+/*
+ * uart related funcs
+ */
+static u_int8_t
+uart_getreg(u_int8_t *bas, int off)
+{
+ return *((volatile u_int32_t *)(bas + (off << 2))) & 0xff;
+}
+
+static void
+uart_setreg(u_int8_t *bas, int off, u_int8_t val)
+{
+ *((volatile u_int32_t *)(bas + (off << 2))) = (u_int32_t)val;
+}
+
+int
+getc(int seconds)
+{
+ int c, delay, limit;
+
+ c = 0;
+ delay = 10000;
+ limit = seconds * 1000000/10000;
+ while ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == 0 && --limit)
+ DELAY(delay);
+
+ if ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == LSR_RXRDY)
+ c = uart_getreg(ubase, REG_DATA);
+
+ return c;
+}
+
+void
+putchar(int ch)
+{
+ int delay, limit;
+
+ delay = 500;
+ limit = 20;
+ while ((uart_getreg(ubase, REG_LSR) & LSR_THRE) == 0 && --limit)
+ DELAY(delay);
+ uart_setreg(ubase, REG_DATA, ch);
+
+ limit = 40;
+ while ((uart_getreg(ubase, REG_LSR) & LSR_TEMT) == 0 && --limit)
+ DELAY(delay);
+}
+
+void
+xputchar(int ch)
+{
+ if (ch == '\n')
+ putchar('\r');
+ putchar(ch);
+}
+
+void
+putstr(const char *str)
+{
+ while(*str)
+ xputchar(*str++);
+}
+
+void
+puthex8(u_int8_t ch)
+{
+ const char *hex = "0123456789abcdef";
+
+ putchar(hex[ch >> 4]);
+ putchar(hex[ch & 0xf]);
+}
+
+void
+puthexlist(const u_int8_t *str, int length)
+{
+ while(length) {
+ puthex8(*str);
+ putchar(' ');
+ str++;
+ length--;
+ }
+}
+
+/*
+ *
+ * CF/IDE functions.
+ *
+ */
+
+struct {
+ u_int64_t dsize;
+ u_int64_t total_secs;
+ u_int8_t heads;
+ u_int8_t sectors;
+ u_int32_t cylinders;
+
+ u_int32_t *cs1to;
+ u_int32_t *cs2to;
+
+ u_int8_t *cs1;
+ u_int8_t *cs2;
+
+ u_int32_t use_lba;
+ u_int32_t use_stream8;
+ u_int32_t debug;
+
+ u_int8_t status;
+ u_int8_t error;
+} dskinf;
+
+static void cfenable16(void);
+static void cfdisable16(void);
+static u_int8_t cfread8(u_int32_t off);
+static u_int16_t cfread16(u_int32_t off);
+static void cfreadstream8(void *buf, int length);
+static void cfreadstream16(void *buf, int length);
+static void cfwrite8(u_int32_t off, u_int8_t val);
+static u_int8_t cfaltread8(u_int32_t off);
+static void cfaltwrite8(u_int32_t off, u_int8_t val);
+static int cfwait(u_int8_t mask);
+static int cfaltwait(u_int8_t mask);
+static int cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head,
+ u_int32_t sector, u_int32_t count, u_int32_t feature);
+static void cfreset(void);
+#ifdef DEBUG
+static int cfgetparams(void);
+#endif
+static void cfprintregs(void);
+
+static void
+cf_init(void)
+{
+ u_int8_t status;
+#ifdef DEBUG
+ int rval;
+#endif
+
+ /* NB: board init routines setup other parts of dskinf */
+ dskinf.use_stream8 = 0;
+ dskinf.use_lba = 0;
+ dskinf.debug = 1;
+
+ DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2);
+
+ /* Setup the CF window */
+ *dskinf.cs1to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+ DPRINTF("t1 %x, ", *dskinf.cs1to);
+
+ *dskinf.cs2to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+ DPRINTF("t2 %x\n", *dskinf.cs2to);
+
+ /* Detect if there is a disk. */
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1000);
+ status = cfread8(CF_STATUS);
+ if (status != 0x50)
+ printf("cf-ata0 %x\n", (u_int32_t)status);
+ if (status == 0xff) {
+ printf("cf_ata0: No disk!\n");
+ return;
+ }
+
+ cfreset();
+
+ if (dskinf.use_stream8) {
+ DPRINTF("setting %d bit mode.\n", 8);
+ cfwrite8(CF_FEATURE, 0x01); /* Enable 8 bit transfers */
+ cfwrite8(CF_COMMAND, ATA_SETFEATURES);
+ cfaltwait(CF_S_READY);
+ }
+
+#ifdef DEBUG
+ rval = cfgetparams();
+ if (rval)
+ return;
+#endif
+ dskinf.use_lba = 1;
+ dskinf.debug = 0;
+}
+
+static void
+cf_clr(void)
+{
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ cfaltwait(CF_S_READY);
+ cfwrite8(CF_FEATURE, 0x81); /* Enable 8 bit transfers */
+ cfwrite8(CF_COMMAND, ATA_SETFEATURES);
+ cfaltwait(CF_S_READY);
+}
+
+static void
+cfenable16(void)
+{
+ u_int32_t val;
+
+ val = *dskinf.cs1to;
+ *dskinf.cs1to = val &~ EXP_BYTE_EN;
+ DELAY(100);
+#if 0
+ DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__);
+#endif
+}
+
+static void
+cfdisable16(void)
+{
+ u_int32_t val;
+
+ DELAY(100);
+ val = *dskinf.cs1to;
+ *dskinf.cs1to = val | EXP_BYTE_EN;
+#if 0
+ DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__);
+#endif
+}
+
+static u_int8_t
+cfread8(u_int32_t off)
+{
+ volatile u_int8_t *vp;
+
+ vp = (volatile u_int8_t *)(dskinf.cs1 + off);
+ return *vp;
+}
+
+static void
+cfreadstream8(void *buf, int length)
+{
+ u_int8_t *lbuf;
+ u_int8_t tmp;
+
+ lbuf = buf;
+ while (length) {
+ tmp = cfread8(CF_DATA);
+ *lbuf = tmp;
+#ifdef DEBUG
+ if (dskinf.debug && (length > (512 - 32))) {
+ if ((length % 16) == 0)
+ xputchar('\n');
+ puthex8(tmp);
+ putchar(' ');
+ }
+#endif
+ lbuf++;
+ length--;
+ }
+#ifdef DEBUG
+ if (dskinf.debug)
+ xputchar('\n');
+#endif
+}
+
+static u_int16_t
+cfread16(u_int32_t off)
+{
+ volatile u_int16_t *vp;
+
+ vp = (volatile u_int16_t *)(dskinf.cs1 + off);
+ return swap16(*vp);
+}
+
+static void
+cfreadstream16(void *buf, int length)
+{
+ u_int16_t *lbuf;
+
+ length = length / 2;
+ cfenable16();
+ lbuf = buf;
+ while (length--) {
+ *lbuf = cfread16(CF_DATA);
+ lbuf++;
+ }
+ cfdisable16();
+}
+
+static void
+cfwrite8(u_int32_t off, u_int8_t val)
+{
+ volatile u_int8_t *vp;
+
+ vp = (volatile u_int8_t *)(dskinf.cs1 + off);
+ *vp = val;
+}
+
+#if 0
+static void
+cfwrite16(u_int32_t off, u_int16_t val)
+{
+ volatile u_int16_t *vp;
+
+ vp = (volatile u_int16_t *)(dskinf.cs1 + off);
+ *vp = val;
+}
+#endif
+
+static u_int8_t
+cfaltread8(u_int32_t off)
+{
+ volatile u_int8_t *vp;
+
+ off &= 0x0f;
+ vp = (volatile u_int8_t *)(dskinf.cs2 + off);
+ return *vp;
+}
+
+static void
+cfaltwrite8(u_int32_t off, u_int8_t val)
+{
+ volatile u_int8_t *vp;
+
+ /*
+ * This is documented in the Intel appnote 302456.
+ */
+ off &= 0x0f;
+ vp = (volatile u_int8_t *)(dskinf.cs2 + off);
+ *vp = val;
+}
+
+static int
+cfwait(u_int8_t mask)
+{
+ u_int8_t status;
+ u_int32_t tout;
+
+ tout = 0;
+ while (tout <= 5000000) {
+ status = cfread8(CF_STATUS);
+ if (status == 0xff) {
+ printf("%s: master: no status, reselecting\n",
+ __func__);
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1);
+ status = cfread8(CF_STATUS);
+ }
+ if (status == 0xff)
+ return -1;
+ dskinf.status = status;
+ if (!(status & CF_S_BUSY)) {
+ if (status & CF_S_ERROR) {
+ dskinf.error = cfread8(CF_ERROR);
+ printf("%s: error, status 0x%x error 0x%x\n",
+ __func__, status, dskinf.error);
+ }
+ if ((status & mask) == mask) {
+ DPRINTF("%s: status 0x%x mask 0x%x tout %u\n",
+ __func__, status, mask, tout);
+ return (status & CF_S_ERROR);
+ }
+ }
+ if (tout > 1000) {
+ tout += 1000;
+ DELAY(1000);
+ } else {
+ tout += 10;
+ DELAY(10);
+ }
+ }
+ return -1;
+}
+
+static int
+cfaltwait(u_int8_t mask)
+{
+ u_int8_t status;
+ u_int32_t tout;
+
+ tout = 0;
+ while (tout <= 5000000) {
+ status = cfaltread8(CF_ALT_STATUS);
+ if (status == 0xff) {
+ printf("cfaltwait: master: no status, reselecting\n");
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1);
+ status = cfread8(CF_STATUS);
+ }
+ if (status == 0xff)
+ return -1;
+ dskinf.status = status;
+ if (!(status & CF_S_BUSY)) {
+ if (status & CF_S_ERROR)
+ dskinf.error = cfread8(CF_ERROR);
+ if ((status & mask) == mask) {
+ DPRINTF("cfaltwait: tout %u\n", tout);
+ return (status & CF_S_ERROR);
+ }
+ }
+ if (tout > 1000) {
+ tout += 1000;
+ DELAY(1000);
+ } else {
+ tout += 10;
+ DELAY(10);
+ }
+ }
+ return -1;
+}
+
+static int
+cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head, u_int32_t sector,
+ u_int32_t count, u_int32_t feature)
+{
+ if (cfwait(0) < 0) {
+ printf("cfcmd: timeout\n");
+ return -1;
+ }
+ cfwrite8(CF_FEATURE, feature);
+ cfwrite8(CF_CYL_L, cylinder);
+ cfwrite8(CF_CYL_H, cylinder >> 8);
+ if (dskinf.use_lba)
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM | CF_D_LBA | head);
+ else
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM | head);
+ cfwrite8(CF_SECT_NUM, sector);
+ cfwrite8(CF_SECT_CNT, count);
+ cfwrite8(CF_COMMAND, cmd);
+ return 0;
+}
+
+static void
+cfreset(void)
+{
+ u_int8_t status;
+ u_int32_t tout;
+
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1);
+#ifdef DEBUG
+ cfprintregs();
+#endif
+ cfread8(CF_STATUS);
+ cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS | CF_A_RESET);
+ DELAY(10000);
+ cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS);
+ DELAY(10000);
+ cfread8(CF_ERROR);
+ DELAY(3000);
+
+ for (tout = 0; tout < 310000; tout++) {
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1);
+ status = cfread8(CF_STATUS);
+ if (!(status & CF_S_BUSY))
+ break;
+ DELAY(100);
+ }
+ DELAY(1);
+ if (status & CF_S_BUSY) {
+ cfprintregs();
+ printf("cfreset: Status stayed busy after reset.\n");
+ }
+ DPRINTF("cfreset: finished, tout %u\n", tout);
+}
+
+#ifdef DEBUG
+static int
+cfgetparams(void)
+{
+ u_int8_t *buf;
+
+ buf = (u_int8_t *)(0x170000);
+ p_memset((char *)buf, 0, 1024);
+ /* Select the drive. */
+ cfwrite8(CF_DRV_HEAD, CF_D_IBM);
+ DELAY(1);
+ cfcmd(ATA_ATA_IDENTIFY, 0, 0, 0, 0, 0);
+ if (cfaltwait(CF_S_READY | CF_S_DSC | CF_S_DRQ)) {
+ printf("cfgetparams: ATA_IDENTIFY failed.\n");
+ return -1;
+ }
+ if (dskinf.use_stream8)
+ cfreadstream8(buf, 512);
+ else
+ cfreadstream16(buf, 512);
+ if (dskinf.debug)
+ cfprintregs();
+#if 0
+ memcpy(&dskinf.ata_params, buf, sizeof(struct ata_params));
+ dskinf.cylinders = dskinf.ata_params.cylinders;
+ dskinf.heads = dskinf.ata_params.heads;
+ dskinf.sectors = dskinf.ata_params.sectors;
+ printf("dsk0: sec %x, hd %x, cyl %x, stat %x, err %x\n",
+ (u_int32_t)dskinf.ata_params.sectors,
+ (u_int32_t)dskinf.ata_params.heads,
+ (u_int32_t)dskinf.ata_params.cylinders,
+ (u_int32_t)dskinf.status,
+ (u_int32_t)dskinf.error);
+#endif
+ dskinf.status = cfread8(CF_STATUS);
+ if (dskinf.debug)
+ printf("cfgetparams: ata_params * %x, stat %x\n",
+ (u_int32_t)buf, (u_int32_t)dskinf.status);
+ return 0;
+}
+#endif /* DEBUG */
+
+static void
+cfprintregs(void)
+{
+ u_int8_t rv;
+
+ putstr("cfprintregs: regs error ");
+ rv = cfread8(CF_ERROR);
+ puthex8(rv);
+ putstr(", count ");
+ rv = cfread8(CF_SECT_CNT);
+ puthex8(rv);
+ putstr(", sect ");
+ rv = cfread8(CF_SECT_NUM);
+ puthex8(rv);
+ putstr(", cyl low ");
+ rv = cfread8(CF_CYL_L);
+ puthex8(rv);
+ putstr(", cyl high ");
+ rv = cfread8(CF_CYL_H);
+ puthex8(rv);
+ putstr(", drv head ");
+ rv = cfread8(CF_DRV_HEAD);
+ puthex8(rv);
+ putstr(", status ");
+ rv = cfread8(CF_STATUS);
+ puthex8(rv);
+ putstr("\n");
+}
+
+int
+avila_read(char *dest, unsigned source, unsigned length)
+{
+ if (dskinf.use_lba == 0 && source == 0)
+ source++;
+ if (dskinf.debug)
+ printf("avila_read: 0x%x, sect %d num secs %d\n",
+ (u_int32_t)dest, source, length);
+ while (length) {
+ cfwait(CF_S_READY);
+ /* cmd, cyl, head, sect, count, feature */
+ cfcmd(ATA_READ, (source >> 8) & 0xffff, source >> 24,
+ source & 0xff, 1, 0);
+
+ cfwait(CF_S_READY | CF_S_DRQ | CF_S_DSC);
+ if (dskinf.use_stream8)
+ cfreadstream8(dest, 512);
+ else
+ cfreadstream16(dest, 512);
+ length--;
+ source++;
+ dest += 512;
+ }
+ return 0;
+}
+
+/*
+ * Gateworks Avila Support.
+ */
+static int
+avila_probe(int boardtype_hint)
+{
+ volatile u_int32_t *cs;
+ /*
+ * Redboot only configure the chip selects that are needed, so
+ * use that to figure out if it is an Avila or ADI board. The
+ * Avila boards use CS2 and ADI does not.
+ */
+ cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+ return (*cs != 0);
+}
+
+static void
+avila_init(void)
+{
+ /* Config the serial port. RedBoot should do the rest. */
+ ubase = (u_int8_t *)(IXP425_UART0_HWBASE);
+
+ dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET);
+ dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+ dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS1_HWBASE;
+ dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS2_HWBASE;
+
+ cf_init();
+}
+BOARD_CONFIG(avila, "Gateworks Avila");
+
+/*
+ * Gateworks Cambria Support.
+ */
+static int
+cambria_probe(int boardtype_hint)
+{
+ return cpu_is_ixp43x();
+}
+
+static void
+cambria_init(void)
+{
+ /* Config the serial port. RedBoot should do the rest. */
+ ubase = (u_int8_t *)(IXP425_UART0_HWBASE);
+
+ dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
+ dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET);
+ dskinf.cs1 = (u_int8_t *)CAMBRIA_CFSEL0_HWBASE;
+ dskinf.cs2 = (u_int8_t *)CAMBRIA_CFSEL1_HWBASE;
+
+ cf_init();
+}
+BOARD_CONFIG(cambria, "Gateworks Cambria");
+
+/*
+ * Pronghorn Metro Support.
+ */
+static int
+pronghorn_probe(int boardtype_hint)
+{
+ volatile u_int32_t *cs;
+ /*
+ * Redboot only configure the chip selects that are needed, so
+ * use that to figure out if it is an Avila or ADI board. The
+ * Avila boards use CS2 and ADI does not.
+ */
+ cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+ return (*cs == 0);
+}
+
+static void
+pronghorn_init(void)
+{
+ /* Config the serial port. RedBoot should do the rest. */
+ ubase = (u_int8_t *)(IXP425_UART1_HWBASE);
+
+ dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
+ dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET);
+ dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS3_HWBASE;
+ dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS4_HWBASE;
+
+ cf_init();
+}
+BOARD_CONFIG(pronghorn, "Pronghorn Metro");
diff --git a/usr/src/boot/sys/boot/arm/ixp425/boot2/lib.h b/usr/src/boot/sys/boot/arm/ixp425/boot2/lib.h
new file mode 100644
index 0000000000..9c88030c25
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/ixp425/boot2/lib.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2008 John Hay. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ARM_BOOT_LIB_H
+#define ARM_BOOT_LIB_H
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+int main(void);
+
+void DELAY(int);
+
+int getc(int);
+void putchar(int);
+void xputchar(int);
+void putstr(const char *);
+void puthex8(u_int8_t);
+void puthexlist(const u_int8_t *, int);
+void printf(const char *fmt,...);
+
+void bzero(void *, size_t);
+char *strcpy(char *to, const char *from);
+int strcmp(const char *to, const char *from);
+int p_strlen(const char *);
+int p_memcmp(const char *, const char *, unsigned);
+void *memchr(const void *, int, size_t);
+void memcpy(void *to, const void *from, unsigned size);
+void *memmem(const void *, size_t, const void *, size_t);
+void p_memset(char *buffer, char value, int size);
+
+#define strlen p_strlen
+#define memcmp p_memcmp
+#define memset p_memset
+
+u_int16_t swap16(u_int16_t);
+u_int32_t swap32(u_int32_t);
+
+const char *board_init(void);
+void clr_board(void);
+int avila_read(char*, unsigned, unsigned);
+u_int cpu_id(void);
+
+#endif /* !ARM_BOOT_LIB_H */
diff --git a/usr/src/boot/sys/boot/arm/uboot/Makefile b/usr/src/boot/sys/boot/arm/uboot/Makefile
new file mode 100644
index 0000000000..7f0fd2e643
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/Makefile
@@ -0,0 +1,159 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+FILES= ubldr ubldr.bin
+
+NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH}
+BINDIR?= /boot
+INSTALLFLAGS= -b
+WARNS?= 1
+# Address at which ubldr will be loaded.
+# This varies for different boards and SOCs.
+UBLDR_LOADADDR?= 0x1000000
+
+# Architecture-specific loader code
+SRCS= start.S conf.c self_reloc.c vers.c
+
+.if !defined(LOADER_NO_DISK_SUPPORT)
+LOADER_DISK_SUPPORT?= yes
+.else
+LOADER_DISK_SUPPORT= no
+.endif
+LOADER_UFS_SUPPORT?= yes
+LOADER_CD9660_SUPPORT?= no
+LOADER_EXT2FS_SUPPORT?= no
+.if ${MK_NAND} != "no"
+LOADER_NANDFS_SUPPORT?= yes
+.else
+LOADER_NANDFS_SUPPORT?= no
+.endif
+LOADER_NET_SUPPORT?= yes
+LOADER_NFS_SUPPORT?= yes
+LOADER_TFTP_SUPPORT?= no
+LOADER_GZIP_SUPPORT?= no
+LOADER_BZIP2_SUPPORT?= no
+.if ${MK_FDT} != "no"
+LOADER_FDT_SUPPORT= yes
+.else
+LOADER_FDT_SUPPORT= no
+.endif
+
+.if ${LOADER_DISK_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_DISK_SUPPORT
+.endif
+.if ${LOADER_UFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_UFS_SUPPORT
+.endif
+.if ${LOADER_CD9660_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_CD9660_SUPPORT
+.endif
+.if ${LOADER_EXT2FS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_EXT2FS_SUPPORT
+.endif
+.if ${LOADER_NANDFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NANDFS_SUPPORT
+.endif
+.if ${LOADER_GZIP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_GZIP_SUPPORT
+.endif
+.if ${LOADER_BZIP2_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_BZIP2_SUPPORT
+.endif
+.if ${LOADER_NET_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NET_SUPPORT
+.endif
+.if ${LOADER_NFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NFS_SUPPORT
+.endif
+.if ${LOADER_TFTP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_TFTP_SUPPORT
+.endif
+.if ${LOADER_FDT_SUPPORT} == "yes"
+CFLAGS+= -I${.CURDIR}/../../fdt
+CFLAGS+= -I${.OBJDIR}/../../fdt
+CFLAGS+= -DLOADER_FDT_SUPPORT
+LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a
+LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
+.endif
+
+CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE
+
+.if ${MK_FORTH} != "no"
+# Enable BootForth
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/arm
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I.
+
+CLEANFILES+= vers.c loader.help
+
+CFLAGS+= -ffreestanding -msoft-float
+
+LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
+
+# Pull in common loader code
+.PATH: ${.CURDIR}/../../uboot/common
+.include "${.CURDIR}/../../uboot/common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../uboot/common
+
+# U-Boot standalone support library
+LIBUBOOT= ${.OBJDIR}/../../uboot/lib/libuboot.a
+CFLAGS+= -I${.CURDIR}/../../uboot/lib
+CFLAGS+= -I${.OBJDIR}/../../uboot/lib
+
+# where to get libstand from
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+# clang doesn't understand %D as a specifier to printf
+NO_WERROR.clang=
+
+DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} -lstand
+
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+
+loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt
+ cat ${.ALLSRC} | \
+ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+
+ldscript.abs:
+ echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET}
+
+ldscript.pie:
+ echo "UBLDR_LOADADDR = 0;" >${.TARGET}
+
+ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD}
+ ${CC} ${CFLAGS} -T ldscript.abs ${LDFLAGS} \
+ -o ${.TARGET} ${OBJS} ${LDADD}
+
+ubldr.pie: ${OBJS} ldscript.pie ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD}
+ ${CC} ${CFLAGS} -T ldscript.pie ${LDFLAGS} -pie -Wl,-Bsymbolic \
+ -o ${.TARGET} ${OBJS} ${LDADD}
+
+ubldr.bin: ubldr.pie
+ ${OBJCOPY} -S -O binary ubldr.pie ${.TARGET}
+
+CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin
+
+.if !defined(LOADER_ONLY)
+.PATH: ${.CURDIR}/../../forth
+.include "${.CURDIR}/../../forth/Makefile.inc"
+
+# Install loader.rc.
+FILES+= loader.rc
+# Put sample menu.rc on disk but don't enable it by default.
+FILES+= menu.rc
+FILESNAME_menu.rc= menu.rc.sample
+.endif
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/arm/uboot/conf.c b/usr/src/boot/sys/boot/arm/uboot/conf.c
new file mode 100644
index 0000000000..03dc64125e
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/conf.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2008 Semihalf, Rafal Jaworowski
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+#include "libuboot.h"
+
+#if defined(LOADER_NET_SUPPORT)
+#include "dev_net.h"
+#endif
+
+struct devsw *devsw[] = {
+#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT)
+ &uboot_storage,
+#endif
+#if defined(LOADER_NET_SUPPORT)
+ &netdev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+#if defined(LOADER_UFS_SUPPORT)
+ &ufs_fsops,
+#endif
+#if defined(LOADER_CD9660_SUPPORT)
+ &cd9660_fsops,
+#endif
+#if defined(LOADER_EXT2FS_SUPPORT)
+ &ext2fs_fsops,
+#endif
+#if defined(LOADER_NANDFS_SUPPORT)
+ &nandfs_fsops,
+#endif
+#if defined(LOADER_NFS_SUPPORT)
+ &nfs_fsops,
+#endif
+#if defined(LOADER_TFTP_SUPPORT)
+ &tftp_fsops,
+#endif
+#if defined(LOADER_GZIP_SUPPORT)
+ &gzipfs_fsops,
+#endif
+#if defined(LOADER_BZIP2_SUPPORT)
+ &bzipfs_fsops,
+#endif
+ NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+#if defined(LOADER_NET_SUPPORT)
+ &uboot_net,
+#endif
+ NULL,
+};
+
+struct file_format *file_formats[] = {
+ &uboot_elf,
+ NULL
+};
+
+extern struct console uboot_console;
+
+struct console *consoles[] = {
+ &uboot_console,
+ NULL
+};
diff --git a/usr/src/boot/sys/boot/arm/uboot/help.uboot b/usr/src/boot/sys/boot/arm/uboot/help.uboot
new file mode 100644
index 0000000000..c1574af927
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/help.uboot
@@ -0,0 +1,27 @@
+$FreeBSD$
+
+###############################################################################
+# Tubenv DShow or import U-Boot environment variables
+
+ ubenv <import | show> [varname ...]
+
+ Display U-Boot environment variables, or import them into the
+ loader environment (which makes them available in the kernel).
+
+###############################################################################
+# Tubenv Simport DImport U-Boot env vars
+
+ ubenv import [varname ...]
+
+ If no variable names are specified, all U-Boot environment
+ variables are imported. Each variable is prefixed with "uboot."
+ to avoid any possible conflicts with loader or kernel variables.
+
+###############################################################################
+# Tubenv Sshow DShow U-Boot env vars
+
+ ubenv show [varname ...]
+
+ If no variable names are specified, all U-Boot environment
+ variables are shown.
+
diff --git a/usr/src/boot/sys/boot/arm/uboot/ldscript.arm b/usr/src/boot/sys/boot/arm/uboot/ldscript.arm
new file mode 100644
index 0000000000..1eb10a8ee1
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/ldscript.arm
@@ -0,0 +1,133 @@
+/* $FreeBSD$ */
+
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = UBLDR_LOADADDR + SIZEOF_HEADERS;
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rela.text :
+ { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rela.data :
+ { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rela.rodata :
+ { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rela.init : { *(.rela.init) }
+ .rela.fini : { *(.rela.fini) }
+ .rela.bss : { *(.rela.bss) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.sdata : { *(.rela.sdata) }
+ .rela.sbss : { *(.rela.sbss) }
+ .rela.sdata2 : { *(.rela.sdata2) }
+ .rela.sbss2 : { *(.rela.sbss2) }
+ .init : { *(.init) } =0
+ .fini : { *(.fini) } =0
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ .sdata2 : { *(.sdata2) }
+ .sbss2 : { *(.sbss2) }
+ /* Adjust the address for the data segment to the next page up. */
+ . = ((. + 0x1000) & ~(0x1000 - 1));
+ .data :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .got1 : { *(.got1) }
+ .dynamic : { *(.dynamic) }
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) }
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) }
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) }
+ PROVIDE (__DTOR_END__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) }
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ PROVIDE (__sbss_end = .);
+ }
+ .plt : { *(.plt) }
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/usr/src/boot/sys/boot/arm/uboot/loader.conf b/usr/src/boot/sys/boot/arm/uboot/loader.conf
new file mode 100644
index 0000000000..4154ab7bcc
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/loader.conf
@@ -0,0 +1,13 @@
+# This is defaults/loader.conf for ARM, containing defaults for loader(8).
+# Do not modify the contents of this file, instead put your customizations
+# into /boot/loader.conf or /boot/loader.conf.local
+# $FreeBSD$
+
+autoboot_delay=10
+bootfile="kernel" # Kernel name (possibly absolute path)
+kernel="kernel" # /boot sub-directory containing kernel and modules
+loader_conf_files="/boot/loader.conf /boot/loader.conf.local"
+module_path="/boot/kernel;/boot/modules;/boot/dtb"
+nextboot_conf="/boot/nextboot.conf"
+nextboot_enable="NO"
+verbose_loading="NO"
diff --git a/usr/src/boot/sys/boot/arm/uboot/start.S b/usr/src/boot/sys/boot/arm/uboot/start.S
new file mode 100644
index 0000000000..1ef21f3671
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/start.S
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 2008 Semihalf, Rafal Czubak
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+#include <machine/armreg.h>
+
+ .text
+ .extern _C_LABEL(self_reloc), _C_LABEL(main)
+ .weak _DYNAMIC
+
+/*
+ * Entry point to the loader that U-Boot passes control to.
+ */
+ .globl _start
+_start:
+
+#ifdef _ARM_ARCH_6
+ mrc p15, 0, ip, c1, c0, 0
+ orr ip, ip, #(CPU_CONTROL_UNAL_ENABLE)
+ orr ip, ip, #(CPU_CONTROL_AFLT_ENABLE)
+ mcr p15, 0, ip, c1, c0, 0
+#endif
+ /*
+ * Do self-relocation when the weak external symbol _DYNAMIC is non-NULL.
+ * When linked as a dynamic relocatable file, the linker automatically
+ * defines _DYNAMIC with a value that is the offset of the dynamic
+ * relocation info section.
+ * Note that we're still on u-boot's stack here, but the self_reloc
+ * code uses only a couple dozen bytes of stack space.
+ */
+ adr ip, .here_off /* .here_off is a symbol whose value */
+ ldr r0, [ip] /* is its own offset in the text seg. */
+ sub r0, ip, r0 /* Get its pc-relative address and */
+ ldr r1, .dynamic_off /* subtract its value and we get */
+ teq r1, #0 /* r0 = physaddr we were loaded at. */
+ addne r1, r1, r0 /* r1 = dynamic section physaddr. */
+ blne _C_LABEL(self_reloc) /* Do reloc if _DYNAMIC is non-NULL. */
+
+ /* Hint where to look for the API signature */
+ ldr ip, =uboot_address
+ str sp, [ip]
+
+ /* Save U-Boot's r8 and r9 */
+ ldr ip, =saved_regs
+ str r8, [ip, #0]
+ str r9, [ip, #4]
+
+ /*
+ * Start loader. This is basically a tail-recursion call; if main()
+ * returns, it returns to u-boot (which reports the value returned r0).
+ */
+ b main
+
+ /*
+ * Data for self-relocation, in the text segment for pc-rel access.
+ */
+.here_off:
+ .word .
+.dynamic_off:
+ .word _DYNAMIC
+
+/*
+ * syscall()
+ */
+ENTRY(syscall)
+ /* Save caller's lr, r8 and r9 */
+ ldr ip, =saved_regs
+ str r8, [ip, #8]
+ str r9, [ip, #12]
+ str lr, [ip, #16]
+ /* Restore U-Boot's r8 and r9 */
+ ldr r8, [ip, #0]
+ ldr r9, [ip, #4]
+ /* Call into U-Boot */
+ ldr lr, =return_from_syscall
+ ldr ip, =syscall_ptr
+ ldr pc, [ip]
+return_from_syscall:
+ /* Restore loader's r8, r9 and lr */
+ ldr ip, =saved_regs
+ ldr lr, [ip, #16]
+ ldr r9, [ip, #12]
+ ldr r8, [ip, #8]
+ /* Return to caller */
+ mov pc, lr
+
+/*
+ * Data section
+ */
+ .data
+ .align 4
+ .globl syscall_ptr
+syscall_ptr:
+ .long 0
+
+ .globl uboot_address
+uboot_address:
+ .long 0
+
+saved_regs:
+ .long 0 /* U-Boot's r8 */
+ .long 0 /* U-Boot's r9 */
+ .long 0 /* Loader's r8 */
+ .long 0 /* Loader's r9 */
+ .long 0 /* Loader's lr */
diff --git a/usr/src/boot/sys/boot/arm/uboot/version b/usr/src/boot/sys/boot/arm/uboot/version
new file mode 100644
index 0000000000..486c4125cc
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm/uboot/version
@@ -0,0 +1,9 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.2: Extended with NAND FS support.
+1.1: Flattened Device Tree blob support.
+1.0: Added storage support. Booting from HDD, USB, etc. is now possible.
+0.5: Initial U-Boot/arm version (netbooting only).
diff --git a/usr/src/boot/sys/boot/arm64/Makefile b/usr/src/boot/sys/boot/arm64/Makefile
new file mode 100644
index 0000000000..3ecb5825dc
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm64/Makefile
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/arm64/libarm64/cache.c b/usr/src/boot/sys/boot/arm64/libarm64/cache.c
new file mode 100644
index 0000000000..25766ef564
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm64/libarm64/cache.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <machine/armreg.h>
+
+#include <stand.h>
+#include <efi.h>
+
+#include "cache.h"
+
+static unsigned int
+get_dcache_line_size(void)
+{
+ uint64_t ctr;
+ unsigned int dcl_size;
+
+ /* Accessible from all security levels */
+ ctr = READ_SPECIALREG(ctr_el0);
+
+ /*
+ * Relevant field [19:16] is LOG2
+ * of the number of words in DCache line
+ */
+ dcl_size = CTR_DLINE_SIZE(ctr);
+
+ /* Size of word shifted by cache line size */
+ return (sizeof(int) << dcl_size);
+}
+
+void
+cpu_flush_dcache(const void *ptr, size_t len)
+{
+
+ uint64_t cl_size;
+ vm_offset_t addr, end;
+
+ cl_size = get_dcache_line_size();
+
+ /* Calculate end address to clean */
+ end = (vm_offset_t)ptr + (vm_offset_t)len;
+ /* Align start address to cache line */
+ addr = (vm_offset_t)ptr;
+ addr = rounddown2(addr, cl_size);
+
+ for (; addr < end; addr += cl_size)
+ __asm __volatile("dc civac, %0" : : "r" (addr) : "memory");
+ /* Full system DSB */
+ __asm __volatile("dsb sy" : : : "memory");
+}
+
+void
+cpu_inval_icache(const void *ptr, size_t len)
+{
+
+ /* NULL ptr or 0 len means all */
+ if (ptr == NULL || len == 0) {
+ __asm __volatile(
+ "ic ialluis \n"
+ "dsb ish \n"
+ : : : "memory");
+ return;
+ }
+
+ /* TODO: Other cache ranges if necessary */
+}
diff --git a/usr/src/boot/sys/boot/arm64/libarm64/cache.h b/usr/src/boot/sys/boot/arm64/libarm64/cache.h
new file mode 100644
index 0000000000..89b094b19c
--- /dev/null
+++ b/usr/src/boot/sys/boot/arm64/libarm64/cache.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _CACHE_H_
+#define _CACHE_H_
+
+/* cache.c */
+void cpu_flush_dcache(const void *, size_t);
+void cpu_inval_icache(const void *, size_t);
+
+#endif /* _CACHE_H_ */
diff --git a/usr/src/boot/sys/boot/common/Makefile b/usr/src/boot/sys/boot/common/Makefile
new file mode 100644
index 0000000000..fcca328b50
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+MAN+= loader.8
+.if ${MK_ZFS} != "no"
+MAN+= zfsloader.8
+.endif
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/common/Makefile.inc b/usr/src/boot/sys/boot/common/Makefile.inc
new file mode 100644
index 0000000000..bce0eb5902
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/Makefile.inc
@@ -0,0 +1,72 @@
+# $FreeBSD$
+
+SRCS+= boot.c commands.c console.c devopen.c interp.c
+SRCS+= interp_backslash.c interp_parse.c ls.c misc.c
+SRCS+= module.c panic.c
+
+.if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
+SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c
+.elif ${MACHINE} == "pc98"
+SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
+.elif ${MACHINE_CPUARCH} == "aarch64"
+SRCS+= load_elf64.c reloc_elf64.c
+.elif ${MACHINE_CPUARCH} == "arm"
+SRCS+= load_elf32.c reloc_elf32.c
+.elif ${MACHINE_CPUARCH} == "powerpc"
+SRCS+= load_elf32.c reloc_elf32.c
+SRCS+= load_elf64.c reloc_elf64.c
+.elif ${MACHINE_CPUARCH} == "sparc64"
+SRCS+= load_elf64.c reloc_elf64.c
+.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+SRCS+= load_elf64.c reloc_elf64.c
+.elif ${MACHINE_ARCH} == "mips" || ${MACHINE_ARCH} == "mipsel"
+SRCS+= load_elf32.c reloc_elf32.c
+.endif
+
+.if defined(LOADER_NET_SUPPORT)
+SRCS+= dev_net.c
+.endif
+
+.if !defined(LOADER_NO_DISK_SUPPORT)
+SRCS+= disk.c part.c
+CFLAGS+= -DLOADER_DISK_SUPPORT
+.if !defined(LOADER_NO_GPT_SUPPORT)
+SRCS+= crc32.c
+CFLAGS+= -DLOADER_GPT_SUPPORT
+.endif
+.if !defined(LOADER_NO_MBR_SUPPORT)
+CFLAGS+= -DLOADER_MBR_SUPPORT
+.endif
+.endif
+
+.if defined(HAVE_BCACHE)
+SRCS+= bcache.c
+.endif
+
+.if defined(MD_IMAGE_SIZE)
+CFLAGS+= -DMD_IMAGE_SIZE=${MD_IMAGE_SIZE}
+SRCS+= md.c
+.endif
+
+# Machine-independant ISA PnP
+.if defined(HAVE_ISABUS)
+SRCS+= isapnp.c
+.endif
+.if defined(HAVE_PNP)
+SRCS+= pnp.c
+.endif
+
+# Forth interpreter
+.if defined(BOOT_FORTH)
+SRCS+= interp_forth.c
+.endif
+
+.if defined(BOOT_PROMPT_123)
+CFLAGS+= -DBOOT_PROMPT_123
+.endif
+
+.if defined(LOADER_INSTALL_SUPPORT)
+SRCS+= install.c
+CFLAGS+=-I${.CURDIR}/../../../../lib/libstand
+.endif
diff --git a/usr/src/boot/sys/boot/common/bcache.c b/usr/src/boot/sys/boot/common/bcache.c
new file mode 100644
index 0000000000..3ac38d9b18
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/bcache.c
@@ -0,0 +1,470 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright 2015 Toomas Soome <tsoome@me.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Simple hashed block cache
+ */
+
+#include <sys/stdint.h>
+
+#include <stand.h>
+#include <string.h>
+#include <strings.h>
+
+#include "bootstrap.h"
+
+/* #define BCACHE_DEBUG */
+
+#ifdef BCACHE_DEBUG
+# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+# define DEBUG(fmt, args...)
+#endif
+
+struct bcachectl
+{
+ daddr_t bc_blkno;
+ int bc_count;
+};
+
+/*
+ * bcache per device node. cache is allocated on device first open and freed
+ * on last close, to save memory. The issue there is the size; biosdisk
+ * supports up to 31 (0x1f) devices. Classic setup would use single disk
+ * to boot from, but this has changed with zfs.
+ */
+struct bcache {
+ struct bcachectl *bcache_ctl;
+ caddr_t bcache_data;
+ u_int bcache_nblks;
+ size_t ra;
+};
+
+static u_int bcache_total_nblks; /* set by bcache_init */
+static u_int bcache_blksize; /* set by bcache_init */
+static u_int bcache_numdev; /* set by bcache_add_dev */
+/* statistics */
+static u_int bcache_units; /* number of devices with cache */
+static u_int bcache_unit_nblks; /* nblocks per unit */
+static u_int bcache_hits;
+static u_int bcache_misses;
+static u_int bcache_ops;
+static u_int bcache_bypasses;
+static u_int bcache_bcount;
+static u_int bcache_rablks;
+
+#define BHASH(bc, blkno) ((blkno) & ((bc)->bcache_nblks - 1))
+#define BCACHE_LOOKUP(bc, blkno) \
+ ((bc)->bcache_ctl[BHASH((bc), (blkno))].bc_blkno != (blkno))
+#define BCACHE_READAHEAD 256
+#define BCACHE_MINREADAHEAD 32
+
+static void bcache_invalidate(struct bcache *bc, daddr_t blkno);
+static void bcache_insert(struct bcache *bc, daddr_t blkno);
+static void bcache_free_instance(struct bcache *bc);
+
+/*
+ * Initialise the cache for (nblks) of (bsize).
+ */
+void
+bcache_init(u_int nblks, size_t bsize)
+{
+ /* set up control data */
+ bcache_total_nblks = nblks;
+ bcache_blksize = bsize;
+}
+
+/*
+ * add number of devices to bcache. we have to divide cache space
+ * between the devices, so bcache_add_dev() can be used to set up the
+ * number. The issue is, we need to get the number before actual allocations.
+ * bcache_add_dev() is supposed to be called from device init() call, so the
+ * assumption is, devsw dv_init is called for plain devices first, and
+ * for zfs, last.
+ */
+void
+bcache_add_dev(int devices)
+{
+ bcache_numdev += devices;
+}
+
+void *
+bcache_allocate(void)
+{
+ u_int i;
+ struct bcache *bc = malloc(sizeof (struct bcache));
+ int disks = bcache_numdev;
+
+ if (disks == 0)
+ disks = 1; /* safe guard */
+
+ if (bc == NULL) {
+ errno = ENOMEM;
+ return (bc);
+ }
+
+ /*
+ * the bcache block count must be power of 2 for hash function
+ */
+ i = fls(disks) - 1; /* highbit - 1 */
+ if (disks > (1 << i)) /* next power of 2 */
+ i++;
+
+ bc->bcache_nblks = bcache_total_nblks >> i;
+ bcache_unit_nblks = bc->bcache_nblks;
+ bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize);
+ if (bc->bcache_data == NULL) {
+ /* dont error out yet. fall back to 32 blocks and try again */
+ bc->bcache_nblks = 32;
+ bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize);
+ }
+
+ bc->bcache_ctl = malloc(bc->bcache_nblks * sizeof(struct bcachectl));
+
+ if ((bc->bcache_data == NULL) || (bc->bcache_ctl == NULL)) {
+ bcache_free_instance(bc);
+ errno = ENOMEM;
+ return(NULL);
+ }
+
+ /* Flush the cache */
+ for (i = 0; i < bc->bcache_nblks; i++) {
+ bc->bcache_ctl[i].bc_count = -1;
+ bc->bcache_ctl[i].bc_blkno = -1;
+ }
+ bcache_units++;
+ bc->ra = BCACHE_READAHEAD; /* optimistic read ahead */
+ return (bc);
+}
+
+void
+bcache_free(void *cache)
+{
+ struct bcache *bc = cache;
+
+ if (bc == NULL)
+ return;
+
+ bcache_free_instance(bc);
+ bcache_units--;
+}
+
+/*
+ * Handle a write request; write directly to the disk, and populate the
+ * cache with the new values.
+ */
+static int
+write_strategy(void *devdata, int rw, daddr_t blk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+ struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
+ struct bcache *bc = dd->dv_cache;
+ daddr_t i, nblk;
+
+ nblk = size / bcache_blksize;
+
+ /* Invalidate the blocks being written */
+ for (i = 0; i < nblk; i++) {
+ bcache_invalidate(bc, blk + i);
+ }
+
+ /* Write the blocks */
+ return (dd->dv_strategy(dd->dv_devdata, rw, blk, offset, size, buf, rsize));
+}
+
+/*
+ * Handle a read request; fill in parts of the request that can
+ * be satisfied by the cache, use the supplied strategy routine to do
+ * device I/O and then use the I/O results to populate the cache.
+ */
+static int
+read_strategy(void *devdata, int rw, daddr_t blk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+ struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
+ struct bcache *bc = dd->dv_cache;
+ size_t i, nblk, p_size, r_size, complete, ra;
+ int result;
+ daddr_t p_blk;
+ caddr_t p_buf;
+
+ if (bc == NULL) {
+ errno = ENODEV;
+ return (-1);
+ }
+
+ if (rsize != NULL)
+ *rsize = 0;
+
+ nblk = size / bcache_blksize;
+ if ((nblk == 0 && size != 0) || offset != 0)
+ nblk++;
+ result = 0;
+ complete = 1;
+
+ /* Satisfy any cache hits up front, break on first miss */
+ for (i = 0; i < nblk; i++) {
+ if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) {
+ bcache_misses += (nblk - i);
+ complete = 0;
+ if (nblk - i > BCACHE_MINREADAHEAD && bc->ra > BCACHE_MINREADAHEAD)
+ bc->ra >>= 1; /* reduce read ahead */
+ break;
+ } else {
+ bcache_hits++;
+ }
+ }
+
+ if (complete) { /* whole set was in cache, return it */
+ if (bc->ra < BCACHE_READAHEAD)
+ bc->ra <<= 1; /* increase read ahead */
+ bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)) + offset,
+ buf, size);
+ goto done;
+ }
+
+ /*
+ * Fill in any misses. From check we have i pointing to first missing
+ * block, read in all remaining blocks + readahead.
+ * We have space at least for nblk - i before bcache wraps.
+ */
+ p_blk = blk + i;
+ p_buf = bc->bcache_data + (bcache_blksize * BHASH(bc, p_blk));
+ r_size = bc->bcache_nblks - BHASH(bc, p_blk); /* remaining blocks */
+
+ p_size = MIN(r_size, nblk - i); /* read at least those blocks */
+
+ ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size);
+ if (ra != bc->bcache_nblks) { /* do we have RA space? */
+ ra = MIN(bc->ra, ra);
+ p_size += ra;
+ }
+
+ /* invalidate bcache */
+ for (i = 0; i < p_size; i++) {
+ bcache_invalidate(bc, p_blk + i);
+ }
+
+ r_size = 0;
+ /*
+ * with read-ahead, it may happen we are attempting to read past
+ * disk end, as bcache has no information about disk size.
+ * in such case we should get partial read if some blocks can be
+ * read or error, if no blocks can be read.
+ * in either case we should return the data in bcache and only
+ * return error if there is no data.
+ */
+ result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, 0,
+ p_size * bcache_blksize, p_buf, &r_size);
+
+ r_size /= bcache_blksize;
+ for (i = 0; i < r_size; i++)
+ bcache_insert(bc, p_blk + i);
+
+ /* update ra statistics */
+ if (r_size != 0) {
+ if (r_size < p_size)
+ bcache_rablks += (p_size - r_size);
+ else
+ bcache_rablks += ra;
+ }
+
+ /* check how much data can we copy */
+ for (i = 0; i < nblk; i++) {
+ if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i)))
+ break;
+ }
+
+ if (size > i * bcache_blksize)
+ size = i * bcache_blksize;
+
+ if (size != 0) {
+ bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)) + offset,
+ buf, size);
+ result = 0;
+ }
+
+ done:
+ if ((result == 0) && (rsize != NULL))
+ *rsize = size;
+ return(result);
+}
+
+/*
+ * Requests larger than 1/2 cache size will be bypassed and go
+ * directly to the disk. XXX tune this.
+ */
+int
+bcache_strategy(void *devdata, int rw, daddr_t blk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+ struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
+ struct bcache *bc = dd->dv_cache;
+ u_int bcache_nblks = 0;
+ int nblk, cblk, ret;
+ size_t csize, isize, total;
+
+ bcache_ops++;
+
+ if (bc != NULL)
+ bcache_nblks = bc->bcache_nblks;
+
+ /* bypass large requests, or when the cache is inactive */
+ if (bc == NULL ||
+ (offset == 0 && ((size * 2 / bcache_blksize) > bcache_nblks))) {
+ DEBUG("bypass %d from %d", size / bcache_blksize, blk);
+ bcache_bypasses++;
+ return (dd->dv_strategy(dd->dv_devdata, rw, blk, offset, size, buf,
+ rsize));
+ }
+
+ /* normalize offset */
+ while (offset >= bcache_blksize) {
+ blk++;
+ offset -= bcache_blksize;
+ }
+
+ switch (rw) {
+ case F_READ:
+ nblk = size / bcache_blksize;
+ if (offset || (size != 0 && nblk == 0))
+ nblk++; /* read at least one block */
+
+ ret = 0;
+ total = 0;
+ while(size) {
+ cblk = bcache_nblks - BHASH(bc, blk); /* # of blocks left */
+ cblk = MIN(cblk, nblk);
+
+ if (size <= bcache_blksize)
+ csize = size;
+ else {
+ csize = cblk * bcache_blksize;
+ if (offset)
+ csize -= (bcache_blksize - offset);
+ }
+
+ ret = read_strategy(devdata, rw, blk, offset,
+ csize, buf+total, &isize);
+
+ /*
+ * we may have error from read ahead, if we have read some data
+ * return partial read.
+ */
+ if (ret != 0 || isize == 0) {
+ if (total != 0)
+ ret = 0;
+ break;
+ }
+ blk += (offset+isize) / bcache_blksize;
+ offset = 0;
+ total += isize;
+ size -= isize;
+ nblk = size / bcache_blksize;
+ }
+
+ if (rsize)
+ *rsize = total;
+
+ return (ret);
+ case F_WRITE:
+ return write_strategy(devdata, rw, blk, offset, size, buf, rsize);
+ }
+ return -1;
+}
+
+/*
+ * Free allocated bcache instance
+ */
+static void
+bcache_free_instance(struct bcache *bc)
+{
+ if (bc != NULL) {
+ if (bc->bcache_ctl)
+ free(bc->bcache_ctl);
+ if (bc->bcache_data)
+ free(bc->bcache_data);
+ free(bc);
+ }
+}
+
+/*
+ * Insert a block into the cache.
+ */
+static void
+bcache_insert(struct bcache *bc, daddr_t blkno)
+{
+ u_int cand;
+
+ cand = BHASH(bc, blkno);
+
+ DEBUG("insert blk %llu -> %u # %d", blkno, cand, bcache_bcount);
+ bc->bcache_ctl[cand].bc_blkno = blkno;
+ bc->bcache_ctl[cand].bc_count = bcache_bcount++;
+}
+
+/*
+ * Invalidate a block from the cache.
+ */
+static void
+bcache_invalidate(struct bcache *bc, daddr_t blkno)
+{
+ u_int i;
+
+ i = BHASH(bc, blkno);
+ if (bc->bcache_ctl[i].bc_blkno == blkno) {
+ bc->bcache_ctl[i].bc_count = -1;
+ bc->bcache_ctl[i].bc_blkno = -1;
+ DEBUG("invalidate blk %llu", blkno);
+ }
+}
+
+#ifndef BOOT2
+COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache);
+
+static int
+command_bcache(int argc, char *argv[] __attribute((unused)))
+{
+ if (argc != 1) {
+ command_errmsg = "wrong number of arguments";
+ return(CMD_ERROR);
+ }
+
+ printf("\ncache blocks: %d\n", bcache_total_nblks);
+ printf("cache blocksz: %d\n", bcache_blksize);
+ printf("cache readahead: %d\n", bcache_rablks);
+ printf("unit cache blocks: %d\n", bcache_unit_nblks);
+ printf("cached units: %d\n", bcache_units);
+ printf("%d ops %d bypasses %d hits %d misses\n", bcache_ops,
+ bcache_bypasses, bcache_hits, bcache_misses);
+ return(CMD_OK);
+}
+#endif
diff --git a/usr/src/boot/sys/boot/common/boot.c b/usr/src/boot/sys/boot/common/boot.c
new file mode 100644
index 0000000000..2f6b7f1f78
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/boot.c
@@ -0,0 +1,398 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Loading modules, booting the system
+ */
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+static char *getbootfile(int try);
+static int loadakernel(int try, int argc, char* argv[]);
+
+/* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */
+static const char *default_bootfiles = "kernel";
+
+static int autoboot_tried;
+
+/*
+ * The user wants us to boot.
+ */
+COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot);
+
+static int
+command_boot(int argc, char *argv[])
+{
+ struct preloaded_file *fp;
+
+ /*
+ * See if the user has specified an explicit kernel to boot.
+ */
+ if ((argc > 1) && (argv[1][0] == '/')) {
+
+ /* XXX maybe we should discard everything and start again? */
+ if (file_findfile(NULL, NULL) != NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't boot '%s', kernel module already loaded", argv[1]);
+ return(CMD_ERROR);
+ }
+
+ /* find/load the kernel module */
+ if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0)
+ return(CMD_ERROR);
+ /* we have consumed all arguments */
+ argc = 1;
+ }
+
+ /*
+ * See if there is a kernel module already loaded
+ */
+ if (file_findfile(NULL, NULL) == NULL)
+ if (loadakernel(0, argc - 1, argv + 1))
+ /* we have consumed all arguments */
+ argc = 1;
+
+ /*
+ * Loaded anything yet?
+ */
+ if ((fp = file_findfile(NULL, NULL)) == NULL) {
+ command_errmsg = "no bootable kernel";
+ return(CMD_ERROR);
+ }
+
+ /*
+ * If we were given arguments, discard any previous.
+ * XXX should we merge arguments? Hard to DWIM.
+ */
+ if (argc > 1) {
+ if (fp->f_args != NULL)
+ free(fp->f_args);
+ fp->f_args = unargv(argc - 1, argv + 1);
+ }
+
+ /* Hook for platform-specific autoloading of modules */
+ if (archsw.arch_autoload() != 0)
+ return(CMD_ERROR);
+
+ /* Call the exec handler from the loader matching the kernel */
+ file_formats[fp->f_loader]->l_exec(fp);
+ return(CMD_ERROR);
+}
+
+
+/*
+ * Autoboot after a delay
+ */
+
+COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_autoboot);
+
+static int
+command_autoboot(int argc, char *argv[])
+{
+ int howlong;
+ char *cp, *prompt;
+
+ prompt = NULL;
+ howlong = -1;
+ switch(argc) {
+ case 3:
+ prompt = argv[2];
+ /* FALLTHROUGH */
+ case 2:
+ howlong = strtol(argv[1], &cp, 0);
+ if (*cp != 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "bad delay '%s'", argv[1]);
+ return(CMD_ERROR);
+ }
+ /* FALLTHROUGH */
+ case 1:
+ return(autoboot(howlong, prompt));
+ }
+
+ command_errmsg = "too many arguments";
+ return(CMD_ERROR);
+}
+
+/*
+ * Called before we go interactive. If we think we can autoboot, and
+ * we haven't tried already, try now.
+ */
+void
+autoboot_maybe(void)
+{
+ char *cp;
+
+ /* compatibility with sparc prom, check for autoboot? */
+ cp = getenv("autoboot?");
+ if (cp != NULL && strcasecmp(cp, "true") != 0)
+ return;
+ cp = getenv("autoboot_delay");
+ if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO")))
+ autoboot(-1, NULL); /* try to boot automatically */
+}
+
+int
+autoboot(int timeout, char *prompt)
+{
+ time_t when, otime, ntime;
+ int c, yes;
+ char *argv[2], *cp, *ep;
+ char *kernelname;
+ struct preloaded_file *fp;
+
+ autoboot_tried = 1;
+
+ if (timeout == -1) {
+ timeout = 10;
+ /* try to get a delay from the environment */
+ if ((cp = getenv("autoboot_delay"))) {
+ timeout = strtol(cp, &ep, 0);
+ if (cp == ep)
+ timeout = 10; /* Unparseable? Set default! */
+ }
+ }
+
+ fp = file_findfile(NULL, NULL);
+ if (fp == NULL) { /* no preloaded files, run command start to load all */
+ bf_run("start");
+ fp = file_findfile(NULL, NULL);
+ if (fp == NULL) { /* still nothing? can't boot */
+ command_errmsg = "no valid kernel found";
+ return(CMD_ERROR);
+ }
+ }
+
+ kernelname = fp->f_name;
+
+ if (timeout >= 0) {
+ otime = time(NULL);
+ when = otime + timeout; /* when to boot */
+
+ yes = 0;
+
+ printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
+
+ for (;;) {
+ if (ischar()) {
+ c = getchar();
+ if ((c == '\r') || (c == '\n'))
+ yes = 1;
+ break;
+ }
+ ntime = time(NULL);
+ if (ntime >= when) {
+ yes = 1;
+ break;
+ }
+
+ if (ntime != otime) {
+ printf("\rBooting [%s] in %d second%s... ",
+ kernelname, (int)(when - ntime),
+ (when-ntime)==1?"":"s");
+ otime = ntime;
+ }
+ }
+ } else {
+ yes = 1;
+ }
+
+ if (yes)
+ printf("\rBooting [%s]... ", kernelname);
+ putchar('\n');
+ if (yes) {
+ argv[0] = "boot";
+ argv[1] = NULL;
+ return(command_boot(1, argv));
+ }
+ return(CMD_OK);
+}
+
+/*
+ * Scrounge for the name of the (try)'th file we will try to boot.
+ */
+static char *
+getbootfile(int try)
+{
+ static char *name = NULL;
+ const char *spec, *ep;
+ size_t len;
+
+ /* we use dynamic storage */
+ if (name != NULL) {
+ free(name);
+ name = NULL;
+ }
+
+ /*
+ * Try $bootfile, then try our builtin default
+ */
+ if ((spec = getenv("bootfile")) == NULL)
+ spec = default_bootfiles;
+
+ while ((try > 0) && (spec != NULL)) {
+ spec = strchr(spec, ';');
+ if (spec)
+ spec++; /* skip over the leading ';' */
+ try--;
+ }
+ if (spec != NULL) {
+ if ((ep = strchr(spec, ';')) != NULL) {
+ len = ep - spec;
+ } else {
+ len = strlen(spec);
+ }
+ name = malloc(len + 1);
+ strncpy(name, spec, len);
+ name[len] = 0;
+ }
+ if (name && name[0] == 0) {
+ free(name);
+ name = NULL;
+ }
+ return(name);
+}
+
+/*
+ * Try to find the /etc/fstab file on the filesystem (rootdev),
+ * which should be be the root filesystem, and parse it to find
+ * out what the kernel ought to think the root filesystem is.
+ *
+ * If we're successful, set vfs.root.mountfrom to <vfstype>:<path>
+ * so that the kernel can tell both which VFS and which node to use
+ * to mount the device. If this variable's already set, don't
+ * overwrite it.
+ */
+int
+getrootmount(char *rootdev)
+{
+ char lbuf[128], *cp, *ep, *dev, *fstyp, *options;
+ int fd, error;
+
+ if (getenv("vfs.root.mountfrom") != NULL)
+ return(0);
+
+ error = 1;
+ sprintf(lbuf, "%s/etc/fstab", rootdev);
+ if ((fd = open(lbuf, O_RDONLY)) < 0)
+ goto notfound;
+
+ /* loop reading lines from /etc/fstab What was that about sscanf again? */
+ while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) {
+ if ((lbuf[0] == 0) || (lbuf[0] == '#'))
+ continue;
+
+ /* skip device name */
+ for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++)
+ ;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* delimit and save */
+ *cp++ = 0;
+ dev = strdup(lbuf);
+
+ /* skip whitespace up to mountpoint */
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ /* must have /<space> to be root */
+ if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1)))
+ continue;
+ /* skip whitespace up to fstype */
+ cp += 2;
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* skip text to end of fstype and delimit */
+ ep = cp;
+ while ((*cp != 0) && !isspace(*cp))
+ cp++;
+ *cp = 0;
+ fstyp = strdup(ep);
+
+ /* skip whitespace up to mount options */
+ cp += 1;
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* skip text to end of mount options and delimit */
+ ep = cp;
+ while ((*cp != 0) && !isspace(*cp))
+ cp++;
+ *cp = 0;
+ options = strdup(ep);
+ /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */
+ sprintf(lbuf, "%s:%s", fstyp, dev);
+ free(dev);
+ free(fstyp);
+ setenv("vfs.root.mountfrom", lbuf, 0);
+
+ /* Don't override vfs.root.mountfrom.options if it is already set */
+ if (getenv("vfs.root.mountfrom.options") == NULL) {
+ /* save mount options */
+ setenv("vfs.root.mountfrom.options", options, 0);
+ }
+ free(options);
+ error = 0;
+ break;
+ }
+ close(fd);
+
+notfound:
+ if (error) {
+ const char *currdev;
+
+ currdev = getenv("currdev");
+ if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) {
+ cp = strdup(currdev);
+ cp[strlen(cp) - 1] = '\0';
+ setenv("vfs.root.mountfrom", cp, 0);
+ error = 0;
+ }
+ }
+
+ return(error);
+}
+
+static int
+loadakernel(int try, int argc, char* argv[])
+{
+ char *cp;
+
+ for (try = 0; (cp = getbootfile(try)) != NULL; try++)
+ if (mod_loadkld(cp, argc - 1, argv + 1) != 0)
+ printf("can't load '%s'\n", cp);
+ else
+ return 1;
+ return 0;
+}
diff --git a/usr/src/boot/sys/boot/common/bootstrap.h b/usr/src/boot/sys/boot/common/bootstrap.h
new file mode 100644
index 0000000000..9539180cb3
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/bootstrap.h
@@ -0,0 +1,336 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOTSTRAP_H_
+#define _BOOTSTRAP_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/linker_set.h>
+
+/* Commands and return values; nonzero return sets command_errmsg != NULL */
+typedef int (bootblk_cmd_t)(int argc, char *argv[]);
+#define COMMAND_ERRBUFSZ (256)
+extern const char *command_errmsg;
+extern char command_errbuf[COMMAND_ERRBUFSZ];
+#define CMD_OK 0
+#define CMD_WARN 1
+#define CMD_ERROR 2
+#define CMD_CRIT 3
+#define CMD_FATAL 4
+
+/* interp.c */
+void interact(const char *rc);
+int include(const char *filename);
+
+/* interp_backslash.c */
+char *backslash(char *str);
+
+/* interp_parse.c */
+int parse(int *argc, char ***argv, char *str);
+
+/* interp_forth.c */
+void bf_init(char *rc);
+int bf_run(char *line);
+
+/* boot.c */
+int autoboot(int timeout, char *prompt);
+void autoboot_maybe(void);
+int getrootmount(char *rootdev);
+
+/* misc.c */
+char *unargv(int argc, char *argv[]);
+void hexdump(caddr_t region, size_t len);
+size_t strlenout(vm_offset_t str);
+char *strdupout(vm_offset_t str);
+void kern_bzero(vm_offset_t dest, size_t len);
+int kern_pread(int fd, vm_offset_t dest, size_t len, off_t off);
+void *alloc_pread(int fd, off_t off, size_t len);
+
+/* bcache.c */
+void bcache_init(u_int nblks, size_t bsize);
+void bcache_add_dev(int);
+void *bcache_allocate(void);
+void bcache_free(void *);
+int bcache_strategy(void *devdata, int rw, daddr_t blk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+
+/*
+ * Disk block cache
+ */
+struct bcache_devdata
+{
+ int (*dv_strategy)(void *devdata, int rw, daddr_t blk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+ void *dv_devdata;
+ void *dv_cache;
+};
+
+/*
+ * Modular console support.
+ */
+struct console
+{
+ const char *c_name;
+ const char *c_desc;
+ int c_flags;
+#define C_PRESENTIN (1<<0) /* console can provide input */
+#define C_PRESENTOUT (1<<1) /* console can provide output */
+#define C_ACTIVEIN (1<<2) /* user wants input from console */
+#define C_ACTIVEOUT (1<<3) /* user wants output to console */
+#define C_MODERAW (1<<4) /* raw mode */
+ void (*c_probe)(struct console *); /* set c_flags to match hardware */
+ int (*c_init)(struct console *, int); /* reinit XXX may need more args */
+ void (*c_out)(struct console *, int); /* emit c */
+ int (*c_in)(struct console *); /* wait for and return input */
+ int (*c_ready)(struct console *); /* return nonzer if input waiting */
+ void *private; /* private data */
+};
+extern struct console *consoles[];
+void cons_probe(void);
+void cons_mode(int);
+
+/*
+ * Plug-and-play enumerator/configurator interface.
+ */
+struct pnphandler
+{
+ const char *pp_name; /* handler/bus name */
+ void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */
+};
+
+struct pnpident
+{
+ char *id_ident; /* ASCII identifier, actual format varies with bus/handler */
+ STAILQ_ENTRY(pnpident) id_link;
+};
+
+struct pnpinfo
+{
+ char *pi_desc; /* ASCII description, optional */
+ int pi_revision; /* optional revision (or -1) if not supported */
+ char *pi_module; /* module/args nominated to handle device */
+ int pi_argc; /* module arguments */
+ char **pi_argv;
+ struct pnphandler *pi_handler; /* handler which detected this device */
+ STAILQ_HEAD(,pnpident) pi_ident; /* list of identifiers */
+ STAILQ_ENTRY(pnpinfo) pi_link;
+};
+
+STAILQ_HEAD(pnpinfo_stql, pnpinfo);
+
+extern struct pnpinfo_stql pnp_devices;
+
+extern struct pnphandler *pnphandlers[]; /* provided by MD code */
+
+void pnp_addident(struct pnpinfo *pi, char *ident);
+struct pnpinfo *pnp_allocinfo(void);
+void pnp_freeinfo(struct pnpinfo *pi);
+void pnp_addinfo(struct pnpinfo *pi);
+char *pnp_eisaformat(u_int8_t *data);
+
+/*
+ * < 0 - No ISA in system
+ * == 0 - Maybe ISA, search for read data port
+ * > 0 - ISA in system, value is read data port address
+ */
+extern int isapnp_readport;
+
+/*
+ * Preloaded file metadata header.
+ *
+ * Metadata are allocated on our heap, and copied into kernel space
+ * before executing the kernel.
+ */
+struct file_metadata
+{
+ size_t md_size;
+ u_int16_t md_type;
+ struct file_metadata *md_next;
+ char md_data[1]; /* data are immediately appended */
+};
+
+struct preloaded_file;
+struct mod_depend;
+
+struct kernel_module
+{
+ char *m_name; /* module name */
+ int m_version; /* module version */
+ char *m_args; /* arguments for the module */
+ struct preloaded_file *m_fp;
+ struct kernel_module *m_next;
+};
+
+/*
+ * Preloaded file information. Depending on type, file can contain
+ * additional units called 'modules'.
+ *
+ * At least one file (the kernel) must be loaded in order to boot.
+ * The kernel is always loaded first.
+ *
+ * String fields (m_name, m_type) should be dynamically allocated.
+ */
+struct preloaded_file
+{
+ char *f_name; /* file name */
+ char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
+ char *f_args; /* arguments for the file */
+ struct file_metadata *f_metadata; /* metadata that will be placed in the module directory */
+ int f_loader; /* index of the loader that read the file */
+ vm_offset_t f_addr; /* load address */
+ size_t f_size; /* file size */
+ struct kernel_module *f_modules; /* list of modules if any */
+ struct preloaded_file *f_next; /* next file */
+};
+
+struct file_format
+{
+ /* Load function must return EFTYPE if it can't handle the module supplied */
+ int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result);
+ /* Only a loader that will load a kernel (first module) should have an exec handler */
+ int (* l_exec)(struct preloaded_file *mp);
+};
+
+extern struct file_format *file_formats[]; /* supplied by consumer */
+extern struct preloaded_file *preloaded_files;
+
+int mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]);
+int mod_loadkld(const char *name, int argc, char *argv[]);
+void unload(void);
+
+struct preloaded_file *file_alloc(void);
+struct preloaded_file *file_findfile(const char *name, const char *type);
+struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
+struct preloaded_file *file_loadraw(const char *name, char *type, int argc,
+ char **argv, int insert);
+void file_discard(struct preloaded_file *fp);
+void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
+int file_addmodule(struct preloaded_file *fp, char *modname, int version,
+ struct kernel_module **newmp);
+
+/* MI module loaders */
+#ifdef __elfN
+/* Relocation types. */
+#define ELF_RELOC_REL 1
+#define ELF_RELOC_RELA 2
+
+/* Relocation offset for some architectures */
+extern u_int64_t __elfN(relocation_offset);
+
+struct elf_file;
+typedef Elf_Addr (symaddr_fn)(struct elf_file *ef, Elf_Size symidx);
+
+int __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result);
+int __elfN(obj_loadfile)(char *filename, u_int64_t dest,
+ struct preloaded_file **result);
+int __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr,
+ const void *reldata, int reltype, Elf_Addr relbase,
+ Elf_Addr dataaddr, void *data, size_t len);
+int __elfN(loadfile_raw)(char *filename, u_int64_t dest,
+ struct preloaded_file **result, int multiboot);
+int __elfN(load_modmetadata)(struct preloaded_file *fp, u_int64_t dest);
+#endif
+
+/*
+ * Support for commands
+ */
+struct bootblk_command
+{
+ const char *c_name;
+ const char *c_desc;
+ bootblk_cmd_t *c_fn;
+};
+
+#define COMMAND_SET(tag, key, desc, func) \
+ static bootblk_cmd_t func; \
+ static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \
+ DATA_SET(Xcommand_set, _cmd_ ## tag)
+
+SET_DECLARE(Xcommand_set, struct bootblk_command);
+
+/*
+ * The intention of the architecture switch is to provide a convenient
+ * encapsulation of the interface between the bootstrap MI and MD code.
+ * MD code may selectively populate the switch at runtime based on the
+ * actual configuration of the target system.
+ */
+struct arch_switch
+{
+ /* Automatically load modules as required by detected hardware */
+ int (*arch_autoload)(void);
+ /* Locate the device for (name), return pointer to tail in (*path) */
+ int (*arch_getdev)(void **dev, const char *name, const char **path);
+ /* Copy from local address space to module address space, similar to bcopy() */
+ ssize_t (*arch_copyin)(const void *src, vm_offset_t dest,
+ const size_t len);
+ /* Copy to local address space from module address space, similar to bcopy() */
+ ssize_t (*arch_copyout)(const vm_offset_t src, void *dest,
+ const size_t len);
+ /* Read from file to module address space, same semantics as read() */
+ ssize_t (*arch_readin)(const int fd, vm_offset_t dest,
+ const size_t len);
+ /* Perform ISA byte port I/O (only for systems with ISA) */
+ int (*arch_isainb)(int port);
+ void (*arch_isaoutb)(int port, int value);
+
+ /*
+ * Interface to adjust the load address according to the "object"
+ * being loaded.
+ */
+ uint64_t (*arch_loadaddr)(u_int type, void *data, uint64_t addr);
+#define LOAD_ELF 1 /* data points to the ELF header. */
+#define LOAD_RAW 2 /* data points to the file name. */
+
+ /*
+ * Interface to inform MD code about a loaded (ELF) segment. This
+ * can be used to flush caches and/or set up translations.
+ */
+#ifdef __elfN
+ void (*arch_loadseg)(Elf_Ehdr *eh, Elf_Phdr *ph, uint64_t delta);
+#else
+ void (*arch_loadseg)(void *eh, void *ph, uint64_t delta);
+#endif
+
+ /* Probe ZFS pool(s), if needed. */
+ void (*arch_zfs_probe)(void);
+};
+extern struct arch_switch archsw;
+
+/* This must be provided by the MD code, but should it be in the archsw? */
+void delay(int delay);
+
+void dev_cleanup(void);
+
+#ifndef CTASSERT /* Allow lint to override */
+#define CTASSERT(x) _CTASSERT(x, __LINE__)
+#define _CTASSERT(x, y) __CTASSERT(x, y)
+#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
+#endif
+
+#endif /* !_BOOTSTRAP_H_ */
diff --git a/usr/src/boot/sys/boot/common/commands.c b/usr/src/boot/sys/boot/common/commands.c
new file mode 100644
index 0000000000..cf16d83e8c
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/commands.c
@@ -0,0 +1,525 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+const char *command_errmsg;
+/* XXX should have procedural interface for setting, size limit? */
+char command_errbuf[COMMAND_ERRBUFSZ];
+
+static int page_file(char *filename);
+
+/*
+ * Help is read from a formatted text file.
+ *
+ * Entries in the file are formatted as
+
+# Ttopic [Ssubtopic] Ddescription
+help
+text
+here
+#
+
+ *
+ * Note that for code simplicity's sake, the above format must be followed
+ * exactly.
+ *
+ * Subtopic entries must immediately follow the topic (this is used to
+ * produce the listing of subtopics).
+ *
+ * If no argument(s) are supplied by the user, the help for 'help' is displayed.
+ */
+COMMAND_SET(help, "help", "detailed help", command_help);
+
+static int
+help_getnext(int fd, char **topic, char **subtopic, char **desc)
+{
+ char line[81], *cp, *ep;
+
+ for (;;) {
+ if (fgetstr(line, 80, fd) < 0)
+ return(0);
+
+ if ((strlen(line) < 3) || (line[0] != '#') || (line[1] != ' '))
+ continue;
+
+ *topic = *subtopic = *desc = NULL;
+ cp = line + 2;
+ while((cp != NULL) && (*cp != 0)) {
+ ep = strchr(cp, ' ');
+ if ((*cp == 'T') && (*topic == NULL)) {
+ if (ep != NULL)
+ *ep++ = 0;
+ *topic = strdup(cp + 1);
+ } else if ((*cp == 'S') && (*subtopic == NULL)) {
+ if (ep != NULL)
+ *ep++ = 0;
+ *subtopic = strdup(cp + 1);
+ } else if (*cp == 'D') {
+ *desc = strdup(cp + 1);
+ ep = NULL;
+ }
+ cp = ep;
+ }
+ if (*topic == NULL) {
+ if (*subtopic != NULL)
+ free(*subtopic);
+ if (*desc != NULL)
+ free(*desc);
+ continue;
+ }
+ return(1);
+ }
+}
+
+static int
+help_emitsummary(char *topic, char *subtopic, char *desc)
+{
+ int i;
+
+ pager_output(" ");
+ pager_output(topic);
+ i = strlen(topic);
+ if (subtopic != NULL) {
+ pager_output(" ");
+ pager_output(subtopic);
+ i += strlen(subtopic) + 1;
+ }
+ if (desc != NULL) {
+ do {
+ pager_output(" ");
+ } while (i++ < 30);
+ pager_output(desc);
+ }
+ return (pager_output("\n"));
+}
+
+
+static int
+command_help(int argc, char *argv[])
+{
+ char buf[81]; /* XXX buffer size? */
+ int hfd, matched, doindex;
+ char *topic, *subtopic, *t, *s, *d;
+
+ /* page the help text from our load path */
+ sprintf(buf, "%s/boot/loader.help", getenv("loaddev"));
+ if ((hfd = open(buf, O_RDONLY)) < 0) {
+ printf("Verbose help not available, use '?' to list commands\n");
+ return(CMD_OK);
+ }
+
+ /* pick up request from arguments */
+ topic = subtopic = NULL;
+ switch(argc) {
+ case 3:
+ subtopic = strdup(argv[2]);
+ case 2:
+ topic = strdup(argv[1]);
+ break;
+ case 1:
+ topic = strdup("help");
+ break;
+ default:
+ command_errmsg = "usage is 'help <topic> [<subtopic>]";
+ close(hfd);
+ return(CMD_ERROR);
+ }
+
+ /* magic "index" keyword */
+ doindex = !strcmp(topic, "index");
+ matched = doindex;
+
+ /* Scan the helpfile looking for help matching the request */
+ pager_open();
+ while(help_getnext(hfd, &t, &s, &d)) {
+
+ if (doindex) { /* dink around formatting */
+ if (help_emitsummary(t, s, d))
+ break;
+
+ } else if (strcmp(topic, t)) {
+ /* topic mismatch */
+ if(matched) /* nothing more on this topic, stop scanning */
+ break;
+
+ } else {
+ /* topic matched */
+ matched = 1;
+ if (((subtopic == NULL) && (s == NULL)) ||
+ ((subtopic != NULL) && (s != NULL) && !strcmp(subtopic, s))) {
+ /* exact match, print text */
+ while((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) {
+ if (pager_output(buf))
+ break;
+ if (pager_output("\n"))
+ break;
+ }
+ } else if ((subtopic == NULL) && (s != NULL)) {
+ /* topic match, list subtopics */
+ if (help_emitsummary(t, s, d))
+ break;
+ }
+ }
+ free(t);
+ free(s);
+ free(d);
+ }
+ pager_close();
+ close(hfd);
+ if (!matched) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no help available for '%s'", topic);
+ free(topic);
+ if (subtopic)
+ free(subtopic);
+ return(CMD_ERROR);
+ }
+ free(topic);
+ if (subtopic)
+ free(subtopic);
+ return(CMD_OK);
+}
+
+
+COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
+
+static int
+command_commandlist(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ struct bootblk_command **cmdp;
+ int res;
+ char name[20];
+
+ res = 0;
+ pager_open();
+ res = pager_output("Available commands:\n");
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (res)
+ break;
+ if (((*cmdp)->c_name != NULL) && ((*cmdp)->c_desc != NULL)) {
+ sprintf(name, " %-15s ", (*cmdp)->c_name);
+ pager_output(name);
+ pager_output((*cmdp)->c_desc);
+ res = pager_output("\n");
+ }
+ }
+ pager_close();
+ return(CMD_OK);
+}
+
+/*
+ * XXX set/show should become set/echo if we have variable
+ * substitution happening.
+ */
+
+COMMAND_SET(show, "show", "show variable(s)", command_show);
+
+static int
+command_show(int argc, char *argv[])
+{
+ struct env_var *ev;
+ char *cp;
+
+ if (argc < 2) {
+ /*
+ * With no arguments, print everything.
+ */
+ pager_open();
+ for (ev = environ; ev != NULL; ev = ev->ev_next) {
+ pager_output(ev->ev_name);
+ cp = getenv(ev->ev_name);
+ if (cp != NULL) {
+ pager_output("=");
+ pager_output(cp);
+ }
+ if (pager_output("\n"))
+ break;
+ }
+ pager_close();
+ } else {
+ if ((cp = getenv(argv[1])) != NULL) {
+ printf("%s\n", cp);
+ } else {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "variable '%s' not found", argv[1]);
+ return(CMD_ERROR);
+ }
+ }
+ return(CMD_OK);
+}
+
+COMMAND_SET(set, "set", "set a variable", command_set);
+
+static int
+command_set(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return(CMD_ERROR);
+ } else {
+ if ((err = putenv(argv[1])) != 0) {
+ command_errmsg = strerror(err);
+ return(CMD_ERROR);
+ }
+ }
+ return(CMD_OK);
+}
+
+COMMAND_SET(setprop, "setprop", "set a variable", command_setprop);
+
+static int
+command_setprop(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 3) {
+ command_errmsg = "wrong number of arguments";
+ return(CMD_ERROR);
+ } else {
+ if ((err = setenv(argv[1], argv[2], 1)) != 0) {
+ command_errmsg = strerror(err);
+ return(CMD_ERROR);
+ }
+ }
+ return(CMD_OK);
+}
+
+COMMAND_SET(unset, "unset", "unset a variable", command_unset);
+
+static int
+command_unset(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return(CMD_ERROR);
+ } else {
+ if ((err = unsetenv(argv[1])) != 0) {
+ command_errmsg = strerror(err);
+ return(CMD_ERROR);
+ }
+ }
+ return(CMD_OK);
+}
+
+COMMAND_SET(echo, "echo", "echo arguments", command_echo);
+
+static int
+command_echo(int argc, char *argv[])
+{
+ char *s;
+ int nl, ch;
+
+ nl = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "n")) != -1) {
+ switch(ch) {
+ case 'n':
+ nl = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+ argv += (optind);
+ argc -= (optind);
+
+ s = unargv(argc, argv);
+ if (s != NULL) {
+ printf("%s", s);
+ free(s);
+ }
+ if (!nl)
+ printf("\n");
+ return(CMD_OK);
+}
+
+/*
+ * A passable emulation of the sh(1) command of the same name.
+ */
+
+COMMAND_SET(read, "read", "read input from the terminal", command_read);
+
+static int
+command_read(int argc, char *argv[])
+{
+ char *prompt;
+ int timeout;
+ time_t when;
+ char *cp;
+ char *name;
+ char buf[256]; /* XXX size? */
+ int c;
+
+ timeout = -1;
+ prompt = NULL;
+ optind = 1;
+ optreset = 1;
+ while ((c = getopt(argc, argv, "p:t:")) != -1) {
+ switch(c) {
+
+ case 'p':
+ prompt = optarg;
+ break;
+ case 't':
+ timeout = strtol(optarg, &cp, 0);
+ if (cp == optarg) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "bad timeout '%s'", optarg);
+ return(CMD_ERROR);
+ }
+ break;
+ default:
+ return(CMD_OK);
+ }
+ }
+
+ argv += (optind);
+ argc -= (optind);
+ name = (argc > 0) ? argv[0]: NULL;
+
+ if (prompt != NULL)
+ printf("%s", prompt);
+ if (timeout >= 0) {
+ when = time(NULL) + timeout;
+ while (!ischar())
+ if (time(NULL) >= when)
+ return(CMD_OK); /* is timeout an error? */
+ }
+
+ ngets(buf, sizeof(buf));
+
+ if (name != NULL)
+ setenv(name, buf, 1);
+ return(CMD_OK);
+}
+
+/*
+ * File pager
+ */
+COMMAND_SET(more, "more", "show contents of a file", command_more);
+
+static int
+command_more(int argc, char *argv[])
+{
+ int i;
+ int res;
+ char line[80];
+
+ res=0;
+ pager_open();
+ for (i = 1; (i < argc) && (res == 0); i++) {
+ sprintf(line, "*** FILE %s BEGIN ***\n", argv[i]);
+ if (pager_output(line))
+ break;
+ res = page_file(argv[i]);
+ if (!res) {
+ sprintf(line, "*** FILE %s END ***\n", argv[i]);
+ res = pager_output(line);
+ }
+ }
+ pager_close();
+
+ if (res == 0)
+ return CMD_OK;
+ else
+ return CMD_ERROR;
+}
+
+static int
+page_file(char *filename)
+{
+ int result;
+
+ result = pager_file(filename);
+
+ if (result == -1) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "error showing %s", filename);
+ }
+
+ return result;
+}
+
+/*
+ * List all disk-like devices
+ */
+COMMAND_SET(lsdev, "lsdev", "list all devices", command_lsdev);
+
+static int
+command_lsdev(int argc, char *argv[])
+{
+ int verbose, ch, i;
+ char line[80];
+
+ verbose = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch(ch) {
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+ argv += (optind);
+ argc -= (optind);
+
+ pager_open();
+ for (i = 0; devsw[i] != NULL; i++) {
+ if (devsw[i]->dv_print != NULL){
+ sprintf(line, "%s devices:\n", devsw[i]->dv_name);
+ if (pager_output(line))
+ break;
+ if (devsw[i]->dv_print(verbose))
+ break;
+ } else {
+ sprintf(line, "%s: (unknown)\n", devsw[i]->dv_name);
+ if (pager_output(line))
+ break;
+ }
+ }
+ pager_close();
+ return(CMD_OK);
+}
diff --git a/usr/src/boot/sys/boot/common/console.c b/usr/src/boot/sys/boot/common/console.c
new file mode 100644
index 0000000000..07e8aa4bc1
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/console.c
@@ -0,0 +1,315 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+/*
+ * Core console support
+ */
+
+static int cons_set(struct env_var *ev, int flags, const void *value);
+static int cons_find(const char *name);
+static int cons_check(const char *string);
+static int cons_change(const char *string);
+static int twiddle_set(struct env_var *ev, int flags, const void *value);
+
+/*
+ * Detect possible console(s) to use. If preferred console(s) have been
+ * specified, mark them as active. Else, mark the first probed console
+ * as active. Also create the console variable.
+ */
+void
+cons_probe(void)
+{
+ int cons;
+ int active;
+ char *prefconsole;
+
+ /* We want a callback to install the new value when this var changes. */
+ env_setenv("twiddle_divisor", EV_VOLATILE, "1", twiddle_set, env_nounset);
+
+ /* Do all console probes */
+ for (cons = 0; consoles[cons] != NULL; cons++) {
+ consoles[cons]->c_flags = 0;
+ consoles[cons]->c_probe(consoles[cons]);
+ }
+ /* Now find the first working one */
+ active = -1;
+ for (cons = 0; consoles[cons] != NULL && active == -1; cons++) {
+ consoles[cons]->c_flags = 0;
+ consoles[cons]->c_probe(consoles[cons]);
+ if (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT))
+ active = cons;
+ }
+ /* Force a console even if all probes failed */
+ if (active == -1)
+ active = 0;
+
+ /* Check to see if a console preference has already been registered */
+ prefconsole = getenv("console");
+ if (prefconsole != NULL)
+ prefconsole = strdup(prefconsole);
+ if (prefconsole != NULL) {
+ unsetenv("console"); /* we want to replace this */
+ cons_change(prefconsole);
+ } else {
+ consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
+ consoles[active]->c_init(consoles[active], 0);
+ prefconsole = strdup(consoles[active]->c_name);
+ }
+
+ printf("Consoles: ");
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ if (consoles[cons]->c_flags & (C_ACTIVEIN | C_ACTIVEOUT))
+ printf("%s ", consoles[cons]->c_desc);
+ printf("\n");
+
+ if (prefconsole != NULL) {
+ env_setenv("console", EV_VOLATILE, prefconsole, cons_set,
+ env_nounset);
+ free(prefconsole);
+ }
+}
+
+void
+cons_mode(int raw)
+{
+ int cons;
+
+ for (cons = 0; consoles[cons] != NULL; cons++) {
+ if (raw == 0)
+ consoles[cons]->c_flags &= ~C_MODERAW;
+ else
+ consoles[cons]->c_flags |= C_MODERAW;
+ }
+}
+
+int
+getchar(void)
+{
+ int cons;
+ int rv;
+
+ /* Loop forever polling all active consoles */
+ for(;;)
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ if ((consoles[cons]->c_flags & (C_PRESENTIN | C_ACTIVEIN)) ==
+ (C_PRESENTIN | C_ACTIVEIN) &&
+ ((rv = consoles[cons]->c_in(consoles[cons])) != -1))
+ return(rv);
+}
+
+int
+ischar(void)
+{
+ int cons;
+
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ if ((consoles[cons]->c_flags & (C_PRESENTIN | C_ACTIVEIN)) ==
+ (C_PRESENTIN | C_ACTIVEIN) &&
+ (consoles[cons]->c_ready(consoles[cons]) != 0))
+ return(1);
+ return(0);
+}
+
+void
+putchar(int c)
+{
+ int cons;
+
+ /* Expand newlines if not in raw mode */
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ if ((consoles[cons]->c_flags & (C_PRESENTOUT | C_ACTIVEOUT)) ==
+ (C_PRESENTOUT | C_ACTIVEOUT)) {
+ if (c == '\n' && (consoles[cons]->c_flags & C_MODERAW) == 0)
+ consoles[cons]->c_out(consoles[cons], '\r');
+ consoles[cons]->c_out(consoles[cons], c);
+ }
+}
+
+/*
+ * Find the console with the specified name.
+ */
+static int
+cons_find(const char *name)
+{
+ int cons;
+
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ if (!strcmp(consoles[cons]->c_name, name))
+ return (cons);
+ return (-1);
+}
+
+/*
+ * Select one or more consoles.
+ */
+static int
+cons_set(struct env_var *ev, int flags, const void *value)
+{
+ int ret;
+
+ if ((value == NULL) || (cons_check(value) == 0)) {
+ /*
+ * Return CMD_OK instead of CMD_ERROR to prevent forth syntax error,
+ * which would prevent it processing any further loader.conf entries.
+ */
+ return (CMD_OK);
+ }
+
+ ret = cons_change(value);
+ if (ret != CMD_OK)
+ return (ret);
+
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (CMD_OK);
+}
+
+/*
+ * Check that at least one the consoles listed in *string is valid
+ */
+static int
+cons_check(const char *string)
+{
+ int cons, found, failed;
+ char *curpos, *dup, *next;
+
+ dup = next = strdup(string);
+ found = failed = 0;
+ while (next != NULL) {
+ curpos = strsep(&next, " ,");
+ if (*curpos != '\0') {
+ cons = cons_find(curpos);
+ if (cons == -1) {
+ printf("console %s is invalid!\n", curpos);
+ failed++;
+ } else {
+ found++;
+ }
+ }
+ }
+
+ free(dup);
+
+ if (found == 0)
+ printf("no valid consoles!\n");
+
+ if (found == 0 || failed != 0) {
+ printf("Available consoles:\n");
+ for (cons = 0; consoles[cons] != NULL; cons++)
+ printf(" %s\n", consoles[cons]->c_name);
+ }
+
+ return (found);
+}
+
+/*
+ * Activate all the valid consoles listed in *string and disable all others.
+ */
+static int
+cons_change(const char *string)
+{
+ int cons, active;
+ char *curpos, *dup, *next;
+
+ /* Disable all consoles */
+ for (cons = 0; consoles[cons] != NULL; cons++) {
+ consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
+ }
+
+ /* Enable selected consoles */
+ dup = next = strdup(string);
+ active = 0;
+ while (next != NULL) {
+ curpos = strsep(&next, " ,");
+ if (*curpos == '\0')
+ continue;
+ cons = cons_find(curpos);
+ if (cons >= 0) {
+ consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
+ consoles[cons]->c_init(consoles[cons], 0);
+ if ((consoles[cons]->c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
+ (C_PRESENTIN | C_PRESENTOUT)) {
+ active++;
+ continue;
+ }
+
+ if (active != 0) {
+ /* If no consoles have initialised we wouldn't see this. */
+ printf("console %s failed to initialize\n", consoles[cons]->c_name);
+ }
+ }
+ }
+
+ free(dup);
+
+ if (active == 0) {
+ /* All requested consoles failed to initialise, try to recover. */
+ for (cons = 0; consoles[cons] != NULL; cons++) {
+ consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
+ consoles[cons]->c_init(consoles[cons], 0);
+ if ((consoles[cons]->c_flags &
+ (C_PRESENTIN | C_PRESENTOUT)) ==
+ (C_PRESENTIN | C_PRESENTOUT))
+ active++;
+ }
+
+ if (active == 0)
+ return (CMD_ERROR); /* Recovery failed. */
+ }
+
+ return (CMD_OK);
+}
+
+/*
+ * Change the twiddle divisor.
+ *
+ * The user can set the twiddle_divisor variable to directly control how fast
+ * the progress twiddle spins, useful for folks with slow serial consoles. The
+ * code to monitor changes to the variable and propagate them to the twiddle
+ * routines has to live somewhere. Twiddling is console-related so it's here.
+ */
+static int
+twiddle_set(struct env_var *ev, int flags, const void *value)
+{
+ u_long tdiv;
+ char * eptr;
+
+ tdiv = strtoul(value, &eptr, 0);
+ if (*(const char *)value == 0 || *eptr != 0) {
+ printf("invalid twiddle_divisor '%s'\n", (const char *)value);
+ return (CMD_ERROR);
+ }
+ twiddle_divisor((u_int)tdiv);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+ return(CMD_OK);
+}
diff --git a/usr/src/boot/sys/boot/common/crc32.c b/usr/src/boot/sys/boot/common/crc32.c
new file mode 100644
index 0000000000..1a3e3a3329
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/crc32.c
@@ -0,0 +1,108 @@
+/*-
+ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/*
+ * First, the polynomial itself and its table of feedback terms. The
+ * polynomial is
+ * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ *
+ * Note that we take it "backwards" and put the highest-order term in
+ * the lowest-order bit. The X^32 term is "implied"; the LSB is the
+ * X^31 term, etc. The X^0 term (usually shown as "+1") results in
+ * the MSB being 1
+ *
+ * Note that the usual hardware shift register implementation, which
+ * is what we're using (we're merely optimizing it by doing eight-bit
+ * chunks at a time) shifts bits into the lowest-order term. In our
+ * implementation, that means shifting towards the right. Why do we
+ * do it this way? Because the calculated CRC must be transmitted in
+ * order from highest-order term to lowest-order term. UARTs transmit
+ * characters in order from LSB to MSB. By storing the CRC this way
+ * we hand it to the UART in the order low-byte to high-byte; the UART
+ * sends each low-bit to hight-bit; and the result is transmission bit
+ * by bit from highest- to lowest-order term without requiring any bit
+ * shuffling on our part. Reception works similarly
+ *
+ * The feedback terms table consists of 256, 32-bit entries. Notes
+ *
+ * The table can be generated at runtime if desired; code to do so
+ * is shown later. It might not be obvious, but the feedback
+ * terms simply represent the results of eight shift/xor opera
+ * tions for all combinations of data and CRC register values
+ *
+ * The values must be right-shifted by eight bits by the "updcrc
+ * logic; the shift must be unsigned (bring in zeroes). On some
+ * hardware you could probably optimize the shift in assembler by
+ * using byte-swap instructions
+ * polynomial $edb88320
+ *
+ *
+ * CRC32 code derived from work by Gary S. Brown.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include "crc32.h"
+
+static const uint32_t crc32_tab[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+uint32_t
+crc32(const void *buf, size_t size)
+{
+ const uint8_t *p = buf;
+ uint32_t crc;
+
+ crc = ~0U;
+ while (size--)
+ crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+ return (crc ^ ~0U);
+}
diff --git a/usr/src/boot/sys/boot/common/crc32.h b/usr/src/boot/sys/boot/common/crc32.h
new file mode 100644
index 0000000000..adfd628671
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/crc32.h
@@ -0,0 +1,13 @@
+/*-
+ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _CRC32_H_
+#define _CRC32_H_
+
+uint32_t crc32(const void *buf, size_t size);
+
+#endif /* !_CRC32_H_ */
diff --git a/usr/src/boot/sys/boot/common/dev_net.c b/usr/src/boot/sys/boot/common/dev_net.c
new file mode 100644
index 0000000000..98ae42b33f
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/dev_net.c
@@ -0,0 +1,380 @@
+/* $NetBSD: dev_net.c,v 1.23 2008/04/28 20:24:06 martin Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * RARP for IP address - rarp_getipaddress()
+ * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
+ * RPC/mountd - nfs_mount(sock, ip, path)
+ *
+ * the root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ */
+
+#include <machine/stdarg.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <string.h>
+#include <net.h>
+#include <netif.h>
+#include <bootp.h>
+#include <bootparam.h>
+
+#include "dev_net.h"
+#include "bootstrap.h"
+
+#ifdef NETIF_DEBUG
+int debug = 0;
+#endif
+
+static char *netdev_name;
+static int netdev_sock = -1;
+static int netdev_opens;
+
+static int net_init(void);
+static int net_open(struct open_file *, ...);
+static int net_close(struct open_file *);
+static void net_cleanup(void);
+static int net_strategy();
+static int net_print(int);
+
+static int net_getparams(int sock);
+
+struct devsw netdev = {
+ "net",
+ DEVT_NET,
+ net_init,
+ net_strategy,
+ net_open,
+ net_close,
+ noioctl,
+ net_print,
+ net_cleanup
+};
+
+static int
+net_init(void)
+{
+
+ return (0);
+}
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ * This is declared with variable arguments...
+ */
+static int
+net_open(struct open_file *f, ...)
+{
+ struct iodesc *d;
+ va_list args;
+ char *devname; /* Device part of file name (or NULL). */
+ int error = 0;
+
+ va_start(args, f);
+ devname = va_arg(args, char*);
+ va_end(args);
+
+#ifdef NETIF_OPEN_CLOSE_ONCE
+ /* Before opening another interface, close the previous one first. */
+ if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0)
+ net_cleanup();
+#endif
+
+ /* On first open, do netif open, mount, etc. */
+ if (netdev_opens == 0) {
+ /* Find network interface. */
+ if (netdev_sock < 0) {
+ netdev_sock = netif_open(devname);
+ if (netdev_sock < 0) {
+ printf("net_open: netif_open() failed\n");
+ return (ENXIO);
+ }
+ netdev_name = strdup(devname);
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: netif_open() succeeded\n");
+#endif
+ }
+ /*
+ * If network params were not set by netif_open(), try to get
+ * them via bootp, rarp, etc.
+ */
+ if (rootip.s_addr == 0) {
+ /* Get root IP address, and path, etc. */
+ error = net_getparams(netdev_sock);
+ if (error) {
+ /* getparams makes its own noise */
+ free(netdev_name);
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ return (error);
+ }
+ }
+ /*
+ * Set the variables required by the kernel's nfs_diskless
+ * mechanism. This is the minimum set of variables required to
+ * mount a root filesystem without needing to obtain additional
+ * info from bootp or other sources.
+ */
+ d = socktodesc(netdev_sock);
+ setenv("boot.netif.hwaddr", ether_sprintf(d->myea), 1);
+ setenv("boot.netif.ip", inet_ntoa(myip), 1);
+ setenv("boot.netif.netmask", intoa(netmask), 1);
+ setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
+ setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
+ setenv("boot.nfsroot.path", rootpath, 1);
+ }
+ netdev_opens++;
+ f->f_devdata = &netdev_sock;
+ return (error);
+}
+
+static int
+net_close(struct open_file *f)
+{
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: opens=%d\n", netdev_opens);
+#endif
+
+ f->f_devdata = NULL;
+
+#ifndef NETIF_OPEN_CLOSE_ONCE
+ /* Extra close call? */
+ if (netdev_opens <= 0)
+ return (0);
+ netdev_opens--;
+ /* Not last close? */
+ if (netdev_opens > 0)
+ return (0);
+ /* On last close, do netif close, etc. */
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: calling net_cleanup()\n");
+#endif
+ net_cleanup();
+#endif
+ return (0);
+}
+
+static void
+net_cleanup(void)
+{
+
+ if (netdev_sock >= 0) {
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_cleanup: calling netif_close()\n");
+#endif
+ rootip.s_addr = 0;
+ free(netdev_name);
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ }
+}
+
+static int
+net_strategy()
+{
+
+ return (EIO);
+}
+
+#define SUPPORT_BOOTP
+
+/*
+ * Get info for NFS boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ * There are two ways to do this: The old, Sun way,
+ * and the more modern, BOOTP way. (RFC951, RFC1048)
+ *
+ * The default is to use the Sun bootparams RPC
+ * (because that is what the kernel will do).
+ * MD code can make try_bootp initialied data,
+ * which will override this common definition.
+ */
+#ifdef SUPPORT_BOOTP
+int try_bootp = 1;
+#endif
+
+extern n_long ip_convertaddr(char *p);
+
+static int
+net_getparams(int sock)
+{
+ char buf[MAXHOSTNAMELEN];
+ n_long rootaddr, smask;
+
+#ifdef SUPPORT_BOOTP
+ /*
+ * Try to get boot info using BOOTP. If we succeed, then
+ * the server IP address, gateway, and root path will all
+ * be initialized. If any remain uninitialized, we will
+ * use RARP and RPC/bootparam (the Sun way) to get them.
+ */
+ if (try_bootp)
+ bootp(sock, BOOTP_NONE);
+ if (myip.s_addr != 0)
+ goto exit;
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: BOOTP failed, trying RARP/RPC...\n");
+#endif
+#endif
+
+ /*
+ * Use RARP to get our IP address. This also sets our
+ * netmask to the "natural" default for our address.
+ */
+ if (rarp_getipaddress(sock)) {
+ printf("net_open: RARP failed\n");
+ return (EIO);
+ }
+ printf("net_open: client addr: %s\n", inet_ntoa(myip));
+
+ /* Get our hostname, server IP address, gateway. */
+ if (bp_whoami(sock)) {
+ printf("net_open: bootparam/whoami RPC failed\n");
+ return (EIO);
+ }
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: client name: %s\n", hostname);
+#endif
+
+ /*
+ * Ignore the gateway from whoami (unreliable).
+ * Use the "gateway" parameter instead.
+ */
+ smask = 0;
+ gateip.s_addr = 0;
+ if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
+ /* Got it! Parse the netmask. */
+ smask = ip_convertaddr(buf);
+ }
+ if (smask) {
+ netmask = smask;
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: subnet mask: %s\n", intoa(netmask));
+#endif
+ }
+#ifdef NETIF_DEBUG
+ if (gateip.s_addr && debug)
+ printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
+#endif
+
+ /* Get the root server and pathname. */
+ if (bp_getfile(sock, "root", &rootip, rootpath)) {
+ printf("net_open: bootparam/getfile RPC failed\n");
+ return (EIO);
+ }
+exit:
+ if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
+ rootip.s_addr = rootaddr;
+
+#ifdef NETIF_DEBUG
+ if (debug) {
+ printf("net_open: server addr: %s\n", inet_ntoa(rootip));
+ printf("net_open: server path: %s\n", rootpath);
+ }
+#endif
+
+ return (0);
+}
+
+static int
+net_print(int verbose)
+{
+ struct netif_driver *drv;
+ char line[80];
+ int i, d, cnt;
+ int ret = 0;
+
+ cnt = 0;
+ for (d = 0; netif_drivers[d]; d++) {
+ drv = netif_drivers[d];
+ for (i = 0; i < drv->netif_nifs; i++) {
+ snprintf(line, 80, "\t%s%d:", "net", cnt++);
+ ret = pager_output(line);
+ if (ret != 0)
+ break;
+ if (verbose) {
+ snprintf(line, 80, " (%s%d)", drv->netif_bname,
+ drv->netif_ifs[i].dif_unit);
+ ret = pager_output(line);
+ if (ret != 0)
+ break;
+ }
+ }
+ }
+ return (ret |= pager_output("\n"));
+}
+
+/*
+ * Strip the server's address off of the rootpath if present and return it in
+ * network byte order, leaving just the pathname part in the global rootpath.
+ */
+uint32_t
+net_parse_rootpath()
+{
+ int i;
+ n_long addr = INADDR_NONE;
+
+ for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
+ if (rootpath[i] == ':')
+ break;
+ if (i && i != FNAME_SIZE && rootpath[i] == ':') {
+ rootpath[i++] = '\0';
+ addr = inet_addr(&rootpath[0]);
+ bcopy(&rootpath[i], rootpath, strlen(&rootpath[i])+1);
+ }
+ return (addr);
+}
diff --git a/usr/src/boot/sys/boot/common/dev_net.h b/usr/src/boot/sys/boot/common/dev_net.h
new file mode 100644
index 0000000000..995b67241d
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/dev_net.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOT_DEV_NET_H_
+#define _BOOT_DEV_NET_H_
+
+extern struct devsw netdev;
+
+uint32_t net_parse_rootpath(void);
+
+#endif
diff --git a/usr/src/boot/sys/boot/common/devopen.c b/usr/src/boot/sys/boot/common/devopen.c
new file mode 100644
index 0000000000..de6165c03e
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/devopen.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+int
+devopen(struct open_file *f, const char *fname, const char **file)
+{
+ struct devdesc *dev;
+ int result;
+
+ result = archsw.arch_getdev((void **)&dev, fname, file);
+ if (result)
+ return (result);
+
+ /* point to device-specific data so that device open can use it */
+ f->f_devdata = dev;
+ result = dev->d_dev->dv_open(f, dev);
+ if (result != 0) {
+ f->f_devdata = NULL;
+ free(dev);
+ return (result);
+ }
+
+ /* reference the devsw entry from the open_file structure */
+ f->f_dev = dev->d_dev;
+ return (0);
+}
+
+int
+devclose(struct open_file *f)
+{
+
+ if (f->f_devdata != NULL) {
+ free(f->f_devdata);
+ }
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/common/disk.c b/usr/src/boot/sys/boot/common/disk.c
new file mode 100644
index 0000000000..d1bf0d93fa
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/disk.c
@@ -0,0 +1,534 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/disk.h>
+#include <sys/queue.h>
+#include <stand.h>
+#include <stdarg.h>
+#include <bootstrap.h>
+#include <part.h>
+
+#include "disk.h"
+
+#ifdef DISK_DEBUG
+# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+# define DEBUG(fmt, args...)
+#endif
+
+struct open_disk {
+ struct ptable *table;
+ off_t mediasize;
+ u_int sectorsize;
+ u_int flags;
+ int rcnt;
+};
+
+struct print_args {
+ struct disk_devdesc *dev;
+ const char *prefix;
+ int verbose;
+};
+
+struct dentry {
+ const struct devsw *d_dev;
+ int d_unit;
+ int d_slice;
+ int d_partition;
+
+ struct open_disk *od;
+ off_t d_offset;
+ STAILQ_ENTRY(dentry) entry;
+#ifdef DISK_DEBUG
+ uint32_t count;
+#endif
+};
+
+static STAILQ_HEAD(, dentry) opened_disks =
+ STAILQ_HEAD_INITIALIZER(opened_disks);
+
+static int
+disk_lookup(struct disk_devdesc *dev)
+{
+ struct dentry *entry;
+ int rc;
+
+ rc = ENOENT;
+ STAILQ_FOREACH(entry, &opened_disks, entry) {
+ if (entry->d_dev != dev->d_dev ||
+ entry->d_unit != dev->d_unit)
+ continue;
+ dev->d_opendata = entry->od;
+ if (entry->d_slice == dev->d_slice &&
+ entry->d_partition == dev->d_partition) {
+ dev->d_offset = entry->d_offset;
+ DEBUG("%s offset %lld", disk_fmtdev(dev),
+ (long long)dev->d_offset);
+#ifdef DISK_DEBUG
+ entry->count++;
+#endif
+ return (0);
+ }
+ rc = EAGAIN;
+ }
+ return (rc);
+}
+
+static void
+disk_insert(struct disk_devdesc *dev)
+{
+ struct dentry *entry;
+
+ entry = (struct dentry *)malloc(sizeof(struct dentry));
+ if (entry == NULL) {
+ DEBUG("no memory");
+ return;
+ }
+ entry->d_dev = dev->d_dev;
+ entry->d_unit = dev->d_unit;
+ entry->d_slice = dev->d_slice;
+ entry->d_partition = dev->d_partition;
+ entry->od = (struct open_disk *)dev->d_opendata;
+ entry->od->rcnt++;
+ entry->d_offset = dev->d_offset;
+#ifdef DISK_DEBUG
+ entry->count = 1;
+#endif
+ STAILQ_INSERT_TAIL(&opened_disks, entry, entry);
+ DEBUG("%s cached", disk_fmtdev(dev));
+}
+
+#ifdef DISK_DEBUG
+COMMAND_SET(dcachestat, "dcachestat", "get disk cache stats",
+ command_dcachestat);
+
+static int
+command_dcachestat(int argc, char *argv[])
+{
+ struct disk_devdesc dev;
+ struct dentry *entry;
+
+ STAILQ_FOREACH(entry, &opened_disks, entry) {
+ dev.d_dev = (struct devsw *)entry->d_dev;
+ dev.d_unit = entry->d_unit;
+ dev.d_slice = entry->d_slice;
+ dev.d_partition = entry->d_partition;
+ printf("%s %d => %p [%d]\n", disk_fmtdev(&dev), entry->count,
+ entry->od, entry->od->rcnt);
+ }
+ return (CMD_OK);
+}
+#endif /* DISK_DEBUG */
+
+/* Convert size to a human-readable number. */
+static char *
+display_size(uint64_t size, u_int sectorsize)
+{
+ static char buf[80];
+ char unit;
+
+ size = size * sectorsize / 1024;
+ unit = 'K';
+ if (size >= 10485760000LL) {
+ size /= 1073741824;
+ unit = 'T';
+ } else if (size >= 10240000) {
+ size /= 1048576;
+ unit = 'G';
+ } else if (size >= 10000) {
+ size /= 1024;
+ unit = 'M';
+ }
+ sprintf(buf, "%ld%cB", (long)size, unit);
+ return (buf);
+}
+
+static int
+ptblread(void *d, void *buf, size_t blocks, off_t offset)
+{
+ struct disk_devdesc *dev;
+ struct open_disk *od;
+
+ dev = (struct disk_devdesc *)d;
+ od = (struct open_disk *)dev->d_opendata;
+ return (dev->d_dev->dv_strategy(dev, F_READ, offset, 0,
+ blocks * od->sectorsize, (char *)buf, NULL));
+}
+
+#define PWIDTH 35
+static int
+ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
+{
+ struct print_args *pa, bsd;
+ struct open_disk *od;
+ struct ptable *table;
+ char line[80];
+ int ret = 0;
+
+ pa = (struct print_args *)arg;
+ od = (struct open_disk *)pa->dev->d_opendata;
+ sprintf(line, " %s%s: %s", pa->prefix, pname,
+ parttype2str(part->type));
+ if (pa->verbose)
+ sprintf(line, "%-*s%s", PWIDTH, line,
+ display_size(part->end - part->start + 1,
+ od->sectorsize));
+ strcat(line, "\n");
+ ret = pager_output(line);
+ if (ret != 0)
+ return (ret);
+ if (part->type == PART_FREEBSD || part->type == PART_SOLARIS2) {
+ /* Open slice with BSD or VTOC label */
+ pa->dev->d_offset = part->start;
+ table = ptable_open(pa->dev, part->end - part->start + 1,
+ od->sectorsize, ptblread);
+ if (table == NULL)
+ return (ret);
+ sprintf(line, " %s%s", pa->prefix, pname);
+ bsd.dev = pa->dev;
+ bsd.prefix = line;
+ bsd.verbose = pa->verbose;
+ ret = ptable_iterate(table, &bsd, ptable_print);
+ ptable_close(table);
+ }
+ return (ret);
+}
+#undef PWIDTH
+
+int
+disk_print(struct disk_devdesc *dev, char *prefix, int verbose)
+{
+ struct open_disk *od;
+ struct print_args pa;
+
+ /* Disk should be opened */
+ od = (struct open_disk *)dev->d_opendata;
+ pa.dev = dev;
+ pa.prefix = prefix;
+ pa.verbose = verbose;
+ return (ptable_iterate(od->table, &pa, ptable_print));
+}
+
+int
+disk_read(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
+{
+ struct open_disk *od;
+ int ret;
+
+ od = (struct open_disk *)dev->d_opendata;
+ ret = dev->d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset, 0,
+ blocks * od->sectorsize, buf, NULL);
+
+ return (ret);
+}
+
+int
+disk_write(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
+{
+ struct open_disk *od;
+ int ret;
+
+ od = (struct open_disk *)dev->d_opendata;
+ ret = dev->d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset, 0,
+ blocks * od->sectorsize, buf, NULL);
+
+ return (ret);
+}
+
+int
+disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf)
+{
+
+ if (dev->d_dev->dv_ioctl)
+ return ((*dev->d_dev->dv_ioctl)(dev->d_opendata, cmd, buf));
+
+ return (ENXIO);
+}
+
+int
+disk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize,
+ u_int flags)
+{
+ struct open_disk *od;
+ struct ptable *table;
+ struct ptable_entry part;
+ int rc, slice, partition;
+
+ rc = 0;
+ if ((flags & DISK_F_NOCACHE) == 0) {
+ rc = disk_lookup(dev);
+ if (rc == 0)
+ return (0);
+ }
+ /*
+ * While we are reading disk metadata, make sure we do it relative
+ * to the start of the disk
+ */
+ dev->d_offset = 0;
+ table = NULL;
+ slice = dev->d_slice;
+ partition = dev->d_partition;
+ if (rc == EAGAIN) {
+ /*
+ * This entire disk was already opened and there is no
+ * need to allocate new open_disk structure and open the
+ * main partition table.
+ */
+ od = (struct open_disk *)dev->d_opendata;
+ DEBUG("%s unit %d, slice %d, partition %d => %p (cached)",
+ disk_fmtdev(dev), dev->d_unit, dev->d_slice,
+ dev->d_partition, od);
+ goto opened;
+ } else {
+ od = (struct open_disk *)malloc(sizeof(struct open_disk));
+ if (od == NULL) {
+ DEBUG("no memory");
+ return (ENOMEM);
+ }
+ dev->d_opendata = od;
+ od->rcnt = 0;
+ }
+ od->mediasize = mediasize;
+ od->sectorsize = sectorsize;
+ od->flags = flags;
+ DEBUG("%s unit %d, slice %d, partition %d => %p",
+ disk_fmtdev(dev), dev->d_unit, dev->d_slice, dev->d_partition, od);
+
+ /* Determine disk layout. */
+ od->table = ptable_open(dev, mediasize / sectorsize, sectorsize,
+ ptblread);
+ if (od->table == NULL) {
+ DEBUG("Can't read partition table");
+ rc = ENXIO;
+ goto out;
+ }
+opened:
+ rc = 0;
+ if (ptable_gettype(od->table) == PTABLE_BSD &&
+ partition >= 0) {
+ /* It doesn't matter what value has d_slice */
+ rc = ptable_getpart(od->table, &part, partition);
+ if (rc == 0)
+ dev->d_offset = part.start;
+ } else if (slice >= 0) {
+ /* Try to get information about partition */
+ if (slice == 0)
+ rc = ptable_getbestpart(od->table, &part);
+ else
+ rc = ptable_getpart(od->table, &part, slice);
+ if (rc != 0) /* Partition doesn't exist */
+ goto out;
+ dev->d_offset = part.start;
+ slice = part.index;
+ if (ptable_gettype(od->table) == PTABLE_GPT) {
+ partition = 255;
+ goto out; /* Nothing more to do */
+ } else if (partition == 255) {
+ /*
+ * When we try to open GPT partition, but partition
+ * table isn't GPT, reset d_partition value to -1
+ * and try to autodetect appropriate value.
+ */
+ partition = -1;
+ }
+ /*
+ * If d_partition < 0 and we are looking at a BSD/VTOC slice,
+ * then try to read label, otherwise return the
+ * whole MBR slice.
+ */
+ if (partition == -1 &&
+ (part.type != PART_FREEBSD || part.type != PART_SOLARIS2))
+ goto out;
+ /* Try to read label */
+ table = ptable_open(dev, part.end - part.start + 1,
+ od->sectorsize, ptblread);
+ if (table == NULL) {
+ DEBUG("Can't read BSD/VTOC label");
+ rc = ENXIO;
+ goto out;
+ }
+ /*
+ * If slice contains BSD/VTOC label and d_partition < 0, then
+ * assume the 'a' partition. Otherwise just return the
+ * whole MBR slice, because it can contain ZFS.
+ */
+ if (partition < 0) {
+ if (ptable_gettype(table) != PTABLE_BSD ||
+ ptable_gettype(table) != PTABLE_VTOC)
+ goto out;
+ partition = 0;
+ }
+ rc = ptable_getpart(table, &part, partition);
+ if (rc != 0)
+ goto out;
+ dev->d_offset += part.start;
+ }
+out:
+ if (table != NULL)
+ ptable_close(table);
+
+ if (rc != 0) {
+ if (od->rcnt < 1) {
+ if (od->table != NULL)
+ ptable_close(od->table);
+ free(od);
+ }
+ DEBUG("%s could not open", disk_fmtdev(dev));
+ } else {
+ if ((flags & DISK_F_NOCACHE) == 0)
+ disk_insert(dev);
+ /* Save the slice and partition number to the dev */
+ dev->d_slice = slice;
+ dev->d_partition = partition;
+ DEBUG("%s offset %lld => %p", disk_fmtdev(dev),
+ (long long)dev->d_offset, od);
+ }
+ return (rc);
+}
+
+int
+disk_close(struct disk_devdesc *dev)
+{
+ struct open_disk *od;
+
+ od = (struct open_disk *)dev->d_opendata;
+ DEBUG("%s closed => %p [%d]", disk_fmtdev(dev), od, od->rcnt);
+ if (od->flags & DISK_F_NOCACHE) {
+ ptable_close(od->table);
+ free(od);
+ }
+ return (0);
+}
+
+void
+disk_cleanup(const struct devsw *d_dev)
+{
+#ifdef DISK_DEBUG
+ struct disk_devdesc dev;
+#endif
+ struct dentry *entry, *tmp;
+
+ STAILQ_FOREACH_SAFE(entry, &opened_disks, entry, tmp) {
+ if (entry->d_dev != d_dev)
+ continue;
+ entry->od->rcnt--;
+#ifdef DISK_DEBUG
+ dev.d_dev = (struct devsw *)entry->d_dev;
+ dev.d_unit = entry->d_unit;
+ dev.d_slice = entry->d_slice;
+ dev.d_partition = entry->d_partition;
+ DEBUG("%s was freed => %p [%d]", disk_fmtdev(&dev),
+ entry->od, entry->od->rcnt);
+#endif
+ STAILQ_REMOVE(&opened_disks, entry, dentry, entry);
+ if (entry->od->rcnt < 1) {
+ if (entry->od->table != NULL)
+ ptable_close(entry->od->table);
+ free(entry->od);
+ }
+ free(entry);
+ }
+}
+
+char*
+disk_fmtdev(struct disk_devdesc *dev)
+{
+ static char buf[128];
+ char *cp;
+
+ cp = buf + sprintf(buf, "%s%d", dev->d_dev->dv_name, dev->d_unit);
+ if (dev->d_slice >= 0) {
+#ifdef LOADER_GPT_SUPPORT
+ if (dev->d_partition == 255) {
+ sprintf(cp, "p%d:", dev->d_slice);
+ return (buf);
+ } else
+#endif
+#ifdef LOADER_MBR_SUPPORT
+ cp += sprintf(cp, "s%d", dev->d_slice);
+#endif
+ }
+ if (dev->d_partition >= 0)
+ cp += sprintf(cp, "%c", dev->d_partition + 'a');
+ strcat(cp, ":");
+ return (buf);
+}
+
+int
+disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path)
+{
+ int unit, slice, partition;
+ const char *np;
+ char *cp;
+
+ np = devspec;
+ unit = slice = partition = -1;
+ if (*np != '\0' && *np != ':') {
+ unit = strtol(np, &cp, 10);
+ if (cp == np)
+ return (EUNIT);
+#ifdef LOADER_GPT_SUPPORT
+ if (*cp == 'p') {
+ np = cp + 1;
+ slice = strtol(np, &cp, 10);
+ if (np == cp)
+ return (ESLICE);
+ /* we don't support nested partitions on GPT */
+ if (*cp != '\0' && *cp != ':')
+ return (EINVAL);
+ partition = 255;
+ } else
+#endif
+#ifdef LOADER_MBR_SUPPORT
+ if (*cp == 's') {
+ np = cp + 1;
+ slice = strtol(np, &cp, 10);
+ if (np == cp)
+ return (ESLICE);
+ }
+#endif
+ if (*cp != '\0' && *cp != ':') {
+ partition = *cp - 'a';
+ if (partition < 0)
+ return (EPART);
+ cp++;
+ }
+ } else
+ return (EINVAL);
+
+ if (*cp != '\0' && *cp != ':')
+ return (EINVAL);
+ dev->d_unit = unit;
+ dev->d_slice = slice;
+ dev->d_partition = partition;
+ if (path != NULL)
+ *path = (*cp == '\0') ? cp: cp + 1;
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/common/disk.h b/usr/src/boot/sys/boot/common/disk.h
new file mode 100644
index 0000000000..32bc6eb955
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/disk.h
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Device descriptor for partitioned disks. To use, set the
+ * d_slice and d_partition variables as follows:
+ *
+ * Whole disk access:
+ *
+ * d_slice = -1
+ * d_partition = -1
+ *
+ * Whole MBR slice:
+ *
+ * d_slice = MBR slice number (typically 1..4)
+ * d_partition = -1
+ *
+ * VTOC disklabel partition within an MBR slice:
+ *
+ * d_slice = MBR slice number (typically 1..4)
+ * d_partition = disklabel partition (typically 0..19)
+ *
+ * BSD disklabel partition within an MBR slice:
+ *
+ * d_slice = MBR slice number (typically 1..4)
+ * d_partition = disklabel partition (typically 0..19)
+ *
+ * BSD disklabel partition on the true dedicated disk:
+ *
+ * d_slice = -1
+ * d_partition = disklabel partition (typically 0..19)
+ *
+ * GPT partition:
+ *
+ * d_slice = GPT partition number (typically 1..N)
+ * d_partition = 255
+ *
+ * For both MBR and GPT, to automatically find the 'best' slice or partition,
+ * set d_slice to zero. This uses the partition type to decide which partition
+ * to use according to the following list of preferences:
+ *
+ * Solaris2 (active)
+ * Solaris2 (inactive)
+ * Linux (active)
+ * Linux (inactive)
+ * DOS/Windows (active)
+ * DOS/Windows (inactive)
+ *
+ * Active MBR slices (marked as bootable) are preferred over inactive. GPT
+ * doesn't have the concept of active/inactive partitions. In both MBR and GPT,
+ * if there are multiple slices/partitions of a given type, the first one
+ * is chosen.
+ *
+ * The low-level disk device will typically call disk_open() from its open
+ * method to interpret the disk partition tables according to the rules above.
+ * This will initialize d_offset to the block offset of the start of the
+ * selected partition - this offset should be added to the offset passed to
+ * the device's strategy method.
+ */
+
+struct disk_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ void *d_opendata;
+ int d_slice;
+ int d_partition;
+ off_t d_offset;
+};
+
+enum disk_ioctl {
+ IOCTL_GET_BLOCKS,
+ IOCTL_GET_BLOCK_SIZE
+};
+
+/*
+ * Parse disk metadata and initialise dev->d_offset.
+ */
+extern int disk_open(struct disk_devdesc *dev, off_t mediasize,
+ u_int sectorsize, u_int flags);
+#define DISK_F_NOCACHE 0x0001 /* Do not use metadata caching */
+extern int disk_close(struct disk_devdesc *dev);
+extern void disk_cleanup(const struct devsw *d_dev);
+extern int disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf);
+extern int disk_read(struct disk_devdesc *dev, void *buf, off_t offset,
+ u_int blocks);
+extern int disk_write(struct disk_devdesc *dev, void *buf, off_t offset,
+ u_int blocks);
+
+/*
+ * Print information about slices on a disk.
+ */
+extern int disk_print(struct disk_devdesc *dev, char *prefix, int verbose);
+extern char* disk_fmtdev(struct disk_devdesc *dev);
+extern int disk_parsedev(struct disk_devdesc *dev, const char *devspec,
+ const char **path);
diff --git a/usr/src/boot/sys/boot/common/gpt.c b/usr/src/boot/sys/boot/common/gpt.c
new file mode 100644
index 0000000000..8baa64c37e
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/gpt.c
@@ -0,0 +1,381 @@
+/*-
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/gpt.h>
+
+#ifndef LITTLE_ENDIAN
+#error gpt.c works only for little endian architectures
+#endif
+
+#include "crc32.h"
+#include "drv.h"
+#include "util.h"
+#include "gpt.h"
+
+#define MAXTBLENTS 128
+
+static struct gpt_hdr hdr_primary, hdr_backup, *gpthdr;
+static uint64_t hdr_primary_lba, hdr_backup_lba;
+static struct gpt_ent table_primary[MAXTBLENTS], table_backup[MAXTBLENTS];
+static struct gpt_ent *gpttable;
+static int curent, bootonce;
+
+/*
+ * Buffer below 64kB passed on gptread(), which can hold at least
+ * one sector of data (512 bytes).
+ */
+static char *secbuf;
+
+static void
+gptupdate(const char *which, struct dsk *dskp, struct gpt_hdr *hdr,
+ struct gpt_ent *table)
+{
+ int entries_per_sec, firstent;
+ daddr_t slba;
+
+ /*
+ * We need to update the following for both primary and backup GPT:
+ * 1. Sector on disk that contains current partition.
+ * 2. Partition table checksum.
+ * 3. Header checksum.
+ * 4. Header on disk.
+ */
+
+ entries_per_sec = DEV_BSIZE / hdr->hdr_entsz;
+ slba = curent / entries_per_sec;
+ firstent = slba * entries_per_sec;
+ bcopy(&table[firstent], secbuf, DEV_BSIZE);
+ slba += hdr->hdr_lba_table;
+ if (drvwrite(dskp, secbuf, slba, 1)) {
+ printf("%s: unable to update %s GPT partition table\n",
+ BOOTPROG, which);
+ return;
+ }
+ hdr->hdr_crc_table = crc32(table, hdr->hdr_entries * hdr->hdr_entsz);
+ hdr->hdr_crc_self = 0;
+ hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
+ bzero(secbuf, DEV_BSIZE);
+ bcopy(hdr, secbuf, hdr->hdr_size);
+ if (drvwrite(dskp, secbuf, hdr->hdr_lba_self, 1)) {
+ printf("%s: unable to update %s GPT header\n", BOOTPROG, which);
+ return;
+ }
+}
+
+int
+gptfind(const uuid_t *uuid, struct dsk *dskp, int part)
+{
+ struct gpt_ent *ent;
+ int firsttry;
+
+ if (part >= 0) {
+ if (part == 0 || part > gpthdr->hdr_entries) {
+ printf("%s: invalid partition index\n", BOOTPROG);
+ return (-1);
+ }
+ ent = &gpttable[part - 1];
+ if (bcmp(&ent->ent_type, uuid, sizeof(uuid_t)) != 0) {
+ printf("%s: specified partition is not UFS\n",
+ BOOTPROG);
+ return (-1);
+ }
+ curent = part - 1;
+ goto found;
+ }
+
+ firsttry = (curent == -1);
+ curent++;
+ if (curent >= gpthdr->hdr_entries) {
+ curent = gpthdr->hdr_entries;
+ return (-1);
+ }
+ if (bootonce) {
+ /*
+ * First look for partition with both GPT_ENT_ATTR_BOOTME and
+ * GPT_ENT_ATTR_BOOTONCE flags.
+ */
+ for (; curent < gpthdr->hdr_entries; curent++) {
+ ent = &gpttable[curent];
+ if (bcmp(&ent->ent_type, uuid, sizeof(uuid_t)) != 0)
+ continue;
+ if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTME))
+ continue;
+ if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTONCE))
+ continue;
+ /* Ok, found one. */
+ goto found;
+ }
+ bootonce = 0;
+ curent = 0;
+ }
+ for (; curent < gpthdr->hdr_entries; curent++) {
+ ent = &gpttable[curent];
+ if (bcmp(&ent->ent_type, uuid, sizeof(uuid_t)) != 0)
+ continue;
+ if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTME))
+ continue;
+ if (ent->ent_attr & GPT_ENT_ATTR_BOOTONCE)
+ continue;
+ /* Ok, found one. */
+ goto found;
+ }
+ if (firsttry) {
+ /*
+ * No partition with BOOTME flag was found, try to boot from
+ * first UFS partition.
+ */
+ for (curent = 0; curent < gpthdr->hdr_entries; curent++) {
+ ent = &gpttable[curent];
+ if (bcmp(&ent->ent_type, uuid, sizeof(uuid_t)) != 0)
+ continue;
+ /* Ok, found one. */
+ goto found;
+ }
+ }
+ return (-1);
+found:
+ dskp->part = curent + 1;
+ ent = &gpttable[curent];
+ dskp->start = ent->ent_lba_start;
+ if (ent->ent_attr & GPT_ENT_ATTR_BOOTONCE) {
+ /*
+ * Clear BOOTME, but leave BOOTONCE set before trying to
+ * boot from this partition.
+ */
+ if (hdr_primary_lba > 0) {
+ table_primary[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTME;
+ gptupdate("primary", dskp, &hdr_primary, table_primary);
+ }
+ if (hdr_backup_lba > 0) {
+ table_backup[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTME;
+ gptupdate("backup", dskp, &hdr_backup, table_backup);
+ }
+ }
+ return (0);
+}
+
+static int
+gptread_hdr(const char *which, struct dsk *dskp, struct gpt_hdr *hdr,
+ uint64_t hdrlba)
+{
+ uint32_t crc;
+
+ if (drvread(dskp, secbuf, hdrlba, 1)) {
+ printf("%s: unable to read %s GPT header\n", BOOTPROG, which);
+ return (-1);
+ }
+ bcopy(secbuf, hdr, sizeof(*hdr));
+ if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0 ||
+ hdr->hdr_lba_self != hdrlba || hdr->hdr_revision < 0x00010000 ||
+ hdr->hdr_entsz < sizeof(struct gpt_ent) ||
+ hdr->hdr_entries > MAXTBLENTS || DEV_BSIZE % hdr->hdr_entsz != 0) {
+ printf("%s: invalid %s GPT header\n", BOOTPROG, which);
+ return (-1);
+ }
+ crc = hdr->hdr_crc_self;
+ hdr->hdr_crc_self = 0;
+ if (crc32(hdr, hdr->hdr_size) != crc) {
+ printf("%s: %s GPT header checksum mismatch\n", BOOTPROG,
+ which);
+ return (-1);
+ }
+ hdr->hdr_crc_self = crc;
+ return (0);
+}
+
+void
+gptbootfailed(struct dsk *dskp)
+{
+
+ if (!(gpttable[curent].ent_attr & GPT_ENT_ATTR_BOOTONCE))
+ return;
+
+ if (hdr_primary_lba > 0) {
+ table_primary[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTONCE;
+ table_primary[curent].ent_attr |= GPT_ENT_ATTR_BOOTFAILED;
+ gptupdate("primary", dskp, &hdr_primary, table_primary);
+ }
+ if (hdr_backup_lba > 0) {
+ table_backup[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTONCE;
+ table_backup[curent].ent_attr |= GPT_ENT_ATTR_BOOTFAILED;
+ gptupdate("backup", dskp, &hdr_backup, table_backup);
+ }
+}
+
+static void
+gptbootconv(const char *which, struct dsk *dskp, struct gpt_hdr *hdr,
+ struct gpt_ent *table)
+{
+ struct gpt_ent *ent;
+ daddr_t slba;
+ int table_updated, sector_updated;
+ int entries_per_sec, nent, part;
+
+ table_updated = 0;
+ entries_per_sec = DEV_BSIZE / hdr->hdr_entsz;
+ for (nent = 0, slba = hdr->hdr_lba_table;
+ slba < hdr->hdr_lba_table + hdr->hdr_entries / entries_per_sec;
+ slba++, nent += entries_per_sec) {
+ sector_updated = 0;
+ for (part = 0; part < entries_per_sec; part++) {
+ ent = &table[nent + part];
+ if ((ent->ent_attr & (GPT_ENT_ATTR_BOOTME |
+ GPT_ENT_ATTR_BOOTONCE |
+ GPT_ENT_ATTR_BOOTFAILED)) !=
+ GPT_ENT_ATTR_BOOTONCE) {
+ continue;
+ }
+ ent->ent_attr &= ~GPT_ENT_ATTR_BOOTONCE;
+ ent->ent_attr |= GPT_ENT_ATTR_BOOTFAILED;
+ table_updated = 1;
+ sector_updated = 1;
+ }
+ if (!sector_updated)
+ continue;
+ bcopy(&table[nent], secbuf, DEV_BSIZE);
+ if (drvwrite(dskp, secbuf, slba, 1)) {
+ printf("%s: unable to update %s GPT partition table\n",
+ BOOTPROG, which);
+ }
+ }
+ if (!table_updated)
+ return;
+ hdr->hdr_crc_table = crc32(table, hdr->hdr_entries * hdr->hdr_entsz);
+ hdr->hdr_crc_self = 0;
+ hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
+ bzero(secbuf, DEV_BSIZE);
+ bcopy(hdr, secbuf, hdr->hdr_size);
+ if (drvwrite(dskp, secbuf, hdr->hdr_lba_self, 1))
+ printf("%s: unable to update %s GPT header\n", BOOTPROG, which);
+}
+
+static int
+gptread_table(const char *which, const uuid_t *uuid, struct dsk *dskp,
+ struct gpt_hdr *hdr, struct gpt_ent *table)
+{
+ struct gpt_ent *ent;
+ int entries_per_sec;
+ int part, nent;
+ daddr_t slba;
+
+ if (hdr->hdr_entries == 0)
+ return (0);
+
+ entries_per_sec = DEV_BSIZE / hdr->hdr_entsz;
+ slba = hdr->hdr_lba_table;
+ nent = 0;
+ for (;;) {
+ if (drvread(dskp, secbuf, slba, 1)) {
+ printf("%s: unable to read %s GPT partition table\n",
+ BOOTPROG, which);
+ return (-1);
+ }
+ ent = (struct gpt_ent *)secbuf;
+ for (part = 0; part < entries_per_sec; part++, ent++) {
+ bcopy(ent, &table[nent], sizeof(table[nent]));
+ if (++nent >= hdr->hdr_entries)
+ break;
+ }
+ if (nent >= hdr->hdr_entries)
+ break;
+ slba++;
+ }
+ if (crc32(table, nent * hdr->hdr_entsz) != hdr->hdr_crc_table) {
+ printf("%s: %s GPT table checksum mismatch\n", BOOTPROG, which);
+ return (-1);
+ }
+ return (0);
+}
+
+int
+gptread(const uuid_t *uuid, struct dsk *dskp, char *buf)
+{
+ uint64_t altlba;
+
+ /*
+ * Read and verify both GPT headers: primary and backup.
+ */
+
+ secbuf = buf;
+ hdr_primary_lba = hdr_backup_lba = 0;
+ curent = -1;
+ bootonce = 1;
+ dskp->start = 0;
+
+ if (gptread_hdr("primary", dskp, &hdr_primary, 1) == 0 &&
+ gptread_table("primary", uuid, dskp, &hdr_primary,
+ table_primary) == 0) {
+ hdr_primary_lba = hdr_primary.hdr_lba_self;
+ gpthdr = &hdr_primary;
+ gpttable = table_primary;
+ }
+
+ if (hdr_primary_lba > 0) {
+ /*
+ * If primary header is valid, we can get backup
+ * header location from there.
+ */
+ altlba = hdr_primary.hdr_lba_alt;
+ } else {
+ altlba = drvsize(dskp);
+ if (altlba > 0)
+ altlba--;
+ }
+ if (altlba == 0)
+ printf("%s: unable to locate backup GPT header\n", BOOTPROG);
+ else if (gptread_hdr("backup", dskp, &hdr_backup, altlba) == 0 &&
+ gptread_table("backup", uuid, dskp, &hdr_backup,
+ table_backup) == 0) {
+ hdr_backup_lba = hdr_backup.hdr_lba_self;
+ if (hdr_primary_lba == 0) {
+ gpthdr = &hdr_backup;
+ gpttable = table_backup;
+ printf("%s: using backup GPT\n", BOOTPROG);
+ }
+ }
+
+ /*
+ * Convert all BOOTONCE without BOOTME flags into BOOTFAILED.
+ * BOOTONCE without BOOTME means that we tried to boot from it,
+ * but failed after leaving gptboot and machine was rebooted.
+ * We don't want to leave partitions marked as BOOTONCE only,
+ * because when we boot successfully start-up scripts should
+ * find at most one partition with only BOOTONCE flag and this
+ * will mean that we booted from that partition.
+ */
+ if (hdr_primary_lba != 0)
+ gptbootconv("primary", dskp, &hdr_primary, table_primary);
+ if (hdr_backup_lba != 0)
+ gptbootconv("backup", dskp, &hdr_backup, table_backup);
+
+ if (hdr_primary_lba == 0 && hdr_backup_lba == 0)
+ return (-1);
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/common/gpt.h b/usr/src/boot/sys/boot/common/gpt.h
new file mode 100644
index 0000000000..c42b40de8a
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/gpt.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#include <uuid.h>
+#include <drv.h>
+
+int gptread(const uuid_t *uuid, struct dsk *dskp, char *buf);
+int gptfind(const uuid_t *uuid, struct dsk *dskp, int part);
+void gptbootfailed(struct dsk *dskp);
+
+#endif /* !_GPT_H_ */
diff --git a/usr/src/boot/sys/boot/common/help.common b/usr/src/boot/sys/boot/common/help.common
new file mode 100644
index 0000000000..ead8511faf
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/help.common
@@ -0,0 +1,434 @@
+################################################################################
+# Thelp DDisplay command help
+
+ help [topic [subtopic]]
+ help index
+
+ The help command displays help on commands and their usage.
+
+ In command help, a term enclosed with <...> indicates a value as
+ described by the term. A term enclosed with [...] is optional,
+ and may not be required by all forms of the command.
+
+ Some commands may not be available. Use the '?' command to list
+ most available commands.
+
+################################################################################
+# T? DList available commands
+
+ ?
+
+ Lists all available commands.
+
+################################################################################
+# Tautoboot DBoot after a delay
+
+ autoboot [<delay> [<prompt>]]
+
+ Displays <prompt> or a default prompt, and counts down <delay> seconds
+ before attempting to boot. If <delay> is not specified, the default
+ value is 10.
+
+################################################################################
+# Tbeadm DList or switch Boot Environment
+
+ beadm activate beName [<device>]
+ beadm list [<device>]
+
+ beadm activate unloads the currently loaded configuration and modules,
+ sets currdev to <device> and loads configuration from new device.
+ Use lsdev to get available device names.
+
+################################################################################
+# Tboot DBoot immediately
+
+ boot [<kernelname>] [-<arg> ...]
+
+ Boot the system. If arguments are specified, they are added to the
+ arguments for the kernel. If <kernelname> is specified, and a kernel
+ has not already been loaded, it will be booted instead of the default
+ kernel.
+
+################################################################################
+# Tbcachestat DGet disk block cache stats
+
+ bcachestat
+
+ Displays statistics about disk cache usage. For debugging only.
+
+################################################################################
+# Tchain DChain load disk block
+
+ chain disk:
+
+ chain will read stage1 (MBR or VBR) boot block from specified device
+ to address 0000:7C00 and attempts to run it. Use lsdev to get available
+ device names. Disk name must end with colon.
+
+################################################################################
+# Techo DEcho arguments
+
+ echo [-n] [<message>]
+
+ Emits <message>, with no trailing newline if -n is specified. This is
+ most useful in conjunction with scripts and the '@' line prefix.
+
+ Variables are substituted by prefixing them with $, eg.
+
+ echo Current device is $currdev
+
+ will print the current device.
+
+################################################################################
+# Tload DLoad a kernel or module
+
+ load [-t <type>] <filename> [arguments]
+
+ Loads the module contained in <filename> into memory. If no other
+ modules are loaded, <filename> must be a kernel or the command will
+ fail.
+
+ If -t is specified, the module is loaded as raw data of <type>, for
+ later use by the kernel or other modules. <type> may be any string.
+
+ Optional arguments will be set as module arguments.
+
+################################################################################
+# Tls DList files
+
+ ls [-l] [<path>]
+
+ Displays a listing of files in the directory <path>, or the root
+ directory of the current device if <path> is not specified.
+
+ The -l argument displays file sizes as well; the process of obtaining
+ file sizes on some media may be very slow.
+
+################################################################################
+# Tlsdev DList devices
+
+ lsdev [-v]
+
+ List all of the devices from which it may be possible to load modules.
+ If -v is specified, print more details.
+
+################################################################################
+# Tlsmod DList modules
+
+ lsmod [-v]
+
+ List loaded modules. If [-v] is specified, print more details.
+
+################################################################################
+# Tmore DPage files
+
+ more <filename> [<filename> ...]
+
+ Show contents of text files. When displaying the contents of more,
+ than one file, if the user elects to quit displaying a file, the
+ remaining files will not be shown.
+
+################################################################################
+# Tpnpscan DScan for PnP devices
+
+ pnpscan [-v]
+
+ Scan for Plug-and-Play devices. This command is normally automatically
+ run as part of the boot process, in order to dynamically load modules
+ required for system operation.
+
+ If the -v argument is specified, details on the devices found will
+ be printed.
+
+################################################################################
+# Tset DSet a variable
+
+ set <variable name>
+ set <variable name>=<value>
+
+ The set command is used to set variables.
+
+################################################################################
+# Tsetprop DSet a variable
+
+ setprop <variable name> <value>
+
+ The setprop command is used to set variables.
+
+################################################################################
+# Tset Sautoboot_delay DSet the default autoboot delay
+
+ set autoboot_delay=<value>
+
+ Sets the default delay for the autoboot command to <value> seconds.
+ Set value to -1 if you don't want to allow user to interrupt autoboot
+ process and escape to the loader prompt.
+
+################################################################################
+# Tset Sbootfile DSet the default boot file set
+
+ set bootfile=<filename>[;<filename>...]
+
+ Sets the default set of kernel boot filename(s). It may be overridden
+ by setting the bootfile variable to a semicolon-separated list of
+ filenames, each of which will be searched for in the module_path
+ directories. The default bootfile set is "kernel".
+
+################################################################################
+# Tset Sboot_askname DPrompt for root device
+
+ set boot_askname
+
+ Instructs the kernel to prompt the user for the name of the root device
+ when the kernel is booted.
+
+################################################################################
+# Tset Sboot_cdrom DMount root file system from CD-ROM
+
+ set boot_cdrom
+
+ Instructs the kernel to try to mount the root file system from CD-ROM.
+
+################################################################################
+# Tset Sboot_ddb DDrop to the kernel debugger (DDB)
+
+ set boot_ddb
+
+ Instructs the kernel to start in the DDB debugger, rather than
+ proceeding to initialize when booted.
+
+################################################################################
+# Tset Sboot_dfltroot DUse default root file system
+
+ set boot_dfltroot
+
+ Instructs the kernel to mount the statically compiled-in root
+ file system.
+
+################################################################################
+# Tset Sboot_gdb DSelect gdb-remote mode for the kernel debugger
+
+ set boot_gdb
+
+ Selects gdb-remote mode for the kernel debugger by default.
+
+################################################################################
+# Tset Sboot_multicons DUse multiple consoles
+
+ set boot_multicons
+
+ Enables multiple console support in the kernel early on boot.
+ In a running system, console configuration can be manipulated
+ by the conscontrol(8) utility.
+
+################################################################################
+# Tset Sboot_mute DMute the console
+
+ set boot_mute
+
+ All console output is suppressed when console is muted.
+ In a running system, the state of console muting can be
+ manipulated by the conscontrol(8) utility.
+
+################################################################################
+# Tset Sboot_pause DPause after each line during device probing
+
+ set boot_pause
+
+ During the device probe, pause after each line is printed.
+
+################################################################################
+# Tset Sboot_serial DUse serial console
+
+ set boot_serial
+
+ Force the use of a serial console even when an internal console
+ is present.
+
+################################################################################
+# Tset Sboot_single DStart system in single-user mode
+
+ set boot_single
+
+ Prevents the kernel from initiating a multi-user startup; instead,
+ a single-user mode will be entered when the kernel has finished
+ device probes.
+
+################################################################################
+# Tset Sboot_verbose DVerbose boot messages
+
+ set boot_verbose
+
+ Setting this variable causes extra debugging information to be printed
+ by the kernel during the boot phase.
+
+################################################################################
+# Tset Sconsole DSet the current console
+
+ set console[=<value>]
+
+ Sets the current console. If <value> is omitted, a list of valid
+ consoles will be displayed.
+
+################################################################################
+# Tset Scurrdev DSet the current device
+
+ set currdev=<device>
+
+ Selects the default device. See lsdev for available devices.
+
+################################################################################
+# Tset Sinit_path DSet the list of init candidates
+
+ set init_path=<path>[:<path>...]
+
+ Sets the list of binaries which the kernel will try to run as initial
+ process.
+
+
+################################################################################
+# Tset Smodule_path DSet the module search path
+
+ set module_path=<path>[;<path>...]
+
+ Sets the list of directories which will be searched in for modules
+ named in a load command or implicitly required by a dependency. The
+ default module_path is "/boot/modules" with the kernel directory
+ prepended.
+
+################################################################################
+# Tset Sprompt DSet the command prompt
+
+ set prompt=<value>
+
+ The command prompt is displayed when the loader is waiting for input.
+ Variable substitution is performed on the prompt. The default
+ prompt can be set with:
+
+ set prompt=\${interpret}
+
+################################################################################
+# Tset Srootdev DSet the root filesystem
+
+ set rootdev=<path>
+
+ By default the value of $currdev is used to set the root filesystem
+ when the kernel is booted. This can be overridden by setting
+ $rootdev explicitly.
+
+################################################################################
+# Tset Stunables DSet kernel tunable values
+
+ Various kernel tunable parameters can be overridden by specifying new
+ values in the environment.
+
+ set kern.ipc.nmbclusters=<value>
+
+ Set the number of mbuf clusters to be allocated. The value
+ cannot be set below the default determined when the kernel
+ was compiled.
+
+ set kern.ipc.nsfbufs=<value> NSFBUFS
+
+ Set the number of sendfile buffers to be allocated. This
+ overrides the value determined when the kernel was compiled.
+
+ set vm.kmem_size=<value> VM_KMEM_SIZE
+
+ Sets the size of kernel memory (bytes). This overrides
+ the value determined when the kernel was compiled.
+
+ set machdep.disable_mtrrs=1
+
+ Disable the use of i686 MTRRs (i386 only)
+
+ set net.inet.tcp.tcbhashsize=<value> TCBHASHSIZE
+
+ Overrides the compile-time set value of TCBHASHSIZE or
+ the preset default of 512. Must be a power of 2.
+
+ hw.syscons.sc_no_suspend_vtswitch=<value>
+
+ Disable VT switching on suspend.
+
+ value is 0 (default) or non-zero to enable.
+
+ set hw.physmem=<value> MAXMEM (i386 only)
+
+ Limits the amount of physical memory space available to
+ the system to <value> bytes. <value> may have a k, M or G
+ suffix to indicate kilobytes, megabytes and gigabytes
+ respectively. Note that the current i386 architecture
+ limits this value to 4GB.
+
+ On systems where memory cannot be accurately probed,
+ this option provides a hint as to the actual size of
+ system memory (which will be tested before use).
+
+ set hw.{acpi,pci}.host_start_mem=<value>
+
+ Sets the lowest address that the pci code will assign
+ when it doesn't have other information about the address
+ to assign (like from a pci bridge). This is only useful
+ in older systems without a pci bridge. Also, it only
+ impacts devices that the BIOS doesn't assign to, typically
+ CardBus bridges. The default <value> is 0x80000000, but
+ some systems need values like 0xf0000000, 0xfc000000 or
+ 0xfe000000 may be suitable for older systems (the older
+ the system, the higher the number typically should be).
+
+ set hw.pci.enable_io_modes=<value>
+
+ Enable PCI resources which are left off by some BIOSes
+ or are not enabled correctly by the device driver.
+
+ value is 1 (default), but this may cause problems with
+ some peripherals. Set to 0 to disable.
+
+################################################################################
+# Tshow DShow the values of variables
+
+ show [<variable>]
+
+ Displays the value of <variable>, or all variables if not specified.
+
+################################################################################
+# Tinclude DRead commands from a script file
+
+ include <filename> [<filename> ...]
+
+ The entire contents of <filename> are read into memory before executing
+ commands, so it is safe to source a file from removable media.
+
+################################################################################
+# Tread DRead input from the terminal
+
+ read [-t <value>] [-p <prompt>] [<variable name>]
+
+ The read command reads a line of input from the terminal. If the
+ -t argument is specified, it will return nothing if no input has been
+ received after <value> seconds. (Any keypress will cancel the
+ timeout).
+
+ If -p is specified, <prompt> is printed before reading input. No
+ newline is emitted after the prompt.
+
+ If a variable name is supplied, the variable is set to the value read,
+ less any terminating newline.
+
+################################################################################
+# Tunload DRemove all modules from memory
+
+ unload
+
+ This command removes any kernel and all loaded modules from memory.
+
+################################################################################
+# Tunset DUnset a variable
+
+ unset <variable name>
+
+ If allowed, the named variable's value is discarded and the variable
+ is removed.
+
+################################################################################
diff --git a/usr/src/boot/sys/boot/common/install.c b/usr/src/boot/sys/boot/common/install.c
new file mode 100644
index 0000000000..36e7c6484d
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/install.c
@@ -0,0 +1,339 @@
+/*-
+ * Copyright (c) 2008-2014, Juniper Networks, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <net.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+extern struct in_addr rootip;
+extern struct in_addr servip;
+
+extern int pkgfs_init(const char *, struct fs_ops *);
+extern void pkgfs_cleanup(void);
+
+COMMAND_SET(install, "install", "install software package", command_install);
+
+static char *inst_kernel;
+static char **inst_modules;
+static char *inst_rootfs;
+
+static int
+setpath(char **what, char *val)
+{
+ char *path;
+ size_t len;
+ int rel;
+
+ len = strlen(val) + 1;
+ rel = (val[0] != '/') ? 1 : 0;
+ path = malloc(len + rel);
+ if (path == NULL)
+ return (ENOMEM);
+ path[0] = '/';
+ strcpy(path + rel, val);
+
+ *what = path;
+ return (0);
+}
+
+static int
+setmultipath(char ***what, char *val)
+{
+ char *s, *v;
+ int count, error, idx;
+
+ count = 0;
+ v = val;
+ do {
+ count++;
+ s = strchr(v, ',');
+ v = (s == NULL) ? NULL : s + 1;
+ } while (v != NULL);
+
+ *what = calloc(count + 1, sizeof(char *));
+ if (*what == NULL)
+ return (ENOMEM);
+
+ for (idx = 0; idx < count; idx++) {
+ s = strchr(val, ',');
+ if (s != NULL)
+ *s++ = '\0';
+ error = setpath(*what + idx, val);
+ if (error)
+ return (error);
+ val = s;
+ }
+
+ return (0);
+}
+
+static int
+read_metatags(int fd)
+{
+ char buf[1024];
+ char *p, *tag, *val;
+ ssize_t fsize;
+ int error;
+
+ fsize = read(fd, buf, sizeof(buf));
+ if (fsize == -1)
+ return (errno);
+
+ /*
+ * Assume that if we read a whole buffer worth of data, we
+ * haven't read the entire file. In other words, the buffer
+ * size must always be larger than the file size. That way
+ * we can append a '\0' and use standard string operations.
+ * Return an error if this is not possible.
+ */
+ if (fsize == sizeof(buf))
+ return (ENOMEM);
+
+ buf[fsize] = '\0';
+ error = 0;
+ tag = buf;
+ while (!error && *tag != '\0') {
+ val = strchr(tag, '=');
+ if (val == NULL) {
+ error = EINVAL;
+ break;
+ }
+ *val++ = '\0';
+ p = strchr(val, '\n');
+ if (p == NULL) {
+ error = EINVAL;
+ break;
+ }
+ *p++ = '\0';
+
+ if (strcmp(tag, "KERNEL") == 0)
+ error = setpath(&inst_kernel, val);
+ else if (strcmp(tag, "MODULES") == 0)
+ error = setmultipath(&inst_modules, val);
+ else if (strcmp(tag, "ROOTFS") == 0)
+ error = setpath(&inst_rootfs, val);
+
+ tag = p;
+ }
+
+ return (error);
+}
+
+static void
+cleanup(void)
+{
+ u_int i;
+
+ if (inst_kernel != NULL) {
+ free(inst_kernel);
+ inst_kernel = NULL;
+ }
+ if (inst_modules != NULL) {
+ i = 0;
+ while (inst_modules[i] != NULL)
+ free(inst_modules[i++]);
+ free(inst_modules);
+ inst_modules = NULL;
+ }
+ if (inst_rootfs != NULL) {
+ free(inst_rootfs);
+ inst_rootfs = NULL;
+ }
+ pkgfs_cleanup();
+}
+
+/*
+ * usage: install URL
+ * where: URL = (tftp|file)://[host]/<package>
+ */
+static int
+install(char *pkgname)
+{
+ static char buf[256];
+ struct fs_ops *proto;
+ struct preloaded_file *fp;
+ char *s, *currdev;
+ const char *devname;
+ int error, fd, i, local;
+
+ s = strstr(pkgname, "://");
+ if (s == NULL)
+ goto invalid_url;
+
+ i = s - pkgname;
+ if (i == 4 && !strncasecmp(pkgname, "tftp", i)) {
+ devname = "net0";
+ proto = &tftp_fsops;
+ local = 0;
+ } else if (i == 4 && !strncasecmp(pkgname, "file", i)) {
+ currdev = getenv("currdev");
+ if (currdev != NULL && strcmp(currdev, "pxe0:") == 0) {
+ devname = "pxe0";
+ proto = NULL;
+ } else {
+ devname = "disk1";
+ proto = &dosfs_fsops;
+ }
+ local = 1;
+ } else
+ goto invalid_url;
+
+ s += 3;
+ if (*s == '\0')
+ goto invalid_url;
+
+ if (*s != '/' ) {
+ if (local)
+ goto invalid_url;
+
+ pkgname = strchr(s, '/');
+ if (pkgname == NULL)
+ goto invalid_url;
+
+ *pkgname = '\0';
+ servip.s_addr = inet_addr(s);
+ if (servip.s_addr == htonl(INADDR_NONE))
+ goto invalid_url;
+
+ setenv("serverip", inet_ntoa(servip), 1);
+
+ *pkgname = '/';
+ } else
+ pkgname = s;
+
+ if (strlen(devname) + strlen(pkgname) + 2 > sizeof(buf)) {
+ command_errmsg = "package name too long";
+ return (CMD_ERROR);
+ }
+ sprintf(buf, "%s:%s", devname, pkgname);
+ setenv("install_package", buf, 1);
+
+ error = pkgfs_init(buf, proto);
+ if (error) {
+ command_errmsg = "cannot open package";
+ goto fail;
+ }
+
+ /*
+ * Point of no return: unload anything that may have been
+ * loaded and prune the environment from harmful variables.
+ */
+ unload();
+ unsetenv("vfs.root.mountfrom");
+
+ /*
+ * read the metatags file.
+ */
+ fd = open("/metatags", O_RDONLY);
+ if (fd != -1) {
+ error = read_metatags(fd);
+ close(fd);
+ if (error) {
+ command_errmsg = "cannot load metatags";
+ goto fail;
+ }
+ }
+
+ s = (inst_kernel == NULL) ? "/kernel" : inst_kernel;
+ error = mod_loadkld(s, 0, NULL);
+ if (error) {
+ command_errmsg = "cannot load kernel from package";
+ goto fail;
+ }
+
+ i = 0;
+ while (inst_modules != NULL && inst_modules[i] != NULL) {
+ error = mod_loadkld(inst_modules[i], 0, NULL);
+ if (error) {
+ command_errmsg = "cannot load module(s) from package";
+ goto fail;
+ }
+ i++;
+ }
+
+ s = (inst_rootfs == NULL) ? "/install.iso" : inst_rootfs;
+ if (file_loadraw(s, "mfs_root") == NULL) {
+ error = errno;
+ command_errmsg = "cannot load root file system";
+ goto fail;
+ }
+
+ cleanup();
+
+ fp = file_findfile(NULL, NULL);
+ if (fp != NULL)
+ file_formats[fp->f_loader]->l_exec(fp);
+ error = CMD_ERROR;
+ command_errmsg = "unable to start installation";
+
+ fail:
+ sprintf(buf, "%s (error %d)", command_errmsg, error);
+ cleanup();
+ unload();
+ exclusive_file_system = NULL;
+ command_errmsg = buf; /* buf is static. */
+ return (CMD_ERROR);
+
+ invalid_url:
+ command_errmsg = "invalid URL";
+ return (CMD_ERROR);
+}
+
+static int
+command_install(int argc, char *argv[])
+{
+ int argidx;
+
+ unsetenv("install_format");
+
+ argidx = 1;
+ while (1) {
+ if (argc == argidx) {
+ command_errmsg =
+ "usage: install [--format] <URL>";
+ return (CMD_ERROR);
+ }
+ if (!strcmp(argv[argidx], "--format")) {
+ setenv("install_format", "yes", 1);
+ argidx++;
+ continue;
+ }
+ break;
+ }
+
+ return (install(argv[argidx]));
+}
diff --git a/usr/src/boot/sys/boot/common/interp.c b/usr/src/boot/sys/boot/common/interp.c
new file mode 100644
index 0000000000..cadd764814
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/interp.c
@@ -0,0 +1,310 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Simple commandline interpreter, toplevel and misc.
+ *
+ * XXX may be obsoleted by BootFORTH or some other, better, interpreter.
+ */
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+
+#ifdef BOOT_FORTH
+#include "ficl.h"
+#define RETURN(x) ficlStackPushInteger(ficlVmGetDataStack(bf_vm),!x); return(x)
+
+extern ficlVm *bf_vm;
+#else
+#define RETURN(x) return(x)
+#endif
+
+#include "linenoise/linenoise.h"
+
+#define MAXARGS 20 /* maximum number of arguments allowed */
+
+static char *prompt(void);
+
+#ifndef BOOT_FORTH
+static int perform(int argc, char *argv[]);
+
+/*
+ * Perform the command
+ */
+int
+perform(int argc, char *argv[])
+{
+ int result;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+
+ if (argc < 1)
+ return(CMD_OK);
+
+ /* set return defaults; a successful command will override these */
+ command_errmsg = command_errbuf;
+ strcpy(command_errbuf, "no error message");
+ cmd = NULL;
+ result = CMD_ERROR;
+
+ /* search the command set for the command */
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name))
+ cmd = (*cmdp)->c_fn;
+ }
+ if (cmd != NULL) {
+ result = (cmd)(argc, argv);
+ } else {
+ command_errmsg = "unknown command";
+ }
+ RETURN(result);
+}
+#endif /* ! BOOT_FORTH */
+
+/*
+ * Interactive mode
+ */
+void
+interact(const char *rc)
+{
+ char *input = NULL;
+
+ bf_init((rc) ? "" : NULL);
+
+ if (rc == NULL) {
+ /* Read our default configuration. */
+ if (include("/boot/loader.rc") != CMD_OK)
+ include("/boot/boot.conf");
+ } else if (*rc != '\0')
+ include(rc);
+
+ printf("\n");
+
+ /*
+ * Before interacting, we might want to autoboot.
+ */
+ autoboot_maybe();
+
+ /*
+ * Not autobooting, go manual
+ */
+ printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
+ if (getenv("prompt") == NULL)
+ setenv("prompt", "${interpret}", 1);
+ if (getenv("interpret") == NULL)
+ setenv("interpret", "ok", 1);
+
+
+ while ((input = linenoise(prompt())) != NULL) {
+ bf_vm->sourceId.i = 0;
+ bf_run(input);
+ linenoiseHistoryAdd(input);
+ free(input);
+ }
+}
+
+/*
+ * Read commands from a file, then execute them.
+ *
+ * We store the commands in memory and close the source file so that the media
+ * holding it can safely go away while we are executing.
+ *
+ * Commands may be prefixed with '@' (so they aren't displayed) or '-' (so
+ * that the script won't stop if they fail).
+ */
+COMMAND_SET(include, "include", "read commands from a file", command_include);
+
+static int
+command_include(int argc, char *argv[])
+{
+ int i;
+ int res;
+ char **argvbuf;
+
+ /*
+ * Since argv is static, we need to save it here.
+ */
+ argvbuf = (char**) calloc((u_int)argc, sizeof(char*));
+ for (i = 0; i < argc; i++)
+ argvbuf[i] = strdup(argv[i]);
+
+ res=CMD_OK;
+ for (i = 1; (i < argc) && (res == CMD_OK); i++)
+ res = include(argvbuf[i]);
+
+ for (i = 0; i < argc; i++)
+ free(argvbuf[i]);
+ free(argvbuf);
+
+ return(res);
+}
+
+/*
+ * Header prepended to each line. The text immediately follows the header.
+ * We try to make this short in order to save memory -- the loader has
+ * limited memory available, and some of the forth files are very long.
+ */
+struct includeline
+{
+ struct includeline *next;
+ int line;
+ char text[0];
+};
+
+/*
+ * The PXE TFTP service allows opening exactly one connection at the time,
+ * so we need to read included file into memory, then process line by line
+ * as it may contain embedded include commands.
+ */
+int
+include(const char *filename)
+{
+ struct includeline *script, *se, *sp;
+ int res = CMD_OK;
+ int prevsrcid, fd, line;
+ char *cp, input[256]; /* big enough? */
+
+ if (((fd = open(filename, O_RDONLY)) == -1)) {
+ snprintf(command_errbuf, sizeof (command_errbuf), "can't open '%s': %s",
+ filename, strerror(errno));
+ return(CMD_ERROR);
+ }
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) >= 0) {
+ line++;
+ cp = input;
+ /* Allocate script line structure and copy line, flags */
+ if (*cp == '\0')
+ continue; /* ignore empty line, save memory */
+ if (cp[0] == '\\' && cp[1] == ' ')
+ continue; /* ignore comment */
+
+ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
+ /* On malloc failure (it happens!), free as much as possible and exit */
+ if (sp == NULL) {
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "file '%s' line %d: memory allocation failure - aborting",
+ filename, line);
+ close(fd);
+ return (CMD_ERROR);
+ }
+ strcpy(sp->text, cp);
+ sp->line = line;
+ sp->next = NULL;
+
+ if (script == NULL) {
+ script = sp;
+ } else {
+ se->next = sp;
+ }
+ se = sp;
+ }
+ close(fd);
+
+ /*
+ * Execute the script
+ */
+
+ prevsrcid = bf_vm->sourceId.i;
+ bf_vm->sourceId.i = fd+1; /* 0 is user input device */
+
+ res = CMD_OK;
+
+ for (sp = script; sp != NULL; sp = sp->next) {
+ res = bf_run(sp->text);
+ if (res != FICL_VM_STATUS_OUT_OF_TEXT) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "Error while including %s, in the line %d:\n%s",
+ filename, sp->line, sp->text);
+ res = CMD_ERROR;
+ break;
+ } else
+ res = CMD_OK;
+ }
+
+ bf_vm->sourceId.i = -1;
+ (void) bf_run("");
+ bf_vm->sourceId.i = prevsrcid;
+
+ while(script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+
+ return(res);
+}
+
+/*
+ * Emit the current prompt; use the same syntax as the parser
+ * for embedding environment variables.
+ */
+static char *
+prompt(void)
+{
+ static char promptbuf[20]; /* probably too large, but well... */
+ char *pr, *p, *cp, *ev;
+ int n = 0;
+
+ if ((cp = getenv("prompt")) == NULL)
+ cp = (char *)(uintptr_t)">";
+ pr = p = strdup(cp);
+
+ while (*p != 0) {
+ if ((*p == '$') && (*(p+1) == '{')) {
+ for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++)
+ ;
+ *cp = 0;
+ ev = getenv(p + 2);
+
+ if (ev != NULL)
+ n = sprintf(promptbuf+n, "%s", ev);
+ p = cp + 1;
+ continue;
+ }
+ promptbuf[n++] = *p;
+ p++;
+ }
+ if (promptbuf[n - 1] != ' ')
+ promptbuf[n++] = ' ';
+ promptbuf[n] = '\0';
+ free(pr);
+ return (promptbuf);
+}
diff --git a/usr/src/boot/sys/boot/common/interp_backslash.c b/usr/src/boot/sys/boot/common/interp_backslash.c
new file mode 100644
index 0000000000..3cbdd5b105
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/interp_backslash.c
@@ -0,0 +1,167 @@
+/*-
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 29 August 1998
+ *
+ * Routine for doing backslash elimination.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+
+#define DIGIT(x) (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
+
+/*
+ * backslash: Return malloc'd copy of str with all standard "backslash
+ * processing" done on it. Original can be free'd if desired.
+ */
+char *
+backslash(char *str)
+{
+ /*
+ * Remove backslashes from the strings. Turn \040 etc. into a single
+ * character (we allow eight bit values). Currently NUL is not
+ * allowed.
+ *
+ * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
+ *
+ */
+ char *new_str;
+ int seenbs = 0;
+ int i = 0;
+
+ if ((new_str = strdup(str)) == NULL)
+ return NULL;
+
+ while (*str) {
+ if (seenbs) {
+ seenbs = 0;
+ switch (*str) {
+ case '\\':
+ new_str[i++] = '\\';
+ str++;
+ break;
+
+ /* preserve backslashed quotes, dollar signs */
+ case '\'':
+ case '"':
+ case '$':
+ new_str[i++] = '\\';
+ new_str[i++] = *str++;
+ break;
+
+ case 'b':
+ new_str[i++] = '\b';
+ str++;
+ break;
+
+ case 'f':
+ new_str[i++] = '\f';
+ str++;
+ break;
+
+ case 'r':
+ new_str[i++] = '\r';
+ str++;
+ break;
+
+ case 'n':
+ new_str[i++] = '\n';
+ str++;
+ break;
+
+ case 's':
+ new_str[i++] = ' ';
+ str++;
+ break;
+
+ case 't':
+ new_str[i++] = '\t';
+ str++;
+ break;
+
+ case 'v':
+ new_str[i++] = '\13';
+ str++;
+ break;
+
+ case 'z':
+ str++;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ char val;
+
+ /* Three digit octal constant? */
+ if (*str >= '0' && *str <= '3' &&
+ *(str + 1) >= '0' && *(str + 1) <= '7' &&
+ *(str + 2) >= '0' && *(str + 2) <= '7') {
+
+ val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) +
+ DIGIT(*(str + 2));
+
+ /* Allow null value if user really wants to shoot
+ at feet, but beware! */
+ new_str[i++] = val;
+ str += 3;
+ break;
+ }
+
+ /* One or two digit hex constant?
+ * If two are there they will both be taken.
+ * Use \z to split them up if this is not wanted.
+ */
+ if (*str == '0' &&
+ (*(str + 1) == 'x' || *(str + 1) == 'X') &&
+ isxdigit(*(str + 2))) {
+ val = DIGIT(*(str + 2));
+ if (isxdigit(*(str + 3))) {
+ val = (val << 4) + DIGIT(*(str + 3));
+ str += 4;
+ }
+ else
+ str += 3;
+ /* Yep, allow null value here too */
+ new_str[i++] = val;
+ break;
+ }
+ }
+ break;
+
+ default:
+ new_str[i++] = *str++;
+ break;
+ }
+ }
+ else {
+ if (*str == '\\') {
+ seenbs = 1;
+ str++;
+ }
+ else
+ new_str[i++] = *str++;
+ }
+ }
+
+ if (seenbs) {
+ /*
+ * The final character was a '\'. Put it in as a single backslash.
+ */
+ new_str[i++] = '\\';
+ }
+ new_str[i] = '\0';
+ return new_str;
+}
diff --git a/usr/src/boot/sys/boot/common/interp_forth.c b/usr/src/boot/sys/boot/common/interp_forth.c
new file mode 100644
index 0000000000..f241f405d5
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/interp_forth.c
@@ -0,0 +1,370 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h> /* to pick up __FreeBSD_version */
+#include <string.h>
+#include <stand.h>
+#include "bootstrap.h"
+#include "ficl.h"
+
+extern char bootprog_rev[];
+
+/* #define BFORTH_DEBUG */
+
+#ifdef BFORTH_DEBUG
+# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+# define DEBUG(fmt, args...)
+#endif
+
+/*
+ * Eventually, all builtin commands throw codes must be defined
+ * elsewhere, possibly bootstrap.h. For now, just this code, used
+ * just in this file, it is getting defined.
+ */
+#define BF_PARSE 100
+
+/*
+ * FreeBSD loader default dictionary cells
+ */
+#ifndef BF_DICTSIZE
+#define BF_DICTSIZE 30000
+#endif
+
+/*
+ * BootForth Interface to Ficl Forth interpreter.
+ */
+
+ficlSystemInformation *fsi;
+ficlSystem *bf_sys;
+ficlVm *bf_vm;
+ficlWord *pInterp;
+
+/*
+ * Shim for taking commands from BF and passing them out to 'standard'
+ * argv/argc command functions.
+ */
+static void
+bf_command(ficlVm *vm)
+{
+ char *name, *line, *tail, *cp;
+ size_t len;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+ int nstrings, i;
+ int argc, result;
+ char **argv;
+
+ /* Get the name of the current word */
+ name = vm->runningWord->name;
+
+ /* Find our command structure */
+ cmd = NULL;
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name))
+ cmd = (*cmdp)->c_fn;
+ }
+ if (cmd == NULL)
+ panic("callout for unknown command '%s'", name);
+
+ /* Check whether we have been compiled or are being interpreted */
+ if (ficlStackPopInteger(ficlVmGetDataStack(vm))) {
+ /*
+ * Get parameters from stack, in the format:
+ * an un ... a2 u2 a1 u1 n --
+ * Where n is the number of strings, a/u are pairs of
+ * address/size for strings, and they will be concatenated
+ * in LIFO order.
+ */
+ nstrings = ficlStackPopInteger(ficlVmGetDataStack(vm));
+ for (i = 0, len = 0; i < nstrings; i++)
+ len += ficlStackFetch(ficlVmGetDataStack(vm), i * 2).i + 1;
+ line = malloc(strlen(name) + len + 1);
+ strcpy(line, name);
+
+ if (nstrings)
+ for (i = 0; i < nstrings; i++) {
+ len = ficlStackPopInteger(ficlVmGetDataStack(vm));
+ cp = ficlStackPopPointer(ficlVmGetDataStack(vm));
+ strcat(line, " ");
+ strncat(line, cp, len);
+ }
+ } else {
+ /* Get remainder of invocation */
+ tail = ficlVmGetInBuf(vm);
+
+ for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++)
+ ;
+
+ line = malloc(strlen(name) + len + 2);
+ strcpy(line, name);
+ if (len > 0) {
+ strcat(line, " ");
+ strncat(line, tail, len);
+ ficlVmUpdateTib(vm, tail + len);
+ }
+ }
+ DEBUG("cmd '%s'", line);
+
+ command_errmsg = command_errbuf;
+ command_errbuf[0] = 0;
+ if (!parse(&argc, &argv, line)) {
+ result = (cmd)(argc, argv);
+ free(argv);
+ } else {
+ result=BF_PARSE;
+ }
+
+ switch (result) {
+ case CMD_CRIT:
+ printf("%s\n", command_errmsg);
+ break;
+ case CMD_FATAL:
+ panic("%s\n", command_errmsg);
+ }
+
+ free(line);
+ /*
+ * If there was error during nested ficlExec(), we may no longer have
+ * valid environment to return. Throw all exceptions from here.
+ */
+ if (result != CMD_OK)
+ ficlVmThrow(vm, result);
+
+ /* This is going to be thrown!!! */
+ ficlStackPushInteger(ficlVmGetDataStack(vm),result);
+}
+
+/*
+ * Replace a word definition (a builtin command) with another
+ * one that:
+ *
+ * - Throw error results instead of returning them on the stack
+ * - Pass a flag indicating whether the word was compiled or is
+ * being interpreted.
+ *
+ * There is one major problem with builtins that cannot be overcome
+ * in anyway, except by outlawing it. We want builtins to behave
+ * differently depending on whether they have been compiled or they
+ * are being interpreted. Notice that this is *not* the interpreter's
+ * current state. For example:
+ *
+ * : example ls ; immediate
+ * : problem example ; \ "ls" gets executed while compiling
+ * example \ "ls" gets executed while interpreting
+ *
+ * Notice that, though the current state is different in the two
+ * invocations of "example", in both cases "ls" has been
+ * *compiled in*, which is what we really want.
+ *
+ * The problem arises when you tick the builtin. For example:
+ *
+ * : example-1 ['] ls postpone literal ; immediate
+ * : example-2 example-1 execute ; immediate
+ * : problem example-2 ;
+ * example-2
+ *
+ * We have no way, when we get EXECUTEd, of knowing what our behavior
+ * should be. Thus, our only alternative is to "outlaw" this. See RFI
+ * 0007, and ANS Forth Standard's appendix D, item 6.7 for a related
+ * problem, concerning compile semantics.
+ *
+ * The problem is compounded by the fact that "' builtin CATCH" is valid
+ * and desirable. The only solution is to create an intermediary word.
+ * For example:
+ *
+ * : my-ls ls ;
+ * : example ['] my-ls catch ;
+ *
+ * So, with the below implementation, here is a summary of the behavior
+ * of builtins:
+ *
+ * ls -l \ "interpret" behavior, ie,
+ * \ takes parameters from TIB
+ * : ex-1 s" -l" 1 ls ; \ "compile" behavior, ie,
+ * \ takes parameters from the stack
+ * : ex-2 ['] ls catch ; immediate \ undefined behavior
+ * : ex-3 ['] ls catch ; \ undefined behavior
+ * ex-2 ex-3 \ "interpret" behavior,
+ * \ catch works
+ * : ex-4 ex-2 ; \ "compile" behavior,
+ * \ catch does not work
+ * : ex-5 ex-3 ; immediate \ same as ex-2
+ * : ex-6 ex-3 ; \ same as ex-3
+ * : ex-7 ['] ex-1 catch ; \ "compile" behavior,
+ * \ catch works
+ * : ex-8 postpone ls ; immediate \ same as ex-2
+ * : ex-9 postpone ls ; \ same as ex-3
+ *
+ * As the definition below is particularly tricky, and it's side effects
+ * must be well understood by those playing with it, I'll be heavy on
+ * the comments.
+ *
+ * (if you edit this definition, pay attention to trailing spaces after
+ * each word -- I warned you! :-) )
+ */
+#define BUILTIN_CONSTRUCTOR \
+": builtin: " \
+ ">in @ " /* save the tib index pointer */ \
+ "' " /* get next word's xt */ \
+ "swap >in ! " /* point again to next word */ \
+ "create " /* create a new definition of the next word */ \
+ ", " /* save previous definition's xt */ \
+ "immediate " /* make the new definition an immediate word */ \
+ \
+ "does> " /* Now, the *new* definition will: */ \
+ "state @ if " /* if in compiling state: */ \
+ "1 postpone literal " /* pass 1 flag to indicate compile */ \
+ "@ compile, " /* compile in previous definition */ \
+ "postpone throw " /* throw stack-returned result */ \
+ "else " /* if in interpreting state: */ \
+ "0 swap " /* pass 0 flag to indicate interpret */ \
+ "@ execute " /* call previous definition */ \
+ "throw " /* throw stack-returned result */ \
+ "then ; "
+
+/*
+ * Initialise the Forth interpreter, create all our commands as words.
+ */
+void
+bf_init(char *rc)
+{
+ struct bootblk_command **cmdp;
+ char create_buf[41]; /* 31 characters-long builtins */
+ int fd, rv;
+ ficlDictionary *dict;
+ ficlDictionary *env;
+
+ fsi = malloc(sizeof(ficlSystemInformation));
+ ficlSystemInformationInitialize(fsi);
+ fsi->dictionarySize = BF_DICTSIZE;
+
+ bf_sys = ficlSystemCreate(fsi);
+ bf_vm = ficlSystemCreateVm(bf_sys);
+
+ /* Put all private definitions in a "builtins" vocabulary */
+ rv = ficlVmEvaluate(bf_vm, "vocabulary builtins also builtins definitions");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+
+ /* Builtin constructor word */
+ rv = ficlVmEvaluate(bf_vm, BUILTIN_CONSTRUCTOR);
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+
+ /* make all commands appear as Forth words */
+ dict = ficlSystemGetDictionary(bf_sys);
+ SET_FOREACH(cmdp, Xcommand_set) {
+ ficlDictionaryAppendPrimitive(dict, (char *)(*cmdp)->c_name,
+ bf_command, FICL_WORD_DEFAULT);
+ rv = ficlVmEvaluate(bf_vm, "forth definitions builtins");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
+ rv = ficlVmEvaluate(bf_vm, create_buf);
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ rv = ficlVmEvaluate(bf_vm, "builtins definitions");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ }
+ rv = ficlVmEvaluate(bf_vm, "only forth definitions");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+
+ /*
+ * Export some version numbers so that code can detect the loader/host
+ * version
+ */
+ env = ficlSystemGetEnvironment(bf_sys);
+ ficlDictionarySetConstant(env, "loader_version",
+ (bootprog_rev[0] - '0') * 10 + (bootprog_rev[2] - '0'));
+
+ pInterp = ficlSystemLookup(bf_sys, "interpret");
+
+ /* try to load and run init file if present */
+ if (rc == NULL)
+ rc = "/boot/forth/boot.4th";
+ if (*rc != '\0') {
+ fd = open(rc, O_RDONLY);
+ if (fd != -1) {
+ (void)ficlExecFD(bf_vm, fd);
+ close(fd);
+ }
+ }
+
+ /* Do this again, so that interpret can be redefined. */
+ pInterp = ficlSystemLookup(bf_sys, "interpret");
+}
+
+/*
+ * Feed a line of user input to the Forth interpreter
+ */
+int
+bf_run(char *line)
+{
+ int result;
+ ficlString s;
+
+ FICL_STRING_SET_FROM_CSTRING(s, line);
+ result = ficlVmExecuteString(bf_vm, s);
+
+ DEBUG("ficlExec '%s' = %d", line, result);
+ switch (result) {
+ case FICL_VM_STATUS_OUT_OF_TEXT:
+ case FICL_VM_STATUS_ABORTQ:
+ case FICL_VM_STATUS_QUIT:
+ case FICL_VM_STATUS_ERROR_EXIT:
+ break;
+ case FICL_VM_STATUS_USER_EXIT:
+ printf("No where to leave to!\n");
+ break;
+ case FICL_VM_STATUS_ABORT:
+ printf("Aborted!\n");
+ break;
+ case BF_PARSE:
+ printf("Parse error!\n");
+ break;
+ default:
+ /* Hopefully, all other codes filled this buffer */
+ printf("%s\n", command_errmsg);
+ }
+
+ /* bye is same as reboot and will behave depending on platform */
+ if (result == FICL_VM_STATUS_USER_EXIT)
+ bf_run("reboot");
+ setenv("interpret", bf_vm->state ? "" : "ok", 1);
+
+ return result;
+}
diff --git a/usr/src/boot/sys/boot/common/interp_parse.c b/usr/src/boot/sys/boot/common/interp_parse.c
new file mode 100644
index 0000000000..64ddadea21
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/interp_parse.c
@@ -0,0 +1,224 @@
+/*-
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 29 August 1998
+ *
+ * The meat of the simple parser.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+
+static void clean(void);
+static int insert(int *argcp, char *buf);
+static char *variable_lookup(char *name);
+
+#define PARSE_BUFSIZE 1024 /* maximum size of one element */
+#define MAXARGS 20 /* maximum number of elements */
+static char *args[MAXARGS];
+
+/*
+ * parse: accept a string of input and "parse" it for backslash
+ * substitutions and environment variable expansions (${var}),
+ * returning an argc/argv style vector of whitespace separated
+ * arguments. Returns 0 on success, 1 on failure (ok, ok, so I
+ * wimped-out on the error codes! :).
+ *
+ * Note that the argv array returned must be freed by the caller, but
+ * we own the space allocated for arguments and will free that on next
+ * invocation. This allows argv consumers to modify the array if
+ * required.
+ *
+ * NB: environment variables that expand to more than one whitespace
+ * separated token will be returned as a single argv[] element, not
+ * split in turn. Expanded text is also immune to further backslash
+ * elimination or expansion since this is a one-pass, non-recursive
+ * parser. You didn't specify more than this so if you want more, ask
+ * me. - jkh
+ */
+
+#define PARSE_FAIL(expr) \
+if (expr) { \
+ printf("fail at line %d\n", __LINE__); \
+ clean(); \
+ free(copy); \
+ free(buf); \
+ return 1; \
+}
+
+/* Accept the usual delimiters for a variable, returning counterpart */
+static char
+isdelim(int ch)
+{
+ if (ch == '{')
+ return '}';
+ else if (ch == '(')
+ return ')';
+ return '\0';
+}
+
+static int
+isquote(int ch)
+{
+ return (ch == '\'');
+}
+
+static int
+isdquote(int ch)
+{
+ return (ch == '"');
+}
+
+int
+parse(int *argc, char ***argv, char *str)
+{
+ int ac;
+ char *val, *p, *q, *copy = NULL;
+ size_t i = 0;
+ char token, tmp, quote, dquote, *buf;
+ enum { STR, VAR, WHITE } state;
+
+ ac = *argc = 0;
+ dquote = quote = 0;
+ if (!str || (p = copy = backslash(str)) == NULL)
+ return 1;
+
+ /* Initialize vector and state */
+ clean();
+ state = STR;
+ buf = (char *)malloc(PARSE_BUFSIZE);
+ token = 0;
+
+ /* And awaaaaaaaaay we go! */
+ while (*p) {
+ switch (state) {
+ case STR:
+ if ((*p == '\\') && p[1]) {
+ p++;
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else if (isquote(*p)) {
+ quote = quote ? 0 : *p;
+ if (dquote) { /* keep quote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else {
+ ++p;
+ }
+ } else if (isdquote(*p)) {
+ dquote = dquote ? 0 : *p;
+ if (quote) { /* keep dquote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else {
+ ++p;
+ }
+ } else if (isspace(*p) && !quote && !dquote) {
+ state = WHITE;
+ if (i) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ i = 0;
+ }
+ ++p;
+ } else if (*p == '$' && !quote) {
+ token = isdelim(*(p + 1));
+ if (token)
+ p += 2;
+ else
+ ++p;
+ state = VAR;
+ } else {
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ }
+ break;
+
+ case WHITE:
+ if (isspace(*p))
+ ++p;
+ else
+ state = STR;
+ break;
+
+ case VAR:
+ if (token) {
+ PARSE_FAIL((q = strchr(p, token)) == NULL);
+ } else {
+ q = p;
+ while (*q && !isspace(*q))
+ ++q;
+ }
+ tmp = *q;
+ *q = '\0';
+ if ((val = variable_lookup(p)) != NULL) {
+ size_t len = strlen(val);
+
+ strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
+ i += min(len, PARSE_BUFSIZE - 1);
+ }
+ *q = tmp; /* restore value */
+ p = q + (token ? 1 : 0);
+ state = STR;
+ break;
+ }
+ }
+ /* missing terminating ' or " */
+ PARSE_FAIL(quote || dquote);
+ /* If at end of token, add it */
+ if (i && state == STR) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ }
+ args[ac] = NULL;
+ *argc = ac;
+ *argv = (char **)malloc((sizeof(char *) * ac + 1));
+ bcopy(args, *argv, sizeof(char *) * ac + 1);
+ free(buf);
+ free(copy);
+ return 0;
+}
+
+#define MAXARGS 20
+
+/* Clean vector space */
+static void
+clean(void)
+{
+ int i;
+
+ for (i = 0; i < MAXARGS; i++) {
+ if (args[i] != NULL) {
+ free(args[i]);
+ args[i] = NULL;
+ }
+ }
+}
+
+static int
+insert(int *argcp, char *buf)
+{
+ if (*argcp >= MAXARGS)
+ return 1;
+ args[(*argcp)++] = strdup(buf);
+ return 0;
+}
+
+static char *
+variable_lookup(char *name)
+{
+ /* XXX search "special variable" space first? */
+ return (char *)getenv(name);
+}
diff --git a/usr/src/boot/sys/boot/common/isapnp.c b/usr/src/boot/sys/boot/common/isapnp.c
new file mode 100644
index 0000000000..a8efb28c7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/isapnp.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1998, Michael Smith
+ * Copyright (c) 1996, Sujal M. Patel
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Machine-independant ISA PnP enumerator implementing a subset of the
+ * ISA PnP specification.
+ */
+#include <stand.h>
+#include <string.h>
+#include <bootstrap.h>
+#include <isapnp.h>
+
+#define inb(x) (archsw.arch_isainb((x)))
+#define outb(x,y) (archsw.arch_isaoutb((x),(y)))
+
+static void isapnp_write(int d, int r);
+static void isapnp_send_Initiation_LFSR(void);
+static int isapnp_get_serial(u_int8_t *p);
+static int isapnp_isolation_protocol(void);
+static void isapnp_enumerate(void);
+
+/* PnP read data port */
+int isapnp_readport = 0;
+
+#define _PNP_ID_LEN 9
+
+struct pnphandler isapnphandler =
+{
+ "ISA bus",
+ isapnp_enumerate
+};
+
+static void
+isapnp_write(int d, int r)
+{
+ outb (_PNP_ADDRESS, d);
+ outb (_PNP_WRITE_DATA, r);
+}
+
+/*
+ * Send Initiation LFSR as described in "Plug and Play ISA Specification",
+ * Intel May 94.
+ */
+static void
+isapnp_send_Initiation_LFSR(void)
+{
+ int cur, i;
+
+ /* Reset the LSFR */
+ outb(_PNP_ADDRESS, 0);
+ outb(_PNP_ADDRESS, 0); /* yes, we do need it twice! */
+
+ cur = 0x6a;
+ outb(_PNP_ADDRESS, cur);
+
+ for (i = 1; i < 32; i++) {
+ cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
+ outb(_PNP_ADDRESS, cur);
+ }
+}
+
+/*
+ * Get the device's serial number. Returns 1 if the serial is valid.
+ */
+static int
+isapnp_get_serial(u_int8_t *data)
+{
+ int i, bit, valid = 0, sum = 0x6a;
+
+ bzero(data, _PNP_ID_LEN);
+ outb(_PNP_ADDRESS, SERIAL_ISOLATION);
+ for (i = 0; i < 72; i++) {
+ bit = inb(isapnp_readport) == 0x55;
+ delay(250); /* Delay 250 usec */
+
+ /* Can't Short Circuit the next evaluation, so 'and' is last */
+ bit = (inb(isapnp_readport) == 0xaa) && bit;
+ delay(250); /* Delay 250 usec */
+
+ valid = valid || bit;
+
+ if (i < 64)
+ sum = (sum >> 1) |
+ (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);
+
+ data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
+ }
+
+ valid = valid && (data[8] == sum);
+
+ return valid;
+}
+
+/*
+ * Fills the buffer with resource info from the device.
+ * Returns nonzero if the device fails to report
+ */
+static int
+isapnp_get_resource_info(u_int8_t *buffer, int len)
+{
+ int i, j;
+ u_char temp;
+
+ for (i = 0; i < len; i++) {
+ outb(_PNP_ADDRESS, STATUS);
+ for (j = 0; j < 100; j++) {
+ if ((inb(isapnp_readport)) & 0x1)
+ break;
+ delay(1);
+ }
+ if (j == 100) {
+ printf("PnP device failed to report resource data\n");
+ return(1);
+ }
+ outb(_PNP_ADDRESS, RESOURCE_DATA);
+ temp = inb(isapnp_readport);
+ if (buffer != NULL)
+ buffer[i] = temp;
+ }
+ return(0);
+}
+
+/*
+ * Scan Resource Data for useful information.
+ *
+ * We scan the resource data for compatible device IDs and
+ * identifier strings; we only take the first identifier string
+ * and assume it's for the card as a whole.
+ *
+ * Returns 0 if the scan completed OK, nonzero on error.
+ */
+static int
+isapnp_scan_resdata(struct pnpinfo *pi)
+{
+ u_char tag, resinfo[8];
+ u_int limit;
+ size_t large_len;
+ u_char *str;
+
+ limit = 1000;
+ while ((limit-- > 0) && !isapnp_get_resource_info(&tag, 1)) {
+ if (PNP_RES_TYPE(tag) == 0) {
+ /* Small resource */
+ switch (PNP_SRES_NUM(tag)) {
+
+ case COMP_DEVICE_ID:
+ /* Got a compatible device id resource */
+ if (isapnp_get_resource_info(resinfo, PNP_SRES_LEN(tag)))
+ return(1);
+ pnp_addident(pi, pnp_eisaformat(resinfo));
+
+ case END_TAG:
+ return(0);
+ break;
+
+ default:
+ /* Skip this resource */
+ if (isapnp_get_resource_info(NULL, PNP_SRES_LEN(tag)))
+ return(1);
+ break;
+ }
+ } else {
+ /* Large resource */
+ if (isapnp_get_resource_info(resinfo, 2))
+ return(1);
+
+ large_len = resinfo[1];
+ large_len = (large_len << 8) + resinfo[0];
+
+ switch(PNP_LRES_NUM(tag)) {
+
+ case ID_STRING_ANSI:
+ str = malloc(large_len + 1);
+ if (isapnp_get_resource_info(str, (ssize_t)large_len)) {
+ free(str);
+ return(1);
+ }
+ str[large_len] = 0;
+ if (pi->pi_desc == NULL) {
+ pi->pi_desc = (char *)str;
+ } else {
+ free(str);
+ }
+ break;
+
+ default:
+ /* Large resource, skip it */
+ if (isapnp_get_resource_info(NULL, (ssize_t)large_len))
+ return(1);
+ }
+ }
+ }
+ return(1);
+}
+
+/*
+ * Run the isolation protocol. Upon exiting, all cards are aware that
+ * they should use isapnp_readport as the READ_DATA port.
+ */
+static int
+isapnp_isolation_protocol(void)
+{
+ int csn;
+ struct pnpinfo *pi;
+ u_int8_t cardid[_PNP_ID_LEN];
+ int ndevs;
+
+ isapnp_send_Initiation_LFSR();
+ ndevs = 0;
+
+ isapnp_write(CONFIG_CONTROL, 0x04); /* Reset CSN for All Cards */
+
+ for (csn = 1; ; csn++) {
+ /* Wake up cards without a CSN (ie. all of them) */
+ isapnp_write(WAKE, 0);
+ isapnp_write(SET_RD_DATA, (isapnp_readport >> 2));
+ outb(_PNP_ADDRESS, SERIAL_ISOLATION);
+ delay(1000); /* Delay 1 msec */
+
+ if (isapnp_get_serial(cardid)) {
+ isapnp_write(SET_CSN, csn);
+ pi = pnp_allocinfo();
+ ndevs++;
+ pnp_addident(pi, pnp_eisaformat(cardid));
+ /* scan the card obtaining all the identifiers it holds */
+ if (isapnp_scan_resdata(pi)) {
+ pnp_freeinfo(pi); /* error getting data, ignore */
+ } else {
+ pnp_addinfo(pi);
+ }
+ } else {
+ break;
+ }
+ }
+ /* Move all cards to wait-for-key state */
+ while (--csn > 0) {
+ isapnp_send_Initiation_LFSR();
+ isapnp_write(WAKE, csn);
+ isapnp_write(CONFIG_CONTROL, 0x02);
+ delay(1000); /* XXX is it really necessary ? */
+ csn--;
+ }
+ return(ndevs);
+}
+
+/*
+ * Locate ISA-PnP devices and populate the supplied list.
+ */
+static void
+isapnp_enumerate(void)
+{
+ int pnp_rd_port;
+
+ /* Check for I/O port access */
+ if ((archsw.arch_isainb == NULL) || (archsw.arch_isaoutb == NULL))
+ return;
+
+ /*
+ * Validate a possibly-suggested read port value. If the autoscan failed
+ * last time, this will return us to autoscan mode again.
+ */
+ if ((isapnp_readport > 0) &&
+ (((isapnp_readport < 0x203) ||
+ (isapnp_readport > 0x3ff) ||
+ (isapnp_readport & 0x3) != 0x3)))
+ /* invalid, go look for ourselves */
+ isapnp_readport = 0;
+
+ if (isapnp_readport < 0) {
+ /* someone is telling us there is no ISA in the system */
+ return;
+
+ } else if (isapnp_readport > 0) {
+ /* Someone has told us where the port is/should be, or we found one last time */
+ isapnp_isolation_protocol();
+
+ } else {
+ /* No clues, look for it ourselves */
+ for (pnp_rd_port = 0x80; pnp_rd_port < 0xff; pnp_rd_port += 0x10) {
+ /* Look for something, quit when we find it */
+ isapnp_readport = (pnp_rd_port << 2) | 0x3;
+ if (isapnp_isolation_protocol() > 0)
+ break;
+ }
+ }
+}
diff --git a/usr/src/boot/sys/boot/common/isapnp.h b/usr/src/boot/sys/boot/common/isapnp.h
new file mode 100644
index 0000000000..0f9956c4f1
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/isapnp.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 1996, Sujal M. Patel
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Sujal M. Patel
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _I386_ISA_PNP_H_
+#define _I386_ISA_PNP_H_
+
+/* Maximum Number of PnP Devices. 8 should be plenty */
+#define MAX_PNP_CARDS 8
+/*
+ * the following is the maximum number of PnP Logical devices that
+ * userconfig can handle.
+ */
+#define MAX_PNP_LDN 20
+
+/* Static ports to access PnP state machine */
+#ifndef _KERNEL
+#ifdef PC98
+/* pnp.h is included from pnpinfo.c. */
+#define _PNP_ADDRESS 0x259
+#define _PNP_WRITE_DATA 0xa59
+#else
+#define _PNP_ADDRESS 0x279
+#define _PNP_WRITE_DATA 0xa79
+#endif
+#endif
+
+/* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
+#define SET_RD_DATA 0x00
+ /***
+ Writing to this location modifies the address of the port used for
+ reading from the Plug and Play ISA cards. Bits[7:0] become I/O
+ read port address bits[9:2]. Reads from this register are ignored.
+ ***/
+
+#define SERIAL_ISOLATION 0x01
+ /***
+ A read to this register causes a Plug and Play cards in the Isolation
+ state to compare one bit of the boards ID.
+ This register is read only.
+ ***/
+
+#define CONFIG_CONTROL 0x02
+ /***
+ Bit[2] Reset CSN to 0
+ Bit[1] Return to the Wait for Key state
+ Bit[0] Reset all logical devices and restore configuration
+ registers to their power-up values.
+
+ A write to bit[0] of this register performs a reset function on
+ all logical devices. This resets the contents of configuration
+ registers to their default state. All card's logical devices
+ enter their default state and the CSN is preserved.
+
+ A write to bit[1] of this register causes all cards to enter the
+ Wait for Key state but all CSNs are preserved and logical devices
+ are not affected.
+
+ A write to bit[2] of this register causes all cards to reset their
+ CSN to zero .
+
+ This register is write-only. The values are not sticky, that is,
+ hardware will automatically clear them and there is no need for
+ software to clear the bits.
+ ***/
+
+#define WAKE 0x03
+ /***
+ A write to this port will cause all cards that have a CSN that
+ matches the write data[7:0] to go from the Sleep state to the either
+ the Isolation state if the write data for this command is zero or
+ the Config state if the write data is not zero. Additionally, the
+ pointer to the byte-serial device is reset. This register is
+ writeonly.
+ ***/
+
+#define RESOURCE_DATA 0x04
+ /***
+ A read from this address reads the next byte of resource information.
+ The Status register must be polled until bit[0] is set before this
+ register may be read. This register is read only.
+ ***/
+
+#define STATUS 0x05
+ /***
+ Bit[0] when set indicates it is okay to read the next data byte
+ from the Resource Data register. This register is readonly.
+ ***/
+
+#define SET_CSN 0x06
+ /***
+ A write to this port sets a card's CSN. The CSN is a value uniquely
+ assigned to each ISA card after the serial identification process
+ so that each card may be individually selected during a Wake[CSN]
+ command. This register is read/write.
+ ***/
+
+#define SET_LDN 0x07
+ /***
+ Selects the current logical device. All reads and writes of memory,
+ I/O, interrupt and DMA configuration information access the registers
+ of the logical device written here. In addition, the I/O Range
+ Check and Activate commands operate only on the selected logical
+ device. This register is read/write. If a card has only 1 logical
+ device, this location should be a read-only value of 0x00.
+ ***/
+
+/*** addresses 0x08 - 0x1F Card Level Reserved for future use ***/
+/*** addresses 0x20 - 0x2F Card Level, Vendor Defined ***/
+
+#define ACTIVATE 0x30
+ /***
+ For each logical device there is one activate register that controls
+ whether or not the logical device is active on the ISA bus. Bit[0],
+ if set, activates the logical device. Bits[7:1] are reserved and
+ must return 0 on reads. This is a read/write register. Before a
+ logical device is activated, I/O range check must be disabled.
+ ***/
+
+#define IO_RANGE_CHECK 0x31
+ /***
+ This register is used to perform a conflict check on the I/O port
+ range programmed for use by a logical device.
+
+ Bit[7:2] Reserved and must return 0 on reads
+ Bit[1] Enable I/O Range check, if set then I/O Range Check
+ is enabled. I/O range check is only valid when the logical
+ device is inactive.
+
+ Bit[0], if set, forces the logical device to respond to I/O reads
+ of the logical device's assigned I/O range with a 0x55 when I/O
+ range check is in operation. If clear, the logical device drives
+ 0xAA. This register is read/write.
+ ***/
+
+/*** addr 0x32 - 0x37 Logical Device Control Reserved for future use ***/
+/*** addr 0x38 - 0x3F Logical Device Control Vendor Define ***/
+
+#define MEM_CONFIG 0x40
+ /***
+ Four memory resource registers per range, four ranges.
+ Fill with 0 if no ranges are enabled.
+
+ Offset 0: RW Memory base address bits[23:16]
+ Offset 1: RW Memory base address bits[15:8]
+ Offset 2: Memory control
+ Bit[1] specifies 8/16-bit control. This bit is set to indicate
+ 16-bit memory, and cleared to indicate 8-bit memory.
+ Bit[0], if cleared, indicates the next field can be used as a range
+ length for decode (implies range length and base alignment of memory
+ descriptor are equal).
+ Bit[0], if set, indicates the next field is the upper limit for
+ the address. - - Bit[0] is read-only.
+ Offset 3: RW upper limit or range len, bits[23:16]
+ Offset 4: RW upper limit or range len, bits[15:8]
+ Offset 5-Offset 7: filler, unused.
+ ***/
+
+#define IO_CONFIG_BASE 0x60
+ /***
+ Eight ranges, two bytes per range.
+ Offset 0: I/O port base address bits[15:8]
+ Offset 1: I/O port base address bits[7:0]
+ ***/
+
+#define IRQ_CONFIG 0x70
+ /***
+ Two entries, two bytes per entry.
+ Offset 0: RW interrupt level (1..15, 0=unused).
+ Offset 1: Bit[1]: level(1:hi, 0:low),
+ Bit[0]: type (1:level, 0:edge)
+ byte 1 can be readonly if 1 type of int is used.
+ ***/
+
+#define DRQ_CONFIG 0x74
+ /***
+ Two entries, one byte per entry. Bits[2:0] select
+ which DMA channel is in use for DMA 0. Zero selects DMA channel
+ 0, seven selects DMA channel 7. DMA channel 4, the cascade channel
+ is used to indicate no DMA channel is active.
+ ***/
+
+/*** 32-bit memory accesses are at 0x76 ***/
+
+/* Macros to parse Resource IDs */
+#define PNP_RES_TYPE(a) (a >> 7)
+#define PNP_SRES_NUM(a) (a >> 3)
+#define PNP_SRES_LEN(a) (a & 0x07)
+#define PNP_LRES_NUM(a) (a & 0x7f)
+
+/* Small Resource Item names */
+#define PNP_VERSION 0x1
+#define LOG_DEVICE_ID 0x2
+#define COMP_DEVICE_ID 0x3
+#define IRQ_FORMAT 0x4
+#define DMA_FORMAT 0x5
+#define START_DEPEND_FUNC 0x6
+#define END_DEPEND_FUNC 0x7
+#define IO_PORT_DESC 0x8
+#define FIXED_IO_PORT_DESC 0x9
+#define SM_RES_RESERVED 0xa-0xd
+#define SM_VENDOR_DEFINED 0xe
+#define END_TAG 0xf
+
+/* Large Resource Item names */
+#define MEMORY_RANGE_DESC 0x1
+#define ID_STRING_ANSI 0x2
+#define ID_STRING_UNICODE 0x3
+#define LG_VENDOR_DEFINED 0x4
+#define _32BIT_MEM_RANGE_DESC 0x5
+#define _32BIT_FIXED_LOC_DESC 0x6
+#define LG_RES_RESERVED 0x7-0x7f
+
+/*
+ * pnp_cinfo contains Configuration Information. They are used
+ * to communicate to the device driver the actual configuration
+ * of the device, and also by the userconfig menu to let the
+ * operating system override any configuration set by the bios.
+ *
+ */
+struct pnp_cinfo {
+ u_int vendor_id; /* board id */
+ u_int serial; /* Board's Serial Number */
+ u_long flags; /* OS-reserved flags */
+ u_char csn; /* assigned Card Select Number */
+ u_char ldn; /* Logical Device Number */
+ u_char enable; /* pnp enable */
+ u_char override; /* override bios parms (in userconfig) */
+ u_char irq[2]; /* IRQ Number */
+ u_char irq_type[2]; /* IRQ Type */
+ u_char drq[2];
+ u_short port[8]; /* The Base Address of the Port */
+ struct {
+ u_long base; /* Memory Base Address */
+ int control; /* Memory Control Register */
+ u_long range; /* Memory Range *OR* Upper Limit */
+ } mem[4];
+};
+
+#ifdef _KERNEL
+
+struct pnp_device {
+ char *pd_name;
+ char * (*pd_probe ) (u_long csn, u_long vendor_id);
+ void (*pd_attach ) (u_long csn, u_long vend_id, char * name,
+ struct isa_device *dev);
+ u_long *pd_count;
+ u_int *imask ;
+};
+
+struct _pnp_id {
+ u_long vendor_id;
+ u_long serial;
+ u_char checksum;
+} ;
+
+struct pnp_dlist_node {
+ struct pnp_device *pnp;
+ struct isa_device dev;
+ struct pnp_dlist_node *next;
+};
+
+typedef struct _pnp_id pnp_id;
+extern struct pnp_dlist_node *pnp_device_list;
+extern pnp_id pnp_devices[MAX_PNP_CARDS];
+extern struct pnp_cinfo pnp_ldn_overrides[MAX_PNP_LDN];
+extern int pnp_overrides_valid;
+
+/*
+ * these two functions are for use in drivers
+ */
+int read_pnp_parms(struct pnp_cinfo *d, int ldn);
+int write_pnp_parms(struct pnp_cinfo *d, int ldn);
+int enable_pnp_card(void);
+
+/*
+ * used by autoconfigure to actually probe and attach drivers
+ */
+void pnp_configure(void);
+
+#endif /* _KERNEL */
+
+#endif /* !_I386_ISA_PNP_H_ */
diff --git a/usr/src/boot/sys/boot/common/linenoise/LICENSE b/usr/src/boot/sys/boot/common/linenoise/LICENSE
new file mode 100755
index 0000000000..18e814865a
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
+Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
diff --git a/usr/src/boot/sys/boot/common/linenoise/LICENSE.descrip b/usr/src/boot/sys/boot/common/linenoise/LICENSE.descrip
new file mode 100644
index 0000000000..2191e517d7
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/LICENSE.descrip
@@ -0,0 +1 @@
+linenoise
diff --git a/usr/src/boot/sys/boot/common/linenoise/Makefile b/usr/src/boot/sys/boot/common/linenoise/Makefile
new file mode 100755
index 0000000000..a285410678
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/Makefile
@@ -0,0 +1,7 @@
+linenoise_example: linenoise.h linenoise.c
+
+linenoise_example: linenoise.c example.c
+ $(CC) -Wall -W -Os -g -o linenoise_example linenoise.c example.c
+
+clean:
+ rm -f linenoise_example
diff --git a/usr/src/boot/sys/boot/common/linenoise/README.markdown b/usr/src/boot/sys/boot/common/linenoise/README.markdown
new file mode 100755
index 0000000000..c845673cd4
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/README.markdown
@@ -0,0 +1,52 @@
+# Linenoise
+
+A minimal, zero-config, BSD licensed, readline replacement used in Redis,
+MongoDB, and Android.
+
+* Single and multi line editing mode with the usual key bindings implemented.
+* History handling.
+* Completion.
+* About 1,100 lines of BSD license source code.
+* Only uses a subset of VT100 escapes (ANSI.SYS compatible).
+
+## Can a line editing library be 20k lines of code?
+
+Line editing with some support for history is a really important feature for command line utilities. Instead of retyping almost the same stuff again and again it's just much better to hit the up arrow and edit on syntax errors, or in order to try a slightly different command. But apparently code dealing with terminals is some sort of Black Magic: readline is 30k lines of code, libedit 20k. Is it reasonable to link small utilities to huge libraries just to get a minimal support for line editing?
+
+So what usually happens is either:
+
+ * Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Real world example of this problem: Tclsh).
+ * Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance).
+
+The result is a pollution of binaries without line editing support.
+
+So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to linenoise if not.
+
+## Terminals, in 2010.
+
+Apparently almost every terminal you can happen to use today has some kind of support for basic VT100 escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it, and now can work even on ANSI.SYS compatible terminals, since no
+VT220 specific sequences are used anymore.
+
+The library is currently about 1100 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software.
+
+## Tested with...
+
+ * Linux text only console ($TERM = linux)
+ * Linux KDE terminal application ($TERM = xterm)
+ * Linux xterm ($TERM = xterm)
+ * Linux Buildroot ($TERM = vt100)
+ * Mac OS X iTerm ($TERM = xterm)
+ * Mac OS X default Terminal.app ($TERM = xterm)
+ * OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen)
+ * IBM AIX 6.1
+ * FreeBSD xterm ($TERM = xterm)
+ * ANSI.SYS
+
+Please test it everywhere you can and report back!
+
+## Let's push this forward!
+
+Patches should be provided in the respect of linenoise sensibility for small
+easy to understand code.
+
+Send feedbacks to antirez at gmail
diff --git a/usr/src/boot/sys/boot/common/linenoise/example.c b/usr/src/boot/sys/boot/common/linenoise/example.c
new file mode 100755
index 0000000000..a2f0936ede
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/example.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "linenoise.h"
+
+
+void completion(const char *buf, linenoiseCompletions *lc) {
+ if (buf[0] == 'h') {
+ linenoiseAddCompletion(lc,"hello");
+ linenoiseAddCompletion(lc,"hello there");
+ }
+}
+
+int main(int argc, char **argv) {
+ char *line;
+ char *prgname = argv[0];
+
+ /* Parse options, with --multiline we enable multi line editing. */
+ while(argc > 1) {
+ argc--;
+ argv++;
+ if (!strcmp(*argv,"--multiline")) {
+ linenoiseSetMultiLine(1);
+ printf("Multi-line mode enabled.\n");
+ } else if (!strcmp(*argv,"--keycodes")) {
+ linenoisePrintKeyCodes();
+ exit(0);
+ } else {
+ fprintf(stderr, "Usage: %s [--multiline] [--keycodes]\n", prgname);
+ exit(1);
+ }
+ }
+
+ /* Set the completion callback. This will be called every time the
+ * user uses the <tab> key. */
+ linenoiseSetCompletionCallback(completion);
+
+ /* Load history from file. The history file is just a plain text file
+ * where entries are separated by newlines. */
+ linenoiseHistoryLoad("history.txt"); /* Load the history at startup */
+
+ /* Now this is the main loop of the typical linenoise-based application.
+ * The call to linenoise() will block as long as the user types something
+ * and presses enter.
+ *
+ * The typed string is returned as a malloc() allocated string by
+ * linenoise, so the user needs to free() it. */
+ while((line = linenoise("hello> ")) != NULL) {
+ /* Do something with the string. */
+ if (line[0] != '\0' && line[0] != '/') {
+ printf("echo: '%s'\n", line);
+ linenoiseHistoryAdd(line); /* Add to the history. */
+ linenoiseHistorySave("history.txt"); /* Save the history on disk. */
+ } else if (!strncmp(line,"/historylen",11)) {
+ /* The "/historylen" command will change the history len. */
+ int len = atoi(line+11);
+ linenoiseHistorySetMaxLen(len);
+ } else if (line[0] == '/') {
+ printf("Unreconized command: %s\n", line);
+ }
+ free(line);
+ }
+ return 0;
+}
diff --git a/usr/src/boot/sys/boot/common/linenoise/linenoise.c b/usr/src/boot/sys/boot/common/linenoise/linenoise.c
new file mode 100755
index 0000000000..e789a21d3f
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/linenoise.c
@@ -0,0 +1,854 @@
+/* linenoise.c -- VERSION 1.0
+ *
+ * Guerrilla line editing library against the idea that a line editing lib
+ * needs to be 20,000 lines of C code.
+ *
+ * You can find the latest source code at:
+ *
+ * http://github.com/antirez/linenoise
+ *
+ * Does a number of crazy assumptions that happen to be true in 99.9999% of
+ * the 2010 UNIX computers around.
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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 MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ *
+ * ------------------------------------------------------------------------
+ *
+ * References:
+ * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
+ * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
+ *
+ * Todo list:
+ * - Filter bogus Ctrl+<char> combinations.
+ * - Win32 support
+ *
+ * Bloat:
+ * - History search like Ctrl+r in readline?
+ *
+ * List of escape sequences used by this program, we do everything just
+ * with three sequences. In order to be so cheap we may have some
+ * flickering effect with some slow terminal, but the lesser sequences
+ * the more compatible.
+ *
+ * EL (Erase Line)
+ * Sequence: ESC [ n K
+ * Effect: if n is 0 or missing, clear from cursor to end of line
+ * Effect: if n is 1, clear from beginning of line to cursor
+ * Effect: if n is 2, clear entire line
+ *
+ * CUF (CUrsor Forward)
+ * Sequence: ESC [ n C
+ * Effect: moves cursor forward n chars
+ *
+ * CUB (CUrsor Backward)
+ * Sequence: ESC [ n D
+ * Effect: moves cursor backward n chars
+ *
+ * The following is used to get the terminal width if getting
+ * the width with the TIOCGWINSZ ioctl fails
+ *
+ * DSR (Device Status Report)
+ * Sequence: ESC [ 6 n
+ * Effect: reports the current cusor position as ESC [ n ; m R
+ * where n is the row and m is the column
+ *
+ * When multi line mode is enabled, we also use an additional escape
+ * sequence. However multi line editing is disabled by default.
+ *
+ * CUU (Cursor Up)
+ * Sequence: ESC [ n A
+ * Effect: moves cursor up of n chars.
+ *
+ * CUD (Cursor Down)
+ * Sequence: ESC [ n B
+ * Effect: moves cursor down of n chars.
+ *
+ * When linenoiseClearScreen() is called, two additional escape sequences
+ * are used in order to clear the screen and position the cursor at home
+ * position.
+ *
+ * CUP (Cursor position)
+ * Sequence: ESC [ H
+ * Effect: moves the cursor to upper left corner
+ *
+ * ED (Erase display)
+ * Sequence: ESC [ 2 J
+ * Effect: clear the whole screen
+ *
+ */
+
+#include <stand.h>
+#include "linenoise.h"
+#include "bootstrap.h"
+
+#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
+#define LINENOISE_MAX_LINE 256
+static linenoiseCompletionCallback *completionCallback = NULL;
+
+static int mlmode = 1; /* Multi line mode. Default is single line. */
+static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
+static int history_len = 0;
+static char **history = NULL;
+
+/* The linenoiseState structure represents the state during line editing.
+ * We pass this state to functions implementing specific editing
+ * functionalities. */
+struct linenoiseState {
+ char *buf; /* Edited line buffer. */
+ size_t buflen; /* Edited line buffer size. */
+ const char *prompt; /* Prompt to display. */
+ size_t plen; /* Prompt length. */
+ size_t pos; /* Current cursor position. */
+ size_t oldpos; /* Previous refresh cursor position. */
+ size_t len; /* Current edited line length. */
+ size_t cols; /* Number of columns in terminal. */
+ size_t maxrows; /* Maximum num of rows used so far (multiline mode) */
+ int history_index; /* The history index we are currently editing. */
+};
+
+enum KEY_ACTION{
+ KEY_NULL = 0, /* NULL */
+ CTRL_A = 1, /* Ctrl+a */
+ CTRL_B = 2, /* Ctrl-b */
+ CTRL_C = 3, /* Ctrl-c */
+ CTRL_D = 4, /* Ctrl-d */
+ CTRL_E = 5, /* Ctrl-e */
+ CTRL_F = 6, /* Ctrl-f */
+ CTRL_H = 8, /* Ctrl-h */
+ TAB = 9, /* Tab */
+ CTRL_K = 11, /* Ctrl+k */
+ CTRL_L = 12, /* Ctrl+l */
+ ENTER = 13, /* Enter */
+ CTRL_N = 14, /* Ctrl-n */
+ CTRL_P = 16, /* Ctrl-p */
+ CTRL_T = 20, /* Ctrl-t */
+ CTRL_U = 21, /* Ctrl+u */
+ CTRL_W = 23, /* Ctrl+w */
+ ESC = 27, /* Escape */
+ BACKSPACE = 127 /* Backspace */
+};
+
+static void refreshLine(struct linenoiseState *l);
+
+/* ======================= Low level terminal handling ====================== */
+
+static int
+put_bytes(const char *s, int len)
+{
+ int i;
+ if (s == NULL)
+ return -1;
+
+ for (i = 0; i < len; i++)
+ putchar(s[i]);
+ return (i);
+}
+
+/* Set if to use or not the multi line mode. */
+void linenoiseSetMultiLine(int ml) {
+ mlmode = ml;
+}
+
+/* Clear the screen. Used to handle ctrl+l */
+void linenoiseClearScreen(void) {
+ if (put_bytes("\x1b[H\x1b[J", 6) <= 0) {
+ /* nothing to do, just to avoid warning. */
+ }
+}
+
+static int
+getColumns(void)
+{
+ char *columns = getenv("COLUMNS");
+ if (columns == NULL)
+ return (80);
+ return (strtol(columns, NULL, 0));
+}
+
+/* Beep, used for completion when there is nothing to complete or when all
+ * the choices were already shown. */
+static void linenoiseBeep(void) {
+ put_bytes("\x7", 1);
+}
+
+/* ============================== Completion ================================ */
+
+/* Free a list of completion option populated by linenoiseAddCompletion(). */
+static void freeCompletions(linenoiseCompletions *lc) {
+ size_t i;
+ for (i = 0; i < lc->len; i++)
+ free(lc->cvec[i]);
+ if (lc->cvec != NULL)
+ free(lc->cvec);
+}
+
+/* This is an helper function for linenoiseEdit() and is called when the
+ * user types the <tab> key in order to complete the string currently in the
+ * input.
+ *
+ * The state of the editing is encapsulated into the pointed linenoiseState
+ * structure as described in the structure definition. */
+static int completeLine(struct linenoiseState *ls) {
+ linenoiseCompletions lc = { 0, NULL };
+ int nwritten;
+ char c = 0;
+
+ completionCallback(ls->buf,&lc);
+ if (lc.len == 0) {
+ linenoiseBeep();
+ } else {
+ size_t stop = 0, i = 0;
+
+ while(!stop) {
+ /* Show completion or original buffer */
+ if (i < lc.len) {
+ struct linenoiseState saved = *ls;
+
+ ls->len = ls->pos = strlen(lc.cvec[i]);
+ ls->buf = lc.cvec[i];
+ refreshLine(ls);
+ ls->len = saved.len;
+ ls->pos = saved.pos;
+ ls->buf = saved.buf;
+ } else {
+ refreshLine(ls);
+ }
+
+ c = getchar();
+ if (c <= 0) {
+ freeCompletions(&lc);
+ return -1;
+ }
+
+ switch(c) {
+ case 9: /* tab */
+ i = (i+1) % (lc.len+1);
+ if (i == lc.len) linenoiseBeep();
+ break;
+ case 27: /* escape */
+ /* Re-show original buffer */
+ if (i < lc.len) refreshLine(ls);
+ stop = 1;
+ break;
+ default:
+ /* Update buffer and return */
+ if (i < lc.len) {
+ nwritten = snprintf(ls->buf,ls->buflen,"%s",lc.cvec[i]);
+ ls->len = ls->pos = nwritten;
+ }
+ stop = 1;
+ break;
+ }
+ }
+ }
+
+ freeCompletions(&lc);
+ return c; /* Return last read character */
+}
+
+/* Register a callback function to be called for tab-completion. */
+void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
+ completionCallback = fn;
+}
+
+/* This function is used by the callback function registered by the user
+ * in order to add completion options given the input string when the
+ * user typed <tab>. See the example.c source code for a very easy to
+ * understand example. */
+void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
+ size_t len = strlen(str);
+ char *copy, **cvec;
+
+ copy = malloc(len+1);
+ if (copy == NULL) return;
+ memcpy(copy,str,len+1);
+ cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1));
+ if (cvec == NULL) {
+ free(copy);
+ return;
+ }
+ lc->cvec = cvec;
+ lc->cvec[lc->len++] = copy;
+}
+
+/* =========================== Line editing ================================= */
+
+/* We define a very simple "append buffer" structure, that is an heap
+ * allocated string where we can append to. This is useful in order to
+ * write all the escape sequences in a buffer and flush them to the standard
+ * output in a single call, to avoid flickering effects. */
+struct abuf {
+ char *b;
+ int len;
+};
+
+static void abInit(struct abuf *ab) {
+ ab->b = NULL;
+ ab->len = 0;
+}
+
+static void abAppend(struct abuf *ab, const char *s, int len) {
+ char *new = malloc(ab->len+len);
+
+ if (new == NULL) return;
+ memcpy(new, ab->b, ab->len);
+ memcpy(new+ab->len,s,len);
+ free(ab->b);
+ ab->b = new;
+ ab->len += len;
+}
+
+static void abFree(struct abuf *ab) {
+ free(ab->b);
+}
+
+/* Single line low level line refresh.
+ *
+ * Rewrite the currently edited line accordingly to the buffer content,
+ * cursor position, and number of columns of the terminal. */
+static void refreshSingleLine(struct linenoiseState *l) {
+ char seq[64];
+ size_t plen = strlen(l->prompt);
+ char *buf = l->buf;
+ size_t len = l->len;
+ size_t pos = l->pos;
+ struct abuf ab;
+
+ while((plen+pos) >= l->cols) {
+ buf++;
+ len--;
+ pos--;
+ }
+ while (plen+len > l->cols) {
+ len--;
+ }
+
+ abInit(&ab);
+ /* Cursor to left edge */
+ snprintf(seq,64,"\r");
+ abAppend(&ab,seq,strlen(seq));
+ /* Write the prompt and the current buffer content */
+ abAppend(&ab,l->prompt,strlen(l->prompt));
+ abAppend(&ab,buf,len);
+ /* Erase to right */
+ snprintf(seq,64,"\x1b[K");
+ abAppend(&ab,seq,strlen(seq));
+ /* Move cursor to original position. */
+ snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen));
+ abAppend(&ab,seq,strlen(seq));
+ put_bytes(ab.b, ab.len);
+
+ abFree(&ab);
+}
+
+/* Multi line low level line refresh.
+ *
+ * Rewrite the currently edited line accordingly to the buffer content,
+ * cursor position, and number of columns of the terminal. */
+static void refreshMultiLine(struct linenoiseState *l) {
+ char seq[64];
+ int plen = strlen(l->prompt);
+ int rows = (plen+l->len+l->cols)/l->cols; /* rows used by current buf. */
+ int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */
+ int rpos2; /* rpos after refresh. */
+ int col; /* colum position, zero-based. */
+ int old_rows = l->maxrows;
+ int j;
+ struct abuf ab;
+
+ /* Update maxrows if needed. */
+ if (rows > (int)l->maxrows) l->maxrows = rows;
+
+ /* First step: clear all the lines used before. To do so start by
+ * going to the last row. */
+ abInit(&ab);
+ if (old_rows-rpos > 0) {
+ snprintf(seq,64,"\x1b[%dB", old_rows-rpos);
+ abAppend(&ab,seq,strlen(seq));
+ }
+
+ /* Now for every row clear it, go up. */
+ for (j = 0; j < old_rows-1; j++) {
+ snprintf(seq,64,"\r\x1b[0K\x1b[1A");
+ abAppend(&ab,seq,strlen(seq));
+ }
+
+ /* Clean the top line. */
+ snprintf(seq,64,"\r\x1b[0K");
+ abAppend(&ab,seq,strlen(seq));
+
+ /* Write the prompt and the current buffer content */
+ abAppend(&ab,l->prompt,strlen(l->prompt));
+ abAppend(&ab,l->buf,l->len);
+
+ /* If we are at the very end of the screen with our prompt, we need to
+ * emit a newline and move the prompt to the first column. */
+ if (l->pos &&
+ l->pos == l->len &&
+ (l->pos+plen) % l->cols == 0)
+ {
+ abAppend(&ab,"\n",1);
+ snprintf(seq,64,"\r");
+ abAppend(&ab,seq,strlen(seq));
+ rows++;
+ if (rows > (int)l->maxrows) l->maxrows = rows;
+ }
+
+ /* Move cursor to right position. */
+ rpos2 = (plen+l->pos+l->cols)/l->cols; /* current cursor relative row. */
+
+ /* Go up till we reach the expected positon. */
+ if (rows-rpos2 > 0) {
+ snprintf(seq,64,"\x1b[%dA", rows-rpos2);
+ abAppend(&ab,seq,strlen(seq));
+ }
+
+ /* Set column. */
+ col = (plen+(int)l->pos) % (int)l->cols;
+ if (col)
+ snprintf(seq,64,"\r\x1b[%dC", col);
+ else
+ snprintf(seq,64,"\r");
+ abAppend(&ab,seq,strlen(seq));
+
+ l->oldpos = l->pos;
+
+ put_bytes(ab.b, ab.len);
+ abFree(&ab);
+}
+
+/* Calls the two low level functions refreshSingleLine() or
+ * refreshMultiLine() according to the selected mode. */
+static void refreshLine(struct linenoiseState *l) {
+ if (mlmode)
+ refreshMultiLine(l);
+ else
+ refreshSingleLine(l);
+}
+
+/* Insert the character 'c' at cursor current position.
+ *
+ * On error writing to the terminal -1 is returned, otherwise 0. */
+static int
+linenoiseEditInsert(struct linenoiseState *l, char c) {
+ if (l->len < l->buflen) {
+ if (l->len == l->pos) {
+ l->buf[l->pos] = c;
+ l->pos++;
+ l->len++;
+ l->buf[l->len] = '\0';
+ if ((!mlmode && l->plen+l->len < l->cols) /* || mlmode */) {
+ /* Avoid a full update of the line in the
+ * trivial case. */
+ putchar(c);
+ } else {
+ refreshLine(l);
+ }
+ } else {
+ memmove(l->buf+l->pos+1,l->buf+l->pos,l->len-l->pos);
+ l->buf[l->pos] = c;
+ l->len++;
+ l->pos++;
+ l->buf[l->len] = '\0';
+ refreshLine(l);
+ }
+ }
+ return 0;
+}
+
+/* Move cursor on the left. */
+static void
+linenoiseEditMoveLeft(struct linenoiseState *l) {
+ if (l->pos > 0) {
+ l->pos--;
+ refreshLine(l);
+ }
+}
+
+/* Move cursor on the right. */
+static void
+linenoiseEditMoveRight(struct linenoiseState *l) {
+ if (l->pos != l->len) {
+ l->pos++;
+ refreshLine(l);
+ }
+}
+
+/* Move cursor to the start of the line. */
+static void
+linenoiseEditMoveHome(struct linenoiseState *l) {
+ if (l->pos != 0) {
+ l->pos = 0;
+ refreshLine(l);
+ }
+}
+
+/* Move cursor to the end of the line. */
+static void
+linenoiseEditMoveEnd(struct linenoiseState *l) {
+ if (l->pos != l->len) {
+ l->pos = l->len;
+ refreshLine(l);
+ }
+}
+
+/* Substitute the currently edited line with the next or previous history
+ * entry as specified by 'dir'. */
+#define LINENOISE_HISTORY_NEXT 0
+#define LINENOISE_HISTORY_PREV 1
+static void
+linenoiseEditHistoryNext(struct linenoiseState *l, int dir) {
+ if (history_len > 1) {
+ /* Update the current history entry before to
+ * overwrite it with the next one. */
+ free(history[history_len - 1 - l->history_index]);
+ history[history_len - 1 - l->history_index] = strdup(l->buf);
+ /* Show the new entry */
+ l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1;
+ if (l->history_index < 0) {
+ l->history_index = 0;
+ return;
+ } else if (l->history_index >= history_len) {
+ l->history_index = history_len-1;
+ return;
+ }
+ strncpy(l->buf,history[history_len - 1 - l->history_index],l->buflen);
+ l->buf[l->buflen-1] = '\0';
+ l->len = l->pos = strlen(l->buf);
+ refreshLine(l);
+ }
+}
+
+/* Delete the character at the right of the cursor without altering the cursor
+ * position. Basically this is what happens with the "Delete" keyboard key. */
+static void
+linenoiseEditDelete(struct linenoiseState *l) {
+ if (l->len > 0 && l->pos < l->len) {
+ memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1);
+ l->len--;
+ l->buf[l->len] = '\0';
+ refreshLine(l);
+ }
+}
+
+/* Backspace implementation. */
+static void
+linenoiseEditBackspace(struct linenoiseState *l) {
+ if (l->pos > 0 && l->len > 0) {
+ memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos);
+ l->pos--;
+ l->len--;
+ l->buf[l->len] = '\0';
+ refreshLine(l);
+ }
+}
+
+/* Delete the previosu word, maintaining the cursor at the start of the
+ * current word. */
+static void
+linenoiseEditDeletePrevWord(struct linenoiseState *l) {
+ size_t old_pos = l->pos;
+ size_t diff;
+
+ while (l->pos > 0 && l->buf[l->pos-1] == ' ')
+ l->pos--;
+ while (l->pos > 0 && l->buf[l->pos-1] != ' ')
+ l->pos--;
+ diff = old_pos - l->pos;
+ memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1);
+ l->len -= diff;
+ refreshLine(l);
+}
+
+/* This function is the core of the line editing capability of linenoise.
+ * It expects 'fd' to be already in "raw mode" so that every key pressed
+ * will be returned ASAP to read().
+ *
+ * The resulting string is put into 'buf' when the user type enter, or
+ * when ctrl+d is typed.
+ *
+ * The function returns the length of the current buffer. */
+static int linenoiseEdit(char *buf, size_t buflen, const char *prompt)
+{
+ struct linenoiseState l;
+
+ /* Populate the linenoise state that we pass to functions implementing
+ * specific editing functionalities. */
+ l.buf = buf;
+ l.buflen = buflen;
+ l.prompt = prompt;
+ l.plen = strlen(prompt);
+ l.oldpos = l.pos = 0;
+ l.len = 0;
+ l.cols = getColumns();
+ l.maxrows = 0;
+ l.history_index = 0;
+
+ /* Buffer starts empty. */
+ l.buf[0] = '\0';
+ l.buflen--; /* Make sure there is always space for the nulterm */
+
+ /* The latest history entry is always our current buffer, that
+ * initially is just an empty string. */
+ linenoiseHistoryAdd("");
+
+ printf ("%s", prompt);
+ while(1) {
+ char c;
+ char seq[3];
+
+ c = getchar();
+ if (c == -1)
+ continue;
+
+ /* Only autocomplete when the callback is set. It returns < 0 when
+ * there was an error reading from fd. Otherwise it will return the
+ * character that should be handled next. */
+ if (c == 9 && completionCallback != NULL) {
+ c = completeLine(&l);
+ /* Return on errors */
+ if (c < 0) return l.len;
+ /* Read next character when 0 */
+ if (c == 0) continue;
+ }
+
+ switch(c) {
+ case ENTER: /* enter */
+ history_len--;
+ free(history[history_len]);
+ if (mlmode) linenoiseEditMoveEnd(&l);
+ return (int)l.len;
+ case CTRL_C: /* ctrl-c */
+ buf[0] = '\0';
+ l.pos = l.len = 0;
+ refreshLine(&l);
+ case BACKSPACE: /* backspace */
+ case 8: /* ctrl-h */
+ linenoiseEditBackspace(&l);
+ break;
+ case CTRL_D: /* ctrl-d, remove char at right of cursor. */
+ if (l.len > 0) {
+ linenoiseEditDelete(&l);
+ }
+ break;
+ case CTRL_T: /* ctrl-t, swaps current character with previous. */
+ if (l.pos > 0 && l.pos < l.len) {
+ int aux = buf[l.pos-1];
+ buf[l.pos-1] = buf[l.pos];
+ buf[l.pos] = aux;
+ if (l.pos != l.len-1) l.pos++;
+ refreshLine(&l);
+ }
+ break;
+ case CTRL_B: /* ctrl-b */
+ linenoiseEditMoveLeft(&l);
+ break;
+ case CTRL_F: /* ctrl-f */
+ linenoiseEditMoveRight(&l);
+ break;
+ case CTRL_P: /* ctrl-p */
+ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
+ break;
+ case CTRL_N: /* ctrl-n */
+ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
+ break;
+ case ESC: /* escape sequence */
+ /* Read the next two bytes representing the escape sequence.
+ * Use two calls to handle slow terminals returning the two
+ * chars at different times. */
+ seq[0] = getchar();
+ seq[1] = getchar();
+
+ /* ESC [ sequences. */
+ if (seq[0] == '[') {
+ if (seq[1] >= '0' && seq[1] <= '9') {
+ /* Extended escape, read additional byte. */
+ seq[2] = getchar();
+ if (seq[2] == '~') {
+ switch(seq[1]) {
+ case '3': /* Delete key. */
+ linenoiseEditDelete(&l);
+ break;
+ }
+ }
+ } else {
+ switch(seq[1]) {
+ case 'A': /* Up */
+ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
+ break;
+ case 'B': /* Down */
+ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
+ break;
+ case 'C': /* Right */
+ linenoiseEditMoveRight(&l);
+ break;
+ case 'D': /* Left */
+ linenoiseEditMoveLeft(&l);
+ break;
+ case 'H': /* Home */
+ linenoiseEditMoveHome(&l);
+ break;
+ case 'F': /* End*/
+ linenoiseEditMoveEnd(&l);
+ break;
+ }
+ }
+ }
+
+ /* ESC O sequences. */
+ else if (seq[0] == 'O') {
+ switch(seq[1]) {
+ case 'H': /* Home */
+ linenoiseEditMoveHome(&l);
+ break;
+ case 'F': /* End*/
+ linenoiseEditMoveEnd(&l);
+ break;
+ }
+ }
+ break;
+ default:
+ if (linenoiseEditInsert(&l,c)) return -1;
+ break;
+ case CTRL_U: /* Ctrl+u, delete the whole line. */
+ buf[0] = '\0';
+ l.pos = l.len = 0;
+ refreshLine(&l);
+ break;
+ case CTRL_K: /* Ctrl+k, delete from current to end of line. */
+ buf[l.pos] = '\0';
+ l.len = l.pos;
+ refreshLine(&l);
+ break;
+ case CTRL_A: /* Ctrl+a, go to the start of the line */
+ linenoiseEditMoveHome(&l);
+ break;
+ case CTRL_E: /* ctrl+e, go to the end of the line */
+ linenoiseEditMoveEnd(&l);
+ break;
+ case CTRL_L: /* ctrl+l, clear screen */
+ linenoiseClearScreen();
+ refreshLine(&l);
+ break;
+ case CTRL_W: /* ctrl+w, delete previous word */
+ linenoiseEditDeletePrevWord(&l);
+ break;
+ }
+ }
+ return l.len;
+}
+
+/* The high level function that is the main API of the linenoise library.
+ * This function checks if the terminal has basic capabilities, just checking
+ * for a blacklist of stupid terminals, and later either calls the line
+ * editing function or uses dummy fgets() so that you will be able to type
+ * something even in the most desperate of the conditions. */
+char *linenoise(const char *prompt) {
+ char buf[LINENOISE_MAX_LINE];
+ int count;
+
+ cons_mode(C_MODERAW);
+ count = linenoiseEdit(buf,LINENOISE_MAX_LINE,prompt);
+ cons_mode(0);
+ printf("\n");
+ if (count == -1) return NULL;
+ return strdup(buf);
+}
+
+/* ================================ History ================================= */
+
+/* This is the API call to add a new entry in the linenoise history.
+ * It uses a fixed array of char pointers that are shifted (memmoved)
+ * when the history max length is reached in order to remove the older
+ * entry and make room for the new one, so it is not exactly suitable for huge
+ * histories, but will work well for a few hundred of entries.
+ *
+ * Using a circular buffer is smarter, but a bit more complex to handle. */
+int linenoiseHistoryAdd(const char *line) {
+ char *linecopy;
+
+ if (history_max_len == 0) return 0;
+
+ /* Initialization on first call. */
+ if (history == NULL) {
+ history = malloc(sizeof(char*)*history_max_len);
+ if (history == NULL) return 0;
+ memset(history,0,(sizeof(char*)*history_max_len));
+ }
+
+ /* Don't add duplicated lines. */
+ if (history_len && !strcmp(history[history_len-1], line)) return 0;
+
+ /* Add an heap allocated copy of the line in the history.
+ * If we reached the max length, remove the older line. */
+ linecopy = strdup(line);
+ if (!linecopy) return 0;
+ if (history_len == history_max_len) {
+ free(history[0]);
+ memmove(history,history+1,sizeof(char*)*(history_max_len-1));
+ history_len--;
+ }
+ history[history_len] = linecopy;
+ history_len++;
+ return 1;
+}
+
+/* Set the maximum length for the history. This function can be called even
+ * if there is already some history, the function will make sure to retain
+ * just the latest 'len' elements if the new history length value is smaller
+ * than the amount of items already inside the history. */
+int linenoiseHistorySetMaxLen(int len) {
+ char **new;
+
+ if (len < 1) return 0;
+ if (history) {
+ int tocopy = history_len;
+
+ new = malloc(sizeof(char*)*len);
+ if (new == NULL) return 0;
+
+ /* If we can't copy everything, free the elements we'll not use. */
+ if (len < tocopy) {
+ int j;
+
+ for (j = 0; j < tocopy-len; j++) free(history[j]);
+ tocopy = len;
+ }
+ memset(new,0,sizeof(char*)*len);
+ memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy);
+ free(history);
+ history = new;
+ }
+ history_max_len = len;
+ if (history_len > history_max_len)
+ history_len = history_max_len;
+ return 1;
+}
diff --git a/usr/src/boot/sys/boot/common/linenoise/linenoise.h b/usr/src/boot/sys/boot/common/linenoise/linenoise.h
new file mode 100755
index 0000000000..fbb01cfaad
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/linenoise/linenoise.h
@@ -0,0 +1,68 @@
+/* linenoise.h -- VERSION 1.0
+ *
+ * Guerrilla line editing library against the idea that a line editing lib
+ * needs to be 20,000 lines of C code.
+ *
+ * See linenoise.c for more information.
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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 MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+#ifndef __LINENOISE_H
+#define __LINENOISE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct linenoiseCompletions {
+ size_t len;
+ char **cvec;
+} linenoiseCompletions;
+
+typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
+void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
+void linenoiseAddCompletion(linenoiseCompletions *, const char *);
+
+char *linenoise(const char *prompt);
+int linenoiseHistoryAdd(const char *line);
+int linenoiseHistorySetMaxLen(int len);
+int linenoiseHistorySave(const char *filename);
+int linenoiseHistoryLoad(const char *filename);
+void linenoiseClearScreen(void);
+void linenoiseSetMultiLine(int ml);
+void linenoisePrintKeyCodes(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LINENOISE_H */
diff --git a/usr/src/boot/sys/boot/common/load_elf.c b/usr/src/boot/sys/boot/common/load_elf.c
new file mode 100644
index 0000000000..287bfac56a
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf.c
@@ -0,0 +1,1090 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998 Peter Wemm <peter@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <sys/stdint.h>
+#include <string.h>
+#include <machine/elf.h>
+#include <stand.h>
+#define FREEBSD_ELF
+#include <link.h>
+
+#include "bootstrap.h"
+
+#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l)
+
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+#undef ELF_TARG_CLASS
+#undef ELF_TARG_MACH
+#define ELF_TARG_CLASS ELFCLASS64
+#define ELF_TARG_MACH EM_X86_64
+#endif
+
+typedef struct elf_file {
+ Elf_Phdr *ph;
+ Elf_Ehdr *ehdr;
+ Elf_Sym *symtab;
+ Elf_Hashelt *hashtab;
+ Elf_Hashelt nbuckets;
+ Elf_Hashelt nchains;
+ Elf_Hashelt *buckets;
+ Elf_Hashelt *chains;
+ Elf_Rel *rel;
+ size_t relsz;
+ Elf_Rela *rela;
+ size_t relasz;
+ char *strtab;
+ size_t strsz;
+ int fd;
+ caddr_t firstpage;
+ size_t firstlen;
+ int kernel;
+ u_int64_t off;
+} *elf_file_t;
+
+static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, u_int64_t loadaddr);
+static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym);
+static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
+ Elf_Addr p, void *val, size_t len);
+static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
+ Elf_Addr p_start, Elf_Addr p_end);
+static symaddr_fn __elfN(symaddr);
+static char *fake_modname(const char *name);
+
+const char *__elfN(kerneltype) = "elf kernel";
+const char *__elfN(moduletype) = "elf module";
+
+u_int64_t __elfN(relocation_offset) = 0;
+
+static int
+__elfN(load_elf_header)(char *filename, elf_file_t ef)
+{
+ ssize_t bytes_read;
+ Elf_Ehdr *ehdr;
+ int err;
+
+ /*
+ * Open the image, read and validate the ELF header
+ */
+ if (filename == NULL) /* can't handle nameless */
+ return (EFTYPE);
+ if ((ef->fd = open(filename, O_RDONLY)) == -1)
+ return (errno);
+ ef->firstpage = malloc(PAGE_SIZE);
+ if (ef->firstpage == NULL) {
+ close(ef->fd);
+ return (ENOMEM);
+ }
+ bytes_read = read(ef->fd, ef->firstpage, PAGE_SIZE);
+ ef->firstlen = (size_t)bytes_read;
+ if (bytes_read < 0 || ef->firstlen <= sizeof(Elf_Ehdr)) {
+ err = EFTYPE; /* could be EIO, but may be small file */
+ goto error;
+ }
+ ehdr = ef->ehdr = (Elf_Ehdr *)ef->firstpage;
+
+ /* Is it ELF? */
+ if (!IS_ELF(*ehdr)) {
+ err = EFTYPE;
+ goto error;
+ }
+ if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
+ ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
+ ehdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */
+ ehdr->e_version != EV_CURRENT ||
+ ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */
+ err = EFTYPE;
+ goto error;
+ }
+
+ return (0);
+
+error:
+ if (ef->firstpage != NULL) {
+ free(ef->firstpage);
+ ef->firstpage = NULL;
+ }
+ if (ef->fd != -1) {
+ close(ef->fd);
+ ef->fd = -1;
+ }
+ return (err);
+}
+
+/*
+ * Attempt to load the file (file) as an ELF module. It will be stored at
+ * (dest), and a pointer to a module structure describing the loaded object
+ * will be saved in (result).
+ */
+int
+__elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result)
+{
+ return (__elfN(loadfile_raw)(filename, dest, result, 0));
+}
+
+int
+__elfN(loadfile_raw)(char *filename, u_int64_t dest,
+ struct preloaded_file **result, int multiboot)
+{
+ struct preloaded_file *fp, *kfp;
+ struct elf_file ef;
+ Elf_Ehdr *ehdr;
+ int err;
+
+ fp = NULL;
+ bzero(&ef, sizeof(struct elf_file));
+ ef.fd = -1;
+
+ err = __elfN(load_elf_header)(filename, &ef);
+ if (err != 0)
+ return (err);
+
+ ehdr = ef.ehdr;
+
+ /*
+ * Check to see what sort of module we are.
+ */
+ kfp = file_findfile(NULL, __elfN(kerneltype));
+#ifdef __powerpc__
+ /*
+ * Kernels can be ET_DYN, so just assume the first loaded object is the
+ * kernel. This assumption will be checked later.
+ */
+ if (kfp == NULL)
+ ef.kernel = 1;
+#endif
+ if (ef.kernel || ehdr->e_type == ET_EXEC) {
+ /* Looks like a kernel */
+ if (kfp != NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n");
+ err = EPERM;
+ goto oerr;
+ }
+ /*
+ * Calculate destination address based on kernel entrypoint.
+ *
+ * For ARM, the destination address is independent of any values in the
+ * elf header (an ARM kernel can be loaded at any 2MB boundary), so we
+ * leave dest set to the value calculated by archsw.arch_loadaddr() and
+ * passed in to this function.
+ */
+#ifndef __arm__
+ if (ehdr->e_type == ET_EXEC)
+ dest = (ehdr->e_entry & ~PAGE_MASK);
+#endif
+ if ((ehdr->e_entry & ~PAGE_MASK) == 0) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n");
+ err = EPERM;
+ goto oerr;
+ }
+ ef.kernel = 1;
+
+ } else if (ehdr->e_type == ET_DYN) {
+ /* Looks like a kld module */
+ if (multiboot != 0) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n");
+ err = EPERM;
+ goto oerr;
+ }
+ if (kfp == NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n");
+ err = EPERM;
+ goto oerr;
+ }
+ if (strcmp(__elfN(kerneltype), kfp->f_type)) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type);
+ err = EPERM;
+ goto oerr;
+ }
+ /* Looks OK, got ahead */
+ ef.kernel = 0;
+
+ } else {
+ err = EFTYPE;
+ goto oerr;
+ }
+
+ if (archsw.arch_loadaddr != NULL)
+ dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest);
+ else
+ dest = roundup(dest, PAGE_SIZE);
+
+ /*
+ * Ok, we think we should handle this.
+ */
+ fp = file_alloc();
+ if (fp == NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n");
+ err = EPERM;
+ goto out;
+ }
+ if (ef.kernel == 1 && multiboot == 0)
+ setenv("kernelname", filename, 1);
+ fp->f_name = strdup(filename);
+ if (multiboot == 0)
+ fp->f_type = strdup(ef.kernel ?
+ __elfN(kerneltype) : __elfN(moduletype));
+ else
+ fp->f_type = strdup("elf multiboot kernel");
+
+#ifdef ELF_VERBOSE
+ if (ef.kernel)
+ printf("%s entry at 0x%jx\n", filename, (uintmax_t)ehdr->e_entry);
+#else
+ printf("%s ", filename);
+#endif
+
+ fp->f_size = __elfN(loadimage)(fp, &ef, dest);
+ if (fp->f_size == 0 || fp->f_addr == 0)
+ goto ioerr;
+
+ /* save exec header as metadata */
+ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr);
+
+ /* Load OK, return module pointer */
+ *result = (struct preloaded_file *)fp;
+ err = 0;
+ goto out;
+
+ ioerr:
+ err = EIO;
+ oerr:
+ file_discard(fp);
+ out:
+ if (ef.firstpage)
+ free(ef.firstpage);
+ if (ef.fd != -1)
+ close(ef.fd);
+ return(err);
+}
+
+/*
+ * With the file (fd) open on the image, and (ehdr) containing
+ * the Elf header, load the image at (off)
+ */
+static int
+__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
+{
+ int i;
+ u_int j;
+ Elf_Ehdr *ehdr;
+ Elf_Phdr *phdr, *php;
+ Elf_Shdr *shdr;
+ char *shstr;
+ int ret;
+ vm_offset_t firstaddr;
+ vm_offset_t lastaddr;
+ size_t chunk;
+ ssize_t result;
+ Elf_Addr ssym, esym;
+ Elf_Dyn *dp;
+ Elf_Addr adp;
+ Elf_Addr ctors;
+ int ndp;
+ int symstrindex;
+ int symtabindex;
+ Elf_Size size;
+ u_int fpcopy;
+ Elf_Sym sym;
+ Elf_Addr p_start, p_end;
+
+ dp = NULL;
+ shdr = NULL;
+ ret = 0;
+ firstaddr = lastaddr = 0;
+ ehdr = ef->ehdr;
+ if (ehdr->e_type == ET_EXEC) {
+#if defined(__i386__) || defined(__amd64__)
+#if __ELF_WORD_SIZE == 64
+ off = - (off & 0xffffffffff000000ull);/* x86_64 relocates after locore */
+#else
+ off = - (off & 0xff000000u); /* i386 relocates after locore */
+#endif
+#elif defined(__powerpc__)
+ /*
+ * On the purely virtual memory machines like e500, the kernel is
+ * linked against its final VA range, which is most often not
+ * available at the loader stage, but only after kernel initializes
+ * and completes its VM settings. In such cases we cannot use p_vaddr
+ * field directly to load ELF segments, but put them at some
+ * 'load-time' locations.
+ */
+ if (off & 0xf0000000u) {
+ off = -(off & 0xf0000000u);
+ /*
+ * XXX the physical load address should not be hardcoded. Note
+ * that the Book-E kernel assumes that it's loaded at a 16MB
+ * boundary for now...
+ */
+ off += 0x01000000;
+ ehdr->e_entry += off;
+#ifdef ELF_VERBOSE
+ printf("Converted entry 0x%08x\n", ehdr->e_entry);
+#endif
+ } else
+ off = 0;
+#elif defined(__arm__) && !defined(EFI)
+ /*
+ * The elf headers in arm kernels specify virtual addresses in all
+ * header fields, even the ones that should be physical addresses.
+ * We assume the entry point is in the first page, and masking the page
+ * offset will leave us with the virtual address the kernel was linked
+ * at. We subtract that from the load offset, making 'off' into the
+ * value which, when added to a virtual address in an elf header,
+ * translates it to a physical address. We do the va->pa conversion on
+ * the entry point address in the header now, so that later we can
+ * launch the kernel by just jumping to that address.
+ *
+ * When booting from UEFI the copyin and copyout functions handle
+ * adjusting the location relative to the first virtual address.
+ * Because of this there is no need to adjust the offset or entry
+ * point address as these will both be handled by the efi code.
+ */
+ off -= ehdr->e_entry & ~PAGE_MASK;
+ ehdr->e_entry += off;
+#ifdef ELF_VERBOSE
+ printf("ehdr->e_entry 0x%08x, va<->pa off %llx\n", ehdr->e_entry, off);
+#endif
+#else
+ off = 0; /* other archs use direct mapped kernels */
+#endif
+ }
+ ef->off = off;
+
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ /* use entry address from header */
+ fp->f_addr = ehdr->e_entry;
+ }
+
+ if (ef->kernel)
+ __elfN(relocation_offset) = off;
+
+ if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: program header not within first page\n");
+ goto out;
+ }
+ phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff);
+
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ /* We want to load PT_LOAD segments only.. */
+ if (phdr[i].p_type != PT_LOAD)
+ continue;
+
+#ifdef ELF_VERBOSE
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx",
+ (long)phdr[i].p_filesz, (long)phdr[i].p_offset,
+ (long)(phdr[i].p_paddr + off),
+ (long)(phdr[i].p_paddr + off + phdr[i].p_memsz - 1));
+ } else {
+ printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx",
+ (long)phdr[i].p_filesz, (long)phdr[i].p_offset,
+ (long)(phdr[i].p_vaddr + off),
+ (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
+ }
+#else
+ if ((phdr[i].p_flags & PF_W) == 0) {
+ printf("text=0x%lx ", (long)phdr[i].p_filesz);
+ } else {
+ printf("data=0x%lx", (long)phdr[i].p_filesz);
+ if (phdr[i].p_filesz < phdr[i].p_memsz)
+ printf("+0x%lx", (long)(phdr[i].p_memsz -phdr[i].p_filesz));
+ printf(" ");
+ }
+#endif
+ fpcopy = 0;
+ if (ef->firstlen > phdr[i].p_offset) {
+ fpcopy = ef->firstlen - phdr[i].p_offset;
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ archsw.arch_copyin(ef->firstpage + phdr[i].p_offset,
+ phdr[i].p_paddr + off, fpcopy);
+ } else {
+ archsw.arch_copyin(ef->firstpage + phdr[i].p_offset,
+ phdr[i].p_vaddr + off, fpcopy);
+ }
+ }
+ if (phdr[i].p_filesz > fpcopy) {
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ if (kern_pread(ef->fd, phdr[i].p_paddr + off + fpcopy,
+ phdr[i].p_filesz - fpcopy,
+ phdr[i].p_offset + fpcopy) != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_loadimage: read failed\n");
+ goto out;
+ }
+ } else {
+ if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy,
+ phdr[i].p_filesz - fpcopy,
+ phdr[i].p_offset + fpcopy) != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_loadimage: read failed\n");
+ goto out;
+ }
+ }
+ }
+ /* clear space from oversized segments; eg: bss */
+ if (phdr[i].p_filesz < phdr[i].p_memsz) {
+#ifdef ELF_VERBOSE
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ printf(" (bss: 0x%lx-0x%lx)",
+ (long)(phdr[i].p_paddr + off + phdr[i].p_filesz),
+ (long)(phdr[i].p_paddr + off + phdr[i].p_memsz - 1));
+ } else {
+ printf(" (bss: 0x%lx-0x%lx)",
+ (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz),
+ (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
+ }
+#endif
+
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ kern_bzero(phdr[i].p_paddr + off + phdr[i].p_filesz,
+ phdr[i].p_memsz - phdr[i].p_filesz);
+ } else {
+ kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz,
+ phdr[i].p_memsz - phdr[i].p_filesz);
+ }
+ }
+#ifdef ELF_VERBOSE
+ printf("\n");
+#endif
+
+ if (archsw.arch_loadseg != NULL)
+ archsw.arch_loadseg(ehdr, phdr + i, off);
+
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) {
+ if (firstaddr == 0 || firstaddr > (phdr[i].p_paddr + off))
+ firstaddr = phdr[i].p_paddr + off;
+ if (lastaddr == 0 ||
+ lastaddr < (phdr[i].p_paddr + off + phdr[i].p_memsz))
+ lastaddr = phdr[i].p_paddr + off + phdr[i].p_memsz;
+ } else {
+ if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off))
+ firstaddr = phdr[i].p_vaddr + off;
+ if (lastaddr == 0 ||
+ lastaddr < (phdr[i].p_vaddr + off + phdr[i].p_memsz))
+ lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz;
+ }
+ }
+ lastaddr = roundup(lastaddr, sizeof(long));
+
+ /*
+ * Get the section headers. We need this for finding the .ctors
+ * section as well as for loading any symbols. Both may be hard
+ * to do if reading from a .gz file as it involves seeking. I
+ * think the rule is going to have to be that you must strip a
+ * file to remove symbols before gzipping it.
+ */
+ chunk = ehdr->e_shnum * ehdr->e_shentsize;
+ if (chunk == 0 || ehdr->e_shoff == 0)
+ goto nosyms;
+ shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk);
+ if (shdr == NULL) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_loadimage: failed to read section headers");
+ goto nosyms;
+ }
+ file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);
+
+ /*
+ * Read the section string table and look for the .ctors section.
+ * We need to tell the kernel where it is so that it can call the
+ * ctors.
+ */
+ chunk = shdr[ehdr->e_shstrndx].sh_size;
+ if (chunk) {
+ shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, chunk);
+ if (shstr) {
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (strcmp(shstr + shdr[i].sh_name, ".ctors") != 0)
+ continue;
+ ctors = shdr[i].sh_addr;
+ file_addmetadata(fp, MODINFOMD_CTORS_ADDR, sizeof(ctors),
+ &ctors);
+ size = shdr[i].sh_size;
+ file_addmetadata(fp, MODINFOMD_CTORS_SIZE, sizeof(size),
+ &size);
+ break;
+ }
+ free(shstr);
+ }
+ }
+
+ /*
+ * Now load any symbols.
+ */
+ symtabindex = -1;
+ symstrindex = -1;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (shdr[i].sh_type != SHT_SYMTAB)
+ continue;
+ for (j = 0; j < ehdr->e_phnum; j++) {
+ if (phdr[j].p_type != PT_LOAD)
+ continue;
+ if (shdr[i].sh_offset >= phdr[j].p_offset &&
+ (shdr[i].sh_offset + shdr[i].sh_size <=
+ phdr[j].p_offset + phdr[j].p_filesz)) {
+ shdr[i].sh_offset = 0;
+ shdr[i].sh_size = 0;
+ break;
+ }
+ }
+ if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0)
+ continue; /* alread loaded in a PT_LOAD above */
+ /* Save it for loading below */
+ symtabindex = i;
+ symstrindex = shdr[i].sh_link;
+ }
+ if (symtabindex < 0 || symstrindex < 0)
+ goto nosyms;
+
+ /* Ok, committed to a load. */
+#ifndef ELF_VERBOSE
+ printf("syms=[");
+#endif
+ ssym = lastaddr;
+ for (i = symtabindex; i >= 0; i = symstrindex) {
+#ifdef ELF_VERBOSE
+ char *secname;
+
+ switch(shdr[i].sh_type) {
+ case SHT_SYMTAB: /* Symbol table */
+ secname = "symtab";
+ break;
+ case SHT_STRTAB: /* String table */
+ secname = "strtab";
+ break;
+ default:
+ secname = "WHOA!!";
+ break;
+ }
+#endif
+
+ size = shdr[i].sh_size;
+ archsw.arch_copyin(&size, lastaddr, sizeof(size));
+ lastaddr += sizeof(size);
+
+#ifdef ELF_VERBOSE
+ printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname,
+ (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset,
+ (uintmax_t)lastaddr, (uintmax_t)(lastaddr + shdr[i].sh_size));
+#else
+ if (i == symstrindex)
+ printf("+");
+ printf("0x%lx+0x%lx", (long)sizeof(size), (long)size);
+#endif
+
+ if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not seek for symbols - skipped!");
+ lastaddr = ssym;
+ ssym = 0;
+ goto nosyms;
+ }
+ result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size);
+ if (result < 0 || (size_t)result != shdr[i].sh_size) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped! (%ju != %ju)", (uintmax_t)result,
+ (uintmax_t)shdr[i].sh_size);
+ lastaddr = ssym;
+ ssym = 0;
+ goto nosyms;
+ }
+ /* Reset offsets relative to ssym */
+ lastaddr += shdr[i].sh_size;
+ lastaddr = roundup(lastaddr, sizeof(size));
+ if (i == symtabindex)
+ symtabindex = -1;
+ else if (i == symstrindex)
+ symstrindex = -1;
+ }
+ esym = lastaddr;
+#ifndef ELF_VERBOSE
+ printf("]");
+#endif
+
+ file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
+ file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
+
+nosyms:
+ printf("\n");
+
+ ret = lastaddr - firstaddr;
+ if (ehdr->e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
+ fp->f_addr = firstaddr;
+
+ php = NULL;
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ if (phdr[i].p_type == PT_DYNAMIC) {
+ php = phdr + i;
+ adp = php->p_vaddr;
+ file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), &adp);
+ break;
+ }
+ }
+
+ if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */
+ goto out;
+
+ ndp = php->p_filesz / sizeof(Elf_Dyn);
+ if (ndp == 0)
+ goto out;
+ dp = malloc(php->p_filesz);
+ if (dp == NULL)
+ goto out;
+ if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
+ archsw.arch_copyout(php->p_paddr + off, dp, php->p_filesz);
+ else
+ archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz);
+
+ ef->strsz = 0;
+ for (i = 0; i < ndp; i++) {
+ if (dp[i].d_tag == 0)
+ break;
+ switch (dp[i].d_tag) {
+ case DT_HASH:
+ ef->hashtab = (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off);
+ break;
+ case DT_STRTAB:
+ ef->strtab = (char *)(uintptr_t)(dp[i].d_un.d_ptr + off);
+ break;
+ case DT_STRSZ:
+ ef->strsz = dp[i].d_un.d_val;
+ break;
+ case DT_SYMTAB:
+ ef->symtab = (Elf_Sym*)(uintptr_t)(dp[i].d_un.d_ptr + off);
+ break;
+ case DT_REL:
+ ef->rel = (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off);
+ break;
+ case DT_RELSZ:
+ ef->relsz = dp[i].d_un.d_val;
+ break;
+ case DT_RELA:
+ ef->rela = (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off);
+ break;
+ case DT_RELASZ:
+ ef->relasz = dp[i].d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+ if (ef->hashtab == NULL || ef->symtab == NULL ||
+ ef->strtab == NULL || ef->strsz == 0)
+ goto out;
+ COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets));
+ COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains));
+ ef->buckets = ef->hashtab + 2;
+ ef->chains = ef->buckets + ef->nbuckets;
+
+ if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0)
+ return 0;
+ p_start = sym.st_value + ef->off;
+ if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0)
+ return ENOENT;
+ p_end = sym.st_value + ef->off;
+
+ if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0)
+ goto out;
+
+ if (ef->kernel) /* kernel must not depend on anything */
+ goto out;
+
+out:
+ if (dp)
+ free(dp);
+ if (shdr)
+ free(shdr);
+ return ret;
+}
+
+static char invalid_name[] = "bad";
+
+char *
+fake_modname(const char *name)
+{
+ const char *sp, *ep;
+ char *fp;
+ size_t len;
+
+ sp = strrchr(name, '/');
+ if (sp)
+ sp++;
+ else
+ sp = name;
+ ep = strrchr(name, '.');
+ if (ep) {
+ if (ep == name) {
+ sp = invalid_name;
+ ep = invalid_name + sizeof(invalid_name) - 1;
+ }
+ } else
+ ep = name + strlen(name);
+ len = ep - sp;
+ fp = malloc(len + 1);
+ if (fp == NULL)
+ return NULL;
+ memcpy(fp, sp, len);
+ fp[len] = '\0';
+ return fp;
+}
+
+#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
+struct mod_metadata64 {
+ int md_version; /* structure version MDTV_* */
+ int md_type; /* type of entry MDT_* */
+ u_int64_t md_data; /* specific data */
+ u_int64_t md_cval; /* common string label */
+};
+#endif
+#if defined(__amd64__) && __ELF_WORD_SIZE == 32
+struct mod_metadata32 {
+ int md_version; /* structure version MDTV_* */
+ int md_type; /* type of entry MDT_* */
+ u_int32_t md_data; /* specific data */
+ u_int32_t md_cval; /* common string label */
+};
+#endif
+
+int
+__elfN(load_modmetadata)(struct preloaded_file *fp, u_int64_t dest)
+{
+ struct elf_file ef;
+ int err, i, j;
+ Elf_Shdr *sh_meta, *shdr = NULL;
+ Elf_Shdr *sh_data[2];
+ char *shstrtab = NULL;
+ size_t size;
+ Elf_Addr p_start, p_end;
+
+ bzero(&ef, sizeof(struct elf_file));
+ ef.fd = -1;
+
+ err = __elfN(load_elf_header)(fp->f_name, &ef);
+ if (err != 0)
+ goto out;
+
+ if (ef.kernel == 1 || ef.ehdr->e_type == ET_EXEC) {
+ ef.kernel = 1;
+ } else if (ef.ehdr->e_type != ET_DYN) {
+ err = EFTYPE;
+ goto out;
+ }
+
+ size = ef.ehdr->e_shnum * ef.ehdr->e_shentsize;
+ shdr = alloc_pread(ef.fd, ef.ehdr->e_shoff, size);
+ if (shdr == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+
+ /* Load shstrtab. */
+ shstrtab = alloc_pread(ef.fd, shdr[ef.ehdr->e_shstrndx].sh_offset,
+ shdr[ef.ehdr->e_shstrndx].sh_size);
+ if (shstrtab == NULL) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to load shstrtab\n");
+ err = EFTYPE;
+ goto out;
+ }
+
+ /* Find set_modmetadata_set and data sections. */
+ sh_data[0] = sh_data[1] = sh_meta = NULL;
+ for (i = 0, j = 0; i < ef.ehdr->e_shnum; i++) {
+ if (strcmp(&shstrtab[shdr[i].sh_name],
+ "set_modmetadata_set") == 0) {
+ sh_meta = &shdr[i];
+ }
+ if ((strcmp(&shstrtab[shdr[i].sh_name], ".data") == 0) ||
+ (strcmp(&shstrtab[shdr[i].sh_name], ".rodata") == 0)) {
+ sh_data[j++] = &shdr[i];
+ }
+ }
+ if (sh_meta == NULL || sh_data[0] == NULL || sh_data[1] == NULL) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to find set_modmetadata_set or data sections\n");
+ err = EFTYPE;
+ goto out;
+ }
+
+ /* Load set_modmetadata_set into memory */
+ err = kern_pread(ef.fd, dest, sh_meta->sh_size, sh_meta->sh_offset);
+ if (err != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to load set_modmetadata_set: %d\n", err);
+ goto out;
+ }
+ p_start = dest;
+ p_end = dest + sh_meta->sh_size;
+ dest += sh_meta->sh_size;
+
+ /* Load data sections into memory. */
+ err = kern_pread(ef.fd, dest, sh_data[0]->sh_size,
+ sh_data[0]->sh_offset);
+ if (err != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to load data: %d\n", err);
+ goto out;
+ }
+
+ /*
+ * We have to increment the dest, so that the offset is the same into
+ * both the .rodata and .data sections.
+ */
+ ef.off = -(sh_data[0]->sh_addr - dest);
+ dest += (sh_data[1]->sh_addr - sh_data[0]->sh_addr);
+
+ err = kern_pread(ef.fd, dest, sh_data[1]->sh_size,
+ sh_data[1]->sh_offset);
+ if (err != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to load data: %d\n", err);
+ goto out;
+ }
+
+ err = __elfN(parse_modmetadata)(fp, &ef, p_start, p_end);
+ if (err != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "load_modmetadata: unable to parse metadata: %d\n", err);
+ goto out;
+ }
+
+out:
+ if (shstrtab != NULL)
+ free(shstrtab);
+ if (shdr != NULL)
+ free(shdr);
+ if (ef.firstpage != NULL)
+ free(ef.firstpage);
+ if (ef.fd != -1)
+ close(ef.fd);
+ return (err);
+}
+
+int
+__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
+ Elf_Addr p_start, Elf_Addr p_end)
+{
+ struct mod_metadata md;
+#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
+ struct mod_metadata64 md64;
+#elif defined(__amd64__) && __ELF_WORD_SIZE == 32
+ struct mod_metadata32 md32;
+#endif
+ struct mod_depend *mdepend;
+ struct mod_version mver;
+ char *s;
+ int error, modcnt, minfolen;
+ Elf_Addr v, p;
+
+ modcnt = 0;
+ p = p_start;
+ while (p < p_end) {
+ COPYOUT(p, &v, sizeof(v));
+ error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
+ if (error == EOPNOTSUPP)
+ v += ef->off;
+ else if (error != 0)
+ return (error);
+#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
+ COPYOUT(v, &md64, sizeof(md64));
+ error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64));
+ if (error == EOPNOTSUPP) {
+ md64.md_cval += ef->off;
+ md64.md_data += ef->off;
+ } else if (error != 0)
+ return (error);
+ md.md_version = md64.md_version;
+ md.md_type = md64.md_type;
+ md.md_cval = (const char *)(uintptr_t)md64.md_cval;
+ md.md_data = (void *)(uintptr_t)md64.md_data;
+#elif defined(__amd64__) && __ELF_WORD_SIZE == 32
+ COPYOUT(v, &md32, sizeof(md32));
+ error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32));
+ if (error == EOPNOTSUPP) {
+ md32.md_cval += ef->off;
+ md32.md_data += ef->off;
+ } else if (error != 0)
+ return (error);
+ md.md_version = md32.md_version;
+ md.md_type = md32.md_type;
+ md.md_cval = (const char *)(uintptr_t)md32.md_cval;
+ md.md_data = (void *)(uintptr_t)md32.md_data;
+#else
+ COPYOUT(v, &md, sizeof(md));
+ error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md));
+ if (error == EOPNOTSUPP) {
+ md.md_cval += ef->off;
+ md.md_data = (void *)((uintptr_t)md.md_data + (uintptr_t)ef->off);
+ } else if (error != 0)
+ return (error);
+#endif
+ p += sizeof(Elf_Addr);
+ switch(md.md_type) {
+ case MDT_DEPEND:
+ if (ef->kernel) /* kernel must not depend on anything */
+ break;
+ s = strdupout((vm_offset_t)md.md_cval);
+ minfolen = sizeof(*mdepend) + strlen(s) + 1;
+ mdepend = malloc(minfolen);
+ if (mdepend == NULL)
+ return ENOMEM;
+ COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof(*mdepend));
+ strcpy((char*)(mdepend + 1), s);
+ free(s);
+ file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend);
+ free(mdepend);
+ break;
+ case MDT_VERSION:
+ s = strdupout((vm_offset_t)md.md_cval);
+ COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver));
+ file_addmodule(fp, s, mver.mv_version, NULL);
+ free(s);
+ modcnt++;
+ break;
+ }
+ }
+ if (modcnt == 0) {
+ s = fake_modname(fp->f_name);
+ file_addmodule(fp, s, 1, NULL);
+ free(s);
+ }
+ return 0;
+}
+
+static unsigned long
+elf_hash(const char *name)
+{
+ const unsigned char *p = (const unsigned char *) name;
+ unsigned long h = 0;
+ unsigned long g;
+
+ while (*p != '\0') {
+ h = (h << 4) + *p++;
+ if ((g = h & 0xf0000000) != 0)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ return h;
+}
+
+static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) "_lookup_symbol: corrupt symbol table\n";
+int
+__elfN(lookup_symbol)(struct preloaded_file *fp __unused, elf_file_t ef,
+ const char* name, Elf_Sym *symp)
+{
+ Elf_Hashelt symnum;
+ Elf_Sym sym;
+ char *strp;
+ unsigned long hash;
+
+ hash = elf_hash(name);
+ COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum));
+
+ while (symnum != STN_UNDEF) {
+ if (symnum >= ef->nchains) {
+ printf(__elfN(bad_symtable));
+ return ENOENT;
+ }
+
+ COPYOUT(ef->symtab + symnum, &sym, sizeof(sym));
+ if (sym.st_name == 0) {
+ printf(__elfN(bad_symtable));
+ return ENOENT;
+ }
+
+ strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name));
+ if (strcmp(name, strp) == 0) {
+ free(strp);
+ if (sym.st_shndx != SHN_UNDEF ||
+ (sym.st_value != 0 &&
+ ELF_ST_TYPE(sym.st_info) == STT_FUNC)) {
+ *symp = sym;
+ return 0;
+ }
+ return ENOENT;
+ }
+ free(strp);
+ COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum));
+ }
+ return ENOENT;
+}
+
+/*
+ * Apply any intra-module relocations to the value. p is the load address
+ * of the value and val/len is the value to be modified. This does NOT modify
+ * the image in-place, because this is done by kern_linker later on.
+ *
+ * Returns EOPNOTSUPP if no relocation method is supplied.
+ */
+static int
+__elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
+ Elf_Addr p, void *val, size_t len)
+{
+ size_t n;
+ Elf_Rela a;
+ Elf_Rel r;
+ int error;
+
+ (void)mp;
+ /*
+ * The kernel is already relocated, but we still want to apply
+ * offset adjustments.
+ */
+ if (ef->kernel)
+ return (EOPNOTSUPP);
+
+ for (n = 0; n < ef->relsz / sizeof(r); n++) {
+ COPYOUT(ef->rel + n, &r, sizeof(r));
+
+ error = __elfN(reloc)(ef, __elfN(symaddr), &r, ELF_RELOC_REL,
+ ef->off, p, val, len);
+ if (error != 0)
+ return (error);
+ }
+ for (n = 0; n < ef->relasz / sizeof(a); n++) {
+ COPYOUT(ef->rela + n, &a, sizeof(a));
+
+ error = __elfN(reloc)(ef, __elfN(symaddr), &a, ELF_RELOC_RELA,
+ ef->off, p, val, len);
+ if (error != 0)
+ return (error);
+ }
+
+ return (0);
+}
+
+static Elf_Addr
+__elfN(symaddr)(struct elf_file *ef __unused, Elf_Size symidx __unused)
+{
+ /* Symbol lookup by index not required here. */
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/common/load_elf32.c b/usr/src/boot/sys/boot/common/load_elf32.c
new file mode 100644
index 0000000000..0c9f460d48
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf32.c
@@ -0,0 +1,7 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 32
+#define _MACHINE_ELF_WANT_32BIT
+
+#include "load_elf.c"
diff --git a/usr/src/boot/sys/boot/common/load_elf32_obj.c b/usr/src/boot/sys/boot/common/load_elf32_obj.c
new file mode 100644
index 0000000000..94b0896188
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf32_obj.c
@@ -0,0 +1,7 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 32
+#define _MACHINE_ELF_WANT_32BIT
+
+#include "load_elf_obj.c"
diff --git a/usr/src/boot/sys/boot/common/load_elf64.c b/usr/src/boot/sys/boot/common/load_elf64.c
new file mode 100644
index 0000000000..c29e8e3596
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf64.c
@@ -0,0 +1,6 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include "load_elf.c"
diff --git a/usr/src/boot/sys/boot/common/load_elf64_obj.c b/usr/src/boot/sys/boot/common/load_elf64_obj.c
new file mode 100644
index 0000000000..3c9371ba01
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf64_obj.c
@@ -0,0 +1,6 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include "load_elf_obj.c"
diff --git a/usr/src/boot/sys/boot/common/load_elf_obj.c b/usr/src/boot/sys/boot/common/load_elf_obj.c
new file mode 100644
index 0000000000..f32388e170
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/load_elf_obj.c
@@ -0,0 +1,535 @@
+/*-
+ * Copyright (c) 2004 Ian Dowse <iedowse@freebsd.org>
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998 Peter Wemm <peter@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <inttypes.h>
+#include <string.h>
+#include <machine/elf.h>
+#include <stand.h>
+#define FREEBSD_ELF
+#include <link.h>
+
+#include "bootstrap.h"
+
+#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l)
+
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+#undef ELF_TARG_CLASS
+#undef ELF_TARG_MACH
+#define ELF_TARG_CLASS ELFCLASS64
+#define ELF_TARG_MACH EM_X86_64
+#endif
+
+typedef struct elf_file {
+ Elf_Ehdr hdr;
+ Elf_Shdr *e_shdr;
+
+ int symtabindex; /* Index of symbol table */
+ int shstrindex; /* Index of section name string table */
+
+ int fd;
+ vm_offset_t off;
+} *elf_file_t;
+
+static int __elfN(obj_loadimage)(struct preloaded_file *mp, elf_file_t ef,
+ u_int64_t loadaddr);
+static int __elfN(obj_lookup_set)(struct preloaded_file *mp, elf_file_t ef,
+ const char *name, Elf_Addr *startp, Elf_Addr *stopp, int *countp);
+static int __elfN(obj_reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
+ Elf_Addr p, void *val, size_t len);
+static int __elfN(obj_parse_modmetadata)(struct preloaded_file *mp,
+ elf_file_t ef);
+static Elf_Addr __elfN(obj_symaddr)(struct elf_file *ef, Elf_Size symidx);
+
+const char *__elfN(obj_kerneltype) = "elf kernel";
+const char *__elfN(obj_moduletype) = "elf obj module";
+
+/*
+ * Attempt to load the file (file) as an ELF module. It will be stored at
+ * (dest), and a pointer to a module structure describing the loaded object
+ * will be saved in (result).
+ */
+int
+__elfN(obj_loadfile)(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ struct preloaded_file *fp, *kfp;
+ struct elf_file ef;
+ Elf_Ehdr *hdr;
+ int err;
+ ssize_t bytes_read;
+
+ fp = NULL;
+ bzero(&ef, sizeof(struct elf_file));
+
+ /*
+ * Open the image, read and validate the ELF header
+ */
+ if (filename == NULL) /* can't handle nameless */
+ return(EFTYPE);
+ if ((ef.fd = open(filename, O_RDONLY)) == -1)
+ return(errno);
+
+ hdr = &ef.hdr;
+ bytes_read = read(ef.fd, hdr, sizeof(*hdr));
+ if (bytes_read != sizeof(*hdr)) {
+ err = EFTYPE; /* could be EIO, but may be small file */
+ goto oerr;
+ }
+
+ /* Is it ELF? */
+ if (!IS_ELF(*hdr)) {
+ err = EFTYPE;
+ goto oerr;
+ }
+ if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
+ hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
+ hdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */
+ hdr->e_version != EV_CURRENT ||
+ hdr->e_machine != ELF_TARG_MACH || /* Machine ? */
+ hdr->e_type != ET_REL) {
+ err = EFTYPE;
+ goto oerr;
+ }
+
+ if (hdr->e_shnum * hdr->e_shentsize == 0 || hdr->e_shoff == 0 ||
+ hdr->e_shentsize != sizeof(Elf_Shdr)) {
+ err = EFTYPE;
+ goto oerr;
+ }
+
+ kfp = file_findfile(NULL, __elfN(obj_kerneltype));
+ if (kfp == NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadfile: can't load module before kernel\n");
+ err = EPERM;
+ goto oerr;
+ }
+
+ if (archsw.arch_loadaddr != NULL)
+ dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest);
+ else
+ dest = roundup(dest, PAGE_SIZE);
+
+ /*
+ * Ok, we think we should handle this.
+ */
+ fp = file_alloc();
+ if (fp == NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadfile: cannot allocate module info\n");
+ err = EPERM;
+ goto out;
+ }
+ fp->f_name = strdup(filename);
+ fp->f_type = strdup(__elfN(obj_moduletype));
+
+ printf("%s ", filename);
+
+ fp->f_size = __elfN(obj_loadimage)(fp, &ef, dest);
+ if (fp->f_size == 0 || fp->f_addr == 0)
+ goto ioerr;
+
+ /* save exec header as metadata */
+ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*hdr), hdr);
+
+ /* Load OK, return module pointer */
+ *result = (struct preloaded_file *)fp;
+ err = 0;
+ goto out;
+
+ioerr:
+ err = EIO;
+oerr:
+ file_discard(fp);
+out:
+ close(ef.fd);
+ if (ef.e_shdr != NULL)
+ free(ef.e_shdr);
+
+ return(err);
+}
+
+/*
+ * With the file (fd) open on the image, and (ehdr) containing
+ * the Elf header, load the image at (off)
+ */
+static int
+__elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *shdr, *cshdr, *lshdr;
+ vm_offset_t firstaddr, lastaddr;
+ int i, nsym, res, ret, shdrbytes, symstrindex;
+
+ ret = 0;
+ firstaddr = lastaddr = (vm_offset_t)off;
+ hdr = &ef->hdr;
+ ef->off = (vm_offset_t)off;
+
+ /* Read in the section headers. */
+ shdrbytes = hdr->e_shnum * hdr->e_shentsize;
+ shdr = alloc_pread(ef->fd, (off_t)hdr->e_shoff, shdrbytes);
+ if (shdr == NULL) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadimage: read section headers failed\n");
+ goto out;
+ }
+ ef->e_shdr = shdr;
+
+ /*
+ * Decide where to load everything, but don't read it yet.
+ * We store the load address as a non-zero sh_addr value.
+ * Start with the code/data and bss.
+ */
+ for (i = 0; i < hdr->e_shnum; i++)
+ shdr[i].sh_addr = 0;
+ for (i = 0; i < hdr->e_shnum; i++) {
+ if (shdr[i].sh_size == 0)
+ continue;
+ switch (shdr[i].sh_type) {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ lastaddr = roundup(lastaddr, shdr[i].sh_addralign);
+ shdr[i].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[i].sh_size;
+ break;
+ }
+ }
+
+ /* Symbols. */
+ nsym = 0;
+ for (i = 0; i < hdr->e_shnum; i++) {
+ switch (shdr[i].sh_type) {
+ case SHT_SYMTAB:
+ nsym++;
+ ef->symtabindex = i;
+ shdr[i].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[i].sh_size;
+ break;
+ }
+ }
+ if (nsym != 1) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadimage: file has no valid symbol table\n");
+ goto out;
+ }
+ lastaddr = roundup(lastaddr, shdr[ef->symtabindex].sh_addralign);
+ shdr[ef->symtabindex].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[ef->symtabindex].sh_size;
+
+ symstrindex = shdr[ef->symtabindex].sh_link;
+ if (symstrindex < 0 || symstrindex >= hdr->e_shnum ||
+ shdr[symstrindex].sh_type != SHT_STRTAB) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadimage: file has invalid symbol strings\n");
+ goto out;
+ }
+ lastaddr = roundup(lastaddr, shdr[symstrindex].sh_addralign);
+ shdr[symstrindex].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[symstrindex].sh_size;
+
+ /* Section names. */
+ if (hdr->e_shstrndx == 0 || hdr->e_shstrndx >= hdr->e_shnum ||
+ shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadimage: file has no section names\n");
+ goto out;
+ }
+ ef->shstrindex = hdr->e_shstrndx;
+ lastaddr = roundup(lastaddr, shdr[ef->shstrindex].sh_addralign);
+ shdr[ef->shstrindex].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[ef->shstrindex].sh_size;
+
+ /* Relocation tables. */
+ for (i = 0; i < hdr->e_shnum; i++) {
+ switch (shdr[i].sh_type) {
+ case SHT_REL:
+ case SHT_RELA:
+ lastaddr = roundup(lastaddr, shdr[i].sh_addralign);
+ shdr[i].sh_addr = (Elf_Addr)lastaddr;
+ lastaddr += shdr[i].sh_size;
+ break;
+ }
+ }
+
+ /* Clear the whole area, including bss regions. */
+ kern_bzero(firstaddr, lastaddr - firstaddr);
+
+ /* Figure section with the lowest file offset we haven't loaded yet. */
+ for (cshdr = NULL; /* none */; /* none */)
+ {
+ /*
+ * Find next section to load. The complexity of this loop is
+ * O(n^2), but with the number of sections being typically
+ * small, we do not care.
+ */
+ lshdr = cshdr;
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ if (shdr[i].sh_addr == 0 ||
+ shdr[i].sh_type == SHT_NOBITS)
+ continue;
+ /* Skip sections that were loaded already. */
+ if (lshdr != NULL &&
+ lshdr->sh_offset >= shdr[i].sh_offset)
+ continue;
+ /* Find section with smallest offset. */
+ if (cshdr == lshdr ||
+ cshdr->sh_offset > shdr[i].sh_offset)
+ cshdr = &shdr[i];
+ }
+
+ if (cshdr == lshdr)
+ break;
+
+ if (kern_pread(ef->fd, (vm_offset_t)cshdr->sh_addr,
+ cshdr->sh_size, (off_t)cshdr->sh_offset) != 0) {
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
+ "_obj_loadimage: read failed\n");
+ goto out;
+ }
+ }
+
+ file_addmetadata(fp, MODINFOMD_SHDR, shdrbytes, shdr);
+
+ res = __elfN(obj_parse_modmetadata)(fp, ef);
+ if (res != 0)
+ goto out;
+
+ ret = lastaddr - firstaddr;
+ fp->f_addr = firstaddr;
+
+ printf("size 0x%lx at 0x%lx", (u_long)ret, (u_long)firstaddr);
+
+out:
+ printf("\n");
+ return ret;
+}
+
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+struct mod_metadata64 {
+ int md_version; /* structure version MDTV_* */
+ int md_type; /* type of entry MDT_* */
+ u_int64_t md_data; /* specific data */
+ u_int64_t md_cval; /* common string label */
+};
+#endif
+
+int
+__elfN(obj_parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef)
+{
+ struct mod_metadata md;
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+ struct mod_metadata64 md64;
+#endif
+ struct mod_depend *mdepend;
+ struct mod_version mver;
+ char *s;
+ int error, modcnt, minfolen;
+ Elf_Addr v, p, p_stop;
+
+ if (__elfN(obj_lookup_set)(fp, ef, "modmetadata_set", &p, &p_stop,
+ &modcnt) != 0)
+ return 0;
+
+ modcnt = 0;
+ while (p < p_stop) {
+ COPYOUT(p, &v, sizeof(v));
+ error = __elfN(obj_reloc_ptr)(fp, ef, p, &v, sizeof(v));
+ if (error != 0)
+ return (error);
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+ COPYOUT(v, &md64, sizeof(md64));
+ error = __elfN(obj_reloc_ptr)(fp, ef, v, &md64, sizeof(md64));
+ if (error != 0)
+ return (error);
+ md.md_version = md64.md_version;
+ md.md_type = md64.md_type;
+ md.md_cval = (const char *)(uintptr_t)md64.md_cval;
+ md.md_data = (void *)(uintptr_t)md64.md_data;
+#else
+ COPYOUT(v, &md, sizeof(md));
+ error = __elfN(obj_reloc_ptr)(fp, ef, v, &md, sizeof(md));
+ if (error != 0)
+ return (error);
+#endif
+ p += sizeof(Elf_Addr);
+ switch(md.md_type) {
+ case MDT_DEPEND:
+ s = strdupout((vm_offset_t)md.md_cval);
+ minfolen = sizeof(*mdepend) + strlen(s) + 1;
+ mdepend = malloc(minfolen);
+ if (mdepend == NULL)
+ return ENOMEM;
+ COPYOUT((vm_offset_t)md.md_data, mdepend,
+ sizeof(*mdepend));
+ strcpy((char*)(mdepend + 1), s);
+ free(s);
+ file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen,
+ mdepend);
+ free(mdepend);
+ break;
+ case MDT_VERSION:
+ s = strdupout((vm_offset_t)md.md_cval);
+ COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver));
+ file_addmodule(fp, s, mver.mv_version, NULL);
+ free(s);
+ modcnt++;
+ break;
+ case MDT_MODULE:
+ case MDT_PNP_INFO:
+ break;
+ default:
+ printf("unknown type %d\n", md.md_type);
+ break;
+ }
+ }
+ return 0;
+}
+
+static int
+__elfN(obj_lookup_set)(struct preloaded_file *fp __unused, elf_file_t ef,
+ const char* name, Elf_Addr *startp, Elf_Addr *stopp, int *countp)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *shdr;
+ char *p;
+ vm_offset_t shstrtab;
+ int i;
+
+ hdr = &ef->hdr;
+ shdr = ef->e_shdr;
+ shstrtab = shdr[ef->shstrindex].sh_addr;
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ if (shdr[i].sh_type != SHT_PROGBITS)
+ continue;
+ if (shdr[i].sh_name == 0)
+ continue;
+ p = strdupout(shstrtab + shdr[i].sh_name);
+ if (strncmp(p, "set_", 4) == 0 && strcmp(p + 4, name) == 0) {
+ *startp = shdr[i].sh_addr;
+ *stopp = shdr[i].sh_addr + shdr[i].sh_size;
+ *countp = (*stopp - *startp) / sizeof(Elf_Addr);
+ free(p);
+ return (0);
+ }
+ free(p);
+ }
+
+ return (ESRCH);
+}
+
+/*
+ * Apply any intra-module relocations to the value. p is the load address
+ * of the value and val/len is the value to be modified. This does NOT modify
+ * the image in-place, because this is done by kern_linker later on.
+ */
+static int
+__elfN(obj_reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, Elf_Addr p,
+ void *val, size_t len)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *shdr;
+ Elf_Addr off = p;
+ Elf_Addr base;
+ Elf_Rela a, *abase;
+ Elf_Rel r, *rbase;
+ int error, i, j, nrel, nrela;
+
+ (void)mp;
+ hdr = &ef->hdr;
+ shdr = ef->e_shdr;
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ if (shdr[i].sh_type != SHT_RELA && shdr[i].sh_type != SHT_REL)
+ continue;
+ base = shdr[shdr[i].sh_info].sh_addr;
+ if (base == 0 || shdr[i].sh_addr == 0)
+ continue;
+ if (off < base || off + len > base +
+ shdr[shdr[i].sh_info].sh_size)
+ continue;
+
+ switch (shdr[i].sh_type) {
+ case SHT_RELA:
+ abase = (Elf_Rela *)(intptr_t)shdr[i].sh_addr;
+
+ nrela = shdr[i].sh_size / sizeof(Elf_Rela);
+ for (j = 0; j < nrela; j++) {
+ COPYOUT(abase + j, &a, sizeof(a));
+
+ error = __elfN(reloc)(ef, __elfN(obj_symaddr),
+ &a, ELF_RELOC_RELA, base, off, val, len);
+ if (error != 0)
+ return (error);
+ }
+ break;
+ case SHT_REL:
+ rbase = (Elf_Rel *)(intptr_t)shdr[i].sh_addr;
+
+ nrel = shdr[i].sh_size / sizeof(Elf_Rel);
+ for (j = 0; j < nrel; j++) {
+ COPYOUT(rbase + j, &r, sizeof(r));
+
+ error = __elfN(reloc)(ef, __elfN(obj_symaddr),
+ &r, ELF_RELOC_REL, base, off, val, len);
+ if (error != 0)
+ return (error);
+ }
+ break;
+ }
+ }
+ return (0);
+}
+
+/* Look up the address of a specified symbol. */
+static Elf_Addr
+__elfN(obj_symaddr)(struct elf_file *ef, Elf_Size symidx)
+{
+ Elf_Sym sym;
+ Elf_Addr base;
+
+ if (symidx >= ef->e_shdr[ef->symtabindex].sh_size / sizeof(Elf_Sym))
+ return (0);
+ COPYOUT(ef->e_shdr[ef->symtabindex].sh_addr + symidx * sizeof(Elf_Sym),
+ &sym, sizeof(sym));
+ if (sym.st_shndx == SHN_UNDEF || sym.st_shndx >= ef->hdr.e_shnum)
+ return (0);
+ base = ef->e_shdr[sym.st_shndx].sh_addr;
+ if (base == 0)
+ return (0);
+ return (base + sym.st_value);
+}
diff --git a/usr/src/boot/sys/boot/common/loader.8 b/usr/src/boot/sys/boot/common/loader.8
new file mode 100644
index 0000000000..7dff914d64
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/loader.8
@@ -0,0 +1,1097 @@
+.\" Copyright (c) 1999 Daniel C. Sobral
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 18, 2015
+.Dt LOADER 8
+.Os
+.Sh NAME
+.Nm loader
+.Nd kernel bootstrapping final stage
+.Sh DESCRIPTION
+The program called
+.Nm
+is the final stage of
+.Fx Ns 's
+kernel bootstrapping process.
+On IA32 (i386) architectures, it is a
+.Pa BTX
+client.
+It is linked statically to
+.Xr libstand 3
+and usually located in the directory
+.Pa /boot .
+.Pp
+It provides a scripting language that can be used to
+automate tasks, do pre-configuration or assist in recovery
+procedures.
+This scripting language is roughly divided in
+two main components.
+The smaller one is a set of commands
+designed for direct use by the casual user, called "builtin
+commands" for historical reasons.
+The main drive behind these commands is user-friendliness.
+The bigger component is an
+.Tn ANS
+Forth compatible Forth interpreter based on FICL, by
+.An John Sadler .
+.Pp
+During initialization,
+.Nm
+will probe for a console and set the
+.Va console
+variable, or set it to serial console
+.Pq Dq Li comconsole
+if the previous boot stage used that.
+If multiple consoles are selected, they will be listed separated by spaces.
+Then, devices are probed,
+.Va currdev
+and
+.Va loaddev
+are set, and
+.Va LINES
+is set to 24.
+Next,
+.Tn FICL
+is initialized, the builtin words are added to its vocabulary, and
+.Pa /boot/boot.4th
+is processed if it exists.
+No disk switching is possible while that file is being read.
+The inner interpreter
+.Nm
+will use with
+.Tn FICL
+is then set to
+.Ic interpret ,
+which is
+.Tn FICL Ns 's
+default.
+After that,
+.Pa /boot/loader.rc
+is processed if available, and, failing that,
+.Pa /boot/boot.conf
+is read for historical reasons.
+These files are processed through the
+.Ic include
+command, which reads all of them into memory before processing them,
+making disk changes possible.
+.Pp
+At this point, if an
+.Ic autoboot
+has not been tried, and if
+.Va autoboot_delay
+is not set to
+.Dq Li NO
+(not case sensitive), then an
+.Ic autoboot
+will be tried.
+If the system gets past this point,
+.Va prompt
+will be set and
+.Nm
+will engage interactive mode.
+Please note that historically even when
+.Va autoboot_delay
+is set to
+.Dq Li 0
+user will be able to interrupt autoboot process by pressing some key
+on the console while kernel and modules are being loaded.
+In some
+cases such behaviour may be undesirable, to prevent it set
+.Va autoboot_delay
+to
+.Dq Li -1 ,
+in this case
+.Nm
+will engage interactive mode only if
+.Ic autoboot
+has failed.
+.Sh BUILTIN COMMANDS
+In
+.Nm ,
+builtin commands take parameters from the command line.
+Presently,
+the only way to call them from a script is by using
+.Pa evaluate
+on a string.
+If an error condition occurs, an exception will be generated,
+which can be intercepted using
+.Tn ANS
+Forth exception handling
+words.
+If not intercepted, an error message will be displayed and
+the interpreter's state will be reset, emptying the stack and restoring
+interpreting mode.
+.Pp
+The builtin commands available are:
+.Pp
+.Bl -tag -width Ds -compact
+.It Ic autoboot Op Ar seconds Op Ar prompt
+Proceeds to bootstrap the system after a number of seconds, if not
+interrupted by the user.
+Displays a countdown prompt
+warning the user the system is about to be booted,
+unless interrupted by a key press.
+The kernel will be loaded first if necessary.
+Defaults to 10 seconds.
+.Pp
+.It Ic bcachestat
+Displays statistics about disk cache usage.
+For debugging only.
+.Pp
+.It Ic boot
+.It Ic boot Ar kernelname Op Cm ...
+.It Ic boot Fl flag Cm ...
+Immediately proceeds to bootstrap the system, loading the kernel
+if necessary.
+Any flags or arguments are passed to the kernel, but they
+must precede the kernel name, if a kernel name is provided.
+.Pp
+.Em WARNING :
+The behavior of this builtin is changed if
+.Xr loader.4th 8
+is loaded.
+.Pp
+.It Ic echo Xo
+.Op Fl n
+.Op Aq message
+.Xc
+Displays text on the screen.
+A new line will be printed unless
+.Fl n
+is specified.
+.Pp
+.It Ic heap
+Displays memory usage statistics.
+For debugging purposes only.
+.Pp
+.It Ic help Op topic Op subtopic
+Shows help messages read from
+.Pa /boot/loader.help .
+The special topic
+.Em index
+will list the topics available.
+.Pp
+.It Ic include Ar file Op Ar
+Process script files.
+Each file, in turn, is completely read into memory,
+and then each of its lines is passed to the command line interpreter.
+If any error is returned by the interpreter, the include
+command aborts immediately, without reading any other files, and
+returns an error itself (see
+.Sx ERRORS ) .
+.Pp
+.It Ic load Xo
+.Op Fl t Ar type
+.Ar file Cm ...
+.Xc
+Loads a kernel, kernel loadable module (kld), disk image,
+or file of opaque contents tagged as being of the type
+.Ar type .
+Kernel and modules can be either in a.out or ELF format.
+Any arguments passed after the name of the file to be loaded
+will be passed as arguments to that file.
+Use the
+.Li md_image
+type to make the kernel create a file-backed
+.Xr md 4
+disk.
+This is useful for booting from a temporary rootfs.
+Currently, argument passing does not work for the kernel.
+.Pp
+.It Ic load_geli Xo
+.Op Fl n Ar keyno
+.Ar prov Ar file
+.Xc
+Loads a
+.Xr geli 8
+encryption keyfile for the given provider name.
+The key index can be specified via
+.Ar keyno
+or will default to zero.
+.Pp
+.It Ic ls Xo
+.Op Fl l
+.Op Ar path
+.Xc
+Displays a listing of files in the directory
+.Ar path ,
+or the root directory if
+.Ar path
+is not specified.
+If
+.Fl l
+is specified, file sizes will be shown too.
+.Pp
+.It Ic lsdev Op Fl v
+Lists all of the devices from which it may be possible to load modules.
+If
+.Fl v
+is specified, more details are printed.
+.Pp
+.It Ic lsmod Op Fl v
+Displays loaded modules.
+If
+.Fl v
+is specified, more details are shown.
+.Pp
+.It Ic more Ar file Op Ar
+Display the files specified, with a pause at each
+.Va LINES
+displayed.
+.Pp
+.It Ic pnpscan Op Fl v
+Scans for Plug-and-Play devices.
+This is not functional at present.
+.Pp
+.It Ic read Xo
+.Op Fl t Ar seconds
+.Op Fl p Ar prompt
+.Op Va variable
+.Xc
+Reads a line of input from the terminal, storing it in
+.Va variable
+if specified.
+A timeout can be specified with
+.Fl t ,
+though it will be canceled at the first key pressed.
+A prompt may also be displayed through the
+.Fl p
+flag.
+.Pp
+.It Ic reboot
+Immediately reboots the system.
+.Pp
+.It Ic set Ar variable
+.It Ic set Ar variable Ns = Ns Ar value
+Set loader's environment variables.
+.Pp
+.It Ic show Op Va variable
+Displays the specified variable's value, or all variables and their
+values if
+.Va variable
+is not specified.
+.Pp
+.It Ic unload
+Remove all modules from memory.
+.Pp
+.It Ic unset Va variable
+Removes
+.Va variable
+from the environment.
+.Pp
+.It Ic \&?
+Lists available commands.
+.El
+.Ss BUILTIN ENVIRONMENT VARIABLES
+The
+.Nm
+has actually two different kinds of
+.Sq environment
+variables.
+There are ANS Forth's
+.Em environmental queries ,
+and a separate space of environment variables used by builtins, which
+are not directly available to Forth words.
+It is the latter type that this section covers.
+.Pp
+Environment variables can be set and unset through the
+.Ic set
+and
+.Ic unset
+builtins, and can have their values interactively examined through the
+use of the
+.Ic show
+builtin.
+Their values can also be accessed as described in
+.Sx BUILTIN PARSER .
+.Pp
+Notice that these environment variables are not inherited by any shell
+after the system has been booted.
+.Pp
+A few variables are set automatically by
+.Nm .
+Others can affect the behavior of either
+.Nm
+or the kernel at boot.
+Some options may require a value,
+while others define behavior just by being set.
+Both types of builtin variables are described below.
+.Bl -tag -width bootfile
+.It Va autoboot_delay
+Number of seconds
+.Ic autoboot
+will wait before booting.
+If this variable is not defined,
+.Ic autoboot
+will default to 10 seconds.
+.Pp
+If set to
+.Dq Li NO ,
+no
+.Ic autoboot
+will be automatically attempted after processing
+.Pa /boot/loader.rc ,
+though explicit
+.Ic autoboot Ns 's
+will be processed normally, defaulting to 10 seconds delay.
+.Pp
+If set to
+.Dq Li 0 ,
+no delay will be inserted, but user still will be able to interrupt
+.Ic autoboot
+process and escape into the interactive mode by pressing some key
+on the console while kernel and
+modules are being loaded.
+.Pp
+If set to
+.Dq Li -1 ,
+no delay will be inserted and
+.Nm
+will engage interactive mode only if
+.Ic autoboot
+has failed for some reason.
+.It Va boot_askname
+Instructs the kernel to prompt the user for the name of the root device
+when the kernel is booted.
+.It Va boot_cdrom
+Instructs the kernel to try to mount the root file system from CD-ROM.
+.It Va boot_ddb
+Instructs the kernel to start in the DDB debugger, rather than
+proceeding to initialize when booted.
+.It Va boot_dfltroot
+Instructs the kernel to mount the statically compiled-in root file system.
+.It Va boot_gdb
+Selects gdb-remote mode for the kernel debugger by default.
+.It Va boot_multicons
+Enables multiple console support in the kernel early on boot.
+In a running system, console configuration can be manipulated
+by the
+.Xr conscontrol 8
+utility.
+.It Va boot_mute
+All console output is suppressed when console is muted.
+In a running system, the state of console muting can be manipulated by the
+.Xr conscontrol 8
+utility.
+.It Va boot_pause
+During the device probe, pause after each line is printed.
+.It Va boot_serial
+Force the use of a serial console even when an internal console
+is present.
+.It Va boot_single
+Prevents the kernel from initiating a multi-user startup; instead,
+a single-user mode will be entered when the kernel has finished
+device probing.
+.It Va boot_verbose
+Setting this variable causes extra debugging information to be printed
+by the kernel during the boot phase.
+.It Va bootfile
+List of semicolon-separated search path for bootable kernels.
+The default is
+.Dq Li kernel .
+.It Va comconsole_speed
+Defines the speed of the serial console (i386 and amd64 only).
+If the previous boot stage indicated that a serial console is in use
+then this variable is initialized to the current speed of the console
+serial port.
+Otherwise it is set to 9600 unless this was overridden using the
+.Va BOOT_COMCONSOLE_SPEED
+variable when
+.Nm
+was compiled.
+Changes to the
+.Va comconsole_speed
+variable take effect immediately.
+.It Va comconsole_port
+Defines the base i/o port used to access console UART
+(i386 and amd64 only).
+If the variable is not set, its assumed value is 0x3F8, which
+corresponds to PC port COM1, unless overridden by
+.Va BOOT_COMCONSOLE_PORT
+variable during the compilation of
+.Nm .
+Setting the
+.Va comconsole_port
+variable automatically set
+.Va hw.uart.console
+environment variable to provide a hint to kernel for location of the console.
+Loader console is changed immediately after variable
+.Va comconsole_port
+is set.
+.It Va comconsole_pcidev
+Defines the location of a PCI device of the 'simple communication'
+class to be used as the serial console UART (i386 and amd64 only).
+The syntax of the variable is
+.Li 'bus:device:function[:bar]' ,
+where all members must be numeric, with possible
+.Li 0x
+prefix to indicate a hexadecimal value.
+The
+.Va bar
+member is optional and assumed to be 0x10 if omitted.
+The bar must decode i/o space.
+Setting the variable
+.Va comconsole_pcidev
+automatically sets the variable
+.Va comconsole_port
+to the base of the selected bar, and hint
+.Va hw.uart.console .
+Loader console is changed immediately after variable
+.Va comconsole_pcidev
+is set.
+.It Va console
+Defines the current console or consoles.
+Multiple consoles may be specified.
+In that case, the first listed console will become the default console for
+userland output (e.g.\& from
+.Xr init 8 ) .
+.It Va currdev
+Selects the default device.
+Syntax for devices is odd.
+.It Va dumpdev
+Sets the device for kernel dumps.
+This can be used to ensure that a device is configured before the corresponding
+.Va dumpdev
+directive from
+.Xr rc.conf 5
+has been processed, allowing kernel panics that happen during the early stages
+of boot to be captured.
+.It Va init_chroot
+If set to a valid directory in the root file system, it causes
+.Xr init 8
+to perform a
+.Xr chroot 2
+operation on that directory, making it the new root directory.
+That happens before entering single-user mode or multi-user
+mode (but after executing the
+.Va init_script
+if enabled).
+.It Va init_path
+Sets the list of binaries which the kernel will try to run as the initial
+process.
+The first matching binary is used.
+The default list is
+.Dq Li /sbin/init:/sbin/oinit:/sbin/init.bak:\:/rescue/init .
+.It Va init_script
+If set to a valid file name in the root file system,
+instructs
+.Xr init 8
+to run that script as the very first action,
+before doing anything else.
+Signal handling and exit code interpretation is similar to
+running the
+.Pa /etc/rc
+script.
+In particular, single-user operation is enforced
+if the script terminates with a non-zero exit code,
+or if a SIGTERM is delivered to the
+.Xr init 8
+process (PID 1).
+.It Va init_shell
+Defines the shell binary to be used for executing the various shell scripts.
+The default is
+.Dq Li /bin/sh .
+It is used for running the
+.Va init_script
+if set, as well as for the
+.Pa /etc/rc
+and
+.Pa /etc/rc.shutdown
+scripts.
+The value of the corresponding
+.Xr kenv 2
+variable is evaluated every time
+.Xr init 8
+calls a shell script, so it can be changed later on using the
+.Xr kenv 1
+utility.
+In particular, if a non-default shell is used for running an
+.Va init_script ,
+it might be desirable to have that script reset the value of
+.Va init_shell
+back to the default, so that the
+.Pa /etc/rc
+script is executed with the standard shell
+.Pa /bin/sh .
+.It Va interpret
+Has the value
+.Dq Li OK
+if the Forth's current state is interpreting.
+.It Va LINES
+Define the number of lines on the screen, to be used by the pager.
+.It Va module_path
+Sets the list of directories which will be searched for modules
+named in a load command or implicitly required by a dependency.
+The default value for this variable is
+.Dq Li /boot/kernel;/boot/modules .
+.It Va num_ide_disks
+Sets the number of IDE disks as a workaround for some problems in
+finding the root disk at boot.
+This has been deprecated in favor of
+.Va root_disk_unit .
+.It Va prompt
+Value of
+.Nm Ns 's
+prompt.
+Defaults to
+.Dq Li "${interpret}" .
+If variable
+.Va prompt
+is unset, the default prompt is
+.Ql > .
+.It Va root_disk_unit
+If the code which detects the disk unit number for the root disk is
+confused, e.g.\& by a mix of SCSI and IDE disks, or IDE disks with
+gaps in the sequence (e.g.\& no primary slave), the unit number can
+be forced by setting this variable.
+.It Va rootdev
+By default the value of
+.Va currdev
+is used to set the root file system
+when the kernel is booted.
+This can be overridden by setting
+.Va rootdev
+explicitly.
+.El
+.Pp
+Other variables are used to override kernel tunable parameters.
+The following tunables are available:
+.Bl -tag -width Va
+.It Va hw.physmem
+Limit the amount of physical memory the system will use.
+By default the size is in bytes, but the
+.Cm k , K , m , M , g
+and
+.Cm G
+suffixes
+are also accepted and indicate kilobytes, megabytes and gigabytes
+respectively.
+An invalid suffix will result in the variable being ignored by the
+kernel.
+.It Va hw.pci.host_start_mem , hw.acpi.host_start_mem
+When not otherwise constrained, this limits the memory start
+address.
+The default is 0x80000000 and should be set to at least size of the
+memory and not conflict with other resources.
+Typically, only systems without PCI bridges need to set this variable
+since PCI bridges typically constrain the memory starting address
+(and the variable is only used when bridges do not constrain this
+address).
+.It Va hw.pci.enable_io_modes
+Enable PCI resources which are left off by some BIOSes or are not
+enabled correctly by the device driver.
+Tunable value set to ON (1) by default, but this may cause problems
+with some peripherals.
+.It Va kern.maxusers
+Set the size of a number of statically allocated system tables; see
+.Xr tuning 7
+for a description of how to select an appropriate value for this
+tunable.
+When set, this tunable replaces the value declared in the kernel
+compile-time configuration file.
+.It Va kern.ipc.nmbclusters
+Set the number of mbuf clusters to be allocated.
+The value cannot be set below the default
+determined when the kernel was compiled.
+.It Va kern.ipc.nsfbufs
+Set the number of
+.Xr sendfile 2
+buffers to be allocated.
+Overrides
+.Dv NSFBUFS .
+Not all architectures use such buffers; see
+.Xr sendfile 2
+for details.
+.It Va kern.maxswzone
+Limits the amount of KVM to be used to hold swap
+metadata, which directly governs the
+maximum amount of swap the system can support,
+at the rate of approximately 200 MB of swap space
+per 1 MB of metadata.
+This value is specified in bytes of KVA space.
+If no value is provided, the system allocates
+enough memory to handle an amount of swap
+that corresponds to eight times the amount of
+physical memory present in the system.
+.Pp
+Note that swap metadata can be fragmented,
+which means that the system can run out of
+space before it reaches the theoretical limit.
+Therefore, care should be taken to not configure
+more swap than approximately half of the
+theoretical maximum.
+.Pp
+Running out of space for swap metadata can leave
+the system in an unrecoverable state.
+Therefore, you should only change
+this parameter if you need to greatly extend the
+KVM reservation for other resources such as the
+buffer cache or
+.Va kern.ipc.nmbclusters .
+Modifies kernel option
+.Dv VM_SWZONE_SIZE_MAX .
+.It Va kern.maxbcache
+Limits the amount of KVM reserved for use by the
+buffer cache, specified in bytes.
+The default maximum is 200MB on i386,
+and 400MB on amd64 and sparc64.
+This parameter is used to
+prevent the buffer cache from eating too much
+KVM in large-memory machine configurations.
+Only mess around with this parameter if you need to
+greatly extend the KVM reservation for other resources
+such as the swap zone or
+.Va kern.ipc.nmbclusters .
+Note that
+the NBUF parameter will override this limit.
+Modifies
+.Dv VM_BCACHE_SIZE_MAX .
+.It Va kern.msgbufsize
+Sets the size of the kernel message buffer.
+The default limit of 64KB is usually sufficient unless
+large amounts of trace data need to be collected
+between opportunities to examine the buffer or
+dump it to a file.
+Overrides kernel option
+.Dv MSGBUF_SIZE .
+.It Va machdep.disable_mtrrs
+Disable the use of i686 MTRRs (x86 only).
+.It Va net.inet.tcp.tcbhashsize
+Overrides the compile-time set value of
+.Dv TCBHASHSIZE
+or the preset default of 512.
+Must be a power of 2.
+.It Va twiddle_divisor
+Throttles the output of the
+.Sq twiddle
+I/O progress indicator displayed while loading the kernel and modules.
+This is useful on slow serial consoles where the time spent waiting for
+these characters to be written can add up to many seconds.
+The default is 1 (full speed); a value of 2 spins half as fast, and so on.
+.It Va vm.kmem_size
+Sets the size of kernel memory (bytes).
+This overrides the value determined when the kernel was compiled.
+Modifies
+.Dv VM_KMEM_SIZE .
+.It Va vm.kmem_size_min
+.It Va vm.kmem_size_max
+Sets the minimum and maximum (respectively) amount of kernel memory
+that will be automatically allocated by the kernel.
+These override the values determined when the kernel was compiled.
+Modifies
+.Dv VM_KMEM_SIZE_MIN
+and
+.Dv VM_KMEM_SIZE_MAX .
+.El
+.Ss BUILTIN PARSER
+When a builtin command is executed, the rest of the line is taken
+by it as arguments, and it is processed by a special parser which
+is not used for regular Forth commands.
+.Pp
+This special parser applies the following rules to the parsed text:
+.Bl -enum
+.It
+All backslash characters are preprocessed.
+.Bl -bullet
+.It
+\eb , \ef , \er , \en and \et are processed as in C.
+.It
+\es is converted to a space.
+.It
+\ev is converted to
+.Tn ASCII
+11.
+.It
+\ez is just skipped.
+Useful for things like
+.Dq \e0xf\ez\e0xf .
+.It
+\e0xN and \e0xNN are replaced by the hex N or NN.
+.It
+\eNNN is replaced by the octal NNN
+.Tn ASCII
+character.
+.It
+\e" , \e' and \e$ will escape these characters, preventing them from
+receiving special treatment in Step 2, described below.
+.It
+\e\e will be replaced with a single \e .
+.It
+In any other occurrence, backslash will just be removed.
+.El
+.It
+Every string between non-escaped quotes or double-quotes will be treated
+as a single word for the purposes of the remaining steps.
+.It
+Replace any
+.Li $VARIABLE
+or
+.Li ${VARIABLE}
+with the value of the environment variable
+.Va VARIABLE .
+.It
+Space-delimited arguments are passed to the called builtin command.
+Spaces can also be escaped through the use of \e\e .
+.El
+.Pp
+An exception to this parsing rule exists, and is described in
+.Sx BUILTINS AND FORTH .
+.Ss BUILTINS AND FORTH
+All builtin words are state-smart, immediate words.
+If interpreted, they behave exactly as described previously.
+If they are compiled, though,
+they extract their arguments from the stack instead of the command line.
+.Pp
+If compiled, the builtin words expect to find, at execution time, the
+following parameters on the stack:
+.D1 Ar addrN lenN ... addr2 len2 addr1 len1 N
+where
+.Ar addrX lenX
+are strings which will compose the command line that will be parsed
+into the builtin's arguments.
+Internally, these strings are concatenated in from 1 to N,
+with a space put between each one.
+.Pp
+If no arguments are passed, a 0
+.Em must
+be passed, even if the builtin accepts no arguments.
+.Pp
+While this behavior has benefits, it has its trade-offs.
+If the execution token of a builtin is acquired (through
+.Ic '
+or
+.Ic ['] ) ,
+and then passed to
+.Ic catch
+or
+.Ic execute ,
+the builtin behavior will depend on the system state
+.Bf Em
+at the time
+.Ic catch
+or
+.Ic execute
+is processed!
+.Ef
+This is particularly annoying for programs that want or need to
+handle exceptions.
+In this case, the use of a proxy is recommended.
+For example:
+.Dl : (boot) boot ;
+.Sh FICL
+.Tn FICL
+is a Forth interpreter written in C, in the form of a forth
+virtual machine library that can be called by C functions and vice
+versa.
+.Pp
+In
+.Nm ,
+each line read interactively is then fed to
+.Tn FICL ,
+which may call
+.Nm
+back to execute the builtin words.
+The builtin
+.Ic include
+will also feed
+.Tn FICL ,
+one line at a time.
+.Pp
+The words available to
+.Tn FICL
+can be classified into four groups.
+The
+.Tn ANS
+Forth standard words, extra
+.Tn FICL
+words, extra
+.Fx
+words, and the builtin commands;
+the latter were already described.
+The
+.Tn ANS
+Forth standard words are listed in the
+.Sx STANDARDS
+section.
+The words falling in the two other groups are described in the
+following subsections.
+.Ss FICL EXTRA WORDS
+.Bl -tag -width wid-set-super
+.It Ic .env
+.It Ic .ver
+.It Ic -roll
+.It Ic 2constant
+.It Ic >name
+.It Ic body>
+.It Ic compare
+This is the STRING word set's
+.Ic compare .
+.It Ic compile-only
+.It Ic endif
+.It Ic forget-wid
+.It Ic parse-word
+.It Ic sliteral
+This is the STRING word set's
+.Ic sliteral .
+.It Ic wid-set-super
+.It Ic w@
+.It Ic w!
+.It Ic x.
+.It Ic empty
+.It Ic cell-
+.It Ic -rot
+.El
+.Ss FREEBSD EXTRA WORDS
+.Bl -tag -width XXXXXXXX
+.It Ic \&$ Pq --
+Evaluates the remainder of the input buffer, after having printed it first.
+.It Ic \&% Pq --
+Evaluates the remainder of the input buffer under a
+.Ic catch
+exception guard.
+.It Ic .#
+Works like
+.Ic "."
+but without outputting a trailing space.
+.It Ic fclose Pq Ar fd --
+Closes a file.
+.It Ic fkey Pq Ar fd -- char
+Reads a single character from a file.
+.It Ic fload Pq Ar fd --
+Processes a file
+.Em fd .
+.It Ic fopen Pq Ar addr len mode Li -- Ar fd
+Opens a file.
+Returns a file descriptor, or \-1 in case of failure.
+The
+.Ar mode
+parameter selects whether the file is to be opened for read access, write
+access, or both.
+The constants
+.Dv O_RDONLY , O_WRONLY ,
+and
+.Dv O_RDWR
+are defined in
+.Pa /boot/support.4th ,
+indicating read only, write only, and read-write access, respectively.
+.It Xo
+.Ic fread
+.Pq Ar fd addr len -- len'
+.Xc
+Tries to read
+.Em len
+bytes from file
+.Em fd
+into buffer
+.Em addr .
+Returns the actual number of bytes read, or -1 in case of error or end of
+file.
+.It Ic heap? Pq -- Ar cells
+Return the space remaining in the dictionary heap, in cells.
+This is not related to the heap used by dynamic memory allocation words.
+.It Ic inb Pq Ar port -- char
+Reads a byte from a port.
+.It Ic key Pq -- Ar char
+Reads a single character from the console.
+.It Ic key? Pq -- Ar flag
+Returns
+.Ic true
+if there is a character available to be read from the console.
+.It Ic ms Pq Ar u --
+Waits
+.Em u
+microseconds.
+.It Ic outb Pq Ar port char --
+Writes a byte to a port.
+.It Ic seconds Pq -- Ar u
+Returns the number of seconds since midnight.
+.It Ic tib> Pq -- Ar addr len
+Returns the remainder of the input buffer as a string on the stack.
+.It Ic trace! Pq Ar flag --
+Activates or deactivates tracing.
+Does not work with
+.Ic catch .
+.El
+.Ss FREEBSD DEFINED ENVIRONMENTAL QUERIES
+.Bl -tag -width Ds
+.It arch-i386
+.Ic TRUE
+if the architecture is IA32.
+.It FreeBSD_version
+.Fx
+version at compile time.
+.It loader_version
+.Nm
+version.
+.El
+.Ss SYSTEM DOCUMENTATION
+.Sh FILES
+.Bl -tag -width /boot/defaults/loader.conf -compact
+.It Pa /boot/loader
+.Nm
+itself.
+.It Pa /boot/boot.4th
+Additional
+.Tn FICL
+initialization.
+.It Pa /boot/boot.conf
+.Nm
+bootstrapping script.
+Deprecated.
+.It Pa /boot/defaults/loader.conf
+.It Pa /boot/loader.conf
+.It Pa /boot/loader.conf.local
+.Nm
+configuration files, as described in
+.Xr loader.conf 5 .
+.It Pa /boot/loader.rc
+.Nm
+bootstrapping script.
+.It Pa /boot/loader.help
+Loaded by
+.Ic help .
+Contains the help messages.
+.El
+.Sh EXAMPLES
+Boot in single user mode:
+.Pp
+.Dl boot -s
+.Pp
+Load the kernel, a splash screen, and then autoboot in five seconds.
+Notice that a kernel must be loaded before any other
+.Ic load
+command is attempted.
+.Bd -literal -offset indent
+load kernel
+load splash_bmp
+load -t splash_image_data /boot/chuckrulez.bmp
+autoboot 5
+.Ed
+.Pp
+Set the disk unit of the root device to 2, and then boot.
+This would be needed in a system with two IDE disks,
+with the second IDE disk hardwired to ada2 instead of ada1.
+.Bd -literal -offset indent
+set root_disk_unit=2
+boot /boot/kernel/kernel
+.Ed
+.Pp
+See also:
+.Bl -tag -width /usr/share/examples/bootforth/X
+.It Pa /boot/loader.4th
+Extra builtin-like words.
+.It Pa /boot/support.4th
+.Pa loader.conf
+processing words.
+.It Pa /usr/share/examples/bootforth/
+Assorted examples.
+.El
+.Sh ERRORS
+The following values are thrown by
+.Nm :
+.Bl -tag -width XXXXX -offset indent
+.It 100
+Any type of error in the processing of a builtin.
+.It -1
+.Ic Abort
+executed.
+.It -2
+.Ic Abort"
+executed.
+.It -56
+.Ic Quit
+executed.
+.It -256
+Out of interpreting text.
+.It -257
+Need more text to succeed -- will finish on next run.
+.It -258
+.Ic Bye
+executed.
+.It -259
+Unspecified error.
+.El
+.Sh SEE ALSO
+.Xr libstand 3 ,
+.Xr loader.conf 5 ,
+.Xr tuning 7 ,
+.Xr boot 8 ,
+.Xr btxld 8
+.Sh STANDARDS
+For the purposes of ANS Forth compliance, loader is an
+.Bf Em
+ANS Forth System with Environmental Restrictions, Providing
+.Ef
+.Bf Li
+.No .( ,
+.No :noname ,
+.No ?do ,
+parse, pick, roll, refill, to, value, \e, false, true,
+.No <> ,
+.No 0<> ,
+compile\&, , erase, nip, tuck
+.Ef
+.Em and
+.Li marker
+.Bf Em
+from the Core Extensions word set, Providing the Exception Extensions
+word set, Providing the Locals Extensions word set, Providing the
+Memory-Allocation Extensions word set, Providing
+.Ef
+.Bf Li
+\&.s,
+bye, forget, see, words,
+\&[if],
+\&[else]
+.Ef
+.Em and
+.Li [then]
+.Bf Em
+from the Programming-Tools extension word set, Providing the
+Search-Order extensions word set.
+.Ef
+.Sh HISTORY
+The
+.Nm
+first appeared in
+.Fx 3.1 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+was written by
+.An Michael Smith Aq msmith@FreeBSD.org .
+.Pp
+.Tn FICL
+was written by
+.An John Sadler Aq john_sadler@alum.mit.edu .
+.Sh BUGS
+The
+.Ic expect
+and
+.Ic accept
+words will read from the input buffer instead of the console.
+The latter will be fixed, but the former will not.
diff --git a/usr/src/boot/sys/boot/common/ls.c b/usr/src/boot/sys/boot/common/ls.c
new file mode 100644
index 0000000000..81a308b880
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/ls.c
@@ -0,0 +1,204 @@
+/*
+ * $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1996
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+static char typestr[] = "?fc?d?b? ?l?s?w";
+
+static int ls_getdir(char **pathp);
+
+COMMAND_SET(ls, "ls", "list files", command_ls);
+
+static int
+command_ls(int argc, char *argv[])
+{
+ int fd;
+ struct stat sb;
+ struct dirent *d;
+ char *buf, *path;
+ char lbuf[128]; /* one line */
+ int result, ch;
+ int verbose;
+
+ result = CMD_OK;
+ fd = -1;
+ verbose = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "l")) != -1) {
+ switch(ch) {
+ case 'l':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+ argv += (optind - 1);
+ argc -= (optind - 1);
+
+ if (argc < 2) {
+ path = "";
+ } else {
+ path = argv[1];
+ }
+
+ if (stat(path, &sb) == 0 && !S_ISDIR(sb.st_mode)) {
+ if (verbose) {
+ printf(" %c %8d %s\n",
+ typestr[sb.st_mode >> 12],
+ (int)sb.st_size, path);
+ } else {
+ printf(" %c %s\n",
+ typestr[sb.st_mode >> 12], path);
+ }
+ return (CMD_OK);
+ }
+
+ fd = ls_getdir(&path);
+ if (fd == -1) {
+ result = CMD_ERROR;
+ goto out;
+ }
+ pager_open();
+ pager_output(path);
+ pager_output("\n");
+
+ while ((d = readdirfd(fd)) != NULL) {
+ if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
+ if (d->d_type == 0 || verbose) {
+ /* stat the file, if possible */
+ sb.st_size = 0;
+ sb.st_mode = 0;
+ buf = malloc(strlen(path) + strlen(d->d_name) + 2);
+ sprintf(buf, "%s/%s", path, d->d_name);
+ /* ignore return, could be symlink, etc. */
+ if (stat(buf, &sb))
+ sb.st_size = 0;
+ free(buf);
+ }
+ if (verbose) {
+ sprintf(lbuf, " %c %8d %s\n",
+ typestr[d->d_type? d->d_type:sb.st_mode >> 12],
+ (int)sb.st_size, d->d_name);
+ } else {
+ sprintf(lbuf, " %c %s\n",
+ typestr[d->d_type? d->d_type:sb.st_mode >> 12], d->d_name);
+ }
+ if (pager_output(lbuf))
+ goto out;
+ }
+ }
+ out:
+ pager_close();
+ if (fd != -1)
+ close(fd);
+ if (path != NULL)
+ free(path);
+ return(result);
+}
+
+/*
+ * Given (path) containing a vaguely reasonable path specification, return an fd
+ * on the directory, and an allocated copy of the path to the directory.
+ */
+static int
+ls_getdir(char **pathp)
+{
+ struct stat sb;
+ int fd;
+ const char *cp;
+ char *path;
+
+ fd = -1;
+
+ /* one extra byte for a possible trailing slash required */
+ path = malloc(strlen(*pathp) + 2);
+ strcpy(path, *pathp);
+
+ /* Make sure the path is respectable to begin with */
+ if (archsw.arch_getdev(NULL, path, &cp)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "bad path '%s'", path);
+ goto out;
+ }
+
+ /* If there's no path on the device, assume '/' */
+ if (*cp == 0)
+ strcat(path, "/");
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "open '%s' failed: %s", path, strerror(errno));
+ goto out;
+ }
+ if (fstat(fd, &sb) < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "stat failed: %s", strerror(errno));
+ goto out;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "%s: %s", path, strerror(ENOTDIR));
+ goto out;
+ }
+
+ *pathp = path;
+ return(fd);
+
+ out:
+ free(path);
+ *pathp = NULL;
+ if (fd != -1)
+ close(fd);
+ return(-1);
+}
diff --git a/usr/src/boot/sys/boot/common/md.c b/usr/src/boot/sys/boot/common/md.c
new file mode 100644
index 0000000000..a8f092b92b
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/md.c
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 2009 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/queue.h>
+#include <machine/stdarg.h>
+
+#include "bootstrap.h"
+
+#define MD_BLOCK_SIZE 512
+
+#ifndef MD_IMAGE_SIZE
+#error Must be compiled with MD_IMAGE_SIZE defined
+#endif
+#if (MD_IMAGE_SIZE == 0 || MD_IMAGE_SIZE % MD_BLOCK_SIZE)
+#error Image size must be a multiple of 512.
+#endif
+
+/*
+ * Preloaded image gets put here.
+ * Applications that patch the object with the image can determine
+ * the size looking at the start and end markers (strings),
+ * so we want them contiguous.
+ */
+static struct {
+ u_char start[MD_IMAGE_SIZE];
+ u_char end[128];
+} md_image = {
+ .start = "MFS Filesystem goes here",
+ .end = "MFS Filesystem had better STOP here",
+};
+
+/* devsw I/F */
+static int md_init(void);
+static int md_strategy(void *, int, daddr_t, size_t, char *, size_t *);
+static int md_open(struct open_file *, ...);
+static int md_close(struct open_file *);
+static void md_print(int);
+
+struct devsw md_dev = {
+ "md",
+ DEVT_DISK,
+ md_init,
+ md_strategy,
+ md_open,
+ md_close,
+ noioctl,
+ md_print
+};
+
+static int
+md_init(void)
+{
+
+ return (0);
+}
+
+static int
+md_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
+ size_t *rsize)
+{
+ struct devdesc *dev = (struct devdesc *)devdata;
+ size_t ofs;
+
+ if (dev->d_unit != 0)
+ return (ENXIO);
+
+ if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE))
+ return (EIO);
+
+ if (size % MD_BLOCK_SIZE)
+ return (EIO);
+
+ ofs = blk * MD_BLOCK_SIZE;
+ if ((ofs + size) > MD_IMAGE_SIZE)
+ size = MD_IMAGE_SIZE - ofs;
+
+ if (rsize != 0)
+ *rsize = size;
+
+ switch (rw) {
+ case F_READ:
+ bcopy(md_image.start + ofs, buf, size);
+ return (0);
+ case F_WRITE:
+ bcopy(buf, md_image.start + ofs, size);
+ return (0);
+ }
+
+ return (ENODEV);
+}
+
+static int
+md_open(struct open_file *f, ...)
+{
+ va_list ap;
+ struct devdesc *dev;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct devdesc *);
+ va_end(ap);
+
+ if (dev->d_unit != 0)
+ return (ENXIO);
+
+ return (0);
+}
+
+static int
+md_close(struct open_file *f)
+{
+ struct devdesc *dev;
+
+ dev = (struct devdesc *)(f->f_devdata);
+ return ((dev->d_unit != 0) ? ENXIO : 0);
+}
+
+static void
+md_print(int verbose)
+{
+
+ printf("MD (%u bytes)\n", MD_IMAGE_SIZE);
+}
diff --git a/usr/src/boot/sys/boot/common/merge_help.awk b/usr/src/boot/sys/boot/common/merge_help.awk
new file mode 100644
index 0000000000..1070f73f1f
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/merge_help.awk
@@ -0,0 +1,104 @@
+#!/usr/bin/awk -f
+#
+# $FreeBSD$
+#
+# Merge two boot loader help files for FreeBSD 3.0
+# Joe Abley <jabley@patho.gen.nz>
+
+BEGIN \
+{
+ state = 0;
+ first = -1;
+ ind = 0;
+}
+
+# beginning of first command
+/^###/ && (state == 0) \
+{
+ state = 1;
+ next;
+}
+
+# entry header
+/^# T[[:graph:]]+ (S[[:graph:]]+ )*D[[:graph:]][[:print:]]*$/ && (state == 1) \
+{
+ match($0, " T[[:graph:]]+");
+ T = substr($0, RSTART + 2, RLENGTH - 2);
+ match($0, " S[[:graph:]]+");
+ SSTART = RSTART
+ S = (RLENGTH == -1) ? "" : substr($0, RSTART + 2, RLENGTH - 2);
+ match($0, " D[[:graph:]][[:print:]]*$");
+ D = substr($0, RSTART + 2);
+ if (SSTART > RSTART)
+ S = "";
+
+ # find a suitable place to store this one...
+ ind++;
+ if (ind == 1)
+ {
+ first = ind;
+ help[ind, "T"] = T;
+ help[ind, "S"] = S;
+ help[ind, "link"] = -1;
+ } else {
+ i = first; j = -1;
+ while (help[i, "T"] help[i, "S"] < T S)
+ {
+ j = i;
+ i = help[i, "link"];
+ if (i == -1) break;
+ }
+
+ if (i == -1)
+ {
+ help[j, "link"] = ind;
+ help[ind, "link"] = -1;
+ } else {
+ help[ind, "link"] = i;
+ if (j == -1)
+ first = ind;
+ else
+ help[j, "link"] = ind;
+ }
+ }
+ help[ind, "T"] = T;
+ help[ind, "S"] = S;
+ help[ind, "D"] = D;
+
+ # set our state
+ state = 2;
+ help[ind, "text"] = 0;
+ next;
+}
+
+# end of last command, beginning of next one
+/^###/ && (state == 2) \
+{
+ state = 1;
+}
+
+(state == 2) \
+{
+ sub("[[:blank:]]+$", "");
+ if (help[ind, "text"] == 0 && $0 ~ /^[[:blank:]]*$/) next;
+ help[ind, "text", help[ind, "text"]] = $0;
+ help[ind, "text"]++;
+ next;
+}
+
+# show them what we have (it's already sorted in help[])
+END \
+{
+ node = first;
+ while (node != -1)
+ {
+ printf "################################################################################\n";
+ printf "# T%s ", help[node, "T"];
+ if (help[node, "S"] != "") printf "S%s ", help[node, "S"];
+ printf "D%s\n\n", help[node, "D"];
+ for (i = 0; i < help[node, "text"]; i++)
+ printf "%s\n", help[node, "text", i];
+ node = help[node, "link"];
+ }
+ printf "################################################################################\n";
+}
diff --git a/usr/src/boot/sys/boot/common/misc.c b/usr/src/boot/sys/boot/common/misc.c
new file mode 100644
index 0000000000..9b938afdf8
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/misc.c
@@ -0,0 +1,219 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+#include <stand.h>
+#include <bootstrap.h>
+
+/*
+ * Concatenate the (argc) elements of (argv) into a single string, and return
+ * a copy of same.
+ */
+char *
+unargv(int argc, char *argv[])
+{
+ size_t hlong;
+ int i;
+ char *cp;
+
+ for (i = 0, hlong = 0; i < argc; i++)
+ hlong += strlen(argv[i]) + 2;
+
+ if(hlong == 0)
+ return(NULL);
+
+ cp = malloc(hlong);
+ cp[0] = 0;
+ for (i = 0; i < argc; i++) {
+ strcat(cp, argv[i]);
+ if (i < (argc - 1))
+ strcat(cp, " ");
+ }
+
+ return(cp);
+}
+
+/*
+ * Get the length of a string in kernel space
+ */
+size_t
+strlenout(vm_offset_t src)
+{
+ char c;
+ size_t len;
+
+ for (len = 0; ; len++) {
+ archsw.arch_copyout(src++, &c, 1);
+ if (c == 0)
+ break;
+ }
+ return(len);
+}
+
+/*
+ * Make a duplicate copy of a string in kernel space
+ */
+char *
+strdupout(vm_offset_t str)
+{
+ char *result, *cp;
+
+ result = malloc(strlenout(str) + 1);
+ for (cp = result; ;cp++) {
+ archsw.arch_copyout(str++, cp, 1);
+ if (*cp == 0)
+ break;
+ }
+ return(result);
+}
+
+/* Zero a region in kernel space. */
+void
+kern_bzero(vm_offset_t dest, size_t len)
+{
+ char buf[256];
+ size_t chunk, resid;
+
+ bzero(buf, sizeof(buf));
+ resid = len;
+ while (resid > 0) {
+ chunk = min(sizeof(buf), resid);
+ archsw.arch_copyin(buf, dest, chunk);
+ resid -= chunk;
+ dest += chunk;
+ }
+}
+
+/*
+ * Read the specified part of a file to kernel space. Unlike regular
+ * pread, the file pointer is advanced to the end of the read data,
+ * and it just returns 0 if successful.
+ */
+int
+kern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
+{
+
+ if (lseek(fd, off, SEEK_SET) == -1) {
+#ifdef DEBUG
+ printf("\nlseek failed\n");
+#endif
+ return (-1);
+ }
+ if ((size_t)archsw.arch_readin(fd, dest, len) != len) {
+#ifdef DEBUG
+ printf("\nreadin failed\n");
+#endif
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Read the specified part of a file to a malloced buffer. The file
+ * pointer is advanced to the end of the read data.
+ */
+void *
+alloc_pread(int fd, off_t off, size_t len)
+{
+ void *buf;
+
+ buf = malloc(len);
+ if (buf == NULL) {
+#ifdef DEBUG
+ printf("\nmalloc(%d) failed\n", (int)len);
+#endif
+ return (NULL);
+ }
+ if (lseek(fd, off, SEEK_SET) == -1) {
+#ifdef DEBUG
+ printf("\nlseek failed\n");
+#endif
+ free(buf);
+ return (NULL);
+ }
+ if ((size_t)read(fd, buf, len) != len) {
+#ifdef DEBUG
+ printf("\nread failed\n");
+#endif
+ free(buf);
+ return (NULL);
+ }
+ return (buf);
+}
+
+/*
+ * Display a region in traditional hexdump format.
+ */
+void
+hexdump(caddr_t region, size_t len)
+{
+ caddr_t line;
+ int x, c;
+ char lbuf[80];
+#define emit(fmt, args...) {sprintf(lbuf, fmt , ## args); pager_output(lbuf);}
+
+ pager_open();
+ for (line = region; line < (region + len); line += 16) {
+ emit("%08lx ", (long) line);
+
+ for (x = 0; x < 16; x++) {
+ if ((line + x) < (region + len)) {
+ emit("%02x ", *(u_int8_t *)(line + x));
+ } else {
+ emit("-- ");
+ }
+ if (x == 7)
+ emit(" ");
+ }
+ emit(" |");
+ for (x = 0; x < 16; x++) {
+ if ((line + x) < (region + len)) {
+ c = *(u_int8_t *)(line + x);
+ if ((c < ' ') || (c > '~')) /* !isprint(c) */
+ c = '.';
+ emit("%c", c);
+ } else {
+ emit(" ");
+ }
+ }
+ emit("|\n");
+ }
+ pager_close();
+}
+
+void
+dev_cleanup(void)
+{
+ int i;
+
+ /* Call cleanup routines */
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+}
diff --git a/usr/src/boot/sys/boot/common/module.c b/usr/src/boot/sys/boot/common/module.c
new file mode 100644
index 0000000000..c748a8211c
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/module.c
@@ -0,0 +1,1072 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * file/module function dispatcher, support, etc.
+ */
+
+#include <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/stdint.h>
+
+#include "bootstrap.h"
+
+#define MDIR_REMOVED 0x0001
+#define MDIR_NOHINTS 0x0002
+
+struct moduledir {
+ char *d_path; /* path of modules directory */
+ u_char *d_hints; /* content of linker.hints file */
+ int d_hintsz; /* size of hints data */
+ int d_flags;
+ STAILQ_ENTRY(moduledir) d_link;
+};
+
+static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
+static int file_load_dependencies(struct preloaded_file *base_mod);
+static char * file_search(const char *name, const char **extlist);
+static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo);
+static int file_havepath(const char *name);
+static char *mod_searchmodule(char *name, struct mod_depend *verinfo);
+static void file_insert_tail(struct preloaded_file *mp);
+struct file_metadata* metadata_next(struct file_metadata *base_mp, int type);
+static void moduledir_readhints(struct moduledir *mdp);
+static void moduledir_rebuild(void);
+
+/* load address should be tweaked by first module loaded (kernel) */
+static vm_offset_t loadaddr = 0;
+
+#if defined(LOADER_FDT_SUPPORT)
+static const char *default_searchpath =
+ "/boot/kernel;/boot/modules;/boot/dtb";
+#else
+static const char *default_searchpath ="/platform/i86pc";
+#endif
+
+static STAILQ_HEAD(, moduledir) moduledir_list = STAILQ_HEAD_INITIALIZER(moduledir_list);
+
+struct preloaded_file *preloaded_files = NULL;
+
+static const char *kld_ext_list[] = {
+ ".ko",
+ "",
+ ".debug",
+ NULL
+};
+
+
+/*
+ * load an object, either a disk file or code module.
+ *
+ * To load a file, the syntax is:
+ *
+ * load -t <type> <path>
+ *
+ * code modules are loaded as:
+ *
+ * load <path> <options>
+ */
+
+COMMAND_SET(load, "load", "load a kernel or module", command_load);
+
+static int
+command_load(int argc, char *argv[])
+{
+ char *typestr;
+ int dofile, dokld, ch, error;
+
+ dokld = dofile = 0;
+ optind = 1;
+ optreset = 1;
+ typestr = NULL;
+ if (argc == 1) {
+ command_errmsg = "no filename specified";
+ return (CMD_CRIT);
+ }
+ while ((ch = getopt(argc, argv, "kt:")) != -1) {
+ switch(ch) {
+ case 'k':
+ dokld = 1;
+ break;
+ case 't':
+ typestr = optarg;
+ dofile = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return (CMD_OK);
+ }
+ }
+ argv += (optind - 1);
+ argc -= (optind - 1);
+
+ printf("Loading %s...\n", argv[1]);
+ /*
+ * Request to load a raw file?
+ */
+ if (dofile) {
+ if ((typestr == NULL) || (*typestr == 0)) {
+ command_errmsg = "invalid load type";
+ return (CMD_CRIT);
+ }
+
+ if (file_findfile(argv[1], typestr) != NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: file '%s' already loaded", argv[1]);
+ return (CMD_WARN);
+ }
+
+ if (file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1) != NULL)
+ return (CMD_OK);
+
+ /* Failing to load mfs_root is never going to end well! */
+ if (strcmp("mfs_root", typestr) == 0)
+ return (CMD_FATAL);
+
+ return (CMD_ERROR);
+ }
+ /*
+ * Do we have explicit KLD load ?
+ */
+ if (dokld || file_havepath(argv[1])) {
+ error = mod_loadkld(argv[1], argc - 2, argv + 2);
+ if (error == EEXIST) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: KLD '%s' already loaded", argv[1]);
+ return (CMD_WARN);
+ }
+
+ return (error == 0 ? CMD_OK : CMD_CRIT);
+ }
+ /*
+ * Looks like a request for a module.
+ */
+ error = mod_load(argv[1], NULL, argc - 2, argv + 2);
+ if (error == EEXIST) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: module '%s' already loaded", argv[1]);
+ return (CMD_WARN);
+ }
+
+ return (error == 0 ? CMD_OK : CMD_CRIT);
+}
+
+#ifdef __FreeBSD__
+COMMAND_SET(load_geli, "load_geli", "load a geli key", command_load_geli);
+
+static int
+command_load_geli(int argc, char *argv[])
+{
+ char typestr[80];
+ char *cp;
+ int ch, num;
+
+ if (argc < 3) {
+ command_errmsg = "usage is [-n key#] <prov> <file>";
+ return(CMD_ERROR);
+ }
+
+ num = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "n:")) != -1) {
+ switch(ch) {
+ case 'n':
+ num = strtol(optarg, &cp, 0);
+ if (cp == optarg) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "bad key index '%s'", optarg);
+ return(CMD_ERROR);
+ }
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+ argv += (optind - 1);
+ argc -= (optind - 1);
+ sprintf(typestr, "%s:geli_keyfile%d", argv[1], num);
+ return (file_loadraw(argv[2], typestr, 0, NULL, 1) ? CMD_OK : CMD_ERROR);
+}
+#endif /* __FreeBSD__ */
+
+void
+unload(void)
+{
+ struct preloaded_file *fp;
+
+ while (preloaded_files != NULL) {
+ fp = preloaded_files;
+ preloaded_files = preloaded_files->f_next;
+ file_discard(fp);
+ }
+ loadaddr = 0;
+ unsetenv("kernelname");
+}
+
+COMMAND_SET(unload, "unload", "unload all modules", command_unload);
+
+static int
+command_unload(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ unload();
+ return(CMD_OK);
+}
+
+COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
+
+static int
+command_lsmod(int argc, char *argv[])
+{
+ struct preloaded_file *fp;
+ struct kernel_module *mp;
+ struct file_metadata *md;
+ char lbuf[80];
+ int ch, verbose, ret = 0;
+
+ verbose = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch(ch) {
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+
+ pager_open();
+ for (fp = preloaded_files; fp; fp = fp->f_next) {
+ sprintf(lbuf, " %p: ", (void *) fp->f_addr);
+ pager_output(lbuf);
+ pager_output(fp->f_name);
+ sprintf(lbuf, " (%s, 0x%lx)\n", fp->f_type, (long)fp->f_size);
+ if (pager_output(lbuf))
+ break;
+ if (fp->f_args != NULL) {
+ pager_output(" args: ");
+ pager_output(fp->f_args);
+ if (pager_output("\n"))
+ break;
+ }
+ if (fp->f_modules) {
+ pager_output(" modules: ");
+ for (mp = fp->f_modules; mp; mp = mp->m_next) {
+ sprintf(lbuf, "%s.%d ", mp->m_name, mp->m_version);
+ pager_output(lbuf);
+ }
+ if (pager_output("\n"))
+ break;
+ }
+ if (verbose) {
+ /* XXX could add some formatting smarts here to display some better */
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ sprintf(lbuf, " 0x%04x, 0x%lx\n", md->md_type, (long) md->md_size);
+ if ((ret = pager_output(lbuf)))
+ break;
+ }
+ }
+ if (ret)
+ break;
+ }
+ pager_close();
+ return(CMD_OK);
+}
+
+/*
+ * File level interface, functions file_*
+ */
+int
+file_load(char *filename, vm_offset_t dest, struct preloaded_file **result)
+{
+ static int last_file_format = 0;
+ struct preloaded_file *fp;
+ int error;
+ int i;
+
+ if (archsw.arch_loadaddr != NULL)
+ dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
+
+ error = EFTYPE;
+ for (i = last_file_format, fp = NULL;
+ file_formats[i] && fp == NULL; i++) {
+ error = (file_formats[i]->l_load)(filename, dest, &fp);
+ if (error == 0) {
+ fp->f_loader = last_file_format = i; /* remember the loader */
+ *result = fp;
+ break;
+ } else if (last_file_format == i && i != 0) {
+ /* Restart from the beginning */
+ i = -1;
+ last_file_format = 0;
+ fp = NULL;
+ continue;
+ }
+ if (error == EFTYPE)
+ continue; /* Unknown to this handler? */
+ if (error) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't load file '%s': %s", filename, strerror(error));
+ break;
+ }
+ }
+ return (error);
+}
+
+static int
+file_load_dependencies(struct preloaded_file *base_file)
+{
+ struct file_metadata *md;
+ struct preloaded_file *fp;
+ struct mod_depend *verinfo;
+ struct kernel_module *mp;
+ char *dmodname;
+ int error;
+
+ md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
+ if (md == NULL)
+ return (0);
+ error = 0;
+ do {
+ verinfo = (struct mod_depend*)md->md_data;
+ dmodname = (char *)(verinfo + 1);
+ if (file_findmodule(NULL, dmodname, verinfo) == NULL) {
+ printf("loading required module '%s'\n", dmodname);
+ error = mod_load(dmodname, verinfo, 0, NULL);
+ if (error)
+ break;
+ /*
+ * If module loaded via kld name which isn't listed
+ * in the linker.hints file, we should check if it have
+ * required version.
+ */
+ mp = file_findmodule(NULL, dmodname, verinfo);
+ if (mp == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "module '%s' exists but with wrong version", dmodname);
+ error = ENOENT;
+ break;
+ }
+ }
+ md = metadata_next(md, MODINFOMD_DEPLIST);
+ } while (md);
+ if (!error)
+ return (0);
+ /* Load failed; discard everything */
+ while (base_file != NULL) {
+ fp = base_file;
+ base_file = base_file->f_next;
+ file_discard(fp);
+ }
+ return (error);
+}
+
+/*
+ * We've been asked to load (fname) as (type), so just suck it in,
+ * no arguments or anything.
+ */
+struct preloaded_file *
+file_loadraw(const char *fname, char *type, int argc, char **argv, int insert)
+{
+ struct preloaded_file *fp;
+ char *name;
+ int fd, got;
+ vm_offset_t laddr;
+
+ /* We can't load first */
+ if ((file_findfile(NULL, NULL)) == NULL) {
+ command_errmsg = "can't load file before kernel";
+ return(NULL);
+ }
+
+ /* locate the file on the load path */
+ name = file_search(fname, NULL);
+ if (name == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", fname);
+ return(NULL);
+ }
+
+ if ((fd = open(name, O_RDONLY)) < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't open '%s': %s", name, strerror(errno));
+ free(name);
+ return(NULL);
+ }
+
+ if (archsw.arch_loadaddr != NULL)
+ loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
+
+ laddr = roundup(loadaddr, PAGE_SIZE);
+ loadaddr = laddr;
+ for (;;) {
+ /* read in 4k chunks; size is not really important */
+ got = archsw.arch_readin(fd, laddr, 4096);
+ if (got == 0) /* end of file */
+ break;
+ if (got < 0) { /* error */
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "error reading '%s': %s", name, strerror(errno));
+ free(name);
+ close(fd);
+ return(NULL);
+ }
+ laddr += got;
+ }
+
+ /* Looks OK so far; create & populate control structure */
+ fp = file_alloc();
+ fp->f_name = strdup(name);
+ fp->f_args = unargv(argc, argv);
+ fp->f_type = strdup(type);
+ fp->f_metadata = NULL;
+ fp->f_loader = -1;
+ fp->f_addr = loadaddr;
+ fp->f_size = laddr - loadaddr;
+
+ /* recognise space consumption */
+ loadaddr = laddr;
+
+ /* Add to the list of loaded files */
+ if (insert != 0)
+ file_insert_tail(fp);
+ close(fd);
+ return(fp);
+}
+
+/*
+ * Load the module (name), pass it (argc),(argv), add container file
+ * to the list of loaded files.
+ * If module is already loaded just assign new argc/argv.
+ */
+int
+mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
+{
+ struct kernel_module *mp;
+ int err;
+ char *filename;
+
+ if (file_havepath(modname)) {
+ printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname);
+ return (mod_loadkld(modname, argc, argv));
+ }
+ /* see if module is already loaded */
+ mp = file_findmodule(NULL, modname, verinfo);
+ if (mp) {
+ if (mp->m_args)
+ free(mp->m_args);
+ mp->m_args = unargv(argc, argv);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: module '%s' already loaded", mp->m_name);
+ return (0);
+ }
+ /* locate file with the module on the search path */
+ filename = mod_searchmodule(modname, verinfo);
+ if (filename == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", modname);
+ return (ENOENT);
+ }
+ err = mod_loadkld(filename, argc, argv);
+ return (err);
+}
+
+/*
+ * Load specified KLD. If path is omitted, then try to locate it via
+ * search path.
+ */
+int
+mod_loadkld(const char *kldname, int argc, char *argv[])
+{
+ struct preloaded_file *fp, *last_file;
+ int err;
+ char *filename;
+
+ /*
+ * Get fully qualified KLD name
+ */
+ filename = file_search(kldname, kld_ext_list);
+ if (filename == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", kldname);
+ return (ENOENT);
+ }
+ /*
+ * Check if KLD already loaded
+ */
+ fp = file_findfile(filename, NULL);
+ if (fp) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: KLD '%s' already loaded", filename);
+ free(filename);
+ return (0);
+ }
+ for (last_file = preloaded_files;
+ last_file != NULL && last_file->f_next != NULL;
+ last_file = last_file->f_next)
+ ;
+
+ do {
+ err = file_load(filename, loadaddr, &fp);
+ if (err)
+ break;
+ fp->f_args = unargv(argc, argv);
+ loadaddr = fp->f_addr + fp->f_size;
+ file_insert_tail(fp); /* Add to the list of loaded files */
+ if (file_load_dependencies(fp) != 0) {
+ err = ENOENT;
+ last_file->f_next = NULL;
+ loadaddr = last_file->f_addr + last_file->f_size;
+ fp = NULL;
+ break;
+ }
+ } while(0);
+ if (err == EFTYPE) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "don't know how to load module '%s'", filename);
+ }
+ if (err && fp)
+ file_discard(fp);
+ free(filename);
+ return (err);
+}
+
+/*
+ * Find a file matching (name) and (type).
+ * NULL may be passed as a wildcard to either.
+ */
+struct preloaded_file *
+file_findfile(const char *name, const char *type)
+{
+ struct preloaded_file *fp;
+
+ for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
+ if (((name == NULL) || !strcmp(name, fp->f_name)) &&
+ ((type == NULL) || !strcmp(type, fp->f_type)))
+ break;
+ }
+ return (fp);
+}
+
+/*
+ * Find a module matching (name) inside of given file.
+ * NULL may be passed as a wildcard.
+ */
+struct kernel_module *
+file_findmodule(struct preloaded_file *fp, char *modname,
+ struct mod_depend *verinfo)
+{
+ struct kernel_module *mp, *best;
+ int bestver, mver;
+
+ if (fp == NULL) {
+ for (fp = preloaded_files; fp; fp = fp->f_next) {
+ mp = file_findmodule(fp, modname, verinfo);
+ if (mp)
+ return (mp);
+ }
+ return (NULL);
+ }
+ best = NULL;
+ bestver = 0;
+ for (mp = fp->f_modules; mp; mp = mp->m_next) {
+ if (strcmp(modname, mp->m_name) == 0) {
+ if (verinfo == NULL)
+ return (mp);
+ mver = mp->m_version;
+ if (mver == verinfo->md_ver_preferred)
+ return (mp);
+ if (mver >= verinfo->md_ver_minimum &&
+ mver <= verinfo->md_ver_maximum &&
+ mver > bestver) {
+ best = mp;
+ bestver = mver;
+ }
+ }
+ }
+ return (best);
+}
+/*
+ * Make a copy of (size) bytes of data from (p), and associate them as
+ * metadata of (type) to the module (mp).
+ */
+void
+file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
+{
+ struct file_metadata *md;
+
+ md = malloc(sizeof(struct file_metadata) - sizeof(md->md_data) + size);
+ md->md_size = size;
+ md->md_type = type;
+ bcopy(p, md->md_data, size);
+ md->md_next = fp->f_metadata;
+ fp->f_metadata = md;
+}
+
+/*
+ * Find a metadata object of (type) associated with the file (fp)
+ */
+struct file_metadata *
+file_findmetadata(struct preloaded_file *fp, int type)
+{
+ struct file_metadata *md;
+
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (md->md_type == type)
+ break;
+ return(md);
+}
+
+struct file_metadata *
+metadata_next(struct file_metadata *md, int type)
+{
+ if (md == NULL)
+ return (NULL);
+ while((md = md->md_next) != NULL)
+ if (md->md_type == type)
+ break;
+ return (md);
+}
+
+static const char *emptyextlist[] = { "", NULL };
+
+/*
+ * Check if the given file is in place and return full path to it.
+ */
+static char *
+file_lookup(const char *path, const char *name, int namelen, const char **extlist)
+{
+ struct stat st;
+ char *result, *cp;
+ const char **cpp;
+ int pathlen, extlen, len;
+
+ pathlen = strlen(path);
+ extlen = 0;
+ if (extlist == NULL)
+ extlist = emptyextlist;
+ for (cpp = extlist; *cpp; cpp++) {
+ len = strlen(*cpp);
+ if (len > extlen)
+ extlen = len;
+ }
+ result = malloc(pathlen + namelen + extlen + 2);
+ if (result == NULL)
+ return (NULL);
+ bcopy(path, result, pathlen);
+ if (pathlen > 0 && result[pathlen - 1] != '/')
+ result[pathlen++] = '/';
+ cp = result + pathlen;
+ bcopy(name, cp, namelen);
+ cp += namelen;
+ for (cpp = extlist; *cpp; cpp++) {
+ strcpy(cp, *cpp);
+ if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
+ return result;
+ }
+ free(result);
+ return NULL;
+}
+
+/*
+ * Check if file name have any qualifiers
+ */
+static int
+file_havepath(const char *name)
+{
+ const char *cp;
+
+ archsw.arch_getdev(NULL, name, &cp);
+ return (cp != name || strchr(name, '/') != NULL);
+}
+
+/*
+ * Attempt to find the file (name) on the module searchpath.
+ * If (name) is qualified in any way, we simply check it and
+ * return it or NULL. If it is not qualified, then we attempt
+ * to construct a path using entries in the environment variable
+ * module_path.
+ *
+ * The path we return a pointer to need never be freed, as we manage
+ * it internally.
+ */
+static char *
+file_search(const char *name, const char **extlist)
+{
+ struct moduledir *mdp;
+ struct stat sb;
+ char *result;
+ int namelen;
+
+ /* Don't look for nothing */
+ if (name == NULL)
+ return(NULL);
+
+ if (*name == 0)
+ return(strdup(name));
+
+ if (file_havepath(name)) {
+ /* Qualified, so just see if it exists */
+ if (stat(name, &sb) == 0)
+ return(strdup(name));
+ return(NULL);
+ }
+ moduledir_rebuild();
+ result = NULL;
+ namelen = strlen(name);
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ result = file_lookup(mdp->d_path, name, namelen, extlist);
+ if (result)
+ break;
+ }
+ return(result);
+}
+
+#define INT_ALIGN(base, ptr) ptr = \
+ (base) + (((ptr) - (base) + sizeof(int) - 1) & ~(sizeof(int) - 1))
+
+static char *
+mod_search_hints(struct moduledir *mdp, const char *modname,
+ struct mod_depend *verinfo)
+{
+ u_char *cp, *recptr, *bufend, *best;
+ char *result;
+ int *intp, bestver, blen, clen, found, ival, modnamelen, reclen;
+
+ moduledir_readhints(mdp);
+ modnamelen = strlen(modname);
+ found = 0;
+ result = NULL;
+ bestver = 0;
+ if (mdp->d_hints == NULL)
+ goto bad;
+ recptr = mdp->d_hints;
+ bufend = recptr + mdp->d_hintsz;
+ clen = blen = 0;
+ best = cp = NULL;
+ while (recptr < bufend && !found) {
+ intp = (int*)recptr;
+ reclen = *intp++;
+ ival = *intp++;
+ cp = (u_char*)intp;
+ switch (ival) {
+ case MDT_VERSION:
+ clen = *cp++;
+ if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
+ break;
+ cp += clen;
+ INT_ALIGN(mdp->d_hints, cp);
+ ival = *(int*)cp;
+ cp += sizeof(int);
+ clen = *cp++;
+ if (verinfo == NULL || ival == verinfo->md_ver_preferred) {
+ found = 1;
+ break;
+ }
+ if (ival >= verinfo->md_ver_minimum &&
+ ival <= verinfo->md_ver_maximum &&
+ ival > bestver) {
+ bestver = ival;
+ best = cp;
+ blen = clen;
+ }
+ break;
+ default:
+ break;
+ }
+ recptr += reclen + sizeof(int);
+ }
+ /*
+ * Finally check if KLD is in the place
+ */
+ if (found)
+ result = file_lookup(mdp->d_path, (char *)cp, clen, NULL);
+ else if (best)
+ result = file_lookup(mdp->d_path, (char *)best, blen, NULL);
+bad:
+ /*
+ * If nothing found or hints is absent - fallback to the old way
+ * by using "kldname[.ko]" as module name.
+ */
+ if (!found && !bestver && result == NULL)
+ result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list);
+ return result;
+}
+
+/*
+ * Attempt to locate the file containing the module (name)
+ */
+static char *
+mod_searchmodule(char *name, struct mod_depend *verinfo)
+{
+ struct moduledir *mdp;
+ char *result;
+
+ moduledir_rebuild();
+ /*
+ * Now we ready to lookup module in the given directories
+ */
+ result = NULL;
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ result = mod_search_hints(mdp, name, verinfo);
+ if (result)
+ break;
+ }
+
+ return(result);
+}
+
+int
+file_addmodule(struct preloaded_file *fp, char *modname, int version,
+ struct kernel_module **newmp)
+{
+ struct kernel_module *mp;
+ struct mod_depend mdepend;
+
+ bzero(&mdepend, sizeof(mdepend));
+ mdepend.md_ver_preferred = version;
+ mp = file_findmodule(fp, modname, &mdepend);
+ if (mp)
+ return (EEXIST);
+ mp = malloc(sizeof(struct kernel_module));
+ if (mp == NULL)
+ return (ENOMEM);
+ bzero(mp, sizeof(struct kernel_module));
+ mp->m_name = strdup(modname);
+ mp->m_version = version;
+ mp->m_fp = fp;
+ mp->m_next = fp->f_modules;
+ fp->f_modules = mp;
+ if (newmp)
+ *newmp = mp;
+ return (0);
+}
+
+/*
+ * Throw a file away
+ */
+void
+file_discard(struct preloaded_file *fp)
+{
+ struct file_metadata *md, *md1;
+ struct kernel_module *mp, *mp1;
+ if (fp == NULL)
+ return;
+ md = fp->f_metadata;
+ while (md) {
+ md1 = md;
+ md = md->md_next;
+ free(md1);
+ }
+ mp = fp->f_modules;
+ while (mp) {
+ if (mp->m_name)
+ free(mp->m_name);
+ mp1 = mp;
+ mp = mp->m_next;
+ free(mp1);
+ }
+ if (fp->f_name != NULL)
+ free(fp->f_name);
+ if (fp->f_type != NULL)
+ free(fp->f_type);
+ if (fp->f_args != NULL)
+ free(fp->f_args);
+ free(fp);
+}
+
+/*
+ * Allocate a new file; must be used instead of malloc()
+ * to ensure safe initialisation.
+ */
+struct preloaded_file *
+file_alloc(void)
+{
+ struct preloaded_file *fp;
+
+ if ((fp = malloc(sizeof(struct preloaded_file))) != NULL) {
+ bzero(fp, sizeof(struct preloaded_file));
+ }
+ return (fp);
+}
+
+/*
+ * Add a module to the chain
+ */
+static void
+file_insert_tail(struct preloaded_file *fp)
+{
+ struct preloaded_file *cm;
+
+ /* Append to list of loaded file */
+ fp->f_next = NULL;
+ if (preloaded_files == NULL) {
+ preloaded_files = fp;
+ } else {
+ for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
+ ;
+ cm->f_next = fp;
+ }
+}
+
+static char *
+moduledir_fullpath(struct moduledir *mdp, const char *fname)
+{
+ char *cp;
+
+ cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
+ if (cp == NULL)
+ return NULL;
+ strcpy(cp, mdp->d_path);
+ strcat(cp, "/");
+ strcat(cp, fname);
+ return (cp);
+}
+
+/*
+ * Read linker.hints file into memory performing some sanity checks.
+ */
+static void
+moduledir_readhints(struct moduledir *mdp)
+{
+ struct stat st;
+ char *path;
+ int fd, size, version;
+
+ if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
+ return;
+ path = moduledir_fullpath(mdp, "linker.hints");
+ if (stat(path, &st) != 0 ||
+ st.st_size < (ssize_t)(sizeof(version) + sizeof(int)) ||
+ st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) {
+ free(path);
+ mdp->d_flags |= MDIR_NOHINTS;
+ return;
+ }
+ free(path);
+ size = read(fd, &version, sizeof(version));
+ if (size != sizeof(version) || version != LINKER_HINTS_VERSION)
+ goto bad;
+ size = st.st_size - size;
+ mdp->d_hints = malloc(size);
+ if (mdp->d_hints == NULL)
+ goto bad;
+ if (read(fd, mdp->d_hints, size) != size)
+ goto bad;
+ mdp->d_hintsz = size;
+ close(fd);
+ return;
+bad:
+ close(fd);
+ if (mdp->d_hints) {
+ free(mdp->d_hints);
+ mdp->d_hints = NULL;
+ }
+ mdp->d_flags |= MDIR_NOHINTS;
+ return;
+}
+
+/*
+ * Extract directories from the ';' separated list, remove duplicates.
+ */
+static void
+moduledir_rebuild(void)
+{
+ struct moduledir *mdp, *mtmp;
+ const char *path, *cp, *ep;
+ size_t cplen;
+
+ path = getenv("module_path");
+ if (path == NULL)
+ path = default_searchpath;
+ /*
+ * Rebuild list of module directories if it changed
+ */
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link)
+ mdp->d_flags |= MDIR_REMOVED;
+
+ for (ep = path; *ep != 0; ep++) {
+ cp = ep;
+ for (; *ep != 0 && *ep != ';'; ep++)
+ ;
+ /*
+ * Ignore trailing slashes
+ */
+ for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--)
+ ;
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ if (strlen(mdp->d_path) != cplen || bcmp(cp, mdp->d_path, cplen) != 0)
+ continue;
+ mdp->d_flags &= ~MDIR_REMOVED;
+ break;
+ }
+ if (mdp == NULL) {
+ mdp = malloc(sizeof(*mdp) + cplen + 1);
+ if (mdp == NULL)
+ return;
+ mdp->d_path = (char*)(mdp + 1);
+ bcopy(cp, mdp->d_path, cplen);
+ mdp->d_path[cplen] = 0;
+ mdp->d_hints = NULL;
+ mdp->d_flags = 0;
+ STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
+ }
+ if (*ep == 0)
+ break;
+ }
+ /*
+ * Delete unused directories if any
+ */
+ mdp = STAILQ_FIRST(&moduledir_list);
+ while (mdp) {
+ if ((mdp->d_flags & MDIR_REMOVED) == 0) {
+ mdp = STAILQ_NEXT(mdp, d_link);
+ } else {
+ if (mdp->d_hints)
+ free(mdp->d_hints);
+ mtmp = mdp;
+ mdp = STAILQ_NEXT(mdp, d_link);
+ STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
+ free(mtmp);
+ }
+ }
+ return;
+}
diff --git a/usr/src/boot/sys/boot/common/newvers.sh b/usr/src/boot/sys/boot/common/newvers.sh
new file mode 100755
index 0000000000..f3bc389111
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/newvers.sh
@@ -0,0 +1,47 @@
+#!/bin/sh -
+#
+# $FreeBSD$
+# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $
+#
+# Copyright (c) 1984, 1986, 1990, 1993
+# The Regents of the University of California. 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
+
+tempfile=$(mktemp tmp.XXXXXX) || exit
+trap "rm -f $tempfile" EXIT INT TERM
+
+LC_ALL=C; export LC_ALL
+u=${USER-root} h=${HOSTNAME-`hostname`} t=`date`
+#r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
+r=`awk -F: ' /^[0-9]\.[0-9]+:/ { print $1; exit }' $1`
+
+echo "char bootprog_name[] = \"illumos/${3} ${2}\";" > $tempfile
+echo "char bootprog_rev[] = \"${r}\";" >> $tempfile
+echo "char bootprog_date[] = \"${t}\";" >> $tempfile
+echo "char bootprog_maker[] = \"${u}@${h}\";" >> $tempfile
+mv $tempfile vers.c
diff --git a/usr/src/boot/sys/boot/common/panic.c b/usr/src/boot/sys/boot/common/panic.c
new file mode 100644
index 0000000000..6e4c76d0e0
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/panic.c
@@ -0,0 +1,59 @@
+/*
+ * $NetBSD: panic.c,v 1.2 1997/03/22 01:48:36 thorpej Exp $
+ */
+/*-
+ * Copyright (c) 1996
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <machine/stdarg.h>
+
+extern void exit(int) __dead2;
+
+void
+panic(const char *fmt,...)
+{
+ va_list ap;
+
+ printf("panic: ");
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+
+ printf("--> Press a key on the console to reboot <--\n");
+ getchar();
+ printf("Rebooting...\n");
+ exit(1);
+}
diff --git a/usr/src/boot/sys/boot/common/part.c b/usr/src/boot/sys/boot/common/part.c
new file mode 100644
index 0000000000..9ac88721bc
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/part.c
@@ -0,0 +1,983 @@
+/*-
+ * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/diskmbr.h>
+#include <sys/disklabel.h>
+#include <sys/endian.h>
+#include <sys/gpt.h>
+#include <sys/stddef.h>
+#include <sys/queue.h>
+#include <sys/vtoc.h>
+
+#include <crc32.h>
+#include <part.h>
+#include <uuid.h>
+
+#ifdef PART_DEBUG
+#define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+#define DEBUG(fmt, args...)
+#endif
+
+#ifdef LOADER_GPT_SUPPORT
+#define MAXTBLSZ 64
+static const uuid_t gpt_uuid_unused = GPT_ENT_TYPE_UNUSED;
+static const uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA;
+static const uuid_t gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS;
+static const uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI;
+static const uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD;
+static const uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT;
+static const uuid_t gpt_uuid_freebsd_nandfs = GPT_ENT_TYPE_FREEBSD_NANDFS;
+static const uuid_t gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
+static const uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
+static const uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
+static const uuid_t gpt_uuid_illumos_ufs = GPT_ENT_TYPE_ILLUMOS_UFS;
+static const uuid_t gpt_uuid_illumos_zfs = GPT_ENT_TYPE_ILLUMOS_ZFS;
+static const uuid_t gpt_uuid_reserved = GPT_ENT_TYPE_RESERVED;
+#endif
+
+struct pentry {
+ struct ptable_entry part;
+ uint64_t flags;
+ union {
+ uint8_t bsd;
+ uint8_t mbr;
+ uuid_t gpt;
+ uint16_t vtoc8;
+ uint16_t vtoc;
+ } type;
+ STAILQ_ENTRY(pentry) entry;
+};
+
+struct ptable {
+ enum ptable_type type;
+ uint16_t sectorsize;
+ uint64_t sectors;
+
+ STAILQ_HEAD(, pentry) entries;
+};
+
+static struct parttypes {
+ enum partition_type type;
+ const char *desc;
+} ptypes[] = {
+ { PART_UNKNOWN, "Unknown" },
+ { PART_EFI, "EFI" },
+ { PART_FREEBSD, "FreeBSD" },
+ { PART_FREEBSD_BOOT, "FreeBSD boot" },
+ { PART_FREEBSD_NANDFS, "FreeBSD nandfs" },
+ { PART_FREEBSD_UFS, "FreeBSD UFS" },
+ { PART_FREEBSD_ZFS, "FreeBSD ZFS" },
+ { PART_FREEBSD_SWAP, "FreeBSD swap" },
+ { PART_FREEBSD_VINUM, "FreeBSD vinum" },
+ { PART_LINUX, "Linux" },
+ { PART_LINUX_SWAP, "Linux swap" },
+ { PART_DOS, "DOS/Windows" },
+ { PART_SOLARIS2, "Solaris 2" },
+ { PART_ILLUMOS_UFS, "illumos UFS" },
+ { PART_ILLUMOS_ZFS, "illumos ZFS" },
+ { PART_RESERVED, "Reserved" },
+ { PART_VTOC_BOOT, "boot" },
+ { PART_VTOC_ROOT, "root" },
+ { PART_VTOC_SWAP, "swap" },
+ { PART_VTOC_USR, "usr" },
+ { PART_VTOC_STAND, "stand" },
+ { PART_VTOC_VAR, "var" },
+ { PART_VTOC_HOME, "home" }
+};
+
+const char *
+parttype2str(enum partition_type type)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ptypes) / sizeof(ptypes[0]); i++)
+ if (ptypes[i].type == type)
+ return (ptypes[i].desc);
+ return (ptypes[0].desc);
+}
+
+#ifdef LOADER_GPT_SUPPORT
+static void
+uuid_letoh(uuid_t *uuid)
+{
+
+ uuid->time_low = le32toh(uuid->time_low);
+ uuid->time_mid = le16toh(uuid->time_mid);
+ uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version);
+}
+
+static enum partition_type
+gpt_parttype(uuid_t type)
+{
+
+ if (uuid_equal(&type, &gpt_uuid_efi, NULL))
+ return (PART_EFI);
+ else if (uuid_equal(&type, &gpt_uuid_ms_basic_data, NULL))
+ return (PART_DOS);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_boot, NULL))
+ return (PART_FREEBSD_BOOT);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_ufs, NULL))
+ return (PART_FREEBSD_UFS);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_zfs, NULL))
+ return (PART_FREEBSD_ZFS);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_swap, NULL))
+ return (PART_FREEBSD_SWAP);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_vinum, NULL))
+ return (PART_FREEBSD_VINUM);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd_nandfs, NULL))
+ return (PART_FREEBSD_NANDFS);
+ else if (uuid_equal(&type, &gpt_uuid_freebsd, NULL))
+ return (PART_FREEBSD);
+ else if (uuid_equal(&type, &gpt_uuid_illumos_ufs, NULL))
+ return (PART_ILLUMOS_UFS);
+ else if (uuid_equal(&type, &gpt_uuid_illumos_zfs, NULL))
+ return (PART_ILLUMOS_ZFS);
+ else if (uuid_equal(&type, &gpt_uuid_reserved, NULL))
+ return (PART_RESERVED);
+ return (PART_UNKNOWN);
+}
+
+static struct gpt_hdr*
+gpt_checkhdr(struct gpt_hdr *hdr, uint64_t lba_self,
+ uint64_t lba_last __attribute((unused)), uint16_t sectorsize)
+{
+ uint32_t sz, crc;
+
+ if (memcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0) {
+ DEBUG("no GPT signature");
+ return (NULL);
+ }
+ sz = le32toh(hdr->hdr_size);
+ if (sz < 92 || sz > sectorsize) {
+ DEBUG("invalid GPT header size: %d", sz);
+ return (NULL);
+ }
+ crc = le32toh(hdr->hdr_crc_self);
+ hdr->hdr_crc_self = 0;
+ if (crc32(hdr, sz) != crc) {
+ DEBUG("GPT header's CRC doesn't match");
+ return (NULL);
+ }
+ hdr->hdr_crc_self = crc;
+ hdr->hdr_revision = le32toh(hdr->hdr_revision);
+ if (hdr->hdr_revision < GPT_HDR_REVISION) {
+ DEBUG("unsupported GPT revision %d", hdr->hdr_revision);
+ return (NULL);
+ }
+ hdr->hdr_lba_self = le64toh(hdr->hdr_lba_self);
+ if (hdr->hdr_lba_self != lba_self) {
+ DEBUG("self LBA doesn't match");
+ return (NULL);
+ }
+ hdr->hdr_lba_alt = le64toh(hdr->hdr_lba_alt);
+ if (hdr->hdr_lba_alt == hdr->hdr_lba_self) {
+ DEBUG("invalid alternate LBA");
+ return (NULL);
+ }
+ hdr->hdr_entries = le32toh(hdr->hdr_entries);
+ hdr->hdr_entsz = le32toh(hdr->hdr_entsz);
+ if (hdr->hdr_entries == 0 ||
+ hdr->hdr_entsz < sizeof(struct gpt_ent) ||
+ sectorsize % hdr->hdr_entsz != 0) {
+ DEBUG("invalid entry size or number of entries");
+ return (NULL);
+ }
+ hdr->hdr_lba_start = le64toh(hdr->hdr_lba_start);
+ hdr->hdr_lba_end = le64toh(hdr->hdr_lba_end);
+ hdr->hdr_lba_table = le64toh(hdr->hdr_lba_table);
+ hdr->hdr_crc_table = le32toh(hdr->hdr_crc_table);
+ uuid_letoh(&hdr->hdr_uuid);
+ return (hdr);
+}
+
+static int
+gpt_checktbl(const struct gpt_hdr *hdr, u_char *tbl, size_t size,
+ uint64_t lba_last __attribute((unused)))
+{
+ struct gpt_ent *ent;
+ uint32_t i, cnt;
+
+ cnt = size / hdr->hdr_entsz;
+ if (hdr->hdr_entries <= cnt) {
+ cnt = hdr->hdr_entries;
+ /* Check CRC only when buffer size is enough for table. */
+ if (hdr->hdr_crc_table !=
+ crc32(tbl, hdr->hdr_entries * hdr->hdr_entsz)) {
+ DEBUG("GPT table's CRC doesn't match");
+ return (-1);
+ }
+ }
+ for (i = 0; i < cnt; i++) {
+ ent = (struct gpt_ent *)(tbl + i * hdr->hdr_entsz);
+ uuid_letoh(&ent->ent_type);
+ if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL))
+ continue;
+ ent->ent_lba_start = le64toh(ent->ent_lba_start);
+ ent->ent_lba_end = le64toh(ent->ent_lba_end);
+ }
+ return (0);
+}
+
+static struct ptable*
+ptable_gptread(struct ptable *table, void *dev, diskread_t dread)
+{
+ struct pentry *entry;
+ struct gpt_hdr *phdr, hdr;
+ struct gpt_ent *ent;
+ u_char *buf, *tbl;
+ uint64_t offset;
+ int pri, sec;
+ size_t size, i;
+
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (NULL);
+ tbl = malloc(table->sectorsize * MAXTBLSZ);
+ if (tbl == NULL) {
+ free(buf);
+ return (NULL);
+ }
+ /* Read the primary GPT header. */
+ if (dread(dev, buf, 1, 1) != 0) {
+ ptable_close(table);
+ table = NULL;
+ goto out;
+ }
+ pri = sec = 0;
+ /* Check the primary GPT header. */
+ phdr = gpt_checkhdr((struct gpt_hdr *)buf, 1, table->sectors - 1,
+ table->sectorsize);
+ if (phdr != NULL) {
+ /* Read the primary GPT table. */
+ size = MIN(MAXTBLSZ, (phdr->hdr_entries * phdr->hdr_entsz +
+ table->sectorsize - 1) / table->sectorsize);
+ if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 &&
+ gpt_checktbl(phdr, tbl, size * table->sectorsize,
+ table->sectors - 1) == 0) {
+ memcpy(&hdr, phdr, sizeof(hdr));
+ pri = 1;
+ }
+ }
+ offset = pri ? hdr.hdr_lba_alt: table->sectors - 1;
+ /* Read the backup GPT header. */
+ if (dread(dev, buf, 1, offset) != 0)
+ phdr = NULL;
+ else
+ phdr = gpt_checkhdr((struct gpt_hdr *)buf, offset,
+ table->sectors - 1, table->sectorsize);
+ if (phdr != NULL) {
+ /*
+ * Compare primary and backup headers.
+ * If they are equal, then we do not need to read backup
+ * table. If they are different, then prefer backup header
+ * and try to read backup table.
+ */
+ if (pri == 0 ||
+ uuid_equal(&hdr.hdr_uuid, &phdr->hdr_uuid, NULL) == 0 ||
+ hdr.hdr_revision != phdr->hdr_revision ||
+ hdr.hdr_size != phdr->hdr_size ||
+ hdr.hdr_lba_start != phdr->hdr_lba_start ||
+ hdr.hdr_lba_end != phdr->hdr_lba_end ||
+ hdr.hdr_entries != phdr->hdr_entries ||
+ hdr.hdr_entsz != phdr->hdr_entsz ||
+ hdr.hdr_crc_table != phdr->hdr_crc_table) {
+ /* Read the backup GPT table. */
+ size = MIN(MAXTBLSZ, (phdr->hdr_entries *
+ phdr->hdr_entsz + table->sectorsize - 1) /
+ table->sectorsize);
+ if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 &&
+ gpt_checktbl(phdr, tbl, size * table->sectorsize,
+ table->sectors - 1) == 0) {
+ memcpy(&hdr, phdr, sizeof(hdr));
+ sec = 1;
+ }
+ }
+ }
+ if (pri == 0 && sec == 0) {
+ /* Both primary and backup tables are invalid. */
+ table->type = PTABLE_NONE;
+ goto out;
+ }
+ DEBUG("GPT detected");
+ size = MIN(hdr.hdr_entries * hdr.hdr_entsz,
+ MAXTBLSZ * table->sectorsize);
+ for (i = 0; i < size / hdr.hdr_entsz; i++) {
+ ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz);
+ if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL))
+ continue;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = ent->ent_lba_start;
+ entry->part.end = ent->ent_lba_end;
+ entry->part.index = i + 1;
+ entry->part.type = gpt_parttype(ent->ent_type);
+ entry->flags = le64toh(ent->ent_attr);
+ memcpy(&entry->type.gpt, &ent->ent_type, sizeof(uuid_t));
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new GPT partition added");
+ }
+out:
+ free(buf);
+ free(tbl);
+ return (table);
+}
+#endif /* LOADER_GPT_SUPPORT */
+
+#ifdef LOADER_MBR_SUPPORT
+/* We do not need to support too many EBR partitions in the loader */
+#define MAXEBRENTRIES 8
+static enum partition_type
+mbr_parttype(uint8_t type)
+{
+
+ switch (type) {
+ case DOSPTYP_386BSD:
+ return (PART_FREEBSD);
+ case DOSPTYP_LINSWP:
+ return (PART_LINUX_SWAP);
+ case DOSPTYP_LINUX:
+ return (PART_LINUX);
+ case DOSPTYP_SUNIXOS2:
+ return (PART_SOLARIS2);
+ case 0x01:
+ case 0x04:
+ case 0x06:
+ case 0x07:
+ case 0x0b:
+ case 0x0c:
+ case 0x0e:
+ return (PART_DOS);
+ }
+ return (PART_UNKNOWN);
+}
+
+static struct ptable*
+ptable_ebrread(struct ptable *table, void *dev, diskread_t dread)
+{
+ struct dos_partition *dp;
+ struct pentry *e1, *entry;
+ uint32_t start, end, offset;
+ u_char *buf;
+ int i, idx;
+
+ STAILQ_FOREACH(e1, &table->entries, entry) {
+ if (e1->type.mbr == DOSPTYP_EXT ||
+ e1->type.mbr == DOSPTYP_EXTLBA)
+ break;
+ }
+ if (e1 == NULL)
+ return (table);
+ idx = 5;
+ offset = e1->part.start;
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (table);
+ DEBUG("EBR detected");
+ for (i = 0; i < MAXEBRENTRIES; i++) {
+#if 0 /* Some BIOSes return an incorrect number of sectors */
+ if (offset >= table->sectors)
+ break;
+#endif
+ if (dread(dev, buf, 1, offset) != 0)
+ break;
+ dp = (struct dos_partition *)(buf + DOSPARTOFF);
+ if (dp[0].dp_typ == 0)
+ break;
+ start = le32toh(dp[0].dp_start);
+ if (dp[0].dp_typ == DOSPTYP_EXT &&
+ dp[1].dp_typ == 0) {
+ offset = e1->part.start + start;
+ continue;
+ }
+ end = le32toh(dp[0].dp_size);
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = offset + start;
+ entry->part.end = entry->part.start + end - 1;
+ entry->part.index = idx++;
+ entry->part.type = mbr_parttype(dp[0].dp_typ);
+ entry->flags = dp[0].dp_flag;
+ entry->type.mbr = dp[0].dp_typ;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new EBR partition added");
+ if (dp[1].dp_typ == 0)
+ break;
+ offset = e1->part.start + le32toh(dp[1].dp_start);
+ }
+ free(buf);
+ return (table);
+}
+#endif /* LOADER_MBR_SUPPORT */
+
+static enum partition_type
+bsd_parttype(uint8_t type)
+{
+
+ switch (type) {
+ case FS_NANDFS:
+ return (PART_FREEBSD_NANDFS);
+ case FS_SWAP:
+ return (PART_FREEBSD_SWAP);
+ case FS_BSDFFS:
+ return (PART_FREEBSD_UFS);
+ case FS_VINUM:
+ return (PART_FREEBSD_VINUM);
+ case FS_ZFS:
+ return (PART_FREEBSD_ZFS);
+ }
+ return (PART_UNKNOWN);
+}
+
+static struct ptable*
+ptable_bsdread(struct ptable *table, void *dev, diskread_t dread)
+{
+ struct disklabel *dl;
+ struct partition *part;
+ struct pentry *entry;
+ u_char *buf;
+ uint32_t raw_offset;
+ int i;
+
+ if (table->sectorsize < sizeof(struct disklabel)) {
+ DEBUG("Too small sectorsize");
+ return (table);
+ }
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (table);
+ if (dread(dev, buf, 1, 1) != 0) {
+ DEBUG("read failed");
+ ptable_close(table);
+ table = NULL;
+ goto out;
+ }
+ dl = (struct disklabel *)buf;
+ if (le32toh(dl->d_magic) != DISKMAGIC &&
+ le32toh(dl->d_magic2) != DISKMAGIC)
+ goto out;
+ if (le32toh(dl->d_secsize) != table->sectorsize) {
+ DEBUG("unsupported sector size");
+ goto out;
+ }
+ dl->d_npartitions = le16toh(dl->d_npartitions);
+ if (dl->d_npartitions > 20 || dl->d_npartitions < 8) {
+ DEBUG("invalid number of partitions");
+ goto out;
+ }
+ DEBUG("BSD detected");
+ part = &dl->d_partitions[0];
+ raw_offset = le32toh(part[RAW_PART].p_offset);
+ for (i = 0; i < dl->d_npartitions; i++, part++) {
+ if (i == RAW_PART)
+ continue;
+ if (part->p_size == 0)
+ continue;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = le32toh(part->p_offset) - raw_offset;
+ entry->part.end = entry->part.start +
+ le32toh(part->p_size) + 1;
+ entry->part.type = bsd_parttype(part->p_fstype);
+ entry->part.index = i; /* starts from zero */
+ entry->type.bsd = part->p_fstype;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new BSD partition added");
+ }
+ table->type = PTABLE_BSD;
+out:
+ free(buf);
+ return (table);
+}
+
+#ifdef LOADER_VTOC8_SUPPORT
+static enum partition_type
+vtoc8_parttype(uint16_t type)
+{
+
+ switch (type) {
+ case VTOC_TAG_FREEBSD_NANDFS:
+ return (PART_FREEBSD_NANDFS);
+ case VTOC_TAG_FREEBSD_SWAP:
+ return (PART_FREEBSD_SWAP);
+ case VTOC_TAG_FREEBSD_UFS:
+ return (PART_FREEBSD_UFS);
+ case VTOC_TAG_FREEBSD_VINUM:
+ return (PART_FREEBSD_VINUM);
+ case VTOC_TAG_FREEBSD_ZFS:
+ return (PART_FREEBSD_ZFS);
+ };
+ return (PART_UNKNOWN);
+}
+
+static struct ptable*
+ptable_vtoc8read(struct ptable *table, void *dev, diskread_t dread)
+{
+ struct pentry *entry;
+ struct vtoc8 *dl;
+ u_char *buf;
+ uint16_t sum, heads, sectors;
+ int i;
+
+ if (table->sectorsize != sizeof(struct vtoc8))
+ return (table);
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (table);
+ if (dread(dev, buf, 1, 0) != 0) {
+ DEBUG("read failed");
+ ptable_close(table);
+ table = NULL;
+ goto out;
+ }
+ dl = (struct vtoc8 *)buf;
+ /* Check the sum */
+ for (i = sum = 0; i < sizeof(struct vtoc8); i += sizeof(sum))
+ sum ^= be16dec(buf + i);
+ if (sum != 0) {
+ DEBUG("incorrect checksum");
+ goto out;
+ }
+ if (be16toh(dl->nparts) != VTOC8_NPARTS) {
+ DEBUG("invalid number of entries");
+ goto out;
+ }
+ sectors = be16toh(dl->nsecs);
+ heads = be16toh(dl->nheads);
+ if (sectors * heads == 0) {
+ DEBUG("invalid geometry");
+ goto out;
+ }
+ DEBUG("VTOC8 detected");
+ for (i = 0; i < VTOC8_NPARTS; i++) {
+ dl->part[i].tag = be16toh(dl->part[i].tag);
+ if (i == VTOC_RAW_PART ||
+ dl->part[i].tag == VTOC_TAG_UNASSIGNED)
+ continue;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = be32toh(dl->map[i].cyl) * heads * sectors;
+ entry->part.end = be32toh(dl->map[i].nblks) +
+ entry->part.start - 1;
+ entry->part.type = vtoc8_parttype(dl->part[i].tag);
+ entry->part.index = i; /* starts from zero */
+ entry->type.vtoc8 = dl->part[i].tag;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new VTOC8 partition added");
+ }
+ table->type = PTABLE_VTOC8;
+out:
+ free(buf);
+ return (table);
+
+}
+#endif /* LOADER_VTOC8_SUPPORT */
+
+static enum partition_type
+vtoc_parttype(uint16_t type)
+{
+ switch (type) {
+ case VTOC_TAG_BOOT:
+ return (PART_VTOC_BOOT);
+ case VTOC_TAG_ROOT:
+ return (PART_VTOC_ROOT);
+ case VTOC_TAG_SWAP:
+ return (PART_VTOC_SWAP);
+ case VTOC_TAG_USR:
+ return (PART_VTOC_USR);
+ case VTOC_TAG_BACKUP:
+ return (PART_VTOC_BACKUP);
+ case VTOC_TAG_STAND:
+ return (PART_VTOC_STAND);
+ case VTOC_TAG_VAR:
+ return (PART_VTOC_VAR);
+ case VTOC_TAG_HOME:
+ return (PART_VTOC_HOME);
+ };
+ return (PART_UNKNOWN);
+}
+
+static struct ptable*
+ptable_dklabelread(struct ptable *table, void *dev, diskread_t dread)
+{
+ struct pentry *entry;
+ struct dk_label *dl;
+ struct dk_vtoc *dv;
+ u_char *buf;
+ int i;
+
+ if (table->sectorsize < sizeof(struct dk_label)) {
+ DEBUG("Too small sectorsize");
+ return (table);
+ }
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (table);
+ if (dread(dev, buf, 1, DK_LABEL_LOC) != 0) {
+ DEBUG("read failed");
+ ptable_close(table);
+ table = NULL;
+ goto out;
+ }
+ dl = (struct dk_label *)buf;
+ dv = (struct dk_vtoc *)&dl->dkl_vtoc;
+
+ if (dl->dkl_magic != VTOC_MAGIC) {
+ DEBUG("dk_label magic error");
+ goto out;
+ }
+ if (dv->v_sanity != VTOC_SANITY) {
+ DEBUG("this vtoc is not sane");
+ goto out;
+ }
+ if (dv->v_nparts != NDKMAP) {
+ DEBUG("invalid number of entries");
+ goto out;
+ }
+ DEBUG("VTOC detected");
+ for (i = 0; i < NDKMAP; i++) {
+ if (i == VTOC_RAW_PART || /* skip slice 2 and empty */
+ dv->v_part[i].p_size == 0)
+ continue;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = dv->v_part[i].p_start;
+ entry->part.end = dv->v_part[i].p_size +
+ entry->part.start;
+ entry->part.type = vtoc_parttype(dv->v_part[i].p_tag);
+ entry->part.index = i; /* starts from zero */
+ entry->type.vtoc = dv->v_part[i].p_tag;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new VTOC partition added");
+ }
+ table->type = PTABLE_VTOC;
+out:
+ free(buf);
+ return (table);
+}
+
+struct ptable*
+ptable_open(void *dev, off_t sectors, uint16_t sectorsize,
+ diskread_t *dread)
+{
+ struct dos_partition *dp;
+ struct ptable *table;
+ u_char *buf;
+ int i, count;
+#ifdef LOADER_MBR_SUPPORT
+ struct pentry *entry;
+ uint32_t start, end;
+ int has_ext;
+#endif
+ table = NULL;
+ buf = malloc(sectorsize);
+ if (buf == NULL)
+ return (NULL);
+ /* First, read the MBR. */
+ if (dread(dev, buf, 1, DOSBBSECTOR) != 0) {
+ DEBUG("read failed");
+ goto out;
+ }
+
+ table = malloc(sizeof(*table));
+ if (table == NULL)
+ goto out;
+ table->sectors = sectors;
+ table->sectorsize = sectorsize;
+ table->type = PTABLE_NONE;
+ STAILQ_INIT(&table->entries);
+
+ if (ptable_dklabelread(table, dev, dread) == NULL) { /* Read error. */
+ table = NULL;
+ goto out;
+ } else if (table->type == PTABLE_VTOC)
+ goto out;
+
+#ifdef LOADER_VTOC8_SUPPORT
+ if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) {
+ if (ptable_vtoc8read(table, dev, dread) == NULL) {
+ /* Read error. */
+ table = NULL;
+ goto out;
+ } else if (table->type == PTABLE_VTOC8)
+ goto out;
+ }
+#endif
+ /* Check the BSD label. */
+ if (ptable_bsdread(table, dev, dread) == NULL) { /* Read error. */
+ table = NULL;
+ goto out;
+ } else if (table->type == PTABLE_BSD)
+ goto out;
+
+#if defined(LOADER_GPT_SUPPORT) || defined(LOADER_MBR_SUPPORT)
+ /* Check the MBR magic. */
+ if (buf[DOSMAGICOFFSET] != 0x55 ||
+ buf[DOSMAGICOFFSET + 1] != 0xaa) {
+ DEBUG("magic sequence not found");
+#if defined(LOADER_GPT_SUPPORT)
+ /* There is no PMBR, check that we have backup GPT */
+ table->type = PTABLE_GPT;
+ table = ptable_gptread(table, dev, dread);
+#endif
+ goto out;
+ }
+ /* Check that we have PMBR. Also do some validation. */
+ dp = (struct dos_partition *)(buf + DOSPARTOFF);
+ for (i = 0, count = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_flag != 0 && dp[i].dp_flag != 0x80) {
+ DEBUG("invalid partition flag %x", dp[i].dp_flag);
+ goto out;
+ }
+#ifdef LOADER_GPT_SUPPORT
+ if (dp[i].dp_typ == DOSPTYP_PMBR) {
+ table->type = PTABLE_GPT;
+ DEBUG("PMBR detected");
+ }
+#endif
+ if (dp[i].dp_typ != 0)
+ count++;
+ }
+ /* Do we have some invalid values? */
+ if (table->type == PTABLE_GPT && count > 1) {
+ if (dp[1].dp_typ != DOSPTYP_HFS) {
+ table->type = PTABLE_NONE;
+ DEBUG("Incorrect PMBR, ignore it");
+ } else
+ DEBUG("Bootcamp detected");
+ }
+#ifdef LOADER_GPT_SUPPORT
+ if (table->type == PTABLE_GPT) {
+ table = ptable_gptread(table, dev, dread);
+ goto out;
+ }
+#endif
+#ifdef LOADER_MBR_SUPPORT
+ /* Read MBR. */
+ DEBUG("MBR detected");
+ table->type = PTABLE_MBR;
+ for (i = has_ext = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == 0)
+ continue;
+ start = le32dec(&(dp[i].dp_start));
+ end = le32dec(&(dp[i].dp_size));
+ if (start == 0 || end == 0)
+ continue;
+#if 0 /* Some BIOSes return an incorrect number of sectors */
+ if (start + end - 1 >= sectors)
+ continue; /* XXX: ignore */
+#endif
+ if (dp[i].dp_typ == DOSPTYP_EXT ||
+ dp[i].dp_typ == DOSPTYP_EXTLBA)
+ has_ext = 1;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ break;
+ entry->part.start = start;
+ entry->part.end = start + end - 1;
+ entry->part.index = i + 1;
+ entry->part.type = mbr_parttype(dp[i].dp_typ);
+ entry->flags = dp[i].dp_flag;
+ entry->type.mbr = dp[i].dp_typ;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+ DEBUG("new MBR partition added");
+ }
+ if (has_ext) {
+ table = ptable_ebrread(table, dev, dread);
+ /* FALLTHROUGH */
+ }
+#endif /* LOADER_MBR_SUPPORT */
+#endif /* LOADER_MBR_SUPPORT || LOADER_GPT_SUPPORT */
+out:
+ free(buf);
+ return (table);
+}
+
+void
+ptable_close(struct ptable *table)
+{
+ struct pentry *entry;
+
+ while (!STAILQ_EMPTY(&table->entries)) {
+ entry = STAILQ_FIRST(&table->entries);
+ STAILQ_REMOVE_HEAD(&table->entries, entry);
+ free(entry);
+ }
+ free(table);
+}
+
+enum ptable_type
+ptable_gettype(const struct ptable *table)
+{
+
+ return (table->type);
+}
+
+int
+ptable_getpart(const struct ptable *table, struct ptable_entry *part, int idx)
+{
+ struct pentry *entry;
+
+ if (part == NULL || table == NULL)
+ return (EINVAL);
+
+ STAILQ_FOREACH(entry, &table->entries, entry) {
+ if (entry->part.index != idx)
+ continue;
+ memcpy(part, &entry->part, sizeof(*part));
+ return (0);
+ }
+ return (ENOENT);
+}
+
+/*
+ * Search for a slice with the following preferences:
+ *
+ * 1: Active illumos slice
+ * 2: Non-active illumos slice
+ * 3: Active Linux slice
+ * 4: non-active Linux slice
+ * 5: Active FAT/FAT32 slice
+ * 6: non-active FAT/FAT32 slice
+ */
+#define PREF_RAWDISK 0
+#define PREF_ILLUMOS_ACT 1
+#define PREF_ILLUMOS 2
+#define PREF_LINUX_ACT 3
+#define PREF_LINUX 4
+#define PREF_DOS_ACT 5
+#define PREF_DOS 6
+#define PREF_NONE 7
+int
+ptable_getbestpart(const struct ptable *table, struct ptable_entry *part)
+{
+ struct pentry *entry, *best;
+ int pref, preflevel;
+
+ if (part == NULL || table == NULL)
+ return (EINVAL);
+
+ best = NULL;
+ preflevel = pref = PREF_NONE;
+ STAILQ_FOREACH(entry, &table->entries, entry) {
+#ifdef LOADER_MBR_SUPPORT
+ if (table->type == PTABLE_MBR) {
+ switch (entry->type.mbr) {
+ case DOSPTYP_SUNIXOS2:
+ pref = entry->flags & 0x80 ? PREF_ILLUMOS_ACT:
+ PREF_ILLUMOS;
+ break;
+ case DOSPTYP_LINUX:
+ pref = entry->flags & 0x80 ? PREF_LINUX_ACT:
+ PREF_LINUX;
+ break;
+ case 0x01: /* DOS/Windows */
+ case 0x04:
+ case 0x06:
+ case 0x0c:
+ case 0x0e:
+ case DOSPTYP_FAT32:
+ pref = entry->flags & 0x80 ? PREF_DOS_ACT:
+ PREF_DOS;
+ break;
+ default:
+ pref = PREF_NONE;
+ }
+ }
+#endif /* LOADER_MBR_SUPPORT */
+#ifdef LOADER_GPT_SUPPORT
+ if (table->type == PTABLE_GPT) {
+ if (entry->part.type == PART_DOS)
+ pref = PREF_DOS;
+ else if (entry->part.type == PART_ILLUMOS_ZFS)
+ pref = PREF_ILLUMOS;
+ else
+ pref = PREF_NONE;
+ }
+#endif /* LOADER_GPT_SUPPORT */
+ if (pref < preflevel) {
+ preflevel = pref;
+ best = entry;
+ }
+ }
+ if (best != NULL) {
+ memcpy(part, &best->part, sizeof(*part));
+ return (0);
+ }
+ return (ENOENT);
+}
+
+/*
+ * iterate will stop if iterator will return non 0.
+ */
+int
+ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter)
+{
+ struct pentry *entry;
+ char name[32];
+ int ret = 0;
+
+ name[0] = '\0';
+ STAILQ_FOREACH(entry, &table->entries, entry) {
+#ifdef LOADER_MBR_SUPPORT
+ if (table->type == PTABLE_MBR)
+ sprintf(name, "s%d", entry->part.index);
+ else
+#endif
+#ifdef LOADER_GPT_SUPPORT
+ if (table->type == PTABLE_GPT)
+ sprintf(name, "p%d", entry->part.index);
+ else
+#endif
+#ifdef LOADER_VTOC8_SUPPORT
+ if (table->type == PTABLE_VTOC8)
+ sprintf(name, "%c", (u_char) 'a' +
+ entry->part.index);
+ else
+#endif
+ if (table->type == PTABLE_VTOC)
+ sprintf(name, "%c", (u_char) 'a' +
+ entry->part.index);
+ else
+ if (table->type == PTABLE_BSD)
+ sprintf(name, "%c", (u_char) 'a' +
+ entry->part.index);
+ ret = iter(arg, name, &entry->part);
+ if (ret != 0)
+ return (ret);
+ }
+ return (ret);
+}
diff --git a/usr/src/boot/sys/boot/common/part.h b/usr/src/boot/sys/boot/common/part.h
new file mode 100644
index 0000000000..be2270356c
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/part.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PART_H_
+#define _PART_H_
+
+struct ptable;
+
+enum ptable_type {
+ PTABLE_NONE,
+ PTABLE_BSD,
+ PTABLE_MBR,
+ PTABLE_GPT,
+ PTABLE_VTOC8,
+ PTABLE_VTOC
+};
+
+enum partition_type {
+ PART_UNKNOWN,
+ PART_EFI,
+ PART_FREEBSD,
+ PART_FREEBSD_BOOT,
+ PART_FREEBSD_NANDFS,
+ PART_FREEBSD_UFS,
+ PART_FREEBSD_ZFS,
+ PART_FREEBSD_SWAP,
+ PART_FREEBSD_VINUM,
+ PART_LINUX,
+ PART_LINUX_SWAP,
+ PART_DOS,
+ PART_SOLARIS2,
+ PART_ILLUMOS_UFS,
+ PART_ILLUMOS_ZFS,
+ PART_RESERVED,
+ PART_VTOC_BOOT,
+ PART_VTOC_ROOT,
+ PART_VTOC_SWAP,
+ PART_VTOC_USR,
+ PART_VTOC_BACKUP,
+ PART_VTOC_STAND,
+ PART_VTOC_VAR,
+ PART_VTOC_HOME,
+};
+
+struct ptable_entry {
+ uint64_t start;
+ uint64_t end;
+ int index;
+ enum partition_type type;
+};
+
+/* The offset and size are in sectors */
+typedef int (diskread_t)(void *arg, void *buf, size_t blocks, off_t offset);
+typedef int (ptable_iterate_t)(void *arg, const char *partname,
+ const struct ptable_entry *part);
+
+struct ptable *ptable_open(void *dev, off_t sectors, uint16_t sectorsize,
+ diskread_t *dread);
+void ptable_close(struct ptable *table);
+enum ptable_type ptable_gettype(const struct ptable *table);
+
+int ptable_getpart(const struct ptable *table, struct ptable_entry *part,
+ int index);
+int ptable_getbestpart(const struct ptable *table, struct ptable_entry *part);
+
+int ptable_iterate(const struct ptable *table, void *arg,
+ ptable_iterate_t *iter);
+const char *parttype2str(enum partition_type type);
+
+#endif /* !_PART_H_ */
diff --git a/usr/src/boot/sys/boot/common/paths.h b/usr/src/boot/sys/boot/common/paths.h
new file mode 100644
index 0000000000..9ed45e646a
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/paths.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2016 M. Warner Losh <imp@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PATHS_H_
+#define _PATHS_H_
+
+#define PATH_DOTCONFIG "/boot.config"
+#define PATH_CONFIG "/boot/config"
+#define PATH_LOADER "/boot/loader"
+#define PATH_LOADER_EFI "/boot/loader.efi"
+#define PATH_LOADER_ZFS "/boot/zfsloader"
+#define PATH_KERNEL "/boot/kernel/kernel"
+
+#endif /* _PATHS_H_ */
diff --git a/usr/src/boot/sys/boot/common/pnp.c b/usr/src/boot/sys/boot/common/pnp.c
new file mode 100644
index 0000000000..589926b590
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/pnp.c
@@ -0,0 +1,184 @@
+/*
+ * mjs copyright
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * "Plug and Play" functionality.
+ *
+ * We use the PnP enumerators to obtain identifiers for installed hardware,
+ * and the contents of a database to determine modules to be loaded to support
+ * such hardware.
+ */
+
+#include <stand.h>
+#include <string.h>
+#include <bootstrap.h>
+
+struct pnpinfo_stql pnp_devices;
+static int pnp_devices_initted = 0;
+
+static void pnp_discard(void);
+
+/*
+ * Perform complete enumeration sweep
+ */
+
+COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan);
+
+static int
+pnp_scan(int argc, char *argv[])
+{
+ struct pnpinfo *pi;
+ int hdlr;
+ int verbose;
+ int ch;
+
+ if (pnp_devices_initted == 0) {
+ STAILQ_INIT(&pnp_devices);
+ pnp_devices_initted = 1;
+ }
+
+ verbose = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch(ch) {
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return(CMD_OK);
+ }
+ }
+
+ /* forget anything we think we knew */
+ pnp_discard();
+
+ /* iterate over all of the handlers */
+ for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) {
+ if (verbose)
+ printf("Probing %s...\n", pnphandlers[hdlr]->pp_name);
+ pnphandlers[hdlr]->pp_enumerate();
+ }
+ if (verbose) {
+ pager_open();
+ pager_output("PNP scan summary:\n");
+ STAILQ_FOREACH(pi, &pnp_devices, pi_link) {
+ pager_output(STAILQ_FIRST(&pi->pi_ident)->id_ident); /* first ident should be canonical */
+ if (pi->pi_desc != NULL) {
+ pager_output(" : ");
+ pager_output(pi->pi_desc);
+ }
+ pager_output("\n");
+ }
+ pager_close();
+ }
+ return(CMD_OK);
+}
+
+/*
+ * Throw away anything we think we know about PnP devices.
+ */
+static void
+pnp_discard(void)
+{
+ struct pnpinfo *pi;
+
+ while (STAILQ_FIRST(&pnp_devices) != NULL) {
+ pi = STAILQ_FIRST(&pnp_devices);
+ STAILQ_REMOVE_HEAD(&pnp_devices, pi_link);
+ pnp_freeinfo(pi);
+ }
+}
+
+/*
+ * Add a unique identifier to (pi)
+ */
+void
+pnp_addident(struct pnpinfo *pi, char *ident)
+{
+ struct pnpident *id;
+
+ STAILQ_FOREACH(id, &pi->pi_ident, id_link)
+ if (!strcmp(id->id_ident, ident))
+ return; /* already have this one */
+
+ id = malloc(sizeof(struct pnpident));
+ id->id_ident = strdup(ident);
+ STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link);
+}
+
+/*
+ * Allocate a new pnpinfo struct
+ */
+struct pnpinfo *
+pnp_allocinfo(void)
+{
+ struct pnpinfo *pi;
+
+ pi = malloc(sizeof(struct pnpinfo));
+ bzero(pi, sizeof(struct pnpinfo));
+ STAILQ_INIT(&pi->pi_ident);
+ return(pi);
+}
+
+/*
+ * Release storage held by a pnpinfo struct
+ */
+void
+pnp_freeinfo(struct pnpinfo *pi)
+{
+ struct pnpident *id;
+
+ while (!STAILQ_EMPTY(&pi->pi_ident)) {
+ id = STAILQ_FIRST(&pi->pi_ident);
+ STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link);
+ free(id->id_ident);
+ free(id);
+ }
+ if (pi->pi_desc)
+ free(pi->pi_desc);
+ if (pi->pi_module)
+ free(pi->pi_module);
+ if (pi->pi_argv)
+ free(pi->pi_argv);
+ free(pi);
+}
+
+/*
+ * Add a new pnpinfo struct to the list.
+ */
+void
+pnp_addinfo(struct pnpinfo *pi)
+{
+ STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link);
+}
+
+
+/*
+ * Format an EISA id as a string in standard ISA PnP format, AAAIIRR
+ * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID.
+ */
+char *
+pnp_eisaformat(u_int8_t *data)
+{
+ static char idbuf[8];
+ const char hextoascii[] = "0123456789abcdef";
+
+ idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
+ idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
+ idbuf[2] = '@' + (data[1] & 0x1f);
+ idbuf[3] = hextoascii[(data[2] >> 4)];
+ idbuf[4] = hextoascii[(data[2] & 0xf)];
+ idbuf[5] = hextoascii[(data[3] >> 4)];
+ idbuf[6] = hextoascii[(data[3] & 0xf)];
+ idbuf[7] = 0;
+ return(idbuf);
+}
+
diff --git a/usr/src/boot/sys/boot/common/rbx.h b/usr/src/boot/sys/boot/common/rbx.h
new file mode 100644
index 0000000000..21371a5638
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/rbx.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _RBX_H_
+#define _RBX_H_
+
+#define RBX_ASKNAME 0x0 /* -a */
+#define RBX_SINGLE 0x1 /* -s */
+/* 0x2 is reserved for log2(RB_NOSYNC). */
+/* 0x3 is reserved for log2(RB_HALT). */
+/* 0x4 is reserved for log2(RB_INITNAME). */
+#define RBX_DFLTROOT 0x5 /* -r */
+#define RBX_KDB 0x6 /* -d */
+/* 0x7 is reserved for log2(RB_RDONLY). */
+/* 0x8 is reserved for log2(RB_DUMP). */
+/* 0x9 is reserved for log2(RB_MINIROOT). */
+#define RBX_CONFIG 0xa /* -c */
+#define RBX_VERBOSE 0xb /* -v */
+#define RBX_SERIAL 0xc /* -h */
+#define RBX_CDROM 0xd /* -C */
+/* 0xe is reserved for log2(RB_POWEROFF). */
+#define RBX_GDB 0xf /* -g */
+#define RBX_MUTE 0x10 /* -m */
+/* 0x11 is reserved for log2(RB_SELFTEST). */
+/* 0x12 is reserved for boot programs. */
+/* 0x13 is reserved for boot programs. */
+#define RBX_PAUSE 0x14 /* -p */
+#define RBX_QUIET 0x15 /* -q */
+#define RBX_NOINTR 0x1c /* -n */
+/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
+#define RBX_DUAL 0x1d /* -D */
+/* 0x1f is reserved for log2(RB_BOOTINFO). */
+
+/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
+#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
+ OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
+ OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
+ OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
+ OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
+ OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
+
+#define OPT_SET(opt) (1 << (opt))
+#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
+
+extern uint32_t opts;
+
+#endif /* !_RBX_H_ */
diff --git a/usr/src/boot/sys/boot/common/reloc_elf.c b/usr/src/boot/sys/boot/common/reloc_elf.c
new file mode 100644
index 0000000000..188d259069
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/reloc_elf.c
@@ -0,0 +1,231 @@
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * Copyright 1996-1998 John D. Polstra.
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998 Peter Wemm <peter@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#define FREEBSD_ELF
+#include <link.h>
+
+#include "bootstrap.h"
+
+#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l)
+
+/*
+ * Apply a single intra-module relocation to the data. `relbase' is the
+ * target relocation base for the section (i.e. it corresponds to where
+ * r_offset == 0). `dataaddr' is the relocated address corresponding to
+ * the start of the data, and `len' is the number of bytes.
+ */
+int
+__elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata,
+ int reltype, Elf_Addr relbase, Elf_Addr dataaddr, void *data, size_t len)
+{
+#ifdef __sparc__
+ Elf_Size w;
+ const Elf_Rela *a;
+
+ switch (reltype) {
+ case ELF_RELOC_RELA:
+ a = reldata;
+ if (relbase + a->r_offset >= dataaddr &&
+ relbase + a->r_offset < dataaddr + len) {
+ switch (ELF_R_TYPE(a->r_info)) {
+ case R_SPARC_RELATIVE:
+ w = relbase + a->r_addend;
+ bcopy(&w, (u_char *)data + (relbase +
+ a->r_offset - dataaddr), sizeof(w));
+ break;
+ default:
+ printf("\nunhandled relocation type %u\n",
+ (u_int)ELF_R_TYPE(a->r_info));
+ return (EFTYPE);
+ }
+ }
+ break;
+ }
+
+ return (0);
+#elif (defined(__i386__) || defined(__amd64__)) && __ELF_WORD_SIZE == 64
+ Elf64_Addr *where, val;
+ Elf_Addr addend, addr;
+ Elf_Size rtype, symidx;
+ const Elf_Rel *rel;
+ const Elf_Rela *rela;
+
+ switch (reltype) {
+ case ELF_RELOC_REL:
+ rel = (const Elf_Rel *)reldata;
+ where = (Elf_Addr *)((char *)data + relbase + rel->r_offset -
+ dataaddr);
+ addend = 0;
+ rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
+ addend = 0;
+ break;
+ case ELF_RELOC_RELA:
+ rela = (const Elf_Rela *)reldata;
+ where = (Elf_Addr *)((char *)data + relbase + rela->r_offset -
+ dataaddr);
+ addend = rela->r_addend;
+ rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ if ((char *)where < (char *)data || (char *)where >= (char *)data + len)
+ return (0);
+
+ if (reltype == ELF_RELOC_REL)
+ addend = *where;
+
+/* XXX, definitions not available on i386. */
+#define R_X86_64_64 1
+#define R_X86_64_RELATIVE 8
+
+ switch (rtype) {
+ case R_X86_64_64: /* S + A */
+ addr = symaddr(ef, symidx);
+ if (addr == 0)
+ return (ESRCH);
+ val = addr + addend;
+ *where = val;
+ break;
+ case R_X86_64_RELATIVE:
+ addr = (Elf_Addr)addend + relbase;
+ val = addr;
+ *where = val;
+ break;
+ default:
+ printf("\nunhandled relocation type %u\n", (u_int)rtype);
+ return (EFTYPE);
+ }
+
+ return (0);
+#elif defined(__i386__) && __ELF_WORD_SIZE == 32
+ Elf_Addr addend, addr, *where, val;
+ Elf_Size rtype, symidx;
+ const Elf_Rel *rel;
+ const Elf_Rela *rela;
+
+ switch (reltype) {
+ case ELF_RELOC_REL:
+ rel = (const Elf_Rel *)reldata;
+ where = (Elf_Addr *)((char *)data + relbase + rel->r_offset -
+ dataaddr);
+ addend = 0;
+ rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
+ addend = 0;
+ break;
+ case ELF_RELOC_RELA:
+ rela = (const Elf_Rela *)reldata;
+ where = (Elf_Addr *)((char *)data + relbase + rela->r_offset -
+ dataaddr);
+ addend = rela->r_addend;
+ rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ if ((char *)where < (char *)data || (char *)where >= (char *)data + len)
+ return (0);
+
+ if (reltype == ELF_RELOC_REL)
+ addend = *where;
+
+/* XXX, definitions not available on amd64. */
+#define R_386_32 1 /* Add symbol value. */
+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_386_RELATIVE 8 /* Add load address of shared object. */
+
+ switch (rtype) {
+ case R_386_RELATIVE:
+ addr = addend + relbase;
+ *where = addr;
+ break;
+ case R_386_32: /* S + A */
+ addr = symaddr(ef, symidx);
+ if (addr == 0)
+ return (ESRCH);
+ val = addr + addend;
+ *where = val;
+ break;
+ default:
+ printf("\nunhandled relocation type %u\n", (u_int)rtype);
+ return (EFTYPE);
+ }
+
+ return (0);
+#elif defined(__powerpc__)
+ Elf_Size w;
+ const Elf_Rela *rela;
+
+ switch (reltype) {
+ case ELF_RELOC_RELA:
+ rela = reldata;
+ if (relbase + rela->r_offset >= dataaddr &&
+ relbase + rela->r_offset < dataaddr + len) {
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_PPC_RELATIVE:
+ w = relbase + rela->r_addend;
+ bcopy(&w, (u_char *)data + (relbase +
+ rela->r_offset - dataaddr), sizeof(w));
+ break;
+ default:
+ printf("\nunhandled relocation type %u\n",
+ (u_int)ELF_R_TYPE(rela->r_info));
+ return (EFTYPE);
+ }
+ }
+ break;
+ }
+
+ return (0);
+#else
+ (void)ef;
+ (void)symaddr;
+ (void)reldata;
+ (void)reltype;
+ (void)relbase;
+ (void)dataaddr;
+ (void)data;
+ (void)len;
+ return (EOPNOTSUPP);
+#endif
+}
diff --git a/usr/src/boot/sys/boot/common/reloc_elf32.c b/usr/src/boot/sys/boot/common/reloc_elf32.c
new file mode 100644
index 0000000000..03d9d73bab
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/reloc_elf32.c
@@ -0,0 +1,6 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 32
+
+#include "reloc_elf.c"
diff --git a/usr/src/boot/sys/boot/common/reloc_elf64.c b/usr/src/boot/sys/boot/common/reloc_elf64.c
new file mode 100644
index 0000000000..c8dcf2a36b
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/reloc_elf64.c
@@ -0,0 +1,6 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include "reloc_elf.c"
diff --git a/usr/src/boot/sys/boot/common/self_reloc.c b/usr/src/boot/sys/boot/common/self_reloc.c
new file mode 100644
index 0000000000..3b27b17c76
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/self_reloc.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <elf.h>
+#include <bootstrap.h>
+
+#if defined(__aarch64__)
+#define ElfW_Rel Elf64_Rela
+#define ElfW_Dyn Elf64_Dyn
+#define ELFW_R_TYPE ELF64_R_TYPE
+#define ELF_RELA
+#elif defined(__arm__) || defined(__i386__)
+#define ElfW_Rel Elf32_Rel
+#define ElfW_Dyn Elf32_Dyn
+#define ELFW_R_TYPE ELF32_R_TYPE
+#elif defined(__amd64__)
+#define ElfW_Rel Elf64_Rel
+#define ElfW_Dyn Elf64_Dyn
+#define ELFW_R_TYPE ELF64_R_TYPE
+#else
+#error architecture not supported
+#endif
+#if defined(__aarch64__)
+#define RELOC_TYPE_NONE R_AARCH64_NONE
+#define RELOC_TYPE_RELATIVE R_AARCH64_RELATIVE
+#elif defined(__amd64__)
+#define RELOC_TYPE_NONE R_X86_64_NONE
+#define RELOC_TYPE_RELATIVE R_X86_64_RELATIVE
+#elif defined(__arm__)
+#define RELOC_TYPE_NONE R_ARM_NONE
+#define RELOC_TYPE_RELATIVE R_ARM_RELATIVE
+#elif defined(__i386__)
+#define RELOC_TYPE_NONE R_386_NONE
+#define RELOC_TYPE_RELATIVE R_386_RELATIVE
+#endif
+
+void self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic);
+
+/*
+ * A simple elf relocator.
+ */
+void
+self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic)
+{
+ Elf_Word relsz, relent;
+ Elf_Addr *newaddr;
+ ElfW_Rel *rel = 0;
+ ElfW_Dyn *dynp;
+
+ /*
+ * Find the relocation address, its size and the relocation entry.
+ */
+ relsz = 0;
+ relent = 0;
+ for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_REL:
+ case DT_RELA:
+ rel = (ElfW_Rel *)(dynp->d_un.d_ptr + baseaddr);
+ break;
+ case DT_RELSZ:
+ case DT_RELASZ:
+ relsz = dynp->d_un.d_val;
+ break;
+ case DT_RELENT:
+ case DT_RELAENT:
+ relent = dynp->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Perform the actual relocation.
+ */
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELFW_R_TYPE(rel->r_info)) {
+ case RELOC_TYPE_NONE:
+ /* No relocation needs be performed. */
+ break;
+
+ case RELOC_TYPE_RELATIVE:
+ /* Address relative to the base address. */
+ newaddr = (Elf_Addr *)(rel->r_offset + baseaddr);
+ *newaddr += baseaddr;
+ /* Add the addend when the ABI uses them */
+#ifdef ELF_RELA
+ *newaddr += rel->r_addend;
+#endif
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ break;
+ }
+ rel = (ElfW_Rel *)(void *)((caddr_t) rel + relent);
+ }
+}
diff --git a/usr/src/boot/sys/boot/common/ufsread.c b/usr/src/boot/sys/boot/common/ufsread.c
new file mode 100644
index 0000000000..1ceb533352
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/ufsread.c
@@ -0,0 +1,366 @@
+/*-
+ * Copyright (c) 2002 McAfee, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and McAfee Research,, the Security Research Division of
+ * McAfee, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as
+ * part of the DARPA CHATS research program
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+
+#ifdef UFS_SMALL_CGBASE
+/* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase
+ (see sys/ufs/ffs/fs.h rev 1.39) so that small boot loaders (e.g. boot2) can
+ support both UFS1 and UFS2. */
+#undef cgbase
+#define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c)))
+#endif
+
+typedef uint32_t ufs_ino_t;
+
+/*
+ * We use 4k `virtual' blocks for filesystem data, whatever the actual
+ * filesystem block size. FFS blocks are always a multiple of 4k.
+ */
+#define VBLKSHIFT 12
+#define VBLKSIZE (1 << VBLKSHIFT)
+#define VBLKMASK (VBLKSIZE - 1)
+#define DBPERVBLK (VBLKSIZE / DEV_BSIZE)
+#define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
+#define IPERVBLK(fs) (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
+#define INO_TO_VBA(fs, ipervblk, x) \
+ (fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \
+ (((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK))
+#define INO_TO_VBO(ipervblk, x) ((x) % ipervblk)
+#define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \
+ ((off) / VBLKSIZE) * DBPERVBLK)
+#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK)
+
+/* Buffers that must not span a 64k boundary. */
+struct dmadat {
+ char blkbuf[VBLKSIZE]; /* filesystem blocks */
+ char indbuf[VBLKSIZE]; /* indir blocks */
+ char sbbuf[SBLOCKSIZE]; /* superblock */
+ char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
+};
+static struct dmadat *dmadat;
+
+static ufs_ino_t lookup(const char *);
+static ssize_t fsread(ufs_ino_t, void *, size_t);
+static uint8_t inode_type(ufs_ino_t inode);
+
+static uint8_t ls, dsk_meta;
+static uint32_t fs_off;
+
+#ifndef UFS2_ONLY
+static struct ufs1_dinode dp1;
+ufs1_daddr_t addr1;
+#endif
+#ifndef UFS1_ONLY
+static struct ufs2_dinode dp2;
+#endif
+static struct fs fs;
+static ufs_ino_t inomap;
+static ufs2_daddr_t blkmap, indmap;
+
+static __inline uint8_t
+fsfind(const char *name, ufs_ino_t * ino)
+{
+ static char buf[DEV_BSIZE];
+ struct direct *d;
+ char *s;
+ ssize_t n;
+
+ fs_off = 0;
+ while ((n = fsread(*ino, buf, DEV_BSIZE)) > 0)
+ for (s = buf; s < buf + DEV_BSIZE;) {
+ d = (void *)s;
+ if (ls)
+ printf("%s ", d->d_name);
+ else if (!strcmp(name, d->d_name)) {
+ *ino = d->d_ino;
+ return inode_type(*ino);
+ }
+ s += d->d_reclen;
+ }
+ if (n != -1 && ls)
+ printf("\n");
+ return 0;
+}
+
+static ufs_ino_t
+lookup(const char *path)
+{
+ static char name[MAXNAMLEN + 1];
+ const char *s;
+ ufs_ino_t ino;
+ ssize_t n;
+ uint8_t dt;
+
+ ino = ROOTINO;
+ dt = DT_DIR;
+ for (;;) {
+ if (*path == '/')
+ path++;
+ if (!*path)
+ break;
+ for (s = path; *s && *s != '/'; s++);
+ if ((n = s - path) > MAXNAMLEN)
+ return 0;
+ ls = *path == '?' && n == 1 && !*s;
+ memcpy(name, path, n);
+ name[n] = 0;
+ if (dt != DT_DIR) {
+ printf("%s: not a directory.\n", name);
+ return (0);
+ }
+ if ((dt = fsfind(name, &ino)) <= 0)
+ break;
+ path = s;
+ }
+ return dt == DT_REG ? ino : 0;
+}
+
+/*
+ * Possible superblock locations ordered from most to least likely.
+ */
+static int sblock_try[] = SBLOCKSEARCH;
+
+#if defined(UFS2_ONLY)
+#define DIP(field) dp2.field
+#elif defined(UFS1_ONLY)
+#define DIP(field) dp1.field
+#else
+#define DIP(field) fs.fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field
+#endif
+
+static uint8_t
+inode_type(ufs_ino_t inode)
+{
+ char *blkbuf;
+ void *indbuf;
+ size_t n;
+
+ blkbuf = dmadat->blkbuf;
+ indbuf = dmadat->indbuf;
+
+ if (!inode)
+ return (0);
+ if (inomap != inode) {
+ n = IPERVBLK(&fs);
+ if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
+ return (-1);
+ n = INO_TO_VBO(n, inode);
+#if defined(UFS1_ONLY)
+ memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
+ sizeof(struct ufs1_dinode));
+#elif defined(UFS2_ONLY)
+ memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
+ sizeof(struct ufs2_dinode));
+#else
+ if (fs.fs_magic == FS_UFS1_MAGIC)
+ memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
+ sizeof(struct ufs1_dinode));
+ else
+ memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
+ sizeof(struct ufs2_dinode));
+#endif
+ inomap = inode;
+ fs_off = 0;
+ blkmap = indmap = 0;
+ }
+ return (IFTODT(DIP(di_mode)));
+}
+
+static ssize_t
+fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep)
+{
+ char *blkbuf;
+ void *indbuf;
+ char *s;
+ size_t n, nb, size, off, vboff;
+ ufs_lbn_t lbn;
+ ufs2_daddr_t addr2, vbaddr;
+ u_int u;
+
+ /* Basic parameter validation. */
+ if ((buf == NULL && nbyte != 0) || dmadat == NULL)
+ return (-1);
+
+ blkbuf = dmadat->blkbuf;
+ indbuf = dmadat->indbuf;
+
+ /*
+ * Force probe if inode is zero to ensure we have a valid fs, otherwise
+ * when probing multiple paritions, reads from subsequent parititions
+ * will incorrectly succeed.
+ */
+ if (!dsk_meta || inode == 0) {
+ inomap = 0;
+ dsk_meta = 0;
+ for (n = 0; sblock_try[n] != -1; n++) {
+ if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
+ SBLOCKSIZE / DEV_BSIZE))
+ return -1;
+ memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
+ if ((
+#if defined(UFS1_ONLY)
+ fs.fs_magic == FS_UFS1_MAGIC
+#elif defined(UFS2_ONLY)
+ (fs.fs_magic == FS_UFS2_MAGIC &&
+ fs.fs_sblockloc == sblock_try[n])
+#else
+ fs.fs_magic == FS_UFS1_MAGIC ||
+ (fs.fs_magic == FS_UFS2_MAGIC &&
+ fs.fs_sblockloc == sblock_try[n])
+#endif
+ ) &&
+ fs.fs_bsize <= MAXBSIZE &&
+ fs.fs_bsize >= (int32_t)sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[n] == -1) {
+ return -1;
+ }
+ dsk_meta++;
+ } else
+ memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
+ if (!inode)
+ return 0;
+ if (inomap != inode) {
+ n = IPERVBLK(&fs);
+ if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
+ return -1;
+ n = INO_TO_VBO(n, inode);
+#if defined(UFS1_ONLY)
+ memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
+ sizeof(dp1));
+#elif defined(UFS2_ONLY)
+ memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
+ sizeof(dp2));
+#else
+ if (fs.fs_magic == FS_UFS1_MAGIC)
+ memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
+ sizeof(dp1));
+ else
+ memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
+ sizeof(dp2));
+#endif
+ inomap = inode;
+ fs_off = 0;
+ blkmap = indmap = 0;
+ }
+ s = buf;
+ size = DIP(di_size);
+ n = size - fs_off;
+ if (nbyte > n)
+ nbyte = n;
+ nb = nbyte;
+ while (nb) {
+ lbn = lblkno(&fs, fs_off);
+ off = blkoff(&fs, fs_off);
+ if (lbn < NDADDR) {
+ addr2 = DIP(di_db[lbn]);
+ } else if (lbn < NDADDR + NINDIR(&fs)) {
+ n = INDIRPERVBLK(&fs);
+ addr2 = DIP(di_ib[0]);
+ u = (u_int)(lbn - NDADDR) / n * DBPERVBLK;
+ vbaddr = fsbtodb(&fs, addr2) + u;
+ if (indmap != vbaddr) {
+ if (dskread(indbuf, vbaddr, DBPERVBLK))
+ return -1;
+ indmap = vbaddr;
+ }
+ n = (lbn - NDADDR) & (n - 1);
+#if defined(UFS1_ONLY)
+ memcpy(&addr1, (ufs1_daddr_t *)indbuf + n,
+ sizeof(ufs1_daddr_t));
+ addr2 = addr1;
+#elif defined(UFS2_ONLY)
+ memcpy(&addr2, (ufs2_daddr_t *)indbuf + n,
+ sizeof(ufs2_daddr_t));
+#else
+ if (fs.fs_magic == FS_UFS1_MAGIC) {
+ memcpy(&addr1, (ufs1_daddr_t *)indbuf + n,
+ sizeof(ufs1_daddr_t));
+ addr2 = addr1;
+ } else
+ memcpy(&addr2, (ufs2_daddr_t *)indbuf + n,
+ sizeof(ufs2_daddr_t));
+#endif
+ } else
+ return -1;
+ vbaddr = fsbtodb(&fs, addr2) + (off >> VBLKSHIFT) * DBPERVBLK;
+ vboff = off & VBLKMASK;
+ n = sblksize(&fs, (off_t)size, lbn) - (off & ~VBLKMASK);
+ if (n > VBLKSIZE)
+ n = VBLKSIZE;
+ if (blkmap != vbaddr) {
+ if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT))
+ return -1;
+ blkmap = vbaddr;
+ }
+ n -= vboff;
+ if (n > nb)
+ n = nb;
+ memcpy(s, blkbuf + vboff, n);
+ s += n;
+ fs_off += n;
+ nb -= n;
+ }
+
+ if (fsizep != NULL)
+ *fsizep = size;
+
+ return nbyte;
+}
+
+static ssize_t
+fsread(ufs_ino_t inode, void *buf, size_t nbyte)
+{
+
+ return fsread_size(inode, buf, nbyte, NULL);
+}
+
diff --git a/usr/src/boot/sys/boot/common/util.c b/usr/src/boot/sys/boot/common/util.c
new file mode 100644
index 0000000000..455053dab8
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/util.c
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <stdarg.h>
+
+#include "cons.h"
+#include "util.h"
+
+void
+memcpy(void *dst, const void *src, int len)
+{
+ const char *s = src;
+ char *d = dst;
+
+ while (len--)
+ *d++ = *s++;
+}
+
+void
+memset(void *b, int c, size_t len)
+{
+ char *bp = b;
+
+ while (len--)
+ *bp++ = (unsigned char)c;
+}
+
+int
+memcmp(const void *b1, const void *b2, size_t len)
+{
+ const unsigned char *p1, *p2;
+
+ for (p1 = b1, p2 = b2; len > 0; len--, p1++, p2++) {
+ if (*p1 != *p2)
+ return ((*p1) - (*p2));
+ }
+ return (0);
+}
+
+int
+strcmp(const char *s1, const char *s2)
+{
+
+ for (; *s1 == *s2 && *s1 != '\0'; s1++, s2++)
+ ;
+ return ((unsigned char)*s1 - (unsigned char)*s2);
+}
+
+int
+strncmp(const char *s1, const char *s2, size_t len)
+{
+
+ for (; len > 0 && *s1 == *s2 && *s1 != '\0'; len--, s1++, s2++)
+ ;
+ return (len == 0 ? 0 : (unsigned char)*s1 - (unsigned char)*s2);
+}
+
+void
+strcpy(char *dst, const char *src)
+{
+
+ while (*src != '\0')
+ *dst++ = *src++;
+ *dst = '\0';
+}
+
+void
+strcat(char *dst, const char *src)
+{
+
+ while (*dst != '\0')
+ dst++;
+ while (*src != '\0')
+ *dst++ = *src++;
+ *dst = '\0';
+}
+
+char *
+strchr(const char *s, char ch)
+{
+
+ for (; *s != '\0'; s++) {
+ if (*s == ch)
+ return ((char *)(uintptr_t)(const void *)s);
+ }
+ return (NULL);
+}
+
+size_t
+strlen(const char *s)
+{
+ size_t len = 0;
+
+ while (*s++ != '\0')
+ len++;
+ return (len);
+}
+
+int
+printf(const char *fmt, ...)
+{
+ va_list ap;
+ const char *hex = "0123456789abcdef";
+ char buf[32], *s;
+ unsigned long long u;
+ int c, l;
+
+ va_start(ap, fmt);
+ while ((c = *fmt++) != '\0') {
+ if (c != '%') {
+ putchar(c);
+ continue;
+ }
+ l = 0;
+nextfmt:
+ c = *fmt++;
+ switch (c) {
+ case 'l':
+ l++;
+ goto nextfmt;
+ case 'c':
+ putchar(va_arg(ap, int));
+ break;
+ case 's':
+ for (s = va_arg(ap, char *); *s != '\0'; s++)
+ putchar(*s);
+ break;
+ case 'd': /* A lie, always prints unsigned */
+ case 'u':
+ case 'x':
+ switch (l) {
+ case 2:
+ u = va_arg(ap, unsigned long long);
+ break;
+ case 1:
+ u = va_arg(ap, unsigned long);
+ break;
+ default:
+ u = va_arg(ap, unsigned int);
+ break;
+ }
+ s = buf;
+ if (c == 'd' || c == 'u') {
+ do
+ *s++ = '0' + (u % 10U);
+ while (u /= 10);
+ } else {
+ do
+ *s++ = hex[u & 0xfu];
+ while (u >>= 4);
+ }
+ while (--s >= buf)
+ putchar(*s);
+ break;
+ }
+ }
+ va_end(ap);
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/common/util.h b/usr/src/boot/sys/boot/common/util.h
new file mode 100644
index 0000000000..88a99f19f0
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/util.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+
+void memcpy(void *dst, const void *src, int len);
+void memset(void *b, int c, size_t len);
+int memcmp(const void *b1, const void *b2, size_t len);
+
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bzero(buf, size) memset((buf), 0, (size))
+#define bcmp(b1, b2, len) (memcmp((b1), (b2), (len)) != 0)
+
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, size_t len);
+void strcpy(char *dst, const char *src);
+void strcat(char *dst, const char *src);
+char *strchr(const char *s, char ch);
+size_t strlen(const char *s);
+
+int printf(const char *fmt, ...);
+
+#endif /* !_UTIL_H_ */
diff --git a/usr/src/boot/sys/boot/common/zfsloader.8 b/usr/src/boot/sys/boot/common/zfsloader.8
new file mode 100644
index 0000000000..fd437d9399
--- /dev/null
+++ b/usr/src/boot/sys/boot/common/zfsloader.8
@@ -0,0 +1,106 @@
+.\" Copyright (c) 2014 Andriy Gapon <avg@FreeBSD.org>
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 15, 2014
+.Dt ZFSLOADER 8
+.Os
+.Sh NAME
+.Nm zfsloader
+.Nd kernel bootstrapping final stage
+.Sh DESCRIPTION
+.Nm
+is an extended variant of
+.Xr loader 8
+with added support for booting from ZFS.
+This document describes only differences from
+.Xr loader 8 .
+.Sh ZFS FEATURES
+.Nm
+supports the following format for specifying ZFS filesystems which
+can be used wherever
+.Xr loader 8
+refers to a device specification:
+.Pp
+.Ar zfs:pool/filesystem:
+.Pp
+where
+.Pa pool/filesystem
+is a ZFS filesystem name as described in
+.Xr zfs 8 .
+.Pp
+If
+.Pa /etc/fstab
+does not have an entry for the root filesystem and
+.Va vfs.root.mountfrom
+is not set, but
+.Va currdev
+refers to a ZFS filesystem, then
+.Nm
+will instruct kernel to use that filesystem as the root filesystem.
+.Sh ZFS COMMAND EXTENSIONS
+.Bl -tag -width Ds -compact
+.It Ic lsdev Op Fl v
+Lists ZFS pools in addition to disks and partitions.
+Adding
+.Fl v
+shows more ZFS pool details in a format that resembles
+.Nm zpool Cm status
+output.
+.Pp
+.It Ic lszfs Ar filesystem
+A ZFS extended command that can be used to explore the ZFS filesystem
+hierarchy in a pool.
+Lists the immediate children of the
+.Ar filesystem .
+The filesystem hierarchy is rooted at a filesystem with the same name
+as the pool.
+.El
+.Sh FILES
+.Bl -tag -width /boot/zfsloader -compact
+.It Pa /boot/zfsloader
+.Nm
+itself.
+.El
+.Sh EXAMPLES
+Set the default device used for loading a kernel from a ZFS filesystem:
+.Bd -literal -offset indent
+set currdev=zfs:tank/ROOT/knowngood:
+.Ed
+.Sh SEE ALSO
+.Xr gptzfsboot 8 ,
+.Xr loader 8 ,
+.Xr zfs 8 ,
+.Xr zfsboot 8 ,
+.Xr zfsloader 8 ,
+.Xr zpool 8
+.Sh HISTORY
+The
+.Nm
+first appeared in
+.Fx 7.3 .
+.Sh AUTHORS
+This manual page was written by
+.An Andriy Gapon Aq avg@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/efi/Makefile b/usr/src/boot/sys/boot/efi/Makefile
new file mode 100644
index 0000000000..e22e8615e0
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/Makefile
@@ -0,0 +1,39 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+.KEEP_STATE:
+
+include $(SRC)/Makefile.master
+
+SUBDIRS = boot1 libefi loader
+
+#.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
+#.if ${MK_FDT} != "no"
+#SUBDIRS+= fdt
+#.endif
+#.endif
+
+
+all install clean clobber: $(SUBDIRS)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/boot/sys/boot/efi/Makefile.inc b/usr/src/boot/sys/boot/efi/Makefile.inc
new file mode 100644
index 0000000000..2253891b5a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/Makefile.inc
@@ -0,0 +1,31 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+BINDIR= /boot
+
+# Options used when building app-specific efi components
+# See conf/kern.mk for the correct set of these
+CFLAGS += -m64 -fPIC -ffreestanding -Wformat -msoft-float
+CFLAGS += -mno-mmx -mno-sse -mno-avx -fshort-wchar -mno-red-zone -mno-aes
+CFLAGS += -std=gnu99 -Wno-pointer-sign -Wno-empty-body
+
+#CFLAGS += -Wsystem-headers -Werror -Wall -Wno-format-y2k -W
+#CFLAGS += -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes
+#CFLAGS += -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings
+#CFLAGS += -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wno-cast-qual
+#CFLAGS += -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls
+#CFLAGS += -Wold-style-definition
+
+# include ../Makefile.inc
diff --git a/usr/src/boot/sys/boot/efi/boot1/Makefile b/usr/src/boot/sys/boot/efi/boot1/Makefile
new file mode 100644
index 0000000000..01d8d95fdc
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/boot1/Makefile
@@ -0,0 +1,126 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+CC= $(GCC_ROOT)/bin/gcc
+LD= $(GNU_ROOT)/bin/gld
+OBJCOPY= $(GNU_ROOT)/bin/gobjcopy
+OBJDUMP= $(GNU_ROOT)/bin/gobjdump
+OBJCOPY= /code/binutils-gdb/binutils/objcopy
+OBJDUMP= /code/binutils-gdb/binutils/objdump
+
+PROG= boot1.sym
+MACHINE=$(MACH64)
+
+# need to update this to trigger installboot updates.
+BUILDDATE :sh = TZ=UTC date +%Y%m%dT%H%M%SZ
+BOOT1_VERSION= 1.1:$(BUILDDATE)
+
+# architecture-specific loader code
+SRCS= boot1.c self_reloc.c start.S ufs_module.c zfs_module.c devopen.c
+OBJS= boot1.o self_reloc.o start.o ufs_module.o zfs_module.o devopen.o
+
+ASFLAGS=-m64 -fPIC
+CFLAGS= -O2
+CPPFLAGS= -nostdinc
+CPPFLAGS += -I.
+CPPFLAGS += -I./../include
+CPPFLAGS += -I./../include/${MACHINE}
+CPPFLAGS += -I./../../../contrib/dev/acpica/include
+CPPFLAGS += -I./../../../../include
+CPPFLAGS += -I./../../../sys
+CPPFLAGS += -I./../../..
+CPPFLAGS += -I../../../../lib/libstand
+CPPFLAGS += -DEFI_UFS_BOOT
+# CPPFLAGS += -DEFI_DEBUG
+
+CPPFLAGS += -I./../../zfs/
+CPPFLAGS += -I./../../../cddl/boot/zfs/
+CPPFLAGS += -DEFI_ZFS_BOOT
+
+# Always add MI sources and REGULAR efi loader bits
+CPPFLAGS += -I./../../common
+
+include ../Makefile.inc
+
+FILES= boot1.efi
+FILEMODE= 0555
+ROOT_BOOT= $(ROOT)/boot
+ROOTBOOTFILES=$(FILES:%=$(ROOT_BOOT)/%)
+
+LDSCRIPT= ./../loader/arch/${MACHINE}/ldscript.${MACHINE}
+LDFLAGS= -nostdlib --eh-frame-hdr -znocombreloc
+LDFLAGS += -shared --hash-style=both --enable-new-dtags
+LDFLAGS += -T${LDSCRIPT} -Bsymbolic
+
+all: machine x86 boot1.efi
+install: all $(ROOTBOOTFILES)
+
+#
+# Add libstand for the runtime functions used by the compiler - for example
+# __aeabi_* (arm) or __divdi3 (i386).
+# as well as required string and memory functions for all platforms.
+#
+LIBSTAND= ../../libstand/$(MACH64)/libstand.a
+LIBZFSBOOT= ../../zfs/$(MACH64)/libzfsboot.a
+DPADD= ${LIBSTAND} ${LIBZFSBOOT}
+LDADD= -L../../zfs/$(MACH64) -lzfsboot -L../../libstand/$(MACH64) -lstand
+
+DPADD += ${LDSCRIPT}
+
+EFI_TARGET= pei-x86-64
+
+boot1.efi: ${PROG}
+ if [ `${OBJDUMP} -t ${PROG} | fgrep '*UND*' | wc -l` != 0 ]; then \
+ ${OBJDUMP} -t ${PROG} | fgrep '*UND*'; \
+ exit 1; \
+ fi
+ ${OBJCOPY} --readonly-text -j .peheader -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel.dyn \
+ -j .rela.dyn -j .reloc -j .eh_frame \
+ --output-target=${EFI_TARGET} --subsystem efi-app ${PROG} $@
+
+boot1.o: ./../../common/ufsread.c
+
+CLEANFILES= boot1.efi ${PROG}
+
+${PROG}: $(OBJS) $(DPADD)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDADD)
+
+CLEANFILES += machine x86
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ./../../../${MACHINE}/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ./../../../x86/include x86
+
+clean clobber:
+ $(RM) $(CLEANFILES) $(OBJS)
+
+%.o: ../loader/arch/${MACHINE}/%.S
+ $(COMPILE.S) $<
+
+%.o: ../loader/%.c
+ $(COMPILE.c) $<
+
+%.o: ../../common/%.c
+ $(COMPILE.c) $<
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/efi/boot1/boot1.c b/usr/src/boot/sys/boot/efi/boot1/boot1.c
new file mode 100644
index 0000000000..b11c93e934
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/boot1/boot1.c
@@ -0,0 +1,748 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ * Copyright (c) 2014 Nathan Whitehorn
+ * All rights reserved.
+ * Copyright (c) 2015 Eric McCorkle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <machine/elf.h>
+#include <machine/stdarg.h>
+#include <stand.h>
+
+#include <efi.h>
+#include <eficonsctl.h>
+
+#include <bootstrap.h>
+#include "boot_module.h"
+#include "paths.h"
+
+struct arch_switch archsw;
+struct fs_ops *file_system[] = {
+ NULL
+};
+
+static const boot_module_t *boot_modules[] =
+{
+#ifdef EFI_ZFS_BOOT
+ &zfs_module,
+#endif
+#ifdef EFI_UFS_BOOT
+ &ufs_module
+#endif
+};
+
+#define NUM_BOOT_MODULES (sizeof(boot_modules) / sizeof(boot_module_t*))
+/* The initial number of handles used to query EFI for partitions. */
+#define NUM_HANDLES_INIT 24
+
+EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
+
+EFI_SYSTEM_TABLE *systab;
+EFI_BOOT_SERVICES *bs;
+static EFI_HANDLE *image;
+
+static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
+static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
+static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+
+/*
+ * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
+ * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
+ * EFI methods.
+ */
+void *
+Malloc(size_t len, const char *file __unused, int line __unused)
+{
+ void *out;
+
+ if (bs->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
+ return (out);
+
+ return (NULL);
+}
+
+void
+Free(void *buf, const char *file __unused, int line __unused)
+{
+ (void)bs->FreePool(buf);
+}
+
+/*
+ * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
+ * FALSE otherwise.
+ */
+static BOOLEAN
+nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+{
+ int len;
+
+ if (imgpath == NULL || imgpath->Type != devpath->Type ||
+ imgpath->SubType != devpath->SubType)
+ return (FALSE);
+
+ len = DevicePathNodeLength(imgpath);
+ if (len != DevicePathNodeLength(devpath))
+ return (FALSE);
+
+ return (memcmp(imgpath, devpath, (size_t)len) == 0);
+}
+
+/*
+ * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
+ * in imgpath and devpath match up to their respect occurances of a media
+ * node, FALSE otherwise.
+ */
+static BOOLEAN
+device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+{
+
+ if (imgpath == NULL)
+ return (FALSE);
+
+ while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
+ if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
+ IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
+ return (TRUE);
+
+ if (!nodes_match(imgpath, devpath))
+ return (FALSE);
+
+ imgpath = NextDevicePathNode(imgpath);
+ devpath = NextDevicePathNode(devpath);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * devpath_last returns the last non-path end node in devpath.
+ */
+static EFI_DEVICE_PATH *
+devpath_last(EFI_DEVICE_PATH *devpath)
+{
+
+ while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
+ devpath = NextDevicePathNode(devpath);
+
+ return (devpath);
+}
+
+/*
+ * devpath_node_str is a basic output method for a devpath node which
+ * only understands a subset of the available sub types.
+ *
+ * If we switch to UEFI 2.x then we should update it to use:
+ * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
+ */
+static int
+devpath_node_str(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
+{
+
+ switch (devpath->Type) {
+ case MESSAGING_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case MSG_ATAPI_DP: {
+ ATAPI_DEVICE_PATH *atapi;
+
+ atapi = (ATAPI_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "ata(%s,%s,0x%x)",
+ (atapi->PrimarySecondary == 1) ? "Sec" : "Pri",
+ (atapi->SlaveMaster == 1) ? "Slave" : "Master",
+ atapi->Lun);
+ }
+ case MSG_USB_DP: {
+ USB_DEVICE_PATH *usb;
+
+ usb = (USB_DEVICE_PATH *)devpath;
+ return snprintf(buf, size, "usb(0x%02x,0x%02x)",
+ usb->ParentPortNumber, usb->InterfaceNumber);
+ }
+ case MSG_SCSI_DP: {
+ SCSI_DEVICE_PATH *scsi;
+
+ scsi = (SCSI_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "scsi(0x%02x,0x%02x)",
+ scsi->Pun, scsi->Lun);
+ }
+ case MSG_SATA_DP: {
+ SATA_DEVICE_PATH *sata;
+
+ sata = (SATA_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "sata(0x%x,0x%x,0x%x)",
+ sata->HBAPortNumber, sata->PortMultiplierPortNumber,
+ sata->Lun);
+ }
+ default:
+ return snprintf(buf, size, "msg(0x%02x)",
+ devpath->SubType);
+ }
+ break;
+ case HARDWARE_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case HW_PCI_DP: {
+ PCI_DEVICE_PATH *pci;
+
+ pci = (PCI_DEVICE_PATH *)devpath;
+ return snprintf(buf, size, "pci(0x%02x,0x%02x)",
+ pci->Device, pci->Function);
+ }
+ default:
+ return snprintf(buf, size, "hw(0x%02x)",
+ devpath->SubType);
+ }
+ break;
+ case ACPI_DEVICE_PATH: {
+ ACPI_HID_DEVICE_PATH *acpi;
+
+ acpi = (ACPI_HID_DEVICE_PATH *)(void *)devpath;
+ if ((acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ switch (EISA_ID_TO_NUM(acpi->HID)) {
+ case 0x0a03:
+ return snprintf(buf, size, "pciroot(0x%x)",
+ acpi->UID);
+ case 0x0a08:
+ return snprintf(buf, size, "pcieroot(0x%x)",
+ acpi->UID);
+ case 0x0604:
+ return snprintf(buf, size, "floppy(0x%x)",
+ acpi->UID);
+ case 0x0301:
+ return snprintf(buf, size, "keyboard(0x%x)",
+ acpi->UID);
+ case 0x0501:
+ return snprintf(buf, size, "serial(0x%x)",
+ acpi->UID);
+ case 0x0401:
+ return snprintf(buf, size, "parallelport(0x%x)",
+ acpi->UID);
+ default:
+ return snprintf(buf, size, "acpi(pnp%04x,0x%x)",
+ EISA_ID_TO_NUM(acpi->HID), acpi->UID);
+ }
+ }
+
+ return snprintf(buf, size, "acpi(0x%08x,0x%x)", acpi->HID,
+ acpi->UID);
+ }
+ case MEDIA_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case MEDIA_CDROM_DP: {
+ CDROM_DEVICE_PATH *cdrom;
+
+ cdrom = (CDROM_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "cdrom(%x)",
+ cdrom->BootEntry);
+ }
+ case MEDIA_HARDDRIVE_DP: {
+ HARDDRIVE_DEVICE_PATH *hd;
+
+ hd = (HARDDRIVE_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "hd(%x)",
+ hd->PartitionNumber);
+ }
+ default:
+ return snprintf(buf, size, "media(0x%02x)",
+ devpath->SubType);
+ }
+ case BBS_DEVICE_PATH:
+ return snprintf(buf, size, "bbs(0x%02x)", devpath->SubType);
+ case END_DEVICE_PATH_TYPE:
+ return (0);
+ }
+
+ return snprintf(buf, size, "type(0x%02x, 0x%02x)", devpath->Type,
+ devpath->SubType);
+}
+
+/*
+ * devpath_strlcat appends a text description of devpath to buf but not more
+ * than size - 1 characters followed by NUL-terminator.
+ */
+int
+devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
+{
+ size_t len, used;
+ const char *sep;
+
+ sep = "";
+ used = 0;
+ while (!IsDevicePathEnd(devpath)) {
+ len = snprintf(buf, size - used, "%s", sep);
+ used += len;
+ if (used > size)
+ return (used);
+ buf += len;
+
+ len = devpath_node_str(buf, size - used, devpath);
+ used += len;
+ if (used > size)
+ return (used);
+ buf += len;
+ devpath = NextDevicePathNode(devpath);
+ sep = ":";
+ }
+
+ return (used);
+}
+
+/*
+ * devpath_str is convenience method which returns the text description of
+ * devpath using a static buffer, so it isn't thread safe!
+ */
+char *
+devpath_str(EFI_DEVICE_PATH *devpath)
+{
+ static char buf[256];
+
+ devpath_strlcat(buf, sizeof(buf), devpath);
+
+ return buf;
+}
+
+/*
+ * load_loader attempts to load the loader image data.
+ *
+ * It tries each module and its respective devices, identified by mod->probe,
+ * in order until a successful load occurs at which point it returns EFI_SUCCESS
+ * and EFI_NOT_FOUND otherwise.
+ *
+ * Only devices which have preferred matching the preferred parameter are tried.
+ */
+static EFI_STATUS
+load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
+ size_t *bufsize, BOOLEAN preferred)
+{
+ UINTN i;
+ dev_info_t *dev;
+ const boot_module_t *mod;
+
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] == NULL)
+ continue;
+ mod = boot_modules[i];
+ for (dev = mod->devices(); dev != NULL; dev = dev->next) {
+ if (dev->preferred != preferred)
+ continue;
+
+ if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
+ EFI_SUCCESS) {
+ *devinfop = dev;
+ *modp = mod;
+ return (EFI_SUCCESS);
+ }
+ }
+ }
+
+ return (EFI_NOT_FOUND);
+}
+
+/*
+ * try_boot only returns if it fails to load the loader. If it succeeds
+ * it simply boots, otherwise it returns the status of last EFI call.
+ */
+static EFI_STATUS
+try_boot(void)
+{
+ size_t bufsize, loadersize, cmdsize;
+ void *buf, *loaderbuf;
+ char *cmd;
+ dev_info_t *dev;
+ const boot_module_t *mod;
+ EFI_HANDLE loaderhandle;
+ EFI_LOADED_IMAGE *loaded_image;
+ EFI_STATUS status;
+
+ status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
+ if (status != EFI_SUCCESS) {
+ status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
+ FALSE);
+ if (status != EFI_SUCCESS) {
+ printf("Failed to load '%s'\n", PATH_LOADER_EFI);
+ return (status);
+ }
+ }
+
+ /*
+ * Read in and parse the command line from /boot.config or /boot/config,
+ * if present. We'll pass it the next stage via a simple ASCII
+ * string. loader.efi has a hack for ASCII strings, so we'll use that to
+ * keep the size down here. We only try to read the alternate file if
+ * we get EFI_NOT_FOUND because all other errors mean that the boot_module
+ * had troubles with the filesystem. We could return early, but we'll let
+ * loading the actual kernel sort all that out. Since these files are
+ * optional, we don't report errors in trying to read them.
+ */
+ cmd = NULL;
+ cmdsize = 0;
+ status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
+ if (status == EFI_NOT_FOUND)
+ status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
+ if (status == EFI_SUCCESS) {
+ cmdsize = bufsize + 1;
+ cmd = malloc(cmdsize);
+ if (cmd == NULL)
+ goto errout;
+ memcpy(cmd, buf, bufsize);
+ cmd[bufsize] = '\0';
+ free(buf);
+ buf = NULL;
+ }
+
+ if ((status = bs->LoadImage(TRUE, image, devpath_last(dev->devpath),
+ loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
+ printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
+ mod->name, bufsize, EFI_ERROR_CODE(status));
+ goto errout;
+ }
+
+ if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
+ (VOID**)&loaded_image)) != EFI_SUCCESS) {
+ printf("Failed to query LoadedImage provided by %s (%lu)\n",
+ mod->name, EFI_ERROR_CODE(status));
+ goto errout;
+ }
+
+ if (cmd != NULL)
+ printf(" command args: %s\n", cmd);
+
+ loaded_image->DeviceHandle = dev->devhandle;
+ loaded_image->LoadOptionsSize = cmdsize;
+ loaded_image->LoadOptions = cmd;
+
+ DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".\n");
+
+ if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
+ EFI_SUCCESS) {
+ printf("Failed to start image provided by %s (%lu)\n",
+ mod->name, EFI_ERROR_CODE(status));
+ loaded_image->LoadOptionsSize = 0;
+ loaded_image->LoadOptions = NULL;
+ }
+
+errout:
+ if (cmd != NULL)
+ free(cmd);
+ if (buf != NULL)
+ free(buf);
+ if (loaderbuf != NULL)
+ free(loaderbuf);
+
+ return (status);
+}
+
+/*
+ * probe_handle determines if the passed handle represents a logical partition
+ * if it does it uses each module in order to probe it and if successful it
+ * returns EFI_SUCCESS.
+ */
+static EFI_STATUS
+probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
+{
+ dev_info_t *devinfo;
+ EFI_BLOCK_IO *blkio;
+ EFI_DEVICE_PATH *devpath;
+ EFI_STATUS status;
+ UINTN i;
+
+ /* Figure out if we're dealing with an actual partition. */
+ status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
+ if (status == EFI_UNSUPPORTED)
+ return (status);
+
+ if (status != EFI_SUCCESS) {
+ DPRINTF("\nFailed to query DevicePath (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ DPRINTF("probing: %s\n", devpath_str(devpath));
+
+ status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
+ if (status == EFI_UNSUPPORTED)
+ return (status);
+
+ if (status != EFI_SUCCESS) {
+ DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ if (!blkio->Media->LogicalPartition)
+ return (EFI_UNSUPPORTED);
+
+ *preferred = device_paths_match(imgpath, devpath);
+
+ /* Run through each module, see if it can load this partition */
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] == NULL)
+ continue;
+
+ if ((status = bs->AllocatePool(EfiLoaderData,
+ sizeof(*devinfo), (void **)&devinfo)) !=
+ EFI_SUCCESS) {
+ DPRINTF("\nFailed to allocate devinfo (%lu)\n",
+ EFI_ERROR_CODE(status));
+ continue;
+ }
+ devinfo->dev = blkio;
+ devinfo->devpath = devpath;
+ devinfo->devhandle = h;
+ devinfo->devdata = NULL;
+ devinfo->preferred = *preferred;
+ devinfo->next = NULL;
+
+ status = boot_modules[i]->probe(devinfo);
+ if (status == EFI_SUCCESS)
+ return (EFI_SUCCESS);
+ (void)bs->FreePool(devinfo);
+ }
+
+ return (EFI_UNSUPPORTED);
+}
+
+/*
+ * probe_handle_status calls probe_handle and outputs the returned status
+ * of the call.
+ */
+static void
+probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
+{
+ EFI_STATUS status;
+ BOOLEAN preferred = false;
+
+ status = probe_handle(h, imgpath, &preferred);
+
+ DPRINTF("probe: ");
+ switch (status) {
+ case EFI_UNSUPPORTED:
+ printf(".");
+ DPRINTF(" not supported\n");
+ break;
+ case EFI_SUCCESS:
+ if (preferred) {
+ printf("%c", '*');
+ DPRINTF(" supported (preferred)\n");
+ } else {
+ printf("%c", '+');
+ DPRINTF(" supported\n");
+ }
+ break;
+ default:
+ printf("x");
+ DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
+ break;
+ }
+ DSTALL(500000);
+}
+
+EFI_STATUS
+efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
+{
+ EFI_HANDLE *handles;
+ EFI_LOADED_IMAGE *img;
+ EFI_DEVICE_PATH *imgpath;
+ EFI_STATUS status;
+ EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
+ UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
+
+ /* Basic initialization*/
+ systab = Xsystab;
+ image = Ximage;
+ bs = Xsystab->BootServices;
+
+ /* Set up the console, so printf works. */
+ status = bs->LocateProtocol(&ConsoleControlGUID, NULL,
+ (VOID **)&ConsoleControl);
+ if (status == EFI_SUCCESS)
+ (void)ConsoleControl->SetMode(ConsoleControl,
+ EfiConsoleControlScreenText);
+ /*
+ * Reset the console and find the best text mode.
+ */
+ conout = systab->ConOut;
+ conout->Reset(conout, TRUE);
+ max_dim = best_mode = 0;
+ for (i = 0; ; i++) {
+ status = conout->QueryMode(conout, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ break;
+ if (cols * rows > max_dim) {
+ max_dim = cols * rows;
+ best_mode = i;
+ }
+ }
+ if (max_dim > 0)
+ conout->SetMode(conout, best_mode);
+ conout->EnableCursor(conout, TRUE);
+ conout->ClearScreen(conout);
+
+ printf("\n>> illumos EFI boot block\n");
+ printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
+ printf(" Initializing modules:");
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] == NULL)
+ continue;
+
+ printf(" %s", boot_modules[i]->name);
+ if (boot_modules[i]->init != NULL)
+ boot_modules[i]->init();
+ }
+ putchar('\n');
+
+ /* Get all the device handles */
+ hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
+ if ((status = bs->AllocatePool(EfiLoaderData, hsize, (void **)&handles))
+ != EFI_SUCCESS)
+ panic("Failed to allocate %d handles (%lu)", NUM_HANDLES_INIT,
+ EFI_ERROR_CODE(status));
+
+ status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
+ &hsize, handles);
+ switch (status) {
+ case EFI_SUCCESS:
+ break;
+ case EFI_BUFFER_TOO_SMALL:
+ (void)bs->FreePool(handles);
+ if ((status = bs->AllocatePool(EfiLoaderData, hsize,
+ (void **)&handles) != EFI_SUCCESS)) {
+ panic("Failed to allocate %zu handles (%lu)", hsize /
+ sizeof(*handles), EFI_ERROR_CODE(status));
+ }
+ status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
+ NULL, &hsize, handles);
+ if (status != EFI_SUCCESS)
+ panic("Failed to get device handles (%lu)\n",
+ EFI_ERROR_CODE(status));
+ break;
+ default:
+ panic("Failed to get device handles (%lu)",
+ EFI_ERROR_CODE(status));
+ }
+
+ /* Scan all partitions, probing with all modules. */
+ nhandles = hsize / sizeof(*handles);
+ printf(" Probing %zu block devices...", nhandles);
+ DPRINTF("\n");
+
+ /* Determine the devpath of our image so we can prefer it. */
+ status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
+ imgpath = NULL;
+ if (status == EFI_SUCCESS) {
+ status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
+ (void **)&imgpath);
+ if (status != EFI_SUCCESS)
+ DPRINTF("Failed to get image DevicePath (%lu)\n",
+ EFI_ERROR_CODE(status));
+ DPRINTF("boot1 imagepath: %s\n", devpath_str(imgpath));
+ }
+
+ for (i = 0; i < nhandles; i++)
+ probe_handle_status(handles[i], imgpath);
+ printf(" done\n");
+
+ /* Status summary. */
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] != NULL) {
+ printf(" ");
+ boot_modules[i]->status();
+ }
+ }
+
+ try_boot();
+
+ /* If we get here, we're out of luck... */
+ panic("No bootable partitions found!");
+}
+
+/*
+ * add_device adds a device to the passed devinfo list.
+ */
+void
+add_device(dev_info_t **devinfop, dev_info_t *devinfo)
+{
+ dev_info_t *dev;
+
+ if (*devinfop == NULL) {
+ *devinfop = devinfo;
+ return;
+ }
+
+ for (dev = *devinfop; dev->next != NULL; dev = dev->next)
+ ;
+
+ dev->next = devinfo;
+}
+
+void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ printf("panic: ");
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+
+ while (1) {}
+}
+
+void
+putchar(int c)
+{
+ CHAR16 buf[2];
+
+ if (c == '\n') {
+ buf[0] = '\r';
+ buf[1] = 0;
+ systab->ConOut->OutputString(systab->ConOut, buf);
+ }
+ buf[0] = c;
+ buf[1] = 0;
+ systab->ConOut->OutputString(systab->ConOut, buf);
+}
+
+int
+getchar(void)
+{
+ EFI_INPUT_KEY key;
+ EFI_STATUS status;
+ UINTN junk;
+
+ status = systab->ConIn->ReadKeyStroke(systab->ConIn, &key);
+ if (status == EFI_NOT_READY) {
+ bs->WaitForEvent(1, &systab->ConIn->WaitForKey, &junk);
+ status = systab->ConIn->ReadKeyStroke(systab->ConIn, &key);
+ }
+ return (key.UnicodeChar);
+}
diff --git a/usr/src/boot/sys/boot/efi/boot1/boot_module.h b/usr/src/boot/sys/boot/efi/boot1/boot_module.h
new file mode 100644
index 0000000000..0f1fc089c8
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/boot1/boot_module.h
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 2015 Eric McCorkle
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOT_MODULE_H_
+#define _BOOT_MODULE_H_
+
+#include <stdbool.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <eficonsctl.h>
+
+#ifdef EFI_DEBUG
+#define DPRINTF(fmt, args...) printf(fmt, ##args)
+#define DSTALL(d) bs->Stall(d)
+#else
+#define DPRINTF(fmt, ...) {}
+#define DSTALL(d) {}
+#endif
+
+/* EFI device info */
+typedef struct dev_info
+{
+ EFI_BLOCK_IO *dev;
+ EFI_DEVICE_PATH *devpath;
+ EFI_HANDLE *devhandle;
+ void *devdata;
+ BOOLEAN preferred;
+ struct dev_info *next;
+} dev_info_t;
+
+/*
+ * A boot loader module.
+ *
+ * This is a standard interface for filesystem modules in the EFI system.
+ */
+typedef struct boot_module_t
+{
+ const char *name;
+
+ /* init is the optional initialiser for the module. */
+ void (*init)(void);
+
+ /*
+ * probe checks to see if the module can handle dev.
+ *
+ * Return codes:
+ * EFI_SUCCESS = The module can handle the device.
+ * EFI_NOT_FOUND = The module can not handle the device.
+ * Other = The module encountered an error.
+ */
+ EFI_STATUS (*probe)(dev_info_t* dev);
+
+ /*
+ * load should select the best out of a set of devices that probe
+ * indicated were loadable and load the specified file.
+ *
+ * Return codes:
+ * EFI_SUCCESS = The module can handle the device.
+ * EFI_NOT_FOUND = The module can not handle the device.
+ * Other = The module encountered an error.
+ */
+ EFI_STATUS (*load)(const char *filepath, dev_info_t *devinfo,
+ void **buf, size_t *bufsize);
+
+ /* status outputs information about the probed devices. */
+ void (*status)(void);
+
+ /* valid devices as found by probe. */
+ dev_info_t *(*devices)(void);
+} boot_module_t;
+
+/* Standard boot modules. */
+#ifdef EFI_UFS_BOOT
+extern const boot_module_t ufs_module;
+#endif
+#ifdef EFI_ZFS_BOOT
+extern const boot_module_t zfs_module;
+#endif
+
+/* Functions available to modules. */
+extern void add_device(dev_info_t **devinfop, dev_info_t *devinfo);
+
+extern EFI_SYSTEM_TABLE *systab;
+extern EFI_BOOT_SERVICES *bs;
+
+extern int devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath);
+extern char *devpath_str(EFI_DEVICE_PATH *devpath);
+#endif
diff --git a/usr/src/boot/sys/boot/efi/boot1/ufs_module.c b/usr/src/boot/sys/boot/efi/boot1/ufs_module.c
new file mode 100644
index 0000000000..63087ea22f
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/boot1/ufs_module.c
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ * Copyright (c) 2014 Nathan Whitehorn
+ * All rights reserved.
+ * Copyright (c) 2015 Eric McCorkle
+ * All rights reverved.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <efi.h>
+
+#include "boot_module.h"
+
+static dev_info_t *devinfo;
+static dev_info_t *devices;
+
+static int
+dskread(void *buf, u_int64_t lba, int nblk)
+{
+ int size;
+ EFI_STATUS status;
+
+ lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE);
+ size = nblk * DEV_BSIZE;
+
+ status = devinfo->dev->ReadBlocks(devinfo->dev,
+ devinfo->dev->Media->MediaId, lba, size, buf);
+
+ if (status != EFI_SUCCESS) {
+ DPRINTF("dskread: failed dev: %p, id: %u, lba: %lu, size: %d, "
+ "status: %lu\n", devinfo->dev,
+ devinfo->dev->Media->MediaId, lba, size,
+ EFI_ERROR_CODE(status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+#include "ufsread.c"
+
+static struct dmadat __dmadat;
+
+static int
+init_dev(dev_info_t* dev)
+{
+
+ devinfo = dev;
+ dmadat = &__dmadat;
+
+ return fsread(0, NULL, 0);
+}
+
+static EFI_STATUS
+probe(dev_info_t* dev)
+{
+
+ if (init_dev(dev) < 0)
+ return (EFI_UNSUPPORTED);
+
+ add_device(&devices, dev);
+
+ return (EFI_SUCCESS);
+}
+
+static EFI_STATUS
+load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize)
+{
+ ufs_ino_t ino;
+ EFI_STATUS status;
+ size_t size;
+ ssize_t read;
+ void *buf;
+
+ DPRINTF("Loading '%s' from %s\n", filepath, devpath_str(dev->devpath));
+
+ if (init_dev(dev) < 0) {
+ DPRINTF("Failed to init device\n");
+ return (EFI_UNSUPPORTED);
+ }
+
+ if ((ino = lookup(filepath)) == 0) {
+ DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath);
+ return (EFI_NOT_FOUND);
+ }
+
+ if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
+ printf("Failed to read size of '%s' ino: %d\n", filepath, ino);
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if ((status = bs->AllocatePool(EfiLoaderData, size, &buf)) !=
+ EFI_SUCCESS) {
+ printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
+ size, filepath, EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ read = fsread(ino, buf, size);
+ if ((size_t)read != size) {
+ printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
+ size);
+ (void)bs->FreePool(buf);
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ DPRINTF("Load complete\n");
+
+ *bufp = buf;
+ *bufsize = size;
+
+ return (EFI_SUCCESS);
+}
+
+static void
+status()
+{
+ int i;
+ dev_info_t *dev;
+
+ for (dev = devices, i = 0; dev != NULL; dev = dev->next, i++)
+ ;
+
+ printf("%s found ", ufs_module.name);
+ switch (i) {
+ case 0:
+ printf("no partitions\n");
+ break;
+ case 1:
+ printf("%d partition\n", i);
+ break;
+ default:
+ printf("%d partitions\n", i);
+ }
+}
+
+static dev_info_t *
+_devices()
+{
+
+ return (devices);
+}
+
+const boot_module_t ufs_module =
+{
+ .name = "UFS",
+ .probe = probe,
+ .load = load,
+ .status = status,
+ .devices = _devices
+};
diff --git a/usr/src/boot/sys/boot/efi/boot1/zfs_module.c b/usr/src/boot/sys/boot/efi/boot1/zfs_module.c
new file mode 100644
index 0000000000..925f0b28c1
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/boot1/zfs_module.c
@@ -0,0 +1,196 @@
+/*-
+ * Copyright (c) 2015 Eric McCorkle
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <efi.h>
+
+#include "boot_module.h"
+
+#include "libzfs.h"
+#include "zfsimpl.c"
+
+static dev_info_t *devices;
+
+static int
+vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
+{
+ dev_info_t *devinfo;
+ off_t lba;
+ EFI_STATUS status;
+
+ devinfo = (dev_info_t *)priv;
+ lba = off / devinfo->dev->Media->BlockSize;
+
+ status = devinfo->dev->ReadBlocks(devinfo->dev,
+ devinfo->dev->Media->MediaId, lba, bytes, buf);
+ if (status != EFI_SUCCESS) {
+ DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %zu, size: %zu,"
+ " status: %lu\n", devinfo->dev,
+ devinfo->dev->Media->MediaId, lba, bytes,
+ EFI_ERROR_CODE(status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static EFI_STATUS
+probe(dev_info_t *dev)
+{
+ spa_t *spa;
+ dev_info_t *tdev;
+ EFI_STATUS status;
+
+ /* ZFS consumes the dev on success so we need a copy. */
+ if ((status = bs->AllocatePool(EfiLoaderData, sizeof(*dev),
+ (void**)&tdev)) != EFI_SUCCESS) {
+ DPRINTF("Failed to allocate tdev (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+ memcpy(tdev, dev, sizeof(*dev));
+
+ if (vdev_probe(vdev_read, tdev, &spa) != 0) {
+ (void)bs->FreePool(tdev);
+ return (EFI_UNSUPPORTED);
+ }
+
+ dev->devdata = spa;
+ add_device(&devices, dev);
+
+ return (EFI_SUCCESS);
+}
+
+static EFI_STATUS
+load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize)
+{
+ spa_t *spa;
+ struct zfsmount zfsmount;
+ dnode_phys_t dn;
+ struct stat st;
+ int err;
+ void *buf;
+ EFI_STATUS status;
+
+ spa = devinfo->devdata;
+
+ DPRINTF("load: '%s' spa: '%s', devpath: %s\n", filepath, spa->spa_name,
+ devpath_str(devinfo->devpath));
+
+ if ((err = zfs_spa_init(spa)) != 0) {
+ DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
+ return (EFI_NOT_FOUND);
+ }
+
+ if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
+ DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
+ return (EFI_NOT_FOUND);
+ }
+
+ if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
+ if (err == ENOENT) {
+ DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
+ filepath, spa->spa_name, err);
+ return (EFI_NOT_FOUND);
+ }
+ printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
+ spa->spa_name, err);
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
+ printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
+ spa->spa_name, err);
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
+ != EFI_SUCCESS) {
+ printf("Failed to allocate load buffer %zd for pool '%s' for '%s' "
+ "(%lu)\n", st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if ((err = dnode_read(spa, &dn, 0, buf, st.st_size)) != 0) {
+ printf("Failed to read node from %s (%d)\n", spa->spa_name,
+ err);
+ (void)bs->FreePool(buf);
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ *bufsize = st.st_size;
+ *bufp = buf;
+
+ return (EFI_SUCCESS);
+}
+
+static void
+status()
+{
+ spa_t *spa;
+
+ spa = STAILQ_FIRST(&zfs_pools);
+ if (spa == NULL) {
+ printf("%s found no pools\n", zfs_module.name);
+ return;
+ }
+
+ printf("%s found the following pools:", zfs_module.name);
+ STAILQ_FOREACH(spa, &zfs_pools, spa_link)
+ printf(" %s", spa->spa_name);
+
+ printf("\n");
+}
+
+static void
+init()
+{
+
+ zfs_init();
+}
+
+static dev_info_t *
+_devices()
+{
+
+ return (devices);
+}
+
+const boot_module_t zfs_module =
+{
+ .name = "ZFS",
+ .init = init,
+ .probe = probe,
+ .load = load,
+ .status = status,
+ .devices = _devices
+};
diff --git a/usr/src/boot/sys/boot/efi/fdt/Makefile b/usr/src/boot/sys/boot/efi/fdt/Makefile
new file mode 100644
index 0000000000..15862dc295
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/fdt/Makefile
@@ -0,0 +1,37 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+.PATH: ${.CURDIR}/../../common
+
+LIB= efi_fdt
+INTERNALLIB=
+WARNS?= 6
+
+SRCS= efi_fdt.c
+
+CFLAGS+= -ffreestanding -msoft-float
+.if ${MACHINE_CPUARCH} == "aarch64"
+CFLAGS+= -mgeneral-regs-only
+.endif
+
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+# EFI library headers
+CFLAGS+= -I${.CURDIR}/../include
+CFLAGS+= -I${.CURDIR}/../include/${MACHINE}
+
+# libfdt headers
+CFLAGS+= -I${.CURDIR}/../../fdt
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+
+machine:
+ ln -sf ${.CURDIR}/../../../${MACHINE}/include machine
+
+CLEANFILES+= machine
+
+.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/usr/src/boot/sys/boot/efi/fdt/efi_fdt.c b/usr/src/boot/sys/boot/efi/fdt/efi_fdt.c
new file mode 100644
index 0000000000..d6757689c8
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/fdt/efi_fdt.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <stand.h>
+#include <efi.h>
+#include <efilib.h>
+#include <fdt_platform.h>
+
+#include "bootstrap.h"
+
+static EFI_GUID fdtdtb = FDT_TABLE_GUID;
+
+int
+fdt_platform_load_dtb(void)
+{
+ struct fdt_header *hdr;
+
+ hdr = efi_get_table(&fdtdtb);
+ if (hdr != NULL) {
+ if (fdt_load_dtb_addr(hdr) == 0) {
+ printf("Using DTB provided by EFI at %p.\n", hdr);
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+void
+fdt_platform_fixups(void)
+{
+}
diff --git a/usr/src/boot/sys/boot/efi/include/README b/usr/src/boot/sys/boot/efi/include/README
new file mode 100644
index 0000000000..bf821fae7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/README
@@ -0,0 +1,36 @@
+/* $FreeBSD$ */
+/*-
+
+Files in this directory and subdirectories are subject to the following
+copyright unless superceded or supplemented by additional specific license
+terms found in the file headers of individual files.
+
+Copyright (c) 1998-2000 Intel Corporation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL INTEL BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, 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 DAMAGE. THE EFI SPECIFICATION AND ALL
+OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO
+WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE.
+
+*/
diff --git a/usr/src/boot/sys/boot/efi/include/amd64/efibind.h b/usr/src/boot/sys/boot/efi/include/amd64/efibind.h
new file mode 100644
index 0000000000..e871085d39
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/amd64/efibind.h
@@ -0,0 +1,268 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efefind.h
+
+Abstract:
+
+ EFI to compile bindings
+
+
+
+
+Revision History
+
+--*/
+
+#pragma pack()
+
+#include <sys/stdint.h>
+
+#if 0
+//
+// Basic int types of various widths
+//
+
+#if (__STDC_VERSION__ < 199901L )
+
+ // No ANSI C 1999/2000 stdint.h integer width declarations
+
+ #ifdef _MSC_EXTENSIONS
+
+ // Use Microsoft C compiler integer width declarations
+
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int32 int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+ #ifdef UNIX_LP64
+
+ // Use LP64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+
+ // Assume P64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #endif
+ #endif
+#endif
+#endif
+
+//
+// Basic EFI types of various widths
+//
+
+#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */
+#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+
+#ifndef _BASETSD_H_
+ typedef uint32_t UINT32;
+ typedef int32_t INT32;
+#endif
+
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+#endif
+
+#undef VOID
+#define VOID void
+
+
+typedef int64_t INTN;
+typedef uint64_t UINTN;
+
+#ifdef EFI_NT_EMULATOR
+ #define POST_CODE(_Data)
+#else
+ #ifdef EFI_DEBUG
+#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al
+ #else
+ #define POST_CODE(_Data)
+ #endif
+#endif
+
+#define EFIERR(a) (0x8000000000000000 | a)
+#define EFI_ERROR_MASK 0x8000000000000000
+#define EFIERR_OEM(a) (0xc000000000000000 | a)
+
+
+#define BAD_POINTER 0xFBFBFBFBFBFBFBFB
+#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+#define BREAKPOINT() __asm { int 3 }
+
+//
+// Pointers must be aligned to these address to function
+//
+
+#define MIN_ALIGNMENT_SIZE 4
+
+#define ALIGN_VARIABLE(Value ,Adjustment) \
+ (UINTN)Adjustment = 0; \
+ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
+ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
+ Value = (UINTN)Value + (UINTN)Adjustment
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+//
+// EFIAPI - prototype calling convention for EFI function pointers
+// BOOTSERVICE - prototype for implementation of a boot service interface
+// RUNTIMESERVICE - prototype for implementation of a runtime service interface
+// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
+// RUNTIME_CODE - pragma macro for declaring runtime code
+//
+
+#ifdef __amd64__
+#define EFIAPI __attribute__((ms_abi))
+#endif
+
+#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options
+ #ifdef _MSC_EXTENSIONS
+ #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler
+ #else
+ #define EFIAPI // Substitute expresion to force C calling convention
+ #endif
+#endif
+
+#define BOOTSERVICE
+//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a
+//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a
+#define RUNTIMESERVICE
+#define RUNTIMEFUNCTION
+
+
+#define RUNTIME_CODE(a) alloc_text("rtcode", a)
+#define BEGIN_RUNTIME_DATA() data_seg("rtdata")
+#define END_RUNTIME_DATA() data_seg("")
+
+#define VOLATILE volatile
+
+#define MEMORY_FENCE()
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+ #define EFI_INTERFACE_DECL(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+ #define EFI_INTERFACE_DECL(x) typedef struct x
+#endif
+
+#ifdef EFI_NT_EMULATOR
+
+//
+// To help ensure proper coding of integrated drivers, they are
+// compiled as DLLs. In NT they require a dll init entry pointer.
+// The macro puts a stub entry point into the DLL so it will load.
+//
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction) \
+ EFI_STATUS \
+ InitFunction ( \
+ EFI_HANDLE ImageHandle, \
+ EFI_SYSTEM_TABLE *SystemTable \
+ ); \
+ \
+ UINTN \
+ __stdcall \
+ _DllMainCRTStartup ( \
+ UINTN Inst, \
+ UINTN reason_for_call, \
+ VOID *rserved \
+ ) \
+ { \
+ return 1; \
+ } \
+ \
+ int \
+ __declspec( dllexport ) \
+ __cdecl \
+ InitializeDriver ( \
+ void *ImageHandle, \
+ void *SystemTable \
+ ) \
+ { \
+ return InitFunction(ImageHandle, SystemTable); \
+ }
+
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, NULL)
+
+#else // EFI_NT_EMULATOR
+
+//
+// When build similiar to FW, then link everything together as
+// one big module.
+//
+
+ #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, entry)
+
+#endif // EFI_FW_NT
+
+#define INTERFACE_DECL(x) struct x
+#if 0
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX
+//
+// The following macro provide a workaround for such cases.
+//
+#ifdef NO_INTERFACE_DECL
+#define INTERFACE_DECL(x)
+#else
+#define INTERFACE_DECL(x) typedef struct x
+#endif
+#endif /* __FreeBSD__ */
+
+#ifdef _MSC_EXTENSIONS
+#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/amd64/pe.h b/usr/src/boot/sys/boot/efi/include/amd64/pe.h
new file mode 100644
index 0000000000..f8033c55ac
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/amd64/pe.h
@@ -0,0 +1,591 @@
+/* $FreeBSD$ */
+/*
+ PE32+ header file
+ */
+#ifndef _PE_H
+#define _PE_H
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define IMAGE_OS2_SIGNATURE 0x454E // NE
+#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+
+
+typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
+ UINT16 ne_magic; // Magic number
+ UINT8 ne_ver; // Version number
+ UINT8 ne_rev; // Revision number
+ UINT16 ne_enttab; // Offset of Entry Table
+ UINT16 ne_cbenttab; // Number of bytes in Entry Table
+ UINT32 ne_crc; // Checksum of whole file
+ UINT16 ne_flags; // Flag UINT16
+ UINT16 ne_autodata; // Automatic data segment number
+ UINT16 ne_heap; // Initial heap allocation
+ UINT16 ne_stack; // Initial stack allocation
+ UINT32 ne_csip; // Initial CS:IP setting
+ UINT32 ne_sssp; // Initial SS:SP setting
+ UINT16 ne_cseg; // Count of file segments
+ UINT16 ne_cmod; // Entries in Module Reference Table
+ UINT16 ne_cbnrestab; // Size of non-resident name table
+ UINT16 ne_segtab; // Offset of Segment Table
+ UINT16 ne_rsrctab; // Offset of Resource Table
+ UINT16 ne_restab; // Offset of resident name table
+ UINT16 ne_modtab; // Offset of Module Reference Table
+ UINT16 ne_imptab; // Offset of Imported Names Table
+ UINT32 ne_nrestab; // Offset of Non-resident Names Table
+ UINT16 ne_cmovent; // Count of movable entries
+ UINT16 ne_align; // Segment alignment shift count
+ UINT16 ne_cres; // Count of resource segments
+ UINT8 ne_exetyp; // Target Operating system
+ UINT8 ne_flagsothers; // Other .EXE flags
+ UINT16 ne_pretthunks; // offset to return thunks
+ UINT16 ne_psegrefbytes; // offset to segment ref. bytes
+ UINT16 ne_swaparea; // Minimum code swap area size
+ UINT16 ne_expver; // Expected Windows version number
+ } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
+
+//
+// File header format.
+//
+
+typedef struct _IMAGE_FILE_HEADER {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
+#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
+#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
+#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
+#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// Directory format.
+//
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+//
+// Optional header format.
+//
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ //
+ // Standard fields.
+ //
+
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+
+ //
+ // NT additional fields.
+ //
+
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Reserved1;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
+
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
+
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+
+typedef struct _IMAGE_NT_HEADERS {
+ UINT32 Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+typedef struct _IMAGE_ROM_HEADERS {
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
+
+#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
+ ((UINT32)ntheader + \
+ FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
+ ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
+ ))
+
+
+// Subsystem Values
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
+#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
+#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
+
+
+// Directory Entries
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
+#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
+
+//
+// Section header format.
+//
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ UINT8 Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
+
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
+#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
+#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
+#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
+
+//
+// Symbol format.
+//
+
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+
+#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common.
+#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value.
+#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item.
+
+//
+// Type (fundamental) values.
+//
+
+#define IMAGE_SYM_TYPE_NULL 0 // no type.
+#define IMAGE_SYM_TYPE_VOID 1 //
+#define IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define IMAGE_SYM_TYPE_INT 4 //
+#define IMAGE_SYM_TYPE_LONG 5 //
+#define IMAGE_SYM_TYPE_FLOAT 6 //
+#define IMAGE_SYM_TYPE_DOUBLE 7 //
+#define IMAGE_SYM_TYPE_STRUCT 8 //
+#define IMAGE_SYM_TYPE_UNION 9 //
+#define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define IMAGE_SYM_TYPE_BYTE 12 //
+#define IMAGE_SYM_TYPE_WORD 13 //
+#define IMAGE_SYM_TYPE_UINT 14 //
+#define IMAGE_SYM_TYPE_DWORD 15 //
+
+//
+// Type (derived) values.
+//
+
+#define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
+#define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
+#define IMAGE_SYM_DTYPE_ARRAY 3 // array.
+
+//
+// Storage classes.
+//
+
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
+#define IMAGE_SYM_CLASS_NULL 0
+#define IMAGE_SYM_CLASS_AUTOMATIC 1
+#define IMAGE_SYM_CLASS_EXTERNAL 2
+#define IMAGE_SYM_CLASS_STATIC 3
+#define IMAGE_SYM_CLASS_REGISTER 4
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define IMAGE_SYM_CLASS_LABEL 6
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define IMAGE_SYM_CLASS_ARGUMENT 9
+#define IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define IMAGE_SYM_CLASS_UNION_TAG 12
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define IMAGE_SYM_CLASS_ENUM_TAG 15
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define IMAGE_SYM_CLASS_BIT_FIELD 18
+#define IMAGE_SYM_CLASS_BLOCK 100
+#define IMAGE_SYM_CLASS_FUNCTION 101
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define IMAGE_SYM_CLASS_FILE 103
+// new
+#define IMAGE_SYM_CLASS_SECTION 104
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+// type packing constants
+
+#define N_BTMASK 017
+#define N_TMASK 060
+#define N_TMASK1 0300
+#define N_TMASK2 0360
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+// MACROS
+
+//
+// Communal selection types.
+//
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+
+//
+// Relocation format.
+//
+
+typedef struct _IMAGE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} IMAGE_RELOCATION;
+
+#define IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+
+#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define IMAGE_REL_I386_SECTION 012
+#define IMAGE_REL_I386_SECREL 013
+#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
+
+//
+// MIPS relocation types.
+//
+
+#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_MIPS_REFHALF 01
+#define IMAGE_REL_MIPS_REFWORD 02
+#define IMAGE_REL_MIPS_JMPADDR 03
+#define IMAGE_REL_MIPS_REFHI 04
+#define IMAGE_REL_MIPS_REFLO 05
+#define IMAGE_REL_MIPS_GPREL 06
+#define IMAGE_REL_MIPS_LITERAL 07
+#define IMAGE_REL_MIPS_SECTION 012
+#define IMAGE_REL_MIPS_SECREL 013
+#define IMAGE_REL_MIPS_REFWORDNB 042
+#define IMAGE_REL_MIPS_PAIR 045
+
+//
+// Alpha Relocation types.
+//
+
+#define IMAGE_REL_ALPHA_ABSOLUTE 0x0
+#define IMAGE_REL_ALPHA_REFLONG 0x1
+#define IMAGE_REL_ALPHA_REFQUAD 0x2
+#define IMAGE_REL_ALPHA_GPREL32 0x3
+#define IMAGE_REL_ALPHA_LITERAL 0x4
+#define IMAGE_REL_ALPHA_LITUSE 0x5
+#define IMAGE_REL_ALPHA_GPDISP 0x6
+#define IMAGE_REL_ALPHA_BRADDR 0x7
+#define IMAGE_REL_ALPHA_HINT 0x8
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
+#define IMAGE_REL_ALPHA_REFHI 0xA
+#define IMAGE_REL_ALPHA_REFLO 0xB
+#define IMAGE_REL_ALPHA_PAIR 0xC
+#define IMAGE_REL_ALPHA_MATCH 0xD
+#define IMAGE_REL_ALPHA_SECTION 0xE
+#define IMAGE_REL_ALPHA_SECREL 0xF
+#define IMAGE_REL_ALPHA_REFLONGNB 0x10
+
+//
+// IBM PowerPC relocation types.
+//
+
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
+#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
+#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
+#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
+#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
+#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
+#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
+#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
+#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
+#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
+
+#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
+#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
+#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
+#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
+#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
+
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
+
+// Flag bits in IMAGE_RELOCATION.TYPE
+
+#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
+#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
+#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
+
+//
+// Based relocation format.
+//
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+// UINT16 TypeOffset[1];
+} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_DIR64 10
+
+//
+// Line number format.
+//
+
+typedef struct _IMAGE_LINENUMBER {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} IMAGE_LINENUMBER;
+
+#define IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+
+//
+// Export Format
+//
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 *AddressOfFunctions;
+ UINT32 *AddressOfNames;
+ UINT32 *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+//
+// Import Format
+//
+
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ UINT16 Hint;
+ UINT8 Name[1];
+} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
+
+typedef struct _IMAGE_THUNK_DATA {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ PIMAGE_IMPORT_BY_NAME AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
+
+#define IMAGE_ORDINAL_FLAG 0x80000000
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
+#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ PIMAGE_THUNK_DATA FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/arm/efibind.h b/usr/src/boot/sys/boot/efi/include/arm/efibind.h
new file mode 100644
index 0000000000..85537ad376
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/arm/efibind.h
@@ -0,0 +1,165 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiBind.h
+
+Abstract:
+
+ Processor or Compiler specific defines and types for IA-32.
+ We are using the ANSI C 2000 _t type definitions for basic types.
+ This it technically a violation of the coding standard, but they
+ are used to make EfiTypes.h portable. Code other than EfiTypes.h
+ should never use any ANSI C 2000 _t integer types.
+
+--*/
+
+#ifndef _EFI_BIND_H_
+#define _EFI_BIND_H_
+
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction)
+#define EFI_APPLICATION_ENTRY_POINT EFI_DRIVER_ENTRY_POINT
+
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#else
+//
+// Assume standard IA-32 alignment.
+// BugBug: Need to check portability of long long
+//
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+typedef unsigned int uint32_t;
+typedef int int32_t;
+typedef unsigned short uint16_t;
+typedef short int16_t;
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+#endif
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+#undef VOID
+#define VOID void
+
+//
+// Native integer size in stdint.h
+//
+typedef uint32_t UINTN;
+typedef int32_t INTN;
+
+#define EFIERR(a) (0x80000000 | a)
+#define EFI_ERROR_MASK 0x80000000
+#define EFIERR_OEM(a) (0xc0000000 | a)
+
+//
+// Processor specific defines
+//
+#define EFI_MAX_BIT 0x80000000
+#define MAX_2_BITS 0xC0000000
+
+//
+// Maximum legal IA-32 address
+//
+#define EFI_MAX_ADDRESS 0xFFFFFFFF
+
+//
+// Bad pointer value to use in check builds.
+// if you see this value you are using uninitialized or free'ed data
+//
+#define EFI_BAD_POINTER 0xAFAFAFAF
+#define EFI_BAD_POINTER_AS_BYTE 0xAF
+
+#define EFI_DEADLOOP() { volatile UINTN __iii; __iii = 1; while (__iii); }
+
+//
+// Inject a break point in the code to assist debugging for NT Emulation Environment
+// For real hardware, just put in a halt loop. Don't do a while(1) because the
+// compiler will optimize away the rest of the function following, so that you run out in
+// the weeds if you skip over it with a debugger.
+//
+#define EFI_BREAKPOINT EFI_DEADLOOP()
+
+
+//
+// Memory Fence forces serialization, and is needed to support out of order
+// memory transactions. The Memory Fence is mainly used to make sure IO
+// transactions complete in a deterministic sequence, and to syncronize locks
+// an other MP code. Currently no memory fencing is required.
+//
+#define MEMORY_FENCE()
+
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX. The forward reference is required for
+// ANSI compatibility.
+//
+// The following macro provide a workaround for such cases.
+//
+
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+#endif
+
+
+//
+// Some C compilers optimize the calling conventions to increase performance.
+// EFIAPI is used to make all public APIs follow the standard C calling
+// convention.
+//
+#define EFIAPI
+
+
+
+//
+// For symbol name in GNU assembly code, an extra "_" is necessary
+//
+#if defined(__GNUC__)
+ ///
+ /// Private worker functions for ASM_PFX()
+ ///
+ #define _CONCATENATE(a, b) __CONCATENATE(a, b)
+ #define __CONCATENATE(a, b) a ## b
+
+ ///
+ /// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix
+ /// on symbols in assembly language.
+ ///
+ #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
+
+#endif
+
+#define INTERFACE_DECL(x) struct x
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/arm64/efibind.h b/usr/src/boot/sys/boot/efi/include/arm64/efibind.h
new file mode 100644
index 0000000000..142f16267c
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/arm64/efibind.h
@@ -0,0 +1,217 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efefind.h
+
+Abstract:
+
+ EFI to compile bindings
+
+
+
+
+Revision History
+
+--*/
+
+#pragma pack()
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#else
+//
+// Basic int types of various widths
+//
+
+#if (__STDC_VERSION__ < 199901L )
+
+ // No ANSI C 1999/2000 stdint.h integer width declarations
+
+ #ifdef _MSC_EXTENSIONS
+
+ // Use Microsoft C compiler integer width declarations
+
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int16 uint16_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int8 int8_t;
+ #else
+ #ifdef UNIX_LP64
+
+ // Use LP64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+
+ // Assume P64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #endif
+ #endif
+#endif
+#endif /* __FreeBSD__ */
+
+//
+// Basic EFI types of various widths
+//
+
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+
+#undef VOID
+#define VOID void
+
+
+typedef int64_t INTN;
+typedef uint64_t UINTN;
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// BugBug: Code to debug
+//
+#define BIT63 0x8000000000000000
+
+#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63)
+#define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) )
+
+//
+// Macro's with casts make this much easier to use and read.
+//
+#define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port)))
+#define POST_CODE(_Data) (PORT_TO_MEM8D(0x80) = (_Data))
+//
+// BugBug: End Debug Code!!!
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#define EFIERR(a) (0x8000000000000000 | a)
+#define EFI_ERROR_MASK 0x8000000000000000
+#define EFIERR_OEM(a) (0xc000000000000000 | a)
+
+#define BAD_POINTER 0xFBFBFBFBFBFBFBFB
+#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+#define BREAKPOINT() __break(0)
+
+//
+// Pointers must be aligned to these address to function
+// you will get an alignment fault if this value is less than 8
+//
+#define MIN_ALIGNMENT_SIZE 8
+
+#define ALIGN_VARIABLE(Value , Adjustment) \
+ (UINTN) Adjustment = 0; \
+ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
+ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
+ Value = (UINTN)Value + (UINTN)Adjustment
+
+//
+// Define macros to create data structure signatures.
+//
+
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+//
+// EFIAPI - prototype calling convention for EFI function pointers
+// BOOTSERVICE - prototype for implementation of a boot service interface
+// RUNTIMESERVICE - prototype for implementation of a runtime service interface
+// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
+// RUNTIME_CODE - pragma macro for declaring runtime code
+//
+
+#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options
+ #ifdef _MSC_EXTENSIONS
+ #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler
+ #else
+ #define EFIAPI // Substitute expresion to force C calling convention
+ #endif
+#endif
+
+#define BOOTSERVICE
+#define RUNTIMESERVICE
+#define RUNTIMEFUNCTION
+
+#define RUNTIME_CODE(a) alloc_text("rtcode", a)
+#define BEGIN_RUNTIME_DATA() data_seg("rtdata")
+#define END_RUNTIME_DATA() data_seg()
+
+#define VOLATILE volatile
+
+//
+// BugBug: Need to find out if this is portable accross compliers.
+//
+void __mfa (void);
+#define MEMORY_FENCE() __mfa()
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+ #define EFI_INTERFACE_DECL(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+ #define EFI_INTERFACE_DECL(x) typedef struct x
+#endif
+
+//
+// When build similiar to FW, then link everything together as
+// one big module.
+//
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction)
+
+#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, entry)
+// entry(NULL, ST)
+
+#ifdef __FreeBSD__
+#define INTERFACE_DECL(x) struct x
+#else
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX
+//
+// The following macro provide a workaround for such cases.
+//
+#ifdef NO_INTERFACE_DECL
+#define INTERFACE_DECL(x)
+#else
+#define INTERFACE_DECL(x) typedef struct x
+#endif
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efi.h b/usr/src/boot/sys/boot/efi/include/efi.h
new file mode 100644
index 0000000000..3f6cd01c97
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efi.h
@@ -0,0 +1,70 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efi.h
+
+Abstract:
+
+ Public EFI header files
+
+
+
+Revision History
+
+--*/
+
+//
+// Build flags on input
+// EFI32
+// EFI_DEBUG - Enable debugging code
+// EFI_NT_EMULATOR - Building for running under NT
+//
+
+
+#ifndef _EFI_INCLUDE_
+#define _EFI_INCLUDE_
+
+#define EFI_FIRMWARE_VENDOR L"INTEL"
+#define EFI_FIRMWARE_MAJOR_REVISION 14
+#define EFI_FIRMWARE_MINOR_REVISION 62
+#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION))
+
+#include "efibind.h"
+#include "efidef.h"
+#include "efidevp.h"
+#include "efipciio.h"
+#include "efiprot.h"
+#include "eficon.h"
+#include "eficonsctl.h"
+#include "efiser.h"
+#include "efi_nii.h"
+#include "efipxebc.h"
+#include "efinet.h"
+#include "efiapi.h"
+#include "efifs.h"
+#include "efierr.h"
+#include "efigop.h"
+#include "efiip.h"
+#include "efiudp.h"
+#include "efitcp.h"
+#include "efipoint.h"
+#include "efiuga.h"
+
+#define EFI_STRINGIZE(a) #a
+#define EFI_PROTOCOL_DEFINITION(a) EFI_STRINGIZE(Protocol/a/a.h)
+
+#define EFI_GUID_DEFINITION(a) EFI_STRINGIZE(Guid/a/a##.h)
+#define EFI_GUID_STRING(guidpointer, shortstring, longstring)
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efi_nii.h b/usr/src/boot/sys/boot/efi/include/efi_nii.h
new file mode 100644
index 0000000000..561cbd46a3
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efi_nii.h
@@ -0,0 +1,86 @@
+/* $FreeBSD$ */
+#ifndef _EFI_NII_H
+#define _EFI_NII_H
+
+/*++
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module name:
+ efi_nii.h
+
+Abstract:
+
+Revision history:
+ 2000-Feb-18 M(f)J GUID updated.
+ Structure order changed for machine word alignment.
+ Added StringId[4] to structure.
+
+ 2000-Feb-14 M(f)J Genesis.
+--*/
+
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL \
+ { 0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29} }
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_31 \
+ { 0x1ACED566, 0x76ED, 0x4218, {0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89} }
+
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION 0x00010000
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION_31 0x00010001
+
+typedef enum {
+ EfiNetworkInterfaceUndi = 1
+} EFI_NETWORK_INTERFACE_TYPE;
+
+typedef struct {
+
+ UINT64 Revision;
+ // Revision of the network interface identifier protocol interface.
+
+ UINT64 ID;
+ // Address of the first byte of the identifying structure for this
+ // network interface. This is set to zero if there is no structure.
+ //
+ // For PXE/UNDI this is the first byte of the !PXE structure.
+
+ UINT64 ImageAddr;
+ // Address of the UNrelocated driver/ROM image. This is set
+ // to zero if there is no driver/ROM image.
+ //
+ // For 16-bit UNDI, this is the first byte of the option ROM in
+ // upper memory.
+ //
+ // For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM
+ // image.
+ //
+ // For H/W UNDI, this is set to zero.
+
+ UINT32 ImageSize;
+ // Size of the UNrelocated driver/ROM image of this network interface.
+ // This is set to zero if there is no driver/ROM image.
+
+ CHAR8 StringId[4];
+ // 4 char ASCII string to go in class identifier (option 60) in DHCP
+ // and Boot Server discover packets.
+ // For EfiNetworkInterfaceUndi this field is "UNDI".
+ // For EfiNetworkInterfaceSnp this field is "SNPN".
+
+ UINT8 Type;
+ UINT8 MajorVer;
+ UINT8 MinorVer;
+ // Information to be placed into the PXE DHCP and Discover packets.
+ // This is the network interface type and version number that will
+ // be placed into DHCP option 94 (client network interface identifier).
+ BOOLEAN Ipv6Supported;
+ UINT8 IfNum; // interface number to be used with pxeid structure
+} EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE;
+
+extern EFI_GUID NetworkInterfaceIdentifierProtocol;
+extern EFI_GUID NetworkInterfaceIdentifierProtocol_31;
+
+#endif // _EFI_NII_H
diff --git a/usr/src/boot/sys/boot/efi/include/efiapi.h b/usr/src/boot/sys/boot/efi/include/efiapi.h
new file mode 100644
index 0000000000..ec11a2d363
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiapi.h
@@ -0,0 +1,1204 @@
+/* $FreeBSD$ */
+#ifndef _EFI_API_H
+#define _EFI_API_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efiapi.h
+
+Abstract:
+
+ Global EFI runtime & boot service interfaces
+
+
+
+
+Revision History
+
+--*/
+
+//
+// EFI Specification Revision
+//
+
+#define EFI_SPECIFICATION_MAJOR_REVISION 1
+#define EFI_SPECIFICATION_MINOR_REVISION 10
+
+//
+// Declare forward referenced data structures
+//
+
+INTERFACE_DECL(_EFI_SYSTEM_TABLE);
+
+//
+// EFI Memory
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_PAGES) (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NoPages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_PAGES) (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NoPages
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_MAP) (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ );
+
+#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size))
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_POOL) (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_POOL) (
+ IN VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) (
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion,
+ IN EFI_MEMORY_DESCRIPTOR *VirtualMap
+ );
+
+
+#define EFI_OPTIONAL_PTR 0x00000001
+#define EFI_INTERNAL_FNC 0x00000002 // Pointer to internal runtime fnc
+#define EFI_INTERNAL_PTR 0x00000004 // Pointer to internal runtime data
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONVERT_POINTER) (
+ IN UINTN DebugDisposition,
+ IN OUT VOID **Address
+ );
+
+
+//
+// EFI Events
+//
+
+
+
+#define EVT_TIMER 0x80000000
+#define EVT_RUNTIME 0x40000000
+#define EVT_RUNTIME_CONTEXT 0x20000000
+
+#define EVT_NOTIFY_WAIT 0x00000100
+#define EVT_NOTIFY_SIGNAL 0x00000200
+
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+#define EVT_EFI_SIGNAL_MASK 0x000000FF
+#define EVT_EFI_SIGNAL_MAX 2
+
+typedef
+VOID
+(EFIAPI *EFI_EVENT_NOTIFY) (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT) (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT EFI_EVENT *Event
+ );
+
+typedef enum {
+ TimerCancel,
+ TimerPeriodic,
+ TimerRelative,
+ TimerTypeMax
+} EFI_TIMER_DELAY;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER) (
+ IN EFI_EVENT Event,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIGNAL_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WAIT_FOR_EVENT) (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *Event,
+ OUT UINTN *Index
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CHECK_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+//
+// Task priority level
+//
+
+#define TPL_APPLICATION 4
+#define TPL_CALLBACK 8
+#define TPL_NOTIFY 16
+#define TPL_HIGH_LEVEL 31
+
+typedef
+EFI_TPL
+(EFIAPI *EFI_RAISE_TPL) (
+ IN EFI_TPL NewTpl
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_RESTORE_TPL) (
+ IN EFI_TPL OldTpl
+ );
+
+
+//
+// EFI platform varibles
+//
+
+#define EFI_GLOBAL_VARIABLE \
+ { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
+
+// Variable attributes
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+
+// Variable size limitation
+#define EFI_MAXIMUM_VARIABLE_SIZE 1024
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_VARIABLE) (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) (
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VARIABLE) (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+//
+// EFI Time
+//
+
+typedef struct {
+ UINT32 Resolution; // 1e-6 parts per million
+ UINT32 Accuracy; // hertz
+ BOOLEAN SetsToZero; // Set clears sub-second time
+} EFI_TIME_CAPABILITIES;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIME) (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIME) (
+ IN EFI_TIME *Time
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_WAKEUP_TIME) (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WAKEUP_TIME) (
+ IN BOOLEAN Enable,
+ IN EFI_TIME *Time OPTIONAL
+ );
+
+
+//
+// Image functions
+//
+
+
+// PE32+ Subsystem type for EFI images
+
+#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION)
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#endif
+
+// PE32+ Machine type for EFI images
+
+#if !defined(EFI_IMAGE_MACHINE_IA32)
+#define EFI_IMAGE_MACHINE_IA32 0x014c
+#endif
+
+#if !defined(EFI_IMAGE_MACHINE_EBC)
+#define EFI_IMAGE_MACHINE_EBC 0x0EBC
+#endif
+
+// Image Entry prototype
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_ENTRY_POINT) (
+ IN EFI_HANDLE ImageHandle,
+ IN struct _EFI_SYSTEM_TABLE *SystemTable
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_LOAD) (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_START) (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT) (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS ExitStatus,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_UNLOAD) (
+ IN EFI_HANDLE ImageHandle
+ );
+
+
+// Image handle
+#define LOADED_IMAGE_PROTOCOL \
+ { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} }
+
+#define EFI_LOADED_IMAGE_INFORMATION_REVISION 0x1000
+typedef struct {
+ UINT32 Revision;
+ EFI_HANDLE ParentHandle;
+ struct _EFI_SYSTEM_TABLE *SystemTable;
+
+ // Source location of image
+ EFI_HANDLE DeviceHandle;
+ EFI_DEVICE_PATH *FilePath;
+ VOID *Reserved;
+
+ // Images load options
+ UINT32 LoadOptionsSize;
+ VOID *LoadOptions;
+
+ // Location of where image was loaded
+ VOID *ImageBase;
+ UINT64 ImageSize;
+ EFI_MEMORY_TYPE ImageCodeType;
+ EFI_MEMORY_TYPE ImageDataType;
+
+ // If the driver image supports a dynamic unload request
+ EFI_IMAGE_UNLOAD Unload;
+
+} EFI_LOADED_IMAGE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT_BOOT_SERVICES) (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ );
+
+//
+// Misc
+//
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL) (
+ IN UINTN Microseconds
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WATCHDOG_TIMER) (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ );
+
+
+typedef enum {
+ EfiResetCold,
+ EfiResetWarm,
+ EfiResetShutdown
+} EFI_RESET_TYPE;
+
+typedef
+VOID
+(EFIAPI *EFI_RESET_SYSTEM) (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) (
+ OUT UINT64 *Count
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) (
+ OUT UINT32 *HighCount
+ );
+
+//
+// Protocol handler functions
+//
+
+typedef enum {
+ EFI_NATIVE_INTERFACE
+} EFI_INTERFACE_TYPE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) (
+ IN OUT EFI_HANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HANDLE_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ );
+
+typedef enum {
+ AllHandles,
+ ByRegisterNotify,
+ ByProtocol
+} EFI_LOCATE_SEARCH_TYPE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE) (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_DEVICE_PATH) (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH **DevicePath,
+ OUT EFI_HANDLE *Device
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RESERVED_SERVICE) (
+ VOID
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONNECT_CONTROLLER) (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle, OPTIONAL
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle, OPTIONAL
+ IN UINT32 Attributes
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle
+ );
+
+typedef struct {
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_PROTOCOL) (
+ EFI_GUID *Protocol,
+ VOID *Registration, OPTIONAL
+ VOID **Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) (
+ IN EFI_HANDLE Handle,
+ ...
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CALCULATE_CRC32) (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *Crc32
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_COPY_MEM) (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_SET_MEM) (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ );
+
+//
+// Standard EFI table header
+//
+
+typedef struct _EFI_TABLE_HEARDER {
+ UINT64 Signature;
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 CRC32;
+ UINT32 Reserved;
+} EFI_TABLE_HEADER;
+
+
+//
+// EFI Runtime Serivces Table
+//
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552
+#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+
+typedef struct {
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Time services
+ //
+
+ EFI_GET_TIME GetTime;
+ EFI_SET_TIME SetTime;
+ EFI_GET_WAKEUP_TIME GetWakeupTime;
+ EFI_SET_WAKEUP_TIME SetWakeupTime;
+
+ //
+ // Virtual memory services
+ //
+
+ EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
+ EFI_CONVERT_POINTER ConvertPointer;
+
+ //
+ // Variable serviers
+ //
+
+ EFI_GET_VARIABLE GetVariable;
+ EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
+ EFI_SET_VARIABLE SetVariable;
+
+ //
+ // Misc
+ //
+
+ EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
+ EFI_RESET_SYSTEM ResetSystem;
+
+} EFI_RUNTIME_SERVICES;
+
+
+//
+// EFI Boot Services Table
+//
+
+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
+#define EFI_BOOT_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+
+typedef struct {
+
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Task priority functions
+ //
+
+ EFI_RAISE_TPL RaiseTPL;
+ EFI_RESTORE_TPL RestoreTPL;
+
+ //
+ // Memory functions
+ //
+
+ EFI_ALLOCATE_PAGES AllocatePages;
+ EFI_FREE_PAGES FreePages;
+ EFI_GET_MEMORY_MAP GetMemoryMap;
+ EFI_ALLOCATE_POOL AllocatePool;
+ EFI_FREE_POOL FreePool;
+
+ //
+ // Event & timer functions
+ //
+
+ EFI_CREATE_EVENT CreateEvent;
+ EFI_SET_TIMER SetTimer;
+ EFI_WAIT_FOR_EVENT WaitForEvent;
+ EFI_SIGNAL_EVENT SignalEvent;
+ EFI_CLOSE_EVENT CloseEvent;
+ EFI_CHECK_EVENT CheckEvent;
+
+ //
+ // Protocol handler functions
+ //
+
+ EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
+ EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
+ EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
+ EFI_HANDLE_PROTOCOL HandleProtocol;
+ VOID *Reserved;
+ EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
+ EFI_LOCATE_HANDLE LocateHandle;
+ EFI_LOCATE_DEVICE_PATH LocateDevicePath;
+ EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
+
+ //
+ // Image functions
+ //
+
+ EFI_IMAGE_LOAD LoadImage;
+ EFI_IMAGE_START StartImage;
+ EFI_EXIT Exit;
+ EFI_IMAGE_UNLOAD UnloadImage;
+ EFI_EXIT_BOOT_SERVICES ExitBootServices;
+
+ //
+ // Misc functions
+ //
+
+ EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
+ EFI_STALL Stall;
+ EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
+
+ //
+ // DriverSupport Services
+ //
+ EFI_CONNECT_CONTROLLER ConnectController;
+ EFI_DISCONNECT_CONTROLLER DisconnectController;
+
+ //
+ // Open and Close Protocol Services
+ //
+ EFI_OPEN_PROTOCOL OpenProtocol;
+ EFI_CLOSE_PROTOCOL CloseProtocol;
+ EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
+
+ //
+ // Library Services to reduce size of drivers
+ //
+ EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
+ EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
+ EFI_LOCATE_PROTOCOL LocateProtocol;
+
+ EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
+ EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
+
+ //
+ // CRC32 services
+ //
+ EFI_CALCULATE_CRC32 CalculateCrc32;
+
+ //
+ // Memory Utility Services
+ //
+ EFI_COPY_MEM CopyMem;
+ EFI_SET_MEM SetMem;
+
+} EFI_BOOT_SERVICES;
+
+
+//
+// EFI Configuration Table and GUID definitions
+//
+
+#define MPS_TABLE_GUID \
+ { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define ACPI_TABLE_GUID \
+ { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define ACPI_20_TABLE_GUID \
+ { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+
+#define SMBIOS_TABLE_GUID \
+ { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define SAL_SYSTEM_TABLE_GUID \
+ { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define SMBIOS3_TABLE_GUID \
+ { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } }
+
+#define FDT_TABLE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} }
+
+#define DXE_SERVICES_TABLE_GUID \
+ { 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9} }
+
+#define HOB_LIST_TABLE_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define MEMORY_TYPE_INFORMATION_TABLE_GUID \
+ { 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} }
+
+#define DEBUG_IMAGE_INFO_TABLE_GUID \
+ { 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b} }
+
+typedef struct _EFI_CONFIGURATION_TABLE {
+ EFI_GUID VendorGuid;
+ VOID *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+
+//
+// EFI System Table
+//
+
+
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
+#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+#define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | 10)
+#define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | 02)
+
+typedef struct _EFI_SYSTEM_TABLE {
+ EFI_TABLE_HEADER Hdr;
+
+ CHAR16 *FirmwareVendor;
+ UINT32 FirmwareRevision;
+
+ EFI_HANDLE ConsoleInHandle;
+ SIMPLE_INPUT_INTERFACE *ConIn;
+
+ EFI_HANDLE ConsoleOutHandle;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
+
+ EFI_HANDLE StandardErrorHandle;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
+
+ EFI_RUNTIME_SERVICES *RuntimeServices;
+ EFI_BOOT_SERVICES *BootServices;
+
+ UINTN NumberOfTableEntries;
+ EFI_CONFIGURATION_TABLE *ConfigurationTable;
+
+} EFI_SYSTEM_TABLE;
+
+/*
+ * unlisted GUID's..
+ */
+#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \
+{ 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7} }
+
+#define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \
+{ 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe} }
+
+#define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \
+{ 0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ { 0x18A031AB, 0xB443, 0x4D1A, \
+ { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \
+ }
+
+#define EFI_TAPE_IO_PROTOCOL_GUID \
+ { 0x1e93e633, 0xd65a, 0x459e, \
+ { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \
+ }
+
+#define EFI_SCSI_IO_PROTOCOL_GUID \
+ { 0x932f47e6, 0x2362, 0x4002, \
+ { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \
+ }
+
+#define EFI_USB2_HC_PROTOCOL_GUID \
+ { 0x3e745226, 0x9818, 0x45b6, \
+ { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \
+ }
+
+#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \
+ { 0x2755590C, 0x6F3C, 0x42FA, \
+ { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \
+ }
+
+#define EFI_DEBUGPORT_PROTOCOL_GUID \
+ { 0xEBA4E8D2, 0x3858, 0x41EC, \
+ { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+ }
+
+#define EFI_DECOMPRESS_PROTOCOL_GUID \
+ { 0xd8117cfe, 0x94a6, 0x11d4, \
+ { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+ { 0x8b843e20, 0x8132, 0x4852, \
+ { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \
+ }
+
+#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \
+ { 0x379be4e, 0xd706, 0x437d, \
+ { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+ }
+
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+ { 0x5c99a21, 0xc70f, 0x4ad2, \
+ { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \
+ }
+
+#define EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { 0xffe06bdd, 0x6107, 0x46a6, \
+ { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \
+ }
+
+#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
+ { 0x587e72d7, 0xcc50, 0x4f79, \
+ { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \
+ }
+
+#define EFI_HII_DATABASE_PROTOCOL_GUID \
+ { 0xef9fc172, 0xa1b2, 0x4693, \
+ { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \
+ }
+
+#define EFI_HII_STRING_PROTOCOL_GUID \
+ { 0xfd96974, 0x23aa, 0x4cdc, \
+ { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \
+ }
+
+#define EFI_HII_IMAGE_PROTOCOL_GUID \
+ { 0x31a6406a, 0x6bdf, 0x4e46, \
+ { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \
+ }
+
+#define EFI_HII_FONT_PROTOCOL_GUID \
+ { 0xe9ca4775, 0x8657, 0x47fc, \
+ { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \
+ }
+#define EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \
+ { 0x330d4706, 0xf2a0, 0x4e4f, \
+ { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \
+ }
+
+#define EFI_COMPONENT_NAME_PROTOCOL_GUID \
+{ 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \
+ { 0x6a7a5cff, 0xe8d9, 0x4f70, \
+ { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \
+ }
+
+#define EFI_USB_IO_PROTOCOL_GUID \
+ { 0x2B2F68D6, 0x0CD2, 0x44cf, \
+ { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \
+ }
+#define EFI_HCDP_TABLE_GUID \
+ { 0xf951938d, 0x620b, 0x42ef, \
+ { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
+ }
+
+#define EFI_DEVICE_TREE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, \
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+ }
+
+#define EFI_VENDOR_APPLE_GUID \
+ { 0x2B0585EB, 0xD8B8, 0x49A9, \
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+ }
+
+#define EFI_CONSOLE_IN_DEVICE_GUID \
+{ 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_CONSOLE_OUT_DEVICE_GUID \
+{ 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_STANDARD_ERROR_DEVICE_GUID \
+{ 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_UNICODE_COLLATION2_PROTOCOL_GUID \
+{ 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49} }
+
+#define EFI_FORM_BROWSER2_PROTOCOL_GUID \
+{ 0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58} }
+
+#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3} }
+
+#define EFI_ARP_PROTOCOL_GUID \
+{ 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c} }
+
+#define EFI_IP4_CONFIG_PROTOCOL_GUID \
+{ 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e} }
+
+#define EFI_IP6_CONFIG_PROTOCOL_GUID \
+{ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a} }
+
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+{ 0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf} }
+
+#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c} }
+
+#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \
+{ 0x7ab33a91, 0xace5, 0x4326, {0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16} }
+
+#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F} }
+
+#define EFI_MTFTP4_PROTOCOL_GUID \
+{ 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b} }
+
+#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23} }
+
+#define EFI_MTFTP6_PROTOCOL_GUID \
+{ 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51} }
+
+#define EFI_DHCP4_PROTOCOL_GUID \
+{ 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56} }
+
+#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80} }
+
+#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5} }
+
+#define EFI_DHCP6_PROTOCOL_GUID \
+{ 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b} }
+
+#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \
+{ 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77} }
+
+#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \
+{ 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe} }
+
+#define EFI_DISK_INFO_PROTOCOL_GUID \
+{ 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27} }
+
+#define EFI_ISA_IO_PROTOCOL_GUID \
+{ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_VLAN_CONFIG_PROTOCOL_GUID \
+{ 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74} }
+
+#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \
+{ 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9} }
+
+#define EFI_ISA_ACPI_PROTOCOL_GUID \
+{ 0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55} }
+
+#define EFI_PCI_ENUMERATION_COMPLETE_GUID \
+{ 0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93} }
+
+#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \
+{ 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \
+{ 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63} }
+
+#define EFI_CAPSULE_ARCH_PROTOCOL_GUID \
+{ 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54} }
+
+#define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \
+{0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} }
+
+#define EFI_REALTIME_CLOCK_ARCH_PROTOCOL_GUID \
+{0x27cfac87, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} }
+
+#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \
+{ 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_ACPI_SUPPORT_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_BDS_ARCH_PROTOCOL_GUID \
+{ 0x665e3ff6, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_METRONOME_ARCH_PROTOCOL_GUID \
+{ 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_TIMER_ARCH_PROTOCOL_GUID \
+{ 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_DPC_PROTOCOL_GUID \
+{ 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6} }
+
+#define EFI_PRINT2_PROTOCOL_GUID \
+{ 0xf05976ef, 0x83f1, 0x4f3d, {0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38} }
+
+#define EFI_RESET_ARCH_PROTOCOL_GUID \
+{ 0x27cfac88, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_CPU_ARCH_PROTOCOL_GUID \
+{ 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_CPU_IO2_PROTOCOL_GUID \
+{ 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} }
+
+#define EFI_LEGACY_8259_PROTOCOL_GUID \
+{ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1} }
+
+#define EFI_SECURITY_ARCH_PROTOCOL_GUID \
+{ 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39} }
+
+#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \
+{ 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68} }
+
+#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \
+{ 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33} }
+
+#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \
+{ 0xd2b2b828, 0x826, 0x48a7, {0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0} }
+
+#define EFI_DATA_HUB_PROTOCOL_GUID \
+{ 0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+
+#define PCD_PROTOCOL_GUID \
+{ 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7} }
+
+#define EFI_PCD_PROTOCOL_GUID \
+{ 0x13a3f0f6, 0x264a, 0x3ef0, {0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34} }
+
+#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \
+{ 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } }
+
+#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \
+{ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a } }
+
+#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \
+{ 0x7aa35a69, 0x506c, 0x444f, {0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8} }
+
+#define LZMA_COMPRESS_GUID \
+{ 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf} }
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/eficon.h b/usr/src/boot/sys/boot/efi/include/eficon.h
new file mode 100644
index 0000000000..1d0c869f47
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/eficon.h
@@ -0,0 +1,313 @@
+/* $FreeBSD$ */
+#ifndef _EFI_CON_H
+#define _EFI_CON_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ eficon.h
+
+Abstract:
+
+ EFI console protocols
+
+
+
+Revision History
+
+--*/
+
+//
+// Text output protocol
+//
+
+#define SIMPLE_TEXT_OUTPUT_PROTOCOL \
+ { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_RESET) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_OUTPUT_STRING) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN CHAR16 *String
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_TEST_STRING) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN CHAR16 *String
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_QUERY_MODE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_MODE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN ModeNumber
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN Attribute
+ );
+
+#define EFI_BLACK 0x00
+#define EFI_BLUE 0x01
+#define EFI_GREEN 0x02
+#define EFI_CYAN (EFI_BLUE | EFI_GREEN)
+#define EFI_RED 0x04
+#define EFI_MAGENTA (EFI_BLUE | EFI_RED)
+#define EFI_BROWN (EFI_GREEN | EFI_RED)
+#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED)
+#define EFI_BRIGHT 0x08
+#define EFI_DARKGRAY (EFI_BRIGHT)
+#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT)
+#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT)
+#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT)
+#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT)
+#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT)
+#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT)
+#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
+
+#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4))
+
+#define EFI_BACKGROUND_BLACK 0x00
+#define EFI_BACKGROUND_BLUE 0x10
+#define EFI_BACKGROUND_GREEN 0x20
+#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)
+#define EFI_BACKGROUND_RED 0x40
+#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_CLEAR_SCREEN) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN Column,
+ IN UINTN Row
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_ENABLE_CURSOR) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN BOOLEAN Enable
+ );
+
+typedef struct {
+ INT32 MaxMode;
+ // current settings
+ INT32 Mode;
+ INT32 Attribute;
+ INT32 CursorColumn;
+ INT32 CursorRow;
+ BOOLEAN CursorVisible;
+} SIMPLE_TEXT_OUTPUT_MODE;
+
+typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE {
+ EFI_TEXT_RESET Reset;
+
+ EFI_TEXT_OUTPUT_STRING OutputString;
+ EFI_TEXT_TEST_STRING TestString;
+
+ EFI_TEXT_QUERY_MODE QueryMode;
+ EFI_TEXT_SET_MODE SetMode;
+ EFI_TEXT_SET_ATTRIBUTE SetAttribute;
+
+ EFI_TEXT_CLEAR_SCREEN ClearScreen;
+ EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;
+ EFI_TEXT_ENABLE_CURSOR EnableCursor;
+
+ // Current mode
+ SIMPLE_TEXT_OUTPUT_MODE *Mode;
+} SIMPLE_TEXT_OUTPUT_INTERFACE;
+
+//
+// Define's for required EFI Unicode Box Draw character
+//
+
+#define BOXDRAW_HORIZONTAL 0x2500
+#define BOXDRAW_VERTICAL 0x2502
+#define BOXDRAW_DOWN_RIGHT 0x250c
+#define BOXDRAW_DOWN_LEFT 0x2510
+#define BOXDRAW_UP_RIGHT 0x2514
+#define BOXDRAW_UP_LEFT 0x2518
+#define BOXDRAW_VERTICAL_RIGHT 0x251c
+#define BOXDRAW_VERTICAL_LEFT 0x2524
+#define BOXDRAW_DOWN_HORIZONTAL 0x252c
+#define BOXDRAW_UP_HORIZONTAL 0x2534
+#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c
+
+#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550
+#define BOXDRAW_DOUBLE_VERTICAL 0x2551
+#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552
+#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553
+#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554
+
+#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555
+#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556
+#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557
+
+#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558
+#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559
+#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a
+
+#define BOXDRAW_UP_LEFT_DOUBLE 0x255b
+#define BOXDRAW_UP_DOUBLE_LEFT 0x255c
+#define BOXDRAW_DOUBLE_UP_LEFT 0x255d
+
+#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e
+#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f
+#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560
+
+#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561
+#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562
+#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563
+
+#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564
+#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565
+#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566
+
+#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567
+#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568
+#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569
+
+#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a
+#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b
+#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c
+
+//
+// EFI Required Block Elements Code Chart
+//
+
+#define BLOCKELEMENT_FULL_BLOCK 0x2588
+#define BLOCKELEMENT_LIGHT_SHADE 0x2591
+//
+// EFI Required Geometric Shapes Code Chart
+//
+
+#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2
+#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba
+#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc
+#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4
+
+//
+// EFI Required Arrow shapes
+//
+
+#define ARROW_UP 0x2191
+#define ARROW_DOWN 0x2193
+
+//
+// Text input protocol
+//
+
+#define SIMPLE_TEXT_INPUT_PROTOCOL \
+ { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE);
+
+typedef struct {
+ UINT16 ScanCode;
+ CHAR16 UnicodeChar;
+} EFI_INPUT_KEY;
+
+//
+// Baseline unicode control chars
+//
+
+#define CHAR_NULL 0x0000
+#define CHAR_BACKSPACE 0x0008
+#define CHAR_TAB 0x0009
+#define CHAR_LINEFEED 0x000A
+#define CHAR_CARRIAGE_RETURN 0x000D
+
+//
+// Scan codes for base line keys
+//
+
+#define SCAN_NULL 0x0000
+#define SCAN_UP 0x0001
+#define SCAN_DOWN 0x0002
+#define SCAN_RIGHT 0x0003
+#define SCAN_LEFT 0x0004
+#define SCAN_HOME 0x0005
+#define SCAN_END 0x0006
+#define SCAN_INSERT 0x0007
+#define SCAN_DELETE 0x0008
+#define SCAN_PAGE_UP 0x0009
+#define SCAN_PAGE_DOWN 0x000A
+#define SCAN_F1 0x000B
+#define SCAN_F2 0x000C
+#define SCAN_F3 0x000D
+#define SCAN_F4 0x000E
+#define SCAN_F5 0x000F
+#define SCAN_F6 0x0010
+#define SCAN_F7 0x0011
+#define SCAN_F8 0x0012
+#define SCAN_F9 0x0013
+#define SCAN_F10 0x0014
+#define SCAN_ESC 0x0017
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET) (
+ IN struct _SIMPLE_INPUT_INTERFACE *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY) (
+ IN struct _SIMPLE_INPUT_INTERFACE *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+typedef struct _SIMPLE_INPUT_INTERFACE {
+ EFI_INPUT_RESET Reset;
+ EFI_INPUT_READ_KEY ReadKeyStroke;
+ EFI_EVENT WaitForKey;
+} SIMPLE_INPUT_INTERFACE;
+
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+ {0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, \
+ 0x17, 0xa6, 0x25, 0xaa} }
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/eficonsctl.h b/usr/src/boot/sys/boot/efi/include/eficonsctl.h
new file mode 100644
index 0000000000..68be3d69f4
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/eficonsctl.h
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 2004 - 2010, Intel Corporation. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+/*
+ * Original Module Name: ConsoleControl.h
+ * Abstract: Abstraction of a Text mode or GOP/UGA screen
+ */
+
+/* $FreeBSD$ */
+
+#ifndef _EFI_CONS_CTL_H
+#define _EFI_CONS_CTL_H
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+ { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} }
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL;
+
+
+typedef enum {
+ EfiConsoleControlScreenText,
+ EfiConsoleControlScreenGraphics,
+ EfiConsoleControlScreenMaxValue
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+ OUT BOOLEAN *GopUgaExists, OPTIONAL
+ OUT BOOLEAN *StdInLocked OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Return the current video mode information. Also returns info about existence
+ of Graphics Output devices or UGA Draw devices in system, and if the Std In
+ device is locked. All the arguments are optional and only returned if a non
+ NULL pointer is passed in.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Are we in text of grahics mode.
+ GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device
+ StdInLocked - TRUE if StdIn device is keyboard locked
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+ )
+/*++
+
+ Routine Description:
+ Set the current mode to either text or graphics. Graphics is
+ for Quiet Boot.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Mode to set the
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN CHAR16 *Password
+ )
+/*++
+
+ Routine Description:
+ Lock Std In devices until Password is typed.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Password - Password needed to unlock screen. NULL means unlock keyboard
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_DEVICE_ERROR - Std In not locked
+
+--*/
+;
+
+
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+ EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
+};
+
+extern EFI_GUID gEfiConsoleControlProtocolGuid;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efidebug.h b/usr/src/boot/sys/boot/efi/include/efidebug.h
new file mode 100644
index 0000000000..5576d5f4e4
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efidebug.h
@@ -0,0 +1,118 @@
+/* $FreeBSD$ */
+#ifndef _EFI_DEBUG_H
+#define _EFI_DEBUG_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efidebug.h
+
+Abstract:
+
+ EFI library debug functions
+
+
+
+Revision History
+
+--*/
+
+extern UINTN EFIDebug;
+
+#if EFI_DEBUG
+
+ #define DBGASSERT(a) DbgAssert(__FILE__, __LINE__, #a)
+ #define DEBUG(a) DbgPrint a
+
+#else
+
+ #define DBGASSERT(a)
+ #define DEBUG(a)
+
+#endif
+
+#if EFI_DEBUG_CLEAR_MEMORY
+
+ #define DBGSETMEM(a,l) SetMem(a,l,(CHAR8)BAD_POINTER)
+
+#else
+
+ #define DBGSETMEM(a,l)
+
+#endif
+
+#define D_INIT 0x00000001 // Initialization style messages
+#define D_WARN 0x00000002 // Warnings
+#define D_LOAD 0x00000004 // Load events
+#define D_FS 0x00000008 // EFI File system
+#define D_POOL 0x00000010 // Alloc & Free's
+#define D_PAGE 0x00000020 // Alloc & Free's
+#define D_INFO 0x00000040 // Verbose
+#define D_VARIABLE 0x00000100 // Variable
+#define D_VAR 0x00000100 // Variable
+#define D_BM 0x00000400 // Boot Manager
+#define D_BLKIO 0x00001000 // BlkIo Driver
+#define D_BLKIO_ULTRA 0x00002000 // BlkIo Driver
+#define D_NET 0x00004000 // SNI Driver
+#define D_NET_ULTRA 0x00008000 // SNI Driver
+#define D_UNDI 0x00010000 // UNDI Driver
+#define D_LOADFILE 0x00020000 // UNDI Driver
+#define D_EVENT 0x00080000 // Event messages
+
+#define D_ERROR 0x80000000 // Error
+
+#define D_RESERVED 0x7ff40A80 // Bits not reserved above
+
+//
+// Current Debug level of the system, value of EFIDebug
+//
+//#define EFI_DBUG_MASK (D_ERROR | D_WARN | D_LOAD | D_BLKIO | D_INIT)
+#define EFI_DBUG_MASK (D_ERROR)
+
+//
+//
+//
+
+#if EFI_DEBUG
+
+ #define ASSERT(a) if(!(a)) DBGASSERT(a)
+ #define ASSERT_LOCKED(l) if(!(l)->Lock) DBGASSERT(l not locked)
+ #define ASSERT_STRUCT(p,t) DBGASSERT(t not structure), p
+
+#else
+
+ #define ASSERT(a)
+ #define ASSERT_LOCKED(l)
+ #define ASSERT_STRUCT(p,t)
+
+#endif
+
+//
+// Prototypes
+//
+
+INTN
+DbgAssert (
+ CHAR8 *file,
+ INTN lineno,
+ CHAR8 *string
+ );
+
+INTN
+DbgPrint (
+ INTN mask,
+ CHAR8 *format,
+ ...
+ );
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efidef.h b/usr/src/boot/sys/boot/efi/include/efidef.h
new file mode 100644
index 0000000000..3ee0708144
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efidef.h
@@ -0,0 +1,218 @@
+/* $FreeBSD$ */
+#ifndef _EFI_DEF_H
+#define _EFI_DEF_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efidef.h
+
+Abstract:
+
+ EFI definitions
+
+
+
+
+Revision History
+
+--*/
+
+typedef UINT16 CHAR16;
+typedef UINT8 CHAR8;
+#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */
+typedef UINT8 BOOLEAN;
+#endif
+
+#ifndef TRUE
+ #define TRUE ((BOOLEAN) 1)
+ #define FALSE ((BOOLEAN) 0)
+#endif
+
+#ifndef NULL
+ #define NULL ((VOID *) 0)
+#endif
+
+typedef UINTN EFI_STATUS;
+typedef UINT64 EFI_LBA;
+typedef UINTN EFI_TPL;
+typedef VOID *EFI_HANDLE;
+typedef VOID *EFI_EVENT;
+
+
+//
+// Prototype argument decoration for EFI parameters to indicate
+// their direction
+//
+// IN - argument is passed into the function
+// OUT - argument (pointer) is returned from the function
+// OPTIONAL - argument is optional
+//
+
+#ifndef IN
+ #define IN
+ #define OUT
+ #define OPTIONAL
+#endif
+
+
+//
+// A GUID
+//
+
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+
+
+//
+// Time
+//
+
+typedef struct {
+ UINT16 Year; // 1998 - 20XX
+ UINT8 Month; // 1 - 12
+ UINT8 Day; // 1 - 31
+ UINT8 Hour; // 0 - 23
+ UINT8 Minute; // 0 - 59
+ UINT8 Second; // 0 - 59
+ UINT8 Pad1;
+ UINT32 Nanosecond; // 0 - 999,999,999
+ INT16 TimeZone; // -1440 to 1440 or 2047
+ UINT8 Daylight;
+ UINT8 Pad2;
+} EFI_TIME;
+
+// Bit definitions for EFI_TIME.Daylight
+#define EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define EFI_TIME_IN_DAYLIGHT 0x02
+
+// Value definition for EFI_TIME.TimeZone
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+
+
+//
+// Networking
+//
+
+typedef struct {
+ UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+typedef struct {
+ UINT32 ReceivedQueueTimeoutValue;
+ UINT32 TransmitQueueTimeoutValue;
+ UINT16 ProtocolTypeFilter;
+ BOOLEAN EnableUnicastReceive;
+ BOOLEAN EnableMulticastReceive;
+ BOOLEAN EnableBroadcastReceive;
+ BOOLEAN EnablePromiscuousReceive;
+ BOOLEAN FlushQueuesOnReset;
+ BOOLEAN EnableReceiveTimestamps;
+ BOOLEAN DisableBackgroundPolling;
+} EFI_MANAGED_NETWORK_CONFIG_DATA;
+
+//
+// Memory
+//
+
+typedef UINT64 EFI_PHYSICAL_ADDRESS;
+typedef UINT64 EFI_VIRTUAL_ADDRESS;
+
+typedef enum {
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ AllocateAddress,
+ MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+//Preseve the attr on any range supplied.
+//ConventialMemory must have WB,SR,SW when supplied.
+//When allocating from ConventialMemory always make it WB,SR,SW
+//When returning to ConventialMemory always make it WB,SR,SW
+//When getting the memory map, or on RT for runtime types
+
+
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+// possible caching types for the memory range
+#define EFI_MEMORY_UC 0x0000000000000001
+#define EFI_MEMORY_WC 0x0000000000000002
+#define EFI_MEMORY_WT 0x0000000000000004
+#define EFI_MEMORY_WB 0x0000000000000008
+#define EFI_MEMORY_UCE 0x0000000000000010
+
+// physical memory protection on range
+#define EFI_MEMORY_WP 0x0000000000001000
+#define EFI_MEMORY_RP 0x0000000000002000
+#define EFI_MEMORY_XP 0x0000000000004000
+
+// range requires a runtime mapping
+#define EFI_MEMORY_RUNTIME 0x8000000000000000
+
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+typedef struct {
+ UINT32 Type; // Field size is 32 bits followed by 32 bit pad
+ EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits
+ EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits
+ UINT64 NumberOfPages; // Field size is 64 bits
+ UINT64 Attribute; // Field size is 64 bits
+} EFI_MEMORY_DESCRIPTOR;
+
+//
+// International Language
+//
+
+typedef UINT8 ISO_639_2;
+#define ISO_639_2_ENTRY_SIZE 3
+
+//
+//
+//
+
+#define EFI_PAGE_SIZE 4096
+#define EFI_PAGE_MASK 0xFFF
+#define EFI_PAGE_SHIFT 12
+
+#define EFI_SIZE_TO_PAGES(a) \
+ ( ((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0) )
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efidevp.h b/usr/src/boot/sys/boot/efi/include/efidevp.h
new file mode 100644
index 0000000000..dda79de7af
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efidevp.h
@@ -0,0 +1,428 @@
+/* $FreeBSD$ */
+#ifndef _DEVPATH_H
+#define _DEVPATH_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ devpath.h
+
+Abstract:
+
+ Defines for parsing the EFI Device Path structures
+
+
+
+Revision History
+
+--*/
+
+//
+// Device Path structures - Section C
+//
+
+typedef struct _EFI_DEVICE_PATH {
+ UINT8 Type;
+ UINT8 SubType;
+ UINT8 Length[2];
+} EFI_DEVICE_PATH;
+
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+
+#define END_DEVICE_PATH_TYPE 0x7f
+
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH))
+
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK )
+#define DevicePathSubType(a) ( (a)->SubType )
+#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+#define IsDevicePathType(a, t) ( DevicePathType(a) == t )
+#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE)
+#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED )
+
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \
+ (a)->Length[1] = 0; \
+ }
+
+
+
+/*
+ *
+ */
+#define HARDWARE_DEVICE_PATH 0x01
+
+#define HW_PCI_DP 0x01
+typedef struct _PCI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 Function;
+ UINT8 Device;
+} PCI_DEVICE_PATH;
+
+#define HW_PCCARD_DP 0x02
+typedef struct _PCCARD_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+#define HW_MEMMAP_DP 0x03
+typedef struct _MEMMAP_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 MemoryType;
+ EFI_PHYSICAL_ADDRESS StartingAddress;
+ EFI_PHYSICAL_ADDRESS EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+#define HW_VENDOR_DP 0x04
+typedef struct _VENDOR_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_GUID Guid;
+} VENDOR_DEVICE_PATH;
+
+#define UNKNOWN_DEVICE_GUID \
+ { 0xcf31fac5, 0xc24e, 0x11d2, {0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }
+
+typedef struct _UKNOWN_DEVICE_VENDOR_DP {
+ VENDOR_DEVICE_PATH DevicePath;
+ UINT8 LegacyDriveLetter;
+} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;
+
+#define HW_CONTROLLER_DP 0x05
+typedef struct _CONTROLLER_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Controller;
+} CONTROLLER_DEVICE_PATH;
+
+/*
+ *
+ */
+#define ACPI_DEVICE_PATH 0x02
+
+#define ACPI_DP 0x01
+typedef struct _ACPI_HID_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 HID;
+ UINT32 UID;
+} ACPI_HID_DEVICE_PATH;
+
+#define ACPI_EXTENDED_DP 0x02
+typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 HID;
+ UINT32 UID;
+ UINT32 CID;
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+//
+// EISA ID Macro
+// EISA ID Definition 32-bits
+// bits[15:0] - three character compressed ASCII EISA ID.
+// bits[31:16] - binary number
+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST 0x41d0
+#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK 0xffff
+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
+/*
+ *
+ */
+#define MESSAGING_DEVICE_PATH 0x03
+
+#define MSG_ATAPI_DP 0x01
+typedef struct _ATAPI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 PrimarySecondary;
+ UINT8 SlaveMaster;
+ UINT16 Lun;
+} ATAPI_DEVICE_PATH;
+
+#define MSG_SCSI_DP 0x02
+typedef struct _SCSI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 Pun;
+ UINT16 Lun;
+} SCSI_DEVICE_PATH;
+
+#define MSG_FIBRECHANNEL_DP 0x03
+typedef struct _FIBRECHANNEL_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 WWN;
+ UINT64 Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+#define MSG_1394_DP 0x04
+typedef struct _F1394_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 Guid;
+} F1394_DEVICE_PATH;
+
+#define MSG_USB_DP 0x05
+typedef struct _USB_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 ParentPortNumber;
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+
+#define MSG_USB_CLASS_DP 0x0F
+typedef struct _USB_CLASS_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 VendorId;
+ UINT16 ProductId;
+ UINT8 DeviceClass;
+ UINT8 DeviceSubClass;
+ UINT8 DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+#define MSG_I2O_DP 0x06
+typedef struct _I2O_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Tid;
+} I2O_DEVICE_PATH;
+
+#define MSG_MAC_ADDR_DP 0x0b
+typedef struct _MAC_ADDR_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_MAC_ADDRESS MacAddress;
+ UINT8 IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+#define MSG_IPv4_DP 0x0c
+typedef struct _IPv4_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_IPv4_ADDRESS LocalIpAddress;
+ EFI_IPv4_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+} IPv4_DEVICE_PATH;
+
+#define MSG_IPv6_DP 0x0d
+typedef struct _IPv6_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_IPv6_ADDRESS LocalIpAddress;
+ EFI_IPv6_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+} IPv6_DEVICE_PATH;
+
+#define MSG_INFINIBAND_DP 0x09
+typedef struct _INFINIBAND_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 ResourceFlags;
+ UINT8 PortGid[16];
+ UINT64 ServiceId;
+ UINT64 TargetPortId;
+ UINT64 DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
+
+#define MSG_UART_DP 0x0e
+typedef struct _UART_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 BaudRate;
+ UINT8 DataBits;
+ UINT8 Parity;
+ UINT8 StopBits;
+} UART_DEVICE_PATH;
+
+#define MSG_VENDOR_DP 0x0A
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI \
+ { 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define DEVICE_PATH_MESSAGING_VT_100 \
+ { 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS \
+ { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} }
+
+#define DEVICE_PATH_MESSAGING_VT_UTF8 \
+ { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} }
+
+#define MSG_SATA_DP 0x12
+typedef struct _SATA_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 HBAPortNumber;
+ UINT16 PortMultiplierPortNumber;
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
+
+#define MEDIA_DEVICE_PATH 0x04
+
+#define MEDIA_HARDDRIVE_DP 0x01
+typedef struct _HARDDRIVE_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 PartitionNumber;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+ UINT8 Signature[16];
+ UINT8 MBRType;
+ UINT8 SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define SIGNATURE_TYPE_MBR 0x01
+#define SIGNATURE_TYPE_GUID 0x02
+
+#define MEDIA_CDROM_DP 0x02
+typedef struct _CDROM_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 BootEntry;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+} CDROM_DEVICE_PATH;
+
+#define MEDIA_VENDOR_DP 0x03
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define MEDIA_FILEPATH_DP 0x04
+typedef struct _FILEPATH_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ CHAR16 PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName)
+
+#define MEDIA_PROTOCOL_DP 0x05
+typedef struct _MEDIA_PROTOCOL_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_GUID Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+
+#define BBS_DEVICE_PATH 0x05
+#define BBS_BBS_DP 0x01
+typedef struct _BBS_BBS_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 DeviceType;
+ UINT16 StatusFlag;
+ CHAR8 String[1];
+} BBS_BBS_DEVICE_PATH;
+
+/* DeviceType definitions - from BBS specification */
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_DEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+typedef union {
+ EFI_DEVICE_PATH DevPath;
+ PCI_DEVICE_PATH Pci;
+ PCCARD_DEVICE_PATH PcCard;
+ MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;
+ CONTROLLER_DEVICE_PATH Controller;
+ ACPI_HID_DEVICE_PATH Acpi;
+
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ I2O_DEVICE_PATH I2O;
+ MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+
+ FILEPATH_DEVICE_PATH FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+
+ BBS_BBS_DEVICE_PATH Bbs;
+
+} EFI_DEV_PATH;
+
+typedef union {
+ EFI_DEVICE_PATH *DevPath;
+ PCI_DEVICE_PATH *Pci;
+ PCCARD_DEVICE_PATH *PcCard;
+ MEMMAP_DEVICE_PATH *MemMap;
+ VENDOR_DEVICE_PATH *Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor;
+ CONTROLLER_DEVICE_PATH *Controller;
+ ACPI_HID_DEVICE_PATH *Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
+
+ ATAPI_DEVICE_PATH *Atapi;
+ SCSI_DEVICE_PATH *Scsi;
+ FIBRECHANNEL_DEVICE_PATH *FibreChannel;
+
+ F1394_DEVICE_PATH *F1394;
+ USB_DEVICE_PATH *Usb;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ I2O_DEVICE_PATH *I2O;
+ MAC_ADDR_DEVICE_PATH *MacAddr;
+ IPv4_DEVICE_PATH *Ipv4;
+ IPv6_DEVICE_PATH *Ipv6;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+ UART_DEVICE_PATH *Uart;
+
+ HARDDRIVE_DEVICE_PATH *HardDrive;
+
+ FILEPATH_DEVICE_PATH *FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
+
+ CDROM_DEVICE_PATH *CD;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+} EFI_DEV_PATH_PTR;
+
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efierr.h b/usr/src/boot/sys/boot/efi/include/efierr.h
new file mode 100644
index 0000000000..a8b6557185
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efierr.h
@@ -0,0 +1,68 @@
+/* $FreeBSD$ */
+#ifndef _EFI_ERR_H
+#define _EFI_ERR_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efierr.h
+
+Abstract:
+
+ EFI error codes
+
+
+
+
+Revision History
+
+--*/
+
+
+#define EFIWARN(a) (a)
+#define EFI_ERROR(a) (((INTN) a) < 0)
+#define EFI_ERROR_CODE(a) (unsigned long)(a & ~EFI_ERROR_MASK)
+
+
+#define EFI_SUCCESS 0
+#define EFI_LOAD_ERROR EFIERR(1)
+#define EFI_INVALID_PARAMETER EFIERR(2)
+#define EFI_UNSUPPORTED EFIERR(3)
+#define EFI_BAD_BUFFER_SIZE EFIERR(4)
+#define EFI_BUFFER_TOO_SMALL EFIERR(5)
+#define EFI_NOT_READY EFIERR(6)
+#define EFI_DEVICE_ERROR EFIERR(7)
+#define EFI_WRITE_PROTECTED EFIERR(8)
+#define EFI_OUT_OF_RESOURCES EFIERR(9)
+#define EFI_VOLUME_CORRUPTED EFIERR(10)
+#define EFI_VOLUME_FULL EFIERR(11)
+#define EFI_NO_MEDIA EFIERR(12)
+#define EFI_MEDIA_CHANGED EFIERR(13)
+#define EFI_NOT_FOUND EFIERR(14)
+#define EFI_ACCESS_DENIED EFIERR(15)
+#define EFI_NO_RESPONSE EFIERR(16)
+#define EFI_NO_MAPPING EFIERR(17)
+#define EFI_TIMEOUT EFIERR(18)
+#define EFI_NOT_STARTED EFIERR(19)
+#define EFI_ALREADY_STARTED EFIERR(20)
+#define EFI_ABORTED EFIERR(21)
+#define EFI_ICMP_ERROR EFIERR(22)
+#define EFI_TFTP_ERROR EFIERR(23)
+#define EFI_PROTOCOL_ERROR EFIERR(24)
+
+#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1)
+#define EFI_WARN_DELETE_FAILURE EFIWARN(2)
+#define EFI_WARN_WRITE_FAILURE EFIWARN(3)
+#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4)
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efifpswa.h b/usr/src/boot/sys/boot/efi/include/efifpswa.h
new file mode 100644
index 0000000000..21823c5ff6
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efifpswa.h
@@ -0,0 +1,40 @@
+/* $FreeBSD$ */
+#ifndef _EFI_FPSWA_H
+#define _EFI_FPSWA_H
+
+/*
+ * EFI FP SWA Driver (Floating Point Software Assist)
+ */
+
+#define EFI_INTEL_FPSWA \
+ { 0xc41b6531, 0x97b9, 0x11d3, {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+INTERFACE_DECL(_FPSWA_INTERFACE);
+
+typedef struct _FPSWA_RET {
+ UINT64 status;
+ UINT64 err1;
+ UINT64 err2;
+ UINT64 err3;
+} FPSWA_RET;
+
+typedef
+FPSWA_RET
+(EFIAPI *EFI_FPSWA) (
+ IN UINTN TrapType,
+ IN OUT VOID *Bundle,
+ IN OUT UINT64 *pipsr,
+ IN OUT UINT64 *pfsr,
+ IN OUT UINT64 *pisr,
+ IN OUT UINT64 *ppreds,
+ IN OUT UINT64 *pifs,
+ IN OUT VOID *fp_state
+ );
+
+typedef struct _FPSWA_INTERFACE {
+ UINT32 Revision;
+ UINT32 Reserved;
+ EFI_FPSWA Fpswa;
+} FPSWA_INTERFACE;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efifs.h b/usr/src/boot/sys/boot/efi/include/efifs.h
new file mode 100644
index 0000000000..58febb66eb
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efifs.h
@@ -0,0 +1,123 @@
+/* $FreeBSD$ */
+#ifndef _EFI_FS_H
+#define _EFI_FS_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efifs.h
+
+Abstract:
+
+ EFI File System structures
+
+
+
+Revision History
+
+--*/
+
+
+//
+// EFI Partition header (normaly starts in LBA 1)
+//
+
+#define EFI_PARTITION_SIGNATURE 0x5053595320494249
+#define EFI_PARTITION_REVISION 0x00010001
+#define MIN_EFI_PARTITION_BLOCK_SIZE 512
+#define EFI_PARTITION_LBA 1
+
+typedef struct _EFI_PARTITION_HEADER {
+ EFI_TABLE_HEADER Hdr;
+ UINT32 DirectoryAllocationNumber;
+ UINT32 BlockSize;
+ EFI_LBA FirstUsableLba;
+ EFI_LBA LastUsableLba;
+ EFI_LBA UnusableSpace;
+ EFI_LBA FreeSpace;
+ EFI_LBA RootFile;
+ EFI_LBA SecutiryFile;
+} EFI_PARTITION_HEADER;
+
+
+//
+// File header
+//
+
+#define EFI_FILE_HEADER_SIGNATURE 0x454c494620494249
+#define EFI_FILE_HEADER_REVISION 0x00010000
+#define EFI_FILE_STRING_SIZE 260
+
+typedef struct _EFI_FILE_HEADER {
+ EFI_TABLE_HEADER Hdr;
+ UINT32 Class;
+ UINT32 LBALOffset;
+ EFI_LBA Parent;
+ UINT64 FileSize;
+ UINT64 FileAttributes;
+ EFI_TIME FileCreateTime;
+ EFI_TIME FileModificationTime;
+ EFI_GUID VendorGuid;
+ CHAR16 FileString[EFI_FILE_STRING_SIZE];
+} EFI_FILE_HEADER;
+
+
+//
+// Return the file's first LBAL which is in the same
+// logical block as the file header
+//
+
+#define EFI_FILE_LBAL(a) ((EFI_LBAL *) (((CHAR8 *) (a)) + (a)->LBALOffset))
+
+#define EFI_FILE_CLASS_FREE_SPACE 1
+#define EFI_FILE_CLASS_EMPTY 2
+#define EFI_FILE_CLASS_NORMAL 3
+
+
+//
+// Logical Block Address List - the fundemental block
+// description structure
+//
+
+#define EFI_LBAL_SIGNATURE 0x4c41424c20494249
+#define EFI_LBAL_REVISION 0x00010000
+
+typedef struct _EFI_LBAL {
+ EFI_TABLE_HEADER Hdr;
+ UINT32 Class;
+ EFI_LBA Parent;
+ EFI_LBA Next;
+ UINT32 ArraySize;
+ UINT32 ArrayCount;
+} EFI_LBAL;
+
+// Array size
+#define EFI_LBAL_ARRAY_SIZE(lbal,offs,blks) \
+ (((blks) - (offs) - (lbal)->Hdr.HeaderSize) / sizeof(EFI_RL))
+
+//
+// Logical Block run-length
+//
+
+typedef struct {
+ EFI_LBA Start;
+ UINT64 Length;
+} EFI_RL;
+
+//
+// Return the run-length structure from an LBAL header
+//
+
+#define EFI_LBAL_RL(a) ((EFI_RL*) (((CHAR8 *) (a)) + (a)->Hdr.HeaderSize))
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efigop.h b/usr/src/boot/sys/boot/efi/include/efigop.h
new file mode 100644
index 0000000000..104fa6e44b
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efigop.h
@@ -0,0 +1,121 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efigop.h
+
+Abstract:
+ Info about framebuffers
+
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFIGOP_H
+#define _EFIGOP_H
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a} }
+
+INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT);
+
+typedef struct {
+ UINT32 RedMask;
+ UINT32 GreenMask;
+ UINT32 BlueMask;
+ UINT32 ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef enum {
+ PixelRedGreenBlueReserved8BitPerColor,
+ PixelBlueGreenRedReserved8BitPerColor,
+ PixelBitMask,
+ PixelBltOnly,
+ PixelFormatMax,
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+ UINT32 Version;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ UINT32 PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+typedef struct {
+ UINT32 MaxMode;
+ UINT32 Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber
+ );
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef enum {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphcisOutputBltOperationMax,
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ );
+
+typedef struct _EFI_GRAPHICS_OUTPUT {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
+} EFI_GRAPHICS_OUTPUT;
+
+#endif /* _EFIGOP_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efigpt.h b/usr/src/boot/sys/boot/efi/include/efigpt.h
new file mode 100644
index 0000000000..ac90a304f7
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efigpt.h
@@ -0,0 +1,68 @@
+#ifndef _EFI_GPT_H
+#define _EFI_GPT_H
+/*++
+
+Copyright (c) 1998 Intel Corporation
+
+Module Name:
+
+ EfiGpt.h
+
+Abstract:
+ Include file for EFI partitioning scheme
+
+
+
+Revision History
+
+--*/
+
+#define PRIMARY_PART_HEADER_LBA 1
+
+typedef struct {
+ EFI_TABLE_HEADER Header;
+ EFI_LBA MyLBA;
+ EFI_LBA AlternateLBA;
+ EFI_LBA FirstUsableLBA;
+ EFI_LBA LastUsableLBA;
+ EFI_GUID DiskGUID;
+ EFI_LBA PartitionEntryLBA;
+ UINT32 NumberOfPartitionEntries;
+ UINT32 SizeOfPartitionEntry;
+ UINT32 PartitionEntryArrayCRC32;
+} EFI_PARTITION_TABLE_HEADER;
+
+#define EFI_PTAB_HEADER_ID "EFI PART"
+
+typedef struct {
+ EFI_GUID PartitionTypeGUID;
+ EFI_GUID UniquePartitionGUID;
+ EFI_LBA StartingLBA;
+ EFI_LBA EndingLBA;
+ UINT64 Attributes;
+ CHAR16 PartitionName[36];
+} EFI_PARTITION_ENTRY;
+
+//
+// EFI Partition Attributes
+//
+#define EFI_PART_USED_BY_EFI 0x0000000000000001
+#define EFI_PART_REQUIRED_TO_FUNCTION 0x0000000000000002
+#define EFI_PART_USED_BY_OS 0x0000000000000004
+#define EFI_PART_REQUIRED_BY_OS 0x0000000000000008
+#define EFI_PART_BACKUP_REQUIRED 0x0000000000000010
+#define EFI_PART_USER_DATA 0x0000000000000020
+#define EFI_PART_CRITICAL_USER_DATA 0x0000000000000040
+#define EFI_PART_REDUNDANT_PARTITION 0x0000000000000080
+
+#define EFI_PART_TYPE_UNUSED_GUID \
+ { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
+
+#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \
+ { 0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }
+
+#define EFI_PART_TYPE_LEGACY_MBR_GUID \
+ { 0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f} }
+
+#endif
+
diff --git a/usr/src/boot/sys/boot/efi/include/efiip.h b/usr/src/boot/sys/boot/efi/include/efiip.h
new file mode 100644
index 0000000000..839507964f
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiip.h
@@ -0,0 +1,459 @@
+#ifndef _EFI_IP_H
+#define _EFI_IP_H
+
+/*++
+Copyright (c) 2013 Intel Corporation
+
+--*/
+
+#define EFI_IP4_SERVICE_BINDING_PROTOCOL \
+ {0xc51711e7,0xb4bf,0x404a,{0xbf,0xb8,0x0a,0x04, 0x8e,0xf1,0xff,0xe4}}
+
+#define EFI_IP4_PROTOCOL \
+ {0x41d94cd2,0x35b6,0x455a,{0x82,0x58,0xd4,0xe5,0x13,0x34,0xaa,0xdd}}
+
+#define EFI_IP6_SERVICE_BINDING_PROTOCOL \
+ {0xec835dd3,0xfe0f,0x617b,{0xa6,0x21,0xb3,0x50,0xc3,0xe1,0x33,0x88}}
+
+#define EFI_IP6_PROTOCOL \
+ {0x2c8759d5,0x5c2d,0x66ef,{0x92,0x5f,0xb6,0x6c,0x10,0x19,0x57,0xe2}}
+
+INTERFACE_DECL(_EFI_IP4);
+INTERFACE_DECL(_EFI_IP6);
+
+typedef struct {
+ EFI_HANDLE InstanceHandle;
+ EFI_IPv4_ADDRESS Ip4Address;
+ EFI_IPv4_ADDRESS SubnetMask;
+} EFI_IP4_ADDRESS_PAIR;
+
+typedef struct {
+ EFI_HANDLE DriverHandle;
+ UINT32 AddressCount;
+ EFI_IP4_ADDRESS_PAIR AddressPairs[1];
+} EFI_IP4_VARIABLE_DATA;
+
+typedef struct {
+ UINT8 DefaultProtocol;
+ BOOLEAN AcceptAnyProtocol;
+ BOOLEAN AcceptIcmpErrors;
+ BOOLEAN AcceptBroadcast;
+ BOOLEAN AcceptPromiscuous;
+ BOOLEAN UseDefaultAddress;
+ EFI_IPv4_ADDRESS StationAddress;
+ EFI_IPv4_ADDRESS SubnetMask;
+ UINT8 TypeOfService;
+ UINT8 TimeToLive;
+ BOOLEAN DoNotFragment;
+ BOOLEAN RawData;
+ UINT32 ReceiveTimeout;
+ UINT32 TransmitTimeout;
+} EFI_IP4_CONFIG_DATA;
+
+typedef struct {
+ EFI_IPv4_ADDRESS SubnetAddress;
+ EFI_IPv4_ADDRESS SubnetMask;
+ EFI_IPv4_ADDRESS GatewayAddress;
+} EFI_IP4_ROUTE_TABLE;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Code;
+} EFI_IP4_ICMP_TYPE;
+
+typedef struct {
+ BOOLEAN IsStarted;
+ UINT32 MaxPacketSize;
+ EFI_IP4_CONFIG_DATA ConfigData;
+ BOOLEAN IsConfigured;
+ UINT32 GroupCount;
+ EFI_IPv4_ADDRESS *GroupTable;
+ UINT32 RouteCount;
+ EFI_IP4_ROUTE_TABLE *RouteTable;
+ UINT32 IcmpTypeCount;
+ EFI_IP4_ICMP_TYPE *IcmpTypeList;
+} EFI_IP4_MODE_DATA;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_GET_MODE_DATA) (
+ IN struct _EFI_IP4 *This,
+ OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CONFIGURE) (
+ IN struct _EFI_IP4 *This,
+ IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_GROUPS) (
+ IN struct _EFI_IP4 *This,
+ IN BOOLEAN JoinFlag,
+ IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_ROUTES) (
+ IN struct _EFI_IP4 *This,
+ IN BOOLEAN DeleteRoute,
+ IN EFI_IPv4_ADDRESS *SubnetAddress,
+ IN EFI_IPv4_ADDRESS *SubnetMask,
+ IN EFI_IPv4_ADDRESS *GatewayAddress
+ );
+
+#pragma pack(1)
+typedef struct {
+ UINT8 HeaderLength:4;
+ UINT8 Version:4;
+ UINT8 TypeOfService;
+ UINT16 TotalLength;
+ UINT16 Identification;
+ UINT16 Fragmentation;
+ UINT8 TimeToLive;
+ UINT8 Protocol;
+ UINT16 Checksum;
+ EFI_IPv4_ADDRESS SourceAddress;
+ EFI_IPv4_ADDRESS DestinationAddress;
+} EFI_IP4_HEADER;
+#pragma pack()
+
+typedef struct {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_IP4_FRAGMENT_DATA;
+
+typedef struct {
+ EFI_TIME TimeStamp;
+ EFI_EVENT RecycleSignal;
+ UINT32 HeaderLength;
+ EFI_IP4_HEADER *Header;
+ UINT32 OptionsLength;
+ VOID *Options;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_IP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_IP4_RECEIVE_DATA;
+
+typedef struct {
+ EFI_IPv4_ADDRESS SourceAddress;
+ EFI_IPv4_ADDRESS GatewayAddress;
+ UINT8 Protocol;
+ UINT8 TypeOfService;
+ UINT8 TimeToLive;
+ BOOLEAN DoNotFragment;
+} EFI_IP4_OVERRIDE_DATA;
+
+typedef struct {
+ EFI_IPv4_ADDRESS DestinationAddress;
+ EFI_IP4_OVERRIDE_DATA *OverrideData;
+ UINT32 OptionsLength;
+ VOID *OptionsBuffer;
+ UINT32 TotalDataLength;
+ UINT32 FragmentCount;
+ EFI_IP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_IP4_TRANSMIT_DATA;
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ union {
+ EFI_IP4_RECEIVE_DATA *RxData;
+ EFI_IP4_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_IP4_COMPLETION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_TRANSMIT) (
+ IN struct _EFI_IP4 *This,
+ IN EFI_IP4_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_RECEIVE) (
+ IN struct _EFI_IP4 *This,
+ IN EFI_IP4_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CANCEL)(
+ IN struct _EFI_IP4 *This,
+ IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_POLL) (
+ IN struct _EFI_IP4 *This
+ );
+
+typedef struct _EFI_IP4 {
+ EFI_IP4_GET_MODE_DATA GetModeData;
+ EFI_IP4_CONFIGURE Configure;
+ EFI_IP4_GROUPS Groups;
+ EFI_IP4_ROUTES Routes;
+ EFI_IP4_TRANSMIT Transmit;
+ EFI_IP4_RECEIVE Receive;
+ EFI_IP4_CANCEL Cancel;
+ EFI_IP4_POLL Poll;
+} EFI_IP4;
+
+typedef struct {
+ UINT8 DefaultProtocol;
+ BOOLEAN AcceptAnyProtocol;
+ BOOLEAN AcceptIcmpErrors;
+ BOOLEAN AcceptPromiscuous;
+ EFI_IPv6_ADDRESS DestinationAddress;
+ EFI_IPv6_ADDRESS StationAddress;
+ UINT8 TrafficClass;
+ UINT8 HopLimit;
+ UINT32 FlowLabel;
+ UINT32 ReceiveTimeout;
+ UINT32 TransmitTimeout;
+} EFI_IP6_CONFIG_DATA;
+
+typedef struct {
+ EFI_IPv6_ADDRESS Address;
+ UINT8 PrefixLength;
+} EFI_IP6_ADDRESS_INFO;
+
+typedef struct {
+ EFI_IPv6_ADDRESS Gateway;
+ EFI_IPv6_ADDRESS Destination;
+ UINT8 PrefixLength;
+} EFI_IP6_ROUTE_TABLE;
+
+typedef enum {
+ EfiNeighborInComplete,
+ EfiNeighborReachable,
+ EfiNeighborStale,
+ EfiNeighborDelay,
+ EfiNeighborProbe
+} EFI_IP6_NEIGHBOR_STATE;
+
+typedef struct {
+ EFI_IPv6_ADDRESS Neighbor;
+ EFI_MAC_ADDRESS LinkAddress;
+ EFI_IP6_NEIGHBOR_STATE State;
+} EFI_IP6_NEIGHBOR_CACHE;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Code;
+} EFI_IP6_ICMP_TYPE;
+
+//***********************************************************
+// ICMPv6 type definitions for error messages
+//***********************************************************
+#define ICMP_V6_DEST_UNREACHABLE 0x1
+#define ICMP_V6_PACKET_TOO_BIG 0x2
+#define ICMP_V6_TIME_EXCEEDED 0x3
+#define ICMP_V6_PARAMETER_PROBLEM 0x4
+
+//***********************************************************
+// ICMPv6 type definition for informational messages
+//***********************************************************
+#define ICMP_V6_ECHO_REQUEST 0x80
+#define ICMP_V6_ECHO_REPLY 0x81
+#define ICMP_V6_LISTENER_QUERY 0x82
+#define ICMP_V6_LISTENER_REPORT 0x83
+#define ICMP_V6_LISTENER_DONE 0x84
+#define ICMP_V6_ROUTER_SOLICIT 0x85
+#define ICMP_V6_ROUTER_ADVERTISE 0x86
+#define ICMP_V6_NEIGHBOR_SOLICIT 0x87
+#define ICMP_V6_NEIGHBOR_ADVERTISE 0x88
+#define ICMP_V6_REDIRECT 0x89
+#define ICMP_V6_LISTENER_REPORT_2 0x8F
+
+//***********************************************************
+// ICMPv6 code definitions for ICMP_V6_DEST_UNREACHABLE
+//***********************************************************
+#define ICMP_V6_NO_ROUTE_TO_DEST 0x0
+#define ICMP_V6_COMM_PROHIBITED 0x1
+#define ICMP_V6_BEYOND_SCOPE 0x2
+#define ICMP_V6_ADDR_UNREACHABLE 0x3
+#define ICMP_V6_PORT_UNREACHABLE 0x4
+#define ICMP_V6_SOURCE_ADDR_FAILED 0x5
+#define ICMP_V6_ROUTE_REJECTED 0x6
+
+//***********************************************************
+// ICMPv6 code definitions for ICMP_V6_TIME_EXCEEDED
+//***********************************************************
+#define ICMP_V6_TIMEOUT_HOP_LIMIT 0x0
+#define ICMP_V6_TIMEOUT_REASSEMBLE 0x1
+
+//***********************************************************
+// ICMPv6 code definitions for ICMP_V6_PARAMETER_PROBLEM
+//***********************************************************
+#define ICMP_V6_ERRONEOUS_HEADER 0x0
+#define ICMP_V6_UNRECOGNIZE_NEXT_HDR 0x1
+#define ICMP_V6_UNRECOGNIZE_OPTION 0x2
+
+typedef struct {
+ BOOLEAN IsStarted;
+ UINT32 MaxPacketSize;
+ EFI_IP6_CONFIG_DATA ConfigData;
+ BOOLEAN IsConfigured;
+ UINT32 AddressCount;
+ EFI_IP6_ADDRESS_INFO *AddressList;
+ UINT32 GroupCount;
+ EFI_IPv6_ADDRESS *GroupTable;
+ UINT32 RouteCount;
+ EFI_IP6_ROUTE_TABLE *RouteTable;
+ UINT32 NeighborCount;
+ EFI_IP6_NEIGHBOR_CACHE *NeighborCache;
+ UINT32 PrefixCount;
+ EFI_IP6_ADDRESS_INFO *PrefixTable;
+ UINT32 IcmpTypeCount;
+ EFI_IP6_ICMP_TYPE *IcmpTypeList;
+} EFI_IP6_MODE_DATA;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_GET_MODE_DATA) (
+ IN struct _EFI_IP6 *This,
+ OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIGURE) (
+ IN struct _EFI_IP6 *This,
+ IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL
+ );
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_GROUPS) (
+ IN struct _EFI_IP6 *This,
+ IN BOOLEAN JoinFlag,
+ IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_ROUTES) (
+ IN struct _EFI_IP6 *This,
+ IN BOOLEAN DeleteRoute,
+ IN EFI_IPv6_ADDRESS *Destination OPTIONAL,
+ IN UINT8 PrefixLength,
+ IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_NEIGHBORS) (
+ IN struct _EFI_IP6 *This,
+ IN BOOLEAN DeleteFlag,
+ IN EFI_IPv6_ADDRESS *TargetIp6Address,
+ IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL,
+ IN UINT32 Timeout,
+ IN BOOLEAN Override
+ );
+
+typedef struct _EFI_IP6_FRAGMENT_DATA {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_IP6_FRAGMENT_DATA;
+
+typedef struct _EFI_IP6_OVERRIDE_DATA {
+ UINT8 Protocol;
+ UINT8 HopLimit;
+ UINT32 FlowLabel;
+} EFI_IP6_OVERRIDE_DATA;
+
+typedef struct _EFI_IP6_TRANSMIT_DATA {
+ EFI_IPv6_ADDRESS DestinationAddress;
+ EFI_IP6_OVERRIDE_DATA *OverrideData;
+ UINT32 ExtHdrsLength;
+ VOID *ExtHdrs;
+ UINT8 NextHeader;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_IP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_IP6_TRANSMIT_DATA;
+
+#pragma pack(1)
+typedef struct _EFI_IP6_HEADER {
+ UINT8 TrafficClassH:4;
+ UINT8 Version:4;
+ UINT8 FlowLabelH:4;
+ UINT8 TrafficClassL:4;
+ UINT16 FlowLabelL;
+ UINT16 PayloadLength;
+ UINT8 NextHeader;
+ UINT8 HopLimit;
+ EFI_IPv6_ADDRESS SourceAddress;
+ EFI_IPv6_ADDRESS DestinationAddress;
+} EFI_IP6_HEADER;
+#pragma pack()
+
+typedef struct _EFI_IP6_RECEIVE_DATA {
+ EFI_TIME TimeStamp;
+ EFI_EVENT RecycleSignal;
+ UINT32 HeaderLength;
+ EFI_IP6_HEADER *Header;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_IP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_IP6_RECEIVE_DATA;
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ union {
+ EFI_IP6_RECEIVE_DATA *RxData;
+ EFI_IP6_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_IP6_COMPLETION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_TRANSMIT) (
+ IN struct _EFI_IP6 *This,
+ IN EFI_IP6_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_RECEIVE) (
+ IN struct _EFI_IP6 *This,
+ IN EFI_IP6_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CANCEL)(
+ IN struct _EFI_IP6 *This,
+ IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_POLL) (
+ IN struct _EFI_IP6 *This
+ );
+
+typedef struct _EFI_IP6 {
+ EFI_IP6_GET_MODE_DATA GetModeData;
+ EFI_IP6_CONFIGURE Configure;
+ EFI_IP6_GROUPS Groups;
+ EFI_IP6_ROUTES Routes;
+ EFI_IP6_NEIGHBORS Neighbors;
+ EFI_IP6_TRANSMIT Transmit;
+ EFI_IP6_RECEIVE Receive;
+ EFI_IP6_CANCEL Cancel;
+ EFI_IP6_POLL Poll;
+} EFI_IP6;
+
+#endif /* _EFI_IP_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efilib.h b/usr/src/boot/sys/boot/efi/include/efilib.h
new file mode 100644
index 0000000000..53c44a90b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efilib.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stand.h>
+
+extern EFI_HANDLE IH;
+extern EFI_SYSTEM_TABLE *ST;
+extern EFI_BOOT_SERVICES *BS;
+extern EFI_RUNTIME_SERVICES *RS;
+
+extern struct devsw efipart_dev;
+extern struct devsw efinet_dev;
+extern struct netif_driver efinetif;
+
+void *efi_get_table(EFI_GUID *tbl);
+
+int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
+EFI_HANDLE efi_find_handle(struct devsw *, int);
+int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *);
+int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t);
+
+int efi_status_to_errno(EFI_STATUS);
+
+EFI_STATUS main(int argc, CHAR16 *argv[]);
+void exit(EFI_STATUS status);
diff --git a/usr/src/boot/sys/boot/efi/include/efinet.h b/usr/src/boot/sys/boot/efi/include/efinet.h
new file mode 100644
index 0000000000..3ac58b2431
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efinet.h
@@ -0,0 +1,348 @@
+/* $FreeBSD$ */
+#ifndef _EFINET_H
+#define _EFINET_H
+
+
+/*++
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+ efinet.h
+
+Abstract:
+ EFI Simple Network protocol
+
+Revision History
+--*/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Simple Network Protocol
+//
+
+#define EFI_SIMPLE_NETWORK_PROTOCOL \
+ { 0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} }
+
+
+INTERFACE_DECL(_EFI_SIMPLE_NETWORK);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef struct {
+ //
+ // Total number of frames received. Includes frames with errors and
+ // dropped frames.
+ //
+ UINT64 RxTotalFrames;
+
+ //
+ // Number of valid frames received and copied into receive buffers.
+ //
+ UINT64 RxGoodFrames;
+
+ //
+ // Number of frames below the minimum length for the media.
+ // This would be <64 for ethernet.
+ //
+ UINT64 RxUndersizeFrames;
+
+ //
+ // Number of frames longer than the maxminum length for the
+ // media. This would be >1500 for ethernet.
+ //
+ UINT64 RxOversizeFrames;
+
+ //
+ // Valid frames that were dropped because receive buffers were full.
+ //
+ UINT64 RxDroppedFrames;
+
+ //
+ // Number of valid unicast frames received and not dropped.
+ //
+ UINT64 RxUnicastFrames;
+
+ //
+ // Number of valid broadcast frames received and not dropped.
+ //
+ UINT64 RxBroadcastFrames;
+
+ //
+ // Number of valid mutlicast frames received and not dropped.
+ //
+ UINT64 RxMulticastFrames;
+
+ //
+ // Number of frames w/ CRC or alignment errors.
+ //
+ UINT64 RxCrcErrorFrames;
+
+ //
+ // Total number of bytes received. Includes frames with errors
+ // and dropped frames.
+ //
+ UINT64 RxTotalBytes;
+
+ //
+ // Transmit statistics.
+ //
+ UINT64 TxTotalFrames;
+ UINT64 TxGoodFrames;
+ UINT64 TxUndersizeFrames;
+ UINT64 TxOversizeFrames;
+ UINT64 TxDroppedFrames;
+ UINT64 TxUnicastFrames;
+ UINT64 TxBroadcastFrames;
+ UINT64 TxMulticastFrames;
+ UINT64 TxCrcErrorFrames;
+ UINT64 TxTotalBytes;
+
+ //
+ // Number of collisions detection on this subnet.
+ //
+ UINT64 Collisions;
+
+ //
+ // Number of frames destined for unsupported protocol.
+ //
+ UINT64 UnsupportedProtocol;
+
+} EFI_NETWORK_STATISTICS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef enum {
+ EfiSimpleNetworkStopped,
+ EfiSimpleNetworkStarted,
+ EfiSimpleNetworkInitialized,
+ EfiSimpleNetworkMaxState
+} EFI_SIMPLE_NETWORK_STATE;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
+#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
+#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01
+#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02
+#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04
+#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08
+
+///////////////////////////////////////////////////////////////////////////////
+//
+#define MAX_MCAST_FILTER_CNT 16
+typedef struct {
+ UINT32 State;
+ UINT32 HwAddressSize;
+ UINT32 MediaHeaderSize;
+ UINT32 MaxPacketSize;
+ UINT32 NvRamSize;
+ UINT32 NvRamAccessSize;
+ UINT32 ReceiveFilterMask;
+ UINT32 ReceiveFilterSetting;
+ UINT32 MaxMCastFilterCount;
+ UINT32 MCastFilterCount;
+ EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT];
+ EFI_MAC_ADDRESS CurrentAddress;
+ EFI_MAC_ADDRESS BroadcastAddress;
+ EFI_MAC_ADDRESS PermanentAddress;
+ UINT8 IfType;
+ BOOLEAN MacAddressChangeable;
+ BOOLEAN MultipleTxSupported;
+ BOOLEAN MediaPresentSupported;
+ BOOLEAN MediaPresent;
+} EFI_SIMPLE_NETWORK_MODE;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_START) (
+ IN struct _EFI_SIMPLE_NETWORK *This
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_STOP) (
+ IN struct _EFI_SIMPLE_NETWORK *This
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_RESET) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) (
+ IN struct _EFI_SIMPLE_NETWORK *This
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN UINT32 Enable,
+ IN UINT32 Disable,
+ IN BOOLEAN ResetMCastFilter,
+ IN UINTN MCastFilterCnt OPTIONAL,
+ IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS *New OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN BOOLEAN Reset,
+ IN OUT UINTN *StatisticsSize OPTIONAL,
+ OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN BOOLEAN IPv6,
+ IN EFI_IP_ADDRESS *IP,
+ OUT EFI_MAC_ADDRESS *MAC
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN BOOLEAN ReadWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ OUT UINT32 *InterruptStatus OPTIONAL,
+ OUT VOID **TxBuf OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ IN UINTN HeaderSize,
+ IN UINTN BufferSize,
+ IN VOID *Buffer,
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ IN UINT16 *Protocol OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) (
+ IN struct _EFI_SIMPLE_NETWORK *This,
+ OUT UINTN *HeaderSize OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer,
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+
+#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION 0x00010000
+
+typedef struct _EFI_SIMPLE_NETWORK {
+ UINT64 Revision;
+ EFI_SIMPLE_NETWORK_START Start;
+ EFI_SIMPLE_NETWORK_STOP Stop;
+ EFI_SIMPLE_NETWORK_INITIALIZE Initialize;
+ EFI_SIMPLE_NETWORK_RESET Reset;
+ EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown;
+ EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters;
+ EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress;
+ EFI_SIMPLE_NETWORK_STATISTICS Statistics;
+ EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac;
+ EFI_SIMPLE_NETWORK_NVDATA NvData;
+ EFI_SIMPLE_NETWORK_GET_STATUS GetStatus;
+ EFI_SIMPLE_NETWORK_TRANSMIT Transmit;
+ EFI_SIMPLE_NETWORK_RECEIVE Receive;
+ EFI_EVENT WaitForPacket;
+ EFI_SIMPLE_NETWORK_MODE *Mode;
+} EFI_SIMPLE_NETWORK;
+
+#endif /* _EFINET_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efipart.h b/usr/src/boot/sys/boot/efi/include/efipart.h
new file mode 100644
index 0000000000..ef1a8709d9
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efipart.h
@@ -0,0 +1,69 @@
+/* $FreeBSD$ */
+#ifndef _EFI_PART_H
+#define _EFI_PART_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efipart.h
+
+Abstract:
+ Info about disk partitions and Master Boot Records
+
+
+
+
+Revision History
+
+--*/
+
+//
+//
+//
+
+#define EFI_PARTITION 0xef
+#define MBR_SIZE 512
+
+#pragma pack(1)
+
+typedef struct {
+ UINT8 BootIndicator;
+ UINT8 StartHead;
+ UINT8 StartSector;
+ UINT8 StartTrack;
+ UINT8 OSIndicator;
+ UINT8 EndHead;
+ UINT8 EndSector;
+ UINT8 EndTrack;
+ UINT8 StartingLBA[4];
+ UINT8 SizeInLBA[4];
+} MBR_PARTITION_RECORD;
+
+#define EXTRACT_UINT32(D) (UINT32)(D[0] | (D[1] << 8) | (D[2] << 16) | (D[3] << 24))
+
+#define MBR_SIGNATURE 0xaa55
+#define MIN_MBR_DEVICE_SIZE 0x80000
+#define MBR_ERRATA_PAD 0x40000 // 128 MB
+
+#define MAX_MBR_PARTITIONS 4
+typedef struct {
+ UINT8 BootStrapCode[440];
+ UINT8 UniqueMbrSignature[4];
+ UINT8 Unknown[2];
+ MBR_PARTITION_RECORD Partition[MAX_MBR_PARTITIONS];
+ UINT16 Signature;
+} MASTER_BOOT_RECORD;
+#pragma pack()
+
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efipciio.h b/usr/src/boot/sys/boot/efi/include/efipciio.h
new file mode 100644
index 0000000000..b42fa59395
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efipciio.h
@@ -0,0 +1,560 @@
+/* $FreeBSD$ */
+/** @file
+ EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration,
+ and DMA interfaces that a driver uses to access its PCI controller.
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PCI_IO_H__
+#define __PCI_IO_H__
+
+#define EFI_PCI_ROOT_IO_GUID \
+ { 0x2F707EBB, 0x4A1A, 0x11d4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
+
+///
+/// Global ID for the PCI I/O Protocol
+///
+#define EFI_PCI_IO_PROTOCOL_GUID \
+ { 0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a} }
+
+typedef struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL;
+
+///
+/// *******************************************************
+/// EFI_PCI_IO_PROTOCOL_WIDTH
+/// *******************************************************
+///
+typedef enum {
+ EfiPciIoWidthUint8 = 0,
+ EfiPciIoWidthUint16,
+ EfiPciIoWidthUint32,
+ EfiPciIoWidthUint64,
+ EfiPciIoWidthFifoUint8,
+ EfiPciIoWidthFifoUint16,
+ EfiPciIoWidthFifoUint32,
+ EfiPciIoWidthFifoUint64,
+ EfiPciIoWidthFillUint8,
+ EfiPciIoWidthFillUint16,
+ EfiPciIoWidthFillUint32,
+ EfiPciIoWidthFillUint64,
+ EfiPciIoWidthMaximum
+} EFI_PCI_IO_PROTOCOL_WIDTH;
+
+//
+// Complete PCI address generater
+//
+#define EFI_PCI_IO_PASS_THROUGH_BAR 0xff ///< Special BAR that passes a memory or I/O cycle through unchanged
+#define EFI_PCI_IO_ATTRIBUTE_MASK 0x077f ///< All the following I/O and Memory cycles
+#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 ///< I/O cycles 0x0000-0x00FF (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002 ///< I/O cycles 0x0100-0x03FF or greater (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008 ///< MEM cycles 0xA0000-0xBFFFF (24 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 ///< I/O cycles 0x1F0-0x1F7, 0x3F6, 0x3F7 (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 ///< I/O cycles 0x170-0x177, 0x376, 0x377 (10 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 ///< Map a memory range so writes are combined
+#define EFI_PCI_IO_ATTRIBUTE_IO 0x0100 ///< Enable the I/O decode bit in the PCI Config Header
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200 ///< Enable the Memory decode bit in the PCI Config Header
+#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400 ///< Enable the DMA bit in the PCI Config Header
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800 ///< Map a memory range so all r/w accesses are cached
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 ///< Clear for an add-in PCI Device
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000 ///< Clear for a physical PCI Option ROM accessed through ROM BAR
+#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 ///< Clear for PCI controllers that can not genrate a DAC
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000 ///< I/O cycles 0x0100-0x03FF or greater (16 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (16 bit decode)
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode)
+
+#define EFI_PCI_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)
+#define EFI_VGA_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_IO)
+
+///
+/// *******************************************************
+/// EFI_PCI_IO_PROTOCOL_OPERATION
+/// *******************************************************
+///
+typedef enum {
+ ///
+ /// A read operation from system memory by a bus master.
+ ///
+ EfiPciIoOperationBusMasterRead,
+ ///
+ /// A write operation from system memory by a bus master.
+ ///
+ EfiPciIoOperationBusMasterWrite,
+ ///
+ /// Provides both read and write access to system memory by both the processor and a
+ /// bus master. The buffer is coherent from both the processor's and the bus master's point of view.
+ ///
+ EfiPciIoOperationBusMasterCommonBuffer,
+ EfiPciIoOperationMaximum
+} EFI_PCI_IO_PROTOCOL_OPERATION;
+
+///
+/// *******************************************************
+/// EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION
+/// *******************************************************
+///
+typedef enum {
+ ///
+ /// Retrieve the PCI controller's current attributes, and return them in Result.
+ ///
+ EfiPciIoAttributeOperationGet,
+ ///
+ /// Set the PCI controller's current attributes to Attributes.
+ ///
+ EfiPciIoAttributeOperationSet,
+ ///
+ /// Enable the attributes specified by the bits that are set in Attributes for this PCI controller.
+ ///
+ EfiPciIoAttributeOperationEnable,
+ ///
+ /// Disable the attributes specified by the bits that are set in Attributes for this PCI controller.
+ ///
+ EfiPciIoAttributeOperationDisable,
+ ///
+ /// Retrieve the PCI controller's supported attributes, and return them in Result.
+ ///
+ EfiPciIoAttributeOperationSupported,
+ EfiPciIoAttributeOperationMaximum
+} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;
+
+/**
+ Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is
+ satisfied or after a defined duration.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Width Signifies the width of the memory or I/O operations.
+ @param BarIndex The BAR index of the standard PCI Configuration header to use as the
+ base address for the memory operation to perform.
+ @param Offset The offset within the selected BAR to start the memory operation.
+ @param Mask Mask used for the polling criteria.
+ @param Value The comparison value used for the polling exit criteria.
+ @param Delay The number of 100 ns units to poll.
+ @param Result Pointer to the last value read from the memory location.
+
+ @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
+ @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller.
+ @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller.
+ @retval EFI_TIMEOUT Delay expired before a match occurred.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+/**
+ Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Width Signifies the width of the memory or I/O operations.
+ @param BarIndex The BAR index of the standard PCI Configuration header to use as the
+ base address for the memory or I/O operation to perform.
+ @param Offset The offset within the selected BAR to start the memory or I/O operation.
+ @param Count The number of memory or I/O operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI controller.
+ @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller.
+ @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
+ valid for the PCI BAR specified by BarIndex.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+typedef struct {
+ ///
+ /// Read PCI controller registers in the PCI memory or I/O space.
+ ///
+ EFI_PCI_IO_PROTOCOL_IO_MEM Read;
+ ///
+ /// Write PCI controller registers in the PCI memory or I/O space.
+ ///
+ EFI_PCI_IO_PROTOCOL_IO_MEM Write;
+} EFI_PCI_IO_PROTOCOL_ACCESS;
+
+/**
+ Enable a PCI driver to access PCI controller registers in PCI configuration space.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Width Signifies the width of the memory operations.
+ @param Offset The offset within the PCI configuration space for the PCI controller.
+ @param Count The number of PCI configuration operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI controller.
+ @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
+ valid for the PCI configuration header of the PCI controller.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+typedef struct {
+ ///
+ /// Read PCI controller registers in PCI configuration space.
+ ///
+ EFI_PCI_IO_PROTOCOL_CONFIG Read;
+ ///
+ /// Write PCI controller registers in PCI configuration space.
+ ///
+ EFI_PCI_IO_PROTOCOL_CONFIG Write;
+} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS;
+
+/**
+ Enables a PCI driver to copy one region of PCI memory space to another region of PCI
+ memory space.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Width Signifies the width of the memory operations.
+ @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the
+ base address for the memory operation to perform.
+ @param DestOffset The destination offset within the BAR specified by DestBarIndex to
+ start the memory writes for the copy operation.
+ @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the
+ base address for the memory operation to perform.
+ @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start
+ the memory reads for the copy operation.
+ @param Count The number of memory operations to perform. Bytes moved is Width
+ size * Count, starting at DestOffset and SrcOffset.
+
+ @retval EFI_SUCCESS The data was copied from one memory region to another memory region.
+ @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller.
+ @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller.
+ @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count
+ is not valid for the PCI BAR specified by DestBarIndex.
+ @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is
+ not valid for the PCI BAR specified by SrcBarIndex.
+ @retval EFI_INVALID_PARAMETER Width is invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count
+ );
+
+/**
+ Provides the PCI controller-specific addresses needed to access system memory.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the PCI controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_MAP)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer
+ mapping.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Type This parameter is not used and must be ignored.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ );
+
+/**
+ Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host
+ bridge to system memory.
+ @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI
+ host bridge due to a hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH)(
+ IN EFI_PCI_IO_PROTOCOL *This
+ );
+
+/**
+ Retrieves this PCI controller's current PCI bus number, device number, and function number.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param SegmentNumber The PCI controller's current PCI segment number.
+ @param BusNumber The PCI controller's current PCI bus number.
+ @param DeviceNumber The PCI controller's current PCI device number.
+ @param FunctionNumber The PCI controller's current PCI function number.
+
+ @retval EFI_SUCCESS The PCI controller location was returned.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *SegmentNumber,
+ OUT UINTN *BusNumber,
+ OUT UINTN *DeviceNumber,
+ OUT UINTN *FunctionNumber
+ );
+
+/**
+ Performs an operation on the attributes that this PCI controller supports. The operations include
+ getting the set of supported attributes, retrieving the current attributes, setting the current
+ attributes, enabling attributes, and disabling attributes.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Operation The operation to perform on the attributes for this PCI controller.
+ @param Attributes The mask of attributes that are used for Set, Enable, and Disable
+ operations.
+ @param Result A pointer to the result mask of attributes that are returned for the Get
+ and Supported operations.
+
+ @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_UNSUPPORTED one or more of the bits set in
+ Attributes are not supported by this PCI controller or one of
+ its parent bridges when Operation is Set, Enable or Disable.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL
+ );
+
+/**
+ Gets the attributes that this PCI controller supports setting on a BAR using
+ SetBarAttributes(), and retrieves the list of resource descriptors for a BAR.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param BarIndex The BAR index of the standard PCI Configuration header to use as the
+ base address for resource range. The legal range for this field is 0..5.
+ @param Supports A pointer to the mask of attributes that this PCI controller supports
+ setting for this BAR with SetBarAttributes().
+ @param Resources A pointer to the ACPI 2.0 resource descriptors that describe the current
+ configuration of this BAR of the PCI controller.
+
+ @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI
+ controller supports are returned in Supports. If Resources
+ is not NULL, then the ACPI 2.0 resource descriptors that the PCI
+ controller is currently using are returned in Resources.
+ @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+ @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate
+ Resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL
+ );
+
+/**
+ Sets the attributes for a range of a BAR on a PCI controller.
+
+ @param This A pointer to the EFI_PCI_IO_PROTOCOL instance.
+ @param Attributes The mask of attributes to set for the resource range specified by
+ BarIndex, Offset, and Length.
+ @param BarIndex The BAR index of the standard PCI Configuration header to use as the
+ base address for resource range. The legal range for this field is 0..5.
+ @param Offset A pointer to the BAR relative base address of the resource range to be
+ modified by the attributes specified by Attributes.
+ @param Length A pointer to the length of the resource range to be modified by the
+ attributes specified by Attributes.
+
+ @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource
+ range specified by BarIndex, Offset, and Length were
+ set on the PCI controller, and the actual resource range is returned
+ in Offset and Length.
+ @retval EFI_INVALID_PARAMETER Offset or Length is NULL.
+ @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the
+ resource range specified by BarIndex, Offset, and
+ Length.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)(
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length
+ );
+
+///
+/// The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration,
+/// and DMA interfaces used to abstract accesses to PCI controllers.
+/// There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus.
+/// A device driver that wishes to manage a PCI controller in a system will have to
+/// retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller.
+///
+struct _EFI_PCI_IO_PROTOCOL {
+ EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem;
+ EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo;
+ EFI_PCI_IO_PROTOCOL_ACCESS Mem;
+ EFI_PCI_IO_PROTOCOL_ACCESS Io;
+ EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci;
+ EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem;
+ EFI_PCI_IO_PROTOCOL_MAP Map;
+ EFI_PCI_IO_PROTOCOL_UNMAP Unmap;
+ EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
+ EFI_PCI_IO_PROTOCOL_FLUSH Flush;
+ EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation;
+ EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes;
+ EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes;
+ EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes;
+
+ ///
+ /// The size, in bytes, of the ROM image.
+ ///
+ UINT64 RomSize;
+
+ ///
+ /// A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible
+ /// for allocating memory for the ROM image, and copying the contents of the ROM to memory.
+ /// The contents of this buffer are either from the PCI option ROM that can be accessed
+ /// through the ROM BAR of the PCI controller, or it is from a platform-specific location.
+ /// The Attributes() function can be used to determine from which of these two sources
+ /// the RomImage buffer was initialized.
+ ///
+ VOID *RomImage;
+};
+
+extern EFI_GUID gEfiPciIoProtocolGuid;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efipoint.h b/usr/src/boot/sys/boot/efi/include/efipoint.h
new file mode 100644
index 0000000000..46e92ffd3b
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efipoint.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 2014 by John Cronin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef _EFI_POINT_H
+#define _EFI_POINT_H
+
+#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \
+ { 0x31878c87, 0xb75, 0x11d5, { 0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+INTERFACE_DECL(_EFI_SIMPLE_POINTER);
+
+typedef struct {
+ INT32 RelativeMovementX;
+ INT32 RelativeMovementY;
+ INT32 RelativeMovementZ;
+ BOOLEAN LeftButton;
+ BOOLEAN RightButton;
+} EFI_SIMPLE_POINTER_STATE;
+
+typedef struct {
+ UINT64 ResolutionX;
+ UINT64 ResolutionY;
+ UINT64 ResolutionZ;
+ BOOLEAN LeftButton;
+ BOOLEAN RightButton;
+} EFI_SIMPLE_POINTER_MODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_POINTER_RESET) (
+ IN struct _EFI_SIMPLE_POINTER *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE) (
+ IN struct _EFI_SIMPLE_POINTER *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State
+);
+
+typedef struct _EFI_SIMPLE_POINTER {
+ EFI_SIMPLE_POINTER_RESET Reset;
+ EFI_SIMPLE_POINTER_GET_STATE GetState;
+ EFI_EVENT WaitForInput;
+ EFI_SIMPLE_POINTER_MODE *Mode;
+} EFI_SIMPLE_POINTER_PROTOCOL;
+
+#define EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \
+ { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } }
+
+INTERFACE_DECL(_EFI_ABSOLUTE_POINTER_PROTOCOL);
+
+typedef struct {
+ UINT64 AbsoluteMinX;
+ UINT64 AbsoluteMinY;
+ UINT64 AbsoluteMinZ;
+ UINT64 AbsoluteMaxX;
+ UINT64 AbsoluteMaxY;
+ UINT64 AbsoluteMaxZ;
+ UINT32 Attributes;
+} EFI_ABSOLUTE_POINTER_MODE;
+
+typedef struct {
+ UINT64 CurrentX;
+ UINT64 CurrentY;
+ UINT64 CurrentZ;
+ UINT32 ActiveButtons;
+} EFI_ABSOLUTE_POINTER_STATE;
+
+#define EFI_ABSP_SupportsAltActive 0x00000001
+#define EFI_ABSP_SupportsPressureAsZ 0x00000002
+#define EFI_ABSP_TouchActive 0x00000001
+#define EFI_ABS_AltActive 0x00000002
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ABSOLUTE_POINTER_RESET) (
+ IN struct _EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE) (
+ IN struct _EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ IN OUT EFI_ABSOLUTE_POINTER_STATE *State
+);
+
+typedef struct _EFI_ABSOLUTE_POINTER_PROTOCOL {
+ EFI_ABSOLUTE_POINTER_RESET Reset;
+ EFI_ABSOLUTE_POINTER_GET_STATE GetState;
+ EFI_EVENT WaitForInput;
+ EFI_ABSOLUTE_POINTER_MODE *Mode;
+} EFI_ABSOLUTE_POINTER_PROTOCOL;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efiprot.h b/usr/src/boot/sys/boot/efi/include/efiprot.h
new file mode 100644
index 0000000000..28cec5991e
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiprot.h
@@ -0,0 +1,558 @@
+/* $FreeBSD$ */
+#ifndef _EFI_PROT_H
+#define _EFI_PROT_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efiprot.h
+
+Abstract:
+
+ EFI Protocols
+
+
+
+Revision History
+
+--*/
+
+//
+// Device Path protocol
+//
+
+#define DEVICE_PATH_PROTOCOL \
+ { 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+
+//
+// Block IO protocol
+//
+
+#define BLOCK_IO_PROTOCOL \
+ { 0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+#define EFI_BLOCK_IO_INTERFACE_REVISION 0x00010000
+
+INTERFACE_DECL(_EFI_BLOCK_IO);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_RESET) (
+ IN struct _EFI_BLOCK_IO *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_READ) (
+ IN struct _EFI_BLOCK_IO *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_WRITE) (
+ IN struct _EFI_BLOCK_IO *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_FLUSH) (
+ IN struct _EFI_BLOCK_IO *This
+ );
+
+
+
+typedef struct {
+ UINT32 MediaId;
+ BOOLEAN RemovableMedia;
+ BOOLEAN MediaPresent;
+
+ BOOLEAN LogicalPartition;
+ BOOLEAN ReadOnly;
+ BOOLEAN WriteCaching;
+
+ UINT32 BlockSize;
+ UINT32 IoAlign;
+
+ EFI_LBA LastBlock;
+} EFI_BLOCK_IO_MEDIA;
+
+typedef struct _EFI_BLOCK_IO {
+ UINT64 Revision;
+
+ EFI_BLOCK_IO_MEDIA *Media;
+
+ EFI_BLOCK_RESET Reset;
+ EFI_BLOCK_READ ReadBlocks;
+ EFI_BLOCK_WRITE WriteBlocks;
+ EFI_BLOCK_FLUSH FlushBlocks;
+
+} EFI_BLOCK_IO;
+
+
+
+//
+// Disk Block IO protocol
+//
+
+#define DISK_IO_PROTOCOL \
+ { 0xce345171, 0xba0b, 0x11d2, {0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+#define EFI_DISK_IO_INTERFACE_REVISION 0x00010000
+
+INTERFACE_DECL(_EFI_DISK_IO);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISK_READ) (
+ IN struct _EFI_DISK_IO *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISK_WRITE) (
+ IN struct _EFI_DISK_IO *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+
+typedef struct _EFI_DISK_IO {
+ UINT64 Revision;
+ EFI_DISK_READ ReadDisk;
+ EFI_DISK_WRITE WriteDisk;
+} EFI_DISK_IO;
+
+
+//
+// Simple file system protocol
+//
+
+#define SIMPLE_FILE_SYSTEM_PROTOCOL \
+ { 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_EFI_FILE_IO_INTERFACE);
+INTERFACE_DECL(_EFI_FILE_HANDLE);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_VOLUME_OPEN) (
+ IN struct _EFI_FILE_IO_INTERFACE *This,
+ OUT struct _EFI_FILE_HANDLE **Root
+ );
+
+#define EFI_FILE_IO_INTERFACE_REVISION 0x00010000
+
+typedef struct _EFI_FILE_IO_INTERFACE {
+ UINT64 Revision;
+ EFI_VOLUME_OPEN OpenVolume;
+} EFI_FILE_IO_INTERFACE;
+
+//
+//
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_OPEN) (
+ IN struct _EFI_FILE_HANDLE *File,
+ OUT struct _EFI_FILE_HANDLE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+// Open modes
+#define EFI_FILE_MODE_READ 0x0000000000000001
+#define EFI_FILE_MODE_WRITE 0x0000000000000002
+#define EFI_FILE_MODE_CREATE 0x8000000000000000
+
+// File attributes
+#define EFI_FILE_READ_ONLY 0x0000000000000001
+#define EFI_FILE_HIDDEN 0x0000000000000002
+#define EFI_FILE_SYSTEM 0x0000000000000004
+#define EFI_FILE_RESERVIED 0x0000000000000008
+#define EFI_FILE_DIRECTORY 0x0000000000000010
+#define EFI_FILE_ARCHIVE 0x0000000000000020
+#define EFI_FILE_VALID_ATTR 0x0000000000000037
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_CLOSE) (
+ IN struct _EFI_FILE_HANDLE *File
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_DELETE) (
+ IN struct _EFI_FILE_HANDLE *File
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_READ) (
+ IN struct _EFI_FILE_HANDLE *File,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_WRITE) (
+ IN struct _EFI_FILE_HANDLE *File,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_SET_POSITION) (
+ IN struct _EFI_FILE_HANDLE *File,
+ IN UINT64 Position
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_GET_POSITION) (
+ IN struct _EFI_FILE_HANDLE *File,
+ OUT UINT64 *Position
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_GET_INFO) (
+ IN struct _EFI_FILE_HANDLE *File,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_SET_INFO) (
+ IN struct _EFI_FILE_HANDLE *File,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_FLUSH) (
+ IN struct _EFI_FILE_HANDLE *File
+ );
+
+
+
+#define EFI_FILE_HANDLE_REVISION 0x00010000
+typedef struct _EFI_FILE_HANDLE {
+ UINT64 Revision;
+ EFI_FILE_OPEN Open;
+ EFI_FILE_CLOSE Close;
+ EFI_FILE_DELETE Delete;
+ EFI_FILE_READ Read;
+ EFI_FILE_WRITE Write;
+ EFI_FILE_GET_POSITION GetPosition;
+ EFI_FILE_SET_POSITION SetPosition;
+ EFI_FILE_GET_INFO GetInfo;
+ EFI_FILE_SET_INFO SetInfo;
+ EFI_FILE_FLUSH Flush;
+} EFI_FILE, *EFI_FILE_HANDLE;
+
+
+//
+// File information types
+//
+
+#define EFI_FILE_INFO_ID \
+ { 0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+typedef struct {
+ UINT64 Size;
+ UINT64 FileSize;
+ UINT64 PhysicalSize;
+ EFI_TIME CreateTime;
+ EFI_TIME LastAccessTime;
+ EFI_TIME ModificationTime;
+ UINT64 Attribute;
+ CHAR16 FileName[1];
+} EFI_FILE_INFO;
+
+//
+// The FileName field of the EFI_FILE_INFO data structure is variable length.
+// Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to
+// be the size of the data structure without the FileName field. The following macro
+// computes this size correctly no matter how big the FileName array is declared.
+// This is required to make the EFI_FILE_INFO data structure ANSI compilant.
+//
+
+#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName)
+
+#define EFI_FILE_SYSTEM_INFO_ID \
+ { 0x9576e93, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+typedef struct {
+ UINT64 Size;
+ BOOLEAN ReadOnly;
+ UINT64 VolumeSize;
+ UINT64 FreeSpace;
+ UINT32 BlockSize;
+ CHAR16 VolumeLabel[1];
+} EFI_FILE_SYSTEM_INFO;
+
+//
+// The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.
+// Whenever code needs to know the size of the EFI_FILE_SYSTEM_INFO data structure, it needs
+// to be the size of the data structure without the VolumeLable field. The following macro
+// computes this size correctly no matter how big the VolumeLable array is declared.
+// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant.
+//
+
+#define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel)
+
+#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID \
+ { 0xDB47D7D3,0xFE81, 0x11d3, {0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} }
+
+typedef struct {
+ CHAR16 VolumeLabel[1];
+} EFI_FILE_SYSTEM_VOLUME_LABEL_INFO;
+
+#define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_VOLUME_LABEL_INFO,VolumeLabel)
+
+//
+// Load file protocol
+//
+
+
+#define LOAD_FILE_PROTOCOL \
+ { 0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} }
+
+INTERFACE_DECL(_EFI_LOAD_FILE_INTERFACE);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOAD_FILE) (
+ IN struct _EFI_LOAD_FILE_INTERFACE *This,
+ IN EFI_DEVICE_PATH *FilePath,
+ IN BOOLEAN BootPolicy,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL
+ );
+
+typedef struct _EFI_LOAD_FILE_INTERFACE {
+ EFI_LOAD_FILE LoadFile;
+} EFI_LOAD_FILE_INTERFACE;
+
+
+//
+// Device IO protocol
+//
+
+#define DEVICE_IO_PROTOCOL \
+ { 0xaf6ac311, 0x84c3, 0x11d2, {0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_EFI_DEVICE_IO_INTERFACE);
+
+typedef enum {
+ IO_UINT8,
+ IO_UINT16,
+ IO_UINT32,
+ IO_UINT64,
+//
+// Specification Change: Copy from MMIO to MMIO vs. MMIO to buffer, buffer to MMIO
+//
+ MMIO_COPY_UINT8,
+ MMIO_COPY_UINT16,
+ MMIO_COPY_UINT32,
+ MMIO_COPY_UINT64
+} EFI_IO_WIDTH;
+
+#define EFI_PCI_ADDRESS(bus,dev,func,reg) \
+ ( (UINT64) ( (((UINTN)bus) << 24) + (((UINTN)dev) << 16) + (((UINTN)func) << 8) + ((UINTN)reg) ))
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DEVICE_IO) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+typedef struct {
+ EFI_DEVICE_IO Read;
+ EFI_DEVICE_IO Write;
+} EFI_IO_ACCESS;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_DEVICE_PATH) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN UINT64 Address,
+ IN OUT EFI_DEVICE_PATH **PciDevicePath
+ );
+
+typedef enum {
+ EfiBusMasterRead,
+ EfiBusMasterWrite,
+ EfiBusMasterCommonBuffer
+} EFI_IO_OPERATION_TYPE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IO_MAP) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_OPERATION_TYPE Operation,
+ IN EFI_PHYSICAL_ADDRESS *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IO_UNMAP) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN VOID *Mapping
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IO_ALLOCATE_BUFFER) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *HostAddress
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IO_FLUSH) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IO_FREE_BUFFER) (
+ IN struct _EFI_DEVICE_IO_INTERFACE *This,
+ IN UINTN Pages,
+ IN EFI_PHYSICAL_ADDRESS HostAddress
+ );
+
+typedef struct _EFI_DEVICE_IO_INTERFACE {
+ EFI_IO_ACCESS Mem;
+ EFI_IO_ACCESS Io;
+ EFI_IO_ACCESS Pci;
+ EFI_IO_MAP Map;
+ EFI_PCI_DEVICE_PATH PciDevicePath;
+ EFI_IO_UNMAP Unmap;
+ EFI_IO_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_IO_FLUSH Flush;
+ EFI_IO_FREE_BUFFER FreeBuffer;
+} EFI_DEVICE_IO_INTERFACE;
+
+
+//
+// Unicode Collation protocol
+//
+
+#define UNICODE_COLLATION_PROTOCOL \
+ { 0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define UNICODE_BYTE_ORDER_MARK (CHAR16)(0xfeff)
+
+INTERFACE_DECL(_EFI_UNICODE_COLLATION_INTERFACE);
+
+typedef
+INTN
+(EFIAPI *EFI_UNICODE_COLLATION_STRICOLL) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN CHAR16 *s1,
+ IN CHAR16 *s2
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_UNICODE_COLLATION_METAIMATCH) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN CHAR16 *String,
+ IN CHAR16 *Pattern
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_UNICODE_COLLATION_STRLWR) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN OUT CHAR16 *Str
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_UNICODE_COLLATION_STRUPR) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN OUT CHAR16 *Str
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_UNICODE_COLLATION_FATTOSTR) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN UINTN FatSize,
+ IN CHAR8 *Fat,
+ OUT CHAR16 *String
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_UNICODE_COLLATION_STRTOFAT) (
+ IN struct _EFI_UNICODE_COLLATION_INTERFACE *This,
+ IN CHAR16 *String,
+ IN UINTN FatSize,
+ OUT CHAR8 *Fat
+ );
+
+
+typedef struct _EFI_UNICODE_COLLATION_INTERFACE {
+
+ // general
+ EFI_UNICODE_COLLATION_STRICOLL StriColl;
+ EFI_UNICODE_COLLATION_METAIMATCH MetaiMatch;
+ EFI_UNICODE_COLLATION_STRLWR StrLwr;
+ EFI_UNICODE_COLLATION_STRUPR StrUpr;
+
+ // for supporting fat volumes
+ EFI_UNICODE_COLLATION_FATTOSTR FatToStr;
+ EFI_UNICODE_COLLATION_STRTOFAT StrToFat;
+
+ CHAR8 *SupportedLanguages;
+} EFI_UNICODE_COLLATION_INTERFACE;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efipxebc.h b/usr/src/boot/sys/boot/efi/include/efipxebc.h
new file mode 100644
index 0000000000..ba0b2e9b6c
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efipxebc.h
@@ -0,0 +1,472 @@
+/* $FreeBSD$ */
+#ifndef _EFIPXEBC_H
+#define _EFIPXEBC_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efipxebc.h
+
+Abstract:
+
+ EFI PXE Base Code Protocol
+
+
+
+Revision History
+
+--*/
+
+//
+// PXE Base Code protocol
+//
+
+#define EFI_PXE_BASE_CODE_PROTOCOL \
+ { 0x03c4e603, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+INTERFACE_DECL(_EFI_PXE_BASE_CODE);
+
+#define DEFAULT_TTL 8
+#define DEFAULT_ToS 0
+//
+// Address definitions
+//
+
+typedef union {
+ UINT32 Addr[4];
+ EFI_IPv4_ADDRESS v4;
+ EFI_IPv6_ADDRESS v6;
+} EFI_IP_ADDRESS;
+
+typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT;
+
+//
+// Packet definitions
+//
+
+typedef struct {
+ UINT8 BootpOpcode;
+ UINT8 BootpHwType;
+ UINT8 BootpHwAddrLen;
+ UINT8 BootpGateHops;
+ UINT32 BootpIdent;
+ UINT16 BootpSeconds;
+ UINT16 BootpFlags;
+ UINT8 BootpCiAddr[4];
+ UINT8 BootpYiAddr[4];
+ UINT8 BootpSiAddr[4];
+ UINT8 BootpGiAddr[4];
+ UINT8 BootpHwAddr[16];
+ UINT8 BootpSrvName[64];
+ UINT8 BootpBootFile[128];
+ UINT32 DhcpMagik;
+ UINT8 DhcpOptions[56];
+} EFI_PXE_BASE_CODE_DHCPV4_PACKET;
+
+// TBD in EFI v1.1
+//typedef struct {
+// UINT8 reserved;
+//} EFI_PXE_BASE_CODE_DHCPV6_PACKET;
+
+typedef union {
+ UINT8 Raw[1472];
+ EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4;
+// EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6;
+} EFI_PXE_BASE_CODE_PACKET;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Code;
+ UINT16 Checksum;
+ union {
+ UINT32 reserved;
+ UINT32 Mtu;
+ UINT32 Pointer;
+ struct {
+ UINT16 Identifier;
+ UINT16 Sequence;
+ } Echo;
+ } u;
+ UINT8 Data[494];
+} EFI_PXE_BASE_CODE_ICMP_ERROR;
+
+typedef struct {
+ UINT8 ErrorCode;
+ CHAR8 ErrorString[127];
+} EFI_PXE_BASE_CODE_TFTP_ERROR;
+
+//
+// IP Receive Filter definitions
+//
+#define EFI_PXE_BASE_CODE_MAX_IPCNT 8
+typedef struct {
+ UINT8 Filters;
+ UINT8 IpCnt;
+ UINT16 reserved;
+ EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT];
+} EFI_PXE_BASE_CODE_IP_FILTER;
+
+#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001
+#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002
+#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004
+#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008
+
+//
+// ARP Cache definitions
+//
+
+typedef struct {
+ EFI_IP_ADDRESS IpAddr;
+ EFI_MAC_ADDRESS MacAddr;
+} EFI_PXE_BASE_CODE_ARP_ENTRY;
+
+typedef struct {
+ EFI_IP_ADDRESS IpAddr;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_IP_ADDRESS GwAddr;
+} EFI_PXE_BASE_CODE_ROUTE_ENTRY;
+
+//
+// UDP definitions
+//
+
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010
+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020
+
+//
+// Discover() definitions
+//
+
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16
+//
+// 17 through 32767 are reserved
+// 32768 through 65279 are for vendor use
+// 65280 through 65534 are reserved
+//
+#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535
+
+#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF
+#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000
+#define EFI_PXE_BASE_CODE_BOOT_LAYER_CREDENTIALS 0x8000
+
+
+typedef struct {
+ UINT16 Type;
+ BOOLEAN AcceptAnyResponse;
+ UINT8 Reserved;
+ EFI_IP_ADDRESS IpAddr;
+} EFI_PXE_BASE_CODE_SRVLIST;
+
+typedef struct {
+ BOOLEAN UseMCast;
+ BOOLEAN UseBCast;
+ BOOLEAN UseUCast;
+ BOOLEAN MustUseList;
+ EFI_IP_ADDRESS ServerMCastIp;
+ UINT16 IpCnt;
+ EFI_PXE_BASE_CODE_SRVLIST SrvList[1];
+} EFI_PXE_BASE_CODE_DISCOVER_INFO;
+
+//
+// Mtftp() definitions
+//
+
+typedef enum {
+ EFI_PXE_BASE_CODE_TFTP_FIRST,
+ EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,
+ EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,
+ EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY,
+ EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE,
+ EFI_PXE_BASE_CODE_MTFTP_READ_FILE,
+ EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY,
+ EFI_PXE_BASE_CODE_MTFTP_LAST
+} EFI_PXE_BASE_CODE_TFTP_OPCODE;
+
+typedef struct {
+ EFI_IP_ADDRESS MCastIp;
+ EFI_PXE_BASE_CODE_UDP_PORT CPort;
+ EFI_PXE_BASE_CODE_UDP_PORT SPort;
+ UINT16 ListenTimeout;
+ UINT16 TransmitTimeout;
+} EFI_PXE_BASE_CODE_MTFTP_INFO;
+
+//
+// PXE Base Code Mode structure
+//
+
+#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8
+#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8
+
+typedef struct {
+ BOOLEAN Started;
+ BOOLEAN Ipv6Available;
+ BOOLEAN Ipv6Supported;
+ BOOLEAN UsingIpv6;
+ BOOLEAN BisSupported;
+ BOOLEAN BisDetected;
+ BOOLEAN AutoArp;
+ BOOLEAN SendGUID;
+ BOOLEAN DhcpDiscoverValid;
+ BOOLEAN DhcpAckReceived;
+ BOOLEAN ProxyOfferReceived;
+ BOOLEAN PxeDiscoverValid;
+ BOOLEAN PxeReplyReceived;
+ BOOLEAN PxeBisReplyReceived;
+ BOOLEAN IcmpErrorReceived;
+ BOOLEAN TftpErrorReceived;
+ BOOLEAN MakeCallbacks;
+ UINT8 TTL;
+ UINT8 ToS;
+ EFI_IP_ADDRESS StationIp;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_PXE_BASE_CODE_PACKET DhcpDiscover;
+ EFI_PXE_BASE_CODE_PACKET DhcpAck;
+ EFI_PXE_BASE_CODE_PACKET ProxyOffer;
+ EFI_PXE_BASE_CODE_PACKET PxeDiscover;
+ EFI_PXE_BASE_CODE_PACKET PxeReply;
+ EFI_PXE_BASE_CODE_PACKET PxeBisReply;
+ EFI_PXE_BASE_CODE_IP_FILTER IpFilter;
+ UINT32 ArpCacheEntries;
+ EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES];
+ UINT32 RouteTableEntries;
+ EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES];
+ EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError;
+ EFI_PXE_BASE_CODE_TFTP_ERROR TftpError;
+} EFI_PXE_BASE_CODE_MODE;
+
+//
+// PXE Base Code Interface Function definitions
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_START) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN BOOLEAN UseIpv6
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_STOP) (
+ IN struct _EFI_PXE_BASE_CODE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_DHCP) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN BOOLEAN SortOffers
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN UINT16 Type,
+ IN UINT16 *Layer,
+ IN BOOLEAN UseBis,
+ IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_MTFTP) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
+ IN OUT VOID *BufferPtr OPTIONAL,
+ IN BOOLEAN Overwrite,
+ IN OUT UINT64 *BufferSize,
+ IN UINTN *BlockSize OPTIONAL,
+ IN EFI_IP_ADDRESS *ServerIp,
+ IN UINT8 *Filename,
+ IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,
+ IN BOOLEAN DontUseBuffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN UINT16 OpFlags,
+ IN EFI_IP_ADDRESS *DestIp,
+ IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort,
+ IN EFI_IP_ADDRESS *GatewayIp, OPTIONAL
+ IN EFI_IP_ADDRESS *SrcIp, OPTIONAL
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
+ IN UINTN *HeaderSize, OPTIONAL
+ IN VOID *HeaderPtr, OPTIONAL
+ IN UINTN *BufferSize,
+ IN VOID *BufferPtr
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN UINT16 OpFlags,
+ IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL
+ IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
+ IN UINTN *HeaderSize, OPTIONAL
+ IN VOID *HeaderPtr, OPTIONAL
+ IN OUT UINTN *BufferSize,
+ IN VOID *BufferPtr
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_ARP) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN EFI_IP_ADDRESS *IpAddr,
+ IN EFI_MAC_ADDRESS *MacAddr OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN BOOLEAN *NewAutoArp, OPTIONAL
+ IN BOOLEAN *NewSendGUID, OPTIONAL
+ IN UINT8 *NewTTL, OPTIONAL
+ IN UINT8 *NewToS, OPTIONAL
+ IN BOOLEAN *NewMakeCallback OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL
+ IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS) (
+ IN struct _EFI_PXE_BASE_CODE *This,
+ BOOLEAN *NewDhcpDiscoverValid, OPTIONAL
+ BOOLEAN *NewDhcpAckReceived, OPTIONAL
+ BOOLEAN *NewProxyOfferReceived, OPTIONAL
+ BOOLEAN *NewPxeDiscoverValid, OPTIONAL
+ BOOLEAN *NewPxeReplyReceived, OPTIONAL
+ BOOLEAN *NewPxeBisReplyReceived,OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover, OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck, OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer, OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover, OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply, OPTIONAL
+ IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL
+ );
+
+//
+// PXE Base Code Protocol structure
+//
+
+#define EFI_PXE_BASE_CODE_INTERFACE_REVISION 0x00010000
+
+typedef struct _EFI_PXE_BASE_CODE {
+ UINT64 Revision;
+ EFI_PXE_BASE_CODE_START Start;
+ EFI_PXE_BASE_CODE_STOP Stop;
+ EFI_PXE_BASE_CODE_DHCP Dhcp;
+ EFI_PXE_BASE_CODE_DISCOVER Discover;
+ EFI_PXE_BASE_CODE_MTFTP Mtftp;
+ EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite;
+ EFI_PXE_BASE_CODE_UDP_READ UdpRead;
+ EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter;
+ EFI_PXE_BASE_CODE_ARP Arp;
+ EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters;
+ EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp;
+ EFI_PXE_BASE_CODE_SET_PACKETS SetPackets;
+ EFI_PXE_BASE_CODE_MODE *Mode;
+} EFI_PXE_BASE_CODE;
+
+//
+// Call Back Definitions
+//
+
+#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL \
+ { 0x245dca21, 0xfb7b, 0x11d3, {0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+//
+// Revision Number
+//
+
+#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION 0x00010000
+
+INTERFACE_DECL(_EFI_PXE_BASE_CODE_CALLBACK);
+
+typedef enum {
+ EFI_PXE_BASE_CODE_FUNCTION_FIRST,
+ EFI_PXE_BASE_CODE_FUNCTION_DHCP,
+ EFI_PXE_BASE_CODE_FUNCTION_DISCOVER,
+ EFI_PXE_BASE_CODE_FUNCTION_MTFTP,
+ EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE,
+ EFI_PXE_BASE_CODE_FUNCTION_UDP_READ,
+ EFI_PXE_BASE_CODE_FUNCTION_ARP,
+ EFI_PXE_BASE_CODE_FUNCTION_IGMP,
+ EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST
+} EFI_PXE_BASE_CODE_FUNCTION;
+
+typedef enum {
+ EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST,
+ EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,
+ EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT,
+ EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST
+} EFI_PXE_BASE_CODE_CALLBACK_STATUS;
+
+typedef
+EFI_PXE_BASE_CODE_CALLBACK_STATUS
+(EFIAPI *EFI_PXE_CALLBACK) (
+ IN struct _EFI_PXE_BASE_CODE_CALLBACK *This,
+ IN EFI_PXE_BASE_CODE_FUNCTION Function,
+ IN BOOLEAN Received,
+ IN UINT32 PacketLen,
+ IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL
+ );
+
+typedef struct _EFI_PXE_BASE_CODE_CALLBACK {
+ UINT64 Revision;
+ EFI_PXE_CALLBACK Callback;
+} EFI_PXE_BASE_CODE_CALLBACK;
+
+#endif /* _EFIPXEBC_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efiser.h b/usr/src/boot/sys/boot/efi/include/efiser.h
new file mode 100644
index 0000000000..e3d66e203a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiser.h
@@ -0,0 +1,139 @@
+/* $FreeBSD$ */
+#ifndef _EFI_SER_H
+#define _EFI_SER_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efiser.h
+
+Abstract:
+
+ EFI serial protocol
+
+Revision History
+
+--*/
+
+//
+// Serial protocol
+//
+
+#define SERIAL_IO_PROTOCOL \
+ { 0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD} }
+
+INTERFACE_DECL(_SERIAL_IO_INTERFACE);
+
+typedef enum {
+ DefaultParity,
+ NoParity,
+ EvenParity,
+ OddParity,
+ MarkParity,
+ SpaceParity
+} EFI_PARITY_TYPE;
+
+typedef enum {
+ DefaultStopBits,
+ OneStopBit, // 1 stop bit
+ OneFiveStopBits, // 1.5 stop bits
+ TwoStopBits // 2 stop bits
+} EFI_STOP_BITS_TYPE;
+
+#define EFI_SERIAL_CLEAR_TO_SEND 0x0010 // RO
+#define EFI_SERIAL_DATA_SET_READY 0x0020 // RO
+#define EFI_SERIAL_RING_INDICATE 0x0040 // RO
+#define EFI_SERIAL_CARRIER_DETECT 0x0080 // RO
+#define EFI_SERIAL_REQUEST_TO_SEND 0x0002 // WO
+#define EFI_SERIAL_DATA_TERMINAL_READY 0x0001 // WO
+#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x0100 // RO
+#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x0200 // RO
+#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x1000 // RW
+#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x2000 // RW
+#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x4000 // RW
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_RESET) (
+ IN struct _SERIAL_IO_INTERFACE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES) (
+ IN struct _SERIAL_IO_INTERFACE *This,
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) (
+ IN struct _SERIAL_IO_INTERFACE *This,
+ IN UINT32 Control
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS) (
+ IN struct _SERIAL_IO_INTERFACE *This,
+ OUT UINT32 *Control
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_WRITE) (
+ IN struct _SERIAL_IO_INTERFACE *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_READ) (
+ IN struct _SERIAL_IO_INTERFACE *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+typedef struct {
+ UINT32 ControlMask;
+
+ // current Attributes
+ UINT32 Timeout;
+ UINT64 BaudRate;
+ UINT32 ReceiveFifoDepth;
+ UINT32 DataBits;
+ UINT32 Parity;
+ UINT32 StopBits;
+} SERIAL_IO_MODE;
+
+#define SERIAL_IO_INTERFACE_REVISION 0x00010000
+
+typedef struct _SERIAL_IO_INTERFACE {
+ UINT32 Revision;
+ EFI_SERIAL_RESET Reset;
+ EFI_SERIAL_SET_ATTRIBUTES SetAttributes;
+ EFI_SERIAL_SET_CONTROL_BITS SetControl;
+ EFI_SERIAL_GET_CONTROL_BITS GetControl;
+ EFI_SERIAL_WRITE Write;
+ EFI_SERIAL_READ Read;
+
+ SERIAL_IO_MODE *Mode;
+} SERIAL_IO_INTERFACE;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/efistdarg.h b/usr/src/boot/sys/boot/efi/include/efistdarg.h
new file mode 100644
index 0000000000..25f5569841
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efistdarg.h
@@ -0,0 +1,39 @@
+/* $FreeBSD$ */
+#ifndef _EFISTDARG_H_
+#define _EFISTDARG_H_
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ devpath.h
+
+Abstract:
+
+ Defines for parsing the EFI Device Path structures
+
+
+
+Revision History
+
+--*/
+
+#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(UINTN) - 1) & ~(sizeof(UINTN) - 1) )
+
+typedef CHAR8 * va_list;
+
+#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
+#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
+#define va_end(ap) ( ap = (va_list)0 )
+
+
+#endif /* _INC_STDARG */
diff --git a/usr/src/boot/sys/boot/efi/include/efitcp.h b/usr/src/boot/sys/boot/efi/include/efitcp.h
new file mode 100644
index 0000000000..6c5df7fd94
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efitcp.h
@@ -0,0 +1,391 @@
+#ifndef _EFI_TCP_H
+#define _EFI_TCP_H
+
+/*++
+Copyright (c) 2013 Intel Corporation
+
+--*/
+
+#define EFI_TCP4_SERVICE_BINDING_PROTOCOL \
+ { 0x00720665, 0x67eb, 0x4a99, {0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c,0x7c, 0xc9}}
+
+#define EFI_TCP4_PROTOCOL \
+ { 0x65530bc7, 0xa359, 0x410f, {0xb0, 0x10, 0x5a, 0xad, 0xc7, 0xec, 0x2b, 0x62}}
+
+#define EFI_TCP6_SERVICE_BINDING_PROTOCOL \
+ { 0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0xd, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64}}
+
+#define EFI_TCP6_PROTOCOL \
+ { 0x46e44855, 0xbd60, 0x4ab7, {0xab, 0xd, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77}}
+
+INTERFACE_DECL(_EFI_TCP4);
+INTERFACE_DECL(_EFI_TCP6);
+
+typedef struct {
+ BOOLEAN UseDefaultAddress;
+ EFI_IPv4_ADDRESS StationAddress;
+ EFI_IPv4_ADDRESS SubnetMask;
+ UINT16 StationPort;
+ EFI_IPv4_ADDRESS RemoteAddress;
+ UINT16 RemotePort;
+ BOOLEAN ActiveFlag;
+} EFI_TCP4_ACCESS_POINT;
+
+typedef struct {
+ UINT32 ReceiveBufferSize;
+ UINT32 SendBufferSize;
+ UINT32 MaxSynBackLog;
+ UINT32 ConnectionTimeout;
+ UINT32 DataRetries;
+ UINT32 FinTimeout;
+ UINT32 TimeWaitTimeout;
+ UINT32 KeepAliveProbes;
+ UINT32 KeepAliveTime;
+ UINT32 KeepAliveInterval;
+ BOOLEAN EnableNagle;
+ BOOLEAN EnableTimeStamp;
+ BOOLEAN EnableWindowScaling;
+ BOOLEAN EnableSelectiveAck;
+ BOOLEAN EnablePAthMtuDiscovery;
+} EFI_TCP4_OPTION;
+
+typedef struct {
+ // Receiving Filters
+ // I/O parameters
+ UINT8 TypeOfService;
+ UINT8 TimeToLive;
+
+ // Access Point
+ EFI_TCP4_ACCESS_POINT AccessPoint;
+
+ // TCP Control Options
+ EFI_TCP4_OPTION *ControlOption;
+} EFI_TCP4_CONFIG_DATA;
+
+typedef enum {
+ Tcp4StateClosed = 0,
+ Tcp4StateListen = 1,
+ Tcp4StateSynSent = 2,
+ Tcp4StateSynReceived = 3,
+ Tcp4StateEstablished = 4,
+ Tcp4StateFinWait1 = 5,
+ Tcp4StateFinWait2 = 6,
+ Tcp4StateClosing = 7,
+ Tcp4StateTimeWait = 8,
+ Tcp4StateCloseWait = 9,
+ Tcp4StateLastAck = 10
+} EFI_TCP4_CONNECTION_STATE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_GET_MODE_DATA) (
+ IN struct _EFI_TCP4 *This,
+ OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL,
+ OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL,
+ OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_CONFIGURE) (
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_ROUTES) (
+ IN struct _EFI_TCP4 *This,
+ IN BOOLEAN DeleteRoute,
+ IN EFI_IPv4_ADDRESS *SubnetAddress,
+ IN EFI_IPv4_ADDRESS *SubnetMask,
+ IN EFI_IPv4_ADDRESS *GatewayAddress
+);
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+} EFI_TCP4_COMPLETION_TOKEN;
+
+typedef struct {
+ EFI_TCP4_COMPLETION_TOKEN CompletionToken;
+} EFI_TCP4_CONNECTION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_CONNECT) (
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
+ );
+
+typedef struct {
+ EFI_TCP4_COMPLETION_TOKEN CompletionToken;
+ EFI_HANDLE NewChildHandle;
+} EFI_TCP4_LISTEN_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_ACCEPT) (
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_LISTEN_TOKEN *ListenToken
+ );
+
+#define EFI_CONNECTION_FIN EFIERR(104)
+#define EFI_CONNECTION_RESET EFIERR(105)
+#define EFI_CONNECTION_REFUSED EFIERR(106)
+
+typedef struct {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_TCP4_FRAGMENT_DATA;
+
+typedef struct {
+ BOOLEAN UrgentFlag;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_TCP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_TCP4_RECEIVE_DATA;
+
+typedef struct {
+ BOOLEAN Push;
+ BOOLEAN Urgent;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_TCP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_TCP4_TRANSMIT_DATA;
+
+typedef struct {
+ EFI_TCP4_COMPLETION_TOKEN CompletionToken;
+ union {
+ EFI_TCP4_RECEIVE_DATA *RxData;
+ EFI_TCP4_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_TCP4_IO_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_TRANSMIT) (
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_IO_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_RECEIVE) (
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_IO_TOKEN *Token
+ );
+
+typedef struct {
+ EFI_TCP4_COMPLETION_TOKEN CompletionToken;
+ BOOLEAN AbortOnClose;
+} EFI_TCP4_CLOSE_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_CLOSE)(
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_CLOSE_TOKEN *CloseToken
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_CANCEL)(
+ IN struct _EFI_TCP4 *This,
+ IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP4_POLL) (
+ IN struct _EFI_TCP4 *This
+ );
+
+typedef struct _EFI_TCP4 {
+ EFI_TCP4_GET_MODE_DATA GetModeData;
+ EFI_TCP4_CONFIGURE Configure;
+ EFI_TCP4_ROUTES Routes;
+ EFI_TCP4_CONNECT Connect;
+ EFI_TCP4_ACCEPT Accept;
+ EFI_TCP4_TRANSMIT Transmit;
+ EFI_TCP4_RECEIVE Receive;
+ EFI_TCP4_CLOSE Close;
+ EFI_TCP4_CANCEL Cancel;
+ EFI_TCP4_POLL Poll;
+} EFI_TCP4;
+
+typedef enum {
+ Tcp6StateClosed = 0,
+ Tcp6StateListen = 1,
+ Tcp6StateSynSent = 2,
+ Tcp6StateSynReceived = 3,
+ Tcp6StateEstablished = 4,
+ Tcp6StateFinWait1 = 5,
+ Tcp6StateFinWait2 = 6,
+ Tcp6StateClosing = 7,
+ Tcp6StateTimeWait = 8,
+ Tcp6StateCloseWait = 9,
+ Tcp6StateLastAck = 10
+} EFI_TCP6_CONNECTION_STATE;
+
+typedef struct {
+ EFI_IPv6_ADDRESS StationAddress;
+ UINT16 StationPort;
+ EFI_IPv6_ADDRESS RemoteAddress;
+ UINT16 RemotePort;
+ BOOLEAN ActiveFlag;
+} EFI_TCP6_ACCESS_POINT;
+
+typedef struct {
+ UINT32 ReceiveBufferSize;
+ UINT32 SendBufferSize;
+ UINT32 MaxSynBackLog;
+ UINT32 ConnectionTimeout;
+ UINT32 DataRetries;
+ UINT32 FinTimeout;
+ UINT32 TimeWaitTimeout;
+ UINT32 KeepAliveProbes;
+ UINT32 KeepAliveTime;
+ UINT32 KeepAliveInterval;
+ BOOLEAN EnableNagle;
+ BOOLEAN EnableTimeStamp;
+ BOOLEAN EnableWindbowScaling;
+ BOOLEAN EnableSelectiveAck;
+ BOOLEAN EnablePathMtuDiscovery;
+} EFI_TCP6_OPTION;
+
+typedef struct {
+ UINT8 TrafficClass;
+ UINT8 HopLimit;
+ EFI_TCP6_ACCESS_POINT AccessPoint;
+ EFI_TCP6_OPTION *ControlOption;
+} EFI_TCP6_CONFIG_DATA;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_GET_MODE_DATA) (
+ IN struct _EFI_TCP6 *This,
+ OUT EFI_TCP6_CONNECTION_STATE *Tcp6State OPTIONAL,
+ OUT EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL,
+ OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CONFIGURE) (
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL
+ );
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+} EFI_TCP6_COMPLETION_TOKEN;
+
+typedef struct {
+ EFI_TCP6_COMPLETION_TOKEN CompletionToken;
+} EFI_TCP6_CONNECTION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CONNECT) (
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_CONNECTION_TOKEN *ConnectionToken
+ );
+
+typedef struct {
+ EFI_TCP6_COMPLETION_TOKEN CompletionToken;
+ EFI_HANDLE NewChildHandle;
+} EFI_TCP6_LISTEN_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_ACCEPT) (
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_LISTEN_TOKEN *ListenToken
+ );
+
+typedef struct {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_TCP6_FRAGMENT_DATA;
+
+typedef struct {
+ BOOLEAN UrgentFlag;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_TCP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_TCP6_RECEIVE_DATA;
+
+typedef struct {
+ BOOLEAN Push;
+ BOOLEAN Urgent;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_TCP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_TCP6_TRANSMIT_DATA;
+
+typedef struct {
+ EFI_TCP6_COMPLETION_TOKEN CompletionToken;
+ union {
+ EFI_TCP6_RECEIVE_DATA *RxData;
+ EFI_TCP6_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_TCP6_IO_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_TRANSMIT) (
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_IO_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_RECEIVE) (
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_IO_TOKEN *Token
+ );
+
+typedef struct {
+ EFI_TCP6_COMPLETION_TOKEN CompletionToken;
+ BOOLEAN AbortOnClose;
+} EFI_TCP6_CLOSE_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CLOSE)(
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_CLOSE_TOKEN *CloseToken
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CANCEL)(
+ IN struct _EFI_TCP6 *This,
+ IN EFI_TCP6_COMPLETION_TOKEN *Token OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_POLL) (
+ IN struct _EFI_TCP6 *This
+ );
+
+typedef struct _EFI_TCP6 {
+ EFI_TCP6_GET_MODE_DATA GetModeData;
+ EFI_TCP6_CONFIGURE Configure;
+ EFI_TCP6_CONNECT Connect;
+ EFI_TCP6_ACCEPT Accept;
+ EFI_TCP6_TRANSMIT Transmit;
+ EFI_TCP6_RECEIVE Receive;
+ EFI_TCP6_CLOSE Close;
+ EFI_TCP6_CANCEL Cancel;
+ EFI_TCP6_POLL Poll;
+} EFI_TCP6;
+
+#endif /* _EFI_TCP_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efiudp.h b/usr/src/boot/sys/boot/efi/include/efiudp.h
new file mode 100644
index 0000000000..7c8b467eb9
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiudp.h
@@ -0,0 +1,272 @@
+#ifndef _EFI_UDP_H
+#define _EFI_UDP_H
+
+
+/*++
+Copyright (c) 2013 Intel Corporation
+
+--*/
+
+#define EFI_UDP4_SERVICE_BINDING_PROTOCOL \
+ { 0x83f01464, 0x99bd, 0x45e5, {0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6} }
+
+#define EFI_UDP4_PROTOCOL \
+ { 0x3ad9df29, 0x4501, 0x478d, {0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3} }
+
+#define EFI_UDP6_SERVICE_BINDING_PROTOCOL \
+ { 0x66ed4721, 0x3c98, 0x4d3e, {0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54} }
+
+#define EFI_UDP6_PROTOCOL \
+ { 0x4f948815, 0xb4b9, 0x43cb, {0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3,0x49, 0x55} }
+
+INTERFACE_DECL(_EFI_UDP4);
+INTERFACE_DECL(_EFI_UDP6);
+
+typedef struct {
+ BOOLEAN AcceptBroadcast;
+ BOOLEAN AcceptPromiscuous;
+ BOOLEAN AcceptAnyPort;
+ BOOLEAN AllowDuplicatePort;
+ UINT8 TypeOfService;
+ UINT8 TimeToLive;
+ BOOLEAN DoNotFragment;
+ UINT32 ReceiveTimeout;
+ UINT32 TransmitTimeout;
+ BOOLEAN UseDefaultAddress;
+ EFI_IPv4_ADDRESS StationAddress;
+ EFI_IPv4_ADDRESS SubnetMask;
+ UINT16 StationPort;
+ EFI_IPv4_ADDRESS RemoteAddress;
+ UINT16 RemotePort;
+} EFI_UDP4_CONFIG_DATA;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_GET_MODE_DATA) (
+ IN struct _EFI_UDP4 *This,
+ OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL,
+ OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_CONFIGURE) (
+ IN struct _EFI_UDP4 *This,
+ IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_GROUPS) (
+ IN struct _EFI_UDP4 *This,
+ IN BOOLEAN JoinFlag,
+ IN EFI_IPv4_ADDRESS *MulticastAddress OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_ROUTES) (
+ IN struct _EFI_UDP4 *This,
+ IN BOOLEAN DeleteRoute,
+ IN EFI_IPv4_ADDRESS *SubnetAddress,
+ IN EFI_IPv4_ADDRESS *SubnetMask,
+ IN EFI_IPv4_ADDRESS *GatewayAddress
+ );
+
+#define EFI_NETWORK_UNREACHABLE EFIERR(100)
+#define EFI_HOST_UNREACHABLE EFIERR(101)
+#define EFI_PROTOCOL_UNREACHABLE EFIERR(102)
+#define EFI_PORT_UNREACHABLE EFIERR(103)
+
+typedef struct {
+ EFI_IPv4_ADDRESS SourceAddress;
+ UINT16 SourcePort;
+ EFI_IPv4_ADDRESS DestinationAddress;
+ UINT16 DestinationPort;
+} EFI_UDP4_SESSION_DATA;
+
+typedef struct {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_UDP4_FRAGMENT_DATA;
+
+typedef struct {
+ EFI_TIME TimeStamp;
+ EFI_EVENT RecycleSignal;
+ EFI_UDP4_SESSION_DATA UdpSession;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_UDP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_UDP4_RECEIVE_DATA;
+
+typedef struct {
+ EFI_UDP4_SESSION_DATA *UdpSessionData;
+ EFI_IPv4_ADDRESS *GatewayAddress;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_UDP4_FRAGMENT_DATA FragmentTable[1];
+} EFI_UDP4_TRANSMIT_DATA;
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ union {
+ EFI_UDP4_RECEIVE_DATA *RxData;
+ EFI_UDP4_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_UDP4_COMPLETION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_TRANSMIT) (
+ IN struct _EFI_UDP4 *This,
+ IN EFI_UDP4_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_RECEIVE) (
+ IN struct _EFI_UDP4 *This,
+ IN EFI_UDP4_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_CANCEL)(
+ IN struct _EFI_UDP4 *This,
+ IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP4_POLL) (
+ IN struct _EFI_UDP4 *This
+ );
+
+typedef struct _EFI_UDP4 {
+ EFI_UDP4_GET_MODE_DATA GetModeData;
+ EFI_UDP4_CONFIGURE Configure;
+ EFI_UDP4_GROUPS Groups;
+ EFI_UDP4_ROUTES Routes;
+ EFI_UDP4_TRANSMIT Transmit;
+ EFI_UDP4_RECEIVE Receive;
+ EFI_UDP4_CANCEL Cancel;
+ EFI_UDP4_POLL Poll;
+} EFI_UDP4;
+
+typedef struct {
+ BOOLEAN AcceptPromiscuous;
+ BOOLEAN AcceptAnyPort;
+ BOOLEAN AllowDuplicatePort;
+ UINT8 TrafficClass;
+ UINT8 HopLimit;
+ UINT32 ReceiveTimeout;
+ UINT32 TransmitTimeout;
+ EFI_IPv6_ADDRESS StationAddress;
+ UINT16 StationPort;
+ EFI_IPv6_ADDRESS RemoteAddress;
+ UINT16 RemotePort;
+} EFI_UDP6_CONFIG_DATA;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_GET_MODE_DATA) (
+ IN struct _EFI_UDP6 *This,
+ OUT EFI_UDP6_CONFIG_DATA *Udp6ConfigData OPTIONAL,
+ OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_CONFIGURE) (
+ IN struct _EFI_UDP6 *This,
+ IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_GROUPS) (
+ IN struct _EFI_UDP6 *This,
+ IN BOOLEAN JoinFlag,
+ IN EFI_IPv6_ADDRESS *MulticastAddress OPTIONAL
+ );
+
+typedef struct {
+ EFI_IPv6_ADDRESS SourceAddress;
+ UINT16 SourcePort;
+ EFI_IPv6_ADDRESS DestinationAddress;
+ UINT16 DestinationPort;
+} EFI_UDP6_SESSION_DATA;
+
+typedef struct {
+ UINT32 FragmentLength;
+ VOID *FragmentBuffer;
+} EFI_UDP6_FRAGMENT_DATA;
+
+typedef struct {
+ EFI_TIME TimeStamp;
+ EFI_EVENT RecycleSignal;
+ EFI_UDP6_SESSION_DATA UdpSession;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_UDP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_UDP6_RECEIVE_DATA;
+
+typedef struct {
+ EFI_UDP6_SESSION_DATA *UdpSessionData;
+ UINT32 DataLength;
+ UINT32 FragmentCount;
+ EFI_UDP6_FRAGMENT_DATA FragmentTable[1];
+} EFI_UDP6_TRANSMIT_DATA;
+
+typedef struct {
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ union {
+ EFI_UDP6_RECEIVE_DATA *RxData;
+ EFI_UDP6_TRANSMIT_DATA *TxData;
+ } Packet;
+} EFI_UDP6_COMPLETION_TOKEN;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_TRANSMIT) (
+ IN struct _EFI_UDP6 *This,
+ IN EFI_UDP6_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_RECEIVE) (
+ IN struct _EFI_UDP6 *This,
+ IN EFI_UDP6_COMPLETION_TOKEN *Token
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_CANCEL)(
+ IN struct _EFI_UDP6 *This,
+ IN EFI_UDP6_COMPLETION_TOKEN *Token OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_POLL) (
+ IN struct _EFI_UDP6 *This
+ );
+
+typedef struct _EFI_UDP6 {
+ EFI_UDP6_GET_MODE_DATA GetModeData;
+ EFI_UDP6_CONFIGURE Configure;
+ EFI_UDP6_GROUPS Groups;
+ EFI_UDP6_TRANSMIT Transmit;
+ EFI_UDP6_RECEIVE Receive;
+ EFI_UDP6_CANCEL Cancel;
+ EFI_UDP6_POLL Poll;
+} EFI_UDP6;
+
+#endif /* _EFI_UDP_H */
diff --git a/usr/src/boot/sys/boot/efi/include/efiuga.h b/usr/src/boot/sys/boot/efi/include/efiuga.h
new file mode 100644
index 0000000000..6dfaf500b2
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/efiuga.h
@@ -0,0 +1,168 @@
+/* $FreeBSD$ */
+/** @file
+ UGA Draw protocol from the EFI 1.1 specification.
+
+ Abstraction of a very simple graphics device.
+
+ Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at:
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ File name: UgaDraw.h
+
+**/
+
+#ifndef __UGA_DRAW_H__
+#define __UGA_DRAW_H__
+
+#define EFI_UGA_DRAW_PROTOCOL_GUID \
+ { 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39} }
+
+typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param HorizontalResolution Current video horizontal resolution in pixels
+ @param VerticalResolution Current video vertical resolution in pixels
+ @param ColorDepth Current video color depth in bits per pixel
+ @param RefreshRate Current video refresh rate in Hz.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) (
+ IN EFI_UGA_DRAW_PROTOCOL *This,
+ OUT UINT32 *HorizontalResolution,
+ OUT UINT32 *VerticalResolution,
+ OUT UINT32 *ColorDepth,
+ OUT UINT32 *RefreshRate
+ )
+;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param HorizontalResolution Current video horizontal resolution in pixels
+ @param VerticalResolution Current video vertical resolution in pixels
+ @param ColorDepth Current video color depth in bits per pixel
+ @param RefreshRate Current video refresh rate in Hz.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) (
+ IN EFI_UGA_DRAW_PROTOCOL *This,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ )
+;
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_UGA_PIXEL;
+
+typedef union {
+ EFI_UGA_PIXEL Pixel;
+ UINT32 Raw;
+} EFI_UGA_PIXEL_UNION;
+
+typedef enum {
+ EfiUgaVideoFill,
+ EfiUgaVideoToBltBuffer,
+ EfiUgaBltBufferToVideo,
+ EfiUgaVideoToVideo,
+ EfiUgaBltMax
+} EFI_UGA_BLT_OPERATION;
+
+/**
+ Type specifying a pointer to a function to perform an UGA Blt operation.
+
+ The following table defines actions for BltOperations:
+
+ <B>EfiUgaVideoFill</B> - Write data from the BltBuffer pixel (SourceX, SourceY)
+ directly to every pixel of the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ Only one pixel will be used from the BltBuffer. Delta is NOT used.
+
+ <B>EfiUgaVideoToBltBuffer</B> - Read data from the video display rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
+ the BltBuffer rectangle (DestinationX, DestinationY )
+ (DestinationX + Width, DestinationY + Height). If DestinationX or
+ DestinationY is not zero then Delta must be set to the length in bytes
+ of a row in the BltBuffer.
+
+ <B>EfiUgaBltBufferToVideo</B> - Write data from the BltBuffer rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
+ video display rectangle (DestinationX, DestinationY)
+ (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
+ not zero then Delta must be set to the length in bytes of a row in the
+ BltBuffer.
+
+ <B>EfiUgaVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY)
+ (SourceX + Width, SourceY + Height) .to the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ The BltBuffer and Delta are not used in this mode.
+
+
+ @param[in] This - Protocol instance pointer.
+ @param[in] BltBuffer - Buffer containing data to blit into video buffer. This
+ buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
+ @param[in] BltOperation - Operation to perform on BlitBuffer and video memory
+ @param[in] SourceX - X coordinate of source for the BltBuffer.
+ @param[in] SourceY - Y coordinate of source for the BltBuffer.
+ @param[in] DestinationX - X coordinate of destination for the BltBuffer.
+ @param[in] DestinationY - Y coordinate of destination for the BltBuffer.
+ @param[in] Width - Width of rectangle in BltBuffer in pixels.
+ @param[in] Height - Hight of rectangle in BltBuffer in pixels.
+ @param[in] Delta - OPTIONAL
+
+ @retval EFI_SUCCESS - The Blt operation completed.
+ @retval EFI_INVALID_PARAMETER - BltOperation is not valid.
+ @retval EFI_DEVICE_ERROR - A hardware error occured writting to the video buffer.
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) (
+ IN EFI_UGA_DRAW_PROTOCOL * This,
+ IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL
+ IN EFI_UGA_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ );
+
+struct _EFI_UGA_DRAW_PROTOCOL {
+ EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode;
+ EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode;
+ EFI_UGA_DRAW_PROTOCOL_BLT Blt;
+};
+
+extern EFI_GUID gEfiUgaDrawProtocolGuid;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/include/i386/efibind.h b/usr/src/boot/sys/boot/efi/include/i386/efibind.h
new file mode 100644
index 0000000000..6e5a7163a9
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/i386/efibind.h
@@ -0,0 +1,267 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efefind.h
+
+Abstract:
+
+ EFI to compile bindings
+
+
+
+
+Revision History
+
+--*/
+
+#pragma pack()
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#else
+//
+// Basic int types of various widths
+//
+
+#if (__STDC_VERSION__ < 199901L )
+
+ // No ANSI C 1999/2000 stdint.h integer width declarations
+
+ #ifdef _MSC_EXTENSIONS
+
+ // Use Microsoft C compiler integer width declarations
+
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int32 int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+ #ifdef UNIX_LP64
+
+ // Use LP64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+
+ // Assume P64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #endif
+ #endif
+#endif
+#endif /* __FreeBSD__ */
+
+//
+// Basic EFI types of various widths
+//
+
+#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine, use those */
+#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+
+#ifndef _BASETSD_H_
+ typedef uint32_t UINT32;
+ typedef int32_t INT32;
+#endif
+
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+#endif
+
+#undef VOID
+#define VOID void
+
+
+typedef int32_t INTN;
+typedef uint32_t UINTN;
+
+#ifdef EFI_NT_EMULATOR
+ #define POST_CODE(_Data)
+#else
+ #ifdef EFI_DEBUG
+#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al
+ #else
+ #define POST_CODE(_Data)
+ #endif
+#endif
+
+#define EFIERR(a) (0x80000000 | a)
+#define EFI_ERROR_MASK 0x80000000
+#define EFIERR_OEM(a) (0xc0000000 | a)
+
+
+#define BAD_POINTER 0xFBFBFBFB
+#define MAX_ADDRESS 0xFFFFFFFF
+
+#define BREAKPOINT() __asm { int 3 }
+
+//
+// Pointers must be aligned to these address to function
+//
+
+#define MIN_ALIGNMENT_SIZE 4
+
+#define ALIGN_VARIABLE(Value ,Adjustment) \
+ (UINTN)Adjustment = 0; \
+ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
+ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
+ Value = (UINTN)Value + (UINTN)Adjustment
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+//
+// EFIAPI - prototype calling convention for EFI function pointers
+// BOOTSERVICE - prototype for implementation of a boot service interface
+// RUNTIMESERVICE - prototype for implementation of a runtime service interface
+// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
+// RUNTIME_CODE - pragma macro for declaring runtime code
+//
+
+#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options
+ #ifdef _MSC_EXTENSIONS
+ #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler
+ #else
+ #define EFIAPI // Substitute expresion to force C calling convention
+ #endif
+#endif
+
+#define BOOTSERVICE
+//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a
+//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a
+#define RUNTIMESERVICE
+#define RUNTIMEFUNCTION
+
+
+#define RUNTIME_CODE(a) alloc_text("rtcode", a)
+#define BEGIN_RUNTIME_DATA() data_seg("rtdata")
+#define END_RUNTIME_DATA() data_seg()
+
+#define VOLATILE volatile
+
+#define MEMORY_FENCE()
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+ #define EFI_INTERFACE_DECL(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+ #define EFI_INTERFACE_DECL(x) typedef struct x
+#endif
+
+#ifdef EFI_NT_EMULATOR
+
+//
+// To help ensure proper coding of integrated drivers, they are
+// compiled as DLLs. In NT they require a dll init entry pointer.
+// The macro puts a stub entry point into the DLL so it will load.
+//
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction) \
+ EFI_STATUS \
+ InitFunction ( \
+ EFI_HANDLE ImageHandle, \
+ EFI_SYSTEM_TABLE *SystemTable \
+ ); \
+ \
+ UINTN \
+ __stdcall \
+ _DllMainCRTStartup ( \
+ UINTN Inst, \
+ UINTN reason_for_call, \
+ VOID *rserved \
+ ) \
+ { \
+ return 1; \
+ } \
+ \
+ int \
+ __declspec( dllexport ) \
+ __cdecl \
+ InitializeDriver ( \
+ void *ImageHandle, \
+ void *SystemTable \
+ ) \
+ { \
+ return InitFunction(ImageHandle, SystemTable); \
+ }
+
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, NULL)
+
+#else // EFI_NT_EMULATOR
+
+//
+// When build similiar to FW, then link everything together as
+// one big module.
+//
+
+ #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, entry)
+
+#endif // EFI_FW_NT
+
+#ifdef __FreeBSD__
+#define INTERFACE_DECL(x) struct x
+#else
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX
+//
+// The following macro provide a workaround for such cases.
+//
+#ifdef NO_INTERFACE_DECL
+#define INTERFACE_DECL(x)
+#else
+#define INTERFACE_DECL(x) typedef struct x
+#endif
+#endif /* __FreeBSD__ */
+
+#ifdef _MSC_EXTENSIONS
+#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP
+#endif
+
diff --git a/usr/src/boot/sys/boot/efi/include/i386/pe.h b/usr/src/boot/sys/boot/efi/include/i386/pe.h
new file mode 100644
index 0000000000..e2ae25c3dd
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/include/i386/pe.h
@@ -0,0 +1,630 @@
+/* $FreeBSD$ */
+/*
+ PE32+ header file
+ */
+#ifndef _PE_H
+#define _PE_H
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define IMAGE_OS2_SIGNATURE 0x454E // NE
+#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+
+
+typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
+ UINT16 ne_magic; // Magic number
+ UINT8 ne_ver; // Version number
+ UINT8 ne_rev; // Revision number
+ UINT16 ne_enttab; // Offset of Entry Table
+ UINT16 ne_cbenttab; // Number of bytes in Entry Table
+ UINT32 ne_crc; // Checksum of whole file
+ UINT16 ne_flags; // Flag UINT16
+ UINT16 ne_autodata; // Automatic data segment number
+ UINT16 ne_heap; // Initial heap allocation
+ UINT16 ne_stack; // Initial stack allocation
+ UINT32 ne_csip; // Initial CS:IP setting
+ UINT32 ne_sssp; // Initial SS:SP setting
+ UINT16 ne_cseg; // Count of file segments
+ UINT16 ne_cmod; // Entries in Module Reference Table
+ UINT16 ne_cbnrestab; // Size of non-resident name table
+ UINT16 ne_segtab; // Offset of Segment Table
+ UINT16 ne_rsrctab; // Offset of Resource Table
+ UINT16 ne_restab; // Offset of resident name table
+ UINT16 ne_modtab; // Offset of Module Reference Table
+ UINT16 ne_imptab; // Offset of Imported Names Table
+ UINT32 ne_nrestab; // Offset of Non-resident Names Table
+ UINT16 ne_cmovent; // Count of movable entries
+ UINT16 ne_align; // Segment alignment shift count
+ UINT16 ne_cres; // Count of resource segments
+ UINT8 ne_exetyp; // Target Operating system
+ UINT8 ne_flagsothers; // Other .EXE flags
+ UINT16 ne_pretthunks; // offset to return thunks
+ UINT16 ne_psegrefbytes; // offset to segment ref. bytes
+ UINT16 ne_swaparea; // Minimum code swap area size
+ UINT16 ne_expver; // Expected Windows version number
+ } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
+
+//
+// File header format.
+//
+
+typedef struct _IMAGE_FILE_HEADER {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
+#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
+#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
+#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
+#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// Directory format.
+//
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+//
+// Optional header format.
+//
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ //
+ // Standard fields.
+ //
+
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+
+ //
+ // NT additional fields.
+ //
+
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Reserved1;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
+
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
+
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+
+typedef struct _IMAGE_NT_HEADERS {
+ UINT32 Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+typedef struct _IMAGE_ROM_HEADERS {
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
+
+#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
+ ((UINT32)ntheader + \
+ FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
+ ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
+ ))
+
+
+// Subsystem Values
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
+#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
+#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
+
+
+// Directory Entries
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
+#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
+
+//
+// Section header format.
+//
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ UINT8 Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
+
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
+#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
+#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
+#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
+
+//
+// Symbol format.
+//
+
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+
+#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common.
+#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value.
+#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item.
+
+//
+// Type (fundamental) values.
+//
+
+#define IMAGE_SYM_TYPE_NULL 0 // no type.
+#define IMAGE_SYM_TYPE_VOID 1 //
+#define IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define IMAGE_SYM_TYPE_INT 4 //
+#define IMAGE_SYM_TYPE_LONG 5 //
+#define IMAGE_SYM_TYPE_FLOAT 6 //
+#define IMAGE_SYM_TYPE_DOUBLE 7 //
+#define IMAGE_SYM_TYPE_STRUCT 8 //
+#define IMAGE_SYM_TYPE_UNION 9 //
+#define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define IMAGE_SYM_TYPE_BYTE 12 //
+#define IMAGE_SYM_TYPE_WORD 13 //
+#define IMAGE_SYM_TYPE_UINT 14 //
+#define IMAGE_SYM_TYPE_DWORD 15 //
+
+//
+// Type (derived) values.
+//
+
+#define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
+#define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
+#define IMAGE_SYM_DTYPE_ARRAY 3 // array.
+
+//
+// Storage classes.
+//
+
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
+#define IMAGE_SYM_CLASS_NULL 0
+#define IMAGE_SYM_CLASS_AUTOMATIC 1
+#define IMAGE_SYM_CLASS_EXTERNAL 2
+#define IMAGE_SYM_CLASS_STATIC 3
+#define IMAGE_SYM_CLASS_REGISTER 4
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define IMAGE_SYM_CLASS_LABEL 6
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define IMAGE_SYM_CLASS_ARGUMENT 9
+#define IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define IMAGE_SYM_CLASS_UNION_TAG 12
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define IMAGE_SYM_CLASS_ENUM_TAG 15
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define IMAGE_SYM_CLASS_BIT_FIELD 18
+#define IMAGE_SYM_CLASS_BLOCK 100
+#define IMAGE_SYM_CLASS_FUNCTION 101
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define IMAGE_SYM_CLASS_FILE 103
+// new
+#define IMAGE_SYM_CLASS_SECTION 104
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+// type packing constants
+
+#define N_BTMASK 017
+#define N_TMASK 060
+#define N_TMASK1 0300
+#define N_TMASK2 0360
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+// MACROS
+
+//
+// Communal selection types.
+//
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+
+//
+// Relocation format.
+//
+
+typedef struct _IMAGE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} IMAGE_RELOCATION;
+
+#define IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+
+#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define IMAGE_REL_I386_SECTION 012
+#define IMAGE_REL_I386_SECREL 013
+#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
+
+//
+// MIPS relocation types.
+//
+
+#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_MIPS_REFHALF 01
+#define IMAGE_REL_MIPS_REFWORD 02
+#define IMAGE_REL_MIPS_JMPADDR 03
+#define IMAGE_REL_MIPS_REFHI 04
+#define IMAGE_REL_MIPS_REFLO 05
+#define IMAGE_REL_MIPS_GPREL 06
+#define IMAGE_REL_MIPS_LITERAL 07
+#define IMAGE_REL_MIPS_SECTION 012
+#define IMAGE_REL_MIPS_SECREL 013
+#define IMAGE_REL_MIPS_REFWORDNB 042
+#define IMAGE_REL_MIPS_PAIR 045
+
+//
+// Alpha Relocation types.
+//
+
+#define IMAGE_REL_ALPHA_ABSOLUTE 0x0
+#define IMAGE_REL_ALPHA_REFLONG 0x1
+#define IMAGE_REL_ALPHA_REFQUAD 0x2
+#define IMAGE_REL_ALPHA_GPREL32 0x3
+#define IMAGE_REL_ALPHA_LITERAL 0x4
+#define IMAGE_REL_ALPHA_LITUSE 0x5
+#define IMAGE_REL_ALPHA_GPDISP 0x6
+#define IMAGE_REL_ALPHA_BRADDR 0x7
+#define IMAGE_REL_ALPHA_HINT 0x8
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
+#define IMAGE_REL_ALPHA_REFHI 0xA
+#define IMAGE_REL_ALPHA_REFLO 0xB
+#define IMAGE_REL_ALPHA_PAIR 0xC
+#define IMAGE_REL_ALPHA_MATCH 0xD
+#define IMAGE_REL_ALPHA_SECTION 0xE
+#define IMAGE_REL_ALPHA_SECREL 0xF
+#define IMAGE_REL_ALPHA_REFLONGNB 0x10
+
+//
+// IBM PowerPC relocation types.
+//
+
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
+#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
+#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
+#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
+#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
+#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
+#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
+#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
+#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
+#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
+
+#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
+#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
+#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
+#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
+#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
+
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
+
+// Flag bits in IMAGE_RELOCATION.TYPE
+
+#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
+#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
+#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
+
+//
+// Based relocation format.
+//
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+// UINT16 TypeOffset[1];
+} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_DIR64 10
+
+//
+// Line number format.
+//
+
+typedef struct _IMAGE_LINENUMBER {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} IMAGE_LINENUMBER;
+
+#define IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+
+//
+// Export Format
+//
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 *AddressOfFunctions;
+ UINT32 *AddressOfNames;
+ UINT32 *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+//
+// Import Format
+//
+
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ UINT16 Hint;
+ UINT8 Name[1];
+} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
+
+typedef struct _IMAGE_THUNK_DATA {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ PIMAGE_IMPORT_BY_NAME AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
+
+#define IMAGE_ORDINAL_FLAG 0x80000000
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
+#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ PIMAGE_THUNK_DATA FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
+
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Type;
+ UINT32 SizeOfData;
+ UINT32 RVA;
+ UINT32 FileOffset;
+} IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
+
+typedef struct {
+ UINT32 Signature; // "NB10"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS"
+
+typedef struct {
+ UINT32 Signature; // "RSDS"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ UINT32 Unknown4;
+ UINT32 Unknown5;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+#endif
diff --git a/usr/src/boot/sys/boot/efi/libefi/Makefile b/usr/src/boot/sys/boot/efi/libefi/Makefile
new file mode 100644
index 0000000000..38a544f743
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/Makefile
@@ -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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+CC= $(GCC_ROOT)/bin/gcc
+
+LIB= efi
+
+all: machine x86 lib$(LIB).a
+install:
+
+SRCS= delay.c efi_console.c efinet.c efipart.c errno.c handles.c \
+ libefi.c time.c
+
+OBJS= $(SRCS:%.c=%.o)
+
+CPPFLAGS= -DTERM_EMU
+CFLAGS = -O2
+
+#.if ${MACHINE_CPUARCH} == "aarch64"
+#CFLAGS+= -msoft-float -mgeneral-regs-only
+#.endif
+#.if ${MACHINE_ARCH} == "amd64"
+CFLAGS += -fPIC
+#.endif
+
+CFLAGS += -nostdinc -I. -I../../../../include -I../../..
+CFLAGS += -I../include
+CFLAGS += -I../include/${MACH64}
+CFLAGS += -I../../../../lib/libstand
+
+# Pick up the bootstrap header for some interface items
+CFLAGS += -I../../common
+
+# Handle FreeBSD specific %b and %D printf format specifiers
+# CFLAGS+= ${FORMAT_EXTENSIONS}
+# CFLAGS += -D__printf__=__freebsd_kprintf__
+CFLAGS+= -DTERM_EMU
+
+include ../Makefile.inc
+
+lib$(LIB).a: $(SRCS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean: clobber
+clobber:
+ $(RM) $(CLEANFILES) $(OBJS) machine x86 lib$(LIB).a
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../amd64/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
diff --git a/usr/src/boot/sys/boot/efi/libefi/delay.c b/usr/src/boot/sys/boot/efi/libefi/delay.c
new file mode 100644
index 0000000000..c805fa13a7
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/delay.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2001 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+void delay(int);
+
+void
+delay(int usecs)
+{
+ static EFI_EVENT ev = 0;
+ UINTN junk;
+
+ if (!ev) {
+ if (BS->CreateEvent(EVT_TIMER, TPL_APPLICATION, 0, 0, &ev)
+ != EFI_SUCCESS)
+ return;
+ }
+
+ BS->SetTimer(ev, TimerRelative, usecs * 10);
+ BS->WaitForEvent(1, &ev, &junk);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/efi_console.c b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
new file mode 100644
index 0000000000..2b46019bc1
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
@@ -0,0 +1,589 @@
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+
+static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+static SIMPLE_INPUT_INTERFACE *conin;
+
+#ifdef TERM_EMU
+#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
+#define DEFAULT_BGCOLOR EFI_BLACK
+
+#define MAXARGS 8
+#define KEYBUFSZ 10
+static unsigned keybuf[KEYBUFSZ]; /* keybuf for extended codes */
+static int args[MAXARGS], argc;
+static int fg_c, bg_c;
+static UINTN curx, cury;
+static int esc;
+
+void get_pos(UINTN *x, UINTN *y);
+void curs_move(UINTN *_x, UINTN *_y, UINTN x, UINTN y);
+static void CL(int);
+void HO(void);
+void end_term(void);
+#endif
+
+static void efi_cons_probe(struct console *);
+static int efi_cons_init(struct console *, int);
+void efi_cons_putchar(struct console *, int);
+int efi_cons_getchar(struct console *);
+void efi_cons_efiputchar(int);
+int efi_cons_poll(struct console *);
+
+struct console efi_console = {
+ "text",
+ "EFI console",
+ 0,
+ efi_cons_probe,
+ efi_cons_init,
+ efi_cons_putchar,
+ efi_cons_getchar,
+ efi_cons_poll,
+ 0
+};
+
+#ifdef TERM_EMU
+
+/* Get cursor position. */
+void
+get_pos(UINTN *x, UINTN *y)
+{
+ *x = conout->Mode->CursorColumn;
+ *y = conout->Mode->CursorRow;
+}
+
+/* Move cursor to x rows and y cols (0-based). */
+void
+curs_move(UINTN *_x, UINTN *_y, UINTN x, UINTN y)
+{
+ conout->SetCursorPosition(conout, x, y);
+ if (_x != NULL)
+ *_x = conout->Mode->CursorColumn;
+ if (_y != NULL)
+ *_y = conout->Mode->CursorRow;
+}
+
+/* Clear internal state of the terminal emulation code. */
+void
+end_term(void)
+{
+ esc = 0;
+ argc = -1;
+}
+
+#endif
+
+static void
+efi_cons_probe(struct console *cp)
+{
+ conout = ST->ConOut;
+ conin = ST->ConIn;
+ cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
+}
+
+static int
+efi_cons_init(struct console *cp __attribute((unused)),
+ int arg __attribute((unused)))
+{
+ conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
+ DEFAULT_BGCOLOR));
+#ifdef TERM_EMU
+ end_term();
+ get_pos(&curx, &cury);
+ curs_move(&curx, &cury, curx, cury);
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ memset(keybuf, 0, KEYBUFSZ);
+#endif
+ conout->EnableCursor(conout, TRUE);
+ return 0;
+}
+
+static void
+efi_cons_rawputchar(int c)
+{
+ int i;
+ UINTN x, y;
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+ static int ignorenl = 0;
+
+ if (c == '\t')
+ /* XXX lame tab expansion */
+ for (i = 0; i < 8; i++)
+ efi_cons_rawputchar(' ');
+ else {
+#ifndef TERM_EMU
+ if (c == '\n')
+ efi_cons_efiputchar('\r');
+ else
+ efi_cons_efiputchar(c);
+#else
+ switch (c) {
+ case '\r':
+ curx = 0;
+ break;
+ case '\n':
+ if (ignorenl)
+ ignorenl = 0;
+ else
+ cury++;
+ if ((efi_console.c_flags & C_MODERAW) == 0)
+ curx = 0;
+ if (cury >= y) {
+ efi_cons_efiputchar('\n');
+ cury--;
+ }
+ break;
+ case '\b':
+ if (curx > 0)
+ curx--;
+ break;
+ default:
+ if (curx > x) {
+ curx = 0;
+ cury++;
+ curs_move(&curx, &cury, curx, cury);
+ }
+ if ((efi_console.c_flags & C_MODERAW) == 0) {
+ if (cury > y-1) {
+ curx = 0;
+ efi_cons_efiputchar('\n');
+ cury--;
+ curs_move(&curx, &cury, curx, cury);
+ }
+ }
+ efi_cons_efiputchar(c);
+ curx++;
+ if ((efi_console.c_flags & C_MODERAW) == 0) {
+ if (curx == x) {
+ curx = 0;
+ ignorenl = 1;
+ }
+ } else if (curx == x) {
+ curx = 0;
+ if (cury == y)
+ efi_cons_efiputchar('\n');
+ else
+ cury++;
+ }
+ }
+ curs_move(&curx, &cury, curx, cury);
+#endif
+ }
+}
+
+/* Gracefully exit ESC-sequence processing in case of misunderstanding. */
+static void
+bail_out(int c)
+{
+ char buf[16], *ch;
+ int i;
+
+ if (esc) {
+ efi_cons_rawputchar('\033');
+ if (esc != '\033')
+ efi_cons_rawputchar(esc);
+ for (i = 0; i <= argc; ++i) {
+ sprintf(buf, "%d", args[i]);
+ ch = buf;
+ while (*ch)
+ efi_cons_rawputchar(*ch++);
+ }
+ }
+ efi_cons_rawputchar(c);
+ end_term();
+}
+
+/* Clear display from current position to end of screen. */
+static void
+CD(void) {
+ UINTN i, x, y;
+
+ get_pos(&curx, &cury);
+ if (curx == 0 && cury == 0) {
+ conout->ClearScreen(conout);
+ end_term();
+ return;
+ }
+
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+ CL(0); /* clear current line from cursor to end */
+ for (i = cury + 1; i < y-1; i++) {
+ curs_move(NULL, NULL, 0, i);
+ CL(0);
+ }
+ curs_move(NULL, NULL, curx, cury);
+ end_term();
+}
+
+/*
+ * Absolute cursor move to args[0] rows and args[1] columns
+ * (the coordinates are 1-based).
+ */
+static void
+CM(void)
+{
+ if (args[0] > 0)
+ args[0]--;
+ if (args[1] > 0)
+ args[1]--;
+ curs_move(&curx, &cury, args[1], args[0]);
+ end_term();
+}
+
+/* Home cursor (left top corner), also called from mode command. */
+void
+HO(void)
+{
+ argc = 1;
+ args[0] = args[1] = 1;
+ CM();
+}
+
+/* Clear line from current position to end of line */
+static void
+CL(int direction)
+{
+ int i, len;
+ UINTN x, y;
+ CHAR16 *line;
+
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+ switch (direction) {
+ case 0: /* from cursor to end */
+ len = x - curx + 1;
+ break;
+ case 1: /* from beginning to cursor */
+ len = curx;
+ break;
+ case 2: /* entire line */
+ default:
+ len = x;
+ break;
+ }
+
+ if (cury == y - 1)
+ len--;
+
+ line = malloc(len * sizeof (CHAR16));
+ if (line == NULL) {
+ printf("out of memory\n");
+ return;
+ }
+ for (i = 0; i < len; i++)
+ line[i] = ' ';
+ line[len-1] = 0;
+
+ if (direction != 0)
+ curs_move(NULL, NULL, 0, cury);
+
+ conout->OutputString(conout, line);
+ /* restore cursor position */
+ curs_move(NULL, NULL, curx, cury);
+ free(line);
+ end_term();
+}
+
+static void
+get_arg(int c)
+{
+ if (argc < 0)
+ argc = 0;
+ args[argc] *= 10;
+ args[argc] += c - '0';
+}
+
+/* Emulate basic capabilities of sun-color terminal */
+static void
+efi_term_emu(int c)
+{
+ static int ansi_col[] = {
+ 0, 4, 2, 6, 1, 5, 3, 7
+ };
+ int t, i;
+
+ switch (esc) {
+ case 0:
+ switch (c) {
+ case '\033':
+ esc = c;
+ break;
+ default:
+ efi_cons_rawputchar(c);
+ break;
+ }
+ break;
+ case '\033':
+ switch (c) {
+ case '[':
+ esc = c;
+ args[0] = 0;
+ argc = -1;
+ break;
+ default:
+ bail_out(c);
+ break;
+ }
+ break;
+ case '[':
+ switch (c) {
+ case ';':
+ if (argc < 0)
+ argc = 0;
+ else if (argc + 1 >= MAXARGS)
+ bail_out(c);
+ else
+ args[++argc] = 0;
+ break;
+ case 'A': /* UP = \E[%dA */
+ if (argc == 0) {
+ UINTN x, y;
+ get_pos(&x, &y);
+ args[1] = x + 1;
+ args[0] = y - args[0] + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'B': /* DO = \E[%dB */
+ if (argc == 0) {
+ UINTN x, y;
+ get_pos(&x, &y);
+ args[1] = x + 1;
+ args[0] = y + args[0] + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'C': /* RI = \E[%dC */
+ if (argc == 0) {
+ UINTN x, y;
+ get_pos(&x, &y);
+ args[1] = args[0] + 1;
+ args[0] = y + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'H': /* ho = \E[H */
+ if (argc < 0)
+ HO();
+ else if (argc == 1)
+ CM();
+ else
+ bail_out(c);
+ break;
+ case 'J': /* cd = \E[J */
+ if (argc < 0)
+ CD();
+ else
+ bail_out(c);
+ break;
+ case 'K':
+ if (argc < 0)
+ CL(0);
+ else if (argc == 0)
+ switch (args[0]) {
+ case 0:
+ case 1:
+ case 2:
+ CL(args[0]);
+ break;
+ default:
+ bail_out(c);
+ }
+ else
+ bail_out(c);
+ break;
+ case 'm':
+ if (argc < 0) {
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ }
+ for (i = 0; i <= argc; ++i) {
+ switch (args[i]) {
+ case 0: /* back to normal */
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ case 1: /* bold */
+ fg_c |= 0x8;
+ break;
+ case 4: /* underline */
+ case 5: /* blink */
+ bg_c |= 0x8;
+ break;
+ case 7: /* reverse */
+ t = fg_c;
+ fg_c = bg_c;
+ bg_c = t;
+ break;
+ case 30: case 31: case 32: case 33:
+ case 34: case 35: case 36: case 37:
+ fg_c = ansi_col[args[i] - 30];
+ break;
+ case 39: /* normal */
+ fg_c = DEFAULT_FGCOLOR;
+ break;
+ case 40: case 41: case 42: case 43:
+ case 44: case 45: case 46: case 47:
+ bg_c = ansi_col[args[i] - 40];
+ break;
+ case 49: /* normal */
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ }
+ }
+ conout->SetAttribute(conout, EFI_TEXT_ATTR(fg_c, bg_c));
+ end_term();
+ break;
+ default:
+ if (isdigit(c))
+ get_arg(c);
+ else
+ bail_out(c);
+ break;
+ }
+ break;
+ default:
+ bail_out(c);
+ break;
+ }
+}
+
+void
+efi_cons_putchar(struct console *cp __attribute((unused)), int c)
+{
+#ifdef TERM_EMU
+ efi_term_emu(c);
+#else
+ efi_cons_rawputchar(c);
+#endif
+}
+
+int
+efi_cons_getchar(struct console *cp __attribute((unused)))
+{
+ EFI_INPUT_KEY key;
+ EFI_STATUS status;
+ UINTN junk;
+ int i, c;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0) {
+ c = keybuf[i];
+ keybuf[i] = 0;
+ return (c);
+ }
+ }
+
+ /* Try to read a key stroke. We wait for one if none is pending. */
+ status = conin->ReadKeyStroke(conin, &key);
+ if (status == EFI_NOT_READY) {
+ BS->WaitForEvent(1, &conin->WaitForKey, &junk);
+ status = conin->ReadKeyStroke(conin, &key);
+ }
+
+ switch (key.ScanCode) {
+ case 0x1: /* UP */
+ keybuf[0] = '[';
+ keybuf[1] = 'A';
+ return (0x1b); /* esc */
+ case 0x2: /* DOWN */
+ keybuf[0] = '[';
+ keybuf[1] = 'B';
+ return (0x1b); /* esc */
+ case 0x3: /* RIGHT */
+ keybuf[0] = '[';
+ keybuf[1] = 'C';
+ return (0x1b); /* esc */
+ case 0x4: /* LEFT */
+ keybuf[0] = '[';
+ keybuf[1] = 'D';
+ return (0x1b); /* esc */
+ case 0x17: /* ESC */
+ return (0x1b); /* esc */
+ }
+
+ /* this can return */
+ return (key.UnicodeChar);
+}
+
+int
+efi_cons_poll(struct console *cp __attribute((unused)))
+{
+ int i;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0)
+ return (1);
+ }
+
+ /* This can clear the signaled state. */
+ return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
+}
+
+/* Plain direct access to EFI OutputString(). */
+void
+efi_cons_efiputchar(int c)
+{
+ CHAR16 buf[2];
+
+ /*
+ * translate box chars to unicode
+ */
+ switch (c) {
+ /* single frame */
+ case 0xb3: buf[0] = BOXDRAW_VERTICAL; break;
+ case 0xbf: buf[0] = BOXDRAW_DOWN_LEFT; break;
+ case 0xc0: buf[0] = BOXDRAW_UP_RIGHT; break;
+ case 0xc4: buf[0] = BOXDRAW_HORIZONTAL; break;
+ case 0xda: buf[0] = BOXDRAW_DOWN_RIGHT; break;
+ case 0xd9: buf[0] = BOXDRAW_UP_LEFT; break;
+
+ /* double frame */
+ case 0xba: buf[0] = BOXDRAW_DOUBLE_VERTICAL; break;
+ case 0xbb: buf[0] = BOXDRAW_DOUBLE_DOWN_LEFT; break;
+ case 0xbc: buf[0] = BOXDRAW_DOUBLE_UP_LEFT; break;
+ case 0xc8: buf[0] = BOXDRAW_DOUBLE_UP_RIGHT; break;
+ case 0xc9: buf[0] = BOXDRAW_DOUBLE_DOWN_RIGHT; break;
+ case 0xcd: buf[0] = BOXDRAW_DOUBLE_HORIZONTAL; break;
+
+ default:
+ buf[0] = c;
+ }
+ buf[1] = 0; /* terminate string */
+
+ conout->OutputString(conout, buf);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/efinet.c b/usr/src/boot/sys/boot/efi/libefi/efinet.c
new file mode 100644
index 0000000000..e48b4a4b72
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/efinet.c
@@ -0,0 +1,340 @@
+/*-
+ * Copyright (c) 2001 Doug Rabson
+ * Copyright (c) 2002, 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <net.h>
+#include <netif.h>
+
+#include <dev_net.c>
+
+#include <efi.h>
+#include <efilib.h>
+
+static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL;
+
+static void efinet_end(struct netif *);
+static int efinet_get(struct iodesc *, void *, size_t, time_t);
+static void efinet_init(struct iodesc *, void *);
+static int efinet_match(struct netif *, void *);
+static int efinet_probe(struct netif *, void *);
+static int efinet_put(struct iodesc *, void *, size_t);
+
+struct netif_driver efinetif = {
+ .netif_bname = "efinet",
+ .netif_match = efinet_match,
+ .netif_probe = efinet_probe,
+ .netif_init = efinet_init,
+ .netif_get = efinet_get,
+ .netif_put = efinet_put,
+ .netif_end = efinet_end,
+ .netif_ifs = NULL,
+ .netif_nifs = 0
+};
+
+#ifdef EFINET_DEBUG
+static void
+dump_mode(EFI_SIMPLE_NETWORK_MODE *mode)
+{
+ int i;
+
+ printf("State = %x\n", mode->State);
+ printf("HwAddressSize = %u\n", mode->HwAddressSize);
+ printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize);
+ printf("MaxPacketSize = %u\n", mode->MaxPacketSize);
+ printf("NvRamSize = %u\n", mode->NvRamSize);
+ printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize);
+ printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask);
+ printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting);
+ printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount);
+ printf("MCastFilterCount = %u\n", mode->MCastFilterCount);
+ printf("MCastFilter = {");
+ for (i = 0; i < mode->MCastFilterCount; i++)
+ printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr));
+ printf(" }\n");
+ printf("CurrentAddress = %s\n",
+ ether_sprintf(mode->CurrentAddress.Addr));
+ printf("BroadcastAddress = %s\n",
+ ether_sprintf(mode->BroadcastAddress.Addr));
+ printf("PermanentAddress = %s\n",
+ ether_sprintf(mode->PermanentAddress.Addr));
+ printf("IfType = %u\n", mode->IfType);
+ printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable);
+ printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported);
+ printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported);
+ printf("MediaPresent = %d\n", mode->MediaPresent);
+}
+#endif
+
+static int
+efinet_match(struct netif *nif, void *machdep_hint)
+{
+ struct devdesc *dev = machdep_hint;
+
+ if (dev->d_unit - 1 == nif->nif_unit)
+ return (1);
+ return(0);
+}
+
+static int
+efinet_probe(struct netif *nif, void *machdep_hint)
+{
+
+ return (0);
+}
+
+static int
+efinet_put(struct iodesc *desc, void *pkt, size_t len)
+{
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
+ EFI_STATUS status;
+ void *buf;
+
+ net = nif->nif_devdata;
+
+ status = net->Transmit(net, 0, len, pkt, 0, 0, 0);
+ if (status != EFI_SUCCESS)
+ return (-1);
+
+ /* Wait for the buffer to be transmitted */
+ do {
+ buf = 0; /* XXX Is this needed? */
+ status = net->GetStatus(net, 0, &buf);
+ /*
+ * XXX EFI1.1 and the E1000 card returns a different
+ * address than we gave. Sigh.
+ */
+ } while (status == EFI_SUCCESS && buf == 0);
+
+ /* XXX How do we deal with status != EFI_SUCCESS now? */
+ return ((status == EFI_SUCCESS) ? len : -1);
+}
+
+static int
+efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+{
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
+ EFI_STATUS status;
+ UINTN bufsz;
+ time_t t;
+ char buf[2048];
+
+ net = nif->nif_devdata;
+
+ t = time(0);
+ while ((time(0) - t) < timeout) {
+ bufsz = sizeof(buf);
+ status = net->Receive(net, 0, &bufsz, buf, 0, 0, 0);
+ if (status == EFI_SUCCESS) {
+ /*
+ * XXX EFI1.1 and the E1000 card trash our
+ * workspace if we do not do this silly copy.
+ * Either they are not respecting the len
+ * value or do not like the alignment.
+ */
+ if (bufsz > len)
+ bufsz = len;
+ bcopy(buf, pkt, bufsz);
+ return (bufsz);
+ }
+ if (status != EFI_NOT_READY)
+ return (0);
+ }
+
+ return (0);
+}
+
+static void
+efinet_init(struct iodesc *desc, void *machdep_hint)
+{
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+
+ if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) {
+ printf("Invalid network interface %d\n", nif->nif_unit);
+ return;
+ }
+
+ h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
+ status = BS->HandleProtocol(h, &sn_guid, (VOID **)&nif->nif_devdata);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot start interface (status=%lu)\n",
+ nif->nif_unit, EFI_ERROR_CODE(status));
+ return;
+ }
+
+ net = nif->nif_devdata;
+ if (net->Mode->State == EfiSimpleNetworkStopped) {
+ status = net->Start(net);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot start interface (status=%ld)\n",
+ nif->nif_unit, (long)status);
+ return;
+ }
+ }
+
+ if (net->Mode->State != EfiSimpleNetworkInitialized) {
+ status = net->Initialize(net, 0, 0);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot init. interface (status=%ld)\n",
+ nif->nif_unit, (long)status);
+ return;
+ }
+ }
+
+ if (net->Mode->ReceiveFilterSetting == 0) {
+ UINT32 mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
+ EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
+
+ status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot set rx. filters (status=%ld)\n",
+ nif->nif_unit, (long)status);
+ return;
+ }
+ }
+
+#ifdef EFINET_DEBUG
+ dump_mode(net->Mode);
+#endif
+
+ bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6);
+ desc->xid = 1;
+}
+
+static void
+efinet_end(struct netif *nif)
+{
+ EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
+
+ net->Shutdown(net);
+}
+
+static int efinet_dev_init(void);
+static int efinet_dev_print(int);
+
+struct devsw efinet_dev = {
+ .dv_name = "net",
+ .dv_type = DEVT_NET,
+ .dv_init = efinet_dev_init,
+ .dv_strategy = net_strategy,
+ .dv_open = net_open,
+ .dv_close = net_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efinet_dev_print,
+ .dv_cleanup = NULL
+};
+
+static int
+efinet_dev_init()
+{
+ struct netif_dif *dif;
+ struct netif_stats *stats;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN sz;
+ int err, i, nifs;
+
+ sz = 0;
+ handles = NULL;
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz,
+ handles);
+ if (EFI_ERROR(status))
+ free(handles);
+ }
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+ nifs = sz / sizeof(EFI_HANDLE);
+ err = efi_register_handles(&efinet_dev, handles, NULL, nifs);
+ free(handles);
+ if (err != 0)
+ return (err);
+
+ efinetif.netif_nifs = nifs;
+ efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
+
+ stats = calloc(nifs, sizeof(struct netif_stats));
+
+ for (i = 0; i < nifs; i++) {
+ EFI_SIMPLE_NETWORK *net;
+ EFI_HANDLE h;
+
+ dif = &efinetif.netif_ifs[i];
+ dif->dif_unit = -1;
+
+ h = efi_find_handle(&efinet_dev, i);
+
+ /*
+ * Open the network device in exclusive mode. Without this
+ * we will be racing with the UEFI network stack. It will
+ * pull packets off the network leading to lost packets.
+ */
+ status = BS->OpenProtocol(h, &sn_guid, (void **)&net,
+ IH, 0, EFI_OPEN_PROTOCOL_EXCLUSIVE);
+ if (status != EFI_SUCCESS) {
+ printf("Unable to open network interface %d for "
+ "exclusive access\n", i);
+ }
+
+ dif->dif_unit = i;
+ dif->dif_nsel = 1;
+ dif->dif_stats = &stats[i];
+ dif->dif_private = h;
+ }
+
+ return (0);
+}
+
+static int
+efinet_dev_print(int verbose)
+{
+ char line[80];
+ EFI_HANDLE h;
+ int unit, ret;
+
+ for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
+ h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
+ sprintf(line, " %s%d:\n", efinet_dev.dv_name, unit);
+ ret = pager_output(line);
+ if (ret)
+ break;
+ }
+ return (ret);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/efipart.c b/usr/src/boot/sys/boot/efi/libefi/efipart.c
new file mode 100644
index 0000000000..c97eb6694a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c
@@ -0,0 +1,372 @@
+/*-
+ * Copyright (c) 2010 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#include <bootstrap.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <efiprot.h>
+
+static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
+static EFI_GUID devpath_guid = DEVICE_PATH_PROTOCOL;
+
+static int efipart_init(void);
+static int efipart_strategy(void *, int, daddr_t, size_t, size_t, char *,
+ size_t *);
+static int efipart_realstrategy(void *, int, daddr_t, size_t, size_t, char *,
+ size_t *);
+static int efipart_open(struct open_file *, ...);
+static int efipart_close(struct open_file *);
+static int efipart_print(int);
+
+struct devsw efipart_dev = {
+ .dv_name = "part",
+ .dv_type = DEVT_DISK,
+ .dv_init = efipart_init,
+ .dv_strategy = efipart_strategy,
+ .dv_open = efipart_open,
+ .dv_close = efipart_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efipart_print,
+ .dv_cleanup = NULL
+};
+
+/*
+ * info structure to support bcache
+ */
+struct pdinfo
+{
+ int pd_unit; /* unit number */
+ int pd_open; /* reference counter */
+ void *pd_bcache; /* buffer cache data */
+};
+static struct pdinfo *pdinfo;
+static int npdinfo = 0;
+
+#define PD(dev) (pdinfo[(dev)->d_unit])
+
+static int
+efipart_init(void)
+{
+ EFI_BLOCK_IO *blkio;
+ EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node;
+ EFI_HANDLE *hin, *hout, *aliases, handle;
+ EFI_STATUS status;
+ UINTN sz;
+ u_int n, nin, nout;
+ int err;
+ size_t devpathlen;
+
+ sz = 0;
+ hin = NULL;
+ status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ hin = (EFI_HANDLE *)malloc(sz * 3);
+ status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
+ hin);
+ if (EFI_ERROR(status))
+ free(hin);
+ }
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ /* Filter handles to only include illumos partitions. */
+ nin = sz / sizeof(EFI_HANDLE);
+ hout = hin + nin;
+ aliases = hout + nin;
+ nout = 0;
+
+ bzero(aliases, nin * sizeof(EFI_HANDLE));
+ pdinfo = malloc(nin * sizeof(*pdinfo));
+ if (pdinfo == NULL)
+ return (ENOMEM);
+
+ for (n = 0; n < nin; n++) {
+ status = BS->HandleProtocol(hin[n], &devpath_guid,
+ (void **)&devpath);
+ if (EFI_ERROR(status)) {
+ continue;
+ }
+
+ node = devpath;
+ devpathlen = DevicePathNodeLength(node);
+ while (!IsDevicePathEnd(NextDevicePathNode(node))) {
+ node = NextDevicePathNode(node);
+ devpathlen += DevicePathNodeLength(node);
+ }
+ devpathlen += DevicePathNodeLength(NextDevicePathNode(node));
+
+ status = BS->HandleProtocol(hin[n], &blkio_guid,
+ (void**)&blkio);
+ if (EFI_ERROR(status))
+ continue;
+ if (!blkio->Media->LogicalPartition)
+ continue;
+
+ /*
+ * If we come across a logical partition of subtype CDROM
+ * it doesn't refer to the CD filesystem itself, but rather
+ * to any usable El Torito boot image on it. In this case
+ * we try to find the parent device and add that instead as
+ * that will be the CD filesystem.
+ */
+ if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType(node) == MEDIA_CDROM_DP) {
+ devpathcpy = malloc(devpathlen);
+ memcpy(devpathcpy, devpath, devpathlen);
+ node = devpathcpy;
+ while (!IsDevicePathEnd(NextDevicePathNode(node)))
+ node = NextDevicePathNode(node);
+ SetDevicePathEndNode(node);
+ tmpdevpath = devpathcpy;
+ status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
+ &handle);
+ free(devpathcpy);
+ if (EFI_ERROR(status))
+ continue;
+ hout[nout] = handle;
+ aliases[nout] = hin[n];
+ } else
+ hout[nout] = hin[n];
+ nout++;
+ pdinfo[npdinfo].pd_open = 0;
+ pdinfo[npdinfo].pd_bcache = NULL;
+ pdinfo[npdinfo].pd_unit = npdinfo;
+ npdinfo++;
+ }
+
+ bcache_add_dev(npdinfo);
+ err = efi_register_handles(&efipart_dev, hout, aliases, nout);
+ free(hin);
+ return (err);
+}
+
+static int
+efipart_print(int verbose)
+{
+ char line[80];
+ EFI_BLOCK_IO *blkio;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+ u_int unit;
+ int ret = 0;
+
+ for (unit = 0, h = efi_find_handle(&efipart_dev, 0);
+ h != NULL; h = efi_find_handle(&efipart_dev, ++unit)) {
+ sprintf(line, " %s%d:", efipart_dev.dv_name, unit);
+ ret = pager_output(line);
+
+ status = BS->HandleProtocol(h, &blkio_guid, (void **)&blkio);
+ if (!EFI_ERROR(status)) {
+ sprintf(line, " %llu blocks",
+ (unsigned long long)(blkio->Media->LastBlock + 1));
+ ret = pager_output(line);
+ if (blkio->Media->RemovableMedia)
+ ret = pager_output(" (removable)");
+ }
+ ret = pager_output("\n");
+ if (ret != 0)
+ break;
+ }
+ return (ret);
+}
+
+static int
+efipart_open(struct open_file *f, ...)
+{
+ va_list args;
+ struct devdesc *dev;
+ EFI_BLOCK_IO *blkio;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+
+ va_start(args, f);
+ dev = va_arg(args, struct devdesc*);
+ va_end(args);
+
+ h = efi_find_handle(&efipart_dev, dev->d_unit);
+ if (h == NULL)
+ return (EINVAL);
+
+ status = BS->HandleProtocol(h, &blkio_guid, (void **)&blkio);
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ if (!blkio->Media->MediaPresent)
+ return (EAGAIN);
+
+ dev->d_opendata = blkio;
+ PD(dev).pd_open++;
+ if (PD(dev).pd_bcache == NULL)
+ PD(dev).pd_bcache = bcache_allocate();
+ return (0);
+}
+
+static int
+efipart_close(struct open_file *f)
+{
+ struct devdesc *dev;
+
+ dev = (struct devdesc *)(f->f_devdata);
+ if (dev->d_opendata == NULL)
+ return (EINVAL);
+
+ dev->d_opendata = NULL;
+ PD(dev).pd_open--;
+ if (PD(dev).pd_open == 0) {
+ bcache_free(PD(dev).pd_bcache);
+ PD(dev).pd_bcache = NULL;
+ }
+ return (0);
+}
+
+/*
+ * efipart_readwrite()
+ * Internal equivalent of efipart_strategy(), which operates on the
+ * media-native block size. This function expects all I/O requests
+ * to be within the media size and returns an error if such is not
+ * the case.
+ */
+static int
+efipart_readwrite(EFI_BLOCK_IO *blkio, int rw, daddr_t blk, daddr_t nblks,
+ char *buf)
+{
+ EFI_STATUS status;
+
+ if (blkio == NULL)
+ return (ENXIO);
+ if (blk < 0 || blk > blkio->Media->LastBlock)
+ return (EIO);
+ if ((blk + nblks - 1) > blkio->Media->LastBlock)
+ return (EIO);
+
+ switch (rw) {
+ case F_READ:
+ status = blkio->ReadBlocks(blkio, blkio->Media->MediaId, blk,
+ nblks * blkio->Media->BlockSize, buf);
+ break;
+ case F_WRITE:
+ if (blkio->Media->ReadOnly)
+ return (EROFS);
+ status = blkio->WriteBlocks(blkio, blkio->Media->MediaId, blk,
+ nblks * blkio->Media->BlockSize, buf);
+ break;
+ default:
+ return (ENOSYS);
+ }
+
+ if (EFI_ERROR(status))
+ printf("%s: rw=%d, status=%lu\n", __func__, rw, (u_long)status);
+ return (efi_status_to_errno(status));
+}
+
+static int
+efipart_strategy(void *devdata, int rw, daddr_t blk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+ struct bcache_devdata bcd;
+ struct devdesc *dev;
+
+ dev = (struct devdesc *)devdata;
+ bcd.dv_strategy = efipart_realstrategy;
+ bcd.dv_devdata = devdata;
+ bcd.dv_cache = PD(dev).pd_bcache;
+ return (bcache_strategy(&bcd, rw, blk, offset, size,
+ buf, rsize));
+}
+
+static int
+efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+ struct devdesc *dev = (struct devdesc *)devdata;
+ EFI_BLOCK_IO *blkio;
+ off_t off;
+ char *blkbuf;
+ size_t blkoff, blksz;
+ int error;
+
+ if (dev == NULL || blk < 0)
+ return (EINVAL);
+
+ blkio = dev->d_opendata;
+ if (blkio == NULL)
+ return (ENXIO);
+
+ if (size == 0 || (size % 512) != 0)
+ return (EIO);
+
+ off = blk * 512;
+ /* make sure we don't read past disk end */
+ if ((off + size) / blkio->Media->BlockSize - 1 >
+ blkio->Media->LastBlock) {
+ size = blkio->Media->LastBlock + 1 -
+ off / blkio->Media->BlockSize;
+ size = size * blkio->Media->BlockSize;
+ }
+
+ if (rsize != NULL)
+ *rsize = size;
+
+ if (blkio->Media->BlockSize == 512)
+ return (efipart_readwrite(blkio, rw, blk, size / 512, buf));
+
+ /*
+ * The block size of the media is not 512B per sector.
+ */
+ blkbuf = malloc(blkio->Media->BlockSize);
+ if (blkbuf == NULL)
+ return (ENOMEM);
+
+ error = 0;
+ blk = off / blkio->Media->BlockSize;
+ blkoff = off % blkio->Media->BlockSize;
+ blksz = blkio->Media->BlockSize - blkoff;
+ while (size > 0) {
+ error = efipart_readwrite(blkio, rw, blk, 1, blkbuf);
+ if (error)
+ break;
+ if (size < blksz)
+ blksz = size;
+ bcopy(blkbuf + blkoff, buf, blksz);
+ buf += blksz;
+ size -= blksz;
+ blk++;
+ blkoff = 0;
+ blksz = blkio->Media->BlockSize;
+ }
+
+ free(blkbuf);
+ return (error);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/errno.c b/usr/src/boot/sys/boot/efi/libefi/errno.c
new file mode 100644
index 0000000000..fac903faf2
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/errno.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+int
+efi_status_to_errno(EFI_STATUS status)
+{
+ int errno;
+
+ switch (status) {
+ case EFI_ACCESS_DENIED:
+ errno = EPERM;
+ break;
+
+ case EFI_BUFFER_TOO_SMALL:
+ errno = EOVERFLOW;
+ break;
+
+ case EFI_DEVICE_ERROR:
+ case EFI_VOLUME_CORRUPTED:
+ errno = EIO;
+ break;
+
+ case EFI_INVALID_PARAMETER:
+ errno = EINVAL;
+ break;
+
+ case EFI_MEDIA_CHANGED:
+ errno = ESTALE;
+ break;
+
+ case EFI_NO_MEDIA:
+ errno = ENXIO;
+ break;
+
+ case EFI_NOT_FOUND:
+ errno = ENOENT;
+ break;
+
+ case EFI_OUT_OF_RESOURCES:
+ errno = ENOMEM;
+ break;
+
+ case EFI_UNSUPPORTED:
+ errno = ENODEV;
+ break;
+
+ case EFI_VOLUME_FULL:
+ errno = ENOSPC;
+ break;
+
+ case EFI_WRITE_PROTECTED:
+ errno = EACCES;
+ break;
+
+ case 0:
+ errno = 0;
+ break;
+
+ default:
+ errno = EDOOFUS;
+ break;
+ }
+
+ return (errno);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/handles.c b/usr/src/boot/sys/boot/efi/libefi/handles.c
new file mode 100644
index 0000000000..1e4ef6ffbd
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/handles.c
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+struct entry {
+ EFI_HANDLE handle;
+ EFI_HANDLE alias;
+ struct devsw *dev;
+ int unit;
+ uint64_t extra;
+};
+
+struct entry *entry;
+int nentries;
+
+int
+efi_register_handles(struct devsw *sw, EFI_HANDLE *handles,
+ EFI_HANDLE *aliases, int count)
+{
+ size_t sz;
+ int idx, unit;
+
+ idx = nentries;
+ nentries += count;
+ sz = nentries * sizeof(struct entry);
+ entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
+ for (unit = 0; idx < nentries; idx++, unit++) {
+ entry[idx].handle = handles[unit];
+ if (aliases != NULL)
+ entry[idx].alias = aliases[unit];
+ else
+ entry[idx].alias = NULL;
+ entry[idx].dev = sw;
+ entry[idx].unit = unit;
+ }
+ return (0);
+}
+
+EFI_HANDLE
+efi_find_handle(struct devsw *dev, int unit)
+{
+ int idx;
+
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].dev != dev)
+ continue;
+ if (entry[idx].unit != unit)
+ continue;
+ return (entry[idx].handle);
+ }
+ return (NULL);
+}
+
+int
+efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit, uint64_t *extra)
+{
+ int idx;
+
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].handle != h && entry[idx].alias != h)
+ continue;
+ if (dev != NULL)
+ *dev = entry[idx].dev;
+ if (unit != NULL)
+ *unit = entry[idx].unit;
+ if (extra != NULL)
+ *extra = entry[idx].extra;
+ return (0);
+ }
+ return (ENOENT);
+}
+
+int
+efi_handle_update_dev(EFI_HANDLE h, struct devsw *dev, int unit,
+ uint64_t guid)
+{
+ int idx;
+
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].handle != h)
+ continue;
+ entry[idx].dev = dev;
+ entry[idx].unit = unit;
+ entry[idx].alias = NULL;
+ entry[idx].extra = guid;
+ return (0);
+ }
+
+ return (ENOENT);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/libefi.c b/usr/src/boot/sys/boot/efi/libefi/libefi.c
new file mode 100644
index 0000000000..77e8be96f1
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/libefi.c
@@ -0,0 +1,200 @@
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <eficonsctl.h>
+#include <efilib.h>
+#include <stand.h>
+
+EFI_HANDLE IH;
+EFI_SYSTEM_TABLE *ST;
+EFI_BOOT_SERVICES *BS;
+EFI_RUNTIME_SERVICES *RS;
+
+static EFI_PHYSICAL_ADDRESS heap;
+static UINTN heapsize;
+
+static CHAR16 *
+arg_skipsep(CHAR16 *argp)
+{
+
+ while (*argp == ' ' || *argp == '\t' || *argp == '\n')
+ argp++;
+ return (argp);
+}
+
+static CHAR16 *
+arg_skipword(CHAR16 *argp)
+{
+
+ while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n')
+ argp++;
+ return (argp);
+}
+
+void *
+efi_get_table(EFI_GUID *tbl)
+{
+ EFI_GUID *id;
+ int i;
+
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
+ id = &ST->ConfigurationTable[i].VendorGuid;
+ if (!memcmp(id, tbl, sizeof(EFI_GUID)))
+ return (ST->ConfigurationTable[i].VendorTable);
+ }
+ return (NULL);
+}
+
+void exit(EFI_STATUS exit_code)
+{
+
+ BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize));
+ BS->Exit(IH, exit_code, 0, NULL);
+}
+
+void
+efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
+{
+ static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL;
+ static EFI_GUID console_control_protocol =
+ EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+ EFI_CONSOLE_CONTROL_PROTOCOL *console_control = NULL;
+ EFI_LOADED_IMAGE *img;
+ CHAR16 *argp, *args, **argv;
+ EFI_STATUS status;
+ int argc, addprog;
+
+ IH = image_handle;
+ ST = system_table;
+ BS = ST->BootServices;
+ RS = ST->RuntimeServices;
+
+ status = BS->LocateProtocol(&console_control_protocol, NULL,
+ (VOID **)&console_control);
+ if (status == EFI_SUCCESS)
+ (void)console_control->SetMode(console_control,
+ EfiConsoleControlScreenText);
+
+ heapsize = 64 * 1024 * 1024;
+ /* 4GB upper limit, try to leave some space from 1MB */
+ heap = 0x0000000100000000;
+ status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData,
+ EFI_SIZE_TO_PAGES(heapsize), &heap);
+ if (status != EFI_SUCCESS)
+ BS->Exit(IH, status, 0, NULL);
+
+ setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize));
+
+ /* Use exit() from here on... */
+
+ status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img);
+ if (status != EFI_SUCCESS)
+ exit(status);
+
+ /*
+ * Pre-process the (optional) load options. If the option string
+ * is given as an ASCII string, we use a poor man's ASCII to
+ * Unicode-16 translation. The size of the option string as given
+ * to us includes the terminating null character. We assume the
+ * string is an ASCII string if strlen() plus the terminating
+ * '\0' is less than LoadOptionsSize. Even if all Unicode-16
+ * characters have the upper 8 bits non-zero, the terminating
+ * null character will cause a one-off.
+ * If the string is already in Unicode-16, we make a copy so that
+ * we know we can always modify the string.
+ */
+ if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) {
+ if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) {
+ args = malloc(img->LoadOptionsSize << 1);
+ for (argc = 0; argc < img->LoadOptionsSize; argc++)
+ args[argc] = ((char*)img->LoadOptions)[argc];
+ } else {
+ args = malloc(img->LoadOptionsSize);
+ memcpy(args, img->LoadOptions, img->LoadOptionsSize);
+ }
+ } else
+ args = NULL;
+
+ /*
+ * Use a quick and dirty algorithm to build the argv vector. We
+ * first count the number of words. Then, after allocating the
+ * vector, we split the string up. We don't deal with quotes or
+ * other more advanced shell features.
+ * The EFI shell will pass the name of the image as the first
+ * word in the argument list. This does not happen if we're
+ * loaded by the boot manager. This is not so easy to figure
+ * out though. The ParentHandle is not always NULL, because
+ * there can be a function (=image) that will perform the task
+ * for the boot manager.
+ */
+ /* Part 1: Figure out if we need to add our program name. */
+ addprog = (args == NULL || img->ParentHandle == NULL ||
+ img->FilePath == NULL) ? 1 : 0;
+ if (!addprog) {
+ addprog =
+ (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP ||
+ DevicePathNodeLength(img->FilePath) <=
+ sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0;
+ if (!addprog) {
+ /* XXX todo. */
+ }
+ }
+ /* Part 2: count words. */
+ argc = (addprog) ? 1 : 0;
+ argp = args;
+ while (argp != NULL && *argp != 0) {
+ argp = arg_skipsep(argp);
+ if (*argp == 0)
+ break;
+ argc++;
+ argp = arg_skipword(argp);
+ }
+ /* Part 3: build vector. */
+ argv = malloc((argc + 1) * sizeof(CHAR16*));
+ argc = 0;
+ if (addprog)
+ argv[argc++] = (CHAR16 *)L"loader.efi";
+ argp = args;
+ while (argp != NULL && *argp != 0) {
+ argp = arg_skipsep(argp);
+ if (*argp == 0)
+ break;
+ argv[argc++] = argp;
+ argp = arg_skipword(argp);
+ /* Terminate the words. */
+ if (*argp != 0)
+ *argp++ = 0;
+ }
+ argv[argc] = NULL;
+
+ status = main(argc, argv);
+ exit(status);
+}
diff --git a/usr/src/boot/sys/boot/efi/libefi/time.c b/usr/src/boot/sys/boot/efi/libefi/time.c
new file mode 100644
index 0000000000..1f9d5daed1
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/libefi/time.c
@@ -0,0 +1,224 @@
+/*-
+ * Copyright (c) 1999, 2000
+ * Intel Corporation.
+ * 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *
+ * This product includes software developed by Intel Corporation and
+ * its contributors.
+ *
+ * 4. Neither the name of Intel Corporation or its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <time.h>
+#include <sys/time.h>
+
+/*
+// Accurate only for the past couple of centuries;
+// that will probably do.
+//
+// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h)
+*/
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+#define SECSPERHOUR ( 60*60 )
+#define SECSPERDAY (24 * SECSPERHOUR)
+
+static time_t
+efi_time(EFI_TIME *ETime)
+{
+ /*
+ // These arrays give the cumulative number of days up to the first of the
+ // month number used as the index (1 -> 12) for regular and leap years.
+ // The value at index 13 is for the whole year.
+ */
+ static time_t CumulativeDays[2][14] = {
+ {0,
+ 0,
+ 31,
+ 31 + 28,
+ 31 + 28 + 31,
+ 31 + 28 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 },
+ {0,
+ 0,
+ 31,
+ 31 + 29,
+ 31 + 29 + 31,
+ 31 + 29 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }};
+
+ time_t UTime;
+ int Year;
+
+ /*
+ // Do a santity check
+ */
+ if ( ETime->Year < 1998 || ETime->Year > 2099 ||
+ ETime->Month == 0 || ETime->Month > 12 ||
+ ETime->Day == 0 || ETime->Month > 31 ||
+ ETime->Hour > 23 ||
+ ETime->Minute > 59 ||
+ ETime->Second > 59 ||
+ ETime->TimeZone < -1440 ||
+ (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) {
+ return (0);
+ }
+
+ /*
+ // Years
+ */
+ UTime = 0;
+ for (Year = 1970; Year != ETime->Year; ++Year) {
+ UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY);
+ }
+
+ /*
+ // UTime should now be set to 00:00:00 on Jan 1 of the file's year.
+ //
+ // Months
+ */
+ UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY);
+
+ /*
+ // UTime should now be set to 00:00:00 on the first of the file's month and year
+ //
+ // Days -- Don't count the file's day
+ */
+ UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY);
+
+ /*
+ // Hours
+ */
+ UTime += (ETime->Hour * SECSPERHOUR);
+
+ /*
+ // Minutes
+ */
+ UTime += (ETime->Minute * 60);
+
+ /*
+ // Seconds
+ */
+ UTime += ETime->Second;
+
+ /*
+ // EFI time is repored in local time. Adjust for any time zone offset to
+ // get true UT
+ */
+ if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) {
+ /*
+ // TimeZone is kept in minues...
+ */
+ UTime += (ETime->TimeZone * 60);
+ }
+
+ return UTime;
+}
+
+static int
+EFI_GetTimeOfDay(
+ OUT struct timeval *tp,
+ OUT struct timezone *tzp
+ )
+{
+ EFI_TIME EfiTime;
+ EFI_TIME_CAPABILITIES Capabilities;
+ EFI_STATUS Status;
+
+ /*
+ // Get time from EFI
+ */
+
+ Status = RS->GetTime(&EfiTime, &Capabilities);
+ if (EFI_ERROR(Status))
+ return (-1);
+
+ /*
+ // Convert to UNIX time (ie seconds since the epoch
+ */
+
+ tp->tv_sec = efi_time( &EfiTime );
+ tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */
+
+ /*
+ // Do something with the timezone if needed
+ */
+
+ if (tzp) {
+ tzp->tz_minuteswest =
+ EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone;
+ /*
+ // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT
+ */
+ tzp->tz_dsttime =
+ EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0;
+ }
+
+ return (0);
+}
+
+time_t
+time(time_t *tloc)
+{
+ struct timeval tv;
+ EFI_GetTimeOfDay(&tv, 0);
+
+ if (tloc)
+ *tloc = tv.tv_sec;
+ return tv.tv_sec;
+}
+
+time_t
+getsecs()
+{
+ return time(0);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/Makefile b/usr/src/boot/sys/boot/efi/loader/Makefile
new file mode 100644
index 0000000000..5824a84ada
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/Makefile
@@ -0,0 +1,154 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+CC= $(GCC_ROOT)/bin/gcc
+LD= $(GNU_ROOT)/bin/gld
+OBJCOPY= $(GNU_ROOT)/bin/gobjcopy
+OBJDUMP= $(GNU_ROOT)/bin/gobjdump
+
+PROG= loader.sym
+MACHINE= $(MACH64)
+
+# architecture-specific loader code
+SRCS= autoload.c bootinfo.c conf.c copy.c devicename.c main.c self_reloc.c \
+ smbios.c biosacpi.c vers.c
+OBJS= autoload.o bootinfo.o conf.o copy.o devicename.o main.o self_reloc.o \
+ smbios.o biosacpi.o vers.o
+
+ASFLAGS=-m64 -fPIC
+CFLAGS= -O2
+CPPFLAGS= -nostdinc -I../../../../include -I../../..
+CPPFLAGS += -I../../../../lib/libstand
+
+include ../Makefile.inc
+
+include arch/${MACHINE}/Makefile.inc
+
+CPPFLAGS += -I.
+CPPFLAGS += -I./arch/${MACHINE}
+CPPFLAGS += -I./../include
+CPPFLAGS += -I./../include/${MACHINE}
+CPPFLAGS += -I./../../../contrib/dev/acpica/include
+CPPFLAGS += -I./../../..
+CPPFLAGS += -I./../../i386/libi386
+CPPFLAGS += -I./../../zfs
+CPPFLAGS += -I./../../../cddl/boot/zfs
+CPPFLAGS += -DEFI_ZFS_BOOT
+CPPFLAGS += -DNO_PCI -DEFI -DTERM_EMU
+
+LIBSTAND= ../../libstand/${MACHINE}/libstand.a
+
+BOOT_FORTH= yes
+CPPFLAGS += -DBOOT_FORTH -DSTAND
+CPPFLAGS += -I$(SRC)/common/ficl
+CPPFLAGS += -I../../ficl
+LIBFICL= ../../ficl/${MACHINE}/libficl.a
+
+CPPFLAGS += -I../../zfs
+LIBZFSBOOT= ../../zfs/${MACHINE}/libzfsboot.a
+
+#LOADER_FDT_SUPPORT?= no
+#.if ${MK_FDT} != "no" && ${LOADER_FDT_SUPPORT} != "no"
+#CFLAGS+= -I${.CURDIR}/../../fdt
+#CFLAGS+= -I${.OBJDIR}/../../fdt
+#CFLAGS+= -DLOADER_FDT_SUPPORT
+#LIBEFI_FDT= ${.OBJDIR}/../../efi/fdt/libefi_fdt.a
+#LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
+#.endif
+
+# Always add MI sources
+include ./Makefile.common
+CPPFLAGS += -I../../common
+
+FILES= loader.efi
+FILEMODE= 0555
+ROOT_BOOT= $(ROOT)/boot
+ROOTBOOTFILES=$(FILES:%=$(ROOT_BOOT)/%)
+
+LDSCRIPT= ./arch/${MACHINE}/ldscript.${MACHINE}
+LDFLAGS = -nostdlib --eh-frame-hdr -znocombreloc
+LDFLAGS += -shared --hash-style=both --enable-new-dtags
+LDFLAGS += -T${LDSCRIPT} -Bsymbolic
+
+CLEANFILES= vers.c loader.efi
+
+NEWVERSWHAT= "EFI loader" ${MACHINE}
+
+all: machine x86 loader.efi
+install: all $(ROOTBOOTFILES)
+
+vers.c: ../../common/newvers.sh ../../efi/loader/version
+ $(SH) ../../common/newvers.sh version ${NEWVERSWHAT}
+
+EFI_TARGET= pei-x86-64
+
+loader.efi: loader.sym
+ if [ `${OBJDUMP} -t loader.sym | fgrep '*UND*' | wc -l` != 0 ]; then \
+ ${OBJDUMP} -t loader.sym | fgrep '*UND*'; \
+ exit 1; \
+ fi
+ ${OBJCOPY} --readonly-text -j .peheader -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel.dyn \
+ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
+ --output-target=${EFI_TARGET} --subsystem efi-app loader.sym $@
+
+LIBEFI= ../libefi/libefi.a
+
+DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} \
+ ${LIBSTAND} ${LDSCRIPT}
+LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} \
+ ${LIBSTAND}
+
+
+loader.sym: $(OBJS) $(DPADD)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDADD)
+
+beforedepend ${OBJS}: machine
+
+CLEANFILES += machine x86
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../${MACHINE}/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+clean clobber:
+ $(RM) $(CLEANFILES) $(OBJS) loader.sym loader.efi
+
+%.o: %.c
+ $(COMPILE.c) $<
+
+%.o: ./arch/${MACHINE}/%.c
+ $(COMPILE.c) $<
+
+%.o: ./arch/${MACHINE}/%.S
+ $(COMPILE.S) $<
+
+%.o: ../../common/%.c
+ $(COMPILE.c) $<
+
+%.o: ../../common/linenoise/%.c
+ $(COMPILE.c) $<
+
+%.o: ../../i386/libi386/%.c
+ $(COMPILE.c) $<
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/efi/loader/Makefile.common b/usr/src/boot/sys/boot/efi/loader/Makefile.common
new file mode 100644
index 0000000000..fbddfeab8a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/Makefile.common
@@ -0,0 +1,36 @@
+# $FreeBSD$
+
+SRCS += boot.c commands.c console.c devopen.c interp.c
+SRCS += interp_backslash.c interp_parse.c ls.c misc.c
+SRCS += module.c panic.c linenoise.c
+
+OBJS += boot.o commands.o console.o devopen.o interp.o \
+ interp_backslash.o interp_parse.o ls.o misc.o \
+ module.o panic.o linenoise.o
+
+SRCS += load_elf32.c load_elf32_obj.c reloc_elf32.c
+SRCS += load_elf64.c load_elf64_obj.c reloc_elf64.c
+
+OBJS += load_elf32.o load_elf32_obj.o reloc_elf32.o \
+ load_elf64.o load_elf64_obj.o reloc_elf64.o
+
+SRCS += disk.c part.c
+OBJS += disk.o part.o
+CFLAGS += -DLOADER_DISK_SUPPORT
+SRCS += crc32.c
+OBJS += crc32.o
+CFLAGS += -DLOADER_GPT_SUPPORT
+CFLAGS += -DLOADER_MBR_SUPPORT
+
+SRCS += bcache.c
+OBJS += bcache.o
+
+#SRCS += isapnp.c
+#SRCS += pnp.c
+
+# Forth interpreter
+SRCS += interp_forth.c
+OBJS += interp_forth.o
+
+MAN += loader.8
+MAN += zfsloader.8
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/Makefile.inc b/usr/src/boot/sys/boot/efi/loader/arch/amd64/Makefile.inc
new file mode 100644
index 0000000000..5ff8a8c714
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/Makefile.inc
@@ -0,0 +1,21 @@
+
+SRCS += amd64_tramp.S \
+ start.S \
+ framebuffer.c \
+ elf64_freebsd.c
+
+OBJS += amd64_tramp.o \
+ start.o \
+ framebuffer.o \
+ elf64_freebsd.o
+
+SRCS += nullconsole.c \
+ spinconsole.c \
+ comconsole.c
+
+OBJS += nullconsole.o \
+ spinconsole.o \
+ comconsole.o
+
+CFLAGS += -fPIC
+LDFLAGS += -znocombreloc
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/amd64_tramp.S b/usr/src/boot/sys/boot/efi/loader/arch/amd64/amd64_tramp.S
new file mode 100644
index 0000000000..c102d92435
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/amd64_tramp.S
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asmacros.h>
+
+ .text
+ .globl amd64_tramp
+
+/*
+ * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend,
+ * uint64_t modulep, uint64_t pagetable, uint64_t entry)
+ */
+amd64_tramp:
+ cli /* Make sure we don't get interrupted. */
+ movq %rdi,%rsp /* Switch to our temporary stack. */
+
+ movq %rdx,%r12 /* Stash the kernel values for later. */
+ movq %rcx,%r13
+ movq %r8,%r14
+ movq %r9,%r15
+
+ callq *%rsi /* Call copy_finish so we're all ready to go. */
+
+ pushq %r12 /* Push kernend. */
+ salq $32,%r13 /* Shift modulep and push it. */
+ pushq %r13
+ pushq %r15 /* Push the entry address. */
+ movq %r14,%cr3 /* Switch page tables. */
+ ret /* "Return" to kernel entry. */
+
+ ALIGN_TEXT
+amd64_tramp_end:
+
+ .data
+ .globl amd64_tramp_size
+amd64_tramp_size:
+ .long amd64_tramp_end-amd64_tramp
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c b/usr/src/boot/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
new file mode 100644
index 0000000000..f0cb7e7248
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+#include "loader_efi.h"
+
+static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
+static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
+
+extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+
+static int elf64_exec(struct preloaded_file *amp);
+static int elf64_obj_exec(struct preloaded_file *amp);
+
+static struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
+static struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+
+struct file_format *file_formats[] = {
+ &amd64_elf,
+ &amd64_elf_obj,
+ NULL
+};
+
+#define PG_V 0x001
+#define PG_RW 0x002
+#define PG_U 0x004
+#define PG_PS 0x080
+
+typedef u_int64_t p4_entry_t;
+typedef u_int64_t p3_entry_t;
+typedef u_int64_t p2_entry_t;
+static p4_entry_t *PT4;
+static p3_entry_t *PT3;
+static p2_entry_t *PT2;
+
+static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
+ uint64_t modulep, p4_entry_t *pagetable,
+ uint64_t entry);
+
+extern uintptr_t amd64_tramp;
+extern uint32_t amd64_tramp_size;
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf64_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t modulep, kernend, trampcode, trampstack;
+ int err, i;
+ ACPI_TABLE_RSDP *rsdp;
+ char buf[24];
+ int revision;
+
+ rsdp = efi_get_table(&acpi20_guid);
+ if (rsdp == NULL) {
+ rsdp = efi_get_table(&acpi_guid);
+ }
+ if (rsdp != NULL) {
+ sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
+ setenv("hint.acpi.0.rsdp", buf, 1);
+ revision = rsdp->Revision;
+ if (revision == 0)
+ revision = 1;
+ sprintf(buf, "%d", revision);
+ setenv("hint.acpi.0.revision", buf, 1);
+ strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+ buf[sizeof(rsdp->OemId)] = '\0';
+ setenv("hint.acpi.0.oem", buf, 1);
+ sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
+ setenv("hint.acpi.0.rsdt", buf, 1);
+ if (revision >= 2) {
+ /* XXX extended checksum? */
+ sprintf(buf, "0x%016llx",
+ (unsigned long long)rsdp->XsdtPhysicalAddress);
+ setenv("hint.acpi.0.xsdt", buf, 1);
+ sprintf(buf, "%d", rsdp->Length);
+ setenv("hint.acpi.0.xsdt_length", buf, 1);
+ }
+ }
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ trampcode = (vm_offset_t)0x0000000040000000;
+ err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
+ (EFI_PHYSICAL_ADDRESS *)&trampcode);
+ bzero((void *)trampcode, EFI_PAGE_SIZE);
+ trampstack = trampcode + EFI_PAGE_SIZE - 8;
+ bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size);
+ trampoline = (void *)trampcode;
+
+ PT4 = (p4_entry_t *)0x0000000040000000;
+ err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
+ (EFI_PHYSICAL_ADDRESS *)&PT4);
+ bzero(PT4, 3 * EFI_PAGE_SIZE);
+
+ PT3 = &PT4[512];
+ PT2 = &PT3[512];
+
+ /*
+ * This is kinda brutal, but every single 1GB VM memory segment points
+ * to the same first 1GB of physical memory. But it is more than
+ * adequate.
+ */
+ for (i = 0; i < 512; i++) {
+ /* Each slot of the L4 pages points to the same L3 page. */
+ PT4[i] = (p4_entry_t)PT3;
+ PT4[i] |= PG_V | PG_RW | PG_U;
+
+ /* Each slot of the L3 pages points to the same L2 page. */
+ PT3[i] = (p3_entry_t)PT2;
+ PT3[i] |= PG_V | PG_RW | PG_U;
+
+ /* The L2 page slots are mapped with 2MB pages for 1GB. */
+ PT2[i] = i * (2 * 1024 * 1024);
+ PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+ }
+
+ printf("Start @ 0x%lx ...\n", ehdr->e_entry);
+
+ err = bi_load(fp->f_args, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+
+ dev_cleanup();
+
+ trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4,
+ ehdr->e_entry);
+
+ panic("exec returned");
+}
+
+static int
+elf64_obj_exec(struct preloaded_file *fp __attribute((unused)))
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.c b/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.c
new file mode 100644
index 0000000000..f31704bdb9
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.c
@@ -0,0 +1,568 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <bootstrap.h>
+#include <sys/endian.h>
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <efiuga.h>
+#include <efipciio.h>
+#include <machine/metadata.h>
+
+#include "framebuffer.h"
+
+static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+static EFI_GUID pciio_guid = EFI_PCI_IO_PROTOCOL_GUID;
+static EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID;
+
+static u_int
+efifb_color_depth(struct efi_fb *efifb)
+{
+ uint32_t mask;
+ u_int depth;
+
+ mask = efifb->fb_mask_red | efifb->fb_mask_green |
+ efifb->fb_mask_blue | efifb->fb_mask_reserved;
+ if (mask == 0)
+ return (0);
+ for (depth = 1; mask != 1; depth++)
+ mask >>= 1;
+ return (depth);
+}
+
+static int
+efifb_mask_from_pixfmt(struct efi_fb *efifb, EFI_GRAPHICS_PIXEL_FORMAT pixfmt,
+ EFI_PIXEL_BITMASK *pixinfo)
+{
+ int result;
+
+ result = 0;
+ switch (pixfmt) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ efifb->fb_mask_red = 0x000000ff;
+ efifb->fb_mask_green = 0x0000ff00;
+ efifb->fb_mask_blue = 0x00ff0000;
+ efifb->fb_mask_reserved = 0xff000000;
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ efifb->fb_mask_red = 0x00ff0000;
+ efifb->fb_mask_green = 0x0000ff00;
+ efifb->fb_mask_blue = 0x000000ff;
+ efifb->fb_mask_reserved = 0xff000000;
+ break;
+ case PixelBitMask:
+ efifb->fb_mask_red = pixinfo->RedMask;
+ efifb->fb_mask_green = pixinfo->GreenMask;
+ efifb->fb_mask_blue = pixinfo->BlueMask;
+ efifb->fb_mask_reserved = pixinfo->ReservedMask;
+ break;
+ default:
+ result = 1;
+ break;
+ }
+ return (result);
+}
+
+static int
+efifb_from_gop(struct efi_fb *efifb, EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode,
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info)
+{
+ int result;
+
+ efifb->fb_addr = mode->FrameBufferBase;
+ efifb->fb_size = mode->FrameBufferSize;
+ efifb->fb_height = info->VerticalResolution;
+ efifb->fb_width = info->HorizontalResolution;
+ efifb->fb_stride = info->PixelsPerScanLine;
+ result = efifb_mask_from_pixfmt(efifb, info->PixelFormat,
+ &info->PixelInformation);
+ return (result);
+}
+
+static ssize_t
+efifb_uga_find_pixel(EFI_UGA_DRAW_PROTOCOL *uga, u_int line,
+ EFI_PCI_IO_PROTOCOL *pciio, uint64_t addr, uint64_t size)
+{
+ EFI_UGA_PIXEL pix0, pix1;
+ uint8_t *data1, *data2;
+ size_t count, maxcount = 1024;
+ ssize_t ofs;
+ EFI_STATUS status;
+ u_int idx;
+
+ status = uga->Blt(uga, &pix0, EfiUgaVideoToBltBuffer,
+ 0, line, 0, 0, 1, 1, 0);
+ if (EFI_ERROR(status)) {
+ printf("UGA BLT operation failed (video->buffer)");
+ return (-1);
+ }
+ pix1.Red = ~pix0.Red;
+ pix1.Green = ~pix0.Green;
+ pix1.Blue = ~pix0.Blue;
+ pix1.Reserved = 0;
+
+ data1 = calloc(maxcount, 2);
+ if (data1 == NULL) {
+ printf("Unable to allocate memory");
+ return (-1);
+ }
+ data2 = data1 + maxcount;
+
+ ofs = 0;
+ while (size > 0) {
+ count = min(size, maxcount);
+
+ status = pciio->Mem.Read(pciio, EfiPciIoWidthUint32,
+ EFI_PCI_IO_PASS_THROUGH_BAR, addr + ofs, count >> 2,
+ data1);
+ if (EFI_ERROR(status)) {
+ printf("Error reading frame buffer (before)");
+ goto fail;
+ }
+ status = uga->Blt(uga, &pix1, EfiUgaBltBufferToVideo,
+ 0, 0, 0, line, 1, 1, 0);
+ if (EFI_ERROR(status)) {
+ printf("UGA BLT operation failed (modify)");
+ goto fail;
+ }
+ status = pciio->Mem.Read(pciio, EfiPciIoWidthUint32,
+ EFI_PCI_IO_PASS_THROUGH_BAR, addr + ofs, count >> 2,
+ data2);
+ if (EFI_ERROR(status)) {
+ printf("Error reading frame buffer (after)");
+ goto fail;
+ }
+ status = uga->Blt(uga, &pix0, EfiUgaBltBufferToVideo,
+ 0, 0, 0, line, 1, 1, 0);
+ if (EFI_ERROR(status)) {
+ printf("UGA BLT operation failed (restore)");
+ goto fail;
+ }
+ for (idx = 0; idx < count; idx++) {
+ if (data1[idx] != data2[idx]) {
+ free(data1);
+ return (ofs + (idx & ~3));
+ }
+ }
+ ofs += count;
+ size -= count;
+ }
+ printf("No change detected in frame buffer");
+
+ fail:
+ printf(" -- error %lu\n", EFI_ERROR_CODE(status));
+ free(data1);
+ return (-1);
+}
+
+static EFI_PCI_IO_PROTOCOL *
+efifb_uga_get_pciio(void)
+{
+ EFI_PCI_IO_PROTOCOL *pciio;
+ EFI_HANDLE *buf, *hp;
+ EFI_STATUS status;
+ UINTN bufsz;
+
+ /* Get all handles that support the UGA protocol. */
+ bufsz = 0;
+ status = BS->LocateHandle(ByProtocol, &uga_guid, NULL, &bufsz, NULL);
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return (NULL);
+ buf = malloc(bufsz);
+ status = BS->LocateHandle(ByProtocol, &uga_guid, NULL, &bufsz, buf);
+ if (status != EFI_SUCCESS) {
+ free(buf);
+ return (NULL);
+ }
+ bufsz /= sizeof(EFI_HANDLE);
+
+ /* Get the PCI I/O interface of the first handle that supports it. */
+ pciio = NULL;
+ for (hp = buf; hp < buf + bufsz; hp++) {
+ status = BS->HandleProtocol(*hp, &pciio_guid, (void **)&pciio);
+ if (status == EFI_SUCCESS) {
+ free(buf);
+ return (pciio);
+ }
+ }
+ free(buf);
+ return (NULL);
+}
+
+static EFI_STATUS
+efifb_uga_locate_framebuffer(EFI_PCI_IO_PROTOCOL *pciio, uint64_t *addrp,
+ uint64_t *sizep)
+{
+ uint8_t *resattr;
+ uint64_t addr, size;
+ EFI_STATUS status;
+ u_int bar;
+
+ if (pciio == NULL)
+ return (EFI_DEVICE_ERROR);
+
+ /* Attempt to get the frame buffer address (imprecise). */
+ *addrp = 0;
+ *sizep = 0;
+ for (bar = 0; bar < 6; bar++) {
+ status = pciio->GetBarAttributes(pciio, bar, NULL,
+ (void **)&resattr);
+ if (status != EFI_SUCCESS)
+ continue;
+ /* XXX magic offsets and constants. */
+ if (resattr[0] == 0x87 && resattr[3] == 0) {
+ /* 32-bit address space descriptor (MEMIO) */
+ addr = le32dec(resattr + 10);
+ size = le32dec(resattr + 22);
+ } else if (resattr[0] == 0x8a && resattr[3] == 0) {
+ /* 64-bit address space descriptor (MEMIO) */
+ addr = le64dec(resattr + 14);
+ size = le64dec(resattr + 38);
+ } else {
+ addr = 0;
+ size = 0;
+ }
+ BS->FreePool(resattr);
+ if (addr == 0 || size == 0)
+ continue;
+
+ /* We assume the largest BAR is the frame buffer. */
+ if (size > *sizep) {
+ *addrp = addr;
+ *sizep = size;
+ }
+ }
+ return ((*addrp == 0 || *sizep == 0) ? EFI_DEVICE_ERROR : 0);
+}
+
+static int
+efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga)
+{
+ EFI_PCI_IO_PROTOCOL *pciio;
+ char *ev, *p;
+ EFI_STATUS status;
+ ssize_t offset;
+ uint64_t fbaddr;
+ uint32_t horiz, vert, stride;
+ uint32_t np, depth, refresh;
+
+ status = uga->GetMode(uga, &horiz, &vert, &depth, &refresh);
+ if (EFI_ERROR(status))
+ return (1);
+ efifb->fb_height = vert;
+ efifb->fb_width = horiz;
+ /* Paranoia... */
+ if (efifb->fb_height == 0 || efifb->fb_width == 0)
+ return (1);
+
+ /* The color masks are fixed AFAICT. */
+ efifb_mask_from_pixfmt(efifb, PixelBlueGreenRedReserved8BitPerColor,
+ NULL);
+
+ /* pciio can be NULL on return! */
+ pciio = efifb_uga_get_pciio();
+
+ /* Try to find the frame buffer. */
+ status = efifb_uga_locate_framebuffer(pciio, &efifb->fb_addr,
+ &efifb->fb_size);
+ if (EFI_ERROR(status)) {
+ efifb->fb_addr = 0;
+ efifb->fb_size = 0;
+ }
+
+ /*
+ * There's no reliable way to detect the frame buffer or the
+ * offset within the frame buffer of the visible region, nor
+ * the stride. Our only option is to look at the system and
+ * fill in the blanks based on that. Luckily, UGA was mostly
+ * only used on Apple hardware.
+ */
+ offset = -1;
+ ev = getenv("smbios.system.maker");
+ if (ev != NULL && !strcmp(ev, "Apple Inc.")) {
+ ev = getenv("smbios.system.product");
+ if (ev != NULL && !strcmp(ev, "iMac7,1")) {
+ /* These are the expected values we should have. */
+ horiz = 1680;
+ vert = 1050;
+ fbaddr = 0xc0000000;
+ /* These are the missing bits. */
+ offset = 0x10000;
+ stride = 1728;
+ } else if (ev != NULL && !strcmp(ev, "MacBook3,1")) {
+ /* These are the expected values we should have. */
+ horiz = 1280;
+ vert = 800;
+ fbaddr = 0xc0000000;
+ /* These are the missing bits. */
+ offset = 0x0;
+ stride = 2048;
+ }
+ }
+
+ /*
+ * If this is hardware we know, make sure that it looks familiar
+ * before we accept our hardcoded values.
+ */
+ if (offset >= 0 && efifb->fb_width == horiz &&
+ efifb->fb_height == vert && efifb->fb_addr == fbaddr) {
+ efifb->fb_addr += offset;
+ efifb->fb_size -= offset;
+ efifb->fb_stride = stride;
+ return (0);
+ } else if (offset >= 0) {
+ printf("Hardware make/model known, but graphics not "
+ "as expected.\n");
+ printf("Console may not work!\n");
+ }
+
+ /*
+ * The stride is equal or larger to the width. Often it's the
+ * next larger power of two. We'll start with that...
+ */
+ efifb->fb_stride = efifb->fb_width;
+ do {
+ np = efifb->fb_stride & (efifb->fb_stride - 1);
+ if (np) {
+ efifb->fb_stride |= (np - 1);
+ efifb->fb_stride++;
+ }
+ } while (np);
+
+ ev = getenv("hw.efifb.address");
+ if (ev == NULL) {
+ if (efifb->fb_addr == 0) {
+ printf("Please set hw.efifb.address and "
+ "hw.efifb.stride.\n");
+ return (1);
+ }
+
+ /*
+ * The visible part of the frame buffer may not start at
+ * offset 0, so try to detect it. Note that we may not
+ * always be able to read from the frame buffer, which
+ * means that we may not be able to detect anything. In
+ * that case, we would take a long time scanning for a
+ * pixel change in the frame buffer, which would have it
+ * appear that we're hanging, so we limit the scan to
+ * 1/256th of the frame buffer. This number is mostly
+ * based on PR 202730 and the fact that on a MacBoook,
+ * where we can't read from the frame buffer the offset
+ * of the visible region is 0. In short: we want to scan
+ * enough to handle all adapters that have an offset
+ * larger than 0 and we want to scan as little as we can
+ * to not appear to hang when we can't read from the
+ * frame buffer.
+ */
+ offset = efifb_uga_find_pixel(uga, 0, pciio, efifb->fb_addr,
+ efifb->fb_size >> 8);
+ if (offset == -1) {
+ printf("Unable to reliably detect frame buffer.\n");
+ } else if (offset > 0) {
+ efifb->fb_addr += offset;
+ efifb->fb_size -= offset;
+ }
+ } else {
+ offset = 0;
+ efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4;
+ efifb->fb_addr = strtoul(ev, &p, 0);
+ if (*p != '\0')
+ return (1);
+ }
+
+ ev = getenv("hw.efifb.stride");
+ if (ev == NULL) {
+ if (pciio != NULL && offset != -1) {
+ /* Determine the stride. */
+ offset = efifb_uga_find_pixel(uga, 1, pciio,
+ efifb->fb_addr, horiz * 8);
+ if (offset != -1)
+ efifb->fb_stride = offset >> 2;
+ } else {
+ printf("Unable to reliably detect the stride.\n");
+ }
+ } else {
+ efifb->fb_stride = strtoul(ev, &p, 0);
+ if (*p != '\0')
+ return (1);
+ }
+
+ /*
+ * We finalized on the stride, so recalculate the size of the
+ * frame buffer.
+ */
+ efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4;
+ return (0);
+}
+
+int
+efi_find_framebuffer(struct efi_fb *efifb)
+{
+ EFI_GRAPHICS_OUTPUT *gop;
+ EFI_UGA_DRAW_PROTOCOL *uga;
+ EFI_STATUS status;
+
+ status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
+ if (status == EFI_SUCCESS)
+ return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info));
+
+ status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga);
+ if (status == EFI_SUCCESS)
+ return (efifb_from_uga(efifb, uga));
+
+ return (1);
+}
+
+static void
+print_efifb(int mode, struct efi_fb *efifb, int verbose)
+{
+ u_int depth;
+
+ if (mode >= 0)
+ printf("mode %d: ", mode);
+ depth = efifb_color_depth(efifb);
+ printf("%ux%ux%u, stride=%u", efifb->fb_width, efifb->fb_height,
+ depth, efifb->fb_stride);
+ if (verbose) {
+ printf("\n frame buffer: address=%jx, size=%jx",
+ (uintmax_t)efifb->fb_addr, (uintmax_t)efifb->fb_size);
+ printf("\n color mask: R=%08x, G=%08x, B=%08x\n",
+ efifb->fb_mask_red, efifb->fb_mask_green,
+ efifb->fb_mask_blue);
+ }
+}
+
+COMMAND_SET(gop, "gop", "graphics output protocol", command_gop);
+
+static int
+command_gop(int argc, char *argv[])
+{
+ struct efi_fb efifb;
+ EFI_GRAPHICS_OUTPUT *gop;
+ EFI_STATUS status;
+ u_int mode;
+
+ status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
+ if (EFI_ERROR(status)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "%s: Graphics Output Protocol not present (error=%lu)",
+ argv[0], EFI_ERROR_CODE(status));
+ return (CMD_ERROR);
+ }
+
+ if (argc < 2)
+ goto usage;
+
+ if (!strcmp(argv[1], "set")) {
+ char *cp;
+
+ if (argc != 3)
+ goto usage;
+ mode = strtol(argv[2], &cp, 0);
+ if (cp[0] != '\0') {
+ sprintf(command_errbuf, "mode is an integer");
+ return (CMD_ERROR);
+ }
+ status = gop->SetMode(gop, mode);
+ if (EFI_ERROR(status)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "%s: Unable to set mode to %u (error=%lu)",
+ argv[0], mode, EFI_ERROR_CODE(status));
+ return (CMD_ERROR);
+ }
+ } else if (!strcmp(argv[1], "get")) {
+ if (argc != 2)
+ goto usage;
+ efifb_from_gop(&efifb, gop->Mode, gop->Mode->Info);
+ print_efifb(gop->Mode->Mode, &efifb, 1);
+ printf("\n");
+ } else if (!strcmp(argv[1], "list")) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ UINTN infosz;
+
+ if (argc != 2)
+ goto usage;
+ pager_open();
+ for (mode = 0; mode < gop->Mode->MaxMode; mode++) {
+ status = gop->QueryMode(gop, mode, &infosz, &info);
+ if (EFI_ERROR(status))
+ continue;
+ efifb_from_gop(&efifb, gop->Mode, info);
+ print_efifb(mode, &efifb, 0);
+ if (pager_output("\n"))
+ break;
+ }
+ pager_close();
+ }
+ return (CMD_OK);
+
+ usage:
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "usage: %s [list | get | set <mode>]", argv[0]);
+ return (CMD_ERROR);
+}
+
+COMMAND_SET(uga, "uga", "universal graphics adapter", command_uga);
+
+static int
+command_uga(int argc, char *argv[])
+{
+ struct efi_fb efifb;
+ EFI_UGA_DRAW_PROTOCOL *uga;
+ EFI_STATUS status;
+
+ status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga);
+ if (EFI_ERROR(status)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "%s: UGA Protocol not present (error=%lu)",
+ argv[0], EFI_ERROR_CODE(status));
+ return (CMD_ERROR);
+ }
+
+ if (argc != 1)
+ goto usage;
+
+ if (efifb_from_uga(&efifb, uga) != CMD_OK) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "%s: Unable to get UGA information", argv[0]);
+ return (CMD_ERROR);
+ }
+
+ print_efifb(-1, &efifb, 1);
+ printf("\n");
+ return (CMD_OK);
+
+ usage:
+ snprintf(command_errbuf, sizeof (command_errbuf), "usage: %s", argv[0]);
+ return (CMD_ERROR);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.h b/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.h
new file mode 100644
index 0000000000..2ec9017dc3
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/framebuffer.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _EFIFB_H_
+#define _EFIFB_H_
+
+int efi_find_framebuffer(struct efi_fb *efifb);
+
+#endif /* _EFIFB_H_ */
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/ldscript.amd64 b/usr/src/boot/sys/boot/efi/loader/arch/amd64/ldscript.amd64
new file mode 100644
index 0000000000..d9a83faf1b
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/ldscript.amd64
@@ -0,0 +1,66 @@
+OUTPUT_FORMAT("elf64-x86-64-sol2", "elf64-x86-64-sol2", "elf64-x86-64-sol2")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .eh_frame :
+ {
+ *(.eh_frame)
+ }
+ . = ALIGN(4096);
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.plt)
+ } =0x00300000010070000002000001000400
+ . = ALIGN(4096);
+ .data : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ *(.opd)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.plabel)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ . = ALIGN(4096);
+ __gp = .;
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rela.dyn : {
+ *(.rela.data*)
+ *(.rela.got)
+ *(.rela.stab)
+ *(.relaset_*)
+ }
+ . = ALIGN(4096);
+ .reloc : { *(.reloc) }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/amd64/start.S b/usr/src/boot/sys/boot/efi/loader/arch/amd64/start.S
new file mode 100644
index 0000000000..774ef4fa79
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/amd64/start.S
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ * Copyright (C) 2005 Intel Co.
+ * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hewlett-Packard Co. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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 MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+/*
+ * crt0-efi-x86_64.S - x86_64 EFI startup code.
+ * $FreeBSD$
+ */
+
+ .text
+ .align 4
+
+ .globl _start
+_start:
+ subq $8, %rsp
+ pushq %rcx
+ pushq %rdx
+
+0:
+ lea ImageBase(%rip), %rdi
+ lea _DYNAMIC(%rip), %rsi
+
+ popq %rcx
+ popq %rdx
+ pushq %rcx
+ pushq %rdx
+ call self_reloc
+
+ popq %rdi
+ popq %rsi
+
+ call efi_main
+ addq $8, %rsp
+
+.exit:
+ ret
+
+ /*
+ * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+ * executable:
+ */
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm/Makefile.inc b/usr/src/boot/sys/boot/efi/loader/arch/arm/Makefile.inc
new file mode 100644
index 0000000000..b2876ca195
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SRCS+= exec.c \
+ start.S
+
+LOADER_FDT_SUPPORT=yes
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm/exec.c b/usr/src/boot/sys/boot/efi/loader/arch/arm/exec.c
new file mode 100644
index 0000000000..716c7d300a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm/exec.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "loader_efi.h"
+
+extern vm_offset_t md_load(char *, vm_offset_t *);
+extern int bi_load(char *, vm_offset_t *, vm_offset_t *);
+
+static int
+__elfN(arm_load)(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+ return (0);
+}
+
+static int
+__elfN(arm_exec)(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t modulep, kernend;
+ Elf_Ehdr *e;
+ int error;
+ void (*entry)(void *);
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return (EFTYPE);
+
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0)
+ return (error);
+
+ entry = efi_translate(e->e_entry);
+ printf("Kernel entry at 0x%x...\n", (unsigned)entry);
+ printf("Kernel args: %s\n", fp->f_args);
+ printf("modulep: %#x\n", modulep);
+ printf("relocation_offset %llx\n", __elfN(relocation_offset));
+
+ dev_cleanup();
+
+ (*entry)((void *)modulep);
+ panic("exec returned");
+}
+
+static struct file_format arm_elf = {
+ __elfN(arm_load),
+ __elfN(arm_exec)
+};
+
+struct file_format *file_formats[] = {
+ &arm_elf,
+ NULL
+};
+
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm/ldscript.arm b/usr/src/boot/sys/boot/efi/loader/arch/arm/ldscript.arm
new file mode 100644
index 0000000000..8b4a6dc64b
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm/ldscript.arm
@@ -0,0 +1,62 @@
+/* $FreeBSD$ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ .text : {
+ *(.peheader)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ . = ALIGN(16);
+ .data :
+ {
+ *(.data *.data.*)
+ *(.gnu.linkonce.d*)
+ *(.rodata)
+ *(.rodata.*)
+ CONSTRUCTORS
+
+ . = ALIGN(4);
+ PROVIDE (__bss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ PROVIDE (__bss_end = .);
+ }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata*.sdata.* .gnu.linkonce.s.*)
+ }
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ __gp = .;
+ .plt : { *(.plt) }
+ .dynamic : { *(.dynamic) }
+ .reloc : { *(.reloc) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.dyn : {
+ *(.rel.*)
+ *(.relset_*)
+ }
+ _edata = .;
+ .hash : { *(.hash) }
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm/start.S b/usr/src/boot/sys/boot/efi/loader/arch/arm/start.S
new file mode 100644
index 0000000000..443de4af1f
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm/start.S
@@ -0,0 +1,189 @@
+/*-
+ * Copyright (c) 2014, 2015 Andrew Turner
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+/*
+ * We need to be a PE32 file for EFI. On some architectures we can use
+ * objcopy to create the correct file, however on arm we need to do
+ * it ourselves.
+ */
+
+#define IMAGE_FILE_MACHINE_ARM 0x01c2
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+
+ .section .peheader
+efi_start:
+ /* The MS-DOS Stub, only used to get the offset of the COFF header */
+ .ascii "MZ"
+ .short 0
+ .space 0x38
+ .long pe_sig - efi_start
+
+ /* The PE32 Signature. Needs to be 8-byte aligned */
+ .align 3
+pe_sig:
+ .ascii "PE"
+ .short 0
+coff_head:
+ .short IMAGE_FILE_MACHINE_ARM /* ARM file */
+ .short 2 /* 2 Sections */
+ .long 0 /* Timestamp */
+ .long 0 /* No symbol table */
+ .long 0 /* No symbols */
+ .short section_table - optional_header /* Optional header size */
+ .short 0 /* Characteristics TODO: Fill in */
+
+optional_header:
+ .short 0x010b /* PE32 (32-bit addressing) */
+ .byte 0 /* Major linker version */
+ .byte 0 /* Minor linker version */
+ .long _edata - _end_header /* Code size */
+ .long 0 /* No initialized data */
+ .long 0 /* No uninitialized data */
+ .long _start - efi_start /* Entry point */
+ .long _end_header - efi_start /* Start of code */
+ .long 0 /* Start of data */
+
+optional_windows_header:
+ .long 0 /* Image base */
+ .long 32 /* Section Alignment */
+ .long 8 /* File alignment */
+ .short 0 /* Major OS version */
+ .short 0 /* Minor OS version */
+ .short 0 /* Major image version */
+ .short 0 /* Minor image version */
+ .short 0 /* Major subsystem version */
+ .short 0 /* Minor subsystem version */
+ .long 0 /* Win32 version */
+ .long _edata - efi_start /* Image size */
+ .long _end_header - efi_start /* Header size */
+ .long 0 /* Checksum */
+ .short 0xa /* Subsystem (EFI app) */
+ .short 0 /* DLL Characteristics */
+ .long 0 /* Stack reserve */
+ .long 0 /* Stack commit */
+ .long 0 /* Heap reserve */
+ .long 0 /* Heap commit */
+ .long 0 /* Loader flags */
+ .long 6 /* Number of RVAs */
+
+ /* RVAs: */
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+
+section_table:
+ /* We need a .reloc section for EFI */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 /* Pad to 8 bytes */
+ .long 0 /* Virtual size */
+ .long 0 /* Virtual address */
+ .long 0 /* Size of raw data */
+ .long 0 /* Pointer to raw data */
+ .long 0 /* Pointer to relocations */
+ .long 0 /* Pointer to line numbers */
+ .short 0 /* Number of relocations */
+ .short 0 /* Number of line numbers */
+ .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */
+
+ /* The contents of the loader */
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 /* Pad to 8 bytes */
+ .long _edata - _end_header /* Virtual size */
+ .long _end_header - efi_start /* Virtual address */
+ .long _edata - _end_header /* Size of raw data */
+ .long _end_header - efi_start /* Pointer to raw data */
+ .long 0 /* Pointer to relocations */
+ .long 0 /* Pointer to line numbers */
+ .short 0 /* Number of relocations */
+ .short 0 /* Number of line numbers */
+ .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ) /* Characteristics */
+_end_header:
+
+ .text
+_start:
+ /* Save the boot params to the stack */
+ push {r0, r1}
+
+ adr r0, .Lbase
+ ldr r1, [r0]
+ sub r5, r0, r1
+
+ ldr r0, .Limagebase
+ add r0, r0, r5
+ ldr r1, .Ldynamic
+ add r1, r1, r5
+
+ bl _C_LABEL(self_reloc)
+
+ /* Zero the BSS, _reloc fixed the values for us */
+ ldr r0, .Lbss
+ ldr r1, .Lbssend
+ mov r2, #0
+
+1: cmp r0, r1
+ bgt 2f
+ str r2, [r0], #4
+ b 1b
+2:
+
+ pop {r0, r1}
+ bl _C_LABEL(efi_main)
+
+1: b 1b
+
+.Lbase:
+ .word .
+.Limagebase:
+ .word ImageBase
+.Ldynamic:
+ .word _DYNAMIC
+.Lbss:
+ .word __bss_start
+.Lbssend:
+ .word __bss_end
+
+.align 3
+stack:
+ .space 512
+stack_end:
+
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm64/Makefile.inc b/usr/src/boot/sys/boot/efi/loader/arch/arm64/Makefile.inc
new file mode 100644
index 0000000000..d263db956a
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm64/Makefile.inc
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+LOADER_FDT_SUPPORT=yes
+SRCS+= exec.c \
+ start.S
+
+.PATH: ${.CURDIR}/../../arm64/libarm64
+CFLAGS+=-I${.CURDIR}/../../arm64/libarm64
+SRCS+= cache.c
+
+CFLAGS+= -msoft-float -mgeneral-regs-only
+
+CLEANFILES+= loader.help
+
+loader.help: help.common
+ cat ${.ALLSRC} | \
+ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+
+.if !defined(LOADER_ONLY)
+.PATH: ${.CURDIR}/../../forth
+.include "${.CURDIR}/../../forth/Makefile.inc"
+
+FILES+= loader.rc
+.endif
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm64/exec.c b/usr/src/boot/sys/boot/efi/loader/arch/arm64/exec.c
new file mode 100644
index 0000000000..eb1830c548
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm64/exec.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <machine/elf.h>
+
+#include <bootstrap.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "loader_efi.h"
+#include "cache.h"
+
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#define ACPI_USE_SYSTEM_INTTYPES
+#include "actypes.h"
+#include "actbl.h"
+
+static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
+static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
+
+static int elf64_exec(struct preloaded_file *amp);
+static int elf64_obj_exec(struct preloaded_file *amp);
+
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+
+static struct file_format arm64_elf = {
+ elf64_loadfile,
+ elf64_exec
+};
+
+struct file_format *file_formats[] = {
+ &arm64_elf,
+ NULL
+};
+
+static int
+elf64_exec(struct preloaded_file *fp)
+{
+ vm_offset_t modulep, kernendp;
+ vm_offset_t clean_addr;
+ size_t clean_size;
+ struct file_metadata *md;
+ ACPI_TABLE_RSDP *rsdp;
+ Elf_Ehdr *ehdr;
+ char buf[24];
+ int err, revision;
+ void (*entry)(vm_offset_t);
+
+ rsdp = efi_get_table(&acpi20_guid);
+ if (rsdp == NULL) {
+ rsdp = efi_get_table(&acpi_guid);
+ }
+ if (rsdp != NULL) {
+ sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
+ setenv("hint.acpi.0.rsdp", buf, 1);
+ revision = rsdp->Revision;
+ if (revision == 0)
+ revision = 1;
+ sprintf(buf, "%d", revision);
+ setenv("hint.acpi.0.revision", buf, 1);
+ strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+ buf[sizeof(rsdp->OemId)] = '\0';
+ setenv("hint.acpi.0.oem", buf, 1);
+ sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
+ setenv("hint.acpi.0.rsdt", buf, 1);
+ if (revision >= 2) {
+ /* XXX extended checksum? */
+ sprintf(buf, "0x%016llx",
+ (unsigned long long)rsdp->XsdtPhysicalAddress);
+ setenv("hint.acpi.0.xsdt", buf, 1);
+ sprintf(buf, "%d", rsdp->Length);
+ setenv("hint.acpi.0.xsdt_length", buf, 1);
+ }
+ }
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+ entry = efi_translate(ehdr->e_entry);
+
+ err = bi_load(fp->f_args, &modulep, &kernendp);
+ if (err != 0)
+ return (err);
+
+ dev_cleanup();
+
+ /* Clean D-cache under kernel area and invalidate whole I-cache */
+ clean_addr = (vm_offset_t)efi_translate(fp->f_addr);
+ clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr;
+
+ cpu_flush_dcache((void *)clean_addr, clean_size);
+ cpu_inval_icache(NULL, 0);
+
+ (*entry)(modulep);
+ panic("exec returned");
+}
+
+static int
+elf64_obj_exec(struct preloaded_file *fp)
+{
+
+ printf("%s called for preloaded file %p (=%s):\n", __func__, fp,
+ fp->f_name);
+ return (ENOSYS);
+}
+
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm64/ldscript.arm64 b/usr/src/boot/sys/boot/efi/loader/arch/arm64/ldscript.arm64
new file mode 100644
index 0000000000..7b62eaa4d6
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm64/ldscript.arm64
@@ -0,0 +1,80 @@
+/* $FreeBSD$ */
+/*
+OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd")
+*/
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ .text : {
+ *(.peheader)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.plt)
+ } =0x00300000010070000002000001000400
+ . = ALIGN(16);
+ .data : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ *(.opd)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.plabel)
+
+ . = ALIGN(16);
+ __bss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss *.bss.*)
+ *(COMMON)
+ . = ALIGN(16);
+ __bss_end = .;
+ }
+ . = ALIGN(16);
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ . = ALIGN(16);
+ __gp = .;
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(dynsbss)
+ *(.scommon)
+ }
+ . = ALIGN(16);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(16);
+ .rela.dyn : {
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.got)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ *(.rela.plt)
+ *(.relset_*)
+ *(.rela.dyn .rela.dyn.*)
+ }
+ . = ALIGN(16);
+ .reloc : { *(.reloc) }
+ . = ALIGN(16);
+ .dynsym : { *(.dynsym) }
+ _edata = .;
+
+ /* Unused sections */
+ .dynstr : { *(.dynstr) }
+ .hash : { *(.hash) }
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/arm64/start.S b/usr/src/boot/sys/boot/efi/loader/arch/arm64/start.S
new file mode 100644
index 0000000000..cd9badb05b
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/arm64/start.S
@@ -0,0 +1,165 @@
+/*-
+ * Copyright (c) 2014 Andrew Turner
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * We need to be a PE32+ file for EFI. On some architectures we can use
+ * objcopy to create the correct file, however on arm64 we need to do
+ * it ourselves.
+ */
+
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+
+ .section .peheader
+efi_start:
+ /* The MS-DOS Stub, only used to get the offset of the COFF header */
+ .ascii "MZ"
+ .short 0
+ .space 0x38
+ .long pe_sig - efi_start
+
+ /* The PE32 Signature. Needs to be 8-byte aligned */
+ .align 3
+pe_sig:
+ .ascii "PE"
+ .short 0
+coff_head:
+ .short IMAGE_FILE_MACHINE_ARM64 /* AArch64 file */
+ .short 2 /* 2 Sections */
+ .long 0 /* Timestamp */
+ .long 0 /* No symbol table */
+ .long 0 /* No symbols */
+ .short section_table - optional_header /* Optional header size */
+ .short 0 /* Characteristics TODO: Fill in */
+
+optional_header:
+ .short 0x020b /* PE32+ (64-bit addressing) */
+ .byte 0 /* Major linker version */
+ .byte 0 /* Minor linker version */
+ .long _edata - _end_header /* Code size */
+ .long 0 /* No initialized data */
+ .long 0 /* No uninitialized data */
+ .long _start - efi_start /* Entry point */
+ .long _end_header - efi_start /* Start of code */
+
+optional_windows_header:
+ .quad 0 /* Image base */
+ .long 32 /* Section Alignment */
+ .long 8 /* File alignment */
+ .short 0 /* Major OS version */
+ .short 0 /* Minor OS version */
+ .short 0 /* Major image version */
+ .short 0 /* Minor image version */
+ .short 0 /* Major subsystem version */
+ .short 0 /* Minor subsystem version */
+ .long 0 /* Win32 version */
+ .long _edata - efi_start /* Image size */
+ .long _end_header - efi_start /* Header size */
+ .long 0 /* Checksum */
+ .short 0xa /* Subsystem (EFI app) */
+ .short 0 /* DLL Characteristics */
+ .quad 0 /* Stack reserve */
+ .quad 0 /* Stack commit */
+ .quad 0 /* Heap reserve */
+ .quad 0 /* Heap commit */
+ .long 0 /* Loader flags */
+ .long 6 /* Number of RVAs */
+
+ /* RVAs: */
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+ .quad 0
+
+section_table:
+ /* We need a .reloc section for EFI */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 /* Pad to 8 bytes */
+ .long 0 /* Virtual size */
+ .long 0 /* Virtual address */
+ .long 0 /* Size of raw data */
+ .long 0 /* Pointer to raw data */
+ .long 0 /* Pointer to relocations */
+ .long 0 /* Pointer to line numbers */
+ .short 0 /* Number of relocations */
+ .short 0 /* Number of line numbers */
+ .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */
+
+ /* The contents of the loader */
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 /* Pad to 8 bytes */
+ .long _edata - _end_header /* Virtual size */
+ .long _end_header - efi_start /* Virtual address */
+ .long _edata - _end_header /* Size of raw data */
+ .long _end_header - efi_start /* Pointer to raw data */
+ .long 0 /* Pointer to relocations */
+ .long 0 /* Pointer to line numbers */
+ .short 0 /* Number of relocations */
+ .short 0 /* Number of line numbers */
+ .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ) /* Characteristics */
+_end_header:
+
+ .text
+ .globl _start
+_start:
+ /* Save the boot params to the stack */
+ stp x0, x1, [sp, #-16]!
+
+ adr x0, __bss_start
+ adr x1, __bss_end
+
+ b 2f
+
+1:
+ stp xzr, xzr, [x0], #16
+2:
+ cmp x0, x1
+ b.lo 1b
+
+ adr x0, ImageBase
+ adr x1, _DYNAMIC
+
+ bl self_reloc
+
+ ldp x0, x1, [sp], #16
+
+ bl efi_main
+
+1: b 1b
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/Makefile.inc b/usr/src/boot/sys/boot/efi/loader/arch/i386/Makefile.inc
new file mode 100644
index 0000000000..4e08c53763
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/Makefile.inc
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+SRCS+= start.S \
+ efimd.c \
+ elf32_freebsd.c \
+ exec.c
+
+.PATH: ${.CURDIR}/../../i386/libi386
+SRCS+= nullconsole.c \
+ comconsole.c
+
+CFLAGS+= -fPIC
+LDFLAGS+= -Wl,-znocombreloc
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/bootinfo.c b/usr/src/boot/sys/boot/efi/loader/arch/i386/bootinfo.c
new file mode 100644
index 0000000000..cbd6e4ebe9
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/bootinfo.c
@@ -0,0 +1,275 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "libi386.h"
+#include <machine/bootinfo.h>
+
+static const char howto_switches[] = "aCdrgDmphsv";
+static int howto_masks[] = {
+ RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
+ RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
+};
+
+int
+bi_getboothowto(char *kargs)
+{
+ const char *sw;
+ char *opts;
+ int howto, i;
+
+ howto = 0;
+
+ /* Get the boot options from the environment first. */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+
+ /* Parse kargs */
+ if (kargs == NULL)
+ return (howto);
+
+ opts = strchr(kargs, '-');
+ while (opts != NULL) {
+ while (*(++opts) != '\0') {
+ sw = strchr(howto_switches, *opts);
+ if (sw == NULL)
+ break;
+ howto |= howto_masks[sw - howto_switches];
+ }
+ opts = strchr(opts, '-');
+ }
+
+ return (howto);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+bi_copyenv(vm_offset_t start)
+{
+ struct env_var *ep;
+ vm_offset_t addr, last;
+ size_t len;
+
+ addr = last = start;
+
+ /* Traverse the environment. */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ len = strlen(ep->ev_name);
+ if (i386_copyin(ep->ev_name, addr, len) != len)
+ break;
+ addr += len;
+ if (i386_copyin("=", addr, 1) != 1)
+ break;
+ addr++;
+ if (ep->ev_value != NULL) {
+ len = strlen(ep->ev_value);
+ if (i386_copyin(ep->ev_value, addr, len) != len)
+ break;
+ addr += len;
+ }
+ if (i386_copyin("", addr, 1) != 1)
+ break;
+ last = ++addr;
+ }
+
+ if (i386_copyin("", last++, 1) != 1)
+ last = start;
+ return(last);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a) { \
+ u_int32_t x = (v); \
+ i386_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(strlen(s) + 1, a); \
+ i386_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
+}
+
+#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
+#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
+#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s)
+
+#define MOD_VAR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(sizeof(s), a); \
+ i386_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
+#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
+
+#define MOD_METADATA(a, mm) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a); \
+ COPY32(mm->md_size, a); \
+ i386_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t));\
+}
+
+#define MOD_END(a) { \
+ COPY32(MODINFO_END, a); \
+ COPY32(0, a); \
+}
+
+vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+
+ /* Start with the first module on the list, should be the kernel. */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+ /* The name field must come first. */
+ MOD_NAME(addr, fp->f_name);
+ MOD_TYPE(addr, fp->f_type);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args);
+ MOD_ADDR(addr, fp->f_addr);
+ MOD_SIZE(addr, fp->f_size);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md);
+ }
+ }
+ MOD_END(addr);
+ return(addr);
+}
+
+/*
+ * Load the information expected by the kernel.
+ *
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(struct preloaded_file *fp, uint64_t *bi_addr)
+{
+ struct bootinfo bi;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ struct devdesc *rootdev;
+ char *rootdevname;
+ vm_offset_t addr, ssym, esym;
+
+ bzero(&bi, sizeof(struct bootinfo));
+ bi.bi_version = 1;
+// bi.bi_boothowto = bi_getboothowto(fp->f_args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied
+ * device. This should perhaps go to MI code and/or have $rootdev
+ * tested/set by MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ i386_getdev((void**)&rootdev, rootdevname, NULL);
+ if (rootdev != NULL) {
+ /* Try reading /etc/fstab to select the root device. */
+ getrootmount(i386_fmtdev(rootdev));
+ free(rootdev);
+ }
+
+ md = file_findmetadata(fp, MODINFOMD_SSYM);
+ ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ md = file_findmetadata(fp, MODINFOMD_ESYM);
+ esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ if (ssym != 0 && esym != 0) {
+ bi.bi_symtab = ssym;
+ bi.bi_esymtab = esym;
+ }
+
+ /* Find the last module in the chain. */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy module list and metadata. */
+ bi.bi_modulep = addr;
+ addr = bi_copymodules(addr);
+ if (addr <= bi.bi_modulep) {
+ addr = bi.bi_modulep;
+ bi.bi_modulep = 0;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy our environment. */
+ bi.bi_envp = addr;
+ addr = bi_copyenv(addr);
+ if (addr <= bi.bi_envp) {
+ addr = bi.bi_envp;
+ bi.bi_envp = 0;
+ }
+
+ addr = (addr + PAGE_MASK) & ~PAGE_MASK;
+ bi.bi_kernend = addr;
+
+ return (ldr_bootinfo(&bi, bi_addr));
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/efimd.c b/usr/src/boot/sys/boot/efi/loader/arch/i386/efimd.c
new file mode 100644
index 0000000000..01905e664f
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/efimd.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <libi386.h>
+#include <machine/bootinfo.h>
+
+#define EFI_INTEL_FPSWA \
+ {0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+
+static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
+
+/* DIG64 Headless Console & Debug Port Table. */
+#define HCDP_TABLE_GUID \
+ {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
+static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
+
+static UINTN mapkey;
+
+uint64_t
+ldr_alloc(vm_offset_t va)
+{
+
+ return (0);
+}
+
+int
+ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
+{
+ VOID *fpswa;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_HANDLE handle;
+ EFI_STATUS status;
+ size_t bisz;
+ UINTN mmsz, pages, sz;
+ UINT32 mmver;
+
+ bi->bi_systab = (uint64_t)ST;
+ bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
+
+ sz = sizeof(EFI_HANDLE);
+ status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
+ if (status == 0)
+ status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
+ bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
+
+ bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
+
+ /*
+ * Allocate enough pages to hold the bootinfo block and the memory
+ * map EFI will return to us. The memory map has an unknown size,
+ * so we have to determine that first. Note that the AllocatePages
+ * call can itself modify the memory map, so we have to take that
+ * into account as well. The changes to the memory map are caused
+ * by splitting a range of free memory into two (AFAICT), so that
+ * one is marked as being loader data.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 15) & ~15;
+ pages = EFI_SIZE_TO_PAGES(sz + bisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+ &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+ (long)status);
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ *bi_addr = addr;
+ mm = (void *)(addr + bisz);
+ sz = (EFI_PAGE_SIZE * pages) - bisz;
+ status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+ bi->bi_memmap = (uint64_t)mm;
+ bi->bi_memmap_size = sz;
+ bi->bi_memdesc_size = mmsz;
+ bi->bi_memdesc_version = mmver;
+
+ bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
+ return (0);
+}
+
+int
+ldr_enter(const char *kernel)
+{
+ EFI_STATUS status;
+
+ status = BS->ExitBootServices(IH, mapkey);
+ if (EFI_ERROR(status)) {
+ printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/elf32_freebsd.c b/usr/src/boot/sys/boot/efi/loader/arch/i386/elf32_freebsd.c
new file mode 100644
index 0000000000..bae8f7bbca
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/elf32_freebsd.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "../libi386/libi386.h"
+#include "../btx/lib/btxv86.h"
+
+extern void __exec(caddr_t addr, ...);
+
+
+static int elf32_exec(struct preloaded_file *amp);
+static int elf32_obj_exec(struct preloaded_file *amp);
+
+struct file_format i386_elf = { elf32_loadfile, elf32_exec };
+struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
+
+struct file_format *file_formats[] = {
+ &i386_elf,
+ &i386_elf_obj,
+ NULL
+};
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf32_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t entry, bootinfop, modulep, kernend;
+ int boothowto, err, bootdev;
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+ entry = ehdr->e_entry & 0xffffff;
+
+ printf("Start @ 0x%lx ...\n", entry);
+
+ ldr_enter(fp->f_name);
+
+ dev_cleanup();
+ __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend);
+
+ panic("exec returned");
+}
+
+static int
+elf32_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/exec.c b/usr/src/boot/sys/boot/efi/loader/arch/i386/exec.c
new file mode 100644
index 0000000000..579f5593b2
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/exec.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <machine/elf.h>
+#include "../btx/lib/btxv86.h"
+
+#include "../../common/bootstrap.h"
+
+uint32_t __base;
+struct __v86 __v86;
+
+void
+__v86int()
+{
+ printf("%s\n", __func__);
+ exit(1);
+}
+
+void
+__exec(caddr_t addr, ...)
+{
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/i386_copy.c b/usr/src/boot/sys/boot/efi/loader/arch/i386/i386_copy.c
new file mode 100644
index 0000000000..522913f5da
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/i386_copy.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * MD primitives supporting placement of module data
+ *
+ * XXX should check load address/size against memory top.
+ */
+#include <stand.h>
+
+#include "libi386.h"
+#include "btxv86.h"
+
+ssize_t
+i386_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ bcopy(src, PTOV(dest), len);
+ return(len);
+}
+
+ssize_t
+i386_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ bcopy(PTOV(src), dest, len);
+ return(len);
+}
+
+
+ssize_t
+i386_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ return (read(fd, PTOV(dest), len));
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/ldscript.i386 b/usr/src/boot/sys/boot/efi/loader/arch/i386/ldscript.i386
new file mode 100644
index 0000000000..fdfda0a05c
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/ldscript.i386
@@ -0,0 +1,72 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ . = SIZEOF_HEADERS;
+ . = ALIGN(4096);
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.plt)
+ } =0x00300000010070000002000001000400
+ . = ALIGN(4096);
+ .data : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ *(.opd)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.plabel)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ . = ALIGN(4096);
+ __gp = .;
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rel.dyn : {
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.got)
+ *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ *(.rel.plt)
+ *(.relset_*)
+ *(.rel.dyn .rel.dyn.*)
+ }
+ . = ALIGN(4096);
+ .reloc : { *(.reloc) }
+ . = ALIGN(4096);
+ .hash : { *(.hash) }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/arch/i386/start.S b/usr/src/boot/sys/boot/efi/loader/arch/i386/start.S
new file mode 100644
index 0000000000..b597f419d4
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/arch/i386/start.S
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+ .text
+
+#include <machine/asm.h>
+
+#define EFI_SUCCESS 0
+
+/*
+ * EFI entry point.
+ * _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table);
+ *
+ * We calculate the base address along with _DYNAMIC, relocate us and finally
+ * pass control to efi_main.
+ */
+
+ENTRY(_start)
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl 12(%ebp) /* image_handle */
+ pushl 8(%ebp) /* system_table */
+ call 0f
+0: popl %eax
+ movl %eax, %ebx
+ addl $ImageBase-0b, %eax
+ addl $_DYNAMIC-0b, %ebx
+ pushl %ebx /* dynamic */
+ pushl %eax /* ImageBase */
+ call self_reloc
+ popl %ebx /* remove ImageBase from the stack */
+ popl %ebx /* remove dynamic from the stack */
+ call efi_main
+1: leave
+ ret
+END(_start)
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
diff --git a/usr/src/boot/sys/boot/efi/loader/autoload.c b/usr/src/boot/sys/boot/efi/loader/autoload.c
new file mode 100644
index 0000000000..c1eb84928e
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/autoload.c
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "loader_efi.h"
+
+int
+efi_autoload(void)
+{
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/bootinfo.c b/usr/src/boot/sys/boot/efi/loader/bootinfo.c
new file mode 100644
index 0000000000..c6a76abc08
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/bootinfo.c
@@ -0,0 +1,463 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+#include <machine/cpufunc.h>
+#include <machine/elf.h>
+#include <machine/metadata.h>
+#include <machine/psl.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "loader_efi.h"
+
+#if defined(__amd64__)
+#include <machine/specialreg.h>
+#include "framebuffer.h"
+#endif
+
+#if defined(LOADER_FDT_SUPPORT)
+#include <fdt_platform.h>
+#endif
+
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+
+extern EFI_SYSTEM_TABLE *ST;
+
+static const char howto_switches[] = "aCdrgDmphsv";
+static int howto_masks[] = {
+ RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
+ RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
+};
+
+static int
+bi_getboothowto(char *kargs)
+{
+ const char *sw;
+ char *opts;
+ char *console;
+ int howto, i;
+
+ howto = 0;
+
+ /* Get the boot options from the environment first. */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+
+ console = getenv("console");
+ if (console != NULL) {
+ if (strcmp(console, "comconsole") == 0)
+ howto |= RB_SERIAL;
+ if (strcmp(console, "nullconsole") == 0)
+ howto |= RB_MUTE;
+ }
+
+ /* Parse kargs */
+ if (kargs == NULL)
+ return (howto);
+
+ opts = strchr(kargs, '-');
+ while (opts != NULL) {
+ while (*(++opts) != '\0') {
+ sw = strchr(howto_switches, *opts);
+ if (sw == NULL)
+ break;
+ howto |= howto_masks[sw - howto_switches];
+ }
+ opts = strchr(opts, '-');
+ }
+
+ return (howto);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+static vm_offset_t
+bi_copyenv(vm_offset_t start)
+{
+ struct env_var *ep;
+ vm_offset_t addr, last;
+ size_t len;
+
+ addr = last = start;
+
+ /* Traverse the environment. */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ len = strlen(ep->ev_name);
+ if ((size_t)archsw.arch_copyin(ep->ev_name, addr, len) != len)
+ break;
+ addr += len;
+ if (archsw.arch_copyin("=", addr, 1) != 1)
+ break;
+ addr++;
+ if (ep->ev_value != NULL) {
+ len = strlen(ep->ev_value);
+ if ((size_t)archsw.arch_copyin(ep->ev_value, addr, len) != len)
+ break;
+ addr += len;
+ }
+ if (archsw.arch_copyin("", addr, 1) != 1)
+ break;
+ last = ++addr;
+ }
+
+ if (archsw.arch_copyin("", last++, 1) != 1)
+ last = start;
+ return(last);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ uint32_t x = (v); \
+ if (c) \
+ archsw.arch_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ archsw.arch_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_long)); \
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ archsw.arch_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_long)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ archsw.arch_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_long)); \
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+ uint64_t v;
+
+ c = addr != 0;
+ /* Start with the first module on the list, should be the kernel. */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+ MOD_NAME(addr, fp->f_name, c); /* This must come first. */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ v = fp->f_addr;
+#if defined(__arm__)
+ v -= __elfN(relocation_offset);
+#endif
+ MOD_ADDR(addr, v, c);
+ v = fp->f_size;
+ MOD_SIZE(addr, v, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+static int
+bi_load_efi_data(struct preloaded_file *kfp)
+{
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_STATUS status;
+ size_t efisz;
+ UINTN efi_mapkey;
+ UINTN mmsz, pages, retry, sz;
+ UINT32 mmver;
+ struct efi_map_header *efihdr;
+
+#if defined(__amd64__)
+ struct efi_fb efifb;
+
+ if (efi_find_framebuffer(&efifb) == 0) {
+ printf("EFI framebuffer information:\n");
+ printf("addr, size 0x%lx, 0x%lx\n", efifb.fb_addr,
+ efifb.fb_size);
+ printf("dimensions %d x %d\n", efifb.fb_width,
+ efifb.fb_height);
+ printf("stride %d\n", efifb.fb_stride);
+ printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue,
+ efifb.fb_mask_reserved);
+
+ file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb);
+ }
+#endif
+
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+
+ /*
+ * It is possible that the first call to ExitBootServices may change
+ * the map key. Fetch a new map key and retry ExitBootServices in that
+ * case.
+ */
+ for (retry = 2; retry > 0; retry--) {
+ /*
+ * Allocate enough pages to hold the bootinfo block and the
+ * memory map EFI will return to us. The memory map has an
+ * unknown size, so we have to determine that first. Note that
+ * the AllocatePages call can itself modify the memory map, so
+ * we have to take that into account as well. The changes to
+ * the memory map are caused by splitting a range of free
+ * memory into two (AFAICT), so that one is marked as being
+ * loader data.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &efi_mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 0xf) & ~0xf;
+ pages = EFI_SIZE_TO_PAGES(sz + efisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
+ pages, &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages error %lu\n", __func__,
+ EFI_ERROR_CODE(status));
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ efihdr = (struct efi_map_header *)addr;
+ mm = (void *)((uint8_t *)efihdr + efisz);
+ sz = (EFI_PAGE_SIZE * pages) - efisz;
+
+ status = BS->GetMemoryMap(&sz, mm, &efi_mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap error %lu\n", __func__,
+ EFI_ERROR_CODE(status));
+ return (EINVAL);
+ }
+ status = BS->ExitBootServices(IH, efi_mapkey);
+ if (EFI_ERROR(status) == 0) {
+ efihdr->memory_size = sz;
+ efihdr->descriptor_size = mmsz;
+ efihdr->descriptor_version = mmver;
+ file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz,
+ efihdr);
+ return (0);
+ }
+ BS->FreePages(addr, pages);
+ }
+ printf("ExitBootServices error %lu\n", EFI_ERROR_CODE(status));
+ return (EINVAL);
+}
+
+/*
+ * Load the information expected by an amd64 kernel.
+ *
+ * - The 'boothowto' argument is constructed.
+ * - The 'bootdev' argument is constructed.
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ struct devdesc *rootdev;
+ struct file_metadata *md;
+ vm_offset_t addr;
+ uint64_t kernend;
+ uint64_t envp;
+ vm_offset_t size;
+ char *rootdevname;
+ int howto;
+#if defined(LOADER_FDT_SUPPORT)
+ vm_offset_t dtbp;
+ int dtb_size;
+#endif
+#if defined(__arm__)
+ vm_offset_t vaddr;
+ size_t i;
+ /*
+ * These metadata addreses must be converted for kernel after
+ * relocation.
+ */
+ uint32_t mdt[] = {
+ MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND,
+ MODINFOMD_ENVP,
+#if defined(LOADER_FDT_SUPPORT)
+ MODINFOMD_DTBP
+#endif
+ };
+#endif
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied
+ * device. This should perhaps go to MI code and/or have $rootdev
+ * tested/set by MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ archsw.arch_getdev((void**)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) {
+ printf("Can't determine root device.\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(efi_fmtdev((void *)rootdev));
+
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+
+ /* Pad to a page boundary. */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* Copy our environment. */
+ envp = addr;
+ addr = bi_copyenv(addr);
+
+ /* Pad to a page boundary. */
+ addr = roundup(addr, PAGE_SIZE);
+
+#if defined(LOADER_FDT_SUPPORT)
+ /* Handle device tree blob */
+ dtbp = addr;
+ dtb_size = fdt_copy(addr);
+
+ /* Pad to a page boundary */
+ if (dtb_size)
+ addr += roundup(dtb_size, PAGE_SIZE);
+#endif
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+#if defined(LOADER_FDT_SUPPORT)
+ if (dtb_size)
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp);
+ else
+ pager_output("WARNING! Trying to fire up the kernel, but no "
+ "device tree blob found!\n");
+#endif
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof ST, &ST);
+
+ bi_load_efi_data(kfp);
+
+ /* Figure out the size and location of the metadata. */
+ *modulep = addr;
+ size = bi_copymodules(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+#if defined(__arm__)
+ *modulep -= __elfN(relocation_offset);
+
+ /* Do relocation fixup on metadata of each module. */
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ for (i = 0; i < sizeof mdt / sizeof mdt[0]; i++) {
+ md = file_findmetadata(xp, mdt[i]);
+ if (md) {
+ bcopy(md->md_data, &vaddr, sizeof vaddr);
+ vaddr -= __elfN(relocation_offset);
+ bcopy(&vaddr, md->md_data, sizeof vaddr);
+ }
+ }
+ }
+#endif
+
+ /* Copy module list and metadata. */
+ (void)bi_copymodules(addr);
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/conf.c b/usr/src/boot/sys/boot/efi/loader/conf.c
new file mode 100644
index 0000000000..b805baffa8
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/conf.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <efi.h>
+#include <efilib.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+
+struct devsw *devsw[] = {
+ &efipart_dev,
+ &efinet_dev,
+#ifdef EFI_ZFS_BOOT
+ &zfs_dev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+ &gzipfs_fsops,
+#ifdef EFI_ZFS_BOOT
+ &zfs_fsops,
+#endif
+ &dosfs_fsops,
+ &ufs_fsops,
+ &cd9660_fsops,
+ &dosfs_fsops,
+ &nfs_fsops,
+ &bzipfs_fsops,
+ NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+ &efinetif,
+ NULL
+};
+
+extern struct console efi_console;
+#if defined(__amd64__) || defined(__i386__)
+extern struct console ttya;
+extern struct console ttyb;
+extern struct console ttyc;
+extern struct console ttyd;
+extern struct console nullconsole;
+extern struct console spinconsole;
+#endif
+
+struct console *consoles[] = {
+#if defined(__amd64__) || defined(__i386__)
+ &efi_console,
+ &ttya,
+ &ttyb,
+ &ttyc,
+ &ttyd,
+ &nullconsole,
+ &spinconsole,
+#endif
+ NULL
+};
diff --git a/usr/src/boot/sys/boot/efi/loader/copy.c b/usr/src/boot/sys/boot/efi/loader/copy.c
new file mode 100644
index 0000000000..128196e269
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/copy.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "loader_efi.h"
+
+#ifndef EFI_STAGING_SIZE
+#define EFI_STAGING_SIZE 48
+#endif
+
+#define STAGE_PAGES EFI_SIZE_TO_PAGES((EFI_STAGING_SIZE) * 1024 * 1024)
+
+EFI_PHYSICAL_ADDRESS staging, staging_end;
+int stage_offset_set = 0;
+ssize_t stage_offset;
+
+int
+efi_copy_init(void)
+{
+ EFI_STATUS status;
+
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
+ STAGE_PAGES, &staging);
+ if (EFI_ERROR(status)) {
+ printf("failed to allocate staging area: %lu\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+ staging_end = staging + STAGE_PAGES * EFI_PAGE_SIZE;
+
+#if defined(__aarch64__) || defined(__arm__)
+ /*
+ * Round the kernel load address to a 2MiB value. This is needed
+ * because the kernel builds a page table based on where it has
+ * been loaded in physical address space. As the kernel will use
+ * either a 1MiB or 2MiB page for this we need to make sure it
+ * is correctly aligned for both cases.
+ */
+ staging = roundup2(staging, 2 * 1024 * 1024);
+#endif
+
+ return (0);
+}
+
+void *
+efi_translate(vm_offset_t ptr)
+{
+
+ return ((void *)(ptr + stage_offset));
+}
+
+ssize_t
+efi_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+
+ if (!stage_offset_set) {
+ stage_offset = (vm_offset_t)staging - dest;
+ stage_offset_set = 1;
+ }
+
+ /* XXX: Callers do not check for failure. */
+ if (dest + stage_offset + len > staging_end) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ bcopy(src, (void *)(dest + stage_offset), len);
+ return (len);
+}
+
+ssize_t
+efi_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+
+ /* XXX: Callers do not check for failure. */
+ if (src + stage_offset + len > staging_end) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ bcopy((void *)(src + stage_offset), dest, len);
+ return (len);
+}
+
+
+ssize_t
+efi_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+
+ if (dest + stage_offset + len > staging_end) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ return (read(fd, (void *)(dest + stage_offset), len));
+}
+
+void
+efi_copy_finish(void)
+{
+ uint64_t *src, *dst, *last;
+
+ src = (uint64_t *)staging;
+ dst = (uint64_t *)(staging - stage_offset);
+ last = (uint64_t *)staging_end;
+
+ while (src < last)
+ *dst++ = *src++;
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/devicename.c b/usr/src/boot/sys/boot/efi/loader/devicename.c
new file mode 100644
index 0000000000..8fc80ebbc5
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/devicename.c
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include <sys/disklabel.h>
+#include <sys/param.h>
+#include <bootstrap.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "loader_efi.h"
+
+static int efi_parsedev(struct devdesc **, const char *, const char **);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+efi_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct devdesc **dev = (struct devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no device, then
+ * use the current device instead.
+ */
+ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
+ rv = efi_parsedev(dev, getenv("currdev"), NULL);
+ if (rv == 0 && path != NULL)
+ *path = devspec;
+ return (rv);
+ }
+
+ /* Parse the device name off the beginning of the devspec. */
+ return (efi_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * fs<unit>:
+ */
+static int
+efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return (EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+ break;
+ }
+ if (devsw[i] == NULL)
+ return (ENOENT);
+
+ np = devspec + strlen(dv->dv_name);
+
+#ifdef EFI_ZFS_BOOT
+ if (dv->dv_type == DEVT_ZFS) {
+ int err;
+
+ idev = malloc(sizeof(struct zfs_devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ err = zfs_parsedev((struct zfs_devdesc*)idev, np, path);
+ if (err != 0) {
+ free(idev);
+ return (err);
+ }
+ *dev = idev;
+ cp = strchr(np + 1, ':');
+ } else
+#endif
+ {
+ idev = malloc(sizeof(struct devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ idev->d_unit = -1;
+ if (*np != '\0' && *np != ':') {
+ idev->d_unit = strtol(np, &cp, 0);
+ if (cp == np) {
+ idev->d_unit = -1;
+ free(idev);
+ return (EUNIT);
+ }
+ }
+ }
+
+ if (*cp != '\0' && *cp != ':') {
+ free(idev);
+ return (EINVAL);
+ }
+
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+}
+
+char *
+efi_fmtdev(void *vdev)
+{
+ struct devdesc *dev = (struct devdesc *)vdev;
+ static char buf[SPECNAMELEN + 1];
+
+ switch(dev->d_type) {
+#ifdef EFI_ZFS_BOOT
+ case DEVT_ZFS:
+ return (zfs_fmtdev(dev));
+#endif
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ default:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+ }
+
+ return (buf);
+}
+
+/*
+ * Set currdev to suit the value being supplied in (value)
+ */
+int
+efi_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct devdesc *ncurr;
+ int rv;
+
+ rv = efi_parsedev(&ncurr, value, NULL);
+ if (rv != 0)
+ return (rv);
+
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/loader_efi.h b/usr/src/boot/sys/boot/efi/loader/loader_efi.h
new file mode 100644
index 0000000000..ee7c4bb72e
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/loader_efi.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOADER_EFI_COPY_H_
+#define _LOADER_EFI_COPY_H_
+
+#include <stand.h>
+
+int efi_autoload(void);
+
+int efi_getdev(void **vdev, const char *devspec, const char **path);
+char *efi_fmtdev(void *vdev);
+int efi_setcurrdev(struct env_var *ev, int flags, const void *value);
+
+int efi_copy_init(void);
+
+ssize_t efi_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t efi_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t efi_readin(const int fd, vm_offset_t dest, const size_t len);
+void * efi_translate(vm_offset_t ptr);
+
+void efi_copy_finish(void);
+
+#endif /* _LOADER_EFI_COPY_H_ */
diff --git a/usr/src/boot/sys/boot/efi/loader/main.c b/usr/src/boot/sys/boot/efi/loader/main.c
new file mode 100644
index 0000000000..5dc1099cdd
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/main.c
@@ -0,0 +1,1050 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/boot.h>
+#include <stand.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <efigpt.h>
+
+#include <bootstrap.h>
+#include <smbios.h>
+
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+
+#include "loader_efi.h"
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+EFI_GUID acpi = ACPI_TABLE_GUID;
+EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
+EFI_GUID devid = DEVICE_PATH_PROTOCOL;
+EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
+EFI_GUID mps = MPS_TABLE_GUID;
+EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
+EFI_GUID smbios = SMBIOS_TABLE_GUID;
+EFI_GUID smbios3 = SMBIOS3_TABLE_GUID;
+EFI_GUID dxe = DXE_SERVICES_TABLE_GUID;
+EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
+EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
+EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
+EFI_GUID fdtdtb = FDT_TABLE_GUID;
+EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
+EFI_GUID serial_io = SERIAL_IO_PROTOCOL;
+
+extern void acpi_detect(const caddr_t);
+void efi_serial_init(void);
+#ifdef EFI_ZFS_BOOT
+static void efi_zfs_probe(void);
+#endif
+
+/*
+ * Need this because EFI uses UTF-16 unicode string constants, but we
+ * use UTF-8. We can't use printf due to the possiblity of \0 and we
+ * don't support support wide characters either.
+ */
+static void
+print_str16(const CHAR16 *str)
+{
+ int i;
+
+ for (i = 0; str[i]; i++)
+ printf("%c", (char)str[i]);
+}
+
+static void
+cp16to8(const CHAR16 *src, char *dst, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len && src[i]; i++)
+ dst[i] = (char)src[i];
+}
+
+static int
+has_keyboard(void)
+{
+ EFI_STATUS status;
+ EFI_DEVICE_PATH *path;
+ EFI_HANDLE *hin, *hin_end, *walker;
+ UINTN sz;
+ int retval = 0;
+
+ /*
+ * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and
+ * do the typical dance to get the right sized buffer.
+ */
+ sz = 0;
+ hin = NULL;
+ status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ hin = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz,
+ hin);
+ if (EFI_ERROR(status))
+ free(hin);
+ }
+ if (EFI_ERROR(status))
+ return retval;
+
+ /*
+ * Look at each of the handles. If it supports the device path protocol,
+ * use it to get the device path for this handle. Then see if that
+ * device path matches either the USB device path for keyboards or the
+ * legacy device path for keyboards.
+ */
+ hin_end = &hin[sz / sizeof(*hin)];
+ for (walker = hin; walker < hin_end; walker++) {
+ status = BS->HandleProtocol(*walker, &devid, (VOID **)&path);
+ if (EFI_ERROR(status))
+ continue;
+
+ while (!IsDevicePathEnd(path)) {
+ /*
+ * Check for the ACPI keyboard node. All PNP3xx nodes
+ * are keyboards of different flavors. Note: It is
+ * unclear of there's always a keyboard node when
+ * there's a keyboard controller, or if there's only one
+ * when a keyboard is detected at boot.
+ */
+ if (DevicePathType(path) == ACPI_DEVICE_PATH &&
+ (DevicePathSubType(path) == ACPI_DP ||
+ DevicePathSubType(path) == ACPI_EXTENDED_DP)) {
+ ACPI_HID_DEVICE_PATH *acpi;
+
+ acpi = (ACPI_HID_DEVICE_PATH *)(void *)path;
+ if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 &&
+ (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) {
+ retval = 1;
+ goto out;
+ }
+ /*
+ * Check for USB keyboard node, if present. Unlike a
+ * PS/2 keyboard, these definitely only appear when
+ * connected to the system.
+ */
+ } else if (DevicePathType(path) == MESSAGING_DEVICE_PATH &&
+ DevicePathSubType(path) == MSG_USB_CLASS_DP) {
+ USB_CLASS_DEVICE_PATH *usb;
+
+ usb = (USB_CLASS_DEVICE_PATH *)(void *)path;
+ if (usb->DeviceClass == 3 && /* HID */
+ usb->DeviceSubClass == 1 && /* Boot devices */
+ usb->DeviceProtocol == 1) { /* Boot keyboards */
+ retval = 1;
+ goto out;
+ }
+ }
+ path = NextDevicePathNode(path);
+ }
+ }
+out:
+ free(hin);
+ return retval;
+}
+
+EFI_STATUS
+main(int argc, CHAR16 *argv[])
+{
+ char var[128];
+ EFI_LOADED_IMAGE *img;
+ EFI_GUID *guid;
+ int i, j, vargood, unit, howto;
+ struct devsw *dev;
+ uint64_t pool_guid;
+ UINTN k;
+ int has_kbd;
+
+ archsw.arch_autoload = efi_autoload;
+ archsw.arch_getdev = efi_getdev;
+ archsw.arch_copyin = efi_copyin;
+ archsw.arch_copyout = efi_copyout;
+ archsw.arch_readin = efi_readin;
+#ifdef EFI_ZFS_BOOT
+ /* Note this needs to be set before ZFS init. */
+ archsw.arch_zfs_probe = efi_zfs_probe;
+#endif
+
+ has_kbd = has_keyboard();
+
+ /*
+ * XXX Chicken-and-egg problem; we want to have console output
+ * early, but some console attributes may depend on reading from
+ * eg. the boot device, which we can't do yet. We can use
+ * printf() etc. once this is done.
+ */
+ cons_probe();
+
+ /*
+ * Initialise the block cache. Set the upper limit.
+ */
+ bcache_init(32768, 512);
+
+ /*
+ * Parse the args to set the console settings, etc
+ * boot1.efi passes these in, if it can read /boot.config or /boot/config
+ * or iPXE may be setup to pass these in.
+ *
+ * Loop through the args, and for each one that contains an '=' that is
+ * not the first character, add it to the environment. This allows
+ * loader and kernel env vars to be passed on the command line. Convert
+ * args from UCS-2 to ASCII (16 to 8 bit) as they are copied.
+ */
+ howto = 0;
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ for (j = 1; argv[i][j] != 0; j++) {
+ int ch;
+
+ ch = argv[i][j];
+ switch (ch) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'P':
+ if (!has_kbd)
+ howto |= RB_SERIAL | RB_MULTIPLE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'S':
+ if (argv[i][j + 1] == 0) {
+ if (i + 1 == argc) {
+ setenv("comconsole_speed", "115200", 1);
+ } else {
+ cp16to8(&argv[i + 1][0], var,
+ sizeof(var));
+ setenv("comconsole_speedspeed", var, 1);
+ }
+ i++;
+ break;
+ } else {
+ cp16to8(&argv[i][j + 1], var,
+ sizeof(var));
+ setenv("comconsole_speed", var, 1);
+ break;
+ }
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ }
+ }
+ } else {
+ vargood = 0;
+ for (j = 0; argv[i][j] != 0; j++) {
+ if (j == sizeof(var)) {
+ vargood = 0;
+ break;
+ }
+ if (j > 0 && argv[i][j] == '=')
+ vargood = 1;
+ var[j] = (char)argv[i][j];
+ }
+ if (vargood) {
+ var[j] = 0;
+ putenv(var);
+ }
+ }
+ }
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (howto & howto_names[i].mask)
+ setenv(howto_names[i].ev, "YES", 1);
+ if (howto & RB_MULTIPLE) {
+ if (howto & RB_SERIAL)
+ setenv("console", "ttya text" , 1);
+ else
+ setenv("console", "text ttya" , 1);
+ } else if (howto & RB_SERIAL) {
+ setenv("console", "ttya" , 1);
+ }
+
+ if (efi_copy_init()) {
+ printf("failed to allocate staging area\n");
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ /* Get our loaded image protocol interface structure. */
+ BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+ printf("Command line arguments:");
+ for (i = 0; i < argc; i++) {
+ printf(" ");
+ print_str16(argv[i]);
+ }
+ printf("\n");
+
+ printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
+ printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
+ ST->Hdr.Revision & 0xffff);
+ printf("EFI Firmware: ");
+ /* printf doesn't understand EFI Unicode */
+ ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor);
+ printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16,
+ ST->FirmwareRevision & 0xffff);
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
+ /*
+ * Disable the watchdog timer. By default the boot manager sets
+ * the timer to 5 minutes before invoking a boot option. If we
+ * want to return to the boot manager, we have to disable the
+ * watchdog timer and since we're an interactive program, we don't
+ * want to wait until the user types "quit". The timer may have
+ * fired by then. We don't care if this fails. It does not prevent
+ * normal functioning in any way...
+ */
+ BS->SetWatchdogTimer(0, 0, 0, NULL);
+
+ if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &pool_guid) != 0)
+ return (EFI_NOT_FOUND);
+
+ switch (dev->dv_type) {
+#ifdef EFI_ZFS_BOOT
+ case DEVT_ZFS: {
+ struct zfs_devdesc currdev;
+
+ currdev.d_dev = dev;
+ currdev.d_unit = unit;
+ currdev.d_type = currdev.d_dev->dv_type;
+ currdev.d_opendata = NULL;
+ currdev.pool_guid = pool_guid;
+ currdev.root_guid = 0;
+ env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
+ efi_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
+ env_nounset);
+#ifdef __FreeBSD__
+ init_zfs_bootenv(zfs_fmtdev(&currdev));
+#endif
+ break;
+ }
+#endif
+ default: {
+ struct devdesc currdev;
+
+ currdev.d_dev = dev;
+ currdev.d_unit = unit;
+ currdev.d_opendata = NULL;
+ currdev.d_type = currdev.d_dev->dv_type;
+ env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
+ efi_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
+ env_nounset);
+ break;
+ }
+ }
+
+ setenv("LINES", "24", 1); /* optional */
+ setenv("COLUMNS", "80", 1); /* optional */
+ setenv("ISADIR", "amd64", 1); /* we only build 64bit */
+
+ for (k = 0; k < ST->NumberOfTableEntries; k++) {
+ guid = &ST->ConfigurationTable[k].VendorGuid;
+ if (!memcmp(guid, &smbios, sizeof(EFI_GUID)) ||
+ !memcmp(guid, &smbios3, sizeof(EFI_GUID))) {
+ smbios_detect(ST->ConfigurationTable[k].VendorTable);
+ continue;
+ }
+ if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) {
+ acpi_detect(ST->ConfigurationTable[k].VendorTable);
+ }
+ }
+
+ efi_serial_init(); /* detect and set up serial ports */
+ interact(NULL); /* doesn't return */
+
+ return (EFI_SUCCESS); /* keep compiler happy */
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ int i;
+ const CHAR16 *msg = L"Reboot from the loader";
+
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+
+ RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 23, (CHAR16 *)msg);
+
+ /* NOTREACHED */
+ return (CMD_ERROR);
+}
+
+COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
+
+static int
+command_memmap(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ UINTN sz;
+ EFI_MEMORY_DESCRIPTOR *map, *p;
+ UINTN key, dsz;
+ UINT32 dver;
+ EFI_STATUS status;
+ int i, ndesc;
+ int rv = 0;
+ char line[80];
+ static const char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode"
+ };
+
+ sz = 0;
+ status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ printf("Can't determine memory map size\n");
+ return (CMD_ERROR);
+ }
+ map = malloc(sz);
+ status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
+ if (EFI_ERROR(status)) {
+ printf("Can't read memory map\n");
+ return (CMD_ERROR);
+ }
+
+ ndesc = sz / dsz;
+ snprintf(line, 80, "%23s %12s %12s %8s %4s\n",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+ pager_open();
+ rv = pager_output(line);
+ if (rv) {
+ pager_close();
+ return (CMD_OK);
+ }
+
+ for (i = 0, p = map; i < ndesc;
+ i++, p = NextMemoryDescriptor(p, dsz)) {
+ snprintf(line, 80, "%23s %012lx %012lx %08lx ",
+ types[p->Type],
+ p->PhysicalStart,
+ p->VirtualStart,
+ p->NumberOfPages);
+ rv = pager_output(line);
+ if (rv)
+ break;
+
+ if (p->Attribute & EFI_MEMORY_UC)
+ printf("UC ");
+ if (p->Attribute & EFI_MEMORY_WC)
+ printf("WC ");
+ if (p->Attribute & EFI_MEMORY_WT)
+ printf("WT ");
+ if (p->Attribute & EFI_MEMORY_WB)
+ printf("WB ");
+ if (p->Attribute & EFI_MEMORY_UCE)
+ printf("UCE ");
+ if (p->Attribute & EFI_MEMORY_WP)
+ printf("WP ");
+ if (p->Attribute & EFI_MEMORY_RP)
+ printf("RP ");
+ if (p->Attribute & EFI_MEMORY_XP)
+ printf("XP ");
+ rv = pager_output("\n");
+ if (rv)
+ break;
+ }
+
+ pager_close();
+ return (CMD_OK);
+}
+
+COMMAND_SET(configuration, "configuration", "print configuration tables",
+ command_configuration);
+
+static const char *
+guid_to_string(EFI_GUID *guid)
+{
+ static char buf[40];
+
+ sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
+ guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
+ guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+ return (buf);
+}
+
+static int
+command_configuration(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ UINTN i;
+
+ printf("NumberOfTableEntries=%lu\n",
+ (unsigned long)ST->NumberOfTableEntries);
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
+ EFI_GUID *guid;
+
+ printf(" ");
+ guid = &ST->ConfigurationTable[i].VendorGuid;
+ if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
+ printf("MPS Table");
+ else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
+ printf("ACPI Table");
+ else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
+ printf("ACPI 2.0 Table");
+ else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
+ printf("SMBIOS Table");
+ else if (!memcmp(guid, &smbios3, sizeof(EFI_GUID)))
+ printf("SMBIOS3 Table");
+ else if (!memcmp(guid, &dxe, sizeof(EFI_GUID)))
+ printf("DXE Table");
+ else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID)))
+ printf("HOB List Table");
+ else if (!memcmp(guid, &memtype, sizeof(EFI_GUID)))
+ printf("Memory Type Information Table");
+ else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID)))
+ printf("Debug Image Info Table");
+ else if (!memcmp(guid, &fdtdtb, sizeof(EFI_GUID)))
+ printf("FDT Table");
+ else
+ printf("Unknown Table (%s)", guid_to_string(guid));
+ printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
+ }
+
+ return (CMD_OK);
+}
+
+
+COMMAND_SET(mode, "mode", "change or display EFI text modes", command_mode);
+
+static int
+command_mode(int argc, char *argv[])
+{
+ UINTN cols, rows;
+ unsigned int mode;
+ int i;
+ char *cp;
+ char rowenv[8];
+ EFI_STATUS status;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+ extern void HO(void);
+
+ conout = ST->ConOut;
+
+ if (argc > 1) {
+ mode = strtol(argv[1], &cp, 0);
+ if (cp[0] != '\0') {
+ printf("Invalid mode\n");
+ return (CMD_ERROR);
+ }
+ status = conout->QueryMode(conout, mode, &cols, &rows);
+ if (EFI_ERROR(status)) {
+ printf("invalid mode %d\n", mode);
+ return (CMD_ERROR);
+ }
+ status = conout->SetMode(conout, mode);
+ if (EFI_ERROR(status)) {
+ printf("couldn't set mode %d\n", mode);
+ return (CMD_ERROR);
+ }
+ sprintf(rowenv, "%u", (unsigned)rows);
+ setenv("LINES", rowenv, 1);
+ sprintf(rowenv, "%u", (unsigned)cols);
+ setenv("COLUMNS", rowenv, 1);
+ HO(); /* set cursor */
+ return (CMD_OK);
+ }
+
+ printf("Current mode: %d\n", conout->Mode->Mode);
+ for (i = 0; i <= conout->Mode->MaxMode; i++) {
+ status = conout->QueryMode(conout, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ continue;
+ printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols,
+ (unsigned)rows);
+ }
+
+ if (i != 0)
+ printf("Select a mode with the command \"mode <number>\"\n");
+
+ return (CMD_OK);
+}
+
+
+COMMAND_SET(nvram, "nvram", "get NVRAM variables", command_nvram);
+
+static int
+command_nvram(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ CHAR16 var[128];
+ UINT8 *data; /* value is in bytes */
+ EFI_STATUS status;
+ EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
+ UINTN varsz, datasz, i;
+ UINT32 attr;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+
+ conout = ST->ConOut;
+
+ pager_open();
+ var[0] = 0; /* Initiate the enumeration */
+ varsz = 128;
+
+ for (status = RS->GetNextVariableName(&varsz, var, &varguid);
+ status != EFI_NOT_FOUND;
+ status = RS->GetNextVariableName(&varsz, var, &varguid)) {
+
+ /*
+ * as term emu is keeping track on cursor, use putchar().
+ */
+ for (i = 0; var[i] != 0; i++)
+ putchar(var[i]);
+ varsz = 128; /* GetNextVariableName() did change it. */
+
+ printf(": Attributes:");
+ datasz = 0;
+ status = RS->GetVariable(var, &varguid, &attr, &datasz, NULL);
+ if ((data = malloc(datasz)) == NULL)
+ break;
+ status = RS->GetVariable(var, &varguid, &attr, &datasz, data);
+ if (EFI_ERROR(status))
+ printf("<error retrieving variable>");
+ else {
+ if (attr & EFI_VARIABLE_NON_VOLATILE)
+ printf(" NV");
+ if (attr & EFI_VARIABLE_BOOTSERVICE_ACCESS)
+ printf(" BS");
+ if (attr & EFI_VARIABLE_RUNTIME_ACCESS)
+ printf(" RS");
+ if (attr & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
+ printf(" HR");
+ if (attr & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+ printf(" AW");
+ if (attr &
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
+ printf(" TW");
+
+ printf(": DataLength: %lld", (long long)datasz);
+ }
+ free(data);
+ if (pager_output("\n"))
+ break;
+ }
+
+ pager_close();
+ return (CMD_OK);
+}
+
+struct protocol_name {
+ EFI_GUID guid;
+ const char *name;
+} proto_names[] = {
+ { DEVICE_PATH_PROTOCOL, "device path" },
+ { BLOCK_IO_PROTOCOL, "block io" },
+ { DISK_IO_PROTOCOL, "disk io" },
+ { EFI_DISK_INFO_PROTOCOL_GUID, "disk info" },
+ { SIMPLE_FILE_SYSTEM_PROTOCOL, "simple fs" },
+ { LOAD_FILE_PROTOCOL, "load file" },
+ { DEVICE_IO_PROTOCOL, "device io" },
+ { UNICODE_COLLATION_PROTOCOL, "unicode collation" },
+ { EFI_UNICODE_COLLATION2_PROTOCOL_GUID, "unicode collation2" },
+ { EFI_SIMPLE_NETWORK_PROTOCOL, "simple network" },
+ { SIMPLE_TEXT_OUTPUT_PROTOCOL, "simple text output" },
+ { SIMPLE_TEXT_INPUT_PROTOCOL, "simple text input" },
+ { EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID, "simple text ex input" },
+ { EFI_CONSOLE_CONTROL_PROTOCOL_GUID, "console control" },
+ { EFI_CONSOLE_IN_DEVICE_GUID, "stdin" },
+ { EFI_CONSOLE_OUT_DEVICE_GUID, "stdout" },
+ { EFI_STANDARD_ERROR_DEVICE_GUID, "stderr" },
+ { EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, "GOP" },
+ { EFI_UGA_DRAW_PROTOCOL_GUID, "UGA draw" },
+ { EFI_PXE_BASE_CODE_PROTOCOL, "PXE base code" },
+ { EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL, "PXE base code callback" },
+ { SERIAL_IO_PROTOCOL, "serial io" },
+ { LOADED_IMAGE_PROTOCOL, "loaded image" },
+ { EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
+ "loaded image device path" },
+ { EFI_ISA_IO_PROTOCOL_GUID, "ISA io" },
+ { EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID, "IDE controller init" },
+ { EFI_ISA_ACPI_PROTOCOL_GUID, "ISA ACPI" },
+ { EFI_PCI_IO_PROTOCOL_GUID, "PCI" },
+ { EFI_PCI_ROOT_IO_GUID, "PCI root" },
+ { EFI_PCI_ENUMERATION_COMPLETE_GUID, "PCI enumeration" },
+ { EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID, "Driver diagnostics" },
+ { EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID, "Driver diagnostics2" },
+ { EFI_SIMPLE_POINTER_PROTOCOL_GUID, "simple pointer" },
+ { EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
+ { EFI_VLAN_CONFIG_PROTOCOL_GUID, "VLAN config" },
+ { EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID, "ARP service binding" },
+ { EFI_ARP_PROTOCOL_GUID, "ARP" },
+ { EFI_IP4_SERVICE_BINDING_PROTOCOL, "IPv4 service binding" },
+ { EFI_IP4_PROTOCOL, "IPv4" },
+ { EFI_IP4_CONFIG_PROTOCOL_GUID, "IPv4 config" },
+ { EFI_IP6_SERVICE_BINDING_PROTOCOL, "IPv6 service binding" },
+ { EFI_IP6_PROTOCOL, "IPv6" },
+ { EFI_IP6_CONFIG_PROTOCOL_GUID, "IPv6 config" },
+ { EFI_UDP4_PROTOCOL, "UDPv4" },
+ { EFI_UDP4_SERVICE_BINDING_PROTOCOL, "UDPv4 service binding" },
+ { EFI_UDP6_PROTOCOL, "UDPv6" },
+ { EFI_UDP6_SERVICE_BINDING_PROTOCOL, "UDPv6 service binding" },
+ { EFI_TCP4_PROTOCOL, "TCPv4" },
+ { EFI_TCP4_SERVICE_BINDING_PROTOCOL, "TCPv4 service binding" },
+ { EFI_TCP6_PROTOCOL, "TCPv6" },
+ { EFI_TCP6_SERVICE_BINDING_PROTOCOL, "TCPv6 service binding" },
+ { EFI_PART_TYPE_EFI_SYSTEM_PART_GUID, "EFI System partition" },
+ { EFI_PART_TYPE_LEGACY_MBR_GUID, "MBR legacy" },
+ { EFI_DEVICE_TREE_GUID, "device tree" },
+ { EFI_USB_IO_PROTOCOL_GUID, "USB io" },
+ { EFI_USB2_HC_PROTOCOL_GUID, "USB2 HC" },
+ { EFI_COMPONENT_NAME_PROTOCOL_GUID, "component name" },
+ { EFI_COMPONENT_NAME2_PROTOCOL_GUID, "component name2" },
+ { EFI_DRIVER_BINDING_PROTOCOL_GUID, "driver binding" },
+ { EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID, "driver configuration" },
+ { EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID, "driver configuration2" },
+ { EFI_DECOMPRESS_PROTOCOL_GUID, "decompress" },
+ { EFI_EBC_INTERPRETER_PROTOCOL_GUID, "ebc interpreter" },
+ { EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL,
+ "network interface identifier" },
+ { EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_31,
+ "network interface identifier_31" },
+ { EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID,
+ "managed network service binding" },
+ { EFI_MANAGED_NETWORK_PROTOCOL_GUID, "managed network" },
+ { EFI_FORM_BROWSER2_PROTOCOL_GUID, "form browser" },
+ { EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, "HII config routing" },
+ { EFI_HII_DATABASE_PROTOCOL_GUID, "HII database" },
+ { EFI_HII_STRING_PROTOCOL_GUID, "HII string" },
+ { EFI_HII_IMAGE_PROTOCOL_GUID, "HII image" },
+ { EFI_HII_FONT_PROTOCOL_GUID, "HII font" },
+ { EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID, "HII config" },
+ { EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID, "MTFTP4 service binding" },
+ { EFI_MTFTP4_PROTOCOL_GUID, "MTFTP4" },
+ { EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID, "MTFTP6 service binding" },
+ { EFI_MTFTP6_PROTOCOL_GUID, "MTFTP6" },
+ { EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID, "DHCP4 service binding" },
+ { EFI_DHCP4_PROTOCOL_GUID, "DHCP4" },
+ { EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID, "DHCP6 service binding" },
+ { EFI_DHCP6_PROTOCOL_GUID, "DHCP6" },
+ { EFI_SCSI_IO_PROTOCOL_GUID, "SCSI io" },
+ { EFI_SCSI_PASS_THRU_PROTOCOL_GUID, "SCSI pass thru" },
+ { EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID, "SCSI pass thru ext" },
+ { EFI_CAPSULE_ARCH_PROTOCOL_GUID, "Capsule arch" },
+ { EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID, "monotonic counter arch" },
+ { EFI_REALTIME_CLOCK_ARCH_PROTOCOL_GUID, "realtime clock arch" },
+ { EFI_VARIABLE_ARCH_PROTOCOL_GUID, "variable arch" },
+ { EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID, "variable write arch" },
+ { EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID, "watchdog timer arch" },
+ { EFI_MP_SERVICES_PROTOCOL_GUID, "MP services" },
+ { EFI_ACPI_SUPPORT_PROTOCOL_GUID, "ACPI support" },
+ { EFI_BDS_ARCH_PROTOCOL_GUID, "BDS arch" },
+ { EFI_METRONOME_ARCH_PROTOCOL_GUID, "metronome arch" },
+ { EFI_TIMER_ARCH_PROTOCOL_GUID, "timer arch" },
+ { EFI_DPC_PROTOCOL_GUID, "DPC" },
+ { EFI_PRINT2_PROTOCOL_GUID, "print2" },
+ { EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, "device path to text" },
+ { EFI_RESET_ARCH_PROTOCOL_GUID, "reset arch" },
+ { EFI_CPU_ARCH_PROTOCOL_GUID, "CPU arch" },
+ { EFI_CPU_IO2_PROTOCOL_GUID, "CPU IO2" },
+ { EFI_LEGACY_8259_PROTOCOL_GUID, "Legacy 8259" },
+ { EFI_SECURITY_ARCH_PROTOCOL_GUID, "Security arch" },
+ { EFI_SECURITY2_ARCH_PROTOCOL_GUID, "Security2 arch" },
+ { EFI_RUNTIME_ARCH_PROTOCOL_GUID, "Runtime arch" },
+ { EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID, "status code runtime" },
+ { EFI_DATA_HUB_PROTOCOL_GUID, "data hub" },
+ { PCD_PROTOCOL_GUID, "PCD" },
+ { EFI_PCD_PROTOCOL_GUID, "EFI PCD" },
+ { EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID, "firmware volume block" },
+ { EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID, "firmware volume2" },
+ { EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID,
+ "firmware volume dispatch" },
+ { LZMA_COMPRESS_GUID, "lzma compress" },
+ { { 0,0,0,{0,0,0,0,0,0,0,0} }, NULL } /* must be last entry */
+};
+
+COMMAND_SET(lsefi, "lsefi", "list EFI handles", command_lsefi);
+
+static int
+command_lsefi(int argc __attribute((unused)),
+ char *argv[] __attribute((unused)))
+{
+ EFI_HANDLE *buffer = NULL;
+ EFI_HANDLE handle;
+ UINTN bufsz = 0, i, j;
+ EFI_STATUS status;
+ int k, ret;
+
+ status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "unexpected error: %lld", (long long)status);
+ return (CMD_ERROR);
+ }
+ if ((buffer = malloc(bufsz)) == NULL) {
+ sprintf(command_errbuf, "out of memory");
+ return (CMD_ERROR);
+ }
+
+ status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer);
+ if (EFI_ERROR(status)) {
+ free(buffer);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "LocateHandle() error: %lld", (long long)status);
+ return (CMD_ERROR);
+ }
+
+ pager_open();
+ for (i = 0; i < (bufsz / sizeof (EFI_HANDLE)); i++) {
+ UINTN nproto = 0;
+ EFI_GUID **protocols = NULL;
+
+ handle = buffer[i];
+ printf("Handle %p", handle);
+ if (pager_output("\n"))
+ break;
+ /* device path */
+
+ status = BS->ProtocolsPerHandle(handle, &protocols, &nproto);
+ if (EFI_ERROR(status)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "ProtocolsPerHandle() error: %lld",
+ (long long)status);
+ continue;
+ }
+ for (j = 0; j < nproto; j++) {
+ for (k = 0; proto_names[k].name != NULL; k++)
+ if (memcmp(protocols[j], &proto_names[k].guid,
+ sizeof (proto_names[k].guid)) == 0)
+ break;
+ if (proto_names[k].name != NULL)
+ printf(" %s", proto_names[k].name);
+ else
+ printf(" %s", guid_to_string(protocols[j]));
+ ret = pager_output("\n");
+ if (ret)
+ break;
+ }
+ BS->FreePool(protocols);
+ if (ret)
+ break;
+ }
+ pager_close();
+ free(buffer);
+ return (CMD_OK);
+}
+
+#ifdef EFI_ZFS_BOOT
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+ command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ err = zfs_list(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+
+#ifdef __FreeBSD__
+COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
+ command_reloadbe);
+
+static int
+command_reloadbe(int argc, char *argv[])
+{
+ int err;
+ char *root;
+
+ if (argc > 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ if (argc == 2) {
+ err = zfs_bootenv(argv[1]);
+ } else {
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ return (CMD_OK);
+ }
+ err = zfs_bootenv(root);
+ }
+
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+
+ return (CMD_OK);
+}
+#endif /* __FreeBSD__ */
+#endif
+
+void
+efi_serial_init(void)
+{
+ EFI_HANDLE *buffer = NULL;
+ UINTN bufsz = 0, i;
+ EFI_STATUS status;
+ int serial = 0;
+
+ /*
+ * get buffer size
+ */
+ status = BS->LocateHandle(ByProtocol, &serial_io, NULL, &bufsz, buffer);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "unexpected error: %lld", (long long)status);
+ return;
+ }
+ if ((buffer = malloc(bufsz)) == NULL) {
+ sprintf(command_errbuf, "out of memory");
+ return;
+ }
+
+ /*
+ * get handle array
+ */
+ status = BS->LocateHandle(ByProtocol, &serial_io, NULL, &bufsz, buffer);
+ if (EFI_ERROR(status)) {
+ free(buffer);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "LocateHandle() error: %lld", (long long)status);
+ return;
+ }
+
+ for (i = 0; i < (bufsz / sizeof (EFI_HANDLE)); i++) {
+ SERIAL_IO_INTERFACE *sio;
+ status = BS->OpenProtocol(buffer[i], &serial_io, (void**)&sio,
+ IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(status)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "OpenProtocol() error: %lld", (long long)status);
+ }
+ printf("serial# %d\n", serial++);
+ }
+
+ free(buffer);
+}
+
+#ifdef LOADER_FDT_SUPPORT
+extern int command_fdt_internal(int argc, char *argv[]);
+
+/*
+ * Since proper fdt command handling function is defined in fdt_loader_cmd.c,
+ * and declaring it as extern is in contradiction with COMMAND_SET() macro
+ * (which uses static pointer), we're defining wrapper function, which
+ * calls the proper fdt handling routine.
+ */
+static int
+command_fdt(int argc, char *argv[])
+{
+ return (command_fdt_internal(argc, argv));
+}
+
+COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
+#endif
+
+#ifdef EFI_ZFS_BOOT
+static void
+efi_zfs_probe(void)
+{
+ EFI_HANDLE h;
+ u_int unit;
+ int i;
+ char dname[SPECNAMELEN + 1];
+ uint64_t guid;
+
+ unit = 0;
+ h = efi_find_handle(&efipart_dev, 0);
+ for (i = 0; h != NULL; h = efi_find_handle(&efipart_dev, ++i)) {
+ snprintf(dname, sizeof(dname), "%s%d:", efipart_dev.dv_name, i);
+ if (zfs_probe_dev(dname, &guid) == 0)
+ (void)efi_handle_update_dev(h, &zfs_dev, unit++, guid);
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/boot/efi/loader/reloc.c b/usr/src/boot/sys/boot/efi/loader/reloc.c
new file mode 100644
index 0000000000..5d03e09dc7
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/reloc.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <elf.h>
+#include <efi.h>
+#include <bootstrap.h>
+
+#if defined(__aarch64__)
+#define ElfW_Rel Elf64_Rela
+#define ElfW_Dyn Elf64_Dyn
+#define ELFW_R_TYPE ELF64_R_TYPE
+#define ELF_RELA
+#elif defined(__arm__) || defined(__i386__)
+#define ElfW_Rel Elf32_Rel
+#define ElfW_Dyn Elf32_Dyn
+#define ELFW_R_TYPE ELF32_R_TYPE
+#elif defined(__amd64__)
+#define ElfW_Rel Elf64_Rel
+#define ElfW_Dyn Elf64_Dyn
+#define ELFW_R_TYPE ELF64_R_TYPE
+#else
+#error architecture not supported
+#endif
+#if defined(__aarch64__)
+#define RELOC_TYPE_NONE R_AARCH64_NONE
+#define RELOC_TYPE_RELATIVE R_AARCH64_RELATIVE
+#elif defined(__amd64__)
+#define RELOC_TYPE_NONE R_X86_64_NONE
+#define RELOC_TYPE_RELATIVE R_X86_64_RELATIVE
+#elif defined(__arm__)
+#define RELOC_TYPE_NONE R_ARM_NONE
+#define RELOC_TYPE_RELATIVE R_ARM_RELATIVE
+#elif defined(__i386__)
+#define RELOC_TYPE_NONE R_386_NONE
+#define RELOC_TYPE_RELATIVE R_386_RELATIVE
+#endif
+
+/*
+ * A simple relocator for EFI binaries.
+ */
+EFI_STATUS
+_reloc(unsigned long ImageBase, ElfW_Dyn *dynamic, EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *system_table)
+{
+ unsigned long relsz, relent;
+ unsigned long *newaddr;
+ ElfW_Rel *rel;
+ ElfW_Dyn *dynp;
+
+ /*
+ * Find the relocation address, its size and the relocation entry.
+ */
+ relsz = 0;
+ relent = 0;
+ for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_REL:
+ case DT_RELA:
+ rel = (ElfW_Rel *) ((unsigned long) dynp->d_un.d_ptr +
+ ImageBase);
+ break;
+ case DT_RELSZ:
+ case DT_RELASZ:
+ relsz = dynp->d_un.d_val;
+ break;
+ case DT_RELENT:
+ case DT_RELAENT:
+ relent = dynp->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Perform the actual relocation.
+ */
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELFW_R_TYPE(rel->r_info)) {
+ case RELOC_TYPE_NONE:
+ /* No relocation needs be performed. */
+ break;
+
+ case RELOC_TYPE_RELATIVE:
+ /* Address relative to the base address. */
+ newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+ *newaddr += ImageBase;
+ /* Add the addend when the ABI uses them */
+#ifdef ELF_RELA
+ *newaddr += rel->r_addend;
+#endif
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ break;
+ }
+ rel = (ElfW_Rel *) ((caddr_t) rel + relent);
+ }
+
+ return (EFI_SUCCESS);
+}
diff --git a/usr/src/boot/sys/boot/efi/loader/version b/usr/src/boot/sys/boot/efi/loader/version
new file mode 100644
index 0000000000..3a4c47c5ef
--- /dev/null
+++ b/usr/src/boot/sys/boot/efi/loader/version
@@ -0,0 +1,7 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.1: Keep in sync with i386 version.
+0.1: Initial i386 version. Derived from ia64.
diff --git a/usr/src/boot/sys/boot/fdt/Makefile b/usr/src/boot/sys/boot/fdt/Makefile
new file mode 100644
index 0000000000..22d8da5965
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/Makefile
@@ -0,0 +1,30 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../contrib/libfdt/
+
+LIB= fdt
+INTERNALLIB=
+
+# Vendor sources of libfdt.
+SRCS+= fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c \
+ fdt_empty_tree.c
+
+# Loader's fdt commands extension sources.
+SRCS+= fdt_loader_cmd.c
+
+CFLAGS+= -I${.CURDIR}/../../contrib/libfdt/ -I${.CURDIR}/../common/
+
+CFLAGS+= -ffreestanding
+
+.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips"
+CFLAGS+= -msoft-float
+.endif
+
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32
+.endif
+
+CFLAGS+= -Wformat -Wall
+
+.include <bsd.stand.mk>
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/fdt/dts/Makefile b/usr/src/boot/sys/boot/fdt/dts/Makefile
new file mode 100644
index 0000000000..66f65a712f
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR=arm mips powerpc
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/fdt/dts/Makefile.inc b/usr/src/boot/sys/boot/fdt/dts/Makefile.inc
new file mode 100644
index 0000000000..4454755dc8
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/Makefile.inc
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+SYSDIR?=${.CURDIR}/../../../..
+
+test-dts:
+.for dts in ${DTS}
+ @env MACHINE=`basename ${.CURDIR}` ${SYSDIR}/tools/fdt/make_dtb.sh ${SYSDIR} ${dts} /tmp
+
+.endfor
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/Makefile b/usr/src/boot/sys/boot/fdt/dts/arm/Makefile
new file mode 100644
index 0000000000..03d156d947
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+DTS!=ls *.dts
+
+all: test-dts
+
+.include <bsd.init.mk>
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/am335x-evm.dts b/usr/src/boot/sys/boot/fdt/dts/arm/am335x-evm.dts
new file mode 100644
index 0000000000..3e1c4c0caa
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/am335x-evm.dts
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "am335x-evm.dts"
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/am335x.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/am335x.dtsi
new file mode 100644
index 0000000000..fea57e98b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/am335x.dtsi
@@ -0,0 +1,349 @@
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&AINTC>;
+
+ SOC: am335x {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ AINTC: interrupt-controller@48200000 {
+ compatible = "ti,aintc";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = < 0x48200000 0x1000 >;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <3>;
+ };
+
+ scm@44e10000 {
+ compatible = "ti,scm";
+ reg = < 0x44e10000 0x2000 >;
+ };
+
+ prcm@44E00000 {
+ compatible = "am335x,prcm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x44E00000 0x1300 >;
+ };
+
+ dmtimers@44E05000 {
+ compatible = "ti,am335x-dmtimer";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x44E05000 0x1000
+ 0x44E31000 0x1000
+ 0x48040000 0x1000
+ 0x48042000 0x1000
+ 0x48044000 0x1000
+ 0x48046000 0x1000
+ 0x48048000 0x1000
+ 0x4804A000 0x1000 >;
+ interrupts = < 66 67 68 69 92 93 94 95 >;
+ interrupt-parent = <&AINTC>;
+ };
+
+ rtc: rtc@44E3E000 {
+ compatible = "ti,da830-rtc";
+ reg = <0x44E3E000 0x1000>;
+ interrupts = < 75 76 >;
+ interrupt-parent = <&AINTC>;
+ };
+
+ adc0: adc@44E0D000 {
+ compatible = "ti,adc";
+ reg = <0x44E0D000 0x2000>;
+ interrupts = < 16 >;
+ interrupt-parent = <&AINTC>;
+ };
+
+ wdt1@44E35000 {
+ compatible = "ti,omap3-wdt";
+ reg = <0x44E35000 0x1000>;
+ interrupts = <91>;
+ interrupt-parent = <&AINTC>;
+ };
+
+ GPIO: gpio {
+ #gpio-cells = <3>;
+ compatible = "ti,gpio";
+ gpio-controller;
+ reg =< 0x44E07000 0x1000
+ 0x4804C000 0x1000
+ 0x481AC000 0x1000
+ 0x481AE000 0x1000 >;
+ interrupts = < 96 97 98 99 32 33 62 63 >;
+ interrupt-parent = <&AINTC>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ uart0: serial@44E09000 {
+ compatible = "ti,ns16550";
+ reg = <0x44E09000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 72 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 0 >;
+ };
+
+ uart1: serial@48022000 {
+ compatible = "ti,ns16550";
+ reg = <0x48022000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 73 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 1 >;
+ status = "disabled";
+ };
+
+ uart2: serial@48024000 {
+ compatible = "ti,ns16550";
+ reg = <0x48024000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 74 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 2 >;
+ status = "disabled";
+ };
+
+ uart3: serial@481a6000 {
+ compatible = "ti,ns16550";
+ reg = <0x481A6000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 44 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 3 >;
+ status = "disabled";
+ };
+
+ uart4: serial@481a8000 {
+ compatible = "ti,ns16550";
+ reg = <0x481A8000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 45 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 4 >;
+ status = "disabled";
+ };
+
+ uart5: serial@481aa000 {
+ compatible = "ti,ns16550";
+ reg = <0x481AA000 0x1000>;
+ reg-shift = <2>;
+ interrupts = < 46 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 48000000 >;
+ uart-device-id = < 5 >;
+ status = "disabled";
+ };
+
+ edma3@49000000 {
+ compatible = "ti,edma3";
+ reg =< 0x49000000 0x100000 /* Channel Controller Regs */
+ 0x49800000 0x100000 /* Transfer Controller 0 Regs */
+ 0x49900000 0x100000 /* Transfer Controller 1 Regs */
+ 0x49a00000 0x100000 >; /* Transfer Controller 2 Regs */
+ interrupts = <12 13 14>;
+ interrupt-parent = <&AINTC>;
+ };
+
+ mmchs0@48060000 {
+ compatible = "ti,omap3-hsmmc", "ti,mmchs";
+ reg =<0x48060000 0x1000 >;
+ interrupts = <64>;
+ interrupt-parent = <&AINTC>;
+ mmchs-device-id = <0>;
+ mmchs-wp-gpio-pin = <0xffffffff>;
+ ti,dual-volt;
+ };
+
+ mmchs1@481D8000 {
+ compatible = "ti,omap3-hsmmc", "ti,mmchs";
+ reg =<0x481D8000 0x1000 >;
+ interrupts = <28>;
+ interrupt-parent = <&AINTC>;
+ mmchs-device-id = <1>;
+ mmchs-wp-gpio-pin = <0xffffffff>;
+ status = "disabled";
+ };
+
+ enet0: ethernet@4A100000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ti,cpsw";
+ reg = <0x4A100000 0x4000>;
+ interrupts = <40 41 42 43>;
+ interrupt-parent = <&AINTC>;
+ phy-handle = <&phy0>;
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,cpsw-mdio";
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+
+ i2c0: i2c@44e0b000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,i2c";
+ reg =< 0x44e0b000 0x1000 >;
+ interrupts = <70>;
+ interrupt-parent = <&AINTC>;
+ i2c-device-id = <0>;
+ };
+
+ i2c1: i2c@4802a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,i2c";
+ reg =< 0x4802a000 0x1000 >;
+ interrupts = <71>;
+ interrupt-parent = <&AINTC>;
+ i2c-device-id = <1>;
+ };
+
+ i2c2: i2c@4819c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,i2c";
+ reg =< 0x4819c000 0x1000 >;
+ interrupts = <30>;
+ interrupt-parent = <&AINTC>;
+ i2c-device-id = <2>;
+ };
+
+ pwm@48300000 {
+ compatible = "ti,am335x-pwm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x48300000 0x100 /* PWMSS0 */
+ 0x48300100 0x80 /* eCAP0 */
+ 0x48300180 0x80 /* eQEP0 */
+ 0x48300200 0x60 /* ePWM0 */
+ >;
+ interrupts = <86 58>; /* ePWM0INT, ePWM0_TZINT */
+ interrupt-parent = <&AINTC>;
+ pwm-device-id = <0>;
+ };
+
+ pwm@48302000 {
+ compatible = "ti,am335x-pwm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x48302000 0x100 /* PWMSS1 */
+ 0x48302100 0x80 /* eCAP1 */
+ 0x48302180 0x80 /* eQEP1 */
+ 0x48302200 0x60 /* ePWM1 */
+ >;
+ interrupts = <87 59>; /* ePWM1INT, ePWM1_TZINT */
+ interrupt-parent = <&AINTC>;
+ pwm-device-id = <1>;
+ };
+
+ pwm@48304000 {
+ compatible = "ti,am335x-pwm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x48304000 0x100 /* PWMSS2 */
+ 0x48304100 0x80 /* eCAP2 */
+ 0x48304180 0x80 /* eQEP2 */
+ 0x48304200 0x60 /* ePWM2 */
+ >;
+ interrupts = <88 60>; /* ePWM2INT, ePWM2_TZINT */
+ interrupt-parent = <&AINTC>;
+ pwm-device-id = <2>;
+ };
+
+ lcd: lcd@4830e000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,am335x-lcd";
+ reg =< 0x4830e000 0x1000 >;
+ interrupts = <36>;
+ interrupt-parent = <&AINTC>;
+ };
+
+ usb@47400000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,musb-am33xx";
+ reg =< 0x47400000 0x1000 /* USBSS */
+ 0x47401000 0x300 /* USB0 */
+ 0x47401300 0x100 /* USB0_PHY */
+ 0x47401400 0x400 /* USB0_CORE */
+ 0x47401800 0x300 /* USB1 */
+ 0x47401B00 0x100 /* USB1_PHY */
+ 0x47401C00 0x400 /* USB1_CORE */
+ >;
+ interrupts = <17 18 19>;
+ interrupt-parent = <&AINTC>;
+ /* 1 - Host Mode, 0 - Device Mode */
+ modemask = <2>;
+ };
+
+ mbox0@480C8000 {
+ compatible = "am335x,system-mbox";
+ reg = < 0x480C8000 0x1000 >;
+ interrupts = <77>;
+ interrupt-parent = <&AINTC>;
+ };
+
+ spinlock0@480CA000 {
+ compatible = "am335x,spinlock";
+ reg = < 0x480CA000 0x1000 >;
+ };
+
+ pruss@4A300000 {
+ compatible = "ti,pruss-v2";
+ reg = <0x4A300000 0x80000>;
+ interrupt-parent = <&AINTC>;
+ interrupts = <20 21 22 23 24 25 26 27>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/annapurna-alpine.dts b/usr/src/boot/sys/boot/fdt/dts/arm/annapurna-alpine.dts
new file mode 100644
index 0000000000..100d2d046f
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/annapurna-alpine.dts
@@ -0,0 +1,244 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015 Semihalf
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "annapurna,alpine";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &serial0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ d-cache-line-size = <64>; // 64 bytes
+ i-cache-line-size = <64>; // 64 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <375000000>;
+ clock-frequency = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ d-cache-line-size = <64>; // 64 bytes
+ i-cache-line-size = <64>; // 64 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <375000000>;
+ clock-frequency = <0>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ d-cache-line-size = <64>; // 64 bytes
+ i-cache-line-size = <64>; // 64 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <375000000>;
+ clock-frequency = <0>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ d-cache-line-size = <64>; // 64 bytes
+ i-cache-line-size = <64>; // 64 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <375000000>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00100000 0x7ff00000>; // 2047MB at 1MB
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xfb000000 0x03000000>;
+ bus-frequency = <0>;
+
+ MPIC: interrupt-controller {
+ compatible = "arm,gic";
+ reg = < 0x1000 0x1000 >, /* Distributor Registers */
+ < 0x2000 0x2000 >; /* CPU Interface Registers */
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <3>;
+
+ // In intr[2], bits[3:0] are trigger type and level flags.
+ // 1 = low-to-high edge triggered
+ // 2 = high-to-low edge triggered
+ // 4 = active high level-sensitive
+ // 8 = active low level-sensitive
+ // The hardware only supports active-high-level or rising-edge.
+
+ };
+
+ generic_timer {
+ compatible = "arm,sp804";
+ reg = <0x02890000 0x1000>;
+ interrupts = <0 9 4>;
+ interrupt-parent = <&MPIC>;
+ clock-frequency = <375000000>;
+ };
+
+ cpu_resume {
+ compatible = "annapurna-labs,al-cpu-resume";
+ reg = <0x00ff5ec0 0x30>;
+ };
+
+ nb_service {
+ compatible = "annapurna-labs,al-nb-service";
+ reg = <0x00070000 0x10000>;
+ interrupts = <0 32 4>,
+ <0 33 4>,
+ <0 34 4>,
+ <0 35 4>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ wdt0 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x288c000 0x1000>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ serial0: serial@2883000 {
+ compatible = "ns16550";
+ reg = <0x2883000 0x20>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <375000000>;
+ interrupts = <0 17 4>;
+ interrupt-parent = <&MPIC>;
+ };
+ };
+
+ pcie-internal {
+ compatible = "annapurna-labs,al-internal-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ interrupt-parent = <&MPIC>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0x3000 0 0 1 &MPIC 0 32 4>, // USB adapter
+ <0x3800 0 0 1 &MPIC 0 36 4>,
+ <0x4000 0 0 1 &MPIC 0 43 4>, // SATA 0 (PCIe expander)
+ <0x4800 0 0 1 &MPIC 0 44 1>; // SATA 1 (onboard)
+
+ // ranges:
+ // - ECAM - non prefetchable config space
+ // - 32 bit non prefetchable memory space
+ ranges = <0x00000000 0x0 0xfbc00000 0xfbc00000 0x0 0x100000
+ 0x02000000 0x0 0xfe000000 0xfe000000 0x0 0x1000000>;
+
+ bus-range = <0x00 0x00>;
+ };
+
+// WORKAROUND: enabling PCIe controller when no card is plugged in
+// leads to kernel panic because u-boot disables PCIe controller if no link
+// is detected. Just be kind and compatible with Linux
+/* // External PCIe Controller 0
+ pcie-external0 {
+ compatible = "annapurna-labs,al-external-pcie";
+ reg = <0xfd800000 0x00020000>;
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ interrupt-parent = <&MPIC>;
+ interrupt-map-mask = <0x00 0 0 7>;
+ interrupt-map = <0x0000 0 0 1 &MPIC 0 40 4>;
+
+ // ranges:
+ // Controller 0:
+ // - ECAM - non prefetchable config space: 2MB
+ // - IO - IO port space 64KB, reserve 64KB from target memory windows
+ // real IO address on the pci bus starts at 0x10000
+ // - 32 bit non prefetchable memory space: 128MB - 64KB
+
+ ranges = <0x00000000 0x0 0xfb600000 0xfb600000 0x0 0x00200000
+ 0x01000000 0x0 0x00010000 0xe0000000 0x0 0x00010000
+ 0x02000000 0x0 0xe1000000 0xe1000000 0x0 0x06f00000>;
+
+ bus-range = <0x00 0xff>;
+ };
+
+ // External PCIe Controllers 1
+ pcie-external1 {
+ compatible = "annapurna-labs,al-external-pcie";
+ reg = <0xfd820000 0x00020000>;
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ interrupt-parent = <&MPIC>;
+ interrupt-map-mask = <0x0 0 0 7>;
+ interrupt-map = <0x0000 0 0 1 &MPIC 0 41 4>;
+
+ // ranges:
+ // - ECAM - non prefetchable config space: 2MB
+ // - IO - IO port space 64KB, reserve 64KB from target memory windows
+ // real IO address on the pci bus starts at 0x20000
+ // - 32 bit non prefetchable memory space: 64MB - 64KB
+ ranges = <0x00000000 0x0 0xfb800000 0xfb800000 0x0 0x00200000
+ 0x01000000 0x0 0x00020000 0xe8000000 0x0 0x00010000
+ 0x02000000 0x0 0xe8100000 0xe8100000 0x0 0x02ff0000>;
+
+ bus-range = <0x00 0xff>;
+ }; */
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ stddbg = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/apalis-imx6.dts b/usr/src/boot/sys/boot/fdt/dts/arm/apalis-imx6.dts
new file mode 100644
index 0000000000..b6440603c5
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/apalis-imx6.dts
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014-2015 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "imx6q-pinfunc.h"
+
+/dts-v1/;
+/include/ "imx6.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ model = "Toradex Apalis i.MX6";
+ compatible = "toradex,imx6q-apalis", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x40000000>; /* RAM 1GB */
+ };
+
+ SOC: soc@00000000 {
+ aips@02000000 { /* AIPS1 */
+ iomux@020e0000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_ssi>;
+ pins_ssi: ssi {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0
+ MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0
+ MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ MX6QDL_PAD_GPIO_19__CCM_CLKO1 0x130b0
+ >;
+ };
+ };
+ gpio@0209c000 { status = "okay"; };
+ gpio@020a0000 { status = "okay"; };
+ gpio@020a4000 { status = "okay"; };
+ gpio@020a8000 { status = "okay"; };
+ gpio@020ac000 { status = "okay"; };
+ gpio@020b0000 { status = "okay"; };
+ gpio@020b4000 { status = "okay"; };
+ console:serial@02020000 { status = "okay"; };
+ serial@021e8000 { status = "disabled"; };
+ serial@021ec000 { status = "disabled"; };
+ serial@021f0000 { status = "disabled"; };
+ serial@021f4000 { status = "disabled"; };
+ usbphy@020c9000 { status = "okay"; };
+ usbphy@020ca000 { status = "okay"; };
+ ecspi@02008000 { status = "okay"; };
+ ssi@02028000 { status = "okay"; };
+ sdma@020ec000 { status = "okay"; };
+ };
+ aips@02100000 { /* AIPS2 */
+ ethernet@02188000 {
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-disable-preamble;
+ };
+ usb@02184000 { status = "okay"; };
+ usb@02184200 { status = "okay"; };
+ usb@02184400 { status = "disabled"; };
+ usb@02184600 { status = "disabled"; };
+ usdhc@02190000 { status = "disabled"; };
+ usdhc@02194000 { status = "okay"; };
+ usdhc@02198000 { status = "disabled"; };
+ usdhc@0219c000 { status = "disabled"; };
+ audmux@021d8000 { status = "okay"; };
+ i2c@021a0000 { status = "okay"; };
+ };
+ };
+
+ chosen {
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/armada-380.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/armada-380.dtsi
new file mode 100644
index 0000000000..876bae4a4b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/armada-380.dtsi
@@ -0,0 +1,154 @@
+/*
+ * Device Tree Include file for Marvell Armada 380 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "armada-38x.dtsi"
+
+/ {
+ model = "Marvell Armada 380 family SoC";
+ compatible = "marvell,armada380";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-380-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6810-pinctrl";
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO */
+ 0x82000000 0x2 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+ 0x81000000 0x3 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO */>;
+
+ /* x1 port */
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/armada-385.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/armada-385.dtsi
new file mode 100644
index 0000000000..8dc6202280
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/armada-385.dtsi
@@ -0,0 +1,81 @@
+/*
+ * Device Tree Include file for Marvell Armada 385 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "armada-38x.dtsi"
+
+/ {
+ model = "Marvell Armada 385 family SoC";
+ compatible = "marvell,armada385", "marvell,armada380";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,armada-380-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6820-pinctrl";
+ };
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/armada-388-gp.dts b/usr/src/boot/sys/boot/fdt/dts/arm/armada-388-gp.dts
new file mode 100644
index 0000000000..8a211f644d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/armada-388-gp.dts
@@ -0,0 +1,393 @@
+/*
+ * Device Tree file for Marvell Armada 385 development board
+ * (RD-88F6820-GP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 GP";
+ compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2 GB */
+ };
+
+ soc {
+ ranges = <0 0 0xf1000000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+ };
+ };
+
+ i2c@11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+ clock-frequency = <100000>;
+ /*
+ * The EEPROM located at adresse 54 is needed
+ * for the boot - DO NOT ERASE IT -
+ */
+
+ expander0: pca9555@20 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pca0_pins>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x20>;
+ };
+
+ expander1: pca9555@21 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x21>;
+ };
+
+ };
+
+ serial@12000 {
+ /*
+ * Exported on the micro USB connector CON16
+ * through an FTDI
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
+
+ /* GE1 CON15 */
+ ethernet@30000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ /* CON4 */
+ usb@58000 {
+ vcc-supply = <&reg_usb2_0_vbus>;
+ status = "okay";
+ };
+
+ /* GE0 CON1 */
+ ethernet@70000 {
+ pinctrl-names = "default";
+ /*
+ * The Reference Clock 0 is used to provide a
+ * clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+
+ mdio@72004 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ sata@a8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata0_pins>, <&sata1_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata1>;
+ };
+ };
+
+ sata@e0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata2: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata2>;
+ };
+
+ sata3: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata3>;
+ };
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ };
+
+ /* CON5 */
+ usb3@f0000 {
+ vcc-supply = <&reg_usb2_1_vbus>;
+ status = "okay";
+ };
+
+ /* CON7 */
+ usb3@f8000 {
+ vcc-supply = <&reg_usb3_vbus>;
+ status = "okay";
+ };
+ };
+
+ gpio-fan {
+ compatible = "gpio-fan";
+ gpios = <&expander1 3 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 3000 1>;
+ };
+ };
+
+ pci0: pcie@f1080000 {
+ status = "okay";
+ };
+
+ reg_usb3_vbus: usb3-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb3-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_0_vbus: v5-vbus0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_sata0: pwr-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata0";
+ enable-active-high;
+ regulator-always-on;
+
+ };
+
+ reg_5v_sata0: v5-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_12v_sata0: v12-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_sata1: pwr-sata1 {
+ regulator-name = "pwr_en_sata1";
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata1: v5-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_12v_sata1: v12-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata1";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_sata2: pwr-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata2";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata2: v5-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_12v_sata2: v12-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata2";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_sata3: pwr-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata3";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata3: v5-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata3";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+
+ reg_12v_sata3: v12-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata3";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+};
+
+&pinctrl {
+ pca0_pins: pca0_pins {
+ marvell,pins = "mpp18";
+ marvell,function = "gpio";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/armada-388.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/armada-388.dtsi
new file mode 100644
index 0000000000..7be5f78478
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/armada-388.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Device Tree Include file for Marvell Armada 388 SoC.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * The main difference with the Armada 385 is that the 388 can handle two more
+ * SATA ports. So we can reuse the dtsi of the Armada 385, override the pinctrl
+ * property and the name of the SoC, and add the second SATA host which control
+ * the 2 other ports.
+ *
+ * $FreeBSD$
+ */
+
+#include "armada-385.dtsi"
+
+/ {
+ model = "Marvell Armada 388 family SoC";
+ compatible = "marvell,armada388", "marvell,armada385",
+ "marvell,armada380";
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6828-pinctrl";
+ };
+
+ sata@e0000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xe0000 0x2000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>;
+ status = "disabled";
+ };
+
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/armada-38x.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/armada-38x.dtsi
new file mode 100644
index 0000000000..d93dab28c4
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/armada-38x.dtsi
@@ -0,0 +1,630 @@
+/*
+ * Device Tree Include file for Marvell Armada 38x family of SoCs.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+ model = "Marvell Armada 38x family SoC";
+ compatible = "marvell,armada380";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts-extended = <&mpic 3>;
+ };
+
+ soc {
+ compatible = "marvell,armada380-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ interrupt-parent = <&gic>;
+ pcie-mem-aperture = <0xe0000000 0x8000000>;
+ pcie-io-aperture = <0xe8000000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x200000>;
+ };
+
+ devbus-bootcs {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ L2: cache-controller@8000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x8000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xc000 0x58>;
+ };
+
+ timer@c200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0xc200 0x20>;
+ interrupts = <GIC_PPI 11 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+ clock-frequency = <800000000>;
+ clocks = <&coreclk 2>;
+ };
+
+ timer@c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xc600 0x20>;
+ interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+ clock-frequency = <800000000>;
+ clocks = <&coreclk 2>;
+ };
+
+ gic: interrupt-controller@d000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #size-cells = <0>;
+ interrupt-controller;
+ reg = <0xd000 0x1000>,
+ <0xc100 0x100>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,armada-380-spi",
+ "marvell,orion-spi";
+ reg = <0x10600 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,armada-380-spi",
+ "marvell,orion-spi";
+ reg = <0x10680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@18000 {
+ reg = <0x18000 0x20>;
+
+ ge0_rgmii_pins: ge-rgmii-pins-0 {
+ marvell,pins = "mpp6", "mpp7", "mpp8",
+ "mpp9", "mpp10", "mpp11",
+ "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "ge0";
+ };
+
+ ge1_rgmii_pins: ge-rgmii-pins-1 {
+ marvell,pins = "mpp21", "mpp27", "mpp28",
+ "mpp29", "mpp30", "mpp31",
+ "mpp32", "mpp37", "mpp38",
+ "mpp39", "mpp40", "mpp41";
+ marvell,function = "ge1";
+ };
+
+ i2c0_pins: i2c-pins-0 {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "i2c0";
+ };
+
+ mdio_pins: mdio-pins {
+ marvell,pins = "mpp4", "mpp5";
+ marvell,function = "ge";
+ };
+
+ ref_clk0_pins: ref-clk-pins-0 {
+ marvell,pins = "mpp45";
+ marvell,function = "ref";
+ };
+
+ ref_clk1_pins: ref-clk-pins-1 {
+ marvell,pins = "mpp46";
+ marvell,function = "ref";
+ };
+
+ spi0_pins: spi-pins-0 {
+ marvell,pins = "mpp22", "mpp23", "mpp24",
+ "mpp25";
+ marvell,function = "spi0";
+ };
+
+ spi1_pins: spi-pins-1 {
+ marvell,pins = "mpp56", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "spi1";
+ };
+
+ uart0_pins: uart-pins-0 {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "ua0";
+ };
+
+ uart1_pins: uart-pins-1 {
+ marvell,pins = "mpp19", "mpp20";
+ marvell,function = "ua1";
+ };
+
+ sdhci_pins: sdhci-pins {
+ marvell,pins = "mpp48", "mpp49", "mpp50",
+ "mpp52", "mpp53", "mpp54",
+ "mpp55", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "sd0";
+ };
+
+ sata0_pins: sata-pins-0 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata0";
+ };
+
+ sata1_pins: sata-pins-1 {
+ marvell,pins = "mpp19";
+ marvell,function = "sata1";
+ };
+
+ sata2_pins: sata-pins-2 {
+ marvell,pins = "mpp47";
+ marvell,function = "sata2";
+ };
+
+ sata3_pins: sata-pins-3 {
+ marvell,pins = "mpp44";
+ marvell,function = "sata3";
+ };
+ };
+
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <28>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-380-system-controller",
+ "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x100>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-380-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ coreclk: mvebu-sar@18600 {
+ compatible = "marvell,armada-380-core-clock";
+ reg = <0x18600 0x04>;
+ #clock-cells = <1>;
+ };
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ mpic: interrupt-controller@20a00 {
+ compatible = "marvell,mpic";
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-380-timer",
+ "marvell,armada-xp-timer";
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpic 5>,
+ <&mpic 6>;
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ watchdog@20300 {
+ compatible = "marvell,armada-380-wdt";
+ reg = <0x20300 0x34>, <0x20704 0x4>, <0x18260 0x4>;
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x10>;
+ };
+
+ mpcore-soc-ctrl@20d20 {
+ compatible = "marvell,armada-380-mpcore-soc-ctrl";
+ reg = <0x20d20 0x6c>;
+ };
+
+ coherency-fabric@21010 {
+ compatible = "marvell,armada-380-coherency-fabric";
+ reg = <0x21010 0x1c>;
+ };
+
+ pmsu@22000 {
+ compatible = "marvell,armada-380-pmsu";
+ reg = <0x22000 0x1000>;
+ };
+
+ eth1: ethernet@30000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x30000 0x4000>;
+ interrupts-extended = <&mpic 10>;
+ clocks = <&gateclk 3>;
+ status = "disabled";
+ };
+
+ eth2: ethernet@34000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x34000 0x4000>;
+ interrupts-extended = <&mpic 12>;
+ clocks = <&gateclk 2>;
+ status = "disabled";
+ };
+
+ usb@58000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x58000 0x500>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 18>;
+ status = "disabled";
+ };
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60a00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ eth0: ethernet@70000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0x70000 0x4000>;
+ interrupts-extended = <&mpic 8>;
+ clocks = <&gateclk 4>;
+ status = "disabled";
+ };
+
+ mdio: mdio@72004 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x72004 0x4>;
+ clocks = <&gateclk 4>;
+ };
+
+ rtc@a3800 {
+ compatible = "marvell,armada-380-rtc";
+ reg = <0xa3800 0x20>, <0x184a0 0x0c>;
+ reg-names = "rtc", "rtc-soc";
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sata@a8000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xa8000 0x2000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 15>;
+ status = "disabled";
+ };
+
+ sata@e0000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xe0000 0x2000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>;
+ status = "disabled";
+ };
+
+ coredivclk: clock@e4250 {
+ compatible = "marvell,armada-380-corediv-clock";
+ reg = <0xe4250 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+
+ thermal@e8078 {
+ compatible = "marvell,armada380-thermal";
+ reg = <0xe4078 0x4>, <0xe4074 0x4>;
+ status = "okay";
+ };
+
+ flash@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&coredivclk 0>;
+ status = "disabled";
+ };
+
+ sdhci@d8000 {
+ compatible = "marvell,armada-380-sdhci";
+ reg-names = "sdhci", "mbus", "conf-sdio3";
+ reg = <0xd8000 0x1000>,
+ <0xdc000 0x100>,
+ <0x18454 0x4>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 17>;
+ mrvl,clk-delay-cycles = <0x1F>;
+ status = "disabled";
+ };
+
+ usb3@f0000 {
+ compatible = "marvell,armada-380-xhci";
+ reg = <0xf0000 0x4000>,<0xf4000 0x4000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+
+ usb3@f8000 {
+ compatible = "marvell,armada-380-xhci";
+ reg = <0xf8000 0x4000>,<0xfc000 0x4000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+ };
+ };
+
+ pci0: pcie@f1080000 {
+ compatible = "mrvl,pcie";
+ status = "disabled";
+ device_type = "pci";
+ #interrupt-cells = <3>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf1080000 0x2000>;
+ bus-range = <0 255>;
+ ranges = <0x42000000 0x0 0xf1200000 0xf1200000 0x0 0x00100000
+ 0x41000000 0x0 0x00000000 0xf1300000 0x0 0x00100000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 91 0>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH
+ >;
+ };
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ /* 25 MHz reference crystal */
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/bananapi.dts b/usr/src/boot/sys/boot/fdt/dts/arm/bananapi.dts
new file mode 100644
index 0000000000..0bd1b38394
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/bananapi.dts
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+#include "sun7i-a20.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "LeMaker Banana Pi";
+ compatible = "lemaker,bananapi", "allwinner,sun7i-a20";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x40000000 0x40000000 >; /* 1GB RAM */
+ };
+
+ aliases {
+ soc = &SOC;
+ UART0 = &UART0;
+ };
+
+ SOC: a20 {
+
+ usb1: usb@01c14000 {
+ status = "okay";
+ };
+
+ usb2: usb@01c1c000 {
+ status = "okay";
+ };
+
+ UART0: serial@01c28000 {
+ status = "okay";
+ };
+
+ mmc0: mmc@01c0f000 {
+ status = "okay";
+ };
+
+ gmac@01c50000 {
+ phy-mode = "rgmii-bpi";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii>;
+ };
+
+ ahci: sata@01c18000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ green {
+ label = "bananapi:green:usr";
+ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "UART0";
+ stdout = "UART0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/bcm2835.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/bcm2835.dtsi
new file mode 100644
index 0000000000..0b73401e4a
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/bcm2835.dtsi
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,1176jzf-s";
+ };
+ };
+
+
+ SOC: axi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x20000000 0x01000000>;
+ ranges = <0 0x20000000 0x01000000>;
+
+ intc: interrupt-controller {
+ compatible = "broadcom,bcm2835-armctrl-ic",
+ "broadcom,bcm2708-armctrl-ic";
+ reg = <0xB200 0x200>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ /* Bank 0
+ * 0: ARM_TIMER
+ * 1: ARM_MAILBOX
+ * 2: ARM_DOORBELL_0
+ * 3: ARM_DOORBELL_1
+ * 4: VPU0_HALTED
+ * 5: VPU1_HALTED
+ * 6: ILLEGAL_TYPE0
+ * 7: ILLEGAL_TYPE1
+ */
+
+ /* Bank 1
+ * 0: TIMER0 16: DMA0
+ * 1: TIMER1 17: DMA1
+ * 2: TIMER2 18: VC_DMA2
+ * 3: TIMER3 19: VC_DMA3
+ * 4: CODEC0 20: DMA4
+ * 5: CODEC1 21: DMA5
+ * 6: CODEC2 22: DMA6
+ * 7: VC_JPEG 23: DMA7
+ * 8: ISP 24: DMA8
+ * 9: VC_USB 25: DMA9
+ * 10: VC_3D 26: DMA10
+ * 11: TRANSPOSER 27: DMA11
+ * 12: MULTICORESYNC0 28: DMA12
+ * 13: MULTICORESYNC1 29: AUX
+ * 14: MULTICORESYNC2 30: ARM
+ * 15: MULTICORESYNC3 31: VPUDMA
+ */
+
+ /* Bank 2
+ * 0: HOSTPORT 16: SMI
+ * 1: VIDEOSCALER 17: GPIO0
+ * 2: CCP2TX 18: GPIO1
+ * 3: SDC 19: GPIO2
+ * 4: DSI0 20: GPIO3
+ * 5: AVE 21: VC_I2C
+ * 6: CAM0 22: VC_SPI
+ * 7: CAM1 23: VC_I2SPCM
+ * 8: HDMI0 24: VC_SDIO
+ * 9: HDMI1 25: VC_UART
+ * 10: PIXELVALVE1 26: SLIMBUS
+ * 11: I2CSPISLV 27: VEC
+ * 12: DSI1 28: CPG
+ * 13: PWA0 29: RNG
+ * 14: PWA1 30: VC_ARASANSDIO
+ * 15: CPR 31: AVSPMON
+ */
+ };
+
+ timer {
+ compatible = "broadcom,bcm2835-system-timer",
+ "broadcom,bcm2708-system-timer";
+ reg = <0x3000 0x1000>;
+ interrupts = <8 9 10 11>;
+ interrupt-parent = <&intc>;
+
+ clock-frequency = <1000000>;
+ };
+
+ armtimer {
+ /* Not AMBA compatible */
+ compatible = "broadcom,bcm2835-sp804", "arm,sp804";
+ reg = <0xB400 0x24>;
+ interrupts = <0>;
+ interrupt-parent = <&intc>;
+ };
+
+ watchdog0 {
+ compatible = "broadcom,bcm2835-wdt",
+ "broadcom,bcm2708-wdt";
+ reg = <0x10001c 0x0c>; /* 0x1c, 0x20, 0x24 */
+ };
+
+ gpio: gpio {
+ compatible = "broadcom,bcm2835-gpio",
+ "broadcom,bcm2708-gpio";
+ reg = <0x200000 0xb0>;
+
+ /* Unusual arrangement of interrupts
+ * (determined by testing)
+ * 17: Bank 0 (GPIOs 0-31)
+ * 19: Bank 1 (GPIOs 32-53)
+ * 18: Bank 2
+ * 20: All banks (GPIOs 0-53)
+ */
+ interrupts = <57 59 58 60>;
+ interrupt-parent = <&intc>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_reserved>;
+
+ /* Pins that can short 3.3V to GND in output mode: 46-47
+ * Pins used by VideoCore: 48-53
+ */
+ broadcom,read-only = <46>, <47>, <48>, <49>, <50>,
+ <51>, <52>, <53>;
+
+ /* BSC0 */
+ pins_bsc0_a: bsc0_a {
+ broadcom,pins = <0>, <1>;
+ };
+
+ pins_bsc0_b: bsc0_b {
+ broadcom,pins = <28>, <29>;
+ };
+
+ pins_bsc0_c: bsc0_c {
+ broadcom,pins = <44>, <45>;
+ };
+
+ /* BSC1 */
+ pins_bsc1_a: bsc1_a {
+ broadcom,pins = <2>, <3>;
+ };
+
+ pins_bsc1_b: bsc1_b {
+ broadcom,pins = <44>, <45>;
+ };
+
+ /* GPCLK0 */
+ pins_gpclk0_a: gpclk0_a {
+ broadcom,pins = <4>;
+ };
+
+ pins_gpclk0_b: gpclk0_b {
+ broadcom,pins = <20>;
+ };
+
+ pins_gpclk0_c: gpclk0_c {
+ broadcom,pins = <32>;
+ };
+
+ pins_gpclk0_d: gpclk0_d {
+ broadcom,pins = <34>;
+ };
+
+ /* GPCLK1 */
+ pins_gpclk1_a: gpclk1_a {
+ broadcom,pins = <5>;
+ };
+
+ pins_gpclk1_b: gpclk1_b {
+ broadcom,pins = <21>;
+ };
+
+ pins_gpclk1_c: gpclk1_c {
+ broadcom,pins = <42>;
+ };
+
+ pins_gpclk1_d: gpclk1_d {
+ broadcom,pins = <44>;
+ };
+
+ /* GPCLK2 */
+ pins_gpclk2_a: gpclk2_a {
+ broadcom,pins = <6>;
+ };
+
+ pins_gpclk2_b: gpclk2_b {
+ broadcom,pins = <43>;
+ };
+
+ /* SPI0 */
+ pins_spi0_a: spi0_a {
+ broadcom,pins = <7>, <8>, <9>, <10>, <11>;
+ };
+
+ pins_spi0_b: spi0_b {
+ broadcom,pins = <35>, <36>, <37>, <38>, <39>;
+ };
+
+ /* PWM */
+ pins_pwm0_a: pwm0_a {
+ broadcom,pins = <12>;
+ };
+
+ pins_pwm0_b: pwm0_b {
+ broadcom,pins = <18>;
+ };
+
+ pins_pwm0_c: pwm0_c {
+ broadcom,pins = <40>;
+ };
+
+ pins_pwm1_a: pwm1_a {
+ broadcom,pins = <13>;
+ };
+
+ pins_pwm1_b: pwm1_b {
+ broadcom,pins = <19>;
+ };
+
+ pins_pwm1_c: pwm1_c {
+ broadcom,pins = <41>;
+ };
+
+ pins_pwm1_d: pwm1_d {
+ broadcom,pins = <45>;
+ };
+
+ /* UART0 */
+ pins_uart0_a: uart0_a {
+ broadcom,pins = <14>, <15>;
+ };
+
+ pins_uart0_b: uart0_b {
+ broadcom,pins = <32>, <33>;
+ };
+
+ pins_uart0_c: uart0_c {
+ broadcom,pins = <36>, <37>;
+ };
+
+ pins_uart0_fc_a: uart0_fc_a {
+ broadcom,pins = <16>, <17>;
+ };
+
+ pins_uart0_fc_b: uart0_fc_b {
+ broadcom,pins = <30>, <31>;
+ };
+
+ pins_uart0_fc_c: uart0_fc_c {
+ broadcom,pins = <39>, <38>;
+ };
+
+ /* PCM */
+ pins_pcm_a: pcm_a {
+ broadcom,pins = <18>, <19>, <20>, <21>;
+ };
+
+ pins_pcm_b: pcm_b {
+ broadcom,pins = <28>, <29>, <30>, <31>;
+ };
+
+ /* Secondary Address Bus */
+ pins_sm_addr_a: sm_addr_a {
+ broadcom,pins = <5>, <4>, <3>, <2>, <1>, <0>;
+ };
+
+ pins_sm_addr_b: sm_addr_b {
+ broadcom,pins = <33>, <32>, <31>, <30>, <29>,
+ <28>;
+ };
+
+ pins_sm_ctl_a: sm_ctl_a {
+ broadcom,pins = <6>, <7>;
+ };
+
+ pins_sm_ctl_b: sm_ctl_b {
+ broadcom,pins = <34>, <35>;
+ };
+
+ pins_sm_data_8bit_a: sm_data_8bit_a {
+ broadcom,pins = <8>, <9>, <10>, <11>, <12>,
+ <13>, <14>, <15>;
+ };
+
+ pins_sm_data_8bit_b: sm_data_8bit_b {
+ broadcom,pins = <36>, <37>, <38>, <39>, <40>,
+ <41>, <42>, <43>;
+ };
+
+ pins_sm_data_16bit: sm_data_16bit {
+ broadcom,pins = <16>, <17>, <18>, <19>, <20>,
+ <21>, <22>, <23>;
+ };
+
+ pins_sm_data_18bit: sm_data_18bit {
+ broadcom,pins = <24>, <25>;
+ };
+
+ /* BSCSL */
+ pins_bscsl: bscsl {
+ broadcom,pins = <18>, <19>;
+ };
+
+ /* SPISL */
+ pins_spisl: spisl {
+ broadcom,pins = <18>, <19>, <20>, <21>;
+ };
+
+ /* SPI1 */
+ pins_spi1: spi1 {
+ broadcom,pins = <16>, <17>, <18>, <19>, <20>,
+ <21>;
+ };
+
+ /* UART1 */
+ pins_uart1_a: uart1_a {
+ broadcom,pins = <14>, <15>;
+ };
+
+ pins_uart1_b: uart1_b {
+ broadcom,pins = <32>, <33>;
+ };
+
+ pins_uart1_c: uart1_c {
+ broadcom,pins = <40>, <41>;
+ };
+
+ pins_uart1_fc_a: uart1_fc_a {
+ broadcom,pins = <16>, <17>;
+ };
+
+ pins_uart1_fc_b: uart1_fc_b {
+ broadcom,pins = <30>, <31>;
+ };
+
+ pins_uart1_fc_c: uart1_fc_c {
+ broadcom,pins = <43>, <42>;
+ };
+
+ /* SPI2 */
+ pins_spi2: spi2 {
+ broadcom,pins = <40>, <41>, <42>, <43>, <44>,
+ <45>;
+ };
+
+ /* ARM JTAG */
+ pins_arm_jtag_trst: arm_jtag_trst {
+ broadcom,pins = <22>;
+ };
+
+ pins_arm_jtag_a: arm_jtag_a {
+ broadcom,pins = <4>, <5>, <6>, <12>, <13>;
+ };
+
+ pins_arm_jtag_b: arm_jtag_b {
+ broadcom,pins = <23>, <24>, <25>, <26>, <27>;
+ };
+
+ /* Reserved */
+ pins_reserved: reserved {
+ broadcom,pins = <48>, <49>, <50>, <51>, <52>,
+ <53>;
+ };
+ };
+
+ bsc0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "broadcom,bcm2835-bsc",
+ "broadcom,bcm2708-bsc";
+ reg = <0x205000 0x20>;
+ interrupts = <61>;
+ interrupt-parent = <&intc>;
+ };
+
+ bsc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "broadcom,bcm2835-bsc",
+ "broadcom,bcm2708-bsc";
+ reg = <0x804000 0x20>;
+ interrupts = <61>;
+ interrupt-parent = <&intc>;
+ };
+
+ spi0 {
+ compatible = "broadcom,bcm2835-spi",
+ "broadcom,bcm2708-spi";
+ reg = <0x204000 0x20>;
+ interrupts = <62>;
+ interrupt-parent = <&intc>;
+ };
+
+ dma: dma {
+ compatible = "broadcom,bcm2835-dma",
+ "broadcom,bcm2708-dma";
+ reg = <0x7000 0x1000>, <0xE05000 0x1000>;
+ interrupts = <24 25 26 27 28 29 30 31 32 33 34 35 36>;
+ interrupt-parent = <&intc>;
+
+ broadcom,channels = <0>; /* Set by VideoCore */
+ };
+
+ vc_mbox: mbox {
+ compatible = "broadcom,bcm2835-mbox",
+ "broadcom,bcm2708-mbox";
+ reg = <0xB880 0x40>;
+ interrupts = <1>;
+ interrupt-parent = <&intc>;
+
+ /* Channels
+ * 0: Power
+ * 1: Frame buffer
+ * 2: Virtual UART
+ * 3: VCHIQ
+ * 4: LEDs
+ * 5: Buttons
+ * 6: Touch screen
+ */
+ };
+
+ sdhci {
+ compatible = "broadcom,bcm2835-sdhci",
+ "broadcom,bcm2708-sdhci";
+ reg = <0x300000 0x100>;
+ interrupts = <70>;
+ interrupt-parent = <&intc>;
+
+ clock-frequency = <50000000>; /* Set by VideoCore */
+ };
+
+ uart0: uart0 {
+ compatible = "broadcom,bcm2835-uart",
+ "broadcom,bcm2708-uart", "arm,pl011",
+ "arm,primecell";
+ reg = <0x201000 0x1000>;
+ interrupts = <65>;
+ interrupt-parent = <&intc>;
+
+ clock-frequency = <3000000>; /* Set by VideoCore */
+ reg-shift = <2>;
+ };
+
+ vchiq: vchiq {
+ compatible = "broadcom,bcm2835-vchiq";
+ reg = <0xB800 0x50>;
+ interrupts = <2>;
+ interrupt-parent = <&intc>;
+ cache-line-size = <32>;
+ };
+
+ usb {
+ compatible = "broadcom,bcm2835-usb",
+ "broadcom,bcm2708-usb",
+ "synopsys,designware-hs-otg2";
+ reg = <0x980000 0x20000>;
+ interrupts = <17>;
+ interrupt-parent = <&intc>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/bcm2836.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/bcm2836.dtsi
new file mode 100644
index 0000000000..ce967df7ea
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/bcm2836.dtsi
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ timer {
+ compatible = "arm,armv7-timer";
+ clock-frequency = <19200000>;
+ interrupts = <72 73 75 74>;
+ interrupt-parent = <&intc>;
+ };
+
+ SOC: axi {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x3f000000 0x01000000>;
+ ranges = <0 0x3f000000 0x01000000>;
+
+ intc: interrupt-controller {
+ compatible = "broadcom,bcm2835-armctrl-ic",
+ "broadcom,bcm2708-armctrl-ic";
+ reg = <0xB200 0x200>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ /* Bank 0
+ * 0: ARM_TIMER
+ * 1: ARM_MAILBOX
+ * 2: ARM_DOORBELL_0
+ * 3: ARM_DOORBELL_1
+ * 4: VPU0_HALTED
+ * 5: VPU1_HALTED
+ * 6: ILLEGAL_TYPE0
+ * 7: ILLEGAL_TYPE1
+ */
+
+ /* Bank 1
+ * 0: TIMER0 16: DMA0
+ * 1: TIMER1 17: DMA1
+ * 2: TIMER2 18: VC_DMA2
+ * 3: TIMER3 19: VC_DMA3
+ * 4: CODEC0 20: DMA4
+ * 5: CODEC1 21: DMA5
+ * 6: CODEC2 22: DMA6
+ * 7: VC_JPEG 23: DMA7
+ * 8: ISP 24: DMA8
+ * 9: VC_USB 25: DMA9
+ * 10: VC_3D 26: DMA10
+ * 11: TRANSPOSER 27: DMA11
+ * 12: MULTICORESYNC0 28: DMA12
+ * 13: MULTICORESYNC1 29: AUX
+ * 14: MULTICORESYNC2 30: ARM
+ * 15: MULTICORESYNC3 31: VPUDMA
+ */
+
+ /* Bank 2
+ * 0: HOSTPORT 16: SMI
+ * 1: VIDEOSCALER 17: GPIO0
+ * 2: CCP2TX 18: GPIO1
+ * 3: SDC 19: GPIO2
+ * 4: DSI0 20: GPIO3
+ * 5: AVE 21: VC_I2C
+ * 6: CAM0 22: VC_SPI
+ * 7: CAM1 23: VC_I2SPCM
+ * 8: HDMI0 24: VC_SDIO
+ * 9: HDMI1 25: VC_UART
+ * 10: PIXELVALVE1 26: SLIMBUS
+ * 11: I2CSPISLV 27: VEC
+ * 12: DSI1 28: CPG
+ * 13: PWA0 29: RNG
+ * 14: PWA1 30: VC_ARASANSDIO
+ * 15: CPR 31: AVSPMON
+ */
+ };
+
+ watchdog0 {
+ compatible = "broadcom,bcm2835-wdt",
+ "broadcom,bcm2708-wdt";
+ reg = <0x10001c 0x0c>; /* 0x1c, 0x20, 0x24 */
+ };
+
+ gpio: gpio {
+ compatible = "broadcom,bcm2835-gpio",
+ "broadcom,bcm2708-gpio";
+ reg = <0x200000 0xb0>;
+
+ /* Unusual arrangement of interrupts
+ * (determined by testing)
+ * 17: Bank 0 (GPIOs 0-31)
+ * 19: Bank 1 (GPIOs 32-53)
+ * 18: Bank 2
+ * 20: All banks (GPIOs 0-53)
+ */
+ interrupts = <57 59 58 60>;
+ interrupt-parent = <&intc>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_reserved>;
+
+ /* Pins that can short 3.3V to GND in output mode: 46
+ * Pins used by VideoCore: 48-53
+ */
+ broadcom,read-only = <46>, <48>, <49>, <50>,
+ <51>, <52>, <53>;
+
+ /* BSC0 */
+ pins_bsc0_a: bsc0_a {
+ broadcom,pins = <0>, <1>;
+ };
+
+ pins_bsc0_b: bsc0_b {
+ broadcom,pins = <28>, <29>;
+ };
+
+ pins_bsc0_c: bsc0_c {
+ broadcom,pins = <44>, <45>;
+ };
+
+ /* BSC1 */
+ pins_bsc1_a: bsc1_a {
+ broadcom,pins = <2>, <3>;
+ };
+
+ pins_bsc1_b: bsc1_b {
+ broadcom,pins = <44>, <45>;
+ };
+
+ /* GPCLK0 */
+ pins_gpclk0_a: gpclk0_a {
+ broadcom,pins = <4>;
+ };
+
+ pins_gpclk0_b: gpclk0_b {
+ broadcom,pins = <20>;
+ };
+
+ pins_gpclk0_c: gpclk0_c {
+ broadcom,pins = <32>;
+ };
+
+ pins_gpclk0_d: gpclk0_d {
+ broadcom,pins = <34>;
+ };
+
+ /* GPCLK1 */
+ pins_gpclk1_a: gpclk1_a {
+ broadcom,pins = <5>;
+ };
+
+ pins_gpclk1_b: gpclk1_b {
+ broadcom,pins = <21>;
+ };
+
+ pins_gpclk1_c: gpclk1_c {
+ broadcom,pins = <42>;
+ };
+
+ pins_gpclk1_d: gpclk1_d {
+ broadcom,pins = <44>;
+ };
+
+ /* GPCLK2 */
+ pins_gpclk2_a: gpclk2_a {
+ broadcom,pins = <6>;
+ };
+
+ pins_gpclk2_b: gpclk2_b {
+ broadcom,pins = <43>;
+ };
+
+ /* SPI0 */
+ pins_spi0_a: spi0_a {
+ broadcom,pins = <7>, <8>, <9>, <10>, <11>;
+ };
+
+ pins_spi0_b: spi0_b {
+ broadcom,pins = <35>, <36>, <37>, <38>, <39>;
+ };
+
+ /* PWM */
+ pins_pwm0_a: pwm0_a {
+ broadcom,pins = <12>;
+ };
+
+ pins_pwm0_b: pwm0_b {
+ broadcom,pins = <18>;
+ };
+
+ pins_pwm0_c: pwm0_c {
+ broadcom,pins = <40>;
+ };
+
+ pins_pwm1_a: pwm1_a {
+ broadcom,pins = <13>;
+ };
+
+ pins_pwm1_b: pwm1_b {
+ broadcom,pins = <19>;
+ };
+
+ pins_pwm1_c: pwm1_c {
+ broadcom,pins = <41>;
+ };
+
+ pins_pwm1_d: pwm1_d {
+ broadcom,pins = <45>;
+ };
+
+ /* UART0 */
+ pins_uart0_a: uart0_a {
+ broadcom,pins = <14>, <15>;
+ };
+
+ pins_uart0_b: uart0_b {
+ broadcom,pins = <32>, <33>;
+ };
+
+ pins_uart0_c: uart0_c {
+ broadcom,pins = <36>, <37>;
+ };
+
+ pins_uart0_fc_a: uart0_fc_a {
+ broadcom,pins = <16>, <17>;
+ };
+
+ pins_uart0_fc_b: uart0_fc_b {
+ broadcom,pins = <30>, <31>;
+ };
+
+ pins_uart0_fc_c: uart0_fc_c {
+ broadcom,pins = <39>, <38>;
+ };
+
+ /* PCM */
+ pins_pcm_a: pcm_a {
+ broadcom,pins = <18>, <19>, <20>, <21>;
+ };
+
+ pins_pcm_b: pcm_b {
+ broadcom,pins = <28>, <29>, <30>, <31>;
+ };
+
+ /* Secondary Address Bus */
+ pins_sm_addr_a: sm_addr_a {
+ broadcom,pins = <5>, <4>, <3>, <2>, <1>, <0>;
+ };
+
+ pins_sm_addr_b: sm_addr_b {
+ broadcom,pins = <33>, <32>, <31>, <30>, <29>,
+ <28>;
+ };
+
+ pins_sm_ctl_a: sm_ctl_a {
+ broadcom,pins = <6>, <7>;
+ };
+
+ pins_sm_ctl_b: sm_ctl_b {
+ broadcom,pins = <34>, <35>;
+ };
+
+ pins_sm_data_8bit_a: sm_data_8bit_a {
+ broadcom,pins = <8>, <9>, <10>, <11>, <12>,
+ <13>, <14>, <15>;
+ };
+
+ pins_sm_data_8bit_b: sm_data_8bit_b {
+ broadcom,pins = <36>, <37>, <38>, <39>, <40>,
+ <41>, <42>, <43>;
+ };
+
+ pins_sm_data_16bit: sm_data_16bit {
+ broadcom,pins = <16>, <17>, <18>, <19>, <20>,
+ <21>, <22>, <23>;
+ };
+
+ pins_sm_data_18bit: sm_data_18bit {
+ broadcom,pins = <24>, <25>;
+ };
+
+ /* BSCSL */
+ pins_bscsl: bscsl {
+ broadcom,pins = <18>, <19>;
+ };
+
+ /* SPISL */
+ pins_spisl: spisl {
+ broadcom,pins = <18>, <19>, <20>, <21>;
+ };
+
+ /* SPI1 */
+ pins_spi1: spi1 {
+ broadcom,pins = <16>, <17>, <18>, <19>, <20>,
+ <21>;
+ };
+
+ /* UART1 */
+ pins_uart1_a: uart1_a {
+ broadcom,pins = <14>, <15>;
+ };
+
+ pins_uart1_b: uart1_b {
+ broadcom,pins = <32>, <33>;
+ };
+
+ pins_uart1_c: uart1_c {
+ broadcom,pins = <40>, <41>;
+ };
+
+ pins_uart1_fc_a: uart1_fc_a {
+ broadcom,pins = <16>, <17>;
+ };
+
+ pins_uart1_fc_b: uart1_fc_b {
+ broadcom,pins = <30>, <31>;
+ };
+
+ pins_uart1_fc_c: uart1_fc_c {
+ broadcom,pins = <43>, <42>;
+ };
+
+ /* SPI2 */
+ pins_spi2: spi2 {
+ broadcom,pins = <40>, <41>, <42>, <43>, <44>,
+ <45>;
+ };
+
+ /* ARM JTAG */
+ pins_arm_jtag_trst: arm_jtag_trst {
+ broadcom,pins = <22>;
+ };
+
+ pins_arm_jtag_a: arm_jtag_a {
+ broadcom,pins = <4>, <5>, <6>, <12>, <13>;
+ };
+
+ pins_arm_jtag_b: arm_jtag_b {
+ broadcom,pins = <23>, <24>, <25>, <26>, <27>;
+ };
+
+ /* Reserved */
+ pins_reserved: reserved {
+ broadcom,pins = <48>, <49>, <50>, <51>, <52>,
+ <53>;
+ };
+ };
+
+ bsc0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "broadcom,bcm2835-bsc",
+ "broadcom,bcm2708-bsc";
+ reg = <0x205000 0x20>;
+ interrupts = <61>;
+ interrupt-parent = <&intc>;
+ };
+
+ bsc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "broadcom,bcm2835-bsc",
+ "broadcom,bcm2708-bsc";
+ reg = <0x804000 0x20>;
+ interrupts = <61>;
+ interrupt-parent = <&intc>;
+ };
+
+ spi0 {
+ compatible = "broadcom,bcm2835-spi",
+ "broadcom,bcm2708-spi";
+ reg = <0x204000 0x20>;
+ interrupts = <62>;
+ interrupt-parent = <&intc>;
+ };
+
+ dma: dma {
+ compatible = "broadcom,bcm2835-dma",
+ "broadcom,bcm2708-dma";
+ reg = <0x7000 0x1000>, <0xE05000 0x1000>;
+ interrupts = <24 25 26 27 28 29 30 31 32 33 34 35 36>;
+ interrupt-parent = <&intc>;
+
+ broadcom,channels = <0>; /* Set by VideoCore */
+ };
+
+ vc_mbox: mbox {
+ compatible = "broadcom,bcm2835-mbox",
+ "broadcom,bcm2708-mbox";
+ reg = <0xB880 0x40>;
+ interrupts = <1>;
+ interrupt-parent = <&intc>;
+
+ /* Channels
+ * 0: Power
+ * 1: Frame buffer
+ * 2: Virtual UART
+ * 3: VCHIQ
+ * 4: LEDs
+ * 5: Buttons
+ * 6: Touch screen
+ */
+ };
+
+ sdhci {
+ compatible = "broadcom,bcm2835-sdhci",
+ "broadcom,bcm2708-sdhci";
+ reg = <0x300000 0x100>;
+ interrupts = <70>;
+ interrupt-parent = <&intc>;
+
+ clock-frequency = <250000000>; /* Set by VideoCore */
+ };
+
+ uart0: uart0 {
+ compatible = "broadcom,bcm2835-uart",
+ "broadcom,bcm2708-uart", "arm,pl011",
+ "arm,primecell";
+ reg = <0x201000 0x1000>;
+ interrupts = <65>;
+ interrupt-parent = <&intc>;
+
+ clock-frequency = <3000000>; /* Set by VideoCore */
+ reg-shift = <2>;
+ };
+
+ vchiq: vchiq {
+ compatible = "broadcom,bcm2835-vchiq";
+ reg = <0xB800 0x50>;
+ interrupts = <2>;
+ interrupt-parent = <&intc>;
+ cache-line-size = <32>;
+ };
+
+ usb {
+ compatible = "broadcom,bcm2835-usb",
+ "broadcom,bcm2708-usb",
+ "synopsys,designware-hs-otg2";
+ reg = <0x980000 0x20000>;
+ interrupts = <17>;
+ interrupt-parent = <&intc>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-black.dts b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-black.dts
new file mode 100644
index 0000000000..d4f19b260c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-black.dts
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#include "am335x-boneblack.dts"
+#include "beaglebone-common.dtsi"
+
+&am33xx_pinmux {
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x158 (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ 0x15c (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x178 (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
+ 0x17c (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
+ >;
+ };
+};
+
+&i2c0 {
+ tda998x: hdmi-encoder {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+ status = "okay";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ status = "okay";
+};
+
+&lcdc {
+ hdmi = <&tda998x>;
+};
+
+/ {
+ hdmi {
+ status = "disabled";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-common.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-common.dtsi
new file mode 100644
index 0000000000..ec69d97c2c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone-common.dtsi
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ ocp {
+ pruss@4A300000 {
+ compatible = "ti,pruss-v2";
+ reg = <0x4A300000 0x80000>;
+ interrupt-parent = <&intc>;
+ interrupts = <20 21 22 23 24 25 26 27>;
+ };
+
+ };
+
+};
+
+&tps {
+ interrupt-parent = <&intc>;
+ interrupts = <7>;
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone.dts b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone.dts
new file mode 100644
index 0000000000..18e849dab2
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/beaglebone.dts
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "am335x-bone.dts"
+#include "beaglebone-common.dtsi"
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard.dts b/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard.dts
new file mode 100644
index 0000000000..a21ea4d746
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard.dts
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+#include "sun4i-a10.dtsi"
+
+/ {
+ model = "Cubietech Cubieboard";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x40000000 0x40000000 >; /* 1GB RAM */
+ };
+
+ aliases {
+ soc = &SOC;
+ UART0 = &UART0;
+ };
+
+ SOC: a10 {
+
+ usb1: usb@01c14000 {
+ status = "okay";
+ };
+
+ usb2: usb@01c1c000 {
+ status = "okay";
+ };
+
+ UART0: serial@01c28000 {
+ status = "okay";
+ };
+
+ mmc0: mmc@01c0f000 {
+ status = "okay";
+ };
+
+ emac@01c0b000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins>;
+ };
+
+ ahci: sata@01c18000 {
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "UART0";
+ stdout = "UART0";
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard2.dts b/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard2.dts
new file mode 100644
index 0000000000..f9e1eb8e77
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/cubieboard2.dts
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * Copyright (c) 2016 Emmanuel Vadot <manu@bidouilliste.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sun7i-a20-cubieboard2.dts"
+#include "sun7i-a20-hdmi.dtsi"
+
+/ {
+ soc@01c00000 {
+ ccm@01c20000 {
+ compatible = "allwinner,sun4i-ccm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c20000 0x400 >;
+ };
+
+ hdmi@01c16000 {
+ status = "okay";
+ };
+
+ hdmiaudio {
+ status = "okay";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/db78100.dts b/usr/src/boot/sys/boot/fdt/dts/arm/db78100.dts
new file mode 100644
index 0000000000..8a9e91c020
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/db78100.dts
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell DB-78100 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,DB-78100";
+ compatible = "DB-78100-BP", "DB-78100-BP-A";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ mpp = &MPP;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR571";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>; // 512M at 0x0
+ };
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <5>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xf9300000 0x00100000
+ 0x1 0x3e 0xf9400000 0x00100000
+ 0x2 0x3d 0xf9500000 0x02000000
+ 0x3 0x3b 0xfb500000 0x00100000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ };
+
+ led@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "led";
+ reg = <0x1 0x0 0x00100000>;
+ };
+
+ nor@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x2 0x0 0x02000000>;
+ };
+
+ nand@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mrvl,nfc";
+ reg = <0x3 0x0 0x00100000>;
+ };
+ };
+
+ soc78100@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <8>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 2 /* MPP[0]: GE1_TXCLK */
+ 1 2 /* MPP[1]: GE1_TXCTL */
+ 2 2 /* MPP[2]: GE1_RXCTL */
+ 3 2 /* MPP[3]: GE1_RXCLK */
+ 4 2 /* MPP[4]: GE1_TXD[0] */
+ 5 2 /* MPP[5]: GE1_TXD[1] */
+ 6 2 /* MPP[6]: GE1_TXD[2] */
+ 7 2 /* MPP[7]: GE1_TXD[3] */
+ 8 2 /* MPP[8]: GE1_RXD[0] */
+ 9 2 /* MPP[9]: GE1_RXD[1] */
+ 10 2 /* MPP[10]: GE1_RXD[2] */
+ 11 2 /* MPP[11]: GE1_RXD[3] */
+ 13 3 /* MPP[13]: SYSRST_OUTn */
+ 14 3 /* MPP[14]: SATA1_ACTn */
+ 15 3 /* MPP[15]: SATA0_ACTn */
+ 16 4 /* MPP[16]: UA2_TXD */
+ 17 4 /* MPP[17]: UA2_RXD */
+ 18 3 /* MPP[18]: <UNKNOWN> */
+ 19 3 /* MPP[19]: <UNKNOWN> */
+ 20 3 /* MPP[20]: <UNKNOWN> */
+ 21 3 /* MPP[21]: <UNKNOWN> */
+ 22 4 /* MPP[22]: UA3_TXD */
+ 23 4 >; /* MPP[21]: UA3_RXD */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <56 57 58 59>;
+ interrupt-parent = <&PIC>;
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <2>;
+ interrupt-parent = <&PIC>;
+ };
+
+ twsi@11100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11100 0x20>;
+ interrupts = <3>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <41 42 43 40 70>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x8>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <0x9>;
+ };
+ };
+ };
+
+ enet1: ethernet@76000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x76000 0x2000>;
+ ranges = <0x0 0x76000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <45 46 47 44 70>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy1>;
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <12>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <13>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <72 16>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@51000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x51000 0x1000>;
+ interrupts = <72 17>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@52000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x52000 0x1000>;
+ interrupts = <72 18>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <22 23>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@90000 {
+ compatible = "mrvl,cesa";
+ reg = <0x90000 0x10000>;
+ interrupts = <19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sata@a0000 {
+ compatible = "mrvl,sata";
+ reg = <0xa0000 0x6000>;
+ interrupts = <26>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ pci0: pcie@f1040000 {
+ compatible = "mrvl,pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf1040000 0x2000>;
+ bus-range = <0 255>;
+ ranges = <0x02000000 0x0 0xf2000000 0xf2000000 0x0 0x04000000
+ 0x01000000 0x0 0x00000000 0xf1100000 0x0 0x00100000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&PIC>;
+ interrupts = <68>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x1 */
+ 0x0800 0x0 0x0 0x1 &PIC 0x20
+ 0x0800 0x0 0x0 0x2 &PIC 0x21
+ 0x0800 0x0 0x0 0x3 &PIC 0x22
+ 0x0800 0x0 0x0 0x4 &PIC 0x23
+ >;
+ };
+
+ sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/db78460.dts b/usr/src/boot/sys/boot/fdt/dts/arm/db78460.dts
new file mode 100644
index 0000000000..8bc04f8dfa
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/db78460.dts
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * Copyright (c) 2010-2011 Semihalf
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell DB-78460 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,DB-78460";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &serial0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88VS584";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <200000000>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000>; // 2G at 0x0
+ };
+
+ soc78460@d0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xd0000000 0x00100000>;
+ bus-frequency = <0>;
+
+
+ MPIC: mpic@20a00 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20a00 0x500 0x21000 0x800 0x20400 0x100>;
+ compatible = "mrvl,mpic";
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ timer@21840 {
+ compatible = "mrvl,timer";
+ reg = <0x21840 0x30>;
+ interrupts = <5>;
+ interrupt-parent = <&MPIC>;
+ mrvl,has-wdt;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <31>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ twsi@11100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11100 0x20>;
+ interrupts = <32>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ serial0: serial@12000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <0>;
+ interrupts = <41>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <0>;
+ interrupts = <42>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ serial2: serial@12200 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12200 0x20>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <0>;
+ interrupts = <43>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ serial3: serial@12300 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x12300 0x20>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <0>;
+ interrupts = <44>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x18000 0x34>;
+ pin-count = <68>;
+ pin-map = <
+ 0 1 /* MPP[0]: GE1_TXCLK */
+ 1 1 /* MPP[1]: GE1_TXCTL */
+ 2 1 /* MPP[2]: GE1_RXCTL */
+ 3 1 /* MPP[3]: GE1_RXCLK */
+ 4 1 /* MPP[4]: GE1_TXD[0] */
+ 5 1 /* MPP[5]: GE1_TXD[1] */
+ 6 1 /* MPP[6]: GE1_TXD[2] */
+ 7 1 /* MPP[7]: GE1_TXD[3] */
+ 8 1 /* MPP[8]: GE1_RXD[0] */
+ 9 1 /* MPP[9]: GE1_RXD[1] */
+ 10 1 /* MPP[10]: GE1_RXD[2] */
+ 11 1 /* MPP[11]: GE1_RXD[3] */
+ 12 2 /* MPP[13]: SYSRST_OUTn */
+ 13 2 /* MPP[13]: SYSRST_OUTn */
+ 14 2 /* MPP[14]: SATA1_ACTn */
+ 15 2 /* MPP[15]: SATA0_ACTn */
+ 16 2 /* MPP[16]: UA2_TXD */
+ 17 2 /* MPP[17]: UA2_RXD */
+ 18 2 /* MPP[18]: <UNKNOWN> */
+ 19 2 /* MPP[19]: <UNKNOWN> */
+ 20 2 /* MPP[20]: <UNKNOWN> */
+ 21 2 /* MPP[21]: <UNKNOWN> */
+ 22 2 /* MPP[22]: UA3_TXD */
+ 23 2
+ 24 0
+ 25 0
+ 26 0
+ 27 0
+ 28 4
+ 29 0
+ 30 1
+ 31 1
+ 32 1
+ 33 1
+ 34 1
+ 35 1
+ 36 1
+ 37 1
+ 38 1
+ 39 1
+ 40 0
+ 41 3
+ 42 1
+ 43 1
+ 44 2
+ 45 2
+ 46 4
+ 47 3
+ 48 0
+ 49 1
+ 50 1
+ 51 1
+ 52 1
+ 53 1
+ 54 1
+ 55 1
+ 56 1
+ 57 0
+ 58 1
+ 59 1
+ 60 1
+ 61 1
+ 62 1
+ 63 1
+ 64 1
+ 65 1
+ 66 1
+ 67 2 >;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <124 45>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ usb@51000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x51000 0x1000>;
+ interrupts = <124 46>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ usb@52000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x52000 0x1000>;
+ interrupts = <124 47>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 04 01 07 84 60 ];
+ interrupts = <67 68 122 >;
+ interrupt-parent = <&MPIC>;
+ phy-handle = <&phy0>;
+ has-neta;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ reg = <0x19>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <0x1b>;
+ };
+ };
+ };
+
+ sata@A0000 {
+ compatible = "mrvl,sata";
+ reg = <0xA0000 0x6000>;
+ interrupts = <55>;
+ interrupt-parent = <&MPIC>;
+ };
+ };
+
+ pci0: pcie@d0040000 {
+ compatible = "mrvl,pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xd0040000 0x2000>;
+ bus-range = <0 255>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xa0000000 0x0 0x08000000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <120>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0800 0x0 0x0 0x1 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x2 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x3 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x4 &MPIC 0x3A
+ >;
+ };
+
+ sram@ffff0000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xffff0000 0x00010000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ stddbg = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/db88f5182.dts b/usr/src/boot/sys/boot/fdt/dts/arm/db88f5182.dts
new file mode 100644
index 0000000000..6ce7b6580d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/db88f5182.dts
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell DB-88F5182 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,DB-88F5182";
+ compatible = "DB-88F5182-BP", "DB-88F5182-BP-A";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ mpp = &MPP;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR531";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>; // 128M at 0x0
+ };
+
+ localbus@f1000000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x0f 0xf9300000 0x00100000
+ 0x1 0x1e 0xfa000000 0x00100000
+ 0x2 0x1d 0xfa100000 0x02000000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ led@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "led";
+ reg = <0x1 0x0 0x00100000>;
+ };
+
+ nor@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x2 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+
+ soc88f5182@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <0>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x54>;
+ pin-count = <20>;
+ pin-map = <
+ 0 3 /* MPP[0]: GPIO[0] */
+ 2 2 /* MPP[2]: PCI_REQn[3] */
+ 3 2 /* MPP[3]: PCI_GNTn[3] */
+ 4 2 /* MPP[4]: PCI_REQn[4] */
+ 5 2 /* MPP[5]: PCI_GNTn[4] */
+ 6 5 /* MPP[6]: SATA0_ACT */
+ 7 5 /* MPP[7]: SATA1_ACT */
+ 12 5 /* MPP[12]: SATA0_PRESENT */
+ 13 5 /* MPP[13]: SATA1_PRESENT */
+ 14 4 /* MPP[14]: NAND Flash REn[2] */
+ 15 4 /* MPP[15]: NAND Flash WEn[2] */
+ 16 0 /* MPP[16]: UA1_RXD */
+ 17 0 /* MPP[17]: UA1_TXD */
+ 18 0 /* MPP[18]: UA1_CTS */
+ 19 0 >; /* MPP[19]: UA1_RTS */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <6 7 8 9>;
+ interrupt-parent = <&PIC>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V1";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <18 19 20 21 22>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <3>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <4>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <17 16>;
+ interrupt-parent = <&PIC>;
+ };
+
+ idma@60000 {
+ compatible = "mrvl,idma";
+ reg = <0x60000 0x1000>;
+ interrupts = <24 25 26 27 23>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sata@80000 {
+ compatible = "mrvl,sata";
+ reg = <0x80000 0x6000>;
+ interrupts = <29>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/db88f5281.dts b/usr/src/boot/sys/boot/fdt/dts/arm/db88f5281.dts
new file mode 100644
index 0000000000..61212eb4db
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/db88f5281.dts
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell DB-88F5281 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,DB-88F5281";
+ compatible = "DB-88F5281-BP", "DB-88F5281-BP-A";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ mpp = &MPP;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR531";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>; // 128M at 0x0
+ };
+
+ localbus@f1000000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x0f 0xf9300000 0x00100000
+ 0x1 0x1e 0xfa000000 0x00100000
+ 0x2 0x1d 0xfa100000 0x02000000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ led@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "led";
+ reg = <0x1 0x0 0x00100000>;
+ };
+
+ nor@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x2 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+
+ soc88f5281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <0>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x54>;
+ pin-count = <20>;
+ pin-map = <
+ 0 3 /* MPP[0]: GPIO[0] */
+ 2 2 /* MPP[2]: PCI_REQn[3] */
+ 3 2 /* MPP[3]: PCI_GNTn[3] */
+ 4 2 /* MPP[4]: PCI_REQn[4] */
+ 5 2 /* MPP[5]: PCI_GNTn[4] */
+ 6 3 /* MPP[6]: <UNKNOWN> */
+ 7 3 /* MPP[7]: <UNKNOWN> */
+ 8 3 /* MPP[8]: <UNKNOWN> */
+ 9 3 /* MPP[9]: <UNKNOWN> */
+ 14 4 /* MPP[14]: NAND Flash REn[2] */
+ 15 4 /* MPP[15]: NAND Flash WEn[2] */
+ 16 0 /* MPP[16]: UA1_RXD */
+ 17 0 /* MPP[17]: UA1_TXD */
+ 18 0 /* MPP[18]: UA1_CTS */
+ 19 0 >; /* MPP[19]: UA1_RTS */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <6 7 8 9>;
+ interrupt-parent = <&PIC>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V1";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <18 19 20 21 22>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x8>;
+ };
+ };
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <3>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <4>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <17 16>;
+ interrupt-parent = <&PIC>;
+ };
+
+ idma@60000 {
+ compatible = "mrvl,idma";
+ reg = <0x60000 0x1000>;
+ interrupts = <24 25 26 27 23>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/db88f6281.dts b/usr/src/boot/sys/boot/fdt/dts/arm/db88f6281.dts
new file mode 100644
index 0000000000..55a27fc303
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/db88f6281.dts
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2009-2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell DB-88F6281 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,DB-88F6281";
+ compatible = "DB-88F6281-BP", "DB-88F6281-BP-A";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ mpp = &MPP;
+ pci0 = &pci0;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ soc = &SOC;
+ sram = &SRAM;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR131";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>; // 512M at 0x0
+ };
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <3>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mrvl,nfc";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ slice@0 {
+ reg = <0x0 0x200000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ slice@200000 {
+ reg = <0x200000 0x7e00000>;
+ label = "root";
+ };
+ };
+ };
+
+ SOC: soc88f6281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <1>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 1 /* MPP[0]: NF_IO[2] */
+ 1 1 /* MPP[1]: NF_IO[3] */
+ 2 1 /* MPP[2]: NF_IO[4] */
+ 3 1 /* MPP[3]: NF_IO[5] */
+ 4 1 /* MPP[4]: NF_IO[6] */
+ 5 1 /* MPP[5]: NF_IO[7] */
+ 6 1 /* MPP[6]: SYSRST_OUTn */
+ 7 2 /* MPP[7]: SPI_SCn */
+ 8 1 /* MPP[8]: TW_SDA */
+ 9 1 /* MPP[9]: TW_SCK */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: UA0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 20 5 /* MPP[20]: SATA1_AC */
+ 21 5 >; /* MPP[21]: SATA0_AC */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <35 36 37 38 39 40 41>;
+ interrupt-parent = <&PIC>;
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <12 13 14 11 46>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x8>;
+ };
+ };
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <33>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <34>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@30000 {
+ compatible = "mrvl,cesa";
+ reg = <0x30000 0x10000>;
+ interrupts = <22>;
+ interrupt-parent = <&PIC>;
+
+ sram-handle = <&SRAM>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <48 19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <5 6 7 8>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sata@80000 {
+ compatible = "mrvl,sata";
+ reg = <0x80000 0x6000>;
+ interrupts = <21>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ SRAM: sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ pci0: pcie@f1040000 {
+ compatible = "mrvl,pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf1040000 0x2000>;
+ bus-range = <0 255>;
+ ranges = <0x02000000 0x0 0xf1300000 0xf1300000 0x0 0x04000000
+ 0x01000000 0x0 0x00000000 0xf1100000 0x0 0x00100000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&PIC>;
+ interrupts = <44>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x1 */
+ 0x0800 0x0 0x0 0x1 &PIC 0x9
+ 0x0800 0x0 0x0 0x2 &PIC 0x9
+ 0x0800 0x0 0x0 0x3 &PIC 0x9
+ 0x0800 0x0 0x0 0x4 &PIC 0x9
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xf1300000
+ 0x02000000 0x0 0xf1300000
+ 0x0 0x04000000
+
+ 0x01000000 0x0 0x0
+ 0x01000000 0x0 0x0
+ 0x0 0x00100000>;
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/digi-ccwmx53.dts b/usr/src/boot/sys/boot/fdt/dts/arm/digi-ccwmx53.dts
new file mode 100644
index 0000000000..f101c5a27d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/digi-ccwmx53.dts
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * Copyright (c) 2013 Rui Paulo
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Digi ConnectCore Wi-i.MX53
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx53x.dtsi"
+
+/ {
+ model = "Digi ConnectCore Wi-i.MX53";
+ compatible = "digi,imx53-ccwm53", "fsl,imx53";
+
+ memory {
+ /* RAM 512M */
+ reg = <0x70000000 0x10000000
+ 0xB0000000 0x10000000>;
+ };
+
+ localbus@10000000 {
+ sata@10000000 {
+ status = "okay";
+ };
+ ipu3@1E000000 {
+ status = "okay";
+ };
+ };
+
+ soc@50000000 {
+ aips@50000000 {
+ spba@50000000 {
+ esdhc@50004000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ esdhc@50008000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ SSI2: ssi@50014000 {
+ status = "okay";
+ };
+ };
+ timer@53fa0000 {
+ status = "okay";
+ };
+ /* UART1, console */
+ console: serial@53fbc000 {
+ status = "okay";
+ clock-frequency = <0>; /* won't load w/o this */
+ };
+ serial@53fc0000 {
+ status = "okay";
+ clock-frequency = <0>; /* won't load w/o this */
+ };
+ serial@53ff0000 {
+ status = "okay";
+ clock-frequency = <0>; /* won't load w/o this */
+ };
+ clock@53fd4000 {
+ status = "okay";
+ };
+ gpio@53f84000 {
+ status = "okay";
+ };
+ gpio@53f88000 {
+ status = "okay";
+ };
+ gpio@53f8c000 {
+ status = "okay";
+ };
+ gpio@53f90000 {
+ status = "okay";
+ };
+ usb@53f80000 /* OTG */ {
+ status = "okay";
+ };
+ usb@53f80200 /* Host 1 */ {
+ status = "okay";
+ };
+ wdog@53f98000 {
+ status = "okay";
+ };
+ i2c@53fec000 {
+ status = "okay";
+ rtc@68 {
+ compatible = "dialog,ds9052";
+ reg = <0x48>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+ };
+ aips@60000000 {
+ ethernet@63fec000 {
+ status = "okay";
+ phy-mode = "rmii";
+ };
+ i2c@63fc4000 {
+ status = "okay";
+ };
+ i2c@63fc8000 {
+ status = "okay";
+ };
+ audmux@63fd4000 {
+ status = "okay";
+ };
+ ide@63fe0000 {
+ status = "okay";
+ };
+ serial@63f90000 {
+ status = "okay";
+ };
+ };
+ };
+
+ aliases {
+ SSI2 = &SSI2;
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/dockstar.dts b/usr/src/boot/sys/boot/fdt/dts/arm/dockstar.dts
new file mode 100644
index 0000000000..595894a7c8
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/dockstar.dts
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Seagate DockStar (Marvell SheevaPlug based) Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "seagate,DockStar";
+ compatible = "DockStar";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ mpp = &MPP;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ soc = &SOC;
+ sram = &SRAM;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR131";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x8000000>; // 128M at 0x0
+ };
+
+ localbus@f1000000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+
+ /* This reflects CPU decode windows setup for NAND access. */
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mrvl,nfc";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+
+ SOC: soc88f6281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <1>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 1 /* MPP[0]: NF_IO[2] */
+ 1 1 /* MPP[1]: NF_IO[3] */
+ 2 1 /* MPP[2]: NF_IO[4] */
+ 3 1 /* MPP[3]: NF_IO[5] */
+ 4 1 /* MPP[4]: NF_IO[6] */
+ 5 1 /* MPP[5]: NF_IO[7] */
+ 6 1 /* MPP[6]: SYSRST_OUTn */
+ 8 2 /* MPP[8]: UA0_RTS */
+ 9 2 /* MPP[9]: UA0_CTS */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: UA0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 29 1 >; /* MPP[29]: TSMP[9] */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <35 36 37 38 39 40 41>;
+ interrupt-parent = <&PIC>;
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <12 13 14 11 46>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <33>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <34>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@30000 {
+ compatible = "mrvl,cesa";
+ reg = <0x30000 0x10000>;
+ interrupts = <22>;
+ interrupt-parent = <&PIC>;
+
+ sram-handle = <&SRAM>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <48 19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <5 6 7 8>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ SRAM: sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001.dts b/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001.dts
new file mode 100644
index 0000000000..92ca1b0ec8
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001.dts
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software substantially based on work developed by Semihalf
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * GlobalScale Technologies DreamPlug Device Tree Source.
+ *
+ * This source is for version 10 revision 01 units with NOR SPI flash.
+ * These units are marked "1001" on the serial number label.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "GlobalScale Technologies Dreamplug v1001";
+ compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ mpp = &MPP;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ soc = &SOC;
+ sram = &SRAM;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR131";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>; // 512M at 0x0
+ };
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <1>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x1e 0xfa000000 0x00100000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+
+ SOC: soc88f6281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <1>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 2 /* MPP[ 0]: SPI_SCn */
+ 1 2 /* MPP[ 1]: SPI_MOSI */
+ 2 2 /* MPP[ 2]: SPI_SCK */
+ 3 2 /* MPP[ 3]: SPI_MISO */
+ 4 1 /* MPP[ 4]: NF_IO[6] */
+ 5 1 /* MPP[ 5]: NF_IO[7] */
+ 6 1 /* MPP[ 6]: SYSRST_OUTn */
+ 7 0 /* MPP[ 7]: GPO[7] */
+ 8 1 /* MPP[ 8]: TW_SDA */
+ 9 1 /* MPP[ 9]: TW_SCK */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: US0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 20 3 /* MPP[20]: GE1[ 0] */
+ 21 3 /* MPP[21]: GE1[ 1] */
+ 22 3 /* MPP[22]: GE1[ 2] */
+ 23 3 /* MPP[23]: GE1[ 3] */
+ 24 3 /* MPP[24]: GE1[ 4] */
+ 25 3 /* MPP[25]: GE1[ 5] */
+ 26 3 /* MPP[26]: GE1[ 6] */
+ 27 3 /* MPP[27]: GE1[ 7] */
+ 28 3 /* MPP[28]: GE1[ 8] */
+ 29 3 /* MPP[29]: GE1[ 9] */
+ 30 3 /* MPP[30]: GE1[10] */
+ 31 3 /* MPP[31]: GE1[11] */
+ 32 3 /* MPP[32]: GE1[12] */
+ 33 3 /* MPP[33]: GE1[13] */
+ 34 3 /* MPP[34]: GE1[14] */
+ 35 3 /* MPP[35]: GE1[15] */
+ 36 0 /* MPP[36]: GPIO[36] */
+ 37 0 /* MPP[37]: GPIO[37] */
+ 38 0 /* MPP[38]: GPIO[38] */
+ 39 0 /* MPP[39]: GPIO[39] */
+ 40 2 /* MPP[40]: TDM_SPI_SCK */
+ 41 2 /* MPP[41]: TDM_SPI_MISO */
+ 42 2 /* MPP[42]: TDM_SPI_MOSI */
+ 43 0 /* MPP[43]: GPIO[43] */
+ 44 0 /* MPP[44]: GPIO[44] */
+ 45 0 /* MPP[45]: GPIO[45] */
+ 46 0 /* MPP[46]: GPIO[46] */
+ 47 0 /* MPP[47]: GPIO[47] */
+ 48 0 /* MPP[48]: GPIO[48] */
+ 49 0 /* MPP[49]: GPIO[49] */
+ >;
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <35 36 37 38 39 40 41>;
+ interrupt-parent = <&PIC>;
+ pin-count = <50>;
+ };
+
+ gpioled@0 {
+ compatible = "mrvl,gpioled";
+
+ gpios = <&GPIO 47 2 0 /* GPIO[47] BT LED: OUT */
+ &GPIO 48 2 0 /* GPIO[48] WLAN LED: OUT */
+ &GPIO 49 2 0>; /* GPIO[49] WLAN AP LED: OUT */
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <12 13 14 11 46>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+ };
+
+ enet1: ethernet@76000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x76000 0x02000>;
+ ranges = <0x0 0x76000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <16 17 18 15 47>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy1>;
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <33>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <34>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@30000 {
+ compatible = "mrvl,cesa";
+ reg = <0x30000 0x10000>;
+ interrupts = <22>;
+ interrupt-parent = <&PIC>;
+
+ sram-handle = <&SRAM>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <48 19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <5 6 7 8>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sata@80000 {
+ compatible = "mrvl,sata";
+ reg = <0x80000 0x6000>;
+ interrupts = <21>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sdio@90000 {
+ compatible = "mrvl,sdio";
+ reg = <0x90000 0x134>;
+ interrupts = <28>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ SRAM: sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001N.dts b/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001N.dts
new file mode 100644
index 0000000000..230a65f486
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/dreamplug-1001N.dts
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software substantially based on work developed by Semihalf
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * GlobalScale Technologies DreamPlug Device Tree Source.
+ *
+ * This source is for version 10 revision 01 units with NAND flash.
+ * These units are marked "1001N" on the serial number label.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "GlobalScale Technologies Dreamplug v1001N";
+ compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ mpp = &MPP;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ soc = &SOC;
+ sram = &SRAM;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR131";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>; // 512M at 0x0
+ };
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <1>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mrvl,nfc";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ // Slice info reported by builtin linux when it boots...
+ //[ 11.161328] 0x00000000-0x00100000 : "u-boot"
+ //[ 11.167431] 0x00100000-0x00500000 : "uImage"
+ //[ 11.173471] 0x00500000-0x20000000 : "root"
+
+ slice@0 {
+ reg = <0x0 0x100000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ slice@200000 {
+ reg = <0x100000 0x40000>;
+ label = "uImage";
+ };
+
+ slice@500000 {
+ reg = <0x500000 0x1FB00000>;
+ label = "root";
+ };
+ };
+ };
+
+ SOC: soc88f6281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <1>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 1 /* MPP[ 0]: NF_IO[2] */
+ 1 1 /* MPP[ 1]: NF_IO[3] */
+ 2 1 /* MPP[ 2]: NF_IO[4] */
+ 3 1 /* MPP[ 3]: NF_IO[5] */
+ 4 1 /* MPP[ 4]: NF_IO[6] */
+ 5 1 /* MPP[ 5]: NF_IO[7] */
+ 6 1 /* MPP[ 6]: SYSRST_OUTn */
+ 7 0 /* MPP[ 7]: GPO[7] */
+ 8 1 /* MPP[ 8]: TW_SDA */
+ 9 1 /* MPP[ 9]: TW_SCK */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: US0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 20 3 /* MPP[20]: GE1[ 0] */
+ 21 3 /* MPP[21]: GE1[ 1] */
+ 22 3 /* MPP[22]: GE1[ 2] */
+ 23 3 /* MPP[23]: GE1[ 3] */
+ 24 3 /* MPP[24]: GE1[ 4] */
+ 25 3 /* MPP[25]: GE1[ 5] */
+ 26 3 /* MPP[26]: GE1[ 6] */
+ 27 3 /* MPP[27]: GE1[ 7] */
+ 28 3 /* MPP[28]: GE1[ 8] */
+ 29 3 /* MPP[29]: GE1[ 9] */
+ 30 3 /* MPP[30]: GE1[10] */
+ 31 3 /* MPP[31]: GE1[11] */
+ 32 3 /* MPP[32]: GE1[12] */
+ 33 3 /* MPP[33]: GE1[13] */
+ 34 3 /* MPP[34]: GE1[14] */
+ 35 3 /* MPP[35]: GE1[15] */
+ 36 0 /* MPP[36]: GPIO[36] */
+ 37 0 /* MPP[37]: GPIO[37] */
+ 38 0 /* MPP[38]: GPIO[38] */
+ 39 0 /* MPP[39]: GPIO[39] */
+ 40 2 /* MPP[40]: TDM_SPI_SCK */
+ 41 2 /* MPP[41]: TDM_SPI_MISO */
+ 42 2 /* MPP[42]: TDM_SPI_MOSI */
+ 43 0 /* MPP[43]: GPIO[43] */
+ 44 0 /* MPP[44]: GPIO[44] */
+ 45 0 /* MPP[45]: GPIO[45] */
+ 46 0 /* MPP[46]: GPIO[46] */
+ 47 0 /* MPP[47]: GPIO[47] */
+ 48 0 /* MPP[48]: GPIO[48] */
+ 49 0 /* MPP[49]: GPIO[49] */
+ >;
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <35 36 37 38 39 40 41>;
+ interrupt-parent = <&PIC>;
+ pin-count = <50>;
+ };
+
+ gpioled@0 {
+ compatible = "mrvl,gpioled";
+
+ gpios = <&GPIO 47 2 0 /* GPIO[47] BT LED: OUT */
+ &GPIO 48 2 0 /* GPIO[48] WLAN LED: OUT */
+ &GPIO 49 2 0>; /* GPIO[49] WLAN AP LED: OUT */
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <12 13 14 11 46>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+ };
+
+ enet1: ethernet@76000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x76000 0x02000>;
+ ranges = <0x0 0x76000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <16 17 18 15 47>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy1>;
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <33>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <34>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@30000 {
+ compatible = "mrvl,cesa";
+ reg = <0x30000 0x10000>;
+ interrupts = <22>;
+ interrupt-parent = <&PIC>;
+
+ sram-handle = <&SRAM>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <48 19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <5 6 7 8>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sata@80000 {
+ compatible = "mrvl,sata";
+ reg = <0x80000 0x6000>;
+ interrupts = <21>;
+ interrupt-parent = <&PIC>;
+ };
+
+ sdio@90000 {
+ compatible = "mrvl,sdio";
+ reg = <0x90000 0x134>;
+ interrupts = <28>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ SRAM: sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/ea3250.dts b/usr/src/boot/sys/boot/fdt/dts/arm/ea3250.dts
new file mode 100644
index 0000000000..2c466e3637
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/ea3250.dts
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2011 Jakub Klama <jceel@FreeBSD.org>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Embedded Artists LPC3250-Kit Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "ea,LPC3250-KIT";
+ compatible = "LPC3250-KIT";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &soc;
+ serial4 = &serial4;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,926EJ-S";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x4000000>; // 64M at 0x80000000
+ };
+
+ soc: ahb7@40000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x40000000 0x10000000>;
+ bus-frequency = <13000000>;
+
+ pwr@4000 {
+ compatible = "lpc,pwr";
+ reg = <0x4000 0x4000>;
+ };
+
+ PIC: pic@8000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x8000 0xc000>;
+ compatible = "lpc,pic";
+ };
+
+ timer@44000 {
+ compatible = "lpc,timer";
+ reg = <0x44000 0x4000
+ 0x4c000 0x4000>;
+ interrupts = <16 17>;
+ interrupt-parent = <&PIC>;
+ };
+
+ rtc@24000 {
+ compatible = "lpc,rtc";
+ reg = <0x24000 0x4000>;
+ interrupts = <52>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial0: serial@14000 {
+ compatible = "lpc,hsuart";
+ status = "disabled";
+ reg = <0x14000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <26>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@18000 {
+ compatible = "lpc,hsuart";
+ status = "disabled";
+ reg = <0x18000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <25>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial2: serial@80000 {
+ compatible = "lpc,uart";
+ status = "disabled";
+ reg = <0x80000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <13000000>;
+ interrupts = <7>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial3: serial@88000 {
+ compatible = "lpc,uart";
+ status = "disabled";
+ reg = <0x88000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <13000000>;
+ interrupts = <8>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial4: serial@90000 {
+ compatible = "lpc,uart";
+ reg = <0x90000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <13000000>;
+ current-speed = <115200>;
+ interrupts = <9>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial5: serial@98000 {
+ compatible = "lpc,uart";
+ status = "disabled";
+ reg = <0x98000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <13000000>;
+ interrupts = <10>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial6: serial@1c000 {
+ compatible = "lpc,uart";
+ status = "disabled";
+ reg = <0x1c000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <24>;
+ interrupt-parent = <&PIC>;
+ };
+
+ gpio@28000 {
+ compatible = "lpc,gpio";
+ reg = <0x28000 0x4000>;
+ };
+ };
+
+ ahb6@30000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x30000000 0x10000000>;
+
+ dmac@1000000 {
+ compatible = "lpc,dmac";
+ reg = <0x1000000 0x20000>;
+ interrupts = <28>;
+ interrupt-parent = <&PIC>;
+ };
+
+ usb@1020000 {
+ compatible = "lpc,usb-ohci", "usb-ohci";
+ reg = <0x1020000 0x20000>;
+ interrupts = <59>;
+ interrupt-parent = <&PIC>;
+ };
+
+ lpcfb@1040000 {
+ compatible = "lpc,fb";
+ reg = <0x1040000 0x20000>;
+ interrupts = <14>;
+ interrupt-parent = <&PIC>;
+
+ /* Screen parameters: */
+ is-tft = <1>;
+ horizontal-resolution = <240>;
+ vertical-resolution = <320>;
+ bits-per-pixel = <16>;
+ pixel-clock = <121654>;
+ left-margin = <28>;
+ right-margin = <10>;
+ upper-margin = <2>;
+ lower-margin = <2>;
+ hsync-len = <3>;
+ vsync-len = <2>;
+ };
+
+ lpe@1060000 {
+ compatible = "lpc,ethernet";
+ reg = <0x1060000 0x20000>;
+ interrupts = <29>;
+ interrupt-parent = <&PIC>;
+ local-mac-address = [ 00 1a f1 01 1f 23 ];
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "lpc,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+
+ };
+ };
+
+ ahb5@20000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x20000000 0x10000000>;
+
+ spi0@84000 {
+ compatible = "lpc,spi";
+ reg = <0x84000 0x4000>;
+ interrupts = <20>;
+ interrupt-parent = <&PIC>;
+ };
+
+ spi1@8c000 {
+ compatible = "lpc,spi";
+ status = "disabled";
+ reg = <0x8c000 0x4000>;
+ interrupts = <21>;
+ interrupt-parent = <&PIC>;
+ };
+
+ lpcmmc@98000 {
+ compatible = "lpc,mmc";
+ reg = <0x98000 0x4000>;
+ interrupts = <15 13>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ chosen {
+ stdin = "serial4";
+ stdout = "serial4";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/efikamx.dts b/usr/src/boot/sys/boot/fdt/dts/arm/efikamx.dts
new file mode 100644
index 0000000000..e077fb78ad
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/efikamx.dts
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Freescale i.MX515 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx51x.dtsi"
+
+/ {
+ model = "Genesi Efika MX";
+ compatible = "genesi,imx51-efikamx", "fsl,imx51";
+
+ memory {
+ /* RAM 512M */
+ reg = <0x90000000 0x20000000>;
+ };
+
+ localbus@5e000000 {
+ ipu3@5e000000 {
+ status = "okay";
+ };
+ };
+
+ soc@70000000 {
+ aips@70000000 {
+ spba@70000000 {
+ esdhc@70004000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ esdhc@70008000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ SSI2: ssi@70014000 {
+ status = "okay";
+ };
+ };
+ timer@73fa0000 {
+ status = "okay";
+ };
+
+ /* UART1, console */
+ UART1: serial@73fbc000 {
+ status = "okay";
+ clock-frequency = <3000000>; /* XXX */
+ };
+
+ clock@73fd4000 {
+ status = "okay";
+ };
+ gpio@73f84000 {
+ status = "okay";
+ };
+ gpio@73f88000 {
+ status = "okay";
+ };
+ gpio@73f8c000 {
+ status = "okay";
+ };
+ gpio@73f90000 {
+ status = "okay";
+ };
+ usb@73f80000 /* OTG */ {
+ status = "okay";
+ };
+ usb@73f80200 /* Host 1 */ {
+ status = "okay";
+ };
+ wdog@73f98000 {
+ status = "okay";
+ };
+ };
+ aips@80000000 {
+ i2c@83fc4000 {
+ status = "okay";
+ };
+ i2c@83fc8000 {
+ status = "okay";
+ };
+ audmux@83fd4000 {
+ status = "okay";
+ };
+ ide@83fe0000 {
+ status = "okay";
+ };
+ };
+ };
+
+ aliases {
+ UART1 = &UART1;
+ SSI2 = &SSI2;
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "UART1";
+ stdout = "UART1";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5.dtsi
new file mode 100644
index 0000000000..87d8fdb019
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5.dtsi
@@ -0,0 +1,337 @@
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ compatible = "samsung,exynos5";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ clk0 = &clk0;
+ dp0 = &dp0;
+ fimd0 = &fimd0;
+ };
+
+ SOC: Exynos5@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ pmu_system_controller: system-controller@10040000 {
+ reg = <0x10040000 0x5000>;
+ status = "disabled";
+ };
+
+ GIC: interrupt-controller@10481000 {
+ compatible = "arm,gic";
+ reg = < 0x10481000 0x1000 >, /* Distributor Registers */
+ < 0x10482000 0x2000 >; /* CPU Interface Registers */
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ combiner: interrupt-controller@10440000 {
+ compatible = "exynos,combiner";
+ reg = <0x10440000 0x1000>;
+ interrupts = < 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55
+ 56 57 58 59 60 61 62 63 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ clk0: clk@10010000 {
+ compatible = "exynos,clk";
+ reg = < 0x10020000 0x20000 >;
+ };
+
+ mct {
+ compatible = "exynos,mct";
+ reg = < 0x101C0000 0x1000 >;
+ clock-frequency = <24000000>;
+ };
+
+ generic_timer {
+ compatible = "arm,armv7-timer";
+ clock-frequency = <24000000>;
+ interrupts = < 29 30 27 26 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ pwm {
+ compatible = "samsung,s3c24x0-timer";
+ reg = <0x12DD0000 0x1000>;
+ interrupts = < 71 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <24000000>;
+ };
+
+ pad0: pad@11400000 {
+ status = "disabled";
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ compatible = "samsung,exynos5420-usbdrd-phy";
+ status = "disabled";
+ reg = <0x12100000 0x100>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ };
+
+ usbdrd_phy1: phy@12500000 {
+ compatible = "samsung,exynos5420-usbdrd-phy";
+ status = "disabled";
+ reg = <0x12500000 0x100>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ };
+
+ xhci@12000000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ status = "disabled";
+ reg = <0x12000000 0x1000>,
+ <0x1200c100 0x1000>;
+ interrupts = < 104 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ xhci@12400000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ status = "disabled";
+ reg = <0x12400000 0x1000>,
+ <0x1240c100 0x1000>;
+ interrupts = < 105 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb@12110000 {
+ compatible = "exynos,usb-ehci", "usb-ehci";
+ status = "disabled";
+ reg = <0x12110000 0x1000>, /* EHCI */
+ <0x12130000 0x1000>, /* EHCI host ctrl */
+ <0x10050230 0x10>; /* Sysreg */
+ interrupts = < 103 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb@12120000 {
+ compatible = "exynos,usb-ohci", "usb-ohci";
+ status = "disabled";
+ reg = <0x12120000 0x10000>;
+ interrupts = < 103 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ sdhci@12200000 {
+ compatible = "sdhci_generic";
+ status = "disabled";
+ reg = <0x12200000 0x1000>;
+ interrupts = <107>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <24000000>; /* TODO: verify freq */
+ };
+
+ sdhci@12210000 {
+ compatible = "sdhci_generic";
+ status = "disabled";
+ reg = <0x12210000 0x1000>;
+ interrupts = <108>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <24000000>;
+ };
+
+ sdhci@12220000 {
+ compatible = "sdhci_generic";
+ status = "disabled";
+ reg = <0x12220000 0x1000>;
+ interrupts = <109>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <24000000>;
+ };
+
+ sdhci@12230000 {
+ compatible = "sdhci_generic";
+ status = "disabled";
+ reg = <0x12230000 0x1000>;
+ interrupts = <110>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <24000000>;
+ };
+
+ serial0: serial@12C00000 {
+ compatible = "exynos";
+ status = "disabled";
+ reg = <0x12C00000 0x100>;
+ interrupts = < 83 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 100000000 >;
+ current-speed = <115200>;
+ };
+
+ serial1: serial@12C10000 {
+ compatible = "exynos";
+ status = "disabled";
+ reg = <0x12C10000 0x100>;
+ interrupts = < 84 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 100000000 >;
+ current-speed = <115200>;
+ };
+
+ serial2: serial@12C20000 {
+ compatible = "exynos";
+ status = "disabled";
+ reg = <0x12C20000 0x100>;
+ interrupts = < 85 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 100000000 >;
+ current-speed = <115200>;
+ };
+
+ serial3: serial@12C30000 {
+ compatible = "exynos";
+ status = "disabled";
+ reg = <0x12C30000 0x100>;
+ interrupts = < 86 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 100000000 >;
+ current-speed = <115200>;
+ };
+
+ spi0: spi@12d20000 {
+ compatible = "samsung,exynos5-spi";
+ status = "disabled";
+ reg = <0x12d20000 0x100>;
+ interrupts = < 100 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ spi1: spi@12d30000 {
+ compatible = "samsung,exynos5-spi";
+ status = "disabled";
+ reg = <0x12d30000 0x100>;
+ interrupts = < 101 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ spi2: spi@12d40000 {
+ compatible = "samsung,exynos5-spi";
+ status = "disabled";
+ reg = <0x12d40000 0x100>;
+ interrupts = < 102 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c0: i2c@12C60000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12C60000 0x10000>;
+ interrupts = < 88 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c1: i2c@12C70000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12C70000 0x10000>;
+ interrupts = < 89 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c2: i2c@12C80000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12C80000 0x10000>;
+ interrupts = < 90 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c3: i2c@12C90000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12C90000 0x10000>;
+ interrupts = < 91 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c4: i2c@12CA0000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12CA0000 0x10000>;
+ interrupts = < 92 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c5: i2c@12CB0000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12CB0000 0x10000>;
+ interrupts = < 93 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c6: i2c@12CC0000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12CC0000 0x10000>;
+ interrupts = < 94 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ i2c7: i2c@12CD0000 {
+ compatible = "exynos,i2c";
+ status = "disabled";
+ reg = <0x12CD0000 0x10000>;
+ interrupts = < 95 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ fimd0: fimd@14400000 {
+ compatible = "exynos,fimd";
+ status = "disabled";
+ reg = < 0x14400000 0x10000 >, /* fimd */
+ < 0x14420000 0x10000 >, /* disp */
+ < 0x10050000 0x220 >; /* sysreg */
+ interrupt-parent = <&GIC>;
+ };
+
+ dp0: dp@145B0000 {
+ compatible = "exynos,dp";
+ status = "disabled";
+ reg = < 0x145B0000 0x10000 >;
+ interrupt-parent = <&GIC>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-arndale.dts b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-arndale.dts
new file mode 100644
index 0000000000..81d1817fc8
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-arndale.dts
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "exynos5250.dtsi"
+
+/ {
+ model = "Arndale Board";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x40000000 0x80000000 >; /* 2G */
+ };
+
+ SOC: Exynos5@0 {
+
+ pad0: pad@11400000 {
+ status = "okay";
+ };
+
+ serial2: serial@12C20000 {
+ status = "okay";
+ };
+
+ };
+
+ chosen {
+ stdin = &serial2;
+ stdout = &serial2;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-snow.dts b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-snow.dts
new file mode 100644
index 0000000000..cb40ec5b0b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-snow.dts
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "exynos5250.dtsi"
+
+/ {
+ model = "Samsung Chromebook";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x40000000 0x80000000 >; /* 2G */
+ };
+
+ SOC: Exynos5@0 {
+
+ pad0: pad@11400000 {
+ status = "okay";
+ };
+
+ fimd0: fimd@14400000 {
+ status = "okay";
+
+ panel-size = < 1366 768 >;
+ panel-hsync = < 80 32 48 >;
+ panel-vsync = < 14 5 3 >;
+ panel-clk-div = < 17 >;
+ panel-backlight-pin = < 25 >;
+ };
+
+ i2c4: i2c@12CA0000 {
+ status = "okay";
+ };
+
+ keyboard-controller {
+ compatible = "google,mkbp-keyb";
+ google,key-rows = <8>;
+ google,key-columns = <13>;
+ freebsd,intr-gpio = <146>;
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ vbus-supply = < 155 >;
+ };
+ };
+
+ i2c-arbitrator {
+ freebsd,our-gpio = <177>;
+ freebsd,ec-gpio = <168>;
+ };
+
+ chosen {
+ stdin = &serial2;
+ stdout = &serial2;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-spring.dts b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-spring.dts
new file mode 100644
index 0000000000..c0e4285806
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250-spring.dts
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "exynos5250.dtsi"
+
+/ {
+ model = "HP Chromebook 11";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x40000000 0x80000000 >; /* 2G */
+ };
+
+ SOC: Exynos5@0 {
+
+ pad0: pad@11400000 {
+ status = "okay";
+ };
+
+ fimd0: fimd@14400000 {
+ status = "okay";
+
+ panel-size = < 1366 768 >;
+ panel-hsync = < 80 32 48 >;
+ panel-vsync = < 14 5 3 >;
+ panel-clk-div = < 17 >;
+ panel-backlight-pin = < 25 >;
+ };
+
+ i2c4: i2c@12CA0000 {
+ status = "okay";
+ };
+
+ keyboard-controller {
+ compatible = "google,mkbp-keyb";
+ google,key-rows = <8>;
+ google,key-columns = <13>;
+ freebsd,intr-gpio = <146>;
+ };
+ };
+
+ chosen {
+ stdin = &serial2;
+ stdout = &serial2;
+ };
+
+ hsichub@13400000 {
+ compatible = "smsc,usb3503";
+ freebsd,reset-gpio = <172>;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250.dtsi
new file mode 100644
index 0000000000..a8f74f498b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5250.dtsi
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/include/ "exynos5.dtsi"
+
+/ {
+ compatible = "samsung,exynos5250", "samsung,exynos5";
+
+ SOC: Exynos5@0 {
+
+ pmu_system_controller: system-controller@10040000 {
+ compatible = "samsung,exynos5250-pmu";
+ status = "okay";
+ };
+
+ pad0: pad@11400000 {
+ compatible = "samsung,exynos5250-padctrl";
+ reg = <0x11400000 0x1000>,
+ <0x13400000 0x1000>,
+ <0x10D10000 0x1000>,
+ <0x03860000 0x1000>;
+ interrupts = < 78 77 82 79 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ serial0: serial@12C00000 {
+ clock-frequency = < 100000000 >;
+ };
+
+ serial1: serial@12C10000 {
+ clock-frequency = < 100000000 >;
+ };
+
+ serial2: serial@12C20000 {
+ clock-frequency = < 100000000 >;
+ };
+
+ serial3: serial@12C30000 {
+ clock-frequency = < 100000000 >;
+ };
+
+ usb@12110000 {
+ status = "okay";
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ status = "okay";
+ };
+
+ xhci@12000000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-arndale-octa.dts b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-arndale-octa.dts
new file mode 100644
index 0000000000..8f090651c3
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-arndale-octa.dts
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "exynos5420.dtsi"
+
+/ {
+ model = "Arndale Octa Board";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x20000000 0x7f200000 >; /* 2G */
+ };
+
+ SOC: Exynos5@0 {
+ serial3: serial@12C30000 {
+ status = "okay";
+ };
+
+ usb@12110000 {
+ status = "okay";
+ };
+
+ mmc2: dwmmc@12220000 {
+ status = "okay";
+ num-slots = <1>;
+ supports-highspeed;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-frequency = <50000000>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+ };
+
+ chosen {
+ stdin = &serial3;
+ stdout = &serial3;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-peach-pit.dts b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-peach-pit.dts
new file mode 100644
index 0000000000..80aca895d7
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420-peach-pit.dts
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "exynos5420.dtsi"
+
+/ {
+ model = "Chromebook Peach Pit";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x20000000 0xdf000000 >; /* 3.5G */
+ };
+
+ SOC: Exynos5@0 {
+
+ fimd0: fimd@14400000 {
+ status = "okay";
+
+ panel-size = < 1366 768 >;
+ panel-hsync = < 80 32 48 >;
+ panel-vsync = < 14 5 3 >;
+ panel-clk-div = < 17 >;
+ panel-backlight-pin = < 25 >;
+ };
+
+ spi2: spi@12d40000 {
+ status = "okay";
+ };
+
+ keyboard-controller {
+ compatible = "google,mkbp-keyb";
+ google,key-rows = <8>;
+ google,key-columns = <13>;
+ freebsd,intr-gpio = < 21 >;
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ vbus-supply = < 217 >;
+ };
+
+ usbdrd_phy1: phy@12500000 {
+ vbus-supply = < 218 >;
+ };
+
+ mmc2: dwmmc@12220000 {
+ status = "okay";
+ num-slots = <1>;
+ supports-highspeed;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-frequency = <50000000>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420.dtsi
new file mode 100644
index 0000000000..38a5a88794
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/exynos5420.dtsi
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/include/ "exynos5.dtsi"
+
+/ {
+ compatible = "samsung,exynos5420", "samsung,exynos5";
+
+ SOC: Exynos5@0 {
+
+ pmu_system_controller: system-controller@10040000 {
+ compatible = "samsung,exynos5420-pmu";
+ status = "okay";
+ };
+
+ pad0: pad@11400000 {
+ compatible = "samsung,exynos5420-padctrl";
+ status = "okay";
+ reg = <0x13400000 0x1000>,
+ <0x13410000 0x1000>,
+ <0x14000000 0x1000>,
+ <0x14010000 0x1000>,
+ <0x03860000 0x1000>;
+ interrupts = < 77 110 78 82 79 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ serial0: serial@12C00000 {
+ clock-frequency = < 50000000 >;
+ };
+
+ serial1: serial@12C10000 {
+ clock-frequency = < 50000000 >;
+ };
+
+ serial2: serial@12C20000 {
+ clock-frequency = < 50000000 >;
+ };
+
+ serial3: serial@12C30000 {
+ clock-frequency = < 50000000 >;
+ };
+
+ usbdrd_phy0: phy@12100000 {
+ status = "okay";
+ };
+
+ usbdrd_phy1: phy@12500000 {
+ status = "okay";
+ };
+
+ xhci@12000000 {
+ status = "okay";
+ };
+
+ xhci@12400000 {
+ status = "okay";
+ };
+
+ mmc0: dwmmc@12200000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ reg = <0x12200000 0x10000>;
+ interrupts = <107>;
+ interrupt-parent = <&GIC>;
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc1: dwmmc@12210000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ reg = <0x12210000 0x10000>;
+ interrupts = <108>;
+ interrupt-parent = <&GIC>;
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc2: dwmmc@12220000 {
+ compatible = "samsung,exynos5420-dw-mshc";
+ reg = <0x12220000 0x10000>;
+ interrupts = <109>;
+ interrupt-parent = <&GIC>;
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/hl201.dts b/usr/src/boot/sys/boot/fdt/dts/arm/hl201.dts
new file mode 100644
index 0000000000..1566b30f8f
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/hl201.dts
@@ -0,0 +1,44 @@
+/*
+ * Hot-e HL-201 - Warner Losh public domain
+ *
+ * $FreeBSD$
+ */
+/dts-v1/;
+
+/*
+ * The following is a white lie. The HL-201 is a stripped down version of
+ * the SAM9G20EK board with a video output chip.
+ */
+#include "at91sam9g20ek_common.dtsi"
+
+/ {
+ model = "Thinlinx HL201";
+ compatible = "thinlinx,hl201", "atmel,at91sam9g20ek", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds1 {
+ label = "ds1";
+ gpios = <&pioA 9 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds5 {
+ label = "ds5";
+ gpios = <&pioA 6 1>;
+ };
+ };
+
+ /* Missing: one wire serial number, video chip */
+
+ aliases {
+ dbgu = &dbgu;
+ };
+
+
+ chosen {
+ stdin = "dbgu";
+ stdout = "dbgu";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/imx51x.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/imx51x.dtsi
new file mode 100644
index 0000000000..cc06f0f355
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/imx51x.dtsi
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Freescale i.MX515 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,MCIMX515";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x8000>;
+ i-cache-size = <0x8000>;
+ /* TODO: describe L2 cache also */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ localbus@e0000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges;
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x00004000>;
+ };
+ /*
+ * 60000000 60000FFF 4K Debug ROM
+ * 60001000 60001FFF 4K ETB
+ * 60002000 60002FFF 4K ETM
+ * 60003000 60003FFF 4K TPIU
+ * 60004000 60004FFF 4K CTI0
+ * 60005000 60005FFF 4K CTI1
+ * 60006000 60006FFF 4K CTI2
+ * 60007000 60007FFF 4K CTI3
+ * 60008000 60008FFF 4K Cortex Debug Unit
+ *
+ * E0000000 E0003FFF 0x4000 TZIC
+ */
+ };
+
+ SOC: soc@70000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges = <0x70000000 0x70000000 0x14000000>;
+
+ aips@70000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* Required by many devices, so better to stay first */
+ /* 73FD4000 0x4000 CCM */
+ clock@73fd4000 {
+ compatible = "fsl,imx51-ccm";
+ /* 83F80000 0x4000 DPLLIP1 */
+ /* 83F84000 0x4000 DPLLIP2 */
+ /* 83F88000 0x4000 DPLLIP3 */
+ reg = <0x73fd4000 0x4000
+ 0x83F80000 0x4000
+ 0x83F84000 0x4000
+ 0x83F88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <71 72>;
+ status = "disabled";
+ };
+
+ /*
+ * GPIO modules moved up - to have it attached for
+ * drivers which rely on GPIO
+ */
+ /* 73F84000 0x4000 GPIO1 */
+ gpio1: gpio@73f84000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f84000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <50 51 42 43 44 45 46 47 48 49>;
+ /* TODO: use <> also */
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F88000 0x4000 GPIO2 */
+ gpio2: gpio@73f88000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F8C000 0x4000 GPIO3 */
+ gpio3: gpio@73f8c000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f8c000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F90000 0x4000 GPIO4 */
+ gpio4: gpio@73f90000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f90000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ spba@70000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 70004000 0x4000 ESDHC 1 */
+ esdhc@70004000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70004000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <1>;
+ status = "disabled";
+ };
+
+ /* 70008000 0x4000 ESDHC 2 */
+ esdhc@70008000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70008000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <2>;
+ status = "disabled";
+ };
+
+ /* 7000C000 0x4000 UART 3 */
+ uart3: serial@7000c000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <33>;
+ status = "disabled";
+ };
+
+ /* 70010000 0x4000 eCSPI1 */
+ ecspi@70010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x70010000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <36>;
+ status = "disabled";
+ };
+
+ /* 70014000 0x4000 SSI2 irq30 */
+ SSI2: ssi@70014000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <30>;
+ status = "disabled";
+ };
+
+ /* 70020000 0x4000 ESDHC 3 */
+ esdhc@70020000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70020000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <3>;
+ status = "disabled";
+ };
+
+ /* 70024000 0x4000 ESDHC 4 */
+ esdhc@70024000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70024000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <4>;
+ status = "disabled";
+ };
+
+ /* 70028000 0x4000 SPDIF */
+ /* 91 SPDIF */
+
+ /* 70030000 0x4000 PATA (PORT UDMA) irq70 */
+
+ /* 70034000 0x4000 SLM */
+ /* 70038000 0x4000 HSI2C */ /* 64 HS-I2C */
+ /* 7003C000 0x4000 SPBA */
+ };
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usbotg: usb@73f80000 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80000 0x0200>;
+ interrupts = <18>;
+ fsl,usbmisc = <&usbmisc 0>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@73f80200 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80200 0x0200>;
+ interrupts = <14>;
+ fsl,usbmisc = <&usbmisc 1>;
+ status = "disabled";
+ };
+
+ usbh2: usb@73f80400 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80400 0x0200>;
+ interrupts = <16>;
+ fsl,usbmisc = <&usbmisc 2>;
+ status = "disabled";
+ };
+
+ usbh3: usb@73f80600 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80600 0x0200>;
+ interrupts = <17>;
+ fsl,usbmisc = <&usbmisc 3>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@73f80800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx51-usbmisc";
+ reg = <0x73f80800 0x200>;
+ };
+
+ /* 73F98000 0x4000 WDOG1 */
+ wdog@73f98000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f98000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <58>;
+ status = "disabled";
+ };
+
+ /* 73F9C000 0x4000 WDOG2 (TZ) */
+ wdog@73f9c000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f9c000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <59>;
+ status = "disabled";
+ };
+
+ /* 73F94000 0x4000 KPP */
+ keyboard@73f94000 {
+ compatible = "fsl,imx51-kpp";
+ reg = <0x73f94000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <60>;
+ status = "disabled";
+ };
+
+ /* 73FA0000 0x4000 GPT */
+ timer@73fa0000 {
+ compatible = "fsl,imx51-gpt";
+ reg = <0x73fa0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <39>;
+ status = "disabled";
+ };
+
+ /* 73FA4000 0x4000 SRTC */
+
+ rtc@73fa4000 {
+ compatible = "fsl,imx51-srtc";
+ reg = <0x73fa4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <24 25>;
+ status = "disabled";
+ };
+
+ /* 73FA8000 0x4000 IOMUXC */
+ iomux@73fa8000 {
+ compatible = "fsl,imx51-iomux";
+ reg = <0x73fa8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <7>;
+ };
+
+ /* 73FAC000 0x4000 EPIT1 */
+ epit1: timer@73fac000 {
+ compatible = "fsl,imx51-epit";
+ reg = <0x73fac000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <40>;
+ status = "disabled";
+ };
+
+ /* 73FB0000 0x4000 EPIT2 */
+ epit2: timer@73fb0000 {
+ compatible = "fsl,imx51-epit";
+ reg = <0x73fb0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <41>;
+ status = "disabled";
+ };
+
+ /* 73FB4000 0x4000 PWM1 */
+ pwm@73fb4000 {
+ compatible = "fsl,imx51-pwm";
+ reg = <0x73fb4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <61>;
+ status = "disabled";
+ };
+
+ /* 73FB8000 0x4000 PWM2 */
+ pwm@73fb8000 {
+ compatible = "fsl,imx51-pwm";
+ reg = <0x73fb8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <94>;
+ status = "disabled";
+ };
+
+ /* 73FBC000 0x4000 UART 1 */
+ uart1: serial@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <31>;
+ status = "disabled";
+ };
+
+ /* 73FC0000 0x4000 UART 2 */
+ uart2: serial@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <32>;
+ status = "disabled";
+ };
+
+ /* 73FC4000 0x4000 USBOH3 */
+ /* NOTYET
+ usb@73fc4000 {
+ compatible = "fsl,imx51-otg";
+ reg = <0x73fc4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <>;
+ status = "disabled";
+ };
+ */
+ /* 73FD0000 0x4000 SRC */
+ reset@73fd0000 {
+ compatible = "fsl,imx51-src";
+ reg = <0x73fd0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <75>;
+ status = "disabled";
+ };
+ /* 73FD8000 0x4000 GPC */
+ power@73fd8000 {
+ compatible = "fsl,imx51-gpc";
+ reg = <0x73fd8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <73 74>;
+ status = "disabled";
+ };
+
+ };
+
+ aips@80000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 83F94000 0x4000 AHBMAX */
+ /* 83F98000 0x4000 IIM */
+ /*
+ * 69 IIM Interrupt request to the processor.
+ * Indicates to the processor that program or
+ * explicit.
+ */
+ /* 83F9C000 0x4000 CSU */
+ /*
+ * 27 CSU Interrupt Request 1. Indicates to the
+ * processor that one or more alarm inputs were.
+ */
+
+ /* 83FA0000 0x4000 TIGERP_PLATFORM_NE_32K_256K */
+ /* irq76 Neon Monitor Interrupt */
+ /* irq77 Performance Unit Interrupt */
+ /* irq78 CTI IRQ */
+ /* irq79 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq80 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq89 Debug Interrupt, Cross-Trigger Interface 2 */
+ /* irq98 Debug Interrupt, Cross-Trigger Interface 3 */
+
+ /* 83FA4000 0x4000 OWIRE irq88 */
+ /* 83FA8000 0x4000 FIRI irq93 */
+ /* 83FAC000 0x4000 eCSPI2 */
+ ecspi@83fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x83fac000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <37>;
+ status = "disabled";
+ };
+
+ /* 83FB0000 0x4000 SDMA */
+ sdma@83fb0000 {
+ compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+ reg = <0x83fb0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <6>;
+ };
+
+ /* 83FB4000 0x4000 SCC */
+ /* 21 SCC Security Monitor High Priority Interrupt. */
+ /* 22 SCC Secure (TrustZone) Interrupt. */
+ /* 23 SCC Regular (Non-Secure) Interrupt. */
+
+ /* 83FB8000 0x4000 ROMCP */
+ /* 83FBC000 0x4000 RTIC */
+ /*
+ * 26 RTIC RTIC (Trust Zone) Interrupt Request.
+ * Indicates that the RTIC has completed hashing the
+ */
+
+ /* 83FC0000 0x4000 CSPI */
+ cspi@83fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+ reg = <0x83fc0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <38>;
+ status = "disabled";
+ };
+
+ /* 83FC4000 0x4000 I2C2 */
+ i2c@83fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x83fc4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <63>;
+ status = "disabled";
+ };
+
+ /* 83FC8000 0x4000 I2C1 */
+ i2c@83fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x83fc8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <62>;
+ status = "disabled";
+ };
+
+ /* 83FCC000 0x4000 SSI1 */
+ /* 29 SSI1 SSI-1 Interrupt Request */
+ SSI1: ssi@83fcc000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x83fcc000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <29>;
+ status = "disabled";
+ };
+
+ /* 83FD0000 0x4000 AUDMUX */
+ audmux@83fd4000 {
+ compatible = "fsl,imx51-audmux";
+ reg = <0x83fd4000 0x4000>;
+ status = "disabled";
+ };
+
+ /* 83FD8000 0x4000 EMI1 */
+ /* 8 EMI (NFC) */
+ /* 15 EMI */
+ /* 97 EMI Boot sequence completed interrupt */
+ /*
+ * 101 EMI Indicates all pages have been transferred
+ * to NFC during an auto program operation.
+ */
+
+ /* 83FE0000 0x4000 PATA (PORT PIO) */
+ /* 70 PATA Parallel ATA host controller interrupt */
+ ide@83fe0000 {
+ compatible = "fsl,imx51-ata";
+ reg = <0x83fe0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <70>;
+ status = "disabled";
+ };
+
+ /* 83FE4000 0x4000 SIM */
+ /* 67 SIM intr composed of oef, xte, sdi1, and sdi0 */
+ /* 68 SIM intr composed of tc, etc, tfe, and rdrf */
+
+ /* 83FE8000 0x4000 SSI3 */
+ /* 96 SSI3 SSI-3 Interrupt Request */
+ SSI3: ssi@83fe8000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x83fe8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <96>;
+ status = "disabled";
+ };
+
+ /* 83FEC000 0x4000 FEC */
+ ethernet@83fec000 {
+ compatible = "fsl,imx51-fec";
+ reg = <0x83fec000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <87>;
+ status = "disabled";
+ };
+
+ /* 83FF0000 0x4000 TVE */
+ /* 92 TVE */
+ /* 83FF4000 0x4000 VPU */
+ /* 9 VPU */
+ /* 100 VPU Idle interrupt from VPU */
+
+ /* 83FF8000 0x4000 SAHARA Lite */
+ /* 19 SAHARA SAHARA host 0 (TrustZone) Intr Lite */
+ /* 20 SAHARA SAHARA host 1 (non-TrustZone) Intr Lite */
+ };
+ };
+
+ localbus@5e000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges;
+
+ vga: ipu3@5e000000 {
+ compatible = "fsl,ipu3";
+ reg = <
+ 0x5e000000 0x08000 /* CM */
+ 0x5e008000 0x08000 /* IDMAC */
+ 0x5e018000 0x08000 /* DP */
+ 0x5e020000 0x08000 /* IC */
+ 0x5e028000 0x08000 /* IRT */
+ 0x5e030000 0x08000 /* CSI0 */
+ 0x5e038000 0x08000 /* CSI1 */
+ 0x5e040000 0x08000 /* DI0 */
+ 0x5e048000 0x08000 /* DI1 */
+ 0x5e050000 0x08000 /* SMFC */
+ 0x5e058000 0x08000 /* DC */
+ 0x5e060000 0x08000 /* DMFC */
+ 0x5e068000 0x08000 /* VDI */
+ 0x5f000000 0x20000 /* CPMEM */
+ 0x5f020000 0x20000 /* LUT */
+ 0x5f040000 0x20000 /* SRM */
+ 0x5f060000 0x20000 /* TPM */
+ 0x5f080000 0x20000 /* DCTMPL */
+ >;
+ interrupt-parent = <&tzic>;
+ interrupts = <
+ 10 /* IPUEX Error */
+ 11 /* IPUEX Sync */
+ >;
+ status = "disabled";
+ };
+ };
+};
+
+/*
+
+TODO: Not mapped interrupts
+
+5 DAP
+84 GPU2D (OpenVG) general interrupt
+85 GPU2D (OpenVG) busy signal (for S/W power gating feasibility)
+12 GPU3D
+102 GPU3D Idle interrupt from GPU3D (for S/W power gating)
+90 SJC
+*/
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/imx53-qsb.dts b/usr/src/boot/sys/boot/fdt/dts/arm/imx53-qsb.dts
new file mode 100644
index 0000000000..f22b540318
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/imx53-qsb.dts
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * Copyright (c) 2013 Rui Paulo
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Freescale i.MX53 Quick Start Board
+ * In u-boot, this board is known as "MX53LOCO" for some reason.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx53x.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Quick Start Board";
+ compatible = "fsl,imx53-qsb", "fsl,imx53";
+
+ memory {
+ /* RAM is 2 banks of 512M each. */
+ reg = <0x70000000 0x20000000
+ 0xb0000000 0x20000000>;
+ };
+
+ localbus@18000000 {
+ ipu3@1E000000 {
+ status = "okay";
+ };
+ };
+
+ soc@50000000 {
+ aips@50000000 {
+ spba@50000000 {
+ esdhc@50004000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ esdhc@50008000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ SSI2: ssi@50014000 {
+ status = "okay";
+ };
+ };
+ timer@53fa0000 {
+ status = "okay";
+ };
+
+ /* UART1, console */
+ console: serial@53fbc000 {
+ status = "okay";
+ clock-frequency = <0>; /* won't load w/o this */
+ };
+
+ clock@53fd4000 {
+ status = "okay";
+ };
+ gpio@53f84000 {
+ status = "okay";
+ };
+ gpio@53f88000 {
+ status = "okay";
+ };
+ gpio@53f8c000 {
+ status = "okay";
+ };
+ gpio@53f90000 {
+ status = "okay";
+ };
+ usb@53f80000 /* OTG */ {
+ status = "okay";
+ };
+ usb@53f80200 /* Host 1 */ {
+ status = "okay";
+ };
+ wdog@53f98000 {
+ status = "okay";
+ };
+ };
+ aips@60000000 {
+ ethernet@63fec000 {
+ status = "okay";
+ phy-mode = "rmii";
+ };
+ i2c@63fc4000 {
+ status = "okay";
+ };
+ i2c@63fc8000 {
+ status = "okay";
+ };
+ audmux@63fd4000 {
+ status = "okay";
+ };
+ ide@63fe0000 {
+ status = "okay";
+ };
+ };
+ };
+
+ aliases {
+ SSI2 = &SSI2;
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/imx53x.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/imx53x.dtsi
new file mode 100644
index 0000000000..c6a696ede7
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/imx53x.dtsi
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * Copyright (c) 2013 Rui Paulo
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Freescale i.MX535 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,MCIMX535";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x8000>;
+ i-cache-size = <0x8000>;
+ l2-cache-line-size = <32>;
+ l2-cache-line = <0x40000>;
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ localbus@0fffc000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges;
+
+ tzic: tz-interrupt-controller@0fffc000 {
+ compatible = "fsl,imx53-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x0fffc000 0x00004000>;
+ };
+ /*
+ * 40000000 40000FFF 4K Debug ROM
+ * 40001000 40001FFF 4K ETB
+ * 40002000 40002FFF 4K ETM
+ * 40003000 40003FFF 4K TPIU
+ * 40004000 40004FFF 4K CTI0
+ * 40005000 40005FFF 4K CTI1
+ * 40006000 40006FFF 4K CTI2
+ * 40007000 40007FFF 4K CTI3
+ * 40008000 40008FFF 4K ARM Debug Unit
+ *
+ * 0FFFC000 0FFFCFFF 0x4000 TZIC
+ */
+ };
+
+ SOC: soc@50000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ aips@50000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* Required by many devices, so better to stay first */
+ /* 53FD4000 0x4000 CCM */
+ clock@53fd4000 {
+ compatible = "fsl,imx53-ccm";
+ /* 63F80000 0x4000 DPLLIP1 */
+ /* 63F84000 0x4000 DPLLIP2 */
+ /* 63F88000 0x4000 DPLLIP3 */
+ reg = <0x53fd4000 0x4000
+ 0x63F80000 0x4000
+ 0x63F84000 0x4000
+ 0x63F88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <71 72>;
+ status = "disabled";
+ };
+
+ /*
+ * GPIO modules moved up - to have it attached for
+ * drivers which rely on GPIO
+ */
+ /* 53F84000 0x4000 GPIO1 */
+ gpio1: gpio@53f84000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53f84000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <50 51 42 43 44 45 46 47 48 49>;
+ /* TODO: use <> also */
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53F88000 0x4000 GPIO2 */
+ gpio2: gpio@53f88000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53f88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53F8C000 0x4000 GPIO3 */
+ gpio3: gpio@53f8c000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53f8c000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53F90000 0x4000 GPIO4 */
+ gpio4: gpio@53f90000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53f90000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53FDC000 0x4000 GPIO5 */
+ gpio5: gpio@53fdc000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53fdc000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <103 104>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53FE0000 0x4000 GPIO6 */
+ gpio6: gpio@53fe0000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53fe0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <105 106>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 53FE4000 0x4000 GPIO5 */
+ gpio7: gpio@53fe4000 {
+ compatible = "fsl,imx53-gpio";
+ reg = <0x53fe4000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <107 108>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 50004000 0x4000 ESDHC 1 */
+ esdhc@50004000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50004000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <1>;
+ status = "disabled";
+ };
+
+ /* 50008000 0x4000 ESDHC 2 */
+ esdhc@50008000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50008000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <2>;
+ status = "disabled";
+ };
+
+ /* 5000C000 0x4000 UART 3 */
+ uart3: serial@5000c000 {
+ compatible = "fsl,imx53-uart", "fsl,imx-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ /* 50010000 0x4000 eCSPI1 */
+ ecspi@50010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi";
+ reg = <0x50010000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <36>;
+ status = "disabled";
+ };
+
+ /* 50014000 0x4000 SSI2 irq30 */
+ SSI2: ssi@50014000 {
+ compatible = "fsl,imx53-ssi";
+ reg = <0x50014000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <30>;
+ status = "disabled";
+ };
+
+ /* 50020000 0x4000 ESDHC 3 */
+ esdhc@50020000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50020000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ /* 50024000 0x4000 ESDHC 4 */
+ esdhc@50024000 {
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50024000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <4>;
+ status = "disabled";
+ };
+
+ /* 50028000 0x4000 SPDIF */
+ /* 91 SPDIF */
+
+ pata@50030000 {
+ compatible = "fsl,imx53-ata";
+ reg = <0x50030000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <70>;
+ status = "disabled";
+ };
+
+ /* 50034000 0x4000 SLM */
+ /* 50038000 0x4000 HSI2C */
+ /* 64 HS-I2C */
+ /* 5003C000 0x4000 SPBA */
+ };
+
+ usbphy0: usbphy@0 {
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usbphy1: usbphy@1 {
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usbotg: usb@53f80000 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80000 0x0200>;
+ interrupts = <18>;
+ fsl,usbphy = <&usbphy0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@53f80200 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80200 0x0200>;
+ interrupts = <14>;
+ fsl,usbphy = <&usbphy1>;
+ status = "disabled";
+ };
+
+ usbh2: usb@53f80400 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80400 0x0200>;
+ interrupts = <16>;
+ status = "disabled";
+ };
+
+ usbh3: usb@53f80600 {
+ compatible = "fsl,imx53-usb", "fsl,imx27-usb";
+ reg = <0x53f80600 0x0200>;
+ interrupts = <17>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@53f80800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx53-usbmisc";
+ reg = <0x53f80800 0x200>;
+ };
+
+ /* 53F98000 0x4000 WDOG1 */
+ wdog@53f98000 {
+ compatible = "fsl,imx53-wdt";
+ reg = <0x53f98000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <58>;
+ status = "disabled";
+ };
+
+ /* 53F9C000 0x4000 WDOG2 (TZ) */
+ wdog@53f9c000 {
+ compatible = "fsl,imx53-wdt";
+ reg = <0x53f9c000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <59>;
+ status = "disabled";
+ };
+
+ /* 53F94000 0x4000 KPP */
+ keyboard@53f94000 {
+ compatible = "fsl,imx53-kpp";
+ reg = <0x53f94000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <60>;
+ status = "disabled";
+ };
+
+ /* 53FA0000 0x4000 GPT */
+ timer@53fa0000 {
+ compatible = "fsl,imx53-gpt";
+ reg = <0x53fa0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <39>;
+ status = "disabled";
+ };
+
+ /* 53FA4000 0x4000 SRTC */
+
+ rtc@53fa4000 {
+ compatible = "fsl,imx53-srtc";
+ reg = <0x53fa4000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <24 25>;
+ status = "disabled";
+ };
+
+ /* 53FA8000 0x4000 IOMUXC */
+ iomux@53fa8000 {
+ compatible = "fsl,imx53-iomux";
+ reg = <0x53fa8000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <7>;
+ };
+
+ /* 53FAC000 0x4000 EPIT1 */
+ epit1: timer@53fac000 {
+ compatible = "fsl,imx53-epit";
+ reg = <0x53fac000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <40>;
+ status = "disabled";
+ };
+
+ /* 53FB0000 0x4000 EPIT2 */
+ epit2: timer@53fb0000 {
+ compatible = "fsl,imx53-epit";
+ reg = <0x53fb0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <41>;
+ status = "disabled";
+ };
+
+ /* 53FB4000 0x4000 PWM1 */
+ pwm@53fb4000 {
+ compatible = "fsl,imx53-pwm";
+ reg = <0x53fb4000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <61>;
+ status = "disabled";
+ };
+
+ /* 53FB8000 0x4000 PWM2 */
+ pwm@53fb8000 {
+ compatible = "fsl,imx53-pwm";
+ reg = <0x53fb8000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <94>;
+ status = "disabled";
+ };
+
+ /* 53FBC000 0x4000 UART 1 */
+ uart1: serial@53fbc000 {
+ compatible = "fsl,imx53-uart", "fsl,imx-uart";
+ reg = <0x53fbc000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ /* 53FC0000 0x4000 UART 2 */
+ uart2: serial@53fc0000 {
+ compatible = "fsl,imx53-uart", "fsl,imx-uart";
+ reg = <0x53fc0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ /* 53FF0000 0x4000 UART 4 */
+ uart4: serial@53ff0000 {
+ compatible = "fsl,imx53-uart", "fsl,imx-uart";
+ reg = <0x53ff0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <13>;
+ status = "disabled";
+ };
+
+ /* 53FD0000 0x4000 SRC */
+ reset@53fd0000 {
+ compatible = "fsl,imx53-src";
+ reg = <0x53fd0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <75>;
+ status = "disabled";
+ };
+ /* 53FD8000 0x4000 GPC */
+ power@53fd8000 {
+ compatible = "fsl,imx53-gpc";
+ reg = <0x53fd8000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <73 74>;
+ status = "disabled";
+ };
+ i2c@53fec000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c",
+ "fsl,imx-i2c";
+ reg = <0x53fec000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <64>;
+ status = "disabled";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 63F90000 0x4000 UART 5 */
+ uart5: serial@63f90000 {
+ compatible = "fsl,imx53-uart", "fsl,imx-uart";
+ reg = <0x63f90000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ /* 63F94000 0x4000 AHBMAX */
+ /* 63F98000 0x4000 IIM */
+ /*
+ * 69 IIM Interrupt request to the processor.
+ * Indicates to the processor that program or
+ * explicit.
+ */
+ /* 63F9C000 0x4000 CSU */
+ /*
+ * 27 CSU Interrupt Request 1. Indicates to the
+ * processor that one or more alarm inputs were.
+ */
+
+ /* 63FA0000 0x4000 TIGERP_PLATFORM_NE_32K_256K */
+ /* irq76 Neon Monitor Interrupt */
+ /* irq77 Performance Unit Interrupt */
+ /* irq78 CTI IRQ */
+ /* irq79 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq80 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq89 Debug Interrupt, Cross-Trigger Interface 2 */
+ /* irq98 Debug Interrupt, Cross-Trigger Interface 3 */
+
+ /* 63FA4000 0x4000 OWIRE irq88 */
+ /* 63FA8000 0x4000 FIRI irq93 */
+ /* 63FAC000 0x4000 eCSPI2 */
+ ecspi@63fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi";
+ reg = <0x63fac000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <37>;
+ status = "disabled";
+ };
+
+ /* 63FB0000 0x4000 SDMA */
+ sdma@63fb0000 {
+ compatible = "fsl,imx53-sdma";
+ reg = <0x63fb0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <6>;
+ };
+
+ /* 63FB4000 0x4000 SCC */
+ /* 21 SCC Security Monitor High Priority Interrupt. */
+ /* 22 SCC Secure (TrustZone) Interrupt. */
+ /* 23 SCC Regular (Non-Secure) Interrupt. */
+
+ /* 63FB8000 0x4000 ROMCP */
+ /* 63FBC000 0x4000 RTIC */
+ /*
+ * 26 RTIC RTIC (Trust Zone) Interrupt Request.
+ * Indicates that the RTIC has completed hashing the
+ */
+
+ /* 63FC0000 0x4000 CSPI */
+ cspi@63fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-cspi";
+ reg = <0x63fc0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <38>;
+ status = "disabled";
+ };
+
+ /* 63FC4000 0x4000 I2C2 */
+ i2c@63fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x63fc4000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <63>;
+ status = "disabled";
+ };
+
+ /* 63FC8000 0x4000 I2C1 */
+ i2c@63fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x63fc8000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <62>;
+ status = "disabled";
+ };
+
+ /* 63FCC000 0x4000 SSI1 */
+ /* 29 SSI1 SSI-1 Interrupt Request */
+ SSI1: ssi@63fcc000 {
+ compatible = "fsl,imx53-ssi";
+ reg = <0x63fcc000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ /* 63FD0000 0x4000 AUDMUX */
+ audmux@63fd4000 {
+ compatible = "fsl,imx53-audmux";
+ reg = <0x63fd4000 0x4000>;
+ status = "disabled";
+ };
+
+ /* 63FD8000 0x4000 EXTMC */
+ /* 8 EXTMC (NFC) */
+ /* 15 EXTMC */
+ /* 97 EXTMC Boot sequence completed interrupt */
+ /*
+ * 101 EMI Indicates all pages have been transferred
+ * to NFC during an auto program operation.
+ */
+
+ /* 83FE4000 0x4000 SIM */
+ /* 67 SIM intr composed of oef, xte, sdi1, and sdi0 */
+ /* 68 SIM intr composed of tc, etc, tfe, and rdrf */
+
+ /* 63FD_C000 0x4000 apb2ip_pl301_2x2 */
+ /* 63FE_0000 0x4000 apb2ip_pl301_4x1 */
+ /* 63FE4000 0x4000 MLB */
+ /* 63FE8000 0x4000 SSI3 */
+ /* 96 SSI3 SSI-3 Interrupt Request */
+ SSI3: ssi@63fe8000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x63fe8000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <96>;
+ status = "disabled";
+ };
+
+ /* 63FEC000 0x4000 FEC */
+ ethernet@63fec000 {
+ compatible = "fsl,imx53-fec";
+ reg = <0x63fec000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <87>;
+ status = "disabled";
+ };
+
+ /* 63FF0000 0x4000 TVE */
+ /* 92 TVE */
+ /* 63FF4000 0x4000 VPU */
+ /* 9 VPU */
+ /* 100 VPU Idle interrupt from VPU */
+
+ /* 63FF8000 0x4000 SAHARA */
+ /* 19 SAHARA SAHARA host 0 (TrustZone) Intr */
+ /* 20 SAHARA SAHARA host 1 (non-TrustZone) Intr */
+ };
+ };
+
+ localbus@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ sata@10000000 {
+ compatible = "fsl,imx53-ata";
+ reg = <0x10000000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <28>;
+ status = "disabled";
+ };
+
+ vga: ipu3@1E000000 {
+ compatible = "fsl,ipu3";
+ reg = <
+ 0x1E000000 0x08000 /* CM */
+ 0x1E008000 0x08000 /* IDMAC */
+ 0x1E018000 0x08000 /* DP */
+ 0x1E020000 0x08000 /* IC */
+ 0x1E028000 0x08000 /* IRT */
+ 0x1E030000 0x08000 /* CSI0 */
+ 0x1E038000 0x08000 /* CSI1 */
+ 0x1E040000 0x08000 /* DI0 */
+ 0x1E048000 0x08000 /* DI1 */
+ 0x1E050000 0x08000 /* SMFC */
+ 0x1E058000 0x08000 /* DC */
+ 0x1E060000 0x08000 /* DMFC */
+ 0x1E068000 0x08000 /* VDI */
+ 0x1F000000 0x20000 /* CPMEM */
+ 0x1F020000 0x20000 /* LUT */
+ 0x1F040000 0x20000 /* SRM */
+ 0x1F060000 0x20000 /* TPM */
+ 0x1F080000 0x20000 /* DCTMPL */
+ >;
+ interrupt-parent = <&tzic>;
+ interrupts = <
+ 10 /* IPUEX Error */
+ 11 /* IPUEX Sync */
+ >;
+ status = "disabled";
+ };
+ };
+};
+
+/*
+
+TODO: Not mapped interrupts
+
+5 DAP
+84 GPU2D (OpenVG) general interrupt
+85 GPU2D (OpenVG) busy signal (for S/W power gating feasibility)
+12 GPU3D
+102 GPU3D Idle interrupt from GPU3D (for S/W power gating)
+90 SJC
+*/
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/imx6.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/imx6.dtsi
new file mode 100644
index 0000000000..db8b44e53b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/imx6.dtsi
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Freescale i.MX6 Common Device Tree Source.
+ * There are enough differences between the Solo, Dual, Quad, and *-lite
+ * flavors of this SoC that eventually we will need a finer-grained breakdown
+ * of some of this stuff. For now this file works for all of them. I think.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,MCIMX6";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x8000>;
+ i-cache-size = <0x8000>;
+ /* TODO: describe L2 cache also */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: soc@00000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ ranges = <0x00000000 0x00000000 0x10000000>;
+
+ gic: generic-interrupt-controller@00a00100 {
+ compatible = "arm,gic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x00a01000 0x00001000
+ 0x00a00100 0x00000100>;
+ };
+
+ mp_tmr0@00a00200 {
+ compatible = "arm,mpcore-timers";
+ reg = <0x00a00200 0x100
+ 0x00a00600 0x100>;
+ interrupts = <27 29>;
+ interrupt-parent = <&gic>;
+ };
+
+ l2-cache@00a02000 {
+ compatible = "arm,pl310-cache", "arm,pl310";
+ reg = <0xa02000 0x1000>;
+ interrupts = <124>;
+ cache-level = <0x2>;
+ interrupt-parent = < &gic >;
+ };
+
+ aips@02000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ reg = <0x02000000 0x00100000>;
+ ranges;
+
+ /* Required by many devices, so better to stay first */
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6q-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <119 120>;
+ };
+
+ /* System Reset Controller */
+ src: src@4006E000 {
+ compatible = "fsl,imx6-src";
+ reg = <0x020D8000 0x100>;
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6q-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <34>;
+ status = "disabled";
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6q-anatop";
+ reg = <0x020c8000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <49>;
+ };
+
+ gpt: timer@02098000 {
+ compatible = "fsl,imx6q-gpt", "fsl,imx51-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <87>;
+ };
+
+ iomux@020e0000 {
+ compatible = "fsl,imx6q-iomuxc";
+ reg = <0x020e0000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <32>;
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = < 98 99 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = < 100 101 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = < 102 103 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = < 104 105 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = < 106 107 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio6: gpio@020b0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b0000 0x4000>;
+ interrupts = < 108 109 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio7: gpio@020b4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b4000 0x4000>;
+ interrupts = < 110 111 >;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6q-uart";
+ reg = <0x02020000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <58>;
+ clock-frequency = <80000000>;
+ status = "disabled";
+ };
+
+ uart2: serial@021e8000 {
+ compatible = "fsl,imx6q-uart";
+ reg = <0x021e8000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <59>;
+ clock-frequency = <80000000>;
+ status = "disabled";
+ };
+
+ uart3: serial@021ec000 {
+ compatible = "fsl,imx6q-uart";
+ reg = <0x021ec000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <60>;
+ clock-frequency = <80000000>;
+ status = "disabled";
+ };
+
+ uart4: serial@021f0000 {
+ compatible = "fsl,imx6q-uart";
+ reg = <0x021f0000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <61>;
+ clock-frequency = <80000000>;
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6q-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <62>;
+ clock-frequency = <80000000>;
+ status = "disabled";
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <44>;
+ status = "disabled";
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@02008000 {
+ compatible = "fsl,imx6q-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = < 63 >;
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200C000 {
+ compatible = "fsl,imx6q-ecspi";
+ reg = <0x0200C000 0x4000>;
+ interrupts = < 64 >;
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ compatible = "fsl,imx6q-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = < 65 >;
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ compatible = "fsl,imx6q-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = < 66 >;
+ status = "disabled";
+ };
+
+ ecspi5: ecspi@02018000 {
+ compatible = "fsl,imx6q-ecspi";
+ reg = <0x02018000 0x4000>;
+ interrupts = < 67 >;
+ status = "disabled";
+ };
+
+ ssi1: ssi@02028000 {
+ compatible = "fsl,imx6q-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = < 78 >;
+ dmas = <&sdma 37 1 0>,
+ <&sdma 38 1 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ssi2: ssi@0202C000 {
+ compatible = "fsl,imx6q-ssi";
+ reg = <0x0202C000 0x4000>;
+ interrupts = < 79 >;
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ compatible = "fsl,imx6q-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = < 80 >;
+ status = "disabled";
+ };
+ };
+
+ aips@02100000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ reg = <0x02100000 0x00100000>;
+ ranges;
+
+ i2c1: i2c@021a0000 {
+ compatible = "fsl,imx6q-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = < 68 >;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ compatible = "fsl,imx6q-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = < 69 >;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021ac000 {
+ compatible = "fsl,imx6q-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = < 70 >;
+ status = "disabled";
+ };
+
+ fec1: ethernet@02188000 {
+ compatible = "fsl,imx6q-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts = <150 151>;
+ status = "disabled";
+ };
+
+ usbotg1: usb@02184000 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <75>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@02184200 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <72>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ status = "disabled";
+ };
+
+ usbh2: usb@02184400 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184400 0x200>;
+ interrupts = <73>;
+ fsl,usbmisc = <&usbmisc 2>;
+ status = "disabled";
+ };
+
+ usbh3: usb@02184600 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184600 0x200>;
+ interrupts = <74>;
+ fsl,usbmisc = <&usbmisc 3>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ // Not disabled on purpose.
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <54>;
+ cd-gpios = <&gpio1 2 0>;
+ bus-width = <0x4>;
+ status ="disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <55>;
+ non-removable;
+ bus-width = <0x4>;
+ status ="disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <56>;
+ cd-gpios = <&gpio3 9 0>;
+ bus-width = <0x4>;
+ status ="disabled";
+ };
+
+ usdhc4: usdhc@0219c000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x0219c000 0x4000>;
+ interrupt-parent = <&gic>;
+ interrupts = <57>;
+ bus-width = <0x4>;
+ status ="disabled";
+ };
+
+ ocotp0: ocotp@021bc000 {
+ compatible = "fsl,imx6q-ocotp";
+ reg = <0x021bc000 0x4000>;
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6q-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/meson3.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/meson3.dtsi
new file mode 100644
index 0000000000..444e3cf62e
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/meson3.dtsi
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The basic single core aml8726 (aka meson) uses an Amlogic interrupt
+ * controller, however meson.dtsi specifies GIC (which is present on
+ * the multicore aml8726) so we need to override things here.
+ */
+
+/include/ "meson.dtsi"
+
+/ {
+ model = "Amlogic Meson3 SoC";
+ compatible = "amlogic,meson3";
+
+ interrupt-parent = <&pic>;
+
+ pic: pic@c1109a40 {
+ device_type = "interrupt-controller";
+ compatible = "amlogic,aml8726-pic";
+ reg = <0xc1109a40 128>; /* cbus 0x2690 */
+
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+ };
+
+ clk81: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+
+&gic {
+ status = "disabled";
+};
+
+&L2 {
+ interrupts = <0 61 1>;
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/meson8b.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/meson8b.dtsi
new file mode 100644
index 0000000000..c76a01a4fa
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/meson8b.dtsi
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/include/ "meson.dtsi"
+
+/ {
+ model = "Amlogic Meson8b SoC";
+ compatible = "amlogic,meson8b";
+
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x201>;
+ };
+
+ cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x202>;
+ };
+
+ cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x203>;
+ };
+ };
+
+ clk81: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+
+&L2 {
+ interrupts = <0 143 1>;
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/odroidc1.dts b/usr/src/boot/sys/boot/fdt/dts/arm/odroidc1.dts
new file mode 100644
index 0000000000..2d15a0900e
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/odroidc1.dts
@@ -0,0 +1,396 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The ordering of certain devices is significant (e.g. usb depends on
+ * usb-phy which depends on gpio, also the timer should appear early on
+ * to provide a reasonably accurate DELAY implementation).
+ *
+ * Both usb-phys devices must be configured to prevent the usb controller
+ * from hanging during initialization.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x7900000 0x00600000; /* 6MB frame buffer */
+
+#include "meson8b.dtsi"
+
+/ {
+ model = "hardkernel,odroid-c1";
+ compatible = "hardkernel,odroid-c1", "amlogic,s805";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &soc;
+ screen = &screen;
+ uart0 = &uart_AO;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB RAM */
+ };
+
+ soc: soc {
+ device_type = "soc";
+ bus-frequency = <0>;
+
+ scu: scu@c4300000 {
+ compatible = "arm,cortex-a5-scu";
+ reg = <0xc4300000 0x1000>;
+ };
+
+ cpuconfig: cpuconfig@d901ff80 {
+ compatible = "amlogic,aml8726-cpuconfig";
+ reg = <0xd901ff80 16>;
+ };
+
+ ccm@c1104140 {
+ compatible = "amlogic,aml8726-ccm";
+ reg = <0xc1104140 20>; /* cbus 0x1050 */
+
+ functions = "ethernet", "i2c", "rng", "sdio", "sdxc",
+ "uart-a", "uart-b", "uart-c",
+ "usb-a", "usb-b";
+ };
+
+ pinctrl@c11080b0 {
+ compatible = "amlogic,aml8726-pinctrl";
+ reg = <0xc11080b0 40>, /* mux */
+ <0xc11080e8 24>, /* pu/pd */
+ <0xc1108120 24>, /* pull enable */
+ <0xc8100014 4>, /* ao mux */
+ <0xc810002c 4>, /* ao pu/pd */
+ <0xc810002c 4>; /* ao pull enable */
+
+ /*
+ * Currently only pin muxing that deviates
+ * from the power on default of gpio is
+ * specified here.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_uartao &pins_ethernet &pins_hdmi>;
+
+ pins_ethernet: ethernet {
+ amlogic,pins = "ref_clk",
+ "tx_clk", "tx_en",
+ "tx_d0", "tx_d1",
+ "tx_d2", "tx_d3",
+ "rx_clk", "rx_dv",
+ "rx_d0", "rx_d1",
+ "rx_d2", "rx_d3",
+ "mdc", "mdio";
+ amlogic,function = "ethernet";
+ };
+
+ pins_hdmi: hdmi {
+ amlogic,pins = "cec", "hpd",
+ "scl", "sda";
+ amlogic,function = "hdmi";
+ };
+
+ pins_sdio_b: sdio_b {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdio-b";
+ amlogic,pull = "up";
+ };
+
+ pins_sdxc_b: sdxc_b {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdxc-b";
+ amlogic,pull = "up";
+ };
+
+ pins_sdio_c: sdio_c {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdio-c";
+ amlogic,pull = "up";
+ };
+
+ pins_sdxc_c: sdxc_c {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3",
+ "d4", "d5",
+ "d6", "d7";
+ amlogic,function = "sdxc-c";
+ amlogic,pull = "up";
+ };
+
+ pins_i2c_a: i2c_a {
+ amlogic,pins = "scl", "sda";
+ amlogic,function = "i2c-a";
+ };
+
+ pins_i2c_b: i2c_b {
+ amlogic,pins = "scl", "sda";
+ amlogic,function = "i2c-b";
+ };
+
+ pins_uarta: uarta {
+ amlogic,pins = "tx", "rx", "cts", "rts";
+ amlogic,function = "uart-a";
+ };
+
+ pins_uartb: uartb {
+
+ /*
+ * gpiox18 appears to have special
+ * meaning to the bootloader making
+ * hardware handshaking unavailable.
+ */
+
+ amlogic,pins = "tx", "rx";
+ amlogic,function = "uart-b";
+ };
+
+ pins_uartc: uartc {
+ amlogic,pins = "tx", "rx", "cts", "rts";
+ amlogic,function = "uart-c";
+ };
+
+ pins_uartao: uartao {
+ amlogic,pins = "tx", "rx";
+ amlogic,function = "uart-ao";
+ };
+ };
+
+ rtc@c8100740 {
+ compatible = "amlogic,aml8726-rtc";
+ reg = <0xc8100740 20>; /* aobus 0x1d0 */
+ interrupts = <0 72 1>;
+ };
+
+ clkmsr: clkmsr@c1108758 {
+ compatible = "amlogic,aml8726-clkmsr";
+ reg = <0xc1108758 16>; /* cbus 0x21d6 */
+
+ clocks = <&clk81>;
+ };
+
+ gpioao: gpio@c8100024 {
+ /* gpio unit 7 */
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc8100024 4>, /* oen aobus 0x9 */
+ <0xc8100024 4>, /* out */
+ <0xc8100028 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <14>;
+ };
+
+ gpio3: gpio@c1108054 {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc1108054 4>, /* oen cbus 0x2015 */
+ <0xc1108058 4>, /* out */
+ <0xc110805c 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <32>;
+ };
+
+ gpio5: gpio@c110806c {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc110806c 4>, /* oen cbus 0x201b */
+ <0xc1108070 4>, /* out */
+ <0xc1108074 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <32>;
+ };
+
+ mmc@c1108c20 {
+ compatible = "amlogic,aml8726-mmc";
+ reg = <0xc1108c20 32>; /* cbus 0x2308 */
+ interrupts = <0 28 1>;
+
+ clocks = <&clk81>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_sdio_b>;
+
+ /*
+ * Ordering is significant.
+ *
+ * mmc-vselect low sets first voltage
+ * mmc-vselect high sets second voltage
+ *
+ * If mmc-vselect is not present, then
+ * only one voltage should be specified.
+ */
+ mmc-voltages = "3.3", "1.8";
+ mmc-vselect = <&gpioao 3>; /* gpioao_3 */
+
+ mmc-pwr-en = <&gpio5 31 0>; /* card_8 */
+ ins-detect = <&gpio5 29 0>; /* card_6 */
+ };
+
+ sdxc@c1108e00 {
+ compatible = "amlogic,aml8726-sdxc-m8";
+ clock-frequency = <1275000000>;
+ reg = <0xc1108e00 60>; /* cbus 0x2380 */
+ interrupts = <0 78 1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_sdxc_c>;
+
+ mmc-voltages = "1.8";
+
+ mmc-rst = <&gpio3 9 0>; /* boot_9 emmc-rst */
+ };
+
+ rng@c1108100 {
+ compatible = "amlogic,aml8726-rng";
+ reg = <0xc1108100 8>; /* cbus 0x2040 */
+ };
+
+ usb-phy@c1108800 {
+ /* usb-a phy */
+ compatible = "amlogic,aml8726-m8-usb-phy";
+ reg = <0xc1108800 32>; /* cbus 0x2200 */
+
+ usb-pwr-en = <&gpioao 5 1>; /* gpioao_5 vbus */
+ };
+
+ usb-phy@c1108820 {
+ /* usb-b phy */
+ compatible = "amlogic,aml8726-m8-usb-phy";
+ reg = <0xc1108820 32>; /* cbus 0x2208 */
+
+ force-aca = "true";
+ usb-hub-rst = <&gpioao 4 0>; /* gpioao_4 hub-rst */
+ };
+
+ usb@c9040000 {
+ /* usb-a */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
+ interrupts = <0 30 4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+ };
+
+ usb@c90c0000 {
+ /* usb-b */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
+ interrupts = <0 31 4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+ };
+
+ eth@c9410000 {
+ /* ethernet */
+ compatible = "amlogic,meson6-dwmac";
+ reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
+ interrupts = <0 8 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth-phy-rst = <&gpio3 23 0>; /* gpioh_4 phy-rst */
+ };
+
+ screen: fb@c8006020 {
+ device_type = "display";
+ compatible = "amlogic,aml8726-fb";
+ reg = <0xc8006048 12>, /* CANVAS */
+ <0xc1106800 1024>, /* VIU */
+ <0xc1107400 1024>; /* VPP */
+ interrupts = <0 2 1>,
+ <0 3 1>,
+ <0 12 1>,
+ <0 13 1>;
+
+ address = <0x7900000>; /* match memreserve */
+ width = <720>;
+ height = <480>;
+ depth = <24>;
+ linebytes = <2160>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ sys_led {
+ gpios = <&gpioao 13>; /* gpioao_13 sys_led */
+ label = "sys_led";
+ };
+ };
+
+ chosen {
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+};
+
+&clk81 {
+ clock-frequency = <0>;
+};
+
+&uart_AO {
+ status = "okay";
+ current-speed = <115200>;
+};
+
+&uart_A {
+ status = "okay";
+};
+
+&uart_B {
+ status = "okay";
+};
+
+&uart_C {
+ status = "okay";
+};
+
+&i2c_A {
+ status = "okay";
+};
+
+&i2c_B {
+ status = "okay";
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts b/usr/src/boot/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts
new file mode 100644
index 0000000000..ffe0777b5c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sun7i-a20-olimex-som-evb.dts"
+
+/ {
+ soc@01c00000 {
+ ccm@01c20000 {
+ compatible = "allwinner,sun4i-ccm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c20000 0x400 >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/olinuxino-lime.dts b/usr/src/boot/sys/boot/fdt/dts/arm/olinuxino-lime.dts
new file mode 100644
index 0000000000..b965788991
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/olinuxino-lime.dts
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sun4i-a10-olinuxino-lime.dts"
+
+/ {
+ soc@01c00000 {
+ ccm@01c20000 {
+ compatible = "allwinner,sun4i-ccm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c20000 0x400 >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-common.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-common.dtsi
new file mode 100644
index 0000000000..f8d2a0814b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-common.dtsi
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+&mmc1 {
+ non-removable; /* XXX need real solution */
+};
+
+&mmc5 {
+ status = "disabled";
+};
+
+/ {
+ ocp {
+ global-timer@48240600 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x48240200 0x20>;
+ interrupts = <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ elm: elm@48078000 {
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ chosen {
+ stdin = "serial2";
+ stdout = "serial2";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-es.dts b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-es.dts
new file mode 100644
index 0000000000..6c3f4b58e4
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard-es.dts
@@ -0,0 +1,31 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#include "omap4-panda-es.dts"
+#include "pandaboard-common.dtsi"
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard.dts b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard.dts
new file mode 100644
index 0000000000..b25ca634e2
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/pandaboard.dts
@@ -0,0 +1,31 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#include "omap4-panda.dts"
+#include "pandaboard-common.dtsi"
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts
new file mode 100644
index 0000000000..643f5d0ea8
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "rk3188.dtsi"
+
+/ {
+ model = "Radxa RadxaRock Lite";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x60000000 0x40000000 >; /* 1GB RAM */
+ };
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: rk3188 {
+
+ uart2: serial@20064000 {
+ status = "okay";
+ };
+
+ mmc@10214000 {
+ status = "okay";
+ };
+
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = &uart2;
+ stdout = &uart2;
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa.dts b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa.dts
new file mode 100644
index 0000000000..c3740a0a5a
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188-radxa.dts
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "rk3188.dtsi"
+
+/ {
+ model = "Radxa RadxaRock";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x60000000 0x80000000 >; /* 2GB RAM */
+ };
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: rk3188 {
+
+ uart2: serial@20064000 {
+ status = "okay";
+ };
+
+ mmc@10214000 {
+ status = "okay";
+ };
+
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = &uart2;
+ stdout = &uart2;
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/rk3188.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188.dtsi
new file mode 100644
index 0000000000..66284aa184
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/rk3188.dtsi
@@ -0,0 +1,254 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ compatible = "rockchip,rk3188";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: rk3188 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@1013d000 {
+ compatible = "arm,gic";
+ reg = <0x1013d000 0x1000>, /* Distributor Registers */
+ <0x1013c100 0x0100>; /* CPU Interface Registers */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ pmu@20004000 {
+ compatible = "rockchip,rk30xx-pmu";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x20004000 0x100>;
+ };
+
+ grf@20008000 {
+ compatible = "rockchip,rk30xx-grf";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x20008000 0x2000 >;
+ };
+
+ mp_tmr@1013c600 {
+ compatible = "arm,mpcore-timers";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = < 148500000 >;
+ reg = <0x1013c200 0x100>, /* Global Timer Regs */
+ <0x1013c600 0x20>; /* Private Timer Regs */
+ interrupts = < 27 29 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ timer@20038000 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038000 0x20>;
+ interrupts = <76>;
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038020 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038020 0x20>;
+ interrupts = <77>;
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038060 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038060 0x20>;
+ interrupts = <91>;
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038080 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038080 0x20>;
+ interrupts = <92>;
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ timer@200380a0 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x200380a0 0x20>;
+ interrupts = <96>;
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ watchdog@2004c000 {
+ compatible = "rockchip,rk30xx-wdt";
+ reg = <0x2004c000 0x100>;
+ clock-frequency = < 66000000 >;
+ };
+
+ gpio0: gpio@2000a000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2000a000 0x100>;
+ interrupts = <86>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio1: gpio@2003c000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2003c000 0x100>;
+ interrupts = <87>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio2: gpio@2003e000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2003e000 0x100>;
+ interrupts = <88>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio3: gpio@20080000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20080000 0x100>;
+ interrupts = <89>;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb0: usb@10180000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <48>;
+ interrupt-parent = <&GIC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb1: usb@101c0000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = < 49 >;
+ interrupt-parent = <&GIC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpios = <&gpio0 3 2 2>;
+ };
+
+ uart0: serial@10124000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10124000 0x400>;
+ reg-shift = <2>;
+ interrupts = <66>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart1: serial@10126000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10126000 0x400>;
+ reg-shift = <2>;
+ interrupts = <67>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart2: serial@20064000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20064000 0x400>;
+ reg-shift = <2>;
+ interrupts = <68>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart3: serial@20068000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20068000 0x400>;
+ reg-shift = <2>;
+ interrupts = <69>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ mmc@10214000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10214000 0x1000>;
+ interrupts = <55>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-frequency = <48000000>; /* TODO: verify freq */
+ fifo-depth = <0x40>;
+ num-slots = <1>;
+ status = "disabled";
+ };
+
+ mmc@10218000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10218000 0x1000>;
+ interrupts = <56>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-frequency = <48000000>; /* TODO: verify freq */
+ fifo-depth = <0x40>;
+ num-slots = <1>;
+ status = "disabled";
+ };
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/rpi.dts b/usr/src/boot/sys/boot/fdt/dts/arm/rpi.dts
new file mode 100644
index 0000000000..548f888b2b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/rpi.dts
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/dts-v1/;
+
+/include/ "bcm2835.dtsi"
+
+/ {
+ model = "Raspberry Pi (BCM2835)";
+ compatible = "raspberrypi,model-a", "raspberrypi,model-b",
+ "broadcom,bcm2835-vc", "broadcom,bcm2708-vc";
+
+ memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,1176jzf-s";
+ device_type = "cpu";
+ reg = <0>; /* CPU ID=0 */
+ clock-frequency = <700000000>; /* 700MHz */
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x8000000>; /* 128MB, Set by VideoCore */
+
+ };
+
+ system {
+ revision = <0>; /* Set by VideoCore */
+ serial = <0 0>; /* Set by VideoCore */
+ };
+
+ axi {
+ gpio: gpio {
+ /* BSC0 */
+ pins_bsc0_a: bsc0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc0_b: bsc0_b {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc0_c: bsc0_c {
+ broadcom,function = "ALT1";
+ };
+
+ /* BSC1 */
+ pins_bsc1_a: bsc1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc1_b: bsc1_b {
+ broadcom,function = "ALT2";
+ };
+
+ /* GPCLK0 */
+ pins_gpclk0_a: gpclk0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk0_b: gpclk0_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_gpclk0_c: gpclk0_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk0_d: gpclk0_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* GPCLK1 */
+ pins_gpclk1_a: gpclk1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk1_b: gpclk1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_gpclk1_c: gpclk1_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk1_d: gpclk1_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* GPCLK2 */
+ pins_gpclk2_a: gpclk2_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk2_b: gpclk2_b {
+ broadcom,function = "ALT0";
+ };
+
+ /* SPI0 */
+ pins_spi0_a: spi0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_spi0_b: spi0_b {
+ broadcom,function = "ALT0";
+ };
+
+ /* PWM */
+ pins_pwm0_a: pwm0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm0_b: pwm0_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_pwm0_c: pwm0_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_a: pwm1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_b: pwm1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_pwm1_c: pwm1_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_d: pwm1_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* UART0 */
+ pins_uart0_a: uart0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_uart0_b: uart0_b {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_c: uart0_c {
+ broadcom,function = "ALT2";
+ };
+
+ pins_uart0_fc_a: uart0_fc_a {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_fc_b: uart0_fc_b {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_fc_c: uart0_fc_c {
+ broadcom,function = "ALT2";
+ };
+
+ /* PCM */
+ pins_pcm_a: pcm_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pcm_b: pcm_b {
+ broadcom,function = "ALT2";
+ };
+
+ /* Secondary Address Bus */
+ pins_sm_addr_a: sm_addr_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_addr_b: sm_addr_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_ctl_a: sm_ctl_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_ctl_b: sm_ctl_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_8bit_a: sm_data_8bit_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_8bit_b: sm_data_8bit_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_16bit: sm_data_16bit {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_18bit: sm_data_18bit {
+ broadcom,function = "ALT1";
+ };
+
+ /* BSCSL */
+ pins_bscsl: bscsl {
+ broadcom,function = "ALT3";
+ };
+
+ /* SPISL */
+ pins_spisl: spisl {
+ broadcom,function = "ALT3";
+ };
+
+ /* SPI1 */
+ pins_spi1: spi1 {
+ broadcom,function = "ALT4";
+ };
+
+ /* UART1 */
+ pins_uart1_a: uart1_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_b: uart1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_c: uart1_c {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_a: uart1_fc_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_b: uart1_fc_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_c: uart1_fc_c {
+ broadcom,function = "ALT5";
+ };
+
+ /* SPI2 */
+ pins_spi2: spi2 {
+ broadcom,function = "ALT4";
+ };
+
+ /* ARM JTAG */
+ pins_arm_jtag_trst: arm_jtag_trst {
+ broadcom,function = "ALT4";
+ };
+
+ pins_arm_jtag_a: arm_jtag_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_arm_jtag_b: arm_jtag_b {
+ broadcom,function = "ALT4";
+ };
+
+ /* Reserved */
+ pins_reserved: reserved {
+ broadcom,function = "ALT3";
+ };
+ };
+ usb {
+ hub {
+ compatible = "usb,hub", "usb,device";
+ reg = <0x00000001>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethernet {
+ compatible = "net,ethernet",
+ "usb,device";
+ reg = <0x00000001>;
+ mac-address = [00 00 00 00 00 00];
+ };
+ };
+
+ };
+
+
+ };
+
+ display {
+ compatible = "broadcom,bcm2835-fb", "broadcom,bcm2708-fb";
+
+ broadcom,vc-mailbox = <&vc_mbox>;
+ broadcom,vc-channel = <1>;
+
+ broadcom,width = <0>; /* Set by VideoCore */
+ broadcom,height = <0>; /* Set by VideoCore */
+ broadcom,depth = <0>; /* Set by VideoCore */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ok {
+ label = "ok";
+ gpios = <&gpio 16 1>;
+
+ /* Don't change this - it configures
+ * how the led driver determines if
+ * the led is on or off when it loads.
+ */
+ default-state = "keep";
+
+ /* This is the real default state. */
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ power: regulator {
+ compatible = "broadcom,bcm2835-power-mgr",
+ "broadcom,bcm2708-power-mgr",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ broadcom,vc-mailbox = <&vc_mbox>;
+ broadcom,vc-channel = <0>;
+
+ regulator-name = "VideoCore";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on = <1>;
+
+ sd_card_power: regulator@0 {
+ compatible = "broadcom,bcm2835-power-dev",
+ "broadcom,bcm2708-power-dev";
+ reg = <0>;
+
+ vin-supply = <&power>;
+ regulator-name = "SD Card";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ /* This is for the controller itself, not the root port */
+ usb_hcd_power: regulator@3 {
+ compatible = "broadcom,bcm2835-power-dev",
+ "broadcom,bcm2708-power-dev";
+ reg = <3>;
+
+ vin-supply = <&power>;
+ regulator-name = "USB HCD";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ aliases {
+ uart0 = &uart0;
+ };
+
+ chosen {
+ bootargs = ""; /* Set by VideoCore */
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+
+ __overrides__ {
+ cache_line_size = <&vchiq>, "cache-line-size:0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/rpi2.dts b/usr/src/boot/sys/boot/fdt/dts/arm/rpi2.dts
new file mode 100644
index 0000000000..951bca3b47
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/rpi2.dts
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/dts-v1/;
+
+/include/ "bcm2836.dtsi"
+
+/ {
+ model = "Raspberry Pi 2 Model B";
+ compatible = "brcm,bcm2709";
+
+ memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf00>; /* CPU ID=0xf00 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf01>; /* CPU ID=0xf01 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf02>; /* CPU ID=0xf02 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf03>; /* CPU ID=0xf03 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x8000000>; /* 128MB, Set by VideoCore */
+
+ };
+
+ system {
+ revision = <0>; /* Set by VideoCore */
+ serial = <0 0>; /* Set by VideoCore */
+ };
+
+ axi {
+ gpio: gpio {
+ /* BSC0 */
+ pins_bsc0_a: bsc0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc0_b: bsc0_b {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc0_c: bsc0_c {
+ broadcom,function = "ALT1";
+ };
+
+ /* BSC1 */
+ pins_bsc1_a: bsc1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_bsc1_b: bsc1_b {
+ broadcom,function = "ALT2";
+ };
+
+ /* GPCLK0 */
+ pins_gpclk0_a: gpclk0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk0_b: gpclk0_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_gpclk0_c: gpclk0_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk0_d: gpclk0_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* GPCLK1 */
+ pins_gpclk1_a: gpclk1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk1_b: gpclk1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_gpclk1_c: gpclk1_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk1_d: gpclk1_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* GPCLK2 */
+ pins_gpclk2_a: gpclk2_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_gpclk2_b: gpclk2_b {
+ broadcom,function = "ALT0";
+ };
+
+ /* SPI0 */
+ pins_spi0_a: spi0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_spi0_b: spi0_b {
+ broadcom,function = "ALT0";
+ };
+
+ /* PWM */
+ pins_pwm0_a: pwm0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm0_b: pwm0_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_pwm0_c: pwm0_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_a: pwm1_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_b: pwm1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_pwm1_c: pwm1_c {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pwm1_d: pwm1_d {
+ broadcom,function = "ALT0";
+ };
+
+ /* UART0 */
+ pins_uart0_a: uart0_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_uart0_b: uart0_b {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_c: uart0_c {
+ broadcom,function = "ALT2";
+ };
+
+ pins_uart0_fc_a: uart0_fc_a {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_fc_b: uart0_fc_b {
+ broadcom,function = "ALT3";
+ };
+
+ pins_uart0_fc_c: uart0_fc_c {
+ broadcom,function = "ALT2";
+ };
+
+ /* PCM */
+ pins_pcm_a: pcm_a {
+ broadcom,function = "ALT0";
+ };
+
+ pins_pcm_b: pcm_b {
+ broadcom,function = "ALT2";
+ };
+
+ /* Secondary Address Bus */
+ pins_sm_addr_a: sm_addr_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_addr_b: sm_addr_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_ctl_a: sm_ctl_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_ctl_b: sm_ctl_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_8bit_a: sm_data_8bit_a {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_8bit_b: sm_data_8bit_b {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_16bit: sm_data_16bit {
+ broadcom,function = "ALT1";
+ };
+
+ pins_sm_data_18bit: sm_data_18bit {
+ broadcom,function = "ALT1";
+ };
+
+ /* BSCSL */
+ pins_bscsl: bscsl {
+ broadcom,function = "ALT3";
+ };
+
+ /* SPISL */
+ pins_spisl: spisl {
+ broadcom,function = "ALT3";
+ };
+
+ /* SPI1 */
+ pins_spi1: spi1 {
+ broadcom,function = "ALT4";
+ };
+
+ /* UART1 */
+ pins_uart1_a: uart1_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_b: uart1_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_c: uart1_c {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_a: uart1_fc_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_b: uart1_fc_b {
+ broadcom,function = "ALT5";
+ };
+
+ pins_uart1_fc_c: uart1_fc_c {
+ broadcom,function = "ALT5";
+ };
+
+ /* SPI2 */
+ pins_spi2: spi2 {
+ broadcom,function = "ALT4";
+ };
+
+ /* ARM JTAG */
+ pins_arm_jtag_trst: arm_jtag_trst {
+ broadcom,function = "ALT4";
+ };
+
+ pins_arm_jtag_a: arm_jtag_a {
+ broadcom,function = "ALT5";
+ };
+
+ pins_arm_jtag_b: arm_jtag_b {
+ broadcom,function = "ALT4";
+ };
+
+ /* Reserved */
+ pins_reserved: reserved {
+ broadcom,function = "ALT3";
+ };
+ };
+ usb {
+ hub {
+ compatible = "usb,hub", "usb,device";
+ reg = <0x00000001>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethernet {
+ compatible = "net,ethernet",
+ "usb,device";
+ reg = <0x00000001>;
+ mac-address = [00 00 00 00 00 00];
+ };
+ };
+
+ };
+ };
+
+ display {
+ compatible = "broadcom,bcm2835-fb", "broadcom,bcm2708-fb";
+
+ broadcom,vc-mailbox = <&vc_mbox>;
+ broadcom,vc-channel = <1>;
+
+ broadcom,width = <0>; /* Set by VideoCore */
+ broadcom,height = <0>; /* Set by VideoCore */
+ broadcom,depth = <0>; /* Set by VideoCore */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pwr {
+ label = "pwr";
+ gpios = <&gpio 35 0>;
+ };
+
+ act {
+ label = "act";
+ gpios = <&gpio 47 0>;
+ };
+ };
+
+ power: regulator {
+ compatible = "broadcom,bcm2835-power-mgr",
+ "broadcom,bcm2708-power-mgr",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ broadcom,vc-mailbox = <&vc_mbox>;
+ broadcom,vc-channel = <0>;
+
+ regulator-name = "VideoCore";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on = <1>;
+
+ sd_card_power: regulator@0 {
+ compatible = "broadcom,bcm2835-power-dev",
+ "broadcom,bcm2708-power-dev";
+ reg = <0>;
+
+ vin-supply = <&power>;
+ regulator-name = "SD Card";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ /* This is for the controller itself, not the root port */
+ usb_hcd_power: regulator@3 {
+ compatible = "broadcom,bcm2835-power-dev",
+ "broadcom,bcm2708-power-dev";
+ reg = <3>;
+
+ vin-supply = <&power>;
+ regulator-name = "USB HCD";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+ aliases {
+ uart0 = &uart0;
+ };
+
+ chosen {
+ bootargs = ""; /* Set by VideoCore */
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+
+ __overrides__ {
+ cache_line_size = <&vchiq>, "cache-line-size:0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/sam9260ek.dts b/usr/src/boot/sys/boot/fdt/dts/arm/sam9260ek.dts
new file mode 100644
index 0000000000..8e4d7530ea
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/sam9260ek.dts
@@ -0,0 +1,37 @@
+/*
+ * SAM9260EK eval board - Warner Losh public domain
+ *
+ * $FreeBSD$
+ */
+/dts-v1/;
+#include "sam9260ek_common.dtsi"
+
+/ {
+ model = "Atmel at91sam9260ek";
+ compatible = "atmel,at91sam9260ek", "atmel,at91sam9260", "atmel,at91sam9";
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds1 {
+ label = "ds1";
+ gpios = <&pioA 9 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds5 {
+ label = "ds5";
+ gpios = <&pioA 6 1>;
+ };
+ };
+
+ aliases {
+ dbgu = &dbgu;
+ };
+
+
+ chosen {
+ stdin = "dbgu";
+ stdout = "dbgu";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/sheevaplug.dts b/usr/src/boot/sys/boot/fdt/dts/arm/sheevaplug.dts
new file mode 100644
index 0000000000..3d347da19d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/sheevaplug.dts
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Marvell SheevaPlug Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,SheevaPlug";
+ compatible = "SheevaPlug";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ mpp = &MPP;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ soc = &SOC;
+ sram = &SRAM;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR131";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x20000000>; // 512M at 0x0
+ };
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <3>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mrvl,nfc";
+ reg = <0x0 0x0 0x00100000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ slice@0 {
+ reg = <0x0 0x200000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ slice@200000 {
+ reg = <0x200000 0x1fe00000>;
+ label = "root";
+ };
+ };
+ };
+
+ SOC: soc88f6281@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <1>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count = <50>;
+ pin-map = <
+ 0 1 /* MPP[0]: NF_IO[2] */
+ 1 1 /* MPP[1]: NF_IO[3] */
+ 2 1 /* MPP[2]: NF_IO[4] */
+ 3 1 /* MPP[3]: NF_IO[5] */
+ 4 1 /* MPP[4]: NF_IO[6] */
+ 5 1 /* MPP[5]: NF_IO[7] */
+ 6 1 /* MPP[6]: SYSRST_OUTn */
+ 8 2 /* MPP[8]: UA0_RTS */
+ 9 2 /* MPP[9]: UA0_CTS */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: UA0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 29 1 >; /* MPP[29]: TSMP[9] */
+ };
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <35 36 37 38 39 40 41>;
+ interrupt-parent = <&PIC>;
+ };
+
+ rtc@10300 {
+ compatible = "mrvl,rtc";
+ reg = <0x10300 0x08>;
+ };
+
+ twsi@11000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,twsi";
+ reg = <0x11000 0x20>;
+ interrupts = <43>;
+ interrupt-parent = <&PIC>;
+ };
+
+ enet0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V2";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <12 13 14 11 46>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <33>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <34>;
+ interrupt-parent = <&PIC>;
+ };
+
+ crypto@30000 {
+ compatible = "mrvl,cesa";
+ reg = <0x30000 0x10000>;
+ interrupts = <22>;
+ interrupt-parent = <&PIC>;
+
+ sram-handle = <&SRAM>;
+ };
+
+ usb@50000 {
+ compatible = "mrvl,usb-ehci", "usb-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <48 19>;
+ interrupt-parent = <&PIC>;
+ };
+
+ xor@60000 {
+ compatible = "mrvl,xor";
+ reg = <0x60000 0x1000>;
+ interrupts = <5 6 7 8>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ SRAM: sram@fd000000 {
+ compatible = "mrvl,cesa-sram";
+ reg = <0xfd000000 0x00100000>;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts
new file mode 100644
index 0000000000..c7dcde3826
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "socfpga.dtsi"
+
+/ {
+ model = "Terasic SoCKit";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ memreserve = < 0x00000000 0x1000 >, /* SMP trampoline */
+ < 0x00001000 0x1000 >, /* virtio block */
+ < 0x00002000 0x1000 >; /* virtio net */
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x40000000 >; /* 1G RAM */
+ };
+
+ SOC: socfpga {
+ serial0: serial@ffc02000 {
+ status = "okay";
+ };
+
+ usb1: usb@ffb40000 {
+ status = "okay";
+ };
+
+ gmac1: ethernet@ff702000 {
+ status = "okay";
+
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <2600>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <2000>;
+ };
+
+ mmc: dwmmc@ff704000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ bus-frequency = <25000000>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+
+ beri_mem0: mem@d0000000 {
+ compatible = "sri-cambridge,beri-mem";
+ reg = <0xd0000000 0x10000000>; /* 256mb */
+ status = "okay";
+ };
+
+ pio0: pio@c0020000 {
+ compatible = "altr,pio";
+ reg = <0xc0020000 0x1000>; /* recv */
+ interrupts = < 76 >;
+ interrupt-parent = <&GIC>;
+ status = "okay";
+ };
+
+ pio1: pio@c0021000 {
+ compatible = "altr,pio";
+ reg = <0xc0021000 0x1000>; /* send */
+ interrupts = < 82 >; /* not in use on arm side */
+ interrupt-parent = <&GIC>;
+ status = "okay";
+ };
+
+ pio2: pio@c0022000 {
+ compatible = "altr,pio";
+ reg = <0xc0022000 0x1000>; /* recv */
+ interrupts = < 77 >;
+ interrupt-parent = <&GIC>;
+ status = "okay";
+ };
+
+ pio3: pio@c0023000 {
+ compatible = "altr,pio";
+ reg = <0xc0023000 0x1000>; /* send */
+ interrupts = < 83 >; /* not in use on arm side */
+ interrupt-parent = <&GIC>;
+ status = "okay";
+ };
+
+ beri_vtblk: vtblk@00001000 {
+ compatible = "sri-cambridge,beri-vtblk";
+ reg = <0x00001000 0x1000>;
+ pio-recv = <&pio0>;
+ pio-send = <&pio1>;
+ beri-mem = <&beri_mem0>;
+ status = "okay";
+ };
+
+ beri_vtnet: vtnet@00002000 {
+ compatible = "sri-cambridge,beri-vtnet";
+ reg = <0x00002000 0x1000>;
+ pio-recv = <&pio2>;
+ pio-send = <&pio3>;
+ beri-mem = <&beri_mem0>;
+ status = "okay";
+ };
+
+ beri_debug: ring@c0000000 {
+ compatible = "sri-cambridge,beri-ring";
+ reg = <0xc0000000 0x3000>;
+ interrupts = < 72 73 >;
+ interrupt-parent = <&GIC>;
+ device_name = "beri_debug";
+ data_size = <0x1000>;
+ data_read = <0x0>;
+ data_write = <0x1000>;
+ control_read = <0x2000>;
+ control_write = <0x2010>;
+ status = "okay";
+ };
+
+ beri_console: ring@c0004000 {
+ compatible = "sri-cambridge,beri-ring";
+ reg = <0xc0004000 0x3000>;
+ interrupts = < 74 75 >;
+ interrupt-parent = <&GIC>;
+ device_name = "beri_console";
+ data_size = <0x1000>;
+ data_read = <0x0>;
+ data_write = <0x1000>;
+ control_read = <0x2000>;
+ control_write = <0x2010>;
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit.dts b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit.dts
new file mode 100644
index 0000000000..ad1902d07d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga-sockit.dts
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "socfpga.dtsi"
+
+/ {
+ model = "Terasic SoCKit";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ /* Reserve first page for secondary CPU trampoline code */
+ memreserve = < 0x00000000 0x1000 >;
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x40000000 >; /* 1G RAM */
+ };
+
+ SOC: socfpga {
+ serial0: serial@ffc02000 {
+ status = "okay";
+ };
+
+ usb1: usb@ffb40000 {
+ status = "okay";
+ };
+
+ gmac1: ethernet@ff702000 {
+ status = "okay";
+
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <2600>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <2000>;
+ };
+
+ mmc: dwmmc@ff704000 {
+ status = "okay";
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ bus-frequency = <25000000>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/socfpga.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga.dtsi
new file mode 100644
index 0000000000..baecbf843e
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/socfpga.dtsi
@@ -0,0 +1,200 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ compatible = "altr,socfpga";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ rstmgr = &rstmgr;
+ l3regs = &l3regs;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ };
+
+ SOC: socfpga {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@fffed000 {
+ compatible = "arm,gic";
+ reg = < 0xfffed000 0x1000 >, /* Distributor */
+ < 0xfffec100 0x100 >; /* CPU Interface */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ mp_tmr@40002100 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = <200000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = < 0xfffec200 0x100 >, /* Global Timer */
+ < 0xfffec600 0x100 >; /* Private Timer */
+ interrupts = < 27 29 >;
+ interrupt-parent = < &GIC >;
+ };
+
+ sysmgr: sysmgr@ffd08000 {
+ compatible = "altr,sys-mgr";
+ reg = <0xffd08000 0x1000>;
+ };
+
+ clkmgr: clkmgr@ffd04000 {
+ compatible = "altr,clk-mgr";
+ reg = <0xffd04000 0x1000>;
+ };
+
+ rstmgr: rstmgr@ffd05000 {
+ compatible = "altr,rst-mgr";
+ reg = <0xffd05000 0x1000>;
+ };
+
+ l3regs: l3regs@ff800000 {
+ compatible = "altr,l3regs";
+ reg = <0xff800000 0x1000>;
+ };
+
+ fpgamgr: fpgamgr@ff706000 {
+ compatible = "altr,fpga-mgr";
+ reg = <0xff706000 0x1000>, /* FPGAMGRREGS */
+ <0xffb90000 0x1000>; /* FPGAMGRDATA */
+ interrupts = < 207 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio0: gpio@ff708000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff708000 0x1000>;
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ snps,nr-gpios = <29>;
+ };
+ };
+
+ gpio1: gpio@ff709000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff709000 0x1000>;
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ snps,nr-gpios = <29>;
+ };
+ };
+
+ gpio2: gpio@ff70a000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff70a000 0x1000>;
+ portc: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ snps,nr-gpios = <27>;
+ };
+ };
+
+ serial0: serial@ffc02000 {
+ compatible = "ns16550";
+ reg = <0xffc02000 0x1000>;
+ reg-shift = <2>;
+ interrupts = <194>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 100000000 >;
+ status = "disabled";
+ };
+
+ serial1: serial@ffc03000 {
+ compatible = "ns16550";
+ reg = <0xffc03000 0x1000>;
+ reg-shift = <2>;
+ interrupts = <195>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 100000000 >;
+ status = "disabled";
+ };
+
+ usb0: usb@ffb00000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xffb00000 0xffff>;
+ interrupts = <157>;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ usb1: usb@ffb40000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xffb40000 0xffff>;
+ interrupts = <160>;
+ interrupt-parent = <&GIC>;
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ gmac0: ethernet@ff700000 {
+ compatible = "altr,socfpga-stmmac",
+ "snps,dwmac-3.70a", "snps,dwmac";
+ reg = <0xff700000 0x2000>;
+ interrupts = <147>;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
+ gmac1: ethernet@ff702000 {
+ compatible = "altr,socfpga-stmmac",
+ "snps,dwmac-3.70a", "snps,dwmac";
+ reg = <0xff702000 0x2000>;
+ interrupts = <152>;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
+ mmc: dwmmc@ff704000 {
+ compatible = "altr,socfpga-dw-mshc";
+ reg = <0xff704000 0x1000>;
+ interrupts = <171>;
+ interrupt-parent = <&GIC>;
+ fifo-depth = <0x400>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/sun4i-a10.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
new file mode 100644
index 0000000000..417ea229c9
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ compatible = "allwinner,sun4i-a10";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&AINTC>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: a10 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ AINTC: interrupt-controller@01c20400 {
+ compatible = "allwinner,sun4i-a10-ic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = < 0x01c20400 0x400 >;
+ };
+
+ sramc@01c00000 {
+ compatible = "allwinner,sun4i-sramc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c00000 0x1000 >;
+ };
+
+ ccm@01c20000 {
+ compatible = "allwinner,sun4i-ccm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c20000 0x400 >;
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = < 22 >;
+ interrupt-parent = <&AINTC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-wdt";
+ reg = <0x01c20c90 0x08>;
+ };
+
+
+ GPIO: gpio@01c20800 {
+ #gpio-cells = <3>;
+ compatible = "allwinner,sun4i-a10-pinctrl";
+ gpio-controller;
+ reg =< 0x01c20800 0x400 >;
+ interrupts = < 28 >;
+ interrupt-parent = <&AINTC>;
+
+ emac_pins: emac@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ usb1: usb@01c14000 {
+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+ reg = <0x01c14000 0x1000>;
+ interrupts = < 39 >;
+ interrupt-parent = <&AINTC>;
+ };
+
+ usb2: usb@01c1c000 {
+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+ reg = <0x01c1c000 0x1000>;
+ interrupts = < 40 >;
+ interrupt-parent = <&AINTC>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun4i-a10-mmc";
+ reg = <0x01c0f000 0x1000>;
+ interrupts = <32>;
+ interrupt-parent = <&AINTC>;
+ status = "disabled";
+ };
+
+ sata@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <56>;
+ interrupt-parent = <&AINTC>;
+ status = "disabled";
+ };
+
+ UART0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ reg-shift = <2>;
+ interrupts = <1>;
+ interrupt-parent = <&AINTC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ };
+
+ emac@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <55>;
+ interrupt-parent = <&AINTC>;
+ };
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20-hdmi.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20-hdmi.dtsi
new file mode 100644
index 0000000000..4d4a3c5ec4
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20-hdmi.dtsi
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ soc@01c00000 {
+ hdmi: hdmi@01c16000 {
+ compatible = "allwinner,sun7i-a20-hdmi";
+ reg = <0x01c16000 0x1000>;
+ status = "disabled";
+ };
+
+ hdmiaudio {
+ compatible = "allwinner,sun7i-a20-hdmiaudio";
+ status = "disabled";
+ };
+
+ fb: fb@01e60000 {
+ compatible = "allwinner,sun7i-a20-fb";
+ reg = <0x01e60000 0x10000>, /* DEBE0 */
+ <0x01c0c000 0x1000>; /* LCD0 */
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
new file mode 100644
index 0000000000..43c6e4bd7f
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ compatible = "allwinner,sun7i-a20";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ SOC: a20 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@01c81000 {
+ compatible = "arm,gic";
+ reg = <0x01c81000 0x1000>, /* Distributor Registers */
+ <0x01c82000 0x0100>, /* CPU Interface Registers */
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ sramc@01c00000 {
+ compatible = "allwinner,sun4i-sramc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c00000 0x1000 >;
+ };
+
+ cpu-cfg@01c25c00 {
+ compatible = "allwinner,sun7i-cpu-cfg";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c25c00 0x400 >;
+ };
+
+ ccm@01c20000 {
+ compatible = "allwinner,sun4i-ccm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x01c20000 0x400 >;
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0x90>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ watchdog@01c20c90 {
+ compatible = "allwinner,sun4i-a10-wdt";
+ reg = <0x01c20c90 0x10>;
+ };
+
+ pio: gpio@01c20800 {
+ #gpio-cells = <3>;
+ compatible = "allwinner,sun7i-a20-pinctrl";
+ gpio-controller;
+ reg =< 0x01c20800 0x400 >;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&GIC>;
+
+ gmac_pins_mii: gmac_mii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA9", "PA10",
+ "PA11", "PA12", "PA13", "PA14",
+ "PA15", "PA16";
+ allwinner,function = "gmac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_rgmii: gmac_rgmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2",
+ "PA3", "PA4", "PA5", "PA6",
+ "PA7", "PA8", "PA10",
+ "PA11", "PA12", "PA13",
+ "PA15", "PA16";
+ allwinner,function = "gmac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ };
+
+ usb1: usb@01c14000 {
+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+ reg = <0x01c14000 0x1000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb2: usb@01c1c000 {
+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+ reg = <0x01c1c000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sata@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ UART0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ };
+
+ emac@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ gmac@01c50000 {
+ compatible = "allwinner,sun7i-a20-gmac";
+ reg = <0x01c50000 0x10000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&GIC>;
+ snps,pbl = <2>;
+ snps,fixed-burst;
+ snps,force_sf_dma_mode;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <27>;
+ interrupt-parent = <&GIC>;
+ };
+
+ codec: codec@01c22c00 {
+ compatible = "allwinner,sun7i-a20-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <30>;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/tegra20-paz00.dts b/usr/src/boot/sys/boot/fdt/dts/arm/tegra20-paz00.dts
new file mode 100644
index 0000000000..912a8f9c63
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/tegra20-paz00.dts
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2012 Andrew Turner
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion@gmail.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/dts-v1/;
+
+/include/ "tegra20.dtsi"
+
+/ {
+ model = "Toshiba AC100 / Dynabook AZ";
+
+ aliases {
+ serial0 = &serial0;
+ soc = &SOC;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x20000000 >; /* 512MB RAM at 0x0 */
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+
+ SOC: tegra20@0 {
+ serial0: serial@70006000 {
+ };
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/tegra20.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/tegra20.dtsi
new file mode 100644
index 0000000000..d7107fdc31
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/tegra20.dtsi
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2012 Andrew Turner
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion@gmail.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ compatible = "compal,paz00", "nvidia,tegra20";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&GIC>;
+
+ SOC: tegra20@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@50041000 {
+ compatible = "arm,gic";
+ reg = < 0x50041000 0x1000 >, /* Distributor Registers */
+ < 0x50040100 0x0100 >; /* CPU Interface Registers */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ mp_tmr@50040200 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = < 50040200 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = < 0x50040200 0x100 >, /* Global Timer Registers */
+ < 0x50040600 0x100 >; /* Private Timer Registers */
+ interrupts = < 27 29 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ serial@70006000 {
+ compatible = "ns16550";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = < 68 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 215654400 >;
+ };
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/trimslice.dts b/usr/src/boot/sys/boot/fdt/dts/arm/trimslice.dts
new file mode 100644
index 0000000000..ac7017fc59
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/trimslice.dts
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion@gmail.com>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "CompuLab TrimSlice";
+ compatible = "compulab,trimslice", "nvidia,tegra20";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ serial0 = &serial0;
+ soc = &SOC;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x40000000 >; /* 1GB RAM at 0x0 */
+ };
+
+
+ SOC: tegra20@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@50041000 {
+ compatible = "arm,gic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = < 0x50041000 0x1000 >, /* Distributor Registers */
+ < 0x50040100 0x0100 >; /* CPU Interface Registers */
+ };
+ mp_tmr@50040200 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = < 50040200 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = < 0x50040200 0x100 >, /* Global Timer Registers */
+ < 0x50040600 0x100 >; /* Private Timer Registers */
+ interrupts = < 27 29 >;
+ interrupt-parent = < &GIC >;
+ };
+
+ tmr1@60005000 {
+ compatible = "nvidia,tegra2-timer";
+ reg = <0x60005000 0x8>;
+ interrupts = < 32 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ tmr2@60005008 {
+ compatible = "nvidia,tegra2-timer";
+ reg = <0x60005008 0x8>;
+ interrupts = < 33 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ tmrus@60005010 {
+ compatible = "nvidia,tegra2-timestamp";
+ reg = <0x60005010 0x8>;
+ };
+
+ tmr3@60005050 {
+ compatible = "nvidia,tegra2-timer";
+ reg = <0x60005050 0x8>;
+ interrupts = < 73 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ tmr4@60005058 {
+ compatible = "nvidia,tegra2-timer";
+ reg = <0x60005058 0x8>;
+ interrupts = < 74 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ serial0: serial@70006000 {
+ compatible = "ns16550";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = < 68 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 215654400 >;
+ };
+
+ serial1: serial@70006040 {
+ compatible = "ns16550";
+ reg = <0x70006040 0x40>;
+ reg-shift = <2>;
+ interrupts = < 69 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 215654400 >;
+ };
+
+ serial2: serial@70006200 {
+ compatible = "ns16550";
+ reg = <0x70006200 0x100>;
+ reg-shift = <2>;
+ interrupts = < 78 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 215654400 >;
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/ts7800.dts b/usr/src/boot/sys/boot/fdt/dts/arm/ts7800.dts
new file mode 100644
index 0000000000..547a2d7551
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/ts7800.dts
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Technologic Systems TS-7800 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mrvl,TS-7800";
+ compatible = "DB-88F5182-BP", "DB-88F5182-BP-A";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &mge0;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ mpp = &MPP;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,88FR531";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>; // 128M at 0x0
+ };
+
+ localbus@f1000000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x0f 0xf9300000 0x00100000
+ 0x1 0x1e 0xfa000000 0x00100000
+ 0x2 0x1d 0xfa100000 0x02000000>;
+ };
+
+ soc88f5182@f1000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0xf1000000 0x00100000>;
+ bus-frequency = <0>;
+
+ PIC: pic@20200 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x3c>;
+ compatible = "mrvl,pic";
+ };
+
+ timer@20300 {
+ compatible = "mrvl,timer";
+ reg = <0x20300 0x30>;
+ interrupts = <0>;
+ interrupt-parent = <&PIC>;
+ mrvl,has-wdt;
+ };
+
+ MPP: mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x54>;
+ pin-count = <20>;
+ pin-map = <
+ 16 0 /* MPP[16]: UA1_RXD */
+ 17 0 /* MPP[17]: UA1_TXD */
+ 19 0 >; /* MPP[19]: UA1_RTS */
+ };
+
+ mge0: ethernet@72000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "V1";
+ compatible = "mrvl,ge";
+ reg = <0x72000 0x2000>;
+ ranges = <0x0 0x72000 0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <18 19 20 21 22>;
+ interrupt-parent = <&PIC>;
+
+ phy-handle = <&phy0>;
+
+ mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mrvl,mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+
+ serial0: serial@12000 {
+ compatible = "ns16550";
+ reg = <0x12000 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <3>;
+ interrupt-parent = <&PIC>;
+ };
+
+ serial1: serial@12100 {
+ compatible = "ns16550";
+ reg = <0x12100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <0>;
+ interrupts = <4>;
+ interrupt-parent = <&PIC>;
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/versatilepb.dts b/usr/src/boot/sys/boot/fdt/dts/arm/versatilepb.dts
new file mode 100644
index 0000000000..ca58e8859c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/versatilepb.dts
@@ -0,0 +1,118 @@
+/*
+ * $FreeBSD$
+ */
+/dts-v1/;
+
+/ {
+ model = "ARM Versatile PB";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,versatile-pb";
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller {
+ compatible = "arm,versatile-vic";
+ reg = <0x10140000 0x1000>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ sic: secondary-interrupt-controller {
+ compatible = "arm,versatile-sic";
+ reg = <0x10003000 0x28>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ uart0: uart0 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f1000 0x1000>;
+ interrupts = <12>;
+ interrupt-parent = <&intc>;
+ clock-frequency = <3000000>;
+ reg-shift = <2>;
+ };
+
+ uart1: uart1 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f2000 0x1000>;
+ interrupts = <13>;
+ interrupt-parent = <&intc>;
+ clock-frequency = <3000000>;
+ reg-shift = <2>;
+ };
+
+ uart2: uart2 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x101f3000 0x1000>;
+ interrupts = <14>;
+ interrupt-parent = <&intc>;
+ clock-frequency = <3000000>;
+ reg-shift = <2>;
+ };
+
+ timer0 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x101e2000 0x40>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ };
+
+ pci0 {
+
+ compatible = "versatile,pci";
+ reg = <0x10000044 0x4
+ 0x10001000 0x1000
+ 0x41000000 0x01000000
+ 0x42000000 0x02000000>;
+ };
+
+ net {
+ compatible = "smsc,lan91c111";
+ reg = <0x10010000 0x10000>;
+ interrupts = <25>;
+ interrupt-parent = <&intc>;
+ };
+
+ display {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0x10000050 4
+ 0x10120000 0x1000>;
+ interrupts = <16>;
+ interrupt-parent = <&intc>;
+ };
+
+ /*
+ * Cut corner here: we do not have proper interrupt
+ * controllers cascading so just hardwire SIC IRQ 3
+ * to VIC IRQ31
+ */
+ kmi {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x10006000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupts = <31>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x08000000>; /* 128MB */
+ };
+
+ aliases {
+ uart0 = &uart0;
+ };
+
+ chosen {
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/vsatv102-m6.dts b/usr/src/boot/sys/boot/fdt/dts/arm/vsatv102-m6.dts
new file mode 100644
index 0000000000..468d5f0096
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/vsatv102-m6.dts
@@ -0,0 +1,309 @@
+/*-
+ * Copyright (c) 2013-2015 John Wehle <john@feith.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The ordering of certain devices is significant (e.g. usb depends on
+ * usb-phy which depends on gpio, also the timer should appear early on
+ * to provide a reasonably accurate DELAY implementation).
+ *
+ * Both usb-phys devices must be configured to prevent the usb controller
+ * from hanging during initialization.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84900000 0x00600000; /* 6MB frame buffer */
+
+#include "meson6.dtsi"
+
+/ {
+ /*
+ * My development unit visually appears to be a Visson ATV-102
+ * and the specs for both my unit and the Visson ATV-102 say
+ * the SoC is an aml8726-m3. However the uboot prompt says
+ * m6_mbx_v1, the RTC is located on SECBUS2 instead of AOBUS,
+ * and there are two cores so it seems my unit is a newer
+ * version using the later processor.
+ */
+
+ model = "visson,atv-102";
+ compatible = "visson,atv-102", "amlogic,meson6";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &soc;
+ screen = &screen;
+ uart0 = &uart_AO;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1GB RAM */
+ };
+
+ soc: soc {
+ device_type = "soc";
+ bus-frequency = <0>;
+
+ pic: pic@c1109a40 {
+ device_type = "interrupt-controller";
+ compatible = "amlogic,aml8726-pic";
+ reg = <0xc1109a40 128>; /* cbus 0x2690 */
+
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ scu: scu@c4300000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xc4300000 0x1000>;
+ };
+
+ cpuconfig: cpuconfig@d901ff80 {
+ compatible = "amlogic,aml8726-cpuconfig";
+ reg = <0xd901ff80 8>;
+ };
+
+ ccm@c1104140 {
+ compatible = "amlogic,aml8726-ccm";
+ reg = <0xc1104140 20>; /* cbus 0x1050 */
+
+ functions = "ethernet", "i2c", "rng", "sdio",
+ "uart-a", "uart-b", "uart-c",
+ "usb-a", "usb-b";
+ };
+
+ pinctrl: pinctrl@c11080b0 {
+ compatible = "amlogic,aml8726-pinctrl";
+ reg = <0xc11080b0 40>, /* mux */
+ <0xc11080e8 24>, /* pu/pd */
+ <0xc11080e8 24>, /* pull enable */
+ <0xc8100014 4>, /* ao mux */
+ <0xc810002c 4>, /* ao pu/pd */
+ <0xc810002c 4>; /* ao pull enable */
+
+ /*
+ * Currently only pin muxing that deviates
+ * from the power on default of gpio is
+ * specified here.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_uartao &pins_ethernet &pins_hdmi>;
+
+ pins_ethernet: ethernet {
+ amlogic,pins = "ref_clk_in",
+ "tx_clk", "tx_en",
+ "tx_d0", "tx_d1",
+ "tx_d2", "tx_d3",
+ "rx_clk", "rx_dv",
+ "rx_d0", "rx_d1",
+ "rx_d2", "rx_d3",
+ "mdc", "mdio";
+ amlogic,function = "ethernet";
+ };
+
+ pins_hdmi: hdmi {
+ amlogic,pins = "cec", "hpd",
+ "scl", "sda";
+ amlogic,function = "hdmi";
+ };
+
+ pins_sdio_b: sdio_b {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdio-b";
+ };
+
+ pins_uartao: uartao {
+ amlogic,pins = "tx", "rx";
+ amlogic,function = "uart-ao";
+ };
+ };
+
+ rtc@da004340 {
+ compatible = "amlogic,aml8726-rtc";
+ reg = <0xda004340 20>; /* secbus2 0xd0 */
+ interrupts = <0 72 1>; /* AM_IRQ2(8) */
+ };
+
+ clkmsr: clkmsr@c1108758 {
+ compatible = "amlogic,aml8726-clkmsr";
+ reg = <0xc1108758 16>; /* cbus 0x21d6 */
+
+ clocks = <&clk81>;
+ };
+
+ gpioao: gpio@c8100024 {
+ /* gpio unit 7 */
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc8100024 4>, /* oen aobus 0x9 */
+ <0xc8100024 4>, /* out */
+ <0xc8100028 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <12>;
+ };
+
+ gpio5: gpio@c110806c {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc110806c 4>, /* oen cbus 0x201b */
+ <0xc1108070 4>, /* out */
+ <0xc1108074 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <32>;
+ };
+
+ gpio6: gpio@c1108020 {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc1108020 4>, /* oen cbus 0x2008 */
+ <0xc1108024 4>, /* out */
+ <0xc1108028 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <29>;
+ };
+
+ mmc@c1108c20 {
+ compatible = "amlogic,aml8726-mmc";
+ reg = <0xc1108c20 32>; /* cbus 0x2308 */
+ interrupts = <0 28 1>; /* AM_IRQ0(28) */
+
+ clocks = <&clk81>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_sdio_b>;
+
+ mmc-voltages = "3.3";
+
+ mmc-pwr-en = <&gpio5 31 0>; /* card_8 */
+ ins-detect = <&gpio5 29 0>; /* card_6 */
+ };
+
+ rng@c1108100 {
+ compatible = "amlogic,aml8726-rng";
+ reg = <0xc1108100 8>; /* cbus 0x2040 */
+ };
+
+ usb-phy@c1108400 {
+ /* usb-a phy */
+ compatible = "amlogic,aml8726-m6-usb-phy";
+ reg = <0xc1108400 32>; /* cbus 0x2100 */
+ };
+
+ usb-phy@c1108420 {
+ /* usb-b phy */
+ compatible = "amlogic,aml8726-m6-usb-phy";
+ reg = <0xc1108420 32>; /* cbus 0x2108 */
+
+ usb-pwr-en = <&gpioao 3 1>, /* gpioao_3 vbus */
+ <&gpio6 11 0>; /* gpioe_11 wifi */
+ };
+
+ usb@c9040000 {
+ /* usb-a */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
+ interrupts = <0 30 4>; /* AM_IRQ0(30) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb@c90c0000 {
+ /* usb-b */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
+ interrupts = <0 31 4>; /* AM_IRQ0(31) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+ };
+
+ eth@c9410000 {
+ /* ethernet */
+ compatible = "snps,dwmac";
+ reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
+ interrupts = <0 8 1>; /* AM_IRQ0(8) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth-phy-rst = <&gpio5 15 0>; /* gpioy_15 phy-rst */
+ };
+
+ screen: fb@c8006324 {
+ device_type = "display";
+ compatible = "amlogic,aml8726-fb";
+ reg = <0xc8006324 12>, /* CANVAS */
+ <0xc1106800 1024>, /* VIU */
+ <0xc1107400 1024>; /* VPP */
+ interrupts = <0 2 1>, /* AM_IRQ0(2) */
+ <0 3 1>, /* AM_IRQ0(3) */
+ <0 12 1>, /* AM_IRQ0(12) */
+ <0 13 1>; /* AM_IRQ0(13) */
+
+ address = <0x84900000>; /* match memreserve */
+ width = <720>;
+ height = <480>;
+ depth = <24>;
+ linebytes = <2160>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ sys_led {
+ gpios = <&gpioao 2>; /* gpioao_2 sys_led */
+ label = "sys_led";
+
+ default-state = "on";
+ };
+ };
+
+ chosen {
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+};
+
+&clk81 {
+ clock-frequency = <0>;
+};
+
+&uart_AO {
+ status = "okay";
+ current-speed = <115200>;
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-colibri-vf50.dts b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-colibri-vf50.dts
new file mode 100644
index 0000000000..6d4d934b3d
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-colibri-vf50.dts
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "vybrid.dtsi"
+
+/ {
+ model = "Toradex Colibri VF50";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x80000000 0x08000000 >; /* 128MB RAM */
+ };
+
+ SOC: vybrid {
+ serial0: serial@40027000 {
+ status = "okay";
+ };
+
+ fec1: ethernet@400D1000 {
+ status = "okay";
+ iomux_config = < 54 0x103192
+ 55 0x103193
+ 56 0x103191
+ 57 0x103191
+ 58 0x103191
+ 59 0x103191
+ 60 0x103192
+ 61 0x103192
+ 62 0x103192
+ 0 0x103191 >;
+ };
+
+ sai3: sai@40032000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@40066000 {
+ status = "okay";
+ };
+
+ adc0: adc@4003B000 {
+ status = "okay";
+ };
+
+ edma1: edma@40098000 {
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-cosmic.dts b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-cosmic.dts
new file mode 100644
index 0000000000..c98c093257
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-cosmic.dts
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "vybrid.dtsi"
+
+/ {
+ model = "Cosmic Board";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
+ };
+
+ SOC: vybrid {
+ serial1: serial@40028000 {
+ status = "okay";
+ };
+
+ fec1: ethernet@400D1000 {
+ status = "okay";
+ iomux_config = < 54 0x103192
+ 55 0x103193
+ 56 0x103191
+ 57 0x103191
+ 58 0x103191
+ 59 0x103191
+ 60 0x103192
+ 61 0x103192
+ 62 0x103192
+ 0 0x203191 >;
+ };
+
+ esai: esai@40062000 {
+ status = "okay";
+ };
+
+ edma1: edma@40098000 {
+ status = "okay";
+ };
+
+ tcon0: tcon@4003D000 {
+ status = "okay";
+ };
+
+ dcu0: dcu4@40058000 {
+ status = "okay";
+ };
+
+ adc0: adc@4003B000 {
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial1";
+ stdout = "serial1";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-quartz.dts b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-quartz.dts
new file mode 100644
index 0000000000..48cc1b5f90
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid-quartz.dts
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/include/ "vybrid.dtsi"
+
+/ {
+ model = "Device Solutions Quartz Module";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
+ };
+
+ SOC: vybrid {
+ serial0: serial@40027000 {
+ status = "okay";
+ };
+
+ fec1: ethernet@400D1000 {
+ status = "okay";
+ iomux_config = < 54 0x103192
+ 55 0x103193
+ 56 0x103191
+ 57 0x103191
+ 58 0x103191
+ 59 0x103191
+ 60 0x103192
+ 61 0x103192
+ 62 0x103192
+ 0 0x203191 >;
+ };
+
+ edma1: edma@40098000 {
+ status = "okay";
+ };
+
+ dcu0: dcu4@40058000 {
+ status = "okay";
+
+ panel-size = < 800 480 >;
+ panel-hsync = < 40 48 40 >;
+ panel-vsync = < 29 3 13 >;
+ panel-clk-div = < 17 >;
+ panel-backlight-pin = < 25 >;
+
+ iomux_config = < 105 0x1001c4 /* hsync */
+ 106 0x1001c4 /* vsync */
+ 107 0x1001e0 /* pclk */
+ 108 0x1001e0
+ 109 0x1001be /* de */
+ 110 0x1001e0 /* r0 */
+ 111 0x1001e0
+ 112 0x1001e0
+ 113 0x1001e0
+ 114 0x1001e0
+ 115 0x1001e0
+ 116 0x1001e0
+ 117 0x1001e0
+ 118 0x1001e0 /* g0 */
+ 119 0x1001e0
+ 120 0x1001e0
+ 121 0x1001e0
+ 122 0x1001e0
+ 123 0x1001e0
+ 124 0x1001e0
+ 125 0x1001e0
+ 126 0x1001e0 /* b0 */
+ 127 0x1001e0
+ 128 0x1001e0
+ 129 0x1001e0
+ 130 0x1001e0
+ 131 0x1001e0
+ 132 0x1001e0
+ 133 0x1001e0
+ 25 0x0001be >; /* led */
+ };
+
+ tcon0: tcon@4003D000 {
+ status = "okay";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/vybrid.dtsi b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid.dtsi
new file mode 100644
index 0000000000..1386c70f4b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/vybrid.dtsi
@@ -0,0 +1,497 @@
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ model = "Freescale Vybrid Family";
+ compatible = "freescale,vybrid", "fsl,mvf";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ sai0 = &sai0;
+ sai1 = &sai1;
+ sai2 = &sai2;
+ sai3 = &sai3;
+ esai = &esai;
+ adc0 = &adc0;
+ adc1 = &adc1;
+ edma0 = &edma0;
+ edma1 = &edma1;
+ src = &SRC;
+ };
+
+ SOC: vybrid {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ SRC: src@4006E000 {
+ compatible = "fsl,mvf600-src";
+ reg = <0x4006E000 0x100>;
+ };
+
+ mscm@40001000 {
+ compatible = "fsl,mvf600-mscm";
+ reg = <0x40001000 0x1000>;
+ };
+
+ GIC: interrupt-controller@01c81000 {
+ compatible = "arm,gic";
+ reg = <0x40003000 0x1000>, /* Distributor Registers */
+ <0x40002100 0x100>; /* CPU Interface Registers */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ anadig@40050000 {
+ compatible = "fsl,mvf600-anadig";
+ reg = <0x40050000 0x300>;
+ };
+
+ ccm@4006b000 {
+ compatible = "fsl,mvf600-ccm";
+ reg = <0x4006b000 0x1000>;
+ clock_names = "pll4";
+ };
+
+ mp_tmr@40002100 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = <133000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = < 0x40002200 0x100 >, /* Global Timer Registers */
+ < 0x40002600 0x100 >; /* Private Timer Registers */
+ interrupts = < 27 29 >;
+ interrupt-parent = < &GIC >;
+ };
+
+ dmamux@40024000 {
+ compatible = "fsl,mvf600-dmamux";
+ reg = <0x40024000 0x100>,
+ <0x40025000 0x100>,
+ <0x400A1000 0x100>,
+ <0x400A2000 0x100>;
+ };
+
+ edma0: edma@40018000 {
+ compatible = "fsl,mvf600-edma";
+ reg = <0x40018000 0x1000>,
+ <0x40019000 0x1000>; /* TCD */
+ interrupts = < 40 41 >;
+ interrupt-parent = <&GIC>;
+ device-id = < 0 >;
+ status = "disabled";
+ };
+
+ edma1: edma@40098000 {
+ compatible = "fsl,mvf600-edma";
+ reg = <0x40098000 0x1000>,
+ <0x40099000 0x1000>; /* TCD */
+ interrupts = < 42 43 >;
+ interrupt-parent = <&GIC>;
+ device-id = < 1 >;
+ status = "disabled";
+ };
+
+ pit@40037000 {
+ compatible = "fsl,mvf600-pit";
+ reg = <0x40037000 0x1000>;
+ interrupts = < 71 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ lptmr@40040000 {
+ compatible = "fsl,mvf600-lptmr";
+ reg = <0x40040000 0x1000>;
+ interrupts = < 72 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ iomuxc@40048000 {
+ compatible = "fsl,mvf600-iomuxc";
+ reg = <0x40048000 0x1000>;
+ };
+
+ port@40049000 {
+ compatible = "fsl,mvf600-port";
+ reg = <0x40049000 0x5000>;
+ interrupts = < 139 140 141 142 143 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio@400FF000 {
+ compatible = "fsl,mvf600-gpio";
+ reg = <0x400FF000 0x200>;
+ #gpio-cells = <3>;
+ gpio-controller;
+ };
+
+ nand@400E0000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mvf600-nand";
+ reg = <0x400E0000 0x10000>;
+ interrupts = < 115 >;
+ interrupt-parent = <&GIC>;
+ clock_names = "nand";
+ status = "disabled";
+
+ partition@40000 {
+ reg = <0x40000 0x200000>; /* 2MB */
+ label = "u-boot";
+ read-only;
+ };
+
+ partition@240000 {
+ reg = <0x240000 0x200000>; /* 2MB */
+ label = "test";
+ };
+
+ partition@440000 {
+ reg = <0x440000 0xa00000>; /* 10MB */
+ label = "kernel";
+ };
+
+ partition@e40000 {
+ reg = <0xe40000 0x1e000000>; /* 480MB */
+ label = "root";
+ };
+ };
+
+ sdhci0: sdhci@400B1000 {
+ compatible = "fsl,mvf600-sdhci";
+ reg = <0x400B1000 0x1000>;
+ interrupts = < 59 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ status = "disabled";
+ clock_names = "esdhc0";
+ };
+
+ sdhci1: sdhci@400B2000 {
+ compatible = "fsl,mvf600-sdhci";
+ reg = <0x400B2000 0x1000>;
+ interrupts = < 60 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ status = "disabled";
+ clock_names = "esdhc1";
+ iomux_config = < 14 0x500060
+ 15 0x500060
+ 16 0x500060
+ 17 0x500060
+ 18 0x500060
+ 19 0x500060 >;
+ };
+
+ serial0: serial@40027000 {
+ compatible = "fsl,mvf600-uart";
+ reg = <0x40027000 0x1000>;
+ interrupts = <93>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ status = "disabled";
+ };
+
+ serial1: serial@40028000 {
+ compatible = "fsl,mvf600-uart";
+ reg = <0x40028000 0x1000>;
+ interrupts = <94>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ status = "disabled";
+ };
+
+ usb@40034000 {
+ compatible = "fsl,mvf600-usb-ehci", "usb-ehci";
+ reg = < 0x40034000 0x1000 >, /* ehci */
+ < 0x40035000 0x1000 >, /* usbc */
+ < 0x40050800 0x100 >; /* phy */
+ interrupts = < 107 >;
+ interrupt-parent = <&GIC>;
+ iomux_config = < 134 0x0001be
+ 7 0x200060 >;
+ };
+
+ usb@400b4000 {
+ compatible = "fsl,mvf600-usb-ehci", "usb-ehci";
+ reg = < 0x400b4000 0x1000 >, /* ehci */
+ < 0x400b5000 0x1000 >, /* usbc */
+ < 0x40050C00 0x100 >; /* phy */
+ interrupts = < 108 >;
+ interrupt-parent = <&GIC>;
+ iomux_config = < 134 0x0001be
+ 7 0x200060 >;
+ };
+
+ fec0: ethernet@400D0000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400D0000 0x1000>;
+ interrupts = < 110 >;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rmii";
+ phy-disable-preamble;
+ status = "disabled";
+ clock_names = "enet";
+ iomux_config = < 45 0x100061
+ 46 0x100061
+ 47 0x100061
+ 48 0x100060
+ 49 0x100060
+ 50 0x100060
+ 51 0x100060
+ 52 0x100060
+ 53 0x100060 >;
+ };
+
+ fec1: ethernet@400D1000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400D1000 0x1000>;
+ interrupts = < 111 >;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rmii";
+ phy-disable-preamble;
+ status = "disabled";
+ clock_names = "enet";
+ iomux_config = < 54 0x103192
+ 55 0x103193
+ 56 0x103191
+ 57 0x103191
+ 58 0x103191
+ 59 0x103191
+ 60 0x103192
+ 61 0x103192
+ 62 0x103192 >;
+ };
+
+ sai0: sai@4002F000 {
+ compatible = "fsl,mvf600-sai";
+ reg = <0x4002F000 0x1000>;
+ interrupts = < 116 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ sai1: sai@40030000 {
+ compatible = "fsl,mvf600-sai";
+ reg = <0x40030000 0x1000>;
+ interrupts = < 117 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ sai2: sai@40031000 {
+ compatible = "fsl,mvf600-sai";
+ reg = <0x40031000 0x1000>;
+ interrupts = < 118 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ sai3: sai@40032000 {
+ compatible = "fsl,mvf600-sai";
+ reg = <0x40032000 0x1000>;
+ interrupts = < 119 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ edma-controller = <&edma1>;
+ edma-src-receive = < 8 >;
+ edma-src-transmit = < 9 >;
+ edma-mux-group = < 1 >;
+ clock_names = "sai3", "cko1";
+ iomux_config = < 16 0x200060
+ 19 0x200060
+ 21 0x200060
+ 40 0x400061 >; /* CKO1 */
+ };
+
+ esai: esai@40062000 {
+ compatible = "fsl,mvf600-esai";
+ reg = <0x40062000 0x1000>;
+ interrupts = < 120 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ clock_names = "esai";
+ iomux_config = < 45 0x400061
+ 46 0x400061
+ 47 0x400061
+ 48 0x400060
+ 49 0x400060
+ 50 0x400060
+ 51 0x400060
+ 52 0x400060
+ 78 0x3038df
+ 40 0x400061 >;
+ };
+
+ spi0: spi@4002C000 {
+ compatible = "fsl,mvf600-spi";
+ reg = <0x4002C000 0x1000>;
+ interrupts = < 99 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ iomux_config = < 40 0x100061
+ 41 0x100061
+ 42 0x100060
+ 43 0x100060
+ 44 0x100061 >;
+ };
+
+ spi1: spi@4002D000 {
+ compatible = "fsl,mvf600-spi";
+ reg = <0x4002D000 0x1000>;
+ interrupts = < 100 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ spi2: spi@400AC000 {
+ compatible = "fsl,mvf600-spi";
+ reg = <0x400AC000 0x1000>;
+ interrupts = < 101 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ spi3: spi@400AD000 {
+ compatible = "fsl,mvf600-spi";
+ reg = <0x400AD000 0x1000>;
+ interrupts = < 102 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@40066000 {
+ compatible = "fsl,mvf600-i2c";
+ reg = <0x40066000 0x1000>;
+ interrupts = < 103 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ clock_names = "ipg";
+ iomux_config = < 36 0x2034d3
+ 37 0x2034d3
+ 207 0x1
+ 208 0x1 >;
+ };
+
+ i2c1: i2c@40067000 {
+ compatible = "fsl,mvf600-i2c";
+ reg = <0x40067000 0x1000>;
+ interrupts = < 104 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@400E6000 {
+ compatible = "fsl,mvf600-i2c";
+ reg = <0x400E6000 0x1000>;
+ interrupts = < 105 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@400E7000 {
+ compatible = "fsl,mvf600-i2c";
+ reg = <0x400E7000 0x1000>;
+ interrupts = < 106 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ adc0: adc@4003B000 {
+ compatible = "fsl,mvf600-adc";
+ reg = <0x4003B000 0x1000>;
+ interrupts = < 85 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ adc1: adc@400BB000 {
+ compatible = "fsl,mvf600-adc";
+ reg = <0x400BB000 0x1000>;
+ interrupts = < 86 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ };
+
+ tcon0: tcon@4003D000 {
+ compatible = "fsl,mvf600-tcon";
+ reg = <0x4003D000 0x1000>;
+ status = "disabled";
+ };
+
+ dcu0: dcu4@40058000 {
+ compatible = "fsl,mvf600-dcu4";
+ reg = <0x40058000 0x7000>;
+ interrupts = < 62 >;
+ interrupt-parent = <&GIC>;
+ status = "disabled";
+ clock_names = "dcu0";
+ iomux_config = < 105 0x100044
+ 106 0x100044
+ 107 0x100060
+ 108 0x100060
+ 109 0x100060
+ 110 0x100060
+ 111 0x100060
+ 112 0x100060
+ 113 0x100060
+ 114 0x100060
+ 115 0x100060
+ 116 0x100060
+ 117 0x100060
+ 118 0x100060
+ 119 0x100060
+ 120 0x100060
+ 121 0x100060
+ 122 0x100060
+ 123 0x100060
+ 124 0x100060
+ 125 0x100060
+ 126 0x100060
+ 127 0x100060
+ 128 0x100060
+ 129 0x100060
+ 130 0x100060
+ 131 0x100060
+ 132 0x100060
+ 133 0x100060 >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-dual.dts b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-dual.dts
new file mode 100644
index 0000000000..89c9d30827
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-dual.dts
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Wandboard Dual.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx6.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ model = "Wandboard Dual";
+ compatible = "wand,imx6d-wandboard", "fsl,imx6d";
+
+ memory {
+ reg = <0x10000000 0x40000000>; /* RAM 1GB */
+ };
+
+ SOC: soc@00000000 {
+ aips@02000000 { /* AIPS1 */
+ gpio@0209c000 { status = "okay"; };
+ gpio@020a0000 { status = "okay"; };
+ gpio@020a4000 { status = "okay"; };
+ gpio@020a8000 { status = "okay"; };
+ gpio@020ac000 { status = "okay"; };
+ gpio@020b0000 { status = "okay"; };
+ gpio@020b4000 { status = "okay"; };
+ console:serial@02020000 { status = "okay"; };
+ serial@021e8000 { status = "disabled"; };
+ serial@021ec000 { status = "disabled"; };
+ serial@021f0000 { status = "disabled"; };
+ serial@021f4000 { status = "disabled"; };
+ usbphy@020c9000 { status = "okay"; };
+ usbphy@020ca000 { status = "okay"; };
+ };
+ aips@02100000 { /* AIPS2 */
+ ethernet@02188000 {
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-disable-preamble;
+ };
+ usb@02184000 { status = "okay"; };
+ usb@02184200 { status = "okay"; };
+ usb@02184400 { status = "disabled"; };
+ usb@02184600 { status = "disabled"; };
+ usdhc@02190000 { status = "okay"; };
+ usdhc@02194000 { status = "disabled"; };
+ usdhc@02198000 { status = "okay"; };
+ usdhc@0219c000 { status = "disabled"; };
+ };
+ };
+
+ chosen {
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-quad.dts b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-quad.dts
new file mode 100644
index 0000000000..fd7b9b41ed
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-quad.dts
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Wandboard Quad.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx6.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ model = "Wandboard Quad";
+ compatible = "wand,imx6q-wandboard", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x80000000>; /* RAM 2GB */
+ };
+
+ SOC: soc@00000000 {
+ aips@02000000 { /* AIPS1 */
+ gpio@0209c000 { status = "okay"; };
+ gpio@020a0000 { status = "okay"; };
+ gpio@020a4000 { status = "okay"; };
+ gpio@020a8000 { status = "okay"; };
+ gpio@020ac000 { status = "okay"; };
+ gpio@020b0000 { status = "okay"; };
+ gpio@020b4000 { status = "okay"; };
+ console:serial@02020000 { status = "okay"; };
+ serial@021e8000 { status = "disabled"; };
+ serial@021ec000 { status = "disabled"; };
+ serial@021f0000 { status = "disabled"; };
+ serial@021f4000 { status = "disabled"; };
+ usbphy@020c9000 { status = "okay"; };
+ usbphy@020ca000 { status = "okay"; };
+ };
+ aips@02100000 { /* AIPS2 */
+ ethernet@02188000 {
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-disable-preamble;
+ };
+ usb@02184000 { status = "okay"; };
+ usb@02184200 { status = "okay"; };
+ usb@02184400 { status = "disabled"; };
+ usb@02184600 { status = "disabled"; };
+ usdhc@02190000 { status = "okay"; };
+ usdhc@02194000 { status = "disabled"; };
+ usdhc@02198000 { status = "okay"; };
+ usdhc@0219c000 { status = "disabled"; };
+ };
+ };
+
+ chosen {
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-solo.dts b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-solo.dts
new file mode 100644
index 0000000000..5d67f2b8b9
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/wandboard-solo.dts
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 Ian Lepore
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Wandboard Solo.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx6.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ model = "Wandboard Solo";
+ compatible = "wand,imx6s-wandboard", "fsl,imx6s";
+
+ memory {
+ reg = <0x10000000 0x20000000>; /* RAM 512M */
+ };
+
+ SOC: soc@00000000 {
+ aips@02000000 { /* AIPS1 */
+ gpio@0209c000 { status = "okay"; };
+ gpio@020a0000 { status = "okay"; };
+ gpio@020a4000 { status = "okay"; };
+ gpio@020a8000 { status = "okay"; };
+ gpio@020ac000 { status = "okay"; };
+ gpio@020b0000 { status = "okay"; };
+ gpio@020b4000 { status = "okay"; };
+ console:serial@02020000 { status = "okay"; };
+ serial@021e8000 { status = "disabled"; };
+ serial@021ec000 { status = "disabled"; };
+ serial@021f0000 { status = "disabled"; };
+ serial@021f4000 { status = "disabled"; };
+ usbphy@020c9000 { status = "okay"; };
+ usbphy@020ca000 { status = "okay"; };
+ };
+ aips@02100000 { /* AIPS2 */
+ ethernet@02188000 {
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-disable-preamble;
+ };
+ usb@02184000 { status = "okay"; };
+ usb@02184200 { status = "okay"; };
+ usb@02184400 { status = "disabled"; };
+ usb@02184600 { status = "disabled"; };
+ usdhc@02190000 { status = "okay"; };
+ usdhc@02194000 { status = "disabled"; };
+ usdhc@02198000 { status = "okay"; };
+ usdhc@0219c000 { status = "disabled"; };
+ };
+ };
+
+ chosen {
+ stdin = &console;
+ stdout = &console;
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/yyhd18-m3.dts b/usr/src/boot/sys/boot/fdt/dts/arm/yyhd18-m3.dts
new file mode 100644
index 0000000000..bdb425d034
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/yyhd18-m3.dts
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The ordering of certain devices is significant (e.g. usb depends on
+ * usb-phy which depends on gpio, also the timer should appear early on
+ * to provide a reasonably accurate DELAY implementation).
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84900000 0x00600000; /* 6MB frame buffer */
+
+#include "meson3.dtsi"
+
+/ {
+ /*
+ * My development unit is a Yiyate Android TV Box containing
+ * a HD18 motherboard and an aml8726-m3 SoC ... later versions
+ * shipped with an aml8726-m6. Printenv in uboot shows m3-oplay
+ * as the boardname supplied as part of mmcargs.
+ */
+
+ model = "yiyate,hd18-m3";
+ compatible = "yiyate,hd18-m3", "amlogic,meson3";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &soc;
+ screen = &screen;
+ uart0 = &uart_AO;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1GB RAM */
+ };
+
+ soc: soc {
+ device_type = "soc";
+ bus-frequency = <0>;
+
+ ccm@c1104140 {
+ compatible = "amlogic,aml8726-ccm";
+ reg = <0xc1104140 20>; /* cbus 0x1050 */
+
+ functions = "ethernet", "i2c", "rng", "sdio",
+ "uart-a", "uart-b", "uart-c",
+ "usb-a", "usb-b";
+ };
+
+ pinctrl: pinctrl@c11080b0 {
+ compatible = "amlogic,aml8726-pinctrl";
+ reg = <0xc11080b0 40>, /* mux */
+ <0xc11080e8 24>, /* pu/pd */
+ <0xc11080e8 24>, /* pull enable */
+ <0xc8100014 4>, /* ao mux */
+ <0xc810002c 4>, /* ao pu/pd */
+ <0xc810002c 4>; /* ao pull enable */
+
+ /*
+ * Currently only pin muxing that deviates
+ * from the power on default of gpio is
+ * specified here.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_uartao &pins_ethernet &pins_hdmi>;
+
+ pins_ethernet: ethernet {
+ amlogic,pins = "clk_out", "tx_en",
+ "tx_d0", "tx_d1",
+ "crs_dv", "rx_err",
+ "rx_d0", "rx_d1",
+ "mdc", "mdio";
+ amlogic,function = "ethernet";
+ };
+
+ pins_hdmi: hdmi {
+ amlogic,pins = "cec", "hpd",
+ "scl", "sda";
+ amlogic,function = "hdmi";
+ };
+
+ pins_sdio_b: sdio_b {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdio-b";
+ };
+
+ pins_uartao: uartao {
+ amlogic,pins = "tx", "rx";
+ amlogic,function = "uart-ao";
+ };
+ };
+
+ rtc@c8100740 {
+ compatible = "amlogic,aml8726-rtc";
+ reg = <0xc8100740 20>; /* aobus 0x1d0 */
+ interrupts = <0 72 1>; /* AM_IRQ2(8) */
+ };
+
+ clkmsr: clkmsr@c1108758 {
+ compatible = "amlogic,aml8726-clkmsr";
+ reg = <0xc1108758 16>; /* cbus 0x21d6 */
+
+ clocks = <&clk81>;
+ };
+
+ gpio5: gpio@c110806c {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc110806c 4>, /* oen cbus 0x201b */
+ <0xc1108070 4>, /* out */
+ <0xc1108074 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <32>;
+ };
+
+ mmc@c1108c20 {
+ compatible = "amlogic,aml8726-mmc";
+ reg = <0xc1108c20 32>; /* cbus 0x2308 */
+ interrupts = <0 28 1>; /* AM_IRQ0(28) */
+
+ clocks = <&clk81>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_sdio_b>;
+
+ mmc-voltages = "3.3";
+
+ mmc-pwr-en = <&gpio5 31 0>; /* card_8 */
+ ins-detect = <&gpio5 29 0>; /* card_6 */
+ };
+
+ rng@c1108100 {
+ compatible = "amlogic,aml8726-rng";
+ reg = <0xc1108100 8>; /* cbus 0x2040 */
+ };
+
+ usb-phy@c1108400 {
+ /* usb-a and usb-b phy */
+ compatible = "amlogic,aml8726-m3-usb-phy";
+ reg = <0xc1108400 32>; /* cbus 0x2100 */
+ };
+
+ usb@c9040000 {
+ /* usb-a */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
+ interrupts = <0 30 4>; /* AM_IRQ0(30) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb@c90c0000 {
+ /* usb-b */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
+ interrupts = <0 31 4>; /* AM_IRQ0(31) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+ };
+
+ eth@c9410000 {
+ /* ethernet */
+ compatible = "snps,dwmac";
+ reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
+ interrupts = <0 8 1>; /* AM_IRQ0(8) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ screen: fb@c8001324 {
+ device_type = "display";
+ compatible = "amlogic,aml8726-fb";
+ reg = <0xc8001324 12>, /* CANVAS */
+ <0xc1106800 1024>, /* VIU */
+ <0xc1107400 1024>; /* VPP */
+ interrupts = <0 2 1>, /* AM_IRQ0(2) */
+ <0 3 1>, /* AM_IRQ0(3) */
+ <0 12 1>, /* AM_IRQ0(12) */
+ <0 13 1>; /* AM_IRQ0(13) */
+
+ address = <0x84900000>; /* match memreserve */
+ width = <720>;
+ height = <480>;
+ depth = <24>;
+ linebytes = <2160>;
+ };
+ };
+
+ chosen {
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+};
+
+&clk81 {
+ clock-frequency = <0>;
+};
+
+&uart_AO {
+ status = "okay";
+ current-speed = <115200>;
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/zedboard.dts b/usr/src/boot/sys/boot/fdt/dts/arm/zedboard.dts
new file mode 100644
index 0000000000..7277308c87
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/zedboard.dts
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "zedboard";
+ compatible = "digilent,zedboard";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&GIC>;
+
+ // cpus {
+ // #address-cells = <1>;
+ // #size-cells = <0>;
+ // cpu@0 {
+ // device-type = "cpu";
+ // model = "ARM Cortex-A9";
+ // };
+ // };
+
+ memory {
+ // First megabyte isn't accessible by all interconnect masters.
+ device_type = "memory";
+ reg = <0x100000 0x1ff00000>; /* 511MB RAM at 0x100000 */
+ };
+
+ // Zynq PS System registers.
+ //
+ ps7sys@f8000000 {
+ device_type = "soc";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xf8000000 0xf10000>;
+
+ // SLCR block
+ slcr: slcr@7000 {
+ compatible = "xlnx,zy7_slcr";
+ reg = <0x0 0x1000>;
+ clock-frequency = <33333333>; // 33Mhz PS_CLK
+ };
+
+ // Interrupt controller
+ GIC: gic {
+ compatible = "arm,gic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0xf01000 0x1000>, // distributer registers
+ <0xf00100 0x0100>; // CPU if registers
+ };
+
+ // L2 cache controller
+ pl310@f02000 {
+ compatible = "arm,pl310";
+ reg = <0xf02000 0x1000>;
+ interrupts = <34>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // Device Config
+ devcfg: devcfg@7000 {
+ compatible = "xlnx,zy7_devcfg";
+ reg = <0x7000 0x1000>;
+ interrupts = <40>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // triple timer counters0,1
+ ttc0: ttc@1000 {
+ compatible = "xlnx,ttc";
+ reg = <0x1000 0x1000>;
+ };
+ ttc1: ttc@2000 {
+ compatible = "xlnx,ttc";
+ reg = <0x2000 0x1000>;
+ };
+
+ // ARM Cortex A9 TWD Timer
+ timer@f00600 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = <333333333>; // 333Mhz
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xf00200 0x100>, // Global Timer Regs
+ <0xf00600 0x20>; // Private Timer Regs
+ interrupts = < 27 29 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ // system watch-dog timer
+ swdt@5000 {
+ device_type = "watchdog";
+ compatible = "xlnx,zy7_wdt";
+ reg = <0x5000 0x1000>;
+ interrupts = <41>;
+ interrupt-parent = <&GIC>;
+ };
+
+ scuwdt@f00620 {
+ device_type = "watchdog";
+ compatible = "arm,mpcore_wdt";
+ reg = <0xf00620 0x20>;
+ interrupts = <30>;
+ interrupt-parent = <&GIC>;
+ reset = <1>;
+ };
+ }; // pssys@f8000000
+
+ // Zynq PS I/O Peripheral registers.
+ //
+ ps7io@e0000000 {
+ device_type = "soc";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0000000 0x300000>;
+
+ // uart0: uart@0000 {
+ // device_type = "serial";
+ // compatible = "cadence,uart";
+ // reg = <0x0000 0x1000>;
+ // interrupts = <59>;
+ // interrupt-parent = <&GIC>;
+ // clock-frequency = <50000000>;
+ // };
+
+ uart1: uart@1000 {
+ device_type = "serial";
+ compatible = "cadence,uart";
+ reg = <0x1000 0x1000>;
+ interrupts = <82>;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ current-speed = <115200>;
+ };
+
+ gpio: gpio@a000 {
+ compatible = "xlnx,zy7_gpio";
+ reg = <0xa000 0x1000>;
+ interrupts = <52>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // GigE
+ eth0: eth@b000 {
+ // device_type = "network";
+
+ compatible = "cadence,gem";
+ reg = <0xb000 0x1000>;
+ interrupts = <54 55>;
+ interrupt-parent = <&GIC>;
+ ref-clock-num = <0>;
+ };
+
+ // SDIO
+ sdhci0: sdhci@100000 {
+ compatible = "xlnx,zy7_sdhci";
+ reg = <0x100000 0x1000>;
+ interrupts = <56>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <50000000>;
+ };
+
+ // QSPI
+ qspi0: qspi@d000 {
+ compatible = "xlnx,zy7_qspi";
+ reg = <0xd000 0x1000>;
+ interrupts = <51>;
+ interrupt-parent = <&GIC>;
+ spi-clock = <50000000>;
+ ref-clock = <190476000>;
+ };
+
+ // USB
+ ehci0: ehci@2000 {
+ compatible = "xlnx,zy7_ehci";
+ reg = <0x2000 0x1000>;
+ interrupts = <53>;
+ interrupt-parent = <&GIC>;
+ phy_vbus_ext;
+ };
+
+ }; // ps7io@e0000000
+
+ chosen {
+ stdin = &uart1;
+ stdout = &uart1;
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/arm/zybo.dts b/usr/src/boot/sys/boot/fdt/dts/arm/zybo.dts
new file mode 100644
index 0000000000..b386edbc65
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/arm/zybo.dts
@@ -0,0 +1,216 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "zybo";
+ compatible = "digilent,zybo";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&GIC>;
+
+ // cpus {
+ // #address-cells = <1>;
+ // #size-cells = <0>;
+ // cpu@0 {
+ // device-type = "cpu";
+ // model = "ARM Cortex-A9";
+ // };
+ // };
+
+ memory {
+ // First megabyte isn't accessible by all interconnect masters.
+ device_type = "memory";
+ reg = <0x100000 0x1ff00000>; /* 511MB RAM at 0x100000 */
+ };
+
+ // Zynq PS System registers.
+ //
+ ps7sys@f8000000 {
+ device_type = "soc";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xf8000000 0xf10000>;
+
+ // SLCR block
+ slcr: slcr@7000 {
+ compatible = "xlnx,zy7_slcr";
+ reg = <0x0 0x1000>;
+ clock-frequency = <50000000>; // 50Mhz PS_CLK
+ };
+
+ // Interrupt controller
+ GIC: gic {
+ compatible = "arm,gic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0xf01000 0x1000>, // distributer registers
+ <0xf00100 0x0100>; // CPU if registers
+ };
+
+ // L2 cache controller
+ pl310@f02000 {
+ compatible = "arm,pl310";
+ reg = <0xf02000 0x1000>;
+ interrupts = <34>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // Device Config
+ devcfg: devcfg@7000 {
+ compatible = "xlnx,zy7_devcfg";
+ reg = <0x7000 0x1000>;
+ interrupts = <40>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // triple timer counters0,1
+ ttc0: ttc@1000 {
+ compatible = "xlnx,ttc";
+ reg = <0x1000 0x1000>;
+ };
+ ttc1: ttc@2000 {
+ compatible = "xlnx,ttc";
+ reg = <0x2000 0x1000>;
+ };
+
+ // ARM Cortex A9 TWD Timer
+ timer@f00600 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = <325000000>; // 325Mhz
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xf00200 0x100>, // Global Timer Regs
+ <0xf00600 0x20>; // Private Timer Regs
+ interrupts = < 27 29 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ // system watch-dog timer
+ swdt@5000 {
+ device_type = "watchdog";
+ compatible = "xlnx,zy7_wdt";
+ reg = <0x5000 0x1000>;
+ interrupts = <41>;
+ interrupt-parent = <&GIC>;
+ };
+
+ scuwdt@f00620 {
+ device_type = "watchdog";
+ compatible = "arm,mpcore_wdt";
+ reg = <0xf00620 0x20>;
+ interrupts = <30>;
+ interrupt-parent = <&GIC>;
+ reset = <1>;
+ };
+ }; // pssys@f8000000
+
+ // Zynq PS I/O Peripheral registers.
+ //
+ ps7io@e0000000 {
+ device_type = "soc";
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0000000 0x300000>;
+
+ // uart0: uart@0000 {
+ // device_type = "serial";
+ // compatible = "cadence,uart";
+ // reg = <0x0000 0x1000>;
+ // interrupts = <59>;
+ // interrupt-parent = <&GIC>;
+ // clock-frequency = <50000000>;
+ // };
+
+ uart1: uart@1000 {
+ device_type = "serial";
+ compatible = "cadence,uart";
+ reg = <0x1000 0x1000>;
+ interrupts = <82>;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ current-speed = <115200>;
+ };
+
+ gpio: gpio@a000 {
+ compatible = "xlnx,zy7_gpio";
+ reg = <0xa000 0x1000>;
+ interrupts = <52>;
+ interrupt-parent = <&GIC>;
+ };
+
+ // GigE
+ eth0: eth@b000 {
+ // device_type = "network";
+
+ compatible = "cadence,gem";
+ reg = <0xb000 0x1000>;
+ interrupts = <54 55>;
+ interrupt-parent = <&GIC>;
+ ref-clock-num = <0>;
+ };
+
+ // SDIO
+ sdhci0: sdhci@100000 {
+ compatible = "xlnx,zy7_sdhci";
+ reg = <0x100000 0x1000>;
+ interrupts = <56>;
+ interrupt-parent = <&GIC>;
+ max-frequency = <50000000>;
+ };
+
+ // QSPI
+ qspi0: qspi@d000 {
+ compatible = "xlnx,zy7_qspi";
+ reg = <0xd000 0x1000>;
+ interrupts = <51>;
+ interrupt-parent = <&GIC>;
+ spi-clock = <50000000>;
+ ref-clock = <200000000>;
+ };
+
+ // USB
+ ehci0: ehci@2000 {
+ compatible = "xlnx,zy7_ehci";
+ reg = <0x2000 0x1000>;
+ interrupts = <53>;
+ interrupt-parent = <&GIC>;
+ };
+
+ }; // ps7io@e0000000
+
+ chosen {
+ stdin = &uart1;
+ stdout = &uart1;
+ };
+};
+
diff --git a/usr/src/boot/sys/boot/fdt/dts/bindings-gpio.txt b/usr/src/boot/sys/boot/fdt/dts/bindings-gpio.txt
new file mode 100644
index 0000000000..b13078aeb0
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/bindings-gpio.txt
@@ -0,0 +1,101 @@
+$FreeBSD$
+
+GPIO configuration.
+===================
+
+1. Properties for GPIO Controllers
+
+1.1 #gpio-cells
+
+Property: #gpio-cells
+
+Value type: <u32>
+
+Description: The #gpio-cells property defines the number of cells required
+ to encode a gpio specifier.
+
+
+1.2 gpio-controller
+
+Property: gpio-controller
+
+Value type: <empty>
+
+Description: The presence of a gpio-controller property defines a node as a
+ GPIO controller node.
+
+
+1.3 pin-count
+
+Property: pin-count
+
+Value type: <u32>
+
+Description: The pin-count property defines the number of GPIO pins.
+
+
+1.4 Example
+
+ GPIO: gpio@10100 {
+ #gpio-cells = <3>;
+ compatible = "mrvl,gpio";
+ reg = <0x10100 0x20>;
+ gpio-controller;
+ interrupts = <6 7 8 9>;
+ interrupt-parent = <&PIC>;
+ pin-count = <50>
+ };
+
+2. Properties for GPIO consumer nodes.
+
+2.1 gpios
+
+Property: gpios
+
+Value type: <prop-encoded-array> encoded as arbitrary number of GPIO
+ specifiers.
+
+Description: The gpios property of a device node defines the GPIO or GPIOs
+ that are used by the device. The value of the gpios property
+ consists of an arbitrary number of GPIO specifiers.
+
+ The first cell of the GPIO specifier is phandle of the node's
+ parent GPIO controller and remaining cells are defined by the
+ binding describing the GPIO parent, typically include
+ information like pin number, direction and various flags.
+
+Example:
+ gpios = <&GPIO 0 1 0 /* GPIO[0]: IN, NONE */
+ &GPIO 1 2 0>; /* GPIO[1]: OUT, NONE */
+
+
+3. "mrvl,gpio" controller GPIO specifier
+
+ <phandle pin dir flags>
+
+
+pin: 0-MAX GPIO pin number.
+
+dir:
+ 1 IN Input direction.
+ 2 OUT Output direction.
+
+flags:
+ 0x0000---- IN_NONE
+ 0x0001---- IN_POL_LOW Polarity low (active-low).
+ 0x0002---- IN_IRQ_EDGE Interrupt, edge triggered.
+ 0x0004---- IN_IRQ_LEVEL Interrupt, level triggered.
+
+ 0x----0000 OUT_NONE
+ 0x----0001 OUT_BLINK Blink on the pin.
+ 0x----0002 OUT_OPEN_DRAIN Open drain output line.
+ 0x----0004 OUT_OPEN_SRC Open source output line.
+
+
+Example:
+ gpios = <&GPIO 0 1 0x00000000 /* GPIO[0]: IN */
+ &GPIO 1 2 0x00000000 /* GPIO[1]: OUT */
+ &GPIO 2 1 0x00020000 /* GPIO[2]: IN, IRQ (edge) */
+ &GPIO 3 1 0x00040000 /* GPIO[3]: IN, IRQ (level) */
+ ...
+ &GPIO 10 2 0x00000001>; /* GPIO[10]: OUT, blink */
diff --git a/usr/src/boot/sys/boot/fdt/dts/bindings-localbus.txt b/usr/src/boot/sys/boot/fdt/dts/bindings-localbus.txt
new file mode 100644
index 0000000000..d960fefcf7
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/bindings-localbus.txt
@@ -0,0 +1,83 @@
+$FreeBSD$
+
+Marvell Device bus (localbus) configuration.
+============================================
+
+1. Properties for localbus nodes
+
+1.1 ranges
+
+Property: ranges
+
+Value type: <prop-encoded-array> encoded as arbitrary number of localbus
+ nodes specifiers.
+
+Description: ranges property defines values used for mapping devices
+ connected to localbus, in Marvell devices it is used also for
+ setting decoding windows.
+
+ a) child node address-cells:
+ - first cell: number of bank (chip select)
+ - second cell: (Marvell devices) Target ID for decoding
+ windows setup
+
+ b) parent node address cells:
+ - address offset: used with parent's node base address to
+ specify base address of mapped device
+
+ c) child node size-cells:
+ - size: defines amount of memory that should be reserved for
+ device
+
+1.2 bank-count
+
+Property: bank-count
+
+Value type: <u32>
+
+Description: The bank_count property defines maximum number of banks on
+ localbus node. Bank is most often interpreted as device chip
+ select, but may also describe another device (e.g. SPI flash).
+
+1.3 Example
+
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <5>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xb2200000 0x00100000
+ 0x1 0x3e 0xb2100000 0x00100000
+ 0x2 0x3d 0xb0000000 0x02000000
+ 0x3 0x3b 0xb2000000 0x00100000>;
+ };
+
+2. Properties for localbus consumer nodes:
+
+2.1 reg
+
+Property: reg
+
+Value type: <prop-encoded-array>
+
+Description: A standard property required for localbus child nodes. Defines
+ the device memory region.
+
+ a) first cell: number of bank (chip select)
+
+ b) address offset: used with address offset from parent's ranges
+ for corresponding bank to specify base address of
+ the device
+
+ c) size: defines size of the device memory region
+
+2.2 Example
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ };
diff --git a/usr/src/boot/sys/boot/fdt/dts/bindings-mpp.txt b/usr/src/boot/sys/boot/fdt/dts/bindings-mpp.txt
new file mode 100644
index 0000000000..5da776e43c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/bindings-mpp.txt
@@ -0,0 +1,50 @@
+$FreeBSD$
+
+* Multi purpose pin (MPP) configuration.
+
+Required properties:
+
+- pin-map : array of pin configurations. Each pin is defined by 2 cells,
+ respectively: <pin> <function>. Pins not specified in the pin-map property
+ are assumed to have default value of <function> = 0, which means GPIO.
+
+ - pin : pin number.
+
+ - function : function ID of the pin according to the assignment tables in
+ User Manual. Each pin can have many possible functions depending on the
+ MPP unit incarnation.
+
+- pin-count: number of the physical MPP connections on the SOC (depending on
+ the model it can be 24-50, or possibly else in future devices).
+
+Example:
+
+ mpp@10000 {
+ #pin-cells = <2>;
+ compatible = "mrvl,mpp";
+ reg = <0x10000 0x34>;
+ pin-count= <50>;
+ pin-map = <
+ 0 1 /* MPP[0]: NF_IO[2] */
+ 1 1 /* MPP[1]: NF_IO[3] */
+ 2 1 /* MPP[2]: NF_IO[4] */
+ 3 1 /* MPP[3]: NF_IO[5] */
+ 4 1 /* MPP[4]: NF_IO[6] */
+ 5 1 /* MPP[5]: NF_IO[7] */
+ 6 1 /* MPP[6]: SYSRST_OUTn */
+ 7 2 /* MPP[7]: SPI_SCn */
+ 8 1 /* MPP[8]: TW_SDA */
+ 9 1 /* MPP[9]: TW_SCK */
+ 10 3 /* MPP[10]: UA0_TXD */
+ 11 3 /* MPP[11]: UA0_RXD */
+ 12 1 /* MPP[12]: SD_CLK */
+ 13 1 /* MPP[13]: SD_CMD */
+ 14 1 /* MPP[14]: SD_D[0] */
+ 15 1 /* MPP[15]: SD_D[1] */
+ 16 1 /* MPP[16]: SD_D[2] */
+ 17 1 /* MPP[17]: SD_D[3] */
+ 18 1 /* MPP[18]: NF_IO[0] */
+ 19 1 /* MPP[19]: NF_IO[1] */
+ 20 5 /* MPP[20]: SATA1_AC */
+ 21 5 >; /* MPP[21]: SATA0_AC */
+ };
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/Makefile b/usr/src/boot/sys/boot/fdt/dts/mips/Makefile
new file mode 100644
index 0000000000..03d156d947
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+DTS!=ls *.dts
+
+all: test-dts
+
+.include <bsd.init.mk>
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/beri-netfpga.dts b/usr/src/boot/sys/boot/fdt/dts/mips/beri-netfpga.dts
new file mode 100644
index 0000000000..f272f9cfa5
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/beri-netfpga.dts
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2012-2013 Robert N. M. Watson
+ * Copyright (c) 2013 SRI International
+ * Copyright (c) 2013-2014 Bjoern A. Zeeb
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-11-C-0249)
+ * ("MRC2"), as part of the DARPA MRC research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/*
+ * Device names here have been largely made up on the spot, especially for the
+ * "compatible" strings, and might want to be revised.
+ */
+
+/ {
+ model = "SRI/Cambridge Beri (NetFPGA)";
+ compatible = "sri-cambridge,beri-netfpga";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * Secondary CPUs all start disabled and use the
+ * spin-table enable method. cpu-release-addr must be
+ * specified for each cpu other than cpu@0. Values of
+ * cpu-release-addr grow down from 0x100000 (kernel).
+ */
+ status = "disabled";
+ enable-method = "spin-table";
+
+ cpu@0 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <0 1>;
+ status = "okay";
+ };
+
+/*
+ cpu@1 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <1 1>;
+ // XXX: should we need cached prefix?
+ cpu-release-addr = <0xffffffff 0x800fffe0>;
+ };
+*/
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0FFFFFFF>; // ~256M at 0x0
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+
+ /*
+ * Declare mips,mips4k since BERI doesn't (yet) have a PIC, so
+ * we use mips4k coprocessor 0 interrupt management directly.
+ */
+ compatible = "simple-bus", "mips,mips4k";
+ ranges = <>;
+
+ beripic: beripic@7f804000 {
+ compatible = "sri-cambridge,beri-pic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x7f804000 0x400
+ 0x7f806000 0x10
+ 0x7f806080 0x10
+ 0x7f806100 0x10>;
+ interrupts = <0 1 2 3 4>;
+ hard-interrupt-sources = <64>;
+ soft-interrupt-sources = <64>;
+ };
+
+ serial0: serial@7f000000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f000000 0x40>;
+/*
+ interrupts = <0>;
+ interrupt-parent = <&beripic>;
+*/
+ };
+
+/*
+ serial0: serial@7f002100 {
+ compatible = "ns16550";
+ reg = <0x7f002100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <100000000>;
+ interrupts = <8>;
+ interrupt-parent = <&beripic>;
+ };
+*/
+
+ ethernet@7f005000 {
+ compatible = "netfpag10g,nf10bmac";
+ // LOOP, TX, RX, INTR
+ reg = <0x7f005000 0x20
+ 0x7f005020 0x30
+ 0x7f005050 0x30
+ 0x7f005100 0x10>;
+ // RX
+ interrupts = <1>;
+ interrupt-parent = <&beripic>;
+ };
+ };
+
+ aliases {
+ serial0 = &serial0;
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ bootargs = "-v";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/beri-sim.dts b/usr/src/boot/sys/boot/fdt/dts/mips/beri-sim.dts
new file mode 100644
index 0000000000..5e0ab1976b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/beri-sim.dts
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2012-2013 Robert N. M. Watson
+ * Copyright (c) 2013 SRI International
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/*
+ * Device names here have been largely made up on the spot, especially for the
+ * "compatible" strings, and might want to be revised.
+ *
+ * For now, use 32-bit addressing as our Avalon bus is 32-bit. However, in
+ * the future, we should likely change to 64-bit.
+ */
+
+/ {
+ model = "SRI/Cambridge BERI simulation";
+ compatible = "sri-cambridge,beri-sim";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * Secondary CPUs all start disabled and use the
+ * spin-table enable method. cpu-release-addr must be
+ * specified for each cpu other than cpu@0. Values of
+ * cpu-release-addr grow down from 0x100000 (kernel).
+ */
+ status = "disabled";
+ enable-method = "spin-table";
+
+ cpu@0 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <0 1>;
+ status = "okay";
+ };
+
+/*
+ cpu@1 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <1 1>;
+ // XXX: should we need cached prefix?
+ cpu-release-addr = <0xffffffff 0x800fffe0>;
+ };
+*/
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x4000000>; // 64M at 0x0
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+
+ /*
+ * Declare mips,mips4k since BERI doesn't (yet) have a PIC, so
+ * we use mips4k coprocessor 0 interrupt management directly.
+ */
+ compatible = "simple-bus", "mips,mips4k";
+ ranges = <>;
+
+ beripic0: beripic@7f804000 {
+ compatible = "sri-cambridge,beri-pic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x7f804000 0x400
+ 0x7f806000 0x10
+ 0x7f806080 0x10
+ 0x7f806100 0x10>;
+ interrupts = <0 1 2 3 4>;
+ hard-interrupt-sources = <64>;
+ soft-interrupt-sources = <64>;
+ };
+
+ serial@7f000000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f000000 0x40>;
+ interrupts = <0>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ serial@7f001000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f001000 0x40>;
+ };
+
+ serial@7f002000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f002000 0x40>;
+ };
+
+ virtio_mmio_platform0: virtio_mmio_platform@0 {
+ compatible = "beri,virtio_mmio_platform";
+ interrupts = <1>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ virtio_block@7f020000 {
+ compatible = "virtio,mmio";
+ reg = <0x7f020000 0x1000>;
+ platform = <&virtio_mmio_platform0>;
+ };
+
+ sdcard@7f008000 {
+ compatible = "altera,sdcard_11_2011";
+ reg = <0x7f008000 0x400>;
+ };
+
+ avgen@0x7f00a000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f00a000 0x14>;
+ sri-cambridge,width = <4>;
+ sri-cambridge,fileio = "rw";
+ sri-cambridge,devname = "berirom";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/beripad-de4.dts b/usr/src/boot/sys/boot/fdt/dts/mips/beripad-de4.dts
new file mode 100644
index 0000000000..287c2306d1
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/beripad-de4.dts
@@ -0,0 +1,258 @@
+/*-
+ * Copyright (c) 2012-2013 Robert N. M. Watson
+ * Copyright (c) 2013 SRI International
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/*
+ * Device names here have been largely made up on the spot, especially for the
+ * "compatible" strings, and might want to be revised.
+ *
+ * For now, use 32-bit addressing as our Avalon bus is 32-bit. However, in
+ * the future, we should likely change to 64-bit.
+ */
+
+/ {
+ model = "SRI/Cambridge BeriPad (DE4)";
+ compatible = "sri-cambridge,beripad-de4";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * Secondary CPUs all start disabled and use the
+ * spin-table enable method. cpu-release-addr must be
+ * specified for each cpu other than cpu@0. Values of
+ * cpu-release-addr grow down from 0x100000 (kernel).
+ */
+ status = "disabled";
+ enable-method = "spin-table";
+
+ cpu@0 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <0 1>;
+ status = "okay";
+ };
+
+/*
+ cpu@1 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <1 1>;
+ // XXX: should we need cached prefix?
+ cpu-release-addr = <0xffffffff 0x800fffe0>;
+ };
+*/
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // 1G at 0x0
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+
+ /*
+ * Declare mips,mips4k since BERI doesn't (yet) have a PIC, so
+ * we use mips4k coprocessor 0 interrupt management directly.
+ */
+ compatible = "simple-bus", "mips,mips4k";
+ ranges = <>;
+
+ beripic0: beripic@7f804000 {
+ compatible = "sri-cambridge,beri-pic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x7f804000 0x400
+ 0x7f806000 0x10
+ 0x7f806080 0x10
+ 0x7f806100 0x10>;
+ interrupts = <0 1 2 3 4>;
+ hard-interrupt-sources = <64>;
+ soft-interrupt-sources = <64>;
+ };
+
+ serial@7f002100 {
+ compatible = "ns16550";
+ reg = <0x7f002100 0x20>;
+ reg-shift = <2>;
+ clock-frequency = <50000000>;
+ interrupts = <6>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ serial@7f000000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f000000 0x40>;
+ interrupts = <0>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ serial@7f001000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f001000 0x40>;
+ };
+
+ serial@7f002000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f002000 0x40>;
+ };
+
+ sdcard@7f008000 {
+ compatible = "altera,sdcard_11_2011";
+ reg = <0x7f008000 0x400>;
+ };
+
+ led@7f006000 {
+ compatible = "sri-cambridge,de4led";
+ reg = <0x7f006000 0x1>;
+ };
+
+ /*
+ * XXX-BZ keep flash before ethernet so that atse can read the
+ * Ethernet addresses for now.
+ */
+ flash@74000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x74000000 0x4000000>;
+
+ /* Board configuration */
+ partition@0 {
+ reg = <0x0 0x20000>;
+ label = "config";
+ };
+
+ /* Power up FPGA image */
+ partition@20000 {
+ reg = <0x20000 0xc00000>;
+ label = "fpga0";
+ };
+
+ /* Secondary FPGA image (on RE_CONFIGn button) */
+ partition@C20000 {
+ reg = <0xc20000 0xc00000>;
+ label = "fpga1";
+ };
+
+ /* Space for operating system use */
+ partition@1820000 {
+ reg = <0x1820000 0x027c0000>;
+ label = "os";
+ };
+
+ /* Second stage bootloader */
+ parition@3fe0000 {
+ reg = <0x3fe0000 0x20000>;
+ label = "boot";
+ };
+ };
+
+ ethernet@7f007000 {
+ compatible = "altera,atse";
+ // MAC, RX+RXC, TX+TXC.
+ reg = <0x7f007000 0x400
+ 0x7f007500 0x8
+ 0x7f007520 0x20
+ 0x7f007400 0x8
+ 0x7f007420 0x20>;
+ // RX, TX
+ interrupts = <1 2>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ ethernet@7f005000 {
+ compatible = "altera,atse";
+ // MAC, RX+RXC, TX+TXC.
+ reg = <0x7f005000 0x400
+ 0x7f005500 0x8
+ 0x7f005520 0x20
+ 0x7f005400 0x8
+ 0x7f005420 0x20>;
+ // RX, TX
+ interrupts = <11 12>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ touchscreen@70400000 {
+ compatible = "sri-cambridge,mtl";
+ panel-size = < 800 480 >;
+ reg = <0x70400000 0x1000
+ 0x70000000 0x177000
+ 0x70177000 0x2000>;
+ };
+
+ usb@0x7f100000 {
+ compatible = "nxp,usb-isp1761";
+ reg = <0x7f100000 0x40000
+ 0x7f140000 0x4>;
+ // IRQ 4 is DC, IRQ 5 is HC.
+ interrupts = <4 5>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ avgen@0x7f009000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f009000 0x2>;
+ sri-cambridge,width = <1>;
+ sri-cambridge,fileio = "r";
+ sri-cambridge,devname = "de4bsw";
+ };
+
+ avgen@0x7f00a000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f00a000 0x14>;
+ sri-cambridge,width = <4>;
+ sri-cambridge,fileio = "rw";
+ sri-cambridge,devname = "berirom";
+ };
+
+ avgen@0x7f00c000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f00c000 0x8>;
+ sri-cambridge,width = <4>;
+ sri-cambridge,fileio = "rw";
+ sri-cambridge,devname = "de4tempfan";
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/beripad-sockit.dts b/usr/src/boot/sys/boot/fdt/dts/mips/beripad-sockit.dts
new file mode 100644
index 0000000000..ad9e4acfbe
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/beripad-sockit.dts
@@ -0,0 +1,219 @@
+/*-
+ * Copyright (c) 2012-2013 Robert N. M. Watson
+ * Copyright (c) 2013-2014 SRI International
+ * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/*
+ * Device names here have been largely made up on the spot, especially for the
+ * "compatible" strings, and might want to be revised.
+ */
+
+/ {
+ model = "SRI/Cambridge BeriPad (SoCKit)";
+ compatible = "sri-cambridge,beripad-sockit";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * Secondary CPUs all start disabled and use the
+ * spin-table enable method. cpu-release-addr must be
+ * specified for each cpu other than cpu@0. Values of
+ * cpu-release-addr grow down from 0x100000 (kernel).
+ */
+ status = "disabled";
+ enable-method = "spin-table";
+
+ cpu@0 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <0 1>;
+ status = "okay";
+ };
+
+/*
+ cpu@1 {
+ device-type = "cpu";
+ compatible = "sri-cambridge,beri";
+
+ reg = <1 1>;
+ // XXX: should we need cached prefix?
+ cpu-release-addr = <0xffffffff 0x800fffe0>;
+ };
+*/
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x10000000>; /* 256MB at 0x0 */
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ /*
+ * Declare mips,mips4k since BERI doesn't (yet) have a PIC, so
+ * we use mips4k coprocessor 0 interrupt management directly.
+ */
+ compatible = "simple-bus", "mips,mips4k";
+ /* ranges = <>; */
+
+ beripic0: beripic@7f804000 {
+ compatible = "sri-cambridge,beri-pic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x0 0x7f804000 0x0 0x400
+ 0x0 0x7f806000 0x0 0x10
+ 0x0 0x7f806080 0x0 0x10
+ 0x0 0x7f806100 0x0 0x10>;
+ interrupts = <0 1 2 3 4>;
+ hard-interrupt-sources = <64>;
+ soft-interrupt-sources = <64>;
+ };
+
+ pio0: pio@7f020000 {
+ compatible = "altr,pio";
+ reg = <0x0 0x7f020000 0x0 0x1000>; /* send */
+ interrupts = <4>; /* not used */
+ interrupt-parent = <&beripic0>;
+ };
+
+ pio1: pio@7f021000 {
+ compatible = "altr,pio";
+ reg = <0x0 0x7f021000 0x0 0x1000>; /* recv */
+ interrupts = <10>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ pio2: pio@7f022000 {
+ compatible = "altr,pio";
+ reg = <0x0 0x7f022000 0x0 0x1000>; /* send */
+ interrupts = <5>; /* not used */
+ interrupt-parent = <&beripic0>;
+ };
+
+ pio3: pio@7f023000 {
+ compatible = "altr,pio";
+ reg = <0x0 0x7f023000 0x0 0x1000>; /* recv */
+ interrupts = <11>;
+ interrupt-parent = <&beripic0>;
+ };
+
+ virtio_mmio_platform0: virtio_mmio_platform@0 {
+ compatible = "beri,virtio_mmio_platform";
+ pio-send = <&pio0>;
+ pio-recv = <&pio1>;
+ };
+
+ virtio_mmio_platform1: virtio_mmio_platform@1 {
+ compatible = "beri,virtio_mmio_platform";
+ pio-send = <&pio2>;
+ pio-recv = <&pio3>;
+ };
+
+ virtio_block@200001000 {
+ compatible = "virtio,mmio";
+ reg = <0x2 0x1000 0x0 0x1000>;
+ platform = <&virtio_mmio_platform0>;
+ status = "okay";
+ };
+
+ virtio_net@200002000 {
+ compatible = "virtio,mmio";
+ reg = <0x2 0x2000 0x0 0x1000>;
+ platform = <&virtio_mmio_platform1>;
+ status = "okay";
+ };
+
+ serial@7f000000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x0 0x7f000000 0x0 0x40>;
+ interrupts = <0>;
+ interrupt-parent = <&beripic0>;
+ };
+
+/*
+ serial@7f001000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f001000 0x40>;
+ };
+
+ serial@7f002000 {
+ compatible = "altera,jtag_uart-11_0";
+ reg = <0x7f002000 0x40>;
+ };
+*/
+
+/*
+ led@7f006000 {
+ compatible = "sri-cambridge,de4led";
+ reg = <0x7f006000 0x1>;
+ };
+*/
+
+/*
+ avgen@0x7f009000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f009000 0x2>;
+ sri-cambridge,width = <1>;
+ sri-cambridge,fileio = "r";
+ sri-cambridge,devname = "de4bsw";
+ };
+*/
+
+/*
+ berirom@0x7f00a000 {
+ compatible = "sri-cambridge,berirom";
+ reg = <0x7f00a000 0x1000>;
+ };
+*/
+
+/*
+ avgen@0x7f00c000 {
+ compatible = "sri-cambridge,avgen";
+ reg = <0x7f00c000 0x8>;
+ sri-cambridge,width = <4>;
+ sri-cambridge,fileio = "rw";
+ sri-cambridge,devname = "de4tempfan";
+ };
+*/
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/mips/xlp-basic.dts b/usr/src/boot/sys/boot/fdt/dts/mips/xlp-basic.dts
new file mode 100644
index 0000000000..19f0801768
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/mips/xlp-basic.dts
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Netlogic Microsystems XLP8xx Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "netl,XLP8XX";
+ compatible = "XLP8XX";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &serial0;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x18000000 0x04000000>;
+ bus-frequency = <0>;
+
+ pic: pic@4000 {
+ compatible = "netlogic,xlp-pic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x4000 0x200>;
+ };
+
+ serial0: serial@30100 {
+ compatible = "ns16550";
+ reg = <0x30100 0x200>;
+ reg-shift = <2>;
+ current-speed = <115200>;
+ clock-frequency = <133000000>;
+ interrupt-parent = <&pic>;
+ interrupts = <17>;
+ };
+
+ pci0: pci@18000000 {
+ compatible = "netlogic,xlp-pci", "pci";
+ reg = <0xd0000000 0x10000000>;
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ cpumask = <0xffffffff>;
+ bootargs = "-v";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/Makefile b/usr/src/boot/sys/boot/fdt/dts/powerpc/Makefile
new file mode 100644
index 0000000000..03d156d947
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+DTS!=ls *.dts
+
+all: test-dts
+
+.include <bsd.init.mk>
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8555cds.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8555cds.dts
new file mode 100644
index 0000000000..34991baaef
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8555cds.dts
@@ -0,0 +1,443 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006, 2008 Freescale Semiconductor Inc. All rights reserved
+ *
+ * Neither the name of Freescale Semiconductor, Inc nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Freescale hereby publishes it under the following licenses:
+ *
+ * BSD License
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * GNU General Public License, version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * You may select the license of your choice.
+ *------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "MPC8555CDS";
+ compatible = "MPC8555CDS", "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8555@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x10000000>; // 256M at 0x0
+ };
+
+ localbus@e0005000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,lbc", "fsl,elbc";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0x0 0x0 0xff800000 0x00800000
+ 0x1 0x0 0xff000000 0x00800000
+ 0x2 0x0 0xf8000000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00800000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nor@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x1 0x0 0x00800000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ rtc@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "dallas,ds1553";
+ reg = <0x2 0x0 0x00008000>;
+ bank-width = <1>;
+ device-width = <1>;
+ };
+ };
+
+ soc8555@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <0>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,8555-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,8555-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8555-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x7e>;
+ fsl,descriptor-types-mask = <0x01010ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ cpm@80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8555-cpm", "fsl,cpm2";
+ reg = <0x80000 0x20000>;
+ interrupts = <46 2>;
+ interrupt-parent = <&mpic>;
+ };
+ };
+
+ pci0: pci@e0008000 {
+ interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x11 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1
+ 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+ 0x1000000 0x0 0x0 0xfee00000 0x0 0x00010000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0008000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+
+ i8259@19000 {
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <0x19000 0x0 0x0 0x0 0x1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <1>;
+ interrupt-parent = <&pci0>;
+ };
+ };
+
+ pci1: pci@e0009000 {
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x90000000 0x90000000 0x0 0x10000000
+ 0x1000000 0x0 0x0 0xfee10000 0x0 0x00010000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0009000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8572ds.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8572ds.dts
new file mode 100644
index 0000000000..67f0d66f86
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/mpc8572ds.dts
@@ -0,0 +1,895 @@
+/*
+ * MPC8572 DS Device Tree Source
+ *
+ * Copyright 2007-2009 Freescale Semiconductor Inc. All rights reserved
+ *
+ * Neither the name of Freescale Semiconductor, Inc nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Freescale hereby publishes it under the following licenses:
+ *
+ * BSD License
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * GNU General Public License, version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * You may select the license of your choice.
+ *------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/ {
+ model = "fsl,MPC8572DS";
+ compatible = "fsl,MPC8572DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8572@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,8572@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@ffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus";
+ reg = <0 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ reg = <0x0 0x03000000>;
+ label = "ramdisk-nor";
+ read-only;
+ };
+
+ partition@3000000 {
+ reg = <0x03000000 0x00e00000>;
+ label = "diagnostic-nor";
+ read-only;
+ };
+
+ partition@3e00000 {
+ reg = <0x03e00000 0x00200000>;
+ label = "dink-nor";
+ read-only;
+ };
+
+ partition@4000000 {
+ reg = <0x04000000 0x00400000>;
+ label = "kernel-nor";
+ read-only;
+ };
+
+ partition@4400000 {
+ reg = <0x04400000 0x03b00000>;
+ label = "jffs2-nor";
+ };
+
+ partition@7f00000 {
+ reg = <0x07f00000 0x00080000>;
+ label = "dtb-nor";
+ read-only;
+ };
+
+ partition@7f80000 {
+ reg = <0x07f80000 0x00080000>;
+ label = "u-boot-nor";
+ read-only;
+ };
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ reg = <0x0 0x02000000>;
+ label = "u-boot-nand";
+ read-only;
+ };
+
+ partition@2000000 {
+ reg = <0x02000000 0x10000000>;
+ label = "jffs2-nand";
+ };
+
+ partition@12000000 {
+ reg = <0x12000000 0x08000000>;
+ label = "ramdisk-nand";
+ read-only;
+ };
+
+ partition@1a000000 {
+ reg = <0x1a000000 0x04000000>;
+ label = "kernel-nand";
+ };
+
+ partition@1e000000 {
+ reg = <0x1e000000 0x01000000>;
+ label = "dtb-nand";
+ read-only;
+ };
+
+ partition@1f000000 {
+ reg = <0x1f000000 0x21000000>;
+ label = "reserved-nand";
+ };
+ };
+
+ nand@4,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x4 0x0 0x40000>;
+ };
+
+ nand@5,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x5 0x0 0x40000>;
+ };
+
+ nand@6,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x6 0x0 0x40000>;
+ };
+ };
+
+ soc8572@ffe00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0 0xffe00000 0x100000>;
+ bus-frequency = <0>; // Filled out by uboot.
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8572-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ memory-controller@6000 {
+ compatible = "fsl,mpc8572-memory-controller";
+ reg = <0x6000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8572-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x100000>; // L2, 1M
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@c300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+ reg = <0xc300 0x4>;
+ ranges = <0x0 0xc100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <76 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <77 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <78 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <79 2>;
+ };
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ ptp_timer: ptimer@24e00 {
+ compatible = "fsl,gianfar-ptp-timer";
+ reg = <0x24e00 0xb0>;
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ ptimer-handle = < &ptp_timer >;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x3>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ ptimer-handle = < &ptp_timer >;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <2>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <31 2 32 2 33 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ ptimer-handle = < &ptp_timer >;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <3>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <37 2 38 2 39 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,mpc8572-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ power@e0070{
+ compatible = "fsl,mpc8548-pmc";
+ reg = <0xe0070 0x14>;
+ };
+
+ timer@41100 {
+ compatible = "fsl,mpic-global-timer";
+ reg = <0x41100 0x204>;
+ interrupts = <0xf7 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ msi@41600 {
+ compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
+ "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x9fe>;
+ fsl,descriptor-types-mask = <0x3ab0ebf>;
+ };
+
+ /* PME (pattern-matcher) */
+ pme@10000 {
+ device_type = "pme";
+ compatible = "pme8572";
+ reg = <0x10000 0x5000>;
+ interrupts = <0x39 0x2 0x40 0x2 0x41 0x2 0x42 0x2 0x43 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+ };
+
+ pci0: pcie@ffe08000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe08000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xfee20000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 0x8900 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8900 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8900 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8900 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 0x9100 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9100 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9100 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9100 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 0x9200 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9200 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9200 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9200 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 0x9300 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9300 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9300 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9300 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 0x9400 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9400 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9400 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9400 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 0x9500 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9500 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9500 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9500 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 0x9600 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9600 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9600 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9600 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 0x9700 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9700 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9700 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9700 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ // IDSEL 0x1c USB
+ 0xe000 0x0 0x0 0x1 &i8259 0xc 0x2
+ 0xe100 0x0 0x0 0x2 &i8259 0x9 0x2
+ 0xe200 0x0 0x0 0x3 &i8259 0xa 0x2
+ 0xe300 0x0 0x0 0x4 &i8259 0xb 0x2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+ 0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+ 0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+
+ >;
+
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ uli1575@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ isa@1e {
+ device_type = "isa";
+ #interrupt-cells = <2>;
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0x0 0x0 0x0 0x0>;
+ ranges = <0x1 0x0 0x1000000 0x0 0x0
+ 0x1000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <0x1 0x20 0x2
+ 0x1 0xa0 0x2
+ 0x1 0x4d0 0x2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <9 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent =
+ <&i8259>;
+
+ keyboard@0 {
+ reg = <0x0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <0x1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible = "pnpPNP,b00";
+ reg = <0x1 0x70 0x2>;
+ };
+
+ gpio@400 {
+ reg = <0x1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci1: pcie@ffe09000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0x90000000 0 0x90000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xfee10000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1
+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1
+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0x90000000
+ 0x2000000 0x0 0x90000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci2: pcie@ffe0a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xfee00000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <26 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p1020rdb.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/p1020rdb.dts
new file mode 100644
index 0000000000..ec5118ce0f
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p1020rdb.dts
@@ -0,0 +1,627 @@
+/*
+ * P1020 RDB Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/dts-v1/;
+
+/ {
+ model = "fsl,P1020";
+ compatible = "fsl,P1020RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,P1020@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,P1020@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@ffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
+ reg = <0 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xffa00000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR (RO) Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR (RO) DTB Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR (RW) JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR (RO) U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND (RW) Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+
+ };
+
+ soc@ffe00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,p1020-immr", "simple-bus";
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ bus-frequency = <0>; // Filled out by uboot.
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,p1020-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <16 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,p1020-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ spi@7000 {
+ cell-index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,espi";
+ reg = <0x7000 0x1000>;
+ interrupts = <59 0x2>;
+ interrupt-parent = <&mpic>;
+ mode = "cpu";
+
+ fsl_m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,espi-flash";
+ reg = <0>;
+ linux,modalias = "fsl_m25p80";
+ modal = "s25sl128b";
+ spi-max-frequency = <50000000>;
+ mode = <0>;
+
+ partition@0 {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "SPI (RO) DTB Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@500000 {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "SPI (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@900000 {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "SPI (RW) JFFS2 RFS";
+ };
+ };
+ };
+
+ gpio: gpio-controller@f000 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8572-gpio";
+ reg = <0xf000 0x100>;
+ interrupts = <47 0x2>;
+ interrupt-parent = <&mpic>;
+ gpio-controller;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,p1020-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2,256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ mdio@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-mdio";
+ reg = <0x24000 0x1000 0xb0030 0x4>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+ };
+
+ mdio@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-tbi";
+ reg = <0x25000 0x1000 0xb1030 0x4>;
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@b0000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+
+ queue-group@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb0000 0x1000>;
+ interrupts = <29 2 30 2 34 2>;
+ };
+
+ queue-group@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb4000 0x1000>;
+ interrupts = <17 2 18 2 24 2>;
+ };
+ };
+
+ enet1: ethernet@b1000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+
+ queue-group@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb1000 0x1000>;
+ interrupts = <35 2 36 2 40 2>;
+ };
+
+ queue-group@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb5000 0x1000>;
+ interrupts = <51 2 52 2 67 2>;
+ };
+ };
+
+ enet2: ethernet@b2000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+
+ queue-group@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb2000 0x1000>;
+ interrupts = <31 2 32 2 33 2>;
+ };
+
+ queue-group@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb6000 0x1000>;
+ interrupts = <25 2 26 2 27 2>;
+ };
+ };
+
+ usb@22000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-usb2-dr";
+ reg = <0x22000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <28 0x2>;
+ phy_type = "ulpi";
+ };
+
+ /* USB2 is shared with localbus, so it must be disabled
+ by default. We can't put 'status = "disabled";' here
+ since U-Boot doesn't clear the status property when
+ it enables USB2. OTOH, U-Boot does create a new node
+ when there isn't any. So, just comment it out.
+ usb@23000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-usb2-dr";
+ reg = <0x23000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <46 0x2>;
+ phy_type = "ulpi";
+ };
+ */
+
+ sdhci@2e000 {
+ compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0xbfe>;
+ fsl,descriptor-types-mask = <0x3ab0ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi@41600 {
+ compatible = "fsl,p1020-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,p1020-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p2020ds.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2020ds.dts
new file mode 100644
index 0000000000..7823429dc9
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2020ds.dts
@@ -0,0 +1,754 @@
+/*
+ * P2020 DS Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * Neither the name of Freescale Semiconductor, Inc nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Freescale hereby publishes it under the following licenses:
+ *
+ * BSD License
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * GNU General Public License, version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * You may select the license of your choice.
+ *------------------------------------------------------------------
+ */
+/* $FreeBSD$ */
+
+/dts-v1/;
+/ {
+ model = "fsl,P2020";
+ compatible = "fsl,P2020DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,P2020@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,P2020@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@ffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc", "simple-bus";
+ reg = <0 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+ 0x1 0x0 0x0 0xe0000000 0x08000000
+ 0x2 0x0 0x0 0xffa00000 0x00040000
+ 0x3 0x0 0x0 0xffdf0000 0x00008000
+ 0x4 0x0 0x0 0xffa40000 0x00040000
+ 0x5 0x0 0x0 0xffa80000 0x00040000
+ 0x6 0x0 0x0 0xffac0000 0x00040000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ ramdisk@0 {
+ reg = <0x0 0x03000000>;
+ read-only;
+ };
+
+ diagnostic@3000000 {
+ reg = <0x03000000 0x00e00000>;
+ read-only;
+ };
+
+ dink@3e00000 {
+ reg = <0x03e00000 0x00200000>;
+ read-only;
+ };
+
+ kernel@4000000 {
+ reg = <0x04000000 0x00400000>;
+ read-only;
+ };
+
+ jffs2@4400000 {
+ reg = <0x04400000 0x03b00000>;
+ };
+
+ dtb@7f00000 {
+ reg = <0x07f00000 0x00080000>;
+ read-only;
+ };
+
+ u-boot@7f80000 {
+ reg = <0x07f80000 0x00080000>;
+ read-only;
+ };
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ u-boot@0 {
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ jffs2@2000000 {
+ reg = <0x02000000 0x10000000>;
+ };
+
+ ramdisk@12000000 {
+ reg = <0x12000000 0x08000000>;
+ read-only;
+ };
+
+ kernel@1a000000 {
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ dtb@1e000000 {
+ reg = <0x1e000000 0x01000000>;
+ read-only;
+ };
+
+ empty@1f000000 {
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ nand@4,0 {
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x4 0x0 0x40000>;
+ };
+
+ nand@5,0 {
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x5 0x0 0x40000>;
+ };
+
+ nand@6,0 {
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x6 0x0 0x40000>;
+ };
+ };
+
+ soc@ffe00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,p2020-immr", "simple-bus";
+ ranges = <0x0 0 0xffe00000 0x100000>;
+ bus-frequency = <0>; // Filled out by uboot.
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,p2020-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,p2020-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ spi@7000 {
+ compatible = "fsl,espi";
+ reg = <0x7000 0x1000>;
+ interrupts = <59 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ dma@c300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eloplus-dma";
+ reg = <0xc300 0x4>;
+ ranges = <0x0 0xc100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <76 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <77 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <78 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <79 2>;
+ };
+ };
+
+ gpio: gpio-controller@f000 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8572-gpio";
+ reg = <0xf000 0x100>;
+ interrupts = <47 0x2>;
+ interrupt-parent = <&mpic>;
+ gpio-controller;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,p2020-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x80000>; // L2, 512k
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ usb@22000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-usb2-dr";
+ reg = <0x22000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <28 0x2>;
+ phy_type = "ulpi";
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x2>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <2>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <31 2 32 2 33 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ sdhci@2e000 {
+ compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0xbfe>;
+ fsl,descriptor-types-mask = <0x3ab0ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi@41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,p2020-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+ };
+
+ pci0: pcie@ffe08000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe08000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1
+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1
+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci1: pcie@ffe09000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ // IDSEL 0x11 func 0 - PCI slot 1
+ 0x8800 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8800 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 1 - PCI slot 1
+ 0x8900 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8900 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 2 - PCI slot 1
+ 0x8a00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8a00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 3 - PCI slot 1
+ 0x8b00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8b00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 4 - PCI slot 1
+ 0x8c00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8c00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 5 - PCI slot 1
+ 0x8d00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8d00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 6 - PCI slot 1
+ 0x8e00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8e00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x11 func 7 - PCI slot 1
+ 0x8f00 0x0 0x0 0x1 &i8259 0x9 0x2
+ 0x8f00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+ 0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+ 0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+ >;
+
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ uli1575@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ isa@1e {
+ device_type = "isa";
+ #interrupt-cells = <2>;
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0x0 0x0 0x0 0x0>;
+ ranges = <0x1 0x0 0x1000000 0x0 0x0
+ 0x1000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <0x1 0x20 0x2
+ 0x1 0xa0 0x2
+ 0x1 0x4d0 0x2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <4 1>;
+ interrupt-parent = <&mpic>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent =
+ <&i8259>;
+
+ keyboard@0 {
+ reg = <0x0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <0x1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible = "pnpPNP,b00";
+ reg = <0x1 0x70 0x2>;
+ };
+
+ gpio@400 {
+ reg = <0x1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci2: pcie@ffe0a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <26 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041rdb.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041rdb.dts
new file mode 100644
index 0000000000..aa5af072e7
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041rdb.dts
@@ -0,0 +1,490 @@
+/*
+ * P2041RDB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/include/ "p2041si.dtsi"
+
+/ {
+ model = "fsl,P2041RDB";
+ compatible = "fsl,P2041RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_2 = &phy_sgmii_2;
+ phy_sgmii_3 = &phy_sgmii_3;
+ phy_sgmii_4 = &phy_sgmii_4;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_2 = &phy_xgmii_2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals@ff4000000 {
+ bman-portal@0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal@8000 {
+ cpu-handle = <&cpu2>;
+ };
+ bman-portal@c000 {
+ cpu-handle = <&cpu3>;
+ };
+ bman-portal@10000 {
+ };
+ bman-portal@14000 {
+ };
+ bman-portal@18000 {
+ };
+ bman-portal@1c000 {
+ };
+ bman-portal@20000 {
+ };
+ bman-portal@24000 {
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p2041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ qportal0: qman-portal@0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal@8000 {
+ cpu-handle = <&cpu2>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal@c000 {
+ cpu-handle = <&cpu3>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal@10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal@14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal@18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal@20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal@24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118000 {
+ lm75b@48 {
+ compatible = "nxp,lm75a";
+ reg = <0x48>;
+ };
+ eeprom@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@118100 {
+ eeprom@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ };
+
+ usb1: usb@211000 {
+ dr_mode = "host";
+ };
+
+ pme: pme@316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ };
+
+ qman: qman@318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ enet0: ethernet@e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_sgmii_2>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio0: mdio@e1120 {
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ phy_sgmii_2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ phy_sgmii_3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ phy_sgmii_4: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ enet1: ethernet@e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_3>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e3120 {
+ tbi1: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_4>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e5120 {
+ tbi2: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio@e7120 {
+ tbi3: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet@e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio@e9120 {
+ tbi4: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet@f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_2>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@f1000 {
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
+ 0 0x00010000>;
+ };
+ };
+
+ fsl,dpaa {
+ compatible = "fsl,p2041-dpaa", "fsl,dpaa";
+
+ ethernet@0 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status = "okay";
+ };
+ ethernet@1 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "okay";
+ };
+ ethernet@2 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "okay";
+ };
+ ethernet@3 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "okay";
+ };
+ ethernet@4 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet@5 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "okay";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041si.dtsi b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041si.dtsi
new file mode 100644
index 0000000000..9db01fa62c
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p2041si.dtsi
@@ -0,0 +1,1296 @@
+/*
+ * P2041 Silicon Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P2041";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e500mc@0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <749999996>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e500mc@1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu2: PowerPC,e500mc@2 {
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2_2>;
+ L2_2: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu3: PowerPC,e500mc@3 {
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2_3>;
+ L2_3: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu@0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc@2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa@9000 {
+ compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn@11000 {
+ compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr@12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-nal@18000 {
+ compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm@22000 {
+ compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@40000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@41000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@42000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu2>;
+ reg = <0x42000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@43000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu3>;
+ reg = <0x43000 0x1000>;
+ };
+ };
+
+ bman-portals@ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal@8000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p2041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal@8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool@1 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool@2 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool@3 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool@4 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool@5 {
+ cell-index = <5>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool@6 {
+ cell-index = <6>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool@7 {
+ cell-index = <7>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool@8 {
+ cell-index = <8>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool@9 {
+ cell-index = <9>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool@10 {
+ cell-index = <10>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool@11 {
+ cell-index = <11>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool@12 {
+ cell-index = <12>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool@13 {
+ cell-index = <13>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool@14 {
+ cell-index = <14>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool@15 {
+ cell-index = <15>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law@0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr: memory-controller@8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ cpc: l3-cache-controller@10000 {
+ compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000>;
+ interrupts = <16 2 1 27>;
+ };
+
+ corenet-cf@18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu@20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic@40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi@41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi@41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi@41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities@e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities@e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities@e1000 {
+ compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities@e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp@e8000 {
+ compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes@ea000 {
+ compatible = "fsl,p2041-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma@100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma@101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi@110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p2041-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc@114000 {
+ compatible = "fsl,p2041-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c@118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial@11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial@11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial@11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial@11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio@130000 {
+ compatible = "fsl,p2041-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman@1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block@0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg@b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block@1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block@2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block@3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb@210000 {
+ compatible = "fsl,p2041-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb@211000 {
+ compatible = "fsl,p2041-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ phy_type = "utmi";
+ };
+
+ sata@220000 {
+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata@221000 {
+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto@300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic@6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a@0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b@20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c@40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d@60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon@314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ pme: pme@316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman@318000 {
+ compatible = "fsl,p2041-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ compatible = "fsl,p2041-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc@0 {
+ compatible = "fsl,p2041-fman-cc", "fsl,fman-cc";
+ };
+
+ parser@c7000 {
+ compatible = "fsl,p2041-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen@c1000 {
+ compatible = "fsl,p2041-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer@c0000 {
+ compatible = "fsl,p2041-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram@0 {
+ compatible = "fsl,p2041-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi@80000 {
+ compatible = "fsl,p2041-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi@80400 {
+ compatible = "fsl,p2041-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port@88000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port@89000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port@8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port@8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port@8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port@90000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port@b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port@a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port@a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port@aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port@ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port@ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port@81000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port@82000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port@83000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port@84000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port@85000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port@86000 {
+ cell-index = <5>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port@87000 {
+ cell-index = <6>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ };
+
+ mdio0: mdio@e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ };
+
+ mdio@e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ };
+
+ mdio@e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ };
+
+ mdio@e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet@f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus@ffe124000 {
+ compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus";
+ interrupts = <25 2 0 0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie@ffe200000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041ds.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041ds.dts
new file mode 100644
index 0000000000..70787e4327
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041ds.dts
@@ -0,0 +1,587 @@
+/*
+ * P3041DS Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/include/ "p3041si.dtsi"
+
+/ {
+ model = "fsl,P3041DS";
+ compatible = "fsl,P3041DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals@ff4000000 {
+ bman-portal@0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal@8000 {
+ cpu-handle = <&cpu2>;
+ };
+ bman-portal@c000 {
+ cpu-handle = <&cpu3>;
+ };
+ bman-portal@10000 {
+ };
+ bman-portal@14000 {
+ };
+ bman-portal@18000 {
+ };
+ bman-portal@1c000 {
+ };
+ bman-portal@20000 {
+ };
+ bman-portal@24000 {
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p3041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ qportal0: qman-portal@0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal@8000 {
+ cpu-handle = <&cpu2>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal@c000 {
+ cpu-handle = <&cpu3>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal@10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal@14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal@18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal@20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal@24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <35000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ pme: pme@316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ };
+
+ qman: qman@318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ enet0: ethernet@e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio0: mdio@e1120 {
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ /*
+ * Virtual MDIO for the two on-board RGMII
+ * ports. The fsl,hydra-mdio-muxval property
+ * is already correct.
+ */
+ hydra_mdio_rgmii: hydra-mdio-rgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ /*
+ * Virtual MDIO for the four-port SGMII card.
+ * The fsl,hydra-mdio-muxval property will be
+ * fixed-up by U-Boot based on the slot that
+ * the SGMII card is in.
+ *
+ * Note: we do not support DTSEC5 connected to
+ * SGMII, so this is the only SGMII node.
+ */
+ hydra_mdio_sgmii: hydra-mdio-sgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+
+ enet1: ethernet@e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e3120 {
+ tbi1: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e5120 {
+ tbi2: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+
+ tbi3: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet@e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio@e9120 {
+ tbi4: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet@f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ /*
+ * We only support one XAUI card, so the MDIO muxing
+ * is set by U-Boot, and Linux never touches it.
+ * Therefore, we don't need a virtual MDIO node.
+ * However, the phy address depends on the slot, so
+ * only one of the ethernet-phy nodes below will be
+ * used.
+ */
+ hydra_mdio_xgmii: mdio@f1000 {
+ status = "disabled";
+
+ /* XAUI card in slot 1 */
+ phy_xgmii_1: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xb0000000 0x0 0xb0000000 0 0x08000000
+ 0x01000000 0 0x00000000 0x0 0xff030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xb0000000
+ 0x02000000 0 0xb0000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff030000
+ 0 0x00010000>;
+ };
+ };
+
+ fsl,dpaa {
+ compatible = "fsl,p3041-dpaa", "fsl,dpaa";
+
+ ethernet@0 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status="okay";
+ };
+ ethernet@1 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "disabled";
+ };
+ ethernet@2 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "disabled";
+ };
+ ethernet@3 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "disabled";
+ };
+ ethernet@4 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet@5 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "disabled";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041si.dtsi b/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041si.dtsi
new file mode 100644
index 0000000000..3335e48d47
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p3041si.dtsi
@@ -0,0 +1,1339 @@
+/*
+ * P3041 Silicon Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P3041";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ pci3 = &pci3;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e500mc@0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <749999996>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e500mc@1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu2: PowerPC,e500mc@2 {
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2_2>;
+ L2_2: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu3: PowerPC,e500mc@3 {
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2_3>;
+ L2_3: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu@0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc@2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa@9000 {
+ compatible = "fsl,p43041-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn@11000 {
+ compatible = "fsl,p43041-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr@12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-nal@18000 {
+ compatible = "fsl,p43041-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm@22000 {
+ compatible = "fsl,p43041-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@40000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@41000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@42000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu2>;
+ reg = <0x42000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@43000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu3>;
+ reg = <0x43000 0x1000>;
+ };
+ };
+
+ bman-portals@ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal@8000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p3041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal@8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool@1 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool@2 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool@3 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool@4 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool@5 {
+ cell-index = <5>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool@6 {
+ cell-index = <6>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool@7 {
+ cell-index = <7>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool@8 {
+ cell-index = <8>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool@9 {
+ cell-index = <9>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool@10 {
+ cell-index = <10>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool@11 {
+ cell-index = <11>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool@12 {
+ cell-index = <12>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool@13 {
+ cell-index = <13>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool@14 {
+ cell-index = <14>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool@15 {
+ cell-index = <15>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law@0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr: memory-controller@8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ cpc: l3-cache-controller@10000 {
+ compatible = "fsl,p3041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000>;
+ interrupts = <16 2 1 27>;
+ };
+
+ corenet-cf@18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu@20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic@40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi@41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi@41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi@41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities@e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities@e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities@e1000 {
+ compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities@e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp@e8000 {
+ compatible = "fsl,p3041-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes@ea000 {
+ compatible = "fsl,p3041-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma@100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma@101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi@110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p3041-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc@114000 {
+ compatible = "fsl,p3041-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c@118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial@11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial@11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial@11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial@11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio@130000 {
+ compatible = "fsl,p3041-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman@1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block@0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg@b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block@1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block@2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block@3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb@210000 {
+ compatible = "fsl,p3041-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb@211000 {
+ compatible = "fsl,p3041-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+ sata@220000 {
+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata@221000 {
+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto@300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic@6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a@0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b@20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c@40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d@60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon@314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ pme: pme@316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman@318000 {
+ compatible = "fsl,p3041-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ compatible = "fsl,p3041-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc@0 {
+ compatible = "fsl,p3041-fman-cc", "fsl,fman-cc";
+ };
+
+ parser@c7000 {
+ compatible = "fsl,p3041-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen@c1000 {
+ compatible = "fsl,p3041-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer@c0000 {
+ compatible = "fsl,p3041-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram@0 {
+ compatible = "fsl,p3041-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi@80000 {
+ compatible = "fsl,p3041-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi@80400 {
+ compatible = "fsl,p3041-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port@88000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port@89000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port@8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port@8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port@8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port@90000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port@b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port@a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port@a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port@aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port@ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port@ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port@81000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port@82000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port@83000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port@84000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port@85000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port@86000 {
+ cell-index = <5>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port@87000 {
+ cell-index = <6>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio0: mdio@e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet@f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+
+ ptp_timer0: rtc@fe000 {
+ compatible = "fsl,fman-rtc";
+ reg = <0xfe000 0x1000>;
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus@ffe124000 {
+ compatible = "fsl,p3041-rev1.0-elbc", "simple-bus", "fsl,elbc";
+ interrupts = <
+ 25 2 0 0
+ 16 2 1 19
+ >;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie@ffe200000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 12>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 12>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 43 1 0 0
+ 0000 0 0 2 &mpic 0 1 0 0
+ 0000 0 0 3 &mpic 4 1 0 0
+ 0000 0 0 4 &mpic 8 1 0 0
+ >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020ds.dts b/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020ds.dts
new file mode 100644
index 0000000000..cb07045792
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020ds.dts
@@ -0,0 +1,583 @@
+/*
+ * P5020DS Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/include/ "p5020si.dtsi"
+
+/ {
+ model = "fsl,P5020DS";
+ compatible = "fsl,P5020DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals@ff4000000 {
+ bman-portal@0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal@8000 {
+ };
+ bman-portal@c000 {
+ };
+ bman-portal@10000 {
+ };
+ bman-portal@14000 {
+ };
+ bman-portal@18000 {
+ };
+ bman-portal@1c000 {
+ };
+ bman-portal@20000 {
+ };
+ bman-portal@24000 {
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p5020-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ qportal0: qman-portal@0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal@8000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal@c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal@10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal@14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal@18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal@20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal@24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ pme: pme@316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ };
+
+ qman: qman@318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ enet0: ethernet@e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio0: mdio@e1120 {
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ /*
+ * Virtual MDIO for the two on-board RGMII
+ * ports. The fsl,hydra-mdio-muxval property
+ * is already correct.
+ */
+ hydra_mdio_rgmii: hydra-mdio-rgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ /*
+ * Virtual MDIO for the four-port SGMII card.
+ * The fsl,hydra-mdio-muxval property will be
+ * fixed-up by U-Boot based on the slot that
+ * the SGMII card is in.
+ *
+ * Note: we do not support DTSEC5 connected to
+ * SGMII, so this is the only SGMII node.
+ */
+ hydra_mdio_sgmii: hydra-mdio-sgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+
+ enet1: ethernet@e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e3120 {
+ tbi1: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e5120 {
+ tbi2: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+
+ tbi3: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet@e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio@e9120 {
+ tbi4: tbi-phy@8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet@f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ /*
+ * We only support one XAUI card, so the MDIO muxing
+ * is set by U-Boot, and Linux never touches it.
+ * Therefore, we don't need a virtual MDIO node.
+ * However, the phy address depends on the slot, so
+ * only one of the ethernet-phy nodes below will be
+ * used.
+ */
+ hydra_mdio_xgmii: mdio@f1000 {
+ status = "disabled";
+
+ /* XAUI card in slot 1 */
+ phy_xgmii_1: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xb0000000 0x0 0xb0000000 0 0x08000000
+ 0x01000000 0 0x00000000 0x0 0xff030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xb0000000
+ 0x02000000 0 0xb0000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff030000
+ 0 0x00010000>;
+ };
+ };
+
+ fsl,dpaa {
+ compatible = "fsl,p5020-dpaa", "fsl,dpaa";
+
+ ethernet@0 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status = "okay";
+ };
+ ethernet@1 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "disabled";
+ };
+ ethernet@2 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "disabled";
+ };
+ ethernet@3 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "disabled";
+ };
+ ethernet@4 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet@5 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "disabled";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020si.dtsi b/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020si.dtsi
new file mode 100644
index 0000000000..27699cbc7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/powerpc/p5020si.dtsi
@@ -0,0 +1,1389 @@
+/*
+ * P5020 Silicon Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its 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") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/* $FreeBSD$ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P5020";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ pci3 = &pci3;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ raideng = &raideng;
+ raideng_jr0 = &raideng_jr0;
+ raideng_jr1 = &raideng_jr1;
+ raideng_jr2 = &raideng_jr2;
+ raideng_jr3 = &raideng_jr3;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e5500@0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <799999998>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e5500@1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu@0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc@2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa@9000 {
+ compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn@11000 {
+ compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr@12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr1>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-ddr@13000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr2>;
+ reg = <0x13000 0x1000>;
+ };
+ dcsr-nal@18000 {
+ compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm@22000 {
+ compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@40000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@41000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ };
+
+ bman-portals@ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal@8000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool@0 {
+ compatible = "fsl,p5020-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals@ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal@0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal@4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal@8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal@c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal@10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal@14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal@18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal@1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal@20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal@24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool@1 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool@2 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool@3 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool@4 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool@5 {
+ cell-index = <5>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool@6 {
+ cell-index = <6>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool@7 {
+ cell-index = <7>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool@8 {
+ cell-index = <8>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool@9 {
+ cell-index = <9>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool@10 {
+ cell-index = <10>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool@11 {
+ cell-index = <11>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool@12 {
+ cell-index = <12>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool@13 {
+ cell-index = <13>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool@14 {
+ cell-index = <14>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool@15 {
+ cell-index = <15>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc@ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law@0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr1: memory-controller@8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ ddr2: memory-controller@9000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x9000 0x1000>;
+ interrupts = <16 2 1 22>;
+ };
+
+ cpc: l3-cache-controller@10000 {
+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000
+ 0x11000 0x1000>;
+ interrupts = <16 2 1 27
+ 16 2 1 26>;
+ };
+
+ corenet-cf@18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu@20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic@40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi@41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi@41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi@41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities@e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities@e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities@e1000 {
+ compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities@e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp@e8000 {
+ compatible = "fsl,p5020-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes@ea000 {
+ compatible = "fsl,p5020-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma@100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5020-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma@101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5020-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi@110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p5020-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc@114000 {
+ compatible = "fsl,p5020-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c@118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c@119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial@11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial@11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial@11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial@11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio@130000 {
+ compatible = "fsl,p5020-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman@1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block@0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg@b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block@1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block@2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block@3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb@210000 {
+ compatible = "fsl,p5020-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb@211000 {
+ compatible = "fsl,p5020-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+ sata@220000 {
+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata@221000 {
+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto@300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic@6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a@0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b@20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c@40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d@60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon@314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ raideng: raideng@320000 {
+ compatible = "fsl,raideng-v1.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x320000 0x10000>;
+ ranges = <0 0x320000 0x10000>;
+
+ raideng_jq0@1000 {
+ compatible = "fsl,raideng-v1.0-job-queue";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1000 0x1000>;
+ ranges = <0x0 0x1000 0x1000>;
+
+ raideng_jr0: jr@0 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
+ reg = <0x0 0x400>;
+ interrupts = <139 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ raideng_jr1: jr@400 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
+ reg = <0x400 0x400>;
+ interrupts = <140 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+ };
+
+ raideng_jq1@2000 {
+ compatible = "fsl,raideng-v1.0-job-queue";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2000 0x1000>;
+ ranges = <0x0 0x2000 0x1000>;
+
+ raideng_jr2: jr@0 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
+ reg = <0x0 0x400>;
+ interrupts = <141 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ raideng_jr3: jr@400 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
+ reg = <0x400 0x400>;
+ interrupts = <142 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+ };
+ };
+
+ pme: pme@316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman@318000 {
+ compatible = "fsl,p5020-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman@31a000 {
+ compatible = "fsl,p5020-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc@0 {
+ compatible = "fsl,p5020-fman-cc", "fsl,fman-cc";
+ };
+
+ parser@c7000 {
+ compatible = "fsl,p5020-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen@c1000 {
+ compatible = "fsl,p5020-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer@c0000 {
+ compatible = "fsl,p5020-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram@0 {
+ compatible = "fsl,p5020-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi@80000 {
+ compatible = "fsl,p5020-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi@80400 {
+ compatible = "fsl,p5020-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port@88000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port@89000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port@8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port@8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port@8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port@90000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port@b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port@a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port@a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port@aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port@ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port@ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port@81000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port@82000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port@83000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port@84000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port@85000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port@86000 {
+ cell-index = <5>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port@87000 {
+ cell-index = <6>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio0: mdio@e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio@e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet@f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+
+ ptp_timer0: rtc@fe000 {
+ compatible = "fsl,fman-rtc";
+ reg = <0xfe000 0x1000>;
+ };
+ };
+ };
+
+ rapidio@ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus@ffe124000 {
+ compatible = "fsl,p5020-rev1.0-elbc", "simple-bus", "fsl,elbc";
+ interrupts = <
+ 25 2 0 0
+ 16 2 1 19
+ >;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie@ffe200000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <0>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <1>;
+ bus-range = <0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <2>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 12>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 12>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 43 1 0 0
+ 0000 0 0 2 &mpic 0 1 0 0
+ 0000 0 0 3 &mpic 4 1 0 0
+ 0000 0 0 4 &mpic 8 1 0 0
+ >;
+ };
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/riscv/qemu.dts b/usr/src/boot/sys/boot/fdt/dts/riscv/qemu.dts
new file mode 100644
index 0000000000..067e18fcea
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/riscv/qemu.dts
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "QEMU RV64I";
+ compatible = "riscv,rv64i";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+
+ aliases {
+ console0 = &console0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB at 0x0 */
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ compatible = "simple-bus";
+ ranges;
+
+ pic0: pic@0 {
+ compatible = "riscv,pic";
+ interrupt-controller;
+ };
+
+ timer0: timer@0 {
+ compatible = "riscv,timer";
+ interrupts = < 1 >;
+ interrupt-parent = < &pic0 >;
+ clock-frequency = < 400000000 >;
+ };
+
+ htif0: htif@0 {
+ compatible = "riscv,htif";
+ interrupts = < 0 >;
+ interrupt-parent = < &pic0 >;
+
+ console0: console@0 {
+ compatible = "htif,console";
+ status = "okay";
+ };
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "console0";
+ stdout = "console0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/dts/riscv/spike.dts b/usr/src/boot/sys/boot/fdt/dts/riscv/spike.dts
new file mode 100644
index 0000000000..dc671141ac
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/dts/riscv/spike.dts
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+
+/ {
+ model = "UC Berkeley Spike Simulator RV64I";
+ compatible = "riscv,rv64i";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "riscv,rv64i";
+ reg = <0x40002000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "riscv,rv64i";
+ reg = <0x4000a000>;
+ };
+ };
+
+ aliases {
+ console0 = &console0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1GB at 0x0 */
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ compatible = "simple-bus";
+ ranges;
+
+ pic0: pic@0 {
+ compatible = "riscv,pic";
+ interrupt-controller;
+ };
+
+ timer0: timer@0 {
+ compatible = "riscv,timer";
+ interrupts = < 1 >;
+ interrupt-parent = < &pic0 >;
+ clock-frequency = < 1000000 >;
+ };
+
+ htif0: htif@0 {
+ compatible = "riscv,htif";
+ interrupts = < 0 >;
+ interrupt-parent = < &pic0 >;
+
+ console0: console@0 {
+ compatible = "htif,console";
+ status = "okay";
+ };
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "console0";
+ stdout = "console0";
+ };
+};
diff --git a/usr/src/boot/sys/boot/fdt/fdt_loader_cmd.c b/usr/src/boot/sys/boot/fdt/fdt_loader_cmd.c
new file mode 100644
index 0000000000..662d004807
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/fdt_loader_cmd.c
@@ -0,0 +1,1589 @@
+/*-
+ * Copyright (c) 2009-2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <fdt.h>
+#include <libfdt.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <machine/elf.h>
+
+#include "bootstrap.h"
+#include "fdt_platform.h"
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
+ printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+#define FDT_CWD_LEN 256
+#define FDT_MAX_DEPTH 6
+
+#define FDT_PROP_SEP " = "
+
+#define COPYOUT(s,d,l) archsw.arch_copyout(s, d, l)
+#define COPYIN(s,d,l) archsw.arch_copyin(s, d, l)
+
+#define FDT_STATIC_DTB_SYMBOL "fdt_static_dtb"
+
+#define CMD_REQUIRES_BLOB 0x01
+
+/* Location of FDT yet to be loaded. */
+/* This may be in read-only memory, so can't be manipulated directly. */
+static struct fdt_header *fdt_to_load = NULL;
+/* Location of FDT on heap. */
+/* This is the copy we actually manipulate. */
+static struct fdt_header *fdtp = NULL;
+/* Size of FDT blob */
+static size_t fdtp_size = 0;
+/* Location of FDT in kernel or module. */
+/* This won't be set if FDT is loaded from disk or memory. */
+/* If it is set, we'll update it when fdt_copy() gets called. */
+static vm_offset_t fdtp_va = 0;
+
+static int fdt_load_dtb(vm_offset_t va);
+
+static int fdt_cmd_nyi(int argc, char *argv[]);
+
+static int fdt_cmd_addr(int argc, char *argv[]);
+static int fdt_cmd_mkprop(int argc, char *argv[]);
+static int fdt_cmd_cd(int argc, char *argv[]);
+static int fdt_cmd_hdr(int argc, char *argv[]);
+static int fdt_cmd_ls(int argc, char *argv[]);
+static int fdt_cmd_prop(int argc, char *argv[]);
+static int fdt_cmd_pwd(int argc, char *argv[]);
+static int fdt_cmd_rm(int argc, char *argv[]);
+static int fdt_cmd_mknode(int argc, char *argv[]);
+static int fdt_cmd_mres(int argc, char *argv[]);
+
+typedef int cmdf_t(int, char *[]);
+
+struct cmdtab {
+ const char *name;
+ cmdf_t *handler;
+ int flags;
+};
+
+static const struct cmdtab commands[] = {
+ { "addr", &fdt_cmd_addr, 0 },
+ { "alias", &fdt_cmd_nyi, 0 },
+ { "cd", &fdt_cmd_cd, CMD_REQUIRES_BLOB },
+ { "header", &fdt_cmd_hdr, CMD_REQUIRES_BLOB },
+ { "ls", &fdt_cmd_ls, CMD_REQUIRES_BLOB },
+ { "mknode", &fdt_cmd_mknode, CMD_REQUIRES_BLOB },
+ { "mkprop", &fdt_cmd_mkprop, CMD_REQUIRES_BLOB },
+ { "mres", &fdt_cmd_mres, CMD_REQUIRES_BLOB },
+ { "prop", &fdt_cmd_prop, CMD_REQUIRES_BLOB },
+ { "pwd", &fdt_cmd_pwd, CMD_REQUIRES_BLOB },
+ { "rm", &fdt_cmd_rm, CMD_REQUIRES_BLOB },
+ { NULL, NULL }
+};
+
+static char cwd[FDT_CWD_LEN] = "/";
+
+static vm_offset_t
+fdt_find_static_dtb()
+{
+ Elf_Ehdr *ehdr;
+ Elf_Shdr *shdr;
+ Elf_Sym sym;
+ vm_offset_t strtab, symtab, fdt_start;
+ uint64_t offs;
+ struct preloaded_file *kfp;
+ struct file_metadata *md;
+ char *strp;
+ int i, sym_count;
+
+ debugf("fdt_find_static_dtb()\n");
+
+ sym_count = symtab = strtab = 0;
+ strp = NULL;
+
+ offs = __elfN(relocation_offset);
+
+ kfp = file_findfile(NULL, NULL);
+ if (kfp == NULL)
+ return (0);
+
+ /* Locate the dynamic symbols and strtab. */
+ md = file_findmetadata(kfp, MODINFOMD_ELFHDR);
+ if (md == NULL)
+ return (0);
+ ehdr = (Elf_Ehdr *)md->md_data;
+
+ md = file_findmetadata(kfp, MODINFOMD_SHDR);
+ if (md == NULL)
+ return (0);
+ shdr = (Elf_Shdr *)md->md_data;
+
+ for (i = 0; i < ehdr->e_shnum; ++i) {
+ if (shdr[i].sh_type == SHT_DYNSYM && symtab == 0) {
+ symtab = shdr[i].sh_addr + offs;
+ sym_count = shdr[i].sh_size / sizeof(Elf_Sym);
+ } else if (shdr[i].sh_type == SHT_STRTAB && strtab == 0) {
+ strtab = shdr[i].sh_addr + offs;
+ }
+ }
+
+ /*
+ * The most efficent way to find a symbol would be to calculate a
+ * hash, find proper bucket and chain, and thus find a symbol.
+ * However, that would involve code duplication (e.g. for hash
+ * function). So we're using simpler and a bit slower way: we're
+ * iterating through symbols, searching for the one which name is
+ * 'equal' to 'fdt_static_dtb'. To speed up the process a little bit,
+ * we are eliminating symbols type of which is not STT_NOTYPE, or(and)
+ * those which binding attribute is not STB_GLOBAL.
+ */
+ fdt_start = 0;
+ while (sym_count > 0 && fdt_start == 0) {
+ COPYOUT(symtab, &sym, sizeof(sym));
+ symtab += sizeof(sym);
+ --sym_count;
+ if (ELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
+ ELF_ST_TYPE(sym.st_info) != STT_NOTYPE)
+ continue;
+ strp = strdupout(strtab + sym.st_name);
+ if (strcmp(strp, FDT_STATIC_DTB_SYMBOL) == 0)
+ fdt_start = (vm_offset_t)sym.st_value + offs;
+ free(strp);
+ }
+ return (fdt_start);
+}
+
+static int
+fdt_load_dtb(vm_offset_t va)
+{
+ struct fdt_header header;
+ int err;
+
+ debugf("fdt_load_dtb(0x%08jx)\n", (uintmax_t)va);
+
+ COPYOUT(va, &header, sizeof(header));
+ err = fdt_check_header(&header);
+ if (err < 0) {
+ if (err == -FDT_ERR_BADVERSION) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "incompatible blob version: %d, should be: %d",
+ fdt_version(fdtp), FDT_LAST_SUPPORTED_VERSION);
+
+ } else {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "error validating blob: %s", fdt_strerror(err));
+ }
+ return (1);
+ }
+
+ /*
+ * Release previous blob
+ */
+ if (fdtp)
+ free(fdtp);
+
+ fdtp_size = fdt_totalsize(&header);
+ fdtp = malloc(fdtp_size);
+
+ if (fdtp == NULL) {
+ command_errmsg = "can't allocate memory for device tree copy";
+ return (1);
+ }
+
+ fdtp_va = va;
+ COPYOUT(va, fdtp, fdtp_size);
+ debugf("DTB blob found at 0x%jx, size: 0x%jx\n", (uintmax_t)va, (uintmax_t)fdtp_size);
+
+ return (0);
+}
+
+int
+fdt_load_dtb_addr(struct fdt_header *header)
+{
+ int err;
+
+ debugf("fdt_load_dtb_addr(%p)\n", header);
+
+ fdtp_size = fdt_totalsize(header);
+ err = fdt_check_header(header);
+ if (err < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "error validating blob: %s", fdt_strerror(err));
+ return (err);
+ }
+ free(fdtp);
+ if ((fdtp = malloc(fdtp_size)) == NULL) {
+ command_errmsg = "can't allocate memory for device tree copy";
+ return (1);
+ }
+
+ fdtp_va = 0; // Don't write this back into module or kernel.
+ bcopy(header, fdtp, fdtp_size);
+ return (0);
+}
+
+int
+fdt_load_dtb_file(const char * filename)
+{
+ struct preloaded_file *bfp, *oldbfp;
+ int err;
+
+ debugf("fdt_load_dtb_file(%s)\n", filename);
+
+ oldbfp = file_findfile(NULL, "dtb");
+
+ /* Attempt to load and validate a new dtb from a file. */
+ if ((bfp = file_loadraw(filename, "dtb", 1)) == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "failed to load file '%s'", filename);
+ return (1);
+ }
+ if ((err = fdt_load_dtb(bfp->f_addr)) != 0) {
+ file_discard(bfp);
+ return (err);
+ }
+
+ /* A new dtb was validated, discard any previous file. */
+ if (oldbfp)
+ file_discard(oldbfp);
+ return (0);
+}
+
+int
+fdt_setup_fdtp()
+{
+ struct preloaded_file *bfp;
+ vm_offset_t va;
+
+ debugf("fdt_setup_fdtp()\n");
+
+ /* If we already loaded a file, use it. */
+ if ((bfp = file_findfile(NULL, "dtb")) != NULL) {
+ if (fdt_load_dtb(bfp->f_addr) == 0) {
+ printf("Using DTB from loaded file '%s'.\n",
+ bfp->f_name);
+ return (0);
+ }
+ }
+
+ /* If we were given the address of a valid blob in memory, use it. */
+ if (fdt_to_load != NULL) {
+ if (fdt_load_dtb_addr(fdt_to_load) == 0) {
+ printf("Using DTB from memory address 0x%p.\n",
+ fdt_to_load);
+ return (0);
+ }
+ }
+
+ if (fdt_platform_load_dtb() == 0)
+ return (0);
+
+ /* If there is a dtb compiled into the kernel, use it. */
+ if ((va = fdt_find_static_dtb()) != 0) {
+ if (fdt_load_dtb(va) == 0) {
+ printf("Using DTB compiled into kernel.\n");
+ return (0);
+ }
+ }
+
+ command_errmsg = "No device tree blob found!\n";
+ return (1);
+}
+
+#define fdt_strtovect(str, cellbuf, lim, cellsize) _fdt_strtovect((str), \
+ (cellbuf), (lim), (cellsize), 0);
+
+/* Force using base 16 */
+#define fdt_strtovectx(str, cellbuf, lim, cellsize) _fdt_strtovect((str), \
+ (cellbuf), (lim), (cellsize), 16);
+
+static int
+_fdt_strtovect(const char *str, void *cellbuf, int lim, unsigned char cellsize,
+ uint8_t base)
+{
+ const char *buf = str;
+ const char *end = str + strlen(str) - 2;
+ uint32_t *u32buf = NULL;
+ uint8_t *u8buf = NULL;
+ int cnt = 0;
+
+ if (cellsize == sizeof(uint32_t))
+ u32buf = (uint32_t *)cellbuf;
+ else
+ u8buf = (uint8_t *)cellbuf;
+
+ if (lim == 0)
+ return (0);
+
+ while (buf < end) {
+
+ /* Skip white whitespace(s)/separators */
+ while (!isxdigit(*buf) && buf < end)
+ buf++;
+
+ if (u32buf != NULL)
+ u32buf[cnt] =
+ cpu_to_fdt32((uint32_t)strtol(buf, NULL, base));
+
+ else
+ u8buf[cnt] = (uint8_t)strtol(buf, NULL, base);
+
+ if (cnt + 1 <= lim - 1)
+ cnt++;
+ else
+ break;
+ buf++;
+ /* Find another number */
+ while ((isxdigit(*buf) || *buf == 'x') && buf < end)
+ buf++;
+ }
+ return (cnt);
+}
+
+void
+fdt_fixup_ethernet(const char *str, char *ethstr, int len)
+{
+ uint8_t tmp_addr[6];
+
+ /* Convert macaddr string into a vector of uints */
+ fdt_strtovectx(str, &tmp_addr, 6, sizeof(uint8_t));
+ /* Set actual property to a value from vect */
+ fdt_setprop(fdtp, fdt_path_offset(fdtp, ethstr),
+ "local-mac-address", &tmp_addr, 6 * sizeof(uint8_t));
+}
+
+void
+fdt_fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq)
+{
+ int lo, o = 0, o2, maxo = 0, depth;
+ const uint32_t zero = 0;
+
+ /* We want to modify every subnode of /cpus */
+ o = fdt_path_offset(fdtp, "/cpus");
+ if (o < 0)
+ return;
+
+ /* maxo should contain offset of node next to /cpus */
+ depth = 0;
+ maxo = o;
+ while (depth != -1)
+ maxo = fdt_next_node(fdtp, maxo, &depth);
+
+ /* Find CPU frequency properties */
+ o = fdt_node_offset_by_prop_value(fdtp, o, "clock-frequency",
+ &zero, sizeof(uint32_t));
+
+ o2 = fdt_node_offset_by_prop_value(fdtp, o, "bus-frequency", &zero,
+ sizeof(uint32_t));
+
+ lo = MIN(o, o2);
+
+ while (o != -FDT_ERR_NOTFOUND && o2 != -FDT_ERR_NOTFOUND) {
+
+ o = fdt_node_offset_by_prop_value(fdtp, lo,
+ "clock-frequency", &zero, sizeof(uint32_t));
+
+ o2 = fdt_node_offset_by_prop_value(fdtp, lo, "bus-frequency",
+ &zero, sizeof(uint32_t));
+
+ /* We're only interested in /cpus subnode(s) */
+ if (lo > maxo)
+ break;
+
+ fdt_setprop_inplace_cell(fdtp, lo, "clock-frequency",
+ (uint32_t)cpufreq);
+
+ fdt_setprop_inplace_cell(fdtp, lo, "bus-frequency",
+ (uint32_t)busfreq);
+
+ lo = MIN(o, o2);
+ }
+}
+
+#ifdef notyet
+static int
+fdt_reg_valid(uint32_t *reg, int len, int addr_cells, int size_cells)
+{
+ int cells_in_tuple, i, tuples, tuple_size;
+ uint32_t cur_start, cur_size;
+
+ cells_in_tuple = (addr_cells + size_cells);
+ tuple_size = cells_in_tuple * sizeof(uint32_t);
+ tuples = len / tuple_size;
+ if (tuples == 0)
+ return (EINVAL);
+
+ for (i = 0; i < tuples; i++) {
+ if (addr_cells == 2)
+ cur_start = fdt64_to_cpu(reg[i * cells_in_tuple]);
+ else
+ cur_start = fdt32_to_cpu(reg[i * cells_in_tuple]);
+
+ if (size_cells == 2)
+ cur_size = fdt64_to_cpu(reg[i * cells_in_tuple + 2]);
+ else
+ cur_size = fdt32_to_cpu(reg[i * cells_in_tuple + 1]);
+
+ if (cur_size == 0)
+ return (EINVAL);
+
+ debugf(" reg#%d (start: 0x%0x size: 0x%0x) valid!\n",
+ i, cur_start, cur_size);
+ }
+ return (0);
+}
+#endif
+
+void
+fdt_fixup_memory(struct fdt_mem_region *region, size_t num)
+{
+ struct fdt_mem_region *curmr;
+ uint32_t addr_cells, size_cells;
+ uint32_t *addr_cellsp, *size_cellsp;
+ int err, i, len, memory, root;
+ size_t realmrno;
+ uint8_t *buf, *sb;
+ uint64_t rstart, rsize;
+ int reserved;
+
+ root = fdt_path_offset(fdtp, "/");
+ if (root < 0) {
+ sprintf(command_errbuf, "Could not find root node !");
+ return;
+ }
+
+ memory = fdt_path_offset(fdtp, "/memory");
+ if (memory <= 0) {
+ /* Create proper '/memory' node. */
+ memory = fdt_add_subnode(fdtp, root, "memory");
+ if (memory <= 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "Could not fixup '/memory' "
+ "node, error code : %d!\n", memory);
+ return;
+ }
+
+ err = fdt_setprop(fdtp, memory, "device_type", "memory",
+ sizeof("memory"));
+
+ if (err < 0)
+ return;
+ }
+
+ addr_cellsp = (uint32_t *)fdt_getprop(fdtp, root, "#address-cells",
+ NULL);
+ size_cellsp = (uint32_t *)fdt_getprop(fdtp, root, "#size-cells", NULL);
+
+ if (addr_cellsp == NULL || size_cellsp == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "Could not fixup '/memory' node : "
+ "%s %s property not found in root node!\n",
+ (!addr_cellsp) ? "#address-cells" : "",
+ (!size_cellsp) ? "#size-cells" : "");
+ return;
+ }
+
+ addr_cells = fdt32_to_cpu(*addr_cellsp);
+ size_cells = fdt32_to_cpu(*size_cellsp);
+
+ /*
+ * Convert memreserve data to memreserve property
+ * Check if property already exists
+ */
+ reserved = fdt_num_mem_rsv(fdtp);
+ if (reserved &&
+ (fdt_getprop(fdtp, root, "memreserve", NULL) == NULL)) {
+ len = (addr_cells + size_cells) * reserved * sizeof(uint32_t);
+ sb = buf = (uint8_t *)malloc(len);
+ if (!buf)
+ return;
+
+ bzero(buf, len);
+
+ for (i = 0; i < reserved; i++) {
+ if (fdt_get_mem_rsv(fdtp, i, &rstart, &rsize))
+ break;
+ if (rsize) {
+ /* Ensure endianess, and put cells into a buffer */
+ if (addr_cells == 2)
+ *(uint64_t *)buf =
+ cpu_to_fdt64(rstart);
+ else
+ *(uint32_t *)buf =
+ cpu_to_fdt32(rstart);
+
+ buf += sizeof(uint32_t) * addr_cells;
+ if (size_cells == 2)
+ *(uint64_t *)buf =
+ cpu_to_fdt64(rsize);
+ else
+ *(uint32_t *)buf =
+ cpu_to_fdt32(rsize);
+
+ buf += sizeof(uint32_t) * size_cells;
+ }
+ }
+
+ /* Set property */
+ if ((err = fdt_setprop(fdtp, root, "memreserve", sb, len)) < 0)
+ printf("Could not fixup 'memreserve' property.\n");
+
+ free(sb);
+ }
+
+ /* Count valid memory regions entries in sysinfo. */
+ realmrno = num;
+ for (i = 0; i < num; i++)
+ if (region[i].start == 0 && region[i].size == 0)
+ realmrno--;
+
+ if (realmrno == 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "Could not fixup '/memory' node : "
+ "sysinfo doesn't contain valid memory regions info!\n");
+ return;
+ }
+
+ len = (addr_cells + size_cells) * realmrno * sizeof(uint32_t);
+ sb = buf = (uint8_t *)malloc(len);
+ if (!buf)
+ return;
+
+ bzero(buf, len);
+
+ for (i = 0; i < num; i++) {
+ curmr = &region[i];
+ if (curmr->size != 0) {
+ /* Ensure endianess, and put cells into a buffer */
+ if (addr_cells == 2)
+ *(uint64_t *)buf =
+ cpu_to_fdt64(curmr->start);
+ else
+ *(uint32_t *)buf =
+ cpu_to_fdt32(curmr->start);
+
+ buf += sizeof(uint32_t) * addr_cells;
+ if (size_cells == 2)
+ *(uint64_t *)buf =
+ cpu_to_fdt64(curmr->size);
+ else
+ *(uint32_t *)buf =
+ cpu_to_fdt32(curmr->size);
+
+ buf += sizeof(uint32_t) * size_cells;
+ }
+ }
+
+ /* Set property */
+ if ((err = fdt_setprop(fdtp, memory, "reg", sb, len)) < 0)
+ sprintf(command_errbuf, "Could not fixup '/memory' node.\n");
+
+ free(sb);
+}
+
+void
+fdt_fixup_stdout(const char *str)
+{
+ char *ptr;
+ int serialno;
+ int len, no, sero;
+ const struct fdt_property *prop;
+ char *tmp[10];
+
+ ptr = (char *)str + strlen(str) - 1;
+ while (ptr > str && isdigit(*(str - 1)))
+ str--;
+
+ if (ptr == str)
+ return;
+
+ serialno = (int)strtol(ptr, NULL, 0);
+ no = fdt_path_offset(fdtp, "/chosen");
+ if (no < 0)
+ return;
+
+ prop = fdt_get_property(fdtp, no, "stdout", &len);
+
+ /* If /chosen/stdout does not extist, create it */
+ if (prop == NULL || (prop != NULL && len == 0)) {
+
+ bzero(tmp, 10 * sizeof(char));
+ strcpy((char *)&tmp, "serial");
+ if (strlen(ptr) > 3)
+ /* Serial number too long */
+ return;
+
+ strncpy((char *)tmp + 6, ptr, 3);
+ sero = fdt_path_offset(fdtp, (const char *)tmp);
+ if (sero < 0)
+ /*
+ * If serial device we're trying to assign
+ * stdout to doesn't exist in DT -- return.
+ */
+ return;
+
+ fdt_setprop(fdtp, no, "stdout", &tmp,
+ strlen((char *)&tmp) + 1);
+ fdt_setprop(fdtp, no, "stdin", &tmp,
+ strlen((char *)&tmp) + 1);
+ }
+}
+
+/*
+ * Locate the blob, fix it up and return its location.
+ */
+static int
+fdt_fixup(void)
+{
+ int chosen, len;
+
+ len = 0;
+
+ debugf("fdt_fixup()\n");
+
+ if (fdtp == NULL && fdt_setup_fdtp() != 0)
+ return (0);
+
+ /* Create /chosen node (if not exists) */
+ if ((chosen = fdt_subnode_offset(fdtp, 0, "chosen")) ==
+ -FDT_ERR_NOTFOUND)
+ chosen = fdt_add_subnode(fdtp, 0, "chosen");
+
+ /* Value assigned to fixup-applied does not matter. */
+ if (fdt_getprop(fdtp, chosen, "fixup-applied", NULL))
+ return (1);
+
+ fdt_platform_fixups();
+
+ fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0);
+ return (1);
+}
+
+/*
+ * Copy DTB blob to specified location and return size
+ */
+int
+fdt_copy(vm_offset_t va)
+{
+ int err;
+ debugf("fdt_copy va 0x%08x\n", va);
+ if (fdtp == NULL) {
+ err = fdt_setup_fdtp();
+ if (err) {
+ printf("No valid device tree blob found!\n");
+ return (0);
+ }
+ }
+
+ if (fdt_fixup() == 0)
+ return (0);
+
+ if (fdtp_va != 0) {
+ /* Overwrite the FDT with the fixed version. */
+ /* XXX Is this really appropriate? */
+ COPYIN(fdtp, fdtp_va, fdtp_size);
+ }
+ COPYIN(fdtp, va, fdtp_size);
+ return (fdtp_size);
+}
+
+
+
+int
+command_fdt_internal(int argc, char *argv[])
+{
+ cmdf_t *cmdh;
+ int flags;
+ char *cmd;
+ int i, err;
+
+ if (argc < 2) {
+ command_errmsg = "usage is 'fdt <command> [<args>]";
+ return (CMD_ERROR);
+ }
+
+ /*
+ * Validate fdt <command>.
+ */
+ cmd = strdup(argv[1]);
+ i = 0;
+ cmdh = NULL;
+ while (!(commands[i].name == NULL)) {
+ if (strcmp(cmd, commands[i].name) == 0) {
+ /* found it */
+ cmdh = commands[i].handler;
+ flags = commands[i].flags;
+ break;
+ }
+ i++;
+ }
+ if (cmdh == NULL) {
+ command_errmsg = "unknown command";
+ return (CMD_ERROR);
+ }
+
+ if (flags & CMD_REQUIRES_BLOB) {
+ /*
+ * Check if uboot env vars were parsed already. If not, do it now.
+ */
+ if (fdt_fixup() == 0)
+ return (CMD_ERROR);
+ }
+
+ /*
+ * Call command handler.
+ */
+ err = (*cmdh)(argc, argv);
+
+ return (err);
+}
+
+static int
+fdt_cmd_addr(int argc, char *argv[])
+{
+ struct preloaded_file *fp;
+ struct fdt_header *hdr;
+ const char *addr;
+ char *cp;
+
+ fdt_to_load = NULL;
+
+ if (argc > 2)
+ addr = argv[2];
+ else {
+ sprintf(command_errbuf, "no address specified");
+ return (CMD_ERROR);
+ }
+
+ hdr = (struct fdt_header *)strtoul(addr, &cp, 16);
+ if (cp == addr) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "Invalid address: %s", addr);
+ return (CMD_ERROR);
+ }
+
+ while ((fp = file_findfile(NULL, "dtb")) != NULL) {
+ file_discard(fp);
+ }
+
+ fdt_to_load = hdr;
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_cd(int argc, char *argv[])
+{
+ char *path;
+ char tmp[FDT_CWD_LEN];
+ int len, o;
+
+ path = (argc > 2) ? argv[2] : "/";
+
+ if (path[0] == '/') {
+ len = strlen(path);
+ if (len >= FDT_CWD_LEN)
+ goto fail;
+ } else {
+ /* Handle path specification relative to cwd */
+ len = strlen(cwd) + strlen(path) + 1;
+ if (len >= FDT_CWD_LEN)
+ goto fail;
+
+ strcpy(tmp, cwd);
+ strcat(tmp, "/");
+ strcat(tmp, path);
+ path = tmp;
+ }
+
+ o = fdt_path_offset(fdtp, path);
+ if (o < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "could not find node: '%s'", path);
+ return (CMD_ERROR);
+ }
+
+ strcpy(cwd, path);
+ return (CMD_OK);
+
+fail:
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "path too long: %d, max allowed: %d", len, FDT_CWD_LEN - 1);
+ return (CMD_ERROR);
+}
+
+static int
+fdt_cmd_hdr(int argc __unused, char *argv[] __unused)
+{
+ char line[80];
+ int ver;
+
+ if (fdtp == NULL) {
+ command_errmsg = "no device tree blob pointer?!";
+ return (CMD_ERROR);
+ }
+
+ ver = fdt_version(fdtp);
+ pager_open();
+ sprintf(line, "\nFlattened device tree header (%p):\n", fdtp);
+ pager_output(line);
+ sprintf(line, " magic = 0x%08x\n", fdt_magic(fdtp));
+ pager_output(line);
+ sprintf(line, " size = %d\n", fdt_totalsize(fdtp));
+ pager_output(line);
+ sprintf(line, " off_dt_struct = 0x%08x\n",
+ fdt_off_dt_struct(fdtp));
+ pager_output(line);
+ sprintf(line, " off_dt_strings = 0x%08x\n",
+ fdt_off_dt_strings(fdtp));
+ pager_output(line);
+ sprintf(line, " off_mem_rsvmap = 0x%08x\n",
+ fdt_off_mem_rsvmap(fdtp));
+ pager_output(line);
+ sprintf(line, " version = %d\n", ver);
+ pager_output(line);
+ sprintf(line, " last compatible version = %d\n",
+ fdt_last_comp_version(fdtp));
+ pager_output(line);
+ if (ver >= 2) {
+ sprintf(line, " boot_cpuid = %d\n",
+ fdt_boot_cpuid_phys(fdtp));
+ pager_output(line);
+ }
+ if (ver >= 3) {
+ sprintf(line, " size_dt_strings = %d\n",
+ fdt_size_dt_strings(fdtp));
+ pager_output(line);
+ }
+ if (ver >= 17) {
+ sprintf(line, " size_dt_struct = %d\n",
+ fdt_size_dt_struct(fdtp));
+ pager_output(line);
+ }
+ pager_close();
+
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_ls(int argc, char *argv[])
+{
+ const char *prevname[FDT_MAX_DEPTH] = { NULL };
+ const char *name;
+ char *path;
+ int i, o, depth, len;
+
+ path = (argc > 2) ? argv[2] : NULL;
+ if (path == NULL)
+ path = cwd;
+
+ o = fdt_path_offset(fdtp, path);
+ if (o < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "could not find node: '%s'", path);
+ return (CMD_ERROR);
+ }
+
+ for (depth = 0;
+ (o >= 0) && (depth >= 0);
+ o = fdt_next_node(fdtp, o, &depth)) {
+
+ name = fdt_get_name(fdtp, o, &len);
+
+ if (depth > FDT_MAX_DEPTH) {
+ printf("max depth exceeded: %d\n", depth);
+ continue;
+ }
+
+ prevname[depth] = name;
+
+ /* Skip root (i = 1) when printing devices */
+ for (i = 1; i <= depth; i++) {
+ if (prevname[i] == NULL)
+ break;
+
+ if (strcmp(cwd, "/") == 0)
+ printf("/");
+ printf("%s", prevname[i]);
+ }
+ printf("\n");
+ }
+
+ return (CMD_OK);
+}
+
+static __inline int
+isprint(int c)
+{
+
+ return (c >= ' ' && c <= 0x7e);
+}
+
+static int
+fdt_isprint(const void *data, int len, int *count)
+{
+ const char *d;
+ char ch;
+ int yesno, i;
+
+ if (len == 0)
+ return (0);
+
+ d = (const char *)data;
+ if (d[len - 1] != '\0')
+ return (0);
+
+ *count = 0;
+ yesno = 1;
+ for (i = 0; i < len; i++) {
+ ch = *(d + i);
+ if (isprint(ch) || (ch == '\0' && i > 0)) {
+ /* Count strings */
+ if (ch == '\0')
+ (*count)++;
+ continue;
+ }
+
+ yesno = 0;
+ break;
+ }
+
+ return (yesno);
+}
+
+static int
+fdt_data_str(const void *data, int len, int count, char **buf)
+{
+ char *b, *tmp;
+ const char *d;
+ int buf_len, i, l;
+
+ /*
+ * Calculate the length for the string and allocate memory.
+ *
+ * Note that 'len' already includes at least one terminator.
+ */
+ buf_len = len;
+ if (count > 1) {
+ /*
+ * Each token had already a terminator buried in 'len', but we
+ * only need one eventually, don't count space for these.
+ */
+ buf_len -= count - 1;
+
+ /* Each consecutive token requires a ", " separator. */
+ buf_len += count * 2;
+ }
+
+ /* Add some space for surrounding double quotes. */
+ buf_len += count * 2;
+
+ /* Note that string being put in 'tmp' may be as big as 'buf_len'. */
+ b = (char *)malloc(buf_len);
+ tmp = (char *)malloc(buf_len);
+ if (b == NULL)
+ goto error;
+
+ if (tmp == NULL) {
+ free(b);
+ goto error;
+ }
+
+ b[0] = '\0';
+
+ /*
+ * Now that we have space, format the string.
+ */
+ i = 0;
+ do {
+ d = (const char *)data + i;
+ l = strlen(d) + 1;
+
+ sprintf(tmp, "\"%s\"%s", d,
+ (i + l) < len ? ", " : "");
+ strcat(b, tmp);
+
+ i += l;
+
+ } while (i < len);
+ *buf = b;
+
+ free(tmp);
+
+ return (0);
+error:
+ return (1);
+}
+
+static int
+fdt_data_cell(const void *data, int len, char **buf)
+{
+ char *b, *tmp;
+ const uint32_t *c;
+ int count, i, l;
+
+ /* Number of cells */
+ count = len / 4;
+
+ /*
+ * Calculate the length for the string and allocate memory.
+ */
+
+ /* Each byte translates to 2 output characters */
+ l = len * 2;
+ if (count > 1) {
+ /* Each consecutive cell requires a " " separator. */
+ l += (count - 1) * 1;
+ }
+ /* Each cell will have a "0x" prefix */
+ l += count * 2;
+ /* Space for surrounding <> and terminator */
+ l += 3;
+
+ b = (char *)malloc(l);
+ tmp = (char *)malloc(l);
+ if (b == NULL)
+ goto error;
+
+ if (tmp == NULL) {
+ free(b);
+ goto error;
+ }
+
+ b[0] = '\0';
+ strcat(b, "<");
+
+ for (i = 0; i < len; i += 4) {
+ c = (const uint32_t *)((const uint8_t *)data + i);
+ sprintf(tmp, "0x%08x%s", fdt32_to_cpu(*c),
+ i < (len - 4) ? " " : "");
+ strcat(b, tmp);
+ }
+ strcat(b, ">");
+ *buf = b;
+
+ free(tmp);
+
+ return (0);
+error:
+ return (1);
+}
+
+static int
+fdt_data_bytes(const void *data, int len, char **buf)
+{
+ char *b, *tmp;
+ const char *d;
+ int i, l;
+
+ /*
+ * Calculate the length for the string and allocate memory.
+ */
+
+ /* Each byte translates to 2 output characters */
+ l = len * 2;
+ if (len > 1)
+ /* Each consecutive byte requires a " " separator. */
+ l += (len - 1) * 1;
+ /* Each byte will have a "0x" prefix */
+ l += len * 2;
+ /* Space for surrounding [] and terminator. */
+ l += 3;
+
+ b = (char *)malloc(l);
+ tmp = (char *)malloc(l);
+ if (b == NULL)
+ goto error;
+
+ if (tmp == NULL) {
+ free(b);
+ goto error;
+ }
+
+ b[0] = '\0';
+ strcat(b, "[");
+
+ for (i = 0, d = data; i < len; i++) {
+ sprintf(tmp, "0x%02x%s", d[i], i < len - 1 ? " " : "");
+ strcat(b, tmp);
+ }
+ strcat(b, "]");
+ *buf = b;
+
+ free(tmp);
+
+ return (0);
+error:
+ return (1);
+}
+
+static int
+fdt_data_fmt(const void *data, int len, char **buf)
+{
+ int count;
+
+ if (len == 0) {
+ *buf = NULL;
+ return (1);
+ }
+
+ if (fdt_isprint(data, len, &count))
+ return (fdt_data_str(data, len, count, buf));
+
+ else if ((len % 4) == 0)
+ return (fdt_data_cell(data, len, buf));
+
+ else
+ return (fdt_data_bytes(data, len, buf));
+}
+
+static int
+fdt_prop(int offset)
+{
+ char *line, *buf;
+ const struct fdt_property *prop;
+ const char *name;
+ const void *data;
+ int len, rv;
+
+ line = NULL;
+ prop = fdt_offset_ptr(fdtp, offset, sizeof(*prop));
+ if (prop == NULL)
+ return (1);
+
+ name = fdt_string(fdtp, fdt32_to_cpu(prop->nameoff));
+ len = fdt32_to_cpu(prop->len);
+
+ rv = 0;
+ buf = NULL;
+ if (len == 0) {
+ /* Property without value */
+ line = (char *)malloc(strlen(name) + 2);
+ if (line == NULL) {
+ rv = 2;
+ goto out2;
+ }
+ sprintf(line, "%s\n", name);
+ goto out1;
+ }
+
+ /*
+ * Process property with value
+ */
+ data = prop->data;
+
+ if (fdt_data_fmt(data, len, &buf) != 0) {
+ rv = 3;
+ goto out2;
+ }
+
+ line = (char *)malloc(strlen(name) + strlen(FDT_PROP_SEP) +
+ strlen(buf) + 2);
+ if (line == NULL) {
+ sprintf(command_errbuf, "could not allocate space for string");
+ rv = 4;
+ goto out2;
+ }
+
+ sprintf(line, "%s" FDT_PROP_SEP "%s\n", name, buf);
+
+out1:
+ pager_open();
+ pager_output(line);
+ pager_close();
+
+out2:
+ if (buf)
+ free(buf);
+
+ if (line)
+ free(line);
+
+ return (rv);
+}
+
+static int
+fdt_modprop(int nodeoff, char *propname, void *value, char mode)
+{
+ uint32_t cells[100];
+ const char *buf;
+ int len, rv;
+ const struct fdt_property *p;
+
+ p = fdt_get_property(fdtp, nodeoff, propname, NULL);
+
+ if (p != NULL) {
+ if (mode == 1) {
+ /* Adding inexistant value in mode 1 is forbidden */
+ sprintf(command_errbuf, "property already exists!");
+ return (CMD_ERROR);
+ }
+ } else if (mode == 0) {
+ sprintf(command_errbuf, "property does not exist!");
+ return (CMD_ERROR);
+ }
+ len = strlen(value);
+ rv = 0;
+ buf = value;
+
+ switch (*buf) {
+ case '&':
+ /* phandles */
+ break;
+ case '<':
+ /* Data cells */
+ len = fdt_strtovect(buf, (void *)&cells, 100,
+ sizeof(uint32_t));
+
+ rv = fdt_setprop(fdtp, nodeoff, propname, &cells,
+ len * sizeof(uint32_t));
+ break;
+ case '[':
+ /* Data bytes */
+ len = fdt_strtovect(buf, (void *)&cells, 100,
+ sizeof(uint8_t));
+
+ rv = fdt_setprop(fdtp, nodeoff, propname, &cells,
+ len * sizeof(uint8_t));
+ break;
+ case '"':
+ default:
+ /* Default -- string */
+ rv = fdt_setprop_string(fdtp, nodeoff, propname, value);
+ break;
+ }
+
+ if (rv != 0) {
+ if (rv == -FDT_ERR_NOSPACE)
+ sprintf(command_errbuf,
+ "Device tree blob is too small!\n");
+ else
+ sprintf(command_errbuf,
+ "Could not add/modify property!\n");
+ }
+ return (rv);
+}
+
+/* Merge strings from argv into a single string */
+static int
+fdt_merge_strings(int argc, char *argv[], int start, char **buffer)
+{
+ char *buf;
+ int i, idx, sz;
+
+ *buffer = NULL;
+ sz = 0;
+
+ for (i = start; i < argc; i++)
+ sz += strlen(argv[i]);
+
+ /* Additional bytes for whitespaces between args */
+ sz += argc - start;
+
+ buf = (char *)malloc(sizeof(char) * sz);
+ if (buf == NULL) {
+ sprintf(command_errbuf, "could not allocate space "
+ "for string");
+ return (1);
+ }
+ bzero(buf, sizeof(char) * sz);
+
+ idx = 0;
+ for (i = start, idx = 0; i < argc; i++) {
+ strcpy(buf + idx, argv[i]);
+ idx += strlen(argv[i]);
+ buf[idx] = ' ';
+ idx++;
+ }
+ buf[sz - 1] = '\0';
+ *buffer = buf;
+ return (0);
+}
+
+/* Extract offset and name of node/property from a given path */
+static int
+fdt_extract_nameloc(char **pathp, char **namep, int *nodeoff)
+{
+ int o;
+ char *path = *pathp, *name = NULL, *subpath = NULL;
+
+ subpath = strrchr(path, '/');
+ if (subpath == NULL) {
+ o = fdt_path_offset(fdtp, cwd);
+ name = path;
+ path = (char *)&cwd;
+ } else {
+ *subpath = '\0';
+ if (strlen(path) == 0)
+ path = cwd;
+
+ name = subpath + 1;
+ o = fdt_path_offset(fdtp, path);
+ }
+
+ if (strlen(name) == 0) {
+ sprintf(command_errbuf, "name not specified");
+ return (1);
+ }
+ if (o < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "could not find node: '%s'", path);
+ return (1);
+ }
+ *namep = name;
+ *nodeoff = o;
+ *pathp = path;
+ return (0);
+}
+
+static int
+fdt_cmd_prop(int argc, char *argv[])
+{
+ char *path, *propname, *value;
+ int o, next, depth, rv;
+ uint32_t tag;
+
+ path = (argc > 2) ? argv[2] : NULL;
+
+ value = NULL;
+
+ if (argc > 3) {
+ /* Merge property value strings into one */
+ if (fdt_merge_strings(argc, argv, 3, &value) != 0)
+ return (CMD_ERROR);
+ } else
+ value = NULL;
+
+ if (path == NULL)
+ path = cwd;
+
+ rv = CMD_OK;
+
+ if (value) {
+ /* If value is specified -- try to modify prop. */
+ if (fdt_extract_nameloc(&path, &propname, &o) != 0)
+ return (CMD_ERROR);
+
+ rv = fdt_modprop(o, propname, value, 0);
+ if (rv)
+ return (CMD_ERROR);
+ return (CMD_OK);
+
+ }
+ /* User wants to display properties */
+ o = fdt_path_offset(fdtp, path);
+
+ if (o < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "could not find node: '%s'", path);
+ rv = CMD_ERROR;
+ goto out;
+ }
+
+ depth = 0;
+ while (depth >= 0) {
+ tag = fdt_next_tag(fdtp, o, &next);
+ switch (tag) {
+ case FDT_NOP:
+ break;
+ case FDT_PROP:
+ if (depth > 1)
+ /* Don't process properties of nested nodes */
+ break;
+
+ if (fdt_prop(o) != 0) {
+ sprintf(command_errbuf, "could not process "
+ "property");
+ rv = CMD_ERROR;
+ goto out;
+ }
+ break;
+ case FDT_BEGIN_NODE:
+ depth++;
+ if (depth > FDT_MAX_DEPTH) {
+ printf("warning: nesting too deep: %d\n",
+ depth);
+ goto out;
+ }
+ break;
+ case FDT_END_NODE:
+ depth--;
+ if (depth == 0)
+ /*
+ * This is the end of our starting node, force
+ * the loop finish.
+ */
+ depth--;
+ break;
+ }
+ o = next;
+ }
+out:
+ return (rv);
+}
+
+static int
+fdt_cmd_mkprop(int argc, char *argv[])
+{
+ int o;
+ char *path, *propname, *value;
+
+ path = (argc > 2) ? argv[2] : NULL;
+
+ value = NULL;
+
+ if (argc > 3) {
+ /* Merge property value strings into one */
+ if (fdt_merge_strings(argc, argv, 3, &value) != 0)
+ return (CMD_ERROR);
+ } else
+ value = NULL;
+
+ if (fdt_extract_nameloc(&path, &propname, &o) != 0)
+ return (CMD_ERROR);
+
+ if (fdt_modprop(o, propname, value, 1))
+ return (CMD_ERROR);
+
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_rm(int argc, char *argv[])
+{
+ int o, rv;
+ char *path = NULL, *propname;
+
+ if (argc > 2)
+ path = argv[2];
+ else {
+ sprintf(command_errbuf, "no node/property name specified");
+ return (CMD_ERROR);
+ }
+
+ o = fdt_path_offset(fdtp, path);
+ if (o < 0) {
+ /* If node not found -- try to find & delete property */
+ if (fdt_extract_nameloc(&path, &propname, &o) != 0)
+ return (CMD_ERROR);
+
+ if ((rv = fdt_delprop(fdtp, o, propname)) != 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "could not delete %s\n",
+ (rv == -FDT_ERR_NOTFOUND) ?
+ "(property/node does not exist)" : "");
+ return (CMD_ERROR);
+
+ } else
+ return (CMD_OK);
+ }
+ /* If node exists -- remove node */
+ rv = fdt_del_node(fdtp, o);
+ if (rv) {
+ sprintf(command_errbuf, "could not delete node");
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_mknode(int argc, char *argv[])
+{
+ int o, rv;
+ char *path = NULL, *nodename = NULL;
+
+ if (argc > 2)
+ path = argv[2];
+ else {
+ sprintf(command_errbuf, "no node name specified");
+ return (CMD_ERROR);
+ }
+
+ if (fdt_extract_nameloc(&path, &nodename, &o) != 0)
+ return (CMD_ERROR);
+
+ rv = fdt_add_subnode(fdtp, o, nodename);
+
+ if (rv < 0) {
+ if (rv == -FDT_ERR_NOSPACE)
+ sprintf(command_errbuf,
+ "Device tree blob is too small!\n");
+ else
+ sprintf(command_errbuf,
+ "Could not add node!\n");
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_pwd(int argc, char *argv[])
+{
+ char line[FDT_CWD_LEN];
+
+ pager_open();
+ sprintf(line, "%s\n", cwd);
+ pager_output(line);
+ pager_close();
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_mres(int argc, char *argv[])
+{
+ uint64_t start, size;
+ int i, total;
+ char line[80];
+
+ pager_open();
+ total = fdt_num_mem_rsv(fdtp);
+ if (total > 0) {
+ pager_output("Reserved memory regions:\n");
+ for (i = 0; i < total; i++) {
+ fdt_get_mem_rsv(fdtp, i, &start, &size);
+ sprintf(line, "reg#%d: (start: 0x%jx, size: 0x%jx)\n",
+ i, start, size);
+ pager_output(line);
+ }
+ } else
+ pager_output("No reserved memory regions\n");
+ pager_close();
+
+ return (CMD_OK);
+}
+
+static int
+fdt_cmd_nyi(int argc, char *argv[])
+{
+
+ printf("command not yet implemented\n");
+ return (CMD_ERROR);
+}
diff --git a/usr/src/boot/sys/boot/fdt/fdt_platform.h b/usr/src/boot/sys/boot/fdt/fdt_platform.h
new file mode 100644
index 0000000000..cad760279b
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/fdt_platform.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef FDT_PLATFORM_H
+#define FDT_PLATFORM_H
+
+struct fdt_header;
+
+struct fdt_mem_region {
+ unsigned long start;
+ unsigned long size;
+};
+
+#define TMP_MAX_ETH 8
+
+int fdt_copy(vm_offset_t);
+void fdt_fixup_cpubusfreqs(unsigned long, unsigned long);
+void fdt_fixup_ethernet(const char *, char *, int);
+void fdt_fixup_memory(struct fdt_mem_region *, size_t);
+void fdt_fixup_stdout(const char *);
+int fdt_load_dtb_addr(struct fdt_header *);
+int fdt_load_dtb_file(const char *);
+int fdt_setup_fdtp(void);
+
+/* The platform library needs to implement these functions */
+int fdt_platform_load_dtb(void);
+void fdt_platform_fixups(void);
+
+#endif /* FDT_PLATFORM_H */
diff --git a/usr/src/boot/sys/boot/fdt/help.fdt b/usr/src/boot/sys/boot/fdt/help.fdt
new file mode 100644
index 0000000000..665f63c260
--- /dev/null
+++ b/usr/src/boot/sys/boot/fdt/help.fdt
@@ -0,0 +1,93 @@
+$FreeBSD$
+###############################################################################
+# Tfdt Dfdt manipulation commands
+
+ fdt <subcommand> <arguments>
+
+ Facilities for loading and manipulating device tree data.
+
+###############################################################################
+# Tfdt Saddr Dload fdt from an address in memory
+
+ fdt addr <address>
+
+ Copies compiled device tree from a particular location
+ in memory.
+
+###############################################################################
+# Tfdt Salias DXXX
+
+ fdt alias <address>
+
+ Not Yet Implemented
+
+###############################################################################
+# Tfdt Scd DSelect a particular node for future commands
+
+ fdt cd <path>
+
+ Changes the current node to the node specified by the path.
+ Path elements are separated by '/'; a leading '/' represents
+ the root node.
+
+###############################################################################
+# Tfdt Sheader DDump the header of the compiled device tree
+
+ fdt header
+
+ Dumps DTB size, format and other key values.
+
+###############################################################################
+# Tfdt Sls DList subnodes of the current node
+
+ fdt ls <path>
+
+ Lists the nodes under the specified path.
+ If no path is specified, lists nodes under the current path.
+
+###############################################################################
+# Tfdt Smknode DCreate a new node in the device tree
+
+ fdt mknode <name>
+
+ Creates a new node with the specified name.
+
+###############################################################################
+# Tfdt Smkprop DAdd a new property to the current node
+
+ fdt mkprop <name> <value> ...
+
+ Creates a new property with the specified name and values.
+ Multiple values can be specified and will be concatenated.
+
+###############################################################################
+# Tfdt Smres DXXX
+
+ fdt mres
+
+ Dumps the list of reserved memory regions.
+
+###############################################################################
+# Tfdt Sprop DDump value of a particular property
+
+ fdt prop <name> <value> ...
+
+ If value is specified, set the given property to the indicated value.
+ Otherwise, print the value of the property.
+
+###############################################################################
+# Tfdt Spwd DPrint path to current node in device tree
+
+ fdt pwd
+
+ Print path to the current node in the device tree.
+ The current node can be changed with "fdt cd".
+
+###############################################################################
+# Tfdt Srm DRemove node or property from device tree
+
+ fdt rm <name>
+
+ The named node or property will be removed from the device tree.
+
+###############################################################################
diff --git a/usr/src/boot/sys/boot/ficl/Makefile b/usr/src/boot/sys/boot/ficl/Makefile
new file mode 100644
index 0000000000..51e6a20ed9
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/Makefile
@@ -0,0 +1,31 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+SUBDIRS = softcore $(MACH) $(MACH64)
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+
+all install: $(SUBDIRS)
+clean clobber: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/boot/sys/boot/ficl/Makefile.inc b/usr/src/boot/sys/boot/ficl/Makefile.inc
new file mode 100644
index 0000000000..37a3cc45af
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/Makefile.inc
@@ -0,0 +1,66 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+
+CC= $(GCC_ROOT)/bin/gcc
+FICLDIR= $(SRC)/common/ficl
+
+all: lib
+
+CPPFLAGS= -DSTAND -I. -I.. -I../../../../include -I../../../../lib/libstand
+CPPFLAGS += -I../../.. -I$(FICLDIR) -I../../common
+CFLAGS= -O2 -Wall -nostdinc
+
+CFLAGS += -ffreestanding
+CFLAGS += -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
+CFLAGS += -std=gnu99
+
+OBJECTS= dictionary.o system.o fileaccess.o float.o double.o prefix.o search.o
+OBJECTS += softcore.o stack.o tools.o vm.o primitives.o unix.o utility.o
+OBJECTS += hash.o callback.o word.o loader.o
+HEADERS= $(FICLDIR)/ficl.h $(FICLDIR)/ficlplatform/unix.h ../ficllocal.h
+#
+
+MAJOR = 4
+MINOR = 1.0
+
+lib: machine x86 libficl.a
+
+# static library build
+libficl.a: $(OBJECTS)
+ $(AR) $(ARFLAGS) libficl.a $(OBJECTS)
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../$(MACHINE)/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+%.o: ../softcore/%.c $(HEADERS)
+ $(COMPILE.c) $<
+
+%.o: $(FICLDIR)/%.c $(HEADERS)
+ $(COMPILE.c) $<
+
+%.o: $(FICLDIR)/ficlplatform/%.c $(HEADERS)
+ $(COMPILE.c) $<
+
+#
+# generic cleanup code
+#
+clobber clean: FRC
+ $(RM) *.o *.a libficl.* ficl machine x86
diff --git a/usr/src/boot/sys/boot/ficl/amd64/Makefile b/usr/src/boot/sys/boot/ficl/amd64/Makefile
new file mode 100644
index 0000000000..e9187ba9eb
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/amd64/Makefile
@@ -0,0 +1,26 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+MACHINE= $(MACH64)
+
+all install: lib
+
+include ../Makefile.inc
+
+CFLAGS += -fPIC -m64 -mno-red-zone
+
+FRC:
diff --git a/usr/src/boot/sys/boot/ficl/ficllocal.h b/usr/src/boot/sys/boot/ficl/ficllocal.h
new file mode 100644
index 0000000000..964cd79780
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/ficllocal.h
@@ -0,0 +1,11 @@
+/*
+** ficllocal.h
+**
+** Put all local settings here. This file will always ship empty.
+**
+*/
+
+/*
+** no need for float in loader
+**/
+#define FICL_WANT_FLOAT (0)
diff --git a/usr/src/boot/sys/boot/ficl/i386/Makefile b/usr/src/boot/sys/boot/ficl/i386/Makefile
new file mode 100644
index 0000000000..10e0c32dae
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/i386/Makefile
@@ -0,0 +1,27 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+MACHINE= $(MACH)
+
+all install: lib
+
+include ../Makefile.inc
+
+CFLAGS += -m32 -march=i386 -mpreferred-stack-boundary=2
+CFLAGS += -fno-reorder-functions
+
+FRC:
diff --git a/usr/src/boot/sys/boot/ficl/softcore/Makefile b/usr/src/boot/sys/boot/ficl/softcore/Makefile
new file mode 100644
index 0000000000..18565a73c3
--- /dev/null
+++ b/usr/src/boot/sys/boot/ficl/softcore/Makefile
@@ -0,0 +1,46 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/tools/Makefile.tools
+
+SOFTCORE= $(SRC)/common/ficl/softcore
+PROG = makesoftcore
+
+#
+# not needed: file access
+#
+FR = softcore.fr ifbrack.fr prefix.fr ficl.fr jhlocal.fr marker.fr
+FR += freebsd.fr ficllocal.fr oo.fr classes.fr string.fr
+SOURCES= $(FR:%=$(SOFTCORE)/%)
+
+OBJS= makesoftcore.o lz4.o
+SRCS= makesoftcore.c lz4.c
+LDLIBS= -lumem
+
+CPPFLAGS += -I.. -I$(SRC)/common/ficl
+
+all: softcore.c
+
+softcore.c: $(PROG) $(SOURCES)
+ ./$(PROG) $(SOURCES)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+
+%.o: $(SOFTCORE)/%.c
+ $(COMPILE.c) $<
+
+clobber clean:
+ $(RM) softcore.c $(OBJS) $(PROG)
diff --git a/usr/src/boot/sys/boot/forth/Makefile b/usr/src/boot/sys/boot/forth/Makefile
new file mode 100644
index 0000000000..1f42003f9d
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+MAN+= beastie.4th.8 \
+ brand.4th.8 \
+ check-password.4th.8 \
+ color.4th.8 \
+ delay.4th.8 \
+ loader.conf.5 \
+ loader.4th.8 \
+ menu.4th.8 \
+ menusets.4th.8 \
+ version.4th.8
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/forth/Makefile.inc b/usr/src/boot/sys/boot/forth/Makefile.inc
new file mode 100644
index 0000000000..eeab1a54eb
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/Makefile.inc
@@ -0,0 +1,25 @@
+# $FreeBSD$
+
+FORTH = beastie.4th
+FORTH += beadm.4th
+FORTH += brand.4th
+FORTH += brand-illumos.4th
+FORTH += check-password.4th
+FORTH += color.4th
+FORTH += delay.4th
+FORTH += frames.4th
+FORTH += loader.4th
+DEFFILES = loader.conf
+FORTH += logo-beastie.4th
+FORTH += logo-beastiebw.4th
+FORTH += logo-fbsdbw.4th
+FORTH += logo-illumos.4th
+FORTH += logo-orb.4th
+FORTH += logo-orbbw.4th
+FORTH += menu.4th
+FORTH += menu-commands.4th
+FORTH += menusets.4th
+FORTH += screen.4th
+FORTH += shortcuts.4th
+FORTH += support.4th
+FORTH += version.4th
diff --git a/usr/src/boot/sys/boot/forth/beadm.4th b/usr/src/boot/sys/boot/forth/beadm.4th
new file mode 100644
index 0000000000..7a65e669b0
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/beadm.4th
@@ -0,0 +1,428 @@
+\
+\ 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 2015 Toomas Soome <tsoome@me.com>
+
+\ This module is implementing the beadm user command to support listing
+\ and switching Boot Environments (BE) from command line and
+\ support words to provide data for BE menu in loader menu system.
+\ Note: this module needs an update to provide proper BE vocabulary.
+
+only forth also support-functions also file-processing
+also file-processing definitions also parser
+also line-reading definitions also builtins definitions
+
+variable page_count
+variable page_remainder
+0 page_count !
+0 page_remainder !
+
+\ from menu.4th
+: +c! ( N C-ADDR/U K -- C-ADDR/U )
+ 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr )
+ rot + c! ( n c-addr/u k n c-addr -- n c-addr/u )
+ rot drop ( n c-addr/u -- c-addr/u )
+;
+
+: get_value ( -- )
+ eat_space
+ line_pointer
+ skip_to_end_of_line
+ line_pointer over -
+ strdup value_buffer strset
+ ['] exit to parsing_function
+;
+
+: get_name ( -- )
+ read_name
+ ['] get_value to parsing_function
+;
+
+: get_name_value
+ line_buffer strget + to end_of_line
+ line_buffer .addr @ to line_pointer
+ ['] get_name to parsing_function
+ begin
+ end_of_line? 0=
+ while
+ parsing_function execute
+ repeat
+;
+
+\ beadm support
+: beadm_longest_title ( addr len -- width )
+ 0 to end_of_file?
+ O_RDONLY fopen fd !
+ reset_line_reading
+ fd @ -1 = if EOPEN throw then
+ 0 >r \ length into return stack
+ begin
+ end_of_file? 0=
+ while
+ free_buffers
+ read_line
+ get_name_value
+ value_buffer .len @ r@ > if r> drop value_buffer .len @ >r then
+ free_buffers
+ read_line
+ repeat
+ fd @ fclose
+ r> 1 + \ space between columns
+;
+
+\ Pretty print BE list
+: beadm_list ( width addr len -- )
+ 0 to end_of_file?
+ O_RDONLY fopen fd !
+ reset_line_reading
+ fd @ -1 = if EOPEN throw then
+ ." BE" dup 2 - spaces ." bootfs" cr
+ begin
+ end_of_file? 0=
+ while
+ free_buffers
+ read_line
+ get_name_value
+ value_buffer strget type
+ dup value_buffer .len @ - spaces
+ free_buffers
+ read_line
+ get_name_value
+ value_buffer strget type cr
+ free_buffers
+ repeat
+ fd @ fclose
+ drop
+;
+
+: beadm_bootfs ( be_addr be_len menu_addr menu_len -- addr len flag )
+ 0 to end_of_file?
+ O_RDONLY fopen fd !
+ reset_line_reading
+ fd @ -1 = if EOPEN throw then
+ 2swap
+ begin
+ end_of_file? 0=
+ while
+ free_buffers
+ read_line
+ get_name_value
+ 2dup value_buffer strget compare
+ 0= if ( title == be )
+ 2drop
+ free_buffers
+ read_line
+ get_name_value
+ value_buffer strget strdup -1
+ free_buffers
+ 1 to end_of_file? \ mark end of file to skip the rest
+ else
+ read_line \ skip over next line
+ then
+ repeat
+ fd @ fclose
+ line_buffer strfree
+ read_buffer strfree
+ dup -1 > if ( dev_addr dev_len )
+ 2drop
+ 0 0 0
+ then
+;
+
+: current-dev ( -- addr len ) \ return current dev
+ s" currdev" getenv
+ 2dup [char] / strchr nip
+ dup 0> if ( strchr '/' != NULL ) - else drop then
+ \ we have now zfs:pool or diskname:
+;
+
+\ chop trailing ':'
+: colon- ( addr len -- addr len - 1 | addr len )
+ 2dup 1 - + C@ [char] : = if ( string[len-1] == ':' ) 1 - then
+;
+
+\ add trailing ':'
+: colon+ ( addr len -- addr len+1 )
+ 2dup + \ addr len -- addr+len
+ [char] : swap c! \ save ':' at the end of the string
+ 1+ \ addr len -- addr len+1
+;
+
+\ make menu.lst path
+: menu.lst ( addr len -- addr' len' )
+ colon-
+ \ need to allocate space for len + 16
+ dup 16 + allocate if ENOMEM throw then
+ swap 2dup 2>R \ copy of new addr len to return stack
+ move 2R>
+ s" :/boot/menu.lst" strcat
+;
+
+\ list be's on device
+: list-dev ( addr len -- )
+ menu.lst 2dup 2>R
+ beadm_longest_title
+ line_buffer strfree
+ read_buffer strfree
+ R@ swap 2R> \ addr width addr len
+ beadm_list free-memory
+ ." Current boot device: " s" currdev" getenv type cr
+ line_buffer strfree
+ read_buffer strfree
+;
+
+\ activate be on device.
+\ in case of zfs, we query device:/boot/menu.lst for bootfs and
+\ use zfs:bootfs: for currdev
+\ in case of ufs we have device name without ':', so we just
+\ set currdev=device: and hope for best - there are no multiple BE's on ufs
+
+: activate-dev ( dev.addr dev.len be.addr be.len -- )
+ 2swap colon- \ remove : at the end of the dev name
+ 2dup [char] : strchr nip
+ 0= if ( no ':' in dev name, its ufs )
+ 2swap 2drop
+ dup 1+ allocate if ENOMEM throw then
+ dup 2swap 0 -rot strcat
+ colon+
+ s" currdev" setenv \ setenv currdev = device
+ free-memory
+ else
+ dup 16 + allocate if ENOMEM throw then
+ swap 2dup 2>R \ copy of new addr len to return stack
+ move 2R> \ copy dev name and concat file name
+ s" :/boot/menu.lst" strcat 2dup \ leave copy to stack
+ beadm_bootfs if ( dev_addr dev_len addr len )
+ 2swap \ addr len dev_addr dev_len
+ drop
+ free-memory
+ \ have dataset and need to get zfs:pool/ROOT/be:
+ dup 5 + allocate if ENOMEM throw then
+ 0 s" zfs:" strcat
+ 2swap strcat
+ colon+
+ 2dup s" currdev" setenv
+ drop free-memory
+ else
+ 2drop drop free \ free the file name
+ ." Failed to process BE/dev" cr abort
+ then
+ then
+
+ \ need to do:
+ 0 unload drop
+ free-module-options
+ \ unset kernel env?
+ start \ load config, kernel and modules
+ ." Current boot device: " s" currdev" getenv type cr
+;
+
+\ beadm list [device]
+\ beadm activate BE [device] BE
+\
+\ lists BE's from current or specified device /boot/menu.lst file
+\ activates specified BE by unloading modules, setting currdev and
+\ running start to load configuration.
+: beadm ( -- ) ( throws: abort )
+ 0= if ( interpreted ) get_arguments then
+
+ dup 0= if
+ ." Usage:" cr
+ ." beadm activate beName [device]" cr
+ ." beadm list [device]" cr
+ ." Use lsdev to get device names." cr
+ drop exit
+ then
+ \ First argument is 0 when we're interprated. See support.4th
+ \ for get_arguments reading the rest of the line and parsing it
+ \ stack: argN lenN ... arg1 len1 N
+ \ rotate arg1 len1, dont use argv[] as we want to get arg1 out of stack
+ -rot 2dup
+
+ s" list" compare-insensitive 0= if ( list )
+ 2drop
+ argc 1 = if ( list currdev )
+ \ add dev to list of args and switch to case 2
+ current-dev rot 1 +
+ then
+ 2 = if ( list device ) list-dev exit then
+ ." too many arguments" cr abort
+ then
+ s" activate" compare-insensitive 0= if ( activate )
+ argc 1 = if ( missing be )
+ drop ." missing bName" cr abort
+ then
+ argc 2 = if ( activate be )
+ \ need to set arg list into proper order
+ 1 + >R \ save argc+1 to return stack
+ \ if we have : in name, its device, inject
+ \ dummy be name, as it must be ufs device
+ 2dup [char] : strchr nip
+ if ( its : in name )
+ s" ufs" R>
+ else
+ \ add device, swap with be and receive argc
+ current-dev 2swap R>
+ then
+ then
+ 3 = if ( activate be device ) activate-dev exit then
+ ." too many arguments" cr abort
+ then
+ ." Unknown argument" cr abort
+;
+
+also forth definitions also builtins
+
+\ make beadm available as user command.
+builtin: beadm
+
+\ count the pages of BE list
+\ leave FALSE in stack in case of error
+: be-pages ( -- flag )
+ 1 local flag
+ 0 0 2local currdev
+ 0 0 2local title
+ end-locals
+
+ current-dev menu.lst 2dup 2>R
+ 0 to end_of_file?
+ O_RDONLY fopen fd !
+ 2R> drop free-memory
+ reset_line_reading
+ fd @ -1 = if FALSE else
+ s" currdev" getenv
+ over ( addr len addr )
+ 4 s" zfs:" compare 0= if
+ 5 - \ len -= 5
+ swap 4 + \ addr += 4
+ swap to currdev
+ then
+
+ 0
+ begin
+ end_of_file? 0=
+ while
+ read_line
+ get_name_value
+ s" title" name_buffer strget compare
+ 0= if 1+ then
+
+ flag if \ check for title
+ value_buffer strget strdup to title free_buffers
+ read_line \ get bootfs
+ get_name_value
+ value_buffer strget currdev compare 0= if
+ title s" zfs_be_active" setenv
+ 0 to flag
+ then
+ title drop free-memory 0 0 to title
+ free_buffers
+ else
+ free_buffers
+ read_line \ get bootfs
+ then
+ repeat
+ fd @ fclose
+ line_buffer strfree
+ read_buffer strfree
+ 5 /mod swap dup page_remainder ! \ save remainder
+ if 1+ then
+ dup page_count ! \ save count
+ s>d <# #s #> s" zfs_be_pages" setenv
+ TRUE
+ then
+;
+
+: be-set-page { | entry count n -- }
+ page_count @ 0= if
+ be-pages
+ page_count @ 0= if exit then
+ then
+
+ s" zfs_be_currpage" getenv dup -1 = if
+ drop s" 1"
+ then
+ 0 s>d 2swap
+ >number ( ud caddr/u -- ud' caddr'/u' )
+ 2drop
+ 1 um/mod nip 5 *
+ page_count @ 5 *
+ page_remainder @ if
+ 5 page_remainder @ - -
+ then
+ swap -
+ dup to entry
+ 0 < if
+ entry 5 + to count
+ 0 to entry
+ else
+ 5 to count
+ then
+ current-dev menu.lst 2dup 2>R
+ 0 to end_of_file?
+ O_RDONLY fopen fd !
+ 2R> drop free-memory
+ reset_line_reading
+ fd @ -1 = if EOPEN throw then
+ 0 to n
+ begin
+ end_of_file? 0=
+ while
+ n entry < if
+ read_line \ skip title
+ read_line \ skip bootfs
+ n 1+ to n
+ else
+ count 0 do
+ read_line \ read title line
+ get_name_value
+ value_buffer strget
+ 52 i + \ ascii 4 + i
+ s" bootenvmenu_caption[4]" 20 +c! setenv
+ value_buffer strget
+ 52 i + \ ascii 4 + i
+ s" bootenvansi_caption[4]" 20 +c! setenv
+ s" set_bootenv"
+ 52 i + \ ascii 4 + i
+ s" bootenvmenu_command[4]" 20 +c! setenv
+ free_buffers
+ read_line \ read value line
+ get_name_value
+ 52 i + \ ascii 4 + i
+ value_buffer strget swap drop
+ 5 + allocate if ENOMEM throw then
+ s" zfs:" ( N addr addr1 len )
+ 2 pick swap move ( N addr )
+ swap over ( addr N addr )
+ 4 value_buffer
+ strget ( addr N addr 4 addr1 len )
+ strcat ( addr N addr 4+len )
+ s" :" strcat ( addr N addr 5+len )
+ rot ( addr addr 5+len N )
+ s" bootenv_root[4]" 13 +c! setenv
+ free-memory
+ free_buffers
+ loop
+
+ 5 count do \ unset unused entries
+ 52 i + \ ascii 4 + i
+ dup s" bootenvmenu_caption[4]" 20 +c! unsetenv
+ dup s" bootenvansi_caption[4]" 20 +c! unsetenv
+ dup s" bootenvmenu_command[4]" 20 +c! unsetenv
+ s" bootenv_root[4]" 13 +c! unsetenv
+ loop
+
+ 1 to end_of_file? \ we are done
+ then
+ repeat
+ fd @ fclose
+ line_buffer strfree
+ read_buffer strfree
+;
diff --git a/usr/src/boot/sys/boot/forth/beastie.4th b/usr/src/boot/sys/boot/forth/beastie.4th
new file mode 100644
index 0000000000..cba112281a
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/beastie.4th
@@ -0,0 +1,110 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-beastie.4th
+
+only forth definitions
+
+variable logoX
+variable logoY
+
+\ Initialize logo placement to defaults
+46 logoX !
+4 logoY !
+
+\ This function draws any number of beastie logos at (loader_logo_x,
+\ loader_logo_y) if defined, else (46,4) (to the right of the menu). To choose
+\ your beastie, set the variable `loader_logo' to the respective logo name.
+\
+\ NOTE: Each is defined as a logo function in /boot/logo-${loader_logo}.4th
+\ NOTE: If `/boot/logo-${loader_logo}.4th' does not exist or does not define
+\ a `logo' function, no beastie is drawn.
+\
+: draw-beastie ( -- ) \ at (loader_logo_x,loader_logo_y), else (46,4)
+
+ s" loader_logo_x" getenv dup -1 <> if
+ ?number 1 = if logoX ! then
+ else drop then
+ s" loader_logo_y" getenv dup -1 <> if
+ ?number 1 = if logoY ! then
+ else drop then
+
+
+ \ If `logo' is defined, execute it
+ s" logo" sfind ( -- xt|0 bool ) if
+ logoX @ logoY @ rot execute
+ else
+ \ Not defined; try-include desired logo file
+ drop ( xt = 0 ) \ cruft
+ s" loader_logo" getenv dup -1 = over 0= or if
+ dup 0= if 2drop else drop then \ getenv result unused
+ loader_color? if
+ s" try-include /boot/forth/logo-orb.4th"
+ else
+ s" try-include /boot/forth/logo-orbbw.4th"
+ then
+ else
+ 2drop ( c-addr/u -- ) \ getenv result unused
+ s" try-include /boot/forth/logo-${loader_logo}.4th"
+ then
+ evaluate
+ 1 spaces
+
+ \ Execute `logo' if defined now
+ s" logo" sfind if
+ logoX @ logoY @ rot execute
+ else drop then
+ then
+;
+
+also support-functions
+
+: beastie-start ( -- ) \ starts the menu
+ s" beastie_disable" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ any_conf_read? if
+ load_xen_throw
+ load_kernel
+ load_modules
+ then
+ exit \ to autoboot (default)
+ then
+ else drop then
+
+ s" loader_delay" getenv -1 = if
+ s" include /boot/forth/menu.rc" evaluate
+ else
+ drop
+ ." Loading Menu (Ctrl-C to Abort)" cr
+ s" set delay_command='include /boot/forth/menu.rc'" evaluate
+ s" set delay_showdots" evaluate
+ delay_execute
+ then
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/beastie.4th.8 b/usr/src/boot/sys/boot/forth/beastie.4th.8
new file mode 100644
index 0000000000..9f77d5db29
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/beastie.4th.8
@@ -0,0 +1,173 @@
+.\" Copyright (c) 2011-2012 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 6, 2016
+.Dt BEASTIE.4TH 8
+.Os
+.Sh NAME
+.Nm beastie.4th
+.Nd FreeBSD ASCII art boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the ASCII art FreeBSD mascot
+.Nd known simply as
+.Ic beastie
+.Nd to the right of the boot loader menu.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include beastie.4th
+.Pp
+This line is present in the default
+.Pa /boot/loader.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic draw-beastie
+Draws the FreeBSD logo.
+.Pp
+The logo that is drawn is configured by setting the
+.Ic loader_logo
+variable in
+.Xr loader.conf 5
+to one of
+.Dq Li beastie ,
+.Dq Li beastiebw ,
+.Dq Li fbsdbw ,
+.Dq Li orb ,
+and
+.Dq Li orbbw
+(the default).
+.Pp
+The position of the logo can be configured by setting the
+.Ic loader_logo_x
+and
+.Ic loader_logo_y
+variables in
+.Xr loader.conf 5 .
+The default values are 46 (x) and 4 (y).
+.Pp
+.It Ic clear-beastie
+Clears the screen of beastie.
+.Pp
+.It Ic beastie-start
+Initializes the interactive boot loader menu.
+.Pp
+The
+.Ic loader_delay
+variable can be configured in
+.Xr loader.conf 5
+to the number of seconds you would like to delay loading the boot menu.
+During the delay the user can press Ctrl-C to fall back to
+.Ic autoboot
+or ENTER to proceed.
+The default behavior is to not delay.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_logo
+Selects the desired logo in the beastie boot menu. Possible values are:
+.Dq Li fbsdbw ,
+.Dq Li beastie ,
+.Dq Li beastiebw ,
+.Dq Li orb ,
+.Dq Li orbbw
+(default), and
+.Dq Li none .
+.It Va loader_logo_x
+Sets the desired column position of the logo. Default is 46.
+.It Va loader_logo_y
+Sets the desired row position of the logo. Default is 4.
+.It Va beastie_disable
+If set to
+.Dq YES ,
+the beastie boot menu will be skipped.
+The beastie boot menu is always skipped if running non-x86 hardware.
+.It Va loader_delay
+If set to a number higher than zero, introduces a delay before starting the
+beastie boot menu. During the delay the user can press either Ctrl-C to skip
+the menu or ENTER to proceed to the menu. The default is to not delay when
+loading the menu.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/beastie.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/beastie.4th
+beastie-start
+.Ed
+.Pp
+Set a different logo in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_logo="beastie"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 5.1 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Scott Long Aq scottl@FreeBSD.org ,
+.An Aleksander Fafula Aq alex@fafula.com
+and
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/brand-fbsd.4th b/usr/src/boot/sys/boot/forth/brand-fbsd.4th
new file mode 100644
index 0000000000..9cd017f84a
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/brand-fbsd.4th
@@ -0,0 +1,46 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+2 brandX ! 1 brandY ! \ Initialize brand placement defaults
+
+: brand+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: brand ( x y -- ) \ "FreeBSD" [wide] logo in B/W (7 rows x 42 columns)
+
+ s" ______ ____ _____ _____ " brand+
+ s" | ____| | _ \ / ____| __ \ " brand+
+ s" | |___ _ __ ___ ___ | |_) | (___ | | | |" brand+
+ s" | ___| '__/ _ \/ _ \| _ < \___ \| | | |" brand+
+ s" | | | | | __/ __/| |_) |____) | |__| |" brand+
+ s" | | | | | | || | | |" brand+
+ s" |_| |_| \___|\___||____/|_____/|_____/ " brand+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/brand-illumos.4th b/usr/src/boot/sys/boot/forth/brand-illumos.4th
new file mode 100644
index 0000000000..9859623aa6
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/brand-illumos.4th
@@ -0,0 +1,44 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+2 brandX ! 1 brandY ! \ Initialize brand placement defaults
+
+: brand+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: brand ( x y -- ) \ "illumos" [wide] logo in B/W (5 rows x 39 columns)
+
+ s" _ _ _ " brand+
+ s" (_)| || | _ _ _ __ ___ ___ ___ " brand+
+ s" | || || || | | || '_ ` _ \ / _ \ / __|" brand+
+ s" | || || || |_| || | | | | || (_) |\__ \" brand+
+ s" |_||_||_| \__,_||_| |_| |_| \___/ |___/" brand+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/brand.4th b/usr/src/boot/sys/boot/forth/brand.4th
new file mode 100644
index 0000000000..2caadcbaf5
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/brand.4th
@@ -0,0 +1,74 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-brand.4th
+
+variable brandX
+variable brandY
+
+\ Initialize brand placement to defaults
+2 brandX !
+1 brandY !
+
+\ This function draws any number of company brands at (loader_brand_x,
+\ loader_brand_y) if defined, or (2,1) (top-left). To choose your brand, set
+\ the variable `loader_brand' to the respective brand name.
+\
+\ NOTE: Each is defined as a brand function in /boot/brand-${loader_brand}.4th
+\ NOTE: If `/boot/brand-${loader_brand}.4th' does not exist or does not define
+\ a `brand' function, no brand is drawn.
+\
+: draw-brand ( -- ) \ at (loader_brand_x,loader_brand_y), else (2,1)
+
+ s" loader_brand_x" getenv dup -1 <> if
+ ?number 1 = if brandX ! then
+ else drop then
+ s" loader_brand_y" getenv dup -1 <> if
+ ?number 1 = if brandY ! then
+ else drop then
+
+ \ If `brand' is defined, execute it
+ s" brand" sfind ( -- xt|0 bool ) if
+ brandX @ brandY @ rot execute
+ else
+ \ Not defined; try-include desired brand file
+ drop ( xt = 0 ) \ cruft
+ s" loader_brand" getenv dup -1 = over 0= or if
+ dup 0= if 2drop else drop then \ getenv result unused
+ s" try-include /boot/forth/brand-illumos.4th"
+ else
+ 2drop ( c-addr/u -- ) \ getenv result unused
+ s" try-include /boot/forth/brand-${loader_brand}.4th"
+ then
+ evaluate
+ 1 spaces
+
+ \ Execute `brand' if defined now
+ s" brand" sfind if
+ brandX @ brandY @ rot execute
+ else drop then
+ then
+;
diff --git a/usr/src/boot/sys/boot/forth/brand.4th.8 b/usr/src/boot/sys/boot/forth/brand.4th.8
new file mode 100644
index 0000000000..dfd188d0ff
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/brand.4th.8
@@ -0,0 +1,125 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt BRAND.4TH 8
+.Os
+.Sh NAME
+.Nm brand.4th
+.Nd FreeBSD ASCII art boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the ASCII art BSD brand above the boot
+loader menu.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include brand.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic draw-brand
+Draws the BSD brand.
+.Pp
+The brand that is drawn is configured by setting the
+.Ic loader_brand
+variable in
+.Xr loader.conf 5
+to one of
+.Dq Li fbsd
+(the default) or
+.Dq Li none .
+.Pp
+The position of the logo can be configured by setting the
+.Ic loader_brand_x
+and
+.Ic loader_brand_y
+variables in
+.Xr loader.conf 5 .
+The default values are 2 (x) and 1 (y).
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_brand
+Selects the desired brand in the beastie boot menu. Possible values are:
+.Dq Li fbsd
+(default) or
+.Dq Li none .
+.It Va loader_brand_x
+Sets the desired column position of the brand. Default is 2.
+.It Va loader_brand_y
+Sets the desired row position of the brand. Default is 1.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/brand.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Set FreeBSD brand in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_brand="fbsd"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/check-password.4th b/usr/src/boot/sys/boot/forth/check-password.4th
new file mode 100644
index 0000000000..58d69cd689
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/check-password.4th
@@ -0,0 +1,179 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-check-password.4th
+
+include /boot/forth/screen.4th
+
+vocabulary password-processing
+only forth also password-processing definitions
+
+13 constant enter_key \ The decimal ASCII value for Enter key
+8 constant bs_key \ The decimal ASCII value for Backspace key
+21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence
+255 constant readmax \ Maximum number of characters for the password
+
+variable read-tick \ Twiddle position (used by read)
+variable read-start \ Starting X offset (column)(used by read)
+
+create readval readmax allot \ input obtained (up to readmax characters)
+variable readlen \ input length
+
+\ This function blocks program flow (loops forever) until a key is pressed.
+\ The key that was pressed is added to the top of the stack in the form of its
+\ decimal ASCII representation. Note: the stack cannot be empty when this
+\ function starts or an underflow exception will occur. Simplest way to prevent
+\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
+\ called by the read function. You need not call it directly. NOTE: arrow keys
+\ show as 0 on the stack
+\
+: sgetkey ( -- )
+
+ begin \ Loop forever
+ key? if \ Was a key pressed? (see loader(8))
+ drop \ Remove stack-cruft
+ key \ Get the key that was pressed
+
+ \ Check key pressed (see loader(8)) and input limit
+ dup 0<> if ( and ) readlen @ readmax < if
+ \ Spin the twiddle and then exit this function
+ read-tick @ dup 1+ 4 mod read-tick !
+ 2 spaces
+ dup 0 = if ( 1 ) ." /" else
+ dup 1 = if ( 2 ) ." -" else
+ dup 2 = if ( 3 ) ." \" else
+ dup 3 = if ( 4 ) ." |" else
+ 1 spaces
+ then then then then drop
+ read-start @ 25 at-xy
+ exit
+ then then
+
+ \ Always allow Backspace, Enter, and Ctrl-U
+ dup bs_key = if exit then
+ dup enter_key = if exit then
+ dup ctrl_u = if exit then
+ then
+ 50 ms \ Sleep for 50 milliseconds (see loader(8))
+ again
+;
+
+: cfill ( c c-addr/u -- )
+ begin dup 0> while
+ -rot 2dup c! 1+ rot 1-
+ repeat 2drop drop
+;
+
+: read-reset ( -- )
+ 0 readlen !
+ 0 readval readmax cfill
+;
+
+: read ( c-addr/u -- ) \ Expects string prompt as stack input
+
+ 0 25 at-xy \ Move the cursor to the bottom-left
+ dup 1+ read-start ! \ Store X offset after the prompt
+ 0 readlen ! \ Initialize the read length
+ type \ Print the prompt
+
+ begin \ Loop forever
+
+ 0 sgetkey \ Block here, waiting for a key to be pressed
+
+ \ We are not going to echo the password to the screen (for
+ \ security reasons). If Enter is pressed, we process the
+ \ password, otherwise augment the key to a string.
+
+ dup enter_key = if
+ drop \ Clean up stack cruft
+ 3 spaces \ Erase the twiddle
+ 10 emit \ Echo new line
+ exit
+ else dup ctrl_u = if
+ 3 spaces read-start @ 25 at-xy \ Erase the twiddle
+ 0 readlen ! \ Reset input to NULL
+ else dup bs_key = if
+ readlen @ 1 - dup readlen ! \ Decrement input length
+ dup 0< if drop 0 dup readlen ! then \ Don't go negative
+ 0= if 3 spaces read-start @ 25 at-xy then \ Twiddle
+ else dup \ Store the character
+ \ NB: sgetkey prevents overflow by way of blocking
+ \ at readmax except for Backspace or Enter
+ readlen @ 1+ dup readlen ! 1- readval + c!
+ then then then
+
+ drop \ last key pressed
+ again \ Enter was not pressed; repeat
+;
+
+only forth definitions also password-processing
+
+: check-password ( -- )
+
+ \ Do not allow the user to proceed beyond this point if a boot-lock
+ \ password has been set (preventing even boot from proceeding)
+ s" bootlock_password" getenv dup -1 <> if
+ dup readmax > if drop readmax then
+ begin
+ s" Boot Password: " read ( prompt -- )
+ 2dup readval readlen @ compare 0<>
+ while
+ 3000 ms ." loader: incorrect password" 10 emit
+ repeat
+ 2drop read-reset
+ else drop then
+
+ \ Prompt for GEOM ELI (geli(8)) passphrase if enabled
+ s" geom_eli_passphrase_prompt" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ s" GELI Passphrase: " read ( prompt -- )
+ readval readlen @ s" kern.geom.eli.passphrase" setenv
+ read-reset
+ then
+ else drop then
+
+ \ Exit if a password was not set
+ s" password" getenv -1 = if exit else drop then
+
+ \ We should prevent the user from visiting the menu or dropping to the
+ \ interactive loader(8) prompt, but still allow the machine to boot...
+
+ 0 autoboot
+
+ \ Only reached if autoboot fails for any reason (including if/when
+ \ the user aborts/escapes the countdown sequence leading to boot).
+
+ s" password" getenv dup readmax > if drop readmax then
+ begin
+ s" Password: " read ( prompt -- )
+ 2dup readval readlen @ compare 0= if \ Correct password?
+ 2drop read-reset exit
+ then
+ 3000 ms ." loader: incorrect password" 10 emit
+ again
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/check-password.4th.8 b/usr/src/boot/sys/boot/forth/check-password.4th.8
new file mode 100644
index 0000000000..db0aa4bc6b
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/check-password.4th.8
@@ -0,0 +1,167 @@
+.\" Copyright (c) 2011-2015 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 20, 2015
+.Dt CHECK-PASSWORD.4TH 8
+.Os
+.Sh NAME
+.Nm check-password.4th
+.Nd FreeBSD password-checking boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to do one or more of the following:
+.Pp
+.Dl o Prevent booting without password
+.Dl o Prevent modification of boot options without password
+.Dl o Provide a password to mount geli(8) encrypted root disk(s)
+.Pp
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include check-password.4th
+.Pp
+This line is present in
+.Pa /boot/loader.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic check-password
+Multi-purpose function that can protect the interactive boot menu,
+prevent boot without password, or prompt for geli(8) passphrase
+.Pq depending on Xr loader.conf 5 settings .
+.Pp
+First checks
+.Va bootlock_password
+and if-set, the user cannot continue until the correct password is entered.
+.Pp
+Next, checks
+.Va geom_eli_passphrase_prompt
+and if set to
+.Li YES
+.Pq case-insensitive
+prompts the user to enter their GELI password for later mounting of the root
+device(s) during boot.
+.Pp
+Last, checks
+.Va password
+and if-set, tries to
+.Ic autoboot
+and only prompts for password on failure or user-interrupt.
+See
+.Xr loader.conf 5
+for additional information.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootlock_password -offset indent
+.It Va bootlock_password
+Sets the bootlock password (up to 16 characters long) that is required by
+.Ic check-password
+to be entered before the system is allowed to boot.
+.It Va geom_eli_passphrase_prompt
+Selects whether loader(8) will prompt for GELI credentials, handing-off to the
+kernel for later mounting of
+.Xr geli 8
+encrypted root device(s).
+.It Va password
+Sets the password (up to 16 characters long) that is required by
+.Ic check-password
+before the user is allowed to visit the boot menu.
+.El
+.Sh FILES
+.Bl -tag -width /boot/check-password.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/check-password.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/loader.4th
+check-password
+.Ed
+.Pp
+Set a password in
+.Xr loader.conf 5
+to prevent modification of boot options:
+.Pp
+.Bd -literal -offset indent -compact
+password="abc123"
+.Ed
+.Pp
+Set a password in
+.Xr loader.conf 5
+to prevent booting without password:
+.Pp
+.Bd -literal -offset indent -compact
+bootlock_password="boot"
+.Ed
+.Pp
+Add the following to
+.Xr loader.conf 5
+to generate a prompt at boot to collect GELI credentials for mounting
+.Xr geli 8
+encrypted root device(s):
+.Pp
+.Bd -literal -offset indent -compact
+geom_eli_passphrase_prompt="YES"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/color.4th b/usr/src/boot/sys/boot/forth/color.4th
new file mode 100644
index 0000000000..65e6de905a
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/color.4th
@@ -0,0 +1,49 @@
+\ Copyright (c) 2011-2013 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-color.4th
+
+\ This function returns FALSE if the `loader_color' environment variable is set
+\ to NO, no, or 0. Otherwise, TRUE is returned (unless booting serial).
+\
+: loader_color? ( -- N )
+
+ s" loader_color" getenv dup -1 <> if
+
+ 2dup s" NO" compare-insensitive 0= if
+ 2drop
+ FALSE exit
+ then
+ 2dup s" 0" compare 0= if
+ 2drop
+ FALSE exit
+ then
+ drop
+ then
+ drop
+
+ boot_serial? if FALSE else TRUE then
+;
diff --git a/usr/src/boot/sys/boot/forth/color.4th.8 b/usr/src/boot/sys/boot/forth/color.4th.8
new file mode 100644
index 0000000000..9191da0f04
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/color.4th.8
@@ -0,0 +1,116 @@
+.\" Copyright (c) 2011-2013 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 6, 2013
+.Dt COLOR.4TH 8
+.Os
+.Sh NAME
+.Nm color.4th
+.Nd FreeBSD color-detection boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to simplify color logic.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include color.4th
+.Pp
+This line is present in
+.Pa /boot/loader.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic loader_color?
+Returns FALSE if the
+.Ic loader_color
+environment variable is set to
+.Dq NO
+(case-insensitive) or
+.Dq 0 .
+Otherwise returns TRUE
+.Pq unless booting serial .
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_color
+If set to
+.Dq NO
+(case-insensitive) or
+.Dq 0 ,
+causes
+.Ic loader_color?
+to return FALSE, indicating to many modules that color should not be used.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/color.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+Use color where applicable:
+.Pp
+.Bd -literal -offset indent -compact
+loader_color="YES"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/delay.4th b/usr/src/boot/sys/boot/forth/delay.4th
new file mode 100644
index 0000000000..56dfcf05f4
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/delay.4th
@@ -0,0 +1,119 @@
+\ Copyright (c) 2008-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-delay.4th
+
+vocabulary delay-processing
+only forth also delay-processing definitions
+
+2 constant delay_default \ Default delay (in seconds)
+3 constant etx_key \ End-of-Text character produced by Ctrl+C
+13 constant enter_key \ Carriage-Return character produce by ENTER
+27 constant esc_key \ Escape character produced by ESC or Ctrl+[
+
+variable delay_tstart \ state variable used for delay timing
+variable delay_delay \ determined configurable delay duration
+variable delay_cancelled \ state variable for user cancellation
+variable delay_showdots \ whether continually print dots while waiting
+
+only forth definitions also delay-processing
+
+: delay_execute ( -- )
+
+ \ make sure that we have a command to execute
+ s" delay_command" getenv dup -1 = if
+ drop exit
+ then
+
+ \ read custom time-duration (if set)
+ s" loader_delay" getenv dup -1 = if
+ drop \ no custom duration (remove dup'd bunk -1)
+ delay_default \ use default setting (replacing bunk -1)
+ else
+ \ make sure custom duration is a number
+ ?number 0= if
+ delay_default \ use default if otherwise
+ then
+ then
+
+ \ initialize state variables
+ delay_delay ! \ stored value is on the stack from above
+ seconds delay_tstart ! \ store the time we started
+ 0 delay_cancelled ! \ boolean flag indicating user-cancelled event
+
+ false delay_showdots ! \ reset to zero and read from environment
+ s" delay_showdots" getenv dup -1 <> if
+ 2drop \ don't need the value, just existance
+ true delay_showdots !
+ else
+ drop
+ then
+
+ \ Loop until we have exceeded the desired time duration
+ begin
+ 25 ms \ sleep for 25 milliseconds (40 iterations/sec)
+
+ \ throw some dots up on the screen if desired
+ delay_showdots @ if
+ ." ." \ dots visually aid in the perception of time
+ then
+
+ \ was a key depressed?
+ key? if
+ key \ obtain ASCII value for keystroke
+ dup enter_key = if
+ -1 delay_delay ! \ break loop
+ then
+ dup etx_key = swap esc_key = OR if
+ -1 delay_delay ! \ break loop
+ -1 delay_cancelled ! \ set cancelled flag
+ then
+ then
+
+ \ if the time duration is set to zero, loop forever
+ \ waiting for either ENTER or Ctrl-C/Escape to be pressed
+ delay_delay @ 0> if
+ \ calculate elapsed time
+ seconds delay_tstart @ - delay_delay @ >
+ else
+ -1 \ break loop
+ then
+ until
+
+ \ if we were throwing up dots, throw up a line-break
+ delay_showdots @ if
+ cr
+ then
+
+ \ did the user press either Ctrl-C or Escape?
+ delay_cancelled @ if
+ 2drop \ we don't need the command string anymore
+ else
+ evaluate \ evaluate/execute the command string
+ then
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/delay.4th.8 b/usr/src/boot/sys/boot/forth/delay.4th.8
new file mode 100644
index 0000000000..af31fd04ba
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/delay.4th.8
@@ -0,0 +1,126 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt DELAY.4TH 8
+.Os
+.Sh NAME
+.Nm delay.4th
+.Nd FreeBSD debugging boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to add debugging capabilities to
+.Xr loader 8 .
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include delay.4th
+.Pp
+This line is present in
+.Pa /boot/beastie.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic delay_execute
+Executes the [string] procedure stored in the
+.Ic delay_command
+environment variable after
+.Ic loader_delay
+seconds.
+.Pp
+If the optional
+.Ic delay_showdots
+environment variable is set, a continuous series of dots is printed.
+.Pp
+During the duration, the user can either press Ctrl-C (or Esc) to abort or
+ENTER to proceed immediately.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va delay_command
+The command to be executed by
+.Ic delay_execute .
+.It Va loader_delay
+The duration (in seconds) to delay before executing
+.Ic delay_command .
+.It Va delay_showdots
+If set, will cause
+.Ic delay_execute
+to print a continuous series of dots during the delay duration.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/delay.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Introducing a 5-second delay before including another file from
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/delay.4th
+set delay_command="include /boot/other.4th"
+set delay_showdots
+set loader_delay=5
+delay_execute
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr beastie.4th 8 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/frames.4th b/usr/src/boot/sys/boot/forth/frames.4th
new file mode 100644
index 0000000000..0f8d460aa7
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/frames.4th
@@ -0,0 +1,165 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2012-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-frames.4th
+
+vocabulary frame-drawing
+only forth also frame-drawing definitions
+
+\ XXX Filled boxes are left as an exercise for the reader... ;-/
+
+variable h_el
+variable v_el
+variable lt_el
+variable lb_el
+variable rt_el
+variable rb_el
+variable fill
+
+\ ASCII frames (used when serial console is detected)
+ 45 constant ascii_dash
+ 61 constant ascii_equal
+124 constant ascii_pipe
+ 43 constant ascii_plus
+
+s" arch-pc98" environment? [if]
+ \ Single frames
+ 149 constant sh_el
+ 150 constant sv_el
+ 152 constant slt_el
+ 154 constant slb_el
+ 153 constant srt_el
+ 155 constant srb_el
+ \ Double frames
+ 149 constant dh_el
+ 150 constant dv_el
+ 152 constant dlt_el
+ 154 constant dlb_el
+ 153 constant drt_el
+ 155 constant drb_el
+ \ Fillings
+ 0 constant fill_none
+ 32 constant fill_blank
+ 135 constant fill_dark
+ 135 constant fill_med
+ 135 constant fill_bright
+[else]
+ \ Single frames
+ 196 constant sh_el
+ 179 constant sv_el
+ 218 constant slt_el
+ 192 constant slb_el
+ 191 constant srt_el
+ 217 constant srb_el
+ \ Double frames
+ 205 constant dh_el
+ 186 constant dv_el
+ 201 constant dlt_el
+ 200 constant dlb_el
+ 187 constant drt_el
+ 188 constant drb_el
+ \ Fillings
+ 0 constant fill_none
+ 32 constant fill_blank
+ 176 constant fill_dark
+ 177 constant fill_med
+ 178 constant fill_bright
+[then]
+
+only forth definitions also frame-drawing
+
+: hline ( len x y -- ) \ Draw horizontal single line
+ at-xy \ move cursor
+ 0 do
+ h_el @ emit
+ loop
+;
+
+: f_ascii ( -- ) ( -- ) \ set frames to ascii
+ ascii_dash h_el !
+ ascii_pipe v_el !
+ ascii_plus lt_el !
+ ascii_plus lb_el !
+ ascii_plus rt_el !
+ ascii_plus rb_el !
+;
+
+: f_single ( -- ) \ set frames to single
+ boot_serial? if f_ascii exit then
+ sh_el h_el !
+ sv_el v_el !
+ slt_el lt_el !
+ slb_el lb_el !
+ srt_el rt_el !
+ srb_el rb_el !
+;
+
+: f_double ( -- ) \ set frames to double
+ boot_serial? if
+ f_ascii
+ ascii_equal h_el !
+ exit
+ then
+ dh_el h_el !
+ dv_el v_el !
+ dlt_el lt_el !
+ dlb_el lb_el !
+ drt_el rt_el !
+ drb_el rb_el !
+;
+
+: vline ( len x y -- ) \ Draw vertical single line
+ 2dup 4 pick
+ 0 do
+ at-xy
+ v_el @ emit
+ 1+
+ 2dup
+ loop
+ 2drop 2drop drop
+;
+
+: box ( w h x y -- ) \ Draw a box
+ 2dup 1+ 4 pick 1- -rot
+ vline \ Draw left vert line
+ 2dup 1+ swap 5 pick + swap 4 pick 1- -rot
+ vline \ Draw right vert line
+ 2dup swap 1+ swap 5 pick 1- -rot
+ hline \ Draw top horiz line
+ 2dup swap 1+ swap 4 pick + 5 pick 1- -rot
+ hline \ Draw bottom horiz line
+ 2dup at-xy lt_el @ emit \ Draw left-top corner
+ 2dup 4 pick + at-xy lb_el @ emit \ Draw left bottom corner
+ 2dup swap 5 pick + swap at-xy rt_el @ emit \ Draw right top corner
+ 2 pick + swap 3 pick + swap at-xy rb_el @ emit
+ 2drop
+;
+
+f_single
+fill_none fill !
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/loader.4th b/usr/src/boot/sys/boot/forth/loader.4th
new file mode 100644
index 0000000000..c61bb1033b
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/loader.4th
@@ -0,0 +1,621 @@
+\ Copyright (c) 1999 Daniel C. Sobral <dcs@FreeBSD.org>
+\ Copyright (c) 2011-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+only forth definitions
+
+s" arch-i386" environment? [if] [if]
+ s" loader_version" environment? [if]
+ 11 < [if]
+ .( Loader version 1.1+ required) cr
+ abort
+ [then]
+ [else]
+ .( Could not get loader version!) cr
+ abort
+ [then]
+[then] [then]
+
+include /boot/forth/support.4th
+include /boot/forth/color.4th
+include /boot/forth/delay.4th
+include /boot/forth/check-password.4th
+
+only forth definitions
+
+: bootmsg ( -- )
+ loader_color? dup ( -- bool bool )
+ if 7 fg 4 bg then
+ ." Booting..."
+ if me then
+ cr
+;
+
+: try-menu-unset
+ \ menu-unset may not be present
+ s" beastie_disable" getenv
+ dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ exit
+ then
+ else
+ drop
+ then
+ s" menu-unset"
+ sfind if
+ execute
+ else
+ drop
+ then
+ s" menusets-unset"
+ sfind if
+ execute
+ else
+ drop
+ then
+;
+
+only forth also support-functions also builtins definitions
+
+\ the boot-args was parsed to individual options while loaded
+\ now compose boot-args, so the boot can set kernel arguments
+\ note the command line switched for boot command will cause
+\ environment variable boot-args to be ignored
+\ There are 2 larger strings, acpi-user-options and existing boot-args
+\ other switches are 1 byte each, so allocate boot-args+acpi + extra bytes
+\ for rest. Be sure to review this, if more options are to be added into
+\ environment.
+
+: set-boot-args { | addr len baddr blen aaddr alen -- }
+ s" boot-args" getenv dup -1 <> if
+ to blen to baddr
+ else
+ drop
+ then
+ s" acpi-user-options" getenv dup -1 <> if
+ to alen to aaddr
+ else
+ drop
+ then
+
+ \ allocate temporary space. max is:
+ \ 7 kernel switches
+ \ 26 for acpi, so use 40 for safety
+ blen alen 40 + + allocate abort" out of memory"
+ to addr
+ \ boot-addr may have file name before options, copy it to addr
+ baddr 0<> if
+ baddr c@ [char] - <> if
+ baddr blen [char] - strchr ( addr len )
+ dup 0= if \ no options, copy all
+ 2drop
+ baddr addr blen move
+ blen to len
+ 0 to blen
+ 0 to baddr
+ else ( addr len )
+ dup blen
+ swap -
+ to len ( addr len )
+ to blen ( addr )
+ baddr addr len move ( addr )
+ to baddr \ baddr points now to first option
+ then
+ then
+ then
+ \ now add kernel switches
+ len 0<> if
+ bl addr len + c! len 1+ to len
+ then
+ [char] - addr len + c! len 1+ to len
+
+ s" boot_single" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] s addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+ s" boot_verbose" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] v addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+ s" boot_kmdb" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] k addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+ s" boot_debug" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] d addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+ s" boot_reconfigure" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] r addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+ s" boot_ask" getenv dup -1 <> if
+ s" YES" compare-insensitive 0= if
+ [char] a addr len + c! len 1+ to len
+ then
+ else
+ drop
+ then
+
+ \ now add remining boot args if blen != 0.
+ \ baddr[0] is '-', if baddr[1] != 'B' append to addr,
+ \ otherwise add space then copy
+ blen 0<> if
+ baddr 1+ c@ [char] B = if
+ addr len + 1- c@ [char] - = if \ if addr[len -1] == '-'
+ baddr 1+ to baddr
+ blen 1- to blen
+ else
+ bl addr len + c! len 1+ to len
+ then
+ else
+ baddr 1+ to baddr
+ blen 1- to blen
+ then
+ baddr addr len + blen move
+ len blen + to len
+ 0 to baddr
+ 0 to blen
+ then
+ \ last part - add acpi.
+ alen 0<> if
+ addr len + 1- c@ [char] - <> if
+ bl addr len + c! len 1+ to len
+ [char] - addr len + c! len 1+ to len
+ then
+ s" B acpi-user-options=" dup -rot ( len addr len )
+ addr len + swap move ( len )
+ len + to len
+ aaddr addr len + alen move
+ len alen + to len
+ then
+
+ \ check for left over '-'
+ addr len 1- + c@ [char] - = if
+ len 1- to len
+ \ but now we may also have left over ' '
+ len if ( len <> 0 )
+ addr len 1- + c@ bl = if
+ len 1- to len
+ then
+ then
+ then
+
+ \ if len != 0, set boot-args
+ len 0<> if
+ addr len s" boot-args" setenv
+ then
+ addr free drop
+;
+
+: boot
+ 0= if ( interpreted ) get_arguments then
+ set-boot-args
+
+ \ Unload only if a path was passed. Paths start with /
+ dup if
+ >r over r> swap
+ c@ [char] / = if
+ 0 1 unload drop
+ else
+ s" kernelname" getenv? if ( a kernel has been loaded )
+ try-menu-unset
+ bootmsg 1 boot exit
+ then
+ load_kernel_and_modules
+ ?dup if exit then
+ try-menu-unset
+ bootmsg 0 1 boot exit
+ then
+ else
+ s" kernelname" getenv? if ( a kernel has been loaded )
+ try-menu-unset
+ bootmsg 1 boot exit
+ then
+ load_kernel_and_modules
+ ?dup if exit then
+ try-menu-unset
+ bootmsg 0 1 boot exit
+ then
+ load_kernel_and_modules
+ ?dup 0= if bootmsg 0 1 boot then
+;
+
+\ ***** boot-conf
+\
+\ Prepares to boot as specified by loaded configuration files.
+
+: boot-conf
+ 0= if ( interpreted ) get_arguments then
+ 0 1 unload drop
+ load_kernel_and_modules
+ ?dup 0= if 0 1 autoboot then
+;
+
+also forth definitions previous
+
+builtin: boot
+builtin: boot-conf
+
+only forth definitions also support-functions
+
+\
+\ in case the boot-args is set, parse it and extract following options:
+\ -a to boot_ask=YES
+\ -s to boot_single=YES
+\ -v to boot_verbose=YES
+\ -k to boot_kmdb=YES
+\ -d to boot_debug=YES
+\ -r to boot_reconfigure=YES
+\ -B acpi-user-options=X to acpi-user-options=X
+\
+\ This is needed so that the menu can manage these options. Unfortunately, this
+\ also means that boot-args will override previously set options, but we have no\ way to control the processing order here. boot-args will be rebuilt at boot.
+\
+\ NOTE: The best way to address the order is to *not* set any above options
+\ in boot-args.
+
+: parse-boot-args { | baddr blen -- }
+ s" boot-args" getenv dup -1 = if drop exit then
+ to blen
+ to baddr
+
+ baddr blen
+
+ \ loop over all instances of switch blocks, starting with '-'
+ begin
+ [char] - strchr
+ 2dup to blen to baddr
+ dup 0<>
+ while ( addr len ) \ points to -
+ \ block for switch B. keep it on top of the stack for case
+ \ the property list will get empty.
+
+ over 1+ c@ [char] B = if
+ 2dup \ save "-B ...." in case options is empty
+ 2 - swap 2 + ( addr len len-2 addr+2 ) \ skip -B
+
+ begin \ skip spaces
+ dup c@ bl =
+ while
+ 1+ swap 1- swap
+ repeat
+
+ ( addr len len' addr' )
+ \ its 3 cases now: end of string, -switch, or option list
+
+ over 0= if \ end of string, remove trailing -B
+ 2drop ( addr len )
+ swap 0 swap c! \ store 0 at -B
+ blen swap ( blen len )
+ - ( rem )
+ baddr swap ( addr rem )
+ dup 0= if
+ s" boot-args" unsetenv
+ 2drop
+ exit
+ then
+ \ trailing space(s)
+ begin
+ over ( addr rem addr )
+ over + 1- ( addr rem addr+rem-1 )
+ c@ bl =
+ while
+ 1- swap ( rem-1 addr )
+ over ( rem-1 addr rem-1 )
+ over + ( rem-1 addr addr+rem-1 )
+ 0 swap c!
+ swap
+ repeat
+ s" boot-args" setenv
+ recurse \ restart
+ exit
+ then
+ ( addr len len' addr' )
+ dup c@ [char] - = if \ it is switch. set to boot-args
+ swap s" boot-args" setenv
+ 2drop
+ recurse \ restart
+ exit
+ then
+ ( addr len len' addr' )
+ \ its options string "option1,option2,... -..."
+ \ cut acpi-user-options=xxx and restart the parser
+ \ or skip to next option block
+ begin
+ dup c@ dup 0<> swap bl <> and \ stop if space or 0
+ while
+ dup 18 s" acpi-user-options=" compare 0= if \ matched
+ ( addr len len' addr' )
+ \ addr' points to acpi options, find its end [',' or ' ' or 0 ]
+ \ set it as acpi-user-options and move remaining to addr'
+ 2dup ( addr len len' addr' len' addr' )
+ \ skip to next option in list
+ \ loop to first , or bl or 0
+ begin
+ dup c@ [char] , <> >r
+ dup c@ bl <> >r
+ dup c@ 0<> r> r> and and
+ while
+ 1+ swap 1- swap
+ repeat
+ ( addr len len' addr' len" addr" )
+ >r >r ( addr len len' addr' R: addr" len" )
+ over r@ - ( addr len len' addr' proplen R: addr" len" )
+ dup 5 + ( addr len len' addr' proplen proplen+5 )
+ allocate abort" out of memory"
+
+ 0 s" set " strcat ( addr len len' addr' proplen caddr clen )
+ >r >r 2dup r> r> 2swap strcat ( addr len len' addr' proplen caddr clen )
+ 2dup + 0 swap c! \ terminate with 0
+ 2dup evaluate drop free drop
+ ( addr len len' addr' proplen R: addr" len" )
+ \ acpi-user-options is set, now move remaining string to its place.
+ \ addr: -B, addr': acpi... addr": reminder
+ swap ( addr len len' proplen addr' )
+ r> r> ( addr len len' proplen addr' len" addr" )
+ dup c@ [char] , = if
+ \ skip , and move addr" to addr'
+ 1+ swap 1- ( addr len len' proplen addr' addr" len" )
+ rot swap 1+ move ( addr len len' proplen )
+ else \ its bl or 0 ( addr len len' proplen addr' len" addr" )
+ \ for both bl and 0 we need to copy to addr'-1 to remove
+ \ comma, then reset boot-args, and recurse will clear -B
+ \ if there are no properties left.
+ dup c@ 0= if
+ 2drop ( addr len len' proplen addr' )
+ 1- 0 swap c! ( addr len len' proplen )
+ else
+ >r >r ( addr len len' proplen addr' R: addr" len" )
+ 1- swap 1+ swap
+ r> r> ( addr len len' proplen addr' len" addr" )
+ rot rot move ( addr len len' proplen )
+ then
+ then
+
+ 2swap 2drop ( len' proplen )
+ nip ( proplen )
+ baddr blen rot -
+ s" boot-args" setenv
+ recurse
+ exit
+ else
+ ( addr len len' addr' )
+ \ not acpi option, skip to next option in list
+ \ loop to first , or bl or 0
+ begin
+ dup c@ [char] , <> >r
+ dup c@ bl <> >r
+ dup c@ 0<> r> r> and and
+ while
+ 1+ swap 1- swap
+ repeat
+ \ if its ',', skip over
+ dup c@ [char] , = if
+ 1+ swap 1- swap
+ then
+ then
+ repeat
+ ( addr len len' addr' )
+ \ this block is done, remove addr and len from stack
+ 2swap 2drop swap
+ then
+
+ over c@ [char] - = if ( addr len )
+ 2dup 1- swap 1+ ( addr len len' addr' )
+ begin \ loop till ' ' or 0
+ dup c@ dup 0<> swap bl <> and
+ while
+ dup c@ [char] s = if
+ s" set boot_single=YES" evaluate TRUE
+ else dup c@ [char] v = if
+ s" set boot_verbose=YES" evaluate TRUE
+ else dup c@ [char] k = if
+ s" set boot_kmdb=YES" evaluate TRUE
+ else dup c@ [char] d = if
+ s" set boot_debug=YES" evaluate TRUE
+ else dup c@ [char] r = if
+ s" set boot_reconfigure=YES" evaluate TRUE
+ else dup c@ [char] a = if
+ s" set boot_ask=YES" evaluate TRUE
+ then then then then then then
+ dup TRUE = if
+ drop
+ dup >r ( addr len len' addr' R: addr' )
+ 1+ swap 1- ( addr len addr'+1 len'-1 R: addr' )
+ r> swap move ( addr len )
+
+ 2drop baddr blen 1-
+ \ check if we have space after '-', if so, drop '- '
+ swap dup 1+ c@ bl = if
+ 2 + swap 2 -
+ else
+ swap
+ then
+ dup dup 0= swap 1 = or if \ empty or only '-' is left.
+ 2drop
+ s" boot-args" unsetenv
+ exit
+ else
+ s" boot-args" setenv
+ then
+ recurse
+ exit
+ then
+ 1+ swap 1- swap
+ repeat
+
+ 2swap 2drop
+ dup c@ 0= if \ end of string
+ 2drop
+ exit
+ else
+ swap
+ then
+ then
+ repeat
+
+ 2drop
+;
+
+\ ***** start
+\
+\ Initializes support.4th global variables, sets loader_conf_files,
+\ processes conf files, and, if any one such file was succesfully
+\ read to the end, loads kernel and modules.
+
+: start ( -- ) ( throws: abort & user-defined )
+ s" /boot/defaults/loader.conf" initialize
+ include_bootenv
+ include_conf_files
+ include_transient
+ parse-boot-args
+ \ Will *NOT* try to load kernel and modules if no configuration file
+ \ was succesfully loaded!
+ any_conf_read? if
+ s" loader_delay" getenv -1 = if
+ load_xen_throw
+ load_kernel
+ load_modules
+ else
+ drop
+ ." Loading Kernel and Modules (Ctrl-C to Abort)" cr
+ s" also support-functions" evaluate
+ s" set delay_command='load_xen_throw load_kernel load_modules'" evaluate
+ s" set delay_showdots" evaluate
+ delay_execute
+ then
+ then
+;
+
+\ ***** initialize
+\
+\ Overrides support.4th initialization word with one that does
+\ everything start one does, short of loading the kernel and
+\ modules. Returns a flag
+
+: initialize ( -- flag )
+ s" /boot/defaults/loader.conf" initialize
+ include_bootenv
+ include_conf_files
+ include_transient
+ parse-boot-args
+ any_conf_read?
+;
+
+\ ***** read-conf
+\
+\ Read a configuration file, whose name was specified on the command
+\ line, if interpreted, or given on the stack, if compiled in.
+
+: (read-conf) ( addr len -- )
+ conf_files string=
+ include_conf_files \ Will recurse on new loader_conf_files definitions
+;
+
+: read-conf ( <filename> | addr len -- ) ( throws: abort & user-defined )
+ state @ if
+ \ Compiling
+ postpone (read-conf)
+ else
+ \ Interpreting
+ bl parse (read-conf)
+ then
+; immediate
+
+\ show, enable, disable, toggle module loading. They all take module from
+\ the next word
+
+: set-module-flag ( module_addr val -- ) \ set and print flag
+ over module.flag !
+ dup module.name strtype
+ module.flag @ if ." will be loaded" else ." will not be loaded" then cr
+;
+
+: enable-module find-module ?dup if true set-module-flag then ;
+
+: disable-module find-module ?dup if false set-module-flag then ;
+
+: toggle-module find-module ?dup if dup module.flag @ 0= set-module-flag then ;
+
+\ ***** show-module
+\
+\ Show loading information about a module.
+
+: show-module ( <module> -- ) find-module ?dup if show-one-module then ;
+
+\ Words to be used inside configuration files
+
+: retry false ; \ For use in load error commands
+: ignore true ; \ For use in load error commands
+
+\ Return to strict forth vocabulary
+
+: #type
+ over - >r
+ type
+ r> spaces
+;
+
+: .? 2 spaces 2swap 15 #type 2 spaces type cr ;
+
+: ?
+ ['] ? execute
+ s" boot-conf" s" load kernel and modules, then autoboot" .?
+ s" read-conf" s" read a configuration file" .?
+ s" enable-module" s" enable loading of a module" .?
+ s" disable-module" s" disable loading of a module" .?
+ s" toggle-module" s" toggle loading of a module" .?
+ s" show-module" s" show module load data" .?
+ s" try-include" s" try to load/interpret files" .?
+ s" beadm" s" list or activate Boot Environments" .?
+;
+
+: try-include ( -- ) \ see loader.4th(8)
+ ['] include ( -- xt ) \ get the execution token of `include'
+ catch ( xt -- exception# | 0 ) if \ failed
+ LF parse ( c -- s-addr/u ) 2drop \ advance >in to EOL (drop data)
+ \ ... prevents words unused by `include' from being interpreted
+ then
+; immediate \ interpret immediately for access to `source' (aka tib)
+
+include /boot/forth/beadm.4th
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/loader.4th.8 b/usr/src/boot/sys/boot/forth/loader.4th.8
new file mode 100644
index 0000000000..b689077058
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/loader.4th.8
@@ -0,0 +1,233 @@
+.\" Copyright (c) 1999 Daniel C. Sobral
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 13, 2013
+.Dt LOADER.4TH 8
+.Os
+.Sh NAME
+.Nm loader.4th
+.Nd loader.conf processing tools
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to manipulate
+.Xr loader.conf 5
+files.
+The default
+.Pa /boot/loader.rc
+includes
+.Nm
+and uses one of its commands to automatically read and process
+the standard
+.Xr loader.conf 5
+files.
+Other commands exists to help the user specify alternate
+configurations.
+.Pp
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include loader.4th
+.Pp
+This line is present in the default
+.Pa /boot/loader.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic boot
+.It Ic boot Ar kernelname Op Cm ...
+.It Ic boot Ar directory Op Cm ...
+.It Ic boot Fl flag Cm ...
+Boot as specified by the
+.Xr loader.conf 5
+files read.
+.Pp
+Depending on the arguments passed, it can override boot flags and
+either the kernel name or the search path for kernel and modules.
+.Pp
+.It Ic boot-conf
+.It Ic boot-conf Ar kernelname Op Cm ...
+.It Ic boot-conf Ar directory Op Cm ...
+.It Ic boot-conf Fl flag Cm ...
+Works like
+.Ic boot
+described above, but instead of booting immediately, uses
+.Ic autoboot ,
+so it can be stopped.
+.Pp
+.It Ic start
+Reads
+.Pa /boot/defaults/loader.conf ,
+all other
+.Xr loader.conf 5
+files specified in it, then loads the desired kernel and modules
+.Pq if not already loaded .
+After which you can use the
+.Ic boot
+or
+.Ic autoboot
+commmands or simply exit (provided
+.Va autoboot_delay
+is not set to NO) to boot the system.
+.Ic start
+is the command used in the default
+.Pa /boot/loader.rc
+file
+.Pq see Xr loader 8 .
+.Pp
+.It Ic initialize
+Initialize the support library so commands can be used without executing
+.Ic start
+first.
+Like
+.Ic start ,
+it reads
+.Pa /boot/defaults/loader.conf
+and all other
+.Xr loader.conf 5
+files specified in it
+.Pq but does not load kernel or modules .
+Returns a flag on the stack to indicate
+if any configuration files were successfully loaded.
+.Pp
+.It Ic read-conf Ar filename
+Reads and processes a
+.Xr loader.conf 5
+file.
+Does not proceed to boot.
+.Pp
+.It Ic enable-module Ar module
+Enables the loading of
+.Ar module .
+.Pp
+.It Ic disable-module Ar module
+Disables the loading of
+.Ar module .
+.Pp
+.It Ic toggle-module Ar module
+Toggles the loading of
+.Ar module
+on and off.
+.Pp
+.It Ic show-module Ar module
+Shows the information gathered in the
+.Xr loader.conf 5
+files about the module
+.Ar module .
+.Pp
+.It Ic retry
+Used inside
+.Xr loader.conf 5
+files to specify the action after a module loading fails.
+.Pp
+.It Ic ignore
+Used inside
+.Xr loader.conf 5
+files to specify the action after a module loading fails.
+.It Ic try-include Ar file Op Ar
+Process script files if they exist.
+Each file, in turn, is completely read into memory,
+and then each of its lines is passed to the command line interpreter.
+If any error is returned by the interpreter, the try-include
+command aborts immediately, without reading any other files, and
+silently returns without error.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/loader.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.It Pa /boot/defaults/loader.conf
+File loaded by the
+.Ic start
+command.
+.El
+.Sh EXAMPLES
+Standard
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/loader.4th
+start
+.Ed
+.Pp
+Load a different kernel with the standard configuration:
+.Pp
+.Bd -literal -offset indent -compact
+set kernel="kernel.old"
+unload
+boot-conf
+.Ed
+.Pp
+Read an additional configuration file and then proceed to boot:
+.Pp
+.Bd -literal -offset indent -compact
+unload
+read-conf /boot/special.conf
+boot-conf
+.Ed
+.Pp
+Disable the loading of the splash screen module and bitmap and then
+proceed to boot:
+.Pp
+.Bd -literal -offset indent -compact
+unload
+disable-module splash_bmp
+disable-module bitmap
+boot-conf
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 3.2 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An Daniel C. Sobral Aq dcs@FreeBSD.org .
+.Sh BUGS
+A British espionage series.
diff --git a/usr/src/boot/sys/boot/forth/loader.conf b/usr/src/boot/sys/boot/forth/loader.conf
new file mode 100644
index 0000000000..b1e0fb6a16
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/loader.conf
@@ -0,0 +1,94 @@
+# This is loader.conf - a file full of useful variables that you can
+# set to change the default load behavior of your system. You should
+# not edit this file! Put any overrides into one of the
+# loader_conf_files instead and you will be able to update these
+# defaults later without spamming your local configuration information.
+#
+# All arguments must be in double quotes.
+#
+
+##############################################################
+### Basic configuration options ############################
+##############################################################
+
+exec=".( Loading /boot/defaults/loader.conf ) cr"
+
+kernel="i86pc/kernel/${ISADIR}" # /platform sub-directory containing kernel
+bootfile="unix" # Kernel name (possibly absolute path)
+# boot-args="" # Flags to be passed to the kernel
+
+# default list of explicit config files.
+# the load order for config files is:
+# /boot/defaults/loader.conf, files listed in loader_conf_files,
+# config snippets in /boot/conf.d in lexicographical order
+# last is /boot/transient.conf
+# note the transient.conf is for automatic temporary options
+# managed by bootadm
+# /boot/conf.d is managed by bootadm and preferred directory for
+# custom options.
+loader_conf_files="/boot/loader.conf /boot/loader.conf.local"
+
+verbose_loading="NO" # Set to YES for verbose loader output
+
+
+##############################################################
+### Splash screen configuration ############################
+##############################################################
+
+# splash_bmp_load="NO" # Set this to YES for bmp splash screen!
+# splash_pcx_load="NO" # Set this to YES for pcx splash screen!
+# splash_txt_load="NO" # Set this to YES for TheDraw splash screen!
+# vesa_load="NO" # Set this to YES to load the vesa module
+# bitmap_load="NO" # Set this to YES if you want splash screen!
+# bitmap_name="splash.bmp" # Set this to the name of the file
+# bitmap_type="splash_image_data" # and place it on the module_path
+
+
+##############################################################
+### Loader settings ########################################
+##############################################################
+
+#loader_delay="3" # Delay in seconds before loading anything.
+ # Default is unset and disabled (no delay).
+autoboot_delay="10" # Delay in seconds before autobooting,
+ # set to -1 if you don't want user to be
+ # allowed to interrupt autoboot process and
+ # escape to the loader prompt, set to
+ # "NO" to disable autobooting
+beastie_disable="NO" # Turn the beastie boot menu on and off
+loader_logo="illumos" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none
+#loader_brand="illumos" # brand name
+#console="text" # A comma separated list of console(s)
+#currdev="disk1s1a" # Set the current device
+module_path="/platform/i86pc/${ISADIR}/" # Set the module search path
+#prompt="\\${interpret}" # Set the command prompt
+#root_disk_unit="0" # Force the root disk unit number
+#rootdev="disk1s1a" # Set the root filesystem
+#tftp.blksize="1428" # Set the RFC 2348 TFTP block size.
+ # If the TFTP server does not support RFC 2348,
+ # the block size is set to 512. If the value
+ # is out of range ( < 8 || > 9008 ) an error is
+ # returned.
+
+##############################################################
+### boot archive ###########################################
+##############################################################
+boot_archive_load="YES" # illumos will not boot without rootfs
+boot_archive_type="rootfs"
+boot_archive_name="/platform/i86pc/${ISADIR}/boot_archive"
+
+boot_archive.hash_load="YES" # use hash file as it will use ISADIR
+boot_archive.hash_type="hash"
+boot_archive.hash_name="/platform/i86pc/${ISADIR}/boot_archive.hash"
+
+##############################################################
+### Module loading syntax example ##########################
+##############################################################
+
+#module_load="YES" # loads module "module"
+#module_name="realname" # uses "realname" instead of "module"
+#module_type="type" # passes "-t type" to load
+#module_flags="flags" # passes "flags" to the module
+#module_before="cmd" # executes "cmd" before loading the module
+#module_after="cmd" # executes "cmd" after loading the module
+#module_error="cmd" # executes "cmd" if load fails
diff --git a/usr/src/boot/sys/boot/forth/loader.conf.5 b/usr/src/boot/sys/boot/forth/loader.conf.5
new file mode 100644
index 0000000000..0320e988cd
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/loader.conf.5
@@ -0,0 +1,305 @@
+.\" Copyright (c) 1999 Daniel C. Sobral
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd January 6, 2016
+.Dt LOADER.CONF 5
+.Os
+.Sh NAME
+.Nm loader.conf
+.Nd "system bootstrap configuration information"
+.Sh DESCRIPTION
+The file
+.Nm
+contains descriptive information on bootstrapping the system.
+Through
+it you can specify the kernel to be booted, parameters to be passed to
+it, and additional modules to be loaded; and generally set all variables
+described in
+.Xr loader 8 .
+.Pp
+The file
+.Pa /boot/loader.rc
+must contain the following two lines for
+.Nm
+to be automatically processed:
+.Pp
+.Dl include /boot/loader.4th
+.Dl start
+.Pp
+If no
+.Pa /boot/loader.rc
+exists at installworld time, one with the above lines will be installed.
+.Sh SYNTAX
+Though
+.Nm Ns 's
+format was defined explicitly to resemble
+.Xr rc.conf 5 ,
+and can be sourced by
+.Xr sh 1 ,
+some settings are treated in a special fashion.
+Also, the
+behavior of some settings is defined by the setting's suffix;
+the prefix identifies which module the setting controls.
+.Pp
+The general parsing rules are:
+.Bl -bullet
+.It
+Spaces and empty lines are ignored.
+.It
+A # sign will mark the remainder of the line as a comment.
+.It
+Only one setting can be present on each line.
+.El
+.Pp
+All settings have the following format:
+.Pp
+.Dl variable="value"
+.Pp
+Unless it belongs to one of the classes of settings that receive special
+treatment, a setting will set the value of a
+.Xr loader 8
+environment variable.
+The settings that receive special
+treatment are listed below.
+Settings beginning with
+.Qq *
+below define the modules to be loaded and
+may have any prefix; the prefix identifies a module.
+All such settings sharing a common
+prefix refer to the same module.
+.Bl -tag -width Ar
+.It Ar exec
+Immediately executes a
+.Xr loader 8
+command.
+This type of setting cannot be processed by programs other
+than
+.Xr loader 8 ,
+so its use should be avoided.
+Multiple instances of it will be processed
+independently.
+.It Ar loader_conf_files
+Defines additional configuration files to be processed right after the
+present file.
+.It Ar kernel
+Name of the kernel to be loaded.
+If no kernel name is set, no additional
+modules will be loaded.
+The name must be a subdirectory of
+.Pa /boot
+that contains a kernel.
+.It Ar kernel_options
+Flags to be passed to the kernel.
+.It Ar password
+Protect boot menu with a password without interrupting
+.Ic autoboot
+process.
+The password should be in clear text format.
+If a password is set, boot menu will not appear until any key is pressed during
+countdown period specified by
+.Va autoboot_delay
+variable or
+.Ic autoboot
+process fails.
+In both cases user should provide specified password to be able to access boot
+menu.
+.It Ar bootlock_password
+Provides a password to be required by check-password before execution is
+allowed to continue.
+The password should be in clear text format.
+If a password is set, the user must provide specified password to boot.
+.It Ar verbose_loading
+If set to
+.Dq YES ,
+module names will be displayed as they are loaded.
+.It Ar *_load
+If set to
+.Dq YES ,
+that module will be loaded.
+If no name is defined (see below), the
+module's name is taken to be the same as the prefix.
+.It Ar *_name
+Defines the name of the module.
+.It Ar *_type
+Defines the module's type.
+If none is given, it defaults to a kld module.
+.It Ar *_flags
+Flags and parameters to be passed to the module.
+.It Ar *_before
+Commands to be executed before the module is loaded.
+Use of this setting
+should be avoided.
+.It Ar *_after
+Commands to be executed after the module is loaded.
+Use of this setting
+should be avoided.
+.It Ar *_error
+Commands to be executed if the loading of a module fails.
+Except for the
+special value
+.Dq abort ,
+which aborts the bootstrap process, use of this setting should be avoided.
+.El
+.Pp
+.Em WARNING:
+developers should never use these suffixes for any kernel environment
+variables (tunables) or conflicts will result.
+.Sh DEFAULT SETTINGS
+Most of
+.Nm Ns 's
+default settings can be ignored.
+The few of them which are important
+or useful are:
+.Bl -tag -width bootfile -offset indent
+.It Va bitmap_load
+.Pq Dq NO
+If set to
+.Dq YES ,
+a bitmap will be loaded to be displayed on screen while booting.
+.It Va bitmap_name
+.Pq Dq Pa /boot/splash.bmp
+Name of the bitmap to be loaded.
+Any other name can be used.
+.It Va comconsole_speed
+.Dq ( 9600
+or the value of the
+.Va BOOT_COMCONSOLE_SPEED
+variable when
+.Xr loader 8
+was compiled).
+Sets the speed of the serial console.
+If the previous boot loader stage specified that a serial console
+is in use then the default speed is determined from the current
+serial port speed setting.
+.It Va console
+.Pq Dq vidconsole
+.Dq comconsole
+selects serial console,
+.Dq vidconsole
+selects the video console,
+.Dq nullconsole
+selects a mute console
+(useful for systems with neither a video console nor a serial port), and
+.Dq spinconsole
+selects the video console which prevents any input and hides all output
+replacing it with
+.Dq spinning
+character (useful for embedded products and such).
+.It Va kernel
+.Pq Dq kernel
+.It Va kernels
+.Pq Dq kernel kernel.old
+Space or comma separated list of kernels to present in the boot menu.
+.It Va loader_conf_files
+.Pq Dq Pa /boot/loader.conf /boot/loader.conf.local
+.It Va splash_bmp_load
+.Pq Dq NO
+If set to
+.Dq YES ,
+will load the splash screen module, making it possible to display a bmp image
+on the screen while booting.
+.It Va splash_pcx_load
+.Pq Dq NO
+If set to
+.Dq YES ,
+will load the splash screen module, making it possible to display a pcx image
+on the screen while booting.
+.It Va vesa_load
+.Pq Dq NO
+If set to
+.Dq YES ,
+the vesa module will be loaded, enabling bitmaps above VGA resolution to
+be displayed.
+.It Va beastie_disable
+If set to
+.Dq YES ,
+the beastie boot menu will be skipped.
+The beastie boot menu is always skipped if running non-x86 hardware.
+.It Va loader_logo Pq Dq Li orbbw
+Selects a desired logo in the beastie boot menu.
+Possible values are:
+.Dq Li orbbw ,
+.Dq Li orb ,
+.Dq Li fbsdbw ,
+.Dq Li beastiebw ,
+.Dq Li beastie ,
+and
+.Dq Li none .
+.It Va loader_color
+If set to
+.Dq NO ,
+the beastie boot menu will be displayed without ANSI coloring.
+.It Va entropy_cache_load
+.Pq Dq YES
+If set to
+.Dq NO ,
+the very early
+boot-time entropy file
+will not be loaded.
+See the entropy entries in
+.Xr rc.conf 5 .
+.It Va entropy_cache_name
+.Pq Dq /boot/entropy
+The name of the very early
+boot-time entropy cache file.
+.El
+.Sh FILES
+.Bl -tag -width /boot/defaults/loader.conf -compact
+.It Pa /boot/defaults/loader.conf
+default settings -- do not change this file.
+.It Pa /boot/loader.4th
+defines the commands used by loader to read and process
+.Nm .
+.It Pa /boot/loader.conf
+user defined settings.
+.It Pa /boot/loader.conf.local
+machine-specific settings for sites with a common loader.conf.
+.It Pa /boot/loader.rc
+contains the instructions to automatically process
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr rc.conf 5 ,
+.Xr boot 8 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The file
+.Nm
+first appeared in
+.Fx 3.2 .
+.Sh AUTHORS
+This manual page was written by
+.An Daniel C. Sobral Aq dcs@FreeBSD.org .
+.Sh BUGS
+The
+.Xr loader 8
+stops reading
+.Nm
+when it encounters a syntax error, so any options which are vital for
+booting a particular system (i.e.\&
+.Dq Va hw.ata.ata_dma Ns "=0" )
+should precede any experimental additions to
+.Nm .
diff --git a/usr/src/boot/sys/boot/forth/loader.rc b/usr/src/boot/sys/boot/forth/loader.rc
new file mode 100644
index 0000000000..1bdc5dca30
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/loader.rc
@@ -0,0 +1,20 @@
+\ Loader.rc
+\
+\ Includes additional commands
+include /boot/forth/loader.4th
+try-include /boot/loader.rc.local
+
+\ Reads and processes loader.conf variables
+\ NOTE: Change to `initialize' if you enable the below boot menu
+\ also note that initialize will leave flag in stack from any_conf_read?
+\ start
+initialize drop
+
+\ Tests for password -- executes autoboot first if a password was defined
+check-password
+
+\ Uncomment to enable boot menu
+include /boot/forth/beastie.4th
+beastie-start
+
+\ Unless set otherwise, autoboot is automatic at this point
diff --git a/usr/src/boot/sys/boot/forth/logo-beastie.4th b/usr/src/boot/sys/boot/forth/logo-beastie.4th
new file mode 100644
index 0000000000..671eb5e496
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-beastie.4th
@@ -0,0 +1,61 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+46 logoX ! 4 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ [char] @ escc! \ replace @ with Esc
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ color BSD mascot (19 rows x 34 columns)
+
+ s" @[31m, ," logo+
+ s" /( )`" logo+
+ s" \ \___ / |" logo+
+ s" /- @[m_@[31m `-/ '" logo+
+ s" (@[m/\/ \@[31m \ /\" logo+
+ s" @[m/ / |@[31m ` \" logo+
+ s" @[34mO O @[m) @[31m/ |" logo+
+ s" @[m`-^--'@[31m`< '" logo+
+ s" (_.) _ ) /" logo+
+ s" `.___/` /" logo+
+ s" `-----' /" logo+
+ s" @[33m<----.@[31m __ / __ \" logo+
+ s" @[33m<----|====@[31mO)))@[33m==@[31m) \) /@[33m====|" logo+
+ s" @[33m<----'@[31m `--' `.__,' \" logo+
+ s" | |" logo+
+ s" \ / /\" logo+
+ s" @[36m______@[31m( (_ / \______/" logo+
+ s" @[36m,' ,-----' |" logo+
+ s" `--{__________)@[m" logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/logo-beastiebw.4th b/usr/src/boot/sys/boot/forth/logo-beastiebw.4th
new file mode 100644
index 0000000000..197099cda0
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-beastiebw.4th
@@ -0,0 +1,59 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+46 logoX ! 4 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ B/W BSD mascot (19 rows x 34 columns)
+
+ s" , ," logo+
+ s" /( )`" logo+
+ s" \ \___ / |" logo+
+ s" /- _ `-/ '" logo+
+ s" (/\/ \ \ /\" logo+
+ s" / / | ` \" logo+
+ s" O O ) / |" logo+
+ s" `-^--'`< '" logo+
+ s" (_.) _ ) /" logo+
+ s" `.___/` /" logo+
+ s" `-----' /" logo+
+ s" <----. __ / __ \" logo+
+ s" <----|====O)))==) \) /====|" logo+
+ s" <----' `--' `.__,' \" logo+
+ s" | |" logo+
+ s" \ / /\" logo+
+ s" ______( (_ / \______/" logo+
+ s" ,' ,-----' |" logo+
+ s" `--{__________)" logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/logo-fbsdbw.4th b/usr/src/boot/sys/boot/forth/logo-fbsdbw.4th
new file mode 100644
index 0000000000..d4a532b78f
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-fbsdbw.4th
@@ -0,0 +1,53 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+52 logoX ! 9 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ "FreeBSD" logo in B/W (13 rows x 21 columns)
+
+ s" ______" logo+
+ s" | ____| __ ___ ___ " logo+
+ s" | |__ | '__/ _ \/ _ \" logo+
+ s" | __|| | | __/ __/" logo+
+ s" | | | | | | |" logo+
+ s" |_| |_| \___|\___|" logo+
+ s" ____ _____ _____" logo+
+ s" | _ \ / ____| __ \" logo+
+ s" | |_) | (___ | | | |" logo+
+ s" | _ < \___ \| | | |" logo+
+ s" | |_) |____) | |__| |" logo+
+ s" | | | |" logo+
+ s" |____/|_____/|_____/" logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/logo-illumos.4th b/usr/src/boot/sys/boot/forth/logo-illumos.4th
new file mode 100644
index 0000000000..77b28a683b
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-illumos.4th
@@ -0,0 +1,61 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+46 logoX ! 4 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ [char] @ escc! \ replace @ with Esc
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ color Illumos logo
+
+ s" @[33m, " logo+
+ s" @[33m,./% @[31m& " logo+
+ s" @[33m(****@[31m*( " logo+
+ s" @[33m*/*@[31m// " logo+
+ s" @[33m*,//@[31m/(( " logo+
+ s" @[33m,*/@[31m/((/% " logo+
+ s" @[33m//@[31m/((((% " logo+
+ s" @[33m,*@[31m/(((((% @[33m&@[31m#///((&" logo+
+ s" @[33m./@[31m//((((((% %/(((/ " logo+
+ s" @[33m./@[31m///(((((///((, " logo+
+ s" @[33m.*//@[31m//(((((((((( " logo+
+ s" ./((((((((/ " logo+
+ s" (/((((((( " logo+
+ s" ,,((((((/ " logo+
+ s" /(((( " logo+
+ s" %/(((( " logo+
+ s" @[33m&@[31m%#/((((. " logo+
+ s" @[33m,@[31m( ,/ /(/ " logo+
+ s" ,/@[m " logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/logo-orb.4th b/usr/src/boot/sys/boot/forth/logo-orb.4th
new file mode 100644
index 0000000000..c2a504d1dd
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-orb.4th
@@ -0,0 +1,55 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+46 logoX ! 7 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ [char] @ escc! \ replace @ with Esc
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ color Orb mascot (15 rows x 30 columns)
+
+ s" @[31m``` @[31;1m`@[31m" logo+
+ s" s` `.....---...@[31;1m....--.``` -/@[31m" logo+
+ s" +o .--` @[31;1m/y:` +.@[31m" logo+
+ s" yo`:. @[31;1m:o `+-@[31m" logo+
+ s" y/ @[31;1m-/` -o/@[31m" logo+
+ s" .- @[31;1m::/sy+:.@[31m" logo+
+ s" / @[31;1m`-- /@[31m" logo+
+ s" `: @[31;1m:`@[31m" logo+
+ s" `: @[31;1m:`@[31m" logo+
+ s" / @[31;1m/@[31m" logo+
+ s" .- @[31;1m-.@[31m" logo+
+ s" -- @[31;1m-.@[31m" logo+
+ s" `:` @[31;1m`:`" logo+
+ s" @[31;1m.-- `--." logo+
+ s" .---.....----.@[m" logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/logo-orbbw.4th b/usr/src/boot/sys/boot/forth/logo-orbbw.4th
new file mode 100644
index 0000000000..11dc11cabb
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-orbbw.4th
@@ -0,0 +1,54 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+46 logoX ! 7 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ B/W Orb mascot (15 rows x 32 columns)
+
+ s" ``` `" logo+
+ s" s` `.....---.......--.``` -/" logo+
+ s" +o .--` /y:` +." logo+
+ s" yo`:. :o `+-" logo+
+ s" y/ -/` -o/" logo+
+ s" .- ::/sy+:." logo+
+ s" / `-- /" logo+
+ s" `: :`" logo+
+ s" `: :`" logo+
+ s" / /" logo+
+ s" .- -." logo+
+ s" -- -." logo+
+ s" `:` `:`" logo+
+ s" .-- `--." logo+
+ s" .---.....----." logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/menu-commands.4th b/usr/src/boot/sys/boot/forth/menu-commands.4th
new file mode 100644
index 0000000000..ae544b0c7c
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menu-commands.4th
@@ -0,0 +1,611 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ Copyright 2015 Toomas Soome <tsoome@me.com>
+
+marker task-menu-commands.4th
+
+include /boot/forth/menusets.4th
+
+only forth definitions
+
+variable osconsole_state
+variable acpi_state
+variable kernel_state
+variable root_state
+variable kmdb_state
+variable debug_state
+0 kmdb_state !
+0 debug_state !
+0 osconsole_state !
+0 acpi_state !
+0 kernel_state !
+0 root_state !
+
+also menu-namespace also menu-command-helpers
+
+\
+\ Boot
+\
+
+: init_boot ( N -- N )
+ dup
+ s" smartos" getenv? if
+ s" set menu_keycode[N]=98" \ base command to execute
+ else
+ s" boot_single" getenv -1 <> if
+ drop ( n n c-addr -- n n ) \ unused
+ toggle_menuitem ( n n -- n n )
+ s" set menu_keycode[N]=115" \ base command to execute
+ else
+ s" set menu_keycode[N]=98" \ base command to execute
+ then
+ then
+ 17 +c! \ replace 'N' with ASCII numeral
+ evaluate
+;
+
+\
+\ Alternate Boot
+\
+
+: init_altboot ( N -- N )
+ dup
+ s" smartos" getenv? if
+ s" set menu_keycode[N]=114" \ base command to execute
+ else
+ s" boot_single" getenv -1 <> if
+ drop ( n c-addr -- n ) \ unused
+ toggle_menuitem ( n -- n )
+ s" set menu_keycode[N]=109" \ base command to execute
+ else
+ s" set menu_keycode[N]=115" \ base command to execute
+ then
+ then
+ 17 +c! \ replace 'N' with ASCII numeral
+ evaluate
+;
+
+: altboot ( N -- NOTREACHED )
+ s" smartos" getenv? if
+ s" alt-boot-args" getenv dup -1 <> if
+ s" boot-args" setenv ( c-addr/u -- )
+ then
+ ." NoInstall/Recovery mode boot. login/pw: root/root" cr
+ else
+ s" boot_single" 2dup getenv -1 <> if
+ drop ( c-addr/u c-addr -- c-addr/u ) \ unused
+ unsetenv ( c-addr/u -- )
+ else
+ 2drop ( c-addr/u -- ) \ unused
+ s" set boot_single=YES" evaluate
+ then
+ then
+ 0 boot ( state -- )
+;
+
+\
+\ Single User Mode
+\
+
+: singleuser_enabled? ( -- flag )
+ s" boot_single" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: singleuser_enable ( -- )
+ s" set boot_single=YES" evaluate
+;
+
+: singleuser_disable ( -- )
+ s" boot_single" unsetenv
+;
+
+: init_singleuser ( N -- N )
+ singleuser_enabled? if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_singleuser ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ singleuser_disable
+ else
+ singleuser_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
+\ Verbose Boot
+\
+
+: verbose_enabled? ( -- flag )
+ s" boot_verbose" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: verbose_enable ( -- )
+ s" set boot_verbose=YES" evaluate
+;
+
+: verbose_disable ( -- )
+ s" boot_verbose" unsetenv
+;
+
+: init_verbose ( N -- N )
+ verbose_enabled? if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_verbose ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ verbose_disable
+ else
+ verbose_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
+\ kmdb
+\
+
+: kmdb_enabled? ( -- flag )
+ s" boot_kmdb" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: kmdb_enable ( -- )
+ s" set boot_kmdb=YES" evaluate
+;
+
+: kmdb_disable ( -- )
+ s" boot_kmdb" unsetenv
+ s" boot_debug" unsetenv
+;
+
+: init_kmdb ( N -- N )
+ dup kmdb_state ! \ store entry number for kmdb+debug
+ kmdb_enabled? if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_kmdb ( N -- N TRUE )
+ toggle_menuitem
+ dup toggle_stateN @ 0= if ( kmdb is not set )
+ debug_state @ if ( debug is set? )
+ debug_state @ toggle_stateN @ if ( debug is enabled? )
+ debug_state @ toggle_menuitem drop
+ then
+ then
+ then
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ kmdb_disable
+ else
+ kmdb_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
+\ kmdb + debug
+\
+
+: debug_disable ( -- )
+ s" boot_debug" unsetenv
+;
+
+: debug_enabled? ( -- flag )
+ \ -d is only allowed with -k
+ s" boot_debug" getenv -1 <> kmdb_enabled? and dup if
+ swap drop ( c-addr flag -- flag )
+ else
+ debug_disable \ make sure env is not set
+ then
+;
+
+: debug_enable ( -- )
+ kmdb_enable
+ s" set boot_debug=YES" evaluate
+;
+
+: init_debug ( N -- N )
+ dup debug_state ! \ store entry number for kmdb
+ kmdb_enabled? debug_enabled? and if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_debug ( N -- N TRUE )
+ toggle_menuitem
+ kmdb_enabled? 0= if
+ kmdb_state @ toggle_menuitem drop
+ then
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ debug_disable
+ else
+ debug_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
+\ Reconfiguration boot
+\
+
+: reconfigure_enabled? ( -- flag )
+ s" boot_reconfigure" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: reconfigure_enable ( -- )
+ s" set boot_reconfigure=YES" evaluate
+;
+
+: reconfigure_disable ( -- )
+ s" boot_reconfigure" unsetenv
+;
+
+: init_reconfigure ( N -- N )
+ reconfigure_enabled? if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_reconfigure ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ reconfigure_disable
+ else
+ reconfigure_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
+\ Escape to Prompt
+\
+
+: goto_prompt ( N -- N FALSE )
+
+ s" set autoboot_delay=NO" evaluate
+
+ cr
+ ." To get back to the menu, type `menu' and press ENTER" cr
+ ." or type `boot' and press ENTER to start illumos." cr
+ cr
+
+ FALSE \ exit the menu
+;
+
+\
+\ Cyclestate (used by osconsole/acpi/kernel/root below)
+\
+
+: init_cyclestate ( N K -- N )
+ over cycle_stateN ( n k -- n k addr )
+ begin
+ tuck @ ( n k addr -- n addr k c )
+ over <> ( n addr k c -- n addr k 0|-1 )
+ while
+ rot ( n addr k -- addr k n )
+ cycle_menuitem
+ swap rot ( addr k n -- n k addr )
+ repeat
+ 2drop ( n k addr -- n )
+;
+
+\
+\ OS Console
+\ getenv os_console, if not set getenv console, if not set, default to "text"
+\ allowed serial consoles: ttya .. ttyd
+\ if new console will be added (graphics?), this section needs to be updated
+\
+: init_osconsole ( N -- N )
+ s" os_console" getenv dup -1 = if
+ drop
+ s" console" getenv dup -1 = if
+ drop 0 \ default to text
+ then
+ then ( n c-addr/u | n 0 )
+
+ dup 0<> if ( n c-addr/u )
+ 2dup s" ttyd" compare 0= if
+ 2drop 4
+ else 2dup s" ttyc" compare 0= if
+ 2drop 3
+ else 2dup s" ttyb" compare 0= if
+ 2drop 2
+ else 2dup s" ttya" compare 0= if
+ 2drop 1
+ else
+ 2drop 0 \ anything else defaults to text
+ then then then then
+ then
+ osconsole_state !
+;
+
+: activate_osconsole ( N -- N )
+ dup cycle_stateN @ ( n -- n n2 )
+ dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization
+
+ case
+ 0 of s" text" endof
+ 1 of s" ttya" endof
+ 2 of s" ttyb" endof
+ 3 of s" ttyc" endof
+ 4 of s" ttyd" endof
+ dup s" unknown state: " type . cr
+ endcase
+ s" os_console" setenv
+;
+
+: cycle_osconsole ( N -- N TRUE )
+ cycle_menuitem \ cycle cycle_stateN to next value
+ activate_osconsole \ apply current cycle_stateN
+ menu-redraw \ redraw menu
+ TRUE \ loop menu again
+;
+
+\
+\ ACPI
+\
+: init_acpi ( N -- N )
+ s" acpi-user-options" getenv dup -1 <> if
+ evaluate \ use ?number parse step
+
+ \ translate option to cycle state
+ case
+ 1 of 1 acpi_state ! endof
+ 2 of 2 acpi_state ! endof
+ 4 of 3 acpi_state ! endof
+ 8 of 4 acpi_state ! endof
+ 0 acpi_state !
+ endcase
+ else
+ drop
+ then
+;
+
+: activate_acpi ( N -- N )
+ dup cycle_stateN @ ( n -- n n2 )
+ dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization
+
+ \ if N == 0, it's default, just unset env.
+ dup 0= if
+ drop
+ s" acpi-user-options" unsetenv
+ else
+ case
+ 1 of s" 1" endof
+ 2 of s" 2" endof
+ 3 of s" 4" endof
+ 4 of s" 8" endof
+ endcase
+ s" acpi-user-options" setenv
+ then
+;
+
+: cycle_acpi ( N -- N TRUE )
+ cycle_menuitem \ cycle cycle_stateN to next value
+ activate_acpi \ apply current cycle_stateN
+ menu-redraw \ redraw menu
+ TRUE \ loop menu again
+;
+
+\
+\ Kernel
+\
+
+: init_kernel ( N -- N )
+ kernel_state @ ( n -- n k )
+ init_cyclestate ( n k -- n )
+;
+
+: activate_kernel ( N -- N )
+ dup cycle_stateN @ ( n -- n n2 )
+ dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization
+ 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num
+
+ s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
+ 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
+ evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path
+;
+
+: cycle_kernel ( N -- N TRUE )
+ cycle_menuitem \ cycle cycle_stateN to next value
+ activate_kernel \ apply current cycle_stateN
+ menu-redraw \ redraw menu
+ TRUE \ loop menu again
+;
+
+\
+\ Root
+\
+
+: init_root ( N -- N )
+ root_state @ ( n -- n k )
+ init_cyclestate ( n k -- n )
+;
+
+: activate_root ( N -- N )
+ dup cycle_stateN @ ( n -- n n2 )
+ dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization
+ 48 + ( n n2 -- n n2' ) \ root_state to ASCII num
+
+ s" set root=${root_prefix}${root[N]}${root_suffix}"
+ 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
+ evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path
+;
+
+: cycle_root ( N -- N TRUE )
+ cycle_menuitem \ cycle cycle_stateN to next value
+ activate_root \ apply current cycle_stateN
+ menu-redraw \ redraw menu
+ TRUE \ loop menu again
+;
+
+\
+\ Menusets
+\
+
+: goto_menu ( N M -- N TRUE )
+ menu-unset
+ menuset-loadsetnum ( n m -- n )
+ menu-redraw
+ TRUE \ Loop menu again
+;
+
+\
+\ Defaults
+\
+
+: set_default_boot_options ( N -- N TRUE )
+ 0 acpi_state !
+ s" acpi-user-options" unsetenv
+ singleuser_disable
+ verbose_disable
+ kmdb_disable \ disables debug as well
+ reconfigure_disable
+ 2 goto_menu
+;
+
+\
+\ Set boot environment defaults
+\
+
+
+: init_bootenv ( -- )
+ s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate
+ s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate
+ s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate
+ s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate
+ s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
+ s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
+;
+
+\
+\ Redraw the entire screen. A long BE name can corrupt the menu
+\
+
+: be_draw_screen
+ clear \ Clear the screen (in screen.4th)
+ print_version \ print version string (bottom-right; see version.4th)
+ draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
+ draw-brand \ Draw brand.4th logo at top (in brand.4th)
+ menu-init \ Initialize menu and draw bounding box (in menu.4th)
+;
+
+\
+\ Select a boot environment
+\
+
+: set_bootenv ( N -- N TRUE )
+ dup s" bootenv_root[E]" 13 +c! getenv
+ s" currdev" getenv compare 0= if
+ s" zfs_be_active" getenv type ." is already active"
+ 500 ms \ sleep
+ else
+ dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate
+ dup s" bootenvmenu_caption[E]" 20 +c! getenv
+ s" zfs_be_active" setenv
+ ." Activating " s" currdev" getenv type cr
+ s" unload" evaluate
+ free-module-options
+ s" /boot/defaults/loader.conf" read-conf
+ s" /boot/loader.conf" read-conf
+ s" /boot/loader.conf.local" read-conf
+ init_bootenv
+ then
+
+ be_draw_screen
+ menu-redraw
+ TRUE
+;
+
+\
+\ Switch to the next page of boot environments
+\
+
+: set_be_page ( N -- N TRUE )
+ s" zfs_be_currpage" getenv dup -1 = if
+ drop s" 1"
+ else
+ 0 s>d 2swap
+ >number ( ud caddr/u -- ud' caddr'/u' )
+ 2drop
+ 1 um/mod ( ud u1 -- u2 u3 )
+ swap drop ( ud2 u3 -- u3 )
+ 1+ \ increment the page number
+ dup
+ s" zfs_be_pages" getenv
+ 0 s>d 2swap
+ >number ( ud caddr/u -- ud' caddr'/u' )
+ 2drop
+ 1 um/mod ( ud u1 -- u2 u3 )
+ swap drop ( ud2 u3 -- u3 )
+ > if drop 1 then
+ s>d <# #s #> \ convert back to a string
+ then
+
+ s" zfs_be_currpage" setenv
+ s" be-set-page" evaluate
+ 3 goto_menu
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/menu.4th b/usr/src/boot/sys/boot/forth/menu.4th
new file mode 100644
index 0000000000..9c7ba8e3ae
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menu.4th
@@ -0,0 +1,1394 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-menu.4th
+
+\ Frame drawing
+include /boot/forth/frames.4th
+
+vocabulary menu-infrastructure
+vocabulary menu-namespace
+vocabulary menu-command-helpers
+
+only forth also menu-infrastructure definitions
+
+f_double \ Set frames to double (see frames.4th). Replace with
+ \ f_single if you want single frames.
+46 constant dot \ ASCII definition of a period (in decimal)
+
+ 5 constant menu_default_x \ default column position of timeout
+10 constant menu_default_y \ default row position of timeout msg
+ 4 constant menu_timeout_default_x \ default column position of timeout
+23 constant menu_timeout_default_y \ default row position of timeout msg
+10 constant menu_timeout_default \ default timeout (in seconds)
+
+\ Customize the following values with care
+
+ 1 constant menu_start \ Numerical prefix of first menu item
+dot constant bullet \ Menu bullet (appears after numerical prefix)
+ 5 constant menu_x \ Row position of the menu (from the top)
+ 10 constant menu_y \ Column position of the menu (from left side)
+
+\ Menu Appearance
+variable menuidx \ Menu item stack for number prefixes
+variable menurow \ Menu item stack for positioning
+variable menubllt \ Menu item bullet
+
+\ Menu Positioning
+variable menuX \ Menu X offset (columns)
+variable menuY \ Menu Y offset (rows)
+
+\ Menu-item elements
+variable menurebootadded
+
+\ Parsing of kernels into menu-items
+variable kernidx
+variable kernlen
+variable kernmenuidx
+
+\ Menu timer [count-down] variables
+variable menu_timeout_enabled \ timeout state (internal use only)
+variable menu_time \ variable for tracking the passage of time
+variable menu_timeout \ determined configurable delay duration
+variable menu_timeout_x \ column position of timeout message
+variable menu_timeout_y \ row position of timeout message
+
+\ Containers for parsing kernels into menu-items
+create kerncapbuf 64 allot
+create kerndefault 64 allot
+create kernelsbuf 256 allot
+
+only forth also menu-namespace definitions
+
+\ Menu-item key association/detection
+variable menukey1
+variable menukey2
+variable menukey3
+variable menukey4
+variable menukey5
+variable menukey6
+variable menukey7
+variable menukey8
+variable menureboot
+variable menuacpi
+variable menuosconsole
+variable menuoptions
+variable menukernel
+
+\ Menu initialization status variables
+variable init_state1
+variable init_state2
+variable init_state3
+variable init_state4
+variable init_state5
+variable init_state6
+variable init_state7
+variable init_state8
+
+\ Boolean option status variables
+variable toggle_state1
+variable toggle_state2
+variable toggle_state3
+variable toggle_state4
+variable toggle_state5
+variable toggle_state6
+variable toggle_state7
+variable toggle_state8
+
+\ Array option status variables
+variable cycle_state1
+variable cycle_state2
+variable cycle_state3
+variable cycle_state4
+variable cycle_state5
+variable cycle_state6
+variable cycle_state7
+variable cycle_state8
+
+\ Containers for storing the initial caption text
+create init_text1 64 allot
+create init_text2 64 allot
+create init_text3 64 allot
+create init_text4 64 allot
+create init_text5 64 allot
+create init_text6 64 allot
+create init_text7 64 allot
+create init_text8 64 allot
+
+only forth definitions
+
+: arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise.
+ s" arch-i386" environment? dup if
+ drop
+ then
+;
+
+: acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise
+ s" hint.acpi.0.rsdp" getenv
+ dup -1 = if
+ drop false exit
+ then
+ 2drop
+ true
+;
+
+: acpienabled? ( -- flag ) \ Returns TRUE if ACPI is enabled, FALSE otherwise
+ s" hint.acpi.0.disabled" getenv
+ dup -1 <> if
+ s" 0" compare 0<> if
+ false exit
+ then
+ else
+ drop
+ then
+ true
+;
+
+: +c! ( N C-ADDR/U K -- C-ADDR/U )
+ 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr )
+ rot + c! ( n c-addr/u k n c-addr -- n c-addr/u )
+ rot drop ( n c-addr/u -- c-addr/u )
+;
+
+only forth also menu-namespace definitions
+
+\ Forth variables
+: namespace ( C-ADDR/U N -- ) also menu-namespace +c! evaluate previous ;
+: menukeyN ( N -- ADDR ) s" menukeyN" 7 namespace ;
+: init_stateN ( N -- ADDR ) s" init_stateN" 10 namespace ;
+: toggle_stateN ( N -- ADDR ) s" toggle_stateN" 12 namespace ;
+: cycle_stateN ( N -- ADDR ) s" cycle_stateN" 11 namespace ;
+: init_textN ( N -- C-ADDR ) s" init_textN" 9 namespace ;
+
+\ Environment variables
+: kernel[x] ( N -- C-ADDR/U ) s" kernel[x]" 7 +c! ;
+: menu_init[x] ( N -- C-ADDR/U ) s" menu_init[x]" 10 +c! ;
+: menu_command[x] ( N -- C-ADDR/U ) s" menu_command[x]" 13 +c! ;
+: menu_caption[x] ( N -- C-ADDR/U ) s" menu_caption[x]" 13 +c! ;
+: ansi_caption[x] ( N -- C-ADDR/U ) s" ansi_caption[x]" 13 +c! ;
+: menu_keycode[x] ( N -- C-ADDR/U ) s" menu_keycode[x]" 13 +c! ;
+: toggled_text[x] ( N -- C-ADDR/U ) s" toggled_text[x]" 13 +c! ;
+: toggled_ansi[x] ( N -- C-ADDR/U ) s" toggled_ansi[x]" 13 +c! ;
+: menu_caption[x][y] ( N M -- C-ADDR/U ) s" menu_caption[x][y]" 16 +c! 13 +c! ;
+: ansi_caption[x][y] ( N M -- C-ADDR/U ) s" ansi_caption[x][y]" 16 +c! 13 +c! ;
+
+also menu-infrastructure definitions
+
+\ This function prints a menu item at menuX (row) and menuY (column), returns
+\ the incremental decimal ASCII value associated with the menu item, and
+\ increments the cursor position to the next row for the creation of the next
+\ menu item. This function is called by the menu-create function. You need not
+\ call it directly.
+\
+: printmenuitem ( menu_item_str -- ascii_keycode )
+
+ loader_color? if [char] ^ escc! then
+
+ menurow dup @ 1+ swap ! ( increment menurow )
+ menuidx dup @ 1+ swap ! ( increment menuidx )
+
+ \ Calculate the menuitem row position
+ menurow @ menuY @ +
+
+ \ Position the cursor at the menuitem position
+ dup menuX @ swap at-xy
+
+ \ Print the value of menuidx
+ loader_color? dup ( -- bool bool )
+ if b then
+ menuidx @ .
+ if me then
+
+ \ Move the cursor forward 1 column
+ dup menuX @ 1+ swap at-xy
+
+ menubllt @ emit \ Print the menu bullet using the emit function
+
+ \ Move the cursor to the 3rd column from the current position
+ \ to allow for a space between the numerical prefix and the
+ \ text caption
+ menuX @ 3 + swap at-xy
+
+ \ Print the menu caption (we expect a string to be on the stack
+ \ prior to invoking this function)
+ type
+
+ \ Here we will add the ASCII decimal of the numerical prefix
+ \ to the stack (decimal ASCII for `1' is 49) as a "return value"
+ menuidx @ 48 +
+;
+
+: delim? ( C -- BOOL )
+ dup 32 = ( c -- c bool ) \ [sp] space
+ over 9 = or ( c bool -- c bool ) \ [ht] horizontal tab
+ over 10 = or ( c bool -- c bool ) \ [nl] newline
+ over 13 = or ( c bool -- c bool ) \ [cr] carriage return
+ over [char] , = or ( c bool -- c bool ) \ comma
+ swap drop ( c bool -- bool ) \ return boolean
+;
+
+\ This function parses $kernels into variables that are used by the menu to
+\ display wich kernel to boot when the [overloaded] `boot' word is interpreted.
+\ Used internally by menu-create, you need not (nor should you) call this
+\ directly.
+\
+: parse-kernels ( N -- ) \ kernidx
+ kernidx ! ( n -- ) \ store provided `x' value
+ [char] 0 kernmenuidx ! \ initialize `y' value for menu_caption[x][y]
+
+ \ Attempt to get a list of kernels, fall back to sensible default
+ s" kernels" getenv dup -1 = if
+ drop ( cruft )
+ s" kernel kernel.old"
+ then ( -- c-addr/u )
+
+ \ Check to see if the user has altered $kernel by comparing it against
+ \ $kernel[N] where N is kernel_state (the actively displayed kernel).
+ s" kernel_state" evaluate @ 48 + s" kernel[N]" 7 +c! getenv
+ dup -1 <> if
+ s" kernel" getenv dup -1 = if
+ drop ( cruft ) s" "
+ then
+ 2swap 2over compare 0= if
+ 2drop FALSE ( skip below conditional )
+ else \ User has changed $kernel
+ TRUE ( slurp in new value )
+ then
+ else \ We haven't yet parsed $kernels into $kernel[N]
+ drop ( getenv cruft )
+ s" kernel" getenv dup -1 = if
+ drop ( cruft ) s" "
+ then
+ TRUE ( slurp in initial value )
+ then ( c-addr/u -- c-addr/u c-addr/u,-1 | 0 )
+ if \ slurp new value into kerndefault
+ kerndefault 1+ 0 2swap strcat swap 1- c!
+ then
+
+ \ Clear out existing parsed-kernels
+ kernidx @ [char] 0
+ begin
+ dup kernel[x] unsetenv
+ 2dup menu_caption[x][y] unsetenv
+ 2dup ansi_caption[x][y] unsetenv
+ 1+ dup [char] 8 >
+ until
+ 2drop
+
+ \ Step through the string until we find the end
+ begin
+ 0 kernlen ! \ initialize length of value
+
+ \ Skip leading whitespace and/or comma delimiters
+ begin
+ dup 0<> if
+ over c@ delim? ( c-addr/u -- c-addr/u bool )
+ else
+ false ( c-addr/u -- c-addr/u bool )
+ then
+ while
+ 1- swap 1+ swap ( c-addr/u -- c-addr'/u' )
+ repeat
+ ( c-addr/u -- c-addr'/u' )
+
+ dup 0= if \ end of string while eating whitespace
+ 2drop ( c-addr/u -- )
+ kernmenuidx @ [char] 0 <> if \ found at least one
+ exit \ all done
+ then
+
+ \ No entries in $kernels; use $kernel instead
+ s" kernel" getenv dup -1 = if
+ drop ( cruft ) s" "
+ then ( -- c-addr/u )
+ dup kernlen ! \ store entire value length as kernlen
+ else
+ \ We're still within $kernels parsing toward the end;
+ \ find delimiter/end to determine kernlen
+ 2dup ( c-addr/u -- c-addr/u c-addr/u )
+ begin dup 0<> while
+ over c@ delim? if
+ drop 0 ( break ) \ found delimiter
+ else
+ kernlen @ 1+ kernlen ! \ incrememnt
+ 1- swap 1+ swap \ c-addr++ u--
+ then
+ repeat
+ 2drop ( c-addr/u c-addr'/u' -- c-addr/u )
+
+ \ If this is the first entry, compare it to $kernel
+ \ If different, then insert $kernel beforehand
+ kernmenuidx @ [char] 0 = if
+ over kernlen @ kerndefault count compare if
+ kernelsbuf 0 kerndefault count strcat
+ s" ," strcat 2swap strcat
+ kerndefault count swap drop kernlen !
+ then
+ then
+ then
+ ( c-addr/u -- c-addr'/u' )
+
+ \ At this point, we should have something on the stack to store
+ \ as the next kernel menu option; start assembling variables
+
+ over kernlen @ ( c-addr/u -- c-addr/u c-addr/u2 )
+
+ \ Assign first to kernel[x]
+ 2dup kernmenuidx @ kernel[x] setenv
+
+ \ Assign second to menu_caption[x][y]
+ kerncapbuf 0 s" [K]ernel: " strcat
+ 2over strcat
+ kernidx @ kernmenuidx @ menu_caption[x][y]
+ setenv
+
+ \ Assign third to ansi_caption[x][y]
+ kerncapbuf 0 s" @[1mK@[37mernel: " [char] @ escc! strcat
+ kernmenuidx @ [char] 0 = if
+ s" default/@[32m"
+ else
+ s" @[34;1m"
+ then
+ [char] @ escc! strcat
+ 2over strcat
+ s" @[37m" [char] @ escc! strcat
+ kernidx @ kernmenuidx @ ansi_caption[x][y]
+ setenv
+
+ 2drop ( c-addr/u c-addr/u2 -- c-addr/u )
+
+ kernmenuidx @ 1+ dup kernmenuidx ! [char] 8 > if
+ 2drop ( c-addr/u -- ) exit
+ then
+
+ kernlen @ - swap kernlen @ + swap ( c-addr/u -- c-addr'/u' )
+ again
+;
+
+\ This function goes through the kernels that were discovered by the
+\ parse-kernels function [above], adding " (# of #)" text to the end of each
+\ caption.
+\
+: tag-kernels ( -- )
+ kernidx @ ( -- x ) dup 0= if exit then
+ [char] 0 s" (Y of Z)" ( x -- x y c-addr/u )
+ kernmenuidx @ -rot 7 +c! \ Replace 'Z' with number of kernels parsed
+ begin
+ 2 pick 1+ -rot 2 +c! \ Replace 'Y' with current ASCII num
+
+ 2over menu_caption[x][y] getenv dup -1 <> if
+ 2dup + 1- c@ [char] ) = if
+ 2drop \ Already tagged
+ else
+ kerncapbuf 0 2swap strcat
+ 2over strcat
+ 5 pick 5 pick menu_caption[x][y] setenv
+ then
+ else
+ drop ( getenv cruft )
+ then
+
+ 2over ansi_caption[x][y] getenv dup -1 <> if
+ 2dup + 1- c@ [char] ) = if
+ 2drop \ Already tagged
+ else
+ kerncapbuf 0 2swap strcat
+ 2over strcat
+ 5 pick 5 pick ansi_caption[x][y] setenv
+ then
+ else
+ drop ( getenv cruft )
+ then
+
+ rot 1+ dup [char] 8 > if
+ -rot 2drop TRUE ( break )
+ else
+ -rot FALSE
+ then
+ until
+ 2drop ( x y -- )
+;
+
+\ Illumos kernel acpi-user-options has following values:
+\ default: 0 - system will enable acpi based on bios date
+\ on: 1 - acpi is set on
+\ off: 2 - acpi is set off
+\ madt: 4 - use only MADT
+\ legacy: 8 - use legacy mode
+
+: acpi-captions ( N -- )
+ \ first entry
+ dup s" [A]CPI.... default" rot 48 menu_caption[x][y] setenv
+ dup s" ^[1mA^[mCPI.... ^[32;7mdefault^[m" rot 48 ansi_caption[x][y] setenv
+
+ dup s" [A]CPI........ On" rot 49 menu_caption[x][y] setenv
+ dup s" ^[1mA^[mCPI........ ^[34;1mOn^[m" rot 49 ansi_caption[x][y] setenv
+
+ dup s" [A]CPI........ Off" rot 50 menu_caption[x][y] setenv
+ dup s" ^[1mA^[mCPI........ ^[34;1mOff^[m" rot 50 ansi_caption[x][y] setenv
+
+ dup s" [A]CPI....... MADT" rot 51 menu_caption[x][y] setenv
+ dup s" ^[1mA^[mCPI....... ^[34;1mMADT^[m" rot 51 ansi_caption[x][y] setenv
+
+ dup s" [A]CPI..... Legacy" rot 52 menu_caption[x][y] setenv
+ s" ^[1mA^[mCPI..... ^[34;1mLegacy^[m" rot 52 ansi_caption[x][y] setenv
+;
+
+\ Illumos console has following values:
+\ text, ttya, ttyb, ttyc, ttyd
+
+: osconsole-captions ( N -- )
+ \ first entry
+ dup s" Os[C]onsole.. text" rot 48 menu_caption[x][y] setenv
+ dup s" Os^[1mC^[monsole.. ^[32;7mtext^[m" rot 48 ansi_caption[x][y] setenv
+
+ dup s" Os[C]onsole.. ttya" rot 49 menu_caption[x][y] setenv
+ dup s" Os^[1mC^[monsole.. ^[34;1mttya^[m" rot 49 ansi_caption[x][y] setenv
+
+ dup s" Os[C]onsole.. ttyb" rot 50 menu_caption[x][y] setenv
+ dup s" Os^[1mC^[monsole.. ^[34;1mttyb^[m" rot 50 ansi_caption[x][y] setenv
+
+ dup s" Os[C]onsole.. ttyc" rot 51 menu_caption[x][y] setenv
+ dup s" Os^[1mC^[monsole.. ^[34;1mttyc^[m" rot 51 ansi_caption[x][y] setenv
+
+ dup s" Os[C]onsole.. ttyd" rot 52 menu_caption[x][y] setenv
+ s" Os^[1mC^[monsole.. ^[34;1mttyd^[m" rot 52 ansi_caption[x][y] setenv
+;
+
+\ This function creates the list of menu items. This function is called by the
+\ menu-display function. You need not call it directly.
+\
+: menu-create ( -- )
+
+ \ Print the frame caption at (x,y)
+ s" loader_menu_title" getenv dup -1 = if
+ drop s" Welcome to illumos"
+ then
+ TRUE ( use default alignment )
+ s" loader_menu_title_align" getenv dup -1 <> if
+ 2dup s" left" compare-insensitive 0= if ( 1 )
+ 2drop ( c-addr/u ) drop ( bool )
+ menuX @ menuY @ 1-
+ FALSE ( don't use default alignment )
+ else ( 1 ) 2dup s" right" compare-insensitive 0= if ( 2 )
+ 2drop ( c-addr/u ) drop ( bool )
+ menuX @ 42 + 4 - over - menuY @ 1-
+ FALSE ( don't use default alignment )
+ else ( 2 ) 2drop ( c-addr/u ) then ( 1 ) then
+ else
+ drop ( getenv cruft )
+ then
+ if ( use default center alignement? )
+ menuX @ 19 + over 2 / - menuY @ 1-
+ then
+ at-xy type
+
+ \ If $menu_init is set, evaluate it (allowing for whole menus to be
+ \ constructed dynamically -- as this function could conceivably set
+ \ the remaining environment variables to construct the menu entirely).
+ \
+ s" menu_init" getenv dup -1 <> if
+ evaluate
+ else
+ drop
+ then
+
+ \ Print our menu options with respective key/variable associations.
+ \ `printmenuitem' ends by adding the decimal ASCII value for the
+ \ numerical prefix to the stack. We store the value left on the stack
+ \ to the key binding variable for later testing against a character
+ \ captured by the `getkey' function.
+
+ \ Note that any menu item beyond 9 will have a numerical prefix on the
+ \ screen consisting of the first digit (ie. 1 for the tenth menu item)
+ \ and the key required to activate that menu item will be the decimal
+ \ ASCII of 48 plus the menu item (ie. 58 for the tenth item, aka. `:')
+ \ which is misleading and not desirable.
+ \
+ \ Thus, we do not allow more than 8 configurable items on the menu
+ \ (with "Reboot" as the optional ninth and highest numbered item).
+
+ \
+ \ Initialize the OsConsole option status.
+ \
+ 0 menuosconsole !
+ s" menu_osconsole" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ dup menuosconsole !
+ dup osconsole-captions
+
+ s" init_osconsole" evaluate
+
+ \ Get the current cycle state (entry to use)
+ s" osconsole_state" evaluate @ 48 + ( n -- n y )
+
+ \ Set the current non-ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set menu_caption[x]=$menu_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Set the current ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set ansi_caption[x]=$ansi_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Initialize cycle state from stored value
+ 48 - ( n y -- n k )
+ s" init_cyclestate" evaluate ( n k -- n )
+
+ \ Set $os_console
+ s" activate_osconsole" evaluate ( n -- n )
+ then
+ drop
+ then
+
+ \
+ \ Initialize the ACPI option status.
+ \
+ 0 menuacpi !
+ s" menu_acpi" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ dup menuacpi !
+ dup acpi-captions
+
+ s" init_acpi" evaluate
+
+ \ Get the current cycle state (entry to use)
+ s" acpi_state" evaluate @ 48 + ( n -- n y )
+
+ \ Set the current non-ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set menu_caption[x]=$menu_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Set the current ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set ansi_caption[x]=$ansi_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Initialize cycle state from stored value
+ 48 - ( n y -- n k )
+ s" init_cyclestate" evaluate ( n k -- n )
+
+ \ Set $acpi-user-options
+ s" activate_acpi" evaluate ( n -- n )
+ then
+ drop
+ then
+
+ \
+ \ Initialize kernel captions after parsing $kernels
+ \
+ 0 menukernel !
+ s" menu_kernel" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ dup menukernel !
+ dup parse-kernels tag-kernels
+
+ \ Get the current cycle state (entry to use)
+ s" kernel_state" evaluate @ 48 + ( n -- n y )
+
+ \ If state is invalid, reset
+ dup kernmenuidx @ 1- > if
+ drop [char] 0 ( n y -- n 48 )
+ 0 s" kernel_state" evaluate !
+ over s" init_kernel" evaluate drop
+ then
+
+ \ Set the current non-ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set menu_caption[x]=$menu_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Set the current ANSI caption
+ 2dup swap dup ( n y -- n y y n n )
+ s" set ansi_caption[x]=$ansi_caption[x][y]"
+ 17 +c! 34 +c! 37 +c! evaluate
+ ( n y y n n c-addr/u -- n y )
+
+ \ Initialize cycle state from stored value
+ 48 - ( n y -- n k )
+ s" init_cyclestate" evaluate ( n k -- n )
+
+ \ Set $kernel to $kernel[y]
+ s" activate_kernel" evaluate ( n -- n )
+ then
+ drop
+ then
+
+ \
+ \ Initialize the menu_options visual separator.
+ \
+ 0 menuoptions !
+ s" menu_options" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ menuoptions !
+ else
+ drop
+ then
+ then
+
+ \ Initialize "Reboot" menu state variable (prevents double-entry)
+ false menurebootadded !
+
+ menu_start
+ 1- menuidx ! \ Initialize the starting index for the menu
+ 0 menurow ! \ Initialize the starting position for the menu
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ \ If the "Options:" separator, print it.
+ dup menuoptions @ = if
+ \ Optionally add a reboot option to the menu
+ s" menu_reboot" getenv -1 <> if
+ drop
+ s" Reboot" printmenuitem menureboot !
+ true menurebootadded !
+ then
+
+ menuX @
+ menurow @ 2 + menurow !
+ menurow @ menuY @ +
+ at-xy
+ s" menu_optionstext" getenv dup -1 <> if
+ type
+ else
+ drop ." Options:"
+ then
+ then
+
+ \ make sure we have not already initialized this item
+ dup init_stateN dup @ 0= if
+ 1 swap !
+
+ \ If this menuitem has an initializer, run it
+ dup menu_init[x]
+ getenv dup -1 <> if
+ evaluate
+ else
+ drop
+ then
+ else
+ drop
+ then
+
+ dup
+ loader_color? if
+ ansi_caption[x]
+ else
+ menu_caption[x]
+ then
+
+ dup -1 <> if
+ \ test for environment variable
+ getenv dup -1 <> if
+ printmenuitem ( c-addr/u -- n )
+ dup menukeyN !
+ else
+ drop
+ then
+ else
+ drop
+ then
+
+ 1+ dup 56 > \ add 1 to iterator, continue if less than 57
+ until
+ drop \ iterator
+
+ \ Optionally add a reboot option to the menu
+ menurebootadded @ true <> if
+ s" menu_reboot" getenv -1 <> if
+ drop \ no need for the value
+ s" Reboot" \ menu caption (required by printmenuitem)
+
+ printmenuitem
+ menureboot !
+ else
+ 0 menureboot !
+ then
+ then
+;
+
+\ Takes a single integer on the stack and updates the timeout display. The
+\ integer must be between 0 and 9 (we will only update a single digit in the
+\ source message).
+\
+: menu-timeout-update ( N -- )
+
+ \ Enforce minimum/maximum
+ dup 9 > if drop 9 then
+ dup 0 < if drop 0 then
+
+ s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u )
+
+ 2 pick 0> if
+ rot 48 + -rot ( n c-addr/u -- n' c-addr/u ) \ convert to ASCII
+ 12 +c! ( n' c-addr/u -- c-addr/u ) \ replace 'N' above
+
+ menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor
+ type ( c-addr/u -- ) \ print message
+ else
+ menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor
+ spaces ( n c-addr/u -- n c-addr ) \ erase message
+ 2drop ( n c-addr -- )
+ then
+
+ 0 25 at-xy ( position cursor back at bottom-left )
+;
+
+\ This function blocks program flow (loops forever) until a key is pressed.
+\ The key that was pressed is added to the top of the stack in the form of its
+\ decimal ASCII representation. This function is called by the menu-display
+\ function. You need not call it directly.
+\ note, the esc sequences will be dropped, this needs to be changed if
+\ menu is built based on arrow keys.
+\
+: getkey ( -- ascii_keycode )
+
+ begin \ loop forever
+
+ menu_timeout_enabled @ 1 = if
+ ( -- )
+ seconds ( get current time: -- N )
+ dup menu_time @ <> if ( has time elapsed?: N N N -- N )
+
+ \ At least 1 second has elapsed since last loop
+ \ so we will decrement our "timeout" (really a
+ \ counter, insuring that we do not proceed too
+ \ fast) and update our timeout display.
+
+ menu_time ! ( update time record: N -- )
+ menu_timeout @ ( "time" remaining: -- N )
+ dup 0> if ( greater than 0?: N N 0 -- N )
+ 1- ( decrement counter: N -- N )
+ dup menu_timeout !
+ ( re-assign: N N Addr -- N )
+ then
+ ( -- N )
+
+ dup 0= swap 0< or if ( N <= 0?: N N -- )
+ \ halt the timer
+ 0 menu_timeout ! ( 0 Addr -- )
+ 0 menu_timeout_enabled ! ( 0 Addr -- )
+ then
+
+ \ update the timer display ( N -- )
+ menu_timeout @ menu-timeout-update
+
+ menu_timeout @ 0= if
+ \ We've reached the end of the timeout
+ \ (user did not cancel by pressing ANY
+ \ key)
+
+ s" menu_timeout_command" getenv dup
+ -1 = if
+ drop \ clean-up
+ else
+ evaluate
+ then
+ then
+
+ else ( -- N )
+ \ No [detectable] time has elapsed (in seconds)
+ drop ( N -- )
+ then
+ ( -- )
+ then
+
+ key? if \ Was a key pressed? (see loader(8))
+
+ \ An actual key was pressed (if the timeout is running,
+ \ kill it regardless of which key was pressed)
+ menu_timeout @ 0<> if
+ 0 menu_timeout !
+ 0 menu_timeout_enabled !
+
+ \ clear screen of timeout message
+ 0 menu-timeout-update
+ then
+
+ \ get the key that was pressed and exit (if we
+ \ get a non-zero ASCII code)
+ key dup 0<> if
+ dup 0x1b = if
+ key? if ( is it sequence? )
+ drop
+ begin
+ key?
+ while
+ key drop
+ repeat
+ else
+ exit
+ then
+ else
+ exit
+ then
+ else
+ drop
+ then
+ then
+ 50 ms \ sleep for 50 milliseconds (see loader(8))
+
+ again
+;
+
+: menu-erase ( -- ) \ Erases menu and resets positioning variable to positon 1.
+
+ \ Clear the screen area associated with the interactive menu
+ menuX @ menuY @
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces
+ 2drop
+
+ \ Reset the starting index and position for the menu
+ menu_start 1- menuidx !
+ 0 menurow !
+;
+
+only forth
+also menu-infrastructure
+also menu-namespace
+also menu-command-helpers definitions
+
+: toggle_menuitem ( N -- N ) \ toggles caption text and internal menuitem state
+
+ \ ASCII numeral equal to user-selected menu item must be on the stack.
+ \ We do not modify the stack, so the ASCII numeral is left on top.
+
+ dup init_textN c@ 0= if
+ \ NOTE: no need to check toggle_stateN since the first time we
+ \ are called, we will populate init_textN. Further, we don't
+ \ need to test whether menu_caption[x] (ansi_caption[x] when
+ \ loader_color?=1) is available since we would not have been
+ \ called if the caption was NULL.
+
+ \ base name of environment variable
+ dup ( n -- n n ) \ key pressed
+ loader_color? if
+ ansi_caption[x]
+ else
+ menu_caption[x]
+ then
+ getenv dup -1 <> if
+
+ 2 pick ( n c-addr/u -- n c-addr/u n )
+ init_textN ( n c-addr/u n -- n c-addr/u c-addr )
+
+ \ now we have the buffer c-addr on top
+ \ ( followed by c-addr/u of current caption )
+
+ \ Copy the current caption into our buffer
+ 2dup c! -rot \ store strlen at first byte
+ begin
+ rot 1+ \ bring alt addr to top and increment
+ -rot -rot \ bring buffer addr to top
+ 2dup c@ swap c! \ copy current character
+ 1+ \ increment buffer addr
+ rot 1- \ bring buffer len to top and decrement
+ dup 0= \ exit loop if buffer len is zero
+ until
+ 2drop \ buffer len/addr
+ drop \ alt addr
+
+ else
+ drop
+ then
+ then
+
+ \ Now we are certain to have init_textN populated with the initial
+ \ value of menu_caption[x] (ansi_caption[x] with loader_color enabled).
+ \ We can now use init_textN as the untoggled caption and
+ \ toggled_text[x] (toggled_ansi[x] with loader_color enabled) as the
+ \ toggled caption and store the appropriate value into menu_caption[x]
+ \ (again, ansi_caption[x] with loader_color enabled). Last, we'll
+ \ negate the toggled state so that we reverse the flow on subsequent
+ \ calls.
+
+ dup toggle_stateN @ 0= if
+ \ state is OFF, toggle to ON
+
+ dup ( n -- n n ) \ key pressed
+ loader_color? if
+ toggled_ansi[x]
+ else
+ toggled_text[x]
+ then
+ getenv dup -1 <> if
+ \ Assign toggled text to menu caption
+ 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed
+ loader_color? if
+ ansi_caption[x]
+ else
+ menu_caption[x]
+ then
+ setenv
+ else
+ \ No toggled text, keep the same caption
+ drop ( n -1 -- n ) \ getenv cruft
+ then
+
+ true \ new value of toggle state var (to be stored later)
+ else
+ \ state is ON, toggle to OFF
+
+ dup init_textN count ( n -- n c-addr/u )
+
+ \ Assign init_textN text to menu caption
+ 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed
+ loader_color? if
+ ansi_caption[x]
+ else
+ menu_caption[x]
+ then
+ setenv
+
+ false \ new value of toggle state var (to be stored below)
+ then
+
+ \ now we'll store the new toggle state (on top of stack)
+ over toggle_stateN !
+;
+
+: cycle_menuitem ( N -- N ) \ cycles through array of choices for a menuitem
+
+ \ ASCII numeral equal to user-selected menu item must be on the stack.
+ \ We do not modify the stack, so the ASCII numeral is left on top.
+
+ dup cycle_stateN dup @ 1+ \ get value and increment
+
+ \ Before assigning the (incremented) value back to the pointer,
+ \ let's test for the existence of this particular array element.
+ \ If the element exists, we'll store index value and move on.
+ \ Otherwise, we'll loop around to zero and store that.
+
+ dup 48 + ( n addr k -- n addr k k' )
+ \ duplicate array index and convert to ASCII numeral
+
+ 3 pick swap ( n addr k k' -- n addr k n k' ) \ (n,k') as (x,y)
+ loader_color? if
+ ansi_caption[x][y]
+ else
+ menu_caption[x][y]
+ then
+ ( n addr k n k' -- n addr k c-addr/u )
+
+ \ Now test for the existence of our incremented array index in the
+ \ form of $menu_caption[x][y] ($ansi_caption[x][y] with loader_color
+ \ enabled) as set in loader.rc(5), et. al.
+
+ getenv dup -1 = if
+ \ No caption set for this array index. Loop back to zero.
+
+ drop ( n addr k -1 -- n addr k ) \ getenv cruft
+ drop 0 ( n addr k -- n addr 0 ) \ new value to store later
+
+ 2 pick [char] 0 ( n addr 0 -- n addr 0 n 48 ) \ (n,48) as (x,y)
+ loader_color? if
+ ansi_caption[x][y]
+ else
+ menu_caption[x][y]
+ then
+ ( n addr 0 n 48 -- n addr 0 c-addr/u )
+ getenv dup -1 = if
+ \ Highly unlikely to occur, but to ensure things move
+ \ along smoothly, allocate a temporary NULL string
+ drop ( cruft ) s" "
+ then
+ then
+
+ \ At this point, we should have the following on the stack (in order,
+ \ from bottom to top):
+ \
+ \ n - Ascii numeral representing the menu choice (inherited)
+ \ addr - address of our internal cycle_stateN variable
+ \ k - zero-based number we intend to store to the above
+ \ c-addr/u - string value we intend to store to menu_caption[x]
+ \ (or ansi_caption[x] with loader_color enabled)
+ \
+ \ Let's perform what we need to with the above.
+
+ \ Assign array value text to menu caption
+ 4 pick ( n addr k c-addr/u -- n addr k c-addr/u n )
+ loader_color? if
+ ansi_caption[x]
+ else
+ menu_caption[x]
+ then
+ setenv
+
+ swap ! ( n addr k -- n ) \ update array state variable
+;
+
+only forth definitions also menu-infrastructure
+
+\ Erase and redraw the menu. Useful if you change a caption and want to
+\ update the menu to reflect the new value.
+\
+: menu-redraw ( -- )
+ menu-erase
+ menu-create
+;
+
+\ This function initializes the menu. Call this from your `loader.rc' file
+\ before calling any other menu-related functions.
+\
+: menu-init ( -- )
+ menu_start
+ 1- menuidx ! \ Initialize the starting index for the menu
+ 0 menurow ! \ Initialize the starting position for the menu
+
+ \ Assign configuration values
+ s" loader_menu_y" getenv dup -1 = if
+ drop \ no custom row position
+ menu_default_y
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_default_y \ or use default
+ then
+ then
+ menuY !
+ s" loader_menu_x" getenv dup -1 = if
+ drop \ no custom column position
+ menu_default_x
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_default_x \ or use default
+ then
+ then
+ menuX !
+
+ \ Interpret a custom frame type for the menu
+ TRUE ( draw a box? default yes, but might be altered below )
+ s" loader_menu_frame" getenv dup -1 = if ( 1 )
+ drop \ no custom frame type
+ else ( 1 ) 2dup s" single" compare-insensitive 0= if ( 2 )
+ f_single ( see frames.4th )
+ else ( 2 ) 2dup s" double" compare-insensitive 0= if ( 3 )
+ f_double ( see frames.4th )
+ else ( 3 ) s" none" compare-insensitive 0= if ( 4 )
+ drop FALSE \ don't draw a box
+ ( 4 ) then ( 3 ) then ( 2 ) then ( 1 ) then
+ if
+ 42 13 menuX @ 3 - menuY @ 1- box \ Draw frame (w,h,x,y)
+ then
+
+ 0 25 at-xy \ Move cursor to the bottom for output
+;
+
+also menu-namespace
+
+\ Main function. Call this from your `loader.rc' file.
+\
+: menu-display ( -- )
+
+ 0 menu_timeout_enabled ! \ start with automatic timeout disabled
+
+ \ check indication that automatic execution after delay is requested
+ s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr )
+ drop ( just testing existence right now: Addr -- )
+
+ \ initialize state variables
+ seconds menu_time ! ( store the time we started )
+ 1 menu_timeout_enabled ! ( enable automatic timeout )
+
+ \ read custom time-duration (if set)
+ s" autoboot_delay" getenv dup -1 = if
+ drop \ no custom duration (remove dup'd bunk -1)
+ menu_timeout_default \ use default setting
+ else
+ 2dup ?number 0= if ( if not a number )
+ \ disable timeout if "NO", else use default
+ s" NO" compare-insensitive 0= if
+ 0 menu_timeout_enabled !
+ 0 ( assigned to menu_timeout below )
+ else
+ menu_timeout_default
+ then
+ else
+ -rot 2drop
+
+ \ boot immediately if less than zero
+ dup 0< if
+ drop
+ menu-create
+ 0 25 at-xy
+ 0 boot
+ then
+ then
+ then
+ menu_timeout ! ( store value on stack from above )
+
+ menu_timeout_enabled @ 1 = if
+ \ read custom column position (if set)
+ s" loader_menu_timeout_x" getenv dup -1 = if
+ drop \ no custom column position
+ menu_timeout_default_x \ use default setting
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_timeout_default_x \ or use default
+ then
+ then
+ menu_timeout_x ! ( store value on stack from above )
+
+ \ read custom row position (if set)
+ s" loader_menu_timeout_y" getenv dup -1 = if
+ drop \ no custom row position
+ menu_timeout_default_y \ use default setting
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_timeout_default_y \ or use default
+ then
+ then
+ menu_timeout_y ! ( store value on stack from above )
+ then
+ then
+
+ menu-create
+
+ begin \ Loop forever
+
+ 0 25 at-xy \ Move cursor to the bottom for output
+ getkey \ Block here, waiting for a key to be pressed
+
+ dup -1 = if
+ drop exit \ Caught abort (abnormal return)
+ then
+
+ \ Boot if the user pressed Enter/Ctrl-M (13) or
+ \ Ctrl-Enter/Ctrl-J (10)
+ dup over 13 = swap 10 = or if
+ drop ( no longer needed )
+ s" boot" evaluate
+ exit ( pedantic; never reached )
+ then
+
+ dup menureboot @ = if 0 reboot then
+
+ \ Evaluate the decimal ASCII value against known menu item
+ \ key associations and act accordingly
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ dup menukeyN @
+ rot tuck = if
+
+ \ Adjust for missing ACPI menuitem on non-i386
+\ arch-i386? true <> menuacpi @ 0<> and if
+\ menuacpi @ over 2dup < -rot = or
+\ over 58 < and if
+\ ( key >= menuacpi && key < 58: N -- N )
+\ 1+
+\ then
+\ then
+
+ \ Test for the environment variable
+ dup menu_command[x]
+ getenv dup -1 <> if
+ \ Execute the stored procedure
+ evaluate
+
+ \ We expect there to be a non-zero
+ \ value left on the stack after
+ \ executing the stored procedure.
+ \ If so, continue to run, else exit.
+
+ 0= if
+ drop \ key pressed
+ drop \ loop iterator
+ exit
+ else
+ swap \ need iterator on top
+ then
+ then
+
+ \ Re-adjust for missing ACPI menuitem
+\ arch-i386? true <> menuacpi @ 0<> and if
+\ swap
+\ menuacpi @ 1+ over 2dup < -rot = or
+\ over 59 < and if
+\ 1-
+\ then
+\ swap
+\ then
+ else
+ swap \ need iterator on top
+ then
+
+ \
+ \ Check for menu keycode shortcut(s)
+ \
+ dup menu_keycode[x]
+ getenv dup -1 = if
+ drop
+ else
+ ?number 0<> if
+ rot tuck = if
+ swap
+ dup menu_command[x]
+ getenv dup -1 <> if
+ evaluate
+ 0= if
+ 2drop
+ exit
+ then
+ else
+ drop
+ then
+ else
+ swap
+ then
+ then
+ then
+
+ 1+ dup 56 > \ increment iterator
+ \ continue if less than 57
+ until
+ drop \ loop iterator
+ drop \ key pressed
+
+ again \ Non-operational key was pressed; repeat
+;
+
+\ This function unsets all the possible environment variables associated with
+\ creating the interactive menu.
+\
+: menu-unset ( -- )
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ dup menu_init[x] unsetenv \ menu initializer
+ dup menu_command[x] unsetenv \ menu command
+ dup menu_caption[x] unsetenv \ menu caption
+ dup ansi_caption[x] unsetenv \ ANSI caption
+ dup menu_keycode[x] unsetenv \ menu keycode
+ dup toggled_text[x] unsetenv \ toggle_menuitem caption
+ dup toggled_ansi[x] unsetenv \ toggle_menuitem ANSI caption
+
+ 48 \ Iterator start (inner range 48 to 57; ASCII '0' to '9')
+ begin
+ \ cycle_menuitem caption and ANSI caption
+ 2dup menu_caption[x][y] unsetenv
+ 2dup ansi_caption[x][y] unsetenv
+ 1+ dup 57 >
+ until
+ drop \ inner iterator
+
+ 0 over menukeyN ! \ used by menu-create, menu-display
+ 0 over init_stateN ! \ used by menu-create
+ 0 over toggle_stateN ! \ used by toggle_menuitem
+ 0 over init_textN c! \ used by toggle_menuitem
+ 0 over cycle_stateN ! \ used by cycle_menuitem
+
+ 1+ dup 56 > \ increment, continue if less than 57
+ until
+ drop \ iterator
+
+ s" menu_timeout_command" unsetenv \ menu timeout command
+ s" menu_reboot" unsetenv \ Reboot menu option flag
+ s" menu_acpi" unsetenv \ ACPI menu option flag
+ s" menu_osconsole" unsetenv \ osconsole menu option flag
+ s" menu_kernel" unsetenv \ Kernel menu option flag
+ s" menu_options" unsetenv \ Options separator flag
+ s" menu_optionstext" unsetenv \ separator display text
+ s" menu_init" unsetenv \ menu initializer
+
+ 0 menureboot !
+ 0 menuacpi !
+ 0 menuosconsole !
+ 0 menuoptions !
+;
+
+only forth definitions also menu-infrastructure
+
+\ This function both unsets menu variables and visually erases the menu area
+\ in-preparation for another menu.
+\
+: menu-clear ( -- )
+ menu-unset
+ menu-erase
+;
+
+bullet menubllt !
+
+also menu-namespace
+
+\ Initialize our menu initialization state variables
+0 init_state1 !
+0 init_state2 !
+0 init_state3 !
+0 init_state4 !
+0 init_state5 !
+0 init_state6 !
+0 init_state7 !
+0 init_state8 !
+
+\ Initialize our boolean state variables
+0 toggle_state1 !
+0 toggle_state2 !
+0 toggle_state3 !
+0 toggle_state4 !
+0 toggle_state5 !
+0 toggle_state6 !
+0 toggle_state7 !
+0 toggle_state8 !
+
+\ Initialize our array state variables
+0 cycle_state1 !
+0 cycle_state2 !
+0 cycle_state3 !
+0 cycle_state4 !
+0 cycle_state5 !
+0 cycle_state6 !
+0 cycle_state7 !
+0 cycle_state8 !
+
+\ Initialize string containers
+0 init_text1 c!
+0 init_text2 c!
+0 init_text3 c!
+0 init_text4 c!
+0 init_text5 c!
+0 init_text6 c!
+0 init_text7 c!
+0 init_text8 c!
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/menu.4th.8 b/usr/src/boot/sys/boot/forth/menu.4th.8
new file mode 100644
index 0000000000..3673eec74a
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menu.4th.8
@@ -0,0 +1,352 @@
+.\" Copyright (c) 2011-2013 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 6, 2013
+.Dt MENU.4TH 8
+.Os
+.Sh NAME
+.Nm menu.4th
+.Nd FreeBSD dynamic menu boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to display a dynamic menu system managed through
+a system of carefully named environment variables.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include menu.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic menu-init
+Draws the menu bounding box and initializes some internal state variables.
+This should be called before any other menu-related functions.
+.It Ic menu-display
+Displays the menu (configured via the below documented environment variables)
+and blocks on keyboard input, awaiting user action.
+.It Ic menu-erase
+Clears the screen area within the menu bounding box.
+.It Ic menu-redraw
+Calls
+.Ic menu-erase
+and then redraws the menu.
+.It Ic menu-unset
+Unsets the environment variables associated with individual menu items,
+clearing the way for a new menu.
+.It Ic menu-clear
+Calls
+.Ic menu-unset
+and then
+.Ic menu-erase .
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_color
+If set to
+.Dq Li NO
+(case-insensitive) or
+.Dq Li 0 ,
+causes the menu to be displayed without color.
+The default is to use ANSI coloring whenever possible.
+If serial boot is enabled, color is disabled by default.
+Color features include the use of ANSI bold for numbers appearing to the left
+of menuitems and the use of special
+.Dq Li ansi
+variables described below.
+.It Va autoboot_delay
+Number of seconds
+.Ic menu-display
+will wait before executing
+.Va menu_timeout_command
+.Ic ( boot
+by default) unless a key is pressed.
+If set to
+.Dq Li NO
+(case-insensitive)
+.Ic menu-display
+will wait for user input and never execute
+.Ic menu_timeout_command .
+If set to
+.Dq Li -1 ,
+.Ic menu-display
+will boot immediately, preventing both interruption of the
+.Ic autoboot
+process and escaping to the loader prompt.
+Default is
+.Dq Li 10 .
+See
+.Xr loader 8
+for additional information.
+.It Va menu_timeout_command
+The command to be executed after
+.Va autoboot_delay
+seconds if a key is not pressed.
+The default is
+.Ic boot .
+.It Va loader_menu_frame
+Sets the desired box style to draw around the boot menu.
+Possible values are:
+.Dq Li single
+.Pq the default ,
+.Dq Li double ,
+and
+.Dq Li none .
+.It Va loader_menu_timeout_x
+Sets the desired column position of the timeout countdown text.
+Default is 4.
+.It Va loader_menu_timeout_y
+Sets the desired row position of the timeout countdown text.
+Default is 23.
+.It Va loader_menu_title
+The text to display above the menu.
+Default is
+.Dq Li "Welcome to FreeBSD" .
+.It Va loader_menu_title_align
+Default is to align
+.Ic loader_menu_title
+centered above the menu. This can be set to
+.Dq Li left
+or
+.Dq Li right
+to instead display the title left-or-right justified
+.Pq respectively .
+.It Va loader_menu_x
+Sets the desired column position of the boot menu.
+Default is 5.
+.It Va loader_menu_y
+Sets the desired row position of the boot menu.
+Default is 10.
+.It Va menu_caption[x]
+The text to be displayed for the numbered menuitem
+.Dq Li x .
+.It Va menu_command[x]
+The command to be executed when the number associated with menuitem
+.Dq Li x
+is pressed.
+See the list of included FICL words below for some ideas.
+.It Va menu_keycode[x]
+An optional decimal ASCII keycode to be associated with menuitem
+.Dq Li x .
+When pressed, will cause the execution of
+.Va menu_command[x] .
+.It Va ansi_caption[x]
+If
+.Va loader_color
+is set
+.Pq enabled by default ,
+use this caption for menuitem
+.Dq Li x
+instead of
+.Va menu_caption[x] .
+.It Va toggled_text[x]
+For menuitems where
+.Va menu_command[x]
+is set to
+.Dq Li toggle_menuitem
+(or a derivative thereof), the text displayed
+will toggle between this and
+.Va menu_caption[x] .
+.It Va toggled_ansi[x]
+Like
+.Va toggled_text[x]
+except used when
+.Va loader_color
+is enabled
+.Pq default .
+.It Va menu_caption[x][y]
+For menuitems where
+.Va menu_command[x]
+is set to
+.Dq Li cycle_menuitem
+(or a derivative thereof), the text displayed will cycle between this and other
+.Va menu_caption[x][y]
+entries.
+.It Va ansi_caption[x][y]
+Like
+.Va menu_caption[x][y]
+except used when
+.Va loader_color
+is enabled
+.Pq default .
+.It Va menu_acpi
+When set to a number
+.Dq Li x
+associated with a given menuitem, that menuitem will only appear when
+running on i386-compatible hardware,
+.Va hint.acpi.0.rsdp
+is set (indicating the presence of hardware ACPI support as detected by
+.Xr loader 8 ) ,
+and
+.Va hint.acpi.0.disabled
+is not set.
+On non-i386 hardware, menuitems configured after the
+.Dq Li menu_acpi
+menuitem will use a lower number (to compensate for the missing ACPI menuitem)
+but continue to function as expected.
+On i386-compatible hardware lacking ACPI support (as detected by
+.Xr loader 8 ) ,
+subsequent menuitems will retain their associated numbers.
+.It Va hint.acpi.0.rsdp
+Set automatically by
+.Xr loader 8
+on i386-compatible hardware when ACPI support is detected at boot time.
+Effects the display of the
+.Dq Li menu_acpi
+menuitem (if configured).
+.It Va hint.acpi.0.disabled
+Effects the display of the
+.Va menu_acpi
+menuitem.
+If set, the menuitem will display
+.Va toggled_text[x]
+.Va ( toggled_ansi[x]
+if
+.Va loader_color
+is set), otherwise
+.Va menu_caption[x]
+.Va ( ansi_caption[x]
+if
+.Va loader_color
+is set).
+.It Va menu_options
+When set to a number
+.Dq Li x ,
+a single blank-line and an
+.Dq Li Options
+header are inserted between
+.Va menu_caption[x-1]
+and
+.Va menu_caption[x]
+(if configured).
+.It Va menu_reboot
+If set, adds a built-in
+.Dq Li Reboot
+menuitem to the end of the last configured menuitem.
+If
+.Va menu_options
+is configured, the
+.Dq Li Reboot
+menuitem will be inserted before the
+.Dq Options
+separator.
+.El
+.Pp
+In addition, it provides the following FICL words:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic arch-i386? ( -- BOOL )
+Returns true (-1) on i386 and false (0) otherwise.
+.It Ic acpipresent? ( -- BOOL )
+Returns true (-1) if ACPI is present and false (0) otherwise.
+.It Ic acpienabled? ( -- BOOL )
+Returns true (-1) if ACPI is enabled and false (0) otherwise.
+.It Ic toggle_menuitem ( N -- N )
+Toggles menuitem
+.Dq Li N
+between
+.Va menu_caption[x]
+and
+.Va toggled_text[x]
+(where
+.Dq Li N
+represents the ASCII decimal value for
+.Dq Li x ) .
+.It Ic cycle_menuitem ( N -- N )
+Cycles menuitem
+.Dq Li N
+between
+.Va menu_caption[x][y]
+entries (where
+.Va N
+represents the ASCII decimal value for
+.Va x ) .
+.El
+.Pp
+For all values of
+.Dq Li x
+above, use any number between 1 through 9. Sorry, double-digits are not
+currently supported.
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/menu.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+A simple boot menu:
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/menu.4th
+menu-init
+set menu_caption[1]="Boot"
+set menu_command[1]="boot"
+set menu_options=2
+set menu_caption[2]="Option: NO"
+set toggled_text[2]="Option: YES"
+set menu_command[2]="toggle_menuitem"
+set menu_timeout_command="boot"
+set menu_reboot
+menu-display
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr beastie.4th 8 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/menu.rc b/usr/src/boot/sys/boot/forth/menu.rc
new file mode 100644
index 0000000000..b08d6bae54
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menu.rc
@@ -0,0 +1,222 @@
+\ Menu.rc
+\
+\ Load required Forth modules
+include /boot/forth/version.4th
+include /boot/forth/brand.4th
+include /boot/forth/menu.4th
+include /boot/forth/menu-commands.4th
+include /boot/forth/shortcuts.4th
+
+\ Screen prep
+clear \ clear the screen (see `screen.4th')
+print_version \ print version string (bottom-right; see `version.4th')
+draw-beastie \ draw freebsd mascot (on right; see `beastie.4th')
+draw-brand \ draw the FreeBSD title (top-left; see `brand.4th')
+menu-init \ initialize the menu area (see `menu.4th')
+
+\ Initialize main menu constructs (see `menu.4th')
+\ NOTE: To use `non-ansi' variants, add `loader_color=0' to loader.conf(5)
+\ NOTE: ANSI variants can use `^' in place of literal `Esc' (ASCII 27)
+
+\
+\ MAIN MENU
+\
+
+set menuset_name1="main"
+
+set mainmenu_init[1]="init_boot"
+
+s" smartos" getenv? [if]
+ set mainmenu_caption[1]="Boot SmartOS [Enter]"
+ set maintoggled_text[1]="R[e]covery (root/root) [Enter]"
+ set mainansi_caption[1]="^[1mB^[moot SmartOS ^[1m[Enter]^[m"
+ set maintoggled_ansi[1]="R^[1me^[mcovery (root/root) ^[1m[Enter]^[m"
+[else]
+ set mainmenu_caption[1]="Boot Multi User [Enter]"
+ set maintoggled_text[1]="Boot [S]ingle User [Enter]"
+ set mainansi_caption[1]="^[1mB^[moot Multi User ^[1m[Enter]^[m"
+ set maintoggled_ansi[1]="Boot ^[1mS^[mingle User ^[1m[Enter]^[m"
+[then]
+set mainmenu_command[1]="boot"
+\ keycode set by init_boot
+
+set mainmenu_init[2]="init_altboot"
+s" smartos" getenv? [if]
+ set mainmenu_caption[2]="[R]ecovery (root/root)"
+ set maintoggled_text[2]="[B]oot SmartOS"
+ set mainansi_caption[2]="^[1mR^[mecovery (root/root)"
+ set maintoggled_ansi[2]="^[1mB^[oot SmartOS"
+[else]
+ set mainmenu_caption[2]="Boot [S]ingle User"
+ set maintoggled_text[2]="Boot [M]ulti User"
+ set mainansi_caption[2]="Boot ^[1mS^[mingle User"
+ set maintoggled_ansi[2]="Boot ^[1mM^[multi User"
+[then]
+set mainmenu_command[2]="altboot"
+\ keycode set by init_altboot
+
+set mainmenu_caption[3]="[Esc]ape to loader prompt"
+set mainmenu_command[3]="goto_prompt"
+set mainmenu_keycode[3]=27
+set mainansi_caption[3]="^[1mEsc^[mape to loader prompt"
+
+\ Enable built-in "Reboot" trailing menuitem
+\ NOTE: appears before menu_options if configured
+\
+set mainmenu_reboot
+
+\ Enable "Options:" separator. When set to a numerical value (1-8), a visual
+\ separator is inserted before that menuitem number.
+\
+set mainmenu_options=5
+
+\ illumos does not have multiple kernels
+\ set mainmenu_kernel=5
+\ set mainmenu_command[5]="cycle_kernel"
+\ set mainmenu_keycode[5]=107
+
+set mainmenu_caption[5]="Configure Boot [O]ptions..."
+set mainmenu_command[5]="2 goto_menu"
+set mainmenu_keycode[5]=111
+set mainansi_caption[5]="Configure Boot ^[1mO^[mptions..."
+
+\ Boot Environments are (supported) only on ZFS
+s" currdev" getenv drop 4 s" zfs:" compare 0= be-pages and [if]
+set mainmenu_caption[6]="Select Boot [E]nvironment..."
+set mainmenu_command[6]="3 goto_menu"
+set mainmenu_keycode[6]=101
+set mainansi_caption[6]="Select Boot ^[1mE^[mnvironment..."
+
+ s" chain_disk" getenv? [if]
+ set mainmenu_caption[7]="Chain[L]load ${chain_disk}"
+ set mainmenu_command[7]="chain ${chain_disk}"
+ set mainmenu_keycode[7]=108
+ set mainansi_caption[7]="Chain^[1mL^[moad ${chain_disk}"
+ [then]
+[else]
+ s" chain_disk" getenv? [if]
+ set mainmenu_caption[6]="Chain[L]load ${chain_disk}"
+ set mainmenu_command[6]="chain ${chain_disk}"
+ set mainmenu_keycode[6]=108
+ set mainansi_caption[6]="Chain^[1mL^[moad ${chain_disk}"
+ [then]
+[then]
+
+\
+\ BOOT OPTIONS MENU
+\
+
+set menuset_name2="options"
+
+set optionsmenu_caption[1]="Back to Main Menu [Backspace]"
+set optionsmenu_command[1]="1 goto_menu"
+set optionsmenu_keycode[1]=8
+set optionsansi_caption[1]="Back to Main Menu ^[1m[Backspace]^[m"
+
+\ set optionsmenu_caption[2]="Load System [D]efaults"
+\ set optionsmenu_command[2]="set_default_boot_options"
+\ set optionsmenu_keycode[2]=100
+\ set optionsansi_caption[2]="Load System ^[1mD^[mefaults"
+
+set optionsmenu_options=2
+set optionsmenu_optionstext="Boot Options:"
+
+set optionsmenu_osconsole=2
+set optionsmenu_command[2]="cycle_osconsole"
+set optionsmenu_keycode[2]=99
+
+set optionsmenu_acpi=3
+set optionsmenu_command[3]="cycle_acpi"
+set optionsmenu_keycode[3]=97
+
+set optionsmenu_init[4]="init_singleuser"
+set optionsmenu_caption[4]="[S]ingle User. Off"
+set optionstoggled_text[4]="[S]ingle User. On"
+set optionsmenu_command[4]="toggle_singleuser"
+set optionsmenu_keycode[4]=115
+set optionsansi_caption[4]="^[1mS^[mingle User. ^[34;1mOff^[m"
+set optionstoggled_ansi[4]="^[1mS^[mingle User. ^[32;7mOn^[m"
+
+set optionsmenu_init[5]="init_verbose"
+set optionsmenu_caption[5]="[V]erbose..... off"
+set optionstoggled_text[5]="[V]erbose..... On"
+set optionsmenu_command[5]="toggle_verbose"
+set optionsmenu_keycode[5]=118
+set optionsansi_caption[5]="^[1mV^[merbose..... ^[34;1mOff^[m"
+set optionstoggled_ansi[5]="^[1mV^[merbose..... ^[32;7mOn^[m"
+
+set optionsmenu_init[6]="init_reconfigure"
+set optionsmenu_caption[6]="[R]econfigure. Off"
+set optionstoggled_text[6]="[R]econfigure. On"
+set optionsmenu_command[6]="toggle_reconfigure"
+set optionsmenu_keycode[6]=114
+set optionsansi_caption[6]="^[1mR^[meconfigure. ^[34;1mOff^[m"
+set optionstoggled_ansi[6]="^[1mR^[meconfigure. ^[32;7mOn^[m"
+
+set optionsmenu_init[7]="init_kmdb"
+set optionsmenu_caption[7]="k[M]db........ Off"
+set optionstoggled_text[7]="k[M]db........ On"
+set optionsmenu_command[7]="toggle_kmdb"
+set optionsmenu_keycode[7]=109
+set optionsansi_caption[7]="k^[1mm^[mdb........ ^[34;1mOff^[m"
+set optionstoggled_ansi[7]="k^[1mm^[mdb........ ^[32;7mOn^[m"
+
+set optionsmenu_init[8]="init_debug"
+set optionsmenu_caption[8]="[D]ebug....... Off"
+set optionstoggled_text[8]="[D]ebug....... On"
+set optionsmenu_command[8]="toggle_debug"
+set optionsmenu_keycode[8]=100
+set optionsansi_caption[8]="^[1mD^[mebug....... ^[34;1mOff^[m"
+set optionstoggled_ansi[8]="^[1mD^[mebug....... ^[32;7mOn^[m"
+
+\
+\ BOOT ENVIRONMENT MENU
+\
+
+\ the BE list is read from pool/boot/menu.lst, the list in file
+\ is ordered from oldest to most recent.
+\ the BE menu will list entries from most recent to oldest,
+\ so the first page in menu is last page in menu.lst
+
+s" currdev" getenv drop 4 s" zfs:" compare 0= be-pages and [if]
+ set zfs_be_currpage=1
+ be-set-page \ set page data
+ set menuset_name3="bootenv"
+
+ set bootenvmenu_command[1]="be_draw_screen 1 goto_menu"
+ set bootenvmenu_keycode[1]=8
+
+ set bootenvmenu_keycode[2]=8
+ set bootenvmenu_command[2]="be_draw_screen 1 goto_menu"
+
+ set bemenu_current="Active: "
+ set beansi_current="^[1m${bemenu_current}^[m"
+ set bemenu_bootfs="bootfs: "
+ set beansi_bootfs="^[1m${bemenu_bootfs}^[m"
+ set bemenu_page="[P]age: "
+ set beansi_page="^[1mP^[mage: "
+ set bemenu_pageof=" of "
+ set beansi_pageof="${bemenu_pageof}"
+
+ set bootenvmenu_init="init_bootenv"
+
+ set bootenvmenu_keycode[3]=112
+ set bootenvmenu_command[3]="set_be_page"
+
+ set bootenvmenu_options=4
+ set bootenvmenu_optionstext="Boot Environments:"
+[then]
+
+\ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to
+\ customize the timeout; default is 10-seconds)
+\
+set menu_timeout_command="boot"
+
+\ Include optional elements defined in a local file
+\
+try-include /boot/menu.rc.local
+
+\ Display the main menu (see `menu.4th')
+set menuset_initial=1
+menuset-loadinitial
+menu-display
diff --git a/usr/src/boot/sys/boot/forth/menusets.4th b/usr/src/boot/sys/boot/forth/menusets.4th
new file mode 100644
index 0000000000..b0c1dd5c64
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menusets.4th
@@ -0,0 +1,630 @@
+\ Copyright (c) 2012 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-menusets.4th
+
+vocabulary menusets-infrastructure
+only forth also menusets-infrastructure definitions
+
+variable menuset_use_name
+
+create menuset_affixbuf 255 allot
+create menuset_x 1 allot
+create menuset_y 1 allot
+
+: menuset-loadvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ s" set cmdbuf='set ${type}_${var}=\$'" evaluate
+ s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
+ menuset_use_name @ true = if
+ s" set cmdbuf=${cmdbuf}${affix}${type}_${var}"
+ ( u1 -- u1 c-addr2 u2 )
+ else
+ s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}"
+ ( u1 -- u1 c-addr2 u2 )
+ then
+ evaluate ( u1 c-addr2 u2 -- u1 )
+ s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
+ rot 2 pick 2 pick over + -rot + tuck -
+ ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
+ \ Generate a string representing rvalue inheritance var
+ getenv dup -1 = if
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
+ \ NOT set -- clean up the stack
+ drop ( c-addr2 u2 -1 -- c-addr2 u2 )
+ 2drop ( c-addr2 u2 -- )
+ else
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
+ \ SET -- execute cmdbuf (c-addr2/u2) to inherit value
+ 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
+ evaluate ( c-addr2 u2 -- )
+ then
+
+ s" cmdbuf" unsetenv
+;
+
+: menuset-unloadvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ menuset_use_name @ true = if
+ s" set buf=${affix}${type}_${var}"
+ else
+ s" set buf=${type}set${affix}_${var}"
+ then
+ evaluate
+ s" buf" getenv unsetenv
+ s" buf" unsetenv
+;
+
+: menuset-loadmenuvar ( -- )
+ s" set type=menu" evaluate
+ menuset-loadvar
+;
+
+: menuset-unloadmenuvar ( -- )
+ s" set type=menu" evaluate
+ menuset-unloadvar
+;
+
+: menuset-loadxvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $x is "1" through "8"
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ s" set cmdbuf='set ${type}_${var}[${x}]=\$'" evaluate
+ s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
+ menuset_use_name @ true = if
+ s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}]"
+ ( u1 -- u1 c-addr2 u2 )
+ else
+ s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}]"
+ ( u1 -- u1 c-addr2 u2 )
+ then
+ evaluate ( u1 c-addr2 u2 -- u1 )
+ s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
+ rot 2 pick 2 pick over + -rot + tuck -
+ ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
+ \ Generate a string representing rvalue inheritance var
+ getenv dup -1 = if
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
+ \ NOT set -- clean up the stack
+ drop ( c-addr2 u2 -1 -- c-addr2 u2 )
+ 2drop ( c-addr2 u2 -- )
+ else
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
+ \ SET -- execute cmdbuf (c-addr2/u2) to inherit value
+ 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
+ evaluate ( c-addr2 u2 -- )
+ then
+
+ s" cmdbuf" unsetenv
+;
+
+: menuset-unloadxvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $x is "1" through "8"
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ menuset_use_name @ true = if
+ s" set buf=${affix}${type}_${var}[${x}]"
+ else
+ s" set buf=${type}set${affix}_${var}[${x}]"
+ then
+ evaluate
+ s" buf" getenv unsetenv
+ s" buf" unsetenv
+;
+
+: menuset-loadansixvar ( -- )
+ s" set type=ansi" evaluate
+ menuset-loadxvar
+;
+
+: menuset-unloadansixvar ( -- )
+ s" set type=ansi" evaluate
+ menuset-unloadxvar
+;
+
+: menuset-loadmenuxvar ( -- )
+ s" set type=menu" evaluate
+ menuset-loadxvar
+;
+
+: menuset-unloadmenuxvar ( -- )
+ s" set type=menu" evaluate
+ menuset-unloadxvar
+;
+
+: menuset-loadtoggledxvar ( -- )
+ s" set type=toggled" evaluate
+ menuset-loadxvar
+;
+
+: menuset-unloadtoggledxvar ( -- )
+ s" set type=toggled" evaluate
+ menuset-unloadxvar
+;
+
+: menuset-loadxyvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $x is "1" through "8"
+ \ $y is "0" through "9"
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ s" set cmdbuf='set ${type}_${var}[${x}][${y}]=\$'" evaluate
+ s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
+ menuset_use_name @ true = if
+ s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}][${y}]"
+ ( u1 -- u1 c-addr2 u2 )
+ else
+ s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}][${y}]"
+ ( u1 -- u1 c-addr2 u2 )
+ then
+ evaluate ( u1 c-addr2 u2 -- u1 )
+ s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
+ rot 2 pick 2 pick over + -rot + tuck -
+ ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
+ \ Generate a string representing rvalue inheritance var
+ getenv dup -1 = if
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
+ \ NOT set -- clean up the stack
+ drop ( c-addr2 u2 -1 -- c-addr2 u2 )
+ 2drop ( c-addr2 u2 -- )
+ else
+ ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
+ \ SET -- execute cmdbuf (c-addr2/u2) to inherit value
+ 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
+ evaluate ( c-addr2 u2 -- )
+ then
+
+ s" cmdbuf" unsetenv
+;
+
+: menuset-unloadxyvar ( -- )
+
+ \ menuset_use_name is true or false
+ \ $type should be set to one of:
+ \ menu toggled ansi
+ \ $var should be set to one of:
+ \ caption command keycode text ...
+ \ $x is "1" through "8"
+ \ $y is "0" through "9"
+ \ $affix is either prefix (menuset_use_name is true)
+ \ or infix (menuset_use_name is false)
+
+ menuset_use_name @ true = if
+ s" set buf=${affix}${type}_${var}[${x}][${y}]"
+ else
+ s" set buf=${type}set${affix}_${var}[${x}][${y}]"
+ then
+ evaluate
+ s" buf" getenv unsetenv
+ s" buf" unsetenv
+;
+
+: menuset-loadansixyvar ( -- )
+ s" set type=ansi" evaluate
+ menuset-loadxyvar
+;
+
+: menuset-unloadansixyvar ( -- )
+ s" set type=ansi" evaluate
+ menuset-unloadxyvar
+;
+
+: menuset-loadmenuxyvar ( -- )
+ s" set type=menu" evaluate
+ menuset-loadxyvar
+;
+
+: menuset-unloadmenuxyvar ( -- )
+ s" set type=menu" evaluate
+ menuset-unloadxyvar
+;
+
+: menuset-setnum-namevar ( N -- C-Addr/U )
+
+ s" menuset_nameNNNNN" ( n -- n c-addr1 u1 ) \ variable basename
+ drop 12 ( n c-addr1 u1 -- n c-addr1 12 ) \ remove "NNNNN"
+ rot ( n c-addr1 12 -- c-addr1 12 n ) \ move number on top
+
+ \ convert to string
+ s>d <# #s #> ( c-addr1 12 n -- c-addr1 12 c-addr2 u2 )
+
+ \ Combine strings
+ begin ( using u2 in c-addr2/u2 pair as countdown to zero )
+ over ( c-addr1 u1 c-addr2 u2 -- continued below )
+ ( c-addr1 u1 c-addr2 u2 c-addr2 ) \ copy src-addr
+ c@ ( c-addr1 u1 c-addr2 u2 c-addr2 -- continued below )
+ ( c-addr1 u1 c-addr2 u2 c ) \ get next src-addr byte
+ 4 pick 4 pick
+ ( c-addr1 u1 c-addr2 u2 c -- continued below )
+ ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 )
+ \ get destination c-addr1/u1 pair
+ + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- cont. below )
+ ( c-addr1 u1 c-addr2 u2 c c-addr3 )
+ \ combine dest-c-addr to get dest-addr for byte
+ c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below )
+ ( c-addr1 u1 c-addr2 u2 )
+ \ store the current src-addr byte into dest-addr
+
+ 2swap 1+ 2swap \ increment u1 in destination c-addr1/u1 pair
+ swap 1+ swap \ increment c-addr2 in source c-addr2/u2 pair
+ 1- \ decrement u2 in the source c-addr2/u2 pair
+
+ dup 0= \ time to break?
+ until
+
+ 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 )
+ \ drop temporary number-format conversion c-addr2/u2
+;
+
+: menuset-checksetnum ( N -- )
+
+ \
+ \ adjust input to be both positive and no-higher than 65535
+ \
+ abs dup 65535 > if drop 65535 then ( n -- n )
+
+ \
+ \ The next few blocks will determine if we should use the default
+ \ methodology (referencing the original numeric stack-input), or if-
+ \ instead $menuset_name{N} has been defined wherein we would then
+ \ use the value thereof as the prefix to every menu variable.
+ \
+
+ false menuset_use_name ! \ assume name is not set
+
+ menuset-setnum-namevar
+ \
+ \ We now have a string that is the assembled variable name to check
+ \ for... $menuset_name{N}. Let's check for it.
+ \
+ 2dup ( c-addr1 u1 -- c-addr1 u1 c-addr1 u1 ) \ save a copy
+ getenv dup -1 <> if ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 c-addr2 u2 )
+ \ The variable is set. Let's clean up the stack leaving only
+ \ its value for later use.
+
+ true menuset_use_name !
+ 2swap 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr2 u2 )
+ \ drop assembled variable name, leave the value
+ else ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 -1 ) \ no such variable
+ \ The variable is not set. Let's clean up the stack leaving the
+ \ string [portion] representing the original numeric input.
+
+ drop ( c-addr1 u1 -1 -- c-addr1 u1 ) \ drop -1 result
+ 12 - swap 12 + swap ( c-addr1 u1 -- c-addr2 u2 )
+ \ truncate to original numeric stack-input
+ then
+
+ \
+ \ Now, depending on whether $menuset_name{N} has been set, we have
+ \ either the value thereof to be used as a prefix to all menu_*
+ \ variables or we have a string representing the numeric stack-input
+ \ to be used as a "set{N}" infix to the same menu_* variables.
+ \
+ \ For example, if the stack-input is 1 and menuset_name1 is NOT set
+ \ the following variables will be referenced:
+ \ ansiset1_caption[x] -> ansi_caption[x]
+ \ ansiset1_caption[x][y] -> ansi_caption[x][y]
+ \ menuset1_acpi -> menu_acpi
+ \ menuset1_osconsole -> menu_osconsole
+ \ menuset1_caption[x] -> menu_caption[x]
+ \ menuset1_caption[x][y] -> menu_caption[x][y]
+ \ menuset1_command[x] -> menu_command[x]
+ \ menuset1_init -> ``evaluated''
+ \ menuset1_init[x] -> menu_init[x]
+ \ menuset1_kernel -> menu_kernel
+ \ menuset1_keycode[x] -> menu_keycode[x]
+ \ menuset1_options -> menu_options
+ \ menuset1_optionstext -> menu_optionstext
+ \ menuset1_reboot -> menu_reboot
+ \ toggledset1_ansi[x] -> toggled_ansi[x]
+ \ toggledset1_text[x] -> toggled_text[x]
+ \ otherwise, the following variables are referenced (where {name}
+ \ represents the value of $menuset_name1 (given 1 as stack-input):
+ \ {name}ansi_caption[x] -> ansi_caption[x]
+ \ {name}ansi_caption[x][y] -> ansi_caption[x][y]
+ \ {name}menu_acpi -> menu_acpi
+ \ {name}menu_caption[x] -> menu_caption[x]
+ \ {name}menu_caption[x][y] -> menu_caption[x][y]
+ \ {name}menu_command[x] -> menu_command[x]
+ \ {name}menu_init -> ``evaluated''
+ \ {name}menu_init[x] -> menu_init[x]
+ \ {name}menu_kernel -> menu_kernel
+ \ {name}menu_keycode[x] -> menu_keycode[x]
+ \ {name}menu_options -> menu_options
+ \ {name}menu_optionstext -> menu_optionstext
+ \ {name}menu_reboot -> menu_reboot
+ \ {name}toggled_ansi[x] -> toggled_ansi[x]
+ \ {name}toggled_text[x] -> toggled_text[x]
+ \
+ \ Note that menuset{N}_init and {name}menu_init are the initializers
+ \ for the entire menu (for wholly dynamic menus) opposed to the per-
+ \ menuitem initializers (with [x] afterward). The whole-menu init
+ \ routine is evaluated and not passed down to $menu_init (which
+ \ would result in double evaluation). By doing this, the initializer
+ \ can initialize the menuset before we transfer it to active-duty.
+ \
+
+ \
+ \ Copy our affixation (prefix or infix depending on menuset_use_name)
+ \ to our buffer so that we can safely use the s-quote (s") buf again.
+ \
+ menuset_affixbuf 0 2swap ( c-addr2 u2 -- c-addr1 0 c-addr2 u2 )
+ begin ( using u2 in c-addr2/u2 pair as countdown to zero )
+ over ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c-addr2 )
+ c@ ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c )
+ 4 pick 4 pick
+ ( c-addr1 u1 c-addr2 u2 c -- continued below )
+ ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 )
+ + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- continued below )
+ ( c-addr1 u1 c-addr2 u2 c c-addr3 )
+ c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below )
+ ( c-addr1 u1 c-addr2 u2 )
+ 2swap 1+ 2swap \ increment affixbuf byte position/count
+ swap 1+ swap \ increment strbuf pointer (source c-addr2)
+ 1- \ decrement strbuf byte count (source u2)
+ dup 0= \ time to break?
+ until
+ 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) \ drop strbuf c-addr2/u2
+
+ \
+ \ Create a variable for referencing our affix data (prefix or infix
+ \ depending on menuset_use_name as described above). This variable will
+ \ be temporary and only used to simplify cmdbuf assembly.
+ \
+ s" affix" setenv ( c-addr1 u1 -- )
+;
+
+: menuset-cleanup ( -- )
+ s" type" unsetenv
+ s" var" unsetenv
+ s" x" unsetenv
+ s" y" unsetenv
+ s" affix" unsetenv
+;
+
+only forth definitions also menusets-infrastructure
+
+: menuset-loadsetnum ( N -- )
+
+ menuset-checksetnum ( n -- )
+
+ \
+ \ From here out, we use temporary environment variables to make
+ \ dealing with variable-length strings easier.
+ \
+ \ menuset_use_name is true or false
+ \ $affix should be used appropriately w/respect to menuset_use_name
+ \
+
+ \ ... menu_init ...
+ s" set var=init" evaluate
+ menuset-loadmenuvar
+
+ \ If menu_init was set by the above, evaluate it here-and-now
+ \ so that the remaining variables are influenced by its actions
+ s" menu_init" 2dup getenv dup -1 <> if
+ 2swap unsetenv \ don't want later menu-create to re-call this
+ evaluate
+ else
+ drop 2drop ( n c-addr u -1 -- n )
+ then
+
+ [char] 1 ( -- x ) \ Loop range ASCII '1' (49) to '8' (56)
+ begin
+ dup menuset_x tuck c! 1 s" x" setenv \ set loop iterator and $x
+
+ s" set var=caption" evaluate
+
+ \ ... menu_caption[x] ...
+ menuset-loadmenuxvar
+
+ \ ... ansi_caption[x] ...
+ menuset-loadansixvar
+
+ [char] 0 ( x -- x y ) \ Inner Loop ASCII '1' (48) to '9' (57)
+ begin
+ dup menuset_y tuck c! 1 s" y" setenv
+ \ set inner loop iterator and $y
+
+ \ ... menu_caption[x][y] ...
+ menuset-loadmenuxyvar
+
+ \ ... ansi_caption[x][y] ...
+ menuset-loadansixyvar
+
+ 1+ dup 57 > ( x y -- y' 0|-1 ) \ increment and test
+ until
+ drop ( x y -- x )
+
+ \ ... menu_command[x] ...
+ s" set var=command" evaluate
+ menuset-loadmenuxvar
+
+ \ ... menu_init[x] ...
+ s" set var=init" evaluate
+ menuset-loadmenuxvar
+
+ \ ... menu_keycode[x] ...
+ s" set var=keycode" evaluate
+ menuset-loadmenuxvar
+
+ \ ... toggled_text[x] ...
+ s" set var=text" evaluate
+ menuset-loadtoggledxvar
+
+ \ ... toggled_ansi[x] ...
+ s" set var=ansi" evaluate
+ menuset-loadtoggledxvar
+
+ 1+ dup 56 > ( x -- x' 0|-1 ) \ increment iterator
+ \ continue if less than 57
+ until
+ drop ( x -- ) \ loop iterator
+
+ \ ... menu_reboot ...
+ s" set var=reboot" evaluate
+ menuset-loadmenuvar
+
+ \ ... menu_acpi ...
+ s" set var=acpi" evaluate
+ menuset-loadmenuvar
+
+ \ ... menu_osconsole ...
+ s" set var=osconsole" evaluate
+ menuset-loadmenuvar
+
+ \ ... menu_kernel ...
+ s" set var=kernel" evaluate
+ menuset-loadmenuvar
+
+ \ ... menu_options ...
+ s" set var=options" evaluate
+ menuset-loadmenuvar
+
+ \ ... menu_optionstext ...
+ s" set var=optionstext" evaluate
+ menuset-loadmenuvar
+
+ menuset-cleanup
+;
+
+: menusets-unset ( -- )
+
+ s" menuset_initial" unsetenv
+
+ 1 begin
+ dup menuset-checksetnum ( n n -- n )
+
+ dup menuset-setnum-namevar ( n n -- n )
+ unsetenv
+
+ \ If the current menuset does not populate the first menuitem,
+ \ we stop completely.
+
+ menuset_use_name @ true = if
+ s" set buf=${affix}menu_caption[1]"
+ else
+ s" set buf=menuset${affix}_caption[1]"
+ then
+ evaluate s" buf" getenv getenv -1 = if
+ drop ( n -- )
+ s" buf" unsetenv
+ menuset-cleanup
+ exit
+ else
+ drop ( n c-addr2 -- n ) \ unused
+ then
+
+ [char] 1 ( n -- n x ) \ Loop range ASCII '1' (49) to '8' (56)
+ begin
+ dup menuset_x tuck c! 1 s" x" setenv \ set $x to x
+
+ s" set var=caption" evaluate
+ menuset-unloadmenuxvar
+ menuset-unloadmenuxvar
+ menuset-unloadansixvar
+ [char] 0 ( n x -- n x y ) \ Inner loop '0' to '9'
+ begin
+ dup menuset_y tuck c! 1 s" y" setenv
+ \ sets $y to y
+ menuset-unloadmenuxyvar
+ menuset-unloadansixyvar
+ 1+ dup 57 > ( n x y -- n x y' 0|-1 )
+ until
+ drop ( n x y -- n x )
+ s" set var=command" evaluate menuset-unloadmenuxvar
+ s" set var=init" evaluate menuset-unloadmenuxvar
+ s" set var=keycode" evaluate menuset-unloadmenuxvar
+ s" set var=text" evaluate menuset-unloadtoggledxvar
+ s" set var=ansi" evaluate menuset-unloadtoggledxvar
+
+ 1+ dup 56 > ( x -- x' 0|-1 ) \ increment and test
+ until
+ drop ( n x -- n ) \ loop iterator
+
+ s" set var=acpi" evaluate menuset-unloadmenuvar
+ s" set var=osconsole" evaluate menuset-unloadmenuvar
+ s" set var=init" evaluate menuset-unloadmenuvar
+ s" set var=kernel" evaluate menuset-unloadmenuvar
+ s" set var=options" evaluate menuset-unloadmenuvar
+ s" set var=optionstext" evaluate menuset-unloadmenuvar
+ s" set var=reboot" evaluate menuset-unloadmenuvar
+
+ 1+ dup 65535 > ( n -- n' 0|-1 ) \ increment and test
+ until
+ drop ( n' -- ) \ loop iterator
+
+ s" buf" unsetenv
+ menuset-cleanup
+;
+
+only forth definitions
+
+: menuset-loadinitial ( -- )
+ s" menuset_initial" getenv dup -1 <> if
+ ?number 0<> if
+ menuset-loadsetnum
+ then
+ else
+ drop \ cruft
+ then
+;
diff --git a/usr/src/boot/sys/boot/forth/menusets.4th.8 b/usr/src/boot/sys/boot/forth/menusets.4th.8
new file mode 100644
index 0000000000..f785ae18ea
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/menusets.4th.8
@@ -0,0 +1,372 @@
+.\" Copyright (c) 2012 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 5, 2012
+.Dt MENUSETS.4TH 8
+.Os
+.Sh NAME
+.Nm menusets.4th
+.Nd FreeBSD dynamic submenu boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to add submenu functionality to the dynamic menu
+system provided by
+.Xr menu.4th 8 .
+Submenus are managed through a system of carefully named environment variables.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the examples below for the most common situations, and to
+.Xr menu.4th 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include menusets.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu-commands.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width menuset-loadinitial -compact -offset indent
+.It Ic menuset-loadsetnum
+Takes a single integer on the stack to identify the menuset environment
+variables to be activated (see environment variables below).
+.It Ic menuset-loadinitial
+If $menuset_initial is set, passes the value to menuset-loadsetnum.
+The value must be a number.
+.It Ic menusets-unset
+Unsets the environment variables associated with all menusets.
+Increments starting at 1 and stops at the first unconfigured menuset.
+A menuset is considered configured if the caption for item 1 is set.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va menuset_initial
+Number to pass to menuset-loadsetnum when menuset-loadinitial is called.
+.It Va menuset_nameN
+Used to give a name to a menuset.
+.El
+.Pp
+When a menuset is NOT given a name (the default),
+menuset N is comprised of the following environment variables:
+.Pp
+.Bl -tag -width menusetN_caption[x][y] -compact -offset indent
+.It Va ansisetN_caption[x]
+-> ansi_caption[x]
+.It Va ansisetN_caption[x][y]
+-> ansi_caption[x][y]
+.It Va menusetN_acpi
+-> menu_acpi
+.It Va menusetN_caption[x]
+-> menu_caption[x]
+.It Va menusetN_caption[x][y]
+-> menu_caption[x][y]
+.It Va menusetN_command[x]
+-> menu_command[x]
+.It Va menusetN_init
+->
+.Dq Li evaluated
+.It Va menusetN_init[x]
+-> menu_init[x]
+.It Va menusetN_keycode[x]
+-> menu_keycode[x]
+.It Va menusetN_options
+-> menu_options
+.It Va menusetN_optionstext
+-> menu_optionstext
+.It Va menusetN_reboot
+-> menu_reboot
+.It Va toggledsetN_ansi[x]
+-> toggled_ansi[x]
+.It Va toggledsetN_text[x]
+-> toggled_text[x]
+.El
+.Pp
+When you choose to give a menuset a name (by setting $menuset_nameN),
+menuset N is instead comprised of the following environment variables:
+.Pp
+.Bl -tag -width NAMEmenu_caption[x][y] -compact -offset indent
+.It Va NAMEansi_caption[x]
+-> ansi_caption[x]
+.It Va NAMEansi_caption[x][y]
+-> ansi_caption[x][y]
+.It Va NAMEmenu_acpi
+-> menu_acpi
+.It Va NAMEmenu_caption[x]
+-> menu_caption[x]
+.It Va NAMEmenu_caption[x][y]
+-> menu_caption[x][y]
+.It Va NAMEmenu_command[x]
+-> menu_command[x]
+.It Va NAMEmenu_init
+->
+.Dq Li evaluated
+.It Va NAMEmenu_init[x]
+-> menu_init[x]
+.It Va NAMEmenu_keycode[x]
+-> menu_keycode[x]
+.It Va NAMEmenu_options
+-> menu_options
+.It Va NAMEmenu_optionstext
+-> menu_optionstext
+.It Va NAMEmenu_reboot
+-> menu_reboot
+.It Va NAMEtoggled_ansi[x]
+-> toggled_ansi[x]
+.It Va NAMEtoggled_text[x]
+-> toggled_text[x]
+.El
+.Pp
+where
+.Dq Li NAME
+is the value of $menuset_nameN.
+In the case of $NAMEmenu_init ($menusetN_init when $menuset_nameN is unset),
+the value is evaluated as an FICL statement.
+This can be used to dynamically adjust the menuset variables right before the
+menu is activated.
+.Pp
+In addition,
+.Nm
+provides the following FICL words:
+.Pp
+.Bl -tag -width menuset -compact -offset indent
+.It Ic menuset-checksetnum ( N -- )
+Given a single integer on the stack, sets a global variable
+.Va menuset_use_name
+to a boolean based on whether $menuset_nameN is set (true) or not (false).
+Also sets $affix temporary variable (prefix or infix depending on
+menuset_use_name).
+Automatically called by menuset-loadsetnum and menusets-unset.
+.It Ic menuset-loadvar ( -- )
+Used indirectly to shorten syntax and mitigate dictionary size.
+Requires the following temporary environment variables:
+.Pp
+.Bl -tag -width affix -compact -offset indent
+.It Va type
+should be set to one of: menu toggled ansi
+.It Va var
+should be set to one of: caption command keycode text ...
+.It Va affix
+either a prefix (menuset_use_name is true) or infix (menuset_use_name is false)
+.El
+.Pp
+If the global
+.Va menuset_use_name
+is true, the variable ${type}_${var} is made to
+equal the value of the variable ${affix}${type}_${var}
+(note: in this case menuset-checksetnum has set $affix to $menuset_nameN).
+Otherwise (when
+.Va menuset_use_name
+is false), the variable ${type}_${var} is made to
+equal the value of the variable ${type}set${affix}_${var}
+(note: in this case menuset-checksetnum has set $affix to N).
+.Pp
+Both the global variable
+.Va menuset_use_name
+and the environment variable $affix are automatically handled by
+menuset-checksetnum above (which is automatically called by
+menuset-loadsetnum).
+.It Ic menuset-unloadvar ( -- )
+Used indirectly to shorten syntax and mitigate dictionary size.
+Like menuset-loadvar except it unsets the menuset variable.
+If global
+.Va menuset_use_name
+is true ($affix is $menuset_nameN),
+variable ${affix}${type}_${var} is unset.
+Otherwise, $affix is N and variable ${type}set${affix}_${var} is unset.
+.It Ic menuset-loadmenuvar ( -- )
+Sets $type to
+.Dq menu
+and calls menuset-loadvar.
+.It Ic menuset-unloadmenuvar ( -- )
+Sets $type to
+.Dq menu
+and calls menuset-unloadvar.
+.It Ic menuset-loadxvar ( -- )
+Like menuset-loadvar except it takes an additional temporary variable $x.
+If the global
+.Va menuset_use_name
+is true (making $affix equal $menuset_nameN),
+sets variable ${type}_${var}[${x}] to variable ${affix}${type}_${var}[${x}].
+Otherwise ($affix being N), sets the same variable to instead
+${type}set{affix}_${var}[${x}].
+.It Ic menuset-unloadxvar ( -- )
+Like menuset-loadxvar except it unsets the menuset variable.
+If global
+.Va menuset_use_name
+is true, unsets ${affix}${type}_${var}[${x}].
+Otherwise, unsets ${type}set${affix}_${var}[${x}].
+.It Ic menuset-loadansixvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-loadxvar
+.It Ic menuset-unloadansixvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-unloadxvar
+.It Ic menuset-loadmenuxvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-loadxvar
+.It Ic menuset-unloadmenuxvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-unloadxvar
+.It Ic menuset-loadtoggledxvar ( -- )
+Sets $type to
+.Dq toggled
+and calls menuset-loadxvar
+.It Ic menuset-unloadtoggledxvar ( -- )
+Sets $type to
+.Dq toggled
+and calls menuset-unloadxvar
+.It Ic menuset-loadxyvar ( -- )
+Like menuset-loadxvar except it takes an additional temporary variable $y.
+If the global
+.Va menuset_use_name
+is true ($affix is $menuset_nameN),
+sets variable ${type}_${var}[${x}][${y}] to ${affix}${type}_${var}[${x}][${y}].
+Otherwise ($affix is N) sets the same variable to instead
+${type}set${affix}_${var}[${x}][${y}].
+.It Ic menuset-unloadxyvar ( -- )
+Like menuset-loadxyvar except it unsets the menuset variable.
+If the global
+.Va menuset_use_name
+is true, unsets ${affix}${type}_${var}[${x}][${y}].
+Otherwise, unsets ${type}set${affix}_${var}[${x}][${y}].
+.It Ic menuset-loadansixyvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-loadxyvar.
+.It Ic menuset-unloadansixyvar ( -- )
+Sets $type to
+.Dq ansi
+and calls menuset-unloadxyvar.
+.It Ic menuset-loadmenuxyvar ( -- )
+Sets $type to
+.Dq menu
+and calls menuset-loadxyvar.
+.It Ic menuset-unloadmenuxyvar ( -- )
+Sets $type to
+.Dq menu
+and calls menuset-unloadxyvar.
+.It Ic menuset-setnum-namevar ( N -- C-Addr/U )
+Takes a single integer on the stack and replaces it with a string (in c-addr/u
+format) whose value is
+.Dq menuset_nameN .
+For example, if given 1 returns
+.Dq menuset_name1 .
+.It Ic menuset-cleanup ( N -- )
+Unsets all the various temporary variables, currently
+.Va type ,
+.Va var ,
+.Va x ,
+.Va y ,
+and
+.Va affix .
+.El
+.Pp
+For all values of
+.Dq Li x
+above, use any number between 1 through 9. Sorry, double-digits are not
+currently supported.
+For all values of
+.Dq Li N
+above, use any number between 1 and 65535.
+.Sh FILES
+.Bl -tag -width /boot/menu-commands.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/menu.4th
+Dynamic menu module.
+.It Pa /boot/menu-commands.4th
+Contains the goto_menu command.
+.It Pa /boot/menusets.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+A simple boot menu with a submenu:
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/menu.4th
+include /boot/menu-commands.4th
+menu-init
+set menuset1_caption[1]="Boot"
+set menuset1_command[1]="boot"
+set menuset1_caption[2]="Submenu..."
+set menuset1_command[2]="2 goto_menu"
+set menuset2_caption[1]="Back"
+set menuset2_command[1]="1 goto_menu"
+set menuset_initial=2
+menuset-loadinitial
+menu-display
+.Ed
+.Pp
+The same boot menu with named menusets:
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/menu.4th
+include /boot/menu-commands.4th
+menu-init
+set menuset_name1=main
+set mainmenu_caption[1]="Boot"
+set mainmenu_command[1]="boot"
+set mainmenu_caption[2]="Submenu..."
+set mainmenu_command[2]="2 goto_menu"
+set menuset_name2=sub
+set submenu_caption[1]="Back"
+set submenu_command[1]="1 goto_menu"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr beastie.4th 8 ,
+.Xr loader 8 ,
+.Xr loader.4th 8 ,
+.Xr menu.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 10.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/forth/pcibios.4th b/usr/src/boot/sys/boot/forth/pcibios.4th
new file mode 100644
index 0000000000..71702dad8a
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/pcibios.4th
@@ -0,0 +1,47 @@
+\ Copyright (c) 2014 M. Warner Losh <imp@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+only forth also support-functions also builtins definitions
+
+\ pci-device-count pci-id
+\
+\ Counts the number of instances of pci-id in the system and reports
+\ it to the user.
+: pci-device-count
+ 0= if ( interpreted ) get_arguments then
+
+ 0= if ." Need an argument" cr abort then
+ \ First argument is 0 when we're interprated. See support.4th
+ \ for get_arguments reading the rest of the line and parsing it
+ \ stack: argN lenN ... arg1 len1 N
+ hex ?number decimal
+ 0= if ." Bad pci-id given (must be legal hex value)" cr abort then
+ dup pcibios-device-count ." Found " . ." instances of " hex . decimal cr
+;
+
+also forth definitions also builtins
+
+builtin: pci-device-count
diff --git a/usr/src/boot/sys/boot/forth/pnp.4th b/usr/src/boot/sys/boot/forth/pnp.4th
new file mode 100644
index 0000000000..8be89d8277
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/pnp.4th
@@ -0,0 +1,205 @@
+\ Copyright (c) 2000 Daniel C. Sobral <dcs@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+
+\ The following pnp code is used in pnp.4th and pnp.c
+structure: STAILQ_HEAD
+ ptr stqh_first \ type*
+ ptr stqh_last \ type**
+;structure
+
+structure: STAILQ_ENTRY
+ ptr stqe_next \ type*
+;structure
+
+structure: pnphandler
+ ptr pnph.name
+ ptr pnph.enumerate
+;structure
+
+structure: pnpident
+ ptr pnpid.ident \ char*
+ sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident
+;structure
+
+structure: pnpinfo \ sync with sys/boot/config/bootstrap.h
+ ptr pnpi.desc
+ int pnpi.revision
+ ptr pnpi.module \ (char*) module args
+ int pnpi.argc
+ ptr pnpi.argv
+ ptr pnpi.handler \ pnphandler
+ sizeof STAILQ_HEAD member: pnpi.ident \ pnpident
+ sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo
+;structure
+\ end of pnp support
+
+pnpdevices drop
+
+: enumerate
+ pnphandlers begin
+ dup @
+ while
+ ." Probing " dup @ pnph.name @ dup strlen type ." ..." cr
+ 0 over @ pnph.enumerate @ ccall drop
+ cell+
+ repeat
+;
+
+: summary
+ ." PNP scan summary:" cr
+ pnpdevices stqh_first @
+ begin
+ dup
+ while
+ dup pnpi.ident stqh_first @ pnpid.ident @ dup strlen type
+ dup pnpi.desc @ ?dup if
+ ." : "
+ dup strlen type
+ then
+ cr
+ pnpi.link stqe_next @
+ repeat
+ drop
+;
+
+: compare-pnpid ( addr addr' -- flag )
+ begin
+ over c@ over c@ <> if drop drop false exit then
+ over c@ over c@ and
+ while
+ char+ swap char+ swap
+ repeat
+ c@ swap c@ or 0=
+;
+
+: search-pnpid ( id -- flag )
+ >r
+ pnpdevices stqh_first @
+ begin ( pnpinfo )
+ dup
+ while
+ dup pnpi.ident stqh_first @
+ begin ( pnpinfo pnpident )
+ dup pnpid.ident @ r@ compare-pnpid
+ if
+ r> drop
+ \ XXX Temporary debugging message
+ ." Found " pnpid.ident @ dup strlen type
+ pnpi.desc @ ?dup if
+ ." : " dup strlen type
+ then cr
+ \ drop drop
+ true
+ exit
+ then
+ pnpid.link stqe_next @
+ ?dup 0=
+ until
+ pnpi.link stqe_next @
+ repeat
+ r> drop
+ drop
+ false
+;
+
+: skip-space ( addr -- addr' )
+ begin
+ dup c@ bl =
+ over c@ 9 = or
+ while
+ char+
+ repeat
+;
+
+: skip-to-space ( addr -- addr' )
+ begin
+ dup c@ bl <>
+ over c@ 9 <> and
+ over c@ and
+ while
+ char+
+ repeat
+;
+
+: premature-end? ( addr -- addr flag )
+ postpone dup postpone c@ postpone 0=
+ postpone if postpone exit postpone then
+; immediate
+
+0 value filename
+0 value timestamp
+0 value id
+
+only forth also support-functions
+
+: (load) load ;
+
+: check-pnpid ( -- )
+ line_buffer .addr @
+ \ Search for filename
+ skip-space premature-end?
+ dup to filename
+ \ Search for end of filename
+ skip-to-space premature-end?
+ 0 over c! char+
+ \ Search for timestamp
+ skip-space premature-end?
+ dup to timestamp
+ skip-to-space premature-end?
+ 0 over c! char+
+ \ Search for ids
+ begin
+ skip-space premature-end?
+ dup to id
+ skip-to-space dup c@ >r
+ 0 over c! char+
+ id search-pnpid if
+ filename dup strlen 1 ['] (load) catch if
+ drop drop drop
+ ." Error loading " filename dup strlen type cr
+ then
+ r> drop exit
+ then
+ r> 0=
+ until
+;
+
+: load-pnp
+ 0 to end_of_file?
+ reset_line_reading
+ s" /boot/pnpid.conf" O_RDONLY fopen fd !
+ fd @ -1 <> if
+ begin
+ end_of_file? 0=
+ while
+ read_line
+ check-pnpid
+ repeat
+ fd @ fclose
+ then
+;
+
diff --git a/usr/src/boot/sys/boot/forth/screen.4th b/usr/src/boot/sys/boot/forth/screen.4th
new file mode 100644
index 0000000000..e0af82b3a8
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/screen.4th
@@ -0,0 +1,74 @@
+\ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
+\ Copyright (c) 2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-screen.4th
+
+\ emit Esc-[
+: escc ( -- ) 27 emit [char] [ emit ;
+
+\ Home cursor ( Esc-[H )
+: ho ( -- ) escc [char] H emit ;
+
+\ Clear from current position to end of display ( Esc-[J )
+: cld ( -- ) escc [char] J emit ;
+
+\ clear screen
+: clear ( -- ) ho cld ;
+
+\ move cursor to x rows, y cols (1-based coords) ( Esc-[%d;%dH )
+: at-xy ( x y -- ) escc .# [char] ; emit .# [char] H emit ;
+
+\ Set foreground color ( Esc-[3%dm )
+: fg ( x -- ) escc 3 .# .# [char] m emit ;
+
+\ Set background color ( Esc-[4%dm )
+: bg ( x -- ) escc 4 .# .# [char] m emit ;
+
+\ Mode end (clear attributes)
+: me ( -- ) escc [char] m emit ;
+
+\ Enable bold mode ( Esc-[1m )
+: b ( -- ) escc 1 .# [char] m emit ;
+
+\ Disable bold mode ( Esc-[22m )
+: -b ( -- ) escc 22 .# [char] m emit ;
+
+\ Enable inverse foreground/background mode ( Esc-[7m )
+: inv ( -- ) escc 7 .# [char] m emit ;
+
+\ Disable inverse foreground/background mode ( Esc-[27m )
+: -inv ( -- ) escc 27 .# [char] m emit ;
+
+\ Convert all occurrences of given character (c) in string (c-addr/u) to Esc
+: escc! ( c-addr/u c -- c-addr/u )
+ 2 pick 2 pick
+ begin dup 0> while
+ over c@ 3 pick = if over 27 swap c! then
+ 1- swap 1+ swap
+ repeat
+ 2drop drop
+;
diff --git a/usr/src/boot/sys/boot/forth/shortcuts.4th b/usr/src/boot/sys/boot/forth/shortcuts.4th
new file mode 100644
index 0000000000..33a1cf6789
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/shortcuts.4th
@@ -0,0 +1,50 @@
+\ Copyright (c) 2008-2011 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+\ FICL words intended to be used as shortcuts for carrying out common tasks or
+\ producing common results. Generally, words defined here are simply groupings
+\ of other custom words that pull from multiple libraries (for example, if you
+\ want to define a custom word that uses words defined in three different
+\ libraries, this is a good place to define such a word).
+\
+\ This script should be included after you have included any/all other
+\ libraries. This will prevent calling a word defined here before any required
+\ words have been defined.
+
+marker task-shortcuts.4th
+
+\ This "shortcut" word will not be used directly, but is defined here to
+\ offer the user a quick way to get back into the interactive PXE menu
+\ after they have escaped to the shell (perhaps by accident).
+\
+: menu ( -- )
+ clear \ Clear the screen (in screen.4th)
+ print_version \ print version string (bottom-right; see version.4th)
+ draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
+ draw-brand \ Draw FIS logo at top (in brand.4th)
+ menu-init \ Initialize menu and draw bounding box (in menu.4th)
+ menu-display \ Launch interactive menu (in menu.4th)
+;
diff --git a/usr/src/boot/sys/boot/forth/support.4th b/usr/src/boot/sys/boot/forth/support.4th
new file mode 100644
index 0000000000..2d2fe03426
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/support.4th
@@ -0,0 +1,1945 @@
+\ Copyright (c) 1999 Daniel C. Sobral <dcs@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+\ Loader.rc support functions:
+\
+\ initialize ( addr len -- ) as above, plus load_conf_files
+\ load_conf ( addr len -- ) load conf file given
+\ include_bootenv ( -- ) load bootenv.rc
+\ include_conf_files ( -- ) load all conf files in load_conf_files
+\ print_syntax_error ( -- ) print line and marker of where a syntax
+\ error was detected
+\ print_line ( -- ) print last line processed
+\ load_kernel ( -- ) load kernel
+\ load_modules ( -- ) load modules flagged
+\
+\ Exported structures:
+\
+\ string counted string structure
+\ cell .addr string address
+\ cell .len string length
+\ module module loading information structure
+\ cell module.flag should we load it?
+\ string module.name module's name
+\ string module.loadname name to be used in loading the module
+\ string module.type module's type (file | hash | rootfs)
+\ string module.hash module's sha1 hash
+\ string module.args flags to be passed during load
+\ string module.largs internal argument list
+\ string module.beforeload command to be executed before load
+\ string module.afterload command to be executed after load
+\ string module.loaderror command to be executed if load fails
+\ cell module.next list chain
+\
+\ Exported global variables;
+\
+\ string conf_files configuration files to be loaded
+\ cell modules_options pointer to first module information
+\ value verbose? indicates if user wants a verbose loading
+\ value any_conf_read? indicates if a conf file was succesfully read
+\
+\ Other exported words:
+\ note, strlen is internal
+\ strdup ( addr len -- addr' len) similar to strdup(3)
+\ strcat ( addr len addr' len' -- addr len+len' ) similar to strcat(3)
+\ s' ( | string' -- addr len | ) similar to s"
+\ rudimentary structure support
+
+\ Exception values
+
+1 constant ESYNTAX
+2 constant ENOMEM
+3 constant EFREE
+4 constant ESETERROR \ error setting environment variable
+5 constant EREAD \ error reading
+6 constant EOPEN
+7 constant EEXEC \ XXX never catched
+8 constant EBEFORELOAD
+9 constant EAFTERLOAD
+
+\ I/O constants
+
+0 constant SEEK_SET
+1 constant SEEK_CUR
+2 constant SEEK_END
+
+0 constant O_RDONLY
+1 constant O_WRONLY
+2 constant O_RDWR
+
+\ Crude structure support
+
+: structure:
+ create here 0 , ['] drop , 0
+ does> create here swap dup @ allot cell+ @ execute
+;
+: member: create dup , over , + does> cell+ @ + ;
+: ;structure swap ! ;
+: constructor! >body cell+ ! ;
+: constructor: over :noname ;
+: ;constructor postpone ; swap cell+ ! ; immediate
+: sizeof ' >body @ state @ if postpone literal then ; immediate
+: offsetof ' >body cell+ @ state @ if postpone literal then ; immediate
+: ptr 1 cells member: ;
+: int 1 cells member: ;
+
+\ String structure
+
+structure: string
+ ptr .addr
+ int .len
+ constructor:
+ 0 over .addr !
+ 0 swap .len !
+ ;constructor
+;structure
+
+
+\ Module options linked list
+
+structure: module
+ int module.flag
+ sizeof string member: module.name
+ sizeof string member: module.loadname
+ sizeof string member: module.type
+ sizeof string member: module.hash
+ sizeof string member: module.args
+ sizeof string member: module.largs
+ sizeof string member: module.beforeload
+ sizeof string member: module.afterload
+ sizeof string member: module.loaderror
+ ptr module.next
+;structure
+
+\ Internal loader structures (preloaded_file, kernel_module, file_metadata)
+\ must be in sync with the C struct in sys/boot/common/bootstrap.h
+structure: preloaded_file
+ ptr pf.name
+ ptr pf.type
+ ptr pf.args
+ ptr pf.metadata \ file_metadata
+ int pf.loader
+ int pf.addr
+ int pf.size
+ ptr pf.modules \ kernel_module
+ ptr pf.next \ preloaded_file
+;structure
+
+structure: kernel_module
+ ptr km.name
+ ptr km.args
+ ptr km.fp \ preloaded_file
+ ptr km.next \ kernel_module
+;structure
+
+structure: file_metadata
+ int md.size
+ 2 member: md.type \ this is not ANS Forth compatible (XXX)
+ ptr md.next \ file_metadata
+ 0 member: md.data \ variable size
+;structure
+
+\ end of structures
+
+\ Global variables
+
+string conf_files
+create module_options sizeof module.next allot 0 module_options !
+create last_module_option sizeof module.next allot 0 last_module_option !
+0 value verbose?
+
+\ Support string functions
+: strdup { addr len -- addr' len' }
+ len allocate if ENOMEM throw then
+ addr over len move len
+;
+
+: strcat { addr len addr' len' -- addr len+len' }
+ addr' addr len + len' move
+ addr len len' +
+;
+
+: strchr { addr len c -- addr' len' }
+ begin
+ len
+ while
+ addr c@ c = if addr len exit then
+ addr 1 + to addr
+ len 1 - to len
+ repeat
+ 0 0
+;
+
+: s' \ same as s", allows " in the string
+ [char] ' parse
+ state @ if postpone sliteral then
+; immediate
+
+: 2>r postpone >r postpone >r ; immediate
+: 2r> postpone r> postpone r> ; immediate
+: 2r@ postpone 2r> postpone 2dup postpone 2>r ; immediate
+
+: getenv? getenv -1 = if false else drop true then ;
+
+\ determine if a word appears in a string, case-insensitive
+: contains? ( addr1 len1 addr2 len2 -- 0 | -1 )
+ 2 pick 0= if 2drop 2drop true exit then
+ dup 0= if 2drop 2drop false exit then
+ begin
+ begin
+ swap dup c@ dup 32 = over 9 = or over 10 = or
+ over 13 = or over 44 = or swap drop
+ while 1+ swap 1- repeat
+ swap 2 pick 1- over <
+ while
+ 2over 2over drop over compare-insensitive 0= if
+ 2 pick over = if 2drop 2drop true exit then
+ 2 pick tuck - -rot + swap over c@ dup 32 =
+ over 9 = or over 10 = or over 13 = or over 44 = or
+ swap drop if 2drop 2drop true exit then
+ then begin
+ swap dup c@ dup 32 = over 9 = or over 10 = or
+ over 13 = or over 44 = or swap drop
+ if false else true then 2 pick 0> and
+ while 1+ swap 1- repeat
+ swap
+ repeat
+ 2drop 2drop false
+;
+
+: boot_serial? ( -- 0 | -1 )
+ s" console" getenv dup -1 <> if
+ 2dup
+ s" ttya" 2swap contains? ( addr len f )
+ -rot 2dup ( f addr len addr len )
+ s" ttyb" 2swap contains? ( f addr len f )
+ -rot 2dup ( f f addr len addr len )
+ s" ttyc" 2swap contains? ( f f addr len f )
+ -rot ( f f f addr len )
+ s" ttyd" 2swap contains? ( f f addr len f )
+ or or or
+ else drop false then
+ s" boot_serial" getenv dup -1 <> if
+ swap drop 0>
+ else drop false then
+ or \ console contains tty ( or ) boot_serial
+ s" boot_multicons" getenv dup -1 <> if
+ swap drop 0>
+ else drop false then
+ or \ previous boolean ( or ) boot_multicons
+;
+
+\ Private definitions
+
+vocabulary support-functions
+only forth also support-functions definitions
+
+\ Some control characters constants
+
+7 constant bell
+8 constant backspace
+9 constant tab
+10 constant lf
+13 constant <cr>
+
+\ Read buffer size
+
+80 constant read_buffer_size
+
+\ Standard suffixes
+
+: load_module_suffix s" _load" ;
+: module_loadname_suffix s" _name" ;
+: module_type_suffix s" _type" ;
+: module_hash_suffix s" _hash" ;
+: module_args_suffix s" _flags" ;
+: module_beforeload_suffix s" _before" ;
+: module_afterload_suffix s" _after" ;
+: module_loaderror_suffix s" _error" ;
+
+\ Support operators
+
+: >= < 0= ;
+: <= > 0= ;
+
+\ Assorted support functions
+
+: free-memory free if EFREE throw then ;
+
+: strget { var -- addr len } var .addr @ var .len @ ;
+
+\ assign addr len to variable.
+: strset { addr len var -- } addr var .addr ! len var .len ! ;
+
+\ free memory and reset fields
+: strfree { var -- } var .addr @ ?dup if free-memory 0 0 var strset then ;
+
+\ free old content, make a copy of the string and assign to variable
+: string= { addr len var -- } var strfree addr len strdup var strset ;
+
+: strtype ( str -- ) strget type ;
+
+\ assign a reference to what is on the stack
+: strref { addr len var -- addr len }
+ addr var .addr ! len var .len ! addr len
+;
+
+\ unquote a string
+: unquote ( addr len -- addr len )
+ over c@ [char] " = if 2 chars - swap char+ swap then
+;
+
+\ Assignment data temporary storage
+
+string name_buffer
+string value_buffer
+
+\ Line by line file reading functions
+\
+\ exported:
+\ line_buffer
+\ end_of_file?
+\ fd
+\ read_line
+\ reset_line_reading
+
+vocabulary line-reading
+also line-reading definitions
+
+\ File data temporary storage
+
+string read_buffer
+0 value read_buffer_ptr
+
+\ File's line reading function
+
+get-current ( -- wid ) previous definitions
+
+string line_buffer
+0 value end_of_file?
+variable fd
+
+>search ( wid -- ) definitions
+
+: skip_newlines
+ begin
+ read_buffer .len @ read_buffer_ptr >
+ while
+ read_buffer .addr @ read_buffer_ptr + c@ lf = if
+ read_buffer_ptr char+ to read_buffer_ptr
+ else
+ exit
+ then
+ repeat
+;
+
+: scan_buffer ( -- addr len )
+ read_buffer_ptr >r
+ begin
+ read_buffer .len @ r@ >
+ while
+ read_buffer .addr @ r@ + c@ lf = if
+ read_buffer .addr @ read_buffer_ptr + ( -- addr )
+ r@ read_buffer_ptr - ( -- len )
+ r> to read_buffer_ptr
+ exit
+ then
+ r> char+ >r
+ repeat
+ read_buffer .addr @ read_buffer_ptr + ( -- addr )
+ r@ read_buffer_ptr - ( -- len )
+ r> to read_buffer_ptr
+;
+
+: line_buffer_resize ( len -- len )
+ >r
+ line_buffer .len @ if
+ line_buffer .addr @
+ line_buffer .len @ r@ +
+ resize if ENOMEM throw then
+ else
+ r@ allocate if ENOMEM throw then
+ then
+ line_buffer .addr !
+ r>
+;
+
+: append_to_line_buffer ( addr len -- )
+ line_buffer strget
+ 2swap strcat
+ line_buffer .len !
+ drop
+;
+
+: read_from_buffer
+ scan_buffer ( -- addr len )
+ line_buffer_resize ( len -- len )
+ append_to_line_buffer ( addr len -- )
+;
+
+: refill_required?
+ read_buffer .len @ read_buffer_ptr =
+ end_of_file? 0= and
+;
+
+: refill_buffer
+ 0 to read_buffer_ptr
+ read_buffer .addr @ 0= if
+ read_buffer_size allocate if ENOMEM throw then
+ read_buffer .addr !
+ then
+ fd @ read_buffer .addr @ read_buffer_size fread
+ dup -1 = if EREAD throw then
+ dup 0= if true to end_of_file? then
+ read_buffer .len !
+;
+
+get-current ( -- wid ) previous definitions >search ( wid -- )
+
+: reset_line_reading
+ 0 to read_buffer_ptr
+;
+
+: read_line
+ line_buffer strfree
+ skip_newlines
+ begin
+ read_from_buffer
+ refill_required?
+ while
+ refill_buffer
+ repeat
+;
+
+only forth also support-functions definitions
+
+\ Conf file line parser:
+\ <line> ::= <spaces><name><spaces>'='<spaces><value><spaces>[<comment>] |
+\ <spaces>[<comment>]
+\ <name> ::= <letter>{<letter>|<digit>|'_'|'-'}
+\ <vname> ::= <letter>{<letter>|<digit>|'_'|'-'|','}
+\ <value> ::= '"'{<character_set>|'\'<anything>}'"' | <vname>
+\ <character_set> ::= ASCII 32 to 126, except '\' and '"'
+\ <comment> ::= '#'{<anything>}
+\
+\ bootenv line parser:
+\ <line> ::= <spaces>setprop<spaces><name><spaces><value><spaces>[<comment>] |
+\ <spaces>[<comment>]
+\
+\ exported:
+\ line_pointer
+\ process_conf
+\ process_conf
+
+0 value line_pointer
+
+vocabulary file-processing
+also file-processing definitions
+
+\ parser functions
+\
+\ exported:
+\ get_assignment
+\ get_prop
+
+vocabulary parser
+also parser definitions
+
+0 value parsing_function
+0 value end_of_line
+
+: end_of_line? line_pointer end_of_line = ;
+
+\ classifiers for various character classes in the input line
+
+: letter?
+ line_pointer c@ >r
+ r@ [char] A >=
+ r@ [char] Z <= and
+ r@ [char] a >=
+ r> [char] z <= and
+ or
+;
+
+: digit?
+ line_pointer c@ >r
+ r@ [char] - =
+ r@ [char] 0 >=
+ r> [char] 9 <= and
+ or
+;
+
+: "quote? line_pointer c@ [char] " = ;
+
+: 'quote? line_pointer c@ [char] ' = ;
+
+: assignment_sign? line_pointer c@ [char] = = ;
+
+: comment? line_pointer c@ [char] # = ;
+
+: space? line_pointer c@ bl = line_pointer c@ tab = or ;
+
+: backslash? line_pointer c@ [char] \ = ;
+
+: underscore? line_pointer c@ [char] _ = ;
+
+: dot? line_pointer c@ [char] . = ;
+
+: dash? line_pointer c@ [char] - = ;
+
+: comma? line_pointer c@ [char] , = ;
+
+\ manipulation of input line
+: skip_character line_pointer char+ to line_pointer ;
+
+: skip_to_end_of_line end_of_line to line_pointer ;
+
+: eat_space
+ begin
+ end_of_line? if 0 else space? then
+ while
+ skip_character
+ repeat
+;
+
+: parse_name ( -- addr len )
+ line_pointer
+ begin
+ end_of_line? if 0 else
+ letter? digit? underscore? dot? dash?
+ or or or or
+ then
+ while
+ skip_character
+ repeat
+ line_pointer over -
+ strdup
+;
+
+: parse_value ( -- addr len )
+ line_pointer
+ begin
+ end_of_line? if 0 else
+ letter? digit? underscore? dot? comma? dash?
+ or or or or or
+ then
+ while
+ skip_character
+ repeat
+ line_pointer over -
+ strdup
+;
+
+: remove_backslashes { addr len | addr' len' -- addr' len' }
+ len allocate if ENOMEM throw then
+ to addr'
+ addr >r
+ begin
+ addr c@ [char] \ <> if
+ addr c@ addr' len' + c!
+ len' char+ to len'
+ then
+ addr char+ to addr
+ r@ len + addr =
+ until
+ r> drop
+ addr' len'
+;
+
+: parse_quote ( xt -- addr len )
+ >r ( R: xt )
+ line_pointer
+ skip_character
+ end_of_line? if ESYNTAX throw then
+ begin
+ r@ execute 0=
+ while
+ backslash? if
+ skip_character
+ end_of_line? if ESYNTAX throw then
+ then
+ skip_character
+ end_of_line? if ESYNTAX throw then
+ repeat
+ r> drop
+ skip_character
+ line_pointer over -
+ remove_backslashes
+;
+
+: read_name
+ parse_name ( -- addr len )
+ name_buffer strset
+;
+
+: read_value
+ "quote? if
+ ['] "quote? parse_quote ( -- addr len )
+ else
+ 'quote? if
+ ['] 'quote? parse_quote ( -- addr len )
+ else
+ parse_value ( -- addr len )
+ then
+ then
+ value_buffer strset
+;
+
+: comment
+ skip_to_end_of_line
+;
+
+: white_space_4
+ eat_space
+ comment? if ['] comment to parsing_function exit then
+ end_of_line? 0= if ESYNTAX throw then
+;
+
+: variable_value
+ read_value
+ ['] white_space_4 to parsing_function
+;
+
+: white_space_3
+ eat_space
+ letter? digit? "quote? 'quote? or or or if
+ ['] variable_value to parsing_function exit
+ then
+ ESYNTAX throw
+;
+
+: assignment_sign
+ skip_character
+ ['] white_space_3 to parsing_function
+;
+
+: white_space_2
+ eat_space
+ assignment_sign? if ['] assignment_sign to parsing_function exit then
+ ESYNTAX throw
+;
+
+: variable_name
+ read_name
+ ['] white_space_2 to parsing_function
+;
+
+: white_space_1
+ eat_space
+ letter? if ['] variable_name to parsing_function exit then
+ comment? if ['] comment to parsing_function exit then
+ end_of_line? 0= if ESYNTAX throw then
+;
+
+: prop_name
+ eat_space
+ read_name
+ ['] white_space_3 to parsing_function
+;
+
+: get_prop_cmd
+ eat_space
+ s" setprop" line_pointer over compare 0=
+ if line_pointer 7 + to line_pointer
+ ['] prop_name to parsing_function exit
+ then
+ comment? if ['] comment to parsing_function exit then
+ end_of_line? 0= if ESYNTAX throw then
+;
+
+get-current ( -- wid ) previous definitions >search ( wid -- )
+
+: get_assignment
+ line_buffer strget + to end_of_line
+ line_buffer .addr @ to line_pointer
+ ['] white_space_1 to parsing_function
+ begin
+ end_of_line? 0=
+ while
+ parsing_function execute
+ repeat
+ parsing_function ['] comment =
+ parsing_function ['] white_space_1 =
+ parsing_function ['] white_space_4 =
+ or or 0= if ESYNTAX throw then
+;
+
+: get_prop
+ line_buffer strget + to end_of_line
+ line_buffer .addr @ to line_pointer
+ ['] get_prop_cmd to parsing_function
+ begin
+ end_of_line? 0=
+ while
+ parsing_function execute
+ repeat
+ parsing_function ['] comment =
+ parsing_function ['] get_prop_cmd =
+ parsing_function ['] white_space_4 =
+ or or 0= if ESYNTAX throw then
+;
+
+only forth also support-functions also file-processing definitions
+
+\ Process line
+
+: assignment_type? ( addr len -- flag )
+ name_buffer strget
+ compare 0=
+;
+
+: suffix_type? ( addr len -- flag )
+ name_buffer .len @ over <= if 2drop false exit then
+ name_buffer .len @ over - name_buffer .addr @ +
+ over compare 0=
+;
+
+: loader_conf_files? s" loader_conf_files" assignment_type? ;
+
+: verbose_flag? s" verbose_loading" assignment_type? ;
+
+: execute? s" exec" assignment_type? ;
+
+: module_load? load_module_suffix suffix_type? ;
+
+: module_loadname? module_loadname_suffix suffix_type? ;
+
+: module_type? module_type_suffix suffix_type? ;
+
+: module_hash? module_hash_suffix suffix_type? ;
+
+: module_args? module_args_suffix suffix_type? ;
+
+: module_beforeload? module_beforeload_suffix suffix_type? ;
+
+: module_afterload? module_afterload_suffix suffix_type? ;
+
+: module_loaderror? module_loaderror_suffix suffix_type? ;
+
+\ build a 'set' statement and execute it
+: set_environment_variable
+ name_buffer .len @ value_buffer .len @ + 5 chars + \ size of result string
+ allocate if ENOMEM throw then
+ dup 0 \ start with an empty string and append the pieces
+ s" set " strcat
+ name_buffer strget strcat
+ s" =" strcat
+ value_buffer strget strcat
+ ['] evaluate catch if
+ 2drop free drop
+ ESETERROR throw
+ else
+ free-memory
+ then
+;
+
+: set_conf_files
+ set_environment_variable
+ s" loader_conf_files" getenv conf_files string=
+;
+
+: append_to_module_options_list ( addr -- )
+ module_options @ 0= if
+ dup module_options !
+ last_module_option !
+ else
+ dup last_module_option @ module.next !
+ last_module_option !
+ then
+;
+
+: set_module_name { addr -- } \ check leaks
+ name_buffer strget addr module.name string=
+;
+
+: yes_value?
+ value_buffer strget unquote
+ s" yes" compare-insensitive 0=
+;
+
+: find_module_option ( -- addr | 0 ) \ return ptr to entry matching name_buffer
+ module_options @
+ begin
+ dup
+ while
+ dup module.name strget
+ name_buffer strget
+ compare 0= if exit then
+ module.next @
+ repeat
+;
+
+: new_module_option ( -- addr )
+ sizeof module allocate if ENOMEM throw then
+ dup sizeof module erase
+ dup append_to_module_options_list
+ dup set_module_name
+;
+
+: get_module_option ( -- addr )
+ find_module_option
+ ?dup 0= if new_module_option then
+;
+
+: set_module_flag
+ name_buffer .len @ load_module_suffix nip - name_buffer .len !
+ yes_value? get_module_option module.flag !
+;
+
+: set_module_args
+ name_buffer .len @ module_args_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.args string=
+;
+
+: set_module_loadname
+ name_buffer .len @ module_loadname_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.loadname string=
+;
+
+: set_module_type
+ name_buffer .len @ module_type_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.type string=
+;
+
+: set_module_hash
+ name_buffer .len @ module_hash_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.hash string=
+;
+
+: set_module_beforeload
+ name_buffer .len @ module_beforeload_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.beforeload string=
+;
+
+: set_module_afterload
+ name_buffer .len @ module_afterload_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.afterload string=
+;
+
+: set_module_loaderror
+ name_buffer .len @ module_loaderror_suffix nip - name_buffer .len !
+ value_buffer strget unquote
+ get_module_option module.loaderror string=
+;
+
+: set_verbose
+ yes_value? to verbose?
+;
+
+: execute_command
+ value_buffer strget unquote
+ ['] evaluate catch if EEXEC throw then
+;
+
+: process_assignment
+ name_buffer .len @ 0= if exit then
+ loader_conf_files? if set_conf_files exit then
+ verbose_flag? if set_verbose exit then
+ execute? if execute_command exit then
+ module_load? if set_module_flag exit then
+ module_loadname? if set_module_loadname exit then
+ module_type? if set_module_type exit then
+ module_hash? if set_module_hash exit then
+ module_args? if set_module_args exit then
+ module_beforeload? if set_module_beforeload exit then
+ module_afterload? if set_module_afterload exit then
+ module_loaderror? if set_module_loaderror exit then
+ set_environment_variable
+;
+
+\ free_buffer ( -- )
+\
+\ Free some pointers if needed. The code then tests for errors
+\ in freeing, and throws an exception if needed. If a pointer is
+\ not allocated, it's value (0) is used as flag.
+
+: free_buffers
+ name_buffer strfree
+ value_buffer strfree
+;
+
+\ Higher level file processing
+
+get-current ( -- wid ) previous definitions >search ( wid -- )
+
+: process_bootenv
+ begin
+ end_of_file? 0=
+ while
+ free_buffers
+ read_line
+ get_prop
+ ['] process_assignment catch
+ ['] free_buffers catch
+ swap throw throw
+ repeat
+;
+
+: process_conf
+ begin
+ end_of_file? 0=
+ while
+ free_buffers
+ read_line
+ get_assignment
+ ['] process_assignment catch
+ ['] free_buffers catch
+ swap throw throw
+ repeat
+;
+
+: peek_file ( addr len -- )
+ 0 to end_of_file?
+ reset_line_reading
+ O_RDONLY fopen fd !
+ fd @ -1 = if EOPEN throw then
+ free_buffers
+ read_line
+ get_assignment
+ ['] process_assignment catch
+ ['] free_buffers catch
+ fd @ fclose
+ swap throw throw
+;
+
+only forth also support-functions definitions
+
+\ Interface to loading conf files
+
+: load_conf ( addr len -- )
+ 0 to end_of_file?
+ reset_line_reading
+ O_RDONLY fopen fd !
+ fd @ -1 = if EOPEN throw then
+ ['] process_conf catch
+ fd @ fclose
+ throw
+;
+
+: print_line line_buffer strtype cr ;
+
+: print_syntax_error
+ line_buffer strtype cr
+ line_buffer .addr @
+ begin
+ line_pointer over <>
+ while
+ bl emit char+
+ repeat
+ drop
+ ." ^" cr
+;
+
+: load_bootenv ( addr len -- )
+ 0 to end_of_file?
+ reset_line_reading
+ O_RDONLY fopen fd !
+ fd @ -1 = if EOPEN throw then
+ ['] process_bootenv catch
+ fd @ fclose
+ throw
+;
+
+\ Debugging support functions
+
+only forth definitions also support-functions
+
+: test-file
+ ['] load_conf catch dup .
+ ESYNTAX = if cr print_syntax_error then
+;
+
+\ find a module name, leave addr on the stack (0 if not found)
+: find-module ( <module> -- ptr | 0 )
+ bl parse ( addr len )
+ module_options @ >r ( store current pointer )
+ begin
+ r@
+ while
+ 2dup ( addr len addr len )
+ r@ module.name strget
+ compare 0= if drop drop r> exit then ( found it )
+ r> module.next @ >r
+ repeat
+ type ." was not found" cr r>
+;
+
+: show-nonempty ( addr len mod -- )
+ strget dup verbose? or if
+ 2swap type type cr
+ else
+ drop drop drop drop
+ then ;
+
+: show-one-module { addr -- addr }
+ ." Name: " addr module.name strtype cr
+ s" Path: " addr module.loadname show-nonempty
+ s" Type: " addr module.type show-nonempty
+ s" Hash: " addr module.hash show-nonempty
+ s" Flags: " addr module.args show-nonempty
+ s" Before load: " addr module.beforeload show-nonempty
+ s" After load: " addr module.afterload show-nonempty
+ s" Error: " addr module.loaderror show-nonempty
+ ." Status: " addr module.flag @ if ." Load" else ." Don't load" then cr
+ cr
+ addr
+;
+
+: show-module-options
+ module_options @
+ begin
+ ?dup
+ while
+ show-one-module
+ module.next @
+ repeat
+;
+
+: free-one-module { addr -- addr }
+ addr module.name strfree
+ addr module.loadname strfree
+ addr module.type strfree
+ addr module.hash strfree
+ addr module.args strfree
+ addr module.largs strfree
+ addr module.beforeload strfree
+ addr module.afterload strfree
+ addr module.loaderror strfree
+ addr
+;
+
+: free-module-options
+ module_options @
+ begin
+ ?dup
+ while
+ free-one-module
+ dup module.next @
+ swap free-memory
+ repeat
+ 0 module_options !
+ 0 last_module_option !
+;
+
+only forth also support-functions definitions
+
+\ Variables used for processing multiple conf files
+
+string current_file_name_ref \ used to print the file name
+
+\ Indicates if any conf file was succesfully read
+
+0 value any_conf_read?
+
+\ loader_conf_files processing support functions
+
+\ true if string in addr1 is smaller than in addr2
+: compar ( addr1 addr2 -- flag )
+ swap ( addr2 addr1 )
+ dup cell+ ( addr2 addr1 addr )
+ swap @ ( addr2 addr len )
+ rot ( addr len addr2 )
+ dup cell+ ( addr len addr2 addr' )
+ swap @ ( addr len addr' len' )
+ compare -1 =
+;
+
+\ insertion sort algorithm. we dont expect large amounts of data to be
+\ sorted, so insert should be ok. compar needs to implement < operator.
+: insert ( start end -- start )
+ dup @ >r ( r: v ) \ v = a[i]
+ begin
+ 2dup < \ j>0
+ while
+ r@ over cell- @ compar \ a[j-1] > v
+ while
+ cell- \ j--
+ dup @ over cell+ ! \ a[j] = a[j-1]
+ repeat then
+ r> swap ! \ a[j] = v
+;
+
+: sort ( array len -- )
+ 1 ?do dup i cells + insert loop drop
+;
+
+: opendir
+ s" /boot/conf.d" fopendir if fd ! else
+ EOPEN throw
+ then
+;
+
+: readdir ( addr len flag | flag )
+ fd @ freaddir
+;
+
+: closedir
+ fd @ fclosedir
+;
+
+: entries ( -- n ) \ count directory entries
+ ['] opendir catch ( n array )
+ throw
+
+ 0 ( i )
+ begin \ count the entries
+ readdir ( i addr len flag | i flag )
+ dup -1 = if
+ -ROT 2drop
+ swap 1+ swap
+ then
+ 0=
+ until
+ closedir
+;
+
+\ built-in prefix directory name; it must end with /, so we don't
+\ need to check and insert it.
+: make_cstring ( addr len -- addr' )
+ dup ( addr len len )
+ s" /boot/conf.d/" ( addr len len addr' len' )
+ rot ( addr len addr' len' len )
+ over + ( addr len addr' len' total ) \ space for prefix+str
+ dup cell+ 1+ \ 1+ for '\0'
+ allocate if
+ -1 abort" malloc failed"
+ then
+ ( addr len addr' len' total taddr )
+ dup rot ( addr len addr' len' taddr taddr total )
+ swap ! ( addr len addr' len' taddr ) \ store length
+ dup >r \ save reference
+ cell+ \ point to string area
+ 2dup 2>r ( addr len addr' len' taddr' ) ( R: taddr len' taddr' )
+ swap move ( addr len )
+ 2r> + ( addr len taddr' ) ( R: taddr )
+ swap 1+ move \ 1+ for '\0'
+ r> ( taddr )
+;
+
+: scan_conf_dir ( -- addr len -1 | 0 )
+ s" currdev" getenv dup -1 <> if
+ s" pxe0:" compare 0= if 0 exit then \ readdir does not work on tftp
+ else
+ drop
+ then
+
+ ['] entries catch if
+ 0 exit
+ then
+ dup 0= if exit then \ nothing to do
+
+ dup cells allocate ( n array flag ) \ allocate array
+ if 0 exit then
+ ['] opendir catch if ( n array )
+ free drop drop
+ 0 exit
+ then
+ over 0 do
+ readdir ( n array addr len flag | n array flag )
+ 0= if -1 abort" unexpected readdir error" then \ shouldnt happen
+ ( n array addr len )
+ \ we have relative name, make it absolute and convert to counted string
+ make_cstring ( n array addr )
+ over I cells + ! ( n array )
+ loop
+ closedir
+ 2dup swap sort
+ \ we have now array of strings with directory entry names.
+ \ calculate size of concatenated string
+ over 0 swap 0 do ( n array 0 )
+ over I cells + @ ( n array total array[I] )
+ @ + 1+ ( n array total' )
+ loop
+ dup allocate if drop free 2drop 0 exit then
+ ( n array len addr )
+ \ now concatenate all entries.
+ 2swap ( len addr n array )
+ over 0 swap 0 do ( len addr n array 0 )
+ over I cells + @ ( len addr n array total array[I] )
+ dup @ swap cell+ ( len addr n array total len addr' )
+ over ( len addr n array total len addr' len )
+ 6 pick ( len addr n array total len addr' len addr )
+ 4 pick + ( len addr n array total len addr' len addr+total )
+ swap move + ( len addr n array total+len )
+ 3 pick ( len addr n array total addr )
+ over + bl swap c! 1+ ( len addr n array total )
+ over I cells + @ free drop \ free array[I]
+ loop
+ drop free drop drop ( len addr )
+ swap ( addr len )
+ -1
+;
+
+: get_conf_files ( -- addr len ) \ put addr/len on stack, reset var
+ \ ." -- starting on <" conf_files strtype ." >" cr \ debugging
+ scan_conf_dir if \ concatenate with conf_files
+ ( addr len )
+ dup conf_files .len @ + 2 + allocate abort" out of memory" ( addr len addr' )
+ dup conf_files strget ( addr len addr' caddr clen )
+ rot swap move ( addr len addr' )
+ \ add space
+ dup conf_files .len @ + ( addr len addr' addr'+clen )
+ dup bl swap c! 1+ ( addr len addr' addr'' )
+ 3 pick swap ( addr len addr' addr addr'' )
+ 3 pick move ( addr len addr' )
+ rot ( len addr' addr )
+ free drop swap ( addr' len )
+ conf_files .len @ + 1+ ( addr len )
+ conf_files strfree
+ else
+ conf_files strget 0 0 conf_files strset
+ then
+;
+
+: skip_leading_spaces { addr len pos -- addr len pos' }
+ begin
+ pos len = if 0 else addr pos + c@ bl = then
+ while
+ pos char+ to pos
+ repeat
+ addr len pos
+;
+
+\ return the file name at pos, or free the string if nothing left
+: get_file_name { addr len pos -- addr len pos' addr' len' || 0 }
+ pos len = if
+ addr free abort" Fatal error freeing memory"
+ 0 exit
+ then
+ pos >r
+ begin
+ \ stay in the loop until have chars and they are not blank
+ pos len = if 0 else addr pos + c@ bl <> then
+ while
+ pos char+ to pos
+ repeat
+ addr len pos addr r@ + pos r> -
+;
+
+: get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 )
+ skip_leading_spaces
+ get_file_name
+;
+
+: print_current_file
+ current_file_name_ref strtype
+;
+
+: process_conf_errors
+ dup 0= if true to any_conf_read? drop exit then
+ >r 2drop r>
+ dup ESYNTAX = if
+ ." Warning: syntax error on file " print_current_file cr
+ print_syntax_error drop exit
+ then
+ dup ESETERROR = if
+ ." Warning: bad definition on file " print_current_file cr
+ print_line drop exit
+ then
+ dup EREAD = if
+ ." Warning: error reading file " print_current_file cr drop exit
+ then
+ dup EOPEN = if
+ verbose? if ." Warning: unable to open file " print_current_file cr then
+ drop exit
+ then
+ dup EFREE = abort" Fatal error freeing memory"
+ dup ENOMEM = abort" Out of memory"
+ throw \ Unknown error -- pass ahead
+;
+
+\ Process loader_conf_files recursively
+\ Interface to loader_conf_files processing
+
+: include_bootenv
+ s" /boot/solaris/bootenv.rc"
+ ['] load_bootenv catch
+ dup 0= if drop exit then
+ >r 2drop r>
+ dup ESYNTAX = if
+ ." Warning: syntax error on /boot/solaris/bootenv.rc" cr drop exit
+ then
+ dup EREAD = if
+ ." Warning: error reading /boot/solaris/bootenv.rc" cr drop exit
+ then
+ dup EOPEN = if
+ verbose? if ." Warning: unable to open /boot/solaris/bootenv.rc" cr then
+ drop exit
+ then
+ dup EFREE = abort" Fatal error freeing memory"
+ dup ENOMEM = abort" Out of memory"
+ throw \ Unknown error -- pass ahead
+;
+
+: include_transient
+ s" /boot/transient.conf" ['] load_conf catch
+ dup 0= if drop exit then \ no error
+ >r 2drop r>
+ dup ESYNTAX = if
+ ." Warning: syntax error on file /boot/transient.conf" cr
+ drop exit
+ then
+ dup ESETERROR = if
+ ." Warning: bad definition on file /boot/transient.conf" cr
+ drop exit
+ then
+ dup EREAD = if
+ ." Warning: error reading file /boot/transient.conf" cr drop exit
+ then
+ dup EOPEN = if
+ verbose? if ." Warning: unable to open file /boot/transient.conf" cr then
+ drop exit
+ then
+ dup EFREE = abort" Fatal error freeing memory"
+ dup ENOMEM = abort" Out of memory"
+ throw \ Unknown error -- pass ahead
+;
+
+: include_conf_files
+ get_conf_files 0 ( addr len offset )
+ begin
+ get_next_file ?dup ( addr len 1 | 0 )
+ while
+ current_file_name_ref strref
+ ['] load_conf catch
+ process_conf_errors
+ conf_files .addr @ if recurse then
+ repeat
+;
+
+\ Module loading functions
+
+\ concat two strings by allocating space
+: concat { a1 l1 a2 l2 -- a' l' }
+ l1 l2 + allocate if ENOMEM throw then
+ 0 a1 l1 strcat
+ a2 l2 strcat
+;
+
+\ build module argument list as: "hash= name= module.args"
+\ if type is hash, name= will have module name without .hash suffix
+\ will free old largs and set new.
+
+: build_largs { addr -- addr }
+ addr module.largs strfree
+ addr module.hash .len @
+ if ( set hash= )
+ s" hash=" addr module.hash strget concat
+ addr module.largs strset \ largs = "hash=" + module.hash
+ then
+
+ addr module.type strget s" hash" compare 0=
+ if ( module.type == "hash" )
+ addr module.largs strget s" name=" concat
+
+ addr module.loadname .len @
+ if ( module.loadname != NULL )
+ addr module.loadname strget concat
+ else
+ addr module.name strget concat
+ then
+
+ addr module.largs strfree
+ addr module.largs strset \ largs = largs + name
+
+ \ last thing to do is to strip off ".hash" suffix
+ addr module.largs strget [char] . strchr
+ dup if ( strchr module.largs '.' )
+ s" .hash" compare 0=
+ if ( it is ".hash" )
+ addr module.largs .len @ 5 -
+ addr module.largs .len !
+ then
+ else
+ 2drop
+ then
+ then
+ \ and now add up the module.args
+ addr module.largs strget s" " concat
+ addr module.args strget concat
+ addr module.largs strfree
+ addr module.largs strset
+ addr
+;
+
+: load_parameters { addr -- addr addrN lenN ... addr1 len1 N }
+ addr build_largs
+ addr module.largs strget
+ addr module.loadname .len @ if
+ addr module.loadname strget
+ else
+ addr module.name strget
+ then
+ addr module.type .len @ if
+ addr module.type strget
+ s" -t "
+ 4 ( -t type name flags )
+ else
+ 2 ( name flags )
+ then
+;
+
+: before_load ( addr -- addr )
+ dup module.beforeload .len @ if
+ dup module.beforeload strget
+ ['] evaluate catch if EBEFORELOAD throw then
+ then
+;
+
+: after_load ( addr -- addr )
+ dup module.afterload .len @ if
+ dup module.afterload strget
+ ['] evaluate catch if EAFTERLOAD throw then
+ then
+;
+
+: load_error ( addr -- addr )
+ dup module.loaderror .len @ if
+ dup module.loaderror strget
+ evaluate \ This we do not intercept so it can throw errors
+ then
+;
+
+: pre_load_message ( addr -- addr )
+ verbose? if
+ dup module.name strtype
+ ." ..."
+ then
+;
+
+: load_error_message verbose? if ." failed!" cr then ;
+
+: load_succesful_message verbose? if ." ok" cr then ;
+
+: load_module
+ load_parameters load
+;
+
+: process_module ( addr -- addr )
+ pre_load_message
+ before_load
+ begin
+ ['] load_module catch if
+ dup module.loaderror .len @ if
+ load_error \ Command should return a flag!
+ else
+ load_error_message true \ Do not retry
+ then
+ else
+ after_load
+ load_succesful_message true \ Succesful, do not retry
+ then
+ until
+;
+
+: process_module_errors ( addr ior -- )
+ dup EBEFORELOAD = if
+ drop
+ ." Module "
+ dup module.name strtype
+ dup module.loadname .len @ if
+ ." (" dup module.loadname strtype ." )"
+ then
+ cr
+ ." Error executing "
+ dup module.beforeload strtype cr \ XXX there was a typo here
+ abort
+ then
+
+ dup EAFTERLOAD = if
+ drop
+ ." Module "
+ dup module.name .addr @ over module.name .len @ type
+ dup module.loadname .len @ if
+ ." (" dup module.loadname strtype ." )"
+ then
+ cr
+ ." Error executing "
+ dup module.afterload strtype cr
+ abort
+ then
+
+ throw \ Don't know what it is all about -- pass ahead
+;
+
+\ Module loading interface
+
+\ scan the list of modules, load enabled ones.
+: load_modules ( -- ) ( throws: abort & user-defined )
+ module_options @ ( list_head )
+ begin
+ ?dup
+ while
+ dup module.flag @ if
+ ['] process_module catch
+ process_module_errors
+ then
+ module.next @
+ repeat
+;
+
+\ h00h00 magic used to try loading either a kernel with a given name,
+\ or a kernel with the default name in a directory of a given name
+\ (the pain!)
+
+: bootpath s" /platform/" ;
+: modulepath s" module_path" ;
+
+\ Functions used to save and restore module_path's value.
+: saveenv ( addr len | -1 -- addr' len | 0 -1 )
+ dup -1 = if 0 swap exit then
+ strdup
+;
+: freeenv ( addr len | 0 -1 )
+ -1 = if drop else free abort" Freeing error" then
+;
+: restoreenv ( addr len | 0 -1 -- )
+ dup -1 = if ( it wasn't set )
+ 2drop
+ modulepath unsetenv
+ else
+ over >r
+ modulepath setenv
+ r> free abort" Freeing error"
+ then
+;
+
+: clip_args \ Drop second string if only one argument is passed
+ 1 = if
+ 2swap 2drop
+ 1
+ else
+ 2
+ then
+;
+
+also builtins
+
+\ Parse filename from a semicolon-separated list
+
+\ replacement, not working yet
+: newparse-; { addr len | a1 -- a' len-x addr x }
+ addr len [char] ; strchr dup if ( a1 len1 )
+ swap to a1 ( store address )
+ 1 - a1 @ 1 + swap ( remove match )
+ addr a1 addr -
+ else
+ 0 0 addr len
+ then
+;
+
+: parse-; ( addr len -- addr' len-x addr x )
+ over 0 2swap ( addr 0 addr len )
+ begin
+ dup 0 <> ( addr 0 addr len )
+ while
+ over c@ [char] ; <> ( addr 0 addr len flag )
+ while
+ 1- swap 1+ swap
+ 2swap 1+ 2swap
+ repeat then
+ dup 0 <> if
+ 1- swap 1+ swap
+ then
+ 2swap
+;
+
+\ Try loading one of multiple kernels specified
+
+: try_multiple_kernels ( addr len addr' len' args -- flag )
+ >r
+ begin
+ parse-; 2>r
+ 2over 2r>
+ r@ clip_args
+ s" DEBUG" getenv? if
+ s" echo Module_path: ${module_path}" evaluate
+ ." Kernel : " >r 2dup type r> cr
+ dup 2 = if ." Flags : " >r 2over type r> cr then
+ then
+ \ if it's xen, the xen kernel is loaded, unix needs to be loaded as module
+ s" xen_kernel" getenv -1 = if
+ 1 load \ normal kernel
+ else
+ drop
+ >r s" kernel" s" -t " r> 2 + 1 load
+ then
+ while
+ dup 0=
+ until
+ 1 >r \ Failure
+ else
+ 0 >r \ Success
+ then
+ 2drop 2drop
+ r>
+ r> drop
+;
+
+\ Try to load a kernel; the kernel name is taken from one of
+\ the following lists, as ordered:
+\
+\ 1. The "bootfile" environment variable
+\ 2. The "kernel" environment variable
+\
+\ Flags are passed, if available. If not, dummy values must be given.
+\
+\ The kernel gets loaded from the current module_path.
+
+: load_a_kernel ( flags len 1 | x x 0 -- flag )
+ local args
+ 2local flags
+ 0 0 2local kernel
+ end-locals
+
+ \ Check if a default kernel name exists at all, exits if not
+ s" bootfile" getenv dup -1 <> if
+ to kernel
+ flags kernel args 1+ try_multiple_kernels
+ dup 0= if exit then
+ then
+ drop
+
+ s" kernel" getenv dup -1 <> if
+ to kernel
+ else
+ drop
+ 1 exit \ Failure
+ then
+
+ \ Try all default kernel names
+ flags kernel args 1+ try_multiple_kernels
+;
+
+\ Try to load a kernel; the kernel name is taken from one of
+\ the following lists, as ordered:
+\
+\ 1. The "bootfile" environment variable
+\ 2. The "kernel" environment variable
+\
+\ Flags are passed, if provided.
+\
+\ The kernel will be loaded from a directory computed from the
+\ path given. Two directories will be tried in the following order:
+\
+\ 1. /boot/path
+\ 2. path
+\
+\ The module_path variable is overridden if load is succesful, by
+\ prepending the successful path.
+
+: load_from_directory ( path len 1 | flags len' path len 2 -- flag )
+ local args
+ 2local path
+ args 1 = if 0 0 then
+ 2local flags
+ 0 0 2local oldmodulepath \ like a string
+ 0 0 2local newmodulepath \ like a string
+ end-locals
+
+ \ Set the environment variable module_path, and try loading
+ \ the kernel again.
+ modulepath getenv saveenv to oldmodulepath
+
+ \ Try prepending /boot/ first
+ bootpath nip path nip + \ total length
+ oldmodulepath nip dup -1 = if
+ drop
+ else
+ 1+ + \ add oldpath -- XXX why the 1+ ?
+ then
+ allocate if ( out of memory ) 1 exit then \ XXX throw ?
+
+ 0
+ bootpath strcat
+ path strcat
+ 2dup to newmodulepath
+ modulepath setenv
+
+ \ Try all default kernel names
+ flags args 1- load_a_kernel
+ 0= if ( success )
+ oldmodulepath nip -1 <> if
+ newmodulepath s" ;" strcat
+ oldmodulepath strcat
+ modulepath setenv
+ newmodulepath drop free-memory
+ oldmodulepath drop free-memory
+ then
+ 0 exit
+ then
+
+ \ Well, try without the prepended /boot/
+ path newmodulepath drop swap move
+ newmodulepath drop path nip
+ 2dup to newmodulepath
+ modulepath setenv
+
+ \ Try all default kernel names
+ flags args 1- load_a_kernel
+ if ( failed once more )
+ oldmodulepath restoreenv
+ newmodulepath drop free-memory
+ 1
+ else
+ oldmodulepath nip -1 <> if
+ newmodulepath s" ;" strcat
+ oldmodulepath strcat
+ modulepath setenv
+ newmodulepath drop free-memory
+ oldmodulepath drop free-memory
+ then
+ 0
+ then
+;
+
+\ Try to load a kernel; the kernel name is taken from one of
+\ the following lists, as ordered:
+\
+\ 1. The "bootfile" environment variable
+\ 2. The "kernel" environment variable
+\ 3. The "path" argument
+\
+\ Flags are passed, if provided.
+\
+\ The kernel will be loaded from a directory computed from the
+\ path given. Two directories will be tried in the following order:
+\
+\ 1. /boot/path
+\ 2. path
+\
+\ Unless "path" is meant to be kernel name itself. In that case, it
+\ will first be tried as a full path, and, next, search on the
+\ directories pointed by module_path.
+\
+\ The module_path variable is overridden if load is succesful, by
+\ prepending the successful path.
+
+: load_directory_or_file ( path len 1 | flags len' path len 2 -- flag )
+ local args
+ 2local path
+ args 1 = if 0 0 then
+ 2local flags
+ end-locals
+
+ \ First, assume path is an absolute path to a directory
+ flags path args clip_args load_from_directory
+ dup 0= if exit else drop then
+
+ \ Next, assume path points to the kernel
+ flags path args try_multiple_kernels
+;
+
+: initialize ( addr len -- )
+ strdup conf_files strset
+;
+
+: boot-args ( -- addr len 1 | 0 )
+ s" boot-args" getenv
+ dup -1 = if drop 0 else 1 then
+;
+
+: standard_kernel_search ( flags 1 | 0 -- flag )
+ local args
+ args 0= if 0 0 then
+ 2local flags
+ s" kernel" getenv
+ dup -1 = if 0 swap then
+ 2local path
+ end-locals
+
+ path nip -1 = if ( there isn't a "kernel" environment variable )
+ flags args load_a_kernel
+ else
+ flags path args 1+ clip_args load_directory_or_file
+ then
+;
+
+: load_kernel ( -- ) ( throws: abort )
+ s" xen_kernel" getenv -1 = if
+ boot-args standard_kernel_search
+ abort" Unable to load a kernel!"
+ exit
+ then
+
+ drop
+ \ we have loaded the xen kernel, load unix as module
+ s" bootfile" getenv dup -1 <> if
+ s" kernel" s" -t " 3 1 load
+ then
+ abort" Unable to load a kernel!"
+;
+
+: load_xen ( -- )
+ s" xen_kernel" getenv dup -1 <> if
+ 1 1 load ( c-addr/u flag N -- flag )
+ else
+ drop
+ 0 ( -1 -- flag )
+ then
+;
+
+: load_xen_throw ( -- ) ( throws: abort )
+ load_xen
+ abort" Unable to load Xen!"
+;
+
+: set_defaultoptions ( -- )
+ s" boot-args" getenv dup -1 = if
+ drop
+ else
+ s" temp_options" setenv
+ then
+;
+
+\ pick the i-th argument, i starts at 0
+: argv[] ( aN uN ... a1 u1 N i -- aN uN ... a1 u1 N ai+1 ui+1 )
+ 2dup = if 0 0 exit then \ out of range
+ dup >r
+ 1+ 2* ( skip N and ui )
+ pick
+ r>
+ 1+ 2* ( skip N and ai )
+ pick
+;
+
+: drop_args ( aN uN ... a1 u1 N -- )
+ 0 ?do 2drop loop
+;
+
+: argc
+ dup
+;
+
+: queue_argv ( aN uN ... a1 u1 N a u -- a u aN uN ... a1 u1 N+1 )
+ >r
+ over 2* 1+ -roll
+ r>
+ over 2* 1+ -roll
+ 1+
+;
+
+: unqueue_argv ( aN uN ... a1 u1 N -- aN uN ... a2 u2 N-1 a1 u1 )
+ 1- -rot
+;
+
+\ compute the length of the buffer including the spaces between words
+: strlen(argv) ( aN uN .. a1 u1 N -- aN uN .. a1 u1 N len )
+ dup 0= if 0 exit then
+ 0 >r \ Size
+ 0 >r \ Index
+ begin
+ argc r@ <>
+ while
+ r@ argv[]
+ nip
+ r> r> rot + 1+
+ >r 1+ >r
+ repeat
+ r> drop
+ r>
+;
+
+: concat_argv ( aN uN ... a1 u1 N -- a u )
+ strlen(argv) allocate if ENOMEM throw then
+ 0 2>r ( save addr 0 on return stack )
+
+ begin
+ dup
+ while
+ unqueue_argv ( ... N a1 u1 )
+ 2r> 2swap ( old a1 u1 )
+ strcat
+ s" " strcat ( append one space ) \ XXX this gives a trailing space
+ 2>r ( store string on the result stack )
+ repeat
+ drop_args
+ 2r>
+;
+
+: set_tempoptions ( addrN lenN ... addr1 len1 N -- addr len 1 | 0 )
+ \ Save the first argument, if it exists and is not a flag
+ argc if
+ 0 argv[] drop c@ [char] - <> if
+ unqueue_argv 2>r \ Filename
+ 1 >r \ Filename present
+ else
+ 0 >r \ Filename not present
+ then
+ else
+ 0 >r \ Filename not present
+ then
+
+ \ If there are other arguments, assume they are flags
+ ?dup if
+ concat_argv
+ 2dup s" temp_options" setenv
+ drop free if EFREE throw then
+ else
+ set_defaultoptions
+ then
+
+ \ Bring back the filename, if one was provided
+ r> if 2r> 1 else 0 then
+;
+
+: get_arguments ( -- addrN lenN ... addr1 len1 N )
+ 0
+ begin
+ \ Get next word on the command line
+ parse-word
+ ?dup while
+ queue_argv
+ repeat
+ drop ( empty string )
+;
+
+: load_kernel_and_modules ( args -- flag )
+ set_tempoptions
+ argc >r
+ s" temp_options" getenv dup -1 <> if
+ queue_argv
+ else
+ drop
+ then
+ load_xen
+ ?dup 0= if ( success )
+ r> if ( a path was passed )
+ load_directory_or_file
+ else
+ standard_kernel_search
+ then
+ ?dup 0= if ['] load_modules catch then
+ then
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/version.4th b/usr/src/boot/sys/boot/forth/version.4th
new file mode 100644
index 0000000000..a5311b4442
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/version.4th
@@ -0,0 +1,96 @@
+\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
+\ 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.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-version.4th
+
+vocabulary version-processing
+only forth also version-processing definitions
+
+variable versionX
+variable versionY
+
+\ Default $loader_version value if not overridden or using tribute screen
+: str_loader_version ( -- C-ADDR/U|-1 ) -1 ;
+
+\ Initialize text placement to defaults
+80 versionX ! \ NOTE: this is the ending column (text is right-justified)
+24 versionY !
+
+only forth definitions also version-processing
+
+: print_version ( -- )
+
+ \ Get the text placement position (if set)
+ s" loader_version_x" getenv dup -1 <> if
+ ?number drop versionX ! -1
+ then drop
+ s" loader_version_y" getenv dup -1 <> if
+ ?number drop versionY ! -1
+ then drop
+
+ \ Default version if none was set
+ s" loader_version" getenv dup -1 = if
+ drop
+ \ Use above default if no logo is requested
+ s" loader_logo" getenv dup -1 = if
+ drop str_loader_version
+ else
+ \ For tributes, do nothing (defer to logo-*.4th)
+ 2dup s" tribute" compare-insensitive 0= if
+ 2drop
+ s" logo" sfind if
+ drop exit \ see logo-tribute.4th
+ else
+ drop str_loader_version
+ then
+ else 2dup s" tributebw" compare-insensitive 0= if
+ 2drop
+ s" logo" sfind if
+ drop exit \ see logo-tributebw.4th
+ else
+ drop str_loader_version
+ then
+ else
+ 2drop str_loader_version
+ then then
+ then
+ then dup -1 = if
+ drop exit \ default version (above) is disabled
+ then
+
+ \ Right justify the text
+ dup versionX @ swap - versionY @ at-xy
+
+ \ Print the version (optionally in cyan)
+ loader_color? dup ( c-addr/u -- c-addr/u bool bool )
+ if 6 fg then
+ -rot type
+ if me then
+
+ 0 25 at-xy
+;
+
+only forth definitions
diff --git a/usr/src/boot/sys/boot/forth/version.4th.8 b/usr/src/boot/sys/boot/forth/version.4th.8
new file mode 100644
index 0000000000..256df1ee5f
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/version.4th.8
@@ -0,0 +1,128 @@
+.\" Copyright (c) 2011-2013 Devin Teske
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 6, 2013
+.Dt VERSION.4TH 8
+.Os
+.Sh NAME
+.Nm version.4th
+.Nd FreeBSD version string boot module
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the boot loader
+version at the bottom-right of the screen.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include version.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic print_version
+Prints the contents of the
+.Va loader_version
+environment variable right-justified at the column
+.Va loader_version_x
+and row
+.Va loader_version_y .
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_version
+Set automatically by
+.Xr loader 8 ,
+but you can override it by setting in
+.Xr loader.conf 5 .
+This should be the version of boot loader used.
+.It Va loader_version_x
+Sets the desired ending column position of
+.Va loader_version .
+Default is 80.
+.It Va loader_version_y
+Sets the desired ending row position of
+.Va loader_version .
+Default is 24.
+.It Va loader_color
+If set to
+.Dq Li NO
+(case-insensitive) or
+.Dq Li 0 ,
+causes the version to be printed without color
+.Pq default is ANSI Cyan .
+.El
+.Sh FILES
+.Bl -tag -width /boot/version.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/version.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Override
+.Xr loader 8
+version in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_version="loader 1.1"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr color.4th 8 ,
+.Xr loader 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq dteske@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/i386/Makefile b/usr/src/boot/sys/boot/i386/Makefile
new file mode 100644
index 0000000000..305a816aa0
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/Makefile
@@ -0,0 +1,39 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+
+# likely targets for removal, keeping around just in case...
+# SUBDIRS= boot0 boot0sio kgzldr libfirewire
+# current targets
+SUBDIRS= pmbr btx cdboot gptzfsboot libi386 loader pxeldr
+INSTDIRS= pmbr cdboot gptzfsboot loader pxeldr
+
+all:= TARGET= all
+install:= TARGET= install
+clean:= TARGET= clean
+clobber:= TARGET= clobber
+
+.KEEP_STATE:
+
+all clean clobber: $(SUBDIRS)
+
+install: all $(INSTDIRS)
+
+FRC:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/boot/sys/boot/i386/Makefile.inc b/usr/src/boot/sys/boot/i386/Makefile.inc
new file mode 100644
index 0000000000..5398b4b545
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/Makefile.inc
@@ -0,0 +1,39 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+# Common defines for all of /sys/boot/i386/
+
+ROOT_BOOT= $(ROOT)/boot
+ROOTBOOTPROG=$(PROG:%=$(ROOT_BOOT)/%)
+
+LOADER_ADDRESS=0x200000
+CFLAGS += -march=i386 -ffreestanding
+CFLAGS += -mpreferred-stack-boundary=2
+CFLAGS += -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
+CFLAGS += -std=gnu99 -fno-reorder-functions
+LDFLAGS += -nostdlib
+
+CFLAGS += -m32
+ACFLAGS += -m32
+AFLAGS += --32
+
+# BTX components
+BTXDIR= $(SRC)/boot/sys/boot/i386/btx
+BTXLDR= ${BTXDIR}/btxldr/btxldr
+BTXKERN= ${BTXDIR}/btx/btx
+BTXCRT= ${BTXDIR}/lib/crt0.o
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/i386/boot0/Makefile b/usr/src/boot/sys/boot/i386/boot0/Makefile
new file mode 100644
index 0000000000..733fc68d32
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/boot0/Makefile
@@ -0,0 +1,83 @@
+# $FreeBSD$
+
+PROG?= boot0
+STRIP=
+BINMODE=${NOBINMODE}
+MAN=
+SRCS= ${PROG}.S
+
+# Additional options that you can specify with make OPTS="..."
+# (these only apply to boot0.S)
+#
+# -DVOLUME_SERIAL support volume serial number (NT, XP, Vista)
+# -DSIO do I/O using COM1:
+# -DPXE fallback to INT18/PXE with F6
+# -DCHECK_DRIVE enable checking drive number
+# -DONLY_F_KEYS accept only Fx keys in console
+# -DTEST print drive number on entry
+#
+OPTS ?= -DVOLUME_SERIAL -DPXE
+CFLAGS += ${OPTS}
+
+# Flags used in the boot0.S code:
+# 0x0f all valid partitions enabled.
+# 0x80 'packet', use BIOS EDD (LBA) extensions instead of CHS
+# to read from disk. boot0.S does not check that the extensions
+# are supported, but all modern BIOSes should have them.
+# 0x40 'noupdate', disable writing boot0 back to disk so that
+# the current selection is not preserved across reboots.
+# 0x20 'setdrv', override the drive number supplied by the bios
+# with the one in the boot sector.
+
+# Default boot flags:
+BOOT_BOOT0_FLAGS?= 0x8f
+
+# The number of timer ticks to wait for a keypress before assuming the default
+# selection. Since there are 18.2 ticks per second, the default value of
+# 0xb6 (182d) corresponds to 10 seconds.
+BOOT_BOOT0_TICKS?= 0xb6
+
+# The base address that we the boot0 code to to run it. Don't change this
+# unless you are glutton for punishment.
+BOOT_BOOT0_ORG?= 0x600
+
+# Comm settings for boot0sio.
+# Bit(s) Description
+# 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps)
+# 4-3 parity (00 or 10 = none, 01 = odd, 11 = even)
+# 2 stop bits (set = 2, clear = 1)
+# 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8)
+.if !defined(BOOT_BOOT0_COMCONSOLE_SPEED)
+BOOT_COMCONSOLE_SPEED?= 9600
+.if ${BOOT_COMCONSOLE_SPEED} == 9600
+BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 4800
+BOOT_BOOT0_COMCONSOLE_SPEED= "6 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 2400
+BOOT_BOOT0_COMCONSOLE_SPEED= "5 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 1200
+BOOT_BOOT0_COMCONSOLE_SPEED= "4 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 600
+BOOT_BOOT0_COMCONSOLE_SPEED= "3 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 300
+BOOT_BOOT0_COMCONSOLE_SPEED= "2 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 150
+BOOT_BOOT0_COMCONSOLE_SPEED= "1 << 5 + 3"
+.elif ${BOOT_COMCONSOLE_SPEED} == 110
+BOOT_BOOT0_COMCONSOLE_SPEED= "0 << 5 + 3"
+.else
+BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3"
+.endif
+.endif
+
+CFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \
+ -DTICKS=${BOOT_BOOT0_TICKS} \
+ -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED}
+
+LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-S,--oformat,binary
+
+.include <bsd.prog.mk>
+
+# XXX: clang integrated-as doesn't grok .codeNN directives yet
+CFLAGS.boot0.S= ${CLANG_NO_IAS}
+CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
diff --git a/usr/src/boot/sys/boot/i386/boot0/boot0.S b/usr/src/boot/sys/boot/i386/boot0/boot0.S
new file mode 100644
index 0000000000..708f0934c4
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/boot0/boot0.S
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2008 Luigi Rizzo (mostly documentation)
+ * Copyright (c) 2002 Bruce M. Simpson
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+/* build options: */
+#ifdef SIO /* use serial console on COM1. */
+#endif
+
+#ifdef PXE /* enable PXE/INT18 booting with F6 */
+#define SAVE_MORE_MEMORY
+#endif
+
+#ifdef CHECK_DRIVE /* make sure we boot from a HD. */
+#endif
+
+#ifdef ONLY_F_KEYS /* Only F1..F6, no digits on console */
+#endif
+
+#ifdef VOLUME_SERIAL /* support Volume serial number */
+#define B0_BASE 0x1ae /* move the internal data area */
+#define SAVE_MEMORY
+#else
+#define B0_BASE 0x1b2
+#endif
+
+#ifdef TEST /* enable some test code */
+#define SAVE_MEMORY
+#define SAVE_MORE_MEMORY
+#endif
+
+/*
+ * Note - this code uses many tricks to save space and fit in one sector.
+ * This includes using side effects of certain instructions, reusing
+ * register values from previous operations, etc.
+ * Be extremely careful when changing the code, even for simple things.
+ */
+
+/*
+ * BOOT BLOCK STRUCTURE
+ *
+ * This code implements a Master Boot Record (MBR) for an Intel/PC disk.
+ * It is 512 bytes long and it is normally loaded by the BIOS (or another
+ * bootloader) at 0:0x7c00. This code depends on %cs:%ip being 0:0x7c00
+ *
+ * The initial chunk of instructions is used as a signature by external
+ * tools (e.g. boot0cfg) which can manipulate the block itself.
+ *
+ * The area at offset 0x1b2 contains a magic string ('Drive '), also
+ * used as a signature to detect the block, and some variables that can
+ * be updated by boot0cfg (and optionally written back to the disk).
+ * These variables control the operation of the bootloader itself,
+ * e.g. which partitions to enable, the timeout, the use of LBA
+ * (called 'packet') or CHS mode, whether to force a drive number,
+ * and whether to write back the user's selection back to disk.
+ *
+ * As in every Master Boot Record, the partition table is at 0x1be,
+ * made of four 16-byte entries each containing:
+ *
+ * OFF SIZE DESCRIPTION
+ * 0 1 status (0x80: bootable, 0: non bootable)
+ * 1 3 start sector CHS
+ * 8:head, 6:sector, 2:cyl bit 9..8, 8:cyl bit 7..0
+ * 4 1 partition type
+ * 5 3 end sector CHS
+ * 8 4 LBA of first sector
+ * 12 4 partition size in sectors
+ *
+ * and followed by the two bytes 0x55, 0xAA (MBR signature).
+ */
+
+
+/*
+ * BOOT BLOCK OPERATION
+ *
+ * On entry, the registers contain the following values:
+ *
+ * %cs:%ip 0:0x7c00
+ * %dl drive number (0x80, 0x81, ... )
+ * %si pointer to the partition table from which we were loaded.
+ * Some boot code (e.g. syslinux) use this info to relocate
+ * themselves, so we want to pass a valid one to the next stage.
+ * NOTE: the use of %si is not a standard.
+ *
+ * This boot block first relocates itself at a different address (0:0x600),
+ * to free the space at 0:0x7c00 for the next stage boot block.
+ *
+ * It then initializes some memory at 0:0x800 and above (pointed by %bp)
+ * to store the original drive number (%dl) passed to us, and to construct a
+ * fake partition entry. The latter is used by the disk I/O routine and,
+ * in some cases, passed in %si to the next stage boot code.
+ *
+ * The variables at 0x1b2 are accessed as negative offsets from %bp.
+ *
+ * After the relocation, the code scans the partition table printing
+ * out enabled partition or disks, and waits for user input.
+ *
+ * When a partition is selected, or a timeout expires, the currently
+ * selected partition is used to load the next stage boot code,
+ * %dl and %si are set appropriately as when we were called, and
+ * control is transferred to the newly loaded code at 0:0x7c00.
+ */
+
+/*
+ * CONSTANTS
+ *
+ * NHRDRV is the address in segment 0 where the BIOS writes the
+ * total number of hard disks in the system.
+ * LOAD is the original load address and cannot be changed.
+ * ORIGIN is the relocation address. If you change it, you also need
+ * to change the value passed to the linker in the Makefile
+ * PRT_OFF is the location of the partition table (from the MBR standard).
+ * B0_OFF is the location of the data area, known to boot0cfg so
+ * it cannot be changed. Computed as a negative offset from 0x200
+ * MAGIC is the signature of a boot block.
+ */
+
+ .set NHRDRV,0x475 # Number of hard drives
+ .set ORIGIN,0x600 # Execution address
+ .set LOAD,0x7c00 # Load address
+
+ .set PRT_OFF,0x1be # Partition table
+ .set B0_OFF,(B0_BASE-0x200) # Offset of boot0 data
+
+ .set MAGIC,0xaa55 # Magic: bootable
+
+ .set KEY_ENTER,0x1c # Enter key scan code
+ .set KEY_F1,0x3b # F1 key scan code
+ .set KEY_1,0x02 # #1 key scan code
+
+ .set ASCII_BEL,'#' # ASCII code for <BEL>
+ .set ASCII_CR,0x0D # ASCII code for <CR>
+
+/*
+ * Offsets of variables in the block at B0_OFF, and in the volatile
+ * data area, computed as displacement from %bp.
+ * We need to define them as constant as the assembler cannot
+ * compute them in its single pass.
+ */
+ .set _NXTDRV, B0_OFF+6 # Next drive
+ .set _OPT, B0_OFF+7 # Default option
+ .set _SETDRV, B0_OFF+8 # Drive to force
+ .set _FLAGS, B0_OFF+9 # Flags
+ .set SETDRV, 0x20 # the 'setdrv' flag
+ .set NOUPDATE, 0x40 # the 'noupdate' flag
+ .set USEPACKET, 0x80 # the 'packet' flag
+
+ /* ticks is at a fixed position */
+ .set _TICKS, (PRT_OFF - 0x200 - 2) # Timeout ticks
+ .set _MNUOPT, 0x10 # Saved menu entries
+
+ .set TLEN, (desc_ofs - bootable_ids) # size of bootable ids
+ .globl start # Entry point
+ .code16 # This runs in real mode
+
+/*
+ * MAIN ENTRY POINT
+ * Initialise segments and registers to known values.
+ * segments start at 0.
+ * The stack is immediately below the address we were loaded to.
+ * NOTE: the initial section of the code (up to movw $LOAD,%sp)
+ * is used by boot0cfg, together with the 'Drive ' string and
+ * the 0x55, 0xaa at the end, as an identifier for version 1.0
+ * of the boot code. Do not change it.
+ * In version 1.0 the parameter table (_NEXTDRV etc) is at 0x1b9
+ */
+start: cld # String ops inc
+ xorw %ax,%ax # Zero
+ movw %ax,%es # Address
+ movw %ax,%ds # data
+ movw %ax,%ss # Set up
+ movw $LOAD,%sp # stack
+
+ /*
+ * Copy this code to the address it was linked for, 0x600 by default.
+ */
+ movw %sp,%si # Source
+ movw $start,%di # Destination
+ movw $0x100,%cx # Word count
+ rep # Relocate
+ movsw # code
+ /*
+ * After the code, (i.e. at %di+0, 0x800) create a partition entry,
+ * initialized to LBA 0 / CHS 0:0:1.
+ * Set %bp to point to the partition and also, with negative offsets,
+ * to the variables embedded in the bootblock (nextdrv and so on).
+ */
+ movw %di,%bp # Address variables
+ movb $0x8,%cl # Words to clear
+ rep # Zero
+ stosw # them
+ incb -0xe(%di) # Set the S field to 1
+
+ jmp main-LOAD+ORIGIN # Jump to relocated code
+
+main:
+#if defined(SIO) && COMSPEED != 0
+ /*
+ * Init the serial port. bioscom preserves the driver number in DX.
+ */
+ movw $COMSPEED,%ax # defined by Makefile
+ callw bioscom
+#endif
+
+ /*
+ * If the 'setdrv' flag is set in the boot sector, use the drive
+ * number from the boot sector at 'setdrv_num'.
+ * Optionally, do the same if the BIOS gives us an invalid number
+ * (note though that the override prevents booting from a floppy
+ * or a ZIP/flash drive in floppy emulation).
+ * The test costs 4 bytes of code so it is disabled by default.
+ */
+ testb $SETDRV,_FLAGS(%bp) # Set drive number?
+#ifndef CHECK_DRIVE /* disable drive checks */
+ jz save_curdrive # no, use the default
+#else
+ jnz disable_update # Yes
+ testb %dl,%dl # Drive number valid?
+ js save_curdrive # Possibly (0x80 set)
+#endif
+ /*
+ * Disable updates if the drive number is forced.
+ */
+disable_update: orb $NOUPDATE,_FLAGS(%bp) # Disable updates
+ movb _SETDRV(%bp),%dl # Use stored drive number
+
+ /*
+ * Whatever drive we decided to use, store it at (%bp). The byte
+ * is normally used for the state of the partition (0x80 or 0x00),
+ * but we abuse it as it is very convenient to access at offset 0.
+ * The value is read back after 'check_selection'
+ */
+save_curdrive: movb %dl, (%bp) # Save drive number
+ pushw %dx # Also in the stack
+#ifdef TEST /* test code, print internal bios drive */
+ rolb $1, %dl
+ movw $drive, %si
+ call putkey
+#endif
+ callw putn # Print a newline
+ /*
+ * Start out with a pointer to the 4th byte of the first table entry
+ * so that after 4 iterations it's beyond the end of the sector
+ * and beyond a 256 byte boundary. We use the latter trick to check for
+ * end of the loop without using an extra register (see start.5).
+ */
+ movw $(partbl+0x4),%bx # Partition table (+4)
+ xorw %dx,%dx # Item number
+
+ /*
+ * Loop around on the partition table, printing values until we
+ * pass a 256 byte boundary.
+ */
+read_entry: movb %ch,-0x4(%bx) # Zero active flag (ch == 0)
+ btw %dx,_FLAGS(%bp) # Entry enabled?
+ jnc next_entry # No
+ movb (%bx),%al # Load type
+ test %al, %al # skip empty partition
+ jz next_entry
+ /*
+ * Scan the table of bootable ids, which starts at %di and has
+ * length TLEN. On a match, %di points to the element following the
+ * match; the corresponding offset to the description is $(TLEN-1)
+ * bytes ahead. We use a count of TLEN+1 so if we don't find a match
+ * within the first TLEN entries, we hit the 'unknown' entry.
+ */
+ movw $bootable_ids,%di # Lookup tables
+ movb $(TLEN+1),%cl # Number of entries
+ repne # Locate
+ scasb # type
+ /*
+ * Get the matching element in the next array.
+ * The byte at $(TLEN-1)(%di) contains the offset of the description
+ * string from %di, so we add the number and print the string.
+ */
+ addw $(TLEN-1), %di # Adjust
+ movb (%di),%cl # Partition
+ addw %cx,%di # description
+ callw putx # Display it
+
+next_entry: incw %dx # Next item
+ addb $0x10,%bl # Next entry
+ jnc read_entry # Till done
+ /*
+ * We are past a 256 byte boundary: the partition table is finished.
+ * Add one to the drive number and check it is valid.
+ * Note that if we started from a floppy, %dl was 0 so we still
+ * get an entry for the next drive, which is the first Hard Disk.
+ */
+ popw %ax # Drive number
+ subb $0x80-0x1,%al # Does next
+ cmpb NHRDRV,%al # drive exist? (from BIOS?)
+ jb print_drive # Yes
+ /*
+ * If this is the only drive, don't display it as an option.
+ */
+ decw %ax # Already drive 0?
+ jz print_prompt # Yes
+ /*
+ * If it was illegal or we cycled through them, go back to drive 0.
+ */
+ xorb %al,%al # Drive 0
+ /*
+ * Whatever drive we selected, make it an ascii digit and save it
+ * back to the "nxtdrv" location in case we want to save it to disk.
+ * This digit is also part of the printed drive string, so add 0x80
+ * to indicate end of string.
+ */
+print_drive: addb $'0'|0x80,%al # Save next
+ movb %al,_NXTDRV(%bp) # drive number
+ movw $drive,%di # Display
+ callw putx # item
+ /*
+ * Menu is complete, display a prompt followed by current selection.
+ * 'decw %si' makes the register point to the space after 'Boot: '
+ * so we do not see an extra CRLF on the screen.
+ */
+print_prompt: movw $prompt,%si # Display
+ callw putstr # prompt
+ movb _OPT(%bp),%dl # Display
+ decw %si # default
+ callw putkey # key
+ jmp start_input # Skip beep
+
+/*
+ * Here we have the code waiting for user input or a timeout.
+ */
+beep: movb $ASCII_BEL,%al # Input error, print or beep
+ callw putchr
+
+start_input:
+ /*
+ * Actual Start of input loop. Take note of time
+ */
+ xorb %ah,%ah # BIOS: Get
+ int $0x1a # system time
+ movw %dx,%di # Ticks when
+ addw _TICKS(%bp),%di # timeout
+read_key:
+ /*
+ * Busy loop, looking for keystrokes but keeping one eye on the time.
+ */
+#ifndef SIO
+ movb $0x1,%ah # BIOS: Check
+ int $0x16 # for keypress
+#else /* SIO */
+ movb $0x03,%ah # BIOS: Read COM
+ call bioscom
+ testb $0x01,%ah # Check line status
+ # (bit 1 indicates input)
+#endif /* SIO */
+ jnz got_key # Have input
+ xorb %ah,%ah # BIOS: int 0x1a, 00
+ int $0x1a # get system time
+ cmpw %di,%dx # Timeout?
+ jb read_key # No
+
+ /*
+ * Timed out or default selection
+ */
+use_default: movb _OPT(%bp),%al # Load default
+ orb $NOUPDATE,_FLAGS(%bp) # Disable updates
+ jmp check_selection # Join common code
+
+ /*
+ * Get the keystroke.
+ * ENTER or CR confirm the current selection (same as a timeout).
+ * Otherwise convert F1..F6 (or '1'..'6') to 0..5 and check if the
+ * selection is valid.
+ * The SIO code uses ascii chars, the console code uses scancodes.
+ */
+got_key:
+#ifndef SIO
+ xorb %ah,%ah # BIOS: int 0x16, 00
+ int $0x16 # get keypress
+ movb %ah,%al # move scan code to %al
+ cmpb $KEY_ENTER,%al
+#else
+ movb $0x02,%ah # BIOS: Receive
+ call bioscom
+ cmpb $ASCII_CR,%al
+#endif
+ je use_default # enter -> default
+ /*
+ * Check if the key is acceptable, and loop back if not.
+ * The console (non-SIO) code looks at scancodes and accepts
+ * both F1..F6 and 1..6 (the latter costs 6 bytes of code),
+ * relying on the fact that F1..F6 have higher scancodes than 1..6
+ * The SIO code only takes 1..6
+ */
+#ifdef SIO /* SIO mode, use ascii values */
+ subb $'1',%al # Subtract '1' ascii code
+#else /* console mode -- use scancodes */
+ subb $KEY_F1,%al /* Subtract F1 scan code */
+#if !defined(ONLY_F_KEYS)
+ cmpb $0x5,%al # F1..F6
+ jna 3f # Yes
+ subb $(KEY_1 - KEY_F1),%al # Less #1 scan code
+ 3:
+#endif /* ONLY_F_KEYS */
+#endif /* SIO */
+check_selection:
+ cmpb $0x5,%al # F1..F6 or 1..6 ?
+#ifdef PXE /* enable PXE/INT18 using F6 */
+ jne 1f;
+ int $0x18 # found F6, try INT18
+ 1:
+#endif /* PXE */
+ jae beep # Not in F1..F5, beep
+
+ /*
+ * We have a selection. If it's a bad selection go back to complain.
+ * The bits in MNUOPT were set when the options were printed.
+ * Anything not printed is not an option.
+ */
+ cbtw # Extend (%ah=0 used later)
+ btw %ax,_MNUOPT(%bp) # Option enabled?
+ jnc beep # No
+ /*
+ * Save the info in the original tables
+ * for rewriting to the disk.
+ */
+ movb %al,_OPT(%bp) # Save option
+
+ /*
+ * Make %si and %bx point to the fake partition at LBA 0 (CHS 0:0:1).
+ * Because the correct address is already in %bp, just use it.
+ * Set %dl with the drive number saved in byte 0.
+ * If we have pressed F5 or 5, then this is a good, fake value
+ * to present to the next stage boot code.
+ */
+ movw %bp,%si # Partition for write
+ movb (%si),%dl # Drive number, saved above
+ movw %si,%bx # Partition for read
+ cmpb $0x4,%al # F5/#5 pressed?
+ pushf # Save results for later
+ je 1f # Yes, F5
+
+ /*
+ * F1..F4 was pressed, so make %bx point to the currently
+ * selected partition, and leave the drive number unchanged.
+ */
+ shlb $0x4,%al # Point to
+ addw $partbl,%ax # selected
+ xchgw %bx,%ax # partition
+ movb $0x80,(%bx) # Flag active
+ /*
+ * If not asked to do a write-back (flags 0x40) don't do one.
+ * Around the call, save the partition pointer to %bx and
+ * restore to %si which is where the next stage expects it.
+ */
+ 1: pushw %bx # Save
+ testb $NOUPDATE,_FLAGS(%bp) # No updates?
+ jnz 2f # skip update
+ movw $start,%bx # Data to write
+ movb $0x3,%ah # Write sector
+ callw intx13 # to disk
+ 2: popw %si # Restore
+
+ /*
+ * If going to next drive, replace drive with selected one.
+ * Remember to un-ascii it. Hey 0x80 is already set, cool!
+ */
+ popf # Restore %al test results
+ jne 3f # If not F5/#5
+ movb _NXTDRV(%bp),%dl # Next drive
+ subb $'0',%dl # number
+ /*
+ * Load selected bootsector to the LOAD location in RAM. If read
+ * fails or there is no 0x55aa marker, treat it as a bad selection.
+ */
+ 3: movw $LOAD,%bx # Address for read
+ movb $0x2,%ah # Read sector
+ callw intx13 # from disk
+ jc beep # If error
+ cmpw $MAGIC,0x1fe(%bx) # Bootable?
+ jne beep # No
+ pushw %si # Save ptr to selected part.
+ callw putn # Leave some space
+ popw %si # Restore, next stage uses it
+ jmp *%bx # Invoke bootstrap
+
+/*
+ * Display routines
+ * putkey prints the option selected in %dl (F1..F5 or 1..5) followed by
+ * the string at %si
+ * putx: print the option in %dl followed by the string at %di
+ * also record the drive as valid.
+ * putn: print a crlf
+ * putstr: print the string at %si
+ * putchr: print the char in al
+ */
+
+/*
+ * Display the option and record the drive as valid in the options.
+ * That last point is done using the btsw instruction which does
+ * a test and set. We don't care for the test part.
+ */
+putx: btsw %dx,_MNUOPT(%bp) # Enable menu option
+ movw $item,%si # Display
+ callw putkey # key
+ movw %di,%si # Display the rest
+ callw putstr # Display string
+
+putn: movw $crlf,%si # To next line
+ jmp putstr
+
+putkey:
+#ifndef SIO
+ movb $'F',%al # Display
+ callw putchr # 'F'
+#endif
+ movb $'1',%al # Prepare
+ addb %dl,%al # digit
+
+putstr.1: callw putchr # Display char
+putstr: lodsb # Get byte
+ testb $0x80,%al # End of string?
+ jz putstr.1 # No
+ andb $~0x80,%al # Clear MSB then print last
+
+putchr:
+#ifndef SIO
+ pushw %bx # Save
+ movw $0x7,%bx # Page:attribute
+ movb $0xe,%ah # BIOS: Display
+ int $0x10 # character
+ popw %bx # Restore
+#else /* SIO */
+ movb $0x01,%ah # BIOS: Send character
+bioscom:
+ pushw %dx # Save
+ xorw %dx,%dx # Use COM1
+ int $0x14 # BIOS: Serial I/O
+ popw %dx # Restore
+#endif /* SIO */
+ retw # To caller
+
+/* One-sector disk I/O routine */
+
+/*
+ * %dl: drive, %si partition entry, %es:%bx transfer buffer.
+ * Load the CHS values and possibly the LBA address from the block
+ * at %si, and use the appropriate method to load the sector.
+ * Don't use packet mode for a floppy.
+ */
+intx13: # Prepare CHS parameters
+ movb 0x1(%si),%dh # Load head
+ movw 0x2(%si),%cx # Load cylinder:sector
+ movb $0x1,%al # Sector count
+ pushw %si # Save
+ movw %sp,%di # Save
+#ifndef CHECK_DRIVE /* floppy support */
+ testb %dl, %dl # is this a floppy ?
+ jz 1f # Yes, use CHS mode
+#endif
+ testb $USEPACKET,_FLAGS(%bp) # Use packet interface?
+ jz 1f # No
+ pushl $0x0 # Set the
+ pushl 0x8(%si) # LBA address
+ pushw %es # Set the transfer
+ pushw %bx # buffer address
+ push $0x1 # Block count
+ push $0x10 # Packet size
+ movw %sp,%si # Packet pointer
+ decw %ax # Verify off
+ orb $0x40,%ah # Use disk packet
+ 1: int $0x13 # BIOS: Disk I/O
+ movw %di,%sp # Restore
+ popw %si # Restore
+ retw # To caller
+
+/*
+ * Various menu strings. 'item' goes after 'prompt' to save space.
+ * Also use shorter versions to make room for the PXE/INT18 code.
+ */
+prompt:
+#ifdef PXE
+ .ascii "\nF6 PXE\r"
+#endif
+ .ascii "\nBoot:"
+item: .ascii " "; .byte ' '|0x80
+crlf: .ascii "\r"; .byte '\n'|0x80
+
+/* Partition type tables */
+
+bootable_ids:
+ /*
+ * These values indicate bootable types we know about.
+ * Corresponding descriptions are at desc_ofs:
+ * Entries don't need to be sorted.
+ */
+ .byte 0x83, 0xa5, 0xa6, 0xa9, 0x06, 0x07, 0x0b
+#ifndef SAVE_MORE_MEMORY
+ .byte 0x05 # extended partition
+#endif
+#ifndef SAVE_MEMORY /* other DOS partitions */
+ .byte 0x01 # FAT12
+ .byte 0x04 # FAT16 < 32M
+#endif
+
+desc_ofs:
+ /*
+ * Offsets that match the known types above, used to point to the
+ * actual partition name. The last entry must point to os_misc,
+ * which is used for non-matching names.
+ */
+ .byte os_linux-. # 131, Linux
+ .byte os_freebsd-. # 165, FreeBSD
+ .byte os_bsd-. # 166, OpenBSD
+ .byte os_bsd-. # 169, NetBSD
+ .byte os_dos-. # 6, FAT16 >= 32M
+ .byte os_win-. # 7, NTFS
+ .byte os_win-. # 11, FAT32
+
+#ifndef SAVE_MORE_MEMORY
+ .byte os_ext-. # 5, DOS Ext
+#endif
+#ifndef SAVE_MEMORY
+ .byte os_dos-. # 1, FAT12 DOS
+ .byte os_dos-. # 4, FAT16 <32M
+#endif
+ .byte os_misc-. # Unknown
+
+ /*
+ * And here are the strings themselves. The last byte of
+ * the string has bit 7 set.
+ */
+os_misc: .byte '?'|0x80
+os_dos:
+#ifndef SAVE_MORE_MEMORY /* 'DOS' remapped to 'WIN' if no room */
+ .ascii "DO"; .byte 'S'|0x80
+#endif
+os_win: .ascii "Wi"; .byte 'n'|0x80
+os_linux: .ascii "Linu"; .byte 'x'|0x80
+os_freebsd: .ascii "Free"
+os_bsd: .ascii "BS"; .byte 'D'|0x80
+#ifndef SAVE_MORE_MEMORY
+os_ext: .ascii "EX"; .byte 'T'|0x80
+#endif
+
+ .org (0x200 + B0_OFF),0x90
+/*
+ * The boot0 version 1.0 parameter table.
+ * Do not move it nor change the "Drive " string, boot0cfg
+ * uses its offset and content to identify the boot sector.
+ * The other fields are sometimes changed before writing back to the drive
+ * Be especially careful that nxtdrv: must come after drive:, as it
+ * is part of the same string.
+ */
+drive: .ascii "Drive "
+nxtdrv: .byte 0x0 # Next drive number
+opt: .byte 0x0 # Option
+setdrv_num: .byte 0x80 # Drive to force
+flags: .byte FLAGS # Flags
+#ifdef VOLUME_SERIAL
+ .byte 0xa8,0xa8,0xa8,0xa8 # Volume Serial Number
+#endif
+ticks: .word TICKS # Delay
+
+ .org PRT_OFF
+/*
+ * Here is the 64 byte partition table that fdisk would fiddle with.
+ */
+partbl: .fill 0x40,0x1,0x0 # Partition table
+ .word MAGIC # Magic number
+ .org 0x200 # again, safety check
+endblock:
diff --git a/usr/src/boot/sys/boot/i386/boot0sio/Makefile b/usr/src/boot/sys/boot/i386/boot0sio/Makefile
new file mode 100644
index 0000000000..1321dd330c
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/boot0sio/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../boot0
+
+PROGNAME= boot0sio
+CFLAGS+= -DSIO
+
+.include "${.CURDIR}/../boot0/Makefile"
diff --git a/usr/src/boot/sys/boot/i386/boot2/Makefile b/usr/src/boot/sys/boot/i386/boot2/Makefile
new file mode 100644
index 0000000000..195206f1c6
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/boot2/Makefile
@@ -0,0 +1,118 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+FILES= boot boot1 boot2
+
+NM?= nm
+
+# A value of 0x80 enables LBA support.
+BOOT_BOOT1_FLAGS?= 0x80
+
+BOOT_COMCONSOLE_PORT?= 0x3f8
+BOOT_COMCONSOLE_SPEED?= 9600
+B2SIOFMT?= 0x3
+
+REL1= 0x700
+ORG1= 0x7c00
+ORG2= 0x2000
+
+# Decide level of UFS support.
+BOOT2_UFS?= UFS1_AND_UFS2
+#BOOT2_UFS?= UFS2_ONLY
+#BOOT2_UFS?= UFS1_ONLY
+
+CFLAGS= -fomit-frame-pointer \
+ -mrtd \
+ -mregparm=3 \
+ -DUSE_XREAD \
+ -D${BOOT2_UFS} \
+ -DFLAGS=${BOOT_BOOT1_FLAGS} \
+ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \
+ -DSIOFMT=${B2SIOFMT} \
+ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
+ -I${.CURDIR}/../../common \
+ -I${.CURDIR}/../btx/lib -I. \
+ -Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
+ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
+ -Winline
+
+CFLAGS.gcc+= -Os \
+ -fno-guess-branch-probability \
+ -fno-unit-at-a-time \
+ --param max-inline-insns-single=100
+.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} <= 40201
+CFLAGS.gcc+= -mno-align-long-strings
+.endif
+
+CFLAGS.clang+= -Oz ${CLANG_OPT_SMALL}
+
+LD_FLAGS=-static -N --gc-sections
+
+# Pick up ../Makefile.inc early.
+.include <bsd.init.mk>
+
+CLEANFILES= boot
+
+boot: boot1 boot2
+ cat boot1 boot2 > boot
+
+CLEANFILES+= boot1 boot1.out boot1.o
+
+boot1: boot1.out
+ ${OBJCOPY} -S -O binary boot1.out ${.TARGET}
+
+boot1.out: boot1.o
+ ${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} boot1.o
+
+CLEANFILES+= boot2 boot2.ld boot2.ldr boot2.bin boot2.out boot2.o \
+ boot2.s boot2.s.tmp boot2.h sio.o
+
+boot2: boot2.ld
+ @set -- `ls -l boot2.ld`; x=$$((7680-$$5)); \
+ echo "$$x bytes available"; test $$x -ge 0
+ dd if=boot2.ld of=${.TARGET} obs=7680 conv=osync status=none
+
+boot2.ld: boot2.ldr boot2.bin ${BTXKERN}
+ btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l boot2.ldr \
+ -o ${.TARGET} -P 1 boot2.bin
+
+boot2.ldr:
+ dd if=/dev/zero of=${.TARGET} bs=512 count=1 status=none
+
+boot2.bin: boot2.out
+ ${OBJCOPY} -S -O binary boot2.out ${.TARGET}
+
+boot2.out: ${BTXCRT} boot2.o sio.o
+ ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
+
+boot2.o: boot2.s
+ ${CC} ${ACFLAGS} -c boot2.s
+
+SRCS= boot2.c boot2.h
+
+boot2.s: boot2.c boot2.h ${.CURDIR}/../../common/ufsread.c
+ ${CC} ${CFLAGS} -S -o boot2.s.tmp ${.CURDIR}/boot2.c
+ sed -e '/align/d' -e '/nop/d' < boot2.s.tmp > boot2.s
+ rm -f boot2.s.tmp
+
+boot2.h: boot1.out
+ ${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T xread/ \
+ { x = $$1 - ORG1; \
+ printf("#define XREADORG %#x\n", REL1 + x) }' \
+ ORG1=`printf "%d" ${ORG1}` \
+ REL1=`printf "%d" ${REL1}` > ${.TARGET}
+
+.if ${MACHINE_CPUARCH} == "amd64"
+beforedepend boot2.s: machine
+CLEANFILES+= machine
+machine: ${.CURDIR}/../../../i386/include .NOMETA
+ ln -sf ${.ALLSRC} ${.TARGET}
+.endif
+
+.include <bsd.prog.mk>
+
+# XXX: clang integrated-as doesn't grok .codeNN directives yet
+CFLAGS.boot1.S= ${CLANG_NO_IAS}
+CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
diff --git a/usr/src/boot/sys/boot/i386/btx/Makefile b/usr/src/boot/sys/boot/i386/btx/Makefile
new file mode 100644
index 0000000000..a95d1b1db9
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/Makefile
@@ -0,0 +1,36 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+.PARALLEL:
+
+SUBDIRS= btx btxldr lib
+
+all:= TARGET= all
+install:= TARGET= install
+clean:= TARGET= clean
+clobber:= TARGET= clobber
+
+.KEEP_STATE:
+
+all clean clobber: $(SUBDIRS)
+
+install: $(SUBDIRS)
+
+FRC:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/boot/sys/boot/i386/btx/Makefile.inc b/usr/src/boot/sys/boot/i386/btx/Makefile.inc
new file mode 100644
index 0000000000..265f86d1ed
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/i386/btx/btx/Makefile b/usr/src/boot/sys/boot/i386/btx/btx/Makefile
new file mode 100644
index 0000000000..d31f59f0f9
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/btx/Makefile
@@ -0,0 +1,62 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+PROG= btx
+SRCS= btx.S
+OBJS= btx.o
+
+AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+
+#.if defined(BOOT_BTX_NOHANG)
+#BOOT_BTX_FLAGS=0x1
+#.else
+BOOT_BTX_FLAGS=0x0
+#.endif
+
+CFLAGS = -DBTX_FLAGS=${BOOT_BTX_FLAGS}
+CFLAGS += -I./../../common
+CFLAGS += -march=i386 -ffreestanding -mno-mmx -mno-3dnow -mno-sse -mno-sse2
+CFLAGS += -mno-sse3 -msoft-float -m32 -std=gnu99
+CFLAGS += -Wa,--divide
+
+#.if defined(BTX_SERIAL)
+#BOOT_COMCONSOLE_PORT?= 0x3f8
+#BOOT_COMCONSOLE_SPEED?= 9600
+#B2SIOFMT?= 0x3
+#
+#CFLAGS+=-DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \
+# -DSIOFMT=${B2SIOFMT} -DSIOSPD=${BOOT_COMCONSOLE_SPEED}
+#.endif
+
+ORG= 0x9000
+
+LDFLAGS=-e start -Ttext ${ORG} -N -S --oformat binary
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS)
+
+.S.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+clobber: clean
+
+clean:
+ $(RM) $(PROG) $(OBJS)
diff --git a/usr/src/boot/sys/boot/i386/btx/btx/btx.S b/usr/src/boot/sys/boot/i386/btx/btx/btx.S
new file mode 100644
index 0000000000..87d09a5a1e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/btx/btx.S
@@ -0,0 +1,1082 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#include <bootargs.h>
+
+/*
+ * Memory layout.
+ */
+ .set MEM_BTX,0x1000 # Start of BTX memory
+ .set MEM_ESP0,0x1800 # Supervisor stack
+ .set MEM_BUF,0x1800 # Scratch buffer
+ .set MEM_ESPR,0x5e00 # Real mode stack
+ .set MEM_IDT,0x5e00 # IDT
+ .set MEM_TSS,0x5f98 # TSS
+ .set MEM_MAP,0x6000 # I/O bit map
+ .set MEM_TSS_END,0x7fff # End of TSS
+ .set MEM_ORG,0x9000 # BTX code
+ .set MEM_USR,0xa000 # Start of user memory
+/*
+ * Paging control.
+ */
+ .set PAG_SIZ,0x1000 # Page size
+ .set PAG_CNT,0x1000 # Pages to map
+/*
+ * Fields in %eflags.
+ */
+ .set PSL_RESERVED_DEFAULT,0x00000002
+ .set PSL_T,0x00000100 # Trap flag
+ .set PSL_I,0x00000200 # Interrupt enable flag
+ .set PSL_D,0x00000400 # String instruction direction
+ .set PSL_NT,0x00004000 # Nested task flag
+ .set PSL_VM,0x00020000 # Virtual 8086 mode flag
+ .set PSL_AC,0x00040000 # Alignment check flag
+/*
+ * Segment selectors.
+ */
+ .set SEL_SCODE,0x8 # Supervisor code
+ .set SEL_SDATA,0x10 # Supervisor data
+ .set SEL_RCODE,0x18 # Real mode code
+ .set SEL_RDATA,0x20 # Real mode data
+ .set SEL_UCODE,0x28|3 # User code
+ .set SEL_UDATA,0x30|3 # User data
+ .set SEL_TSS,0x38 # TSS
+/*
+ * Task state segment fields.
+ */
+ .set TSS_ESP0,0x4 # PL 0 ESP
+ .set TSS_SS0,0x8 # PL 0 SS
+ .set TSS_MAP,0x66 # I/O bit map base
+/*
+ * System calls.
+ */
+ .set SYS_EXIT,0x0 # Exit
+ .set SYS_EXEC,0x1 # Exec
+/*
+ * Fields in V86 interface structure.
+ */
+ .set V86_CTL,0x0 # Control flags
+ .set V86_ADDR,0x4 # Int number/address
+ .set V86_ES,0x8 # V86 ES
+ .set V86_DS,0xc # V86 DS
+ .set V86_FS,0x10 # V86 FS
+ .set V86_GS,0x14 # V86 GS
+/*
+ * V86 control flags.
+ */
+ .set V86F_ADDR,0x10000 # Segment:offset address
+ .set V86F_CALLF,0x20000 # Emulate far call
+ .set V86F_FLAGS,0x40000 # Return flags
+/*
+ * Dump format control bytes.
+ */
+ .set DMP_X16,0x1 # Word
+ .set DMP_X32,0x2 # Long
+ .set DMP_MEM,0x4 # Memory
+ .set DMP_EOL,0x8 # End of line
+/*
+ * Screen defaults and assumptions.
+ */
+ .set SCR_MAT,0x7 # Mode/attribute
+ .set SCR_COL,0x50 # Columns per row
+ .set SCR_ROW,0x19 # Rows per screen
+/*
+ * BIOS Data Area locations.
+ */
+ .set BDA_MEM,0x413 # Free memory
+ .set BDA_SCR,0x449 # Video mode
+ .set BDA_POS,0x450 # Cursor position
+ .set BDA_BOOT,0x472 # Boot howto flag
+/*
+ * Derivations, for brevity.
+ */
+ .set _ESP0H,MEM_ESP0>>0x8 # Byte 1 of ESP0
+ .set _TSSIO,MEM_MAP-MEM_TSS # TSS I/O base
+ .set _TSSLM,MEM_TSS_END-MEM_TSS # TSS limit
+ .set _IDTLM,MEM_TSS-MEM_IDT-1 # IDT limit
+/*
+ * Code segment.
+ */
+ .globl start
+ .code16
+start: # Start of code
+/*
+ * BTX header.
+ */
+btx_hdr: .byte 0xeb # Machine ID
+ .byte 0xe # Header size
+ .ascii "BTX" # Magic
+ .byte 0x1 # Major version
+ .byte 0x2 # Minor version
+ .byte BTX_FLAGS # Flags
+ .word PAG_CNT-MEM_ORG>>0xc # Paging control
+ .word break-start # Text size
+ .long 0x0 # Entry address
+/*
+ * Initialization routine.
+ */
+init: cli # Disable interrupts
+ xor %ax,%ax # Zero/segment
+ mov %ax,%ss # Set up
+ mov $MEM_ESP0,%sp # stack
+ mov %ax,%es # Address
+ mov %ax,%ds # data
+ pushl $0x2 # Clear
+ popfl # flags
+/*
+ * Initialize memory.
+ */
+ mov $MEM_IDT,%di # Memory to initialize
+ mov $(MEM_ORG-MEM_IDT)/2,%cx # Words to zero
+ rep # Zero-fill
+ stosw # memory
+/*
+ * Update real mode IDT for reflecting hardware interrupts.
+ */
+ mov $intr20,%bx # Address first handler
+ mov $0x10,%cx # Number of handlers
+ mov $0x20*4,%di # First real mode IDT entry
+init.0: mov %bx,(%di) # Store IP
+ inc %di # Address next
+ inc %di # entry
+ stosw # Store CS
+ add $4,%bx # Next handler
+ loop init.0 # Next IRQ
+/*
+ * Create IDT.
+ */
+ mov $MEM_IDT,%di
+ mov $idtctl,%si # Control string
+init.1: lodsb # Get entry
+ cbw # count
+ xchg %ax,%cx # as word
+ jcxz init.4 # If done
+ lodsb # Get segment
+ xchg %ax,%dx # P:DPL:type
+ lodsw # Get control
+ xchg %ax,%bx # set
+ lodsw # Get handler offset
+ mov $SEL_SCODE,%dh # Segment selector
+init.2: shr %bx # Handle this int?
+ jnc init.3 # No
+ mov %ax,(%di) # Set handler offset
+ mov %dh,0x2(%di) # and selector
+ mov %dl,0x5(%di) # Set P:DPL:type
+ add $0x4,%ax # Next handler
+init.3: lea 0x8(%di),%di # Next entry
+ loop init.2 # Till set done
+ jmp init.1 # Continue
+/*
+ * Initialize TSS.
+ */
+init.4: movb $_ESP0H,TSS_ESP0+1(%di) # Set ESP0
+ movb $SEL_SDATA,TSS_SS0(%di) # Set SS0
+ movb $_TSSIO,TSS_MAP(%di) # Set I/O bit map base
+/*
+ * Bring up the system.
+ */
+ mov $0x2820,%bx # Set protected mode
+ callw setpic # IRQ offsets
+ lidt idtdesc # Set IDT
+ lgdt gdtdesc # Set GDT
+ mov %cr0,%eax # Switch to protected
+ inc %ax # mode
+ mov %eax,%cr0 #
+ ljmp $SEL_SCODE,$init.8 # To 32-bit code
+ .code32
+init.8: xorl %ecx,%ecx # Zero
+ movb $SEL_SDATA,%cl # To 32-bit
+ movw %cx,%ss # stack
+/*
+ * Launch user task.
+ */
+ movb $SEL_TSS,%cl # Set task
+ ltr %cx # register
+ movl $MEM_USR,%edx # User base address
+ movzwl %ss:BDA_MEM,%eax # Get free memory
+ shll $0xa,%eax # To bytes
+ subl $ARGSPACE,%eax # Less arg space
+ subl %edx,%eax # Less base
+ movb $SEL_UDATA,%cl # User data selector
+ pushl %ecx # Set SS
+ pushl %eax # Set ESP
+ push $0x202 # Set flags (IF set)
+ push $SEL_UCODE # Set CS
+ pushl btx_hdr+0xc # Set EIP
+ pushl %ecx # Set GS
+ pushl %ecx # Set FS
+ pushl %ecx # Set DS
+ pushl %ecx # Set ES
+ pushl %edx # Set EAX
+ movb $0x7,%cl # Set remaining
+init.9: push $0x0 # general
+ loop init.9 # registers
+#ifdef BTX_SERIAL
+ call sio_init # setup the serial console
+#endif
+ popa # and initialize
+ popl %es # Initialize
+ popl %ds # user
+ popl %fs # segment
+ popl %gs # registers
+ iret # To user mode
+/*
+ * Exit routine.
+ */
+exit: cli # Disable interrupts
+ movl $MEM_ESP0,%esp # Clear stack
+/*
+ * Turn off paging.
+ */
+ movl %cr0,%eax # Get CR0
+ andl $~0x80000000,%eax # Disable
+ movl %eax,%cr0 # paging
+ xorl %ecx,%ecx # Zero
+ movl %ecx,%cr3 # Flush TLB
+/*
+ * Restore the GDT in case we caught a kernel trap.
+ */
+ lgdt %cs:gdtdesc # Set GDT
+/*
+ * To 16 bits.
+ */
+ ljmpw $SEL_RCODE,$exit.1 # Reload CS
+ .code16
+exit.1: mov $SEL_RDATA,%cl # 16-bit selector
+ mov %cx,%ss # Reload SS
+ mov %cx,%ds # Load
+ mov %cx,%es # remaining
+ mov %cx,%fs # segment
+ mov %cx,%gs # registers
+/*
+ * To real-address mode.
+ */
+ dec %ax # Switch to
+ mov %eax,%cr0 # real mode
+ ljmp $0x0,$exit.2 # Reload CS
+exit.2: xor %ax,%ax # Real mode segment
+ mov %ax,%ss # Reload SS
+ mov %ax,%ds # Address data
+ mov $0x7008,%bx # Set real mode
+ callw setpic # IRQ offsets
+ lidt ivtdesc # Set IVT
+/*
+ * Reboot or await reset.
+ */
+ sti # Enable interrupts
+ testb $0x1,btx_hdr+0x7 # Reboot?
+exit.3: jz exit.3 # No
+ movw $0x1234, BDA_BOOT # Do a warm boot
+ ljmp $0xf000,$0xfff0 # reboot the machine
+/*
+ * Set IRQ offsets by reprogramming 8259A PICs.
+ */
+setpic: in $0x21,%al # Save master
+ push %ax # IMR
+ in $0xa1,%al # Save slave
+ push %ax # IMR
+ movb $0x11,%al # ICW1 to
+ outb %al,$0x20 # master,
+ outb %al,$0xa0 # slave
+ movb %bl,%al # ICW2 to
+ outb %al,$0x21 # master
+ movb %bh,%al # ICW2 to
+ outb %al,$0xa1 # slave
+ movb $0x4,%al # ICW3 to
+ outb %al,$0x21 # master
+ movb $0x2,%al # ICW3 to
+ outb %al,$0xa1 # slave
+ movb $0x1,%al # ICW4 to
+ outb %al,$0x21 # master,
+ outb %al,$0xa1 # slave
+ pop %ax # Restore slave
+ outb %al,$0xa1 # IMR
+ pop %ax # Restore master
+ outb %al,$0x21 # IMR
+ retw # To caller
+ .code32
+/*
+ * Exception jump table.
+ */
+intx00: push $0x0 # Int 0x0: #DE
+ jmp ex_noc # Divide error
+ push $0x1 # Int 0x1: #DB
+ jmp ex_noc # Debug
+ push $0x3 # Int 0x3: #BP
+ jmp ex_noc # Breakpoint
+ push $0x4 # Int 0x4: #OF
+ jmp ex_noc # Overflow
+ push $0x5 # Int 0x5: #BR
+ jmp ex_noc # BOUND range exceeded
+ push $0x6 # Int 0x6: #UD
+ jmp ex_noc # Invalid opcode
+ push $0x7 # Int 0x7: #NM
+ jmp ex_noc # Device not available
+ push $0x8 # Int 0x8: #DF
+ jmp except # Double fault
+ push $0xa # Int 0xa: #TS
+ jmp except # Invalid TSS
+ push $0xb # Int 0xb: #NP
+ jmp except # Segment not present
+ push $0xc # Int 0xc: #SS
+ jmp except # Stack segment fault
+ push $0xd # Int 0xd: #GP
+ jmp except # General protection
+ push $0xe # Int 0xe: #PF
+ jmp except # Page fault
+intx10: push $0x10 # Int 0x10: #MF
+ jmp ex_noc # Floating-point error
+/*
+ * Save a zero error code.
+ */
+ex_noc: pushl (%esp,1) # Duplicate int no
+ movb $0x0,0x4(%esp,1) # Fake error code
+/*
+ * Handle exception.
+ */
+except: cld # String ops inc
+ pushl %ds # Save
+ pushl %es # most
+ pusha # registers
+ pushl %gs # Set GS
+ pushl %fs # Set FS
+ pushl %ds # Set DS
+ pushl %es # Set ES
+ cmpw $SEL_SCODE,0x44(%esp,1) # Supervisor mode?
+ jne except.1 # No
+ pushl %ss # Set SS
+ jmp except.2 # Join common code
+except.1: pushl 0x50(%esp,1) # Set SS
+except.2: pushl 0x50(%esp,1) # Set ESP
+ push $SEL_SDATA # Set up
+ popl %ds # to
+ pushl %ds # address
+ popl %es # data
+ movl %esp,%ebx # Stack frame
+ movl $dmpfmt,%esi # Dump format string
+ movl $MEM_BUF,%edi # Buffer
+ pushl %edi # Dump to
+ call dump # buffer
+ popl %esi # and
+ call putstr # display
+ leal 0x18(%esp,1),%esp # Discard frame
+ popa # Restore
+ popl %es # registers
+ popl %ds # saved
+ cmpb $0x3,(%esp,1) # Breakpoint?
+ je except.3 # Yes
+ cmpb $0x1,(%esp,1) # Debug?
+ jne except.2a # No
+ testl $PSL_T,0x10(%esp,1) # Trap flag set?
+ jnz except.3 # Yes
+except.2a: jmp exit # Exit
+except.3: leal 0x8(%esp,1),%esp # Discard err, int no
+ iret # From interrupt
+
+/*
+ * Reboot the machine by setting the reboot flag and exiting
+ */
+reboot: orb $0x1,btx_hdr+0x7 # Set the reboot flag
+ jmp exit # Terminate BTX and reboot
+
+/*
+ * Protected Mode Hardware interrupt jump table.
+ */
+intx20: push $0x8 # Int 0x20: IRQ0
+ jmp int_hw # V86 int 0x8
+ push $0x9 # Int 0x21: IRQ1
+ jmp int_hw # V86 int 0x9
+ push $0xa # Int 0x22: IRQ2
+ jmp int_hw # V86 int 0xa
+ push $0xb # Int 0x23: IRQ3
+ jmp int_hw # V86 int 0xb
+ push $0xc # Int 0x24: IRQ4
+ jmp int_hw # V86 int 0xc
+ push $0xd # Int 0x25: IRQ5
+ jmp int_hw # V86 int 0xd
+ push $0xe # Int 0x26: IRQ6
+ jmp int_hw # V86 int 0xe
+ push $0xf # Int 0x27: IRQ7
+ jmp int_hw # V86 int 0xf
+ push $0x70 # Int 0x28: IRQ8
+ jmp int_hw # V86 int 0x70
+ push $0x71 # Int 0x29: IRQ9
+ jmp int_hw # V86 int 0x71
+ push $0x72 # Int 0x2a: IRQ10
+ jmp int_hw # V86 int 0x72
+ push $0x73 # Int 0x2b: IRQ11
+ jmp int_hw # V86 int 0x73
+ push $0x74 # Int 0x2c: IRQ12
+ jmp int_hw # V86 int 0x74
+ push $0x75 # Int 0x2d: IRQ13
+ jmp int_hw # V86 int 0x75
+ push $0x76 # Int 0x2e: IRQ14
+ jmp int_hw # V86 int 0x76
+ push $0x77 # Int 0x2f: IRQ15
+ jmp int_hw # V86 int 0x77
+
+/*
+ * Invoke real mode interrupt/function call from user mode with arguments.
+ */
+intx31: pushl $-1 # Dummy int no for btx_v86
+/*
+ * Invoke real mode interrupt/function call from protected mode.
+ *
+ * We place a trampoline on the user stack that will return to rret_tramp
+ * which will reenter protected mode and then finally return to the user
+ * client.
+ *
+ * Kernel frame %esi points to: Real mode stack frame at MEM_ESPR:
+ *
+ * -0x00 user %ss -0x04 kernel %esp (with full frame)
+ * -0x04 user %esp -0x08 btx_v86 pointer
+ * -0x08 user %eflags -0x0c flags (only used if interrupt)
+ * -0x0c user %cs -0x10 real mode CS:IP return trampoline
+ * -0x10 user %eip -0x12 real mode flags
+ * -0x14 int no -0x16 real mode CS:IP (target)
+ * -0x18 %eax
+ * -0x1c %ecx
+ * -0x20 %edx
+ * -0x24 %ebx
+ * -0x28 %esp
+ * -0x2c %ebp
+ * -0x30 %esi
+ * -0x34 %edi
+ * -0x38 %gs
+ * -0x3c %fs
+ * -0x40 %ds
+ * -0x44 %es
+ * -0x48 zero %eax (hardware int only)
+ * -0x4c zero %ecx (hardware int only)
+ * -0x50 zero %edx (hardware int only)
+ * -0x54 zero %ebx (hardware int only)
+ * -0x58 zero %esp (hardware int only)
+ * -0x5c zero %ebp (hardware int only)
+ * -0x60 zero %esi (hardware int only)
+ * -0x64 zero %edi (hardware int only)
+ * -0x68 zero %gs (hardware int only)
+ * -0x6c zero %fs (hardware int only)
+ * -0x70 zero %ds (hardware int only)
+ * -0x74 zero %es (hardware int only)
+ */
+int_hw: cld # String ops inc
+ pusha # Save gp regs
+ pushl %gs # Save
+ pushl %fs # seg
+ pushl %ds # regs
+ pushl %es
+ push $SEL_SDATA # Set up
+ popl %ds # to
+ pushl %ds # address
+ popl %es # data
+ leal 0x44(%esp,1),%esi # Base of frame
+ movl %esp,MEM_ESPR-0x04 # Save kernel stack pointer
+ movl -0x14(%esi),%eax # Get Int no
+ cmpl $-1,%eax # Hardware interrupt?
+ jne intusr.1 # Yes
+/*
+ * v86 calls save the btx_v86 pointer on the real mode stack and read
+ * the address and flags from the btx_v86 structure. For interrupt
+ * handler invocations (VM86 INTx requests), disable interrupts,
+ * tracing, and alignment checking while the handler runs.
+ */
+ movl $MEM_USR,%ebx # User base
+ movl %ebx,%edx # address
+ addl -0x4(%esi),%ebx # User ESP
+ movl (%ebx),%ebp # btx_v86 pointer
+ addl %ebp,%edx # Flatten btx_v86 ptr
+ movl %edx,MEM_ESPR-0x08 # Save btx_v86 ptr
+ movl V86_ADDR(%edx),%eax # Get int no/address
+ movl V86_CTL(%edx),%edx # Get control flags
+ movl -0x08(%esi),%ebx # Save user flags in %ebx
+ testl $V86F_ADDR,%edx # Segment:offset?
+ jnz intusr.4 # Yes
+ andl $~(PSL_I|PSL_T|PSL_AC),%ebx # Disable interrupts, tracing,
+ # and alignment checking for
+ # interrupt handler
+ jmp intusr.3 # Skip hardware interrupt
+/*
+ * Hardware interrupts store a NULL btx_v86 pointer and use the
+ * address (interrupt number) from the stack with empty flags. Also,
+ * push a dummy frame of zeros onto the stack for all the general
+ * purpose and segment registers and clear %eflags. This gives the
+ * hardware interrupt handler a clean slate.
+ */
+intusr.1: xorl %edx,%edx # Control flags
+ movl %edx,MEM_ESPR-0x08 # NULL btx_v86 ptr
+ movl $12,%ecx # Frame is 12 dwords
+intusr.2: pushl $0x0 # Fill frame
+ loop intusr.2 # with zeros
+ movl $PSL_RESERVED_DEFAULT,%ebx # Set clean %eflags
+/*
+ * Look up real mode IDT entry for hardware interrupts and VM86 INTx
+ * requests.
+ */
+intusr.3: shll $0x2,%eax # Scale
+ movl (%eax),%eax # Load int vector
+ jmp intusr.5 # Skip CALLF test
+/*
+ * Panic if V86F_CALLF isn't set with V86F_ADDR.
+ */
+intusr.4: testl $V86F_CALLF,%edx # Far call?
+ jnz intusr.5 # Ok
+ movl %edx,0x30(%esp,1) # Place VM86 flags in int no
+ movl $badvm86,%esi # Display bad
+ call putstr # VM86 call
+ popl %es # Restore
+ popl %ds # seg
+ popl %fs # regs
+ popl %gs
+ popal # Restore gp regs
+ jmp ex_noc # Panic
+/*
+ * %eax now holds the segment:offset of the function.
+ * %ebx now holds the %eflags to pass to real mode.
+ * %edx now holds the V86F_* flags.
+ */
+intusr.5: movw %bx,MEM_ESPR-0x12 # Pass user flags to real mode
+ # target
+/*
+ * If this is a v86 call, copy the seg regs out of the btx_v86 structure.
+ */
+ movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
+ jecxz intusr.6 # Skip for hardware ints
+ leal -0x44(%esi),%edi # %edi => kernel stack seg regs
+ pushl %esi # Save
+ leal V86_ES(%ecx),%esi # %esi => btx_v86 seg regs
+ movl $4,%ecx # Copy seg regs
+ rep # from btx_v86
+ movsl # to kernel stack
+ popl %esi # Restore
+intusr.6: movl -0x08(%esi),%ebx # Copy user flags to real
+ movl %ebx,MEM_ESPR-0x0c # mode return trampoline
+ movl $rret_tramp,%ebx # Set return trampoline
+ movl %ebx,MEM_ESPR-0x10 # CS:IP
+ movl %eax,MEM_ESPR-0x16 # Real mode target CS:IP
+ ljmpw $SEL_RCODE,$intusr.7 # Change to 16-bit segment
+ .code16
+intusr.7: movl %cr0,%eax # Leave
+ dec %al # protected
+ movl %eax,%cr0 # mode
+ ljmpw $0x0,$intusr.8
+intusr.8: xorw %ax,%ax # Reset %ds
+ movw %ax,%ds # and
+ movw %ax,%ss # %ss
+ lidt ivtdesc # Set IVT
+ popl %es # Restore
+ popl %ds # seg
+ popl %fs # regs
+ popl %gs
+ popal # Restore gp regs
+ movw $MEM_ESPR-0x16,%sp # Switch to real mode stack
+ iret # Call target routine
+/*
+ * For the return to real mode we setup a stack frame like this on the real
+ * mode stack. Note that callf calls won't pop off the flags, but we just
+ * ignore that by repositioning %sp to be just above the btx_v86 pointer
+ * so it is aligned. The stack is relative to MEM_ESPR.
+ *
+ * -0x04 kernel %esp
+ * -0x08 btx_v86
+ * -0x0c %eax
+ * -0x10 %ecx
+ * -0x14 %edx
+ * -0x18 %ebx
+ * -0x1c %esp
+ * -0x20 %ebp
+ * -0x24 %esi
+ * -0x28 %edi
+ * -0x2c %gs
+ * -0x30 %fs
+ * -0x34 %ds
+ * -0x38 %es
+ * -0x3c %eflags
+ */
+rret_tramp: movw $MEM_ESPR-0x08,%sp # Reset stack pointer
+ pushal # Save gp regs
+ pushl %gs # Save
+ pushl %fs # seg
+ pushl %ds # regs
+ pushl %es
+ pushfl # Save %eflags
+ pushl $PSL_RESERVED_DEFAULT|PSL_D # Use clean %eflags with
+ popfl # string ops dec
+ xorw %ax,%ax # Reset seg
+ movw %ax,%ds # regs
+ movw %ax,%es # (%ss is already 0)
+ lidt idtdesc # Set IDT
+ lgdt gdtdesc # Set GDT
+ mov %cr0,%eax # Switch to protected
+ inc %ax # mode
+ mov %eax,%cr0 #
+ ljmp $SEL_SCODE,$rret_tramp.1 # To 32-bit code
+ .code32
+rret_tramp.1: xorl %ecx,%ecx # Zero
+ movb $SEL_SDATA,%cl # Setup
+ movw %cx,%ss # 32-bit
+ movw %cx,%ds # seg
+ movw %cx,%es # regs
+ movl MEM_ESPR-0x04,%esp # Switch to kernel stack
+ leal 0x44(%esp,1),%esi # Base of frame
+ andb $~0x2,tss_desc+0x5 # Clear TSS busy
+ movb $SEL_TSS,%cl # Set task
+ ltr %cx # register
+/*
+ * Now we are back in protected mode. The kernel stack frame set up
+ * before entering real mode is still intact. For hardware interrupts,
+ * leave the frame unchanged.
+ */
+ cmpl $0,MEM_ESPR-0x08 # Leave saved regs unchanged
+ jz rret_tramp.3 # for hardware ints
+/*
+ * For V86 calls, copy the registers off of the real mode stack onto
+ * the kernel stack as we want their updated values. Also, initialize
+ * the segment registers on the kernel stack.
+ *
+ * Note that the %esp in the kernel stack after this is garbage, but popa
+ * ignores it, so we don't have to fix it up.
+ */
+ leal -0x18(%esi),%edi # Kernel stack GP regs
+ pushl %esi # Save
+ movl $MEM_ESPR-0x0c,%esi # Real mode stack GP regs
+ movl $8,%ecx # Copy GP regs from
+ rep # real mode stack
+ movsl # to kernel stack
+ movl $SEL_UDATA,%eax # Selector for data seg regs
+ movl $4,%ecx # Initialize %ds,
+ rep # %es, %fs, and
+ stosl # %gs
+/*
+ * For V86 calls, copy the saved seg regs on the real mode stack back
+ * over to the btx_v86 structure. Also, conditionally update the
+ * saved eflags on the kernel stack based on the flags from the user.
+ */
+ movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr
+ leal V86_GS(%ecx),%edi # %edi => btx_v86 seg regs
+ leal MEM_ESPR-0x2c,%esi # %esi => real mode seg regs
+ xchgl %ecx,%edx # Save btx_v86 ptr
+ movl $4,%ecx # Copy seg regs
+ rep # from real mode stack
+ movsl # to btx_v86
+ popl %esi # Restore
+ movl V86_CTL(%edx),%edx # Read V86 control flags
+ testl $V86F_FLAGS,%edx # User wants flags?
+ jz rret_tramp.3 # No
+ movl MEM_ESPR-0x3c,%eax # Read real mode flags
+ andl $~(PSL_T|PSL_NT),%eax # Clear unsafe flags
+ movw %ax,-0x08(%esi) # Update user flags (low 16)
+/*
+ * Return to the user task
+ */
+rret_tramp.3: popl %es # Restore
+ popl %ds # seg
+ popl %fs # regs
+ popl %gs
+ popal # Restore gp regs
+ addl $4,%esp # Discard int no
+ iret # Return to user mode
+
+/*
+ * System Call.
+ */
+intx30: cmpl $SYS_EXEC,%eax # Exec system call?
+ jne intx30.1 # No
+ pushl %ss # Set up
+ popl %es # all
+ pushl %es # segment
+ popl %ds # registers
+ pushl %ds # for the
+ popl %fs # program
+ pushl %fs # we're
+ popl %gs # invoking
+ movl $MEM_USR,%eax # User base address
+ addl 0xc(%esp,1),%eax # Change to user
+ leal 0x4(%eax),%esp # stack
+ popl %eax # Call
+ call *%eax # program
+intx30.1: orb $0x1,%ss:btx_hdr+0x7 # Flag reboot
+ jmp exit # Exit
+/*
+ * Dump structure [EBX] to [EDI], using format string [ESI].
+ */
+dump.0: stosb # Save char
+dump: lodsb # Load char
+ testb %al,%al # End of string?
+ jz dump.10 # Yes
+ testb $0x80,%al # Control?
+ jz dump.0 # No
+ movb %al,%ch # Save control
+ movb $'=',%al # Append
+ stosb # '='
+ lodsb # Get offset
+ pushl %esi # Save
+ movsbl %al,%esi # To
+ addl %ebx,%esi # pointer
+ testb $DMP_X16,%ch # Dump word?
+ jz dump.1 # No
+ lodsw # Get and
+ call hex16 # dump it
+dump.1: testb $DMP_X32,%ch # Dump long?
+ jz dump.2 # No
+ lodsl # Get and
+ call hex32 # dump it
+dump.2: testb $DMP_MEM,%ch # Dump memory?
+ jz dump.8 # No
+ pushl %ds # Save
+ testl $PSL_VM,0x50(%ebx) # V86 mode?
+ jnz dump.3 # Yes
+ verr 0x4(%esi) # Readable selector?
+ jnz dump.3 # No
+ ldsl (%esi),%esi # Load pointer
+ jmp dump.4 # Join common code
+dump.3: lodsl # Set offset
+ xchgl %eax,%edx # Save
+ lodsl # Get segment
+ shll $0x4,%eax # * 0x10
+ addl %edx,%eax # + offset
+ xchgl %eax,%esi # Set pointer
+dump.4: movb $2,%dl # Num lines
+dump.4a: movb $0x10,%cl # Bytes to dump
+dump.5: lodsb # Get byte and
+ call hex8 # dump it
+ decb %cl # Keep count
+ jz dump.6a # If done
+ movb $'-',%al # Separator
+ cmpb $0x8,%cl # Half way?
+ je dump.6 # Yes
+ movb $' ',%al # Use space
+dump.6: stosb # Save separator
+ jmp dump.5 # Continue
+dump.6a: decb %dl # Keep count
+ jz dump.7 # If done
+ movb $0xa,%al # Line feed
+ stosb # Save one
+ movb $7,%cl # Leading
+ movb $' ',%al # spaces
+dump.6b: stosb # Dump
+ decb %cl # spaces
+ jnz dump.6b
+ jmp dump.4a # Next line
+dump.7: popl %ds # Restore
+dump.8: popl %esi # Restore
+ movb $0xa,%al # Line feed
+ testb $DMP_EOL,%ch # End of line?
+ jnz dump.9 # Yes
+ movb $' ',%al # Use spaces
+ stosb # Save one
+dump.9: jmp dump.0 # Continue
+dump.10: stosb # Terminate string
+ ret # To caller
+/*
+ * Convert EAX, AX, or AL to hex, saving the result to [EDI].
+ */
+hex32: pushl %eax # Save
+ shrl $0x10,%eax # Do upper
+ call hex16 # 16
+ popl %eax # Restore
+hex16: call hex16.1 # Do upper 8
+hex16.1: xchgb %ah,%al # Save/restore
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+/*
+ * Output zero-terminated string [ESI] to the console.
+ */
+putstr.0: call putchr # Output char
+putstr: lodsb # Load char
+ testb %al,%al # End of string?
+ jnz putstr.0 # No
+ ret # To caller
+#ifdef BTX_SERIAL
+ .set SIO_PRT,SIOPRT # Base port
+ .set SIO_FMT,SIOFMT # 8N1
+ .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD
+
+/*
+ * int sio_init(void)
+ */
+sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
+ movb $SIO_FMT|0x80,%al # Set format
+ outb %al,(%dx) # and DLAB
+ pushl %edx # Save
+ subb $0x3,%dl # Divisor latch reg
+ movw $SIO_DIV,%ax # Set
+ outw %ax,(%dx) # BPS
+ popl %edx # Restore
+ movb $SIO_FMT,%al # Clear
+ outb %al,(%dx) # DLAB
+ incl %edx # Modem control reg
+ movb $0x3,%al # Set RTS,
+ outb %al,(%dx) # DTR
+ incl %edx # Line status reg
+ call sio_getc.1 # Get character
+
+/*
+ * int sio_flush(void)
+ */
+sio_flush: xorl %eax,%eax # Return value
+ xorl %ecx,%ecx # Timeout
+ movb $0x80,%ch # counter
+sio_flush.1: call sio_ischar # Check for character
+ jz sio_flush.2 # Till none
+ loop sio_flush.1 # or counter is zero
+ movb $1, %al # Exhausted all tries
+sio_flush.2: ret # To caller
+
+/*
+ * void sio_putc(int c)
+ */
+sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg
+ xor %ecx,%ecx # Timeout
+ movb $0x40,%ch # counter
+sio_putc.1: inb (%dx),%al # Transmitter
+ testb $0x20,%al # buffer empty?
+ loopz sio_putc.1 # No
+ jz sio_putc.2 # If timeout
+ movb 0x4(%esp,1),%al # Get character
+ subb $0x5,%dl # Transmitter hold reg
+ outb %al,(%dx) # Write character
+sio_putc.2: ret $0x4 # To caller
+
+/*
+ * int sio_getc(void)
+ */
+sio_getc: call sio_ischar # Character available?
+ jz sio_getc # No
+sio_getc.1: subb $0x5,%dl # Receiver buffer reg
+ inb (%dx),%al # Read character
+ ret # To caller
+
+/*
+ * int sio_ischar(void)
+ */
+sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register
+ xorl %eax,%eax # Zero
+ inb (%dx),%al # Received data
+ andb $0x1,%al # ready?
+ ret # To caller
+
+/*
+ * Output character AL to the serial console.
+ */
+putchr: pusha # Save
+ cmpb $10, %al # is it a newline?
+ jne putchr.1 # no?, then leave
+ push $13 # output a carriage
+ call sio_putc # return first
+ movb $10, %al # restore %al
+putchr.1: pushl %eax # Push the character
+ # onto the stack
+ call sio_putc # Output the character
+ popa # Restore
+ ret # To caller
+#else
+/*
+ * Output character AL to the console.
+ */
+putchr: pusha # Save
+ xorl %ecx,%ecx # Zero for loops
+ movb $SCR_MAT,%ah # Mode/attribute
+ movl $BDA_POS,%ebx # BDA pointer
+ movw (%ebx),%dx # Cursor position
+ movl $0xb8000,%edi # Regen buffer (color)
+ cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
+ jne putchr.1 # No
+ xorw %di,%di # Regen buffer (mono)
+putchr.1: cmpb $0xa,%al # New line?
+ je putchr.2 # Yes
+ xchgl %eax,%ecx # Save char
+ movb $SCR_COL,%al # Columns per row
+ mulb %dh # * row position
+ addb %dl,%al # + column
+ adcb $0x0,%ah # position
+ shll %eax # * 2
+ xchgl %eax,%ecx # Swap char, offset
+ movw %ax,(%edi,%ecx,1) # Write attr:char
+ incl %edx # Bump cursor
+ cmpb $SCR_COL,%dl # Beyond row?
+ jb putchr.3 # No
+putchr.2: xorb %dl,%dl # Zero column
+ incb %dh # Bump row
+putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
+ jb putchr.4 # No
+ leal 2*SCR_COL(%edi),%esi # New top line
+ movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
+ rep # Scroll
+ movsl # screen
+ movb $0x20,%al # Space
+ movb $SCR_COL,%cl # Columns to clear
+ rep # Clear
+ stosw # line
+ movb $SCR_ROW-1,%dh # Bottom line
+putchr.4: movw %dx,(%ebx) # Update position
+ popa # Restore
+ ret # To caller
+#endif
+
+ .code16
+/*
+ * Real Mode Hardware interrupt jump table.
+ */
+intr20: push $0x8 # Int 0x20: IRQ0
+ jmp int_hwr # V86 int 0x8
+ push $0x9 # Int 0x21: IRQ1
+ jmp int_hwr # V86 int 0x9
+ push $0xa # Int 0x22: IRQ2
+ jmp int_hwr # V86 int 0xa
+ push $0xb # Int 0x23: IRQ3
+ jmp int_hwr # V86 int 0xb
+ push $0xc # Int 0x24: IRQ4
+ jmp int_hwr # V86 int 0xc
+ push $0xd # Int 0x25: IRQ5
+ jmp int_hwr # V86 int 0xd
+ push $0xe # Int 0x26: IRQ6
+ jmp int_hwr # V86 int 0xe
+ push $0xf # Int 0x27: IRQ7
+ jmp int_hwr # V86 int 0xf
+ push $0x70 # Int 0x28: IRQ8
+ jmp int_hwr # V86 int 0x70
+ push $0x71 # Int 0x29: IRQ9
+ jmp int_hwr # V86 int 0x71
+ push $0x72 # Int 0x2a: IRQ10
+ jmp int_hwr # V86 int 0x72
+ push $0x73 # Int 0x2b: IRQ11
+ jmp int_hwr # V86 int 0x73
+ push $0x74 # Int 0x2c: IRQ12
+ jmp int_hwr # V86 int 0x74
+ push $0x75 # Int 0x2d: IRQ13
+ jmp int_hwr # V86 int 0x75
+ push $0x76 # Int 0x2e: IRQ14
+ jmp int_hwr # V86 int 0x76
+ push $0x77 # Int 0x2f: IRQ15
+ jmp int_hwr # V86 int 0x77
+/*
+ * Reflect hardware interrupts in real mode.
+ */
+int_hwr: push %ax # Save
+ push %ds # Save
+ push %bp # Save
+ mov %sp,%bp # Address stack frame
+ xchg %bx,6(%bp) # Swap BX, int no
+ xor %ax,%ax # Set %ds:%bx to
+ shl $2,%bx # point to
+ mov %ax,%ds # IDT entry
+ mov (%bx),%ax # Load IP
+ mov 2(%bx),%bx # Load CS
+ xchg %ax,4(%bp) # Swap saved %ax,%bx with
+ xchg %bx,6(%bp) # CS:IP of handler
+ pop %bp # Restore
+ pop %ds # Restore
+ lret # Jump to handler
+
+ .p2align 4
+/*
+ * Global descriptor table.
+ */
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+ .word 0xffff,MEM_USR,0xfa00,0xcf# SEL_UCODE
+ .word 0xffff,MEM_USR,0xf200,0xcf# SEL_UDATA
+tss_desc: .word _TSSLM,MEM_TSS,0x8900,0x0 # SEL_TSS
+gdt.1:
+/*
+ * Pseudo-descriptors.
+ */
+gdtdesc: .word gdt.1-gdt-1,gdt,0x0 # GDT
+idtdesc: .word _IDTLM,MEM_IDT,0x0 # IDT
+ivtdesc: .word 0x400-0x0-1,0x0,0x0 # IVT
+/*
+ * IDT construction control string.
+ */
+idtctl: .byte 0x10, 0x8e # Int 0x0-0xf
+ .word 0x7dfb,intx00 # (exceptions)
+ .byte 0x10, 0x8e # Int 0x10
+ .word 0x1, intx10 # (exception)
+ .byte 0x10, 0x8e # Int 0x20-0x2f
+ .word 0xffff,intx20 # (hardware)
+ .byte 0x1, 0xee # int 0x30
+ .word 0x1, intx30 # (system call)
+ .byte 0x2, 0xee # Int 0x31-0x32
+ .word 0x1, intx31 # (V86, null)
+ .byte 0x0 # End of string
+/*
+ * Dump format string.
+ */
+dmpfmt: .byte '\n' # "\n"
+ .ascii "int" # "int="
+ .byte 0x80|DMP_X32, 0x40 # "00000000 "
+ .ascii "err" # "err="
+ .byte 0x80|DMP_X32, 0x44 # "00000000 "
+ .ascii "efl" # "efl="
+ .byte 0x80|DMP_X32, 0x50 # "00000000 "
+ .ascii "eip" # "eip="
+ .byte 0x80|DMP_X32|DMP_EOL,0x48 # "00000000\n"
+ .ascii "eax" # "eax="
+ .byte 0x80|DMP_X32, 0x34 # "00000000 "
+ .ascii "ebx" # "ebx="
+ .byte 0x80|DMP_X32, 0x28 # "00000000 "
+ .ascii "ecx" # "ecx="
+ .byte 0x80|DMP_X32, 0x30 # "00000000 "
+ .ascii "edx" # "edx="
+ .byte 0x80|DMP_X32|DMP_EOL,0x2c # "00000000\n"
+ .ascii "esi" # "esi="
+ .byte 0x80|DMP_X32, 0x1c # "00000000 "
+ .ascii "edi" # "edi="
+ .byte 0x80|DMP_X32, 0x18 # "00000000 "
+ .ascii "ebp" # "ebp="
+ .byte 0x80|DMP_X32, 0x20 # "00000000 "
+ .ascii "esp" # "esp="
+ .byte 0x80|DMP_X32|DMP_EOL,0x0 # "00000000\n"
+ .ascii "cs" # "cs="
+ .byte 0x80|DMP_X16, 0x4c # "0000 "
+ .ascii "ds" # "ds="
+ .byte 0x80|DMP_X16, 0xc # "0000 "
+ .ascii "es" # "es="
+ .byte 0x80|DMP_X16, 0x8 # "0000 "
+ .ascii " " # " "
+ .ascii "fs" # "fs="
+ .byte 0x80|DMP_X16, 0x10 # "0000 "
+ .ascii "gs" # "gs="
+ .byte 0x80|DMP_X16, 0x14 # "0000 "
+ .ascii "ss" # "ss="
+ .byte 0x80|DMP_X16|DMP_EOL,0x4 # "0000\n"
+ .ascii "cs:eip" # "cs:eip="
+ .byte 0x80|DMP_MEM|DMP_EOL,0x48 # "00 00 ... 00 00\n"
+ .ascii "ss:esp" # "ss:esp="
+ .byte 0x80|DMP_MEM|DMP_EOL,0x0 # "00 00 ... 00 00\n"
+ .asciz "BTX halted\n" # End
+/*
+ * Bad VM86 call panic
+ */
+badvm86: .asciz "Invalid VM86 Request\n"
+
+/*
+ * End of BTX memory.
+ */
+ .p2align 4
+break:
diff --git a/usr/src/boot/sys/boot/i386/btx/btxldr/Makefile b/usr/src/boot/sys/boot/i386/btx/btxldr/Makefile
new file mode 100644
index 0000000000..338bf63ea0
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/btxldr/Makefile
@@ -0,0 +1,46 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+PROG= btxldr
+SRCS= btxldr.S
+OBJS= btxldr.o
+
+AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+
+LOADER_ADDRESS=0x200000
+CPPFLAGS=
+CFLAGS = -m32 -DLOADER_ADDRESS=${LOADER_ADDRESS}
+CFLAGS += -I./../../common
+CFLAGS += -Wa,--divide
+CFLAGS += -DBTXLDR_VERBOSE
+
+LDFLAGS=-e start -Ttext ${LOADER_ADDRESS} -N -S --oformat binary
+
+$(PROG): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS)
+
+.S.o:
+ $(COMPILE.S) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+all: $(PROG)
+
+clobber: clean
+
+clean:
+ $(RM) $(PROG) $(OBJS)
diff --git a/usr/src/boot/sys/boot/i386/btx/btxldr/btxldr.S b/usr/src/boot/sys/boot/i386/btx/btxldr/btxldr.S
new file mode 100644
index 0000000000..848b930b79
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/btxldr/btxldr.S
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#include <bootargs.h>
+
+#define RBX_MUTE 0x10 /* -m */
+#define OPT_SET(opt) (1 << (opt))
+
+/*
+ * Prototype BTX loader program, written in a couple of hours. The
+ * real thing should probably be more flexible, and in C.
+ */
+
+/*
+ * Memory locations.
+ */
+ .set MEM_STUB,0x600 # Real mode stub
+ .set MEM_ESP,0x1000 # New stack pointer
+ .set MEM_TBL,0x5000 # BTX page tables
+ .set MEM_ENTRY,0x9010 # BTX entry point
+ .set MEM_DATA,start+0x1000 # Data segment
+/*
+ * Segment selectors.
+ */
+ .set SEL_SCODE,0x8 # 4GB code
+ .set SEL_SDATA,0x10 # 4GB data
+ .set SEL_RCODE,0x18 # 64K code
+ .set SEL_RDATA,0x20 # 64K data
+/*
+ * Paging constants.
+ */
+ .set PAG_SIZ,0x1000 # Page size
+ .set PAG_ENT,0x4 # Page entry size
+/*
+ * Screen constants.
+ */
+ .set SCR_MAT,0x7 # Mode/attribute
+ .set SCR_COL,0x50 # Columns per row
+ .set SCR_ROW,0x19 # Rows per screen
+/*
+ * BIOS Data Area locations.
+ */
+ .set BDA_MEM,0x413 # Free memory
+ .set BDA_SCR,0x449 # Video mode
+ .set BDA_POS,0x450 # Cursor position
+/*
+ * Required by aout gas inadequacy.
+ */
+ .set SIZ_STUB,0x1a # Size of stub
+/*
+ * We expect to be loaded by boot2 at the origin defined in ./Makefile.
+ */
+ .globl start
+/*
+ * BTX program loader for ELF clients.
+ */
+start: cld # String ops inc
+ testl $OPT_SET(RBX_MUTE), 4(%esp) # Check first argument
+ setnz muted # for RBX_MUTE, set flag
+ movl $m_logo,%esi # Identify
+ call putstr # ourselves
+ movzwl BDA_MEM,%eax # Get base memory
+ shll $0xa,%eax # in bytes
+ movl %eax,%ebp # Base of user stack
+#ifdef BTXLDR_VERBOSE
+ movl $m_mem,%esi # Display
+ call hexout # amount of
+ call putstr # base memory
+#endif
+ lgdt gdtdesc # Load new GDT
+/*
+ * Relocate caller's arguments.
+ */
+#ifdef BTXLDR_VERBOSE
+ movl $m_esp,%esi # Display
+ movl %esp,%eax # caller
+ call hexout # stack
+ call putstr # pointer
+ movl $m_args,%esi # Format string
+ leal 0x4(%esp),%ebx # First argument
+ movl $0x6,%ecx # Count
+start.1: movl (%ebx),%eax # Get argument and
+ addl $0x4,%ebx # bump pointer
+ call hexout # Display it
+ loop start.1 # Till done
+ call putstr # End message
+#endif
+ movl BA_BOOTINFO+4(%esp),%esi # Source: bootinfo
+ cmpl $0x0, %esi # If the bootinfo pointer
+ je start_null_bi # is null, don't copy it
+ movl BI_SIZE(%esi),%ecx # Allocate space
+ subl %ecx,%ebp # for bootinfo
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # it
+ movl %ebp,BA_BOOTINFO+4(%esp) # Update pointer
+ movl %edi,%ebp # Restore base pointer
+#ifdef BTXLDR_VERBOSE
+ movl $m_rel_bi,%esi # Display
+ movl %ebp,%eax # bootinfo
+ call hexout # relocation
+ call putstr # message
+#endif
+start_null_bi: movl $BOOTARGS_SIZE,%ecx # Fixed size of arguments
+ testl $KARGS_FLAGS_EXTARG, BA_BOOTFLAGS+4(%esp) # Check for extra data
+ jz start_fixed # Skip if the flag is not set
+ addl BOOTARGS_SIZE+4(%esp),%ecx # Add size of variable args
+start_fixed: subl $ARGOFF,%ebp # Place args at fixed offset
+ leal 0x4(%esp),%esi # Source
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # them
+#ifdef BTXLDR_VERBOSE
+ movl $m_rel_args,%esi # Display
+ movl %ebp,%eax # argument
+ call hexout # relocation
+ call putstr # message
+#endif
+/*
+ * Set up BTX kernel.
+ */
+ movl $MEM_ESP,%esp # Set up new stack
+ movl $MEM_DATA,%ebx # Data segment
+ movl $m_vers,%esi # Display BTX
+ call putstr # version message
+ movb 0x5(%ebx),%al # Get major version
+ addb $'0',%al # Display
+ call putchr # it
+ movb $'.',%al # And a
+ call putchr # dot
+ movb 0x6(%ebx),%al # Get minor
+ xorb %ah,%ah # version
+ movb $0xa,%dl # Divide
+ divb %dl,%al # by 10
+ addb $'0',%al # Display
+ call putchr # tens
+ movb %ah,%al # Get units
+ addb $'0',%al # Display
+ call putchr # units
+ call putstr # End message
+ movl %ebx,%esi # BTX image
+ movzwl 0x8(%ebx),%edi # Compute
+ orl $PAG_SIZ/PAG_ENT-1,%edi # the
+ incl %edi # BTX
+ shll $0x2,%edi # load
+ addl $MEM_TBL,%edi # address
+ pushl %edi # Save load address
+ movzwl 0xa(%ebx),%ecx # Image size
+#ifdef BTXLDR_VERBOSE
+ pushl %ecx # Save image size
+#endif
+ rep # Relocate
+ movsb # BTX
+ movl %esi,%ebx # Keep place
+#ifdef BTXLDR_VERBOSE
+ movl $m_rel_btx,%esi # Restore
+ popl %eax # parameters
+ call hexout # and
+#endif
+ popl %ebp # display
+#ifdef BTXLDR_VERBOSE
+ movl %ebp,%eax # the
+ call hexout # relocation
+ call putstr # message
+#endif
+ addl $PAG_SIZ,%ebp # Display
+#ifdef BTXLDR_VERBOSE
+ movl $m_base,%esi # the
+ movl %ebp,%eax # user
+ call hexout # base
+ call putstr # address
+#endif
+/*
+ * Set up ELF-format client program.
+ */
+ cmpl $0x464c457f,(%ebx) # ELF magic number?
+ je start.3 # Yes
+ movl $e_fmt,%esi # Display error
+ call putstr # message
+start.2: jmp start.2 # Hang
+start.3:
+#ifdef BTXLDR_VERBOSE
+ movl $m_elf,%esi # Display ELF
+ call putstr # message
+ movl $m_segs,%esi # Format string
+#endif
+ movl $0x2,%edi # Segment count
+ movl 0x1c(%ebx),%edx # Get e_phoff
+ addl %ebx,%edx # To pointer
+ movzwl 0x2c(%ebx),%ecx # Get e_phnum
+start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
+ jne start.6 # No
+#ifdef BTXLDR_VERBOSE
+ movl 0x4(%edx),%eax # Display
+ call hexout # p_offset
+ movl 0x8(%edx),%eax # Display
+ call hexout # p_vaddr
+ movl 0x10(%edx),%eax # Display
+ call hexout # p_filesz
+ movl 0x14(%edx),%eax # Display
+ call hexout # p_memsz
+ call putstr # End message
+#endif
+ pushl %esi # Save
+ pushl %edi # working
+ pushl %ecx # registers
+ movl 0x4(%edx),%esi # Get p_offset
+ addl %ebx,%esi # as pointer
+ movl 0x8(%edx),%edi # Get p_vaddr
+ addl %ebp,%edi # as pointer
+ movl 0x10(%edx),%ecx # Get p_filesz
+ rep # Set up
+ movsb # segment
+ movl 0x14(%edx),%ecx # Any bytes
+ subl 0x10(%edx),%ecx # to zero?
+ jz start.5 # No
+ xorb %al,%al # Then
+ rep # zero
+ stosb # them
+start.5: popl %ecx # Restore
+ popl %edi # working
+ popl %esi # registers
+ decl %edi # Segments to do
+ je start.7 # If none
+start.6: addl $0x20,%edx # To next entry
+ loop start.4 # Till done
+start.7:
+#ifdef BTXLDR_VERBOSE
+ movl $m_done,%esi # Display done
+ call putstr # message
+#endif
+ movl $start.8,%esi # Real mode stub
+ movl $MEM_STUB,%edi # Destination
+ movl $start.9-start.8,%ecx # Size
+ rep # Relocate
+ movsb # it
+ ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
+ .code16
+start.8: xorw %ax,%ax # Data
+ movb $SEL_RDATA,%al # selector
+ movw %ax,%ss # Reload SS
+ movw %ax,%ds # Reset
+ movw %ax,%es # other
+ movw %ax,%fs # segment
+ movw %ax,%gs # limits
+ movl %cr0,%eax # Switch to
+ decw %ax # real
+ movl %eax,%cr0 # mode
+ ljmp $0,$MEM_ENTRY # Jump to BTX entry point
+start.9:
+ .code32
+/*
+ * Output message [ESI] followed by EAX in hex.
+ */
+hexout: pushl %eax # Save
+ call putstr # Display message
+ popl %eax # Restore
+ pushl %esi # Save
+ pushl %edi # caller's
+ movl $buf,%edi # Buffer
+ pushl %edi # Save
+ call hex32 # To hex
+ xorb %al,%al # Terminate
+ stosb # string
+ popl %esi # Restore
+hexout.1: lodsb # Get a char
+ cmpb $'0',%al # Leading zero?
+ je hexout.1 # Yes
+ testb %al,%al # End of string?
+ jne hexout.2 # No
+ decl %esi # Undo
+hexout.2: decl %esi # Adjust for inc
+ call putstr # Display hex
+ popl %edi # Restore
+ popl %esi # caller's
+ ret # To caller
+/*
+ * Output zero-terminated string [ESI] to the console.
+ */
+putstr.0: call putchr # Output char
+putstr: lodsb # Load char
+ testb %al,%al # End of string?
+ jne putstr.0 # No
+ ret # To caller
+/*
+ * Output character AL to the console.
+ */
+putchr: testb $1,muted # Check muted
+ jnz putchr.5 # do a nop
+ pusha # Save
+ xorl %ecx,%ecx # Zero for loops
+ movb $SCR_MAT,%ah # Mode/attribute
+ movl $BDA_POS,%ebx # BDA pointer
+ movw (%ebx),%dx # Cursor position
+ movl $0xb8000,%edi # Regen buffer (color)
+ cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
+ jne putchr.1 # No
+ xorw %di,%di # Regen buffer (mono)
+putchr.1: cmpb $0xa,%al # New line?
+ je putchr.2 # Yes
+ xchgl %eax,%ecx # Save char
+ movb $SCR_COL,%al # Columns per row
+ mulb %dh # * row position
+ addb %dl,%al # + column
+ adcb $0x0,%ah # position
+ shll %eax # * 2
+ xchgl %eax,%ecx # Swap char, offset
+ movw %ax,(%edi,%ecx,1) # Write attr:char
+ incl %edx # Bump cursor
+ cmpb $SCR_COL,%dl # Beyond row?
+ jb putchr.3 # No
+putchr.2: xorb %dl,%dl # Zero column
+ incb %dh # Bump row
+putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
+ jb putchr.4 # No
+ leal 2*SCR_COL(%edi),%esi # New top line
+ movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
+ rep # Scroll
+ movsl # screen
+ movb $' ',%al # Space
+ movb $SCR_COL,%cl # Columns to clear
+ rep # Clear
+ stosw # line
+ movb $SCR_ROW-1,%dh # Bottom line
+putchr.4: movw %dx,(%ebx) # Update position
+ popa # Restore
+putchr.5: ret # To caller
+/*
+ * Convert EAX, AX, or AL to hex, saving the result to [EDI].
+ */
+hex32: pushl %eax # Save
+ shrl $0x10,%eax # Do upper
+ call hex16 # 16
+ popl %eax # Restore
+hex16: call hex16.1 # Do upper 8
+hex16.1: xchgb %ah,%al # Save/restore
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+
+ .data
+ .p2align 4
+/*
+ * Global descriptor table.
+ */
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+gdt.1:
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+/*
+ * Messages.
+ */
+m_logo: .asciz " \nBTX loader 1.00 "
+m_vers: .asciz "BTX version is \0\n"
+e_fmt: .asciz "Error: Client format not supported\n"
+#ifdef BTXLDR_VERBOSE
+m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
+m_esp: .asciz "Arguments passed (esp=\0):\n"
+m_args: .asciz"<howto="
+ .asciz" bootdev="
+ .asciz" junk="
+ .asciz" "
+ .asciz" "
+ .asciz" bootinfo=\0>\n"
+m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
+m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
+m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
+m_base: .asciz "Client base address is \0\n"
+m_elf: .asciz "Client format is ELF\n"
+m_segs: .asciz "text segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+ .asciz "data segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+m_done: .asciz "Loading complete\n"
+#endif
+
+/*
+ * Flags
+ */
+muted: .byte 0x0
+
+/*
+ * Uninitialized data area.
+ */
+buf: # Scratch buffer
diff --git a/usr/src/boot/sys/boot/i386/btx/lib/Makefile b/usr/src/boot/sys/boot/i386/btx/lib/Makefile
new file mode 100644
index 0000000000..a627021b66
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/lib/Makefile
@@ -0,0 +1,45 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+
+CPPFLAGS= -I./../../common
+CFLAGS= -O2 -march=i386 -ffreestanding -mno-mmx -mno-3dnow -mno-sse -mno-sse2
+CFLAGS += -mno-sse3 -msoft-float -m32 -std=gnu99
+AS_CPPFLAGS=
+ASFLAGS=--32
+
+PROG= crt0.o
+SRCS= btxcsu.S btxsys.s btxv86.s
+OBJS= btxcsu.o btxsys.o btxv86.o
+
+LDFLAGS=-Wl,-r -nostdlib
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)
+
+.S.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+clobber: clean
+
+clean:
+ $(RM) $(PROG) $(OBJS)
diff --git a/usr/src/boot/sys/boot/i386/btx/lib/btxcsu.S b/usr/src/boot/sys/boot/i386/btx/lib/btxcsu.S
new file mode 100644
index 0000000000..c46f8097db
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/lib/btxcsu.S
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $FreeBSD$
+
+#include <bootargs.h>
+
+#
+# BTX C startup code (ELF).
+#
+
+#
+# Globals.
+#
+ .global _start
+#
+# Client entry point.
+#
+_start: cld
+ pushl %eax
+ movl $_edata,%edi
+ movl $_end,%ecx
+ subl %edi, %ecx
+ xorb %al, %al
+ rep
+ stosb
+ popl __base
+ movl %esp,%eax # Set
+ addl $ARGADJ,%eax # argument
+ movl %eax,__args # pointer
+ call main # Invoke client main()
+ call exit # Invoke client exit()
+#
+# Data.
+#
+ .comm __base,4 # Client base address
+ .comm __args,4 # Client arguments
diff --git a/usr/src/boot/sys/boot/i386/btx/lib/btxsys.s b/usr/src/boot/sys/boot/i386/btx/lib/btxsys.s
new file mode 100644
index 0000000000..9c77b4295e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/lib/btxsys.s
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $FreeBSD$
+
+#
+# BTX system calls.
+#
+
+#
+# Globals.
+#
+ .global __exit
+ .global __exec
+#
+# Constants.
+#
+ .set INT_SYS,0x30 # Interrupt number
+#
+# System call: exit
+#
+__exit: xorl %eax,%eax # BTX system
+ int $INT_SYS # call 0x0
+#
+# System call: exec
+#
+__exec: movl $0x1,%eax # BTX system
+ int $INT_SYS # call 0x1
diff --git a/usr/src/boot/sys/boot/i386/btx/lib/btxv86.h b/usr/src/boot/sys/boot/i386/btx/lib/btxv86.h
new file mode 100644
index 0000000000..27f6b34042
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/lib/btxv86.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifndef _BTXV86_H_
+#define _BTXV86_H_
+
+#include <sys/types.h>
+#include <machine/psl.h>
+
+#define V86_ADDR 0x10000 /* Segment:offset address */
+#define V86_CALLF 0x20000 /* Emulate far call */
+#define V86_FLAGS 0x40000 /* Return flags */
+
+struct __v86 {
+ uint32_t ctl; /* Control flags */
+ uint32_t addr; /* Interrupt number or address */
+ uint32_t es; /* V86 ES register */
+ uint32_t ds; /* V86 DS register */
+ uint32_t fs; /* V86 FS register */
+ uint32_t gs; /* V86 GS register */
+ uint32_t eax; /* V86 EAX register */
+ uint32_t ecx; /* V86 ECX register */
+ uint32_t edx; /* V86 EDX register */
+ uint32_t ebx; /* V86 EBX register */
+ uint32_t efl; /* V86 eflags register */
+ uint32_t ebp; /* V86 EBP register */
+ uint32_t esi; /* V86 ESI register */
+ uint32_t edi; /* V86 EDI register */
+};
+
+extern struct __v86 __v86; /* V86 interface structure */
+void __v86int(void);
+
+#define v86 __v86
+#define v86int __v86int
+
+extern u_int32_t __base;
+extern u_int32_t __args;
+
+#define PTOV(pa) ((caddr_t)(pa) - __base)
+#define VTOP(va) ((vm_offset_t)(va) + __base)
+#define VTOPSEG(va) (u_int16_t)(VTOP((caddr_t)va) >> 4)
+#define VTOPOFF(va) (u_int16_t)(VTOP((caddr_t)va) & 0xf)
+
+#define V86_CY(x) ((x) & PSL_C)
+#define V86_ZR(x) ((x) & PSL_Z)
+
+void __exit(int) __attribute__((__noreturn__));
+void __exec(caddr_t, ...);
+
+#endif /* !_BTXV86_H_ */
diff --git a/usr/src/boot/sys/boot/i386/btx/lib/btxv86.s b/usr/src/boot/sys/boot/i386/btx/lib/btxv86.s
new file mode 100644
index 0000000000..0d7d111632
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/btx/lib/btxv86.s
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $FreeBSD$
+
+#
+# BTX V86 interface.
+#
+
+#
+# Globals.
+#
+ .global __v86int
+#
+# Fields in V86 interface structure.
+#
+ .set V86_CTL,0x0 # Control flags
+ .set V86_ADDR,0x4 # Int number/address
+ .set V86_ES,0x8 # V86 ES
+ .set V86_DS,0xc # V86 DS
+ .set V86_FS,0x10 # V86 FS
+ .set V86_GS,0x14 # V86 GS
+ .set V86_EAX,0x18 # V86 EAX
+ .set V86_ECX,0x1c # V86 ECX
+ .set V86_EDX,0x20 # V86 EDX
+ .set V86_EBX,0x24 # V86 EBX
+ .set V86_EFL,0x28 # V86 eflags
+ .set V86_EBP,0x2c # V86 EBP
+ .set V86_ESI,0x30 # V86 ESI
+ .set V86_EDI,0x34 # V86 EDI
+#
+# Other constants.
+#
+ .set INT_V86,0x31 # Interrupt number
+ .set SIZ_V86,0x38 # Size of V86 structure
+#
+# V86 interface function.
+#
+__v86int: popl __v86ret # Save return address
+ pushl $__v86 # Push pointer
+ call __v86_swap # Load V86 registers
+ int $INT_V86 # To BTX
+ call __v86_swap # Load user registers
+ addl $0x4,%esp # Discard pointer
+ pushl __v86ret # Restore return address
+ ret # To user
+#
+# Swap V86 and user registers.
+#
+__v86_swap: xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
+ xchgl %eax,V86_EAX(%ebp) # Swap EAX
+ xchgl %ecx,V86_ECX(%ebp) # Swap ECX
+ xchgl %edx,V86_EDX(%ebp) # Swap EDX
+ xchgl %ebx,V86_EBX(%ebp) # Swap EBX
+ pushl %eax # Save
+ pushf # Put eflags
+ popl %eax # in EAX
+ xchgl %eax,V86_EFL(%ebp) # Swap
+ pushl %eax # Put EAX
+ popf # in eflags
+ movl 0x8(%esp,1),%eax # Load EBP
+ xchgl %eax,V86_EBP(%ebp) # Swap
+ movl %eax,0x8(%esp,1) # Save EBP
+ popl %eax # Restore
+ xchgl %esi,V86_ESI(%ebp) # Swap ESI
+ xchgl %edi,V86_EDI(%ebp) # Swap EDI
+ xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
+ ret # To caller
+#
+# V86 interface structure.
+#
+ .comm __v86,SIZ_V86
+ .comm __v86ret,4
diff --git a/usr/src/boot/sys/boot/i386/cdboot/Makefile b/usr/src/boot/sys/boot/i386/cdboot/Makefile
new file mode 100644
index 0000000000..37d06f9fab
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/cdboot/Makefile
@@ -0,0 +1,55 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+ROOT_BOOT = $(ROOT)/boot
+
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+
+CFLAGS = -O2 -I../common -march=i386 -ffreestanding -mno-mmx -mno-3dnow
+CFLAGS += -mno-sse -mno-sse2 -mno-sse3 -msoft-float -std=gnu99 -m32
+CPPFLAGS=
+CCASFLAGS= -Wa,--divide
+
+PROG= cdboot
+STRIP=
+FILEMODE=0444
+MAN=
+SRCS= ${PROG}.S
+OBJS= $(SRCS:%.S=%.o)
+
+
+ORG= 0x7c00
+
+LDFLAGS=-e start -Ttext ${ORG} -N -S --oformat binary
+
+all: ${PROG}
+
+install: $(PROG:%=$(ROOT_BOOT)/%)
+
+${PROG}: ${OBJS}
+ ${LD} ${LDFLAGS} -o $@ $^
+
+clobber: clean
+clean:
+ $(RM) $(PROG) $(OBJS)
+
+.S.o:
+ $(CC) $(CFLAGS) $(CCASFLAGS) -c -o $@ $<
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/i386/cdboot/cdboot.S b/usr/src/boot/sys/boot/i386/cdboot/cdboot.S
new file mode 100644
index 0000000000..5d88bffcaa
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/cdboot/cdboot.S
@@ -0,0 +1,602 @@
+#
+# Copyright (c) 2001 John Baldwin <jhb@FreeBSD.org>
+# 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+
+# $FreeBSD$
+
+#
+# This program is a freestanding boot program to load an a.out binary
+# from a CD-ROM booted with no emulation mode as described by the El
+# Torito standard. Due to broken BIOSen that do not load the desired
+# number of sectors, we try to fit this in as small a space as possible.
+#
+# Basically, we first create a set of boot arguments to pass to the loaded
+# binary. Then we attempt to load /boot/loader from the CD we were booted
+# off of.
+#
+
+#include <bootargs.h>
+
+#
+# Memory locations.
+#
+ .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
+ .set MEM_ARG,0x900 # Arguments at start
+ .set MEM_ARG_BTX,0xa100 # Where we move them to so the
+ # BTX client can see them
+ .set MEM_ARG_SIZE,0x18 # Size of the arguments
+ .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
+ .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
+ .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
+ .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
+#
+# a.out header fields
+#
+ .set AOUT_TEXT,0x04 # text segment size
+ .set AOUT_DATA,0x08 # data segment size
+ .set AOUT_BSS,0x0c # zero'd BSS size
+ .set AOUT_SYMBOLS,0x10 # symbol table
+ .set AOUT_ENTRY,0x14 # entry point
+ .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
+#
+# Segment selectors.
+#
+ .set SEL_SDATA,0x8 # Supervisor data
+ .set SEL_RDATA,0x10 # Real mode data
+ .set SEL_SCODE,0x18 # PM-32 code
+ .set SEL_SCODE16,0x20 # PM-16 code
+#
+# BTX constants
+#
+ .set INT_SYS,0x30 # BTX syscall interrupt
+#
+# Constants for reading from the CD.
+#
+ .set ERROR_TIMEOUT,0x80 # BIOS timeout on read
+ .set NUM_RETRIES,3 # Num times to retry
+ .set SECTOR_SIZE,0x800 # size of a sector
+ .set SECTOR_SHIFT,11 # number of place to shift
+ .set BUFFER_LEN,0x100 # number of sectors in buffer
+ .set MAX_READ,0x10000 # max we can read at a time
+ .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
+ .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
+ .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
+ .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
+ .set VOLDESC_LBA,0x10 # LBA of vol descriptor
+ .set VD_PRIMARY,1 # Primary VD
+ .set VD_END,255 # VD Terminator
+ .set VD_ROOTDIR,156 # Offset of Root Dir Record
+ .set DIR_LEN,0 # Offset of Dir Record length
+ .set DIR_EA_LEN,1 # Offset of EA length
+ .set DIR_EXTENT,2 # Offset of 64-bit LBA
+ .set DIR_SIZE,10 # Offset of 64-bit length
+ .set DIR_NAMELEN,32 # Offset of 8-bit name len
+ .set DIR_NAME,33 # Offset of dir name
+#
+# We expect to be loaded by the BIOS at 0x7c00 (standard boot loader entry
+# point)
+#
+ .code16
+ .globl start
+ .org 0x0, 0x0
+#
+# Program start.
+#
+start: jmp real_start
+ .org 0x8, 0x8
+
+bi_pvd: .long VOLDESC_LBA # LBA of primary volume desc
+bi_file: .long 0 # LBA of boot file.
+bi_length: .long 0 # Length of boot file.
+bi_csum: .long 0 # Checksum of boot file
+bi_reserved: .space (10*4) # Reserved
+
+real_start: cld # string ops inc
+ xor %ax,%ax # zero %ax
+ mov %ax,%ss # setup the
+ mov $start,%sp # stack
+ mov %ax,%ds # setup the
+ mov %ax,%es # data segments
+ mov %dl,drive # Save BIOS boot device
+ mov $msg_welcome,%si # %ds:(%si) -> welcome message
+ call putstr # display the welcome message
+#
+# Setup the arguments that the loader is expecting from boot[12]
+#
+ mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
+ call putstr # display the message
+ mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
+ mov %bx,%di # %es:(%di) -> boot args
+ xor %eax,%eax # zero %eax
+ mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
+ # dwords
+ rep # Clear the arguments
+ stosl # to zero
+ mov drive,%dl # Store BIOS boot device
+ mov %dl,0x4(%bx) # in kargs->bootdev
+ or $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
+ # KARGS_FLAGS_CD
+#
+# Load Volume Descriptor
+#
+ mov $VOLDESC_LBA,%eax # Set LBA of first VD
+load_vd: push %eax # Save %eax
+ mov $1,%dh # One sector
+ mov $MEM_VOLDESC,%ebx # Destination
+ call read # Read it in
+ cmpb $VD_PRIMARY,(%bx) # Primary VD?
+ je have_vd # Yes
+ pop %eax # Prepare to
+ inc %eax # try next
+ cmpb $VD_END,(%bx) # Last VD?
+ jne load_vd # No, read next
+ mov $msg_novd,%si # No VD
+ jmp error # Halt
+have_vd: # Have Primary VD
+#
+# Try to look up the loader binary using the paths in the loader_paths
+# array.
+#
+ mov $loader_paths,%si # Point to start of array
+lookup_path: push %si # Save file name pointer
+ call lookup # Try to find file
+ pop %di # Restore file name pointer
+ jnc lookup_found # Found this file
+ xor %al,%al # Look for next
+ mov $0xffff,%cx # path name by
+ repnz # scanning for
+ scasb # nul char
+ mov %di,%si # Point %si at next path
+ mov (%si),%al # Get first char of next path
+ or %al,%al # Is it double nul?
+ jnz lookup_path # No, try it.
+ mov $msg_failed,%si # Failed message
+ jmp error # Halt
+lookup_found: # Found a loader file
+#
+# Load the binary into the buffer. Due to real mode addressing limitations
+# we have to read it in 64k chunks.
+#
+ mov DIR_SIZE(%bx),%eax # Read file length
+ add $SECTOR_SIZE-1,%eax # Convert length to sectors
+ shr $SECTOR_SHIFT,%eax
+ cmp $BUFFER_LEN,%eax
+ jbe load_sizeok
+ mov $msg_load2big,%si # Error message
+ call error
+load_sizeok: movzbw %al,%cx # Num sectors to read
+ mov DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended
+ mov $MEM_READ_BUFFER,%ebx # Read into the buffer
+load_loop: mov %cl,%dh
+ cmp $MAX_READ_SEC,%cl # Truncate to max read size
+ jbe load_notrunc
+ mov $MAX_READ_SEC,%dh
+load_notrunc: sub %dh,%cl # Update count
+ push %eax # Save
+ call read # Read it in
+ pop %eax # Restore
+ add $MAX_READ_SEC,%eax # Update LBA
+ add $MAX_READ,%ebx # Update dest addr
+ jcxz load_done # Done?
+ jmp load_loop # Keep going
+load_done:
+#
+# Turn on the A20 address line
+#
+ call seta20 # Turn A20 on
+#
+# Relocate the loader and BTX using a very lazy protected mode
+#
+ mov $msg_relocate,%si # Display the
+ call putstr # relocation message
+ mov MEM_READ_BUFFER+AOUT_ENTRY,%edi # %edi is the destination
+ mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
+ # the start of the text
+ # segment
+ mov MEM_READ_BUFFER+AOUT_TEXT,%ecx # %ecx = length of the text
+ # segment
+ push %edi # Save entry point for later
+ lgdt gdtdesc # setup our own gdt
+ cli # turn off interrupts
+ mov %cr0,%eax # Turn on
+ or $0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $SEL_SCODE,$pm_start # long jump to clear the
+ # instruction pre-fetch queue
+ .code32
+pm_start: mov $SEL_SDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a flat selector
+ rep # Relocate the
+ movsb # text segment
+ add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
+ and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
+ mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
+ rep # Relocate the
+ movsb # data segment
+ mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
+ xor %eax,%eax # zero %eax
+ add $3,%cl # round %ecx up to
+ shr $2,%ecx # a multiple of 4
+ rep # zero the
+ stosl # bss
+ mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
+ add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
+ mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
+ movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
+ rep # Relocate
+ movsb # BTX
+ ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
+ .code16
+pm_16: mov $SEL_RDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a real mode selector
+ mov %cr0,%eax # Turn off
+ and $~0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $0,$pm_end # Long jump to clear the
+ # instruction pre-fetch queue
+pm_end: sti # Turn interrupts back on now
+#
+# Copy the BTX client to MEM_BTX_CLIENT
+#
+ xor %ax,%ax # zero %ax and set
+ mov %ax,%ds # %ds and %es
+ mov %ax,%es # to segment 0
+ mov $MEM_BTX_CLIENT,%di # Prepare to relocate
+ mov $btx_client,%si # the simple btx client
+ mov $(btx_client_end-btx_client),%cx # length of btx client
+ rep # Relocate the
+ movsb # simple BTX client
+#
+# Copy the boot[12] args to where the BTX client can see them
+#
+ mov $MEM_ARG,%si # where the args are at now
+ mov $MEM_ARG_BTX,%di # where the args are moving to
+ mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
+ rep # Relocate
+ movsl # the words
+#
+# Save the entry point so the client can get to it later on
+#
+ pop %eax # Restore saved entry point
+ stosl # and add it to the end of
+ # the arguments
+#
+# Now we just start up BTX and let it do the rest
+#
+ mov $msg_jump,%si # Display the
+ call putstr # jump message
+ ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
+
+#
+# Lookup the file in the path at [SI] from the root directory.
+#
+# Trashes: All but BX
+# Returns: CF = 0 (success), BX = pointer to record
+# CF = 1 (not found)
+#
+lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
+ push %si
+ mov $msg_lookup,%si # Display lookup message
+ call putstr
+ pop %si
+ push %si
+ call putstr
+ mov $msg_lookup2,%si
+ call putstr
+ pop %si
+lookup_dir: lodsb # Get first char of path
+ cmp $0,%al # Are we done?
+ je lookup_done # Yes
+ cmp $'/',%al # Skip path separator.
+ je lookup_dir
+ dec %si # Undo lodsb side effect
+ call find_file # Lookup first path item
+ jnc lookup_dir # Try next component
+ mov $msg_lookupfail,%si # Not found message
+ call putstr
+ stc # Set carry
+ ret
+ jmp error
+lookup_done: mov $msg_lookupok,%si # Success message
+ call putstr
+ clc # Clear carry
+ ret
+
+#
+# Lookup file at [SI] in directory whose record is at [BX].
+#
+# Trashes: All but returns
+# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
+# CF = 1 (not found), SI = preserved
+#
+find_file: mov DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended attributes
+ mov %eax,rec_lba # Save LBA
+ mov DIR_SIZE(%bx),%eax # Save size
+ mov %eax,rec_size
+ xor %cl,%cl # Zero length
+ push %si # Save
+ff.namelen: inc %cl # Update length
+ lodsb # Read char
+ cmp $0,%al # Nul?
+ je ff.namedone # Yes
+ cmp $'/',%al # Path separator?
+ jnz ff.namelen # No, keep going
+ff.namedone: dec %cl # Adjust length and save
+ mov %cl,name_len
+ pop %si # Restore
+ff.load: mov rec_lba,%eax # Load LBA
+ mov $MEM_DIR,%ebx # Address buffer
+ mov $1,%dh # One sector
+ call read # Read directory block
+ incl rec_lba # Update LBA to next block
+ff.scan: mov %ebx,%edx # Check for EOF
+ sub $MEM_DIR,%edx
+ cmp %edx,rec_size
+ ja ff.scan.1
+ stc # EOF reached
+ ret
+ff.scan.1: cmpb $0,DIR_LEN(%bx) # Last record in block?
+ je ff.nextblock
+ push %si # Save
+ movzbw DIR_NAMELEN(%bx),%si # Find end of string
+ff.checkver: cmpb $'0',DIR_NAME-1(%bx,%si) # Less than '0'?
+ jb ff.checkver.1
+ cmpb $'9',DIR_NAME-1(%bx,%si) # Greater than '9'?
+ ja ff.checkver.1
+ dec %si # Next char
+ jnz ff.checkver
+ jmp ff.checklen # All numbers in name, so
+ # no version
+ff.checkver.1: movzbw DIR_NAMELEN(%bx),%cx
+ cmp %cx,%si # Did we find any digits?
+ je ff.checkdot # No
+ cmpb $';',DIR_NAME-1(%bx,%si) # Check for semicolon
+ jne ff.checkver.2
+ dec %si # Skip semicolon
+ mov %si,%cx
+ mov %cl,DIR_NAMELEN(%bx) # Adjust length
+ jmp ff.checkdot
+ff.checkver.2: mov %cx,%si # Restore %si to end of string
+ff.checkdot: cmpb $'.',DIR_NAME-1(%bx,%si) # Trailing dot?
+ jne ff.checklen # No
+ decb DIR_NAMELEN(%bx) # Adjust length
+ff.checklen: pop %si # Restore
+ movzbw name_len,%cx # Load length of name
+ cmp %cl,DIR_NAMELEN(%bx) # Does length match?
+ je ff.checkname # Yes, check name
+ff.nextrec: add DIR_LEN(%bx),%bl # Next record
+ adc $0,%bh
+ jmp ff.scan
+ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
+ jnc ff.load # If subtract ok, keep going
+ ret # End of file, so not found
+ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
+ push %si # Save
+ repe cmpsb # Compare name
+ je ff.match # We have a winner!
+ pop %si # Restore
+ jmp ff.nextrec # Keep looking.
+ff.match: add $2,%sp # Discard saved %si
+ clc # Clear carry
+ ret
+
+#
+# Load DH sectors starting at LBA EAX into [EBX].
+#
+# Trashes: EAX
+#
+read: push %si # Save
+ push %cx # Save since some BIOSs trash
+ mov %eax,edd_lba # LBA to read from
+ mov %ebx,%eax # Convert address
+ shr $4,%eax # to segment
+ mov %ax,edd_addr+0x2 # and store
+read.retry: call twiddle # Entertain the user
+ push %dx # Save
+ mov $edd_packet,%si # Address Packet
+ mov %dh,edd_len # Set length
+ mov drive,%dl # BIOS Device
+ mov $0x42,%ah # BIOS: Extended Read
+ int $0x13 # Call BIOS
+ pop %dx # Restore
+ jc read.fail # Worked?
+ pop %cx # Restore
+ pop %si
+ ret # Return
+read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
+ je read.retry # Yes, Retry.
+read.error: mov %ah,%al # Save error
+ mov $hex_error,%di # Format it
+ call hex8 # as hex
+ mov $msg_badread,%si # Display Read error message
+
+#
+# Display error message at [SI] and halt.
+#
+error: call putstr # Display message
+halt: hlt
+ jmp halt # Spin
+
+#
+# Display a null-terminated string.
+#
+# Trashes: AX, SI
+#
+putstr: push %bx # Save
+putstr.load: lodsb # load %al from %ds:(%si)
+ test %al,%al # stop at null
+ jnz putstr.putc # if the char != null, output it
+ pop %bx # Restore
+ ret # return when null is hit
+putstr.putc: call putc # output char
+ jmp putstr.load # next char
+
+#
+# Display a single char.
+#
+putc: mov $0x7,%bx # attribute for output
+ mov $0xe,%ah # BIOS: put_char
+ int $0x10 # call BIOS, print char in %al
+ ret # Return to caller
+
+#
+# Output the "twiddle"
+#
+twiddle: push %ax # Save
+ push %bx # Save
+ mov twiddle_index,%al # Load index
+ mov $twiddle_chars,%bx # Address table
+ inc %al # Next
+ and $3,%al # char
+ mov %al,twiddle_index # Save index for next call
+ xlat # Get char
+ call putc # Output it
+ mov $8,%al # Backspace
+ call putc # Output it
+ pop %bx # Restore
+ pop %ax # Restore
+ ret
+
+#
+# Enable A20. Put an upper limit on the amount of time we wait for the
+# keyboard controller to get ready (65K x ISA access time). If
+# we wait more than that amount, the hardware is probably
+# legacy-free and simply doesn't have a keyboard controller.
+# Thus, the A20 line is already enabled.
+#
+seta20: cli # Disable interrupts
+ xor %cx,%cx # Clear
+seta20.1: inc %cx # Increment, overflow?
+ jz seta20.3 # Yes
+ in $0x64,%al # Get status
+ test $0x2,%al # Busy?
+ jnz seta20.1 # Yes
+ mov $0xd1,%al # Command: Write
+ out %al,$0x64 # output port
+seta20.2: in $0x64,%al # Get status
+ test $0x2,%al # Busy?
+ jnz seta20.2 # Yes
+ mov $0xdf,%al # Enable
+ out %al,$0x60 # A20
+seta20.3: sti # Enable interrupts
+ ret # To caller
+
+#
+# Convert AL to hex, saving the result to [EDI].
+#
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+
+#
+# BTX client to start btxldr
+#
+ .code32
+btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
+ # %ds:(%esi) -> end
+ # of boot[12] args
+ mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
+ std # Go backwards
+push_arg: lodsl # Read argument
+ push %eax # Push it onto the stack
+ loop push_arg # Push all of the arguments
+ cld # In case anyone depends on this
+ pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
+ # the loader
+ push %eax # Emulate a near call
+ mov $0x1,%eax # 'exec' system call
+ int $INT_SYS # BTX system call
+btx_client_end:
+ .code16
+
+ .p2align 4
+#
+# Global descriptor table.
+#
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE (32-bit)
+ .word 0xffff,0x0,0x9a00,0x8f # SEL_SCODE16 (16-bit)
+gdt.1:
+#
+# Pseudo-descriptors.
+#
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+#
+# EDD Packet
+#
+edd_packet: .byte 0x10 # Length
+ .byte 0 # Reserved
+edd_len: .byte 0x0 # Num to read
+ .byte 0 # Reserved
+edd_addr: .word 0x0,0x0 # Seg:Off
+edd_lba: .quad 0x0 # LBA
+
+drive: .byte 0
+
+#
+# State for searching dir
+#
+rec_lba: .long 0x0 # LBA (adjusted for EA)
+rec_size: .long 0x0 # File size
+name_len: .byte 0x0 # Length of current name
+
+twiddle_index: .byte 0x0
+
+msg_welcome: .asciz "CD Loader 1.2\r\n\n"
+msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
+msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
+msg_jump: .asciz "Starting the BTX loader\r\n"
+msg_badread: .ascii "Read Error: 0x"
+hex_error: .asciz "00\r\n"
+msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
+msg_lookup: .asciz "Looking up "
+msg_lookup2: .asciz "... "
+msg_lookupok: .asciz "Found\r\n"
+msg_lookupfail: .asciz "File not found\r\n"
+msg_load2big: .asciz "File too big\r\n"
+msg_failed: .asciz "Boot failed\r\n"
+twiddle_chars: .ascii "|/-\\"
+loader_paths: .asciz "/BOOT/ZFSLOADER"
+ .asciz "/boot/zfsloader"
+ .byte 0
diff --git a/usr/src/boot/sys/boot/i386/common/bootargs.h b/usr/src/boot/sys/boot/i386/common/bootargs.h
new file mode 100644
index 0000000000..4768d68ae1
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/bootargs.h
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOT_I386_ARGS_H_
+#define _BOOT_I386_ARGS_H_
+
+#define KARGS_FLAGS_CD 0x1
+#define KARGS_FLAGS_PXE 0x2
+#define KARGS_FLAGS_ZFS 0x4
+#define KARGS_FLAGS_EXTARG 0x8 /* variably sized extended argument */
+
+#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */
+#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */
+#define BA_BOOTINFO 20 /* offsetof(struct bootargs, bootinfo) */
+#define BI_SIZE 48 /* offsetof(struct bootinfo, bi_size) */
+
+/*
+ * We reserve some space above BTX allocated stack for the arguments
+ * and certain data that could hang off them. Currently only struct bootinfo
+ * is supported in that category. The bootinfo is placed at the top
+ * of the arguments area and the actual arguments are placed at ARGOFF offset
+ * from the top and grow towards the top. Hopefully we have enough space
+ * for bootinfo and the arguments to not run into each other.
+ * Arguments area below ARGOFF is reserved for future use.
+ */
+#define ARGSPACE 0x1000 /* total size of the BTX args area */
+#define ARGOFF 0x800 /* actual args offset within the args area */
+#define ARGADJ (ARGSPACE - ARGOFF)
+
+#ifndef __ASSEMBLER__
+
+struct bootargs
+{
+ uint32_t howto;
+ uint32_t bootdev;
+ uint32_t bootflags;
+ union {
+ struct {
+ uint32_t pxeinfo;
+ uint32_t reserved;
+ };
+ uint64_t zfspool;
+ };
+ uint32_t bootinfo;
+
+ /*
+ * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields
+ * are followed by a uint32_t field that specifies a size of the
+ * extended arguments (including the size field).
+ */
+};
+
+#endif /*__ASSEMBLER__*/
+
+#endif /* !_BOOT_I386_ARGS_H_ */
diff --git a/usr/src/boot/sys/boot/i386/common/cons.c b/usr/src/boot/sys/boot/i386/common/cons.c
new file mode 100644
index 0000000000..90fa99eda5
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/cons.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+
+#include <machine/psl.h>
+
+#include <btxv86.h>
+
+#include "lib.h"
+#include "rbx.h"
+#include "util.h"
+#include "cons.h"
+
+#define SECOND 18 /* Circa that many ticks in a second. */
+
+uint8_t ioctrl = IO_KEYBOARD;
+
+void
+putc(int c)
+{
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x10;
+ v86.eax = 0xe00 | (c & 0xff);
+ v86.ebx = 0x7;
+ v86int();
+}
+
+void
+xputc(int c)
+{
+
+ if (ioctrl & IO_KEYBOARD)
+ putc(c);
+ if (ioctrl & IO_SERIAL)
+ sio_putc(c);
+}
+
+void
+putchar(int c)
+{
+
+ if (c == '\n')
+ xputc('\r');
+ xputc(c);
+}
+
+int
+getc(int fn)
+{
+
+ /*
+ * The extra comparison against zero is an attempt to work around
+ * what appears to be a bug in QEMU and Bochs. Both emulators
+ * sometimes report a key-press with scancode one and ascii zero
+ * when no such key is pressed in reality. As far as I can tell,
+ * this only happens shortly after a reboot.
+ */
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x16;
+ v86.eax = fn << 8;
+ v86int();
+ return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff));
+}
+
+int
+xgetc(int fn)
+{
+
+ if (OPT_CHECK(RBX_NOINTR))
+ return (0);
+ for (;;) {
+ if (ioctrl & IO_KEYBOARD && getc(1))
+ return (fn ? 1 : getc(0));
+ if (ioctrl & IO_SERIAL && sio_ischar())
+ return (fn ? 1 : sio_getc());
+ if (fn)
+ return (0);
+ }
+ /* NOTREACHED */
+}
+
+int
+keyhit(unsigned int secs)
+{
+ uint32_t t0, t1;
+
+ if (OPT_CHECK(RBX_NOINTR))
+ return (0);
+ secs *= SECOND;
+ t0 = 0;
+ for (;;) {
+ if (xgetc(1))
+ return (1);
+ if (secs > 0) {
+ t1 = *(uint32_t *)PTOV(0x46c);
+ if (!t0)
+ t0 = t1;
+ if (t1 < t0 || t1 >= t0 + secs)
+ return (0);
+ }
+ }
+ /* NOTREACHED */
+}
+
+void
+getstr(char *cmdstr, size_t cmdstrsize)
+{
+ char *s;
+ int c;
+
+ s = cmdstr;
+ for (;;) {
+ switch (c = xgetc(0)) {
+ case 0:
+ break;
+ case '\177':
+ case '\b':
+ if (s > cmdstr) {
+ s--;
+ printf("\b \b");
+ }
+ break;
+ case '\n':
+ case '\r':
+ *s = 0;
+ return;
+ default:
+ if (s - cmdstr < cmdstrsize - 1)
+ *s++ = c;
+ putchar(c);
+ break;
+ }
+ }
+}
+
+int
+getchar(void)
+{
+ return (xgetc(0));
+}
diff --git a/usr/src/boot/sys/boot/i386/common/cons.h b/usr/src/boot/sys/boot/i386/common/cons.h
new file mode 100644
index 0000000000..8add66fa3f
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/cons.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _CONS_H_
+#define _CONS_H_
+
+#define IO_KEYBOARD 1
+#define IO_SERIAL 2
+
+extern uint8_t ioctrl;
+
+void putc(int c);
+void xputc(int c);
+int getchar(void);
+void putchar(int c);
+int getc(int fn);
+int xgetc(int fn);
+int keyhit(unsigned int secs);
+void getstr(char *cmdstr, size_t cmdstrsize);
+
+#endif /* !_CONS_H_ */
diff --git a/usr/src/boot/sys/boot/i386/common/drv.c b/usr/src/boot/sys/boot/i386/common/drv.c
new file mode 100644
index 0000000000..52933d5d52
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/drv.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <btxv86.h>
+
+#include "rbx.h"
+#include "util.h"
+#include "drv.h"
+#include "edd.h"
+#ifdef USE_XREAD
+#include "xreadorg.h"
+#endif
+
+#ifdef GPT
+static struct edd_params params;
+
+uint64_t
+drvsize(struct dsk *dskp)
+{
+
+ params.len = sizeof(struct edd_params);
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4800;
+ v86.edx = dskp->drive;
+ v86.ds = VTOPSEG(&params);
+ v86.esi = VTOPOFF(&params);
+ v86int();
+ if (V86_CY(v86.efl)) {
+ printf("error %u\n", v86.eax >> 8 & 0xff);
+ return (0);
+ }
+ return (params.sectors);
+}
+#endif /* GPT */
+
+#ifndef USE_XREAD
+static struct edd_packet packet;
+#endif
+
+int
+drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
+{
+ static unsigned c = 0x2d5c7c2f;
+
+ if (!OPT_CHECK(RBX_QUIET))
+ printf("%c\b", c = c << 8 | c >> 24);
+#ifndef USE_XREAD
+ packet.len = sizeof(struct edd_packet);
+ packet.count = nblk;
+ packet.off = VTOPOFF(buf);
+ packet.seg = VTOPSEG(buf);
+ packet.lba = lba;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4200;
+ v86.edx = dskp->drive;
+ v86.ds = VTOPSEG(&packet);
+ v86.esi = VTOPOFF(&packet);
+#else /* USE_XREAD */
+ v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+ v86.addr = XREADORG; /* call to xread in boot1 */
+ v86.es = VTOPSEG(buf);
+ v86.eax = lba;
+ v86.ebx = VTOPOFF(buf);
+ v86.ecx = lba >> 32;
+ v86.edx = nblk << 8 | dskp->drive;
+#endif /* USE_XREAD */
+ v86int();
+ if (V86_CY(v86.efl)) {
+ printf("%s: error %u lba %u\n",
+ BOOTPROG, v86.eax >> 8 & 0xff, lba);
+ return (-1);
+ }
+ return (0);
+}
+
+#ifdef GPT
+int
+drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
+{
+
+ packet.len = sizeof(struct edd_packet);
+ packet.count = nblk;
+ packet.off = VTOPOFF(buf);
+ packet.seg = VTOPSEG(buf);
+ packet.lba = lba;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4300;
+ v86.edx = dskp->drive;
+ v86.ds = VTOPSEG(&packet);
+ v86.esi = VTOPOFF(&packet);
+ v86int();
+ if (V86_CY(v86.efl)) {
+ printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
+ return (-1);
+ }
+ return (0);
+}
+#endif /* GPT */
diff --git a/usr/src/boot/sys/boot/i386/common/drv.h b/usr/src/boot/sys/boot/i386/common/drv.h
new file mode 100644
index 0000000000..1ecfbc3af9
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/drv.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DRV_H_
+#define _DRV_H_
+
+struct dsk {
+ unsigned int drive;
+ unsigned int type;
+ unsigned int unit;
+ unsigned int slice;
+ int part;
+ daddr_t start;
+ int init;
+};
+
+int drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk);
+#ifdef GPT
+int drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk);
+uint64_t drvsize(struct dsk *dskp);
+#endif /* GPT */
+
+#endif /* !_DRV_H_ */
diff --git a/usr/src/boot/sys/boot/i386/common/edd.h b/usr/src/boot/sys/boot/i386/common/edd.h
new file mode 100644
index 0000000000..7d1f45020f
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/common/edd.h
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2011 Hudson River Trading LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _EDD_H_
+#define _EDD_H_
+
+/* Supported interfaces for "Check Extensions Present". */
+#define EDD_INTERFACE_FIXED_DISK 0x01
+#define EDD_INTERFACE_EJECT 0x02
+#define EDD_INTERFACE_EDD 0x04
+
+struct edd_packet {
+ uint16_t len;
+ uint16_t count;
+ uint16_t off;
+ uint16_t seg;
+ uint64_t lba;
+};
+
+struct edd_packet_v3 {
+ uint16_t len;
+ uint16_t count;
+ uint16_t off;
+ uint16_t seg;
+ uint64_t lba;
+ uint64_t phys_addr;
+};
+
+struct edd_params {
+ uint16_t len;
+ uint16_t flags;
+ uint32_t cylinders;
+ uint32_t heads;
+ uint32_t sectors_per_track;
+ uint64_t sectors;
+ uint16_t sector_size;
+ uint16_t edd_params_seg;
+ uint16_t edd_params_off;
+} __packed;
+
+struct edd_device_path_v3 {
+ uint16_t key;
+ uint8_t len;
+ uint8_t reserved[3];
+ char host_bus[4];
+ char interface[8];
+ uint64_t interface_path;
+ uint64_t device_path;
+ uint8_t reserved2[1];
+ uint8_t checksum;
+} __packed;
+
+struct edd_params_v3 {
+ struct edd_params params;
+ struct edd_device_path_v3 device_path;
+} __packed;
+
+struct edd_device_path_v4 {
+ uint16_t key;
+ uint8_t len;
+ uint8_t reserved[3];
+ char host_bus[4];
+ char interface[8];
+ uint64_t interface_path;
+ uint64_t device_path[2];
+ uint8_t reserved2[1];
+ uint8_t checksum;
+} __packed;
+
+struct edd_params_v4 {
+ struct edd_params params;
+ struct edd_device_path_v4 device_path;
+} __packed;
+
+#define EDD_FLAGS_DMA_BOUNDARY_HANDLING 0x0001
+#define EDD_FLAGS_REMOVABLE_MEDIA 0x0002
+#define EDD_FLAGS_WRITE_VERIFY 0x0004
+#define EDD_FLAGS_MEDIA_CHANGE_NOTIFICATION 0x0008
+#define EDD_FLAGS_LOCKABLE_MEDIA 0x0010
+#define EDD_FLAGS_NO_MEDIA_PRESENT 0x0020
+
+#define EDD_DEVICE_PATH_KEY 0xbedd
+
+#endif /* !_EDD_H_ */
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/Makefile b/usr/src/boot/sys/boot/i386/gptzfsboot/Makefile
new file mode 100644
index 0000000000..6147c3a947
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/Makefile
@@ -0,0 +1,144 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+#
+
+include $(SRC)/Makefile.master
+
+AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+OBJCOPY= $(GNU_ROOT)/bin/gobjcopy
+
+PROG= gptzfsboot
+MAN= gptzfsboot.8
+FILEMODE=0444
+
+# need to update this to trigger installboot updates.
+BUILDDATE :sh = TZ=UTC date +%Y%m%dT%H%M%SZ
+BOOT2_VERSION= 1.1:$(BUILDDATE)
+
+BOOT_COMCONSOLE_PORT= 0x3f8
+BOOT_COMCONSOLE_SPEED= 9600
+B2SIOFMT= 0x3
+
+REL1= 0x700
+ORG1= 0x7c00
+ORG2= 0x0
+
+CPPFLAGS=
+CFLAGS= -nostdinc -DBOOTPROG=\"gptzfsboot\" \
+ -O1 \
+ -DGPT -DBOOT2 \
+ -DLOADER_MBR_SUPPORT -DLOADER_GPT_SUPPORT \
+ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \
+ -DSIOFMT=${B2SIOFMT} \
+ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
+ -I../../../../include \
+ -I../../../../lib/libstand \
+ -I../../common \
+ -I../common \
+ -I../../zfs \
+ -I../../../cddl/boot/zfs \
+ -I../btx/lib -I. \
+ -I../../.. \
+ -I../../../sys \
+ -I../libi386 \
+ -Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
+ -Wpointer-arith -Wshadow -Wwrite-strings \
+ -Winline -Wno-unknown-pragmas
+
+CFLAGS += --param max-inline-insns-single=100
+CFLAGS += -fno-reorder-functions
+
+LD_FLAGS=-static -N --gc-sections
+CCASFLAGS=-Wa,--divide
+LIBSTAND= ../../libstand/i386/libstand.a
+LIBZFSBOOT= ../../zfs/i386/libzfsboot.a
+
+include ../Makefile.inc
+
+.PARALLEL:
+
+all: machine x86 $(PROG)
+
+install: all $(ROOTBOOTPROG)
+
+OBJS = multiboot.o zfsboot.o sio.o cons.o panic.o devopen.o \
+ part.o biosmem.o smbios.o biosdisk.o devicename.o disk.o bcache.o \
+ time.o crc32.o
+
+CLEANFILES= gptzfsboot $(OBJS)
+
+gptzfsboot: gptldr.bin gptzfsboot.bin ${BTXKERN}
+ $(BTXLD) -v -E ${ORG2} -f bin -b ${BTXKERN} -V ${BOOT2_VERSION} -l \
+ gptldr.bin -o $@ gptzfsboot.bin
+
+CLEANFILES += gptldr.bin gptldr.out gptldr.o
+
+gptldr.bin: gptldr.out
+ ${OBJCOPY} -S -O binary gptldr.out $@
+
+gptldr.out: gptldr.o
+ ${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o $@ gptldr.o
+
+CLEANFILES += gptzfsboot.bin gptzfsboot.out
+
+gptzfsboot.bin: gptzfsboot.out
+ ${OBJCOPY} -S -O binary gptzfsboot.out $@
+
+gptzfsboot.out: ${BTXCRT} ${OBJS} ${LIBZFSBOOT} ${LIBSTAND}
+ ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o $@ ${BTXCRT} ${OBJS} \
+ ${LIBZFSBOOT} ${LIBSTAND}
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../i386/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+%.o: ../common/%.c
+ $(COMPILE.c) -o $@ $<
+
+%.o: ../../common/%.c
+ $(COMPILE.c) -o $@ $<
+
+biosdisk.o: ../libi386/biosdisk.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -Dalloca=__builtin_alloca -c -o $@ ../libi386/$*.c
+
+biosmem.o: ../libi386/biosmem.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ ../libi386/$*.c
+
+smbios.o: ../libi386/smbios.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) \
+ -DSMBIOS_SERIAL_NUMBERS -DSMBIOS_LITTLE_ENDIAN_UUID \
+ -c -o $@ ../libi386/$*.c
+
+devicename.o: ../libi386/devicename.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ ../libi386/$*.c
+
+time.o: ../libi386/time.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ ../libi386/$*.c
+
+.S.o:
+ $(CC) $(CFLAGS) $(CCASFLAGS) -c -o $@ $<
+
+clobber: clean
+
+clean:
+ $(RM) $(CLEANFILES) machine x86
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/gptldr.S b/usr/src/boot/sys/boot/i386/gptzfsboot/gptldr.S
new file mode 100644
index 0000000000..9b646aee66
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/gptldr.S
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2007 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb@FreeBSD.org>
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Partly from: src/sys/boot/i386/boot2/boot1.S 1.31
+ */
+
+/* Memory Locations */
+ .set MEM_REL,0x700 # Relocation address
+ .set MEM_ARG,0x900 # Arguments
+ .set MEM_ORG,0x7c00 # Origin
+ .set MEM_BUF,0x8cec # Load area
+ .set MEM_BTX,0x9000 # BTX start
+ .set MEM_JMP,0x9010 # BTX entry point
+ .set MEM_USR,0xa000 # Client start
+ .set BDA_BOOT,0x472 # Boot howto flag
+
+/* Misc. Constants */
+ .set SIZ_PAG,0x1000 # Page size
+ .set SIZ_SEC,0x200 # Sector size
+ .set COPY_BLKS,0x4 # Number of blocks
+ # to copy for boot2
+ .set COPY_BLK_SZ,0x8000 # Copy in 32k blocks; must be
+ # a multiple of 16 bytes
+
+ .globl start
+ .code16
+
+/*
+ * Copy BTX and boot2 to the right locations and start it all up.
+ */
+
+/*
+ * Setup the segment registers to flat addressing (segment 0) and setup the
+ * stack to end just below the start of our code.
+ */
+start: xor %cx,%cx # Zero
+ mov %cx,%es # Address
+ mov %cx,%ds # data
+ mov %cx,%ss # Set up
+ mov $start,%sp # stack
+
+/*
+ * BTX is right after us at 'end'. We read the length of BTX out of
+ * its header to find boot2. We need to copy boot2 to MEM_USR and BTX
+ * to MEM_BTX. Since those might overlap, we have to copy boot2
+ * backwards first and then copy BTX. We aren't sure exactly how long
+ * boot2 is, but it's currently under 128kB so we'll copy 4 blocks of 32kB
+ * each; this can be adjusted via COPY_BLK and COPY_BLK_SZ above.
+ */
+ mov $end,%bx # BTX
+ mov 0xa(%bx),%si # Get BTX length and set
+ add %bx,%si # %si to start of boot2
+ dec %si # Set %ds:%si to point at the
+ mov %si,%ax # last byte we want to copy
+ shr $4,%ax # from boot2, with %si made as
+ add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # small as possible.
+ and $0xf,%si #
+ mov %ax,%ds #
+ mov $MEM_USR/16,%ax # Set %es:(-1) to point at
+ add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # the last byte we
+ mov %ax,%es # want to copy boot2 into.
+ mov $COPY_BLKS,%bx # Copy COPY_BLKS 32k blocks
+copyloop:
+ add $COPY_BLK_SZ,%si # Adjust %ds:%si to point at
+ mov %ds,%ax # the end of the next 32k to
+ sub $COPY_BLK_SZ/16,%ax # copy from boot2
+ mov %ax,%ds
+ mov $COPY_BLK_SZ-1,%di # Adjust %es:%di to point at
+ mov %es,%ax # the end of the next 32k into
+ sub $COPY_BLK_SZ/16,%ax # which we want boot2 copied
+ mov %ax,%es
+ mov $COPY_BLK_SZ,%cx # Copy 32k
+ std
+ rep movsb
+ dec %bx
+ jnz copyloop
+ mov %cx,%ds # Reset %ds and %es
+ mov %cx,%es
+ mov $end,%bx # BTX
+ mov 0xa(%bx),%cx # Get BTX length and set
+ mov %bx,%si # %si to end of BTX
+ mov $MEM_BTX,%di # %di -> end of BTX at
+ add %cx,%si # MEM_BTX
+ add %cx,%di
+ dec %si
+ dec %di
+ rep movsb # Move BTX
+ cld # String ops inc
+/*
+ * Enable A20 so we can access memory above 1 meg.
+ * Use the zero-valued %cx as a timeout for embedded hardware which do not
+ * have a keyboard controller.
+ */
+seta20: cli # Disable interrupts
+seta20.1: dec %cx # Timeout?
+ jz seta20.3 # Yes
+ inb $0x64,%al # Get status
+ testb $0x2,%al # Busy?
+ jnz seta20.1 # Yes
+ movb $0xd1,%al # Command: Write
+ outb %al,$0x64 # output port
+seta20.2: inb $0x64,%al # Get status
+ testb $0x2,%al # Busy?
+ jnz seta20.2 # Yes
+ movb $0xdf,%al # Enable
+ outb %al,$0x60 # A20
+seta20.3: sti # Enable interrupts
+
+/*
+ * Save drive number from BIOS so boot2 can see it and start BTX.
+ */
+ movb %dl,MEM_ARG
+ jmp MEM_JMP # Start BTX
+/*
+ * make sure the end is aligned for concatenated next module
+ */
+ .align 4
+end:
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/gptzfsboot.8 b/usr/src/boot/sys/boot/i386/gptzfsboot/gptzfsboot.8
new file mode 100644
index 0000000000..66feb6d350
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/gptzfsboot.8
@@ -0,0 +1,193 @@
+.\" Copyright (c) 2014 Andriy Gapon <avg@FreeBSD.org>
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 15, 2014
+.Dt GPTZFSBOOT 8
+.Os
+.Sh NAME
+.Nm gptzfsboot
+.Nd GPT bootcode for ZFS on BIOS-based computers
+.Sh DESCRIPTION
+.Nm
+is used on BIOS-based computers to boot from a filesystem in
+a ZFS pool.
+.Nm
+is installed in a
+.Cm freebsd-boot
+partition of a GPT-partitioned disk with
+.Xr gpart 8 .
+.Sh IMPLEMENTATION NOTES
+The GPT standard allows a variable number of partitions, but
+.Nm
+only boots from tables with 128 partitions or less.
+.Sh BOOTING
+.Nm
+tries to find all ZFS pools that are composed of BIOS-visible
+hard disks or partitions on them.
+.Nm
+looks for ZFS device labels on all visible disks and in discovered
+supported partitions for all supported partition scheme types.
+The search starts with the disk from which
+.Nm
+itself was loaded.
+Other disks are probed in BIOS defined order.
+After a disk is probed and
+.Nm
+determines that the whole disk is not a ZFS pool member, the
+individual partitions are probed in their partition table order.
+Currently GPT and MBR partition schemes are supported.
+With the GPT scheme, only partitions of type
+.Cm freebsd-zfs
+are probed.
+The first pool seen during probing is used as a default boot pool.
+.Pp
+The filesystem specified by the
+.Cm bootfs
+property of the pool is used as a default boot filesystem.
+If the
+.Cm bootfs
+property is not set, then the root filesystem of the pool is used as
+the default.
+.Xr zfsloader 8
+is loaded from the boot filesystem.
+If
+.Pa /boot.config
+or
+.Pa /boot/config
+is present in the boot filesystem, boot options are read from it
+in the same way as
+.Xr boot 8 .
+.Pp
+The ZFS GUIDs of the first successfully probed device and the first
+detected pool are made available to
+.Xr zfsloader 8
+in the
+.Cm vfs.zfs.boot.primary_vdev
+and
+.Cm vfs.zfs.boot.primary_pool
+variables.
+.Sh USAGE
+Normally
+.Nm
+will boot in fully automatic mode.
+However, like
+.Xr boot 8 ,
+it is possible to interrupt the automatic boot process and interact with
+.Nm
+through a prompt.
+.Nm
+accepts all the options that
+.Xr boot 8
+supports.
+.Pp
+The filesystem specification and the path to
+.Xr zfsloader 8
+are different from
+.Xr boot 8 .
+The format is
+.Pp
+.Sm off
+.Oo zfs:pool/filesystem: Oc Oo /path/to/loader Oc
+.Sm on
+.Pp
+Both the filesystem and the path can be specified.
+If only a path is specified, then the default filesystem is used.
+If only a pool and filesystem are specified, then
+.Pa /boot/zfsloader
+is used as a path.
+.Pp
+Additionally, the
+.Ic status
+command can be used to query information about discovered pools.
+The output format is similar to that of
+.Cm zpool status
+.Pq see Xr zpool 8 .
+.Pp
+The configured or automatically determined ZFS boot filesystem is
+stored in the
+.Xr zfsloader 8
+.Cm loaddev
+variable, and also set as the initial value of the
+.Cm currdev
+variable.
+.Sh FILES
+.Bl -tag -width /boot/gptzfsboot -compact
+.It Pa /boot/gptzfsboot
+boot code binary
+.It Pa /boot.config
+parameters for the boot block
+.Pq optional
+.It Pa /boot/config
+alternative parameters for the boot block
+.Pq optional
+.El
+.Sh EXAMPLES
+.Nm
+is typically installed in combination with a
+.Dq protective MBR
+.Po
+see
+.Xr gpart 8
+.Pc .
+To install
+.Nm
+on the
+.Pa ada0
+drive:
+.Bd -literal -offset indent
+gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
+.Ed
+.Pp
+.Nm
+can also be installed without the PMBR:
+.Bd -literal -offset indent
+gpart bootcode -p /boot/gptzfsboot -i 1 ada0
+.Ed
+.Sh SEE ALSO
+.Xr boot.config 5 ,
+.Xr boot 8 ,
+.Xr gpart 8 ,
+.Xr loader 8 ,
+.Xr zfsloader 8 ,
+.Xr zpool 8
+.Sh HISTORY
+.Nm
+appeared in FreeBSD 7.3.
+.Sh AUTHORS
+This manual page was written by
+.An Andriy Gapon Aq avg@FreeBSD.org .
+.Sh BUGS
+.Nm
+looks for ZFS meta-data only in MBR partitions
+.Pq known on FreeBSD as slices .
+It does not look into BSD
+.Xr disklabel 8
+partitions that are traditionally called partitions.
+If a disklabel partition happens to be placed so that ZFS meta-data can be
+found at the fixed offsets relative to a slice, then
+.Nm
+will recognize the partition as a part of a ZFS pool,
+but this is not guaranteed to happen.
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/lib.h b/usr/src/boot/sys/boot/i386/gptzfsboot/lib.h
new file mode 100644
index 0000000000..d8d3317e5a
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/lib.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+int sio_init(int) __attribute__((regparm (3)));
+int sio_flush(void);
+void sio_putc(int) __attribute__((regparm (3)));
+int sio_getc(void);
+int sio_ischar(void);
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/multiboot.S b/usr/src/boot/sys/boot/i386/gptzfsboot/multiboot.S
new file mode 100644
index 0000000000..55a190e411
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/multiboot.S
@@ -0,0 +1,39 @@
+/*
+ * 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 2015 Toomas Soome <tsoome@me.com>
+ */
+
+ .file "multiboot.s"
+
+/*
+ * Provide fake multiboot header to support versioning and partition
+ * start.
+ */
+
+#define ASM_FILE
+#include <multiboot.h>
+
+ .globl mb_header, start_sector
+ .text
+
+ .align 4
+mb_header:
+ .long MULTIBOOT_HEADER_MAGIC
+ .long MULTIBOOT_AOUT_KLUDGE
+ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_AOUT_KLUDGE)
+ .long 0 /* header_addr */
+ .long 0 /* load_addr */
+ .long 0 /* load_end_addr */
+start_sector: .long 0 /* partition LBA */
+ .long 0
+
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/sio.S b/usr/src/boot/sys/boot/i386/gptzfsboot/sio.S
new file mode 100644
index 0000000000..ca9d0a2406
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/sio.S
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD$
+ */
+
+ .set SIO_PRT,SIOPRT # Base port
+ .set SIO_FMT,SIOFMT # 8N1
+
+ .globl sio_init
+ .globl sio_flush
+ .globl sio_putc
+ .globl sio_getc
+ .globl sio_ischar
+
+/* int sio_init(int div) */
+
+sio_init: pushl %eax
+ movw $SIO_PRT+0x3,%dx # Data format reg
+ movb $SIO_FMT|0x80,%al # Set format
+ outb %al,(%dx) # and DLAB
+ subb $0x3,%dl # Divisor latch reg
+ popl %eax
+ outw %ax,(%dx) # BPS
+ movw $SIO_PRT+0x3,%dx # Data format reg
+ movb $SIO_FMT,%al # Clear
+ outb %al,(%dx) # DLAB
+ incl %edx # Modem control reg
+ movb $0x3,%al # Set RTS,
+ outb %al,(%dx) # DTR
+ incl %edx # Line status reg
+ # Fallthrough
+
+/* int sio_flush(void) */
+
+sio_flush: xorl %ecx,%ecx # Timeout
+ movb $0x80,%ch # counter
+sio_flush.1: call sio_ischar # Check for character
+ jz sio_flush.2 # Till none
+ loop sio_flush.1 # or counter is zero
+ movb $1, %al # Exhausted all tries
+sio_flush.2: ret # To caller
+
+/* void sio_putc(int c) */
+
+sio_putc: pushl %eax
+ movw $SIO_PRT+0x5,%dx # Line status reg
+ xor %ecx,%ecx # Timeout
+ movb $0x40,%ch # counter
+sio_putc.1: inb (%dx),%al # Transmitter
+ testb $0x20,%al # buffer empty?
+ loopz sio_putc.1 # No
+ jz sio_putc.2 # If timeout
+ popl %eax # Get the character
+ subb $0x5,%dl # Transmitter hold reg
+ outb %al,(%dx) # Write character
+sio_putc.2: ret # To caller
+
+/* int sio_getc(void) */
+
+sio_getc: call sio_ischar # Character available?
+ jz sio_getc # No
+sio_getc.1: subb $0x5,%dl # Receiver buffer reg
+ inb (%dx),%al # Read character
+ ret # To caller
+
+/* int sio_ischar(void) */
+
+sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register
+ xorl %eax,%eax # Zero
+ inb (%dx),%al # Received data
+ andb $0x1,%al # ready?
+ ret # To caller
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c b/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
new file mode 100644
index 0000000000..400c752de4
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
@@ -0,0 +1,699 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+#include <stand.h>
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/diskmbr.h>
+#include <sys/vtoc.h>
+#include <sys/disk.h>
+#include <sys/reboot.h>
+#include <sys/queue.h>
+#include <multiboot.h>
+
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+#include <machine/pc/bios.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#include <a.out.h>
+#include "bootstrap.h"
+#include "libi386.h"
+#include <btxv86.h>
+
+#include "lib.h"
+#include "rbx.h"
+#include "cons.h"
+#include "bootargs.h"
+#include "disk.h"
+#include "part.h"
+#include "paths.h"
+
+#include "libzfs.h"
+
+#define ARGS 0x900
+#define NOPT 14
+#define NDEV 3
+
+#define BIOS_NUMDRIVES 0x475
+#define DRV_HARD 0x80
+#define DRV_MASK 0x7f
+
+#define TYPE_AD 0
+#define TYPE_DA 1
+#define TYPE_MAXHARD TYPE_DA
+#define TYPE_FD 2
+
+extern uint32_t _end;
+
+/*
+ * Fake multiboot header to provide versioning and to pass
+ * partition start LBA. Partition is either GPT partition or
+ * VTOC slice.
+ */
+extern const struct multiboot_header mb_header;
+extern uint64_t start_sector;
+
+static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
+static const unsigned char flags[NOPT] = {
+ RBX_DUAL,
+ RBX_SERIAL,
+ RBX_ASKNAME,
+ RBX_CDROM,
+ RBX_CONFIG,
+ RBX_KDB,
+ RBX_GDB,
+ RBX_MUTE,
+ RBX_NOINTR,
+ RBX_PAUSE,
+ RBX_QUIET,
+ RBX_DFLTROOT,
+ RBX_SINGLE,
+ RBX_VERBOSE
+};
+uint32_t opts;
+
+static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
+static const unsigned char dev_maj[NDEV] = {30, 4, 2};
+
+static struct i386_devdesc *bdev;
+static char cmd[512];
+static char cmddup[512];
+static char kname[1024];
+static int comspeed = SIOSPD;
+static struct bootinfo bootinfo;
+static uint32_t bootdev;
+static struct zfs_boot_args zfsargs;
+
+extern vm_offset_t high_heap_base;
+extern uint32_t bios_basemem, bios_extmem, high_heap_size;
+
+static char *heap_top;
+static char *heap_bottom;
+
+static void i386_zfs_probe(void);
+void exit(int);
+static void load(void);
+static int parse_cmd(void);
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */
+
+struct devsw *devsw[] = {
+ &biosdisk,
+ &zfs_dev,
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+ &zfs_fsops,
+ &ufs_fsops,
+ &dosfs_fsops,
+ NULL
+};
+
+/*
+ * probe arguments for partition iterator (see below)
+ */
+struct probe_args {
+ int fd;
+ char *devname;
+ u_int secsz;
+ uint64_t offset;
+};
+
+/*
+ * simple wrapper around read() to avoid using device specific
+ * strategy() directly.
+ */
+static int
+parttblread(void *arg, void *buf, size_t blocks, off_t offset)
+{
+ struct probe_args *ppa = arg;
+ size_t size = ppa->secsz * blocks;
+
+ lseek(ppa->fd, offset * ppa->secsz, SEEK_SET);
+ if (read(ppa->fd, buf, size) == size)
+ return (0);
+ return (EIO);
+}
+
+/*
+ * scan partition entries to find boot partition starting at start_sector.
+ * in case of MBR partition type PART_SOLARIS2, read VTOC and recurse.
+ */
+static int
+probe_partition(void *arg, const char *partname,
+ const struct ptable_entry *part)
+{
+ struct probe_args pa, *ppa = arg;
+ struct ptable *table;
+ char devname[32];
+ int ret = 0;
+
+ strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
+ devname[strlen(ppa->devname) - 1] = '\0';
+ sprintf(devname, "%s%s:", devname, partname);
+
+ if (part->type == PART_SOLARIS2) {
+ pa.offset = part->start;
+ pa.fd = open(devname, O_RDONLY);
+ if (pa.fd == -1)
+ return (ret);
+ pa.devname = devname;
+ pa.secsz = ppa->secsz;
+ table = ptable_open(&pa, part->end - part->start + 1,
+ ppa->secsz, parttblread);
+ if (table != NULL) {
+ ret = ptable_iterate(table, &pa, probe_partition);
+ ptable_close(table);
+ }
+ close(pa.fd);
+ if (ret) {
+ strcpy(ppa->devname, devname);
+ return (ret);
+ }
+ }
+
+ if (ppa->offset + part->start == start_sector) {
+ ret = 1; /* this is the end of the search */
+ strcpy(ppa->devname, devname);
+ }
+
+ return (ret);
+}
+
+/*
+ * open partition table on disk and scan partition entries to find
+ * boot partition starting at start_sector (recorded by installboot).
+ */
+static int
+probe_disk(char *devname)
+{
+ struct ptable *table;
+ struct probe_args pa;
+ off_t mediasz;
+ int ret;
+
+ pa.offset = 0;
+ pa.devname = devname;
+ pa.fd = open(devname, O_RDONLY);
+ if (pa.fd == -1) {
+ return (ENXIO);
+ }
+
+ ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
+ if (ret == 0)
+ ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
+ if (ret == 0) {
+ table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
+ parttblread);
+ if (table != NULL) {
+ ret = ptable_iterate(table, &pa, probe_partition);
+ ptable_close(table);
+ }
+ }
+ close(pa.fd);
+ return (ret);
+}
+
+int
+main(void)
+{
+ int auto_boot, i, fd, ret;
+ struct disk_devdesc devdesc;
+
+ bios_getmem();
+
+ if (high_heap_size > 0) {
+ heap_top = PTOV(high_heap_base + high_heap_size);
+ heap_bottom = PTOV(high_heap_base);
+ } else {
+ heap_bottom = (char *)
+ (roundup2(__base + (int32_t)&_end, 0x10000) - __base);
+ heap_top = (char *) PTOV(bios_basemem);
+ }
+ setheap(heap_bottom, heap_top);
+
+ /*
+ * Initialise the block cache. Set the upper limit.
+ */
+ bcache_init(32768, 512);
+
+ archsw.arch_autoload = NULL;
+ archsw.arch_getdev = i386_getdev;
+ archsw.arch_copyin = NULL;
+ archsw.arch_copyout = NULL;
+ archsw.arch_readin = NULL;
+ archsw.arch_isainb = NULL;
+ archsw.arch_isaoutb = NULL;
+ archsw.arch_zfs_probe = i386_zfs_probe;
+
+ /*
+ * dont init zfs yet, need to run through probe_disk(), then init
+ * zfs with probing boot device by name first.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL && strcmp(devsw[i]->dv_name, "zfs"))
+ (devsw[i]->dv_init)();
+
+ bootinfo.bi_version = BOOTINFO_VERSION;
+ bootinfo.bi_size = sizeof(bootinfo);
+ bootinfo.bi_basemem = bios_basemem / 1024;
+ bootinfo.bi_extmem = bios_extmem / 1024;
+ bootinfo.bi_memsizes_valid++;
+ bootinfo.bi_bios_dev = *(uint8_t *)PTOV(ARGS);
+
+ /*
+ * detect partition from boot disk and start_sector
+ * we need partition as devsw/fs switch is depending on it.
+ */
+ sprintf(boot_devname, "disk%d:", bd_bios2unit(bootinfo.bi_bios_dev));
+ ret = probe_disk(boot_devname);
+ if (!ret)
+ printf("start sector %llu does not match any partition on device: %s\n",
+ start_sector, boot_devname);
+
+ disk_parsedev(&devdesc, boot_devname+4, NULL);
+
+ bootdev = MAKEBOOTDEV(dev_maj[devdesc.d_type], devdesc.d_slice + 1,
+ devdesc.d_unit, devdesc.d_partition >= 0? devdesc.d_partition:0xff);
+
+ /*
+ * check for zfs on boot partition, we need to make sure this is
+ * the first registered pool.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL && strcmp(devsw[i]->dv_name, "zfs") == 0)
+ (devsw[i]->dv_init)();
+
+ /*
+ * zfs_fmtdev() can be called only after dv_init
+ */
+ if (bdev != NULL && bdev->d_type == DEVT_ZFS) {
+ /* set up proper device name string for ZFS */
+ strcpy(boot_devname, zfs_fmtdev(bdev));
+ }
+
+ /* now make sure we have bdev on all cases */
+ if (bdev != NULL)
+ free(bdev);
+ i386_getdev((void **)&bdev, boot_devname, NULL);
+
+ env_setenv("currdev", EV_VOLATILE, boot_devname, i386_setcurrdev,
+ env_nounset);
+
+ /* Process configuration file */
+ setenv("LINES", "24", 1);
+ auto_boot = 1;
+
+ fd = open(PATH_CONFIG, O_RDONLY);
+ if (fd == -1)
+ fd = open(PATH_DOTCONFIG, O_RDONLY);
+
+ if (fd != -1) {
+ read(fd, cmd, sizeof(cmd));
+ close(fd);
+ }
+
+ if (*cmd) {
+ /*
+ * Note that parse_cmd() is destructive to cmd[] and we also want
+ * to honor RBX_QUIET option that could be present in cmd[].
+ */
+ memcpy(cmddup, cmd, sizeof(cmd));
+ if (parse_cmd())
+ auto_boot = 0;
+ if (!OPT_CHECK(RBX_QUIET))
+ printf("%s: %s\n", PATH_CONFIG, cmddup);
+ /* Do not process this command twice */
+ *cmd = 0;
+ }
+
+ /*
+ * Try to exec stage 3 boot loader. If interrupted by a keypress,
+ * or in case of failure, switch off auto boot.
+ */
+
+ if (auto_boot && !*kname) {
+ memcpy(kname, PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS));
+ if (!keyhit(3)) {
+ load();
+ auto_boot = 0;
+ }
+ }
+
+ /* Present the user with the boot2 prompt. */
+
+ for (;;) {
+ if (!auto_boot || !OPT_CHECK(RBX_QUIET)) {
+ printf("\nillumos/x86 boot\n");
+ printf("Default: %s%s\nboot: ", boot_devname, kname);
+ }
+ if (ioctrl & IO_SERIAL)
+ sio_flush();
+ if (!auto_boot || keyhit(5))
+ getstr(cmd, sizeof(cmd));
+ else if (!auto_boot || !OPT_CHECK(RBX_QUIET))
+ putchar('\n');
+ auto_boot = 0;
+ if (parse_cmd())
+ putchar('\a');
+ else
+ load();
+ }
+}
+
+/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
+void
+exit(int x)
+{
+}
+
+static void
+load(void)
+{
+ union {
+ struct exec ex;
+ Elf32_Ehdr eh;
+ } hdr;
+ static Elf32_Phdr ep[2];
+ static Elf32_Shdr es[2];
+ caddr_t p;
+ uint32_t addr, x;
+ int fd, fmt, i, j;
+
+ if ((fd = open(kname, O_RDONLY)) == -1) {
+ printf("\nCan't find %s\n", kname);
+ return;
+ }
+ if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ close(fd);
+ return;
+ }
+ if (N_GETMAGIC(hdr.ex) == ZMAGIC)
+ fmt = 0;
+ else if (IS_ELF(hdr.eh))
+ fmt = 1;
+ else {
+ printf("Invalid %s\n", "format");
+ close(fd);
+ return;
+ }
+ if (fmt == 0) {
+ addr = hdr.ex.a_entry & 0xffffff;
+ p = PTOV(addr);
+ lseek(fd, PAGE_SIZE, SEEK_SET);
+ if (read(fd, p, hdr.ex.a_text) != hdr.ex.a_text) {
+ close(fd);
+ return;
+ }
+ p += roundup2(hdr.ex.a_text, PAGE_SIZE);
+ if (read(fd, p, hdr.ex.a_data) != hdr.ex.a_data) {
+ close(fd);
+ return;
+ }
+ p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
+ bootinfo.bi_symtab = VTOP(p);
+ memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
+ p += sizeof(hdr.ex.a_syms);
+ if (hdr.ex.a_syms) {
+ if (read(fd, p, hdr.ex.a_syms) != hdr.ex.a_syms) {
+ close(fd);
+ return;
+ }
+ p += hdr.ex.a_syms;
+ if (read(fd, p, sizeof(int)) != sizeof(int)) {
+ close(fd);
+ return;
+ }
+ x = *(uint32_t *)p;
+ p += sizeof(int);
+ x -= sizeof(int);
+ if (read(fd, p, x) != x) {
+ close(fd);
+ return;
+ }
+ p += x;
+ }
+ } else {
+ lseek(fd, hdr.eh.e_phoff, SEEK_SET);
+ for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
+ if (read(fd, ep + j, sizeof(ep[0])) != sizeof(ep[0])) {
+ close(fd);
+ return;
+ }
+ if (ep[j].p_type == PT_LOAD)
+ j++;
+ }
+ for (i = 0; i < 2; i++) {
+ p = PTOV(ep[i].p_paddr & 0xffffff);
+ lseek(fd, ep[i].p_offset, SEEK_SET);
+ if (read(fd, p, ep[i].p_filesz) != ep[i].p_filesz) {
+ close(fd);
+ return;
+ }
+ }
+ p += roundup2(ep[1].p_memsz, PAGE_SIZE);
+ bootinfo.bi_symtab = VTOP(p);
+ if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
+ lseek(fd, hdr.eh.e_shoff + sizeof(es[0]) * (hdr.eh.e_shstrndx + 1),
+ SEEK_SET);
+ if (read(fd, &es, sizeof(es)) != sizeof(es)) {
+ close(fd);
+ return;
+ }
+ for (i = 0; i < 2; i++) {
+ memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
+ p += sizeof(es[i].sh_size);
+ lseek(fd, es[i].sh_offset, SEEK_SET);
+ if (read(fd, p, es[i].sh_size) != es[i].sh_size) {
+ close(fd);
+ return;
+ }
+ p += es[i].sh_size;
+ }
+ }
+ addr = hdr.eh.e_entry & 0xffffff;
+ }
+ close(fd);
+
+ bootinfo.bi_esymtab = VTOP(p);
+ bootinfo.bi_kernelname = VTOP(kname);
+
+ if (bdev->d_type == DEVT_ZFS) {
+ zfsargs.size = sizeof(zfsargs);
+ zfsargs.pool = bdev->d_kind.zfs.pool_guid;
+ zfsargs.root = bdev->d_kind.zfs.root_guid;
+ __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
+ bootdev,
+ KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG,
+ (uint32_t) bdev->d_kind.zfs.pool_guid,
+ (uint32_t) (bdev->d_kind.zfs.pool_guid >> 32),
+ VTOP(&bootinfo),
+ zfsargs);
+ } else
+ __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
+ bootdev, 0, 0, 0, VTOP(&bootinfo));
+}
+
+static int
+mount_root(char *arg)
+{
+ char *root;
+ struct i386_devdesc *ddesc;
+ uint8_t part;
+
+ root = malloc(strlen(arg) + 2);
+ if (root == NULL)
+ return (1);
+ sprintf(root, "%s:", arg);
+ if (i386_getdev((void **)&ddesc, root, NULL)) {
+ free(root);
+ return (1);
+ }
+
+ /* we should have new device descriptor, free old and replace it. */
+ if (bdev != NULL)
+ free(bdev);
+ bdev = ddesc;
+ if (bdev->d_type == DEVT_DISK) {
+ if (bdev->d_kind.biosdisk.partition == -1)
+ part = 0xff;
+ else
+ part = bdev->d_kind.biosdisk.partition;
+ bootdev = MAKEBOOTDEV(dev_maj[bdev->d_type],
+ bdev->d_kind.biosdisk.slice + 1,
+ bdev->d_unit, part);
+ bootinfo.bi_bios_dev = bd_unit2bios(bdev->d_unit);
+ }
+ setenv("currdev", root, 1);
+ free(root);
+ return (0);
+}
+
+static void
+fs_list(char *arg)
+{
+ int fd;
+ struct dirent *d;
+ char line[80];
+
+ fd = open(arg, O_RDONLY);
+ if (fd < 0)
+ return;
+ pager_open();
+ while ((d = readdirfd(fd)) != NULL) {
+ sprintf(line, "%s\n", d->d_name);
+ if (pager_output(line))
+ break;
+ }
+ pager_close();
+ close(fd);
+}
+
+static int
+parse_cmd(void)
+{
+ char *arg = cmd;
+ char *ep, *p, *q;
+ const char *cp;
+ char line[80];
+ int c, i, j;
+
+ while ((c = *arg++)) {
+ if (c == ' ' || c == '\t' || c == '\n')
+ continue;
+ for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
+ ep = p;
+ if (*p)
+ *p++ = 0;
+ if (c == '-') {
+ while ((c = *arg++)) {
+ if (c == 'P') {
+ if (*(uint8_t *)PTOV(0x496) & 0x10) {
+ cp = "yes";
+ } else {
+ opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
+ cp = "no";
+ }
+ printf("Keyboard: %s\n", cp);
+ continue;
+ } else if (c == 'S') {
+ j = 0;
+ while ((unsigned int)(i = *arg++ - '0') <= 9)
+ j = j * 10 + i;
+ if (j > 0 && i == -'0') {
+ comspeed = j;
+ break;
+ }
+ /* Fall through to error below ('S' not in optstr[]). */
+ }
+ for (i = 0; c != optstr[i]; i++)
+ if (i == NOPT - 1)
+ return -1;
+ opts ^= OPT_SET(flags[i]);
+ }
+ ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
+ OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
+ if (ioctrl & IO_SERIAL) {
+ if (sio_init(115200 / comspeed) != 0)
+ ioctrl &= ~IO_SERIAL;
+ }
+ } if (c == '?') {
+ printf("\n");
+ fs_list(arg);
+ zfs_list(arg);
+ return -1;
+ } else {
+ arg--;
+
+ /*
+ * Report pool status if the comment is 'status'. Lets
+ * hope no-one wants to load /status as a kernel.
+ */
+ if (!strcmp(arg, "status")) {
+ pager_open();
+ for (i = 0; devsw[i] != NULL; i++) {
+ if (devsw[i]->dv_print != NULL) {
+ sprintf(line, "\n%s devices:\n", devsw[i]->dv_name);
+ if (pager_output(line))
+ break;
+ if (devsw[i]->dv_print(1))
+ break;
+ } else {
+ sprintf(line, "%s: (unknown)\n", devsw[i]->dv_name);
+ if (pager_output(line))
+ break;
+ }
+ }
+ pager_close();
+ return -1;
+ }
+
+ /*
+ * If there is a colon, switch pools.
+ */
+ if (strncmp(arg, "zfs:", 4) == 0)
+ q = strchr(arg + 4, ':');
+ else
+ q = strchr(arg, ':');
+ if (q) {
+ *q++ = '\0';
+ if (mount_root(arg) != 0)
+ return -1;
+ arg = q;
+ }
+ if ((i = ep - arg)) {
+ if ((size_t)i >= sizeof(kname))
+ return -1;
+ memcpy(kname, arg, i + 1);
+ }
+ }
+ arg = p;
+ }
+ return 0;
+}
+
+static void
+i386_zfs_probe(void)
+{
+ char devname[32];
+ uint64_t pool_guid = 0;
+ int unit;
+
+ /*
+ * Open all the disks we can find and see if we can reconstruct
+ * ZFS pools from them. We start from boot device to get boot pool_guid.
+ */
+ bdev = malloc(sizeof (struct i386_devdesc));
+ bzero(bdev, sizeof (struct i386_devdesc));
+ zfs_probe_dev(boot_devname, &pool_guid);
+ if (pool_guid) {
+ bdev->d_type = DEVT_ZFS;
+ bdev->d_dev = &zfs_dev;
+ bdev->d_kind.zfs.pool_guid = pool_guid;
+ }
+ for (unit = 0; unit < MAXBDDEV; unit++) {
+ if (bd_unit2bios(unit) == -1)
+ break;
+ sprintf(devname, "disk%d:", unit);
+ zfs_probe_dev(devname, NULL);
+ }
+}
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/Makefile b/usr/src/boot/sys/boot/i386/libfirewire/Makefile
new file mode 100644
index 0000000000..191b95479e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/Makefile
@@ -0,0 +1,30 @@
+# $FreeBSD$
+
+LIB= firewire
+INTERNALLIB=
+
+.PATH: ${.CURDIR}/../../../dev/dcons ${.CURDIR}/../../../dev/firewire
+SRCS+= firewire.c fwohci.c dconsole.c
+SRCS+= dcons.c fwcrom.c
+
+CFLAGS+= -D_BOOT
+
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -I${.CURDIR}/../btx/lib
+CFLAGS+= -I${.CURDIR}/../libi386
+
+CFLAGS+= -Wformat -Wall
+
+.if ${MACHINE_CPUARCH} == "amd64"
+CLEANFILES+= machine
+machine:
+ ln -sf ${.CURDIR}/../../../i386/include machine
+.endif
+
+.include <bsd.lib.mk>
+
+.if ${MACHINE_CPUARCH} == "amd64"
+beforedepend ${OBJS}: machine
+.endif
+
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c b/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c
new file mode 100644
index 0000000000..16645e259c
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2004 Hidetoshi Shimokawa
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <sys/param.h>
+#include <btxv86.h>
+#include <dev/dcons/dcons.h>
+
+void fw_enable(void);
+void fw_poll(void);
+
+static void dconsole_probe(struct console *cp);
+static int dconsole_init(int arg);
+static void dconsole_putchar(int c);
+static int dconsole_getchar(void);
+static int dconsole_ischar(void);
+
+static int dcons_started = 0;
+
+#define DCONS_BUF_SIZE (64*1024)
+static struct dcons_softc sc[DCONS_NPORT];
+uint32_t dcons_paddr;
+
+/* The buffer must be allocated in BSS becase:
+ * - The dcons driver in the kernel is initialized before VM/pmap is
+ * initialized, so that the buffer must be allocate in the region
+ * that is mapped at the very early boot state.
+ * - We expect identiy map only for regions before KERNLOAD
+ * (i386:4MB amd64:1MB).
+ * - It seems that heap in conventional memory(640KB) is not sufficent
+ * and we move it to high address as LOADER_SUPPORT_BZIP2.
+ * - BSS is placed in conventional memory.
+ */
+static char dcons_buffer[DCONS_BUF_SIZE + PAGE_SIZE];
+
+struct console dconsole = {
+ "dcons",
+ "dumb console port",
+ 0,
+ dconsole_probe,
+ dconsole_init,
+ dconsole_putchar,
+ dconsole_getchar,
+ dconsole_ischar
+};
+
+#define DCONSOLE_AS_MULTI_CONSOLE 1
+
+static void
+dconsole_probe(struct console *cp)
+{
+ /* XXX check the BIOS equipment list? */
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+#if DCONSOLE_AS_MULTI_CONSOLE
+ dconsole_init(0);
+ cp->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT);
+#endif
+}
+
+static int
+dconsole_init(int arg)
+{
+ char buf[16], *dbuf;
+ int size;
+
+ if (dcons_started && arg == 0)
+ return 0;
+ dcons_started = 1;
+
+ size = DCONS_BUF_SIZE;
+ dbuf = (char *)round_page((vm_offset_t)&dcons_buffer[0]);
+ dcons_paddr = VTOP(dbuf);
+ sprintf(buf, "0x%08x", dcons_paddr);
+ setenv("dcons.addr", buf, 1);
+
+ dcons_init((struct dcons_buf *)dbuf, size, sc);
+ sprintf(buf, "%d", size);
+ setenv("dcons.size", buf, 1);
+ fw_enable();
+ return(0);
+}
+
+static void
+dconsole_putchar(int c)
+{
+ dcons_putc(&sc[0], c);
+}
+
+static int
+dconsole_getchar(void)
+{
+ fw_poll();
+ return (dcons_checkc(&sc[0]));
+}
+
+static int
+dconsole_ischar(void)
+{
+ fw_poll();
+ return (dcons_ischar(&sc[0]));
+}
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/firewire.c b/usr/src/boot/sys/boot/i386/libfirewire/firewire.c
new file mode 100644
index 0000000000..8191a63d8b
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/firewire.c
@@ -0,0 +1,474 @@
+/*-
+ * Copyright (c) 2004 Hidetoshi Shimokawa <simokawa@FreeBSD.ORG>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * FireWire disk device handling.
+ *
+ */
+
+#include <stand.h>
+
+#include <machine/bootinfo.h>
+
+#include <stdarg.h>
+
+#include <bootstrap.h>
+#include <btxv86.h>
+#include <libi386.h>
+#include "fwohci.h"
+#include <dev/dcons/dcons.h>
+
+/* XXX */
+#define BIT4x2(x,y) uint8_t y:4, x:4
+#define BIT16x2(x,y) uint32_t y:16, x:16
+#define _KERNEL
+#include <dev/firewire/iec13213.h>
+
+extern uint32_t dcons_paddr;
+extern struct console dconsole;
+
+struct crom_src_buf {
+ struct crom_src src;
+ struct crom_chunk root;
+ struct crom_chunk vendor;
+ struct crom_chunk hw;
+ /* for dcons */
+ struct crom_chunk unit;
+ struct crom_chunk spec;
+ struct crom_chunk ver;
+};
+
+static int fw_init(void);
+static int fw_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, char *buf, size_t *rsize);
+static int fw_open(struct open_file *f, ...);
+static int fw_close(struct open_file *f);
+static void fw_print(int verbose);
+static void fw_cleanup(void);
+
+void fw_enable(void);
+
+struct devsw fwohci = {
+ "FW1394", /* 7 chars at most */
+ DEVT_NET,
+ fw_init,
+ fw_strategy,
+ fw_open,
+ fw_close,
+ noioctl,
+ fw_print,
+ fw_cleanup
+};
+
+static struct fwohci_softc fwinfo[MAX_OHCI];
+static int fw_initialized = 0;
+
+static void
+fw_probe(int index, struct fwohci_softc *sc)
+{
+ int err;
+
+ sc->state = FWOHCI_STATE_INIT;
+ err = biospci_find_devclass(
+ 0x0c0010 /* Serial:FireWire:OHCI */,
+ index /* index */,
+ &sc->locator);
+
+ if (err != 0) {
+ sc->state = FWOHCI_STATE_DEAD;
+ return;
+ }
+
+ biospci_write_config(sc->locator,
+ 0x4 /* command */,
+ 0x6 /* enable bus master and memory mapped I/O */,
+ 1 /* word */);
+
+ biospci_read_config(sc->locator, 0x00 /*devid*/, 2 /*dword*/,
+ &sc->devid);
+ biospci_read_config(sc->locator, 0x10 /*base_addr*/, 2 /*dword*/,
+ &sc->base_addr);
+
+ sc->handle = (uint32_t)PTOV(sc->base_addr);
+ sc->bus_id = OREAD(sc, OHCI_BUS_ID);
+
+ return;
+}
+
+static int
+fw_init(void)
+{
+ int i, avail;
+ struct fwohci_softc *sc;
+
+ if (fw_initialized)
+ return (0);
+
+ avail = 0;
+ for (i = 0; i < MAX_OHCI; i ++) {
+ sc = &fwinfo[i];
+ fw_probe(i, sc);
+ if (sc->state == FWOHCI_STATE_DEAD)
+ break;
+ avail ++;
+ break;
+ }
+ fw_initialized = 1;
+
+ return (0);
+}
+
+
+/*
+ * Print information about OHCI chips
+ */
+static void
+fw_print(int verbose)
+{
+ int i;
+ struct fwohci_softc *sc;
+
+ for (i = 0; i < MAX_OHCI; i ++) {
+ sc = &fwinfo[i];
+ if (sc->state == FWOHCI_STATE_DEAD)
+ break;
+ printf("%d: locator=0x%04x devid=0x%08x"
+ " base_addr=0x%08x handle=0x%08x bus_id=0x%08x\n",
+ i, sc->locator, sc->devid,
+ sc->base_addr, sc->handle, sc->bus_id);
+ }
+}
+
+static int
+fw_open(struct open_file *f, ...)
+{
+#if 0
+ va_list ap;
+ struct i386_devdesc *dev;
+ struct open_disk *od;
+ int error;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct i386_devdesc *);
+ va_end(ap);
+#endif
+
+ return (ENXIO);
+}
+
+static int
+fw_close(struct open_file *f)
+{
+ return (0);
+}
+
+static void
+fw_cleanup()
+{
+ struct dcons_buf *db;
+
+ /* invalidate dcons buffer */
+ if (dcons_paddr) {
+ db = (struct dcons_buf *)PTOV(dcons_paddr);
+ db->magic = 0;
+ }
+}
+
+static int
+fw_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
+{
+ return (EIO);
+}
+
+static void
+fw_init_crom(struct fwohci_softc *sc)
+{
+ struct crom_src *src;
+
+ printf("fw_init_crom\n");
+ sc->crom_src_buf = (struct crom_src_buf *)
+ malloc(sizeof(struct crom_src_buf));
+ if (sc->crom_src_buf == NULL)
+ return;
+
+ src = &sc->crom_src_buf->src;
+ bzero(src, sizeof(struct crom_src));
+
+ /* BUS info sample */
+ src->hdr.info_len = 4;
+
+ src->businfo.bus_name = CSR_BUS_NAME_IEEE1394;
+
+ src->businfo.irmc = 1;
+ src->businfo.cmc = 1;
+ src->businfo.isc = 1;
+ src->businfo.bmc = 1;
+ src->businfo.pmc = 0;
+ src->businfo.cyc_clk_acc = 100;
+ src->businfo.max_rec = sc->maxrec;
+ src->businfo.max_rom = MAXROM_4;
+#define FW_GENERATION_CHANGEABLE 2
+ src->businfo.generation = FW_GENERATION_CHANGEABLE;
+ src->businfo.link_spd = sc->speed;
+
+ src->businfo.eui64.hi = sc->eui.hi;
+ src->businfo.eui64.lo = sc->eui.lo;
+
+ STAILQ_INIT(&src->chunk_list);
+
+ sc->crom_src = src;
+ sc->crom_root = &sc->crom_src_buf->root;
+}
+
+static void
+fw_reset_crom(struct fwohci_softc *sc)
+{
+ struct crom_src_buf *buf;
+ struct crom_src *src;
+ struct crom_chunk *root;
+
+ printf("fw_reset\n");
+ if (sc->crom_src_buf == NULL)
+ fw_init_crom(sc);
+
+ buf = sc->crom_src_buf;
+ src = sc->crom_src;
+ root = sc->crom_root;
+
+ STAILQ_INIT(&src->chunk_list);
+
+ bzero(root, sizeof(struct crom_chunk));
+ crom_add_chunk(src, NULL, root, 0);
+ crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
+ /* private company_id */
+ crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
+#ifdef __DragonFly__
+ crom_add_simple_text(src, root, &buf->vendor, "DragonFly Project");
+#else
+ crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project");
+#endif
+}
+
+
+#define ADDR_HI(x) (((x) >> 24) & 0xffffff)
+#define ADDR_LO(x) ((x) & 0xffffff)
+
+static void
+dcons_crom(struct fwohci_softc *sc)
+{
+ struct crom_src_buf *buf;
+ struct crom_src *src;
+ struct crom_chunk *root;
+
+ buf = sc->crom_src_buf;
+ src = sc->crom_src;
+ root = sc->crom_root;
+
+ bzero(&buf->unit, sizeof(struct crom_chunk));
+
+ crom_add_chunk(src, root, &buf->unit, CROM_UDIR);
+ crom_add_entry(&buf->unit, CSRKEY_SPEC, CSRVAL_VENDOR_PRIVATE);
+ crom_add_simple_text(src, &buf->unit, &buf->spec, "FreeBSD");
+ crom_add_entry(&buf->unit, CSRKEY_VER, DCONS_CSR_VAL_VER);
+ crom_add_simple_text(src, &buf->unit, &buf->ver, "dcons");
+ crom_add_entry(&buf->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr));
+ crom_add_entry(&buf->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr));
+}
+
+void
+fw_crom(struct fwohci_softc *sc)
+{
+ struct crom_src *src;
+ void *newrom;
+
+ fw_reset_crom(sc);
+ dcons_crom(sc);
+
+ newrom = malloc(CROMSIZE);
+ src = &sc->crom_src_buf->src;
+ crom_load(src, (uint32_t *)newrom, CROMSIZE);
+ if (bcmp(newrom, sc->config_rom, CROMSIZE) != 0) {
+ /* Bump generation and reload. */
+ src->businfo.generation++;
+
+ /* Handle generation count wraps. */
+ if (src->businfo.generation < 2)
+ src->businfo.generation = 2;
+
+ /* Recalculate CRC to account for generation change. */
+ crom_load(src, (uint32_t *)newrom, CROMSIZE);
+ bcopy(newrom, (void *)sc->config_rom, CROMSIZE);
+ }
+ free(newrom);
+}
+
+static int
+fw_busreset(struct fwohci_softc *sc)
+{
+ int count;
+
+ if (sc->state < FWOHCI_STATE_ENABLED) {
+ printf("fwohci not enabled\n");
+ return(CMD_OK);
+ }
+ fw_crom(sc);
+ fwohci_ibr(sc);
+ count = 0;
+ while (sc->state< FWOHCI_STATE_NORMAL) {
+ fwohci_poll(sc);
+ count ++;
+ if (count > 1000) {
+ printf("give up to wait bus initialize\n");
+ return (-1);
+ }
+ }
+ printf("poll count = %d\n", count);
+ return (0);
+}
+
+void
+fw_enable(void)
+{
+ struct fwohci_softc *sc;
+ int i;
+
+ if (fw_initialized == 0)
+ fw_init();
+
+ for (i = 0; i < MAX_OHCI; i ++) {
+ sc = &fwinfo[i];
+ if (sc->state != FWOHCI_STATE_INIT)
+ break;
+
+ sc->config_rom = (uint32_t *)
+ (((uint32_t)sc->config_rom_buf
+ + (CROMSIZE - 1)) & ~(CROMSIZE - 1));
+#if 0
+ printf("configrom: %08p %08p\n",
+ sc->config_rom_buf, sc->config_rom);
+#endif
+ if (fwohci_init(sc, 0) == 0) {
+ sc->state = FWOHCI_STATE_ENABLED;
+ fw_busreset(sc);
+ } else
+ sc->state = FWOHCI_STATE_DEAD;
+ }
+}
+
+void
+fw_poll(void)
+{
+ struct fwohci_softc *sc;
+ int i;
+
+ if (fw_initialized == 0)
+ return;
+
+ for (i = 0; i < MAX_OHCI; i ++) {
+ sc = &fwinfo[i];
+ if (sc->state < FWOHCI_STATE_ENABLED)
+ break;
+ fwohci_poll(sc);
+ }
+}
+
+#if 0 /* for debug */
+static int
+fw_busreset_cmd(int argc, char *argv[])
+{
+ struct fwohci_softc *sc;
+ int i;
+
+ for (i = 0; i < MAX_OHCI; i ++) {
+ sc = &fwinfo[i];
+ if (sc->state < FWOHCI_STATE_INIT)
+ break;
+ fw_busreset(sc);
+ }
+ return(CMD_OK);
+}
+
+static int
+fw_poll_cmd(int argc, char *argv[])
+{
+ fw_poll();
+ return(CMD_OK);
+}
+
+static int
+fw_enable_cmd(int argc, char *argv[])
+{
+ fw_print(0);
+ fw_enable();
+ return(CMD_OK);
+}
+
+
+static int
+dcons_enable(int argc, char *argv[])
+{
+ dconsole.c_init(0);
+ fw_enable();
+ dconsole.c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
+ return(CMD_OK);
+}
+
+static int
+dcons_read(int argc, char *argv[])
+{
+ char c;
+ while (dconsole.c_ready()) {
+ c = dconsole.c_in();
+ printf("%c", c);
+ }
+ printf("\r\n");
+ return(CMD_OK);
+}
+
+static int
+dcons_write(int argc, char *argv[])
+{
+ int len, i;
+ if (argc < 2)
+ return(CMD_OK);
+
+ len = strlen(argv[1]);
+ for (i = 0; i < len; i ++)
+ dconsole.c_out(argv[1][i]);
+ dconsole.c_out('\r');
+ dconsole.c_out('\n');
+ return(CMD_OK);
+}
+COMMAND_SET(firewire, "firewire", "enable firewire", fw_enable_cmd);
+COMMAND_SET(fwbusreset, "fwbusreset", "firewire busreset", fw_busreset_cmd);
+COMMAND_SET(fwpoll, "fwpoll", "firewire poll", fw_poll_cmd);
+COMMAND_SET(dcons, "dcons", "enable dcons", dcons_enable);
+COMMAND_SET(dread, "dread", "read from dcons", dcons_read);
+COMMAND_SET(dwrite, "dwrite", "write to dcons", dcons_write);
+#endif
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/fwohci.c b/usr/src/boot/sys/boot/i386/libfirewire/fwohci.c
new file mode 100644
index 0000000000..326e44b2ec
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/fwohci.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2003 Hidetoshi Shimokawa
+ * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the acknowledgement as bellow:
+ *
+ * This product includes software developed by K. Kobayashi and H. Shimokawa
+ *
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stand.h>
+#include <btxv86.h>
+#include <bootstrap.h>
+
+#include "fwohci.h"
+#include "fwohcireg.h"
+#include <dev/firewire/firewire_phy.h>
+
+static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t);
+static uint32_t fwphy_rddata ( struct fwohci_softc *, uint32_t);
+int firewire_debug=0;
+
+#if 0
+#define device_printf(a, x, ...) printf("FW1394: " x, ## __VA_ARGS__)
+#else
+#define device_printf(a, x, ...)
+#endif
+
+#define device_t int
+#define DELAY(x) delay(x)
+
+#define MAX_SPEED 3
+#define MAXREC(x) (2 << (x))
+char *linkspeed[] = {
+ "S100", "S200", "S400", "S800",
+ "S1600", "S3200", "undef", "undef"
+};
+
+#define FW_EUI64_BYTE(eui, x) \
+ ((((x)<4)? \
+ ((eui)->hi >> (8*(3-(x)))): \
+ ((eui)->lo >> (8*(7-(x)))) \
+ ) & 0xff)
+
+/*
+ * Communication with PHY device
+ */
+static uint32_t
+fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data)
+{
+ uint32_t fun;
+
+ addr &= 0xf;
+ data &= 0xff;
+
+ fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA));
+ OWRITE(sc, OHCI_PHYACCESS, fun);
+ DELAY(100);
+
+ return(fwphy_rddata( sc, addr));
+}
+
+static uint32_t
+fwphy_rddata(struct fwohci_softc *sc, u_int addr)
+{
+ uint32_t fun, stat;
+ u_int i, retry = 0;
+
+ addr &= 0xf;
+#define MAX_RETRY 100
+again:
+ OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
+ fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
+ OWRITE(sc, OHCI_PHYACCESS, fun);
+ for ( i = 0 ; i < MAX_RETRY ; i ++ ){
+ fun = OREAD(sc, OHCI_PHYACCESS);
+ if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
+ break;
+ DELAY(100);
+ }
+ if(i >= MAX_RETRY) {
+ if (firewire_debug)
+ device_printf(sc->fc.dev, "phy read failed(1).\n");
+ if (++retry < MAX_RETRY) {
+ DELAY(100);
+ goto again;
+ }
+ }
+ /* Make sure that SCLK is started */
+ stat = OREAD(sc, FWOHCI_INTSTAT);
+ if ((stat & OHCI_INT_REG_FAIL) != 0 ||
+ ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
+ if (firewire_debug)
+ device_printf(sc->fc.dev, "phy read failed(2).\n");
+ if (++retry < MAX_RETRY) {
+ DELAY(100);
+ goto again;
+ }
+ }
+ if (firewire_debug || retry >= MAX_RETRY)
+ device_printf(sc->fc.dev,
+ "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry);
+#undef MAX_RETRY
+ return((fun >> PHYDEV_RDDATA )& 0xff);
+}
+
+
+static int
+fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
+{
+ uint32_t reg, reg2;
+ int e1394a = 1;
+ int nport, speed;
+/*
+ * probe PHY parameters
+ * 0. to prove PHY version, whether compliance of 1394a.
+ * 1. to probe maximum speed supported by the PHY and
+ * number of port supported by core-logic.
+ * It is not actually available port on your PC .
+ */
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS);
+ DELAY(500);
+
+ reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
+
+ if((reg >> 5) != 7 ){
+ nport = reg & FW_PHY_NP;
+ speed = reg & FW_PHY_SPD >> 6;
+ if (speed > MAX_SPEED) {
+ device_printf(dev, "invalid speed %d (fixed to %d).\n",
+ speed, MAX_SPEED);
+ speed = MAX_SPEED;
+ }
+ device_printf(dev,
+ "Phy 1394 only %s, %d ports.\n",
+ linkspeed[speed], nport);
+ }else{
+ reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
+ nport = reg & FW_PHY_NP;
+ speed = (reg2 & FW_PHY_ESPD) >> 5;
+ if (speed > MAX_SPEED) {
+ device_printf(dev, "invalid speed %d (fixed to %d).\n",
+ speed, MAX_SPEED);
+ speed = MAX_SPEED;
+ }
+ device_printf(dev,
+ "Phy 1394a available %s, %d ports.\n",
+ linkspeed[speed], nport);
+
+ /* check programPhyEnable */
+ reg2 = fwphy_rddata(sc, 5);
+#if 0
+ if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) {
+#else /* XXX force to enable 1394a */
+ if (e1394a) {
+#endif
+ if (firewire_debug)
+ device_printf(dev,
+ "Enable 1394a Enhancements\n");
+ /* enable EAA EMC */
+ reg2 |= 0x03;
+ /* set aPhyEnhanceEnable */
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN);
+ OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY);
+ } else {
+ /* for safe */
+ reg2 &= ~0x83;
+ }
+ reg2 = fwphy_wrdata(sc, 5, reg2);
+ }
+ sc->speed = speed;
+
+ reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
+ if((reg >> 5) == 7 ){
+ reg = fwphy_rddata(sc, 4);
+ reg |= 1 << 6;
+ fwphy_wrdata(sc, 4, reg);
+ reg = fwphy_rddata(sc, 4);
+ }
+ return 0;
+}
+
+
+void
+fwohci_reset(struct fwohci_softc *sc, device_t dev)
+{
+ int i, max_rec, speed;
+ uint32_t reg, reg2;
+
+ /* Disable interrupts */
+ OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
+
+ /* FLUSH FIFO and reset Transmitter/Reciever */
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
+ if (firewire_debug)
+ device_printf(dev, "resetting OHCI...");
+ i = 0;
+ while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
+ if (i++ > 100) break;
+ DELAY(1000);
+ }
+ if (firewire_debug)
+ printf("done (loop=%d)\n", i);
+
+ /* Probe phy */
+ fwohci_probe_phy(sc, dev);
+
+ /* Probe link */
+ reg = OREAD(sc, OHCI_BUS_OPT);
+ reg2 = reg | OHCI_BUSFNC;
+ max_rec = (reg & 0x0000f000) >> 12;
+ speed = (reg & 0x00000007);
+ device_printf(dev, "Link %s, max_rec %d bytes.\n",
+ linkspeed[speed], MAXREC(max_rec));
+ /* XXX fix max_rec */
+ sc->maxrec = sc->speed + 8;
+ if (max_rec != sc->maxrec) {
+ reg2 = (reg2 & 0xffff0fff) | (sc->maxrec << 12);
+ device_printf(dev, "max_rec %d -> %d\n",
+ MAXREC(max_rec), MAXREC(sc->maxrec));
+ }
+ if (firewire_debug)
+ device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
+ OWRITE(sc, OHCI_BUS_OPT, reg2);
+
+ /* Initialize registers */
+ OWRITE(sc, OHCI_CROMHDR, sc->config_rom[0]);
+ OWRITE(sc, OHCI_CROMPTR, VTOP(sc->config_rom));
+#if 0
+ OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
+#endif
+ OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND);
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR);
+#if 0
+ OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
+#endif
+
+ /* Enable link */
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
+}
+
+int
+fwohci_init(struct fwohci_softc *sc, device_t dev)
+{
+ int i, mver;
+ uint32_t reg;
+ uint8_t ui[8];
+
+/* OHCI version */
+ reg = OREAD(sc, OHCI_VERSION);
+ mver = (reg >> 16) & 0xff;
+ device_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
+ mver, reg & 0xff, (reg>>24) & 1);
+ if (mver < 1 || mver > 9) {
+ device_printf(dev, "invalid OHCI version\n");
+ return (ENXIO);
+ }
+
+/* Available Isochronous DMA channel probe */
+ OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
+ OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
+ reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
+ OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
+ OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
+ for (i = 0; i < 0x20; i++)
+ if ((reg & (1 << i)) == 0)
+ break;
+ device_printf(dev, "No. of Isochronous channels is %d.\n", i);
+ if (i == 0)
+ return (ENXIO);
+
+#if 0
+/* SID recieve buffer must align 2^11 */
+#define OHCI_SIDSIZE (1 << 11)
+ sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
+ &sc->sid_dma, BUS_DMA_WAITOK);
+ if (sc->sid_buf == NULL) {
+ device_printf(dev, "sid_buf alloc failed.");
+ return ENOMEM;
+ }
+#endif
+
+ sc->eui.hi = OREAD(sc, FWOHCIGUID_H);
+ sc->eui.lo = OREAD(sc, FWOHCIGUID_L);
+ for( i = 0 ; i < 8 ; i ++)
+ ui[i] = FW_EUI64_BYTE(&sc->eui,i);
+ device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
+ fwohci_reset(sc, dev);
+
+ return 0;
+}
+
+void
+fwohci_ibr(struct fwohci_softc *sc)
+{
+ uint32_t fun;
+
+ device_printf(sc->dev, "Initiate bus reset\n");
+
+ /*
+ * Make sure our cached values from the config rom are
+ * initialised.
+ */
+ OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0]));
+ OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2]));
+
+ /*
+ * Set root hold-off bit so that non cyclemaster capable node
+ * shouldn't became the root node.
+ */
+#if 1
+ fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
+ fun |= FW_PHY_IBR;
+ fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
+#else /* Short bus reset */
+ fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
+ fun |= FW_PHY_ISBR;
+ fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
+#endif
+}
+
+
+void
+fwohci_sid(struct fwohci_softc *sc)
+{
+ uint32_t node_id;
+ int plen;
+
+ node_id = OREAD(sc, FWOHCI_NODEID);
+ if (!(node_id & OHCI_NODE_VALID)) {
+#if 0
+ printf("Bus reset failure\n");
+#endif
+ return;
+ }
+
+ /* Enable bus reset interrupt */
+ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R);
+ /* Allow async. request to us */
+ OWRITE(sc, OHCI_AREQHI, 1 << 31);
+ /* XXX insecure ?? */
+ OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
+ OWRITE(sc, OHCI_PREQLO, 0xffffffff);
+ OWRITE(sc, OHCI_PREQUPPER, 0x10000);
+ /* Set ATRetries register */
+ OWRITE(sc, OHCI_ATRETRY, 1<<(13+16) | 0xfff);
+/*
+** Checking whether the node is root or not. If root, turn on
+** cycle master.
+*/
+ plen = OREAD(sc, OHCI_SID_CNT);
+ device_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
+ node_id, (plen >> 16) & 0xff);
+ if (node_id & OHCI_NODE_ROOT) {
+ device_printf(sc->dev, "CYCLEMASTER mode\n");
+ OWRITE(sc, OHCI_LNKCTL,
+ OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
+ } else {
+ device_printf(sc->dev, "non CYCLEMASTER mode\n");
+ OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
+ OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
+ }
+ if (plen & OHCI_SID_ERR) {
+ device_printf(fc->dev, "SID Error\n");
+ return;
+ }
+ device_printf(sc->dev, "bus reset phase done\n");
+ sc->state = FWOHCI_STATE_NORMAL;
+}
+
+static void
+fwohci_intr_body(struct fwohci_softc *sc, uint32_t stat, int count)
+{
+#undef OHCI_DEBUG
+#ifdef OHCI_DEBUG
+#if 0
+ if(stat & OREAD(sc, FWOHCI_INTMASK))
+#else
+ if (1)
+#endif
+ device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
+ stat & OHCI_INT_EN ? "DMA_EN ":"",
+ stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
+ stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
+ stat & OHCI_INT_ERR ? "INT_ERR ":"",
+ stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
+ stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
+ stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
+ stat & OHCI_INT_CYC_START ? "CYC_START ":"",
+ stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
+ stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
+ stat & OHCI_INT_PHY_SID ? "SID ":"",
+ stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
+ stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
+ stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
+ stat & OHCI_INT_DMA_IT ? "DMA_IT " :"",
+ stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"",
+ stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"",
+ stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"",
+ stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"",
+ stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"",
+ stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"",
+ stat, OREAD(sc, FWOHCI_INTMASK)
+ );
+#endif
+/* Bus reset */
+ if(stat & OHCI_INT_PHY_BUS_R ){
+ device_printf(fc->dev, "BUS reset\n");
+ if (sc->state == FWOHCI_STATE_BUSRESET)
+ goto busresetout;
+ sc->state = FWOHCI_STATE_BUSRESET;
+ /* Disable bus reset interrupt until sid recv. */
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
+
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
+ OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
+
+ OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0]));
+ OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2]));
+ } else if (sc->state == FWOHCI_STATE_BUSRESET) {
+ fwohci_sid(sc);
+ }
+busresetout:
+ return;
+}
+
+static uint32_t
+fwochi_check_stat(struct fwohci_softc *sc)
+{
+ uint32_t stat;
+
+ stat = OREAD(sc, FWOHCI_INTSTAT);
+ if (stat == 0xffffffff) {
+ device_printf(sc->fc.dev,
+ "device physically ejected?\n");
+ return(stat);
+ }
+ if (stat)
+ OWRITE(sc, FWOHCI_INTSTATCLR, stat);
+ return(stat);
+}
+
+void
+fwohci_poll(struct fwohci_softc *sc)
+{
+ uint32_t stat;
+
+ stat = fwochi_check_stat(sc);
+ if (stat != 0xffffffff)
+ fwohci_intr_body(sc, stat, 1);
+}
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/fwohci.h b/usr/src/boot/sys/boot/i386/libfirewire/fwohci.h
new file mode 100644
index 0000000000..4a93220b31
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/fwohci.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2007 Hidetoshi Shimokawa
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the acknowledgement as bellow:
+ *
+ * This product includes software developed by K. Kobayashi and H. Shimokawa
+ *
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#define MAX_OHCI 5
+#define CROMSIZE 0x400
+
+struct fw_eui64 {
+ uint32_t hi, lo;
+};
+
+struct fwohci_softc {
+ uint32_t locator;
+ uint32_t devid;
+ uint32_t base_addr;
+ uint32_t bus_id;
+ uint32_t handle;
+ int32_t state;
+ struct crom_src_buf *crom_src_buf;
+ struct crom_src *crom_src;
+ struct crom_chunk *crom_root;
+ struct fw_eui64 eui;
+ int speed;
+ int maxrec;
+ uint32_t *config_rom;
+ char config_rom_buf[CROMSIZE*2]; /* double size for alignment */
+};
+
+int fwohci_init(struct fwohci_softc *, int);
+void fwohci_ibr(struct fwohci_softc *);
+void fwohci_poll(struct fwohci_softc *);
+
+#define FWOHCI_STATE_DEAD (-1)
+#define FWOHCI_STATE_INIT 0
+#define FWOHCI_STATE_ENABLED 1
+#define FWOHCI_STATE_BUSRESET 2
+#define FWOHCI_STATE_NORMAL 3
+
+#define OREAD(f, o) (*(volatile uint32_t *)((f)->handle + (o)))
+#define OWRITE(f, o, v) (*(volatile uint32_t *)((f)->handle + (o)) = (v))
+
+#define OHCI_VERSION 0x00
+#define OHCI_ATRETRY 0x08
+#define OHCI_CROMHDR 0x18
+#define OHCI_BUS_ID 0x1c
+#define OHCI_BUS_OPT 0x20
+#define OHCI_BUSIRMC (1U << 31)
+#define OHCI_BUSCMC (1 << 30)
+#define OHCI_BUSISC (1 << 29)
+#define OHCI_BUSBMC (1 << 28)
+#define OHCI_BUSPMC (1 << 27)
+#define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
+ OHCI_BUSBMC | OHCI_BUSPMC
+
+#define OHCI_EUID_HI 0x24
+#define OHCI_EUID_LO 0x28
+
+#define OHCI_CROMPTR 0x34
+#define OHCI_HCCCTL 0x50
+#define OHCI_HCCCTLCLR 0x54
+#define OHCI_AREQHI 0x100
+#define OHCI_AREQHICLR 0x104
+#define OHCI_AREQLO 0x108
+#define OHCI_AREQLOCLR 0x10c
+#define OHCI_PREQHI 0x110
+#define OHCI_PREQHICLR 0x114
+#define OHCI_PREQLO 0x118
+#define OHCI_PREQLOCLR 0x11c
+#define OHCI_PREQUPPER 0x120
+
+#define OHCI_SID_BUF 0x64
+#define OHCI_SID_CNT 0x68
+#define OHCI_SID_ERR (1U << 31)
+#define OHCI_SID_CNT_MASK 0xffc
+
+#define OHCI_IT_STAT 0x90
+#define OHCI_IT_STATCLR 0x94
+#define OHCI_IT_MASK 0x98
+#define OHCI_IT_MASKCLR 0x9c
+
+#define OHCI_IR_STAT 0xa0
+#define OHCI_IR_STATCLR 0xa4
+#define OHCI_IR_MASK 0xa8
+#define OHCI_IR_MASKCLR 0xac
+
+#define OHCI_LNKCTL 0xe0
+#define OHCI_LNKCTLCLR 0xe4
+
+#define OHCI_PHYACCESS 0xec
+#define OHCI_CYCLETIMER 0xf0
+
+#define OHCI_DMACTL(off) (off)
+#define OHCI_DMACTLCLR(off) (off + 4)
+#define OHCI_DMACMD(off) (off + 0xc)
+#define OHCI_DMAMATCH(off) (off + 0x10)
+
+#define OHCI_ATQOFF 0x180
+#define OHCI_ATQCTL OHCI_ATQOFF
+#define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4)
+#define OHCI_ATQCMD (OHCI_ATQOFF + 0xc)
+#define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10)
+
+#define OHCI_ATSOFF 0x1a0
+#define OHCI_ATSCTL OHCI_ATSOFF
+#define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4)
+#define OHCI_ATSCMD (OHCI_ATSOFF + 0xc)
+#define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10)
+
+#define OHCI_ARQOFF 0x1c0
+#define OHCI_ARQCTL OHCI_ARQOFF
+#define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4)
+#define OHCI_ARQCMD (OHCI_ARQOFF + 0xc)
+#define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10)
+
+#define OHCI_ARSOFF 0x1e0
+#define OHCI_ARSCTL OHCI_ARSOFF
+#define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4)
+#define OHCI_ARSCMD (OHCI_ARSOFF + 0xc)
+#define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10)
+
+#define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH))
+#define OHCI_ITCTL(CH) (OHCI_ITOFF(CH))
+#define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4)
+#define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc)
+
+#define OHCI_IROFF(CH) (0x400 + 0x20 * (CH))
+#define OHCI_IRCTL(CH) (OHCI_IROFF(CH))
+#define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4)
+#define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc)
+#define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10)
diff --git a/usr/src/boot/sys/boot/i386/libfirewire/fwohcireg.h b/usr/src/boot/sys/boot/i386/libfirewire/fwohcireg.h
new file mode 100644
index 0000000000..d57870cd62
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libfirewire/fwohcireg.h
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2003 Hidetoshi Shimokawa
+ * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the acknowledgement as bellow:
+ *
+ * This product includes software developed by K. Kobayashi and H. Shimokawa
+ *
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#define PCI_CBMEM PCIR_BAR(0)
+
+#define FW_VENDORID_NATSEMI 0x100B
+#define FW_VENDORID_NEC 0x1033
+#define FW_VENDORID_SIS 0x1039
+#define FW_VENDORID_TI 0x104c
+#define FW_VENDORID_SONY 0x104d
+#define FW_VENDORID_VIA 0x1106
+#define FW_VENDORID_RICOH 0x1180
+#define FW_VENDORID_APPLE 0x106b
+#define FW_VENDORID_LUCENT 0x11c1
+#define FW_VENDORID_INTEL 0x8086
+#define FW_VENDORID_ADAPTEC 0x9004
+
+#define FW_DEVICE_CS4210 (0x000f << 16)
+#define FW_DEVICE_UPD861 (0x0063 << 16)
+#define FW_DEVICE_UPD871 (0x00ce << 16)
+#define FW_DEVICE_UPD72870 (0x00cd << 16)
+#define FW_DEVICE_UPD72873 (0x00e7 << 16)
+#define FW_DEVICE_UPD72874 (0x00f2 << 16)
+#define FW_DEVICE_TITSB22 (0x8009 << 16)
+#define FW_DEVICE_TITSB23 (0x8019 << 16)
+#define FW_DEVICE_TITSB26 (0x8020 << 16)
+#define FW_DEVICE_TITSB43 (0x8021 << 16)
+#define FW_DEVICE_TITSB43A (0x8023 << 16)
+#define FW_DEVICE_TITSB43AB23 (0x8024 << 16)
+#define FW_DEVICE_TITSB82AA2 (0x8025 << 16)
+#define FW_DEVICE_TITSB43AB21 (0x8026 << 16)
+#define FW_DEVICE_TIPCI4410A (0x8017 << 16)
+#define FW_DEVICE_TIPCI4450 (0x8011 << 16)
+#define FW_DEVICE_TIPCI4451 (0x8027 << 16)
+#define FW_DEVICE_CXD1947 (0x8009 << 16)
+#define FW_DEVICE_CXD3222 (0x8039 << 16)
+#define FW_DEVICE_VT6306 (0x3044 << 16)
+#define FW_DEVICE_R5C551 (0x0551 << 16)
+#define FW_DEVICE_R5C552 (0x0552 << 16)
+#define FW_DEVICE_PANGEA (0x0030 << 16)
+#define FW_DEVICE_UNINORTH (0x0031 << 16)
+#define FW_DEVICE_AIC5800 (0x5800 << 16)
+#define FW_DEVICE_FW322 (0x5811 << 16)
+#define FW_DEVICE_7007 (0x7007 << 16)
+#define FW_DEVICE_82372FB (0x7605 << 16)
+
+#define PCI_INTERFACE_OHCI 0x10
+
+#define FW_OHCI_BASE_REG 0x10
+
+#define OHCI_DMA_ITCH 0x20
+#define OHCI_DMA_IRCH 0x20
+
+#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH)
+
+
+typedef uint32_t fwohcireg_t;
+
+/* for PCI */
+#if BYTE_ORDER == BIG_ENDIAN
+#define FWOHCI_DMA_WRITE(x, y) ((x) = htole32(y))
+#define FWOHCI_DMA_READ(x) le32toh(x)
+#define FWOHCI_DMA_SET(x, y) ((x) |= htole32(y))
+#define FWOHCI_DMA_CLEAR(x, y) ((x) &= htole32(~(y)))
+#else
+#define FWOHCI_DMA_WRITE(x, y) ((x) = (y))
+#define FWOHCI_DMA_READ(x) (x)
+#define FWOHCI_DMA_SET(x, y) ((x) |= (y))
+#define FWOHCI_DMA_CLEAR(x, y) ((x) &= ~(y))
+#endif
+
+struct fwohcidb {
+ union {
+ struct {
+ uint32_t cmd;
+ uint32_t addr;
+ uint32_t depend;
+ uint32_t res;
+ } desc;
+ uint32_t immed[4];
+ } db;
+#define OHCI_STATUS_SHIFT 16
+#define OHCI_COUNT_MASK 0xffff
+#define OHCI_OUTPUT_MORE (0 << 28)
+#define OHCI_OUTPUT_LAST (1 << 28)
+#define OHCI_INPUT_MORE (2 << 28)
+#define OHCI_INPUT_LAST (3 << 28)
+#define OHCI_STORE_QUAD (4 << 28)
+#define OHCI_LOAD_QUAD (5 << 28)
+#define OHCI_NOP (6 << 28)
+#define OHCI_STOP (7 << 28)
+#define OHCI_STORE (8 << 28)
+#define OHCI_CMD_MASK (0xf << 28)
+
+#define OHCI_UPDATE (1 << 27)
+
+#define OHCI_KEY_ST0 (0 << 24)
+#define OHCI_KEY_ST1 (1 << 24)
+#define OHCI_KEY_ST2 (2 << 24)
+#define OHCI_KEY_ST3 (3 << 24)
+#define OHCI_KEY_REGS (5 << 24)
+#define OHCI_KEY_SYS (6 << 24)
+#define OHCI_KEY_DEVICE (7 << 24)
+#define OHCI_KEY_MASK (7 << 24)
+
+#define OHCI_INTERRUPT_NEVER (0 << 20)
+#define OHCI_INTERRUPT_TRUE (1 << 20)
+#define OHCI_INTERRUPT_FALSE (2 << 20)
+#define OHCI_INTERRUPT_ALWAYS (3 << 20)
+
+#define OHCI_BRANCH_NEVER (0 << 18)
+#define OHCI_BRANCH_TRUE (1 << 18)
+#define OHCI_BRANCH_FALSE (2 << 18)
+#define OHCI_BRANCH_ALWAYS (3 << 18)
+#define OHCI_BRANCH_MASK (3 << 18)
+
+#define OHCI_WAIT_NEVER (0 << 16)
+#define OHCI_WAIT_TRUE (1 << 16)
+#define OHCI_WAIT_FALSE (2 << 16)
+#define OHCI_WAIT_ALWAYS (3 << 16)
+};
+
+#define OHCI_SPD_S100 0x4
+#define OHCI_SPD_S200 0x1
+#define OHCI_SPD_S400 0x2
+
+
+#define FWOHCIEV_NOSTAT 0
+#define FWOHCIEV_LONGP 2
+#define FWOHCIEV_MISSACK 3
+#define FWOHCIEV_UNDRRUN 4
+#define FWOHCIEV_OVRRUN 5
+#define FWOHCIEV_DESCERR 6
+#define FWOHCIEV_DTRDERR 7
+#define FWOHCIEV_DTWRERR 8
+#define FWOHCIEV_BUSRST 9
+#define FWOHCIEV_TIMEOUT 0xa
+#define FWOHCIEV_TCODERR 0xb
+#define FWOHCIEV_UNKNOWN 0xe
+#define FWOHCIEV_FLUSHED 0xf
+#define FWOHCIEV_ACKCOMPL 0x11
+#define FWOHCIEV_ACKPEND 0x12
+#define FWOHCIEV_ACKBSX 0x14
+#define FWOHCIEV_ACKBSA 0x15
+#define FWOHCIEV_ACKBSB 0x16
+#define FWOHCIEV_ACKTARD 0x1b
+#define FWOHCIEV_ACKDERR 0x1d
+#define FWOHCIEV_ACKTERR 0x1e
+
+#define FWOHCIEV_MASK 0x1f
+
+struct ohci_dma{
+ fwohcireg_t cntl;
+
+#define OHCI_CNTL_CYCMATCH_S (0x1 << 31)
+
+#define OHCI_CNTL_BUFFIL (0x1 << 31)
+#define OHCI_CNTL_ISOHDR (0x1 << 30)
+#define OHCI_CNTL_CYCMATCH_R (0x1 << 29)
+#define OHCI_CNTL_MULTICH (0x1 << 28)
+
+#define OHCI_CNTL_DMA_RUN (0x1 << 15)
+#define OHCI_CNTL_DMA_WAKE (0x1 << 12)
+#define OHCI_CNTL_DMA_DEAD (0x1 << 11)
+#define OHCI_CNTL_DMA_ACTIVE (0x1 << 10)
+#define OHCI_CNTL_DMA_BT (0x1 << 8)
+#define OHCI_CNTL_DMA_BAD (0x1 << 7)
+#define OHCI_CNTL_DMA_STAT (0xff)
+
+ fwohcireg_t cntl_clr;
+ fwohcireg_t dummy0;
+ fwohcireg_t cmd;
+ fwohcireg_t match;
+ fwohcireg_t dummy1;
+ fwohcireg_t dummy2;
+ fwohcireg_t dummy3;
+};
+
+struct ohci_itdma{
+ fwohcireg_t cntl;
+ fwohcireg_t cntl_clr;
+ fwohcireg_t dummy0;
+ fwohcireg_t cmd;
+};
+
+struct ohci_registers {
+ fwohcireg_t ver; /* Version No. 0x0 */
+ fwohcireg_t guid; /* GUID_ROM No. 0x4 */
+ fwohcireg_t retry; /* AT retries 0x8 */
+#define FWOHCI_RETRY 0x8
+ fwohcireg_t csr_data; /* CSR data 0xc */
+ fwohcireg_t csr_cmp; /* CSR compare 0x10 */
+ fwohcireg_t csr_cntl; /* CSR compare 0x14 */
+ fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */
+ fwohcireg_t bus_id; /* BUS_ID 0x1c */
+ fwohcireg_t bus_opt; /* BUS option 0x20 */
+#define FWOHCIGUID_H 0x24
+#define FWOHCIGUID_L 0x28
+ fwohcireg_t guid_hi; /* GUID hi 0x24 */
+ fwohcireg_t guid_lo; /* GUID lo 0x28 */
+ fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */
+ fwohcireg_t config_rom; /* config ROM map 0x34 */
+ fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */
+ fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */
+ fwohcireg_t vendor; /* vendor ID 0x40 */
+ fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */
+ fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */
+ fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */
+#define OHCI_HCC_BIBIV (1U << 31) /* BIBimage Valid */
+#define OHCI_HCC_BIGEND (1 << 30) /* noByteSwapData */
+#define OHCI_HCC_PRPHY (1 << 23) /* programPhyEnable */
+#define OHCI_HCC_PHYEN (1 << 22) /* aPhyEnhanceEnable */
+#define OHCI_HCC_LPS (1 << 19) /* LPS */
+#define OHCI_HCC_POSTWR (1 << 18) /* postedWriteEnable */
+#define OHCI_HCC_LINKEN (1 << 17) /* linkEnable */
+#define OHCI_HCC_RESET (1 << 16) /* softReset */
+ fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */
+ fwohcireg_t dummy3[1]; /* dummy 0x60 */
+ fwohcireg_t sid_buf; /* self id buffer 0x64 */
+ fwohcireg_t sid_cnt; /* self id count 0x68 */
+ fwohcireg_t dummy4[1]; /* dummy 0x6c */
+ fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */
+ fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */
+ fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */
+ fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */
+#define FWOHCI_INTSTAT 0x80
+#define FWOHCI_INTSTATCLR 0x84
+#define FWOHCI_INTMASK 0x88
+#define FWOHCI_INTMASKCLR 0x8c
+ fwohcireg_t int_stat; /* 0x80 */
+ fwohcireg_t int_clear; /* 0x84 */
+ fwohcireg_t int_mask; /* 0x88 */
+ fwohcireg_t int_mask_clear; /* 0x8c */
+ fwohcireg_t it_int_stat; /* 0x90 */
+ fwohcireg_t it_int_clear; /* 0x94 */
+ fwohcireg_t it_int_mask; /* 0x98 */
+ fwohcireg_t it_mask_clear; /* 0x9c */
+ fwohcireg_t ir_int_stat; /* 0xa0 */
+ fwohcireg_t ir_int_clear; /* 0xa4 */
+ fwohcireg_t ir_int_mask; /* 0xa8 */
+ fwohcireg_t ir_mask_clear; /* 0xac */
+ fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */
+ fwohcireg_t fairness; /* fairness control 0xdc */
+ fwohcireg_t link_cntl; /* Chip control 0xe0*/
+ fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/
+#define FWOHCI_NODEID 0xe8
+ fwohcireg_t node; /* Node ID 0xe8 */
+#define OHCI_NODE_VALID (1U << 31)
+#define OHCI_NODE_ROOT (1 << 30)
+
+#define OHCI_ASYSRCBUS 1
+
+ fwohcireg_t phy_access; /* PHY cntl 0xec */
+#define PHYDEV_RDDONE (1<<31)
+#define PHYDEV_RDCMD (1<<15)
+#define PHYDEV_WRCMD (1<<14)
+#define PHYDEV_REGADDR 8
+#define PHYDEV_WRDATA 0
+#define PHYDEV_RDADDR 24
+#define PHYDEV_RDDATA 16
+
+ fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */
+ fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */
+ fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */
+ fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */
+ fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */
+ fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */
+ fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */
+ fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */
+ fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */
+ fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */
+
+ fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */
+
+ fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */
+
+ /* 0x180, 0x184, 0x188, 0x18c */
+ /* 0x190, 0x194, 0x198, 0x19c */
+ /* 0x1a0, 0x1a4, 0x1a8, 0x1ac */
+ /* 0x1b0, 0x1b4, 0x1b8, 0x1bc */
+ /* 0x1c0, 0x1c4, 0x1c8, 0x1cc */
+ /* 0x1d0, 0x1d4, 0x1d8, 0x1dc */
+ /* 0x1e0, 0x1e4, 0x1e8, 0x1ec */
+ /* 0x1f0, 0x1f4, 0x1f8, 0x1fc */
+ struct ohci_dma dma_ch[0x4];
+
+ /* 0x200, 0x204, 0x208, 0x20c */
+ /* 0x210, 0x204, 0x208, 0x20c */
+ struct ohci_itdma dma_itch[0x20];
+
+ /* 0x400, 0x404, 0x408, 0x40c */
+ /* 0x410, 0x404, 0x408, 0x40c */
+ struct ohci_dma dma_irch[0x20];
+};
+
+#define OHCI_CNTL_CYCSRC (0x1 << 22)
+#define OHCI_CNTL_CYCMTR (0x1 << 21)
+#define OHCI_CNTL_CYCTIMER (0x1 << 20)
+#define OHCI_CNTL_PHYPKT (0x1 << 10)
+#define OHCI_CNTL_SID (0x1 << 9)
+
+#define OHCI_INT_DMA_ATRQ (0x1 << 0)
+#define OHCI_INT_DMA_ATRS (0x1 << 1)
+#define OHCI_INT_DMA_ARRQ (0x1 << 2)
+#define OHCI_INT_DMA_ARRS (0x1 << 3)
+#define OHCI_INT_DMA_PRRQ (0x1 << 4)
+#define OHCI_INT_DMA_PRRS (0x1 << 5)
+#define OHCI_INT_DMA_IT (0x1 << 6)
+#define OHCI_INT_DMA_IR (0x1 << 7)
+#define OHCI_INT_PW_ERR (0x1 << 8)
+#define OHCI_INT_LR_ERR (0x1 << 9)
+
+#define OHCI_INT_PHY_SID (0x1 << 16)
+#define OHCI_INT_PHY_BUS_R (0x1 << 17)
+
+#define OHCI_INT_REG_FAIL (0x1 << 18)
+
+#define OHCI_INT_PHY_INT (0x1 << 19)
+#define OHCI_INT_CYC_START (0x1 << 20)
+#define OHCI_INT_CYC_64SECOND (0x1 << 21)
+#define OHCI_INT_CYC_LOST (0x1 << 22)
+#define OHCI_INT_CYC_ERR (0x1 << 23)
+
+#define OHCI_INT_ERR (0x1 << 24)
+#define OHCI_INT_CYC_LONG (0x1 << 25)
+#define OHCI_INT_PHY_REG (0x1 << 26)
+
+#define OHCI_INT_EN (0x1 << 31)
+
+#define IP_CHANNELS 0x0234
+#define FWOHCI_MAXREC 2048
+
+#define OHCI_ISORA 0x02
+#define OHCI_ISORB 0x04
+
+#define FWOHCITCODE_PHY 0xe
diff --git a/usr/src/boot/sys/boot/i386/libi386/Makefile b/usr/src/boot/sys/boot/i386/libi386/Makefile
new file mode 100644
index 0000000000..f3780e856e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/Makefile
@@ -0,0 +1,112 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+CFLAGS= -O2 -I../../../../include -I../../..
+CFLAGS += -DLOADER_ZFS_SUPPORT
+CPPFLAGS=
+
+all: machine x86 libi386.a
+
+clean: clobber
+clobber:
+ $(RM) machine x86 $(OBJS) libi386.a
+
+AS= $(GNU_ROOT)/bin/gas
+CC= $(GCC_ROOT)/bin/gcc
+OBJCOPY= $(GNU_ROOT)/bin/gobjcopy
+AS_FLAGS=--32
+ASFLAGS=-m32
+AS_CPPFLAGS=
+COMPILE.s = $(AS) $(AS_FLAGS)
+
+SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \
+ biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
+ comconsole.c devicename.c elf32_freebsd.c \
+ elf64_freebsd.c multiboot.c multiboot_tramp.S \
+ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
+ smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c linux.c \
+ relocater_tramp.S
+OBJS= biosacpi.o bioscd.o biosdisk.o biosmem.o biospnp.o \
+ biospci.o biossmap.o bootinfo.o bootinfo32.o bootinfo64.o \
+ comconsole.o devicename.o elf32_freebsd.o \
+ elf64_freebsd.o multiboot.o multiboot_tramp.o \
+ i386_copy.o i386_module.o nullconsole.o pxe.o pxetramp.o \
+ smbios.o time.o vidconsole.o amd64_tramp.o spinconsole.o linux.o \
+ relocater_tramp.o
+
+LIBZFS= ../../zfs
+SRCS += $(LIBZFS)/devicename_stubs.c
+OBJS += devicename_stubs.o
+
+# Enable PXE TFTP or NFS support, not both.
+CFLAGS += -DLOADER_TFTP_SUPPORT
+
+BOOT_COMCONSOLE_PORT= 0x3f8
+CFLAGS += -DCOMPORT=${BOOT_COMCONSOLE_PORT}
+
+BOOT_COMCONSOLE_SPEED= 9600
+CFLAGS += -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
+
+# Make the disk code more talkative
+# CFLAGS+= -DDISK_DEBUG
+
+# Export serial numbers, UUID, and asset tag from loader.
+CFLAGS += -DSMBIOS_SERIAL_NUMBERS
+# Use little-endian UUID format as defined in SMBIOS 2.6.
+CFLAGS += -DSMBIOS_LITTLE_ENDIAN_UUID
+# Use network-endian UUID format for backward compatibility.
+#CFLAGS += -DSMBIOS_NETWORK_ENDIAN_UUID
+
+# Include simple terminal emulation (cons25-compatible)
+CFLAGS += -DTERM_EMU
+
+# XXX: make alloca() useable
+CFLAGS += -Dalloca=__builtin_alloca
+
+CFLAGS += -I../../common -I../common \
+ -I../btx/lib \
+ -I../../../contrib/dev/acpica/include \
+ -I../../.. -I.
+# the location of libstand
+CFLAGS += -I../../../../lib/libstand/
+
+# Handle FreeBSD specific %b and %D printf format specifiers
+#FORMAT_EXTENSIONS=-D__printf__=__freebsd_kprintf__
+#CFLAGS += ${FORMAT_EXTENSIONS}
+
+CLEANFILES += machine x86
+
+# XXX: clang integrated-as doesn't grok .codeNN directives yet
+# CFLAGS.amd64_tramp.S= ${CLANG_NO_IAS}
+# CFLAGS.multiboot_tramp.S= ${CLANG_NO_IAS}
+# CFLAGS += ${CFLAGS.${.IMPSRC:T}}
+
+include ../Makefile.inc
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../i386/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+libi386.a: machine $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+%.o: $(LIBZFS)/%.c
+ $(COMPILE.c) -o $@ $<
diff --git a/usr/src/boot/sys/boot/i386/libi386/amd64_tramp.S b/usr/src/boot/sys/boot/i386/libi386/amd64_tramp.S
new file mode 100644
index 0000000000..fe0cf83c9d
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/amd64_tramp.S
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Quick and dirty trampoline to get into 64 bit (long) mode and running
+ * with paging enabled so that we enter the kernel at its linked address.
+ */
+#define MSR_EFER 0xc0000080
+#define EFER_LME 0x00000100
+#define CR4_PAE 0x00000020
+#define CR4_PSE 0x00000010
+#define CR0_PG 0x80000000
+
+/* GRRR. Deal with BTX that links us for a non-zero location */
+#define VPBASE 0xa000
+#define VTOP(x) ((x) + VPBASE)
+
+ .data
+
+ .p2align 12,0x40
+
+ .globl PT4
+PT4:
+ .space 0x1000
+ .globl PT3
+PT3:
+ .space 0x1000
+ .globl PT2
+PT2:
+ .space 0x1000
+
+gdtdesc:
+ .word gdtend - gdt
+ .long VTOP(gdt) # low
+ .long 0 # high
+
+gdt:
+ .long 0 # null descriptor
+ .long 0
+ .long 0x00000000 # %cs
+ .long 0x00209800
+ .long 0x00000000 # %ds
+ .long 0x00008000
+gdtend:
+
+ .text
+ .code32
+
+ .globl amd64_tramp
+amd64_tramp:
+ /* Be sure that interrupts are disabled */
+ cli
+
+ /* Turn on EFER.LME */
+ movl $MSR_EFER, %ecx
+ rdmsr
+ orl $EFER_LME, %eax
+ wrmsr
+
+ /* Turn on PAE */
+ movl %cr4, %eax
+ orl $CR4_PAE, %eax
+ movl %eax, %cr4
+
+ /* Set %cr3 for PT4 */
+ movl $VTOP(PT4), %eax
+ movl %eax, %cr3
+
+ /* Turn on paging (implicitly sets EFER.LMA) */
+ movl %cr0, %eax
+ orl $CR0_PG, %eax
+ movl %eax, %cr0
+
+ /* Now we're in compatability mode. set %cs for long mode */
+ movl $VTOP(gdtdesc), %eax
+ movl VTOP(entry_hi), %esi
+ movl VTOP(entry_lo), %edi
+ lgdt (%eax)
+ ljmp $0x8, $VTOP(longmode)
+
+ .code64
+longmode:
+ /* We're still running V=P, jump to entry point */
+ movl %esi, %eax
+ salq $32, %rax
+ orq %rdi, %rax
+ pushq %rax
+ ret
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosacpi.c b/usr/src/boot/sys/boot/i386/libi386/biosacpi.c
new file mode 100644
index 0000000000..18f8050783
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biosacpi.c
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 2001 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <machine/stdarg.h>
+#include <bootstrap.h>
+#include <btxv86.h>
+#include "libi386.h"
+
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+/*
+ * Detect ACPI and export information about the ACPI BIOS into the
+ * environment.
+ */
+
+static ACPI_TABLE_RSDP *biosacpi_find_rsdp(void);
+static ACPI_TABLE_RSDP *biosacpi_search_rsdp(char *base, int length);
+
+#define RSDP_CHECKSUM_LENGTH 20
+
+void
+biosacpi_detect(void)
+{
+ ACPI_TABLE_RSDP *rsdp;
+ char buf[24];
+ int revision;
+
+ /* locate and validate the RSDP */
+ if ((rsdp = biosacpi_find_rsdp()) == NULL)
+ return;
+
+ /* export values from the RSDP */
+ sprintf(buf, "0x%08x", (unsigned int)VTOP(rsdp));
+ setenv("acpi.rsdp", buf, 1);
+ revision = rsdp->Revision;
+ if (revision == 0)
+ revision = 1;
+ sprintf(buf, "%d", revision);
+ setenv("acpi.revision", buf, 1);
+ strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+ buf[sizeof(rsdp->OemId)] = '\0';
+ setenv("acpi.oem", buf, 1);
+ sprintf(buf, "0x%08x", rsdp->RsdtPhysicalAddress);
+ setenv("acpi.rsdt", buf, 1);
+ if (revision >= 2) {
+ /* XXX extended checksum? */
+ sprintf(buf, "0x%016llx",
+ (unsigned long long)rsdp->XsdtPhysicalAddress);
+ setenv("acpi.xsdt", buf, 1);
+ sprintf(buf, "%d", rsdp->Length);
+ setenv("acpi.xsdt_length", buf, 1);
+ }
+}
+
+/*
+ * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
+ */
+static ACPI_TABLE_RSDP *
+biosacpi_find_rsdp(void)
+{
+ ACPI_TABLE_RSDP *rsdp;
+ uint16_t *addr;
+
+ /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
+ addr = (uint16_t *)PTOV(0x40E);
+ rsdp = biosacpi_search_rsdp((char *)(intptr_t)(*addr << 4), 0x400);
+ if (rsdp != NULL)
+ return (rsdp);
+
+ /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
+ if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000)) != NULL)
+ return (rsdp);
+
+ return (NULL);
+}
+
+static ACPI_TABLE_RSDP *
+biosacpi_search_rsdp(char *base, int length)
+{
+ ACPI_TABLE_RSDP *rsdp;
+ u_int8_t *cp, sum;
+ int ofs, idx;
+
+ /* search on 16-byte boundaries */
+ for (ofs = 0; ofs < length; ofs += 16) {
+ rsdp = (ACPI_TABLE_RSDP *)PTOV(base + ofs);
+
+ /* compare signature, validate checksum */
+ if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) {
+ cp = (u_int8_t *)rsdp;
+ sum = 0;
+ for (idx = 0; idx < RSDP_CHECKSUM_LENGTH; idx++)
+ sum += *(cp + idx);
+ if (sum != 0)
+ continue;
+ return(rsdp);
+ }
+ }
+ return(NULL);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/bioscd.c b/usr/src/boot/sys/boot/i386/libi386/bioscd.c
new file mode 100644
index 0000000000..764fdc7c2e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/bioscd.c
@@ -0,0 +1,448 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2001 John H. Baldwin <jhb@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * BIOS CD device handling for CD's that have been booted off of via no
+ * emulation booting as defined in the El Torito standard.
+ *
+ * Ideas and algorithms from:
+ *
+ * - FreeBSD libi386/biosdisk.c
+ *
+ */
+
+#include <stand.h>
+
+#include <sys/param.h>
+#include <machine/bootinfo.h>
+
+#include <stdarg.h>
+
+#include <bootstrap.h>
+#include <btxv86.h>
+#include <edd.h>
+#include "libi386.h"
+
+#define BIOSCD_SECSIZE 2048
+#define BUFSIZE (1 * BIOSCD_SECSIZE)
+#define MAXBCDEV 1
+
+/* Major numbers for devices we frontend for. */
+#define ACDMAJOR 117
+#define CDMAJOR 15
+
+#ifdef DISK_DEBUG
+# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+# define DEBUG(fmt, args...)
+#endif
+
+struct specification_packet {
+ u_char sp_size;
+ u_char sp_bootmedia;
+ u_char sp_drive;
+ u_char sp_controller;
+ u_int sp_lba;
+ u_short sp_devicespec;
+ u_short sp_buffersegment;
+ u_short sp_loadsegment;
+ u_short sp_sectorcount;
+ u_short sp_cylsec;
+ u_char sp_head;
+};
+
+/*
+ * List of BIOS devices, translation from disk unit number to
+ * BIOS unit number.
+ */
+static struct bcinfo {
+ int bc_unit; /* BIOS unit number */
+ struct specification_packet bc_sp;
+ int bc_open; /* reference counter */
+ void *bc_bcache; /* buffer cache data */
+} bcinfo [MAXBCDEV];
+static int nbcinfo = 0;
+
+#define BC(dev) (bcinfo[(dev)->d_unit])
+
+static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
+static int bc_init(void);
+static int bc_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+static int bc_realstrategy(void *devdata, int flag, daddr_t dblk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+static int bc_open(struct open_file *f, ...);
+static int bc_close(struct open_file *f);
+static int bc_print(int verbose);
+
+struct devsw bioscd = {
+ "cd",
+ DEVT_CD,
+ bc_init,
+ bc_strategy,
+ bc_open,
+ bc_close,
+ noioctl,
+ bc_print,
+ NULL
+};
+
+/*
+ * Translate between BIOS device numbers and our private unit numbers.
+ */
+int
+bc_bios2unit(int biosdev)
+{
+ int i;
+
+ DEBUG("looking for bios device 0x%x", biosdev);
+ for (i = 0; i < nbcinfo; i++) {
+ DEBUG("bc unit %d is BIOS device 0x%x", i, bcinfo[i].bc_unit);
+ if (bcinfo[i].bc_unit == biosdev)
+ return(i);
+ }
+ return(-1);
+}
+
+int
+bc_unit2bios(int unit)
+{
+ if ((unit >= 0) && (unit < nbcinfo))
+ return(bcinfo[unit].bc_unit);
+ return(-1);
+}
+
+/*
+ * We can't quiz, we have to be told what device to use, so this functoin
+ * doesn't do anything. Instead, the loader calls bc_add() with the BIOS
+ * device number to add.
+ */
+static int
+bc_init(void)
+{
+
+ return (0);
+}
+
+int
+bc_add(int biosdev)
+{
+
+ if (nbcinfo >= MAXBCDEV)
+ return (-1);
+ bcinfo[nbcinfo].bc_unit = biosdev;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4b01;
+ v86.edx = biosdev;
+ v86.ds = VTOPSEG(&bcinfo[nbcinfo].bc_sp);
+ v86.esi = VTOPOFF(&bcinfo[nbcinfo].bc_sp);
+ v86int();
+ if ((v86.eax & 0xff00) != 0)
+ return (-1);
+
+ printf("BIOS CD is cd%d\n", nbcinfo);
+ nbcinfo++;
+ bcache_add_dev(nbcinfo); /* register cd device in bcache */
+ return(0);
+}
+
+/*
+ * Print information about disks
+ */
+static int
+bc_print(int verbose)
+{
+ char line[80];
+ int i, ret = 0;
+
+ for (i = 0; i < nbcinfo; i++) {
+ sprintf(line, " cd%d: Device 0x%x\n", i,
+ bcinfo[i].bc_sp.sp_devicespec);
+ ret = pager_output(line);
+ if (ret != 0)
+ return (ret);
+ }
+ return (ret);
+}
+
+/*
+ * Attempt to open the disk described by (dev) for use by (f).
+ */
+static int
+bc_open(struct open_file *f, ...)
+{
+ va_list ap;
+ struct i386_devdesc *dev;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct i386_devdesc *);
+ va_end(ap);
+ if (dev->d_unit >= nbcinfo) {
+ DEBUG("attempt to open nonexistent disk");
+ return(ENXIO);
+ }
+
+ BC(dev).bc_open++;
+ if (BC(dev).bc_bcache == NULL)
+ BC(dev).bc_bcache = bcache_allocate();
+ return(0);
+}
+
+static int
+bc_close(struct open_file *f)
+{
+ struct i386_devdesc *dev;
+
+ dev = (struct i386_devdesc *)f->f_devdata;
+ BC(dev).bc_open--;
+ if (BC(dev).bc_open == 0) {
+ bcache_free(BC(dev).bc_bcache);
+ BC(dev).bc_bcache = NULL;
+ }
+ return(0);
+}
+
+static int
+bc_strategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct bcache_devdata bcd;
+ struct i386_devdesc *dev;
+
+ dev = (struct i386_devdesc *)devdata;
+ bcd.dv_strategy = bc_realstrategy;
+ bcd.dv_devdata = devdata;
+ bcd.dv_cache = BC(dev).bc_bcache;
+
+ return (bcache_strategy(&bcd, rw, dblk, offset, size, buf, rsize));
+}
+
+static int
+bc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct i386_devdesc *dev;
+ int unit;
+ int blks;
+#ifdef BD_SUPPORT_FRAGS
+ char fragbuf[BIOSCD_SECSIZE];
+ size_t fragsize;
+
+ fragsize = size % BIOSCD_SECSIZE;
+#else
+ if (size % BIOSCD_SECSIZE)
+ return (EINVAL);
+#endif
+
+ if (rw != F_READ)
+ return(EROFS);
+ dev = (struct i386_devdesc *)devdata;
+ unit = dev->d_unit;
+ blks = size / BIOSCD_SECSIZE;
+ if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0)
+ return (EINVAL);
+ dblk /= (BIOSCD_SECSIZE / DEV_BSIZE);
+ DEBUG("read %d from %lld to %p", blks, dblk, buf);
+
+ if (rsize)
+ *rsize = 0;
+ if ((blks = bc_read(unit, dblk, blks, buf)) < 0) {
+ DEBUG("read error");
+ return (EIO);
+ } else {
+ if (size / BIOSCD_SECSIZE > blks) {
+ if (rsize)
+ *rsize = blks * BIOSCD_SECSIZE;
+ return (0);
+ }
+ }
+#ifdef BD_SUPPORT_FRAGS
+ DEBUG("frag read %d from %lld+%d to %p",
+ fragsize, dblk, blks, buf + (blks * BIOSCD_SECSIZE));
+ if (fragsize && bc_read(unit, dblk + blks, 1, fragbuf) != 1) {
+ if (blks) {
+ if (rsize)
+ *rsize = blks * BIOSCD_SECSIZE;
+ return (0);
+ }
+ DEBUG("frag read error");
+ return(EIO);
+ }
+ bcopy(fragbuf, buf + (blks * BIOSCD_SECSIZE), fragsize);
+#endif
+ if (rsize)
+ *rsize = size;
+ return (0);
+}
+
+/* Max number of sectors to bounce-buffer at a time. */
+#define CD_BOUNCEBUF 8
+
+/* return negative value for an error, otherwise blocks read */
+static int
+bc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
+{
+ u_int maxfer, resid, result, retry, x;
+ caddr_t bbuf, p, xp;
+ static struct edd_packet packet;
+ int biosdev;
+#ifdef DISK_DEBUG
+ int error;
+#endif
+
+ /* Just in case some idiot actually tries to read -1 blocks... */
+ if (blks < 0)
+ return (-1);
+
+ /* If nothing to do, just return succcess. */
+ if (blks == 0)
+ return (0);
+
+ /* Decide whether we have to bounce */
+ if (VTOP(dest) >> 20 != 0) {
+ /*
+ * The destination buffer is above first 1MB of
+ * physical memory so we have to arrange a suitable
+ * bounce buffer.
+ */
+ x = min(CD_BOUNCEBUF, (unsigned)blks);
+ bbuf = alloca(x * BIOSCD_SECSIZE);
+ maxfer = x;
+ } else {
+ bbuf = NULL;
+ maxfer = 0;
+ }
+
+ biosdev = bc_unit2bios(unit);
+ resid = blks;
+ p = dest;
+
+ while (resid > 0) {
+ if (bbuf)
+ xp = bbuf;
+ else
+ xp = p;
+ x = resid;
+ if (maxfer > 0)
+ x = min(x, maxfer);
+
+ /*
+ * Loop retrying the operation a couple of times. The BIOS
+ * may also retry.
+ */
+ for (retry = 0; retry < 3; retry++) {
+ /* If retrying, reset the drive */
+ if (retry > 0) {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0;
+ v86.edx = biosdev;
+ v86int();
+ }
+
+ packet.len = sizeof(struct edd_packet);
+ packet.count = x;
+ packet.off = VTOPOFF(xp);
+ packet.seg = VTOPSEG(xp);
+ packet.lba = dblk;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4200;
+ v86.edx = biosdev;
+ v86.ds = VTOPSEG(&packet);
+ v86.esi = VTOPOFF(&packet);
+ v86int();
+ result = V86_CY(v86.efl);
+ if (result == 0)
+ break;
+ /* fall back to 1 sector read */
+ x = 1;
+ }
+
+#ifdef DISK_DEBUG
+ error = (v86.eax >> 8) & 0xff;
+#endif
+ DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p,
+ VTOP(p), result ? "failed" : "ok");
+ DEBUG("unit %d status 0x%x", unit, error);
+
+ /* still an error? break off */
+ if (result != 0)
+ break;
+
+ if (bbuf != NULL)
+ bcopy(bbuf, p, x * BIOSCD_SECSIZE);
+ p += (x * BIOSCD_SECSIZE);
+ dblk += x;
+ resid -= x;
+ }
+
+/* hexdump(dest, (blks * BIOSCD_SECSIZE)); */
+
+ if (blks - resid == 0)
+ return (-1); /* read failed */
+
+ return (blks - resid);
+}
+
+/*
+ * Return a suitable dev_t value for (dev).
+ */
+int
+bc_getdev(struct i386_devdesc *dev)
+{
+ int biosdev, unit;
+ int major;
+ int rootdev;
+
+ unit = dev->d_unit;
+ biosdev = bc_unit2bios(unit);
+ DEBUG("unit %d BIOS device %d", unit, biosdev);
+ if (biosdev == -1) /* not a BIOS device */
+ return(-1);
+
+ /*
+ * XXX: Need to examine device spec here to figure out if SCSI or
+ * ATAPI. No idea on how to figure out device number. All we can
+ * really pass to the kernel is what bus and device on which bus we
+ * were booted from, which dev_t isn't well suited to since those
+ * number don't match to unit numbers very well. We may just need
+ * to engage in a hack where we pass -C to the boot args if we are
+ * the boot device.
+ */
+ major = ACDMAJOR;
+ unit = 0; /* XXX */
+
+ /* XXX: Assume partition 'a'. */
+ rootdev = MAKEBOOTDEV(major, 0, unit, 0);
+ DEBUG("dev is 0x%x\n", rootdev);
+ return(rootdev);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
new file mode 100644
index 0000000000..faa03309a8
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
@@ -0,0 +1,734 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * BIOS disk device handling.
+ *
+ * Ideas and algorithms from:
+ *
+ * - NetBSD libi386/biosdisk.c
+ * - FreeBSD biosboot/disk.c
+ *
+ */
+
+#include <sys/disk.h>
+#include <stand.h>
+#include <machine/bootinfo.h>
+#include <stdarg.h>
+
+#include <bootstrap.h>
+#include <btxv86.h>
+#include <edd.h>
+#include "disk.h"
+#include "libi386.h"
+
+CTASSERT(sizeof(struct i386_devdesc) >= sizeof(struct disk_devdesc));
+
+#define BIOS_NUMDRIVES 0x475
+#define BIOSDISK_SECSIZE 512
+#define BUFSIZE (1 * BIOSDISK_SECSIZE)
+
+#define DT_ATAPI 0x10 /* disk type for ATAPI floppies */
+#define WDMAJOR 0 /* major numbers for devices we frontend for */
+#define WFDMAJOR 1
+#define FDMAJOR 2
+#define DAMAJOR 4
+
+#ifdef DISK_DEBUG
+# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#else
+# define DEBUG(fmt, args...)
+#endif
+
+/*
+ * List of BIOS devices, translation from disk unit number to
+ * BIOS unit number.
+ */
+static struct bdinfo
+{
+ int bd_unit; /* BIOS unit number */
+ int bd_cyl; /* BIOS geometry */
+ int bd_hds;
+ int bd_sec;
+ int bd_flags;
+#define BD_MODEINT13 0x0000
+#define BD_MODEEDD1 0x0001
+#define BD_MODEEDD3 0x0002
+#define BD_MODEMASK 0x0003
+#define BD_FLOPPY 0x0004
+ int bd_type; /* BIOS 'drive type' (floppy only) */
+ uint16_t bd_sectorsize; /* Sector size */
+ uint64_t bd_sectors; /* Disk size */
+ int bd_open; /* reference counter */
+ void *bd_bcache; /* buffer cache data */
+} bdinfo [MAXBDDEV];
+static int nbdinfo = 0;
+
+#define BD(dev) (bdinfo[(dev)->d_unit])
+
+static int bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks,
+ caddr_t dest);
+static int bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks,
+ caddr_t dest);
+static int bd_int13probe(struct bdinfo *bd);
+
+static int bd_init(void);
+static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t offset,
+ size_t size, char *buf, size_t *rsize);
+static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t offset,
+ size_t size, char *buf, size_t *rsize);
+static int bd_open(struct open_file *f, ...);
+static int bd_close(struct open_file *f);
+static int bd_ioctl(struct open_file *f, u_long cmd, void *data);
+static int bd_print(int verbose);
+static void bd_cleanup(void);
+
+struct devsw biosdisk = {
+ "disk",
+ DEVT_DISK,
+ bd_init,
+ bd_strategy,
+ bd_open,
+ bd_close,
+ bd_ioctl,
+ bd_print,
+ bd_cleanup
+};
+
+/*
+ * Translate between BIOS device numbers and our private unit numbers.
+ */
+int
+bd_bios2unit(int biosdev)
+{
+ int i;
+
+ DEBUG("looking for bios device 0x%x", biosdev);
+ for (i = 0; i < nbdinfo; i++) {
+ DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit);
+ if (bdinfo[i].bd_unit == biosdev)
+ return (i);
+ }
+ return (-1);
+}
+
+int
+bd_unit2bios(int unit)
+{
+
+ if ((unit >= 0) && (unit < nbdinfo))
+ return (bdinfo[unit].bd_unit);
+ return (-1);
+}
+
+/*
+ * Quiz the BIOS for disk devices, save a little info about them.
+ */
+static int
+bd_init(void)
+{
+ int base, unit, nfd = 0;
+
+ /* sequence 0, 0x80 */
+ for (base = 0; base <= 0x80; base += 0x80) {
+ for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
+#ifndef VIRTUALBOX
+ /*
+ * Check the BIOS equipment list for number
+ * of fixed disks.
+ */
+ if(base == 0x80 &&
+ (nfd >= *(unsigned char *)PTOV(BIOS_NUMDRIVES)))
+ break;
+#endif
+ bdinfo[nbdinfo].bd_open = 0;
+ bdinfo[nbdinfo].bd_bcache = NULL;
+ bdinfo[nbdinfo].bd_unit = unit;
+ bdinfo[nbdinfo].bd_flags = unit < 0x80 ? BD_FLOPPY: 0;
+ if (!bd_int13probe(&bdinfo[nbdinfo]))
+ break;
+
+#ifndef BOOT2
+ /* XXX we need "disk aliases" to make this simpler */
+ printf("BIOS drive %c: is disk%d\n", (unit < 0x80) ?
+ ('A' + unit): ('C' + unit - 0x80), nbdinfo);
+#endif
+ nbdinfo++;
+ if (base == 0x80)
+ nfd++;
+ }
+ }
+ bcache_add_dev(nbdinfo);
+ return(0);
+}
+
+static void
+bd_cleanup(void)
+{
+
+ disk_cleanup(&biosdisk);
+}
+
+/*
+ * Try to detect a device supported by the legacy int13 BIOS
+ */
+static int
+bd_int13probe(struct bdinfo *bd)
+{
+ struct edd_params params;
+ int ret = 1; /* assume success */
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x800;
+ v86.edx = bd->bd_unit;
+ v86int();
+
+ /* Don't error out if we get bad sector number, try EDD as well */
+ if (V86_CY(v86.efl) || /* carry set */
+ (v86.edx & 0xff) <= (unsigned)(bd->bd_unit & 0x7f)) /* unit # bad */
+ return (0); /* skip device */
+
+ if ((v86.ecx & 0x3f) == 0) /* absurd sector number */
+ ret = 0; /* set error */
+
+ /* Convert max cyl # -> # of cylinders */
+ bd->bd_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1;
+ /* Convert max head # -> # of heads */
+ bd->bd_hds = ((v86.edx & 0xff00) >> 8) + 1;
+ bd->bd_sec = v86.ecx & 0x3f;
+ bd->bd_type = v86.ebx & 0xff;
+ bd->bd_flags |= BD_MODEINT13;
+
+ /* Calculate sectors count from the geometry */
+ bd->bd_sectors = bd->bd_cyl * bd->bd_hds * bd->bd_sec;
+ bd->bd_sectorsize = BIOSDISK_SECSIZE;
+ DEBUG("unit 0x%x geometry %d/%d/%d", bd->bd_unit, bd->bd_cyl,
+ bd->bd_hds, bd->bd_sec);
+
+ /* Determine if we can use EDD with this device. */
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4100;
+ v86.edx = bd->bd_unit;
+ v86.ebx = 0x55aa;
+ v86int();
+ if (V86_CY(v86.efl) || /* carry set */
+ (v86.ebx & 0xffff) != 0xaa55 || /* signature */
+ (v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0)
+ return (ret); /* return code from int13 AH=08 */
+
+ /* EDD supported */
+ bd->bd_flags |= BD_MODEEDD1;
+ if ((v86.eax & 0xff00) >= 0x3000)
+ bd->bd_flags |= BD_MODEEDD3;
+ /* Get disk params */
+ params.len = sizeof(struct edd_params);
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4800;
+ v86.edx = bd->bd_unit;
+ v86.ds = VTOPSEG(&params);
+ v86.esi = VTOPOFF(&params);
+ v86int();
+ if (!V86_CY(v86.efl)) {
+ uint64_t total;
+
+ if (params.sectors != 0)
+ bd->bd_sectors = params.sectors;
+
+ total = (uint64_t)params.cylinders *
+ params.heads * params.sectors_per_track;
+ if (bd->bd_sectors < total)
+ bd->bd_sectors = total;
+
+ bd->bd_sectorsize = params.sector_size;
+ ret = 1;
+ }
+ DEBUG("unit 0x%x flags %x, sectors %llu, sectorsize %u",
+ bd->bd_unit, bd->bd_flags, bd->bd_sectors, bd->bd_sectorsize);
+ return (ret);
+}
+
+/*
+ * Print information about disks
+ */
+static int
+bd_print(int verbose)
+{
+ static char line[80];
+ struct disk_devdesc dev;
+ int i, ret = 0;
+
+ for (i = 0; i < nbdinfo; i++) {
+ sprintf(line, " disk%d: BIOS drive %c:\n", i,
+ (bdinfo[i].bd_unit < 0x80) ? ('A' + bdinfo[i].bd_unit):
+ ('C' + bdinfo[i].bd_unit - 0x80));
+ ret = pager_output(line);
+ if (ret != 0)
+ return (ret);
+
+ dev.d_dev = &biosdisk;
+ dev.d_unit = i;
+ dev.d_slice = -1;
+ dev.d_partition = -1;
+ if (disk_open(&dev,
+ bdinfo[i].bd_sectorsize * bdinfo[i].bd_sectors,
+ bdinfo[i].bd_sectorsize,
+ (bdinfo[i].bd_flags & BD_FLOPPY) ?
+ DISK_F_NOCACHE: 0) == 0) {
+ sprintf(line, " disk%d", i);
+ ret = disk_print(&dev, line, verbose);
+ disk_close(&dev);
+ if (ret != 0)
+ return (ret);
+ }
+ }
+ return (ret);
+}
+
+/*
+ * Attempt to open the disk described by (dev) for use by (f).
+ *
+ * Note that the philosophy here is "give them exactly what
+ * they ask for". This is necessary because being too "smart"
+ * about what the user might want leads to complications.
+ * (eg. given no slice or partition value, with a disk that is
+ * sliced - are they after the first BSD slice, or the DOS
+ * slice before it?)
+ */
+static int
+bd_open(struct open_file *f, ...)
+{
+ struct disk_devdesc *dev;
+ va_list ap;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct disk_devdesc *);
+ va_end(ap);
+
+ if (dev->d_unit < 0 || dev->d_unit >= nbdinfo)
+ return (EIO);
+ BD(dev).bd_open++;
+ if (BD(dev).bd_bcache == NULL)
+ BD(dev).bd_bcache = bcache_allocate();
+ return (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
+ BD(dev).bd_sectorsize, (BD(dev).bd_flags & BD_FLOPPY) ?
+ DISK_F_NOCACHE: 0));
+}
+
+static int
+bd_close(struct open_file *f)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ BD(dev).bd_open--;
+ if (BD(dev).bd_open == 0) {
+ bcache_free(BD(dev).bd_bcache);
+ BD(dev).bd_bcache = NULL;
+ }
+ return (disk_close(dev));
+}
+
+static int
+bd_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ switch (cmd) {
+ case DIOCGSECTORSIZE:
+ *(u_int *)data = BD(dev).bd_sectorsize;
+ break;
+ case DIOCGMEDIASIZE:
+ *(off_t *)data = BD(dev).bd_sectors * BD(dev).bd_sectorsize;
+ break;
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+static int
+bd_strategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct bcache_devdata bcd;
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)devdata;
+ bcd.dv_strategy = bd_realstrategy;
+ bcd.dv_devdata = devdata;
+ bcd.dv_cache = BD(dev).bd_bcache;
+
+ return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, offset, size,
+ buf, rsize));
+}
+
+static int
+bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
+ int blks, remaining;
+#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */
+ char fragbuf[BIOSDISK_SECSIZE];
+ size_t fragsize;
+
+ fragsize = size % BIOSDISK_SECSIZE;
+#else
+ if (size % BD(dev).bd_sectorsize)
+ panic("bd_strategy: %d bytes I/O not multiple of block size", size);
+#endif
+
+ DEBUG("open_disk %p", dev);
+ blks = size / BD(dev).bd_sectorsize;
+ if (rsize)
+ *rsize = 0;
+
+ /*
+ * Perform partial read to prevent read-ahead crossing
+ * the end of disk - or any 32 bit aliases of the end.
+ * Signed arithmetic is used to handle wrap-around cases
+ * like we do for TCP sequence numbers.
+ */
+ remaining = (int)(BD(dev).bd_sectors - dblk); /* truncate */
+ if (remaining > 0 && remaining < blks) {
+ blks = remaining;
+ size = blks * BD(dev).bd_sectorsize;
+ DEBUG("short read %d", blks);
+ }
+
+ switch(rw){
+ case F_READ:
+ DEBUG("read %d from %lld to %p", blks, dblk, buf);
+
+ if (blks && bd_read(dev, dblk, blks, buf)) {
+ DEBUG("read error");
+ return (EIO);
+ }
+#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */
+ DEBUG("bd_strategy: frag read %d from %d+%d to %p",
+ fragsize, dblk, blks, buf + (blks * BIOSDISK_SECSIZE));
+ if (fragsize && bd_read(od, dblk + blks, 1, fragsize)) {
+ DEBUG("frag read error");
+ return(EIO);
+ }
+ bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize);
+#endif
+ break;
+ case F_WRITE :
+ DEBUG("write %d from %d to %p", blks, dblk, buf);
+
+ if (blks && bd_write(dev, dblk, blks, buf)) {
+ DEBUG("write error");
+ return (EIO);
+ }
+#ifdef BD_SUPPORT_FRAGS
+ if(fragsize) {
+ DEBUG("Attempted to write a frag");
+ return (EIO);
+ }
+#endif
+ break;
+ default:
+ /* DO NOTHING */
+ return (EROFS);
+ }
+
+ if (rsize)
+ *rsize = size;
+ return (0);
+}
+
+/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */
+#define FLOPPY_BOUNCEBUF 18
+
+static int
+bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
+ int dowrite)
+{
+ static struct edd_packet packet;
+
+ packet.len = sizeof(struct edd_packet);
+ packet.count = blks;
+ packet.off = VTOPOFF(dest);
+ packet.seg = VTOPSEG(dest);
+ packet.lba = dblk;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ if (dowrite)
+ /* Should we Write with verify ?? 0x4302 ? */
+ v86.eax = 0x4300;
+ else
+ v86.eax = 0x4200;
+ v86.edx = BD(dev).bd_unit;
+ v86.ds = VTOPSEG(&packet);
+ v86.esi = VTOPOFF(&packet);
+ v86int();
+ return (V86_CY(v86.efl));
+}
+
+static int
+bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
+ int dowrite)
+{
+ u_int x, bpc, cyl, hd, sec;
+
+ bpc = BD(dev).bd_sec * BD(dev).bd_hds; /* blocks per cylinder */
+ x = dblk;
+ cyl = x / bpc; /* block # / blocks per cylinder */
+ x %= bpc; /* block offset into cylinder */
+ hd = x / BD(dev).bd_sec; /* offset / blocks per track */
+ sec = x % BD(dev).bd_sec; /* offset into track */
+
+ /* correct sector number for 1-based BIOS numbering */
+ sec++;
+
+ if (cyl > 1023)
+ /* CHS doesn't support cylinders > 1023. */
+ return (1);
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ if (dowrite)
+ v86.eax = 0x300 | blks;
+ else
+ v86.eax = 0x200 | blks;
+ v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
+ v86.edx = (hd << 8) | BD(dev).bd_unit;
+ v86.es = VTOPSEG(dest);
+ v86.ebx = VTOPOFF(dest);
+ v86int();
+ return (V86_CY(v86.efl));
+}
+
+static int
+bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int dowrite)
+{
+ u_int x, sec, result, resid, retry, maxfer;
+ caddr_t p, xp, bbuf, breg;
+
+ /* Just in case some idiot actually tries to read/write -1 blocks... */
+ if (blks < 0)
+ return (-1);
+
+ resid = blks;
+ p = dest;
+
+ /* Decide whether we have to bounce */
+ if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 &&
+ (VTOP(dest) >> 16) != (VTOP(dest +
+ blks * BD(dev).bd_sectorsize) >> 16))) {
+
+ /*
+ * There is a 64k physical boundary somewhere in the
+ * destination buffer, or the destination buffer is above
+ * first 1MB of physical memory so we have to arrange a
+ * suitable bounce buffer. Allocate a buffer twice as large
+ * as we need to. Use the bottom half unless there is a break
+ * there, in which case we use the top half.
+ */
+ x = min(FLOPPY_BOUNCEBUF, (unsigned)blks);
+ bbuf = alloca(x * 2 * BD(dev).bd_sectorsize);
+ if (((u_int32_t)VTOP(bbuf) & 0xffff0000) ==
+ ((u_int32_t)VTOP(bbuf + x * BD(dev).bd_sectorsize) & 0xffff0000)) {
+ breg = bbuf;
+ } else {
+ breg = bbuf + x * BD(dev).bd_sectorsize;
+ }
+ maxfer = x; /* limit transfers to bounce region size */
+ } else {
+ breg = bbuf = NULL;
+ maxfer = 0;
+ }
+
+ while (resid > 0) {
+ /*
+ * Play it safe and don't cross track boundaries.
+ * (XXX this is probably unnecessary)
+ */
+ sec = dblk % BD(dev).bd_sec; /* offset into track */
+ x = min(BD(dev).bd_sec - sec, resid);
+ if (maxfer > 0)
+ x = min(x, maxfer); /* fit bounce buffer */
+
+ /* where do we transfer to? */
+ xp = bbuf == NULL ? p : breg;
+
+ /*
+ * Put your Data In, Put your Data out,
+ * Put your Data In, and shake it all about
+ */
+ if (dowrite && bbuf != NULL)
+ bcopy(p, breg, x * BD(dev).bd_sectorsize);
+
+ /*
+ * Loop retrying the operation a couple of times. The BIOS
+ * may also retry.
+ */
+ for (retry = 0; retry < 3; retry++) {
+ /* if retrying, reset the drive */
+ if (retry > 0) {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0;
+ v86.edx = BD(dev).bd_unit;
+ v86int();
+ }
+
+ if (BD(dev).bd_flags & BD_MODEEDD1)
+ result = bd_edd_io(dev, dblk, x, xp, dowrite);
+ else
+ result = bd_chs_io(dev, dblk, x, xp, dowrite);
+ if (result == 0)
+ break;
+ }
+
+ if (dowrite)
+ DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x,
+ p, VTOP(p), dblk, result ? "failed" : "ok");
+ else
+ DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x,
+ dblk, p, VTOP(p), result ? "failed" : "ok");
+ if (result) {
+ return(-1);
+ }
+ if (!dowrite && bbuf != NULL)
+ bcopy(breg, p, x * BD(dev).bd_sectorsize);
+ p += (x * BD(dev).bd_sectorsize);
+ dblk += x;
+ resid -= x;
+ }
+
+/* hexdump(dest, (blks * BD(dev).bd_sectorsize)); */
+ return(0);
+}
+
+static int
+bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
+{
+
+ return (bd_io(dev, dblk, blks, dest, 0));
+}
+
+static int
+bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
+{
+
+ return (bd_io(dev, dblk, blks, dest, 1));
+}
+
+/*
+ * Return the BIOS geometry of a given "fixed drive" in a format
+ * suitable for the legacy bootinfo structure. Since the kernel is
+ * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we
+ * prefer to get the information directly, rather than rely on being
+ * able to put it together from information already maintained for
+ * different purposes and for a probably different number of drives.
+ *
+ * For valid drives, the geometry is expected in the format (31..0)
+ * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are
+ * indicated by returning the geometry of a "1.2M" PC-format floppy
+ * disk. And, incidentally, what is returned is not the geometry as
+ * such but the highest valid cylinder, head, and sector numbers.
+ */
+u_int32_t
+bd_getbigeom(int bunit)
+{
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x800;
+ v86.edx = 0x80 + bunit;
+ v86int();
+ if (V86_CY(v86.efl))
+ return 0x4f010f;
+ return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) |
+ (v86.edx & 0xff00) | (v86.ecx & 0x3f);
+}
+
+/*
+ * Return a suitable dev_t value for (dev).
+ *
+ * In the case where it looks like (dev) is a SCSI disk, we allow the number of
+ * IDE disks to be specified in $num_ide_disks. There should be a Better Way.
+ */
+int
+bd_getdev(struct i386_devdesc *d)
+{
+ struct disk_devdesc *dev;
+ int biosdev;
+ int major;
+ int rootdev;
+ char *nip, *cp;
+ int i, unit;
+
+ dev = (struct disk_devdesc *)d;
+ biosdev = bd_unit2bios(dev->d_unit);
+ DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev);
+ if (biosdev == -1) /* not a BIOS device */
+ return(-1);
+ if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
+ BD(dev).bd_sectorsize,(BD(dev).bd_flags & BD_FLOPPY) ?
+ DISK_F_NOCACHE: 0) != 0) /* oops, not a viable device */
+ return (-1);
+ else
+ disk_close(dev);
+
+ if (biosdev < 0x80) {
+ /* floppy (or emulated floppy) or ATAPI device */
+ if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) {
+ /* is an ATAPI disk */
+ major = WFDMAJOR;
+ } else {
+ /* is a floppy disk */
+ major = FDMAJOR;
+ }
+ } else {
+ /* assume an IDE disk */
+ major = WDMAJOR;
+ }
+ /* default root disk unit number */
+ unit = biosdev & 0x7f;
+
+ /* XXX a better kludge to set the root disk unit number */
+ if ((nip = getenv("root_disk_unit")) != NULL) {
+ i = strtol(nip, &cp, 0);
+ /* check for parse error */
+ if ((cp != nip) && (*cp == 0))
+ unit = i;
+ }
+
+ rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition);
+ DEBUG("dev is 0x%x\n", rootdev);
+ return(rootdev);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosmem.c b/usr/src/boot/sys/boot/i386/libi386/biosmem.c
new file mode 100644
index 0000000000..38160da601
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biosmem.c
@@ -0,0 +1,244 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * Obtain memory configuration information from the BIOS
+ */
+#include <stand.h>
+#include <machine/pc/bios.h>
+#include "bootstrap.h"
+#include "smbios.h"
+#include "libi386.h"
+#include "btxv86.h"
+#include "smbios.h"
+
+vm_offset_t memtop, memtop_copyin, high_heap_base;
+uint32_t bios_basemem, bios_extmem, high_heap_size;
+
+static struct bios_smap_xattr smap;
+
+/*
+ * Used to track which method was used to set BIOS memory
+ * regions.
+ */
+static uint8_t b_bios_probed;
+#define B_BASEMEM_E820 0x1
+#define B_BASEMEM_12 0x2
+#define B_EXTMEM_E820 0x4
+#define B_EXTMEM_E801 0x8
+#define B_EXTMEM_8800 0x10
+
+/*
+ * The minimum amount of memory to reserve in bios_extmem for the heap.
+ */
+#define HEAP_MIN (64 * 1024 * 1024)
+
+/*
+ * Products in this list need quirks to detect
+ * memory correctly. You need both maker and product as
+ * reported by smbios.
+ */
+#define BQ_DISTRUST_E820_EXTMEM 0x1 /* e820 might not return useful
+ extended memory */
+struct bios_getmem_quirks {
+ const char* bios_vendor;
+ const char* maker;
+ const char* product;
+ int quirk;
+};
+
+static struct bios_getmem_quirks quirks[] = {
+ {"coreboot", "Acer", "Peppy", BQ_DISTRUST_E820_EXTMEM},
+ {NULL, NULL, NULL, 0}
+};
+
+static int
+bios_getquirks(void)
+{
+ int i;
+
+ for (i=0; quirks[i].quirk != 0; ++i)
+ if (smbios_match(quirks[i].bios_vendor, quirks[i].maker,
+ quirks[i].product))
+ return (quirks[i].quirk);
+
+ return (0);
+}
+
+void
+bios_getmem(void)
+{
+ uint64_t size;
+
+ /* Parse system memory map */
+ v86.ebx = 0;
+ do {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x15; /* int 0x15 function 0xe820*/
+ v86.eax = 0xe820;
+ v86.ecx = sizeof(struct bios_smap_xattr);
+ v86.edx = SMAP_SIG;
+ v86.es = VTOPSEG(&smap);
+ v86.edi = VTOPOFF(&smap);
+ v86int();
+ if ((V86_CY(v86.efl)) || (v86.eax != SMAP_SIG))
+ break;
+ /* look for a low-memory segment that's large enough */
+ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) &&
+ (smap.length >= (512 * 1024))) {
+ bios_basemem = smap.length;
+ b_bios_probed |= B_BASEMEM_E820;
+ }
+
+ /* look for the first segment in 'extended' memory */
+ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000) &&
+ !(bios_getquirks() & BQ_DISTRUST_E820_EXTMEM)) {
+ bios_extmem = smap.length;
+ b_bios_probed |= B_EXTMEM_E820;
+ }
+
+ /*
+ * Look for the largest segment in 'extended' memory beyond
+ * 1MB but below 4GB.
+ */
+ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) &&
+ (smap.base < 0x100000000ull)) {
+ size = smap.length;
+
+ /*
+ * If this segment crosses the 4GB boundary, truncate it.
+ */
+ if (smap.base + size > 0x100000000ull)
+ size = 0x100000000ull - smap.base;
+
+ if (size > high_heap_size) {
+ high_heap_size = size;
+ high_heap_base = smap.base;
+ }
+ }
+ } while (v86.ebx != 0);
+
+ /* Fall back to the old compatibility function for base memory */
+ if (bios_basemem == 0) {
+ v86.ctl = 0;
+ v86.addr = 0x12; /* int 0x12 */
+ v86int();
+
+ bios_basemem = (v86.eax & 0xffff) * 1024;
+ b_bios_probed |= B_BASEMEM_12;
+ }
+
+ /* Fall back through several compatibility functions for extended memory */
+ if (bios_extmem == 0) {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x15; /* int 0x15 function 0xe801*/
+ v86.eax = 0xe801;
+ v86int();
+ if (!(V86_CY(v86.efl))) {
+ /*
+ * Clear high_heap; it may end up overlapping
+ * with the segment we're determining here.
+ * Let the default "steal stuff from top of
+ * bios_extmem" code below pick up on it.
+ */
+ high_heap_size = 0;
+ high_heap_base = 0;
+
+ /*
+ * %cx is the number of 1KiB blocks between 1..16MiB.
+ * It can only be up to 0x3c00; if it's smaller then
+ * there's a PC AT memory hole so we can't treat
+ * it as contiguous.
+ */
+ bios_extmem = (v86.ecx & 0xffff) * 1024;
+ if (bios_extmem == (1024 * 0x3c00))
+ bios_extmem += (v86.edx & 0xffff) * 64 * 1024;
+
+ /* truncate bios_extmem */
+ if (bios_extmem > 0x3ff00000)
+ bios_extmem = 0x3ff00000;
+
+ b_bios_probed |= B_EXTMEM_E801;
+ }
+ }
+ if (bios_extmem == 0) {
+ v86.ctl = 0;
+ v86.addr = 0x15; /* int 0x15 function 0x88*/
+ v86.eax = 0x8800;
+ v86int();
+ bios_extmem = (v86.eax & 0xffff) * 1024;
+ b_bios_probed |= B_EXTMEM_8800;
+ }
+
+ /* Set memtop to actual top of memory */
+ memtop = memtop_copyin = 0x100000 + bios_extmem;
+
+ /*
+ * If we have extended memory and did not find a suitable heap
+ * region in the SMAP, use the last 3MB of 'extended' memory as a
+ * high heap candidate.
+ */
+ if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) {
+ high_heap_size = HEAP_MIN;
+ high_heap_base = memtop - HEAP_MIN;
+ }
+}
+
+#ifndef BOOT2
+static int
+command_biosmem(int argc, char *argv[])
+{
+ int bq = bios_getquirks();
+
+ printf("bios_basemem: 0x%llx\n", (unsigned long long) bios_basemem);
+ printf("bios_extmem: 0x%llx\n", (unsigned long long) bios_extmem);
+ printf("memtop: 0x%llx\n", (unsigned long long) memtop);
+ printf("high_heap_base: 0x%llx\n", (unsigned long long) high_heap_base);
+ printf("high_heap_size: 0x%llx\n", (unsigned long long) high_heap_size);
+ printf("bios_quirks: 0x%02x", bq);
+ if (bq & BQ_DISTRUST_E820_EXTMEM)
+ printf(" BQ_DISTRUST_E820_EXTMEM");
+ printf("\n");
+ printf("b_bios_probed: 0x%02x", (int) b_bios_probed);
+ if (b_bios_probed & B_BASEMEM_E820)
+ printf(" B_BASEMEM_E820");
+ if (b_bios_probed & B_BASEMEM_12)
+ printf(" B_BASEMEM_12");
+ if (b_bios_probed & B_EXTMEM_E820)
+ printf(" B_EXTMEM_E820");
+ if (b_bios_probed & B_EXTMEM_E801)
+ printf(" B_EXTMEM_E801");
+ if (b_bios_probed & B_EXTMEM_8800)
+ printf(" B_EXTMEM_8800");
+ printf("\n");
+
+ return (CMD_OK);
+}
+
+COMMAND_SET(biosmem, "biosmem", "show BIOS memory setup", command_biosmem);
+#endif
diff --git a/usr/src/boot/sys/boot/i386/libi386/biospci.c b/usr/src/boot/sys/boot/i386/libi386/biospci.c
new file mode 100644
index 0000000000..196590e1bf
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biospci.c
@@ -0,0 +1,428 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * PnP enumerator using the PCI BIOS.
+ */
+
+#include <stand.h>
+#include <machine/stdarg.h>
+#include <bootstrap.h>
+#include <isapnp.h>
+#include <btxv86.h>
+#include "libi386.h"
+
+/*
+ * Stupid PCI BIOS interface doesn't let you simply enumerate everything
+ * that's there, instead you have to ask it if it has something.
+ *
+ * So we have to scan by class code, subclass code and sometimes programming
+ * interface.
+ */
+
+struct pci_progif
+{
+ int pi_code;
+ const char *pi_name;
+};
+
+static struct pci_progif progif_null[] = {
+ {0x0, NULL},
+ {-1, NULL}
+};
+
+static struct pci_progif progif_display[] = {
+ {0x0, "VGA"},
+ {0x1, "8514"},
+ {-1, NULL}
+};
+
+static struct pci_progif progif_ide[] = {
+ {0x00, NULL},
+ {0x01, NULL},
+ {0x02, NULL},
+ {0x03, NULL},
+ {0x04, NULL},
+ {0x05, NULL},
+ {0x06, NULL},
+ {0x07, NULL},
+ {0x08, NULL},
+ {0x09, NULL},
+ {0x0a, NULL},
+ {0x0b, NULL},
+ {0x0c, NULL},
+ {0x0d, NULL},
+ {0x0e, NULL},
+ {0x0f, NULL},
+ {0x80, NULL},
+ {0x81, NULL},
+ {0x82, NULL},
+ {0x83, NULL},
+ {0x84, NULL},
+ {0x85, NULL},
+ {0x86, NULL},
+ {0x87, NULL},
+ {0x88, NULL},
+ {0x89, NULL},
+ {0x8a, NULL},
+ {0x8b, NULL},
+ {0x8c, NULL},
+ {0x8d, NULL},
+ {0x8e, NULL},
+ {0x8f, NULL},
+ {-1, NULL}
+};
+
+static struct pci_progif progif_serial[] = {
+ {0x0, "8250"},
+ {0x1, "16450"},
+ {0x2, "16550"},
+ {-1, NULL}
+};
+
+static struct pci_progif progif_parallel[] = {
+ {0x0, "Standard"},
+ {0x1, "Bidirectional"},
+ {0x2, "ECP"},
+ {-1, NULL}
+};
+
+static struct pci_progif progif_firewire[] = {
+ {0x10, "OHCI"},
+ {-1, NULL}
+};
+
+struct pci_subclass
+{
+ int ps_subclass;
+ const char *ps_name;
+ struct pci_progif *ps_progif; /* if set, use for programming interface value(s) */
+};
+
+static struct pci_subclass subclass_old[] = {
+ {0x0, "Old non-VGA", progif_null},
+ {0x1, "Old VGA", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_subclass subclass_mass[] = {
+ {0x0, "SCSI", progif_null},
+ {0x1, "IDE", progif_ide},
+ {0x2, "Floppy disk", progif_null},
+ {0x3, "IPI", progif_null},
+ {0x4, "RAID", progif_null},
+ {0x80, "mass storage", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_subclass subclass_net[] = {
+ {0x0, "Ethernet", progif_null},
+ {0x1, "Token ring", progif_null},
+ {0x2, "FDDI", progif_null},
+ {0x3, "ATM", progif_null},
+ {0x80, "network", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_subclass subclass_display[] = {
+ {0x0, NULL, progif_display},
+ {0x1, "XGA", progif_null},
+ {0x80, "other", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_subclass subclass_comms[] = {
+ {0x0, "serial", progif_serial},
+ {0x1, "parallel", progif_parallel},
+ {0x80, "communications", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_subclass subclass_serial[] = {
+ {0x0, "FireWire", progif_firewire},
+ {0x1, "ACCESS.bus", progif_null},
+ {0x2, "SSA", progif_null},
+ {0x3, "USB", progif_null},
+ {0x4, "Fibrechannel", progif_null},
+ {-1, NULL, NULL}
+};
+
+static struct pci_class
+{
+ int pc_class;
+ const char *pc_name;
+ struct pci_subclass *pc_subclass;
+} pci_classes[] = {
+ {0x0, "device", subclass_old},
+ {0x1, "controller", subclass_mass},
+ {0x2, "controller", subclass_net},
+ {0x3, "display", subclass_display},
+ {0x7, "controller", subclass_comms},
+ {0xc, "controller", subclass_serial},
+ {-1, NULL, NULL}
+};
+
+
+static void biospci_enumerate(void);
+static void biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi);
+
+struct pnphandler biospcihandler =
+{
+ "PCI BIOS",
+ biospci_enumerate
+};
+
+#define PCI_BIOS_PRESENT 0xb101
+#define FIND_PCI_DEVICE 0xb102
+#define FIND_PCI_CLASS_CODE 0xb103
+#define GENERATE_SPECIAL_CYCLE 0xb106
+#define READ_CONFIG_BYTE 0xb108
+#define READ_CONFIG_WORD 0xb109
+#define READ_CONFIG_DWORD 0xb10a
+#define WRITE_CONFIG_BYTE 0xb10b
+#define WRITE_CONFIG_WORD 0xb10c
+#define WRITE_CONFIG_DWORD 0xb10d
+#define GET_IRQ_ROUTING_OPTIONS 0xb10e
+#define SET_PCI_IRQ 0xb10f
+
+#define PCI_INT 0x1a
+
+#define PCI_SIGNATURE 0x20494350 /* AKA "PCI " */
+
+void
+biospci_detect(void)
+{
+ uint16_t version, hwcap, maxbus;
+ char buf[24];
+
+ /* Find the PCI BIOS */
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = PCI_BIOS_PRESENT;
+ v86.edi = 0x0;
+ v86int();
+
+ /* Check for OK response */
+ if (V86_CY(v86.efl) || ((v86.eax & 0xff00) != 0) ||
+ (v86.edx != PCI_SIGNATURE))
+ return;
+
+ version = v86.ebx & 0xffff;
+ hwcap = v86.eax & 0xff;
+ maxbus = v86.ecx & 0xff;
+#if 0
+ printf("PCI BIOS %d.%d%s%s maxbus %d\n",
+ bcd2bin((version >> 8) & 0xf), bcd2bin(version & 0xf),
+ (hwcap & 1) ? " config1" : "", (hwcap & 2) ? " config2" : "",
+ maxbus);
+#endif
+ sprintf(buf, "%d", bcd2bin((version >> 8) & 0xf));
+ setenv("pcibios.major", buf, 1);
+ sprintf(buf, "%d", bcd2bin(version & 0xf));
+ setenv("pcibios.minor", buf, 1);
+ sprintf(buf, "%d", !!(hwcap & 1));
+ setenv("pcibios.config1", buf, 1);
+ sprintf(buf, "%d", !!(hwcap & 2));
+ setenv("pcibios.config2", buf, 1);
+ sprintf(buf, "%d", maxbus);
+ setenv("pcibios.maxbus", buf, 1);
+
+}
+
+static void
+biospci_enumerate(void)
+{
+ int device_index, err;
+ uint32_t locator, devid;
+ struct pci_class *pc;
+ struct pci_subclass *psc;
+ struct pci_progif *ppi;
+
+ /* Iterate over known classes */
+ for (pc = pci_classes; pc->pc_class >= 0; pc++) {
+ /* Iterate over subclasses */
+ for (psc = pc->pc_subclass; psc->ps_subclass >= 0; psc++) {
+ /* Iterate over programming interfaces */
+ for (ppi = psc->ps_progif; ppi->pi_code >= 0; ppi++) {
+
+ /* Scan for matches */
+ for (device_index = 0; ; device_index++) {
+ /* Look for a match */
+ err = biospci_find_devclass((pc->pc_class << 16)
+ + (psc->ps_subclass << 8) + ppi->pi_code,
+ device_index, &locator);
+ if (err != 0)
+ break;
+
+ /* Read the device identifier from the nominated device */
+ err = biospci_read_config(locator, 0, 2, &devid);
+ if (err != 0)
+ break;
+
+ /* We have the device ID, create a PnP object and save everything */
+ biospci_addinfo(devid, pc, psc, ppi);
+ }
+ }
+ }
+ }
+}
+
+static void
+biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi)
+{
+ struct pnpinfo *pi;
+ char desc[80];
+
+
+ /* build the description */
+ desc[0] = 0;
+ if (ppi->pi_name != NULL) {
+ strcat(desc, ppi->pi_name);
+ strcat(desc, " ");
+ }
+ if (psc->ps_name != NULL) {
+ strcat(desc, psc->ps_name);
+ strcat(desc, " ");
+ }
+ if (pc->pc_name != NULL)
+ strcat(desc, pc->pc_name);
+
+ pi = pnp_allocinfo();
+ pi->pi_desc = strdup(desc);
+ sprintf(desc,"0x%08x", devid);
+ pnp_addident(pi, desc);
+ pnp_addinfo(pi);
+}
+
+int
+biospci_find_devclass(uint32_t class, int index, uint32_t *locator)
+{
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = FIND_PCI_CLASS_CODE;
+ v86.ecx = class;
+ v86.esi = index;
+ v86int();
+
+ /* error */
+ if (V86_CY(v86.efl) || (v86.eax & 0xff00))
+ return (-1);
+
+ *locator = v86.ebx;
+ return (0);
+}
+
+int
+biospci_find_device(uint32_t devid, int index, uint32_t *locator)
+{
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = FIND_PCI_DEVICE;
+ v86.edx = devid & 0xffff; /* EDX - Vendor ID */
+ v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */
+ v86.esi = index;
+ v86int();
+
+ /* error */
+ if (V86_CY(v86.efl) || (v86.eax & 0xff00))
+ return (-1);
+
+ *locator = v86.ebx;
+ return (0);
+}
+/*
+ * Configuration space access methods.
+ * width = 0(byte), 1(word) or 2(dword).
+ */
+int
+biospci_write_config(uint32_t locator, int offset, int width, uint32_t val)
+{
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = WRITE_CONFIG_BYTE + width;
+ v86.ebx = locator;
+ v86.edi = offset;
+ v86.ecx = val;
+ v86int();
+
+ /* error */
+ if (V86_CY(v86.efl) || (v86.eax & 0xff00))
+ return (-1);
+
+ return(0);
+}
+
+int
+biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val)
+{
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = READ_CONFIG_BYTE + width;
+ v86.ebx = locator;
+ v86.edi = offset;
+ v86int();
+
+ /* error */
+ if (V86_CY(v86.efl) || (v86.eax & 0xff00))
+ return (-1);
+
+ *val = v86.ecx;
+ return (0);
+}
+
+uint32_t
+biospci_locator(int8_t bus, uint8_t device, uint8_t function)
+{
+
+ return ((bus << 8) | ((device & 0x1f) << 3) | (function & 0x7));
+}
+
+/*
+ * Counts the number of instances of devid we have in the system, as least as
+ * far as the PCI BIOS is able to tell.
+ */
+int
+biospci_count_device_type(uint32_t devid)
+{
+ int i;
+
+ for (i = 0; 1; i++) {
+ v86.ctl = V86_FLAGS;
+ v86.addr = PCI_INT;
+ v86.eax = FIND_PCI_DEVICE;
+ v86.edx = devid & 0xffff; /* EDX - Vendor ID */
+ v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */
+ v86.esi = i;
+ v86int();
+ if (V86_CY(v86.efl) || (v86.eax & 0xff00))
+ break;
+
+ }
+ return i;
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/biospnp.c b/usr/src/boot/sys/boot/i386/libi386/biospnp.c
new file mode 100644
index 0000000000..30e55fc893
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biospnp.c
@@ -0,0 +1,292 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * PnP BIOS enumerator.
+ */
+
+#include <stand.h>
+#include <machine/stdarg.h>
+#include <bootstrap.h>
+#include <isapnp.h>
+#include <btxv86.h>
+
+
+static int biospnp_init(void);
+static void biospnp_enumerate(void);
+
+struct pnphandler biospnphandler =
+{
+ "PnP BIOS",
+ biospnp_enumerate
+};
+
+struct pnp_ICstructure
+{
+ u_int8_t pnp_signature[4];
+ u_int8_t pnp_version;
+ u_int8_t pnp_length;
+ u_int16_t pnp_BIOScontrol;
+ u_int8_t pnp_checksum;
+ u_int32_t pnp_eventflag;
+ u_int16_t pnp_rmip;
+ u_int16_t pnp_rmcs;
+ u_int16_t pnp_pmip;
+ u_int32_t pnp_pmcs;
+ u_int8_t pnp_OEMdev[4];
+ u_int16_t pnp_rmds;
+ u_int32_t pnp_pmds;
+} __packed;
+
+struct pnp_devNode
+{
+ u_int16_t dn_size;
+ u_int8_t dn_handle;
+ u_int8_t dn_id[4];
+ u_int8_t dn_type[3];
+ u_int16_t dn_attrib;
+ u_int8_t dn_data[1];
+} __packed;
+
+struct pnp_isaConfiguration
+{
+ u_int8_t ic_revision;
+ u_int8_t ic_nCSN;
+ u_int16_t ic_rdport;
+ u_int16_t ic_reserved;
+} __packed;
+
+static struct pnp_ICstructure *pnp_Icheck = NULL;
+static u_int16_t pnp_NumNodes;
+static u_int16_t pnp_NodeSize;
+
+static void biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn);
+static int biospnp_call(int func, const char *fmt, ...);
+
+#define vsegofs(vptr) (((u_int32_t)VTOPSEG(vptr) << 16) + VTOPOFF(vptr))
+
+typedef void v86bios_t(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
+v86bios_t *v86bios = (v86bios_t *)v86int;
+
+#define biospnp_f00(NumNodes, NodeSize) biospnp_call(0x00, "ll", NumNodes, NodeSize)
+#define biospnp_f01(Node, devNodeBuffer, Control) biospnp_call(0x01, "llw", Node, devNodeBuffer, Control)
+#define biospnp_f40(Configuration) biospnp_call(0x40, "l", Configuration)
+
+/* PnP BIOS return codes */
+#define PNP_SUCCESS 0x00
+#define PNP_FUNCTION_NOT_SUPPORTED 0x80
+
+/*
+ * Initialisation: locate the PnP BIOS, test that we can call it.
+ * Returns nonzero if the PnP BIOS is not usable on this system.
+ */
+static int
+biospnp_init(void)
+{
+ struct pnp_isaConfiguration icfg;
+ char *sigptr;
+ int result;
+
+ /* Search for the $PnP signature */
+ pnp_Icheck = NULL;
+ for (sigptr = PTOV(0xf0000); sigptr < PTOV(0xfffff); sigptr += 16)
+ if (!bcmp(sigptr, "$PnP", 4)) {
+ pnp_Icheck = (struct pnp_ICstructure *)sigptr;
+ break;
+ }
+
+ /* No signature, no BIOS */
+ if (pnp_Icheck == NULL)
+ return(1);
+
+ /*
+ * Fetch the system table parameters as a test of the BIOS
+ */
+ result = biospnp_f00(vsegofs(&pnp_NumNodes), vsegofs(&pnp_NodeSize));
+ if (result != PNP_SUCCESS) {
+ return(1);
+ }
+
+ /*
+ * Look for the PnP ISA configuration table
+ */
+ result = biospnp_f40(vsegofs(&icfg));
+ switch (result) {
+ case PNP_SUCCESS:
+ /* If the BIOS found some PnP devices, take its hint for the read port */
+ if ((icfg.ic_revision == 1) && (icfg.ic_nCSN > 0))
+ isapnp_readport = icfg.ic_rdport;
+ break;
+ case PNP_FUNCTION_NOT_SUPPORTED:
+ /* The BIOS says there is no ISA bus (should we trust that this works?) */
+ printf("PnP BIOS claims no ISA bus\n");
+ isapnp_readport = -1;
+ break;
+ }
+ return(0);
+}
+
+static void
+biospnp_enumerate(void)
+{
+ u_int8_t Node;
+ struct pnp_devNode *devNodeBuffer;
+ int result;
+ struct pnpinfo *pi;
+ int count;
+
+ /* Init/check state */
+ if (biospnp_init())
+ return;
+
+ devNodeBuffer = (struct pnp_devNode *)alloca(pnp_NodeSize);
+ Node = 0;
+ count = 1000;
+ while((Node != 0xff) && (count-- > 0)) {
+ result = biospnp_f01(vsegofs(&Node), vsegofs(devNodeBuffer), 0x1);
+ if (result != PNP_SUCCESS) {
+ printf("PnP BIOS node %d: error 0x%x\n", Node, result);
+ } else {
+ pi = pnp_allocinfo();
+ pnp_addident(pi, pnp_eisaformat(devNodeBuffer->dn_id));
+ biospnp_scanresdata(pi, devNodeBuffer);
+ pnp_addinfo(pi);
+ }
+ }
+}
+
+/*
+ * Scan the resource data in the node's data area for compatible device IDs
+ * and descriptions.
+ */
+static void
+biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn)
+{
+ u_int tag, i, rlen, dlen;
+ u_int8_t *p;
+ char *str;
+
+ p = dn->dn_data; /* point to resource data */
+ dlen = dn->dn_size - (p - (u_int8_t *)dn); /* length of resource data */
+
+ for (i = 0; i < dlen; i+= rlen) {
+ tag = p[i];
+ i++;
+ if (PNP_RES_TYPE(tag) == 0) {
+ rlen = PNP_SRES_LEN(tag);
+ /* small resource */
+ switch (PNP_SRES_NUM(tag)) {
+
+ case COMP_DEVICE_ID:
+ /* got a compatible device ID */
+ pnp_addident(pi, pnp_eisaformat(p + i));
+ break;
+
+ case END_TAG:
+ return;
+ }
+ } else {
+ /* large resource */
+ rlen = *(u_int16_t *)(p + i);
+ i += sizeof(u_int16_t);
+
+ switch(PNP_LRES_NUM(tag)) {
+
+ case ID_STRING_ANSI:
+ str = malloc(rlen + 1);
+ bcopy(p + i, str, rlen);
+ str[rlen] = 0;
+ if (pi->pi_desc == NULL) {
+ pi->pi_desc = str;
+ } else {
+ free(str);
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * Make a 16-bit realmode PnP BIOS call.
+ *
+ * The first argument passed is the function number, the last is the
+ * BIOS data segment selector. Intermediate arguments may be 16 or
+ * 32 bytes in length, and are described by the format string.
+ *
+ * Arguments to the BIOS functions must be packed on the stack, hence
+ * this evil.
+ */
+static int
+biospnp_call(int func, const char *fmt, ...)
+{
+ va_list ap;
+ const char *p;
+ u_int8_t *argp;
+ u_int32_t args[4];
+ u_int32_t i;
+
+ /* function number first */
+ argp = (u_int8_t *)args;
+ *(u_int16_t *)argp = func;
+ argp += sizeof(u_int16_t);
+
+ /* take args according to format */
+ va_start(ap, fmt);
+ for (p = fmt; *p != 0; p++) {
+ switch(*p) {
+
+ case 'w':
+ i = va_arg(ap, u_int);
+ *(u_int16_t *)argp = i;
+ argp += sizeof(u_int16_t);
+ break;
+
+ case 'l':
+ i = va_arg(ap, u_int32_t);
+ *(u_int32_t *)argp = i;
+ argp += sizeof(u_int32_t);
+ break;
+ }
+ }
+ va_end(ap);
+
+ /* BIOS segment last */
+ *(u_int16_t *)argp = pnp_Icheck->pnp_rmds;
+ argp += sizeof(u_int16_t);
+
+ /* prepare for call */
+ v86.ctl = V86_ADDR | V86_CALLF;
+ v86.addr = ((u_int32_t)pnp_Icheck->pnp_rmcs << 16) + pnp_Icheck->pnp_rmip;
+
+ /* call with packed stack and return */
+ v86bios(args[0], args[1], args[2], args[3]);
+ return(v86.eax & 0xffff);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/biossmap.c b/usr/src/boot/sys/boot/i386/libi386/biossmap.c
new file mode 100644
index 0000000000..e95ea64517
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/biossmap.c
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Obtain memory configuration information from the BIOS
+ */
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/queue.h>
+#include <sys/stddef.h>
+#include <machine/metadata.h>
+#include <machine/pc/bios.h>
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+struct smap_buf {
+ struct bios_smap smap;
+ uint32_t xattr; /* Extended attribute from ACPI 3.0 */
+ STAILQ_ENTRY(smap_buf) bufs;
+};
+
+#define SMAP_BUFSIZE offsetof(struct smap_buf, bufs)
+
+static struct bios_smap *smapbase;
+static uint32_t *smapattr;
+static u_int smaplen;
+
+void
+bios_getsmap(void)
+{
+ struct smap_buf buf;
+ STAILQ_HEAD(smap_head, smap_buf) head =
+ STAILQ_HEAD_INITIALIZER(head);
+ struct smap_buf *cur, *next;
+ u_int n, x;
+
+ STAILQ_INIT(&head);
+ n = 0;
+ x = 0;
+ v86.ebx = 0;
+ do {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x15;
+ v86.eax = 0xe820; /* int 0x15 function 0xe820 */
+ v86.ecx = SMAP_BUFSIZE;
+ v86.edx = SMAP_SIG;
+ v86.es = VTOPSEG(&buf);
+ v86.edi = VTOPOFF(&buf);
+ v86int();
+ if (V86_CY(v86.efl) || v86.eax != SMAP_SIG ||
+ v86.ecx < sizeof(buf.smap) || v86.ecx > SMAP_BUFSIZE)
+ break;
+
+ next = malloc(sizeof(*next));
+ if (next == NULL)
+ break;
+ next->smap = buf.smap;
+ if (v86.ecx == SMAP_BUFSIZE) {
+ next->xattr = buf.xattr;
+ x++;
+ }
+ STAILQ_INSERT_TAIL(&head, next, bufs);
+ n++;
+ } while (v86.ebx != 0);
+ smaplen = n;
+
+ if (smaplen > 0) {
+ smapbase = malloc(smaplen * sizeof(*smapbase));
+ if (smapbase != NULL) {
+ n = 0;
+ STAILQ_FOREACH(cur, &head, bufs)
+ smapbase[n++] = cur->smap;
+ }
+ if (smaplen == x) {
+ smapattr = malloc(smaplen * sizeof(*smapattr));
+ if (smapattr != NULL) {
+ n = 0;
+ STAILQ_FOREACH(cur, &head, bufs)
+ smapattr[n++] = cur->xattr &
+ SMAP_XATTR_MASK;
+ }
+ } else
+ smapattr = NULL;
+ cur = STAILQ_FIRST(&head);
+ while (cur != NULL) {
+ next = STAILQ_NEXT(cur, bufs);
+ free(cur);
+ cur = next;
+ }
+ }
+}
+
+void
+bios_addsmapdata(struct preloaded_file *kfp)
+{
+ size_t size;
+
+ if (smapbase == NULL || smaplen == 0)
+ return;
+ size = smaplen * sizeof(*smapbase);
+ file_addmetadata(kfp, MODINFOMD_SMAP, size, smapbase);
+ if (smapattr != NULL) {
+ size = smaplen * sizeof(*smapattr);
+ file_addmetadata(kfp, MODINFOMD_SMAP_XATTR, size, smapattr);
+ }
+}
+
+COMMAND_SET(smap, "smap", "show BIOS SMAP", command_smap);
+
+static int
+command_smap(int argc, char *argv[])
+{
+ u_int i;
+
+ if (smapbase == NULL || smaplen == 0)
+ return (CMD_ERROR);
+ if (smapattr != NULL)
+ for (i = 0; i < smaplen; i++)
+ printf("SMAP type=%02x base=%016llx len=%016llx attr=%02x\n",
+ (unsigned int)smapbase[i].type,
+ (unsigned long long)smapbase[i].base,
+ (unsigned long long)smapbase[i].length,
+ (unsigned int)smapattr[i]);
+ else
+ for (i = 0; i < smaplen; i++)
+ printf("SMAP type=%02x base=%016llx len=%016llx\n",
+ (unsigned int)smapbase[i].type,
+ (unsigned long long)smapbase[i].base,
+ (unsigned long long)smapbase[i].length);
+ return (CMD_OK);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/bootinfo.c b/usr/src/boot/sys/boot/i386/libi386/bootinfo.c
new file mode 100644
index 0000000000..a207545258
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/bootinfo.c
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+int
+bi_getboothowto(char *kargs)
+{
+ char *cp;
+ char *curpos, *next, *string;
+ int howto;
+ int active;
+ int i;
+ int vidconsole;
+
+ /* Parse kargs */
+ howto = 0;
+ if (kargs != NULL) {
+ cp = kargs;
+ active = 0;
+ while (*cp != 0) {
+ if (!active && (*cp == '-')) {
+ active = 1;
+ } else if (active)
+ switch (*cp) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'C':
+ howto |= RB_CDROM;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'g':
+ howto |= RB_GDB;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ default:
+ active = 0;
+ break;
+ }
+ cp++;
+ }
+ }
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+
+ /* Enable selected consoles */
+ string = next = strdup(getenv("console"));
+ vidconsole = 0;
+ while (next != NULL) {
+ curpos = strsep(&next, " ,");
+ if (*curpos == '\0')
+ continue;
+ if (!strcmp(curpos, "text"))
+ vidconsole = 1;
+ else if (!strcmp(curpos, "ttya"))
+ howto |= RB_SERIAL;
+ else if (!strcmp(curpos, "ttyb"))
+ howto |= RB_SERIAL;
+ else if (!strcmp(curpos, "ttyc"))
+ howto |= RB_SERIAL;
+ else if (!strcmp(curpos, "ttyd"))
+ howto |= RB_SERIAL;
+ else if (!strcmp(curpos, "null"))
+ howto |= RB_MUTE;
+ }
+
+ if (vidconsole && (howto & RB_SERIAL))
+ howto |= RB_MULTIPLE;
+
+ /*
+ * XXX: Note that until the kernel is ready to respect multiple consoles
+ * for the boot messages, the first named console is the primary console
+ */
+ if (!strcmp(string, "text"))
+ howto &= ~RB_SERIAL;
+
+ free(string);
+
+ return(howto);
+}
+
+void
+bi_setboothowto(int howto)
+{
+ int i;
+
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (howto & howto_names[i].mask)
+ setenv(howto_names[i].ev, "YES", 1);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+bi_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ i386_copyin("=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ i386_copyin("", addr, 1);
+ addr++;
+ }
+ i386_copyin("", addr, 1);
+ addr++;
+ return(addr);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/bootinfo32.c b/usr/src/boot/sys/boot/i386/libi386/bootinfo32.c
new file mode 100644
index 0000000000..d434427835
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/bootinfo32.c
@@ -0,0 +1,274 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <machine/bootinfo.h>
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+static struct bootinfo bi;
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ i386_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ i386_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_long));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ i386_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_long)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ i386_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_long));\
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules32(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ MOD_ADDR(addr, fp->f_addr, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Load the information expected by an i386 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ struct i386_devdesc *rootdev;
+ struct file_metadata *md;
+ vm_offset_t addr;
+ vm_offset_t kernend;
+ vm_offset_t envp;
+ vm_offset_t size;
+ vm_offset_t ssym, esym;
+ char *rootdevname;
+ int bootdevnr, i, howto;
+ char *kernelname;
+ const char *kernelpath;
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ i386_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(i386_fmtdev((void *)rootdev));
+
+ /* Do legacy rootdev guessing */
+
+ /* XXX - use a default bootdev of 0. Is this ok??? */
+ bootdevnr = 0;
+
+ switch(rootdev->d_type) {
+ case DEVT_CD:
+ /* Pass in BIOS device number. */
+ bi.bi_bios_dev = bc_unit2bios(rootdev->d_unit);
+ bootdevnr = bc_getdev(rootdev);
+ break;
+
+ case DEVT_DISK:
+ /* pass in the BIOS device number of the current disk */
+ bi.bi_bios_dev = bd_unit2bios(rootdev->d_unit);
+ bootdevnr = bd_getdev(rootdev);
+ break;
+
+ case DEVT_NET:
+ case DEVT_ZFS:
+ break;
+
+ default:
+ printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
+ }
+ if (bootdevnr == -1) {
+ printf("root device %s invalid\n", i386_fmtdev(rootdev));
+ return (EINVAL);
+ }
+ free(rootdev);
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* copy our environment */
+ envp = addr;
+ addr = bi_copyenv(addr);
+
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf32 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ bios_addsmapdata(kfp);
+
+ /* Figure out the size and location of the metadata */
+ *modulep = addr;
+ size = bi_copymodules32(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* copy module list and metadata */
+ (void)bi_copymodules32(addr);
+
+ ssym = esym = 0;
+ md = file_findmetadata(kfp, MODINFOMD_SSYM);
+ if (md != NULL)
+ ssym = *((vm_offset_t *)&(md->md_data));
+ md = file_findmetadata(kfp, MODINFOMD_ESYM);
+ if (md != NULL)
+ esym = *((vm_offset_t *)&(md->md_data));
+ if (ssym == 0 || esym == 0)
+ ssym = esym = 0; /* sanity */
+
+ /* legacy bootinfo structure */
+ kernelname = getenv("kernelname");
+ i386_getdev(NULL, kernelname, &kernelpath);
+ bi.bi_version = BOOTINFO_VERSION;
+ bi.bi_kernelname = 0; /* XXX char * -> kernel name */
+ bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */
+ bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */
+ for (i = 0; i < N_BIOS_GEOM; i++)
+ bi.bi_bios_geom[i] = bd_getbigeom(i);
+ bi.bi_size = sizeof(bi);
+ bi.bi_memsizes_valid = 1;
+ bi.bi_basemem = bios_basemem / 1024;
+ bi.bi_extmem = bios_extmem / 1024;
+ bi.bi_envp = envp;
+ bi.bi_modulep = *modulep;
+ bi.bi_kernend = kernend;
+ bi.bi_kernelname = VTOP(kernelpath);
+ bi.bi_symtab = ssym; /* XXX this is only the primary kernel symtab */
+ bi.bi_esymtab = esym;
+
+ /* legacy boot arguments */
+ *howtop = howto | RB_BOOTINFO;
+ *bootdevp = bootdevnr;
+ *bip = VTOP(&bi);
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/bootinfo64.c b/usr/src/boot/sys/boot/i386/libi386/bootinfo64.c
new file mode 100644
index 0000000000..e3d8970e7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/bootinfo64.c
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <machine/bootinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/metadata.h>
+#include <machine/psl.h>
+#include <machine/specialreg.h>
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ i386_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ i386_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ i386_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ i386_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t));\
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules64(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+ u_int64_t v;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ v = fp->f_addr;
+ MOD_ADDR(addr, v, c);
+ v = fp->f_size;
+ MOD_SIZE(addr, v, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Check to see if this CPU supports long mode.
+ */
+int
+bi_checkcpu(void)
+{
+ char *cpu_vendor;
+ int vendor[3];
+ int eflags;
+ unsigned int regs[4];
+
+ /* Check for presence of "cpuid". */
+ eflags = read_eflags();
+ write_eflags(eflags ^ PSL_ID);
+ if (!((eflags ^ read_eflags()) & PSL_ID))
+ return (0);
+
+ /* Fetch the vendor string. */
+ do_cpuid(0, regs);
+ vendor[0] = regs[1];
+ vendor[1] = regs[3];
+ vendor[2] = regs[2];
+ cpu_vendor = (char *)vendor;
+
+ /* Check for vendors that support AMD features. */
+ if (strncmp(cpu_vendor, INTEL_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, AMD_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, CENTAUR_VENDOR_ID, 12) != 0)
+ return (0);
+
+ /* Has to support AMD features. */
+ do_cpuid(0x80000000, regs);
+ if (!(regs[0] >= 0x80000001))
+ return (0);
+
+ /* Check for long mode. */
+ do_cpuid(0x80000001, regs);
+ return (regs[3] & AMDID_LM);
+}
+
+/*
+ * Load the information expected by an amd64 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load64(char *args, vm_offset_t addr, vm_offset_t *modulep,
+ vm_offset_t *kernendp, int add_smap)
+{
+ struct preloaded_file *xp, *kfp;
+ struct i386_devdesc *rootdev;
+ struct file_metadata *md;
+ u_int64_t kernend;
+ u_int64_t envp;
+ u_int64_t module;
+ vm_offset_t size;
+ char *rootdevname;
+ int howto;
+
+ if (!bi_checkcpu()) {
+ printf("CPU doesn't support long mode\n");
+ return (EINVAL);
+ }
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ i386_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(i386_fmtdev((void *)rootdev));
+
+ if (addr == 0) {
+ /* find the last module in the chain */
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* place the metadata before anything */
+ module = *modulep = addr;
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof module, &module);
+ if (add_smap != 0)
+ bios_addsmapdata(kfp);
+
+ size = bi_copymodules64(0);
+
+ /* copy our environment */
+ envp = roundup(addr + size, PAGE_SIZE);
+ addr = bi_copyenv(envp);
+
+ /* set kernend */
+ kernend = roundup(addr, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* patch MODINFOMD_ENVP */
+ md = file_findmetadata(kfp, MODINFOMD_ENVP);
+ bcopy(&envp, md->md_data, sizeof envp);
+
+ /* copy module list and metadata */
+ (void)bi_copymodules64(*modulep);
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/comconsole.c b/usr/src/boot/sys/boot/i386/libi386/comconsole.c
new file mode 100644
index 0000000000..a8ce7906a0
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/comconsole.c
@@ -0,0 +1,607 @@
+/*-
+ * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <machine/cpufunc.h>
+#include <dev/ic/ns16550.h>
+#include <dev/pci/pcireg.h>
+#include "libi386.h"
+
+#define COMC_TXWAIT 0x40000 /* transmit timeout */
+#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */
+#define COMC_DIV2BPS(x) (115200 / (x)) /* DLAB divisor to speed */
+
+#ifndef COMSPEED
+#define COMSPEED 9600
+#endif
+
+#define COM1_IOADDR 0x3f8
+#define COM2_IOADDR 0x2f8
+#define COM3_IOADDR 0x3e8
+#define COM4_IOADDR 0x2e8
+
+#define STOP1 0x00
+#define STOP2 0x04
+
+#define PARODD 0x00
+#define PAREN 0x08
+#define PAREVN 0x10
+#define PARMARK 0x20
+
+#define BITS5 0x00 /* 5 bits per char */
+#define BITS6 0x01 /* 6 bits per char */
+#define BITS7 0x02 /* 7 bits per char */
+#define BITS8 0x03 /* 8 bits per char */
+
+struct serial {
+ int speed; /* baud rate */
+ uint8_t lcr; /* line control */
+ uint8_t ignore_cd; /* boolean */
+ uint8_t rtsdtr_off; /* boolean */
+ int ioaddr;
+ uint32_t locator;
+};
+
+static void comc_probe(struct console *cp);
+static int comc_init(struct console *cp, int arg);
+static void comc_putchar(struct console *cp, int c);
+static int comc_getchar(struct console *cp);
+static int comc_getspeed(struct serial *sp);
+static int comc_ischar(struct console *cp);
+static uint32_t comc_parse_pcidev(const char *string);
+static int comc_pcidev_set(struct env_var *ev, int flags,
+ const void *value);
+static int comc_pcidev_handle(struct console *cp, uint32_t locator);
+static void comc_setup(struct console *cp);
+static char *comc_print_mode(struct serial *sp, char *buf);
+static int comc_parse_mode(struct serial *sp, const char *value);
+static int comc_mode_set(struct env_var *, int, const void *);
+static int comc_cd_set(struct env_var *, int, const void *);
+static int comc_rtsdtr_set(struct env_var *, int, const void *);
+
+struct console ttya = {
+ "ttya",
+ "serial port a",
+ 0,
+ comc_probe,
+ comc_init,
+ comc_putchar,
+ comc_getchar,
+ comc_ischar,
+ NULL
+};
+
+struct console ttyb = {
+ "ttyb",
+ "serial port b",
+ 0,
+ comc_probe,
+ comc_init,
+ comc_putchar,
+ comc_getchar,
+ comc_ischar,
+ NULL
+};
+
+struct console ttyc = {
+ "ttyc",
+ "serial port c",
+ 0,
+ comc_probe,
+ comc_init,
+ comc_putchar,
+ comc_getchar,
+ comc_ischar,
+ NULL
+};
+
+struct console ttyd = {
+ "ttyd",
+ "serial port d",
+ 0,
+ comc_probe,
+ comc_init,
+ comc_putchar,
+ comc_getchar,
+ comc_ischar,
+ NULL
+};
+
+static void
+comc_probe(struct console *cp)
+{
+ struct serial *port;
+ char name[20];
+ char value[20];
+ char *cons, *env;
+
+ if (cp->private == NULL) {
+ cp->private = malloc(sizeof(struct serial));
+ port = cp->private;
+ port->speed = COMSPEED;
+
+ if (strcmp(cp->c_name, "ttya") == 0)
+ port->ioaddr = COM1_IOADDR;
+ else if (strcmp(cp->c_name, "ttyb") == 0)
+ port->ioaddr = COM2_IOADDR;
+ else if (strcmp(cp->c_name, "ttyc") == 0)
+ port->ioaddr = COM3_IOADDR;
+ else if (strcmp(cp->c_name, "ttyd") == 0)
+ port->ioaddr = COM4_IOADDR;
+
+ port->lcr = BITS8; /* 8,n,1 */
+ port->ignore_cd = 1; /* ignore cd */
+ port->rtsdtr_off = 0; /* rts-dtr is on */
+
+ /*
+ * Assume that the speed was set by an earlier boot loader if
+ * comconsole is already the preferred console.
+ */
+ cons = getenv("console");
+ if ((cons != NULL && strcmp(cons, cp->c_name) == 0) ||
+ getenv("boot_multicons") != NULL) {
+ port->speed = comc_getspeed(port);
+ }
+
+ snprintf(name, 20, "%s-mode", cp->c_name);
+ env = getenv(name);
+
+ if (env != NULL) {
+ (void) comc_parse_mode(port, env);
+ }
+ env = comc_print_mode(port, value);
+
+ unsetenv(name);
+ env_setenv(name, EV_VOLATILE, env, comc_mode_set, env_nounset);
+
+ snprintf(name, 20, "%s-ignore-cd", cp->c_name);
+ env = getenv(name);
+ if (env != NULL) {
+ if (strcmp(env, "true") == 0)
+ port->ignore_cd = 1;
+ else if (strcmp(env, "false") == 0)
+ port->ignore_cd = 0;
+ }
+
+ sprintf(value, "%s", port->ignore_cd? "true":"false");
+ unsetenv(name);
+ env_setenv(name, EV_VOLATILE, value, comc_cd_set, env_nounset);
+
+ snprintf(name, 20, "%s-rts-dtr-off", cp->c_name);
+ env = getenv(name);
+ if (env != NULL) {
+ if (strcmp(env, "true") == 0)
+ port->rtsdtr_off = 1;
+ else if (strcmp(env, "false") == 0)
+ port->rtsdtr_off = 0;
+ }
+
+ sprintf(value, "%s", port->rtsdtr_off? "true":"false");
+ unsetenv(name);
+ env_setenv(name, EV_VOLATILE, value, comc_rtsdtr_set, env_nounset);
+
+ snprintf(name, 20, "%s-pcidev", cp->c_name);
+ env = getenv(name);
+ if (env != NULL) {
+ port->locator = comc_parse_pcidev(env);
+ if (port->locator != 0)
+ comc_pcidev_handle(cp, port->locator);
+ }
+
+ unsetenv(name);
+ env_setenv(name, EV_VOLATILE, env, comc_pcidev_set, env_nounset);
+ }
+ comc_setup(cp);
+}
+
+static int
+comc_init(struct console *cp, int arg __attribute((unused)))
+{
+
+ comc_setup(cp);
+
+ if ((cp->c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
+ (C_PRESENTIN | C_PRESENTOUT))
+ return (CMD_OK);
+ return (CMD_ERROR);
+}
+
+static void
+comc_putchar(struct console *cp, int c)
+{
+ int wait;
+ struct serial *sp = cp->private;
+
+ for (wait = COMC_TXWAIT; wait > 0; wait--)
+ if (inb(sp->ioaddr + com_lsr) & LSR_TXRDY) {
+ outb(sp->ioaddr + com_data, (u_char)c);
+ break;
+ }
+}
+
+static int
+comc_getchar(struct console *cp)
+{
+ struct serial *sp = cp->private;
+ return (comc_ischar(cp) ? inb(sp->ioaddr + com_data) : -1);
+}
+
+static int
+comc_ischar(struct console *cp)
+{
+ struct serial *sp = cp->private;
+ return (inb(sp->ioaddr + com_lsr) & LSR_RXRDY);
+}
+
+static char *
+comc_print_mode(struct serial *sp, char *buf)
+{
+ char par;
+
+ if ((sp->lcr & (PAREN|PAREVN)) == (PAREN|PAREVN))
+ par = 'e';
+ else if ((sp->lcr & PAREN) == PAREN)
+ par = 'o';
+ else
+ par = 'n';
+
+ sprintf(buf, "%d,%d,%c,%d,-", sp->speed,
+ (sp->lcr & BITS8) == BITS8? 8:7,
+ par, (par & STOP2) == STOP2? 2:1);
+ return (buf);
+}
+
+static int
+comc_parse_mode(struct serial *sp, const char *value)
+{
+ int n;
+ int speed;
+ int lcr;
+ char *ep;
+
+ n = strtol(value, &ep, 0);
+ if (n > 0)
+ speed = n;
+ else
+ return (CMD_ERROR);
+
+ if (*ep == ',')
+ ep++;
+ else
+ return (CMD_ERROR);
+
+ n = strtol(ep, &ep, 0);
+ switch (n) {
+ case 7: lcr = BITS7;
+ break;
+ case 8: lcr = BITS8;
+ break;
+ default:
+ return (CMD_ERROR);
+ }
+
+ if (*ep == ',')
+ ep++;
+ else
+ return (CMD_ERROR);
+
+ switch (*ep++) {
+ case 'n':
+ break;
+ case 'e': lcr |= PAREN|PAREVN;
+ break;
+ case 'o': lcr |= PAREN|PARODD;
+ break;
+ default:
+ return (CMD_ERROR);
+ }
+
+ if (*ep == ',')
+ ep++;
+ else
+ return (CMD_ERROR);
+
+ switch (*ep++) {
+ case '1':
+ break;
+ case '2': lcr |= STOP2;
+ break;
+ default:
+ return (CMD_ERROR);
+ }
+
+ /* handshake is ignored, but we check syntax anyhow */
+ if (*ep == ',')
+ ep++;
+ else
+ return (CMD_ERROR);
+
+ switch (*ep++) {
+ case '-':
+ case 'h':
+ case 's':
+ break;
+ default:
+ return (CMD_ERROR);
+ }
+
+ if (*ep != '\0')
+ return (CMD_ERROR);
+
+ sp->speed = speed;
+ sp->lcr = lcr;
+ return (CMD_OK);
+}
+
+static struct console *
+get_console(char *name)
+{
+ struct console *cp = NULL;
+
+ switch(name[3]) {
+ case 'a': cp = &ttya;
+ break;
+ case 'b': cp = &ttyb;
+ break;
+ case 'c': cp = &ttyc;
+ break;
+ case 'd': cp = &ttyd;
+ break;
+ }
+ return (cp);
+}
+
+static int
+comc_mode_set(struct env_var *ev, int flags, const void *value)
+{
+ struct console *cp;
+
+ if (value == NULL)
+ return (CMD_ERROR);
+
+ if ((cp = get_console(ev->ev_name)) == NULL)
+ return (CMD_ERROR);
+
+ if (comc_parse_mode(cp->private, value) == CMD_ERROR)
+ return (CMD_ERROR);
+
+ comc_setup(cp);
+
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+ return (CMD_OK);
+}
+
+static int
+comc_cd_set(struct env_var *ev, int flags, const void *value)
+{
+ struct console *cp;
+ struct serial *sp;
+
+ if (value == NULL)
+ return (CMD_ERROR);
+
+ if ((cp = get_console(ev->ev_name)) == NULL)
+ return (CMD_ERROR);
+
+ sp = cp->private;
+ if (strcmp(value, "true") == 0)
+ sp->ignore_cd = 1;
+ else if (strcmp(value, "false") == 0)
+ sp->ignore_cd = 0;
+ else
+ return (CMD_ERROR);
+
+ comc_setup(cp);
+
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+ return (CMD_OK);
+}
+
+static int
+comc_rtsdtr_set(struct env_var *ev, int flags, const void *value)
+{
+ struct console *cp;
+ struct serial *sp;
+
+ if (value == NULL)
+ return (CMD_ERROR);
+
+ if ((cp = get_console(ev->ev_name)) == NULL)
+ return (CMD_ERROR);
+
+ sp = cp->private;
+ if (strcmp(value, "true") == 0)
+ sp->rtsdtr_off = 1;
+ else if (strcmp(value, "false") == 0)
+ sp->rtsdtr_off = 0;
+ else
+ return (CMD_ERROR);
+
+ comc_setup(cp);
+
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+ return (CMD_OK);
+}
+
+/*
+ * Input: bus:dev:func[:bar]. If bar is not specified, it is 0x10.
+ * Output: bar[24:16] bus[15:8] dev[7:3] func[2:0]
+ */
+static uint32_t
+comc_parse_pcidev(const char *string)
+{
+#ifdef NO_PCI
+ (void)string;
+ return (0);
+#else
+ char *p, *p1;
+ uint8_t bus, dev, func, bar;
+ uint32_t locator;
+ int pres;
+
+ pres = strtol(string, &p, 0);
+ if (p == string || *p != ':' || pres < 0 )
+ return (0);
+ bus = pres;
+ p1 = ++p;
+
+ pres = strtol(p1, &p, 0);
+ if (p == string || *p != ':' || pres < 0 )
+ return (0);
+ dev = pres;
+ p1 = ++p;
+
+ pres = strtol(p1, &p, 0);
+ if (p == string || (*p != ':' && *p != '\0') || pres < 0 )
+ return (0);
+ func = pres;
+
+ if (*p == ':') {
+ p1 = ++p;
+ pres = strtol(p1, &p, 0);
+ if (p == string || *p != '\0' || pres <= 0 )
+ return (0);
+ bar = pres;
+ } else
+ bar = 0x10;
+
+ locator = (bar << 16) | biospci_locator(bus, dev, func);
+ return (locator);
+#endif
+}
+
+static int
+comc_pcidev_handle(struct console *cp, uint32_t locator)
+{
+#ifdef NO_PCI
+ (void)cp;
+ (void)locator;
+ return (CMD_ERROR);
+#else
+ struct serial *sp = cp->private;
+ char intbuf[64];
+ uint32_t port;
+
+ if (biospci_read_config(locator & 0xffff,
+ (locator & 0xff0000) >> 16, 2, &port) == -1) {
+ printf("Cannot read bar at 0x%x\n", locator);
+ return (CMD_ERROR);
+ }
+ if (!PCI_BAR_IO(port)) {
+ printf("Memory bar at 0x%x\n", locator);
+ return (CMD_ERROR);
+ }
+ port &= PCIM_BAR_IO_BASE;
+
+ comc_setup(cp);
+ sp->locator = locator;
+
+ return (CMD_OK);
+#endif
+}
+
+static int
+comc_pcidev_set(struct env_var *ev, int flags, const void *value)
+{
+ struct console *cp;
+ struct serial *sp;
+ uint32_t locator;
+ int error;
+
+ if ((cp = get_console(ev->ev_name)) == NULL)
+ return (CMD_ERROR);
+ sp = cp->private;
+
+ if (value == NULL || (locator = comc_parse_pcidev(value)) <= 0) {
+ printf("Invalid pcidev\n");
+ return (CMD_ERROR);
+ }
+ if ((cp->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
+ sp->locator != locator) {
+ error = comc_pcidev_handle(cp, locator);
+ if (error != CMD_OK)
+ return (error);
+ }
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (CMD_OK);
+}
+
+static void
+comc_setup(struct console *cp)
+{
+ struct serial *sp = cp->private;
+ static int TRY_COUNT = 1000000;
+ int tries;
+
+ if ((cp->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == 0)
+ return;
+
+ outb(sp->ioaddr + com_cfcr, CFCR_DLAB | sp->lcr);
+ outb(sp->ioaddr + com_dlbl, COMC_BPS(sp->speed) & 0xff);
+ outb(sp->ioaddr + com_dlbh, COMC_BPS(sp->speed) >> 8);
+ outb(sp->ioaddr + com_cfcr, sp->lcr);
+ outb(sp->ioaddr + com_mcr,
+ sp->rtsdtr_off? ~(MCR_RTS | MCR_DTR):MCR_RTS | MCR_DTR);
+
+ tries = 0;
+ do
+ inb(sp->ioaddr + com_data);
+ while (inb(sp->ioaddr + com_lsr) & LSR_RXRDY && ++tries < TRY_COUNT);
+
+ if (tries < TRY_COUNT) {
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+ } else
+ cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT);
+}
+
+static int
+comc_getspeed(struct serial *sp)
+{
+ u_int divisor;
+ u_char dlbh;
+ u_char dlbl;
+ u_char cfcr;
+
+ cfcr = inb(sp->ioaddr + com_cfcr);
+ outb(sp->ioaddr + com_cfcr, CFCR_DLAB | cfcr);
+
+ dlbl = inb(sp->ioaddr + com_dlbl);
+ dlbh = inb(sp->ioaddr + com_dlbh);
+
+ outb(sp->ioaddr + com_cfcr, cfcr);
+
+ divisor = dlbh << 8 | dlbl;
+
+ /* XXX there should be more sanity checking. */
+ if (divisor == 0)
+ return (COMSPEED);
+ return (COMC_DIV2BPS(divisor));
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/devicename.c b/usr/src/boot/sys/boot/i386/libi386/devicename.c
new file mode 100644
index 0000000000..c7705d7138
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/devicename.c
@@ -0,0 +1,206 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+#include "disk.h"
+#include "libi386.h"
+#include "../zfs/libzfs.h"
+
+static int i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+i386_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct i386_devdesc **dev = (struct i386_devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) ||
+ (devspec[0] == '/') ||
+ (strchr(devspec, ':') == NULL)) {
+
+ if (((rv = i386_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
+ (path != NULL))
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec
+ */
+ return(i386_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * disk<unit>[s<slice>][<partition>]:
+ *
+ */
+static int
+i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path)
+{
+ struct i386_devdesc *idev;
+ struct devsw *dv;
+ int i, unit, err;
+ char *cp;
+ const char *np;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return(EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
+ if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
+ dv = devsw[i];
+ break;
+ }
+ }
+ if (dv == NULL)
+ return(ENOENT);
+ idev = malloc(sizeof(struct i386_devdesc));
+ err = 0;
+ np = (devspec + strlen(dv->dv_name));
+
+ switch(dv->dv_type) {
+ case DEVT_NONE: /* XXX what to do here? Do we care? */
+ break;
+
+ case DEVT_DISK:
+ err = disk_parsedev((struct disk_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+
+ case DEVT_CD:
+ case DEVT_NET:
+ unit = 0;
+
+ if (*np && (*np != ':')) {
+ unit = strtol(np, &cp, 0); /* get unit number if present */
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ } else {
+ cp = (char *)np;
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_unit = unit;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+ case DEVT_ZFS:
+ err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+ default:
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (dev == NULL) {
+ free(idev);
+ } else {
+ *dev = idev;
+ }
+ return(0);
+
+ fail:
+ free(idev);
+ return(err);
+}
+
+
+char *
+i386_fmtdev(void *vdev)
+{
+ struct i386_devdesc *dev = (struct i386_devdesc *)vdev;
+ static char buf[128]; /* XXX device length constant? */
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ case DEVT_CD:
+ case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+
+ case DEVT_DISK:
+ return (disk_fmtdev(vdev));
+
+ case DEVT_ZFS:
+ return(zfs_fmtdev(vdev));
+ }
+ return(buf);
+}
+
+
+/*
+ * Set currdev to suit the value being supplied in (value)
+ */
+int
+i386_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct i386_devdesc *ncurr;
+ int rv;
+
+ if ((rv = i386_parsedev(&ncurr, value, NULL)) != 0)
+ return(rv);
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/elf32_freebsd.c b/usr/src/boot/sys/boot/i386/libi386/elf32_freebsd.c
new file mode 100644
index 0000000000..641e2733c3
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/elf32_freebsd.c
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+static int elf32_exec(struct preloaded_file *amp);
+static int elf32_obj_exec(struct preloaded_file *amp);
+
+struct file_format i386_elf = { elf32_loadfile, elf32_exec };
+struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf32_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t entry, bootinfop, modulep, kernend;
+ int boothowto, err, bootdev;
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load32(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+ entry = ehdr->e_entry & 0xffffff;
+
+#ifdef DEBUG
+ printf("Start @ 0x%lx ...\n", entry);
+#endif
+
+ dev_cleanup();
+ __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend);
+
+ panic("exec returned");
+}
+
+static int
+elf32_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/elf64_freebsd.c b/usr/src/boot/sys/boot/i386/libi386/elf64_freebsd.c
new file mode 100644
index 0000000000..338a745644
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/elf64_freebsd.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+static int elf64_exec(struct preloaded_file *amp);
+static int elf64_obj_exec(struct preloaded_file *amp);
+
+struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
+struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+
+#define PG_V 0x001
+#define PG_RW 0x002
+#define PG_U 0x004
+#define PG_PS 0x080
+
+typedef u_int64_t p4_entry_t;
+typedef u_int64_t p3_entry_t;
+typedef u_int64_t p2_entry_t;
+extern p4_entry_t PT4[];
+extern p3_entry_t PT3[];
+extern p2_entry_t PT2[];
+
+u_int32_t entry_hi;
+u_int32_t entry_lo;
+
+extern void amd64_tramp();
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf64_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t modulep, kernend;
+ int err;
+ int i;
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load64(fp->f_args, 0, &modulep, &kernend, 1);
+ if (err != 0)
+ return(err);
+
+ bzero(PT4, PAGE_SIZE);
+ bzero(PT3, PAGE_SIZE);
+ bzero(PT2, PAGE_SIZE);
+
+ /*
+ * This is kinda brutal, but every single 1GB VM memory segment points to
+ * the same first 1GB of physical memory. But it is more than adequate.
+ */
+ for (i = 0; i < 512; i++) {
+ /* Each slot of the level 4 pages points to the same level 3 page */
+ PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]);
+ PT4[i] |= PG_V | PG_RW | PG_U;
+
+ /* Each slot of the level 3 pages points to the same level 2 page */
+ PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]);
+ PT3[i] |= PG_V | PG_RW | PG_U;
+
+ /* The level 2 page slots are mapped with 2MB pages for 1GB. */
+ PT2[i] = i * (2 * 1024 * 1024);
+ PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+ }
+
+ entry_lo = ehdr->e_entry & 0xffffffff;
+ entry_hi = (ehdr->e_entry >> 32) & 0xffffffff;
+#ifdef DEBUG
+ printf("Start @ %#llx ...\n", ehdr->e_entry);
+#endif
+
+ dev_cleanup();
+ __exec((void *)VTOP(amd64_tramp), modulep, kernend);
+
+ panic("exec returned");
+}
+
+static int
+elf64_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/i386_copy.c b/usr/src/boot/sys/boot/i386/libi386/i386_copy.c
new file mode 100644
index 0000000000..3af23a0ca8
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/i386_copy.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * MD primitives supporting placement of module data
+ *
+ * XXX should check load address/size against memory top.
+ */
+#include <stand.h>
+
+#include "libi386.h"
+#include "btxv86.h"
+
+ssize_t
+i386_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ if (dest + len >= memtop) {
+ errno = EFBIG;
+ return(-1);
+ }
+
+ bcopy(src, PTOV(dest), len);
+ return(len);
+}
+
+ssize_t
+i386_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ if (src + len >= memtop) {
+ errno = EFBIG;
+ return(-1);
+ }
+
+ bcopy(PTOV(src), dest, len);
+ return(len);
+}
+
+
+ssize_t
+i386_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ if (dest + len >= memtop_copyin) {
+ errno = EFBIG;
+ return(-1);
+ }
+
+ return (read(fd, PTOV(dest), len));
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/i386_module.c b/usr/src/boot/sys/boot/i386/libi386/i386_module.c
new file mode 100644
index 0000000000..78ab61ba9a
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/i386_module.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * i386-specific module functionality.
+ *
+ */
+
+/*
+ * Use voodoo to load modules required by current hardware.
+ */
+int
+i386_autoload(void)
+{
+
+ /* XXX use PnP to locate stuff here */
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/libi386.h b/usr/src/boot/sys/boot/i386/libi386/libi386.h
new file mode 100644
index 0000000000..f03346f117
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/libi386.h
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+
+/*
+ * i386 fully-qualified device descriptor.
+ * Note, this must match the 'struct devdesc' declaration
+ * in bootstrap.h and also with struct zfs_devdesc for zfs
+ * support.
+ */
+struct i386_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ union
+ {
+ struct
+ {
+ void *data;
+ int slice;
+ int partition;
+ off_t offset;
+ } biosdisk;
+ struct
+ {
+ void *data;
+ } bioscd;
+ struct
+ {
+ void *data;
+ uint64_t pool_guid;
+ uint64_t root_guid;
+ } zfs;
+ } d_kind;
+};
+
+/*
+ * relocater trampoline support.
+ */
+struct relocate_data {
+ uint32_t src;
+ uint32_t dest;
+ uint32_t size;
+};
+
+extern void relocater(void);
+
+extern uint32_t relocater_data;
+extern uint32_t relocater_size;
+
+extern uint16_t relocator_ip;
+extern uint16_t relocator_cs;
+extern uint16_t relocator_ds;
+extern uint16_t relocator_es;
+extern uint16_t relocator_fs;
+extern uint16_t relocator_gs;
+extern uint16_t relocator_ss;
+extern uint16_t relocator_sp;
+extern uint32_t relocator_esi;
+extern uint32_t relocator_eax;
+extern uint32_t relocator_ebx;
+extern uint32_t relocator_edx;
+extern uint32_t relocator_ebp;
+extern uint16_t relocator_a20_enabled;
+
+int i386_getdev(void **vdev, const char *devspec, const char **path);
+char *i386_fmtdev(void *vdev);
+int i386_setcurrdev(struct env_var *ev, int flags, const void *value);
+
+extern struct devdesc currdev; /* our current device */
+
+#define MAXDEV 31 /* maximum number of distinct devices */
+#define MAXBDDEV MAXDEV
+
+/* exported devices XXX rename? */
+extern struct devsw bioscd;
+extern struct devsw biosdisk;
+extern struct devsw pxedisk;
+extern struct fs_ops pxe_fsops;
+
+int bc_add(int biosdev); /* Register CD booted from. */
+int bc_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
+int bc_bios2unit(int biosdev); /* xlate BIOS device -> bioscd unit */
+int bc_unit2bios(int unit); /* xlate bioscd unit -> BIOS device */
+uint32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */
+int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */
+int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */
+int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
+
+ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t i386_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t i386_readin(const int fd, vm_offset_t dest, const size_t len);
+
+struct preloaded_file;
+void bios_addsmapdata(struct preloaded_file *);
+void bios_getsmap(void);
+
+void bios_getmem(void);
+extern uint32_t bios_basemem; /* base memory in bytes */
+extern uint32_t bios_extmem; /* extended memory in bytes */
+extern vm_offset_t memtop; /* last address of physical memory + 1 */
+extern vm_offset_t memtop_copyin; /* memtop less heap size for the cases */
+ /* when heap is at the top of */
+ /* extended memory; for other cases */
+ /* just the same as memtop */
+extern uint32_t high_heap_size; /* extended memory region available */
+extern vm_offset_t high_heap_base; /* for use as the heap */
+
+void biospci_detect(void);
+int biospci_count_device_type(uint32_t devid);
+int biospci_find_devclass(uint32_t class, int index, uint32_t *locator);
+int biospci_find_device(uint32_t devid, int index, uint32_t *locator);
+int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val);
+int biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val);
+uint32_t biospci_locator(int8_t bus, uint8_t device, uint8_t function);
+
+void biosacpi_detect(void);
+
+int i386_autoload(void);
+
+int bi_getboothowto(char *kargs);
+void bi_setboothowto(int howto);
+vm_offset_t bi_copyenv(vm_offset_t addr);
+int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip,
+ vm_offset_t *modulep, vm_offset_t *kernend);
+int bi_load64(char *args, vm_offset_t addr, vm_offset_t *modulep,
+ vm_offset_t *kernend, int add_smap);
+int bi_checkcpu(void);
+
+void pxe_enable(void *pxeinfo);
diff --git a/usr/src/boot/sys/boot/i386/libi386/linux.c b/usr/src/boot/sys/boot/i386/libi386/linux.c
new file mode 100644
index 0000000000..5d0a6435d3
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/linux.c
@@ -0,0 +1,438 @@
+/*
+ * 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 2015 Toomas Soome <tsoome@me.com>
+ */
+
+/*
+ * Primitive linux loader, at the moment only intended to load memtest86+.bin.
+ *
+ * Note the linux kernel location conflicts with loader, so we need to
+ * read in to temporary space and relocate on exec, when btx is stopped.
+ */
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+#include <stand.h>
+#include <machine/metadata.h>
+#include <machine/pc/bios.h>
+
+#include "linux.h"
+#include "bootstrap.h"
+#include "libi386.h"
+#include "btxv86.h"
+
+static int linux_loadkernel(char *, u_int64_t, struct preloaded_file **);
+static int linux_loadinitrd(char *, u_int64_t, struct preloaded_file **);
+static int linux_exec(struct preloaded_file *);
+static int linux_execinitrd(struct preloaded_file *);
+
+struct file_format linux = { linux_loadkernel, linux_exec };
+struct file_format linux_initrd = { linux_loadinitrd, linux_execinitrd };
+
+uint32_t linux_text_len;
+uint32_t linux_data_tmp_addr;
+uint32_t linux_data_real_addr;
+static size_t max_cmdline_size;
+
+static void
+test_addr(uint64_t addr, uint64_t length, vm_offset_t *result)
+{
+ vm_offset_t candidate;
+
+ if (addr + length >= 0xa0000)
+ length = 0xa0000 - addr;
+
+ candidate = addr + length - (LINUX_CL_OFFSET + max_cmdline_size);
+ if (candidate > LINUX_OLD_REAL_MODE_ADDR)
+ candidate = LINUX_OLD_REAL_MODE_ADDR;
+ if (candidate < addr)
+ return;
+
+ if (candidate > *result || *result == (vm_offset_t)-1)
+ *result = candidate;
+}
+
+static vm_offset_t
+find_real_addr(struct preloaded_file *fp)
+{
+ struct bios_smap *smap;
+ struct file_metadata *md;
+ int entries, i;
+ vm_offset_t candidate = -1;
+
+ md = file_findmetadata(fp, MODINFOMD_SMAP);
+ if (md == NULL) {
+ printf("no memory smap\n");
+ return (candidate);
+ }
+ entries = md->md_size / sizeof (struct bios_smap);
+ smap = (struct bios_smap *)md->md_data;
+ for (i = 0; i < entries; i++) {
+ if (smap[i].type != SMAP_TYPE_MEMORY)
+ continue;
+ if (smap[i].base >= 0xa0000)
+ continue;
+ test_addr(smap[i].base, smap[i].length, &candidate);
+ }
+ return (candidate);
+}
+
+static int
+linux_loadkernel(char *filename, uint64_t dest, struct preloaded_file **result)
+{
+ struct linux_kernel_header lh;
+ struct preloaded_file *fp;
+ struct stat sb;
+ ssize_t n;
+ int fd, error = 0;
+ int setup_sects, linux_big;
+ unsigned long data, text;
+ vm_offset_t mem;
+ struct relocate_data *rdata;
+
+ /*
+ * relocater_data is space allocated in relocater_tramp.S
+ * There is space for 3 instances + terminating zero in case
+ * all 3 entries are used.
+ */
+ rdata = (struct relocate_data *)&relocater_data;
+
+ if (filename == NULL)
+ return (EFTYPE);
+
+ /* is kernel already loaded? */
+ fp = file_findfile(NULL, NULL);
+ if (fp != NULL)
+ return (EFTYPE);
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ return (errno);
+
+ if (fstat(fd, &sb) != 0) {
+ printf("stat failed\n");
+ error = errno;
+ close(fd);
+ return (error);
+ }
+
+ n = read(fd, &lh, sizeof (lh));
+ if (n != sizeof (lh)) {
+ printf("error reading kernel header\n");
+ error = EIO;
+ goto end;
+ }
+
+ if (lh.boot_flag != BOOTSEC_SIGNATURE) {
+ printf("invalid magic number\n");
+ error = EFTYPE;
+ goto end;
+ }
+
+ setup_sects = lh.setup_sects;
+ linux_big = 0;
+ max_cmdline_size = 256;
+
+ if (setup_sects > LINUX_MAX_SETUP_SECTS) {
+ printf("too many setup sectors\n");
+ error = EFTYPE;
+ goto end;
+ }
+
+ fp = file_alloc();
+ if (fp == NULL) {
+ error = ENOMEM;
+ goto end;
+ }
+
+ bios_addsmapdata(fp);
+
+ if (lh.header == LINUX_MAGIC_SIGNATURE && lh.version >= 0x0200) {
+ linux_big = lh.loadflags & LINUX_FLAG_BIG_KERNEL;
+ lh.type_of_loader = LINUX_BOOT_LOADER_TYPE;
+
+ if (lh.version >= 0x0206)
+ max_cmdline_size = lh.cmdline_size + 1;
+
+ linux_data_real_addr = find_real_addr(fp);
+ if (linux_data_real_addr == -1) {
+ printf("failed to detect suitable low memory\n");
+ file_discard(fp);
+ error = ENOMEM;
+ goto end;
+ }
+ if (lh.version >= 0x0201) {
+ lh.heap_end_ptr = LINUX_HEAP_END_OFFSET;
+ lh.loadflags |= LINUX_FLAG_CAN_USE_HEAP;
+ }
+ if (lh.version >= 0x0202) {
+ lh.cmd_line_ptr = linux_data_real_addr +
+ LINUX_CL_OFFSET;
+ } else {
+ lh.cl_magic = LINUX_CL_MAGIC;
+ lh.cl_offset = LINUX_CL_OFFSET;
+ lh.setup_move_size = LINUX_CL_OFFSET + max_cmdline_size;
+ }
+ } else {
+ /* old kernel */
+ lh.cl_magic = LINUX_CL_MAGIC;
+ lh.cl_offset = LINUX_CL_OFFSET;
+ setup_sects = LINUX_DEFAULT_SETUP_SECTS;
+ linux_data_real_addr = LINUX_OLD_REAL_MODE_ADDR;
+ }
+ if (setup_sects == 0)
+ setup_sects = LINUX_DEFAULT_SETUP_SECTS;
+
+ data = setup_sects << 9;
+ text = sb.st_size - data - 512;
+
+ /* temporary location of real mode part */
+ linux_data_tmp_addr = LINUX_BZIMAGE_ADDR + text;
+
+ if (!linux_big && text > linux_data_real_addr - LINUX_ZIMAGE_ADDR) {
+ printf("Linux zImage is too big, use bzImage instead\n");
+ file_discard(fp);
+ error = EFBIG;
+ goto end;
+ }
+ printf(" [Linux-%s, setup=0x%x, size=0x%x]\n",
+ (linux_big ? "bzImage" : "zImage"), data, text);
+
+ /* copy real mode part to place */
+ i386_copyin(&lh, linux_data_tmp_addr, sizeof (lh));
+ n = data + 512 - sizeof (lh);
+ if (archsw.arch_readin(fd, linux_data_tmp_addr+sizeof (lh), n) != n) {
+ printf("failed to read %s\n", filename);
+ file_discard(fp);
+ error = errno;
+ goto end;
+ }
+
+ /* Clear the heap space. */
+ if (lh.header != LINUX_MAGIC_SIGNATURE || lh.version < 0x0200) {
+ memset(PTOV(linux_data_tmp_addr + ((setup_sects + 1) << 9)),
+ 0, (LINUX_MAX_SETUP_SECTS - setup_sects - 1) << 9);
+ }
+
+ mem = LINUX_BZIMAGE_ADDR;
+
+ if (archsw.arch_readin(fd, mem, text) != text) {
+ printf("failed to read %s\n", filename);
+ file_discard(fp);
+ error = EIO;
+ goto end;
+ }
+
+ fp->f_name = strdup(filename);
+ if (linux_big)
+ fp->f_type = strdup("Linux bzImage");
+ else
+ fp->f_type = strdup("Linux zImage");
+
+ /*
+ * NOTE: f_addr and f_size is used here as hint for module
+ * allocation, as module location will be f_addr + f_size.
+ */
+ fp->f_addr = linux_data_tmp_addr;
+ fp->f_size = LINUX_SETUP_MOVE_SIZE;
+ linux_text_len = text;
+
+ if (linux_big == 0) {
+ rdata[0].src = LINUX_BZIMAGE_ADDR;
+ rdata[0].dest = LINUX_ZIMAGE_ADDR;
+ rdata[0].size = text;
+ rdata[1].src = linux_data_tmp_addr;
+ rdata[1].dest = linux_data_real_addr;
+ rdata[1].size = LINUX_SETUP_MOVE_SIZE;
+ /* make sure the next entry is zeroed */
+ rdata[2].src = 0;
+ rdata[2].dest = 0;
+ rdata[2].size = 0;
+ } else {
+ rdata[0].src = linux_data_tmp_addr;
+ rdata[0].dest = linux_data_real_addr;
+ rdata[0].size = LINUX_SETUP_MOVE_SIZE;
+ /* make sure the next entry is zeroed */
+ rdata[1].src = 0;
+ rdata[1].dest = 0;
+ rdata[1].size = 0;
+ }
+
+ *result = fp;
+ setenv("kernelname", fp->f_name, 1);
+end:
+ close(fd);
+ return (error);
+}
+
+static int
+linux_exec(struct preloaded_file *fp)
+{
+ struct linux_kernel_header *lh = (struct linux_kernel_header *)
+ PTOV(linux_data_tmp_addr);
+ struct preloaded_file *mfp = fp->f_next;
+ struct relocate_data *rdata;
+ char *arg, *vga;
+ char *src, *dst;
+ int linux_big;
+ uint32_t moveto, max_addr;
+ uint16_t segment;
+ struct i386_devdesc *rootdev;
+
+ if (strcmp(fp->f_type, "Linux bzImage") == 0)
+ linux_big = 1;
+ else if (strcmp(fp->f_type, "Linux zImage") == 0)
+ linux_big = 0;
+ else
+ return (EFTYPE);
+
+ i386_getdev((void **)(&rootdev), fp->f_name, NULL);
+ if (rootdev != NULL)
+ relocator_edx = bd_unit2bios(rootdev->d_unit);
+
+ rdata = (struct relocate_data *)&relocater_data;
+ /*
+ * command line
+ * if not set in fp, read from boot-args env
+ */
+ if (fp->f_args == NULL)
+ fp->f_args = getenv("boot-args");
+ arg = fp->f_args; /* it can still be NULL */
+
+ /* video mode selection */
+ if (arg && (vga = strstr(arg, "vga=")) != NULL) {
+ char *value = vga + 4;
+ uint16_t vid_mode;
+
+ if (strncmp(value, "normal", 6) < 1)
+ vid_mode = LINUX_VID_MODE_NORMAL;
+ else if (strncmp(value, "ext", 3) < 1)
+ vid_mode = LINUX_VID_MODE_EXTENDED;
+ else if (strncmp(value, "ask", 3) < 1)
+ vid_mode = LINUX_VID_MODE_ASK;
+ else {
+ long mode;
+ errno = 0;
+
+ /*
+ * libstand sets ERANGE as only error case;
+ * however, the actual value is 16bit, so
+ * additional check is needed.
+ */
+ mode = strtol(value, NULL, 0);
+ if (errno != 0 || mode >> 16 != 0 || mode == 0) {
+ printf("bad value for video mode\n");
+ return (EINTR);
+ }
+ vid_mode = (uint16_t) mode;
+ }
+ lh->vid_mode = vid_mode;
+ }
+
+ src = arg;
+ dst = (char *)PTOV(linux_data_tmp_addr + LINUX_CL_OFFSET);
+ if (src != NULL) {
+ while (*src != 0 && dst < (char *)
+ PTOV(linux_data_tmp_addr + LINUX_CL_END_OFFSET))
+ *(dst++) = *(src++);
+ }
+ *dst = 0;
+
+ /* set up module relocation */
+ if (mfp != NULL) {
+ moveto = (bios_extmem / 1024 + 0x400) << 10;
+ moveto = (moveto - mfp->f_size) & 0xfffff000;
+ max_addr = (lh->header == LINUX_MAGIC_SIGNATURE &&
+ lh->version >= 0x0203 ?
+ lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
+ if (moveto + mfp->f_size >= max_addr)
+ moveto = (max_addr - mfp->f_size) & 0xfffff000;
+
+ /*
+ * XXX: Linux 2.3.xx has a bug in the memory range check,
+ * so avoid the last page.
+ * XXX: Linux 2.2.xx has a bug in the memory range check,
+ * which is worse than that of Linux 2.3.xx, so avoid the
+ * last 64kb. *sigh*
+ */
+ moveto -= 0x10000;
+
+ /* need to relocate initrd first */
+ if (linux_big == 0) {
+ rdata[2].src = rdata[1].src;
+ rdata[2].dest = rdata[1].dest;
+ rdata[2].size = rdata[1].size;
+ rdata[1].src = rdata[0].src;
+ rdata[1].dest = rdata[0].dest;
+ rdata[1].size = rdata[0].size;
+ rdata[0].src = mfp->f_addr;
+ rdata[0].dest = moveto;
+ rdata[0].size = mfp->f_size;
+ } else {
+ rdata[1].src = rdata[0].src;
+ rdata[1].dest = rdata[0].dest;
+ rdata[1].size = rdata[0].size;
+ rdata[0].src = mfp->f_addr;
+ rdata[0].dest = moveto;
+ rdata[0].size = mfp->f_size;
+ }
+ lh->ramdisk_image = moveto;
+ lh->ramdisk_size = mfp->f_size;
+ }
+
+ segment = linux_data_real_addr >> 4;
+ relocator_ds = segment;
+ relocator_es = segment;
+ relocator_fs = segment;
+ relocator_gs = segment;
+ relocator_ss = segment;
+ relocator_sp = LINUX_ESP;
+ relocator_ip = 0;
+ relocator_cs = segment + 0x20;
+ relocator_a20_enabled = 1;
+ i386_copyin(relocater, 0x600, relocater_size);
+
+ dev_cleanup();
+
+ __exec((void *)0x600);
+
+ panic("exec returned");
+
+ return (EINTR); /* not reached */
+}
+
+static int
+linux_loadinitrd(char *filename, uint64_t dest, struct preloaded_file **result)
+{
+ struct preloaded_file *mfp;
+ vm_offset_t mem;
+
+ if (filename == NULL)
+ return (EFTYPE);
+
+ /* check if the kernel is loaded */
+ mfp = file_findfile(NULL, "Linux bzImage");
+ if (mfp == NULL)
+ mfp = file_findfile(NULL, "Linux zImage");
+ if (mfp == NULL)
+ return (EFTYPE);
+
+ mfp = file_loadraw(filename, "module", 0, NULL, 0);
+ if (mfp == NULL)
+ return (EFTYPE);
+ *result = mfp;
+ return (0);
+}
+
+static int linux_execinitrd(struct preloaded_file *pf)
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/linux.h b/usr/src/boot/sys/boot/i386/libi386/linux.h
new file mode 100644
index 0000000000..9ca7c3d0de
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/linux.h
@@ -0,0 +1,97 @@
+/*
+ * 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 2015 Toomas Soome <tsoome@me.com>
+ */
+
+#ifndef _LINUX_H
+#define _LINUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM_FILE
+/* For the Linux/i386 boot protocol version 2.10. */
+struct linux_kernel_header
+{
+ uint8_t code1[0x0020];
+ uint16_t cl_magic; /* Magic number 0xA33F */
+ uint16_t cl_offset; /* The offset of command line */
+ uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
+ uint8_t setup_sects; /* The size of the setup in sectors */
+ uint16_t root_flags; /* If the root is mounted readonly */
+ uint16_t syssize; /* obsolete */
+ uint16_t swap_dev; /* obsolete */
+ uint16_t ram_size; /* obsolete */
+ uint16_t vid_mode; /* Video mode control */
+ uint16_t root_dev; /* Default root device number */
+ uint16_t boot_flag; /* 0xAA55 magic number */
+ uint16_t jump; /* Jump instruction */
+ uint32_t header; /* Magic signature "HdrS" */
+ uint16_t version; /* Boot protocol version supported */
+ uint32_t realmode_swtch; /* Boot loader hook */
+ uint16_t start_sys; /* The load-low segment (obsolete) */
+ uint16_t kernel_version; /* Points to kernel version string */
+ uint8_t type_of_loader; /* Boot loader identifier */
+ uint8_t loadflags; /* Boot protocol option flags */
+ uint16_t setup_move_size; /* Move to high memory size */
+ uint32_t code32_start; /* Boot loader hook */
+ uint32_t ramdisk_image; /* initrd load address */
+ uint32_t ramdisk_size; /* initrd size */
+ uint32_t bootsect_kludge; /* obsolete */
+ uint16_t heap_end_ptr; /* Free memory after setup end */
+ uint16_t pad1; /* Unused */
+ uint32_t cmd_line_ptr; /* Points to the kernel command line */
+ uint32_t initrd_addr_max; /* Highest address for initrd */
+ uint32_t kernel_alignment;
+ uint8_t relocatable;
+ uint8_t min_alignment;
+ uint8_t pad[2];
+ uint32_t cmdline_size;
+ uint32_t hardware_subarch;
+ uint64_t hardware_subarch_data;
+ uint32_t payload_offset;
+ uint32_t payload_length;
+ uint64_t setup_data;
+ uint64_t pref_address;
+ uint32_t init_size;
+} __attribute__ ((packed));
+#endif
+
+#define LINUX_VID_MODE_NORMAL 0xFFFF
+#define LINUX_VID_MODE_EXTENDED 0xFFFE
+#define LINUX_VID_MODE_ASK 0xFFFD
+
+#define BOOTSEC_SIGNATURE 0xAA55
+#define LINUX_BOOT_LOADER_TYPE 0x72
+#define LINUX_BZIMAGE_ADDR 0x100000
+#define LINUX_CL_END_OFFSET 0x90FF
+#define LINUX_CL_MAGIC 0xA33F
+#define LINUX_CL_OFFSET 0x9000
+#define LINUX_DEFAULT_SETUP_SECTS 4
+#define LINUX_ESP 0x9000
+#define LINUX_FLAG_BIG_KERNEL 0x1
+#define LINUX_FLAG_CAN_USE_HEAP 0x80
+#define LINUX_HEAP_END_OFFSET (0x9000 - 0x200)
+#define LINUX_MAGIC_SIGNATURE 0x53726448
+#define LINUX_MAX_SETUP_SECTS 64
+#define LINUX_OLD_REAL_MODE_ADDR 0x90000
+#define LINUX_SETUP_MOVE_SIZE 0x9100
+#define LINUX_ZIMAGE_ADDR 0x10000
+#define LINUX_INITRD_MAX_ADDRESS 0x38000000
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LINUX_H */
diff --git a/usr/src/boot/sys/boot/i386/libi386/multiboot.c b/usr/src/boot/sys/boot/i386/libi386/multiboot.c
new file mode 100644
index 0000000000..37c132e088
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/multiboot.c
@@ -0,0 +1,706 @@
+/*-
+ * Copyright (c) 2014 Roger Pau Monné <royger@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+/*
+ * This multiboot implementation only implements a subset of the full
+ * multiboot specification in order to be able to boot Xen and a
+ * FreeBSD Dom0. Trying to use it to boot other multiboot compliant
+ * kernels will most surely fail.
+ *
+ * The full multiboot specification can be found here:
+ * http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <sys/stdint.h>
+#define _MACHINE_ELF_WANT_32BIT
+#include <machine/elf.h>
+#include <machine/metadata.h>
+#include <machine/pc/bios.h>
+#include <string.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "multiboot.h"
+#include "pxe.h"
+#include "../zfs/libzfs.h"
+#include "../i386/libi386/libi386.h"
+#include "../i386/btx/lib/btxv86.h"
+
+#define MULTIBOOT_SUPPORTED_FLAGS \
+ (MULTIBOOT_AOUT_KLUDGE|MULTIBOOT_PAGE_ALIGN|MULTIBOOT_MEMORY_INFO)
+#define NUM_MODULES 2
+#define METADATA_FIXED_SIZE (PAGE_SIZE*4)
+#define METADATA_MODULE_SIZE PAGE_SIZE
+
+#define METADATA_RESV_SIZE(mod_num) \
+ roundup(METADATA_FIXED_SIZE + METADATA_MODULE_SIZE * mod_num, PAGE_SIZE)
+
+/* MB data heap pointer */
+static vm_offset_t last_addr;
+
+extern int elf32_loadfile_raw(char *filename, u_int64_t dest,
+ struct preloaded_file **result, int multiboot);
+extern int elf64_load_modmetadata(struct preloaded_file *fp, u_int64_t dest);
+extern int elf64_obj_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result);
+
+static int multiboot_loadfile(char *, u_int64_t, struct preloaded_file **);
+static int multiboot_exec(struct preloaded_file *);
+
+static int multiboot_obj_loadfile(char *, u_int64_t, struct preloaded_file **);
+static int multiboot_obj_exec(struct preloaded_file *fp);
+
+struct file_format multiboot = { multiboot_loadfile, multiboot_exec };
+struct file_format multiboot_obj =
+ { multiboot_obj_loadfile, multiboot_obj_exec };
+
+extern void multiboot_tramp();
+
+static const char mbl_name[] = "illumos Loader";
+
+static int
+num_modules(struct preloaded_file *kfp)
+{
+ struct kernel_module *kmp;
+ int mod_num = 0;
+
+ for (kmp = kfp->f_modules; kmp != NULL; kmp = kmp->m_next)
+ mod_num++;
+
+ return (mod_num);
+}
+
+static vm_offset_t
+max_addr(void)
+{
+ struct preloaded_file *fp;
+ vm_offset_t addr = 0;
+
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+ if (addr < (fp->f_addr + fp->f_size))
+ addr = fp->f_addr + fp->f_size;
+ }
+
+ return (addr);
+}
+
+static int
+multiboot_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ uint32_t *magic;
+ int i, error;
+ caddr_t header_search;
+ ssize_t search_size;
+ int fd;
+ struct multiboot_header *header;
+ char *cmdline;
+ struct preloaded_file *fp;
+
+ if (filename == NULL)
+ return (EFTYPE);
+
+ /* is kernel already loaded? */
+ fp = file_findfile(NULL, NULL);
+ if (fp != NULL) {
+ return (EFTYPE);
+ }
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ return (errno);
+
+ /*
+ * Read MULTIBOOT_SEARCH size in order to search for the
+ * multiboot magic header.
+ */
+ header_search = malloc(MULTIBOOT_SEARCH);
+ if (header_search == NULL) {
+ close(fd);
+ return (ENOMEM);
+ }
+
+ search_size = read(fd, header_search, MULTIBOOT_SEARCH);
+ magic = (uint32_t *)header_search;
+
+ header = NULL;
+ for (i = 0; i < (search_size / sizeof(uint32_t)); i++) {
+ if (magic[i] == MULTIBOOT_HEADER_MAGIC) {
+ header = (struct multiboot_header *)&magic[i];
+ break;
+ }
+ }
+
+ if (header == NULL) {
+ error = EFTYPE;
+ goto out;
+ }
+
+ /* Valid multiboot header has been found, validate checksum */
+ if (header->magic + header->flags + header->checksum != 0) {
+ printf(
+ "Multiboot checksum failed, magic: 0x%x flags: 0x%x checksum: 0x%x\n",
+ header->magic, header->flags, header->checksum);
+ error = EFTYPE;
+ goto out;
+ }
+
+ if ((header->flags & ~MULTIBOOT_SUPPORTED_FLAGS) != 0) {
+ printf("Unsupported multiboot flags found: 0x%x\n",
+ header->flags);
+ error = EFTYPE;
+ goto out;
+ }
+ /* AOUT KLUDGE means we just load entire flat file as blob */
+ if (header->flags & MULTIBOOT_AOUT_KLUDGE) {
+ vm_offset_t laddr;
+ int got;
+
+ dest = header->load_addr;
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ printf("lseek failed\n");
+ error = EIO;
+ goto out;
+ }
+ laddr = dest;
+ for (;;) {
+ got = archsw.arch_readin(fd, laddr, 4096);
+ if (got == 0)
+ break;
+ if (got < 0) {
+ printf("error reading: %s", strerror(errno));
+ error = EIO;
+ goto out;
+ }
+ laddr += got;
+ }
+
+ fp = file_alloc();
+ if (fp == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ fp->f_name = strdup(filename);
+ fp->f_type = strdup("aout multiboot kernel");
+ fp->f_addr = header->entry_addr;
+ fp->f_size = laddr - dest;
+ if (fp->f_size == 0) {
+ file_discard(fp);
+ error = EIO;
+ goto out;
+ }
+ fp->f_metadata = NULL;
+
+ *result = fp;
+ error = 0;
+ } else {
+
+ error = elf32_loadfile_raw(filename, dest, result, 1);
+ if (error != 0) {
+ printf("elf32_loadfile_raw failed: %d unable to "
+ "load multiboot kernel\n", error);
+ goto out;
+ }
+ }
+
+ setenv("kernelname", (*result)->f_name, 1);
+ bios_addsmapdata(*result);
+out:
+ free(header_search);
+ close(fd);
+ return (error);
+}
+
+/*
+ * returns allocated virtual address from MB info area
+ */
+static vm_offset_t
+mb_malloc(size_t n)
+{
+ vm_offset_t ptr = last_addr;
+ if (ptr + n >= high_heap_base)
+ return (0);
+ last_addr = roundup(last_addr + n, MULTIBOOT_INFO_ALIGN);
+ return (ptr);
+}
+
+/*
+ * Since for now we have no way to pass the environment to the kernel other than
+ * through arguments, we need to take care of console setup.
+ *
+ * If the console is in mirror mode, set the kernel console from $os_console.
+ * If it's unset, use first item from $console.
+ * If $console is "ttyX", also pass $ttyX-mode, since it may have been set by
+ * the user.
+ *
+ * In case of memory allocation errors, just return original command line,
+ * so we have chance of booting.
+ *
+ * On success, cl will be freed and a new, allocated command line string is
+ * returned.
+ */
+static char *
+update_cmdline(char *cl)
+{
+ char *os_console = getenv("os_console");
+ char *ttymode = NULL;
+ char mode[10];
+ char *tmp;
+ int len;
+
+ if (os_console == NULL) {
+ tmp = strdup(getenv("console"));
+ os_console = strsep(&tmp, ", ");
+ } else
+ os_console = strdup(os_console);
+
+ if (os_console == NULL)
+ return (cl);
+
+ if (strncmp(os_console, "tty", 3) == 0) {
+ snprintf(mode, sizeof (mode), "%s-mode", os_console);
+ ttymode = getenv(mode); /* never NULL */
+ }
+
+ if (strstr(cl, "-B") != NULL) {
+ len = strlen(cl) + 1;
+ /*
+ * if console is not present, add it
+ * if console is ttyX, add ttymode
+ */
+ tmp = strstr(cl, "console");
+ if (tmp == NULL) {
+ len += 12; /* " -B console=" */
+ len += strlen(os_console);
+ if (ttymode != NULL) {
+ len += 13; /* ",ttyX-mode=\"\"" */
+ len += strlen(ttymode);
+ }
+ tmp = malloc(len);
+ if (tmp == NULL) {
+ free(os_console);
+ return (cl);
+ }
+ if (ttymode != NULL)
+ sprintf(tmp,
+ "%s -B console=%s,%s-mode=\"%s\"",
+ cl, os_console, os_console, ttymode);
+ else
+ sprintf(tmp, "%s -B console=%s",
+ cl, os_console);
+ } else {
+ /* console is set, do we need tty mode? */
+ tmp += 8;
+ if (strstr(tmp, "tty") == tmp) {
+ strncpy(mode, tmp, 4);
+ mode[4] = '\0';
+ strcat(mode, "-mode");
+ ttymode = getenv(mode); /* never NULL */
+ } else { /* nope */
+ free(os_console);
+ return (cl);
+ }
+ len = strlen(cl) + 1;
+ len += 13; /* ",ttyX-mode=\"\"" */
+ len += strlen(ttymode);
+ tmp = malloc(len);
+ if (tmp == NULL) {
+ free(os_console);
+ return (cl);
+ }
+ sprintf(tmp, "%s,%s=\"%s\"", cl, mode, ttymode);
+ }
+ } else {
+ /*
+ * no -B, so we need to add " -B console=%s[,ttyX-mode=\"%s\"]"
+ */
+ len = strlen(cl) + 1;
+ len += 12; /* " -B console=" */
+ len += strlen(os_console);
+ if (ttymode != NULL) {
+ len += 13; /* ",ttyX-mode=\"\"" */
+ len += strlen(ttymode);
+ }
+ tmp = malloc(len);
+ if (tmp == NULL) {
+ free(os_console);
+ return (cl);
+ }
+ if (ttymode != NULL)
+ sprintf(tmp, "%s -B console=%s,%s-mode=\"%s\"", cl,
+ os_console, os_console, ttymode);
+ else
+ sprintf(tmp, "%s -B console=%s", cl, os_console);
+ }
+ free(os_console);
+ free(cl);
+ return (tmp);
+}
+
+static char *
+kernel_cmdline(struct preloaded_file *fp, struct i386_devdesc *rootdev)
+{
+ char *cmdline = NULL;
+ size_t len;
+
+ if (fp->f_args == NULL)
+ fp->f_args = getenv("boot-args");
+
+ len = strlen(fp->f_name) + 1;
+
+ if (fp->f_args != NULL)
+ len += strlen(fp->f_args) + 1;
+
+ if (rootdev->d_type == DEVT_ZFS)
+ len += 3 + strlen(zfs_bootfs(rootdev)) + 1;
+
+ cmdline = malloc(len);
+ if (cmdline == NULL)
+ return (cmdline);
+
+ if (rootdev->d_type == DEVT_ZFS) {
+ if (fp->f_args != NULL)
+ snprintf(cmdline, len, "%s %s -B %s", fp->f_name,
+ fp->f_args, zfs_bootfs(rootdev));
+ else
+ snprintf(cmdline, len, "%s -B %s", fp->f_name,
+ zfs_bootfs(rootdev));
+ } else if (fp->f_args != NULL)
+ snprintf(cmdline, len, "%s %s", fp->f_name, fp->f_args);
+ else
+ snprintf(cmdline, len, "%s", fp->f_name);
+
+ return (update_cmdline(cmdline));
+}
+
+static int
+multiboot_exec(struct preloaded_file *fp)
+{
+ struct preloaded_file *mfp;
+ vm_offset_t module_start, metadata_size;
+ vm_offset_t modulep, kernend, entry;
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ struct multiboot_info *mb_info = NULL;
+ struct multiboot_mod_list *mb_mod = NULL;
+ multiboot_memory_map_t *mmap;
+ struct bios_smap *smap;
+ struct i386_devdesc *rootdev;
+ extern BOOTPLAYER bootplayer; /* dhcp info */
+ char *cmdline = NULL;
+ size_t len;
+ int error, num, i;
+ int rootfs = 0; /* flag for rootfs */
+ int xen = 0; /* flag for xen */
+ int kernel = 0; /* flag for kernel */
+
+ /* set up base for mb_malloc */
+ for (mfp = fp; mfp->f_next != NULL; mfp = mfp->f_next);
+
+ /* start info block from new page */
+ last_addr = roundup(mfp->f_addr + mfp->f_size, MULTIBOOT_MOD_ALIGN);
+
+ /* Allocate the multiboot struct and fill the basic details. */
+ mb_info = (struct multiboot_info *)PTOV(mb_malloc(sizeof (*mb_info)));
+
+ bzero(mb_info, sizeof(struct multiboot_info));
+ mb_info->flags = MULTIBOOT_INFO_MEMORY|MULTIBOOT_INFO_BOOT_LOADER_NAME;
+ mb_info->mem_lower = bios_basemem / 1024;
+ mb_info->mem_upper = bios_extmem / 1024;
+ mb_info->boot_loader_name = mb_malloc(strlen(mbl_name) + 1);
+
+ i386_copyin(mbl_name, mb_info->boot_loader_name, strlen(mbl_name)+1);
+
+ i386_getdev((void **)(&rootdev), NULL, NULL);
+ if (rootdev == NULL) {
+ printf("can't determine root device\n");
+ error = EINVAL;
+ goto error;
+ }
+
+ /*
+ * boot image command line. if args were not provided, we need to set
+ * args here, and that depends on image type...
+ * fortunately we only have following options:
+ * 64 or 32 bit unix or xen. so we just check if f_name has unix.
+ */
+ /* do we boot xen? */
+ if (strstr(fp->f_name, "unix") == NULL)
+ xen = 1;
+
+ entry = fp->f_addr;
+
+ num = 0;
+ for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) {
+ num++;
+ if (mfp->f_type != NULL && strcmp(mfp->f_type, "rootfs") == 0)
+ rootfs++;
+ if (mfp->f_type != NULL && strcmp(mfp->f_type, "kernel") == 0)
+ kernel++;
+ }
+
+ if (num == 0 || rootfs == 0) {
+ /* need at least one module - rootfs */
+ printf("No rootfs module provided, aborting\n");
+ error = EINVAL;
+ goto error;
+ }
+ if (xen == 1 && kernel == 0) {
+ printf("No kernel module provided for xen, aborting\n");
+ error = EINVAL;
+ goto error;
+ }
+ mb_mod = (struct multiboot_mod_list *) PTOV(last_addr);
+ last_addr += roundup(sizeof(*mb_mod) * num, MULTIBOOT_INFO_ALIGN);
+
+ bzero(mb_mod, sizeof(*mb_mod) * num);
+
+ num = 0;
+ for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) {
+ mb_mod[num].mod_start = mfp->f_addr;
+ mb_mod[num].mod_end = mfp->f_addr + mfp->f_size;
+
+ if (strcmp(mfp->f_type, "kernel") == 0) {
+ cmdline = kernel_cmdline(mfp, rootdev);
+ if (cmdline == NULL) {
+ error = ENOMEM;
+ goto error;
+ }
+ } else {
+ len = strlen(mfp->f_name) + 1;
+ len += strlen(mfp->f_type) + 5 + 1;
+ if (mfp->f_args != NULL) {
+ len += strlen(mfp->f_args) + 1;
+ }
+ cmdline = malloc(len);
+ if (cmdline == NULL) {
+ error = ENOMEM;
+ goto error;
+ }
+
+ if (mfp->f_args != NULL)
+ snprintf(cmdline, len, "%s type=%s %s",
+ mfp->f_name, mfp->f_type, mfp->f_args);
+ else
+ snprintf(cmdline, len, "%s type=%s",
+ mfp->f_name, mfp->f_type);
+ }
+
+ mb_mod[num].cmdline = mb_malloc(strlen(cmdline)+1);
+ i386_copyin(cmdline, mb_mod[num].cmdline, strlen(cmdline)+1);
+ free(cmdline);
+ num++;
+ }
+
+ mb_info->mods_count = num;
+ mb_info->mods_addr = VTOP(mb_mod);
+ mb_info->flags |= MULTIBOOT_INFO_MODS;
+
+ md = file_findmetadata(fp, MODINFOMD_SMAP);
+ if (md == NULL) {
+ printf("no memory smap\n");
+ error = EINVAL;
+ goto error;
+ }
+
+ num = md->md_size / sizeof(struct bios_smap); /* number of entries */
+ mmap = (multiboot_memory_map_t *)PTOV(mb_malloc(sizeof(*mmap) * num));
+
+ mb_info->mmap_length = num * sizeof(*mmap);
+ smap = (struct bios_smap *)md->md_data;
+
+ for (i = 0; i < num; i++) {
+ mmap[i].size = sizeof(*smap);
+ mmap[i].addr = smap[i].base;
+ mmap[i].len = smap[i].length;
+ mmap[i].type = smap[i].type;
+ }
+ mb_info->mmap_addr = VTOP(mmap);
+ mb_info->flags |= MULTIBOOT_INFO_MEM_MAP;
+
+ if (strstr(getenv("loaddev"), "pxe") != NULL) {
+ mb_info->drives_length = sizeof (BOOTPLAYER);
+ mb_info->drives_addr = mb_malloc(mb_info->drives_length);
+ i386_copyin(&bootplayer, mb_info->drives_addr,
+ mb_info->drives_length);
+ mb_info->flags &= ~MULTIBOOT_INFO_DRIVE_INFO;
+ }
+ /*
+ * Set the image command line. Need to do this as last thing,
+ * as Illumos kernel dboot_startkern will check cmdline
+ * address as last check to find first free address.
+ */
+ if (fp->f_args == NULL) {
+ if (xen)
+ cmdline = getenv("xen_cmdline");
+ else
+ cmdline = getenv("boot-args");
+ if (cmdline != NULL) {
+ fp->f_args = strdup(cmdline);
+ if (fp->f_args == NULL) {
+ error = ENOMEM;
+ goto error;
+ }
+ }
+ }
+
+ /*
+ * if image is xen, we just use f_name + f_args for commandline
+ * for unix, we need to add zfs-bootfs.
+ */
+ if (xen) {
+ len = strlen(fp->f_name) + 1;
+ if (fp->f_args != NULL)
+ len += strlen(fp->f_args) + 1;
+
+ if (fp->f_args != NULL) {
+ if((cmdline = malloc(len)) == NULL) {
+ error = ENOMEM;
+ goto error;
+ }
+ snprintf(cmdline, len, "%s %s", fp->f_name, fp->f_args);
+ } else {
+ cmdline = strdup(fp->f_name);
+ }
+ } else {
+ cmdline = kernel_cmdline(fp, rootdev);
+ }
+
+ if (cmdline == NULL) {
+ error = ENOMEM;
+ goto error;
+ }
+
+ mb_info->cmdline = mb_malloc(strlen(cmdline)+1);
+ i386_copyin(cmdline, mb_info->cmdline, strlen(cmdline)+1);
+ mb_info->flags |= MULTIBOOT_INFO_CMDLINE;
+ free(cmdline);
+ cmdline = NULL;
+
+ dev_cleanup();
+ __exec((void *)VTOP(multiboot_tramp), (void *)entry,
+ (void *)VTOP(mb_info));
+
+ panic("exec returned");
+
+error:
+ return (error);
+}
+
+static int
+multiboot_obj_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ struct preloaded_file *mfp, *kfp, *rfp;
+ struct kernel_module *kmp;
+ int error, mod_num;
+
+ /* See if there's a aout multiboot kernel loaded */
+ mfp = file_findfile(NULL, "aout multiboot kernel");
+ if (mfp != NULL) {
+ /* we have normal kernel loaded, add module */
+ rfp = file_loadraw(filename, "module", 0, NULL, 0);
+ if (rfp == NULL) {
+ printf(
+ "Unable to load %s as a multiboot payload module\n",
+ filename);
+ return (EINVAL);
+ }
+ rfp->f_size = roundup(rfp->f_size, PAGE_SIZE);
+ *result = rfp;
+ return (0);
+ }
+
+ /* See if there's a multiboot kernel loaded */
+ mfp = file_findfile(NULL, "elf multiboot kernel");
+ if (mfp == NULL) {
+ return (EFTYPE); /* this allows to check other methods */
+ }
+
+ /*
+ * We have a multiboot kernel loaded, see if there's a
+ * kernel loaded also.
+ */
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL) {
+ /*
+ * No kernel loaded, this must be it. The kernel has to
+ * be loaded as a raw file, it will be processed by
+ * Xen and correctly loaded as an ELF file.
+ */
+ rfp = file_loadraw(filename, "elf kernel", 0, NULL, 0);
+ if (rfp == NULL) {
+ printf(
+ "Unable to load %s as a multiboot payload kernel\n",
+ filename);
+ return (EINVAL);
+ }
+
+ /* Load kernel metadata... */
+ setenv("kernelname", filename, 1);
+ error = elf64_load_modmetadata(rfp, rfp->f_addr + rfp->f_size);
+ if (error) {
+ printf("Unable to load kernel %s metadata error: %d\n",
+ rfp->f_name, error);
+ return (EINVAL);
+ }
+
+ /*
+ * Save space at the end of the kernel in order to place
+ * the metadata information. We do an approximation of the
+ * max metadata size, this is not optimal but it's probably
+ * the best we can do at this point. Once all modules are
+ * loaded and the size of the metadata is known this
+ * space will be recovered if not used.
+ */
+ mod_num = num_modules(rfp);
+ rfp->f_size = roundup(rfp->f_size, PAGE_SIZE);
+ rfp->f_size += METADATA_RESV_SIZE(mod_num);
+ *result = rfp;
+ } else {
+ /* The rest should be loaded as regular modules */
+ error = elf64_obj_loadfile(filename, dest, result);
+ if (error != 0) {
+ printf("Unable to load %s as an object file, error: %d",
+ filename, error);
+ return (error);
+ }
+ }
+
+ return (0);
+}
+
+static int
+multiboot_obj_exec(struct preloaded_file *fp)
+{
+
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/multiboot.h b/usr/src/boot/sys/boot/i386/libi386/multiboot.h
new file mode 100644
index 0000000000..819fa2e501
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/multiboot.h
@@ -0,0 +1,225 @@
+/* multiboot.h - Multiboot header file. */
+/* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to
+* deal in the Software without restriction, including without limitation the
+* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+* sell copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
+* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+* $FreeBSD$
+*/
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header. */
+#define MULTIBOOT_SEARCH 8192
+
+/* The magic field should contain this. */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+
+/* This should be in %eax. */
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+/* The bits in the required part of flags field we don't support. */
+#define MULTIBOOT_UNSUPPORTED 0x0000fffc
+
+/* Alignment of multiboot modules. */
+#define MULTIBOOT_MOD_ALIGN 0x00001000
+
+/* Alignment of the multiboot info structure. */
+#define MULTIBOOT_INFO_ALIGN 0x00000004
+
+/* Flags set in the 'flags' member of the multiboot header. */
+
+/* Align all boot modules on i386 page (4KB) boundaries. */
+#define MULTIBOOT_PAGE_ALIGN 0x00000001
+
+/* Must pass memory information to OS. */
+#define MULTIBOOT_MEMORY_INFO 0x00000002
+
+/* Must pass video information to OS. */
+#define MULTIBOOT_VIDEO_MODE 0x00000004
+
+/* This flag indicates the use of the address fields in the header. */
+#define MULTIBOOT_AOUT_KLUDGE 0x00010000
+
+/* Flags to be set in the 'flags' member of the multiboot info structure. */
+
+/* is there basic lower/upper memory information? */
+#define MULTIBOOT_INFO_MEMORY 0x00000001
+/* is there a boot device set? */
+#define MULTIBOOT_INFO_BOOTDEV 0x00000002
+/* is the command-line defined? */
+#define MULTIBOOT_INFO_CMDLINE 0x00000004
+/* are there modules to do something with? */
+#define MULTIBOOT_INFO_MODS 0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
+/* is there an ELF section header table? */
+#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
+
+/* is there a full memory map? */
+#define MULTIBOOT_INFO_MEM_MAP 0x00000040
+
+/* Is there drive info? */
+#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
+
+/* Is there a config table? */
+#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
+
+/* Is there a boot loader name? */
+#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
+
+/* Is there a APM table? */
+#define MULTIBOOT_INFO_APM_TABLE 0x00000400
+
+/* Is there video information? */
+#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800
+
+#ifndef ASM_FILE
+
+typedef unsigned short multiboot_uint16_t;
+typedef unsigned int multiboot_uint32_t;
+typedef unsigned long long multiboot_uint64_t;
+
+struct multiboot_header
+{
+/* Must be MULTIBOOT_MAGIC - see above. */
+ multiboot_uint32_t magic;
+
+/* Feature flags. */
+ multiboot_uint32_t flags;
+
+/* The above fields plus this one must equal 0 mod 2^32. */
+ multiboot_uint32_t checksum;
+
+/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
+ multiboot_uint32_t header_addr;
+ multiboot_uint32_t load_addr;
+ multiboot_uint32_t load_end_addr;
+ multiboot_uint32_t bss_end_addr;
+ multiboot_uint32_t entry_addr;
+
+/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
+ multiboot_uint32_t mode_type;
+ multiboot_uint32_t width;
+ multiboot_uint32_t height;
+ multiboot_uint32_t depth;
+};
+
+/* The symbol table for a.out. */
+struct multiboot_aout_symbol_table
+{
+ multiboot_uint32_t tabsize;
+ multiboot_uint32_t strsize;
+ multiboot_uint32_t addr;
+ multiboot_uint32_t reserved;
+};
+typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
+
+/* The section header table for ELF. */
+struct multiboot_elf_section_header_table
+{
+ multiboot_uint32_t num;
+ multiboot_uint32_t size;
+ multiboot_uint32_t addr;
+ multiboot_uint32_t shndx;
+};
+typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
+
+struct multiboot_info
+{
+/* Multiboot info version number */
+ multiboot_uint32_t flags;
+
+/* Available memory from BIOS */
+ multiboot_uint32_t mem_lower;
+ multiboot_uint32_t mem_upper;
+
+/* "root" partition */
+ multiboot_uint32_t boot_device;
+
+/* Kernel command line */
+ multiboot_uint32_t cmdline;
+
+/* Boot-Module list */
+ multiboot_uint32_t mods_count;
+ multiboot_uint32_t mods_addr;
+
+ union
+ {
+ multiboot_aout_symbol_table_t aout_sym;
+ multiboot_elf_section_header_table_t elf_sec;
+ } u;
+
+/* Memory Mapping buffer */
+ multiboot_uint32_t mmap_length;
+ multiboot_uint32_t mmap_addr;
+
+/* Drive Info buffer */
+ multiboot_uint32_t drives_length;
+ multiboot_uint32_t drives_addr;
+
+/* ROM configuration table */
+ multiboot_uint32_t config_table;
+
+/* Boot Loader Name */
+ multiboot_uint32_t boot_loader_name;
+
+/* APM table */
+ multiboot_uint32_t apm_table;
+
+/* Video */
+ multiboot_uint32_t vbe_control_info;
+ multiboot_uint32_t vbe_mode_info;
+ multiboot_uint16_t vbe_mode;
+ multiboot_uint16_t vbe_interface_seg;
+ multiboot_uint16_t vbe_interface_off;
+ multiboot_uint16_t vbe_interface_len;
+};
+typedef struct multiboot_info multiboot_info_t;
+
+struct multiboot_mmap_entry
+{
+ multiboot_uint32_t size;
+ multiboot_uint64_t addr;
+ multiboot_uint64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE 1
+#define MULTIBOOT_MEMORY_RESERVED 2
+ multiboot_uint32_t type;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
+
+struct multiboot_mod_list
+{
+/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+ multiboot_uint32_t mod_start;
+ multiboot_uint32_t mod_end;
+
+/* Module command line */
+ multiboot_uint32_t cmdline;
+
+/* padding to take it to 16 bytes (must be zero) */
+ multiboot_uint32_t pad;
+};
+typedef struct multiboot_mod_list multiboot_module_t;
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT_HEADER */
diff --git a/usr/src/boot/sys/boot/i386/libi386/multiboot_tramp.S b/usr/src/boot/sys/boot/i386/libi386/multiboot_tramp.S
new file mode 100644
index 0000000000..0bd604365f
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/multiboot_tramp.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2014 Roger Pau Monné <royger@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define ASM_FILE
+#include "multiboot.h"
+
+/*
+ * The multiboot specification requires the executable to be launched
+ * with %cs set to a flat read/execute segment with offset 0 and limit
+ * 0xFFFFFFFF, and the rest of the segment registers (%ds, %es, %fs,
+ * %gs, %ss) to flat read/write segments with the same offset and limit.
+ * This is already done by the BTX code before calling multiboot_tramp,
+ * so there is no need to do anything here.
+ */
+
+ .globl multiboot_tramp
+multiboot_tramp:
+ /* Be sure that interrupts are disabled. */
+ cli
+
+ movl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
+ /* Get the entry point and address of the multiboot_info parameter. */
+ movl 8(%esp), %ebx
+ movl 4(%esp), %ecx
+
+ call *%ecx
diff --git a/usr/src/boot/sys/boot/i386/libi386/nullconsole.c b/usr/src/boot/sys/boot/i386/libi386/nullconsole.c
new file mode 100644
index 0000000000..cd9f3a514a
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/nullconsole.c
@@ -0,0 +1,90 @@
+/*-
+ * nullconsole.c
+ *
+ * Author: Doug Ambrisko <ambrisko@whistle.com>
+ * Copyright (c) 2000 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+
+static void nullc_probe(struct console *cp);
+static int nullc_init(struct console *, int arg);
+static void nullc_putchar(struct console *, int c);
+static int nullc_getchar(struct console *);
+static int nullc_ischar(struct console *);
+
+struct console nullconsole = {
+ "null",
+ "null port",
+ 0,
+ nullc_probe,
+ nullc_init,
+ nullc_putchar,
+ nullc_getchar,
+ nullc_ischar,
+ NULL
+};
+
+static void
+nullc_probe(struct console *cp)
+{
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+}
+
+static int
+nullc_init(struct console *cp __attribute((unused)),
+ int arg __attribute((unused)))
+{
+ return(0);
+}
+
+static void
+nullc_putchar(struct console *cp __attribute((unused)),
+ int c __attribute((unused)))
+{
+}
+
+static int
+nullc_getchar(struct console *cp __attribute((unused)))
+{
+ return(-1);
+}
+
+static int
+nullc_ischar(struct console *cp __attribute((unused)))
+{
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/pread.c b/usr/src/boot/sys/boot/i386/libi386/pread.c
new file mode 100644
index 0000000000..870e254015
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/pread.c
@@ -0,0 +1,80 @@
+/*
+ * $NetBSD: pread.c,v 1.2 1997/03/22 01:48:38 thorpej Exp $
+ */
+
+/*-
+ * Copyright (c) 1996
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* read into destination in flat addr space */
+
+#include <stand.h>
+
+#include "libi386.h"
+
+#ifdef SAVE_MEMORY
+#define BUFSIZE (1*1024)
+#else
+#define BUFSIZE (4*1024)
+#endif
+
+static char buf[BUFSIZE];
+
+int
+pread(fd, dest, size)
+ int fd;
+ vm_offset_t dest;
+ int size;
+{
+ int rsize;
+
+ rsize = size;
+ while (rsize > 0) {
+ int count, got;
+
+ count = (rsize < BUFSIZE ? rsize : BUFSIZE);
+
+ got = read(fd, buf, count);
+ if (got < 0)
+ return (-1);
+
+ /* put to physical space */
+ vpbcopy(buf, dest, got);
+
+ dest += got;
+ rsize -= got;
+ if (got < count)
+ break; /* EOF */
+ }
+ return (size - rsize);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/pxe.c b/usr/src/boot/sys/boot/i386/libi386/pxe.c
new file mode 100644
index 0000000000..cddf8d244e
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/pxe.c
@@ -0,0 +1,710 @@
+/*-
+ * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
+ * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
+ * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+
+#include <net.h>
+#include <netif.h>
+#include <nfsv2.h>
+#include <iodesc.h>
+
+#include <bootp.h>
+#include <bootstrap.h>
+#include "btxv86.h"
+#include "pxe.h"
+
+/*
+ * Allocate the PXE buffers statically instead of sticking grimy fingers into
+ * BTX's private data area. The scratch buffer is used to send information to
+ * the PXE BIOS, and the data buffer is used to receive data from the PXE BIOS.
+ */
+#define PXE_BUFFER_SIZE 0x2000
+#define PXE_TFTP_BUFFER_SIZE 512
+static char scratch_buffer[PXE_BUFFER_SIZE];
+static char data_buffer[PXE_BUFFER_SIZE];
+
+static pxenv_t *pxenv_p = NULL; /* PXENV+ */
+static pxe_t *pxe_p = NULL; /* !PXE */
+BOOTPLAYER bootplayer = {0}; /* PXE Cached information. */
+
+static int pxe_debug = 0;
+static int pxe_sock = -1;
+static int pxe_opens = 0;
+
+void pxe_enable(void *pxeinfo);
+static void (*pxe_call)(int func);
+static void pxenv_call(int func);
+static void bangpxe_call(int func);
+
+static int pxe_init(void);
+static int pxe_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t offset, size_t size, char *buf, size_t *rsize);
+static int pxe_open(struct open_file *f, ...);
+static int pxe_close(struct open_file *f);
+static int pxe_print(int verbose);
+static void pxe_cleanup(void);
+static void pxe_setnfshandle(char *rootpath);
+
+static void pxe_perror(int error);
+static int pxe_netif_match(struct netif *nif, void *machdep_hint);
+static int pxe_netif_probe(struct netif *nif, void *machdep_hint);
+static void pxe_netif_init(struct iodesc *desc, void *machdep_hint);
+static int pxe_netif_get(struct iodesc *desc, void *pkt, size_t len,
+ time_t timeout);
+static int pxe_netif_put(struct iodesc *desc, void *pkt, size_t len);
+static void pxe_netif_end(struct netif *nif);
+
+#ifdef OLD_NFSV2
+int nfs_getrootfh(struct iodesc*, char*, u_char*);
+#else
+int nfs_getrootfh(struct iodesc*, char*, uint32_t*, u_char*);
+#endif
+
+extern struct netif_stats pxe_st[];
+extern u_int16_t __bangpxeseg;
+extern u_int16_t __bangpxeoff;
+extern void __bangpxeentry(void);
+extern u_int16_t __pxenvseg;
+extern u_int16_t __pxenvoff;
+extern void __pxenventry(void);
+
+struct netif_dif pxe_ifs[] = {
+/* dif_unit dif_nsel dif_stats dif_private */
+ {0, 1, &pxe_st[0], 0}
+};
+
+struct netif_stats pxe_st[NENTS(pxe_ifs)];
+
+struct netif_driver pxenetif = {
+ "pxenet",
+ pxe_netif_match,
+ pxe_netif_probe,
+ pxe_netif_init,
+ pxe_netif_get,
+ pxe_netif_put,
+ pxe_netif_end,
+ pxe_ifs,
+ NENTS(pxe_ifs)
+};
+
+struct netif_driver *netif_drivers[] = {
+ &pxenetif,
+ NULL
+};
+
+struct devsw pxedisk = {
+ "pxe",
+ DEVT_NET,
+ pxe_init,
+ pxe_strategy,
+ pxe_open,
+ pxe_close,
+ noioctl,
+ pxe_print,
+ pxe_cleanup
+};
+
+/*
+ * This function is called by the loader to enable PXE support if we
+ * are booted by PXE. The passed in pointer is a pointer to the
+ * PXENV+ structure.
+ */
+void
+pxe_enable(void *pxeinfo)
+{
+ pxenv_p = (pxenv_t *)pxeinfo;
+ pxe_p = (pxe_t *)PTOV(pxenv_p->PXEPtr.segment * 16 +
+ pxenv_p->PXEPtr.offset);
+ pxe_call = NULL;
+}
+
+/*
+ * return true if pxe structures are found/initialized,
+ * also figures out our IP information via the pxe cached info struct
+ */
+static int
+pxe_init(void)
+{
+ t_PXENV_GET_CACHED_INFO *gci_p;
+ int counter;
+ uint8_t checksum;
+ uint8_t *checkptr;
+
+ if(pxenv_p == NULL)
+ return (0);
+
+ /* look for "PXENV+" */
+ if (bcmp((void *)pxenv_p->Signature, S_SIZE("PXENV+"))) {
+ pxenv_p = NULL;
+ return (0);
+ }
+
+ /* make sure the size is something we can handle */
+ if (pxenv_p->Length > sizeof(*pxenv_p)) {
+ printf("PXENV+ structure too large, ignoring\n");
+ pxenv_p = NULL;
+ return (0);
+ }
+
+ /*
+ * do byte checksum:
+ * add up each byte in the structure, the total should be 0
+ */
+ checksum = 0;
+ checkptr = (uint8_t *) pxenv_p;
+ for (counter = 0; counter < pxenv_p->Length; counter++)
+ checksum += *checkptr++;
+ if (checksum != 0) {
+ printf("PXENV+ structure failed checksum, ignoring\n");
+ pxenv_p = NULL;
+ return (0);
+ }
+
+
+ /*
+ * PXENV+ passed, so use that if !PXE is not available or
+ * the checksum fails.
+ */
+ pxe_call = pxenv_call;
+ if (pxenv_p->Version >= 0x0200) {
+ for (;;) {
+ if (bcmp((void *)pxe_p->Signature, S_SIZE("!PXE"))) {
+ pxe_p = NULL;
+ break;
+ }
+ checksum = 0;
+ checkptr = (uint8_t *)pxe_p;
+ for (counter = 0; counter < pxe_p->StructLength;
+ counter++)
+ checksum += *checkptr++;
+ if (checksum != 0) {
+ pxe_p = NULL;
+ break;
+ }
+ pxe_call = bangpxe_call;
+ break;
+ }
+ }
+
+ printf("\nPXE version %d.%d, real mode entry point ",
+ (uint8_t) (pxenv_p->Version >> 8),
+ (uint8_t) (pxenv_p->Version & 0xFF));
+ if (pxe_call == bangpxe_call)
+ printf("@%04x:%04x\n",
+ pxe_p->EntryPointSP.segment,
+ pxe_p->EntryPointSP.offset);
+ else
+ printf("@%04x:%04x\n",
+ pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset);
+
+ gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
+ bzero(gci_p, sizeof(*gci_p));
+ gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
+ pxe_call(PXENV_GET_CACHED_INFO);
+ if (gci_p->Status != 0) {
+ pxe_perror(gci_p->Status);
+ pxe_p = NULL;
+ return (0);
+ }
+ bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
+ &bootplayer, gci_p->BufferSize);
+ return (1);
+}
+
+
+static int
+pxe_strategy(void *devdata, int flag, daddr_t dblk, size_t offset, size_t size,
+ char *buf, size_t *rsize)
+{
+ return (EIO);
+}
+
+static int
+pxe_open(struct open_file *f, ...)
+{
+ va_list args;
+ char *devname; /* Device part of file name (or NULL). */
+ char temp[FNAME_SIZE];
+ int error = 0;
+ int i;
+
+ va_start(args, f);
+ devname = va_arg(args, char*);
+ va_end(args);
+
+ /* On first open, do netif open, mount, etc. */
+ if (pxe_opens == 0) {
+ /* Find network interface. */
+ if (pxe_sock < 0) {
+ pxe_sock = netif_open(devname);
+ if (pxe_sock < 0) {
+ printf("pxe_open: netif_open() failed\n");
+ return (ENXIO);
+ }
+ if (pxe_debug)
+ printf("pxe_open: netif_open() succeeded\n");
+ }
+ if (rootip.s_addr == 0) {
+ /*
+ * Do a bootp/dhcp request to find out where our
+ * NFS/TFTP server is. Even if we dont get back
+ * the proper information, fall back to the server
+ * which brought us to life and a default rootpath.
+ */
+ bootp(pxe_sock, BOOTP_PXE);
+ if (rootip.s_addr == 0)
+ rootip.s_addr = bootplayer.sip;
+#ifdef LOADER_NFS_SUPPORT
+ if (!rootpath[0])
+ strcpy(rootpath, PXENFSROOTPATH);
+#endif
+
+ for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
+ if (rootpath[i] == ':')
+ break;
+ if (i && i != FNAME_SIZE && rootpath[i] == ':') {
+ rootpath[i++] = '\0';
+ if (inet_addr(&rootpath[0]) != INADDR_NONE)
+ rootip.s_addr = inet_addr(&rootpath[0]);
+ bcopy(&rootpath[i], &temp[0], strlen(&rootpath[i])+1);
+ bcopy(&temp[0], &rootpath[0], strlen(&rootpath[i])+1);
+ }
+ setenv("boot.netif.ip", inet_ntoa(myip), 1);
+ setenv("boot.netif.netmask", intoa(netmask), 1);
+ setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
+ if (bootplayer.Hardware == ETHER_TYPE) {
+ sprintf(temp, "%6D", bootplayer.CAddr, ":");
+ setenv("boot.netif.hwaddr", temp, 1);
+ }
+#ifdef LOADER_NFS_SUPPORT
+ printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
+ printf("pxe_open: server path: %s\n", rootpath);
+ printf("pxe_open: gateway ip: %s\n", inet_ntoa(gateip));
+
+ setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
+ setenv("boot.nfsroot.path", rootpath, 1);
+#else
+ setenv("boot.netif.server", inet_ntoa(rootip), 1);
+ setenv("boot.tftproot.path", rootpath, 1);
+#endif
+ setenv("dhcp.host-name", hostname, 1);
+
+ setenv("pxeboot.ip", inet_ntoa(myip), 1);
+ if (bootplayer.Hardware == ETHER_TYPE) {
+ sprintf(temp, "%6D", bootplayer.CAddr, ":");
+ setenv("pxeboot.hwaddr", temp, 1);
+ }
+ }
+ }
+ pxe_opens++;
+ f->f_devdata = &pxe_sock;
+ return (error);
+}
+
+static int
+pxe_close(struct open_file *f)
+{
+
+#ifdef PXE_DEBUG
+ if (pxe_debug)
+ printf("pxe_close: opens=%d\n", pxe_opens);
+#endif
+
+ /* On last close, do netif close, etc. */
+ f->f_devdata = NULL;
+ /* Extra close call? */
+ if (pxe_opens <= 0)
+ return (0);
+ pxe_opens--;
+ /* Not last close? */
+ if (pxe_opens > 0)
+ return(0);
+
+#ifdef LOADER_NFS_SUPPORT
+ /* get an NFS filehandle for our root filesystem */
+ pxe_setnfshandle(rootpath);
+#endif
+
+ if (pxe_sock >= 0) {
+
+#ifdef PXE_DEBUG
+ if (pxe_debug)
+ printf("pxe_close: calling netif_close()\n");
+#endif
+ netif_close(pxe_sock);
+ pxe_sock = -1;
+ }
+ return (0);
+}
+
+static int
+pxe_print(int verbose)
+{
+ char line[255];
+ if (pxe_call == NULL)
+ return (0);
+
+ snprintf(line, sizeof (line), " pxe0: %s:%s\n", inet_ntoa(rootip),
+ rootpath);
+ return (pager_output(line));
+}
+
+static void
+pxe_cleanup(void)
+{
+#ifdef PXE_DEBUG
+ t_PXENV_UNLOAD_STACK *unload_stack_p =
+ (t_PXENV_UNLOAD_STACK *)scratch_buffer;
+ t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p =
+ (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
+#endif
+
+ if (pxe_call == NULL)
+ return;
+
+ pxe_call(PXENV_UNDI_SHUTDOWN);
+
+#ifdef PXE_DEBUG
+ if (pxe_debug && undi_shutdown_p->Status != 0)
+ printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n",
+ undi_shutdown_p->Status);
+#endif
+
+ pxe_call(PXENV_UNLOAD_STACK);
+
+#ifdef PXE_DEBUG
+ if (pxe_debug && unload_stack_p->Status != 0)
+ printf("pxe_cleanup: UNLOAD_STACK failed %x\n",
+ unload_stack_p->Status);
+#endif
+}
+
+void
+pxe_perror(int err)
+{
+ return;
+}
+
+#ifdef LOADER_NFS_SUPPORT
+/*
+ * Reach inside the libstand NFS code and dig out an NFS handle
+ * for the root filesystem.
+ */
+#ifdef OLD_NFSV2
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ u_char fh[NFS_FHSIZE];
+ /* structure truncated here */
+};
+extern struct nfs_iodesc nfs_root_node;
+extern int rpc_port;
+
+static void
+pxe_rpcmountcall()
+{
+ struct iodesc *d;
+ int error;
+
+ if (!(d = socktodesc(pxe_sock)))
+ return;
+ d->myport = htons(--rpc_port);
+ d->destip = rootip;
+ if ((error = nfs_getrootfh(d, rootpath, nfs_root_node.fh)) != 0)
+ printf("NFS MOUNT RPC error: %d\n", error);
+ nfs_root_node.iodesc = d;
+}
+
+static void
+pxe_setnfshandle(char *rootpath)
+{
+ int i;
+ u_char *fh;
+ char buf[2 * NFS_FHSIZE + 3], *cp;
+
+ /*
+ * If NFS files were never opened, we need to do mount call
+ * ourselves. Use nfs_root_node.iodesc as flag indicating
+ * previous NFS usage.
+ */
+ if (nfs_root_node.iodesc == NULL)
+ pxe_rpcmountcall();
+
+ fh = &nfs_root_node.fh[0];
+ buf[0] = 'X';
+ cp = &buf[1];
+ for (i = 0; i < NFS_FHSIZE; i++, cp += 2)
+ sprintf(cp, "%02x", fh[i]);
+ sprintf(cp, "X");
+ setenv("boot.nfsroot.nfshandle", buf, 1);
+}
+#else /* !OLD_NFSV2 */
+
+#define NFS_V3MAXFHSIZE 64
+
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ uint32_t fhsize;
+ u_char fh[NFS_V3MAXFHSIZE];
+ /* structure truncated */
+};
+extern struct nfs_iodesc nfs_root_node;
+extern int rpc_port;
+
+static void
+pxe_rpcmountcall()
+{
+ struct iodesc *d;
+ int error;
+
+ if (!(d = socktodesc(pxe_sock)))
+ return;
+ d->myport = htons(--rpc_port);
+ d->destip = rootip;
+ if ((error = nfs_getrootfh(d, rootpath, &nfs_root_node.fhsize,
+ nfs_root_node.fh)) != 0) {
+ printf("NFS MOUNT RPC error: %d\n", error);
+ nfs_root_node.fhsize = 0;
+ }
+ nfs_root_node.iodesc = d;
+}
+
+static void
+pxe_setnfshandle(char *rootpath)
+{
+ int i;
+ u_char *fh;
+ char buf[2 * NFS_V3MAXFHSIZE + 3], *cp;
+
+ /*
+ * If NFS files were never opened, we need to do mount call
+ * ourselves. Use nfs_root_node.iodesc as flag indicating
+ * previous NFS usage.
+ */
+ if (nfs_root_node.iodesc == NULL)
+ pxe_rpcmountcall();
+
+ fh = &nfs_root_node.fh[0];
+ buf[0] = 'X';
+ cp = &buf[1];
+ for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2)
+ sprintf(cp, "%02x", fh[i]);
+ sprintf(cp, "X");
+ setenv("boot.nfsroot.nfshandle", buf, 1);
+ sprintf(buf, "%d", nfs_root_node.fhsize);
+ setenv("boot.nfsroot.nfshandlelen", buf, 1);
+}
+#endif /* OLD_NFSV2 */
+#endif /* LOADER_NFS_SUPPORT */
+
+void
+pxenv_call(int func)
+{
+#ifdef PXE_DEBUG
+ if (pxe_debug)
+ printf("pxenv_call %x\n", func);
+#endif
+
+ bzero(&v86, sizeof(v86));
+ bzero(data_buffer, sizeof(data_buffer));
+
+ __pxenvseg = pxenv_p->RMEntry.segment;
+ __pxenvoff = pxenv_p->RMEntry.offset;
+
+ v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+ v86.es = VTOPSEG(scratch_buffer);
+ v86.edi = VTOPOFF(scratch_buffer);
+ v86.addr = (VTOPSEG(__pxenventry) << 16) | VTOPOFF(__pxenventry);
+ v86.ebx = func;
+ v86int();
+ v86.ctl = V86_FLAGS;
+}
+
+void
+bangpxe_call(int func)
+{
+#ifdef PXE_DEBUG
+ if (pxe_debug)
+ printf("bangpxe_call %x\n", func);
+#endif
+
+ bzero(&v86, sizeof(v86));
+ bzero(data_buffer, sizeof(data_buffer));
+
+ __bangpxeseg = pxe_p->EntryPointSP.segment;
+ __bangpxeoff = pxe_p->EntryPointSP.offset;
+
+ v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+ v86.edx = VTOPSEG(scratch_buffer);
+ v86.eax = VTOPOFF(scratch_buffer);
+ v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry);
+ v86.ebx = func;
+ v86int();
+ v86.ctl = V86_FLAGS;
+}
+
+
+time_t
+getsecs()
+{
+ time_t n = 0;
+ time(&n);
+ return n;
+}
+
+static int
+pxe_netif_match(struct netif *nif, void *machdep_hint)
+{
+ return 1;
+}
+
+
+static int
+pxe_netif_probe(struct netif *nif, void *machdep_hint)
+{
+ t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer;
+
+ if (pxe_call == NULL)
+ return -1;
+
+ bzero(udpopen_p, sizeof(*udpopen_p));
+ udpopen_p->src_ip = bootplayer.yip;
+ pxe_call(PXENV_UDP_OPEN);
+
+ if (udpopen_p->status != 0) {
+ printf("pxe_netif_probe: failed %x\n", udpopen_p->status);
+ return -1;
+ }
+ return 0;
+}
+
+static void
+pxe_netif_end(struct netif *nif)
+{
+ t_PXENV_UDP_CLOSE *udpclose_p = (t_PXENV_UDP_CLOSE *)scratch_buffer;
+ bzero(udpclose_p, sizeof(*udpclose_p));
+
+ pxe_call(PXENV_UDP_CLOSE);
+ if (udpclose_p->status != 0)
+ printf("pxe_end failed %x\n", udpclose_p->status);
+}
+
+static void
+pxe_netif_init(struct iodesc *desc, void *machdep_hint)
+{
+ int i;
+ for (i = 0; i < 6; ++i)
+ desc->myea[i] = bootplayer.CAddr[i];
+ desc->xid = bootplayer.ident;
+}
+
+static int
+pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+{
+ return len;
+}
+
+static int
+pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
+{
+ return len;
+}
+
+ssize_t
+sendudp(struct iodesc *h, void *pkt, size_t len)
+{
+ t_PXENV_UDP_WRITE *udpwrite_p = (t_PXENV_UDP_WRITE *)scratch_buffer;
+ bzero(udpwrite_p, sizeof(*udpwrite_p));
+
+ udpwrite_p->ip = h->destip.s_addr;
+ udpwrite_p->dst_port = h->destport;
+ udpwrite_p->src_port = h->myport;
+ udpwrite_p->buffer_size = len;
+ udpwrite_p->buffer.segment = VTOPSEG(pkt);
+ udpwrite_p->buffer.offset = VTOPOFF(pkt);
+
+ if (netmask == 0 || SAMENET(myip, h->destip, netmask))
+ udpwrite_p->gw = 0;
+ else
+ udpwrite_p->gw = gateip.s_addr;
+
+ pxe_call(PXENV_UDP_WRITE);
+
+#if 0
+ /* XXX - I dont know why we need this. */
+ delay(1000);
+#endif
+ if (udpwrite_p->status != 0) {
+ /* XXX: This happens a lot. It shouldn't. */
+ if (udpwrite_p->status != 1)
+ printf("sendudp failed %x\n", udpwrite_p->status);
+ return -1;
+ }
+ return len;
+}
+
+ssize_t
+readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout)
+{
+ t_PXENV_UDP_READ *udpread_p = (t_PXENV_UDP_READ *)scratch_buffer;
+ struct udphdr *uh = NULL;
+
+ uh = (struct udphdr *) pkt - 1;
+ bzero(udpread_p, sizeof(*udpread_p));
+
+ udpread_p->dest_ip = h->myip.s_addr;
+ udpread_p->d_port = h->myport;
+ udpread_p->buffer_size = len;
+ udpread_p->buffer.segment = VTOPSEG(data_buffer);
+ udpread_p->buffer.offset = VTOPOFF(data_buffer);
+
+ pxe_call(PXENV_UDP_READ);
+
+#if 0
+ /* XXX - I dont know why we need this. */
+ delay(1000);
+#endif
+ if (udpread_p->status != 0) {
+ /* XXX: This happens a lot. It shouldn't. */
+ if (udpread_p->status != 1)
+ printf("readudp failed %x\n", udpread_p->status);
+ return -1;
+ }
+ bcopy(data_buffer, pkt, udpread_p->buffer_size);
+ uh->uh_sport = udpread_p->s_port;
+ return udpread_p->buffer_size;
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/pxe.h b/usr/src/boot/sys/boot/i386/libi386/pxe.h
new file mode 100644
index 0000000000..651bdcd35f
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/pxe.h
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The typedefs and structures declared in this file
+ * clearly violate style(9), the reason for this is to conform to the
+ * typedefs/structure-names used in the Intel literature to avoid confusion.
+ *
+ * It's for your own good. :)
+ */
+
+/* It seems that intel didn't think about ABI,
+ * either that or 16bit ABI != 32bit ABI (which seems reasonable)
+ * I have to thank Intel for the hair loss I incurred trying to figure
+ * out why PXE was mis-reading structures I was passing it (at least
+ * from my point of view)
+ *
+ * Solution: use gcc's '__packed' to correctly align
+ * structures passed into PXE
+ * Question: does this really work for PXE's expected ABI?
+ */
+#define PACKED __packed
+
+#define S_SIZE(s) s, sizeof(s) - 1
+
+#define PXENFSROOTPATH "/pxeroot"
+
+typedef struct {
+ uint16_t offset;
+ uint16_t segment;
+} SEGOFF16_t;
+
+typedef struct {
+ uint16_t Seg_Addr;
+ uint32_t Phy_Addr;
+ uint16_t Seg_Size;
+} SEGDESC_t;
+
+typedef uint16_t SEGSEL_t;
+typedef uint16_t PXENV_STATUS_t;
+typedef uint32_t IP4_t;
+typedef uint32_t ADDR32_t;
+typedef uint16_t UDP_PORT_t;
+
+#define MAC_ADDR_LEN 16
+typedef uint8_t MAC_ADDR[MAC_ADDR_LEN];
+
+/* PXENV+ */
+typedef struct {
+ uint8_t Signature[6]; /* 'PXENV+' */
+ uint16_t Version; /* MSB = major, LSB = minor */
+ uint8_t Length; /* structure length */
+ uint8_t Checksum; /* checksum pad */
+ SEGOFF16_t RMEntry; /* SEG:OFF to PXE entry point */
+ /* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
+ uint32_t PMOffset; /* Protected mode entry */
+ SEGSEL_t PMSelector; /* Protected mode selector */
+ SEGSEL_t StackSeg; /* Stack segment address */
+ uint16_t StackSize; /* Stack segment size (bytes) */
+ SEGSEL_t BC_CodeSeg; /* BC Code segment address */
+ uint16_t BC_CodeSize; /* BC Code segment size (bytes) */
+ SEGSEL_t BC_DataSeg; /* BC Data segment address */
+ uint16_t BC_DataSize; /* BC Data segment size (bytes) */
+ SEGSEL_t UNDIDataSeg; /* UNDI Data segment address */
+ uint16_t UNDIDataSize; /* UNDI Data segment size (bytes) */
+ SEGSEL_t UNDICodeSeg; /* UNDI Code segment address */
+ uint16_t UNDICodeSize; /* UNDI Code segment size (bytes) */
+ SEGOFF16_t PXEPtr; /* SEG:OFF to !PXE struct,
+ only present when Version > 2.1 */
+} PACKED pxenv_t;
+
+/* !PXE */
+typedef struct {
+ uint8_t Signature[4];
+ uint8_t StructLength;
+ uint8_t StructCksum;
+ uint8_t StructRev;
+ uint8_t reserved_1;
+ SEGOFF16_t UNDIROMID;
+ SEGOFF16_t BaseROMID;
+ SEGOFF16_t EntryPointSP;
+ SEGOFF16_t EntryPointESP;
+ SEGOFF16_t StatusCallout;
+ uint8_t reserved_2;
+ uint8_t SegDescCn;
+ SEGSEL_t FirstSelector;
+ SEGDESC_t Stack;
+ SEGDESC_t UNDIData;
+ SEGDESC_t UNDICode;
+ SEGDESC_t UNDICodeWrite;
+ SEGDESC_t BC_Data;
+ SEGDESC_t BC_Code;
+ SEGDESC_t BC_CodeWrite;
+} PACKED pxe_t;
+
+#define PXENV_START_UNDI 0x0000
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t ax;
+ uint16_t bx;
+ uint16_t dx;
+ uint16_t di;
+ uint16_t es;
+} PACKED t_PXENV_START_UNDI;
+
+#define PXENV_UNDI_STARTUP 0x0001
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_STARTUP;
+
+#define PXENV_UNDI_CLEANUP 0x0002
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_CLEANUP;
+
+#define PXENV_UNDI_INITIALIZE 0x0003
+typedef struct {
+ PXENV_STATUS_t Status;
+ ADDR32_t ProtocolIni; /* Phys addr of a copy of the driver module */
+ uint8_t reserved[8];
+} PACKED t_PXENV_UNDI_INITALIZE;
+
+
+#define MAXNUM_MCADDR 8
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t MCastAddrCount;
+ MAC_ADDR McastAddr[MAXNUM_MCADDR];
+} PACKED t_PXENV_UNDI_MCAST_ADDRESS;
+
+#define PXENV_UNDI_RESET_ADAPTER 0x0004
+typedef struct {
+ PXENV_STATUS_t Status;
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED t_PXENV_UNDI_RESET;
+
+#define PXENV_UNDI_SHUTDOWN 0x0005
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_SHUTDOWN;
+
+#define PXENV_UNDI_OPEN 0x0006
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t OpenFlag;
+ uint16_t PktFilter;
+# define FLTR_DIRECTED 0x0001
+# define FLTR_BRDCST 0x0002
+# define FLTR_PRMSCS 0x0003
+# define FLTR_SRC_RTG 0x0004
+
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED t_PXENV_UNDI_OPEN;
+
+#define PXENV_UNDI_CLOSE 0x0007
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_CLOSE;
+
+#define PXENV_UNDI_TRANSMIT 0x0008
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t Protocol;
+# define P_UNKNOWN 0
+# define P_IP 1
+# define P_ARP 2
+# define P_RARP 3
+
+ uint8_t XmitFlag;
+# define XMT_DESTADDR 0x0000
+# define XMT_BROADCAST 0x0001
+
+ SEGOFF16_t DestAddr;
+ SEGOFF16_t TBD;
+ uint32_t Reserved[2];
+} PACKED t_PXENV_UNDI_TRANSMIT;
+
+#define MAX_DATA_BLKS 8
+typedef struct {
+ uint16_t ImmedLength;
+ SEGOFF16_t Xmit;
+ uint16_t DataBlkCount;
+ struct DataBlk {
+ uint8_t TDPtrType;
+ uint8_t TDRsvdByte;
+ uint16_t TDDataLen;
+ SEGOFF16_t TDDataPtr;
+ } DataBlock[MAX_DATA_BLKS];
+} PACKED t_PXENV_UNDI_TBD;
+
+#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009
+typedef struct {
+ PXENV_STATUS_t Status;
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED t_PXENV_UNDI_SET_MCAST_ADDR;
+
+#define PXENV_UNDI_SET_STATION_ADDRESS 0x000A
+typedef struct {
+ PXENV_STATUS_t Status;
+ MAC_ADDR StationAddress; /* Temp MAC addres to use */
+} PACKED t_PXENV_UNDI_SET_STATION_ADDR;
+
+#define PXENV_UNDI_SET_PACKET_FILTER 0x000B
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t filter; /* see UNDI_OPEN (0x0006) */
+} PACKED t_PXENV_UNDI_SET_PACKET_FILTER;
+
+#define PXENV_UNDI_GET_INFORMATION 0x000C
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t BaseIo; /* Adapter base I/O address */
+ uint16_t IntNumber; /* Adapter IRQ number */
+ uint16_t MaxTranUnit; /* Adapter maximum transmit unit */
+ uint16_t HwType; /* Type of protocol at the hardware addr */
+# define ETHER_TYPE 1
+# define EXP_ETHER_TYPE 2
+# define IEEE_TYPE 6
+# define ARCNET_TYPE 7
+
+ uint16_t HwAddrLen; /* Length of hardware address */
+ MAC_ADDR CurrentNodeAddress; /* Current hardware address */
+ MAC_ADDR PermNodeAddress; /* Permanent hardware address */
+ SEGSEL_t ROMAddress; /* Real mode ROM segment address */
+ uint16_t RxBufCt; /* Receive queue length */
+ uint16_t TxBufCt; /* Transmit queue length */
+} PACKED t_PXENV_UNDI_GET_INFORMATION;
+
+#define PXENV_UNDI_GET_STATISTICS 0x000D
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint32_t XmitGoodFrames; /* Number of successful transmissions */
+ uint32_t RcvGoodFrames; /* Number of good frames received */
+ uint32_t RcvCRCErrors; /* Number of frames with CRC errors */
+ uint32_t RcvResourceErrors; /* Number of frames dropped */
+} PACKED t_PXENV_UNDI_GET_STATISTICS;
+
+#define PXENV_UNDI_CLEAR_STATISTICS 0x000E
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_CLEAR_STATISTICS;
+
+#define PXENV_UNDI_INITIATE_DIAGS 0x000F
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_INITIATE_DIAGS;
+
+#define PXENV_UNDI_FORCE_INTERRUPT 0x0010
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_UNDI_FORCE_INTERRUPT;
+
+#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t InetAddr; /* IP mulicast address */
+ MAC_ADDR MediaAddr; /* MAC multicast address */
+} PACKED t_PXENV_UNDI_GET_MCAST_ADDR;
+
+#define PXENV_UNDI_GET_NIC_TYPE 0x0012
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t NicType; /* Type of NIC */
+# define PCI_NIC 2
+# define PnP_NIC 3
+# define CardBus_NIC 4
+
+ union {
+ struct {
+ uint16_t Vendor_ID;
+ uint16_t Dev_ID;
+ uint8_t Base_Class;
+ uint8_t Sub_Class;
+ uint8_t Prog_Intf;
+ uint8_t Rev;
+ uint16_t BusDevFunc;
+ uint16_t SubVendor_ID;
+ uint16_t SubDevice_ID;
+ } pci, cardbus;
+ struct {
+ uint32_t EISA_Dev_ID;
+ uint8_t Base_Class;
+ uint8_t Sub_Class;
+ uint8_t Prog_Intf;
+ uint16_t CardSelNum;
+ } pnp;
+ } info;
+} PACKED t_PXENV_UNDI_GET_NIC_TYPE;
+
+#define PXENV_UNDI_GET_IFACE_INFO 0x0013
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t IfaceType[16]; /* Name of MAC type in ASCII. */
+ uint32_t LinkSpeed; /* Defined in NDIS 2.0 spec */
+ uint32_t ServiceFlags; /* Defined in NDIS 2.0 spec */
+ uint32_t Reserved[4]; /* must be 0 */
+} PACKED t_PXENV_UNDI_GET_NDIS_INFO;
+
+#define PXENV_UNDI_ISR 0x0014
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t FuncFlag; /* PXENV_UNDI_ISR_OUT_xxx */
+ uint16_t BufferLength; /* Length of Frame */
+ uint16_t FrameLength; /* Total length of reciever frame */
+ uint16_t FrameHeaderLength; /* Length of the media header in Frame */
+ SEGOFF16_t Frame; /* receive buffer */
+ uint8_t ProtType; /* Protocol type */
+ uint8_t PktType; /* Packet Type */
+# define PXENV_UNDI_ISR_IN_START 1
+# define PXENV_UNDI_ISR_IN_PROCESS 2
+# define PXENV_UNDI_ISR_IN_GET_NEXT 3
+
+ /* one of these will be returned for PXENV_UNDI_ISR_IN_START */
+# define PXENV_UNDI_ISR_OUT_OURS 0
+# define PXENV_UNDI_ISR_OUT_NOT_OUTS 1
+
+ /*
+ * one of these will bre returnd for PXEND_UNDI_ISR_IN_PROCESS
+ * and PXENV_UNDI_ISR_IN_GET_NEXT
+ */
+# define PXENV_UNDI_ISR_OUT_DONE 0
+# define PXENV_UNDI_ISR_OUT_TRANSMIT 2
+# define PXENV_UNDI_ISR_OUT_RECIEVE 3
+# define PXENV_UNDI_ISR_OUT_BUSY 4
+} PACKED t_PXENV_UNDI_ISR;
+
+#define PXENV_STOP_UNDI 0x0015
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_STOP_UNDI;
+
+#define PXENV_TFTP_OPEN 0x0020
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAddress;
+ uint8_t FileName[128];
+ UDP_PORT_t TFTPPort;
+ uint16_t PacketSize;
+} PACKED t_PXENV_TFTP_OPEN;
+
+#define PXENV_TFTP_CLOSE 0x0021
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_TFTP_CLOSE;
+
+#define PXENV_TFTP_READ 0x0022
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t PacketNumber;
+ uint16_t BufferSize;
+ SEGOFF16_t Buffer;
+} PACKED t_PXENV_TFTP_READ;
+
+#define PXENV_TFTP_READ_FILE 0x0023
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t FileName[128];
+ uint32_t BufferSize;
+ ADDR32_t Buffer;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAdress;
+ IP4_t McastIPAdress;
+ UDP_PORT_t TFTPClntPort;
+ UDP_PORT_t TFTPSrvPort;
+ uint16_t TFTPOpenTimeOut;
+ uint16_t TFTPReopenDelay;
+} PACKED t_PXENV_TFTP_READ_FILE;
+
+#define PXENV_TFTP_GET_FSIZE 0x0025
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAdress;
+ uint8_t FileName[128];
+ uint32_t FileSize;
+} PACKED t_PXENV_TFTP_GET_FSIZE;
+
+#define PXENV_UDP_OPEN 0x0030
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t src_ip; /* IP address of this station */
+} PACKED t_PXENV_UDP_OPEN;
+
+#define PXENV_UDP_CLOSE 0x0031
+typedef struct {
+ PXENV_STATUS_t status;
+} PACKED t_PXENV_UDP_CLOSE;
+
+#define PXENV_UDP_READ 0x0032
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t src_ip; /* IP of sender */
+ IP4_t dest_ip; /* Only accept packets sent to this IP */
+ UDP_PORT_t s_port; /* UDP source port of sender */
+ UDP_PORT_t d_port; /* Only accept packets sent to this port */
+ uint16_t buffer_size; /* Size of the packet buffer */
+ SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
+} PACKED t_PXENV_UDP_READ;
+
+#define PXENV_UDP_WRITE 0x0033
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t ip; /* dest ip addr */
+ IP4_t gw; /* ip gateway */
+ UDP_PORT_t src_port; /* source udp port */
+ UDP_PORT_t dst_port; /* destination udp port */
+ uint16_t buffer_size; /* Size of the packet buffer */
+ SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
+} PACKED t_PXENV_UDP_WRITE;
+
+#define PXENV_UNLOAD_STACK 0x0070
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t reserved[10];
+} PACKED t_PXENV_UNLOAD_STACK;
+
+
+#define PXENV_GET_CACHED_INFO 0x0071
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t PacketType; /* type (defined right here) */
+# define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
+# define PXENV_PACKET_TYPE_DHCP_ACK 2
+# define PXENV_PACKET_TYPE_BINL_REPLY 3
+ uint16_t BufferSize; /* max to copy, leave at 0 for pointer */
+ SEGOFF16_t Buffer; /* copy to, leave at 0 for pointer */
+ uint16_t BufferLimit; /* max size of buffer in BC dataseg ? */
+} PACKED t_PXENV_GET_CACHED_INFO;
+
+
+/* structure filled in by PXENV_GET_CACHED_INFO
+ * (how we determine which IP we downloaded the initial bootstrap from)
+ * words can't describe...
+ */
+typedef struct {
+ uint8_t opcode;
+# define BOOTP_REQ 1
+# define BOOTP_REP 2
+ uint8_t Hardware; /* hardware type */
+ uint8_t Hardlen; /* hardware addr len */
+ uint8_t Gatehops; /* zero it */
+ uint32_t ident; /* random number chosen by client */
+ uint16_t seconds; /* seconds since did initial bootstrap */
+ uint16_t Flags; /* seconds since did initial bootstrap */
+# define BOOTP_BCAST 0x8000 /* ? */
+ IP4_t cip; /* Client IP */
+ IP4_t yip; /* Your IP */
+ IP4_t sip; /* IP to use for next boot stage */
+ IP4_t gip; /* Relay IP ? */
+ MAC_ADDR CAddr; /* Client hardware address */
+ uint8_t Sname[64]; /* Server's hostname (Optional) */
+ uint8_t bootfile[128]; /* boot filename */
+ union {
+# if 1
+# define BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
+# else
+# define BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
+# endif
+ uint8_t d[BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */
+ struct {
+ uint8_t magic[4]; /* DHCP magic cookie */
+# ifndef VM_RFC1048
+# define VM_RFC1048 0x63825363L /* ? */
+# endif
+ uint32_t flags; /* bootp flags/opcodes */
+ uint8_t pad[56]; /* I don't think intel knows what a
+ union does... */
+ } v;
+ } vendor;
+} PACKED BOOTPLAYER;
+
+#define PXENV_RESTART_TFTP 0x0073
+#define t_PXENV_RESTART_TFTP t_PXENV_TFTP_READ_FILE
+
+#define PXENV_START_BASE 0x0075
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_START_BASE;
+
+#define PXENV_STOP_BASE 0x0076
+typedef struct {
+ PXENV_STATUS_t Status;
+} PACKED t_PXENV_STOP_BASE;
diff --git a/usr/src/boot/sys/boot/i386/libi386/pxetramp.s b/usr/src/boot/sys/boot/i386/libi386/pxetramp.s
new file mode 100644
index 0000000000..dcf1441aeb
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/pxetramp.s
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2000 Peter Wemm
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+# $FreeBSD$
+
+# ph33r this
+
+ .globl __bangpxeentry, __bangpxeseg, __bangpxeoff
+ .globl __pxenventry, __pxenvseg, __pxenvoff
+
+ .code16
+ .p2align 4,0x90
+__bangpxeentry:
+ push %dx # seg:data
+ push %ax # off:data
+ push %bx # int16 func
+ .byte 0x9a # far call
+__bangpxeoff: .word 0x0000 # offset
+__bangpxeseg: .word 0x0000 # segment
+ add $6, %sp # restore stack
+ .byte 0xcb # to vm86int
+#
+__pxenventry:
+ .byte 0x9a # far call
+__pxenvoff: .word 0x0000 # offset
+__pxenvseg: .word 0x0000 # segment
+ .byte 0xcb # to vm86int
diff --git a/usr/src/boot/sys/boot/i386/libi386/relocater_tramp.S b/usr/src/boot/sys/boot/i386/libi386/relocater_tramp.S
new file mode 100644
index 0000000000..ad36b60873
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/relocater_tramp.S
@@ -0,0 +1,345 @@
+/*
+ * 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 Toomas Soome <tsoome@me.com>
+ */
+
+/*
+ * Relocate is needed to support loading code which has to be located
+ * below 1MB, as both BTX and loader are using low memory area.
+ *
+ * Relocate and start loaded code. Since loaded code may need to be
+ * placed in an already occupied memory area, the code is moved to a safe
+ * memory area and then btx __exec will be called with physical pointer
+ * to this area. __exec will set the pointer to %eax and call *%eax,
+ * so that on entry, we have the new "base" address in %eax.
+ *
+ * Relocate will first set up and load new safe GDT to shut down BTX,
+ * then loaded code will be relocated to final memory location,
+ * then machine will be switched from 32-bit protected mode to 16-bit
+ * protected mode following by switch to real mode with A20 enabled or
+ * disabled. Finally the loaded code will be started and it will take
+ * over the whole system.
+ *
+ * For now, the known "safe" memory area for relocate is 0x600,
+ * the actual "free" memory is supposed to start from 0x500, leaving
+ * first 0x100 bytes in reserve. As relocate code+data is very small,
+ * it will leave enough space to set up boot blocks to 0:7c00 or load
+ * linux kernel below 1MB space.
+ */
+/*
+ * segment selectors
+ */
+ .set SEL_SCODE,0x8
+ .set SEL_SDATA,0x10
+ .set SEL_RCODE,0x18
+ .set SEL_RDATA,0x20
+
+ .p2align 4
+ .globl relocater
+relocater:
+ cli
+ /*
+ * set up GDT from new location
+ */
+ movl %eax, %esi /* our base address */
+ add $(relocater.1-relocater), %eax
+ jmp *%eax
+relocater.1:
+ /* set up jump */
+ lea (relocater.2-relocater)(%esi), %eax
+ movl %eax, (jump_vector-relocater) (%esi)
+
+ /* set up gdt */
+ lea (gdt-relocater) (%esi), %eax
+ movl %eax, (gdtaddr-relocater) (%esi)
+
+ /* load gdt */
+ lgdt (gdtdesc - relocater) (%esi)
+ lidt (idt-relocater) (%esi)
+
+ /* update cs */
+ ljmp *(jump_vector-relocater) (%esi)
+
+ .code32
+relocater.2:
+ xorl %eax, %eax
+ movb $SEL_SDATA, %al
+ movw %ax, %ss
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movl %cr0, %eax /* disable paging */
+ andl $~0x80000000,%eax
+ movl %eax, %cr0
+ xorl %ecx, %ecx /* flush TLB */
+ movl %ecx, %cr3
+ cld
+/*
+ * relocate data loop. load source, dest and size from
+ * relocater_data[i], 0 value will stop the loop.
+ * registers used for move: %esi, %edi, %ecx.
+ * %ebx to keep base
+ * %edx for relocater_data offset
+ */
+ movl %esi, %ebx /* base address */
+ xorl %edx, %edx
+loop.1:
+ movl (relocater_data-relocater)(%ebx, %edx, 4), %eax
+ testl %eax, %eax
+ jz loop.2
+ movl (relocater_data-relocater)(%ebx, %edx, 4), %esi
+ inc %edx
+ movl (relocater_data-relocater)(%ebx, %edx, 4), %edi
+ inc %edx
+ movl (relocater_data-relocater)(%ebx, %edx, 4), %ecx
+ inc %edx
+ rep
+ movsb
+ jmp loop.1
+loop.2:
+ movl %ebx, %esi /* restore esi */
+ /*
+ * data is relocated, switch to 16-bit mode
+ */
+ lea (relocater.3-relocater)(%esi), %eax
+ movl %eax, (jump_vector-relocater) (%esi)
+ movl $SEL_RCODE, %eax
+ movl %eax, (jump_vector-relocater+4) (%esi)
+
+ ljmp *(jump_vector-relocater) (%esi)
+relocater.3:
+ .code16
+
+ movw $SEL_RDATA, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+ lidt (idt-relocater) (%esi)
+ lea (relocater.4-relocater)(%esi), %eax
+ movl %eax, (jump_vector-relocater) (%esi)
+ xorl %eax, %eax
+ movl %eax, (jump_vector-relocater+4) (%esi)
+ /* clear PE */
+ movl %cr0, %eax
+ dec %al
+ movl %eax, %cr0
+ ljmp *(jump_vector-relocater) (%esi)
+relocater.4:
+ xorw %ax, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+ /*
+ * set real mode irq offsets
+ */
+ movw $0x7008,%bx
+ in $0x21,%al # Save master
+ push %ax # IMR
+ in $0xa1,%al # Save slave
+ push %ax # IMR
+ movb $0x11,%al # ICW1 to
+ outb %al,$0x20 # master,
+ outb %al,$0xa0 # slave
+ movb %bl,%al # ICW2 to
+ outb %al,$0x21 # master
+ movb %bh,%al # ICW2 to
+ outb %al,$0xa1 # slave
+ movb $0x4,%al # ICW3 to
+ outb %al,$0x21 # master
+ movb $0x2,%al # ICW3 to
+ outb %al,$0xa1 # slave
+ movb $0x1,%al # ICW4 to
+ outb %al,$0x21 # master,
+ outb %al,$0xa1 # slave
+ pop %ax # Restore slave
+ outb %al,$0xa1 # IMR
+ pop %ax # Restore master
+ outb %al,$0x21 # IMR
+ # done
+ /*
+ * Should A20 be left enabled?
+ */
+ /* movw imm16, %ax */
+ .byte 0xb8
+ .globl relocator_a20_enabled
+relocator_a20_enabled:
+ .word 0
+ test %ax, %ax
+ jnz a20_done
+
+ movw $0xa00, %ax
+ movw %ax, %sp
+ movw %ax, %bp
+
+ /* Disable A20 */
+ movw $0x2400, %ax
+ int $0x15
+# jnc a20_done
+
+ call a20_check_state
+ testb %al, %al
+ jz a20_done
+
+ inb $0x92
+ andb $(~0x03), %al
+ outb $0x92
+ jmp a20_done
+
+a20_check_state:
+ movw $100, %cx
+1:
+ xorw %ax, %ax
+ movw %ax, %ds
+ decw %ax
+ movw %ax, %es
+ xorw %ax, %ax
+ movw $0x8000, %ax
+ movw %ax, %si
+ addw $0x10, %ax
+ movw %ax, %di
+ movb %ds:(%si), %dl
+ movb %es:(%di), %al
+ movb %al, %dh
+ decb %dh
+ movb %dh, %ds:(%si)
+ outb %al, $0x80
+ outb %al, $0x80
+ movb %es:(%di), %dh
+ subb %dh, %al
+ xorb $1, %al
+ movb %dl, %ds:(%si)
+ testb %al, %al
+ jz a20_done
+ loop 1b
+ ret
+a20_done:
+ /*
+ * set up registers
+ */
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_ds
+relocator_ds: .word 0
+ movw %ax, %ds
+
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_es
+relocator_es: .word 0
+ movw %ax, %es
+
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_fs
+relocator_fs: .word 0
+ movw %ax, %fs
+
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_gs
+relocator_gs: .word 0
+ movw %ax, %gs
+
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_ss
+relocator_ss: .word 0
+ movw %ax, %ss
+
+ /* movw imm16, %ax. */
+ .byte 0xb8
+ .globl relocator_sp
+relocator_sp: .word 0
+ movzwl %ax, %esp
+
+ /* movw imm32, %eax. */
+ .byte 0x66, 0xb8
+ .globl relocator_esi
+relocator_esi: .long 0
+ movl %eax, %esi
+
+ /* movw imm32, %edx. */
+ .byte 0x66, 0xba
+ .globl relocator_edx
+relocator_edx: .long 0
+
+ /* movw imm32, %ebx. */
+ .byte 0x66, 0xbb
+ .globl relocator_ebx
+relocator_ebx: .long 0
+
+ /* movw imm32, %eax. */
+ .byte 0x66, 0xb8
+ .globl relocator_eax
+relocator_eax: .long 0
+
+ /* movw imm32, %ebp. */
+ .byte 0x66, 0xbd
+ .globl relocator_ebp
+relocator_ebp: .long 0
+
+ sti
+ .byte 0xea /* ljmp */
+ .globl relocator_ip
+relocator_ip:
+ .word 0
+ .globl relocator_cs
+relocator_cs:
+ .word 0
+
+/* GDT to reset BTX */
+ .code32
+ .p2align 4
+jump_vector: .long 0
+ .long SEL_SCODE
+
+gdt: .word 0x0, 0x0 /* null entry */
+ .byte 0x0, 0x0, 0x0, 0x0
+ .word 0xffff, 0x0 /* SEL_SCODE */
+ .byte 0x0, 0x9a, 0xcf, 0x0
+ .word 0xffff, 0x0 /* SEL_SDATA */
+ .byte 0x0, 0x92, 0xcf, 0x0
+ .word 0xffff, 0x0 /* SEL_RCODE */
+ .byte 0x0, 0x9a, 0x0f, 0x0
+ .word 0xffff, 0x0 /* SEL_RDATA */
+ .byte 0x0, 0x92, 0x0f, 0x0
+gdt.1:
+
+gdtdesc: .word gdt.1 - gdt - 1 /* limit */
+gdtaddr: .long 0 /* base */
+
+idt: .word 0x3ff
+ .long 0
+
+ .globl relocater_data
+
+/* reserve space for 3 entries */
+relocater_data:
+ .long 0 /* src */
+ .long 0 /* dest */
+ .long 0 /* size */
+ .long 0 /* src */
+ .long 0 /* dest */
+ .long 0 /* size */
+ .long 0 /* src */
+ .long 0 /* dest */
+ .long 0 /* size */
+ .long 0
+
+ .globl relocater_size
+relocater_size:
+ .long relocater_size-relocater
diff --git a/usr/src/boot/sys/boot/i386/libi386/smbios.c b/usr/src/boot/sys/boot/i386/libi386/smbios.c
new file mode 100644
index 0000000000..7a7ce4ba4f
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/smbios.c
@@ -0,0 +1,447 @@
+/*-
+ * Copyright (c) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <sys/endian.h>
+
+#ifdef EFI
+/* In EFI, we don't need PTOV(). */
+#define PTOV(x) (caddr_t)(x)
+#else
+#include "btxv86.h"
+#endif
+#include "smbios.h"
+
+/*
+ * Detect SMBIOS and export information about the SMBIOS into the
+ * environment.
+ *
+ * System Management BIOS Reference Specification, v2.6 Final
+ * http://www.dmtf.org/standards/published_documents/DSP0134_2.6.0.pdf
+ */
+
+/*
+ * 2.1.1 SMBIOS Structure Table Entry Point
+ *
+ * "On non-EFI systems, the SMBIOS Entry Point structure, described below, can
+ * be located by application software by searching for the anchor-string on
+ * paragraph (16-byte) boundaries within the physical memory address range
+ * 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor
+ * string that is used by some existing DMI browsers."
+ */
+#define SMBIOS_START 0xf0000
+#define SMBIOS_LENGTH 0x10000
+#define SMBIOS_STEP 0x10
+#define SMBIOS_SIG "_SM_"
+#define SMBIOS_DMI_SIG "_DMI_"
+
+#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off)))
+#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
+#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
+
+#define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01)
+#define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base))
+
+struct smbios_attr {
+ int probed;
+ caddr_t addr;
+ size_t length;
+ size_t count;
+ int major;
+ int minor;
+ int ver;
+ const char* bios_vendor;
+ const char* maker;
+ const char* product;
+ uint32_t enabled_memory;
+ uint32_t old_enabled_memory;
+ uint8_t enabled_sockets;
+ uint8_t populated_sockets;
+};
+
+static struct smbios_attr smbios;
+
+static uint8_t
+smbios_checksum(const caddr_t addr, const uint8_t len)
+{
+ uint8_t sum;
+ int i;
+
+ for (sum = 0, i = 0; i < len; i++)
+ sum += SMBIOS_GET8(addr, i);
+ return (sum);
+}
+
+static caddr_t
+smbios_sigsearch(const caddr_t addr, const uint32_t len)
+{
+ caddr_t cp;
+
+ /* Search on 16-byte boundaries. */
+ for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
+ if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
+ smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
+ strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 &&
+ smbios_checksum(cp + 0x10, 0x0f) == 0)
+ return (cp);
+ return (NULL);
+}
+
+static const char*
+smbios_getstring(caddr_t addr, const int offset)
+{
+ caddr_t cp;
+ int i, idx;
+
+ idx = SMBIOS_GET8(addr, offset);
+ if (idx != 0) {
+ cp = SMBIOS_GETSTR(addr);
+ for (i = 1; i < idx; i++)
+ cp += strlen(cp) + 1;
+ return cp;
+ }
+ return (NULL);
+}
+
+static void
+smbios_setenv(const char *name, caddr_t addr, const int offset)
+{
+ const char* val;
+
+ val = smbios_getstring(addr, offset);
+ if (val != NULL)
+ setenv(name, val, 1);
+}
+
+#ifdef SMBIOS_SERIAL_NUMBERS
+
+#define UUID_SIZE 16
+#define UUID_TYPE uint32_t
+#define UUID_STEP sizeof(UUID_TYPE)
+#define UUID_ALL_BITS (UUID_SIZE / UUID_STEP)
+#define UUID_GET(base, off) (*(UUID_TYPE *)((base) + (off)))
+
+static void
+smbios_setuuid(const char *name, const caddr_t addr, const int ver)
+{
+ char uuid[37];
+ int byteorder, i, ones, zeros;
+ UUID_TYPE n;
+ uint32_t f1;
+ uint16_t f2, f3;
+
+ for (i = 0, ones = 0, zeros = 0; i < UUID_SIZE; i += UUID_STEP) {
+ n = UUID_GET(addr, i) + 1;
+ if (zeros == 0 && n == 0)
+ ones++;
+ else if (ones == 0 && n == 1)
+ zeros++;
+ else
+ break;
+ }
+
+ if (ones != UUID_ALL_BITS && zeros != UUID_ALL_BITS) {
+ /*
+ * 3.3.2.1 System UUID
+ *
+ * "Although RFC 4122 recommends network byte order for all
+ * fields, the PC industry (including the ACPI, UEFI, and
+ * Microsoft specifications) has consistently used
+ * little-endian byte encoding for the first three fields:
+ * time_low, time_mid, time_hi_and_version. The same encoding,
+ * also known as wire format, should also be used for the
+ * SMBIOS representation of the UUID."
+ *
+ * Note: We use network byte order for backward compatibility
+ * unless SMBIOS version is 2.6+ or little-endian is forced.
+ */
+#if defined(SMBIOS_LITTLE_ENDIAN_UUID)
+ byteorder = LITTLE_ENDIAN;
+#elif defined(SMBIOS_NETWORK_ENDIAN_UUID)
+ byteorder = BIG_ENDIAN;
+#else
+ byteorder = ver < 0x0206 ? BIG_ENDIAN : LITTLE_ENDIAN;
+#endif
+ if (byteorder != LITTLE_ENDIAN) {
+ f1 = ntohl(SMBIOS_GET32(addr, 0));
+ f2 = ntohs(SMBIOS_GET16(addr, 4));
+ f3 = ntohs(SMBIOS_GET16(addr, 6));
+ } else {
+ f1 = le32toh(SMBIOS_GET32(addr, 0));
+ f2 = le16toh(SMBIOS_GET16(addr, 4));
+ f3 = le16toh(SMBIOS_GET16(addr, 6));
+ }
+ sprintf(uuid,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ f1, f2, f3, SMBIOS_GET8(addr, 8), SMBIOS_GET8(addr, 9),
+ SMBIOS_GET8(addr, 10), SMBIOS_GET8(addr, 11),
+ SMBIOS_GET8(addr, 12), SMBIOS_GET8(addr, 13),
+ SMBIOS_GET8(addr, 14), SMBIOS_GET8(addr, 15));
+ setenv(name, uuid, 1);
+ }
+}
+
+#undef UUID_SIZE
+#undef UUID_TYPE
+#undef UUID_STEP
+#undef UUID_ALL_BITS
+#undef UUID_GET
+
+#endif
+
+static caddr_t
+smbios_parse_table(const caddr_t addr)
+{
+ caddr_t cp;
+ int proc, size, osize, type;
+
+ type = SMBIOS_GET8(addr, 0); /* 3.1.2 Structure Header Format */
+ switch(type) {
+ case 0: /* 3.3.1 BIOS Information (Type 0) */
+ smbios_setenv("smbios.bios.vendor", addr, 0x04);
+ smbios_setenv("smbios.bios.version", addr, 0x05);
+ smbios_setenv("smbios.bios.reldate", addr, 0x08);
+ break;
+
+ case 1: /* 3.3.2 System Information (Type 1) */
+ smbios_setenv("smbios.system.maker", addr, 0x04);
+ smbios_setenv("smbios.system.product", addr, 0x05);
+ smbios_setenv("smbios.system.version", addr, 0x06);
+#ifdef SMBIOS_SERIAL_NUMBERS
+ smbios_setenv("smbios.system.serial", addr, 0x07);
+ smbios_setuuid("smbios.system.uuid", addr + 0x08, smbios.ver);
+#endif
+ break;
+
+ case 2: /* 3.3.3 Base Board (or Module) Information (Type 2) */
+ smbios_setenv("smbios.planar.maker", addr, 0x04);
+ smbios_setenv("smbios.planar.product", addr, 0x05);
+ smbios_setenv("smbios.planar.version", addr, 0x06);
+#ifdef SMBIOS_SERIAL_NUMBERS
+ smbios_setenv("smbios.planar.serial", addr, 0x07);
+#endif
+ break;
+
+ case 3: /* 3.3.4 System Enclosure or Chassis (Type 3) */
+ smbios_setenv("smbios.chassis.maker", addr, 0x04);
+ smbios_setenv("smbios.chassis.version", addr, 0x06);
+#ifdef SMBIOS_SERIAL_NUMBERS
+ smbios_setenv("smbios.chassis.serial", addr, 0x07);
+ smbios_setenv("smbios.chassis.tag", addr, 0x08);
+#endif
+ break;
+
+ case 4: /* 3.3.5 Processor Information (Type 4) */
+ /*
+ * Offset 18h: Processor Status
+ *
+ * Bit 7 Reserved, must be 0
+ * Bit 6 CPU Socket Populated
+ * 1 - CPU Socket Populated
+ * 0 - CPU Socket Unpopulated
+ * Bit 5:3 Reserved, must be zero
+ * Bit 2:0 CPU Status
+ * 0h - Unknown
+ * 1h - CPU Enabled
+ * 2h - CPU Disabled by User via BIOS Setup
+ * 3h - CPU Disabled by BIOS (POST Error)
+ * 4h - CPU is Idle, waiting to be enabled
+ * 5-6h - Reserved
+ * 7h - Other
+ */
+ proc = SMBIOS_GET8(addr, 0x18);
+ if ((proc & 0x07) == 1)
+ smbios.enabled_sockets++;
+ if ((proc & 0x40) != 0)
+ smbios.populated_sockets++;
+ break;
+
+ case 6: /* 3.3.7 Memory Module Information (Type 6, Obsolete) */
+ /*
+ * Offset 0Ah: Enabled Size
+ *
+ * Bit 7 Bank connection
+ * 1 - Double-bank connection
+ * 0 - Single-bank connection
+ * Bit 6:0 Size (n), where 2**n is the size in MB
+ * 7Dh - Not determinable (Installed Size only)
+ * 7Eh - Module is installed, but no memory
+ * has been enabled
+ * 7Fh - Not installed
+ */
+ osize = SMBIOS_GET8(addr, 0x0a) & 0x7f;
+ if (osize > 0 && osize < 22)
+ smbios.old_enabled_memory += 1 << (osize + 10);
+ break;
+
+ case 17: /* 3.3.18 Memory Device (Type 17) */
+ /*
+ * Offset 0Ch: Size
+ *
+ * Bit 15 Granularity
+ * 1 - Value is in kilobytes units
+ * 0 - Value is in megabytes units
+ * Bit 14:0 Size
+ */
+ size = SMBIOS_GET16(addr, 0x0c);
+ if (size != 0 && size != 0xffff)
+ smbios.enabled_memory += (size & 0x8000) != 0 ?
+ (size & 0x7fff) : (size << 10);
+ break;
+
+ default: /* skip other types */
+ break;
+ }
+
+ /* Find structure terminator. */
+ cp = SMBIOS_GETSTR(addr);
+ while (SMBIOS_GET16(cp, 0) != 0)
+ cp++;
+
+ return (cp + 2);
+}
+
+static caddr_t
+smbios_find_struct(int type)
+{
+ caddr_t dmi;
+ size_t i;
+
+ if (smbios.addr == NULL)
+ return (NULL);
+
+ for (dmi = smbios.addr, i = 0;
+ dmi < smbios.addr + smbios.length && i < smbios.count; i++) {
+ if (SMBIOS_GET8(dmi, 0) == type)
+ return dmi;
+ /* Find structure terminator. */
+ dmi = SMBIOS_GETSTR(dmi);
+ while (SMBIOS_GET16(dmi, 0) != 0)
+ dmi++;
+ dmi += 2;
+ }
+
+ return (NULL);
+}
+
+static void
+smbios_probe(const caddr_t addr)
+{
+ caddr_t saddr, info;
+ uintptr_t paddr;
+
+ if (smbios.probed)
+ return;
+ smbios.probed = 1;
+
+ /* Search signatures and validate checksums. */
+ saddr = smbios_sigsearch(addr ? addr : PTOV(SMBIOS_START),
+ SMBIOS_LENGTH);
+ if (saddr == NULL)
+ return;
+
+ smbios.length = SMBIOS_GET16(saddr, 0x16); /* Structure Table Length */
+ paddr = SMBIOS_GET32(saddr, 0x18); /* Structure Table Address */
+ smbios.count = SMBIOS_GET16(saddr, 0x1c); /* No of SMBIOS Structures */
+ smbios.ver = SMBIOS_GET8(saddr, 0x1e); /* SMBIOS BCD Revision */
+
+ if (smbios.ver != 0) {
+ smbios.major = smbios.ver >> 4;
+ smbios.minor = smbios.ver & 0x0f;
+ if (smbios.major > 9 || smbios.minor > 9)
+ smbios.ver = 0;
+ }
+ if (smbios.ver == 0) {
+ smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version */
+ smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version */
+ }
+ smbios.ver = (smbios.major << 8) | smbios.minor;
+ smbios.addr = PTOV(paddr);
+
+ /* Get system information from SMBIOS */
+ info = smbios_find_struct(0x00);
+ if (info != NULL) {
+ smbios.bios_vendor = smbios_getstring(info, 0x04);
+ }
+ info = smbios_find_struct(0x01);
+ if (info != NULL) {
+ smbios.maker = smbios_getstring(info, 0x04);
+ smbios.product = smbios_getstring(info, 0x05);
+ }
+}
+
+void
+smbios_detect(const caddr_t addr)
+{
+ char buf[16];
+ caddr_t dmi;
+ size_t i;
+
+ smbios_probe(addr);
+ if (smbios.addr == NULL)
+ return;
+
+ for (dmi = smbios.addr, i = 0;
+ dmi < smbios.addr + smbios.length && i < smbios.count; i++)
+ dmi = smbios_parse_table(dmi);
+
+ sprintf(buf, "%d.%d", smbios.major, smbios.minor);
+ setenv("smbios.version", buf, 1);
+ if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) {
+ sprintf(buf, "%u", smbios.enabled_memory > 0 ?
+ smbios.enabled_memory : smbios.old_enabled_memory);
+ setenv("smbios.memory.enabled", buf, 1);
+ }
+ if (smbios.enabled_sockets > 0) {
+ sprintf(buf, "%u", smbios.enabled_sockets);
+ setenv("smbios.socket.enabled", buf, 1);
+ }
+ if (smbios.populated_sockets > 0) {
+ sprintf(buf, "%u", smbios.populated_sockets);
+ setenv("smbios.socket.populated", buf, 1);
+ }
+}
+
+static int
+smbios_match_str(const char* s1, const char* s2)
+{
+ return (s1 == NULL || (s2 != NULL && !strcmp(s1, s2)));
+}
+
+int
+smbios_match(const char* bios_vendor, const char* maker,
+ const char* product)
+{
+ /* XXXRP currently, only called from non-EFI. */
+ smbios_probe(NULL);
+ return (smbios_match_str(bios_vendor, smbios.bios_vendor) &&
+ smbios_match_str(maker, smbios.maker) &&
+ smbios_match_str(product, smbios.product));
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/smbios.h b/usr/src/boot/sys/boot/i386/libi386/smbios.h
new file mode 100644
index 0000000000..03fc07e293
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/smbios.h
@@ -0,0 +1,34 @@
+/*-
+ * Copyright (c) 2015 Rui Paulo <rpaulo@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _SMBIOS_H_
+#define _SMBIOS_H_
+
+void smbios_detect(const caddr_t);
+int smbios_match(const char *, const char *, const char *);
+
+#endif /* _SMBIOS_H_ */
diff --git a/usr/src/boot/sys/boot/i386/libi386/spinconsole.c b/usr/src/boot/sys/boot/i386/libi386/spinconsole.c
new file mode 100644
index 0000000000..762b88abd1
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/spinconsole.c
@@ -0,0 +1,120 @@
+/*-
+ * spinconsole.c
+ *
+ * Author: Maksym Sobolyev <sobomax@sippysoft.com>
+ * Copyright (c) 2009 Sippy Software, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+
+extern void get_pos(int *x, int *y);
+extern void curs_move(int *_x, int *_y, int x, int y);
+#if defined(EFI)
+extern void efi_cons_efiputchar(int c);
+#else
+extern void vidc_biosputchar(int c);
+#endif
+
+static void spinc_probe(struct console *cp);
+static int spinc_init(struct console *cp, int arg);
+static void spinc_putchar(struct console *cp, int c);
+static int spinc_getchar(struct console *cp);
+static int spinc_ischar(struct console *cp);
+
+struct console spinconsole = {
+ "spin",
+ "spin port",
+ 0,
+ spinc_probe,
+ spinc_init,
+ spinc_putchar,
+ spinc_getchar,
+ spinc_ischar,
+ NULL
+};
+
+static void
+spinc_probe(struct console *cp)
+{
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+}
+
+static int
+spinc_init(struct console *cp __attribute((unused)),
+ int arg __attribute((unused)))
+{
+ return(0);
+}
+
+static void
+spinc_putchar(struct console *cp __attribute((unused)),
+ int c __attribute((unused)))
+{
+#ifdef TERM_EMU
+ static int curx, cury;
+#endif
+ static unsigned tw_chars = 0x5C2D2F7C; /* "\-/|" */
+ static time_t lasttime;
+ time_t now;
+
+ now = time(NULL);
+ if (now < (lasttime + 1))
+ return;
+ lasttime = now;
+#ifdef TERM_EMU
+ get_pos(&curx, &cury);
+ if (curx > 0)
+ curs_move(&curx, &cury, curx - 1, cury);
+#endif
+#if defined(EFI)
+ efi_cons_efiputchar((char)tw_chars);
+#else
+ vidc_biosputchar((char)tw_chars);
+#endif
+ tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24);
+}
+
+static int
+spinc_getchar(struct console *cp __attribute((unused)))
+{
+ return(-1);
+}
+
+static int
+spinc_ischar(struct console *cp __attribute((unused)))
+{
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/time.c b/usr/src/boot/sys/boot/i386/libi386/time.c
new file mode 100644
index 0000000000..c27dcf6b5d
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/time.c
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <btxv86.h>
+#include "bootstrap.h"
+#include "libi386.h"
+
+static int bios_seconds(void);
+
+/*
+ * Return the BIOS time-of-day value.
+ *
+ * XXX uses undocumented BCD support from libstand.
+ */
+static int
+bios_seconds(void)
+{
+ int hr, minute, sec;
+
+ v86.ctl = 0;
+ v86.addr = 0x1a; /* int 0x1a, function 2 */
+ v86.eax = 0x0200;
+ v86int();
+
+ hr = bcd2bin((v86.ecx & 0xff00) >> 8); /* hour in %ch */
+ minute = bcd2bin(v86.ecx & 0xff); /* minute in %cl */
+ sec = bcd2bin((v86.edx & 0xff00) >> 8); /* second in %dh */
+
+ return (hr * 3600 + minute * 60 + sec);
+}
+
+/*
+ * Return the time in seconds since the beginning of the day.
+ *
+ * Some BIOSes (notably qemu) don't correctly read the RTC
+ * registers in an atomic way, sometimes returning bogus values.
+ * Therefore we "debounce" the reading by accepting it only when
+ * we got 8 identical values in succession.
+ *
+ * If we pass midnight, don't wrap back to 0.
+ */
+time_t
+time(time_t *t)
+{
+ static time_t lasttime;
+ time_t now, check;
+ int same, try;
+
+ same = try = 0;
+ check = bios_seconds();
+ do {
+ now = check;
+ check = bios_seconds();
+ if (check != now)
+ same = 0;
+ } while (++same < 8 && ++try < 1000);
+
+ if (now < lasttime)
+ now += 24 * 3600;
+ lasttime = now;
+
+ if (t != NULL)
+ *t = now;
+ return(now);
+}
+
+/*
+ * Use the BIOS Wait function to pause for (period) microseconds.
+ *
+ * Resolution of this function is variable, but typically around
+ * 1ms.
+ */
+void
+delay(int period)
+{
+ v86.ctl = 0;
+ v86.addr = 0x15; /* int 0x15, function 0x86 */
+ v86.eax = 0x8600;
+ v86.ecx = period >> 16;
+ v86.edx = period & 0xffff;
+ v86int();
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
new file mode 100644
index 0000000000..edefda223c
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
@@ -0,0 +1,759 @@
+/*-
+ * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
+ * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
+ */
+
+#include <sys/cdefs.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <btxv86.h>
+#include <machine/psl.h>
+#include "libi386.h"
+
+#if KEYBOARD_PROBE
+#include <machine/cpufunc.h>
+
+static int probe_keyboard(void);
+#endif
+static void vidc_probe(struct console *cp);
+static int vidc_init(struct console *cp, int arg);
+static void vidc_putchar(struct console *cp, int c);
+static int vidc_getchar(struct console *cp);
+static int vidc_ischar(struct console *cp);
+
+static int vidc_started;
+
+#ifdef TERM_EMU
+#define MAXARGS 8
+#define KEYBUFSZ 10
+#define DEFAULT_FGCOLOR 7
+#define DEFAULT_BGCOLOR 0
+
+void end_term(void);
+void bail_out(int c);
+void vidc_term_emu(int c);
+void get_pos(int *x, int *y);
+void curs_move(int *_x, int *_y, int x, int y);
+void write_char(int c, int fg, int bg);
+void scroll_up(int rows, int fg, int bg);
+void CD(void);
+void CM(void);
+void HO(void);
+
+static unsigned keybuf[KEYBUFSZ]; /* keybuf for extended codes */
+static int args[MAXARGS], argc;
+static int fg_c, bg_c, curx, cury;
+static int esc;
+#endif
+
+
+struct console text = {
+ "text",
+ "internal video/keyboard",
+ 0,
+ vidc_probe,
+ vidc_init,
+ vidc_putchar,
+ vidc_getchar,
+ vidc_ischar,
+ NULL
+};
+
+static void
+vidc_probe(struct console *cp)
+{
+
+ /* look for a keyboard */
+#if KEYBOARD_PROBE
+ if (probe_keyboard())
+#endif
+ {
+
+ cp->c_flags |= C_PRESENTIN;
+ }
+
+ /* XXX for now, always assume we can do BIOS screen output */
+ cp->c_flags |= C_PRESENTOUT;
+}
+
+static int
+vidc_init(struct console *cp, int arg)
+{
+ int i;
+
+ if (vidc_started && arg == 0)
+ return (0);
+ vidc_started = 1;
+#ifdef TERM_EMU
+ /* Init terminal emulator */
+ end_term();
+ get_pos(&curx, &cury);
+ curs_move(&curx, &cury, curx, cury);
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ memset(keybuf, 0, KEYBUFSZ);
+#endif
+ for (i = 0; i < 10 && vidc_ischar(cp); i++)
+ (void)vidc_getchar(cp);
+ return (0); /* XXX reinit? */
+}
+
+void
+vidc_biosputchar(int c)
+{
+
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0xe00 | (c & 0xff);
+ v86.ebx = 0x7;
+ v86int();
+}
+
+static void
+vidc_rawputchar(int c)
+{
+ int i;
+
+ if (c == '\t')
+ /* lame tab expansion */
+ for (i = 0; i < 8; i++)
+ vidc_rawputchar(' ');
+ else {
+#ifndef TERM_EMU
+ vidc_biosputchar(c);
+#else
+ /* Emulate AH=0eh (teletype output) */
+ switch(c) {
+ case '\a':
+ vidc_biosputchar(c);
+ return;
+ case '\r':
+ curx = 0;
+ break;
+ case '\n':
+ cury++;
+ if ((text.c_flags & C_MODERAW) == 0)
+ curx = 0;
+
+ if (cury > 24) {
+ scroll_up(1, fg_c, bg_c);
+ cury--;
+ }
+ break;
+ case '\b':
+ if (curx > 0)
+ curx--;
+ break;
+ default:
+ if (curx > 79) {
+ curx = 0;
+ cury++;
+ curs_move(&curx, &cury, curx, cury);
+ }
+ if ((text.c_flags & C_MODERAW) == 0) {
+ if (cury > 24) {
+ curx = 0;
+ scroll_up(1, fg_c, bg_c);
+ cury--;
+ curs_move(&curx, &cury, curx, cury);
+ }
+ }
+ write_char(c, fg_c, bg_c);
+ curx++;
+ if (text.c_flags & C_MODERAW) {
+ if (curx > 79) {
+ curx = 0;
+ if (cury == 25)
+ scroll_up(1, fg_c, bg_c);
+ else
+ cury++;
+ }
+ }
+ }
+ curs_move(&curx, &cury, curx, cury);
+#endif
+ }
+}
+
+#ifdef TERM_EMU
+
+/* Get cursor position on the screen. Result is in edx. Sets
+ * curx and cury appropriately.
+ */
+void
+get_pos(int *x, int *y)
+{
+
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0300;
+ v86.ebx = 0x0;
+ v86int();
+ *x = v86.edx & 0x00ff;
+ *y = (v86.edx & 0xff00) >> 8;
+}
+
+/* Move cursor to x rows and y cols (0-based). */
+void
+curs_move(int *_x, int *_y, int x, int y)
+{
+
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0200;
+ v86.ebx = 0x0;
+ v86.edx = ((0x00ff & y) << 8) + (0x00ff & x);
+ v86int();
+ if (_x != NULL)
+ *_x = x;
+ if (_y != NULL)
+ *_y = y;
+ /* If there is ctrl char at this position, cursor would be invisible.
+ * Make it a space instead.
+ */
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0800;
+ v86.ebx = 0x0;
+ v86int();
+#define isvisible(c) (((c) >= 32) && ((c) < 255))
+ if (!isvisible(v86.eax & 0x00ff)) {
+ write_char(' ', fg_c, bg_c);
+ }
+ v86.ctl = 0; /* show normal underline cursor */
+ v86.addr = 0x10;
+ v86.eax = 0x0100;
+ v86.ecx = 0x0607;
+ v86int();
+}
+
+/* Scroll up the whole window by a number of rows. If rows==0,
+ * clear the window. fg and bg are attributes for the new lines
+ * inserted in the window.
+ */
+void
+scroll_up(int rows, int fgcol, int bgcol)
+{
+ if (rows == 0)
+ rows = 25;
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0600 + (0x00ff & rows);
+ v86.ebx = (bgcol << 12) + (fgcol << 8);
+ v86.ecx = 0x0;
+ v86.edx = 0x184f;
+ v86int();
+}
+
+/* Write character and attribute at cursor position. */
+void
+write_char(int c, int fgcol, int bgcol)
+{
+
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0900 + (0x00ff & c);
+ v86.ebx = (bgcol << 4) + fgcol;
+ v86.ecx = 0x1;
+ v86int();
+}
+
+/**************************************************************/
+/*
+ * Screen manipulation functions. They use accumulated data in
+ * args[] and argc variables.
+ *
+ */
+
+/* Clear line from current position to end of line */
+void
+CL(int direction)
+{
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0600;
+ v86.ebx = (bg_c << 12) + (fg_c << 8);
+ if (direction == 0) { /* from cursor to end */
+ v86.ecx = (cury << 8) + curx;
+ v86.edx = (cury << 8) + 79;
+ } else if (direction == 1) { /* from beginning to cursor */
+ v86.ecx = (cury << 8) + 0;
+ v86.edx = (cury << 8) + curx;
+ } else if (direction == 2) { /* entire line */
+ v86.ecx = (cury << 8) + 0;
+ v86.edx = (cury << 8) + 79;
+ }
+ v86int();
+ end_term();
+ return;
+}
+
+/* Clear display from current position to end of screen */
+void
+CD(void)
+{
+
+ get_pos(&curx, &cury);
+ if (curx > 0) {
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0600;
+ v86.ebx = (bg_c << 12) + (fg_c << 8);
+ v86.ecx = (cury << 8) + curx;
+ v86.edx = (cury << 8) + 79;
+ v86int();
+ if (++cury > 24) {
+ end_term();
+ return;
+ }
+ }
+ v86.ctl = 0;
+ v86.addr = 0x10;
+ v86.eax = 0x0600;
+ v86.ebx = (bg_c << 12) + (fg_c << 8);
+ v86.ecx = (cury << 8) + 0;
+ v86.edx = (24 << 8) + 79;
+ v86int();
+ end_term();
+}
+
+/* Absolute cursor move to args[0] rows and args[1] columns
+ * (the coordinates are 1-based).
+ */
+void
+CM(void)
+{
+
+ if (args[0] > 0)
+ args[0]--;
+ if (args[1] > 0)
+ args[1]--;
+ curs_move(&curx, &cury, args[1], args[0]);
+ end_term();
+}
+
+/* Home cursor (left top corner) */
+void
+HO(void)
+{
+
+ argc = 1;
+ args[0] = args[1] = 1;
+ CM();
+}
+
+/* Clear internal state of the terminal emulation code */
+void
+end_term(void)
+{
+
+ esc = 0;
+ argc = -1;
+}
+
+/* Gracefully exit ESC-sequence processing in case of misunderstanding */
+void
+bail_out(int c)
+{
+ char buf[16], *ch;
+ int i;
+
+ if (esc) {
+ vidc_rawputchar('\033');
+ if (esc != '\033')
+ vidc_rawputchar(esc);
+ for (i = 0; i <= argc; ++i) {
+ sprintf(buf, "%d", args[i]);
+ ch = buf;
+ while (*ch)
+ vidc_rawputchar(*ch++);
+ }
+ }
+ vidc_rawputchar(c);
+ end_term();
+}
+
+static void
+get_arg(int c)
+{
+
+ if (argc < 0)
+ argc = 0;
+ args[argc] *= 10;
+ args[argc] += c - '0';
+}
+
+/* Emulate basic capabilities of sun-color terminal */
+void
+vidc_term_emu(int c)
+{
+ static int ansi_col[] = {
+ 0, 4, 2, 6, 1, 5, 3, 7,
+ };
+ int t;
+ int i;
+
+ switch (esc) {
+ case 0:
+ switch (c) {
+ case '\033':
+ esc = c;
+ break;
+ default:
+ vidc_rawputchar(c);
+ break;
+ }
+ break;
+
+ case '\033':
+ switch (c) {
+ case '[':
+ esc = c;
+ args[0] = 0;
+ argc = -1;
+ break;
+ default:
+ bail_out(c);
+ break;
+ }
+ break;
+
+ case '[':
+ switch (c) {
+ case ';':
+ if (argc < 0) /* XXX */
+ argc = 0;
+ else if (argc + 1 >= MAXARGS)
+ bail_out(c);
+ else
+ args[++argc] = 0;
+ break;
+ case 'A': /* UP = \E[%dA */
+ if (argc == 0) {
+ int x, y;
+ get_pos(&x, &y);
+ args[1] = x + 1;
+ args[0] = y - args[0] + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'B': /* DO = \E[%dB */
+ if (argc == 0) {
+ int x, y;
+ get_pos(&x, &y);
+ args[1] = x + 1;
+ args[0] = y + args[0] + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'C': /* RI = \E[%dC */
+ if (argc == 0) {
+ int x, y;
+ get_pos(&x, &y);
+ args[1] = args[0] + 1;
+ args[0] = y + 1;
+ CM();
+ } else
+ bail_out(c);
+ break;
+ case 'H': /* ho = \E[H */
+ if (argc < 0)
+ HO();
+ else if (argc == 1)
+ CM();
+ else
+ bail_out(c);
+ break;
+ case 'J': /* cd = \E[J */
+ if (argc < 0)
+ CD();
+ else
+ bail_out(c);
+ break;
+ case 'K':
+ if (argc < 0)
+ CL(0);
+ else if (argc == 0)
+ switch (args[0]) {
+ case 0:
+ case 1:
+ case 2:
+ CL(args[0]);
+ break;
+ default:
+ bail_out(c);
+ }
+ else
+ bail_out(c);
+ break;
+ case 'm':
+ if (argc < 0) {
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ }
+ for (i = 0; i <= argc; ++i) {
+ switch (args[i]) {
+ case 0: /* back to normal */
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ case 1: /* bold */
+ fg_c |= 0x8;
+ break;
+ case 4: /* underline */
+ case 5: /* blink */
+ bg_c |= 0x8;
+ break;
+ case 7: /* reverse */
+ t = fg_c;
+ fg_c = bg_c;
+ bg_c = t;
+ break;
+ case 30: case 31: case 32: case 33:
+ case 34: case 35: case 36: case 37:
+ fg_c = ansi_col[args[i] - 30];
+ break;
+ case 39: /* normal */
+ fg_c = DEFAULT_FGCOLOR;
+ break;
+ case 40: case 41: case 42: case 43:
+ case 44: case 45: case 46: case 47:
+ bg_c = ansi_col[args[i] - 40];
+ break;
+ case 49: /* normal */
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ }
+ }
+ end_term();
+ break;
+ default:
+ if (isdigit(c))
+ get_arg(c);
+ else
+ bail_out(c);
+ break;
+ }
+ break;
+
+ default:
+ bail_out(c);
+ break;
+ }
+}
+#endif
+
+static void
+vidc_putchar(struct console *cp, int c)
+{
+#ifdef TERM_EMU
+ vidc_term_emu(c);
+#else
+ vidc_rawputchar(c);
+#endif
+}
+
+static int
+vidc_getchar(struct console *cp)
+{
+ int i, c;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0) {
+ c = keybuf[i];
+ keybuf[i] = 0;
+ return (c);
+ }
+ }
+
+ if (vidc_ischar(cp)) {
+ v86.ctl = 0;
+ v86.addr = 0x16;
+ v86.eax = 0x0;
+ v86int();
+ if ((v86.eax & 0xff) != 0) {
+ return (v86.eax & 0xff);
+ }
+
+ /* extended keys */
+ switch (v86.eax & 0xff00) {
+ case 0x4800: /* up */
+ keybuf[0] = '[';
+ keybuf[1] = 'A';
+ return (0x1b); /* esc */
+ case 0x4b00: /* left */
+ keybuf[0] = '[';
+ keybuf[1] = 'D';
+ return (0x1b); /* esc */
+ case 0x4d00: /* right */
+ keybuf[0] = '[';
+ keybuf[1] = 'C';
+ return (0x1b); /* esc */
+ case 0x5000: /* down */
+ keybuf[0] = '[';
+ keybuf[1] = 'B';
+ return (0x1b); /* esc */
+ default:
+ return (-1);
+ }
+ } else {
+ return (-1);
+ }
+}
+
+static int
+vidc_ischar(struct console *cp)
+{
+ int i;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0) {
+ return (1);
+ }
+ }
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x16;
+ v86.eax = 0x100;
+ v86int();
+ return (!V86_ZR(v86.efl));
+}
+
+#if KEYBOARD_PROBE
+
+#define PROBE_MAXRETRY 5
+#define PROBE_MAXWAIT 400
+#define IO_DUMMY 0x84
+#define IO_KBD 0x060 /* 8042 Keyboard */
+
+/* selected defines from kbdio.h */
+#define KBD_STATUS_PORT 4 /* status port, read */
+#define KBD_DATA_PORT 0 /* data port, read/write
+ * also used as keyboard command
+ * and mouse command port
+ */
+#define KBDC_ECHO 0x00ee
+#define KBDS_ANY_BUFFER_FULL 0x0001
+#define KBDS_INPUT_BUFFER_FULL 0x0002
+#define KBD_ECHO 0x00ee
+
+/* 7 microsec delay necessary for some keyboard controllers */
+static void
+delay7(void)
+{
+ /*
+ * I know this is broken, but no timer is available yet at this stage...
+ * See also comments in `delay1ms()'.
+ */
+ inb(IO_DUMMY); inb(IO_DUMMY);
+ inb(IO_DUMMY); inb(IO_DUMMY);
+ inb(IO_DUMMY); inb(IO_DUMMY);
+}
+
+/*
+ * This routine uses an inb to an unused port, the time to execute that
+ * inb is approximately 1.25uS. This value is pretty constant across
+ * all CPU's and all buses, with the exception of some PCI implentations
+ * that do not forward this I/O address to the ISA bus as they know it
+ * is not a valid ISA bus address, those machines execute this inb in
+ * 60 nS :-(.
+ *
+ */
+static void
+delay1ms(void)
+{
+ int i = 800;
+ while (--i >= 0)
+ (void)inb(0x84);
+}
+
+/*
+ * We use the presence/absence of a keyboard to determine whether the internal
+ * console can be used for input.
+ *
+ * Perform a simple test on the keyboard; issue the ECHO command and see
+ * if the right answer is returned. We don't do anything as drastic as
+ * full keyboard reset; it will be too troublesome and take too much time.
+ */
+static int
+probe_keyboard(void)
+{
+ int retry = PROBE_MAXRETRY;
+ int wait;
+ int i;
+
+ while (--retry >= 0) {
+ /* flush any noise */
+ while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ delay7();
+ inb(IO_KBD + KBD_DATA_PORT);
+ delay1ms();
+ }
+
+ /* wait until the controller can accept a command */
+ for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
+ if (((i = inb(IO_KBD + KBD_STATUS_PORT))
+ & (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
+ break;
+ if (i & KBDS_ANY_BUFFER_FULL) {
+ delay7();
+ inb(IO_KBD + KBD_DATA_PORT);
+ }
+ delay1ms();
+ }
+ if (wait <= 0)
+ continue;
+
+ /* send the ECHO command */
+ outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
+
+ /* wait for a response */
+ for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
+ if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
+ break;
+ delay1ms();
+ }
+ if (wait <= 0)
+ continue;
+
+ delay7();
+ i = inb(IO_KBD + KBD_DATA_PORT);
+#ifdef PROBE_KBD_BEBUG
+ printf("probe_keyboard: got 0x%x.\n", i);
+#endif
+ if (i == KBD_ECHO) {
+ /* got the right answer */
+ return (1);
+ }
+ }
+
+ return (0);
+}
+#endif /* KEYBOARD_PROBE */
diff --git a/usr/src/boot/sys/boot/i386/loader/Makefile b/usr/src/boot/sys/boot/i386/loader/Makefile
new file mode 100644
index 0000000000..bf8ed9f9b4
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/Makefile
@@ -0,0 +1,174 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+CFLAGS= -O2
+CPPFLAGS= -DSTAND -nostdinc -I../../../../include -I../../..
+LOADER= zfsloader
+NEWVERSWHAT= "ZFS enabled bootstrap loader" x86
+MAN=
+
+# Set by zfsloader Makefile
+CPPFLAGS += -DLOADER_ZFS_SUPPORT -I../../zfs
+CPPFLAGS += -I../libi386
+LIBZFSBOOT= ../../zfs/i386/libzfsboot.a
+LIBI386= ../libi386/libi386.a
+
+# loader.help build needs better awk
+AWK= /usr/xpg4/bin/awk
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+OBJCOPY= $(GNU_ROOT)/bin/gobjcopy
+GSTRIP= $(GNU_ROOT)/bin/gstrip
+ROOT_BOOT= $(ROOT)/boot
+ROOT_BOOT_DEFAULTS= $(ROOT)/boot/defaults
+ROOT_BOOT_FORTH= $(ROOT)/boot/forth
+ROOT_BOOT_CONF= $(ROOT)/boot/conf.d
+ROOTBOOTFILES=$(FILES:%=$(ROOT_BOOT)/%)
+ROOTBOOTFORTH=$(FORTH:%=$(ROOT_BOOT_FORTH)/%)
+ROOTBOOTDEFAULTS=$(DEFFILES:%=$(ROOT_BOOT_DEFAULTS)/%)
+FILEMODE=0444
+
+all: machine x86 ${LOADER} loader.help
+
+install: all $(ROOTBOOTLOADER)
+
+PROG= ${LOADER}.sym
+INTERNALPROG=
+
+# architecture-specific loader code
+SRCS= main.c conf.c vers.c chain.c
+
+CPPFLAGS += -DLOADER_TFTP_SUPPORT -DLOADER_GZIP_SUPPORT
+
+# Enable BootForth
+CPPFLAGS += -DBOOT_FORTH -I$(SRC)/common/ficl -I../../ficl
+LIBFICL= ../../ficl/i386/libficl.a
+
+# Always add MI sources
+SRCS += boot.c commands.c console.c devopen.c interp.c
+SRCS += interp_backslash.c interp_parse.c ls.c misc.c
+SRCS += module.c panic.c linenoise.c
+
+SRCS += load_elf32.c load_elf32_obj.c reloc_elf32.c
+SRCS += load_elf64.c load_elf64_obj.c reloc_elf64.c
+
+SRCS += dev_net.c
+
+SRCS += disk.c part.c
+CPPFLAGS += -DLOADER_DISK_SUPPORT
+SRCS += crc32.c
+CPPFLAGS += -DLOADER_GPT_SUPPORT
+CPPFLAGS += -DLOADER_MBR_SUPPORT
+
+SRCS += bcache.c
+
+SRCS += isapnp.c
+SRCS += pnp.c
+
+# Forth interpreter
+SRCS += interp_forth.c
+
+MAN += loader.8
+MAN += zfsloader.8
+CPPFLAGS += -I../../common
+CPPFLAGS += -I.
+
+CLEANFILES= vers.c ${LOADER} ${LOADER}.sym ${LOADER}.bin loader.help
+
+CFLAGS += -Wall
+LDFLAGS= -static -Ttext 0x0
+
+# i386 standalone support library
+CPPFLAGS += -I.. -I../../../../lib/libstand
+LIBSTAND= ../../libstand/i386/libstand.a
+
+# BTX components
+CPPFLAGS += -I../btx/lib
+
+# Debug me!
+#CFLAGS+= -g
+#LDFLAGS+= -g
+
+include ../Makefile.inc
+
+vers.c: ../../common/newvers.sh version
+ $(SH) ../../common/newvers.sh version ${NEWVERSWHAT}
+
+${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
+ $(BTXLD) -v -f aout -e ${LOADER_ADDRESS} -o $@ -l ${BTXLDR} \
+ -b ${BTXKERN} ${LOADER}.bin
+
+${LOADER}.bin: ${LOADER}.sym
+ $(CP) $^ $@
+ $(GSTRIP) -R .comment -R .note $@
+
+loader.help: ../../common/help.common help.i386
+ $(CAT) $^ | $(AWK) -f ../../common/merge_help.awk > $@
+
+FILES= ${LOADER} loader.help
+
+include ../../forth/Makefile.inc
+FORTH += pcibios.4th
+
+FILES += loader.rc
+FORTH += menu.rc
+
+# XXX crt0.o needs to be first for pxeboot(8) to work
+
+DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
+
+CLEANFILES += machine x86
+CFLAGS += -DLOADER_PREFER_AMD64
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../i386/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+OBJS= $(SRCS:%.c=%.o)
+
+${PROG}: ${OBJS} $(LDADD)
+ $(LD) $(LDFLAGS) -o $@ $(BTXCRT) $(OBJS) $(LDADD)
+
+clean: clobber
+clobber:
+ $(RM) $(CLEANFILES) $(OBJS)
+
+install: all $(ROOT_BOOT_DEFAULTS) $(ROOT_BOOT_FORTH) \
+ $(ROOTBOOTFILES) $(ROOTBOOTDEFAULTS) $(ROOT_BOOT_CONF) $(ROOTBOOTFORTH)
+
+%.o: ../../common/%.c
+ $(COMPILE.c) -o $@ $<
+
+%.o: ../../common/linenoise/%.c
+ $(COMPILE.c) -o $@ $<
+
+$(ROOT_BOOT)/%: ../../forth/%
+ $(INS.file)
+
+$(ROOT_BOOT_DEFAULTS)/%: ../../forth/%
+ $(INS.file)
+
+$(ROOT_BOOT_FORTH)/%: ../../forth/%
+ $(INS.file)
+
+$(ROOT_BOOT_DEFAULTS) $(ROOT_BOOT_CONF) $(ROOT_BOOT_FORTH):
+ $(INS.dir)
diff --git a/usr/src/boot/sys/boot/i386/loader/chain.c b/usr/src/boot/sys/boot/i386/loader/chain.c
new file mode 100644
index 0000000000..74f75adffb
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/chain.c
@@ -0,0 +1,124 @@
+/*
+ * 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 2015 Toomas Soome <tsoome@me.com>
+ */
+
+/*
+ * Chain loader to load BIOS boot block either from MBR or PBR.
+ *
+ * Note the boot block location 0000:7c000 conflicts with loader, so we need to
+ * read in to temporary space and relocate on exec, when btx is stopped.
+ */
+
+#include <sys/cdefs.h>
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/diskmbr.h>
+
+#include "bootstrap.h"
+#include "libi386/libi386.h"
+#include "btxv86.h"
+
+/*
+ * The MBR/VBR is located in first sector of disk/partition.
+ * Read 512B to temporary location and set up relocation. Then
+ * exec relocator.
+ */
+#define SECTOR_SIZE (512)
+
+COMMAND_SET(chain, "chain", "chain load boot block from device", command_chain);
+
+static int
+command_chain(int argc, char *argv[])
+{
+ int fd, len, size = SECTOR_SIZE;
+ struct stat st;
+ vm_offset_t mem = 0x100000;
+ uint32_t *uintptr = &relocater_data;
+ struct i386_devdesc *rootdev;
+
+ if (argc == 1) {
+ command_errmsg = "no device or file name specified";
+ return (CMD_ERROR);
+ }
+ if (argc != 2) {
+ command_errmsg = "invalid trailing arguments";
+ return (CMD_ERROR);
+ }
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ command_errmsg = "open failed";
+ return (CMD_ERROR);
+ }
+
+ len = strlen(argv[1]);
+ if (argv[1][len-1] != ':') {
+ if (fstat(fd, &st) == -1) {
+ command_errmsg = "stat failed";
+ close(fd);
+ return (CMD_ERROR);
+ }
+ size = st.st_size;
+ } else if (strncmp(argv[1], "disk", 4) != 0) {
+ command_errmsg = "can only use disk device";
+ close(fd);
+ return (CMD_ERROR);
+ }
+
+ i386_getdev((void **)(&rootdev), argv[1], NULL);
+ if (rootdev == NULL) {
+ command_errmsg = "can't determine root device";
+ close(fd);
+ return (CMD_ERROR);
+ }
+
+ if (archsw.arch_readin(fd, mem, size) != size) {
+ command_errmsg = "failed to read disk";
+ close(fd);
+ return (CMD_ERROR);
+ }
+ close(fd);
+
+ if (argv[1][len-1] == ':' &&
+ *((uint16_t *)PTOV(mem + DOSMAGICOFFSET)) != DOSMAGIC) {
+ command_errmsg = "wrong magic";
+ return (CMD_ERROR);
+ }
+
+ uintptr[0] = mem;
+ uintptr[1] = 0x7C00;
+ uintptr[2] = size;
+
+ relocator_edx = bd_unit2bios(rootdev->d_unit);
+ relocator_esi = relocater_size;
+ relocator_ds = 0;
+ relocator_es = 0;
+ relocator_fs = 0;
+ relocator_gs = 0;
+ relocator_ss = 0;
+ relocator_cs = 0;
+ relocator_sp = 0x7C00;
+ relocator_ip = 0x7C00;
+ relocator_a20_enabled = 0;
+
+ i386_copyin(relocater, 0x600, relocater_size);
+
+ dev_cleanup();
+
+ __exec((void *)0x600);
+
+ panic("exec returned");
+ return (CMD_ERROR); /* not reached */
+}
diff --git a/usr/src/boot/sys/boot/i386/loader/conf.c b/usr/src/boot/sys/boot/i386/loader/conf.c
new file mode 100644
index 0000000000..66916dd8c1
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/conf.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <bootstrap.h>
+#include "libi386/libi386.h"
+#if defined(LOADER_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
+
+/*
+ * We could use linker sets for some or all of these, but
+ * then we would have to control what ended up linked into
+ * the bootstrap. So it's easier to conditionalise things
+ * here.
+ *
+ * XXX rename these arrays to be consistent and less namespace-hostile
+ *
+ * XXX as libi386 and biosboot merge, some of these can become linker sets.
+ */
+
+#if defined(LOADER_NFS_SUPPORT) && defined(LOADER_TFTP_SUPPORT)
+#error "Cannot have both tftp and nfs support yet."
+#endif
+
+#if defined(LOADER_FIREWIRE_SUPPORT)
+extern struct devsw fwohci;
+#endif
+
+/* Exported for libstand */
+struct devsw *devsw[] = {
+ &bioscd,
+ &biosdisk,
+#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT)
+ &pxedisk,
+#endif
+#if defined(LOADER_FIREWIRE_SUPPORT)
+ &fwohci,
+#endif
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_dev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+#ifdef LOADER_GZIP_SUPPORT
+ &gzipfs_fsops,
+#endif
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_fsops,
+#endif
+ &ufs_fsops,
+ &dosfs_fsops,
+#if 0
+ &ext2fs_fsops,
+#endif
+ &cd9660_fsops,
+#if defined(LOADER_NANDFS_SUPPORT)
+ &nandfs_fsops,
+#endif
+#ifdef LOADER_NFS_SUPPORT
+ &nfs_fsops,
+#endif
+#ifdef LOADER_TFTP_SUPPORT
+ &tftp_fsops,
+#endif
+#ifdef LOADER_BZIP2_SUPPORT
+ &bzipfs_fsops,
+#endif
+#ifdef LOADER_SPLIT_SUPPORT
+ &splitfs_fsops,
+#endif
+ NULL
+};
+
+/* Exported for i386 only */
+/*
+ * Sort formats so that those that can detect based on arguments
+ * rather than reading the file go first.
+ */
+extern struct file_format i386_elf;
+extern struct file_format i386_elf_obj;
+extern struct file_format amd64_elf;
+extern struct file_format amd64_elf_obj;
+extern struct file_format multiboot;
+extern struct file_format multiboot_obj;
+extern struct file_format linux;
+extern struct file_format linux_initrd;
+
+struct file_format *file_formats[] = {
+ &multiboot,
+ &multiboot_obj,
+ &amd64_elf,
+ &amd64_elf_obj,
+ &i386_elf,
+ &i386_elf_obj,
+ &linux,
+ &linux_initrd,
+ NULL
+};
+
+/*
+ * Consoles
+ *
+ * We don't prototype these in libi386.h because they require
+ * data structures from bootstrap.h as well.
+ */
+extern struct console text;
+extern struct console ttya;
+extern struct console ttyb;
+extern struct console ttyc;
+extern struct console ttyd;
+#if defined(LOADER_FIREWIRE_SUPPORT)
+extern struct console dconsole;
+#endif
+extern struct console nullconsole;
+extern struct console spinconsole;
+
+struct console *consoles[] = {
+ &text,
+ &ttya,
+ &ttyb,
+ &ttyc,
+ &ttyd,
+#if defined(LOADER_FIREWIRE_SUPPORT)
+ &dconsole,
+#endif
+ &nullconsole,
+ &spinconsole,
+ NULL
+};
+
+extern struct pnphandler isapnphandler;
+extern struct pnphandler biospnphandler;
+extern struct pnphandler biospcihandler;
+
+struct pnphandler *pnphandlers[] = {
+ &biospnphandler, /* should go first, as it may set isapnp_readport */
+ &isapnphandler,
+ &biospcihandler,
+ NULL
+};
diff --git a/usr/src/boot/sys/boot/i386/loader/help.i386 b/usr/src/boot/sys/boot/i386/loader/help.i386
new file mode 100644
index 0000000000..dc285347c3
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/help.i386
@@ -0,0 +1,45 @@
+################################################################################
+# Treboot DReboot the system
+
+ reboot
+
+ Causes the system to immediately reboot.
+
+################################################################################
+# Theap DDisplay memory management statistics
+
+ heap
+
+ Requests debugging output from the heap manager. For debugging use
+ only.
+
+################################################################################
+# Tset Snum_ide_disks DSet the number of IDE disks
+
+ NOTE: this variable is deprecated, use root_disk_unit instead.
+
+ set num_ide_disks=<value>
+
+ When booting from a SCSI disk on a system with one or more IDE disks,
+ and where the IDE disks are the default boot device, it is necessary
+ to tell the kernel how many IDE disks there are in order to have it
+ correctly locate the SCSI disk you are booting from.
+
+################################################################################
+# Tset Sroot_disk_unit DForce the root disk unit number.
+
+ set root_disk_unit=<value>
+
+ If the code which detects the disk unit number for the root disk is
+ confused, eg. by a mix of SCSI and IDE disks, or IDE disks with
+ gaps in the sequence (eg. no primary slave), the unit number can be
+ forced by setting this variable.
+
+################################################################################
+# Tsmap DDisplay BIOS SMAP table
+
+ smap
+
+ Displays the BIOS SMAP (system memory map) table.
+
+################################################################################
diff --git a/usr/src/boot/sys/boot/i386/loader/loader.rc b/usr/src/boot/sys/boot/i386/loader/loader.rc
new file mode 100644
index 0000000000..32f6bf8043
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/loader.rc
@@ -0,0 +1,20 @@
+\ Loader.rc
+\
+\ Includes additional commands
+include /boot/forth/loader.4th
+try-include /boot/loader.rc.local
+
+\ Reads and processes loader.conf variables
+\ NOTE: Change to `start' if you disable the below boot menu
+\ also note that initialize will leave flag in stack from any_conf_read?
+\ start
+initialize drop
+
+\ Tests for password -- executes autoboot first if a password was defined
+check-password
+
+\ Load in the boot menu
+include /boot/forth/beastie.4th
+
+\ Start the boot menu
+beastie-start
diff --git a/usr/src/boot/sys/boot/i386/loader/main.c b/usr/src/boot/sys/boot/i386/loader/main.c
new file mode 100644
index 0000000000..4cba1b9945
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/main.c
@@ -0,0 +1,444 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * MD bootstrap main() and assorted miscellaneous
+ * commands.
+ */
+
+#include <stand.h>
+#include <stddef.h>
+#include <string.h>
+#include <machine/bootinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/psl.h>
+#include <sys/reboot.h>
+
+#include "bootstrap.h"
+#include "common/bootargs.h"
+#include "libi386/libi386.h"
+#include "libi386/smbios.h"
+#include "btxv86.h"
+
+#ifdef LOADER_ZFS_SUPPORT
+#include "../zfs/libzfs.h"
+#endif
+
+CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
+CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
+CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
+CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
+
+/* Arguments passed in from the boot1/boot2 loader */
+static struct bootargs *kargs;
+
+static u_int32_t initial_howto;
+static u_int32_t initial_bootdev;
+static struct bootinfo *initial_bootinfo;
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+static void extract_currdev(void);
+static int isa_inb(int port);
+static void isa_outb(int port, int value);
+void exit(int code);
+#ifdef LOADER_ZFS_SUPPORT
+static void i386_zfs_probe(void);
+#endif
+
+/* from vers.c */
+extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
+
+/* XXX debugging */
+extern char end[];
+
+static void *heap_top;
+static void *heap_bottom;
+
+int
+main(void)
+{
+ int i;
+
+ /* Pick up arguments */
+ kargs = (void *)__args;
+ initial_howto = kargs->howto;
+ initial_bootdev = kargs->bootdev;
+ initial_bootinfo = kargs->bootinfo ? (struct bootinfo *)PTOV(kargs->bootinfo) : NULL;
+
+ /* Initialize the v86 register set to a known-good state. */
+ bzero(&v86, sizeof(v86));
+ v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
+
+ /*
+ * Initialise the heap as early as possible. Once this is done, malloc() is usable.
+ */
+ bios_getmem();
+
+#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \
+ defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
+ if (high_heap_size > 0) {
+ heap_top = PTOV(high_heap_base + high_heap_size);
+ heap_bottom = PTOV(high_heap_base);
+ if (high_heap_base < memtop_copyin)
+ memtop_copyin = high_heap_base;
+ } else
+#endif
+ {
+ heap_top = (void *)PTOV(bios_basemem);
+ heap_bottom = (void *)end;
+ }
+ setheap(heap_bottom, heap_top);
+
+ /*
+ * XXX Chicken-and-egg problem; we want to have console output early, but some
+ * console attributes may depend on reading from eg. the boot device, which we
+ * can't do yet.
+ *
+ * We can use printf() etc. once this is done.
+ * If the previous boot stage has requested a serial console, prefer that.
+ */
+ bi_setboothowto(initial_howto);
+ if (initial_howto & RB_MULTIPLE) {
+ if (initial_howto & RB_SERIAL)
+ setenv("console", "ttya text", 1);
+ else
+ setenv("console", "text ttya", 1);
+ } else if (initial_howto & RB_SERIAL)
+ setenv("console", "ttya", 1);
+ else if (initial_howto & RB_MUTE)
+ setenv("console", "null", 1);
+ cons_probe();
+
+ /*
+ * Initialise the block cache. Set the upper limit.
+ */
+ bcache_init(32768, 512);
+
+ /*
+ * Special handling for PXE and CD booting.
+ */
+ if (kargs->bootinfo == 0) {
+ /*
+ * We only want the PXE disk to try to init itself in the below
+ * walk through devsw if we actually booted off of PXE.
+ */
+ if (kargs->bootflags & KARGS_FLAGS_PXE)
+ pxe_enable(kargs->pxeinfo ? PTOV(kargs->pxeinfo) : NULL);
+ else if (kargs->bootflags & KARGS_FLAGS_CD)
+ bc_add(initial_bootdev);
+ }
+
+ archsw.arch_autoload = i386_autoload;
+ archsw.arch_getdev = i386_getdev;
+ archsw.arch_copyin = i386_copyin;
+ archsw.arch_copyout = i386_copyout;
+ archsw.arch_readin = i386_readin;
+ archsw.arch_isainb = isa_inb;
+ archsw.arch_isaoutb = isa_outb;
+#ifdef LOADER_ZFS_SUPPORT
+ archsw.arch_zfs_probe = i386_zfs_probe;
+#endif
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+ printf("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024);
+ if (initial_bootinfo != NULL) {
+ initial_bootinfo->bi_basemem = bios_basemem / 1024;
+ initial_bootinfo->bi_extmem = bios_extmem / 1024;
+ }
+
+ /* detect ACPI for future reference */
+ biosacpi_detect();
+
+ /* detect SMBIOS for future reference */
+ smbios_detect(NULL);
+
+ /* detect PCI BIOS for future reference */
+ biospci_detect();
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
+ extract_currdev(); /* set $currdev and $loaddev */
+ setenv("LINES", "24", 1); /* optional */
+ setenv("COLUMNS", "80", 1); /* optional */
+
+ if (bi_checkcpu())
+ setenv("ISADIR", "amd64", 1);
+ else
+ setenv("ISADIR", "", 1);
+
+ bios_getsmap();
+
+ interact(NULL);
+
+ /* if we ever get here, it is an error */
+ return (1);
+}
+
+/*
+ * Set the 'current device' by (if possible) recovering the boot device as
+ * supplied by the initial bootstrap.
+ *
+ * XXX should be extended for netbooting.
+ */
+static void
+extract_currdev(void)
+{
+ struct i386_devdesc new_currdev;
+#ifdef LOADER_ZFS_SUPPORT
+ char buf[20];
+ struct zfs_boot_args *zargs;
+#endif
+ int biosdev = -1;
+
+ /* Assume we are booting from a BIOS disk by default */
+ new_currdev.d_dev = &biosdisk;
+
+ /* new-style boot loaders such as pxeldr and cdldr */
+ if (kargs->bootinfo == 0) {
+ if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
+ /* we are booting from a CD with cdboot */
+ new_currdev.d_dev = &bioscd;
+ new_currdev.d_unit = bc_bios2unit(initial_bootdev);
+ } else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
+ /* we are booting from pxeldr */
+ new_currdev.d_dev = &pxedisk;
+ new_currdev.d_unit = 0;
+ } else {
+ /* we don't know what our boot device is */
+ new_currdev.d_kind.biosdisk.slice = -1;
+ new_currdev.d_kind.biosdisk.partition = 0;
+ biosdev = -1;
+ }
+#ifdef LOADER_ZFS_SUPPORT
+ } else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) {
+ zargs = NULL;
+ /* check for new style extended argument */
+ if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
+ zargs = (struct zfs_boot_args *)(kargs + 1);
+
+ if (zargs != NULL &&
+ zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) {
+ /* sufficient data is provided */
+ new_currdev.d_kind.zfs.pool_guid = zargs->pool;
+ new_currdev.d_kind.zfs.root_guid = zargs->root;
+ if (zargs->size >= sizeof(*zargs) && zargs->primary_vdev != 0) {
+ sprintf(buf, "%llu", zargs->primary_pool);
+ setenv("vfs.zfs.boot.primary_pool", buf, 1);
+ sprintf(buf, "%llu", zargs->primary_vdev);
+ setenv("vfs.zfs.boot.primary_vdev", buf, 1);
+ }
+ } else {
+ /* old style zfsboot block */
+ new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
+ new_currdev.d_kind.zfs.root_guid = 0;
+ }
+ new_currdev.d_dev = &zfs_dev;
+#endif
+ } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
+ /* The passed-in boot device is bad */
+ new_currdev.d_kind.biosdisk.slice = -1;
+ new_currdev.d_kind.biosdisk.partition = 0;
+ biosdev = -1;
+ } else {
+ new_currdev.d_kind.biosdisk.slice = B_SLICE(initial_bootdev) - 1;
+ new_currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
+ if (new_currdev.d_kind.biosdisk.partition == 0xff)
+ new_currdev.d_kind.biosdisk.partition = -1;
+ biosdev = initial_bootinfo->bi_bios_dev;
+
+ /*
+ * If we are booted by an old bootstrap, we have to guess at the BIOS
+ * unit number. We will lose if there is more than one disk type
+ * and we are not booting from the lowest-numbered disk type
+ * (ie. SCSI when IDE also exists).
+ */
+ if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */
+ biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
+ }
+ new_currdev.d_type = new_currdev.d_dev->dv_type;
+
+ /*
+ * If we are booting off of a BIOS disk and we didn't succeed in determining
+ * which one we booted off of, just use disk0: as a reasonable default.
+ */
+ if ((new_currdev.d_type == biosdisk.dv_type) &&
+ ((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) {
+ printf("Can't work out which disk we are booting from.\n"
+ "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
+ new_currdev.d_unit = 0;
+ }
+
+#ifdef LOADER_ZFS_SUPPORT
+#ifdef __FreeBSD__
+ if (new_currdev.d_type == DEVT_ZFS)
+ init_zfs_bootenv(zfs_fmtdev(&new_currdev));
+#endif
+#endif
+
+ env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
+ i386_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
+ env_nounset);
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+
+ printf("Rebooting...\n");
+ delay(1000000);
+ __exit(0);
+}
+
+/* provide this for panic, as it's not in the startup code */
+void
+exit(int code)
+{
+ __exit(code);
+}
+
+COMMAND_SET(heap, "heap", "show heap usage", command_heap);
+
+static int
+command_heap(int argc, char *argv[])
+{
+ mallocstats();
+ printf("heap base at %p, top at %p, upper limit at %p\n", heap_bottom,
+ sbrk(0), heap_top);
+ return(CMD_OK);
+}
+
+#ifdef LOADER_ZFS_SUPPORT
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+ command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ err = zfs_list(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+
+ return (CMD_OK);
+}
+
+#ifdef __FreeBSD__
+COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
+ command_reloadbe);
+
+static int
+command_reloadbe(int argc, char *argv[])
+{
+ int err;
+ char *root;
+
+ if (argc > 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ if (argc == 2) {
+ err = zfs_bootenv(argv[1]);
+ } else {
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ /* There does not appear to be a ZFS pool here, exit without error */
+ return (CMD_OK);
+ }
+ err = zfs_bootenv(getenv("zfs_be_root"));
+ }
+
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+
+ return (CMD_OK);
+}
+#endif /* __FreeBSD__ */
+#endif
+
+/* ISA bus access functions for PnP. */
+static int
+isa_inb(int port)
+{
+
+ return (inb(port));
+}
+
+static void
+isa_outb(int port, int value)
+{
+
+ outb(port, value);
+}
+
+#ifdef LOADER_ZFS_SUPPORT
+static void
+i386_zfs_probe(void)
+{
+ char devname[32];
+ int unit;
+
+ /*
+ * Open all the disks we can find and see if we can reconstruct
+ * ZFS pools from them.
+ */
+ for (unit = 0; unit < MAXBDDEV; unit++) {
+ if (bd_unit2bios(unit) == -1)
+ break;
+ sprintf(devname, "disk%d:", unit);
+ zfs_probe_dev(devname, NULL);
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/boot/i386/loader/version b/usr/src/boot/sys/boot/i386/loader/version
new file mode 100644
index 0000000000..7a2acaf185
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/loader/version
@@ -0,0 +1,14 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.1: New calling conventions for fopen.
+1.0: New semantics for finding the kernel, new boot.
+0.8: Set/getenv & cia, copyin/out.
+0.7: Supports large KVM
+0.6: Increased dictionary size -- supports loader.4th
+0.5: First release version
+0.2: Initial integration with BTX
+0.1: Initial i386 version, inspiration and some structure from the
+ NetBSD version.
diff --git a/usr/src/boot/sys/boot/i386/pmbr/Makefile b/usr/src/boot/sys/boot/i386/pmbr/Makefile
new file mode 100644
index 0000000000..a654ea2df2
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/pmbr/Makefile
@@ -0,0 +1,52 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+#
+# x86 EFI pmbr build rules
+#
+include $(SRC)/Makefile.master
+
+ROOT_BOOT = $(ROOT)/boot
+
+PROG= pmbr
+
+#AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+STRIP= # no strip is needed
+FILEMODE=0444
+MAN=
+OBJS= pmbr.o
+SRCS= $(OBJS:%.o=%.s)
+
+ORG= 0x600
+
+AS_CPPFLAGS= # no CPP for now
+ASFLAGS=--32 --divide
+LDFLAGS=-e start -Ttext ${ORG} -N -S --oformat binary
+
+all: $(PROG)
+
+install: $(PROG:%=$(ROOT_BOOT)/%)
+
+$(PROG): $(OBJS)
+ $(LD) $(LDFLAGS) -o $(PROG) $(OBJS)
+
+clobber: clean
+
+clean:
+ $(RM) $(PROG) $(OBJS)
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/i386/pmbr/pmbr.s b/usr/src/boot/sys/boot/i386/pmbr/pmbr.s
new file mode 100644
index 0000000000..46088cc78c
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/pmbr/pmbr.s
@@ -0,0 +1,188 @@
+#-
+# Copyright (c) 2007 Yahoo!, Inc.
+# All rights reserved.
+# Written by: John Baldwin <jhb@FreeBSD.org>
+#
+# 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the author nor the names of any co-contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+# $FreeBSD$
+#
+# Partly from: src/sys/boot/i386/mbr/mbr.s 1.7
+
+# A 512 byte PMBR boot manager to read a boot program and run it.
+# The embedded MBR is set up for PMBR and default bootblock sector
+# is hardcoded to 256 and size 1. The actual values are supposed to be
+# updated by installboot.
+
+ .set LOAD,0x7c00 # Load address
+ .set EXEC,0x600 # Execution address
+ .set MAGIC,0xaa55 # Magic: bootable
+ .set SECSIZE,0x200 # Size of a single disk sector
+ .set DISKSIG,440 # Disk signature offset
+ .set STACK,EXEC+SECSIZE*4 # Stack address
+ .set DPBUF,STACK
+
+ .set NHRDRV,0x475 # Number of hard drives
+
+ .globl start # Entry point
+ .code16
+ .text
+
+start: jmp real_code
+ .fill 0x3c,0x1,0x90 # fill with nop to ease disasm
+#
+# BIOS Parameter Block. Reserved space from 0xb to 0x3e, the FAT32 BPB
+# is 60 (3Ch) bytes.
+#
+ . = start + 0x3e
+
+#
+# Setup the segment registers for flat addressing and setup the stack.
+#
+real_code: cld # String ops inc
+ xorw %ax,%ax # Zero
+ movw %ax,%es # Address
+ movw %ax,%ds # data
+ movw %ax,%ss # Set up
+ movw $STACK,%sp # stack
+#
+# Relocate ourself to a lower address so that we have more room to load
+# other sectors.
+#
+ movw $main-EXEC+LOAD,%si # Source
+ movw $main,%di # Destination
+ movw $SECSIZE-(main-start),%cx # Byte count
+ rep # Relocate
+ movsb # code
+#
+# Jump to the relocated code.
+#
+ jmp main-LOAD+EXEC # To relocated code
+#
+# Validate drive number in %dl.
+#
+main: cmpb $0x80,%dl # Drive valid?
+ jb main.1 # No
+ movb NHRDRV,%dh # Calculate the highest
+ addb $0x80,%dh # drive number available
+ cmpb %dh,%dl # Within range?
+ jb main.2 # Yes
+main.1: movb $0x80,%dl # Assume drive 0x80
+#
+# Load stage2 and start it. location and size is written by installboot
+# and if size is 0, we can not do anything...
+#
+main.2: movw stage2_size, %ax
+ cmpw $0, %ax
+ je err_noboot # the stage2 size is not set
+ pushw %dx # save drive
+ movb $0x41, %ah # check extensions
+ movw $0x55aa, %bx
+ int $0x13
+ popw %dx # restore drive
+ jc err_rd # need lba mode for now
+ cmpw $0xaa55, %bx # chs support is not
+ jne err_rd # implemented.
+ movw $stage2_sector, %si # pointer to lba
+ movw $LOAD/16,%bx # set buffer segment
+ movw %bx,%es
+ xorw %bx,%bx # and offset
+load_boot: push %si # Save %si
+ call read
+ pop %si # Restore
+ decw stage2_size # stage2_size--
+ jnz next_boot
+boot: mov %bx,%es # Reset %es to zero
+ jmp LOAD # Jump to boot code
+next_boot: incl (%si) # Next LBA
+ adcl $0,4(%si)
+ mov %es,%ax # Adjust segment for next
+ addw $SECSIZE/16,%ax # sector
+ mov %ax,%es #
+ jmp load_boot
+#
+# Load a sector (64-bit LBA at %si) from disk %dl into %es:%bx by creating
+# a EDD packet on the stack and passing it to the BIOS. Trashes %ax and %si.
+#
+read: pushl 0x4(%si) # Set the LBA
+ pushl 0x0(%si) # address
+ pushw %es # Set the address of
+ pushw %bx # the transfer buffer
+ pushw $0x1 # Read 1 sector
+ pushw $0x10 # Packet length
+ movw %sp,%si # Packer pointer
+ movw $0x4200,%ax # BIOS: LBA Read from disk
+ int $0x13 # Call the BIOS
+ add $0x10,%sp # Restore stack
+ jc err_rd # If error
+ ret
+#
+# Various error message entry points.
+#
+err_rd: movw $msg_rd,%si # "I/O error loading
+ jmp putstr # boot loader"
+
+err_noboot: movw $msg_noboot,%si # "Missing boot
+ jmp putstr # loader"
+#
+# Output an ASCIZ string to the console via the BIOS.
+#
+putstr.0: movw $0x7,%bx # Page:attribute
+ movb $0xe,%ah # BIOS: Display
+ int $0x10 # character
+putstr: lodsb # Get character
+ testb %al,%al # End of string?
+ jnz putstr.0 # No
+putstr.1: jmp putstr.1 # Await reset
+
+msg_rd: .asciz "I/O error"
+msg_noboot: .asciz "No boot loader"
+
+ nop
+mbr_version: .byte 1, 1 # 1.1
+ .align 4
+stage2_size: .word 1 # bootblock size in sectors
+stage2_sector: .quad 256 # lba of bootblock
+disk_uuid: .quad 0 # uuid
+ .quad 0
+
+# this is the end of the code block we can use, next is space for
+# signature, partition table 4 entries and signature.
+ .org DISKSIG,0x1b8 #
+sig: .long 0 # OS Disk Signature
+ .word 0 # "Unknown" in PMBR
+
+partbl: .byte 0x00 # non-bootable
+ .byte 0x00 # head 0
+ .byte 0x02 # sector
+ .byte 0x00 # cylinder
+ .byte 0xEE # ID
+ .byte 0xFF # ending head
+ .byte 0xFF # ending sector
+ .byte 0xFF # ending cylinder
+ .long 0x00000001 # starting LBA
+ .long 0xFFFFFFFF # size
+ .fill 0x10,0x3,0x0 # other 3 entries
+ .word MAGIC # Magic number
diff --git a/usr/src/boot/sys/boot/i386/pxeldr/Makefile b/usr/src/boot/sys/boot/i386/pxeldr/Makefile
new file mode 100644
index 0000000000..dedb38a73a
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/pxeldr/Makefile
@@ -0,0 +1,84 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+ROOT_BOOT = $(ROOT)/boot
+
+CC= $(GCC_ROOT)/bin/gcc
+LD= $(GNU_ROOT)/bin/gld
+DD= /usr/bin/dd
+CFLAGS= -O2 -I../../..
+CCASFLAGS= -Wa,--divide
+
+include ../Makefile.inc
+
+BTXDIR=../btx
+
+PROG= ${LDR}
+INTERNALPROG=
+FILES= ${BOOT}
+MAN= ${BOOT}.8
+SRCS= ${LDR}.S
+OBJS= ${LDR}.o
+CLEANFILES= ${BOOT} ${OBJS}
+
+BOOT= pxeboot
+LDR= pxeldr
+ORG= 0x7c00
+LOADER= loader
+FILEMODE=0444
+
+#CFLAGS += -DPROBE_KEYBOARD
+
+#.if defined(BOOT_PXELDR_ALWAYS_SERIAL)
+#CFLAGS+=-DALWAYS_SERIAL
+#.endif
+
+CFLAGS +=-I../common
+
+LOADERBIN= ../loader/zfsloader.bin
+
+CLEANFILES += ${BOOT}.tmp
+
+${BOOT}: ${LDR} ${LOADER}
+ $(CAT) ${LDR} ${LOADER} > $@.tmp
+ $(DD) if=$@.tmp of=$@ obs=2k conv=sync
+ $(RM) $@.tmp
+
+LDFLAGS +=-e start -Ttext ${ORG} -N -S --oformat binary
+
+CLEANFILES += ${LOADER} ${LDR}
+
+${LDR}: ${OBJS}
+ ${LD} ${LDFLAGS} -o $@ $^
+
+${LOADER}: ${LOADERBIN} ${BTXLDR} ${BTXKERN}
+ $(BTXLD) -v -f aout -e ${LOADER_ADDRESS} -o $@ -l ${BTXLDR} \
+ -b ${BTXKERN} ${LOADERBIN}
+
+all: ${BOOT}
+
+install: $(BOOT:%=$(ROOT_BOOT)/%)
+
+clobber: clean
+clean:
+ $(RM) $(CLEANFILES)
+
+.S.o:
+ $(CC) $(CFLAGS) $(CCASFLAGS) -c -o $@ $<
+
+$(ROOT_BOOT)/%: %
+ $(INS.file)
diff --git a/usr/src/boot/sys/boot/i386/pxeldr/pxeboot.8 b/usr/src/boot/sys/boot/i386/pxeldr/pxeboot.8
new file mode 100644
index 0000000000..d2ca7038c5
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/pxeldr/pxeboot.8
@@ -0,0 +1,121 @@
+.\" Copyright (c) 1999 Doug White
+.\" 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.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 1, 2000
+.Dt PXEBOOT 8
+.Os
+.Sh NAME
+.Nm pxeboot
+.Nd Preboot Execution Environment (PXE) bootloader
+.Sh DESCRIPTION
+The
+.Nm
+bootloader is a modified version of the system third-stage bootstrap
+.Xr loader 8
+configured to run under Intel's Preboot Execution Environment (PXE) system.
+PXE is a form of smart boot ROM, built into Intel EtherExpress Pro/100 and
+3Com 3c905c Ethernet cards, and Ethernet-equipped Intel motherboards.
+PXE supports DHCP configuration and provides low-level NIC access services.
+The
+.Nm
+bootloader retrieves the kernel, modules,
+and other files either via NFS over UDP or by TFTP,
+selectable through compile-time options.
+In combination with a memory file system image or NFS-mounted root file system,
+.Nm
+allows for easy,
+EEPROM-burner free construction of diskless machines.
+.Pp
+The
+.Nm
+binary is loaded just like any other boot file,
+by specifying it in the DHCP server's configuration file.
+Below is a sample configuration for the ISC DHCP v2 server:
+.Bd -literal -offset indent
+option domain-name "example.com";
+option routers 10.0.0.1;
+option subnet-mask 255.255.255.0;
+option broadcast-address 10.0.0.255;
+option domain-name-servers 10.0.0.1;
+server-name "DHCPserver";
+server-identifier 10.0.0.1;
+
+default-lease-time 120;
+max-lease-time 120;
+
+subnet 10.0.0.0 netmask 255.255.255.0 {
+ filename "pxeboot";
+ range 10.0.0.10 10.0.0.254;
+}
+
+.Ed
+.Nm
+recognizes
+.Va next-server
+and
+.Va option root-path
+directives as the server and path to NFS mount for file requests,
+respectively, or the server to make TFTP requests to.
+Note that
+.Nm
+expects to fetch
+.Pa /boot/loader.rc
+from the specified server before loading any other files.
+.Pp
+In all other respects,
+.Nm
+acts just like
+.Xr loader 8 .
+.Pp
+As PXE is still in its infancy, some firmware versions may not work
+properly.
+The
+.Nm
+bootloader has been extensively tested on version 0.99 of Intel firmware;
+pre-release versions of the newer 2.0 firmware are known to have
+problems.
+Check with the device's manufacturer for their latest stable release.
+.Pp
+For further information on Intel's PXE specifications and Wired for
+Management (WfM) systems, see
+.Li http://www.intel.com/design/archives/wfm/ .
+.Sh SEE ALSO
+.Xr loader 8
+.Sh HISTORY
+The
+.Nm
+bootloader first appeared in
+.Fx 4.1 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+bootloader was written by
+.An John Baldwin Aq jhb@FreeBSD.org
+and
+.An Paul Saab Aq ps@FreeBSD.org .
+This manual page was written by
+.An Doug White Aq dwhite@FreeBSD.org .
diff --git a/usr/src/boot/sys/boot/i386/pxeldr/pxeldr.S b/usr/src/boot/sys/boot/i386/pxeldr/pxeldr.S
new file mode 100644
index 0000000000..ee1e18a1f3
--- /dev/null
+++ b/usr/src/boot/sys/boot/i386/pxeldr/pxeldr.S
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2000 John Baldwin
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This simple program is a preloader for the normal boot3 loader. It is simply
+ * prepended to the beginning of a fully built and btxld'd loader. It then
+ * copies the loader to the address boot2 normally loads it, emulates the
+ * boot[12] environment (protected mode, a bootinfo struct, etc.), and then jumps
+ * to the start of btxldr to start the boot process. This method allows a stock
+ * /boot/loader to be booted over the network via PXE w/o having to write a
+ * separate PXE-aware client just to load the loader.
+ */
+
+#include <sys/reboot.h>
+#include <bootargs.h>
+
+/*
+ * Memory locations.
+ */
+ .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
+ .set MEM_ARG,0x900 # Arguments at start
+ .set MEM_ARG_BTX,0xa100 # Where we move them to so the
+ # BTX client can see them
+ .set MEM_ARG_SIZE,0x18 # Size of the arguments
+ .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
+ .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
+ .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
+ .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
+ .set MEM_BIOS_KEYBOARD,0x496 # BDA byte with keyboard bit
+/*
+ * a.out header fields
+ */
+ .set AOUT_TEXT,0x04 # text segment size
+ .set AOUT_DATA,0x08 # data segment size
+ .set AOUT_BSS,0x0c # zero'd BSS size
+ .set AOUT_SYMBOLS,0x10 # symbol table
+ .set AOUT_ENTRY,0x14 # entry point
+ .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
+/*
+ * Segment selectors.
+ */
+ .set SEL_SDATA,0x8 # Supervisor data
+ .set SEL_RDATA,0x10 # Real mode data
+ .set SEL_SCODE,0x18 # PM-32 code
+ .set SEL_SCODE16,0x20 # PM-16 code
+/*
+ * BTX constants
+ */
+ .set INT_SYS,0x30 # BTX syscall interrupt
+/*
+ * Bit in MEM_BIOS_KEYBOARD that is set if an enhanced keyboard is present
+ */
+ .set KEYBOARD_BIT,0x10
+/*
+ * We expect to be loaded by the BIOS at 0x7c00 (standard boot loader entry
+ * point)
+ */
+ .code16
+ .globl start
+ .org 0x0, 0x0
+/*
+ * BTX program loader for PXE network booting
+ */
+start: cld # string ops inc
+ xorw %ax, %ax # zero %ax
+ movw %ax, %ss # setup the
+ movw $start, %sp # stack
+ movw %es, %cx # save PXENV+ segment
+ movw %ax, %ds # setup the
+ movw %ax, %es # data segments
+ andl $0xffff, %ecx # clear upper words
+ andl $0xffff, %ebx # of %ebx and %ecx
+ shll $4, %ecx # calculate the offset of
+ addl %ebx, %ecx # the PXENV+ struct and
+ pushl %ecx # save it on the stack
+ movw $welcome_msg, %si # %ds:(%si) -> welcome message
+ callw putstr # display the welcome message
+/*
+ * Setup the arguments that the loader is expecting from boot[12]
+ */
+ movw $bootinfo_msg, %si # %ds:(%si) -> boot args message
+ callw putstr # display the message
+ movw $MEM_ARG, %bx # %ds:(%bx) -> boot args
+ movw %bx, %di # %es:(%di) -> boot args
+ xorl %eax, %eax # zero %eax
+ movw $(MEM_ARG_SIZE/4), %cx # Size of arguments in 32-bit
+ # dwords
+ rep # Clear the arguments
+ stosl # to zero
+ orb $KARGS_FLAGS_PXE, 0x8(%bx) # kargs->bootflags |=
+ # KARGS_FLAGS_PXE
+ popl 0xc(%bx) # kargs->pxeinfo = *PXENV+
+#ifdef ALWAYS_SERIAL
+/*
+ * set the RBX_SERIAL bit in the howto byte.
+ */
+ orl $RB_SERIAL, (%bx) # enable serial console
+#endif
+#ifdef PROBE_KEYBOARD
+/*
+ * Look at the BIOS data area to see if we have an enhanced keyboard. If not,
+ * set the RBX_DUAL and RBX_SERIAL bits in the howto byte.
+ */
+ testb $KEYBOARD_BIT, MEM_BIOS_KEYBOARD # keyboard present?
+ jnz keyb # yes, so skip
+ orl $(RB_MULTIPLE | RB_SERIAL), (%bx) # enable serial console
+keyb:
+#endif
+/*
+ * Turn on the A20 address line
+ */
+ callw seta20 # Turn A20 on
+/*
+ * Relocate the loader and BTX using a very lazy protected mode
+ */
+ movw $relocate_msg, %si # Display the
+ callw putstr # relocation message
+ movl end+AOUT_ENTRY, %edi # %edi is the destination
+ movl $(end+AOUT_HEADER), %esi # %esi is
+ # the start of the text
+ # segment
+ movl end+AOUT_TEXT, %ecx # %ecx = length of the text
+ # segment
+ lgdt gdtdesc # setup our own gdt
+ cli # turn off interrupts
+ movl %cr0, %eax # Turn on
+ orb $0x1, %al # protected
+ movl %eax, %cr0 # mode
+ ljmp $SEL_SCODE,$pm_start # long jump to clear the
+ # instruction pre-fetch queue
+ .code32
+pm_start: movw $SEL_SDATA, %ax # Initialize
+ movw %ax, %ds # %ds and
+ movw %ax, %es # %es to a flat selector
+ rep # Relocate the
+ movsb # text segment
+ addl $(MEM_PAGE_SIZE - 1), %edi # pad %edi out to a new page
+ andl $~(MEM_PAGE_SIZE - 1), %edi # for the data segment
+ movl end+AOUT_DATA, %ecx # size of the data segment
+ rep # Relocate the
+ movsb # data segment
+ movl end+AOUT_BSS, %ecx # size of the bss
+ xorl %eax, %eax # zero %eax
+ addb $3, %cl # round %ecx up to
+ shrl $2, %ecx # a multiple of 4
+ rep # zero the
+ stosl # bss
+ movl end+AOUT_ENTRY, %esi # %esi -> relocated loader
+ addl $MEM_BTX_OFFSET, %esi # %esi -> BTX in the loader
+ movl $MEM_BTX_ADDRESS, %edi # %edi -> where BTX needs to go
+ movzwl 0xa(%esi), %ecx # %ecx -> length of BTX
+ rep # Relocate
+ movsb # BTX
+ ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
+ .code16
+pm_16: movw $SEL_RDATA, %ax # Initialize
+ movw %ax, %ds # %ds and
+ movw %ax, %es # %es to a real mode selector
+ movl %cr0, %eax # Turn off
+ andb $~0x1, %al # protected
+ movl %eax, %cr0 # mode
+ ljmp $0,$pm_end # Long jump to clear the
+ # instruction pre-fetch queue
+pm_end: sti # Turn interrupts back on now
+/*
+ * Copy the BTX client to MEM_BTX_CLIENT
+ */
+ xorw %ax, %ax # zero %ax and set
+ movw %ax, %ds # %ds and %es
+ movw %ax, %es # to segment 0
+ movw $MEM_BTX_CLIENT, %di # Prepare to relocate
+ movw $btx_client, %si # the simple btx client
+ movw $(btx_client_end-btx_client), %cx # length of btx client
+ rep # Relocate the
+ movsb # simple BTX client
+/*
+ * Copy the boot[12] args to where the BTX client can see them
+ */
+ movw $MEM_ARG, %si # where the args are at now
+ movw $MEM_ARG_BTX, %di # where the args are moving to
+ movw $(MEM_ARG_SIZE/4), %cx # size of the arguments in longs
+ rep # Relocate
+ movsl # the words
+/*
+ * Save the entry point so the client can get to it later on
+ */
+ movl end+AOUT_ENTRY, %eax # load the entry point
+ stosl # add it to the end of the
+ # arguments
+/*
+ * Now we just start up BTX and let it do the rest
+ */
+ movw $jump_message, %si # Display the
+ callw putstr # jump message
+ ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
+
+/*
+ * Display a null-terminated string
+ */
+putstr: lodsb # load %al from %ds:(%si)
+ testb %al,%al # stop at null
+ jnz putc # if the char != null, output it
+ retw # return when null is hit
+putc: movw $0x7,%bx # attribute for output
+ movb $0xe,%ah # BIOS: put_char
+ int $0x10 # call BIOS, print char in %al
+ jmp putstr # keep looping
+
+/*
+ * Enable A20. Put an upper limit on the amount of time we wait for the
+ * keyboard controller to get ready (65K x ISA access time). If
+ * we wait more than that amount, the hardware is probably
+ * legacy-free and simply doesn't have a keyboard controller.
+ * Thus, the A20 line is already enabled.
+ */
+seta20: cli # Disable interrupts
+ xor %cx,%cx # Clear
+seta20.1: inc %cx # Increment, overflow?
+ jz seta20.3 # Yes
+ inb $0x64,%al # Get status
+ testb $0x2,%al # Busy?
+ jnz seta20.1 # Yes
+ movb $0xd1,%al # Command: Write
+ outb %al,$0x64 # output port
+seta20.2: inb $0x64,%al # Get status
+ testb $0x2,%al # Busy?
+ jnz seta20.2 # Yes
+ movb $0xdf,%al # Enable
+ outb %al,$0x60 # A20
+seta20.3: sti # Enable interrupts
+ retw # To caller
+
+/*
+ * BTX client to start btxldr
+ */
+ .code32
+btx_client: movl $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
+ # %ds:(%esi) -> end
+ # of boot[12] args
+ movl $(MEM_ARG_SIZE/4), %ecx # Number of words to push
+ std # Go backwards
+push_arg: lodsl # Read argument
+ pushl %eax # Push it onto the stack
+ loop push_arg # Push all of the arguments
+ cld # In case anyone depends on this
+ pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
+ # the loader
+ pushl %eax # Emulate a near call
+ movl $0x1, %eax # 'exec' system call
+ int $INT_SYS # BTX system call
+btx_client_end:
+ .code16
+
+ .p2align 4
+/*
+ * Global descriptor table.
+ */
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE (32-bit)
+ .word 0xffff,0x0,0x9a00,0x8f # SEL_SCODE16 (16-bit)
+gdt.1:
+/*
+ * Pseudo-descriptors.
+ */
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+
+welcome_msg: .asciz "PXE Loader 1.00\r\n\n"
+bootinfo_msg: .asciz "Building the boot loader arguments\r\n"
+relocate_msg: .asciz "Relocating the loader and the BTX\r\n"
+jump_message: .asciz "Starting the BTX loader\r\n"
+
+ .p2align 4
+end:
diff --git a/usr/src/boot/sys/boot/libstand/Makefile b/usr/src/boot/sys/boot/libstand/Makefile
new file mode 100644
index 0000000000..b45ddb2f97
--- /dev/null
+++ b/usr/src/boot/sys/boot/libstand/Makefile
@@ -0,0 +1,34 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+.KEEP_STATE:
+
+include $(SRC)/Makefile.master
+
+SUBDIRS = $(MACH) $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+
+all clean clobber: $(SUBDIRS)
+
+install: all
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/boot/sys/boot/libstand/Makefile.com b/usr/src/boot/sys/boot/libstand/Makefile.com
new file mode 100644
index 0000000000..73c0538dbd
--- /dev/null
+++ b/usr/src/boot/sys/boot/libstand/Makefile.com
@@ -0,0 +1,70 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+AS= $(GNU_ROOT)/bin/gas
+LD= $(GNU_ROOT)/bin/gld
+CC= $(GCC_ROOT)/bin/gcc
+
+LIBRARY= libstand.a
+
+all install: machine x86 $(LIBRARY)
+
+LIB_BASE= $(SRC)/boot/lib
+LIBSTAND_SRC= $(LIB_BASE)/libstand
+
+CPPFLAGS = -nostdinc -I../../../../include -I${LIBSTAND_SRC} -I../../..
+CPPFLAGS += -I../../../sys -I.
+
+CFLAGS = -O2 -ffreestanding -Wformat
+CFLAGS += -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
+CFLAGS += -Wno-pointer-sign -Wno-empty-body -Wno-string-plus-int \
+ -Wno-unused-const-variable -Wno-tautological-compare \
+ -Wno-unused-value -Wno-parentheses-equality \
+ -Wno-unused-function -Wno-enum-conversion -Wno-switch \
+ -Wno-switch-enum -Wno-knr-promoted-parameter -Wno-parentheses
+
+include ${LIBSTAND_SRC}/Makefile.inc
+
+$(LIBRARY): $(SRCS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean: clobber
+clobber:
+ $(RM) $(CLEANFILES) $(OBJS) machine x86 libstand.a
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../$(MACHINE)/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+%.o: $(LIBSTAND_SRC)/%.c
+ $(COMPILE.c) $<
+
+%.o: $(LIB_BASE)/libc/net/%.c
+ $(COMPILE.c) $<
+
+%.o: $(LIB_BASE)/libc/string/%.c
+ $(COMPILE.c) $<
+
+%.o: $(LIB_BASE)/libc/uuid/%.c
+ $(COMPILE.c) $<
+
+%.o: $(LIB_BASE)/libz/%.c
+ $(COMPILE.c) $<
diff --git a/usr/src/boot/sys/boot/libstand/amd64/Makefile b/usr/src/boot/sys/boot/libstand/amd64/Makefile
new file mode 100644
index 0000000000..3516128c65
--- /dev/null
+++ b/usr/src/boot/sys/boot/libstand/amd64/Makefile
@@ -0,0 +1,30 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include ../Makefile.com
+
+MACHINE= $(MACH64)
+
+CFLAGS += -m64 -fPIC -mno-red-zone
+ASFLAGS = -m64 -fPIC
+
+# _setjmp/_longjmp
+SRCS += $(LIBSTAND_SRC)/amd64/_setjmp.S
+OBJS += _setjmp.o
+
+$(LIBRARY): $(SRCS) $(OBJS)
+
+%.o: $(LIBSTAND_SRC)/amd64/%.S
+ $(COMPILE.S) $<
diff --git a/usr/src/boot/sys/boot/libstand/i386/Makefile b/usr/src/boot/sys/boot/libstand/i386/Makefile
new file mode 100644
index 0000000000..80983da037
--- /dev/null
+++ b/usr/src/boot/sys/boot/libstand/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include ../Makefile.com
+
+MACHINE= $(MACH)
+
+CFLAGS += -m32 -fno-reorder-functions
+CFLAGS += -mpreferred-stack-boundary=2
+
+# _setjmp/_longjmp
+SRCS += $(LIBSTAND_SRC)/i386/_setjmp.S
+OBJS += _setjmp.o
+
+$(LIBRARY): $(SRCS) $(OBJS)
+
+%.o: $(LIBSTAND_SRC)/i386/%.S
+ $(COMPILE.S) $<
diff --git a/usr/src/boot/sys/boot/ofw/Makefile b/usr/src/boot/sys/boot/ofw/Makefile
new file mode 100644
index 0000000000..3b881b780e
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= libofw
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/ofw/Makefile.inc b/usr/src/boot/sys/boot/ofw/Makefile.inc
new file mode 100644
index 0000000000..e67c0dc904
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/Makefile.inc
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc
+LDFLAGS+= -m elf32ppc_fbsd
+.endif
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/ofw/common/Makefile.inc b/usr/src/boot/sys/boot/ofw/common/Makefile.inc
new file mode 100644
index 0000000000..5d20372631
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/common/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+SRCS+= main.c
diff --git a/usr/src/boot/sys/boot/ofw/common/main.c b/usr/src/boot/sys/boot/ofw/common/main.c
new file mode 100644
index 0000000000..0913f0c9c2
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/common/main.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
+ * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "openfirm.h"
+#include "libofw.h"
+#include "bootstrap.h"
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+extern char end[];
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+u_int32_t acells, scells;
+
+static char bootargs[128];
+
+#define HEAP_SIZE 0x100000
+
+#define OF_puts(fd, text) OF_write(fd, text, strlen(text))
+
+void
+init_heap(void)
+{
+ void *base;
+ ihandle_t stdout;
+
+ if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) {
+ OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
+ OF_puts(stdout, "Heap memory claim failed!\n");
+ OF_enter();
+ }
+
+ setheap(base, (void *)((int)base + HEAP_SIZE));
+}
+
+uint64_t
+memsize(void)
+{
+ phandle_t memoryp;
+ cell_t reg[24];
+ int i, sz;
+ u_int64_t memsz;
+
+ memsz = 0;
+ memoryp = OF_instance_to_package(memory);
+
+ sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
+ sz /= sizeof(reg[0]);
+
+ for (i = 0; i < sz; i += (acells + scells)) {
+ if (scells > 1)
+ memsz += (uint64_t)reg[i + acells] << 32;
+ memsz += reg[i + acells + scells - 1];
+ }
+
+ return (memsz);
+}
+
+int
+main(int (*openfirm)(void *))
+{
+ phandle_t root;
+ int i;
+ char bootpath[64];
+ char *ch;
+ int bargc;
+ char **bargv;
+
+ /*
+ * Initalise the Open Firmware routines by giving them the entry point.
+ */
+ OF_init(openfirm);
+
+ root = OF_finddevice("/");
+
+ scells = acells = 1;
+ OF_getprop(root, "#address-cells", &acells, sizeof(acells));
+ OF_getprop(root, "#size-cells", &scells, sizeof(scells));
+
+ /*
+ * Initialise the heap as early as possible. Once this is done,
+ * alloc() is usable. The stack is buried inside us, so this is
+ * safe.
+ */
+ init_heap();
+
+ /*
+ * Set up console.
+ */
+ cons_probe();
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+ printf("Memory: %lldKB\n", memsize() / 1024);
+
+ OF_getprop(chosen, "bootpath", bootpath, 64);
+ ch = strchr(bootpath, ':');
+ *ch = '\0';
+ printf("Booted from: %s\n", bootpath);
+
+ printf("\n");
+
+ /*
+ * Only parse the first bootarg if present. It should
+ * be simple to handle extra arguments
+ */
+ OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
+ bargc = 0;
+ parse(&bargc, &bargv, bootargs);
+ if (bargc == 1)
+ env_setenv("currdev", EV_VOLATILE, bargv[0], ofw_setcurrdev,
+ env_nounset);
+ else
+ env_setenv("currdev", EV_VOLATILE, bootpath,
+ ofw_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset,
+ env_nounset);
+ setenv("LINES", "24", 1); /* optional */
+
+ archsw.arch_getdev = ofw_getdev;
+ archsw.arch_copyin = ofw_copyin;
+ archsw.arch_copyout = ofw_copyout;
+ archsw.arch_readin = ofw_readin;
+ archsw.arch_autoload = ofw_autoload;
+
+ interact(NULL); /* doesn't return */
+
+ OF_exit();
+
+ return 0;
+}
+
+COMMAND_SET(halt, "halt", "halt the system", command_halt);
+
+static int
+command_halt(int argc, char *argv[])
+{
+
+ OF_exit();
+ return (CMD_OK);
+}
+
+COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
+
+int
+command_memmap(int argc, char **argv)
+{
+
+ ofw_memmap(acells);
+ return (CMD_OK);
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/Makefile b/usr/src/boot/sys/boot/ofw/libofw/Makefile
new file mode 100644
index 0000000000..751ebfda75
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/Makefile
@@ -0,0 +1,35 @@
+# $FreeBSD$
+
+LIB= ofw
+INTERNALLIB=
+
+SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \
+ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
+ ofw_time.c openfirm.c
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= devicename_stubs.c
+
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+
+CFLAGS+= -ffreestanding
+.if ${MACHINE_CPUARCH} == "powerpc"
+CFLAGS+= -msoft-float
+SRCS+= ppc64_elf_freebsd.c
+.endif
+
+.ifdef(BOOT_DISK_DEBUG)
+# Make the disk code more talkative
+CFLAGS+= -DDISK_DEBUG
+.endif
+
+machine:
+ ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine
+
+CLEANFILES+= machine
+
+.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/usr/src/boot/sys/boot/ofw/libofw/devicename.c b/usr/src/boot/sys/boot/ofw/libofw/devicename.c
new file mode 100644
index 0000000000..c9814b76e9
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/devicename.c
@@ -0,0 +1,147 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+#include "../zfs/libzfs.h"
+
+static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+ofw_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct ofw_devdesc **dev = (struct ofw_devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) ||
+ ((strchr(devspec, '@') == NULL) &&
+ (strchr(devspec, ':') == NULL))) {
+
+ if (((rv = ofw_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
+ (path != NULL))
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec
+ */
+ return(ofw_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ */
+static int
+ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path)
+{
+ struct ofw_devdesc *idev;
+ struct devsw *dv;
+ phandle_t handle;
+ const char *p;
+ const char *s;
+ char *ep;
+ char name[256];
+ char type[64];
+ int err;
+ int len;
+ int i;
+
+ for (p = s = devspec; *s != '\0'; p = s) {
+ if ((s = strchr(p + 1, '/')) == NULL)
+ s = strchr(p, '\0');
+ len = s - devspec;
+ bcopy(devspec, name, len);
+ name[len] = '\0';
+ if ((handle = OF_finddevice(name)) == -1) {
+ bcopy(name, type, len);
+ type[len] = '\0';
+ } else if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1)
+ continue;
+ for (i = 0; (dv = devsw[i]) != NULL; i++) {
+ if (strncmp(dv->dv_name, type, strlen(dv->dv_name)) == 0)
+ goto found;
+ }
+ }
+ return(ENOENT);
+
+found:
+ if (path != NULL)
+ *path = s;
+ idev = malloc(sizeof(struct ofw_devdesc));
+ if (idev == NULL) {
+ printf("ofw_parsedev: malloc failed\n");
+ return ENOMEM;
+ }
+ strcpy(idev->d_path, name);
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (idev->d_type == DEVT_ZFS) {
+ p = devspec + strlen(dv->dv_name);
+ err = zfs_parsedev((struct zfs_devdesc *)idev, p, path);
+ if (err != 0) {
+ free(idev);
+ return (err);
+ }
+ }
+
+ if (dev == NULL) {
+ free(idev);
+ } else {
+ *dev = idev;
+ }
+ return(0);
+}
+
+int
+ofw_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct ofw_devdesc *ncurr;
+ int rv;
+
+ if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0)
+ return rv;
+
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return 0;
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/elf_freebsd.c b/usr/src/boot/sys/boot/ofw/libofw/elf_freebsd.c
new file mode 100644
index 0000000000..80ece7eeba
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/elf_freebsd.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+#include "openfirm.h"
+
+extern char end[];
+extern vm_offset_t reloc; /* From <arch>/conf.c */
+
+int
+__elfN(ofw_loadfile)(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+#if defined(__powerpc__)
+ /*
+ * No need to sync the icache for modules: this will
+ * be done by the kernel after relocation.
+ */
+ if (!strcmp((*result)->f_type, "elf kernel"))
+ __syncicache((void *) (*result)->f_addr, (*result)->f_size);
+#endif
+ return (0);
+}
+
+int
+__elfN(ofw_exec)(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp, dtbp;
+ Elf_Ehdr *e;
+ int error;
+ intptr_t entry;
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
+ return(EFTYPE);
+ }
+ e = (Elf_Ehdr *)&fmp->md_data;
+ entry = e->e_entry;
+
+ if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0)
+ return (error);
+
+ printf("Kernel entry at 0x%lx ...\n", e->e_entry);
+
+ dev_cleanup();
+ ofw_release_heap();
+ if (dtbp != 0) {
+ OF_quiesce();
+ ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0,
+ mdp, sizeof(mdp));
+ } else {
+ OF_chain((void *)reloc, end - (char *)reloc, (void *)entry,
+ (void *)mdp, sizeof(mdp));
+ }
+
+ panic("exec returned");
+}
+
+struct file_format ofw_elf =
+{
+ __elfN(ofw_loadfile),
+ __elfN(ofw_exec)
+};
diff --git a/usr/src/boot/sys/boot/ofw/libofw/libofw.h b/usr/src/boot/sys/boot/ofw/libofw/libofw.h
new file mode 100644
index 0000000000..87e90959c9
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/libofw.h
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (C) 2000 Benno Rice.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "openfirm.h"
+
+/* Note: Must match the 'struct devdesc' in bootstrap.h */
+struct ofw_devdesc {
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ ihandle_t d_handle;
+ union {
+ char d_path[256];
+ struct {
+ uint64_t pool_guid;
+ uint64_t root_guid;
+ };
+ };
+};
+
+extern int ofw_getdev(void **vdev, const char *devspec, const char **path);
+extern ev_sethook_t ofw_setcurrdev;
+
+extern struct devsw ofwdisk;
+extern struct netif_driver ofwnet;
+
+int ofwn_getunit(const char *);
+
+ssize_t ofw_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t ofw_readin(const int fd, vm_offset_t dest, const size_t len);
+
+extern int ofw_boot(void);
+extern int ofw_autoload(void);
+
+void ofw_memmap(int);
+void *ofw_alloc_heap(unsigned int);
+void ofw_release_heap(void);
+
+struct preloaded_file;
+struct file_format;
+
+int ofw_elf_loadfile(char *, vm_offset_t, struct preloaded_file **);
+int ofw_elf_exec(struct preloaded_file *);
+
+extern struct file_format ofw_elf;
+#ifdef __powerpc__
+extern struct file_format ofw_elf64;
+#endif
+
+extern void reboot(void);
+
+struct ofw_reg
+{
+ cell_t base;
+ cell_t size;
+};
+
+struct ofw_reg2
+{
+ cell_t base_hi;
+ cell_t base_lo;
+ cell_t size;
+};
+
+extern int (*openfirmware)(void *);
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c
new file mode 100644
index 0000000000..59ce9a5067
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c
@@ -0,0 +1,120 @@
+/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */
+
+/*-
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include "bootstrap.h"
+#include "openfirm.h"
+
+static void ofw_cons_probe(struct console *cp);
+static int ofw_cons_init(int);
+void ofw_cons_putchar(int);
+int ofw_cons_getchar(void);
+int ofw_cons_poll(void);
+
+static ihandle_t stdin;
+static ihandle_t stdout;
+
+struct console ofwconsole = {
+ "ofw",
+ "Open Firmware console",
+ 0,
+ ofw_cons_probe,
+ ofw_cons_init,
+ ofw_cons_putchar,
+ ofw_cons_getchar,
+ ofw_cons_poll,
+};
+
+static void
+ofw_cons_probe(struct console *cp)
+{
+
+ OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
+ OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
+ cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;
+}
+
+static int
+ofw_cons_init(int arg)
+{
+ return 0;
+}
+
+void
+ofw_cons_putchar(int c)
+{
+ char cbuf;
+
+ if (c == '\n') {
+ cbuf = '\r';
+ OF_write(stdout, &cbuf, 1);
+ }
+
+ cbuf = c;
+ OF_write(stdout, &cbuf, 1);
+}
+
+static int saved_char = -1;
+
+int
+ofw_cons_getchar()
+{
+ unsigned char ch = '\0';
+ int l;
+
+ if (saved_char != -1) {
+ l = saved_char;
+ saved_char = -1;
+ return l;
+ }
+
+ if (OF_read(stdin, &ch, 1) > 0)
+ return (ch);
+
+ return (-1);
+}
+
+int
+ofw_cons_poll()
+{
+ unsigned char ch;
+
+ if (saved_char != -1)
+ return 1;
+
+ if (OF_read(stdin, &ch, 1) > 0) {
+ saved_char = ch;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_copy.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_copy.c
new file mode 100644
index 0000000000..ffd6987315
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_copy.c
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * MD primitives supporting placement of module data
+ *
+ * XXX should check load address/size against memory top.
+ */
+#include <stand.h>
+
+#include "libofw.h"
+
+#define READIN_BUF (4 * 1024)
+#define PAGE_SIZE 0x1000
+#define PAGE_MASK 0x0fff
+#define MAPMEM_PAGE_INC 16
+
+
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+
+static int
+ofw_mapmem(vm_offset_t dest, const size_t len)
+{
+ void *destp, *addr;
+ size_t dlen;
+ size_t resid;
+ size_t nlen;
+ static vm_offset_t last_dest = 0;
+ static size_t last_len = 0;
+
+ nlen = len;
+ /*
+ * Check to see if this region fits in a prior mapping.
+ * Allocations are generally sequential, so only check
+ * the last one.
+ */
+ if (dest >= last_dest &&
+ (dest + len) <= (last_dest + last_len)) {
+ return (0);
+ }
+
+ /*
+ * Trim area covered by existing mapping, if any
+ */
+ if (dest < (last_dest + last_len) && dest >= last_dest) {
+ nlen -= (last_dest + last_len) - dest;
+ dest = last_dest + last_len;
+ }
+
+ destp = (void *)(dest & ~PAGE_MASK);
+ resid = dest & PAGE_MASK;
+
+ /*
+ * To avoid repeated mappings on small allocations,
+ * never map anything less than MAPMEM_PAGE_INC pages at a time
+ */
+ if ((nlen + resid) < PAGE_SIZE*MAPMEM_PAGE_INC) {
+ dlen = PAGE_SIZE*MAPMEM_PAGE_INC;
+ } else
+ dlen = roundup(nlen + resid, PAGE_SIZE);
+
+ if (OF_call_method("claim", memory, 3, 1, destp, dlen, 0, &addr)
+ == -1) {
+ printf("ofw_mapmem: physical claim failed\n");
+ return (ENOMEM);
+ }
+
+ /*
+ * We only do virtual memory management when real_mode is false.
+ */
+ if (real_mode == 0) {
+ if (OF_call_method("claim", mmu, 3, 1, destp, dlen, 0, &addr)
+ == -1) {
+ printf("ofw_mapmem: virtual claim failed\n");
+ return (ENOMEM);
+ }
+
+ if (OF_call_method("map", mmu, 4, 0, destp, destp, dlen, 0)
+ == -1) {
+ printf("ofw_mapmem: map failed\n");
+ return (ENOMEM);
+ }
+ }
+ last_dest = (vm_offset_t) destp;
+ last_len = dlen;
+
+ return (0);
+}
+
+ssize_t
+ofw_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ if (ofw_mapmem(dest, len)) {
+ printf("ofw_copyin: map error\n");
+ return (0);
+ }
+
+ bcopy(src, (void *)dest, len);
+ return(len);
+}
+
+ssize_t
+ofw_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ bcopy((void *)src, dest, len);
+ return(len);
+}
+
+ssize_t
+ofw_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ void *buf;
+ size_t resid, chunk, get;
+ ssize_t got;
+ vm_offset_t p;
+
+ p = dest;
+
+ chunk = min(READIN_BUF, len);
+ buf = malloc(chunk);
+ if (buf == NULL) {
+ printf("ofw_readin: buf malloc failed\n");
+ return(0);
+ }
+
+ if (ofw_mapmem(dest, len)) {
+ printf("ofw_readin: map error\n");
+ free(buf);
+ return (0);
+ }
+
+ for (resid = len; resid > 0; resid -= got, p += got) {
+ get = min(chunk, resid);
+ got = read(fd, buf, get);
+
+ if (got <= 0) {
+ if (got < 0)
+ printf("ofw_readin: read failed\n");
+ break;
+ }
+
+ bcopy(buf, (void *)p, got);
+ }
+
+ free(buf);
+ return(len - resid);
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_disk.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_disk.c
new file mode 100644
index 0000000000..9b2e11cbfb
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_disk.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (C) 2000 Benno Rice.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Disk I/O routines using Open Firmware
+ */
+
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#include <machine/stdarg.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+
+static int ofwd_init(void);
+static int ofwd_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, char *buf, size_t *rsize);
+static int ofwd_open(struct open_file *f, ...);
+static int ofwd_close(struct open_file *f);
+static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data);
+static void ofwd_print(int verbose);
+
+struct devsw ofwdisk = {
+ "block",
+ DEVT_DISK,
+ ofwd_init,
+ ofwd_strategy,
+ ofwd_open,
+ ofwd_close,
+ ofwd_ioctl,
+ ofwd_print
+};
+
+/*
+ * We're not guaranteed to be able to open a device more than once and there
+ * is no OFW standard method to determine whether a device is already opened.
+ * Opening a device multiple times simultaneously happens to work with most
+ * OFW block device drivers but triggers a trap with at least the driver for
+ * the on-board controllers of Sun Fire V100 and Ultra 1. Upper layers and MI
+ * code expect to be able to open a device more than once however. Given that
+ * different partitions of the same device might be opened at the same time as
+ * done by ZFS, we can't generally just keep track of the opened devices and
+ * reuse the instance handle when asked to open an already opened device. So
+ * the best we can do is to cache the lastly used device path and close and
+ * open devices in ofwd_strategy() as needed.
+ */
+static struct ofw_devdesc *kdp;
+
+static int
+ofwd_init(void)
+{
+
+ return (0);
+}
+
+static int
+ofwd_strategy(void *devdata, int flag __unused, daddr_t dblk, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct ofw_devdesc *dp = (struct ofw_devdesc *)devdata;
+ daddr_t pos;
+ int n;
+
+ if (dp != kdp) {
+ if (kdp != NULL) {
+#if !defined(__powerpc__)
+ OF_close(kdp->d_handle);
+#endif
+ kdp = NULL;
+ }
+ if ((dp->d_handle = OF_open(dp->d_path)) == -1)
+ return (ENOENT);
+ kdp = dp;
+ }
+
+ pos = dblk * 512;
+ do {
+ if (OF_seek(dp->d_handle, pos) < 0)
+ return (EIO);
+ n = OF_read(dp->d_handle, buf, size);
+ if (n < 0 && n != -2)
+ return (EIO);
+ } while (n == -2);
+ *rsize = size;
+ return (0);
+}
+
+static int
+ofwd_open(struct open_file *f, ...)
+{
+ struct ofw_devdesc *dp;
+ va_list vl;
+
+ va_start(vl, f);
+ dp = va_arg(vl, struct ofw_devdesc *);
+ va_end(vl);
+
+ if (dp != kdp) {
+ if (kdp != NULL) {
+ OF_close(kdp->d_handle);
+ kdp = NULL;
+ }
+ if ((dp->d_handle = OF_open(dp->d_path)) == -1) {
+ printf("%s: Could not open %s\n", __func__,
+ dp->d_path);
+ return (ENOENT);
+ }
+ kdp = dp;
+ }
+ return (0);
+}
+
+static int
+ofwd_close(struct open_file *f)
+{
+ struct ofw_devdesc *dev = f->f_devdata;
+
+ if (dev == kdp) {
+#if !defined(__powerpc__)
+ OF_close(dev->d_handle);
+#endif
+ kdp = NULL;
+ }
+ return (0);
+}
+
+static int
+ofwd_ioctl(struct open_file *f __unused, u_long cmd __unused,
+ void *data __unused)
+{
+
+ return (EINVAL);
+}
+
+static void
+ofwd_print(int verbose __unused)
+{
+
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_memory.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_memory.c
new file mode 100644
index 0000000000..60cc90457b
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_memory.c
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2001 Benno Rice
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <stand.h>
+
+#include "libofw.h"
+#include "openfirm.h"
+
+static void *heap_base = 0;
+static unsigned int heap_size = 0;
+
+struct ofw_mapping {
+ vm_offset_t va;
+ int len;
+ vm_offset_t pa;
+ int mode;
+};
+
+struct ofw_mapping2 {
+ vm_offset_t va;
+ int len;
+ vm_offset_t pa_hi;
+ vm_offset_t pa_lo;
+ int mode;
+};
+
+void
+ofw_memmap(int acells)
+{
+ struct ofw_mapping *mapptr;
+ struct ofw_mapping2 *mapptr2;
+ phandle_t mmup;
+ int nmapping, i;
+ u_char mappings[256 * sizeof(struct ofw_mapping2)];
+ char lbuf[80];
+
+ mmup = OF_instance_to_package(mmu);
+
+ bzero(mappings, sizeof(mappings));
+
+ nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings));
+ if (nmapping == -1) {
+ printf("Could not get memory map (%d)\n",
+ nmapping);
+ return;
+ }
+
+ pager_open();
+ if (acells == 1) {
+ nmapping /= sizeof(struct ofw_mapping);
+ mapptr = (struct ofw_mapping *) mappings;
+
+ printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range",
+ "Physical Range", "#Pages", "Mode");
+
+ for (i = 0; i < nmapping; i++) {
+ sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n",
+ mapptr[i].va,
+ mapptr[i].va + mapptr[i].len,
+ mapptr[i].pa,
+ mapptr[i].pa + mapptr[i].len,
+ mapptr[i].len / 0x1000,
+ mapptr[i].mode);
+ if (pager_output(lbuf))
+ break;
+ }
+ } else {
+ nmapping /= sizeof(struct ofw_mapping2);
+ mapptr2 = (struct ofw_mapping2 *) mappings;
+
+ printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range",
+ "Physical Range", "#Pages", "Mode");
+
+ for (i = 0; i < nmapping; i++) {
+ sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n",
+ mapptr2[i].va,
+ mapptr2[i].va + mapptr2[i].len,
+ mapptr2[i].pa_lo,
+ mapptr2[i].pa_lo + mapptr2[i].len,
+ mapptr2[i].len / 0x1000,
+ mapptr2[i].mode);
+ if (pager_output(lbuf))
+ break;
+ }
+ }
+ pager_close();
+}
+
+void *
+ofw_alloc_heap(unsigned int size)
+{
+ phandle_t memoryp, root;
+ cell_t available[4];
+ cell_t acells;
+
+ root = OF_finddevice("/");
+ acells = 1;
+ OF_getprop(root, "#address-cells", &acells, sizeof(acells));
+
+ memoryp = OF_instance_to_package(memory);
+ OF_getprop(memoryp, "available", available, sizeof(available));
+
+ heap_base = OF_claim((void *)available[acells-1], size,
+ sizeof(register_t));
+
+ if (heap_base != (void *)-1) {
+ heap_size = size;
+ }
+
+ return (heap_base);
+}
+
+void
+ofw_release_heap(void)
+{
+ OF_release(heap_base, heap_size);
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_module.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_module.c
new file mode 100644
index 0000000000..d39a343445
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_module.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * ofw-specific module functionality.
+ *
+ */
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+
+/*
+ * Use voodoo to load modules required by current hardware.
+ */
+int
+ofw_autoload(void)
+{
+ /* XXX Call some machdep autoload routine? */
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c
new file mode 100644
index 0000000000..691dedab05
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c
@@ -0,0 +1,260 @@
+/*-
+ * Copyright (c) 2000-2001 Benno Rice
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+#include <stand.h>
+#include <net.h>
+#include <netif.h>
+
+#include "openfirm.h"
+
+static int ofwn_probe(struct netif *, void *);
+static int ofwn_match(struct netif *, void *);
+static void ofwn_init(struct iodesc *, void *);
+static int ofwn_get(struct iodesc *, void *, size_t, time_t);
+static int ofwn_put(struct iodesc *, void *, size_t);
+static void ofwn_end(struct netif *);
+
+extern struct netif_stats ofwn_stats[];
+
+struct netif_dif ofwn_ifs[] = {
+ /* dif_unit dif_nsel dif_stats dif_private */
+ { 0, 1, &ofwn_stats[0], 0, },
+};
+
+struct netif_stats ofwn_stats[NENTS(ofwn_ifs)];
+
+struct netif_driver ofwnet = {
+ "net", /* netif_bname */
+ ofwn_match, /* netif_match */
+ ofwn_probe, /* netif_probe */
+ ofwn_init, /* netif_init */
+ ofwn_get, /* netif_get */
+ ofwn_put, /* netif_put */
+ ofwn_end, /* netif_end */
+ ofwn_ifs, /* netif_ifs */
+ NENTS(ofwn_ifs) /* netif_nifs */
+};
+
+static ihandle_t netinstance;
+
+static void *dmabuf;
+
+static int
+ofwn_match(struct netif *nif, void *machdep_hint)
+{
+ return 1;
+}
+
+static int
+ofwn_probe(struct netif *nif, void *machdep_hint)
+{
+ return 0;
+}
+
+static int
+ofwn_put(struct iodesc *desc, void *pkt, size_t len)
+{
+ size_t sendlen;
+ ssize_t rv;
+
+#if defined(NETIF_DEBUG)
+ struct ether_header *eh;
+ printf("netif_put: desc=0x%x pkt=0x%x len=%d\n", desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xffff);
+#endif
+
+ sendlen = len;
+ if (sendlen < 60) {
+ sendlen = 60;
+#if defined(NETIF_DEBUG)
+ printf("netif_put: length padded to %d\n", sendlen);
+#endif
+ }
+
+ if (dmabuf) {
+ bcopy(pkt, dmabuf, sendlen);
+ pkt = dmabuf;
+ }
+
+ rv = OF_write(netinstance, pkt, len);
+
+#if defined(NETIF_DEBUG)
+ printf("netif_put: OF_write returned %d\n", rv);
+#endif
+
+ return rv;
+}
+
+static int
+ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+{
+ time_t t;
+ int length;
+
+#if defined(NETIF_DEBUG)
+ printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len,
+ timeout);
+#endif
+
+ t = getsecs();
+ do {
+ length = OF_read(netinstance, pkt, len);
+ } while ((length == -2 || length == 0) &&
+ (getsecs() - t < timeout));
+
+#if defined(NETIF_DEBUG)
+ printf("netif_get: received length=%d (%x)\n", length, length);
+#endif
+
+ if (length < 12)
+ return -1;
+
+#if defined(NETIF_VERBOSE_DEBUG)
+ {
+ char *ch = pkt;
+ int i;
+
+ for(i = 0; i < 96; i += 4) {
+ printf("%02x%02x%02x%02x ", ch[i], ch[i+1],
+ ch[i+2], ch[i+3]);
+ }
+ printf("\n");
+ }
+#endif
+
+#if defined(NETIF_DEBUG)
+ {
+ struct ether_header *eh = pkt;
+
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xffff);
+ }
+#endif
+
+ return length;
+}
+
+extern char *strchr();
+
+static void
+ofwn_init(struct iodesc *desc, void *machdep_hint)
+{
+ phandle_t netdev;
+ char path[64];
+ char *ch;
+ int pathlen;
+
+ pathlen = OF_getprop(chosen, "bootpath", path, 64);
+ if ((ch = strchr(path, ':')) != NULL)
+ *ch = '\0';
+ netdev = OF_finddevice(path);
+#ifdef __sparc64__
+ if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1)
+#else
+ if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1)
+#endif
+ goto punt;
+
+ printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
+
+ if ((netinstance = OF_open(path)) == -1) {
+ printf("Could not open network device.\n");
+ goto punt;
+ }
+
+#if defined(NETIF_DEBUG)
+ printf("ofwn_init: Open Firmware instance handle: %08x\n", netinstance);
+#endif
+
+#ifndef __sparc64__
+ dmabuf = NULL;
+ if (OF_call_method("dma-alloc", netinstance, 1, 1, (64 * 1024), &dmabuf)
+ < 0) {
+ printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf);
+ goto punt;
+ }
+
+#if defined(NETIF_DEBUG)
+ printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf);
+#endif
+#endif
+
+ return;
+
+punt:
+ printf("\n");
+ printf("Could not boot from %s.\n", path);
+ OF_enter();
+}
+
+static void
+ofwn_end(struct netif *nif)
+{
+#ifdef BROKEN
+ /* dma-free freezes at least some Apple ethernet controllers */
+ OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS);
+#endif
+ OF_close(netinstance);
+}
+
+#if 0
+int
+ofwn_getunit(const char *path)
+{
+ int i;
+ char newpath[255];
+
+ OF_canon(path, newpath, 254);
+
+ for (i = 0; i < nofwninfo; i++) {
+ printf(">>> test =\t%s\n", ofwninfo[i].ofwn_path);
+ if (strcmp(path, ofwninfo[i].ofwn_path) == 0)
+ return i;
+
+ if (strcmp(newpath, ofwninfo[i].ofwn_path) == 0)
+ return i;
+ }
+
+ return -1;
+}
+#endif
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_reboot.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_reboot.c
new file mode 100644
index 0000000000..bbb420ac17
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_reboot.c
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2000 Benno Rice
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "openfirm.h"
+
+void
+exit(int code)
+{
+ OF_exit();
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_time.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_time.c
new file mode 100644
index 0000000000..f53997dc05
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_time.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2000 Benno Rice
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "openfirm.h"
+
+time_t
+time(time_t *tloc)
+{
+ int secs;
+
+ secs = OF_milliseconds() / 1000;
+ if (tloc)
+ *tloc = secs;
+ return secs;
+}
+
+int
+getsecs()
+{
+ time_t n = 0;
+ time(&n);
+ return n;
+}
+
+void
+delay(int usecs)
+{
+ int msecs, start;
+
+ msecs = usecs / 1000;
+ start = OF_milliseconds();
+
+ while (OF_milliseconds() - start < msecs);
+}
diff --git a/usr/src/boot/sys/boot/ofw/libofw/openfirm.c b/usr/src/boot/sys/boot/ofw/libofw/openfirm.c
new file mode 100644
index 0000000000..a8626cc403
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/openfirm.c
@@ -0,0 +1,785 @@
+/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+/*-
+ * Copyright (C) 2000 Benno Rice.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <machine/stdarg.h>
+
+#include <stand.h>
+
+#include "openfirm.h"
+
+int (*openfirmware)(void *);
+
+phandle_t chosen;
+ihandle_t mmu;
+ihandle_t memory;
+int real_mode = 0;
+
+/* Initialiser */
+
+void
+OF_init(int (*openfirm)(void *))
+{
+ phandle_t options;
+ char mode[sizeof("true")];
+
+ openfirmware = openfirm;
+
+ if ((chosen = OF_finddevice("/chosen")) == -1)
+ OF_exit();
+ if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) {
+ memory = OF_open("/memory");
+ if (memory == -1)
+ memory = OF_open("/memory@0");
+ if (memory == -1)
+ OF_exit();
+ }
+ if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
+ OF_exit();
+
+ /*
+ * Check if we run in real mode. If so, we do not need to map
+ * memory later on.
+ */
+ options = OF_finddevice("/options");
+ if (OF_getprop(options, "real-mode?", mode, sizeof(mode)) > 0 &&
+ strcmp(mode, "true") == 0)
+ real_mode = 1;
+}
+
+/*
+ * Generic functions
+ */
+
+/* Test to see if a service exists. */
+int
+OF_test(char *name)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t service;
+ cell_t missing;
+ } args = {
+ (cell_t)"test",
+ 1,
+ 1,
+ };
+
+ args.service = (cell_t)name;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.missing);
+}
+
+/* Return firmware millisecond count. */
+int
+OF_milliseconds()
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t ms;
+ } args = {
+ (cell_t)"milliseconds",
+ 0,
+ 1,
+ };
+
+ openfirmware(&args);
+ return (args.ms);
+}
+
+/*
+ * Device tree functions
+ */
+
+/* Return the next sibling of this node or 0. */
+phandle_t
+OF_peer(phandle_t node)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t node;
+ cell_t next;
+ } args = {
+ (cell_t)"peer",
+ 1,
+ 1,
+ };
+
+ args.node = node;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.next);
+}
+
+/* Return the first child of this node or 0. */
+phandle_t
+OF_child(phandle_t node)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t node;
+ cell_t child;
+ } args = {
+ (cell_t)"child",
+ 1,
+ 1,
+ };
+
+ args.node = node;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.child);
+}
+
+/* Return the parent of this node or 0. */
+phandle_t
+OF_parent(phandle_t node)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t node;
+ cell_t parent;
+ } args = {
+ (cell_t)"parent",
+ 1,
+ 1,
+ };
+
+ args.node = node;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.parent);
+}
+
+/* Return the package handle that corresponds to an instance handle. */
+phandle_t
+OF_instance_to_package(ihandle_t instance)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ cell_t package;
+ } args = {
+ (cell_t)"instance-to-package",
+ 1,
+ 1,
+ };
+
+ args.instance = instance;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.package);
+}
+
+/* Get the length of a property of a package. */
+int
+OF_getproplen(phandle_t package, char *propname)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t package;
+ cell_t propname;
+ cell_t proplen;
+ } args = {
+ (cell_t)"getproplen",
+ 2,
+ 1,
+ };
+
+ args.package = package;
+ args.propname = (cell_t)propname;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.proplen);
+}
+
+/* Get the value of a property of a package. */
+int
+OF_getprop(phandle_t package, char *propname, void *buf, int buflen)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t package;
+ cell_t propname;
+ cell_t buf;
+ cell_t buflen;
+ cell_t size;
+ } args = {
+ (cell_t)"getprop",
+ 4,
+ 1,
+ };
+
+ args.package = package;
+ args.propname = (cell_t)propname;
+ args.buf = (cell_t)buf;
+ args.buflen = buflen;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.size);
+}
+
+/* Get the next property of a package. */
+int
+OF_nextprop(phandle_t package, char *previous, char *buf)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t package;
+ cell_t previous;
+ cell_t buf;
+ cell_t flag;
+ } args = {
+ (cell_t)"nextprop",
+ 3,
+ 1,
+ };
+
+ args.package = package;
+ args.previous = (cell_t)previous;
+ args.buf = (cell_t)buf;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.flag);
+}
+
+/* Set the value of a property of a package. */
+/* XXX Has a bug on FirePower */
+int
+OF_setprop(phandle_t package, char *propname, void *buf, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t package;
+ cell_t propname;
+ cell_t buf;
+ cell_t len;
+ cell_t size;
+ } args = {
+ (cell_t)"setprop",
+ 4,
+ 1,
+ };
+
+ args.package = package;
+ args.propname = (cell_t)propname;
+ args.buf = (cell_t)buf;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.size);
+}
+
+/* Convert a device specifier to a fully qualified pathname. */
+int
+OF_canon(const char *device, char *buf, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t device;
+ cell_t buf;
+ cell_t len;
+ cell_t size;
+ } args = {
+ (cell_t)"canon",
+ 3,
+ 1,
+ };
+
+ args.device = (cell_t)device;
+ args.buf = (cell_t)buf;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.size);
+}
+
+/* Return a package handle for the specified device. */
+phandle_t
+OF_finddevice(const char *device)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t device;
+ cell_t package;
+ } args = {
+ (cell_t)"finddevice",
+ 1,
+ 1,
+ };
+
+ args.device = (cell_t)device;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.package);
+}
+
+/* Return the fully qualified pathname corresponding to an instance. */
+int
+OF_instance_to_path(ihandle_t instance, char *buf, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ cell_t buf;
+ cell_t len;
+ cell_t size;
+ } args = {
+ (cell_t)"instance-to-path",
+ 3,
+ 1,
+ };
+
+ args.instance = instance;
+ args.buf = (cell_t)buf;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.size);
+}
+
+/* Return the fully qualified pathname corresponding to a package. */
+int
+OF_package_to_path(phandle_t package, char *buf, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t package;
+ cell_t buf;
+ cell_t len;
+ cell_t size;
+ } args = {
+ (cell_t)"package-to-path",
+ 3,
+ 1,
+ };
+
+ args.package = package;
+ args.buf = (cell_t)buf;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.size);
+}
+
+/* Call the method in the scope of a given instance. */
+int
+OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...)
+{
+ va_list ap;
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t method;
+ cell_t instance;
+ cell_t args_n_results[12];
+ } args = {
+ (cell_t)"call-method",
+ 2,
+ 1,
+ };
+ cell_t *cp;
+ int n;
+
+ if (nargs > 6)
+ return (-1);
+ args.nargs = nargs + 2;
+ args.nreturns = nreturns + 1;
+ args.method = (cell_t)method;
+ args.instance = instance;
+ va_start(ap, nreturns);
+ for (cp = (cell_t *)(args.args_n_results + (n = nargs)); --n >= 0;)
+ *--cp = va_arg(ap, cell_t);
+ if (openfirmware(&args) == -1)
+ return (-1);
+ if (args.args_n_results[nargs])
+ return (args.args_n_results[nargs]);
+ for (cp = (cell_t *)(args.args_n_results + nargs + (n = args.nreturns));
+ --n > 0;)
+ *va_arg(ap, cell_t *) = *--cp;
+ va_end(ap);
+ return (0);
+}
+
+/*
+ * Device I/O functions
+ */
+
+/* Open an instance for a device. */
+ihandle_t
+OF_open(char *device)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t device;
+ cell_t instance;
+ } args = {
+ (cell_t)"open",
+ 1,
+ 1,
+ };
+
+ args.device = (cell_t)device;
+ if (openfirmware(&args) == -1 || args.instance == 0) {
+ return (-1);
+ }
+ return (args.instance);
+}
+
+/* Close an instance. */
+void
+OF_close(ihandle_t instance)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ } args = {
+ (cell_t)"close",
+ 1,
+ };
+
+ args.instance = instance;
+ openfirmware(&args);
+}
+
+/* Read from an instance. */
+int
+OF_read(ihandle_t instance, void *addr, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ cell_t addr;
+ cell_t len;
+ cell_t actual;
+ } args = {
+ (cell_t)"read",
+ 3,
+ 1,
+ };
+
+ args.instance = instance;
+ args.addr = (cell_t)addr;
+ args.len = len;
+
+#if defined(OPENFIRM_DEBUG)
+ printf("OF_read: called with instance=%08x, addr=%p, len=%d\n",
+ args.instance, args.addr, args.len);
+#endif
+
+ if (openfirmware(&args) == -1)
+ return (-1);
+
+#if defined(OPENFIRM_DEBUG)
+ printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n",
+ args.instance, args.addr, args.len, args.actual);
+#endif
+
+ return (args.actual);
+}
+
+/* Write to an instance. */
+int
+OF_write(ihandle_t instance, void *addr, int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ cell_t addr;
+ cell_t len;
+ cell_t actual;
+ } args = {
+ (cell_t)"write",
+ 3,
+ 1,
+ };
+
+ args.instance = instance;
+ args.addr = (cell_t)addr;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.actual);
+}
+
+/* Seek to a position. */
+int
+OF_seek(ihandle_t instance, u_int64_t pos)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t instance;
+ cell_t poshi;
+ cell_t poslo;
+ cell_t status;
+ } args = {
+ (cell_t)"seek",
+ 3,
+ 1,
+ };
+
+ args.instance = instance;
+ args.poshi = pos >> 32;
+ args.poslo = pos;
+ if (openfirmware(&args) == -1)
+ return (-1);
+ return (args.status);
+}
+
+/*
+ * Memory functions
+ */
+
+/* Claim an area of memory. */
+void *
+OF_claim(void *virt, u_int size, u_int align)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t virt;
+ cell_t size;
+ cell_t align;
+ cell_t baseaddr;
+ } args = {
+ (cell_t)"claim",
+ 3,
+ 1,
+ };
+
+ args.virt = (cell_t)virt;
+ args.size = size;
+ args.align = align;
+ if (openfirmware(&args) == -1)
+ return ((void *)-1);
+ return ((void *)args.baseaddr);
+}
+
+/* Release an area of memory. */
+void
+OF_release(void *virt, u_int size)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t virt;
+ cell_t size;
+ } args = {
+ (cell_t)"release",
+ 2,
+ };
+
+ args.virt = (cell_t)virt;
+ args.size = size;
+ openfirmware(&args);
+}
+
+/*
+ * Control transfer functions
+ */
+
+/* Reset the system and call "boot <bootspec>". */
+void
+OF_boot(char *bootspec)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t bootspec;
+ } args = {
+ (cell_t)"boot",
+ 1,
+ };
+
+ args.bootspec = (cell_t)bootspec;
+ openfirmware(&args);
+ for (;;) /* just in case */
+ ;
+}
+
+/* Suspend and drop back to the Open Firmware interface. */
+void
+OF_enter()
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ } args = {
+ (cell_t)"enter",
+ };
+
+ openfirmware(&args);
+ /* We may come back. */
+}
+
+/* Shut down and drop back to the Open Firmware interface. */
+void
+OF_exit()
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ } args = {
+ (cell_t)"exit",
+ };
+
+ openfirmware(&args);
+ for (;;) /* just in case */
+ ;
+}
+
+void
+OF_quiesce()
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ } args = {
+ (cell_t)"quiesce",
+ };
+
+ openfirmware(&args);
+}
+
+/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */
+#if 0
+void
+OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
+{
+ static struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t virt;
+ cell_t size;
+ cell_t entry;
+ cell_t arg;
+ cell_t len;
+ } args = {
+ (cell_t)"chain",
+ 5,
+ };
+
+ args.virt = (cell_t)virt;
+ args.size = size;
+ args.entry = (cell_t)entry;
+ args.arg = (cell_t)arg;
+ args.len = len;
+ openfirmware(&args);
+}
+#else
+void
+OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
+{
+ /*
+ * This is a REALLY dirty hack till the firmware gets this going
+ */
+#if 0
+ if (size > 0)
+ OF_release(virt, size);
+#endif
+ entry(0, 0, openfirmware, arg, len);
+}
+#endif
diff --git a/usr/src/boot/sys/boot/ofw/libofw/openfirm.h b/usr/src/boot/sys/boot/ofw/libofw/openfirm.h
new file mode 100644
index 0000000000..ecb1f32834
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/openfirm.h
@@ -0,0 +1,122 @@
+/* $NetBSD: openfirm.h,v 1.1 1998/05/15 10:16:00 tsubai Exp $ */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ */
+/*-
+ * Copyright (C) 2000 Benno Rice.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _OPENFIRM_H_
+#define _OPENFIRM_H_
+/*
+ * Prototypes for Open Firmware Interface Routines
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+typedef unsigned int ihandle_t;
+typedef unsigned int phandle_t;
+typedef unsigned long int cell_t;
+
+extern int (*openfirmware)(void *);
+extern phandle_t chosen;
+extern ihandle_t memory, mmu;
+extern int real_mode;
+
+/*
+ * This isn't actually an Open Firmware function, but it seemed like the right
+ * place for it to go.
+ */
+void OF_init(int (*openfirm)(void *));
+
+/* Generic functions */
+int OF_test(char *);
+void OF_quiesce(); /* Disable firmware */
+
+/* Device tree functions */
+phandle_t OF_peer(phandle_t);
+phandle_t OF_child(phandle_t);
+phandle_t OF_parent(phandle_t);
+phandle_t OF_instance_to_package(ihandle_t);
+int OF_getproplen(phandle_t, char *);
+int OF_getprop(phandle_t, char *, void *, int);
+int OF_nextprop(phandle_t, char *, char *);
+int OF_setprop(phandle_t, char *, void *, int);
+int OF_canon(const char *, char *, int);
+phandle_t OF_finddevice(const char *);
+int OF_instance_to_path(ihandle_t, char *, int);
+int OF_package_to_path(phandle_t, char *, int);
+int OF_call_method(char *, ihandle_t, int, int, ...);
+
+/* Device I/O functions */
+ihandle_t OF_open(char *);
+void OF_close(ihandle_t);
+int OF_read(ihandle_t, void *, int);
+int OF_write(ihandle_t, void *, int);
+int OF_seek(ihandle_t, u_quad_t);
+
+/* Memory functions */
+void *OF_claim(void *, u_int, u_int);
+void OF_release(void *, u_int);
+
+/* Control transfer functions */
+void OF_boot(char *);
+void OF_enter(void);
+void OF_exit(void) __attribute__((noreturn));
+void OF_chain(void *, u_int, void (*)(), void *, u_int);
+
+/* Time function */
+int OF_milliseconds(void);
+
+#endif /* _OPENFIRM_H_ */
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ppc64_elf_freebsd.c b/usr/src/boot/sys/boot/ofw/libofw/ppc64_elf_freebsd.c
new file mode 100644
index 0000000000..b411da4912
--- /dev/null
+++ b/usr/src/boot/sys/boot/ofw/libofw/ppc64_elf_freebsd.c
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+#include "openfirm.h"
+
+extern char end[];
+extern vm_offset_t reloc; /* From <arch>/conf.c */
+
+int
+ppc64_ofw_elf_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+ /*
+ * No need to sync the icache for modules: this will
+ * be done by the kernel after relocation.
+ */
+ if (!strcmp((*result)->f_type, "elf kernel"))
+ __syncicache((void *) (*result)->f_addr, (*result)->f_size);
+ return (0);
+}
+
+int
+ppc64_ofw_elf_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp, dtbp;
+ Elf_Ehdr *e;
+ int error;
+ intptr_t entry;
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
+ return(EFTYPE);
+ }
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ /* Handle function descriptor for ELFv1 kernels */
+ if ((e->e_flags & 3) == 2)
+ entry = e->e_entry;
+ else
+ entry = *(uint64_t *)e->e_entry;
+
+ if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0)
+ return (error);
+
+ printf("Kernel entry at 0x%lx ...\n", entry);
+
+ dev_cleanup();
+ ofw_release_heap();
+
+ if (dtbp != 0) {
+ OF_quiesce();
+ ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0,
+ mdp, sizeof(mdp));
+ } else {
+ OF_chain((void *)reloc, end - (char *)reloc, (void *)entry,
+ (void *)mdp, sizeof(mdp));
+ }
+
+ panic("exec returned");
+}
+
+struct file_format ofw_elf64 =
+{
+ ppc64_ofw_elf_loadfile,
+ ppc64_ofw_elf_exec
+};
diff --git a/usr/src/boot/sys/boot/sparc64/Makefile b/usr/src/boot/sys/boot/sparc64/Makefile
new file mode 100644
index 0000000000..a768039090
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= boot1 loader zfsboot zfsloader
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/sparc64/Makefile.inc b/usr/src/boot/sys/boot/sparc64/Makefile.inc
new file mode 100644
index 0000000000..ef5a7cee74
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/Makefile.inc
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+BINDIR?= /boot
+CFLAGS+= -ffreestanding
+LDFLAGS+= -nostdlib
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/sparc64/boot1/Makefile b/usr/src/boot/sys/boot/sparc64/boot1/Makefile
new file mode 100644
index 0000000000..5150c3b5f8
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/boot1/Makefile
@@ -0,0 +1,30 @@
+# $FreeBSD$
+
+PROG= boot1.elf
+INTERNALPROG=
+MAN=
+FILES?= boot1
+SRCS= _start.s boot1.c
+CLEANFILES=${FILES} boot1.aout
+
+BOOTBLOCKBASE= 0x4000
+
+CFLAGS.clang+=-mcmodel=small
+CFLAGS.gcc+=-mcmodel=medlow
+CFLAGS+=-Os -I${.CURDIR}/../../common
+LDFLAGS=-Ttext ${BOOTBLOCKBASE} -Wl,-N
+
+# Construct boot1. sunlabel expects it to contain zeroed-out space for the
+# label, and to be of the correct size.
+${FILES}: boot1.aout
+ @set -- `ls -l boot1.aout`; x=$$((7680-$$5)); \
+ echo "$$x bytes available"; test $$x -ge 0
+ dd if=/dev/zero of=${.TARGET} bs=512 count=16
+ dd if=boot1.aout of=${.TARGET} bs=512 oseek=1 conv=notrunc
+
+boot1.aout: boot1.elf
+ elf2aout -o ${.TARGET} ${.ALLSRC}
+
+boot1.o: ${.CURDIR}/../../common/ufsread.c
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/sparc64/boot1/_start.s b/usr/src/boot/sys/boot/sparc64/boot1/_start.s
new file mode 100644
index 0000000000..30f8019cc8
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/boot1/_start.s
@@ -0,0 +1,8 @@
+/* $FreeBSD$ */
+
+ .text
+ .globl _start
+_start:
+ call ofw_init
+ nop
+ sir
diff --git a/usr/src/boot/sys/boot/sparc64/boot1/boot1.c b/usr/src/boot/sys/boot/sparc64/boot1/boot1.c
new file mode 100644
index 0000000000..d0b738039b
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/boot1/boot1.c
@@ -0,0 +1,751 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/dirent.h>
+
+#include <machine/elf.h>
+#include <machine/stdarg.h>
+
+#include "paths.h"
+
+#define READ_BUF_SIZE 8192
+
+typedef int putc_func_t(char c, void *arg);
+typedef int32_t ofwh_t;
+
+struct sp_data {
+ char *sp_buf;
+ u_int sp_len;
+ u_int sp_size;
+};
+
+static const char digits[] = "0123456789abcdef";
+
+static char bootpath[128];
+static char bootargs[128];
+
+static ofwh_t bootdev;
+
+static uint32_t fs_off;
+
+int main(int ac, char **av);
+static void exit(int) __dead2;
+static void usage(void);
+
+#ifdef ZFSBOOT
+static void loadzfs(void);
+static int zbread(char *buf, off_t off, size_t bytes);
+#else
+static void load(const char *);
+#endif
+
+static void bcopy(const void *src, void *dst, size_t len);
+static void bzero(void *b, size_t len);
+
+static int domount(const char *device);
+static int dskread(void *buf, u_int64_t lba, int nblk);
+
+static void panic(const char *fmt, ...) __dead2;
+static int printf(const char *fmt, ...);
+static int putchar(char c, void *arg);
+static int vprintf(const char *fmt, va_list ap);
+static int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
+
+static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap);
+static int __puts(const char *s, putc_func_t *putc, void *arg);
+static int __sputc(char c, void *arg);
+static char *__uitoa(char *buf, u_int val, int base);
+static char *__ultoa(char *buf, u_long val, int base);
+
+/*
+ * Open Firmware interface functions
+ */
+typedef u_int64_t ofwcell_t;
+typedef u_int32_t u_ofwh_t;
+typedef int (*ofwfp_t)(ofwcell_t []);
+static ofwfp_t ofw; /* the PROM Open Firmware entry */
+
+void ofw_init(int, int, int, int, ofwfp_t);
+static ofwh_t ofw_finddevice(const char *);
+static ofwh_t ofw_open(const char *);
+static int ofw_getprop(ofwh_t, const char *, void *, size_t);
+static int ofw_read(ofwh_t, void *, size_t);
+static int ofw_write(ofwh_t, const void *, size_t);
+static int ofw_seek(ofwh_t, u_int64_t);
+static void ofw_exit(void) __dead2;
+
+static ofwh_t stdinh, stdouth;
+
+/*
+ * This has to stay here, as the PROM seems to ignore the
+ * entry point specified in the a.out header. (or elftoaout is broken)
+ */
+
+void
+ofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr)
+{
+ ofwh_t chosenh;
+ char *av[16];
+ char *p;
+ int ac;
+
+ ofw = ofwaddr;
+
+ chosenh = ofw_finddevice("/chosen");
+ ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh));
+ ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth));
+ ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs));
+ ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath));
+
+ bootargs[sizeof(bootargs) - 1] = '\0';
+ bootpath[sizeof(bootpath) - 1] = '\0';
+
+ ac = 0;
+ p = bootargs;
+ for (;;) {
+ while (*p == ' ' && *p != '\0')
+ p++;
+ if (*p == '\0' || ac >= 16)
+ break;
+ av[ac++] = p;
+ while (*p != ' ' && *p != '\0')
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+
+ exit(main(ac, av));
+}
+
+static ofwh_t
+ofw_finddevice(const char *name)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"finddevice",
+ 1,
+ 1,
+ (ofwcell_t)name,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_finddevice: name=\"%s\"\n", name);
+ return (1);
+ }
+ return (args[4]);
+}
+
+static int
+ofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"getprop",
+ 4,
+ 1,
+ (u_ofwh_t)ofwh,
+ (ofwcell_t)name,
+ (ofwcell_t)buf,
+ len,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n",
+ ofwh, buf, len);
+ return (1);
+ }
+ return (0);
+}
+
+static ofwh_t
+ofw_open(const char *path)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"open",
+ 1,
+ 1,
+ (ofwcell_t)path,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_open: path=\"%s\"\n", path);
+ return (-1);
+ }
+ return (args[4]);
+}
+
+static int
+ofw_close(ofwh_t devh)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"close",
+ 1,
+ 0,
+ (u_ofwh_t)devh
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_close: devh=0x%x\n", devh);
+ return (1);
+ }
+ return (0);
+}
+
+static int
+ofw_read(ofwh_t devh, void *buf, size_t len)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"read",
+ 3,
+ 1,
+ (u_ofwh_t)devh,
+ (ofwcell_t)buf,
+ len,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len);
+ return (1);
+ }
+ return (0);
+}
+
+static int
+ofw_write(ofwh_t devh, const void *buf, size_t len)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"write",
+ 3,
+ 1,
+ (u_ofwh_t)devh,
+ (ofwcell_t)buf,
+ len,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len);
+ return (1);
+ }
+ return (0);
+}
+
+static int
+ofw_seek(ofwh_t devh, u_int64_t off)
+{
+ ofwcell_t args[] = {
+ (ofwcell_t)"seek",
+ 3,
+ 1,
+ (u_ofwh_t)devh,
+ off >> 32,
+ off,
+ 0
+ };
+
+ if ((*ofw)(args)) {
+ printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off);
+ return (1);
+ }
+ return (0);
+}
+
+static void
+ofw_exit(void)
+{
+ ofwcell_t args[3];
+
+ args[0] = (ofwcell_t)"exit";
+ args[1] = 0;
+ args[2] = 0;
+
+ for (;;)
+ (*ofw)(args);
+}
+
+static void
+bcopy(const void *src, void *dst, size_t len)
+{
+ const char *s = src;
+ char *d = dst;
+
+ while (len-- != 0)
+ *d++ = *s++;
+}
+
+static void
+memcpy(void *dst, const void *src, size_t len)
+{
+
+ bcopy(src, dst, len);
+}
+
+static void
+bzero(void *b, size_t len)
+{
+ char *p = b;
+
+ while (len-- != 0)
+ *p++ = 0;
+}
+
+static int
+strcmp(const char *s1, const char *s2)
+{
+
+ for (; *s1 == *s2 && *s1; s1++, s2++)
+ ;
+ return ((u_char)*s1 - (u_char)*s2);
+}
+
+int
+main(int ac, char **av)
+{
+ const char *path;
+ int i;
+
+ path = PATH_LOADER;
+ for (i = 0; i < ac; i++) {
+ switch (av[i][0]) {
+ case '-':
+ switch (av[i][1]) {
+ default:
+ usage();
+ }
+ break;
+ default:
+ path = av[i];
+ break;
+ }
+ }
+
+#ifdef ZFSBOOT
+ printf(" \n>> FreeBSD/sparc64 ZFS boot block\n Boot path: %s\n",
+ bootpath);
+#else
+ printf(" \n>> FreeBSD/sparc64 boot block\n Boot path: %s\n"
+ " Boot loader: %s\n", bootpath, path);
+#endif
+
+ if (domount(bootpath) == -1)
+ panic("domount");
+
+#ifdef ZFSBOOT
+ loadzfs();
+#else
+ load(path);
+#endif
+ return (1);
+}
+
+static void
+usage(void)
+{
+
+ printf("usage: boot device [/path/to/loader]\n");
+ exit(1);
+}
+
+static void
+exit(int code)
+{
+
+ ofw_exit();
+}
+
+#ifdef ZFSBOOT
+
+#define VDEV_BOOT_OFFSET (2 * 256 * 1024)
+static char zbuf[READ_BUF_SIZE];
+
+static int
+zbread(char *buf, off_t off, size_t bytes)
+{
+ size_t len;
+ off_t poff;
+ off_t soff;
+ char *p;
+ unsigned int nb;
+ unsigned int lb;
+
+ p = buf;
+ soff = VDEV_BOOT_OFFSET + off;
+ lb = (soff + bytes + DEV_BSIZE - 1) / DEV_BSIZE;
+ poff = soff;
+ while (poff < soff + bytes) {
+ nb = lb - poff / DEV_BSIZE;
+ if (nb > READ_BUF_SIZE / DEV_BSIZE)
+ nb = READ_BUF_SIZE / DEV_BSIZE;
+ if (dskread(zbuf, poff / DEV_BSIZE, nb))
+ break;
+ if ((poff / DEV_BSIZE + nb) * DEV_BSIZE > soff + bytes)
+ len = soff + bytes - poff;
+ else
+ len = (poff / DEV_BSIZE + nb) * DEV_BSIZE - poff;
+ memcpy(p, zbuf + poff % DEV_BSIZE, len);
+ p += len;
+ poff += len;
+ }
+ return (poff - soff);
+}
+
+static void
+loadzfs(void)
+{
+ Elf64_Ehdr eh;
+ Elf64_Phdr ph;
+ caddr_t p;
+ int i;
+
+ if (zbread((char *)&eh, 0, sizeof(eh)) != sizeof(eh)) {
+ printf("Can't read elf header\n");
+ return;
+ }
+ if (!IS_ELF(eh)) {
+ printf("Not an ELF file\n");
+ return;
+ }
+ for (i = 0; i < eh.e_phnum; i++) {
+ fs_off = eh.e_phoff + i * eh.e_phentsize;
+ if (zbread((char *)&ph, fs_off, sizeof(ph)) != sizeof(ph)) {
+ printf("Can't read program header %d\n", i);
+ return;
+ }
+ if (ph.p_type != PT_LOAD)
+ continue;
+ fs_off = ph.p_offset;
+ p = (caddr_t)ph.p_vaddr;
+ if (zbread(p, fs_off, ph.p_filesz) != ph.p_filesz) {
+ printf("Can't read content of section %d\n", i);
+ return;
+ }
+ if (ph.p_filesz != ph.p_memsz)
+ bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
+ }
+ ofw_close(bootdev);
+ (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
+}
+
+#else
+
+#include "ufsread.c"
+
+static struct dmadat __dmadat;
+
+static void
+load(const char *fname)
+{
+ Elf64_Ehdr eh;
+ Elf64_Phdr ph;
+ caddr_t p;
+ ufs_ino_t ino;
+ int i;
+
+ if ((ino = lookup(fname)) == 0) {
+ printf("File %s not found\n", fname);
+ return;
+ }
+ if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) {
+ printf("Can't read elf header\n");
+ return;
+ }
+ if (!IS_ELF(eh)) {
+ printf("Not an ELF file\n");
+ return;
+ }
+ for (i = 0; i < eh.e_phnum; i++) {
+ fs_off = eh.e_phoff + i * eh.e_phentsize;
+ if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) {
+ printf("Can't read program header %d\n", i);
+ return;
+ }
+ if (ph.p_type != PT_LOAD)
+ continue;
+ fs_off = ph.p_offset;
+ p = (caddr_t)ph.p_vaddr;
+ if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) {
+ printf("Can't read content of section %d\n", i);
+ return;
+ }
+ if (ph.p_filesz != ph.p_memsz)
+ bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
+ }
+ ofw_close(bootdev);
+ (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
+}
+
+#endif /* ZFSBOOT */
+
+static int
+domount(const char *device)
+{
+
+ if ((bootdev = ofw_open(device)) == -1) {
+ printf("domount: can't open device\n");
+ return (-1);
+ }
+#ifndef ZFSBOOT
+ dmadat = &__dmadat;
+ if (fsread(0, NULL, 0)) {
+ printf("domount: can't read superblock\n");
+ return (-1);
+ }
+#endif
+ return (0);
+}
+
+static int
+dskread(void *buf, u_int64_t lba, int nblk)
+{
+
+ /*
+ * The Open Firmware should open the correct partition for us.
+ * That means, if we read from offset zero on an open instance handle,
+ * we should read from offset zero of that partition.
+ */
+ ofw_seek(bootdev, lba * DEV_BSIZE);
+ ofw_read(bootdev, buf, nblk * DEV_BSIZE);
+ return (0);
+}
+
+static void
+panic(const char *fmt, ...)
+{
+ char buf[128];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof buf, fmt, ap);
+ printf("panic: %s\n", buf);
+ va_end(ap);
+
+ exit(1);
+}
+
+static int
+printf(const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vprintf(fmt, ap);
+ va_end(ap);
+ return (ret);
+}
+
+static int
+putchar(char c, void *arg)
+{
+ char buf;
+
+ if (c == '\n') {
+ buf = '\r';
+ ofw_write(stdouth, &buf, 1);
+ }
+ buf = c;
+ ofw_write(stdouth, &buf, 1);
+ return (1);
+}
+
+static int
+vprintf(const char *fmt, va_list ap)
+{
+ int ret;
+
+ ret = __printf(fmt, putchar, 0, ap);
+ return (ret);
+}
+
+static int
+vsnprintf(char *str, size_t sz, const char *fmt, va_list ap)
+{
+ struct sp_data sp;
+ int ret;
+
+ sp.sp_buf = str;
+ sp.sp_len = 0;
+ sp.sp_size = sz;
+ ret = __printf(fmt, __sputc, &sp, ap);
+ return (ret);
+}
+
+static int
+__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap)
+{
+ char buf[(sizeof(long) * 8) + 1];
+ char *nbuf;
+ u_long ul;
+ u_int ui;
+ int lflag;
+ int sflag;
+ char *s;
+ int pad;
+ int ret;
+ int c;
+
+ nbuf = &buf[sizeof buf - 1];
+ ret = 0;
+ while ((c = *fmt++) != 0) {
+ if (c != '%') {
+ ret += putc(c, arg);
+ continue;
+ }
+ lflag = 0;
+ sflag = 0;
+ pad = 0;
+reswitch: c = *fmt++;
+ switch (c) {
+ case '#':
+ sflag = 1;
+ goto reswitch;
+ case '%':
+ ret += putc('%', arg);
+ break;
+ case 'c':
+ c = va_arg(ap, int);
+ ret += putc(c, arg);
+ break;
+ case 'd':
+ if (lflag == 0) {
+ ui = (u_int)va_arg(ap, int);
+ if (ui < (int)ui) {
+ ui = -ui;
+ ret += putc('-', arg);
+ }
+ s = __uitoa(nbuf, ui, 10);
+ } else {
+ ul = (u_long)va_arg(ap, long);
+ if (ul < (long)ul) {
+ ul = -ul;
+ ret += putc('-', arg);
+ }
+ s = __ultoa(nbuf, ul, 10);
+ }
+ ret += __puts(s, putc, arg);
+ break;
+ case 'l':
+ lflag = 1;
+ goto reswitch;
+ case 'o':
+ if (lflag == 0) {
+ ui = (u_int)va_arg(ap, u_int);
+ s = __uitoa(nbuf, ui, 8);
+ } else {
+ ul = (u_long)va_arg(ap, u_long);
+ s = __ultoa(nbuf, ul, 8);
+ }
+ ret += __puts(s, putc, arg);
+ break;
+ case 'p':
+ ul = (u_long)va_arg(ap, void *);
+ s = __ultoa(nbuf, ul, 16);
+ ret += __puts("0x", putc, arg);
+ ret += __puts(s, putc, arg);
+ break;
+ case 's':
+ s = va_arg(ap, char *);
+ ret += __puts(s, putc, arg);
+ break;
+ case 'u':
+ if (lflag == 0) {
+ ui = va_arg(ap, u_int);
+ s = __uitoa(nbuf, ui, 10);
+ } else {
+ ul = va_arg(ap, u_long);
+ s = __ultoa(nbuf, ul, 10);
+ }
+ ret += __puts(s, putc, arg);
+ break;
+ case 'x':
+ if (lflag == 0) {
+ ui = va_arg(ap, u_int);
+ s = __uitoa(nbuf, ui, 16);
+ } else {
+ ul = va_arg(ap, u_long);
+ s = __ultoa(nbuf, ul, 16);
+ }
+ if (sflag)
+ ret += __puts("0x", putc, arg);
+ ret += __puts(s, putc, arg);
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ pad = pad * 10 + c - '0';
+ goto reswitch;
+ default:
+ break;
+ }
+ }
+ return (ret);
+}
+
+static int
+__sputc(char c, void *arg)
+{
+ struct sp_data *sp;
+
+ sp = arg;
+ if (sp->sp_len < sp->sp_size)
+ sp->sp_buf[sp->sp_len++] = c;
+ sp->sp_buf[sp->sp_len] = '\0';
+ return (1);
+}
+
+static int
+__puts(const char *s, putc_func_t *putc, void *arg)
+{
+ const char *p;
+ int ret;
+
+ ret = 0;
+ for (p = s; *p != '\0'; p++)
+ ret += putc(*p, arg);
+ return (ret);
+}
+
+static char *
+__uitoa(char *buf, u_int ui, int base)
+{
+ char *p;
+
+ p = buf;
+ *p = '\0';
+ do
+ *--p = digits[ui % base];
+ while ((ui /= base) != 0);
+ return (p);
+}
+
+static char *
+__ultoa(char *buf, u_long ul, int base)
+{
+ char *p;
+
+ p = buf;
+ *p = '\0';
+ do
+ *--p = digits[ul % base];
+ while ((ul /= base) != 0);
+ return (p);
+}
diff --git a/usr/src/boot/sys/boot/sparc64/loader/Makefile b/usr/src/boot/sys/boot/sparc64/loader/Makefile
new file mode 100644
index 0000000000..05d23ff192
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/Makefile
@@ -0,0 +1,104 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+MK_SSP= no
+MAN=
+
+PROG?= loader
+NEWVERSWHAT?= "bootstrap loader" sparc64
+INSTALLFLAGS= -b
+
+# Architecture-specific loader code
+SRCS= locore.S main.c metadata.c vers.c
+
+LOADER_DISK_SUPPORT?= yes
+LOADER_UFS_SUPPORT?= yes
+LOADER_CD9660_SUPPORT?= yes
+LOADER_ZFS_SUPPORT?= no
+LOADER_NET_SUPPORT?= yes
+LOADER_NFS_SUPPORT?= yes
+LOADER_TFTP_SUPPORT?= yes
+LOADER_GZIP_SUPPORT?= yes
+LOADER_BZIP2_SUPPORT?= no
+LOADER_DEBUG?= no
+
+.if ${LOADER_DEBUG} == "yes"
+CFLAGS+= -DLOADER_DEBUG
+.endif
+.if ${LOADER_DISK_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_DISK_SUPPORT
+.endif
+.if ${LOADER_UFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_UFS_SUPPORT
+.endif
+.if ${LOADER_CD9660_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_CD9660_SUPPORT
+.endif
+.if ${LOADER_ZFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_ZFS_SUPPORT
+CFLAGS+= -I${.CURDIR}/../../zfs
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
+.endif
+.if ${LOADER_GZIP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_GZIP_SUPPORT
+.endif
+.if ${LOADER_BZIP2_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_BZIP2_SUPPORT
+.endif
+.if ${LOADER_NET_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NET_SUPPORT
+.endif
+.if ${LOADER_NFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NFS_SUPPORT
+.endif
+.if ${LOADER_TFTP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_TFTP_SUPPORT
+.endif
+
+.if ${MK_FORTH} != "no"
+# Enable BootForth
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
+CFLAGS+= -I${.CURDIR}/../../ficl/sparc64
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I.
+# Avoid the open-close-dance for every file access as some firmwares perform
+# an auto-negotiation on every open of the network interface and thus causes
+# netbooting to take horribly long.
+CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE
+
+CLEANFILES+= vers.c loader.help
+
+LDFLAGS= -static
+
+# Open Firmware standalone support library
+LIBOFW= ${.OBJDIR}/../../ofw/libofw/libofw.a
+CFLAGS+= -I${.CURDIR}/../../ofw/libofw/
+
+# where to get libstand from
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} -lstand
+
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version \
+ ${NEWVERSWHAT}
+
+loader.help: help.common help.sparc64
+ cat ${.ALLSRC} | \
+ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+
+.PATH: ${.CURDIR}/../../forth
+.include "${.CURDIR}/../../forth/Makefile.inc"
+
+FILES+= loader.rc menu.rc
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/sparc64/loader/help.sparc64 b/usr/src/boot/sys/boot/sparc64/loader/help.sparc64
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/help.sparc64
diff --git a/usr/src/boot/sys/boot/sparc64/loader/locore.S b/usr/src/boot/sys/boot/sparc64/loader/locore.S
new file mode 100644
index 0000000000..a73f5bfa7f
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/locore.S
@@ -0,0 +1,42 @@
+/*-
+ * Initial implementation:
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ *
+ * As long as the above copyright statement and this notice remain
+ * unchanged, you can do what ever you want with this file.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+#define LOCORE
+
+#include <machine/frame.h>
+#include <machine/fsr.h>
+#include <machine/intr_machdep.h>
+#include <machine/pstate.h>
+
+#define PAGE_SIZE 8192
+#define PAGE_SHIFT 13
+
+#define STACK_SIZE (2 * PAGE_SIZE)
+
+ENTRY(_start)
+ /* Limit interrupts. */
+ wrpr %g0, PIL_TICK - 1, %pil
+
+ /*
+ * PSTATE: privileged, interrupts enabled, floating point
+ * unit enabled
+ */
+ wrpr %g0, PSTATE_PRIV | PSTATE_IE | PSTATE_PEF, %pstate
+ wr %g0, FPRS_FEF, %fprs
+
+ setx stack + STACK_SIZE - SPOFF - CCFSZ, %l7, %l6
+ mov %l6, %sp
+ call main
+ mov %o4, %o0
+ sir
+
+ .comm stack, STACK_SIZE, 32
diff --git a/usr/src/boot/sys/boot/sparc64/loader/main.c b/usr/src/boot/sys/boot/sparc64/loader/main.c
new file mode 100644
index 0000000000..ae1e5597a3
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/main.c
@@ -0,0 +1,994 @@
+/*-
+ * Initial implementation:
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ *
+ * As long as the above copyright statement and this notice remain
+ * unchanged, you can do what ever you want with this file.
+ */
+/*-
+ * Copyright (c) 2008 - 2012 Marius Strobl <marius@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * FreeBSD/sparc64 kernel loader - machine dependent part
+ *
+ * - implements copyin and readin functions that map kernel
+ * pages on demand. The machine independent code does not
+ * know the size of the kernel early enough to pre-enter
+ * TTEs and install just one 4MB mapping seemed to limiting
+ * to me.
+ */
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#ifdef LOADER_ZFS_SUPPORT
+#include <sys/vtoc.h>
+#include "../zfs/libzfs.h"
+#endif
+
+#include <vm/vm.h>
+#include <machine/asi.h>
+#include <machine/cmt.h>
+#include <machine/cpufunc.h>
+#include <machine/elf.h>
+#include <machine/fireplane.h>
+#include <machine/jbus.h>
+#include <machine/lsu.h>
+#include <machine/metadata.h>
+#include <machine/tte.h>
+#include <machine/tlb.h>
+#include <machine/upa.h>
+#include <machine/ver.h>
+#include <machine/vmparam.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+#include "dev_net.h"
+
+extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
+
+enum {
+ HEAPVA = 0x800000,
+ HEAPSZ = 0x1000000,
+ LOADSZ = 0x1000000 /* for kernel and modules */
+};
+
+/* At least Sun Fire V1280 require page sized allocations to be claimed. */
+CTASSERT(HEAPSZ % PAGE_SIZE == 0);
+
+static struct mmu_ops {
+ void (*tlb_init)(void);
+ int (*mmu_mapin)(vm_offset_t va, vm_size_t len);
+} *mmu_ops;
+
+typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3,
+ void *openfirmware);
+
+static inline u_long dtlb_get_data_sun4u(u_int, u_int);
+static int dtlb_enter_sun4u(u_int, u_long data, vm_offset_t);
+static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t);
+static inline u_long itlb_get_data_sun4u(u_int, u_int);
+static int itlb_enter_sun4u(u_int, u_long data, vm_offset_t);
+static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t);
+static void itlb_relocate_locked0_sun4u(void);
+extern vm_offset_t md_load(char *, vm_offset_t *, vm_offset_t *);
+static int sparc64_autoload(void);
+static ssize_t sparc64_readin(const int, vm_offset_t, const size_t);
+static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t);
+static vm_offset_t claim_virt(vm_offset_t, size_t, int);
+static vm_offset_t alloc_phys(size_t, int);
+static int map_phys(int, size_t, vm_offset_t, vm_offset_t);
+static void release_phys(vm_offset_t, u_int);
+static int __elfN(exec)(struct preloaded_file *);
+static int mmu_mapin_sun4u(vm_offset_t, vm_size_t);
+static vm_offset_t init_heap(void);
+static phandle_t find_bsp_sun4u(phandle_t, uint32_t);
+const char *cpu_cpuid_prop_sun4u(void);
+uint32_t cpu_get_mid_sun4u(void);
+static void tlb_init_sun4u(void);
+
+#ifdef LOADER_DEBUG
+typedef u_int64_t tte_t;
+
+static void pmap_print_tlb_sun4u(void);
+static void pmap_print_tte_sun4u(tte_t, tte_t);
+#endif
+
+static struct mmu_ops mmu_ops_sun4u = { tlb_init_sun4u, mmu_mapin_sun4u };
+
+/* sun4u */
+struct tlb_entry *dtlb_store;
+struct tlb_entry *itlb_store;
+u_int dtlb_slot;
+u_int itlb_slot;
+static int cpu_impl;
+static u_int dtlb_slot_max;
+static u_int itlb_slot_max;
+static u_int tlb_locked;
+
+static vm_offset_t curkva = 0;
+static vm_offset_t heapva;
+
+static char bootpath[64];
+static phandle_t root;
+
+#ifdef LOADER_ZFS_SUPPORT
+static struct zfs_devdesc zfs_currdev;
+#endif
+
+/*
+ * Machine dependent structures that the machine independent
+ * loader part uses.
+ */
+struct devsw *devsw[] = {
+#ifdef LOADER_DISK_SUPPORT
+ &ofwdisk,
+#endif
+#ifdef LOADER_NET_SUPPORT
+ &netdev,
+#endif
+#ifdef LOADER_ZFS_SUPPORT
+ &zfs_dev,
+#endif
+ NULL
+};
+
+struct arch_switch archsw;
+
+static struct file_format sparc64_elf = {
+ __elfN(loadfile),
+ __elfN(exec)
+};
+
+struct file_format *file_formats[] = {
+ &sparc64_elf,
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+#ifdef LOADER_ZFS_SUPPORT
+ &zfs_fsops,
+#endif
+#ifdef LOADER_UFS_SUPPORT
+ &ufs_fsops,
+#endif
+#ifdef LOADER_CD9660_SUPPORT
+ &cd9660_fsops,
+#endif
+#ifdef LOADER_ZIP_SUPPORT
+ &zipfs_fsops,
+#endif
+#ifdef LOADER_GZIP_SUPPORT
+ &gzipfs_fsops,
+#endif
+#ifdef LOADER_BZIP2_SUPPORT
+ &bzipfs_fsops,
+#endif
+#ifdef LOADER_NFS_SUPPORT
+ &nfs_fsops,
+#endif
+#ifdef LOADER_TFTP_SUPPORT
+ &tftp_fsops,
+#endif
+ NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+#ifdef LOADER_NET_SUPPORT
+ &ofwnet,
+#endif
+ NULL
+};
+
+extern struct console ofwconsole;
+struct console *consoles[] = {
+ &ofwconsole,
+ NULL
+};
+
+#ifdef LOADER_DEBUG
+static int
+watch_phys_set_mask(vm_offset_t pa, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_PWPR, ASI_DMMU, pa & (((2UL << 38) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_PW) & ~LSU_PM_MASK) |
+ (mask << LSU_PM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+static int
+watch_phys_set(vm_offset_t pa, int sz)
+{
+ u_long off;
+
+ off = (u_long)pa & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_phys_set_mask(pa, ((1 << sz) - 1) << off));
+}
+
+
+static int
+watch_virt_set_mask(vm_offset_t va, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_VWPR, ASI_DMMU, va & (((2UL << 41) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_VW) & ~LSU_VM_MASK) |
+ (mask << LSU_VM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+static int
+watch_virt_set(vm_offset_t va, int sz)
+{
+ u_long off;
+
+ off = (u_long)va & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_virt_set_mask(va, ((1 << sz) - 1) << off));
+}
+#endif
+
+/*
+ * archsw functions
+ */
+static int
+sparc64_autoload(void)
+{
+
+ return (0);
+}
+
+static ssize_t
+sparc64_readin(const int fd, vm_offset_t va, const size_t len)
+{
+
+ mmu_ops->mmu_mapin(va, len);
+ return (read(fd, (void *)va, len));
+}
+
+static ssize_t
+sparc64_copyin(const void *src, vm_offset_t dest, size_t len)
+{
+
+ mmu_ops->mmu_mapin(dest, len);
+ memcpy((void *)dest, src, len);
+ return (len);
+}
+
+/*
+ * other MD functions
+ */
+static vm_offset_t
+claim_virt(vm_offset_t virt, size_t size, int align)
+{
+ vm_offset_t mva;
+
+ if (OF_call_method("claim", mmu, 3, 1, virt, size, align, &mva) == -1)
+ return ((vm_offset_t)-1);
+ return (mva);
+}
+
+static vm_offset_t
+alloc_phys(size_t size, int align)
+{
+ cell_t phys_hi, phys_low;
+
+ if (OF_call_method("claim", memory, 2, 2, size, align, &phys_low,
+ &phys_hi) == -1)
+ return ((vm_offset_t)-1);
+ return ((vm_offset_t)phys_hi << 32 | phys_low);
+}
+
+static int
+map_phys(int mode, size_t size, vm_offset_t virt, vm_offset_t phys)
+{
+
+ return (OF_call_method("map", mmu, 5, 0, (uint32_t)phys,
+ (uint32_t)(phys >> 32), virt, size, mode));
+}
+
+static void
+release_phys(vm_offset_t phys, u_int size)
+{
+
+ (void)OF_call_method("release", memory, 3, 0, (uint32_t)phys,
+ (uint32_t)(phys >> 32), size);
+}
+
+static int
+__elfN(exec)(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp, dtbp;
+ Elf_Addr entry;
+ Elf_Ehdr *e;
+ int error;
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == 0)
+ return (EFTYPE);
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0)
+ return (error);
+
+ printf("jumping to kernel entry at %#lx.\n", e->e_entry);
+#ifdef LOADER_DEBUG
+ pmap_print_tlb_sun4u();
+#endif
+
+ dev_cleanup();
+
+ entry = e->e_entry;
+
+ OF_release((void *)heapva, HEAPSZ);
+
+ ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware);
+
+ panic("%s: exec returned", __func__);
+}
+
+static inline u_long
+dtlb_get_data_sun4u(u_int tlb, u_int slot)
+{
+ u_long data, pstate;
+
+ slot = TLB_DAR_SLOT(tlb, slot);
+ /*
+ * We read ASI_DTLB_DATA_ACCESS_REG twice back-to-back in order to
+ * work around errata of USIII and beyond.
+ */
+ pstate = rdpr(pstate);
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ (void)ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+ data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG);
+ wrpr(pstate, pstate, 0);
+ return (data);
+}
+
+static inline u_long
+itlb_get_data_sun4u(u_int tlb, u_int slot)
+{
+ u_long data, pstate;
+
+ slot = TLB_DAR_SLOT(tlb, slot);
+ /*
+ * We read ASI_DTLB_DATA_ACCESS_REG twice back-to-back in order to
+ * work around errata of USIII and beyond.
+ */
+ pstate = rdpr(pstate);
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ (void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+ data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG);
+ wrpr(pstate, pstate, 0);
+ return (data);
+}
+
+static vm_offset_t
+dtlb_va_to_pa_sun4u(vm_offset_t va)
+{
+ u_long pstate, reg;
+ u_int i, tlb;
+
+ pstate = rdpr(pstate);
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ for (i = 0; i < dtlb_slot_max; i++) {
+ reg = ldxa(TLB_DAR_SLOT(tlb_locked, i),
+ ASI_DTLB_TAG_READ_REG);
+ if (TLB_TAR_VA(reg) != va)
+ continue;
+ reg = dtlb_get_data_sun4u(tlb_locked, i);
+ wrpr(pstate, pstate, 0);
+ reg >>= TD_PA_SHIFT;
+ if (cpu_impl == CPU_IMPL_SPARC64V ||
+ cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+ return (reg & TD_PA_CH_MASK);
+ return (reg & TD_PA_SF_MASK);
+ }
+ wrpr(pstate, pstate, 0);
+ return (-1);
+}
+
+static vm_offset_t
+itlb_va_to_pa_sun4u(vm_offset_t va)
+{
+ u_long pstate, reg;
+ int i;
+
+ pstate = rdpr(pstate);
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ for (i = 0; i < itlb_slot_max; i++) {
+ reg = ldxa(TLB_DAR_SLOT(tlb_locked, i),
+ ASI_ITLB_TAG_READ_REG);
+ if (TLB_TAR_VA(reg) != va)
+ continue;
+ reg = itlb_get_data_sun4u(tlb_locked, i);
+ wrpr(pstate, pstate, 0);
+ reg >>= TD_PA_SHIFT;
+ if (cpu_impl == CPU_IMPL_SPARC64V ||
+ cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+ return (reg & TD_PA_CH_MASK);
+ return (reg & TD_PA_SF_MASK);
+ }
+ wrpr(pstate, pstate, 0);
+ return (-1);
+}
+
+static int
+dtlb_enter_sun4u(u_int index, u_long data, vm_offset_t virt)
+{
+
+ return (OF_call_method("SUNW,dtlb-load", mmu, 3, 0, index, data,
+ virt));
+}
+
+static int
+itlb_enter_sun4u(u_int index, u_long data, vm_offset_t virt)
+{
+
+ if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp && index == 0 &&
+ (data & TD_L) != 0)
+ panic("%s: won't enter locked TLB entry at index 0 on USIII+",
+ __func__);
+ return (OF_call_method("SUNW,itlb-load", mmu, 3, 0, index, data,
+ virt));
+}
+
+static void
+itlb_relocate_locked0_sun4u(void)
+{
+ u_long data, pstate, tag;
+ int i;
+
+ if (cpu_impl != CPU_IMPL_ULTRASPARCIIIp)
+ return;
+
+ pstate = rdpr(pstate);
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+
+ data = itlb_get_data_sun4u(tlb_locked, 0);
+ if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) {
+ wrpr(pstate, pstate, 0);
+ return;
+ }
+
+ /* Flush the mapping of slot 0. */
+ tag = ldxa(TLB_DAR_SLOT(tlb_locked, 0), ASI_ITLB_TAG_READ_REG);
+ stxa(TLB_DEMAP_VA(TLB_TAR_VA(tag)) | TLB_DEMAP_PRIMARY |
+ TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0);
+ flush(0); /* The USIII-family ignores the address. */
+
+ /*
+ * Search a replacement slot != 0 and enter the data and tag
+ * that formerly were in slot 0.
+ */
+ for (i = 1; i < itlb_slot_max; i++) {
+ if ((itlb_get_data_sun4u(tlb_locked, i) & TD_V) != 0)
+ continue;
+
+ stxa(AA_IMMU_TAR, ASI_IMMU, tag);
+ stxa(TLB_DAR_SLOT(tlb_locked, i), ASI_ITLB_DATA_ACCESS_REG,
+ data);
+ flush(0); /* The USIII-family ignores the address. */
+ break;
+ }
+ wrpr(pstate, pstate, 0);
+ if (i == itlb_slot_max)
+ panic("%s: could not find a replacement slot", __func__);
+}
+
+static int
+mmu_mapin_sun4u(vm_offset_t va, vm_size_t len)
+{
+ vm_offset_t pa, mva;
+ u_long data;
+ u_int index;
+
+ if (va + len > curkva)
+ curkva = va + len;
+
+ pa = (vm_offset_t)-1;
+ len += va & PAGE_MASK_4M;
+ va &= ~PAGE_MASK_4M;
+ while (len) {
+ if (dtlb_va_to_pa_sun4u(va) == (vm_offset_t)-1 ||
+ itlb_va_to_pa_sun4u(va) == (vm_offset_t)-1) {
+ /* Allocate a physical page, claim the virtual area. */
+ if (pa == (vm_offset_t)-1) {
+ pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M);
+ if (pa == (vm_offset_t)-1)
+ panic("%s: out of memory", __func__);
+ mva = claim_virt(va, PAGE_SIZE_4M, 0);
+ if (mva != va)
+ panic("%s: can't claim virtual page "
+ "(wanted %#lx, got %#lx)",
+ __func__, va, mva);
+ /*
+ * The mappings may have changed, be paranoid.
+ */
+ continue;
+ }
+ /*
+ * Actually, we can only allocate two pages less at
+ * most (depending on the kernel TSB size).
+ */
+ if (dtlb_slot >= dtlb_slot_max)
+ panic("%s: out of dtlb_slots", __func__);
+ if (itlb_slot >= itlb_slot_max)
+ panic("%s: out of itlb_slots", __func__);
+ data = TD_V | TD_4M | TD_PA(pa) | TD_L | TD_CP |
+ TD_CV | TD_P | TD_W;
+ dtlb_store[dtlb_slot].te_pa = pa;
+ dtlb_store[dtlb_slot].te_va = va;
+ index = dtlb_slot_max - dtlb_slot - 1;
+ if (dtlb_enter_sun4u(index, data, va) < 0)
+ panic("%s: can't enter dTLB slot %d data "
+ "%#lx va %#lx", __func__, index, data,
+ va);
+ dtlb_slot++;
+ itlb_store[itlb_slot].te_pa = pa;
+ itlb_store[itlb_slot].te_va = va;
+ index = itlb_slot_max - itlb_slot - 1;
+ if (itlb_enter_sun4u(index, data, va) < 0)
+ panic("%s: can't enter iTLB slot %d data "
+ "%#lx va %#lxd", __func__, index, data,
+ va);
+ itlb_slot++;
+ pa = (vm_offset_t)-1;
+ }
+ len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len;
+ va += PAGE_SIZE_4M;
+ }
+ if (pa != (vm_offset_t)-1)
+ release_phys(pa, PAGE_SIZE_4M);
+ return (0);
+}
+
+static vm_offset_t
+init_heap(void)
+{
+
+ /* There is no need for continuous physical heap memory. */
+ heapva = (vm_offset_t)OF_claim((void *)HEAPVA, HEAPSZ, 32);
+ return (heapva);
+}
+
+static phandle_t
+find_bsp_sun4u(phandle_t node, uint32_t bspid)
+{
+ char type[sizeof("cpu")];
+ phandle_t child;
+ uint32_t cpuid;
+
+ for (; node > 0; node = OF_peer(node)) {
+ child = OF_child(node);
+ if (child > 0) {
+ child = find_bsp_sun4u(child, bspid);
+ if (child > 0)
+ return (child);
+ } else {
+ if (OF_getprop(node, "device_type", type,
+ sizeof(type)) <= 0)
+ continue;
+ if (strcmp(type, "cpu") != 0)
+ continue;
+ if (OF_getprop(node, cpu_cpuid_prop_sun4u(), &cpuid,
+ sizeof(cpuid)) <= 0)
+ continue;
+ if (cpuid == bspid)
+ return (node);
+ }
+ }
+ return (0);
+}
+
+const char *
+cpu_cpuid_prop_sun4u(void)
+{
+
+ switch (cpu_impl) {
+ case CPU_IMPL_SPARC64:
+ case CPU_IMPL_SPARC64V:
+ case CPU_IMPL_ULTRASPARCI:
+ case CPU_IMPL_ULTRASPARCII:
+ case CPU_IMPL_ULTRASPARCIIi:
+ case CPU_IMPL_ULTRASPARCIIe:
+ return ("upa-portid");
+ case CPU_IMPL_ULTRASPARCIII:
+ case CPU_IMPL_ULTRASPARCIIIp:
+ case CPU_IMPL_ULTRASPARCIIIi:
+ case CPU_IMPL_ULTRASPARCIIIip:
+ return ("portid");
+ case CPU_IMPL_ULTRASPARCIV:
+ case CPU_IMPL_ULTRASPARCIVp:
+ return ("cpuid");
+ default:
+ return ("");
+ }
+}
+
+uint32_t
+cpu_get_mid_sun4u(void)
+{
+
+ switch (cpu_impl) {
+ case CPU_IMPL_SPARC64:
+ case CPU_IMPL_SPARC64V:
+ case CPU_IMPL_ULTRASPARCI:
+ case CPU_IMPL_ULTRASPARCII:
+ case CPU_IMPL_ULTRASPARCIIi:
+ case CPU_IMPL_ULTRASPARCIIe:
+ return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)));
+ case CPU_IMPL_ULTRASPARCIII:
+ case CPU_IMPL_ULTRASPARCIIIp:
+ return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG,
+ ASI_FIREPLANE_CONFIG_REG)));
+ case CPU_IMPL_ULTRASPARCIIIi:
+ case CPU_IMPL_ULTRASPARCIIIip:
+ return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG)));
+ case CPU_IMPL_ULTRASPARCIV:
+ case CPU_IMPL_ULTRASPARCIVp:
+ return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID)));
+ default:
+ return (0);
+ }
+}
+
+static void
+tlb_init_sun4u(void)
+{
+ phandle_t bsp;
+
+ cpu_impl = VER_IMPL(rdpr(ver));
+ switch (cpu_impl) {
+ case CPU_IMPL_SPARC64:
+ case CPU_IMPL_ULTRASPARCI:
+ case CPU_IMPL_ULTRASPARCII:
+ case CPU_IMPL_ULTRASPARCIIi:
+ case CPU_IMPL_ULTRASPARCIIe:
+ tlb_locked = TLB_DAR_T32;
+ break;
+ case CPU_IMPL_ULTRASPARCIII:
+ case CPU_IMPL_ULTRASPARCIIIp:
+ case CPU_IMPL_ULTRASPARCIIIi:
+ case CPU_IMPL_ULTRASPARCIIIip:
+ case CPU_IMPL_ULTRASPARCIV:
+ case CPU_IMPL_ULTRASPARCIVp:
+ tlb_locked = TLB_DAR_T16;
+ break;
+ case CPU_IMPL_SPARC64V:
+ tlb_locked = TLB_DAR_FTLB;
+ break;
+ }
+ bsp = find_bsp_sun4u(OF_child(root), cpu_get_mid_sun4u());
+ if (bsp == 0)
+ panic("%s: no node for bootcpu?!?!", __func__);
+
+ if (OF_getprop(bsp, "#dtlb-entries", &dtlb_slot_max,
+ sizeof(dtlb_slot_max)) == -1 ||
+ OF_getprop(bsp, "#itlb-entries", &itlb_slot_max,
+ sizeof(itlb_slot_max)) == -1)
+ panic("%s: can't get TLB slot max.", __func__);
+
+ if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) {
+#ifdef LOADER_DEBUG
+ printf("pre fixup:\n");
+ pmap_print_tlb_sun4u();
+#endif
+
+ /*
+ * Relocate the locked entry in it16 slot 0 (if existent)
+ * as part of working around Cheetah+ erratum 34.
+ */
+ itlb_relocate_locked0_sun4u();
+
+#ifdef LOADER_DEBUG
+ printf("post fixup:\n");
+ pmap_print_tlb_sun4u();
+#endif
+ }
+
+ dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store));
+ itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store));
+ if (dtlb_store == NULL || itlb_store == NULL)
+ panic("%s: can't allocate TLB store", __func__);
+}
+
+#ifdef LOADER_ZFS_SUPPORT
+static void
+sparc64_zfs_probe(void)
+{
+ struct vtoc8 vtoc;
+ char alias[64], devname[sizeof(alias) + sizeof(":x") - 1];
+ char type[sizeof("device_type")];
+ char *bdev, *dev, *odev;
+ uint64_t guid;
+ int fd, len, part;
+ phandle_t aliases, options;
+
+ /* Get the GUID of the ZFS pool on the boot device. */
+ guid = 0;
+ zfs_probe_dev(bootpath, &guid);
+
+ /*
+ * Get the GUIDs of the ZFS pools on any additional disks listed in
+ * the boot-device environment variable.
+ */
+ if ((aliases = OF_finddevice("/aliases")) == -1)
+ goto out;
+ options = OF_finddevice("/options");
+ len = OF_getproplen(options, "boot-device");
+ if (len <= 0)
+ goto out;
+ bdev = odev = malloc(len + 1);
+ if (bdev == NULL)
+ goto out;
+ if (OF_getprop(options, "boot-device", bdev, len) <= 0)
+ goto out;
+ bdev[len] = '\0';
+ while ((dev = strsep(&bdev, " ")) != NULL) {
+ if (*dev == '\0')
+ continue;
+ strcpy(alias, dev);
+ (void)OF_getprop(aliases, dev, alias, sizeof(alias));
+ /*
+ * Don't probe the boot disk twice. Note that bootpath
+ * includes the partition specifier.
+ */
+ if (strncmp(alias, bootpath, strlen(alias)) == 0)
+ continue;
+ if (OF_getprop(OF_finddevice(alias), "device_type", type,
+ sizeof(type)) == -1)
+ continue;
+ if (strcmp(type, "block") != 0)
+ continue;
+
+ /* Find freebsd-zfs slices in the VTOC. */
+ fd = open(alias, O_RDONLY);
+ if (fd == -1)
+ continue;
+ lseek(fd, 0, SEEK_SET);
+ if (read(fd, &vtoc, sizeof(vtoc)) != sizeof(vtoc)) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+
+ for (part = 0; part < 8; part++) {
+ if (part == 2 || vtoc.part[part].tag !=
+ VTOC_TAG_FREEBSD_ZFS)
+ continue;
+ (void)sprintf(devname, "%s:%c", alias, part + 'a');
+ if (zfs_probe_dev(devname, NULL) == ENXIO)
+ break;
+ }
+ }
+ free(odev);
+
+ out:
+ if (guid != 0) {
+ zfs_currdev.pool_guid = guid;
+ zfs_currdev.root_guid = 0;
+ zfs_currdev.d_dev = &zfs_dev;
+ zfs_currdev.d_type = zfs_currdev.d_dev->dv_type;
+ }
+}
+#endif /* LOADER_ZFS_SUPPORT */
+
+int
+main(int (*openfirm)(void *))
+{
+ char compatible[32];
+ struct devsw **dp;
+
+ /*
+ * Tell the Open Firmware functions where they find the OFW gate.
+ */
+ OF_init(openfirm);
+
+ archsw.arch_getdev = ofw_getdev;
+ archsw.arch_copyin = sparc64_copyin;
+ archsw.arch_copyout = ofw_copyout;
+ archsw.arch_readin = sparc64_readin;
+ archsw.arch_autoload = sparc64_autoload;
+#ifdef LOADER_ZFS_SUPPORT
+ archsw.arch_zfs_probe = sparc64_zfs_probe;
+#endif
+
+ if (init_heap() == (vm_offset_t)-1)
+ OF_exit();
+ setheap((void *)heapva, (void *)(heapva + HEAPSZ));
+
+ /*
+ * Probe for a console.
+ */
+ cons_probe();
+
+ if ((root = OF_peer(0)) == -1)
+ panic("%s: can't get root phandle", __func__);
+ OF_getprop(root, "compatible", compatible, sizeof(compatible));
+ mmu_ops = &mmu_ops_sun4u;
+
+ mmu_ops->tlb_init();
+
+ /*
+ * Set up the current device.
+ */
+ OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath));
+
+ /*
+ * Initialize devices.
+ */
+ for (dp = devsw; *dp != 0; dp++)
+ if ((*dp)->dv_init != 0)
+ (*dp)->dv_init();
+
+#ifdef LOADER_ZFS_SUPPORT
+ if (zfs_currdev.pool_guid != 0) {
+ (void)strncpy(bootpath, zfs_fmtdev(&zfs_currdev),
+ sizeof(bootpath) - 1);
+ bootpath[sizeof(bootpath) - 1] = '\0';
+ } else
+#endif
+
+ /*
+ * Sun compatible bootable CD-ROMs have a disk label placed before
+ * the ISO 9660 data, with the actual file system being in the first
+ * partition, while the other partitions contain pseudo disk labels
+ * with embedded boot blocks for different architectures, which may
+ * be followed by UFS file systems.
+ * The firmware will set the boot path to the partition it boots from
+ * ('f' in the sun4u/sun4v case), but we want the kernel to be loaded
+ * from the ISO 9660 file system ('a'), so the boot path needs to be
+ * altered.
+ */
+ if (bootpath[strlen(bootpath) - 2] == ':' &&
+ bootpath[strlen(bootpath) - 1] == 'f')
+ bootpath[strlen(bootpath) - 1] = 'a';
+
+ env_setenv("currdev", EV_VOLATILE, bootpath,
+ ofw_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, bootpath,
+ env_noset, env_nounset);
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+ printf("bootpath=\"%s\"\n", bootpath);
+
+ /* Give control to the machine independent loader code. */
+ interact(NULL);
+ return (1);
+}
+
+COMMAND_SET(heap, "heap", "show heap usage", command_heap);
+
+static int
+command_heap(int argc, char *argv[])
+{
+
+ mallocstats();
+ printf("heap base at %p, top at %p, upper limit at %p\n", heapva,
+ sbrk(0), heapva + HEAPSZ);
+ return(CMD_OK);
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+
+ printf("Rebooting...\n");
+ OF_exit();
+}
+
+/* provide this for panic, as it's not in the startup code */
+void
+exit(int code)
+{
+
+ OF_exit();
+}
+
+#ifdef LOADER_DEBUG
+static const char *const page_sizes[] = {
+ " 8k", " 64k", "512k", " 4m"
+};
+
+static void
+pmap_print_tte_sun4u(tte_t tag, tte_t tte)
+{
+
+ printf("%s %s ",
+ page_sizes[(tte >> TD_SIZE_SHIFT) & TD_SIZE_MASK],
+ tag & TD_G ? "G" : " ");
+ printf(tte & TD_W ? "W " : " ");
+ printf(tte & TD_P ? "\e[33mP\e[0m " : " ");
+ printf(tte & TD_E ? "E " : " ");
+ printf(tte & TD_CV ? "CV " : " ");
+ printf(tte & TD_CP ? "CP " : " ");
+ printf(tte & TD_L ? "\e[32mL\e[0m " : " ");
+ printf(tte & TD_IE ? "IE " : " ");
+ printf(tte & TD_NFO ? "NFO " : " ");
+ printf("pa=0x%lx va=0x%lx ctx=%ld\n",
+ TD_PA(tte), TLB_TAR_VA(tag), TLB_TAR_CTX(tag));
+}
+
+static void
+pmap_print_tlb_sun4u(void)
+{
+ tte_t tag, tte;
+ u_long pstate;
+ int i;
+
+ pstate = rdpr(pstate);
+ for (i = 0; i < itlb_slot_max; i++) {
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ tte = itlb_get_data_sun4u(tlb_locked, i);
+ wrpr(pstate, pstate, 0);
+ if (!(tte & TD_V))
+ continue;
+ tag = ldxa(TLB_DAR_SLOT(tlb_locked, i),
+ ASI_ITLB_TAG_READ_REG);
+ printf("iTLB-%2u: ", i);
+ pmap_print_tte_sun4u(tag, tte);
+ }
+ for (i = 0; i < dtlb_slot_max; i++) {
+ wrpr(pstate, pstate & ~PSTATE_IE, 0);
+ tte = dtlb_get_data_sun4u(tlb_locked, i);
+ wrpr(pstate, pstate, 0);
+ if (!(tte & TD_V))
+ continue;
+ tag = ldxa(TLB_DAR_SLOT(tlb_locked, i),
+ ASI_DTLB_TAG_READ_REG);
+ printf("dTLB-%2u: ", i);
+ pmap_print_tte_sun4u(tag, tte);
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/boot/sparc64/loader/metadata.c b/usr/src/boot/sys/boot/sparc64/loader/metadata.c
new file mode 100644
index 0000000000..a3b3eb5ced
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/metadata.c
@@ -0,0 +1,345 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: FreeBSD: src/sys/boot/i386/libi386/bootinfo.c,v 1.29
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+
+#include <machine/metadata.h>
+
+#include "bootstrap.h"
+#include "libofw.h"
+
+extern struct tlb_entry *dtlb_store;
+extern struct tlb_entry *itlb_store;
+
+extern int dtlb_slot;
+extern int itlb_slot;
+
+static int md_bootserial(void);
+
+int
+md_getboothowto(char *kargs)
+{
+ char *cp;
+ int howto;
+ int active;
+ int i;
+
+ /* Parse kargs */
+ howto = 0;
+ if (kargs != NULL) {
+ cp = kargs;
+ active = 0;
+ while (*cp != 0) {
+ if (!active && (*cp == '-')) {
+ active = 1;
+ } else if (active)
+ switch (*cp) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'C':
+ howto |= RB_CDROM;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'g':
+ howto |= RB_GDB;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ default:
+ active = 0;
+ break;
+ }
+ cp++;
+ }
+ }
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ if (md_bootserial() != -1)
+ howto |= RB_SERIAL;
+ return(howto);
+}
+
+static int
+md_bootserial(void)
+{
+ char buf[64];
+ ihandle_t inst;
+ phandle_t input;
+ phandle_t node;
+ phandle_t output;
+
+ if ((node = OF_finddevice("/options")) == -1)
+ return(-1);
+ if (OF_getprop(node, "input-device", buf, sizeof(buf)) == -1)
+ return(-1);
+ input = OF_finddevice(buf);
+ if (OF_getprop(node, "output-device", buf, sizeof(buf)) == -1)
+ return(-1);
+ output = OF_finddevice(buf);
+ if (input == -1 || output == -1 || OF_getproplen(input, "keyboard") >= 0) {
+ if ((node = OF_finddevice("/chosen")) == -1)
+ return(-1);
+ if (OF_getprop(node, "stdin", &inst, sizeof(inst)) == -1)
+ return(-1);
+ if ((input = OF_instance_to_package(inst)) == -1)
+ return(-1);
+ if (OF_getprop(node, "stdout", &inst, sizeof(inst)) == -1)
+ return(-1);
+ if ((output = OF_instance_to_package(inst)) == -1)
+ return(-1);
+ }
+ if (input != output)
+ return(-1);
+ if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
+ return(-1);
+ if (strcmp(buf, "serial") != 0)
+ return(-1);
+ return(0);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+md_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ archsw.arch_copyin("=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ return(addr);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ archsw.arch_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c) \
+ if (c) \
+ archsw.arch_copyin(s, a, strlen(s) + 1);\
+ a += roundup(strlen(s) + 1, sizeof(u_long));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ archsw.arch_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_long)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c);\
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ archsw.arch_copyin(mm->md_data, a, mm->md_size);\
+ a += roundup(mm->md_size, sizeof(u_long)); \
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+vm_offset_t
+md_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ MOD_ADDR(addr, fp->f_addr, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ if (!(md->md_type & MODINFOMD_NOCOPY)) {
+ MOD_METADATA(addr, md, c);
+ }
+ }
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Load the information expected by a sparc64 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtbp)
+{
+ struct preloaded_file *kfp;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ vm_offset_t kernend;
+ vm_offset_t addr;
+ vm_offset_t envp;
+ vm_offset_t size;
+ char *rootdevname;
+ int howto;
+
+ howto = md_getboothowto(args);
+ *dtbp = 0;
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ if ((rootdevname = getenv("rootdev")) == NULL)
+ rootdevname = getenv("currdev");
+ getrootmount(rootdevname);
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* copy our environment */
+ envp = addr;
+ addr = md_copyenv(addr);
+
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kernend = 0;
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS, sizeof dtlb_slot, &dtlb_slot);
+ file_addmetadata(kfp, MODINFOMD_ITLB_SLOTS, sizeof itlb_slot, &itlb_slot);
+ file_addmetadata(kfp, MODINFOMD_DTLB,
+ dtlb_slot * sizeof(*dtlb_store), dtlb_store);
+ file_addmetadata(kfp, MODINFOMD_ITLB,
+ itlb_slot * sizeof(*itlb_store), itlb_store);
+
+ *modulep = addr;
+ size = md_copymodules(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ (void)md_copymodules(addr);
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/sparc64/loader/version b/usr/src/boot/sys/boot/sparc64/loader/version
new file mode 100644
index 0000000000..bef4091e58
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/loader/version
@@ -0,0 +1,6 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.0: I hate the loader.
diff --git a/usr/src/boot/sys/boot/sparc64/zfsboot/Makefile b/usr/src/boot/sys/boot/sparc64/zfsboot/Makefile
new file mode 100644
index 0000000000..9e58c27eb0
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/zfsboot/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../boot1
+
+PROGNAME= zfsboot
+CFLAGS+= -DZFSBOOT
+FILES= zfsboot
+
+.include "${.CURDIR}/../boot1/Makefile"
diff --git a/usr/src/boot/sys/boot/sparc64/zfsloader/Makefile b/usr/src/boot/sys/boot/sparc64/zfsloader/Makefile
new file mode 100644
index 0000000000..1ed2808292
--- /dev/null
+++ b/usr/src/boot/sys/boot/sparc64/zfsloader/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../loader
+
+PROG= zfsloader
+NEWVERSWHAT= "ZFS enabled bootstrap loader" sparc64
+LOADER_ZFS_SUPPORT=yes
+
+.include "${.CURDIR}/../loader/Makefile"
diff --git a/usr/src/boot/sys/boot/uboot/Makefile b/usr/src/boot/sys/boot/uboot/Makefile
new file mode 100644
index 0000000000..43b57480fe
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+SUBDIR= lib
+
+.if ${MK_FDT} != "no"
+SUBDIR+=fdt
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/usr/src/boot/sys/boot/uboot/Makefile.inc b/usr/src/boot/sys/boot/uboot/Makefile.inc
new file mode 100644
index 0000000000..e67c0dc904
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/Makefile.inc
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc
+LDFLAGS+= -m elf32ppc_fbsd
+.endif
+
+.include "../Makefile.inc"
diff --git a/usr/src/boot/sys/boot/uboot/common/Makefile.inc b/usr/src/boot/sys/boot/uboot/common/Makefile.inc
new file mode 100644
index 0000000000..e12804cb39
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/common/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+SRCS+= main.c metadata.c
diff --git a/usr/src/boot/sys/boot/uboot/common/main.c b/usr/src/boot/sys/boot/uboot/common/main.c
new file mode 100644
index 0000000000..f4fe214e7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/common/main.c
@@ -0,0 +1,680 @@
+/*-
+ * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
+ * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
+ * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
+#include <stand.h>
+
+#include "api_public.h"
+#include "bootstrap.h"
+#include "glue.h"
+#include "libuboot.h"
+
+#ifndef nitems
+#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
+#endif
+
+struct uboot_devdesc currdev;
+struct arch_switch archsw; /* MI/MD interface boundary */
+int devs_no;
+
+uintptr_t uboot_heap_start;
+uintptr_t uboot_heap_end;
+
+struct device_type {
+ const char *name;
+ int type;
+} device_types[] = {
+ { "disk", DEV_TYP_STOR },
+ { "ide", DEV_TYP_STOR | DT_STOR_IDE },
+ { "mmc", DEV_TYP_STOR | DT_STOR_MMC },
+ { "sata", DEV_TYP_STOR | DT_STOR_SATA },
+ { "scsi", DEV_TYP_STOR | DT_STOR_SCSI },
+ { "usb", DEV_TYP_STOR | DT_STOR_USB },
+ { "net", DEV_TYP_NET }
+};
+
+extern char end[];
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+extern unsigned char _etext[];
+extern unsigned char _edata[];
+extern unsigned char __bss_start[];
+extern unsigned char __sbss_start[];
+extern unsigned char __sbss_end[];
+extern unsigned char _end[];
+
+#ifdef LOADER_FDT_SUPPORT
+extern int command_fdt_internal(int argc, char *argv[]);
+#endif
+
+static void
+dump_sig(struct api_signature *sig)
+{
+#ifdef DEBUG
+ printf("signature:\n");
+ printf(" version\t= %d\n", sig->version);
+ printf(" checksum\t= 0x%08x\n", sig->checksum);
+ printf(" sc entry\t= 0x%08x\n", sig->syscall);
+#endif
+}
+
+static void
+dump_addr_info(void)
+{
+#ifdef DEBUG
+ printf("\naddresses info:\n");
+ printf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
+ printf(" _edata = 0x%08x\n", (uint32_t)_edata);
+ printf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start);
+ printf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end);
+ printf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start);
+ printf(" _end = 0x%08x\n", (uint32_t)_end);
+ printf(" syscall entry = 0x%08x\n", (uint32_t)syscall_ptr);
+#endif
+}
+
+static uint64_t
+memsize(struct sys_info *si, int flags)
+{
+ uint64_t size;
+ int i;
+
+ size = 0;
+ for (i = 0; i < si->mr_no; i++)
+ if (si->mr[i].flags == flags && si->mr[i].size)
+ size += (si->mr[i].size);
+
+ return (size);
+}
+
+static void
+meminfo(void)
+{
+ uint64_t size;
+ struct sys_info *si;
+ int t[3] = { MR_ATTR_DRAM, MR_ATTR_FLASH, MR_ATTR_SRAM };
+ int i;
+
+ if ((si = ub_get_sys_info()) == NULL)
+ panic("could not retrieve system info");
+
+ for (i = 0; i < 3; i++) {
+ size = memsize(si, t[i]);
+ if (size > 0)
+ printf("%s: %juMB\n", ub_mem_type(t[i]),
+ (uintmax_t)(size / 1024 / 1024));
+ }
+}
+
+static const char *
+get_device_type(const char *devstr, int *devtype)
+{
+ int i;
+ int namelen;
+ struct device_type *dt;
+
+ if (devstr) {
+ for (i = 0; i < nitems(device_types); i++) {
+ dt = &device_types[i];
+ namelen = strlen(dt->name);
+ if (strncmp(dt->name, devstr, namelen) == 0) {
+ *devtype = dt->type;
+ return (devstr + namelen);
+ }
+ }
+ printf("Unknown device type '%s'\n", devstr);
+ }
+
+ *devtype = -1;
+ return (NULL);
+}
+
+static const char *
+device_typename(int type)
+{
+ int i;
+
+ for (i = 0; i < nitems(device_types); i++)
+ if (device_types[i].type == type)
+ return (device_types[i].name);
+
+ return ("<unknown>");
+}
+
+/*
+ * Parse a device string into type, unit, slice and partition numbers. A
+ * returned value of -1 for type indicates a search should be done for the
+ * first loadable device, otherwise a returned value of -1 for unit
+ * indicates a search should be done for the first loadable device of the
+ * given type.
+ *
+ * The returned values for slice and partition are interpreted by
+ * disk_open().
+ *
+ * Valid device strings: For device types:
+ *
+ * <type_name> DEV_TYP_STOR, DEV_TYP_NET
+ * <type_name><unit> DEV_TYP_STOR, DEV_TYP_NET
+ * <type_name><unit>: DEV_TYP_STOR, DEV_TYP_NET
+ * <type_name><unit>:<slice> DEV_TYP_STOR
+ * <type_name><unit>:<slice>. DEV_TYP_STOR
+ * <type_name><unit>:<slice>.<partition> DEV_TYP_STOR
+ *
+ * For valid type names, see the device_types array, above.
+ *
+ * Slice numbers are 1-based. 0 is a wildcard.
+ */
+static void
+get_load_device(int *type, int *unit, int *slice, int *partition)
+{
+ char *devstr;
+ const char *p;
+ char *endp;
+
+ *type = -1;
+ *unit = -1;
+ *slice = 0;
+ *partition = -1;
+
+ devstr = ub_env_get("loaderdev");
+ if (devstr == NULL) {
+ printf("U-Boot env: loaderdev not set, will probe all devices.\n");
+ return;
+ }
+ printf("U-Boot env: loaderdev='%s'\n", devstr);
+
+ p = get_device_type(devstr, type);
+
+ /* Ignore optional spaces after the device name. */
+ while (*p == ' ')
+ p++;
+
+ /* Unknown device name, or a known name without unit number. */
+ if ((*type == -1) || (*p == '\0')) {
+ return;
+ }
+
+ /* Malformed unit number. */
+ if (!isdigit(*p)) {
+ *type = -1;
+ return;
+ }
+
+ /* Guaranteed to extract a number from the string, as *p is a digit. */
+ *unit = strtol(p, &endp, 10);
+ p = endp;
+
+ /* Known device name with unit number and nothing else. */
+ if (*p == '\0') {
+ return;
+ }
+
+ /* Device string is malformed beyond unit number. */
+ if (*p != ':') {
+ *type = -1;
+ *unit = -1;
+ return;
+ }
+
+ p++;
+
+ /* No slice and partition specification. */
+ if ('\0' == *p )
+ return;
+
+ /* Only DEV_TYP_STOR devices can have a slice specification. */
+ if (!(*type & DEV_TYP_STOR)) {
+ *type = -1;
+ *unit = -1;
+ return;
+ }
+
+ *slice = strtoul(p, &endp, 10);
+
+ /* Malformed slice number. */
+ if (p == endp) {
+ *type = -1;
+ *unit = -1;
+ *slice = 0;
+ return;
+ }
+
+ p = endp;
+
+ /* No partition specification. */
+ if (*p == '\0')
+ return;
+
+ /* Device string is malformed beyond slice number. */
+ if (*p != '.') {
+ *type = -1;
+ *unit = -1;
+ *slice = 0;
+ return;
+ }
+
+ p++;
+
+ /* No partition specification. */
+ if (*p == '\0')
+ return;
+
+ *partition = strtol(p, &endp, 10);
+ p = endp;
+
+ /* Full, valid device string. */
+ if (*endp == '\0')
+ return;
+
+ /* Junk beyond partition number. */
+ *type = -1;
+ *unit = -1;
+ *slice = 0;
+ *partition = -1;
+}
+
+static void
+print_disk_probe_info()
+{
+ char slice[32];
+ char partition[32];
+
+ if (currdev.d_disk.slice > 0)
+ sprintf(slice, "%d", currdev.d_disk.slice);
+ else
+ strcpy(slice, "<auto>");
+
+ if (currdev.d_disk.partition >= 0)
+ sprintf(partition, "%d", currdev.d_disk.partition);
+ else
+ strcpy(partition, "<auto>");
+
+ printf(" Checking unit=%d slice=%s partition=%s...",
+ currdev.d_unit, slice, partition);
+
+}
+
+static int
+probe_disks(int devidx, int load_type, int load_unit, int load_slice,
+ int load_partition)
+{
+ int open_result, unit;
+ struct open_file f;
+
+ currdev.d_disk.slice = load_slice;
+ currdev.d_disk.partition = load_partition;
+
+ f.f_devdata = &currdev;
+ open_result = -1;
+
+ if (load_type == -1) {
+ printf(" Probing all disk devices...\n");
+ /* Try each disk in succession until one works. */
+ for (currdev.d_unit = 0; currdev.d_unit < UB_MAX_DEV;
+ currdev.d_unit++) {
+ print_disk_probe_info();
+ open_result = devsw[devidx]->dv_open(&f, &currdev);
+ if (open_result == 0) {
+ printf(" good.\n");
+ return (0);
+ }
+ printf("\n");
+ }
+ return (-1);
+ }
+
+ if (load_unit == -1) {
+ printf(" Probing all %s devices...\n", device_typename(load_type));
+ /* Try each disk of given type in succession until one works. */
+ for (unit = 0; unit < UB_MAX_DEV; unit++) {
+ currdev.d_unit = uboot_diskgetunit(load_type, unit);
+ if (currdev.d_unit == -1)
+ break;
+ print_disk_probe_info();
+ open_result = devsw[devidx]->dv_open(&f, &currdev);
+ if (open_result == 0) {
+ printf(" good.\n");
+ return (0);
+ }
+ printf("\n");
+ }
+ return (-1);
+ }
+
+ if ((currdev.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) {
+ print_disk_probe_info();
+ open_result = devsw[devidx]->dv_open(&f,&currdev);
+ if (open_result == 0) {
+ printf(" good.\n");
+ return (0);
+ }
+ printf("\n");
+ }
+
+ printf(" Requested disk type/unit/slice/partition not found\n");
+ return (-1);
+}
+
+int
+main(void)
+{
+ struct api_signature *sig = NULL;
+ int load_type, load_unit, load_slice, load_partition;
+ int i;
+ const char *ldev;
+
+ /*
+ * If we can't find the magic signature and related info, exit with a
+ * unique error code that U-Boot reports as "## Application terminated,
+ * rc = 0xnnbadab1". Hopefully 'badab1' looks enough like "bad api" to
+ * provide a clue. It's better than 0xffffffff anyway.
+ */
+ if (!api_search_sig(&sig))
+ return (0x01badab1);
+
+ syscall_ptr = sig->syscall;
+ if (syscall_ptr == NULL)
+ return (0x02badab1);
+
+ if (sig->version > API_SIG_VERSION)
+ return (0x03badab1);
+
+ /* Clear BSS sections */
+ bzero(__sbss_start, __sbss_end - __sbss_start);
+ bzero(__bss_start, _end - __bss_start);
+
+ /*
+ * Initialise the heap as early as possible. Once this is done,
+ * alloc() is usable. The stack is buried inside us, so this is safe.
+ */
+ uboot_heap_start = round_page((uintptr_t)end);
+ uboot_heap_end = uboot_heap_start + 512 * 1024;
+ setheap((void *)uboot_heap_start, (void *)uboot_heap_end);
+
+ /*
+ * Set up console.
+ */
+ cons_probe();
+ printf("Compatible U-Boot API signature found @%p\n", sig);
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+ printf("\n");
+
+ dump_sig(sig);
+ dump_addr_info();
+
+ meminfo();
+
+ /*
+ * Enumerate U-Boot devices
+ */
+ if ((devs_no = ub_dev_enum()) == 0)
+ panic("no U-Boot devices found");
+ printf("Number of U-Boot devices: %d\n", devs_no);
+
+ get_load_device(&load_type, &load_unit, &load_slice, &load_partition);
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++) {
+
+ if (devsw[i]->dv_init == NULL)
+ continue;
+ if ((devsw[i]->dv_init)() != 0)
+ continue;
+
+ printf("Found U-Boot device: %s\n", devsw[i]->dv_name);
+
+ currdev.d_dev = devsw[i];
+ currdev.d_type = currdev.d_dev->dv_type;
+ currdev.d_unit = 0;
+
+ if ((load_type == -1 || (load_type & DEV_TYP_STOR)) &&
+ strcmp(devsw[i]->dv_name, "disk") == 0) {
+ if (probe_disks(i, load_type, load_unit, load_slice,
+ load_partition) == 0)
+ break;
+ }
+
+ if ((load_type == -1 || (load_type & DEV_TYP_NET)) &&
+ strcmp(devsw[i]->dv_name, "net") == 0)
+ break;
+ }
+
+ /*
+ * If we couldn't find a boot device, return an error to u-boot.
+ * U-boot may be running a boot script that can try something different
+ * so returning an error is better than forcing a reboot.
+ */
+ if (devsw[i] == NULL) {
+ printf("No boot device found!\n");
+ return (0xbadef1ce);
+ }
+
+ ldev = uboot_fmtdev(&currdev);
+ env_setenv("currdev", EV_VOLATILE, ldev, uboot_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, ldev, env_noset, env_nounset);
+ printf("Booting from %s\n", ldev);
+
+ setenv("LINES", "24", 1); /* optional */
+ setenv("prompt", "loader>", 1);
+
+ archsw.arch_loadaddr = uboot_loadaddr;
+ archsw.arch_getdev = uboot_getdev;
+ archsw.arch_copyin = uboot_copyin;
+ archsw.arch_copyout = uboot_copyout;
+ archsw.arch_readin = uboot_readin;
+ archsw.arch_autoload = uboot_autoload;
+
+ interact(NULL); /* doesn't return */
+
+ return (0);
+}
+
+
+COMMAND_SET(heap, "heap", "show heap usage", command_heap);
+static int
+command_heap(int argc, char *argv[])
+{
+
+ printf("heap base at %p, top at %p, used %td\n", end, sbrk(0),
+ sbrk(0) - end);
+
+ return (CMD_OK);
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+static int
+command_reboot(int argc, char *argv[])
+{
+
+ printf("Resetting...\n");
+ ub_reset();
+
+ printf("Reset failed!\n");
+ while(1);
+}
+
+COMMAND_SET(devinfo, "devinfo", "show U-Boot devices", command_devinfo);
+static int
+command_devinfo(int argc, char *argv[])
+{
+ int i;
+
+ if ((devs_no = ub_dev_enum()) == 0) {
+ command_errmsg = "no U-Boot devices found!?";
+ return (CMD_ERROR);
+ }
+
+ printf("U-Boot devices:\n");
+ for (i = 0; i < devs_no; i++) {
+ ub_dump_di(i);
+ printf("\n");
+ }
+ return (CMD_OK);
+}
+
+COMMAND_SET(sysinfo, "sysinfo", "show U-Boot system info", command_sysinfo);
+static int
+command_sysinfo(int argc, char *argv[])
+{
+ struct sys_info *si;
+
+ if ((si = ub_get_sys_info()) == NULL) {
+ command_errmsg = "could not retrieve U-Boot sys info!?";
+ return (CMD_ERROR);
+ }
+
+ printf("U-Boot system info:\n");
+ ub_dump_si(si);
+ return (CMD_OK);
+}
+
+enum ubenv_action {
+ UBENV_UNKNOWN,
+ UBENV_SHOW,
+ UBENV_IMPORT
+};
+
+static void
+handle_uboot_env_var(enum ubenv_action action, const char * var)
+{
+ char ldvar[128];
+ const char *val;
+ char *wrk;
+ int len;
+
+ /*
+ * On an import with the variable name formatted as ldname=ubname,
+ * import the uboot variable ubname into the loader variable ldname,
+ * otherwise the historical behavior is to import to uboot.ubname.
+ */
+ if (action == UBENV_IMPORT) {
+ len = strcspn(var, "=");
+ if (len == 0) {
+ printf("name cannot start with '=': '%s'\n", var);
+ return;
+ }
+ if (var[len] == 0) {
+ strcpy(ldvar, "uboot.");
+ strncat(ldvar, var, sizeof(ldvar) - 7);
+ } else {
+ len = MIN(len, sizeof(ldvar) - 1);
+ strncpy(ldvar, var, len);
+ ldvar[len] = 0;
+ var = &var[len + 1];
+ }
+ }
+
+ /*
+ * If the user prepended "uboot." (which is how they usually see these
+ * names) strip it off as a convenience.
+ */
+ if (strncmp(var, "uboot.", 6) == 0) {
+ var = &var[6];
+ }
+
+ /* If there is no variable name left, punt. */
+ if (var[0] == 0) {
+ printf("empty variable name\n");
+ return;
+ }
+
+ val = ub_env_get(var);
+ if (action == UBENV_SHOW) {
+ if (val == NULL)
+ printf("uboot.%s is not set\n", var);
+ else
+ printf("uboot.%s=%s\n", var, val);
+ } else if (action == UBENV_IMPORT) {
+ if (val != NULL) {
+ setenv(ldvar, val, 1);
+ }
+ }
+}
+
+static int
+command_ubenv(int argc, char *argv[])
+{
+ enum ubenv_action action;
+ const char *var;
+ int i;
+
+ action = UBENV_UNKNOWN;
+ if (argc > 1) {
+ if (strcasecmp(argv[1], "import") == 0)
+ action = UBENV_IMPORT;
+ else if (strcasecmp(argv[1], "show") == 0)
+ action = UBENV_SHOW;
+ }
+ if (action == UBENV_UNKNOWN) {
+ command_errmsg = "usage: 'ubenv <import|show> [var ...]";
+ return (CMD_ERROR);
+ }
+
+ if (argc > 2) {
+ for (i = 2; i < argc; i++)
+ handle_uboot_env_var(action, argv[i]);
+ } else {
+ var = NULL;
+ for (;;) {
+ if ((var = ub_env_enum(var)) == NULL)
+ break;
+ handle_uboot_env_var(action, var);
+ }
+ }
+
+ return (CMD_OK);
+}
+COMMAND_SET(ubenv, "ubenv", "show or import U-Boot env vars", command_ubenv);
+
+#ifdef LOADER_FDT_SUPPORT
+/*
+ * Since proper fdt command handling function is defined in fdt_loader_cmd.c,
+ * and declaring it as extern is in contradiction with COMMAND_SET() macro
+ * (which uses static pointer), we're defining wrapper function, which
+ * calls the proper fdt handling routine.
+ */
+static int
+command_fdt(int argc, char *argv[])
+{
+
+ return (command_fdt_internal(argc, argv));
+}
+
+COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
+#endif
diff --git a/usr/src/boot/sys/boot/uboot/common/metadata.c b/usr/src/boot/sys/boot/uboot/common/metadata.c
new file mode 100644
index 0000000000..c00b56006d
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/common/metadata.c
@@ -0,0 +1,366 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (C) 2006 Semihalf, Piotr Kruszynski <ppk@semihalf.com>
+ * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+
+#include <machine/elf.h>
+#include <machine/metadata.h>
+
+#include "api_public.h"
+#include "bootstrap.h"
+#include "glue.h"
+
+#if defined(LOADER_FDT_SUPPORT)
+#include <fdt_platform.h>
+#endif
+
+static int
+md_getboothowto(char *kargs)
+{
+ char *cp;
+ char *p;
+ int howto;
+ int active;
+ int i;
+
+ /* Parse kargs */
+ howto = 0;
+ if (kargs != NULL) {
+ cp = kargs;
+ active = 0;
+ while (*cp != 0) {
+ if (!active && (*cp == '-'))
+ active = 1;
+ else if (active)
+ switch (*cp) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'C':
+ howto |= RB_CDROM;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'g':
+ howto |= RB_GDB;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ default:
+ active = 0;
+ break;
+ }
+ cp++;
+ }
+ }
+
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+ if ((p = getenv("console"))) {
+ if (!strcmp(p, "comconsole"))
+ howto |= RB_SERIAL;
+ if (!strcmp(p, "nullconsole"))
+ howto |= RB_MUTE;
+ }
+
+ return(howto);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+static vm_offset_t
+md_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ archsw.arch_copyin("=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ archsw.arch_copyin(ep->ev_value, addr,
+ strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ return(addr);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ archsw.arch_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c) \
+ if (c) \
+ archsw.arch_copyin(s, a, strlen(s) + 1);\
+ a += roundup(strlen(s) + 1, sizeof(u_long));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ archsw.arch_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_long)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c);\
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ archsw.arch_copyin(mm->md_data, a, mm->md_size);\
+ a += roundup(mm->md_size, sizeof(u_long)); \
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+md_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+ vm_offset_t a;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must be first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ a = fp->f_addr - __elfN(relocation_offset);
+ MOD_ADDR(addr, a, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Load the information expected by a kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+md_load(char *args, vm_offset_t *modulep)
+{
+ struct preloaded_file *kfp, *bfp;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ struct bootinfo *bip;
+ vm_offset_t kernend;
+ vm_offset_t addr;
+ vm_offset_t envp;
+ vm_offset_t size;
+ vm_offset_t vaddr;
+#if defined(LOADER_FDT_SUPPORT)
+ vm_offset_t dtbp;
+ int dtb_size;
+#endif
+ char *rootdevname;
+ int howto;
+ int i;
+
+ /*
+ * These metadata addreses must be converted for kernel after
+ * relocation.
+ */
+ uint32_t mdt[] = {
+ MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND,
+ MODINFOMD_ENVP,
+#if defined(LOADER_FDT_SUPPORT)
+ MODINFOMD_DTBP
+#endif
+ };
+
+ howto = md_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied
+ * device. This should perhaps go to MI code and/or have $rootdev
+ * tested/set by MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ if (rootdevname == NULL)
+ rootdevname = getenv("currdev");
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(rootdevname);
+
+ /* Find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* Pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* Copy our environment */
+ envp = addr;
+ addr = md_copyenv(addr);
+
+ /* Pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+#if defined(LOADER_FDT_SUPPORT)
+ /* Handle device tree blob */
+ dtbp = addr;
+ dtb_size = fdt_copy(addr);
+
+ /* Pad to a page boundary */
+ if (dtb_size)
+ addr += roundup(dtb_size, PAGE_SIZE);
+#endif
+
+ kernend = 0;
+ kfp = file_findfile(NULL, "elf32 kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+
+#if defined(LOADER_FDT_SUPPORT)
+ if (dtb_size)
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp);
+ else
+ pager_output("WARNING! Trying to fire up the kernel, but no "
+ "device tree blob found!\n");
+#endif
+
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+
+ /* Figure out the size and location of the metadata */
+ *modulep = addr;
+ size = md_copymodules(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+
+ /* Provide MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* Convert addresses to the final VA */
+ *modulep -= __elfN(relocation_offset);
+
+ /* Do relocation fixup on metadata of each module. */
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ for (i = 0; i < sizeof mdt / sizeof mdt[0]; i++) {
+ md = file_findmetadata(xp, mdt[i]);
+ if (md) {
+ bcopy(md->md_data, &vaddr, sizeof vaddr);
+ vaddr -= __elfN(relocation_offset);
+ bcopy(&vaddr, md->md_data, sizeof vaddr);
+ }
+ }
+ }
+
+ /* Only now copy actual modules and metadata */
+ (void)md_copymodules(addr);
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/uboot/fdt/Makefile b/usr/src/boot/sys/boot/uboot/fdt/Makefile
new file mode 100644
index 0000000000..6f68665cc6
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/fdt/Makefile
@@ -0,0 +1,34 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+.PATH: ${.CURDIR}/../../common
+
+LIB= uboot_fdt
+INTERNALLIB=
+WARNS?= 2
+
+SRCS= uboot_fdt.c
+
+CFLAGS+= -ffreestanding -msoft-float
+
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+# U-Boot library headers
+CFLAGS+= -I${.CURDIR}/../lib
+
+# libfdt headers
+CFLAGS+= -I${.CURDIR}/../../fdt
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+
+machine:
+ ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine
+
+CLEANFILES+= machine
+
+.include <bsd.stand.mk>
+.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/usr/src/boot/sys/boot/uboot/fdt/uboot_fdt.c b/usr/src/boot/sys/boot/uboot/fdt/uboot_fdt.c
new file mode 100644
index 0000000000..6b646f63dc
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/fdt/uboot_fdt.c
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2009-2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <stand.h>
+#include <fdt_platform.h>
+
+#include "glue.h"
+
+#define STR(number) #number
+#define STRINGIFY(number) STR(number)
+
+int
+fdt_platform_load_dtb(void)
+{
+ struct fdt_header *hdr;
+ const char *s;
+ char *p;
+
+ /*
+ * If the U-boot environment contains a variable giving the address of a
+ * valid blob in memory, use it. The U-boot README says the right
+ * variable for fdt data loaded into ram is fdt_addr_r, so try that
+ * first. Board vendors also use both fdtaddr and fdt_addr names.
+ */
+ s = ub_env_get("fdt_addr_r");
+ if (s == NULL)
+ s = ub_env_get("fdtaddr");
+ if (s == NULL)
+ s = ub_env_get("fdt_addr");
+ if (s != NULL && *s != '\0') {
+ hdr = (struct fdt_header *)strtoul(s, &p, 16);
+ if (*p == '\0') {
+ if (fdt_load_dtb_addr(hdr) == 0) {
+ printf("Using DTB provided by U-Boot at "
+ "address %p.\n", hdr);
+ return (0);
+ }
+ }
+ }
+
+ /*
+ * Try to get FDT filename first from loader env and then from u-boot env
+ */
+ s = getenv("fdt_file");
+ if (s == NULL)
+ s = ub_env_get("fdtfile");
+ if (s == NULL)
+ s = ub_env_get("fdt_file");
+ if (s != NULL && *s != '\0') {
+ if (fdt_load_dtb_file(s) == 0) {
+ printf("Loaded DTB from file '%s'.\n", s);
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+void
+fdt_platform_fixups(void)
+{
+ static struct fdt_mem_region regions[UB_MAX_MR];
+ const char *env, *str;
+ char *end, *ethstr;
+ int eth_no, i, len, n;
+ struct sys_info *si;
+
+ env = NULL;
+ eth_no = 0;
+ ethstr = NULL;
+
+ /* Acquire sys_info */
+ si = ub_get_sys_info();
+
+ while ((env = ub_env_enum(env)) != NULL) {
+ if (strncmp(env, "eth", 3) == 0 &&
+ strncmp(env + (strlen(env) - 4), "addr", 4) == 0) {
+ /*
+ * Handle Ethernet addrs: parse uboot env eth%daddr
+ */
+
+ if (!eth_no) {
+ /*
+ * Check how many chars we will need to store
+ * maximal eth iface number.
+ */
+ len = strlen(STRINGIFY(TMP_MAX_ETH)) +
+ strlen("ethernet") + 1;
+
+ /*
+ * Reserve mem for string "ethernet" and len
+ * chars for iface no.
+ */
+ ethstr = (char *)malloc(len * sizeof(char));
+ bzero(ethstr, len * sizeof(char));
+ strcpy(ethstr, "ethernet0");
+ }
+
+ /* Extract interface number */
+ i = strtol(env + 3, &end, 10);
+ if (end == (env + 3))
+ /* 'ethaddr' means interface 0 address */
+ n = 0;
+ else
+ n = i;
+
+ if (n > TMP_MAX_ETH)
+ continue;
+
+ str = ub_env_get(env);
+
+ if (n != 0) {
+ /*
+ * Find the lenght of the interface id by
+ * taking in to account the first 3 and
+ * last 4 characters.
+ */
+ i = strlen(env) - 7;
+ strncpy(ethstr + 8, env + 3, i);
+ }
+
+ /* Modify blob */
+ fdt_fixup_ethernet(str, ethstr, len);
+
+ /* Clear ethernet..XXXX.. string */
+ bzero(ethstr + 8, len - 8);
+
+ if (n + 1 > eth_no)
+ eth_no = n + 1;
+ } else if (strcmp(env, "consoledev") == 0) {
+ str = ub_env_get(env);
+ fdt_fixup_stdout(str);
+ }
+ }
+
+ /* Modify cpu(s) and bus clock frequenties in /cpus node [Hz] */
+ fdt_fixup_cpubusfreqs(si->clk_cpu, si->clk_bus);
+
+ /* Extract the DRAM regions into fdt_mem_region format. */
+ for (i = 0, n = 0; i < si->mr_no && n < nitems(regions); i++) {
+ if (si->mr[i].flags == MR_ATTR_DRAM) {
+ regions[n].start = si->mr[i].start;
+ regions[n].size = si->mr[i].size;
+ n++;
+ }
+ }
+
+ /* Fixup memory regions */
+ fdt_fixup_memory(regions, n);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/Makefile b/usr/src/boot/sys/boot/uboot/lib/Makefile
new file mode 100644
index 0000000000..b56c06021c
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/Makefile
@@ -0,0 +1,52 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+.PATH: ${.CURDIR}/../../common
+
+LIB= uboot
+INTERNALLIB=
+WARNS?= 2
+
+SRCS= crc32.c console.c copy.c devicename.c elf_freebsd.c glue.c
+SRCS+= module.c net.c reboot.c time.c
+
+CFLAGS+= -ffreestanding -msoft-float
+
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+.if !defined(LOADER_NO_DISK_SUPPORT)
+SRCS+= disk.c
+CFLAGS+= -DLOADER_DISK_SUPPORT
+.endif
+
+.if ${MK_FDT} != "no"
+LOADER_FDT_SUPPORT= yes
+.else
+LOADER_FDT_SUPPORT= no
+.endif
+
+.if ${LOADER_FDT_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_FDT_SUPPORT -I${.CURDIR}/../../fdt
+.endif
+
+# Pick up FDT includes
+CFLAGS+= -I${.CURDIR}/../../../../sys/contrib/libfdt/
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+
+.ifdef(BOOT_DISK_DEBUG)
+# Make the disk code more talkative
+CFLAGS+= -DDISK_DEBUG
+.endif
+
+machine:
+ ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine
+
+CLEANFILES+= machine
+
+.include <bsd.stand.mk>
+.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/usr/src/boot/sys/boot/uboot/lib/api_public.h b/usr/src/boot/sys/boot/uboot/lib/api_public.h
new file mode 100644
index 0000000000..f393de8893
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/api_public.h
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2007-2008 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ *
+ * This file is dual licensed; you can use it under the terms of
+ * either the GPL, or the BSD license, at your option.
+ *
+ * I. GPL:
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Alternatively,
+ *
+ * II. BSD license:
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * This file needs to be kept in sync with U-Boot reference:
+ * http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=blob;f=include/api_public.h
+ */
+
+#ifndef _API_PUBLIC_H_
+#define _API_PUBLIC_H_
+
+#define API_EINVAL 1 /* invalid argument(s) */
+#define API_ENODEV 2 /* no device */
+#define API_ENOMEM 3 /* no memory */
+#define API_EBUSY 4 /* busy, occupied etc. */
+#define API_EIO 5 /* I/O error */
+#define API_ESYSC 6 /* syscall error */
+
+typedef int (*scp_t)(int, int *, ...);
+
+#define API_SIG_VERSION 1
+#define API_SIG_MAGIC "UBootAPI"
+#define API_SIG_MAGLEN 8
+
+struct api_signature {
+ char magic[API_SIG_MAGLEN]; /* magic string */
+ uint16_t version; /* API version */
+ uint32_t checksum; /* checksum of this sig struct */
+ scp_t syscall; /* entry point to the API */
+};
+
+enum {
+ API_RSVD = 0,
+ API_GETC,
+ API_PUTC,
+ API_TSTC,
+ API_PUTS,
+ API_RESET,
+ API_GET_SYS_INFO,
+ API_UDELAY,
+ API_GET_TIMER,
+ API_DEV_ENUM,
+ API_DEV_OPEN,
+ API_DEV_CLOSE,
+ API_DEV_READ,
+ API_DEV_WRITE,
+ API_ENV_ENUM,
+ API_ENV_GET,
+ API_ENV_SET,
+ API_MAXCALL
+};
+
+#define MR_ATTR_FLASH 0x0001
+#define MR_ATTR_DRAM 0x0002
+#define MR_ATTR_SRAM 0x0003
+
+struct mem_region {
+ unsigned long start;
+ unsigned long size;
+ int flags;
+};
+
+struct sys_info {
+ unsigned long clk_bus;
+ unsigned long clk_cpu;
+ unsigned long bar;
+ struct mem_region *mr;
+ int mr_no; /* number of memory regions */
+};
+
+#undef CFG_64BIT_LBA
+#ifdef CFG_64BIT_LBA
+typedef uint64_t lbasize_t;
+#else
+typedef unsigned long lbasize_t;
+#endif
+typedef unsigned long lbastart_t;
+
+#define DEV_TYP_NONE 0x0000
+#define DEV_TYP_NET 0x0001
+
+#define DEV_TYP_STOR 0x0002
+#define DT_STOR_IDE 0x0010
+#define DT_STOR_SCSI 0x0020
+#define DT_STOR_USB 0x0040
+#define DT_STOR_MMC 0x0080
+#define DT_STOR_SATA 0x0100
+
+#define DEV_STA_CLOSED 0x0000 /* invalid, closed */
+#define DEV_STA_OPEN 0x0001 /* open i.e. active */
+
+struct device_info {
+ int type;
+ void *cookie;
+
+ union {
+ struct {
+ lbasize_t block_count; /* no of blocks */
+ unsigned long block_size; /* size of one block */
+ } storage;
+
+ struct {
+ unsigned char hwaddr[6];
+ } net;
+ } info;
+#define di_stor info.storage
+#define di_net info.net
+
+ int state;
+};
+
+#endif /* _API_PUBLIC_H_ */
diff --git a/usr/src/boot/sys/boot/uboot/lib/console.c b/usr/src/boot/sys/boot/uboot/lib/console.c
new file mode 100644
index 0000000000..f49f455c7e
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/console.c
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+#include "glue.h"
+
+int console;
+
+static void uboot_cons_probe(struct console *cp);
+static int uboot_cons_init(int);
+static void uboot_cons_putchar(int);
+static int uboot_cons_getchar(void);
+static int uboot_cons_poll(void);
+
+struct console uboot_console = {
+ "uboot",
+ "U-Boot console",
+ 0,
+ uboot_cons_probe,
+ uboot_cons_init,
+ uboot_cons_putchar,
+ uboot_cons_getchar,
+ uboot_cons_poll,
+};
+
+static void
+uboot_cons_probe(struct console *cp)
+{
+
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+}
+
+static int
+uboot_cons_init(int arg)
+{
+
+ return (0);
+}
+
+static void
+uboot_cons_putchar(int c)
+{
+
+ if (c == '\n')
+ ub_putc('\r');
+
+ ub_putc(c);
+}
+
+static int
+uboot_cons_getchar()
+{
+
+ return (ub_getc());
+}
+
+static int
+uboot_cons_poll()
+{
+
+ return (ub_tstc());
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/copy.c b/usr/src/boot/sys/boot/uboot/lib/copy.c
new file mode 100644
index 0000000000..131b88d858
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/copy.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
+#include <stand.h>
+#include <stdint.h>
+
+#include "api_public.h"
+#include "glue.h"
+#include "libuboot.h"
+
+/*
+ * MD primitives supporting placement of module data
+ */
+
+#ifdef __arm__
+#define KERN_ALIGN (2 * 1024 * 1024)
+#else
+#define KERN_ALIGN PAGE_SIZE
+#endif
+
+/*
+ * Avoid low memory, u-boot puts things like args and dtb blobs there.
+ */
+#define KERN_MINADDR max(KERN_ALIGN, (1024 * 1024))
+
+extern void _start(void); /* ubldr entry point address. */
+
+/*
+ * This is called for every object loaded (kernel, module, dtb file, etc). The
+ * expected return value is the next address at or after the given addr which is
+ * appropriate for loading the given object described by type and data. On each
+ * call the addr is the next address following the previously loaded object.
+ *
+ * The first call is for loading the kernel, and the addr argument will be zero,
+ * and we search for a big block of ram to load the kernel and modules.
+ *
+ * On subsequent calls the addr will be non-zero, and we just round it up so
+ * that each object begins on a page boundary.
+ */
+uint64_t
+uboot_loadaddr(u_int type, void *data, uint64_t addr)
+{
+ struct sys_info *si;
+ uint64_t sblock, eblock, subldr, eubldr;
+ uint64_t biggest_block, this_block;
+ uint64_t biggest_size, this_size;
+ int i;
+ char *envstr;
+
+ if (addr == 0) {
+ /*
+ * If the loader_kernaddr environment variable is set, blindly
+ * honor it. It had better be right. We force interpretation
+ * of the value in base-16 regardless of any leading 0x prefix,
+ * because that's the U-Boot convention.
+ */
+ envstr = ub_env_get("loader_kernaddr");
+ if (envstr != NULL)
+ return (strtoul(envstr, NULL, 16));
+
+ /*
+ * Find addr/size of largest DRAM block. Carve our own address
+ * range out of the block, because loading the kernel over the
+ * top ourself is a poor memory-conservation strategy. Avoid
+ * memory at beginning of the first block of physical ram,
+ * since u-boot likes to pass args and data there. Assume that
+ * u-boot has moved itself to the very top of ram and
+ * optimistically assume that we won't run into it up there.
+ */
+ if ((si = ub_get_sys_info()) == NULL)
+ panic("could not retrieve system info");
+
+ biggest_block = 0;
+ biggest_size = 0;
+ subldr = rounddown2((uintptr_t)_start, KERN_ALIGN);
+ eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN);
+ for (i = 0; i < si->mr_no; i++) {
+ if (si->mr[i].flags != MR_ATTR_DRAM)
+ continue;
+ sblock = roundup2((uint64_t)si->mr[i].start,
+ KERN_ALIGN);
+ eblock = rounddown2((uint64_t)si->mr[i].start +
+ si->mr[i].size, KERN_ALIGN);
+ if (biggest_size == 0)
+ sblock += KERN_MINADDR;
+ if (subldr >= sblock && subldr < eblock) {
+ if (subldr - sblock > eblock - eubldr) {
+ this_block = sblock;
+ this_size = subldr - sblock;
+ } else {
+ this_block = eubldr;
+ this_size = eblock - eubldr;
+ }
+ } else if (subldr < sblock && eubldr < eblock) {
+ /* Loader is below or engulfs the sblock */
+ this_block = (eubldr < sblock) ? sblock : eubldr;
+ this_size = eblock - this_block;
+ } else {
+ this_block = 0;
+ this_size = 0;
+ }
+ if (biggest_size < this_size) {
+ biggest_block = this_block;
+ biggest_size = this_size;
+ }
+ }
+ if (biggest_size == 0)
+ panic("Not enough DRAM to load kernel\n");
+#if 0
+ printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n",
+ (uintmax_t)biggest_block,
+ (uintmax_t)biggest_block + biggest_size - 1,
+ (uintmax_t)biggest_size / 1024 / 1024);
+#endif
+ return (biggest_block);
+ }
+ return roundup2(addr, PAGE_SIZE);
+}
+
+ssize_t
+uboot_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ bcopy(src, (void *)dest, len);
+ return (len);
+}
+
+ssize_t
+uboot_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ bcopy((void *)src, dest, len);
+ return (len);
+}
+
+ssize_t
+uboot_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ return (read(fd, (void *)dest, len));
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/devicename.c b/usr/src/boot/sys/boot/uboot/lib/devicename.c
new file mode 100644
index 0000000000..9e68f9df9e
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/devicename.c
@@ -0,0 +1,201 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+#include "disk.h"
+#include "libuboot.h"
+
+static int uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
+ const char **path);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+uboot_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct uboot_devdesc **dev = (struct uboot_devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) || (devspec[0] == '/') ||
+ (strchr(devspec, ':') == NULL)) {
+
+ if (((rv = uboot_parsedev(dev, getenv("currdev"), NULL)) == 0)
+ && (path != NULL))
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec.
+ */
+ return (uboot_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * disk<unit>[<partition>]:
+ *
+ */
+static int
+uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
+ const char **path)
+{
+ struct uboot_devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i, unit, err;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return(EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
+ if (!strncmp(devspec, devsw[i]->dv_name,
+ strlen(devsw[i]->dv_name))) {
+ dv = devsw[i];
+ break;
+ }
+ }
+ if (dv == NULL)
+ return(ENOENT);
+ idev = malloc(sizeof(struct uboot_devdesc));
+ err = 0;
+ np = (devspec + strlen(dv->dv_name));
+
+ switch(dv->dv_type) {
+ case DEVT_NONE:
+ break;
+
+#ifdef LOADER_DISK_SUPPORT
+ case DEVT_DISK:
+ err = disk_parsedev((struct disk_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+#endif
+
+ case DEVT_NET:
+ unit = 0;
+
+ if (*np && (*np != ':')) {
+ /* get unit number if present */
+ unit = strtol(np, &cp, 0);
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_unit = unit;
+
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+
+ default:
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (dev == NULL) {
+ free(idev);
+ } else {
+ *dev = idev;
+ }
+ return (0);
+
+fail:
+ free(idev);
+ return (err);
+}
+
+
+char *
+uboot_fmtdev(void *vdev)
+{
+ struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev;
+ static char buf[128];
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ case DEVT_DISK:
+#ifdef LOADER_DISK_SUPPORT
+ return (disk_fmtdev(vdev));
+#endif
+
+ case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+ }
+ return(buf);
+}
+
+/*
+ * Set currdev to suit the value being supplied in (value).
+ */
+int
+uboot_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct uboot_devdesc *ncurr;
+ int rv;
+
+ if ((rv = uboot_parsedev(&ncurr, value, NULL)) != 0)
+ return (rv);
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/disk.c b/usr/src/boot/sys/boot/uboot/lib/disk.c
new file mode 100644
index 0000000000..a8b7853198
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/disk.c
@@ -0,0 +1,304 @@
+/*-
+ * Copyright (c) 2008 Semihalf, Rafal Jaworowski
+ * Copyright (c) 2009 Semihalf, Piotr Ziecik
+ * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ */
+
+/*
+ * Block storage I/O routines for U-Boot
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/disk.h>
+#include <machine/stdarg.h>
+#include <stand.h>
+
+#include "api_public.h"
+#include "bootstrap.h"
+#include "disk.h"
+#include "glue.h"
+#include "libuboot.h"
+
+#define stor_printf(fmt, args...) do { \
+ printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit); \
+ printf(fmt, ##args); \
+} while (0)
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
+ printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+static struct {
+ int opened; /* device is opened */
+ int handle; /* storage device handle */
+ int type; /* storage type */
+ off_t blocks; /* block count */
+ u_int bsize; /* block size */
+} stor_info[UB_MAX_DEV];
+
+#define SI(dev) (stor_info[(dev)->d_unit])
+
+static int stor_info_no = 0;
+static int stor_opendev(struct disk_devdesc *);
+static int stor_readdev(struct disk_devdesc *, daddr_t, size_t, char *);
+
+/* devsw I/F */
+static int stor_init(void);
+static int stor_strategy(void *, int, daddr_t, size_t, char *, size_t *);
+static int stor_open(struct open_file *, ...);
+static int stor_close(struct open_file *);
+static int stor_ioctl(struct open_file *f, u_long cmd, void *data);
+static void stor_print(int);
+static void stor_cleanup(void);
+
+struct devsw uboot_storage = {
+ "disk",
+ DEVT_DISK,
+ stor_init,
+ stor_strategy,
+ stor_open,
+ stor_close,
+ stor_ioctl,
+ stor_print,
+ stor_cleanup
+};
+
+static int
+stor_init(void)
+{
+ struct device_info *di;
+ int i;
+
+ if (devs_no == 0) {
+ printf("No U-Boot devices! Really enumerated?\n");
+ return (-1);
+ }
+
+ for (i = 0; i < devs_no; i++) {
+ di = ub_dev_get(i);
+ if ((di != NULL) && (di->type & DEV_TYP_STOR)) {
+ if (stor_info_no >= UB_MAX_DEV) {
+ printf("Too many storage devices: %d\n",
+ stor_info_no);
+ return (-1);
+ }
+ stor_info[stor_info_no].handle = i;
+ stor_info[stor_info_no].opened = 0;
+ stor_info[stor_info_no].type = di->type;
+ stor_info[stor_info_no].blocks =
+ di->di_stor.block_count;
+ stor_info[stor_info_no].bsize =
+ di->di_stor.block_size;
+ stor_info_no++;
+ }
+ }
+
+ if (!stor_info_no) {
+ debugf("No storage devices\n");
+ return (-1);
+ }
+
+ debugf("storage devices found: %d\n", stor_info_no);
+ return (0);
+}
+
+static void
+stor_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < stor_info_no; i++)
+ if (stor_info[i].opened > 0)
+ ub_dev_close(stor_info[i].handle);
+ disk_cleanup(&uboot_storage);
+}
+
+static int
+stor_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
+ size_t *rsize)
+{
+ struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
+ daddr_t bcount;
+ int err;
+
+ if (rw != F_READ) {
+ stor_printf("write attempt, operation not supported!\n");
+ return (EROFS);
+ }
+
+ if (size % SI(dev).bsize) {
+ stor_printf("size=%zu not multiple of device "
+ "block size=%d\n",
+ size, SI(dev).bsize);
+ return (EIO);
+ }
+ bcount = size / SI(dev).bsize;
+ if (rsize)
+ *rsize = 0;
+
+ err = stor_readdev(dev, blk + dev->d_offset, bcount, buf);
+ if (!err && rsize)
+ *rsize = size;
+
+ return (err);
+}
+
+static int
+stor_open(struct open_file *f, ...)
+{
+ va_list ap;
+ struct disk_devdesc *dev;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct disk_devdesc *);
+ va_end(ap);
+
+ return (stor_opendev(dev));
+}
+
+static int
+stor_opendev(struct disk_devdesc *dev)
+{
+ int err;
+
+ if (dev->d_unit < 0 || dev->d_unit >= stor_info_no)
+ return (EIO);
+
+ if (SI(dev).opened == 0) {
+ err = ub_dev_open(SI(dev).handle);
+ if (err != 0) {
+ stor_printf("device open failed with error=%d, "
+ "handle=%d\n", err, SI(dev).handle);
+ return (ENXIO);
+ }
+ SI(dev).opened++;
+ }
+ return (disk_open(dev, SI(dev).blocks * SI(dev).bsize,
+ SI(dev).bsize, 0));
+}
+
+static int
+stor_close(struct open_file *f)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)(f->f_devdata);
+ return (disk_close(dev));
+}
+
+static int
+stor_readdev(struct disk_devdesc *dev, daddr_t blk, size_t size, char *buf)
+{
+ lbasize_t real_size;
+ int err;
+
+ debugf("reading blk=%d size=%d @ 0x%08x\n", (int)blk, size, (uint32_t)buf);
+
+ err = ub_dev_read(SI(dev).handle, buf, size, blk, &real_size);
+ if (err != 0) {
+ stor_printf("read failed, error=%d\n", err);
+ return (EIO);
+ }
+
+ if (real_size != size) {
+ stor_printf("real size != size\n");
+ err = EIO;
+ }
+
+ return (err);
+}
+
+static void
+stor_print(int verbose)
+{
+ struct disk_devdesc dev;
+ static char line[80];
+ int i;
+
+ for (i = 0; i < stor_info_no; i++) {
+ dev.d_dev = &uboot_storage;
+ dev.d_unit = i;
+ dev.d_slice = -1;
+ dev.d_partition = -1;
+ sprintf(line, "\tdisk%d (%s)\n", i,
+ ub_stor_type(SI(&dev).type));
+ pager_output(line);
+ if (stor_opendev(&dev) == 0) {
+ sprintf(line, "\tdisk%d", i);
+ disk_print(&dev, line, verbose);
+ disk_close(&dev);
+ }
+ }
+}
+
+static int
+stor_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ switch (cmd) {
+ case DIOCGSECTORSIZE:
+ *(u_int *)data = SI(dev).bsize;
+ break;
+ case DIOCGMEDIASIZE:
+ *(off_t *)data = SI(dev).bsize * SI(dev).blocks;
+ break;
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+
+/*
+ * Return the device unit number for the given type and type-relative unit
+ * number.
+ */
+int
+uboot_diskgetunit(int type, int type_unit)
+{
+ int local_type_unit;
+ int i;
+
+ local_type_unit = 0;
+ for (i = 0; i < stor_info_no; i++) {
+ if ((stor_info[i].type & type) == type) {
+ if (local_type_unit == type_unit) {
+ return (i);
+ }
+ local_type_unit++;
+ }
+ }
+
+ return (-1);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/elf_freebsd.c b/usr/src/boot/sys/boot/uboot/lib/elf_freebsd.c
new file mode 100644
index 0000000000..b4fd1b3c6f
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/elf_freebsd.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#ifdef __mips__
+#include <sys/proc.h>
+#include <machine/frame.h>
+#endif
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libuboot.h"
+
+extern vm_offset_t md_load(char *, vm_offset_t *);
+
+int
+__elfN(uboot_load)(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+#if defined(__powerpc__)
+ /*
+ * No need to sync the icache for modules: this will
+ * be done by the kernel after relocation.
+ */
+ if (!strcmp((*result)->f_type, "elf kernel"))
+ __syncicache((void *) (*result)->f_addr, (*result)->f_size);
+#endif
+ return (0);
+}
+
+int
+__elfN(uboot_exec)(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp;
+ Elf_Ehdr *e;
+ int error;
+ void (*entry)(void *);
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return (EFTYPE);
+
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ if ((error = md_load(fp->f_args, &mdp)) != 0)
+ return (error);
+
+ entry = (void *)e->e_entry;
+ printf("Kernel entry at 0x%p...\n", entry);
+
+ dev_cleanup();
+ printf("Kernel args: %s\n", fp->f_args);
+
+ (*entry)((void *)mdp);
+ panic("exec returned");
+}
+
+struct file_format uboot_elf = {
+ __elfN(uboot_load),
+ __elfN(uboot_exec)
+};
diff --git a/usr/src/boot/sys/boot/uboot/lib/glue.c b/usr/src/boot/sys/boot/uboot/lib/glue.c
new file mode 100644
index 0000000000..4c843f0c42
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/glue.c
@@ -0,0 +1,529 @@
+/*-
+ * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <crc32.h>
+#include <stand.h>
+#include "api_public.h"
+#include "glue.h"
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+/* Some random address used by U-Boot. */
+extern long uboot_address;
+
+static int
+valid_sig(struct api_signature *sig)
+{
+ uint32_t checksum;
+ struct api_signature s;
+
+ if (sig == NULL)
+ return (0);
+ /*
+ * Clear the checksum field (in the local copy) so as to calculate the
+ * CRC with the same initial contents as at the time when the sig was
+ * produced
+ */
+ s = *sig;
+ s.checksum = 0;
+
+ checksum = crc32((void *)&s, sizeof(struct api_signature));
+
+ if (checksum != sig->checksum)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Searches for the U-Boot API signature
+ *
+ * returns 1/0 depending on found/not found result
+ */
+int
+api_search_sig(struct api_signature **sig)
+{
+ unsigned char *sp, *spend;
+
+ if (sig == NULL)
+ return (0);
+
+ if (uboot_address == 0)
+ uboot_address = 255 * 1024 * 1024;
+
+ sp = (void *)(uboot_address & API_SIG_SEARCH_MASK);
+ spend = sp + API_SIG_SEARCH_LEN - API_SIG_MAGLEN;
+
+ while (sp < spend) {
+ if (!bcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
+ *sig = (struct api_signature *)sp;
+ if (valid_sig(*sig))
+ return (1);
+ }
+ sp += API_SIG_MAGLEN;
+ }
+
+ *sig = NULL;
+ return (0);
+}
+
+/****************************************
+ *
+ * console
+ *
+ ****************************************/
+
+int
+ub_getc(void)
+{
+ int c;
+
+ if (!syscall(API_GETC, NULL, &c))
+ return (-1);
+
+ return (c);
+}
+
+int
+ub_tstc(void)
+{
+ int t;
+
+ if (!syscall(API_TSTC, NULL, &t))
+ return (-1);
+
+ return (t);
+}
+
+void
+ub_putc(const char c)
+{
+
+ syscall(API_PUTC, NULL, &c);
+}
+
+void
+ub_puts(const char *s)
+{
+
+ syscall(API_PUTS, NULL, s);
+}
+
+/****************************************
+ *
+ * system
+ *
+ ****************************************/
+
+void
+ub_reset(void)
+{
+
+ syscall(API_RESET, NULL);
+}
+
+static struct mem_region mr[UB_MAX_MR];
+static struct sys_info si;
+
+struct sys_info *
+ub_get_sys_info(void)
+{
+ int err = 0;
+
+ memset(&si, 0, sizeof(struct sys_info));
+ si.mr = mr;
+ si.mr_no = UB_MAX_MR;
+ memset(&mr, 0, sizeof(mr));
+
+ if (!syscall(API_GET_SYS_INFO, &err, &si))
+ return (NULL);
+
+ return ((err) ? NULL : &si);
+}
+
+/****************************************
+ *
+ * timing
+ *
+ ****************************************/
+
+void
+ub_udelay(unsigned long usec)
+{
+
+ syscall(API_UDELAY, NULL, &usec);
+}
+
+unsigned long
+ub_get_timer(unsigned long base)
+{
+ unsigned long cur;
+
+ if (!syscall(API_GET_TIMER, NULL, &cur, &base))
+ return (0);
+
+ return (cur);
+}
+
+/****************************************************************************
+ *
+ * devices
+ *
+ * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
+ *
+ ***************************************************************************/
+
+static struct device_info devices[UB_MAX_DEV];
+
+struct device_info *
+ub_dev_get(int i)
+{
+
+ return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
+}
+
+/*
+ * Enumerates the devices: fills out device_info elements in the devices[]
+ * array.
+ *
+ * returns: number of devices found
+ */
+int
+ub_dev_enum(void)
+{
+ struct device_info *di;
+ int n = 0;
+
+ memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
+ di = &devices[0];
+
+ if (!syscall(API_DEV_ENUM, NULL, di))
+ return (0);
+
+ while (di->cookie != NULL) {
+
+ if (++n >= UB_MAX_DEV)
+ break;
+
+ /* take another device_info */
+ di++;
+
+ /* pass on the previous cookie */
+ di->cookie = devices[n - 1].cookie;
+
+ if (!syscall(API_DEV_ENUM, NULL, di))
+ return (0);
+ }
+
+ return (n);
+}
+
+/*
+ * handle: 0-based id of the device
+ *
+ * returns: 0 when OK, err otherwise
+ */
+int
+ub_dev_open(int handle)
+{
+ struct device_info *di;
+ int err = 0;
+
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return (API_EINVAL);
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_OPEN, &err, di))
+ return (-1);
+
+ return (err);
+}
+
+int
+ub_dev_close(int handle)
+{
+ struct device_info *di;
+
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return (API_EINVAL);
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_CLOSE, NULL, di))
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Validates device for read/write, it has to:
+ *
+ * - have sane handle
+ * - be opened
+ *
+ * returns: 0/1 accordingly
+ */
+static int
+dev_valid(int handle)
+{
+
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return (0);
+
+ if (devices[handle].state != DEV_STA_OPEN)
+ return (0);
+
+ return (1);
+}
+
+static int
+dev_stor_valid(int handle)
+{
+
+ if (!dev_valid(handle))
+ return (0);
+
+ if (!(devices[handle].type & DEV_TYP_STOR))
+ return (0);
+
+ return (1);
+}
+
+int
+ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
+ lbasize_t *rlen)
+{
+ struct device_info *di;
+ lbasize_t act_len;
+ int err = 0;
+
+ if (!dev_stor_valid(handle))
+ return (API_ENODEV);
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
+ return (API_ESYSC);
+
+ if (!err && rlen)
+ *rlen = act_len;
+
+ return (err);
+}
+
+static int
+dev_net_valid(int handle)
+{
+
+ if (!dev_valid(handle))
+ return (0);
+
+ if (devices[handle].type != DEV_TYP_NET)
+ return (0);
+
+ return (1);
+}
+
+int
+ub_dev_recv(int handle, void *buf, int len, int *rlen)
+{
+ struct device_info *di;
+ int err = 0, act_len;
+
+ if (!dev_net_valid(handle))
+ return (API_ENODEV);
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
+ return (API_ESYSC);
+
+ if (!err)
+ *rlen = act_len;
+
+ return (err);
+}
+
+int
+ub_dev_send(int handle, void *buf, int len)
+{
+ struct device_info *di;
+ int err = 0;
+
+ if (!dev_net_valid(handle))
+ return (API_ENODEV);
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
+ return (API_ESYSC);
+
+ return (err);
+}
+
+char *
+ub_stor_type(int type)
+{
+
+ if (type & DT_STOR_IDE)
+ return ("IDE");
+
+ if (type & DT_STOR_SCSI)
+ return ("SCSI");
+
+ if (type & DT_STOR_USB)
+ return ("USB");
+
+ if (type & DT_STOR_MMC)
+ return ("MMC");
+
+ if (type & DT_STOR_SATA)
+ return ("SATA");
+
+ return ("Unknown");
+}
+
+char *
+ub_mem_type(int flags)
+{
+
+ switch (flags & 0x000F) {
+ case MR_ATTR_FLASH:
+ return ("FLASH");
+ case MR_ATTR_DRAM:
+ return ("DRAM");
+ case MR_ATTR_SRAM:
+ return ("SRAM");
+ default:
+ return ("Unknown");
+ }
+}
+
+void
+ub_dump_di(int handle)
+{
+ struct device_info *di = ub_dev_get(handle);
+ int i;
+
+ printf("device info (%d):\n", handle);
+ printf(" cookie\t= 0x%p\n", di->cookie);
+ printf(" type\t\t= 0x%08x\n", di->type);
+
+ if (di->type == DEV_TYP_NET) {
+ printf(" hwaddr\t= ");
+ for (i = 0; i < 6; i++)
+ printf("%02x ", di->di_net.hwaddr[i]);
+
+ printf("\n");
+
+ } else if (di->type & DEV_TYP_STOR) {
+ printf(" type\t\t= %s\n", ub_stor_type(di->type));
+ printf(" blk size\t\t= %ld\n", di->di_stor.block_size);
+ printf(" blk count\t\t= %ld\n", di->di_stor.block_count);
+ }
+}
+
+void
+ub_dump_si(struct sys_info *si)
+{
+ int i;
+
+ printf("sys info:\n");
+ printf(" clkbus\t= %ld MHz\n", si->clk_bus / 1000 / 1000);
+ printf(" clkcpu\t= %ld MHz\n", si->clk_cpu / 1000 / 1000);
+ printf(" bar\t\t= 0x%08lx\n", si->bar);
+
+ printf("---\n");
+ for (i = 0; i < si->mr_no; i++) {
+ if (si->mr[i].flags == 0)
+ break;
+
+ printf(" start\t= 0x%08lx\n", si->mr[i].start);
+ printf(" size\t= 0x%08lx\n", si->mr[i].size);
+ printf(" type\t= %s\n", ub_mem_type(si->mr[i].flags));
+ printf("---\n");
+ }
+}
+
+/****************************************
+ *
+ * env vars
+ *
+ ****************************************/
+
+char *
+ub_env_get(const char *name)
+{
+ char *value;
+
+ if (!syscall(API_ENV_GET, NULL, name, &value))
+ return (NULL);
+
+ return (value);
+}
+
+void
+ub_env_set(const char *name, char *value)
+{
+
+ syscall(API_ENV_SET, NULL, name, value);
+}
+
+static char env_name[256];
+
+const char *
+ub_env_enum(const char *last)
+{
+ const char *env, *str;
+ int i;
+
+ /*
+ * It's OK to pass only the name piece as last (and not the whole
+ * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
+ * internally, which handles such case
+ */
+ env = NULL;
+ if (!syscall(API_ENV_ENUM, NULL, last, &env))
+ return (NULL);
+
+ if (env == NULL || last == env)
+ /* no more env. variables to enumerate */
+ return (NULL);
+
+ /* next enumerated env var */
+ memset(env_name, 0, 256);
+ for (i = 0, str = env; *str != '=' && *str != '\0';)
+ env_name[i++] = *str++;
+
+ env_name[i] = '\0';
+
+ return (env_name);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/glue.h b/usr/src/boot/sys/boot/uboot/lib/glue.h
new file mode 100644
index 0000000000..b9c60b625c
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/glue.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This is the header file for conveniency wrapper routines (API glue)
+ */
+
+#ifndef _API_GLUE_H_
+#define _API_GLUE_H_
+
+#include "api_public.h"
+
+/*
+ * Mask used to align the start address for API signature search to 1MiB
+ */
+#define API_SIG_SEARCH_MASK ~0x000fffff
+
+#ifdef __mips__
+/*
+ * On MIPS, U-Boot passes us a hint address, which is very close to the end of
+ * RAM (less than 1MiB), so searching for the API signature within more than
+ * that leads to exception.
+ */
+#define API_SIG_SEARCH_LEN 0x00100000
+#else
+/*
+ * Search for the API signature within 3MiB of the 1MiB-aligned address that
+ * U-Boot has hinted us.
+ */
+#define API_SIG_SEARCH_LEN 0x00300000
+#endif
+
+int syscall(int, int *, ...);
+void *syscall_ptr;
+
+int api_search_sig(struct api_signature **sig);
+
+#define UB_MAX_MR 16 /* max mem regions number */
+#define UB_MAX_DEV 6 /* max devices number */
+
+/*
+ * The ub_ library calls are part of the application, not U-Boot code! They
+ * are front-end wrappers that are used by the consumer application: they
+ * prepare arguments for particular syscall and jump to the low level
+ * syscall()
+ */
+
+/* console */
+int ub_getc(void);
+int ub_tstc(void);
+void ub_putc(char);
+void ub_puts(const char *);
+
+/* system */
+void ub_reset(void);
+struct sys_info *ub_get_sys_info(void);
+
+/* time */
+void ub_udelay(unsigned long);
+unsigned long ub_get_timer(unsigned long);
+
+/* env vars */
+char *ub_env_get(const char *);
+void ub_env_set(const char *, char *);
+const char *ub_env_enum(const char *);
+
+/* devices */
+int ub_dev_enum(void);
+int ub_dev_open(int);
+int ub_dev_close(int);
+int ub_dev_read(int, void *, lbasize_t, lbastart_t, lbasize_t *);
+int ub_dev_send(int, void *, int);
+int ub_dev_recv(int, void *, int, int *);
+struct device_info *ub_dev_get(int);
+
+void ub_dump_di(int);
+void ub_dump_si(struct sys_info *);
+char *ub_mem_type(int);
+char *ub_stor_type(int);
+
+#endif /* _API_GLUE_H_ */
diff --git a/usr/src/boot/sys/boot/uboot/lib/libuboot.h b/usr/src/boot/sys/boot/uboot/lib/libuboot.h
new file mode 100644
index 0000000000..e4201d8a13
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/libuboot.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (C) 2000 Benno Rice.
+ * Copyright (C) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+struct uboot_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ void *d_opendata;
+ union {
+ struct {
+ int slice;
+ int partition;
+ off_t offset;
+ } disk;
+ } d_kind;
+};
+
+#define d_disk d_kind.disk
+
+/*
+ * Default network packet alignment in memory
+ */
+#define PKTALIGN 32
+
+int uboot_getdev(void **vdev, const char *devspec, const char **path);
+char *uboot_fmtdev(void *vdev);
+int uboot_setcurrdev(struct env_var *ev, int flags, const void *value);
+
+extern int devs_no;
+extern struct netif_driver uboot_net;
+extern struct devsw uboot_storage;
+
+extern uintptr_t uboot_heap_start;
+extern uintptr_t uboot_heap_end;
+
+uint64_t uboot_loadaddr(u_int type, void *data, uint64_t addr);
+ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t uboot_readin(const int fd, vm_offset_t dest, const size_t len);
+extern int uboot_autoload(void);
+
+struct preloaded_file;
+struct file_format;
+
+extern struct file_format uboot_elf;
+
+void reboot(void);
+
+int uboot_diskgetunit(int type, int type_unit);
+
diff --git a/usr/src/boot/sys/boot/uboot/lib/module.c b/usr/src/boot/sys/boot/uboot/lib/module.c
new file mode 100644
index 0000000000..0951ed6618
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/module.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * U-Boot-specific module functionality.
+ */
+
+#include <stand.h>
+#include <string.h>
+
+#if defined(LOADER_FDT_SUPPORT)
+#include <fdt_platform.h>
+#endif
+
+#include "bootstrap.h"
+#include "libuboot.h"
+
+int
+uboot_autoload(void)
+{
+#if defined(LOADER_FDT_SUPPORT)
+ int err;
+
+ if ((err = fdt_setup_fdtp()) != 0) {
+ printf("No valid device tree blob found!\n");
+ return (err);
+ }
+#endif
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/net.c b/usr/src/boot/sys/boot/uboot/lib/net.c
new file mode 100644
index 0000000000..9bc0c07543
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/net.c
@@ -0,0 +1,362 @@
+/*-
+ * Copyright (c) 2000-2001 Benno Rice
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+#include <stand.h>
+#include <net.h>
+#include <netif.h>
+
+#include "api_public.h"
+#include "glue.h"
+#include "libuboot.h"
+#include "dev_net.h"
+
+static int net_probe(struct netif *, void *);
+static int net_match(struct netif *, void *);
+static void net_init(struct iodesc *, void *);
+static int net_get(struct iodesc *, void *, size_t, time_t);
+static int net_put(struct iodesc *, void *, size_t);
+static void net_end(struct netif *);
+
+extern struct netif_stats net_stats[];
+
+struct netif_dif net_ifs[] = {
+ /* dif_unit dif_nsel dif_stats dif_private */
+ { 0, 1, &net_stats[0], 0, },
+};
+
+struct netif_stats net_stats[NENTS(net_ifs)];
+
+struct netif_driver uboot_net = {
+ "uboot_eth", /* netif_bname */
+ net_match, /* netif_match */
+ net_probe, /* netif_probe */
+ net_init, /* netif_init */
+ net_get, /* netif_get */
+ net_put, /* netif_put */
+ net_end, /* netif_end */
+ net_ifs, /* netif_ifs */
+ NENTS(net_ifs) /* netif_nifs */
+};
+
+struct uboot_softc {
+ uint32_t sc_pad;
+ uint8_t sc_rxbuf[ETHER_MAX_LEN];
+ uint8_t sc_txbuf[ETHER_MAX_LEN + PKTALIGN];
+ uint8_t *sc_txbufp;
+ int sc_handle; /* device handle for ub_dev_xxx */
+};
+
+static struct uboot_softc uboot_softc;
+
+/*
+ * get_env_net_params()
+ *
+ * Attempt to obtain all the parms we need for netbooting from the U-Boot
+ * environment. If we fail to obtain the values it may still be possible to
+ * netboot; the net_dev code will attempt to get the values from bootp, rarp,
+ * and other such sources.
+ *
+ * If rootip.s_addr is non-zero net_dev assumes the required global variables
+ * are set and skips the bootp inquiry. For that reason, we don't set rootip
+ * until we've verified that we have at least the minimum required info.
+ *
+ * This is called from netif_init() which can result in it getting called
+ * multiple times, by design. The network code at higher layers zeroes out
+ * rootip when it closes a network interface, so if it gets opened again we have
+ * to obtain all this info again.
+ */
+static void
+get_env_net_params()
+{
+ char *envstr;
+ in_addr_t rootaddr, serveraddr;
+
+ /*
+ * Silently get out right away if we don't have rootpath, because none
+ * of the other info we obtain below is sufficient to boot without it.
+ *
+ * If we do have rootpath, copy it into the global var and also set
+ * dhcp.root-path in the env. If we don't get all the other info from
+ * the u-boot env below, we will still try dhcp/bootp, but the server-
+ * provided path will not replace the user-provided value we set here.
+ */
+ if ((envstr = ub_env_get("rootpath")) == NULL)
+ return;
+ strlcpy(rootpath, envstr, sizeof(rootpath));
+ setenv("dhcp.root-path", rootpath, 0);
+
+ /*
+ * Our own IP address must be valid. Silently get out if it's not set,
+ * but whine if it's there and we can't parse it.
+ */
+ if ((envstr = ub_env_get("ipaddr")) == NULL)
+ return;
+ if ((myip.s_addr = inet_addr(envstr)) == INADDR_NONE) {
+ printf("Could not parse ipaddr '%s'\n", envstr);
+ return;
+ }
+
+ /*
+ * Netmask is optional, default to the "natural" netmask for our IP, but
+ * whine if it was provided and we couldn't parse it.
+ */
+ if ((envstr = ub_env_get("netmask")) != NULL &&
+ (netmask = inet_addr(envstr)) == INADDR_NONE) {
+ printf("Could not parse netmask '%s'\n", envstr);
+ }
+ if (netmask == INADDR_NONE) {
+ if (IN_CLASSA(myip.s_addr))
+ netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(myip.s_addr))
+ netmask = IN_CLASSB_NET;
+ else
+ netmask = IN_CLASSC_NET;
+ }
+
+ /*
+ * Get optional serverip before rootpath; the latter can override it.
+ * Whine only if it's present but can't be parsed.
+ */
+ serveraddr = INADDR_NONE;
+ if ((envstr = ub_env_get("serverip")) != NULL) {
+ if ((serveraddr = inet_addr(envstr)) == INADDR_NONE)
+ printf("Could not parse serverip '%s'\n", envstr);
+ }
+
+ /*
+ * There must be a rootpath. It may be ip:/path or it may be just the
+ * path in which case the ip needs to be in serverip.
+ */
+ rootaddr = net_parse_rootpath();
+ if (rootaddr == INADDR_NONE)
+ rootaddr = serveraddr;
+ if (rootaddr == INADDR_NONE) {
+ printf("No server address for rootpath '%s'\n", envstr);
+ return;
+ }
+ rootip.s_addr = rootaddr;
+
+ /*
+ * Gateway IP is optional unless rootip is on a different net in which
+ * case whine if it's missing or we can't parse it, and set rootip addr
+ * to zero, which signals to other network code that network params
+ * aren't set (so it will try dhcp, bootp, etc).
+ */
+ envstr = ub_env_get("gatewayip");
+ if (!SAMENET(myip, rootip, netmask)) {
+ if (envstr == NULL) {
+ printf("Need gatewayip for a root server on a "
+ "different network.\n");
+ rootip.s_addr = 0;
+ return;
+ }
+ if ((gateip.s_addr = inet_addr(envstr) == INADDR_NONE)) {
+ printf("Could not parse gatewayip '%s'\n", envstr);
+ rootip.s_addr = 0;
+ return;
+ }
+ }
+}
+
+static int
+net_match(struct netif *nif, void *machdep_hint)
+{
+ char **a = (char **)machdep_hint;
+
+ if (memcmp("net", *a, 3) == 0)
+ return (1);
+
+ printf("net_match: could not match network device\n");
+ return (0);
+}
+
+static int
+net_probe(struct netif *nif, void *machdep_hint)
+{
+ struct device_info *di;
+ int i;
+
+ for (i = 0; i < devs_no; i++)
+ if ((di = ub_dev_get(i)) != NULL)
+ if (di->type == DEV_TYP_NET)
+ break;
+
+ if (i == devs_no) {
+ printf("net_probe: no network devices found, maybe not"
+ " enumerated yet..?\n");
+ return (-1);
+ }
+
+#if defined(NETIF_DEBUG)
+ printf("net_probe: network device found: %d\n", i);
+#endif
+ uboot_softc.sc_handle = i;
+
+ return (0);
+}
+
+static int
+net_put(struct iodesc *desc, void *pkt, size_t len)
+{
+ struct netif *nif = desc->io_netif;
+ struct uboot_softc *sc = nif->nif_devdata;
+ size_t sendlen;
+ ssize_t rv;
+
+#if defined(NETIF_DEBUG)
+ struct ether_header *eh;
+
+ printf("net_put: desc %p, pkt %p, len %d\n", desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xffff);
+#endif
+
+ if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
+ sendlen = ETHER_MIN_LEN - ETHER_CRC_LEN;
+ bzero(sc->sc_txbufp, sendlen);
+ } else
+ sendlen = len;
+
+ memcpy(sc->sc_txbufp, pkt, len);
+
+ rv = ub_dev_send(sc->sc_handle, sc->sc_txbufp, sendlen);
+
+#if defined(NETIF_DEBUG)
+ printf("net_put: ub_send returned %d\n", rv);
+#endif
+ if (rv == 0)
+ rv = len;
+ else
+ rv = -1;
+
+ return (rv);
+}
+
+static int
+net_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+{
+ struct netif *nif = desc->io_netif;
+ struct uboot_softc *sc = nif->nif_devdata;
+ time_t t;
+ int err, rlen;
+
+#if defined(NETIF_DEBUG)
+ printf("net_get: pkt %p, len %d, timeout %d\n", pkt, len, timeout);
+#endif
+ t = getsecs();
+ do {
+ err = ub_dev_recv(sc->sc_handle, sc->sc_rxbuf, len, &rlen);
+
+ if (err != 0) {
+ printf("net_get: ub_dev_recv() failed, error=%d\n",
+ err);
+ rlen = 0;
+ break;
+ }
+ } while ((rlen == -1 || rlen == 0) && (getsecs() - t < timeout));
+
+#if defined(NETIF_DEBUG)
+ printf("net_get: received len %d (%x)\n", rlen, rlen);
+#endif
+
+ if (rlen > 0) {
+ memcpy(pkt, sc->sc_rxbuf, MIN(len, rlen));
+ if (rlen != len) {
+#if defined(NETIF_DEBUG)
+ printf("net_get: len %x, rlen %x\n", len, rlen);
+#endif
+ }
+ return (rlen);
+ }
+
+ return (-1);
+}
+
+static void
+net_init(struct iodesc *desc, void *machdep_hint)
+{
+ struct netif *nif = desc->io_netif;
+ struct uboot_softc *sc;
+ struct device_info *di;
+ int err;
+
+ sc = nif->nif_devdata = &uboot_softc;
+
+ if ((err = ub_dev_open(sc->sc_handle)) != 0)
+ panic("%s%d: initialisation failed with error %d\n",
+ nif->nif_driver->netif_bname, nif->nif_unit, err);
+
+ /* Get MAC address */
+ di = ub_dev_get(sc->sc_handle);
+ memcpy(desc->myea, di->di_net.hwaddr, 6);
+ if (memcmp (desc->myea, "\0\0\0\0\0\0", 6) == 0) {
+ panic("%s%d: empty ethernet address!",
+ nif->nif_driver->netif_bname, nif->nif_unit);
+ }
+
+ /* Attempt to get netboot params from the u-boot env. */
+ get_env_net_params();
+ if (myip.s_addr != 0)
+ desc->myip = myip;
+
+#if defined(NETIF_DEBUG)
+ printf("network: %s%d attached to %s\n", nif->nif_driver->netif_bname,
+ nif->nif_unit, ether_sprintf(desc->myea));
+#endif
+
+ /* Set correct alignment for TX packets */
+ sc->sc_txbufp = sc->sc_txbuf;
+ if ((unsigned long)sc->sc_txbufp % PKTALIGN)
+ sc->sc_txbufp += PKTALIGN -
+ (unsigned long)sc->sc_txbufp % PKTALIGN;
+}
+
+static void
+net_end(struct netif *nif)
+{
+ struct uboot_softc *sc = nif->nif_devdata;
+ int err;
+
+ if ((err = ub_dev_close(sc->sc_handle)) != 0)
+ panic("%s%d: net_end failed with error %d\n",
+ nif->nif_driver->netif_bname, nif->nif_unit, err);
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/reboot.c b/usr/src/boot/sys/boot/uboot/lib/reboot.c
new file mode 100644
index 0000000000..9f4d277eb6
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/reboot.c
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "glue.h"
+
+void
+exit(int code)
+{
+
+ ub_reset();
+}
diff --git a/usr/src/boot/sys/boot/uboot/lib/time.c b/usr/src/boot/sys/boot/uboot/lib/time.c
new file mode 100644
index 0000000000..9083675b75
--- /dev/null
+++ b/usr/src/boot/sys/boot/uboot/lib/time.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2000 Benno Rice
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include "glue.h"
+
+/*
+ * Return the time in seconds since the beginning of the day.
+ */
+time_t
+time(time_t *tloc)
+{
+ int secs;
+
+ secs = ub_get_timer(0) / 1000;
+ if (tloc)
+ *tloc = secs;
+
+ return (secs);
+}
+
+int
+getsecs(void)
+{
+
+ return (time(NULL));
+}
+
+/*
+ * Use U-Boot udelay() function to wait for a given microseconds period
+ */
+void
+delay(int usecs)
+{
+
+ ub_udelay(usecs);
+}
diff --git a/usr/src/boot/sys/boot/usb/Makefile b/usr/src/boot/sys/boot/usb/Makefile
new file mode 100644
index 0000000000..1b94b3db7d
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/Makefile
@@ -0,0 +1,58 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky.
+# Copyright (c) 2014 SRI International
+# All rights reserved.
+#
+# This software was developed by SRI International and the University of
+# Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+# ("CTSRD"), as part of the DARPA CRASH research programme.
+#
+# 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+
+LIB= usbboot
+INTERNALLIB=
+
+CFLAGS+= -DBOOTPROG=\"usbloader\"
+CFLAGS+= -ffunction-sections -fdata-sections
+CFLAGS+= -ffreestanding
+CFLAGS+= -Wformat -Wall
+CFLAGS+= -g
+CFLAGS+= -fno-pic
+
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+= -march=i386
+CFLAGS.gcc+= -mpreferred-stack-boundary=2
+.endif
+.if ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+= -m32
+.endif
+.if ${MACHINE_CPUARCH} == "mips"
+CFLAGS+= -mno-abicalls
+.endif
+
+
+.include "usbcore.mk"
+.include "../kshim/kshim.mk"
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/usb/Makefile.test b/usr/src/boot/sys/boot/usb/Makefile.test
new file mode 100644
index 0000000000..7c6a66d173
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/Makefile.test
@@ -0,0 +1,61 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky. 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+
+#
+# USB test application
+#
+
+.PATH: ${.CURDIR}
+
+PROG= usbloader
+MAN=
+SRCS=
+
+CFLAGS+= -Wall
+CFLAGS+= -g
+
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+= -march=i386
+CFLAGS.gcc+= -mpreferred-stack-boundary=2
+.endif
+.if ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+= -m32
+.endif
+
+LDFLAGS+= -Wl,--gc-sections
+
+SRCS+= bsd_usbloader_test.c
+
+LDADD+= libusbboot.a
+DPADD+= libusbboot.a
+
+.include <bsd.prog.mk>
+
+${PROG}: libusbboot.a
+
+libusbboot.a:
+ make -f Makefile
diff --git a/usr/src/boot/sys/boot/usb/bsd_usbloader_test.c b/usr/src/boot/sys/boot/usb/bsd_usbloader_test.c
new file mode 100644
index 0000000000..8744e2e763
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/bsd_usbloader_test.c
@@ -0,0 +1,95 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+
+extern int usleep(int);
+extern void callout_process(int);
+extern void usb_idle(void);
+extern void usb_init(void);
+extern void usb_uninit(void);
+
+#define hz 1000
+
+#ifdef HAVE_MALLOC
+void *
+usb_malloc(size_t size)
+{
+ return (malloc(size));
+}
+
+void
+usb_free(void *ptr)
+{
+ free(ptr);
+}
+#endif
+
+void
+DELAY(unsigned int delay)
+{
+ usleep(delay);
+}
+
+int
+pause(const char *what, int timeout)
+{
+ if (timeout == 0)
+ timeout = 1;
+
+ usleep((1000000 / hz) * timeout);
+
+ return (0);
+}
+
+int
+main(int argc, char **argv)
+{
+ uint32_t time;
+
+ usb_init();
+
+ time = 0;
+
+ while (1) {
+
+ usb_idle();
+
+ usleep(1000);
+
+ if (++time >= (1000 / hz)) {
+ time = 0;
+ callout_process(1);
+ }
+ }
+
+ usb_uninit();
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/usb/storage/umass_common.c b/usr/src/boot/sys/boot/usb/storage/umass_common.c
new file mode 100644
index 0000000000..5ddd159297
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/storage/umass_common.c
@@ -0,0 +1,90 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include USB_GLOBAL_INCLUDE_FILE
+
+#include "umass_common.h"
+
+struct usb_attach_arg umass_uaa;
+
+static device_probe_t umass_probe;
+static device_attach_t umass_attach;
+static device_detach_t umass_detach;
+
+static devclass_t umass_devclass;
+
+static device_method_t umass_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, umass_probe),
+ DEVMETHOD(device_attach, umass_attach),
+ DEVMETHOD(device_detach, umass_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t umass_driver = {
+ .name = "umass",
+ .methods = umass_methods,
+};
+
+DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);
+
+static int
+umass_probe(device_t dev)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+
+ if (uaa->usb_mode != USB_MODE_HOST ||
+ uaa->info.bInterfaceClass != UICLASS_MASS ||
+ uaa->info.bInterfaceSubClass != UISUBCLASS_SCSI ||
+ uaa->info.bInterfaceProtocol != UIPROTO_MASS_BBB ||
+ device_get_unit(dev) != 0)
+ return (ENXIO);
+ return (0);
+}
+
+static int
+umass_attach(device_t dev)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ umass_uaa = *uaa;
+ return (0); /* success */
+}
+
+static int
+umass_detach(device_t dev)
+{
+
+#ifdef USB_DEBUG
+ memset(&umass_uaa, 0, sizeof(umass_uaa));
+#endif
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/usb/storage/umass_common.h b/usr/src/boot/sys/boot/usb/storage/umass_common.h
new file mode 100644
index 0000000000..a8ffd4987e
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/storage/umass_common.h
@@ -0,0 +1,41 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#ifndef _UMASS_COMMON_H_
+#define _UMASS_COMMON_H_
+
+struct usb_attach_arg;
+struct devsw;
+
+extern struct usb_attach_arg umass_uaa;
+extern struct devsw umass_disk;
+
+#endif /* _UMASS_COMMON_H_ */
diff --git a/usr/src/boot/sys/boot/usb/storage/umass_loader.c b/usr/src/boot/sys/boot/usb/storage/umass_loader.c
new file mode 100644
index 0000000000..4311b2b65e
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/storage/umass_loader.c
@@ -0,0 +1,222 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/param.h>
+
+#include <bootstrap.h>
+#include <stdarg.h>
+
+#include <stand.h>
+#include <disk.h>
+
+#define HAVE_STANDARD_DEFS
+
+#include USB_GLOBAL_INCLUDE_FILE
+
+#include "umass_common.h"
+
+static int umass_disk_init(void);
+static int umass_disk_open(struct open_file *,...);
+static int umass_disk_close(struct open_file *);
+static void umass_disk_cleanup(void);
+static int umass_disk_ioctl(struct open_file *, u_long, void *);
+static int umass_disk_strategy(void *, int, daddr_t, size_t, char *, size_t *);
+static void umass_disk_print(int);
+
+struct devsw umass_disk = {
+ .dv_name = "umass",
+ .dv_type = DEVT_DISK,
+ .dv_init = umass_disk_init,
+ .dv_strategy = umass_disk_strategy,
+ .dv_open = umass_disk_open,
+ .dv_close = umass_disk_close,
+ .dv_ioctl = umass_disk_ioctl,
+ .dv_print = umass_disk_print,
+ .dv_cleanup = umass_disk_cleanup,
+};
+
+static int
+umass_disk_init(void)
+{
+ uint32_t time;
+
+ usb_init();
+ usb_needs_explore_all();
+
+ /* wait 8 seconds for a USB mass storage device to appear */
+ for (time = 0; time < (8 * hz); time++) {
+ usb_idle();
+ delay(1000000 / hz);
+ time++;
+ callout_process(1);
+ if (umass_uaa.device != NULL)
+ return (0);
+ }
+ return (0);
+}
+
+static int
+umass_disk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
+ char *buf, size_t *rsizep)
+{
+ if (umass_uaa.device == NULL)
+ return (ENXIO);
+ if (rsizep != NULL)
+ *rsizep = 0;
+
+ if (flag == F_WRITE) {
+ if (usb_msc_write_10(umass_uaa.device, 0, dblk, size >> 9, buf) != 0)
+ return (EINVAL);
+ } else if (flag == F_READ) {
+ if (usb_msc_read_10(umass_uaa.device, 0, dblk, size >> 9, buf) != 0)
+ return (EINVAL);
+ } else {
+ return (EROFS);
+ }
+
+ if (rsizep != NULL)
+ *rsizep = size;
+ return (0);
+}
+
+static int
+umass_disk_open_sub(struct disk_devdesc *dev)
+{
+ uint32_t nblock;
+ uint32_t blocksize;
+
+ if (usb_msc_read_capacity(umass_uaa.device, 0, &nblock, &blocksize) != 0)
+ return (EINVAL);
+
+ return (disk_open(dev, ((uint64_t)nblock + 1) * (uint64_t)blocksize, blocksize, 0));
+}
+
+static int
+umass_disk_open(struct open_file *f,...)
+{
+ va_list ap;
+ struct disk_devdesc *dev;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct disk_devdesc *);
+ va_end(ap);
+
+ if (umass_uaa.device == NULL)
+ return (ENXIO);
+ if (dev->d_unit != 0)
+ return (EIO);
+ return (umass_disk_open_sub(dev));
+}
+
+static int
+umass_disk_ioctl(struct open_file *f __unused, u_long cmd, void *buf)
+{
+ uint32_t nblock;
+ uint32_t blocksize;
+
+ switch (cmd) {
+ case IOCTL_GET_BLOCK_SIZE:
+ case IOCTL_GET_BLOCKS:
+ if (usb_msc_read_capacity(umass_uaa.device, 0,
+ &nblock, &blocksize) != 0)
+ return (EINVAL);
+
+ if (cmd == IOCTL_GET_BLOCKS)
+ *(uint32_t*)buf = nblock;
+ else
+ *(uint32_t*)buf = blocksize;
+
+ return (0);
+ default:
+ return (ENXIO);
+ }
+}
+
+static int
+umass_disk_close(struct open_file *f)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ return (disk_close(dev));
+}
+
+static void
+umass_disk_print(int verbose)
+{
+ struct disk_devdesc dev;
+
+ memset(&dev, 0, sizeof(dev));
+
+ pager_output(" umass0 UMASS device\n");
+ dev.d_dev = &umass_disk;
+ dev.d_unit = 0;
+ dev.d_slice = -1;
+ dev.d_partition = -1;
+
+ if (umass_disk_open_sub(&dev) == 0) {
+ disk_print(&dev, " umass0", verbose);
+ disk_close(&dev);
+ }
+}
+
+static void
+umass_disk_cleanup(void)
+{
+ disk_cleanup(&umass_disk);
+
+ usb_uninit();
+}
+
+
+/* USB specific functions */
+
+extern void callout_process(int);
+extern void usb_idle(void);
+extern void usb_init(void);
+extern void usb_uninit(void);
+
+void
+DELAY(unsigned int usdelay)
+{
+ delay(usdelay);
+}
+
+int
+pause(const char *what, int timeout)
+{
+ if (timeout == 0)
+ timeout = 1;
+
+ delay((1000000 / hz) * timeout);
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/usb/tools/Makefile b/usr/src/boot/sys/boot/usb/tools/Makefile
new file mode 100644
index 0000000000..64cf28ca75
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/tools/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= sysinit
+MAN=
+
+CFLAGS+= -I${.CURDIR}/../../kshim
+
+BINDIR?= /usr/bin
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/usb/tools/sysinit.c b/usr/src/boot/sys/boot/usb/tools/sysinit.c
new file mode 100644
index 0000000000..b968fe0ab8
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/tools/sysinit.c
@@ -0,0 +1,331 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+/*
+ * This utility sorts sysinit structure entries in binary format and
+ * prints out the result in C-format.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <err.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sysexits.h>
+#include "sysinit.h"
+
+static int opt_R;
+static const char *input_f;
+static const char *output_f;
+static const char *struct_name;
+static const char *keyword;
+static struct sysinit_data **start;
+static struct sysinit_data **stop;
+
+static int input_file = -1;
+static int output_file = -1;
+
+static uint8_t *input_ptr;
+static uint32_t input_len;
+
+static uint32_t endian32;
+
+static char scratch_buf[4096];
+
+static int success;
+
+static void do_sysinit(void);
+
+/* the following function converts the numbers into host endian format */
+
+static uint32_t
+read32(uint32_t val)
+{
+ uint32_t temp;
+ uint32_t endian;
+
+ endian = endian32;
+ temp = 0;
+
+ while (val) {
+ temp |= (val & 0xF) << ((endian & 0xF) * 4);
+ endian >>= 4;
+ val >>= 4;
+ }
+ return (temp);
+}
+
+static void
+do_write(int fd, const char *buf)
+{
+ int len = strlen(buf);
+
+ if (write(fd, buf, len) != len)
+ err(EX_SOFTWARE, "Could not write to output file");
+}
+
+static void *
+do_malloc(int size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+ if (ptr == NULL)
+ errx(EX_SOFTWARE, "Could not allocate memory");
+ return (ptr);
+}
+
+static void
+usage(void)
+{
+ errx(EX_USAGE, "sysinit -i sysinit.bin -o sysinit_data.c \\\n"
+ "\t" "-k sysinit -s sysinit_data [ -R (reverse)]");
+}
+
+static void
+cleanup(void)
+{
+ if (output_file >= 0)
+ close(output_file);
+ if (input_file >= 0)
+ close(input_file);
+ if (success == 0) {
+ if (output_f)
+ unlink(output_f);
+ }
+}
+
+static int
+compare(const void *_pa, const void *_pb)
+{
+ const struct sysinit_data * const *pa = _pa;
+ const struct sysinit_data * const *pb = _pb;
+
+ if ((*pa)->dw_msb_value > (*pb)->dw_msb_value)
+ return (1);
+
+ if ((*pa)->dw_msb_value < (*pb)->dw_msb_value)
+ return (-1);
+
+ if ((*pa)->dw_lsb_value > (*pb)->dw_lsb_value)
+ return (1);
+
+ if ((*pa)->dw_lsb_value < (*pb)->dw_lsb_value)
+ return (-1);
+
+ return (0); /* equal */
+}
+
+static int
+compare_R(const void *_pa, const void *_pb)
+{
+ const struct sysinit_data * const *pa = _pa;
+ const struct sysinit_data * const *pb = _pb;
+
+ if ((*pa)->dw_msb_value > (*pb)->dw_msb_value)
+ return (-1);
+
+ if ((*pa)->dw_msb_value < (*pb)->dw_msb_value)
+ return (1);
+
+ if ((*pa)->dw_lsb_value > (*pb)->dw_lsb_value)
+ return (-1);
+
+ if ((*pa)->dw_lsb_value < (*pb)->dw_lsb_value)
+ return (1);
+
+ return (0); /* equal */
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sysinit_data **sipp;
+ int c;
+ int entries;
+ off_t off;
+
+ while ((c = getopt(argc, argv, "k:s:i:o:Rh")) != -1) {
+ switch (c) {
+ case 'i':
+ input_f = optarg;
+ break;
+ case 'o':
+ output_f = optarg;
+ break;
+ case 'R':
+ opt_R = 1;
+ break;
+ case 'k':
+ keyword = optarg;
+ break;
+ case 's':
+ struct_name = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (input_f == NULL || output_f == NULL ||
+ struct_name == NULL || keyword == NULL)
+ usage();
+
+ atexit(&cleanup);
+
+ cleanup();
+
+ input_file = open(input_f, O_RDONLY);
+ if (input_file < 0)
+ err(EX_SOFTWARE, "Could not open input file: %s", input_f);
+
+ output_file = open(output_f, O_TRUNC | O_CREAT | O_RDWR, 0600);
+ if (output_file < 0)
+ err(EX_SOFTWARE, "Could not open output file: %s", output_f);
+
+ off = lseek(input_file, 0, SEEK_END);
+
+ input_ptr = do_malloc(off);
+ input_len = off;
+
+ if (input_len % (uint32_t)sizeof(struct sysinit_data)) {
+ errx(EX_SOFTWARE, "Input file size is not divisible by %u",
+ (unsigned int)sizeof(struct sysinit_data));
+ }
+ off = lseek(input_file, 0, SEEK_SET);
+ if (off < 0)
+ err(EX_SOFTWARE, "Could not seek to start of input file");
+
+ if (read(input_file, input_ptr, input_len) != input_len)
+ err(EX_SOFTWARE, "Could not read input file");
+
+ entries = input_len / (uint32_t)sizeof(struct sysinit_data);
+
+ start = do_malloc(sizeof(void *) * entries);
+ stop = start + entries;
+
+ for (c = 0; c != entries; c++)
+ start[c] = &((struct sysinit_data *)input_ptr)[c];
+
+ if (start != stop)
+ endian32 = (*start)->dw_endian32;
+
+ /* switch all fields to host endian order */
+ for (sipp = start; sipp < stop; sipp++) {
+ (*sipp)->dw_lsb_value = read32((*sipp)->dw_lsb_value);
+ (*sipp)->dw_msb_value = read32((*sipp)->dw_msb_value);
+ (*sipp)->dw_file_line = read32((*sipp)->dw_file_line);
+ }
+
+ if (opt_R == 0) {
+ /* sort entries, rising numerical order */
+ qsort(start, entries, sizeof(void *), &compare);
+ } else {
+ /* sort entries, falling numerical order */
+ qsort(start, entries, sizeof(void *), &compare_R);
+ }
+
+ /* safe all strings */
+ for (sipp = start; sipp < stop; sipp++) {
+ (*sipp)->b_keyword_name[sizeof((*sipp)->b_keyword_name) - 1] = 0;
+ (*sipp)->b_global_type[sizeof((*sipp)->b_global_type) - 1] = 0;
+ (*sipp)->b_global_name[sizeof((*sipp)->b_global_name) - 1] = 0;
+ (*sipp)->b_file_name[sizeof((*sipp)->b_file_name) - 1] = 0;
+ (*sipp)->b_debug_info[sizeof((*sipp)->b_debug_info) - 1] = 0;
+ }
+
+ if (strcmp(keyword, "sysinit") == 0)
+ do_sysinit();
+ else if (strcmp(keyword, "sysuninit") == 0)
+ do_sysinit();
+ else
+ errx(EX_USAGE, "Unknown keyword '%s'", keyword);
+
+ success = 1;
+
+ return (0);
+}
+
+static void
+do_sysinit(void)
+{
+ struct sysinit_data **sipp;
+ int c;
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "/*\n"
+ " * This file was automatically generated.\n"
+ " * Please do not edit.\n"
+ " */\n\n");
+
+ /* write out externals */
+ for (c = 0, sipp = start; sipp < stop; c++, sipp++) {
+ if (strcmp((const char *)(*sipp)->b_keyword_name, keyword))
+ continue;
+ if ((*sipp)->dw_msb_value == 0)
+ continue;
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "/* #%04u: %s entry at %s:%u */\n",
+ c, (*sipp)->b_debug_info, (*sipp)->b_file_name,
+ (unsigned int)(*sipp)->dw_file_line);
+
+ do_write(output_file, scratch_buf);
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "extern %s %s;\n\n", (*sipp)->b_global_type,
+ (*sipp)->b_global_name);
+
+ do_write(output_file, scratch_buf);
+ }
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "const void *%s[] = {\n", struct_name);
+
+ do_write(output_file, scratch_buf);
+
+ /* write out actual table */
+ for (c = 0, sipp = start; sipp < stop; c++, sipp++) {
+ if (strcmp((const char *)(*sipp)->b_keyword_name, keyword))
+ continue;
+ if ((*sipp)->dw_msb_value == 0)
+ continue;
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "\t&%s, /* #%04u */\n",
+ (*sipp)->b_global_name, (unsigned int)c);
+
+ do_write(output_file, scratch_buf);
+ }
+
+ snprintf(scratch_buf, sizeof(scratch_buf),
+ "\t(const void *)0\n"
+ "};\n");
+
+ do_write(output_file, scratch_buf);
+}
diff --git a/usr/src/boot/sys/boot/usb/usb_busdma_loader.c b/usr/src/boot/sys/boot/usb/usb_busdma_loader.c
new file mode 100644
index 0000000000..90dc1692ba
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/usb_busdma_loader.c
@@ -0,0 +1,619 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <bsd_global.h>
+
+#if USB_HAVE_BUSDMA
+static void usb_pc_common_mem_cb(struct usb_page_cache *pc,
+ void *vaddr, uint32_t length);
+#endif
+
+/*------------------------------------------------------------------------*
+ * usbd_get_page - lookup DMA-able memory for the given offset
+ *
+ * NOTE: Only call this function when the "page_cache" structure has
+ * been properly initialized !
+ *------------------------------------------------------------------------*/
+void
+usbd_get_page(struct usb_page_cache *pc, usb_frlength_t offset,
+ struct usb_page_search *res)
+{
+#if USB_HAVE_BUSDMA
+ struct usb_page *page;
+
+ if (pc->page_start) {
+
+ /* Case 1 - something has been loaded into DMA */
+
+ if (pc->buffer) {
+
+ /* Case 1a - Kernel Virtual Address */
+
+ res->buffer = USB_ADD_BYTES(pc->buffer, offset);
+ }
+ offset += pc->page_offset_buf;
+
+ /* compute destination page */
+
+ page = pc->page_start;
+
+ if (pc->ismultiseg) {
+
+ page += (offset / USB_PAGE_SIZE);
+
+ offset %= USB_PAGE_SIZE;
+
+ res->length = USB_PAGE_SIZE - offset;
+ res->physaddr = page->physaddr + offset;
+ } else {
+ res->length = (usb_size_t)-1;
+ res->physaddr = page->physaddr + offset;
+ }
+ if (!pc->buffer) {
+
+ /* Case 1b - Non Kernel Virtual Address */
+
+ res->buffer = USB_ADD_BYTES(page->buffer, offset);
+ }
+ return;
+ }
+#endif
+ /* Case 2 - Plain PIO */
+
+ res->buffer = USB_ADD_BYTES(pc->buffer, offset);
+ res->length = (usb_size_t)-1;
+#if USB_HAVE_BUSDMA
+ res->physaddr = 0;
+#endif
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_copy_in - copy directly to DMA-able memory
+ *------------------------------------------------------------------------*/
+void
+usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset,
+ const void *ptr, usb_frlength_t len)
+{
+ struct usb_page_search buf_res;
+
+ while (len != 0) {
+
+ usbd_get_page(cache, offset, &buf_res);
+
+ if (buf_res.length > len) {
+ buf_res.length = len;
+ }
+ memcpy(buf_res.buffer, ptr, buf_res.length);
+
+ offset += buf_res.length;
+ len -= buf_res.length;
+ ptr = USB_ADD_BYTES(ptr, buf_res.length);
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_copy_out - copy directly from DMA-able memory
+ *------------------------------------------------------------------------*/
+void
+usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset,
+ void *ptr, usb_frlength_t len)
+{
+ struct usb_page_search res;
+
+ while (len != 0) {
+
+ usbd_get_page(cache, offset, &res);
+
+ if (res.length > len) {
+ res.length = len;
+ }
+ memcpy(ptr, res.buffer, res.length);
+
+ offset += res.length;
+ len -= res.length;
+ ptr = USB_ADD_BYTES(ptr, res.length);
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_frame_zero - zero DMA-able memory
+ *------------------------------------------------------------------------*/
+void
+usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset,
+ usb_frlength_t len)
+{
+ struct usb_page_search res;
+
+ while (len != 0) {
+
+ usbd_get_page(cache, offset, &res);
+
+ if (res.length > len) {
+ res.length = len;
+ }
+ memset(res.buffer, 0, res.length);
+
+ offset += res.length;
+ len -= res.length;
+ }
+}
+
+#if USB_HAVE_BUSDMA
+
+/*------------------------------------------------------------------------*
+ * usb_pc_common_mem_cb - BUS-DMA callback function
+ *------------------------------------------------------------------------*/
+static void
+usb_pc_common_mem_cb(struct usb_page_cache *pc,
+ void *vaddr, uint32_t length)
+{
+ struct usb_page *pg;
+ usb_size_t rem;
+ bus_size_t off;
+ bus_addr_t phys = (uintptr_t)vaddr; /* XXX */
+ uint32_t nseg;
+
+ if (length == 0)
+ nseg = 1;
+ else
+ nseg = ((length + USB_PAGE_SIZE - 1) / USB_PAGE_SIZE);
+
+ pg = pc->page_start;
+ pg->physaddr = phys & ~(USB_PAGE_SIZE - 1);
+ rem = phys & (USB_PAGE_SIZE - 1);
+ pc->page_offset_buf = rem;
+ pc->page_offset_end += rem;
+ length += rem;
+
+ for (off = USB_PAGE_SIZE; off < length; off += USB_PAGE_SIZE) {
+ pg++;
+ pg->physaddr = (phys + off) & ~(USB_PAGE_SIZE - 1);
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_alloc_mem - allocate DMA'able memory
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+uint8_t
+usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
+ usb_size_t size, usb_size_t align)
+{
+ void *ptr;
+ uint32_t rem;
+
+ /* allocate zeroed memory */
+
+ if (align != 1) {
+ ptr = malloc(size + align, XXX, XXX);
+ if (ptr == NULL)
+ goto error;
+
+ rem = (-((uintptr_t)ptr)) & (align - 1);
+ } else {
+ ptr = malloc(size, XXX, XXX);
+ if (ptr == NULL)
+ goto error;
+ rem = 0;
+ }
+
+ /* setup page cache */
+ pc->buffer = ((uint8_t *)ptr) + rem;
+ pc->page_start = pg;
+ pc->page_offset_buf = 0;
+ pc->page_offset_end = size;
+ pc->map = NULL;
+ pc->tag = ptr;
+ pc->ismultiseg = (align == 1);
+
+ /* compute physical address */
+ usb_pc_common_mem_cb(pc, pc->buffer, size);
+
+ usb_pc_cpu_flush(pc);
+ return (0);
+
+error:
+ /* reset most of the page cache */
+ pc->buffer = NULL;
+ pc->page_start = NULL;
+ pc->page_offset_buf = 0;
+ pc->page_offset_end = 0;
+ pc->map = NULL;
+ pc->tag = NULL;
+ return (1);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_free_mem - free DMA memory
+ *
+ * This function is NULL safe.
+ *------------------------------------------------------------------------*/
+void
+usb_pc_free_mem(struct usb_page_cache *pc)
+{
+ if (pc != NULL && pc->buffer != NULL) {
+ free(pc->tag, XXX);
+ pc->buffer = NULL;
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_load_mem - load virtual memory into DMA
+ *
+ * Return values:
+ * 0: Success
+ * Else: Error
+ *------------------------------------------------------------------------*/
+uint8_t
+usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync)
+{
+ /* setup page cache */
+ pc->page_offset_buf = 0;
+ pc->page_offset_end = size;
+ pc->ismultiseg = 1;
+
+ mtx_assert(pc->tag_parent->mtx, MA_OWNED);
+
+ if (size > 0) {
+ /* compute physical address */
+ usb_pc_common_mem_cb(pc, pc->buffer, size);
+ }
+ if (sync == 0) {
+ /*
+ * Call callback so that refcount is decremented
+ * properly:
+ */
+ pc->tag_parent->dma_error = 0;
+ (pc->tag_parent->func) (pc->tag_parent);
+ }
+ return (0);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_cpu_invalidate - invalidate CPU cache
+ *------------------------------------------------------------------------*/
+void
+usb_pc_cpu_invalidate(struct usb_page_cache *pc)
+{
+ if (pc->page_offset_end == pc->page_offset_buf) {
+ /* nothing has been loaded into this page cache! */
+ return;
+ }
+ /* NOP */
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_cpu_flush - flush CPU cache
+ *------------------------------------------------------------------------*/
+void
+usb_pc_cpu_flush(struct usb_page_cache *pc)
+{
+ if (pc->page_offset_end == pc->page_offset_buf) {
+ /* nothing has been loaded into this page cache! */
+ return;
+ }
+ /* NOP */
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_dmamap_create - create a DMA map
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+uint8_t
+usb_pc_dmamap_create(struct usb_page_cache *pc, usb_size_t size)
+{
+ return (0); /* NOP, success */
+}
+
+/*------------------------------------------------------------------------*
+ * usb_pc_dmamap_destroy
+ *
+ * This function is NULL safe.
+ *------------------------------------------------------------------------*/
+void
+usb_pc_dmamap_destroy(struct usb_page_cache *pc)
+{
+ /* NOP */
+}
+
+/*------------------------------------------------------------------------*
+ * usb_dma_tag_setup - initialise USB DMA tags
+ *------------------------------------------------------------------------*/
+void
+usb_dma_tag_setup(struct usb_dma_parent_tag *udpt,
+ struct usb_dma_tag *udt, bus_dma_tag_t dmat,
+ struct mtx *mtx, usb_dma_callback_t *func,
+ uint8_t ndmabits, uint8_t nudt)
+{
+ memset(udpt, 0, sizeof(*udpt));
+
+ /* sanity checking */
+ if ((nudt == 0) ||
+ (ndmabits == 0) ||
+ (mtx == NULL)) {
+ /* something is corrupt */
+ return;
+ }
+ /* initialise condition variable */
+ cv_init(udpt->cv, "USB DMA CV");
+
+ /* store some information */
+ udpt->mtx = mtx;
+ udpt->func = func;
+ udpt->tag = dmat;
+ udpt->utag_first = udt;
+ udpt->utag_max = nudt;
+ udpt->dma_bits = ndmabits;
+
+ while (nudt--) {
+ memset(udt, 0, sizeof(*udt));
+ udt->tag_parent = udpt;
+ udt++;
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bus_tag_unsetup - factored out code
+ *------------------------------------------------------------------------*/
+void
+usb_dma_tag_unsetup(struct usb_dma_parent_tag *udpt)
+{
+ struct usb_dma_tag *udt;
+ uint8_t nudt;
+
+ udt = udpt->utag_first;
+ nudt = udpt->utag_max;
+
+ while (nudt--) {
+ udt->align = 0;
+ udt++;
+ }
+
+ if (udpt->utag_max) {
+ /* destroy the condition variable */
+ cv_destroy(udpt->cv);
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bdma_work_loop
+ *
+ * This function handles loading of virtual buffers into DMA and is
+ * only called when "dma_refcount" is zero.
+ *------------------------------------------------------------------------*/
+void
+usb_bdma_work_loop(struct usb_xfer_queue *pq)
+{
+ struct usb_xfer_root *info;
+ struct usb_xfer *xfer;
+ usb_frcount_t nframes;
+
+ xfer = pq->curr;
+ info = xfer->xroot;
+
+ mtx_assert(info->xfer_mtx, MA_OWNED);
+
+ if (xfer->error) {
+ /* some error happened */
+ USB_BUS_LOCK(info->bus);
+ usbd_transfer_done(xfer, 0);
+ USB_BUS_UNLOCK(info->bus);
+ return;
+ }
+ if (!xfer->flags_int.bdma_setup) {
+ struct usb_page *pg;
+ usb_frlength_t frlength_0;
+ uint8_t isread;
+
+ xfer->flags_int.bdma_setup = 1;
+
+ /* reset BUS-DMA load state */
+
+ info->dma_error = 0;
+
+ if (xfer->flags_int.isochronous_xfr) {
+ /* only one frame buffer */
+ nframes = 1;
+ frlength_0 = xfer->sumlen;
+ } else {
+ /* can be multiple frame buffers */
+ nframes = xfer->nframes;
+ frlength_0 = xfer->frlengths[0];
+ }
+
+ /*
+ * Set DMA direction first. This is needed to
+ * select the correct cache invalidate and cache
+ * flush operations.
+ */
+ isread = USB_GET_DATA_ISREAD(xfer);
+ pg = xfer->dma_page_ptr;
+
+ if (xfer->flags_int.control_xfr &&
+ xfer->flags_int.control_hdr) {
+ /* special case */
+ if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
+ /* The device controller writes to memory */
+ xfer->frbuffers[0].isread = 1;
+ } else {
+ /* The host controller reads from memory */
+ xfer->frbuffers[0].isread = 0;
+ }
+ } else {
+ /* default case */
+ xfer->frbuffers[0].isread = isread;
+ }
+
+ /*
+ * Setup the "page_start" pointer which points to an array of
+ * USB pages where information about the physical address of a
+ * page will be stored. Also initialise the "isread" field of
+ * the USB page caches.
+ */
+ xfer->frbuffers[0].page_start = pg;
+
+ info->dma_nframes = nframes;
+ info->dma_currframe = 0;
+ info->dma_frlength_0 = frlength_0;
+
+ pg += (frlength_0 / USB_PAGE_SIZE);
+ pg += 2;
+
+ while (--nframes > 0) {
+ xfer->frbuffers[nframes].isread = isread;
+ xfer->frbuffers[nframes].page_start = pg;
+
+ pg += (xfer->frlengths[nframes] / USB_PAGE_SIZE);
+ pg += 2;
+ }
+
+ }
+ if (info->dma_error) {
+ USB_BUS_LOCK(info->bus);
+ usbd_transfer_done(xfer, USB_ERR_DMA_LOAD_FAILED);
+ USB_BUS_UNLOCK(info->bus);
+ return;
+ }
+ if (info->dma_currframe != info->dma_nframes) {
+
+ if (info->dma_currframe == 0) {
+ /* special case */
+ usb_pc_load_mem(xfer->frbuffers,
+ info->dma_frlength_0, 0);
+ } else {
+ /* default case */
+ nframes = info->dma_currframe;
+ usb_pc_load_mem(xfer->frbuffers + nframes,
+ xfer->frlengths[nframes], 0);
+ }
+
+ /* advance frame index */
+ info->dma_currframe++;
+
+ return;
+ }
+ /* go ahead */
+ usb_bdma_pre_sync(xfer);
+
+ /* start loading next USB transfer, if any */
+ usb_command_wrapper(pq, NULL);
+
+ /* finally start the hardware */
+ usbd_pipe_enter(xfer);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bdma_done_event
+ *
+ * This function is called when the BUS-DMA has loaded virtual memory
+ * into DMA, if any.
+ *------------------------------------------------------------------------*/
+void
+usb_bdma_done_event(struct usb_dma_parent_tag *udpt)
+{
+ struct usb_xfer_root *info;
+
+ info = USB_DMATAG_TO_XROOT(udpt);
+
+ mtx_assert(info->xfer_mtx, MA_OWNED);
+
+ /* copy error */
+ info->dma_error = udpt->dma_error;
+
+ /* enter workloop again */
+ usb_command_wrapper(&info->dma_q,
+ info->dma_q.curr);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bdma_pre_sync
+ *
+ * This function handles DMA synchronisation that must be done before
+ * an USB transfer is started.
+ *------------------------------------------------------------------------*/
+void
+usb_bdma_pre_sync(struct usb_xfer *xfer)
+{
+ struct usb_page_cache *pc;
+ usb_frcount_t nframes;
+
+ if (xfer->flags_int.isochronous_xfr) {
+ /* only one frame buffer */
+ nframes = 1;
+ } else {
+ /* can be multiple frame buffers */
+ nframes = xfer->nframes;
+ }
+
+ pc = xfer->frbuffers;
+
+ while (nframes--) {
+
+ if (pc->isread) {
+ usb_pc_cpu_invalidate(pc);
+ } else {
+ usb_pc_cpu_flush(pc);
+ }
+ pc++;
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bdma_post_sync
+ *
+ * This function handles DMA synchronisation that must be done after
+ * an USB transfer is complete.
+ *------------------------------------------------------------------------*/
+void
+usb_bdma_post_sync(struct usb_xfer *xfer)
+{
+ struct usb_page_cache *pc;
+ usb_frcount_t nframes;
+
+ if (xfer->flags_int.isochronous_xfr) {
+ /* only one frame buffer */
+ nframes = 1;
+ } else {
+ /* can be multiple frame buffers */
+ nframes = xfer->nframes;
+ }
+
+ pc = xfer->frbuffers;
+
+ while (nframes--) {
+ if (pc->isread) {
+ usb_pc_cpu_invalidate(pc);
+ }
+ pc++;
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/boot/usb/usbcore.mk b/usr/src/boot/sys/boot/usb/usbcore.mk
new file mode 100644
index 0000000000..153a1d435c
--- /dev/null
+++ b/usr/src/boot/sys/boot/usb/usbcore.mk
@@ -0,0 +1,175 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky.
+# Copyright (c) 2014 SRI International
+# All rights reserved.
+#
+# This software was developed by SRI International and the University of
+# Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+# ("CTSRD"), as part of the DARPA CRASH research programme.
+#
+# 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.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+#
+
+USBCOREDIR:= ${.PARSEDIR}
+S=${USBCOREDIR}/../..
+
+MACHDEP_DIRS=
+
+.if defined(HAVE_EXYNOS_EHCI)
+MACHDEP_DIRS+= ${S}/arm/samsung/exynos
+.endif
+
+.PATH: \
+ ${USBCOREDIR} \
+ ${USBCOREDIR}/storage \
+ ${S}/dev/usb \
+ ${S}/dev/usb/controller \
+ ${S}/dev/usb/serial \
+ ${S}/dev/usb/storage \
+ ${S}/dev/usb/template \
+ ${MACHDEP_DIRS}
+.undef S
+
+USB_POOL_SIZE?= 131072
+
+CFLAGS+= -DUSB_MSCTEST_BULK_SIZE=65536
+CFLAGS+= -DUSB_POOL_SIZE=${USB_POOL_SIZE}
+
+
+#
+# BUSDMA implementation
+#
+SRCS+= usb_busdma_loader.c
+
+#
+# USB controller drivers
+#
+
+KSRCS+= usb_controller.c
+
+.if defined(HAVE_AT91DCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"at91dci\""
+KSRCS+= at91dci.c
+.endif
+
+.if defined(HAVE_ATMEGADCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"atmegadci\""
+KSRCS+= atmegadci.c
+.endif
+
+.if defined(HAVE_AVR32DCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"avr32dci\""
+KSRCS+= avr32dci.c
+.endif
+
+.if defined(HAVE_DWCOTG)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"dwcotg\""
+KSRCS+= dwcotg.c
+.endif
+
+.if defined(HAVE_MUSBOTG)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"musbotg\""
+KSRCS+= musbotg.c
+.endif
+
+.if defined(HAVE_EHCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"ehci\""
+KSRCS+= ehci.c
+.endif
+
+.if defined(HAVE_EXYNOS_EHCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"combiner\", \"pad\", \"ehci\""
+KSRCS+= ehci.c
+KSRCS+= exynos5_combiner.c
+KSRCS+= exynos5_pad.c
+KSRCS+= exynos5_ehci.c
+.endif
+
+.if defined(HAVE_OHCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"ohci\""
+KSRCS+= ohci.c
+.endif
+
+.if defined(HAVE_UHCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"uhci\""
+KSRCS+= uhci.c
+.endif
+
+.if defined(HAVE_XHCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"xhci\""
+KSRCS+= xhci.c
+.endif
+
+.if defined(HAVE_USS820DCI)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"uss820dci\""
+KSRCS+= uss820dci.c
+.endif
+
+.if defined(HAVE_SAF1761OTG)
+CFLAGS += -DUSB_PCI_PROBE_LIST="\"saf1761otg\""
+CFLAGS += -DUSB_PCI_MEMORY_ADDRESS=0x900000007f100000ULL
+CFLAGS += -DUSB_PCI_MEMORY_SIZE=0x40000U
+KSRCS+= saf1761_otg.c
+KSRCS+= saf1761_otg_boot.c
+.endif
+
+#
+# USB core and templates
+#
+KSRCS+= usb_core.c
+KSRCS+= usb_debug.c
+KSRCS+= usb_device.c
+KSRCS+= usb_dynamic.c
+KSRCS+= usb_error.c
+KSRCS+= usb_handle_request.c
+KSRCS+= usb_hid.c
+KSRCS+= usb_hub.c
+KSRCS+= usb_lookup.c
+KSRCS+= usb_msctest.c
+KSRCS+= usb_parse.c
+KSRCS+= usb_request.c
+KSRCS+= usb_transfer.c
+KSRCS+= usb_util.c
+KSRCS+= usb_template.c
+KSRCS+= usb_template_cdce.c
+KSRCS+= usb_template_msc.c
+KSRCS+= usb_template_mtp.c
+KSRCS+= usb_template_modem.c
+KSRCS+= usb_template_mouse.c
+KSRCS+= usb_template_kbd.c
+KSRCS+= usb_template_audio.c
+KSRCS+= usb_template_phone.c
+KSRCS+= usb_template_serialnet.c
+KSRCS+= usb_template_midi.c
+
+#
+# USB mass storage support
+#
+SRCS+= umass_common.c
+
+.if defined(HAVE_UMASS_LOADER)
+CFLAGS+= -I${.CURDIR}/../common
+SRCS+= umass_loader.c
+.endif
+
diff --git a/usr/src/boot/sys/boot/userboot/Makefile b/usr/src/boot/sys/boot/userboot/Makefile
new file mode 100644
index 0000000000..ebacf64547
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+SUBDIR= ficl libstand test zfs userboot
+
+.include <bsd.subdir.mk>
+
diff --git a/usr/src/boot/sys/boot/userboot/ficl/Makefile b/usr/src/boot/sys/boot/userboot/ficl/Makefile
new file mode 100644
index 0000000000..d8f749f9c6
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/ficl/Makefile
@@ -0,0 +1,60 @@
+# $FreeBSD$
+#
+.include <bsd.own.mk>
+MK_SSP= no
+
+.PATH: ${.CURDIR}/../../ficl
+.PATH: ${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
+BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \
+ prefix.c search.c stack.c tools.c vm.c words.c
+
+SRCS= ${BASE_SRCS} sysdep.c softcore.c
+CLEANFILES= softcore.c testmain testmain.o
+.if HAVE_PNP
+CFLAGS+= -DHAVE_PNP
+.endif
+.include <bsd.stand.mk>
+.ifmake testmain
+CFLAGS+= -DTESTMAIN -D_TESTMAIN
+SRCS+= testmain.c
+PROG= testmain
+.include <bsd.prog.mk>
+.else
+LIB= ficl
+INTERNALLIB=
+.include <bsd.lib.mk>
+.endif
+
+# Standard softwords
+.PATH: ${.CURDIR}/../../ficl/softwords
+SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \
+ ifbrack.fr
+# Optional OO extension softwords
+#SOFTWORDS+= oo.fr classes.fr
+
+#.if ${MACHINE_CPUARCH} == "amd64"
+#CFLAGS+= -m32 -I.
+#.endif
+
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc -I.
+.endif
+
+CFLAGS+= -I${.CURDIR}/../../ficl
+CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
+CFLAGS+= -I${.CURDIR}/../../common
+
+softcore.c: ${SOFTWORDS} softcore.awk
+ (cd ${.CURDIR}/../../ficl/softwords; cat ${SOFTWORDS} \
+ | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET}
+
+#.if ${MACHINE_CPUARCH} == "amd64"
+#${SRCS:M*.c:R:S/$/.o/g}: machine
+#
+#beforedepend ${OBJS}: machine
+#
+#machine:
+# ln -sf ${.CURDIR}/../../i386/include machine
+#
+#CLEANFILES+= machine
+#.endif
diff --git a/usr/src/boot/sys/boot/userboot/libstand/Makefile b/usr/src/boot/sys/boot/userboot/libstand/Makefile
new file mode 100644
index 0000000000..401bbdacdb
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/libstand/Makefile
@@ -0,0 +1,136 @@
+# $FreeBSD$
+# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $
+#
+# Notes:
+# - We don't use the libc strerror/sys_errlist because the string table is
+# quite large.
+#
+
+MAN=
+
+.include <bsd.own.mk>
+MK_SSP= no
+
+LIBSTAND_SRC= ${.CURDIR}/../../../../lib/libstand
+LIBC_SRC= ${LIBSTAND_SRC}/../libc
+
+.PATH: ${LIBSTAND_SRC}
+LIB= stand
+INTERNALLIB=
+MK_PROFILE= no
+NO_PIC=
+
+WARNS?= 0
+
+# standalone components and stuff we have modified locally
+SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
+ globals.c pager.c printf.c strdup.c strerror.c strtol.c strtoul.c random.c \
+ sbrk.c twiddle.c zalloc.c zalloc_malloc.c
+
+# private (pruned) versions of libc string functions
+SRCS+= strcasecmp.c
+
+.PATH: ${LIBC_SRC}/net
+
+SRCS+= ntoh.c
+
+# string functions from libc
+.PATH: ${LIBC_SRC}/string
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "powerpc" || \
+ ${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "amd64" || \
+ ${MACHINE_CPUARCH} == "arm"
+SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
+ memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \
+ strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
+ strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
+.endif
+.if ${MACHINE_CPUARCH} == "arm"
+.PATH: ${LIBC_SRC}/arm/gen
+SRCS+= divsi3.S
+.endif
+.if ${MACHINE_CPUARCH} == "powerpc"
+.PATH: ${LIBC_SRC}/quad
+SRCS+= ashldi3.c ashrdi3.c
+.PATH: ${LIBC_SRC}/powerpc/gen
+SRCS+= syncicache.c
+.endif
+
+# uuid functions from libc
+.PATH: ${LIBC_SRC}/uuid
+SRCS+= uuid_equal.c uuid_is_nil.c
+
+# _setjmp/_longjmp
+.if ${MACHINE_CPUARCH} == "amd64"
+.PATH: ${LIBSTAND_SRC}/amd64
+.elif ${MACHINE_ARCH} == "powerpc64"
+.PATH: ${LIBSTAND_SRC}/powerpc
+.else
+.PATH: ${LIBSTAND_SRC}/${MACHINE_CPUARCH}
+.endif
+SRCS+= _setjmp.S
+
+# decompression functionality from libbz2
+# NOTE: to actually test this functionality after libbz2 upgrade compile
+# loader(8) with LOADER_BZIP2_SUPPORT defined
+.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2
+CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS
+SRCS+= libstand_bzlib_private.h
+
+.for file in bzlib.c crctable.c decompress.c huffman.c randtable.c
+SRCS+= _${file}
+CLEANFILES+= _${file}
+
+_${file}: ${file}
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \
+ ${.ALLSRC} > ${.TARGET}
+.endfor
+
+CLEANFILES+= libstand_bzlib_private.h
+libstand_bzlib_private.h: bzlib_private.h
+ sed -e 's|<stdlib.h>|"stand.h"|' \
+ ${.ALLSRC} > ${.TARGET}
+
+# decompression functionality from libz
+.PATH: ${LIBSTAND_SRC}/../libz
+CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../libz
+SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
+
+.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
+SRCS+= _${file}
+CLEANFILES+= _${file}
+
+_${file}: ${file}
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ ${.ALLSRC} > ${.TARGET}
+.endfor
+
+# depend on stand.h being able to be included multiple times
+.for file in zutil.h gzguts.h
+CLEANFILES+= libstand_${file}
+libstand_${file}: ${file}
+ sed -e 's|<fcntl.h>|"stand.h"|' \
+ -e 's|<stddef.h>|"stand.h"|' \
+ -e 's|<string.h>|"stand.h"|' \
+ -e 's|<stdio.h>|"stand.h"|' \
+ -e 's|<stdlib.h>|"stand.h"|' \
+ ${.ALLSRC} > ${.TARGET}
+.endfor
+
+# io routines
+SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
+ fstat.c close.c lseek.c open.c read.c write.c readdir.c
+
+# network routines
+SRCS+= arp.c ether.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c
+
+# network info services:
+SRCS+= bootp.c rarp.c bootparam.c
+
+# boot filesystems
+SRCS+= ufs.c nfs.c cd9660.c tftp.c gzipfs.c bzipfs.c
+SRCS+= dosfs.c ext2fs.c
+SRCS+= splitfs.c
+
+.include <bsd.stand.mk>
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/userboot/test/Makefile b/usr/src/boot/sys/boot/userboot/test/Makefile
new file mode 100644
index 0000000000..e9ecf58c77
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/test/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+
+MAN=
+
+.include <bsd.own.mk>
+MK_SSP= no
+
+PROG= test
+INTERNALPROG=
+
+CFLAGS+= -I${.CURDIR}/..
+CFLAGS+= -I${.CURDIR}/../../..
+
+.include <bsd.prog.mk>
diff --git a/usr/src/boot/sys/boot/userboot/test/test.c b/usr/src/boot/sys/boot/userboot/test/test.c
new file mode 100644
index 0000000000..d5707de216
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/test/test.c
@@ -0,0 +1,475 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/disk.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <boot/userboot/userboot.h>
+
+char *host_base = NULL;
+struct termios term, oldterm;
+char *image;
+size_t image_size;
+int disk_fd = -1;
+
+uint64_t regs[16];
+uint64_t pc;
+
+void test_exit(void *arg, int v);
+
+/*
+ * Console i/o
+ */
+
+void
+test_putc(void *arg, int ch)
+{
+ char c = ch;
+
+ write(1, &c, 1);
+}
+
+int
+test_getc(void *arg)
+{
+ char c;
+
+ if (read(0, &c, 1) == 1)
+ return c;
+ return -1;
+}
+
+int
+test_poll(void *arg)
+{
+ int n;
+
+ if (ioctl(0, FIONREAD, &n) >= 0)
+ return (n > 0);
+ return (0);
+}
+
+/*
+ * Host filesystem i/o
+ */
+
+struct test_file {
+ int tf_isdir;
+ size_t tf_size;
+ struct stat tf_stat;
+ union {
+ int fd;
+ DIR *dir;
+ } tf_u;
+};
+
+int
+test_open(void *arg, const char *filename, void **h_return)
+{
+ struct stat st;
+ struct test_file *tf;
+ char path[PATH_MAX];
+
+ if (!host_base)
+ return (ENOENT);
+
+ strlcpy(path, host_base, PATH_MAX);
+ if (path[strlen(path) - 1] == '/')
+ path[strlen(path) - 1] = 0;
+ strlcat(path, filename, PATH_MAX);
+ tf = malloc(sizeof(struct test_file));
+ if (stat(path, &tf->tf_stat) < 0) {
+ free(tf);
+ return (errno);
+ }
+
+ tf->tf_size = st.st_size;
+ if (S_ISDIR(tf->tf_stat.st_mode)) {
+ tf->tf_isdir = 1;
+ tf->tf_u.dir = opendir(path);
+ if (!tf->tf_u.dir)
+ goto out;
+ *h_return = tf;
+ return (0);
+ }
+ if (S_ISREG(tf->tf_stat.st_mode)) {
+ tf->tf_isdir = 0;
+ tf->tf_u.fd = open(path, O_RDONLY);
+ if (tf->tf_u.fd < 0)
+ goto out;
+ *h_return = tf;
+ return (0);
+ }
+
+out:
+ free(tf);
+ return (EINVAL);
+}
+
+int
+test_close(void *arg, void *h)
+{
+ struct test_file *tf = h;
+
+ if (tf->tf_isdir)
+ closedir(tf->tf_u.dir);
+ else
+ close(tf->tf_u.fd);
+ free(tf);
+
+ return (0);
+}
+
+int
+test_isdir(void *arg, void *h)
+{
+ struct test_file *tf = h;
+
+ return (tf->tf_isdir);
+}
+
+int
+test_read(void *arg, void *h, void *dst, size_t size, size_t *resid_return)
+{
+ struct test_file *tf = h;
+ ssize_t sz;
+
+ if (tf->tf_isdir)
+ return (EINVAL);
+ sz = read(tf->tf_u.fd, dst, size);
+ if (sz < 0)
+ return (EINVAL);
+ *resid_return = size - sz;
+ return (0);
+}
+
+int
+test_readdir(void *arg, void *h, uint32_t *fileno_return, uint8_t *type_return,
+ size_t *namelen_return, char *name)
+{
+ struct test_file *tf = h;
+ struct dirent *dp;
+
+ if (!tf->tf_isdir)
+ return (EINVAL);
+
+ dp = readdir(tf->tf_u.dir);
+ if (!dp)
+ return (ENOENT);
+
+ /*
+ * Note: d_namlen is in the range 0..255 and therefore less
+ * than PATH_MAX so we don't need to test before copying.
+ */
+ *fileno_return = dp->d_fileno;
+ *type_return = dp->d_type;
+ *namelen_return = dp->d_namlen;
+ memcpy(name, dp->d_name, dp->d_namlen);
+ name[dp->d_namlen] = 0;
+
+ return (0);
+}
+
+int
+test_seek(void *arg, void *h, uint64_t offset, int whence)
+{
+ struct test_file *tf = h;
+
+ if (tf->tf_isdir)
+ return (EINVAL);
+ if (lseek(tf->tf_u.fd, offset, whence) < 0)
+ return (errno);
+ return (0);
+}
+
+int
+test_stat(void *arg, void *h, int *mode_return, int *uid_return, int *gid_return,
+ uint64_t *size_return)
+{
+ struct test_file *tf = h;
+
+ *mode_return = tf->tf_stat.st_mode;
+ *uid_return = tf->tf_stat.st_uid;
+ *gid_return = tf->tf_stat.st_gid;
+ *size_return = tf->tf_stat.st_size;
+ return (0);
+}
+
+/*
+ * Disk image i/o
+ */
+
+int
+test_diskread(void *arg, int unit, uint64_t offset, void *dst, size_t size,
+ size_t *resid_return)
+{
+ ssize_t n;
+
+ if (unit != 0 || disk_fd == -1)
+ return (EIO);
+ n = pread(disk_fd, dst, size, offset);
+ if (n < 0)
+ return (errno);
+ *resid_return = size - n;
+ return (0);
+}
+
+int
+test_diskioctl(void *arg, int unit, u_long cmd, void *data)
+{
+ struct stat sb;
+
+ if (unit != 0 || disk_fd == -1)
+ return (EBADF);
+ switch (cmd) {
+ case DIOCGSECTORSIZE:
+ *(u_int *)data = 512;
+ break;
+ case DIOCGMEDIASIZE:
+ if (fstat(disk_fd, &sb) == 0)
+ *(off_t *)data = sb.st_size;
+ else
+ return (ENOTTY);
+ break;
+ default:
+ return (ENOTTY);
+ };
+ return (0);
+}
+
+/*
+ * Guest virtual machine i/o
+ *
+ * Note: guest addresses are kernel virtual
+ */
+
+int
+test_copyin(void *arg, const void *from, uint64_t to, size_t size)
+{
+
+ to &= 0x7fffffff;
+ if (to > image_size)
+ return (EFAULT);
+ if (to + size > image_size)
+ size = image_size - to;
+ memcpy(&image[to], from, size);
+ return(0);
+}
+
+int
+test_copyout(void *arg, uint64_t from, void *to, size_t size)
+{
+
+ from &= 0x7fffffff;
+ if (from > image_size)
+ return (EFAULT);
+ if (from + size > image_size)
+ size = image_size - from;
+ memcpy(to, &image[from], size);
+ return(0);
+}
+
+void
+test_setreg(void *arg, int r, uint64_t v)
+{
+
+ if (r < 0 || r >= 16)
+ return;
+ regs[r] = v;
+}
+
+void
+test_setmsr(void *arg, int r, uint64_t v)
+{
+}
+
+void
+test_setcr(void *arg, int r, uint64_t v)
+{
+}
+
+void
+test_setgdt(void *arg, uint64_t v, size_t sz)
+{
+}
+
+void
+test_exec(void *arg, uint64_t pc)
+{
+ printf("Execute at 0x%"PRIu64"\n", pc);
+ test_exit(arg, 0);
+}
+
+/*
+ * Misc
+ */
+
+void
+test_delay(void *arg, int usec)
+{
+
+ usleep(usec);
+}
+
+void
+test_exit(void *arg, int v)
+{
+
+ tcsetattr(0, TCSAFLUSH, &oldterm);
+ exit(v);
+}
+
+void
+test_getmem(void *arg, uint64_t *lowmem, uint64_t *highmem)
+{
+
+ *lowmem = 128*1024*1024;
+ *highmem = 0;
+}
+
+const char *
+test_getenv(void *arg, int idx)
+{
+ static const char *vars[] = {
+ "foo=bar",
+ "bar=barbar",
+ NULL
+ };
+
+ return (vars[idx]);
+}
+
+struct loader_callbacks cb = {
+ .putc = test_putc,
+ .getc = test_getc,
+ .poll = test_poll,
+
+ .open = test_open,
+ .close = test_close,
+ .isdir = test_isdir,
+ .read = test_read,
+ .readdir = test_readdir,
+ .seek = test_seek,
+ .stat = test_stat,
+
+ .diskread = test_diskread,
+ .diskioctl = test_diskioctl,
+
+ .copyin = test_copyin,
+ .copyout = test_copyout,
+ .setreg = test_setreg,
+ .setmsr = test_setmsr,
+ .setcr = test_setcr,
+ .setgdt = test_setgdt,
+ .exec = test_exec,
+
+ .delay = test_delay,
+ .exit = test_exit,
+ .getmem = test_getmem,
+
+ .getenv = test_getenv,
+};
+
+void
+usage()
+{
+
+ printf("usage: [-b <userboot shared object>] [-d <disk image path>] [-h <host filesystem path>\n");
+ exit(1);
+}
+
+int
+main(int argc, char** argv)
+{
+ void *h;
+ void (*func)(struct loader_callbacks *, void *, int, int);
+ int opt;
+ char *disk_image = NULL;
+ const char *userboot_obj = "/boot/userboot.so";
+
+ while ((opt = getopt(argc, argv, "b:d:h:")) != -1) {
+ switch (opt) {
+ case 'b':
+ userboot_obj = optarg;
+ break;
+
+ case 'd':
+ disk_image = optarg;
+ break;
+
+ case 'h':
+ host_base = optarg;
+ break;
+
+ case '?':
+ usage();
+ }
+ }
+
+ h = dlopen(userboot_obj, RTLD_LOCAL);
+ if (!h) {
+ printf("%s\n", dlerror());
+ return (1);
+ }
+ func = dlsym(h, "loader_main");
+ if (!func) {
+ printf("%s\n", dlerror());
+ return (1);
+ }
+
+ image_size = 128*1024*1024;
+ image = malloc(image_size);
+ if (disk_image) {
+ disk_fd = open(disk_image, O_RDONLY);
+ if (disk_fd < 0)
+ err(1, "Can't open disk image '%s'", disk_image);
+ }
+
+ tcgetattr(0, &term);
+ oldterm = term;
+ term.c_iflag &= ~(ICRNL);
+ term.c_lflag &= ~(ICANON|ECHO);
+ tcsetattr(0, TCSAFLUSH, &term);
+
+ func(&cb, NULL, USERBOOT_VERSION_3, disk_fd >= 0);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot.h b/usr/src/boot/sys/boot/userboot/userboot.h
new file mode 100644
index 0000000000..7ffb06f652
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot.h
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 2011 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * USERBOOT interface versions
+ */
+#define USERBOOT_VERSION_1 1
+#define USERBOOT_VERSION_2 2
+#define USERBOOT_VERSION_3 3
+
+/*
+ * Version 4 added more generic callbacks for setting up
+ * registers and descriptors. The callback structure is
+ * backward compatible (new callbacks have been added at
+ * the tail end).
+ */
+#define USERBOOT_VERSION_4 4
+
+/*
+ * Exit codes from the loader
+ */
+#define USERBOOT_EXIT_QUIT 1
+#define USERBOOT_EXIT_REBOOT 2
+
+struct loader_callbacks {
+ /*
+ * Console i/o
+ */
+
+ /*
+ * Wait until a key is pressed on the console and then return it
+ */
+ int (*getc)(void *arg);
+
+ /*
+ * Write the character ch to the console
+ */
+ void (*putc)(void *arg, int ch);
+
+ /*
+ * Return non-zero if a key can be read from the console
+ */
+ int (*poll)(void *arg);
+
+ /*
+ * Host filesystem i/o
+ */
+
+ /*
+ * Open a file in the host filesystem
+ */
+ int (*open)(void *arg, const char *filename, void **h_return);
+
+ /*
+ * Close a file
+ */
+ int (*close)(void *arg, void *h);
+
+ /*
+ * Return non-zero if the file is a directory
+ */
+ int (*isdir)(void *arg, void *h);
+
+ /*
+ * Read size bytes from a file. The number of bytes remaining
+ * in dst after reading is returned in *resid_return
+ */
+ int (*read)(void *arg, void *h, void *dst, size_t size,
+ size_t *resid_return);
+
+ /*
+ * Read an entry from a directory. The entry's inode number is
+ * returned in *fileno_return, its type in *type_return and
+ * the name length in *namelen_return. The name itself is
+ * copied to the buffer name which must be at least PATH_MAX
+ * in size.
+ */
+ int (*readdir)(void *arg, void *h, uint32_t *fileno_return,
+ uint8_t *type_return, size_t *namelen_return, char *name);
+
+ /*
+ * Seek to a location within an open file
+ */
+ int (*seek)(void *arg, void *h, uint64_t offset,
+ int whence);
+
+ /*
+ * Return some stat(2) related information about the file
+ */
+ int (*stat)(void *arg, void *h, int *mode_return,
+ int *uid_return, int *gid_return, uint64_t *size_return);
+
+ /*
+ * Disk image i/o
+ */
+
+ /*
+ * Read from a disk image at the given offset
+ */
+ int (*diskread)(void *arg, int unit, uint64_t offset,
+ void *dst, size_t size, size_t *resid_return);
+
+ /*
+ * Guest virtual machine i/o
+ */
+
+ /*
+ * Copy to the guest address space
+ */
+ int (*copyin)(void *arg, const void *from,
+ uint64_t to, size_t size);
+
+ /*
+ * Copy from the guest address space
+ */
+ int (*copyout)(void *arg, uint64_t from,
+ void *to, size_t size);
+
+ /*
+ * Set a guest register value
+ */
+ void (*setreg)(void *arg, int, uint64_t);
+
+ /*
+ * Set a guest MSR value
+ */
+ void (*setmsr)(void *arg, int, uint64_t);
+
+ /*
+ * Set a guest CR value
+ */
+ void (*setcr)(void *arg, int, uint64_t);
+
+ /*
+ * Set the guest GDT address
+ */
+ void (*setgdt)(void *arg, uint64_t, size_t);
+
+ /*
+ * Transfer control to the guest at the given address
+ */
+ void (*exec)(void *arg, uint64_t pc);
+
+ /*
+ * Misc
+ */
+
+ /*
+ * Sleep for usec microseconds
+ */
+ void (*delay)(void *arg, int usec);
+
+ /*
+ * Exit with the given exit code
+ */
+ void (*exit)(void *arg, int v);
+
+ /*
+ * Return guest physical memory map details
+ */
+ void (*getmem)(void *arg, uint64_t *lowmem,
+ uint64_t *highmem);
+
+ /*
+ * ioctl interface to the disk device
+ */
+ int (*diskioctl)(void *arg, int unit, u_long cmd,
+ void *data);
+
+ /*
+ * Returns an environment variable in the form "name=value".
+ *
+ * If there are no more variables that need to be set in the
+ * loader environment then return NULL.
+ *
+ * 'num' is used as a handle for the callback to identify which
+ * environment variable to return next. It will begin at 0 and
+ * each invocation will add 1 to the previous value of 'num'.
+ */
+ const char * (*getenv)(void *arg, int num);
+
+ /*
+ * Version 4 additions.
+ */
+ int (*vm_set_register)(void *arg, int vcpu, int reg, uint64_t val);
+ int (*vm_set_desc)(void *arg, int vcpu, int reg, uint64_t base,
+ u_int limit, u_int access);
+};
diff --git a/usr/src/boot/sys/boot/userboot/userboot/Makefile b/usr/src/boot/sys/boot/userboot/userboot/Makefile
new file mode 100644
index 0000000000..5623e72c2e
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/Makefile
@@ -0,0 +1,67 @@
+# $FreeBSD$
+
+MAN=
+
+.include <src.opts.mk>
+MK_SSP= no
+
+SHLIB_NAME= userboot.so
+NO_CTF= yes
+STRIP=
+LIBDIR= /boot
+
+SRCS= autoload.c
+SRCS+= biossmap.c
+SRCS+= bootinfo.c
+SRCS+= bootinfo32.c
+SRCS+= bootinfo64.c
+SRCS+= conf.c
+SRCS+= console.c
+SRCS+= copy.c
+SRCS+= devicename.c
+SRCS+= elf32_freebsd.c
+SRCS+= elf64_freebsd.c
+SRCS+= host.c
+SRCS+= main.c
+SRCS+= userboot_cons.c
+SRCS+= userboot_disk.c
+SRCS+= vers.c
+
+CFLAGS+= -Wall
+CFLAGS+= -I${.CURDIR}/..
+CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../../..
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -ffreestanding -I.
+
+LDFLAGS+= -nostdlib -Wl,-Bsymbolic
+
+NEWVERSWHAT= "User boot" ${MACHINE_CPUARCH}
+
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+
+CLEANFILES= vers.c
+
+.if ${MK_FORTH} != "no"
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386
+CFLAGS+= -DBF_DICTSIZE=15000
+LIBFICL= ${.OBJDIR}/../ficl/libficl.a
+LIBSTAND= ${.OBJDIR}/../libstand/libstand.a
+.endif
+
+.if ${MK_ZFS} != "no"
+CFLAGS+= -DUSERBOOT_ZFS_SUPPORT
+LIBZFSBOOT= ${.OBJDIR}/../zfs/libzfsboot.a
+.endif
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I.
+DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND}
+LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND}
+
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/userboot/userboot/autoload.c b/usr/src/boot/sys/boot/userboot/userboot/autoload.c
new file mode 100644
index 0000000000..a86afcfa2b
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/autoload.c
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+int
+userboot_autoload(void)
+{
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/biossmap.c b/usr/src/boot/sys/boot/userboot/userboot/biossmap.c
new file mode 100644
index 0000000000..9e556be373
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/biossmap.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <machine/pc/bios.h>
+#include <machine/metadata.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+#define GB (1024UL * 1024 * 1024)
+
+void
+bios_addsmapdata(struct preloaded_file *kfp)
+{
+ uint64_t lowmem, highmem;
+ int smapnum, len;
+ struct bios_smap smap[3], *sm;
+
+ CALLBACK(getmem, &lowmem, &highmem);
+
+ sm = &smap[0];
+
+ sm->base = 0; /* base memory */
+ sm->length = 640 * 1024;
+ sm->type = SMAP_TYPE_MEMORY;
+ sm++;
+
+ sm->base = 0x100000; /* extended memory */
+ sm->length = lowmem - 0x100000;
+ sm->type = SMAP_TYPE_MEMORY;
+ sm++;
+
+ smapnum = 2;
+
+ if (highmem != 0) {
+ sm->base = 4 * GB;
+ sm->length = highmem;
+ sm->type = SMAP_TYPE_MEMORY;
+ smapnum++;
+ }
+
+ len = smapnum * sizeof(struct bios_smap);
+ file_addmetadata(kfp, MODINFOMD_SMAP, len, &smap[0]);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/bootinfo.c b/usr/src/boot/sys/boot/userboot/userboot/bootinfo.c
new file mode 100644
index 0000000000..289ca071fe
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/bootinfo.c
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+int
+bi_getboothowto(char *kargs)
+{
+ char *cp;
+ char *curpos, *next, *string;
+ int howto;
+ int active;
+ int i;
+ int vidconsole;
+
+ /* Parse kargs */
+ howto = 0;
+ if (kargs != NULL) {
+ cp = kargs;
+ active = 0;
+ while (*cp != 0) {
+ if (!active && (*cp == '-')) {
+ active = 1;
+ } else if (active)
+ switch (*cp) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'C':
+ howto |= RB_CDROM;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'g':
+ howto |= RB_GDB;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ default:
+ active = 0;
+ break;
+ }
+ cp++;
+ }
+ }
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+
+ /* Enable selected consoles */
+ string = next = strdup(getenv("console"));
+ vidconsole = 0;
+ while (next != NULL) {
+ curpos = strsep(&next, " ,");
+ if (*curpos == '\0')
+ continue;
+ if (!strcmp(curpos, "vidconsole"))
+ vidconsole = 1;
+ else if (!strcmp(curpos, "comconsole"))
+ howto |= RB_SERIAL;
+ else if (!strcmp(curpos, "nullconsole"))
+ howto |= RB_MUTE;
+ }
+
+ if (vidconsole && (howto & RB_SERIAL))
+ howto |= RB_MULTIPLE;
+
+ /*
+ * XXX: Note that until the kernel is ready to respect multiple consoles
+ * for the boot messages, the first named console is the primary console
+ */
+ if (!strcmp(string, "vidconsole"))
+ howto &= ~RB_SERIAL;
+
+ free(string);
+
+ return(howto);
+}
+
+void
+bi_setboothowto(int howto)
+{
+ int i;
+
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (howto & howto_names[i].mask)
+ setenv(howto_names[i].ev, "YES", 1);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+bi_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ CALLBACK(copyin, ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ CALLBACK(copyin, "=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ CALLBACK(copyin, ep->ev_value, addr, strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ CALLBACK(copyin, "", addr, 1);
+ addr++;
+ }
+ CALLBACK(copyin, "", addr, 1);
+ addr++;
+ return(addr);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/bootinfo32.c b/usr/src/boot/sys/boot/userboot/userboot/bootinfo32.c
new file mode 100644
index 0000000000..6498461a74
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/bootinfo32.c
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <i386/include/bootinfo.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+static struct bootinfo bi;
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ CALLBACK(copyin, &x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ CALLBACK(copyin, s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(uint32_t));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ CALLBACK(copyin, &s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(uint32_t)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ CALLBACK(copyin, mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(uint32_t));\
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules32(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ MOD_ADDR(addr, fp->f_addr, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Load the information expected by an i386 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ struct i386_devdesc *rootdev;
+ struct file_metadata *md;
+ vm_offset_t addr;
+ vm_offset_t kernend;
+ vm_offset_t envp;
+ vm_offset_t size;
+ vm_offset_t ssym, esym;
+ char *rootdevname;
+ int bootdevnr, howto;
+ char *kernelname;
+ const char *kernelpath;
+ uint64_t lowmem, highmem;
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ userboot_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(userboot_fmtdev((void *)rootdev));
+
+ bootdevnr = 0;
+#if 0
+ if (bootdevnr == -1) {
+ printf("root device %s invalid\n", i386_fmtdev(rootdev));
+ return (EINVAL);
+ }
+#endif
+ free(rootdev);
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* copy our environment */
+ envp = addr;
+ addr = bi_copyenv(addr);
+
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf32 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ bios_addsmapdata(kfp);
+
+ /* Figure out the size and location of the metadata */
+ *modulep = addr;
+ size = bi_copymodules32(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* copy module list and metadata */
+ (void)bi_copymodules32(addr);
+
+ ssym = esym = 0;
+ md = file_findmetadata(kfp, MODINFOMD_SSYM);
+ if (md != NULL)
+ ssym = *((vm_offset_t *)&(md->md_data));
+ md = file_findmetadata(kfp, MODINFOMD_ESYM);
+ if (md != NULL)
+ esym = *((vm_offset_t *)&(md->md_data));
+ if (ssym == 0 || esym == 0)
+ ssym = esym = 0; /* sanity */
+
+ /* legacy bootinfo structure */
+ kernelname = getenv("kernelname");
+ userboot_getdev(NULL, kernelname, &kernelpath);
+ bi.bi_version = BOOTINFO_VERSION;
+ bi.bi_kernelname = 0; /* XXX char * -> kernel name */
+ bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */
+ bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */
+#if 0
+ for (i = 0; i < N_BIOS_GEOM; i++)
+ bi.bi_bios_geom[i] = bd_getbigeom(i);
+#endif
+ bi.bi_size = sizeof(bi);
+ CALLBACK(getmem, &lowmem, &highmem);
+ bi.bi_memsizes_valid = 1;
+ bi.bi_basemem = 640;
+ bi.bi_extmem = (lowmem - 0x100000) / 1024;
+ bi.bi_envp = envp;
+ bi.bi_modulep = *modulep;
+ bi.bi_kernend = kernend;
+ bi.bi_symtab = ssym; /* XXX this is only the primary kernel symtab */
+ bi.bi_esymtab = esym;
+
+ /*
+ * Copy the legacy bootinfo and kernel name to the guest at 0x2000
+ */
+ bi.bi_kernelname = 0x2000 + sizeof(bi);
+ CALLBACK(copyin, &bi, 0x2000, sizeof(bi));
+ CALLBACK(copyin, kernelname, 0x2000 + sizeof(bi), strlen(kernelname) + 1);
+
+ /* legacy boot arguments */
+ *howtop = howto | RB_BOOTINFO;
+ *bootdevp = bootdevnr;
+ *bip = 0x2000;
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/bootinfo64.c b/usr/src/boot/sys/boot/userboot/userboot/bootinfo64.c
new file mode 100644
index 0000000000..10ff133ce5
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/bootinfo64.c
@@ -0,0 +1,257 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <i386/include/bootinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/psl.h>
+#include <machine/specialreg.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ CALLBACK(copyin, &x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ CALLBACK(copyin, s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ CALLBACK(copyin, &s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ CALLBACK(copyin, mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t));\
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules64(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+ u_int64_t v;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ v = fp->f_addr;
+ MOD_ADDR(addr, v, c);
+ v = fp->f_size;
+ MOD_SIZE(addr, v, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Check to see if this CPU supports long mode.
+ */
+static int
+bi_checkcpu(void)
+{
+#if 0
+ char *cpu_vendor;
+ int vendor[3];
+ int eflags, regs[4];
+
+ /* Check for presence of "cpuid". */
+ eflags = read_eflags();
+ write_eflags(eflags ^ PSL_ID);
+ if (!((eflags ^ read_eflags()) & PSL_ID))
+ return (0);
+
+ /* Fetch the vendor string. */
+ do_cpuid(0, regs);
+ vendor[0] = regs[1];
+ vendor[1] = regs[3];
+ vendor[2] = regs[2];
+ cpu_vendor = (char *)vendor;
+
+ /* Check for vendors that support AMD features. */
+ if (strncmp(cpu_vendor, INTEL_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, AMD_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, CENTAUR_VENDOR_ID, 12) != 0)
+ return (0);
+
+ /* Has to support AMD features. */
+ do_cpuid(0x80000000, regs);
+ if (!(regs[0] >= 0x80000001))
+ return (0);
+
+ /* Check for long mode. */
+ do_cpuid(0x80000001, regs);
+ return (regs[3] & AMDID_LM);
+#else
+ return (1);
+#endif
+}
+
+/*
+ * Load the information expected by an amd64 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ struct userboot_devdesc *rootdev;
+ struct file_metadata *md;
+ vm_offset_t addr;
+ u_int64_t kernend;
+ u_int64_t envp;
+ vm_offset_t size;
+ char *rootdevname;
+ int howto;
+
+ if (!bi_checkcpu()) {
+ printf("CPU doesn't support long mode\n");
+ return (EINVAL);
+ }
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ userboot_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(userboot_fmtdev((void *)rootdev));
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* copy our environment */
+ envp = addr;
+ addr = bi_copyenv(addr);
+
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ bios_addsmapdata(kfp);
+
+ /* Figure out the size and location of the metadata */
+ *modulep = addr;
+ size = bi_copymodules64(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* copy module list and metadata */
+ (void)bi_copymodules64(addr);
+
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/conf.c b/usr/src/boot/sys/boot/userboot/userboot/conf.c
new file mode 100644
index 0000000000..b8daa7396c
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/conf.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 1997
+ * Matthias Drochner. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include "libuserboot.h"
+
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
+
+/*
+ * We could use linker sets for some or all of these, but
+ * then we would have to control what ended up linked into
+ * the bootstrap. So it's easier to conditionalise things
+ * here.
+ *
+ * XXX rename these arrays to be consistent and less namespace-hostile
+ */
+
+/* Exported for libstand */
+struct devsw *devsw[] = {
+ &host_dev,
+ &userboot_disk,
+#if defined(USERBOOT_ZFS_SUPPORT)
+ &zfs_dev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+ &host_fsops,
+ &ufs_fsops,
+ &cd9660_fsops,
+#if defined(USERBOOT_ZFS_SUPPORT)
+ &zfs_fsops,
+#endif
+ &gzipfs_fsops,
+ &bzipfs_fsops,
+ NULL
+};
+
+/* Exported for i386 only */
+/*
+ * Sort formats so that those that can detect based on arguments
+ * rather than reading the file go first.
+ */
+extern struct file_format i386_elf;
+extern struct file_format i386_elf_obj;
+extern struct file_format amd64_elf;
+extern struct file_format amd64_elf_obj;
+
+struct file_format *file_formats[] = {
+ &i386_elf,
+ &i386_elf_obj,
+ &amd64_elf,
+ &amd64_elf_obj,
+ NULL
+};
+
+/*
+ * Consoles
+ *
+ * We don't prototype these in libuserboot.h because they require
+ * data structures from bootstrap.h as well.
+ */
+extern struct console userboot_console;
+extern struct console userboot_comconsole;
+
+struct console *consoles[] = {
+ &userboot_console,
+ &userboot_comconsole,
+ NULL
+};
diff --git a/usr/src/boot/sys/boot/userboot/userboot/copy.c b/usr/src/boot/sys/boot/userboot/userboot/copy.c
new file mode 100644
index 0000000000..f8763e9b52
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/copy.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include "libuserboot.h"
+
+ssize_t
+userboot_copyin(const void *src, vm_offset_t va, size_t len)
+{
+
+ CALLBACK(copyin, src, va, len);
+ return (len);
+}
+
+ssize_t
+userboot_copyout(vm_offset_t va, void *dst, size_t len)
+{
+
+ CALLBACK(copyout, va, dst, len);
+ return (len);
+}
+
+ssize_t
+userboot_readin(int fd, vm_offset_t va, size_t len)
+{
+ ssize_t res, s;
+ size_t sz;
+ char buf[4096];
+
+ res = 0;
+ while (len > 0) {
+ sz = len;
+ if (sz > sizeof(buf))
+ sz = sizeof(buf);
+ s = read(fd, buf, sz);
+ if (s == 0)
+ break;
+ if (s < 0)
+ return (s);
+ CALLBACK(copyin, buf, va, s);
+ len -= s;
+ res += s;
+ va += s;
+ }
+ return (res);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/devicename.c b/usr/src/boot/sys/boot/userboot/userboot/devicename.c
new file mode 100644
index 0000000000..efa5634e54
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/devicename.c
@@ -0,0 +1,224 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+#include "disk.h"
+#include "libuserboot.h"
+
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
+
+static int userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **path);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+userboot_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct disk_devdesc **dev = (struct disk_devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) ||
+ (devspec[0] == '/') ||
+ (strchr(devspec, ':') == NULL)) {
+
+ if (((rv = userboot_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
+ (path != NULL))
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec
+ */
+ return(userboot_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * disk<unit>[s<slice>][<partition>]:
+ *
+ */
+static int
+userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **path)
+{
+ struct disk_devdesc *idev;
+ struct devsw *dv;
+ int i, unit, err;
+ const char *cp;
+ const char *np;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return(EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
+ if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
+ dv = devsw[i];
+ break;
+ }
+ }
+ if (dv == NULL)
+ return(ENOENT);
+ idev = malloc(sizeof(struct disk_devdesc));
+ err = 0;
+ np = (devspec + strlen(dv->dv_name));
+
+ switch(dv->dv_type) {
+ case DEVT_NONE: /* XXX what to do here? Do we care? */
+ break;
+
+ case DEVT_DISK:
+ err = disk_parsedev(idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+
+ case DEVT_CD:
+ case DEVT_NET:
+ unit = 0;
+
+ if (*np && (*np != ':')) {
+ unit = strtol(np, (char **)&cp, 0); /* get unit number if present */
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ } else {
+ cp = np;
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_unit = unit;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+
+ case DEVT_ZFS:
+#if defined(USERBOOT_ZFS_SUPPORT)
+ err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+#else
+ /* FALLTHROUGH */
+#endif
+
+ default:
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (dev == NULL) {
+ free(idev);
+ } else {
+ *dev = idev;
+ }
+ return(0);
+
+ fail:
+ free(idev);
+ return(err);
+}
+
+
+char *
+userboot_fmtdev(void *vdev)
+{
+ struct disk_devdesc *dev = (struct disk_devdesc *)vdev;
+ static char buf[128]; /* XXX device length constant? */
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ case DEVT_CD:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+
+ case DEVT_DISK:
+ return (disk_fmtdev(vdev));
+
+ case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+
+ case DEVT_ZFS:
+#if defined(USERBOOT_ZFS_SUPPORT)
+ return (zfs_fmtdev(vdev));
+#else
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+#endif
+ break;
+ }
+ return(buf);
+}
+
+
+/*
+ * Set currdev to suit the value being supplied in (value)
+ */
+int
+userboot_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct disk_devdesc *ncurr;
+ int rv;
+
+ if ((rv = userboot_parsedev(&ncurr, value, NULL)) != 0)
+ return(rv);
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return(0);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/elf32_freebsd.c b/usr/src/boot/sys/boot/userboot/userboot/elf32_freebsd.c
new file mode 100644
index 0000000000..d8ccc3375c
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/elf32_freebsd.c
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#define _MACHINE_ELF_WANT_32BIT
+#include <i386/include/bootinfo.h>
+#include <i386/include/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+static int elf32_exec(struct preloaded_file *amp);
+static int elf32_obj_exec(struct preloaded_file *amp);
+
+struct file_format i386_elf = { elf32_loadfile, elf32_exec };
+struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
+
+#define GUEST_STACK 0x1000 /* Initial stack base */
+#define GUEST_GDT 0x3000 /* Address of initial GDT */
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf32_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t entry, bootinfop, modulep, kernend;
+ int boothowto, err, bootdev;
+ uint32_t stack[1024], *sp;
+
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load32(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+ entry = ehdr->e_entry & 0xffffff;
+
+#ifdef DEBUG
+ printf("Start @ 0x%lx ...\n", entry);
+#endif
+
+ dev_cleanup();
+
+ /*
+ * Build a scratch stack at physical 0x1000
+ */
+ memset(stack, 0, sizeof(stack));
+ sp = (uint32_t *)((char *)stack + sizeof(stack));
+ *--sp = kernend;
+ *--sp = modulep;
+ *--sp = bootinfop;
+ *--sp = 0;
+ *--sp = 0;
+ *--sp = 0;
+ *--sp = bootdev;
+ *--sp = boothowto;
+
+ /*
+ * Fake return address to mimic "new" boot blocks. For more
+ * details see recover_bootinfo in locore.S.
+ */
+ *--sp = 0xbeefface;
+ CALLBACK(copyin, stack, GUEST_STACK, sizeof(stack));
+ CALLBACK(setreg, 4, (char *)sp - (char *)stack + GUEST_STACK);
+
+ CALLBACK(setgdt, GUEST_GDT, 8 * 4 - 1);
+
+ CALLBACK(exec, entry);
+
+ panic("exec returned");
+}
+
+static int
+elf32_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/elf64_freebsd.c b/usr/src/boot/sys/boot/userboot/userboot/elf64_freebsd.c
new file mode 100644
index 0000000000..36129ef6b7
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/elf64_freebsd.c
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <i386/include/bootinfo.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+static int elf64_exec(struct preloaded_file *amp);
+static int elf64_obj_exec(struct preloaded_file *amp);
+
+struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
+struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+
+#define MSR_EFER 0xc0000080
+#define EFER_LME 0x00000100
+#define EFER_LMA 0x00000400 /* Long mode active (R) */
+#define CR4_PAE 0x00000020
+#define CR4_VMXE (1UL << 13)
+#define CR4_PSE 0x00000010
+#define CR0_PG 0x80000000
+#define CR0_PE 0x00000001 /* Protected mode Enable */
+#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
+
+#define PG_V 0x001
+#define PG_RW 0x002
+#define PG_U 0x004
+#define PG_PS 0x080
+
+typedef u_int64_t p4_entry_t;
+typedef u_int64_t p3_entry_t;
+typedef u_int64_t p2_entry_t;
+
+#define GUEST_NULL_SEL 0
+#define GUEST_CODE_SEL 1
+#define GUEST_DATA_SEL 2
+#define GUEST_GDTR_LIMIT (3 * 8 - 1)
+
+static void
+setup_freebsd_gdt(uint64_t *gdtr)
+{
+ gdtr[GUEST_NULL_SEL] = 0;
+ gdtr[GUEST_CODE_SEL] = 0x0020980000000000;
+ gdtr[GUEST_DATA_SEL] = 0x0000900000000000;
+}
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf64_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t modulep, kernend;
+ int err;
+ int i;
+ uint32_t stack[1024];
+ p4_entry_t PT4[512];
+ p3_entry_t PT3[512];
+ p2_entry_t PT2[512];
+ uint64_t gdtr[3];
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load64(fp->f_args, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+
+ bzero(PT4, PAGE_SIZE);
+ bzero(PT3, PAGE_SIZE);
+ bzero(PT2, PAGE_SIZE);
+
+ /*
+ * Build a scratch stack at physical 0x1000, page tables:
+ * PT4 at 0x2000,
+ * PT3 at 0x3000,
+ * PT2 at 0x4000,
+ * gdtr at 0x5000,
+ */
+
+ /*
+ * This is kinda brutal, but every single 1GB VM memory segment
+ * points to the same first 1GB of physical memory. But it is
+ * more than adequate.
+ */
+ for (i = 0; i < 512; i++) {
+ /* Each slot of the level 4 pages points to the same level 3 page */
+ PT4[i] = (p4_entry_t) 0x3000;
+ PT4[i] |= PG_V | PG_RW | PG_U;
+
+ /* Each slot of the level 3 pages points to the same level 2 page */
+ PT3[i] = (p3_entry_t) 0x4000;
+ PT3[i] |= PG_V | PG_RW | PG_U;
+
+ /* The level 2 page slots are mapped with 2MB pages for 1GB. */
+ PT2[i] = i * (2 * 1024 * 1024);
+ PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+ }
+
+#ifdef DEBUG
+ printf("Start @ %#llx ...\n", ehdr->e_entry);
+#endif
+
+ dev_cleanup();
+
+ stack[0] = 0; /* return address */;
+ stack[1] = modulep;
+ stack[2] = kernend;
+ CALLBACK(copyin, stack, 0x1000, sizeof(stack));
+ CALLBACK(copyin, PT4, 0x2000, sizeof(PT4));
+ CALLBACK(copyin, PT3, 0x3000, sizeof(PT3));
+ CALLBACK(copyin, PT2, 0x4000, sizeof(PT2));
+ CALLBACK(setreg, 4, 0x1000);
+
+ CALLBACK(setmsr, MSR_EFER, EFER_LMA | EFER_LME);
+ CALLBACK(setcr, 4, CR4_PAE | CR4_VMXE);
+ CALLBACK(setcr, 3, 0x2000);
+ CALLBACK(setcr, 0, CR0_PG | CR0_PE | CR0_NE);
+
+ setup_freebsd_gdt(gdtr);
+ CALLBACK(copyin, gdtr, 0x5000, sizeof(gdtr));
+ CALLBACK(setgdt, 0x5000, sizeof(gdtr));
+
+ CALLBACK(exec, ehdr->e_entry);
+
+ panic("exec returned");
+}
+
+static int
+elf64_obj_exec(struct preloaded_file *fp)
+{
+
+ return (EFTYPE);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/host.c b/usr/src/boot/sys/boot/userboot/userboot/host.c
new file mode 100644
index 0000000000..81858a989f
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/host.c
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Read from the host filesystem
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stand.h>
+#include <bootstrap.h>
+
+#include "libuserboot.h"
+
+/*
+ * Open a file.
+ */
+static int
+host_open(const char *upath, struct open_file *f)
+{
+
+ if (f->f_dev != &host_dev)
+ return (EINVAL);
+
+ return (CALLBACK(open, upath, &f->f_fsdata));
+}
+
+static int
+host_close(struct open_file *f)
+{
+
+ CALLBACK(close, f->f_fsdata);
+ f->f_fsdata = (void *)0;
+
+ return (0);
+}
+
+/*
+ * Copy a portion of a file into memory.
+ */
+static int
+host_read(struct open_file *f, void *start, size_t size, size_t *resid)
+{
+
+ return (CALLBACK(read, f->f_fsdata, start, size, resid));
+}
+
+/*
+ * Don't be silly - the bootstrap has no business writing anything.
+ */
+static int
+host_write(struct open_file *f, void *start, size_t size, size_t *resid)
+{
+
+ return (EROFS);
+}
+
+static off_t
+host_seek(struct open_file *f, off_t offset, int where)
+{
+
+ return (CALLBACK(seek, f->f_fsdata, offset, where));
+}
+
+static int
+host_stat(struct open_file *f, struct stat *sb)
+{
+ int mode;
+ int uid;
+ int gid;
+ uint64_t size;
+
+ CALLBACK(stat, f->f_fsdata, &mode, &uid, &gid, &size);
+ sb->st_mode = mode;
+ sb->st_uid = uid;
+ sb->st_gid = gid;
+ sb->st_size = size;
+ return (0);
+}
+
+static int
+host_readdir(struct open_file *f, struct dirent *d)
+{
+ uint32_t fileno;
+ uint8_t type;
+ size_t namelen;
+ int rc;
+
+ rc = CALLBACK(readdir, f->f_fsdata, &fileno, &type, &namelen,
+ d->d_name);
+ if (rc)
+ return (rc);
+
+ d->d_fileno = fileno;
+ d->d_type = type;
+ d->d_namlen = namelen;
+
+ return (0);
+}
+
+static int
+host_dev_init(void)
+{
+
+ return (0);
+}
+
+static void
+host_dev_print(int verbose)
+{
+ char line[80];
+
+ sprintf(line, " host%d: Host filesystem\n", 0);
+ pager_output(line);
+}
+
+/*
+ * 'Open' the host device.
+ */
+static int
+host_dev_open(struct open_file *f, ...)
+{
+ va_list args;
+ struct devdesc *dev;
+
+ va_start(args, f);
+ dev = va_arg(args, struct devdesc*);
+ va_end(args);
+
+ return (0);
+}
+
+static int
+host_dev_close(struct open_file *f)
+{
+
+ return (0);
+}
+
+static int
+host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
+ char *buf, size_t *rsize)
+{
+
+ return (ENOSYS);
+}
+
+struct fs_ops host_fsops = {
+ "host",
+ host_open,
+ host_close,
+ host_read,
+ host_write,
+ host_seek,
+ host_stat,
+ host_readdir
+};
+
+struct devsw host_dev = {
+ .dv_name = "host",
+ .dv_type = DEVT_NET,
+ .dv_init = host_dev_init,
+ .dv_strategy = host_dev_strategy,
+ .dv_open = host_dev_open,
+ .dv_close = host_dev_close,
+ .dv_ioctl = noioctl,
+ .dv_print = host_dev_print,
+ .dv_cleanup = NULL
+};
diff --git a/usr/src/boot/sys/boot/userboot/userboot/libuserboot.h b/usr/src/boot/sys/boot/userboot/userboot/libuserboot.h
new file mode 100644
index 0000000000..e2048d5fef
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/libuserboot.h
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "userboot.h"
+
+extern struct loader_callbacks *callbacks;
+extern void *callbacks_arg;
+
+#define CALLBACK(fn, args...) (callbacks->fn(callbacks_arg , ##args))
+
+#define MAXDEV 31 /* maximum number of distinct devices */
+
+typedef unsigned long physaddr_t;
+
+/* exported devices */
+extern struct devsw userboot_disk;
+extern int userboot_disk_maxunit;
+extern struct devsw host_dev;
+
+/* access to host filesystem */
+struct fs_ops host_fsops;
+
+struct bootinfo;
+struct preloaded_file;
+extern int bi_load(struct bootinfo *, struct preloaded_file *);
+
+extern void delay(int);
+
+extern int userboot_autoload(void);
+extern ssize_t userboot_copyin(const void *, vm_offset_t, size_t);
+extern ssize_t userboot_copyout(vm_offset_t, void *, size_t);
+extern ssize_t userboot_readin(int, vm_offset_t, size_t);
+extern int userboot_getdev(void **, const char *, const char **);
+char *userboot_fmtdev(void *vdev);
+int userboot_setcurrdev(struct env_var *ev, int flags, const void *value);
+
+int bi_getboothowto(char *kargs);
+void bi_setboothowto(int howto);
+vm_offset_t bi_copyenv(vm_offset_t addr);
+int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip,
+ vm_offset_t *modulep, vm_offset_t *kernend);
+int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend);
+void bios_addsmapdata(struct preloaded_file *kfp);
diff --git a/usr/src/boot/sys/boot/userboot/userboot/main.c b/usr/src/boot/sys/boot/userboot/userboot/main.c
new file mode 100644
index 0000000000..3a7a7fb91c
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/main.c
@@ -0,0 +1,294 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include "bootstrap.h"
+#include "disk.h"
+#include "libuserboot.h"
+
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+
+static void userboot_zfs_probe(void);
+static int userboot_zfs_found;
+#endif
+
+/* Minimum version required */
+#define USERBOOT_VERSION USERBOOT_VERSION_3
+
+#define MALLOCSZ (10*1024*1024)
+
+struct loader_callbacks *callbacks;
+void *callbacks_arg;
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+static jmp_buf jb;
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+static void extract_currdev(void);
+
+void
+delay(int usec)
+{
+
+ CALLBACK(delay, usec);
+}
+
+void
+exit(int v)
+{
+
+ CALLBACK(exit, v);
+ longjmp(jb, 1);
+}
+
+void
+loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
+{
+ static char mallocbuf[MALLOCSZ];
+ const char *var;
+ int i;
+
+ if (version < USERBOOT_VERSION)
+ abort();
+
+ callbacks = cb;
+ callbacks_arg = arg;
+ userboot_disk_maxunit = ndisks;
+
+ /*
+ * initialise the heap as early as possible. Once this is done,
+ * alloc() is usable.
+ */
+ setheap((void *)mallocbuf, (void *)(mallocbuf + sizeof(mallocbuf)));
+
+ /*
+ * Hook up the console
+ */
+ cons_probe();
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+#if 0
+ printf("Memory: %ld k\n", memsize() / 1024);
+#endif
+
+ setenv("LINES", "24", 1); /* optional */
+
+ /*
+ * Set custom environment variables
+ */
+ i = 0;
+ while (1) {
+ var = CALLBACK(getenv, i++);
+ if (var == NULL)
+ break;
+ putenv(var);
+ }
+
+ archsw.arch_autoload = userboot_autoload;
+ archsw.arch_getdev = userboot_getdev;
+ archsw.arch_copyin = userboot_copyin;
+ archsw.arch_copyout = userboot_copyout;
+ archsw.arch_readin = userboot_readin;
+#if defined(USERBOOT_ZFS_SUPPORT)
+ archsw.arch_zfs_probe = userboot_zfs_probe;
+#endif
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ extract_currdev();
+
+ if (setjmp(jb))
+ return;
+
+ interact(NULL); /* doesn't return */
+
+ exit(0);
+}
+
+/*
+ * Set the 'current device' by (if possible) recovering the boot device as
+ * supplied by the initial bootstrap.
+ */
+static void
+extract_currdev(void)
+{
+ struct disk_devdesc dev;
+
+ //bzero(&dev, sizeof(dev));
+
+#if defined(USERBOOT_ZFS_SUPPORT)
+ if (userboot_zfs_found) {
+ struct zfs_devdesc zdev;
+
+ /* Leave the pool/root guid's unassigned */
+ bzero(&zdev, sizeof(zdev));
+ zdev.d_dev = &zfs_dev;
+ zdev.d_type = zdev.d_dev->dv_type;
+
+ dev = *(struct disk_devdesc *)&zdev;
+ init_zfs_bootenv(zfs_fmtdev(&dev));
+ } else
+#endif
+
+ if (userboot_disk_maxunit > 0) {
+ dev.d_dev = &userboot_disk;
+ dev.d_type = dev.d_dev->dv_type;
+ dev.d_unit = 0;
+ dev.d_slice = 0;
+ dev.d_partition = 0;
+ /*
+ * If we cannot auto-detect the partition type then
+ * access the disk as a raw device.
+ */
+ if (dev.d_dev->dv_open(NULL, &dev)) {
+ dev.d_slice = -1;
+ dev.d_partition = -1;
+ }
+ } else {
+ dev.d_dev = &host_dev;
+ dev.d_type = dev.d_dev->dv_type;
+ dev.d_unit = 0;
+ }
+
+ env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
+ userboot_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev),
+ env_noset, env_nounset);
+}
+
+#if defined(USERBOOT_ZFS_SUPPORT)
+static void
+userboot_zfs_probe(void)
+{
+ char devname[32];
+ uint64_t pool_guid;
+ int unit;
+
+ /*
+ * Open all the disks we can find and see if we can reconstruct
+ * ZFS pools from them. Record if any were found.
+ */
+ for (unit = 0; unit < userboot_disk_maxunit; unit++) {
+ sprintf(devname, "disk%d:", unit);
+ pool_guid = 0;
+ zfs_probe_dev(devname, &pool_guid);
+ if (pool_guid != 0)
+ userboot_zfs_found = 1;
+ }
+}
+
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+ command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "a single dataset must be supplied";
+ return (CMD_ERROR);
+ }
+
+ err = zfs_list(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+
+COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
+ command_reloadbe);
+
+static int
+command_reloadbe(int argc, char *argv[])
+{
+ int err;
+ char *root;
+
+ if (argc > 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ if (argc == 2) {
+ err = zfs_bootenv(argv[1]);
+ } else {
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ return (CMD_OK);
+ }
+ err = zfs_bootenv(root);
+ }
+
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+
+ return (CMD_OK);
+}
+#endif /* USERBOOT_ZFS_SUPPORT */
+
+COMMAND_SET(quit, "quit", "exit the loader", command_quit);
+
+static int
+command_quit(int argc, char *argv[])
+{
+
+ exit(USERBOOT_EXIT_QUIT);
+ return (CMD_OK);
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+
+ exit(USERBOOT_EXIT_REBOOT);
+ return (CMD_OK);
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c b/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c
new file mode 100644
index 0000000000..6f73ad5633
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+int console;
+
+static struct console *userboot_comconsp;
+
+static void userboot_cons_probe(struct console *cp);
+static int userboot_cons_init(int);
+static void userboot_comcons_probe(struct console *cp);
+static int userboot_comcons_init(int);
+static void userboot_cons_putchar(int);
+static int userboot_cons_getchar(void);
+static int userboot_cons_poll(void);
+
+struct console userboot_console = {
+ "userboot",
+ "userboot",
+ 0,
+ userboot_cons_probe,
+ userboot_cons_init,
+ userboot_cons_putchar,
+ userboot_cons_getchar,
+ userboot_cons_poll,
+};
+
+/*
+ * Provide a simple alias to allow loader scripts to set the
+ * console to comconsole without resulting in an error
+ */
+struct console userboot_comconsole = {
+ "comconsole",
+ "comconsole",
+ 0,
+ userboot_comcons_probe,
+ userboot_comcons_init,
+ userboot_cons_putchar,
+ userboot_cons_getchar,
+ userboot_cons_poll,
+};
+
+static void
+userboot_cons_probe(struct console *cp)
+{
+
+ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+}
+
+static int
+userboot_cons_init(int arg)
+{
+
+ return (0);
+}
+
+static void
+userboot_comcons_probe(struct console *cp)
+{
+
+ /*
+ * Save the console pointer so the comcons_init routine
+ * can set the C_PRESENT* flags. They are not set
+ * here to allow the existing userboot console to
+ * be elected the default.
+ */
+ userboot_comconsp = cp;
+}
+
+static int
+userboot_comcons_init(int arg)
+{
+
+ /*
+ * Set the C_PRESENT* flags to allow the comconsole
+ * to be selected as the active console
+ */
+ userboot_comconsp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+ return (0);
+}
+
+static void
+userboot_cons_putchar(int c)
+{
+
+ CALLBACK(putc, c);
+}
+
+static int
+userboot_cons_getchar()
+{
+
+ return (CALLBACK(getc));
+}
+
+static int
+userboot_cons_poll()
+{
+
+ return (CALLBACK(poll));
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c b/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c
new file mode 100644
index 0000000000..bbd9efcc03
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c
@@ -0,0 +1,196 @@
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Userboot disk image handling.
+ */
+
+#include <sys/disk.h>
+#include <stand.h>
+#include <stdarg.h>
+#include <bootstrap.h>
+
+#include "disk.h"
+#include "libuserboot.h"
+
+struct userdisk_info {
+ uint64_t mediasize;
+ uint16_t sectorsize;
+};
+
+int userboot_disk_maxunit = 0;
+
+static int userdisk_maxunit = 0;
+static struct userdisk_info *ud_info;
+
+static int userdisk_init(void);
+static void userdisk_cleanup(void);
+static int userdisk_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, char *buf, size_t *rsize);
+static int userdisk_open(struct open_file *f, ...);
+static int userdisk_close(struct open_file *f);
+static int userdisk_ioctl(struct open_file *f, u_long cmd, void *data);
+static void userdisk_print(int verbose);
+
+struct devsw userboot_disk = {
+ "disk",
+ DEVT_DISK,
+ userdisk_init,
+ userdisk_strategy,
+ userdisk_open,
+ userdisk_close,
+ userdisk_ioctl,
+ userdisk_print,
+ userdisk_cleanup
+};
+
+/*
+ * Initialize userdisk_info structure for each disk.
+ */
+static int
+userdisk_init(void)
+{
+ off_t mediasize;
+ u_int sectorsize;
+ int i;
+
+ userdisk_maxunit = userboot_disk_maxunit;
+ if (userdisk_maxunit > 0) {
+ ud_info = malloc(sizeof(*ud_info) * userdisk_maxunit);
+ if (ud_info == NULL)
+ return (ENOMEM);
+ for (i = 0; i < userdisk_maxunit; i++) {
+ if (CALLBACK(diskioctl, i, DIOCGSECTORSIZE,
+ &sectorsize) != 0 || CALLBACK(diskioctl, i,
+ DIOCGMEDIASIZE, &mediasize) != 0)
+ return (ENXIO);
+ ud_info[i].mediasize = mediasize;
+ ud_info[i].sectorsize = sectorsize;
+ }
+ }
+
+ return(0);
+}
+
+static void
+userdisk_cleanup(void)
+{
+
+ if (userdisk_maxunit > 0)
+ free(ud_info);
+ disk_cleanup(&userboot_disk);
+}
+
+/*
+ * Print information about disks
+ */
+static void
+userdisk_print(int verbose)
+{
+ struct disk_devdesc dev;
+ char line[80];
+ int i;
+
+ for (i = 0; i < userdisk_maxunit; i++) {
+ sprintf(line, " disk%d: Guest drive image\n", i);
+ pager_output(line);
+ dev.d_dev = &userboot_disk;
+ dev.d_unit = i;
+ dev.d_slice = -1;
+ dev.d_partition = -1;
+ if (disk_open(&dev, ud_info[i].mediasize,
+ ud_info[i].sectorsize, 0) == 0) {
+ sprintf(line, " disk%d", i);
+ disk_print(&dev, line, verbose);
+ disk_close(&dev);
+ }
+ }
+}
+
+/*
+ * Attempt to open the disk described by (dev) for use by (f).
+ */
+static int
+userdisk_open(struct open_file *f, ...)
+{
+ va_list ap;
+ struct disk_devdesc *dev;
+
+ va_start(ap, f);
+ dev = va_arg(ap, struct disk_devdesc *);
+ va_end(ap);
+
+ if (dev->d_unit < 0 || dev->d_unit >= userdisk_maxunit)
+ return (EIO);
+
+ return (disk_open(dev, ud_info[dev->d_unit].mediasize,
+ ud_info[dev->d_unit].sectorsize, 0));
+}
+
+static int
+userdisk_close(struct open_file *f)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ return (disk_close(dev));
+}
+
+static int
+userdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
+ char *buf, size_t *rsize)
+{
+ struct disk_devdesc *dev = devdata;
+ uint64_t off;
+ size_t resid;
+ int rc;
+
+ if (rw == F_WRITE)
+ return (EROFS);
+ if (rw != F_READ)
+ return (EINVAL);
+ if (rsize)
+ *rsize = 0;
+ off = (dblk + dev->d_offset) * ud_info[dev->d_unit].sectorsize;
+ rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid);
+ if (rc)
+ return (rc);
+ if (rsize)
+ *rsize = size - resid;
+ return (0);
+}
+
+static int
+userdisk_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ return (CALLBACK(diskioctl, dev->d_unit, cmd, data));
+}
diff --git a/usr/src/boot/sys/boot/userboot/userboot/version b/usr/src/boot/sys/boot/userboot/userboot/version
new file mode 100644
index 0000000000..ce6e2701fd
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/userboot/version
@@ -0,0 +1,4 @@
+$FreeBSD$
+
+1.1: Initial userland boot
+
diff --git a/usr/src/boot/sys/boot/userboot/zfs/Makefile b/usr/src/boot/sys/boot/userboot/zfs/Makefile
new file mode 100644
index 0000000000..8fe315b38e
--- /dev/null
+++ b/usr/src/boot/sys/boot/userboot/zfs/Makefile
@@ -0,0 +1,18 @@
+# $FreeBSD$
+
+S= ${.CURDIR}/../../zfs
+
+.PATH: ${S}
+LIB= zfsboot
+INTERNALLIB=
+
+SRCS+= zfs.c
+
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+
+CFLAGS+= -ffreestanding -fPIC
+CFLAGS+= -Wformat -Wall
+
+.include <bsd.lib.mk>
diff --git a/usr/src/boot/sys/boot/zfs/Makefile b/usr/src/boot/sys/boot/zfs/Makefile
new file mode 100644
index 0000000000..025cd562d3
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/Makefile
@@ -0,0 +1,34 @@
+#
+# 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 2015 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+SUBDIRS= i386 amd64
+
+all:= TARGET= all
+install:= TARGET= install
+clean:= TARGET= clean
+clobber:= TARGET= clobber
+
+.KEEP_STATE:
+
+all clean clobber: $(SUBDIRS)
+
+install: $(SUBDIRS)
+
+FRC:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/boot/sys/boot/zfs/Makefile.com b/usr/src/boot/sys/boot/zfs/Makefile.com
new file mode 100644
index 0000000000..bb11ab91d6
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/Makefile.com
@@ -0,0 +1,58 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include $(SRC)/Makefile.master
+
+LIB= zfsboot
+
+all: machine x86 libzfsboot.a
+clean: clobber
+
+clobber:
+ $(RM) machine x86 $(OBJS) libzfsboot.a
+
+CC= $(GCC_ROOT)/bin/gcc
+CPPFLAGS=
+
+SRCS += ../zfs.c ../gzip.c
+OBJS += zfs.o gzip.o
+
+CFLAGS= -O2 -nostdinc -I../../../../include -I../../..
+CFLAGS += -I../../common -I../../.. -I.. -I.
+CFLAGS += -I../../../../lib/libstand
+CFLAGS += -I../../../../lib/libz
+CFLAGS += -I../../../cddl/boot/zfs
+
+CFLAGS += -ffreestanding
+CFLAGS += -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
+CFLAGS += -Wformat -Wall -std=gnu99
+
+CLEANFILES += machine x86
+
+machine:
+ $(RM) machine
+ $(SYMLINK) ../../../$(MACHINE)/include machine
+
+x86:
+ $(RM) x86
+ $(SYMLINK) ../../../x86/include x86
+
+libzfsboot.a: $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+%.o: ../%.c
+ $(COMPILE.c) -o $@ $<
+
+zfs.o: ../zfsimpl.c
diff --git a/usr/src/boot/sys/boot/zfs/amd64/Makefile b/usr/src/boot/sys/boot/zfs/amd64/Makefile
new file mode 100644
index 0000000000..80eb330468
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/amd64/Makefile
@@ -0,0 +1,20 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include ../Makefile.com
+
+CFLAGS += -mno-red-zone -m64 -fPIC
+
+MACHINE= $(MACH64)
diff --git a/usr/src/boot/sys/boot/zfs/devicename_stubs.c b/usr/src/boot/sys/boot/zfs/devicename_stubs.c
new file mode 100644
index 0000000000..41bf907e0c
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/devicename_stubs.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "libzfs.h"
+
+__attribute__((weak))
+int
+zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
+{
+ return (EINVAL);
+}
+
+__attribute__((weak))
+char *
+zfs_fmtdev(void *vdev)
+{
+ static char buf[128];
+
+ return (buf);
+}
diff --git a/usr/src/boot/sys/boot/zfs/gzip.c b/usr/src/boot/sys/boot/zfs/gzip.c
new file mode 100644
index 0000000000..676d1cb87f
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/gzip.c
@@ -0,0 +1,66 @@
+/*
+ * 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 2015 Toomas Soome <tsoome@me.com>
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <zlib.h>
+#include <strings.h>
+
+int gzip_decompress(void *, void *, size_t, size_t, int);
+/*
+ * Uncompress the buffer 'src' into the buffer 'dst'. The caller must store
+ * the expected decompressed data size externally so it can be passed in.
+ * The resulting decompressed size is then returned through dstlen. This
+ * function return Z_OK on success, or another error code on failure.
+ */
+static int
+z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
+{
+ z_stream zs;
+ int err;
+
+ bzero(&zs, sizeof (zs));
+ zs.next_in = (unsigned char *)src;
+ zs.avail_in = srclen;
+ zs.next_out = dst;
+ zs.avail_out = *dstlen;
+
+ /*
+ * Call inflateInit2() specifying a window size of DEF_WBITS
+ * with the 6th bit set to indicate that the compression format
+ * type (zlib or gzip) should be automatically detected.
+ */
+ if ((err = inflateInit2(&zs, 15 | 0x20)) != Z_OK)
+ return (err);
+
+ if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
+ (void) inflateEnd(&zs);
+ return (err == Z_OK ? Z_BUF_ERROR : err);
+ }
+
+ *dstlen = zs.total_out;
+ return (inflateEnd(&zs));
+}
+
+int
+gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+ size_t dstlen = d_len;
+
+ if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK)
+ return (-1);
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/boot/zfs/i386/Makefile b/usr/src/boot/sys/boot/zfs/i386/Makefile
new file mode 100644
index 0000000000..f2bb545d73
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/i386/Makefile
@@ -0,0 +1,21 @@
+#
+# 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 Toomas Soome <tsoome@me.com>
+#
+
+include ../Makefile.com
+
+CFLAGS += -march=i386 -m32 -fno-reorder-functions
+CFLAGS += -mpreferred-stack-boundary=2
+
+MACHINE= $(MACH)
diff --git a/usr/src/boot/sys/boot/zfs/libzfs.h b/usr/src/boot/sys/boot/zfs/libzfs.h
new file mode 100644
index 0000000000..b237a38b96
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/libzfs.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOT_LIBZFS_H_
+#define _BOOT_LIBZFS_H_
+
+#define ZFS_MAXNAMELEN 256
+
+/*
+ * ZFS fully-qualified device descriptor.
+ * Note, this must match the 'struct devdesc' declaration in bootstrap.h.
+ * Arch-specific device descriptors should be binary compatible with this
+ * structure if they are to support ZFS.
+ */
+struct zfs_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ void *d_opendata;
+ uint64_t pool_guid;
+ uint64_t root_guid;
+};
+
+struct zfs_boot_args
+{
+ uint32_t size;
+ uint32_t reserved;
+ uint64_t pool;
+ uint64_t root;
+ uint64_t primary_pool;
+ uint64_t primary_vdev;
+};
+
+int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
+ const char **path);
+char *zfs_bootfs(void *vdev);
+char *zfs_fmtdev(void *vdev);
+int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
+int zfs_list(const char *name);
+#ifdef __FreeBSD__
+void init_zfs_bootenv(char *currdev);
+int zfs_bootenv(const char *name);
+int zfs_belist_add(const char *name, uint64_t __unused);
+int zfs_set_env(void);
+#endif
+
+extern struct devsw zfs_dev;
+extern struct fs_ops zfs_fsops;
+
+#endif /*_BOOT_LIBZFS_H_*/
diff --git a/usr/src/boot/sys/boot/zfs/zfs.c b/usr/src/boot/sys/boot/zfs/zfs.c
new file mode 100644
index 0000000000..f8d95662b5
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/zfs.c
@@ -0,0 +1,971 @@
+/*-
+ * Copyright (c) 2007 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * Stand-alone file reading package.
+ */
+
+#include <sys/disk.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <part.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stand.h>
+#include <bootstrap.h>
+
+#include "libzfs.h"
+
+#include "zfsimpl.c"
+
+/* Define the range of indexes to be populated with ZFS Boot Environments */
+#define ZFS_BE_FIRST 4
+#define ZFS_BE_LAST 8
+
+static int zfs_open(const char *path, struct open_file *f);
+static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int zfs_close(struct open_file *f);
+static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t zfs_seek(struct open_file *f, off_t offset, int where);
+static int zfs_stat(struct open_file *f, struct stat *sb);
+static int zfs_readdir(struct open_file *f, struct dirent *d);
+
+struct devsw zfs_dev;
+
+struct fs_ops zfs_fsops = {
+ "zfs",
+ zfs_open,
+ zfs_close,
+ zfs_read,
+ zfs_write,
+ zfs_seek,
+ zfs_stat,
+ zfs_readdir
+};
+
+/*
+ * In-core open file.
+ */
+struct file {
+ off_t f_seekp; /* seek pointer */
+ dnode_phys_t f_dnode;
+ uint64_t f_zap_type; /* zap type for readdir */
+ uint64_t f_num_leafs; /* number of fzap leaf blocks */
+ zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */
+};
+
+#ifdef __FreeBSD__
+static int zfs_env_index;
+static int zfs_env_count;
+#endif
+
+SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
+struct zfs_be_list *zfs_be_headp;
+struct zfs_be_entry {
+ const char *name;
+ SLIST_ENTRY(zfs_be_entry) entries;
+} *zfs_be, *zfs_be_tmp;
+
+/*
+ * Open a file.
+ */
+static int
+zfs_open(const char *upath, struct open_file *f)
+{
+ struct zfsmount *mount = (struct zfsmount *)f->f_devdata;
+ struct file *fp;
+ int rc;
+
+ if (f->f_dev != &zfs_dev)
+ return (EINVAL);
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ rc = zfs_lookup(mount, upath, &fp->f_dnode);
+ fp->f_seekp = 0;
+ if (rc) {
+ f->f_fsdata = NULL;
+ free(fp);
+ }
+ return (rc);
+}
+
+static int
+zfs_close(struct open_file *f)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ dnode_cache_obj = 0;
+ f->f_fsdata = (void *)0;
+ if (fp == (struct file *)0)
+ return (0);
+
+ free(fp);
+ return (0);
+}
+
+/*
+ * Copy a portion of a file into kernel memory.
+ * Cross block boundaries when necessary.
+ */
+static int
+zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */)
+{
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct stat sb;
+ size_t n;
+ int rc;
+
+ rc = zfs_stat(f, &sb);
+ if (rc)
+ return (rc);
+ n = size;
+ if (fp->f_seekp + n > sb.st_size)
+ n = sb.st_size - fp->f_seekp;
+
+ rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n);
+ if (rc)
+ return (rc);
+
+ if (0) {
+ int i;
+ for (i = 0; i < n; i++)
+ putchar(((char*) start)[i]);
+ }
+ fp->f_seekp += n;
+ if (resid)
+ *resid = size - n;
+
+ return (0);
+}
+
+/*
+ * Don't be silly - the bootstrap has no business writing anything.
+ */
+static int
+zfs_write(struct open_file *f, void *start, size_t size, size_t *resid /* out */)
+{
+
+ return (EROFS);
+}
+
+static off_t
+zfs_seek(struct open_file *f, off_t offset, int where)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seekp = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seekp += offset;
+ break;
+ case SEEK_END:
+ {
+ struct stat sb;
+ int error;
+
+ error = zfs_stat(f, &sb);
+ if (error != 0) {
+ errno = error;
+ return (-1);
+ }
+ fp->f_seekp = sb.st_size - offset;
+ break;
+ }
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (fp->f_seekp);
+}
+
+static int
+zfs_stat(struct open_file *f, struct stat *sb)
+{
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ return (zfs_dnode_stat(spa, &fp->f_dnode, sb));
+}
+
+static int
+zfs_readdir(struct open_file *f, struct dirent *d)
+{
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
+ struct file *fp = (struct file *)f->f_fsdata;
+ mzap_ent_phys_t mze;
+ struct stat sb;
+ size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ int rc;
+
+ rc = zfs_stat(f, &sb);
+ if (rc)
+ return (rc);
+ if (!S_ISDIR(sb.st_mode))
+ return (ENOTDIR);
+
+ /*
+ * If this is the first read, get the zap type.
+ */
+ if (fp->f_seekp == 0) {
+ rc = dnode_read(spa, &fp->f_dnode,
+ 0, &fp->f_zap_type, sizeof(fp->f_zap_type));
+ if (rc)
+ return (rc);
+
+ if (fp->f_zap_type == ZBT_MICRO) {
+ fp->f_seekp = offsetof(mzap_phys_t, mz_chunk);
+ } else {
+ rc = dnode_read(spa, &fp->f_dnode,
+ offsetof(zap_phys_t, zap_num_leafs),
+ &fp->f_num_leafs,
+ sizeof(fp->f_num_leafs));
+ if (rc)
+ return (rc);
+
+ fp->f_seekp = bsize;
+ fp->f_zap_leaf = (zap_leaf_phys_t *)malloc(bsize);
+ rc = dnode_read(spa, &fp->f_dnode,
+ fp->f_seekp,
+ fp->f_zap_leaf,
+ bsize);
+ if (rc)
+ return (rc);
+ }
+ }
+
+ if (fp->f_zap_type == ZBT_MICRO) {
+ mzap_next:
+ if (fp->f_seekp >= bsize)
+ return (ENOENT);
+
+ rc = dnode_read(spa, &fp->f_dnode,
+ fp->f_seekp, &mze, sizeof(mze));
+ if (rc)
+ return (rc);
+ fp->f_seekp += sizeof(mze);
+
+ if (!mze.mze_name[0])
+ goto mzap_next;
+
+ d->d_fileno = ZFS_DIRENT_OBJ(mze.mze_value);
+ d->d_type = ZFS_DIRENT_TYPE(mze.mze_value);
+ strcpy(d->d_name, mze.mze_name);
+ d->d_namlen = strlen(d->d_name);
+ return (0);
+ } else {
+ zap_leaf_t zl;
+ zap_leaf_chunk_t *zc, *nc;
+ int chunk;
+ size_t namelen;
+ char *p;
+ uint64_t value;
+
+ /*
+ * Initialise this so we can use the ZAP size
+ * calculating macros.
+ */
+ zl.l_bs = ilog2(bsize);
+ zl.l_phys = fp->f_zap_leaf;
+
+ /*
+ * Figure out which chunk we are currently looking at
+ * and consider seeking to the next leaf. We use the
+ * low bits of f_seekp as a simple chunk index.
+ */
+ fzap_next:
+ chunk = fp->f_seekp & (bsize - 1);
+ if (chunk == ZAP_LEAF_NUMCHUNKS(&zl)) {
+ fp->f_seekp = (fp->f_seekp & ~(bsize - 1)) + bsize;
+ chunk = 0;
+
+ /*
+ * Check for EOF and read the new leaf.
+ */
+ if (fp->f_seekp >= bsize * fp->f_num_leafs)
+ return (ENOENT);
+
+ rc = dnode_read(spa, &fp->f_dnode,
+ fp->f_seekp,
+ fp->f_zap_leaf,
+ bsize);
+ if (rc)
+ return (rc);
+ }
+
+ zc = &ZAP_LEAF_CHUNK(&zl, chunk);
+ fp->f_seekp++;
+ if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
+ goto fzap_next;
+
+ namelen = zc->l_entry.le_name_numints;
+ if (namelen > sizeof(d->d_name))
+ namelen = sizeof(d->d_name);
+
+ /*
+ * Paste the name back together.
+ */
+ nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk);
+ p = d->d_name;
+ while (namelen > 0) {
+ int len;
+ len = namelen;
+ if (len > ZAP_LEAF_ARRAY_BYTES)
+ len = ZAP_LEAF_ARRAY_BYTES;
+ memcpy(p, nc->l_array.la_array, len);
+ p += len;
+ namelen -= len;
+ nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next);
+ }
+ d->d_name[sizeof(d->d_name) - 1] = 0;
+
+ /*
+ * Assume the first eight bytes of the value are
+ * a uint64_t.
+ */
+ value = fzap_leaf_value(&zl, zc);
+
+ d->d_fileno = ZFS_DIRENT_OBJ(value);
+ d->d_type = ZFS_DIRENT_TYPE(value);
+ d->d_namlen = strlen(d->d_name);
+
+ return (0);
+ }
+}
+
+static int
+vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size)
+{
+ int fd;
+
+ fd = (uintptr_t) priv;
+ lseek(fd, offset, SEEK_SET);
+ if (read(fd, buf, size) == size) {
+ return 0;
+ } else {
+ return (EIO);
+ }
+}
+
+static int
+zfs_dev_init(void)
+{
+ spa_t *spa;
+ spa_t *next;
+ spa_t *prev;
+
+ zfs_init();
+ if (archsw.arch_zfs_probe == NULL)
+ return (ENXIO);
+ archsw.arch_zfs_probe();
+
+ prev = NULL;
+ spa = STAILQ_FIRST(&zfs_pools);
+ while (spa != NULL) {
+ next = STAILQ_NEXT(spa, spa_link);
+ if (zfs_spa_init(spa)) {
+ if (prev == NULL)
+ STAILQ_REMOVE_HEAD(&zfs_pools, spa_link);
+ else
+ STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link);
+ } else
+ prev = spa;
+ spa = next;
+ }
+ return (0);
+}
+
+struct zfs_probe_args {
+ int fd;
+ const char *devname;
+ uint64_t *pool_guid;
+ u_int secsz;
+};
+
+static int
+zfs_diskread(void *arg, void *buf, size_t blocks, off_t offset)
+{
+ struct zfs_probe_args *ppa;
+
+ ppa = (struct zfs_probe_args *)arg;
+ return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd,
+ offset * ppa->secsz, buf, blocks * ppa->secsz));
+}
+
+static int
+zfs_probe(int fd, uint64_t *pool_guid)
+{
+ spa_t *spa;
+ int ret;
+
+ ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa);
+ if (ret == 0 && pool_guid != NULL)
+ *pool_guid = spa->spa_guid;
+ return (ret);
+}
+
+static int
+zfs_probe_partition(void *arg, const char *partname,
+ const struct ptable_entry *part)
+{
+ struct zfs_probe_args *ppa, pa;
+ struct ptable *table;
+ char devname[32];
+ int ret = 0;
+
+ /* filter out partitions *not* used by zfs */
+ switch (part->type) {
+ case PART_RESERVED: /* efi reserverd */
+ case PART_VTOC_BOOT: /* vtoc boot area */
+ case PART_VTOC_SWAP:
+ return (ret);
+ default:
+ break;;
+ }
+ ppa = (struct zfs_probe_args *)arg;
+ strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
+ devname[strlen(ppa->devname) - 1] = '\0';
+ sprintf(devname, "%s%s:", devname, partname);
+ pa.fd = open(devname, O_RDONLY);
+ if (pa.fd == -1)
+ return (ret);
+ ret = zfs_probe(pa.fd, ppa->pool_guid);
+ if (ret == 0)
+ return (ret);
+ if (part->type == PART_SOLARIS2) {
+ pa.devname = devname;
+ pa.pool_guid = ppa->pool_guid;
+ pa.secsz = ppa->secsz;
+ table = ptable_open(&pa, part->end - part->start + 1,
+ ppa->secsz, zfs_diskread);
+ if (table != NULL) {
+ ptable_iterate(table, &pa, zfs_probe_partition);
+ ptable_close(table);
+ }
+ }
+ close(pa.fd);
+ return (0);
+}
+
+int
+zfs_probe_dev(const char *devname, uint64_t *pool_guid)
+{
+ struct ptable *table;
+ struct zfs_probe_args pa;
+ off_t mediasz;
+ int ret;
+
+ pa.fd = open(devname, O_RDONLY);
+ if (pa.fd == -1)
+ return (ENXIO);
+ /* Probe the whole disk */
+ ret = zfs_probe(pa.fd, pool_guid);
+ if (ret == 0)
+ return (0);
+ /* Probe each partition */
+ ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
+ if (ret == 0)
+ ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
+ if (ret == 0) {
+ pa.devname = devname;
+ pa.pool_guid = pool_guid;
+ table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
+ zfs_diskread);
+ if (table != NULL) {
+ ptable_iterate(table, &pa, zfs_probe_partition);
+ ptable_close(table);
+ }
+ }
+ close(pa.fd);
+ return (ret);
+}
+
+/*
+ * Print information about ZFS pools
+ */
+static int
+zfs_dev_print(int verbose)
+{
+ spa_t *spa;
+ char line[80];
+ int ret = 0;
+
+ if (verbose) {
+ return (spa_all_status());
+ }
+ STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
+ sprintf(line, " zfs:%s\n", spa->spa_name);
+ ret = pager_output(line);
+ if (ret != 0)
+ break;
+ }
+ return (ret);
+}
+
+/*
+ * Attempt to open the pool described by (dev) for use by (f).
+ */
+static int
+zfs_dev_open(struct open_file *f, ...)
+{
+ va_list args;
+ struct zfs_devdesc *dev;
+ struct zfsmount *mount;
+ spa_t *spa;
+ int rv;
+
+ va_start(args, f);
+ dev = va_arg(args, struct zfs_devdesc *);
+ va_end(args);
+
+ if (dev->pool_guid == 0)
+ spa = STAILQ_FIRST(&zfs_pools);
+ else
+ spa = spa_find_by_guid(dev->pool_guid);
+ if (!spa)
+ return (ENXIO);
+ mount = malloc(sizeof(*mount));
+ rv = zfs_mount(spa, dev->root_guid, mount);
+ if (rv != 0) {
+ free(mount);
+ return (rv);
+ }
+ if (mount->objset.os_type != DMU_OST_ZFS) {
+ printf("Unexpected object set type %ju\n",
+ (uintmax_t)mount->objset.os_type);
+ free(mount);
+ return (EIO);
+ }
+ f->f_devdata = mount;
+ free(dev);
+ return (0);
+}
+
+static int
+zfs_dev_close(struct open_file *f)
+{
+
+ free(f->f_devdata);
+ f->f_devdata = NULL;
+ return (0);
+}
+
+static int
+zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t offset,
+ size_t size, char *buf, size_t *rsize)
+{
+
+ return (ENOSYS);
+}
+
+struct devsw zfs_dev = {
+ .dv_name = "zfs",
+ .dv_type = DEVT_ZFS,
+ .dv_init = zfs_dev_init,
+ .dv_strategy = zfs_dev_strategy,
+ .dv_open = zfs_dev_open,
+ .dv_close = zfs_dev_close,
+ .dv_ioctl = noioctl,
+ .dv_print = zfs_dev_print,
+ .dv_cleanup = NULL
+};
+
+int
+zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
+{
+ static char rootname[ZFS_MAXNAMELEN];
+ static char poolname[ZFS_MAXNAMELEN];
+ spa_t *spa;
+ const char *end;
+ const char *np;
+ const char *sep;
+ int rv;
+
+ np = devspec;
+ if (*np != ':')
+ return (EINVAL);
+ np++;
+ end = strchr(np, ':');
+ if (end == NULL)
+ return (EINVAL);
+ sep = strchr(np, '/');
+ if (sep == NULL || sep >= end)
+ sep = end;
+ memcpy(poolname, np, sep - np);
+ poolname[sep - np] = '\0';
+ if (sep < end) {
+ sep++;
+ memcpy(rootname, sep, end - sep);
+ rootname[end - sep] = '\0';
+ }
+ else
+ rootname[0] = '\0';
+
+ spa = spa_find_by_name(poolname);
+ if (!spa)
+ return (ENXIO);
+ dev->pool_guid = spa->spa_guid;
+ rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
+ if (rv != 0)
+ return (rv);
+ if (path != NULL)
+ *path = (*end == '\0') ? end : end + 1;
+ dev->d_dev = &zfs_dev;
+ dev->d_type = zfs_dev.dv_type;
+ return (0);
+}
+
+char *
+zfs_bootfs(void *zdev)
+{
+ static char rootname[ZFS_MAXNAMELEN];
+ static char buf[2 * ZFS_MAXNAMELEN];
+ struct zfs_devdesc *dev = (struct zfs_devdesc *)zdev;
+ uint64_t objnum;
+ spa_t *spa;
+ vdev_t *vdev;
+ vdev_t *kid;
+ int n;
+
+ buf[0] = '\0';
+ if (dev->d_type != DEVT_ZFS)
+ return (buf);
+
+ spa = spa_find_by_guid(dev->pool_guid);
+ if (spa == NULL) {
+ printf("ZFS: can't find pool by guid\n");
+ return (buf);
+ }
+ if (zfs_rlookup(spa, dev->root_guid, rootname)) {
+ printf("ZFS: can't find filesystem by guid\n");
+ return (buf);
+ }
+ if (zfs_lookup_dataset(spa, rootname, &objnum)) {
+ printf("ZFS: can't find filesystem by name\n");
+ return (buf);
+ }
+
+ STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) {
+ STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) {
+ /* use this kid? */
+ if (kid->v_state == VDEV_STATE_HEALTHY &&
+ kid->v_phys_path != NULL);
+ break;
+ }
+ if (kid != NULL) {
+ vdev = kid;
+ break;
+ }
+ if (vdev->v_state == VDEV_STATE_HEALTHY &&
+ vdev->v_phys_path != NULL);
+ break;
+ }
+
+ /*
+ * since this pool was used to read in the kernel and boot archive,
+ * there has to be at least one healthy vdev, therefore vdev
+ * can not be NULL.
+ */
+ sprintf(buf, "zfs-bootfs=%s/%llu", spa->spa_name,
+ (unsigned long long)objnum);
+ n = strlen(buf);
+ if (vdev->v_phys_path != NULL) {
+ sprintf(buf+n, ",bootpath=\"%s\"", vdev->v_phys_path);
+ n = strlen(buf);
+ }
+ if (vdev->v_devid != NULL) {
+ sprintf(buf+n, ",diskdevid=\"%s\"", vdev->v_devid);
+ }
+ return (buf);
+}
+
+char *
+zfs_fmtdev(void *vdev)
+{
+ static char rootname[ZFS_MAXNAMELEN];
+ static char buf[2 * ZFS_MAXNAMELEN + 8];
+ struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
+ spa_t *spa;
+
+ buf[0] = '\0';
+ if (dev->d_type != DEVT_ZFS)
+ return (buf);
+
+ if (dev->pool_guid == 0) {
+ spa = STAILQ_FIRST(&zfs_pools);
+ dev->pool_guid = spa->spa_guid;
+ } else
+ spa = spa_find_by_guid(dev->pool_guid);
+ if (spa == NULL) {
+ printf("ZFS: can't find pool by guid\n");
+ return (buf);
+ }
+ if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
+ printf("ZFS: can't find root filesystem\n");
+ return (buf);
+ }
+ if (zfs_rlookup(spa, dev->root_guid, rootname)) {
+ printf("ZFS: can't find filesystem by guid\n");
+ return (buf);
+ }
+
+ if (rootname[0] == '\0')
+ sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name);
+ else
+ sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name,
+ rootname);
+ return (buf);
+}
+
+int
+zfs_list(const char *name)
+{
+ static char poolname[ZFS_MAXNAMELEN];
+ uint64_t objid;
+ spa_t *spa;
+ const char *dsname;
+ int len;
+ int rv;
+
+ len = strlen(name);
+ dsname = strchr(name, '/');
+ if (dsname != NULL) {
+ len = dsname - name;
+ dsname++;
+ } else
+ dsname = "";
+ memcpy(poolname, name, len);
+ poolname[len] = '\0';
+
+ spa = spa_find_by_name(poolname);
+ if (!spa)
+ return (ENXIO);
+ rv = zfs_lookup_dataset(spa, dsname, &objid);
+ if (rv != 0)
+ return (rv);
+
+ return (zfs_list_dataset(spa, objid));
+}
+
+#ifdef __FreeBSD__
+void
+init_zfs_bootenv(char *currdev)
+{
+ char *beroot;
+
+ if (strlen(currdev) == 0)
+ return;
+ if(strncmp(currdev, "zfs:", 4) != 0)
+ return;
+ /* Remove the trailing : */
+ currdev[strlen(currdev) - 1] = '\0';
+ setenv("zfs_be_active", currdev, 1);
+ setenv("zfs_be_currpage", "1", 1);
+ /* Forward past zfs: */
+ currdev = strchr(currdev, ':');
+ currdev++;
+ /* Remove the last element (current bootenv) */
+ beroot = strrchr(currdev, '/');
+ if (beroot != NULL)
+ beroot[0] = '\0';
+ beroot = currdev;
+ setenv("zfs_be_root", beroot, 1);
+}
+
+int
+zfs_bootenv(const char *name)
+{
+ static char poolname[ZFS_MAXNAMELEN], *dsname, *root;
+ char becount[4];
+ uint64_t objid;
+ spa_t *spa;
+ int len, rv, pages, perpage, currpage;
+
+ if (name == NULL)
+ return (EINVAL);
+ if ((root = getenv("zfs_be_root")) == NULL)
+ return (EINVAL);
+
+ if (strcmp(name, root) != 0) {
+ if (setenv("zfs_be_root", name, 1) != 0)
+ return (ENOMEM);
+ }
+
+ SLIST_INIT(&zfs_be_head);
+ zfs_env_count = 0;
+ len = strlen(name);
+ dsname = strchr(name, '/');
+ if (dsname != NULL) {
+ len = dsname - name;
+ dsname++;
+ } else
+ dsname = "";
+ memcpy(poolname, name, len);
+ poolname[len] = '\0';
+
+ spa = spa_find_by_name(poolname);
+ if (!spa)
+ return (ENXIO);
+ rv = zfs_lookup_dataset(spa, dsname, &objid);
+ if (rv != 0)
+ return (rv);
+ rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
+
+ /* Calculate and store the number of pages of BEs */
+ perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
+ pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
+ snprintf(becount, 4, "%d", pages);
+ if (setenv("zfs_be_pages", becount, 1) != 0)
+ return (ENOMEM);
+
+ /* Roll over the page counter if it has exceeded the maximum */
+ currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
+ if (currpage > pages) {
+ if (setenv("zfs_be_currpage", "1", 1) != 0)
+ return (ENOMEM);
+ }
+
+ /* Populate the menu environment variables */
+ zfs_set_env();
+
+ /* Clean up the SLIST of ZFS BEs */
+ while (!SLIST_EMPTY(&zfs_be_head)) {
+ zfs_be = SLIST_FIRST(&zfs_be_head);
+ SLIST_REMOVE_HEAD(&zfs_be_head, entries);
+ free(zfs_be);
+ }
+
+ return (rv);
+}
+
+int
+zfs_belist_add(const char *name, uint64_t value __unused)
+{
+
+ /* Skip special datasets that start with a $ character */
+ if (strncmp(name, "$", 1) == 0) {
+ return (0);
+ }
+ /* Add the boot environment to the head of the SLIST */
+ zfs_be = malloc(sizeof(struct zfs_be_entry));
+ if (zfs_be == NULL) {
+ return (ENOMEM);
+ }
+ zfs_be->name = name;
+ SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
+ zfs_env_count++;
+
+ return (0);
+}
+
+int
+zfs_set_env(void)
+{
+ char envname[32], envval[256];
+ char *beroot, *pagenum;
+ int rv, page, ctr;
+
+ beroot = getenv("zfs_be_root");
+ if (beroot == NULL) {
+ return (1);
+ }
+
+ pagenum = getenv("zfs_be_currpage");
+ if (pagenum != NULL) {
+ page = strtol(pagenum, NULL, 10);
+ } else {
+ page = 1;
+ }
+
+ ctr = 1;
+ rv = 0;
+ zfs_env_index = ZFS_BE_FIRST;
+ SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
+ /* Skip to the requested page number */
+ if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
+ ctr++;
+ continue;
+ }
+
+ snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
+ snprintf(envval, sizeof(envval), "%s", zfs_be->name);
+ rv = setenv(envname, envval, 1);
+ if (rv != 0) {
+ break;
+ }
+
+ snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
+ rv = setenv(envname, envval, 1);
+ if (rv != 0){
+ break;
+ }
+
+ snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
+ rv = setenv(envname, "set_bootenv", 1);
+ if (rv != 0){
+ break;
+ }
+
+ snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
+ snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
+ rv = setenv(envname, envval, 1);
+ if (rv != 0){
+ break;
+ }
+
+ zfs_env_index++;
+ if (zfs_env_index > ZFS_BE_LAST) {
+ break;
+ }
+
+ }
+
+ for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
+ snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
+ (void)unsetenv(envname);
+ snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
+ (void)unsetenv(envname);
+ snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
+ (void)unsetenv(envname);
+ snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
+ (void)unsetenv(envname);
+ }
+
+ return (rv);
+}
+#endif
diff --git a/usr/src/boot/sys/boot/zfs/zfsimpl.c b/usr/src/boot/sys/boot/zfs/zfsimpl.c
new file mode 100644
index 0000000000..d015617f3e
--- /dev/null
+++ b/usr/src/boot/sys/boot/zfs/zfsimpl.c
@@ -0,0 +1,2299 @@
+/*-
+ * Copyright (c) 2007 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * Stand-alone ZFS file reader.
+ */
+
+#include <sys/stat.h>
+#include <sys/stdint.h>
+
+#include "zfsimpl.h"
+#include "zfssubr.c"
+
+
+struct zfsmount {
+ const spa_t *spa;
+ objset_phys_t objset;
+ uint64_t rootobj;
+};
+
+/*
+ * List of all vdevs, chained through v_alllink.
+ */
+static vdev_list_t zfs_vdevs;
+
+ /*
+ * List of ZFS features supported for read
+ */
+static const char *features_for_read[] = {
+ "org.illumos:lz4_compress",
+ "com.delphix:hole_birth",
+ "com.delphix:extensible_dataset",
+ "com.delphix:embedded_data",
+ "org.open-zfs:large_blocks",
+ "org.illumos:sha512",
+ NULL
+};
+
+/*
+ * List of all pools, chained through spa_link.
+ */
+static spa_list_t zfs_pools;
+
+static uint64_t zfs_crc64_table[256];
+static const dnode_phys_t *dnode_cache_obj = 0;
+static uint64_t dnode_cache_bn;
+static char *dnode_cache_buf;
+static char *zap_scratch;
+static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr;
+
+#define TEMP_SIZE (1024 * 1024)
+
+static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf);
+static int zfs_get_root(const spa_t *spa, uint64_t *objid);
+static int zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result);
+
+static void
+zfs_init(void)
+{
+ STAILQ_INIT(&zfs_vdevs);
+ STAILQ_INIT(&zfs_pools);
+
+ zfs_temp_buf = malloc(TEMP_SIZE);
+ zfs_temp_end = zfs_temp_buf + TEMP_SIZE;
+ zfs_temp_ptr = zfs_temp_buf;
+ dnode_cache_buf = malloc(SPA_MAXBLOCKSIZE);
+ zap_scratch = malloc(SPA_MAXBLOCKSIZE);
+
+ zfs_init_crc();
+}
+
+static void *
+zfs_alloc(size_t size)
+{
+ char *ptr;
+
+ if (zfs_temp_ptr + size > zfs_temp_end) {
+ printf("ZFS: out of temporary buffer space\n");
+ for (;;) ;
+ }
+ ptr = zfs_temp_ptr;
+ zfs_temp_ptr += size;
+
+ return (ptr);
+}
+
+static void
+zfs_free(void *ptr, size_t size)
+{
+
+ zfs_temp_ptr -= size;
+ if (zfs_temp_ptr != ptr) {
+ printf("ZFS: zfs_alloc()/zfs_free() mismatch\n");
+ for (;;) ;
+ }
+}
+
+static int
+xdr_int(const unsigned char **xdr, int *ip)
+{
+ *ip = ((*xdr)[0] << 24)
+ | ((*xdr)[1] << 16)
+ | ((*xdr)[2] << 8)
+ | ((*xdr)[3] << 0);
+ (*xdr) += 4;
+ return (0);
+}
+
+static int
+xdr_u_int(const unsigned char **xdr, u_int *ip)
+{
+ *ip = ((*xdr)[0] << 24)
+ | ((*xdr)[1] << 16)
+ | ((*xdr)[2] << 8)
+ | ((*xdr)[3] << 0);
+ (*xdr) += 4;
+ return (0);
+}
+
+static int
+xdr_uint64_t(const unsigned char **xdr, uint64_t *lp)
+{
+ u_int hi, lo;
+
+ xdr_u_int(xdr, &hi);
+ xdr_u_int(xdr, &lo);
+ *lp = (((uint64_t) hi) << 32) | lo;
+ return (0);
+}
+
+static int
+nvlist_find(const unsigned char *nvlist, const char *name, int type,
+ int* elementsp, void *valuep)
+{
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ int namelen, pairtype, elements;
+ const char *pairname;
+
+ xdr_int(&p, &namelen);
+ pairname = (const char*) p;
+ p += roundup(namelen, 4);
+ xdr_int(&p, &pairtype);
+
+ if (!memcmp(name, pairname, namelen) && type == pairtype) {
+ xdr_int(&p, &elements);
+ if (elementsp)
+ *elementsp = elements;
+ if (type == DATA_TYPE_UINT64) {
+ xdr_uint64_t(&p, (uint64_t *) valuep);
+ return (0);
+ } else if (type == DATA_TYPE_STRING) {
+ int len;
+ xdr_int(&p, &len);
+ (*(const char**) valuep) = (const char*) p;
+ return (0);
+ } else if (type == DATA_TYPE_NVLIST
+ || type == DATA_TYPE_NVLIST_ARRAY) {
+ (*(const unsigned char**) valuep) =
+ (const unsigned char*) p;
+ return (0);
+ } else {
+ return (EIO);
+ }
+ } else {
+ /*
+ * Not the pair we are looking for, skip to the next one.
+ */
+ p = pair + encoded_size;
+ }
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return (EIO);
+}
+
+static int
+nvlist_check_features_for_read(const unsigned char *nvlist)
+{
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+ int rc;
+
+ rc = 0;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ int namelen, pairtype;
+ const char *pairname;
+ int i, found;
+
+ found = 0;
+
+ xdr_int(&p, &namelen);
+ pairname = (const char*) p;
+ p += roundup(namelen, 4);
+ xdr_int(&p, &pairtype);
+
+ for (i = 0; features_for_read[i] != NULL; i++) {
+ if (!memcmp(pairname, features_for_read[i], namelen)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("ZFS: unsupported feature: %s\n", pairname);
+ rc = EIO;
+ }
+
+ p = pair + encoded_size;
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return (rc);
+}
+
+/*
+ * Return the next nvlist in an nvlist array.
+ */
+static const unsigned char *
+nvlist_next(const unsigned char *nvlist)
+{
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ p = pair + encoded_size;
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return p;
+}
+
+#ifdef TEST
+
+static const unsigned char *
+nvlist_print(const unsigned char *nvlist, unsigned int indent)
+{
+ static const char* typenames[] = {
+ "DATA_TYPE_UNKNOWN",
+ "DATA_TYPE_BOOLEAN",
+ "DATA_TYPE_BYTE",
+ "DATA_TYPE_INT16",
+ "DATA_TYPE_UINT16",
+ "DATA_TYPE_INT32",
+ "DATA_TYPE_UINT32",
+ "DATA_TYPE_INT64",
+ "DATA_TYPE_UINT64",
+ "DATA_TYPE_STRING",
+ "DATA_TYPE_BYTE_ARRAY",
+ "DATA_TYPE_INT16_ARRAY",
+ "DATA_TYPE_UINT16_ARRAY",
+ "DATA_TYPE_INT32_ARRAY",
+ "DATA_TYPE_UINT32_ARRAY",
+ "DATA_TYPE_INT64_ARRAY",
+ "DATA_TYPE_UINT64_ARRAY",
+ "DATA_TYPE_STRING_ARRAY",
+ "DATA_TYPE_HRTIME",
+ "DATA_TYPE_NVLIST",
+ "DATA_TYPE_NVLIST_ARRAY",
+ "DATA_TYPE_BOOLEAN_VALUE",
+ "DATA_TYPE_INT8",
+ "DATA_TYPE_UINT8",
+ "DATA_TYPE_BOOLEAN_ARRAY",
+ "DATA_TYPE_INT8_ARRAY",
+ "DATA_TYPE_UINT8_ARRAY"
+ };
+
+ unsigned int i, j;
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ int namelen, pairtype, elements;
+ const char *pairname;
+
+ xdr_int(&p, &namelen);
+ pairname = (const char*) p;
+ p += roundup(namelen, 4);
+ xdr_int(&p, &pairtype);
+
+ for (i = 0; i < indent; i++)
+ printf(" ");
+ printf("%s %s", typenames[pairtype], pairname);
+
+ xdr_int(&p, &elements);
+ switch (pairtype) {
+ case DATA_TYPE_UINT64: {
+ uint64_t val;
+ xdr_uint64_t(&p, &val);
+ printf(" = 0x%jx\n", (uintmax_t)val);
+ break;
+ }
+
+ case DATA_TYPE_STRING: {
+ int len;
+ xdr_int(&p, &len);
+ printf(" = \"%s\"\n", p);
+ break;
+ }
+
+ case DATA_TYPE_NVLIST:
+ printf("\n");
+ nvlist_print(p, indent + 1);
+ break;
+
+ case DATA_TYPE_NVLIST_ARRAY:
+ for (j = 0; j < elements; j++) {
+ printf("[%d]\n", j);
+ p = nvlist_print(p, indent + 1);
+ if (j != elements - 1) {
+ for (i = 0; i < indent; i++)
+ printf(" ");
+ printf("%s %s", typenames[pairtype], pairname);
+ }
+ }
+ break;
+
+ default:
+ printf("\n");
+ }
+
+ p = pair + encoded_size;
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return p;
+}
+
+#endif
+
+static int
+vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf,
+ off_t offset, size_t size)
+{
+ size_t psize;
+ int rc;
+
+ if (!vdev->v_phys_read)
+ return (EIO);
+
+ if (bp) {
+ psize = BP_GET_PSIZE(bp);
+ } else {
+ psize = size;
+ }
+
+ /*printf("ZFS: reading %d bytes at 0x%jx to %p\n", psize, (uintmax_t)offset, buf);*/
+ rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize);
+ if (rc)
+ return (rc);
+ if (bp && zio_checksum_verify(bp, buf))
+ return (EIO);
+
+ return (0);
+}
+
+static int
+vdev_disk_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
+ off_t offset, size_t bytes)
+{
+
+ return (vdev_read_phys(vdev, bp, buf,
+ offset + VDEV_LABEL_START_SIZE, bytes));
+}
+
+
+static int
+vdev_mirror_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
+ off_t offset, size_t bytes)
+{
+ vdev_t *kid;
+ int rc;
+
+ rc = EIO;
+ STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) {
+ if (kid->v_state != VDEV_STATE_HEALTHY)
+ continue;
+ rc = kid->v_read(kid, bp, buf, offset, bytes);
+ if (!rc)
+ return (0);
+ }
+
+ return (rc);
+}
+
+static int
+vdev_replacing_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
+ off_t offset, size_t bytes)
+{
+ vdev_t *kid;
+
+ /*
+ * Here we should have two kids:
+ * First one which is the one we are replacing and we can trust
+ * only this one to have valid data, but it might not be present.
+ * Second one is that one we are replacing with. It is most likely
+ * healthy, but we can't trust it has needed data, so we won't use it.
+ */
+ kid = STAILQ_FIRST(&vdev->v_children);
+ if (kid == NULL)
+ return (EIO);
+ if (kid->v_state != VDEV_STATE_HEALTHY)
+ return (EIO);
+ return (kid->v_read(kid, bp, buf, offset, bytes));
+}
+
+static vdev_t *
+vdev_find(uint64_t guid)
+{
+ vdev_t *vdev;
+
+ STAILQ_FOREACH(vdev, &zfs_vdevs, v_alllink)
+ if (vdev->v_guid == guid)
+ return (vdev);
+
+ return (0);
+}
+
+static vdev_t *
+vdev_create(uint64_t guid, vdev_read_t *vdev_read)
+{
+ vdev_t *vdev;
+
+ vdev = malloc(sizeof(vdev_t));
+ memset(vdev, 0, sizeof(vdev_t));
+ STAILQ_INIT(&vdev->v_children);
+ vdev->v_guid = guid;
+ vdev->v_state = VDEV_STATE_OFFLINE;
+ vdev->v_read = vdev_read;
+ vdev->v_phys_read = 0;
+ vdev->v_read_priv = 0;
+ STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink);
+
+ return (vdev);
+}
+
+static int
+vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
+ vdev_t **vdevp, int is_newer)
+{
+ int rc;
+ uint64_t guid, id, ashift, nparity;
+ const char *type;
+ const char *path;
+ vdev_t *vdev, *kid;
+ const unsigned char *kids;
+ int nkids, i, is_new;
+ uint64_t is_offline, is_faulted, is_degraded, is_removed, isnt_present;
+
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID,
+ DATA_TYPE_UINT64, 0, &guid)
+ || nvlist_find(nvlist, ZPOOL_CONFIG_ID,
+ DATA_TYPE_UINT64, 0, &id)
+ || nvlist_find(nvlist, ZPOOL_CONFIG_TYPE,
+ DATA_TYPE_STRING, 0, &type)) {
+ printf("ZFS: can't find vdev details\n");
+ return (ENOENT);
+ }
+
+ if (strcmp(type, VDEV_TYPE_MIRROR)
+ && strcmp(type, VDEV_TYPE_DISK)
+#ifdef ZFS_TEST
+ && strcmp(type, VDEV_TYPE_FILE)
+#endif
+ && strcmp(type, VDEV_TYPE_RAIDZ)
+ && strcmp(type, VDEV_TYPE_REPLACING)) {
+ printf("ZFS: can only boot from disk, mirror, raidz1, raidz2 and raidz3 vdevs\n");
+ return (EIO);
+ }
+
+ is_offline = is_removed = is_faulted = is_degraded = isnt_present = 0;
+
+ nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, 0,
+ &is_offline);
+ nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, 0,
+ &is_removed);
+ nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, 0,
+ &is_faulted);
+ nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, 0,
+ &is_degraded);
+ nvlist_find(nvlist, ZPOOL_CONFIG_NOT_PRESENT, DATA_TYPE_UINT64, 0,
+ &isnt_present);
+
+ vdev = vdev_find(guid);
+ if (!vdev) {
+ is_new = 1;
+
+ if (!strcmp(type, VDEV_TYPE_MIRROR))
+ vdev = vdev_create(guid, vdev_mirror_read);
+ else if (!strcmp(type, VDEV_TYPE_RAIDZ))
+ vdev = vdev_create(guid, vdev_raidz_read);
+ else if (!strcmp(type, VDEV_TYPE_REPLACING))
+ vdev = vdev_create(guid, vdev_replacing_read);
+ else
+ vdev = vdev_create(guid, vdev_disk_read);
+
+ vdev->v_id = id;
+ vdev->v_top = pvdev != NULL ? pvdev : vdev;
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT,
+ DATA_TYPE_UINT64, 0, &ashift) == 0)
+ vdev->v_ashift = ashift;
+ else
+ vdev->v_ashift = 0;
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
+ DATA_TYPE_UINT64, 0, &nparity) == 0)
+ vdev->v_nparity = nparity;
+ else
+ vdev->v_nparity = 0;
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH,
+ DATA_TYPE_STRING, 0, &path) == 0) {
+ if (strncmp(path, "/dev/dsk/", 9) == 0)
+ path += 9;
+ vdev->v_name = strdup(path);
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_PHYS_PATH,
+ DATA_TYPE_STRING, 0, &path) == 0)
+ vdev->v_phys_path = strdup(path);
+ else
+ vdev->v_phys_path = NULL;
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_DEVID,
+ DATA_TYPE_STRING, 0, &path) == 0)
+ vdev->v_devid = strdup(path);
+ else
+ vdev->v_devid = NULL;
+ } else {
+ if (!strcmp(type, "raidz")) {
+ if (vdev->v_nparity == 1)
+ vdev->v_name = "raidz1";
+ else if (vdev->v_nparity == 2)
+ vdev->v_name = "raidz2";
+ else if (vdev->v_nparity == 3)
+ vdev->v_name = "raidz3";
+ else {
+ printf("ZFS: can only boot from disk, mirror, raidz1, raidz2 and raidz3 vdevs\n");
+ return (EIO);
+ }
+ } else {
+ vdev->v_name = strdup(type);
+ }
+ }
+ } else {
+ is_new = 0;
+ }
+
+ if (is_new || is_newer) {
+ /*
+ * This is either new vdev or we've already seen this vdev,
+ * but from an older vdev label, so let's refresh its state
+ * from the newer label.
+ */
+ if (is_offline)
+ vdev->v_state = VDEV_STATE_OFFLINE;
+ else if (is_removed)
+ vdev->v_state = VDEV_STATE_REMOVED;
+ else if (is_faulted)
+ vdev->v_state = VDEV_STATE_FAULTED;
+ else if (is_degraded)
+ vdev->v_state = VDEV_STATE_DEGRADED;
+ else if (isnt_present)
+ vdev->v_state = VDEV_STATE_CANT_OPEN;
+ }
+
+ rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN,
+ DATA_TYPE_NVLIST_ARRAY, &nkids, &kids);
+ /*
+ * Its ok if we don't have any kids.
+ */
+ if (rc == 0) {
+ vdev->v_nchildren = nkids;
+ for (i = 0; i < nkids; i++) {
+ rc = vdev_init_from_nvlist(kids, vdev, &kid, is_newer);
+ if (rc)
+ return (rc);
+ if (is_new)
+ STAILQ_INSERT_TAIL(&vdev->v_children, kid,
+ v_childlink);
+ kids = nvlist_next(kids);
+ }
+ } else {
+ vdev->v_nchildren = 0;
+ }
+
+ if (vdevp)
+ *vdevp = vdev;
+ return (0);
+}
+
+static void
+vdev_set_state(vdev_t *vdev)
+{
+ vdev_t *kid;
+ int good_kids;
+ int bad_kids;
+
+ /*
+ * A mirror or raidz is healthy if all its kids are healthy. A
+ * mirror is degraded if any of its kids is healthy; a raidz
+ * is degraded if at most nparity kids are offline.
+ */
+ if (STAILQ_FIRST(&vdev->v_children)) {
+ good_kids = 0;
+ bad_kids = 0;
+ STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) {
+ if (kid->v_state == VDEV_STATE_HEALTHY)
+ good_kids++;
+ else
+ bad_kids++;
+ }
+ if (bad_kids == 0) {
+ vdev->v_state = VDEV_STATE_HEALTHY;
+ } else {
+ if (vdev->v_read == vdev_mirror_read) {
+ if (good_kids) {
+ vdev->v_state = VDEV_STATE_DEGRADED;
+ } else {
+ vdev->v_state = VDEV_STATE_OFFLINE;
+ }
+ } else if (vdev->v_read == vdev_raidz_read) {
+ if (bad_kids > vdev->v_nparity) {
+ vdev->v_state = VDEV_STATE_OFFLINE;
+ } else {
+ vdev->v_state = VDEV_STATE_DEGRADED;
+ }
+ }
+ }
+ }
+}
+
+static spa_t *
+spa_find_by_guid(uint64_t guid)
+{
+ spa_t *spa;
+
+ STAILQ_FOREACH(spa, &zfs_pools, spa_link)
+ if (spa->spa_guid == guid)
+ return (spa);
+
+ return (0);
+}
+
+static spa_t *
+spa_find_by_name(const char *name)
+{
+ spa_t *spa;
+
+ STAILQ_FOREACH(spa, &zfs_pools, spa_link)
+ if (!strcmp(spa->spa_name, name))
+ return (spa);
+
+ return (0);
+}
+
+spa_t *
+spa_get_primary(void)
+{
+ return (STAILQ_FIRST(&zfs_pools));
+}
+
+vdev_t *
+spa_get_primary_vdev(const spa_t *spa)
+{
+ vdev_t *vdev;
+ vdev_t *kid;
+
+ if (spa == NULL)
+ spa = spa_get_primary();
+ if (spa == NULL)
+ return (NULL);
+ vdev = STAILQ_FIRST(&spa->spa_vdevs);
+ if (vdev == NULL)
+ return (NULL);
+ for (kid = STAILQ_FIRST(&vdev->v_children); kid != NULL;
+ kid = STAILQ_FIRST(&vdev->v_children))
+ vdev = kid;
+ return (vdev);
+}
+
+static spa_t *
+spa_create(uint64_t guid)
+{
+ spa_t *spa;
+
+ spa = malloc(sizeof(spa_t));
+ memset(spa, 0, sizeof(spa_t));
+ STAILQ_INIT(&spa->spa_vdevs);
+ spa->spa_guid = guid;
+ STAILQ_INSERT_TAIL(&zfs_pools, spa, spa_link);
+
+ return (spa);
+}
+
+static const char *
+state_name(vdev_state_t state)
+{
+ static const char* names[] = {
+ "UNKNOWN",
+ "CLOSED",
+ "OFFLINE",
+ "REMOVED",
+ "CANT_OPEN",
+ "FAULTED",
+ "DEGRADED",
+ "ONLINE"
+ };
+ return names[state];
+}
+
+static int
+pager_printf(const char *fmt, ...)
+{
+ char line[80];
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(line, sizeof (line), fmt, args);
+ va_end(args);
+ return (pager_output(line));
+}
+
+#define STATUS_FORMAT " %s %s\n"
+
+static int
+print_state(int indent, const char *name, vdev_state_t state)
+{
+ int i;
+ char buf[512];
+
+ buf[0] = 0;
+ for (i = 0; i < indent; i++)
+ strcat(buf, " ");
+ strcat(buf, name);
+ return (pager_printf(STATUS_FORMAT, buf, state_name(state)));
+}
+
+static int
+vdev_status(vdev_t *vdev, int indent)
+{
+ vdev_t *kid;
+ int ret;
+ ret = print_state(indent, vdev->v_name, vdev->v_state);
+ if (ret != 0)
+ return (ret);
+
+ STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) {
+ ret = vdev_status(kid, indent + 1);
+ if (ret != 0)
+ return (ret);
+ }
+ return (ret);
+}
+
+static int
+spa_status(spa_t *spa)
+{
+ static char bootfs[ZFS_MAXNAMELEN];
+ uint64_t rootid;
+ vdev_t *vdev;
+ int good_kids, bad_kids, degraded_kids, ret;
+ vdev_state_t state;
+
+ ret = pager_printf(" pool: %s\n", spa->spa_name);
+ if (ret != 0)
+ return (ret);
+
+ if (zfs_get_root(spa, &rootid) == 0 &&
+ zfs_rlookup(spa, rootid, bootfs) == 0) {
+ if (bootfs[0] == '\0')
+ ret = pager_printf("bootfs: %s\n", spa->spa_name);
+ else
+ ret = pager_printf("bootfs: %s/%s\n", spa->spa_name,
+ bootfs);
+ if (ret != 0)
+ return (ret);
+ }
+ ret = pager_printf("config:\n\n");
+ if (ret != 0)
+ return (ret);
+ ret = pager_printf(STATUS_FORMAT, "NAME", "STATE");
+ if (ret != 0)
+ return (ret);
+
+ good_kids = 0;
+ degraded_kids = 0;
+ bad_kids = 0;
+ STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) {
+ if (vdev->v_state == VDEV_STATE_HEALTHY)
+ good_kids++;
+ else if (vdev->v_state == VDEV_STATE_DEGRADED)
+ degraded_kids++;
+ else
+ bad_kids++;
+ }
+
+ state = VDEV_STATE_CLOSED;
+ if (good_kids > 0 && (degraded_kids + bad_kids) == 0)
+ state = VDEV_STATE_HEALTHY;
+ else if ((good_kids + degraded_kids) > 0)
+ state = VDEV_STATE_DEGRADED;
+
+ ret = print_state(0, spa->spa_name, state);
+ if (ret != 0)
+ return (ret);
+ STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) {
+ ret = vdev_status(vdev, 1);
+ if (ret != 0)
+ return (ret);
+ }
+ return (ret);
+}
+
+int
+spa_all_status(void)
+{
+ spa_t *spa;
+ int first = 1, ret = 0;
+
+ STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
+ if (!first) {
+ ret = pager_printf("\n");
+ if (ret != 0)
+ return (ret);
+ }
+ first = 0;
+ ret = spa_status(spa);
+ if (ret != 0)
+ return (ret);
+ }
+ return (ret);
+}
+
+static int
+vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
+{
+ vdev_t vtmp;
+ vdev_phys_t *vdev_label = (vdev_phys_t *) zap_scratch;
+ spa_t *spa;
+ vdev_t *vdev, *top_vdev, *pool_vdev;
+ off_t off;
+ blkptr_t bp;
+ const unsigned char *nvlist;
+ uint64_t val;
+ uint64_t guid;
+ uint64_t pool_txg, pool_guid;
+ uint64_t is_log;
+ const char *pool_name;
+ const unsigned char *vdevs;
+ const unsigned char *features;
+ int i, rc, is_newer;
+ char *upbuf;
+ const struct uberblock *up;
+
+ /*
+ * Load the vdev label and figure out which
+ * uberblock is most current.
+ */
+ memset(&vtmp, 0, sizeof(vtmp));
+ vtmp.v_phys_read = phys_read;
+ vtmp.v_read_priv = read_priv;
+ off = offsetof(vdev_label_t, vl_vdev_phys);
+ BP_ZERO(&bp);
+ BP_SET_LSIZE(&bp, sizeof(vdev_phys_t));
+ BP_SET_PSIZE(&bp, sizeof(vdev_phys_t));
+ BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
+ BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
+ DVA_SET_OFFSET(BP_IDENTITY(&bp), off);
+ ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
+ if (vdev_read_phys(&vtmp, &bp, vdev_label, off, 0))
+ return (EIO);
+
+ if (vdev_label->vp_nvlist[0] != NV_ENCODE_XDR) {
+ return (EIO);
+ }
+
+ nvlist = (const unsigned char *) vdev_label->vp_nvlist + 4;
+
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_VERSION,
+ DATA_TYPE_UINT64, 0, &val)) {
+ return (EIO);
+ }
+
+ if (!SPA_VERSION_IS_SUPPORTED(val)) {
+ printf("ZFS: unsupported ZFS version %u (should be %u)\n",
+ (unsigned) val, (unsigned) SPA_VERSION);
+ return (EIO);
+ }
+
+ /* Check ZFS features for read */
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_FEATURES_FOR_READ,
+ DATA_TYPE_NVLIST, 0, &features) == 0
+ && nvlist_check_features_for_read(features) != 0)
+ return (EIO);
+
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_POOL_STATE,
+ DATA_TYPE_UINT64, 0, &val)) {
+ return (EIO);
+ }
+
+ if (val == POOL_STATE_DESTROYED) {
+ /* We don't boot only from destroyed pools. */
+ return (EIO);
+ }
+
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_POOL_TXG,
+ DATA_TYPE_UINT64, 0, &pool_txg)
+ || nvlist_find(nvlist,
+ ZPOOL_CONFIG_POOL_GUID,
+ DATA_TYPE_UINT64, 0, &pool_guid)
+ || nvlist_find(nvlist,
+ ZPOOL_CONFIG_POOL_NAME,
+ DATA_TYPE_STRING, 0, &pool_name)) {
+ /*
+ * Cache and spare devices end up here - just ignore
+ * them.
+ */
+ /*printf("ZFS: can't find pool details\n");*/
+ return (EIO);
+ }
+
+ is_log = 0;
+ (void) nvlist_find(nvlist, ZPOOL_CONFIG_IS_LOG, DATA_TYPE_UINT64, 0,
+ &is_log);
+ if (is_log)
+ return (EIO);
+
+ /*
+ * Create the pool if this is the first time we've seen it.
+ */
+ spa = spa_find_by_guid(pool_guid);
+ if (!spa) {
+ spa = spa_create(pool_guid);
+ spa->spa_name = strdup(pool_name);
+ }
+ if (pool_txg > spa->spa_txg) {
+ spa->spa_txg = pool_txg;
+ is_newer = 1;
+ } else
+ is_newer = 0;
+
+ /*
+ * Get the vdev tree and create our in-core copy of it.
+ * If we already have a vdev with this guid, this must
+ * be some kind of alias (overlapping slices, dangerously dedicated
+ * disks etc).
+ */
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_GUID,
+ DATA_TYPE_UINT64, 0, &guid)) {
+ return (EIO);
+ }
+ vdev = vdev_find(guid);
+ if (vdev && vdev->v_phys_read) /* Has this vdev already been inited? */
+ return (EIO);
+
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_VDEV_TREE,
+ DATA_TYPE_NVLIST, 0, &vdevs)) {
+ return (EIO);
+ }
+
+ rc = vdev_init_from_nvlist(vdevs, NULL, &top_vdev, is_newer);
+ if (rc)
+ return (rc);
+
+ /*
+ * Add the toplevel vdev to the pool if its not already there.
+ */
+ STAILQ_FOREACH(pool_vdev, &spa->spa_vdevs, v_childlink)
+ if (top_vdev == pool_vdev)
+ break;
+ if (!pool_vdev && top_vdev)
+ STAILQ_INSERT_TAIL(&spa->spa_vdevs, top_vdev, v_childlink);
+
+ /*
+ * We should already have created an incomplete vdev for this
+ * vdev. Find it and initialise it with our read proc.
+ */
+ vdev = vdev_find(guid);
+ if (vdev) {
+ vdev->v_phys_read = phys_read;
+ vdev->v_read_priv = read_priv;
+ vdev->v_state = VDEV_STATE_HEALTHY;
+ } else {
+ printf("ZFS: inconsistent nvlist contents\n");
+ return (EIO);
+ }
+
+ /*
+ * Re-evaluate top-level vdev state.
+ */
+ vdev_set_state(top_vdev);
+
+ /*
+ * Ok, we are happy with the pool so far. Lets find
+ * the best uberblock and then we can actually access
+ * the contents of the pool.
+ */
+ upbuf = zfs_alloc(VDEV_UBERBLOCK_SIZE(vdev));
+ up = (const struct uberblock *)upbuf;
+ for (i = 0;
+ i < VDEV_UBERBLOCK_COUNT(vdev);
+ i++) {
+ off = VDEV_UBERBLOCK_OFFSET(vdev, i);
+ BP_ZERO(&bp);
+ DVA_SET_OFFSET(&bp.blk_dva[0], off);
+ BP_SET_LSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
+ BP_SET_PSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
+ BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
+ BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
+ ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
+
+ if (vdev_read_phys(vdev, &bp, upbuf, off, 0))
+ continue;
+
+ if (up->ub_magic != UBERBLOCK_MAGIC)
+ continue;
+ if (up->ub_txg < spa->spa_txg)
+ continue;
+ if (up->ub_txg > spa->spa_uberblock.ub_txg) {
+ spa->spa_uberblock = *up;
+ } else if (up->ub_txg == spa->spa_uberblock.ub_txg) {
+ if (up->ub_timestamp > spa->spa_uberblock.ub_timestamp)
+ spa->spa_uberblock = *up;
+ }
+ }
+ zfs_free(upbuf, VDEV_UBERBLOCK_SIZE(vdev));
+
+ if (spap)
+ *spap = spa;
+ return (0);
+}
+
+static int
+ilog2(int n)
+{
+ int v;
+
+ for (v = 0; v < 32; v++)
+ if (n == (1 << v))
+ return v;
+ return -1;
+}
+
+static int
+zio_read_gang(const spa_t *spa, const blkptr_t *bp, void *buf)
+{
+ blkptr_t gbh_bp;
+ zio_gbh_phys_t zio_gb;
+ char *pbuf;
+ int i;
+
+ /* Artificial BP for gang block header. */
+ gbh_bp = *bp;
+ BP_SET_PSIZE(&gbh_bp, SPA_GANGBLOCKSIZE);
+ BP_SET_LSIZE(&gbh_bp, SPA_GANGBLOCKSIZE);
+ BP_SET_CHECKSUM(&gbh_bp, ZIO_CHECKSUM_GANG_HEADER);
+ BP_SET_COMPRESS(&gbh_bp, ZIO_COMPRESS_OFF);
+ for (i = 0; i < SPA_DVAS_PER_BP; i++)
+ DVA_SET_GANG(&gbh_bp.blk_dva[i], 0);
+
+ /* Read gang header block using the artificial BP. */
+ if (zio_read(spa, &gbh_bp, &zio_gb))
+ return (EIO);
+
+ pbuf = buf;
+ for (i = 0; i < SPA_GBH_NBLKPTRS; i++) {
+ blkptr_t *gbp = &zio_gb.zg_blkptr[i];
+
+ if (BP_IS_HOLE(gbp))
+ continue;
+ if (zio_read(spa, gbp, pbuf))
+ return (EIO);
+ pbuf += BP_GET_PSIZE(gbp);
+ }
+
+ if (zio_checksum_verify(bp, buf))
+ return (EIO);
+ return (0);
+}
+
+static int
+zio_read(const spa_t *spa, const blkptr_t *bp, void *buf)
+{
+ int cpfunc = BP_GET_COMPRESS(bp);
+ uint64_t align, size;
+ void *pbuf;
+ int i, error;
+
+ /*
+ * Process data embedded in block pointer
+ */
+ if (BP_IS_EMBEDDED(bp)) {
+ ASSERT(BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA);
+
+ size = BPE_GET_PSIZE(bp);
+ ASSERT(size <= BPE_PAYLOAD_SIZE);
+
+ if (cpfunc != ZIO_COMPRESS_OFF)
+ pbuf = zfs_alloc(size);
+ else
+ pbuf = buf;
+
+ decode_embedded_bp_compressed(bp, pbuf);
+ error = 0;
+
+ if (cpfunc != ZIO_COMPRESS_OFF) {
+ error = zio_decompress_data(cpfunc, pbuf,
+ size, buf, BP_GET_LSIZE(bp));
+ zfs_free(pbuf, size);
+ }
+ if (error != 0)
+ printf("ZFS: i/o error - unable to decompress block pointer data, error %d\n",
+ error);
+ return (error);
+ }
+
+ error = EIO;
+
+ for (i = 0; i < SPA_DVAS_PER_BP; i++) {
+ const dva_t *dva = &bp->blk_dva[i];
+ vdev_t *vdev;
+ int vdevid;
+ off_t offset;
+
+ if (!dva->dva_word[0] && !dva->dva_word[1])
+ continue;
+
+ vdevid = DVA_GET_VDEV(dva);
+ offset = DVA_GET_OFFSET(dva);
+ STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) {
+ if (vdev->v_id == vdevid)
+ break;
+ }
+ if (!vdev || !vdev->v_read)
+ continue;
+
+ size = BP_GET_PSIZE(bp);
+ if (vdev->v_read == vdev_raidz_read) {
+ align = 1ULL << vdev->v_top->v_ashift;
+ if (P2PHASE(size, align) != 0)
+ size = P2ROUNDUP(size, align);
+ }
+ if (size != BP_GET_PSIZE(bp) || cpfunc != ZIO_COMPRESS_OFF)
+ pbuf = zfs_alloc(size);
+ else
+ pbuf = buf;
+
+ if (DVA_GET_GANG(dva))
+ error = zio_read_gang(spa, bp, pbuf);
+ else
+ error = vdev->v_read(vdev, bp, pbuf, offset, size);
+ if (error == 0) {
+ if (cpfunc != ZIO_COMPRESS_OFF)
+ error = zio_decompress_data(cpfunc, pbuf,
+ BP_GET_PSIZE(bp), buf, BP_GET_LSIZE(bp));
+ else if (size != BP_GET_PSIZE(bp))
+ bcopy(pbuf, buf, BP_GET_PSIZE(bp));
+ }
+ if (buf != pbuf)
+ zfs_free(pbuf, size);
+ if (error == 0)
+ break;
+ }
+ if (error != 0)
+ printf("ZFS: i/o error - all block copies unavailable\n");
+ return (error);
+}
+
+static int
+dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf, size_t buflen)
+{
+ int ibshift = dnode->dn_indblkshift - SPA_BLKPTRSHIFT;
+ int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ int nlevels = dnode->dn_nlevels;
+ int i, rc;
+
+ if (bsize > SPA_MAXBLOCKSIZE) {
+ printf("ZFS: I/O error - blocks larger than %llu are not "
+ "supported\n", SPA_MAXBLOCKSIZE);
+ return (EIO);
+ }
+
+ /*
+ * Note: bsize may not be a power of two here so we need to do an
+ * actual divide rather than a bitshift.
+ */
+ while (buflen > 0) {
+ uint64_t bn = offset / bsize;
+ int boff = offset % bsize;
+ int ibn;
+ const blkptr_t *indbp;
+ blkptr_t bp;
+
+ if (bn > dnode->dn_maxblkid) {
+ printf("warning: zfs bug: bn %llx > dn_maxblkid %llx\n",
+ (unsigned long long)bn,
+ (unsigned long long)dnode->dn_maxblkid);
+ /*
+ * zfs bug, will not return error
+ * return (EIO);
+ */
+ }
+
+ if (dnode == dnode_cache_obj && bn == dnode_cache_bn)
+ goto cached;
+
+ indbp = dnode->dn_blkptr;
+ for (i = 0; i < nlevels; i++) {
+ /*
+ * Copy the bp from the indirect array so that
+ * we can re-use the scratch buffer for multi-level
+ * objects.
+ */
+ ibn = bn >> ((nlevels - i - 1) * ibshift);
+ ibn &= ((1 << ibshift) - 1);
+ bp = indbp[ibn];
+ if (BP_IS_HOLE(&bp)) {
+ memset(dnode_cache_buf, 0, bsize);
+ break;
+ }
+ rc = zio_read(spa, &bp, dnode_cache_buf);
+ if (rc)
+ return (rc);
+ indbp = (const blkptr_t *) dnode_cache_buf;
+ }
+ dnode_cache_obj = dnode;
+ dnode_cache_bn = bn;
+ cached:
+
+ /*
+ * The buffer contains our data block. Copy what we
+ * need from it and loop.
+ */
+ i = bsize - boff;
+ if (i > buflen) i = buflen;
+ memcpy(buf, &dnode_cache_buf[boff], i);
+ buf = ((char*) buf) + i;
+ offset += i;
+ buflen -= i;
+ }
+
+ return (0);
+}
+
+/*
+ * Lookup a value in a microzap directory. Assumes that the zap
+ * scratch buffer contains the directory contents.
+ */
+static int
+mzap_lookup(const dnode_phys_t *dnode, const char *name, uint64_t *value)
+{
+ const mzap_phys_t *mz;
+ const mzap_ent_phys_t *mze;
+ size_t size;
+ int chunks, i;
+
+ /*
+ * Microzap objects use exactly one block. Read the whole
+ * thing.
+ */
+ size = dnode->dn_datablkszsec * 512;
+
+ mz = (const mzap_phys_t *) zap_scratch;
+ chunks = size / MZAP_ENT_LEN - 1;
+
+ for (i = 0; i < chunks; i++) {
+ mze = &mz->mz_chunk[i];
+ if (!strcmp(mze->mze_name, name)) {
+ *value = mze->mze_value;
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+/*
+ * Compare a name with a zap leaf entry. Return non-zero if the name
+ * matches.
+ */
+static int
+fzap_name_equal(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, const char *name)
+{
+ size_t namelen;
+ const zap_leaf_chunk_t *nc;
+ const char *p;
+
+ namelen = zc->l_entry.le_name_numints;
+
+ nc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_name_chunk);
+ p = name;
+ while (namelen > 0) {
+ size_t len;
+ len = namelen;
+ if (len > ZAP_LEAF_ARRAY_BYTES)
+ len = ZAP_LEAF_ARRAY_BYTES;
+ if (memcmp(p, nc->l_array.la_array, len))
+ return (0);
+ p += len;
+ namelen -= len;
+ nc = &ZAP_LEAF_CHUNK(zl, nc->l_array.la_next);
+ }
+
+ return 1;
+}
+
+/*
+ * Extract a uint64_t value from a zap leaf entry.
+ */
+static uint64_t
+fzap_leaf_value(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc)
+{
+ const zap_leaf_chunk_t *vc;
+ int i;
+ uint64_t value;
+ const uint8_t *p;
+
+ vc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_value_chunk);
+ for (i = 0, value = 0, p = vc->l_array.la_array; i < 8; i++) {
+ value = (value << 8) | p[i];
+ }
+
+ return value;
+}
+
+/*
+ * Lookup a value in a fatzap directory. Assumes that the zap scratch
+ * buffer contains the directory header.
+ */
+static int
+fzap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+{
+ int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ zap_phys_t zh = *(zap_phys_t *) zap_scratch;
+ fat_zap_t z;
+ uint64_t *ptrtbl;
+ uint64_t hash;
+ int rc;
+
+ if (zh.zap_magic != ZAP_MAGIC)
+ return (EIO);
+
+ z.zap_block_shift = ilog2(bsize);
+ z.zap_phys = (zap_phys_t *) zap_scratch;
+
+ /*
+ * Figure out where the pointer table is and read it in if necessary.
+ */
+ if (zh.zap_ptrtbl.zt_blk) {
+ rc = dnode_read(spa, dnode, zh.zap_ptrtbl.zt_blk * bsize,
+ zap_scratch, bsize);
+ if (rc)
+ return (rc);
+ ptrtbl = (uint64_t *) zap_scratch;
+ } else {
+ ptrtbl = &ZAP_EMBEDDED_PTRTBL_ENT(&z, 0);
+ }
+
+ hash = zap_hash(zh.zap_salt, name);
+
+ zap_leaf_t zl;
+ zl.l_bs = z.zap_block_shift;
+
+ off_t off = ptrtbl[hash >> (64 - zh.zap_ptrtbl.zt_shift)] << zl.l_bs;
+ zap_leaf_chunk_t *zc;
+
+ rc = dnode_read(spa, dnode, off, zap_scratch, bsize);
+ if (rc)
+ return (rc);
+
+ zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
+
+ /*
+ * Make sure this chunk matches our hash.
+ */
+ if (zl.l_phys->l_hdr.lh_prefix_len > 0
+ && zl.l_phys->l_hdr.lh_prefix
+ != hash >> (64 - zl.l_phys->l_hdr.lh_prefix_len))
+ return (ENOENT);
+
+ /*
+ * Hash within the chunk to find our entry.
+ */
+ int shift = (64 - ZAP_LEAF_HASH_SHIFT(&zl) - zl.l_phys->l_hdr.lh_prefix_len);
+ int h = (hash >> shift) & ((1 << ZAP_LEAF_HASH_SHIFT(&zl)) - 1);
+ h = zl.l_phys->l_hash[h];
+ if (h == 0xffff)
+ return (ENOENT);
+ zc = &ZAP_LEAF_CHUNK(&zl, h);
+ while (zc->l_entry.le_hash != hash) {
+ if (zc->l_entry.le_next == 0xffff) {
+ zc = 0;
+ break;
+ }
+ zc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_next);
+ }
+ if (fzap_name_equal(&zl, zc, name)) {
+ if (zc->l_entry.le_value_intlen * zc->l_entry.le_value_numints > 8)
+ return (E2BIG);
+ *value = fzap_leaf_value(&zl, zc);
+ return (0);
+ }
+
+ return (ENOENT);
+}
+
+/*
+ * Lookup a name in a zap object and return its value as a uint64_t.
+ */
+static int
+zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+{
+ int rc;
+ uint64_t zap_type;
+ size_t size = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+
+ rc = dnode_read(spa, dnode, 0, zap_scratch, size);
+ if (rc)
+ return (rc);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_lookup(dnode, name, value);
+ else if (zap_type == ZBT_HEADER)
+ return fzap_lookup(spa, dnode, name, value);
+ printf("ZFS: invalid zap_type=%d\n", (int)zap_type);
+ return (EIO);
+}
+
+/*
+ * List a microzap directory. Assumes that the zap scratch buffer contains
+ * the directory contents.
+ */
+static int
+mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *, uint64_t))
+{
+ const mzap_phys_t *mz;
+ const mzap_ent_phys_t *mze;
+ size_t size;
+ int chunks, i, rc;
+
+ /*
+ * Microzap objects use exactly one block. Read the whole
+ * thing.
+ */
+ size = dnode->dn_datablkszsec * 512;
+ mz = (const mzap_phys_t *) zap_scratch;
+ chunks = size / MZAP_ENT_LEN - 1;
+
+ for (i = 0; i < chunks; i++) {
+ mze = &mz->mz_chunk[i];
+ if (mze->mze_name[0]) {
+ rc = callback(mze->mze_name, mze->mze_value);
+ if (rc != 0)
+ return (rc);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * List a fatzap directory. Assumes that the zap scratch buffer contains
+ * the directory header.
+ */
+static int
+fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *, uint64_t))
+{
+ int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ zap_phys_t zh = *(zap_phys_t *) zap_scratch;
+ fat_zap_t z;
+ int i, j, rc;
+
+ if (zh.zap_magic != ZAP_MAGIC)
+ return (EIO);
+
+ z.zap_block_shift = ilog2(bsize);
+ z.zap_phys = (zap_phys_t *) zap_scratch;
+
+ /*
+ * This assumes that the leaf blocks start at block 1. The
+ * documentation isn't exactly clear on this.
+ */
+ zap_leaf_t zl;
+ zl.l_bs = z.zap_block_shift;
+ for (i = 0; i < zh.zap_num_leafs; i++) {
+ off_t off = (i + 1) << zl.l_bs;
+ char name[256], *p;
+ uint64_t value;
+
+ if (dnode_read(spa, dnode, off, zap_scratch, bsize))
+ return (EIO);
+
+ zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
+
+ for (j = 0; j < ZAP_LEAF_NUMCHUNKS(&zl); j++) {
+ zap_leaf_chunk_t *zc, *nc;
+ int namelen;
+
+ zc = &ZAP_LEAF_CHUNK(&zl, j);
+ if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
+ continue;
+ namelen = zc->l_entry.le_name_numints;
+ if (namelen > sizeof(name))
+ namelen = sizeof(name);
+
+ /*
+ * Paste the name back together.
+ */
+ nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk);
+ p = name;
+ while (namelen > 0) {
+ int len;
+ len = namelen;
+ if (len > ZAP_LEAF_ARRAY_BYTES)
+ len = ZAP_LEAF_ARRAY_BYTES;
+ memcpy(p, nc->l_array.la_array, len);
+ p += len;
+ namelen -= len;
+ nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next);
+ }
+
+ /*
+ * Assume the first eight bytes of the value are
+ * a uint64_t.
+ */
+ value = fzap_leaf_value(&zl, zc);
+
+ //printf("%s 0x%jx\n", name, (uintmax_t)value);
+ rc = callback((const char *)name, value);
+ if (rc != 0)
+ return (rc);
+ }
+ }
+
+ return (0);
+}
+
+static int zfs_printf(const char *name, uint64_t value __unused)
+{
+
+ printf("%s\n", name);
+
+ return (0);
+}
+
+/*
+ * List a zap directory.
+ */
+static int
+zap_list(const spa_t *spa, const dnode_phys_t *dnode)
+{
+ uint64_t zap_type;
+ size_t size = dnode->dn_datablkszsec * 512;
+
+ if (dnode_read(spa, dnode, 0, zap_scratch, size))
+ return (EIO);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_list(dnode, zfs_printf);
+ else
+ return fzap_list(spa, dnode, zfs_printf);
+}
+
+static int
+objset_get_dnode(const spa_t *spa, const objset_phys_t *os, uint64_t objnum, dnode_phys_t *dnode)
+{
+ off_t offset;
+
+ offset = objnum * sizeof(dnode_phys_t);
+ return dnode_read(spa, &os->os_meta_dnode, offset,
+ dnode, sizeof(dnode_phys_t));
+}
+
+static int
+mzap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ const mzap_phys_t *mz;
+ const mzap_ent_phys_t *mze;
+ size_t size;
+ int chunks, i;
+
+ /*
+ * Microzap objects use exactly one block. Read the whole
+ * thing.
+ */
+ size = dnode->dn_datablkszsec * 512;
+
+ mz = (const mzap_phys_t *) zap_scratch;
+ chunks = size / MZAP_ENT_LEN - 1;
+
+ for (i = 0; i < chunks; i++) {
+ mze = &mz->mz_chunk[i];
+ if (value == mze->mze_value) {
+ strcpy(name, mze->mze_name);
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+static void
+fzap_name_copy(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, char *name)
+{
+ size_t namelen;
+ const zap_leaf_chunk_t *nc;
+ char *p;
+
+ namelen = zc->l_entry.le_name_numints;
+
+ nc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_name_chunk);
+ p = name;
+ while (namelen > 0) {
+ size_t len;
+ len = namelen;
+ if (len > ZAP_LEAF_ARRAY_BYTES)
+ len = ZAP_LEAF_ARRAY_BYTES;
+ memcpy(p, nc->l_array.la_array, len);
+ p += len;
+ namelen -= len;
+ nc = &ZAP_LEAF_CHUNK(zl, nc->l_array.la_next);
+ }
+
+ *p = '\0';
+}
+
+static int
+fzap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ zap_phys_t zh = *(zap_phys_t *) zap_scratch;
+ fat_zap_t z;
+ int i, j;
+
+ if (zh.zap_magic != ZAP_MAGIC)
+ return (EIO);
+
+ z.zap_block_shift = ilog2(bsize);
+ z.zap_phys = (zap_phys_t *) zap_scratch;
+
+ /*
+ * This assumes that the leaf blocks start at block 1. The
+ * documentation isn't exactly clear on this.
+ */
+ zap_leaf_t zl;
+ zl.l_bs = z.zap_block_shift;
+ for (i = 0; i < zh.zap_num_leafs; i++) {
+ off_t off = (i + 1) << zl.l_bs;
+
+ if (dnode_read(spa, dnode, off, zap_scratch, bsize))
+ return (EIO);
+
+ zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
+
+ for (j = 0; j < ZAP_LEAF_NUMCHUNKS(&zl); j++) {
+ zap_leaf_chunk_t *zc;
+
+ zc = &ZAP_LEAF_CHUNK(&zl, j);
+ if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
+ continue;
+ if (zc->l_entry.le_value_intlen != 8 ||
+ zc->l_entry.le_value_numints != 1)
+ continue;
+
+ if (fzap_leaf_value(&zl, zc) == value) {
+ fzap_name_copy(&zl, zc, name);
+ return (0);
+ }
+ }
+ }
+
+ return (ENOENT);
+}
+
+static int
+zap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ int rc;
+ uint64_t zap_type;
+ size_t size = dnode->dn_datablkszsec * 512;
+
+ rc = dnode_read(spa, dnode, 0, zap_scratch, size);
+ if (rc)
+ return (rc);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_rlookup(spa, dnode, name, value);
+ else
+ return fzap_rlookup(spa, dnode, name, value);
+}
+
+static int
+zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result)
+{
+ char name[256];
+ char component[256];
+ uint64_t dir_obj, parent_obj, child_dir_zapobj;
+ dnode_phys_t child_dir_zap, dataset, dir, parent;
+ dsl_dir_phys_t *dd;
+ dsl_dataset_phys_t *ds;
+ char *p;
+ int len;
+
+ p = &name[sizeof(name) - 1];
+ *p = '\0';
+
+ if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (EIO);
+ }
+ ds = (dsl_dataset_phys_t *)&dataset.dn_bonus;
+ dir_obj = ds->ds_dir_obj;
+
+ for (;;) {
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir) != 0)
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ /* Actual loop condition. */
+ parent_obj = dd->dd_parent_obj;
+ if (parent_obj == 0)
+ break;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, parent_obj, &parent) != 0)
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&parent.dn_bonus;
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0)
+ return (EIO);
+ if (zap_rlookup(spa, &child_dir_zap, component, dir_obj) != 0)
+ return (EIO);
+
+ len = strlen(component);
+ p -= len;
+ memcpy(p, component, len);
+ --p;
+ *p = '/';
+
+ /* Actual loop iteration. */
+ dir_obj = parent_obj;
+ }
+
+ if (*p != '\0')
+ ++p;
+ strcpy(result, p);
+
+ return (0);
+}
+
+static int
+zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum)
+{
+ char element[256];
+ uint64_t dir_obj, child_dir_zapobj;
+ dnode_phys_t child_dir_zap, dir;
+ dsl_dir_phys_t *dd;
+ const char *p, *q;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir))
+ return (EIO);
+ if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, &dir_obj))
+ return (EIO);
+
+ p = name;
+ for (;;) {
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir))
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ while (*p == '/')
+ p++;
+ /* Actual loop condition #1. */
+ if (*p == '\0')
+ break;
+
+ q = strchr(p, '/');
+ if (q) {
+ memcpy(element, p, q - p);
+ element[q - p] = '\0';
+ p = q + 1;
+ } else {
+ strcpy(element, p);
+ p += strlen(p);
+ }
+
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0)
+ return (EIO);
+
+ /* Actual loop condition #2. */
+ if (zap_lookup(spa, &child_dir_zap, element, &dir_obj) != 0)
+ return (ENOENT);
+ }
+
+ *objnum = dd->dd_head_dataset_obj;
+ return (0);
+}
+
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+static int
+zfs_list_dataset(const spa_t *spa, uint64_t objnum/*, int pos, char *entry*/)
+{
+ uint64_t dir_obj, child_dir_zapobj;
+ dnode_phys_t child_dir_zap, dir, dataset;
+ dsl_dataset_phys_t *ds;
+ dsl_dir_phys_t *dd;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (EIO);
+ }
+ ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+ dir_obj = ds->ds_dir_obj;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir)) {
+ printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
+ return (EIO);
+ }
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) {
+ printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
+ return (EIO);
+ }
+
+ return (zap_list(spa, &child_dir_zap) != 0);
+}
+
+int
+zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *, uint64_t))
+{
+ uint64_t dir_obj, child_dir_zapobj, zap_type;
+ dnode_phys_t child_dir_zap, dir, dataset;
+ dsl_dataset_phys_t *ds;
+ dsl_dir_phys_t *dd;
+ int err;
+
+ err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset);
+ if (err != 0) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (err);
+ }
+ ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+ dir_obj = ds->ds_dir_obj;
+
+ err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir);
+ if (err != 0) {
+ printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
+ return (err);
+ }
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap);
+ if (err != 0) {
+ printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
+ return (err);
+ }
+
+ err = dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512);
+ if (err != 0)
+ return (err);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_list(&child_dir_zap, callback);
+ else
+ return fzap_list(spa, &child_dir_zap, callback);
+}
+
+/*
+ * Find the object set given the object number of its dataset object
+ * and return its details in *objset
+ */
+static int
+zfs_mount_dataset(const spa_t *spa, uint64_t objnum, objset_phys_t *objset)
+{
+ dnode_phys_t dataset;
+ dsl_dataset_phys_t *ds;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (EIO);
+ }
+
+ ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+ if (zio_read(spa, &ds->ds_bp, objset)) {
+ printf("ZFS: can't read object set for dataset %ju\n",
+ (uintmax_t)objnum);
+ return (EIO);
+ }
+
+ return (0);
+}
+
+/*
+ * Find the object set pointed to by the BOOTFS property or the root
+ * dataset if there is none and return its details in *objset
+ */
+static int
+zfs_get_root(const spa_t *spa, uint64_t *objid)
+{
+ dnode_phys_t dir, propdir;
+ uint64_t props, bootfs, root;
+
+ *objid = 0;
+
+ /*
+ * Start with the MOS directory object.
+ */
+ if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) {
+ printf("ZFS: can't read MOS object directory\n");
+ return (EIO);
+ }
+
+ /*
+ * Lookup the pool_props and see if we can find a bootfs.
+ */
+ if (zap_lookup(spa, &dir, DMU_POOL_PROPS, &props) == 0
+ && objset_get_dnode(spa, &spa->spa_mos, props, &propdir) == 0
+ && zap_lookup(spa, &propdir, "bootfs", &bootfs) == 0
+ && bootfs != 0)
+ {
+ *objid = bootfs;
+ return (0);
+ }
+ /*
+ * Lookup the root dataset directory
+ */
+ if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, &root)
+ || objset_get_dnode(spa, &spa->spa_mos, root, &dir)) {
+ printf("ZFS: can't find root dsl_dir\n");
+ return (EIO);
+ }
+
+ /*
+ * Use the information from the dataset directory's bonus buffer
+ * to find the dataset object and from that the object set itself.
+ */
+ dsl_dir_phys_t *dd = (dsl_dir_phys_t *) &dir.dn_bonus;
+ *objid = dd->dd_head_dataset_obj;
+ return (0);
+}
+
+static int
+zfs_mount(const spa_t *spa, uint64_t rootobj, struct zfsmount *mnt)
+{
+
+ mnt->spa = spa;
+
+ /*
+ * Find the root object set if not explicitly provided
+ */
+ if (rootobj == 0 && zfs_get_root(spa, &rootobj)) {
+ printf("ZFS: can't find root filesystem\n");
+ return (EIO);
+ }
+
+ if (zfs_mount_dataset(spa, rootobj, &mnt->objset)) {
+ printf("ZFS: can't open root filesystem\n");
+ return (EIO);
+ }
+
+ mnt->rootobj = rootobj;
+
+ return (0);
+}
+
+/*
+ * callback function for feature name checks.
+ */
+static int
+check_feature(const char *name, uint64_t value)
+{
+ int i;
+
+ if (value == 0)
+ return (0);
+ if (name[0] == '\0')
+ return (0);
+
+ for (i = 0; features_for_read[i] != NULL; i++) {
+ if (strcmp(name, features_for_read[i]) == 0)
+ return (0);
+ }
+ printf("ZFS: unsupported feature: %s\n", name);
+ return (EIO);
+}
+
+/*
+ * Checks whether the MOS features that are active are supported.
+ */
+static int
+check_mos_features(const spa_t *spa)
+{
+ dnode_phys_t dir;
+ uint64_t objnum, zap_type;
+ size_t size;
+ int rc;
+
+ if ((rc = objset_get_dnode(spa, &spa->spa_mos, DMU_OT_OBJECT_DIRECTORY,
+ &dir)) != 0)
+ return (rc);
+ if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ, &objnum)) != 0)
+ return (rc);
+
+ if ((rc = objset_get_dnode(spa, &spa->spa_mos, objnum, &dir)) != 0)
+ return (rc);
+
+ if (dir.dn_type != DMU_OTN_ZAP_METADATA)
+ return (EIO);
+
+ size = dir.dn_datablkszsec * 512;
+ if (dnode_read(spa, &dir, 0, zap_scratch, size))
+ return (EIO);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ rc = mzap_list(&dir, check_feature);
+ else
+ rc = fzap_list(spa, &dir, check_feature);
+
+ return (rc);
+}
+
+static int
+zfs_spa_init(spa_t *spa)
+{
+ int rc;
+
+ if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) {
+ printf("ZFS: can't read MOS of pool %s\n", spa->spa_name);
+ return (EIO);
+ }
+ if (spa->spa_mos.os_type != DMU_OST_META) {
+ printf("ZFS: corrupted MOS of pool %s\n", spa->spa_name);
+ return (EIO);
+ }
+
+ rc = check_mos_features(spa);
+ if (rc != 0) {
+ printf("ZFS: pool %s is not supported\n", spa->spa_name);
+ }
+
+ return (rc);
+}
+
+static int
+zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb)
+{
+
+ if (dn->dn_bonustype != DMU_OT_SA) {
+ znode_phys_t *zp = (znode_phys_t *)dn->dn_bonus;
+
+ sb->st_mode = zp->zp_mode;
+ sb->st_uid = zp->zp_uid;
+ sb->st_gid = zp->zp_gid;
+ sb->st_size = zp->zp_size;
+ } else {
+ sa_hdr_phys_t *sahdrp;
+ int hdrsize;
+ size_t size = 0;
+ void *buf = NULL;
+
+ if (dn->dn_bonuslen != 0)
+ sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn);
+ else {
+ if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0) {
+ blkptr_t *bp = &dn->dn_spill;
+ int error;
+
+ size = BP_GET_LSIZE(bp);
+ buf = zfs_alloc(size);
+ error = zio_read(spa, bp, buf);
+ if (error != 0) {
+ zfs_free(buf, size);
+ return (error);
+ }
+ sahdrp = buf;
+ } else {
+ return (EIO);
+ }
+ }
+ hdrsize = SA_HDR_SIZE(sahdrp);
+ sb->st_mode = *(uint64_t *)((char *)sahdrp + hdrsize +
+ SA_MODE_OFFSET);
+ sb->st_uid = *(uint64_t *)((char *)sahdrp + hdrsize +
+ SA_UID_OFFSET);
+ sb->st_gid = *(uint64_t *)((char *)sahdrp + hdrsize +
+ SA_GID_OFFSET);
+ sb->st_size = *(uint64_t *)((char *)sahdrp + hdrsize +
+ SA_SIZE_OFFSET);
+ if (buf != NULL)
+ zfs_free(buf, size);
+ }
+
+ return (0);
+}
+
+/*
+ * Lookup a file and return its dnode.
+ */
+static int
+zfs_lookup(const struct zfsmount *mnt, const char *upath, dnode_phys_t *dnode)
+{
+ int rc;
+ uint64_t objnum, rootnum, parentnum;
+ const spa_t *spa;
+ dnode_phys_t dn;
+ const char *p, *q;
+ char element[256];
+ char path[1024];
+ int symlinks_followed = 0;
+ struct stat sb;
+
+ spa = mnt->spa;
+ if (mnt->objset.os_type != DMU_OST_ZFS) {
+ printf("ZFS: unexpected object set type %ju\n",
+ (uintmax_t)mnt->objset.os_type);
+ return (EIO);
+ }
+
+ /*
+ * Get the root directory dnode.
+ */
+ rc = objset_get_dnode(spa, &mnt->objset, MASTER_NODE_OBJ, &dn);
+ if (rc)
+ return (rc);
+
+ rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, &rootnum);
+ if (rc)
+ return (rc);
+
+ rc = objset_get_dnode(spa, &mnt->objset, rootnum, &dn);
+ if (rc)
+ return (rc);
+
+ objnum = rootnum;
+ p = upath;
+ while (p && *p) {
+ while (*p == '/')
+ p++;
+ if (!*p)
+ break;
+ q = strchr(p, '/');
+ if (q) {
+ memcpy(element, p, q - p);
+ element[q - p] = 0;
+ p = q;
+ } else {
+ strcpy(element, p);
+ p = 0;
+ }
+
+ rc = zfs_dnode_stat(spa, &dn, &sb);
+ if (rc)
+ return (rc);
+ if (!S_ISDIR(sb.st_mode))
+ return (ENOTDIR);
+
+ parentnum = objnum;
+ rc = zap_lookup(spa, &dn, element, &objnum);
+ if (rc)
+ return (rc);
+ objnum = ZFS_DIRENT_OBJ(objnum);
+
+ rc = objset_get_dnode(spa, &mnt->objset, objnum, &dn);
+ if (rc)
+ return (rc);
+
+ /*
+ * Check for symlink.
+ */
+ rc = zfs_dnode_stat(spa, &dn, &sb);
+ if (rc)
+ return (rc);
+ if (S_ISLNK(sb.st_mode)) {
+ if (symlinks_followed > 10)
+ return (EMLINK);
+ symlinks_followed++;
+
+ /*
+ * Read the link value and copy the tail of our
+ * current path onto the end.
+ */
+ if (p)
+ strcpy(&path[sb.st_size], p);
+ else
+ path[sb.st_size] = 0;
+ /*
+ * Second test is purely to silence bogus compiler
+ * warning about accessing past the end of dn_bonus.
+ */
+ if (sb.st_size + sizeof(znode_phys_t) <=
+ dn.dn_bonuslen && sizeof(znode_phys_t) <=
+ sizeof(dn.dn_bonus)) {
+ memcpy(path, &dn.dn_bonus[sizeof(znode_phys_t)],
+ sb.st_size);
+ } else {
+ rc = dnode_read(spa, &dn, 0, path, sb.st_size);
+ if (rc)
+ return (rc);
+ }
+
+ /*
+ * Restart with the new path, starting either at
+ * the root or at the parent depending whether or
+ * not the link is relative.
+ */
+ p = path;
+ if (*p == '/')
+ objnum = rootnum;
+ else
+ objnum = parentnum;
+ objset_get_dnode(spa, &mnt->objset, objnum, &dn);
+ }
+ }
+
+ *dnode = dn;
+ return (0);
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/README b/usr/src/boot/sys/cddl/boot/zfs/README
new file mode 100644
index 0000000000..5f16d5cddf
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/README
@@ -0,0 +1,16 @@
+$FreeBSD$
+
+This directory contains various files derived from CDDL sources that
+are used by the ZFS bootstrap:
+
+ fletcher.c checksum support
+ sha256.c checksum support
+ lz4.c compression support
+ lzjb.c compression support
+ blkptr.c ZFS embedded-data block pointers support
+ zfssubr.c checksum, compression and raidz support
+ zfsimpl.h mostly describing the physical layout
+
+The files fletcher.c, lzjb.c, lz4.c, sha256.c and blkptr.c are largely identical
+to the ZFS base code (with write support removed) and could be shared but that
+might complicate future imports from Illumos.
diff --git a/usr/src/boot/sys/cddl/boot/zfs/blkptr.c b/usr/src/boot/sys/cddl/boot/zfs/blkptr.c
new file mode 100644
index 0000000000..c36c59bbe8
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/blkptr.c
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * 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.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/*
+ * Embedded-data Block Pointers
+ *
+ * Normally, block pointers point (via their DVAs) to a block which holds data.
+ * If the data that we need to store is very small, this is an inefficient
+ * use of space, because a block must be at minimum 1 sector (typically 512
+ * bytes or 4KB). Additionally, reading these small blocks tends to generate
+ * more random reads.
+ *
+ * Embedded-data Block Pointers allow small pieces of data (the "payload",
+ * up to 112 bytes) to be stored in the block pointer itself, instead of
+ * being pointed to. The "Pointer" part of this name is a bit of a
+ * misnomer, as nothing is pointed to.
+ *
+ * BP_EMBEDDED_TYPE_DATA block pointers allow highly-compressible data to
+ * be embedded in the block pointer. The logic for this is handled in
+ * the SPA, by the zio pipeline. Therefore most code outside the zio
+ * pipeline doesn't need special-cases to handle these block pointers.
+ *
+ * See spa.h for details on the exact layout of embedded block pointers.
+ */
+
+/*
+ * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
+ * more than BPE_PAYLOAD_SIZE bytes).
+ */
+void
+decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
+{
+ int psize;
+ uint8_t *buf8 = buf;
+ uint64_t w = 0;
+ const uint64_t *bp64 = (const uint64_t *)bp;
+
+ ASSERT(BP_IS_EMBEDDED(bp));
+
+ psize = BPE_GET_PSIZE(bp);
+
+ /*
+ * Decode the words of the block pointer into the byte array.
+ * Low bits of first word are the first byte (little endian).
+ */
+ for (int i = 0; i < psize; i++) {
+ if (i % sizeof (w) == 0) {
+ /* beginning of a word */
+ ASSERT3P(bp64, <, bp + 1);
+ w = *bp64;
+ bp64++;
+ if (!BPE_IS_PAYLOADWORD(bp, bp64))
+ bp64++;
+ }
+ buf8[i] = BF64_GET(w, (i % sizeof (w)) * NBBY, NBBY);
+ }
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/fletcher.c b/usr/src/boot/sys/cddl/boot/zfs/fletcher.c
new file mode 100644
index 0000000000..ca08e5deae
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/fletcher.c
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+static void
+fletcher_2_native(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ const uint64_t *ip = buf;
+ const uint64_t *ipend = ip + (size / sizeof (uint64_t));
+ uint64_t a0, b0, a1, b1;
+
+ for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
+ a0 += ip[0];
+ a1 += ip[1];
+ b0 += a0;
+ b1 += a1;
+ }
+
+ ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
+}
+
+static void
+fletcher_2_byteswap(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ const uint64_t *ip = buf;
+ const uint64_t *ipend = ip + (size / sizeof (uint64_t));
+ uint64_t a0, b0, a1, b1;
+
+ for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
+ a0 += BSWAP_64(ip[0]);
+ a1 += BSWAP_64(ip[1]);
+ b0 += a0;
+ b1 += a1;
+ }
+
+ ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
+}
+
+static void
+fletcher_4_native(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ const uint32_t *ip = buf;
+ const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+ uint64_t a, b, c, d;
+
+ for (a = b = c = d = 0; ip < ipend; ip++) {
+ a += ip[0];
+ b += a;
+ c += b;
+ d += c;
+ }
+
+ ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
+
+static void
+fletcher_4_byteswap(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ const uint32_t *ip = buf;
+ const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+ uint64_t a, b, c, d;
+
+ for (a = b = c = d = 0; ip < ipend; ip++) {
+ a += BSWAP_32(ip[0]);
+ b += a;
+ c += b;
+ d += c;
+ }
+
+ ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/lz4.c b/usr/src/boot/sys/cddl/boot/zfs/lz4.c
new file mode 100644
index 0000000000..23625239b2
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/lz4.c
@@ -0,0 +1,328 @@
+/*
+ * LZ4 - Fast LZ compression algorithm
+ * Header File
+ * Copyright (C) 2011-2013, Yann Collet.
+ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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 MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * 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 DAMAGE.
+ *
+ * You can contact the author at :
+ * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+ * - LZ4 source repository : http://code.google.com/p/lz4/
+ *
+ * $FreeBSD$
+ */
+int lz4_decompress(void *, void *, size_t, size_t, int);
+
+static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
+ int isize, int maxOutputSize);
+
+/* ARGSUSED */
+int
+lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int dummy __unused)
+{
+ const uint8_t *src = s_start;
+ uint32_t bufsiz = htonl(*(uint32_t *)src);
+
+ /* invalid compressed buffer size encoded at start */
+ if (bufsiz + 4 > s_len)
+ return (1);
+
+ /*
+ * Returns 0 on success (decompression function returned non-negative)
+ * and non-zero on failure (decompression function returned negative).
+ */
+ return (LZ4_uncompress_unknownOutputSize((const char *)s_start + 4, d_start, bufsiz,
+ d_len) < 0);
+}
+
+/*
+ * CPU Feature Detection
+ */
+
+/* 32 or 64 bits ? */
+#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || \
+ defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || \
+ defined(__LP64__) || defined(_LP64))
+#define LZ4_ARCH64 1
+#else
+#define LZ4_ARCH64 0
+#endif
+
+/*
+ * Little Endian or Big Endian?
+ * Note: overwrite the below #define if you know your architecture endianess.
+ */
+#if BYTE_ORDER == BIG_ENDIAN
+#define LZ4_BIG_ENDIAN 1
+#else
+ /*
+ * Little Endian assumed. PDP Endian and other very rare endian format
+ * are unsupported.
+ */
+#endif
+
+/*
+ * Unaligned memory access is automatically enabled for "common" CPU,
+ * such as x86. For others CPU, the compiler will be more cautious, and
+ * insert extra code to ensure aligned access is respected. If you know
+ * your target CPU supports unaligned memory access, you may want to
+ * force this option manually to improve performance
+ */
+#if defined(__ARM_FEATURE_UNALIGNED)
+#define LZ4_FORCE_UNALIGNED_ACCESS 1
+#endif
+
+/*
+ * Compiler Options
+ */
+#if __STDC_VERSION__ >= 199901L /* C99 */
+/* "restrict" is a known keyword */
+#else
+/* Disable restrict */
+#define restrict
+#endif
+
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+#define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) \
+ | (((x) & 0xffu) << 8)))
+
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#define expect(expr, value) (__builtin_expect((expr), (value)))
+#else
+#define expect(expr, value) (expr)
+#endif
+
+#define likely(expr) expect((expr) != 0, 1)
+#define unlikely(expr) expect((expr) != 0, 0)
+
+/* Basic types */
+#define BYTE uint8_t
+#define U16 uint16_t
+#define U32 uint32_t
+#define S32 int32_t
+#define U64 uint64_t
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(1)
+#endif
+
+typedef struct _U16_S {
+ U16 v;
+} U16_S;
+typedef struct _U32_S {
+ U32 v;
+} U32_S;
+typedef struct _U64_S {
+ U64 v;
+} U64_S;
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack()
+#endif
+
+#define A64(x) (((U64_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A16(x) (((U16_S *)(x))->v)
+
+/*
+ * Constants
+ */
+#define MINMATCH 4
+
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+
+#define ML_BITS 4
+#define ML_MASK ((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+/*
+ * Architecture-specific macros
+ */
+#if LZ4_ARCH64
+#define STEPSIZE 8
+#define UARCH U64
+#define AARCH A64
+#define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8;
+#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d)
+#define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e)
+#define HTYPE U32
+#define INITBASE(base) const BYTE* const base = ip
+#else
+#define STEPSIZE 4
+#define UARCH U32
+#define AARCH A32
+#define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4;
+#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
+#define LZ4_SECURECOPY LZ4_WILDCOPY
+#define HTYPE const BYTE*
+#define INITBASE(base) const int base = 0
+#endif
+
+#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
+ { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#define LZ4_WRITE_LITTLEENDIAN_16(p, i) \
+ { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p += 2; }
+#else
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - A16(p); }
+#define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = v; p += 2; }
+#endif
+
+/* Macros */
+#define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
+
+/* Decompression functions */
+
+static int
+LZ4_uncompress_unknownOutputSize(const char *source,
+ char *dest, int isize, int maxOutputSize)
+{
+ /* Local Variables */
+ const BYTE *restrict ip = (const BYTE *) source;
+ const BYTE *const iend = ip + isize;
+ const BYTE *restrict ref;
+
+ BYTE *restrict op = (BYTE *) dest;
+ BYTE *const oend = op + maxOutputSize;
+ BYTE *cpy;
+
+ size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
+
+ /* Main Loop */
+ while (ip < iend) {
+ BYTE token;
+ int length;
+
+ /* get runlength */
+ token = *ip++;
+ if ((length = (token >> ML_BITS)) == RUN_MASK) {
+ int s = 255;
+ while ((ip < iend) && (s == 255)) {
+ s = *ip++;
+ length += s;
+ }
+ }
+ /* copy literals */
+ cpy = op + length;
+ if ((cpy > oend - COPYLENGTH) ||
+ (ip + length > iend - COPYLENGTH)) {
+ if (cpy > oend)
+ /*
+ * Error: request to write beyond destination
+ * buffer.
+ */
+ goto _output_error;
+ if (ip + length > iend)
+ /*
+ * Error : request to read beyond source
+ * buffer.
+ */
+ goto _output_error;
+ memcpy(op, ip, length);
+ op += length;
+ ip += length;
+ if (ip < iend)
+ /* Error : LZ4 format violation */
+ goto _output_error;
+ /* Necessarily EOF, due to parsing restrictions. */
+ break;
+ }
+ LZ4_WILDCOPY(ip, op, cpy);
+ ip -= (op - cpy);
+ op = cpy;
+
+ /* get offset */
+ LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
+ ip += 2;
+ if (ref < (BYTE * const) dest)
+ /*
+ * Error: offset creates reference outside of
+ * destination buffer.
+ */
+ goto _output_error;
+
+ /* get matchlength */
+ if ((length = (token & ML_MASK)) == ML_MASK) {
+ while (ip < iend) {
+ int s = *ip++;
+ length += s;
+ if (s == 255)
+ continue;
+ break;
+ }
+ }
+ /* copy repeated sequence */
+ if unlikely(op - ref < STEPSIZE) {
+#if LZ4_ARCH64
+ size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
+ size_t dec2 = dec2table[op - ref];
+#else
+ const int dec2 = 0;
+#endif
+ *op++ = *ref++;
+ *op++ = *ref++;
+ *op++ = *ref++;
+ *op++ = *ref++;
+ ref -= dec[op - ref];
+ A32(op) = A32(ref);
+ op += STEPSIZE - 4;
+ ref -= dec2;
+ } else {
+ LZ4_COPYSTEP(ref, op);
+ }
+ cpy = op + length - (STEPSIZE - 4);
+ if (cpy > oend - COPYLENGTH) {
+ if (cpy > oend)
+ /*
+ * Error: request to write outside of
+ * destination buffer.
+ */
+ goto _output_error;
+ LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
+ while (op < cpy)
+ *op++ = *ref++;
+ op = cpy;
+ if (op == oend)
+ /*
+ * Check EOF (should never happen, since last
+ * 5 bytes are supposed to be literals).
+ */
+ break;
+ continue;
+ }
+ LZ4_SECURECOPY(ref, op, cpy);
+ op = cpy; /* correction */
+ }
+
+ /* end of decoding */
+ return (int)(((char *)op) - dest);
+
+ /* write overflow error detected */
+ _output_error:
+ return (int)(-(((char *)ip) - source));
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/lzjb.c b/usr/src/boot/sys/cddl/boot/zfs/lzjb.c
new file mode 100644
index 0000000000..1283a6c31a
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/lzjb.c
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*#pragma ident "%Z%%M% %I% %E% SMI"*/
+
+/*
+ * We keep our own copy of this algorithm for 2 main reasons:
+ * 1. If we didn't, anyone modifying common/os/compress.c would
+ * directly break our on disk format
+ * 2. Our version of lzjb does not have a number of checks that the
+ * common/os version needs and uses
+ * In particular, we are adding the "feature" that compress() can
+ * take a destination buffer size and return -1 if the data will not
+ * compress to d_len or less.
+ */
+
+#define MATCH_BITS 6
+#define MATCH_MIN 3
+#define MATCH_MAX ((1 << MATCH_BITS) + (MATCH_MIN - 1))
+#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1)
+#define LEMPEL_SIZE 256
+
+/*ARGSUSED*/
+static int
+lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+ unsigned char *src = s_start;
+ unsigned char *dst = d_start;
+ unsigned char *d_end = (unsigned char *)d_start + d_len;
+ unsigned char *cpy, copymap = 0;
+ int copymask = 1 << (NBBY - 1);
+
+ while (dst < d_end) {
+ if ((copymask <<= 1) == (1 << NBBY)) {
+ copymask = 1;
+ copymap = *src++;
+ }
+ if (copymap & copymask) {
+ int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
+ int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
+ src += 2;
+ if ((cpy = dst - offset) < (unsigned char *)d_start)
+ return (-1);
+ while (--mlen >= 0 && dst < d_end)
+ *dst++ = *cpy++;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ return (0);
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/sha256.c b/usr/src/boot/sys/cddl/boot/zfs/sha256.c
new file mode 100644
index 0000000000..403d110b6f
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/sha256.c
@@ -0,0 +1,325 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2013 Saso Kiselkov. All rights reserved.
+ * Copyright 2015 Toomas Soome <tsoome@me.com>
+ */
+
+/*
+ * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
+ * http://csrc.nist.gov/cryptval
+ *
+ * This is a very compact implementation of SHA-256 and SHA-512/256.
+ * It is designed to be simple and portable, not to be fast.
+ */
+
+/*
+ * The literal definitions according to FIPS180-4 would be:
+ *
+ * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
+ * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+ *
+ * We use logical equivalents which require one less op.
+ */
+#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
+#define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
+
+/* SHA-224/256 operations */
+#define BIGSIGMA0_256(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define BIGSIGMA1_256(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define SIGMA0_256(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
+#define SIGMA1_256(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
+
+/* SHA-384/512 operations */
+#define BIGSIGMA0_512(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
+#define BIGSIGMA1_512(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
+#define SIGMA0_512(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
+#define SIGMA1_512(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
+
+/* SHA-256 round constants */
+static const uint32_t SHA256_K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* SHA-512 round constants */
+static const uint64_t SHA512_K[80] = {
+ 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
+ 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
+ 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
+ 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
+ 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
+ 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
+ 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
+ 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
+ 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
+ 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
+ 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
+ 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
+ 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
+ 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
+ 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
+ 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
+ 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
+ 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
+ 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
+ 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
+ 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
+ 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
+ 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
+ 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
+ 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
+ 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
+ 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
+ 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
+ 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
+ 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
+ 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
+ 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
+ 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
+ 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
+ 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
+ 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
+ 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
+ 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
+ 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
+ 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
+};
+
+static void
+SHA256Transform(uint32_t *H, const uint8_t *cp)
+{
+ uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
+
+ /* copy chunk into the first 16 words of the message schedule */
+ for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
+ W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
+
+ /* extend the first 16 words into the remaining 48 words */
+ for (t = 16; t < 64; t++)
+ W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
+ SIGMA0_256(W[t - 15]) + W[t - 16];
+
+ /* init working variables to the current hash value */
+ a = H[0]; b = H[1]; c = H[2]; d = H[3];
+ e = H[4]; f = H[5]; g = H[6]; h = H[7];
+
+ /* iterate the compression function for all rounds of the hash */
+ for (t = 0; t < 64; t++) {
+ T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
+ T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
+ h = g; g = f; f = e; e = d + T1;
+ d = c; c = b; b = a; a = T1 + T2;
+ }
+
+ /* add the compressed chunk to the current hash value */
+ H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+ H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+}
+
+static void
+SHA512Transform(uint64_t *H, const uint8_t *cp)
+{
+ uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
+
+ /* copy chunk into the first 16 words of the message schedule */
+ for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
+ W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
+ ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
+ ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
+ ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
+
+ /* extend the first 16 words into the remaining 64 words */
+ for (t = 16; t < 80; t++)
+ W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
+ SIGMA0_512(W[t - 15]) + W[t - 16];
+
+ /* init working variables to the current hash value */
+ a = H[0]; b = H[1]; c = H[2]; d = H[3];
+ e = H[4]; f = H[5]; g = H[6]; h = H[7];
+
+ /* iterate the compression function for all rounds of the hash */
+ for (t = 0; t < 80; t++) {
+ T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
+ T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
+ h = g; g = f; f = e; e = d + T1;
+ d = c; c = b; b = a; a = T1 + T2;
+ }
+
+ /* add the compressed chunk to the current hash value */
+ H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+ H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+}
+
+/*
+ * Implements the SHA-224 and SHA-256 hash algos - to select between them
+ * pass the appropriate initial values of 'H' and truncate the last 32 bits
+ * in case of SHA-224.
+ */
+static void
+SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+ uint8_t pad[128];
+ unsigned padsize = size & 63;
+ unsigned i, k;
+
+ /* process all blocks up to the last one */
+ for (i = 0; i < size - padsize; i += 64)
+ SHA256Transform(H, (uint8_t *)buf + i);
+
+ /* process the last block and padding */
+ for (k = 0; k < padsize; k++)
+ pad[k] = ((uint8_t *)buf)[k+i];
+
+ for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
+ pad[padsize] = 0;
+
+ for (i = 0; i < 8; i++)
+ pad[padsize++] = (size << 3) >> (56 - 8 * i);
+
+ for (i = 0; i < padsize; i += 64)
+ SHA256Transform(H, pad + i);
+
+ ZIO_SET_CHECKSUM(zcp,
+ (uint64_t)H[0] << 32 | H[1],
+ (uint64_t)H[2] << 32 | H[3],
+ (uint64_t)H[4] << 32 | H[5],
+ (uint64_t)H[6] << 32 | H[7]);
+}
+
+/*
+ * encode 64bit data in big-endian format.
+ */
+static void
+Encode64(uint8_t *output, uint64_t *input, size_t len)
+{
+ size_t i, j;
+ for (i = 0, j = 0; j < len; i++, j += 8) {
+ output[j] = (input[i] >> 56) & 0xff;
+ output[j + 1] = (input[i] >> 48) & 0xff;
+ output[j + 2] = (input[i] >> 40) & 0xff;
+ output[j + 3] = (input[i] >> 32) & 0xff;
+ output[j + 4] = (input[i] >> 24) & 0xff;
+ output[j + 5] = (input[i] >> 16) & 0xff;
+ output[j + 6] = (input[i] >> 8) & 0xff;
+ output[j + 7] = input[i] & 0xff;
+ }
+}
+
+/*
+ * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
+ * between them pass the appropriate initial values for 'H'. The output
+ * of this function is truncated to the first 256 bits that fit into 'zcp'.
+ */
+static void
+SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+ uint64_t c64[2];
+ uint8_t pad[256];
+ unsigned padsize = size & 127;
+ unsigned i, k;
+
+ /* process all blocks up to the last one */
+ for (i = 0; i < size - padsize; i += 128)
+ SHA512Transform(H, (uint8_t *)buf + i);
+
+ /* process the last block and padding */
+ for (k = 0; k < padsize; k++)
+ pad[k] = ((uint8_t *)buf)[k+i];
+
+ if (padsize < 112) {
+ for (pad[padsize++] = 0x80; padsize < 112; padsize++)
+ pad[padsize] = 0;
+ } else {
+ for (pad[padsize++] = 0x80; padsize < 240; padsize++)
+ pad[padsize] = 0;
+ }
+
+ c64[0] = 0;
+ c64[1] = size << 3;
+ Encode64(pad+padsize, c64, sizeof (c64));
+ padsize += sizeof (c64);
+
+ for (i = 0; i < padsize; i += 128)
+ SHA512Transform(H, pad + i);
+
+ /* truncate the output to the first 256 bits which fit into 'zcp' */
+ Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
+}
+
+static void
+zio_checksum_SHA256(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ /* SHA-256 as per FIPS 180-4. */
+ uint32_t H[] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ };
+ SHA256(H, buf, size, zcp);
+}
+
+static void
+zio_checksum_SHA512_native(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ /* SHA-512/256 as per FIPS 180-4. */
+ uint64_t H[] = {
+ 0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
+ 0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
+ 0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
+ 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
+ };
+ SHA512(H, buf, size, zcp);
+}
+
+static void
+zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ zio_cksum_t tmp;
+
+ zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
+ zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
+ zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
+ zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
+ zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
new file mode 100644
index 0000000000..0ddc96ad93
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
@@ -0,0 +1,1518 @@
+/*-
+ * Copyright (c) 2002 McAfee, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and McAfee Research,, the Security Research Division of
+ * McAfee, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as
+ * part of the DARPA CHATS research program
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ */
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2013 by Saso Kiselkov. All rights reserved.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#define MAXNAMELEN 256
+
+#define _NOTE(s)
+
+typedef enum { B_FALSE, B_TRUE } boolean_t;
+
+/* CRC64 table */
+#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
+
+/*
+ * Macros for various sorts of alignment and rounding when the alignment
+ * is known to be a power of 2.
+ */
+#define P2ALIGN(x, align) ((x) & -(align))
+#define P2PHASE(x, align) ((x) & ((align) - 1))
+#define P2NPHASE(x, align) (-(x) & ((align) - 1))
+#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
+#define P2END(x, align) (-(~(x) & -(align)))
+#define P2PHASEUP(x, align, phase) ((phase) - (((phase) - (x)) & -(align)))
+#define P2BOUNDARY(off, len, align) (((off) ^ ((off) + (len) - 1)) > (align) - 1)
+
+/*
+ * General-purpose 32-bit and 64-bit bitfield encodings.
+ */
+#define BF32_DECODE(x, low, len) P2PHASE((x) >> (low), 1U << (len))
+#define BF64_DECODE(x, low, len) P2PHASE((x) >> (low), 1ULL << (len))
+#define BF32_ENCODE(x, low, len) (P2PHASE((x), 1U << (len)) << (low))
+#define BF64_ENCODE(x, low, len) (P2PHASE((x), 1ULL << (len)) << (low))
+
+#define BF32_GET(x, low, len) BF32_DECODE(x, low, len)
+#define BF64_GET(x, low, len) BF64_DECODE(x, low, len)
+
+#define BF32_SET(x, low, len, val) \
+ ((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len))
+#define BF64_SET(x, low, len, val) \
+ ((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len))
+
+#define BF32_GET_SB(x, low, len, shift, bias) \
+ ((BF32_GET(x, low, len) + (bias)) << (shift))
+#define BF64_GET_SB(x, low, len, shift, bias) \
+ ((BF64_GET(x, low, len) + (bias)) << (shift))
+
+#define BF32_SET_SB(x, low, len, shift, bias, val) \
+ BF32_SET(x, low, len, ((val) >> (shift)) - (bias))
+#define BF64_SET_SB(x, low, len, shift, bias, val) \
+ BF64_SET(x, low, len, ((val) >> (shift)) - (bias))
+
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+
+#define SPA_MINBLOCKSHIFT 9
+#define SPA_OLDMAXBLOCKSHIFT 17
+#define SPA_MAXBLOCKSHIFT 24
+#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT)
+#define SPA_OLDMAXBLOCKSIZE (1ULL << SPA_OLDMAXBLOCKSHIFT)
+#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT)
+
+/*
+ * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
+ * The ASIZE encoding should be at least 64 times larger (6 more bits)
+ * to support up to 4-way RAID-Z mirror mode with worst-case gang block
+ * overhead, three DVAs per bp, plus one more bit in case we do anything
+ * else that expands the ASIZE.
+ */
+#define SPA_LSIZEBITS 16 /* LSIZE up to 32M (2^16 * 512) */
+#define SPA_PSIZEBITS 16 /* PSIZE up to 32M (2^16 * 512) */
+#define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */
+
+/*
+ * All SPA data is represented by 128-bit data virtual addresses (DVAs).
+ * The members of the dva_t should be considered opaque outside the SPA.
+ */
+typedef struct dva {
+ uint64_t dva_word[2];
+} dva_t;
+
+/*
+ * Each block has a 256-bit checksum -- strong enough for cryptographic hashes.
+ */
+typedef struct zio_cksum {
+ uint64_t zc_word[4];
+} zio_cksum_t;
+
+/*
+ * Some checksums/hashes need a 256-bit initialization salt. This salt is kept
+ * secret and is suitable for use in MAC algorithms as the key.
+ */
+typedef struct zio_cksum_salt {
+ uint8_t zcs_bytes[32];
+} zio_cksum_salt_t;
+
+/*
+ * Each block is described by its DVAs, time of birth, checksum, etc.
+ * The word-by-word, bit-by-bit layout of the blkptr is as follows:
+ *
+ * 64 56 48 40 32 24 16 8 0
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 0 | vdev1 | GRID | ASIZE |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 1 |G| offset1 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 2 | vdev2 | GRID | ASIZE |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 3 |G| offset2 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 4 | vdev3 | GRID | ASIZE |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 5 |G| offset3 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 7 | padding |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 8 | padding |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 9 | physical birth txg |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * a | logical birth txg |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * b | fill count |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * c | checksum[0] |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * d | checksum[1] |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * e | checksum[2] |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * f | checksum[3] |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Legend:
+ *
+ * vdev virtual device ID
+ * offset offset into virtual device
+ * LSIZE logical size
+ * PSIZE physical size (after compression)
+ * ASIZE allocated size (including RAID-Z parity and gang block headers)
+ * GRID RAID-Z layout information (reserved for future use)
+ * cksum checksum function
+ * comp compression function
+ * G gang block indicator
+ * B byteorder (endianness)
+ * D dedup
+ * X encryption (on version 30, which is not supported)
+ * E blkptr_t contains embedded data (see below)
+ * lvl level of indirection
+ * type DMU object type
+ * phys birth txg of block allocation; zero if same as logical birth txg
+ * log. birth transaction group in which the block was logically born
+ * fill count number of non-zero blocks under this bp
+ * checksum[4] 256-bit checksum of the data this bp describes
+ */
+
+/*
+ * "Embedded" blkptr_t's don't actually point to a block, instead they
+ * have a data payload embedded in the blkptr_t itself. See the comment
+ * in blkptr.c for more details.
+ *
+ * The blkptr_t is laid out as follows:
+ *
+ * 64 56 48 40 32 24 16 8 0
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 0 | payload |
+ * 1 | payload |
+ * 2 | payload |
+ * 3 | payload |
+ * 4 | payload |
+ * 5 | payload |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 6 |BDX|lvl| type | etype |E| comp| PSIZE| LSIZE |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * 7 | payload |
+ * 8 | payload |
+ * 9 | payload |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * a | logical birth txg |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * b | payload |
+ * c | payload |
+ * d | payload |
+ * e | payload |
+ * f | payload |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Legend:
+ *
+ * payload contains the embedded data
+ * B (byteorder) byteorder (endianness)
+ * D (dedup) padding (set to zero)
+ * X encryption (set to zero; see above)
+ * E (embedded) set to one
+ * lvl indirection level
+ * type DMU object type
+ * etype how to interpret embedded data (BP_EMBEDDED_TYPE_*)
+ * comp compression function of payload
+ * PSIZE size of payload after compression, in bytes
+ * LSIZE logical size of payload, in bytes
+ * note that 25 bits is enough to store the largest
+ * "normal" BP's LSIZE (2^16 * 2^9) in bytes
+ * log. birth transaction group in which the block was logically born
+ *
+ * Note that LSIZE and PSIZE are stored in bytes, whereas for non-embedded
+ * bp's they are stored in units of SPA_MINBLOCKSHIFT.
+ * Generally, the generic BP_GET_*() macros can be used on embedded BP's.
+ * The B, D, X, lvl, type, and comp fields are stored the same as with normal
+ * BP's so the BP_SET_* macros can be used with them. etype, PSIZE, LSIZE must
+ * be set with the BPE_SET_* macros. BP_SET_EMBEDDED() should be called before
+ * other macros, as they assert that they are only used on BP's of the correct
+ * "embedded-ness".
+ */
+
+#define BPE_GET_ETYPE(bp) \
+ (ASSERT(BP_IS_EMBEDDED(bp)), \
+ BF64_GET((bp)->blk_prop, 40, 8))
+#define BPE_SET_ETYPE(bp, t) do { \
+ ASSERT(BP_IS_EMBEDDED(bp)); \
+ BF64_SET((bp)->blk_prop, 40, 8, t); \
+_NOTE(CONSTCOND) } while (0)
+
+#define BPE_GET_LSIZE(bp) \
+ (ASSERT(BP_IS_EMBEDDED(bp)), \
+ BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1))
+#define BPE_SET_LSIZE(bp, x) do { \
+ ASSERT(BP_IS_EMBEDDED(bp)); \
+ BF64_SET_SB((bp)->blk_prop, 0, 25, 0, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define BPE_GET_PSIZE(bp) \
+ (ASSERT(BP_IS_EMBEDDED(bp)), \
+ BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1))
+#define BPE_SET_PSIZE(bp, x) do { \
+ ASSERT(BP_IS_EMBEDDED(bp)); \
+ BF64_SET_SB((bp)->blk_prop, 25, 7, 0, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+typedef enum bp_embedded_type {
+ BP_EMBEDDED_TYPE_DATA,
+ BP_EMBEDDED_TYPE_RESERVED, /* Reserved for an unintegrated feature. */
+ NUM_BP_EMBEDDED_TYPES = BP_EMBEDDED_TYPE_RESERVED
+} bp_embedded_type_t;
+
+#define BPE_NUM_WORDS 14
+#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t))
+#define BPE_IS_PAYLOADWORD(bp, wp) \
+ ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
+
+#define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */
+#define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */
+
+typedef struct blkptr {
+ dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */
+ uint64_t blk_prop; /* size, compression, type, etc */
+ uint64_t blk_pad[2]; /* Extra space for the future */
+ uint64_t blk_phys_birth; /* txg when block was allocated */
+ uint64_t blk_birth; /* transaction group at birth */
+ uint64_t blk_fill; /* fill count */
+ zio_cksum_t blk_cksum; /* 256-bit checksum */
+} blkptr_t;
+
+/*
+ * Macros to get and set fields in a bp or DVA.
+ */
+#define DVA_GET_ASIZE(dva) \
+ BF64_GET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0)
+#define DVA_SET_ASIZE(dva, x) \
+ BF64_SET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, \
+ SPA_MINBLOCKSHIFT, 0, x)
+
+#define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8)
+#define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x)
+
+#define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32)
+#define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x)
+
+#define DVA_GET_OFFSET(dva) \
+ BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0)
+#define DVA_SET_OFFSET(dva, x) \
+ BF64_SET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0, x)
+
+#define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1)
+#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x)
+
+#define BP_GET_LSIZE(bp) \
+ (BP_IS_EMBEDDED(bp) ? \
+ (BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA ? BPE_GET_LSIZE(bp) : 0): \
+ BF64_GET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1))
+#define BP_SET_LSIZE(bp, x) do { \
+ ASSERT(!BP_IS_EMBEDDED(bp)); \
+ BF64_SET_SB((bp)->blk_prop, \
+ 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define BP_GET_PSIZE(bp) \
+ BF64_GET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1)
+#define BP_SET_PSIZE(bp, x) \
+ BF64_SET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
+
+#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7)
+#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x)
+
+#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
+#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
+
+#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8)
+#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x)
+
+#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
+#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
+
+#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1)
+
+#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1)
+#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x)
+
+#define BP_GET_BYTEORDER(bp) BF64_GET((bp)->blk_prop, 63, 1)
+#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x)
+
+#define BP_PHYSICAL_BIRTH(bp) \
+ ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth)
+
+#define BP_GET_ASIZE(bp) \
+ (DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
+ DVA_GET_ASIZE(&(bp)->blk_dva[2]))
+
+#define BP_GET_UCSIZE(bp) \
+ ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \
+ BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp));
+
+#define BP_GET_NDVAS(bp) \
+ (!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
+ !!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
+ !!DVA_GET_ASIZE(&(bp)->blk_dva[2]))
+
+#define DVA_EQUAL(dva1, dva2) \
+ ((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
+ (dva1)->dva_word[0] == (dva2)->dva_word[0])
+
+#define ZIO_CHECKSUM_EQUAL(zc1, zc2) \
+ (0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \
+ ((zc1).zc_word[1] - (zc2).zc_word[1]) | \
+ ((zc1).zc_word[2] - (zc2).zc_word[2]) | \
+ ((zc1).zc_word[3] - (zc2).zc_word[3])))
+
+
+#define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0)
+
+#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \
+{ \
+ (zcp)->zc_word[0] = w0; \
+ (zcp)->zc_word[1] = w1; \
+ (zcp)->zc_word[2] = w2; \
+ (zcp)->zc_word[3] = w3; \
+}
+
+#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
+#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
+#define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] == 0ULL && \
+ (dva)->dva_word[1] == 0ULL)
+#define BP_IS_HOLE(bp) DVA_IS_EMPTY(BP_IDENTITY(bp))
+#define BP_IS_OLDER(bp, txg) (!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg))
+
+#define BP_ZERO(bp) \
+{ \
+ (bp)->blk_dva[0].dva_word[0] = 0; \
+ (bp)->blk_dva[0].dva_word[1] = 0; \
+ (bp)->blk_dva[1].dva_word[0] = 0; \
+ (bp)->blk_dva[1].dva_word[1] = 0; \
+ (bp)->blk_dva[2].dva_word[0] = 0; \
+ (bp)->blk_dva[2].dva_word[1] = 0; \
+ (bp)->blk_prop = 0; \
+ (bp)->blk_pad[0] = 0; \
+ (bp)->blk_pad[1] = 0; \
+ (bp)->blk_phys_birth = 0; \
+ (bp)->blk_birth = 0; \
+ (bp)->blk_fill = 0; \
+ ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \
+}
+
+#define BPE_NUM_WORDS 14
+#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t))
+#define BPE_IS_PAYLOADWORD(bp, wp) \
+ ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
+
+/*
+ * Embedded checksum
+ */
+#define ZEC_MAGIC 0x210da7ab10c7a11ULL
+
+typedef struct zio_eck {
+ uint64_t zec_magic; /* for validation, endianness */
+ zio_cksum_t zec_cksum; /* 256-bit checksum */
+} zio_eck_t;
+
+/*
+ * Gang block headers are self-checksumming and contain an array
+ * of block pointers.
+ */
+#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE
+#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \
+ sizeof (zio_eck_t)) / sizeof (blkptr_t))
+#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \
+ sizeof (zio_eck_t) - \
+ (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
+ sizeof (uint64_t))
+
+typedef struct zio_gbh {
+ blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS];
+ uint64_t zg_filler[SPA_GBH_FILLER];
+ zio_eck_t zg_tail;
+} zio_gbh_phys_t;
+
+#define VDEV_RAIDZ_MAXPARITY 3
+
+#define VDEV_PAD_SIZE (8 << 10)
+/* 2 padding areas (vl_pad1 and vl_pad2) to skip */
+#define VDEV_SKIP_SIZE VDEV_PAD_SIZE * 2
+#define VDEV_PHYS_SIZE (112 << 10)
+#define VDEV_UBERBLOCK_RING (128 << 10)
+
+#define VDEV_UBERBLOCK_SHIFT(vd) \
+ MAX((vd)->v_top->v_ashift, UBERBLOCK_SHIFT)
+#define VDEV_UBERBLOCK_COUNT(vd) \
+ (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(vd))
+#define VDEV_UBERBLOCK_OFFSET(vd, n) \
+ offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(vd)])
+#define VDEV_UBERBLOCK_SIZE(vd) (1ULL << VDEV_UBERBLOCK_SHIFT(vd))
+
+typedef struct vdev_phys {
+ char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
+ zio_eck_t vp_zbt;
+} vdev_phys_t;
+
+typedef struct vdev_label {
+ char vl_pad1[VDEV_PAD_SIZE]; /* 8K */
+ char vl_pad2[VDEV_PAD_SIZE]; /* 8K */
+ vdev_phys_t vl_vdev_phys; /* 112K */
+ char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */
+} vdev_label_t; /* 256K total */
+
+/*
+ * vdev_dirty() flags
+ */
+#define VDD_METASLAB 0x01
+#define VDD_DTL 0x02
+
+/*
+ * Size and offset of embedded boot loader region on each label.
+ * The total size of the first two labels plus the boot area is 4MB.
+ */
+#define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t))
+#define VDEV_BOOT_SIZE (7ULL << 19) /* 3.5M */
+
+/*
+ * Size of label regions at the start and end of each leaf device.
+ */
+#define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE)
+#define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t))
+#define VDEV_LABELS 4
+
+enum zio_checksum {
+ ZIO_CHECKSUM_INHERIT = 0,
+ ZIO_CHECKSUM_ON,
+ ZIO_CHECKSUM_OFF,
+ ZIO_CHECKSUM_LABEL,
+ ZIO_CHECKSUM_GANG_HEADER,
+ ZIO_CHECKSUM_ZILOG,
+ ZIO_CHECKSUM_FLETCHER_2,
+ ZIO_CHECKSUM_FLETCHER_4,
+ ZIO_CHECKSUM_SHA256,
+ ZIO_CHECKSUM_ZILOG2,
+ ZIO_CHECKSUM_NOPARITY,
+ ZIO_CHECKSUM_SHA512,
+ ZIO_CHECKSUM_SKEIN,
+ ZIO_CHECKSUM_EDONR,
+ ZIO_CHECKSUM_FUNCTIONS
+};
+
+#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_4
+#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON
+
+enum zio_compress {
+ ZIO_COMPRESS_INHERIT = 0,
+ ZIO_COMPRESS_ON,
+ ZIO_COMPRESS_OFF,
+ ZIO_COMPRESS_LZJB,
+ ZIO_COMPRESS_EMPTY,
+ ZIO_COMPRESS_GZIP_1,
+ ZIO_COMPRESS_GZIP_2,
+ ZIO_COMPRESS_GZIP_3,
+ ZIO_COMPRESS_GZIP_4,
+ ZIO_COMPRESS_GZIP_5,
+ ZIO_COMPRESS_GZIP_6,
+ ZIO_COMPRESS_GZIP_7,
+ ZIO_COMPRESS_GZIP_8,
+ ZIO_COMPRESS_GZIP_9,
+ ZIO_COMPRESS_ZLE,
+ ZIO_COMPRESS_LZ4,
+ ZIO_COMPRESS_FUNCTIONS
+};
+
+#define ZIO_COMPRESS_ON_VALUE ZIO_COMPRESS_LZJB
+#define ZIO_COMPRESS_DEFAULT ZIO_COMPRESS_OFF
+
+/* nvlist pack encoding */
+#define NV_ENCODE_NATIVE 0
+#define NV_ENCODE_XDR 1
+
+typedef enum {
+ DATA_TYPE_UNKNOWN = 0,
+ DATA_TYPE_BOOLEAN,
+ DATA_TYPE_BYTE,
+ DATA_TYPE_INT16,
+ DATA_TYPE_UINT16,
+ DATA_TYPE_INT32,
+ DATA_TYPE_UINT32,
+ DATA_TYPE_INT64,
+ DATA_TYPE_UINT64,
+ DATA_TYPE_STRING,
+ DATA_TYPE_BYTE_ARRAY,
+ DATA_TYPE_INT16_ARRAY,
+ DATA_TYPE_UINT16_ARRAY,
+ DATA_TYPE_INT32_ARRAY,
+ DATA_TYPE_UINT32_ARRAY,
+ DATA_TYPE_INT64_ARRAY,
+ DATA_TYPE_UINT64_ARRAY,
+ DATA_TYPE_STRING_ARRAY,
+ DATA_TYPE_HRTIME,
+ DATA_TYPE_NVLIST,
+ DATA_TYPE_NVLIST_ARRAY,
+ DATA_TYPE_BOOLEAN_VALUE,
+ DATA_TYPE_INT8,
+ DATA_TYPE_UINT8,
+ DATA_TYPE_BOOLEAN_ARRAY,
+ DATA_TYPE_INT8_ARRAY,
+ DATA_TYPE_UINT8_ARRAY
+} data_type_t;
+
+/*
+ * On-disk version number.
+ */
+#define SPA_VERSION_1 1ULL
+#define SPA_VERSION_2 2ULL
+#define SPA_VERSION_3 3ULL
+#define SPA_VERSION_4 4ULL
+#define SPA_VERSION_5 5ULL
+#define SPA_VERSION_6 6ULL
+#define SPA_VERSION_7 7ULL
+#define SPA_VERSION_8 8ULL
+#define SPA_VERSION_9 9ULL
+#define SPA_VERSION_10 10ULL
+#define SPA_VERSION_11 11ULL
+#define SPA_VERSION_12 12ULL
+#define SPA_VERSION_13 13ULL
+#define SPA_VERSION_14 14ULL
+#define SPA_VERSION_15 15ULL
+#define SPA_VERSION_16 16ULL
+#define SPA_VERSION_17 17ULL
+#define SPA_VERSION_18 18ULL
+#define SPA_VERSION_19 19ULL
+#define SPA_VERSION_20 20ULL
+#define SPA_VERSION_21 21ULL
+#define SPA_VERSION_22 22ULL
+#define SPA_VERSION_23 23ULL
+#define SPA_VERSION_24 24ULL
+#define SPA_VERSION_25 25ULL
+#define SPA_VERSION_26 26ULL
+#define SPA_VERSION_27 27ULL
+#define SPA_VERSION_28 28ULL
+#define SPA_VERSION_5000 5000ULL
+
+/*
+ * When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
+ * format change. Go to usr/src/grub/grub-0.97/stage2/{zfs-include/, fsys_zfs*},
+ * and do the appropriate changes. Also bump the version number in
+ * usr/src/grub/capability.
+ */
+#define SPA_VERSION SPA_VERSION_5000
+#define SPA_VERSION_STRING "5000"
+
+/*
+ * Symbolic names for the changes that caused a SPA_VERSION switch.
+ * Used in the code when checking for presence or absence of a feature.
+ * Feel free to define multiple symbolic names for each version if there
+ * were multiple changes to on-disk structures during that version.
+ *
+ * NOTE: When checking the current SPA_VERSION in your code, be sure
+ * to use spa_version() since it reports the version of the
+ * last synced uberblock. Checking the in-flight version can
+ * be dangerous in some cases.
+ */
+#define SPA_VERSION_INITIAL SPA_VERSION_1
+#define SPA_VERSION_DITTO_BLOCKS SPA_VERSION_2
+#define SPA_VERSION_SPARES SPA_VERSION_3
+#define SPA_VERSION_RAID6 SPA_VERSION_3
+#define SPA_VERSION_BPLIST_ACCOUNT SPA_VERSION_3
+#define SPA_VERSION_RAIDZ_DEFLATE SPA_VERSION_3
+#define SPA_VERSION_DNODE_BYTES SPA_VERSION_3
+#define SPA_VERSION_ZPOOL_HISTORY SPA_VERSION_4
+#define SPA_VERSION_GZIP_COMPRESSION SPA_VERSION_5
+#define SPA_VERSION_BOOTFS SPA_VERSION_6
+#define SPA_VERSION_SLOGS SPA_VERSION_7
+#define SPA_VERSION_DELEGATED_PERMS SPA_VERSION_8
+#define SPA_VERSION_FUID SPA_VERSION_9
+#define SPA_VERSION_REFRESERVATION SPA_VERSION_9
+#define SPA_VERSION_REFQUOTA SPA_VERSION_9
+#define SPA_VERSION_UNIQUE_ACCURATE SPA_VERSION_9
+#define SPA_VERSION_L2CACHE SPA_VERSION_10
+#define SPA_VERSION_NEXT_CLONES SPA_VERSION_11
+#define SPA_VERSION_ORIGIN SPA_VERSION_11
+#define SPA_VERSION_DSL_SCRUB SPA_VERSION_11
+#define SPA_VERSION_SNAP_PROPS SPA_VERSION_12
+#define SPA_VERSION_USED_BREAKDOWN SPA_VERSION_13
+#define SPA_VERSION_PASSTHROUGH_X SPA_VERSION_14
+#define SPA_VERSION_USERSPACE SPA_VERSION_15
+#define SPA_VERSION_STMF_PROP SPA_VERSION_16
+#define SPA_VERSION_RAIDZ3 SPA_VERSION_17
+#define SPA_VERSION_USERREFS SPA_VERSION_18
+#define SPA_VERSION_HOLES SPA_VERSION_19
+#define SPA_VERSION_ZLE_COMPRESSION SPA_VERSION_20
+#define SPA_VERSION_DEDUP SPA_VERSION_21
+#define SPA_VERSION_RECVD_PROPS SPA_VERSION_22
+#define SPA_VERSION_SLIM_ZIL SPA_VERSION_23
+#define SPA_VERSION_SA SPA_VERSION_24
+#define SPA_VERSION_SCAN SPA_VERSION_25
+#define SPA_VERSION_DIR_CLONES SPA_VERSION_26
+#define SPA_VERSION_DEADLISTS SPA_VERSION_26
+#define SPA_VERSION_FAST_SNAP SPA_VERSION_27
+#define SPA_VERSION_MULTI_REPLACE SPA_VERSION_28
+#define SPA_VERSION_BEFORE_FEATURES SPA_VERSION_28
+#define SPA_VERSION_FEATURES SPA_VERSION_5000
+
+#define SPA_VERSION_IS_SUPPORTED(v) \
+ (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \
+ ((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION))
+
+/*
+ * The following are configuration names used in the nvlist describing a pool's
+ * configuration.
+ */
+#define ZPOOL_CONFIG_VERSION "version"
+#define ZPOOL_CONFIG_POOL_NAME "name"
+#define ZPOOL_CONFIG_POOL_STATE "state"
+#define ZPOOL_CONFIG_POOL_TXG "txg"
+#define ZPOOL_CONFIG_POOL_GUID "pool_guid"
+#define ZPOOL_CONFIG_CREATE_TXG "create_txg"
+#define ZPOOL_CONFIG_TOP_GUID "top_guid"
+#define ZPOOL_CONFIG_VDEV_TREE "vdev_tree"
+#define ZPOOL_CONFIG_TYPE "type"
+#define ZPOOL_CONFIG_CHILDREN "children"
+#define ZPOOL_CONFIG_ID "id"
+#define ZPOOL_CONFIG_GUID "guid"
+#define ZPOOL_CONFIG_PATH "path"
+#define ZPOOL_CONFIG_DEVID "devid"
+#define ZPOOL_CONFIG_PHYS_PATH "phys_path"
+#define ZPOOL_CONFIG_METASLAB_ARRAY "metaslab_array"
+#define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift"
+#define ZPOOL_CONFIG_ASHIFT "ashift"
+#define ZPOOL_CONFIG_ASIZE "asize"
+#define ZPOOL_CONFIG_DTL "DTL"
+#define ZPOOL_CONFIG_STATS "stats"
+#define ZPOOL_CONFIG_WHOLE_DISK "whole_disk"
+#define ZPOOL_CONFIG_ERRCOUNT "error_count"
+#define ZPOOL_CONFIG_NOT_PRESENT "not_present"
+#define ZPOOL_CONFIG_SPARES "spares"
+#define ZPOOL_CONFIG_IS_SPARE "is_spare"
+#define ZPOOL_CONFIG_NPARITY "nparity"
+#define ZPOOL_CONFIG_HOSTID "hostid"
+#define ZPOOL_CONFIG_HOSTNAME "hostname"
+#define ZPOOL_CONFIG_IS_LOG "is_log"
+#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
+#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read"
+
+/*
+ * The persistent vdev state is stored as separate values rather than a single
+ * 'vdev_state' entry. This is because a device can be in multiple states, such
+ * as offline and degraded.
+ */
+#define ZPOOL_CONFIG_OFFLINE "offline"
+#define ZPOOL_CONFIG_FAULTED "faulted"
+#define ZPOOL_CONFIG_DEGRADED "degraded"
+#define ZPOOL_CONFIG_REMOVED "removed"
+#define ZPOOL_CONFIG_FRU "fru"
+#define ZPOOL_CONFIG_AUX_STATE "aux_state"
+
+#define VDEV_TYPE_ROOT "root"
+#define VDEV_TYPE_MIRROR "mirror"
+#define VDEV_TYPE_REPLACING "replacing"
+#define VDEV_TYPE_RAIDZ "raidz"
+#define VDEV_TYPE_DISK "disk"
+#define VDEV_TYPE_FILE "file"
+#define VDEV_TYPE_MISSING "missing"
+#define VDEV_TYPE_HOLE "hole"
+#define VDEV_TYPE_SPARE "spare"
+#define VDEV_TYPE_LOG "log"
+#define VDEV_TYPE_L2CACHE "l2cache"
+
+/*
+ * This is needed in userland to report the minimum necessary device size.
+ */
+#define SPA_MINDEVSIZE (64ULL << 20)
+
+/*
+ * The location of the pool configuration repository, shared between kernel and
+ * userland.
+ */
+#define ZPOOL_CACHE "/boot/zfs/zpool.cache"
+
+/*
+ * vdev states are ordered from least to most healthy.
+ * A vdev that's CANT_OPEN or below is considered unusable.
+ */
+typedef enum vdev_state {
+ VDEV_STATE_UNKNOWN = 0, /* Uninitialized vdev */
+ VDEV_STATE_CLOSED, /* Not currently open */
+ VDEV_STATE_OFFLINE, /* Not allowed to open */
+ VDEV_STATE_REMOVED, /* Explicitly removed from system */
+ VDEV_STATE_CANT_OPEN, /* Tried to open, but failed */
+ VDEV_STATE_FAULTED, /* External request to fault device */
+ VDEV_STATE_DEGRADED, /* Replicated vdev with unhealthy kids */
+ VDEV_STATE_HEALTHY /* Presumed good */
+} vdev_state_t;
+
+/*
+ * vdev aux states. When a vdev is in the CANT_OPEN state, the aux field
+ * of the vdev stats structure uses these constants to distinguish why.
+ */
+typedef enum vdev_aux {
+ VDEV_AUX_NONE, /* no error */
+ VDEV_AUX_OPEN_FAILED, /* ldi_open_*() or vn_open() failed */
+ VDEV_AUX_CORRUPT_DATA, /* bad label or disk contents */
+ VDEV_AUX_NO_REPLICAS, /* insufficient number of replicas */
+ VDEV_AUX_BAD_GUID_SUM, /* vdev guid sum doesn't match */
+ VDEV_AUX_TOO_SMALL, /* vdev size is too small */
+ VDEV_AUX_BAD_LABEL, /* the label is OK but invalid */
+ VDEV_AUX_VERSION_NEWER, /* on-disk version is too new */
+ VDEV_AUX_VERSION_OLDER, /* on-disk version is too old */
+ VDEV_AUX_SPARED /* hot spare used in another pool */
+} vdev_aux_t;
+
+/*
+ * pool state. The following states are written to disk as part of the normal
+ * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE. The remaining states are
+ * software abstractions used at various levels to communicate pool state.
+ */
+typedef enum pool_state {
+ POOL_STATE_ACTIVE = 0, /* In active use */
+ POOL_STATE_EXPORTED, /* Explicitly exported */
+ POOL_STATE_DESTROYED, /* Explicitly destroyed */
+ POOL_STATE_SPARE, /* Reserved for hot spare use */
+ POOL_STATE_UNINITIALIZED, /* Internal spa_t state */
+ POOL_STATE_UNAVAIL, /* Internal libzfs state */
+ POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */
+} pool_state_t;
+
+/*
+ * The uberblock version is incremented whenever an incompatible on-disk
+ * format change is made to the SPA, DMU, or ZAP.
+ *
+ * Note: the first two fields should never be moved. When a storage pool
+ * is opened, the uberblock must be read off the disk before the version
+ * can be checked. If the ub_version field is moved, we may not detect
+ * version mismatch. If the ub_magic field is moved, applications that
+ * expect the magic number in the first word won't work.
+ */
+#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */
+#define UBERBLOCK_SHIFT 10 /* up to 1K */
+
+struct uberblock {
+ uint64_t ub_magic; /* UBERBLOCK_MAGIC */
+ uint64_t ub_version; /* SPA_VERSION */
+ uint64_t ub_txg; /* txg of last sync */
+ uint64_t ub_guid_sum; /* sum of all vdev guids */
+ uint64_t ub_timestamp; /* UTC time of last sync */
+ blkptr_t ub_rootbp; /* MOS objset_phys_t */
+};
+
+/*
+ * Flags.
+ */
+#define DNODE_MUST_BE_ALLOCATED 1
+#define DNODE_MUST_BE_FREE 2
+
+/*
+ * Fixed constants.
+ */
+#define DNODE_SHIFT 9 /* 512 bytes */
+#define DN_MIN_INDBLKSHIFT 12 /* 4k */
+#define DN_MAX_INDBLKSHIFT 14 /* 16k */
+#define DNODE_BLOCK_SHIFT 14 /* 16k */
+#define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */
+#define DN_MAX_OBJECT_SHIFT 48 /* 256 trillion (zfs_fid_t limit) */
+#define DN_MAX_OFFSET_SHIFT 64 /* 2^64 bytes in a dnode */
+
+/*
+ * Derived constants.
+ */
+#define DNODE_SIZE (1 << DNODE_SHIFT)
+#define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT)
+#define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT))
+#define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT)
+
+#define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT)
+#define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT)
+#define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT)
+
+/* The +2 here is a cheesy way to round up */
+#define DN_MAX_LEVELS (2 + ((DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT) / \
+ (DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT)))
+
+#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \
+ (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t))))
+
+#define DN_USED_BYTES(dnp) (((dnp)->dn_flags & DNODE_FLAG_USED_BYTES) ? \
+ (dnp)->dn_used : (dnp)->dn_used << SPA_MINBLOCKSHIFT)
+
+#define EPB(blkshift, typeshift) (1 << (blkshift - typeshift))
+
+/* Is dn_used in bytes? if not, it's in multiples of SPA_MINBLOCKSIZE */
+#define DNODE_FLAG_USED_BYTES (1<<0)
+#define DNODE_FLAG_USERUSED_ACCOUNTED (1<<1)
+
+/* Does dnode have a SA spill blkptr in bonus? */
+#define DNODE_FLAG_SPILL_BLKPTR (1<<2)
+
+typedef struct dnode_phys {
+ uint8_t dn_type; /* dmu_object_type_t */
+ uint8_t dn_indblkshift; /* ln2(indirect block size) */
+ uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */
+ uint8_t dn_nblkptr; /* length of dn_blkptr */
+ uint8_t dn_bonustype; /* type of data in bonus buffer */
+ uint8_t dn_checksum; /* ZIO_CHECKSUM type */
+ uint8_t dn_compress; /* ZIO_COMPRESS type */
+ uint8_t dn_flags; /* DNODE_FLAG_* */
+ uint16_t dn_datablkszsec; /* data block size in 512b sectors */
+ uint16_t dn_bonuslen; /* length of dn_bonus */
+ uint8_t dn_pad2[4];
+
+ /* accounting is protected by dn_dirty_mtx */
+ uint64_t dn_maxblkid; /* largest allocated block ID */
+ uint64_t dn_used; /* bytes (or sectors) of disk space */
+
+ uint64_t dn_pad3[4];
+
+ blkptr_t dn_blkptr[1];
+ uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)];
+ blkptr_t dn_spill;
+} dnode_phys_t;
+
+typedef enum dmu_object_byteswap {
+ DMU_BSWAP_UINT8,
+ DMU_BSWAP_UINT16,
+ DMU_BSWAP_UINT32,
+ DMU_BSWAP_UINT64,
+ DMU_BSWAP_ZAP,
+ DMU_BSWAP_DNODE,
+ DMU_BSWAP_OBJSET,
+ DMU_BSWAP_ZNODE,
+ DMU_BSWAP_OLDACL,
+ DMU_BSWAP_ACL,
+ /*
+ * Allocating a new byteswap type number makes the on-disk format
+ * incompatible with any other format that uses the same number.
+ *
+ * Data can usually be structured to work with one of the
+ * DMU_BSWAP_UINT* or DMU_BSWAP_ZAP types.
+ */
+ DMU_BSWAP_NUMFUNCS
+} dmu_object_byteswap_t;
+
+#define DMU_OT_NEWTYPE 0x80
+#define DMU_OT_METADATA 0x40
+#define DMU_OT_BYTESWAP_MASK 0x3f
+
+/*
+ * Defines a uint8_t object type. Object types specify if the data
+ * in the object is metadata (boolean) and how to byteswap the data
+ * (dmu_object_byteswap_t).
+ */
+#define DMU_OT(byteswap, metadata) \
+ (DMU_OT_NEWTYPE | \
+ ((metadata) ? DMU_OT_METADATA : 0) | \
+ ((byteswap) & DMU_OT_BYTESWAP_MASK))
+
+typedef enum dmu_object_type {
+ DMU_OT_NONE,
+ /* general: */
+ DMU_OT_OBJECT_DIRECTORY, /* ZAP */
+ DMU_OT_OBJECT_ARRAY, /* UINT64 */
+ DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */
+ DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */
+ DMU_OT_BPLIST, /* UINT64 */
+ DMU_OT_BPLIST_HDR, /* UINT64 */
+ /* spa: */
+ DMU_OT_SPACE_MAP_HEADER, /* UINT64 */
+ DMU_OT_SPACE_MAP, /* UINT64 */
+ /* zil: */
+ DMU_OT_INTENT_LOG, /* UINT64 */
+ /* dmu: */
+ DMU_OT_DNODE, /* DNODE */
+ DMU_OT_OBJSET, /* OBJSET */
+ /* dsl: */
+ DMU_OT_DSL_DIR, /* UINT64 */
+ DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */
+ DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */
+ DMU_OT_DSL_PROPS, /* ZAP */
+ DMU_OT_DSL_DATASET, /* UINT64 */
+ /* zpl: */
+ DMU_OT_ZNODE, /* ZNODE */
+ DMU_OT_OLDACL, /* Old ACL */
+ DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */
+ DMU_OT_DIRECTORY_CONTENTS, /* ZAP */
+ DMU_OT_MASTER_NODE, /* ZAP */
+ DMU_OT_UNLINKED_SET, /* ZAP */
+ /* zvol: */
+ DMU_OT_ZVOL, /* UINT8 */
+ DMU_OT_ZVOL_PROP, /* ZAP */
+ /* other; for testing only! */
+ DMU_OT_PLAIN_OTHER, /* UINT8 */
+ DMU_OT_UINT64_OTHER, /* UINT64 */
+ DMU_OT_ZAP_OTHER, /* ZAP */
+ /* new object types: */
+ DMU_OT_ERROR_LOG, /* ZAP */
+ DMU_OT_SPA_HISTORY, /* UINT8 */
+ DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */
+ DMU_OT_POOL_PROPS, /* ZAP */
+ DMU_OT_DSL_PERMS, /* ZAP */
+ DMU_OT_ACL, /* ACL */
+ DMU_OT_SYSACL, /* SYSACL */
+ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */
+ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */
+ DMU_OT_NEXT_CLONES, /* ZAP */
+ DMU_OT_SCAN_QUEUE, /* ZAP */
+ DMU_OT_USERGROUP_USED, /* ZAP */
+ DMU_OT_USERGROUP_QUOTA, /* ZAP */
+ DMU_OT_USERREFS, /* ZAP */
+ DMU_OT_DDT_ZAP, /* ZAP */
+ DMU_OT_DDT_STATS, /* ZAP */
+ DMU_OT_SA, /* System attr */
+ DMU_OT_SA_MASTER_NODE, /* ZAP */
+ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */
+ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */
+ DMU_OT_SCAN_XLATE, /* ZAP */
+ DMU_OT_DEDUP, /* fake dedup BP from ddt_bp_create() */
+ DMU_OT_NUMTYPES,
+
+ /*
+ * Names for valid types declared with DMU_OT().
+ */
+ DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE),
+ DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE),
+ DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE),
+ DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE),
+ DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE),
+ DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE),
+ DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE),
+ DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE),
+ DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE),
+ DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE)
+} dmu_object_type_t;
+
+typedef enum dmu_objset_type {
+ DMU_OST_NONE,
+ DMU_OST_META,
+ DMU_OST_ZFS,
+ DMU_OST_ZVOL,
+ DMU_OST_OTHER, /* For testing only! */
+ DMU_OST_ANY, /* Be careful! */
+ DMU_OST_NUMTYPES
+} dmu_objset_type_t;
+
+/*
+ * header for all bonus and spill buffers.
+ * The header has a fixed portion with a variable number
+ * of "lengths" depending on the number of variable sized
+ * attribues which are determined by the "layout number"
+ */
+
+#define SA_MAGIC 0x2F505A /* ZFS SA */
+typedef struct sa_hdr_phys {
+ uint32_t sa_magic;
+ uint16_t sa_layout_info; /* Encoded with hdrsize and layout number */
+ uint16_t sa_lengths[1]; /* optional sizes for variable length attrs */
+ /* ... Data follows the lengths. */
+} sa_hdr_phys_t;
+
+/*
+ * sa_hdr_phys -> sa_layout_info
+ *
+ * 16 10 0
+ * +--------+-------+
+ * | hdrsz |layout |
+ * +--------+-------+
+ *
+ * Bits 0-10 are the layout number
+ * Bits 11-16 are the size of the header.
+ * The hdrsize is the number * 8
+ *
+ * For example.
+ * hdrsz of 1 ==> 8 byte header
+ * 2 ==> 16 byte header
+ *
+ */
+
+#define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10)
+#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
+#define SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \
+{ \
+ BF32_SET_SB(x, 10, 6, 3, 0, size); \
+ BF32_SET(x, 0, 10, num); \
+}
+
+#define SA_MODE_OFFSET 0
+#define SA_SIZE_OFFSET 8
+#define SA_GEN_OFFSET 16
+#define SA_UID_OFFSET 24
+#define SA_GID_OFFSET 32
+#define SA_PARENT_OFFSET 40
+
+/*
+ * Intent log header - this on disk structure holds fields to manage
+ * the log. All fields are 64 bit to easily handle cross architectures.
+ */
+typedef struct zil_header {
+ uint64_t zh_claim_txg; /* txg in which log blocks were claimed */
+ uint64_t zh_replay_seq; /* highest replayed sequence number */
+ blkptr_t zh_log; /* log chain */
+ uint64_t zh_claim_seq; /* highest claimed sequence number */
+ uint64_t zh_pad[5];
+} zil_header_t;
+
+#define OBJSET_PHYS_SIZE 2048
+
+typedef struct objset_phys {
+ dnode_phys_t os_meta_dnode;
+ zil_header_t os_zil_header;
+ uint64_t os_type;
+ uint64_t os_flags;
+ char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 -
+ sizeof (zil_header_t) - sizeof (uint64_t)*2];
+ dnode_phys_t os_userused_dnode;
+ dnode_phys_t os_groupused_dnode;
+} objset_phys_t;
+
+typedef struct dsl_dir_phys {
+ uint64_t dd_creation_time; /* not actually used */
+ uint64_t dd_head_dataset_obj;
+ uint64_t dd_parent_obj;
+ uint64_t dd_clone_parent_obj;
+ uint64_t dd_child_dir_zapobj;
+ /*
+ * how much space our children are accounting for; for leaf
+ * datasets, == physical space used by fs + snaps
+ */
+ uint64_t dd_used_bytes;
+ uint64_t dd_compressed_bytes;
+ uint64_t dd_uncompressed_bytes;
+ /* Administrative quota setting */
+ uint64_t dd_quota;
+ /* Administrative reservation setting */
+ uint64_t dd_reserved;
+ uint64_t dd_props_zapobj;
+ uint64_t dd_pad[21]; /* pad out to 256 bytes for good measure */
+} dsl_dir_phys_t;
+
+typedef struct dsl_dataset_phys {
+ uint64_t ds_dir_obj;
+ uint64_t ds_prev_snap_obj;
+ uint64_t ds_prev_snap_txg;
+ uint64_t ds_next_snap_obj;
+ uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */
+ uint64_t ds_num_children; /* clone/snap children; ==0 for head */
+ uint64_t ds_creation_time; /* seconds since 1970 */
+ uint64_t ds_creation_txg;
+ uint64_t ds_deadlist_obj;
+ uint64_t ds_used_bytes;
+ uint64_t ds_compressed_bytes;
+ uint64_t ds_uncompressed_bytes;
+ uint64_t ds_unique_bytes; /* only relevant to snapshots */
+ /*
+ * The ds_fsid_guid is a 56-bit ID that can change to avoid
+ * collisions. The ds_guid is a 64-bit ID that will never
+ * change, so there is a small probability that it will collide.
+ */
+ uint64_t ds_fsid_guid;
+ uint64_t ds_guid;
+ uint64_t ds_flags;
+ blkptr_t ds_bp;
+ uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */
+} dsl_dataset_phys_t;
+
+/*
+ * The names of zap entries in the DIRECTORY_OBJECT of the MOS.
+ */
+#define DMU_POOL_DIRECTORY_OBJECT 1
+#define DMU_POOL_CONFIG "config"
+#define DMU_POOL_FEATURES_FOR_READ "features_for_read"
+#define DMU_POOL_ROOT_DATASET "root_dataset"
+#define DMU_POOL_SYNC_BPLIST "sync_bplist"
+#define DMU_POOL_ERRLOG_SCRUB "errlog_scrub"
+#define DMU_POOL_ERRLOG_LAST "errlog_last"
+#define DMU_POOL_SPARES "spares"
+#define DMU_POOL_DEFLATE "deflate"
+#define DMU_POOL_HISTORY "history"
+#define DMU_POOL_PROPS "pool_props"
+
+#define ZAP_MAGIC 0x2F52AB2ABULL
+
+#define FZAP_BLOCK_SHIFT(zap) ((zap)->zap_block_shift)
+
+#define ZAP_MAXCD (uint32_t)(-1)
+#define ZAP_HASHBITS 28
+#define MZAP_ENT_LEN 64
+#define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2)
+#define MZAP_MAX_BLKSHIFT SPA_MAXBLOCKSHIFT
+#define MZAP_MAX_BLKSZ (1 << MZAP_MAX_BLKSHIFT)
+
+typedef struct mzap_ent_phys {
+ uint64_t mze_value;
+ uint32_t mze_cd;
+ uint16_t mze_pad; /* in case we want to chain them someday */
+ char mze_name[MZAP_NAME_LEN];
+} mzap_ent_phys_t;
+
+typedef struct mzap_phys {
+ uint64_t mz_block_type; /* ZBT_MICRO */
+ uint64_t mz_salt;
+ uint64_t mz_pad[6];
+ mzap_ent_phys_t mz_chunk[1];
+ /* actually variable size depending on block size */
+} mzap_phys_t;
+
+/*
+ * The (fat) zap is stored in one object. It is an array of
+ * 1<<FZAP_BLOCK_SHIFT byte blocks. The layout looks like one of:
+ *
+ * ptrtbl fits in first block:
+ * [zap_phys_t zap_ptrtbl_shift < 6] [zap_leaf_t] ...
+ *
+ * ptrtbl too big for first block:
+ * [zap_phys_t zap_ptrtbl_shift >= 6] [zap_leaf_t] [ptrtbl] ...
+ *
+ */
+
+#define ZBT_LEAF ((1ULL << 63) + 0)
+#define ZBT_HEADER ((1ULL << 63) + 1)
+#define ZBT_MICRO ((1ULL << 63) + 3)
+/* any other values are ptrtbl blocks */
+
+/*
+ * the embedded pointer table takes up half a block:
+ * block size / entry size (2^3) / 2
+ */
+#define ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1)
+
+/*
+ * The embedded pointer table starts half-way through the block. Since
+ * the pointer table itself is half the block, it starts at (64-bit)
+ * word number (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)).
+ */
+#define ZAP_EMBEDDED_PTRTBL_ENT(zap, idx) \
+ ((uint64_t *)(zap)->zap_phys) \
+ [(idx) + (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap))]
+
+/*
+ * TAKE NOTE:
+ * If zap_phys_t is modified, zap_byteswap() must be modified.
+ */
+typedef struct zap_phys {
+ uint64_t zap_block_type; /* ZBT_HEADER */
+ uint64_t zap_magic; /* ZAP_MAGIC */
+
+ struct zap_table_phys {
+ uint64_t zt_blk; /* starting block number */
+ uint64_t zt_numblks; /* number of blocks */
+ uint64_t zt_shift; /* bits to index it */
+ uint64_t zt_nextblk; /* next (larger) copy start block */
+ uint64_t zt_blks_copied; /* number source blocks copied */
+ } zap_ptrtbl;
+
+ uint64_t zap_freeblk; /* the next free block */
+ uint64_t zap_num_leafs; /* number of leafs */
+ uint64_t zap_num_entries; /* number of entries */
+ uint64_t zap_salt; /* salt to stir into hash function */
+ /*
+ * This structure is followed by padding, and then the embedded
+ * pointer table. The embedded pointer table takes up second
+ * half of the block. It is accessed using the
+ * ZAP_EMBEDDED_PTRTBL_ENT() macro.
+ */
+} zap_phys_t;
+
+typedef struct zap_table_phys zap_table_phys_t;
+
+typedef struct fat_zap {
+ int zap_block_shift; /* block size shift */
+ zap_phys_t *zap_phys;
+} fat_zap_t;
+
+#define ZAP_LEAF_MAGIC 0x2AB1EAF
+
+/* chunk size = 24 bytes */
+#define ZAP_LEAF_CHUNKSIZE 24
+
+/*
+ * The amount of space available for chunks is:
+ * block size (1<<l->l_bs) - hash entry size (2) * number of hash
+ * entries - header space (2*chunksize)
+ */
+#define ZAP_LEAF_NUMCHUNKS(l) \
+ (((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \
+ ZAP_LEAF_CHUNKSIZE - 2)
+
+/*
+ * The amount of space within the chunk available for the array is:
+ * chunk size - space for type (1) - space for next pointer (2)
+ */
+#define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
+
+#define ZAP_LEAF_ARRAY_NCHUNKS(bytes) \
+ (((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES)
+
+/*
+ * Low water mark: when there are only this many chunks free, start
+ * growing the ptrtbl. Ideally, this should be larger than a
+ * "reasonably-sized" entry. 20 chunks is more than enough for the
+ * largest directory entry (MAXNAMELEN (256) byte name, 8-byte value),
+ * while still being only around 3% for 16k blocks.
+ */
+#define ZAP_LEAF_LOW_WATER (20)
+
+/*
+ * The leaf hash table has block size / 2^5 (32) number of entries,
+ * which should be more than enough for the maximum number of entries,
+ * which is less than block size / CHUNKSIZE (24) / minimum number of
+ * chunks per entry (3).
+ */
+#define ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5)
+#define ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l))
+
+/*
+ * The chunks start immediately after the hash table. The end of the
+ * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
+ * chunk_t.
+ */
+#define ZAP_LEAF_CHUNK(l, idx) \
+ ((zap_leaf_chunk_t *) \
+ ((l)->l_phys->l_hash + ZAP_LEAF_HASH_NUMENTRIES(l)))[idx]
+#define ZAP_LEAF_ENTRY(l, idx) (&ZAP_LEAF_CHUNK(l, idx).l_entry)
+
+typedef enum zap_chunk_type {
+ ZAP_CHUNK_FREE = 253,
+ ZAP_CHUNK_ENTRY = 252,
+ ZAP_CHUNK_ARRAY = 251,
+ ZAP_CHUNK_TYPE_MAX = 250
+} zap_chunk_type_t;
+
+/*
+ * TAKE NOTE:
+ * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
+ */
+typedef struct zap_leaf_phys {
+ struct zap_leaf_header {
+ uint64_t lh_block_type; /* ZBT_LEAF */
+ uint64_t lh_pad1;
+ uint64_t lh_prefix; /* hash prefix of this leaf */
+ uint32_t lh_magic; /* ZAP_LEAF_MAGIC */
+ uint16_t lh_nfree; /* number free chunks */
+ uint16_t lh_nentries; /* number of entries */
+ uint16_t lh_prefix_len; /* num bits used to id this */
+
+/* above is accessable to zap, below is zap_leaf private */
+
+ uint16_t lh_freelist; /* chunk head of free list */
+ uint8_t lh_pad2[12];
+ } l_hdr; /* 2 24-byte chunks */
+
+ /*
+ * The header is followed by a hash table with
+ * ZAP_LEAF_HASH_NUMENTRIES(zap) entries. The hash table is
+ * followed by an array of ZAP_LEAF_NUMCHUNKS(zap)
+ * zap_leaf_chunk structures. These structures are accessed
+ * with the ZAP_LEAF_CHUNK() macro.
+ */
+
+ uint16_t l_hash[1];
+} zap_leaf_phys_t;
+
+typedef union zap_leaf_chunk {
+ struct zap_leaf_entry {
+ uint8_t le_type; /* always ZAP_CHUNK_ENTRY */
+ uint8_t le_value_intlen; /* size of ints */
+ uint16_t le_next; /* next entry in hash chain */
+ uint16_t le_name_chunk; /* first chunk of the name */
+ uint16_t le_name_numints; /* bytes in name, incl null */
+ uint16_t le_value_chunk; /* first chunk of the value */
+ uint16_t le_value_numints; /* value length in ints */
+ uint32_t le_cd; /* collision differentiator */
+ uint64_t le_hash; /* hash value of the name */
+ } l_entry;
+ struct zap_leaf_array {
+ uint8_t la_type; /* always ZAP_CHUNK_ARRAY */
+ uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
+ uint16_t la_next; /* next blk or CHAIN_END */
+ } l_array;
+ struct zap_leaf_free {
+ uint8_t lf_type; /* always ZAP_CHUNK_FREE */
+ uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
+ uint16_t lf_next; /* next in free list, or CHAIN_END */
+ } l_free;
+} zap_leaf_chunk_t;
+
+typedef struct zap_leaf {
+ int l_bs; /* block size shift */
+ zap_leaf_phys_t *l_phys;
+} zap_leaf_t;
+
+/*
+ * Define special zfs pflags
+ */
+#define ZFS_XATTR 0x1 /* is an extended attribute */
+#define ZFS_INHERIT_ACE 0x2 /* ace has inheritable ACEs */
+#define ZFS_ACL_TRIVIAL 0x4 /* files ACL is trivial */
+
+#define MASTER_NODE_OBJ 1
+
+/*
+ * special attributes for master node.
+ */
+
+#define ZFS_FSID "FSID"
+#define ZFS_UNLINKED_SET "DELETE_QUEUE"
+#define ZFS_ROOT_OBJ "ROOT"
+#define ZPL_VERSION_OBJ "VERSION"
+#define ZFS_PROP_BLOCKPERPAGE "BLOCKPERPAGE"
+#define ZFS_PROP_NOGROWBLOCKS "NOGROWBLOCKS"
+
+#define ZFS_FLAG_BLOCKPERPAGE 0x1
+#define ZFS_FLAG_NOGROWBLOCKS 0x2
+
+/*
+ * ZPL version - rev'd whenever an incompatible on-disk format change
+ * occurs. Independent of SPA/DMU/ZAP versioning.
+ */
+
+#define ZPL_VERSION 1ULL
+
+/*
+ * The directory entry has the type (currently unused on Solaris) in the
+ * top 4 bits, and the object number in the low 48 bits. The "middle"
+ * 12 bits are unused.
+ */
+#define ZFS_DIRENT_TYPE(de) BF64_GET(de, 60, 4)
+#define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48)
+#define ZFS_DIRENT_MAKE(type, obj) (((uint64_t)type << 60) | obj)
+
+typedef struct ace {
+ uid_t a_who; /* uid or gid */
+ uint32_t a_access_mask; /* read,write,... */
+ uint16_t a_flags; /* see below */
+ uint16_t a_type; /* allow or deny */
+} ace_t;
+
+#define ACE_SLOT_CNT 6
+
+typedef struct zfs_znode_acl {
+ uint64_t z_acl_extern_obj; /* ext acl pieces */
+ uint32_t z_acl_count; /* Number of ACEs */
+ uint16_t z_acl_version; /* acl version */
+ uint16_t z_acl_pad; /* pad */
+ ace_t z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */
+} zfs_znode_acl_t;
+
+/*
+ * This is the persistent portion of the znode. It is stored
+ * in the "bonus buffer" of the file. Short symbolic links
+ * are also stored in the bonus buffer.
+ */
+typedef struct znode_phys {
+ uint64_t zp_atime[2]; /* 0 - last file access time */
+ uint64_t zp_mtime[2]; /* 16 - last file modification time */
+ uint64_t zp_ctime[2]; /* 32 - last file change time */
+ uint64_t zp_crtime[2]; /* 48 - creation time */
+ uint64_t zp_gen; /* 64 - generation (txg of creation) */
+ uint64_t zp_mode; /* 72 - file mode bits */
+ uint64_t zp_size; /* 80 - size of file */
+ uint64_t zp_parent; /* 88 - directory parent (`..') */
+ uint64_t zp_links; /* 96 - number of links to file */
+ uint64_t zp_xattr; /* 104 - DMU object for xattrs */
+ uint64_t zp_rdev; /* 112 - dev_t for VBLK & VCHR files */
+ uint64_t zp_flags; /* 120 - persistent flags */
+ uint64_t zp_uid; /* 128 - file owner */
+ uint64_t zp_gid; /* 136 - owning group */
+ uint64_t zp_pad[4]; /* 144 - future */
+ zfs_znode_acl_t zp_acl; /* 176 - 263 ACL */
+ /*
+ * Data may pad out any remaining bytes in the znode buffer, eg:
+ *
+ * |<---------------------- dnode_phys (512) ------------------------>|
+ * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->|
+ * |<---- znode (264) ---->|<---- data (56) ---->|
+ *
+ * At present, we only use this space to store symbolic links.
+ */
+} znode_phys_t;
+
+/*
+ * In-core vdev representation.
+ */
+struct vdev;
+typedef int vdev_phys_read_t(struct vdev *vdev, void *priv,
+ off_t offset, void *buf, size_t bytes);
+typedef int vdev_read_t(struct vdev *vdev, const blkptr_t *bp,
+ void *buf, off_t offset, size_t bytes);
+
+typedef STAILQ_HEAD(vdev_list, vdev) vdev_list_t;
+
+typedef struct vdev {
+ STAILQ_ENTRY(vdev) v_childlink; /* link in parent's child list */
+ STAILQ_ENTRY(vdev) v_alllink; /* link in global vdev list */
+ vdev_list_t v_children; /* children of this vdev */
+ const char *v_name; /* vdev name */
+ const char *v_phys_path; /* vdev bootpath */
+ const char *v_devid; /* vdev devid */
+ uint64_t v_guid; /* vdev guid */
+ int v_id; /* index in parent */
+ int v_ashift; /* offset to block shift */
+ int v_nparity; /* # parity for raidz */
+ struct vdev *v_top; /* parent vdev */
+ int v_nchildren; /* # children */
+ vdev_state_t v_state; /* current state */
+ vdev_phys_read_t *v_phys_read; /* read from raw leaf vdev */
+ vdev_read_t *v_read; /* read from vdev */
+ void *v_read_priv; /* private data for read function */
+} vdev_t;
+
+/*
+ * In-core pool representation.
+ */
+typedef STAILQ_HEAD(spa_list, spa) spa_list_t;
+
+typedef struct spa {
+ STAILQ_ENTRY(spa) spa_link; /* link in global pool list */
+ char *spa_name; /* pool name */
+ uint64_t spa_guid; /* pool guid */
+ uint64_t spa_txg; /* most recent transaction */
+ struct uberblock spa_uberblock; /* best uberblock so far */
+ vdev_list_t spa_vdevs; /* list of all toplevel vdevs */
+ objset_phys_t spa_mos; /* MOS for this pool */
+ int spa_inited; /* initialized */
+} spa_t;
+
+static void decode_embedded_bp_compressed(const blkptr_t *, void *);
diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c b/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c
new file mode 100644
index 0000000000..30d6a71e8d
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c
@@ -0,0 +1,1767 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/cdefs.h>
+
+static uint64_t zfs_crc64_table[256];
+
+#define ECKSUM 666
+
+#define ASSERT3S(x, y, z) ((void)0)
+#define ASSERT3U(x, y, z) ((void)0)
+#define ASSERT3P(x, y, z) ((void)0)
+#define ASSERT0(x) ((void)0)
+#define ASSERT(x) ((void)0)
+
+#define panic(...) do { \
+ printf(__VA_ARGS__); \
+ for (;;) ; \
+} while (0)
+
+#define kmem_alloc(size, flag) zfs_alloc((size))
+#define kmem_free(ptr, size) zfs_free((ptr), (size))
+
+static void
+zfs_init_crc(void)
+{
+ int i, j;
+ uint64_t *ct;
+
+ /*
+ * Calculate the crc64 table (used for the zap hash
+ * function).
+ */
+ if (zfs_crc64_table[128] != ZFS_CRC64_POLY) {
+ memset(zfs_crc64_table, 0, sizeof(zfs_crc64_table));
+ for (i = 0; i < 256; i++)
+ for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--)
+ *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY);
+ }
+}
+
+static void
+zio_checksum_off(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
+}
+
+/*
+ * Signature for checksum functions.
+ */
+typedef void zio_checksum_t(const void *data, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp);
+typedef void *zio_checksum_tmpl_init_t(const zio_cksum_salt_t *salt);
+typedef void zio_checksum_tmpl_free_t(void *ctx_template);
+
+typedef enum zio_checksum_flags {
+ /* Strong enough for metadata? */
+ ZCHECKSUM_FLAG_METADATA = (1 << 1),
+ /* ZIO embedded checksum */
+ ZCHECKSUM_FLAG_EMBEDDED = (1 << 2),
+ /* Strong enough for dedup (without verification)? */
+ ZCHECKSUM_FLAG_DEDUP = (1 << 3),
+ /* Uses salt value */
+ ZCHECKSUM_FLAG_SALTED = (1 << 4),
+ /* Strong enough for nopwrite? */
+ ZCHECKSUM_FLAG_NOPWRITE = (1 << 5)
+} zio_checksum_flags_t;
+
+/*
+ * Information about each checksum function.
+ */
+typedef struct zio_checksum_info {
+ /* checksum function for each byteorder */
+ zio_checksum_t *ci_func[2];
+ zio_checksum_tmpl_init_t *ci_tmpl_init;
+ zio_checksum_tmpl_free_t *ci_tmpl_free;
+ zio_checksum_flags_t ci_flags;
+ const char *ci_name; /* descriptive name */
+} zio_checksum_info_t;
+
+#include "blkptr.c"
+
+#include "fletcher.c"
+#include "sha256.c"
+
+static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
+ {{NULL, NULL}, NULL, NULL, 0, "inherit"},
+ {{NULL, NULL}, NULL, NULL, 0, "on"},
+ {{zio_checksum_off, zio_checksum_off}, NULL, NULL, 0, "off"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "label"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "gang_header"},
+ {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_EMBEDDED, "zilog"},
+ {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL,
+ 0, "fletcher2"},
+ {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA, "fletcher4"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+ ZCHECKSUM_FLAG_NOPWRITE, "SHA256"},
+ {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_EMBEDDED, "zillog2"},
+ {{zio_checksum_off, zio_checksum_off}, NULL, NULL,
+ 0, "noparity"},
+ {{zio_checksum_SHA512_native, zio_checksum_SHA512_byteswap},
+ NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+ ZCHECKSUM_FLAG_NOPWRITE, "SHA512"},
+ /* no skein and edonr for now */
+ {{NULL, NULL}, NULL, NULL, ZCHECKSUM_FLAG_METADATA |
+ ZCHECKSUM_FLAG_DEDUP | ZCHECKSUM_FLAG_SALTED |
+ ZCHECKSUM_FLAG_NOPWRITE, "skein"},
+ {{NULL, NULL}, NULL, NULL, ZCHECKSUM_FLAG_METADATA |
+ ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"},
+};
+
+/*
+ * Common signature for all zio compress/decompress functions.
+ */
+typedef size_t zio_compress_func_t(void *src, void *dst,
+ size_t s_len, size_t d_len, int);
+typedef int zio_decompress_func_t(void *src, void *dst,
+ size_t s_len, size_t d_len, int);
+
+extern int gzip_decompress(void *src, void *dst,
+ size_t s_len, size_t d_len, int);
+/*
+ * Information about each compression function.
+ */
+typedef struct zio_compress_info {
+ zio_compress_func_t *ci_compress; /* compression function */
+ zio_decompress_func_t *ci_decompress; /* decompression function */
+ int ci_level; /* level parameter */
+ const char *ci_name; /* algorithm name */
+} zio_compress_info_t;
+
+#include "lzjb.c"
+#include "zle.c"
+#include "lz4.c"
+
+/*
+ * Compression vectors.
+ */
+static zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
+ {NULL, NULL, 0, "inherit"},
+ {NULL, NULL, 0, "on"},
+ {NULL, NULL, 0, "uncompressed"},
+ {NULL, lzjb_decompress, 0, "lzjb"},
+ {NULL, NULL, 0, "empty"},
+ {NULL, gzip_decompress, 1, "gzip-1"},
+ {NULL, gzip_decompress, 2, "gzip-2"},
+ {NULL, gzip_decompress, 3, "gzip-3"},
+ {NULL, gzip_decompress, 4, "gzip-4"},
+ {NULL, gzip_decompress, 5, "gzip-5"},
+ {NULL, gzip_decompress, 6, "gzip-6"},
+ {NULL, gzip_decompress, 7, "gzip-7"},
+ {NULL, gzip_decompress, 8, "gzip-8"},
+ {NULL, gzip_decompress, 9, "gzip-9"},
+ {NULL, zle_decompress, 64, "zle"},
+ {NULL, lz4_decompress, 0, "lz4"},
+};
+
+static void
+byteswap_uint64_array(void *vbuf, size_t size)
+{
+ uint64_t *buf = vbuf;
+ size_t count = size >> 3;
+ int i;
+
+ ASSERT((size & 7) == 0);
+
+ for (i = 0; i < count; i++)
+ buf[i] = BSWAP_64(buf[i]);
+}
+
+/*
+ * Set the external verifier for a gang block based on <vdev, offset, txg>,
+ * a tuple which is guaranteed to be unique for the life of the pool.
+ */
+static void
+zio_checksum_gang_verifier(zio_cksum_t *zcp, const blkptr_t *bp)
+{
+ const dva_t *dva = BP_IDENTITY(bp);
+ uint64_t txg = BP_PHYSICAL_BIRTH(bp);
+
+ ASSERT(BP_IS_GANG(bp));
+
+ ZIO_SET_CHECKSUM(zcp, DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), txg, 0);
+}
+
+/*
+ * Set the external verifier for a label block based on its offset.
+ * The vdev is implicit, and the txg is unknowable at pool open time --
+ * hence the logic in vdev_uberblock_load() to find the most recent copy.
+ */
+static void
+zio_checksum_label_verifier(zio_cksum_t *zcp, uint64_t offset)
+{
+ ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0);
+}
+
+/*
+ * Calls the template init function of a checksum which supports context
+ * templates and installs the template into the spa_t.
+ */
+static void
+zio_checksum_template_init(enum zio_checksum checksum, const spa_t *spa)
+{
+ zio_checksum_info_t *ci = &zio_checksum_table[checksum];
+
+ if (ci->ci_tmpl_init == NULL)
+ return;
+#if 0 /* for now we dont have anything here */
+ if (spa->spa_cksum_tmpls[checksum] != NULL)
+ return;
+
+ VERIFY(ci->ci_tmpl_free != NULL);
+ mutex_enter(&spa->spa_cksum_tmpls_lock);
+ if (spa->spa_cksum_tmpls[checksum] == NULL) {
+ spa->spa_cksum_tmpls[checksum] =
+ ci->ci_tmpl_init(&spa->spa_cksum_salt);
+ VERIFY(spa->spa_cksum_tmpls[checksum] != NULL);
+ }
+ mutex_exit(&spa->spa_cksum_tmpls_lock);
+#endif
+}
+
+static int
+zio_checksum_verify(const blkptr_t *bp, void *data)
+{
+ uint64_t size;
+ unsigned int checksum;
+ zio_checksum_info_t *ci;
+ zio_cksum_t actual_cksum, expected_cksum, verifier;
+ int byteswap;
+
+ checksum = BP_GET_CHECKSUM(bp);
+ size = BP_GET_PSIZE(bp);
+
+ if (checksum >= ZIO_CHECKSUM_FUNCTIONS)
+ return (EINVAL);
+ ci = &zio_checksum_table[checksum];
+ if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL)
+ return (EINVAL);
+
+ zio_checksum_template_init(checksum, NULL);
+ if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) {
+ zio_eck_t *eck;
+
+ ASSERT(checksum == ZIO_CHECKSUM_GANG_HEADER ||
+ checksum == ZIO_CHECKSUM_LABEL);
+
+ eck = (zio_eck_t *)((char *)data + size) - 1;
+
+ if (checksum == ZIO_CHECKSUM_GANG_HEADER)
+ zio_checksum_gang_verifier(&verifier, bp);
+ else if (checksum == ZIO_CHECKSUM_LABEL)
+ zio_checksum_label_verifier(&verifier,
+ DVA_GET_OFFSET(BP_IDENTITY(bp)));
+ else
+ verifier = bp->blk_cksum;
+
+ byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC));
+
+ if (byteswap)
+ byteswap_uint64_array(&verifier, sizeof (zio_cksum_t));
+
+ expected_cksum = eck->zec_cksum;
+ eck->zec_cksum = verifier;
+ ci->ci_func[byteswap](data, size, NULL, &actual_cksum);
+ eck->zec_cksum = expected_cksum;
+
+ if (byteswap)
+ byteswap_uint64_array(&expected_cksum,
+ sizeof (zio_cksum_t));
+ } else {
+ expected_cksum = bp->blk_cksum;
+ ci->ci_func[0](data, size, NULL, &actual_cksum);
+ }
+
+ if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) {
+ /*printf("ZFS: read checksum failed\n");*/
+ return (EIO);
+ }
+
+ return (0);
+}
+
+static int
+zio_decompress_data(int cpfunc, void *src, uint64_t srcsize,
+ void *dest, uint64_t destsize)
+{
+ zio_compress_info_t *ci;
+
+ if (cpfunc >= ZIO_COMPRESS_FUNCTIONS) {
+ printf("ZFS: unsupported compression algorithm %u\n", cpfunc);
+ return (EIO);
+ }
+
+ ci = &zio_compress_table[cpfunc];
+ if (!ci->ci_decompress) {
+ printf("ZFS: unsupported compression algorithm %s\n",
+ ci->ci_name);
+ return (EIO);
+ }
+
+ return (ci->ci_decompress(src, dest, srcsize, destsize, ci->ci_level));
+}
+
+static uint64_t
+zap_hash(uint64_t salt, const char *name)
+{
+ const uint8_t *cp;
+ uint8_t c;
+ uint64_t crc = salt;
+
+ ASSERT(crc != 0);
+ ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
+ for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++)
+ crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF];
+
+ /*
+ * Only use 28 bits, since we need 4 bits in the cookie for the
+ * collision differentiator. We MUST use the high bits, since
+ * those are the onces that we first pay attention to when
+ * chosing the bucket.
+ */
+ crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
+
+ return (crc);
+}
+
+static void *zfs_alloc(size_t size);
+static void zfs_free(void *ptr, size_t size);
+
+typedef struct raidz_col {
+ uint64_t rc_devidx; /* child device index for I/O */
+ uint64_t rc_offset; /* device offset */
+ uint64_t rc_size; /* I/O size */
+ void *rc_data; /* I/O data */
+ int rc_error; /* I/O error for this device */
+ uint8_t rc_tried; /* Did we attempt this I/O column? */
+ uint8_t rc_skipped; /* Did we skip this I/O column? */
+} raidz_col_t;
+
+typedef struct raidz_map {
+ uint64_t rm_cols; /* Regular column count */
+ uint64_t rm_scols; /* Count including skipped columns */
+ uint64_t rm_bigcols; /* Number of oversized columns */
+ uint64_t rm_asize; /* Actual total I/O size */
+ uint64_t rm_missingdata; /* Count of missing data devices */
+ uint64_t rm_missingparity; /* Count of missing parity devices */
+ uint64_t rm_firstdatacol; /* First data column/parity count */
+ uint64_t rm_nskip; /* Skipped sectors for padding */
+ uint64_t rm_skipstart; /* Column index of padding start */
+ uintptr_t rm_reports; /* # of referencing checksum reports */
+ uint8_t rm_freed; /* map no longer has referencing ZIO */
+ uint8_t rm_ecksuminjected; /* checksum error was injected */
+ raidz_col_t rm_col[1]; /* Flexible array of I/O columns */
+} raidz_map_t;
+
+#define VDEV_RAIDZ_P 0
+#define VDEV_RAIDZ_Q 1
+#define VDEV_RAIDZ_R 2
+
+#define VDEV_RAIDZ_MUL_2(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0))
+#define VDEV_RAIDZ_MUL_4(x) (VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x)))
+
+/*
+ * We provide a mechanism to perform the field multiplication operation on a
+ * 64-bit value all at once rather than a byte at a time. This works by
+ * creating a mask from the top bit in each byte and using that to
+ * conditionally apply the XOR of 0x1d.
+ */
+#define VDEV_RAIDZ_64MUL_2(x, mask) \
+{ \
+ (mask) = (x) & 0x8080808080808080ULL; \
+ (mask) = ((mask) << 1) - ((mask) >> 7); \
+ (x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \
+ ((mask) & 0x1d1d1d1d1d1d1d1dULL); \
+}
+
+#define VDEV_RAIDZ_64MUL_4(x, mask) \
+{ \
+ VDEV_RAIDZ_64MUL_2((x), mask); \
+ VDEV_RAIDZ_64MUL_2((x), mask); \
+}
+
+/*
+ * These two tables represent powers and logs of 2 in the Galois field defined
+ * above. These values were computed by repeatedly multiplying by 2 as above.
+ */
+static const uint8_t vdev_raidz_pow2[256] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
+ 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
+ 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
+ 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
+ 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
+ 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
+ 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
+ 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
+ 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
+ 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
+ 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
+ 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
+ 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
+ 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
+ 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
+ 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
+ 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
+ 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
+ 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
+ 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
+ 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
+ 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
+ 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
+ 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
+ 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
+ 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
+ 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
+ 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
+ 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
+ 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
+ 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
+};
+static const uint8_t vdev_raidz_log2[256] = {
+ 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
+ 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
+ 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
+ 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
+ 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
+ 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
+ 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
+ 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
+ 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
+ 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
+ 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
+ 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
+ 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
+ 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
+ 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
+ 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
+ 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
+ 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
+ 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
+ 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
+ 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
+ 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
+ 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
+ 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
+ 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
+ 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
+ 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
+ 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
+ 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
+ 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
+ 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
+ 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
+};
+
+/*
+ * Multiply a given number by 2 raised to the given power.
+ */
+static uint8_t
+vdev_raidz_exp2(uint8_t a, int exp)
+{
+ if (a == 0)
+ return (0);
+
+ ASSERT(exp >= 0);
+ ASSERT(vdev_raidz_log2[a] > 0 || a == 1);
+
+ exp += vdev_raidz_log2[a];
+ if (exp > 255)
+ exp -= 255;
+
+ return (vdev_raidz_pow2[exp]);
+}
+
+static void
+vdev_raidz_generate_parity_p(raidz_map_t *rm)
+{
+ uint64_t *p, *src, pcount __attribute__((unused)), ccount, i;
+ int c;
+
+ pcount = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+
+ for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+ src = rm->rm_col[c].rc_data;
+ p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+ ccount = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+ if (c == rm->rm_firstdatacol) {
+ ASSERT(ccount == pcount);
+ for (i = 0; i < ccount; i++, src++, p++) {
+ *p = *src;
+ }
+ } else {
+ ASSERT(ccount <= pcount);
+ for (i = 0; i < ccount; i++, src++, p++) {
+ *p ^= *src;
+ }
+ }
+ }
+}
+
+static void
+vdev_raidz_generate_parity_pq(raidz_map_t *rm)
+{
+ uint64_t *p, *q, *src, pcnt, ccnt, mask, i;
+ int c;
+
+ pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+ ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+ rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+
+ for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+ src = rm->rm_col[c].rc_data;
+ p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+ q = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+
+ ccnt = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+ if (c == rm->rm_firstdatacol) {
+ ASSERT(ccnt == pcnt || ccnt == 0);
+ for (i = 0; i < ccnt; i++, src++, p++, q++) {
+ *p = *src;
+ *q = *src;
+ }
+ for (; i < pcnt; i++, src++, p++, q++) {
+ *p = 0;
+ *q = 0;
+ }
+ } else {
+ ASSERT(ccnt <= pcnt);
+
+ /*
+ * Apply the algorithm described above by multiplying
+ * the previous result and adding in the new value.
+ */
+ for (i = 0; i < ccnt; i++, src++, p++, q++) {
+ *p ^= *src;
+
+ VDEV_RAIDZ_64MUL_2(*q, mask);
+ *q ^= *src;
+ }
+
+ /*
+ * Treat short columns as though they are full of 0s.
+ * Note that there's therefore nothing needed for P.
+ */
+ for (; i < pcnt; i++, q++) {
+ VDEV_RAIDZ_64MUL_2(*q, mask);
+ }
+ }
+ }
+}
+
+static void
+vdev_raidz_generate_parity_pqr(raidz_map_t *rm)
+{
+ uint64_t *p, *q, *r, *src, pcnt, ccnt, mask, i;
+ int c;
+
+ pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+ ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+ rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+ ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+ rm->rm_col[VDEV_RAIDZ_R].rc_size);
+
+ for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+ src = rm->rm_col[c].rc_data;
+ p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+ q = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+ r = rm->rm_col[VDEV_RAIDZ_R].rc_data;
+
+ ccnt = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+ if (c == rm->rm_firstdatacol) {
+ ASSERT(ccnt == pcnt || ccnt == 0);
+ for (i = 0; i < ccnt; i++, src++, p++, q++, r++) {
+ *p = *src;
+ *q = *src;
+ *r = *src;
+ }
+ for (; i < pcnt; i++, src++, p++, q++, r++) {
+ *p = 0;
+ *q = 0;
+ *r = 0;
+ }
+ } else {
+ ASSERT(ccnt <= pcnt);
+
+ /*
+ * Apply the algorithm described above by multiplying
+ * the previous result and adding in the new value.
+ */
+ for (i = 0; i < ccnt; i++, src++, p++, q++, r++) {
+ *p ^= *src;
+
+ VDEV_RAIDZ_64MUL_2(*q, mask);
+ *q ^= *src;
+
+ VDEV_RAIDZ_64MUL_4(*r, mask);
+ *r ^= *src;
+ }
+
+ /*
+ * Treat short columns as though they are full of 0s.
+ * Note that there's therefore nothing needed for P.
+ */
+ for (; i < pcnt; i++, q++, r++) {
+ VDEV_RAIDZ_64MUL_2(*q, mask);
+ VDEV_RAIDZ_64MUL_4(*r, mask);
+ }
+ }
+ }
+}
+
+/*
+ * Generate RAID parity in the first virtual columns according to the number of
+ * parity columns available.
+ */
+static void
+vdev_raidz_generate_parity(raidz_map_t *rm)
+{
+ switch (rm->rm_firstdatacol) {
+ case 1:
+ vdev_raidz_generate_parity_p(rm);
+ break;
+ case 2:
+ vdev_raidz_generate_parity_pq(rm);
+ break;
+ case 3:
+ vdev_raidz_generate_parity_pqr(rm);
+ break;
+ default:
+ panic("invalid RAID-Z configuration");
+ }
+}
+
+/* BEGIN CSTYLED */
+/*
+ * In the general case of reconstruction, we must solve the system of linear
+ * equations defined by the coeffecients used to generate parity as well as
+ * the contents of the data and parity disks. This can be expressed with
+ * vectors for the original data (D) and the actual data (d) and parity (p)
+ * and a matrix composed of the identity matrix (I) and a dispersal matrix (V):
+ *
+ * __ __ __ __
+ * | | __ __ | p_0 |
+ * | V | | D_0 | | p_m-1 |
+ * | | x | : | = | d_0 |
+ * | I | | D_n-1 | | : |
+ * | | ~~ ~~ | d_n-1 |
+ * ~~ ~~ ~~ ~~
+ *
+ * I is simply a square identity matrix of size n, and V is a vandermonde
+ * matrix defined by the coeffecients we chose for the various parity columns
+ * (1, 2, 4). Note that these values were chosen both for simplicity, speedy
+ * computation as well as linear separability.
+ *
+ * __ __ __ __
+ * | 1 .. 1 1 1 | | p_0 |
+ * | 2^n-1 .. 4 2 1 | __ __ | : |
+ * | 4^n-1 .. 16 4 1 | | D_0 | | p_m-1 |
+ * | 1 .. 0 0 0 | | D_1 | | d_0 |
+ * | 0 .. 0 0 0 | x | D_2 | = | d_1 |
+ * | : : : : | | : | | d_2 |
+ * | 0 .. 1 0 0 | | D_n-1 | | : |
+ * | 0 .. 0 1 0 | ~~ ~~ | : |
+ * | 0 .. 0 0 1 | | d_n-1 |
+ * ~~ ~~ ~~ ~~
+ *
+ * Note that I, V, d, and p are known. To compute D, we must invert the
+ * matrix and use the known data and parity values to reconstruct the unknown
+ * data values. We begin by removing the rows in V|I and d|p that correspond
+ * to failed or missing columns; we then make V|I square (n x n) and d|p
+ * sized n by removing rows corresponding to unused parity from the bottom up
+ * to generate (V|I)' and (d|p)'. We can then generate the inverse of (V|I)'
+ * using Gauss-Jordan elimination. In the example below we use m=3 parity
+ * columns, n=8 data columns, with errors in d_1, d_2, and p_1:
+ * __ __
+ * | 1 1 1 1 1 1 1 1 |
+ * | 128 64 32 16 8 4 2 1 | <-----+-+-- missing disks
+ * | 19 205 116 29 64 16 4 1 | / /
+ * | 1 0 0 0 0 0 0 0 | / /
+ * | 0 1 0 0 0 0 0 0 | <--' /
+ * (V|I) = | 0 0 1 0 0 0 0 0 | <---'
+ * | 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 1 1 1 1 1 1 1 |
+ * | 128 64 32 16 8 4 2 1 |
+ * | 19 205 116 29 64 16 4 1 |
+ * | 1 0 0 0 0 0 0 0 |
+ * | 0 1 0 0 0 0 0 0 |
+ * (V|I)' = | 0 0 1 0 0 0 0 0 |
+ * | 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ *
+ * Here we employ Gauss-Jordan elimination to find the inverse of (V|I)'. We
+ * have carefully chosen the seed values 1, 2, and 4 to ensure that this
+ * matrix is not singular.
+ * __ __
+ * | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 |
+ * | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 |
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 |
+ * | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 |
+ * | 0 205 116 0 0 0 0 0 0 1 19 29 64 16 4 1 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 |
+ * | 0 0 185 0 0 0 0 0 205 1 222 208 141 221 201 204 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 |
+ * | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 |
+ * | 0 1 0 0 0 0 0 0 167 100 5 41 159 169 217 208 |
+ * | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 |
+ * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ * __ __
+ * | 0 0 1 0 0 0 0 0 |
+ * | 167 100 5 41 159 169 217 208 |
+ * | 166 100 4 40 158 168 216 209 |
+ * (V|I)'^-1 = | 0 0 0 1 0 0 0 0 |
+ * | 0 0 0 0 1 0 0 0 |
+ * | 0 0 0 0 0 1 0 0 |
+ * | 0 0 0 0 0 0 1 0 |
+ * | 0 0 0 0 0 0 0 1 |
+ * ~~ ~~
+ *
+ * We can then simply compute D = (V|I)'^-1 x (d|p)' to discover the values
+ * of the missing data.
+ *
+ * As is apparent from the example above, the only non-trivial rows in the
+ * inverse matrix correspond to the data disks that we're trying to
+ * reconstruct. Indeed, those are the only rows we need as the others would
+ * only be useful for reconstructing data known or assumed to be valid. For
+ * that reason, we only build the coefficients in the rows that correspond to
+ * targeted columns.
+ */
+/* END CSTYLED */
+
+static void
+vdev_raidz_matrix_init(raidz_map_t *rm, int n, int nmap, int *map,
+ uint8_t **rows)
+{
+ int i, j;
+ int pow;
+
+ ASSERT(n == rm->rm_cols - rm->rm_firstdatacol);
+
+ /*
+ * Fill in the missing rows of interest.
+ */
+ for (i = 0; i < nmap; i++) {
+ ASSERT3S(0, <=, map[i]);
+ ASSERT3S(map[i], <=, 2);
+
+ pow = map[i] * n;
+ if (pow > 255)
+ pow -= 255;
+ ASSERT(pow <= 255);
+
+ for (j = 0; j < n; j++) {
+ pow -= map[i];
+ if (pow < 0)
+ pow += 255;
+ rows[i][j] = vdev_raidz_pow2[pow];
+ }
+ }
+}
+
+static void
+vdev_raidz_matrix_invert(raidz_map_t *rm, int n, int nmissing, int *missing,
+ uint8_t **rows, uint8_t **invrows, const uint8_t *used)
+{
+ int i, j, ii, jj;
+ uint8_t log;
+
+ /*
+ * Assert that the first nmissing entries from the array of used
+ * columns correspond to parity columns and that subsequent entries
+ * correspond to data columns.
+ */
+ for (i = 0; i < nmissing; i++) {
+ ASSERT3S(used[i], <, rm->rm_firstdatacol);
+ }
+ for (; i < n; i++) {
+ ASSERT3S(used[i], >=, rm->rm_firstdatacol);
+ }
+
+ /*
+ * First initialize the storage where we'll compute the inverse rows.
+ */
+ for (i = 0; i < nmissing; i++) {
+ for (j = 0; j < n; j++) {
+ invrows[i][j] = (i == j) ? 1 : 0;
+ }
+ }
+
+ /*
+ * Subtract all trivial rows from the rows of consequence.
+ */
+ for (i = 0; i < nmissing; i++) {
+ for (j = nmissing; j < n; j++) {
+ ASSERT3U(used[j], >=, rm->rm_firstdatacol);
+ jj = used[j] - rm->rm_firstdatacol;
+ ASSERT3S(jj, <, n);
+ invrows[i][j] = rows[i][jj];
+ rows[i][jj] = 0;
+ }
+ }
+
+ /*
+ * For each of the rows of interest, we must normalize it and subtract
+ * a multiple of it from the other rows.
+ */
+ for (i = 0; i < nmissing; i++) {
+ for (j = 0; j < missing[i]; j++) {
+ ASSERT3U(rows[i][j], ==, 0);
+ }
+ ASSERT3U(rows[i][missing[i]], !=, 0);
+
+ /*
+ * Compute the inverse of the first element and multiply each
+ * element in the row by that value.
+ */
+ log = 255 - vdev_raidz_log2[rows[i][missing[i]]];
+
+ for (j = 0; j < n; j++) {
+ rows[i][j] = vdev_raidz_exp2(rows[i][j], log);
+ invrows[i][j] = vdev_raidz_exp2(invrows[i][j], log);
+ }
+
+ for (ii = 0; ii < nmissing; ii++) {
+ if (i == ii)
+ continue;
+
+ ASSERT3U(rows[ii][missing[i]], !=, 0);
+
+ log = vdev_raidz_log2[rows[ii][missing[i]]];
+
+ for (j = 0; j < n; j++) {
+ rows[ii][j] ^=
+ vdev_raidz_exp2(rows[i][j], log);
+ invrows[ii][j] ^=
+ vdev_raidz_exp2(invrows[i][j], log);
+ }
+ }
+ }
+
+ /*
+ * Verify that the data that is left in the rows are properly part of
+ * an identity matrix.
+ */
+ for (i = 0; i < nmissing; i++) {
+ for (j = 0; j < n; j++) {
+ if (j == missing[i]) {
+ ASSERT3U(rows[i][j], ==, 1);
+ } else {
+ ASSERT3U(rows[i][j], ==, 0);
+ }
+ }
+ }
+}
+
+static void
+vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing,
+ int *missing, uint8_t **invrows, const uint8_t *used)
+{
+ int i, j, x, cc, c;
+ uint8_t *src;
+ uint64_t ccount;
+ uint8_t *dst[VDEV_RAIDZ_MAXPARITY];
+ uint64_t dcount[VDEV_RAIDZ_MAXPARITY];
+ uint8_t log, val;
+ int ll;
+ uint8_t *invlog[VDEV_RAIDZ_MAXPARITY];
+ uint8_t *p, *pp;
+ size_t psize;
+
+ log = 0; /* gcc */
+ psize = sizeof (invlog[0][0]) * n * nmissing;
+ p = zfs_alloc(psize);
+
+ for (pp = p, i = 0; i < nmissing; i++) {
+ invlog[i] = pp;
+ pp += n;
+ }
+
+ for (i = 0; i < nmissing; i++) {
+ for (j = 0; j < n; j++) {
+ ASSERT3U(invrows[i][j], !=, 0);
+ invlog[i][j] = vdev_raidz_log2[invrows[i][j]];
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ c = used[i];
+ ASSERT3U(c, <, rm->rm_cols);
+
+ src = rm->rm_col[c].rc_data;
+ ccount = rm->rm_col[c].rc_size;
+ for (j = 0; j < nmissing; j++) {
+ cc = missing[j] + rm->rm_firstdatacol;
+ ASSERT3U(cc, >=, rm->rm_firstdatacol);
+ ASSERT3U(cc, <, rm->rm_cols);
+ ASSERT3U(cc, !=, c);
+
+ dst[j] = rm->rm_col[cc].rc_data;
+ dcount[j] = rm->rm_col[cc].rc_size;
+ }
+
+ ASSERT(ccount >= rm->rm_col[missing[0]].rc_size || i > 0);
+
+ for (x = 0; x < ccount; x++, src++) {
+ if (*src != 0)
+ log = vdev_raidz_log2[*src];
+
+ for (cc = 0; cc < nmissing; cc++) {
+ if (x >= dcount[cc])
+ continue;
+
+ if (*src == 0) {
+ val = 0;
+ } else {
+ if ((ll = log + invlog[cc][i]) >= 255)
+ ll -= 255;
+ val = vdev_raidz_pow2[ll];
+ }
+
+ if (i == 0)
+ dst[cc][x] = val;
+ else
+ dst[cc][x] ^= val;
+ }
+ }
+ }
+
+ zfs_free(p, psize);
+}
+
+static int
+vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts)
+{
+ int n, i, c, t, tt;
+ int nmissing_rows;
+ int missing_rows[VDEV_RAIDZ_MAXPARITY];
+ int parity_map[VDEV_RAIDZ_MAXPARITY];
+
+ uint8_t *p, *pp;
+ size_t psize;
+
+ uint8_t *rows[VDEV_RAIDZ_MAXPARITY];
+ uint8_t *invrows[VDEV_RAIDZ_MAXPARITY];
+ uint8_t *used;
+
+ int code = 0;
+
+
+ n = rm->rm_cols - rm->rm_firstdatacol;
+
+ /*
+ * Figure out which data columns are missing.
+ */
+ nmissing_rows = 0;
+ for (t = 0; t < ntgts; t++) {
+ if (tgts[t] >= rm->rm_firstdatacol) {
+ missing_rows[nmissing_rows++] =
+ tgts[t] - rm->rm_firstdatacol;
+ }
+ }
+
+ /*
+ * Figure out which parity columns to use to help generate the missing
+ * data columns.
+ */
+ for (tt = 0, c = 0, i = 0; i < nmissing_rows; c++) {
+ ASSERT(tt < ntgts);
+ ASSERT(c < rm->rm_firstdatacol);
+
+ /*
+ * Skip any targeted parity columns.
+ */
+ if (c == tgts[tt]) {
+ tt++;
+ continue;
+ }
+
+ code |= 1 << c;
+
+ parity_map[i] = c;
+ i++;
+ }
+
+ ASSERT(code != 0);
+ ASSERT3U(code, <, 1 << VDEV_RAIDZ_MAXPARITY);
+
+ psize = (sizeof (rows[0][0]) + sizeof (invrows[0][0])) *
+ nmissing_rows * n + sizeof (used[0]) * n;
+ p = kmem_alloc(psize, KM_SLEEP);
+
+ for (pp = p, i = 0; i < nmissing_rows; i++) {
+ rows[i] = pp;
+ pp += n;
+ invrows[i] = pp;
+ pp += n;
+ }
+ used = pp;
+
+ for (i = 0; i < nmissing_rows; i++) {
+ used[i] = parity_map[i];
+ }
+
+ for (tt = 0, c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+ if (tt < nmissing_rows &&
+ c == missing_rows[tt] + rm->rm_firstdatacol) {
+ tt++;
+ continue;
+ }
+
+ ASSERT3S(i, <, n);
+ used[i] = c;
+ i++;
+ }
+
+ /*
+ * Initialize the interesting rows of the matrix.
+ */
+ vdev_raidz_matrix_init(rm, n, nmissing_rows, parity_map, rows);
+
+ /*
+ * Invert the matrix.
+ */
+ vdev_raidz_matrix_invert(rm, n, nmissing_rows, missing_rows, rows,
+ invrows, used);
+
+ /*
+ * Reconstruct the missing data using the generated matrix.
+ */
+ vdev_raidz_matrix_reconstruct(rm, n, nmissing_rows, missing_rows,
+ invrows, used);
+
+ kmem_free(p, psize);
+
+ return (code);
+}
+
+static int
+vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt)
+{
+ int tgts[VDEV_RAIDZ_MAXPARITY];
+ int ntgts;
+ int i, c;
+ int code;
+ int nbadparity, nbaddata;
+
+ /*
+ * The tgts list must already be sorted.
+ */
+ for (i = 1; i < nt; i++) {
+ ASSERT(t[i] > t[i - 1]);
+ }
+
+ nbadparity = rm->rm_firstdatacol;
+ nbaddata = rm->rm_cols - nbadparity;
+ ntgts = 0;
+ for (i = 0, c = 0; c < rm->rm_cols; c++) {
+ if (i < nt && c == t[i]) {
+ tgts[ntgts++] = c;
+ i++;
+ } else if (rm->rm_col[c].rc_error != 0) {
+ tgts[ntgts++] = c;
+ } else if (c >= rm->rm_firstdatacol) {
+ nbaddata--;
+ } else {
+ nbadparity--;
+ }
+ }
+
+ ASSERT(ntgts >= nt);
+ ASSERT(nbaddata >= 0);
+ ASSERT(nbaddata + nbadparity == ntgts);
+
+ code = vdev_raidz_reconstruct_general(rm, tgts, ntgts);
+ ASSERT(code < (1 << VDEV_RAIDZ_MAXPARITY));
+ ASSERT(code > 0);
+ return (code);
+}
+
+static raidz_map_t *
+vdev_raidz_map_alloc(void *data, off_t offset, size_t size, uint64_t unit_shift,
+ uint64_t dcols, uint64_t nparity)
+{
+ raidz_map_t *rm;
+ uint64_t b = offset >> unit_shift;
+ uint64_t s = size >> unit_shift;
+ uint64_t f = b % dcols;
+ uint64_t o = (b / dcols) << unit_shift;
+ uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot;
+
+ q = s / (dcols - nparity);
+ r = s - q * (dcols - nparity);
+ bc = (r == 0 ? 0 : r + nparity);
+ tot = s + nparity * (q + (r == 0 ? 0 : 1));
+
+ if (q == 0) {
+ acols = bc;
+ scols = MIN(dcols, roundup(bc, nparity + 1));
+ } else {
+ acols = dcols;
+ scols = dcols;
+ }
+
+ ASSERT3U(acols, <=, scols);
+
+ rm = zfs_alloc(offsetof(raidz_map_t, rm_col[scols]));
+
+ rm->rm_cols = acols;
+ rm->rm_scols = scols;
+ rm->rm_bigcols = bc;
+ rm->rm_skipstart = bc;
+ rm->rm_missingdata = 0;
+ rm->rm_missingparity = 0;
+ rm->rm_firstdatacol = nparity;
+ rm->rm_reports = 0;
+ rm->rm_freed = 0;
+ rm->rm_ecksuminjected = 0;
+
+ asize = 0;
+
+ for (c = 0; c < scols; c++) {
+ col = f + c;
+ coff = o;
+ if (col >= dcols) {
+ col -= dcols;
+ coff += 1ULL << unit_shift;
+ }
+ rm->rm_col[c].rc_devidx = col;
+ rm->rm_col[c].rc_offset = coff;
+ rm->rm_col[c].rc_data = NULL;
+ rm->rm_col[c].rc_error = 0;
+ rm->rm_col[c].rc_tried = 0;
+ rm->rm_col[c].rc_skipped = 0;
+
+ if (c >= acols)
+ rm->rm_col[c].rc_size = 0;
+ else if (c < bc)
+ rm->rm_col[c].rc_size = (q + 1) << unit_shift;
+ else
+ rm->rm_col[c].rc_size = q << unit_shift;
+
+ asize += rm->rm_col[c].rc_size;
+ }
+
+ ASSERT3U(asize, ==, tot << unit_shift);
+ rm->rm_asize = roundup(asize, (nparity + 1) << unit_shift);
+ rm->rm_nskip = roundup(tot, nparity + 1) - tot;
+ ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift);
+ ASSERT3U(rm->rm_nskip, <=, nparity);
+
+ for (c = 0; c < rm->rm_firstdatacol; c++)
+ rm->rm_col[c].rc_data = zfs_alloc(rm->rm_col[c].rc_size);
+
+ rm->rm_col[c].rc_data = data;
+
+ for (c = c + 1; c < acols; c++)
+ rm->rm_col[c].rc_data = (char *)rm->rm_col[c - 1].rc_data +
+ rm->rm_col[c - 1].rc_size;
+
+ /*
+ * If all data stored spans all columns, there's a danger that parity
+ * will always be on the same device and, since parity isn't read
+ * during normal operation, that that device's I/O bandwidth won't be
+ * used effectively. We therefore switch the parity every 1MB.
+ *
+ * ... at least that was, ostensibly, the theory. As a practical
+ * matter unless we juggle the parity between all devices evenly, we
+ * won't see any benefit. Further, occasional writes that aren't a
+ * multiple of the LCM of the number of children and the minimum
+ * stripe width are sufficient to avoid pessimal behavior.
+ * Unfortunately, this decision created an implicit on-disk format
+ * requirement that we need to support for all eternity, but only
+ * for single-parity RAID-Z.
+ *
+ * If we intend to skip a sector in the zeroth column for padding
+ * we must make sure to note this swap. We will never intend to
+ * skip the first column since at least one data and one parity
+ * column must appear in each row.
+ */
+ ASSERT(rm->rm_cols >= 2);
+ ASSERT(rm->rm_col[0].rc_size == rm->rm_col[1].rc_size);
+
+ if (rm->rm_firstdatacol == 1 && (offset & (1ULL << 20))) {
+ devidx = rm->rm_col[0].rc_devidx;
+ o = rm->rm_col[0].rc_offset;
+ rm->rm_col[0].rc_devidx = rm->rm_col[1].rc_devidx;
+ rm->rm_col[0].rc_offset = rm->rm_col[1].rc_offset;
+ rm->rm_col[1].rc_devidx = devidx;
+ rm->rm_col[1].rc_offset = o;
+
+ if (rm->rm_skipstart == 0)
+ rm->rm_skipstart = 1;
+ }
+
+ return (rm);
+}
+
+static void
+vdev_raidz_map_free(raidz_map_t *rm)
+{
+ int c;
+
+ for (c = rm->rm_firstdatacol - 1; c >= 0; c--)
+ zfs_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size);
+
+ zfs_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_scols]));
+}
+
+static vdev_t *
+vdev_child(vdev_t *pvd, uint64_t devidx)
+{
+ vdev_t *cvd;
+
+ STAILQ_FOREACH(cvd, &pvd->v_children, v_childlink) {
+ if (cvd->v_id == devidx)
+ break;
+ }
+
+ return (cvd);
+}
+
+/*
+ * We keep track of whether or not there were any injected errors, so that
+ * any ereports we generate can note it.
+ */
+static int
+raidz_checksum_verify(const blkptr_t *bp, void *data, uint64_t size)
+{
+
+ return (zio_checksum_verify(bp, data));
+}
+
+/*
+ * Generate the parity from the data columns. If we tried and were able to
+ * read the parity without error, verify that the generated parity matches the
+ * data we read. If it doesn't, we fire off a checksum error. Return the
+ * number such failures.
+ */
+static int
+raidz_parity_verify(raidz_map_t *rm)
+{
+ void *orig[VDEV_RAIDZ_MAXPARITY];
+ int c, ret = 0;
+ raidz_col_t *rc;
+
+ for (c = 0; c < rm->rm_firstdatacol; c++) {
+ rc = &rm->rm_col[c];
+ if (!rc->rc_tried || rc->rc_error != 0)
+ continue;
+ orig[c] = zfs_alloc(rc->rc_size);
+ bcopy(rc->rc_data, orig[c], rc->rc_size);
+ }
+
+ vdev_raidz_generate_parity(rm);
+
+ for (c = rm->rm_firstdatacol - 1; c >= 0; c--) {
+ rc = &rm->rm_col[c];
+ if (!rc->rc_tried || rc->rc_error != 0)
+ continue;
+ if (bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) {
+ rc->rc_error = ECKSUM;
+ ret++;
+ }
+ zfs_free(orig[c], rc->rc_size);
+ }
+
+ return (ret);
+}
+
+/*
+ * Iterate over all combinations of bad data and attempt a reconstruction.
+ * Note that the algorithm below is non-optimal because it doesn't take into
+ * account how reconstruction is actually performed. For example, with
+ * triple-parity RAID-Z the reconstruction procedure is the same if column 4
+ * is targeted as invalid as if columns 1 and 4 are targeted since in both
+ * cases we'd only use parity information in column 0.
+ */
+static int
+vdev_raidz_combrec(raidz_map_t *rm, const blkptr_t *bp, void *data,
+ off_t offset, uint64_t bytes, int total_errors, int data_errors)
+{
+ raidz_col_t *rc;
+ void *orig[VDEV_RAIDZ_MAXPARITY];
+ int tstore[VDEV_RAIDZ_MAXPARITY + 2];
+ int *tgts = &tstore[1];
+ int current, next, i, c, n;
+ int code, ret = 0;
+
+ ASSERT(total_errors < rm->rm_firstdatacol);
+
+ /*
+ * This simplifies one edge condition.
+ */
+ tgts[-1] = -1;
+
+ for (n = 1; n <= rm->rm_firstdatacol - total_errors; n++) {
+ /*
+ * Initialize the targets array by finding the first n columns
+ * that contain no error.
+ *
+ * If there were no data errors, we need to ensure that we're
+ * always explicitly attempting to reconstruct at least one
+ * data column. To do this, we simply push the highest target
+ * up into the data columns.
+ */
+ for (c = 0, i = 0; i < n; i++) {
+ if (i == n - 1 && data_errors == 0 &&
+ c < rm->rm_firstdatacol) {
+ c = rm->rm_firstdatacol;
+ }
+
+ while (rm->rm_col[c].rc_error != 0) {
+ c++;
+ ASSERT3S(c, <, rm->rm_cols);
+ }
+
+ tgts[i] = c++;
+ }
+
+ /*
+ * Setting tgts[n] simplifies the other edge condition.
+ */
+ tgts[n] = rm->rm_cols;
+
+ /*
+ * These buffers were allocated in previous iterations.
+ */
+ for (i = 0; i < n - 1; i++) {
+ ASSERT(orig[i] != NULL);
+ }
+
+ orig[n - 1] = zfs_alloc(rm->rm_col[0].rc_size);
+
+ current = 0;
+ next = tgts[current];
+
+ while (current != n) {
+ tgts[current] = next;
+ current = 0;
+
+ /*
+ * Save off the original data that we're going to
+ * attempt to reconstruct.
+ */
+ for (i = 0; i < n; i++) {
+ ASSERT(orig[i] != NULL);
+ c = tgts[i];
+ ASSERT3S(c, >=, 0);
+ ASSERT3S(c, <, rm->rm_cols);
+ rc = &rm->rm_col[c];
+ bcopy(rc->rc_data, orig[i], rc->rc_size);
+ }
+
+ /*
+ * Attempt a reconstruction and exit the outer loop on
+ * success.
+ */
+ code = vdev_raidz_reconstruct(rm, tgts, n);
+ if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ for (i = 0; i < n; i++) {
+ c = tgts[i];
+ rc = &rm->rm_col[c];
+ ASSERT(rc->rc_error == 0);
+ rc->rc_error = ECKSUM;
+ }
+
+ ret = code;
+ goto done;
+ }
+
+ /*
+ * Restore the original data.
+ */
+ for (i = 0; i < n; i++) {
+ c = tgts[i];
+ rc = &rm->rm_col[c];
+ bcopy(orig[i], rc->rc_data, rc->rc_size);
+ }
+
+ do {
+ /*
+ * Find the next valid column after the current
+ * position..
+ */
+ for (next = tgts[current] + 1;
+ next < rm->rm_cols &&
+ rm->rm_col[next].rc_error != 0; next++)
+ continue;
+
+ ASSERT(next <= tgts[current + 1]);
+
+ /*
+ * If that spot is available, we're done here.
+ */
+ if (next != tgts[current + 1])
+ break;
+
+ /*
+ * Otherwise, find the next valid column after
+ * the previous position.
+ */
+ for (c = tgts[current - 1] + 1;
+ rm->rm_col[c].rc_error != 0; c++)
+ continue;
+
+ tgts[current] = c;
+ current++;
+
+ } while (current != n);
+ }
+ }
+ n--;
+done:
+ for (i = n - 1; i >= 0; i--) {
+ zfs_free(orig[i], rm->rm_col[0].rc_size);
+ }
+
+ return (ret);
+}
+
+static int
+vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data,
+ off_t offset, size_t bytes)
+{
+ vdev_t *tvd = vd->v_top;
+ vdev_t *cvd;
+ raidz_map_t *rm;
+ raidz_col_t *rc;
+ int c, error;
+ int unexpected_errors;
+ int parity_errors;
+ int parity_untried;
+ int data_errors;
+ int total_errors;
+ int n;
+ int tgts[VDEV_RAIDZ_MAXPARITY];
+ int code;
+
+ rc = NULL; /* gcc */
+ error = 0;
+
+ rm = vdev_raidz_map_alloc(data, offset, bytes, tvd->v_ashift,
+ vd->v_nchildren, vd->v_nparity);
+
+ /*
+ * Iterate over the columns in reverse order so that we hit the parity
+ * last -- any errors along the way will force us to read the parity.
+ */
+ for (c = rm->rm_cols - 1; c >= 0; c--) {
+ rc = &rm->rm_col[c];
+ cvd = vdev_child(vd, rc->rc_devidx);
+ if (cvd == NULL || cvd->v_state != VDEV_STATE_HEALTHY) {
+ if (c >= rm->rm_firstdatacol)
+ rm->rm_missingdata++;
+ else
+ rm->rm_missingparity++;
+ rc->rc_error = ENXIO;
+ rc->rc_tried = 1; /* don't even try */
+ rc->rc_skipped = 1;
+ continue;
+ }
+#if 0 /* XXX: Too hard for the boot code. */
+ if (vdev_dtl_contains(cvd, DTL_MISSING, zio->io_txg, 1)) {
+ if (c >= rm->rm_firstdatacol)
+ rm->rm_missingdata++;
+ else
+ rm->rm_missingparity++;
+ rc->rc_error = ESTALE;
+ rc->rc_skipped = 1;
+ continue;
+ }
+#endif
+ if (c >= rm->rm_firstdatacol || rm->rm_missingdata > 0) {
+ rc->rc_error = cvd->v_read(cvd, NULL, rc->rc_data,
+ rc->rc_offset, rc->rc_size);
+ rc->rc_tried = 1;
+ rc->rc_skipped = 0;
+ }
+ }
+
+reconstruct:
+ unexpected_errors = 0;
+ parity_errors = 0;
+ parity_untried = 0;
+ data_errors = 0;
+ total_errors = 0;
+
+ ASSERT(rm->rm_missingparity <= rm->rm_firstdatacol);
+ ASSERT(rm->rm_missingdata <= rm->rm_cols - rm->rm_firstdatacol);
+
+ for (c = 0; c < rm->rm_cols; c++) {
+ rc = &rm->rm_col[c];
+
+ if (rc->rc_error) {
+ ASSERT(rc->rc_error != ECKSUM); /* child has no bp */
+
+ if (c < rm->rm_firstdatacol)
+ parity_errors++;
+ else
+ data_errors++;
+
+ if (!rc->rc_skipped)
+ unexpected_errors++;
+
+ total_errors++;
+ } else if (c < rm->rm_firstdatacol && !rc->rc_tried) {
+ parity_untried++;
+ }
+ }
+
+ /*
+ * There are three potential phases for a read:
+ * 1. produce valid data from the columns read
+ * 2. read all disks and try again
+ * 3. perform combinatorial reconstruction
+ *
+ * Each phase is progressively both more expensive and less likely to
+ * occur. If we encounter more errors than we can repair or all phases
+ * fail, we have no choice but to return an error.
+ */
+
+ /*
+ * If the number of errors we saw was correctable -- less than or equal
+ * to the number of parity disks read -- attempt to produce data that
+ * has a valid checksum. Naturally, this case applies in the absence of
+ * any errors.
+ */
+ if (total_errors <= rm->rm_firstdatacol - parity_untried) {
+ if (data_errors == 0) {
+ if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ /*
+ * If we read parity information (unnecessarily
+ * as it happens since no reconstruction was
+ * needed) regenerate and verify the parity.
+ * We also regenerate parity when resilvering
+ * so we can write it out to the failed device
+ * later.
+ */
+ if (parity_errors + parity_untried <
+ rm->rm_firstdatacol) {
+ n = raidz_parity_verify(rm);
+ unexpected_errors += n;
+ ASSERT(parity_errors + n <=
+ rm->rm_firstdatacol);
+ }
+ goto done;
+ }
+ } else {
+ /*
+ * We either attempt to read all the parity columns or
+ * none of them. If we didn't try to read parity, we
+ * wouldn't be here in the correctable case. There must
+ * also have been fewer parity errors than parity
+ * columns or, again, we wouldn't be in this code path.
+ */
+ ASSERT(parity_untried == 0);
+ ASSERT(parity_errors < rm->rm_firstdatacol);
+
+ /*
+ * Identify the data columns that reported an error.
+ */
+ n = 0;
+ for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+ rc = &rm->rm_col[c];
+ if (rc->rc_error != 0) {
+ ASSERT(n < VDEV_RAIDZ_MAXPARITY);
+ tgts[n++] = c;
+ }
+ }
+
+ ASSERT(rm->rm_firstdatacol >= n);
+
+ code = vdev_raidz_reconstruct(rm, tgts, n);
+
+ if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ /*
+ * If we read more parity disks than were used
+ * for reconstruction, confirm that the other
+ * parity disks produced correct data. This
+ * routine is suboptimal in that it regenerates
+ * the parity that we already used in addition
+ * to the parity that we're attempting to
+ * verify, but this should be a relatively
+ * uncommon case, and can be optimized if it
+ * becomes a problem. Note that we regenerate
+ * parity when resilvering so we can write it
+ * out to failed devices later.
+ */
+ if (parity_errors < rm->rm_firstdatacol - n) {
+ n = raidz_parity_verify(rm);
+ unexpected_errors += n;
+ ASSERT(parity_errors + n <=
+ rm->rm_firstdatacol);
+ }
+
+ goto done;
+ }
+ }
+ }
+
+ /*
+ * This isn't a typical situation -- either we got a read
+ * error or a child silently returned bad data. Read every
+ * block so we can try again with as much data and parity as
+ * we can track down. If we've already been through once
+ * before, all children will be marked as tried so we'll
+ * proceed to combinatorial reconstruction.
+ */
+ unexpected_errors = 1;
+ rm->rm_missingdata = 0;
+ rm->rm_missingparity = 0;
+
+ n = 0;
+ for (c = 0; c < rm->rm_cols; c++) {
+ rc = &rm->rm_col[c];
+
+ if (rc->rc_tried)
+ continue;
+
+ cvd = vdev_child(vd, rc->rc_devidx);
+ ASSERT(cvd != NULL);
+ rc->rc_error = cvd->v_read(cvd, NULL,
+ rc->rc_data, rc->rc_offset, rc->rc_size);
+ if (rc->rc_error == 0)
+ n++;
+ rc->rc_tried = 1;
+ rc->rc_skipped = 0;
+ }
+ /*
+ * If we managed to read anything more, retry the
+ * reconstruction.
+ */
+ if (n > 0)
+ goto reconstruct;
+
+ /*
+ * At this point we've attempted to reconstruct the data given the
+ * errors we detected, and we've attempted to read all columns. There
+ * must, therefore, be one or more additional problems -- silent errors
+ * resulting in invalid data rather than explicit I/O errors resulting
+ * in absent data. We check if there is enough additional data to
+ * possibly reconstruct the data and then perform combinatorial
+ * reconstruction over all possible combinations. If that fails,
+ * we're cooked.
+ */
+ if (total_errors > rm->rm_firstdatacol) {
+ error = EIO;
+ } else if (total_errors < rm->rm_firstdatacol &&
+ (code = vdev_raidz_combrec(rm, bp, data, offset, bytes,
+ total_errors, data_errors)) != 0) {
+ /*
+ * If we didn't use all the available parity for the
+ * combinatorial reconstruction, verify that the remaining
+ * parity is correct.
+ */
+ if (code != (1 << rm->rm_firstdatacol) - 1)
+ (void) raidz_parity_verify(rm);
+ } else {
+ /*
+ * We're here because either:
+ *
+ * total_errors == rm_first_datacol, or
+ * vdev_raidz_combrec() failed
+ *
+ * In either case, there is enough bad data to prevent
+ * reconstruction.
+ *
+ * Start checksum ereports for all children which haven't
+ * failed, and the IO wasn't speculative.
+ */
+ error = ECKSUM;
+ }
+
+done:
+ vdev_raidz_map_free(rm);
+
+ return (error);
+}
diff --git a/usr/src/boot/sys/cddl/boot/zfs/zle.c b/usr/src/boot/sys/cddl/boot/zfs/zle.c
new file mode 100644
index 0000000000..361b1b29ee
--- /dev/null
+++ b/usr/src/boot/sys/cddl/boot/zfs/zle.c
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Zero-length encoding. This is a fast and simple algorithm to eliminate
+ * runs of zeroes. Each chunk of compressed data begins with a length byte, b.
+ * If b < n (where n is the compression parameter) then the next b + 1 bytes
+ * are literal values. If b >= n then the next (256 - b + 1) bytes are zero.
+ */
+
+static int
+zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+ unsigned char *src = s_start;
+ unsigned char *dst = d_start;
+ unsigned char *s_end = src + s_len;
+ unsigned char *d_end = dst + d_len;
+
+ while (src < s_end && dst < d_end) {
+ int len = 1 + *src++;
+ if (len <= n) {
+ while (len-- != 0)
+ *dst++ = *src++;
+ } else {
+ len -= n;
+ while (len-- != 0)
+ *dst++ = 0;
+ }
+ }
+ return (dst == d_end ? 0 : -1);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/acpica_prep.sh b/usr/src/boot/sys/contrib/dev/acpica/acpica_prep.sh
new file mode 100755
index 0000000000..a7f32e79e9
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/acpica_prep.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# Unpack an ACPI CA drop and restructure it to fit the FreeBSD layout
+#
+
+if [ ! $# -eq 1 ]; then
+ echo "usage: $0 acpica_archive"
+ exit
+fi
+
+src=$1
+wrk="$(realpath .)/_acpi_ca_unpack"
+dst="$(realpath .)/acpi_ca_destination"
+
+# files that should keep their full directory path
+fulldirs="common compiler components include os_specific"
+
+# files to remove
+stripdirs="generate libraries tests tools"
+stripfiles="Makefile README accygwin.h acdragonfly.h acdragonflyex.h \
+ acefi.h acefiex.h achaiku.h acintel.h aclinux.h aclinuxex.h \
+ acmacosx.h acmsvc.h acmsvcex.h acnetbsd.h acos2.h acwin.h \
+ acwin64.h acwinex.h new_table.txt osbsdtbl.c osefitbl.c \
+ osefixf.c osfreebsdtbl.c oslinuxtbl.c osunixdir.c osunixmap.c \
+ oswindir.c oswintbl.c oswinxf.c readme.txt utclib.c"
+
+# include files to canonify
+src_headers="acapps.h acbuffer.h acclib.h accommon.h acconfig.h \
+ acdebug.h acdisasm.h acdispat.h acevents.h acexcep.h acglobal.h \
+ achware.h acinterp.h aclocal.h acmacros.h acnames.h acnamesp.h \
+ acobject.h acopcode.h acoutput.h acparser.h acpi.h acpiosxf.h \
+ acpixf.h acpredef.h acresrc.h acrestyp.h acstruct.h actables.h \
+ actbl.h actbl1.h actbl2.h actbl3.h actypes.h acutils.h acuuid.h \
+ amlcode.h amlresrc.h platform/acenv.h platform/acenvex.h \
+ platform/acfreebsd.h platform/acgcc.h"
+comp_headers="aslcompiler.h asldefine.h aslglobal.h aslmessages.h \
+ aslsupport.l asltypes.h dtcompiler.h dttemplate.h preprocess.h"
+platform_headers="acfreebsd.h acgcc.h"
+
+# pre-clean
+echo pre-clean
+rm -rf ${wrk} ${dst}
+mkdir -p ${wrk}
+mkdir -p ${dst}
+
+# unpack
+echo unpack
+tar -x -z -f ${src} -C ${wrk}
+
+# strip files
+echo strip
+for i in ${stripdirs}; do
+ find ${wrk} -name ${i} -type d -print | xargs rm -r
+done
+for i in ${stripfiles}; do
+ find ${wrk} -name ${i} -type f -delete
+done
+
+# copy files
+echo copying full dirs
+for i in ${fulldirs}; do
+ find ${wrk} -name ${i} -type d -print | xargs -J % mv % ${dst}
+done
+echo copying remaining files
+find ${wrk} -type f -print | xargs -J % mv % ${dst}
+
+# canonify include paths
+for H in ${src_headers}; do
+ find ${dst} -name "*.[chly]" -type f -print | \
+ xargs sed -i "" -e "s|[\"<]$H[\">]|\<contrib/dev/acpica/include/$H\>|g"
+done
+for H in ${comp_headers}; do
+ find ${dst}/common ${dst}/compiler ${dst}/components \
+ -name "*.[chly]" -type f | \
+ xargs sed -i "" -e "s|[\"<]$H[\">]|\<contrib/dev/acpica/compiler/$H\>|g"
+done
+for H in ${platform_headers}; do
+ find ${dst}/include/platform -name "*.h" -type f -print | \
+ xargs sed -i "" -e "s|[\"<]$H[\">]|\<contrib/dev/acpica/include/platform/$H\>|g"
+done
+
+# post-clean
+echo post-clean
+rm -rf ${wrk}
+
+# assist the developer in generating a diff
+echo "Directories you may want to 'svn diff':"
+echo " sys/contrib/dev/acpica sys/dev/acpica \\"
+echo " sys/amd64/acpica sys/i386/acpica sys/x86/acpica \\"
+echo " sys/amd64/include sys/i386/include include \\"
+echo " sys/boot sys/conf sys/modules/acpi usr.sbin/acpi"
diff --git a/usr/src/boot/sys/contrib/dev/acpica/changes.txt b/usr/src/boot/sys/contrib/dev/acpica/changes.txt
new file mode 100644
index 0000000000..2782921f0f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/changes.txt
@@ -0,0 +1,15924 @@
+----------------------------------------
+18 August 2015. Summary of changes for version 20150818:
+
+This release is available at https://acpica.org/downloads
+
+1) ACPICA kernel-resident subsystem:
+
+Fix a regression for AcpiGetTableByIndex interface causing it to fail. Lv
+Zheng. ACPICA BZ 1186.
+
+Completed development to ensure that the ACPICA Disassembler and Debugger
+are fully standalone components of ACPICA. Removed cross-component
+dependences. Lv Zheng.
+
+The max-number-of-AML-loops is now runtime configurable (previously was
+compile-time only). This is essentially a loop timeout to force-abort
+infinite AML loops. ACPCIA BZ 1192.
+
+Debugger: Cleanup output to dump ACPI names and namepaths without any
+trailing underscores. Lv Zheng. ACPICA BZ 1135.
+
+Removed unnecessary conditional compilations across the Debugger and
+Disassembler components where entire modules could be left uncompiled.
+
+The aapits test is deprecated and has been removed from the ACPICA git
+tree. The test has never been completed and has not been maintained, thus
+becoming rather useless. ACPICA BZ 1015, 794.
+
+A batch of small changes to close bugzilla and other reports:
+- Remove duplicate code for _PLD processing. ACPICA BZ 1176.
+- Correctly cleanup after a ACPI table load failure. ACPICA BZ 1185.
+- iASL: Support POSIX yacc again in makefile. Jung-uk Kim.
+- ACPI table support: general cleanup and simplification. Lv Zheng, Bob
+Moore.
+- ACPI table support: fix for a buffer read overrun in AcpiTbFindTable.
+ACPICA BZ 1184.
+- Enhance parameter validation for DataTableRegion and LoadTable ASL/AML
+operators.
+- Debugger: Split debugger initialization/termination interfaces. Lv
+Zheng.
+- AcpiExec: Emit OemTableId for SSDTs during the load phase for table
+identification.
+- AcpiExec: Add debug message during _REG method phase during table
+load/init.
+- AcpiNames: Fix a regression where some output was missing and no longer
+emitted.
+- Debugger: General cleanup and simplification. Lv Zheng.
+- Disassembler: Cleanup use of several global option variables. Lv Zheng.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 101.3K Code, 27.7K Data, 129.0K Total
+ Debug Version: 198.6K Code, 80.9K Data, 279.5K Total
+ Previous Release:
+ Non-Debug Version: 100.9K Code, 24.5K Data, 125.4K Total
+ Debug Version: 197.8K Code, 81.5K Data, 279.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec: Fixed a problem where any more than 32 ACPI tables in the XSDT
+were not handled properly and caused load errors. Now, properly invoke
+and use the ACPICA auto-reallocate mechanism for ACPI table data
+structures. ACPICA BZ 1188
+
+AcpiNames: Add command-line wildcard support for ACPI table files. ACPICA
+BZ 1190.
+
+AcpiExec and AcpiNames: Add -l option to load ACPI tables only. For
+AcpiExec, this means that no control methods (like _REG/_INI/_STA) are
+executed during initialization. ACPICA BZ 1187, 1189.
+
+iASL/Disassembler: Implemented a prototype "listing" mode that emits AML
+that corresponds to each disassembled ASL statement, to simplify
+debugging. ACPICA BZ 1191.
+
+Debugger: Add option to the "objects" command to display a summary of the
+current namespace objects (Object type and count). This is displayed if
+the command is entered with no arguments.
+
+AcpiNames: Add -x option to specify debug level, similar to AcpiExec.
+
+----------------------------------------
+17 July 2015. Summary of changes for version 20150717:
+
+1) ACPICA kernel-resident subsystem:
+
+Improved the partitioning between the Debugger and Disassembler
+components. This allows the Debugger to be used standalone within kernel
+code without the Disassembler (which is used for single stepping also).
+This renames and moves one file, dmobject.c to dbobject.c. Lv Zheng.
+
+Debugger: Implemented a new command to trace the execution of control
+methods (Trace). This is especially useful for the in-kernel version of
+the debugger when file I/O may not be available for method trace output.
+See the ACPICA reference for more information. Lv Zheng.
+
+Moved all C library prototypes (used for the local versions of these
+functions when requested) to a new header, acclib.h
+Cleaned up the use of non-ANSI C library functions. These functions are
+implemented locally in ACPICA. Moved all such functions to a common
+source file, utnonansi.c
+
+Debugger: Fixed a problem with the "!!" command (get last command
+executed) where the debugger could enter an infinite loop and eventually
+crash.
+
+Removed the use of local macros that were used for some of the standard C
+library functions to automatically cast input parameters. This mostly
+affected the is* functions where the input parameter is defined to be an
+int. This required a few modifications to the main ACPICA source code to
+provide casting for these functions and eliminate possible compiler
+warnings for these parameters.
+
+Across the source code, added additional status/error checking to resolve
+issues discovered by static source code analysis tools such as Coverity.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 100.9K Code, 24.5K Data, 125.4K Total
+ Debug Version: 197.8K Code, 81.5K Data, 279.3K Total
+ Previous Release:
+ Non-Debug Version: 100.6K Code, 27.6K Data, 128.2K Total
+ Debug Version: 196.2K Code, 81.0K Data, 277.2K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a regression where the device map file feature no longer
+worked properly when used in conjunction with the disassembler. It only
+worked properly with the compiler itself.
+
+iASL: Implemented a new warning for method LocalX variables that are set
+but never used (similar to a C compiler such as gcc). This also applies
+to ArgX variables that are not defined by the parent method, and are
+instead (legally) used as local variables.
+
+iASL/Preprocessor: Finished the pass-through of line numbers from the
+preprocessor to the compiler. This ensures that compiler errors/warnings
+have the correct original line numbers and filenames, regardless of any
+#include files.
+
+iASL/Preprocessor: Fixed a couple of issues with comment handling and the
+pass-through of comments to the preprocessor output file (which becomes
+the compiler input file). Also fixed a problem with // comments that
+appear after a math expression.
+
+iASL: Added support for the TCPA server table to the table compiler and
+template generator. (The client table was already previously supported)
+
+iASL/Preprocessor: Added a permanent #define of the symbol "__IASL__" to
+identify the iASL compiler.
+
+Cleaned up the use of the macros NEGATIVE and POSITIVE which were defined
+multiple times. The new names are ACPI_SIGN_NEGATIVE and
+ACPI_SIGN_POSITIVE.
+
+AcpiHelp: Update to expand help messages for the iASL preprocessor
+directives.
+
+
+----------------------------------------
+19 June 2015. Summary of changes for version 20150619:
+
+Two regressions in version 20150616 have been addressed:
+
+Fixes some problems/issues with the C library macro removal (ACPI_STRLEN,
+etc.) This update changes ACPICA to only use the standard headers for
+functions, or the prototypes for the local versions of the C library
+functions. Across the source code, this required some additional casts
+for some Clib invocations for portability. Moved all local prototypes to
+a new file, acclib.h
+
+Fixes several problems with recent changes to the handling of the FACS
+table that could cause some systems not to boot.
+
+
+----------------------------------------
+16 June 2015. Summary of changes for version 20150616:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Across the entire ACPICA source code base, the various macros for the C
+library functions (such as ACPI_STRLEN, etc.) have been removed and
+replaced by the standard C library names (strlen, etc.) The original
+purpose for these macros is no longer applicable. This simplification
+reduces the number of macros used in the ACPICA source code
+significantly, improving readability and maintainability.
+
+Implemented support for a new ACPI table, the OSDT. This table, the
+"override" SDT, can be loaded directly by the host OS at boot time. It
+enables the replacement of existing namespace objects that were installed
+via the DSDT and/or SSDTs. The primary purpose for this is to replace
+buggy or incorrect ASL/AML code obtained via the BIOS. The OSDT is slated
+for inclusion in a future version of the ACPI Specification. Lv Zheng/Bob
+Moore.
+
+Added support for systems with (improperly) two FACS tables -- a "32-bit"
+table (via FADT 32-bit legacy field) and a "64-bit" table (via the 64-bit
+X field). This change will support both automatically. There continues to
+be systems found with this issue. This support requires a change to the
+AcpiSetFirmwareWakingVector interface. Also, a public global variable has
+been added to allow the host to select which FACS is desired
+(AcpiGbl_Use32BitFacsAddresses). See the ACPICA reference for more
+details Lv Zheng.
+
+Added a new feature to allow for systems that do not contain an FACS.
+Although this is already supported on hardware-reduced platforms, the
+feature has been extended for all platforms. The reasoning is that we do
+not want to abort the entire ACPICA initialization just because the
+system is seriously buggy and has no FACS.
+
+Fixed a problem where the GUID strings for NFIT tables (in acuuid.h) were
+not correctly transcribed from the ACPI specification in ACPICA version
+20150515.
+
+Implemented support for the _CLS object in the AcpiGetObjectInfo external
+interface.
+
+Updated the definitions of the TCPA and TPM2 ACPI tables to the more
+recent TCG ACPI Specification, December 14, 2014. Table disassembler and
+compiler also updated. Note: The TCPA "server" table is not supported by
+the disassembler/table-compiler at this time.
+
+ACPI 6.0: Added definitions for the new GIC version field in the MADT.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 100.6K Code, 27.6K Data, 128.2K Total
+ Debug Version: 196.2K Code, 81.0K Data, 277.2K Total
+ Previous Release:
+ Non-Debug Version: 99.9K Code, 27.5K Data, 127.4K Total
+ Debug Version: 195.2K Code, 80.8K Data, 276.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a problem with the new symbolic operator disassembler
+where incorrect ASL code could be emitted in some cases for the "non-
+commutative" operators -- Subtract, Divide, Modulo, ShiftLeft, and
+ShiftRight. The actual problem cases seem to be rather unusual in common
+ASL code, however. David Box.
+
+Modified the linux version of acpidump to obtain ACPI tables from not
+just /dev/mem (which may not exist) and /sys/firmware/acpi/tables. Lv
+Zheng.
+
+iASL: Fixed a problem where the user preprocessor output file (.i)
+contained extra data that was not expected. The compiler was using this
+file as a temporary file and passed through #line directives in order to
+keep compiler error messages in sync with the input file and line number
+across multiple include files. The (.i) is no longer a temporary file as
+the compiler uses a new, different file for the original purpose.
+
+iASL: Fixed a problem where comments within the original ASL source code
+file were not passed through to the preprocessor output file, nor any
+listing files.
+
+iASL: Fixed some issues for the handling of the "#include" preprocessor
+directive and the similar (but not the same) "Include" ASL operator.
+
+iASL: Add support for the new OSDT in both the disassembler and compiler.
+
+iASL: Fixed a problem with the constant folding support where a Buffer
+object could be incorrectly generated (incorrectly formed) during a
+conversion to a Store() operator.
+
+AcpiHelp: Updated for new NFIT GUIDs, "External" AML opcode, and new
+description text for the _REV predefined name. _REV now permanently
+returns 2, as per the ACPI 6.0 specification.
+
+Debugger: Enhanced the output of the Debug ASL object for references
+produced by the Index operator. For Buffers and strings, only output the
+actual byte pointed to by the index. For packages, only print the single
+package element decoded by the index. Previously, the entire
+buffer/string/package was emitted.
+
+iASL/Table-compiler: Fixed a regression where the "generic" data types
+were no longer recognized, causing errors.
+
+
+----------------------------------------
+15 May 2015. Summary of changes for version 20150515:
+
+This release implements most of ACPI 6.0 as described below.
+
+1) ACPICA kernel-resident subsystem:
+
+Implemented runtime argument checking and return value checking for all
+new ACPI 6.0 predefined names. This includes: _BTH, _CR3, _DSD, _LPI,
+_MTL, _PRR, _RDI, _RST, _TFP, _TSN.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 99.9K Code, 27.5K Data, 127.4K Total
+ Debug Version: 195.2K Code, 80.8K Data, 276.0K Total
+ Previous Release:
+ Non-Debug Version: 99.1K Code, 27.3K Data, 126.4K Total
+ Debug Version: 192.8K Code, 79.9K Data, 272.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL compiler: Added compile-time support for all new ACPI 6.0 predefined
+names (argument count validation and return value typechecking.)
+
+iASL disassembler and table compiler: implemented support for all new
+ACPI 6.0 tables. This includes: DRTM, IORT, LPIT, NFIT, STAO, WPBT, XENV.
+
+iASL disassembler and table compiler: Added ACPI 6.0 changes to existing
+tables: FADT, MADT.
+
+iASL preprocessor: Added a new directive to enable inclusion of binary
+blobs into ASL code. The new directive is #includebuffer. It takes a
+binary file as input and emits a named ascii buffer object into the ASL
+code.
+
+AcpiHelp: Added support for all new ACPI 6.0 predefined names.
+
+AcpiHelp: Added a new option, -d, to display all iASL preprocessor
+directives.
+
+AcpiHelp: Added a new option, -t, to display all known/supported ACPI
+tables.
+
+----------------------------------------
+10 April 2015. Summary of changes for version 20150410:
+
+Reverted a change introduced in version 20150408 that caused
+a regression in the disassembler where incorrect operator
+symbols could be emitted.
+
+----------------------------------------
+08 April 2015. Summary of changes for version 20150408:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Permanently set the return value for the _REV predefined name. It now
+returns 2 (was 5). This matches other ACPI implementations. _REV will be
+deprecated in the future, and is now defined to be 1 for ACPI 1.0, and 2
+for ACPI 2.0 and later. It should never be used to differentiate or
+identify operating systems.
+
+Added the "Windows 2015" string to the _OSI support. ACPICA will now
+return TRUE to a query with this string.
+
+Fixed several issues with the local version of the printf function.
+
+Added the C99 compiler option (-std=c99) to the Unix makefiles.
+
+ Current Release:
+ Non-Debug Version: 99.9K Code, 27.4K Data, 127.3K Total
+ Debug Version: 195.2K Code, 80.7K Data, 275.9K Total
+ Previous Release:
+ Non-Debug Version: 98.8K Code, 27.3K Data, 126.1K Total
+ Debug Version: 192.1K Code, 79.8K Data, 271.9K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented an enhancement to the constant folding feature to
+transform the parse tree to a simple Store operation whenever possible:
+ Add (2, 3, X) ==> is converted to: Store (5, X)
+ X = 2 + 3 ==> is converted to: Store (5, X)
+
+Updated support for the SLIC table (Software Licensing Description Table)
+in both the Data Table compiler and the disassembler. The SLIC table
+support now conforms to "Microsoft Software Licensing Tables (SLIC and
+MSDM). November 29, 2011. Copyright 2011 Microsoft". Note: Any SLIC data
+following the ACPI header is now defined to be "Proprietary Data", and as
+such, can only be entered or displayed as a hex data block.
+
+Implemented full support for the MSDM table as described in the document
+above. Note: The format of MSDM is similar to SLIC. Any MSDM data
+following the ACPI header is defined to be "Proprietary Data", and can
+only be entered or displayed as a hex data block.
+
+Implemented the -Pn option for the iASL Table Compiler (was only
+implemented for the ASL compiler). This option disables the iASL
+preprocessor.
+
+Disassembler: For disassembly of Data Tables, added a comment field
+around the Ascii equivalent data that is emitted as part of the "Raw
+Table Data" block. This prevents the iASL Preprocessor from possible
+confusion if/when the table is compiled.
+
+Disassembler: Added an option (-df) to force the disassembler to assume
+that the table being disassembled contains valid AML. This feature is
+useful for disassembling AML files that contain ACPI signatures other
+than DSDT or SSDT (such as OEMx or other signatures).
+
+Changes for the EFI version of the tools:
+1) Fixed a build error/issue
+2) Fixed a cast warning
+
+iASL: Fixed a path issue with the __FILE__ operator by making the
+directory prefix optional within the internal SplitInputFilename
+function.
+
+Debugger: Removed some unused global variables.
+
+Tests: Updated the makefile for proper generation of the AAPITS suite.
+
+----------------------------------------
+04 February 2015. Summary of changes for version 20150204:
+
+ACPICA kernel-resident subsystem:
+
+Updated all ACPICA copyrights and signons to 2014. Added the 2014
+copyright to all module headers and signons, including the standard Linux
+header. This affects virtually every file in the ACPICA core subsystem,
+iASL compiler, all ACPICA utilities, and the test suites.
+
+Events: Introduce ACPI_GPE_DISPATCH_RAW_HANDLER to fix GPE storm issues.
+A raw gpe handling mechanism was created to allow better handling of GPE
+storms that aren't easily managed by the normal handler. The raw handler
+allows disabling/renabling of the the GPE so that interrupt storms can be
+avoided in cases where events cannot be timely serviced. In this
+scenario, handlers should use the AcpiSetGpe() API to disable/enable the
+GPE. This API will leave the reference counts undisturbed, thereby
+preventing unintentional clearing of the GPE when the intent in only to
+temporarily disable it. Raw handlers allow enabling and disabling of a
+GPE by removing GPE register locking. As such, raw handlers much provide
+their own locks while using GPE API's to protect access to GPE data
+structures.
+Lv Zheng
+
+Events: Always modify GPE registers under the GPE lock.
+Applies GPE lock around AcpiFinishGpe() to protect access to GPE register
+values. Reported as bug by joe.liu@apple.com.
+
+Unix makefiles: Separate option to disable optimizations and
+_FORTIFY_SOURCE. This change removes the _FORTIFY_SOURCE flag from the
+NOOPT disable option and creates a separate flag (NOFORTIFY) for this
+purpose. Some toolchains may define _FORTIFY_SOURCE which leads redefined
+errors when building ACPICA. This allows disabling the option without
+also having to disable optimazations.
+David Box
+
+ Current Release:
+ Non-Debug Version: 101.7K Code, 27.9K Data, 129.6K Total
+ Debug Version: 199.2K Code, 82.4K Data, 281.6K Total
+
+----------------------------------------
+07 November 2014. Summary of changes for version 20141107:
+
+This release is available at https://acpica.org/downloads
+
+This release introduces and implements language extensions to ASL that
+provide support for symbolic ("C-style") operators and expressions. These
+language extensions are known collectively as ASL+.
+
+
+1) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a problem with disassembly of the UartSerialBus
+macro. Changed "StopBitsNone" to the correct "StopBitsZero". David E.
+Box.
+
+Disassembler: Fixed the Unicode macro support to add escape sequences.
+All non-printable ASCII values are emitted as escape sequences, as well
+as the standard escapes for quote and backslash. Ensures that the
+disassembled macro can be correctly recompiled.
+
+iASL: Added Printf/Fprintf macros for formatted output. These macros are
+translated to existing AML Concatenate and Store operations. Printf
+writes to the ASL Debug object. Fprintf allows the specification of an
+ASL name as the target. Only a single format specifier is required, %o,
+since the AML interpreter dynamically converts objects to the required
+type. David E. Box.
+
+ (old) Store (Concatenate (Concatenate (Concatenate (Concatenate
+ (Concatenate (Concatenate (Concatenate ("", Arg0),
+ ": Unexpected value for "), Arg1), ", "), Arg2),
+ " at line "), Arg3), Debug)
+
+ (new) Printf ("%o: Unexpected value for %o, %o at line %o",
+ Arg0, Arg1, Arg2, Arg3)
+
+ (old) Store (Concatenate (Concatenate (Concatenate (Concatenate
+ ("", Arg1), ": "), Arg0), " Successful"), STR1)
+
+ (new) Fprintf (STR1, "%o: %o Successful", Arg1, Arg0)
+
+iASL: Added debug options (-bp, -bt) to dynamically prune levels of the
+ASL parse tree before the AML code is generated. This allows blocks of
+ASL code to be removed in order to help locate and identify problem
+devices and/or code. David E. Box.
+
+AcpiExec: Added support (-fi) for an optional namespace object
+initialization file. This file specifies initial values for namespace
+objects as necessary for debugging and testing different ASL code paths
+that may be taken as a result of BIOS options.
+
+
+2) Overview of symbolic operator support for ASL (ASL+)
+-------------------------------------------------------
+
+As an extension to the ASL language, iASL implements support for symbolic
+(C-style) operators for math and logical expressions. This can greatly
+simplify ASL code as well as improve both readability and
+maintainability. These language extensions can exist concurrently with
+all legacy ASL code and expressions.
+
+The symbolic extensions are 100% compatible with existing AML
+interpreters, since no new AML opcodes are created. To implement the
+extensions, the iASL compiler transforms the symbolic expressions into
+the legacy ASL/AML equivalents at compile time.
+
+Full symbolic expressions are supported, along with the standard C
+precedence and associativity rules.
+
+Full disassembler support for the symbolic expressions is provided, and
+creates an automatic migration path for existing ASL code to ASL+ code
+via the disassembly process. By default, the disassembler now emits ASL+
+code with symbolic expressions. An option (-dl) is provided to force the
+disassembler to emit legacy ASL code if desired.
+
+Below is the complete list of the currently supported symbolic operators
+with examples. See the iASL User Guide for additional information.
+
+
+ASL+ Syntax Legacy ASL Equivalent
+----------- ---------------------
+
+ // Math operators
+
+Z = X + Y Add (X, Y, Z)
+Z = X - Y Subtract (X, Y, Z)
+Z = X * Y Multiply (X, Y, Z)
+Z = X / Y Divide (X, Y, , Z)
+Z = X % Y Mod (X, Y, Z)
+Z = X << Y ShiftLeft (X, Y, Z)
+Z = X >> Y ShiftRight (X, Y, Z)
+Z = X & Y And (X, Y, Z)
+Z = X | Y Or (X, Y, Z)
+Z = X ^ Y Xor (X, Y, Z)
+Z = ~X Not (X, Z)
+X++ Increment (X)
+X-- Decrement (X)
+
+ // Logical operators
+
+(X == Y) LEqual (X, Y)
+(X != Y) LNotEqual (X, Y)
+(X < Y) LLess (X, Y)
+(X > Y) LGreater (X, Y)
+(X <= Y) LLessEqual (X, Y)
+(X >= Y) LGreaterEqual (X, Y)
+(X && Y) LAnd (X, Y)
+(X || Y) LOr (X, Y)
+(!X) LNot (X)
+
+ // Assignment and compound assignment operations
+
+X = Y Store (Y, X)
+X += Y Add (X, Y, X)
+X -= Y Subtract (X, Y, X)
+X *= Y Multiply (X, Y, X)
+X /= Y Divide (X, Y, , X)
+X %= Y Mod (X, Y, X)
+X <<= Y ShiftLeft (X, Y, X)
+X >>= Y ShiftRight (X, Y, X)
+X &= Y And (X, Y, X)
+X |= Y Or (X, Y, X)
+X ^= Y Xor (X, Y, X)
+
+
+3) ASL+ Examples:
+-----------------
+
+Legacy ASL:
+ If (LOr (LOr (LEqual (And (R510, 0x03FB), 0x02E0), LEqual (
+ And (R520, 0x03FB), 0x02E0)), LOr (LEqual (And (R530,
+0x03FB),
+ 0x02E0), LEqual (And (R540, 0x03FB), 0x02E0))))
+ {
+ And (MEMB, 0xFFFFFFF0, SRMB)
+ Store (MEMB, Local2)
+ Store (PDBM, Local1)
+ And (PDBM, 0xFFFFFFFFFFFFFFF9, PDBM)
+ Store (SRMB, MEMB)
+ Or (PDBM, 0x02, PDBM)
+ }
+
+ASL+ version:
+ If (((R510 & 0x03FB) == 0x02E0) ||
+ ((R520 & 0x03FB) == 0x02E0) ||
+ ((R530 & 0x03FB) == 0x02E0) ||
+ ((R540 & 0x03FB) == 0x02E0))
+ {
+ SRMB = (MEMB & 0xFFFFFFF0)
+ Local2 = MEMB
+ Local1 = PDBM
+ PDBM &= 0xFFFFFFFFFFFFFFF9
+ MEMB = SRMB
+ PDBM |= 0x02
+ }
+
+Legacy ASL:
+ Store (0x1234, Local1)
+ Multiply (Add (Add (Local1, TEST), 0x20), Local2, Local3)
+ Multiply (Local2, Add (Add (Local1, TEST), 0x20), Local3)
+ Add (Local1, Add (TEST, Multiply (0x20, Local2)), Local3)
+ Store (Index (PKG1, 0x03), Local6)
+ Store (Add (Local3, Local2), Debug)
+ Add (Local1, 0x0F, Local2)
+ Add (Local1, Multiply (Local2, Local3), Local2)
+ Multiply (Add (Add (Local1, TEST), 0x20), ToBCD (Local1), Local3)
+
+ASL+ version:
+ Local1 = 0x1234
+ Local3 = (((Local1 + TEST) + 0x20) * Local2)
+ Local3 = (Local2 * ((Local1 + TEST) + 0x20))
+ Local3 = (Local1 + (TEST + (0x20 * Local2)))
+ Local6 = Index (PKG1, 0x03)
+ Debug = (Local3 + Local2)
+ Local2 = (Local1 + 0x0F)
+ Local2 = (Local1 + (Local2 * Local3))
+ Local3 = (((Local1 + TEST) + 0x20) * ToBCD (Local1))
+
+
+----------------------------------------
+26 September 2014. Summary of changes for version 20140926:
+
+1) ACPICA kernel-resident subsystem:
+
+Updated the GPIO operation region handler interface (GeneralPurposeIo).
+In order to support GPIO Connection objects with multiple pins, along
+with the related Field objects, the following changes to the interface
+have been made: The Address is now defined to be the offset in bits of
+the field unit from the previous invocation of a Connection. It can be
+viewed as a "Pin Number Index" into the connection resource descriptor.
+The BitWidth is the exact bit width of the field. It is usually one bit,
+but not always. See the ACPICA reference guide (section 8.8.6.2.1) for
+additional information and examples.
+
+GPE support: During ACPICA/GPE initialization, ensure that all GPEs with
+corresponding _Lxx/_Exx methods are disabled (they may have been enabled
+by the firmware), so that they cannot fire until they are enabled via
+AcpiUpdateAllGpes. Rafael J. Wysocki.
+
+Added a new return flag for the Event/GPE status interfaces --
+AcpiGetEventStatus and AcpiGetGpeStatus. The new
+ACPI_EVENT_FLAGS_HAS_HANDLER flag is used to indicate that the event or
+GPE currently has a handler associated with it, and can thus actually
+affect the system. Lv Zheng.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 99.1K Code, 27.3K Data, 126.4K Total
+ Debug Version: 192.8K Code, 79.9K Data, 272.7K Total
+ Previous Release:
+ Non-Debug Version: 98.8K Code, 27.3K Data, 126.1K Total
+ Debug Version: 192.1K Code, 79.8K Data, 271.9K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a memory allocation/free regression introduced in 20140828
+that could cause the compiler to crash. This was introduced inadvertently
+during the effort to eliminate compiler memory leaks. ACPICA BZ 1111,
+1113.
+
+iASL: Removed two error messages that have been found to create false
+positives, until they can be fixed and fully validated (ACPICA BZ 1112):
+1) Illegal forward reference within a method
+2) Illegal reference across two methods
+
+iASL: Implemented a new option (-lm) to create a hardware mapping file
+that summarizes all GPIO, I2C, SPI, and UART connections. This option
+works for both the compiler and disassembler. See the iASL compiler user
+guide for additional information and examples (section 6.4.6).
+
+AcpiDump: Added support for the version 1 (ACPI 1.0) RSDP in addition to
+version 2. This corrects the AE_BAD_HEADER exception seen on systems with
+a version 1 RSDP. Lv Zheng ACPICA BZ 1097.
+
+AcpiExec: For Unix versions, don't attempt to put STDIN into raw mode
+unless STDIN is actually a terminal. Assists with batch-mode processing.
+ACPICA BZ 1114.
+
+Disassembler/AcpiHelp: Added another large group of recognized _HID
+values.
+
+
+----------------------------------------
+28 August 2014. Summary of changes for version 20140828:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a problem related to the internal use of the Timer() operator where
+a 64-bit divide could cause an attempted link to a double-precision math
+library. This divide is not actually necessary, so the code was
+restructured to eliminate it. Lv Zheng.
+
+ACPI 5.1: Added support for the runtime validation of the _DSD package
+(similar to the iASL support).
+
+ACPI 5.1/Headers: Added support for the GICC affinity subtable to the
+SRAT table. Hanjun Guo <hanjun.guo@linaro.org>.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 98.8K Code, 27.3K Data, 126.1K Total
+ Debug Version: 192.1K Code, 79.8K Data, 271.9K Total
+ Previous Release:
+ Non-Debug Version: 98.7K Code, 27.3K Data, 126.0K Total1
+ Debug Version: 192.0K Code, 79.7K Data, 271.7K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec: Fixed a problem on unix systems where the original terminal
+state was not always properly restored upon exit. Seen when using the -v
+option. ACPICA BZ 1104.
+
+iASL: Fixed a problem with the validation of the ranges/length within the
+Memory24 resource descriptor. There was a boundary condition when the
+range was equal to the (length -1) caused by the fact that these values
+are defined in 256-byte blocks, not bytes. ACPICA BZ 1098
+
+Disassembler: Fixed a problem with the GpioInt descriptor interrupt
+polarity
+flags. The flags are actually 2 bits, not 1, and the "ActiveBoth" keyword
+is
+now supported properly.
+
+ACPI 5.1: Added the GICC affinity subtable to the SRAT table. Supported
+in the disassembler, data table compiler, and table template generator.
+
+iASL: Added a requirement for Device() objects that one of either a _HID
+or _ADR must exist within the scope of a Device, as per the ACPI
+specification. Remove a similar requirement that was incorrectly in place
+for the _DSD object.
+
+iASL: Added error detection for illegal named references within control
+methods that would cause runtime failures. Now trapped as errors are: 1)
+References to objects within a non-parent control method. 2) Forward
+references (within a method) -- for control methods, AML interpreters use
+a one-pass parse of control methods. ACPICA BZ 1008.
+
+iASL: Added error checking for dependencies related to the _PSx power
+methods. ACPICA BZ 1029.
+1) For _PS0, one of these must exist within the same scope: _PS1, _PS2,
+_PS3.
+2) For _PS1, _PS2, and PS3: A _PS0 object must exist within the same
+scope.
+
+iASL and table compiler: Cleanup miscellaneous memory leaks by fully
+deploying the existing object and string caches and adding new caches for
+the table compiler.
+
+iASL: Split the huge parser source file into multiple subfiles to improve
+manageability. Generation now requires the M4 macro preprocessor, which
+is part of the Bison distribution on both unix and windows platforms.
+
+AcpiSrc: Fixed and removed all extraneous warnings generated during
+entire ACPICA source code scan and/or conversion.
+
+
+----------------------------------------
+
+24 July 2014. Summary of changes for version 20140724:
+
+The ACPI 5.1 specification has been released and is available at:
+http://uefi.org/specs/access
+
+
+0) ACPI 5.1 support in ACPICA:
+
+ACPI 5.1 is fully supported in ACPICA as of this release.
+
+New predefined names. Support includes iASL and runtime ACPICA
+validation.
+ _CCA (Cache Coherency Attribute).
+ _DSD (Device-Specific Data). David Box.
+
+Modifications to existing ACPI tables. Support includes headers, iASL
+Data Table compiler, disassembler, and the template generator.
+ FADT - New fields and flags. Graeme Gregory.
+ GTDT - One new subtable and new fields. Tomasz Nowicki.
+ MADT - Two new subtables. Tomasz Nowicki.
+ PCCT - One new subtable.
+
+Miscellaneous.
+ New notification type for System Resource Affinity change events.
+
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a regression introduced in 20140627 where a fault can happen during
+the deletion of Alias AML namespace objects. The problem affected both
+the core ACPICA and the ACPICA tools including iASL and AcpiExec.
+
+Implemented a new GPE public interface, AcpiMarkGpeForWake. Provides a
+simple mechanism to enable wake GPEs that have no associated handler or
+control method. Rafael Wysocki.
+
+Updated the AcpiEnableGpe interface to disallow the enable if there is no
+handler or control method associated with the particular GPE. This will
+help avoid meaningless GPEs and even GPE floods. Rafael Wysocki.
+
+Updated GPE handling and dispatch by disabling the GPE before clearing
+the status bit for edge-triggered GPEs. Lv Zheng.
+
+Added Timer() support to the AML Debug object. The current timer value is
+now displayed with each invocation of (Store to) the debug object to
+enable simple generation of execution times for AML code (method
+execution for example.) ACPICA BZ 1093.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 98.7K Code, 27.3K Data, 126.0K Total
+ Debug Version: 192.0K Code, 79.7K Data, 271.7K Total
+ Previous Release:
+ Non-Debug Version: 98.7K Code, 27.2K Data, 125.9K Total
+ Debug Version: 191.7K Code, 79.6K Data, 271.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed an issue with the recently added local printf implementation,
+concerning width/precision specifiers that could cause incorrect output.
+Lv Zheng. ACPICA BZ 1094.
+
+Disassembler: Added support to detect buffers that contain UUIDs and
+disassemble them to an invocation of the ToUUID operator. Also emit
+commented descriptions of known ACPI-related UUIDs.
+
+AcpiHelp: Added support to display known ACPI-related UUIDs. New option,
+-u. Adds three new files.
+
+iASL: Update table compiler and disassembler for DMAR table changes that
+were introduced in September 2013. With assistance by David Woodhouse.
+
+----------------------------------------
+27 June 2014. Summary of changes for version 20140627:
+
+1) ACPICA kernel-resident subsystem:
+
+Formatted Output: Implemented local versions of standard formatted output
+utilities such as printf, etc. Over time, it has been discovered that
+there are in fact many portability issues with printf, and the addition
+of this feature will fix/prevent these issues once and for all. Some
+known issues are summarized below:
+
+1) Output of 64-bit values is not portable. For example, UINT64 is %ull
+for the Linux kernel and is %uI64 for some MSVC versions.
+2) Invoking printf consistently in a manner that is portable across both
+32-bit and 64-bit platforms is difficult at best in many situations.
+3) The output format for pointers varies from system to system (leading
+zeros especially), and leads to inconsistent output from ACPICA across
+platforms.
+4) Certain platform-specific printf formats may conflict with ACPICA use.
+5) If there is no local C library available, ACPICA now has local support
+for printf.
+
+-- To address these printf issues in a complete manner, ACPICA now
+directly implements a small subset of printf format specifiers, only
+those that it requires. Adds a new file, utilities/utprint.c. Lv Zheng.
+
+Implemented support for ACPICA generation within the EFI environment.
+Initially, the AcpiDump utility is supported in the UEFI shell
+environment. Lv Zheng.
+
+Added a new external interface, AcpiLogError, to improve ACPICA
+portability. This allows the host to redirect error messages from the
+ACPICA utilities. Lv Zheng.
+
+Added and deployed new OSL file I/O interfaces to improve ACPICA
+portability:
+ AcpiOsOpenFile
+ AcpiOsCloseFile
+ AcpiOsReadFile
+ AcpiOsWriteFile
+ AcpiOsGetFileOffset
+ AcpiOsSetFileOffset
+There are C library implementations of these functions in the new file
+service_layers/oslibcfs.c -- however, the functions can be implemented by
+the local host in any way necessary. Lv Zheng.
+
+Implemented a mechanism to disable/enable ACPI table checksum validation
+at runtime. This can be useful when loading tables very early during OS
+initialization when it may not be possible to map the entire table in
+order to compute the checksum. Lv Zheng.
+
+Fixed a buffer allocation issue for the Generic Serial Bus support.
+Originally, a fixed buffer length was used. This change allows for
+variable-length buffers based upon the protocol indicated by the field
+access attributes. Reported by Lan Tianyu. Lv Zheng.
+
+Fixed a problem where an object detached from a namespace node was not
+properly terminated/cleared and could cause a circular list problem if
+reattached. ACPICA BZ 1063. David Box.
+
+Fixed a possible recursive lock acquisition in hwregs.c. Rakib Mullick.
+
+Fixed a possible memory leak in an error return path within the function
+AcpiUtCopyIobjectToIobject. ACPICA BZ 1087. Colin Ian King.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 98.7K Code, 27.2K Data, 125.9K Total
+ Debug Version: 191.7K Code, 79.6K Data, 271.3K Total
+ Previous Release:
+ Non-Debug Version: 96.8K Code, 27.2K Data, 124.0K Total
+ Debug Version: 189.5K Code, 79.7K Data, 269.2K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Add dump of ASCII equivalent text within a comment at the
+end of each line of the output for the Buffer() ASL operator.
+
+AcpiDump: Miscellaneous changes:
+ Fixed repetitive table dump in -n mode.
+ For older EFI platforms, use the ACPI 1.0 GUID during RSDP search if
+the ACPI 2.0 GUID fails.
+
+iASL: Fixed a problem where the compiler could fault if incorrectly given
+an acpidump output file as input. ACPICA BZ 1088. David Box.
+
+AcpiExec/AcpiNames: Fixed a problem where these utilities could fault if
+they are invoked without any arguments.
+
+Debugger: Fixed a possible memory leak in an error return path. ACPICA BZ
+1086. Colin Ian King.
+
+Disassembler: Cleaned up a block of code that extracts a parent Op
+object. Added a comment that explains that the parent is guaranteed to be
+valid in this case. ACPICA BZ 1069.
+
+----------------------------------------
+24 April 2014. Summary of changes for version 20140424:
+
+1) ACPICA kernel-resident subsystem:
+
+Implemented support to skip/ignore NULL address entries in the RSDT/XSDT.
+Some of these tables are known to contain a trailing NULL entry. Lv
+Zheng.
+
+Removed an extraneous error message for the case where there are a large
+number of system GPEs (> 124). This was the "32-bit FADT register is too
+long to convert to GAS struct" message, which is irrelevant for GPEs
+since the GPEx_BLK_LEN fields of the FADT are always used instead of the
+(limited capacity) GAS bit length. Also, several changes to ensure proper
+support for GPE numbers > 255, where some "GPE number" fields were 8-bits
+internally.
+
+Implemented and deployed additional configuration support for the public
+ACPICA external interfaces. Entire classes of interfaces can now be
+easily modified or configured out, replaced by stubbed inline functions
+by default. Lv Zheng.
+
+Moved all public ACPICA runtime configuration globals to the public
+ACPICA external interface file for convenience. Also, removed some
+obsolete/unused globals. See the file acpixf.h. Lv Zheng.
+
+Documentation: Added a new section to the ACPICA reference describing the
+maximum number of GPEs that can be supported by the FADT-defined GPEs in
+block zero and one. About 1200 total. See section 4.4.1 of the ACPICA
+reference.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.8K Code, 27.2K Data, 124.0K Total
+ Debug Version: 189.5K Code, 79.7K Data, 269.2K Total
+ Previous Release:
+ Non-Debug Version: 97.0K Code, 27.2K Data, 124.2K Total
+ Debug Version: 189.7K Code, 79.5K Data, 269.2K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL and disassembler: Add full support for the LPIT table (Low Power
+Idle Table). Includes support in the disassembler, data table compiler,
+and template generator.
+
+AcpiDump utility:
+1) Add option to force the use of the RSDT (over the XSDT).
+2) Improve validation of the RSDP signature (use 8 chars instead of 4).
+
+iASL: Add check for predefined packages that are too large. For
+predefined names that contain subpackages, check if each subpackage is
+too large. (Check for too small already exists.)
+
+Debugger: Updated the GPE command (which simulates a GPE by executing the
+GPE code paths in ACPICA). The GPE device is now optional, and defaults
+to the GPE 0/1 FADT-defined blocks.
+
+Unix application OSL: Update line-editing support. Add additional error
+checking and take care not to reset terminal attributes on exit if they
+were never set. This should help guarantee that the terminal is always
+left in the previous state on program exit.
+
+----------------------------------------
+25 March 2014. Summary of changes for version 20140325:
+
+1) ACPICA kernel-resident subsystem:
+
+Updated the auto-serialize feature for control methods. This feature
+automatically serializes all methods that create named objects in order
+to prevent runtime errors. The update adds support to ignore the
+currently executing AML SyncLevel when invoking such a method, in order
+to prevent disruption of any existing SyncLevel priorities that may exist
+in the AML code. Although the use of SyncLevels is relatively rare, this
+change fixes a regression where an AE_AML_MUTEX_ORDER exception can
+appear on some machines starting with the 20140214 release.
+
+Added a new external interface to allow the host to install ACPI tables
+very early, before the namespace is even created. AcpiInstallTable gives
+the host additional flexibility for ACPI table management. Tables can be
+installed directly by the host as if they had originally appeared in the
+XSDT/RSDT. Installed tables can be SSDTs or other ACPI data tables
+(anything except the DSDT and FACS). Adds a new file, tbdata.c, along
+with additional internal restructuring and cleanup. See the ACPICA
+Reference for interface details. Lv Zheng.
+
+Added validation of the checksum for all incoming dynamically loaded
+tables (via external interfaces or via AML Load/LoadTable operators). Lv
+Zheng.
+
+Updated the use of the AcpiOsWaitEventsComplete interface during Notify
+and GPE handler removal. Restructured calls to eliminate possible race
+conditions. Lv Zheng.
+
+Added a warning for the use/execution of the ASL/AML Unload (table)
+operator. This will help detect and identify machines that use this
+operator if and when it is ever used. This operator has never been seen
+in the field and the usage model and possible side-effects of the drastic
+runtime action of a full table removal are unknown.
+
+Reverted the use of #pragma push/pop which was introduced in the 20140214
+release. It appears that push and pop are not implemented by enough
+compilers to make the use of this feature feasible for ACPICA at this
+time. However, these operators may be deployed in a future ACPICA
+release.
+
+Added the missing EXPORT_SYMBOL macros for the install and remove SCI
+handler interfaces.
+
+Source code generation:
+1) Disabled the use of the "strchr" macro for the gcc-specific
+generation. For some versions of gcc, this macro can periodically expose
+a compiler bug which in turn causes compile-time error(s).
+2) Added support for PPC64 compilation. Colin Ian King.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 97.0K Code, 27.2K Data, 124.2K Total
+ Debug Version: 189.7K Code, 79.5K Data, 269.2K Total
+ Previous Release:
+ Non-Debug Version: 96.5K Code, 27.2K Data, 123.7K Total
+ Debug Version: 188.6K Code, 79.0K Data, 267.6K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Added several new features to improve the readability of
+the resulting ASL code. Extra information is emitted within comment
+fields in the ASL code:
+1) Known _HID/_CID values are decoded to descriptive text.
+2) Standard values for the Notify() operator are decoded to descriptive
+text.
+3) Target operands are expanded to full pathnames (in a comment) when
+possible.
+
+Disassembler: Miscellaneous updates for extern() handling:
+1) Abort compiler if file specified by -fe option does not exist.
+2) Silence unnecessary warnings about argument count mismatches.
+3) Update warning messages concerning unresolved method externals.
+4) Emit "UnknownObj" keyword for externals whose type cannot be
+determined.
+
+AcpiHelp utility:
+1) Added the -a option to display both the ASL syntax and the AML
+encoding for an input ASL operator. This effectively displays all known
+information about an ASL operator with one AcpiHelp invocation.
+2) Added substring match support (similar to a wildcard) for the -i
+(_HID/PNP IDs) option.
+
+iASL/Disassembler: Since this tool does not yet support execution on big-
+endian machines, added detection of endianness and an error message if
+execution is attempted on big-endian. Support for big-endian within iASL
+is a feature that is on the ACPICA to-be-done list.
+
+AcpiBin utility:
+1) Remove option to extract binary files from an acpidump; this function
+is made obsolete by the AcpiXtract utility.
+2) General cleanup of open files and allocated buffers.
+
+----------------------------------------
+14 February 2014. Summary of changes for version 20140214:
+
+1) ACPICA kernel-resident subsystem:
+
+Implemented a new mechanism to proactively prevent problems with ill-
+behaved reentrant control methods that create named ACPI objects. This
+behavior is illegal as per the ACPI specification, but is nonetheless
+frequently seen in the field. Previously, this could lead to an
+AE_ALREADY_EXISTS exception if the method was actually entered by more
+than one thread. This new mechanism detects such methods at table load
+time and marks them "serialized" to prevent reentrancy. A new global
+option, AcpiGbl_AutoSerializeMethods, has been added to disable this
+feature if desired. This mechanism and global option obsoletes and
+supersedes the previous AcpiGbl_SerializeAllMethods option.
+
+Added the "Windows 2013" string to the _OSI support. ACPICA will now
+respond TRUE to _OSI queries with this string. It is the stated policy of
+ACPICA to add new strings to the _OSI support as soon as possible after
+they are defined. See the full ACPICA _OSI policy which has been added to
+the utilities/utosi.c file.
+
+Hardened/updated the _PRT return value auto-repair code:
+1) Do not abort the repair on a single subpackage failure, continue to
+check all subpackages.
+2) Add check for the minimum subpackage length (4).
+3) Properly handle extraneous NULL package elements.
+
+Added support to avoid the possibility of infinite loops when traversing
+object linked lists. Never allow an infinite loop, even in the face of
+corrupted object lists.
+
+ACPICA headers: Deployed the use of #pragma pack(push) and #pragma
+pack(pop) directives to ensure that the ACPICA headers are independent of
+compiler settings or other host headers.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.5K Code, 27.2K Data, 123.7K Total
+ Debug Version: 188.6K Code, 79.0K Data, 267.6K Total
+ Previous Release:
+ Non-Debug Version: 96.2K Code, 27.0K Data, 123.2K Total
+ Debug Version: 187.5K Code, 78.3K Data, 265.8K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/Table-compiler: Fixed a problem with support for the SPMI table. The
+first reserved field was incorrectly forced to have a value of zero. This
+change correctly forces the field to have a value of one. ACPICA BZ 1081.
+
+Debugger: Added missing support for the "Extra" and "Data" subobjects
+when displaying object data.
+
+Debugger: Added support to display entire object linked lists when
+displaying object data.
+
+iASL: Removed the obsolete -g option to obtain ACPI tables from the
+Windows registry. This feature has been superseded by the acpidump
+utility.
+
+----------------------------------------
+14 January 2014. Summary of changes for version 20140114:
+
+1) ACPICA kernel-resident subsystem:
+
+Updated all ACPICA copyrights and signons to 2014. Added the 2014
+copyright to all module headers and signons, including the standard Linux
+header. This affects virtually every file in the ACPICA core subsystem,
+iASL compiler, all ACPICA utilities, and the test suites.
+
+Improved parameter validation for AcpiInstallGpeBlock. Added the
+following checks:
+1) The incoming device handle refers to type ACPI_TYPE_DEVICE.
+2) There is not already a GPE block attached to the device.
+Likewise, with AcpiRemoveGpeBlock, ensure that the incoming object is a
+device.
+
+Correctly support "references" in the ACPI_OBJECT. This change fixes the
+support to allow references (namespace nodes) to be passed as arguments
+to control methods via the evaluate object interface. This is probably
+most useful for testing purposes, however.
+
+Improved support for 32/64 bit physical addresses in printf()-like
+output. This change improves the support for physical addresses in printf
+debug statements and other output on both 32-bit and 64-bit hosts. It
+consistently outputs the appropriate number of bytes for each host. The
+%p specifier is unsatisfactory since it does not emit uniform output on
+all hosts/clib implementations (on some, leading zeros are not supported,
+leading to difficult-to-read output).
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.2K Code, 27.0K Data, 123.2K Total
+ Debug Version: 187.5K Code, 78.3K Data, 265.8K Total
+ Previous Release:
+ Non-Debug Version: 96.1K Code, 27.0K Data, 123.1K Total
+ Debug Version: 185.6K Code, 77.3K Data, 262.9K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fix a possible fault when using the Connection() operator. Fixes a
+problem if the parent Field definition for the Connection operator refers
+to an operation region that does not exist. ACPICA BZ 1064.
+
+AcpiExec: Load of local test tables is now optional. The utility has the
+capability to load some various tables to test features of ACPICA.
+However, there are enough of them that the output of the utility became
+confusing. With this change, only the required local tables are displayed
+(RSDP, XSDT, etc.) along with the actual tables loaded via the command
+line specification. This makes the default output simler and easier to
+understand. The -el command line option restores the original behavior
+for testing purposes.
+
+AcpiExec: Added support for overlapping operation regions. This change
+expands the simulation of operation regions by supporting regions that
+overlap within the given address space. Supports SystemMemory and
+SystemIO. ASLTS test suite updated also. David Box. ACPICA BZ 1031.
+
+AcpiExec: Added region handler support for PCI_Config and EC spaces. This
+allows AcpiExec to simulate these address spaces, similar to the current
+support for SystemMemory and SystemIO.
+
+Debugger: Added new command to read/write/compare all namespace objects.
+The command "test objects" will exercise the entire namespace by writing
+new values to each data object, and ensuring that the write was
+successful. The original value is then restored and verified.
+
+Debugger: Added the "test predefined" command. This change makes this
+test public and puts it under the new "test" command. The test executes
+each and every predefined name within the current namespace.
+
+----------------------------------------
+18 December 2013. Summary of changes for version 20131218:
+
+Global note: The ACPI 5.0A specification was released this month. There
+are no changes needed for ACPICA since this release of ACPI is an
+errata/clarification release. The specification is available at
+acpi.info.
+
+
+1) ACPICA kernel-resident subsystem:
+
+Added validation of the XSDT root table if it is present. Some older
+platforms contain an XSDT that is ill-formed or otherwise invalid (such
+as containing some or all entries that are NULL pointers). This change
+adds a new function to validate the XSDT before actually using it. If the
+XSDT is found to be invalid, ACPICA will now automatically fall back to
+using the RSDT instead. Original implementation by Zhao Yakui. Ported to
+ACPICA and enhanced by Lv Zheng and Bob Moore.
+
+Added a runtime option to ignore the XSDT and force the use of the RSDT.
+This change adds a runtime option that will force ACPICA to use the RSDT
+instead of the XSDT (AcpiGbl_DoNotUseXsdt). Although the ACPI spec
+requires that an XSDT be used instead of the RSDT, the XSDT has been
+found to be corrupt or ill-formed on some machines. Lv Zheng.
+
+Added a runtime option to favor 32-bit FADT register addresses over the
+64-bit addresses. This change adds an option to favor 32-bit FADT
+addresses when there is a conflict between the 32-bit and 64-bit versions
+of the same register. The default behavior is to use the 64-bit version
+in accordance with the ACPI specification. This can now be overridden via
+the AcpiGbl_Use32BitFadtAddresses flag. ACPICA BZ 885. Lv Zheng.
+
+During the change above, the internal "Convert FADT" and "Verify FADT"
+functions have been merged to simplify the code, making it easier to
+understand and maintain. ACPICA BZ 933.
+
+Improve exception reporting and handling for GPE block installation.
+Return an actual status from AcpiEvGetGpeXruptBlock and don't clobber the
+status when exiting AcpiEvInstallGpeBlock. ACPICA BZ 1019.
+
+Added helper macros to extract bus/segment numbers from the HEST table.
+This change adds two macros to extract the encoded bus and segment
+numbers from the HEST Bus field - ACPI_HEST_BUS and ACPI_HEST_SEGMENT.
+Betty Dall <betty.dall@hp.com>
+
+Removed the unused ACPI_FREE_BUFFER macro. This macro is no longer used
+by ACPICA. It is not a public macro, so it should have no effect on
+existing OSV code. Lv Zheng.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.1K Code, 27.0K Data, 123.1K Total
+ Debug Version: 185.6K Code, 77.3K Data, 262.9K Total
+ Previous Release:
+ Non-Debug Version: 95.9K Code, 27.0K Data, 122.9K Total
+ Debug Version: 185.1K Code, 77.2K Data, 262.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Improved pathname support for emitted External()
+statements. This change adds full pathname support for external names
+that have been resolved internally by the inclusion of additional ACPI
+tables (via the iASL -e option). Without this change, the disassembler
+can emit multiple externals for the same object, or it become confused
+when the Scope() operator is used on an external object. Overall, greatly
+improves the ability to actually recompile the emitted ASL code when
+objects a referenced across multiple ACPI tables. Reported by Michael
+Tsirkin (mst@redhat.com).
+
+Tests/ASLTS: Updated functional control suite to execute with no errors.
+David Box. Fixed several errors related to the testing of the interpreter
+slack mode. Lv Zheng.
+
+iASL: Added support to detect names that are declared within a control
+method, but are unused (these are temporary names that are only valid
+during the time the method is executing). A remark is issued for these
+cases. ACPICA BZ 1022.
+
+iASL: Added full support for the DBG2 table. Adds full disassembler,
+table compiler, and template generator support for the DBG2 table (Debug
+Port 2 table).
+
+iASL: Added full support for the PCCT table, update the table definition.
+Updates the PCCT table definition in the actbl3.h header and adds table
+compiler and template generator support.
+
+iASL: Added an option to emit only error messages (no warnings/remarks).
+The -ve option will enable only error messages, warnings and remarks are
+suppressed. This can simplify debugging when only the errors are
+important, such as when an ACPI table is disassembled and there are many
+warnings and remarks -- but only the actual errors are of real interest.
+
+Example ACPICA code (source/tools/examples): Updated the example code so
+that it builds to an actual working program, not just example code. Added
+ACPI tables and execution of an example control method in the DSDT. Added
+makefile support for Unix generation.
+
+----------------------------------------
+15 November 2013. Summary of changes for version 20131115:
+
+This release is available at https://acpica.org/downloads
+
+
+1) ACPICA kernel-resident subsystem:
+
+Resource Manager: Fixed loop termination for the "get AML length"
+function. The loop previously had an error termination on a NULL resource
+pointer, which can never happen since the loop simply increments a valid
+resource pointer. This fix changes the loop to terminate with an error on
+an invalid end-of-buffer condition. The problem can be seen as an
+infinite loop by callers to AcpiSetCurrentResources with an invalid or
+corrupted resource descriptor, or a resource descriptor that is missing
+an END_TAG descriptor. Reported by Dan Carpenter
+<dan.carpenter@oracle.com>. Lv Zheng, Bob Moore.
+
+Table unload and ACPICA termination: Delete all attached data objects
+during namespace node deletion. This fix updates namespace node deletion
+to delete the entire list of attached objects (attached via
+AcpiAttachObject) instead of just one of the attached items. ACPICA BZ
+1024. Tomasz Nowicki (tomasz.nowicki@linaro.org).
+
+ACPICA termination: Added support to delete all objects attached to the
+root namespace node. This fix deletes any and all objects that have been
+attached to the root node via AcpiAttachData. Previously, none of these
+objects were deleted. Reported by Tomasz Nowicki. ACPICA BZ 1026.
+
+Debug output: Do not emit the function nesting level for the in-kernel
+build. The nesting level is really only useful during a single-thread
+execution. Therefore, only enable this output for the AcpiExec utility.
+Also, only emit the thread ID when executing under AcpiExec (Context
+switches are still always detected and a message is emitted). ACPICA BZ
+972.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 95.9K Code, 27.0K Data, 122.9K Total
+ Debug Version: 185.1K Code, 77.2K Data, 262.3K Total
+ Previous Release:
+ Non-Debug Version: 95.8K Code, 27.0K Data, 122.8K Total
+ Debug Version: 185.2K Code, 77.2K Data, 262.4K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec/Unix-OSL: Use <termios.h> instead of <termio.h>. This is the
+correct portable POSIX header for terminal control functions.
+
+Disassembler: Fixed control method invocation issues related to the use
+of the CondRefOf() operator. The problem is seen in the disassembly where
+control method invocations may not be disassembled properly if the
+control method name has been used previously as an argument to CondRefOf.
+The solution is to not attempt to emit an external declaration for the
+CondRefOf target (it is not necessary in the first place). This prevents
+disassembler object type confusion. ACPICA BZ 988.
+
+Unix Makefiles: Added an option to disable compiler optimizations and the
+_FORTIFY_SOURCE flag. Some older compilers have problems compiling ACPICA
+with optimizations (reportedly, gcc 4.4 for example). This change adds a
+command line option for make (NOOPT) that disables all compiler
+optimizations and the _FORTIFY_SOURCE compiler flag. The default
+optimization is -O2 with the _FORTIFY_SOURCE flag specified. ACPICA BZ
+1034. Lv Zheng, Bob Moore.
+
+Tests/ASLTS: Added options to specify individual test cases and modes.
+This allows testers running aslts.sh to optionally specify individual
+test modes and test cases. Also added an option to disable the forced
+generation of the ACPICA tools from source if desired. Lv Zheng.
+
+----------------------------------------
+27 September 2013. Summary of changes for version 20130927:
+
+This release is available at https://acpica.org/downloads
+
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a problem with store operations to reference objects. This change
+fixes a problem where a Store operation to an ArgX object that contained
+a
+reference to a field object did not complete the automatic dereference
+and
+then write to the actual field object. Instead, the object type of the
+field object was inadvertently changed to match the type of the source
+operand. The new behavior will actually write to the field object (buffer
+field or field unit), thus matching the correct ACPI-defined behavior.
+
+Implemented support to allow the host to redefine individual OSL
+prototypes. This change enables the host to redefine OSL prototypes found
+in the acpiosxf.h file. This allows the host to implement OSL interfaces
+with a macro or inlined function. Further, it allows the host to add any
+additional required modifiers such as __iomem, __init, __exit, etc., as
+necessary on a per-interface basis. Enables maximum flexibility for the
+OSL interfaces. Lv Zheng.
+
+Hardcoded the access width for the FADT-defined reset register. The ACPI
+specification requires the reset register width to be 8 bits. ACPICA now
+hardcodes the width to 8 and ignores the FADT width value. This provides
+compatibility with other ACPI implementations that have allowed BIOS code
+with bad register width values to go unnoticed. Matthew Garett, Bob
+Moore,
+Lv Zheng.
+
+Changed the position/use of the ACPI_PRINTF_LIKE macro. This macro is
+used
+in the OSL header (acpiosxf). The change modifies the position of this
+macro in each instance where it is used (AcpiDebugPrint, etc.) to avoid
+build issues if the OSL defines the implementation of the interface to be
+an inline stub function. Lv Zheng.
+
+Deployed a new macro ACPI_EXPORT_SYMBOL_INIT for the main ACPICA
+initialization interfaces. This change adds a new macro for the main init
+and terminate external interfaces in order to support hosts that require
+additional or different processing for these functions. Changed from
+ACPI_EXPORT_SYMBOL to ACPI_EXPORT_SYMBOL_INIT for these functions. Lv
+Zheng, Bob Moore.
+
+Cleaned up the memory allocation macros for configurability. In the
+common
+case, the ACPI_ALLOCATE and related macros now resolve directly to their
+respective AcpiOs* OSL interfaces. Two options:
+1) The ACPI_ALLOCATE_ZEROED macro uses a simple local implementation by
+default, unless overridden by the USE_NATIVE_ALLOCATE_ZEROED define.
+2) For AcpiExec (and for debugging), the macros can optionally be
+resolved
+to the local ACPICA interfaces that track each allocation (local tracking
+is used to immediately detect memory leaks).
+Lv Zheng.
+
+Simplified the configuration for ACPI_REDUCED_HARDWARE. Allows the kernel
+to predefine this macro to either TRUE or FALSE during the system build.
+
+Replaced __FUNCTION_ with __func__ in the gcc-specific header.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 95.8K Code, 27.0K Data, 122.8K Total
+ Debug Version: 185.2K Code, 77.2K Data, 262.4K Total
+ Previous Release:
+ Non-Debug Version: 96.7K Code, 27.1K Data, 123.9K Total
+ Debug Version: 184.4K Code, 76.8K Data, 261.2K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented wildcard support for the -e option. This simplifies use
+when there are many SSDTs that must be included to resolve external
+method
+declarations. ACPICA BZ 1041. Example:
+ iasl -e ssdt*.dat -d dsdt.dat
+
+AcpiExec: Add history/line-editing for Unix/Linux systems. This change
+adds a portable module that implements full history and limited line
+editing for Unix and Linux systems. It does not use readline() due to
+portability issues. Instead it uses the POSIX termio interface to put the
+terminal in raw input mode so that the various special keys can be
+trapped
+(such as up/down-arrow for history support and left/right-arrow for line
+editing). Uses the existing debugger history mechanism. ACPICA BZ 1036.
+
+AcpiXtract: Add support to handle (ignore) "empty" lines containing only
+one or more spaces. This provides compatible with early or different
+versions of the AcpiDump utility. ACPICA BZ 1044.
+
+AcpiDump: Do not ignore tables that contain only an ACPI table header.
+Apparently, some BIOSs create SSDTs that contain an ACPI table header but
+no other data. This change adds support to dump these tables. Any tables
+shorter than the length of an ACPI table header remain in error (an error
+message is emitted). Reported by Yi Li.
+
+Debugger: Echo actual command along with the "unknown command" message.
+
+----------------------------------------
+23 August 2013. Summary of changes for version 20130823:
+
+1) ACPICA kernel-resident subsystem:
+
+Implemented support for host-installed System Control Interrupt (SCI)
+handlers. Certain ACPI functionality requires the host to handle raw
+SCIs. For example, the "SCI Doorbell" that is defined for memory power
+state support requires the host device driver to handle SCIs to examine
+if the doorbell has been activated. Multiple SCI handlers can be
+installed to allow for future expansion. New external interfaces are
+AcpiInstallSciHandler, AcpiRemoveSciHandler; see the ACPICA reference for
+details. Lv Zheng, Bob Moore. ACPICA BZ 1032.
+
+Operation region support: Never locally free the handler "context"
+pointer. This change removes some dangerous code that attempts to free
+the handler context pointer in some (rare) circumstances. The owner of
+the handler owns this pointer and the ACPICA code should never touch it.
+Although not seen to be an issue in any kernel, it did show up as a
+problem (fault) under AcpiExec. Also, set the internal storage field for
+the context pointer to zero when the region is deactivated, simply for
+sanity. David Box. ACPICA BZ 1039.
+
+AcpiRead: On error, do not modify the return value target location. If an
+error happens in the middle of a split 32/32 64-bit I/O operation, do not
+modify the target of the return value pointer. Makes the code consistent
+with the rest of ACPICA. Bjorn Helgaas.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.7K Code, 27.1K Data, 123.9K Total
+ Debug Version: 184.4K Code, 76.8K Data, 261.2K Total
+ Previous Release:
+ Non-Debug Version: 96.2K Code, 27.1K Data, 123.3K Total
+ Debug Version: 185.4K Code, 77.1K Data, 262.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiDump: Implemented several new features and fixed some problems:
+1) Added support to dump the RSDP, RSDT, and XSDT tables.
+2) Added support for multiple table instances (SSDT, UEFI).
+3) Added option to dump "customized" (overridden) tables (-c).
+4) Fixed a problem where some table filenames were improperly
+constructed.
+5) Improved some error messages, removed some unnecessary messages.
+
+iASL: Implemented additional support for disassembly of ACPI tables that
+contain invocations of external control methods. The -fe<file> option
+allows the import of a file that specifies the external methods along
+with the required number of arguments for each -- allowing for the
+correct disassembly of the table. This is a workaround for a limitation
+of AML code where the disassembler often cannot determine the number of
+arguments required for an external control method and generates incorrect
+ASL code. See the iASL reference for details. ACPICA BZ 1030.
+
+Debugger: Implemented a new command (paths) that displays the full
+pathnames (namepaths) and object types of all objects in the namespace.
+This is an alternative to the namespace command.
+
+Debugger: Implemented a new command (sci) that invokes the SCI dispatch
+mechanism and any installed handlers.
+
+iASL: Fixed a possible segfault for "too many parent prefixes" condition.
+This can occur if there are too many parent prefixes in a namepath (for
+example, ^^^^^^PCI0.ECRD). ACPICA BZ 1035.
+
+Application OSLs: Set the return value for the PCI read functions. These
+functions simply return AE_OK, but should set the return value to zero
+also. This change implements this. ACPICA BZ 1038.
+
+Debugger: Prevent possible command line buffer overflow. Increase the
+size of a couple of the debugger line buffers, and ensure that overflow
+cannot happen. ACPICA BZ 1037.
+
+iASL: Changed to abort immediately on serious errors during the parsing
+phase. Due to the nature of ASL, there is no point in attempting to
+compile these types of errors, and they typically end up causing a
+cascade of hundreds of errors which obscure the original problem.
+
+----------------------------------------
+25 July 2013. Summary of changes for version 20130725:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a problem with the DerefOf operator where references to FieldUnits
+and BufferFields incorrectly returned the parent object, not the actual
+value of the object. After this change, a dereference of a FieldUnit
+reference results in a read operation on the field to get the value, and
+likewise, the appropriate BufferField value is extracted from the target
+buffer.
+
+Fixed a problem where the _WAK method could cause a fault under these
+circumstances: 1) Interpreter slack mode was not enabled, and 2) the _WAK
+method returned no value. The problem is rarely seen because most kernels
+run ACPICA in slack mode.
+
+For the DerefOf operator, a fatal error now results if an attempt is made
+to dereference a reference (created by the Index operator) to a NULL
+package element. Provides compatibility with other ACPI implementations,
+and this behavior will be added to a future version of the ACPI
+specification.
+
+The ACPI Power Management Timer (defined in the FADT) is now optional.
+This provides compatibility with other ACPI implementations and will
+appear in the next version of the ACPI specification. If there is no PM
+Timer on the platform, AcpiGetTimer returns AE_SUPPORT. An address of
+zero in the FADT indicates no PM timer.
+
+Implemented a new interface for _OSI support, AcpiUpdateInterfaces. This
+allows the host to globally enable/disable all vendor strings, all
+feature strings, or both. Intended to be primarily used for debugging
+purposes only. Lv Zheng.
+
+Expose the collected _OSI data to the host via a global variable. This
+data tracks the highest level vendor ID that has been invoked by the BIOS
+so that the host (and potentially ACPICA itself) can change behaviors
+based upon the age of the BIOS.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.2K Code, 27.1K Data, 123.3K Total
+ Debug Version: 184.4K Code, 76.8K Data, 261.2K Total
+ Previous Release:
+ Non-Debug Version: 95.9K Code, 26.9K Data, 122.8K Total
+ Debug Version: 184.1K Code, 76.7K Data, 260.8K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Created the following enhancements for the -so option (create
+offset table):
+1)Add offsets for the last nameseg in each namepath for every supported
+object type
+2)Add support for Processor, Device, Thermal Zone, and Scope objects
+3)Add the actual AML opcode for the parent object of every supported
+object type
+4)Add support for the ZERO/ONE/ONES AML opcodes for integer objects
+
+Disassembler: Emit all unresolved external symbols in a single block.
+These are external references to control methods that could not be
+resolved, and thus, the disassembler had to make a guess at the number of
+arguments to parse.
+
+iASL: The argument to the -T option (create table template) is now
+optional. If not specified, the default table is a DSDT, typically the
+most common case.
+
+----------------------------------------
+26 June 2013. Summary of changes for version 20130626:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed an issue with runtime repair of the _CST object. Null or invalid
+elements were not always removed properly. Lv Zheng.
+
+Removed an arbitrary restriction of 256 GPEs per GPE block (such as the
+FADT-defined GPE0 and GPE1). For GPE0, GPE1, and each GPE Block Device,
+the maximum number of GPEs is 1016. Use of multiple GPE block devices
+makes the system-wide number of GPEs essentially unlimited.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 95.9K Code, 26.9K Data, 122.8K Total
+ Debug Version: 184.1K Code, 76.7K Data, 260.8K Total
+ Previous Release:
+ Non-Debug Version: 96.0K Code, 27.0K Data, 123.0K Total
+ Debug Version: 184.1K Code, 76.8K Data, 260.9K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Portable AcpiDump: Implemented full support for the Linux and FreeBSD
+hosts. Now supports Linux, FreeBSD, and Windows.
+
+Disassembler: Added some missing types for the HEST and EINJ tables: "Set
+Error Type With Address", "CMCI", "MCE", and "Flush Cacheline".
+
+iASL/Preprocessor: Implemented full support for nested
+#if/#else/#elif/#endif blocks. Allows arbitrary depth of nested blocks.
+
+Disassembler: Expanded maximum output string length to 64K. Was 256 bytes
+max. The original purpose of this constraint was to limit the amount of
+debug output. However, the string function in question (UtPrintString) is
+now used for the disassembler also, where 256 bytes is insufficient.
+Reported by RehabMan@GitHub.
+
+iASL/DataTables: Fixed some problems and issues with compilation of DMAR
+tables. ACPICA BZ 999. Lv Zheng.
+
+iASL: Fixed a couple of error exit issues that could result in a "Could
+not delete <file>" message during ASL compilation.
+
+AcpiDump: Allow "FADT" and "MADT" as valid table signatures, even though
+the actual signatures for these tables are "FACP" and "APIC",
+respectively.
+
+AcpiDump: Added support for multiple UEFI tables. Only SSDT and UEFI
+tables are allowed to have multiple instances.
+
+----------------------------------------
+17 May 2013. Summary of changes for version 20130517:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a regression introduced in version 20130328 for _INI methods. This
+change fixes a problem introduced in 20130328 where _INI methods are no
+longer executed properly because of a memory block that was not
+initialized correctly. ACPICA BZ 1016. Tomasz Nowicki
+<tomasz.nowicki@linaro.org>.
+
+Fixed a possible problem with the new extended sleep registers in the
+ACPI
+5.0 FADT. Do not use these registers (even if populated) unless the HW-
+reduced bit is set in the FADT (as per the ACPI specification). ACPICA BZ
+1020. Lv Zheng.
+
+Implemented return value repair code for _CST predefined objects: Sort
+the
+list and detect/remove invalid entries. ACPICA BZ 890. Lv Zheng.
+
+Implemented a debug-only option to disable loading of SSDTs from the
+RSDT/XSDT during ACPICA initialization. This can be useful for debugging
+ACPI problems on some machines. Set AcpiGbl_DisableSsdtTableLoad in
+acglobal.h - ACPICA BZ 1005. Lv Zheng.
+
+Fixed some issues in the ACPICA initialization and termination code:
+Tomasz Nowicki <tomasz.nowicki@linaro.org>
+1) Clear events initialized flag upon event component termination. ACPICA
+BZ 1013.
+2) Fixed a possible memory leak in GPE init error path. ACPICA BZ 1018.
+3) Delete global lock pending lock during termination. ACPICA BZ 1012.
+4) Clear debug buffer global on termination to prevent possible multiple
+delete. ACPICA BZ 1010.
+
+Standardized all switch() blocks across the entire source base. After
+many
+years, different formatting for switch() had crept in. This change makes
+the formatting of every switch block identical. ACPICA BZ 997. Chao Guan.
+
+Split some files to enhance ACPICA modularity and configurability:
+1) Split buffer dump routines into utilities/utbuffer.c
+2) Split internal error message routines into utilities/uterror.c
+3) Split table print utilities into tables/tbprint.c
+4) Split iASL command-line option processing into asloptions.c
+
+Makefile enhancements:
+1) Support for all new files above.
+2) Abort make on errors from any subcomponent. Chao Guan.
+3) Add build support for Apple Mac OS X. Liang Qi.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 96.0K Code, 27.0K Data, 123.0K Total
+ Debug Version: 184.1K Code, 76.8K Data, 260.9K Total
+ Previous Release:
+ Non-Debug Version: 95.6K Code, 26.8K Data, 122.4K Total
+ Debug Version: 183.5K Code, 76.6K Data, 260.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+New utility: Implemented an easily portable version of the acpidump
+utility to extract ACPI tables from the system (or a file) in an ASCII
+hex
+dump format. The top-level code implements the various command line
+options, file I/O, and table dump routines. To port to a new host, only
+three functions need to be implemented to get tables -- since this
+functionality is OS-dependent. See the tools/acpidump/apmain.c module and
+the ACPICA reference for porting instructions. ACPICA BZ 859. Notes:
+1) The Windows version obtains the ACPI tables from the Registry.
+2) The Linux version is under development.
+3) Other hosts - If an OS-dependent module is submitted, it will be
+distributed with ACPICA.
+
+iASL: Fixed a regression for -D preprocessor option (define symbol). A
+restructuring/change to the initialization sequence caused this option to
+no longer work properly.
+
+iASL: Implemented a mechanism to disable specific warnings and remarks.
+Adds a new command line option, "-vw <messageid> as well as "#pragma
+disable <messageid>". ACPICA BZ 989. Chao Guan, Bob Moore.
+
+iASL: Fix for too-strict package object validation. The package object
+validation for return values from the predefined names is a bit too
+strict, it does not allow names references within the package (which will
+be resolved at runtime.) These types of references cannot be validated at
+compile time. This change ignores named references within package objects
+for names that return or define static packages.
+
+Debugger: Fixed the 80-character command line limitation for the History
+command. Now allows lines of arbitrary length. ACPICA BZ 1000. Chao Guan.
+
+iASL: Added control method and package support for the -so option
+(generates AML offset table for BIOS support.)
+
+iASL: issue a remark if a non-serialized method creates named objects. If
+a thread blocks within the method for any reason, and another thread
+enters the method, the method will fail because an attempt will be made
+to
+create the same (named) object twice. In this case, issue a remark that
+the method should be marked serialized. NOTE: may become a warning later.
+ACPICA BZ 909.
+
+----------------------------------------
+18 April 2013. Summary of changes for version 20130418:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a possible buffer overrun during some rare but specific field unit
+read operations. This overrun can only happen if the DSDT version is 1 --
+meaning that all AML integers are 32 bits -- and the field length is
+between 33 and 55 bits long. During the read, an internal buffer object
+is
+created for the field unit because the field is larger than an integer
+(32
+bits). However, in this case, the buffer will be incorrectly written
+beyond the end because the buffer length is less than the internal
+minimum
+of 64 bits (8 bytes) long. The buffer will be either 5, 6, or 7 bytes
+long, but a full 8 bytes will be written.
+
+Updated the Embedded Controller "orphan" _REG method support. This refers
+to _REG methods under the EC device that have no corresponding operation
+region. This is allowed by the ACPI specification. This update removes a
+dependency on the existence an ECDT table. It will execute an orphan _REG
+method as long as the operation region handler for the EC is installed at
+the EC device node and not the namespace root. Rui Zhang (original
+update), Bob Moore (update/integrate).
+
+Implemented run-time argument typechecking for all predefined ACPI names
+(_STA, _BIF, etc.) This change performs object typechecking on all
+incoming arguments for all predefined names executed via
+AcpiEvaluateObject. This ensures that ACPI-related device drivers are
+passing correct object types as well as the correct number of arguments
+(therefore identifying any issues immediately). Also, the ASL/namespace
+definition of the predefined name is checked against the ACPI
+specification for the proper argument count. Adds one new file,
+nsarguments.c
+
+Changed an exception code for the ASL UnLoad() operator. Changed the
+exception code for the case where the input DdbHandle is invalid, from
+AE_BAD_PARAMETER to the more appropriate AE_AML_OPERAND_TYPE.
+
+Unix/Linux makefiles: Removed the use of the -O2 optimization flag in the
+global makefile. The use of this flag causes compiler errors on earlier
+versions of GCC, so it has been removed for compatibility.
+
+Miscellaneous cleanup:
+1) Removed some unused/obsolete macros
+2) Fixed a possible memory leak in the _OSI support
+3) Removed an unused variable in the predefined name support
+4) Windows OSL: remove obsolete reference to a memory list field
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 95.2K Code, 26.4K Data, 121.6K Total
+ Debug Version: 183.0K Code, 76.0K Data, 259.0K Total
+ Previous Release:
+ Non-Debug Version: 95.6K Code, 26.8K Data, 122.4K Total
+ Debug Version: 183.5K Code, 76.6K Data, 260.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec: Added installation of a handler for the SystemCMOS address
+space. This prevents control method abort if a method accesses this
+space.
+
+AcpiExec: Added support for multiple EC devices, and now install EC
+operation region handler(s) at the actual EC device instead of the
+namespace root. This reflects the typical behavior of host operating
+systems.
+
+AcpiExec: Updated to ensure that all operation region handlers are
+installed before the _REG methods are executed. This prevents a _REG
+method from aborting if it accesses an address space has no handler.
+AcpiExec installs a handler for every possible address space.
+
+Debugger: Enhanced the "handlers" command to display non-root handlers.
+This change enhances the handlers command to display handlers associated
+with individual devices throughout the namespace, in addition to the
+currently supported display of handlers associated with the root
+namespace
+node.
+
+ASL Test Suite: Several test suite errors have been identified and
+resolved, reducing the total error count during execution. Chao Guan.
+
+----------------------------------------
+28 March 2013. Summary of changes for version 20130328:
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed several possible race conditions with the internal object reference
+counting mechanism. Some of the external ACPICA interfaces update object
+reference counts without holding the interpreter or namespace lock. This
+change adds a spinlock to protect reference count updates on the internal
+ACPICA objects. Reported by and with assistance from Andriy Gapon
+(avg@FreeBSD.org).
+
+FADT support: Removed an extraneous warning for very large GPE register
+sets. This change removes a size mismatch warning if the legacy length
+field for a GPE register set is larger than the 64-bit GAS structure can
+accommodate. GPE register sets can be larger than the 255-bit width
+limitation of the GAS structure. Linn Crosetto (linn@hp.com).
+
+_OSI Support: handle any errors from AcpiOsAcquireMutex. Check for error
+return from this interface. Handles a possible timeout case if
+ACPI_WAIT_FOREVER is modified by the host to be a value less than
+"forever". Jung-uk Kim.
+
+Predefined name support: Add allowed/required argument type information
+to
+the master predefined info table. This change adds the infrastructure to
+enable typechecking on incoming arguments for all predefined
+methods/objects. It does not actually contain the code that will fully
+utilize this information, this is still under development. Also condenses
+some duplicate code for the predefined names into a new module,
+utilities/utpredef.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 95.0K Code, 25.9K Data, 120.9K Total
+ Debug Version: 182.9K Code, 75.6K Data, 258.5K Total
+ Current Release:
+ Non-Debug Version: 95.2K Code, 26.4K Data, 121.6K Total
+ Debug Version: 183.0K Code, 76.0K Data, 259.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented a new option to simplify the development of ACPI-
+related
+BIOS code. Adds support for a new "offset table" output file. The -so
+option will create a C table containing the AML table offsets of various
+named objects in the namespace so that BIOS code can modify them easily
+at
+boot time. This can simplify BIOS runtime code by eliminating expensive
+searches for "magic values", enhancing boot times and adding greater
+reliability. With assistance from Lee Hamel.
+
+iASL: Allow additional predefined names to return zero-length packages.
+Now, all predefined names that are defined by the ACPI specification to
+return a "variable-length package of packages" are allowed to return a
+zero length top-level package. This allows the BIOS to tell the host that
+the requested feature is not supported, and supports existing BIOS/ASL
+code and practices.
+
+iASL: Changed the "result not used" warning to an error. This is the case
+where an ASL operator is effectively a NOOP because the result of the
+operation is not stored anywhere. For example:
+ Add (4, Local0)
+There is no target (missing 3rd argument), nor is the function return
+value used. This is potentially a very serious problem -- since the code
+was probably intended to do something, but for whatever reason, the value
+was not stored. Therefore, this issue has been upgraded from a warning to
+an error.
+
+AcpiHelp: Added allowable/required argument types to the predefined names
+info display. This feature utilizes the recent update to the predefined
+names table (above).
+
+----------------------------------------
+14 February 2013. Summary of changes for version 20130214:
+
+1) ACPICA Kernel-resident Subsystem:
+
+Fixed a possible regression on some hosts: Reinstated the safe return
+macros (return_ACPI_STATUS, etc.) that ensure that the argument is
+evaluated only once. Although these macros are not needed for the ACPICA
+code itself, they are often used by ACPI-related host device drivers
+where
+the safe feature may be necessary.
+
+Fixed several issues related to the ACPI 5.0 reduced hardware support
+(SOC): Now ensure that if the platform declares itself as hardware-
+reduced
+via the FADT, the following functions become NOOPs (and always return
+AE_OK) because ACPI is always enabled by definition on these machines:
+ AcpiEnable
+ AcpiDisable
+ AcpiHwGetMode
+ AcpiHwSetMode
+
+Dynamic Object Repair: Implemented additional runtime repairs for
+predefined name return values. Both of these repairs can simplify code in
+the related device drivers that invoke these methods:
+1) For the _STR and _MLS names, automatically repair/convert an ASCII
+string to a Unicode buffer.
+2) For the _CRS, _PRS, and _DMA names, return a resource descriptor with
+a
+lone end tag descriptor in the following cases: A Return(0) was executed,
+a null buffer was returned, or no object at all was returned (non-slack
+mode only). Adds a new file, nsconvert.c
+ACPICA BZ 998. Bob Moore, Lv Zheng.
+
+Resource Manager: Added additional code to prevent possible infinite
+loops
+while traversing corrupted or ill-formed resource template buffers. Check
+for zero-length resource descriptors in all code that loops through
+resource templates (the length field is used to index through the
+template). This change also hardens the external AcpiWalkResources and
+AcpiWalkResourceBuffer interfaces.
+
+Local Cache Manager: Enhanced the main data structure to eliminate an
+unnecessary mechanism to access the next object in the list. Actually
+provides a small performance enhancement for hosts that use the local
+ACPICA cache manager. Jung-uk Kim.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 94.5K Code, 25.4K Data, 119.9K Total
+ Debug Version: 182.3K Code, 75.0K Data, 257.3K Total
+ Current Release:
+ Non-Debug Version: 95.0K Code, 25.9K Data, 120.9K Total
+ Debug Version: 182.9K Code, 75.6K Data, 258.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/Disassembler: Fixed several issues with the definition of the ACPI
+5.0 RASF table (RAS Feature Table). This change incorporates late changes
+that were made to the ACPI 5.0 specification.
+
+iASL/Disassembler: Added full support for the following new ACPI tables:
+ 1) The MTMR table (MID Timer Table)
+ 2) The VRTC table (Virtual Real Time Clock Table).
+Includes header file, disassembler, table compiler, and template support
+for both tables.
+
+iASL: Implemented compile-time validation of package objects returned by
+predefined names. This new feature validates static package objects
+returned by the various predefined names defined to return packages. Both
+object types and package lengths are validated, for both parent packages
+and sub-packages, if any. The code is similar in structure and behavior
+to
+the runtime repair mechanism within the AML interpreter and uses the
+existing predefined name information table. Adds a new file, aslprepkg.c.
+ACPICA BZ 938.
+
+iASL: Implemented auto-detection of binary ACPI tables for disassembly.
+This feature detects a binary file with a valid ACPI table header and
+invokes the disassembler automatically. Eliminates the need to
+specifically invoke the disassembler with the -d option. ACPICA BZ 862.
+
+iASL/Disassembler: Added several warnings for the case where there are
+unresolved control methods during the disassembly. This can potentially
+cause errors when the output file is compiled, because the disassembler
+assumes zero method arguments in these cases (it cannot determine the
+actual number of arguments without resolution/definition of the method).
+
+Debugger: Added support to display all resources with a single command.
+Invocation of the resources command with no arguments will now display
+all
+resources within the current namespace.
+
+AcpiHelp: Added descriptive text for each ACPICA exception code displayed
+via the -e option.
+
+----------------------------------------
+17 January 2013. Summary of changes for version 20130117:
+
+1) ACPICA Kernel-resident Subsystem:
+
+Updated the AcpiGetSleepTypeData interface: Allow the \_Sx methods to
+return either 1 or 2 integers. Although the ACPI spec defines the \_Sx
+objects to return a package containing one integer, most BIOS code
+returns
+two integers and the previous code reflects that. However, we also need
+to
+support BIOS code that actually implements to the ACPI spec, and this
+change reflects this.
+
+Fixed two issues with the ACPI_DEBUG_PRINT macros:
+1) Added the ACPI_DO_WHILE macro to the main DEBUG_PRINT helper macro for
+C compilers that require this support.
+2) Renamed the internal ACPI_DEBUG macro to ACPI_DO_DEBUG_PRINT since
+ACPI_DEBUG is already used by many of the various hosts.
+
+Updated all ACPICA copyrights and signons to 2013. Added the 2013
+copyright to all module headers and signons, including the standard Linux
+header. This affects virtually every file in the ACPICA core subsystem,
+iASL compiler, all ACPICA utilities, and the test suites.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 94.5K Code, 25.5K Data, 120.0K Total
+ Debug Version: 182.2K Code, 74.9K Data, 257.1K Total
+ Current Release:
+ Non-Debug Version: 94.5K Code, 25.4K Data, 119.9K Total
+ Debug Version: 182.3K Code, 75.0K Data, 257.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Generic Unix OSL: Use a buffer to eliminate multiple vfprintf()s and
+prevent a possible fault on some hosts. Some C libraries modify the arg
+pointer parameter to vfprintf making it difficult to call it twice in the
+AcpiOsVprintf function. Use a local buffer to workaround this issue. This
+does not affect the Windows OSL since the Win C library does not modify
+the arg pointer. Chao Guan, Bob Moore.
+
+iASL: Fixed a possible infinite loop when the maximum error count is
+reached. If an output file other than the .AML file is specified (such as
+a listing file), and the maximum number of errors is reached, do not
+attempt to flush data to the output file(s) as the compiler is aborting.
+This can cause an infinite loop as the max error count code essentially
+keeps calling itself.
+
+iASL/Disassembler: Added an option (-in) to ignore NOOP
+opcodes/operators.
+Implemented for both the compiler and the disassembler. Often, the NOOP
+opcode is used as padding for packages that are changed dynamically by
+the
+BIOS. When disassembled and recompiled, these NOOPs will cause syntax
+errors. This option causes the disassembler to ignore all NOOP opcodes
+(0xA3), and it also causes the compiler to ignore all ASL source code
+NOOP
+statements as well.
+
+Debugger: Enhanced the Sleep command to execute all sleep states. This
+change allows Sleep to be invoked with no arguments and causes the
+debugger to execute all of the sleep states, 0-5, automatically.
+
+----------------------------------------
+20 December 2012. Summary of changes for version 20121220:
+
+1) ACPICA Kernel-resident Subsystem:
+
+Implemented a new interface, AcpiWalkResourceBuffer. This interface is an
+alternate entry point for AcpiWalkResources and improves the usability of
+the resource manager by accepting as input a buffer containing the output
+of either a _CRS, _PRS, or _AEI method. The key functionality is that the
+input buffer is not deleted by this interface so that it can be used by
+the host later. See the ACPICA reference for details.
+
+Interpreter: Add a warning if a 64-bit constant appears in a 32-bit table
+(DSDT version < 2). The constant will be truncated and this warning
+reflects that behavior.
+
+Resource Manager: Add support for the new ACPI 5.0 wake bit in the IRQ,
+ExtendedInterrupt, and GpioInt descriptors. This change adds support to
+both get and set the new wake bit in these descriptors, separately from
+the existing share bit. Reported by Aaron Lu.
+
+Interpreter: Fix Store() when an implicit conversion is not possible. For
+example, in the cases such as a store of a string to an existing package
+object, implement the store as a CopyObject(). This is a small departure
+from the ACPI specification which states that the control method should
+be
+aborted in this case. However, the ASLTS suite depends on this behavior.
+
+Performance improvement for the various FUNCTION_TRACE and DEBUG_PRINT
+macros: check if debug output is currently enabled as soon as possible to
+minimize performance impact if debug is in fact not enabled.
+
+Source code restructuring: Cleanup to improve modularity. The following
+new files have been added: dbconvert.c, evhandler.c, nsprepkg.c,
+psopinfo.c, psobject.c, rsdumpinfo.c, utstring.c, and utownerid.c.
+Associated makefiles and project files have been updated.
+
+Changed an exception code for LoadTable operator. For the case where one
+of the input strings is too long, change the returned exception code from
+AE_BAD_PARAMETER to AE_AML_STRING_LIMIT.
+
+Fixed a possible memory leak in dispatcher error path. On error, delete
+the mutex object created during method mutex creation. Reported by
+tim.gardner@canonical.com.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 94.3K Code, 25.3K Data, 119.6K Total
+ Debug Version: 175.5K Code, 74.5K Data, 250.0K Total
+ Current Release:
+ Non-Debug Version: 94.5K Code, 25.5K Data, 120.0K Total
+ Debug Version: 182.2K Code, 74.9K Data, 257.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Disallow a method call as argument to the ObjectType ASL operator.
+This change tracks an errata to the ACPI 5.0 document. The AML grammar
+will not allow the interpreter to differentiate between a method and a
+method invocation when these are used as an argument to the ObjectType
+operator. The ACPI specification change is to disallow a method
+invocation
+(UserTerm) for the ObjectType operator.
+
+Finish support for the TPM2 and CSRT tables in the headers, table
+compiler, and disassembler.
+
+Unix user-space OSL: Fix a problem with WaitSemaphore where the timeout
+always expires immediately if the semaphore is not available. The
+original
+code was using a relative-time timeout, but sem_timedwait requires the
+use
+of an absolute time.
+
+iASL: Added a remark if the Timer() operator is used within a 32-bit
+table. This operator returns a 64-bit time value that will be truncated
+within a 32-bit table.
+
+iASL Source code restructuring: Cleanup to improve modularity. The
+following new files have been added: aslhex.c, aslxref.c, aslnamesp.c,
+aslmethod.c, and aslfileio.c. Associated makefiles and project files have
+been updated.
+
+
+----------------------------------------
+14 November 2012. Summary of changes for version 20121114:
+
+1) ACPICA Kernel-resident Subsystem:
+
+Implemented a performance enhancement for ACPI/AML Package objects. This
+change greatly increases the performance of Package objects within the
+interpreter. It changes the processing of reference counts for packages
+by
+optimizing for the most common case where the package sub-objects are
+either Integers, Strings, or Buffers. Increases the overall performance
+of
+the ASLTS test suite by 1.5X (Increases the Slack Mode performance by
+2X.)
+Chao Guan. ACPICA BZ 943.
+
+Implemented and deployed common macros to extract flag bits from resource
+descriptors. Improves readability and maintainability of the code. Fixes
+a
+problem with the UART serial bus descriptor for the number of data bits
+flags (was incorrectly 2 bits, should be 3).
+
+Enhanced the ACPI_GETx and ACPI_SETx macros. Improved the implementation
+of the macros and changed the SETx macros to the style of (destination,
+source). Also added ACPI_CASTx companion macros. Lv Zheng.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.9K Code, 25.2K Data, 119.1K Total
+ Debug Version: 175.5K Code, 74.5K Data, 250.0K Total
+ Current Release:
+ Non-Debug Version: 94.3K Code, 25.3K Data, 119.6K Total
+ Debug Version: 175.5K Code, 74.5K Data, 250.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Added the new ACPI 5.0 interrupt sharing flags. This change
+adds the ShareAndWake and ExclusiveAndWake flags which were added to the
+Irq, Interrupt, and Gpio resource descriptors in ACPI 5.0. ACPICA BZ 986.
+
+Disassembler: Fixed a problem with external declaration generation. Fixes
+a problem where an incorrect pathname could be generated for an external
+declaration if the original reference to the object includes leading
+carats (^). ACPICA BZ 984.
+
+Debugger: Completed a major update for the Disassemble<method> command.
+This command was out-of-date and did not properly disassemble control
+methods that had any reasonable complexity. This fix brings the command
+up
+to the same level as the rest of the disassembler. Adds one new file,
+dmdeferred.c, which is existing code that is now common with the main
+disassembler and the debugger disassemble command. ACPICA MZ 978.
+
+iASL: Moved the parser entry prototype to avoid a duplicate declaration.
+Newer versions of Bison emit this prototype, so moved the prototype out
+of
+the iASL header to where it is actually used in order to avoid a
+duplicate
+declaration.
+
+iASL/Tools: Standardized use of the stream I/O functions:
+ 1) Ensure check for I/O error after every fopen/fread/fwrite
+ 2) Ensure proper order of size/count arguments for fread/fwrite
+ 3) Use test of (Actual != Requested) after all fwrite, and most fread
+ 4) Standardize I/O error messages
+Improves reliability and maintainability of the code. Bob Moore, Lv
+Zheng.
+ACPICA BZ 981.
+
+Disassembler: Prevent duplicate External() statements. During generation
+of external statements, detect similar pathnames that are actually
+duplicates such as these:
+ External (\ABCD)
+ External (ABCD)
+Remove all leading '\' characters from pathnames during the external
+statement generation so that duplicates will be detected and tossed.
+ACPICA BZ 985.
+
+Tools: Replace low-level I/O with stream I/O functions. Replace
+open/read/write/close with the stream I/O equivalents
+fopen/fread/fwrite/fclose for portability and performance. Lv Zheng, Bob
+Moore.
+
+AcpiBin: Fix for the dump-to-hex function. Now correctly output the table
+name header so that AcpiXtract recognizes the output file/table.
+
+iASL: Remove obsolete -2 option flag. Originally intended to force the
+compiler/disassembler into an ACPI 2.0 mode, this was never implemented
+and the entire concept is now obsolete.
+
+----------------------------------------
+18 October 2012. Summary of changes for version 20121018:
+
+
+1) ACPICA Kernel-resident Subsystem:
+
+Updated support for the ACPI 5.0 MPST table. Fixes some problems
+introduced by late changes to the table as it was added to the ACPI 5.0
+specification. Includes header, disassembler, and data table compiler
+support as well as a new version of the MPST template.
+
+AcpiGetObjectInfo: Enhanced the device object support to include the ACPI
+5.0 _SUB method. Now calls _SUB in addition to the other PNP-related ID
+methods: _HID, _CID, and _UID.
+
+Changed ACPI_DEVICE_ID to ACPI_PNP_DEVICE_ID. Also changed
+ACPI_DEVICE_ID_LIST to ACPI_PNP_DEVICE_ID_LIST. These changes prevent
+name collisions on hosts that reserve the *_DEVICE_ID (or *DeviceId)
+names for their various drivers. Affects the AcpiGetObjectInfo external
+interface, and other internal interfaces as well.
+
+Added and deployed a new macro for ACPI_NAME management: ACPI_MOVE_NAME.
+This macro resolves to a simple 32-bit move of the 4-character ACPI_NAME
+on machines that support non-aligned transfers. Optimizes for this case
+rather than using a strncpy. With assistance from Zheng Lv.
+
+Resource Manager: Small fix for buffer size calculation. Fixed a one byte
+error in the output buffer calculation. Feng Tang. ACPICA BZ 849.
+
+Added a new debug print message for AML mutex objects that are force-
+released. At control method termination, any currently acquired mutex
+objects are force-released. Adds a new debug-only message for each one
+that is released.
+
+Audited/updated all ACPICA return macros and the function debug depth
+counter: 1) Ensure that all functions that use the various TRACE macros
+also use the appropriate ACPICA return macros. 2) Ensure that all normal
+return statements surround the return expression (value) with parens to
+ensure consistency across the ACPICA code base. Guan Chao, Tang Feng,
+Zheng Lv, Bob Moore. ACPICA Bugzilla 972.
+
+Global source code changes/maintenance: All extra lines at the start and
+end of each source file have been removed for consistency. Also, within
+comments, all new sentences start with a single space instead of a double
+space, again for consistency across the code base.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.7K Code, 25.3K Data, 119.0K Total
+ Debug Version: 175.0K Code, 74.4K Data, 249.4K Total
+ Current Release:
+ Non-Debug Version: 93.9K Code, 25.2K Data, 119.1K Total
+ Debug Version: 175.5K Code, 74.5K Data, 250.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec: Improved the algorithm used for memory leak/corruption
+detection. Added some intelligence to the code that maintains the global
+list of allocated memory. The list is now ordered by allocated memory
+address, significantly improving performance. When running AcpiExec on
+the ASLTS test suite, speed improvements of 3X to 5X are seen, depending
+on the platform and/or the environment. Note, this performance
+enhancement affects the AcpiExec utility only, not the kernel-resident
+ACPICA code.
+
+Enhanced error reporting for invalid AML opcodes and bad ACPI_NAMEs. For
+the disassembler, dump the 48 bytes surrounding the invalid opcode. Fix
+incorrect table offset reported for invalid opcodes. Report the original
+32-bit value for bad ACPI_NAMEs (as well as the repaired name.)
+
+Disassembler: Enhanced the -vt option to emit the binary table data in
+hex format to assist with debugging.
+
+Fixed a potential filename buffer overflow in osunixdir.c. Increased the
+size of file structure. Colin Ian King.
+
+----------------------------------------
+13 September 2012. Summary of changes for version 20120913:
+
+
+1) ACPICA Kernel-resident Subsystem:
+
+ACPI 5.0: Added two new notify types for the Hardware Error Notification
+Structure within the Hardware Error Source Table (HEST) table -- CMCI(5)
+and
+MCE(6).
+
+Table Manager: Merged/removed duplicate code in the root table resize
+functions. One function is external, the other is internal. Lv Zheng,
+ACPICA
+BZ 846.
+
+Makefiles: Completely removed the obsolete "Linux" makefiles under
+acpica/generate/linux. These makefiles are obsolete and have been
+replaced
+by
+the generic unix makefiles under acpica/generate/unix.
+
+Makefiles: Ensure that binary files always copied properly. Minor rule
+change
+to ensure that the final binary output files are always copied up to the
+appropriate binary directory (bin32 or bin64.)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.8K Code, 25.3K Data, 119.1K Total
+ Debug Version: 175.7K Code, 74.8K Data, 250.5K Total
+ Current Release:
+ Non-Debug Version: 93.7K Code, 25.3K Data, 119.0K Total
+ Debug Version: 175.0K Code, 74.4K Data, 249.4K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a possible fault during the disassembly of resource
+descriptors when a second parse is required because of the invocation of
+external control methods within the table. With assistance from
+adq@lidskialf.net. ACPICA BZ 976.
+
+iASL: Fixed a namepath optimization problem. An error can occur if the
+parse
+node that contains the namepath to be optimized does not have a parent
+node
+that is a named object. This change fixes the problem.
+
+iASL: Fixed a regression where the AML file is not deleted on errors. The
+AML
+output file should be deleted if there are any errors during the
+compiler.
+The
+only exception is if the -f (force output) option is used. ACPICA BZ 974.
+
+iASL: Added a feature to automatically increase internal line buffer
+sizes.
+Via realloc(), automatically increase the internal line buffer sizes as
+necessary to support very long source code lines. The current version of
+the
+preprocessor requires a buffer long enough to contain full source code
+lines.
+This change increases the line buffer(s) if the input lines go beyond the
+current buffer size. This eliminates errors that occurred when a source
+code
+line was longer than the buffer.
+
+iASL: Fixed a problem with constant folding in method declarations. The
+SyncLevel term is a ByteConstExpr, and incorrect code would be generated
+if a
+Type3 opcode was used.
+
+Debugger: Improved command help support. For incorrect argument count,
+display
+full help for the command. For help command itself, allow an argument to
+specify a command.
+
+Test Suites: Several bug fixes for the ASLTS suite reduces the number of
+errors during execution of the suite. Guan Chao.
+
+----------------------------------------
+16 August 2012. Summary of changes for version 20120816:
+
+
+1) ACPICA Kernel-resident Subsystem:
+
+Removed all use of the deprecated _GTS and _BFS predefined methods. The
+_GTS
+(Going To Sleep) and _BFS (Back From Sleep) methods are essentially
+deprecated and will probably be removed from the ACPI specification.
+Windows
+does not invoke them, and reportedly never will. The final nail in the
+coffin
+is that the ACPI specification states that these methods must be run with
+interrupts off, which is not going to happen in a kernel interpreter.
+Note:
+Linux has removed all use of the methods also. It was discovered that
+invoking these functions caused failures on some machines, probably
+because
+they were never tested since Windows does not call them. Affects two
+external
+interfaces, AcpiEnterSleepState and AcpiLeaveSleepStatePrep. Tang Feng.
+ACPICA BZ 969.
+
+Implemented support for complex bit-packed buffers returned from the _PLD
+(Physical Location of Device) predefined method. Adds a new external
+interface, AcpiDecodePldBuffer that parses the buffer into a more usable
+C
+structure. Note: C Bitfields cannot be used for this type of predefined
+structure since the memory layout of individual bitfields is not defined
+by
+the C language. In addition, there are endian concerns where a compiler
+will
+change the bitfield ordering based on the machine type. The new ACPICA
+interface eliminates these issues, and should be called after _PLD is
+executed. ACPICA BZ 954.
+
+Implemented a change to allow a scope change to root (via "Scope (\)")
+during
+execution of module-level ASL code (code that is executed at table load
+time.) Lin Ming.
+
+Added the Windows8/Server2012 string for the _OSI method. This change
+adds
+a
+new _OSI string, "Windows 2012" for both Windows 8 and Windows Server
+2012.
+
+Added header support for the new ACPI tables DBG2 (Debug Port Table Type
+2)
+and CSRT (Core System Resource Table).
+
+Added struct header support for the _FDE, _GRT, _GTM, and _SRT predefined
+names. This simplifies access to the buffers returned by these predefined
+names. Adds a new file, include/acbuffer.h. ACPICA BZ 956.
+
+GPE support: Removed an extraneous parameter from the various low-level
+internal GPE functions. Tang Feng.
+
+Removed the linux makefiles from the unix packages. The generate/linux
+makefiles are obsolete and have been removed from the unix tarball
+release
+packages. The replacement makefiles are under generate/unix, and there is
+a
+top-level makefile under the main acpica directory. ACPICA BZ 967, 912.
+
+Updates for Unix makefiles:
+1) Add -D_FORTIFY_SOURCE=2 for gcc generation. Arjan van de Ven.
+2) Update linker flags (move to end of command line) for AcpiExec
+utility.
+Guan Chao.
+
+Split ACPICA initialization functions to new file, utxfinit.c. Split from
+utxface.c to improve modularity and reduce file size.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.5K Code, 25.3K Data, 118.8K Total
+ Debug Version: 173.7K Code, 74.0K Data, 247.7K Total
+ Current Release:
+ Non-Debug Version: 93.8K Code, 25.3K Data, 119.1K Total
+ Debug Version: 175.7K Code, 74.8K Data, 250.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a problem with constant folding for fixed-length constant
+expressions. The constant-folding code was not being invoked for constant
+expressions that allow the use of type 3/4/5 opcodes to generate
+constants
+for expressions such as ByteConstExpr, WordConstExpr, etc. This could
+result
+in the generation of invalid AML bytecode. ACPICA BZ 970.
+
+iASL: Fixed a generation issue on newer versions of Bison. Newer versions
+apparently automatically emit some of the necessary externals. This
+change
+handles these versions in order to eliminate generation warnings.
+
+Disassembler: Added support to decode the DBG2 and CSRT ACPI tables.
+
+Disassembler: Add support to decode _PLD buffers. The decoded buffer
+appears
+within comments in the output file.
+
+Debugger: Fixed a regression with the "Threads" command where
+AE_BAD_PARAMETER was always returned.
+
+----------------------------------------
+11 July 2012. Summary of changes for version 20120711:
+
+1) ACPICA Kernel-resident Subsystem:
+
+Fixed a possible fault in the return package object repair code. Fixes a
+problem that can occur when a lone package object is wrapped with an
+outer
+package object in order to force conformance to the ACPI specification.
+Can
+affect these predefined names: _ALR, _MLS, _PSS, _TRT, _TSS, _PRT, _HPX,
+_DLM,
+_CSD, _PSD, _TSD.
+
+Removed code to disable/enable bus master arbitration (ARB_DIS bit in the
+PM2_CNT register) in the ACPICA sleep/wake interfaces. Management of the
+ARB_DIS bit must be implemented in the host-dependent C3 processor power
+state
+support. Note, ARB_DIS is obsolete and only applies to older chipsets,
+both
+Intel and other vendors. (for Intel: ICH4-M and earlier)
+
+This change removes the code to disable/enable bus master arbitration
+during
+suspend/resume. Use of the ARB_DIS bit in the optional PM2_CNT register
+causes
+resume problems on some machines. The change has been in use for over
+seven
+years within Linux.
+
+Implemented two new external interfaces to support host-directed dynamic
+ACPI
+table load and unload. They are intended to simplify the host
+implementation
+of hot-plug support:
+ AcpiLoadTable: Load an SSDT from a buffer into the namespace.
+ AcpiUnloadParentTable: Unload an SSDT via a named object owned by the
+table.
+See the ACPICA reference for additional details. Adds one new file,
+components/tables/tbxfload.c
+
+Implemented and deployed two new interfaces for errors and warnings that
+are
+known to be caused by BIOS/firmware issues:
+ AcpiBiosError: Prints "ACPI Firmware Error" message.
+ AcpiBiosWarning: Prints "ACPI Firmware Warning" message.
+Deployed these new interfaces in the ACPICA Table Manager code for ACPI
+table
+and FADT errors. Additional deployment to be completed as appropriate in
+the
+future. The associated conditional macros are ACPI_BIOS_ERROR and
+ACPI_BIOS_WARNING. See the ACPICA reference for additional details.
+ACPICA
+BZ
+843.
+
+Implicit notify support: ensure that no memory allocation occurs within a
+critical region. This fix moves a memory allocation outside of the time
+that a
+spinlock is held. Fixes issues on systems that do not allow this
+behavior.
+Jung-uk Kim.
+
+Split exception code utilities and tables into a new file,
+utilities/utexcep.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.1K Code, 25.1K Data, 118.2K Total
+ Debug Version: 172.9K Code, 73.6K Data, 246.5K Total
+ Current Release:
+ Non-Debug Version: 93.5K Code, 25.3K Data, 118.8K Total
+ Debug Version: 173.7K Code, 74.0K Data, 247.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a parser problem for hosts where EOF is defined as -1 instead
+of
+0. Jung-uk Kim.
+
+Debugger: Enhanced the "tables" command to emit additional information
+about
+the current set of ACPI tables, including the owner ID and flags decode.
+
+Debugger: Reimplemented the "unload" command to use the new
+AcpiUnloadParentTable external interface. This command was disable
+previously
+due to need for an unload interface.
+
+AcpiHelp: Added a new option to decode ACPICA exception codes. The -e
+option
+will decode 16-bit hex status codes (ACPI_STATUS) to name strings.
+
+----------------------------------------
+20 June 2012. Summary of changes for version 20120620:
+
+
+1) ACPICA Kernel-resident Subsystem:
+
+Implemented support to expand the "implicit notify" feature to allow
+multiple
+devices to be notified by a single GPE. This feature automatically
+generates a
+runtime device notification in the absence of a BIOS-provided GPE control
+method (_Lxx/_Exx) or a host-installed handler for the GPE. Implicit
+notify is
+provided by ACPICA for Windows compatibility, and is a workaround for
+BIOS
+AML
+code errors. See the description of the AcpiSetupGpeForWake interface in
+the
+APCICA reference. Bob Moore, Rafael Wysocki. ACPICA BZ 918.
+
+Changed some comments and internal function names to simplify and ensure
+correctness of the Linux code translation. No functional changes.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.0K Code, 25.1K Data, 118.1K Total
+ Debug Version: 172.7K Code, 73.6K Data, 246.3K Total
+ Current Release:
+ Non-Debug Version: 93.1K Code, 25.1K Data, 118.2K Total
+ Debug Version: 172.9K Code, 73.6K Data, 246.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Added support to emit short, commented descriptions for the
+ACPI
+predefined names in order to improve the readability of the disassembled
+output. ACPICA BZ 959. Changes include:
+ 1) Emit descriptions for all standard predefined names (_INI, _STA,
+_PRW,
+etc.)
+ 2) Emit generic descriptions for the special names (_Exx, _Qxx, etc.)
+ 3) Emit descriptions for the resource descriptor names (_MIN, _LEN,
+etc.)
+
+AcpiSrc: Fixed several long-standing Linux code translation issues.
+Argument
+descriptions in function headers are now translated properly to lower
+case
+and
+underscores. ACPICA BZ 961. Also fixes translation problems such as
+these:
+(old -> new)
+ i_aSL -> iASL
+ 00-7_f -> 00-7F
+ 16_k -> 16K
+ local_fADT -> local_FADT
+ execute_oSI -> execute_OSI
+
+iASL: Fixed a problem where null bytes were inadvertently emitted into
+some
+listing files.
+
+iASL: Added the existing debug options to the standard help screen. There
+are
+no longer two different help screens. ACPICA BZ 957.
+
+AcpiHelp: Fixed some typos in the various predefined name descriptions.
+Also
+expand some of the descriptions where appropriate.
+
+iASL: Fixed the -ot option (display compile times/statistics). Was not
+working
+properly for standard output; only worked for the debug file case.
+
+----------------------------------------
+18 May 2012. Summary of changes for version 20120518:
+
+
+1) ACPICA Core Subsystem:
+
+Added a new OSL interface, AcpiOsWaitEventsComplete. This interface is
+defined
+to block until asynchronous events such as notifies and GPEs have
+completed.
+Within ACPICA, it is only called before a notify or GPE handler is
+removed/uninstalled. It also may be useful for the host OS within related
+drivers such as the Embedded Controller driver. See the ACPICA reference
+for
+additional information. ACPICA BZ 868.
+
+ACPI Tables: Added a new error message for a possible overflow failure
+during
+the conversion of FADT 32-bit legacy register addresses to internal
+common
+64-
+bit GAS structure representation. The GAS has a one-byte "bit length"
+field,
+thus limiting the register length to 255 bits. ACPICA BZ 953.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.6K Code, 73.4K Data, 246.0K Total
+ Current Release:
+ Non-Debug Version: 93.0K Code, 25.1K Data, 118.1K Total
+ Debug Version: 172.7K Code, 73.6K Data, 246.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added the ACPI 5.0 "PCC" keyword for use in the Register() ASL
+macro.
+This keyword was added late in the ACPI 5.0 release cycle and was not
+implemented until now.
+
+Disassembler: Added support for Operation Region externals. Adds missing
+support for operation regions that are defined in another table, and
+referenced locally via a Field or BankField ASL operator. Now generates
+the
+correct External statement.
+
+Disassembler: Several additional fixes for the External() statement
+generation
+related to some ASL operators. Also, order the External() statements
+alphabetically in the disassembler output. Fixes the External()
+generation
+for
+the Create* field, Alias, and Scope operators:
+ 1) Create* buffer field operators - fix type mismatch warning on
+disassembly
+ 2) Alias - implement missing External support
+ 3) Scope - fix to make sure all necessary externals are emitted.
+
+iASL: Improved pathname support. For include files, merge the prefix
+pathname
+with the file pathname and eliminate unnecessary components. Convert
+backslashes in all pathnames to forward slashes, for readability. Include
+file
+pathname changes affect both #include and Include() type operators.
+
+iASL/DTC/Preprocessor: Gracefully handle early EOF. Handle an EOF at the
+end
+of a valid line by inserting a newline and then returning the EOF during
+the
+next call to GetNextLine. Prevents the line from being ignored due to EOF
+condition.
+
+iASL: Implemented some changes to enhance the IDE support (-vi option.)
+Error
+and Warning messages are now correctly recognized for both the source
+code
+browser and the global error and warning counts.
+
+----------------------------------------
+20 April 2012. Summary of changes for version 20120420:
+
+
+1) ACPICA Core Subsystem:
+
+Implemented support for multiple notify handlers. This change adds
+support
+to
+allow multiple system and device notify handlers on Device, Thermal Zone,
+and
+Processor objects. This can simplify the host OS notification
+implementation.
+Also re-worked and restructured the entire notify support code to
+simplify
+handler installation, handler removal, notify event queuing, and notify
+dispatch to handler(s). Note: there can still only be two global notify
+handlers - one for system notifies and one for device notifies. There are
+no
+changes to the existing handler install/remove interfaces. Lin Ming, Bob
+Moore, Rafael Wysocki.
+
+Fixed a regression in the package repair code where the object reference
+count was calculated incorrectly. Regression was introduced in the commit
+"Support to add Package wrappers".
+
+Fixed a couple possible memory leaks in the AML parser, in the error
+recovery
+path. Jesper Juhl, Lin Ming.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.5K Code, 73.2K Data, 245.7K Total
+ Current Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.6K Code, 73.4K Data, 246.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a problem with the resource descriptor support where the
+length
+of the StartDependentFn and StartDependentFnNoPrio descriptors were not
+included in cumulative descriptor offset, resulting in incorrect values
+for
+resource tags within resource descriptors appearing after a
+StartDependent*
+descriptor. Reported by Petr Vandrovec. ACPICA BZ 949.
+
+iASL and Preprocessor: Implemented full support for the #line directive
+to
+correctly track original source file line numbers through the .i
+preprocessor
+output file - for error and warning messages.
+
+iASL: Expand the allowable byte constants for address space IDs.
+Previously,
+the allowable range was 0x80-0xFF (user-defined spaces), now the range is
+0x0A-0xFF to allow for custom and new IDs without changing the compiler.
+
+iASL: Add option to treat all warnings as errors (-we). ACPICA BZ 948.
+
+iASL: Add option to completely disable the preprocessor (-Pn).
+
+iASL: Now emit all error/warning messages to standard error (stderr) by
+default (instead of the previous stdout).
+
+ASL Test Suite (ASLTS): Reduce iASL warnings due to use of Switch().
+Update
+for resource descriptor offset fix above. Update/cleanup error output
+routines. Enable and send iASL errors/warnings to an error logfile
+(error.txt). Send all other iASL output to a logfile (compiler.txt).
+Fixed
+several extraneous "unrecognized operator" messages.
+
+----------------------------------------
+20 March 2012. Summary of changes for version 20120320:
+
+
+1) ACPICA Core Subsystem:
+
+Enhanced the sleep/wake interfaces to optionally execute the _GTS method
+(Going To Sleep) and the _BFS method (Back From Sleep). Windows
+apparently
+does not execute these methods, and therefore these methods are often
+untested. It has been seen on some systems where the execution of these
+methods causes errors and also prevents the machine from entering S5. It
+is
+therefore suggested that host operating systems do not execute these
+methods
+by default. In the future, perhaps these methods can be optionally
+executed
+based on the age of the system and/or what is the newest version of
+Windows
+that the BIOS asks for via _OSI. Changed interfaces: AcpiEnterSleepState
+and
+AcpileaveSleepStatePrep. See the ACPICA reference and Linux BZ 13041. Lin
+Ming.
+
+Fixed a problem where the length of the local/common FADT was set too
+early.
+The local FADT table length cannot be set to the common length until the
+original length has been examined. There is code that checks the table
+length
+and sets various fields appropriately. This can affect older machines
+with
+early FADT versions. For example, this can cause inadvertent writes to
+the
+CST_CNT register. Julian Anastasov.
+
+Fixed a mapping issue related to a physical table override. Use the
+deferred
+mapping mechanism for tables loaded via the physical override OSL
+interface.
+This allows for early mapping before the virtual memory manager is
+available.
+Thomas Renninger, Bob Moore.
+
+Enhanced the automatic return-object repair code: Repair a common problem
+with
+predefined methods that are defined to return a variable-length Package
+of
+sub-objects. If there is only one sub-object, some BIOS ASL code
+mistakenly
+simply returns the single object instead of a Package with one sub-
+object.
+This new support will repair this error by wrapping a Package object
+around
+the original object, creating the correct and expected Package with one
+sub-
+object. Names that can be repaired in this manner include: _ALR, _CSD,
+_HPX,
+_MLS, _PLD, _PRT, _PSS, _TRT, _TSS, _BCL, _DOD, _FIX, and _Sx. ACPICA BZ
+939.
+
+Changed the exception code returned for invalid ACPI paths passed as
+parameters to external interfaces such as AcpiEvaluateObject. Was
+AE_BAD_PARAMETER, now is the more sensible AE_BAD_PATHNAME.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.0K Code, 25.0K Data, 118.0K Total
+ Debug Version: 172.5K Code, 73.2K Data, 245.7K Total
+ Current Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.5K Code, 73.2K Data, 245.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added the infrastructure and initial implementation of a integrated
+C-
+like preprocessor. This will simplify BIOS development process by
+eliminating
+the need for a separate preprocessing step during builds. On Windows, it
+also
+eliminates the need to install a separate C compiler. ACPICA BZ 761. Some
+features including full #define() macro support are still under
+development.
+These preprocessor directives are supported:
+ #define
+ #elif
+ #else
+ #endif
+ #error
+ #if
+ #ifdef
+ #ifndef
+ #include
+ #pragma message
+ #undef
+ #warning
+In addition, these new command line options are supported:
+ -D <symbol> Define symbol for preprocessor use
+ -li Create preprocessed output file (*.i)
+ -P Preprocess only and create preprocessor output file (*.i)
+
+Table Compiler: Fixed a problem where the equals operator within an
+expression
+did not work properly.
+
+Updated iASL to use the current versions of Bison/Flex. Updated the
+Windows
+project file to invoke these tools from the standard location. ACPICA BZ
+904.
+Versions supported:
+ Flex for Windows: V2.5.4
+ Bison for Windows: V2.4.1
+
+----------------------------------------
+15 February 2012. Summary of changes for version 20120215:
+
+
+1) ACPICA Core Subsystem:
+
+There have been some major changes to the sleep/wake support code, as
+described below (a - e).
+
+a) The AcpiLeaveSleepState has been split into two interfaces, similar to
+AcpiEnterSleepStatePrep and AcpiEnterSleepState. The new interface is
+AcpiLeaveSleepStatePrep. This allows the host to perform actions between
+the
+time the _BFS method is called and the _WAK method is called. NOTE: all
+hosts
+must update their wake/resume code or else sleep/wake will not work
+properly.
+Rafael Wysocki.
+
+b) In AcpiLeaveSleepState, now enable all runtime GPEs before calling the
+_WAK
+method. Some machines require that the GPEs are enabled before the _WAK
+method
+is executed. Thomas Renninger.
+
+c) In AcpiLeaveSleepState, now always clear the WAK_STS (wake status)
+bit.
+Some BIOS code assumes that WAK_STS will be cleared on resume and use it
+to
+determine whether the system is rebooting or resuming. Matthew Garrett.
+
+d) Move the invocations of _GTS (Going To Sleep) and _BFS (Back From
+Sleep) to
+match the ACPI specification requirement. Rafael Wysocki.
+
+e) Implemented full support for the ACPI 5.0 SleepStatus and SleepControl
+registers within the V5 FADT. This support adds two new files:
+hardware/hwesleep.c implements the support for the new registers. Moved
+all
+sleep/wake external interfaces to hardware/hwxfsleep.c.
+
+
+Added a new OSL interface for ACPI table overrides,
+AcpiOsPhysicalTableOverride. This interface allows the host to override a
+table via a physical address, instead of the logical address required by
+AcpiOsTableOverride. This simplifies the host implementation. Initial
+implementation by Thomas Renninger. The ACPICA implementation creates a
+single
+shared function for table overrides that attempts both a logical and a
+physical override.
+
+Expanded the OSL memory read/write interfaces to 64-bit data
+(AcpiOsReadMemory, AcpiOsWriteMemory.) This enables full 64-bit memory
+transfer support for GAS register structures passed to AcpiRead and
+AcpiWrite.
+
+Implemented the ACPI_REDUCED_HARDWARE option to allow the creation of a
+custom
+build of ACPICA that supports only the ACPI 5.0 reduced hardware (SoC)
+model.
+See the ACPICA reference for details. ACPICA BZ 942. This option removes
+about
+10% of the code and 5% of the static data, and the following hardware
+ACPI
+features become unavailable:
+ PM Event and Control registers
+ SCI interrupt (and handler)
+ Fixed Events
+ General Purpose Events (GPEs)
+ Global Lock
+ ACPI PM timer
+ FACS table (Waking vectors and Global Lock)
+
+Updated the unix tarball directory structure to match the ACPICA git
+source
+tree. This ensures that the generic unix makefiles work properly (in
+generate/unix). Also updated the Linux makefiles to match. ACPICA BZ
+867.
+
+Updated the return value of the _REV predefined method to integer value 5
+to
+reflect ACPI 5.0 support.
+
+Moved the external ACPI PM timer interface prototypes to the public
+acpixf.h
+file where they belong.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.8K Code, 24.9K Data, 117.7K Total
+ Debug Version: 171.7K Code, 72.9K Data, 244.5K Total
+ Current Release:
+ Non-Debug Version: 93.0K Code, 25.0K Data, 118.0K Total
+ Debug Version: 172.5K Code, 73.2K Data, 245.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a problem with the new ACPI 5.0 serial resource
+descriptors (I2C, SPI, UART) where the resource produce/consumer bit was
+incorrectly displayed.
+
+AcpiHelp: Add display of ACPI/PNP device IDs that are defined in the ACPI
+specification.
+
+----------------------------------------
+11 January 2012. Summary of changes for version 20120111:
+
+
+1) ACPICA Core Subsystem:
+
+Implemented a new mechanism to allow host device drivers to check for
+address
+range conflicts with ACPI Operation Regions. Both SystemMemory and
+SystemIO
+address spaces are supported. A new external interface,
+AcpiCheckAddressRange,
+allows drivers to check an address range against the ACPI namespace. See
+the
+ACPICA reference for additional details. Adds one new file,
+utilities/utaddress.c. Lin Ming, Bob Moore.
+
+Fixed several issues with the ACPI 5.0 FADT support: Add the sleep
+Control
+and
+Status registers, update the ACPI 5.0 flags, and update internal data
+structures to handle an FADT larger than 256 bytes. The size of the ACPI
+5.0
+FADT is 268 bytes.
+
+Updated all ACPICA copyrights and signons to 2012. Added the 2012
+copyright to
+all module headers and signons, including the standard Linux header. This
+affects virtually every file in the ACPICA core subsystem, iASL compiler,
+and
+all ACPICA utilities.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.3K Code, 24.9K Data, 117.2K Total
+ Debug Version: 170.8K Code, 72.6K Data, 243.4K Total
+ Current Release:
+ Non-Debug Version: 92.8K Code, 24.9K Data, 117.7K Total
+ Debug Version: 171.7K Code, 72.9K Data, 244.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: fixed a problem with the automatic resource tag generation
+support. Fixes a problem where the resource tags are inadvertently not
+constructed if the table being disassembled contains external references
+to
+control methods. Moved the actual construction of the tags to after the
+final
+namespace is constructed (after 2nd parse is invoked due to external
+control
+method references.) ACPICA BZ 941.
+
+Table Compiler: Make all "generic" operators caseless. These are the
+operators
+like UINT8, String, etc. Making these caseless improves ease-of-use.
+ACPICA BZ
+934.
+
+----------------------------------------
+23 November 2011. Summary of changes for version 20111123:
+
+0) ACPI 5.0 Support:
+
+This release contains full support for the ACPI 5.0 specification, as
+summarized below.
+
+Reduced Hardware Support:
+-------------------------
+
+This support allows for ACPI systems without the usual ACPI hardware.
+This
+support is enabled by a flag in the revision 5 FADT. If it is set, ACPICA
+will
+not attempt to initialize or use any of the usual ACPI hardware. Note,
+when
+this flag is set, all of the following ACPI hardware is assumed to be not
+present and is not initialized or accessed:
+
+ General Purpose Events (GPEs)
+ Fixed Events (PM1a/PM1b and PM Control)
+ Power Management Timer and Console Buttons (power/sleep)
+ Real-time Clock Alarm
+ Global Lock
+ System Control Interrupt (SCI)
+ The FACS is assumed to be non-existent
+
+ACPI Tables:
+------------
+
+All new tables and updates to existing tables are fully supported in the
+ACPICA headers (for use by device drivers), the disassembler, and the
+iASL
+Data Table Compiler. ACPI 5.0 defines these new tables:
+
+ BGRT /* Boot Graphics Resource Table */
+ DRTM /* Dynamic Root of Trust for Measurement table */
+ FPDT /* Firmware Performance Data Table */
+ GTDT /* Generic Timer Description Table */
+ MPST /* Memory Power State Table */
+ PCCT /* Platform Communications Channel Table */
+ PMTT /* Platform Memory Topology Table */
+ RASF /* RAS Feature table */
+
+Operation Regions/SpaceIDs:
+---------------------------
+
+All new operation regions are fully supported by the iASL compiler, the
+disassembler, and the ACPICA runtime code (for dispatch to region
+handlers.)
+The new operation region Space IDs are:
+
+ GeneralPurposeIo
+ GenericSerialBus
+
+Resource Descriptors:
+---------------------
+
+All new ASL resource descriptors are fully supported by the iASL
+compiler,
+the
+ASL/AML disassembler, and the ACPICA runtime Resource Manager code
+(including
+all new predefined resource tags). New descriptors are:
+
+ FixedDma
+ GpioIo
+ GpioInt
+ I2cSerialBus
+ SpiSerialBus
+ UartSerialBus
+
+ASL/AML Operators, New and Modified:
+------------------------------------
+
+One new operator is added, the Connection operator, which is used to
+associate
+a GeneralPurposeIo or GenericSerialBus resource descriptor with
+individual
+field objects within an operation region. Several new protocols are
+associated
+with the AccessAs operator. All are fully supported by the iASL compiler,
+disassembler, and runtime ACPICA AML interpreter:
+
+ Connection // Declare Field Connection
+attributes
+ AccessAs: AttribBytes (n) // Read/Write N-Bytes Protocol
+ AccessAs: AttribRawBytes (n) // Raw Read/Write N-Bytes
+Protocol
+ AccessAs: AttribRawProcessBytes (n) // Raw Process Call Protocol
+ RawDataBuffer // Data type for Vendor Data
+fields
+
+Predefined ASL/AML Objects:
+---------------------------
+
+All new predefined objects/control-methods are supported by the iASL
+compiler
+and the ACPICA runtime validation/repair (arguments and return values.)
+New
+predefined names include the following:
+
+Standard Predefined Names (Objects or Control Methods):
+ _AEI, _CLS, _CPC, _CWS, _DEP,
+ _DLM, _EVT, _GCP, _CRT, _GWS,
+ _HRV, _PRE, _PSE, _SRT, _SUB.
+
+Resource Tags (Names used to access individual fields within resource
+descriptors):
+ _DBT, _DPL, _DRS, _END, _FLC,
+ _IOR, _LIN, _MOD, _PAR, _PHA,
+ _PIN, _PPI, _POL, _RXL, _SLV,
+ _SPE, _STB, _TXL, _VEN.
+
+ACPICA External Interfaces:
+---------------------------
+
+Several new interfaces have been defined for use by ACPI-related device
+drivers and other host OS services:
+
+AcpiAcquireMutex and AcpiReleaseMutex: These interfaces allow the host OS
+to
+acquire and release AML mutexes that are defined in the DSDT/SSDT tables
+provided by the BIOS. They are intended to be used in conjunction with
+the
+ACPI 5.0 _DLM (Device Lock Method) in order to provide transaction-level
+mutual exclusion with the AML code/interpreter.
+
+AcpiGetEventResources: Returns the (formatted) resource descriptors as
+defined
+by the ACPI 5.0 _AEI object (ACPI Event Information). This object
+provides
+resource descriptors associated with hardware-reduced platform events,
+similar
+to the AcpiGetCurrentResources interface.
+
+Operation Region Handlers: For General Purpose IO and Generic Serial Bus
+operation regions, information about the Connection() object and any
+optional
+length information is passed to the region handler within the Context
+parameter.
+
+AcpiBufferToResource: This interface converts a raw AML buffer containing
+a
+resource template or resource descriptor to the ACPI_RESOURCE internal
+format
+suitable for use by device drivers. Can be used by an operation region
+handler
+to convert the Connection() buffer object into a ACPI_RESOURCE.
+
+Miscellaneous/Tools/TestSuites:
+-------------------------------
+
+Support for extended _HID names (Four alpha characters instead of three).
+Support for ACPI 5.0 features in the AcpiExec and AcpiHelp utilities.
+Support for ACPI 5.0 features in the ASLTS test suite.
+Fully updated documentation (ACPICA and iASL reference documents.)
+
+ACPI Table Definition Language:
+-------------------------------
+
+Support for this language was implemented and released as a subsystem of
+the
+iASL compiler in 2010. (See the iASL compiler User Guide.)
+
+
+Non-ACPI 5.0 changes for this release:
+--------------------------------------
+
+1) ACPICA Core Subsystem:
+
+Fix a problem with operation region declarations where a failure can
+occur
+if
+the region name and an argument that evaluates to an object (such as the
+region address) are in different namespace scopes. Lin Ming, ACPICA BZ
+937.
+
+Do not abort an ACPI table load if an invalid space ID is found within.
+This
+will be caught later if the offending method is executed. ACPICA BZ 925.
+
+Fixed an issue with the FFixedHW space ID where the ID was not always
+recognized properly (Both ACPICA and iASL). ACPICA BZ 926.
+
+Fixed a problem with the 32-bit generation of the unix-specific OSL
+(osunixxf.c). Lin Ming, ACPICA BZ 936.
+
+Several changes made to enable generation with the GCC 4.6 compiler.
+ACPICA BZ
+935.
+
+New error messages: Unsupported I/O requests (not 8/16/32 bit), and
+Index/Bank
+field registers out-of-range.
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented the __PATH__ operator, which returns the full pathname
+of
+the current source file.
+
+AcpiHelp: Automatically display expanded keyword information for all ASL
+operators.
+
+Debugger: Add "Template" command to disassemble/dump resource template
+buffers.
+
+Added a new master script to generate and execute the ASLTS test suite.
+Automatically handles 32- and 64-bit generation. See tests/aslts.sh
+
+iASL: Fix problem with listing generation during processing of the
+Switch()
+operator where AML listing was disabled until the entire Switch block was
+completed.
+
+iASL: Improve support for semicolon statement terminators. Fix "invalid
+character" message for some cases when the semicolon is used. Semicolons
+are
+now allowed after every <Term> grammar element. ACPICA BZ 927.
+
+iASL: Fixed some possible aliasing warnings during generation. ACPICA BZ
+923.
+
+Disassembler: Fix problem with disassembly of the DataTableRegion
+operator
+where an inadvertent "Unhandled deferred opcode" message could be
+generated.
+
+3) Example Code and Data Size
+
+These are the sizes for the OS-independent acpica.lib produced by the
+Microsoft Visual C++ 9.0 32-bit compiler. The debug version of the code
+includes the debug output trace mechanism and has a much larger code and
+data
+size.
+
+ Previous Release:
+ Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+ Current Release:
+ Non-Debug Version: 92.3K Code, 24.9K Data, 117.2K Total
+ Debug Version: 170.8K Code, 72.6K Data, 243.4K Total
+
+----------------------------------------
+22 September 2011. Summary of changes for version 20110922:
+
+0) ACPI 5.0 News:
+
+Support for ACPI 5.0 in ACPICA has been underway for several months and
+will
+be released at the same time that ACPI 5.0 is officially released.
+
+The ACPI 5.0 specification is on track for release in the next few
+months.
+
+1) ACPICA Core Subsystem:
+
+Fixed a problem where the maximum sleep time for the Sleep() operator was
+intended to be limited to two seconds, but was inadvertently limited to
+20
+seconds instead.
+
+Linux and Unix makefiles: Added header file dependencies to ensure
+correct
+generation of ACPICA core code and utilities. Also simplified the
+makefiles
+considerably through the use of the vpath variable to specify search
+paths.
+ACPICA BZ 924.
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented support to check the access length for all fields
+created to
+access named Resource Descriptor fields. For example, if a resource field
+is
+defined to be two bits, a warning is issued if a CreateXxxxField() is
+used
+with an incorrect bit length. This is implemented for all current
+resource
+descriptor names. ACPICA BZ 930.
+
+Disassembler: Fixed a byte ordering problem with the output of 24-bit and
+56-
+bit integers.
+
+iASL: Fixed a couple of issues associated with variable-length package
+objects. 1) properly handle constants like One, Ones, Zero -- do not make
+a
+VAR_PACKAGE when these are used as a package length. 2) Allow the
+VAR_PACKAGE
+opcode (in addition to PACKAGE) when validating object types for
+predefined
+names.
+
+iASL: Emit statistics for all output files (instead of just the ASL input
+and
+AML output). Includes listings, hex files, etc.
+
+iASL: Added -G option to the table compiler to allow the compilation of
+custom
+ACPI tables. The only part of a table that is required is the standard
+36-
+byte
+ACPI header.
+
+AcpiXtract: Ported to the standard ACPICA environment (with ACPICA
+headers),
+which also adds correct 64-bit support. Also, now all output filenames
+are
+completely lower case.
+
+AcpiExec: Ignore any non-AML tables (tables other than DSDT or SSDT) when
+loading table files. A warning is issued for any such tables. The only
+exception is an FADT. This also fixes a possible fault when attempting to
+load
+non-AML tables. ACPICA BZ 932.
+
+AcpiHelp: Added the AccessAs and Offset operators. Fixed a problem where
+a
+missing table terminator could cause a fault when using the -p option.
+
+AcpiSrc: Fixed a possible divide-by-zero fault when generating file
+statistics.
+
+3) Example Code and Data Size
+
+These are the sizes for the OS-independent acpica.lib produced by the
+Microsoft Visual C++ 9.0 32-bit compiler. The debug version of the code
+includes the debug output trace mechanism and has a much larger code and
+data
+size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+
+
+----------------------------------------
+23 June 2011. Summary of changes for version 20110623:
+
+1) ACPI CA Core Subsystem:
+
+Updated the predefined name repair mechanism to not attempt repair of a
+_TSS
+return object if a _PSS object is present. We can only sort the _TSS
+return
+package if there is no _PSS within the same scope. This is because if
+_PSS
+is
+present, the ACPI specification dictates that the _TSS Power Dissipation
+field
+is to be ignored, and therefore some BIOSs leave garbage values in the
+_TSS
+Power field(s). In this case, it is best to just return the _TSS package
+as-
+is. Reported by, and fixed with assistance from Fenghua Yu.
+
+Added an option to globally disable the control method return value
+validation
+and repair. This runtime option can be used to disable return value
+repair
+if
+this is causing a problem on a particular machine. Also added an option
+to
+AcpiExec (-dr) to set this disable flag.
+
+All makefiles and project files: Major changes to improve generation of
+ACPICA
+tools. ACPICA BZ 912:
+ Reduce default optimization levels to improve compatibility
+ For Linux, add strict-aliasing=0 for gcc 4
+ Cleanup and simplify use of command line defines
+ Cleanup multithread library support
+ Improve usage messages
+
+Linux-specific header: update handling of THREAD_ID and pthread. For the
+32-
+bit case, improve casting to eliminate possible warnings, especially with
+the
+acpica tools.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 90.1K Code, 23.9K Data, 114.0K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+With this release, a new utility named "acpihelp" has been added to the
+ACPICA
+package. This utility summarizes the ACPI specification chapters for the
+ASL
+and AML languages. It generates under Linux/Unix as well as Windows, and
+provides the following functionality:
+ Find/display ASL operator(s) -- with description and syntax.
+ Find/display ASL keyword(s) -- with exact spelling and descriptions.
+ Find/display ACPI predefined name(s) -- with description, number
+ of arguments, and the return value data type.
+ Find/display AML opcode name(s) -- with opcode, arguments, and
+grammar.
+ Decode/display AML opcode -- with opcode name, arguments, and
+grammar.
+
+Service Layers: Make multi-thread support configurable. Conditionally
+compile
+the multi-thread support so that threading libraries will not be linked
+if
+not
+necessary. The only tool that requires multi-thread support is AcpiExec.
+
+iASL: Update yyerrror/AslCompilerError for "const" errors. Newer versions
+of
+Bison appear to want the interface to yyerror to be a const char * (or at
+least this is a problem when generating iASL on some systems.) ACPICA BZ
+923
+Pierre Lejeune.
+
+Tools: Fix for systems where O_BINARY is not defined. Only used for
+Windows
+versions of the tools.
+
+----------------------------------------
+27 May 2011. Summary of changes for version 20110527:
+
+1) ACPI CA Core Subsystem:
+
+ASL Load() operator: Reinstate most restrictions on the incoming ACPI
+table
+signature. Now, only allow SSDT, OEMx, and a null signature. History:
+ 1) Originally, we checked the table signature for "SSDT" or "PSDT".
+ (PSDT is now obsolete.)
+ 2) We added support for OEMx tables, signature "OEM" plus a fourth
+ "don't care" character.
+ 3) Valid tables were encountered with a null signature, so we just
+ gave up on validating the signature, (05/2008).
+ 4) We encountered non-AML tables such as the MADT, which caused
+ interpreter errors and kernel faults. So now, we once again allow
+ only SSDT, OEMx, and now, also a null signature. (05/2011).
+
+Added the missing _TDL predefined name to the global name list in order
+to
+enable validation. Affects both the core ACPICA code and the iASL
+compiler.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug
+version of the code includes the debug output trace mechanism and has a
+much
+larger code and data size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 90.0K Code, 23.8K Data, 113.8K Total
+ Debug Version: 164.5K Code, 68.0K Data, 232.5K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 90.1K Code, 23.9K Data, 114.0K Total
+ Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Debugger/AcpiExec: Implemented support for "complex" method arguments on
+the
+debugger command line. This adds support beyond simple integers --
+including
+Strings, Buffers, and Packages. Includes support for nested packages.
+Increased the default command line buffer size to accommodate these
+arguments.
+See the ACPICA reference for details and syntax. ACPICA BZ 917.
+
+Debugger/AcpiExec: Implemented support for "default" method arguments for
+the
+Execute/Debug command. Now, the debugger will always invoke a control
+method
+with the required number of arguments -- even if the command line
+specifies
+none or insufficient arguments. It uses default integer values for any
+missing
+arguments. Also fixes a bug where only six method arguments maximum were
+supported instead of the required seven.
+
+Debugger/AcpiExec: Add a maximum buffer length parameter to AcpiOsGetLine
+and
+also return status in order to prevent buffer overruns. See the ACPICA
+reference for details and syntax. ACPICA BZ 921
+
+iASL: Cleaned up support for Berkeley yacc. A general cleanup of code and
+makefiles to simplify support for the two different but similar parser
+generators, bison and yacc.
+
+Updated the generic unix makefile for gcc 4. The default gcc version is
+now
+expected to be 4 or greater, since options specific to gcc 4 are used.
+
+----------------------------------------
+13 April 2011. Summary of changes for version 20110413:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support to execute a so-called "orphan" _REG method under the
+EC
+device. This change will force the execution of a _REG method underneath
+the
+EC
+device even if there is no corresponding operation region of type
+EmbeddedControl. Fixes a problem seen on some machines and apparently is
+compatible with Windows behavior. ACPICA BZ 875.
+
+Added more predefined methods that are eligible for automatic NULL
+package
+element removal. This change adds another group of predefined names to
+the
+list
+of names that can be repaired by having NULL package elements dynamically
+removed. This group are those methods that return a single variable-
+length
+package containing simple data types such as integers, buffers, strings.
+This
+includes: _ALx, _BCL, _CID,_ DOD, _EDL, _FIX, _PCL, _PLD, _PMD, _PRx,
+_PSL,
+_Sx,
+and _TZD. ACPICA BZ 914.
+
+Split and segregated all internal global lock functions to a new file,
+evglock.c.
+
+Updated internal address SpaceID for DataTable regions. Moved this
+internal
+space
+id in preparation for ACPI 5.0 changes that will include some new space
+IDs.
+This
+change should not affect user/host code.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib
+produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of
+the code includes the debug output trace mechanism and has a much larger
+code
+and
+data size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 89.8K Code, 23.8K Data, 113.6K Total
+ Debug Version: 164.2K Code, 67.9K Data, 232.1K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 90.0K Code, 23.8K Data, 113.8K Total
+ Debug Version: 164.5K Code, 68.0K Data, 232.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/DTC: Major update for new grammar features. Allow generic data types
+in
+custom ACPI tables. Field names are now optional. Any line can be split
+to
+multiple lines using the continuation char (\). Large buffers now use
+line-
+continuation character(s) and no colon on the continuation lines. See the
+grammar
+update in the iASL compiler reference. ACPI BZ 910,911. Lin Ming, Bob
+Moore.
+
+iASL: Mark ASL "Return()" and the simple "Return" as "Null" return
+statements.
+Since the parser stuffs a "zero" as the return value for these statements
+(due
+to
+the underlying AML grammar), they were seen as "return with value" by the
+iASL
+semantic checking. They are now seen correctly as "null" return
+statements.
+
+iASL: Check if a_REG declaration has a corresponding Operation Region.
+Adds a
+check for each _REG to ensure that there is in fact a corresponding
+operation
+region declaration in the same scope. If not, the _REG method is not very
+useful
+since it probably won't be executed. ACPICA BZ 915.
+
+iASL/DTC: Finish support for expression evaluation. Added a new
+expression
+parser
+that implements c-style operator precedence and parenthesization. ACPICA
+bugzilla
+908.
+
+Disassembler/DTC: Remove support for () and <> style comments in data
+tables.
+Now
+that DTC has full expression support, we don't want to have comment
+strings
+that
+start with a parentheses or a less-than symbol. Now, only the standard /*
+and
+//
+comments are supported, as well as the bracket [] comments.
+
+AcpiXtract: Fix for RSDP and dynamic SSDT extraction. These tables have
+"unusual"
+headers in the acpidump file. Update the header validation to support
+these
+tables. Problem introduced in previous AcpiXtract version in the change
+to
+support "wrong checksum" error messages emitted by acpidump utility.
+
+iASL: Add a * option to generate all template files (as a synonym for
+ALL)
+as
+in
+"iasl -T *" or "iasl -T ALL".
+
+iASL/DTC: Do not abort compiler on fatal errors. We do not want to
+completely
+abort the compiler on "fatal" errors, simply should abort the current
+compile.
+This allows multiple compiles with a single (possibly wildcard) compiler
+invocation.
+
+----------------------------------------
+16 March 2011. Summary of changes for version 20110316:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem caused by a _PRW method appearing at the namespace root
+scope
+during the setup of wake GPEs. A fault could occur if a _PRW directly
+under
+the
+root object was passed to the AcpiSetupGpeForWake interface. Lin Ming.
+
+Implemented support for "spurious" Global Lock interrupts. On some
+systems, a
+global lock interrupt can occur without the pending flag being set. Upon
+a
+GL
+interrupt, we now ensure that a thread is actually waiting for the lock
+before
+signaling GL availability. Rafael Wysocki, Bob Moore.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib
+produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of
+the code includes the debug output trace mechanism and has a much larger
+code
+and
+data size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 89.7K Code, 23.7K Data, 113.4K Total
+ Debug Version: 163.9K Code, 67.5K Data, 231.4K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 89.8K Code, 23.8K Data, 113.6K Total
+ Debug Version: 164.2K Code, 67.9K Data, 232.1K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented full support for the "SLIC" ACPI table. Includes support in
+the
+header files, disassembler, table compiler, and template generator. Bob
+Moore,
+Lin Ming.
+
+AcpiXtract: Correctly handle embedded comments and messages from
+AcpiDump.
+Apparently some or all versions of acpidump will occasionally emit a
+comment
+like
+"Wrong checksum", etc., into the dump file. This was causing problems for
+AcpiXtract. ACPICA BZ 905.
+
+iASL: Fix the Linux makefile by removing an inadvertent double file
+inclusion.
+ACPICA BZ 913.
+
+AcpiExec: Update installation of operation region handlers. Install one
+handler
+for a user-defined address space. This is used by the ASL test suite
+(ASLTS).
+
+----------------------------------------
+11 February 2011. Summary of changes for version 20110211:
+
+1) ACPI CA Core Subsystem:
+
+Added a mechanism to defer _REG methods for some early-installed
+handlers.
+Most user handlers should be installed before call to
+AcpiEnableSubsystem.
+However, Event handlers and region handlers should be installed after
+AcpiInitializeObjects. Override handlers for the "default" regions should
+be
+installed early, however. This change executes all _REG methods for the
+default regions (Memory/IO/PCI/DataTable) simultaneously to prevent any
+chicken/egg issues between them. ACPICA BZ 848.
+
+Implemented an optimization for GPE detection. This optimization will
+simply
+ignore GPE registers that contain no enabled GPEs -- there is no need to
+read the register since this information is available internally. This
+becomes more important on machines with a large GPE space. ACPICA
+bugzilla
+884. Lin Ming. Suggestion from Joe Liu.
+
+Removed all use of the highly unreliable FADT revision field. The
+revision
+number in the FADT has been found to be completely unreliable and cannot
+be
+trusted. Only the actual table length can be used to infer the version.
+This
+change updates the ACPICA core and the disassembler so that both no
+longer
+even look at the FADT version and instead depend solely upon the FADT
+length.
+
+Fix an unresolved name issue for the no-debug and no-error-message source
+generation cases. The _AcpiModuleName was left undefined in these cases,
+but
+it is actually needed as a parameter to some interfaces. Define
+_AcpiModuleName as a null string in these cases. ACPICA Bugzilla 888.
+
+Split several large files (makefiles and project files updated)
+ utglobal.c -> utdecode.c
+ dbcomds.c -> dbmethod.c dbnames.c
+ dsopcode.c -> dsargs.c dscontrol.c
+ dsload.c -> dsload2.c
+ aslanalyze.c -> aslbtypes.c aslwalks.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release (VC 9.0):
+ Non-Debug Version: 89.7K Code, 23.7K Data, 113.4K Total
+ Debug Version: 163.9K Code, 67.5K Data, 231.4K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 89.7K Code, 23.7K Data, 113.4K Total
+ Debug Version: 163.9K Code, 67.5K Data, 231.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented the predefined macros __LINE__, __FILE__, and __DATE__.
+These are useful C-style macros with the standard definitions. ACPICA
+bugzilla 898.
+
+iASL/DTC: Added support for integer expressions and labels. Support for
+full
+expressions for all integer fields in all ACPI tables. Support for labels
+in
+"generic" portions of tables such as UEFI. See the iASL reference manual.
+
+Debugger: Added a command to display the status of global handlers. The
+"handlers" command will display op region, fixed event, and miscellaneous
+global handlers. installation status -- and for op regions, whether
+default
+or user-installed handler will be used.
+
+iASL: Warn if reserved method incorrectly returns a value. Many
+predefined
+names are defined such that they do not return a value. If implemented as
+a
+method, issue a warning if such a name explicitly returns a value. ACPICA
+Bugzilla 855.
+
+iASL: Added detection of GPE method name conflicts. Detects a conflict
+where
+there are two GPE methods of the form _Lxy and _Exy in the same scope.
+(For
+example, _L1D and _E1D in the same scope.) ACPICA bugzilla 848.
+
+iASL/DTC: Fixed a couple input scanner issues with comments and line
+numbers. Comment remover could get confused and miss a comment ending.
+Fixed
+a problem with line counter maintenance.
+
+iASL/DTC: Reduced the severity of some errors from fatal to error. There
+is
+no need to abort on simple errors within a field definition.
+
+Debugger: Simplified the output of the help command. All help output now
+in
+a single screen, instead of help subcommands. ACPICA Bugzilla 897.
+
+----------------------------------------
+12 January 2011. Summary of changes for version 20110112:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a race condition between method execution and namespace walks that
+can
+possibly cause a fault. The problem was apparently introduced in version
+20100528 as a result of a performance optimization that reduces the
+number
+of
+namespace walks upon method exit by using the delete_namespace_subtree
+function instead of the delete_namespace_by_owner function used
+previously.
+Bug is a missing namespace lock in the delete_namespace_subtree function.
+dana.myers@oracle.com
+
+Fixed several issues and a possible fault with the automatic "serialized"
+method support. History: This support changes a method to "serialized" on
+the
+fly if the method generates an AE_ALREADY_EXISTS error, indicating the
+possibility that it cannot handle reentrancy. This fix repairs a couple
+of
+issues seen in the field, especially on machines with many cores:
+
+ 1) Delete method children only upon the exit of the last thread,
+ so as to not delete objects out from under other running threads
+ (and possibly causing a fault.)
+ 2) Set the "serialized" bit for the method only upon the exit of the
+ Last thread, so as to not cause deadlock when running threads
+ attempt to exit.
+ 3) Cleanup the use of the AML "MethodFlags" and internal method flags
+ so that there is no longer any confusion between the two.
+
+ Lin Ming, Bob Moore. Reported by dana.myers@oracle.com.
+
+Debugger: Now lock the namespace for duration of a namespace dump.
+Prevents
+issues if the namespace is changing dynamically underneath the debugger.
+Especially affects temporary namespace nodes, since the debugger displays
+these also.
+
+Updated the ordering of include files. The ACPICA headers should appear
+before any compiler-specific headers (stdio.h, etc.) so that acenv.h can
+set
+any necessary compiler-specific defines, etc. Affects the ACPI-related
+tools
+and utilities.
+
+Updated all ACPICA copyrights and signons to 2011. Added the 2011
+copyright
+to all module headers and signons, including the Linux header. This
+affects
+virtually every file in the ACPICA core subsystem, iASL compiler, and all
+utilities.
+
+Added project files for MS Visual Studio 2008 (VC++ 9.0). The original
+project files for VC++ 6.0 are now obsolete. New project files can be
+found
+under acpica/generate/msvc9. See acpica/generate/msvc9/readme.txt for
+details.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release (VC 6.0):
+ Non-Debug Version: 89.8K Code, 18.9K Data, 108.7K Total
+ Debug Version: 166.6K Code, 52.1K Data, 218.7K Total
+ Current Release (VC 9.0):
+ Non-Debug Version: 89.7K Code, 23.7K Data, 113.4K Total
+ Debug Version: 163.9K Code, 67.5K Data, 231.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added generic data types to the Data Table compiler. Add "generic"
+data
+types such as UINT32, String, Unicode, etc., to simplify the generation
+of
+platform-defined tables such as UEFI. Lin Ming.
+
+iASL: Added listing support for the Data Table Compiler. Adds listing
+support
+(-l) to display actual binary output for each line of input code.
+
+----------------------------------------
+09 December 2010. Summary of changes for version 20101209:
+
+1) ACPI CA Core Subsystem:
+
+Completed the major overhaul of the GPE support code that was begun in
+July
+2010. Major features include: removal of _PRW execution in ACPICA (host
+executes _PRWs anyway), cleanup of "wake" GPE interfaces and processing,
+changes to existing interfaces, simplification of GPE handler operation,
+and
+a handful of new interfaces:
+
+ AcpiUpdateAllGpes
+ AcpiFinishGpe
+ AcpiSetupGpeForWake
+ AcpiSetGpeWakeMask
+ One new file, evxfgpe.c to consolidate all external GPE interfaces.
+
+See the ACPICA Programmer Reference for full details and programming
+information. See the new section 4.4 "General Purpose Event (GPE)
+Support"
+for a full overview, and section 8.7 "ACPI General Purpose Event
+Management"
+for programming details. ACPICA BZ 858,870,877. Matthew Garrett, Lin
+Ming,
+Bob Moore, Rafael Wysocki.
+
+Implemented a new GPE feature for Windows compatibility, the "Implicit
+Wake
+GPE Notify". This feature will automatically issue a Notify(2) on a
+device
+when a Wake GPE is received if there is no corresponding GPE method or
+handler. ACPICA BZ 870.
+
+Fixed a problem with the Scope() operator during table parse and load
+phase.
+During load phase (table load or method execution), the scope operator
+should
+not enter the target into the namespace. Instead, it should open a new
+scope
+at the target location. Linux BZ 19462, ACPICA BZ 882.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 89.8K Code, 18.9K Data, 108.7K Total
+ Debug Version: 166.6K Code, 52.1K Data, 218.7K Total
+ Current Release:
+ Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total
+ Debug Version: 166.3K Code, 52.1K Data, 218.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Relax the alphanumeric restriction on _CID strings. These strings
+are
+"bus-specific" per the ACPI specification, and therefore any characters
+are
+acceptable. The only checks that can be performed are for a null string
+and
+perhaps for a leading asterisk. ACPICA BZ 886.
+
+iASL: Fixed a problem where a syntax error that caused a premature EOF
+condition on the source file emitted a very confusing error message. The
+premature EOF is now detected correctly. ACPICA BZ 891.
+
+Disassembler: Decode the AccessSize within a Generic Address Structure
+(byte
+access, word access, etc.) Note, this field does not allow arbitrary bit
+access, the size is encoded as 1=byte, 2=word, 3=dword, and 4=qword.
+
+New: AcpiNames utility - Example namespace dump utility. Shows an example
+of
+ACPICA configuration for a minimal namespace dump utility. Uses table and
+namespace managers, but no AML interpreter. Does not add any
+functionality
+over AcpiExec, it is a subset of AcpiExec. The purpose is to show how to
+partition and configure ACPICA. ACPICA BZ 883.
+
+AML Debugger: Increased the debugger buffer size for method return
+objects.
+Was 4K, increased to 16K. Also enhanced error messages for debugger
+method
+execution, including the buffer overflow case.
+
+----------------------------------------
+13 October 2010. Summary of changes for version 20101013:
+
+1) ACPI CA Core Subsystem:
+
+Added support to clear the PCIEXP_WAKE event. When clearing ACPI events,
+now
+clear the PCIEXP_WAKE_STS bit in the ACPI PM1 Status Register, via
+HwClearAcpiStatus. Original change from Colin King. ACPICA BZ 880.
+
+Changed the type of the predefined namespace object _TZ from ThermalZone
+to
+Device. This was found to be confusing to the host software that
+processes
+the various thermal zones, since _TZ is not really a ThermalZone.
+However,
+a
+Notify() can still be performed on it. ACPICA BZ 876. Suggestion from Rui
+Zhang.
+
+Added Windows Vista SP2 to the list of supported _OSI strings. The actual
+string is "Windows 2006 SP2".
+
+Eliminated duplicate code in AcpiUtExecute* functions. Now that the
+nsrepair
+code automatically repairs _HID-related strings, this type of code is no
+longer needed in Execute_HID, Execute_CID, and Execute_UID. ACPICA BZ
+878.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total
+ Debug Version: 166.3K Code, 52.1K Data, 218.4K Total
+ Current Release:
+ Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total
+ Debug Version: 166.3K Code, 52.1K Data, 218.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented additional compile-time validation for _HID strings.
+The
+non-hex prefix (such as "PNP" or "ACPI") must be uppercase, and the
+length
+of
+the string must be exactly seven or eight characters. For both _HID and
+_CID
+strings, all characters must be alphanumeric. ACPICA BZ 874.
+
+iASL: Allow certain "null" resource descriptors. Some BIOS code creates
+descriptors that are mostly or all zeros, with the expectation that they
+will
+be filled in at runtime. iASL now allows this as long as there is a
+"resource
+tag" (name) associated with the descriptor, which gives the ASL a handle
+needed to modify the descriptor. ACPICA BZ 873.
+
+Added single-thread support to the generic Unix application OSL.
+Primarily
+for iASL support, this change removes the use of semaphores in the
+single-
+threaded ACPICA tools/applications - increasing performance. The
+_MULTI_THREADED option was replaced by the (reverse) ACPI_SINGLE_THREADED
+option. ACPICA BZ 879.
+
+AcpiExec: several fixes for the 64-bit version. Adds XSDT support and
+support
+for 64-bit DSDT/FACS addresses in the FADT. Lin Ming.
+
+iASL: Moved all compiler messages to a new file, aslmessages.h.
+
+----------------------------------------
+15 September 2010. Summary of changes for version 20100915:
+
+1) ACPI CA Core Subsystem:
+
+Removed the AcpiOsDerivePciId OSL interface. The various host
+implementations
+of this function were not OS-dependent and are now obsolete and can be
+removed from all host OSLs. This function has been replaced by
+AcpiHwDerivePciId, which is now part of the ACPICA core code.
+AcpiHwDerivePciId has been implemented without recursion. Adds one new
+module, hwpci.c. ACPICA BZ 857.
+
+Implemented a dynamic repair for _HID and _CID strings. The following
+problems are now repaired at runtime: 1) Remove a leading asterisk in the
+string, and 2) the entire string is uppercased. Both repairs are in
+accordance with the ACPI specification and will simplify host driver
+code.
+ACPICA BZ 871.
+
+The ACPI_THREAD_ID type is no longer configurable, internally it is now
+always UINT64. This simplifies the ACPICA code, especially any printf
+output.
+UINT64 is the only common data type for all thread_id types across all
+operating systems. It is now up to the host OSL to cast the native
+thread_id
+type to UINT64 before returning the value to ACPICA (via
+AcpiOsGetThreadId).
+Lin Ming, Bob Moore.
+
+Added the ACPI_INLINE type to enhance the ACPICA configuration. The
+"inline"
+keyword is not standard across compilers, and this type allows inline to
+be
+configured on a per-compiler basis. Lin Ming.
+
+Made the system global AcpiGbl_SystemAwakeAndRunning publically
+available.
+Added an extern for this boolean in acpixf.h. Some hosts utilize this
+value
+during suspend/restore operations. ACPICA BZ 869.
+
+All code that implements error/warning messages with the "ACPI:" prefix
+has
+been moved to a new module, utxferror.c.
+
+The UINT64_OVERLAY was moved to utmath.c, which is the only module where
+it
+is used. ACPICA BZ 829. Lin Ming, Bob Moore.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 89.1K Code, 19.0K Data, 108.1K Total
+ Debug Version: 165.1K Code, 51.9K Data, 217.0K Total
+ Current Release:
+ Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total
+ Debug Version: 166.3K Code, 52.1K Data, 218.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/Disassembler: Write ACPI errors to stderr instead of the output
+file.
+This keeps the output files free of random error messages that may
+originate
+from within the namespace/interpreter code. Used this opportunity to
+merge
+all ACPI:-style messages into a single new module, utxferror.c. ACPICA BZ
+866. Lin Ming, Bob Moore.
+
+Tools: update some printfs for ansi warnings on size_t. Handle width
+change
+of size_t on 32-bit versus 64-bit generations. Lin Ming.
+
+----------------------------------------
+06 August 2010. Summary of changes for version 20100806:
+
+1) ACPI CA Core Subsystem:
+
+Designed and implemented a new host interface to the _OSI support code.
+This
+will allow the host to dynamically add or remove multiple _OSI strings,
+as
+well as install an optional handler that is called for each _OSI
+invocation.
+Also added a new AML debugger command, 'osi' to display and modify the
+global
+_OSI string table, and test support in the AcpiExec utility. See the
+ACPICA
+reference manual for full details. Lin Ming, Bob Moore. ACPICA BZ 836.
+New Functions:
+ AcpiInstallInterface - Add an _OSI string.
+ AcpiRemoveInterface - Delete an _OSI string.
+ AcpiInstallInterfaceHandler - Install optional _OSI handler.
+Obsolete Functions:
+ AcpiOsValidateInterface - no longer used.
+New Files:
+ source/components/utilities/utosi.c
+
+Re-introduced the support to enable multi-byte transfers for Embedded
+Controller (EC) operation regions. A reported problem was found to be a
+bug
+in the host OS, not in the multi-byte support. Previously, the maximum
+data
+size passed to the EC operation region handler was a single byte. There
+are
+often EC Fields larger than one byte that need to be transferred, and it
+is
+useful for the EC driver to lock these as a single transaction. This
+change
+enables single transfers larger than 8 bits. This effectively changes the
+access to the EC space from ByteAcc to AnyAcc, and will probably require
+changes to the host OS Embedded Controller driver to enable 16/32/64/256-
+bit
+transfers in addition to 8-bit transfers. Alexey Starikovskiy, Lin Ming.
+
+Fixed a problem with the prototype for AcpiOsReadPciConfiguration. The
+prototype in acpiosxf.h had the output value pointer as a (void *).
+It should be a (UINT64 *). This may affect some host OSL code.
+
+Fixed a couple problems with the recently modified Linux makefiles for
+iASL
+and AcpiExec. These new makefiles place the generated object files in the
+local directory so that there can be no collisions between the files that
+are
+shared between them that are compiled with different options.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 88.3K Code, 18.8K Data, 107.1K Total
+ Debug Version: 164.0K Code, 51.5K Data, 215.5K Total
+ Current Release:
+ Non-Debug Version: 89.1K Code, 19.0K Data, 108.1K Total
+ Debug Version: 165.1K Code, 51.9K Data, 217.0K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/Disassembler: Added a new option (-da, "disassemble all") to load
+the
+namespace from and disassemble an entire group of AML files. Useful for
+loading all of the AML tables for a given machine (DSDT, SSDT1...SSDTn)
+and
+disassembling with one simple command. ACPICA BZ 865. Lin Ming.
+
+iASL: Allow multiple invocations of -e option. This change allows
+multiple
+uses of -e on the command line: "-e ssdt1.dat -e ssdt2.dat". ACPICA BZ
+834.
+Lin Ming.
+
+----------------------------------------
+02 July 2010. Summary of changes for version 20100702:
+
+1) ACPI CA Core Subsystem:
+
+Implemented several updates to the recently added GPE reference count
+support. The model for "wake" GPEs is changing to give the host OS
+complete
+control of these GPEs. Eventually, the ACPICA core will not execute any
+_PRW
+methods, since the host already must execute them. Also, additional
+changes
+were made to help ensure that the reference counts are kept in proper
+synchronization with reality. Rafael J. Wysocki.
+
+1) Ensure that GPEs are not enabled twice during initialization.
+2) Ensure that GPE enable masks stay in sync with the reference count.
+3) Do not inadvertently enable GPEs when writing GPE registers.
+4) Remove the internal wake reference counter and add new AcpiGpeWakeup
+interface. This interface will set or clear individual GPEs for wakeup.
+5) Remove GpeType argument from AcpiEnable and AcpiDisable. These
+interfaces
+are now used for "runtime" GPEs only.
+
+Changed the behavior of the GPE install/remove handler interfaces. The
+GPE
+is
+no longer disabled during this process, as it was found to cause problems
+on
+some machines. Rafael J. Wysocki.
+
+Reverted a change introduced in version 20100528 to enable Embedded
+Controller multi-byte transfers. This change was found to cause problems
+with
+Index Fields and possibly Bank Fields. It will be reintroduced when these
+problems have been resolved.
+
+Fixed a problem with references to Alias objects within Package Objects.
+A
+reference to an Alias within the definition of a Package was not always
+resolved properly. Aliases to objects like Processors, Thermal zones,
+etc.
+were resolved to the actual object instead of a reference to the object
+as
+it
+should be. Package objects are only allowed to contain integer, string,
+buffer, package, and reference objects. Redhat bugzilla 608648.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 88.3K Code, 18.8K Data, 107.1K Total
+ Debug Version: 164.1K Code, 51.5K Data, 215.6K Total
+ Current Release:
+ Non-Debug Version: 88.3K Code, 18.8K Data, 107.1K Total
+ Debug Version: 164.0K Code, 51.5K Data, 215.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented a new compiler subsystem to allow definition and
+compilation of the non-AML ACPI tables such as FADT, MADT, SRAT, etc.
+These
+are called "ACPI Data Tables", and the new compiler is the "Data Table
+Compiler". This compiler is intended to simplify the existing error-prone
+process of creating these tables for the BIOS, as well as allowing the
+disassembly, modification, recompilation, and override of existing ACPI
+data
+tables. See the iASL User Guide for detailed information.
+
+iASL: Implemented a new Template Generator option in support of the new
+Data
+Table Compiler. This option will create examples of all known ACPI tables
+that can be used as the basis for table development. See the iASL
+documentation and the -T option.
+
+Disassembler and headers: Added support for the WDDT ACPI table (Watchdog
+Descriptor Table).
+
+Updated the Linux makefiles for iASL and AcpiExec to place the generated
+object files in the local directory so that there can be no collisions
+between the shared files between them that are generated with different
+options.
+
+Added support for Mac OS X in the Unix OSL used for iASL and AcpiExec.
+Use
+the #define __APPLE__ to enable this support.
+
+----------------------------------------
+28 May 2010. Summary of changes for version 20100528:
+
+Note: The ACPI 4.0a specification was released on April 5, 2010 and is
+available at www.acpi.info. This is primarily an errata release.
+
+1) ACPI CA Core Subsystem:
+
+Undefined ACPI tables: We are looking for the definitions for the
+following
+ACPI tables that have been seen in the field: ATKG, IEIT, GSCI.
+
+Implemented support to enable multi-byte transfers for Embedded
+Controller
+(EC) operation regions. Previously, the maximum data size passed to the
+EC
+operation region handler was a single byte. There are often EC Fields
+larger
+than one byte that need to be transferred, and it is useful for the EC
+driver
+to lock these as a single transaction. This change enables single
+transfers
+larger than 8 bits. This effectively changes the access to the EC space
+from
+ByteAcc to AnyAcc, and will probably require changes to the host OS
+Embedded
+Controller driver to enable 16/32/64/256-bit transfers in addition to 8-
+bit
+transfers. Alexey Starikovskiy, Lin Ming
+
+Implemented a performance enhancement for namespace search and access.
+This
+change enhances the performance of namespace searches and walks by adding
+a
+backpointer to the parent in each namespace node. On large namespaces,
+this
+change can improve overall ACPI performance by up to 9X. Adding a pointer
+to
+each namespace node increases the overall size of the internal namespace
+by
+about 5%, since each namespace entry usually consists of both a namespace
+node and an ACPI operand object. However, this is the first growth of the
+namespace in ten years. ACPICA bugzilla 817. Alexey Starikovskiy.
+
+Implemented a performance optimization that reduces the number of
+namespace
+walks. On control method exit, only walk the namespace if the method is
+known
+to have created namespace objects outside of its local scope. Previously,
+the
+entire namespace was traversed on each control method exit. This change
+can
+improve overall ACPI performance by up to 3X. Alexey Starikovskiy, Bob
+Moore.
+
+Added support to truncate I/O addresses to 16 bits for Windows
+compatibility.
+Some ASL code has been seen in the field that inadvertently has bits set
+above bit 15. This feature is optional and is enabled if the BIOS
+requests
+any Windows OSI strings. It can also be enabled by the host OS. Matthew
+Garrett, Bob Moore.
+
+Added support to limit the maximum time for the ASL Sleep() operator. To
+prevent accidental deep sleeps, limit the maximum time that Sleep() will
+actually sleep. Configurable, the default maximum is two seconds. ACPICA
+bugzilla 854.
+
+Added run-time validation support for the _WDG and_WED Microsoft
+predefined
+methods. These objects are defined by "Windows Instrumentation", and are
+not
+part of the ACPI spec. ACPICA BZ 860.
+
+Expanded all statistic counters used during namespace and device
+initialization from 16 to 32 bits in order to support very large
+namespaces.
+
+Replaced all instances of %d in printf format specifiers with %u since
+nearly
+all integers in ACPICA are unsigned.
+
+Fixed the exception namestring for AE_WAKE_ONLY_GPE. Was incorrectly
+returned
+as AE_NO_HANDLER.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 88.4K Code, 18.8K Data, 107.2K Total
+ Debug Version: 164.2K Code, 51.5K Data, 215.7K Total
+ Current Release:
+ Non-Debug Version: 88.3K Code, 18.8K Data, 107.1K Total
+ Debug Version: 164.1K Code, 51.5K Data, 215.6K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added compiler support for the _WDG and_WED Microsoft predefined
+methods. These objects are defined by "Windows Instrumentation", and are
+not
+part of the ACPI spec. ACPICA BZ 860.
+
+AcpiExec: added option to disable the memory tracking mechanism. The -dt
+option will disable the tracking mechanism, which improves performance
+considerably.
+
+AcpiExec: Restructured the command line options into -d (disable) and -e
+(enable) options.
+
+----------------------------------------
+28 April 2010. Summary of changes for version 20100428:
+
+1) ACPI CA Core Subsystem:
+
+Implemented GPE support for dynamically loaded ACPI tables. For all GPEs,
+including FADT-based and GPE Block Devices, execute any _PRW methods in
+the
+new table, and process any _Lxx/_Exx GPE methods in the new table. Any
+runtime GPE that is referenced by an _Lxx/_Exx method in the new table is
+immediately enabled. Handles the FADT-defined GPEs as well as GPE Block
+Devices. Provides compatibility with other ACPI implementations. Two new
+files added, evgpeinit.c and evgpeutil.c. ACPICA BZ 833. Lin Ming, Bob
+Moore.
+
+Fixed a regression introduced in version 20100331 within the table
+manager
+where initial table loading could fail. This was introduced in the fix
+for
+AcpiReallocateRootTable. Also, renamed some of fields in the table
+manager
+data structures to clarify their meaning and use.
+
+Fixed a possible allocation overrun during internal object copy in
+AcpiUtCopySimpleObject. The original code did not correctly handle the
+case
+where the object to be copied was a namespace node. Lin Ming. ACPICA BZ
+847.
+
+Updated the allocation dump routine, AcpiUtDumpAllocation and fixed a
+possible access beyond end-of-allocation. Also, now fully validate
+descriptor
+(size and type) before output. Lin Ming, Bob Moore. ACPICA BZ 847
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total
+ Debug Version: 163.5K Code, 51.3K Data, 214.8K Total
+ Current Release:
+ Non-Debug Version: 88.4K Code, 18.8K Data, 107.2K Total
+ Debug Version: 164.2K Code, 51.5K Data, 215.7K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented Min/Max/Len/Gran validation for address resource
+descriptors. This change implements validation for the address fields
+that
+are common to all address-type resource descriptors. These checks are
+implemented: Checks for valid Min/Max, length within the Min/Max window,
+valid granularity, Min/Max a multiple of granularity, and _MIF/_MAF as
+per
+table 6-40 in the ACPI 4.0a specification. Also split the large
+aslrestype1.c
+and aslrestype2.c files into five new files. ACPICA BZ 840.
+
+iASL: Added support for the _Wxx predefined names. This support was
+missing
+and these names were not recognized by the compiler as valid predefined
+names. ACPICA BZ 851.
+
+iASL: Added an error for all predefined names that are defined to return
+no
+value and thus must be implemented as Control Methods. These include all
+of
+the _Lxx, _Exx, _Wxx, and _Qxx names, as well as some other miscellaneous
+names such as _DIS, _INI, _IRC, _OFF, _ON, and _PSx. ACPICA BZ 850, 856.
+
+iASL: Implemented the -ts option to emit hex AML data in ASL format, as
+an
+ASL Buffer. Allows ACPI tables to be easily included within ASL files, to
+be
+dynamically loaded via the Load() operator. Also cleaned up output for
+the
+-
+ta and -tc options. ACPICA BZ 853.
+
+Tests: Added a new file with examples of extended iASL error checking.
+Demonstrates the advanced error checking ability of the iASL compiler.
+Available at tests/misc/badcode.asl.
+
+----------------------------------------
+31 March 2010. Summary of changes for version 20100331:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major update for the GPE support in order to improve support
+for
+shared GPEs and to simplify both host OS and ACPICA code. Added a
+reference
+count mechanism to support shared GPEs that require multiple device
+drivers.
+Several external interfaces have changed. One external interface has been
+removed. One new external interface was added. Most of the GPE external
+interfaces now use the GPE spinlock instead of the events mutex (and the
+Flags parameter for many GPE interfaces has been removed.) See the
+updated
+ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore,
+Rafael
+Wysocki. ACPICA BZ 831.
+
+Changed:
+ AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus
+Removed:
+ AcpiSetGpeType
+New:
+ AcpiSetGpe
+
+Implemented write support for DataTable operation regions. These regions
+are
+defined via the DataTableRegion() operator. Previously, only read support
+was
+implemented. The ACPI specification allows DataTableRegions to be
+read/write,
+however.
+
+Implemented a new subsystem option to force a copy of the DSDT to local
+memory. Optionally copy the entire DSDT to local memory (instead of
+simply
+mapping it.) There are some (albeit very rare) BIOSs that corrupt or
+replace
+the original DSDT, creating the need for this option. Default is FALSE,
+do
+not copy the DSDT.
+
+Implemented detection of a corrupted or replaced DSDT. This change adds
+support to detect a DSDT that has been corrupted and/or replaced from
+outside
+the OS (by firmware). This is typically catastrophic for the system, but
+has
+been seen on some machines. Once this problem has been detected, the DSDT
+copy option can be enabled via system configuration. Lin Ming, Bob Moore.
+
+Fixed two problems with AcpiReallocateRootTable during the root table
+copy.
+When copying the root table to the new allocation, the length used was
+incorrect. The new size was used instead of the current table size,
+meaning
+too much data was copied. Also, the count of available slots for ACPI
+tables
+was not set correctly. Alexey Starikovskiy, Bob Moore.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.5K Code, 18.4K Data, 105.9K Total
+ Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
+ Current Release:
+ Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total
+ Debug Version: 163.5K Code, 51.3K Data, 214.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implement limited typechecking for values returned from predefined
+control methods. The type of any returned static (unnamed) object is now
+validated. For example, Return(1). ACPICA BZ 786.
+
+iASL: Fixed a predefined name object verification regression. Fixes a
+problem
+introduced in version 20100304. An error is incorrectly generated if a
+predefined name is declared as a static named object with a value defined
+using the keywords "Zero", "One", or "Ones". Lin Ming.
+
+iASL: Added Windows 7 support for the -g option (get local ACPI tables)
+by
+reducing the requested registry access rights. ACPICA BZ 842.
+
+Disassembler: fixed a possible fault when generating External()
+statements.
+Introduced in commit ae7d6fd: Properly handle externals with parent-
+prefix
+(carat). Fixes a string length allocation calculation. Lin Ming.
+
+----------------------------------------
+04 March 2010. Summary of changes for version 20100304:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a possible problem with the AML Mutex handling function
+AcpiExReleaseMutex where the function could fault under the very rare
+condition when the interpreter has blocked, the interpreter lock is
+released,
+the interpreter is then reentered via the same thread, and attempts to
+acquire an AML mutex that was previously acquired. FreeBSD report 140979.
+Lin
+Ming.
+
+Implemented additional configuration support for the AML "Debug Object".
+Output from the debug object can now be enabled via a global variable,
+AcpiGbl_EnableAmlDebugObject. This will assist with remote machine
+debugging.
+This debug output is now available in the release version of ACPICA
+instead
+of just the debug version. Also, the entire debug output module can now
+be
+configured out of the ACPICA build if desired. One new file added,
+executer/exdebug.c. Lin Ming, Bob Moore.
+
+Added header support for the ACPI MCHI table (Management Controller Host
+Interface Table). This table was added in ACPI 4.0, but the defining
+document
+has only recently become available.
+
+Standardized output of integer values for ACPICA warnings/errors. Always
+use
+0x prefix for hex output, always use %u for unsigned integer decimal
+output.
+Affects ACPI_INFO, ACPI_ERROR, ACPI_EXCEPTION, and ACPI_WARNING (about
+400
+invocations.) These invocations were converted from the original
+ACPI_DEBUG_PRINT invocations and were not consistent. ACPICA BZ 835.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.1K Code, 18.0K Data, 105.1K Total
+ Debug Version: 163.5K Code, 50.9K Data, 214.4K Total
+ Current Release:
+ Non-Debug Version: 87.5K Code, 18.4K Data, 105.9K Total
+ Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented typechecking support for static (non-control method)
+predefined named objects that are declared with the Name() operator. For
+example, the type of this object is now validated to be of type Integer:
+Name(_BBN, 1). This change migrates the compiler to using the core
+predefined
+name table instead of maintaining a local version. Added a new file,
+aslpredef.c. ACPICA BZ 832.
+
+Disassembler: Added support for the ACPI 4.0 MCHI table.
+
+----------------------------------------
+21 January 2010. Summary of changes for version 20100121:
+
+1) ACPI CA Core Subsystem:
+
+Added the 2010 copyright to all module headers and signons. This affects
+virtually every file in the ACPICA core subsystem, the iASL compiler, the
+tools/utilities, and the test suites.
+
+Implemented a change to the AcpiGetDevices interface to eliminate
+unnecessary
+invocations of the _STA method. In the case where a specific _HID is
+requested, do not run _STA until a _HID match is found. This eliminates
+potentially dozens of _STA calls during a search for a particular
+device/HID,
+which in turn can improve boot times. ACPICA BZ 828. Lin Ming.
+
+Implemented an additional repair for predefined method return values.
+Attempt
+to repair unexpected NULL elements within returned Package objects.
+Create
+an
+Integer of value zero, a NULL String, or a zero-length Buffer as
+appropriate.
+ACPICA BZ 818. Lin Ming, Bob Moore.
+
+Removed the obsolete ACPI_INTEGER data type. This type was introduced as
+the
+code was migrated from ACPI 1.0 (with 32-bit AML integers) to ACPI 2.0
+(with
+64-bit AML integers). It is now obsolete and this change removes it from
+the
+ACPICA code base, replaced by UINT64. The original typedef has been
+retained
+for now for compatibility with existing device driver code. ACPICA BZ
+824.
+
+Removed the unused UINT32_STRUCT type, and the obsolete Integer64 field
+in
+the parse tree object.
+
+Added additional warning options for the gcc-4 generation. Updated the
+source
+accordingly. This includes some code restructuring to eliminate
+unreachable
+code, elimination of some gotos, elimination of unused return values,
+some
+additional casting, and removal of redundant declarations.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.0K Code, 18.0K Data, 105.0K Total
+ Debug Version: 163.4K Code, 50.8K Data, 214.2K Total
+ Current Release:
+ Non-Debug Version: 87.1K Code, 18.0K Data, 105.1K Total
+ Debug Version: 163.5K Code, 50.9K Data, 214.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+No functional changes for this release.
+
+----------------------------------------
+14 December 2009. Summary of changes for version 20091214:
+
+1) ACPI CA Core Subsystem:
+
+Enhanced automatic data type conversions for predefined name repairs.
+This
+change expands the automatic repairs/conversions for predefined name
+return
+values to make Integers, Strings, and Buffers fully interchangeable.
+Also,
+a
+Buffer can be converted to a Package of Integers if necessary. The
+nsrepair.c
+module was completely restructured. Lin Ming, Bob Moore.
+
+Implemented automatic removal of null package elements during predefined
+name
+repairs. This change will automatically remove embedded and trailing NULL
+package elements from returned package objects that are defined to
+contain
+a
+variable number of sub-packages. The driver is then presented with a
+package
+with no null elements to deal with. ACPICA BZ 819.
+
+Implemented a repair for the predefined _FDE and _GTM names. The expected
+return value for both names is a Buffer of 5 DWORDs. This repair fixes
+two
+possible problems (both seen in the field), where a package of integers
+is
+returned, or a buffer of BYTEs is returned. With assistance from Jung-uk
+Kim.
+
+Implemented additional module-level code support. This change will
+properly
+execute module-level code that is not at the root of the namespace (under
+a
+Device object, etc.). Now executes the code within the current scope
+instead
+of the root. ACPICA BZ 762. Lin Ming.
+
+Fixed possible mutex acquisition errors when running _REG methods. Fixes
+a
+problem where mutex errors can occur when running a _REG method that is
+in
+the same scope as a method-defined operation region or an operation
+region
+under a module-level IF block. This type of code is rare, so the problem
+has
+not been seen before. ACPICA BZ 826. Lin Ming, Bob Moore.
+
+Fixed a possible memory leak during module-level code execution. An
+object
+could be leaked for each block of executed module-level code if the
+interpreter slack mode is enabled This change deletes any implicitly
+returned
+object from the module-level code block. Lin Ming.
+
+Removed messages for successful predefined repair(s). The repair
+mechanism
+was considered too wordy. Now, messages are only unconditionally emitted
+if
+the return object cannot be repaired. Existing messages for successful
+repairs were converted to ACPI_DEBUG_PRINT messages for now. ACPICA BZ
+827.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 86.6K Code, 18.2K Data, 104.8K Total
+ Debug Version: 162.7K Code, 50.8K Data, 213.5K Total
+ Current Release:
+ Non-Debug Version: 87.0K Code, 18.0K Data, 105.0K Total
+ Debug Version: 163.4K Code, 50.8K Data, 214.2K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a regression introduced in 20091112 where intermediate .SRC
+files
+were no longer automatically removed at the termination of the compile.
+
+acpiexec: Implemented the -f option to specify default region fill value.
+This option specifies the value used to initialize buffers that simulate
+operation regions. Default value is zero. Useful for debugging problems
+that
+depend on a specific initial value for a region or field.
+
+----------------------------------------
+12 November 2009. Summary of changes for version 20091112:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a post-order callback to AcpiWalkNamespace. The existing
+interface only has a pre-order callback. This change adds an additional
+parameter for a post-order callback which will be more useful for bus
+scans.
+ACPICA BZ 779. Lin Ming. Updated the ACPICA Programmer Reference.
+
+Modified the behavior of the operation region memory mapping cache for
+SystemMemory. Ensure that the memory mappings created for operation
+regions
+do not cross 4K page boundaries. Crossing a page boundary while mapping
+regions can cause kernel warnings on some hosts if the pages have
+different
+attributes. Such regions are probably BIOS bugs, and this is the
+workaround.
+Linux BZ 14445. Lin Ming.
+
+Implemented an automatic repair for predefined methods that must return
+sorted lists. This change will repair (by sorting) packages returned by
+_ALR,
+_PSS, and _TSS. Drivers can now assume that the packages are correctly
+sorted
+and do not contain NULL package elements. Adds one new file,
+namespace/nsrepair2.c. ACPICA BZ 784. Lin Ming, Bob Moore.
+
+Fixed a possible fault during predefined name validation if a return
+Package
+object contains NULL elements. Also adds a warning if a NULL element is
+followed by any non-null elements. ACPICA BZ 813, 814. Future enhancement
+may
+include repair or removal of all such NULL elements where possible.
+
+Implemented additional module-level executable AML code support. This
+change
+will execute module-level code that is not at the root of the namespace
+(under a Device object, etc.) at table load time. Module-level executable
+AML
+code has been illegal since ACPI 2.0. ACPICA BZ 762. Lin Ming.
+
+Implemented a new internal function to create Integer objects. This
+function
+simplifies miscellaneous object creation code. ACPICA BZ 823.
+
+Reduced the severity of predefined repair messages, Warning to Info.
+Since
+the object was successfully repaired, a warning is too severe. Reduced to
+an
+info message for now. These messages may eventually be changed to debug-
+only.
+ACPICA BZ 812.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 85.8K Code, 18.0K Data, 103.8K Total
+ Debug Version: 161.8K Code, 50.6K Data, 212.4K Total
+ Current Release:
+ Non-Debug Version: 86.6K Code, 18.2K Data, 104.8K Total
+ Debug Version: 162.7K Code, 50.8K Data, 213.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented Switch() with While(1) so that Break works correctly.
+This
+change correctly implements the Switch operator with a surrounding
+While(1)
+so that the Break operator works as expected. ACPICA BZ 461. Lin Ming.
+
+iASL: Added a message if a package initializer list is shorter than
+package
+length. Adds a new remark for a Package() declaration if an initializer
+list
+exists, but is shorter than the declared length of the package. Although
+technically legal, this is probably a coding error and it is seen in the
+field. ACPICA BZ 815. Lin Ming, Bob Moore.
+
+iASL: Fixed a problem where the compiler could fault after the maximum
+number
+of errors was reached (200).
+
+acpixtract: Fixed a possible warning for pointer cast if the compiler
+warning
+level set very high.
+
+----------------------------------------
+13 October 2009. Summary of changes for version 20091013:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where an Operation Region _REG method could be executed
+more
+than once. If a custom address space handler is installed by the host
+before
+the "initialize operation regions" phase of the ACPICA initialization,
+any
+_REG methods for that address space could be executed twice. This change
+fixes the problem. ACPICA BZ 427. Lin Ming.
+
+Fixed a possible memory leak for the Scope() ASL operator. When the exact
+invocation of "Scope(\)" is executed (change scope to root), one internal
+operand object was leaked. Lin Ming.
+
+Implemented a run-time repair for the _MAT predefined method. If the _MAT
+return value is defined as a Field object in the AML, and the field
+size is less than or equal to the default width of an integer (32 or
+64),_MAT
+can incorrectly return an Integer instead of a Buffer. ACPICA now
+automatically repairs this problem. ACPICA BZ 810.
+
+Implemented a run-time repair for the _BIF and _BIX predefined methods.
+The
+"OEM Information" field is often incorrectly returned as an Integer with
+value zero if the field is not supported by the platform. This is due to
+an
+ambiguity in the ACPI specification. The field should always be a string.
+ACPICA now automatically repairs this problem by returning a NULL string
+within the returned Package. ACPICA BZ 807.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 85.6K Code, 18.0K Data, 103.6K Total
+ Debug Version: 161.7K Code, 50.9K Data, 212.6K Total
+ Current Release:
+ Non-Debug Version: 85.8K Code, 18.0K Data, 103.8K Total
+ Debug Version: 161.8K Code, 50.6K Data, 212.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a problem where references to external symbols that
+contained one or more parent-prefixes (carats) were not handled
+correctly,
+possibly causing a fault. ACPICA BZ 806. Lin Ming.
+
+Disassembler: Restructured the code so that all functions that handle
+external symbols are in a single module. One new file is added,
+common/dmextern.c.
+
+AML Debugger: Added a max count argument for the Batch command (which
+executes multiple predefined methods within the namespace.)
+
+iASL: Updated the compiler documentation (User Reference.) Available at
+http://www.acpica.org/documentation/. ACPICA BZ 750.
+
+AcpiXtract: Updated for Lint and other formatting changes. Close all open
+files.
+
+----------------------------------------
+03 September 2009. Summary of changes for version 20090903:
+
+1) ACPI CA Core Subsystem:
+
+For Windows Vista compatibility, added the automatic execution of an _INI
+method located at the namespace root (\_INI). This method is executed at
+table load time. This support is in addition to the automatic execution
+of
+\_SB._INI. Lin Ming.
+
+Fixed a possible memory leak in the interpreter for AML package objects
+if
+the package initializer list is longer than the defined size of the
+package.
+This apparently can only happen if the BIOS changes the package size on
+the
+fly (seen in a _PSS object), as ASL compilers do not allow this. The
+interpreter will truncate the package to the defined size (and issue an
+error
+message), but previously could leave the extra objects undeleted if they
+were
+pre-created during the argument processing (such is the case if the
+package
+consists of a number of sub-packages as in the _PSS.) ACPICA BZ 805.
+
+Fixed a problem seen when a Buffer or String is stored to itself via ASL.
+This has been reported in the field. Previously, ACPICA would zero out
+the
+buffer/string. Now, the operation is treated as a noop. Provides Windows
+compatibility. ACPICA BZ 803. Lin Ming.
+
+Removed an extraneous error message for ASL constructs of the form
+Store(LocalX,LocalX) when LocalX is uninitialized. These curious
+statements
+are seen in many BIOSs and are once again treated as NOOPs and no error
+is
+emitted when they are encountered. ACPICA BZ 785.
+
+Fixed an extraneous warning message if a _DSM reserved method returns a
+Package object. _DSM can return any type of object, so validation on the
+return type cannot be performed. ACPICA BZ 802.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 85.5K Code, 18.0K Data, 103.5K Total
+ Debug Version: 161.6K Code, 50.9K Data, 212.5K Total
+ Current Release:
+ Non-Debug Version: 85.6K Code, 18.0K Data, 103.6K Total
+ Debug Version: 161.7K Code, 50.9K Data, 212.6K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a problem with the use of the Alias operator and Resource
+Templates. The correct alias is now constructed and no error is emitted.
+ACPICA BZ 738.
+
+iASL: Implemented the -I option to specify additional search directories
+for
+include files. Allows multiple additional search paths for include files.
+Directories are searched in the order specified on the command line
+(after
+the local directory is searched.) ACPICA BZ 800.
+
+iASL: Fixed a problem where the full pathname for include files was not
+emitted for warnings/errors. This caused the IDE support to not work
+properly. ACPICA BZ 765.
+
+iASL: Implemented the -@ option to specify a Windows-style response file
+containing additional command line options. ACPICA BZ 801.
+
+AcpiExec: Added support to load multiple AML files simultaneously (such
+as
+a
+DSDT and multiple SSDTs). Also added support for wildcards within the AML
+pathname. These features allow all machine tables to be easily loaded and
+debugged together. ACPICA BZ 804.
+
+Disassembler: Added missing support for disassembly of HEST table Error
+Bank
+subtables.
+
+----------------------------------------
+30 July 2009. Summary of changes for version 20090730:
+
+The ACPI 4.0 implementation for ACPICA is complete with this release.
+
+1) ACPI CA Core Subsystem:
+
+ACPI 4.0: Added header file support for all new and changed ACPI tables.
+Completely new tables are: IBFT, IVRS, MSCT, and WAET. Tables that are
+new
+for ACPI 4.0, but have previously been supported in ACPICA are: CPEP,
+BERT,
+EINJ, ERST, and HEST. Other newly supported tables are: UEFI and WDAT.
+There
+have been some ACPI 4.0 changes to other existing tables. Split the large
+actbl1.h header into the existing actbl2.h header. ACPICA BZ 774.
+
+ACPI 4.0: Implemented predefined name validation for all new names. There
+are
+31 new names in ACPI 4.0. The predefined validation module was split into
+two
+files. The new file is namespace/nsrepair.c. ACPICA BZ 770.
+
+Implemented support for so-called "module-level executable code". This is
+executable AML code that exists outside of any control method and is
+intended
+to be executed at table load time. Although illegal since ACPI 2.0, this
+type
+of code still exists and is apparently still being created. Blocks of
+this
+code are now detected and executed as intended. Currently, the code
+blocks
+must exist under either an If, Else, or While construct; these are the
+typical cases seen in the field. ACPICA BZ 762. Lin Ming.
+
+Implemented an automatic dynamic repair for predefined names that return
+nested Package objects. This applies to predefined names that are defined
+to
+return a variable-length Package of sub-packages. If the number of sub-
+packages is one, BIOS code is occasionally seen that creates a simple
+single
+package with no sub-packages. This code attempts to fix the problem by
+wrapping a new package object around the existing package. These methods
+can
+be repaired: _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, and _TSS. ACPICA
+BZ
+790.
+
+Fixed a regression introduced in 20090625 for the AcpiGetDevices
+interface.
+The _HID/_CID matching was broken and no longer matched IDs correctly.
+ACPICA
+BZ 793.
+
+Fixed a problem with AcpiReset where the reset would silently fail if the
+register was one of the protected I/O ports. AcpiReset now bypasses the
+port
+validation mechanism. This may eventually be driven into the
+AcpiRead/Write
+interfaces.
+
+Fixed a regression related to the recent update of the AcpiRead/Write
+interfaces. A sleep/suspend could fail if the optional PM2 Control
+register
+does not exist during an attempt to write the Bus Master Arbitration bit.
+(However, some hosts already delete the code that writes this bit, and
+the
+code may in fact be obsolete at this date.) ACPICA BZ 799.
+
+Fixed a problem where AcpiTerminate could fault if inadvertently called
+twice
+in succession. ACPICA BZ 795.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 84.7K Code, 17.8K Data, 102.5K Total
+ Debug Version: 160.5K Code, 50.6K Data, 211.1K Total
+ Current Release:
+ Non-Debug Version: 85.5K Code, 18.0K Data, 103.5K Total
+ Debug Version: 161.6K Code, 50.9K Data, 212.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+ACPI 4.0: Implemented disassembler support for all new ACPI tables and
+changes to existing tables. ACPICA BZ 775.
+
+----------------------------------------
+25 June 2009. Summary of changes for version 20090625:
+
+The ACPI 4.0 Specification was released on June 16 and is available at
+www.acpi.info. ACPICA implementation of ACPI 4.0 is underway and will
+continue for the next few releases.
+
+1) ACPI CA Core Subsystem:
+
+ACPI 4.0: Implemented interpreter support for the IPMI operation region
+address space. Includes support for bi-directional data buffers and an
+IPMI
+address space handler (to be installed by an IPMI device driver.) ACPICA
+BZ
+773. Lin Ming.
+
+ACPI 4.0: Added changes for existing ACPI tables - FACS and SRAT.
+Includes
+support in both the header files and the disassembler.
+
+Completed a major update for the AcpiGetObjectInfo external interface.
+Changes include:
+ - Support for variable, unlimited length HID, UID, and CID strings.
+ - Support Processor objects the same as Devices (HID,UID,CID,ADR,STA,
+etc.)
+ - Call the _SxW power methods on behalf of a device object.
+ - Determine if a device is a PCI root bridge.
+ - Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO.
+These changes will require an update to all callers of this interface.
+See
+the updated ACPICA Programmer Reference for details. One new source file
+has
+been added - utilities/utids.c. ACPICA BZ 368, 780.
+
+Updated the AcpiRead and AcpiWrite external interfaces to support 64-bit
+transfers. The Value parameter has been extended from 32 bits to 64 bits
+in
+order to support new ACPI 4.0 tables. These changes will require an
+update
+to
+all callers of these interfaces. See the ACPICA Programmer Reference for
+details. ACPICA BZ 768.
+
+Fixed several problems with AcpiAttachData. The handler was not invoked
+when
+the host node was deleted. The data sub-object was not automatically
+deleted
+when the host node was deleted. The interface to the handler had an
+unused
+parameter, this was removed. ACPICA BZ 778.
+
+Enhanced the function that dumps ACPI table headers. All non-printable
+characters in the string fields are now replaced with '?' (Signature,
+OemId,
+OemTableId, and CompilerId.) ACPI tables with non-printable characters in
+these fields are occasionally seen in the field. ACPICA BZ 788.
+
+Fixed a problem with predefined method repair code where the code that
+attempts to repair/convert an object of incorrect type is only executed
+on
+the first time the predefined method is called. The mechanism that
+disables
+warnings on subsequent calls was interfering with the repair mechanism.
+ACPICA BZ 781.
+
+Fixed a possible memory leak in the predefined validation/repair code
+when
+a
+buffer is automatically converted to an expected string object.
+
+Removed obsolete 16-bit files from the distribution and from the current
+git
+tree head. ACPICA BZ 776.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 83.4K Code, 17.5K Data, 100.9K Total
+ Debug Version: 158.9K Code, 50.0K Data, 208.9K Total
+ Current Release:
+ Non-Debug Version: 84.7K Code, 17.8K Data, 102.5K Total
+ Debug Version: 160.5K Code, 50.6K Data, 211.1K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+ACPI 4.0: iASL and Disassembler - implemented support for the new IPMI
+operation region keyword. ACPICA BZ 771, 772. Lin Ming.
+
+ACPI 4.0: iASL - implemented compile-time validation support for all new
+predefined names and control methods (31 total). ACPICA BZ 769.
+
+----------------------------------------
+21 May 2009. Summary of changes for version 20090521:
+
+1) ACPI CA Core Subsystem:
+
+Disabled the preservation of the SCI enable bit in the PM1 control
+register.
+The SCI enable bit (bit 0, SCI_EN) is defined by the ACPI specification
+to
+be
+a "preserved" bit - "OSPM always preserves this bit position", section
+4.7.3.2.1. However, some machines fail if this bit is in fact preserved
+because the bit needs to be explicitly set by the OS as a workaround. No
+machines fail if the bit is not preserved. Therefore, ACPICA no longer
+attempts to preserve this bit.
+
+Fixed a problem in AcpiRsGetPciRoutingTableLength where an invalid or
+incorrectly formed _PRT package could cause a fault. Added validation to
+ensure that each package element is actually a sub-package.
+
+Implemented a new interface to install or override a single control
+method,
+AcpiInstallMethod. This interface is useful when debugging in order to
+repair
+an existing method or to install a missing method without having to
+override
+the entire ACPI table. See the ACPICA Programmer Reference for use and
+examples. Lin Ming, Bob Moore.
+
+Fixed several reference count issues with the DdbHandle object that is
+created from a Load or LoadTable operator. Prevent premature deletion of
+the
+object. Also, mark the object as invalid once the table has been
+unloaded.
+This is needed because the handle itself may not be deleted after the
+table
+unload, depending on whether it has been stored in a named object by the
+caller. Lin Ming.
+
+Fixed a problem with Mutex Sync Levels. Fixed a problem where if multiple
+mutexes of the same sync level are acquired but then not released in
+strict
+opposite order, the internally maintained Current Sync Level becomes
+confused
+and can cause subsequent execution errors. ACPICA BZ 471.
+
+Changed the allowable release order for ASL mutex objects. The ACPI 4.0
+specification has been changed to make the SyncLevel for mutex objects
+more
+useful. When releasing a mutex, the SyncLevel of the mutex must now be
+the
+same as the current sync level. This makes more sense than the previous
+rule
+(SyncLevel less than or equal). This change updates the code to match the
+specification.
+
+Fixed a problem with the local version of the AcpiOsPurgeCache function.
+The
+(local) cache must be locked during all cache object deletions. Andrew
+Baumann.
+
+Updated the Load operator to use operation region interfaces. This
+replaces
+direct memory mapping with region access calls. Now, all region accesses
+go
+through the installed region handler as they should.
+
+Simplified and optimized the NsGetNextNode function. Reduced parameter
+count
+and reduced code for this frequently used function.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 82.8K Code, 17.5K Data, 100.3K Total
+ Debug Version: 158.0K Code, 49.9K Data, 207.9K Total
+ Current Release:
+ Non-Debug Version: 83.4K Code, 17.5K Data, 100.9K Total
+ Debug Version: 158.9K Code, 50.0K Data, 208.9K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed some issues with DMAR, HEST, MADT tables. Some
+problems
+with sub-table disassembly and handling invalid sub-tables. Attempt
+recovery
+after an invalid sub-table ID.
+
+----------------------------------------
+22 April 2009. Summary of changes for version 20090422:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a compatibility issue with the recently released I/O port
+protection
+mechanism. For windows compatibility, 1) On a port protection violation,
+simply ignore the request and do not return an exception (allow the
+control
+method to continue execution.) 2) If only part of the request overlaps a
+protected port, read/write the individual ports that are not protected.
+Linux
+BZ 13036. Lin Ming
+
+Enhanced the execution of the ASL/AML BreakPoint operator so that it
+actually
+breaks into the AML debugger if the debugger is present. This matches the
+ACPI-defined behavior.
+
+Fixed several possible warnings related to the use of the configurable
+ACPI_THREAD_ID. This type can now be configured as either an integer or a
+pointer with no warnings. Also fixes several warnings in printf-like
+statements for the 64-bit build when the type is configured as a pointer.
+ACPICA BZ 766, 767.
+
+Fixed a number of possible warnings when compiling with gcc 4+ (depending
+on
+warning options.) Examples include printf formats, aliasing, unused
+globals,
+missing prototypes, missing switch default statements, use of non-ANSI
+library functions, use of non-ANSI constructs. See generate/unix/Makefile
+for
+a list of warning options used with gcc 3 and 4. ACPICA BZ 735.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 82.6K Code, 17.6K Data, 100.2K Total
+ Debug Version: 157.7K Code, 49.9K Data, 207.6K Total
+ Current Release:
+ Non-Debug Version: 82.8K Code, 17.5K Data, 100.3K Total
+ Debug Version: 158.0K Code, 49.9K Data, 207.9K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a generation warning from Bison 2.3 and fixed several
+warnings
+on
+the 64-bit build.
+
+iASL: Fixed a problem where the Unix/Linux versions of the compiler could
+not
+correctly digest Windows/DOS formatted files (with CR/LF).
+
+iASL: Added a new option for "quiet mode" (-va) that produces only the
+compilation summary, not individual errors and warnings. Useful for large
+batch compilations.
+
+AcpiExec: Implemented a new option (-z) to enable a forced
+semaphore/mutex
+timeout that can be used to detect hang conditions during execution of
+AML
+code (includes both internal semaphores and AML-defined mutexes and
+events.)
+
+Added new makefiles for the generation of acpica in a generic unix-like
+environment. These makefiles are intended to generate the acpica tools
+and
+utilities from the original acpica git source tree structure.
+
+Test Suites: Updated and cleaned up the documentation files. Updated the
+copyrights to 2009, affecting all source files. Use the new version of
+iASL
+with quiet mode. Increased the number of available semaphores in the
+Windows
+OSL, allowing the aslts to execute fully on Windows. For the Unix OSL,
+added
+an alternate implementation of the semaphore timeout to allow aslts to
+execute fully on Cygwin.
+
+----------------------------------------
+20 March 2009. Summary of changes for version 20090320:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a possible race condition between AcpiWalkNamespace and dynamic
+table
+unloads. Added a reader/writer locking mechanism to allow multiple
+concurrent
+namespace walks (readers), but block a dynamic table unload until it can
+gain
+exclusive write access to the namespace. This fixes a problem where a
+table
+unload could (possibly catastrophically) delete the portion of the
+namespace
+that is currently being examined by a walk. Adds a new file, utlock.c,
+that
+implements the reader/writer lock mechanism. ACPICA BZ 749.
+
+Fixed a regression introduced in version 20090220 where a change to the
+FADT
+handling could cause the ACPICA subsystem to access non-existent I/O
+ports.
+
+Modified the handling of FADT register and table (FACS/DSDT) addresses.
+The
+FADT can contain both 32-bit and 64-bit versions of these addresses.
+Previously, the 64-bit versions were favored, meaning that if both 32 and
+64
+versions were valid, but not equal, the 64-bit version was used. This was
+found to cause some machines to fail. Now, in this case, the 32-bit
+version
+is used instead. This now matches the Windows behavior.
+
+Implemented a new mechanism to protect certain I/O ports. Provides
+Microsoft
+compatibility and protects the standard PC I/O ports from access via AML
+code. Adds a new file, hwvalid.c
+
+Fixed a possible extraneous warning message from the FADT support. The
+message warns of a 32/64 length mismatch between the legacy and GAS
+definitions for a register.
+
+Removed the obsolete AcpiOsValidateAddress OSL interface. This interface
+is
+made obsolete by the port protection mechanism above. It was previously
+used
+to validate the entire address range of an operation region, which could
+be
+incorrect if the range included illegal ports, but fields within the
+operation region did not actually access those ports. Validation is now
+performed on a per-field basis instead of the entire region.
+
+Modified the handling of the PM1 Status Register ignored bit (bit 11.)
+Ignored bits must be "preserved" according to the ACPI spec. Usually,
+this
+means a read/modify/write when writing to the register. However, for
+status
+registers, writing a one means clear the event. Writing a zero means
+preserve
+the event (do not clear.) This behavior is clarified in the ACPI 4.0
+spec,
+and the ACPICA code now simply always writes a zero to the ignored bit.
+
+Modified the handling of ignored bits for the PM1 A/B Control Registers.
+As
+per the ACPI specification, for the control registers, preserve
+(read/modify/write) all bits that are defined as either reserved or
+ignored.
+
+Updated the handling of write-only bits in the PM1 A/B Control Registers.
+When reading the register, zero the write-only bits as per the ACPI spec.
+ACPICA BZ 443. Lin Ming.
+
+Removed "Linux" from the list of supported _OSI strings. Linux no longer
+wants to reply true to this request. The Windows strings are the only
+paths
+through the AML that are tested and known to work properly.
+
+ Previous Release:
+ Non-Debug Version: 82.0K Code, 17.5K Data, 99.5K Total
+ Debug Version: 156.9K Code, 49.8K Data, 206.7K Total
+ Current Release:
+ Non-Debug Version: 82.6K Code, 17.6K Data, 100.2K Total
+ Debug Version: 157.7K Code, 49.9K Data, 207.6K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Acpiexec: Split the large aeexec.c file into two new files, aehandlers.c
+and
+aetables.c
+
+----------------------------------------
+20 February 2009. Summary of changes for version 20090220:
+
+1) ACPI CA Core Subsystem:
+
+Optimized the ACPI register locking. Removed locking for reads from the
+ACPI
+bit registers in PM1 Status, Enable, Control, and PM2 Control. The lock
+is
+not required when reading the single-bit registers. The
+AcpiGetRegisterUnlocked function is no longer needed and has been
+removed.
+This will improve performance for reads on these registers. ACPICA BZ
+760.
+
+Fixed the parameter validation for AcpiRead/Write. Now return
+AE_BAD_PARAMETER if the input register pointer is null, and
+AE_BAD_ADDRESS
+if
+the register has an address of zero. Previously, these cases simply
+returned
+AE_OK. For optional registers such as PM1B status/enable/control, the
+caller
+should check for a valid register address before calling. ACPICA BZ 748.
+
+Renamed the external ACPI bit register access functions. Renamed
+AcpiGetRegister and AcpiSetRegister to clarify the purpose of these
+functions. The new names are AcpiReadBitRegister and
+AcpiWriteBitRegister.
+Also, restructured the code for these functions by simplifying the code
+path
+and condensing duplicate code to reduce code size.
+
+Added new functions to transparently handle the possibly split PM1 A/B
+registers. AcpiHwReadMultiple and AcpiHwWriteMultiple. These two
+functions
+now handle the split registers for PM1 Status, Enable, and Control.
+ACPICA
+BZ
+746.
+
+Added a function to handle the PM1 control registers,
+AcpiHwWritePm1Control.
+This function writes both of the PM1 control registers (A/B). These
+registers
+are different than the PM1 A/B status and enable registers in that
+different
+values can be written to the A/B registers. Most notably, the SLP_TYP
+bits
+can be different, as per the values returned from the _Sx predefined
+methods.
+
+Removed an extra register write within AcpiHwClearAcpiStatus. This
+function
+was writing an optional PM1B status register twice. The existing call to
+the
+low-level AcpiHwRegisterWrite automatically handles a possibly split PM1
+A/B
+register. ACPICA BZ 751.
+
+Split out the PM1 Status registers from the FADT. Added new globals for
+these
+registers (A/B), similar to the way the PM1 Enable registers are handled.
+Instead of overloading the FADT Event Register blocks. This makes the
+code
+clearer and less prone to error.
+
+Fixed the warning message for when the platform contains too many ACPI
+tables
+for the default size of the global root table data structure. The
+calculation
+for the truncation value was incorrect.
+
+Removed the ACPI_GET_OBJECT_TYPE macro. Removed all instances of this
+obsolete macro, since it is now a simple reference to ->common.type.
+There
+were about 150 invocations of the macro across 41 files. ACPICA BZ 755.
+
+Removed the redundant ACPI_BITREG_SLEEP_TYPE_B. This type is the same as
+TYPE_A. Removed this and all related instances. Renamed SLEEP_TYPE_A to
+simply SLEEP_TYPE. ACPICA BZ 754.
+
+Conditionally compile the AcpiSetFirmwareWakingVector64 function. This
+function is only needed on 64-bit host operating systems and is thus not
+included for 32-bit hosts.
+
+Debug output: print the input and result for invocations of the _OSI
+reserved
+control method via the ACPI_LV_INFO debug level. Also, reduced some of
+the
+verbosity of this debug level. Len Brown.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 82.3K Code, 17.5K Data, 99.8K Total
+ Debug Version: 157.3K Code, 49.8K Data, 207.1K Total
+ Current Release:
+ Non-Debug Version: 82.0K Code, 17.5K Data, 99.5K Total
+ Debug Version: 156.9K Code, 49.8K Data, 206.7K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Decode the FADT PM_Profile field. Emit ascii names for the
+various legal performance profiles.
+
+----------------------------------------
+23 January 2009. Summary of changes for version 20090123:
+
+1) ACPI CA Core Subsystem:
+
+Added the 2009 copyright to all module headers and signons. This affects
+virtually every file in the ACPICA core subsystem, the iASL compiler, and
+the tools/utilities.
+
+Implemented a change to allow the host to override any ACPI table,
+including
+dynamically loaded tables. Previously, only the DSDT could be replaced by
+the
+host. With this change, the AcpiOsTableOverride interface is called for
+each
+table found in the RSDT/XSDT during ACPICA initialization, and also
+whenever
+a table is dynamically loaded via the AML Load operator.
+
+Updated FADT flag definitions, especially the Boot Architecture flags.
+
+Debugger: For the Find command, automatically pad the input ACPI name
+with
+underscores if the name is shorter than 4 characters. This enables a
+match
+with the actual namespace entry which is itself padded with underscores.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 82.3K Code, 17.4K Data, 99.7K Total
+ Debug Version: 157.1K Code, 49.7K Data, 206.8K Total
+ Current Release:
+ Non-Debug Version: 82.3K Code, 17.5K Data, 99.8K Total
+ Debug Version: 157.3K Code, 49.8K Data, 207.1K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fix build error under Bison-2.4.
+
+Dissasembler: Enhanced FADT support. Added decoding of the Boot
+Architecture
+flags. Now decode all flags, regardless of the FADT version. Flag output
+includes the FADT version which first defined each flag.
+
+The iASL -g option now dumps the RSDT to a file (in addition to the FADT
+and
+DSDT). Windows only.
+
+----------------------------------------
+04 December 2008. Summary of changes for version 20081204:
+
+1) ACPI CA Core Subsystem:
+
+The ACPICA Programmer Reference has been completely updated and revamped
+for
+this release. This includes updates to the external interfaces, OSL
+interfaces, the overview sections, and the debugger reference.
+
+Several new ACPICA interfaces have been implemented and documented in the
+programmer reference:
+AcpiReset - Writes the reset value to the FADT-defined reset register.
+AcpiDisableAllGpes - Disable all available GPEs.
+AcpiEnableAllRuntimeGpes - Enable all available runtime GPEs.
+AcpiGetGpeDevice - Get the GPE block device associated with a GPE.
+AcpiGbl_CurrentGpeCount - Tracks the current number of available GPEs.
+AcpiRead - Low-level read ACPI register (was HwLowLevelRead.)
+AcpiWrite - Low-level write ACPI register (was HwLowLevelWrite.)
+
+Most of the public ACPI hardware-related interfaces have been moved to a
+new
+file, components/hardware/hwxface.c
+
+Enhanced the FADT parsing and low-level ACPI register access: The ACPI
+register lengths within the FADT are now used, and the low level ACPI
+register access no longer hardcodes the ACPI register lengths. Given that
+there may be some risk in actually trusting the FADT register lengths, a
+run-
+time option was added to fall back to the default hardcoded lengths if
+the
+FADT proves to contain incorrect values - UseDefaultRegisterWidths. This
+option is set to true for now, and a warning is issued if a suspicious
+FADT
+register length is overridden with the default value.
+
+Fixed a reference count issue in NsRepairObject. This problem was
+introduced
+in version 20081031 as part of a fix to repair Buffer objects within
+Packages. Lin Ming.
+
+Added semaphore support to the Linux/Unix application OS-services layer
+(OSL). ACPICA BZ 448. Lin Ming.
+
+Added the ACPI_MUTEX_TYPE configuration option to select whether mutexes
+will
+be implemented in the OSL, or will binary semaphores be used instead.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 81.7K Code, 17.3K Data, 99.0K Total
+ Debug Version: 156.4K Code, 49.4K Data, 205.8K Total
+ Current Release:
+ Non-Debug Version: 82.3K Code, 17.4K Data, 99.7K Total
+ Debug Version: 157.1K Code, 49.7K Data, 206.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Completed the '-e' option to include additional ACPI tables in
+order
+to
+aid with disassembly and External statement generation. ACPICA BZ 742.
+Lin
+Ming.
+
+iASL: Removed the "named object in while loop" error. The compiler cannot
+determine how many times a loop will execute. ACPICA BZ 730.
+
+Disassembler: Implemented support for FADT revision 2 (MS extension).
+ACPICA
+BZ 743.
+
+Disassembler: Updates for several ACPI data tables (HEST, EINJ, and
+MCFG).
+
+----------------------------------------
+31 October 2008. Summary of changes for version 20081031:
+
+1) ACPI CA Core Subsystem:
+
+Restructured the ACPICA header files into public/private. acpi.h now
+includes
+only the "public" acpica headers. All other acpica headers are "private"
+and
+should not be included by acpica users. One new file, accommon.h is used
+to
+include the commonly used private headers for acpica code generation.
+Future
+plans include moving all private headers to a new subdirectory.
+
+Implemented an automatic Buffer->String return value conversion for
+predefined ACPI methods. For these methods (such as _BIF), added
+automatic
+conversion for return objects that are required to be a String, but a
+Buffer
+was found instead. This can happen when reading string battery data from
+an
+operation region, because it used to be difficult to convert the data
+from
+buffer to string from within the ASL. Ensures that the host OS is
+provided
+with a valid null-terminated string. Linux BZ 11822.
+
+Updated the FACS waking vector interfaces. Split
+AcpiSetFirmwareWakingVector
+into two: one for the 32-bit vector, another for the 64-bit vector. This
+is
+required because the host OS must setup the wake much differently for
+each
+vector (real vs. protected mode, etc.) and the interface itself should
+not
+be
+deciding which vector to use. Also, eliminated the
+GetFirmwareWakingVector
+interface, as it served no purpose (only the firmware reads the vector,
+OS
+only writes the vector.) ACPICA BZ 731.
+
+Implemented a mechanism to escape infinite AML While() loops. Added a
+loop
+counter to force exit from AML While loops if the count becomes too
+large.
+This can occur in poorly written AML when the hardware does not respond
+within a while loop and the loop does not implement a timeout. The
+maximum
+loop count is configurable. A new exception code is returned when a loop
+is
+broken, AE_AML_INFINITE_LOOP. Alexey Starikovskiy, Bob Moore.
+
+Optimized the execution of AML While loops. Previously, a control state
+object was allocated and freed for each execution of the loop. The
+optimization is to simply reuse the control state for each iteration.
+This
+speeds up the raw loop execution time by about 5%.
+
+Enhanced the implicit return mechanism. For Windows compatibility, return
+an
+implicit integer of value zero for methods that contain no executable
+code.
+Such methods are seen in the field as stubs (presumably), and can cause
+drivers to fail if they expect a return value. Lin Ming.
+
+Allow multiple backslashes as root prefixes in namepaths. In a fully
+qualified namepath, allow multiple backslash prefixes. This can happen
+(and
+is seen in the field) because of the use of a double-backslash in strings
+(since backslash is the escape character) causing confusion. ACPICA BZ
+739
+Lin Ming.
+
+Emit a warning if two different FACS or DSDT tables are discovered in the
+FADT. Checks if there are two valid but different addresses for the FACS
+and
+DSDT within the FADT (mismatch between the 32-bit and 64-bit fields.)
+
+Consolidated the method argument count validation code. Merged the code
+that
+validates control method argument counts into the predefined validation
+module. Eliminates possible multiple warnings for incorrect argument
+counts.
+
+Implemented ACPICA example code. Includes code for ACPICA initialization,
+handler installation, and calling a control method. Available at
+source/tools/examples.
+
+Added a global pointer for FACS table to simplify internal FACS access.
+Use
+the global pointer instead of using AcpiGetTableByIndex for each FACS
+access.
+This simplifies the code for the Global Lock and the Firmware Waking
+Vector(s).
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 81.2K Code, 17.0K Data, 98.2K Total
+ Debug Version: 155.8K Code, 49.1K Data, 204.9K Total
+ Current Release:
+ Non-Debug Version: 81.7K Code, 17.3K Data, 99.0K Total
+ Debug Version: 156.4K Code, 49.4K Data, 205.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Improved disassembly of external method calls. Added the -e option
+to
+allow the inclusion of additional ACPI tables to help with the
+disassembly
+of
+method invocations and the generation of external declarations during the
+disassembly. Certain external method invocations cannot be disassembled
+properly without the actual declaration of the method. Use the -e option
+to
+include the table where the external method(s) are actually declared.
+Most
+useful for disassembling SSDTs that make method calls back to the master
+DSDT. Lin Ming. Example: To disassemble an SSDT with calls to DSDT: iasl
+-d
+-e dsdt.aml ssdt1.aml
+
+iASL: Fix to allow references to aliases within ASL namepaths. Fixes a
+problem where the use of an alias within a namepath would result in a not
+found error or cause the compiler to fault. Also now allows forward
+references from the Alias operator itself. ACPICA BZ 738.
+
+----------------------------------------
+26 September 2008. Summary of changes for version 20080926:
+
+1) ACPI CA Core Subsystem:
+
+Designed and implemented a mechanism to validate predefined ACPI methods
+and
+objects. This code validates the predefined ACPI objects (objects whose
+names
+start with underscore) that appear in the namespace, at the time they are
+evaluated. The argument count and the type of the returned object are
+validated against the ACPI specification. The purpose of this validation
+is
+to detect problems with the BIOS-implemented predefined ACPI objects
+before
+the results are returned to the ACPI-related drivers. Future enhancements
+may
+include actual repair of incorrect return objects where possible. Two new
+files are nspredef.c and acpredef.h.
+
+Fixed a fault in the AML parser if a memory allocation fails during the
+Op
+completion routine AcpiPsCompleteThisOp. Lin Ming. ACPICA BZ 492.
+
+Fixed an issue with implicit return compatibility. This change improves
+the
+implicit return mechanism to be more compatible with the MS interpreter.
+Lin
+Ming, ACPICA BZ 349.
+
+Implemented support for zero-length buffer-to-string conversions. Allow
+zero
+length strings during interpreter buffer-to-string conversions. For
+example,
+during the ToDecimalString and ToHexString operators, as well as implicit
+conversions. Fiodor Suietov, ACPICA BZ 585.
+
+Fixed two possible memory leaks in the error exit paths of
+AcpiUtUpdateObjectReference and AcpiUtWalkPackageTree. These functions
+are
+similar in that they use a stack of state objects in order to eliminate
+recursion. The stack must be fully unwound and deallocated if an error
+occurs. Lin Ming. ACPICA BZ 383.
+
+Removed the unused ACPI_BITREG_WAKE_ENABLE definition and entry in the
+global
+ACPI register table. This bit does not exist and is unused. Lin Ming, Bob
+Moore ACPICA BZ 442.
+
+Removed the obsolete version number in module headers. Removed the
+"$Revision" number that appeared in each module header. This version
+number
+was useful under SourceSafe and CVS, but has no meaning under git. It is
+not
+only incorrect, it could also be misleading.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.7K Code, 16.4K Data, 96.1K Total
+ Debug Version: 153.7K Code, 48.2K Data, 201.9K Total
+ Current Release:
+ Non-Debug Version: 81.2K Code, 17.0K Data, 98.2K Total
+ Debug Version: 155.8K Code, 49.1K Data, 204.9K Total
+
+----------------------------------------
+29 August 2008. Summary of changes for version 20080829:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major cleanup of the internal ACPI_OPERAND_OBJECT of type
+Reference. Changes include the elimination of cheating on the Object
+field
+for the DdbHandle subtype, addition of a reference class field to
+differentiate the various reference types (instead of an AML opcode), and
+the
+cleanup of debug output for this object. Lin Ming, Bob Moore. BZ 723
+
+Reduce an error to a warning for an incorrect method argument count.
+Previously aborted with an error if too few arguments were passed to a
+control method via the external ACPICA interface. Now issue a warning
+instead
+and continue. Handles the case where the method inadvertently declares
+too
+many arguments, but does not actually use the extra ones. Applies mainly
+to
+the predefined methods. Lin Ming. Linux BZ 11032.
+
+Disallow the evaluation of named object types with no intrinsic value.
+Return
+AE_TYPE for objects that have no value and therefore evaluation is
+undefined:
+Device, Event, Mutex, Region, Thermal, and Scope. Previously, evaluation
+of
+these types were allowed, but an exception would be generated at some
+point
+during the evaluation. Now, the error is generated up front.
+
+Fixed a possible memory leak in the AcpiNsGetExternalPathname function
+(nsnames.c). Fixes a leak in the error exit path.
+
+Removed the obsolete debug levels ACPI_DB_WARN and ACPI_DB_ERROR. These
+debug
+levels were made obsolete by the ACPI_WARNING, ACPI_ERROR, and
+ACPI_EXCEPTION
+interfaces. Also added ACPI_DB_EVENTS to correspond with the existing
+ACPI_LV_EVENTS.
+
+Removed obsolete and/or unused exception codes from the acexcep.h header.
+There is the possibility that certain device drivers may be affected if
+they
+use any of these exceptions.
+
+The ACPICA documentation has been added to the public git source tree,
+under
+acpica/documents. Included are the ACPICA programmer reference, the iASL
+compiler reference, and the changes.txt release logfile.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.7K Code, 16.4K Data, 96.1K Total
+ Debug Version: 153.9K Code, 48.4K Data, 202.3K Total
+ Current Release:
+ Non-Debug Version: 79.7K Code, 16.4K Data, 96.1K Total
+ Debug Version: 153.7K Code, 48.2K Data, 201.9K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Allow multiple argument counts for the predefined _SCP method. ACPI 3.0
+defines _SCP with 3 arguments. Previous versions defined it with only 1
+argument. iASL now allows both definitions.
+
+iASL/disassembler: avoid infinite loop on bad ACPI tables. Check for
+zero-
+length subtables when disassembling ACPI tables. Also fixed a couple of
+errors where a full 16-bit table type field was not extracted from the
+input
+properly.
+
+acpisrc: Improve comment counting mechanism for generating source code
+statistics. Count first and last lines of multi-line comments as
+whitespace,
+not comment lines. Handle Linux legal header in addition to standard
+acpica
+header.
+
+----------------------------------------
+
+29 July 2008. Summary of changes for version 20080729:
+
+1) ACPI CA Core Subsystem:
+
+Fix a possible deadlock in the GPE dispatch. Remove call to
+AcpiHwDisableAllGpes during wake in AcpiEvGpeDispatch. This call will
+attempt
+to acquire the GPE lock but can deadlock since the GPE lock is already
+held
+at dispatch time. This code was introduced in version 20060831 as a
+response
+to Linux BZ 6881 and has since been removed from Linux.
+
+Add a function to dereference returned reference objects. Examines the
+return
+object from a call to AcpiEvaluateObject. Any Index or RefOf references
+are
+automatically dereferenced in an attempt to return something useful
+(these
+reference types cannot be converted into an external ACPI_OBJECT.)
+Provides
+MS compatibility. Lin Ming, Bob Moore. Linux BZ 11105
+
+x2APIC support: changes for MADT and SRAT ACPI tables. There are 2 new
+subtables for the MADT and one new subtable for the SRAT. Includes
+disassembler and AcpiSrc support. Data from the Intel 64 Architecture
+x2APIC
+Specification, June 2008.
+
+Additional error checking for pathname utilities. Add error check after
+all
+calls to AcpiNsGetPathnameLength. Add status return from
+AcpiNsBuildExternalPath and check after all calls. Add parameter
+validation
+to AcpiUtInitializeBuffer. Reported by and initial patch by Ingo Molnar.
+
+Return status from the global init function AcpiUtGlobalInitialize. This
+is
+used by both the kernel subsystem and the utilities such as iASL
+compiler.
+The function could possibly fail when the caches are initialized. Yang
+Yi.
+
+Add a function to decode reference object types to strings. Created for
+improved error messages.
+
+Improve object conversion error messages. Better error messages during
+object
+conversion from internal to the external ACPI_OBJECT. Used for external
+calls
+to AcpiEvaluateObject.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.6K Code, 16.2K Data, 95.8K Total
+ Debug Version: 153.5K Code, 48.2K Data, 201.7K Total
+ Current Release:
+ Non-Debug Version: 79.7K Code, 16.4K Data, 96.1K Total
+ Debug Version: 153.9K Code, 48.4K Data, 202.3K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Debugger: fix a possible hang when evaluating non-methods. Fixes a
+problem
+introduced in version 20080701. If the object being evaluated (via
+execute
+command) is not a method, the debugger can hang while trying to obtain
+non-
+existent parameters.
+
+iASL: relax error for using reserved "_T_x" identifiers. These names can
+appear in a disassembled ASL file if they were emitted by the original
+compiler. Instead of issuing an error or warning and forcing the user to
+manually change these names, issue a remark instead.
+
+iASL: error if named object created in while loop. Emit an error if any
+named
+object is created within a While loop. If allowed, this code will
+generate
+a
+run-time error on the second iteration of the loop when an attempt is
+made
+to
+create the same named object twice. ACPICA bugzilla 730.
+
+iASL: Support absolute pathnames for include files. Add support for
+absolute
+pathnames within the Include operator. previously, only relative
+pathnames
+were supported.
+
+iASL: Enforce minimum 1 interrupt in interrupt macro and Resource
+Descriptor.
+The ACPI spec requires one interrupt minimum. BZ 423
+
+iASL: Handle a missing ResourceSource arg, with a present SourceIndex.
+Handles the case for the Interrupt Resource Descriptor where
+the ResourceSource argument is omitted but ResourceSourceIndex
+is present. Now leave room for the Index. BZ 426
+
+iASL: Prevent error message if CondRefOf target does not exist. Fixes
+cases
+where an error message is emitted if the target does not exist. BZ 516
+
+iASL: Fix broken -g option (get Windows ACPI tables). Fixes the -g option
+(get ACPI tables on Windows). This was apparently broken in version
+20070919.
+
+AcpiXtract: Handle EOF while extracting data. Correctly handle the case
+where
+the EOF happens immediately after the last table in the input file. Print
+completion message. Previously, no message was displayed in this case.
+
+----------------------------------------
+01 July 2008. Summary of changes for version 20080701:
+
+0) Git source tree / acpica.org
+
+Fixed a problem where a git-clone from http would not transfer the entire
+source tree.
+
+1) ACPI CA Core Subsystem:
+
+Implemented a "careful" GPE disable in AcpiEvDisableGpe, only modify one
+enable bit. Now performs a read-change-write of the enable register
+instead
+of simply writing out the cached enable mask. This will prevent
+inadvertent
+enabling of GPEs if a rogue GPE is received during initialization (before
+GPE
+handlers are installed.)
+
+Implemented a copy for dynamically loaded tables. Previously, dynamically
+loaded tables were simply mapped - but on some machines this memory is
+corrupted after suspend. Now copy the table to a local buffer. For the
+OpRegion case, added checksum verify. Use the table length from the table
+header, not the region length. For the Buffer case, use the table length
+also. Dennis Noordsij, Bob Moore. BZ 10734
+
+Fixed a problem where the same ACPI table could not be dynamically loaded
+and
+unloaded more than once. Without this change, a table cannot be loaded
+again
+once it has been loaded/unloaded one time. The current mechanism does not
+unregister a table upon an unload. During a load, if the same table is
+found,
+this no longer returns an exception. BZ 722
+
+Fixed a problem where the wrong descriptor length was calculated for the
+EndTag descriptor in 64-bit mode. The "minimal" descriptors such as
+EndTag
+are calculated as 12 bytes long, but the actual length in the internal
+descriptor is 16 because of the round-up to 8 on the 64-bit build.
+Reported
+by Linn Crosetto. BZ 728
+
+Fixed a possible memory leak in the Unload operator. The DdbHandle
+returned
+by Load() did not have its reference count decremented during unload,
+leading
+to a memory leak. Lin Ming. BZ 727
+
+Fixed a possible memory leak when deleting thermal/processor objects. Any
+associated notify handlers (and objects) were not being deleted. Fiodor
+Suietov. BZ 506
+
+Fixed the ordering of the ASCII names in the global mutex table to match
+the
+actual mutex IDs. Used by AcpiUtGetMutexName, a function used for debug
+only.
+Vegard Nossum. BZ 726
+
+Enhanced the AcpiGetObjectInfo interface to return the number of required
+arguments if the object is a control method. Added this call to the
+debugger
+so the proper number of default arguments are passed to a method. This
+prevents a warning when executing methods from AcpiExec.
+
+Added a check for an invalid handle in AcpiGetObjectInfo. Return
+AE_BAD_PARAMETER if input handle is invalid. BZ 474
+
+Fixed an extraneous warning from exconfig.c on the 64-bit build.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.3K Code, 16.2K Data, 95.5K Total
+ Debug Version: 153.0K Code, 48.2K Data, 201.2K Total
+ Current Release:
+ Non-Debug Version: 79.6K Code, 16.2K Data, 95.8K Total
+ Debug Version: 153.5K Code, 48.2K Data, 201.7K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added two missing ACPI reserved names. Added _MTP and _ASZ, both
+resource descriptor names.
+
+iASL: Detect invalid ASCII characters in input (windows version). Removed
+the
+"-CF" flag from the flex compile, enables correct detection of non-ASCII
+characters in the input. BZ 441
+
+iASL: Eliminate warning when result of LoadTable is not used. Eliminate
+the
+"result of operation not used" warning when the DDB handle returned from
+LoadTable is not used. The warning is not needed. BZ 590
+
+AcpiExec: Add support for dynamic table load/unload. Now calls _CFG
+method
+to
+pass address of table to the AML. Added option to disable OpRegion
+simulation
+to allow creation of an OpRegion with a real address that was passed to
+_CFG.
+All of this allows testing of the Load and Unload operators from
+AcpiExec.
+
+Debugger: update tables command for unloaded tables. Handle unloaded
+tables
+and use the standard table header output routine.
+
+----------------------------------------
+09 June 2008. Summary of changes for version 20080609:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a workaround for reversed _PRT entries. A significant number
+of
+BIOSs erroneously reverse the _PRT SourceName and the SourceIndex. This
+change dynamically detects and repairs this problem. Provides
+compatibility
+with MS ACPI. BZ 6859
+
+Simplified the internal ACPI hardware interfaces to eliminate the locking
+flag parameter from Register Read/Write. Added a new external interface,
+AcpiGetRegisterUnlocked.
+
+Fixed a problem where the invocation of a GPE control method could hang.
+This
+was a regression introduced in 20080514. The new method argument count
+validation mechanism can enter an infinite loop when a GPE method is
+dispatched. Problem fixed by removing the obsolete code that passed GPE
+block
+information to the notify handler via the control method parameter
+pointer.
+
+Fixed a problem where the _SST execution status was incorrectly returned
+to
+the caller of AcpiEnterSleepStatePrep. This was a regression introduced
+in
+20080514. _SST is optional and a NOT_FOUND exception should never be
+returned. BZ 716
+
+Fixed a problem where a deleted object could be accessed from within the
+AML
+parser. This was a regression introduced in version 20080123 as a fix for
+the
+Unload operator. Lin Ming. BZ 10669
+
+Cleaned up the debug operand dump mechanism. Eliminated unnecessary
+operands
+and eliminated the use of a negative index in a loop. Operands are now
+displayed in the correct order, not backwards. This also fixes a
+regression
+introduced in 20080514 on 64-bit systems where the elimination of
+ACPI_NATIVE_UINT caused the negative index to go large and positive. BZ
+715
+
+Fixed a possible memory leak in EvPciConfigRegionSetup where the error
+exit
+path did not delete a locally allocated structure.
+
+Updated definitions for the DMAR and SRAT tables to synchronize with the
+current specifications. Includes disassembler support.
+
+Fixed a problem in the mutex debug code (in utmutex.c) where an incorrect
+loop termination value was used. Loop terminated on iteration early,
+missing
+one mutex. Linn Crosetto
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.5K Code, 16.2K Data, 95.7K Total
+ Debug Version: 153.3K Code, 48.3K Data, 201.6K Total
+ Current Release:
+ Non-Debug Version: 79.3K Code, 16.2K Data, 95.5K Total
+ Debug Version: 153.0K Code, 48.2K Data, 201.2K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Implemented support for EisaId() within _CID objects. Now
+disassemble integer _CID objects back to EisaId invocations, including
+multiple integers within _CID packages. Includes single-step support for
+debugger also.
+
+Disassembler: Added support for DMAR and SRAT table definition changes.
+
+----------------------------------------
+14 May 2008. Summary of changes for version 20080514:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where GPEs were enabled too early during the ACPICA
+initialization. This could lead to "handler not installed" errors on some
+machines. Moved GPE enable until after _REG/_STA/_INI methods are run.
+This
+ensures that all operation regions and devices throughout the namespace
+have
+been initialized before GPEs are enabled. Alexey Starikovskiy, BZ 9916.
+
+Implemented a change to the enter sleep code. Moved execution of the _GTS
+method to just before setting sleep enable bit. The execution was moved
+from
+AcpiEnterSleepStatePrep to AcpiEnterSleepState. _GTS is now executed
+immediately before the SLP_EN bit is set, as per the ACPI specification.
+Luming Yu, BZ 1653.
+
+Implemented a fix to disable unknown GPEs (2nd version). Now always
+disable
+the GPE, even if ACPICA thinks that that it is already disabled. It is
+possible that the AML or some other code has enabled the GPE unbeknownst
+to
+the ACPICA code.
+
+Fixed a problem with the Field operator where zero-length fields would
+return
+an AE_AML_NO_OPERAND exception during table load. Fix enables zero-length
+ASL
+field declarations in Field(), BankField(), and IndexField(). BZ 10606.
+
+Implemented a fix for the Load operator, now load the table at the
+namespace
+root. This reverts a change introduced in version 20071019. The table is
+now
+loaded at the namespace root even though this goes against the ACPI
+specification. This provides compatibility with other ACPI
+implementations.
+The ACPI specification will be updated to reflect this in ACPI 4.0. Lin
+Ming.
+
+Fixed a problem where ACPICA would not Load() tables with unusual
+signatures.
+Now ignore ACPI table signature for Load() operator. Only "SSDT" is
+acceptable to the ACPI spec, but tables are seen with OEMx and null sigs.
+Therefore, signature validation is worthless. Apparently MS ACPI accepts
+such
+signatures, ACPICA must be compatible. BZ 10454.
+
+Fixed a possible negative array index in AcpiUtValidateException. Added
+NULL
+fields to the exception string arrays to eliminate a -1 subtraction on
+the
+SubStatus field.
+
+Updated the debug tracking macros to reduce overall code and data size.
+Changed ACPI_MODULE_NAME and ACPI_FUNCTION_NAME to use arrays of strings
+instead of pointers to static strings. Jan Beulich and Bob Moore.
+
+Implemented argument count checking in control method invocation via
+AcpiEvaluateObject. Now emit an error if too few arguments, warning if
+too
+many. This applies only to extern programmatic control method execution,
+not
+method-to-method calls within the AML. Lin Ming.
+
+Eliminated the ACPI_NATIVE_UINT type across all ACPICA code. This type is
+no
+longer needed, especially with the removal of 16-bit support. It was
+replaced
+mostly with UINT32, but also ACPI_SIZE where a type that changes 32/64
+bit
+on
+32/64-bit platforms is required.
+
+Added the C const qualifier for appropriate string constants -- mostly
+MODULE_NAME and printf format strings. Jan Beulich.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.0K Code, 17.4K Data, 97.4K Total
+ Debug Version: 159.4K Code, 64.4K Data, 223.8K Total
+ Current Release:
+ Non-Debug Version: 79.5K Code, 16.2K Data, 95.7K Total
+ Debug Version: 153.3K Code, 48.3K Data, 201.6K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented ACPI table revision ID validation in the disassembler. Zero
+is
+always invalid. For DSDTs, the ID controls the interpreter integer width.
+1
+means 32-bit and this is unusual. 2 or greater is 64-bit.
+
+----------------------------------------
+21 March 2008. Summary of changes for version 20080321:
+
+1) ACPI CA Core Subsystem:
+
+Implemented an additional change to the GPE support in order to suppress
+spurious or stray GPEs. The AcpiEvDisableGpe function will now
+permanently
+disable incoming GPEs that are neither enabled nor disabled -- meaning
+that
+the GPE is unknown to the system. This should prevent future interrupt
+floods
+from that GPE. BZ 6217 (Zhang Rui)
+
+Fixed a problem where NULL package elements were not returned to the
+AcpiEvaluateObject interface correctly. The element was simply ignored
+instead of returning a NULL ACPI_OBJECT package element, potentially
+causing
+a buffer overflow and/or confusing the caller who expected a fixed number
+of
+elements. BZ 10132 (Lin Ming, Bob Moore)
+
+Fixed a problem with the CreateField, CreateXXXField (Bit, Byte, Word,
+Dword,
+Qword), Field, BankField, and IndexField operators when invoked from
+inside
+an executing control method. In this case, these operators created
+namespace
+nodes that were incorrectly left marked as permanent nodes instead of
+temporary nodes. This could cause a problem if there is race condition
+between an exiting control method and a running namespace walk. (Reported
+by
+Linn Crosetto)
+
+Fixed a problem where the CreateField and CreateXXXField operators would
+incorrectly allow duplicate names (the name of the field) with no
+exception
+generated.
+
+Implemented several changes for Notify handling. Added support for new
+Notify
+values (ACPI 2.0+) and improved the Notify debug output. Notify on
+PowerResource objects is no longer allowed, as per the ACPI
+specification.
+(Bob Moore, Zhang Rui)
+
+All Reference Objects returned via the AcpiEvaluateObject interface are
+now
+marked as type "REFERENCE" instead of "ANY". The type ANY is now reserved
+for
+NULL objects - either NULL package elements or unresolved named
+references.
+
+Fixed a problem where an extraneous debug message was produced for
+package
+objects (when debugging enabled). The message "Package List length larger
+than NumElements count" is now produced in the correct case, and is now
+an
+error message rather than a debug message. Added a debug message for the
+opposite case, where NumElements is larger than the Package List (the
+package
+will be padded out with NULL elements as per the ACPI spec.)
+
+Implemented several improvements for the output of the ASL "Debug" object
+to
+clarify and keep all data for a given object on one output line.
+
+Fixed two size calculation issues with the variable-length Start
+Dependent
+resource descriptor.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.7K Code, 17.3K Data, 97.0K Total
+ Debug Version: 158.9K Code, 64.0K Data, 222.9K Total
+ Current Release:
+ Non-Debug Version: 80.0K Code, 17.4K Data, 97.4K Total
+ Debug Version: 159.4K Code, 64.4K Data, 223.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed a problem with the use of the Switch operator where execution of
+the
+containing method by multiple concurrent threads could cause an
+AE_ALREADY_EXISTS exception. This is caused by the fact that there is no
+actual Switch opcode, it must be simulated with local named temporary
+variables and if/else pairs. The solution chosen was to mark any method
+that
+uses Switch as Serialized, thus preventing multiple thread entries. BZ
+469.
+
+----------------------------------------
+13 February 2008. Summary of changes for version 20080213:
+
+1) ACPI CA Core Subsystem:
+
+Implemented another MS compatibility design change for GPE/Notify
+handling.
+GPEs are now cleared/enabled asynchronously to allow all pending notifies
+to
+complete first. It is expected that the OSL will queue the enable request
+behind all pending notify requests (may require changes to the local host
+OSL
+in AcpiOsExecute). Alexey Starikovskiy.
+
+Fixed a problem where buffer and package objects passed as arguments to a
+control method via the external AcpiEvaluateObject interface could cause
+an
+AE_AML_INTERNAL exception depending on the order and type of operators
+executed by the target control method.
+
+Fixed a problem where resource descriptor size optimization could cause a
+problem when a _CRS resource template is passed to a _SRS method. The
+_SRS
+resource template must use the same descriptors (with the same size) as
+returned from _CRS. This change affects the following resource
+descriptors:
+IRQ / IRQNoFlags and StartDependendentFn / StartDependentFnNoPri. (BZ
+9487)
+
+Fixed a problem where a CopyObject to RegionField, BankField, and
+IndexField
+objects did not perform an implicit conversion as it should. These types
+must
+retain their initial type permanently as per the ACPI specification.
+However,
+a CopyObject to all other object types should not perform an implicit
+conversion, as per the ACPI specification. (Lin Ming, Bob Moore) BZ 388
+
+Fixed a problem with the AcpiGetDevices interface where the mechanism to
+match device CIDs did not examine the entire list of available CIDs, but
+instead aborted on the first non-matching CID. Andrew Patterson.
+
+Fixed a regression introduced in version 20071114. The ACPI_HIDWORD macro
+was
+inadvertently changed to return a 16-bit value instead of a 32-bit value,
+truncating the upper dword of a 64-bit value. This macro is only used to
+display debug output, so no incorrect calculations were made. Also,
+reimplemented the macro so that a 64-bit shift is not performed by
+inefficient compilers.
+
+Added missing va_end statements that should correspond with each va_start
+statement.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.5K Code, 17.2K Data, 96.7K Total
+ Debug Version: 159.0K Code, 63.8K Data, 222.8K Total
+ Current Release:
+ Non-Debug Version: 79.7K Code, 17.3K Data, 97.0K Total
+ Debug Version: 158.9K Code, 64.0K Data, 222.9K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented full disassembler support for the following new ACPI tables:
+BERT, EINJ, and ERST. Implemented partial disassembler support for the
+complicated HEST table. These tables support the Windows Hardware Error
+Architecture (WHEA).
+
+----------------------------------------
+23 January 2008. Summary of changes for version 20080123:
+
+1) ACPI CA Core Subsystem:
+
+Added the 2008 copyright to all module headers and signons. This affects
+virtually every file in the ACPICA core subsystem, the iASL compiler, and
+the tools/utilities.
+
+Fixed a problem with the SizeOf operator when used with Package and
+Buffer
+objects. These objects have deferred execution for some arguments, and
+the
+execution is now completed before the SizeOf is executed. This problem
+caused
+unexpected AE_PACKAGE_LIMIT errors on some systems (Lin Ming, Bob Moore)
+BZ
+9558
+
+Implemented an enhancement to the interpreter "slack mode". In the
+absence
+of
+an explicit return or an implicitly returned object from the last
+executed
+opcode, a control method will now implicitly return an integer of value 0
+for
+Microsoft compatibility. (Lin Ming) BZ 392
+
+Fixed a problem with the Load operator where an exception was not
+returned
+in
+the case where the table is already loaded. (Lin Ming) BZ 463
+
+Implemented support for the use of DDBHandles as an Indexed Reference, as
+per
+the ACPI spec. (Lin Ming) BZ 486
+
+Implemented support for UserTerm (Method invocation) for the Unload
+operator
+as per the ACPI spec. (Lin Ming) BZ 580
+
+Fixed a problem with the LoadTable operator where the OemId and
+OemTableId
+input strings could cause unexpected failures if they were shorter than
+the
+maximum lengths allowed. (Lin Ming, Bob Moore) BZ 576
+
+Implemented support for UserTerm (Method invocation) for the Unload
+operator
+as per the ACPI spec. (Lin Ming) BZ 580
+
+Implemented header file support for new ACPI tables - BERT, ERST, EINJ,
+HEST,
+IBFT, UEFI, WDAT. Disassembler support is forthcoming.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.3K Code, 17.2K Data, 96.5K Total
+ Debug Version: 158.6K Code, 63.8K Data, 222.4K Total
+ Current Release:
+ Non-Debug Version: 79.5K Code, 17.2K Data, 96.7K Total
+ Debug Version: 159.0K Code, 63.8K Data, 222.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented support in the disassembler for checksum validation on
+incoming
+binary DSDTs and SSDTs. If incorrect, a message is displayed within the
+table
+header dump at the start of the disassembly.
+
+Implemented additional debugging information in the namespace listing
+file
+created during compilation. In addition to the namespace hierarchy, the
+full
+pathname to each namespace object is displayed.
+
+Fixed a problem with the disassembler where invalid ACPI tables could
+cause
+faults or infinite loops.
+
+Fixed an unexpected parse error when using the optional "parameter types"
+list in a control method declaration. (Lin Ming) BZ 397
+
+Fixed a problem where two External declarations with the same name did
+not
+cause an error (Lin Ming) BZ 509
+
+Implemented support for full TermArgs (adding Argx, Localx and method
+invocation) for the ParameterData parameter to the LoadTable operator.
+(Lin
+Ming) BZ 583,587
+
+----------------------------------------
+19 December 2007. Summary of changes for version 20071219:
+
+1) ACPI CA Core Subsystem:
+
+Implemented full support for deferred execution for the TermArg string
+arguments for DataTableRegion. This enables forward references and full
+operand resolution for the three string arguments. Similar to
+OperationRegion
+deferred argument execution.) Lin Ming. BZ 430
+
+Implemented full argument resolution support for the BankValue argument
+to
+BankField. Previously, only constants were supported, now any TermArg may
+be
+used. Lin Ming BZ 387, 393
+
+Fixed a problem with AcpiGetDevices where the search of a branch of the
+device tree could be terminated prematurely. In accordance with the ACPI
+specification, the search down the current branch is terminated if a
+device
+is both not present and not functional (instead of just not present.)
+Yakui
+Zhao.
+
+Fixed a problem where "unknown" GPEs could be allowed to fire repeatedly
+if
+the underlying AML code changed the GPE enable registers. Now, any
+unknown
+incoming GPE (no _Lxx/_Exx method and not the EC GPE) is immediately
+disabled
+instead of simply ignored. Rui Zhang.
+
+Fixed a problem with Index Fields where the Index register was
+incorrectly
+limited to a maximum of 32 bits. Now any size may be used.
+
+Fixed a couple memory leaks associated with "implicit return" objects
+when
+the AML Interpreter slack mode is enabled. Lin Ming BZ 349
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.0K Code, 17.2K Data, 96.2K Total
+ Debug Version: 157.9K Code, 63.6K Data, 221.5K Total
+ Current Release:
+ Non-Debug Version: 79.3K Code, 17.2K Data, 96.5K Total
+ Debug Version: 158.6K Code, 63.8K Data, 222.4K Total
+
+----------------------------------------
+14 November 2007. Summary of changes for version 20071114:
+
+1) ACPI CA Core Subsystem:
+
+Implemented event counters for each of the Fixed Events, the ACPI SCI
+(interrupt) itself, and control methods executed. Named
+AcpiFixedEventCount[], AcpiSciCount, and AcpiMethodCount respectively.
+These
+should be useful for debugging and statistics.
+
+Implemented a new external interface, AcpiGetStatistics, to retrieve the
+contents of the various event counters. Returns the current values for
+AcpiSciCount, AcpiGpeCount, the AcpiFixedEventCount array, and
+AcpiMethodCount. The interface can be expanded in the future if new
+counters
+are added. Device drivers should use this interface rather than access
+the
+counters directly.
+
+Fixed a problem with the FromBCD and ToBCD operators. With some
+compilers,
+the ShortDivide function worked incorrectly, causing problems with the
+BCD
+functions with large input values. A truncation from 64-bit to 32-bit
+inadvertently occurred. Internal BZ 435. Lin Ming
+
+Fixed a problem with Index references passed as method arguments.
+References
+passed as arguments to control methods were dereferenced immediately
+(before
+control was passed to the called method). The references are now
+correctly
+passed directly to the called method. BZ 5389. Lin Ming
+
+Fixed a problem with CopyObject used in conjunction with the Index
+operator.
+The reference was incorrectly dereferenced before the copy. The reference
+is
+now correctly copied. BZ 5391. Lin Ming
+
+Fixed a problem with Control Method references within Package objects.
+These
+references are now correctly generated. This completes the package
+construction overhaul that began in version 20071019.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.8K Code, 17.2K Data, 96.0K Total
+ Debug Version: 157.2K Code, 63.4K Data, 220.6K Total
+ Current Release:
+ Non-Debug Version: 79.0K Code, 17.2K Data, 96.2K Total
+ Debug Version: 157.9K Code, 63.6K Data, 221.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+The AcpiExec utility now installs handlers for all of the predefined
+Operation Region types. New types supported are: PCI_Config, CMOS, and
+PCIBARTarget.
+
+Fixed a problem with the 64-bit version of AcpiExec where the extended
+(64-
+bit) address fields for the DSDT and FACS within the FADT were not being
+used, causing truncation of the upper 32-bits of these addresses. Lin
+Ming
+and Bob Moore
+
+----------------------------------------
+19 October 2007. Summary of changes for version 20071019:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem with the Alias operator when the target of the alias is a
+named ASL operator that opens a new scope -- Scope, Device,
+PowerResource,
+Processor, and ThermalZone. In these cases, any children of the original
+operator could not be accessed via the alias, potentially causing
+unexpected
+AE_NOT_FOUND exceptions. (BZ 9067)
+
+Fixed a problem with the Package operator where all named references were
+created as object references and left otherwise unresolved. According to
+the
+ACPI specification, a Package can only contain Data Objects or references
+to
+control methods. The implication is that named references to Data Objects
+(Integer, Buffer, String, Package, BufferField, Field) should be resolved
+immediately upon package creation. This is the approach taken with this
+change. References to all other named objects (Methods, Devices, Scopes,
+etc.) are all now properly created as reference objects. (BZ 5328)
+
+Reverted a change to Notify handling that was introduced in version
+20070508. This version changed the Notify handling from asynchronous to
+fully synchronous (Device driver Notify handling with respect to the
+Notify
+ASL operator). It was found that this change caused more problems than it
+solved and was removed by most users.
+
+Fixed a problem with the Increment and Decrement operators where the type
+of
+the target object could be unexpectedly and incorrectly changed. (BZ 353)
+Lin Ming.
+
+Fixed a problem with the Load and LoadTable operators where the table
+location within the namespace was ignored. Instead, the table was always
+loaded into the root or current scope. Lin Ming.
+
+Fixed a problem with the Load operator when loading a table from a buffer
+object. The input buffer was prematurely zeroed and/or deleted. (BZ 577)
+
+Fixed a problem with the Debug object where a store of a DdbHandle
+reference
+object to the Debug object could cause a fault.
+
+Added a table checksum verification for the Load operator, in the case
+where
+the load is from a buffer. (BZ 578).
+
+Implemented additional parameter validation for the LoadTable operator.
+The
+length of the input strings SignatureString, OemIdString, and OemTableId
+are
+now checked for maximum lengths. (BZ 582) Lin Ming.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.5K Code, 17.1K Data, 95.6K Total
+ Debug Version: 156.7K Code, 63.2K Data, 219.9K Total
+ Current Release:
+ Non-Debug Version: 78.8K Code, 17.2K Data, 96.0K Total
+ Debug Version: 157.2K Code, 63.4K Data, 220.6K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem where if a single file was specified and the file did not
+exist, no error message was emitted. (Introduced with wildcard support in
+version 20070917.)
+
+----------------------------------------
+19 September 2007. Summary of changes for version 20070919:
+
+1) ACPI CA Core Subsystem:
+
+Designed and implemented new external interfaces to install and remove
+handlers for ACPI table-related events. Current events that are defined
+are
+LOAD and UNLOAD. These interfaces allow the host to track ACPI tables as
+they are dynamically loaded and unloaded. See AcpiInstallTableHandler and
+AcpiRemoveTableHandler. (Lin Ming and Bob Moore)
+
+Fixed a problem where the use of the AcpiGbl_AllMethodsSerialized flag
+(acpi_serialized option on Linux) could cause some systems to hang during
+initialization. (Bob Moore) BZ 8171
+
+Fixed a problem where objects of certain types (Device, ThermalZone,
+Processor, PowerResource) can be not found if they are declared and
+referenced from within the same control method (Lin Ming) BZ 341
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 17.0K Data, 95.3K Total
+ Debug Version: 156.3K Code, 63.1K Data, 219.4K Total
+ Current Release:
+ Non-Debug Version: 78.5K Code, 17.1K Data, 95.6K Total
+ Debug Version: 156.7K Code, 63.2K Data, 219.9K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support to allow multiple files to be compiled/disassembled
+in
+a
+single invocation. This includes command line wildcard support for both
+the
+Windows and Unix versions of the compiler. This feature simplifies the
+disassembly and compilation of multiple ACPI tables in a single
+directory.
+
+----------------------------------------
+08 May 2007. Summary of changes for version 20070508:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a Microsoft compatibility design change for the handling of
+the
+Notify AML operator. Previously, notify handlers were dispatched and
+executed completely asynchronously in a deferred thread. The new design
+still executes the notify handlers in a different thread, but the
+original
+thread that executed the Notify() now waits at a synchronization point
+for
+the notify handler to complete. Some machines depend on a synchronous
+Notify
+operator in order to operate correctly.
+
+Implemented support to allow Package objects to be passed as method
+arguments to the external AcpiEvaluateObject interface. Previously, this
+would return the AE_NOT_IMPLEMENTED exception. This feature had not been
+implemented since there were no reserved control methods that required it
+until recently.
+
+Fixed a problem with the internal FADT conversion where ACPI 1.0 FADTs
+that
+contained invalid non-zero values in reserved fields could cause later
+failures because these fields have meaning in later revisions of the
+FADT.
+For incoming ACPI 1.0 FADTs, these fields are now always zeroed. (The
+fields
+are: Preferred_PM_Profile, PSTATE_CNT, CST_CNT, and IAPC_BOOT_FLAGS.)
+
+Fixed a problem where the Global Lock handle was not properly updated if
+a
+thread that acquired the Global Lock via executing AML code then
+attempted
+to acquire the lock via the AcpiAcquireGlobalLock interface. Reported by
+Joe
+Liu.
+
+Fixed a problem in AcpiEvDeleteGpeXrupt where the global interrupt list
+could be corrupted if the interrupt being removed was at the head of the
+list. Reported by Linn Crosetto.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.9K Code, 63.1K Data, 219.0K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 17.0K Data, 95.3K Total
+ Debug Version: 156.3K Code, 63.1K Data, 219.4K Total
+
+----------------------------------------
+20 March 2007. Summary of changes for version 20070320:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a change to the order of interpretation and evaluation of AML
+operand objects within the AML interpreter. The interpreter now evaluates
+operands in the order that they appear in the AML stream (and the
+corresponding ASL code), instead of in the reverse order (after the
+entire
+operand list has been parsed). The previous behavior caused several
+subtle
+incompatibilities with the Microsoft AML interpreter as well as being
+somewhat non-intuitive. BZ 7871, local BZ 263. Valery Podrezov.
+
+Implemented a change to the ACPI Global Lock support. All interfaces to
+the
+global lock now allow the same thread to acquire the lock multiple times.
+This affects the AcpiAcquireGlobalLock external interface to the global
+lock
+as well as the internal use of the global lock to support AML fields -- a
+control method that is holding the global lock can now simultaneously
+access
+AML fields that require global lock protection. Previously, in both
+cases,
+this would have resulted in an AE_ALREADY_ACQUIRED exception. The change
+to
+AcpiAcquireGlobalLock is of special interest to drivers for the Embedded
+Controller. There is no change to the behavior of the AML Acquire
+operator,
+as this can already be used to acquire a mutex multiple times by the same
+thread. BZ 8066. With assistance from Alexey Starikovskiy.
+
+Fixed a problem where invalid objects could be referenced in the AML
+Interpreter after error conditions. During operand evaluation, ensure
+that
+the internal "Return Object" field is cleared on error and only valid
+pointers are stored there. Caused occasional access to deleted objects
+that
+resulted in "large reference count" warning messages. Valery Podrezov.
+
+Fixed a problem where an AE_STACK_OVERFLOW internal exception could occur
+on
+deeply nested control method invocations. BZ 7873, local BZ 487. Valery
+Podrezov.
+
+Fixed an internal problem with the handling of result objects on the
+interpreter result stack. BZ 7872. Valery Podrezov.
+
+Removed obsolete code that handled the case where AML_NAME_OP is the
+target
+of a reference (Reference.Opcode). This code was no longer necessary. BZ
+7874. Valery Podrezov.
+
+Removed obsolete ACPI_NO_INTEGER64_SUPPORT from two header files. This
+was
+a
+remnant from the previously discontinued 16-bit support.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.8K Code, 63.3K Data, 219.1K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.9K Code, 63.1K Data, 219.0K Total
+
+----------------------------------------
+26 January 2007. Summary of changes for version 20070126:
+
+1) ACPI CA Core Subsystem:
+
+Added the 2007 copyright to all module headers and signons. This affects
+virtually every file in the ACPICA core subsystem, the iASL compiler, and
+the utilities.
+
+Implemented a fix for an incorrect parameter passed to AcpiTbDeleteTable
+during a table load. A bad pointer was passed in the case where the DSDT
+is
+overridden, causing a fault in this case.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.8K Code, 63.3K Data, 219.1K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.8K Code, 63.3K Data, 219.1K Total
+
+----------------------------------------
+15 December 2006. Summary of changes for version 20061215:
+
+1) ACPI CA Core Subsystem:
+
+Support for 16-bit ACPICA has been completely removed since it is no
+longer
+necessary and it clutters the code. All 16-bit macros, types, and
+conditional compiles have been removed, cleaning up and simplifying the
+code
+across the entire subsystem. DOS support is no longer needed since the
+bootable Linux firmware kit is now available.
+
+The handler for the Global Lock is now removed during AcpiTerminate to
+enable a clean subsystem restart, via the implementation of the
+AcpiEvRemoveGlobalLockHandler function. (With assistance from Joel Bretz,
+HP)
+
+Implemented enhancements to the multithreading support within the
+debugger
+to enable improved multithreading debugging and evaluation of the
+subsystem.
+(Valery Podrezov)
+
+Debugger: Enhanced the Statistics/Memory command to emit the total
+(maximum)
+memory used during the execution, as well as the maximum memory consumed
+by
+each of the various object types. (Valery Podrezov)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 17.0K Data, 94.9K Total
+ Debug Version: 155.2K Code, 63.1K Data, 218.3K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 17.1K Data, 95.1K Total
+ Debug Version: 155.8K Code, 63.3K Data, 219.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiExec: Implemented a new option (-m) to display full memory use
+statistics upon subsystem/program termination. (Valery Podrezov)
+
+----------------------------------------
+09 November 2006. Summary of changes for version 20061109:
+
+1) ACPI CA Core Subsystem:
+
+Optimized the Load ASL operator in the case where the source operand is
+an
+operation region. Simply map the operation region memory, instead of
+performing a bytewise read. (Region must be of type SystemMemory, see
+below.)
+
+Fixed the Load ASL operator for the case where the source operand is a
+region field. A buffer object is also allowed as the source operand. BZ
+480
+
+Fixed a problem where the Load ASL operator allowed the source operand to
+be
+an operation region of any type. It is now restricted to regions of type
+SystemMemory, as per the ACPI specification. BZ 481
+
+Additional cleanup and optimizations for the new Table Manager code.
+
+AcpiEnable will now fail if all of the required ACPI tables are not
+loaded
+(FADT, FACS, DSDT). BZ 477
+
+Added #pragma pack(8/4) to acobject.h to ensure that the structures in
+this
+header are always compiled as aligned. The ACPI_OPERAND_OBJECT has been
+manually optimized to be aligned and will not work if it is byte-packed.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 78.1K Code, 17.1K Data, 95.2K Total
+ Debug Version: 155.4K Code, 63.1K Data, 218.5K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 17.0K Data, 94.9K Total
+ Debug Version: 155.2K Code, 63.1K Data, 218.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed a problem where the presence of the _OSI predefined control method
+within complex expressions could cause an internal compiler error.
+
+AcpiExec: Implemented full region support for multiple address spaces.
+SpaceId is now part of the REGION object. BZ 429
+
+----------------------------------------
+11 October 2006. Summary of changes for version 20061011:
+
+1) ACPI CA Core Subsystem:
+
+Completed an AML interpreter performance enhancement for control method
+execution. Previously a 2-pass parse/execution, control methods are now
+completely parsed and executed in a single pass. This improves overall
+interpreter performance by ~25%, reduces code size, and reduces CPU stack
+use. (Valery Podrezov + interpreter changes in version 20051202 that
+eliminated namespace loading during the pass one parse.)
+
+Implemented _CID support for PCI Root Bridge detection. If the _HID does
+not
+match the predefined PCI Root Bridge IDs, the _CID list (if present) is
+now
+obtained and also checked for an ID match.
+
+Implemented additional support for the PCI _ADR execution: upsearch until
+a
+device scope is found before executing _ADR. This allows PCI_Config
+operation regions to be declared locally within control methods
+underneath
+PCI device objects.
+
+Fixed a problem with a possible race condition between threads executing
+AcpiWalkNamespace and the AML interpreter. This condition was removed by
+modifying AcpiWalkNamespace to (by default) ignore all temporary
+namespace
+entries created during any concurrent control method execution. An
+additional namespace race condition is known to exist between
+AcpiWalkNamespace and the Load/Unload ASL operators and is still under
+investigation.
+
+Restructured the AML ParseLoop function, breaking it into several
+subfunctions in order to reduce CPU stack use and improve
+maintainability.
+(Mikhail Kouzmich)
+
+AcpiGetHandle: Fix for parameter validation to detect invalid
+combinations
+of prefix handle and pathname. BZ 478
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 17.1K Data, 95.0K Total
+ Debug Version: 154.6K Code, 63.0K Data, 217.6K Total
+ Current Release:
+ Non-Debug Version: 78.1K Code, 17.1K Data, 95.2K Total
+ Debug Version: 155.4K Code, 63.1K Data, 218.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+Ported the -g option (get local ACPI tables) to the new ACPICA Table
+Manager
+to restore original behavior.
+
+----------------------------------------
+27 September 2006. Summary of changes for version 20060927:
+
+1) ACPI CA Core Subsystem:
+
+Removed the "Flags" parameter from AcpiGetRegister and AcpiSetRegister.
+These functions now use a spinlock for mutual exclusion and the interrupt
+level indication flag is not needed.
+
+Fixed a problem with the Global Lock where the lock could appear to be
+obtained before it is actually obtained. The global lock semaphore was
+inadvertently created with one unit instead of zero units. (BZ 464)
+Fiodor
+Suietov.
+
+Fixed a possible memory leak and fault in AcpiExResolveObjectToValue
+during
+a read from a buffer or region field. (BZ 458) Fiodor Suietov.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 17.1K Data, 95.0K Total
+ Debug Version: 154.7K Code, 63.0K Data, 217.7K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 17.1K Data, 95.0K Total
+ Debug Version: 154.6K Code, 63.0K Data, 217.6K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed a compilation problem with the pre-defined Resource Descriptor
+field
+names where an "object does not exist" error could be incorrectly
+generated
+if the parent ResourceTemplate pathname places the template within a
+different namespace scope than the current scope. (BZ 7212)
+
+Fixed a problem where the compiler could hang after syntax errors
+detected
+in an ElseIf construct. (BZ 453)
+
+Fixed a problem with the AmlFilename parameter to the DefinitionBlock()
+operator. An incorrect output filename was produced when this parameter
+was
+a null string (""). Now, the original input filename is used as the AML
+output filename, with an ".aml" extension.
+
+Implemented a generic batch command mode for the AcpiExec utility
+(execute
+any AML debugger command) (Valery Podrezov).
+
+----------------------------------------
+12 September 2006. Summary of changes for version 20060912:
+
+1) ACPI CA Core Subsystem:
+
+Enhanced the implementation of the "serialized mode" of the interpreter
+(enabled via the AcpiGbl_AllMethodsSerialized flag.) When this mode is
+specified, instead of creating a serialization semaphore per control
+method,
+the interpreter lock is simply no longer released before a blocking
+operation during control method execution. This effectively makes the AML
+Interpreter single-threaded. The overhead of a semaphore per-method is
+eliminated.
+
+Fixed a regression where an error was no longer emitted if a control
+method
+attempts to create 2 objects of the same name. This once again returns
+AE_ALREADY_EXISTS. When this exception occurs, it invokes the mechanism
+that
+will dynamically serialize the control method to possible prevent future
+errors. (BZ 440)
+
+Integrated a fix for a problem with PCI Express HID detection in the PCI
+Config Space setup procedure. (BZ 7145)
+
+Moved all FADT-related functions to a new file, tbfadt.c. Eliminated the
+AcpiHwInitialize function - the FADT registers are now validated when the
+table is loaded.
+
+Added two new warnings during FADT verification - 1) if the FADT is
+larger
+than the largest known FADT version, and 2) if there is a mismatch
+between
+a
+32-bit block address and the 64-bit X counterpart (when both are non-
+zero.)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 16.7K Data, 94.6K Total
+ Debug Version: 154.9K Code, 62.6K Data, 217.5K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 17.1K Data, 95.0K Total
+ Debug Version: 154.7K Code, 63.0K Data, 217.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed a problem with the implementation of the Switch() operator where
+the
+temporary variable was declared too close to the actual Switch, instead
+of
+at method level. This could cause a problem if the Switch() operator is
+within a while loop, causing an error on the second iteration. (BZ 460)
+
+Disassembler - fix for error emitted for unknown type for target of scope
+operator. Now, ignore it and continue.
+
+Disassembly of an FADT now verifies the input FADT and reports any errors
+found. Fix for proper disassembly of full-sized (ACPI 2.0) FADTs.
+
+Disassembly of raw data buffers with byte initialization data now
+prefixes
+each output line with the current buffer offset.
+
+Disassembly of ASF! table now includes all variable-length data fields at
+the end of some of the subtables.
+
+The disassembler now emits a comment if a buffer appears to be a
+ResourceTemplate, but cannot be disassembled as such because the EndTag
+does
+not appear at the very end of the buffer.
+
+AcpiExec - Added the "-t" command line option to enable the serialized
+mode
+of the AML interpreter.
+
+----------------------------------------
+31 August 2006. Summary of changes for version 20060831:
+
+1) ACPI CA Core Subsystem:
+
+Miscellaneous fixes for the Table Manager:
+- Correctly initialize internal common FADT for all 64-bit "X" fields
+- Fixed a couple table mapping issues during table load
+- Fixed a couple alignment issues for IA64
+- Initialize input array to zero in AcpiInitializeTables
+- Additional parameter validation for AcpiGetTable, AcpiGetTableHeader,
+AcpiGetTableByIndex
+
+Change for GPE support: when a "wake" GPE is received, all wake GPEs are
+now
+immediately disabled to prevent the waking GPE from firing again and to
+prevent other wake GPEs from interrupting the wake process.
+
+Added the AcpiGpeCount global that tracks the number of processed GPEs,
+to
+be used for debugging systems with a large number of ACPI interrupts.
+
+Implemented support for the "DMAR" ACPI table (DMA Redirection Table) in
+both the ACPICA headers and the disassembler.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 77.8K Code, 16.5K Data, 94.3K Total
+ Debug Version: 154.6K Code, 62.3K Data, 216.9K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 16.7K Data, 94.6K Total
+ Debug Version: 154.9K Code, 62.6K Data, 217.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler support for the DMAR ACPI table.
+
+----------------------------------------
+23 August 2006. Summary of changes for version 20060823:
+
+1) ACPI CA Core Subsystem:
+
+The Table Manager component has been completely redesigned and
+reimplemented. The new design is much simpler, and reduces the overall
+code
+and data size of the kernel-resident ACPICA by approximately 5%. Also, it
+is
+now possible to obtain the ACPI tables very early during kernel
+initialization, even before dynamic memory management is initialized.
+(Alexey Starikovskiy, Fiodor Suietov, Bob Moore)
+
+Obsolete ACPICA interfaces:
+
+- AcpiGetFirmwareTable: Use AcpiGetTable instead (works at early kernel
+init
+time).
+- AcpiLoadTable: Not needed.
+- AcpiUnloadTable: Not needed.
+
+New ACPICA interfaces:
+
+- AcpiInitializeTables: Must be called before the table manager can be
+used.
+- AcpiReallocateRootTable: Used to transfer the root table to dynamically
+allocated memory after it becomes available.
+- AcpiGetTableByIndex: Allows the host to easily enumerate all ACPI
+tables
+in the RSDT/XSDT.
+
+Other ACPICA changes:
+
+- AcpiGetTableHeader returns the actual mapped table header, not a copy.
+Use
+AcpiOsUnmapMemory to free this mapping.
+- AcpiGetTable returns the actual mapped table. The mapping is managed
+internally and must not be deleted by the caller. Use of this interface
+causes no additional dynamic memory allocation.
+- AcpiFindRootPointer: Support for physical addressing has been
+eliminated,
+it appeared to be unused.
+- The interface to AcpiOsMapMemory has changed to be consistent with the
+other allocation interfaces.
+- The interface to AcpiOsGetRootPointer has changed to eliminate
+unnecessary
+parameters.
+- ACPI_PHYSICAL_ADDRESS is now 32 bits on 32-bit platforms, 64 bits on
+64-
+bit platforms. Was previously 64 bits on all platforms.
+- The interface to the ACPI Global Lock acquire/release macros have
+changed
+slightly since ACPICA no longer keeps a local copy of the FACS with a
+constructed pointer to the actual global lock.
+
+Porting to the new table manager:
+
+- AcpiInitializeTables: Must be called once, and can be called anytime
+during the OS initialization process. It allows the host to specify an
+area
+of memory to be used to store the internal version of the RSDT/XSDT (root
+table). This allows the host to access ACPI tables before memory
+management
+is initialized and running.
+- AcpiReallocateRootTable: Can be called after memory management is
+running
+to copy the root table to a dynamically allocated array, freeing up the
+scratch memory specified in the call to AcpiInitializeTables.
+- AcpiSubsystemInitialize: This existing interface is independent of the
+Table Manager, and does not have to be called before the Table Manager
+can
+be used, it only must be called before the rest of ACPICA can be used.
+- ACPI Tables: Some changes have been made to the names and structure of
+the
+actbl.h and actbl1.h header files and may require changes to existing
+code.
+For example, bitfields have been completely removed because of their lack
+of
+portability across C compilers.
+- Update interfaces to the Global Lock acquire/release macros if local
+versions are used. (see acwin.h)
+
+Obsolete files: tbconvrt.c, tbget.c, tbgetall.c, tbrsdt.c
+
+New files: tbfind.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.7K Code, 17.9K Data, 98.6K Total
+ Debug Version: 161.0K Code, 65.1K Data, 226.1K Total
+ Current Release:
+ Non-Debug Version: 77.8K Code, 16.5K Data, 94.3K Total
+ Debug Version: 154.6K Code, 62.3K Data, 216.9K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+No changes for this release.
+
+----------------------------------------
+21 July 2006. Summary of changes for version 20060721:
+
+1) ACPI CA Core Subsystem:
+
+The full source code for the ASL test suite used to validate the iASL
+compiler and the ACPICA core subsystem is being released with the ACPICA
+source for the first time. The source is contained in a separate package
+and
+consists of over 1100 files that exercise all ASL/AML operators. The
+package
+should appear on the Intel/ACPI web site shortly. (Valery Podrezov,
+Fiodor
+Suietov)
+
+Completed a new design and implementation for support of the ACPI Global
+Lock. On the OS side, the global lock is now treated as a standard AML
+mutex. Previously, multiple OS threads could "acquire" the global lock
+simultaneously. However, this could cause the BIOS to be starved out of
+the
+lock - especially in cases such as the Embedded Controller driver where
+there is a tight coupling between the OS and the BIOS.
+
+Implemented an optimization for the ACPI Global Lock interrupt mechanism.
+The Global Lock interrupt handler no longer queues the execution of a
+separate thread to signal the global lock semaphore. Instead, the
+semaphore
+is signaled directly from the interrupt handler.
+
+Implemented support within the AML interpreter for package objects that
+contain a larger AML length (package list length) than the package
+element
+count. In this case, the length of the package is truncated to match the
+package element count. Some BIOS code apparently modifies the package
+length
+on the fly, and this change supports this behavior. Provides
+compatibility
+with the MS AML interpreter. (With assistance from Fiodor Suietov)
+
+Implemented a temporary fix for the BankValue parameter of a Bank Field
+to
+support all constant values, now including the Zero and One opcodes.
+Evaluation of this parameter must eventually be converted to a full
+TermArg
+evaluation. A not-implemented error is now returned (temporarily) for
+non-
+constant values for this parameter.
+
+Fixed problem reports (Fiodor Suietov) integrated:
+- Fix for premature object deletion after CopyObject on Operation Region
+(BZ
+350)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.7K Code, 18.0K Data, 98.7K Total
+ Debug Version: 160.9K Code, 65.1K Data, 226.0K Total
+ Current Release:
+ Non-Debug Version: 80.7K Code, 17.9K Data, 98.6K Total
+ Debug Version: 161.0K Code, 65.1K Data, 226.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+No changes for this release.
+
+----------------------------------------
+07 July 2006. Summary of changes for version 20060707:
+
+1) ACPI CA Core Subsystem:
+
+Added the ACPI_PACKED_POINTERS_NOT_SUPPORTED macro to support C compilers
+that do not allow the initialization of address pointers within packed
+structures - even though the hardware itself may support misaligned
+transfers. Some of the debug data structures are packed by default to
+minimize size.
+
+Added an error message for the case where AcpiOsGetThreadId() returns
+zero.
+A non-zero value is required by the core ACPICA code to ensure the proper
+operation of AML mutexes and recursive control methods.
+
+The DSDT is now the only ACPI table that determines whether the AML
+interpreter is in 32-bit or 64-bit mode. Not really a functional change,
+but
+the hooks for per-table 32/64 switching have been removed from the code.
+A
+clarification to the ACPI specification is forthcoming in ACPI 3.0B.
+
+Fixed a possible leak of an OwnerID in the error path of
+AcpiTbInitTableDescriptor (tbinstal.c), and migrated all table OwnerID
+deletion to a single place in AcpiTbUninstallTable to correct possible
+leaks
+when using the AcpiTbDeleteTablesByType interface (with assistance from
+Lance Ortiz.)
+
+Fixed a problem with Serialized control methods where the semaphore
+associated with the method could be over-signaled after multiple method
+invocations.
+
+Fixed two issues with the locking of the internal namespace data
+structure.
+Both the Unload() operator and AcpiUnloadTable interface now lock the
+namespace during the namespace deletion associated with the table unload
+(with assistance from Linn Crosetto.)
+
+Fixed problem reports (Valery Podrezov) integrated:
+- Eliminate unnecessary memory allocation for CreateXxxxField (BZ 5426)
+
+Fixed problem reports (Fiodor Suietov) integrated:
+- Incomplete cleanup branches in AcpiTbGetTableRsdt (BZ 369)
+- On Address Space handler deletion, needless deactivation call (BZ 374)
+- AcpiRemoveAddressSpaceHandler: validate Device handle parameter (BZ
+375)
+- Possible memory leak, Notify sub-objects of Processor, Power,
+ThermalZone
+(BZ 376)
+- AcpiRemoveAddressSpaceHandler: validate Handler parameter (BZ 378)
+- Minimum Length of RSDT should be validated (BZ 379)
+- AcpiRemoveNotifyHandler: return AE_NOT_EXIST if Processor Obj has no
+Handler (BZ (380)
+- AcpiUnloadTable: return AE_NOT_EXIST if no table of specified type
+loaded
+(BZ 381)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.5K Code, 17.8K Data, 98.3K Total
+ Debug Version: 160.8K Code, 64.8K Data, 225.6K Total
+ Current Release:
+ Non-Debug Version: 80.7K Code, 17.9K Data, 98.6K Total
+ Debug Version: 161.0K Code, 65.1K Data, 226.1K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed problem reports:
+Compiler segfault when ASL contains a long (>1024) String declaration (BZ
+436)
+
+----------------------------------------
+23 June 2006. Summary of changes for version 20060623:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a new ACPI_SPINLOCK type for the OSL lock interfaces. This
+allows the type to be customized to the host OS for improved efficiency
+(since a spinlock is usually a very small object.)
+
+Implemented support for "ignored" bits in the ACPI registers. According
+to
+the ACPI specification, these bits should be preserved when writing the
+registers via a read/modify/write cycle. There are 3 bits preserved in
+this
+manner: PM1_CONTROL[0] (SCI_EN), PM1_CONTROL[9], and PM1_STATUS[11].
+
+Implemented the initial deployment of new OSL mutex interfaces. Since
+some
+host operating systems have separate mutex and semaphore objects, this
+feature was requested. The base code now uses mutexes (and the new mutex
+interfaces) wherever a binary semaphore was used previously. However, for
+the current release, the mutex interfaces are defined as macros to map
+them
+to the existing semaphore interfaces. Therefore, no OSL changes are
+required
+at this time. (See acpiosxf.h)
+
+Fixed several problems with the support for the control method SyncLevel
+parameter. The SyncLevel now works according to the ACPI specification
+and
+in concert with the Mutex SyncLevel parameter, since the current
+SyncLevel
+is a property of the executing thread. Mutual exclusion for control
+methods
+is now implemented with a mutex instead of a semaphore.
+
+Fixed three instances of the use of the C shift operator in the bitfield
+support code (exfldio.c) to avoid the use of a shift value larger than
+the
+target data width. The behavior of C compilers is undefined in this case
+and
+can cause unpredictable results, and therefore the case must be detected
+and
+avoided. (Fiodor Suietov)
+
+Added an info message whenever an SSDT or OEM table is loaded dynamically
+via the Load() or LoadTable() ASL operators. This should improve
+debugging
+capability since it will show exactly what tables have been loaded
+(beyond
+the tables present in the RSDT/XSDT.)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.0K Code, 17.6K Data, 97.6K Total
+ Debug Version: 160.2K Code, 64.7K Data, 224.9K Total
+ Current Release:
+ Non-Debug Version: 80.5K Code, 17.8K Data, 98.3K Total
+ Debug Version: 160.8K Code, 64.8K Data, 225.6K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+No changes for this release.
+
+----------------------------------------
+08 June 2006. Summary of changes for version 20060608:
+
+1) ACPI CA Core Subsystem:
+
+Converted the locking mutex used for the ACPI hardware to a spinlock.
+This
+change should eliminate all problems caused by attempting to acquire a
+semaphore at interrupt level, and it means that all ACPICA external
+interfaces that directly access the ACPI hardware can be safely called
+from
+interrupt level. OSL code that implements the semaphore interfaces should
+be
+able to eliminate any workarounds for being called at interrupt level.
+
+Fixed a regression introduced in 20060526 where the ACPI device
+initialization could be prematurely aborted with an AE_NOT_FOUND if a
+device
+did not have an optional _INI method.
+
+Fixed an IndexField issue where a write to the Data Register should be
+limited in size to the AccessSize (width) of the IndexField itself. (BZ
+433,
+Fiodor Suietov)
+
+Fixed problem reports (Valery Podrezov) integrated:
+- Allow store of ThermalZone objects to Debug object (BZ 5369/5370)
+
+Fixed problem reports (Fiodor Suietov) integrated:
+- AcpiGetTableHeader doesn't handle multiple instances correctly (BZ 364)
+
+Removed four global mutexes that were obsolete and were no longer being
+used.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.0K Code, 17.7K Data, 97.7K Total
+ Debug Version: 160.3K Code, 64.9K Data, 225.2K Total
+ Current Release:
+ Non-Debug Version: 80.0K Code, 17.6K Data, 97.6K Total
+ Debug Version: 160.2K Code, 64.7K Data, 224.9K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Fixed a fault when using -g option (get tables from registry) on Windows
+machines.
+
+Fixed problem reports integrated:
+- Generate error if CreateField NumBits parameter is zero. (BZ 405)
+- Fault if Offset/Length in Field unit is very large (BZ 432, Fiodor
+Suietov)
+- Global table revision override (-r) is ignored (BZ 413)
+
+----------------------------------------
+26 May 2006. Summary of changes for version 20060526:
+
+1) ACPI CA Core Subsystem:
+
+Restructured, flattened, and simplified the internal interfaces for
+namespace object evaluation - resulting in smaller code, less CPU stack
+use,
+and fewer interfaces. (With assistance from Mikhail Kouzmich)
+
+Fixed a problem with the CopyObject operator where the first parameter
+was
+not typed correctly for the parser, interpreter, compiler, and
+disassembler.
+Caused various errors and unexpected behavior.
+
+Fixed a problem where a ShiftLeft or ShiftRight of more than 64 bits
+produced incorrect results with some C compilers. Since the behavior of C
+compilers when the shift value is larger than the datatype width is
+apparently not well defined, the interpreter now detects this condition
+and
+simply returns zero as expected in all such cases. (BZ 395)
+
+Fixed problem reports (Valery Podrezov) integrated:
+- Update String-to-Integer conversion to match ACPI 3.0A spec (BZ 5329)
+- Allow interpreter to handle nested method declarations (BZ 5361)
+
+Fixed problem reports (Fiodor Suietov) integrated:
+- AcpiTerminate doesn't free debug memory allocation list objects (BZ
+355)
+- After Core Subsystem shutdown, AcpiSubsystemStatus returns AE_OK (BZ
+356)
+- AcpiOsUnmapMemory for RSDP can be invoked inconsistently (BZ 357)
+- Resource Manager should return AE_TYPE for non-device objects (BZ 358)
+- Incomplete cleanup branch in AcpiNsEvaluateRelative (BZ 359)
+- Use AcpiOsFree instead of ACPI_FREE in AcpiRsSetSrsMethodData (BZ 360)
+- Incomplete cleanup branch in AcpiPsParseAml (BZ 361)
+- Incomplete cleanup branch in AcpiDsDeleteWalkState (BZ 362)
+- AcpiGetTableHeader returns AE_NO_ACPI_TABLES until DSDT is loaded (BZ
+365)
+- Status of the Global Initialization Handler call not used (BZ 366)
+- Incorrect object parameter to Global Initialization Handler (BZ 367)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.8K Code, 17.7K Data, 97.5K Total
+ Debug Version: 160.5K Code, 65.1K Data, 225.6K Total
+ Current Release:
+ Non-Debug Version: 80.0K Code, 17.7K Data, 97.7K Total
+ Debug Version: 160.3K Code, 64.9K Data, 225.2K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Modified the parser to allow the names IO, DMA, and IRQ to be used as
+namespace identifiers with no collision with existing resource descriptor
+macro names. This provides compatibility with other ASL compilers and is
+most useful for disassembly/recompilation of existing tables without
+parse
+errors. (With assistance from Thomas Renninger)
+
+Disassembler: fixed an incorrect disassembly problem with the
+DataTableRegion and CopyObject operators. Fixed a possible fault during
+disassembly of some Alias operators.
+
+----------------------------------------
+12 May 2006. Summary of changes for version 20060512:
+
+1) ACPI CA Core Subsystem:
+
+Replaced the AcpiOsQueueForExecution interface with a new interface named
+AcpiOsExecute. The major difference is that the new interface does not
+have
+a Priority parameter, this appeared to be useless and has been replaced
+by
+a
+Type parameter. The Type tells the host what type of execution is being
+requested, such as global lock handler, notify handler, GPE handler, etc.
+This allows the host to queue and execute the request as appropriate for
+the
+request type, possibly using different work queues and different
+priorities
+for the various request types. This enables fixes for multithreading
+deadlock problems such as BZ #5534, and will require changes to all
+existing
+OS interface layers. (Alexey Starikovskiy and Bob Moore)
+
+Fixed a possible memory leak associated with the support for the so-
+called
+"implicit return" ACPI extension. Reported by FreeBSD, BZ #6514. (Fiodor
+Suietov)
+
+Fixed a problem with the Load() operator where a table load from an
+operation region could overwrite an internal table buffer by up to 7
+bytes
+and cause alignment faults on IPF systems. (With assistance from Luming
+Yu)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 79.7K Code, 17.7K Data, 97.4K Total
+ Debug Version: 160.1K Code, 65.2K Data, 225.3K Total
+ Current Release:
+ Non-Debug Version: 79.8K Code, 17.7K Data, 97.5K Total
+ Debug Version: 160.5K Code, 65.1K Data, 225.6K Total
+
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Implemented support to cross reference the internal
+namespace
+and automatically generate ASL External() statements for symbols not
+defined
+within the current table being disassembled. This will simplify the
+disassembly and recompilation of interdependent tables such as SSDTs
+since
+these statements will no longer have to be added manually.
+
+Disassembler: Implemented experimental support to automatically detect
+invocations of external control methods and generate appropriate
+External()
+statements. This is problematic because the AML cannot be correctly
+parsed
+until the number of arguments for each control method is known.
+Currently,
+standalone method invocations and invocations as the source operand of a
+Store() statement are supported.
+
+Disassembler: Implemented support for the ASL pseudo-operators LNotEqual,
+LLessEqual, and LGreaterEqual. Previously disassembled as LNot(LEqual()),
+LNot(LGreater()), and LNot(LLess()), this makes the disassembled ASL code
+more readable and likely closer to the original ASL source.
+
+----------------------------------------
+21 April 2006. Summary of changes for version 20060421:
+
+1) ACPI CA Core Subsystem:
+
+Removed a device initialization optimization introduced in 20051216 where
+the _STA method was not run unless an _INI was also present for the same
+device. This optimization could cause problems because it could allow
+_INI
+methods to be run within a not-present device subtree. (If a not-present
+device had no _INI, _STA would not be run, the not-present status would
+not
+be discovered, and the children of the device would be incorrectly
+traversed.)
+
+Implemented a new _STA optimization where namespace subtrees that do not
+contain _INI are identified and ignored during device initialization.
+Selectively running _STA can significantly improve boot time on large
+machines (with assistance from Len Brown.)
+
+Implemented support for the device initialization case where the returned
+_STA flags indicate a device not-present but functioning. In this case,
+_INI
+is not run, but the device children are examined for presence, as per the
+ACPI specification.
+
+Implemented an additional change to the IndexField support in order to
+conform to MS behavior. The value written to the Index Register is not
+simply a byte offset, it is a byte offset in units of the access width of
+the parent Index Field. (Fiodor Suietov)
+
+Defined and deployed a new OSL interface, AcpiOsValidateAddress. This
+interface is called during the creation of all AML operation regions, and
+allows the host OS to exert control over what addresses it will allow the
+AML code to access. Operation Regions whose addresses are disallowed will
+cause a runtime exception when they are actually accessed (will not
+affect
+or abort table loading.) See oswinxf or osunixxf for an example
+implementation.
+
+Defined and deployed a new OSL interface, AcpiOsValidateInterface. This
+interface allows the host OS to match the various "optional"
+interface/behavior strings for the _OSI predefined control method as
+appropriate (with assistance from Bjorn Helgaas.) See oswinxf or osunixxf
+for an example implementation.
+
+Restructured and corrected various problems in the exception handling
+code
+paths within DsCallControlMethod and DsTerminateControlMethod in dsmethod
+(with assistance from Takayoshi Kochi.)
+
+Modified the Linux source converter to ignore quoted string literals
+while
+converting identifiers from mixed to lower case. This will correct
+problems
+with the disassembler and other areas where such strings must not be
+modified.
+
+The ACPI_FUNCTION_* macros no longer require quotes around the function
+name. This allows the Linux source converter to convert the names, now
+that
+the converter ignores quoted strings.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+
+ Non-Debug Version: 81.1K Code, 17.7K Data, 98.8K Total
+ Debug Version: 158.9K Code, 64.9K Data, 223.8K Total
+ Current Release:
+ Non-Debug Version: 79.7K Code, 17.7K Data, 97.4K Total
+ Debug Version: 160.1K Code, 65.2K Data, 225.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented 3 new warnings for iASL, and implemented multiple warning
+levels
+(w2 flag).
+
+1) Ignored timeouts: If the TimeoutValue parameter to Wait or Acquire is
+not
+WAIT_FOREVER (0xFFFF) and the code does not examine the return value to
+check for the possible timeout, a warning is issued.
+
+2) Useless operators: If an ASL operator does not specify an optional
+target
+operand and it also does not use the function return value from the
+operator, a warning is issued since the operator effectively does
+nothing.
+
+3) Unreferenced objects: If a namespace object is created, but never
+referenced, a warning is issued. This is a warning level 2 since there
+are
+cases where this is ok, such as when a secondary table is loaded that
+uses
+the unreferenced objects. Even so, care is taken to only flag objects
+that
+don't look like they will ever be used. For example, the reserved methods
+(starting with an underscore) are usually not referenced because it is
+expected that the OS will invoke them.
+
+----------------------------------------
+31 March 2006. Summary of changes for version 20060331:
+
+1) ACPI CA Core Subsystem:
+
+Implemented header file support for the following additional ACPI tables:
+ASF!, BOOT, CPEP, DBGP, MCFG, SPCR, SPMI, TCPA, and WDRT. With this
+support,
+all current and known ACPI tables are now defined in the ACPICA headers
+and
+are available for use by device drivers and other software.
+
+Implemented support to allow tables that contain ACPI names with invalid
+characters to be loaded. Previously, this would cause the table load to
+fail, but since there are several known cases of such tables on existing
+machines, this change was made to enable ACPI support for them. Also,
+this
+matches the behavior of the Microsoft ACPI implementation.
+
+Fixed a couple regressions introduced during the memory optimization in
+the
+20060317 release. The namespace node definition required additional
+reorganization and an internal datatype that had been changed to 8-bit
+was
+restored to 32-bit. (Valery Podrezov)
+
+Fixed a problem where a null pointer passed to AcpiUtDeleteGenericState
+could be passed through to AcpiOsReleaseObject which is unexpected. Such
+null pointers are now trapped and ignored, matching the behavior of the
+previous implementation before the deployment of AcpiOsReleaseObject.
+(Valery Podrezov, Fiodor Suietov)
+
+Fixed a memory mapping leak during the deletion of a SystemMemory
+operation
+region where a cached memory mapping was not deleted. This became a
+noticeable problem for operation regions that are defined within
+frequently
+used control methods. (Dana Meyers)
+
+Reorganized the ACPI table header files into two main files: one for the
+ACPI tables consumed by the ACPICA core, and another for the
+miscellaneous
+ACPI tables that are consumed by the drivers and other software. The
+various
+FADT definitions were merged into one common section and three different
+tables (ACPI 1.0, 1.0+, and 2.0)
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has
+a much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 80.9K Code, 17.7K Data, 98.6K Total
+ Debug Version: 158.7K Code, 64.8K Data, 223.5K Total
+ Current Release:
+ Non-Debug Version: 81.1K Code, 17.7K Data, 98.8K Total
+ Debug Version: 158.9K Code, 64.9K Data, 223.8K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Implemented support to decode and format all non-AML ACPI
+tables (tables other than DSDTs and SSDTs.) This includes the new tables
+added to the ACPICA headers, therefore all current and known ACPI tables
+are
+supported.
+
+Disassembler: The change to allow ACPI names with invalid characters also
+enables the disassembly of such tables. Invalid characters within names
+are
+changed to '*' to make the name printable; the iASL compiler will still
+generate an error for such names, however, since this is an invalid ACPI
+character.
+
+Implemented an option for AcpiXtract (-a) to extract all tables found in
+the
+input file. The default invocation extracts only the DSDTs and SSDTs.
+
+Fixed a couple of gcc generation issues for iASL and AcpiExec and added a
+makefile for the AcpiXtract utility.
+
+----------------------------------------
+17 March 2006. Summary of changes for version 20060317:
+
+1) ACPI CA Core Subsystem:
+
+Implemented the use of a cache object for all internal namespace nodes.
+Since there are about 1000 static nodes in a typical system, this will
+decrease memory use for cache implementations that minimize per-
+allocation
+overhead (such as a slab allocator.)
+
+Removed the reference count mechanism for internal namespace nodes, since
+it
+was deemed unnecessary. This reduces the size of each namespace node by
+about 5%-10% on all platforms. Nodes are now 20 bytes for the 32-bit
+case,
+and 32 bytes for the 64-bit case.
+
+Optimized several internal data structures to reduce object size on 64-
+bit
+platforms by packing data within the 64-bit alignment. This includes the
+frequently used ACPI_OPERAND_OBJECT, of which there can be ~1000 static
+instances corresponding to the namespace objects.
+
+Added two new strings for the predefined _OSI method: "Windows 2001.1
+SP1"
+and "Windows 2006".
+
+Split the allocation tracking mechanism out to a separate file, from
+utalloc.c to uttrack.c. This mechanism appears to be only useful for
+application-level code. Kernels may wish to not include uttrack.c in
+distributions.
+
+Removed all remnants of the obsolete ACPI_REPORT_* macros and the
+associated
+code. (These macros have been replaced by the ACPI_ERROR and ACPI_WARNING
+macros.)
+
+Code and Data Size: These are the sizes for the acpica.lib produced by
+the
+Microsoft Visual C++ 6.0 32-bit compiler. The values do not include any
+ACPI
+driver or OSPM code. The debug version of the code includes the debug
+output
+trace mechanism and has a much larger code and data size. Note that these
+values will vary depending on the efficiency of the compiler and the
+compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 81.1K Code, 17.8K Data, 98.9K Total
+ Debug Version: 161.6K Code, 65.7K Data, 227.3K Total
+ Current Release:
+ Non-Debug Version: 80.9K Code, 17.7K Data, 98.6K Total
+ Debug Version: 158.7K Code, 64.8K Data, 223.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented an ANSI C version of the acpixtract utility. This version
+will
+automatically extract the DSDT and all SSDTs from the input acpidump text
+file and dump the binary output to separate files. It can also display a
+summary of the input file including the headers for each table found and
+will extract any single ACPI table, with any signature. (See
+source/tools/acpixtract)
+
+----------------------------------------
+10 March 2006. Summary of changes for version 20060310:
+
+1) ACPI CA Core Subsystem:
+
+Tagged all external interfaces to the subsystem with the new
+ACPI_EXPORT_SYMBOL macro. This macro can be defined as necessary to
+assist
+kernel integration. For Linux, the macro resolves to the EXPORT_SYMBOL
+macro. The default definition is NULL.
+
+Added the ACPI_THREAD_ID type for the return value from
+AcpiOsGetThreadId.
+This allows the host to define this as necessary to simplify kernel
+integration. The default definition is ACPI_NATIVE_UINT.
+
+Fixed two interpreter problems related to error processing, the deletion
+of
+objects, and placing invalid pointers onto the internal operator result
+stack. BZ 6028, 6151 (Valery Podrezov)
+
+Increased the reference count threshold where a warning is emitted for
+large
+reference counts in order to eliminate unnecessary warnings on systems
+with
+large namespaces (especially 64-bit.) Increased the value from 0x400 to
+0x800.
+
+Due to universal disagreement as to the meaning of the 'c' in the
+calloc()
+function, the ACPI_MEM_CALLOCATE macro has been renamed to
+ACPI_ALLOCATE_ZEROED so that the purpose of the interface is 'clear'.
+ACPI_MEM_ALLOCATE and ACPI_MEM_FREE are renamed to ACPI_ALLOCATE and
+ACPI_FREE.
+
+Code and Data Size: These are the sizes for the acpica.lib produced by
+the
+Microsoft Visual C++ 6.0 32-bit compiler. The values do not include any
+ACPI
+driver or OSPM code. The debug version of the code includes the debug
+output
+trace mechanism and has a much larger code and data size. Note that these
+values will vary depending on the efficiency of the compiler and the
+compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 81.0K Code, 17.8K Data, 98.8K Total
+ Debug Version: 161.4K Code, 65.7K Data, 227.1K Total
+ Current Release:
+ Non-Debug Version: 81.1K Code, 17.8K Data, 98.9K Total
+ Debug Version: 161.6K Code, 65.7K Data, 227.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Disassembler: implemented support for symbolic resource descriptor
+references. If a CreateXxxxField operator references a fixed offset
+within
+a
+resource descriptor, a name is assigned to the descriptor and the offset
+is
+translated to the appropriate resource tag and pathname. The addition of
+this support brings the disassembled code very close to the original ASL
+source code and helps eliminate run-time errors when the disassembled
+code
+is modified (and recompiled) in such a way as to invalidate the original
+fixed offsets.
+
+Implemented support for a Descriptor Name as the last parameter to the
+ASL
+Register() macro. This parameter was inadvertently left out of the ACPI
+specification, and will be added for ACPI 3.0b.
+
+Fixed a problem where the use of the "_OSI" string (versus the full path
+"\_OSI") caused an internal compiler error. ("No back ptr to op")
+
+Fixed a problem with the error message that occurs when an invalid string
+is
+used for a _HID object (such as one with an embedded asterisk:
+"*PNP010A".)
+The correct message is now displayed.
+
+----------------------------------------
+17 February 2006. Summary of changes for version 20060217:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a change to the IndexField support to match the behavior of
+the
+Microsoft AML interpreter. The value written to the Index register is now
+a
+byte offset, no longer an index based upon the width of the Data
+register.
+This should fix IndexField problems seen on some machines where the Data
+register is not exactly one byte wide. The ACPI specification will be
+clarified on this point.
+
+Fixed a problem where several resource descriptor types could overrun the
+internal descriptor buffer due to size miscalculation: VendorShort,
+VendorLong, and Interrupt. This was noticed on IA64 machines, but could
+affect all platforms.
+
+Fixed a problem where individual resource descriptors were misaligned
+within
+the internal buffer, causing alignment faults on IA64 platforms.
+
+Code and Data Size: These are the sizes for the acpica.lib produced by
+the
+Microsoft Visual C++ 6.0 32-bit compiler. The values do not include any
+ACPI
+driver or OSPM code. The debug version of the code includes the debug
+output
+trace mechanism and has a much larger code and data size. Note that these
+values will vary depending on the efficiency of the compiler and the
+compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 81.1K Code, 17.8K Data, 98.9K Total
+ Debug Version: 161.3K Code, 65.6K Data, 226.9K Total
+ Current Release:
+ Non-Debug Version: 81.0K Code, 17.8K Data, 98.8K Total
+ Debug Version: 161.4K Code, 65.7K Data, 227.1K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support for new reserved names: _WDG and _WED are Microsoft
+extensions for Windows Instrumentation Management, _TDL is a new ACPI-
+defined method (Throttling Depth Limit.)
+
+Fixed a problem where a zero-length VendorShort or VendorLong resource
+descriptor was incorrectly emitted as a descriptor of length one.
+
+----------------------------------------
+10 February 2006. Summary of changes for version 20060210:
+
+1) ACPI CA Core Subsystem:
+
+Removed a couple of extraneous ACPI_ERROR messages that appeared during
+normal execution. These became apparent after the conversion from
+ACPI_DEBUG_PRINT.
+
+Fixed a problem where the CreateField operator could hang if the BitIndex
+or
+NumBits parameter referred to a named object. (Valery Podrezov, BZ 5359)
+
+Fixed a problem where a DeRefOf operation on a buffer object incorrectly
+failed with an exception. This also fixes a couple of related RefOf and
+DeRefOf issues. (Valery Podrezov, BZ 5360/5392/5387)
+
+Fixed a problem where the AE_BUFFER_LIMIT exception was returned instead
+of
+AE_STRING_LIMIT on an out-of-bounds Index() operation. (Valery Podrezov,
+BZ
+5480)
+
+Implemented a memory cleanup at the end of the execution of each
+iteration
+of an AML While() loop, preventing the accumulation of outstanding
+objects.
+(Valery Podrezov, BZ 5427)
+
+Eliminated a chunk of duplicate code in the object resolution code.
+(Valery
+Podrezov, BZ 5336)
+
+Fixed several warnings during the 64-bit code generation.
+
+The AcpiSrc source code conversion tool now inserts one line of
+whitespace
+after an if() statement that is followed immediately by a comment,
+improving
+readability of the Linux code.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 81.0K Code, 17.9K Data, 98.9K Total
+ Debug Version: 161.3K Code, 65.7K Data, 227.0K Total
+ Current Release:
+ Non-Debug Version: 81.1K Code, 17.8K Data, 98.9K Total
+ Debug Version: 161.3K Code, 65.6K Data, 226.9K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with the disassembly of a BankField operator with a
+complex
+expression for the BankValue parameter.
+
+----------------------------------------
+27 January 2006. Summary of changes for version 20060127:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support in the Resource Manager to allow unresolved
+namestring
+references within resource package objects for the _PRT method. This
+support
+is in addition to the previously implemented unresolved reference support
+within the AML parser. If the interpreter slack mode is enabled, these
+unresolved references will be passed through to the caller as a NULL
+package
+entry.
+
+Implemented and deployed new macros and functions for error and warning
+messages across the subsystem. These macros are simpler and generate less
+code than their predecessors. The new macros ACPI_ERROR, ACPI_EXCEPTION,
+ACPI_WARNING, and ACPI_INFO replace the ACPI_REPORT_* macros. The older
+macros remain defined to allow ACPI drivers time to migrate to the new
+macros.
+
+Implemented the ACPI_CPU_FLAGS type to simplify host OS integration of
+the
+Acquire/Release Lock OSL interfaces.
+
+Fixed a problem where Alias ASL operators are sometimes not correctly
+resolved, in both the interpreter and the iASL compiler.
+
+Fixed several problems with the implementation of the
+ConcatenateResTemplate
+ASL operator. As per the ACPI specification, zero length buffers are now
+treated as a single EndTag. One-length buffers always cause a fatal
+exception. Non-zero length buffers that do not end with a full 2-byte
+EndTag
+cause a fatal exception.
+
+Fixed a possible structure overwrite in the AcpiGetObjectInfo external
+interface. (With assistance from Thomas Renninger)
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 83.1K Code, 18.4K Data, 101.5K Total
+ Debug Version: 163.2K Code, 66.2K Data, 229.4K Total
+ Current Release:
+ Non-Debug Version: 81.0K Code, 17.9K Data, 98.9K Total
+ Debug Version: 161.3K Code, 65.7K Data, 227.0K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed an internal error that was generated for any forward references to
+ASL
+Alias objects.
+
+----------------------------------------
+13 January 2006. Summary of changes for version 20060113:
+
+1) ACPI CA Core Subsystem:
+
+Added 2006 copyright to all module headers and signons. This affects
+virtually every file in the ACPICA core subsystem, iASL compiler, and the
+utilities.
+
+Enhanced the ACPICA error reporting in order to simplify user migration
+to
+the non-debug version of ACPICA. Replaced all instances of the
+ACPI_DEBUG_PRINT macro invoked at the ACPI_DB_ERROR and ACPI_DB_WARN
+debug
+levels with the ACPI_REPORT_ERROR and ACPI_REPORT_WARNING macros,
+respectively. This preserves all error and warning messages in the non-
+debug
+version of the ACPICA code (this has been referred to as the "debug lite"
+option.) Over 200 cases were converted to create a total of over 380
+error/warning messages across the ACPICA code. This increases the code
+and
+data size of the default non-debug version of the code somewhat (about
+13K),
+but all error/warning reporting may be disabled if desired (and code
+eliminated) by specifying the ACPI_NO_ERROR_MESSAGES compile-time
+configuration option. The size of the debug version of ACPICA remains
+about
+the same.
+
+Fixed a memory leak within the AML Debugger "Set" command. One object was
+not properly deleted for every successful invocation of the command.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.6K Code, 12.3K Data, 88.9K Total
+ Debug Version: 163.7K Code, 67.5K Data, 231.2K Total
+ Current Release:
+ Non-Debug Version: 83.1K Code, 18.4K Data, 101.5K Total
+ Debug Version: 163.2K Code, 66.2K Data, 229.4K Total
+
+
+2) iASL Compiler/Disassembler:
+
+The compiler now officially supports the ACPI 3.0a specification that was
+released on December 30, 2005. (Specification is available at
+www.acpi.info)
+
+----------------------------------------
+16 December 2005. Summary of changes for version 20051216:
+
+1) ACPI CA Core Subsystem:
+
+Implemented optional support to allow unresolved names within ASL Package
+objects. A null object is inserted in the package when a named reference
+cannot be located in the current namespace. Enabled via the interpreter
+slack flag, this should eliminate AE_NOT_FOUND exceptions seen on
+machines
+that contain such code.
+
+Implemented an optimization to the initialization sequence that can
+improve
+boot time. During ACPI device initialization, the _STA method is now run
+if
+and only if the _INI method exists. The _STA method is used to determine
+if
+the device is present; An _INI can only be run if _STA returns present,
+but
+it is a waste of time to run the _STA method if the _INI does not exist.
+(Prototype and assistance from Dong Wei)
+
+Implemented use of the C99 uintptr_t for the pointer casting macros if it
+is
+available in the current compiler. Otherwise, the default (void *) cast
+is
+used as before.
+
+Fixed some possible memory leaks found within the execution path of the
+Break, Continue, If, and CreateField operators. (Valery Podrezov)
+
+Fixed a problem introduced in the 20051202 release where an exception is
+generated during method execution if a control method attempts to declare
+another method.
+
+Moved resource descriptor string constants that are used by both the AML
+disassembler and AML debugger to the common utilities directory so that
+these components are independent.
+
+Implemented support in the AcpiExec utility (-e switch) to globally
+ignore
+exceptions during control method execution (method is not aborted.)
+
+Added the rsinfo.c source file to the AcpiExec makefile for Linux/Unix
+generation.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.3K Code, 12.3K Data, 88.6K Total
+ Debug Version: 163.2K Code, 67.4K Data, 230.6K Total
+ Current Release:
+ Non-Debug Version: 76.6K Code, 12.3K Data, 88.9K Total
+ Debug Version: 163.7K Code, 67.5K Data, 231.2K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem where a CPU stack overflow fault could occur if a
+recursive
+method call was made from within a Return statement.
+
+----------------------------------------
+02 December 2005. Summary of changes for version 20051202:
+
+1) ACPI CA Core Subsystem:
+
+Modified the parsing of control methods to no longer create namespace
+objects during the first pass of the parse. Objects are now created only
+during the execute phase, at the moment the namespace creation operator
+is
+encountered in the AML (Name, OperationRegion, CreateByteField, etc.)
+This
+should eliminate ALREADY_EXISTS exceptions seen on some machines where
+reentrant control methods are protected by an AML mutex. The mutex will
+now
+correctly block multiple threads from attempting to create the same
+object
+more than once.
+
+Increased the number of available Owner Ids for namespace object tracking
+from 32 to 255. This should eliminate the OWNER_ID_LIMIT exceptions seen
+on
+some machines with a large number of ACPI tables (either static or
+dynamic).
+
+Fixed a problem with the AcpiExec utility where a fault could occur when
+the
+-b switch (batch mode) is used.
+
+Enhanced the namespace dump routine to output the owner ID for each
+namespace object.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.3K Code, 12.3K Data, 88.6K Total
+ Debug Version: 163.0K Code, 67.4K Data, 230.4K Total
+ Current Release:
+ Non-Debug Version: 76.3K Code, 12.3K Data, 88.6K Total
+ Debug Version: 163.2K Code, 67.4K Data, 230.6K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a parse error during compilation of certain Switch/Case constructs.
+To
+simplify the parse, the grammar now allows for multiple Default
+statements
+and this error is now detected and flagged during the analysis phase.
+
+Disassembler: The disassembly now includes the contents of the original
+table header within a comment at the start of the file. This includes the
+name and version of the original ASL compiler.
+
+----------------------------------------
+17 November 2005. Summary of changes for version 20051117:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem in the AML parser where the method thread count could be
+decremented below zero if any errors occurred during the method parse
+phase.
+This should eliminate AE_AML_METHOD_LIMIT exceptions seen on some
+machines.
+This also fixed a related regression with the mechanism that detects and
+corrects methods that cannot properly handle reentrancy (related to the
+deployment of the new OwnerId mechanism.)
+
+Eliminated the pre-parsing of control methods (to detect errors) during
+table load. Related to the problem above, this was causing unwind issues
+if
+any errors occurred during the parse, and it seemed to be overkill. A
+table
+load should not be aborted if there are problems with any single control
+method, thus rendering this feature rather pointless.
+
+Fixed a problem with the new table-driven resource manager where an
+internal
+buffer overflow could occur for small resource templates.
+
+Implemented a new external interface, AcpiGetVendorResource. This
+interface
+will find and return a vendor-defined resource descriptor within a _CRS
+or
+_PRS method via an ACPI 3.0 UUID match. With assistance from Bjorn
+Helgaas.
+
+Removed the length limit (200) on string objects as per the upcoming ACPI
+3.0A specification. This affects the following areas of the interpreter:
+1)
+any implicit conversion of a Buffer to a String, 2) a String object
+result
+of the ASL Concatentate operator, 3) the String object result of the ASL
+ToString operator.
+
+Fixed a problem in the Windows OS interface layer (OSL) where a
+WAIT_FOREVER
+on a semaphore object would incorrectly timeout. This allows the
+multithreading features of the AcpiExec utility to work properly under
+Windows.
+
+Updated the Linux makefiles for the iASL compiler and AcpiExec to include
+the recently added file named "utresrc.c".
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.2K Code, 12.3K Data, 88.5K Total
+ Debug Version: 163.0K Code, 67.4K Data, 230.4K Total
+ Current Release:
+ Non-Debug Version: 76.3K Code, 12.3K Data, 88.6K Total
+ Debug Version: 163.0K Code, 67.4K Data, 230.4K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Removed the limit (200) on string objects as per the upcoming ACPI 3.0A
+specification. For the iASL compiler, this means that string literals
+within
+the source ASL can be of any length.
+
+Enhanced the listing output to dump the AML code for resource descriptors
+immediately after the ASL code for each descriptor, instead of in a block
+at
+the end of the entire resource template.
+
+Enhanced the compiler debug output to dump the entire original parse tree
+constructed during the parse phase, before any transforms are applied to
+the
+tree. The transformed tree is dumped also.
+
+----------------------------------------
+02 November 2005. Summary of changes for version 20051102:
+
+1) ACPI CA Core Subsystem:
+
+Modified the subsystem initialization sequence to improve GPE support.
+The
+GPE initialization has been split into two parts in order to defer
+execution
+of the _PRW methods (Power Resources for Wake) until after the hardware
+is
+fully initialized and the SCI handler is installed. This allows the _PRW
+methods to access fields protected by the Global Lock. This will fix
+systems
+where a NO_GLOBAL_LOCK exception has been seen during initialization.
+
+Converted the ACPI internal object disassemble and display code within
+the
+AML debugger to fully table-driven operation, reducing code size and
+increasing maintainability.
+
+Fixed a regression with the ConcatenateResTemplate() ASL operator
+introduced
+in the 20051021 release.
+
+Implemented support for "local" internal ACPI object types within the
+debugger "Object" command and the AcpiWalkNamespace external interfaces.
+These local types include RegionFields, BankFields, IndexFields, Alias,
+and
+reference objects.
+
+Moved common AML resource handling code into a new file, "utresrc.c".
+This
+code is shared by both the Resource Manager and the AML Debugger.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.1K Code, 12.2K Data, 88.3K Total
+ Debug Version: 163.5K Code, 67.0K Data, 230.5K Total
+ Current Release:
+ Non-Debug Version: 76.2K Code, 12.3K Data, 88.5K Total
+ Debug Version: 163.0K Code, 67.4K Data, 230.4K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with very large initializer lists (more than 4000
+elements)
+for both Buffer and Package objects where the parse stack could overflow.
+
+Enhanced the pre-compile source code scan for non-ASCII characters to
+ignore
+characters within comment fields. The scan is now always performed and is
+no
+longer optional, detecting invalid characters within a source file
+immediately rather than during the parse phase or later.
+
+Enhanced the ASL grammar definition to force early reductions on all
+list-
+style grammar elements so that the overall parse stack usage is greatly
+reduced. This should improve performance and reduce the possibility of
+parse
+stack overflow.
+
+Eliminated all reduce/reduce conflicts in the iASL parser generation.
+Also,
+with the addition of a %expected statement, the compiler generates from
+source with no warnings.
+
+Fixed a possible segment fault in the disassembler if the input filename
+does not contain a "dot" extension (Thomas Renninger).
+
+----------------------------------------
+21 October 2005. Summary of changes for version 20051021:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for the EM64T and other x86-64 processors. This
+essentially entails recognizing that these processors support non-aligned
+memory transfers. Previously, all 64-bit processors were assumed to lack
+hardware support for non-aligned transfers.
+
+Completed conversion of the Resource Manager to nearly full table-driven
+operation. Specifically, the resource conversion code (convert AML to
+internal format and the reverse) and the debug code to dump internal
+resource descriptors are fully table-driven, reducing code and data size
+and
+improving maintainability.
+
+The OSL interfaces for Acquire and Release Lock now use a 64-bit flag
+word
+on 64-bit processors instead of a fixed 32-bit word. (With assistance
+from
+Alexey Starikovskiy)
+
+Implemented support within the resource conversion code for the Type-
+Specific byte within the various ACPI 3.0 *WordSpace macros.
+
+Fixed some issues within the resource conversion code for the type-
+specific
+flags for both Memory and I/O address resource descriptors. For Memory,
+implemented support for the MTP and TTP flags. For I/O, split the TRS and
+TTP flags into two separate fields.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.1K Code, 12.1K Data, 89.2K Total
+ Debug Version: 168.0K Code, 68.3K Data, 236.3K Total
+ Current Release:
+ Non-Debug Version: 76.1K Code, 12.2K Data, 88.3K Total
+ Debug Version: 163.5K Code, 67.0K Data, 230.5K Total
+
+
+
+2) iASL Compiler/Disassembler:
+
+Relaxed a compiler restriction that disallowed a ResourceIndex byte if
+the
+corresponding ResourceSource string was not also present in a resource
+descriptor declaration. This restriction caused problems with existing
+AML/ASL code that includes the Index byte without the string. When such
+AML
+was disassembled, it could not be compiled without modification. Further,
+the modified code created a resource template with a different size than
+the
+original, breaking code that used fixed offsets into the resource
+template
+buffer.
+
+Removed a recent feature of the disassembler to ignore a lone
+ResourceIndex
+byte. This byte is now emitted if present so that the exact AML can be
+reproduced when the disassembled code is recompiled.
+
+Improved comments and text alignment for the resource descriptor code
+emitted by the disassembler.
+
+Implemented disassembler support for the ACPI 3.0 AccessSize field within
+a
+Register() resource descriptor.
+
+----------------------------------------
+30 September 2005. Summary of changes for version 20050930:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major overhaul of the Resource Manager code - specifically,
+optimizations in the area of the AML/internal resource conversion code.
+The
+code has been optimized to simplify and eliminate duplicated code, CPU
+stack
+use has been decreased by optimizing function parameters and local
+variables, and naming conventions across the manager have been
+standardized
+for clarity and ease of maintenance (this includes function, parameter,
+variable, and struct/typedef names.) The update may force changes in some
+driver code, depending on how resources are handled by the host OS.
+
+All Resource Manager dispatch and information tables have been moved to a
+single location for clarity and ease of maintenance. One new file was
+created, named "rsinfo.c".
+
+The ACPI return macros (return_ACPI_STATUS, etc.) have been modified to
+guarantee that the argument is not evaluated twice, making them less
+prone
+to macro side-effects. However, since there exists the possibility of
+additional stack use if a particular compiler cannot optimize them (such
+as
+in the debug generation case), the original macros are optionally
+available.
+Note that some invocations of the return_VALUE macro may now cause size
+mismatch warnings; the return_UINT8 and return_UINT32 macros are provided
+to
+eliminate these. (From Randy Dunlap)
+
+Implemented a new mechanism to enable debug tracing for individual
+control
+methods. A new external interface, AcpiDebugTrace, is provided to enable
+this mechanism. The intent is to allow the host OS to easily enable and
+disable tracing for problematic control methods. This interface can be
+easily exposed to a user or debugger interface if desired. See the file
+psxface.c for details.
+
+AcpiUtCallocate will now return a valid pointer if a length of zero is
+specified - a length of one is used and a warning is issued. This matches
+the behavior of AcpiUtAllocate.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.5K Code, 12.0K Data, 89.5K Total
+ Debug Version: 168.1K Code, 68.4K Data, 236.5K Total
+ Current Release:
+ Non-Debug Version: 77.1K Code, 12.1K Data, 89.2K Total
+ Debug Version: 168.0K Code, 68.3K Data, 236.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+A remark is issued if the effective compile-time length of a package or
+buffer is zero. Previously, this was a warning.
+
+----------------------------------------
+16 September 2005. Summary of changes for version 20050916:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem within the Resource Manager where support for the Generic
+Register descriptor was not fully implemented. This descriptor is now
+fully
+recognized, parsed, disassembled, and displayed.
+
+Completely restructured the Resource Manager code to utilize table-driven
+dispatch and lookup, eliminating many of the large switch() statements.
+This
+reduces overall subsystem code size and code complexity. Affects the
+resource parsing and construction, disassembly, and debug dump output.
+
+Cleaned up and restructured the debug dump output for all resource
+descriptors. Improved readability of the output and reduced code size.
+
+Fixed a problem where changes to internal data structures caused the
+optional ACPI_MUTEX_DEBUG code to fail compilation if specified.
+
+Code and Data Size: The current and previous library sizes for the core
+subsystem are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler.
+These
+values do not include any ACPI driver or OSPM code. The debug version of
+the
+code includes the debug output trace mechanism and has a much larger code
+and data size. Note that these values will vary depending on the
+efficiency
+of the compiler and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.4K Code, 11.8K Data, 90.2K Total
+ Debug Version: 169.6K Code, 69.9K Data, 239.5K Total
+ Current Release:
+ Non-Debug Version: 77.5K Code, 12.0K Data, 89.5K Total
+ Debug Version: 168.1K Code, 68.4K Data, 236.5K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Updated the disassembler to automatically insert an EndDependentFn()
+macro
+into the ASL stream if this macro is missing in the original AML code,
+simplifying compilation of the resulting ASL module.
+
+Fixed a problem in the disassembler where a disassembled ResourceSource
+string (within a large resource descriptor) was not surrounded by quotes
+and
+not followed by a comma, causing errors when the resulting ASL module was
+compiled. Also, escape sequences within a ResourceSource string are now
+handled correctly (especially "\\")
+
+----------------------------------------
+02 September 2005. Summary of changes for version 20050902:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem with the internal Owner ID allocation and deallocation
+mechanisms for control method execution and recursive method invocation.
+This should eliminate the OWNER_ID_LIMIT exceptions and "Invalid OwnerId"
+messages seen on some systems. Recursive method invocation depth is
+currently limited to 255. (Alexey Starikovskiy)
+
+Completely eliminated all vestiges of support for the "module-level
+executable code" until this support is fully implemented and debugged.
+This
+should eliminate the NO_RETURN_VALUE exceptions seen during table load on
+some systems that invoke this support.
+
+Fixed a problem within the resource manager code where the transaction
+flags
+for a 64-bit address descriptor were handled incorrectly in the type-
+specific flag byte.
+
+Consolidated duplicate code within the address descriptor resource
+manager
+code, reducing overall subsystem code size.
+
+Fixed a fault when using the AML debugger "disassemble" command to
+disassemble individual control methods.
+
+Removed references to the "release_current" directory within the Unix
+release package.
+
+Code and Data Size: The current and previous core subsystem library sizes
+are shown below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler. These values do not
+include any ACPI driver or OSPM code. The debug version of the code
+includes
+the debug output trace mechanism and has a much larger code and data
+size.
+Note that these values will vary depending on the efficiency of the
+compiler
+and the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.6K Code, 11.7K Data, 90.3K Total
+ Debug Version: 170.0K Code, 69.9K Data, 239.9K Total
+ Current Release:
+ Non-Debug Version: 78.4K Code, 11.8K Data, 90.2K Total
+ Debug Version: 169.6K Code, 69.9K Data, 239.5K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented an error check for illegal duplicate values in the interrupt
+and
+dma lists for the following ASL macros: Dma(), Irq(), IrqNoFlags(), and
+Interrupt().
+
+Implemented error checking for the Irq() and IrqNoFlags() macros to
+detect
+too many values in the interrupt list (16 max) and invalid values in the
+list (range 0 - 15)
+
+The maximum length string literal within an ASL file is now restricted to
+200 characters as per the ACPI specification.
+
+Fixed a fault when using the -ln option (generate namespace listing).
+
+Implemented an error check to determine if a DescriptorName within a
+resource descriptor has already been used within the current scope.
+
+----------------------------------------
+15 August 2005. Summary of changes for version 20050815:
+
+1) ACPI CA Core Subsystem:
+
+Implemented a full bytewise compare to determine if a table load request
+is
+attempting to load a duplicate table. The compare is performed if the
+table
+signatures and table lengths match. This will allow different tables with
+the same OEM Table ID and revision to be loaded - probably against the
+ACPI
+specification, but discovered in the field nonetheless.
+
+Added the changes.txt logfile to each of the zipped release packages.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.6K Code, 11.7K Data, 90.3K Total
+ Debug Version: 167.0K Code, 69.9K Data, 236.9K Total
+ Current Release:
+ Non-Debug Version: 78.6K Code, 11.7K Data, 90.3K Total
+ Debug Version: 170.0K Code, 69.9K Data, 239.9K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem where incorrect AML code could be generated for Package
+objects if optimization is disabled (via the -oa switch).
+
+Fixed a problem with where incorrect AML code is generated for variable-
+length packages when the package length is not specified and the number
+of
+initializer values is greater than 255.
+
+
+----------------------------------------
+29 July 2005. Summary of changes for version 20050729:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support to ignore an attempt to install/load a particular
+ACPI
+table more than once. Apparently there exists BIOS code that repeatedly
+attempts to load the same SSDT upon certain events. With assistance from
+Venkatesh Pallipadi.
+
+Restructured the main interface to the AML parser in order to correctly
+handle all exceptional conditions. This will prevent leakage of the
+OwnerId
+resource and should eliminate the AE_OWNER_ID_LIMIT exceptions seen on
+some
+machines. With assistance from Alexey Starikovskiy.
+
+Support for "module level code" has been disabled in this version due to
+a
+number of issues that have appeared on various machines. The support can
+be
+enabled by defining ACPI_ENABLE_MODULE_LEVEL_CODE during subsystem
+compilation. When the issues are fully resolved, the code will be enabled
+by
+default again.
+
+Modified the internal functions for debug print support to define the
+FunctionName parameter as a (const char *) for compatibility with
+compiler
+built-in macros such as __FUNCTION__, etc.
+
+Linted the entire ACPICA source tree for both 32-bit and 64-bit.
+
+Implemented support to display an object count summary for the AML
+Debugger
+commands Object and Methods.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.6K Code, 11.6K Data, 90.2K Total
+ Debug Version: 170.0K Code, 69.7K Data, 239.7K Total
+ Current Release:
+ Non-Debug Version: 78.6K Code, 11.7K Data, 90.3K Total
+ Debug Version: 167.0K Code, 69.9K Data, 236.9K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a regression that appeared in the 20050708 version of the compiler
+where an error message was inadvertently emitted for invocations of the
+_OSI
+reserved control method.
+
+----------------------------------------
+08 July 2005. Summary of changes for version 20050708:
+
+1) ACPI CA Core Subsystem:
+
+The use of the CPU stack in the debug version of the subsystem has been
+considerably reduced. Previously, a debug structure was declared in every
+function that used the debug macros. This structure has been removed in
+favor of declaring the individual elements as parameters to the debug
+functions. This reduces the cumulative stack use during nested execution
+of
+ACPI function calls at the cost of a small increase in the code size of
+the
+debug version of the subsystem. With assistance from Alexey Starikovskiy
+and
+Len Brown.
+
+Added the ACPI_GET_FUNCTION_NAME macro to enable the compiler-dependent
+headers to define a macro that will return the current function name at
+runtime (such as __FUNCTION__ or _func_, etc.) The function name is used
+by
+the debug trace output. If ACPI_GET_FUNCTION_NAME is not defined in the
+compiler-dependent header, the function name is saved on the CPU stack
+(one
+pointer per function.) This mechanism is used because apparently there
+exists no standard ANSI-C defined macro that that returns the function
+name.
+
+Redesigned and reimplemented the "Owner ID" mechanism used to track
+namespace objects created/deleted by ACPI tables and control method
+execution. A bitmap is now used to allocate and free the IDs, thus
+solving
+the wraparound problem present in the previous implementation. The size
+of
+the namespace node descriptor was reduced by 2 bytes as a result (Alexey
+Starikovskiy).
+
+Removed the UINT32_BIT and UINT16_BIT types that were used for the
+bitfield
+flag definitions within the headers for the predefined ACPI tables. These
+have been replaced by UINT8_BIT in order to increase the code portability
+of
+the subsystem. If the use of UINT8 remains a problem, we may be forced to
+eliminate bitfields entirely because of a lack of portability.
+
+Enhanced the performance of the AcpiUtUpdateObjectReference procedure.
+This
+is a frequently used function and this improvement increases the
+performance
+of the entire subsystem (Alexey Starikovskiy).
+
+Fixed several possible memory leaks and the inverse - premature object
+deletion (Alexey Starikovskiy).
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.6K Code, 11.5K Data, 90.1K Total
+ Debug Version: 165.2K Code, 69.6K Data, 234.8K Total
+ Current Release:
+ Non-Debug Version: 78.6K Code, 11.6K Data, 90.2K Total
+ Debug Version: 170.0K Code, 69.7K Data, 239.7K Total
+
+----------------------------------------
+24 June 2005. Summary of changes for version 20050624:
+
+1) ACPI CA Core Subsystem:
+
+Modified the new OSL cache interfaces to use ACPI_CACHE_T as the type for
+the host-defined cache object. This allows the OSL implementation to
+define
+and type this object in any manner desired, simplifying the OSL
+implementation. For example, ACPI_CACHE_T is defined as kmem_cache_t for
+Linux, and should be defined in the OS-specific header file for other
+operating systems as required.
+
+Changed the interface to AcpiOsAcquireObject to directly return the
+requested object as the function return (instead of ACPI_STATUS.) This
+change was made for performance reasons, since this is the purpose of the
+interface in the first place. AcpiOsAcquireObject is now similar to the
+AcpiOsAllocate interface.
+
+Implemented a new AML debugger command named Businfo. This command
+displays
+information about all devices that have an associate _PRT object. The
+_ADR,
+_HID, _UID, and _CID are displayed for these devices.
+
+Modified the initialization sequence in AcpiInitializeSubsystem to call
+the
+OSL interface AcpiOslInitialize first, before any local initialization.
+This
+change was required because the global initialization now calls OSL
+interfaces.
+
+Enhanced the Dump command to display the entire contents of Package
+objects
+(including all sub-objects and their values.)
+
+Restructured the code base to split some files because of size and/or
+because the code logically belonged in a separate file. New files are
+listed
+below. All makefiles and project files included in the ACPI CA release
+have
+been updated.
+ utilities/utcache.c /* Local cache interfaces */
+ utilities/utmutex.c /* Local mutex support */
+ utilities/utstate.c /* State object support */
+ interpreter/parser/psloop.c /* Main AML parse loop */
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 11.6K Data, 89.9K Total
+ Debug Version: 164.0K Code, 69.1K Data, 233.1K Total
+ Current Release:
+ Non-Debug Version: 78.6K Code, 11.5K Data, 90.1K Total
+ Debug Version: 165.2K Code, 69.6K Data, 234.8K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a regression introduced in version 20050513 where the use of a
+Package
+object within a Case() statement caused a compile time exception. The
+original behavior has been restored (a Match() operator is emitted.)
+
+----------------------------------------
+17 June 2005. Summary of changes for version 20050617:
+
+1) ACPI CA Core Subsystem:
+
+Moved the object cache operations into the OS interface layer (OSL) to
+allow
+the host OS to handle these operations if desired (for example, the Linux
+OSL will invoke the slab allocator). This support is optional; the
+compile
+time define ACPI_USE_LOCAL_CACHE may be used to utilize the original
+cache
+code in the ACPI CA core. The new OSL interfaces are shown below. See
+utalloc.c for an example implementation, and acpiosxf.h for the exact
+interface definitions. With assistance from Alexey Starikovskiy.
+ AcpiOsCreateCache
+ AcpiOsDeleteCache
+ AcpiOsPurgeCache
+ AcpiOsAcquireObject
+ AcpiOsReleaseObject
+
+Modified the interfaces to AcpiOsAcquireLock and AcpiOsReleaseLock to
+return
+and restore a flags parameter. This fits better with many OS lock models.
+Note: the current execution state (interrupt handler or not) is no longer
+passed to these interfaces. If necessary, the OSL must determine this
+state
+by itself, a simple and fast operation. With assistance from Alexey
+Starikovskiy.
+
+Fixed a problem in the ACPI table handling where a valid XSDT was assumed
+present if the revision of the RSDP was 2 or greater. According to the
+ACPI
+specification, the XSDT is optional in all cases, and the table manager
+therefore now checks for both an RSDP >=2 and a valid XSDT pointer.
+Otherwise, the RSDT pointer is used. Some ACPI 2.0 compliant BIOSs
+contain
+only the RSDT.
+
+Fixed an interpreter problem with the Mid() operator in the case of an
+input
+string where the resulting output string is of zero length. It now
+correctly
+returns a valid, null terminated string object instead of a string object
+with a null pointer.
+
+Fixed a problem with the control method argument handling to allow a
+store
+to an Arg object that already contains an object of type Device. The
+Device
+object is now correctly overwritten. Previously, an error was returned.
+
+
+Enhanced the debugger Find command to emit object values in addition to
+the
+found object pathnames. The output format is the same as the dump
+namespace
+command.
+
+Enhanced the debugger Set command. It now has the ability to set the
+value
+of any Named integer object in the namespace (Previously, only method
+locals
+and args could be set.)
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.1K Code, 11.6K Data, 89.7K Total
+ Debug Version: 164.0K Code, 69.3K Data, 233.3K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 11.6K Data, 89.9K Total
+ Debug Version: 164.0K Code, 69.1K Data, 233.1K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a regression in the disassembler where if/else/while constructs
+were
+output incorrectly. This problem was introduced in the previous release
+(20050526). This problem also affected the single-step disassembly in the
+debugger.
+
+Fixed a problem where compiling the reserved _OSI method would randomly
+(but
+rarely) produce compile errors.
+
+Enhanced the disassembler to emit compilable code in the face of
+incorrect
+AML resource descriptors. If the optional ResourceSourceIndex is present,
+but the ResourceSource is not, do not emit the ResourceSourceIndex in the
+disassembly. Otherwise, the resulting code cannot be compiled without
+errors.
+
+----------------------------------------
+26 May 2005. Summary of changes for version 20050526:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support to execute Type 1 and Type 2 AML opcodes appearing at
+the module level (not within a control method.) These opcodes are
+executed
+exactly once at the time the table is loaded. This type of code was legal
+up
+until the release of ACPI 2.0B (2002) and is now supported within ACPI CA
+in
+order to provide backwards compatibility with earlier BIOS
+implementations.
+This eliminates the "Encountered executable code at module level" warning
+that was previously generated upon detection of such code.
+
+Fixed a problem in the interpreter where an AE_NOT_FOUND exception could
+inadvertently be generated during the lookup of namespace objects in the
+second pass parse of ACPI tables and control methods. It appears that
+this
+problem could occur during the resolution of forward references to
+namespace
+objects.
+
+Added the ACPI_MUTEX_DEBUG #ifdef to the AcpiUtReleaseMutex function,
+corresponding to the same #ifdef in the AcpiUtAcquireMutex function. This
+allows the deadlock detection debug code to be compiled out in the normal
+case, improving mutex performance (and overall subsystem performance)
+considerably.
+
+Implemented a handful of miscellaneous fixes for possible memory leaks on
+error conditions and error handling control paths. These fixes were
+suggested by FreeBSD and the Coverity Prevent source code analysis tool.
+
+Added a check for a null RSDT pointer in AcpiGetFirmwareTable
+(tbxfroot.c)
+to prevent a fault in this error case.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.2K Code, 11.6K Data, 89.8K Total
+ Debug Version: 163.7K Code, 69.3K Data, 233.0K Total
+ Current Release:
+ Non-Debug Version: 78.1K Code, 11.6K Data, 89.7K Total
+ Debug Version: 164.0K Code, 69.3K Data, 233.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support to allow Type 1 and Type 2 ASL operators to appear at
+the module level (not within a control method.) These operators will be
+executed once at the time the table is loaded. This type of code was
+legal
+up until the release of ACPI 2.0B (2002) and is now supported by the iASL
+compiler in order to provide backwards compatibility with earlier BIOS
+ASL
+code.
+
+The ACPI integer width (specified via the table revision ID or the -r
+override, 32 or 64 bits) is now used internally during compile-time
+constant
+folding to ensure that constants are truncated to 32 bits if necessary.
+Previously, the revision ID value was only emitted in the AML table
+header.
+
+An error message is now generated for the Mutex and Method operators if
+the
+SyncLevel parameter is outside the legal range of 0 through 15.
+
+Fixed a problem with the Method operator ParameterTypes list handling
+(ACPI
+3.0). Previously, more than 2 types or 2 arguments generated a syntax
+error.
+The actual underlying implementation of method argument typechecking is
+still under development, however.
+
+----------------------------------------
+13 May 2005. Summary of changes for version 20050513:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for PCI Express root bridges -- added support for
+device
+PNP0A08 in the root bridge search within AcpiEvPciConfigRegionSetup.
+
+The interpreter now automatically truncates incoming 64-bit constants to
+32
+bits if currently executing out of a 32-bit ACPI table (Revision < 2).
+This
+also affects the iASL compiler constant folding. (Note: as per below, the
+iASL compiler no longer allows 64-bit constants within 32-bit tables.)
+
+Fixed a problem where string and buffer objects with "static" pointers
+(pointers to initialization data within an ACPI table) were not handled
+consistently. The internal object copy operation now always copies the
+data
+to a newly allocated buffer, regardless of whether the source object is
+static or not.
+
+Fixed a problem with the FromBCD operator where an implicit result
+conversion was improperly performed while storing the result to the
+target
+operand. Since this is an "explicit conversion" operator, the implicit
+conversion should never be performed on the output.
+
+Fixed a problem with the CopyObject operator where a copy to an existing
+named object did not always completely overwrite the existing object
+stored
+at name. Specifically, a buffer-to-buffer copy did not delete the
+existing
+buffer.
+
+Replaced "InterruptLevel" with "InterruptNumber" in all GPE interfaces
+and
+structs for consistency.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.2K Code, 11.6K Data, 89.8K Total
+ Debug Version: 163.7K Code, 69.3K Data, 233.0K Total
+ Current Release: (Same sizes)
+ Non-Debug Version: 78.2K Code, 11.6K Data, 89.8K Total
+ Debug Version: 163.7K Code, 69.3K Data, 233.0K Total
+
+
+2) iASL Compiler/Disassembler:
+
+The compiler now emits a warning if an attempt is made to generate a 64-
+bit
+integer constant from within a 32-bit ACPI table (Revision < 2). The
+integer
+is truncated to 32 bits.
+
+Fixed a problem with large package objects: if the static length of the
+package is greater than 255, the "variable length package" opcode is
+emitted. Previously, this caused an error. This requires an update to the
+ACPI spec, since it currently (incorrectly) states that packages larger
+than
+255 elements are not allowed.
+
+The disassembler now correctly handles variable length packages and
+packages
+larger than 255 elements.
+
+----------------------------------------
+08 April 2005. Summary of changes for version 20050408:
+
+1) ACPI CA Core Subsystem:
+
+Fixed three cases in the interpreter where an "index" argument to an ASL
+function was still (internally) 32 bits instead of the required 64 bits.
+This was the Index argument to the Index, Mid, and Match operators.
+
+The "strupr" function is now permanently local (AcpiUtStrupr), since this
+is
+not a POSIX-defined function and not present in most kernel-level C
+libraries. All references to the C library strupr function have been
+removed
+from the headers.
+
+Completed the deployment of static functions/prototypes. All prototypes
+with
+the static attribute have been moved from the headers to the owning C
+file.
+
+Implemented an extract option (-e) for the AcpiBin utility (AML binary
+utility). This option allows the utility to extract individual ACPI
+tables
+from the output of AcpiDmp. It provides the same functionality of the
+acpixtract.pl perl script without the worry of setting the correct perl
+options. AcpiBin runs on Windows and has not yet been generated/validated
+in
+the Linux/Unix environment (but should be soon).
+
+Updated and fixed the table dump option for AcpiBin (-d). This option
+converts a single ACPI table to a hex/ascii file, similar to the output
+of
+AcpiDmp.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 11.6K Data, 89.6K Total
+ Debug Version: 163.5K Code, 69.3K Data, 232.8K Total
+ Current Release:
+ Non-Debug Version: 78.2K Code, 11.6K Data, 89.8K Total
+ Debug Version: 163.7K Code, 69.3K Data, 233.0K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Disassembler fix: Added a check to ensure that the table length found in
+the
+ACPI table header within the input file is not longer than the actual
+input
+file size. This indicates some kind of file or table corruption.
+
+----------------------------------------
+29 March 2005. Summary of changes for version 20050329:
+
+1) ACPI CA Core Subsystem:
+
+An error is now generated if an attempt is made to create a Buffer Field
+of
+length zero (A CreateField with a length operand of zero.)
+
+The interpreter now issues a warning whenever executable code at the
+module
+level is detected during ACPI table load. This will give some idea of the
+prevalence of this type of code.
+
+Implemented support for references to named objects (other than control
+methods) within package objects.
+
+Enhanced package object output for the debug object. Package objects are
+now
+completely dumped, showing all elements.
+
+Enhanced miscellaneous object output for the debug object. Any object can
+now be written to the debug object (for example, a device object can be
+written, and the type of the object will be displayed.)
+
+The "static" qualifier has been added to all local functions across both
+the
+core subsystem and the iASL compiler.
+
+The number of "long" lines (> 80 chars) within the source has been
+significantly reduced, by about 1/3.
+
+Cleaned up all header files to ensure that all CA/iASL functions are
+prototyped (even static functions) and the formatting is consistent.
+
+Two new header files have been added, acopcode.h and acnames.h.
+
+Removed several obsolete functions that were no longer used.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.4K Code, 69.7K Data, 236.1K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 11.6K Data, 89.6K Total
+ Debug Version: 163.5K Code, 69.3K Data, 232.8K Total
+
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with the resource descriptor generation/support. For the
+ResourceSourceIndex and the ResourceSource fields, both must be present,
+or
+both must be not present - can't have one without the other.
+
+The compiler now returns non-zero from the main procedure if any errors
+have
+occurred during the compilation.
+
+
+----------------------------------------
+09 March 2005. Summary of changes for version 20050309:
+
+1) ACPI CA Core Subsystem:
+
+The string-to-buffer implicit conversion code has been modified again
+after
+a change to the ACPI specification. In order to match the behavior of
+the
+other major ACPI implementation, the target buffer is no longer truncated
+if
+the source string is smaller than an existing target buffer. This change
+requires an update to the ACPI spec, and should eliminate the recent
+AE_AML_BUFFER_LIMIT issues.
+
+The "implicit return" support was rewritten to a new algorithm that
+solves
+the general case. Rather than attempt to determine when a method is about
+to
+exit, the result of every ASL operator is saved momentarily until the
+very
+next ASL operator is executed. Therefore, no matter how the method exits,
+there will always be a saved implicit return value. This feature is only
+enabled with the AcpiGbl_EnableInterpreterSlack flag, and should
+eliminate
+AE_AML_NO_RETURN_VALUE errors when enabled.
+
+Implemented implicit conversion support for the predicate (operand) of
+the
+If, Else, and While operators. String and Buffer arguments are
+automatically
+converted to Integers.
+
+Changed the string-to-integer conversion behavior to match the new ACPI
+errata: "If no integer object exists, a new integer is created. The ASCII
+string is interpreted as a hexadecimal constant. Each string character is
+interpreted as a hexadecimal value ('0'-'9', 'A'-'F', 'a', 'f'), starting
+with the first character as the most significant digit, and ending with
+the
+first non-hexadecimal character or end-of-string." This means that the
+first
+non-hex character terminates the conversion and this is the code that was
+changed.
+
+Fixed a problem where the ObjectType operator would fail (fault) when
+used
+on an Index of a Package which pointed to a null package element. The
+operator now properly returns zero (Uninitialized) in this case.
+
+Fixed a problem where the While operator used excessive memory by not
+properly popping the result stack during execution. There was no memory
+leak
+after execution, however. (Code provided by Valery Podrezov.)
+
+Fixed a problem where references to control methods within Package
+objects
+caused the method to be invoked, instead of producing a reference object
+pointing to the method.
+
+Restructured and simplified the pswalk.c module (AcpiPsDeleteParseTree)
+to
+improve performance and reduce code size. (Code provided by Alexey
+Starikovskiy.)
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.4K Code, 69.6K Data, 236.0K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.4K Code, 69.7K Data, 236.1K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with the Return operator with no arguments. Since the AML
+grammar for the byte encoding requires an operand for the Return opcode,
+the
+compiler now emits a Return(Zero) for this case. An ACPI specification
+update has been written for this case.
+
+For tables other than the DSDT, namepath optimization is automatically
+disabled. This is because SSDTs can be loaded anywhere in the namespace,
+the
+compiler has no knowledge of where, and thus cannot optimize namepaths.
+
+Added "ProcessorObj" to the ObjectTypeKeyword list. This object type was
+inadvertently omitted from the ACPI specification, and will require an
+update to the spec.
+
+The source file scan for ASCII characters is now optional (-a). This
+change
+was made because some vendors place non-ascii characters within comments.
+However, the scan is simply a brute-force byte compare to ensure all
+characters in the file are in the range 0x00 to 0x7F.
+
+Fixed a problem with the CondRefOf operator where the compiler was
+inappropriately checking for the existence of the target. Since the point
+of
+the operator is to check for the existence of the target at run-time, the
+compiler no longer checks for the target existence.
+
+Fixed a problem where errors generated from the internal AML interpreter
+during constant folding were not handled properly, causing a fault.
+
+Fixed a problem with overly aggressive range checking for the Stall
+operator. The valid range (max 255) is now only checked if the operand is
+of
+type Integer. All other operand types cannot be statically checked.
+
+Fixed a problem where control method references within the RefOf,
+DeRefOf,
+and ObjectType operators were not treated properly. They are now treated
+as
+actual references, not method invocations.
+
+Fixed and enhanced the "list namespace" option (-ln). This option was
+broken
+a number of releases ago.
+
+Improved error handling for the Field, IndexField, and BankField
+operators.
+The compiler now cleanly reports and recovers from errors in the field
+component (FieldUnit) list.
+
+Fixed a disassembler problem where the optional ResourceDescriptor fields
+TRS and TTP were not always handled correctly.
+
+Disassembler - Comments in output now use "//" instead of "/*"
+
+----------------------------------------
+28 February 2005. Summary of changes for version 20050228:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where the result of an Index() operator (an object
+reference) must increment the reference count on the target object for
+the
+life of the object reference.
+
+Implemented AML Interpreter and Debugger support for the new ACPI 3.0
+Extended Address (IO, Memory, Space), QwordSpace, DwordSpace, and
+WordSpace
+resource descriptors.
+
+Implemented support in the _OSI method for the ACPI 3.0 "Extended Address
+Space Descriptor" string, indicating interpreter support for the
+descriptors
+above.
+
+Implemented header support for the new ACPI 3.0 FADT flag bits.
+
+Implemented header support for the new ACPI 3.0 PCI Express bits for the
+PM1
+status/enable registers.
+
+Updated header support for the MADT processor local Apic struct and MADT
+platform interrupt source struct for new ACPI 3.0 fields.
+
+Implemented header support for the SRAT and SLIT ACPI tables.
+
+Implemented the -s switch in AcpiExec to enable the "InterpreterSlack"
+flag
+at runtime.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.2K Code, 11.5K Data, 89.7K Total
+ Debug Version: 164.9K Code, 69.2K Data, 234.1K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.4K Code, 69.6K Data, 236.0K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with the internal 64-bit String-to-integer conversion
+with
+strings less than two characters long.
+
+Fixed a problem with constant folding where the result of the Index()
+operator can not be considered a constant. This means that Index() cannot
+be
+a type3 opcode and this will require an update to the ACPI specification.
+
+Disassembler: Implemented support for the TTP, MTP, and TRS resource
+descriptor fields. These fields were inadvertently ignored and not output
+in
+the disassembly of the resource descriptor.
+
+
+ ----------------------------------------
+11 February 2005. Summary of changes for version 20050211:
+
+1) ACPI CA Core Subsystem:
+
+Implemented ACPI 3.0 support for implicit conversion within the Match()
+operator. MatchObjects can now be of type integer, buffer, or string
+instead
+of just type integer. Package elements are implicitly converted to the
+type
+of the MatchObject. This change aligns the behavior of Match() with the
+behavior of the other logical operators (LLess(), etc.) It also requires
+an
+errata change to the ACPI specification as this support was intended for
+ACPI 3.0, but was inadvertently omitted.
+
+Fixed a problem with the internal implicit "to buffer" conversion.
+Strings
+that are converted to buffers will cause buffer truncation if the string
+is
+smaller than the target buffer. Integers that are converted to buffers
+will
+not cause buffer truncation, only zero extension (both as per the ACPI
+spec.) The problem was introduced when code was added to truncate the
+buffer, but this should not be performed in all cases, only the string
+case.
+
+Fixed a problem with the Buffer and Package operators where the
+interpreter
+would get confused if two such operators were used as operands to an ASL
+operator (such as LLess(Buffer(1){0},Buffer(1){1}). The internal result
+stack was not being popped after the execution of these operators,
+resulting
+in an AE_NO_RETURN_VALUE exception.
+
+Fixed a problem with constructs of the form Store(Index(...),...). The
+reference object returned from Index was inadvertently resolved to an
+actual
+value. This problem was introduced in version 20050114 when the behavior
+of
+Store() was modified to restrict the object types that can be used as the
+source operand (to match the ACPI specification.)
+
+Reduced excessive stack use within the AcpiGetObjectInfo procedure.
+
+Added a fix to aclinux.h to allow generation of AcpiExec on Linux.
+
+Updated the AcpiSrc utility to add the FADT_DESCRIPTOR_REV2_MINUS struct.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.1K Code, 11.5K Data, 89.6K Total
+ Debug Version: 164.8K Code, 69.2K Data, 234.0K Total
+ Current Release:
+ Non-Debug Version: 78.2K Code, 11.5K Data, 89.7K Total
+ Debug Version: 164.9K Code, 69.2K Data, 234.1K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a code generation problem in the constant folding optimization code
+where incorrect code was generated if a constant was reduced to a buffer
+object (i.e., a reduced type 5 opcode.)
+
+Fixed a typechecking problem for the ToBuffer operator. Caused by an
+incorrect return type in the internal opcode information table.
+
+----------------------------------------
+25 January 2005. Summary of changes for version 20050125:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a recently introduced problem with the Global Lock where the
+underlying semaphore was not created. This problem was introduced in
+version 20050114, and caused an AE_AML_NO_OPERAND exception during an
+Acquire() operation on _GL.
+
+The local object cache is now optional, and is disabled by default. Both
+AcpiExec and the iASL compiler enable the cache because they run in user
+mode and this enhances their performance. #define
+ACPI_ENABLE_OBJECT_CACHE
+to enable the local cache.
+
+Fixed an issue in the internal function AcpiUtEvaluateObject concerning
+the
+optional "implicit return" support where an error was returned if no
+return
+object was expected, but one was implicitly returned. AE_OK is now
+returned
+in this case and the implicitly returned object is deleted.
+AcpiUtEvaluateObject is only occasionally used, and only to execute
+reserved
+methods such as _STA and _INI where the return type is known up front.
+
+Fixed a few issues with the internal convert-to-integer code. It now
+returns
+an error if an attempt is made to convert a null string, a string of only
+blanks/tabs, or a zero-length buffer. This affects both implicit
+conversion
+and explicit conversion via the ToInteger() operator.
+
+The internal debug code in AcpiUtAcquireMutex has been commented out. It
+is
+not needed for normal operation and should increase the performance of
+the
+entire subsystem. The code remains in case it is needed for debug
+purposes
+again.
+
+The AcpiExec source and makefile are included in the Unix/Linux package
+for
+the first time.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.4K Code, 11.5K Data, 89.9K Total
+ Debug Version: 165.4K Code, 69.4K Data, 234.8K Total
+ Current Release:
+ Non-Debug Version: 78.1K Code, 11.5K Data, 89.6K Total
+ Debug Version: 164.8K Code, 69.2K Data, 234.0K Total
+
+2) iASL Compiler/Disassembler:
+
+Switch/Case support: A warning is now issued if the type of the Switch
+value
+cannot be determined at compile time. For example, Switch(Arg0) will
+generate the warning, and the type is assumed to be an integer. As per
+the
+ACPI spec, use a construct such as Switch(ToInteger(Arg0)) to eliminate
+the
+warning.
+
+Switch/Case support: Implemented support for buffer and string objects as
+the switch value. This is an ACPI 3.0 feature, now that LEqual supports
+buffers and strings.
+
+Switch/Case support: The emitted code for the LEqual() comparisons now
+uses
+the switch value as the first operand, not the second. The case value is
+now
+the second operand, and this allows the case value to be implicitly
+converted to the type of the switch value, not the other way around.
+
+Switch/Case support: Temporary variables are now emitted immediately
+within
+the control method, not at the global level. This means that there are
+now
+36 temps available per-method, not 36 temps per-module as was the case
+with
+the earlier implementation (_T_0 through _T_9 and _T_A through _T_Z.)
+
+----------------------------------------
+14 January 2005. Summary of changes for version 20050114:
+
+Added 2005 copyright to all module headers. This affects every module in
+the core subsystem, iASL compiler, and the utilities.
+
+1) ACPI CA Core Subsystem:
+
+Fixed an issue with the String-to-Buffer conversion code where the string
+null terminator was not included in the buffer after conversion, but
+there
+is existing ASL that assumes the string null terminator is included. This
+is
+the root of the ACPI_AML_BUFFER_LIMIT regression. This problem was
+introduced in the previous version when the code was updated to correctly
+set the converted buffer size as per the ACPI specification. The ACPI
+spec
+is ambiguous and will be updated to specify that the null terminator must
+be
+included in the converted buffer. This also affects the ToBuffer() ASL
+operator.
+
+Fixed a problem with the Mid() ASL/AML operator where it did not work
+correctly on Buffer objects. Newly created sub-buffers were not being
+marked
+as initialized.
+
+
+Fixed a problem in AcpiTbFindTable where incorrect string compares were
+performed on the OemId and OemTableId table header fields. These fields
+are
+not null terminated, so strncmp is now used instead of strcmp.
+
+Implemented a restriction on the Store() ASL/AML operator to align the
+behavior with the ACPI specification. Previously, any object could be
+used
+as the source operand. Now, the only objects that may be used are
+Integers,
+Buffers, Strings, Packages, Object References, and DDB Handles. If
+necessary, the original behavior can be restored by enabling the
+EnableInterpreterSlack flag.
+
+Enhanced the optional "implicit return" support to allow an implicit
+return
+value from methods that are invoked externally via the AcpiEvaluateObject
+interface. This enables implicit returns from the _STA and _INI methods,
+for example.
+
+Changed the Revision() ASL/AML operator to return the current version of
+the
+AML interpreter, in the YYYYMMDD format. Previously, it incorrectly
+returned
+the supported ACPI version (This is the function of the _REV method).
+
+Updated the _REV predefined method to return the currently supported
+version
+of ACPI, now 3.
+
+Implemented batch mode option for the AcpiExec utility (-b).
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.3K Code, 69.4K Data, 234.7K Total
+ Current Release:
+ Non-Debug Version: 78.4K Code, 11.5K Data, 89.9K Total
+ Debug Version: 165.4K Code, 69.4K Data, 234.8K Total
+
+----------------------------------------
+10 December 2004. Summary of changes for version 20041210:
+
+ACPI 3.0 support is nearing completion in both the iASL compiler and the
+ACPI CA core subsystem.
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem in the ToDecimalString operator where the resulting
+string
+length was incorrectly calculated. The length is now calculated exactly,
+eliminating incorrect AE_STRING_LIMIT exceptions.
+
+Fixed a problem in the ToHexString operator to allow a maximum 200
+character
+string to be produced.
+
+Fixed a problem in the internal string-to-buffer and buffer-to-buffer
+copy
+routine where the length of the resulting buffer was not truncated to the
+new size (if the target buffer already existed).
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 164.7K Code, 68.5K Data, 233.2K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 165.3K Code, 69.4K Data, 234.7K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented the new ACPI 3.0 resource template macros - DWordSpace,
+ExtendedIO, ExtendedMemory, ExtendedSpace, QWordSpace, and WordSpace.
+Includes support in the disassembler.
+
+Implemented support for the new (ACPI 3.0) parameter to the Register
+macro,
+AccessSize.
+
+Fixed a problem where the _HE resource name for the Interrupt macro was
+referencing bit 0 instead of bit 1.
+
+Implemented check for maximum 255 interrupts in the Interrupt macro.
+
+Fixed a problem with the predefined resource descriptor names where
+incorrect AML code was generated if the offset within the resource buffer
+was 0 or 1. The optimizer shortened the AML code to a single byte opcode
+but did not update the surrounding package lengths.
+
+Changes to the Dma macro: All channels within the channel list must be
+in
+the range 0-7. Maximum 8 channels can be specified. BusMaster operand is
+optional (default is BusMaster).
+
+Implemented check for maximum 7 data bytes for the VendorShort macro.
+
+The ReadWrite parameter is now optional for the Memory32 and similar
+macros.
+
+----------------------------------------
+03 December 2004. Summary of changes for version 20041203:
+
+1) ACPI CA Core Subsystem:
+
+The low-level field insertion/extraction code (exfldio) has been
+completely
+rewritten to eliminate unnecessary complexity, bugs, and boundary
+conditions.
+
+Fixed a problem in the ToInteger, ToBuffer, ToHexString, and
+ToDecimalString
+operators where the input operand could be inadvertently deleted if no
+conversion was necessary (e.g., if the input to ToInteger was an Integer
+object.)
+
+Fixed a problem with the ToDecimalString and ToHexString where an
+incorrect
+exception code was returned if the resulting string would be > 200 chars.
+AE_STRING_LIMIT is now returned.
+
+Fixed a problem with the Concatenate operator where AE_OK was always
+returned, even if the operation failed.
+
+Fixed a problem in oswinxf (used by AcpiExec and iASL) to allow > 128
+semaphores to be allocated.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.5K Code, 11.5K Data, 90.0K Total
+ Debug Version: 165.2K Code, 68.6K Data, 233.8K Total
+ Current Release:
+ Non-Debug Version: 78.3K Code, 11.5K Data, 89.8K Total
+ Debug Version: 164.7K Code, 68.5K Data, 233.2K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed typechecking for the ObjectType and SizeOf operators. Problem was
+recently introduced in 20041119.
+
+Fixed a problem with the ToUUID macro where the upper nybble of each
+buffer
+byte was inadvertently set to zero.
+
+----------------------------------------
+19 November 2004. Summary of changes for version 20041119:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem in the internal ConvertToInteger routine where new
+integers
+were not truncated to 32 bits for 32-bit ACPI tables. This routine
+converts
+buffers and strings to integers.
+
+Implemented support to store a value to an Index() on a String object.
+This
+is an ACPI 2.0 feature that had not yet been implemented.
+
+Implemented new behavior for storing objects to individual package
+elements
+(via the Index() operator). The previous behavior was to invoke the
+implicit
+conversion rules if an object was already present at the index. The new
+behavior is to simply delete any existing object and directly store the
+new
+object. Although the ACPI specification seems unclear on this subject,
+other
+ACPI implementations behave in this manner. (This is the root of the
+AE_BAD_HEX_CONSTANT issue.)
+
+Modified the RSDP memory scan mechanism to support the extended checksum
+for
+ACPI 2.0 (and above) RSDPs. Note that the search continues until a valid
+RSDP signature is found with a valid checksum.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.5K Code, 11.5K Data, 90.0K Total
+ Debug Version: 165.2K Code, 68.6K Data, 233.8K Total
+ Current Release:
+ Non-Debug Version: 78.5K Code, 11.5K Data, 90.0K Total
+ Debug Version: 165.2K Code, 68.6K Data, 233.8K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a missing semicolon in the aslcompiler.y file.
+
+----------------------------------------
+05 November 2004. Summary of changes for version 20041105:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for FADT revision 2. This was an interim table
+(between
+ACPI 1.0 and ACPI 2.0) that adds support for the FADT reset register.
+
+Implemented optional support to allow uninitialized LocalX and ArgX
+variables in a control method. The variables are initialized to an
+Integer
+object with a value of zero. This support is enabled by setting the
+AcpiGbl_EnableInterpreterSlack flag to TRUE.
+
+Implemented support for Integer objects for the SizeOf operator. Either
+4
+or 8 is returned, depending on the current integer size (32-bit or 64-
+bit,
+depending on the parent table revision).
+
+Fixed a problem in the implementation of the SizeOf and ObjectType
+operators
+where the operand was resolved to a value too early, causing incorrect
+return values for some objects.
+
+Fixed some possible memory leaks during exceptional conditions.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 11.5K Data, 89.5K Total
+ Debug Version: 164.8K Code, 68.6K Data, 233.4K Total
+ Current Release:
+ Non-Debug Version: 78.5K Code, 11.5K Data, 90.0K Total
+ Debug Version: 165.2K Code, 68.6K Data, 233.8K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support for all ACPI 3.0 reserved names and methods.
+
+Implemented all ACPI 3.0 grammar elements in the front-end, including
+support for semicolons.
+
+Implemented the ACPI 3.0 Function() and ToUUID() macros
+
+Fixed a problem in the disassembler where a Scope() operator would not be
+emitted properly if the target of the scope was in another table.
+
+----------------------------------------
+15 October 2004. Summary of changes for version 20041015:
+
+Note: ACPI CA is currently undergoing an in-depth and complete formal
+evaluation to test/verify the following areas. Other suggestions are
+welcome. This will result in an increase in the frequency of releases and
+the number of bug fixes in the next few months.
+ - Functional tests for all ASL/AML operators
+ - All implicit/explicit type conversions
+ - Bit fields and operation regions
+ - 64-bit math support and 32-bit-only "truncated" math support
+ - Exceptional conditions, both compiler and interpreter
+ - Dynamic object deletion and memory leaks
+ - ACPI 3.0 support when implemented
+ - External interfaces to the ACPI subsystem
+
+
+1) ACPI CA Core Subsystem:
+
+Fixed two alignment issues on 64-bit platforms - within debug statements
+in
+AcpiEvGpeDetect and AcpiEvCreateGpeBlock. Removed references to the
+Address
+field within the non-aligned ACPI generic address structure.
+
+Fixed a problem in the Increment and Decrement operators where incorrect
+operand resolution could result in the inadvertent modification of the
+original integer when the integer is passed into another method as an
+argument and the arg is then incremented/decremented.
+
+Fixed a problem in the FromBCD operator where the upper 32-bits of a 64-
+bit
+BCD number were truncated during conversion.
+
+Fixed a problem in the ToDecimal operator where the length of the
+resulting
+string could be set incorrectly too long if the input operand was a
+Buffer
+object.
+
+Fixed a problem in the Logical operators (LLess, etc.) where a NULL byte
+(0)
+within a buffer would prematurely terminate a compare between buffer
+objects.
+
+Added a check for string overflow (>200 characters as per the ACPI
+specification) during the Concatenate operator with two string operands.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.8K Code, 11.5K Data, 89.3K Total
+ Debug Version: 164.6K Code, 68.5K Data, 233.1K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 11.5K Data, 89.5K Total
+ Debug Version: 164.8K Code, 68.6K Data, 233.4K Total
+
+
+
+2) iASL Compiler/Disassembler:
+
+Allow the use of the ObjectType operator on uninitialized Locals and Args
+(returns 0 as per the ACPI specification).
+
+Fixed a problem where the compiler would fault if there was a syntax
+error
+in the FieldName of all of the various CreateXXXField operators.
+
+Disallow the use of lower case letters within the EISAID macro, as per
+the
+ACPI specification. All EISAID strings must be of the form "UUUNNNN"
+Where
+U is an uppercase letter and N is a hex digit.
+
+
+----------------------------------------
+06 October 2004. Summary of changes for version 20041006:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for the ACPI 3.0 Timer operator. This ASL function
+implements a 64-bit timer with 100 nanosecond granularity.
+
+Defined a new OSL interface, AcpiOsGetTimer. This interface is used to
+implement the ACPI 3.0 Timer operator. This allows the host OS to
+implement
+the timer with the best clock available. Also, it keeps the core
+subsystem
+out of the clock handling business, since the host OS (usually) performs
+this function.
+
+Fixed an alignment issue on 64-bit platforms. The HwLowLevelRead(Write)
+functions use a 64-bit address which is part of the packed ACPI Generic
+Address Structure. Since the structure is non-aligned, the alignment
+macros
+are now used to extract the address to a local variable before use.
+
+Fixed a problem where the ToInteger operator assumed all input strings
+were
+hexadecimal. The operator now handles both decimal strings and hex
+strings
+(prefixed with "0x").
+
+Fixed a problem where the string length in the string object created as a
+result of the internal ConvertToString procedure could be incorrect. This
+potentially affected all implicit conversions and also the
+ToDecimalString
+and ToHexString operators.
+
+Fixed two problems in the ToString operator. If the length parameter was
+zero, an incorrect string object was created and the value of the input
+length parameter was inadvertently changed from zero to Ones.
+
+Fixed a problem where the optional ResourceSource string in the
+ExtendedIRQ
+resource macro was ignored.
+
+Simplified the interfaces to the internal division functions, reducing
+code
+size and complexity.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 11.4K Data, 89.3K Total
+ Debug Version: 164.5K Code, 68.3K Data, 232.8K Total
+ Current Release:
+ Non-Debug Version: 77.8K Code, 11.5K Data, 89.3K Total
+ Debug Version: 164.6K Code, 68.5K Data, 233.1K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support for the ACPI 3.0 Timer operator.
+
+Fixed a problem where the Default() operator was inadvertently ignored in
+a
+Switch/Case block. This was a problem in the translation of the Switch
+statement to If...Else pairs.
+
+Added support to allow a standalone Return operator, with no parentheses
+(or
+operands).
+
+Fixed a problem with code generation for the ElseIf operator where the
+translated Else...If parse tree was improperly constructed leading to the
+loss of some code.
+
+----------------------------------------
+22 September 2004. Summary of changes for version 20040922:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem with the implementation of the LNot() operator where
+"Ones"
+was not returned for the TRUE case. Changed the code to return Ones
+instead
+of (!Arg) which was usually 1. This change affects iASL constant folding
+for
+this operator also.
+
+Fixed a problem in AcpiUtInitializeBuffer where an existing buffer was
+not
+initialized properly -- Now zero the entire buffer in this case where the
+buffer already exists.
+
+Changed the interface to AcpiOsSleep from (UINT32 Seconds, UINT32
+Milliseconds) to simply (ACPI_INTEGER Milliseconds). This simplifies all
+related code considerably. This will require changes/updates to all OS
+interface layers (OSLs.)
+
+Implemented a new external interface, AcpiInstallExceptionHandler, to
+allow
+a system exception handler to be installed. This handler is invoked upon
+any
+run-time exception that occurs during control method execution.
+
+Added support for the DSDT in AcpiTbFindTable. This allows the
+DataTableRegion() operator to access the local copy of the DSDT.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.8K Code, 11.4K Data, 89.2K Total
+ Debug Version: 164.2K Code, 68.2K Data, 232.4K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 11.4K Data, 89.3K Total
+ Debug Version: 164.5K Code, 68.3K Data, 232.8K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem with constant folding and the LNot operator. LNot was
+returning 1 in the TRUE case, not Ones as per the ACPI specification.
+This
+could result in the generation of an incorrect folded/reduced constant.
+
+End-Of-File is now allowed within a "//"-style comment. A parse error no
+longer occurs if such a comment is at the very end of the input ASL
+source
+file.
+
+Implemented the "-r" option to override the Revision in the table header.
+The initial use of this option will be to simplify the evaluation of the
+AML
+interpreter by allowing a single ASL source module to be compiled for
+either
+32-bit or 64-bit integers.
+
+
+----------------------------------------
+27 August 2004. Summary of changes for version 20040827:
+
+1) ACPI CA Core Subsystem:
+
+- Implemented support for implicit object conversion in the non-numeric
+logical operators (LEqual, LGreater, LGreaterEqual, LLess, LLessEqual,
+and
+LNotEqual.) Any combination of Integers/Strings/Buffers may now be used;
+the second operand is implicitly converted on the fly to match the type
+of
+the first operand. For example:
+
+ LEqual (Source1, Source2)
+
+Source1 and Source2 must each evaluate to an integer, a string, or a
+buffer.
+The data type of Source1 dictates the required type of Source2. Source2
+is
+implicitly converted if necessary to match the type of Source1.
+
+- Updated and corrected the behavior of the string conversion support.
+The
+rules concerning conversion of buffers to strings (according to the ACPI
+specification) are as follows:
+
+ToDecimalString - explicit byte-wise conversion of buffer to string of
+decimal values (0-255) separated by commas. ToHexString - explicit byte-
+wise
+conversion of buffer to string of hex values (0-FF) separated by commas.
+ToString - explicit byte-wise conversion of buffer to string. Byte-by-
+byte
+copy with no transform except NULL terminated. Any other implicit buffer-
+to-
+string conversion - byte-wise conversion of buffer to string of hex
+values
+(0-FF) separated by spaces.
+
+- Fixed typo in definition of AcpiGbl_EnableInterpreterSlack.
+
+- Fixed a problem in AcpiNsGetPathnameLength where the returned length
+was
+one byte too short in the case of a node in the root scope. This could
+cause a fault during debug output.
+
+- Code and Data Size: Current and previous core subsystem library sizes
+are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.9K Code, 11.5K Data, 89.4K Total
+ Debug Version: 164.1K Code, 68.3K Data, 232.4K Total
+ Current Release:
+ Non-Debug Version: 77.8K Code, 11.4K Data, 89.2K Total
+ Debug Version: 164.2K Code, 68.2K Data, 232.4K Total
+
+
+2) iASL Compiler/Disassembler:
+
+- Fixed a Linux generation error.
+
+
+----------------------------------------
+16 August 2004. Summary of changes for version 20040816:
+
+1) ACPI CA Core Subsystem:
+
+Designed and implemented support within the AML interpreter for the so-
+called "implicit return". This support returns the result of the last
+ASL
+operation within a control method, in the absence of an explicit Return()
+operator. A few machines depend on this behavior, even though it is not
+explicitly supported by the ASL language. It is optional support that
+can
+be enabled at runtime via the AcpiGbl_EnableInterpreterSlack flag.
+
+Removed support for the PCI_Config address space from the internal low
+level
+hardware interfaces (AcpiHwLowLevelRead and AcpiHwLowLevelWrite). This
+support was not used internally, and would not work correctly anyway
+because
+the PCI bus number and segment number were not supported. There are
+separate interfaces for PCI configuration space access because of the
+unique
+interface.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 78.0K Code, 11.5K Data, 89.5K Total
+ Debug Version: 164.1K Code, 68.2K Data, 232.3K Total
+ Current Release:
+ Non-Debug Version: 77.9K Code, 11.5K Data, 89.4K Total
+ Debug Version: 164.1K Code, 68.3K Data, 232.4K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a problem where constants in ASL expressions at the root level (not
+within a control method) could be inadvertently truncated during code
+generation. This problem was introduced in the 20040715 release.
+
+
+----------------------------------------
+15 July 2004. Summary of changes for version 20040715:
+
+1) ACPI CA Core Subsystem:
+
+Restructured the internal HW GPE interfaces to pass/track the current
+state
+of interrupts (enabled/disabled) in order to avoid possible deadlock and
+increase flexibility of the interfaces.
+
+Implemented a "lexicographical compare" for String and Buffer objects
+within
+the logical operators -- LGreater, LLess, LGreaterEqual, and LLessEqual -
+-
+as per further clarification to the ACPI specification. Behavior is
+similar
+to C library "strcmp".
+
+Completed a major reduction in CPU stack use for the AcpiGetFirmwareTable
+external function. In the 32-bit non-debug case, the stack use has been
+reduced from 168 bytes to 32 bytes.
+
+Deployed a new run-time configuration flag,
+AcpiGbl_EnableInterpreterSlack,
+whose purpose is to allow the AML interpreter to forgive certain bad AML
+constructs. Default setting is FALSE.
+
+Implemented the first use of AcpiGbl_EnableInterpreterSlack in the Field
+IO
+support code. If enabled, it allows field access to go beyond the end of
+a
+region definition if the field is within the region length rounded up to
+the
+next access width boundary (a common coding error.)
+
+Renamed OSD_HANDLER to ACPI_OSD_HANDLER, and OSD_EXECUTION_CALLBACK to
+ACPI_OSD_EXEC_CALLBACK for consistency with other ACPI symbols. Also,
+these
+symbols are lowercased by the latest version of the AcpiSrc tool.
+
+The prototypes for the PCI interfaces in acpiosxf.h have been updated to
+rename "Register" to simply "Reg" to prevent certain compilers from
+complaining.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.8K Code, 11.5K Data, 89.3K Total
+ Debug Version: 163.8K Code, 68.2K Data, 232.0K Total
+ Current Release:
+ Non-Debug Version: 78.0K Code, 11.5K Data, 89.5K Total
+ Debug Version: 164.1K Code, 68.2K Data, 232.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented full support for Package objects within the Case() operator.
+Note: The Break() operator is currently not supported within Case blocks
+(TermLists) as there is some question about backward compatibility with
+ACPI
+1.0 interpreters.
+
+
+Fixed a problem where complex terms were not supported properly within
+the
+Switch() operator.
+
+Eliminated extraneous warning for compiler-emitted reserved names of the
+form "_T_x". (Used in Switch/Case operators.)
+
+Eliminated optimization messages for "_T_x" objects and small constants
+within the DefinitionBlock operator.
+
+
+----------------------------------------
+15 June 2004. Summary of changes for version 20040615:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for Buffer and String objects (as per ACPI 2.0) for
+the
+following ASL operators: LEqual, LGreater, LLess, LGreaterEqual, and
+LLessEqual.
+
+All directory names in the entire source package are lower case, as they
+were in earlier releases.
+
+Implemented "Disassemble" command in the AML debugger that will
+disassemble
+a single control method.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.7K Code, 11.5K Data, 89.2K Total
+ Debug Version: 163.3K Code, 67.2K Data, 230.5K Total
+
+ Current Release:
+ Non-Debug Version: 77.8K Code, 11.5K Data, 89.3K Total
+ Debug Version: 163.8K Code, 68.2K Data, 232.0K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Implemented support for Buffer and String objects (as per ACPI 2.0) for
+the
+following ASL operators: LEqual, LGreater, LLess, LGreaterEqual, and
+LLessEqual.
+
+All directory names in the entire source package are lower case, as they
+were in earlier releases.
+
+Fixed a fault when using the -g or -d<nofilename> options if the FADT was
+not found.
+
+Fixed an issue with the Windows version of the compiler where later
+versions
+of Windows place the FADT in the registry under the name "FADT" and not
+"FACP" as earlier versions did. This applies when using the -g or -
+d<nofilename> options. The compiler now looks for both strings as
+necessary.
+
+Fixed a problem with compiler namepath optimization where a namepath
+within
+the Scope() operator could not be optimized if the namepath was a subpath
+of
+the current scope path.
+
+----------------------------------------
+27 May 2004. Summary of changes for version 20040527:
+
+1) ACPI CA Core Subsystem:
+
+Completed a new design and implementation for EBDA (Extended BIOS Data
+Area)
+support in the RSDP scan code. The original code improperly scanned for
+the
+EBDA by simply scanning from memory location 0 to 0x400. The correct
+method
+is to first obtain the EBDA pointer from within the BIOS data area, then
+scan 1K of memory starting at the EBDA pointer. There appear to be few
+if
+any machines that place the RSDP in the EBDA, however.
+
+Integrated a fix for a possible fault during evaluation of BufferField
+arguments. Obsolete code that was causing the problem was removed.
+
+Found and fixed a problem in the Field Support Code where data could be
+corrupted on a bit field read that starts on an aligned boundary but does
+not end on an aligned boundary. Merged the read/write "datum length"
+calculation code into a common procedure.
+
+Rolled in a couple of changes to the FreeBSD-specific header.
+
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.6K Code, 11.5K Data, 89.1K Total
+ Debug Version: 163.2K Code, 67.2K Data, 230.4K Total
+ Current Release:
+ Non-Debug Version: 77.7K Code, 11.5K Data, 89.2K Total
+ Debug Version: 163.3K Code, 67.2K Data, 230.5K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Fixed a generation warning produced by some overly-verbose compilers for
+a
+64-bit constant.
+
+----------------------------------------
+14 May 2004. Summary of changes for version 20040514:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where hardware GPE enable bits sometimes not set properly
+during and after GPE method execution. Result of 04/27 changes.
+
+Removed extra "clear all GPEs" when sleeping/waking.
+
+Removed AcpiHwEnableGpe and AcpiHwDisableGpe, replaced by the single
+AcpiHwWriteGpeEnableReg. Changed a couple of calls to the functions above
+to
+the new AcpiEv* calls as appropriate.
+
+ACPI_OS_NAME was removed from the OS-specific headers. The default name
+is
+now "Microsoft Windows NT" for maximum compatibility. However this can
+be
+changed by modifying the acconfig.h file.
+
+Allow a single invocation of AcpiInstallNotifyHandler for a handler that
+traps both types of notifies (System, Device). Use ACPI_ALL_NOTIFY flag.
+
+Run _INI methods on ThermalZone objects. This is against the ACPI
+specification, but there is apparently ASL code in the field that has
+these
+_INI methods, and apparently "other" AML interpreters execute them.
+
+Performed a full 16/32/64 bit lint that resulted in some small changes.
+
+Added a sleep simulation command to the AML debugger to test sleep code.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.6K Code, 11.5K Data, 89.1K Total
+ Debug Version: 162.9K Code, 67.0K Data, 229.9K Total
+ Current Release:
+ Non-Debug Version: 77.6K Code, 11.5K Data, 89.1K Total
+ Debug Version: 163.2K Code, 67.2K Data, 230.4K Total
+
+----------------------------------------
+27 April 2004. Summary of changes for version 20040427:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major overhaul of the GPE handling within ACPI CA. There are
+now three types of GPEs: wake-only, runtime-only, and combination
+wake/run.
+The only GPEs allowed to be combination wake/run are for button-style
+devices such as a control-method power button, control-method sleep
+button,
+or a notebook lid switch. GPEs that have an _Lxx or _Exx method and are
+not
+referenced by any _PRW methods are marked for "runtime" and hardware
+enabled. Any GPE that is referenced by a _PRW method is marked for
+"wake"
+(and disabled at runtime). However, at sleep time, only those GPEs that
+have been specifically enabled for wake via the AcpiEnableGpe interface
+will
+actually be hardware enabled.
+
+A new external interface has been added, AcpiSetGpeType(), that is meant
+to
+be used by device drivers to force a GPE to a particular type. It will
+be
+especially useful for the drivers for the button devices mentioned above.
+
+Completed restructuring of the ACPI CA initialization sequence so that
+default operation region handlers are installed before GPEs are
+initialized
+and the _PRW methods are executed. This will prevent errors when the
+_PRW
+methods attempt to access system memory or I/O space.
+
+GPE enable/disable no longer reads the GPE enable register. We now keep
+the
+enable info for runtime and wake separate and in the GPE_EVENT_INFO. We
+thus no longer depend on the hardware to maintain these bits.
+
+Always clear the wake status and fixed/GPE status bits before sleep, even
+for state S5.
+
+Improved the AML debugger output for displaying the GPE blocks and their
+current status.
+
+Added new strings for the _OSI method, of the form "Windows 2001 SPx"
+where
+x = 0,1,2,3,4.
+
+Fixed a problem where the physical address was incorrectly calculated
+when
+the Load() operator was used to directly load from an Operation Region
+(vs.
+loading from a Field object.) Also added check for minimum table length
+for
+this case.
+
+Fix for multiple mutex acquisition. Restore original thread SyncLevel on
+mutex release.
+
+Added ACPI_VALID_SXDS flag to the AcpiGetObjectInfo interface for
+consistency with the other fields returned.
+
+Shrunk the ACPI_GPE_EVENT_INFO structure by 40%. There is one such
+structure for each GPE in the system, so the size of this structure is
+important.
+
+CPU stack requirement reduction: Cleaned up the method execution and
+object
+evaluation paths so that now a parameter structure is passed, instead of
+copying the various method parameters over and over again.
+
+In evregion.c: Correctly exit and reenter the interpreter region if and
+only if dispatching an operation region request to a user-installed
+handler.
+Do not exit/reenter when dispatching to a default handler (e.g., default
+system memory or I/O handlers)
+
+
+Notes for updating drivers for the new GPE support. The following
+changes
+must be made to ACPI-related device drivers that are attached to one or
+more
+GPEs: (This information will be added to the ACPI CA Programmer
+Reference.)
+
+1) AcpiInstallGpeHandler no longer automatically enables the GPE, you
+must
+explicitly call AcpiEnableGpe.
+2) There is a new interface called AcpiSetGpeType. This should be called
+before enabling the GPE. Also, this interface will automatically disable
+the GPE if it is currently enabled.
+3) AcpiEnableGpe no longer supports a GPE type flag.
+
+Specific drivers that must be changed:
+1) EC driver:
+ AcpiInstallGpeHandler (NULL, GpeNum, ACPI_GPE_EDGE_TRIGGERED,
+AeGpeHandler, NULL);
+ AcpiSetGpeType (NULL, GpeNum, ACPI_GPE_TYPE_RUNTIME);
+ AcpiEnableGpe (NULL, GpeNum, ACPI_NOT_ISR);
+
+2) Button Drivers (Power, Lid, Sleep):
+Run _PRW method under parent device
+If _PRW exists: /* This is a control-method button */
+ Extract GPE number and possibly GpeDevice
+ AcpiSetGpeType (GpeDevice, GpeNum, ACPI_GPE_TYPE_WAKE_RUN);
+ AcpiEnableGpe (GpeDevice, GpeNum, ACPI_NOT_ISR);
+
+For all other devices that have _PRWs, we automatically set the GPE type
+to
+ACPI_GPE_TYPE_WAKE, but the GPE is NOT automatically (wake) enabled.
+This
+must be done on a selective basis, usually requiring some kind of user
+app
+to allow the user to pick the wake devices.
+
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 77.0K Code, 11.4K Data, 88.4K Total
+ Debug Version: 161.0K Code, 66.3K Data, 227.3K Total
+ Current Release:
+
+ Non-Debug Version: 77.6K Code, 11.5K Data, 89.1K Total
+ Debug Version: 162.9K Code, 67.0K Data, 229.9K Total
+
+
+
+----------------------------------------
+02 April 2004. Summary of changes for version 20040402:
+
+1) ACPI CA Core Subsystem:
+
+Fixed an interpreter problem where an indirect store through an ArgX
+parameter was incorrectly applying the "implicit conversion rules" during
+the store. From the ACPI specification: "If the target is a method local
+or
+argument (LocalX or ArgX), no conversion is performed and the result is
+stored directly to the target". The new behavior is to disable implicit
+conversion during ALL stores to an ArgX.
+
+Changed the behavior of the _PRW method scan to ignore any and all errors
+returned by a given _PRW. This prevents the scan from aborting from the
+failure of any single _PRW.
+
+Moved the runtime configuration parameters from the global init procedure
+to
+static variables in acglobal.h. This will allow the host to override the
+default values easily.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 76.9K Code, 11.4K Data, 88.3K Total
+ Debug Version: 160.8K Code, 66.1K Data, 226.9K Total
+ Current Release:
+ Non-Debug Version: 77.0K Code, 11.4K Data, 88.4K Total
+ Debug Version: 161.0K Code, 66.3K Data, 227.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+iASL now fully disassembles SSDTs. However, External() statements are
+not
+generated automatically for unresolved symbols at this time. This is a
+planned feature for future implementation.
+
+Fixed a scoping problem in the disassembler that occurs when the type of
+the
+target of a Scope() operator is overridden. This problem caused an
+incorrectly nested internal namespace to be constructed.
+
+Any warnings or errors that are emitted during disassembly are now
+commented
+out automatically so that the resulting file can be recompiled without
+any
+hand editing.
+
+----------------------------------------
+26 March 2004. Summary of changes for version 20040326:
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for "wake" GPEs via interaction between GPEs and the
+_PRW methods. Every GPE that is pointed to by one or more _PRWs is
+identified as a WAKE GPE and by default will no longer be enabled at
+runtime. Previously, we were blindly enabling all GPEs with a
+corresponding
+_Lxx or _Exx method - but most of these turn out to be WAKE GPEs anyway.
+We
+believe this has been the cause of thousands of "spurious" GPEs on some
+systems.
+
+This new GPE behavior is can be reverted to the original behavior (enable
+ALL GPEs at runtime) via a runtime flag.
+
+Fixed a problem where aliased control methods could not access objects
+properly. The proper scope within the namespace was not initialized
+(transferred to the target of the aliased method) before executing the
+target method.
+
+Fixed a potential race condition on internal object deletion on the
+return
+object in AcpiEvaluateObject.
+
+Integrated a fix for resource descriptors where both _MEM and _MTP were
+being extracted instead of just _MEM. (i.e. bitmask was incorrectly too
+wide, 0x0F instead of 0x03.)
+
+Added a special case for ACPI_ROOT_OBJECT in AcpiUtGetNodeName,
+preventing
+a
+fault in some cases.
+
+Updated Notify() values for debug statements in evmisc.c
+
+Return proper status from AcpiUtMutexInitialize, not just simply AE_OK.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+
+ Non-Debug Version: 76.5K Code, 11.3K Data, 87.8K Total
+ Debug Version: 160.3K Code, 66.0K Data, 226.3K Total
+ Current Release:
+ Non-Debug Version: 76.9K Code, 11.4K Data, 88.3K Total
+ Debug Version: 160.8K Code, 66.1K Data, 226.9K Total
+
+----------------------------------------
+11 March 2004. Summary of changes for version 20040311:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where errors occurring during the parse phase of control
+method execution did not abort cleanly. For example, objects created and
+installed in the namespace were not deleted. This caused all subsequent
+invocations of the method to return the AE_ALREADY_EXISTS exception.
+
+Implemented a mechanism to force a control method to "Serialized"
+execution
+if the method attempts to create namespace objects. (The root of the
+AE_ALREADY_EXISTS problem.)
+
+Implemented support for the predefined _OSI "internal" control method.
+Initial supported strings are "Linux", "Windows 2000", "Windows 2001",
+and
+"Windows 2001.1", and can be easily upgraded for new strings as
+necessary.
+This feature will allow "other" operating systems to execute the fully
+tested, "Windows" code path through the ASL code
+
+Global Lock Support: Now allows multiple acquires and releases with any
+internal thread. Removed concept of "owning thread" for this special
+mutex.
+
+Fixed two functions that were inappropriately declaring large objects on
+the
+CPU stack: PsParseLoop, NsEvaluateRelative. Reduces the stack usage
+during
+method execution considerably.
+
+Fixed a problem in the ACPI 2.0 FACS descriptor (actbl2.h) where the
+S4Bios_f field was incorrectly defined as UINT32 instead of UINT32_BIT.
+
+Fixed a problem where AcpiEvGpeDetect would fault if there were no GPEs
+defined on the machine.
+
+Implemented two runtime options: One to force all control method
+execution
+to "Serialized" to mimic Windows behavior, another to disable _OSI
+support
+if it causes problems on a given machine.
+
+Code and Data Size: Current and previous core subsystem library sizes are
+shown below. These are the code and data sizes for the acpica.lib
+produced
+by the Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code includes the
+debug output trace mechanism and has a much larger code and data size.
+Note
+that these values will vary depending on the efficiency of the compiler
+and
+the compiler options used during generation.
+
+ Previous Release:
+ Non-Debug Version: 74.8K Code, 10.1K Data, 84.9K Total
+ Debug Version: 158.7K Code, 65.1K Data, 223.8K Total
+ Current Release:
+ Non-Debug Version: 76.5K Code, 11.3K Data, 87.8K Total
+ Debug Version: 160.3K Code, 66.0K Data, 226.3K Total
+
+2) iASL Compiler/Disassembler:
+
+Fixed an array size problem for FreeBSD that would cause the compiler to
+fault.
+
+----------------------------------------
+20 February 2004. Summary of changes for version 20040220:
+
+
+1) ACPI CA Core Subsystem:
+
+Implemented execution of _SxD methods for Device objects in the
+GetObjectInfo interface.
+
+Fixed calls to _SST method to pass the correct arguments.
+
+Added a call to _SST on wake to restore to "working" state.
+
+Check for End-Of-Buffer failure case in the WalkResources interface.
+
+Integrated fix for 64-bit alignment issue in acglobal.h by moving two
+structures to the beginning of the file.
+
+After wake, clear GPE status register(s) before enabling GPEs.
+
+After wake, clear/enable power button. (Perhaps we should clear/enable
+all
+fixed events upon wake.)
+
+Fixed a couple of possible memory leaks in the Namespace manager.
+
+Integrated latest acnetbsd.h file.
+
+----------------------------------------
+11 February 2004. Summary of changes for version 20040211:
+
+
+1) ACPI CA Core Subsystem:
+
+Completed investigation and implementation of the call-by-reference
+mechanism for control method arguments.
+
+Fixed a problem where a store of an object into an indexed package could
+fail if the store occurs within a different method than the method that
+created the package.
+
+Fixed a problem where the ToDecimal operator could return incorrect
+results.
+
+Fixed a problem where the CopyObject operator could fail on some of the
+more
+obscure objects (e.g., Reference objects.)
+
+Improved the output of the Debug object to display buffer, package, and
+index objects.
+
+Fixed a problem where constructs of the form "RefOf (ArgX)" did not
+return
+the expected result.
+
+Added permanent ACPI_REPORT_ERROR macros for all instances of the
+ACPI_AML_INTERNAL exception.
+
+Integrated latest version of acfreebsd.h
+
+----------------------------------------
+16 January 2004. Summary of changes for version 20040116:
+
+The purpose of this release is primarily to update the copyright years in
+each module, thus causing a huge number of diffs. There are a few small
+functional changes, however.
+
+1) ACPI CA Core Subsystem:
+
+Improved error messages when there is a problem finding one or more of
+the
+required base ACPI tables
+
+Reintroduced the definition of APIC_HEADER in actbl.h
+
+Changed definition of MADT_ADDRESS_OVERRIDE to 64 bits (actbl.h)
+
+Removed extraneous reference to NewObj in dsmthdat.c
+
+2) iASL compiler
+
+Fixed a problem introduced in December that disabled the correct
+disassembly
+of Resource Templates
+
+
+----------------------------------------
+03 December 2003. Summary of changes for version 20031203:
+
+1) ACPI CA Core Subsystem:
+
+Changed the initialization of Operation Regions during subsystem
+init to perform two entire walks of the ACPI namespace; The first
+to initialize the regions themselves, the second to execute the
+_REG methods. This fixed some interdependencies across _REG
+methods found on some machines.
+
+Fixed a problem where a Store(Local0, Local1) could simply update
+the object reference count, and not create a new copy of the
+object if the Local1 is uninitialized.
+
+Implemented support for the _SST reserved method during sleep
+transitions.
+
+Implemented support to clear the SLP_TYP and SLP_EN bits when
+waking up, this is apparently required by some machines.
+
+When sleeping, clear the wake status only if SleepState is not S5.
+
+Fixed a problem in AcpiRsExtendedIrqResource() where an incorrect
+pointer arithmetic advanced a string pointer too far.
+
+Fixed a problem in AcpiTbGetTablePtr() where a garbage pointer
+could be returned if the requested table has not been loaded.
+
+Within the support for IRQ resources, restructured the handling of
+the active and edge/level bits.
+
+Fixed a few problems in AcpiPsxExecute() where memory could be
+leaked under certain error conditions.
+
+Improved error messages for the cases where the ACPI mode could
+not be entered.
+
+Code and Data Size: Current and previous core subsystem library
+sizes are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and
+these values do not include any ACPI driver or OSPM code. The
+debug version of the code includes the debug output trace
+mechanism and has a much larger code and data size. Note that
+these values will vary depending on the efficiency of the compiler
+and the compiler options used during generation.
+
+ Previous Release (20031029):
+ Non-Debug Version: 74.4K Code, 10.1K Data, 84.5K Total
+ Debug Version: 158.3K Code, 65.0K Data, 223.3K Total
+ Current Release:
+ Non-Debug Version: 74.8K Code, 10.1K Data, 84.9K Total
+ Debug Version: 158.7K Code, 65.1K Data, 223.8K Total
+
+2) iASL Compiler/Disassembler:
+
+Implemented a fix for the iASL disassembler where a bad index was
+generated. This was most noticeable on 64-bit platforms
+
+
+----------------------------------------
+29 October 2003. Summary of changes for version 20031029:
+
+1) ACPI CA Core Subsystem:
+
+
+Fixed a problem where a level-triggered GPE with an associated
+_Lxx control method was incorrectly cleared twice.
+
+Fixed a problem with the Field support code where an access can
+occur beyond the end-of-region if the field is non-aligned but
+extends to the very end of the parent region (resulted in an
+AE_AML_REGION_LIMIT exception.)
+
+Fixed a problem with ACPI Fixed Events where an RT Clock handler
+would not get invoked on an RTC event. The RTC event bitmasks for
+the PM1 registers were not being initialized properly.
+
+Implemented support for executing _STA and _INI methods for
+Processor objects. Although this is currently not part of the
+ACPI specification, there is existing ASL code that depends on the
+init-time execution of these methods.
+
+Implemented and deployed a GetDescriptorName function to decode
+the various types of internal descriptors. Guards against null
+descriptors during debug output also.
+
+Implemented and deployed a GetNodeName function to extract the 4-
+character namespace node name. This function simplifies the debug
+and error output, as well as guarding against null pointers during
+output.
+
+Implemented and deployed the ACPI_FORMAT_UINT64 helper macro to
+simplify the debug and error output of 64-bit integers. This
+macro replaces the HIDWORD and LODWORD macros for dumping these
+integers.
+
+Updated the implementation of the Stall() operator to only call
+AcpiOsStall(), and also return an error if the operand is larger
+than 255. This preserves the required behavior of not
+relinquishing the processor, as would happen if AcpiOsSleep() was
+called for "long stalls".
+
+Constructs of the form "Store(LocalX,LocalX)" where LocalX is not
+initialized are now treated as NOOPs.
+
+Cleaned up a handful of warnings during 64-bit generation.
+
+Fixed a reported error where and incorrect GPE number was passed
+to the GPE dispatch handler. This value is only used for error
+output, however. Used this opportunity to clean up and streamline
+the GPE dispatch code.
+
+Code and Data Size: Current and previous core subsystem library
+sizes are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and
+these values do not include any ACPI driver or OSPM code. The
+
+debug version of the code includes the debug output trace
+mechanism and has a much larger code and data size. Note that
+these values will vary depending on the efficiency of the compiler
+and the compiler options used during generation.
+
+ Previous Release (20031002):
+ Non-Debug Version: 74.1K Code, 9.7K Data, 83.8K Total
+ Debug Version: 157.9K Code, 64.8K Data, 222.7K Total
+ Current Release:
+ Non-Debug Version: 74.4K Code, 10.1K Data, 84.5K Total
+ Debug Version: 158.3K Code, 65.0K Data, 223.3K Total
+
+
+2) iASL Compiler/Disassembler:
+
+Updated the iASL compiler to return an error if the operand to the
+Stall() operator is larger than 255.
+
+
+----------------------------------------
+02 October 2003. Summary of changes for version 20031002:
+
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem with Index Fields where the index was not
+incremented for fields that require multiple writes to the
+index/data registers (Fields that are wider than the data
+register.)
+
+Fixed a problem with all Field objects where a write could go
+beyond the end-of-field if the field was larger than the access
+granularity and therefore required multiple writes to complete the
+request. An extra write beyond the end of the field could happen
+inadvertently.
+
+Fixed a problem with Index Fields where a BUFFER_OVERFLOW error
+would incorrectly be returned if the width of the Data Register
+was larger than the specified field access width.
+
+Completed fixes for LoadTable() and Unload() and verified their
+operation. Implemented full support for the "DdbHandle" object
+throughout the ACPI CA subsystem.
+
+Implemented full support for the MADT and ECDT tables in the ACPI
+CA header files. Even though these tables are not directly
+consumed by ACPI CA, the header definitions are useful for ACPI
+device drivers.
+
+Integrated resource descriptor fixes posted to the Linux ACPI
+list. This included checks for minimum descriptor length, and
+support for trailing NULL strings within descriptors that have
+optional string elements.
+
+Code and Data Size: Current and previous core subsystem library
+sizes are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and
+these values do not include any ACPI driver or OSPM code. The
+debug version of the code includes the debug output trace
+mechanism and has a much larger code and data size. Note that
+these values will vary depending on the efficiency of the compiler
+and the compiler options used during generation.
+
+ Previous Release (20030918):
+ Non-Debug Version: 73.9K Code, 9.7K Data, 83.6K Total
+ Debug Version: 157.3K Code, 64.5K Data, 221.8K Total
+ Current Release:
+ Non-Debug Version: 74.1K Code, 9.7K Data, 83.8K Total
+ Debug Version: 157.9K Code, 64.8K Data, 222.7K Total
+
+
+2) iASL Compiler:
+
+Implemented detection of non-ASCII characters within the input
+source ASL file. This catches attempts to compile binary (AML)
+files early in the compile, with an informative error message.
+
+Fixed a problem where the disassembler would fault if the output
+filename could not be generated or if the output file could not be
+opened.
+
+----------------------------------------
+18 September 2003. Summary of changes for version 20030918:
+
+
+1) ACPI CA Core Subsystem:
+
+Found and fixed a longstanding problem with the late execution of
+the various deferred AML opcodes (such as Operation Regions,
+Buffer Fields, Buffers, and Packages). If the name string
+specified for the name of the new object placed the object in a
+scope other than the current scope, the initialization/execution
+of the opcode failed. The solution to this problem was to
+implement a mechanism where the late execution of such opcodes
+does not attempt to lookup/create the name a second time in an
+incorrect scope. This fixes the "region size computed
+incorrectly" problem.
+
+Fixed a call to AcpiHwRegisterWrite in hwregs.c that was causing a
+Global Lock AE_BAD_PARAMETER error.
+
+Fixed several 64-bit issues with prototypes, casting and data
+types.
+
+Removed duplicate prototype from acdisasm.h
+
+Fixed an issue involving EC Operation Region Detach (Shaohua Li)
+
+Code and Data Size: Current and previous core subsystem library
+sizes are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and
+these values do not include any ACPI driver or OSPM code. The
+debug version of the code includes the debug output trace
+mechanism and has a much larger code and data size. Note that
+these values will vary depending on the efficiency of the compiler
+and the compiler options used during generation.
+
+ Previous Release:
+
+ Non-Debug Version: 73.7K Code, 9.7K Data, 83.4K Total
+ Debug Version: 156.9K Code, 64.2K Data, 221.1K Total
+ Current Release:
+ Non-Debug Version: 73.9K Code, 9.7K Data, 83.6K Total
+ Debug Version: 157.3K Code, 64.5K Data, 221.8K Total
+
+
+2) Linux:
+
+Fixed the AcpiOsSleep implementation in osunixxf.c to pass the
+correct sleep time in seconds.
+
+----------------------------------------
+14 July 2003. Summary of changes for version 20030619:
+
+1) ACPI CA Core Subsystem:
+
+Parse SSDTs in order discovered, as opposed to reverse order
+(Hrvoje Habjanic)
+
+Fixes from FreeBSD and NetBSD. (Frank van der Linden, Thomas
+Klausner,
+ Nate Lawson)
+
+
+2) Linux:
+
+Dynamically allocate SDT list (suggested by Andi Kleen)
+
+proc function return value cleanups (Andi Kleen)
+
+Correctly handle NMI watchdog during long stalls (Andrew Morton)
+
+Make it so acpismp=force works (reported by Andrew Morton)
+
+
+----------------------------------------
+19 June 2003. Summary of changes for version 20030619:
+
+1) ACPI CA Core Subsystem:
+
+Fix To/FromBCD, eliminating the need for an arch-specific #define.
+
+Do not acquire a semaphore in the S5 shutdown path.
+
+Fix ex_digits_needed for 0. (Takayoshi Kochi)
+
+Fix sleep/stall code reversal. (Andi Kleen)
+
+Revert a change having to do with control method calling
+semantics.
+
+2) Linux:
+
+acpiphp update (Takayoshi Kochi)
+
+Export acpi_disabled for sonypi (Stelian Pop)
+
+Mention acpismp=force in config help
+
+Re-add acpitable.c and acpismp=force. This improves backwards
+
+compatibility and also cleans up the code to a significant degree.
+
+Add ASUS Value-add driver (Karol Kozimor and Julien Lerouge)
+
+----------------------------------------
+22 May 2003. Summary of changes for version 20030522:
+
+1) ACPI CA Core Subsystem:
+
+Found and fixed a reported problem where an AE_NOT_FOUND error
+occurred occasionally during _BST evaluation. This turned out to
+be an Owner ID allocation issue where a called method did not get
+a new ID assigned to it. Eventually, (after 64k calls), the Owner
+ID UINT16 would wraparound so that the ID would be the same as the
+caller's and the called method would delete the caller's
+namespace.
+
+Implemented extended error reporting for control methods that are
+aborted due to a run-time exception. Output includes the exact
+AML instruction that caused the method abort, a dump of the method
+locals and arguments at the time of the abort, and a trace of all
+nested control method calls.
+
+Modified the interpreter to allow the creation of buffers of zero
+length from the AML code. Implemented new code to ensure that no
+attempt is made to actually allocate a memory buffer (of length
+zero) - instead, a simple buffer object with a NULL buffer pointer
+and length zero is created. A warning is no longer issued when
+the AML attempts to create a zero-length buffer.
+
+Implemented a workaround for the "leading asterisk issue" in
+_HIDs, _UIDs, and _CIDs in the AML interpreter. One leading
+asterisk is automatically removed if present in any HID, UID, or
+CID strings. The iASL compiler will still flag this asterisk as
+an error, however.
+
+Implemented full support for _CID methods that return a package of
+multiple CIDs (Compatible IDs). The AcpiGetObjectInfo() interface
+now additionally returns a device _CID list if present. This
+required a change to the external interface in order to pass an
+ACPI_BUFFER object as a parameter since the _CID list is of
+variable length.
+
+Fixed a problem with the new AE_SAME_HANDLER exception where
+handler initialization code did not know about this exception.
+
+Code and Data Size: Current and previous core subsystem library
+sizes are shown below. These are the code and data sizes for the
+acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and
+these values do not include any ACPI driver or OSPM code. The
+debug version of the code includes the debug output trace
+mechanism and has a much larger code and data size. Note that
+these values will vary depending on the efficiency of the compiler
+and the compiler options used during generation.
+
+ Previous Release (20030509):
+ Non-Debug Version: 73.4K Code, 9.7K Data, 83.1K Total
+ Debug Version: 156.1K Code, 63.9K Data, 220.0K Total
+ Current Release:
+ Non-Debug Version: 73.7K Code, 9.7K Data, 83.4K Total
+ Debug Version: 156.9K Code, 64.2K Data, 221.1K Total
+
+
+2) Linux:
+
+Fixed a bug in which we would reinitialize the ACPI interrupt
+after it was already working, thus disabling all ACPI and the IRQs
+for any other device sharing the interrupt. (Thanks to Stian
+Jordet)
+
+Toshiba driver update (John Belmonte)
+
+Return only 0 or 1 for our interrupt handler status (Andrew
+Morton)
+
+
+3) iASL Compiler:
+
+Fixed a reported problem where multiple (nested) ElseIf()
+statements were not handled correctly by the compiler, resulting
+in incorrect warnings and incorrect AML code. This was a problem
+in both the ASL parser and the code generator.
+
+
+4) Documentation:
+
+Added changes to existing interfaces, new exception codes, and new
+text concerning reference count object management versus garbage
+collection.
+
+----------------------------------------
+09 May 2003. Summary of changes for version 20030509.
+
+
+1) ACPI CA Core Subsystem:
+
+Changed the subsystem initialization sequence to hold off
+installation of address space handlers until the hardware has been
+initialized and the system has entered ACPI mode. This is because
+the installation of space handlers can cause _REG methods to be
+run. Previously, the _REG methods could potentially be run before
+ACPI mode was enabled.
+
+Fixed some memory leak issues related to address space handler and
+notify handler installation. There were some problems with the
+reference count mechanism caused by the fact that the handler
+objects are shared across several namespace objects.
+
+Fixed a reported problem where reference counts within the
+namespace were not properly updated when named objects created by
+method execution were deleted.
+
+Fixed a reported problem where multiple SSDTs caused a deletion
+issue during subsystem termination. Restructured the table data
+structures to simplify the linked lists and the related code.
+
+Fixed a problem where the table ID associated with secondary
+tables (SSDTs) was not being propagated into the namespace objects
+created by those tables. This would only present a problem for
+tables that are unloaded at run-time, however.
+
+Updated AcpiOsReadable and AcpiOsWritable to use the ACPI_SIZE
+type as the length parameter (instead of UINT32).
+
+Solved a long-standing problem where an ALREADY_EXISTS error
+appears on various systems. This problem could happen when there
+are multiple PCI_Config operation regions under a single PCI root
+bus. This doesn't happen very frequently, but there are some
+systems that do this in the ASL.
+
+Fixed a reported problem where the internal DeleteNode function
+was incorrectly handling the case where a namespace node was the
+first in the parent's child list, and had additional peers (not
+the only child, but first in the list of children.)
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 73.7K Code, 9.5K Data, 83.2K Total
+ Debug Version: 156.1K Code, 63.6K Data, 219.7K Total
+ Current Release:
+ Non-Debug Version: 73.4K Code, 9.7K Data, 83.1K Total
+ Debug Version: 156.1K Code, 63.9K Data, 220.0K Total
+
+
+2) Linux:
+
+Allow ":" in OS override string (Ducrot Bruno)
+
+Kobject fix (Greg KH)
+
+
+3 iASL Compiler/Disassembler:
+
+Fixed a problem in the generation of the C source code files (AML
+is emitted in C source statements for BIOS inclusion) where the
+Ascii dump that appears within a C comment at the end of each line
+could cause a compile time error if the AML sequence happens to
+have an open comment or close comment sequence embedded.
+
+
+----------------------------------------
+24 April 2003. Summary of changes for version 20030424.
+
+
+1) ACPI CA Core Subsystem:
+
+Support for big-endian systems has been implemented. Most of the
+support has been invisibly added behind big-endian versions of the
+ACPI_MOVE_* macros.
+
+Fixed a problem in AcpiHwDisableGpeBlock() and
+AcpiHwClearGpeBlock() where an incorrect offset was passed to the
+low level hardware write routine. The offset parameter was
+actually eliminated from the low level read/write routines because
+they had become obsolete.
+
+Fixed a problem where a handler object was deleted twice during
+the removal of a fixed event handler.
+
+
+2) Linux:
+
+A fix for SMP systems with link devices was contributed by
+
+Compaq's Dan Zink.
+
+(2.5) Return whether we handled the interrupt in our IRQ handler.
+(Linux ISRs no longer return void, so we can propagate the handler
+return value from the ACPI CA core back to the OS.)
+
+
+
+3) Documentation:
+
+The ACPI CA Programmer Reference has been updated to reflect new
+interfaces and changes to existing interfaces.
+
+----------------------------------------
+28 March 2003. Summary of changes for version 20030328.
+
+1) ACPI CA Core Subsystem:
+
+The GPE Block Device support has been completed. New interfaces
+are AcpiInstallGpeBlock and AcpiRemoveGpeBlock. The Event
+interfaces (enable, disable, clear, getstatus) have been split
+into separate interfaces for Fixed Events and General Purpose
+Events (GPEs) in order to support GPE Block Devices properly.
+
+Fixed a problem where the error message "Failed to acquire
+semaphore" would appear during operations on the embedded
+controller (EC).
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 72.3K Code, 9.5K Data, 81.8K Total
+ Debug Version: 154.0K Code, 63.4K Data, 217.4K Total
+ Current Release:
+ Non-Debug Version: 73.7K Code, 9.5K Data, 83.2K Total
+ Debug Version: 156.1K Code, 63.6K Data, 219.7K Total
+
+
+----------------------------------------
+28 February 2003. Summary of changes for version 20030228.
+
+
+1) ACPI CA Core Subsystem:
+
+The GPE handling and dispatch code has been completely overhauled
+in preparation for support of GPE Block Devices (ID ACPI0006).
+This affects internal data structures and code only; there should
+be no differences visible externally. One new file has been
+added, evgpeblk.c
+
+The FADT fields GPE0_BLK_LEN and GPE1_BLK_LEN are now the only
+fields that are used to determine the GPE block lengths. The
+REGISTER_BIT_WIDTH field of the X_GPEx_BLK extended address
+structures are ignored. This is per the ACPI specification but it
+isn't very clear. The full 256 Block 0/1 GPEs are now supported
+(the use of REGISTER_BIT_WIDTH limited the number of GPEs to 128).
+
+In the SCI interrupt handler, removed the read of the PM1_CONTROL
+register to look at the SCI_EN bit. On some machines, this read
+causes an SMI event and greatly slows down SCI events. (This may
+in fact be the cause of slow battery status response on some
+systems.)
+
+Fixed a problem where a store of a NULL string to a package object
+could cause the premature deletion of the object. This was seen
+during execution of the battery _BIF method on some systems,
+resulting in no battery data being returned.
+
+Added AcpiWalkResources interface to simplify parsing of resource
+lists.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 72.0K Code, 9.5K Data, 81.5K Total
+ Debug Version: 153.0K Code, 62.9K Data, 215.9K Total
+ Current Release:
+ Non-Debug Version: 72.3K Code, 9.5K Data, 81.8K Total
+ Debug Version: 154.0K Code, 63.4K Data, 217.4K Total
+
+
+2) Linux
+
+S3 fixes (Ole Rohne)
+
+Update ACPI PHP driver with to use new acpi_walk_resource API
+(Bjorn Helgaas)
+
+Add S4BIOS support (Pavel Machek)
+
+Map in entire table before performing checksum (John Stultz)
+
+Expand the mem= cmdline to allow the specification of reserved and
+ACPI DATA blocks (Pavel Machek)
+
+Never use ACPI on VISWS
+
+Fix derive_pci_id (Ducrot Bruno, Alvaro Lopez)
+
+Revert a change that allowed P_BLK lengths to be 4 or 5. This is
+causing us to think that some systems support C2 when they really
+don't.
+
+Do not count processor objects for non-present CPUs (Thanks to
+Dominik Brodowski)
+
+
+3) iASL Compiler:
+
+Fixed a problem where ASL include files could not be found and
+opened.
+
+Added support for the _PDC reserved name.
+
+
+----------------------------------------
+22 January 2003. Summary of changes for version 20030122.
+
+
+1) ACPI CA Core Subsystem:
+
+Added a check for constructs of the form: Store (Local0, Local0)
+where Local0 is not initialized. Apparently, some BIOS
+programmers believe that this is a NOOP. Since this store doesn't
+do anything anyway, the new prototype behavior will ignore this
+error. This is a case where we can relax the strict checking in
+the interpreter in the name of compatibility.
+
+
+2) Linux
+
+The AcpiSrc Source Conversion Utility has been released with the
+Linux package for the first time. This is the utility that is
+used to convert the ACPI CA base source code to the Linux version.
+
+(Both) Handle P_BLK lengths shorter than 6 more gracefully
+
+(Both) Move more headers to include/acpi, and delete an unused
+header.
+
+(Both) Move drivers/acpi/include directory to include/acpi
+
+(Both) Boot functions don't use cmdline, so don't pass it around
+
+(Both) Remove include of unused header (Adrian Bunk)
+
+(Both) acpiphp.h includes both linux/acpi.h and acpi_bus.h. Since
+the
+former now also includes the latter, acpiphp.h only needs the one,
+now.
+
+(2.5) Make it possible to select method of bios restoring after S3
+resume. [=> no more ugly ifdefs] (Pavel Machek)
+
+(2.5) Make proc write interfaces work (Pavel Machek)
+
+(2.5) Properly init/clean up in cpufreq/acpi (Dominik Brodowski)
+
+(2.5) Break out ACPI Perf code into its own module, under cpufreq
+(Dominik Brodowski)
+
+(2.4) S4BIOS support (Ducrot Bruno)
+
+(2.4) Fix acpiphp_glue.c for latest ACPI struct changes (Sergio
+Visinoni)
+
+
+3) iASL Compiler:
+
+Added support to disassemble SSDT and PSDTs.
+
+Implemented support to obtain SSDTs from the Windows registry if
+available.
+
+
+----------------------------------------
+09 January 2003. Summary of changes for version 20030109.
+
+1) ACPI CA Core Subsystem:
+
+Changed the behavior of the internal Buffer-to-String conversion
+function. The current ACPI specification states that the contents
+of the buffer are "converted to a string of two-character
+hexadecimal numbers, each separated by a space". Unfortunately,
+this definition is not backwards compatible with existing ACPI 1.0
+implementations (although the behavior was not defined in the ACPI
+1.0 specification). The new behavior simply copies data from the
+buffer to the string until a null character is found or the end of
+the buffer is reached. The new String object is always null
+terminated. This problem was seen during the generation of _BIF
+battery data where incorrect strings were returned for battery
+type, etc. This will also require an errata to the ACPI
+specification.
+
+Renamed all instances of NATIVE_UINT and NATIVE_INT to
+ACPI_NATIVE_UINT and ACPI_NATIVE_INT, respectively.
+
+Copyright in all module headers (both Linux and non-Linux) has be
+updated to 2003.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 72.0K Code, 9.5K Data, 81.5K Total
+ Debug Version: 153.0K Code, 62.9K Data, 215.9K Total
+ Current Release:
+ Non-Debug Version: 72.0K Code, 9.5K Data, 81.5K Total
+ Debug Version: 153.0K Code, 62.9K Data, 215.9K Total
+
+
+2) Linux
+
+Fixed an oops on module insertion/removal (Matthew Tippett)
+
+(2.4) Fix to handle dynamic size of mp_irqs (Joerg Prante)
+
+(2.5) Replace pr_debug (Randy Dunlap)
+
+(2.5) Remove usage of CPUFREQ_ALL_CPUS (Dominik Brodowski)
+
+(Both) Eliminate spawning of thread from timer callback, in favor
+of schedule_work()
+
+(Both) Show Lid status in /proc (Zdenek OGAR Skalak)
+
+(Both) Added define for Fixed Function HW region (Matthew Wilcox)
+
+(Both) Add missing statics to button.c (Pavel Machek)
+
+Several changes have been made to the source code translation
+utility that generates the Linux Code in order to make the code
+more "Linux-like":
+
+All typedefs on structs and unions have been removed in keeping
+with the Linux coding style.
+
+Removed the non-Linux SourceSafe module revision number from each
+module header.
+
+Completed major overhaul of symbols to be lowercased for linux.
+Doubled the number of symbols that are lowercased.
+
+Fixed a problem where identifiers within procedure headers and
+within quotes were not fully lower cased (they were left with a
+starting capital.)
+
+Some C macros whose only purpose is to allow the generation of 16-
+bit code are now completely removed in the Linux code, increasing
+readability and maintainability.
+
+----------------------------------------
+
+12 December 2002. Summary of changes for version 20021212.
+
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where the creation of a zero-length AML Buffer
+would cause a fault.
+
+Fixed a problem where a Buffer object that pointed to a static AML
+buffer (in an ACPI table) could inadvertently be deleted, causing
+memory corruption.
+
+Fixed a problem where a user buffer (passed in to the external
+ACPI CA interfaces) could be overwritten if the buffer was too
+small to complete the operation, causing memory corruption.
+
+Fixed a problem in the Buffer-to-String conversion code where a
+string of length one was always returned, regardless of the size
+of the input Buffer object.
+
+Removed the NATIVE_CHAR data type across the entire source due to
+lack of need and lack of consistent use.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 72.1K Code, 9.5K Data, 81.6K Total
+ Debug Version: 152.7K Code, 62.7K Data, 215.4K Total
+ Current Release:
+ Non-Debug Version: 72.0K Code, 9.5K Data, 81.5K Total
+ Debug Version: 153.0K Code, 62.9K Data, 215.9K Total
+
+
+----------------------------------------
+05 December 2002. Summary of changes for version 20021205.
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where a store to a String or Buffer object could
+cause corruption of the DSDT if the object type being stored was
+the same as the target object type and the length of the object
+being stored was equal to or smaller than the original (existing)
+target object. This was seen to cause corruption of battery _BIF
+buffers if the _BIF method modified the buffer on the fly.
+
+Fixed a problem where an internal error was generated if a control
+method invocation was used in an OperationRegion, Buffer, or
+Package declaration. This was caused by the deferred parsing of
+the control method and thus the deferred creation of the internal
+method object. The solution to this problem was to create the
+internal method object at the moment the method is encountered in
+the first pass - so that subsequent references to the method will
+able to obtain the required parameter count and thus properly
+parse the method invocation. This problem presented itself as an
+AE_AML_INTERNAL during the pass 1 parse phase during table load.
+
+Fixed a problem where the internal String object copy routine did
+not always allocate sufficient memory for the target String object
+and caused memory corruption. This problem was seen to cause
+"Allocation already present in list!" errors as memory allocation
+became corrupted.
+
+Implemented a new function for the evaluation of namespace objects
+that allows the specification of the allowable return object
+types. This simplifies a lot of code that checks for a return
+object of one or more specific objects returned from the
+evaluation (such as _STA, etc.) This may become and external
+function if it would be useful to ACPI-related drivers.
+
+Completed another round of prefixing #defines with "ACPI_" for
+clarity.
+
+Completed additional code restructuring to allow more modular
+linking for iASL compiler and AcpiExec. Several files were split
+creating new files. New files: nsparse.c dsinit.c evgpe.c
+
+Implemented an abort mechanism to terminate an executing control
+method via the AML debugger. This feature is useful for debugging
+control methods that depend (wait) for specific hardware
+responses.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 71.4K Code, 9.0K Data, 80.4K Total
+ Debug Version: 152.9K Code, 63.3K Data, 216.2K Total
+ Current Release:
+ Non-Debug Version: 72.1K Code, 9.5K Data, 81.6K Total
+ Debug Version: 152.7K Code, 62.7K Data, 215.4K Total
+
+
+2) iASL Compiler/Disassembler
+
+Fixed a compiler code generation problem for "Interrupt" Resource
+Descriptors. If specified in the ASL, the optional "Resource
+Source Index" and "Resource Source" fields were not inserted into
+the correct location within the AML resource descriptor, creating
+an invalid descriptor.
+
+Fixed a disassembler problem for "Interrupt" resource descriptors.
+The optional "Resource Source Index" and "Resource Source" fields
+were ignored.
+
+
+----------------------------------------
+22 November 2002. Summary of changes for version 20021122.
+
+
+1) ACPI CA Core Subsystem:
+
+Fixed a reported problem where an object stored to a Method Local
+or Arg was not copied to a new object during the store - the
+object pointer was simply copied to the Local/Arg. This caused
+all subsequent operations on the Local/Arg to also affect the
+original source of the store operation.
+
+Fixed a problem where a store operation to a Method Local or Arg
+was not completed properly if the Local/Arg contained a reference
+(from RefOf) to a named field. The general-purpose store-to-
+namespace-node code is now used so that this case is handled
+automatically.
+
+Fixed a problem where the internal object copy routine would cause
+a protection fault if the object being copied was a Package and
+contained either 1) a NULL package element or 2) a nested sub-
+package.
+
+Fixed a problem with the GPE initialization that resulted from an
+ambiguity in the ACPI specification. One section of the
+specification states that both the address and length of the GPE
+block must be zero if the block is not supported. Another section
+implies that only the address need be zero if the block is not
+supported. The code has been changed so that both the address and
+the length must be non-zero to indicate a valid GPE block (i.e.,
+if either the address or the length is zero, the GPE block is
+invalid.)
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 71.3K Code, 9.0K Data, 80.3K Total
+ Debug Version: 152.7K Code, 63.2K Data, 215.5K Total
+ Current Release:
+ Non-Debug Version: 71.4K Code, 9.0K Data, 80.4K Total
+ Debug Version: 152.9K Code, 63.3K Data, 216.2K Total
+
+
+2) Linux
+
+Cleaned up EC driver. Exported an external EC read/write
+interface. By going through this, other drivers (most notably
+sonypi) will be able to serialize access to the EC.
+
+
+3) iASL Compiler/Disassembler
+
+Implemented support to optionally generate include files for both
+ASM and C (the -i switch). This simplifies BIOS development by
+automatically creating include files that contain external
+declarations for the symbols that are created within the
+
+(optionally generated) ASM and C AML source files.
+
+
+----------------------------------------
+15 November 2002. Summary of changes for version 20021115.
+
+1) ACPI CA Core Subsystem:
+
+Fixed a memory leak problem where an error during resolution of
+
+method arguments during a method invocation from another method
+failed to cleanup properly by deleting all successfully resolved
+argument objects.
+
+Fixed a problem where the target of the Index() operator was not
+correctly constructed if the source object was a package. This
+problem has not been detected because the use of a target operand
+with Index() is very rare.
+
+Fixed a problem with the Index() operator where an attempt was
+made to delete the operand objects twice.
+
+Fixed a problem where an attempt was made to delete an operand
+twice during execution of the CondRefOf() operator if the target
+did not exist.
+
+Implemented the first of perhaps several internal create object
+functions that create and initialize a specific object type. This
+consolidates duplicated code wherever the object is created, thus
+shrinking the size of the subsystem.
+
+Implemented improved debug/error messages for errors that occur
+during nested method invocations. All executing method pathnames
+are displayed (with the error) as the call stack is unwound - thus
+simplifying debug.
+
+Fixed a problem introduced in the 10/02 release that caused
+premature deletion of a buffer object if a buffer was used as an
+ASL operand where an integer operand is required (Thus causing an
+implicit object conversion from Buffer to Integer.) The change in
+the 10/02 release was attempting to fix a memory leak (albeit
+incorrectly.)
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 71.9K Code, 9.1K Data, 81.0K Total
+ Debug Version: 153.1K Code, 63.3K Data, 216.4K Total
+ Current Release:
+ Non-Debug Version: 71.3K Code, 9.0K Data, 80.3K Total
+ Debug Version: 152.7K Code, 63.2K Data, 215.5K Total
+
+
+2) Linux
+
+Changed the implementation of the ACPI semaphores to use down()
+instead of down_interruptable(). It is important that the
+execution of ACPI control methods not be interrupted by signals.
+Methods must run to completion, or the system may be left in an
+unknown/unstable state.
+
+Fixed a compilation error when CONFIG_SOFTWARE_SUSPEND is not set.
+(Shawn Starr)
+
+
+3) iASL Compiler/Disassembler
+
+
+Changed the default location of output files. All output files
+are now placed in the current directory by default instead of in
+the directory of the source file. This change may affect some
+existing makefiles, but it brings the behavior of the compiler in
+line with other similar tools. The location of the output files
+can be overridden with the -p command line switch.
+
+
+----------------------------------------
+11 November 2002. Summary of changes for version 20021111.
+
+
+0) ACPI Specification 2.0B is released and is now available at:
+http://www.acpi.info/index.html
+
+
+1) ACPI CA Core Subsystem:
+
+Implemented support for the ACPI 2.0 SMBus Operation Regions.
+This includes the early detection and handoff of the request to
+the SMBus region handler (avoiding all of the complex field
+support code), and support for the bidirectional return packet
+from an SMBus write operation. This paves the way for the
+development of SMBus drivers in each host operating system.
+
+Fixed a problem where the semaphore WAIT_FOREVER constant was
+defined as 32 bits, but must be 16 bits according to the ACPI
+specification. This had the side effect of causing ASL
+Mutex/Event timeouts even though the ASL code requested a wait
+forever. Changed all internal references to the ACPI timeout
+parameter to 16 bits to prevent future problems. Changed the name
+of WAIT_FOREVER to ACPI_WAIT_FOREVER.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 71.4K Code, 9.0K Data, 80.4K Total
+ Debug Version: 152.3K Code, 63.0K Data, 215.3K Total
+ Current Release:
+ Non-Debug Version: 71.9K Code, 9.1K Data, 81.0K Total
+ Debug Version: 153.1K Code, 63.3K Data, 216.4K Total
+
+
+2) Linux
+
+Module loading/unloading fixes (John Cagle)
+
+
+3) iASL Compiler/Disassembler
+
+Added support for the SMBBlockProcessCall keyword (ACPI 2.0)
+
+Implemented support for the disassembly of all SMBus protocol
+keywords (SMBQuick, SMBWord, etc.)
+
+----------------------------------------
+01 November 2002. Summary of changes for version 20021101.
+
+
+1) ACPI CA Core Subsystem:
+
+Fixed a problem where platforms that have a GPE1 block but no GPE0
+block were not handled correctly. This resulted in a "GPE
+overlap" error message. GPE0 is no longer required.
+
+Removed code added in the previous release that inserted nodes
+into the namespace in alphabetical order. This caused some side-
+effects on various machines. The root cause of the problem is
+still under investigation since in theory, the internal ordering
+of the namespace nodes should not matter.
+
+
+Enhanced error reporting for the case where a named object is not
+found during control method execution. The full ACPI namepath
+(name reference) of the object that was not found is displayed in
+this case.
+
+Note: as a result of the overhaul of the namespace object types in
+the previous release, the namespace nodes for the predefined
+scopes (_TZ, _PR, etc.) are now of the type ACPI_TYPE_LOCAL_SCOPE
+instead of ACPI_TYPE_ANY. This simplifies the namespace
+management code but may affect code that walks the namespace tree
+looking for specific object types.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a much larger code and data size. Note that these values will
+vary depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 70.7K Code, 8.6K Data, 79.3K Total
+ Debug Version: 151.7K Code, 62.4K Data, 214.1K Total
+ Current Release:
+ Non-Debug Version: 71.4K Code, 9.0K Data, 80.4K Total
+ Debug Version: 152.3K Code, 63.0K Data, 215.3K Total
+
+
+2) Linux
+
+Fixed a problem introduced in the previous release where the
+Processor and Thermal objects were not recognized and installed in
+/proc. This was related to the scope type change described above.
+
+
+3) iASL Compiler/Disassembler
+
+Implemented the -g option to get all of the required ACPI tables
+from the registry and save them to files (Windows version of the
+compiler only.) The required tables are the FADT, FACS, and DSDT.
+
+Added ACPI table checksum validation during table disassembly in
+order to catch corrupted tables.
+
+
+----------------------------------------
+22 October 2002. Summary of changes for version 20021022.
+
+1) ACPI CA Core Subsystem:
+
+Implemented a restriction on the Scope operator that the target
+must already exist in the namespace at the time the operator is
+encountered (during table load or method execution). In other
+words, forward references are not allowed and Scope() cannot
+create a new object. This changes the previous behavior where the
+interpreter would create the name if not found. This new behavior
+correctly enables the search-to-root algorithm during namespace
+lookup of the target name. Because of this upsearch, this fixes
+the known Compaq _SB_.OKEC problem and makes both the AML
+interpreter and iASL compiler compatible with other ACPI
+implementations.
+
+Completed a major overhaul of the internal ACPI object types for
+the ACPI Namespace and the associated operand objects. Many of
+these types had become obsolete with the introduction of the two-
+pass namespace load. This cleanup simplifies the code and makes
+the entire namespace load mechanism much clearer and easier to
+understand.
+
+Improved debug output for tracking scope opening/closing to help
+diagnose scoping issues. The old scope name as well as the new
+scope name are displayed. Also improved error messages for
+problems with ASL Mutex objects and error messages for GPE
+problems.
+
+Cleaned up the namespace dump code, removed obsolete code.
+
+All string output (for all namespace/object dumps) now uses the
+common ACPI string output procedure which handles escapes properly
+and does not emit non-printable characters.
+
+Fixed some issues with constants in the 64-bit version of the
+local C library (utclib.c)
+
+
+2) Linux
+
+EC Driver: No longer attempts to acquire the Global Lock at
+interrupt level.
+
+
+3) iASL Compiler/Disassembler
+
+Implemented ACPI 2.0B grammar change that disallows all Type 1 and
+2 opcodes outside of a control method. This means that the
+"executable" operators (versus the "namespace" operators) cannot
+be used at the table level; they can only be used within a control
+method.
+
+Implemented the restriction on the Scope() operator where the
+target must already exist in the namespace at the time the
+operator is encountered (during ASL compilation). In other words,
+forward references are not allowed and Scope() cannot create a new
+object. This makes the iASL compiler compatible with other ACPI
+implementations and makes the Scope() implementation adhere to the
+ACPI specification.
+
+Fixed a problem where namepath optimization for the Alias operator
+was optimizing the wrong path (of the two namepaths.) This caused
+a "Missing alias link" error message.
+
+Fixed a problem where an "unknown reserved name" warning could be
+incorrectly generated for names like "_SB" when the trailing
+underscore is not used in the original ASL.
+
+Fixed a problem where the reserved name check did not handle
+NamePaths with multiple NameSegs correctly. The first nameseg of
+the NamePath was examined instead of the last NameSeg.
+
+
+----------------------------------------
+
+02 October 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem version 20021002:
+
+Fixed a problem where a store/copy of a string to an existing
+string did not always set the string length properly in the String
+object.
+
+Fixed a reported problem with the ToString operator where the
+behavior was identical to the ToHexString operator instead of just
+simply converting a raw buffer to a string data type.
+
+Fixed a problem where CopyObject and the other "explicit"
+conversion operators were not updating the internal namespace node
+type as part of the store operation.
+
+Fixed a memory leak during implicit source operand conversion
+where the original object was not deleted if it was converted to a
+new object of a different type.
+
+Enhanced error messages for all problems associated with namespace
+lookups. Common procedure generates and prints the lookup name as
+well as the formatted status.
+
+Completed implementation of a new design for the Alias support
+within the namespace. The existing design did not handle the case
+where a new object was assigned to one of the two names due to the
+use of an explicit conversion operator, resulting in the two names
+pointing to two different objects. The new design simply points
+the Alias name to the original name node - not to the object.
+This results in a level of indirection that must be handled in the
+name resolution mechanism.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 69.6K Code, 8.3K Data, 77.9K Total
+ Debug Version: 150.0K Code, 61.7K Data, 211.7K Total
+ Current Release:
+ Non-Debug Version: 70.7K Code, 8.6K Data, 79.3K Total
+ Debug Version: 151.7K Code, 62.4K Data, 214.1K Total
+
+
+2) Linux
+
+Initialize thermal driver's timer before it is used. (Knut
+Neumann)
+
+Allow handling negative celsius values. (Kochi Takayoshi)
+
+Fix thermal management and make trip points. R/W (Pavel Machek)
+
+Fix /proc/acpi/sleep. (P. Christeas)
+
+IA64 fixes. (David Mosberger)
+
+Fix reversed logic in blacklist code. (Sergio Monteiro Basto)
+
+Replace ACPI_DEBUG define with ACPI_DEBUG_OUTPUT. (Dominik
+Brodowski)
+
+
+3) iASL Compiler/Disassembler
+
+Clarified some warning/error messages.
+
+
+----------------------------------------
+18 September 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem version 20020918:
+
+Fixed a reported problem with reference chaining (via the Index()
+and RefOf() operators) in the ObjectType() and SizeOf() operators.
+The definition of these operators includes the dereferencing of
+all chained references to return information on the base object.
+
+Fixed a problem with stores to indexed package elements - the
+existing code would not complete the store if an "implicit
+conversion" was not performed. In other words, if the existing
+object (package element) was to be replaced completely, the code
+didn't handle this case.
+
+Relaxed typechecking on the ASL "Scope" operator to allow the
+target name to refer to an object of type Integer, String, or
+Buffer, in addition to the scoping object types (Device,
+predefined Scopes, Processor, PowerResource, and ThermalZone.)
+This allows existing AML code that has workarounds for a bug in
+Windows to function properly. A warning is issued, however. This
+affects both the AML interpreter and the iASL compiler. Below is
+an example of this type of ASL code:
+
+ Name(DEB,0x00)
+ Scope(DEB)
+ {
+
+Fixed some reported problems with 64-bit integer support in the
+local implementation of C library functions (clib.c)
+
+
+2) Linux
+
+Use ACPI fix map region instead of IOAPIC region, since it is
+undefined in non-SMP.
+
+Ensure that the SCI has the proper polarity and trigger, even on
+systems that do not have an interrupt override entry in the MADT.
+
+2.5 big driver reorganization (Pat Mochel)
+
+Use early table mapping code from acpitable.c (Andi Kleen)
+
+New blacklist entries (Andi Kleen)
+
+Blacklist improvements. Split blacklist code out into a separate
+file. Move checking the blacklist to very early. Previously, we
+would use ACPI tables, and then halfway through init, check the
+blacklist -- too late. Now, it's early enough to completely fall-
+back to non-ACPI.
+
+
+3) iASL Compiler/Disassembler version 20020918:
+
+Fixed a problem where the typechecking code didn't know that an
+alias could point to a method. In other words, aliases were not
+being dereferenced during typechecking.
+
+
+----------------------------------------
+29 August 2002. Summary of changes for this release.
+
+1) ACPI CA Core Subsystem Version 20020829:
+
+If the target of a Scope() operator already exists, it must be an
+object type that actually opens a scope -- such as a Device,
+Method, Scope, etc. This is a fatal runtime error. Similar error
+check has been added to the iASL compiler also.
+
+Tightened up the namespace load to disallow multiple names in the
+same scope. This previously was allowed if both objects were of
+the same type. (i.e., a lookup was the same as entering a new
+name).
+
+
+2) Linux
+
+Ensure that the ACPI interrupt has the proper trigger and
+polarity.
+
+local_irq_disable is extraneous. (Matthew Wilcox)
+
+Make "acpi=off" actually do what it says, and not use the ACPI
+interpreter *or* the tables.
+
+Added arch-neutral support for parsing SLIT and SRAT tables (Kochi
+Takayoshi)
+
+
+3) iASL Compiler/Disassembler Version 20020829:
+
+Implemented namepath optimization for name declarations. For
+example, a declaration like "Method (\_SB_.ABCD)" would get
+optimized to "Method (ABCD)" if the declaration is within the
+\_SB_ scope. This optimization is in addition to the named
+reference path optimization first released in the previous
+version. This would seem to complete all possible optimizations
+for namepaths within the ASL/AML.
+
+If the target of a Scope() operator already exists, it must be an
+object type that actually opens a scope -- such as a Device,
+Method, Scope, etc.
+
+Implemented a check and warning for unreachable code in the same
+block below a Return() statement.
+
+Fixed a problem where the listing file was not generated if the
+compiler aborted if the maximum error count was exceeded (200).
+
+Fixed a problem where the typechecking of method return values was
+broken. This includes the check for a return value when the
+method is invoked as a TermArg (a return value is expected.)
+
+Fixed a reported problem where EOF conditions during a quoted
+string or comment caused a fault.
+
+
+----------------------------------------
+15 August 2002. Summary of changes for this release.
+
+1) ACPI CA Core Subsystem Version 20020815:
+
+Fixed a reported problem where a Store to a method argument that
+contains a reference did not perform the indirect store correctly.
+This problem was created during the conversion to the new
+reference object model - the indirect store to a method argument
+code was not updated to reflect the new model.
+
+Reworked the ACPI mode change code to better conform to ACPI 2.0,
+handle corner cases, and improve code legibility (Kochi Takayoshi)
+
+Fixed a problem with the pathname parsing for the carat (^)
+prefix. The heavy use of the carat operator by the new namepath
+optimization in the iASL compiler uncovered a problem with the AML
+interpreter handling of this prefix. In the case where one or
+more carats precede a single nameseg, the nameseg was treated as
+standalone and the search rule (to root) was inadvertently
+applied. This could cause both the iASL compiler and the
+interpreter to find the wrong object or to miss the error that
+should occur if the object does not exist at that exact pathname.
+
+Found and fixed the problem where the HP Pavilion DSDT would not
+load. This was a relatively minor tweak to the table loading code
+(a problem caused by the unexpected encounter with a method
+invocation not within a control method), but it does not solve the
+overall issue of the execution of AML code at the table level.
+This investigation is still ongoing.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 69.1K Code, 8.2K Data, 77.3K Total
+ Debug Version: 149.4K Code, 61.6K Data, 211.0K Total
+ Current Release:
+ Non-Debug Version: 69.6K Code, 8.3K Data, 77.9K Total
+ Debug Version: 150.0K Code, 61.7K Data, 211.7K Total
+
+
+2) Linux
+
+Remove redundant slab.h include (Brad Hards)
+
+Fix several bugs in thermal.c (Herbert Nachtnebel)
+
+Make CONFIG_ACPI_BOOT work properly (Pavel Machek)
+
+Change acpi_system_suspend to use updated irq functions (Pavel
+Machek)
+
+Export acpi_get_firmware_table (Matthew Wilcox)
+
+Use proper root proc entry for ACPI (Kochi Takayoshi)
+
+Fix early-boot table parsing (Bjorn Helgaas)
+
+
+3) iASL Compiler/Disassembler
+
+Reworked the compiler options to make them more consistent and to
+use two-letter options where appropriate. We were running out of
+sensible letters. This may break some makefiles, so check the
+current options list by invoking the compiler with no parameters.
+
+Completed the design and implementation of the ASL namepath
+optimization option for the compiler. This option optimizes all
+references to named objects to the shortest possible path. The
+first attempt tries to utilize a single nameseg (4 characters) and
+the "search-to-root" algorithm used by the interpreter. If that
+cannot be used (because either the name is not in the search path
+or there is a conflict with another object with the same name),
+the pathname is optimized using the carat prefix (usually a
+shorter string than specifying the entire path from the root.)
+
+Implemented support to obtain the DSDT from the Windows registry
+(when the disassembly option is specified with no input file).
+Added this code as the implementation for AcpiOsTableOverride in
+the Windows OSL. Migrated the 16-bit code (used in the AcpiDump
+utility) to scan memory for the DSDT to the AcpiOsTableOverride
+function in the DOS OSL to make the disassembler truly OS
+independent.
+
+Implemented a new option to disassemble and compile in one step.
+When used without an input filename, this option will grab the
+DSDT from the local machine, disassemble it, and compile it in one
+step.
+
+Added a warning message for invalid escapes (a backslash followed
+by any character other than the allowable escapes). This catches
+the quoted string error "\_SB_" (which should be "\\_SB_" ).
+
+Also, there are numerous instances in the ACPI specification where
+this error occurs.
+
+Added a compiler option to disable all optimizations. This is
+basically the "compatibility mode" because by using this option,
+the AML code will come out exactly the same as other ASL
+compilers.
+
+Added error messages for incorrectly ordered dependent resource
+functions. This includes: missing EndDependentFn macro at end of
+dependent resource list, nested dependent function macros (both
+start and end), and missing StartDependentFn macro. These are
+common errors that should be caught at compile time.
+
+Implemented _OSI support for the disassembler and compiler. _OSI
+must be included in the namespace for proper disassembly (because
+the disassembler must know the number of arguments.)
+
+Added an "optimization" message type that is optional (off by
+default). This message is used for all optimizations - including
+constant folding, integer optimization, and namepath optimization.
+
+----------------------------------------
+25 July 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem Version 20020725:
+
+The AML Disassembler has been enhanced to produce compilable ASL
+code and has been integrated into the iASL compiler (see below) as
+well as the single-step disassembly for the AML debugger and the
+disassembler for the AcpiDump utility. All ACPI 2.0A opcodes,
+resource templates and macros are fully supported. The
+disassembler has been tested on over 30 different AML files,
+producing identical AML when the resulting disassembled ASL file
+is recompiled with the same ASL compiler.
+
+Modified the Resource Manager to allow zero interrupts and zero
+dma channels during the GetCurrentResources call. This was
+causing problems on some platforms.
+
+Added the AcpiOsRedirectOutput interface to the OSL to simplify
+output redirection for the AcpiOsPrintf and AcpiOsVprintf
+interfaces.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 68.7K Code, 7.4K Data, 76.1K Total
+ Debug Version: 142.9K Code, 58.7K Data, 201.6K Total
+ Current Release:
+ Non-Debug Version: 69.1K Code, 8.2K Data, 77.3K Total
+ Debug Version: 149.4K Code, 61.6K Data, 211.0K Total
+
+
+2) Linux
+
+Fixed a panic in the EC driver (Dominik Brodowski)
+
+Implemented checksum of the R/XSDT itself during Linux table scan
+(Richard Schaal)
+
+
+3) iASL compiler
+
+The AML disassembler is integrated into the compiler. The "-d"
+option invokes the disassembler to completely disassemble an
+input AML file, producing as output a text ASL file with the
+extension ".dsl" (to avoid name collisions with existing .asl
+source files.) A future enhancement will allow the disassembler
+to obtain the BIOS DSDT from the registry under Windows.
+
+Fixed a problem with the VendorShort and VendorLong resource
+descriptors where an invalid AML sequence was created.
+
+Implemented a fix for BufferData term in the ASL parser. It was
+inadvertently defined twice, allowing invalid syntax to pass and
+causing reduction conflicts.
+
+Fixed a problem where the Ones opcode could get converted to a
+value of zero if "Ones" was used where a byte, word or dword value
+was expected. The 64-bit value is now truncated to the correct
+size with the correct value.
+
+
+
+----------------------------------------
+02 July 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem Version 20020702:
+
+The Table Manager code has been restructured to add several new
+features. Tables that are not required by the core subsystem
+(other than the FADT, DSDT, FACS, PSDTs, etc.) are no longer
+validated in any way and are returned from AcpiGetFirmwareTable if
+requested. The AcpiOsTableOverride interface is now called for
+each table that is loaded by the subsystem in order to allow the
+host to override any table it chooses. Previously, only the DSDT
+could be overridden. Added one new files, tbrsdt.c and
+tbgetall.c.
+
+Fixed a problem with the conversion of internal package objects to
+external objects (when a package is returned from a control
+method.) The return buffer length was set to zero instead of the
+proper length of the package object.
+
+Fixed a reported problem with the use of the RefOf and DeRefOf
+operators when passing reference arguments to control methods. A
+new type of Reference object is used internally for references
+produced by the RefOf operator.
+
+Added additional error messages in the Resource Manager to explain
+AE_BAD_DATA errors when they occur during resource parsing.
+
+Split the AcpiEnableSubsystem into two primitives to enable a
+finer granularity initialization sequence. These two calls should
+be called in this order: AcpiEnableSubsystem (flags),
+AcpiInitializeObjects (flags). The flags parameter remains the
+same.
+
+
+2) Linux
+
+Updated the ACPI utilities module to understand the new style of
+fully resolved package objects that are now returned from the core
+subsystem. This eliminates errors of the form:
+
+ ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PPB_._PRT]
+ acpi_utils-0430 [145] acpi_evaluate_reference:
+ Invalid element in package (not a device reference)
+
+The method evaluation utility uses the new buffer allocation
+scheme instead of calling AcpiEvaluate Object twice.
+
+Added support for ECDT. This allows the use of the Embedded
+
+Controller before the namespace has been fully initialized, which
+is necessary for ACPI 2.0 support, and for some laptops to
+initialize properly. (Laptops using ECDT are still rare, so only
+limited testing was performed of the added functionality.)
+
+Fixed memory leaks in the EC driver.
+
+Eliminated a brittle code structure in acpi_bus_init().
+
+Eliminated the acpi_evaluate() helper function in utils.c. It is
+no longer needed since acpi_evaluate_object can optionally
+allocate memory for the return object.
+
+Implemented fix for keyboard hang when getting battery readings on
+some systems (Stephen White)
+
+PCI IRQ routing update (Dominik Brodowski)
+
+Fix an ifdef to allow compilation on UP with LAPIC but no IOAPIC
+support
+
+----------------------------------------
+11 June 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem Version 20020611:
+
+Fixed a reported problem where constants such as Zero and One
+appearing within _PRT packages were not handled correctly within
+the resource manager code. Originally reported against the ASL
+compiler because the code generator now optimizes integers to
+their minimal AML representation (i.e. AML constants if possible.)
+The _PRT code now handles all AML constant opcodes correctly
+(Zero, One, Ones, Revision).
+
+Fixed a problem with the Concatenate operator in the AML
+interpreter where a buffer result object was incorrectly marked as
+not fully evaluated, causing a run-time error of AE_AML_INTERNAL.
+
+All package sub-objects are now fully resolved before they are
+returned from the external ACPI interfaces. This means that name
+strings are resolved to object handles, and constant operators
+(Zero, One, Ones, Revision) are resolved to Integers.
+
+Implemented immediate resolution of the AML Constant opcodes
+(Zero, One, Ones, Revision) to Integer objects upon detection
+within the AML stream. This has simplified and reduced the
+generated code size of the subsystem by eliminating about 10
+switch statements for these constants (which previously were
+contained in Reference objects.) The complicating issues are that
+the Zero opcode is used as a "placeholder" for unspecified
+optional target operands and stores to constants are defined to be
+no-ops.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 69.3K Code, 7.4K Data, 76.7K Total
+ Debug Version: 143.8K Code, 58.8K Data, 202.6K Total
+ Current Release:
+ Non-Debug Version: 68.7K Code, 7.4K Data, 76.1K Total
+ Debug Version: 142.9K Code, 58.7K Data, 201.6K Total
+
+
+2) Linux
+
+
+Added preliminary support for obtaining _TRA data for PCI root
+bridges (Bjorn Helgaas).
+
+
+3) iASL Compiler Version X2046:
+
+Fixed a problem where the "_DDN" reserved name was defined to be a
+control method with one argument. There are no arguments, and
+_DDN does not have to be a control method.
+
+Fixed a problem with the Linux version of the compiler where the
+source lines printed with error messages were the wrong lines.
+This turned out to be the "LF versus CR/LF" difference between
+Windows and Unix. This appears to be the longstanding issue
+concerning listing output and error messages.
+
+Fixed a problem with the Linux version of compiler where opcode
+names within error messages were wrong. This was caused by a
+slight difference in the output of the Flex tool on Linux versus
+Windows.
+
+Fixed a problem with the Linux compiler where the hex output files
+contained some garbage data caused by an internal buffer overrun.
+
+
+----------------------------------------
+17 May 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem Version 20020517:
+
+Implemented a workaround to an BIOS bug discovered on the HP
+OmniBook where the FADT revision number and the table size are
+inconsistent (ACPI 2.0 revision vs. ACPI 1.0 table size). The new
+behavior is to fallback to using only the ACPI 1.0 fields of the
+FADT if the table is too small to be a ACPI 2.0 table as claimed
+by the revision number. Although this is a BIOS bug, this is a
+case where the workaround is simple enough and with no side
+effects, so it seemed prudent to add it. A warning message is
+issued, however.
+
+Implemented minimum size checks for the fixed-length ACPI tables -
+- the FADT and FACS, as well as consistency checks between the
+revision number and the table size.
+
+Fixed a reported problem in the table override support where the
+new table pointer was incorrectly treated as a physical address
+instead of a logical address.
+
+Eliminated the use of the AE_AML_ERROR exception and replaced it
+with more descriptive codes.
+
+Fixed a problem where an exception would occur if an ASL Field was
+defined with no named Field Units underneath it (used by some
+index fields).
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 68.8K Code, 7.1K Data, 75.9K Total
+ Debug Version: 142.9K Code, 58.4K Data, 201.3K Total
+ Current Release:
+ Non-Debug Version: 69.3K Code, 7.4K Data, 76.7K Total
+ Debug Version: 143.8K Code, 58.8K Data, 202.6K Total
+
+
+
+2) Linux
+
+Much work done on ACPI init (MADT and PCI IRQ routing support).
+(Paul D. and Dominik Brodowski)
+
+Fix PCI IRQ-related panic on boot (Sam Revitch)
+
+Set BM_ARB_DIS when entering a sleep state (Ducrot Bruno)
+
+Fix "MHz" typo (Dominik Brodowski)
+
+Fix RTC year 2000 issue (Dominik Brodowski)
+
+Preclude multiple button proc entries (Eric Brunet)
+
+Moved arch-specific code out of include/platform/aclinux.h
+
+3) iASL Compiler Version X2044:
+
+Implemented error checking for the string used in the EISAID macro
+(Usually used in the definition of the _HID object.) The code now
+strictly enforces the PnP format - exactly 7 characters, 3
+uppercase letters and 4 hex digits.
+
+If a raw string is used in the definition of the _HID object
+(instead of the EISAID macro), the string must contain all
+alphanumeric characters (e.g., "*PNP0011" is not allowed because
+of the asterisk.)
+
+Implemented checking for invalid use of ACPI reserved names for
+most of the name creation operators (Name, Device, Event, Mutex,
+OperationRegion, PowerResource, Processor, and ThermalZone.)
+Previously, this check was only performed for control methods.
+
+Implemented an additional check on the Name operator to emit an
+error if a reserved name that must be implemented in ASL as a
+control method is used. We know that a reserved name must be a
+method if it is defined with input arguments.
+
+The warning emitted when a namespace object reference is not found
+during the cross reference phase has been changed into an error.
+The "External" directive should be used for names defined in other
+modules.
+
+
+4) Tools and Utilities
+
+The 16-bit tools (adump16 and aexec16) have been regenerated and
+tested.
+
+Fixed a problem with the output of both acpidump and adump16 where
+the indentation of closing parentheses and brackets was not
+
+aligned properly with the parent block.
+
+
+----------------------------------------
+03 May 2002. Summary of changes for this release.
+
+
+1) ACPI CA Core Subsystem Version 20020503:
+
+Added support a new OSL interface that allows the host operating
+
+system software to override the DSDT found in the firmware -
+AcpiOsTableOverride. With this interface, the OSL can examine the
+version of the firmware DSDT and replace it with a different one
+if desired.
+
+Added new external interfaces for accessing ACPI registers from
+device drivers and other system software - AcpiGetRegister and
+AcpiSetRegister. This was simply an externalization of the
+existing AcpiHwBitRegister interfaces.
+
+Fixed a regression introduced in the previous build where the
+ASL/AML CreateField operator always returned an error,
+"destination must be a NS Node".
+
+Extended the maximum time (before failure) to successfully enable
+ACPI mode to 3 seconds.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 68.5K Code, 7.0K Data, 75.5K Total
+ Debug Version: 142.4K Code, 58.3K Data, 200.7K Total
+ Current Release:
+ Non-Debug Version: 68.8K Code, 7.1K Data, 75.9K Total
+ Debug Version: 142.9K Code, 58.4K Data, 201.3K Total
+
+
+2) Linux
+
+Enhanced ACPI init code for SMP. We are now fully MPS and $PIR-
+free. While 3 out of 4 of our in-house systems work fine, the last
+one still hangs when testing the LAPIC timer.
+
+Renamed many files in 2.5 kernel release to omit "acpi_" from the
+name.
+
+Added warning on boot for Presario 711FR.
+
+Sleep improvements (Pavel Machek)
+
+ACPI can now be built without CONFIG_PCI enabled.
+
+IA64: Fixed memory map functions (JI Lee)
+
+
+3) iASL Compiler Version X2043:
+
+Added support to allow the compiler to be integrated into the MS
+VC++ development environment for one-button compilation of single
+files or entire projects -- with error-to-source-line mapping.
+
+Implemented support for compile-time constant folding for the
+Type3, Type4, and Type5 opcodes first defined in the ACPI 2.0
+specification. This allows the ASL writer to use expressions
+instead of Integer/Buffer/String constants in terms that must
+evaluate to constants at compile time and will also simplify the
+emitted AML in any such sub-expressions that can be folded
+(evaluated at compile-time.) This increases the size of the
+compiler significantly because a portion of the ACPI CA AML
+interpreter is included within the compiler in order to pre-
+evaluate constant expressions.
+
+
+Fixed a problem with the "Unicode" ASL macro that caused the
+compiler to fault. (This macro is used in conjunction with the
+_STR reserved name.)
+
+Implemented an AML opcode optimization to use the Zero, One, and
+Ones opcodes where possible to further reduce the size of integer
+constants and thus reduce the overall size of the generated AML
+code.
+
+Implemented error checking for new reserved terms for ACPI version
+2.0A.
+
+Implemented the -qr option to display the current list of ACPI
+reserved names known to the compiler.
+
+Implemented the -qc option to display the current list of ASL
+operators that are allowed within constant expressions and can
+therefore be folded at compile time if the operands are constants.
+
+
+4) Documentation
+
+Updated the Programmer's Reference for new interfaces, data types,
+and memory allocation model options.
+
+Updated the iASL Compiler User Reference to apply new format and
+add information about new features and options.
+
+----------------------------------------
+19 April 2002. Summary of changes for this release.
+
+1) ACPI CA Core Subsystem Version 20020419:
+
+The source code base for the Core Subsystem has been completely
+cleaned with PC-lint (FlexLint) for both 32-bit and 64-bit
+versions. The Lint option files used are included in the
+/acpi/generate/lint directory.
+
+Implemented enhanced status/error checking across the entire
+Hardware manager subsystem. Any hardware errors (reported from
+the OSL) are now bubbled up and will abort a running control
+method.
+
+
+Fixed a problem where the per-ACPI-table integer width (32 or 64)
+was stored only with control method nodes, causing a fault when
+non-control method code was executed during table loading. The
+solution implemented uses a global variable to indicate table
+width across the entire ACPI subsystem. Therefore, ACPI CA does
+not support mixed integer widths across different ACPI tables
+(DSDT, SSDT).
+
+Fixed a problem where NULL extended fields (X fields) in an ACPI
+2.0 ACPI FADT caused the table load to fail. Although the
+existing ACPI specification is a bit fuzzy on this topic, the new
+behavior is to fall back on a ACPI 1.0 field if the corresponding
+ACPI 2.0 X field is zero (even though the table revision indicates
+a full ACPI 2.0 table.) The ACPI specification will be updated to
+clarify this issue.
+
+Fixed a problem with the SystemMemory operation region handler
+where memory was always accessed byte-wise even if the AML-
+specified access width was larger than a byte. This caused
+problems on systems with memory-mapped I/O. Memory is now
+accessed with the width specified. On systems that do not support
+non-aligned transfers, a check is made to guarantee proper address
+alignment before proceeding in order to avoid an AML-caused
+alignment fault within the kernel.
+
+
+Fixed a problem with the ExtendedIrq resource where only one byte
+of the 4-byte Irq field was extracted.
+
+Fixed the AcpiExDigitsNeeded() procedure to support _UID. This
+function was out of date and required a rewrite.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 66.6K Code, 6.5K Data, 73.1K Total
+ Debug Version: 139.8K Code, 57.4K Data, 197.2K Total
+ Current Release:
+ Non-Debug Version: 68.5K Code, 7.0K Data, 75.5K Total
+ Debug Version: 142.4K Code, 58.3K Data, 200.7K Total
+
+
+2) Linux
+
+PCI IRQ routing fixes (Dominik Brodowski)
+
+
+3) iASL Compiler Version X2042:
+
+Implemented an additional compile-time error check for a field
+unit whose size + minimum access width would cause a run-time
+access beyond the end-of-region. Previously, only the field size
+itself was checked.
+
+The Core subsystem and iASL compiler now share a common parse
+object in preparation for compile-time evaluation of the type
+3/4/5 ASL operators.
+
+
+----------------------------------------
+Summary of changes for this release: 03_29_02
+
+1) ACPI CA Core Subsystem Version 20020329:
+
+Implemented support for late evaluation of TermArg operands to
+Buffer and Package objects. This allows complex expressions to be
+used in the declarations of these object types.
+
+Fixed an ACPI 1.0 compatibility issue when reading Fields. In ACPI
+1.0, if the field was larger than 32 bits, it was returned as a
+buffer - otherwise it was returned as an integer. In ACPI 2.0,
+the field is returned as a buffer only if the field is larger than
+64 bits. The TableRevision is now considered when making this
+conversion to avoid incompatibility with existing ASL code.
+
+Implemented logical addressing for AcpiOsGetRootPointer. This
+allows an RSDP with either a logical or physical address. With
+this support, the host OS can now override all ACPI tables with
+one logical RSDP. Includes implementation of "typed" pointer
+support to allow a common data type for both physical and logical
+pointers internally. This required a change to the
+AcpiOsGetRootPointer interface.
+
+Implemented the use of ACPI 2.0 Generic Address Structures for all
+GPE, Fixed Event, and PM Timer I/O. This allows the use of memory
+mapped I/O for these ACPI features.
+
+Initialization now ignores not only non-required tables (All
+tables other than the FADT, FACS, DSDT, and SSDTs), but also does
+not validate the table headers of unrecognized tables.
+
+Fixed a problem where a notify handler could only be
+installed/removed on an object of type Device. All "notify"
+
+objects are now supported -- Devices, Processor, Power, and
+Thermal.
+
+Removed most verbosity from the ACPI_DB_INFO debug level. Only
+critical information is returned when this debug level is enabled.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release
+ Non-Debug Version: 65.4K Code, 6.2K Data, 71.6K Total
+ Debug Version: 138.0K Code, 56.6K Data, 194.6K Total
+ Current Release:
+ Non-Debug Version: 66.6K Code, 6.5K Data, 73.1K Total
+ Debug Version: 139.8K Code, 57.4K Data, 197.2K Total
+
+
+2) Linux:
+
+The processor driver (acpi_processor.c) now fully supports ACPI
+2.0-based processor performance control (e.g. Intel(R)
+SpeedStep(TM) technology) Note that older laptops that only have
+the Intel "applet" interface are not supported through this. The
+'limit' and 'performance' interface (/proc) are fully functional.
+[Note that basic policy for controlling performance state
+transitions will be included in the next version of ospmd.] The
+idle handler was modified to more aggressively use C2, and PIIX4
+errata handling underwent a complete overhaul (big thanks to
+Dominik Brodowski).
+
+Added support for ACPI-PCI device binding (acpi_pci_root.c). _ADR-
+based devices in the ACPI namespace are now dynamically bound
+(associated) with their PCI counterparts (e.g. PCI1->01:00.0).
+This allows, among other things, ACPI to resolve bus numbers for
+subordinate PCI bridges.
+
+Enhanced PCI IRQ routing to get the proper bus number for _PRT
+entries defined underneath PCI bridges.
+
+Added IBM 600E to bad bios list due to invalid _ADR value for
+PIIX4 PCI-ISA bridge, resulting in improper PCI IRQ routing.
+
+In the process of adding full MADT support (e.g. IOAPIC) for IA32
+(acpi.c, mpparse.c) -- stay tuned.
+
+Added back visual differentiation between fixed-feature and
+control-method buttons in dmesg. Buttons are also subtyped (e.g.
+button/power/PWRF) to simplify button identification.
+
+We no longer use -Wno-unused when compiling debug. Please ignore
+any "_THIS_MODULE defined but not used" messages.
+
+Can now shut down the system using "magic sysrq" key.
+
+
+3) iASL Compiler version 2041:
+
+Fixed a problem where conversion errors for hex/octal/decimal
+constants were not reported.
+
+Implemented a fix for the General Register template Address field.
+This field was 8 bits when it should be 64.
+
+Fixed a problem where errors/warnings were no longer being emitted
+within the listing output file.
+
+Implemented the ACPI 2.0A restriction on ACPI Table Signatures to
+exactly 4 characters, alphanumeric only.
+
+
+
+
+----------------------------------------
+Summary of changes for this release: 03_08_02
+
+
+1) ACPI CA Core Subsystem Version 20020308:
+
+Fixed a problem with AML Fields where the use of the "AccessAny"
+keyword could cause an interpreter error due to attempting to read
+or write beyond the end of the parent Operation Region.
+
+Fixed a problem in the SystemMemory Operation Region handler where
+an attempt was made to map memory beyond the end of the region.
+This was the root cause of the "AE_ERROR" and "AE_NO_MEMORY"
+errors on some Linux systems.
+
+Fixed a problem where the interpreter/namespace "search to root"
+algorithm was not functioning for some object types. Relaxed the
+internal restriction on the search to allow upsearches for all
+external object types as well as most internal types.
+
+
+2) Linux:
+
+We now use safe_halt() macro versus individual calls to sti | hlt.
+
+Writing to the processor limit interface should now work. "echo 1"
+will increase the limit, 2 will decrease, and 0 will reset to the
+
+default.
+
+
+3) ASL compiler:
+
+Fixed segfault on Linux version.
+
+
+----------------------------------------
+Summary of changes for this release: 02_25_02
+
+1) ACPI CA Core Subsystem:
+
+
+Fixed a problem where the GPE bit masks were not initialized
+properly, causing erratic GPE behavior.
+
+Implemented limited support for multiple calling conventions. The
+code can be generated with either the VPL (variable parameter
+list, or "C") convention, or the FPL (fixed parameter list, or
+"Pascal") convention. The core subsystem is about 3.4% smaller
+when generated with FPL.
+
+
+2) Linux
+
+Re-add some /proc/acpi/event functionality that was lost during
+the rewrite
+
+Resolved issue with /proc events for fixed-feature buttons showing
+up as the system device.
+
+Fixed checks on C2/C3 latencies to be inclusive of maximum values.
+
+Replaced AE_ERRORs in acpi_osl.c with more specific error codes.
+
+Changed ACPI PRT option from "pci=noacpi-routing" to "pci=noacpi"
+
+Fixed limit interface & usage to fix bugs with passive cooling
+hysterisis.
+
+Restructured PRT support.
+
+
+----------------------------------------
+Summary of changes for this label: 02_14_02
+
+
+1) ACPI CA Core Subsystem:
+
+Implemented support in AcpiLoadTable to allow loading of FACS and
+FADT tables.
+
+Suport for the now-obsolete interim 0.71 64-bit ACPI tables has
+been removed. All 64-bit platforms should be migrated to the ACPI
+2.0 tables. The actbl71.h header has been removed from the source
+tree.
+
+All C macros defined within the subsystem have been prefixed with
+"ACPI_" to avoid collision with other system include files.
+
+Removed the return value for the two AcpiOsPrint interfaces, since
+it is never used and causes lint warnings for ignoring the return
+value.
+
+Added error checking to all internal mutex acquire and release
+calls. Although a failure from one of these interfaces is
+probably a fatal system error, these checks will cause the
+immediate abort of the currently executing method or interface.
+
+Fixed a problem where the AcpiSetCurrentResources interface could
+fault. This was a side effect of the deployment of the new memory
+allocation model.
+
+Fixed a couple of problems with the Global Lock support introduced
+in the last major build. The "common" (1.0/2.0) internal FACS was
+being overwritten with the FACS signature and clobbering the
+Global Lock pointer. Also, the actual firmware FACS was being
+unmapped after construction of the "common" FACS, preventing
+access to the actual Global Lock field within it. The "common"
+internal FACS is no longer installed as an actual ACPI table; it
+is used simply as a global.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release (02_07_01)
+ Non-Debug Version: 65.2K Code, 6.2K Data, 71.4K Total
+ Debug Version: 136.9K Code, 56.4K Data, 193.3K Total
+ Current Release:
+ Non-Debug Version: 65.4K Code, 6.2K Data, 71.6K Total
+ Debug Version: 138.0K Code, 56.6K Data, 194.6K Total
+
+
+2) Linux
+
+Updated Linux-specific code for core macro and OSL interface
+changes described above.
+
+Improved /proc/acpi/event. It now can be opened only once and has
+proper poll functionality.
+
+Fixed and restructured power management (acpi_bus).
+
+Only create /proc "view by type" when devices of that class exist.
+
+Fixed "charging/discharging" bug (and others) in acpi_battery.
+
+Improved thermal zone code.
+
+
+3) ASL Compiler, version X2039:
+
+
+Implemented the new compiler restriction on ASL String hex/octal
+escapes to non-null, ASCII values. An error results if an invalid
+value is used. (This will require an ACPI 2.0 specification
+change.)
+
+AML object labels that are output to the optional C and ASM source
+are now prefixed with both the ACPI table signature and table ID
+to help guarantee uniqueness within a large BIOS project.
+
+
+----------------------------------------
+Summary of changes for this label: 02_01_02
+
+1) ACPI CA Core Subsystem:
+
+ACPI 2.0 support is complete in the entire Core Subsystem and the
+ASL compiler. All new ACPI 2.0 operators are implemented and all
+other changes for ACPI 2.0 support are complete. With
+simultaneous code and data optimizations throughout the subsystem,
+ACPI 2.0 support has been implemented with almost no additional
+cost in terms of code and data size.
+
+Implemented a new mechanism for allocation of return buffers. If
+the buffer length is set to ACPI_ALLOCATE_BUFFER, the buffer will
+be allocated on behalf of the caller. Consolidated all return
+buffer validation and allocation to a common procedure. Return
+buffers will be allocated via the primary OSL allocation interface
+since it appears that a separate pool is not needed by most users.
+If a separate pool is required for these buffers, the caller can
+still use the original mechanism and pre-allocate the buffer(s).
+
+Implemented support for string operands within the DerefOf
+operator.
+
+Restructured the Hardware and Event managers to be table driven,
+simplifying the source code and reducing the amount of generated
+code.
+
+Split the common read/write low-level ACPI register bitfield
+procedure into a separate read and write, simplifying the code
+considerably.
+
+Obsoleted the AcpiOsCallocate OSL interface. This interface was
+used only a handful of times and didn't have enough critical mass
+for a separate interface. Replaced with a common calloc procedure
+in the core.
+
+Fixed a reported problem with the GPE number mapping mechanism
+that allows GPE1 numbers to be non-contiguous with GPE0.
+Reorganized the GPE information and shrunk a large array that was
+originally large enough to hold info for all possible GPEs (256)
+to simply large enough to hold all GPEs up to the largest GPE
+number on the machine.
+
+Fixed a reported problem with resource structure alignment on 64-
+bit platforms.
+
+Changed the AcpiEnableEvent and AcpiDisableEvent external
+interfaces to not require any flags for the common case of
+enabling/disabling a GPE.
+
+Implemented support to allow a "Notify" on a Processor object.
+
+Most TBDs in comments within the source code have been resolved
+and eliminated.
+
+
+Fixed a problem in the interpreter where a standalone parent
+prefix (^) was not handled correctly in the interpreter and
+debugger.
+
+Removed obsolete and unnecessary GPE save/restore code.
+
+Implemented Field support in the ASL Load operator. This allows a
+table to be loaded from a named field, in addition to loading a
+table directly from an Operation Region.
+
+Implemented timeout and handle support in the external Global Lock
+interfaces.
+
+Fixed a problem in the AcpiDump utility where pathnames were no
+longer being generated correctly during the dump of named objects.
+
+Modified the AML debugger to give a full display of if/while
+predicates instead of just one AML opcode at a time. (The
+predicate can have several nested ASL statements.) The old method
+was confusing during single stepping.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release (12_18_01)
+ Non-Debug Version: 66.1K Code, 5.5K Data, 71.6K Total
+ Debug Version: 138.3K Code, 55.9K Data, 194.2K Total
+ Current Release:
+ Non-Debug Version: 65.2K Code, 6.2K Data, 71.4K Total
+ Debug Version: 136.9K Code, 56.4K Data, 193.3K Total
+
+2) Linux
+
+ Implemented fix for PIIX reverse throttling errata (Processor
+driver)
+
+Added new Limit interface (Processor and Thermal drivers)
+
+New thermal policy (Thermal driver)
+
+Many updates to /proc
+
+Battery "low" event support (Battery driver)
+
+Supports ACPI PCI IRQ routing (PCI Link and PCI root drivers)
+
+IA32 - IA64 initialization unification, no longer experimental
+
+Menuconfig options redesigned
+
+3) ASL Compiler, version X2037:
+
+Implemented several new output features to simplify integration of
+AML code into firmware: 1) Output the AML in C source code with
+labels for each named ASL object. The original ASL source code
+is interleaved as C comments. 2) Output the AML in ASM source code
+with labels and interleaved ASL source. 3) Output the AML in
+raw hex table form, in either C or ASM.
+
+Implemented support for optional string parameters to the
+LoadTable operator.
+
+Completed support for embedded escape sequences within string
+literals. The compiler now supports all single character escapes
+as well as the Octal and Hex escapes. Note: the insertion of a
+null byte into a string literal (via the hex/octal escape) causes
+the string to be immediately terminated. A warning is issued.
+
+Fixed a problem where incorrect AML was generated for the case
+where an ASL namepath consists of a single parent prefix (
+
+) with no trailing name segments.
+
+The compiler has been successfully generated with a 64-bit C
+compiler.
+
+
+
+
+----------------------------------------
+Summary of changes for this label: 12_18_01
+
+1) Linux
+
+Enhanced blacklist with reason and severity fields. Any table's
+signature may now be used to identify a blacklisted system.
+
+Call _PIC control method to inform the firmware which interrupt
+model the OS is using. Turn on any disabled link devices.
+
+Cleaned up busmgr /proc error handling (Andreas Dilger)
+
+ 2) ACPI CA Core Subsystem:
+
+Implemented ACPI 2.0 semantics for the "Break" operator (Exit from
+while loop)
+
+Completed implementation of the ACPI 2.0 "Continue",
+"ConcatenateResTemplate", "DataTableRegion", and "LoadTable"
+operators. All new ACPI 2.0 operators are now implemented in both
+the ASL compiler and the AML interpreter. The only remaining ACPI
+2.0 task is support for the String data type in the DerefOf
+operator. Fixed a problem with AcquireMutex where the status code
+was lost if the caller had to actually wait for the mutex.
+
+Increased the maximum ASL Field size from 64K bits to 4G bits.
+
+Completed implementation of the external Global Lock interfaces --
+AcpiAcquireGlobalLock and AcpiReleaseGlobalLock. The Timeout and
+Handler parameters were added.
+
+Completed another pass at removing warnings and issues when
+compiling with 64-bit compilers. The code now compiles cleanly
+with the Intel 64-bit C/C++ compiler. Most notably, the pointer
+add and subtract (diff) macros have changed considerably.
+
+
+Created and deployed a new ACPI_SIZE type that is 64-bits wide on
+64-bit platforms, 32-bits on all others. This type is used
+wherever memory allocation and/or the C sizeof() operator is used,
+and affects the OSL memory allocation interfaces AcpiOsAllocate
+and AcpiOsCallocate.
+
+Implemented sticky user breakpoints in the AML debugger.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release (12_05_01)
+ Non-Debug Version: 64.7K Code, 5.3K Data, 70.0K Total
+ Debug Version: 136.2K Code, 55.6K Data, 191.8K Total
+ Current Release:
+ Non-Debug Version: 66.1K Code, 5.5K Data, 71.6K Total
+ Debug Version: 138.3K Code, 55.9K Data, 194.2K Total
+
+ 3) ASL Compiler, version X2034:
+
+Now checks for (and generates an error if detected) the use of a
+Break or Continue statement without an enclosing While statement.
+
+
+Successfully generated the compiler with the Intel 64-bit C
+compiler.
+
+ ----------------------------------------
+Summary of changes for this label: 12_05_01
+
+ 1) ACPI CA Core Subsystem:
+
+The ACPI 2.0 CopyObject operator is fully implemented. This
+operator creates a new copy of an object (and is also used to
+bypass the "implicit conversion" mechanism of the Store operator.)
+
+The ACPI 2.0 semantics for the SizeOf operator are fully
+implemented. The change is that performing a SizeOf on a
+reference object causes an automatic dereference of the object to
+tha actual value before the size is evaluated. This behavior was
+undefined in ACPI 1.0.
+
+The ACPI 2.0 semantics for the Extended IRQ resource descriptor
+have been implemented. The interrupt polarity and mode are now
+independently set.
+
+Fixed a problem where ASL Constants (Zero, One, Ones, Revision)
+appearing in Package objects were not properly converted to
+integers when the internal Package was converted to an external
+object (via the AcpiEvaluateObject interface.)
+
+Fixed a problem with the namespace object deletion mechanism for
+objects created by control methods. There were two parts to this
+problem: 1) Objects created during the initialization phase method
+parse were not being deleted, and 2) The object owner ID mechanism
+to track objects was broken.
+
+Fixed a problem where the use of the ASL Scope operator within a
+control method would result in an invalid opcode exception.
+
+Fixed a problem introduced in the previous label where the buffer
+length required for the _PRT structure was not being returned
+correctly.
+
+Code and Data Size: Current core subsystem library sizes are shown
+below. These are the code and data sizes for the acpica.lib
+produced by the Microsoft Visual C++ 6.0 compiler, and these
+values do not include any ACPI driver or OSPM code. The debug
+version of the code includes the debug output trace mechanism and
+has a larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Release (11_20_01)
+ Non-Debug Version: 64.1K Code, 5.3K Data, 69.4K Total
+ Debug Version: 135.1K Code, 55.4K Data, 190.5K Total
+
+ Current Release:
+ Non-Debug Version: 64.7K Code, 5.3K Data, 70.0K Total
+ Debug Version: 136.2K Code, 55.6K Data, 191.8K Total
+
+ 2) Linux:
+
+Updated all files to apply cleanly against 2.4.16.
+
+Added basic PCI Interrupt Routing Table (PRT) support for IA32
+(acpi_pci.c), and unified the PRT code for IA32 and IA64. This
+version supports both static and dyanmic PRT entries, but dynamic
+entries are treated as if they were static (not yet
+reconfigurable). Architecture- specific code to use this data is
+absent on IA32 but should be available shortly.
+
+Changed the initialization sequence to start the ACPI interpreter
+(acpi_init) prior to initialization of the PCI driver (pci_init)
+in init/main.c. This ordering is required to support PRT and
+facilitate other (future) enhancement. A side effect is that the
+ACPI bus driver and certain device drivers can no longer be loaded
+as modules.
+
+Modified the 'make menuconfig' options to allow PCI Interrupt
+Routing support to be included without the ACPI Bus and other
+device drivers.
+
+ 3) ASL Compiler, version X2033:
+
+Fixed some issues with the use of the new CopyObject and
+DataTableRegion operators. Both are fully functional.
+
+ ----------------------------------------
+Summary of changes for this label: 11_20_01
+
+ 20 November 2001. Summary of changes for this release.
+
+ 1) ACPI CA Core Subsystem:
+
+Updated Index support to match ACPI 2.0 semantics. Storing a
+Integer, String, or Buffer to an Index of a Buffer will store only
+the least-significant byte of the source to the Indexed buffer
+byte. Multiple writes are not performed.
+
+Fixed a problem where the access type used in an AccessAs ASL
+operator was not recorded correctly into the field object.
+
+Fixed a problem where ASL Event objects were created in a
+signalled state. Events are now created in an unsignalled state.
+
+The internal object cache is now purged after table loading and
+initialization to reduce the use of dynamic kernel memory -- on
+the assumption that object use is greatest during the parse phase
+of the entire table (versus the run-time use of individual control
+methods.)
+
+ACPI 2.0 variable-length packages are now fully operational.
+
+Code and Data Size: Code and Data optimizations have permitted new
+feature development with an actual reduction in the library size.
+Current core subsystem library sizes are shown below. These are
+the code and data sizes for the acpica.lib produced by the
+Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code
+includes the debug output trace mechanism and has a larger code
+and data size. Note that these values will vary depending on the
+efficiency of the compiler and the compiler options used during
+generation.
+
+ Previous Release (11_09_01):
+ Non-Debug Version: 63.7K Code, 5.2K Data, 68.9K Total
+ Debug Version: 134.5K Code, 55.4K Data, 189.9K Total
+
+ Current Release:
+ Non-Debug Version: 64.1K Code, 5.3K Data, 69.4K Total
+ Debug Version: 135.1K Code, 55.4K Data, 190.5K Total
+
+ 2) Linux:
+
+Enhanced the ACPI boot-time initialization code to allow the use
+of Local APIC tables for processor enumeration on IA-32, and to
+pave the way for a fully MPS-free boot (on SMP systems) in the
+near future. This functionality replaces
+arch/i386/kernel/acpitables.c, which was introduced in an earlier
+2.4.15-preX release. To enable this feature you must add
+"acpi_boot=on" to the kernel command line -- see the help entry
+for CONFIG_ACPI_BOOT for more information. An IA-64 release is in
+the works...
+
+Restructured the configuration options to allow boot-time table
+parsing support without inclusion of the ACPI Interpreter (and
+other) code.
+
+NOTE: This release does not include fixes for the reported events,
+power-down, and thermal passive cooling issues (coming soon).
+
+ 3) ASL Compiler:
+
+Added additional typechecking for Fields within restricted access
+Operation Regions. All fields within EC and CMOS regions must be
+declared with ByteAcc. All fields withing SMBus regions must be
+declared with the BufferAcc access type.
+
+Fixed a problem where the listing file output of control methods
+no longer interleaved the actual AML code with the ASL source
+code.
+
+
+
+
+----------------------------------------
+Summary of changes for this label: 11_09_01
+
+1) ACPI CA Core Subsystem:
+
+Implemented ACPI 2.0-defined support for writes to fields with a
+Buffer, String, or Integer source operand that is smaller than the
+target field. In these cases, the source operand is zero-extended
+to fill the target field.
+
+Fixed a problem where a Field starting bit offset (within the
+parent operation region) was calculated incorrectly if the
+
+alignment of the field differed from the access width. This
+affected CreateWordField, CreateDwordField, CreateQwordField, and
+possibly other fields that use the "AccessAny" keyword.
+
+Fixed a problem introduced in the 11_02_01 release where indirect
+stores through method arguments did not operate correctly.
+
+2) Linux:
+
+Implemented boot-time ACPI table parsing support
+(CONFIG_ACPI_BOOT) for IA32 and IA64 UP/SMP systems. This code
+facilitates the use of ACPI tables (e.g. MADT, SRAT) rather than
+legacy BIOS interfaces (e.g. MPS) for the configuration of system
+processors, memory, and interrupts during setup_arch(). Note that
+this patch does not include the required architecture-specific
+changes required to apply this information -- subsequent patches
+will be posted for both IA32 and IA64 to achieve this.
+
+Added low-level sleep support for IA32 platforms, courtesy of Pat
+Mochel. This allows IA32 systems to transition to/from various
+sleeping states (e.g. S1, S3), although the lack of a centralized
+driver model and power-manageable drivers will prevent its
+(successful) use on most systems.
+
+Revamped the ACPI 'menuconfig' layout: created new "ACPI Support"
+submenu, unified IA32 and IA64 options, added new "Boot using ACPI
+tables" option, etc.
+
+Increased the default timeout for the EC driver from 1ms to 10ms
+(1000 cycles of 10us) to try to address AE_TIME errors during EC
+transactions.
+
+ ----------------------------------------
+Summary of changes for this label: 11_02_01
+
+1) ACPI CA Core Subsystem:
+
+ACPI 2.0 Support: Implemented ACPI 2.0 64-bit Field access
+(QWordAcc keyword). All ACPI 2.0 64-bit support is now
+implemented.
+
+OSL Interfaces: Several of the OSL (AcpiOs*) interfaces required
+changes to support ACPI 2.0 Qword field access. Read/Write
+PciConfiguration(), Read/Write Memory(), and Read/Write Port() now
+accept an ACPI_INTEGER (64 bits) as the value parameter. Also,
+the value parameter for the address space handler interface is now
+an ACPI_INTEGER. OSL implementations of these interfaces must now
+handle the case where the Width parameter is 64.
+
+Index Fields: Fixed a problem where unaligned bit assembly and
+disassembly for IndexFields was not supported correctly.
+
+Index and Bank Fields: Nested Index and Bank Fields are now
+supported. During field access, a check is performed to ensure
+that the value written to an Index or Bank register is not out of
+the range of the register. The Index (or Bank) register is
+written before each access to the field data. Future support will
+include allowing individual IndexFields to be wider than the
+DataRegister width.
+
+Fields: Fixed a problem where the AML interpreter was incorrectly
+attempting to write beyond the end of a Field/OpRegion. This was
+a boundary case that occurred when a DWORD field was written to a
+BYTE access OpRegion, forcing multiple writes and causing the
+interpreter to write one datum too many.
+
+Fields: Fixed a problem with Field/OpRegion access where the
+starting bit address of a field was incorrectly calculated if the
+current access type was wider than a byte (WordAcc, DwordAcc, or
+QwordAcc).
+
+Fields: Fixed a problem where forward references to individual
+FieldUnits (individual Field names within a Field definition) were
+not resolved during the AML table load.
+
+Fields: Fixed a problem where forward references from a Field
+definition to the parent Operation Region definition were not
+resolved during the AML table load.
+
+Fields: Duplicate FieldUnit names within a scope are now detected
+during AML table load.
+
+Acpi Interfaces: Fixed a problem where the AcpiGetName() interface
+returned an incorrect name for the root node.
+
+Code and Data Size: Code and Data optimizations have permitted new
+feature development with an actual reduction in the library size.
+Current core subsystem library sizes are shown below. These are
+the code and data sizes for the acpica.lib produced by the
+Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code
+includes the debug output trace mechanism and has a larger code
+and data size. Note that these values will vary depending on the
+efficiency of the compiler and the compiler options used during
+generation.
+
+ Previous Release (10_18_01):
+ Non-Debug Version: 63.9K Code, 5.1K Data, 69.0K Total
+ Debug Version: 136.7K Code, 57.4K Data, 194.2K Total
+
+ Current Release:
+ Non-Debug Version: 63.7K Code, 5.2K Data, 68.9K Total
+ Debug Version: 134.5K Code, 55.4K Data, 189.9K Total
+
+ 2) Linux:
+
+Improved /proc processor output (Pavel Machek) Re-added
+MODULE_LICENSE("GPL") to all modules.
+
+ 3) ASL Compiler version X2030:
+
+Duplicate FieldUnit names within a scope are now detected and
+flagged as errors.
+
+ 4) Documentation:
+
+Programmer Reference updated to reflect OSL and address space
+handler interface changes described above.
+
+----------------------------------------
+Summary of changes for this label: 10_18_01
+
+ACPI CA Core Subsystem:
+
+Fixed a problem with the internal object reference count mechanism
+that occasionally caused premature object deletion. This resolves
+all of the outstanding problem reports where an object is deleted
+in the middle of an interpreter evaluation. Although this problem
+only showed up in rather obscure cases, the solution to the
+problem involved an adjustment of all reference counts involving
+objects attached to namespace nodes.
+
+Fixed a problem with Field support in the interpreter where
+writing to an aligned field whose length is an exact multiple (2
+or greater) of the field access granularity would cause an attempt
+to write beyond the end of the field.
+
+The top level AML opcode execution functions within the
+interpreter have been renamed with a more meaningful and
+consistent naming convention. The modules exmonad.c and
+exdyadic.c were eliminated. New modules are exoparg1.c,
+exoparg2.c, exoparg3.c, and exoparg6.c.
+
+Support for the ACPI 2.0 "Mid" ASL operator has been implemented.
+
+Fixed a problem where the AML debugger was causing some internal
+objects to not be deleted during subsystem termination.
+
+Fixed a problem with the external AcpiEvaluateObject interface
+where the subsystem would fault if the named object to be
+evaluated refered to a constant such as Zero, Ones, etc.
+
+Fixed a problem with IndexFields and BankFields where the
+subsystem would fault if the index, data, or bank registers were
+not defined in the same scope as the field itself.
+
+Added printf format string checking for compilers that support
+this feature. Corrected more than 50 instances of issues with
+format specifiers within invocations of ACPI_DEBUG_PRINT
+throughout the core subsystem code.
+
+The ASL "Revision" operator now returns the ACPI support level
+implemented in the core - the value "2" since the ACPI 2.0 support
+is more than 50% implemented.
+
+Enhanced the output of the AML debugger "dump namespace" command
+to output in a more human-readable form.
+
+Current core subsystem library code sizes are shown below. These
+
+are the code and data sizes for the acpica.lib produced by the
+Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code
+includes the full debug trace mechanism -- leading to a much
+
+larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Previous Label (09_20_01):
+ Non-Debug Version: 65K Code, 5K Data, 70K Total
+ Debug Version: 138K Code, 58K Data, 196K Total
+
+ This Label:
+
+ Non-Debug Version: 63.9K Code, 5.1K Data, 69.0K Total
+ Debug Version: 136.7K Code, 57.4K Data, 194.2K Total
+
+Linux:
+
+Implemented a "Bad BIOS Blacklist" to track machines that have
+known ASL/AML problems.
+
+Enhanced the /proc interface for the thermal zone driver and added
+support for _HOT (the critical suspend trip point). The 'info'
+file now includes threshold/policy information, and allows setting
+of _SCP (cooling preference) and _TZP (polling frequency) values
+to the 'info' file. Examples: "echo tzp=5 > info" sets the polling
+frequency to 5 seconds, and "echo scp=1 > info" sets the cooling
+preference to the passive/quiet mode (if supported by the ASL).
+
+Implemented a workaround for a gcc bug that resuted in an OOPs
+when loading the control method battery driver.
+
+ ----------------------------------------
+Summary of changes for this label: 09_20_01
+
+ ACPI CA Core Subsystem:
+
+The AcpiEnableEvent and AcpiDisableEvent interfaces have been
+modified to allow individual GPE levels to be flagged as wake-
+enabled (i.e., these GPEs are to remain enabled when the platform
+sleeps.)
+
+The AcpiEnterSleepState and AcpiLeaveSleepState interfaces now
+support wake-enabled GPEs. This means that upon entering the
+sleep state, all GPEs that are not wake-enabled are disabled.
+When leaving the sleep state, these GPEs are reenabled.
+
+A local double-precision divide/modulo module has been added to
+enhance portability to OS kernels where a 64-bit math library is
+not available. The new module is "utmath.c".
+
+Several optimizations have been made to reduce the use of CPU
+stack. Originally over 2K, the maximum stack usage is now below
+2K at 1860 bytes (1.82k)
+
+Fixed a problem with the AcpiGetFirmwareTable interface where the
+root table pointer was not mapped into a logical address properly.
+
+Fixed a problem where a NULL pointer was being dereferenced in the
+interpreter code for the ASL Notify operator.
+
+Fixed a problem where the use of the ASL Revision operator
+returned an error. This operator now returns the current version
+of the ACPI CA core subsystem.
+
+Fixed a problem where objects passed as control method parameters
+to AcpiEvaluateObject were always deleted at method termination.
+However, these objects may end up being stored into the namespace
+by the called method. The object reference count mechanism was
+applied to these objects instead of a force delete.
+
+Fixed a problem where static strings or buffers (contained in the
+AML code) that are declared as package elements within the ASL
+code could cause a fault because the interpreter would attempt to
+delete them. These objects are now marked with the "static
+object" flag to prevent any attempt to delete them.
+
+Implemented an interpreter optimization to use operands directly
+from the state object instead of extracting the operands to local
+variables. This reduces stack use and code size, and improves
+performance.
+
+The module exxface.c was eliminated as it was an unnecessary extra
+layer of code.
+
+Current core subsystem library code sizes are shown below. These
+are the code and data sizes for the acpica.lib produced by the
+Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code
+includes the full debug trace mechanism -- leading to a much
+larger code and data size. Note that these values will vary
+depending on the efficiency of the compiler and the compiler
+options used during generation.
+
+ Non-Debug Version: 65K Code, 5K Data, 70K Total
+(Previously 69K) Debug Version: 138K Code, 58K Data, 196K
+Total (Previously 195K)
+
+Linux:
+
+Support for ACPI 2.0 64-bit integers has been added. All ACPI
+Integer objects are now 64 bits wide
+
+All Acpi data types and structures are now in lower case. Only
+Acpi macros are upper case for differentiation.
+
+ Documentation:
+
+Changes to the external interfaces as described above.
+
+ ----------------------------------------
+Summary of changes for this label: 08_31_01
+
+ ACPI CA Core Subsystem:
+
+A bug with interpreter implementation of the ASL Divide operator
+was found and fixed. The implicit function return value (not the
+explicit store operands) was returning the remainder instead of
+the quotient. This was a longstanding bug and it fixes several
+known outstanding issues on various platforms.
+
+The ACPI_DEBUG_PRINT and function trace entry/exit macros have
+been further optimized for size. There are 700 invocations of the
+DEBUG_PRINT macro alone, so each optimization reduces the size of
+the debug version of the subsystem significantly.
+
+A stack trace mechanism has been implemented. The maximum stack
+usage is about 2K on 32-bit platforms. The debugger command "stat
+stack" will display the current maximum stack usage.
+
+All public symbols and global variables within the subsystem are
+now prefixed with the string "Acpi". This keeps all of the
+symbols grouped together in a kernel map, and avoids conflicts
+with other kernel subsystems.
+
+Most of the internal fixed lookup tables have been moved into the
+code segment via the const operator.
+
+Several enhancements have been made to the interpreter to both
+reduce the code size and improve performance.
+
+Current core subsystem library code sizes are shown below. These
+are the code and data sizes for the acpica.lib produced by the
+Microsoft Visual C++ 6.0 compiler, and these values do not include
+any ACPI driver or OSPM code. The debug version of the code
+includes the full debug trace mechanism which contains over 700
+invocations of the DEBUG_PRINT macro, 500 function entry macro
+invocations, and over 900 function exit macro invocations --
+leading to a much larger code and data size. Note that these
+values will vary depending on the efficiency of the compiler and
+the compiler options used during generation.
+
+ Non-Debug Version: 64K Code, 5K Data, 69K Total
+Debug Version: 137K Code, 58K Data, 195K Total
+
+ Linux:
+
+Implemented wbinvd() macro, pending a kernel-wide definition.
+
+Fixed /proc/acpi/event to handle poll() and short reads.
+
+ ASL Compiler, version X2026:
+
+Fixed a problem introduced in the previous label where the AML
+
+code emitted for package objects produced packages with zero
+length.
+
+ ----------------------------------------
+Summary of changes for this label: 08_16_01
+
+ACPI CA Core Subsystem:
+
+The following ACPI 2.0 ASL operators have been implemented in the
+AML interpreter (These are already supported by the Intel ASL
+compiler): ToDecimalString, ToHexString, ToString, ToInteger, and
+ToBuffer. Support for 64-bit AML constants is implemented in the
+AML parser, debugger, and disassembler.
+
+The internal memory tracking mechanism (leak detection code) has
+been upgraded to reduce the memory overhead (a separate tracking
+block is no longer allocated for each memory allocation), and now
+supports all of the internal object caches.
+
+The data structures and code for the internal object caches have
+been coelesced and optimized so that there is a single cache and
+memory list data structure and a single group of functions that
+implement generic cache management. This has reduced the code
+size in both the debug and release versions of the subsystem.
+
+The DEBUG_PRINT macro(s) have been optimized for size and replaced
+by ACPI_DEBUG_PRINT. The syntax for this macro is slightly
+different, because it generates a single call to an internal
+function. This results in a savings of about 90 bytes per
+invocation, resulting in an overall code and data savings of about
+16% in the debug version of the subsystem.
+
+ Linux:
+
+Fixed C3 disk corruption problems and re-enabled C3 on supporting
+machines.
+
+Integrated low-level sleep code by Patrick Mochel.
+
+Further tweaked source code Linuxization.
+
+Other minor fixes.
+
+ ASL Compiler:
+
+Support for ACPI 2.0 variable length packages is fixed/completed.
+
+Fixed a problem where the optional length parameter for the ACPI
+2.0 ToString operator.
+
+Fixed multiple extraneous error messages when a syntax error is
+detected within the declaration line of a control method.
+
+ ----------------------------------------
+Summary of changes for this label: 07_17_01
+
+ACPI CA Core Subsystem:
+
+Added a new interface named AcpiGetFirmwareTable to obtain any
+ACPI table via the ACPI signature. The interface can be called at
+any time during kernel initialization, even before the kernel
+virtual memory manager is initialized and paging is enabled. This
+allows kernel subsystems to obtain ACPI tables very early, even
+before the ACPI CA subsystem is initialized.
+
+Fixed a problem where Fields defined with the AnyAcc attribute
+could be resolved to the incorrect address under the following
+conditions: 1) the field width is larger than 8 bits and 2) the
+parent operation region is not defined on a DWORD boundary.
+
+Fixed a problem where the interpreter is not being locked during
+namespace initialization (during execution of the _INI control
+methods), causing an error when an attempt is made to release it
+later.
+
+ACPI 2.0 support in the AML Interpreter has begun and will be
+ongoing throughout the rest of this year. In this label, The Mod
+operator is implemented.
+
+Added a new data type to contain full PCI addresses named
+ACPI_PCI_ID. This structure contains the PCI Segment, Bus, Device,
+and Function values.
+
+ Linux:
+
+Enhanced the Linux version of the source code to change most
+capitalized ACPI type names to lowercase. For example, all
+instances of ACPI_STATUS are changed to acpi_status. This will
+result in a large diff, but the change is strictly cosmetic and
+aligns the CA code closer to the Linux coding standard.
+
+OSL Interfaces:
+
+The interfaces to the PCI configuration space have been changed to
+add the PCI Segment number and to split the single 32-bit combined
+DeviceFunction field into two 16-bit fields. This was
+accomplished by moving the four values that define an address in
+PCI configuration space (segment, bus, device, and function) to
+the new ACPI_PCI_ID structure.
+
+The changes to the PCI configuration space interfaces led to a
+reexamination of the complete set of address space access
+interfaces for PCI, I/O, and Memory. The previously existing 18
+interfaces have proven difficult to maintain (any small change
+must be propagated across at least 6 interfaces) and do not easily
+allow for future expansion to 64 bits if necessary. Also, on some
+systems, it would not be appropriate to demultiplex the access
+width (8, 16, 32,or 64) before calling the OSL if the
+corresponding native OS interfaces contain a similar access width
+parameter. For these reasons, the 18 address space interfaces
+have been replaced by these 6 new ones:
+
+AcpiOsReadPciConfiguration
+AcpiOsWritePciConfiguration
+AcpiOsReadMemory
+AcpiOsWriteMemory
+AcpiOsReadPort
+AcpiOsWritePort
+
+Added a new interface named AcpiOsGetRootPointer to allow the OSL
+to perform the platform and/or OS-specific actions necessary to
+obtain the ACPI RSDP table pointer. On IA-32 platforms, this
+interface will simply call down to the CA core to perform the low-
+memory search for the table. On IA-64, the RSDP is obtained from
+EFI. Migrating this interface to the OSL allows the CA core to
+
+remain OS and platform independent.
+
+Added a new interface named AcpiOsSignal to provide a generic
+"function code and pointer" interface for various miscellaneous
+signals and notifications that must be made to the host OS. The
+first such signals are intended to support the ASL Fatal and
+Breakpoint operators. In the latter case, the AcpiOsBreakpoint
+interface has been obsoleted.
+
+The definition of the AcpiFormatException interface has been
+changed to simplify its use. The caller no longer must supply a
+buffer to the call; A pointer to a const string is now returned
+directly. This allows the call to be easily used in printf
+statements, etc. since the caller does not have to manage a local
+buffer.
+
+
+ ASL Compiler, Version X2025:
+
+The ACPI 2.0 Switch/Case/Default operators have been implemented
+and are fully functional. They will work with all ACPI 1.0
+interpreters, since the operators are simply translated to If/Else
+pairs.
+
+The ACPI 2.0 ElseIf operator is implemented and will also work
+with 1.0 interpreters, for the same reason.
+
+Implemented support for ACPI 2.0 variable-length packages. These
+packages have a separate opcode, and their size is determined by
+the interpreter at run-time.
+
+Documentation The ACPI CA Programmer Reference has been updated to
+reflect the new interfaces and changes to existing interfaces.
+
+ ------------------------------------------
+Summary of changes for this label: 06_15_01
+
+ ACPI CA Core Subsystem:
+
+Fixed a problem where a DWORD-accessed field within a Buffer
+object would get its byte address inadvertently rounded down to
+the nearest DWORD. Buffers are always Byte-accessible.
+
+ ASL Compiler, version X2024:
+
+Fixed a problem where the Switch() operator would either fault or
+hang the compiler. Note however, that the AML code for this ACPI
+2.0 operator is not yet implemented.
+
+Compiler uses the new AcpiOsGetTimer interface to obtain compile
+timings.
+
+Implementation of the CreateField operator automatically converts
+a reference to a named field within a resource descriptor from a
+byte offset to a bit offset if required.
+
+Added some missing named fields from the resource descriptor
+support. These are the names that are automatically created by the
+compiler to reference fields within a descriptor. They are only
+valid at compile time and are not passed through to the AML
+interpreter.
+
+Resource descriptor named fields are now typed as Integers and
+subject to compile-time typechecking when used in expressions.
+
+ ------------------------------------------
+Summary of changes for this label: 05_18_01
+
+ ACPI CA Core Subsystem:
+
+Fixed a couple of problems in the Field support code where bits
+from adjacent fields could be returned along with the proper field
+bits. Restructured the field support code to improve performance,
+readability and maintainability.
+
+New DEBUG_PRINTP macro automatically inserts the procedure name
+into the output, saving hundreds of copies of procedure name
+strings within the source, shrinking the memory footprint of the
+debug version of the core subsystem.
+
+ Source Code Structure:
+
+The source code directory tree was restructured to reflect the
+current organization of the component architecture. Some files
+and directories have been moved and/or renamed.
+
+ Linux:
+
+Fixed leaking kacpidpc processes.
+
+Fixed queueing event data even when /proc/acpi/event is not
+opened.
+
+ ASL Compiler, version X2020:
+
+Memory allocation performance enhancement - over 24X compile time
+improvement on large ASL files. Parse nodes and namestring
+buffers are now allocated from a large internal compiler buffer.
+
+The temporary .SRC file is deleted unless the "-s" option is
+specified
+
+The "-d" debug output option now sends all output to the .DBG file
+instead of the console.
+
+"External" second parameter is now optional
+
+"ElseIf" syntax now properly allows the predicate
+
+Last operand to "Load" now recognized as a Target operand
+
+Debug object can now be used anywhere as a normal object.
+
+ResourceTemplate now returns an object of type BUFFER
+
+EISAID now returns an object of type INTEGER
+
+"Index" now works with a STRING operand
+
+"LoadTable" now accepts optional parameters
+
+"ToString" length parameter is now optional
+
+"Interrupt (ResourceType," parse error fixed.
+
+"Register" with a user-defined region space parse error fixed
+
+Escaped backslash at the end of a string ("\\") scan/parse error
+fixed
+
+"Revision" is now an object of type INTEGER.
+
+
+
+------------------------------------------
+Summary of changes for this label: 05_02_01
+
+Linux:
+
+/proc/acpi/event now blocks properly.
+
+Removed /proc/sys/acpi. You can still dump your DSDT from
+/proc/acpi/dsdt.
+
+ ACPI CA Core Subsystem:
+
+Fixed a problem introduced in the previous label where some of the
+"small" resource descriptor types were not recognized.
+
+Improved error messages for the case where an ASL Field is outside
+the range of the parent operation region.
+
+ ASL Compiler, version X2018:
+
+
+Added error detection for ASL Fields that extend beyond the length
+of the parent operation region (only if the length of the region
+is known at compile time.) This includes fields that have a
+minimum access width that is smaller than the parent region, and
+individual field units that are partially or entirely beyond the
+extent of the parent.
+
+
+
+------------------------------------------
+Summary of changes for this label: 04_27_01
+
+ ACPI CA Core Subsystem:
+
+Fixed a problem where the namespace mutex could be released at the
+wrong time during execution of AcpiRemoveAddressSpaceHandler.
+
+Added optional thread ID output for debug traces, to simplify
+debugging of multiple threads. Added context switch notification
+when the debug code realizes that a different thread is now
+executing ACPI code.
+
+Some additional external data types have been prefixed with the
+string "ACPI_" for consistency. This may effect existing code.
+The data types affected are the external callback typedefs - e.g.,
+
+WALK_CALLBACK becomes ACPI_WALK_CALLBACK.
+
+ Linux:
+
+Fixed an issue with the OSL semaphore implementation where a
+thread was waking up with an error from receiving a SIGCHLD
+signal.
+
+Linux version of ACPI CA now uses the system C library for string
+manipulation routines instead of a local implementation.
+
+Cleaned up comments and removed TBDs.
+
+ ASL Compiler, version X2017:
+
+Enhanced error detection and reporting for all file I/O
+operations.
+
+ Documentation:
+
+Programmer Reference updated to version 1.06.
+
+
+
+------------------------------------------
+Summary of changes for this label: 04_13_01
+
+ ACPI CA Core Subsystem:
+
+Restructured support for BufferFields and RegionFields.
+BankFields support is now fully operational. All known 32-bit
+limitations on field sizes have been removed. Both BufferFields
+and (Operation) RegionFields are now supported by the same field
+management code.
+
+Resource support now supports QWORD address and IO resources. The
+16/32/64 bit address structures and the Extended IRQ structure
+have been changed to properly handle Source Resource strings.
+
+A ThreadId of -1 is now used to indicate a "mutex not acquired"
+condition internally and must never be returned by AcpiOsThreadId.
+This reserved value was changed from 0 since Unix systems allow a
+thread ID of 0.
+
+Linux:
+
+Driver code reorganized to enhance portability
+
+Added a kernel configuration option to control ACPI_DEBUG
+
+Fixed the EC driver to honor _GLK.
+
+ASL Compiler, version X2016:
+
+Fixed support for the "FixedHw" keyword. Previously, the FixedHw
+address space was set to 0, not 0x7f as it should be.
+
+ ------------------------------------------
+Summary of changes for this label: 03_13_01
+
+ ACPI CA Core Subsystem:
+
+During ACPI initialization, the _SB_._INI method is now run if
+present.
+
+Notify handler fix - notifies are deferred until the parent method
+completes execution. This fixes the "mutex already acquired"
+issue seen occasionally.
+
+Part of the "implicit conversion" rules in ACPI 2.0 have been
+found to cause compatibility problems with existing ASL/AML. The
+convert "result-to-target-type" implementation has been removed
+for stores to method Args and Locals. Source operand conversion
+is still fully implemented. Possible changes to ACPI 2.0
+specification pending.
+
+Fix to AcpiRsCalculatePciRoutingTableLength to return correct
+length.
+
+Fix for compiler warnings for 64-bit compiles.
+
+ Linux:
+
+/proc output aligned for easier parsing.
+
+Release-version compile problem fixed.
+
+New kernel configuration options documented in Configure.help.
+
+IBM 600E - Fixed Sleep button may generate "Invalid <NULL>
+context" message.
+
+ OSPM:
+
+Power resource driver integrated with bus manager.
+
+Fixed kernel fault during active cooling for thermal zones.
+
+Source Code:
+
+The source code tree has been restructured.
+
+
+
+------------------------------------------
+Summary of changes for this label: 03_02_01
+
+ Linux OS Services Layer (OSL):
+
+Major revision of all Linux-specific code.
+
+Modularized all ACPI-specific drivers.
+
+Added new thermal zone and power resource drivers.
+
+Revamped /proc interface (new functionality is under /proc/acpi).
+
+New kernel configuration options.
+
+ Linux known issues:
+
+New kernel configuration options not documented in Configure.help
+yet.
+
+
+Module dependencies not currently implemented. If used, they
+should be loaded in this order: busmgr, power, ec, system,
+processor, battery, ac_adapter, button, thermal.
+
+Modules will not load if CONFIG_MODVERSION is set.
+
+IBM 600E - entering S5 may reboot instead of shutting down.
+
+IBM 600E - Sleep button may generate "Invalid <NULL> context"
+message.
+
+Some systems may fail with "execution mutex already acquired"
+message.
+
+ ACPI CA Core Subsystem:
+
+Added a new OSL Interface, AcpiOsGetThreadId. This was required
+for the deadlock detection code. Defined to return a non-zero, 32-
+bit thread ID for the currently executing thread. May be a non-
+zero constant integer on single-thread systems.
+
+Implemented deadlock detection for internal subsystem mutexes. We
+may add conditional compilation for this code (debug only) later.
+
+ASL/AML Mutex object semantics are now fully supported. This
+includes multiple acquires/releases by owner and support for the
+
+Mutex SyncLevel parameter.
+
+A new "Force Release" mechanism automatically frees all ASL
+Mutexes that have been acquired but not released when a thread
+exits the interpreter. This forces conformance to the ACPI spec
+("All mutexes must be released when an invocation exits") and
+prevents deadlocked ASL threads. This mechanism can be expanded
+(later) to monitor other resource acquisitions if OEM ASL code
+continues to misbehave (which it will).
+
+Several new ACPI exception codes have been added for the Mutex
+support.
+
+Recursive method calls are now allowed and supported (the ACPI
+spec does in fact allow recursive method calls.) The number of
+recursive calls is subject to the restrictions imposed by the
+SERIALIZED method keyword and SyncLevel (ACPI 2.0) method
+parameter.
+
+Implemented support for the SyncLevel parameter for control
+methods (ACPI 2.0 feature)
+
+Fixed a deadlock problem when multiple threads attempted to use
+the interpreter.
+
+Fixed a problem where the string length of a String package
+element was not always set in a package returned from
+AcpiEvaluateObject.
+
+Fixed a problem where the length of a String package element was
+not always included in the length of the overall package returned
+from AcpiEvaluateObject.
+
+Added external interfaces (Acpi*) to the ACPI debug memory
+manager. This manager keeps a list of all outstanding
+allocations, and can therefore detect memory leaks and attempts to
+free memory blocks more than once. Useful for code such as the
+power manager, etc. May not be appropriate for device drivers.
+Performance with the debug code enabled is slow.
+
+The ACPI Global Lock is now an optional hardware element.
+
+ ASL Compiler Version X2015:
+
+Integrated changes to allow the compiler to be generated on
+multiple platforms.
+
+Linux makefile added to generate the compiler on Linux
+
+ Source Code:
+
+All platform-specific headers have been moved to their own
+subdirectory, Include/Platform.
+
+New source file added, Interpreter/ammutex.c
+
+New header file, Include/acstruct.h
+
+ Documentation:
+
+The programmer reference has been updated for the following new
+interfaces: AcpiOsGetThreadId AcpiAllocate AcpiCallocate AcpiFree
+
+ ------------------------------------------
+Summary of changes for this label: 02_08_01
+
+Core ACPI CA Subsystem: Fixed a problem where an error was
+incorrectly returned if the return resource buffer was larger than
+the actual data (in the resource interfaces).
+
+References to named objects within packages are resolved to the
+
+full pathname string before packages are returned directly (via
+the AcpiEvaluateObject interface) or indirectly via the resource
+interfaces.
+
+Linux OS Services Layer (OSL):
+
+Improved /proc battery interface.
+
+
+Added C-state debugging output and other miscellaneous fixes.
+
+ASL Compiler Version X2014:
+
+All defined method arguments can now be used as local variables,
+including the ones that are not actually passed in as parameters.
+The compiler tracks initialization of the arguments and issues an
+exception if they are used without prior assignment (just like
+locals).
+
+The -o option now specifies a filename prefix that is used for all
+output files, including the AML output file. Otherwise, the
+default behavior is as follows: 1) the AML goes to the file
+specified in the DSDT. 2) all other output files use the input
+source filename as the base.
+
+ ------------------------------------------
+Summary of changes for this label: 01_25_01
+
+Core ACPI CA Subsystem: Restructured the implementation of object
+store support within the interpreter. This includes support for
+the Store operator as well as any ASL operators that include a
+target operand.
+
+Partially implemented support for Implicit Result-to-Target
+conversion. This is when a result object is converted on the fly
+to the type of an existing target object. Completion of this
+support is pending further analysis of the ACPI specification
+concerning this matter.
+
+CPU-specific code has been removed from the subsystem (hardware
+directory).
+
+New Power Management Timer functions added
+
+Linux OS Services Layer (OSL): Moved system state transition code
+to the core, fixed it, and modified Linux OSL accordingly.
+
+Fixed C2 and C3 latency calculations.
+
+
+We no longer use the compilation date for the version message on
+initialization, but retrieve the version from AcpiGetSystemInfo().
+
+Incorporated for fix Sony VAIO machines.
+
+Documentation: The Programmer Reference has been updated and
+reformatted.
+
+
+ASL Compiler: Version X2013: Fixed a problem where the line
+numbering and error reporting could get out of sync in the
+presence of multiple include files.
+
+ ------------------------------------------
+Summary of changes for this label: 01_15_01
+
+Core ACPI CA Subsystem:
+
+Implemented support for type conversions in the execution of the
+ASL Concatenate operator (The second operand is converted to
+match the type of the first operand before concatenation.)
+
+Support for implicit source operand conversion is partially
+implemented. The ASL source operand types Integer, Buffer, and
+String are freely interchangeable for most ASL operators and are
+converted by the interpreter on the fly as required. Implicit
+Target operand conversion (where the result is converted to the
+target type before storing) is not yet implemented.
+
+Support for 32-bit and 64-bit BCD integers is implemented.
+
+Problem fixed where a field read on an aligned field could cause a
+read past the end of the field.
+
+New exception, AE_AML_NO_RETURN_VALUE, is returned when a method
+does not return a value, but the caller expects one. (The ASL
+compiler flags this as a warning.)
+
+ASL Compiler:
+
+Version X2011:
+1. Static typechecking of all operands is implemented. This
+prevents the use of invalid objects (such as using a Package where
+an Integer is required) at compile time instead of at interpreter
+run-time.
+2. The ASL source line is printed with ALL errors and warnings.
+3. Bug fix for source EOF without final linefeed.
+4. Debug option is split into a parse trace and a namespace trace.
+5. Namespace output option (-n) includes initial values for
+integers and strings.
+6. Parse-only option added for quick syntax checking.
+7. Compiler checks for duplicate ACPI name declarations
+
+Version X2012:
+1. Relaxed typechecking to allow interchangeability between
+strings, integers, and buffers. These types are now converted by
+the interpreter at runtime.
+2. Compiler reports time taken by each internal subsystem in the
+debug output file.
+
+
+ ------------------------------------------
+Summary of changes for this label: 12_14_00
+
+ASL Compiler:
+
+This is the first official release of the compiler. Since the
+compiler requires elements of the Core Subsystem, this label
+synchronizes everything.
+
+------------------------------------------
+Summary of changes for this label: 12_08_00
+
+
+Fixed a problem where named references within the ASL definition
+of both OperationRegions and CreateXXXFields did not work
+properly. The symptom was an AE_AML_OPERAND_TYPE during
+initialization of the region/field. This is similar (but not
+related internally) to the problem that was fixed in the last
+label.
+
+Implemented both 32-bit and 64-bit support for the BCD ASL
+functions ToBCD and FromBCD.
+
+Updated all legal headers to include "2000" in the copyright
+years.
+
+ ------------------------------------------
+Summary of changes for this label: 12_01_00
+
+Fixed a problem where method invocations within the ASL definition
+of both OperationRegions and CreateXXXFields did not work
+properly. The symptom was an AE_AML_OPERAND_TYPE during
+initialization of the region/field:
+
+ nsinit-0209: AE_AML_OPERAND_TYPE while getting region arguments
+[DEBG] ammonad-0284: Exec_monadic2_r/Not: bad operand(s)
+(0x3005)
+
+Fixed a problem where operators with more than one nested
+subexpression would fail. The symptoms were varied, by mostly
+AE_AML_OPERAND_TYPE errors. This was actually a rather serious
+problem that has gone unnoticed until now.
+
+ Subtract (Add (1,2), Multiply (3,4))
+
+Fixed a problem where AcpiGetHandle didn't quite get fixed in the
+previous build (The prefix part of a relative path was handled
+incorrectly).
+
+Fixed a problem where Operation Region initialization failed if
+the operation region name was a "namepath" instead of a simple
+"nameseg". Symptom was an AE_NO_OPERAND error.
+
+Fixed a problem where an assignment to a local variable via the
+indirect RefOf mechanism only worked for the first such
+assignment. Subsequent assignments were ignored.
+
+ ------------------------------------------
+Summary of changes for this label: 11_15_00
+
+ACPI 2.0 table support with backwards support for ACPI 1.0 and the
+0.71 extensions. Note: although we can read ACPI 2.0 BIOS tables,
+the AML interpreter does NOT have support for the new 2.0 ASL
+grammar terms at this time.
+
+All ACPI hardware access is via the GAS structures in the ACPI 2.0
+FADT.
+
+All physical memory addresses across all platforms are now 64 bits
+wide. Logical address width remains dependent on the platform
+(i.e., "void *").
+
+AcpiOsMapMemory interface changed to a 64-bit physical address.
+
+The AML interpreter integer size is now 64 bits, as per the ACPI
+2.0 specification.
+
+For backwards compatibility with ACPI 1.0, ACPI tables with a
+revision number less than 2 use 32-bit integers only.
+
+Fixed a problem where the evaluation of OpRegion operands did not
+always resolve them to numbers properly.
+
+------------------------------------------
+Summary of changes for this label: 10_20_00
+
+Fix for CBN_._STA issue. This fix will allow correct access to
+CBN_ OpRegions when the _STA returns 0x8.
+
+Support to convert ACPI constants (Ones, Zeros, One) to actual
+values before a package object is returned
+
+Fix for method call as predicate to if/while construct causing
+incorrect if/while behavior
+
+Fix for Else block package lengths sometimes calculated wrong (if
+block > 63 bytes)
+
+Fix for Processor object length field, was always zero
+
+Table load abort if FACP sanity check fails
+
+Fix for problem with Scope(name) if name already exists
+
+Warning emitted if a named object referenced cannot be found
+(resolved) during method execution.
+
+
+
+
+
+------------------------------------------
+Summary of changes for this label: 9_29_00
+
+New table initialization interfaces: AcpiInitializeSubsystem no
+longer has any parameters AcpiFindRootPointer - Find the RSDP (if
+necessary) AcpiLoadTables (RSDP) - load all tables found at RSDP-
+>RSDT Obsolete Interfaces AcpiLoadFirmwareTables - replaced by
+AcpiLoadTables
+
+Note: These interface changes require changes to all existing OSDs
+
+The PCI_Config default address space handler is always installed
+at the root namespace object.
+
+-------------------------------------------
+Summary of changes for this label: 09_15_00
+
+The new initialization architecture is implemented. New
+interfaces are: AcpiInitializeSubsystem (replaces AcpiInitialize)
+AcpiEnableSubsystem Obsolete Interfaces: AcpiLoadNamespace
+
+(Namespace is automatically loaded when a table is loaded)
+
+The ACPI_OPERAND_OBJECT has been optimized to shrink its size from
+52 bytes to 32 bytes. There is usually one of these for every
+namespace object, so the memory savings is significant.
+
+Implemented just-in-time evaluation of the CreateField operators.
+
+Bug fixes for IA-64 support have been integrated.
+
+Additional code review comments have been implemented
+
+The so-called "third pass parse" has been replaced by a final walk
+through the namespace to initialize all operation regions (address
+spaces) and fields that have not yet been initialized during the
+execution of the various _INI and REG methods.
+
+New file - namespace/nsinit.c
+
+-------------------------------------------
+Summary of changes for this label: 09_01_00
+
+Namespace manager data structures have been reworked to change the
+primary object from a table to a single object. This has
+resulted in dynamic memory savings of 3X within the namespace and
+2X overall in the ACPI CA subsystem.
+
+Fixed problem where the call to AcpiEvFindPciRootBuses was
+inadvertently left commented out.
+
+Reduced the warning count when generating the source with the GCC
+compiler.
+
+Revision numbers added to each module header showing the
+SourceSafe version of the file. Please refer to this version
+number when giving us feedback or comments on individual modules.
+
+The main object types within the subsystem have been renamed to
+clarify their purpose:
+
+ACPI_INTERNAL_OBJECT -> ACPI_OPERAND_OBJECT
+ACPI_GENERIC_OP -> ACPI_PARSE_OBJECT
+ACPI_NAME_TABLE_ENTRY -> ACPI_NAMESPACE_NODE
+
+NOTE: no changes to the initialization sequence are included in
+this label.
+
+-------------------------------------------
+Summary of changes for this label: 08_23_00
+
+Fixed problem where TerminateControlMethod was being called
+multiple times per method
+
+Fixed debugger problem where single stepping caused a semaphore to
+be oversignalled
+
+Improved performance through additional parse object caching -
+added ACPI_EXTENDED_OP type
+
+-------------------------------------------
+Summary of changes for this label: 08_10_00
+
+Parser/Interpreter integration: Eliminated the creation of
+complete parse trees for ACPI tables and control methods.
+Instead, parse subtrees are created and then deleted as soon as
+they are processed (Either entered into the namespace or executed
+by the interpreter). This reduces the use of dynamic kernel
+memory significantly. (about 10X)
+
+Exception codes broken into classes and renumbered. Be sure to
+recompile all code that includes acexcep.h. Hopefully we won't
+have to renumber the codes again now that they are split into
+classes (environment, programmer, AML code, ACPI table, and
+internal).
+
+Fixed some additional alignment issues in the Resource Manager
+subcomponent
+
+Implemented semaphore tracking in the AcpiExec utility, and fixed
+several places where mutexes/semaphores were being unlocked
+without a corresponding lock operation. There are no known
+semaphore or mutex "leaks" at this time.
+
+Fixed the case where an ASL Return operator is used to return an
+unnamed package.
+
+-------------------------------------------
+Summary of changes for this label: 07_28_00
+
+Fixed a problem with the way addresses were calculated in
+AcpiAmlReadFieldData() and AcpiAmlWriteFieldData(). This problem
+manifested itself when a Field was created with WordAccess or
+DwordAccess, but the field unit defined within the Field was less
+
+than a Word or Dword.
+
+Fixed a problem in AmlDumpOperands() module's loop to pull
+operands off of the operand stack to display information. The
+problem manifested itself as a TLB error on 64-bit systems when
+accessing an operand stack with two or more operands.
+
+Fixed a problem with the PCI configuration space handlers where
+context was getting confused between accesses. This required a
+change to the generic address space handler and address space
+setup definitions. Handlers now get both a global handler context
+(this is the one passed in by the user when executing
+AcpiInstallAddressSpaceHandler() and a specific region context
+that is unique to each region (For example, the _ADR, _SEG and
+_BBN values associated with a specific region). The generic
+function definitions have changed to the following:
+
+typedef ACPI_STATUS (*ADDRESS_SPACE_HANDLER) ( UINT32 Function,
+UINT32 Address, UINT32 BitWidth, UINT32 *Value, void
+*HandlerContext, // This used to be void *Context void
+*RegionContext); // This is an additional parameter
+
+typedef ACPI_STATUS (*ADDRESS_SPACE_SETUP) ( ACPI_HANDLE
+RegionHandle, UINT32 Function, void *HandlerContext, void
+**RegionContext); // This used to be **ReturnContext
+
+-------------------------------------------
+Summary of changes for this label: 07_21_00
+
+Major file consolidation and rename. All files within the
+interpreter have been renamed as well as most header files. This
+was done to prevent collisions with existing files in the host
+OSs -- filenames such as "config.h" and "global.h" seem to be
+quite common. The VC project files have been updated. All
+makefiles will require modification.
+
+The parser/interpreter integration continues in Phase 5 with the
+implementation of a complete 2-pass parse (the AML is parsed
+twice) for each table; This avoids the construction of a huge
+parse tree and therefore reduces the amount of dynamic memory
+required by the subsystem. Greater use of the parse object cache
+means that performance is unaffected.
+
+Many comments from the two code reviews have been rolled in.
+
+The 64-bit alignment support is complete.
+
+-------------------------------------------
+Summary of changes for this label: 06_30_00
+
+With a nod and a tip of the hat to the technology of yesteryear,
+we've added support in the source code for 80 column output
+devices. The code is now mostly constrained to 80 columns or
+less to support environments and editors that 1) cannot display
+or print more than 80 characters on a single line, and 2) cannot
+disable line wrapping.
+
+A major restructuring of the namespace data structure has been
+completed. The result is 1) cleaner and more
+understandable/maintainable code, and 2) a significant reduction
+in the dynamic memory requirement for each named ACPI object
+(almost half).
+
+-------------------------------------------
+Summary of changes for this label: 06_23_00
+
+Linux support has been added. In order to obtain approval to get
+the ACPI CA subsystem into the Linux kernel, we've had to make
+quite a few changes to the base subsystem that will affect all
+users (all the changes are generic and OS- independent). The
+effects of these global changes have been somewhat far reaching.
+Files have been merged and/or renamed and interfaces have been
+renamed. The major changes are described below.
+
+Osd* interfaces renamed to AcpiOs* to eliminate namespace
+pollution/confusion within our target kernels. All OSD
+interfaces must be modified to match the new naming convention.
+
+Files merged across the subsystem. A number of the smaller source
+and header files have been merged to reduce the file count and
+increase the density of the existing files. There are too many
+to list here. In general, makefiles that call out individual
+files will require rebuilding.
+
+Interpreter files renamed. All interpreter files now have the
+prefix am* instead of ie* and is*.
+
+Header files renamed: The acapi.h file is now acpixf.h. The
+acpiosd.h file is now acpiosxf.h. We are removing references to
+the acronym "API" since it is somewhat windowsy. The new name is
+"external interface" or xface or xf in the filenames.j
+
+
+All manifest constants have been forced to upper case (some were
+mixed case.) Also, the string "ACPI_" has been prepended to many
+(not all) of the constants, typedefs, and structs.
+
+The globals "DebugLevel" and "DebugLayer" have been renamed
+"AcpiDbgLevel" and "AcpiDbgLayer" respectively.
+
+All other globals within the subsystem are now prefixed with
+"AcpiGbl_" Internal procedures within the subsystem are now
+prefixed with "Acpi" (with only a few exceptions). The original
+two-letter abbreviation for the subcomponent remains after "Acpi"
+- for example, CmCallocate became AcpiCmCallocate.
+
+Added a source code translation/conversion utility. Used to
+generate the Linux source code, it can be modified to generate
+other types of source as well. Can also be used to cleanup
+existing source by removing extraneous spaces and blank lines.
+Found in tools/acpisrc/*
+
+OsdUnMapMemory was renamed to OsdUnmapMemory and then
+AcpiOsUnmapMemory. (UnMap became Unmap).
+
+A "MaxUnits" parameter has been added to AcpiOsCreateSemaphore.
+When set to one, this indicates that the caller wants to use the
+
+semaphore as a mutex, not a counting semaphore. ACPI CA uses
+both types. However, implementers of this call may want to use
+different OS primitives depending on the type of semaphore
+requested. For example, some operating systems provide separate
+
+"mutex" and "semaphore" interfaces - where the mutex interface is
+much faster because it doesn't have all the overhead of a full
+semaphore implementation.
+
+Fixed a deadlock problem where a method that accesses the PCI
+address space can block forever if it is the first access to the
+space.
+
+-------------------------------------------
+Summary of changes for this label: 06_02_00
+
+Support for environments that cannot handle unaligned data
+accesses (e.g. firmware and OS environments devoid of alignment
+handler technology namely SAL/EFI and the IA-64 Linux kernel) has
+been added (via configurable macros) in these three areas: -
+Transfer of data from the raw AML byte stream is done via byte
+moves instead of word/dword/qword moves. - External objects are
+aligned within the user buffer, including package elements (sub-
+objects). - Conversion of name strings to UINT32 Acpi Names is now
+done byte-wise.
+
+The Store operator was modified to mimic Microsoft's
+implementation when storing to a Buffer Field.
+
+Added a check of the BM_STS bit before entering C3.
+
+The methods subdirectory has been obsoleted and removed. A new
+file, cmeval.c subsumes the functionality.
+
+A 16-bit (DOS) version of AcpiExec has been developed. The
+makefile is under the acpiexec directory.
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/acgetline.c b/usr/src/boot/sys/contrib/dev/acpica/common/acgetline.c
new file mode 100644
index 0000000000..712b4a3f7d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/acgetline.c
@@ -0,0 +1,440 @@
+/******************************************************************************
+ *
+ * Module Name: acgetline - local line editing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+#include <stdio.h>
+
+/*
+ * This is an os-independent implementation of line-editing services needed
+ * by the AcpiExec utility. It uses getchar() and putchar() and the existing
+ * history support provided by the AML debugger. It assumes that the terminal
+ * is in the correct line-editing mode such as raw and noecho. The OSL
+ * interface AcpiOsInitialize should do this. AcpiOsTerminate should put the
+ * terminal back into the original mode.
+ */
+#define _COMPONENT ACPI_OS_SERVICES
+ ACPI_MODULE_NAME ("acgetline")
+
+
+/* Local prototypes */
+
+static void
+AcpiAcClearLine (
+ UINT32 EndOfLine,
+ UINT32 CursorPosition);
+
+/* Various ASCII constants */
+
+#define _ASCII_NUL 0
+#define _ASCII_BACKSPACE 0x08
+#define _ASCII_TAB 0x09
+#define _ASCII_ESCAPE 0x1B
+#define _ASCII_SPACE 0x20
+#define _ASCII_LEFT_BRACKET 0x5B
+#define _ASCII_DEL 0x7F
+#define _ASCII_UP_ARROW 'A'
+#define _ASCII_DOWN_ARROW 'B'
+#define _ASCII_RIGHT_ARROW 'C'
+#define _ASCII_LEFT_ARROW 'D'
+#define _ASCII_NEWLINE '\n'
+
+extern UINT32 AcpiGbl_NextCmdNum;
+
+/* Erase a single character on the input command line */
+
+#define ACPI_CLEAR_CHAR() \
+ putchar (_ASCII_BACKSPACE); \
+ putchar (_ASCII_SPACE); \
+ putchar (_ASCII_BACKSPACE);
+
+/* Backup cursor by Count positions */
+
+#define ACPI_BACKUP_CURSOR(i, Count) \
+ for (i = 0; i < (Count); i++) \
+ {putchar (_ASCII_BACKSPACE);}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiAcClearLine
+ *
+ * PARAMETERS: EndOfLine - Current end-of-line index
+ * CursorPosition - Current cursor position within line
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Clear the entire command line the hard way, but probably the
+ * most portable.
+ *
+ *****************************************************************************/
+
+static void
+AcpiAcClearLine (
+ UINT32 EndOfLine,
+ UINT32 CursorPosition)
+{
+ UINT32 i;
+
+
+ if (CursorPosition < EndOfLine)
+ {
+ /* Clear line from current position to end of line */
+
+ for (i = 0; i < (EndOfLine - CursorPosition); i++)
+ {
+ putchar (' ');
+ }
+ }
+
+ /* Clear the entire line */
+
+ for (; EndOfLine > 0; EndOfLine--)
+ {
+ ACPI_CLEAR_CHAR ();
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetLine
+ *
+ * PARAMETERS: Buffer - Where to return the command line
+ * BufferLength - Maximum length of Buffer
+ * BytesRead - Where the actual byte count is returned
+ *
+ * RETURN: Status and actual bytes read
+ *
+ * DESCRIPTION: Get the next input line from the terminal. NOTE: terminal
+ * is expected to be in a mode that supports line-editing (raw,
+ * noecho). This function is intended to be very portable. Also,
+ * it uses the history support implemented in the AML debugger.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsGetLine (
+ char *Buffer,
+ UINT32 BufferLength,
+ UINT32 *BytesRead)
+{
+ char *NextCommand;
+ UINT32 MaxCommandIndex = AcpiGbl_NextCmdNum - 1;
+ UINT32 CurrentCommandIndex = MaxCommandIndex;
+ UINT32 PreviousCommandIndex = MaxCommandIndex;
+ int InputChar;
+ UINT32 CursorPosition = 0;
+ UINT32 EndOfLine = 0;
+ UINT32 i;
+
+
+ /* Always clear the line buffer before we read a new line */
+
+ memset (Buffer, 0, BufferLength);
+
+ /*
+ * This loop gets one character at a time (except for esc sequences)
+ * until a newline or error is detected.
+ *
+ * Note: Don't attempt to write terminal control ESC sequences, even
+ * though it makes certain things more difficult.
+ */
+ while (1)
+ {
+ if (EndOfLine >= (BufferLength - 1))
+ {
+ return (AE_BUFFER_OVERFLOW);
+ }
+
+ InputChar = getchar ();
+ switch (InputChar)
+ {
+ default: /* This is the normal character case */
+
+ /* Echo the character (at EOL) and copy it to the line buffer */
+
+ if (EndOfLine == CursorPosition)
+ {
+ putchar (InputChar);
+ Buffer[EndOfLine] = (char) InputChar;
+
+ EndOfLine++;
+ CursorPosition++;
+ Buffer[EndOfLine] = 0;
+ continue;
+ }
+
+ /* Insert character into the middle of the buffer */
+
+ memmove (&Buffer[CursorPosition + 1], &Buffer[CursorPosition],
+ (EndOfLine - CursorPosition + 1));
+
+ Buffer [CursorPosition] = (char) InputChar;
+ Buffer [EndOfLine + 1] = 0;
+
+ /* Display the new part of line starting at the new character */
+
+ fprintf (stdout, "%s", &Buffer[CursorPosition]);
+
+ /* Restore cursor */
+
+ ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition);
+ CursorPosition++;
+ EndOfLine++;
+ continue;
+
+ case _ASCII_DEL: /* Backspace key */
+
+ if (!EndOfLine) /* Any characters on the command line? */
+ {
+ continue;
+ }
+
+ if (EndOfLine == CursorPosition) /* Erase the final character */
+ {
+ ACPI_CLEAR_CHAR ();
+ EndOfLine--;
+ CursorPosition--;
+ continue;
+ }
+
+ if (!CursorPosition) /* Do not backup beyond start of line */
+ {
+ continue;
+ }
+
+ /* Remove the character from the line */
+
+ memmove (&Buffer[CursorPosition - 1], &Buffer[CursorPosition],
+ (EndOfLine - CursorPosition + 1));
+
+ /* Display the new part of line starting at the new character */
+
+ putchar (_ASCII_BACKSPACE);
+ fprintf (stdout, "%s ", &Buffer[CursorPosition - 1]);
+
+ /* Restore cursor */
+
+ ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition + 1);
+ EndOfLine--;
+ if (CursorPosition > 0)
+ {
+ CursorPosition--;
+ }
+ continue;
+
+ case _ASCII_NEWLINE: /* Normal exit case at end of command line */
+ case _ASCII_NUL:
+
+ /* Return the number of bytes in the command line string */
+
+ if (BytesRead)
+ {
+ *BytesRead = EndOfLine;
+ }
+
+ /* Echo, terminate string buffer, and exit */
+
+ putchar (InputChar);
+ Buffer[EndOfLine] = 0;
+ return (AE_OK);
+
+ case _ASCII_TAB:
+
+ /* Ignore */
+
+ continue;
+
+ case EOF:
+
+ return (AE_ERROR);
+
+ case _ASCII_ESCAPE:
+
+ /* Check for escape sequences of the form "ESC[x" */
+
+ InputChar = getchar ();
+ if (InputChar != _ASCII_LEFT_BRACKET)
+ {
+ continue; /* Ignore this ESC, does not have the '[' */
+ }
+
+ /* Get the code following the ESC [ */
+
+ InputChar = getchar (); /* Backup one character */
+ switch (InputChar)
+ {
+ case _ASCII_LEFT_ARROW:
+
+ if (CursorPosition > 0)
+ {
+ putchar (_ASCII_BACKSPACE);
+ CursorPosition--;
+ }
+ continue;
+
+ case _ASCII_RIGHT_ARROW:
+ /*
+ * Move one character forward. Do this without sending
+ * ESC sequence to the terminal for max portability.
+ */
+ if (CursorPosition < EndOfLine)
+ {
+ /* Backup to start of line and print the entire line */
+
+ ACPI_BACKUP_CURSOR (i, CursorPosition);
+ fprintf (stdout, "%s", Buffer);
+
+ /* Backup to where the cursor should be */
+
+ CursorPosition++;
+ ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition);
+ }
+ continue;
+
+ case _ASCII_UP_ARROW:
+
+ /* If no commands available or at start of history list, ignore */
+
+ if (!CurrentCommandIndex)
+ {
+ continue;
+ }
+
+ /* Manage our up/down progress */
+
+ if (CurrentCommandIndex > PreviousCommandIndex)
+ {
+ CurrentCommandIndex = PreviousCommandIndex;
+ }
+
+ /* Get the historical command from the debugger */
+
+ NextCommand = AcpiDbGetHistoryByIndex (CurrentCommandIndex);
+ if (!NextCommand)
+ {
+ return (AE_ERROR);
+ }
+
+ /* Make this the active command and echo it */
+
+ AcpiAcClearLine (EndOfLine, CursorPosition);
+ strcpy (Buffer, NextCommand);
+ fprintf (stdout, "%s", Buffer);
+ EndOfLine = CursorPosition = strlen (Buffer);
+
+ PreviousCommandIndex = CurrentCommandIndex;
+ CurrentCommandIndex--;
+ continue;
+
+ case _ASCII_DOWN_ARROW:
+
+ if (!MaxCommandIndex) /* Any commands available? */
+ {
+ continue;
+ }
+
+ /* Manage our up/down progress */
+
+ if (CurrentCommandIndex < PreviousCommandIndex)
+ {
+ CurrentCommandIndex = PreviousCommandIndex;
+ }
+
+ /* If we are the end of the history list, output a clear new line */
+
+ if ((CurrentCommandIndex + 1) > MaxCommandIndex)
+ {
+ AcpiAcClearLine (EndOfLine, CursorPosition);
+ EndOfLine = CursorPosition = 0;
+ PreviousCommandIndex = CurrentCommandIndex;
+ continue;
+ }
+
+ PreviousCommandIndex = CurrentCommandIndex;
+ CurrentCommandIndex++;
+
+ /* Get the historical command from the debugger */
+
+ NextCommand = AcpiDbGetHistoryByIndex (CurrentCommandIndex);
+ if (!NextCommand)
+ {
+ return (AE_ERROR);
+ }
+
+ /* Make this the active command and echo it */
+
+ AcpiAcClearLine (EndOfLine, CursorPosition);
+ strcpy (Buffer, NextCommand);
+ fprintf (stdout, "%s", Buffer);
+ EndOfLine = CursorPosition = strlen (Buffer);
+ continue;
+
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ /*
+ * Ignore the various keys like insert/delete/home/end, etc.
+ * But we must eat the final character of the ESC sequence.
+ */
+ InputChar = getchar ();
+ continue;
+
+ default:
+
+ /* Ignore random escape sequences that we don't care about */
+
+ continue;
+ }
+ continue;
+ }
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/adfile.c b/usr/src/boot/sys/contrib/dev/acpica/common/adfile.c
new file mode 100644
index 0000000000..2bfe7edfbc
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/adfile.c
@@ -0,0 +1,358 @@
+/******************************************************************************
+ *
+ * Module Name: adfile - Application-level disassembler file support routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#include <stdio.h>
+
+
+#define _COMPONENT ACPI_TOOLS
+ ACPI_MODULE_NAME ("adfile")
+
+/* Local prototypes */
+
+static INT32
+AdWriteBuffer (
+ char *Filename,
+ char *Buffer,
+ UINT32 Length);
+
+static char FilenameBuf[20];
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AfGenerateFilename
+ *
+ * PARAMETERS: Prefix - prefix string
+ * TableId - The table ID
+ *
+ * RETURN: Pointer to the completed string
+ *
+ * DESCRIPTION: Build an output filename from an ACPI table ID string
+ *
+ ******************************************************************************/
+
+char *
+AdGenerateFilename (
+ char *Prefix,
+ char *TableId)
+{
+ UINT32 i;
+ UINT32 j;
+
+
+ for (i = 0; Prefix[i]; i++)
+ {
+ FilenameBuf[i] = Prefix[i];
+ }
+
+ FilenameBuf[i] = '_';
+ i++;
+
+ for (j = 0; j < 8 && (TableId[j] != ' ') && (TableId[j] != 0); i++, j++)
+ {
+ FilenameBuf[i] = TableId[j];
+ }
+
+ FilenameBuf[i] = 0;
+ strcat (FilenameBuf, ACPI_TABLE_FILE_SUFFIX);
+ return (FilenameBuf);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AfWriteBuffer
+ *
+ * PARAMETERS: Filename - name of file
+ * Buffer - data to write
+ * Length - length of data
+ *
+ * RETURN: Actual number of bytes written
+ *
+ * DESCRIPTION: Open a file and write out a single buffer
+ *
+ ******************************************************************************/
+
+static INT32
+AdWriteBuffer (
+ char *Filename,
+ char *Buffer,
+ UINT32 Length)
+{
+ FILE *File;
+ ACPI_SIZE Actual;
+
+
+ File = fopen (Filename, "wb");
+ if (!File)
+ {
+ printf ("Could not open file %s\n", Filename);
+ return (-1);
+ }
+
+ Actual = fwrite (Buffer, 1, (size_t) Length, File);
+ if (Actual != Length)
+ {
+ printf ("Could not write to file %s\n", Filename);
+ }
+
+ fclose (File);
+ return ((INT32) Actual);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AfWriteTable
+ *
+ * PARAMETERS: Table - pointer to the ACPI table
+ * Length - length of the table
+ * TableName - the table signature
+ * OemTableID - from the table header
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the loaded tables to a file (or files)
+ *
+ ******************************************************************************/
+
+void
+AdWriteTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length,
+ char *TableName,
+ char *OemTableId)
+{
+ char *Filename;
+
+
+ Filename = AdGenerateFilename (TableName, OemTableId);
+ AdWriteBuffer (Filename, (char *) Table, Length);
+
+ AcpiOsPrintf ("Table [%s] written to \"%s\"\n", TableName, Filename);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlGenerateFilename
+ *
+ * PARAMETERS: InputFilename - Original ASL source filename
+ * Suffix - New extension.
+ *
+ * RETURN: New filename containing the original base + the new suffix
+ *
+ * DESCRIPTION: Generate a new filename from the ASL source filename and a new
+ * extension. Used to create the *.LST, *.TXT, etc. files.
+ *
+ ******************************************************************************/
+
+char *
+FlGenerateFilename (
+ char *InputFilename,
+ char *Suffix)
+{
+ char *Position;
+ char *NewFilename;
+ char *DirectoryPosition;
+
+
+ /*
+ * Copy the original filename to a new buffer. Leave room for the worst
+ * case where we append the suffix, an added dot and the null terminator.
+ */
+ NewFilename = UtStringCacheCalloc ((ACPI_SIZE)
+ strlen (InputFilename) + strlen (Suffix) + 2);
+ if (!NewFilename)
+ {
+ return (NULL);
+ }
+
+ strcpy (NewFilename, InputFilename);
+
+ /* Try to find the last dot in the filename */
+
+ DirectoryPosition = strrchr (NewFilename, '/');
+ Position = strrchr (NewFilename, '.');
+
+ if (Position && (Position > DirectoryPosition))
+ {
+ /* Tack on the new suffix */
+
+ Position++;
+ *Position = 0;
+ strcat (Position, Suffix);
+ }
+ else
+ {
+ /* No dot, add one and then the suffix */
+
+ strcat (NewFilename, ".");
+ strcat (NewFilename, Suffix);
+ }
+
+ return (NewFilename);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlStrdup
+ *
+ * DESCRIPTION: Local strdup function
+ *
+ ******************************************************************************/
+
+static char *
+FlStrdup (
+ char *String)
+{
+ char *NewString;
+
+
+ NewString = UtStringCacheCalloc ((ACPI_SIZE) strlen (String) + 1);
+ if (!NewString)
+ {
+ return (NULL);
+ }
+
+ strcpy (NewString, String);
+ return (NewString);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlSplitInputPathname
+ *
+ * PARAMETERS: InputFilename - The user-specified ASL source file to be
+ * compiled
+ * OutDirectoryPath - Where the directory path prefix is
+ * returned
+ * OutFilename - Where the filename part is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Split the input path into a directory and filename part
+ * 1) Directory part used to open include files
+ * 2) Filename part used to generate output filenames
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlSplitInputPathname (
+ char *InputPath,
+ char **OutDirectoryPath,
+ char **OutFilename)
+{
+ char *Substring;
+ char *DirectoryPath;
+ char *Filename;
+
+
+ if (OutDirectoryPath)
+ {
+ *OutDirectoryPath = NULL;
+ }
+
+ if (!InputPath)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the path to the input filename's directory */
+
+ DirectoryPath = FlStrdup (InputPath);
+ if (!DirectoryPath)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Convert backslashes to slashes in the entire path */
+
+ UtConvertBackslashes (DirectoryPath);
+
+ /* Backup to last slash or colon */
+
+ Substring = strrchr (DirectoryPath, '/');
+ if (!Substring)
+ {
+ Substring = strrchr (DirectoryPath, ':');
+ }
+
+ /* Extract the simple filename */
+
+ if (!Substring)
+ {
+ Filename = FlStrdup (DirectoryPath);
+ DirectoryPath[0] = 0;
+ }
+ else
+ {
+ Filename = FlStrdup (Substring + 1);
+ *(Substring+1) = 0;
+ }
+
+ if (!Filename)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ if (OutDirectoryPath)
+ {
+ *OutDirectoryPath = DirectoryPath;
+ }
+
+ if (OutFilename)
+ {
+ *OutFilename = Filename;
+ return (AE_OK);
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/adisasm.c b/usr/src/boot/sys/contrib/dev/acpica/common/adisasm.c
new file mode 100644
index 0000000000..68df6dbf9f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/adisasm.c
@@ -0,0 +1,984 @@
+/******************************************************************************
+ *
+ * Module Name: adisasm - Application-level disassembler routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#include <stdio.h>
+#include <time.h>
+
+
+#define _COMPONENT ACPI_TOOLS
+ ACPI_MODULE_NAME ("adisasm")
+
+/* Local prototypes */
+
+static void
+AdCreateTableHeader (
+ char *Filename,
+ ACPI_TABLE_HEADER *Table);
+
+static ACPI_STATUS
+AdStoreTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 *TableIndex);
+
+/* Stubs for ASL compiler */
+
+#ifndef ACPI_ASL_COMPILER
+BOOLEAN
+AcpiDsIsResultUsed (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ return TRUE;
+}
+
+ACPI_STATUS
+AcpiDsMethodError (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState)
+{
+ return (Status);
+}
+#endif
+
+ACPI_STATUS
+AcpiNsLoadTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *Node)
+{
+ return (AE_NOT_IMPLEMENTED);
+}
+
+ACPI_STATUS
+AcpiDsRestartControlMethod (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ReturnDesc)
+{
+ return (AE_OK);
+}
+
+void
+AcpiDsTerminateControlMethod (
+ ACPI_OPERAND_OBJECT *MethodDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ return;
+}
+
+ACPI_STATUS
+AcpiDsCallControlMethod (
+ ACPI_THREAD_STATE *Thread,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiDsMethodDataInitArgs (
+ ACPI_OPERAND_OBJECT **Params,
+ UINT32 MaxParamCount,
+ ACPI_WALK_STATE *WalkState)
+{
+ return (AE_OK);
+}
+
+
+static ACPI_TABLE_DESC LocalTables[1];
+static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AdInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: ACPICA and local initialization
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AdInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* ACPICA subsystem initialization */
+
+ Status = AcpiOsInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtInitGlobals ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtMutexInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiNsRootInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Setup the Table Manager (cheat - there is no RSDT) */
+
+ AcpiGbl_RootTableList.MaxTableCount = 1;
+ AcpiGbl_RootTableList.CurrentTableCount = 0;
+ AcpiGbl_RootTableList.Tables = LocalTables;
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdAmlDisassemble
+ *
+ * PARAMETERS: Filename - AML input filename
+ * OutToFile - TRUE if output should go to a file
+ * Prefix - Path prefix for output
+ * OutFilename - where the filename is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disassemble an entire ACPI table
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AdAmlDisassemble (
+ BOOLEAN OutToFile,
+ char *Filename,
+ char *Prefix,
+ char **OutFilename)
+{
+ ACPI_STATUS Status;
+ ACPI_STATUS GlobalStatus = AE_OK;
+ char *DisasmFilename = NULL;
+ char *ExternalFilename;
+ ACPI_EXTERNAL_FILE *ExternalFileList = AcpiGbl_ExternalFileList;
+ FILE *File = NULL;
+ ACPI_TABLE_HEADER *Table = NULL;
+ ACPI_TABLE_HEADER *ExternalTable;
+ ACPI_OWNER_ID OwnerId;
+
+
+ /*
+ * Input: AML code from either a file or via GetTables (memory or
+ * registry)
+ */
+ if (Filename)
+ {
+ Status = AcpiDbGetTableFromFile (Filename, &Table, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * External filenames separated by commas
+ * Example: iasl -e file1,file2,file3 -d xxx.aml
+ */
+ while (ExternalFileList)
+ {
+ ExternalFilename = ExternalFileList->Path;
+ if (!strcmp (ExternalFilename, Filename))
+ {
+ /* Next external file */
+
+ ExternalFileList = ExternalFileList->Next;
+ continue;
+ }
+
+ Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_TYPE)
+ {
+ ExternalFileList = ExternalFileList->Next;
+ GlobalStatus = AE_TYPE;
+ Status = AE_OK;
+ continue;
+ }
+ return (Status);
+ }
+
+ /* Load external table for symbol resolution */
+
+ if (ExternalTable)
+ {
+ Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /*
+ * Load namespace from names created within control methods
+ * Set owner id of nodes in external table
+ */
+ AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
+ AcpiGbl_RootNode, OwnerId);
+ AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
+ }
+
+ /* Next external file */
+
+ ExternalFileList = ExternalFileList->Next;
+ }
+
+ if (ACPI_FAILURE (GlobalStatus))
+ {
+ return (GlobalStatus);
+ }
+
+ /* Clear external list generated by Scope in external tables */
+
+ if (AcpiGbl_ExternalFileList)
+ {
+ AcpiDmClearExternalList ();
+ }
+
+ /* Load any externals defined in the optional external ref file */
+
+ AcpiDmGetExternalsFromFile ();
+ }
+ else
+ {
+ Status = AdGetLocalTables ();
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get ACPI tables, %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ if (!AcpiGbl_DmOpt_Disasm)
+ {
+ return (AE_OK);
+ }
+
+ /* Obtained the local tables, just disassemble the DSDT */
+
+ Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get DSDT, %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ AcpiOsPrintf ("\nDisassembly of DSDT\n");
+ Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
+ }
+
+ /*
+ * Output: ASL code. Redirect to a file if requested
+ */
+ if (OutToFile)
+ {
+ /* Create/Open a disassembly output file */
+
+ DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
+ if (!DisasmFilename)
+ {
+ fprintf (stderr, "Could not generate output filename\n");
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+
+ File = fopen (DisasmFilename, "w+");
+ if (!File)
+ {
+ fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+
+ AcpiOsRedirectOutput (File);
+ }
+
+ *OutFilename = DisasmFilename;
+
+ /* ForceAmlDisassembly means to assume the table contains valid AML */
+
+ if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
+ {
+ AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
+ AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
+ Table->Signature);
+ AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] "
+ "FieldName : FieldValue\n */\n\n");
+
+ AcpiDmDumpDataTable (Table);
+ fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
+ Table->Signature);
+
+ if (File)
+ {
+ fprintf (stderr, "Formatted output: %s - %u bytes\n",
+ DisasmFilename, CmGetFileSize (File));
+ }
+ }
+ else
+ {
+ /* Always parse the tables, only option is what to display */
+
+ Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ if (AslCompilerdebug)
+ {
+ AcpiOsPrintf ("/**** Before second load\n");
+
+ if (File)
+ {
+ NsSetupNamespaceListing (File);
+ NsDisplayNamespace ();
+ }
+ AcpiOsPrintf ("*****/\n");
+ }
+
+ /* Load namespace from names created within control methods */
+
+ AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
+ AcpiGbl_RootNode, OwnerId);
+
+ /*
+ * Cross reference the namespace here, in order to
+ * generate External() statements
+ */
+ AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
+ AcpiGbl_RootNode, OwnerId);
+
+ if (AslCompilerdebug)
+ {
+ AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
+ }
+
+ /* Find possible calls to external control methods */
+
+ AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
+
+ /*
+ * If we found any external control methods, we must reparse
+ * the entire tree with the new information (namely, the
+ * number of arguments per method)
+ */
+ if (AcpiDmGetExternalMethodCount ())
+ {
+ fprintf (stderr,
+ "\nFound %u external control methods, "
+ "reparsing with new information\n",
+ AcpiDmGetExternalMethodCount ());
+
+ /* Reparse, rebuild namespace */
+
+ AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
+ AcpiGbl_ParseOpRoot = NULL;
+ AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
+
+ AcpiGbl_RootNode = NULL;
+ AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
+ AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
+ AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE;
+ AcpiGbl_RootNodeStruct.Parent = NULL;
+ AcpiGbl_RootNodeStruct.Child = NULL;
+ AcpiGbl_RootNodeStruct.Peer = NULL;
+ AcpiGbl_RootNodeStruct.Object = NULL;
+ AcpiGbl_RootNodeStruct.Flags = 0;
+
+ Status = AcpiNsRootInitialize ();
+
+ /* New namespace, add the external definitions first */
+
+ AcpiDmAddExternalsToNamespace ();
+
+ /* Parse the table again. No need to reload it, however */
+
+ Status = AdParseTable (Table, NULL, FALSE, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ /* Cross reference the namespace again */
+
+ AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
+ AcpiGbl_RootNode, OwnerId);
+
+ AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
+ AcpiGbl_RootNode, OwnerId);
+
+ if (AslCompilerdebug)
+ {
+ AcpiOsPrintf ("/**** After second load and resource conversion\n");
+ if (File)
+ {
+ NsSetupNamespaceListing (File);
+ NsDisplayNamespace ();
+ }
+ AcpiOsPrintf ("*****/\n");
+
+ AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
+ }
+ }
+
+ /*
+ * Now that the namespace is finalized, we can perform namespace
+ * transforms.
+ *
+ * 1) Convert fixed-offset references to resource descriptors
+ * to symbolic references (Note: modifies namespace)
+ */
+ AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
+
+ /* Optional displays */
+
+ if (AcpiGbl_DmOpt_Disasm)
+ {
+ /* This is the real disassembly */
+
+ AdDisplayTables (Filename, Table);
+
+ /* Dump hex table if requested (-vt) */
+
+ AcpiDmDumpDataTable (Table);
+
+ fprintf (stderr, "Disassembly completed\n");
+ if (File)
+ {
+ fprintf (stderr, "ASL Output: %s - %u bytes\n",
+ DisasmFilename, CmGetFileSize (File));
+ }
+
+ if (Gbl_MapfileFlag)
+ {
+ fprintf (stderr, "%14s %s - %u bytes\n",
+ Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription,
+ Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
+ FlGetFileSize (ASL_FILE_MAP_OUTPUT));
+ }
+ }
+ }
+
+Cleanup:
+
+ if (Table && !AcpiGbl_ForceAmlDisassembly &&!AcpiUtIsAmlTable (Table))
+ {
+ ACPI_FREE (Table);
+ }
+
+ if (File)
+ {
+ if (AslCompilerdebug) /* Display final namespace, with transforms */
+ {
+ NsSetupNamespaceListing (File);
+ NsDisplayNamespace ();
+ }
+
+ fclose (File);
+ AcpiOsRedirectOutput (stdout);
+ }
+
+ AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
+ AcpiGbl_ParseOpRoot = NULL;
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdDisassemblerHeader
+ *
+ * PARAMETERS: Filename - Input file for the table
+ * TableType - Either AML or DataTable
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the disassembler header, including ACPICA signon with
+ * current time and date.
+ *
+ *****************************************************************************/
+
+void
+AdDisassemblerHeader (
+ char *Filename,
+ UINT8 TableType)
+{
+ time_t Timer;
+
+
+ time (&Timer);
+
+ /* Header and input table info */
+
+ AcpiOsPrintf ("/*\n");
+ AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
+
+ if (TableType == ACPI_IS_AML_TABLE)
+ {
+ if (AcpiGbl_CstyleDisassembly)
+ {
+ AcpiOsPrintf (
+ " * Disassembling to symbolic ASL+ operators\n"
+ " *\n");
+ }
+ else
+ {
+ AcpiOsPrintf (
+ " * Disassembling to non-symbolic legacy ASL operators\n"
+ " *\n");
+ }
+ }
+
+ AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
+ AcpiOsPrintf (" *\n");
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdCreateTableHeader
+ *
+ * PARAMETERS: Filename - Input file for the table
+ * Table - Pointer to the raw table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the ASL table header, including ACPICA signon with
+ * current time and date.
+ *
+ *****************************************************************************/
+
+static void
+AdCreateTableHeader (
+ char *Filename,
+ ACPI_TABLE_HEADER *Table)
+{
+ char *NewFilename;
+ UINT8 Checksum;
+
+
+ /*
+ * Print file header and dump original table header
+ */
+ AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
+
+ AcpiOsPrintf (" * Original Table Header:\n");
+ AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature);
+ AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length);
+
+ /* Print and validate the revision */
+
+ AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision);
+
+ switch (Table->Revision)
+ {
+ case 0:
+
+ AcpiOsPrintf (" **** Invalid Revision");
+ break;
+
+ case 1:
+
+ /* Revision of DSDT controls the ACPI integer width */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
+ {
+ AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ AcpiOsPrintf ("\n");
+
+ /* Print and validate the table checksum */
+
+ AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum);
+
+ Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
+ if (Checksum)
+ {
+ AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
+ (UINT8) (Table->Checksum - Checksum));
+ }
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId);
+ AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId);
+ AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
+ AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId);
+ AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
+ AcpiOsPrintf (" */\n");
+
+ /* Create AML output filename based on input filename */
+
+ if (Filename)
+ {
+ NewFilename = FlGenerateFilename (Filename, "aml");
+ }
+ else
+ {
+ NewFilename = UtStringCacheCalloc (9);
+ if (NewFilename)
+ {
+ strncat (NewFilename, Table->Signature, 4);
+ strcat (NewFilename, ".aml");
+ }
+ }
+
+ if (!NewFilename)
+ {
+ AcpiOsPrintf (" **** Could not generate AML output filename\n");
+ return;
+ }
+
+ /* Open the ASL definition block */
+
+ AcpiOsPrintf (
+ "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
+ NewFilename, Table->Signature, Table->Revision,
+ Table->OemId, Table->OemTableId, Table->OemRevision);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdDisplayTables
+ *
+ * PARAMETERS: Filename - Input file for the table
+ * Table - Pointer to the raw table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AdDisplayTables (
+ char *Filename,
+ ACPI_TABLE_HEADER *Table)
+{
+
+
+ if (!AcpiGbl_ParseOpRoot)
+ {
+ return (AE_NOT_EXIST);
+ }
+
+ if (!AcpiGbl_DmOpt_Listing)
+ {
+ AdCreateTableHeader (Filename, Table);
+ }
+
+ AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
+ MpEmitMappingInfo ();
+
+ if (AcpiGbl_DmOpt_Listing)
+ {
+ AcpiOsPrintf ("\n\nTable Header:\n");
+ AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
+ DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+ AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
+ AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
+ Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AdStoreTable
+ *
+ * PARAMETERS: Table - Table header
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status and table index.
+ *
+ * DESCRIPTION: Add an ACPI table to the global table list
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AdStoreTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 *TableIndex)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Initialize added table */
+
+ AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
+ ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
+ Status = AcpiTbValidateTable (TableDesc);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdGetLocalTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the ACPI tables from either memory or a file
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AdGetLocalTables (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER TableHeader;
+ ACPI_TABLE_HEADER *NewTable;
+ UINT32 TableIndex;
+
+
+ /* Get the DSDT via table override */
+
+ ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
+ AcpiOsTableOverride (&TableHeader, &NewTable);
+ if (!NewTable)
+ {
+ fprintf (stderr, "Could not obtain DSDT\n");
+ return (AE_NO_ACPI_TABLES);
+ }
+
+ AdWriteTable (NewTable, NewTable->Length,
+ ACPI_SIG_DSDT, NewTable->OemTableId);
+
+ /* Store DSDT in the Table Manager */
+
+ Status = AdStoreTable (NewTable, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ fprintf (stderr, "Could not store DSDT\n");
+ return (AE_NO_ACPI_TABLES);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AdParseTable
+ *
+ * PARAMETERS: Table - Pointer to the raw table
+ * OwnerId - Returned OwnerId of the table
+ * LoadTable - If add table to the global table list
+ * External - If this is an external table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse the DSDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AdParseTable (
+ ACPI_TABLE_HEADER *Table,
+ ACPI_OWNER_ID *OwnerId,
+ BOOLEAN LoadTable,
+ BOOLEAN External)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_WALK_STATE *WalkState;
+ UINT8 *AmlStart;
+ UINT32 AmlLength;
+ UINT32 TableIndex;
+
+
+ if (!Table)
+ {
+ return (AE_NOT_EXIST);
+ }
+
+ /* Pass 1: Parse everything except control method bodies */
+
+ fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
+
+ AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
+ AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
+
+ /* Create the root object */
+
+ AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart);
+ if (!AcpiGbl_ParseOpRoot)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0,
+ AcpiGbl_ParseOpRoot, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
+ NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
+ WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
+
+ Status = AcpiPsParseAml (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* If LoadTable is FALSE, we are parsing the last loaded table */
+
+ TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
+
+ /* Pass 2 */
+
+ if (LoadTable)
+ {
+ Status = AdStoreTable (Table, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ Status = AcpiTbAllocateOwnerId (TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (OwnerId)
+ {
+ Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
+
+ Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* No need to parse control methods of external table */
+
+ if (External)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Pass 3: Parse control methods and link their parse trees
+ * into the main parse tree
+ */
+ fprintf (stderr,
+ "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
+ Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
+ fprintf (stderr, "\n");
+
+ /* Process Resource Templates */
+
+ AcpiDmFindResources (AcpiGbl_ParseOpRoot);
+
+ fprintf (stderr, "Parsing completed\n");
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/adwalk.c b/usr/src/boot/sys/contrib/dev/acpica/common/adwalk.c
new file mode 100644
index 0000000000..b1dcf87e5a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/adwalk.c
@@ -0,0 +1,1075 @@
+/******************************************************************************
+ *
+ * Module Name: adwalk - Application-level disassembler parse tree walk routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+
+#define _COMPONENT ACPI_TOOLS
+ ACPI_MODULE_NAME ("adwalk")
+
+/*
+ * aslmap - opcode mappings and reserved method names
+ */
+ACPI_OBJECT_TYPE
+AslMapNamedOpcodeToDataType (
+ UINT16 Opcode);
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDmFindOrphanDescending (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmDumpDescending (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmXrefDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmCommonAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmLoadDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static UINT32
+AcpiDmInspectPossibleArgs (
+ UINT32 CurrentOpArgCount,
+ UINT32 TargetCount,
+ ACPI_PARSE_OBJECT *Op);
+
+static ACPI_STATUS
+AcpiDmResourceDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpTree
+ *
+ * PARAMETERS: Origin - Starting object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Parse tree walk to format and output the nodes
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpTree (
+ ACPI_PARSE_OBJECT *Origin)
+{
+ ACPI_OP_WALK_INFO Info;
+
+
+ if (!Origin)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
+ Info.Flags = 0;
+ Info.Count = 0;
+ Info.Level = 0;
+ Info.WalkState = NULL;
+ AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
+ AcpiOsPrintf ("*/\n\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFindOrphanMethods
+ *
+ * PARAMETERS: Origin - Starting object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
+ * that are not resolved in the namespace
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFindOrphanMethods (
+ ACPI_PARSE_OBJECT *Origin)
+{
+ ACPI_OP_WALK_INFO Info;
+
+
+ if (!Origin)
+ {
+ return;
+ }
+
+ Info.Flags = 0;
+ Info.Level = 0;
+ Info.WalkState = NULL;
+ AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFinishNamespaceLoad
+ *
+ * PARAMETERS: ParseTreeRoot - Root of the parse tree
+ * NamespaceRoot - Root of the internal namespace
+ * OwnerId - OwnerId of the table to be disassembled
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Load all namespace items that are created within control
+ * methods. Used before namespace cross reference
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFinishNamespaceLoad (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot,
+ ACPI_OWNER_ID OwnerId)
+{
+ ACPI_STATUS Status;
+ ACPI_OP_WALK_INFO Info;
+ ACPI_WALK_STATE *WalkState;
+
+
+ if (!ParseTreeRoot)
+ {
+ return;
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
+ if (!WalkState)
+ {
+ return;
+ }
+
+ Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Info.Flags = 0;
+ Info.Level = 0;
+ Info.WalkState = WalkState;
+ AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
+ AcpiDmCommonAscendingOp, &Info);
+ ACPI_FREE (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCrossReferenceNamespace
+ *
+ * PARAMETERS: ParseTreeRoot - Root of the parse tree
+ * NamespaceRoot - Root of the internal namespace
+ * OwnerId - OwnerId of the table to be disassembled
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Cross reference the namespace to create externals
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCrossReferenceNamespace (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot,
+ ACPI_OWNER_ID OwnerId)
+{
+ ACPI_STATUS Status;
+ ACPI_OP_WALK_INFO Info;
+ ACPI_WALK_STATE *WalkState;
+
+
+ if (!ParseTreeRoot)
+ {
+ return;
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
+ if (!WalkState)
+ {
+ return;
+ }
+
+ Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Info.Flags = 0;
+ Info.Level = 0;
+ Info.WalkState = WalkState;
+ AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
+ AcpiDmCommonAscendingOp, &Info);
+ ACPI_FREE (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmConvertResourceIndexes
+ *
+ * PARAMETERS: ParseTreeRoot - Root of the parse tree
+ * NamespaceRoot - Root of the internal namespace
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert fixed-offset references to resource descriptors to
+ * symbolic references. Should only be called after namespace has
+ * been cross referenced.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmConvertResourceIndexes (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot)
+{
+ ACPI_STATUS Status;
+ ACPI_OP_WALK_INFO Info;
+ ACPI_WALK_STATE *WalkState;
+
+
+ if (!ParseTreeRoot)
+ {
+ return;
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
+ if (!WalkState)
+ {
+ return;
+ }
+
+ Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Info.Flags = 0;
+ Info.Level = 0;
+ Info.WalkState = WalkState;
+ AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
+ AcpiDmCommonAscendingOp, &Info);
+ ACPI_FREE (WalkState);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpDescending
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Format and print contents of one parse Op.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDumpDescending (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ char *Path;
+
+
+ if (!Op)
+ {
+ return (AE_OK);
+ }
+
+ /* Most of the information (count, level, name) here */
+
+ Info->Count++;
+ AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
+
+ /* Extra info is helpful */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BYTE_OP:
+
+ AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+ case AML_WORD_OP:
+
+ AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+ case AML_DWORD_OP:
+
+ AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+ case AML_QWORD_OP:
+
+ AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
+ break;
+
+ case AML_INT_NAMEPATH_OP:
+
+ if (Op->Common.Value.String)
+ {
+ AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
+ NULL, &Path);
+ AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
+ ACPI_FREE (Path);
+ }
+ else
+ {
+ AcpiOsPrintf ("[NULL]");
+ }
+ break;
+
+ case AML_NAME_OP:
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_INT_NAMEDFIELD_OP:
+
+ AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFindOrphanDescending
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check namepath Ops for orphaned method invocations
+ *
+ * Note: Experimental.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmFindOrphanDescending (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_PARSE_OBJECT *ChildOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *ParentOp;
+ UINT32 ArgCount;
+
+
+ if (!Op)
+ {
+ return (AE_OK);
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ switch (Op->Common.AmlOpcode)
+ {
+#ifdef ACPI_UNDER_DEVELOPMENT
+ case AML_ADD_OP:
+
+ ChildOp = Op->Common.Value.Arg;
+ if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ !ChildOp->Common.Node)
+ {
+ AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
+ NULL, &Path);
+ AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s */\n",
+ Op->Common.AmlOpName, Path);
+ ACPI_FREE (Path);
+
+ NextOp = Op->Common.Next;
+ if (!NextOp)
+ {
+ /* This NamePath has no args, assume it is an integer */
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
+ return (AE_OK);
+ }
+
+ ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
+ AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
+ ArgCount, AcpiDmCountChildren (Op));
+
+ if (ArgCount < 1)
+ {
+ /* One Arg means this is just a Store(Name,Target) */
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
+ return (AE_OK);
+ }
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
+ }
+ break;
+#endif
+
+ case AML_STORE_OP:
+
+ ChildOp = Op->Common.Value.Arg;
+ if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ !ChildOp->Common.Node)
+ {
+ NextOp = Op->Common.Next;
+ if (!NextOp)
+ {
+ /* This NamePath has no args, assume it is an integer */
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
+ return (AE_OK);
+ }
+
+ ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
+ if (ArgCount <= 1)
+ {
+ /* One Arg means this is just a Store(Name,Target) */
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
+ return (AE_OK);
+ }
+
+ AcpiDmAddOpToExternalList (ChildOp,
+ ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
+ }
+ break;
+
+ case AML_INT_NAMEPATH_OP:
+
+ /* Must examine parent to see if this namepath is an argument */
+
+ ParentOp = Op->Common.Parent;
+ OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
+
+ if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
+ (OpInfo->Class != AML_CLASS_CREATE) &&
+ (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
+ (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
+ !Op->Common.Node)
+ {
+ ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
+
+ /*
+ * Check if namepath is a predicate for if/while or lone parameter to
+ * a return.
+ */
+ if (ArgCount == 0)
+ {
+ if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
+
+ /* And namepath is the first argument */
+ (ParentOp->Common.Value.Arg == Op))
+ {
+ AcpiDmAddOpToExternalList (Op,
+ Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
+ break;
+ }
+ }
+
+ /*
+ * This is a standalone namestring (not a parameter to another
+ * operator) - it *must* be a method invocation, nothing else is
+ * grammatically possible.
+ */
+ AcpiDmAddOpToExternalList (Op,
+ Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmLoadDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending handler for namespace control method object load
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmLoadDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_STATUS Status;
+ char *Path = NULL;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_NAMESPACE_NODE *Node;
+ char FieldPath[5];
+ BOOLEAN PreDefined = FALSE;
+ UINT8 PreDefineIndex = 0;
+
+
+ WalkState = Info->WalkState;
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ ObjectType = OpInfo->ObjectType;
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+
+ /* Only interested in operators that create new names */
+
+ if (!(OpInfo->Flags & AML_NAMED) &&
+ !(OpInfo->Flags & AML_CREATE))
+ {
+ goto Exit;
+ }
+
+ /* Get the NamePath from the appropriate place */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ /* For all named operators, get the new name */
+
+ Path = (char *) Op->Named.Path;
+
+ if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
+ FieldPath[4] = 0;
+ Path = FieldPath;
+ }
+ }
+ else if (OpInfo->Flags & AML_CREATE)
+ {
+ /* New name is the last child */
+
+ NextOp = Op->Common.Value.Arg;
+
+ while (NextOp->Common.Next)
+ {
+ NextOp = NextOp->Common.Next;
+ }
+ Path = NextOp->Common.Value.String;
+ }
+
+ if (!Path)
+ {
+ goto Exit;
+ }
+
+ /* Insert the name into the namespace */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Node);
+
+ Op->Common.Node = Node;
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Check if it's a predefined node */
+
+ while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
+ {
+ if (ACPI_COMPARE_NAME (Node->Name.Ascii,
+ AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
+ {
+ PreDefined = TRUE;
+ break;
+ }
+
+ PreDefineIndex++;
+ }
+
+ /*
+ * Set node owner id if it satisfies all the following conditions:
+ * 1) Not a predefined node, _SB_ etc
+ * 2) Not the root node
+ * 3) Not a node created by Scope
+ */
+
+ if (!PreDefined && Node != AcpiGbl_RootNode &&
+ Op->Common.AmlOpcode != AML_SCOPE_OP)
+ {
+ Node->OwnerId = WalkState->OwnerId;
+ }
+ }
+
+
+Exit:
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ if (Op->Common.Node)
+ {
+ Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmXrefDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending handler for namespace cross reference
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmXrefDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_OBJECT_TYPE ObjectType2;
+ ACPI_STATUS Status;
+ char *Path = NULL;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+ UINT32 ParamCount = 0;
+ char *Pathname;
+
+
+ WalkState = Info->WalkState;
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ ObjectType = OpInfo->ObjectType;
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+
+ if ((!(OpInfo->Flags & AML_NAMED)) &&
+ (!(OpInfo->Flags & AML_CREATE)) &&
+ (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
+ (Op->Common.AmlOpcode != AML_NOTIFY_OP))
+ {
+ goto Exit;
+ }
+
+
+ /* Get the NamePath from the appropriate place */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ /*
+ * Only these two operators (Alias, Scope) refer to an existing
+ * name, it is the first argument
+ */
+ if (Op->Common.AmlOpcode == AML_ALIAS_OP)
+ {
+ ObjectType = ACPI_TYPE_ANY;
+
+ NextOp = Op->Common.Value.Arg;
+ NextOp = NextOp->Common.Value.Arg;
+ if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ Path = NextOp->Common.Value.String;
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
+ Path = (char *) Op->Named.Path;
+ }
+ }
+ else if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Referenced Buffer Name is the first child */
+
+ ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
+
+ NextOp = Op->Common.Value.Arg;
+ if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ Path = NextOp->Common.Value.String;
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
+ {
+ Path = Op->Common.Value.Arg->Asl.Value.String;
+ }
+ else
+ {
+ Path = Op->Common.Value.String;
+ }
+
+ if (!Path)
+ {
+ goto Exit;
+ }
+
+ /*
+ * Lookup the name in the namespace. Name must exist at this point, or it
+ * is an invalid reference.
+ *
+ * The namespace is also used as a lookup table for references to resource
+ * descriptors and the fields within them.
+ */
+ Node = NULL;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Node);
+ if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
+ {
+ /* Node was created by an External() statement */
+
+ Status = AE_NOT_FOUND;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ /*
+ * Add this symbol as an external declaration, except if the
+ * parent is a CondRefOf operator. For this operator, we do not
+ * need an external, nor do we want one, since this can cause
+ * disassembly problems if the symbol is actually a control
+ * method.
+ */
+ if (!(Op->Asl.Parent &&
+ (Op->Asl.Parent->Asl.AmlOpcode == AML_COND_REF_OF_OP)))
+ {
+ if (Node)
+ {
+ AcpiDmAddNodeToExternalList (Node,
+ (UINT8) ObjectType, 0, 0);
+ }
+ else
+ {
+ AcpiDmAddOpToExternalList (Op, Path,
+ (UINT8) ObjectType, 0, 0);
+ }
+ }
+ }
+ }
+
+ /*
+ * Found the node, but check if it came from an external table.
+ * Add it to external list. Note: Node->OwnerId == 0 indicates
+ * one of the built-in ACPI Names (_OS_ etc.) which can safely
+ * be ignored.
+ */
+ else if (Node->OwnerId &&
+ (WalkState->OwnerId != Node->OwnerId))
+ {
+ ObjectType2 = ObjectType;
+
+ Object = AcpiNsGetAttachedObject (Node);
+ if (Object)
+ {
+ ObjectType2 = Object->Common.Type;
+ if (ObjectType2 == ACPI_TYPE_METHOD)
+ {
+ ParamCount = Object->Method.ParamCount;
+ }
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
+ ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
+
+ ACPI_FREE (Pathname);
+ Op->Common.Node = Node;
+ }
+ else
+ {
+ Op->Common.Node = Node;
+ }
+
+
+Exit:
+ /* Open new scope if necessary */
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ if (Op->Common.Node)
+ {
+ Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Process one parse op during symbolic resource index conversion.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmResourceDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_STATUS Status;
+
+
+ WalkState = Info->WalkState;
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* Open new scope if necessary */
+
+ ObjectType = OpInfo->ObjectType;
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ if (Op->Common.Node)
+ {
+
+ Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ /*
+ * Check if this operator contains a reference to a resource descriptor.
+ * If so, convert the reference into a symbolic reference.
+ */
+ AcpiDmCheckResourceReference (Op, WalkState);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommonAscendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
+ * scope if necessary.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmCommonAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_OBJECT_TYPE ObjectType;
+
+
+ /* Close scope if necessary */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ ObjectType = OpInfo->ObjectType;
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ (void) AcpiDsScopeStackPop (Info->WalkState);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmInspectPossibleArgs
+ *
+ * PARAMETERS: CurrentOpArgCount - Which arg of the current op was the
+ * possible method invocation found
+ * TargetCount - Number of targets (0,1,2) for this op
+ * Op - Parse op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Examine following args and next ops for possible arguments
+ * for an unrecognized method invocation.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDmInspectPossibleArgs (
+ UINT32 CurrentOpArgCount,
+ UINT32 TargetCount,
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 i;
+ UINT32 Last = 0;
+ UINT32 Lookahead;
+
+
+ Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
+
+ /* Lookahead for the maximum number of possible arguments */
+
+ for (i = 0; i < Lookahead; i++)
+ {
+ if (!Op)
+ {
+ break;
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /*
+ * Any one of these operators is "very probably" not a method arg
+ */
+ if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
+ (Op->Common.AmlOpcode == AML_NOTIFY_OP))
+ {
+ break;
+ }
+
+ if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
+ (OpInfo->Class != AML_CLASS_CONTROL))
+ {
+ Last = i+1;
+ }
+
+ Op = Op->Common.Next;
+ }
+
+ return (Last);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/ahids.c b/usr/src/boot/sys/contrib/dev/acpica/common/ahids.c
new file mode 100644
index 0000000000..1af6b41909
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/ahids.c
@@ -0,0 +1,240 @@
+/******************************************************************************
+ *
+ * Module Name: ahids - Table of ACPI/PNP _HID/_CID values
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("ahids")
+
+
+/*
+ * ACPI/PNP Device IDs with description strings
+ */
+const AH_DEVICE_ID AslDeviceIds[] =
+{
+ {"10EC5640", "Realtek I2S Audio Codec"},
+ {"80860F09", "Intel PWM Controller"},
+ {"80860F0A", "Intel Atom UART Controller"},
+ {"80860F0E", "Intel SPI Controller"},
+ {"80860F14", "Intel Baytrail SDIO/MMC Host Controller"},
+ {"80860F28", "Intel SST Audio DSP"},
+ {"80860F41", "Intel Baytrail I2C Host Controller"},
+ {"ACPI0001", "SMBus 1.0 Host Controller"},
+ {"ACPI0002", "Smart Battery Subsystem"},
+ {"ACPI0003", "Power Source Device"},
+ {"ACPI0004", "Module Device"},
+ {"ACPI0005", "SMBus 2.0 Host Controller"},
+ {"ACPI0006", "GPE Block Device"},
+ {"ACPI0007", "Processor Device"},
+ {"ACPI0008", "Ambient Light Sensor Device"},
+ {"ACPI0009", "I/O xAPIC Device"},
+ {"ACPI000A", "I/O APIC Device"},
+ {"ACPI000B", "I/O SAPIC Device"},
+ {"ACPI000C", "Processor Aggregator Device"},
+ {"ACPI000D", "Power Meter Device"},
+ {"ACPI000E", "Time and Alarm Device"},
+ {"ACPI000F", "User Presence Detection Device"},
+ {"ADMA0F28", "Intel Audio DMA"},
+ {"AMCR0F28", "Intel Audio Machine Driver"},
+ {"ATK4001", "Asus Radio Control Button"},
+ {"ATML1000", "Atmel Touchscreen Controller"},
+ {"AUTH2750", "AuthenTec AES2750"},
+ {"BCM2E39", "Broadcom BT Serial Bus Driver over UART Bus Enumerator"},
+ {"BCM4752E", "Broadcom GPS Controller"},
+ {"BMG0160", "Bosch Gyro Sensor"},
+ {"CPLM3218", "Capella Micro CM3218x Ambient Light Sensor"},
+ {"DELLABCE", "Dell Airplane Mode Switch Driver"},
+ {"DLAC3002", "Qualcomm Atheros Bluetooth UART Transport"},
+ {"FTTH5506", "FocalTech 5506 Touch Controller"},
+ {"HAD0F28", "Intel HDMI Audio Driver"},
+ {"INBC0000", "GPIO Expander"},
+ {"INT0002", "Virtual GPIO Controller"},
+ {"INT0800", "Intel 82802 Firmware Hub Device"},
+ {"INT3394", "ACPI System Fan"},
+ {"INT3396", "Standard Power Management Controller"},
+ {"INT33A0", "Intel Smart Connect Technology Device"},
+ {"INT33A1", "Intel Power Engine"},
+ {"INT33BB", "Intel Baytrail SD Host Controller"},
+ {"INT33BD", "Intel Baytrail Mailbox Device"},
+ {"INT33BE", "Camera Sensor OV5693"},
+ {"INT33C0", "Intel Serial I/O SPI Host Controller"},
+ {"INT33C1", "Intel Serial I/O SPI Host Controller"},
+ {"INT33C2", "Intel Serial I/O I2C Host Controller"},
+ {"INT33C3", "Intel Serial I/O I2C Host Controller"},
+ {"INT33C4", "Intel Serial I/O UART Host Controller"},
+ {"INT33C5", "Intel Serial I/O UART Host Controller"},
+ {"INT33C6", "Intel SD Host Controller"},
+ {"INT33C7", "Intel Serial I/O GPIO Host Controller"},
+ {"INT33C8", "Intel Smart Sound Technology Host Controller"},
+ {"INT33C9", "Wolfson Microelectronics Audio WM5102"},
+ {"INT33CA", "Intel SPB Peripheral"},
+ {"INT33CB", "Intel Smart Sound Technology Audio Codec"},
+ {"INT33D1", "Intel GPIO Buttons"},
+ {"INT33D2", "Intel GPIO Buttons"},
+ {"INT33D3", "Intel GPIO Buttons"},
+ {"INT33D4", "Intel GPIO Buttons"},
+ {"INT33D6", "Intel Virtual Buttons Device"},
+ {"INT33F0", "Camera Sensor MT9M114"},
+ {"INT33F4", "XPOWER PMIC Controller"},
+ {"INT33F5", "TI PMIC Controller"},
+ {"INT33FB", "MIPI-CSI Camera Sensor OV2722"},
+ {"INT33FC", "Intel Baytrail GPIO Controller"},
+ {"INT33FD", "Intel Baytrail Power Management IC"},
+ {"INT33FE", "XPOWER Battery Device"},
+ {"INT3400", "Intel Dynamic Power Performance Management"},
+ {"INT3401", "Intel Extended Thermal Model CPU"},
+ {"INT3403", "DPTF Temperature Sensor"},
+ {"INT3406", "Intel Dynamic Platform & Thermal Framework Display Participant"},
+ {"INT3407", "DPTF Platform Power Meter"},
+ {"INT340E", "Motherboard Resources"},
+ {"INT3420", "Intel Bluetooth RF Kill"},
+ {"INT3F0D", "ACPI Motherboard Resources"},
+ {"INTCF1A", "Sony IMX175 Camera Sensor"},
+ {"INTCFD9", "Intel Baytrail SOC GPIO Controller"},
+ {"INTL9C60", "Intel Baytrail SOC DMA Controller"},
+ {"INVN6500", "InvenSense MPU-6500 Six Axis Gyroscope and Accelerometer"},
+ {"LNXCPU", "Linux Logical CPU"},
+ {"LNXPOWER", "ACPI Power Resource (power gating)"},
+ {"LNXPWRBN", "System Power Button"},
+ {"LNXSYBUS", "System Bus"},
+ {"LNXSYSTM", "ACPI Root Node"},
+ {"LNXTHERM", "ACPI Thermal Zone"},
+ {"LNXVIDEO", "ACPI Video Controller"},
+ {"MAX17047", "Fuel Gauge Controller"},
+ {"MSFT0101", "TPM 2.0 Security Device"},
+ {"NXP5442", "NXP 5442 Near Field Communications Controller"},
+ {"NXP5472", "NXP NFC"},
+ {"PNP0000", "8259-compatible Programmable Interrupt Controller"},
+ {"PNP0001", "EISA Interrupt Controller"},
+ {"PNP0002", "MCA Interrupt Controller"},
+ {"PNP0003", "IO-APIC Interrupt Controller"},
+ {"PNP0100", "PC-class System Timer"},
+ {"PNP0103", "HPET System Timer"},
+ {"PNP0200", "PC-class DMA Controller"},
+ {"PNP0300", "IBM PC/XT Keyboard Controller (83 key)"},
+ {"PNP0301", "IBM PC/XT Keyboard Controller (86 key)"},
+ {"PNP0302", "IBM PC/XT Keyboard Controller (84 key)"},
+ {"PNP0303", "IBM Enhanced Keyboard (101/102-key, PS/2 Mouse)"},
+ {"PNP0400", "Standard LPT Parallel Port"},
+ {"PNP0401", "ECP Parallel Port"},
+ {"PNP0500", "Standard PC COM Serial Port"},
+ {"PNP0501", "16550A-compatible COM Serial Port"},
+ {"PNP0510", "Generic IRDA-compatible Device"},
+ {"PNP0800", "Microsoft Sound System Compatible Device"},
+ {"PNP0A03", "PCI Bus"},
+ {"PNP0A05", "Generic Container Device"},
+ {"PNP0A06", "Generic Container Device"},
+ {"PNP0A08", "PCI Express Bus"},
+ {"PNP0B00", "AT Real-Time Clock"},
+ {"PNP0B01", "Intel PIIX4-compatible RTC/CMOS Device"},
+ {"PNP0B02", "Dallas Semiconductor-compatible RTC/CMOS Device"},
+ {"PNP0C01", "System Board"},
+ {"PNP0C02", "PNP Motherboard Resources"},
+ {"PNP0C04", "x87-compatible Floating Point Processing Unit"},
+ {"PNP0C08", "ACPI Core Hardware"},
+ {"PNP0C09", "Embedded Controller Device"},
+ {"PNP0C0A", "Control Method Battery"},
+ {"PNP0C0B", "Fan (Thermal Solution)"},
+ {"PNP0C0C", "Power Button Device"},
+ {"PNP0C0D", "Lid Device"},
+ {"PNP0C0E", "Sleep Button Device"},
+ {"PNP0C0F", "PCI Interrupt Link Device"},
+ {"PNP0C10", "System Indicator Device"},
+ {"PNP0C11", "Thermal Zone"},
+ {"PNP0C12", "Device Bay Controller"},
+ {"PNP0C14", "Windows Management Instrumentation Device"},
+ {"PNP0C15", "Docking Station"},
+ {"PNP0C40", "Standard Button Controller"},
+ {"PNP0C50", "HID Protocol Device (I2C bus)"},
+ {"PNP0C60", "Display Sensor Device"},
+ {"PNP0C70", "Dock Sensor Device"},
+ {"PNP0C80", "Memory Device"},
+ {"PNP0D10", "XHCI USB Controller with debug"},
+ {"PNP0D15", "XHCI USB Controller without debug"},
+ {"PNP0D20", "EHCI USB Controller without debug"},
+ {"PNP0D25", "EHCI USB Controller with debug"},
+ {"PNP0D40", "SDA Standard Compliant SD Host Controller"},
+ {"PNP0D80", "Windows-compatible System Power Management Controller"},
+ {"PNP0F03", "Microsoft PS/2-style Mouse"},
+ {"PNP0F13", "PS/2 Mouse"},
+ {"RTL8723", "Realtek Wireless Controller"},
+ {"SMB0349", "Charger"},
+ {"SMO91D0", "Sensor Hub"},
+ {"SMSC3750", "SMSC 3750 USB MUX"},
+ {"SSPX0000", "Intel SSP Device"},
+ {"TBQ24296", "Charger"},
+
+ {NULL, NULL}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAhMatchHardwareId
+ *
+ * PARAMETERS: HardwareId - String representation of an _HID or _CID
+ *
+ * RETURN: ID info struct. NULL if HardwareId is not found
+ *
+ * DESCRIPTION: Lookup an _HID/_CID in the device ID table
+ *
+ ******************************************************************************/
+
+const AH_DEVICE_ID *
+AcpiAhMatchHardwareId (
+ char *HardwareId)
+{
+ const AH_DEVICE_ID *Info;
+
+
+ for (Info = AslDeviceIds; Info->Name; Info++)
+ {
+ if (!strcmp (HardwareId, Info->Name))
+ {
+ return (Info);
+ }
+ }
+
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/ahpredef.c b/usr/src/boot/sys/contrib/dev/acpica/common/ahpredef.c
new file mode 100644
index 0000000000..3026ce313e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/ahpredef.c
@@ -0,0 +1,369 @@
+/******************************************************************************
+ *
+ * Module Name: ahpredef - Table of all known ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("ahpredef")
+
+/*
+ * iASL only needs a partial table (short descriptions only).
+ * AcpiHelp needs the full table.
+ */
+#ifdef ACPI_ASL_COMPILER
+#define AH_PREDEF(Name, ShortDesc, LongDesc) {Name, ShortDesc}
+#else
+#define AH_PREDEF(Name, ShortDesc, LongDesc) {Name, ShortDesc, LongDesc}
+#endif
+
+/*
+ * Predefined ACPI names, with short description and return value.
+ * This table was extracted directly from the ACPI specification.
+ */
+const AH_PREDEFINED_NAME AslPredefinedInfo[] =
+{
+ AH_PREDEF ("_ACx", "Active Cooling", "Returns the active cooling policy threshold values"),
+ AH_PREDEF ("_ADR", "Address", "Returns address of a device on parent bus, and resource field"),
+ AH_PREDEF ("_AEI", "ACPI Event Interrupts", "Returns a list of GPIO events to be used as ACPI events"),
+ AH_PREDEF ("_ALC", "Ambient Light Chromaticity", "Returns the ambient light color chromaticity"),
+ AH_PREDEF ("_ALI", "Ambient Light Illuminance", "Returns the ambient light brightness"),
+ AH_PREDEF ("_ALN", "Alignment", "Base alignment, Resource Descriptor field"),
+ AH_PREDEF ("_ALP", "Ambient Light Polling", "Returns the ambient light sensor polling frequency"),
+ AH_PREDEF ("_ALR", "Ambient Light Response", "Returns the ambient light brightness to display brightness mappings"),
+ AH_PREDEF ("_ALT", "Ambient Light Temperature", "Returns the ambient light color temperature"),
+ AH_PREDEF ("_ALx", "Active List", "Returns a list of active cooling device objects"),
+ AH_PREDEF ("_ART", "Active Cooling Relationship Table", "Returns thermal relationship information between platform devices and fan devices"),
+ AH_PREDEF ("_ASI", "Address Space Id", "Resource Descriptor field"),
+ AH_PREDEF ("_ASZ", "Access Size", "Resource Descriptor field"),
+ AH_PREDEF ("_ATT", "Type-Specific Attribute", "Resource Descriptor field"),
+ AH_PREDEF ("_BAS", "Base Address", "Range base address, Resource Descriptor field"),
+ AH_PREDEF ("_BBN", "BIOS Bus Number", "Returns the PCI bus number returned by the BIOS"),
+ AH_PREDEF ("_BCL", "Brightness Control Levels", "Returns a list of supported brightness control levels"),
+ AH_PREDEF ("_BCM", "Brightness Control Method", "Sets the brightness level of the display device"),
+ AH_PREDEF ("_BCT", "Battery Charge Time", "Returns time remaining to complete charging battery"),
+ AH_PREDEF ("_BDN", "BIOS Dock Name", "Returns the Dock ID returned by the BIOS"),
+ AH_PREDEF ("_BFS", "Back From Sleep", "Inform AML of a wake event"),
+ AH_PREDEF ("_BIF", "Battery Information", "Returns a Control Method Battery information block"),
+ AH_PREDEF ("_BIX", "Battery Information Extended", "Returns a Control Method Battery extended information block"),
+ AH_PREDEF ("_BLT", "Battery Level Threshold", "Set battery level threshold preferences"),
+ AH_PREDEF ("_BM_", "Bus Master", "Resource Descriptor field"),
+ AH_PREDEF ("_BMA", "Battery Measurement Averaging Interval", "Sets battery measurement averaging interval"),
+ AH_PREDEF ("_BMC", "Battery Maintenance Control", "Sets battery maintenance and control features"),
+ AH_PREDEF ("_BMD", "Battery Maintenance Data", "Returns battery maintenance, control, and state data"),
+ AH_PREDEF ("_BMS", "Battery Measurement Sampling Time", "Sets the battery measurement sampling time"),
+ AH_PREDEF ("_BQC", "Brightness Query Current", "Returns the current display brightness level"),
+ AH_PREDEF ("_BST", "Battery Status", "Returns a Control Method Battery status block"),
+ AH_PREDEF ("_BTH", "Battery Throttle Limit", "Thermal limit for charging and discharging"),
+ AH_PREDEF ("_BTM", "Battery Time", "Returns the battery runtime"),
+ AH_PREDEF ("_BTP", "Battery Trip Point", "Sets a Control Method Battery trip point"),
+ AH_PREDEF ("_CBA", "Configuration Base Address", "Sets the base address for a PCI Express host bridge"),
+ AH_PREDEF ("_CCA", "Cache Coherency Attribute", "Returns a device's support level for cache coherency"),
+ AH_PREDEF ("_CDM", "Clock Domain", "Returns a logical processor's clock domain identifier"),
+ AH_PREDEF ("_CID", "Compatible ID", "Returns a device's Plug and Play Compatible ID list"),
+ AH_PREDEF ("_CLS", "Class Code", "Returns PCI class code and subclass"),
+ AH_PREDEF ("_CPC", "Continuous Performance Control", "Returns a list of performance control interfaces"),
+ AH_PREDEF ("_CR3", "Warm/Standby Temperature", "Temperature for a fast low power state"),
+ AH_PREDEF ("_CRS", "Current Resource Settings", "Returns the current resource settings for a device"),
+ AH_PREDEF ("_CRT", "Critical Temperature", "Returns the shutdown critical temperature"),
+ AH_PREDEF ("_CSD", "C-State Dependencies", "Returns a list of C-state dependencies"),
+ AH_PREDEF ("_CST", "C-States", "Returns a list of supported C-states"),
+ AH_PREDEF ("_CWS", "Clear Wake Alarm Status", "Clear the status of wake alarms"),
+ AH_PREDEF ("_DBT", "Debounce Timeout", "Timeout value, Resource Descriptor field"),
+ AH_PREDEF ("_DCK", "Dock Present", "Sets docking isolation. Presence indicates device is a docking station"),
+ AH_PREDEF ("_DCS", "Display Current Status", "Returns status of the display output device"),
+ AH_PREDEF ("_DDC", "Display Data Current", "Returns the EDID for the display output device"),
+ AH_PREDEF ("_DDN", "DOS Device Name", "Returns a device logical name"),
+ AH_PREDEF ("_DEC", "Decode", "Device decoding type, Resource Descriptor field"),
+ AH_PREDEF ("_DEP", "Dependencies", "Returns a list of operation region dependencies"),
+ AH_PREDEF ("_DGS", "Display Graphics State", "Return the current state of the output device"),
+ AH_PREDEF ("_DIS", "Disable Device", "Disables a device"),
+ AH_PREDEF ("_DLM", "Device Lock Mutex", "Defines mutex for OS/AML sharing"),
+ AH_PREDEF ("_DMA", "Direct Memory Access", "Returns device current resources for DMA transactions, and resource field"),
+ AH_PREDEF ("_DOD", "Display Output Devices", "Enumerate all devices attached to the display adapter"),
+ AH_PREDEF ("_DOS", "Disable Output Switching", "Sets the display output switching mode"),
+ AH_PREDEF ("_DPL", "Device Selection Polarity", "Polarity of Device Selection signal, Resource Descriptor field"),
+ AH_PREDEF ("_DRS", "Drive Strength", "Drive Strength setting for GPIO connection, Resource Descriptor field"),
+ AH_PREDEF ("_DSD", "Device-Specific Data", "Returns a list of device property information"),
+ AH_PREDEF ("_DSM", "Device-Specific Method", "Executes device-specific functions"),
+ AH_PREDEF ("_DSS", "Device Set State", "Sets the display device state"),
+ AH_PREDEF ("_DSW", "Device Sleep Wake", "Sets the sleep and wake transition states for a device"),
+ AH_PREDEF ("_DTI", "Device Temperature Indication", "Conveys native device temperature to the platform"),
+ AH_PREDEF ("_Exx", "Edge-Triggered GPE", "Method executed as a result of a general-purpose event"),
+ AH_PREDEF ("_EC_", "Embedded Controller", "returns EC offset and query information"),
+ AH_PREDEF ("_EDL", "Eject Device List", "Returns a list of devices that are dependent on a device (docking)"),
+ AH_PREDEF ("_EJD", "Ejection Dependent Device", "Returns the name of dependent (parent) device (docking)"),
+ AH_PREDEF ("_EJx", "Eject Device", "Begin or cancel a device ejection request (docking)"),
+ AH_PREDEF ("_END", "Endianness", "Endian orientation, Resource Descriptor field"),
+ AH_PREDEF ("_EVT", "Event", "Event method for GPIO events"),
+ AH_PREDEF ("_FDE", "Floppy Disk Enumerate", "Returns floppy disk configuration information"),
+ AH_PREDEF ("_FDI", "Floppy Drive Information", "Returns a floppy drive information block"),
+ AH_PREDEF ("_FDM", "Floppy Drive Mode", "Sets a floppy drive speed"),
+ AH_PREDEF ("_FIF", "Fan Information", "Returns fan device information"),
+ AH_PREDEF ("_FIX", "Fixed Register Resource Provider", "Returns a list of devices that implement FADT register blocks"),
+ AH_PREDEF ("_FLC", "Flow Control", "Flow control, Resource Descriptor field"),
+ AH_PREDEF ("_FPS", "Fan Performance States", "Returns a list of supported fan performance states"),
+ AH_PREDEF ("_FSL", "Fan Set Level", "Control method that sets the fan device's speed level (performance state)"),
+ AH_PREDEF ("_FST", "Fan Status", "Returns current status information for a fan device"),
+ AH_PREDEF ("_GAI", "Get Averaging Interval", "Returns the power meter averaging interval"),
+ AH_PREDEF ("_GCP", "Get Capabilities", "Get device time capabilities"),
+ AH_PREDEF ("_GHL", "Get Hardware Limit", "Returns the hardware limit enforced by the power meter"),
+ AH_PREDEF ("_GL_", "Global Lock", "OS-defined Global Lock mutex object"),
+ AH_PREDEF ("_GLK", "Get Global Lock Requirement", "Returns a device's Global Lock requirement for device access"),
+ AH_PREDEF ("_GPD", "Get Post Data", "Returns the value of the VGA device that will be posted at boot"),
+ AH_PREDEF ("_GPE", "General Purpose Events", "Predefined scope (\\_GPE) or SCI number for EC"),
+ AH_PREDEF ("_GRA", "Granularity", "Address space granularity, Resource Descriptor field"),
+ AH_PREDEF ("_GRT", "Get Real Time", "Returns current time-of-day from a time/alarm device"),
+ AH_PREDEF ("_GSB", "Global System Interrupt Base", "Returns the GSB for a I/O APIC device"),
+ AH_PREDEF ("_GTF", "Get Task File", "Returns a list of ATA commands to restore a drive to default state"),
+ AH_PREDEF ("_GTM", "Get Timing Mode", "Returns a list of IDE controller timing information"),
+ AH_PREDEF ("_GTS", "Going To Sleep", "Inform AML of pending sleep"),
+ AH_PREDEF ("_GWS", "Get Wake Status", "Return status of wake alarms"),
+ AH_PREDEF ("_HE_", "High-Edge", "Interrupt triggering, Resource Descriptor field"),
+ AH_PREDEF ("_HID", "Hardware ID", "Returns a device's Plug and Play Hardware ID"),
+ AH_PREDEF ("_HOT", "Hot Temperature", "Returns the critical temperature for sleep (entry to S4)"),
+ AH_PREDEF ("_HPP", "Hot Plug Parameters", "Returns a list of hot-plug information for a PCI device"),
+ AH_PREDEF ("_HPX", "Hot Plug Parameter Extensions", "Returns a list of hot-plug information for a PCI device. Supersedes _HPP"),
+ AH_PREDEF ("_HRV", "Hardware Revision", "Returns a hardware revision value"),
+ AH_PREDEF ("_IFT", "IPMI Interface Type", "See the Intelligent Platform Management Interface Specification"),
+ AH_PREDEF ("_INI", "Initialize", "Performs device specific initialization"),
+ AH_PREDEF ("_INT", "Interrupts", "Interrupt mask bits, Resource Descriptor field"),
+ AH_PREDEF ("_IOR", "I/O Restriction", "Restriction type, Resource Descriptor field"),
+ AH_PREDEF ("_IRC", "Inrush Current", "Presence indicates that a device has a significant inrush current draw"),
+ AH_PREDEF ("_Lxx", "Level-Triggered GPE", "Control method executed as a result of a general-purpose event"),
+ AH_PREDEF ("_LCK", "Lock Device", "Locks or unlocks a device (docking)"),
+ AH_PREDEF ("_LEN", "Length", "Range length, Resource Descriptor field"),
+ AH_PREDEF ("_LID", "Lid Status", "Returns the open/closed status of the lid on a mobile system"),
+ AH_PREDEF ("_LIN", "Lines In Use", "Handshake lines, Resource Descriptor field"),
+ AH_PREDEF ("_LL_", "Low Level", "Interrupt polarity, Resource Descriptor field"),
+ AH_PREDEF ("_LPD", "Low Power Dependencies", "Returns a list of dependencies for low power idle entry"),
+ AH_PREDEF ("_LPI", "Low Power Idle States", "Returns a list of supported low power idle states"),
+ AH_PREDEF ("_MAF", "Maximum Address Fixed", "Resource Descriptor field"),
+ AH_PREDEF ("_MAT", "Multiple APIC Table Entry", "Returns a list of MADT APIC structure entries"),
+ AH_PREDEF ("_MAX", "Maximum Base Address", "Resource Descriptor field"),
+ AH_PREDEF ("_MBM", "Memory Bandwidth Monitoring Data", "Returns bandwidth monitoring data for a memory device"),
+ AH_PREDEF ("_MEM", "Memory Attributes", "Resource Descriptor field"),
+ AH_PREDEF ("_MIF", "Minimum Address Fixed", "Resource Descriptor field"),
+ AH_PREDEF ("_MIN", "Minimum Base Address", "Resource Descriptor field"),
+ AH_PREDEF ("_MLS", "Multiple Language String", "Returns a device description in multiple languages"),
+ AH_PREDEF ("_MOD", "Mode", "Interrupt mode, Resource Descriptor field"),
+ AH_PREDEF ("_MSG", "Message", "Sets the system message waiting status indicator"),
+ AH_PREDEF ("_MSM", "Memory Set Monitoring", "Sets bandwidth monitoring parameters for a memory device"),
+ AH_PREDEF ("_MTL", "Minimum Throttle Limit", "Returns the minimum throttle limit for a thermal zone"),
+ AH_PREDEF ("_MTP", "Memory Type", "Resource Descriptor field"),
+ AH_PREDEF ("_NTT", "Notification Temperature Threshold", "Returns a threshold for device temperature change that requires platform notification"),
+ AH_PREDEF ("_OFF", "Power Off", "Sets a power resource to the off state"),
+ AH_PREDEF ("_ON_", "Power On", "Sets a power resource to the on state"),
+ AH_PREDEF ("_OS_", "Operating System", "Returns a string that identifies the operating system"),
+ AH_PREDEF ("_OSC", "Operating System Capabilities", "Inform AML of host features and capabilities"),
+ AH_PREDEF ("_OSI", "Operating System Interfaces", "Returns supported interfaces, behaviors, and features"),
+ AH_PREDEF ("_OST", "OSPM Status Indication", "Inform AML of event processing status"),
+ AH_PREDEF ("_PAI", "Power Averaging Interval", "Sets the averaging interval for a power meter"),
+ AH_PREDEF ("_PAR", "Parity", "Parity bits, Resource Descriptor field"),
+ AH_PREDEF ("_PCL", "Power Consumer List", "Returns a list of devices powered by a power source"),
+ AH_PREDEF ("_PCT", "Performance Control", "Returns processor performance control and status registers"),
+ AH_PREDEF ("_PDC", "Processor Driver Capabilities", "Inform AML of processor driver capabilities"),
+ AH_PREDEF ("_PDL", "P-state Depth Limit", "Returns the lowest available performance P-state"),
+ AH_PREDEF ("_PHA", "Clock Phase", "Clock phase, Resource Descriptor field"),
+ AH_PREDEF ("_PIC", "Interrupt Model", "Inform AML of the interrupt model in use"),
+ AH_PREDEF ("_PIF", "Power Source Information", "Returns a Power Source information block"),
+ AH_PREDEF ("_PIN", "Pin List", "Pin list, Resource Descriptor field"),
+ AH_PREDEF ("_PLD", "Physical Location of Device", "Returns a device's physical location information"),
+ AH_PREDEF ("_PMC", "Power Meter Capabilities", "Returns a list of Power Meter capabilities info"),
+ AH_PREDEF ("_PMD", "Power Metered Devices", "Returns a list of devices that are measured by the power meter device"),
+ AH_PREDEF ("_PMM", "Power Meter Measurement", "Returns the current value of the Power Meter"),
+ AH_PREDEF ("_POL", "Polarity", "Interrupt polarity, Resource Descriptor field"),
+ AH_PREDEF ("_PPC", "Performance Present Capabilities", "Returns a list of the performance states currently supported by the platform"),
+ AH_PREDEF ("_PPE", "Polling for Platform Error", "Returns the polling interval to retrieve Corrected Platform Error information"),
+ AH_PREDEF ("_PPI", "Pin Configuration", "Resource Descriptor field"),
+ AH_PREDEF ("_PR", "Processor", "Predefined scope for processor objects"),
+ AH_PREDEF ("_PR0", "Power Resources for D0", "Returns a list of dependent power resources to enter state D0 (fully on)"),
+ AH_PREDEF ("_PR1", "Power Resources for D1", "Returns a list of dependent power resources to enter state D1"),
+ AH_PREDEF ("_PR2", "Power Resources for D2", "Returns a list of dependent power resources to enter state D2"),
+ AH_PREDEF ("_PR3", "Power Resources for D3hot", "Returns a list of dependent power resources to enter state D3hot"),
+ AH_PREDEF ("_PRE", "Power Resources for Enumeration", "Returns a list of dependent power resources to enumerate devices on a bus"),
+ AH_PREDEF ("_PRL", "Power Source Redundancy List", "Returns a list of power source devices in the same redundancy grouping"),
+ AH_PREDEF ("_PRR", "Power Resource for Reset", "Execute a reset on a device"),
+ AH_PREDEF ("_PRS", "Possible Resource Settings", "Returns a list of a device's possible resource settings"),
+ AH_PREDEF ("_PRT", "PCI Routing Table", "Returns a list of PCI interrupt mappings"),
+ AH_PREDEF ("_PRW", "Power Resources for Wake", "Returns a list of dependent power resources for waking"),
+ AH_PREDEF ("_PS0", "Power State 0", "Sets a device's power state to D0 (device fully on)"),
+ AH_PREDEF ("_PS1", "Power State 1", "Sets a device's power state to D1"),
+ AH_PREDEF ("_PS2", "Power State 2", "Sets a device's power state to D2"),
+ AH_PREDEF ("_PS3", "Power State 3", "Sets a device's power state to D3 (device off)"),
+ AH_PREDEF ("_PSC", "Power State Current", "Returns a device's current power state"),
+ AH_PREDEF ("_PSD", "Power State Dependencies", "Returns processor P-State dependencies"),
+ AH_PREDEF ("_PSE", "Power State for Enumeration", "Put a bus into enumeration power mode"),
+ AH_PREDEF ("_PSL", "Passive List", "Returns a list of passive cooling device objects"),
+ AH_PREDEF ("_PSR", "Power Source", "Returns the power source device currently in use"),
+ AH_PREDEF ("_PSS", "Performance Supported States", "Returns a list of supported processor performance states"),
+ AH_PREDEF ("_PSV", "Passive Temperature", "Returns the passive trip point temperature"),
+ AH_PREDEF ("_PSW", "Power State Wake", "Sets a device's wake function"),
+ AH_PREDEF ("_PTC", "Processor Throttling Control", "Returns throttling control and status registers"),
+ AH_PREDEF ("_PTP", "Power Trip Points", "Sets trip points for the Power Meter device"),
+ AH_PREDEF ("_PTS", "Prepare To Sleep", "Inform the platform of an impending sleep transition"),
+ AH_PREDEF ("_PUR", "Processor Utilization Request", "Returns the number of processors that the platform would like to idle"),
+ AH_PREDEF ("_PXM", "Device Proximity", "Returns a device's proximity domain identifier"),
+ AH_PREDEF ("_Qxx", "EC Query", "Embedded Controller query and SMBus Alarm control method"),
+ AH_PREDEF ("_RBO", "Register Bit Offset", "Resource Descriptor field"),
+ AH_PREDEF ("_RBW", "Register Bit Width", "Resource Descriptor field"),
+ AH_PREDEF ("_RDI", "Resource Dependencies for Idle", "Returns a list of dependencies for idle states"),
+ AH_PREDEF ("_REG", "Region Availability", "Inform AML code of an operation region availability change"),
+ AH_PREDEF ("_REV", "Supported Integer Width", "Returns the supported integer width (<= 1: 32 bits only, >=2: both 32 and 64 bits"),
+ AH_PREDEF ("_RMV", "Removal Status", "Returns a device's removal ability status (docking)"),
+ AH_PREDEF ("_RNG", "Range", "Memory range type, Resource Descriptor field"),
+ AH_PREDEF ("_RST", "Device Reset", "Executes a reset on a device"),
+ AH_PREDEF ("_ROM", "Read-Only Memory", "Returns a copy of the ROM data for a display device"),
+ AH_PREDEF ("_RT_", "Resource Type", "Resource Descriptor field"),
+ AH_PREDEF ("_RTV", "Relative Temperature Values", "Returns temperature value information"),
+ AH_PREDEF ("_RW_", "Read-Write Status", "Resource Descriptor field"),
+ AH_PREDEF ("_RXL", "Receive Buffer Size", "Serial channel buffer, Resource Descriptor field"),
+ AH_PREDEF ("_S0_", "S0 System State", "Returns values to enter the system into the S0 state"),
+ AH_PREDEF ("_S1_", "S1 System State", "Returns values to enter the system into the S1 state"),
+ AH_PREDEF ("_S2_", "S2 System State", "Returns values to enter the system into the S2 state"),
+ AH_PREDEF ("_S3_", "S3 System State", "Returns values to enter the system into the S3 state"),
+ AH_PREDEF ("_S4_", "S4 System State", "Returns values to enter the system into the S4 state"),
+ AH_PREDEF ("_S5_", "S5 System State", "Returns values to enter the system into the S5 state"),
+ AH_PREDEF ("_S1D", "S1 Device State", "Returns the highest D-state supported by a device when in the S1 state"),
+ AH_PREDEF ("_S2D", "S2 Device State", "Returns the highest D-state supported by a device when in the S2 state"),
+ AH_PREDEF ("_S3D", "S3 Device State", "Returns the highest D-state supported by a device when in the S3 state"),
+ AH_PREDEF ("_S4D", "S4 Device State", "Returns the highest D-state supported by a device when in the S4 state"),
+ AH_PREDEF ("_S0W", "S0 Device Wake State", "Returns the lowest D-state that the device can wake itself from S0"),
+ AH_PREDEF ("_S1W", "S1 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S1"),
+ AH_PREDEF ("_S2W", "S2 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S2"),
+ AH_PREDEF ("_S3W", "S3 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S3"),
+ AH_PREDEF ("_S4W", "S4 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S4"),
+ AH_PREDEF ("_SB_", "System Bus", "Predefined scope for device and bus objects"),
+ AH_PREDEF ("_SBS", "Smart Battery Subsystem", "Returns the subsystem configuration"),
+ AH_PREDEF ("_SCP", "Set Cooling Policy", "Sets the cooling policy (active or passive)"),
+ AH_PREDEF ("_SDD", "Set Device Data", "Sets data for a SATA device"),
+ AH_PREDEF ("_SEG", "PCI Segment", "Returns a device's PCI Segment Group number"),
+ AH_PREDEF ("_SHL", "Set Hardware Limit", "Sets the hardware limit enforced by the Power Meter"),
+ AH_PREDEF ("_SHR", "Sharable", "Interrupt share status, Resource Descriptor field"),
+ AH_PREDEF ("_SI_", "System Indicators", "Predefined scope"),
+ AH_PREDEF ("_SIZ", "Size", "DMA transfer size, Resource Descriptor field"),
+ AH_PREDEF ("_SLI", "System Locality Information", "Returns a list of NUMA system localities"),
+ AH_PREDEF ("_SLV", "Slave Mode", "Mode setting, Resource Descriptor field"),
+ AH_PREDEF ("_SPD", "Set Post Device", "Sets which video device will be posted at boot"),
+ AH_PREDEF ("_SPE", "Speed", "Connection speed, Resource Descriptor field"),
+ AH_PREDEF ("_SRS", "Set Resource Settings", "Sets a device's resource allocation"),
+ AH_PREDEF ("_SRT", "Set Real Time", "Sets the current time for a time/alarm device"),
+ AH_PREDEF ("_SRV", "IPMI Spec Revision", "See the Intelligent Platform Management Interface Specification"),
+ AH_PREDEF ("_SST", "System Status", "Sets the system status indicator"),
+ AH_PREDEF ("_STA", "Status", "Returns the current status of a Device or Power Resource"),
+ AH_PREDEF ("_STB", "Stop Bits", "Serial channel stop bits, Resource Descriptor field"),
+ AH_PREDEF ("_STM", "Set Timing Mode", "Sets an IDE controller transfer timings"),
+ AH_PREDEF ("_STP", "Set Expired Timer Wake Policy", "Sets expired timer policies of the wake alarm device"),
+ AH_PREDEF ("_STR", "Description String", "Returns a device's description string"),
+ AH_PREDEF ("_STV", "Set Timer Value", "Set timer values of the wake alarm device"),
+ AH_PREDEF ("_SUB", "Subsystem ID", "Returns the subsystem ID for a device"),
+ AH_PREDEF ("_SUN", "Slot User Number", "Returns the slot unique ID number"),
+ AH_PREDEF ("_SWS", "System Wake Source", "Returns the source event that caused the system to wake"),
+ AH_PREDEF ("_T_x", "Emitted by ASL Compiler", "Reserved for use by ASL compilers"),
+ AH_PREDEF ("_TC1", "Thermal Constant 1", "Returns TC1 for the passive cooling formula"),
+ AH_PREDEF ("_TC2", "Thermal Constant 2", "Returns TC2 for the passive cooling formula"),
+ AH_PREDEF ("_TDL", "T-State Depth Limit", "Returns the _TSS entry number of the lowest power throttling state"),
+ AH_PREDEF ("_TFP", "Thermal Fast Sampling Period", "Returns the sampling period for passive cooling"),
+ AH_PREDEF ("_TIP", "Expired Timer Wake Policy", "Returns timer policies of the wake alarm device"),
+ AH_PREDEF ("_TIV", "Timer Values", "Returns remaining time of the wake alarm device"),
+ AH_PREDEF ("_TMP", "Temperature", "Returns a thermal zone's current temperature"),
+ AH_PREDEF ("_TPC", "Throttling Present Capabilities", "Returns the current number of supported throttling states"),
+ AH_PREDEF ("_TPT", "Trip Point Temperature", "Inform AML that a device's embedded temperature sensor has crossed a temperature trip point"),
+ AH_PREDEF ("_TRA", "Translation", "Address translation offset, Resource Descriptor field"),
+ AH_PREDEF ("_TRS", "Translation Sparse", "Sparse/dense flag, Resource Descriptor field"),
+ AH_PREDEF ("_TRT", "Thermal Relationship Table", "Returns thermal relationships between platform devices"),
+ AH_PREDEF ("_TSD", "Throttling State Dependencies", "Returns a list of T-state dependencies"),
+ AH_PREDEF ("_TSF", "Type-Specific Flags", "Resource Descriptor field"),
+ AH_PREDEF ("_TSN", "Thermal Sensor Device", "Returns a reference to a thermal sensor"),
+ AH_PREDEF ("_TSP", "Thermal Sampling Period", "Returns the thermal sampling period for passive cooling"),
+ AH_PREDEF ("_TSS", "Throttling Supported States", "Returns supported throttling state information"),
+ AH_PREDEF ("_TST", "Temperature Sensor Threshold", "Returns the minimum separation for a device's temperature trip points"),
+ AH_PREDEF ("_TTP", "Translation Type", "Translation/static flag, Resource Descriptor field"),
+ AH_PREDEF ("_TTS", "Transition To State", "Inform AML of an S-state transition"),
+ AH_PREDEF ("_TXL", "Transmit Buffer Size", "Serial Channel buffer, Resource Descriptor field"),
+ AH_PREDEF ("_TYP", "Type", "DMA channel type (speed), Resource Descriptor field"),
+ AH_PREDEF ("_TZ_", "Thermal Zone", "Predefined scope: ACPI 1.0"),
+ AH_PREDEF ("_TZD", "Thermal Zone Devices", "Returns a list of device names associated with a Thermal Zone"),
+ AH_PREDEF ("_TZM", "Thermal Zone Member", "Returns a reference to the thermal zone of which a device is a member"),
+ AH_PREDEF ("_TZP", "Thermal Zone Polling", "Returns a Thermal zone's polling frequency"),
+ AH_PREDEF ("_UID", "Unique ID", "Return a device's unique persistent ID"),
+ AH_PREDEF ("_UPC", "USB Port Capabilities", "Returns a list of USB port capabilities"),
+ AH_PREDEF ("_UPD", "User Presence Detect", "Returns user detection information"),
+ AH_PREDEF ("_UPP", "User Presence Polling", "Returns the recommended user presence polling interval"),
+ AH_PREDEF ("_VEN", "Vendor Data", "Resource Descriptor field"),
+ AH_PREDEF ("_VPO", "Video Post Options", "Returns the implemented video post options"),
+ AH_PREDEF ("_WAK", "Wake", "Inform AML that the system has just awakened"),
+ AH_PREDEF ("_Wxx", "Wake Event", "Method executed as a result of a wake event"),
+ AH_PREDEF (NULL, NULL, NULL)
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAhMatchPredefinedName
+ *
+ * PARAMETERS: Nameseg - Predefined name string
+ *
+ * RETURN: ID info struct. NULL if Nameseg not found
+ *
+ * DESCRIPTION: Lookup a predefined name.
+ *
+ ******************************************************************************/
+
+const AH_PREDEFINED_NAME *
+AcpiAhMatchPredefinedName (
+ char *Nameseg)
+{
+ const AH_PREDEFINED_NAME *Info;
+
+
+ for (Info = AslPredefinedInfo; Info->Name; Info++)
+ {
+ if (ACPI_COMPARE_NAME (Nameseg, Info->Name))
+ {
+ return (Info);
+ }
+ }
+
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/ahtable.c b/usr/src/boot/sys/contrib/dev/acpica/common/ahtable.c
new file mode 100644
index 0000000000..d4ce436d4c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/ahtable.c
@@ -0,0 +1,150 @@
+/******************************************************************************
+ *
+ * Module Name: ahtable - Table of known ACPI tables with descriptions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+/* Local prototypes */
+
+const AH_TABLE *
+AcpiAhGetTableInfo (
+ char *Signature);
+
+extern const AH_TABLE AcpiSupportedTables[];
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAhGetTableInfo
+ *
+ * PARAMETERS: Signature - ACPI signature (4 chars) to match
+ *
+ * RETURN: Pointer to a valid AH_TABLE. Null if no match found.
+ *
+ * DESCRIPTION: Find a match in the "help" table of supported ACPI tables
+ *
+ ******************************************************************************/
+
+const AH_TABLE *
+AcpiAhGetTableInfo (
+ char *Signature)
+{
+ const AH_TABLE *Info;
+
+
+ for (Info = AcpiSupportedTables; Info->Signature; Info++)
+ {
+ if (ACPI_COMPARE_NAME (Signature, Info->Signature))
+ {
+ return (Info);
+ }
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * Note: Any tables added here should be duplicated within AcpiDmTableData
+ * in the file common/dmtable.c
+ */
+const AH_TABLE AcpiSupportedTables[] =
+{
+ {ACPI_SIG_ASF, "Alert Standard Format table"},
+ {ACPI_SIG_BERT, "Boot Error Record Table"},
+ {ACPI_SIG_BGRT, "Boot Graphics Resource Table"},
+ {ACPI_SIG_BOOT, "Simple Boot Flag Table"},
+ {ACPI_SIG_CPEP, "Corrected Platform Error Polling table"},
+ {ACPI_SIG_CSRT, "Core System Resource Table"},
+ {ACPI_SIG_DBG2, "Debug Port table type 2"},
+ {ACPI_SIG_DBGP, "Debug Port table"},
+ {ACPI_SIG_DMAR, "DMA Remapping table"},
+ {ACPI_SIG_DRTM, "Dynamic Root of Trust for Measurement table"},
+ {ACPI_SIG_DSDT, "Differentiated System Description Table (AML table)"},
+ {ACPI_SIG_ECDT, "Embedded Controller Boot Resources Table"},
+ {ACPI_SIG_EINJ, "Error Injection table"},
+ {ACPI_SIG_ERST, "Error Record Serialization Table"},
+ {ACPI_SIG_FACS, "Firmware ACPI Control Structure"},
+ {ACPI_SIG_FADT, "Fixed ACPI Description Table (FADT)"},
+ {ACPI_SIG_FPDT, "Firmware Performance Data Table"},
+ {ACPI_SIG_GTDT, "Generic Timer Description Table"},
+ {ACPI_SIG_HEST, "Hardware Error Source Table"},
+ {ACPI_SIG_HPET, "High Precision Event Timer table"},
+ {ACPI_SIG_IORT, "IO Remapping Table"},
+ {ACPI_SIG_IVRS, "I/O Virtualization Reporting Structure"},
+ {ACPI_SIG_LPIT, "Low Power Idle Table"},
+ {ACPI_SIG_MADT, "Multiple APIC Description Table (MADT)"},
+ {ACPI_SIG_MCFG, "Memory Mapped Configuration table"},
+ {ACPI_SIG_MCHI, "Management Controller Host Interface table"},
+ {ACPI_SIG_MPST, "Memory Power State Table"},
+ {ACPI_SIG_MSCT, "Maximum System Characteristics Table"},
+ {ACPI_SIG_MSDM, "Microsoft Data Management table"},
+ {ACPI_SIG_MTMR, "MID Timer Table"},
+ {ACPI_SIG_NFIT, "NVDIMM Firmware Interface Table"},
+ {ACPI_SIG_PCCT, "Platform Communications Channel Table"},
+ {ACPI_SIG_PMTT, "Platform Memory Topology Table"},
+ {ACPI_RSDP_NAME,"Root System Description Pointer"},
+ {ACPI_SIG_RSDT, "Root System Description Table"},
+ {ACPI_SIG_S3PT, "S3 Performance Table"},
+ {ACPI_SIG_SBST, "Smart Battery Specification Table"},
+ {ACPI_SIG_SLIC, "Software Licensing Description Table"},
+ {ACPI_SIG_SLIT, "System Locality Information Table"},
+ {ACPI_SIG_SPCR, "Serial Port Console Redirection table"},
+ {ACPI_SIG_SPMI, "Server Platform Management Interface table"},
+ {ACPI_SIG_SRAT, "System Resource Affinity Table"},
+ {ACPI_SIG_SSDT, "Secondary System Description Table (AML table)"},
+ {ACPI_SIG_STAO, "Status Override table"},
+ {ACPI_SIG_TCPA, "Trusted Computing Platform Alliance table"},
+ {ACPI_SIG_TPM2, "Trusted Platform Module hardware interface table"},
+ {ACPI_SIG_UEFI, "UEFI Boot Optimization Table"},
+ {ACPI_SIG_VRTC, "Virtual Real-Time Clock Table"},
+ {ACPI_SIG_WAET, "Windows ACPI Emulated Devices Table"},
+ {ACPI_SIG_WDAT, "Watchdog Action Table"},
+ {ACPI_SIG_WDDT, "Watchdog Description Table"},
+ {ACPI_SIG_WDRT, "Watchdog Resource Table"},
+ {ACPI_SIG_WPBT, "Windows Platform Binary Table"},
+ {ACPI_SIG_XENV, "Xen Environment table"},
+ {ACPI_SIG_XSDT, "Extended System Description Table"},
+ {NULL, NULL}
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/ahuuids.c b/usr/src/boot/sys/contrib/dev/acpica/common/ahuuids.c
new file mode 100644
index 0000000000..46b52ebbfb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/ahuuids.c
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * Module Name: ahuuids - Table of known ACPI-related UUIDs
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acuuid.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("ahuuids")
+
+/*
+ * Table of "known" (ACPI-related) UUIDs
+ */
+const AH_UUID AcpiUuids[] =
+{
+ {"[Controllers]", NULL},
+ {"GPIO Controller", UUID_GPIO_CONTROLLER},
+ {"USB Controller", UUID_USB_CONTROLLER},
+ {"SATA Controller", UUID_SATA_CONTROLLER},
+
+ {"[Devices]", NULL},
+ {"PCI Host Bridge Device", UUID_PCI_HOST_BRIDGE},
+ {"HID I2C Device", UUID_I2C_DEVICE},
+ {"Power Button Device", UUID_POWER_BUTTON},
+
+ {"[Interfaces]", NULL},
+ {"Device Labeling Interface", UUID_DEVICE_LABELING},
+ {"Physical Presence Interface", UUID_PHYSICAL_PRESENCE},
+
+ {"[Non-volatile DIMM and NFIT table]", NULL},
+ {"Volatile Memory Region", UUID_VOLATILE_MEMORY},
+ {"Persistent Memory Region", UUID_PERSISTENT_MEMORY},
+ {"NVDIMM Control Region", UUID_CONTROL_REGION},
+ {"NVDIMM Data Region", UUID_DATA_REGION},
+ {"Volatile Virtual Disk", UUID_VOLATILE_VIRTUAL_DISK},
+ {"Volatile Virtual CD", UUID_VOLATILE_VIRTUAL_CD},
+ {"Persistent Virtual Disk", UUID_PERSISTENT_VIRTUAL_DISK},
+ {"Persistent Virtual CD", UUID_PERSISTENT_VIRTUAL_CD},
+
+ {"[Miscellaneous]", NULL},
+ {"Platform-wide Capabilities", UUID_PLATFORM_CAPABILITIES},
+ {"Dynamic Enumeration", UUID_DYNAMIC_ENUMERATION},
+ {"Battery Thermal Limit", UUID_BATTERY_THERMAL_LIMIT},
+ {"Thermal Extensions", UUID_THERMAL_EXTENSIONS},
+ {"Device Properties for _DSD", UUID_DEVICE_PROPERTIES},
+
+ {NULL, NULL}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAhMatchUuid
+ *
+ * PARAMETERS: Data - Data buffer containing a UUID
+ *
+ * RETURN: ASCII description string for the UUID if it is found.
+ *
+ * DESCRIPTION: Returns a description string for "known" UUIDs, which are
+ * are UUIDs that are related to ACPI in some way.
+ *
+ ******************************************************************************/
+
+const char *
+AcpiAhMatchUuid (
+ UINT8 *Data)
+{
+ const AH_UUID *Info;
+ UINT8 UuidBuffer[UUID_BUFFER_LENGTH];
+
+
+ /* Walk the table of known ACPI-related UUIDs */
+
+ for (Info = AcpiUuids; Info->Description; Info++)
+ {
+ /* Null string means desciption is a UUID class */
+
+ if (!Info->String)
+ {
+ continue;
+ }
+
+ AcpiUtConvertStringToUuid (Info->String, UuidBuffer);
+
+ if (!memcmp (Data, UuidBuffer, UUID_BUFFER_LENGTH))
+ {
+ return (Info->Description);
+ }
+ }
+
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/cmfsize.c b/usr/src/boot/sys/contrib/dev/acpica/common/cmfsize.c
new file mode 100644
index 0000000000..542b150819
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/cmfsize.c
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * Module Name: cfsize - Common get file size function
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <stdio.h>
+
+#define _COMPONENT ACPI_TOOLS
+ ACPI_MODULE_NAME ("cmfsize")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmGetFileSize
+ *
+ * PARAMETERS: File - Open file descriptor
+ *
+ * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
+ *
+ * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
+ * Does not disturb the current file pointer.
+ *
+ ******************************************************************************/
+
+UINT32
+CmGetFileSize (
+ ACPI_FILE File)
+{
+ long FileSize;
+ long CurrentOffset;
+ ACPI_STATUS Status;
+
+
+ /* Save the current file pointer, seek to EOF to obtain file size */
+
+ CurrentOffset = AcpiOsGetFileOffset (File);
+ if (CurrentOffset < 0)
+ {
+ goto OffsetError;
+ }
+
+ Status = AcpiOsSetFileOffset (File, 0, ACPI_FILE_END);
+ if (ACPI_FAILURE (Status))
+ {
+ goto SeekError;
+ }
+
+ FileSize = AcpiOsGetFileOffset (File);
+ if (FileSize < 0)
+ {
+ goto OffsetError;
+ }
+
+ /* Restore original file pointer */
+
+ Status = AcpiOsSetFileOffset (File, CurrentOffset, ACPI_FILE_BEGIN);
+ if (ACPI_FAILURE (Status))
+ {
+ goto SeekError;
+ }
+
+ return ((UINT32) FileSize);
+
+
+OffsetError:
+ AcpiLogError ("Could not get file offset");
+ return (ACPI_UINT32_MAX);
+
+SeekError:
+ AcpiLogError ("Could not set file offset");
+ return (ACPI_UINT32_MAX);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/dmextern.c b/usr/src/boot/sys/contrib/dev/acpica/common/dmextern.c
new file mode 100644
index 0000000000..22d54e9ae5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/dmextern.c
@@ -0,0 +1,1390 @@
+/******************************************************************************
+ *
+ * Module Name: dmextern - Support for External() ASL statements
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <stdio.h>
+#include <errno.h>
+
+
+/*
+ * This module is used for application-level code (iASL disassembler) only.
+ *
+ * It contains the code to create and emit any necessary External() ASL
+ * statements for the module being disassembled.
+ */
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmextern")
+
+
+/*
+ * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
+ * ObjectTypeKeyword. Used to generate typed external declarations
+ */
+static const char *AcpiGbl_DmTypeNames[] =
+{
+ /* 00 */ ", UnknownObj", /* Type ANY */
+ /* 01 */ ", IntObj",
+ /* 02 */ ", StrObj",
+ /* 03 */ ", BuffObj",
+ /* 04 */ ", PkgObj",
+ /* 05 */ ", FieldUnitObj",
+ /* 06 */ ", DeviceObj",
+ /* 07 */ ", EventObj",
+ /* 08 */ ", MethodObj",
+ /* 09 */ ", MutexObj",
+ /* 10 */ ", OpRegionObj",
+ /* 11 */ ", PowerResObj",
+ /* 12 */ ", ProcessorObj",
+ /* 13 */ ", ThermalZoneObj",
+ /* 14 */ ", BuffFieldObj",
+ /* 15 */ ", DDBHandleObj",
+ /* 16 */ "", /* Debug object */
+ /* 17 */ ", FieldUnitObj",
+ /* 18 */ ", FieldUnitObj",
+ /* 19 */ ", FieldUnitObj"
+};
+
+#define METHOD_SEPARATORS " \t,()\n"
+
+
+/* Local prototypes */
+
+static const char *
+AcpiDmGetObjectTypeName (
+ ACPI_OBJECT_TYPE Type);
+
+static char *
+AcpiDmNormalizeParentPrefix (
+ ACPI_PARSE_OBJECT *Op,
+ char *Path);
+
+static void
+AcpiDmAddPathToExternalList (
+ char *Path,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags);
+
+static ACPI_STATUS
+AcpiDmCreateNewExternal (
+ char *ExternalPath,
+ char *InternalPath,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetObjectTypeName
+ *
+ * PARAMETERS: Type - An ACPI_OBJECT_TYPE
+ *
+ * RETURN: Pointer to a string
+ *
+ * DESCRIPTION: Map an object type to the ASL object type string.
+ *
+ ******************************************************************************/
+
+static const char *
+AcpiDmGetObjectTypeName (
+ ACPI_OBJECT_TYPE Type)
+{
+
+ if (Type == ACPI_TYPE_LOCAL_SCOPE)
+ {
+ Type = ACPI_TYPE_DEVICE;
+ }
+
+ else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
+ {
+ return ("");
+ }
+
+ return (AcpiGbl_DmTypeNames[Type]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNormalizeParentPrefix
+ *
+ * PARAMETERS: Op - Parse op
+ * Path - Path with parent prefix
+ *
+ * RETURN: The full pathname to the object (from the namespace root)
+ *
+ * DESCRIPTION: Returns the full pathname of a path with parent prefix
+ * The caller must free the fullpath returned.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmNormalizeParentPrefix (
+ ACPI_PARSE_OBJECT *Op,
+ char *Path)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ char *Fullpath;
+ char *ParentPath;
+ ACPI_SIZE Length;
+ UINT32 Index = 0;
+
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ /* Search upwards in the parse tree until we reach the next namespace node */
+
+ Op = Op->Common.Parent;
+ while (Op)
+ {
+ if (Op->Common.Node)
+ {
+ break;
+ }
+
+ Op = Op->Common.Parent;
+ }
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ /*
+ * Find the actual parent node for the reference:
+ * Remove all carat prefixes from the input path.
+ * There may be multiple parent prefixes (For example, ^^^M000)
+ */
+ Node = Op->Common.Node;
+ while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
+ {
+ Node = Node->Parent;
+ Path++;
+ }
+
+ if (!Node)
+ {
+ return (NULL);
+ }
+
+ /* Get the full pathname for the parent node */
+
+ ParentPath = AcpiNsGetExternalPathname (Node);
+ if (!ParentPath)
+ {
+ return (NULL);
+ }
+
+ Length = (strlen (ParentPath) + strlen (Path) + 1);
+ if (ParentPath[1])
+ {
+ /*
+ * If ParentPath is not just a simple '\', increment the length
+ * for the required dot separator (ParentPath.Path)
+ */
+ Length++;
+
+ /* For External() statements, we do not want a leading '\' */
+
+ if (*ParentPath == AML_ROOT_PREFIX)
+ {
+ Index = 1;
+ }
+ }
+
+ Fullpath = ACPI_ALLOCATE_ZEROED (Length);
+ if (!Fullpath)
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Concatenate parent fullpath and path. For example,
+ * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
+ *
+ * Copy the parent path
+ */
+ strcpy (Fullpath, &ParentPath[Index]);
+
+ /*
+ * Add dot separator
+ * (don't need dot if parent fullpath is a single backslash)
+ */
+ if (ParentPath[1])
+ {
+ strcat (Fullpath, ".");
+ }
+
+ /* Copy child path (carat parent prefix(es) were skipped above) */
+
+ strcat (Fullpath, Path);
+
+Cleanup:
+ ACPI_FREE (ParentPath);
+ return (Fullpath);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddToExternalFileList
+ *
+ * PARAMETERS: PathList - Single path or list separated by comma
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add external files to global list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDmAddToExternalFileList (
+ char *Pathname)
+{
+ ACPI_EXTERNAL_FILE *ExternalFile;
+ char *LocalPathname;
+
+
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
+ if (!LocalPathname)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
+ if (!ExternalFile)
+ {
+ ACPI_FREE (LocalPathname);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Take a copy of the file pathname */
+
+ strcpy (LocalPathname, Pathname);
+ ExternalFile->Path = LocalPathname;
+
+ if (AcpiGbl_ExternalFileList)
+ {
+ ExternalFile->Next = AcpiGbl_ExternalFileList;
+ }
+
+ AcpiGbl_ExternalFileList = ExternalFile;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmClearExternalFileList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Clear the external file list
+ *
+ ******************************************************************************/
+
+void
+AcpiDmClearExternalFileList (
+ void)
+{
+ ACPI_EXTERNAL_FILE *NextExternal;
+
+
+ while (AcpiGbl_ExternalFileList)
+ {
+ NextExternal = AcpiGbl_ExternalFileList->Next;
+ ACPI_FREE (AcpiGbl_ExternalFileList->Path);
+ ACPI_FREE (AcpiGbl_ExternalFileList);
+ AcpiGbl_ExternalFileList = NextExternal;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetExternalsFromFile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Process the optional external reference file.
+ *
+ * Each line in the file should be of the form:
+ * External (<Method namepath>, MethodObj, <ArgCount>)
+ *
+ * Example:
+ * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGetExternalsFromFile (
+ void)
+{
+ FILE *ExternalRefFile;
+ char *Token;
+ char *MethodName;
+ UINT32 ArgCount;
+ UINT32 ImportCount = 0;
+
+
+ if (!Gbl_ExternalRefFilename)
+ {
+ return;
+ }
+
+ /* Open the file */
+
+ ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
+ if (!ExternalRefFile)
+ {
+ fprintf (stderr, "Could not open external reference file \"%s\"\n",
+ Gbl_ExternalRefFilename);
+ AslAbort ();
+ return;
+ }
+
+ /* Each line defines a method */
+
+ while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
+ {
+ Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
+ if (!Token)
+ {
+ continue;
+ }
+ if (strcmp (Token, "External"))
+ {
+ continue;
+ }
+
+ MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
+ if (!MethodName)
+ {
+ continue;
+ }
+
+ Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
+ if (!Token)
+ {
+ continue;
+ }
+
+ if (strcmp (Token, "MethodObj"))
+ {
+ continue;
+ }
+
+ Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
+ if (!Token)
+ {
+ continue;
+ }
+
+ /* Convert arg count string to an integer */
+
+ errno = 0;
+ ArgCount = strtoul (Token, NULL, 0);
+ if (errno)
+ {
+ fprintf (stderr, "Invalid argument count (%s)\n", Token);
+ continue;
+ }
+ if (ArgCount > 7)
+ {
+ fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
+ continue;
+ }
+
+ /* Add this external to the global list */
+
+ AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
+ Gbl_ExternalRefFilename, ArgCount, MethodName);
+
+ AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
+ ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
+ ImportCount++;
+ }
+
+ if (!ImportCount)
+ {
+ fprintf (stderr, "Did not find any external methods in reference file \"%s\"\n",
+ Gbl_ExternalRefFilename);
+ }
+ else
+ {
+ /* Add the external(s) to the namespace */
+
+ AcpiDmAddExternalsToNamespace ();
+
+ AcpiOsPrintf ("%s: Imported %u external method definitions\n",
+ Gbl_ExternalRefFilename, ImportCount);
+ }
+
+ fclose (ExternalRefFile);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddOpToExternalList
+ *
+ * PARAMETERS: Op - Current parser Op
+ * Path - Internal (AML) path to the object
+ * Type - ACPI object type to be added
+ * Value - Arg count if adding a Method object
+ * Flags - To be passed to the external object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a new name into the global list of Externals which
+ * will in turn be later emitted as an External() declaration
+ * in the disassembled output.
+ *
+ * This function handles the most common case where the referenced
+ * name is simply not found in the constructed namespace.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddOpToExternalList (
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags)
+{
+ char *ExternalPath;
+ char *InternalPath = Path;
+ char *Temp;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
+
+
+ if (!Path)
+ {
+ return_VOID;
+ }
+
+ /* Remove a root backslash if present */
+
+ if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
+ {
+ Path++;
+ }
+
+ /* Externalize the pathname */
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
+ NULL, &ExternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /*
+ * Get the full pathname from the root if "Path" has one or more
+ * parent prefixes (^). Note: path will not contain a leading '\'.
+ */
+ if (*Path == (UINT8) AML_PARENT_PREFIX)
+ {
+ Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
+
+ /* Set new external path */
+
+ ACPI_FREE (ExternalPath);
+ ExternalPath = Temp;
+ if (!Temp)
+ {
+ return_VOID;
+ }
+
+ /* Create the new internal pathname */
+
+ Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
+ Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (ExternalPath);
+ return_VOID;
+ }
+ }
+
+ /* Create the new External() declaration node */
+
+ Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
+ Type, Value, Flags);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (ExternalPath);
+ if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
+ {
+ ACPI_FREE (InternalPath);
+ }
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddNodeToExternalList
+ *
+ * PARAMETERS: Node - Namespace node for object to be added
+ * Type - ACPI object type to be added
+ * Value - Arg count if adding a Method object
+ * Flags - To be passed to the external object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a new name into the global list of Externals which
+ * will in turn be later emitted as an External() declaration
+ * in the disassembled output.
+ *
+ * This function handles the case where the referenced name has
+ * been found in the namespace, but the name originated in a
+ * table other than the one that is being disassembled (such
+ * as a table that is added via the iASL -e option).
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddNodeToExternalList (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags)
+{
+ char *ExternalPath;
+ char *InternalPath;
+ char *Temp;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
+
+
+ if (!Node)
+ {
+ return_VOID;
+ }
+
+ /* Get the full external and internal pathnames to the node */
+
+ ExternalPath = AcpiNsGetExternalPathname (Node);
+ if (!ExternalPath)
+ {
+ return_VOID;
+ }
+
+ Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (ExternalPath);
+ return_VOID;
+ }
+
+ /* Remove the root backslash */
+
+ if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
+ {
+ Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
+ if (!Temp)
+ {
+ return_VOID;
+ }
+
+ strcpy (Temp, &ExternalPath[1]);
+ ACPI_FREE (ExternalPath);
+ ExternalPath = Temp;
+ }
+
+ /* Create the new External() declaration node */
+
+ Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
+ Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (ExternalPath);
+ ACPI_FREE (InternalPath);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddPathToExternalList
+ *
+ * PARAMETERS: Path - External name of the object to be added
+ * Type - ACPI object type to be added
+ * Value - Arg count if adding a Method object
+ * Flags - To be passed to the external object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a new name into the global list of Externals which
+ * will in turn be later emitted as an External() declaration
+ * in the disassembled output.
+ *
+ * This function currently is used to add externals via a
+ * reference file (via the -fe iASL option).
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddPathToExternalList (
+ char *Path,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags)
+{
+ char *InternalPath;
+ char *ExternalPath;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
+
+
+ if (!Path)
+ {
+ return_VOID;
+ }
+
+ /* Remove a root backslash if present */
+
+ if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
+ {
+ Path++;
+ }
+
+ /* Create the internal and external pathnames */
+
+ Status = AcpiNsInternalizeName (Path, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
+ NULL, &ExternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (InternalPath);
+ return_VOID;
+ }
+
+ /* Create the new External() declaration node */
+
+ Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
+ Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (ExternalPath);
+ ACPI_FREE (InternalPath);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCreateNewExternal
+ *
+ * PARAMETERS: ExternalPath - External path to the object
+ * InternalPath - Internal (AML) path to the object
+ * Type - ACPI object type to be added
+ * Value - Arg count if adding a Method object
+ * Flags - To be passed to the external object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common low-level function to insert a new name into the global
+ * list of Externals which will in turn be later emitted as
+ * External() declarations in the disassembled output.
+ *
+ * Note: The external name should not include a root prefix
+ * (backslash). We do not want External() statements to contain
+ * a leading '\', as this prevents duplicate external statements
+ * of the form:
+ *
+ * External (\ABCD)
+ * External (ABCD)
+ *
+ * This would cause a compile time error when the disassembled
+ * output file is recompiled.
+ *
+ * There are two cases that are handled here. For both, we emit
+ * an External() statement:
+ * 1) The name was simply not found in the namespace.
+ * 2) The name was found, but it originated in a table other than
+ * the table that is being disassembled.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmCreateNewExternal (
+ char *ExternalPath,
+ char *InternalPath,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags)
+{
+ ACPI_EXTERNAL_LIST *NewExternal;
+ ACPI_EXTERNAL_LIST *NextExternal;
+ ACPI_EXTERNAL_LIST *PrevExternal = NULL;
+
+
+ ACPI_FUNCTION_TRACE (DmCreateNewExternal);
+
+
+ /* Check all existing externals to ensure no duplicates */
+
+ NextExternal = AcpiGbl_ExternalList;
+ while (NextExternal)
+ {
+ if (!strcmp (ExternalPath, NextExternal->Path))
+ {
+ /* Duplicate method, check that the Value (ArgCount) is the same */
+
+ if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
+ (NextExternal->Value != Value) &&
+ (Value > 0))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "External method arg count mismatch %s: Current %u, attempted %u",
+ NextExternal->Path, NextExternal->Value, Value));
+ }
+
+ /* Allow upgrade of type from ANY */
+
+ else if (NextExternal->Type == ACPI_TYPE_ANY)
+ {
+ NextExternal->Type = Type;
+ NextExternal->Value = Value;
+ }
+
+ return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ }
+
+ NextExternal = NextExternal->Next;
+ }
+
+ /* Allocate and init a new External() descriptor */
+
+ NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
+ if (!NewExternal)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Adding external reference node (%s) type [%s]\n",
+ ExternalPath, AcpiUtGetTypeName (Type)));
+
+ NewExternal->Flags = Flags;
+ NewExternal->Value = Value;
+ NewExternal->Path = ExternalPath;
+ NewExternal->Type = Type;
+ NewExternal->Length = (UINT16) strlen (ExternalPath);
+ NewExternal->InternalPath = InternalPath;
+
+ /* Link the new descriptor into the global list, alphabetically ordered */
+
+ NextExternal = AcpiGbl_ExternalList;
+ while (NextExternal)
+ {
+ if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
+ {
+ if (PrevExternal)
+ {
+ PrevExternal->Next = NewExternal;
+ }
+ else
+ {
+ AcpiGbl_ExternalList = NewExternal;
+ }
+
+ NewExternal->Next = NextExternal;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ PrevExternal = NextExternal;
+ NextExternal = NextExternal->Next;
+ }
+
+ if (PrevExternal)
+ {
+ PrevExternal->Next = NewExternal;
+ }
+ else
+ {
+ AcpiGbl_ExternalList = NewExternal;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddExternalsToNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add all externals to the namespace. Allows externals to be
+ * "resolved".
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddExternalsToNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
+
+
+ while (External)
+ {
+ /* Add the external name (object) into the namespace */
+
+ Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
+ ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL, &Node);
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while adding external to namespace [%s]",
+ External->Path));
+ }
+
+ else switch (External->Type)
+ {
+ case ACPI_TYPE_METHOD:
+
+ /* For methods, we need to save the argument count */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ ObjDesc->Method.ParamCount = (UINT8) External->Value;
+ Node->Object = ObjDesc;
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ /* Regions require a region sub-object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ ObjDesc->Region.Node = Node;
+ Node->Object = ObjDesc;
+ break;
+
+ default:
+
+ break;
+ }
+
+ External = External->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetExternalMethodCount
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: The number of control method externals in the external list
+ *
+ * DESCRIPTION: Return the number of method externals that have been generated.
+ * If any control method externals have been found, we must
+ * re-parse the entire definition block with the new information
+ * (number of arguments for the methods.) This is limitation of
+ * AML, we don't know the number of arguments from the control
+ * method invocation itself.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmGetExternalMethodCount (
+ void)
+{
+ ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
+ UINT32 Count = 0;
+
+
+ while (External)
+ {
+ if (External->Type == ACPI_TYPE_METHOD)
+ {
+ Count++;
+ }
+
+ External = External->Next;
+ }
+
+ return (Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmClearExternalList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Free the entire External info list
+ *
+ ******************************************************************************/
+
+void
+AcpiDmClearExternalList (
+ void)
+{
+ ACPI_EXTERNAL_LIST *NextExternal;
+
+
+ while (AcpiGbl_ExternalList)
+ {
+ NextExternal = AcpiGbl_ExternalList->Next;
+ ACPI_FREE (AcpiGbl_ExternalList->Path);
+ ACPI_FREE (AcpiGbl_ExternalList);
+ AcpiGbl_ExternalList = NextExternal;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmEmitExternals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit an External() ASL statement for each of the externals in
+ * the global external info list.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmEmitExternals (
+ void)
+{
+ ACPI_EXTERNAL_LIST *NextExternal;
+
+
+ if (!AcpiGbl_ExternalList)
+ {
+ return;
+ }
+
+ /*
+ * Determine the number of control methods in the external list, and
+ * also how many of those externals were resolved via the namespace.
+ */
+ NextExternal = AcpiGbl_ExternalList;
+ while (NextExternal)
+ {
+ if (NextExternal->Type == ACPI_TYPE_METHOD)
+ {
+ AcpiGbl_NumExternalMethods++;
+ if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
+ {
+ AcpiGbl_ResolvedExternalMethods++;
+ }
+ }
+
+ NextExternal = NextExternal->Next;
+ }
+
+ /* Check if any control methods were unresolved */
+
+ AcpiDmUnresolvedWarning (1);
+
+ /* Emit any unresolved method externals in a single text block */
+
+ NextExternal = AcpiGbl_ExternalList;
+ while (NextExternal)
+ {
+ if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
+ (!(NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
+ {
+ AcpiOsPrintf (" External (%s%s",
+ NextExternal->Path,
+ AcpiDmGetObjectTypeName (NextExternal->Type));
+
+ AcpiOsPrintf (") // Warning: Unresolved method, "
+ "guessing %u arguments\n",
+ NextExternal->Value);
+
+ NextExternal->Flags |= ACPI_EXT_EXTERNAL_EMITTED;
+ }
+
+ NextExternal = NextExternal->Next;
+ }
+
+ AcpiOsPrintf ("\n");
+
+
+ /* Emit externals that were imported from a file */
+
+ if (Gbl_ExternalRefFilename)
+ {
+ AcpiOsPrintf (
+ " /*\n * External declarations that were imported from\n"
+ " * the reference file [%s]\n */\n",
+ Gbl_ExternalRefFilename);
+
+ NextExternal = AcpiGbl_ExternalList;
+ while (NextExternal)
+ {
+ if (!(NextExternal->Flags & ACPI_EXT_EXTERNAL_EMITTED) &&
+ (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_FILE))
+ {
+ AcpiOsPrintf (" External (%s%s",
+ NextExternal->Path,
+ AcpiDmGetObjectTypeName (NextExternal->Type));
+
+ if (NextExternal->Type == ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf (") // %u Arguments\n",
+ NextExternal->Value);
+ }
+ else
+ {
+ AcpiOsPrintf (")\n");
+ }
+ NextExternal->Flags |= ACPI_EXT_EXTERNAL_EMITTED;
+ }
+
+ NextExternal = NextExternal->Next;
+ }
+
+ AcpiOsPrintf ("\n");
+ }
+
+ /*
+ * Walk the list of externals found during the AML parsing
+ */
+ while (AcpiGbl_ExternalList)
+ {
+ if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
+ {
+ AcpiOsPrintf (" External (%s%s",
+ AcpiGbl_ExternalList->Path,
+ AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
+
+ /* For methods, add a comment with the number of arguments */
+
+ if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf (") // %u Arguments\n",
+ AcpiGbl_ExternalList->Value);
+ }
+ else
+ {
+ AcpiOsPrintf (")\n");
+ }
+ }
+
+ /* Free this external info block and move on to next external */
+
+ NextExternal = AcpiGbl_ExternalList->Next;
+ if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
+ {
+ ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
+ }
+
+ ACPI_FREE (AcpiGbl_ExternalList->Path);
+ ACPI_FREE (AcpiGbl_ExternalList);
+ AcpiGbl_ExternalList = NextExternal;
+ }
+
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUnresolvedWarning
+ *
+ * PARAMETERS: Type - Where to output the warning.
+ * 0 means write to stderr
+ * 1 means write to AcpiOsPrintf
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Issue warning message if there are unresolved external control
+ * methods within the disassembly.
+ *
+ ******************************************************************************/
+
+#if 0
+Summary of the external control method problem:
+
+When the -e option is used with disassembly, the various SSDTs are simply
+loaded into a global namespace for the disassembler to use in order to
+resolve control method references (invocations).
+
+The disassembler tracks any such references, and will emit an External()
+statement for these types of methods, with the proper number of arguments .
+
+Without the SSDTs, the AML does not contain enough information to properly
+disassemble the control method invocation -- because the disassembler does
+not know how many arguments to parse.
+
+An example: Assume we have two control methods. ABCD has one argument, and
+EFGH has zero arguments. Further, we have two additional control methods
+that invoke ABCD and EFGH, named T1 and T2:
+
+ Method (ABCD, 1)
+ {
+ }
+ Method (EFGH, 0)
+ {
+ }
+ Method (T1)
+ {
+ ABCD (Add (2, 7, Local0))
+ }
+ Method (T2)
+ {
+ EFGH ()
+ Add (2, 7, Local0)
+ }
+
+Here is the AML code that is generated for T1 and T2:
+
+ 185: Method (T1)
+
+0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
+
+ 186: {
+ 187: ABCD (Add (2, 7, Local0))
+
+00000353: 41 42 43 44 ............ "ABCD"
+00000357: 72 0A 02 0A 07 60 ...... "r....`"
+
+ 188: }
+
+ 190: Method (T2)
+
+0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
+
+ 191: {
+ 192: EFGH ()
+
+00000364: 45 46 47 48 ............ "EFGH"
+
+ 193: Add (2, 7, Local0)
+
+00000368: 72 0A 02 0A 07 60 ...... "r....`"
+ 194: }
+
+Note that the AML code for T1 and T2 is essentially identical. When
+disassembling this code, the methods ABCD and EFGH must be known to the
+disassembler, otherwise it does not know how to handle the method invocations.
+
+In other words, if ABCD and EFGH are actually external control methods
+appearing in an SSDT, the disassembler does not know what to do unless
+the owning SSDT has been loaded via the -e option.
+#endif
+
+void
+AcpiDmUnresolvedWarning (
+ UINT8 Type)
+{
+
+ if (!AcpiGbl_NumExternalMethods)
+ {
+ return;
+ }
+
+ if (Type)
+ {
+ if (!AcpiGbl_ExternalFileList)
+ {
+ /* The -e option was not specified */
+
+ AcpiOsPrintf (" /*\n"
+ " * iASL Warning: There were %u external control methods found during\n"
+ " * disassembly, but additional ACPI tables to resolve these externals\n"
+ " * were not specified. This resulting disassembler output file may not\n"
+ " * compile because the disassembler did not know how many arguments\n"
+ " * to assign to these methods. To specify the tables needed to resolve\n"
+ " * external control method references, the -e option can be used to\n"
+ " * specify the filenames. Note: SSDTs can be dynamically loaded at\n"
+ " * runtime and may or may not be available via the host OS.\n"
+ " * Example iASL invocations:\n"
+ " * iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
+ " * iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
+ " * iasl -e ssdt*.aml -d dsdt.aml\n"
+ " *\n"
+ " * In addition, the -fe option can be used to specify a file containing\n"
+ " * control method external declarations with the associated method\n"
+ " * argument counts. Each line of the file must be of the form:\n"
+ " * External (<method pathname>, MethodObj, <argument count>)\n"
+ " * Invocation:\n"
+ " * iasl -fe refs.txt -d dsdt.aml\n"
+ " *\n"
+ " * The following methods were unresolved and many not compile properly\n"
+ " * because the disassembler had to guess at the number of arguments\n"
+ " * required for each:\n"
+ " */\n",
+ AcpiGbl_NumExternalMethods);
+ }
+ else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
+ {
+ /* The -e option was specified, but there are still some unresolved externals */
+
+ AcpiOsPrintf (" /*\n"
+ " * iASL Warning: There were %u external control methods found during\n"
+ " * disassembly, but only %u %s resolved (%u unresolved). Additional\n"
+ " * ACPI tables may be required to properly disassemble the code. This\n"
+ " * resulting disassembler output file may not compile because the\n"
+ " * disassembler did not know how many arguments to assign to the\n"
+ " * unresolved methods. Note: SSDTs can be dynamically loaded at\n"
+ " * runtime and may or may not be available via the host OS.\n"
+ " *\n"
+ " * If necessary, the -fe option can be used to specify a file containing\n"
+ " * control method external declarations with the associated method\n"
+ " * argument counts. Each line of the file must be of the form:\n"
+ " * External (<method pathname>, MethodObj, <argument count>)\n"
+ " * Invocation:\n"
+ " * iasl -fe refs.txt -d dsdt.aml\n"
+ " *\n"
+ " * The following methods were unresolved and many not compile properly\n"
+ " * because the disassembler had to guess at the number of arguments\n"
+ " * required for each:\n"
+ " */\n",
+ AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
+ (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
+ (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
+ }
+ }
+ else
+ {
+ if (!AcpiGbl_ExternalFileList)
+ {
+ /* The -e option was not specified */
+
+ fprintf (stderr, "\n"
+ "iASL Warning: There were %u external control methods found during\n"
+ "disassembly, but additional ACPI tables to resolve these externals\n"
+ "were not specified. The resulting disassembler output file may not\n"
+ "compile because the disassembler did not know how many arguments\n"
+ "to assign to these methods. To specify the tables needed to resolve\n"
+ "external control method references, the -e option can be used to\n"
+ "specify the filenames. Note: SSDTs can be dynamically loaded at\n"
+ "runtime and may or may not be available via the host OS.\n"
+ "Example iASL invocations:\n"
+ " iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
+ " iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
+ " iasl -e ssdt*.aml -d dsdt.aml\n"
+ "\n"
+ "In addition, the -fe option can be used to specify a file containing\n"
+ "control method external declarations with the associated method\n"
+ "argument counts. Each line of the file must be of the form:\n"
+ " External (<method pathname>, MethodObj, <argument count>)\n"
+ "Invocation:\n"
+ " iasl -fe refs.txt -d dsdt.aml\n",
+ AcpiGbl_NumExternalMethods);
+ }
+ else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
+ {
+ /* The -e option was specified, but there are still some unresolved externals */
+
+ fprintf (stderr, "\n"
+ "iASL Warning: There were %u external control methods found during\n"
+ "disassembly, but only %u %s resolved (%u unresolved). Additional\n"
+ "ACPI tables may be required to properly disassemble the code. The\n"
+ "resulting disassembler output file may not compile because the\n"
+ "disassembler did not know how many arguments to assign to the\n"
+ "unresolved methods. Note: SSDTs can be dynamically loaded at\n"
+ "runtime and may or may not be available via the host OS.\n"
+ "\n"
+ "If necessary, the -fe option can be used to specify a file containing\n"
+ "control method external declarations with the associated method\n"
+ "argument counts. Each line of the file must be of the form:\n"
+ " External (<method pathname>, MethodObj, <argument count>)\n"
+ "Invocation:\n"
+ " iasl -fe refs.txt -d dsdt.aml\n",
+ AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
+ (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
+ (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
+ }
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/dmrestag.c b/usr/src/boot/sys/contrib/dev/acpica/common/dmrestag.c
new file mode 100644
index 0000000000..51d8ba3e3c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/dmrestag.c
@@ -0,0 +1,1048 @@
+/******************************************************************************
+ *
+ * Module Name: dmrestag - Add tags to resource descriptors (Application-level)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmrestag")
+
+/* Local prototypes */
+
+static void
+AcpiDmUpdateResourceName (
+ ACPI_NAMESPACE_NODE *ResourceNode);
+
+static char *
+AcpiDmSearchTagList (
+ UINT32 BitIndex,
+ const ACPI_RESOURCE_TAG *TagList);
+
+static char *
+AcpiDmGetResourceTag (
+ UINT32 BitIndex,
+ AML_RESOURCE *Resource,
+ UINT8 ResourceIndex);
+
+static char *
+AcpiGetTagPathname (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *BufferNode,
+ ACPI_NAMESPACE_NODE *ResourceNode,
+ UINT32 BitIndex);
+
+static ACPI_NAMESPACE_NODE *
+AcpiDmGetResourceNode (
+ ACPI_NAMESPACE_NODE *BufferNode,
+ UINT32 BitIndex);
+
+static ACPI_STATUS
+AcpiDmAddResourceToNamespace (
+ UINT8 *Aml,
+ UINT32 Length,
+ UINT32 Offset,
+ UINT8 ResourceIndex,
+ void **Context);
+
+static void
+AcpiDmAddResourcesToNamespace (
+ ACPI_NAMESPACE_NODE *BufferNode,
+ ACPI_PARSE_OBJECT *Op);
+
+
+/******************************************************************************
+ *
+ * Resource Tag tables
+ *
+ * These are the predefined tags that refer to elements of a resource
+ * descriptor. Each name and offset is defined in the ACPI specification.
+ *
+ * Each table entry contains the bit offset of the field and the associated
+ * name.
+ *
+ ******************************************************************************/
+
+static const ACPI_RESOURCE_TAG AcpiDmIrqTags[] =
+{
+ {( 1 * 8), ACPI_RESTAG_INTERRUPT},
+ {( 3 * 8) + 0, ACPI_RESTAG_INTERRUPTTYPE},
+ {( 3 * 8) + 3, ACPI_RESTAG_INTERRUPTLEVEL},
+ {( 3 * 8) + 4, ACPI_RESTAG_INTERRUPTSHARE},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmDmaTags[] =
+{
+ {( 1 * 8), ACPI_RESTAG_DMA},
+ {( 2 * 8) + 0, ACPI_RESTAG_XFERTYPE},
+ {( 2 * 8) + 2, ACPI_RESTAG_BUSMASTER},
+ {( 2 * 8) + 5, ACPI_RESTAG_DMATYPE},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmIoTags[] =
+{
+ {( 1 * 8) + 0, ACPI_RESTAG_DECODE},
+ {( 2 * 8), ACPI_RESTAG_MINADDR},
+ {( 4 * 8), ACPI_RESTAG_MAXADDR},
+ {( 6 * 8), ACPI_RESTAG_ALIGNMENT},
+ {( 7 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmFixedIoTags[] =
+{
+ {( 1 * 8), ACPI_RESTAG_BASEADDRESS},
+ {( 3 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmFixedDmaTags[] =
+{
+ {( 1 * 8), ACPI_RESTAG_DMA},
+ {( 3 * 8), ACPI_RESTAG_DMATYPE},
+ {( 5 * 8), ACPI_RESTAG_XFERTYPE},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmMemory24Tags[] =
+{
+ {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
+ {( 4 * 8), ACPI_RESTAG_MINADDR},
+ {( 6 * 8), ACPI_RESTAG_MAXADDR},
+ {( 8 * 8), ACPI_RESTAG_ALIGNMENT},
+ {(10 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmRegisterTags[] =
+{
+ {( 3 * 8), ACPI_RESTAG_ADDRESSSPACE},
+ {( 4 * 8), ACPI_RESTAG_REGISTERBITWIDTH},
+ {( 5 * 8), ACPI_RESTAG_REGISTERBITOFFSET},
+ {( 6 * 8), ACPI_RESTAG_ACCESSSIZE},
+ {( 7 * 8), ACPI_RESTAG_ADDRESS},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmMemory32Tags[] =
+{
+ {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
+ {( 4 * 8), ACPI_RESTAG_MINADDR},
+ {( 8 * 8), ACPI_RESTAG_MAXADDR},
+ {(12 * 8), ACPI_RESTAG_ALIGNMENT},
+ {(16 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmFixedMemory32Tags[] =
+{
+ {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
+ {( 4 * 8), ACPI_RESTAG_BASEADDRESS},
+ {( 8 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmInterruptTags[] =
+{
+ {( 3 * 8) + 1, ACPI_RESTAG_INTERRUPTTYPE},
+ {( 3 * 8) + 2, ACPI_RESTAG_INTERRUPTLEVEL},
+ {( 3 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE},
+ {( 5 * 8), ACPI_RESTAG_INTERRUPT},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmAddress16Tags[] =
+{
+ {( 4 * 8) + 1, ACPI_RESTAG_DECODE},
+ {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
+ {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE},
+ {( 6 * 8), ACPI_RESTAG_GRANULARITY},
+ {( 8 * 8), ACPI_RESTAG_MINADDR},
+ {(10 * 8), ACPI_RESTAG_MAXADDR},
+ {(12 * 8), ACPI_RESTAG_TRANSLATION},
+ {(14 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmAddress32Tags[] =
+{
+ {( 4 * 8) + 1, ACPI_RESTAG_DECODE},
+ {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
+ {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE},
+ {( 6 * 8), ACPI_RESTAG_GRANULARITY},
+ {(10 * 8), ACPI_RESTAG_MINADDR},
+ {(14 * 8), ACPI_RESTAG_MAXADDR},
+ {(18 * 8), ACPI_RESTAG_TRANSLATION},
+ {(22 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmAddress64Tags[] =
+{
+ {( 4 * 8) + 1, ACPI_RESTAG_DECODE},
+ {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
+ {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE},
+ {( 6 * 8), ACPI_RESTAG_GRANULARITY},
+ {(14 * 8), ACPI_RESTAG_MINADDR},
+ {(22 * 8), ACPI_RESTAG_MAXADDR},
+ {(30 * 8), ACPI_RESTAG_TRANSLATION},
+ {(38 * 8), ACPI_RESTAG_LENGTH},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmExtendedAddressTags[] =
+{
+ {( 4 * 8) + 1, ACPI_RESTAG_DECODE},
+ {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
+ {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE},
+ {( 8 * 8), ACPI_RESTAG_GRANULARITY},
+ {(16 * 8), ACPI_RESTAG_MINADDR},
+ {(24 * 8), ACPI_RESTAG_MAXADDR},
+ {(32 * 8), ACPI_RESTAG_TRANSLATION},
+ {(40 * 8), ACPI_RESTAG_LENGTH},
+ {(48 * 8), ACPI_RESTAG_TYPESPECIFICATTRIBUTES},
+ {0, NULL}
+};
+
+/* Subtype tables for GPIO descriptors */
+
+static const ACPI_RESOURCE_TAG AcpiDmGpioIntTags[] =
+{
+ {( 7 * 8) + 0, ACPI_RESTAG_MODE},
+ {( 7 * 8) + 1, ACPI_RESTAG_POLARITY},
+ {( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE},
+ {( 9 * 8), ACPI_RESTAG_PINCONFIG},
+ {(10 * 8), ACPI_RESTAG_DRIVESTRENGTH},
+ {(12 * 8), ACPI_RESTAG_DEBOUNCETIME},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmGpioIoTags[] =
+{
+ {( 7 * 8) + 0, ACPI_RESTAG_IORESTRICTION},
+ {( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE},
+ {( 9 * 8), ACPI_RESTAG_PINCONFIG},
+ {(10 * 8), ACPI_RESTAG_DRIVESTRENGTH},
+ {(12 * 8), ACPI_RESTAG_DEBOUNCETIME},
+ {0, NULL}
+};
+
+/* Subtype tables for SerialBus descriptors */
+
+static const ACPI_RESOURCE_TAG AcpiDmI2cSerialBusTags[] =
+{
+ {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE},
+ {( 7 * 8) + 0, ACPI_RESTAG_MODE},
+ {(12 * 8), ACPI_RESTAG_SPEED},
+ {(16 * 8), ACPI_RESTAG_ADDRESS},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmSpiSerialBusTags[] =
+{
+ {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE},
+ {( 7 * 8) + 0, ACPI_RESTAG_MODE},
+ {( 7 * 8) + 1, ACPI_RESTAG_DEVICEPOLARITY},
+ {(12 * 8), ACPI_RESTAG_SPEED},
+ {(16 * 8), ACPI_RESTAG_LENGTH},
+ {(17 * 8), ACPI_RESTAG_PHASE},
+ {(18 * 8), ACPI_RESTAG_POLARITY},
+ {(19 * 8), ACPI_RESTAG_ADDRESS},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmUartSerialBusTags[] =
+{
+ {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE}, /* Note: not part of original macro */
+ {( 7 * 8) + 0, ACPI_RESTAG_FLOWCONTROL},
+ {( 7 * 8) + 2, ACPI_RESTAG_STOPBITS},
+ {( 7 * 8) + 4, ACPI_RESTAG_LENGTH},
+ {( 7 * 8) + 7, ACPI_RESTAG_ENDIANNESS},
+ {(12 * 8), ACPI_RESTAG_SPEED},
+ {(16 * 8), ACPI_RESTAG_LENGTH_RX},
+ {(18 * 8), ACPI_RESTAG_LENGTH_TX},
+ {(20 * 8), ACPI_RESTAG_PARITY},
+ {(21 * 8), ACPI_RESTAG_LINE},
+ {0, NULL}
+};
+
+/* Subtype tables for Address descriptor type-specific flags */
+
+static const ACPI_RESOURCE_TAG AcpiDmMemoryFlagTags[] =
+{
+ {( 5 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
+ {( 5 * 8) + 1, ACPI_RESTAG_MEMTYPE},
+ {( 5 * 8) + 3, ACPI_RESTAG_MEMATTRIBUTES},
+ {( 5 * 8) + 5, ACPI_RESTAG_TYPE},
+ {0, NULL}
+};
+
+static const ACPI_RESOURCE_TAG AcpiDmIoFlagTags[] =
+{
+ {( 5 * 8) + 0, ACPI_RESTAG_RANGETYPE},
+ {( 5 * 8) + 4, ACPI_RESTAG_TYPE},
+ {( 5 * 8) + 5, ACPI_RESTAG_TRANSTYPE},
+ {0, NULL}
+};
+
+
+/*
+ * Dispatch table used to obtain the correct tag table for a descriptor.
+ *
+ * A NULL in this table means one of three things:
+ * 1) The descriptor ID is reserved and invalid
+ * 2) The descriptor has no tags associated with it
+ * 3) The descriptor has subtypes and a separate table will be used.
+ */
+static const ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags[] =
+{
+ /* Small descriptors */
+
+ NULL, /* 0x00, Reserved */
+ NULL, /* 0x01, Reserved */
+ NULL, /* 0x02, Reserved */
+ NULL, /* 0x03, Reserved */
+ AcpiDmIrqTags, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
+ AcpiDmDmaTags, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
+ NULL, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+ NULL, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+ AcpiDmIoTags, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
+ AcpiDmFixedIoTags, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
+ AcpiDmFixedDmaTags, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
+ NULL, /* 0x0B, Reserved */
+ NULL, /* 0x0C, Reserved */
+ NULL, /* 0x0D, Reserved */
+ NULL, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
+ NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
+
+ /* Large descriptors */
+
+ NULL, /* 0x00, Reserved */
+ AcpiDmMemory24Tags, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
+ AcpiDmRegisterTags, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+ NULL, /* 0x03, Reserved */
+ NULL, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
+ AcpiDmMemory32Tags, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
+ AcpiDmFixedMemory32Tags, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
+ AcpiDmAddress32Tags, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
+ AcpiDmAddress16Tags, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
+ AcpiDmInterruptTags, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
+ AcpiDmAddress64Tags, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
+ AcpiDmExtendedAddressTags, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
+ NULL, /* 0x0C, ACPI_RESOURCE_NAME_GPIO - Use Subtype table below */
+ NULL, /* 0x0D, Reserved */
+ NULL /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use Subtype table below */
+};
+
+/* GPIO Subtypes */
+
+static const ACPI_RESOURCE_TAG *AcpiGbl_GpioResourceTags[] =
+{
+ AcpiDmGpioIntTags, /* 0x00 Interrupt Connection */
+ AcpiDmGpioIoTags /* 0x01 I/O Connection */
+};
+
+/* Serial Bus Subtypes */
+
+static const ACPI_RESOURCE_TAG *AcpiGbl_SerialResourceTags[] =
+{
+ NULL, /* 0x00 Reserved */
+ AcpiDmI2cSerialBusTags, /* 0x01 I2C SerialBus */
+ AcpiDmSpiSerialBusTags, /* 0x02 SPI SerialBus */
+ AcpiDmUartSerialBusTags /* 0x03 UART SerialBus */
+};
+
+/*
+ * Globals used to generate unique resource descriptor names. We use names that
+ * start with underscore and a prefix letter that is not used by other ACPI
+ * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes
+ * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL
+ * file. If this becomes too small, we can use alpha+numerals for a total
+ * of 5*36*36 = 6480.
+ */
+#define ACPI_NUM_RES_PREFIX 5
+
+static UINT32 AcpiGbl_NextResourceId = 0;
+static UINT8 AcpiGbl_NextPrefix = 0;
+static char AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] =
+ {'Y','Z','J','K','X'};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckResourceReference
+ *
+ * PARAMETERS: Op - Parse Op for the AML opcode
+ * WalkState - Current walk state (with valid scope)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic
+ * reference if possible
+ *
+ * NOTE: Bit index is used to transparently handle both resource bit
+ * fields and byte fields.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCheckResourceReference (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *BufferNameOp;
+ ACPI_PARSE_OBJECT *IndexOp;
+ ACPI_NAMESPACE_NODE *BufferNode;
+ ACPI_NAMESPACE_NODE *ResourceNode;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 BitIndex;
+
+
+ /* We are only interested in the CreateXxxxField opcodes */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Type != AML_TYPE_CREATE_FIELD)
+ {
+ return;
+ }
+
+ /* Get the buffer term operand */
+
+ BufferNameOp = AcpiPsGetDepthNext (NULL, Op);
+
+ /* Must be a named buffer, not an arg or local or method call */
+
+ if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* Get the Index term, must be an integer constant to convert */
+
+ IndexOp = BufferNameOp->Common.Next;
+
+ /* Major cheat: The Node field is also used for the Tag ptr. Clear it now */
+
+ IndexOp->Common.Node = NULL;
+
+ OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode);
+ if (OpInfo->ObjectType != ACPI_TYPE_INTEGER)
+ {
+ return;
+ }
+
+ /* Get the bit offset of the descriptor within the buffer */
+
+ if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) ||
+ (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP))
+ {
+ /* Index operand is a bit offset */
+
+ BitIndex = (UINT32) IndexOp->Common.Value.Integer;
+ }
+ else
+ {
+ /* Index operand is a byte offset, convert to bits */
+
+ BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer);
+ }
+
+ /* Lookup the buffer in the namespace */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState,
+ &BufferNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Validate object type, we must have a buffer */
+
+ if (BufferNode->Type != ACPI_TYPE_BUFFER)
+ {
+ return;
+ }
+
+ /* Find the resource descriptor node corresponding to the index */
+
+ ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex);
+ if (!ResourceNode)
+ {
+ return;
+ }
+
+ /* Translate the Index to a resource tag pathname */
+
+ AcpiGetTagPathname (IndexOp, BufferNode, ResourceNode, BitIndex);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetResourceNode
+ *
+ * PARAMETERS: BufferNode - Node for the parent buffer
+ * BitIndex - Index into the resource descriptor
+ *
+ * RETURN: Namespace node for the resource descriptor. NULL if not found
+ *
+ * DESCRIPTION: Find a resource descriptor that corresponds to the bit index
+ *
+ ******************************************************************************/
+
+static ACPI_NAMESPACE_NODE *
+AcpiDmGetResourceNode (
+ ACPI_NAMESPACE_NODE *BufferNode,
+ UINT32 BitIndex)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ UINT32 ByteIndex = ACPI_DIV_8 (BitIndex);
+
+
+ /*
+ * Child list contains an entry for each resource descriptor. Find
+ * the descriptor that corresponds to the Index.
+ *
+ * If there are no children, this is not a resource template
+ */
+ Node = BufferNode->Child;
+ while (Node)
+ {
+ /*
+ * Check if the Index falls within this resource.
+ *
+ * Value contains the resource offset, Object contains the resource
+ * length (both in bytes)
+ */
+ if ((ByteIndex >= Node->Value) &&
+ (ByteIndex < (Node->Value + Node->Length)))
+ {
+ return (Node);
+ }
+
+ Node = Node->Peer;
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTagPathname
+ *
+ * PARAMETERS: BufferNode - Node for the parent buffer
+ * ResourceNode - Node for a resource descriptor
+ * BitIndex - Index into the resource descriptor
+ *
+ * RETURN: Full pathname for a resource tag. NULL if no match.
+ * Path is returned in AML (packed) format.
+ *
+ * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
+ *
+ ******************************************************************************/
+
+static char *
+AcpiGetTagPathname (
+ ACPI_PARSE_OBJECT *IndexOp,
+ ACPI_NAMESPACE_NODE *BufferNode,
+ ACPI_NAMESPACE_NODE *ResourceNode,
+ UINT32 BitIndex)
+{
+ ACPI_STATUS Status;
+ UINT32 ResourceBitIndex;
+ UINT8 ResourceTableIndex;
+ ACPI_SIZE RequiredSize;
+ char *Pathname;
+ AML_RESOURCE *Aml;
+ ACPI_PARSE_OBJECT *Op;
+ char *InternalPath;
+ char *Tag;
+
+
+ /* Get the Op that contains the actual buffer data */
+
+ Op = BufferNode->Op->Common.Value.Arg;
+ Op = Op->Common.Next;
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ /* Get the individual resource descriptor and validate it */
+
+ Aml = ACPI_CAST_PTR (AML_RESOURCE,
+ &Op->Named.Data[ResourceNode->Value]);
+
+ Status = AcpiUtValidateResource (NULL, Aml, &ResourceTableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (NULL);
+ }
+
+ /* Get offset into this descriptor (from offset into entire buffer) */
+
+ ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
+
+ /* Get the tag associated with this resource descriptor and offset */
+
+ Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
+ if (!Tag)
+ {
+ return (NULL);
+ }
+
+ /*
+ * Now that we know that we have a reference that can be converted to a
+ * symbol, change the name of the resource to a unique name.
+ */
+ AcpiDmUpdateResourceName (ResourceNode);
+
+ /* Get the full pathname to the parent buffer */
+
+ RequiredSize = AcpiNsBuildNormalizedPath (BufferNode, NULL, 0, FALSE);
+ if (!RequiredSize)
+ {
+ return (NULL);
+ }
+
+ Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
+ if (!Pathname)
+ {
+ return (NULL);
+ }
+
+ (void) AcpiNsBuildNormalizedPath (BufferNode, Pathname,
+ RequiredSize, FALSE);
+
+ /*
+ * Create the full path to the resource and tag by: remove the buffer name,
+ * append the resource descriptor name, append a dot, append the tag name.
+ *
+ * TBD: Always using the full path is a bit brute force, the path can be
+ * often be optimized with carats (if the original buffer namepath is a
+ * single nameseg). This doesn't really matter, because these paths do not
+ * end up in the final compiled AML, it's just an appearance issue for the
+ * disassembled code.
+ */
+ Pathname[strlen (Pathname) - ACPI_NAME_SIZE] = 0;
+ strncat (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
+ strcat (Pathname, ".");
+ strncat (Pathname, Tag, ACPI_NAME_SIZE);
+
+ /* Internalize the namepath to AML format */
+
+ AcpiNsInternalizeName (Pathname, &InternalPath);
+ ACPI_FREE (Pathname);
+
+ /* Update the Op with the symbol */
+
+ AcpiPsInitOp (IndexOp, AML_INT_NAMEPATH_OP);
+ IndexOp->Common.Value.String = InternalPath;
+
+ /* We will need the tag later. Cheat by putting it in the Node field */
+
+ IndexOp->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Tag);
+ return (InternalPath);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUpdateResourceName
+ *
+ * PARAMETERS: ResourceNode - Node for a resource descriptor
+ *
+ * RETURN: Stores new name in the ResourceNode
+ *
+ * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
+ * both the disassembly of the descriptor itself and any symbolic
+ * references to the descriptor. Ignored if a unique name has
+ * already been assigned to the resource.
+ *
+ * NOTE: Single threaded, suitable for applications only!
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUpdateResourceName (
+ ACPI_NAMESPACE_NODE *ResourceNode)
+{
+ char Name[ACPI_NAME_SIZE];
+
+
+ /* Ignore if a unique name has already been assigned */
+
+ if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
+ {
+ return;
+ }
+
+ /* Generate a new ACPI name for the descriptor */
+
+ Name[0] = '_';
+ Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
+ Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4);
+ Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0);
+
+ /* Update globals for next name */
+
+ AcpiGbl_NextResourceId++;
+ if (AcpiGbl_NextResourceId >= 256)
+ {
+ AcpiGbl_NextResourceId = 0;
+ AcpiGbl_NextPrefix++;
+ if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
+ {
+ AcpiGbl_NextPrefix = 0;
+ }
+ }
+
+ /* Change the resource descriptor name */
+
+ ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetResourceTag
+ *
+ * PARAMETERS: BitIndex - Index into the resource descriptor
+ * Resource - Pointer to the raw resource data
+ * ResourceIndex - Index correspoinding to the resource type
+ *
+ * RETURN: Pointer to the resource tag (ACPI_NAME). NULL if no match.
+ *
+ * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
+ *
+ * Note: ResourceIndex should be previously validated and guaranteed to ve
+ * valid.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmGetResourceTag (
+ UINT32 BitIndex,
+ AML_RESOURCE *Resource,
+ UINT8 ResourceIndex)
+{
+ const ACPI_RESOURCE_TAG *TagList;
+ char *Tag = NULL;
+
+
+ /* Get the tag list for this resource descriptor type */
+
+ TagList = AcpiGbl_ResourceTags[ResourceIndex];
+
+ /*
+ * Handle descriptors that have multiple subtypes
+ */
+ switch (Resource->DescriptorType)
+ {
+ case ACPI_RESOURCE_NAME_ADDRESS16:
+ case ACPI_RESOURCE_NAME_ADDRESS32:
+ case ACPI_RESOURCE_NAME_ADDRESS64:
+ case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
+ /*
+ * Subtype differentiation is the flags.
+ * Kindof brute force, but just blindly search for an index match
+ */
+ if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
+ {
+ Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
+ }
+ else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
+ {
+ Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
+ }
+
+ /* If we found a match, all done. Else, drop to normal search below */
+
+ if (Tag)
+ {
+ return (Tag);
+ }
+ break;
+
+ case ACPI_RESOURCE_NAME_GPIO:
+
+ /* GPIO connection has 2 subtypes: Interrupt and I/O */
+
+ if (Resource->Gpio.ConnectionType > AML_RESOURCE_MAX_GPIOTYPE)
+ {
+ return (NULL);
+ }
+
+ TagList = AcpiGbl_GpioResourceTags[Resource->Gpio.ConnectionType];
+ break;
+
+ case ACPI_RESOURCE_NAME_SERIAL_BUS:
+
+ /* SerialBus has 3 subtypes: I2C, SPI, and UART */
+
+ if ((Resource->CommonSerialBus.Type == 0) ||
+ (Resource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
+ {
+ return (NULL);
+ }
+
+ TagList = AcpiGbl_SerialResourceTags[Resource->CommonSerialBus.Type];
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Search for a match against the BitIndex */
+
+ if (TagList)
+ {
+ Tag = AcpiDmSearchTagList (BitIndex, TagList);
+ }
+
+ return (Tag);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSearchTagList
+ *
+ * PARAMETERS: BitIndex - Index into the resource descriptor
+ * TagList - List to search
+ *
+ * RETURN: Pointer to a tag (ACPI_NAME). NULL if no match found.
+ *
+ * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
+ * a fixed offset to a symbolic resource tag name.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmSearchTagList (
+ UINT32 BitIndex,
+ const ACPI_RESOURCE_TAG *TagList)
+{
+
+ /*
+ * Walk the null-terminated tag list to find a matching bit offset.
+ * We are looking for an exact match.
+ */
+ for ( ; TagList->Tag; TagList++)
+ {
+ if (BitIndex == TagList->BitIndex)
+ {
+ return (TagList->Tag);
+ }
+ }
+
+ /* A matching offset was not found */
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFindResources
+ *
+ * PARAMETERS: Root - Root of the parse tree
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
+ * resource descriptor in each template is given a node -- used
+ * for later conversion of resource references to symbolic refs.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFindResources (
+ ACPI_PARSE_OBJECT *Root)
+{
+ ACPI_PARSE_OBJECT *Op = Root;
+ ACPI_PARSE_OBJECT *Parent;
+
+
+ /* Walk the entire parse tree */
+
+ while (Op)
+ {
+ /* We are interested in Buffer() declarations */
+
+ if (Op->Common.AmlOpcode == AML_BUFFER_OP)
+ {
+ /* And only declarations of the form Name (XXXX, Buffer()... ) */
+
+ Parent = Op->Common.Parent;
+ if (Parent->Common.AmlOpcode == AML_NAME_OP)
+ {
+ /*
+ * If the buffer is a resource template, add the individual
+ * resource descriptors to the namespace, as children of the
+ * buffer node.
+ */
+ if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (NULL, Op)))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+ AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
+ }
+ }
+ }
+
+ Op = AcpiPsGetDepthNext (Root, Op);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddResourcesToNamespace
+ *
+ * PARAMETERS: BufferNode - Node for the parent buffer
+ * Op - Parse op for the buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add an entire resource template to the namespace. Each
+ * resource descriptor is added as a namespace node.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddResourcesToNamespace (
+ ACPI_NAMESPACE_NODE *BufferNode,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Get to the ByteData list */
+
+ NextOp = Op->Common.Value.Arg;
+ NextOp = NextOp->Common.Next;
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Set Node and Op to point to each other */
+
+ BufferNode->Op = Op;
+ Op->Common.Node = BufferNode;
+
+ /*
+ * Insert each resource into the namespace
+ * NextOp contains the Aml pointer and the Aml length
+ */
+ AcpiUtWalkAmlResources (NULL, (UINT8 *) NextOp->Named.Data,
+ (ACPI_SIZE) NextOp->Common.Value.Integer,
+ AcpiDmAddResourceToNamespace, (void **) BufferNode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddResourceToNamespace
+ *
+ * PARAMETERS: ACPI_WALK_AML_CALLBACK
+ * BufferNode - Node for the parent buffer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
+ * parent buffer. The same name is used for each descriptor. This
+ * is changed later to a unique name if the resource is actually
+ * referenced by an AML operator.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmAddResourceToNamespace (
+ UINT8 *Aml,
+ UINT32 Length,
+ UINT32 Offset,
+ UINT8 ResourceIndex,
+ void **Context)
+{
+ ACPI_STATUS Status;
+ ACPI_GENERIC_STATE ScopeInfo;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /* TBD: Don't need to add descriptors that have no tags defined? */
+
+ /* Add the resource to the namespace, as child of the buffer */
+
+ ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
+ Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
+ ACPI_IMODE_LOAD_PASS2,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
+ NULL, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /* Set the name to the default, changed later if resource is referenced */
+
+ Node->Name.Integer = ACPI_DEFAULT_RESNAME;
+
+ /* Save the offset of the descriptor (within the original buffer) */
+
+ Node->Value = Offset;
+ Node->Length = Length;
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/dmtable.c b/usr/src/boot/sys/contrib/dev/acpica/common/dmtable.c
new file mode 100644
index 0000000000..44657d8eec
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/dmtable.c
@@ -0,0 +1,1518 @@
+/******************************************************************************
+ *
+ * Module Name: dmtable - Support for ACPI tables that contain no AML code
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmtable")
+
+const AH_TABLE *
+AcpiAhGetTableInfo (
+ char *Signature);
+
+
+/* Local Prototypes */
+
+static void
+AcpiDmCheckAscii (
+ UINT8 *Target,
+ char *RepairedName,
+ UINT32 Count);
+
+
+/* Common format strings for commented values */
+
+#define UINT8_FORMAT "%2.2X [%s]\n"
+#define UINT16_FORMAT "%4.4X [%s]\n"
+#define UINT32_FORMAT "%8.8X [%s]\n"
+#define STRING_FORMAT "[%s]\n"
+
+/* These tables map a subtable type to a description string */
+
+static const char *AcpiDmAsfSubnames[] =
+{
+ "ASF Information",
+ "ASF Alerts",
+ "ASF Remote Control",
+ "ASF RMCP Boot Options",
+ "ASF Address",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmDmarSubnames[] =
+{
+ "Hardware Unit Definition",
+ "Reserved Memory Region",
+ "Root Port ATS Capability",
+ "Remapping Hardware Static Affinity",
+ "ACPI Namespace Device Declaration",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmDmarScope[] =
+{
+ "Reserved value",
+ "PCI Endpoint Device",
+ "PCI Bridge Device",
+ "IOAPIC Device",
+ "Message-capable HPET Device",
+ "Namespace Device",
+ "Unknown Scope Type" /* Reserved */
+};
+
+static const char *AcpiDmEinjActions[] =
+{
+ "Begin Operation",
+ "Get Trigger Table",
+ "Set Error Type",
+ "Get Error Type",
+ "End Operation",
+ "Execute Operation",
+ "Check Busy Status",
+ "Get Command Status",
+ "Set Error Type With Address",
+ "Unknown Action"
+};
+
+static const char *AcpiDmEinjInstructions[] =
+{
+ "Read Register",
+ "Read Register Value",
+ "Write Register",
+ "Write Register Value",
+ "Noop",
+ "Flush Cacheline",
+ "Unknown Instruction"
+};
+
+static const char *AcpiDmErstActions[] =
+{
+ "Begin Write Operation",
+ "Begin Read Operation",
+ "Begin Clear Operation",
+ "End Operation",
+ "Set Record Offset",
+ "Execute Operation",
+ "Check Busy Status",
+ "Get Command Status",
+ "Get Record Identifier",
+ "Set Record Identifier",
+ "Get Record Count",
+ "Begin Dummy Write",
+ "Unused/Unknown Action",
+ "Get Error Address Range",
+ "Get Error Address Length",
+ "Get Error Attributes",
+ "Unknown Action"
+};
+
+static const char *AcpiDmErstInstructions[] =
+{
+ "Read Register",
+ "Read Register Value",
+ "Write Register",
+ "Write Register Value",
+ "Noop",
+ "Load Var1",
+ "Load Var2",
+ "Store Var1",
+ "Add",
+ "Subtract",
+ "Add Value",
+ "Subtract Value",
+ "Stall",
+ "Stall While True",
+ "Skip Next If True",
+ "GoTo",
+ "Set Source Address",
+ "Set Destination Address",
+ "Move Data",
+ "Unknown Instruction"
+};
+
+static const char *AcpiDmGtdtSubnames[] =
+{
+ "Generic Timer Block",
+ "Generic Watchdog Timer",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmHestSubnames[] =
+{
+ "IA-32 Machine Check Exception",
+ "IA-32 Corrected Machine Check",
+ "IA-32 Non-Maskable Interrupt",
+ "Unknown SubTable Type", /* 3 - Reserved */
+ "Unknown SubTable Type", /* 4 - Reserved */
+ "Unknown SubTable Type", /* 5 - Reserved */
+ "PCI Express Root Port AER",
+ "PCI Express AER (AER Endpoint)",
+ "PCI Express/PCI-X Bridge AER",
+ "Generic Hardware Error Source",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmHestNotifySubnames[] =
+{
+ "Polled",
+ "External Interrupt",
+ "Local Interrupt",
+ "SCI",
+ "NMI",
+ "CMCI", /* ACPI 5.0 */
+ "MCE", /* ACPI 5.0 */
+ "Unknown Notify Type" /* Reserved */
+};
+
+static const char *AcpiDmMadtSubnames[] =
+{
+ "Processor Local APIC", /* ACPI_MADT_TYPE_LOCAL_APIC */
+ "I/O APIC", /* ACPI_MADT_TYPE_IO_APIC */
+ "Interrupt Source Override", /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
+ "NMI Source", /* ACPI_MADT_TYPE_NMI_SOURCE */
+ "Local APIC NMI", /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
+ "Local APIC Address Override", /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
+ "I/O SAPIC", /* ACPI_MADT_TYPE_IO_SAPIC */
+ "Local SAPIC", /* ACPI_MADT_TYPE_LOCAL_SAPIC */
+ "Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
+ "Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */
+ "Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
+ "Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */
+ "Generic Interrupt Distributor", /* ACPI_MADT_GENERIC_DISTRIBUTOR */
+ "Generic MSI Frame", /* ACPI_MADT_GENERIC_MSI_FRAME */
+ "Generic Interrupt Redistributor", /* ACPI_MADT_GENERIC_REDISTRIBUTOR */
+ "Generic Interrupt Translator", /* ACPI_MADT_GENERIC_TRANSLATOR */
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmNfitSubnames[] =
+{
+ "System Physical Address Range", /* ACPI_NFIT_TYPE_SYSTEM_ADDRESS */
+ "Memory Range Map", /* ACPI_NFIT_TYPE_MEMORY_MAP */
+ "Interleave Info", /* ACPI_NFIT_TYPE_INTERLEAVE */
+ "SMBIOS Information", /* ACPI_NFIT_TYPE_SMBIOS */
+ "NVDIMM Control Region", /* ACPI_NFIT_TYPE_CONTROL_REGION */
+ "NVDIMM Block Data Window Region", /* ACPI_NFIT_TYPE_DATA_REGION */
+ "Flush Hint Address", /* ACPI_NFIT_TYPE_FLUSH_ADDRESS */
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmPcctSubnames[] =
+{
+ "Generic Communications Subspace", /* ACPI_PCCT_TYPE_GENERIC_SUBSPACE */
+ "HW-Reduced Comm Subspace", /* ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE */
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmPmttSubnames[] =
+{
+ "Socket", /* ACPI_PMTT_TYPE_SOCKET */
+ "Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */
+ "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmSratSubnames[] =
+{
+ "Processor Local APIC/SAPIC Affinity",
+ "Memory Affinity",
+ "Processor Local x2APIC Affinity",
+ "GICC Affinity",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmIvrsSubnames[] =
+{
+ "Hardware Definition Block",
+ "Memory Definition Block",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmLpitSubnames[] =
+{
+ "Native C-state Idle Structure",
+ "Unknown Subtable Type" /* Reserved */
+};
+
+#define ACPI_FADT_PM_RESERVED 9
+
+static const char *AcpiDmFadtProfiles[] =
+{
+ "Unspecified",
+ "Desktop",
+ "Mobile",
+ "Workstation",
+ "Enterprise Server",
+ "SOHO Server",
+ "Appliance PC",
+ "Performance Server",
+ "Tablet",
+ "Unknown Profile Type"
+};
+
+#define ACPI_GAS_WIDTH_RESERVED 5
+
+static const char *AcpiDmGasAccessWidth[] =
+{
+ "Undefined/Legacy",
+ "Byte Access:8",
+ "Word Access:16",
+ "DWord Access:32",
+ "QWord Access:64",
+ "Unknown Width Encoding"
+};
+
+
+/*******************************************************************************
+ *
+ * ACPI Table Data, indexed by signature.
+ *
+ * Each entry contains: Signature, Table Info, Handler, DtHandler,
+ * Template, Description
+ *
+ * Simple tables have only a TableInfo structure, complex tables have a
+ * handler. This table must be NULL terminated. RSDP and FACS are
+ * special-cased elsewhere.
+ *
+ * Note: Any tables added here should be duplicated within AcpiSupportedTables
+ * in the file common/ahtable.c
+ *
+ ******************************************************************************/
+
+const ACPI_DMTABLE_DATA AcpiDmTableData[] =
+{
+ {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf},
+ {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert},
+ {ACPI_SIG_BGRT, AcpiDmTableInfoBgrt, NULL, NULL, TemplateBgrt},
+ {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot},
+ {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep},
+ {ACPI_SIG_CSRT, NULL, AcpiDmDumpCsrt, DtCompileCsrt, TemplateCsrt},
+ {ACPI_SIG_DBG2, AcpiDmTableInfoDbg2, AcpiDmDumpDbg2, DtCompileDbg2, TemplateDbg2},
+ {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp},
+ {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar},
+ {ACPI_SIG_DRTM, NULL, AcpiDmDumpDrtm, DtCompileDrtm, TemplateDrtm},
+ {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt},
+ {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj},
+ {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst},
+ {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt},
+ {ACPI_SIG_FPDT, NULL, AcpiDmDumpFpdt, DtCompileFpdt, TemplateFpdt},
+ {ACPI_SIG_GTDT, NULL, AcpiDmDumpGtdt, DtCompileGtdt, TemplateGtdt},
+ {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest},
+ {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet},
+ {ACPI_SIG_IORT, NULL, AcpiDmDumpIort, DtCompileIort, TemplateIort},
+ {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs},
+ {ACPI_SIG_LPIT, NULL, AcpiDmDumpLpit, DtCompileLpit, TemplateLpit},
+ {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt},
+ {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg},
+ {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi},
+ {ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst},
+ {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct},
+ {ACPI_SIG_MSDM, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateMsdm},
+ {ACPI_SIG_MTMR, NULL, AcpiDmDumpMtmr, DtCompileMtmr, TemplateMtmr},
+ {ACPI_SIG_NFIT, AcpiDmTableInfoNfit, AcpiDmDumpNfit, DtCompileNfit, TemplateNfit},
+ {ACPI_SIG_PCCT, AcpiDmTableInfoPcct, AcpiDmDumpPcct, DtCompilePcct, TemplatePcct},
+ {ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt},
+ {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt},
+ {ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt},
+ {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst},
+ {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic},
+ {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit},
+ {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr},
+ {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi},
+ {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat},
+ {ACPI_SIG_STAO, NULL, AcpiDmDumpStao, DtCompileStao, TemplateStao},
+ {ACPI_SIG_TCPA, NULL, AcpiDmDumpTcpa, DtCompileTcpa, TemplateTcpa},
+ {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, NULL, NULL, TemplateTpm2},
+ {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi},
+ {ACPI_SIG_VRTC, AcpiDmTableInfoVrtc, AcpiDmDumpVrtc, DtCompileVrtc, TemplateVrtc},
+ {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet},
+ {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat},
+ {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt},
+ {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt},
+ {ACPI_SIG_WPBT, NULL, AcpiDmDumpWpbt, DtCompileWpbt, TemplateWpbt},
+ {ACPI_SIG_XENV, AcpiDmTableInfoXenv, NULL, NULL, TemplateXenv},
+ {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt},
+ {NULL, NULL, NULL, NULL, NULL}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGenerateChecksum
+ *
+ * PARAMETERS: Table - Pointer to table to be checksummed
+ * Length - Length of the table
+ * OriginalChecksum - Value of the checksum field
+ *
+ * RETURN: 8 bit checksum of buffer
+ *
+ * DESCRIPTION: Computes an 8 bit checksum of the table.
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiDmGenerateChecksum (
+ void *Table,
+ UINT32 Length,
+ UINT8 OriginalChecksum)
+{
+ UINT8 Checksum;
+
+
+ /* Sum the entire table as-is */
+
+ Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
+
+ /* Subtract off the existing checksum value in the table */
+
+ Checksum = (UINT8) (Checksum - OriginalChecksum);
+
+ /* Compute the final checksum */
+
+ Checksum = (UINT8) (0 - Checksum);
+ return (Checksum);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetTableData
+ *
+ * PARAMETERS: Signature - ACPI signature (4 chars) to match
+ *
+ * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
+ *
+ * DESCRIPTION: Find a match in the global table of supported ACPI tables
+ *
+ ******************************************************************************/
+
+const ACPI_DMTABLE_DATA *
+AcpiDmGetTableData (
+ char *Signature)
+{
+ const ACPI_DMTABLE_DATA *Info;
+
+
+ for (Info = AcpiDmTableData; Info->Signature; Info++)
+ {
+ if (ACPI_COMPARE_NAME (Signature, Info->Signature))
+ {
+ return (Info);
+ }
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpDataTable
+ *
+ * PARAMETERS: Table - An ACPI table
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Format the contents of an ACPI data table (any table other
+ * than an SSDT or DSDT that does not contain executable AML code)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpDataTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ const ACPI_DMTABLE_DATA *TableData;
+ UINT32 Length;
+
+
+ /* Ignore tables that contain AML */
+
+ if (AcpiUtIsAmlTable (Table))
+ {
+ if (Gbl_VerboseTemplates)
+ {
+ /* Dump the raw table data */
+
+ Length = Table->Length;
+
+ AcpiOsPrintf ("\n/*\n%s: Length %d (0x%X)\n\n",
+ ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
+ AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
+ Length, DB_BYTE_DISPLAY, 0);
+ AcpiOsPrintf (" */\n");
+ }
+ return;
+ }
+
+ /*
+ * Handle tables that don't use the common ACPI table header structure.
+ * Currently, these are the FACS, RSDP, and S3PT.
+ */
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
+ {
+ Length = Table->Length;
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ else if (ACPI_VALIDATE_RSDP_SIG (Table->Signature))
+ {
+ Length = AcpiDmDumpRsdp (Table);
+ }
+ else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
+ {
+ Length = AcpiDmDumpS3pt (Table);
+ }
+ else
+ {
+ /*
+ * All other tables must use the common ACPI table header, dump it now
+ */
+ Length = Table->Length;
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ AcpiOsPrintf ("\n");
+
+ /* Match signature and dispatch appropriately */
+
+ TableData = AcpiDmGetTableData (Table->Signature);
+ if (!TableData)
+ {
+ if (!strncmp (Table->Signature, "OEM", 3))
+ {
+ AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
+ Table->Signature);
+ }
+ else
+ {
+ AcpiOsPrintf ("\n**** Unknown ACPI table signature [%4.4s]\n\n",
+ Table->Signature);
+
+ fprintf (stderr, "Unknown ACPI table signature [%4.4s], ",
+ Table->Signature);
+
+ if (!AcpiGbl_ForceAmlDisassembly)
+ {
+ fprintf (stderr, "decoding ACPI table header only\n");
+ }
+ else
+ {
+ fprintf (stderr, "assuming table contains valid AML code\n");
+ }
+ }
+ }
+ else if (TableData->TableHandler)
+ {
+ /* Complex table, has a handler */
+
+ TableData->TableHandler (Table);
+ }
+ else if (TableData->TableInfo)
+ {
+ /* Simple table, just walk the info table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ }
+
+ if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
+ {
+ /* Dump the raw table data */
+
+ AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
+ ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
+ AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
+ Length, DB_BYTE_DISPLAY, 0);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmLineHeader
+ *
+ * PARAMETERS: Offset - Current byte offset, from table start
+ * ByteLength - Length of the field in bytes, 0 for flags
+ * Name - Name of this field
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Utility routines for formatting output lines. Displays the
+ * current table offset in hex and decimal, the field length,
+ * and the field name.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmLineHeader (
+ UINT32 Offset,
+ UINT32 ByteLength,
+ char *Name)
+{
+
+ /* Allow a null name for fields that span multiple lines (large buffers) */
+
+ if (!Name)
+ {
+ Name = "";
+ }
+
+ if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
+ {
+ if (ByteLength)
+ {
+ AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
+ }
+ else
+ {
+ if (*Name)
+ {
+ AcpiOsPrintf ("%41s : ", Name);
+ }
+ else
+ {
+ AcpiOsPrintf ("%41s ", Name);
+ }
+ }
+ }
+ else /* Normal disassembler or verbose template */
+ {
+ if (ByteLength)
+ {
+ AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
+ Offset, Offset, ByteLength, Name);
+ }
+ else
+ {
+ if (*Name)
+ {
+ AcpiOsPrintf ("%44s : ", Name);
+ }
+ else
+ {
+ AcpiOsPrintf ("%44s ", Name);
+ }
+ }
+ }
+}
+
+void
+AcpiDmLineHeader2 (
+ UINT32 Offset,
+ UINT32 ByteLength,
+ char *Name,
+ UINT32 Value)
+{
+
+ if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
+ {
+ if (ByteLength)
+ {
+ AcpiOsPrintf ("[%.4d] %30s %3d : ",
+ ByteLength, Name, Value);
+ }
+ else
+ {
+ AcpiOsPrintf ("%36s % 3d : ",
+ Name, Value);
+ }
+ }
+ else /* Normal disassembler or verbose template */
+ {
+ if (ByteLength)
+ {
+ AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
+ Offset, Offset, ByteLength, Name, Value);
+ }
+ else
+ {
+ AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ",
+ Offset, Offset, Name, Value);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpTable
+ *
+ * PARAMETERS: TableLength - Length of the entire ACPI table
+ * TableOffset - Starting offset within the table for this
+ * sub-descriptor (0 if main table)
+ * Table - The ACPI table
+ * SubtableLength - Length of this sub-descriptor
+ * Info - Info table for this ACPI table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display ACPI table contents by walking the Info table.
+ *
+ * Note: This function must remain in sync with DtGetFieldLength.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDmDumpTable (
+ UINT32 TableLength,
+ UINT32 TableOffset,
+ void *Table,
+ UINT32 SubtableLength,
+ ACPI_DMTABLE_INFO *Info)
+{
+ UINT8 *Target;
+ UINT32 CurrentOffset;
+ UINT32 ByteLength;
+ UINT8 Temp8;
+ UINT16 Temp16;
+ UINT32 Temp32;
+ UINT64 Value;
+ const AH_TABLE *TableData;
+ const char *Name;
+ BOOLEAN LastOutputBlankLine = FALSE;
+ ACPI_STATUS Status;
+ char RepairedName[8];
+
+
+ if (!Info)
+ {
+ AcpiOsPrintf ("Display not implemented\n");
+ return (AE_NOT_IMPLEMENTED);
+ }
+
+ /* Walk entire Info table; Null name terminates */
+
+ for (; Info->Name; Info++)
+ {
+ /*
+ * Target points to the field within the ACPI Table. CurrentOffset is
+ * the offset of the field from the start of the main table.
+ */
+ Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
+ CurrentOffset = TableOffset + Info->Offset;
+
+ /* Check for beyond subtable end or (worse) beyond EOT */
+
+ if (SubtableLength && (Info->Offset >= SubtableLength))
+ {
+ AcpiOsPrintf (
+ "/**** ACPI subtable terminates early - "
+ "may be older version (dump table) */\n");
+
+ /* Move on to next subtable */
+
+ return (AE_OK);
+ }
+
+ if (CurrentOffset >= TableLength)
+ {
+ AcpiOsPrintf (
+ "/**** ACPI table terminates "
+ "in the middle of a data structure! (dump table) */\n");
+ return (AE_BAD_DATA);
+ }
+
+ /* Generate the byte length for this field */
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_UINT8:
+ case ACPI_DMT_CHKSUM:
+ case ACPI_DMT_SPACEID:
+ case ACPI_DMT_ACCWIDTH:
+ case ACPI_DMT_IVRS:
+ case ACPI_DMT_GTDT:
+ case ACPI_DMT_MADT:
+ case ACPI_DMT_PCCT:
+ case ACPI_DMT_PMTT:
+ case ACPI_DMT_SRAT:
+ case ACPI_DMT_ASF:
+ case ACPI_DMT_HESTNTYP:
+ case ACPI_DMT_FADTPM:
+ case ACPI_DMT_EINJACT:
+ case ACPI_DMT_EINJINST:
+ case ACPI_DMT_ERSTACT:
+ case ACPI_DMT_ERSTINST:
+ case ACPI_DMT_DMAR_SCOPE:
+
+ ByteLength = 1;
+ break;
+
+ case ACPI_DMT_UINT16:
+ case ACPI_DMT_DMAR:
+ case ACPI_DMT_HEST:
+ case ACPI_DMT_NFIT:
+
+ ByteLength = 2;
+ break;
+
+ case ACPI_DMT_UINT24:
+
+ ByteLength = 3;
+ break;
+
+ case ACPI_DMT_UINT32:
+ case ACPI_DMT_NAME4:
+ case ACPI_DMT_SIG:
+ case ACPI_DMT_LPIT:
+
+ ByteLength = 4;
+ break;
+
+ case ACPI_DMT_UINT40:
+
+ ByteLength = 5;
+ break;
+
+ case ACPI_DMT_UINT48:
+ case ACPI_DMT_NAME6:
+
+ ByteLength = 6;
+ break;
+
+ case ACPI_DMT_UINT56:
+ case ACPI_DMT_BUF7:
+
+ ByteLength = 7;
+ break;
+
+ case ACPI_DMT_UINT64:
+ case ACPI_DMT_NAME8:
+
+ ByteLength = 8;
+ break;
+
+ case ACPI_DMT_BUF10:
+
+ ByteLength = 10;
+ break;
+
+ case ACPI_DMT_BUF16:
+ case ACPI_DMT_UUID:
+
+ ByteLength = 16;
+ break;
+
+ case ACPI_DMT_BUF128:
+
+ ByteLength = 128;
+ break;
+
+ case ACPI_DMT_UNICODE:
+ case ACPI_DMT_BUFFER:
+ case ACPI_DMT_RAW_BUFFER:
+
+ ByteLength = SubtableLength;
+ break;
+
+ case ACPI_DMT_STRING:
+
+ ByteLength = strlen (ACPI_CAST_PTR (char, Target)) + 1;
+ break;
+
+ case ACPI_DMT_GAS:
+
+ if (!LastOutputBlankLine)
+ {
+ AcpiOsPrintf ("\n");
+ LastOutputBlankLine = TRUE;
+ }
+ ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
+ break;
+
+ case ACPI_DMT_HESTNTFY:
+
+ if (!LastOutputBlankLine)
+ {
+ AcpiOsPrintf ("\n");
+ LastOutputBlankLine = TRUE;
+ }
+ ByteLength = sizeof (ACPI_HEST_NOTIFY);
+ break;
+
+ case ACPI_DMT_IORTMEM:
+
+ if (!LastOutputBlankLine)
+ {
+ LastOutputBlankLine = FALSE;
+ }
+ ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
+ break;
+
+ default:
+
+ ByteLength = 0;
+ break;
+ }
+
+ /* Check if we are beyond a subtable, or (worse) beyond EOT */
+
+ if (CurrentOffset + ByteLength > TableLength)
+ {
+ if (SubtableLength)
+ {
+ AcpiOsPrintf (
+ "/**** ACPI subtable terminates early - "
+ "may be older version (dump table) */\n");
+
+ /* Move on to next subtable */
+
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf (
+ "/**** ACPI table terminates "
+ "in the middle of a data structure! */\n");
+ return (AE_BAD_DATA);
+ }
+
+ if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
+ {
+ AcpiOsPrintf ("%s", Info->Name);
+ continue;
+ }
+
+ /* Start a new line and decode the opcode */
+
+ AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
+
+ switch (Info->Opcode)
+ {
+ /* Single-bit Flag fields. Note: Opcode is the bit position */
+
+ case ACPI_DMT_FLAG0:
+ case ACPI_DMT_FLAG1:
+ case ACPI_DMT_FLAG2:
+ case ACPI_DMT_FLAG3:
+ case ACPI_DMT_FLAG4:
+ case ACPI_DMT_FLAG5:
+ case ACPI_DMT_FLAG6:
+ case ACPI_DMT_FLAG7:
+
+ AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
+ break;
+
+ /* 2-bit Flag fields */
+
+ case ACPI_DMT_FLAGS0:
+
+ AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
+ break;
+
+ case ACPI_DMT_FLAGS1:
+
+ AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
+ break;
+
+ case ACPI_DMT_FLAGS2:
+
+ AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
+ break;
+
+ case ACPI_DMT_FLAGS4:
+
+ AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
+ break;
+
+ /* Integer Data Types */
+
+ case ACPI_DMT_UINT8:
+ case ACPI_DMT_UINT16:
+ case ACPI_DMT_UINT24:
+ case ACPI_DMT_UINT32:
+ case ACPI_DMT_UINT40:
+ case ACPI_DMT_UINT48:
+ case ACPI_DMT_UINT56:
+ case ACPI_DMT_UINT64:
+ /*
+ * Dump bytes - high byte first, low byte last.
+ * Note: All ACPI tables are little-endian.
+ */
+ Value = 0;
+ for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
+ {
+ AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
+ Value |= Target[Temp8 - 1];
+ Value <<= 8;
+ }
+
+ if (!Value && (Info->Flags & DT_DESCRIBES_OPTIONAL))
+ {
+ AcpiOsPrintf (" [Optional field not present]");
+ }
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DMT_BUF7:
+ case ACPI_DMT_BUF10:
+ case ACPI_DMT_BUF16:
+ case ACPI_DMT_BUF128:
+ /*
+ * Buffer: Size depends on the opcode and was set above.
+ * Each hex byte is separated with a space.
+ * Multiple lines are separated by line continuation char.
+ */
+ for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
+ {
+ AcpiOsPrintf ("%2.2X", Target[Temp16]);
+ if ((UINT32) (Temp16 + 1) < ByteLength)
+ {
+ if ((Temp16 > 0) && (!((Temp16+1) % 16)))
+ {
+ AcpiOsPrintf (" \\\n"); /* Line continuation */
+ AcpiDmLineHeader (0, 0, NULL);
+ }
+ else
+ {
+ AcpiOsPrintf (" ");
+ }
+ }
+ }
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DMT_UUID:
+
+ /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
+
+ (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
+
+ AcpiOsPrintf ("%s\n", MsgBuffer);
+ break;
+
+ case ACPI_DMT_STRING:
+
+ AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
+ break;
+
+ /* Fixed length ASCII name fields */
+
+ case ACPI_DMT_SIG:
+
+ AcpiDmCheckAscii (Target, RepairedName, 4);
+ AcpiOsPrintf ("\"%.4s\" ", RepairedName);
+ TableData = AcpiAhGetTableInfo (ACPI_CAST_PTR (char, Target));
+ if (TableData)
+ {
+ AcpiOsPrintf (STRING_FORMAT, TableData->Description);
+ }
+ else
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ case ACPI_DMT_NAME4:
+
+ AcpiDmCheckAscii (Target, RepairedName, 4);
+ AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
+ break;
+
+ case ACPI_DMT_NAME6:
+
+ AcpiDmCheckAscii (Target, RepairedName, 6);
+ AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
+ break;
+
+ case ACPI_DMT_NAME8:
+
+ AcpiDmCheckAscii (Target, RepairedName, 8);
+ AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
+ break;
+
+ /* Special Data Types */
+
+ case ACPI_DMT_CHKSUM:
+
+ /* Checksum, display and validate */
+
+ AcpiOsPrintf ("%2.2X", *Target);
+ Temp8 = AcpiDmGenerateChecksum (Table,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
+
+ if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
+ {
+ AcpiOsPrintf (
+ " /* Incorrect checksum, should be %2.2X */", Temp8);
+ }
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DMT_SPACEID:
+
+ /* Address Space ID */
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
+ break;
+
+ case ACPI_DMT_ACCWIDTH:
+
+ /* Encoded Access Width */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
+ {
+ Temp8 = ACPI_GAS_WIDTH_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmGasAccessWidth[Temp8]);
+ break;
+
+ case ACPI_DMT_GAS:
+
+ /* Generic Address Structure */
+
+ AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
+ Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
+ sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiOsPrintf ("\n");
+ LastOutputBlankLine = TRUE;
+ break;
+
+ case ACPI_DMT_ASF:
+
+ /* ASF subtable types */
+
+ Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */
+ if (Temp16 > ACPI_ASF_TYPE_RESERVED)
+ {
+ Temp16 = ACPI_ASF_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
+ break;
+
+ case ACPI_DMT_DMAR:
+
+ /* DMAR subtable types */
+
+ Temp16 = ACPI_GET16 (Target);
+ if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
+ {
+ Temp16 = ACPI_DMAR_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
+ AcpiDmDmarSubnames[Temp16]);
+ break;
+
+ case ACPI_DMT_DMAR_SCOPE:
+
+ /* DMAR device scope types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_DMAR_SCOPE_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_DMAR_SCOPE_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmDmarScope[Temp8]);
+ break;
+
+ case ACPI_DMT_EINJACT:
+
+ /* EINJ Action types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
+ {
+ Temp8 = ACPI_EINJ_ACTION_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmEinjActions[Temp8]);
+ break;
+
+ case ACPI_DMT_EINJINST:
+
+ /* EINJ Instruction types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
+ {
+ Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmEinjInstructions[Temp8]);
+ break;
+
+ case ACPI_DMT_ERSTACT:
+
+ /* ERST Action types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_ERST_ACTION_RESERVED)
+ {
+ Temp8 = ACPI_ERST_ACTION_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmErstActions[Temp8]);
+ break;
+
+ case ACPI_DMT_ERSTINST:
+
+ /* ERST Instruction types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
+ {
+ Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmErstInstructions[Temp8]);
+ break;
+
+ case ACPI_DMT_GTDT:
+
+ /* GTDT subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_GTDT_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_GTDT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmGtdtSubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_HEST:
+
+ /* HEST subtable types */
+
+ Temp16 = ACPI_GET16 (Target);
+ if (Temp16 > ACPI_HEST_TYPE_RESERVED)
+ {
+ Temp16 = ACPI_HEST_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
+ AcpiDmHestSubnames[Temp16]);
+ break;
+
+ case ACPI_DMT_HESTNTFY:
+
+ AcpiOsPrintf (STRING_FORMAT,
+ "Hardware Error Notification Structure");
+
+ Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
+ sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiOsPrintf ("\n");
+ LastOutputBlankLine = TRUE;
+ break;
+
+ case ACPI_DMT_HESTNTYP:
+
+ /* HEST Notify types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
+ {
+ Temp8 = ACPI_HEST_NOTIFY_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmHestNotifySubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_IORTMEM:
+
+ AcpiOsPrintf (STRING_FORMAT,
+ "IORT Memory Access Properties");
+
+ Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
+ sizeof (ACPI_IORT_MEMORY_ACCESS), AcpiDmTableInfoIortAcc);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ LastOutputBlankLine = TRUE;
+ break;
+
+ case ACPI_DMT_MADT:
+
+ /* MADT subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_MADT_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_MADT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmMadtSubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_NFIT:
+
+ /* NFIT subtable types */
+
+ Temp16 = ACPI_GET16 (Target);
+ if (Temp16 > ACPI_NFIT_TYPE_RESERVED)
+ {
+ Temp16 = ACPI_NFIT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
+ AcpiDmNfitSubnames[Temp16]);
+ break;
+
+ case ACPI_DMT_PCCT:
+
+ /* PCCT subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_PCCT_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_PCCT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmPcctSubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_PMTT:
+
+ /* PMTT subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_PMTT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmPmttSubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_UNICODE:
+
+ if (ByteLength == 0)
+ {
+ AcpiOsPrintf ("/* Zero-length Data */\n");
+ break;
+ }
+
+ AcpiDmDumpUnicode (Table, CurrentOffset, ByteLength);
+ break;
+
+ case ACPI_DMT_RAW_BUFFER:
+
+ if (ByteLength == 0)
+ {
+ AcpiOsPrintf ("/* Zero-length Data */\n");
+ break;
+ }
+
+ AcpiDmDumpBuffer (Table, CurrentOffset, ByteLength,
+ CurrentOffset, NULL);
+ break;
+
+ case ACPI_DMT_SRAT:
+
+ /* SRAT subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_SRAT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmSratSubnames[Temp8]);
+ break;
+
+ case ACPI_DMT_FADTPM:
+
+ /* FADT Preferred PM Profile names */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_FADT_PM_RESERVED)
+ {
+ Temp8 = ACPI_FADT_PM_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmFadtProfiles[Temp8]);
+ break;
+
+ case ACPI_DMT_IVRS:
+
+ /* IVRS subtable types */
+
+ Temp8 = *Target;
+ switch (Temp8)
+ {
+ case ACPI_IVRS_TYPE_HARDWARE:
+
+ Name = AcpiDmIvrsSubnames[0];
+ break;
+
+ case ACPI_IVRS_TYPE_MEMORY1:
+ case ACPI_IVRS_TYPE_MEMORY2:
+ case ACPI_IVRS_TYPE_MEMORY3:
+
+ Name = AcpiDmIvrsSubnames[1];
+ break;
+
+ default:
+
+ Name = AcpiDmIvrsSubnames[2];
+ break;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
+ break;
+
+ case ACPI_DMT_LPIT:
+
+ /* LPIT subtable types */
+
+ Temp32 = ACPI_GET32 (Target);
+ if (Temp32 > ACPI_LPIT_TYPE_RESERVED)
+ {
+ Temp32 = ACPI_LPIT_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT32_FORMAT, ACPI_GET32 (Target),
+ AcpiDmLpitSubnames[Temp32]);
+ break;
+
+ case ACPI_DMT_EXIT:
+
+ return (AE_OK);
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
+ return (AE_SUPPORT);
+ }
+ }
+
+ if (TableOffset && !SubtableLength)
+ {
+ /*
+ * If this table is not the main table, the subtable must have a
+ * valid length
+ */
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return (AE_BAD_DATA);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckAscii
+ *
+ * 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>.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmCheckAscii (
+ 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/boot/sys/contrib/dev/acpica/common/dmtbdump.c b/usr/src/boot/sys/contrib/dev/acpica/common/dmtbdump.c
new file mode 100644
index 0000000000..50d5d21230
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/dmtbdump.c
@@ -0,0 +1,3630 @@
+/******************************************************************************
+ *
+ * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmtbdump")
+
+
+/* Local prototypes */
+
+static void
+AcpiDmValidateFadtLength (
+ UINT32 Revision,
+ UINT32 Length);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpBuffer
+ *
+ * PARAMETERS: Table - ACPI Table or subtable
+ * BufferOffset - Offset of buffer from Table above
+ * Length - Length of the buffer
+ * AbsoluteOffset - Offset of buffer in the main ACPI table
+ * Header - Name of the buffer field (printed on the
+ * first line only.)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of an arbitrary length data buffer (in the
+ * disassembler output format.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpBuffer (
+ void *Table,
+ UINT32 BufferOffset,
+ UINT32 Length,
+ UINT32 AbsoluteOffset,
+ char *Header)
+{
+ UINT8 *Buffer;
+ UINT32 i;
+
+
+ if (!Length)
+ {
+ return;
+ }
+
+ Buffer = ACPI_CAST_PTR (UINT8, Table) + BufferOffset;
+ i = 0;
+
+ while (i < Length)
+ {
+ if (!(i % 16))
+ {
+ /* Insert a backslash - line continuation character */
+
+ if (Length > 16)
+ {
+ AcpiOsPrintf ("\\\n ");
+ }
+ }
+
+ AcpiOsPrintf ("%.02X ", *Buffer);
+ i++;
+ Buffer++;
+ AbsoluteOffset++;
+ }
+
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpUnicode
+ *
+ * PARAMETERS: Table - ACPI Table or subtable
+ * BufferOffset - Offset of buffer from Table above
+ * ByteLength - Length of the buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate and dump the contents of a buffer that contains
+ * unicode data. The output is a standard ASCII string. If it
+ * appears that the data is not unicode, the buffer is dumped
+ * as hex characters.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpUnicode (
+ void *Table,
+ UINT32 BufferOffset,
+ UINT32 ByteLength)
+{
+ UINT8 *Buffer;
+ UINT32 Length;
+ UINT32 i;
+
+
+ Buffer = ((UINT8 *) Table) + BufferOffset;
+ Length = ByteLength - 2; /* Last two bytes are the null terminator */
+
+ /* Ensure all low bytes are entirely printable ASCII */
+
+ for (i = 0; i < Length; i += 2)
+ {
+ if (!isprint (Buffer[i]))
+ {
+ goto DumpRawBuffer;
+ }
+ }
+
+ /* Ensure all high bytes are zero */
+
+ for (i = 1; i < Length; i += 2)
+ {
+ if (Buffer[i])
+ {
+ goto DumpRawBuffer;
+ }
+ }
+
+ /* Dump the buffer as a normal string */
+
+ AcpiOsPrintf ("\"");
+ for (i = 0; i < Length; i += 2)
+ {
+ AcpiOsPrintf ("%c", Buffer[i]);
+ }
+ AcpiOsPrintf ("\"\n");
+ return;
+
+DumpRawBuffer:
+ AcpiDmDumpBuffer (Table, BufferOffset, ByteLength,
+ BufferOffset, NULL);
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpRsdp
+ *
+ * PARAMETERS: Table - A RSDP
+ *
+ * RETURN: Length of the table (there is not always a length field,
+ * use revision or length if available (ACPI 2.0+))
+ *
+ * DESCRIPTION: Format the contents of a RSDP
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmDumpRsdp (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_TABLE_RSDP *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table);
+ UINT32 Length = sizeof (ACPI_RSDP_COMMON);
+ UINT8 Checksum;
+ ACPI_STATUS Status;
+
+
+ /* Dump the common ACPI 1.0 portion */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Length);
+ }
+
+ /* Validate the first checksum */
+
+ Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON),
+ Rsdp->Checksum);
+ if (Checksum != Rsdp->Checksum)
+ {
+ AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n",
+ Checksum);
+ }
+
+ /* The RSDP for ACPI 2.0+ contains more data and has a Length field */
+
+ if (Rsdp->Revision > 0)
+ {
+ Length = Rsdp->Length;
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Length);
+ }
+
+ /* Validate the extended checksum over entire RSDP */
+
+ Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP),
+ Rsdp->ExtendedChecksum);
+ if (Checksum != Rsdp->ExtendedChecksum)
+ {
+ AcpiOsPrintf (
+ "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n",
+ Checksum);
+ }
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpRsdt
+ *
+ * PARAMETERS: Table - A RSDT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a RSDT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpRsdt (
+ ACPI_TABLE_HEADER *Table)
+{
+ UINT32 *Array;
+ UINT32 Entries;
+ UINT32 Offset;
+ UINT32 i;
+
+
+ /* Point to start of table pointer array */
+
+ Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry;
+ Offset = sizeof (ACPI_TABLE_HEADER);
+
+ /* RSDT uses 32-bit pointers */
+
+ Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32);
+
+ for (i = 0; i < Entries; i++)
+ {
+ AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i);
+ AcpiOsPrintf ("%8.8X\n", Array[i]);
+ Offset += sizeof (UINT32);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpXsdt
+ *
+ * PARAMETERS: Table - A XSDT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a XSDT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpXsdt (
+ ACPI_TABLE_HEADER *Table)
+{
+ UINT64 *Array;
+ UINT32 Entries;
+ UINT32 Offset;
+ UINT32 i;
+
+
+ /* Point to start of table pointer array */
+
+ Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry;
+ Offset = sizeof (ACPI_TABLE_HEADER);
+
+ /* XSDT uses 64-bit pointers */
+
+ Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64);
+
+ for (i = 0; i < Entries; i++)
+ {
+ AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i);
+ AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i]));
+ Offset += sizeof (UINT64);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpFadt
+ *
+ * PARAMETERS: Table - A FADT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a FADT
+ *
+ * NOTE: We cannot depend on the FADT version to indicate the actual
+ * contents of the FADT because of BIOS bugs. The table length
+ * is the only reliable indicator.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpFadt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+
+
+ /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt1);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */
+
+ if ((Table->Length > ACPI_FADT_V1_SIZE) &&
+ (Table->Length <= ACPI_FADT_V2_SIZE))
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */
+
+ else if (Table->Length > ACPI_FADT_V2_SIZE)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Check for FADT revision 5 fields and up (ACPI 5.0+) */
+
+ if (Table->Length > ACPI_FADT_V3_SIZE)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt5);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Check for FADT revision 6 fields and up (ACPI 6.0+) */
+
+ if (Table->Length > ACPI_FADT_V3_SIZE)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt6);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ }
+
+ /* Validate various fields in the FADT, including length */
+
+ AcpiTbCreateLocalFadt (Table, Table->Length);
+
+ /* Validate FADT length against the revision */
+
+ AcpiDmValidateFadtLength (Table->Revision, Table->Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmValidateFadtLength
+ *
+ * PARAMETERS: Revision - FADT revision (Header->Revision)
+ * Length - FADT length (Header->Length
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check the FADT revision against the expected table length for
+ * that revision. Issue a warning if the length is not what was
+ * expected. This seems to be such a common BIOS bug that the
+ * FADT revision has been rendered virtually meaningless.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmValidateFadtLength (
+ UINT32 Revision,
+ UINT32 Length)
+{
+ UINT32 ExpectedLength;
+
+
+ switch (Revision)
+ {
+ case 0:
+
+ AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n");
+ return;
+
+ case 1:
+
+ ExpectedLength = ACPI_FADT_V1_SIZE;
+ break;
+
+ case 2:
+
+ ExpectedLength = ACPI_FADT_V2_SIZE;
+ break;
+
+ case 3:
+ case 4:
+
+ ExpectedLength = ACPI_FADT_V3_SIZE;
+ break;
+
+ case 5:
+
+ ExpectedLength = ACPI_FADT_V5_SIZE;
+ break;
+
+ default:
+
+ return;
+ }
+
+ if (Length == ExpectedLength)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (
+ "\n// ACPI Warning: FADT revision %X does not match length: found %X expected %X\n",
+ Revision, Length, ExpectedLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpAsf
+ *
+ * PARAMETERS: Table - A ASF table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a ASF table
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpAsf (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_HEADER);
+ ACPI_ASF_INFO *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_DMTABLE_INFO *DataInfoTable = NULL;
+ UINT8 *DataTable = NULL;
+ UINT32 DataCount = 0;
+ UINT32 DataLength = 0;
+ UINT32 DataOffset = 0;
+ UINT32 i;
+ UINT8 Type;
+
+
+ /* No main table, only subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Header.Length, AcpiDmTableInfoAsfHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* The actual type is the lower 7 bits of Type */
+
+ Type = (UINT8) (SubTable->Header.Type & 0x7F);
+
+ switch (Type)
+ {
+ case ACPI_ASF_TYPE_INFO:
+
+ InfoTable = AcpiDmTableInfoAsf0;
+ break;
+
+ case ACPI_ASF_TYPE_ALERT:
+
+ InfoTable = AcpiDmTableInfoAsf1;
+ DataInfoTable = AcpiDmTableInfoAsf1a;
+ DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT));
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts;
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength;
+ DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
+ break;
+
+ case ACPI_ASF_TYPE_CONTROL:
+
+ InfoTable = AcpiDmTableInfoAsf2;
+ DataInfoTable = AcpiDmTableInfoAsf2a;
+ DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE));
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls;
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength;
+ DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
+ break;
+
+ case ACPI_ASF_TYPE_BOOT:
+
+ InfoTable = AcpiDmTableInfoAsf3;
+ break;
+
+ case ACPI_ASF_TYPE_ADDRESS:
+
+ InfoTable = AcpiDmTableInfoAsf4;
+ DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS));
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices;
+ DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n", SubTable->Header.Type);
+ return;
+ }
+
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Header.Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Dump variable-length extra data */
+
+ switch (Type)
+ {
+ case ACPI_ASF_TYPE_ALERT:
+ case ACPI_ASF_TYPE_CONTROL:
+
+ for (i = 0; i < DataCount; i++)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, DataOffset,
+ DataTable, DataLength, DataInfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
+ DataOffset += DataLength;
+ }
+ break;
+
+ case ACPI_ASF_TYPE_ADDRESS:
+
+ for (i = 0; i < DataLength; i++)
+ {
+ if (!(i % 16))
+ {
+ AcpiDmLineHeader (DataOffset, 1, "Addresses");
+ }
+
+ AcpiOsPrintf ("%2.2X ", *DataTable);
+ DataTable++;
+ DataOffset++;
+ if (DataOffset > Table->Length)
+ {
+ AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure! (ASF! table)\n");
+ return;
+ }
+ }
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+
+ /* Point to next subtable */
+
+ if (!SubTable->Header.Length)
+ {
+ AcpiOsPrintf ("Invalid zero subtable header length\n");
+ return;
+ }
+
+ Offset += SubTable->Header.Length;
+ SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, SubTable->Header.Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpCpep
+ *
+ * PARAMETERS: Table - A CPEP table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a CPEP. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpCpep (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_CPEP_POLLING *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_CPEP);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Header.Length, AcpiDmTableInfoCpep0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += SubTable->Header.Length;
+ SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable,
+ SubTable->Header.Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpCsrt
+ *
+ * PARAMETERS: Table - A CSRT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a CSRT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpCsrt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_CSRT_GROUP *SubTable;
+ ACPI_CSRT_SHARED_INFO *SharedInfoTable;
+ ACPI_CSRT_DESCRIPTOR *SubSubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_CSRT);
+ UINT32 SubOffset;
+ UINT32 SubSubOffset;
+ UINT32 InfoLength;
+
+
+ /* The main table only contains the ACPI header, thus already handled */
+
+ /* Subtables (Resource Groups) */
+
+ SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Resource group subtable */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoCsrt0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Shared info subtable (One per resource group) */
+
+ SubOffset = sizeof (ACPI_CSRT_GROUP);
+ SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
+ Offset + SubOffset);
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
+ sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubOffset += SubTable->SharedInfoLength;
+
+ /* Sub-Subtables (Resource Descriptors) */
+
+ SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
+ Offset + SubOffset);
+
+ while ((SubOffset < SubTable->Length) &&
+ ((Offset + SubOffset) < Table->Length))
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubTable,
+ SubSubTable->Length, AcpiDmTableInfoCsrt2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
+
+ /* Resource-specific info buffer */
+
+ InfoLength = SubSubTable->Length - SubSubOffset;
+ if (InfoLength)
+ {
+ Status = AcpiDmDumpTable (Length,
+ Offset + SubOffset + SubSubOffset, Table,
+ InfoLength, AcpiDmTableInfoCsrt2a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ SubSubOffset += InfoLength;
+ }
+
+ /* Point to next sub-subtable */
+
+ SubOffset += SubSubTable->Length;
+ SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubTable,
+ SubSubTable->Length);
+ }
+
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, SubTable,
+ SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpDbg2
+ *
+ * PARAMETERS: Table - A DBG2 table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a DBG2. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpDbg2 (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_DBG2_DEVICE *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_DBG2);
+ UINT32 i;
+ UINT32 ArrayOffset;
+ UINT32 AbsoluteOffset;
+ UINT8 *Array;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoDbg2Device);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Dump the BaseAddress array */
+
+ for (i = 0; i < SubTable->RegisterCount; i++)
+ {
+ ArrayOffset = SubTable->BaseAddressOffset +
+ (sizeof (ACPI_GENERIC_ADDRESS) * i);
+ AbsoluteOffset = Offset + ArrayOffset;
+ Array = (UINT8 *) SubTable + ArrayOffset;
+
+ Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
+ SubTable->Length, AcpiDmTableInfoDbg2Addr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Dump the AddressSize array */
+
+ for (i = 0; i < SubTable->RegisterCount; i++)
+ {
+ ArrayOffset = SubTable->AddressSizeOffset +
+ (sizeof (UINT32) * i);
+ AbsoluteOffset = Offset + ArrayOffset;
+ Array = (UINT8 *) SubTable + ArrayOffset;
+
+ Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
+ SubTable->Length, AcpiDmTableInfoDbg2Size);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Dump the Namestring (required) */
+
+ AcpiOsPrintf ("\n");
+ ArrayOffset = SubTable->NamepathOffset;
+ AbsoluteOffset = Offset + ArrayOffset;
+ Array = (UINT8 *) SubTable + ArrayOffset;
+
+ Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
+ SubTable->Length, AcpiDmTableInfoDbg2Name);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Dump the OemData (optional) */
+
+ if (SubTable->OemDataOffset)
+ {
+ Status = AcpiDmDumpTable (Length, Offset + SubTable->OemDataOffset,
+ Table, SubTable->OemDataLength,
+ AcpiDmTableInfoDbg2OemData);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, SubTable,
+ SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpDmar
+ *
+ * PARAMETERS: Table - A DMAR table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a DMAR. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpDmar (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_DMAR_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_DMAR);
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_DMAR_DEVICE_SCOPE *ScopeTable;
+ UINT32 ScopeOffset;
+ UINT8 *PciPath;
+ UINT32 PathOffset;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoDmarHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ AcpiOsPrintf ("\n");
+
+ switch (SubTable->Type)
+ {
+ case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+
+ InfoTable = AcpiDmTableInfoDmar0;
+ ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
+ break;
+
+ case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+
+ InfoTable = AcpiDmTableInfoDmar1;
+ ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
+ break;
+
+ case ACPI_DMAR_TYPE_ROOT_ATS:
+
+ InfoTable = AcpiDmTableInfoDmar2;
+ ScopeOffset = sizeof (ACPI_DMAR_ATSR);
+ break;
+
+ case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoDmar3;
+ ScopeOffset = sizeof (ACPI_DMAR_RHSA);
+ break;
+
+ case ACPI_DMAR_TYPE_NAMESPACE:
+
+ InfoTable = AcpiDmTableInfoDmar4;
+ ScopeOffset = sizeof (ACPI_DMAR_ANDD);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n", SubTable->Type);
+ return;
+ }
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /*
+ * Dump the optional device scope entries
+ */
+ if ((SubTable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
+ (SubTable->Type == ACPI_DMAR_TYPE_NAMESPACE))
+ {
+ /* These types do not support device scopes */
+
+ goto NextSubtable;
+ }
+
+ ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset);
+ while (ScopeOffset < SubTable->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
+ ScopeTable->Length, AcpiDmTableInfoDmarScope);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ AcpiOsPrintf ("\n");
+
+ /* Dump the PCI Path entries for this device scope */
+
+ PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
+
+ PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
+ sizeof (ACPI_DMAR_DEVICE_SCOPE));
+
+ while (PathOffset < ScopeTable->Length)
+ {
+ AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2, "PCI Path");
+ AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
+
+ /* Point to next PCI Path entry */
+
+ PathOffset += 2;
+ PciPath += 2;
+ AcpiOsPrintf ("\n");
+ }
+
+ /* Point to next device scope entry */
+
+ ScopeOffset += ScopeTable->Length;
+ ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
+ ScopeTable, ScopeTable->Length);
+ }
+
+NextSubtable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpDrtm
+ *
+ * PARAMETERS: Table - A DRTM table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a DRTM.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpDrtm (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset;
+ ACPI_DRTM_VTABLE_LIST *DrtmVtl;
+ ACPI_DRTM_RESOURCE_LIST *DrtmRl;
+ ACPI_DRTM_DPS_ID *DrtmDps;
+ UINT32 Count;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
+ AcpiDmTableInfoDrtm);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Offset = sizeof (ACPI_TABLE_DRTM);
+
+ /* Sub-tables */
+
+ /* Dump ValidatedTable length */
+
+ DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset,
+ DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
+ AcpiDmTableInfoDrtm0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
+
+ /* Dump Validated table addresses */
+
+ Count = 0;
+ while ((Offset < Table->Length) &&
+ (DrtmVtl->ValidatedTableCount > Count))
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset,
+ ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
+ AcpiDmTableInfoDrtm0a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ Offset += sizeof (UINT64);
+ Count++;
+ }
+
+ /* Dump ResourceList length */
+
+ DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset,
+ DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
+ AcpiDmTableInfoDrtm1);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
+
+ /* Dump the Resource List */
+
+ Count = 0;
+ while ((Offset < Table->Length) &&
+ (DrtmRl->ResourceCount > Count))
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset,
+ ACPI_ADD_PTR (void, Table, Offset),
+ sizeof (ACPI_DRTM_RESOURCE),
+ AcpiDmTableInfoDrtm1a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Offset += sizeof (ACPI_DRTM_RESOURCE);
+ Count++;
+ }
+
+ /* Dump DPS */
+
+ DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
+ AcpiOsPrintf ("\n");
+ (void) AcpiDmDumpTable (Table->Length, Offset,
+ DrtmDps, sizeof (ACPI_DRTM_DPS_ID),
+ AcpiDmTableInfoDrtm2);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpEinj
+ *
+ * PARAMETERS: Table - A EINJ table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a EINJ. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpEinj (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_WHEA_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_EINJ);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable (each subtable is of fixed length) */
+
+ Offset += sizeof (ACPI_WHEA_HEADER);
+ SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
+ sizeof (ACPI_WHEA_HEADER));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpErst
+ *
+ * PARAMETERS: Table - A ERST table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a ERST. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpErst (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_WHEA_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_ERST);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable (each subtable is of fixed length) */
+
+ Offset += sizeof (ACPI_WHEA_HEADER);
+ SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
+ sizeof (ACPI_WHEA_HEADER));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpFpdt
+ *
+ * PARAMETERS: Table - A FPDT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a FPDT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpFpdt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_FPDT_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_FPDT);
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ /* There is no main table (other than the standard ACPI header) */
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoFpdtHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_FPDT_TYPE_BOOT:
+
+ InfoTable = AcpiDmTableInfoFpdt0;
+ break;
+
+ case ACPI_FPDT_TYPE_S3PERF:
+
+ InfoTable = AcpiDmTableInfoFpdt1;
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n", SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpGtdt
+ *
+ * PARAMETERS: Table - A GTDT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a GTDT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpGtdt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_GTDT_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_GTDT);
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 SubTableLength;
+ UINT32 GtCount;
+ ACPI_GTDT_TIMER_ENTRY *GtxTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoGtdtHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ GtCount = 0;
+ switch (SubTable->Type)
+ {
+ case ACPI_GTDT_TYPE_TIMER_BLOCK:
+
+ SubTableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
+ GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
+ SubTable))->TimerCount;
+
+ InfoTable = AcpiDmTableInfoGtdt0;
+ break;
+
+ case ACPI_GTDT_TYPE_WATCHDOG:
+
+ SubTableLength = sizeof (ACPI_GTDT_WATCHDOG);
+
+ InfoTable = AcpiDmTableInfoGtdt1;
+ break;
+
+ default:
+
+ /* Cannot continue on unknown type - no length */
+
+ AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n", SubTable->Type);
+ return;
+ }
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to end of current subtable (each subtable above is of fixed length) */
+
+ Offset += SubTableLength;
+
+ /* If there are any Gt Timer Blocks from above, dump them now */
+
+ if (GtCount)
+ {
+ GtxTable = ACPI_ADD_PTR (ACPI_GTDT_TIMER_ENTRY, SubTable, SubTableLength);
+ SubTableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
+
+ while (GtCount)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, GtxTable,
+ sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
+ GtxTable++;
+ GtCount--;
+ }
+ }
+
+ /* Point to next subtable */
+
+ SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, SubTable, SubTableLength);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpHest
+ *
+ * PARAMETERS: Table - A HEST table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a HEST. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpHest (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_HEST_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_HEST);
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 SubTableLength;
+ UINT32 BankCount;
+ ACPI_HEST_IA_ERROR_BANK *BankTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ BankCount = 0;
+ switch (SubTable->Type)
+ {
+ case ACPI_HEST_TYPE_IA32_CHECK:
+
+ InfoTable = AcpiDmTableInfoHest0;
+ SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
+ BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
+ SubTable))->NumHardwareBanks;
+ break;
+
+ case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
+
+ InfoTable = AcpiDmTableInfoHest1;
+ SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED);
+ BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
+ SubTable))->NumHardwareBanks;
+ break;
+
+ case ACPI_HEST_TYPE_IA32_NMI:
+
+ InfoTable = AcpiDmTableInfoHest2;
+ SubTableLength = sizeof (ACPI_HEST_IA_NMI);
+ break;
+
+ case ACPI_HEST_TYPE_AER_ROOT_PORT:
+
+ InfoTable = AcpiDmTableInfoHest6;
+ SubTableLength = sizeof (ACPI_HEST_AER_ROOT);
+ break;
+
+ case ACPI_HEST_TYPE_AER_ENDPOINT:
+
+ InfoTable = AcpiDmTableInfoHest7;
+ SubTableLength = sizeof (ACPI_HEST_AER);
+ break;
+
+ case ACPI_HEST_TYPE_AER_BRIDGE:
+
+ InfoTable = AcpiDmTableInfoHest8;
+ SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE);
+ break;
+
+ case ACPI_HEST_TYPE_GENERIC_ERROR:
+
+ InfoTable = AcpiDmTableInfoHest9;
+ SubTableLength = sizeof (ACPI_HEST_GENERIC);
+ break;
+
+ default:
+
+ /* Cannot continue on unknown type - no length */
+
+ AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n", SubTable->Type);
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTableLength, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to end of current subtable (each subtable above is of fixed length) */
+
+ Offset += SubTableLength;
+
+ /* If there are any (fixed-length) Error Banks from above, dump them now */
+
+ if (BankCount)
+ {
+ BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength);
+ SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
+
+ while (BankCount)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, BankTable,
+ sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
+ BankTable++;
+ BankCount--;
+ }
+ }
+
+ /* Point to next subtable */
+
+ SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpIort
+ *
+ * PARAMETERS: Table - A IORT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a IORT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpIort (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_IORT *Iort;
+ ACPI_IORT_NODE *IortNode;
+ ACPI_IORT_ITS_GROUP *IortItsGroup = NULL;
+ ACPI_IORT_SMMU *IortSmmu = NULL;
+ UINT32 Offset;
+ UINT32 NodeOffset;
+ UINT32 Length;
+ ACPI_DMTABLE_INFO *InfoTable;
+ char *String;
+ UINT32 i;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
+ Offset = sizeof (ACPI_TABLE_IORT);
+
+ /* Dump the OptionalPadding (optional) */
+
+ if (Iort->NodeOffset > Offset)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset, Table,
+ Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ Offset = Iort->NodeOffset;
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
+ AcpiOsPrintf ("\n");
+ Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
+ Status = AcpiDmDumpTable (Table->Length, Offset,
+ IortNode, Length, AcpiDmTableInfoIortHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ NodeOffset = Length;
+
+ switch (IortNode->Type)
+ {
+ case ACPI_IORT_NODE_ITS_GROUP:
+
+ InfoTable = AcpiDmTableInfoIort0;
+ Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
+ IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
+ break;
+
+ case ACPI_IORT_NODE_NAMED_COMPONENT:
+
+ InfoTable = AcpiDmTableInfoIort1;
+ Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
+ String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
+ Length += strlen (String) + 1;
+ break;
+
+ case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+
+ InfoTable = AcpiDmTableInfoIort2;
+ Length = IortNode->Length - NodeOffset;
+ break;
+
+ case ACPI_IORT_NODE_SMMU:
+
+ InfoTable = AcpiDmTableInfoIort3;
+ Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
+ IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
+ IortNode->Type);
+
+ /* Attempt to continue */
+
+ if (!IortNode->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length IORT node\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ /* Dump the node subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ NodeOffset += Length;
+
+ /* Dump the node specific data */
+
+ switch (IortNode->Type)
+ {
+ case ACPI_IORT_NODE_ITS_GROUP:
+
+ /* Validate IortItsGroup to avoid compiler warnings */
+
+ if (IortItsGroup)
+ {
+ for (i = 0; i < IortItsGroup->ItsCount; i++)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ 4, AcpiDmTableInfoIort0a);
+ NodeOffset += 4;
+ }
+ }
+ break;
+
+ case ACPI_IORT_NODE_NAMED_COMPONENT:
+
+ /* Dump the Padding (optional) */
+
+ if (IortNode->Length > NodeOffset)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ Table, IortNode->Length - NodeOffset,
+ AcpiDmTableInfoIort1a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ break;
+
+ case ACPI_IORT_NODE_SMMU:
+
+ AcpiOsPrintf ("\n");
+
+ /* Validate IortSmmu to avoid compiler warnings */
+
+ if (IortSmmu)
+ {
+ Length = 2 * sizeof (UINT64);
+ NodeOffset = IortSmmu->GlobalInterruptOffset;
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ Length, AcpiDmTableInfoIort3a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ NodeOffset = IortSmmu->ContextInterruptOffset;
+ for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ 8, AcpiDmTableInfoIort3b);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ NodeOffset += 8;
+ }
+
+ NodeOffset = IortSmmu->PmuInterruptOffset;
+ for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ 8, AcpiDmTableInfoIort3c);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ NodeOffset += 8;
+ }
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Dump the ID mappings */
+
+ NodeOffset = IortNode->MappingOffset;
+ for (i = 0; i < IortNode->MappingCount; i++)
+ {
+ AcpiOsPrintf ("\n");
+ Length = sizeof (ACPI_IORT_ID_MAPPING);
+ Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
+ ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
+ Length, AcpiDmTableInfoIortMap);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ NodeOffset += Length;
+ }
+
+NextSubTable:
+ /* Point to next node subtable */
+
+ Offset += IortNode->Length;
+ IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, IortNode->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpIvrs
+ *
+ * PARAMETERS: Table - A IVRS table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a IVRS
+ *
+ ******************************************************************************/
+
+static UINT8 EntrySizes[] = {4,8,16,32};
+
+void
+AcpiDmDumpIvrs (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_IVRS);
+ UINT32 EntryOffset;
+ UINT32 EntryLength;
+ UINT32 EntryType;
+ ACPI_IVRS_DE_HEADER *DeviceEntry;
+ ACPI_IVRS_HEADER *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoIvrsHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_IVRS_TYPE_HARDWARE:
+
+ InfoTable = AcpiDmTableInfoIvrs0;
+ break;
+
+ case ACPI_IVRS_TYPE_MEMORY1:
+ case ACPI_IVRS_TYPE_MEMORY2:
+ case ACPI_IVRS_TYPE_MEMORY3:
+
+ InfoTable = AcpiDmTableInfoIvrs1;
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
+ SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ /* Dump the subtable */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* The hardware subtable can contain multiple device entries */
+
+ if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE)
+ {
+ EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
+ DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable,
+ sizeof (ACPI_IVRS_HARDWARE));
+
+ while (EntryOffset < (Offset + SubTable->Length))
+ {
+ AcpiOsPrintf ("\n");
+ /*
+ * Upper 2 bits of Type encode the length of the device entry
+ *
+ * 00 = 4 byte
+ * 01 = 8 byte
+ * 10 = 16 byte - currently no entries defined
+ * 11 = 32 byte - currently no entries defined
+ */
+ EntryType = DeviceEntry->Type;
+ EntryLength = EntrySizes [EntryType >> 6];
+
+ switch (EntryType)
+ {
+ /* 4-byte device entries */
+
+ case ACPI_IVRS_TYPE_PAD4:
+ case ACPI_IVRS_TYPE_ALL:
+ case ACPI_IVRS_TYPE_SELECT:
+ case ACPI_IVRS_TYPE_START:
+ case ACPI_IVRS_TYPE_END:
+
+ InfoTable = AcpiDmTableInfoIvrs4;
+ break;
+
+ /* 8-byte entries, type A */
+
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
+ case ACPI_IVRS_TYPE_ALIAS_START:
+
+ InfoTable = AcpiDmTableInfoIvrs8a;
+ break;
+
+ /* 8-byte entries, type B */
+
+ case ACPI_IVRS_TYPE_PAD8:
+ case ACPI_IVRS_TYPE_EXT_SELECT:
+ case ACPI_IVRS_TYPE_EXT_START:
+
+ InfoTable = AcpiDmTableInfoIvrs8b;
+ break;
+
+ /* 8-byte entries, type C */
+
+ case ACPI_IVRS_TYPE_SPECIAL:
+
+ InfoTable = AcpiDmTableInfoIvrs8c;
+ break;
+
+ default:
+ InfoTable = AcpiDmTableInfoIvrs4;
+ AcpiOsPrintf (
+ "\n**** Unknown IVRS device entry type/length: "
+ "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
+ EntryType, EntryLength, EntryOffset);
+ break;
+ }
+
+ /* Dump the Device Entry */
+
+ Status = AcpiDmDumpTable (Table->Length, EntryOffset,
+ DeviceEntry, EntryLength, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ EntryOffset += EntryLength;
+ DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
+ EntryLength);
+ }
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpLpit
+ *
+ * PARAMETERS: Table - A LPIT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a LPIT. This table type consists
+ * of an open-ended number of subtables. Note: There are no
+ * entries in the main table. An LPIT consists of the table
+ * header and then subtables only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpLpit (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_LPIT_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_LPIT);
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 SubTableLength;
+
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_LPIT_TYPE_NATIVE_CSTATE:
+
+ InfoTable = AcpiDmTableInfoLpit0;
+ SubTableLength = sizeof (ACPI_LPIT_NATIVE);
+ break;
+
+ default:
+
+ /* Cannot continue on unknown type - no length */
+
+ AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n", SubTable->Type);
+ return;
+ }
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTableLength, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ AcpiOsPrintf ("\n");
+
+ /* Point to next subtable */
+
+ Offset += SubTableLength;
+ SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, SubTable, SubTableLength);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMadt
+ *
+ * PARAMETERS: Table - A MADT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a MADT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMadt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_SUBTABLE_HEADER *SubTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_MADT);
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoMadtHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_MADT_TYPE_LOCAL_APIC:
+
+ InfoTable = AcpiDmTableInfoMadt0;
+ break;
+
+ case ACPI_MADT_TYPE_IO_APIC:
+
+ InfoTable = AcpiDmTableInfoMadt1;
+ break;
+
+ case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
+
+ InfoTable = AcpiDmTableInfoMadt2;
+ break;
+
+ case ACPI_MADT_TYPE_NMI_SOURCE:
+
+ InfoTable = AcpiDmTableInfoMadt3;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+
+ InfoTable = AcpiDmTableInfoMadt4;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
+
+ InfoTable = AcpiDmTableInfoMadt5;
+ break;
+
+ case ACPI_MADT_TYPE_IO_SAPIC:
+
+ InfoTable = AcpiDmTableInfoMadt6;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_SAPIC:
+
+ InfoTable = AcpiDmTableInfoMadt7;
+ break;
+
+ case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
+
+ InfoTable = AcpiDmTableInfoMadt8;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+
+ InfoTable = AcpiDmTableInfoMadt9;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+
+ InfoTable = AcpiDmTableInfoMadt10;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+
+ InfoTable = AcpiDmTableInfoMadt11;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+
+ InfoTable = AcpiDmTableInfoMadt12;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+
+ InfoTable = AcpiDmTableInfoMadt13;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+
+ InfoTable = AcpiDmTableInfoMadt14;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
+
+ InfoTable = AcpiDmTableInfoMadt15;
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n", SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMcfg
+ *
+ * PARAMETERS: Table - A MCFG Table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a MCFG table
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMcfg (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_MCFG);
+ ACPI_MCFG_ALLOCATION *SubTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
+ {
+ AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
+ sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable (each subtable is of fixed length) */
+
+ Offset += sizeof (ACPI_MCFG_ALLOCATION);
+ SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable,
+ sizeof (ACPI_MCFG_ALLOCATION));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMpst
+ *
+ * PARAMETERS: Table - A MPST Table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a MPST table
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMpst (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_MPST);
+ ACPI_MPST_POWER_NODE *SubTable0;
+ ACPI_MPST_POWER_STATE *SubTable0A;
+ ACPI_MPST_COMPONENT *SubTable0B;
+ ACPI_MPST_DATA_HDR *SubTable1;
+ ACPI_MPST_POWER_DATA *SubTable2;
+ UINT16 SubtableCount;
+ UINT32 PowerStateCount;
+ UINT32 ComponentCount;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtable: Memory Power Node(s) */
+
+ SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
+ SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
+
+ while ((Offset < Table->Length) && SubtableCount)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0,
+ sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Extract the sub-subtable counts */
+
+ PowerStateCount = SubTable0->NumPowerStates;
+ ComponentCount = SubTable0->NumPhysicalComponents;
+ Offset += sizeof (ACPI_MPST_POWER_NODE);
+
+ /* Sub-subtables - Memory Power State Structure(s) */
+
+ SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0,
+ sizeof (ACPI_MPST_POWER_NODE));
+
+ while (PowerStateCount)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A,
+ sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubTable0A++;
+ PowerStateCount--;
+ Offset += sizeof (ACPI_MPST_POWER_STATE);
+ }
+
+ /* Sub-subtables - Physical Component ID Structure(s) */
+
+ SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A);
+
+ if (ComponentCount)
+ {
+ AcpiOsPrintf ("\n");
+ }
+
+ while (ComponentCount)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B,
+ sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubTable0B++;
+ ComponentCount--;
+ Offset += sizeof (ACPI_MPST_COMPONENT);
+ }
+
+ /* Point to next Memory Power Node subtable */
+
+ SubtableCount--;
+ SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0,
+ sizeof (ACPI_MPST_POWER_NODE) +
+ (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) +
+ (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents));
+ }
+
+ /* Subtable: Count of Memory Power State Characteristic structures */
+
+ AcpiOsPrintf ("\n");
+ SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0);
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1,
+ sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubtableCount = SubTable1->CharacteristicsCount;
+ Offset += sizeof (ACPI_MPST_DATA_HDR);
+
+ /* Subtable: Memory Power State Characteristics structure(s) */
+
+ SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, sizeof (ACPI_MPST_DATA_HDR));
+
+ while ((Offset < Table->Length) && SubtableCount)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2,
+ sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ SubTable2++;
+ SubtableCount--;
+ Offset += sizeof (ACPI_MPST_POWER_DATA);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMsct
+ *
+ * PARAMETERS: Table - A MSCT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a MSCT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMsct (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_MSCT);
+ ACPI_MSCT_PROXIMITY *SubTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += sizeof (ACPI_MSCT_PROXIMITY);
+ SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMtmr
+ *
+ * PARAMETERS: Table - A MTMR table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a MTMR
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMtmr (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_MTMR);
+ ACPI_MTMR_ENTRY *SubTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMtmr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += sizeof (ACPI_MTMR_ENTRY);
+ SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, SubTable, sizeof (ACPI_MTMR_ENTRY));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpNfit
+ *
+ * PARAMETERS: Table - A NFIT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of an NFIT.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpNfit (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_NFIT);
+ UINT32 FieldOffset = 0;
+ UINT32 Length;
+ ACPI_NFIT_HEADER *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_NFIT_INTERLEAVE *Interleave = NULL;
+ ACPI_NFIT_SMBIOS *SmbiosInfo = NULL;
+ ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
+ UINT32 i;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* NFIT subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoNfitHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
+
+ InfoTable = AcpiDmTableInfoNfit0;
+ break;
+
+ case ACPI_NFIT_TYPE_MEMORY_MAP:
+
+ InfoTable = AcpiDmTableInfoNfit1;
+ break;
+
+ case ACPI_NFIT_TYPE_INTERLEAVE:
+
+ /* Has a variable number of 32-bit values at the end */
+
+ InfoTable = AcpiDmTableInfoNfit2;
+ Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, SubTable);
+ FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
+ break;
+
+ case ACPI_NFIT_TYPE_SMBIOS:
+
+ SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, SubTable);
+ InfoTable = AcpiDmTableInfoNfit3;
+ break;
+
+ case ACPI_NFIT_TYPE_CONTROL_REGION:
+
+ InfoTable = AcpiDmTableInfoNfit4;
+ break;
+
+ case ACPI_NFIT_TYPE_DATA_REGION:
+
+ InfoTable = AcpiDmTableInfoNfit5;
+ break;
+
+ case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
+
+ /* Has a variable number of 64-bit addresses at the end */
+
+ InfoTable = AcpiDmTableInfoNfit6;
+ Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, SubTable);
+ FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
+ break;
+
+ default:
+ AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n", SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Per-subtable variable-length fields */
+
+ switch (SubTable->Type)
+ {
+ case ACPI_NFIT_TYPE_INTERLEAVE:
+
+ for (i = 0; i < Interleave->LineCount; i++)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
+ &Interleave->LineOffset[i],
+ sizeof (UINT32), AcpiDmTableInfoNfit2a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ FieldOffset += sizeof (UINT32);
+ }
+ break;
+
+ case ACPI_NFIT_TYPE_SMBIOS:
+
+ Length = SubTable->Length - sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
+ if (Length)
+ {
+ Status = AcpiDmDumpTable (Table->Length,
+ sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
+ SmbiosInfo,
+ Length, AcpiDmTableInfoNfit3a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ break;
+
+ case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
+
+ for (i = 0; i < Hint->HintCount; i++)
+ {
+ Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
+ &Hint->HintAddress[i],
+ sizeof (UINT64), AcpiDmTableInfoNfit6a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ FieldOffset += sizeof (UINT64);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpPcct
+ *
+ * PARAMETERS: Table - A PCCT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a PCCT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpPcct (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_PCCT_SUBSPACE *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_PCCT);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Header.Length, AcpiDmTableInfoPcctHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Header.Type)
+ {
+ case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
+
+ InfoTable = AcpiDmTableInfoPcct0;
+ break;
+
+ case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
+
+ InfoTable = AcpiDmTableInfoPcct1;
+ break;
+
+ default:
+
+ AcpiOsPrintf (
+ "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
+ SubTable->Header.Type);
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Header.Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += SubTable->Header.Length;
+ SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable,
+ SubTable->Header.Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpPmtt
+ *
+ * PARAMETERS: Table - A PMTT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a PMTT. This table type consists
+ * of an open-ended number of subtables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpPmtt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_PMTT_HEADER *SubTable;
+ ACPI_PMTT_HEADER *MemSubTable;
+ ACPI_PMTT_HEADER *DimmSubTable;
+ ACPI_PMTT_DOMAIN *DomainArray;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_PMTT);
+ UINT32 MemOffset;
+ UINT32 DimmOffset;
+ UINT32 DomainOffset;
+ UINT32 DomainCount;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoPmttHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Only Socket subtables are expected at this level */
+
+ if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET)
+ {
+ AcpiOsPrintf (
+ "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
+ SubTable->Type);
+ return;
+ }
+
+ /* Dump the fixed-length portion of the subtable */
+
+ Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoPmtt0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Walk the memory controller subtables */
+
+ MemOffset = sizeof (ACPI_PMTT_SOCKET);
+ MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable,
+ sizeof (ACPI_PMTT_SOCKET));
+
+ while (((Offset + MemOffset) < Table->Length) &&
+ (MemOffset < SubTable->Length))
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length,
+ Offset + MemOffset, MemSubTable,
+ MemSubTable->Length, AcpiDmTableInfoPmttHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Only memory controller subtables are expected at this level */
+
+ if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER)
+ {
+ AcpiOsPrintf (
+ "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
+ MemSubTable->Type);
+ return;
+ }
+
+ /* Dump the fixed-length portion of the controller subtable */
+
+ Status = AcpiDmDumpTable (Length,
+ Offset + MemOffset, MemSubTable,
+ MemSubTable->Length, AcpiDmTableInfoPmtt1);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Walk the variable count of proximity domains */
+
+ DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount;
+ DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
+ DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable,
+ sizeof (ACPI_PMTT_CONTROLLER));
+
+ while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
+ ((MemOffset + DomainOffset) < SubTable->Length) &&
+ DomainCount)
+ {
+ Status = AcpiDmDumpTable (Length,
+ Offset + MemOffset + DomainOffset, DomainArray,
+ sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ DomainOffset += sizeof (ACPI_PMTT_DOMAIN);
+ DomainArray++;
+ DomainCount--;
+ }
+
+ if (DomainCount)
+ {
+ AcpiOsPrintf (
+ "\n**** DomainCount exceeds subtable length\n\n");
+ }
+
+ /* Walk the physical component (DIMM) subtables */
+
+ DimmOffset = DomainOffset;
+ DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable,
+ DomainOffset);
+
+ while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
+ (DimmOffset < MemSubTable->Length))
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length,
+ Offset + MemOffset + DimmOffset, DimmSubTable,
+ DimmSubTable->Length, AcpiDmTableInfoPmttHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Only DIMM subtables are expected at this level */
+
+ if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM)
+ {
+ AcpiOsPrintf (
+ "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
+ DimmSubTable->Type);
+ return;
+ }
+
+ /* Dump the fixed-length DIMM subtable */
+
+ Status = AcpiDmDumpTable (Length,
+ Offset + MemOffset + DimmOffset, DimmSubTable,
+ DimmSubTable->Length, AcpiDmTableInfoPmtt2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next DIMM subtable */
+
+ DimmOffset += DimmSubTable->Length;
+ DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ DimmSubTable, DimmSubTable->Length);
+ }
+
+ /* Point to next Controller subtable */
+
+ MemOffset += MemSubTable->Length;
+ MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ MemSubTable, MemSubTable->Length);
+ }
+
+ /* Point to next Socket subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpS3pt
+ *
+ * PARAMETERS: Table - A S3PT table
+ *
+ * RETURN: Length of the table
+ *
+ * DESCRIPTION: Format the contents of a S3PT
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmDumpS3pt (
+ ACPI_TABLE_HEADER *Tables)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_S3PT);
+ ACPI_S3PT_HEADER *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_TABLE_S3PT *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
+ if (ACPI_FAILURE (Status))
+ {
+ return 0;
+ }
+
+ SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, S3ptTable, Offset);
+ while (Offset < S3ptTable->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoS3ptHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return 0;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_S3PT_TYPE_RESUME:
+
+ InfoTable = AcpiDmTableInfoS3pt0;
+ break;
+
+ case ACPI_S3PT_TYPE_SUSPEND:
+
+ InfoTable = AcpiDmTableInfoS3pt1;
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n", SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return 0;
+ }
+ goto NextSubTable;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return 0;
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, SubTable, SubTable->Length);
+ }
+
+ return (S3ptTable->Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSlic
+ *
+ * PARAMETERS: Table - A SLIC table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a SLIC
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpSlic (
+ ACPI_TABLE_HEADER *Table)
+{
+ (void) AcpiDmDumpTable (Table->Length, sizeof (ACPI_TABLE_HEADER), Table,
+ Table->Length - sizeof (*Table), AcpiDmTableInfoSlic);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSlit
+ *
+ * PARAMETERS: Table - An SLIT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a SLIT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpSlit (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset;
+ UINT8 *Row;
+ UINT32 Localities;
+ UINT32 i;
+ UINT32 j;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Display the Locality NxN Matrix */
+
+ Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount;
+ Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]);
+ Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry;
+
+ for (i = 0; i < Localities; i++)
+ {
+ /* Display one row of the matrix */
+
+ AcpiDmLineHeader2 (Offset, Localities, "Locality", i);
+ for (j = 0; j < Localities; j++)
+ {
+ /* Check for beyond EOT */
+
+ if (Offset >= Table->Length)
+ {
+ AcpiOsPrintf ("\n**** Not enough room in table for all localities\n");
+ return;
+ }
+
+ AcpiOsPrintf ("%2.2X", Row[j]);
+ Offset++;
+
+ /* Display up to 16 bytes per output row */
+
+ if ((j+1) < Localities)
+ {
+ AcpiOsPrintf (" ");
+
+ if (j && (((j+1) % 16) == 0))
+ {
+ AcpiOsPrintf ("\\\n"); /* With line continuation char */
+ AcpiDmLineHeader (Offset, 0, NULL);
+ }
+ }
+ }
+
+ /* Point to next row */
+
+ AcpiOsPrintf ("\n");
+ Row += Localities;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSrat
+ *
+ * PARAMETERS: Table - A SRAT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a SRAT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpSrat (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_SRAT);
+ ACPI_SUBTABLE_HEADER *SubTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, AcpiDmTableInfoSratHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (SubTable->Type)
+ {
+ case ACPI_SRAT_TYPE_CPU_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat0;
+ break;
+
+ case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat1;
+ break;
+
+ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat2;
+ break;
+
+ case ACPI_SRAT_TYPE_GICC_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat3;
+ break;
+
+ default:
+ AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n", SubTable->Type);
+
+ /* Attempt to continue */
+
+ if (!SubTable->Length)
+ {
+ AcpiOsPrintf ("Invalid zero length subtable\n");
+ return;
+ }
+ goto NextSubTable;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ SubTable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+NextSubTable:
+ /* Point to next subtable */
+
+ Offset += SubTable->Length;
+ SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpStao
+ *
+ * PARAMETERS: Table - A STAO table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a STAO. This is a variable-length
+ * table that contains an open-ended number of ASCII strings
+ * at the end of the table.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpStao (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ char *Namepath;
+ UINT32 Length = Table->Length;
+ UINT32 StringLength;
+ UINT32 Offset = sizeof (ACPI_TABLE_STAO);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoStao);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* The rest of the table consists of Namepath strings */
+
+ while (Offset < Table->Length)
+ {
+ Namepath = ACPI_ADD_PTR (char, Table, Offset);
+ StringLength = strlen (Namepath) + 1;
+
+ AcpiDmLineHeader (Offset, StringLength, "Namestring");
+ AcpiOsPrintf ("\"%s\"\n", Namepath);
+
+ /* Point to next namepath */
+
+ Offset += StringLength;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpTcpa
+ *
+ * PARAMETERS: Table - A TCPA table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a TCPA.
+ *
+ * NOTE: There are two versions of the table with the same signature:
+ * the client version and the server version. The common
+ * PlatformClass field is used to differentiate the two types of
+ * tables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpTcpa (
+ ACPI_TABLE_HEADER *Table)
+{
+ UINT32 Offset = sizeof (ACPI_TABLE_TCPA_HDR);
+ ACPI_TABLE_TCPA_HDR *CommonHeader = ACPI_CAST_PTR (
+ ACPI_TABLE_TCPA_HDR, Table);
+ ACPI_TABLE_TCPA_HDR *SubTable = ACPI_ADD_PTR (
+ ACPI_TABLE_TCPA_HDR, Table, Offset);
+ ACPI_STATUS Status;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table,
+ 0, AcpiDmTableInfoTcpaHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /*
+ * Examine the PlatformClass field to determine the table type.
+ * Either a client or server table. Only one.
+ */
+ switch (CommonHeader->PlatformClass)
+ {
+ case ACPI_TCPA_CLIENT_TABLE:
+
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Table->Length - Offset, AcpiDmTableInfoTcpaClient);
+ break;
+
+ case ACPI_TCPA_SERVER_TABLE:
+
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Table->Length - Offset, AcpiDmTableInfoTcpaServer);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
+ CommonHeader->PlatformClass);
+ Status = AE_ERROR;
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("\n**** Cannot disassemble TCPA table\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpVrtc
+ *
+ * PARAMETERS: Table - A VRTC table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a VRTC
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpVrtc (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_VRTC);
+ ACPI_VRTC_ENTRY *SubTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoVrtc);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ sizeof (ACPI_VRTC_ENTRY), AcpiDmTableInfoVrtc0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += sizeof (ACPI_VRTC_ENTRY);
+ SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, SubTable, sizeof (ACPI_VRTC_ENTRY));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpWdat
+ *
+ * PARAMETERS: Table - A WDAT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a WDAT
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpWdat (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset = sizeof (ACPI_TABLE_WDAT);
+ ACPI_WDAT_ENTRY *SubTable;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += sizeof (ACPI_WDAT_ENTRY);
+ SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY));
+ }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpWpbt
+ *
+ * PARAMETERS: Table - A WPBT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a WPBT. This table type consists
+ * of an open-ended arguments buffer at the end of the table.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpWpbt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_WPBT *SubTable;
+ UINT32 Length = Table->Length;
+ UINT16 ArgumentsLength;
+
+
+ /* Dump the main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoWpbt);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Extract the arguments buffer length from the main table */
+
+ SubTable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table);
+ ArgumentsLength = SubTable->ArgumentsLength;
+
+ /* Dump the arguments buffer */
+
+ (void) AcpiDmDumpTable (Table->Length, 0, Table, ArgumentsLength,
+ AcpiDmTableInfoWpbt0);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/dmtbinfo.c b/usr/src/boot/sys/contrib/dev/acpica/common/dmtbinfo.c
new file mode 100644
index 0000000000..fc4a254f30
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/dmtbinfo.c
@@ -0,0 +1,2918 @@
+/******************************************************************************
+ *
+ * Module Name: dmtbinfo - Table info for non-AML tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmtbinfo")
+
+/*
+ * How to add a new table:
+ *
+ * - Add the C table definition to the actbl1.h or actbl2.h header.
+ * - Add ACPI_xxxx_OFFSET macro(s) for the table (and subtables) to list below.
+ * - Define the table in this file (for the disassembler). If any
+ * new data types are required (ACPI_DMT_*), see below.
+ * - Add an external declaration for the new table definition (AcpiDmTableInfo*)
+ * in acdisam.h
+ * - Add new table definition to the dispatch table in dmtable.c (AcpiDmTableData)
+ * If a simple table (with no subtables), no disassembly code is needed.
+ * Otherwise, create the AcpiDmDump* function for to disassemble the table
+ * and add it to the dmtbdump.c file.
+ * - Add an external declaration for the new AcpiDmDump* function in acdisasm.h
+ * - Add the new AcpiDmDump* function to the dispatch table in dmtable.c
+ * - Create a template for the new table
+ * - Add data table compiler support
+ *
+ * How to add a new data type (ACPI_DMT_*):
+ *
+ * - Add new type at the end of the ACPI_DMT list in acdisasm.h
+ * - Add length and implementation cases in dmtable.c (disassembler)
+ * - Add type and length cases in dtutils.c (DT compiler)
+ */
+
+/*
+ * Macros used to generate offsets to specific table fields
+ */
+#define ACPI_FACS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_FACS,f)
+#define ACPI_GAS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GENERIC_ADDRESS,f)
+#define ACPI_HDR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HEADER,f)
+#define ACPI_RSDP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_RSDP,f)
+#define ACPI_BERT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BERT,f)
+#define ACPI_BGRT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BGRT,f)
+#define ACPI_BOOT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BOOT,f)
+#define ACPI_CPEP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_CPEP,f)
+#define ACPI_DBG2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DBG2,f)
+#define ACPI_DBGP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DBGP,f)
+#define ACPI_DMAR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DMAR,f)
+#define ACPI_DRTM_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DRTM,f)
+#define ACPI_ECDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_ECDT,f)
+#define ACPI_EINJ_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_EINJ,f)
+#define ACPI_ERST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_ERST,f)
+#define ACPI_GTDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_GTDT,f)
+#define ACPI_HEST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HEST,f)
+#define ACPI_HPET_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HPET,f)
+#define ACPI_IORT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_IORT,f)
+#define ACPI_IVRS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_IVRS,f)
+#define ACPI_MADT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MADT,f)
+#define ACPI_MCFG_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MCFG,f)
+#define ACPI_MCHI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MCHI,f)
+#define ACPI_MPST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MPST,f)
+#define ACPI_MSCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MSCT,f)
+#define ACPI_NFIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_NFIT,f)
+#define ACPI_PCCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PCCT,f)
+#define ACPI_PMTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PMTT,f)
+#define ACPI_S3PT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_S3PT,f)
+#define ACPI_SBST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SBST,f)
+#define ACPI_SLIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIT,f)
+#define ACPI_SPCR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPCR,f)
+#define ACPI_SPMI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPMI,f)
+#define ACPI_SRAT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SRAT,f)
+#define ACPI_STAO_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_STAO,f)
+#define ACPI_TCPA_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_HDR,f)
+#define ACPI_TPM2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TPM2,f)
+#define ACPI_UEFI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_UEFI,f)
+#define ACPI_WAET_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WAET,f)
+#define ACPI_WDAT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDAT,f)
+#define ACPI_WDDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDDT,f)
+#define ACPI_WDRT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDRT,f)
+#define ACPI_WPBT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WPBT,f)
+#define ACPI_XENV_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_XENV,f)
+
+/* Subtables */
+
+#define ACPI_ASF0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_INFO,f)
+#define ACPI_ASF1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ALERT,f)
+#define ACPI_ASF1a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ALERT_DATA,f)
+#define ACPI_ASF2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_REMOTE,f)
+#define ACPI_ASF2a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_CONTROL_DATA,f)
+#define ACPI_ASF3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_RMCP,f)
+#define ACPI_ASF4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ADDRESS,f)
+#define ACPI_CPEP0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_CPEP_POLLING,f)
+#define ACPI_CSRT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_CSRT_GROUP,f)
+#define ACPI_CSRT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_CSRT_SHARED_INFO,f)
+#define ACPI_CSRT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_CSRT_DESCRIPTOR,f)
+#define ACPI_DBG20_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DBG2_DEVICE,f)
+#define ACPI_DMARS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_DEVICE_SCOPE,f)
+#define ACPI_DMAR0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_HARDWARE_UNIT,f)
+#define ACPI_DMAR1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_RESERVED_MEMORY,f)
+#define ACPI_DMAR2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_ATSR,f)
+#define ACPI_DMAR3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_RHSA,f)
+#define ACPI_DMAR4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_ANDD,f)
+#define ACPI_DRTM0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST,f)
+#define ACPI_DRTM1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST,f)
+#define ACPI_DRTM1a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DRTM_RESOURCE,f)
+#define ACPI_DRTM2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DRTM_DPS_ID,f)
+#define ACPI_EINJ0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WHEA_HEADER,f)
+#define ACPI_ERST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WHEA_HEADER,f)
+#define ACPI_FPDTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_HEADER,f)
+#define ACPI_FPDT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_BOOT,f)
+#define ACPI_FPDT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_S3PT_PTR,f)
+#define ACPI_GTDT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GTDT_TIMER_BLOCK,f)
+#define ACPI_GTDT0a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GTDT_TIMER_ENTRY,f)
+#define ACPI_GTDT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GTDT_WATCHDOG,f)
+#define ACPI_GTDTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GTDT_HEADER,f)
+#define ACPI_HEST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f)
+#define ACPI_HEST1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_CORRECTED,f)
+#define ACPI_HEST2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_NMI,f)
+#define ACPI_HEST6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER_ROOT,f)
+#define ACPI_HEST7_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER,f)
+#define ACPI_HEST8_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER_BRIDGE,f)
+#define ACPI_HEST9_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_GENERIC,f)
+#define ACPI_HESTN_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_NOTIFY,f)
+#define ACPI_HESTB_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_ERROR_BANK,f)
+#define ACPI_IORT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_ITS_GROUP,f)
+#define ACPI_IORT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT,f)
+#define ACPI_IORT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_ROOT_COMPLEX,f)
+#define ACPI_IORT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_SMMU,f)
+#define ACPI_IORTA_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_MEMORY_ACCESS,f)
+#define ACPI_IORTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_NODE,f)
+#define ACPI_IORTM_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IORT_ID_MAPPING,f)
+#define ACPI_IVRSH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_HEADER,f)
+#define ACPI_IVRS0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_HARDWARE,f)
+#define ACPI_IVRS1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_MEMORY,f)
+#define ACPI_IVRSD_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DE_HEADER,f)
+#define ACPI_IVRS8A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8A,f)
+#define ACPI_IVRS8B_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8B,f)
+#define ACPI_IVRS8C_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8C,f)
+#define ACPI_LPITH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_LPIT_HEADER,f)
+#define ACPI_LPIT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_LPIT_NATIVE,f)
+#define ACPI_MADT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC,f)
+#define ACPI_MADT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_IO_APIC,f)
+#define ACPI_MADT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f)
+#define ACPI_MADT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_NMI_SOURCE,f)
+#define ACPI_MADT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC_NMI,f)
+#define ACPI_MADT5_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC_OVERRIDE,f)
+#define ACPI_MADT6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_IO_SAPIC,f)
+#define ACPI_MADT7_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_SAPIC,f)
+#define ACPI_MADT8_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f)
+#define ACPI_MADT9_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC,f)
+#define ACPI_MADT10_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f)
+#define ACPI_MADT11_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f)
+#define ACPI_MADT12_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_DISTRIBUTOR,f)
+#define ACPI_MADT13_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_MSI_FRAME,f)
+#define ACPI_MADT14_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_REDISTRIBUTOR,f)
+#define ACPI_MADT15_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_TRANSLATOR,f)
+#define ACPI_MADTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f)
+#define ACPI_MCFG0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MCFG_ALLOCATION,f)
+#define ACPI_MPST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_NODE,f)
+#define ACPI_MPST0A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_STATE,f)
+#define ACPI_MPST0B_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_COMPONENT,f)
+#define ACPI_MPST1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_DATA_HDR,f)
+#define ACPI_MPST2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_DATA,f)
+#define ACPI_MSCT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MSCT_PROXIMITY,f)
+#define ACPI_MTMR0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MTMR_ENTRY,f)
+#define ACPI_NFITH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_HEADER,f)
+#define ACPI_NFIT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_SYSTEM_ADDRESS,f)
+#define ACPI_NFIT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_MEMORY_MAP,f)
+#define ACPI_NFIT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_INTERLEAVE,f)
+#define ACPI_NFIT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_SMBIOS,f)
+#define ACPI_NFIT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_CONTROL_REGION,f)
+#define ACPI_NFIT5_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_DATA_REGION,f)
+#define ACPI_NFIT6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_FLUSH_ADDRESS,f)
+#define ACPI_PCCT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_SUBSPACE,f)
+#define ACPI_PCCT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_HW_REDUCED,f)
+#define ACPI_PMTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_SOCKET,f)
+#define ACPI_PMTT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_CONTROLLER,f)
+#define ACPI_PMTT1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_DOMAIN,f)
+#define ACPI_PMTT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_PHYSICAL_COMPONENT,f)
+#define ACPI_PMTTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_HEADER,f)
+#define ACPI_S3PTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_HEADER,f)
+#define ACPI_S3PT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_RESUME,f)
+#define ACPI_S3PT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_SUSPEND,f)
+#define ACPI_SLIC_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIC,f)
+#define ACPI_SRATH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f)
+#define ACPI_SRAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_CPU_AFFINITY,f)
+#define ACPI_SRAT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_MEM_AFFINITY,f)
+#define ACPI_SRAT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f)
+#define ACPI_SRAT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_GICC_AFFINITY,f)
+#define ACPI_TCPA_CLIENT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_CLIENT,f)
+#define ACPI_TCPA_SERVER_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_SERVER,f)
+#define ACPI_VRTC0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_VRTC_ENTRY,f)
+#define ACPI_WDAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WDAT_ENTRY,f)
+
+/*
+ * Simplify access to flag fields by breaking them up into bytes
+ */
+#define ACPI_FLAG_OFFSET(d,f,o) (UINT16) (ACPI_OFFSET (d,f) + o)
+
+/* Flags */
+
+#define ACPI_DRTM_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_DRTM,f,o)
+#define ACPI_DRTM1a_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_DRTM_RESOURCE,f,o)
+#define ACPI_FADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_FADT,f,o)
+#define ACPI_FACS_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_FACS,f,o)
+#define ACPI_HPET_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_HPET,f,o)
+#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_CPU_AFFINITY,f,o)
+#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_MEM_AFFINITY,f,o)
+#define ACPI_SRAT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f,o)
+#define ACPI_SRAT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_GICC_AFFINITY,f,o)
+#define ACPI_GTDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_GTDT,f,o)
+#define ACPI_GTDT0a_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_GTDT_TIMER_ENTRY,f,o)
+#define ACPI_GTDT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_GTDT_WATCHDOG,f,o)
+#define ACPI_IORT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_IORT_SMMU,f,o)
+#define ACPI_IORTA_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_IORT_MEMORY_ACCESS,f,o)
+#define ACPI_IORTM_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_IORT_ID_MAPPING,f,o)
+#define ACPI_LPITH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_LPIT_HEADER,f,o)
+#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_MADT,f,o)
+#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_APIC,f,o)
+#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f,o)
+#define ACPI_MADT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_NMI_SOURCE,f,o)
+#define ACPI_MADT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_APIC_NMI,f,o)
+#define ACPI_MADT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_SAPIC,f,o)
+#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f,o)
+#define ACPI_MADT9_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC,f,o)
+#define ACPI_MADT10_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f,o)
+#define ACPI_MADT11_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f,o)
+#define ACPI_MADT13_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_GENERIC_MSI_FRAME,f,o)
+#define ACPI_MPST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_NODE,f,o)
+#define ACPI_MPST2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_DATA,f,o)
+#define ACPI_NFIT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_SYSTEM_ADDRESS,f,o)
+#define ACPI_NFIT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_MEMORY_MAP,f,o)
+#define ACPI_NFIT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_CONTROL_REGION,f,o)
+#define ACPI_PCCT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_PCCT,f,o)
+#define ACPI_PCCT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_HW_REDUCED,f,o)
+#define ACPI_PMTTH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PMTT_HEADER,f,o)
+#define ACPI_WDDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WDDT,f,o)
+#define ACPI_EINJ0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o)
+#define ACPI_ERST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o)
+#define ACPI_HEST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f,o)
+#define ACPI_HEST1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_IA_CORRECTED,f,o)
+#define ACPI_HEST6_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_AER_ROOT,f,o)
+
+/*
+ * Required terminator for all tables below
+ */
+#define ACPI_DMT_TERMINATOR {ACPI_DMT_EXIT, 0, NULL, 0}
+#define ACPI_DMT_NEW_LINE {ACPI_DMT_EXTRA_TEXT, 0, "\n", 0}
+
+
+/*
+ * ACPI Table Information, used to dump formatted ACPI tables
+ *
+ * Each entry is of the form: <Field Type, Field Offset, Field Name>
+ */
+
+/*******************************************************************************
+ *
+ * Common ACPI table header
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHeader[] =
+{
+ {ACPI_DMT_SIG, ACPI_HDR_OFFSET (Signature[0]), "Signature", 0},
+ {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (Length), "Table Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_HDR_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_CHKSUM, ACPI_HDR_OFFSET (Checksum), "Checksum", 0},
+ {ACPI_DMT_NAME6, ACPI_HDR_OFFSET (OemId[0]), "Oem ID", 0},
+ {ACPI_DMT_NAME8, ACPI_HDR_OFFSET (OemTableId[0]), "Oem Table ID", 0},
+ {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (OemRevision), "Oem Revision", 0},
+ {ACPI_DMT_NAME4, ACPI_HDR_OFFSET (AslCompilerId[0]), "Asl Compiler ID", 0},
+ {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (AslCompilerRevision), "Asl Compiler Revision", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * GAS - Generic Address Structure
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGas[] =
+{
+ {ACPI_DMT_SPACEID, ACPI_GAS_OFFSET (SpaceId), "Space ID", 0},
+ {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitWidth), "Bit Width", 0},
+ {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitOffset), "Bit Offset", 0},
+ {ACPI_DMT_ACCWIDTH, ACPI_GAS_OFFSET (AccessWidth), "Encoded Access Width", 0},
+ {ACPI_DMT_UINT64, ACPI_GAS_OFFSET (Address), "Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * RSDP - Root System Description Pointer (Signature is "RSD PTR ")
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp1[] =
+{
+ {ACPI_DMT_NAME8, ACPI_RSDP_OFFSET (Signature[0]), "Signature", 0},
+ {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (Checksum), "Checksum", 0},
+ {ACPI_DMT_NAME6, ACPI_RSDP_OFFSET (OemId[0]), "Oem ID", 0},
+ {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_UINT32, ACPI_RSDP_OFFSET (RsdtPhysicalAddress), "RSDT Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* ACPI 2.0+ Extensions */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp2[] =
+{
+ {ACPI_DMT_UINT32, ACPI_RSDP_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT64, ACPI_RSDP_OFFSET (XsdtPhysicalAddress), "XSDT Address", 0},
+ {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (ExtendedChecksum), "Extended Checksum", 0},
+ {ACPI_DMT_UINT24, ACPI_RSDP_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * FACS - Firmware ACPI Control Structure
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFacs[] =
+{
+ {ACPI_DMT_NAME4, ACPI_FACS_OFFSET (Signature[0]), "Signature", 0},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (HardwareSignature), "Hardware Signature", 0},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (FirmwareWakingVector), "32 Firmware Waking Vector", 0},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (GlobalLock), "Global Lock", 0},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (Flags,0), "S4BIOS Support Present", 0},
+ {ACPI_DMT_FLAG1, ACPI_FACS_FLAG_OFFSET (Flags,0), "64-bit Wake Supported (V2)", 0},
+ {ACPI_DMT_UINT64, ACPI_FACS_OFFSET (XFirmwareWakingVector), "64 Firmware Waking Vector", 0},
+ {ACPI_DMT_UINT8, ACPI_FACS_OFFSET (Version), "Version", 0},
+ {ACPI_DMT_UINT24, ACPI_FACS_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (OspmFlags), "OspmFlags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (OspmFlags,0), "64-bit Wake Env Required (V2)", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * FADT - Fixed ACPI Description Table (Signature is FACP)
+ *
+ ******************************************************************************/
+
+/* ACPI 1.0 FADT (Version 1) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFadt1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Facs), "FACS Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Dsdt), "DSDT Address", DT_NON_ZERO},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Model), "Model", 0},
+ {ACPI_DMT_FADTPM, ACPI_FADT_OFFSET (PreferredProfile), "PM Profile", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (SciInterrupt), "SCI Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (SmiCommand), "SMI Command Port", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (AcpiEnable), "ACPI Enable Value", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (AcpiDisable), "ACPI Disable Value", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (S4BiosRequest), "S4BIOS Command", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (PstateControl), "P-State Control", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1aEventBlock), "PM1A Event Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1bEventBlock), "PM1B Event Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1aControlBlock), "PM1A Control Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1bControlBlock), "PM1B Control Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm2ControlBlock), "PM2 Control Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (PmTimerBlock), "PM Timer Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Gpe0Block), "GPE0 Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Gpe1Block), "GPE1 Block Address", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm1EventLength), "PM1 Event Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm1ControlLength), "PM1 Control Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm2ControlLength), "PM2 Control Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (PmTimerLength), "PM Timer Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe0BlockLength), "GPE0 Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe1BlockLength), "GPE1 Block Length", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe1Base), "GPE1 Base Offset", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (CstControl), "_CST Support", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (C2Latency), "C2 Latency", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (C3Latency), "C3 Latency", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (FlushSize), "CPU Cache Size", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (FlushStride), "Cache Flush Stride", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DutyOffset), "Duty Cycle Offset", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DutyWidth), "Duty Cycle Width", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DayAlarm), "RTC Day Alarm Index", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (MonthAlarm), "RTC Month Alarm Index", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Century), "RTC Century Index", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (BootFlags), "Boot Flags (decoded below)", DT_FLAG},
+
+ /* Boot Architecture Flags byte 0 */
+
+ {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "Legacy Devices Supported (V2)", 0},
+ {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "8042 Present on ports 60/64 (V2)", 0},
+ {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "VGA Not Present (V4)", 0},
+ {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "MSI Not Supported (V4)", 0},
+ {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "PCIe ASPM Not Supported (V4)", 0},
+ {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "CMOS RTC Not Present (V5)", 0},
+
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+
+ /* Flags byte 0 */
+
+ {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,0), "WBINVD instruction is operational (V1)", 0},
+ {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,0), "WBINVD flushes all caches (V1)", 0},
+ {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,0), "All CPUs support C1 (V1)", 0},
+ {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,0), "C2 works on MP system (V1)", 0},
+ {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,0), "Control Method Power Button (V1)", 0},
+ {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,0), "Control Method Sleep Button (V1)", 0},
+ {ACPI_DMT_FLAG6, ACPI_FADT_FLAG_OFFSET (Flags,0), "RTC wake not in fixed reg space (V1)", 0},
+ {ACPI_DMT_FLAG7, ACPI_FADT_FLAG_OFFSET (Flags,0), "RTC can wake system from S4 (V1)", 0},
+
+ /* Flags byte 1 */
+
+ {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,1), "32-bit PM Timer (V1)", 0},
+ {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,1), "Docking Supported (V1)", 0},
+ {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,1), "Reset Register Supported (V2)", 0},
+ {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,1), "Sealed Case (V3)", 0},
+ {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,1), "Headless - No Video (V3)", 0},
+ {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,1), "Use native instr after SLP_TYPx (V3)", 0},
+ {ACPI_DMT_FLAG6, ACPI_FADT_FLAG_OFFSET (Flags,1), "PCIEXP_WAK Bits Supported (V4)", 0},
+ {ACPI_DMT_FLAG7, ACPI_FADT_FLAG_OFFSET (Flags,1), "Use Platform Timer (V4)", 0},
+
+ /* Flags byte 2 */
+
+ {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,2), "RTC_STS valid on S4 wake (V4)", 0},
+ {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,2), "Remote Power-on capable (V4)", 0},
+ {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Cluster Model (V4)", 0},
+ {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Physical Destination Mode (V4)", 0},
+ {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,2), "Hardware Reduced (V5)", 0},
+ {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,2), "Low Power S0 Idle (V5)", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* ACPI 1.0 MS Extensions (FADT version 2) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFadt2[] =
+{
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (ResetRegister), "Reset Register", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (ResetValue), "Value to cause reset", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (ArmBootFlags), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (MinorRevision), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* ACPI 2.0+ Extensions (FADT version 3, 4, and 5) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFadt3[] =
+{
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (ResetRegister), "Reset Register", 0},
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (ResetValue), "Value to cause reset", 0},
+ {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (ArmBootFlags), "ARM Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET(ArmBootFlags,0), "PSCI Compliant", 0},
+ {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET(ArmBootFlags,0), "Must use HVC for PSCI", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (MinorRevision), "FADT Minor Revision", 0},
+ {ACPI_DMT_UINT64, ACPI_FADT_OFFSET (XFacs), "FACS Address", 0},
+ {ACPI_DMT_UINT64, ACPI_FADT_OFFSET (XDsdt), "DSDT Address", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1aEventBlock), "PM1A Event Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1bEventBlock), "PM1B Event Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1aControlBlock), "PM1A Control Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1bControlBlock), "PM1B Control Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm2ControlBlock), "PM2 Control Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPmTimerBlock), "PM Timer Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XGpe0Block), "GPE0 Block", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XGpe1Block), "GPE1 Block", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* ACPI 5.0 Extensions (FADT version 5) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFadt5[] =
+{
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (SleepControl), "Sleep Control Register", 0},
+ {ACPI_DMT_GAS, ACPI_FADT_OFFSET (SleepStatus), "Sleep Status Register", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* ACPI 6.0 Extensions (FADT version 6) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFadt6[] =
+{
+ {ACPI_DMT_UINT64, ACPI_FADT_OFFSET (HypervisorId), "Hypervisor ID", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*
+ * Remaining tables are not consumed directly by the ACPICA subsystem
+ */
+
+/*******************************************************************************
+ *
+ * ASF - Alert Standard Format table (Signature "ASF!")
+ *
+ ******************************************************************************/
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsfHdr[] =
+{
+ {ACPI_DMT_ASF, ACPI_ASF0_OFFSET (Header.Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (Header.Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF0_OFFSET (Header.Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0: ASF Information */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinResetValue), "Minimum Reset Value", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinPollInterval), "Minimum Polling Interval", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF0_OFFSET (SystemId), "System ID", 0},
+ {ACPI_DMT_UINT32, ACPI_ASF0_OFFSET (MfgId), "Manufacturer ID", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT24, ACPI_ASF0_OFFSET (Reserved2[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: ASF Alerts */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (AssertMask), "AssertMask", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (DeassertMask), "DeassertMask", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (Alerts), "Alert Count", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (DataLength), "Alert Data Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1a: ASF Alert data */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1a[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Address), "Address", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Command), "Command", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Mask), "Mask", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Value), "Value", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SensorType), "SensorType", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Offset), "Offset", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SourceType), "SourceType", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Severity), "Severity", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SensorNumber), "SensorNumber", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Entity), "Entity", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Instance), "Instance", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: ASF Remote Control */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF2_OFFSET (Controls), "Control Count", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF2_OFFSET (DataLength), "Control Data Length", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF2_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2a: ASF Control data */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2a[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Function), "Function", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Address), "Address", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Command), "Command", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Value), "Value", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 3: ASF RMCP Boot Options */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf3[] =
+{
+ {ACPI_DMT_BUF7, ACPI_ASF3_OFFSET (Capabilities[0]), "Capabilities", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF3_OFFSET (CompletionCode), "Completion Code", 0},
+ {ACPI_DMT_UINT32, ACPI_ASF3_OFFSET (EnterpriseId), "Enterprise ID", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF3_OFFSET (Command), "Command", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (Parameter), "Parameter", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (BootOptions), "Boot Options", 0},
+ {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (OemParameters), "Oem Parameters", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 4: ASF Address */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoAsf4[] =
+{
+ {ACPI_DMT_UINT8, ACPI_ASF4_OFFSET (EpromAddress), "Eprom Address", 0},
+ {ACPI_DMT_UINT8, ACPI_ASF4_OFFSET (Devices), "Device Count", DT_COUNT},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * BERT - Boot Error Record table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoBert[] =
+{
+ {ACPI_DMT_UINT32, ACPI_BERT_OFFSET (RegionLength), "Boot Error Region Length", 0},
+ {ACPI_DMT_UINT64, ACPI_BERT_OFFSET (Address), "Boot Error Region Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * BGRT - Boot Graphics Resource Table (ACPI 5.0)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoBgrt[] =
+{
+ {ACPI_DMT_UINT16, ACPI_BGRT_OFFSET (Version), "Version", 0},
+ {ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (Status), "Status", 0},
+ {ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (ImageType), "Image Type", 0},
+ {ACPI_DMT_UINT64, ACPI_BGRT_OFFSET (ImageAddress), "Image Address", 0},
+ {ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetX), "Image OffsetX", 0},
+ {ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetY), "Image OffsetY", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * BOOT - Simple Boot Flag Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoBoot[] =
+{
+ {ACPI_DMT_UINT8, ACPI_BOOT_OFFSET (CmosIndex), "Boot Register Index", 0},
+ {ACPI_DMT_UINT24, ACPI_BOOT_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * CPEP - Corrected Platform Error Polling table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCpep[] =
+{
+ {ACPI_DMT_UINT64, ACPI_CPEP_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCpep0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Id), "Processor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Eid), "Processor EID", 0},
+ {ACPI_DMT_UINT32, ACPI_CPEP0_OFFSET (Interval), "Polling Interval", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * CSRT - Core System Resource Table
+ *
+ ******************************************************************************/
+
+/* Main table consists only of the standard ACPI table header */
+
+/* Resource Group subtable */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt0[] =
+{
+ {ACPI_DMT_UINT32, ACPI_CSRT0_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT32, ACPI_CSRT0_OFFSET (VendorId), "Vendor ID", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT0_OFFSET (SubvendorId), "Subvendor ID", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT0_OFFSET (DeviceId), "Device ID", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT0_OFFSET (SubdeviceId), "Subdevice ID", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT0_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT0_OFFSET (SharedInfoLength), "Shared Info Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Shared Info subtable */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt1[] =
+{
+ {ACPI_DMT_UINT16, ACPI_CSRT1_OFFSET (MajorVersion), "Major Version", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT1_OFFSET (MinorVersion), "Minor Version", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT1_OFFSET (MmioBaseLow), "MMIO Base Address Low", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT1_OFFSET (MmioBaseHigh), "MMIO Base Address High", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT1_OFFSET (GsiInterrupt), "GSI Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_CSRT1_OFFSET (InterruptPolarity), "Interrupt Polarity", 0},
+ {ACPI_DMT_UINT8, ACPI_CSRT1_OFFSET (InterruptMode), "Interrupt Mode", 0},
+ {ACPI_DMT_UINT8, ACPI_CSRT1_OFFSET (NumChannels), "Num Channels", 0},
+ {ACPI_DMT_UINT8, ACPI_CSRT1_OFFSET (DmaAddressWidth), "DMA Address Width", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT1_OFFSET (BaseRequestLine), "Base Request Line", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT1_OFFSET (NumHandshakeSignals), "Num Handshake Signals", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT1_OFFSET (MaxBlockSize), "Max Block Size", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/* Resource Descriptor subtable */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2[] =
+{
+ {ACPI_DMT_UINT32, ACPI_CSRT2_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_CSRT2_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_UINT16, ACPI_CSRT2_OFFSET (Subtype), "Subtype", 0},
+ {ACPI_DMT_UINT32, ACPI_CSRT2_OFFSET (Uid), "UID", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2a[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "ResourceInfo", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * DBG2 - Debug Port Table 2
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2[] =
+{
+ {ACPI_DMT_UINT32, ACPI_DBG2_OFFSET (InfoOffset), "Info Offset", 0},
+ {ACPI_DMT_UINT32, ACPI_DBG2_OFFSET (InfoCount), "Info Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Debug Device Information Subtable */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Device[] =
+{
+ {ACPI_DMT_UINT8, ACPI_DBG20_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_DBG20_OFFSET (RegisterCount), "Register Count", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (NamepathLength), "Namepath Length", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (NamepathOffset), "Namepath Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (OemDataLength), "OEM Data Length", DT_DESCRIBES_OPTIONAL},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (OemDataOffset), "OEM Data Offset", DT_DESCRIBES_OPTIONAL},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (PortType), "Port Type", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (PortSubtype), "Port Subtype", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (BaseAddressOffset), "Base Address Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_DBG20_OFFSET (AddressSizeOffset), "Address Size Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Variable-length data for the subtable */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Addr[] =
+{
+ {ACPI_DMT_GAS, 0, "Base Address Register", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Size[] =
+{
+ {ACPI_DMT_UINT32, 0, "Address Size", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Name[] =
+{
+ {ACPI_DMT_STRING, 0, "Namepath", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2OemData[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "OEM Data", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * DBGP - Debug Port
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDbgp[] =
+{
+ {ACPI_DMT_UINT8, ACPI_DBGP_OFFSET (Type), "Interface Type", 0},
+ {ACPI_DMT_UINT24, ACPI_DBGP_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_DBGP_OFFSET (DebugPort), "Debug Port Register", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * DMAR - DMA Remapping table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar[] =
+{
+ {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Width), "Host Address Width", 0},
+ {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_BUF10, ACPI_DMAR_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmarHdr[] =
+{
+ {ACPI_DMT_DMAR, ACPI_DMAR0_OFFSET (Header.Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT16, ACPI_DMAR0_OFFSET (Header.Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common device scope entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmarScope[] =
+{
+ {ACPI_DMT_DMAR_SCOPE, ACPI_DMARS_OFFSET (EntryType), "Device Scope Type", 0},
+ {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (Length), "Entry Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_DMARS_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (EnumerationId), "Enumeration ID", 0},
+ {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (Bus), "PCI Bus Number", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* DMAR Subtables */
+
+/* 0: Hardware Unit Definition */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_DMAR0_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT8, ACPI_DMAR0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_DMAR0_OFFSET (Segment), "PCI Segment Number", 0},
+ {ACPI_DMT_UINT64, ACPI_DMAR0_OFFSET (Address), "Register Base Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: Reserved Memory Definition */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar1[] =
+{
+ {ACPI_DMT_UINT16, ACPI_DMAR1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_DMAR1_OFFSET (Segment), "PCI Segment Number", 0},
+ {ACPI_DMT_UINT64, ACPI_DMAR1_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_DMAR1_OFFSET (EndAddress), "End Address (limit)", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: Root Port ATS Capability Definition */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar2[] =
+{
+ {ACPI_DMT_UINT8, ACPI_DMAR2_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT8, ACPI_DMAR2_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_DMAR2_OFFSET (Segment), "PCI Segment Number", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 3: Remapping Hardware Static Affinity Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[] =
+{
+ {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_DMAR3_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 4: ACPI Namespace Device Declaration Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDmar4[] =
+{
+ {ACPI_DMT_UINT24, ACPI_DMAR4_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_DMAR4_OFFSET (DeviceNumber), "Device Number", 0},
+ {ACPI_DMT_STRING, ACPI_DMAR4_OFFSET (DeviceName[0]), "Device Name", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * DRTM - Dynamic Root of Trust for Measurement table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm[] =
+{
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (EntryBaseAddress), "Entry Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (EntryLength), "Entry Length", 0},
+ {ACPI_DMT_UINT32, ACPI_DRTM_OFFSET (EntryAddress32), "Entry 32", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (EntryAddress64), "Entry 64", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (ExitAddress), "Exit Address", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (LogAreaAddress), "Log Area Start", 0},
+ {ACPI_DMT_UINT32, ACPI_DRTM_OFFSET (LogAreaLength), "Log Area Length", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM_OFFSET (ArchDependentAddress), "Arch Dependent Address", 0},
+ {ACPI_DMT_UINT32, ACPI_DRTM_OFFSET (Flags), "Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_DRTM_FLAG_OFFSET (Flags, 0), "Namespace in TCB", 0},
+ {ACPI_DMT_FLAG1, ACPI_DRTM_FLAG_OFFSET (Flags, 0), "Gap Code on S3 Resume", 0},
+ {ACPI_DMT_FLAG2, ACPI_DRTM_FLAG_OFFSET (Flags, 0), "Gap Code on DLME_Exit", 0},
+ {ACPI_DMT_FLAG3, ACPI_DRTM_FLAG_OFFSET (Flags, 0), "PCR_Authorities Changed", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm0[] =
+{
+ {ACPI_DMT_UINT32, ACPI_DRTM0_OFFSET (ValidatedTableCount), "Validated Table Count", DT_COUNT},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm0a[] =
+{
+ {ACPI_DMT_UINT64, 0, "Table Address", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_DRTM1_OFFSET (ResourceCount), "Resource Count", DT_COUNT},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm1a[] =
+{
+ {ACPI_DMT_UINT56, ACPI_DRTM1a_OFFSET (Size[0]), "Size", DT_OPTIONAL},
+ {ACPI_DMT_UINT8, ACPI_DRTM1a_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_FLAG0, ACPI_DRTM1a_FLAG_OFFSET (Type, 0), "Resource Type", 0},
+ {ACPI_DMT_FLAG7, ACPI_DRTM1a_FLAG_OFFSET (Type, 0), "Protections", 0},
+ {ACPI_DMT_UINT64, ACPI_DRTM1a_OFFSET (Address), "Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm2[] =
+{
+ {ACPI_DMT_UINT32, ACPI_DRTM2_OFFSET (DpsIdLength), "DLME Platform Id Length", DT_COUNT},
+ {ACPI_DMT_BUF16, ACPI_DRTM2_OFFSET (DpsId), "DLME Platform Id", DT_COUNT},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * ECDT - Embedded Controller Boot Resources Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoEcdt[] =
+{
+ {ACPI_DMT_GAS, ACPI_ECDT_OFFSET (Control), "Command/Status Register", 0},
+ {ACPI_DMT_GAS, ACPI_ECDT_OFFSET (Data), "Data Register", 0},
+ {ACPI_DMT_UINT32, ACPI_ECDT_OFFSET (Uid), "UID", 0},
+ {ACPI_DMT_UINT8, ACPI_ECDT_OFFSET (Gpe), "GPE Number", 0},
+ {ACPI_DMT_STRING, ACPI_ECDT_OFFSET (Id[0]), "Namepath", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * EINJ - Error Injection table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoEinj[] =
+{
+ {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (HeaderLength), "Injection Header Length", 0},
+ {ACPI_DMT_UINT8, ACPI_EINJ_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT24, ACPI_EINJ_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (Entries), "Injection Entry Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoEinj0[] =
+{
+ {ACPI_DMT_EINJACT, ACPI_EINJ0_OFFSET (Action), "Action", 0},
+ {ACPI_DMT_EINJINST, ACPI_EINJ0_OFFSET (Instruction), "Instruction", 0},
+ {ACPI_DMT_UINT8, ACPI_EINJ0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_EINJ0_FLAG_OFFSET (Flags,0), "Preserve Register Bits", 0},
+
+ {ACPI_DMT_UINT8, ACPI_EINJ0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_EINJ0_OFFSET (RegisterRegion), "Register Region", 0},
+ {ACPI_DMT_UINT64, ACPI_EINJ0_OFFSET (Value), "Value", 0},
+ {ACPI_DMT_UINT64, ACPI_EINJ0_OFFSET (Mask), "Mask", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * ERST - Error Record Serialization table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoErst[] =
+{
+ {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (HeaderLength), "Serialization Header Length", 0},
+ {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (Entries), "Instruction Entry Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoErst0[] =
+{
+ {ACPI_DMT_ERSTACT, ACPI_ERST0_OFFSET (Action), "Action", 0},
+ {ACPI_DMT_ERSTINST, ACPI_ERST0_OFFSET (Instruction), "Instruction", 0},
+ {ACPI_DMT_UINT8, ACPI_ERST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_ERST0_FLAG_OFFSET (Flags,0), "Preserve Register Bits", 0},
+
+ {ACPI_DMT_UINT8, ACPI_ERST0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_ERST0_OFFSET (RegisterRegion), "Register Region", 0},
+ {ACPI_DMT_UINT64, ACPI_ERST0_OFFSET (Value), "Value", 0},
+ {ACPI_DMT_UINT64, ACPI_ERST0_OFFSET (Mask), "Mask", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * FPDT - Firmware Performance Data Table (ACPI 5.0)
+ *
+ ******************************************************************************/
+
+/* Main table consists of only the standard ACPI header - subtables follow */
+
+/* FPDT subtable header */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFpdtHdr[] =
+{
+ {ACPI_DMT_UINT16, ACPI_FPDTH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Revision), "Revision", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0: Firmware Basic Boot Performance Record */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt0[] =
+{
+ {ACPI_DMT_UINT32, ACPI_FPDT0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ResetEnd), "Reset End", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (LoadStart), "Load Image Start", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (StartupStart), "Start Image Start", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesEntry), "Exit Services Entry", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesExit), "Exit Services Exit", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: S3 Performance Table Pointer Record */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_FPDT1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_FPDT1_OFFSET (Address), "S3PT Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * GTDT - Generic Timer Description Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt[] =
+{
+ {ACPI_DMT_UINT64, ACPI_GTDT_OFFSET (CounterBlockAddresss), "Counter Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecureEl1Interrupt), "Secure EL1 Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecureEl1Flags), "EL1 Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (SecureEl1Flags,0), "Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (SecureEl1Flags,0), "Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_GTDT_FLAG_OFFSET (SecureEl1Flags,0), "Always On", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecureEl1Interrupt), "Non-Secure EL1 Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecureEl1Flags), "NEL1 Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecureEl1Flags,0),"Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecureEl1Flags,0),"Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_GTDT_FLAG_OFFSET (NonSecureEl1Flags,0),"Always On", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerInterrupt), "Virtual Timer Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerFlags), "VT Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Always On", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecureEl2Interrupt), "Non-Secure EL2 Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecureEl2Flags), "NEL2 Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecureEl2Flags,0),"Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecureEl2Flags,0),"Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_GTDT_FLAG_OFFSET (NonSecureEl2Flags,0),"Always On", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT_OFFSET (CounterReadBlockAddress), "Counter Read Block Address", 0},
+ ACPI_DMT_NEW_LINE,
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (PlatformTimerCount), "Platform Timer Count", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (PlatformTimerOffset), "Platform Timer Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* GTDT Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGtdtHdr[] =
+{
+ {ACPI_DMT_GTDT, ACPI_GTDTH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT16, ACPI_GTDTH_OFFSET (Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* GTDT Subtables */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_GTDT0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT0_OFFSET (BlockAddress), "Block Address", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0_OFFSET (TimerCount), "Timer Count", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0_OFFSET (TimerOffset), "Timer Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt0a[] =
+{
+ {ACPI_DMT_UINT8 , ACPI_GTDT0a_OFFSET (FrameNumber), "Frame Number", 0},
+ {ACPI_DMT_UINT24, ACPI_GTDT0a_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT0a_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT0a_OFFSET (El0BaseAddress), "EL0 Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0a_OFFSET (TimerInterrupt), "Timer Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0a_OFFSET (TimerFlags), "Timer Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_GTDT0a_FLAG_OFFSET (TimerFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT0a_FLAG_OFFSET (TimerFlags,0), "Polarity", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0a_OFFSET (VirtualTimerInterrupt), "Virtual Timer Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0a_OFFSET (VirtualTimerFlags), "Virtual Timer Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_GTDT0a_FLAG_OFFSET (VirtualTimerFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT0a_FLAG_OFFSET (VirtualTimerFlags,0), "Polarity", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT0a_OFFSET (CommonFlags), "Common Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_GTDT0a_FLAG_OFFSET (CommonFlags,0), "Secure", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT0a_FLAG_OFFSET (CommonFlags,0), "Always On", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt1[] =
+{
+ {ACPI_DMT_UINT8, ACPI_GTDT1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT1_OFFSET (RefreshFrameAddress), "Refresh Frame Address", 0},
+ {ACPI_DMT_UINT64, ACPI_GTDT1_OFFSET (ControlFrameAddress), "Control Frame Address", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT1_OFFSET (TimerInterrupt), "Timer Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_GTDT1_OFFSET (TimerFlags), "Timer Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_GTDT1_FLAG_OFFSET (TimerFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_GTDT1_FLAG_OFFSET (TimerFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_GTDT1_FLAG_OFFSET (TimerFlags,0), "Security", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * HEST - Hardware Error Source table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest[] =
+{
+ {ACPI_DMT_UINT32, ACPI_HEST_OFFSET (ErrorSourceCount), "Error Source Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common HEST structures for subtables */
+
+#define ACPI_DM_HEST_HEADER \
+ {ACPI_DMT_HEST, ACPI_HEST0_OFFSET (Header.Type), "Subtable Type", 0}, \
+ {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Header.SourceId), "Source Id", 0}
+
+#define ACPI_DM_HEST_AER \
+ {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved1), "Reserved", 0}, \
+ {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags (decoded below)", DT_FLAG}, \
+ {ACPI_DMT_FLAG0, ACPI_HEST6_FLAG_OFFSET (Aer.Flags,0), "Firmware First", 0}, \
+ {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreallocate), "Records To Preallocate", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus", 0}, \
+ {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device", 0}, \
+ {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function", 0}, \
+ {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl", 0}, \
+ {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved2), "Reserved", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableMask), "Uncorrectable Mask", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableSeverity), "Uncorrectable Severity", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableMask), "Correctable Mask", 0}, \
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedCapabilities), "Advanced Capabilities", 0}
+
+
+/* HEST Subtables */
+
+/* 0: IA32 Machine Check Exception */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest0[] =
+{
+ ACPI_DM_HEST_HEADER,
+ {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Reserved1), "Reserved1", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_HEST0_FLAG_OFFSET (Flags,0), "Firmware First", 0},
+
+ {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Enabled), "Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0},
+ {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalCapabilityData), "Global Capability Data", 0},
+ {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalControlData), "Global Control Data", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (NumHardwareBanks), "Num Hardware Banks", 0},
+ {ACPI_DMT_UINT56, ACPI_HEST0_OFFSET (Reserved3[0]), "Reserved2", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: IA32 Corrected Machine Check */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest1[] =
+{
+ ACPI_DM_HEST_HEADER,
+ {ACPI_DMT_UINT16, ACPI_HEST1_OFFSET (Reserved1), "Reserved1", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_HEST1_FLAG_OFFSET (Flags,0), "Firmware First", 0},
+
+ {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Enabled), "Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0},
+ {ACPI_DMT_HESTNTFY, ACPI_HEST1_OFFSET (Notify), "Notify", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (NumHardwareBanks), "Num Hardware Banks", 0},
+ {ACPI_DMT_UINT24, ACPI_HEST1_OFFSET (Reserved2[0]), "Reserved2", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: IA32 Non-Maskable Interrupt */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest2[] =
+{
+ ACPI_DM_HEST_HEADER,
+ {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxRawDataLength), "Max Raw Data Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 6: PCI Express Root Port AER */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[] =
+{
+ ACPI_DM_HEST_HEADER,
+ ACPI_DM_HEST_AER,
+ {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (RootErrorCommand), "Root Error Command", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 7: PCI Express AER (AER Endpoint) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[] =
+{
+ ACPI_DM_HEST_HEADER,
+ ACPI_DM_HEST_AER,
+ ACPI_DMT_TERMINATOR
+};
+
+/* 8: PCI Express/PCI-X Bridge AER */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[] =
+{
+ ACPI_DM_HEST_HEADER,
+ ACPI_DM_HEST_AER,
+ {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableMask2), "2nd Uncorrectable Mask", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableSeverity2), "2nd Uncorrectable Severity", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (AdvancedCapabilities2), "2nd Advanced Capabilities", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 9: Generic Hardware Error Source */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHest9[] =
+{
+ ACPI_DM_HEST_HEADER,
+ {ACPI_DMT_UINT16, ACPI_HEST9_OFFSET (RelatedSourceId), "Related Source Id", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Enabled), "Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxRawDataLength), "Max Raw Data Length", 0},
+ {ACPI_DMT_GAS, ACPI_HEST9_OFFSET (ErrorStatusAddress), "Error Status Address", 0},
+ {ACPI_DMT_HESTNTFY, ACPI_HEST9_OFFSET (Notify), "Notify", 0},
+ {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (ErrorBlockLength), "Error Status Block Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[] =
+{
+ {ACPI_DMT_HESTNTYP, ACPI_HESTN_OFFSET (Type), "Notify Type", 0},
+ {ACPI_DMT_UINT8, ACPI_HESTN_OFFSET (Length), "Notify Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_HESTN_OFFSET (ConfigWriteEnable), "Configuration Write Enable", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollInterval), "PollInterval", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (Vector), "Vector", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollingThresholdValue), "Polling Threshold Value", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollingThresholdWindow), "Polling Threshold Window", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (ErrorThresholdValue), "Error Threshold Value", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (ErrorThresholdWindow), "Error Threshold Window", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*
+ * IA32 Error Bank(s) - Follows the ACPI_HEST_IA_MACHINE_CHECK and
+ * ACPI_HEST_IA_CORRECTED structures.
+ */
+ACPI_DMTABLE_INFO AcpiDmTableInfoHestBank[] =
+{
+ {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (BankNumber), "Bank Number", 0},
+ {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (ClearStatusOnInit), "Clear Status On Init", 0},
+ {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (StatusFormat), "Status Format", 0},
+ {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (ControlRegister), "Control Register", 0},
+ {ACPI_DMT_UINT64, ACPI_HESTB_OFFSET (ControlData), "Control Data", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (StatusRegister), "Status Register", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (AddressRegister), "Address Register", 0},
+ {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (MiscRegister), "Misc Register", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * HPET - High Precision Event Timer table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoHpet[] =
+{
+ {ACPI_DMT_UINT32, ACPI_HPET_OFFSET (Id), "Hardware Block ID", 0},
+ {ACPI_DMT_GAS, ACPI_HPET_OFFSET (Address), "Timer Block Register", 0},
+ {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Sequence), "Sequence Number", 0},
+ {ACPI_DMT_UINT16, ACPI_HPET_OFFSET (MinimumTick), "Minimum Clock Ticks", 0},
+ {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_HPET_FLAG_OFFSET (Flags,0), "4K Page Protect", 0},
+ {ACPI_DMT_FLAG1, ACPI_HPET_FLAG_OFFSET (Flags,0), "64K Page Protect", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * IORT - IO Remapping Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IORT_OFFSET (NodeCount), "Node Count", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT_OFFSET (NodeOffset), "Node Offset", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Optional padding field */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIortPad[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "Optional Padding", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIortHdr[] =
+{
+ {ACPI_DMT_UINT8, ACPI_IORTH_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_UINT16, ACPI_IORTH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_IORTH_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTH_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTH_OFFSET (MappingCount), "Mapping Count", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTH_OFFSET (MappingOffset), "Mapping Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIortMap[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IORTM_OFFSET (InputBase), "Input base", DT_OPTIONAL},
+ {ACPI_DMT_UINT32, ACPI_IORTM_OFFSET (IdCount), "ID Count", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTM_OFFSET (OutputBase), "Output Base", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTM_OFFSET (OutputReference), "Output Reference", 0},
+ {ACPI_DMT_UINT32, ACPI_IORTM_OFFSET (Flags), "Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_IORTM_FLAG_OFFSET (Flags, 0), "Single Mapping", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIortAcc[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IORTA_OFFSET (CacheCoherency), "Cache Coherency", 0},
+ {ACPI_DMT_UINT8, ACPI_IORTA_OFFSET (Hints), "Hints (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_IORTA_FLAG_OFFSET (Hints, 0), "Transient", 0},
+ {ACPI_DMT_FLAG1, ACPI_IORTA_FLAG_OFFSET (Hints, 0), "Write Allocate", 0},
+ {ACPI_DMT_FLAG2, ACPI_IORTA_FLAG_OFFSET (Hints, 0), "Read Allocate", 0},
+ {ACPI_DMT_FLAG3, ACPI_IORTA_FLAG_OFFSET (Hints, 0), "Override", 0},
+ {ACPI_DMT_UINT16, ACPI_IORTA_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_IORTA_OFFSET (MemoryFlags), "Memory Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_IORTA_FLAG_OFFSET (MemoryFlags, 0), "Coherency", 0},
+ {ACPI_DMT_FLAG1, ACPI_IORTA_FLAG_OFFSET (MemoryFlags, 0), "Device Attribute", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* IORT subtables */
+
+/* 0x00: ITS Group */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort0[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IORT0_OFFSET (ItsCount), "ItsCount", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort0a[] =
+{
+ {ACPI_DMT_UINT32, 0, "Identifiers", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0x01: Named Component */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IORT1_OFFSET (NodeFlags), "Node Flags", 0},
+ {ACPI_DMT_IORTMEM, ACPI_IORT1_OFFSET (MemoryProperties), "Memory Properties", 0},
+ {ACPI_DMT_UINT8, ACPI_IORT1_OFFSET (MemoryAddressLimit), "Memory Size Limit", 0},
+ {ACPI_DMT_STRING, ACPI_IORT1_OFFSET (DeviceName[0]), "Device Name", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort1a[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "Padding", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0x02: PCI Root Complex */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort2[] =
+{
+ {ACPI_DMT_IORTMEM, ACPI_IORT2_OFFSET (MemoryProperties), "Memory Properties", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT2_OFFSET (AtsAttribute), "ATS Attribute", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT2_OFFSET (PciSegmentNumber), "PCI Segment Number", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0x03: SMMUv1/2 */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort3[] =
+{
+ {ACPI_DMT_UINT64, ACPI_IORT3_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_IORT3_OFFSET (Span), "Span", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (Model), "Model", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (Flags), "Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_IORT3_FLAG_OFFSET (Flags, 0), "DVM Supported", 0},
+ {ACPI_DMT_FLAG1, ACPI_IORT3_FLAG_OFFSET (Flags, 0), "Coherent Walk", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (GlobalInterruptOffset), "Global Interrupt Offset", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (ContextInterruptCount), "Context Interrupt Count", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (ContextInterruptOffset), "Context Interrupt Offset", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (PmuInterruptCount), "PMU Interrupt Count", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT3_OFFSET (PmuInterruptOffset), "PMU Interrupt Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort3a[] =
+{
+ {ACPI_DMT_UINT64, 0, "SMMU_NSgIrpt Interrupt", 0},
+ {ACPI_DMT_UINT64, 0, "SMMU_NSgCfgIrpt Interrupt", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort3b[] =
+{
+ {ACPI_DMT_UINT64, 0, "Context Interrupt", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIort3c[] =
+{
+ {ACPI_DMT_UINT64, 0, "PMU Interrupt", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * IVRS - I/O Virtualization Reporting Structure
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs[] =
+{
+ {ACPI_DMT_UINT32, ACPI_IVRS_OFFSET (Info), "Virtualization Info", 0},
+ {ACPI_DMT_UINT64, ACPI_IVRS_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrsHdr[] =
+{
+ {ACPI_DMT_IVRS, ACPI_IVRSH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_IVRSH_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (DeviceId), "DeviceId", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* IVRS subtables */
+
+/* 0x10: I/O Virtualization Hardware Definition (IVHD) Block */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs0[] =
+{
+ {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (CapabilityOffset), "Capability Offset", 0},
+ {ACPI_DMT_UINT64, ACPI_IVRS0_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (PciSegmentGroup), "PCI Segment Group", 0},
+ {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (Info), "Virtualization Info", 0},
+ {ACPI_DMT_UINT32, ACPI_IVRS0_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition (IVMD) Block */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs1[] =
+{
+ {ACPI_DMT_UINT16, ACPI_IVRS1_OFFSET (AuxData), "Auxiliary Data", 0},
+ {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (StartAddress), "Start Address", 0},
+ {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (MemoryLength), "Memory Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Device entry header for IVHD block */
+
+#define ACPI_DMT_IVRS_DE_HEADER \
+ {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (Type), "Entry Type", 0}, \
+ {ACPI_DMT_UINT16, ACPI_IVRSD_OFFSET (Id), "Device ID", 0}, \
+ {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (DataSetting), "Data Setting", 0}
+
+/* 4-byte device entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs4[] =
+{
+ ACPI_DMT_IVRS_DE_HEADER,
+ {ACPI_DMT_EXIT, 0, NULL, 0},
+};
+
+/* 8-byte device entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8a[] =
+{
+ ACPI_DMT_IVRS_DE_HEADER,
+ {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved1), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_IVRS8A_OFFSET (UsedId), "Source Used Device ID", 0},
+ {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 8-byte device entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8b[] =
+{
+ ACPI_DMT_IVRS_DE_HEADER,
+ {ACPI_DMT_UINT32, ACPI_IVRS8B_OFFSET (ExtendedData), "Extended Data", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 8-byte device entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8c[] =
+{
+ ACPI_DMT_IVRS_DE_HEADER,
+ {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Handle), "Handle", 0},
+ {ACPI_DMT_UINT16, ACPI_IVRS8C_OFFSET (UsedId), "Source Used Device ID", 0},
+ {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Variety), "Variety", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * LPIT - Low Power Idle Table
+ *
+ ******************************************************************************/
+
+/* Main table consists only of the standard ACPI table header */
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoLpitHdr[] =
+{
+ {ACPI_DMT_LPIT, ACPI_LPITH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT32, ACPI_LPITH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_LPITH_OFFSET (UniqueId), "Unique ID", 0},
+ {ACPI_DMT_UINT16, ACPI_LPITH_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_LPITH_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_LPITH_FLAG_OFFSET (Flags, 0), "State Disabled", 0},
+ {ACPI_DMT_FLAG1, ACPI_LPITH_FLAG_OFFSET (Flags, 0), "No Counter", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* LPIT Subtables */
+
+/* 0: Native C-state */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoLpit0[] =
+{
+ {ACPI_DMT_GAS, ACPI_LPIT0_OFFSET (EntryTrigger), "Entry Trigger", 0},
+ {ACPI_DMT_UINT32, ACPI_LPIT0_OFFSET (Residency), "Residency", 0},
+ {ACPI_DMT_UINT32, ACPI_LPIT0_OFFSET (Latency), "Latency", 0},
+ {ACPI_DMT_GAS, ACPI_LPIT0_OFFSET (ResidencyCounter), "Residency Counter", 0},
+ {ACPI_DMT_UINT64, ACPI_LPIT0_OFFSET (CounterFrequency), "Counter Frequency", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * MADT - Multiple APIC Description Table and subtables
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt[] =
+{
+ {ACPI_DMT_UINT32, ACPI_MADT_OFFSET (Address), "Local Apic Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT_FLAG_OFFSET (Flags,0), "PC-AT Compatibility", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadtHdr[] =
+{
+ {ACPI_DMT_MADT, ACPI_MADTH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_MADTH_OFFSET (Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* MADT Subtables */
+
+/* 0: processor APIC */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT0_OFFSET (ProcessorId), "Processor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT0_OFFSET (Id), "Local Apic ID", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT0_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT0_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: IO APIC */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt1[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT1_OFFSET (Id), "I/O Apic ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT1_OFFSET (Address), "Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT1_OFFSET (GlobalIrqBase), "Interrupt", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: Interrupt Override */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt2[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT2_OFFSET (Bus), "Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT2_OFFSET (SourceIrq), "Source", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT2_OFFSET (GlobalIrq), "Interrupt", 0},
+ {ACPI_DMT_UINT16, ACPI_MADT2_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAGS0, ACPI_MADT2_FLAG_OFFSET (IntiFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAGS2, ACPI_MADT2_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 3: NMI Sources */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt3[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT3_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAGS0, ACPI_MADT3_FLAG_OFFSET (IntiFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAGS2, ACPI_MADT3_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT3_OFFSET (GlobalIrq), "Interrupt", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 4: Local APIC NMI */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt4[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT4_OFFSET (ProcessorId), "Processor ID", 0},
+ {ACPI_DMT_UINT16, ACPI_MADT4_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAGS0, ACPI_MADT4_FLAG_OFFSET (IntiFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAGS2, ACPI_MADT4_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT4_OFFSET (Lint), "Interrupt Input LINT", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 5: Address Override */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt5[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT5_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT5_OFFSET (Address), "APIC Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 6: I/O Sapic */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt6[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT6_OFFSET (Id), "I/O Sapic ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT6_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT6_OFFSET (GlobalIrqBase), "Interrupt Base", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT6_OFFSET (Address), "Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 7: Local Sapic */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt7[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (ProcessorId), "Processor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (Id), "Local Sapic ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (Eid), "Local Sapic EID", 0},
+ {ACPI_DMT_UINT24, ACPI_MADT7_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT7_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT7_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT7_OFFSET (Uid), "Processor UID", 0},
+ {ACPI_DMT_STRING, ACPI_MADT7_OFFSET (UidString[0]), "Processor UID String", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 8: Platform Interrupt Source */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt8[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT8_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAGS0, ACPI_MADT8_FLAG_OFFSET (IntiFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAGS2, ACPI_MADT8_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Type), "InterruptType", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Id), "Processor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Eid), "Processor EID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (IoSapicVector), "I/O Sapic Vector", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT8_OFFSET (GlobalIrq), "Interrupt", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT8_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT8_OFFSET (Flags), "CPEI Override", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 9: Processor Local X2_APIC (ACPI 4.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt9[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT9_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (LocalApicId), "Processor x2Apic ID", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT9_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (Uid), "Processor UID", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 10: Local X2_APIC NMI (ACPI 4.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT10_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAGS0, ACPI_MADT10_FLAG_OFFSET (IntiFlags,0), "Polarity", 0},
+ {ACPI_DMT_FLAGS2, ACPI_MADT10_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT10_OFFSET (Uid), "Processor UID", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT10_OFFSET (Lint), "Interrupt Input LINT", 0},
+ {ACPI_DMT_UINT24, ACPI_MADT10_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 11: Generic Interrupt Controller (ACPI 5.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt11[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT11_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (CpuInterfaceNumber), "CPU Interface Number", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Uid), "Processor UID", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT11_FLAG_OFFSET (Flags,0), "Processor Enabled", 0},
+ {ACPI_DMT_FLAG1, ACPI_MADT11_FLAG_OFFSET (Flags,0), "Performance Interrupt Trigger Mode", 0},
+ {ACPI_DMT_FLAG2, ACPI_MADT11_FLAG_OFFSET (Flags,0), "Virtual GIC Interrupt Trigger Mode", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (ParkingVersion), "Parking Protocol Version", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (PerformanceInterrupt), "Performance Interrupt", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (ParkedAddress), "Parked Address", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (GicvBaseAddress), "Virtual GIC Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (GichBaseAddress), "Hypervisor GIC Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (VgicInterrupt), "Virtual GIC Interrupt", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (GicrBaseAddress), "Redistributor Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (ArmMpidr), "ARM MPIDR", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT11_OFFSET (EfficiencyClass), "Efficiency Class", 0},
+ {ACPI_DMT_UINT24, ACPI_MADT11_OFFSET (Reserved2[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 12: Generic Interrupt Distributor (ACPI 5.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt12[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT12_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GicId), "Local GIC Hardware ID", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT12_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GlobalIrqBase), "Interrupt Base", 0},
+ {ACPI_DMT_UINT8, ACPI_MADT12_OFFSET (Version), "Version", 0},
+ {ACPI_DMT_UINT24, ACPI_MADT12_OFFSET (Reserved2[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 13: Generic MSI Frame (ACPI 5.1) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt13[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT13_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT13_OFFSET (MsiFrameId), "MSI Frame ID", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT13_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT13_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MADT13_FLAG_OFFSET (Flags,0), "Select SPI", 0},
+ {ACPI_DMT_UINT16, ACPI_MADT13_OFFSET (SpiCount), "SPI Count", 0},
+ {ACPI_DMT_UINT16, ACPI_MADT13_OFFSET (SpiBase), "SPI Base", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 14: Generic Redistributor (ACPI 5.1) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt14[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT14_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT14_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT14_OFFSET (Length), "Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 15: Generic Translator (ACPI 6.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMadt15[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MADT15_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT15_OFFSET (TranslationId), "Translation ID", 0},
+ {ACPI_DMT_UINT64, ACPI_MADT15_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT32, ACPI_MADT15_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/*******************************************************************************
+ *
+ * MCFG - PCI Memory Mapped Configuration table and Subtable
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg[] =
+{
+ {ACPI_DMT_UINT64, ACPI_MCFG_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[] =
+{
+ {ACPI_DMT_UINT64, ACPI_MCFG0_OFFSET (Address), "Base Address", 0},
+ {ACPI_DMT_UINT16, ACPI_MCFG0_OFFSET (PciSegment), "Segment Group Number", 0},
+ {ACPI_DMT_UINT8, ACPI_MCFG0_OFFSET (StartBusNumber), "Start Bus Number", 0},
+ {ACPI_DMT_UINT8, ACPI_MCFG0_OFFSET (EndBusNumber), "End Bus Number", 0},
+ {ACPI_DMT_UINT32, ACPI_MCFG0_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * MCHI - Management Controller Host Interface table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterfaceType), "Interface Type", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Protocol), "Protocol", 0},
+ {ACPI_DMT_UINT64, ACPI_MCHI_OFFSET (ProtocolData), "Protocol Data", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterruptType), "Interrupt Type", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Gpe), "Gpe", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDeviceFlag), "Pci Device Flag", 0},
+ {ACPI_DMT_UINT32, ACPI_MCHI_OFFSET (GlobalInterrupt), "Global Interrupt", 0},
+ {ACPI_DMT_GAS, ACPI_MCHI_OFFSET (ControlRegister), "Control Register", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciSegment), "Pci Segment", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciBus), "Pci Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDevice), "Pci Device", 0},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciFunction), "Pci Function", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * MPST - Memory Power State Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MPST_OFFSET (ChannelId), "Channel ID", 0},
+ {ACPI_DMT_UINT24, ACPI_MPST_OFFSET (Reserved1[0]), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_MPST_OFFSET (PowerNodeCount), "Power Node Count", 0},
+ {ACPI_DMT_UINT16, ACPI_MPST_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* MPST subtables */
+
+/* 0: Memory Power Node Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Node Enabled", 0},
+ {ACPI_DMT_FLAG1, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Power Managed", 0},
+ {ACPI_DMT_FLAG2, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Hot Plug Capable", 0},
+
+ {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Reserved1), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_MPST0_OFFSET (NodeId), "Node ID", 0},
+ {ACPI_DMT_UINT32, ACPI_MPST0_OFFSET (Length), "Length", 0},
+ {ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeAddress), "Range Address", 0},
+ {ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeLength), "Range Length", 0},
+ {ACPI_DMT_UINT32, ACPI_MPST0_OFFSET (NumPowerStates), "Num Power States", 0},
+ {ACPI_DMT_UINT32, ACPI_MPST0_OFFSET (NumPhysicalComponents), "Num Physical Components", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0A: Sub-subtable - Memory Power State Structure (follows Memory Power Node above) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0A[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (PowerState), "Power State", 0},
+ {ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (InfoIndex), "InfoIndex", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0B: Sub-subtable - Physical Component ID Structure (follows Memory Power State(s) above) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0B[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MPST0B_OFFSET (ComponentId), "Component Id", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 01: Power Characteristics Count (follows all Power Node(s) above) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst1[] =
+{
+ {ACPI_DMT_UINT16, ACPI_MPST1_OFFSET (CharacteristicsCount), "Characteristics Count", 0},
+ {ACPI_DMT_UINT16, ACPI_MPST1_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 02: Memory Power State Characteristics Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMpst2[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (StructureId), "Structure ID", 0},
+ {ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Memory Preserved", 0},
+ {ACPI_DMT_FLAG1, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Entry", 0},
+ {ACPI_DMT_FLAG2, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Exit", 0},
+
+ {ACPI_DMT_UINT16, ACPI_MPST2_OFFSET (Reserved1), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (AveragePower), "Average Power", 0},
+ {ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (PowerSaving), "Power Saving", 0},
+ {ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (ExitLatency), "Exit Latency", 0},
+ {ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * MSCT - Maximum System Characteristics Table (ACPI 4.0)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[] =
+{
+ {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (ProximityOffset), "Proximity Offset", 0},
+ {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxProximityDomains), "Max Proximity Domains", 0},
+ {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxClockDomains), "Max Clock Domains", 0},
+ {ACPI_DMT_UINT64, ACPI_MSCT_OFFSET (MaxAddress), "Max Physical Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Subtable - Maximum Proximity Domain Information. Version 1 */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Revision), "Revision", 0},
+ {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeStart), "Domain Range Start", 0},
+ {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeEnd), "Domain Range End", 0},
+ {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (ProcessorCapacity), "Processor Capacity", 0},
+ {ACPI_DMT_UINT64, ACPI_MSCT0_OFFSET (MemoryCapacity), "Memory Capacity", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * MTMR - MID Timer Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMtmr[] =
+{
+ ACPI_DMT_TERMINATOR
+};
+
+/* MTMR Subtables - MTMR Entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMtmr0[] =
+{
+ {ACPI_DMT_GAS, ACPI_MTMR0_OFFSET (PhysicalAddress), "PhysicalAddress", 0},
+ {ACPI_DMT_UINT32, ACPI_MTMR0_OFFSET (Frequency), "Frequency", 0},
+ {ACPI_DMT_UINT32, ACPI_MTMR0_OFFSET (Irq), "IRQ", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * NFIT - NVDIMM Firmware Interface Table and Subtables - (ACPI 6.0)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit[] =
+{
+ {ACPI_DMT_UINT32, ACPI_NFIT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfitHdr[] =
+{
+ {ACPI_DMT_NFIT, ACPI_NFITH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT16, ACPI_NFITH_OFFSET (Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0: System Physical Address Range Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit0[] =
+{
+ {ACPI_DMT_UINT16, ACPI_NFIT0_OFFSET (RangeIndex), "Range Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_NFIT0_FLAG_OFFSET (Flags,0), "Add/Online Operation Only", 0},
+ {ACPI_DMT_FLAG1, ACPI_NFIT0_FLAG_OFFSET (Flags,0), "Proximity Domain Valid", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT0_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ {ACPI_DMT_UUID, ACPI_NFIT0_OFFSET (RangeGuid[0]), "Address Range GUID", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (Address), "Address Range Base", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (Length), "Address Range Length", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (MemoryMapping), "Memory Map Attribute", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: Memory Device to System Address Range Map Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_NFIT1_OFFSET (DeviceHandle), "Device Handle", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (PhysicalId), "Physical Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (RegionId), "Region Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (RangeIndex), "Range Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (RegionIndex), "Control Region Index", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT1_OFFSET (RegionSize), "Region Size", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT1_OFFSET (RegionOffset), "Region Offset", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT1_OFFSET (Address), "Address Region Base", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (InterleaveIndex), "Interleave Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (InterleaveWays), "Interleave Ways", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (Flags), "Flags", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Save to device failed", 0},
+ {ACPI_DMT_FLAG1, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Restore from device failed", 0},
+ {ACPI_DMT_FLAG2, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Platform flush failed", 0},
+ {ACPI_DMT_FLAG3, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Device not armed", 0},
+ {ACPI_DMT_FLAG4, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Health events observed", 0},
+ {ACPI_DMT_FLAG5, ACPI_NFIT1_FLAG_OFFSET (Flags,0), "Health events enabled", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT1_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: Interleave Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit2[] =
+{
+ {ACPI_DMT_UINT16, ACPI_NFIT2_OFFSET (InterleaveIndex), "Interleave Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT2_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT2_OFFSET (LineCount), "Line Count", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT2_OFFSET (LineSize), "Line Size", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit2a[] =
+{
+ {ACPI_DMT_UINT32, 0, "Line Offset", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 3: SMBIOS Management Information Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit3[] =
+{
+ {ACPI_DMT_UINT32, ACPI_NFIT3_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit3a[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "SMBIOS Table Entries", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 4: NVDIMM Control Region Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit4[] =
+{
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (RegionIndex), "Region Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (VendorId), "Vendor Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (DeviceId), "Device Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (RevisionId), "Revision Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (SubsystemVendorId), "Subsystem Vendor Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (SubsystemDeviceId), "Subsystem Device Id", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (SubsystemRevisionId), "Subsystem Revision Id", 0},
+ {ACPI_DMT_UINT48, ACPI_NFIT4_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT4_OFFSET (SerialNumber), "Serial Number", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (Code), "Code", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (Windows), "Window Count", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT4_OFFSET (WindowSize), "Window Size", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT4_OFFSET (CommandOffset), "Command Offset", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT4_OFFSET (CommandSize), "Command Size", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT4_OFFSET (StatusOffset), "Status Offset", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT4_OFFSET (StatusSize), "Status Size", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT4_OFFSET (Flags), "Flags", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_NFIT4_FLAG_OFFSET (Flags,0), "Windows buffered", 0},
+ {ACPI_DMT_UINT48, ACPI_NFIT4_OFFSET (Reserved1[0]), "Reserved1", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 5: NVDIMM Block Data Window Region Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit5[] =
+{
+ {ACPI_DMT_UINT16, ACPI_NFIT5_OFFSET (RegionIndex), "Region Index", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT5_OFFSET (Windows), "Window Count", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT5_OFFSET (Offset), "Offset", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT5_OFFSET (Size), "Size", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT5_OFFSET (Capacity), "Capacity", 0},
+ {ACPI_DMT_UINT64, ACPI_NFIT5_OFFSET (StartAddress), "Start Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 6: Flush Hint Address Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6[] =
+{
+ {ACPI_DMT_UINT32, ACPI_NFIT6_OFFSET (DeviceHandle), "Device Handle", 0},
+ {ACPI_DMT_UINT16, ACPI_NFIT6_OFFSET (HintCount), "Hint Count", 0},
+ {ACPI_DMT_UINT48, ACPI_NFIT6_OFFSET (Reserved[0]), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6a[] =
+{
+ {ACPI_DMT_UINT64, 0, "Hint Address", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * PCCT - Platform Communications Channel Table (ACPI 5.0)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPcct[] =
+{
+ {ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_PCCT_FLAG_OFFSET (Flags,0), "Doorbell", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* PCCT subtables */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPcctHdr[] =
+{
+ {ACPI_DMT_PCCT, ACPI_PCCT0_OFFSET (Header.Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_PCCT0_OFFSET (Header.Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0: Generic Communications Subspace */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPcct0[] =
+{
+ {ACPI_DMT_UINT48, ACPI_PCCT0_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (Length), "Address Length", 0},
+ {ACPI_DMT_GAS, ACPI_PCCT0_OFFSET (DoorbellRegister), "Doorbell Register", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (PreserveMask), "Preserve Mask", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (WriteMask), "Write Mask", 0},
+ {ACPI_DMT_UINT32, ACPI_PCCT0_OFFSET (Latency), "Command Latency", 0},
+ {ACPI_DMT_UINT32, ACPI_PCCT0_OFFSET (MaxAccessRate), "Maximum Access Rate", 0},
+ {ACPI_DMT_UINT16, ACPI_PCCT0_OFFSET (MinTurnaroundTime), "Minimum Turnaround Time", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: HW-reduced Communications Subspace (ACPI 5.1) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPcct1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_PCCT1_OFFSET (DoorbellInterrupt), "Doorbell Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_PCCT1_OFFSET (Flags), "Flags (Decoded Below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_PCCT1_FLAG_OFFSET (Flags,0), "Polarity", 0},
+ {ACPI_DMT_FLAG1, ACPI_PCCT1_FLAG_OFFSET (Flags,0), "Mode", 0},
+ {ACPI_DMT_UINT8, ACPI_PCCT1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT1_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT1_OFFSET (Length), "Address Length", 0},
+ {ACPI_DMT_GAS, ACPI_PCCT1_OFFSET (DoorbellRegister), "Doorbell Register", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT1_OFFSET (PreserveMask), "Preserve Mask", 0},
+ {ACPI_DMT_UINT64, ACPI_PCCT1_OFFSET (WriteMask), "Write Mask", 0},
+ {ACPI_DMT_UINT32, ACPI_PCCT1_OFFSET (Latency), "Command Latency", 0},
+ {ACPI_DMT_UINT32, ACPI_PCCT1_OFFSET (MaxAccessRate), "Maximum Access Rate", 0},
+ {ACPI_DMT_UINT16, ACPI_PCCT1_OFFSET (MinTurnaroundTime), "Minimum Turnaround Time", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * PMTT - Platform Memory Topology Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[] =
+{
+ {ACPI_DMT_UINT32, ACPI_PMTT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmttHdr[] =
+{
+ {ACPI_DMT_PMTT, ACPI_PMTTH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_PMTTH_OFFSET (Reserved1), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Top-level Device", 0},
+ {ACPI_DMT_FLAG1, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Physical Element", 0},
+ {ACPI_DMT_FLAGS2, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Memory Type", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* PMTT Subtables */
+
+/* 0: Socket */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[] =
+{
+ {ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (SocketId), "Socket ID", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: Memory Controller */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadLatency), "Read Latency", 0},
+ {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteLatency), "Write Latency", 0},
+ {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadBandwidth), "Read Bandwidth", 0},
+ {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteBandwidth), "Write Bandwidth", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (AccessWidth), "Access Width", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Alignment), "Alignment", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (DomainCount), "Domain Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1a: Proximity Domain */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1a[] =
+{
+ {ACPI_DMT_UINT32, ACPI_PMTT1A_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: Physical Component */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[] =
+{
+ {ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (ComponentId), "Component ID", 0},
+ {ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (MemorySize), "Memory Size", 0},
+ {ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (BiosHandle), "Bios Handle", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * S3PT - S3 Performance Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt[] =
+{
+ {ACPI_DMT_SIG, ACPI_S3PT_OFFSET (Signature[0]), "Signature", 0},
+ {ACPI_DMT_UINT32, ACPI_S3PT_OFFSET (Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* S3PT subtable header */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoS3ptHdr[] =
+{
+ {ACPI_DMT_UINT16, ACPI_S3PTH_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Length), "Length", DT_LENGTH},
+ {ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Revision), "Revision", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 0: Basic S3 Resume Performance Record */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[] =
+{
+ {ACPI_DMT_UINT32, ACPI_S3PT0_OFFSET (ResumeCount), "Resume Count", 0},
+ {ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (FullResume), "Full Resume", 0},
+ {ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (AverageResume), "Average Resume", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: Basic S3 Suspend Performance Record */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[] =
+{
+ {ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendStart), "Suspend Start", 0},
+ {ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendEnd), "Suspend End", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SBST - Smart Battery Specification Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[] =
+{
+ {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (WarningLevel), "Warning Level", 0},
+ {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (LowLevel), "Low Level", 0},
+ {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (CriticalLevel), "Critical Level", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SLIC - Software Licensing Description Table. This table contains the standard
+ * ACPI header followed by proprietary data structures
+ *
+ ******************************************************************************/
+
+/* Single subtable, a proprietary format, so treat it as a buffer */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSlic[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "Software Licensing Structure", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SLIT - System Locality Information Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSlit[] =
+{
+ {ACPI_DMT_UINT64, ACPI_SLIT_OFFSET (LocalityCount), "Localities", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SPCR - Serial Port Console Redirection table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[] =
+{
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (InterfaceType), "Interface Type", 0},
+ {ACPI_DMT_UINT24, ACPI_SPCR_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_SPCR_OFFSET (SerialPort), "Serial Port Register", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (InterruptType), "Interrupt Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PcInterrupt), "PCAT-compatible IRQ", 0},
+ {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (Interrupt), "Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (BaudRate), "Baud Rate", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (Parity), "Parity", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (StopBits), "Stop Bits", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (FlowControl), "Flow Control", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (TerminalType), "Terminal Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (Reserved2), "Reserved", 0},
+ {ACPI_DMT_UINT16, ACPI_SPCR_OFFSET (PciDeviceId), "PCI Device ID", 0},
+ {ACPI_DMT_UINT16, ACPI_SPCR_OFFSET (PciVendorId), "PCI Vendor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciBus), "PCI Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciDevice), "PCI Device", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciFunction), "PCI Function", 0},
+ {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (PciFlags), "PCI Flags", 0},
+ {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciSegment), "PCI Segment", 0},
+ {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SPMI - Server Platform Management Interface table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSpmi[] =
+{
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterfaceType), "Interface Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved), "Reserved", DT_NON_ZERO}, /* Value must be 1 */
+ {ACPI_DMT_UINT16, ACPI_SPMI_OFFSET (SpecRevision), "IPMI Spec Version", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterruptType), "Interrupt Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (GpeNumber), "GPE Number", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved1), "Reserved", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciDeviceFlag), "PCI Device Flag", 0},
+ {ACPI_DMT_UINT32, ACPI_SPMI_OFFSET (Interrupt), "Interrupt", 0},
+ {ACPI_DMT_GAS, ACPI_SPMI_OFFSET (IpmiRegister), "IPMI Register", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciSegment), "PCI Segment", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciBus), "PCI Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciDevice), "PCI Device", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciFunction), "PCI Function", 0},
+ {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SRAT - System Resource Affinity Table and Subtables
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSrat[] =
+{
+ {ACPI_DMT_UINT32, ACPI_SRAT_OFFSET (TableRevision), "Table Revision", 0},
+ {ACPI_DMT_UINT64, ACPI_SRAT_OFFSET (Reserved), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSratHdr[] =
+{
+ {ACPI_DMT_SRAT, ACPI_SRATH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SRATH_OFFSET (Length), "Length", DT_LENGTH},
+ ACPI_DMT_TERMINATOR
+};
+
+/* SRAT Subtables */
+
+/* 0: Processor Local APIC/SAPIC Affinity */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSrat0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (ProximityDomainLo), "Proximity Domain Low(8)", 0},
+ {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (ApicId), "Apic ID", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_SRAT0_FLAG_OFFSET (Flags,0), "Enabled", 0},
+ {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (LocalSapicEid), "Local Sapic EID", 0},
+ {ACPI_DMT_UINT24, ACPI_SRAT0_OFFSET (ProximityDomainHi[0]), "Proximity Domain High(24)", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT0_OFFSET (ClockDomain), "Clock Domain", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: Memory Affinity */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSrat1[] =
+{
+ {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ {ACPI_DMT_UINT16, ACPI_SRAT1_OFFSET (Reserved), "Reserved1", 0},
+ {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (BaseAddress), "Base Address", 0},
+ {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (Length), "Address Length", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (Reserved1), "Reserved2", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Enabled", 0},
+ {ACPI_DMT_FLAG1, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Hot Pluggable", 0},
+ {ACPI_DMT_FLAG2, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Non-Volatile", 0},
+ {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (Reserved2), "Reserved3", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[] =
+{
+ {ACPI_DMT_UINT16, ACPI_SRAT2_OFFSET (Reserved), "Reserved1", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ApicId), "Apic ID", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_SRAT2_FLAG_OFFSET (Flags,0), "Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ClockDomain), "Clock Domain", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Reserved2), "Reserved2", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* : GICC Affinity (ACPI 5.1) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSrat3[] =
+{
+ {ACPI_DMT_UINT32, ACPI_SRAT3_OFFSET (ProximityDomain), "Proximity Domain", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT3_OFFSET (AcpiProcessorUid), "Acpi Processor UID", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT3_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_SRAT3_FLAG_OFFSET (Flags,0), "Enabled", 0},
+ {ACPI_DMT_UINT32, ACPI_SRAT3_OFFSET (ClockDomain), "Clock Domain", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * STAO - Status Override Table (_STA override) - ACPI 6.0
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoStao[] =
+{
+ {ACPI_DMT_UINT8, ACPI_STAO_OFFSET (IgnoreUart), "Ignore UART", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoStaoStr[] =
+{
+ {ACPI_DMT_STRING, 0, "Namepath", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * TCPA - Trusted Computing Platform Alliance table (Client)
+ *
+ * NOTE: There are two versions of the table with the same signature --
+ * the client version and the server version. The common PlatformClass
+ * field is used to differentiate the two types of tables.
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaHdr[] =
+{
+ {ACPI_DMT_UINT16, ACPI_TCPA_OFFSET (PlatformClass), "Platform Class", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaClient[] =
+{
+ {ACPI_DMT_UINT32, ACPI_TCPA_CLIENT_OFFSET (MinimumLogLength), "Min Event Log Length", 0},
+ {ACPI_DMT_UINT64, ACPI_TCPA_CLIENT_OFFSET (LogAddress), "Event Log Address", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaServer[] =
+{
+ {ACPI_DMT_UINT16, ACPI_TCPA_SERVER_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_TCPA_SERVER_OFFSET (MinimumLogLength), "Min Event Log Length", 0},
+ {ACPI_DMT_UINT64, ACPI_TCPA_SERVER_OFFSET (LogAddress), "Event Log Address", 0},
+ {ACPI_DMT_UINT16, ACPI_TCPA_SERVER_OFFSET (SpecRevision), "Specification Revision", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (DeviceFlags), "Device Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_TCPA_SERVER_OFFSET (DeviceFlags), "Pci Device", 0},
+ {ACPI_DMT_FLAG1, ACPI_TCPA_SERVER_OFFSET (DeviceFlags), "Bus is Pnp", 0},
+ {ACPI_DMT_FLAG2, ACPI_TCPA_SERVER_OFFSET (DeviceFlags), "Address Valid", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (InterruptFlags), "Interrupt Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_TCPA_SERVER_OFFSET (InterruptFlags), "Mode", 0},
+ {ACPI_DMT_FLAG1, ACPI_TCPA_SERVER_OFFSET (InterruptFlags), "Polarity", 0},
+ {ACPI_DMT_FLAG2, ACPI_TCPA_SERVER_OFFSET (InterruptFlags), "GPE SCI Triggered", 0},
+ {ACPI_DMT_FLAG3, ACPI_TCPA_SERVER_OFFSET (InterruptFlags), "Global System Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (GpeNumber), "Gpe Number", 0},
+ {ACPI_DMT_UINT24, ACPI_TCPA_SERVER_OFFSET (Reserved2[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_TCPA_SERVER_OFFSET (GlobalInterrupt), "Global Interrupt", 0},
+ {ACPI_DMT_GAS, ACPI_TCPA_SERVER_OFFSET (Address), "Address", 0},
+ {ACPI_DMT_UINT32, ACPI_TCPA_SERVER_OFFSET (Reserved3), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_TCPA_SERVER_OFFSET (ConfigAddress), "Configuration Address", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (Group), "Pci Group", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (Bus), "Pci Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (Device), "Pci Device", 0},
+ {ACPI_DMT_UINT8, ACPI_TCPA_SERVER_OFFSET (Function), "Pci Function", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[] =
+{
+ {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (PlatformClass), "Platform Class", 0},
+ {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT64, ACPI_TPM2_OFFSET (ControlAddress), "Control Address", 0},
+ {ACPI_DMT_UINT32, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * UEFI - UEFI Boot optimization Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[] =
+{
+ {ACPI_DMT_UUID, ACPI_UEFI_OFFSET (Identifier[0]), "UUID Identifier", 0},
+ {ACPI_DMT_UINT16, ACPI_UEFI_OFFSET (DataOffset), "Data Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * VRTC - Virtual Real Time Clock Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc[] =
+{
+ ACPI_DMT_TERMINATOR
+};
+
+/* VRTC Subtables - VRTC Entry */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc0[] =
+{
+ {ACPI_DMT_GAS, ACPI_VRTC0_OFFSET (PhysicalAddress), "PhysicalAddress", 0},
+ {ACPI_DMT_UINT32, ACPI_VRTC0_OFFSET (Irq), "IRQ", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * WAET - Windows ACPI Emulated devices Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWaet[] =
+{
+ {ACPI_DMT_UINT32, ACPI_WAET_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_WAET_OFFSET (Flags), "RTC needs no INT ack", 0},
+ {ACPI_DMT_FLAG1, ACPI_WAET_OFFSET (Flags), "PM timer, one read only", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * WDAT - Watchdog Action Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWdat[] =
+{
+ {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (HeaderLength), "Header Length", DT_LENGTH},
+ {ACPI_DMT_UINT16, ACPI_WDAT_OFFSET (PciSegment), "PCI Segment", 0},
+ {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciBus), "PCI Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciDevice), "PCI Device", 0},
+ {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciFunction), "PCI Function", 0},
+ {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (TimerPeriod), "Timer Period", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MaxCount), "Max Count", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MinCount), "Min Count", 0},
+ {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_WDAT_OFFSET (Flags), "Enabled", 0},
+ {ACPI_DMT_FLAG7, ACPI_WDAT_OFFSET (Flags), "Stopped When Asleep", 0},
+ {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved2[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (Entries), "Watchdog Entry Count", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* WDAT Subtables - Watchdog Instruction Entries */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWdat0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Action), "Watchdog Action", 0},
+ {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Instruction), "Instruction", 0},
+ {ACPI_DMT_UINT16, ACPI_WDAT0_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_GAS, ACPI_WDAT0_OFFSET (RegisterRegion), "Register Region", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Value), "Value", 0},
+ {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Mask), "Register Mask", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * WDDT - Watchdog Description Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWddt[] =
+{
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (SpecVersion), "Specification Version", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (TableVersion), "Table Version", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (PciVendorId), "PCI Vendor ID", 0},
+ {ACPI_DMT_GAS, ACPI_WDDT_OFFSET (Address), "Timer Register", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (MaxCount), "Max Count", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (MinCount), "Min Count", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Period), "Period", 0},
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Status), "Status (decoded below)", 0},
+
+ /* Status Flags byte 0 */
+
+ {ACPI_DMT_FLAG0, ACPI_WDDT_FLAG_OFFSET (Status,0), "Available", 0},
+ {ACPI_DMT_FLAG1, ACPI_WDDT_FLAG_OFFSET (Status,0), "Active", 0},
+ {ACPI_DMT_FLAG2, ACPI_WDDT_FLAG_OFFSET (Status,0), "OS Owns", 0},
+
+ /* Status Flags byte 1 */
+
+ {ACPI_DMT_FLAG3, ACPI_WDDT_FLAG_OFFSET (Status,1), "User Reset", 0},
+ {ACPI_DMT_FLAG4, ACPI_WDDT_FLAG_OFFSET (Status,1), "Timeout Reset", 0},
+ {ACPI_DMT_FLAG5, ACPI_WDDT_FLAG_OFFSET (Status,1), "Power Fail Reset", 0},
+ {ACPI_DMT_FLAG6, ACPI_WDDT_FLAG_OFFSET (Status,1), "Unknown Reset", 0},
+
+ {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Capability), "Capability (decoded below)", 0},
+
+ /* Capability Flags byte 0 */
+
+ {ACPI_DMT_FLAG0, ACPI_WDDT_FLAG_OFFSET (Capability,0), "Auto Reset", 0},
+ {ACPI_DMT_FLAG1, ACPI_WDDT_FLAG_OFFSET (Capability,0), "Timeout Alert", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * WDRT - Watchdog Resource Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[] =
+{
+ {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (ControlRegister), "Control Register", 0},
+ {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (CountRegister), "Count Register", 0},
+ {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciDeviceId), "PCI Device ID", 0},
+ {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciVendorId), "PCI Vendor ID", 0},
+ {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciBus), "PCI Bus", 0},
+ {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciDevice), "PCI Device", 0},
+ {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciFunction), "PCI Function", 0},
+ {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciSegment), "PCI Segment", 0},
+ {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (MaxCount), "Max Count", 0},
+ {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (Units), "Counter Units", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * WPBT - Windows Platform Environment Table (ACPI 6.0)
+ * Version 1
+ *
+ * Conforms to "Windows Platform Binary Table (WPBT)" 29 November 2011
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWpbt[] =
+{
+ {ACPI_DMT_UINT32, ACPI_WPBT_OFFSET (HandoffSize), "Handoff Size", 0},
+ {ACPI_DMT_UINT64, ACPI_WPBT_OFFSET (HandoffAddress), "Handoff Address", 0},
+ {ACPI_DMT_UINT8, ACPI_WPBT_OFFSET (Layout), "Layout", 0},
+ {ACPI_DMT_UINT8, ACPI_WPBT_OFFSET (Type), "Type", 0},
+ {ACPI_DMT_UINT16, ACPI_WPBT_OFFSET (ArgumentsLength), "Arguments Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoWpbt0[] =
+{
+ {ACPI_DMT_UNICODE, sizeof (ACPI_TABLE_WPBT), "Command-line Arguments", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * XENV - Xen Environment table (ACPI 6.0)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoXenv[] =
+{
+ {ACPI_DMT_UINT64, ACPI_XENV_OFFSET (GrantTableAddress), "Grant Table Address", 0},
+ {ACPI_DMT_UINT64, ACPI_XENV_OFFSET (GrantTableSize), "Grant Table Size", 0},
+ {ACPI_DMT_UINT32, ACPI_XENV_OFFSET (EventInterrupt), "Event Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_XENV_OFFSET (EventFlags), "Event Flags", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*! [Begin] no source code translation */
+
+/*
+ * Generic types (used in UEFI and custom tables)
+ *
+ * Examples:
+ *
+ * Buffer : cc 04 ff bb
+ * UINT8 : 11
+ * UINT16 : 1122
+ * UINT24 : 112233
+ * UINT32 : 11223344
+ * UINT56 : 11223344556677
+ * UINT64 : 1122334455667788
+ *
+ * String : "This is string"
+ * Unicode : "This string encoded to Unicode"
+ *
+ * GUID : 11223344-5566-7788-99aa-bbccddeeff00
+ * DevicePath : "\PciRoot(0)\Pci(0x1f,1)\Usb(0,0)"
+ */
+
+#define ACPI_DM_GENERIC_ENTRY(FieldType, FieldName) \
+ {{FieldType, 0, FieldName, 0}, ACPI_DMT_TERMINATOR}
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2] =
+{
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT8, "UINT8"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT16, "UINT16"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT24, "UINT24"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT32, "UINT32"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT40, "UINT40"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT48, "UINT48"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT56, "UINT56"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT64, "UINT64"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_STRING, "String"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UNICODE, "Unicode"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_BUFFER, "Buffer"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UUID, "GUID"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_STRING, "DevicePath"),
+ ACPI_DM_GENERIC_ENTRY (ACPI_DMT_LABEL, "Label"),
+ {ACPI_DMT_TERMINATOR}
+};
+/*! [End] no source code translation !*/
diff --git a/usr/src/boot/sys/contrib/dev/acpica/common/getopt.c b/usr/src/boot/sys/contrib/dev/acpica/common/getopt.c
new file mode 100644
index 0000000000..4a199c0659
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/common/getopt.c
@@ -0,0 +1,271 @@
+/******************************************************************************
+ *
+ * Module Name: getopt
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 optional single-char sub-options
+ * "f|" - Option has required single-char sub-options
+ */
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/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/boot/sys/contrib/dev/acpica/compiler/aslanalyze.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslanalyze.c
new file mode 100644
index 0000000000..e9b6fb2f6c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslanalyze.c
@@ -0,0 +1,618 @@
+/******************************************************************************
+ *
+ * Module Name: aslanalyze.c - Support functions for parse tree walks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <string.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslanalyze")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnIsInternalMethod
+ *
+ * PARAMETERS: Op - Current op
+ *
+ * RETURN: Boolean
+ *
+ * DESCRIPTION: Check for an internal control method.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AnIsInternalMethod (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
+ (!strcmp (Op->Asl.ExternalName, "_OSI")))
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnGetInternalMethodReturnType
+ *
+ * PARAMETERS: Op - Current op
+ *
+ * RETURN: Btype
+ *
+ * DESCRIPTION: Get the return type of an internal method
+ *
+ ******************************************************************************/
+
+UINT32
+AnGetInternalMethodReturnType (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
+ (!strcmp (Op->Asl.ExternalName, "_OSI")))
+ {
+ return (ACPI_BTYPE_STRING);
+ }
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnCheckId
+ *
+ * PARAMETERS: Op - Current parse op
+ * Type - HID or CID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Perform various checks on _HID and _CID strings. Only limited
+ * checks can be performed on _CID strings.
+ *
+ ******************************************************************************/
+
+void
+AnCheckId (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAME Type)
+{
+ UINT32 i;
+ ACPI_SIZE Length;
+
+
+ /* Only care about string versions of _HID/_CID (integers are legal) */
+
+ if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
+ {
+ return;
+ }
+
+ /* For both _HID and _CID, the string must be non-null */
+
+ Length = strlen (Op->Asl.Value.String);
+ if (!Length)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NULL_STRING,
+ Op, NULL);
+ return;
+ }
+
+ /*
+ * One of the things we want to catch here is the use of a leading
+ * asterisk in the string -- an odd construct that certain platform
+ * manufacturers are fond of. Technically, a leading asterisk is OK
+ * for _CID, but a valid use of this has not been seen.
+ */
+ if (*Op->Asl.Value.String == '*')
+ {
+ AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK,
+ Op, Op->Asl.Value.String);
+ return;
+ }
+
+ /* _CID strings are bus-specific, no more checks can be performed */
+
+ if (Type == ASL_TYPE_CID)
+ {
+ return;
+ }
+
+ /* For _HID, all characters must be alphanumeric */
+
+ for (i = 0; Op->Asl.Value.String[i]; i++)
+ {
+ if (!isalnum ((int) Op->Asl.Value.String[i]))
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
+ Op, Op->Asl.Value.String);
+ return;
+ }
+ }
+
+ /*
+ * _HID String must be one of these forms:
+ *
+ * "AAA####" A is an uppercase letter and # is a hex digit
+ * "ACPI####" # is a hex digit
+ * "NNNN####" N is an uppercase letter or decimal digit (0-9)
+ * # is a hex digit (ACPI 5.0)
+ */
+ if ((Length < 7) || (Length > 8))
+ {
+ AslError (ASL_ERROR, ASL_MSG_HID_LENGTH,
+ Op, Op->Asl.Value.String);
+ return;
+ }
+
+ /* _HID Length is valid (7 or 8), now check the prefix (first 3 or 4 chars) */
+
+ if (Length == 7)
+ {
+ /* AAA####: Ensure the alphabetic prefix is all uppercase */
+
+ for (i = 0; i < 3; i++)
+ {
+ if (!isupper ((int) Op->Asl.Value.String[i]))
+ {
+ AslError (ASL_ERROR, ASL_MSG_UPPER_CASE,
+ Op, &Op->Asl.Value.String[i]);
+ return;
+ }
+ }
+ }
+ else /* Length == 8 */
+ {
+ /*
+ * ACPI#### or NNNN####:
+ * Ensure the prefix contains only uppercase alpha or decimal digits
+ */
+ for (i = 0; i < 4; i++)
+ {
+ if (!isupper ((int) Op->Asl.Value.String[i]) &&
+ !isdigit ((int) Op->Asl.Value.String[i]))
+ {
+ AslError (ASL_ERROR, ASL_MSG_HID_PREFIX,
+ Op, &Op->Asl.Value.String[i]);
+ return;
+ }
+ }
+ }
+
+ /* Remaining characters (suffix) must be hex digits */
+
+ for (; i < Length; i++)
+ {
+ if (!isxdigit ((int) Op->Asl.Value.String[i]))
+ {
+ AslError (ASL_ERROR, ASL_MSG_HID_SUFFIX,
+ Op, &Op->Asl.Value.String[i]);
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnLastStatementIsReturn
+ *
+ * PARAMETERS: Op - A method parse node
+ *
+ * RETURN: TRUE if last statement is an ASL RETURN. False otherwise
+ *
+ * DESCRIPTION: Walk down the list of top level statements within a method
+ * to find the last one. Check if that last statement is in
+ * fact a RETURN statement.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AnLastStatementIsReturn (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Check if last statement is a return */
+
+ Next = ASL_GET_CHILD_NODE (Op);
+ while (Next)
+ {
+ if ((!Next->Asl.Next) &&
+ (Next->Asl.ParseOpcode == PARSEOP_RETURN))
+ {
+ return (TRUE);
+ }
+
+ Next = ASL_GET_PEER_NODE (Next);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnCheckMethodReturnValue
+ *
+ * PARAMETERS: Op - Parent
+ * OpInfo - Parent info
+ * ArgOp - Method invocation op
+ * RequiredBtypes - What caller requires
+ * ThisNodeBtype - What this node returns (if anything)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check a method invocation for 1) A return value and if it does
+ * in fact return a value, 2) check the type of the return value.
+ *
+ ******************************************************************************/
+
+void
+AnCheckMethodReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ const ACPI_OPCODE_INFO *OpInfo,
+ ACPI_PARSE_OBJECT *ArgOp,
+ UINT32 RequiredBtypes,
+ UINT32 ThisNodeBtype)
+{
+ ACPI_PARSE_OBJECT *OwningOp;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ Node = ArgOp->Asl.Node;
+
+
+ /* Examine the parent op of this method */
+
+ OwningOp = Node->Op;
+ if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
+ {
+ /* Method NEVER returns a value */
+
+ AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
+ }
+ else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
+ {
+ /* Method SOMETIMES returns a value, SOMETIMES not */
+
+ AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
+ }
+ else if (!(ThisNodeBtype & RequiredBtypes))
+ {
+ /* Method returns a value, but the type is wrong */
+
+ AnFormatBtype (StringBuffer, ThisNodeBtype);
+ AnFormatBtype (StringBuffer2, RequiredBtypes);
+
+ /*
+ * The case where the method does not return any value at all
+ * was already handled in the namespace cross reference
+ * -- Only issue an error if the method in fact returns a value,
+ * but it is of the wrong type
+ */
+ if (ThisNodeBtype != 0)
+ {
+ sprintf (MsgBuffer,
+ "Method returns [%s], %s operator requires [%s]",
+ StringBuffer, OpInfo->Name, StringBuffer2);
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnIsResultUsed
+ *
+ * PARAMETERS: Op - Parent op for the operator
+ *
+ * RETURN: TRUE if result from this operation is actually consumed
+ *
+ * DESCRIPTION: Determine if the function result value from an operator is
+ * used.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AnIsResultUsed (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Parent;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_INCREMENT:
+ case PARSEOP_DECREMENT:
+
+ /* These are standalone operators, no return value */
+
+ return (TRUE);
+
+ default:
+
+ break;
+ }
+
+ /* Examine parent to determine if the return value is used */
+
+ Parent = Op->Asl.Parent;
+ switch (Parent->Asl.ParseOpcode)
+ {
+ /* If/While - check if the operator is the predicate */
+
+ case PARSEOP_IF:
+ case PARSEOP_WHILE:
+
+ /* First child is the predicate */
+
+ if (Parent->Asl.Child == Op)
+ {
+ return (TRUE);
+ }
+ return (FALSE);
+
+ /* Not used if one of these is the parent */
+
+ case PARSEOP_METHOD:
+ case PARSEOP_DEFINITIONBLOCK:
+ case PARSEOP_ELSE:
+
+ return (FALSE);
+
+ default:
+
+ /* Any other type of parent means that the result is used */
+
+ return (TRUE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForGpeNameConflict
+ *
+ * PARAMETERS: Op - Current parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for a conflict between GPE names within this scope.
+ * Conflict means two GPE names with the same GPE number, but
+ * different types -- such as _L1C and _E1C.
+ *
+ ******************************************************************************/
+
+void
+ApCheckForGpeNameConflict (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 GpeNumber;
+ char Name[ACPI_NAME_SIZE + 1];
+ char Target[ACPI_NAME_SIZE];
+
+
+ /* Need a null-terminated string version of NameSeg */
+
+ ACPI_MOVE_32_TO_32 (Name, &Op->Asl.NameSeg);
+ Name[ACPI_NAME_SIZE] = 0;
+
+ /*
+ * For a GPE method:
+ * 1st char must be underscore
+ * 2nd char must be L or E
+ * 3rd/4th chars must be a hex number
+ */
+ if ((Name[0] != '_') ||
+ ((Name[1] != 'L') && (Name[1] != 'E')))
+ {
+ return;
+ }
+
+ /* Verify 3rd/4th chars are a valid hex value */
+
+ GpeNumber = strtoul (&Name[2], NULL, 16);
+ if (GpeNumber == ACPI_UINT32_MAX)
+ {
+ return;
+ }
+
+ /*
+ * We are now sure we have an _Lxx or _Exx.
+ * Create the target name that would cause collision (Flip E/L)
+ */
+ ACPI_MOVE_32_TO_32 (Target, Name);
+
+ /* Inject opposite letter ("L" versus "E") */
+
+ if (Name[1] == 'L')
+ {
+ Target[1] = 'E';
+ }
+ else /* Name[1] == 'E' */
+ {
+ Target[1] = 'L';
+ }
+
+ /* Search all peers (objects within this scope) for target match */
+
+ NextOp = Op->Asl.Next;
+ while (NextOp)
+ {
+ /*
+ * We mostly care about methods, but check Name() constructs also,
+ * even though they will get another error for not being a method.
+ * All GPE names must be defined as control methods.
+ */
+ if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) ||
+ (NextOp->Asl.ParseOpcode == PARSEOP_NAME))
+ {
+ if (ACPI_COMPARE_NAME (Target, NextOp->Asl.NameSeg))
+ {
+ /* Found both _Exy and _Lxy in the same scope, error */
+
+ AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp,
+ Name);
+ return;
+ }
+ }
+
+ NextOp = NextOp->Asl.Next;
+ }
+
+ /* OK, no conflict found */
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckRegMethod
+ *
+ * PARAMETERS: Op - Current parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Ensure that a _REG method has a corresponding Operation
+ * Region declaration within the same scope. Note: _REG is defined
+ * to have two arguments and must therefore be defined as a
+ * control method.
+ *
+ ******************************************************************************/
+
+void
+ApCheckRegMethod (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_PARSE_OBJECT *Parent;
+
+
+ /* We are only interested in _REG methods */
+
+ if (!ACPI_COMPARE_NAME (METHOD_NAME__REG, &Op->Asl.NameSeg))
+ {
+ return;
+ }
+
+ /* Get the start of the current scope */
+
+ Parent = Op->Asl.Parent;
+ Next = Parent->Asl.Child;
+
+ /* Search entire scope for an operation region declaration */
+
+ while (Next)
+ {
+ if (Next->Asl.ParseOpcode == PARSEOP_OPERATIONREGION)
+ {
+ return; /* Found region, OK */
+ }
+
+ Next = Next->Asl.Next;
+ }
+
+ /* No region found, issue warning */
+
+ AslError (ASL_WARNING, ASL_MSG_NO_REGION, Op, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApFindNameInScope
+ *
+ * PARAMETERS: Name - Name to search for
+ * Op - Current parse op
+ *
+ * RETURN: TRUE if name found in the same scope as Op.
+ *
+ * DESCRIPTION: Determine if a name appears in the same scope as Op, as either
+ * a Method() or a Name().
+ *
+ ******************************************************************************/
+
+BOOLEAN
+ApFindNameInScope (
+ char *Name,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_PARSE_OBJECT *Parent;
+
+
+ /* Get the start of the current scope */
+
+ Parent = Op->Asl.Parent;
+ Next = Parent->Asl.Child;
+
+ /* Search entire scope for a match to the name */
+
+ while (Next)
+ {
+ if ((Next->Asl.ParseOpcode == PARSEOP_METHOD) ||
+ (Next->Asl.ParseOpcode == PARSEOP_NAME))
+ {
+ if (ACPI_COMPARE_NAME (Name, Next->Asl.NameSeg))
+ {
+ return (TRUE);
+ }
+ }
+
+ Next = Next->Asl.Next;
+ }
+
+ return (FALSE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslascii.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslascii.c
new file mode 100644
index 0000000000..67184ede01
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslascii.c
@@ -0,0 +1,370 @@
+/******************************************************************************
+ *
+ * Module Name: aslascii - ASCII detection and support routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslascii")
+
+
+/* Local prototypes */
+
+static void
+FlConsumeAnsiComment (
+ FILE *Handle,
+ ASL_FILE_STATUS *Status);
+
+static void
+FlConsumeNewComment (
+ FILE *Handle,
+ ASL_FILE_STATUS *Status);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlCheckForAcpiTable
+ *
+ * PARAMETERS: Handle - Open input file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
+ * following checks on what would be the table header:
+ * 0) File must be at least as long as an ACPI_TABLE_HEADER
+ * 1) The header length field must match the file size
+ * 2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlCheckForAcpiTable (
+ FILE *Handle)
+{
+ ACPI_TABLE_HEADER Table;
+ UINT32 FileSize;
+ size_t Actual;
+ UINT32 i;
+
+
+ /* Read a potential table header */
+
+ Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
+ fseek (Handle, 0, SEEK_SET);
+
+ if (Actual < sizeof (ACPI_TABLE_HEADER))
+ {
+ return (AE_ERROR);
+ }
+
+ /* Header length field must match the file size */
+
+ FileSize = CmGetFileSize (Handle);
+ if (Table.Length != FileSize)
+ {
+ return (AE_ERROR);
+ }
+
+ /*
+ * These fields must be ASCII:
+ * Signature, OemId, OemTableId, AslCompilerId.
+ * We allow a NULL terminator in OemId and OemTableId.
+ */
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
+ {
+ return (AE_ERROR);
+ }
+
+ if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
+ {
+ return (AE_ERROR);
+ }
+ }
+
+ for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
+ {
+ return (AE_ERROR);
+ }
+ }
+
+ for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
+ {
+ return (AE_ERROR);
+ }
+ }
+
+ printf ("Binary file appears to be a valid ACPI table, disassembling\n");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlCheckForAscii
+ *
+ * PARAMETERS: Filename - Full input filename
+ * DisplayErrors - TRUE if error messages desired
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
+ * within comments. Note: does not handle nested comments and does
+ * not handle comment delimiters within string literals. However,
+ * on the rare chance this happens and an invalid character is
+ * missed, the parser will catch the error by failing in some
+ * spectactular manner.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlCheckForAscii (
+ char *Filename,
+ BOOLEAN DisplayErrors)
+{
+ UINT8 Byte;
+ ACPI_SIZE BadBytes = 0;
+ BOOLEAN OpeningComment = FALSE;
+ ASL_FILE_STATUS Status;
+ FILE *Handle;
+
+
+ /* Open file in text mode so file offset is always accurate */
+
+ Handle = fopen (Filename, "rb");
+ if (!Handle)
+ {
+ perror ("Could not open input file");
+ return (AE_ERROR);
+ }
+
+ Status.Line = 1;
+ Status.Offset = 0;
+
+ /* Read the entire file */
+
+ while (fread (&Byte, 1, 1, Handle) == 1)
+ {
+ /* Ignore comment fields (allow non-ascii within) */
+
+ if (OpeningComment)
+ {
+ /* Check for second comment open delimiter */
+
+ if (Byte == '*')
+ {
+ FlConsumeAnsiComment (Handle, &Status);
+ }
+
+ if (Byte == '/')
+ {
+ FlConsumeNewComment (Handle, &Status);
+ }
+
+ /* Reset */
+
+ OpeningComment = FALSE;
+ }
+ else if (Byte == '/')
+ {
+ OpeningComment = TRUE;
+ }
+
+ /* Check for an ASCII character */
+
+ if (!ACPI_IS_ASCII (Byte))
+ {
+ if ((BadBytes < 10) && (DisplayErrors))
+ {
+ AcpiOsPrintf (
+ "Found non-ASCII character in source text: "
+ "0x%2.2X in line %u, file offset 0x%2.2X\n",
+ Byte, Status.Line, Status.Offset);
+ }
+ BadBytes++;
+ }
+
+ /* Ensure character is either printable or a "space" char */
+
+ else if (!isprint (Byte) && !isspace (Byte))
+ {
+ if ((BadBytes < 10) && (DisplayErrors))
+ {
+ AcpiOsPrintf (
+ "Found invalid character in source text: "
+ "0x%2.2X in line %u, file offset 0x%2.2X\n",
+ Byte, Status.Line, Status.Offset);
+ }
+ BadBytes++;
+ }
+
+ /* Update line counter as necessary */
+
+ if (Byte == 0x0A)
+ {
+ Status.Line++;
+ }
+
+ Status.Offset++;
+ }
+
+ fclose (Handle);
+
+ /* Were there any non-ASCII characters in the file? */
+
+ if (BadBytes)
+ {
+ if (DisplayErrors)
+ {
+ AcpiOsPrintf (
+ "Total %u invalid characters found in input source text, "
+ "could be a binary file\n", BadBytes);
+ AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
+ }
+
+ return (AE_BAD_CHARACTER);
+ }
+
+ /* File is OK (100% ASCII) */
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlConsumeAnsiComment
+ *
+ * PARAMETERS: Handle - Open input file
+ * Status - File current status struct
+ *
+ * RETURN: Number of lines consumed
+ *
+ * DESCRIPTION: Step over a normal slash-star type comment
+ *
+ ******************************************************************************/
+
+static void
+FlConsumeAnsiComment (
+ FILE *Handle,
+ ASL_FILE_STATUS *Status)
+{
+ UINT8 Byte;
+ BOOLEAN ClosingComment = FALSE;
+
+
+ while (fread (&Byte, 1, 1, Handle) == 1)
+ {
+ /* Scan until comment close is found */
+
+ if (ClosingComment)
+ {
+ if (Byte == '/')
+ {
+ Status->Offset++;
+ return;
+ }
+
+ if (Byte != '*')
+ {
+ /* Reset */
+
+ ClosingComment = FALSE;
+ }
+ }
+ else if (Byte == '*')
+ {
+ ClosingComment = TRUE;
+ }
+
+ /* Maintain line count */
+
+ if (Byte == 0x0A)
+ {
+ Status->Line++;
+ }
+
+ Status->Offset++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlConsumeNewComment
+ *
+ * PARAMETERS: Handle - Open input file
+ * Status - File current status struct
+ *
+ * RETURN: Number of lines consumed
+ *
+ * DESCRIPTION: Step over a slash-slash type of comment
+ *
+ ******************************************************************************/
+
+static void
+FlConsumeNewComment (
+ FILE *Handle,
+ ASL_FILE_STATUS *Status)
+{
+ UINT8 Byte;
+
+
+ while (fread (&Byte, 1, 1, Handle) == 1)
+ {
+ Status->Offset++;
+
+ /* Comment ends at newline */
+
+ if (Byte == 0x0A)
+ {
+ Status->Line++;
+ return;
+ }
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslbtypes.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslbtypes.c
new file mode 100644
index 0000000000..0ba219ae80
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslbtypes.c
@@ -0,0 +1,566 @@
+/******************************************************************************
+ *
+ * Module Name: aslbtypes - Support for bitfield types
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslbtypes")
+
+/* Local prototypes */
+
+static UINT32
+AnMapEtypeToBtype (
+ UINT32 Etype);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapArgTypeToBtype
+ *
+ * PARAMETERS: ArgType - The ARGI required type(s) for this
+ * argument, from the opcode info table
+ *
+ * RETURN: The corresponding Bit-encoded types
+ *
+ * DESCRIPTION: Convert an encoded ARGI required argument type code into a
+ * bitfield type code. Implements the implicit source conversion
+ * rules.
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapArgTypeToBtype (
+ UINT32 ArgType)
+{
+
+ switch (ArgType)
+ {
+
+ /* Simple types */
+
+ case ARGI_ANYTYPE:
+
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ case ARGI_PACKAGE:
+
+ return (ACPI_BTYPE_PACKAGE);
+
+ case ARGI_EVENT:
+
+ return (ACPI_BTYPE_EVENT);
+
+ case ARGI_MUTEX:
+
+ return (ACPI_BTYPE_MUTEX);
+
+ case ARGI_DDBHANDLE:
+ /*
+ * DDBHandleObject := SuperName
+ * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
+ */
+ return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
+
+ /* Interchangeable types */
+ /*
+ * Source conversion rules:
+ * Integer, String, and Buffer are all interchangeable
+ */
+ case ARGI_INTEGER:
+ case ARGI_STRING:
+ case ARGI_BUFFER:
+ case ARGI_BUFFER_OR_STRING:
+ case ARGI_COMPUTEDATA:
+
+ return (ACPI_BTYPE_COMPUTE_DATA);
+
+ /* References */
+
+ case ARGI_INTEGER_REF:
+
+ return (ACPI_BTYPE_INTEGER);
+
+ case ARGI_OBJECT_REF:
+
+ return (ACPI_BTYPE_ALL_OBJECTS);
+
+ case ARGI_DEVICE_REF:
+
+ return (ACPI_BTYPE_DEVICE_OBJECTS);
+
+ case ARGI_REFERENCE:
+
+ return (ACPI_BTYPE_REFERENCE);
+
+ case ARGI_TARGETREF:
+ case ARGI_FIXED_TARGET:
+ case ARGI_SIMPLE_TARGET:
+
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ /* Complex types */
+
+ case ARGI_DATAOBJECT:
+ /*
+ * Buffer, string, package or reference to a Op -
+ * Used only by SizeOf operator
+ */
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
+ ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
+
+ case ARGI_COMPLEXOBJ:
+
+ /* Buffer, String, or package */
+
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
+
+ case ARGI_REF_OR_STRING:
+
+ return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
+
+ case ARGI_REGION_OR_BUFFER:
+
+ /* Used by Load() only. Allow buffers in addition to regions/fields */
+
+ return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
+
+ case ARGI_DATAREFOBJ:
+
+ return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
+ ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
+
+ default:
+
+ break;
+ }
+
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapEtypeToBtype
+ *
+ * PARAMETERS: Etype - Encoded ACPI Type
+ *
+ * RETURN: Btype corresponding to the Etype
+ *
+ * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
+ * operand conversion rules. In other words, returns the type(s)
+ * this Etype is implicitly converted to during interpretation.
+ *
+ ******************************************************************************/
+
+static UINT32
+AnMapEtypeToBtype (
+ UINT32 Etype)
+{
+
+
+ if (Etype == ACPI_TYPE_ANY)
+ {
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+ }
+
+ /* Try the standard ACPI data types */
+
+ if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
+ {
+ /*
+ * This switch statement implements the allowed operand conversion
+ * rules as per the "ASL Data Types" section of the ACPI
+ * specification.
+ */
+ switch (Etype)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
+
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+
+ return (ACPI_BTYPE_COMPUTE_DATA);
+
+ case ACPI_TYPE_PACKAGE:
+
+ return (ACPI_BTYPE_PACKAGE);
+
+ case ACPI_TYPE_FIELD_UNIT:
+
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
+
+ case ACPI_TYPE_DDB_HANDLE:
+
+ return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
+
+ case ACPI_TYPE_DEBUG_OBJECT:
+
+ /* Cannot be used as a source operand */
+
+ return (0);
+
+ default:
+
+ return (1 << (Etype - 1));
+ }
+ }
+
+ /* Try the internal data types */
+
+ switch (Etype)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ /* Named fields can be either Integer/Buffer/String */
+
+ return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
+
+ case ACPI_TYPE_LOCAL_ALIAS:
+
+ return (ACPI_BTYPE_INTEGER);
+
+
+ case ACPI_TYPE_LOCAL_RESOURCE:
+ case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
+
+ return (ACPI_BTYPE_REFERENCE);
+
+ default:
+
+ printf ("Unhandled encoded type: %X\n", Etype);
+ return (0);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnFormatBtype
+ *
+ * PARAMETERS: Btype - Bitfield of ACPI types
+ * Buffer - Where to put the ascii string
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Convert a Btype to a string of ACPI types
+ *
+ ******************************************************************************/
+
+void
+AnFormatBtype (
+ char *Buffer,
+ UINT32 Btype)
+{
+ UINT32 Type;
+ BOOLEAN First = TRUE;
+
+
+ *Buffer = 0;
+
+ if (Btype == 0)
+ {
+ strcat (Buffer, "NoReturnValue");
+ return;
+ }
+
+ for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
+ {
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, AcpiUtGetTypeName (Type));
+ }
+ Btype >>= 1;
+ }
+
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, "Reference");
+ }
+
+ Btype >>= 1;
+ if (Btype & 0x00000001)
+ {
+ if (!First)
+ {
+ strcat (Buffer, "|");
+ }
+ First = FALSE;
+ strcat (Buffer, "Resource");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnGetBtype
+ *
+ * PARAMETERS: Op - Parse node whose type will be returned.
+ *
+ * RETURN: The Btype associated with the Op.
+ *
+ * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
+ * Handles the case where the node is a name or method call and
+ * the actual type must be obtained from the namespace node.
+ *
+ ******************************************************************************/
+
+UINT32
+AnGetBtype (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *ReferencedNode;
+ UINT32 ThisNodeBtype = 0;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("Null Op in AnGetBtype\n");
+ return (ACPI_UINT32_MAX);
+ }
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
+ (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
+ {
+ Node = Op->Asl.Node;
+ if (!Node)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "No attached Nsnode: [%s] at line %u name [%s], ignoring typecheck\n",
+ Op->Asl.ParseOpName, Op->Asl.LineNumber,
+ Op->Asl.ExternalName);
+ return (ACPI_UINT32_MAX);
+ }
+
+ ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
+ if (!ThisNodeBtype)
+ {
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "could not map type");
+ }
+
+ /*
+ * Since it was a named reference, enable the
+ * reference bit also
+ */
+ ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
+
+ if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ ReferencedNode = Node->Op;
+ if (!ReferencedNode)
+ {
+ /* Check for an internal method */
+
+ if (AnIsInternalMethod (Op))
+ {
+ return (AnGetInternalMethodReturnType (Op));
+ }
+
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "null Op pointer");
+ return (ACPI_UINT32_MAX);
+ }
+
+ if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
+ {
+ ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
+ }
+ else
+ {
+ return (ACPI_UINT32_MAX -1);
+ }
+ }
+ }
+ else
+ {
+ ThisNodeBtype = Op->Asl.AcpiBtype;
+ }
+
+ return (ThisNodeBtype);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapObjTypeToBtype
+ *
+ * PARAMETERS: Op - A parse node
+ *
+ * RETURN: A Btype
+ *
+ * DESCRIPTION: Map object to the associated "Btype"
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapObjTypeToBtype (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */
+
+ return (ACPI_BTYPE_BUFFER_FIELD);
+
+ case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */
+
+ return (ACPI_BTYPE_BUFFER);
+
+ case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */
+
+ return (ACPI_BTYPE_DDB_HANDLE);
+
+ case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */
+
+ return (ACPI_BTYPE_DEVICE);
+
+ case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */
+
+ return (ACPI_BTYPE_EVENT);
+
+ case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */
+
+ return (ACPI_BTYPE_FIELD_UNIT);
+
+ case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */
+
+ return (ACPI_BTYPE_INTEGER);
+
+ case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */
+
+ return (ACPI_BTYPE_METHOD);
+
+ case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */
+
+ return (ACPI_BTYPE_MUTEX);
+
+ case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */
+
+ return (ACPI_BTYPE_REGION);
+
+ case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */
+
+ return (ACPI_BTYPE_PACKAGE);
+
+ case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */
+
+ return (ACPI_BTYPE_POWER);
+
+ case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */
+
+ return (ACPI_BTYPE_STRING);
+
+ case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */
+
+ return (ACPI_BTYPE_THERMAL);
+
+ case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */
+
+ return (ACPI_BTYPE_OBJECTS_AND_REFS);
+
+ default:
+
+ return (0);
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AnMapBtypeToEtype
+ *
+ * PARAMETERS: Btype - Bitfield of ACPI types
+ *
+ * RETURN: The Etype corresponding the the Btype
+ *
+ * DESCRIPTION: Convert a bitfield type to an encoded type
+ *
+ ******************************************************************************/
+
+UINT32
+AnMapBtypeToEtype (
+ UINT32 Btype)
+{
+ UINT32 i;
+ UINT32 Etype;
+
+
+ if (Btype == 0)
+ {
+ return (0);
+ }
+
+ Etype = 1;
+ for (i = 1; i < Btype; i *= 2)
+ {
+ Etype++;
+ }
+
+ return (Etype);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcodegen.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcodegen.c
new file mode 100644
index 0000000000..a01afb714e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcodegen.c
@@ -0,0 +1,606 @@
+/******************************************************************************
+ *
+ * Module Name: aslcodegen - AML code generation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslcodegen")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+CgAmlWriteWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static void
+CgLocalWriteAmlData (
+ ACPI_PARSE_OBJECT *Op,
+ void *Buffer,
+ UINT32 Length);
+
+static void
+CgWriteAmlOpcode (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+CgWriteTableHeader (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+CgCloseTable (
+ void);
+
+static void
+CgWriteNode (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgGenerateAmlOutput
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generate AML code. Currently generates the listing file
+ * simultaneously.
+ *
+ ******************************************************************************/
+
+void
+CgGenerateAmlOutput (
+ void)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nWriting AML\n\n");
+
+ /* Generate the AML output file */
+
+ FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
+ Gbl_SourceLine = 0;
+ Gbl_NextError = Gbl_ErrorLog;
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ CgAmlWriteWalk, NULL, NULL);
+
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%*s Value P_Op A_Op OpLen PByts Len SubLen PSubLen OpPtr"
+ " Parent Child Next Flags AcTyp Final Col L# EL# LL# ELL#\n",
+ 76, " ");
+
+ CgCloseTable ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgAmlWriteWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse tree walk to generate the AML code.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+CgAmlWriteWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ /*
+ * Print header at level 0. Alignment assumes 32-bit pointers
+ */
+ if (!Level)
+ {
+ DbgPrint (ASL_TREE_OUTPUT,
+ "Final parse tree used for AML output:\n");
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%*s Value P_Op A_Op OpLen PByts Len SubLen PSubLen OpPtr"
+ " Parent Child Next Flags AcTyp Final Col L# EL# LL# ELL#\n",
+ 76, " ");
+ }
+
+ /* Debug output */
+
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
+ UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAMESEG ||
+ Op->Asl.ParseOpcode == PARSEOP_NAMESTRING ||
+ Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%10.32s ", Op->Asl.ExternalName);
+ }
+ else
+ {
+ DbgPrint (ASL_TREE_OUTPUT, " ");
+ }
+
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%08X %04X %04X %01X %04X %04X %04X %04X "
+ "%08X %08X %08X %08X %08X %08X %04X %02d %02d %02d %02d %02d\n",
+ /* 1 */ (UINT32) Op->Asl.Value.Integer,
+ /* 2 */ Op->Asl.ParseOpcode,
+ /* 3 */ Op->Asl.AmlOpcode,
+ /* 4 */ Op->Asl.AmlOpcodeLength,
+ /* 5 */ Op->Asl.AmlPkgLenBytes,
+ /* 6 */ Op->Asl.AmlLength,
+ /* 7 */ Op->Asl.AmlSubtreeLength,
+ /* 8 */ Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,
+ /* 9 */ Op,
+ /* 10 */ Op->Asl.Parent,
+ /* 11 */ Op->Asl.Child,
+ /* 12 */ Op->Asl.Next,
+ /* 13 */ Op->Asl.CompileFlags,
+ /* 14 */ Op->Asl.AcpiBtype,
+ /* 15 */ Op->Asl.FinalAmlLength,
+ /* 16 */ Op->Asl.Column,
+ /* 17 */ Op->Asl.LineNumber,
+ /* 18 */ Op->Asl.EndLine,
+ /* 19 */ Op->Asl.LogicalLineNumber,
+ /* 20 */ Op->Asl.EndLogicalLine);
+
+ /* Generate the AML for this node */
+
+ CgWriteNode (Op);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgLocalWriteAmlData
+ *
+ * PARAMETERS: Op - Current parse op
+ * Buffer - Buffer to write
+ * Length - Size of data in buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write a buffer of AML data to the AML output file.
+ *
+ ******************************************************************************/
+
+static void
+CgLocalWriteAmlData (
+ ACPI_PARSE_OBJECT *Op,
+ void *Buffer,
+ UINT32 Length)
+{
+
+ /* Write the raw data to the AML file */
+
+ FlWriteFile (ASL_FILE_AML_OUTPUT, Buffer, Length);
+
+ /* Update the final AML length for this node (used for listings) */
+
+ if (Op)
+ {
+ Op->Asl.FinalAmlLength += Length;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgWriteAmlOpcode
+ *
+ * PARAMETERS: Op - Parse node with an AML opcode
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Write the AML opcode corresponding to a parse node.
+ *
+ ******************************************************************************/
+
+static void
+CgWriteAmlOpcode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 PkgLenFirstByte;
+ UINT32 i;
+ union {
+ UINT16 Opcode;
+ UINT8 OpcodeBytes[2];
+ } Aml;
+ union {
+ UINT32 Len;
+ UINT8 LenBytes[4];
+ } PkgLen;
+
+
+ /* We expect some DEFAULT_ARGs, just ignore them */
+
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ return;
+ }
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_UNASSIGNED_OPCODE:
+
+ /* These opcodes should not get here */
+
+ printf ("Found a node with an unassigned AML opcode\n");
+ FlPrintFile (ASL_FILE_STDERR, "Found a node with an unassigned AML opcode\n");
+ return;
+
+ case AML_INT_RESERVEDFIELD_OP:
+
+ /* Special opcodes for within a field definition */
+
+ Aml.Opcode = AML_FIELD_OFFSET_OP;
+ break;
+
+ case AML_INT_ACCESSFIELD_OP:
+
+ Aml.Opcode = AML_FIELD_ACCESS_OP;
+ break;
+
+ case AML_INT_CONNECTION_OP:
+
+ Aml.Opcode = AML_FIELD_CONNECTION_OP;
+ break;
+
+ default:
+
+ Aml.Opcode = Op->Asl.AmlOpcode;
+ break;
+ }
+
+
+ switch (Aml.Opcode)
+ {
+ case AML_PACKAGE_LENGTH:
+
+ /* Value is the length to be encoded (Used in field definitions) */
+
+ PkgLen.Len = (UINT32) Op->Asl.Value.Integer;
+ break;
+
+ default:
+
+ /* Check for two-byte opcode */
+
+ if (Aml.Opcode > 0x00FF)
+ {
+ /* Write the high byte first */
+
+ CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[1], 1);
+ }
+
+ CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[0], 1);
+
+ /* Subtreelength doesn't include length of package length bytes */
+
+ PkgLen.Len = Op->Asl.AmlSubtreeLength + Op->Asl.AmlPkgLenBytes;
+ break;
+ }
+
+ /* Does this opcode have an associated "PackageLength" field? */
+
+ if (Op->Asl.CompileFlags & NODE_AML_PACKAGE)
+ {
+ if (Op->Asl.AmlPkgLenBytes == 1)
+ {
+ /* Simplest case -- no bytes to follow, just write the count */
+
+ CgLocalWriteAmlData (Op, &PkgLen.LenBytes[0], 1);
+ }
+ else if (Op->Asl.AmlPkgLenBytes != 0)
+ {
+ /*
+ * Encode the "bytes to follow" in the first byte, top two bits.
+ * The low-order nybble of the length is in the bottom 4 bits
+ */
+ PkgLenFirstByte = (UINT8)
+ (((UINT32) (Op->Asl.AmlPkgLenBytes - 1) << 6) |
+ (PkgLen.LenBytes[0] & 0x0F));
+
+ CgLocalWriteAmlData (Op, &PkgLenFirstByte, 1);
+
+ /*
+ * Shift the length over by the 4 bits we just stuffed
+ * in the first byte
+ */
+ PkgLen.Len >>= 4;
+
+ /* Now we can write the remaining bytes - either 1, 2, or 3 bytes */
+
+ for (i = 0; i < (UINT32) (Op->Asl.AmlPkgLenBytes - 1); i++)
+ {
+ CgLocalWriteAmlData (Op, &PkgLen.LenBytes[i], 1);
+ }
+ }
+ }
+
+ switch (Aml.Opcode)
+ {
+ case AML_BYTE_OP:
+
+ CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 1);
+ break;
+
+ case AML_WORD_OP:
+
+ CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 2);
+ break;
+
+ case AML_DWORD_OP:
+
+ CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 4);
+ break;
+
+ case AML_QWORD_OP:
+
+ CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 8);
+ break;
+
+ case AML_STRING_OP:
+
+ CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
+ break;
+
+ default:
+
+ /* All data opcodes must appear above */
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgWriteTableHeader
+ *
+ * PARAMETERS: Op - The DEFINITIONBLOCK node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write a table header corresponding to the DEFINITIONBLOCK
+ *
+ ******************************************************************************/
+
+static void
+CgWriteTableHeader (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Child;
+
+
+ /* AML filename */
+
+ Child = Op->Asl.Child;
+
+ /* Signature */
+
+ Child = Child->Asl.Next;
+ strncpy (TableHeader.Signature, Child->Asl.Value.String, 4);
+
+ /* Revision */
+
+ Child = Child->Asl.Next;
+ TableHeader.Revision = (UINT8) Child->Asl.Value.Integer;
+
+ /* Command-line Revision override */
+
+ if (Gbl_RevisionOverride)
+ {
+ TableHeader.Revision = Gbl_RevisionOverride;
+ }
+
+ /* OEMID */
+
+ Child = Child->Asl.Next;
+ strncpy (TableHeader.OemId, Child->Asl.Value.String, 6);
+
+ /* OEM TableID */
+
+ Child = Child->Asl.Next;
+ strncpy (TableHeader.OemTableId, Child->Asl.Value.String, 8);
+
+ /* OEM Revision */
+
+ Child = Child->Asl.Next;
+ TableHeader.OemRevision = (UINT32) Child->Asl.Value.Integer;
+
+ /* Compiler ID */
+
+ ACPI_MOVE_NAME (TableHeader.AslCompilerId, ASL_CREATOR_ID);
+
+ /* Compiler version */
+
+ TableHeader.AslCompilerRevision = ACPI_CA_VERSION;
+
+ /* Table length. Checksum zero for now, will rewrite later */
+
+ TableHeader.Length = Gbl_TableLength;
+ TableHeader.Checksum = 0;
+
+ CgLocalWriteAmlData (Op, &TableHeader, sizeof (ACPI_TABLE_HEADER));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgCloseTable
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Complete the ACPI table by calculating the checksum and
+ * re-writing the header.
+ *
+ ******************************************************************************/
+
+static void
+CgCloseTable (
+ void)
+{
+ signed char Sum;
+ UINT8 FileByte;
+
+
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+ Sum = 0;
+
+ /* Calculate the checksum over the entire file */
+
+ while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) == AE_OK)
+ {
+ Sum = (signed char) (Sum + FileByte);
+ }
+
+ /* Re-write the table header with the checksum */
+
+ TableHeader.Checksum = (UINT8) (0 - Sum);
+
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+ CgLocalWriteAmlData (NULL, &TableHeader, sizeof (ACPI_TABLE_HEADER));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgWriteNode
+ *
+ * PARAMETERS: Op - Parse node to write.
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Write the AML that corresponds to a parse node.
+ *
+ ******************************************************************************/
+
+static void
+CgWriteNode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ASL_RESOURCE_NODE *Rnode;
+
+
+ /* Always check for DEFAULT_ARG and other "Noop" nodes */
+ /* TBD: this may not be the best place for this check */
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) ||
+ (Op->Asl.ParseOpcode == PARSEOP_INCLUDE) ||
+ (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END))
+ {
+ return;
+ }
+
+ Op->Asl.FinalAmlLength = 0;
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_RAW_DATA_BYTE:
+ case AML_RAW_DATA_WORD:
+ case AML_RAW_DATA_DWORD:
+ case AML_RAW_DATA_QWORD:
+
+ CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, Op->Asl.AmlLength);
+ return;
+
+
+ case AML_RAW_DATA_BUFFER:
+
+ CgLocalWriteAmlData (Op, Op->Asl.Value.Buffer, Op->Asl.AmlLength);
+ return;
+
+
+ case AML_RAW_DATA_CHAIN:
+
+ Rnode = ACPI_CAST_PTR (ASL_RESOURCE_NODE, Op->Asl.Value.Buffer);
+ while (Rnode)
+ {
+ CgLocalWriteAmlData (Op, Rnode->Buffer, Rnode->BufferLength);
+ Rnode = Rnode->Next;
+ }
+ return;
+
+ default:
+
+ /* Internal data opcodes must all appear above */
+
+ break;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFAULT_ARG:
+
+ break;
+
+ case PARSEOP_DEFINITIONBLOCK:
+
+ CgWriteTableHeader (Op);
+ break;
+
+ case PARSEOP_NAMESEG:
+ case PARSEOP_NAMESTRING:
+ case PARSEOP_METHODCALL:
+
+ CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
+ break;
+
+ default:
+
+ CgWriteAmlOpcode (Op);
+ break;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompile.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompile.c
new file mode 100644
index 0000000000..cda158361e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompile.c
@@ -0,0 +1,834 @@
+/******************************************************************************
+ *
+ * Module Name: aslcompile - top level compile module
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslcompile")
+
+/*
+ * Main parser entry
+ * External is here in case the parser emits the same external in the
+ * generated header. (Newer versions of Bison)
+ */
+int
+AslCompilerparse(
+ void);
+
+/* Local prototypes */
+
+static void
+CmFlushSourceCode (
+ void);
+
+static void
+CmDumpAllEvents (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmDoCompile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status (0 = OK)
+ *
+ * DESCRIPTION: This procedure performs the entire compile
+ *
+ ******************************************************************************/
+
+int
+CmDoCompile (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT8 FullCompile;
+ UINT8 Event;
+
+
+ FullCompile = UtBeginEvent ("*** Total Compile time ***");
+ Event = UtBeginEvent ("Open input and output files");
+ UtEndEvent (Event);
+
+ Event = UtBeginEvent ("Preprocess input file");
+ if (Gbl_PreprocessFlag)
+ {
+ /* Enter compiler name as a #define */
+
+ PrAddDefine (ASL_DEFINE, "", FALSE);
+
+ /* Preprocessor */
+
+ PrDoPreprocess ();
+ Gbl_CurrentLineNumber = 1;
+ Gbl_LogicalLineNumber = 1;
+
+ if (Gbl_PreprocessOnly)
+ {
+ UtEndEvent (Event);
+ CmCleanupAndExit ();
+ return (0);
+ }
+ }
+ UtEndEvent (Event);
+
+
+ /* Build the parse tree */
+
+ Event = UtBeginEvent ("Parse source code and build parse tree");
+ AslCompilerparse();
+ UtEndEvent (Event);
+
+ /* Check for parser-detected syntax errors */
+
+ if (Gbl_SyntaxError)
+ {
+ fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n");
+ LsDumpParseTree ();
+ goto ErrorExit;
+ }
+
+ /* Did the parse tree get successfully constructed? */
+
+ if (!RootNode)
+ {
+ /*
+ * If there are no errors, then we have some sort of
+ * internal problem.
+ */
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
+ NULL, "- Could not resolve parse tree root node");
+
+ goto ErrorExit;
+ }
+
+ /* Flush out any remaining source after parse tree is complete */
+
+ Event = UtBeginEvent ("Flush source input");
+ CmFlushSourceCode ();
+
+ /* Prune the parse tree if requested (debug purposes only) */
+
+ if (Gbl_PruneParseTree)
+ {
+ AslPruneParseTree (Gbl_PruneDepth, Gbl_PruneType);
+ }
+
+ /* Optional parse tree dump, compiler debug output only */
+
+ LsDumpParseTree ();
+
+ OpcGetIntegerWidth (RootNode);
+ UtEndEvent (Event);
+
+ /* Pre-process parse tree for any operator transforms */
+
+ Event = UtBeginEvent ("Parse tree transforms");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ TrAmlTransformWalk, NULL, NULL);
+ UtEndEvent (Event);
+
+ /* Generate AML opcodes corresponding to the parse tokens */
+
+ Event = UtBeginEvent ("Generate AML opcodes");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
+ OpcAmlOpcodeWalk, NULL);
+ UtEndEvent (Event);
+
+ /*
+ * Now that the input is parsed, we can open the AML output file.
+ * Note: by default, the name of this file comes from the table descriptor
+ * within the input file.
+ */
+ Event = UtBeginEvent ("Open AML output file");
+ Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
+ UtEndEvent (Event);
+ if (ACPI_FAILURE (Status))
+ {
+ AePrintErrorLog (ASL_FILE_STDERR);
+ return (-1);
+ }
+
+ /* Interpret and generate all compile-time constants */
+
+ Event = UtBeginEvent ("Constant folding via AML interpreter");
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "\nInterpreting compile-time constant expressions\n\n");
+
+ if (Gbl_FoldConstants)
+ {
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ OpcAmlConstantWalk, NULL, NULL);
+ }
+ else
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, " Optional folding disabled\n");
+ }
+ UtEndEvent (Event);
+
+ /* Update AML opcodes if necessary, after constant folding */
+
+ Event = UtBeginEvent ("Updating AML opcodes after constant folding");
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "\nUpdating AML opcodes after constant folding\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
+ NULL, OpcAmlOpcodeUpdateWalk, NULL);
+ UtEndEvent (Event);
+
+ /* Calculate all AML package lengths */
+
+ Event = UtBeginEvent ("Generate AML package lengths");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
+ LnPackageLengthWalk, NULL);
+ UtEndEvent (Event);
+
+ if (Gbl_ParseOnlyFlag)
+ {
+ AePrintErrorLog (ASL_FILE_STDERR);
+ UtDisplaySummary (ASL_FILE_STDERR);
+ if (Gbl_DebugFlag)
+ {
+ /* Print error summary to the stdout also */
+
+ AePrintErrorLog (ASL_FILE_STDOUT);
+ UtDisplaySummary (ASL_FILE_STDOUT);
+ }
+ UtEndEvent (FullCompile);
+ return (0);
+ }
+
+ /*
+ * Create an internal namespace and use it as a symbol table
+ */
+
+ /* Namespace loading */
+
+ Event = UtBeginEvent ("Create ACPI Namespace");
+ Status = LdLoadNamespace (RootNode);
+ UtEndEvent (Event);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* Namespace cross-reference */
+
+ AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
+ Status = XfCrossReferenceNamespace ();
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* Namespace - Check for non-referenced objects */
+
+ LkFindUnreferencedObjects ();
+ UtEndEvent (AslGbl_NamespaceEvent);
+
+ /*
+ * Semantic analysis. This can happen only after the
+ * namespace has been loaded and cross-referenced.
+ *
+ * part one - check control methods
+ */
+ Event = UtBeginEvent ("Analyze control method return types");
+ AnalysisWalkInfo.MethodStack = NULL;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
+ MtMethodAnalysisWalkBegin,
+ MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
+ UtEndEvent (Event);
+
+ /* Semantic error checking part two - typing of method returns */
+
+ Event = UtBeginEvent ("Determine object types returned by methods");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
+ NULL, AnMethodTypingWalkEnd, NULL);
+ UtEndEvent (Event);
+
+ /* Semantic error checking part three - operand type checking */
+
+ Event = UtBeginEvent ("Analyze AML operand types");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
+ NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
+ UtEndEvent (Event);
+
+ /* Semantic error checking part four - other miscellaneous checks */
+
+ Event = UtBeginEvent ("Miscellaneous analysis");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ AnOtherSemanticAnalysisWalkBegin,
+ NULL, &AnalysisWalkInfo);
+ UtEndEvent (Event);
+
+ /* Calculate all AML package lengths */
+
+ Event = UtBeginEvent ("Finish AML package length generation");
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
+ LnInitLengthsWalk, NULL);
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
+ LnPackageLengthWalk, NULL);
+ UtEndEvent (Event);
+
+ /* Code generation - emit the AML */
+
+ Event = UtBeginEvent ("Generate AML code and write output files");
+ CgGenerateAmlOutput ();
+ UtEndEvent (Event);
+
+ Event = UtBeginEvent ("Write optional output files");
+ CmDoOutputFiles ();
+ UtEndEvent (Event);
+
+ UtEndEvent (FullCompile);
+ CmCleanupAndExit ();
+ return (0);
+
+ErrorExit:
+ UtEndEvent (FullCompile);
+ CmCleanupAndExit ();
+ return (-1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCompilerSignon
+ *
+ * PARAMETERS: FileId - ID of the output file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display compiler signon
+ *
+ ******************************************************************************/
+
+void
+AslCompilerSignon (
+ UINT32 FileId)
+{
+ char *Prefix = "";
+ char *UtilityName;
+
+
+ /* Set line prefix depending on the destination file type */
+
+ switch (FileId)
+ {
+ case ASL_FILE_ASM_SOURCE_OUTPUT:
+ case ASL_FILE_ASM_INCLUDE_OUTPUT:
+
+ Prefix = "; ";
+ break;
+
+ case ASL_FILE_HEX_OUTPUT:
+
+ if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
+ {
+ Prefix = "; ";
+ }
+ else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
+ (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
+ Prefix = " * ";
+ }
+ break;
+
+ case ASL_FILE_C_SOURCE_OUTPUT:
+ case ASL_FILE_C_OFFSET_OUTPUT:
+ case ASL_FILE_C_INCLUDE_OUTPUT:
+
+ Prefix = " * ";
+ break;
+
+ default:
+
+ /* No other output types supported */
+
+ break;
+ }
+
+ /* Running compiler or disassembler? */
+
+ if (Gbl_DisasmFlag)
+ {
+ UtilityName = AML_DISASSEMBLER_NAME;
+ }
+ else
+ {
+ UtilityName = ASL_COMPILER_NAME;
+ }
+
+ /* Compiler signon with copyright */
+
+ FlPrintFile (FileId, "%s\n", Prefix);
+ FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCompilerFileHeader
+ *
+ * PARAMETERS: FileId - ID of the output file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Header used at the beginning of output files
+ *
+ ******************************************************************************/
+
+void
+AslCompilerFileHeader (
+ UINT32 FileId)
+{
+ struct tm *NewTime;
+ time_t Aclock;
+ char *Prefix = "";
+
+
+ /* Set line prefix depending on the destination file type */
+
+ switch (FileId)
+ {
+ case ASL_FILE_ASM_SOURCE_OUTPUT:
+ case ASL_FILE_ASM_INCLUDE_OUTPUT:
+
+ Prefix = "; ";
+ break;
+
+ case ASL_FILE_HEX_OUTPUT:
+
+ if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
+ {
+ Prefix = "; ";
+ }
+ else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
+ (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
+ {
+ Prefix = " * ";
+ }
+ break;
+
+ case ASL_FILE_C_SOURCE_OUTPUT:
+ case ASL_FILE_C_OFFSET_OUTPUT:
+ case ASL_FILE_C_INCLUDE_OUTPUT:
+
+ Prefix = " * ";
+ break;
+
+ default:
+
+ /* No other output types supported */
+
+ break;
+ }
+
+ /* Compilation header with timestamp */
+
+ (void) time (&Aclock);
+ NewTime = localtime (&Aclock);
+
+ FlPrintFile (FileId,
+ "%sCompilation of \"%s\" - %s%s\n",
+ Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
+ Prefix);
+
+ switch (FileId)
+ {
+ case ASL_FILE_C_SOURCE_OUTPUT:
+ case ASL_FILE_C_OFFSET_OUTPUT:
+ case ASL_FILE_C_INCLUDE_OUTPUT:
+
+ FlPrintFile (FileId, " */\n");
+ break;
+
+ default:
+
+ /* Nothing to do for other output types */
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmFlushSourceCode
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Read in any remaining source code after the parse tree
+ * has been constructed.
+ *
+ ******************************************************************************/
+
+static void
+CmFlushSourceCode (
+ void)
+{
+ char Buffer;
+
+
+ while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
+ {
+ AslInsertLineBuffer ((int) Buffer);
+ }
+
+ AslResetCurrentLineBuffer ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmDoOutputFiles
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Create all "listing" type files
+ *
+ ******************************************************************************/
+
+void
+CmDoOutputFiles (
+ void)
+{
+
+ /* Create listings and hex files */
+
+ LsDoListings ();
+ HxDoHexOutput ();
+
+ /* Dump the namespace to the .nsp file if requested */
+
+ (void) NsDisplayNamespace ();
+
+ /* Dump the device mapping file */
+
+ MpEmitMappingInfo ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmDumpAllEvents
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Dump all compiler events
+ *
+ ******************************************************************************/
+
+static void
+CmDumpAllEvents (
+ void)
+{
+ ASL_EVENT_INFO *Event;
+ UINT32 Delta;
+ UINT32 USec;
+ UINT32 MSec;
+ UINT32 i;
+
+
+ Event = AslGbl_Events;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
+ if (Gbl_CompileTimesFlag)
+ {
+ printf ("\nElapsed time for major events\n\n");
+ }
+
+ for (i = 0; i < AslGbl_NextEvent; i++)
+ {
+ if (Event->Valid)
+ {
+ /* Delta will be in 100-nanosecond units */
+
+ Delta = (UINT32) (Event->EndTime - Event->StartTime);
+
+ USec = Delta / ACPI_100NSEC_PER_USEC;
+ MSec = Delta / ACPI_100NSEC_PER_MSEC;
+
+ /* Round milliseconds up */
+
+ if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
+ {
+ MSec++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
+ USec, MSec, Event->EventName);
+
+ if (Gbl_CompileTimesFlag)
+ {
+ printf ("%8u usec %8u msec - %s\n",
+ USec, MSec, Event->EventName);
+ }
+ }
+
+ Event++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmCleanupAndExit
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Close all open files and exit the compiler
+ *
+ ******************************************************************************/
+
+void
+CmCleanupAndExit (
+ void)
+{
+ UINT32 i;
+ BOOLEAN DeleteAmlFile = FALSE;
+
+
+ AePrintErrorLog (ASL_FILE_STDERR);
+ if (Gbl_DebugFlag)
+ {
+ /* Print error summary to stdout also */
+
+ AePrintErrorLog (ASL_FILE_STDOUT);
+ }
+
+ /* Emit compile times if enabled */
+
+ CmDumpAllEvents ();
+
+ if (Gbl_CompileTimesFlag)
+ {
+ printf ("\nMiscellaneous compile statistics\n\n");
+ printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
+ printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
+ printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
+ printf ("%11u : %s\n", TotalMethods, "Control methods");
+ printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
+ printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
+ printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
+ printf ("\n");
+ }
+
+ if (Gbl_NsLookupCount)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "\n\nMiscellaneous compile statistics\n\n");
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%32s : %u\n", "Total Namespace searches",
+ Gbl_NsLookupCount);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%32s : %u usec\n", "Time per search", ((UINT32)
+ (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
+ AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
+ Gbl_NsLookupCount);
+ }
+
+ if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
+ {
+ printf ("\nMaximum error count (%u) exceeded\n",
+ ASL_MAX_ERROR_COUNT);
+ }
+
+ UtDisplaySummary (ASL_FILE_STDOUT);
+
+ /*
+ * We will delete the AML file if there are errors and the
+ * force AML output option has not been used.
+ */
+ if ((Gbl_ExceptionCount[ASL_ERROR] > 0) &&
+ (!Gbl_IgnoreErrors) &&
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
+ {
+ DeleteAmlFile = TRUE;
+ }
+
+ /* Close all open files */
+
+ /*
+ * Take care with the preprocessor file (.pre), it might be the same
+ * as the "input" file, depending on where the compiler has terminated
+ * or aborted. Prevent attempt to close the same file twice in
+ * loop below.
+ */
+ if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
+ Gbl_Files[ASL_FILE_INPUT].Handle)
+ {
+ Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
+ }
+
+ /* Close the standard I/O files */
+
+ for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
+ {
+ FlCloseFile (i);
+ }
+
+ /* Delete AML file if there are errors */
+
+ if (DeleteAmlFile)
+ {
+ FlDeleteFile (ASL_FILE_AML_OUTPUT);
+ }
+
+ /* Delete the preprocessor temp file unless full debug was specified */
+
+ if (Gbl_PreprocessFlag && !Gbl_KeepPreprocessorTempFile)
+ {
+ FlDeleteFile (ASL_FILE_PREPROCESSOR);
+ }
+
+ /*
+ * Delete intermediate ("combined") source file (if -ls flag not set)
+ * This file is created during normal ASL/AML compiles. It is not
+ * created by the data table compiler.
+ *
+ * If the -ls flag is set, then the .SRC file should not be deleted.
+ * In this case, Gbl_SourceOutputFlag is set to TRUE.
+ *
+ * Note: Handles are cleared by FlCloseFile above, so we look at the
+ * filename instead, to determine if the .SRC file was actually
+ * created.
+ */
+ if (!Gbl_SourceOutputFlag)
+ {
+ FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
+ }
+
+ /* Final cleanup after compiling one file */
+
+ CmDeleteCaches ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CmDeleteCaches
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all local cache buffer blocks
+ *
+ ******************************************************************************/
+
+void
+CmDeleteCaches (
+ void)
+{
+ UINT32 BufferCount;
+ ASL_CACHE_INFO *Next;
+
+
+ /* Parse Op cache */
+
+ BufferCount = 0;
+ while (Gbl_ParseOpCacheList)
+ {
+ Next = Gbl_ParseOpCacheList->Next;
+ ACPI_FREE (Gbl_ParseOpCacheList);
+ Gbl_ParseOpCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
+ Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
+ (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
+
+ Gbl_ParseOpCount = 0;
+ Gbl_ParseOpCacheNext = NULL;
+ Gbl_ParseOpCacheLast = NULL;
+ RootNode = NULL;
+
+ /* Generic string cache */
+
+ BufferCount = 0;
+ while (Gbl_StringCacheList)
+ {
+ Next = Gbl_StringCacheList->Next;
+ ACPI_FREE (Gbl_StringCacheList);
+ Gbl_StringCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
+ Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
+
+ Gbl_StringSize = 0;
+ Gbl_StringCount = 0;
+ Gbl_StringCacheNext = NULL;
+ Gbl_StringCacheLast = NULL;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.h
new file mode 100644
index 0000000000..f84f988875
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -0,0 +1,1286 @@
+/******************************************************************************
+ *
+ * Module Name: aslcompiler.h - common include file for iASL
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ASLCOMPILER_H
+#define __ASLCOMPILER_H
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlresrc.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+/* Microsoft-specific */
+
+#if (defined WIN32 || defined WIN64)
+
+/* warn : used #pragma pack */
+#pragma warning(disable:4103)
+
+/* warn : named type definition in parentheses */
+#pragma warning(disable:4115)
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+/* Compiler headers */
+
+#include <contrib/dev/acpica/compiler/asldefine.h>
+#include <contrib/dev/acpica/compiler/asltypes.h>
+#include <contrib/dev/acpica/compiler/aslmessages.h>
+#include <contrib/dev/acpica/compiler/aslglobal.h>
+#include <contrib/dev/acpica/compiler/preprocess.h>
+
+
+/*******************************************************************************
+ *
+ * Compiler prototypes
+ *
+ ******************************************************************************/
+
+/*
+ * Main ASL parser - generated from flex/bison, lex/yacc, etc.
+ */
+ACPI_PARSE_OBJECT *
+AslDoError (
+ void);
+
+int
+AslCompilerlex(
+ void);
+
+void
+AslResetCurrentLineBuffer (
+ void);
+
+void
+AslInsertLineBuffer (
+ int SourceChar);
+
+int
+AslPopInputFileStack (
+ void);
+
+void
+AslPushInputFileStack (
+ FILE *InputFile,
+ char *Filename);
+
+void
+AslParserCleanup (
+ void);
+
+
+/*
+ * aslstartup - entered from main()
+ */
+void
+AslInitializeGlobals (
+ void);
+
+typedef
+ACPI_STATUS (*ASL_PATHNAME_CALLBACK) (
+ char *);
+
+ACPI_STATUS
+AslDoOneFile (
+ char *Filename);
+
+ACPI_STATUS
+AslCheckForErrorExit (
+ void);
+
+
+/*
+ * aslcompile - compile mainline
+ */
+void
+AslCompilerSignon (
+ UINT32 FileId);
+
+void
+AslCompilerFileHeader (
+ UINT32 FileId);
+
+int
+CmDoCompile (
+ void);
+
+void
+CmDoOutputFiles (
+ void);
+
+void
+CmCleanupAndExit (
+ void);
+
+void
+CmDeleteCaches (
+ void);
+
+
+/*
+ * aslascii - ascii support
+ */
+ACPI_STATUS
+FlCheckForAcpiTable (
+ FILE *Handle);
+
+ACPI_STATUS
+FlCheckForAscii (
+ char *Filename,
+ BOOLEAN DisplayErrors);
+
+
+/*
+ * aslwalks - semantic analysis and parse tree walks
+ */
+ACPI_STATUS
+AnOtherSemanticAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+AnOtherSemanticAnalysisWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+AnOperandTypecheckWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+AnMethodTypingWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*
+ * aslmethod - Control method analysis walk
+ */
+ACPI_STATUS
+MtMethodAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+MtMethodAnalysisWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*
+ * aslbtypes - bitfield data types
+ */
+UINT32
+AnMapObjTypeToBtype (
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AnMapArgTypeToBtype (
+ UINT32 ArgType);
+
+UINT32
+AnGetBtype (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AnFormatBtype (
+ char *Buffer,
+ UINT32 Btype);
+
+
+/*
+ * aslanalyze - Support functions for parse tree walks
+ */
+void
+AnCheckId (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAME Type);
+
+/* Values for Type argument above */
+
+#define ASL_TYPE_HID 0
+#define ASL_TYPE_CID 1
+
+BOOLEAN
+AnIsInternalMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AnGetInternalMethodReturnType (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AnLastStatementIsReturn (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AnCheckMethodReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ const ACPI_OPCODE_INFO *OpInfo,
+ ACPI_PARSE_OBJECT *ArgOp,
+ UINT32 RequiredBtypes,
+ UINT32 ThisNodeBtype);
+
+BOOLEAN
+AnIsResultUsed (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+ApCheckForGpeNameConflict (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+ApCheckRegMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+ApFindNameInScope (
+ char *Name,
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * aslerror - error handling/reporting
+ */
+void
+AslAbort (
+ void);
+
+void
+AslError (
+ UINT8 Level,
+ UINT16 MessageId,
+ ACPI_PARSE_OBJECT *Op,
+ char *ExtraMessage);
+
+ACPI_STATUS
+AslDisableException (
+ char *MessageIdString);
+
+BOOLEAN
+AslIsExceptionDisabled (
+ UINT8 Level,
+ UINT16 MessageId);
+
+void
+AslCoreSubsystemError (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status,
+ char *ExtraMessage,
+ BOOLEAN Abort);
+
+int
+AslCompilererror(
+ const char *s);
+
+void
+AslCommonError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 CurrentLineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
+ UINT32 Column,
+ char *Filename,
+ char *ExtraMessage);
+
+void
+AslCommonError2 (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 Column,
+ char *SourceLine,
+ char *Filename,
+ char *ExtraMessage);
+
+void
+AePrintException (
+ UINT32 FileId,
+ ASL_ERROR_MSG *Enode,
+ char *Header);
+
+void
+AePrintErrorLog (
+ UINT32 FileId);
+
+void
+AeClearErrorLog (
+ void);
+
+
+/*
+ * asllisting - generate all "listing" type files
+ */
+void
+LsDoListings (
+ void);
+
+void
+LsWriteNodeToAsmListing (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+LsWriteNode (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 FileId);
+
+void
+LsDumpParseTree (
+ void);
+
+
+/*
+ * asllistsup - Listing file support utilities
+ */
+void
+LsDumpAscii (
+ UINT32 FileId,
+ UINT32 Count,
+ UINT8 *Buffer);
+
+void
+LsDumpAsciiInComment (
+ UINT32 FileId,
+ UINT32 Count,
+ UINT8 *Buffer);
+
+void
+LsCheckException (
+ UINT32 LineNumber,
+ UINT32 FileId);
+
+void
+LsFlushListingBuffer (
+ UINT32 FileId);
+
+void
+LsWriteListingHexBytes (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 FileId);
+
+void
+LsWriteSourceLines (
+ UINT32 ToLineNumber,
+ UINT32 ToLogicalLineNumber,
+ UINT32 FileId);
+
+UINT32
+LsWriteOneSourceLine (
+ UINT32 FileId);
+
+void
+LsPushNode (
+ char *Filename);
+
+ASL_LISTING_NODE *
+LsPopNode (
+ void);
+
+
+/*
+ * aslhex - generate all "hex" output files (C, ASM, ASL)
+ */
+void
+HxDoHexOutput (
+ void);
+
+
+/*
+ * aslfold - constant folding
+ */
+ACPI_STATUS
+OpcAmlConstantWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*
+ * aslmessages - exception strings
+ */
+const char *
+AeDecodeMessageId (
+ UINT16 MessageId);
+
+const char *
+AeDecodeExceptionLevel (
+ UINT8 Level);
+
+UINT16
+AeBuildFullExceptionCode (
+ UINT8 Level,
+ UINT16 MessageId);
+
+/*
+ * asloffset - generate C offset file for BIOS support
+ */
+ACPI_STATUS
+LsAmlOffsetWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+void
+LsDoOffsetTableHeader (
+ UINT32 FileId);
+
+void
+LsDoOffsetTableFooter (
+ UINT32 FileId);
+
+
+/*
+ * aslopcodes - generate AML opcodes
+ */
+ACPI_STATUS
+OpcAmlOpcodeWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+OpcAmlOpcodeUpdateWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+void
+OpcGenerateAmlOpcode (
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+OpcSetOptimalIntegerSize (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+OpcGetIntegerWidth (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * asloperands - generate AML operands for the AML opcodes
+ */
+ACPI_PARSE_OBJECT *
+UtGetArg (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Argn);
+
+void
+OpnGenerateAmlOperands (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+OpnDoPackage (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * aslopt - optmization
+ */
+void
+OptOptimizeNamePath (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Flags,
+ ACPI_WALK_STATE *WalkState,
+ char *AmlNameString,
+ ACPI_NAMESPACE_NODE *TargetNode);
+
+
+/*
+ * aslprintf - Printf/Fprintf macros
+ */
+void
+OpcDoPrintf (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+OpcDoFprintf (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * aslprune - parse tree pruner
+ */
+void
+AslPruneParseTree (
+ UINT32 PruneDepth,
+ UINT32 Type);
+
+
+/*
+ * aslcodegen - code generation
+ */
+void
+CgGenerateAmlOutput (
+ void);
+
+
+/*
+ * aslfile
+ */
+void
+FlOpenFile (
+ UINT32 FileId,
+ char *Filename,
+ char *Mode);
+
+
+/*
+ * asllength - calculate/adjust AML package lengths
+ */
+ACPI_STATUS
+LnPackageLengthWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+ACPI_STATUS
+LnInitLengthsWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+void
+CgGenerateAmlLengths (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * aslmap - opcode mappings and reserved method names
+ */
+ACPI_OBJECT_TYPE
+AslMapNamedOpcodeToDataType (
+ UINT16 Opcode);
+
+
+/*
+ * aslpredef - ACPI predefined names support
+ */
+BOOLEAN
+ApCheckForPredefinedMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+UINT32
+ApCheckForPredefinedName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+void
+ApCheckForPredefinedObject (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+ACPI_STATUS
+ApCheckObjectType (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex);
+
+void
+ApDisplayReservedNames (
+ void);
+
+
+/*
+ * aslprepkg - ACPI predefined names support for packages
+ */
+void
+ApCheckPackage (
+ ACPI_PARSE_OBJECT *ParentOp,
+ const ACPI_PREDEFINED_INFO *Predefined);
+
+
+/*
+ * asltransform - parse tree transformations
+ */
+ACPI_STATUS
+TrAmlTransformWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*
+ * asltree - parse tree support
+ */
+ACPI_STATUS
+TrWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Visitation,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context);
+
+/* Values for "Visitation" parameter above */
+
+#define ASL_WALK_VISIT_DOWNWARD 0x01
+#define ASL_WALK_VISIT_UPWARD 0x02
+#define ASL_WALK_VISIT_TWICE (ASL_WALK_VISIT_DOWNWARD | ASL_WALK_VISIT_UPWARD)
+
+
+ACPI_PARSE_OBJECT *
+TrAllocateNode (
+ UINT32 ParseOpcode);
+
+void
+TrPrintNodeCompileFlags (
+ UINT32 Flags);
+
+void
+TrReleaseNode (
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_PARSE_OBJECT *
+TrUpdateNode (
+ UINT32 ParseOpcode,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_PARSE_OBJECT *
+TrCreateNode (
+ UINT32 ParseOpcode,
+ UINT32 NumChildren,
+ ...);
+
+ACPI_PARSE_OBJECT *
+TrCreateLeafNode (
+ UINT32 ParseOpcode);
+
+ACPI_PARSE_OBJECT *
+TrCreateNullTarget (
+ void);
+
+ACPI_PARSE_OBJECT *
+TrCreateAssignmentNode (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Source);
+
+ACPI_PARSE_OBJECT *
+TrCreateTargetOperand (
+ ACPI_PARSE_OBJECT *OriginalOp,
+ ACPI_PARSE_OBJECT *ParentOp);
+
+ACPI_PARSE_OBJECT *
+TrCreateValuedLeafNode (
+ UINT32 ParseOpcode,
+ UINT64 Value);
+
+ACPI_PARSE_OBJECT *
+TrCreateConstantLeafNode (
+ UINT32 ParseOpcode);
+
+ACPI_PARSE_OBJECT *
+TrLinkChildren (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 NumChildren,
+ ...);
+
+void
+TrSetEndLineNumber (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+TrWalkTree (
+ void);
+
+ACPI_PARSE_OBJECT *
+TrLinkPeerNode (
+ ACPI_PARSE_OBJECT *Op1,
+ ACPI_PARSE_OBJECT *Op2);
+
+ACPI_PARSE_OBJECT *
+TrLinkChildNode (
+ ACPI_PARSE_OBJECT *Op1,
+ ACPI_PARSE_OBJECT *Op2);
+
+ACPI_PARSE_OBJECT *
+TrSetNodeFlags (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Flags);
+
+ACPI_PARSE_OBJECT *
+TrSetNodeAmlLength (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Length);
+
+ACPI_PARSE_OBJECT *
+TrLinkPeerNodes (
+ UINT32 NumPeers,
+ ...);
+
+
+/*
+ * aslfiles - File I/O support
+ */
+void
+FlAddIncludeDirectory (
+ char *Dir);
+
+char *
+FlMergePathnames (
+ char *PrefixDir,
+ char *FilePathname);
+
+void
+FlOpenIncludeFile (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+FlFileError (
+ UINT32 FileId,
+ UINT8 ErrorId);
+
+UINT32
+FlGetFileSize (
+ UINT32 FileId);
+
+ACPI_STATUS
+FlReadFile (
+ UINT32 FileId,
+ void *Buffer,
+ UINT32 Length);
+
+void
+FlWriteFile (
+ UINT32 FileId,
+ void *Buffer,
+ UINT32 Length);
+
+void
+FlSeekFile (
+ UINT32 FileId,
+ long Offset);
+
+void
+FlCloseFile (
+ UINT32 FileId);
+
+void
+FlPrintFile (
+ UINT32 FileId,
+ char *Format,
+ ...);
+
+void
+FlDeleteFile (
+ UINT32 FileId);
+
+void
+FlSetLineNumber (
+ UINT32 LineNumber);
+
+void
+FlSetFilename (
+ char *Filename);
+
+ACPI_STATUS
+FlOpenInputFile (
+ char *InputFilename);
+
+ACPI_STATUS
+FlOpenAmlOutputFile (
+ char *InputFilename);
+
+ACPI_STATUS
+FlOpenMiscOutputFiles (
+ char *InputFilename);
+
+/*
+ * aslhwmap - hardware map summary
+ */
+void
+MpEmitMappingInfo (
+ void);
+
+
+/*
+ * asload - load namespace in prep for cross reference
+ */
+ACPI_STATUS
+LdLoadNamespace (
+ ACPI_PARSE_OBJECT *RootOp);
+
+
+/*
+ * asllookup - namespace lookup functions
+ */
+void
+LkFindUnreferencedObjects (
+ void);
+
+/*
+ * aslmain - startup
+ */
+void
+Usage (
+ void);
+
+void
+AslFilenameHelp (
+ void);
+
+
+/*
+ * aslnamesp - namespace output file generation
+ */
+ACPI_STATUS
+NsDisplayNamespace (
+ void);
+
+void
+NsSetupNamespaceListing (
+ void *Handle);
+
+/*
+ * asloptions - command line processing
+ */
+int
+AslCommandLine (
+ int argc,
+ char **argv);
+
+/*
+ * aslxref - namespace cross reference
+ */
+ACPI_STATUS
+XfCrossReferenceNamespace (
+ void);
+
+
+/*
+ * aslutils - common compiler utilites
+ */
+void
+DbgPrint (
+ UINT32 Type,
+ char *Format,
+ ...);
+
+/* Type values for above */
+
+#define ASL_DEBUG_OUTPUT 0
+#define ASL_PARSE_OUTPUT 1
+#define ASL_TREE_OUTPUT 2
+
+void
+UtDisplaySupportedTables (
+ void);
+
+void
+UtDisplayConstantOpcodes (
+ void);
+
+UINT8
+UtBeginEvent (
+ char *Name);
+
+void
+UtEndEvent (
+ UINT8 Event);
+
+void *
+UtLocalCalloc (
+ UINT32 Size);
+
+void
+UtPrintFormattedName (
+ UINT16 ParseOpcode,
+ UINT32 Level);
+
+void
+UtDisplaySummary (
+ UINT32 FileId);
+
+void
+UtConvertByteToHex (
+ UINT8 RawByte,
+ UINT8 *Buffer);
+
+void
+UtConvertByteToAsmHex (
+ UINT8 RawByte,
+ UINT8 *Buffer);
+
+char *
+UtGetOpName (
+ UINT32 ParseOpcode);
+
+void
+UtSetParseOpName (
+ ACPI_PARSE_OBJECT *Op);
+
+char *
+UtStringCacheCalloc (
+ UINT32 Length);
+
+void
+UtExpandLineBuffers (
+ void);
+
+void
+UtFreeLineBuffers (
+ void);
+
+ACPI_STATUS
+UtInternalizeName (
+ char *ExternalName,
+ char **ConvertedName);
+
+void
+UtAttachNamepathToOwner (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *NameNode);
+
+ACPI_PARSE_OBJECT *
+UtCheckIntegerRange (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 LowValue,
+ UINT32 HighValue);
+
+UINT64
+UtDoConstant (
+ char *String);
+
+ACPI_STATUS
+stroul64 (
+ char *String,
+ UINT32 Base,
+ UINT64 *RetInteger);
+
+
+/*
+ * asluuid - UUID support
+ */
+ACPI_STATUS
+AuValidateUuid (
+ char *InString);
+
+ACPI_STATUS
+AuConvertUuidToString (
+ char *UuIdBuffer,
+ char *OutString);
+
+/*
+ * aslresource - Resource template generation utilities
+ */
+void
+RsSmallAddressCheck (
+ UINT8 Type,
+ UINT32 Minimum,
+ UINT32 Maximum,
+ UINT32 Length,
+ UINT32 Alignment,
+ ACPI_PARSE_OBJECT *MinOp,
+ ACPI_PARSE_OBJECT *MaxOp,
+ ACPI_PARSE_OBJECT *LengthOp,
+ ACPI_PARSE_OBJECT *AlignOp,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+RsLargeAddressCheck (
+ UINT64 Minimum,
+ UINT64 Maximum,
+ UINT64 Length,
+ UINT64 Granularity,
+ UINT8 Flags,
+ ACPI_PARSE_OBJECT *MinOp,
+ ACPI_PARSE_OBJECT *MaxOp,
+ ACPI_PARSE_OBJECT *LengthOp,
+ ACPI_PARSE_OBJECT *GranOp,
+ ACPI_PARSE_OBJECT *Op);
+
+UINT16
+RsGetStringDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp);
+
+ASL_RESOURCE_NODE *
+RsAllocateResourceNode (
+ UINT32 Size);
+
+void
+RsCreateResourceField (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name,
+ UINT32 ByteOffset,
+ UINT32 BitOffset,
+ UINT32 BitLength);
+
+void
+RsSetFlagBits (
+ UINT8 *Flags,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Position,
+ UINT8 DefaultBit);
+
+void
+RsSetFlagBits16 (
+ UINT16 *Flags,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Position,
+ UINT8 DefaultBit);
+
+ACPI_PARSE_OBJECT *
+RsCompleteNodeAndGetNext (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+RsCheckListForDuplicates (
+ ACPI_PARSE_OBJECT *Op);
+
+ASL_RESOURCE_NODE *
+RsDoOneResourceDescriptor (
+ ASL_RESOURCE_INFO *Info,
+ UINT8 *State);
+
+/* Values for State above */
+
+#define ACPI_RSTATE_NORMAL 0
+#define ACPI_RSTATE_START_DEPENDENT 1
+#define ACPI_RSTATE_DEPENDENT_LIST 2
+
+UINT32
+RsLinkDescriptorChain (
+ ASL_RESOURCE_NODE **PreviousRnode,
+ ASL_RESOURCE_NODE *Rnode);
+
+void
+RsDoResourceTemplate (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * aslrestype1 - Miscellaneous Small descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoEndTagDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoEndDependentDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoMemory24Descriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoMemory32Descriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoMemory32FixedDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoStartDependentDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoStartDependentNoPriDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoVendorSmallDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * aslrestype1i - I/O-related Small descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoDmaDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoFixedDmaDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoFixedIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoIrqDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoIrqNoFlagsDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * aslrestype2 - Large resource descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoInterruptDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoVendorLargeDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoGeneralRegisterDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoGpioIntDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoGpioIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoI2cSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoSpiSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoUartSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+/*
+ * aslrestype2d - DWord address descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoDwordIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoDwordMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoDwordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * aslrestype2e - Extended address descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoExtendedIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoExtendedMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoExtendedSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * aslrestype2q - QWord address descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoQwordIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoQwordMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoQwordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * aslrestype2w - Word address descriptors
+ */
+ASL_RESOURCE_NODE *
+RsDoWordIoDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoWordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+ASL_RESOURCE_NODE *
+RsDoWordBusNumberDescriptor (
+ ASL_RESOURCE_INFO *Info);
+
+
+/*
+ * Entry to data table compiler subsystem
+ */
+ACPI_STATUS
+DtDoCompile(
+ void);
+
+ACPI_STATUS
+DtCreateTemplates (
+ char *Signature);
+
+#endif /* __ASLCOMPILER_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.l b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.l
new file mode 100644
index 0000000000..6a3541b496
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslcompiler.l
@@ -0,0 +1,738 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: aslcompiler.l - Flex/lex input file
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#include <stdlib.h>
+#include <string.h>
+YYSTYPE AslCompilerlval;
+
+/*
+ * Generation: Use the following command line:
+ *
+ * flex.exe -PAslCompiler -i -o$(InputPath).c $(InputPath)
+ *
+ * -i: Scanner must be case-insensitive
+ */
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslscanner")
+
+
+/* Local prototypes */
+
+static void
+AslDoLineDirective (void);
+
+static char
+AslDoComment (void);
+
+static char
+AslDoCommentType2 (void);
+
+static char
+AslDoStringLiteral (void);
+
+static void
+count (int type);
+
+
+/*! [Begin] no source code translation */
+
+%}
+ /* Definitions */
+
+LeadNameChar [A-Za-z_]
+DigitChar [0-9]
+HexDigitChar [A-Fa-f0-9]
+RootChar [\\]
+Nothing []
+
+NameChar [A-Za-z_0-9]
+NameSeg1 {LeadNameChar}{NameChar}
+NameSeg2 {LeadNameChar}{NameChar}{NameChar}
+NameSeg3 {LeadNameChar}{NameChar}{NameChar}{NameChar}
+NameSeg {LeadNameChar}|{NameSeg1}|{NameSeg2}|{NameSeg3}
+
+NameString {RootChar}|{RootChar}{NamePath}|[\^]+{NamePath}|{NonEmptyNamePath}
+NamePath {NonEmptyNamePath}?
+NonEmptyNamePath {NameSeg}{NamePathTail}*
+NamePathTail [.]{NameSeg}
+
+%%
+ /* Rules */
+
+[ ] { count (0); }
+[\n] { count (0); } /* Handle files with both LF and CR/LF */
+[\r] { count (0); } /* termination on both Unix and Windows */
+[ \t] { count (0); }
+
+
+"/*" { if (!AslDoComment ()) {yyterminate ();} }
+"//" { if (!AslDoCommentType2 ()) {yyterminate ();} }
+
+"\"" { if (AslDoStringLiteral ()) {return (PARSEOP_STRING_LITERAL);}
+ else {yyterminate ();} }
+";" { count (0); return(';'); }
+
+ /* ASL Extension: Standard C operators */
+
+"~" { count (3); return (PARSEOP_EXP_NOT); }
+"!" { count (3); return (PARSEOP_EXP_LOGICAL_NOT); }
+"*" { count (3); return (PARSEOP_EXP_MULTIPLY); }
+"/" { count (3); return (PARSEOP_EXP_DIVIDE); }
+"%" { count (3); return (PARSEOP_EXP_MODULO); }
+"+" { count (3); return (PARSEOP_EXP_ADD); }
+"-" { count (3); return (PARSEOP_EXP_SUBTRACT); }
+">>" { count (3); return (PARSEOP_EXP_SHIFT_RIGHT); }
+"<<" { count (3); return (PARSEOP_EXP_SHIFT_LEFT); }
+"<" { count (3); return (PARSEOP_EXP_LESS); }
+">" { count (3); return (PARSEOP_EXP_GREATER); }
+"&" { count (3); return (PARSEOP_EXP_AND); }
+"<=" { count (3); return (PARSEOP_EXP_LESS_EQUAL); }
+">=" { count (3); return (PARSEOP_EXP_GREATER_EQUAL); }
+"==" { count (3); return (PARSEOP_EXP_EQUAL); }
+"!=" { count (3); return (PARSEOP_EXP_NOT_EQUAL); }
+"|" { count (3); return (PARSEOP_EXP_OR); }
+"&&" { count (3); return (PARSEOP_EXP_LOGICAL_AND); }
+"||" { count (3); return (PARSEOP_EXP_LOGICAL_OR); }
+"++" { count (3); return (PARSEOP_EXP_INCREMENT); }
+"--" { count (3); return (PARSEOP_EXP_DECREMENT); }
+"^ " { count (3); return (PARSEOP_EXP_XOR); }
+
+ /* ASL Extension: Standard C assignment operators */
+
+"=" { count (3); return (PARSEOP_EXP_EQUALS); }
+"+=" { count (3); return (PARSEOP_EXP_ADD_EQ); }
+"-=" { count (3); return (PARSEOP_EXP_SUB_EQ); }
+"*=" { count (3); return (PARSEOP_EXP_MUL_EQ); }
+"/=" { count (3); return (PARSEOP_EXP_DIV_EQ); }
+"%=" { count (3); return (PARSEOP_EXP_MOD_EQ); }
+"<<=" { count (3); return (PARSEOP_EXP_SHL_EQ); }
+">>=" { count (3); return (PARSEOP_EXP_SHR_EQ); }
+"&=" { count (3); return (PARSEOP_EXP_AND_EQ); }
+"^=" { count (3); return (PARSEOP_EXP_XOR_EQ); }
+"|=" { count (3); return (PARSEOP_EXP_OR_EQ); }
+
+
+ /*
+ * Begin standard ASL grammar
+ */
+0[xX]{HexDigitChar}+ |
+{DigitChar}+ { AslCompilerlval.i = UtDoConstant ((char *) AslCompilertext);
+ count (1); return (PARSEOP_INTEGER); }
+
+"Include" { count (1); return (PARSEOP_INCLUDE); }
+"External" { count (1); return (PARSEOP_EXTERNAL); }
+
+ /*
+ * The #line directive is emitted by the preprocessor and handled
+ * here in the main iASL lexer - simply set the line number and
+ * optionally the current filename.
+ */
+"#line" { AslDoLineDirective ();}
+
+
+ /****************************************************************************
+ *
+ * Main ASL operators
+ *
+ ****************************************************************************/
+
+"AccessAs" { count (1); return (PARSEOP_ACCESSAS); }
+"Acquire" { count (3); return (PARSEOP_ACQUIRE); }
+"Add" { count (3); return (PARSEOP_ADD); }
+"Alias" { count (2); return (PARSEOP_ALIAS); }
+"And" { count (3); return (PARSEOP_AND); }
+"BankField" { count (2); return (PARSEOP_BANKFIELD); }
+"Break" { count (3); return (PARSEOP_BREAK); }
+"BreakPoint" { count (3); return (PARSEOP_BREAKPOINT); }
+"Buffer" { count (1); return (PARSEOP_BUFFER); }
+"Case" { count (3); return (PARSEOP_CASE); }
+"Concatenate" { count (3); return (PARSEOP_CONCATENATE); }
+"ConcatenateResTemplate" { count (3); return (PARSEOP_CONCATENATERESTEMPLATE); }
+"CondRefOf" { count (3); return (PARSEOP_CONDREFOF); }
+"Connection" { count (2); return (PARSEOP_CONNECTION); }
+"Continue" { count (3); return (PARSEOP_CONTINUE); }
+"CopyObject" { count (3); return (PARSEOP_COPYOBJECT); }
+"CreateBitField" { count (2); return (PARSEOP_CREATEBITFIELD); }
+"CreateByteField" { count (2); return (PARSEOP_CREATEBYTEFIELD); }
+"CreateDWordField" { count (2); return (PARSEOP_CREATEDWORDFIELD); }
+"CreateField" { count (2); return (PARSEOP_CREATEFIELD); }
+"CreateQWordField" { count (2); return (PARSEOP_CREATEQWORDFIELD); }
+"CreateWordField" { count (2); return (PARSEOP_CREATEWORDFIELD); }
+"DataTableRegion" { count (2); return (PARSEOP_DATATABLEREGION); }
+"Debug" { count (1); return (PARSEOP_DEBUG); }
+"Decrement" { count (3); return (PARSEOP_DECREMENT); }
+"Default" { count (3); return (PARSEOP_DEFAULT); }
+"DefinitionBlock" { count (1); return (PARSEOP_DEFINITIONBLOCK); }
+"DeRefOf" { count (3); return (PARSEOP_DEREFOF); }
+"Device" { count (2); return (PARSEOP_DEVICE); }
+"Divide" { count (3); return (PARSEOP_DIVIDE); }
+"Eisaid" { count (1); return (PARSEOP_EISAID); }
+"Else" { count (3); return (PARSEOP_ELSE); }
+"ElseIf" { count (3); return (PARSEOP_ELSEIF); }
+"Event" { count (2); return (PARSEOP_EVENT); }
+"Fatal" { count (3); return (PARSEOP_FATAL); }
+"Field" { count (2); return (PARSEOP_FIELD); }
+"FindSetLeftBit" { count (3); return (PARSEOP_FINDSETLEFTBIT); }
+"FindSetRightBit" { count (3); return (PARSEOP_FINDSETRIGHTBIT); }
+"FromBcd" { count (3); return (PARSEOP_FROMBCD); }
+"Function" { count (2); return (PARSEOP_FUNCTION); }
+"If" { count (3); return (PARSEOP_IF); }
+"Increment" { count (3); return (PARSEOP_INCREMENT); }
+"Index" { count (3); return (PARSEOP_INDEX); }
+"IndexField" { count (2); return (PARSEOP_INDEXFIELD); }
+"LAnd" { count (3); return (PARSEOP_LAND); }
+"LEqual" { count (3); return (PARSEOP_LEQUAL); }
+"LGreater" { count (3); return (PARSEOP_LGREATER); }
+"LGreaterEqual" { count (3); return (PARSEOP_LGREATEREQUAL); }
+"LLess" { count (3); return (PARSEOP_LLESS); }
+"LLessEqual" { count (3); return (PARSEOP_LLESSEQUAL); }
+"LNot" { count (3); return (PARSEOP_LNOT); }
+"LNotEqual" { count (3); return (PARSEOP_LNOTEQUAL); }
+"Load" { count (3); return (PARSEOP_LOAD); }
+"LoadTable" { count (3); return (PARSEOP_LOADTABLE); }
+"LOr" { count (3); return (PARSEOP_LOR); }
+"Match" { count (3); return (PARSEOP_MATCH); }
+"Method" { count (2); return (PARSEOP_METHOD); }
+"Mid" { count (3); return (PARSEOP_MID); }
+"Mod" { count (3); return (PARSEOP_MOD); }
+"Multiply" { count (3); return (PARSEOP_MULTIPLY); }
+"Mutex" { count (2); return (PARSEOP_MUTEX); }
+"Name" { count (2); return (PARSEOP_NAME); }
+"NAnd" { count (3); return (PARSEOP_NAND); }
+"Noop" { if (!AcpiGbl_IgnoreNoopOperator) {count (3); return (PARSEOP_NOOP);} }
+"NOr" { count (3); return (PARSEOP_NOR); }
+"Not" { count (3); return (PARSEOP_NOT); }
+"Notify" { count (3); return (PARSEOP_NOTIFY); }
+"ObjectType" { count (3); return (PARSEOP_OBJECTTYPE); }
+"Offset" { count (1); return (PARSEOP_OFFSET); }
+"One" { count (1); return (PARSEOP_ONE); }
+"Ones" { count (1); return (PARSEOP_ONES); }
+"OperationRegion" { count (2); return (PARSEOP_OPERATIONREGION); }
+"Or" { count (3); return (PARSEOP_OR); }
+"Package" { count (1); return (PARSEOP_PACKAGE); }
+"PowerResource" { count (2); return (PARSEOP_POWERRESOURCE); }
+"Processor" { count (2); return (PARSEOP_PROCESSOR); }
+"RefOf" { count (3); return (PARSEOP_REFOF); }
+"Release" { count (3); return (PARSEOP_RELEASE); }
+"Reset" { count (3); return (PARSEOP_RESET); }
+"Return" { count (3); return (PARSEOP_RETURN); }
+"Revision" { count (1); return (PARSEOP_REVISION); }
+"Scope" { count (2); return (PARSEOP_SCOPE); }
+"ShiftLeft" { count (3); return (PARSEOP_SHIFTLEFT); }
+"ShiftRight" { count (3); return (PARSEOP_SHIFTRIGHT); }
+"Signal" { count (3); return (PARSEOP_SIGNAL); }
+"SizeOf" { count (3); return (PARSEOP_SIZEOF); }
+"Sleep" { count (3); return (PARSEOP_SLEEP); }
+"Stall" { count (3); return (PARSEOP_STALL); }
+"Store" { count (3); return (PARSEOP_STORE); }
+"Subtract" { count (3); return (PARSEOP_SUBTRACT); }
+"Switch" { count (3); return (PARSEOP_SWITCH); }
+"ThermalZone" { count (2); return (PARSEOP_THERMALZONE); }
+"Timer" { count (3); return (PARSEOP_TIMER); }
+"ToBcd" { count (3); return (PARSEOP_TOBCD); }
+"ToBuffer" { count (3); return (PARSEOP_TOBUFFER); }
+"ToDecimalString" { count (3); return (PARSEOP_TODECIMALSTRING); }
+"ToHexString" { count (3); return (PARSEOP_TOHEXSTRING); }
+"ToInteger" { count (3); return (PARSEOP_TOINTEGER); }
+"ToString" { count (3); return (PARSEOP_TOSTRING); }
+"ToUuid" { count (1); return (PARSEOP_TOUUID); }
+"Unicode" { count (1); return (PARSEOP_UNICODE); }
+"Unload" { count (3); return (PARSEOP_UNLOAD); }
+"Wait" { count (3); return (PARSEOP_WAIT); }
+"While" { count (3); return (PARSEOP_WHILE); }
+"XOr" { count (3); return (PARSEOP_XOR); }
+"Zero" { count (1); return (PARSEOP_ZERO); }
+
+ /* Control method arguments and locals */
+
+"Arg0" { count (1); return (PARSEOP_ARG0); }
+"Arg1" { count (1); return (PARSEOP_ARG1); }
+"Arg2" { count (1); return (PARSEOP_ARG2); }
+"Arg3" { count (1); return (PARSEOP_ARG3); }
+"Arg4" { count (1); return (PARSEOP_ARG4); }
+"Arg5" { count (1); return (PARSEOP_ARG5); }
+"Arg6" { count (1); return (PARSEOP_ARG6); }
+"Local0" { count (1); return (PARSEOP_LOCAL0); }
+"Local1" { count (1); return (PARSEOP_LOCAL1); }
+"Local2" { count (1); return (PARSEOP_LOCAL2); }
+"Local3" { count (1); return (PARSEOP_LOCAL3); }
+"Local4" { count (1); return (PARSEOP_LOCAL4); }
+"Local5" { count (1); return (PARSEOP_LOCAL5); }
+"Local6" { count (1); return (PARSEOP_LOCAL6); }
+"Local7" { count (1); return (PARSEOP_LOCAL7); }
+
+
+ /****************************************************************************
+ *
+ * Resource Descriptor macros
+ *
+ ****************************************************************************/
+
+"ResourceTemplate" { count (1); return (PARSEOP_RESOURCETEMPLATE); }
+"RawDataBuffer" { count (1); return (PARSEOP_DATABUFFER); }
+
+"DMA" { count (1); return (PARSEOP_DMA); }
+"DWordIO" { count (1); return (PARSEOP_DWORDIO); }
+"DWordMemory" { count (1); return (PARSEOP_DWORDMEMORY); }
+"DWordSpace" { count (1); return (PARSEOP_DWORDSPACE); }
+"EndDependentFn" { count (1); return (PARSEOP_ENDDEPENDENTFN); }
+"ExtendedIO" { count (1); return (PARSEOP_EXTENDEDIO); }
+"ExtendedMemory" { count (1); return (PARSEOP_EXTENDEDMEMORY); }
+"ExtendedSpace" { count (1); return (PARSEOP_EXTENDEDSPACE); }
+"FixedDma" { count (1); return (PARSEOP_FIXEDDMA); }
+"FixedIO" { count (1); return (PARSEOP_FIXEDIO); }
+"GpioInt" { count (1); return (PARSEOP_GPIO_INT); }
+"GpioIo" { count (1); return (PARSEOP_GPIO_IO); }
+"I2cSerialBus" { count (1); return (PARSEOP_I2C_SERIALBUS); }
+"Interrupt" { count (1); return (PARSEOP_INTERRUPT); }
+"IO" { count (1); return (PARSEOP_IO); }
+"IRQ" { count (1); return (PARSEOP_IRQ); }
+"IRQNoFlags" { count (1); return (PARSEOP_IRQNOFLAGS); }
+"Memory24" { count (1); return (PARSEOP_MEMORY24); }
+"Memory32" { count (1); return (PARSEOP_MEMORY32); }
+"Memory32Fixed" { count (1); return (PARSEOP_MEMORY32FIXED); }
+"QWordIO" { count (1); return (PARSEOP_QWORDIO); }
+"QWordMemory" { count (1); return (PARSEOP_QWORDMEMORY); }
+"QWordSpace" { count (1); return (PARSEOP_QWORDSPACE); }
+"Register" { count (1); return (PARSEOP_REGISTER); }
+"SpiSerialBus" { count (1); return (PARSEOP_SPI_SERIALBUS); }
+"StartDependentFn" { count (1); return (PARSEOP_STARTDEPENDENTFN); }
+"StartDependentFnNoPri" { count (1); return (PARSEOP_STARTDEPENDENTFN_NOPRI); }
+"UartSerialBus" { count (1); return (PARSEOP_UART_SERIALBUS); }
+"VendorLong" { count (1); return (PARSEOP_VENDORLONG); }
+"VendorShort" { count (1); return (PARSEOP_VENDORSHORT); }
+"WordBusNumber" { count (1); return (PARSEOP_WORDBUSNUMBER); }
+"WordIO" { count (1); return (PARSEOP_WORDIO); }
+"WordSpace" { count (1); return (PARSEOP_WORDSPACE); }
+
+
+ /****************************************************************************
+ *
+ * Keywords used as arguments to ASL operators and macros
+ *
+ ****************************************************************************/
+
+ /* AccessAttribKeyword: Serial Bus Attributes (ACPI 5.0) */
+
+"AttribQuick" { count (0); return (PARSEOP_ACCESSATTRIB_QUICK); }
+"AttribSendReceive" { count (0); return (PARSEOP_ACCESSATTRIB_SND_RCV); }
+"AttribByte" { count (0); return (PARSEOP_ACCESSATTRIB_BYTE); }
+"AttribWord" { count (0); return (PARSEOP_ACCESSATTRIB_WORD); }
+"AttribBlock" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK); }
+"AttribProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_WORD_CALL); }
+"AttribBlockProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK_CALL); }
+
+ /* AccessAttribKeyword: Legacy synonyms for above (pre-ACPI 5.0) */
+
+"SMBQuick" { count (0); return (PARSEOP_ACCESSATTRIB_QUICK); }
+"SMBSendReceive" { count (0); return (PARSEOP_ACCESSATTRIB_SND_RCV); }
+"SMBByte" { count (0); return (PARSEOP_ACCESSATTRIB_BYTE); }
+"SMBWord" { count (0); return (PARSEOP_ACCESSATTRIB_WORD); }
+"SMBBlock" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK); }
+"SMBProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_WORD_CALL); }
+"SMBBlockProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK_CALL); }
+
+ /* AccessTypeKeyword: Field Access Types */
+
+"AnyAcc" { count (0); return (PARSEOP_ACCESSTYPE_ANY); }
+"ByteAcc" { count (0); return (PARSEOP_ACCESSTYPE_BYTE); }
+"WordAcc" { count (0); return (PARSEOP_ACCESSTYPE_WORD); }
+"DWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_DWORD); }
+"QWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_QWORD); }
+"BufferAcc" { count (0); return (PARSEOP_ACCESSTYPE_BUF); }
+
+ /* AddressingModeKeyword: Mode - Resource Descriptors (ACPI 5.0) */
+
+"AddressingMode7Bit" { count (0); return (PARSEOP_ADDRESSINGMODE_7BIT); }
+"AddressingMode10Bit" { count (0); return (PARSEOP_ADDRESSINGMODE_10BIT); }
+
+ /* AddressKeyword: ACPI memory range types */
+
+"AddressRangeMemory" { count (0); return (PARSEOP_ADDRESSTYPE_MEMORY); }
+"AddressRangeReserved" { count (0); return (PARSEOP_ADDRESSTYPE_RESERVED); }
+"AddressRangeNVS" { count (0); return (PARSEOP_ADDRESSTYPE_NVS); }
+"AddressRangeACPI" { count (0); return (PARSEOP_ADDRESSTYPE_ACPI); }
+
+ /* BusMasterKeyword: DMA Bus Mastering */
+
+"BusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_MASTER); }
+"NotBusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_NOTMASTER); }
+
+ /* ByteLengthKeyword: Bits per Byte - Resource Descriptors (ACPI 5.0) */
+
+"DataBitsFive" { count (0); return (PARSEOP_BITSPERBYTE_FIVE); }
+"DataBitsSix" { count (0); return (PARSEOP_BITSPERBYTE_SIX); }
+"DataBitsSeven" { count (0); return (PARSEOP_BITSPERBYTE_SEVEN); }
+"DataBitsEight" { count (0); return (PARSEOP_BITSPERBYTE_EIGHT); }
+"DataBitsNine" { count (0); return (PARSEOP_BITSPERBYTE_NINE); }
+
+ /* ClockPhaseKeyword: Resource Descriptors (ACPI 5.0) */
+
+"ClockPhaseFirst" { count (0); return (PARSEOP_CLOCKPHASE_FIRST); }
+"ClockPhaseSecond" { count (0); return (PARSEOP_CLOCKPHASE_SECOND); }
+
+ /* ClockPolarityKeyword: Resource Descriptors (ACPI 5.0) */
+
+"ClockPolarityLow" { count (0); return (PARSEOP_CLOCKPOLARITY_LOW); }
+"ClockPolarityHigh" { count (0); return (PARSEOP_CLOCKPOLARITY_HIGH); }
+
+ /* DecodeKeyword: Type of Memory Decoding - Resource Descriptors */
+
+"PosDecode" { count (0); return (PARSEOP_DECODETYPE_POS); }
+"SubDecode" { count (0); return (PARSEOP_DECODETYPE_SUB); }
+
+ /* DmaTypeKeyword: DMA Types - DMA Resource Descriptor */
+
+"Compatibility" { count (0); return (PARSEOP_DMATYPE_COMPATIBILITY); }
+"TypeA" { count (0); return (PARSEOP_DMATYPE_A); }
+"TypeB" { count (0); return (PARSEOP_DMATYPE_B); }
+"TypeF" { count (0); return (PARSEOP_DMATYPE_F); }
+
+ /* EndianKeyword: Endian type - Resource Descriptor (ACPI 5.0) */
+
+"LittleEndian" { count (0); return (PARSEOP_ENDIAN_LITTLE); }
+"BigEndian" { count (0); return (PARSEOP_ENDIAN_BIG); }
+
+ /* ExtendedAttribKeyword: Bus attributes, AccessAs operator (ACPI 5.0) */
+
+"AttribBytes" { count (0); return (PARSEOP_ACCESSATTRIB_MULTIBYTE); }
+"AttribRawBytes" { count (0); return (PARSEOP_ACCESSATTRIB_RAW_BYTES); }
+"AttribRawProcessBytes" { count (0); return (PARSEOP_ACCESSATTRIB_RAW_PROCESS); }
+
+ /* FlowControlKeyword: Resource Descriptors (ACPI 5.0) */
+
+"FlowControlHardware" { count (0); return (PARSEOP_FLOWCONTROL_HW); }
+"FlowControlNone" { count (0); return (PARSEOP_FLOWCONTROL_NONE); }
+"FlowControlXon" { count (0); return (PARSEOP_FLOWCONTROL_SW); }
+
+ /* InterruptLevelKeyword: Interrupt Active Types */
+
+"ActiveBoth" { count (0); return (PARSEOP_INTLEVEL_ACTIVEBOTH); }
+"ActiveHigh" { count (0); return (PARSEOP_INTLEVEL_ACTIVEHIGH); }
+"ActiveLow" { count (0); return (PARSEOP_INTLEVEL_ACTIVELOW); }
+
+ /* InterruptTypeKeyword: Interrupt Types */
+
+"Edge" { count (0); return (PARSEOP_INTTYPE_EDGE); }
+"Level" { count (0); return (PARSEOP_INTTYPE_LEVEL); }
+
+ /* IoDecodeKeyword: Type of Memory Decoding - Resource Descriptors */
+
+"Decode10" { count (0); return (PARSEOP_IODECODETYPE_10); }
+"Decode16" { count (0); return (PARSEOP_IODECODETYPE_16); }
+
+ /* IoRestrictionKeyword: I/O Restriction - GPIO Resource Descriptors (ACPI 5.0) */
+
+"IoRestrictionNone" { count (0); return (PARSEOP_IORESTRICT_NONE); }
+"IoRestrictionInputOnly" { count (0); return (PARSEOP_IORESTRICT_IN); }
+"IoRestrictionOutputOnly" { count (0); return (PARSEOP_IORESTRICT_OUT); }
+"IoRestrictionNoneAndPreserve" { count (0); return (PARSEOP_IORESTRICT_PRESERVE); }
+
+ /* LockRuleKeyword: Global Lock use for Field Operator */
+
+"Lock" { count (0); return (PARSEOP_LOCKRULE_LOCK); }
+"NoLock" { count (0); return (PARSEOP_LOCKRULE_NOLOCK); }
+
+ /* MatchOpKeyword: Types for Match Operator */
+
+"MTR" { count (0); return (PARSEOP_MATCHTYPE_MTR); }
+"MEQ" { count (0); return (PARSEOP_MATCHTYPE_MEQ); }
+"MLE" { count (0); return (PARSEOP_MATCHTYPE_MLE); }
+"MLT" { count (0); return (PARSEOP_MATCHTYPE_MLT); }
+"MGE" { count (0); return (PARSEOP_MATCHTYPE_MGE); }
+"MGT" { count (0); return (PARSEOP_MATCHTYPE_MGT); }
+
+ /* MaxKeyword: Max Range Type - Resource Descriptors */
+
+"MaxFixed" { count (0); return (PARSEOP_MAXTYPE_FIXED); }
+"MaxNotFixed" { count (0); return (PARSEOP_MAXTYPE_NOTFIXED); }
+
+ /* MemTypeKeyword: Memory Types - Resource Descriptors */
+
+"Cacheable" { count (0); return (PARSEOP_MEMTYPE_CACHEABLE); }
+"WriteCombining" { count (0); return (PARSEOP_MEMTYPE_WRITECOMBINING); }
+"Prefetchable" { count (0); return (PARSEOP_MEMTYPE_PREFETCHABLE); }
+"NonCacheable" { count (0); return (PARSEOP_MEMTYPE_NONCACHEABLE); }
+
+ /* MinKeyword: Min Range Type - Resource Descriptors */
+
+"MinFixed" { count (0); return (PARSEOP_MINTYPE_FIXED); }
+"MinNotFixed" { count (0); return (PARSEOP_MINTYPE_NOTFIXED); }
+
+ /* ObjectTypeKeyword: ACPI Object Types */
+
+"UnknownObj" { count (0); return (PARSEOP_OBJECTTYPE_UNK); }
+"IntObj" { count (0); return (PARSEOP_OBJECTTYPE_INT); }
+"StrObj" { count (0); return (PARSEOP_OBJECTTYPE_STR); }
+"BuffObj" { count (0); return (PARSEOP_OBJECTTYPE_BUF); }
+"PkgObj" { count (0); return (PARSEOP_OBJECTTYPE_PKG); }
+"FieldUnitObj" { count (0); return (PARSEOP_OBJECTTYPE_FLD); }
+"DeviceObj" { count (0); return (PARSEOP_OBJECTTYPE_DEV); }
+"EventObj" { count (0); return (PARSEOP_OBJECTTYPE_EVT); }
+"MethodObj" { count (0); return (PARSEOP_OBJECTTYPE_MTH); }
+"MutexObj" { count (0); return (PARSEOP_OBJECTTYPE_MTX); }
+"OpRegionObj" { count (0); return (PARSEOP_OBJECTTYPE_OPR); }
+"PowerResObj" { count (0); return (PARSEOP_OBJECTTYPE_POW); }
+"ProcessorObj" { count (0); return (PARSEOP_OBJECTTYPE_PRO); }
+"ThermalZoneObj" { count (0); return (PARSEOP_OBJECTTYPE_THZ); }
+"BuffFieldObj" { count (0); return (PARSEOP_OBJECTTYPE_BFF); }
+"DDBHandleObj" { count (0); return (PARSEOP_OBJECTTYPE_DDB); }
+
+ /* ParityKeyword: Resource Descriptors (ACPI 5.0) */
+
+"ParityTypeSpace" { count (0); return (PARSEOP_PARITYTYPE_SPACE); }
+"ParityTypeMark" { count (0); return (PARSEOP_PARITYTYPE_MARK); }
+"ParityTypeOdd" { count (0); return (PARSEOP_PARITYTYPE_ODD); }
+"ParityTypeEven" { count (0); return (PARSEOP_PARITYTYPE_EVEN); }
+"ParityTypeNone" { count (0); return (PARSEOP_PARITYTYPE_NONE); }
+
+ /* PinConfigKeyword: Pin Configuration - GPIO Resource Descriptors (ACPI 5.0) */
+
+"PullDefault" { count (0); return (PARSEOP_PIN_PULLDEFAULT); }
+"PullUp" { count (0); return (PARSEOP_PIN_PULLUP); }
+"PullDown" { count (0); return (PARSEOP_PIN_PULLDOWN); }
+"PullNone" { count (0); return (PARSEOP_PIN_NOPULL); }
+
+ /* PolarityKeyword: Resource Descriptors (ACPI 5.0) */
+
+"PolarityLow" { count (0); return (PARSEOP_DEVICEPOLARITY_LOW); }
+"PolarityHigh" { count (0); return (PARSEOP_DEVICEPOLARITY_HIGH); }
+
+ /* RangeTypeKeyword: I/O Range Types - Resource Descriptors */
+
+"ISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_ISAONLY); }
+"NonISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_NONISAONLY); }
+"EntireRange" { count (0); return (PARSEOP_RANGETYPE_ENTIRE); }
+
+ /* ReadWriteKeyword: Memory Access Types - Resource Descriptors */
+
+"ReadWrite" { count (0); return (PARSEOP_READWRITETYPE_BOTH); }
+"ReadOnly" { count (0); return (PARSEOP_READWRITETYPE_READONLY); }
+
+ /* RegionSpaceKeyword: Operation Region Address Space Types */
+
+"SystemIO" { count (0); return (PARSEOP_REGIONSPACE_IO); }
+"SystemMemory" { count (0); return (PARSEOP_REGIONSPACE_MEM); }
+"PCI_Config" { count (0); return (PARSEOP_REGIONSPACE_PCI); }
+"EmbeddedControl" { count (0); return (PARSEOP_REGIONSPACE_EC); }
+"SMBus" { count (0); return (PARSEOP_REGIONSPACE_SMBUS); }
+"SystemCMOS" { count (0); return (PARSEOP_REGIONSPACE_CMOS); }
+"PciBarTarget" { count (0); return (PARSEOP_REGIONSPACE_PCIBAR); }
+"IPMI" { count (0); return (PARSEOP_REGIONSPACE_IPMI); }
+"GeneralPurposeIo" { count (0); return (PARSEOP_REGIONSPACE_GPIO); } /* ACPI 5.0 */
+"GenericSerialBus" { count (0); return (PARSEOP_REGIONSPACE_GSBUS); } /* ACPI 5.0 */
+"PCC" { count (0); return (PARSEOP_REGIONSPACE_PCC); } /* ACPI 5.0 */
+"FFixedHW" { count (0); return (PARSEOP_REGIONSPACE_FFIXEDHW); }
+
+ /* ResourceTypeKeyword: Resource Usage - Resource Descriptors */
+
+"ResourceConsumer" { count (0); return (PARSEOP_RESOURCETYPE_CONSUMER); }
+"ResourceProducer" { count (0); return (PARSEOP_RESOURCETYPE_PRODUCER); }
+
+ /* SerializeRuleKeyword: Control Method Serialization */
+
+"Serialized" { count (0); return (PARSEOP_SERIALIZERULE_SERIAL); }
+"NotSerialized" { count (0); return (PARSEOP_SERIALIZERULE_NOTSERIAL); }
+
+ /* ShareTypeKeyword: Interrupt Sharing - Resource Descriptors */
+
+"Shared" { count (0); return (PARSEOP_SHARETYPE_SHARED); }
+"Exclusive" { count (0); return (PARSEOP_SHARETYPE_EXCLUSIVE); }
+"SharedAndWake" { count (0); return (PARSEOP_SHARETYPE_SHAREDWAKE); } /* ACPI 5.0 */
+"ExclusiveAndWake" { count (0); return (PARSEOP_SHARETYPE_EXCLUSIVEWAKE); } /* ACPI 5.0 */
+
+ /* SlaveModeKeyword: Resource Descriptors (ACPI 5.0) */
+
+"ControllerInitiated" { count (0); return (PARSEOP_SLAVEMODE_CONTROLLERINIT); }
+"DeviceInitiated" { count (0); return (PARSEOP_SLAVEMODE_DEVICEINIT); }
+
+ /* StopBitsKeyword: Resource Descriptors (ACPI 5.0) */
+
+"StopBitsOne" { count (0); return (PARSEOP_STOPBITS_ONE); }
+"StopBitsOnePlusHalf" { count (0); return (PARSEOP_STOPBITS_ONEPLUSHALF); }
+"StopBitsTwo" { count (0); return (PARSEOP_STOPBITS_TWO); }
+"StopBitsZero" { count (0); return (PARSEOP_STOPBITS_ZERO); }
+
+ /* TransferWidthKeyword: DMA Widths - Fixed DMA Resource Descriptor (ACPI 5.0) */
+
+"Width8bit" { count (0); return (PARSEOP_XFERSIZE_8); }
+"Width16bit" { count (0); return (PARSEOP_XFERSIZE_16); }
+"Width32bit" { count (0); return (PARSEOP_XFERSIZE_32); }
+"Width64bit" { count (0); return (PARSEOP_XFERSIZE_64); }
+"Width128bit" { count (0); return (PARSEOP_XFERSIZE_128); }
+"Width256bit" { count (0); return (PARSEOP_XFERSIZE_256); }
+
+ /* TranslationKeyword: Translation Density Types - Resource Descriptors */
+
+"SparseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_SPARSE); }
+"DenseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_DENSE); }
+
+ /* TypeKeyword: Translation Types - Resource Descriptors */
+
+"TypeTranslation" { count (0); return (PARSEOP_TYPE_TRANSLATION); }
+"TypeStatic" { count (0); return (PARSEOP_TYPE_STATIC); }
+
+ /* UpdateRuleKeyword: Field Update Rules */
+
+"Preserve" { count (0); return (PARSEOP_UPDATERULE_PRESERVE); }
+"WriteAsOnes" { count (0); return (PARSEOP_UPDATERULE_ONES); }
+"WriteAsZeros" { count (0); return (PARSEOP_UPDATERULE_ZEROS); }
+
+ /* WireModeKeyword: SPI Wire Mode - Resource Descriptors (ACPI 5.0) */
+
+"FourWireMode" { count (0); return (PARSEOP_WIREMODE_FOUR); }
+"ThreeWireMode" { count (0); return (PARSEOP_WIREMODE_THREE); }
+
+ /* XferTypeKeyword: DMA Transfer Types */
+
+"Transfer8" { count (0); return (PARSEOP_XFERTYPE_8); }
+"Transfer8_16" { count (0); return (PARSEOP_XFERTYPE_8_16); }
+"Transfer16" { count (0); return (PARSEOP_XFERTYPE_16); }
+
+ /* ToPld macro */
+
+"ToPLD" { count (0); return (PARSEOP_TOPLD); }
+
+"PLD_Revision" { count (0); return (PARSEOP_PLD_REVISION); }
+"PLD_IgnoreColor" { count (0); return (PARSEOP_PLD_IGNORECOLOR); }
+"PLD_Red" { count (0); return (PARSEOP_PLD_RED); }
+"PLD_Green" { count (0); return (PARSEOP_PLD_GREEN); }
+"PLD_Blue" { count (0); return (PARSEOP_PLD_BLUE); }
+"PLD_Width" { count (0); return (PARSEOP_PLD_WIDTH); }
+"PLD_Height" { count (0); return (PARSEOP_PLD_HEIGHT); }
+"PLD_UserVisible" { count (0); return (PARSEOP_PLD_USERVISIBLE); }
+"PLD_Dock" { count (0); return (PARSEOP_PLD_DOCK); }
+"PLD_Lid" { count (0); return (PARSEOP_PLD_LID); }
+"PLD_Panel" { count (0); return (PARSEOP_PLD_PANEL); }
+"PLD_VerticalPosition" { count (0); return (PARSEOP_PLD_VERTICALPOSITION); }
+"PLD_HorizontalPosition" { count (0); return (PARSEOP_PLD_HORIZONTALPOSITION); }
+"PLD_Shape" { count (0); return (PARSEOP_PLD_SHAPE); }
+"PLD_GroupOrientation" { count (0); return (PARSEOP_PLD_GROUPORIENTATION); }
+"PLD_GroupToken" { count (0); return (PARSEOP_PLD_GROUPTOKEN); }
+"PLD_GroupPosition" { count (0); return (PARSEOP_PLD_GROUPPOSITION); }
+"PLD_Bay" { count (0); return (PARSEOP_PLD_BAY); }
+"PLD_Ejectable" { count (0); return (PARSEOP_PLD_EJECTABLE); }
+"PLD_EjectRequired" { count (0); return (PARSEOP_PLD_EJECTREQUIRED); }
+"PLD_CabinetNumber" { count (0); return (PARSEOP_PLD_CABINETNUMBER); }
+"PLD_CardCageNumber" { count (0); return (PARSEOP_PLD_CARDCAGENUMBER); }
+"PLD_Reference" { count (0); return (PARSEOP_PLD_REFERENCE); }
+"PLD_Rotation" { count (0); return (PARSEOP_PLD_ROTATION); }
+"PLD_Order" { count (0); return (PARSEOP_PLD_ORDER); }
+"PLD_Reserved" { count (0); return (PARSEOP_PLD_RESERVED); }
+"PLD_VerticalOffset" { count (0); return (PARSEOP_PLD_VERTICALOFFSET); }
+"PLD_HorizontalOffset" { count (0); return (PARSEOP_PLD_HORIZONTALOFFSET); }
+
+
+ /* printf debug macros */
+"printf" { count (0); return (PARSEOP_PRINTF); }
+"fprintf" { count (0); return (PARSEOP_FPRINTF); }
+
+ /* Predefined compiler names */
+
+"__DATE__" { count (0); return (PARSEOP___DATE__); }
+"__FILE__" { count (0); return (PARSEOP___FILE__); }
+"__LINE__" { count (0); return (PARSEOP___LINE__); }
+"__PATH__" { count (0); return (PARSEOP___PATH__); }
+
+
+"{" { count (0); return('{'); }
+"}" { count (0); return('}'); }
+"," { count (0); return(','); }
+"(" { count (0); return('('); }
+")" { count (0); return(')'); }
+
+{NameSeg} { char *s;
+ count (0);
+ s=UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
+ if (strcmp (AslCompilertext, "\\"))
+ {
+ strcpy (s, "____");
+ AcpiUtStrupr (AslCompilertext);
+ }
+ memcpy (s, AslCompilertext, strlen (AslCompilertext));
+ AslCompilerlval.s = s;
+ DbgPrint (ASL_PARSE_OUTPUT, "NameSeg: %s\n", s);
+ return (PARSEOP_NAMESEG); }
+
+{NameString} { char *s;
+ count (0);
+ s=UtStringCacheCalloc (strlen (AslCompilertext)+1);
+ AcpiUtStrupr (AslCompilertext);
+ strcpy (s, AslCompilertext);
+ AslCompilerlval.s = s;
+ DbgPrint (ASL_PARSE_OUTPUT, "NameString: %s\n", s);
+ return (PARSEOP_NAMESTRING); }
+
+. { count (1);
+ if (isprint ((int) *AslCompilertext))
+ {
+ sprintf (MsgBuffer,
+ "Invalid character (%c), expecting ASL keyword or name",
+ *AslCompilertext);
+ }
+ else
+ {
+ sprintf (MsgBuffer,
+ "Invalid character (0x%2.2X), expecting ASL keyword or name",
+ *AslCompilertext);
+ }
+ AslCompilererror (MsgBuffer);}
+
+<<EOF>> { if (AslPopInputFileStack ())
+ {yyterminate();}
+ else
+ {return (PARSEOP_INCLUDE_END);} };
+
+%%
+
+/*! [End] no source code translation !*/
+
+/*
+ * Bring in the scanner support routines
+ */
+#include <contrib/dev/acpica/compiler/aslsupport.l>
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asldefine.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/asldefine.h
new file mode 100644
index 0000000000..9e42ddf8b2
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asldefine.h
@@ -0,0 +1,179 @@
+/******************************************************************************
+ *
+ * Module Name: asldefine.h - Common defines for the iASL compiler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ASLDEFINE_H
+#define __ASLDEFINE_H
+
+
+/*
+ * Compiler versions and names
+ */
+#define ASL_COMPILER_NAME "ASL+ Optimizing Compiler"
+#define AML_DISASSEMBLER_NAME "AML/ASL+ Disassembler"
+#define ASL_INVOCATION_NAME "iasl"
+#define ASL_CREATOR_ID "INTL"
+#define ASL_DEFINE "__IASL__"
+
+#define ASL_COMPLIANCE "Supports ACPI Specification Revision 6.0"
+
+
+/* Configuration constants */
+
+#define ASL_MAX_ERROR_COUNT 200
+#define ASL_PARSEOP_CACHE_SIZE (1024 * 16)
+#define ASL_STRING_CACHE_SIZE (1024 * 64)
+
+#define ASL_FIRST_PARSE_OPCODE PARSEOP_ACCESSAS
+#define ASL_PARSE_OPCODE_BASE PARSEOP_ACCESSAS /* First Lex type */
+
+
+/*
+ * Per-parser-generator configuration. These values are used to cheat and
+ * directly access the bison/yacc token name table (yyname or yytname).
+ * Note: These values are the index in yyname for the first lex token
+ * (PARSEOP_ACCCESSAS).
+ */
+#if defined (YYBISON)
+#define ASL_YYTNAME_START 3 /* Bison */
+#elif defined (YYBYACC)
+#define ASL_YYTNAME_START 257 /* Berkeley yacc */
+#endif
+
+
+/*
+ * Macros
+ */
+#define ASL_RESDESC_OFFSET(m) ACPI_OFFSET (AML_RESOURCE, m)
+#define ASL_PTR_DIFF(a,b) ((UINT8 *)(b) - (UINT8 *)(a))
+#define ASL_PTR_ADD(a,b) ((UINT8 *)(a) = ((UINT8 *)(a) + (b)))
+#define ASL_GET_CHILD_NODE(a) (a)->Asl.Child
+#define ASL_GET_PEER_NODE(a) (a)->Asl.Next
+#define OP_TABLE_ENTRY(a,b,c,d) {b,d,a,c}
+
+
+/* Internal AML opcodes */
+
+#define AML_RAW_DATA_BYTE (UINT16) 0xAA01 /* write one raw byte */
+#define AML_RAW_DATA_WORD (UINT16) 0xAA02 /* write 2 raw bytes */
+#define AML_RAW_DATA_DWORD (UINT16) 0xAA04 /* write 4 raw bytes */
+#define AML_RAW_DATA_QWORD (UINT16) 0xAA08 /* write 8 raw bytes */
+#define AML_RAW_DATA_BUFFER (UINT16) 0xAA0B /* raw buffer with length */
+#define AML_RAW_DATA_CHAIN (UINT16) 0xAA0C /* chain of raw buffers */
+#define AML_PACKAGE_LENGTH (UINT16) 0xAA10
+#define AML_UNASSIGNED_OPCODE (UINT16) 0xEEEE
+#define AML_DEFAULT_ARG_OP (UINT16) 0xDDDD
+
+
+/* filename suffixes for output files */
+
+#define FILE_SUFFIX_PREPROC_USER "i "
+#define FILE_SUFFIX_PREPROCESSOR "pre"
+#define FILE_SUFFIX_AML_CODE "aml"
+#define FILE_SUFFIX_MAP "map"
+#define FILE_SUFFIX_LISTING "lst"
+#define FILE_SUFFIX_HEX_DUMP "hex"
+#define FILE_SUFFIX_DEBUG "txt"
+#define FILE_SUFFIX_SOURCE "src"
+#define FILE_SUFFIX_NAMESPACE "nsp"
+#define FILE_SUFFIX_ASM_SOURCE "asm"
+#define FILE_SUFFIX_C_SOURCE "c"
+#define FILE_SUFFIX_DISASSEMBLY "dsl"
+#define FILE_SUFFIX_ASM_INCLUDE "inc"
+#define FILE_SUFFIX_C_INCLUDE "h"
+#define FILE_SUFFIX_ASL_CODE "asl"
+#define FILE_SUFFIX_C_OFFSET "offset.h"
+
+
+/* Types for input files */
+
+#define ASL_INPUT_TYPE_BINARY 0
+#define ASL_INPUT_TYPE_ACPI_TABLE 1
+#define ASL_INPUT_TYPE_ASCII_ASL 2
+#define ASL_INPUT_TYPE_ASCII_DATA 3
+
+
+/* Misc */
+
+#define ASL_EXTERNAL_METHOD 255
+#define ASL_ABORT TRUE
+#define ASL_NO_ABORT FALSE
+#define ASL_EOF ACPI_UINT32_MAX
+#define ASL_WITHIN_COMMENT (ACPI_UINT32_MAX -1)
+#define ASL_BLANK_LINE (ACPI_UINT32_MAX -1)
+
+
+/* Listings */
+
+#define ASL_LISTING_LINE_PREFIX ": "
+
+
+/* Support for reserved method names */
+
+#define ACPI_VALID_RESERVED_NAME_MAX 0x80000000
+#define ACPI_NOT_RESERVED_NAME ACPI_UINT32_MAX
+#define ACPI_PREDEFINED_NAME (ACPI_UINT32_MAX - 1)
+#define ACPI_EVENT_RESERVED_NAME (ACPI_UINT32_MAX - 2)
+#define ACPI_COMPILER_RESERVED_NAME (ACPI_UINT32_MAX - 3)
+
+
+/* Helper macros for resource tag creation */
+
+#define RsCreateMultiBitField \
+ RsCreateResourceField
+
+#define RsCreateBitField(Op, Name, ByteOffset, BitOffset) \
+ RsCreateResourceField (Op, Name, ByteOffset, BitOffset, 1)
+
+#define RsCreateByteField(Op, Name, ByteOffset) \
+ RsCreateResourceField (Op, Name, ByteOffset, 0, 8);
+
+#define RsCreateWordField(Op, Name, ByteOffset) \
+ RsCreateResourceField (Op, Name, ByteOffset, 0, 16);
+
+#define RsCreateDwordField(Op, Name, ByteOffset) \
+ RsCreateResourceField (Op, Name, ByteOffset, 0, 32);
+
+#define RsCreateQwordField(Op, Name, ByteOffset) \
+ RsCreateResourceField (Op, Name, ByteOffset, 0, 64);
+
+#endif /* ASLDEFINE.H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslerror.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslerror.c
new file mode 100644
index 0000000000..870e30b6d3
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslerror.c
@@ -0,0 +1,929 @@
+/******************************************************************************
+ *
+ * Module Name: aslerror - Error handling and statistics
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslerror")
+
+/* Local prototypes */
+
+static void
+AeAddToErrorLog (
+ ASL_ERROR_MSG *Enode);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslAbort
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
+ * I/O errors.
+ *
+ ******************************************************************************/
+
+void
+AslAbort (
+ void)
+{
+
+ AePrintErrorLog (ASL_FILE_STDERR);
+ if (Gbl_DebugFlag)
+ {
+ /* Print error summary to stdout also */
+
+ AePrintErrorLog (ASL_FILE_STDOUT);
+ }
+
+ exit (1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeClearErrorLog
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Empty the error list
+ *
+ ******************************************************************************/
+
+void
+AeClearErrorLog (
+ void)
+{
+ ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
+ ASL_ERROR_MSG *Next;
+
+ /* Walk the error node list */
+
+ while (Enode)
+ {
+ Next = Enode->Next;
+ ACPI_FREE (Enode);
+ Enode = Next;
+ }
+
+ Gbl_ErrorLog = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeAddToErrorLog
+ *
+ * PARAMETERS: Enode - An error node to add to the log
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a new error node to the error log. The error log is
+ * ordered by the "logical" line number (cumulative line number
+ * including all include files.)
+ *
+ ******************************************************************************/
+
+static void
+AeAddToErrorLog (
+ ASL_ERROR_MSG *Enode)
+{
+ ASL_ERROR_MSG *Next;
+ ASL_ERROR_MSG *Prev;
+
+
+ /* If Gbl_ErrorLog is null, this is the first error node */
+
+ if (!Gbl_ErrorLog)
+ {
+ Gbl_ErrorLog = Enode;
+ return;
+ }
+
+ /*
+ * Walk error list until we find a line number greater than ours.
+ * List is sorted according to line number.
+ */
+ Prev = NULL;
+ Next = Gbl_ErrorLog;
+
+ while ((Next) &&
+ (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
+ {
+ Prev = Next;
+ Next = Next->Next;
+ }
+
+ /* Found our place in the list */
+
+ Enode->Next = Next;
+
+ if (Prev)
+ {
+ Prev->Next = Enode;
+ }
+ else
+ {
+ Gbl_ErrorLog = Enode;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AePrintException
+ *
+ * PARAMETERS: FileId - ID of output file
+ * Enode - Error node to print
+ * Header - Additional text before each message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print the contents of an error node.
+ *
+ * NOTE: We don't use the FlxxxFile I/O functions here because on error
+ * they abort the compiler and call this function! Since we
+ * are reporting errors here, we ignore most output errors and
+ * just try to get out as much as we can.
+ *
+ ******************************************************************************/
+
+void
+AePrintException (
+ UINT32 FileId,
+ ASL_ERROR_MSG *Enode,
+ char *Header)
+{
+ UINT8 SourceByte;
+ int Actual;
+ size_t RActual;
+ UINT32 MsgLength;
+ const char *MainMessage;
+ char *ExtraMessage;
+ UINT32 SourceColumn;
+ UINT32 ErrorColumn;
+ FILE *OutputFile;
+ FILE *SourceFile = NULL;
+ long FileSize;
+ BOOLEAN PrematureEOF = FALSE;
+ UINT32 Total = 0;
+
+
+ if (Gbl_NoErrors)
+ {
+ return;
+ }
+
+ /*
+ * Only listing files have a header, and remarks/optimizations
+ * are always output
+ */
+ if (!Header)
+ {
+ /* Ignore remarks if requested */
+
+ switch (Enode->Level)
+ {
+ case ASL_WARNING:
+ case ASL_WARNING2:
+ case ASL_WARNING3:
+
+ if (!Gbl_DisplayWarnings)
+ {
+ return;
+ }
+ break;
+
+ case ASL_REMARK:
+
+ if (!Gbl_DisplayRemarks)
+ {
+ return;
+ }
+ break;
+
+ case ASL_OPTIMIZATION:
+
+ if (!Gbl_DisplayOptimizations)
+ {
+ return;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+
+ /* Get the various required file handles */
+
+ OutputFile = Gbl_Files[FileId].Handle;
+
+ if (!Enode->SourceLine)
+ {
+ /* Use the merged header/source file if present, otherwise use input file */
+
+ SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
+ if (!SourceFile)
+ {
+ SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
+ }
+
+ if (SourceFile)
+ {
+ /* Determine if the error occurred at source file EOF */
+
+ fseek (SourceFile, 0, SEEK_END);
+ FileSize = ftell (SourceFile);
+
+ if ((long) Enode->LogicalByteOffset >= FileSize)
+ {
+ PrematureEOF = TRUE;
+ }
+ }
+ }
+
+ if (Header)
+ {
+ fprintf (OutputFile, "%s", Header);
+ }
+
+ /* Print filename and line number if present and valid */
+
+ if (Enode->Filename)
+ {
+ if (Gbl_VerboseErrors)
+ {
+ fprintf (OutputFile, "%-8s", Enode->Filename);
+
+ if (Enode->LineNumber)
+ {
+ if (Enode->SourceLine)
+ {
+ fprintf (OutputFile, " %6u: %s",
+ Enode->LineNumber, Enode->SourceLine);
+ }
+ else
+ {
+ fprintf (OutputFile, " %6u: ", Enode->LineNumber);
+
+ /*
+ * If not at EOF, get the corresponding source code line and
+ * display it. Don't attempt this if we have a premature EOF
+ * condition.
+ */
+ if (!PrematureEOF)
+ {
+ /*
+ * Seek to the offset in the combined source file, read
+ * the source line, and write it to the output.
+ */
+ Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
+ (int) SEEK_SET);
+ if (Actual)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Seek error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+ }
+ else
+ {
+ RActual = fread (&SourceByte, 1, 1, SourceFile);
+ if (RActual != 1)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Read error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+ }
+ else
+ {
+ /* Read/write the source line, up to the maximum line length */
+
+ while (RActual && SourceByte && (SourceByte != '\n'))
+ {
+ if (Total < 256)
+ {
+ /* After the max line length, we will just read the line, no write */
+
+ if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
+ {
+ printf ("[*** iASL: Write error on output file ***]\n");
+ return;
+ }
+ }
+ else if (Total == 256)
+ {
+ fprintf (OutputFile,
+ "\n[*** iASL: Very long input line, message below refers to column %u ***]",
+ Enode->Column);
+ }
+
+ RActual = fread (&SourceByte, 1, 1, SourceFile);
+ if (RActual != 1)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Read error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+ return;
+ }
+ Total++;
+ }
+ }
+ }
+ }
+
+ fprintf (OutputFile, "\n");
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Less verbose version of the error message, enabled via the
+ * -vi switch. The format is compatible with MS Visual Studio.
+ */
+ fprintf (OutputFile, "%s", Enode->Filename);
+
+ if (Enode->LineNumber)
+ {
+ fprintf (OutputFile, "(%u) : ",
+ Enode->LineNumber);
+ }
+ }
+ }
+
+ /* If a NULL message ID, just print the raw message */
+
+ if (Enode->MessageId == 0)
+ {
+ fprintf (OutputFile, "%s\n", Enode->Message);
+ return;
+ }
+
+ /* Decode the message ID */
+
+ fprintf (OutputFile, "%s %4.4d -",
+ AeDecodeExceptionLevel (Enode->Level),
+ AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
+
+ MainMessage = AeDecodeMessageId (Enode->MessageId);
+ ExtraMessage = Enode->Message;
+
+ /* If a NULL line number, just print the decoded message */
+
+ if (!Enode->LineNumber)
+ {
+ fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
+ return;
+ }
+
+ MsgLength = strlen (MainMessage);
+ if (MsgLength == 0)
+ {
+ /* Use the secondary/extra message as main message */
+
+ MainMessage = Enode->Message;
+ if (!MainMessage)
+ {
+ MainMessage = "";
+ }
+
+ MsgLength = strlen (MainMessage);
+ ExtraMessage = NULL;
+ }
+
+ if (Gbl_VerboseErrors && !PrematureEOF)
+ {
+ if (Total >= 256)
+ {
+ fprintf (OutputFile, " %s",
+ MainMessage);
+ }
+ else
+ {
+ SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
+ ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
+
+ if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
+ {
+ fprintf (OutputFile, "%*s%s",
+ (int) ((SourceColumn - 1) - ErrorColumn),
+ MainMessage, " ^ ");
+ }
+ else
+ {
+ fprintf (OutputFile, "%*s %s",
+ (int) ((SourceColumn - ErrorColumn) + 1), "^",
+ MainMessage);
+ }
+ }
+ }
+ else
+ {
+ fprintf (OutputFile, " %s", MainMessage);
+ }
+
+ /* Print the extra info message if present */
+
+ if (ExtraMessage)
+ {
+ fprintf (OutputFile, " (%s)", ExtraMessage);
+ }
+
+ if (PrematureEOF)
+ {
+ fprintf (OutputFile, " and premature End-Of-File");
+ }
+
+ fprintf (OutputFile, "\n");
+ if (Gbl_VerboseErrors)
+ {
+ fprintf (OutputFile, "\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AePrintErrorLog
+ *
+ * PARAMETERS: FileId - Where to output the error log
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print the entire contents of the error log
+ *
+ ******************************************************************************/
+
+void
+AePrintErrorLog (
+ UINT32 FileId)
+{
+ ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
+
+
+ /* Walk the error node list */
+
+ while (Enode)
+ {
+ AePrintException (FileId, Enode, NULL);
+ Enode = Enode->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCommonError2
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * LineNumber - Actual file line number
+ * Column - Column in current line
+ * SourceLine - Actual source code line
+ * Filename - source filename
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new error node and add it to the error log
+ *
+ ******************************************************************************/
+
+void
+AslCommonError2 (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 Column,
+ char *SourceLine,
+ char *Filename,
+ char *ExtraMessage)
+{
+ char *MessageBuffer = NULL;
+ char *LineBuffer;
+ ASL_ERROR_MSG *Enode;
+
+
+ Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
+
+ if (ExtraMessage)
+ {
+ /* Allocate a buffer for the message and a new error node */
+
+ MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
+
+ /* Keep a copy of the extra message */
+
+ strcpy (MessageBuffer, ExtraMessage);
+ }
+
+ LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
+ strcpy (LineBuffer, SourceLine);
+
+ /* Initialize the error node */
+
+ if (Filename)
+ {
+ Enode->Filename = Filename;
+ Enode->FilenameLength = strlen (Filename);
+ if (Enode->FilenameLength < 6)
+ {
+ Enode->FilenameLength = 6;
+ }
+ }
+
+ Enode->MessageId = MessageId;
+ Enode->Level = Level;
+ Enode->LineNumber = LineNumber;
+ Enode->LogicalLineNumber = LineNumber;
+ Enode->LogicalByteOffset = 0;
+ Enode->Column = Column;
+ Enode->Message = MessageBuffer;
+ Enode->SourceLine = LineBuffer;
+
+ /* Add the new node to the error node list */
+
+ AeAddToErrorLog (Enode);
+
+ if (Gbl_DebugFlag)
+ {
+ /* stderr is a file, send error to it immediately */
+
+ AePrintException (ASL_FILE_STDERR, Enode, NULL);
+ }
+
+ Gbl_ExceptionCount[Level]++;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCommonError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * CurrentLineNumber - Actual file line number
+ * LogicalLineNumber - Cumulative line number
+ * LogicalByteOffset - Byte offset in source file
+ * Column - Column in current line
+ * Filename - source filename
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new error node and add it to the error log
+ *
+ ******************************************************************************/
+
+void
+AslCommonError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 CurrentLineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
+ UINT32 Column,
+ char *Filename,
+ char *ExtraMessage)
+{
+ char *MessageBuffer = NULL;
+ ASL_ERROR_MSG *Enode;
+
+
+ Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
+
+ if (ExtraMessage)
+ {
+ /* Allocate a buffer for the message and a new error node */
+
+ MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
+
+ /* Keep a copy of the extra message */
+
+ strcpy (MessageBuffer, ExtraMessage);
+ }
+
+ /* Initialize the error node */
+
+ if (Filename)
+ {
+ Enode->Filename = Filename;
+ Enode->FilenameLength = strlen (Filename);
+ if (Enode->FilenameLength < 6)
+ {
+ Enode->FilenameLength = 6;
+ }
+ }
+
+ Enode->MessageId = MessageId;
+ Enode->Level = Level;
+ Enode->LineNumber = CurrentLineNumber;
+ Enode->LogicalLineNumber = LogicalLineNumber;
+ Enode->LogicalByteOffset = LogicalByteOffset;
+ Enode->Column = Column;
+ Enode->Message = MessageBuffer;
+ Enode->SourceLine = NULL;
+
+ /* Add the new node to the error node list */
+
+ AeAddToErrorLog (Enode);
+
+ if (Gbl_DebugFlag)
+ {
+ /* stderr is a file, send error to it immediately */
+
+ AePrintException (ASL_FILE_STDERR, Enode, NULL);
+ }
+
+ Gbl_ExceptionCount[Level]++;
+ if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
+ {
+ printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
+
+ Gbl_SourceLine = 0;
+ Gbl_NextError = Gbl_ErrorLog;
+ CmCleanupAndExit ();
+ exit(1);
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDisableException
+ *
+ * PARAMETERS: MessageIdString - ID to be disabled
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter a message ID into the global disabled messages table
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AslDisableException (
+ char *MessageIdString)
+{
+ UINT32 MessageId;
+
+
+ /* Convert argument to an integer and validate it */
+
+ MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
+
+ if ((MessageId < 2000) || (MessageId > 5999))
+ {
+ printf ("\"%s\" is not a valid warning/remark ID\n",
+ MessageIdString);
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Insert value into the global disabled message array */
+
+ if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
+ {
+ printf ("Too many messages have been disabled (max %u)\n",
+ ASL_MAX_DISABLED_MESSAGES);
+ return (AE_LIMIT);
+ }
+
+ Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
+ Gbl_DisabledMessagesIndex++;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslIsExceptionDisabled
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ *
+ * RETURN: TRUE if exception/message should be ignored
+ *
+ * DESCRIPTION: Check if the user has specified options such that this
+ * exception should be ignored
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AslIsExceptionDisabled (
+ UINT8 Level,
+ UINT16 MessageId)
+{
+ UINT32 EncodedMessageId;
+ UINT32 i;
+
+
+ switch (Level)
+ {
+ case ASL_WARNING2:
+ case ASL_WARNING3:
+
+ /* Check for global disable via -w1/-w2/-w3 options */
+
+ if (Level > Gbl_WarningLevel)
+ {
+ return (TRUE);
+ }
+ /* Fall through */
+
+ case ASL_WARNING:
+ case ASL_REMARK:
+ /*
+ * Ignore this warning/remark if it has been disabled by
+ * the user (-vw option)
+ */
+ EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
+ for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
+ {
+ /* Simple implementation via fixed array */
+
+ if (EncodedMessageId == Gbl_DisabledMessages[i])
+ {
+ return (TRUE);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * Op - Parse node where error happened
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
+ * except the parser.)
+ *
+ ******************************************************************************/
+
+void
+AslError (
+ UINT8 Level,
+ UINT16 MessageId,
+ ACPI_PARSE_OBJECT *Op,
+ char *ExtraMessage)
+{
+
+ /* Check if user wants to ignore this exception */
+
+ if (Gbl_AllExceptionsDisabled ||
+ AslIsExceptionDisabled (Level, MessageId))
+ {
+ return;
+ }
+
+ if (Op)
+ {
+ AslCommonError (Level, MessageId, Op->Asl.LineNumber,
+ Op->Asl.LogicalLineNumber,
+ Op->Asl.LogicalByteOffset,
+ Op->Asl.Column,
+ Op->Asl.Filename, ExtraMessage);
+ }
+ else
+ {
+ AslCommonError (Level, MessageId, 0,
+ 0, 0, 0, NULL, ExtraMessage);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCoreSubsystemError
+ *
+ * PARAMETERS: Op - Parse node where error happened
+ * Status - The ACPICA Exception
+ * ExtraMessage - additional error message
+ * Abort - TRUE -> Abort compilation
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
+ * core subsystem.
+ *
+ ******************************************************************************/
+
+void
+AslCoreSubsystemError (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status,
+ char *ExtraMessage,
+ BOOLEAN Abort)
+{
+
+ sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
+
+ if (Op)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
+ Op->Asl.LogicalLineNumber,
+ Op->Asl.LogicalByteOffset,
+ Op->Asl.Column,
+ Op->Asl.Filename, MsgBuffer);
+ }
+ else
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
+ 0, 0, 0, NULL, MsgBuffer);
+ }
+
+ if (Abort)
+ {
+ AslAbort ();
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCompilererror
+ *
+ * PARAMETERS: CompilerMessage - Error message from the parser
+ *
+ * RETURN: Status (0 for now)
+ *
+ * DESCRIPTION: Report an error situation discovered in a production
+ * NOTE: don't change the name of this function, it is called
+ * from the auto-generated parser.
+ *
+ ******************************************************************************/
+
+int
+AslCompilererror (
+ const char *CompilerMessage)
+{
+
+ Gbl_SyntaxError++;
+
+ AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
+ Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
+ Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
+ ACPI_CAST_PTR (char, CompilerMessage));
+
+ return (0);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfileio.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfileio.c
new file mode 100644
index 0000000000..3feb8ea4c2
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfileio.c
@@ -0,0 +1,400 @@
+/******************************************************************************
+ *
+ * Module Name: aslfileio - File I/O support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslfileio")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlFileError
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * ErrorId - Index into error message array
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode errno to an error message and add the entire error
+ * to the error log.
+ *
+ ******************************************************************************/
+
+void
+FlFileError (
+ UINT32 FileId,
+ UINT8 ErrorId)
+{
+
+ sprintf (MsgBuffer, "\"%s\" (%s) - %s", Gbl_Files[FileId].Filename,
+ Gbl_Files[FileId].Description, strerror (errno));
+ AslCommonError (ASL_ERROR, ErrorId, 0, 0, 0, 0, NULL, MsgBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * Filename - file pathname to open
+ * Mode - Open mode for fopen
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Open a file.
+ * NOTE: Aborts compiler on any error.
+ *
+ ******************************************************************************/
+
+void
+FlOpenFile (
+ UINT32 FileId,
+ char *Filename,
+ char *Mode)
+{
+ FILE *File;
+
+
+ Gbl_Files[FileId].Filename = Filename;
+ Gbl_Files[FileId].Handle = NULL;
+
+ File = fopen (Filename, Mode);
+ if (!File)
+ {
+ FlFileError (FileId, ASL_MSG_OPEN);
+ AslAbort ();
+ }
+
+ Gbl_Files[FileId].Handle = File;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlGetFileSize
+ *
+ * PARAMETERS: FileId - Index into file info array
+ *
+ * RETURN: File Size
+ *
+ * DESCRIPTION: Get current file size. Uses common seek-to-EOF function.
+ * File must be open. Aborts compiler on error.
+ *
+ ******************************************************************************/
+
+UINT32
+FlGetFileSize (
+ UINT32 FileId)
+{
+ UINT32 FileSize;
+
+
+ FileSize = CmGetFileSize (Gbl_Files[FileId].Handle);
+ if (FileSize == ACPI_UINT32_MAX)
+ {
+ AslAbort();
+ }
+
+ return (FileSize);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlReadFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * Buffer - Where to place the data
+ * Length - Amount to read
+ *
+ * RETURN: Status. AE_ERROR indicates EOF.
+ *
+ * DESCRIPTION: Read data from an open file.
+ * NOTE: Aborts compiler on any error.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlReadFile (
+ UINT32 FileId,
+ void *Buffer,
+ UINT32 Length)
+{
+ UINT32 Actual;
+
+
+ /* Read and check for error */
+
+ Actual = fread (Buffer, 1, Length, Gbl_Files[FileId].Handle);
+ if (Actual < Length)
+ {
+ if (feof (Gbl_Files[FileId].Handle))
+ {
+ /* End-of-file, just return error */
+
+ return (AE_ERROR);
+ }
+
+ FlFileError (FileId, ASL_MSG_READ);
+ AslAbort ();
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlWriteFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * Buffer - Data to write
+ * Length - Amount of data to write
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to an open file.
+ * NOTE: Aborts compiler on any error.
+ *
+ ******************************************************************************/
+
+void
+FlWriteFile (
+ UINT32 FileId,
+ void *Buffer,
+ UINT32 Length)
+{
+ UINT32 Actual;
+
+
+ /* Write and check for error */
+
+ Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[FileId].Handle);
+ if (Actual != Length)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+
+ if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag)
+ {
+ /* Duplicate the output to the user preprocessor (.i) file */
+
+ Actual = fwrite ((char *) Buffer, 1, Length,
+ Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle);
+ if (Actual != Length)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlPrintFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * Format - Printf format string
+ * ... - Printf arguments
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Formatted write to an open file.
+ * NOTE: Aborts compiler on any error.
+ *
+ ******************************************************************************/
+
+void
+FlPrintFile (
+ UINT32 FileId,
+ char *Format,
+ ...)
+{
+ INT32 Actual;
+ va_list Args;
+
+
+ va_start (Args, Format);
+ Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args);
+ va_end (Args);
+
+ if (Actual == -1)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+
+ if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag)
+ {
+ /*
+ * Duplicate the output to the user preprocessor (.i) file,
+ * except: no #line directives.
+ */
+ if (!strncmp (Format, "#line", 5))
+ {
+ return;
+ }
+
+ va_start (Args, Format);
+ Actual = vfprintf (Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle,
+ Format, Args);
+ va_end (Args);
+
+ if (Actual == -1)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+ }
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlSeekFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ * Offset - Absolute byte offset in file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Seek to absolute offset.
+ * NOTE: Aborts compiler on any error.
+ *
+ ******************************************************************************/
+
+void
+FlSeekFile (
+ UINT32 FileId,
+ long Offset)
+{
+ int Error;
+
+
+ Error = fseek (Gbl_Files[FileId].Handle, Offset, SEEK_SET);
+ if (Error)
+ {
+ FlFileError (FileId, ASL_MSG_SEEK);
+ AslAbort ();
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlCloseFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Close an open file. Aborts compiler on error
+ *
+ ******************************************************************************/
+
+void
+FlCloseFile (
+ UINT32 FileId)
+{
+ int Error;
+
+
+ if (!Gbl_Files[FileId].Handle)
+ {
+ return;
+ }
+
+ Error = fclose (Gbl_Files[FileId].Handle);
+ if (Error)
+ {
+ FlFileError (FileId, ASL_MSG_CLOSE);
+ AslAbort ();
+ }
+
+ /* Do not clear/free the filename string */
+
+ Gbl_Files[FileId].Handle = NULL;
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlDeleteFile
+ *
+ * PARAMETERS: FileId - Index into file info array
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete a file.
+ *
+ ******************************************************************************/
+
+void
+FlDeleteFile (
+ UINT32 FileId)
+{
+ ASL_FILE_INFO *Info = &Gbl_Files[FileId];
+
+
+ if (!Info->Filename)
+ {
+ return;
+ }
+
+ if (remove (Info->Filename))
+ {
+ printf ("%s (%s file) ",
+ Info->Filename, Info->Description);
+ perror ("Could not delete");
+ }
+
+ Info->Filename = NULL;
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfiles.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfiles.c
new file mode 100644
index 0000000000..762abcd027
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfiles.c
@@ -0,0 +1,905 @@
+/******************************************************************************
+ *
+ * Module Name: aslfiles - File support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslfiles")
+
+/* Local prototypes */
+
+static FILE *
+FlOpenIncludeWithPrefix (
+ char *PrefixDir,
+ ACPI_PARSE_OBJECT *Op,
+ char *Filename);
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_STATUS
+FlParseInputPathname (
+ char *InputFilename);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlSetLineNumber
+ *
+ * PARAMETERS: Op - Parse node for the LINE asl statement
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Set the current line number
+ *
+ ******************************************************************************/
+
+void
+FlSetLineNumber (
+ UINT32 LineNumber)
+{
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
+ LineNumber, Gbl_LogicalLineNumber);
+
+ Gbl_CurrentLineNumber = LineNumber;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlSetFilename
+ *
+ * PARAMETERS: Op - Parse node for the LINE asl statement
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Set the current filename
+ *
+ ******************************************************************************/
+
+void
+FlSetFilename (
+ char *Filename)
+{
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
+ Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
+
+ /* No need to free any existing filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlAddIncludeDirectory
+ *
+ * PARAMETERS: Dir - Directory pathname string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a directory the list of include prefix directories.
+ *
+ ******************************************************************************/
+
+void
+FlAddIncludeDirectory (
+ char *Dir)
+{
+ ASL_INCLUDE_DIR *NewDir;
+ ASL_INCLUDE_DIR *NextDir;
+ ASL_INCLUDE_DIR *PrevDir = NULL;
+ UINT32 NeedsSeparator = 0;
+ size_t DirLength;
+
+
+ DirLength = strlen (Dir);
+ if (!DirLength)
+ {
+ return;
+ }
+
+ /* Make sure that the pathname ends with a path separator */
+
+ if ((Dir[DirLength-1] != '/') &&
+ (Dir[DirLength-1] != '\\'))
+ {
+ NeedsSeparator = 1;
+ }
+
+ NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
+ NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
+ strcpy (NewDir->Dir, Dir);
+ if (NeedsSeparator)
+ {
+ strcat (NewDir->Dir, "/");
+ }
+
+ /*
+ * Preserve command line ordering of -I options by adding new elements
+ * at the end of the list
+ */
+ NextDir = Gbl_IncludeDirList;
+ while (NextDir)
+ {
+ PrevDir = NextDir;
+ NextDir = NextDir->Next;
+ }
+
+ if (PrevDir)
+ {
+ PrevDir->Next = NewDir;
+ }
+ else
+ {
+ Gbl_IncludeDirList = NewDir;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlMergePathnames
+ *
+ * PARAMETERS: PrefixDir - Prefix directory pathname. Can be NULL or
+ * a zero length string.
+ * FilePathname - The include filename from the source ASL.
+ *
+ * RETURN: Merged pathname string
+ *
+ * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
+ * arrive at a minimal length string. Merge can occur if the
+ * FilePathname is relative to the PrefixDir.
+ *
+ ******************************************************************************/
+
+char *
+FlMergePathnames (
+ char *PrefixDir,
+ char *FilePathname)
+{
+ char *CommonPath;
+ char *Pathname;
+ char *LastElement;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
+ "Include: FilePathname - \"%s\"\n",
+ PrefixDir, FilePathname);
+
+ /*
+ * If there is no prefix directory or if the file pathname is absolute,
+ * just return the original file pathname
+ */
+ if (!PrefixDir || (!*PrefixDir) ||
+ (*FilePathname == '/') ||
+ (FilePathname[1] == ':'))
+ {
+ Pathname = UtStringCacheCalloc (strlen (FilePathname) + 1);
+ strcpy (Pathname, FilePathname);
+ goto ConvertBackslashes;
+ }
+
+ /* Need a local copy of the prefix directory path */
+
+ CommonPath = UtStringCacheCalloc (strlen (PrefixDir) + 1);
+ strcpy (CommonPath, PrefixDir);
+
+ /*
+ * Walk forward through the file path, and simultaneously backward
+ * through the prefix directory path until there are no more
+ * relative references at the start of the file path.
+ */
+ while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
+ {
+ /* Remove last element of the prefix directory path */
+
+ LastElement = strrchr (CommonPath, '/');
+ if (!LastElement)
+ {
+ goto ConcatenatePaths;
+ }
+
+ *LastElement = 0; /* Terminate CommonPath string */
+ FilePathname += 3; /* Point to next path element */
+ }
+
+ /*
+ * Remove the last element of the prefix directory path (it is the same as
+ * the first element of the file pathname), and build the final merged
+ * pathname.
+ */
+ LastElement = strrchr (CommonPath, '/');
+ if (LastElement)
+ {
+ *LastElement = 0;
+ }
+
+ /* Build the final merged pathname */
+
+ConcatenatePaths:
+ Pathname = UtStringCacheCalloc (strlen (CommonPath) + strlen (FilePathname) + 2);
+ if (LastElement && *CommonPath)
+ {
+ strcpy (Pathname, CommonPath);
+ strcat (Pathname, "/");
+ }
+ strcat (Pathname, FilePathname);
+
+ /* Convert all backslashes to normal slashes */
+
+ConvertBackslashes:
+ UtConvertBackslashes (Pathname);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
+ Pathname);
+ return (Pathname);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenIncludeWithPrefix
+ *
+ * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero
+ * length string.
+ * Filename - The include filename from the source ASL.
+ *
+ * RETURN: Valid file descriptor if successful. Null otherwise.
+ *
+ * DESCRIPTION: Open an include file and push it on the input file stack.
+ *
+ ******************************************************************************/
+
+static FILE *
+FlOpenIncludeWithPrefix (
+ char *PrefixDir,
+ ACPI_PARSE_OBJECT *Op,
+ char *Filename)
+{
+ FILE *IncludeFile;
+ char *Pathname;
+ UINT32 OriginalLineNumber;
+
+
+ /* Build the full pathname to the file */
+
+ Pathname = FlMergePathnames (PrefixDir, Filename);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
+ Pathname);
+
+ /* Attempt to open the file, push if successful */
+
+ IncludeFile = fopen (Pathname, "r");
+ if (!IncludeFile)
+ {
+ fprintf (stderr, "Could not open include file %s\n", Pathname);
+ ACPI_FREE (Pathname);
+ return (NULL);
+ }
+
+ /*
+ * Check the entire include file for any # preprocessor directives.
+ * This is because there may be some confusion between the #include
+ * preprocessor directive and the ASL Include statement. A file included
+ * by the ASL include cannot contain preprocessor directives because
+ * the preprocessor has already run by the time the ASL include is
+ * recognized (by the compiler, not the preprocessor.)
+ *
+ * Note: DtGetNextLine strips/ignores comments.
+ * Save current line number since DtGetNextLine modifies it.
+ */
+ Gbl_CurrentLineNumber--;
+ OriginalLineNumber = Gbl_CurrentLineNumber;
+ while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
+ {
+ if (Gbl_CurrentLineBuffer[0] == '#')
+ {
+ AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE,
+ Op, "use #include instead");
+ }
+ }
+ Gbl_CurrentLineNumber = OriginalLineNumber;
+
+ /* Must seek back to the start of the file */
+
+ fseek (IncludeFile, 0, SEEK_SET);
+
+ /* Push the include file on the open input file stack */
+
+ AslPushInputFileStack (IncludeFile, Pathname);
+ return (IncludeFile);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenIncludeFile
+ *
+ * PARAMETERS: Op - Parse node for the INCLUDE ASL statement
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Open an include file and push it on the input file stack.
+ *
+ ******************************************************************************/
+
+void
+FlOpenIncludeFile (
+ ACPI_PARSE_OBJECT *Op)
+{
+ FILE *IncludeFile;
+ ASL_INCLUDE_DIR *NextDir;
+
+
+ /* Op must be valid */
+
+ if (!Op)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
+
+ return;
+ }
+
+ /*
+ * Flush out the "include ()" statement on this line, start
+ * the actual include file on the next line
+ */
+ AslResetCurrentLineBuffer ();
+ FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
+ Gbl_CurrentLineOffset++;
+
+
+ /* Attempt to open the include file */
+
+ /* If the file specifies an absolute path, just open it */
+
+ if ((Op->Asl.Value.String[0] == '/') ||
+ (Op->Asl.Value.String[0] == '\\') ||
+ (Op->Asl.Value.String[1] == ':'))
+ {
+ IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String);
+ if (!IncludeFile)
+ {
+ goto ErrorExit;
+ }
+ return;
+ }
+
+ /*
+ * The include filename is not an absolute path.
+ *
+ * First, search for the file within the "local" directory -- meaning
+ * the same directory that contains the source file.
+ *
+ * Construct the file pathname from the global directory name.
+ */
+ IncludeFile = FlOpenIncludeWithPrefix (Gbl_DirectoryPath, Op, Op->Asl.Value.String);
+ if (IncludeFile)
+ {
+ return;
+ }
+
+ /*
+ * Second, search for the file within the (possibly multiple) directories
+ * specified by the -I option on the command line.
+ */
+ NextDir = Gbl_IncludeDirList;
+ while (NextDir)
+ {
+ IncludeFile = FlOpenIncludeWithPrefix (NextDir->Dir, Op, Op->Asl.Value.String);
+ if (IncludeFile)
+ {
+ return;
+ }
+
+ NextDir = NextDir->Next;
+ }
+
+ /* We could not open the include file after trying very hard */
+
+ErrorExit:
+ sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno));
+ AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenInputFile
+ *
+ * PARAMETERS: InputFilename - The user-specified ASL source file to be
+ * compiled
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Open the specified input file, and save the directory path to
+ * the file so that include files can be opened in
+ * the same directory.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlOpenInputFile (
+ char *InputFilename)
+{
+
+ /* Open the input ASL file, text mode */
+
+ FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
+ AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenAmlOutputFile
+ *
+ * PARAMETERS: FilenamePrefix - The user-specified ASL source file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
+ * is created in the same directory as the parent input file.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlOpenAmlOutputFile (
+ char *FilenamePrefix)
+{
+ char *Filename;
+
+
+ /* Output filename usually comes from the ASL itself */
+
+ Filename = Gbl_Files[ASL_FILE_AML_OUTPUT].Filename;
+ if (!Filename)
+ {
+ /* Create the output AML filename */
+
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename;
+ }
+
+ /* Open the output AML file in binary mode */
+
+ FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenMiscOutputFiles
+ *
+ * PARAMETERS: FilenamePrefix - The user-specified ASL source file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create and open the various output files needed, depending on
+ * the command line options
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlOpenMiscOutputFiles (
+ char *FilenamePrefix)
+{
+ char *Filename;
+
+
+ /* Create/Open a map file if requested */
+
+ if (Gbl_MapfileFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the hex file, text mode (closed at compiler exit) */
+
+ FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_MAP_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT);
+ }
+
+ /* All done for disassembler */
+
+ if (Gbl_FileType == ASL_INPUT_TYPE_ACPI_TABLE)
+ {
+ return (AE_OK);
+ }
+
+ /* Create/Open a hex output file if asked */
+
+ if (Gbl_HexOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the hex file, text mode */
+
+ FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
+ }
+
+ /* Create/Open a debug output file if asked */
+
+ if (Gbl_DebugFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the debug file as STDERR, text mode */
+
+ Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
+ Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
+ freopen (Filename, "w+t", stderr);
+
+ if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
+ {
+ /*
+ * A problem with freopen is that on error, we no longer
+ * have stderr and cannot emit normal error messages.
+ * Emit error to stdout, close files, and exit.
+ */
+ fprintf (stdout,
+ "\nCould not open debug output file: %s\n\n", Filename);
+
+ CmCleanupAndExit ();
+ exit (1);
+ }
+
+ AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
+ }
+
+ /* Create/Open a listing output file if asked */
+
+ if (Gbl_ListingFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the listing file, text mode */
+
+ FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
+ }
+
+ /* Create the preprocessor output temp file if preprocessor enabled */
+
+ if (Gbl_PreprocessFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
+ }
+
+ /*
+ * Create the "user" preprocessor output file if -li flag set.
+ * Note, this file contains no embedded #line directives.
+ */
+ if (Gbl_PreprocessorOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
+ }
+
+ /* All done for data table compiler */
+
+ if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
+ {
+ return (AE_OK);
+ }
+
+ /* Create/Open a combined source output file */
+
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /*
+ * Open the source output file, binary mode (so that LF does not get
+ * expanded to CR/LF on some systems, messing up our seek
+ * calculations.)
+ */
+ FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
+
+/*
+// TBD: TEMP
+// AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
+*/
+ /* Create/Open a assembly code source output file if asked */
+
+ if (Gbl_AsmOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the assembly code source file, text mode */
+
+ FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
+ }
+
+ /* Create/Open a C code source output file if asked */
+
+ if (Gbl_C_OutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the C code source file, text mode */
+
+ FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
+
+ FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
+ AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
+ }
+
+ /* Create/Open a C code source output file for the offset table if asked */
+
+ if (Gbl_C_OffsetTableFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the C code source file, text mode */
+
+ FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t");
+
+ FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n");
+ AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT);
+ }
+
+ /* Create/Open a assembly include output file if asked */
+
+ if (Gbl_AsmIncludeOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the assembly include file, text mode */
+
+ FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
+ }
+
+ /* Create/Open a C include output file if asked */
+
+ if (Gbl_C_IncludeOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the C include file, text mode */
+
+ FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
+
+ FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
+ AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
+ }
+
+ /* Create a namespace output file if asked */
+
+ if (Gbl_NsOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ /* Open the namespace file, text mode */
+
+ FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
+
+ AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
+ AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
+ }
+
+ return (AE_OK);
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: FlParseInputPathname
+ *
+ * PARAMETERS: InputFilename - The user-specified ASL source file to be
+ * compiled
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Split the input path into a directory and filename part
+ * 1) Directory part used to open include files
+ * 2) Filename part used to generate output filenames
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+FlParseInputPathname (
+ char *InputFilename)
+{
+ char *Substring;
+
+
+ if (!InputFilename)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the path to the input filename's directory */
+
+ Gbl_DirectoryPath = strdup (InputFilename);
+ if (!Gbl_DirectoryPath)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Substring = strrchr (Gbl_DirectoryPath, '\\');
+ if (!Substring)
+ {
+ Substring = strrchr (Gbl_DirectoryPath, '/');
+ if (!Substring)
+ {
+ Substring = strrchr (Gbl_DirectoryPath, ':');
+ }
+ }
+
+ if (!Substring)
+ {
+ Gbl_DirectoryPath[0] = 0;
+ if (Gbl_UseDefaultAmlFilename)
+ {
+ Gbl_OutputFilenamePrefix = strdup (InputFilename);
+ }
+ }
+ else
+ {
+ if (Gbl_UseDefaultAmlFilename)
+ {
+ Gbl_OutputFilenamePrefix = strdup (Substring + 1);
+ }
+ *(Substring+1) = 0;
+ }
+
+ UtConvertBackslashes (Gbl_OutputFilenamePrefix);
+ return (AE_OK);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfold.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfold.c
new file mode 100644
index 0000000000..af7a019299
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslfold.c
@@ -0,0 +1,789 @@
+/******************************************************************************
+ *
+ * Module Name: aslfold - Constant folding
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslfold")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk1 (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk2 (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+OpcAmlCheckForConstant (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static void
+OpcUpdateIntegerNode (
+ ACPI_PARSE_OBJECT *Op,
+ UINT64 Value);
+
+static ACPI_STATUS
+TrTransformToStoreOp (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+TrSimpleConstantReduction (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+static void
+TrInstallReducedConstant (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlConstantWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reduce an Op and its subtree to a constant if possible
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+OpcAmlConstantWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_STATUS Status = AE_OK;
+
+
+ if (Op->Asl.CompileFlags == 0)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Only interested in subtrees that could possibly contain
+ * expressions that can be evaluated at this time
+ */
+ if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) ||
+ (Op->Asl.CompileFlags & NODE_IS_TARGET))
+ {
+ return (AE_OK);
+ }
+
+ /* Create a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ WalkState->NextOp = NULL;
+ WalkState->Params = NULL;
+
+ /*
+ * Examine the entire subtree -- all nodes must be constants
+ * or type 3/4/5 opcodes
+ */
+ Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD,
+ OpcAmlCheckForConstant, NULL, WalkState);
+
+ /*
+ * Did we find an entire subtree that contains all constants
+ * and type 3/4/5 opcodes?
+ */
+ switch (Status)
+ {
+ case AE_OK:
+
+ /* Simple case, like Add(3,4) -> 7 */
+
+ Status = TrSimpleConstantReduction (Op, WalkState);
+ break;
+
+ case AE_CTRL_RETURN_VALUE:
+
+ /* More complex case, like Add(3,4,Local0) -> Store(7,Local0) */
+
+ Status = TrTransformToStoreOp (Op, WalkState);
+ break;
+
+ case AE_TYPE:
+
+ AcpiDsDeleteWalkState (WalkState);
+ return (AE_OK);
+
+ default:
+ AcpiDsDeleteWalkState (WalkState);
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "Cannot resolve, %s\n",
+ AcpiFormatException (Status));
+
+ /* We could not resolve the subtree for some reason */
+
+ AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op,
+ (char *) AcpiFormatException (Status));
+
+ /* Set the subtree value to ZERO anyway. Eliminates further errors */
+
+ OpcUpdateIntegerNode (Op, 0);
+ }
+
+ /* Abort the walk of this subtree, we are done with it */
+
+ return (AE_CTRL_DEPTH);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlCheckForConstant
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlCheckForConstant (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = Context;
+ ACPI_STATUS Status = AE_OK;
+
+
+ WalkState->Op = Op;
+ WalkState->Opcode = Op->Common.AmlOpcode;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ",
+ Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName);
+
+ /*
+ * TBD: Ignore buffer constants for now. The problem is that these
+ * constants have been transformed into RAW_DATA at this point, from
+ * the parse tree transform process which currently happens before
+ * the constant folding process. We may need to defer this transform
+ * for buffer until after the constant folding.
+ */
+ if (WalkState->Opcode == AML_BUFFER_OP)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nBuffer+Buffer->Buffer constant reduction is not supported yet");
+ Status = AE_TYPE;
+ goto CleanupAndExit;
+ }
+
+ /*
+ * These opcodes do not appear in the OpcodeInfo table, but
+ * they represent constants, so abort the constant walk now.
+ */
+ if ((WalkState->Opcode == AML_RAW_DATA_BYTE) ||
+ (WalkState->Opcode == AML_RAW_DATA_WORD) ||
+ (WalkState->Opcode == AML_RAW_DATA_DWORD) ||
+ (WalkState->Opcode == AML_RAW_DATA_QWORD))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA");
+ Status = AE_TYPE;
+ goto CleanupAndExit;
+ }
+
+ /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */
+
+ if (!(WalkState->OpInfo->Flags & AML_CONSTANT))
+ {
+ /* Not 3/4/5 opcode, but maybe can convert to STORE */
+
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "**** Valid Target, transform to Store ****\n");
+ return (AE_CTRL_RETURN_VALUE);
+ }
+
+ /* Expression cannot be reduced */
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "**** Not a Type 3/4/5 opcode (%s) ****",
+ Op->Asl.ParseOpName);
+
+ Status = AE_TYPE;
+ goto CleanupAndExit;
+ }
+
+ /* Debug output */
+
+ DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345");
+
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ if (Op->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET");
+ }
+ else
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET");
+ }
+ }
+ if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG");
+ }
+
+CleanupAndExit:
+
+ /* Dump the node compile flags also */
+
+ TrPrintNodeCompileFlags (Op->Asl.CompileFlags);
+ DbgPrint (ASL_PARSE_OUTPUT, "\n");
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrSimpleConstantReduction
+ *
+ * PARAMETERS: Op - Parent operator to be transformed
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reduce an entire AML operation to a single constant. The
+ * operation must not have a target operand.
+ *
+ * Add (32,64) --> 96
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+TrSimpleConstantReduction (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *RootOp;
+ ACPI_PARSE_OBJECT *OriginalParentOp;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Simple subtree constant reduction, operator to constant\n");
+
+ /* Allocate a new temporary root for this subtree */
+
+ RootOp = TrAllocateNode (PARSEOP_INTEGER);
+ if (!RootOp)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
+
+ OriginalParentOp = Op->Common.Parent;
+ Op->Common.Parent = RootOp;
+
+ /* Hand off the subtree to the AML interpreter */
+
+ WalkState->CallerReturnDesc = &ObjDesc;
+
+ Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
+ OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
+
+ /* Restore original parse tree */
+
+ Op->Common.Parent = OriginalParentOp;
+
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant Subtree evaluation(1), %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /* Get the final result */
+
+ Status = AcpiDsResultPop (&ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant Subtree evaluation(2), %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /* Disconnect any existing children, install new constant */
+
+ Op->Asl.Child = NULL;
+ TrInstallReducedConstant (Op, ObjDesc);
+
+ UtSetParseOpName (Op);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrTransformToStoreOp
+ *
+ * PARAMETERS: Op - Parent operator to be transformed
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transforms a single AML operation with a constant and target
+ * to a simple store operation:
+ *
+ * Add (32,64,DATA) --> Store (96,DATA)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+TrTransformToStoreOp (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *OriginalTarget;
+ ACPI_PARSE_OBJECT *NewTarget;
+ ACPI_PARSE_OBJECT *Child1;
+ ACPI_PARSE_OBJECT *Child2;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PARSE_OBJECT *NewParent;
+ ACPI_PARSE_OBJECT *OriginalParent;
+ ACPI_STATUS Status;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Reduction/Transform to StoreOp: Store(Constant, Target)\n");
+
+ /* Extract the operands */
+
+ Child1 = Op->Asl.Child;
+ Child2 = Child1->Asl.Next;
+
+ /*
+ * Special case for DIVIDE -- it has two targets. The first
+ * is for the remainder and if present, we will not attempt
+ * to reduce the expression.
+ */
+ if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE)
+ {
+ Child2 = Child2->Asl.Next;
+ if (Child2->Asl.ParseOpcode != PARSEOP_ZERO)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Cannot reduce DIVIDE - has two targets\n\n");
+ return (AE_OK);
+ }
+ }
+
+ /*
+ * Create a NULL (zero) target so that we can use the
+ * interpreter to evaluate the expression.
+ */
+ NewTarget = TrCreateNullTarget ();
+ NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
+
+ /* Handle one-operand cases (NOT, TOBCD, etc.) */
+
+ if (!Child2->Asl.Next)
+ {
+ Child2 = Child1;
+ }
+
+ /* Link in new NULL target as the last operand */
+
+ OriginalTarget = Child2->Asl.Next;
+ Child2->Asl.Next = NewTarget;
+ NewTarget->Asl.Parent = OriginalTarget->Asl.Parent;
+
+ NewParent = TrAllocateNode (PARSEOP_INTEGER);
+ NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
+
+ OriginalParent = Op->Common.Parent;
+ Op->Common.Parent = NewParent;
+
+ /* Hand off the subtree to the AML interpreter */
+
+ WalkState->CallerReturnDesc = &ObjDesc;
+
+ Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
+ OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant Subtree evaluation(3), %s\n",
+ AcpiFormatException (Status));
+ goto EvalError;
+ }
+
+ /* Get the final result */
+
+ Status = AcpiDsResultPop (&ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant Subtree evaluation(4), %s\n",
+ AcpiFormatException (Status));
+ goto EvalError;
+ }
+
+ /* Truncate any subtree expressions, they have been evaluated */
+
+ Child1->Asl.Child = NULL;
+
+ /* Folded constant is in ObjDesc, store into Child1 */
+
+ TrInstallReducedConstant (Child1, ObjDesc);
+
+ /* Convert operator to STORE */
+
+ Op->Asl.ParseOpcode = PARSEOP_STORE;
+ Op->Asl.AmlOpcode = AML_STORE_OP;
+ UtSetParseOpName (Op);
+ Op->Common.Parent = OriginalParent;
+
+ /* First child is the folded constant */
+
+ /* Second child will be the target */
+
+ Child1->Asl.Next = OriginalTarget;
+ return (AE_OK);
+
+
+EvalError:
+
+ /* Restore original links */
+
+ Op->Common.Parent = OriginalParent;
+ Child2->Asl.Next = OriginalTarget;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrInstallReducedConstant
+ *
+ * PARAMETERS: Op - Parent operator to be transformed
+ * ObjDesc - Reduced constant to be installed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Transform the original operator to a simple constant.
+ * Handles Integers, Strings, and Buffers.
+ *
+ ******************************************************************************/
+
+static void
+TrInstallReducedConstant (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_PARSE_OBJECT *LengthOp;
+ ACPI_PARSE_OBJECT *DataOp;
+
+
+ TotalFolds++;
+ AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op,
+ Op->Asl.ParseOpName);
+
+ /*
+ * Because we know we executed type 3/4/5 opcodes above, we know that
+ * the result must be either an Integer, String, or Buffer.
+ */
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant expression reduced to (%s) %8.8X%8.8X\n\n",
+ Op->Asl.ParseOpName,
+ ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
+ Op->Common.AmlOpcode = AML_STRING_OP;
+ Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1;
+ Op->Common.Value.String = ObjDesc->String.Pointer;
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant expression reduced to (STRING) %s\n\n",
+ Op->Common.Value.String);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ /*
+ * Create a new parse subtree of the form:
+ *
+ * BUFFER (Buffer AML opcode)
+ * INTEGER (Buffer length in bytes)
+ * RAW_DATA (Buffer byte data)
+ */
+ Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+ Op->Common.AmlOpcode = AML_BUFFER_OP;
+ Op->Asl.CompileFlags = NODE_AML_PACKAGE;
+ UtSetParseOpName (Op);
+
+ /* Child node is the buffer length */
+
+ LengthOp = TrAllocateNode (PARSEOP_INTEGER);
+
+ LengthOp->Asl.AmlOpcode = AML_DWORD_OP;
+ LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
+ LengthOp->Asl.Parent = Op;
+ (void) OpcSetOptimalIntegerSize (LengthOp);
+
+ Op->Asl.Child = LengthOp;
+
+ /* Next child is the raw buffer data */
+
+ DataOp = TrAllocateNode (PARSEOP_RAW_DATA);
+ DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ DataOp->Asl.AmlLength = ObjDesc->Buffer.Length;
+ DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
+ DataOp->Asl.Parent = Op;
+
+ LengthOp->Asl.Next = DataOp;
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "Constant expression reduced to (BUFFER) length %X\n\n",
+ ObjDesc->Buffer.Length);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcUpdateIntegerNode
+ *
+ * PARAMETERS: Op - Current parse object
+ * Value - Value for the integer op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Update node to the correct Integer type and value
+ *
+ ******************************************************************************/
+
+static void
+OpcUpdateIntegerNode (
+ ACPI_PARSE_OBJECT *Op,
+ UINT64 Value)
+{
+
+ Op->Common.Value.Integer = Value;
+
+ /*
+ * The AmlLength is used by the parser to indicate a constant,
+ * (if non-zero). Length is either (1/2/4/8)
+ */
+ switch (Op->Asl.AmlLength)
+ {
+ case 1:
+
+ TrUpdateNode (PARSEOP_BYTECONST, Op);
+ Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ break;
+
+ case 2:
+
+ TrUpdateNode (PARSEOP_WORDCONST, Op);
+ Op->Asl.AmlOpcode = AML_RAW_DATA_WORD;
+ break;
+
+ case 4:
+
+ TrUpdateNode (PARSEOP_DWORDCONST, Op);
+ Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD;
+ break;
+
+ case 8:
+
+ TrUpdateNode (PARSEOP_QWORDCONST, Op);
+ Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD;
+ break;
+
+ case 0:
+ default:
+
+ OpcSetOptimalIntegerSize (Op);
+ TrUpdateNode (PARSEOP_INTEGER, Op);
+ break;
+ }
+
+ Op->Asl.AmlLength = 0;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlEvaluationWalk1
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback for AML execution of constant subtrees
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk1 (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = Context;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *OutOp;
+
+
+ WalkState->Op = Op;
+ WalkState->Opcode = Op->Common.AmlOpcode;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* Copy child pointer to Arg for compatibility with Interpreter */
+
+ if (Op->Asl.Child)
+ {
+ Op->Common.Value.Arg = Op->Asl.Child;
+ }
+
+ /* Call AML dispatcher */
+
+ Status = AcpiDsExecBeginOp (WalkState, &OutOp);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "%s Constant interpretation failed (1) - %s\n",
+ Op->Asl.ParseOpName, AcpiFormatException (Status));
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlEvaluationWalk2
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for AML execution of constant subtrees
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk2 (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = Context;
+ ACPI_STATUS Status;
+
+
+ WalkState->Op = Op;
+ WalkState->Opcode = Op->Common.AmlOpcode;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* Copy child pointer to Arg for compatibility with Interpreter */
+
+ if (Op->Asl.Child)
+ {
+ Op->Common.Value.Arg = Op->Asl.Child;
+ }
+
+ /* Call AML dispatcher */
+
+ Status = AcpiDsExecEndOp (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "%s: Constant interpretation failed (2) - %s\n",
+ Op->Asl.ParseOpName, AcpiFormatException (Status));
+ }
+
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslglobal.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslglobal.h
new file mode 100644
index 0000000000..0696b67519
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslglobal.h
@@ -0,0 +1,283 @@
+/******************************************************************************
+ *
+ * Module Name: aslglobal.h - Global variable definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ASLGLOBAL_H
+#define __ASLGLOBAL_H
+
+
+/*
+ * Global variables. Defined in aslmain.c only, externed in all other files
+ */
+
+#undef ASL_EXTERN
+
+#ifdef _DECLARE_GLOBALS
+#define ASL_EXTERN
+#define ASL_INIT_GLOBAL(a,b) (a)=(b)
+#else
+#define ASL_EXTERN extern
+#define ASL_INIT_GLOBAL(a,b) (a)
+#endif
+
+
+#ifdef _DECLARE_GLOBALS
+UINT32 Gbl_ExceptionCount[ASL_NUM_REPORT_LEVELS] = {0,0,0,0,0,0};
+
+/* Table below must match ASL_FILE_TYPES in asltypes.h */
+
+ASL_FILE_INFO Gbl_Files [ASL_NUM_FILES] =
+{
+ {NULL, NULL, "stdout: ", "Standard Output"},
+ {NULL, NULL, "stderr: ", "Standard Error"},
+ {NULL, NULL, "Table Input: ", "Source Input"},
+ {NULL, NULL, "Binary Output:", "AML Output"},
+ {NULL, NULL, "Source Output:", "Source Output"},
+ {NULL, NULL, "Preprocessor: ", "Preprocessor Output"},
+ {NULL, NULL, "Preprocessor: ", "Preprocessor Temp File"},
+ {NULL, NULL, "Listing File: ", "Listing Output"},
+ {NULL, NULL, "Hex Dump: ", "Hex Table Output"},
+ {NULL, NULL, "Namespace: ", "Namespace Output"},
+ {NULL, NULL, "Debug File: ", "Debug Output"},
+ {NULL, NULL, "ASM Source: ", "Assembly Code Output"},
+ {NULL, NULL, "C Source: ", "C Code Output"},
+ {NULL, NULL, "ASM Include: ", "Assembly Header Output"},
+ {NULL, NULL, "C Include: ", "C Header Output"},
+ {NULL, NULL, "Offset Table: ", "C Offset Table Output"},
+ {NULL, NULL, "Device Map: ", "Device Map Output"}
+};
+
+#else
+extern UINT32 Gbl_ExceptionCount[ASL_NUM_REPORT_LEVELS];
+extern ASL_FILE_INFO Gbl_Files [ASL_NUM_FILES];
+#endif
+
+
+/*
+ * Parser and other externals
+ */
+extern int yydebug;
+extern FILE *AslCompilerin;
+extern int DtParserdebug;
+extern int PrParserdebug;
+extern const ASL_MAPPING_ENTRY AslKeywordMapping[];
+extern char *AslCompilertext;
+
+/*
+ * Older versions of Bison won't emit this external in the generated header.
+ * Newer versions do emit the external, so we don't need to do it.
+ */
+#ifndef ASLCOMPILER_ASLCOMPILERPARSE_H
+extern int AslCompilerdebug;
+#endif
+
+
+#define ASL_DEFAULT_LINE_BUFFER_SIZE (1024 * 32) /* 32K */
+#define ASL_MSG_BUFFER_SIZE 4096
+#define ASL_MAX_DISABLED_MESSAGES 32
+#define HEX_TABLE_LINE_SIZE 8
+#define HEX_LISTING_LINE_SIZE 8
+
+
+/* Source code buffers and pointers for error reporting */
+
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_CurrentLineBuffer, NULL);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_LineBufPtr, NULL);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LineBufferSize, ASL_DEFAULT_LINE_BUFFER_SIZE);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentColumn, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineNumber, 1);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LogicalLineNumber, 1);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineOffset, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_OriginalInputFileSize, 0);
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_SyntaxError, 0);
+
+/* Exception reporting */
+
+ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_ErrorLog,NULL);
+ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_NextError,NULL);
+
+/* Option flags */
+
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoCompile, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoSignon, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessOnly, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessFlag, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisassembleAll, FALSE);
+
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_UseDefaultAmlFilename, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_MapfileFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NsOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessorOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_KeepPreprocessorTempFile, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DebugFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_AsmOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_C_OutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_C_OffsetTableFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_AsmIncludeOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_C_IncludeOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_ListingFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_IgnoreErrors, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_SourceOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_ParseOnlyFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_CompileTimesFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_FoldConstants, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_VerboseErrors, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NoErrors, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_WarningsAsErrors, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NoResourceChecking, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisasmFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_IntegerOptimizationFlag, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_ReferenceOptimizationFlag, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisplayRemarks, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisplayWarnings, TRUE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisplayOptimizations, FALSE);
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_WarningLevel, ASL_WARNING);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_UseOriginalCompilerId, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_VerboseTemplates, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoTemplates, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_CompileGeneric, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_AllExceptionsDisabled, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PruneParseTree, FALSE);
+
+
+#define HEX_OUTPUT_NONE 0
+#define HEX_OUTPUT_C 1
+#define HEX_OUTPUT_ASM 2
+#define HEX_OUTPUT_ASL 3
+
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HexOutputFlag, HEX_OUTPUT_NONE);
+
+
+/* Files */
+
+ASL_EXTERN char *Gbl_DirectoryPath;
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_IncludeFilename, NULL);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_OutputFilenamePrefix, NULL);
+ASL_EXTERN ASL_INCLUDE_DIR ASL_INIT_GLOBAL (*Gbl_IncludeDirList, NULL);
+ASL_EXTERN char *Gbl_CurrentInputFilename;
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_ExternalRefFilename, NULL);
+
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HasIncludeFiles, FALSE);
+
+
+/* Statistics */
+
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_InputByteCount, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_InputFieldCount, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_NsLookupCount, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalKeywords, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalNamedObjects, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalExecutableOpcodes, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalParseNodes, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalMethods, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalAllocations, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalAllocated, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalFolds, 0);
+
+
+/* Local caches */
+
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_ParseOpCount, 0);
+ASL_EXTERN ASL_CACHE_INFO ASL_INIT_GLOBAL (*Gbl_ParseOpCacheList, NULL);
+ASL_EXTERN ACPI_PARSE_OBJECT ASL_INIT_GLOBAL (*Gbl_ParseOpCacheNext, NULL);
+ASL_EXTERN ACPI_PARSE_OBJECT ASL_INIT_GLOBAL (*Gbl_ParseOpCacheLast, NULL);
+
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_StringCount, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_StringSize, 0);
+ASL_EXTERN ASL_CACHE_INFO ASL_INIT_GLOBAL (*Gbl_StringCacheList, NULL);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_StringCacheNext, NULL);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_StringCacheLast, NULL);
+
+/* Map file */
+
+ASL_EXTERN ACPI_GPIO_INFO ASL_INIT_GLOBAL (*Gbl_GpioList, NULL);
+ASL_EXTERN ACPI_SERIAL_INFO ASL_INIT_GLOBAL (*Gbl_SerialList, NULL);
+
+
+/* Misc */
+
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_RevisionOverride, 0);
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_TempCount, 0);
+ASL_EXTERN ACPI_PARSE_OBJECT ASL_INIT_GLOBAL (*RootNode, NULL);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_TableLength, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_SourceLine, 0);
+ASL_EXTERN ASL_LISTING_NODE ASL_INIT_GLOBAL (*Gbl_ListingNode, NULL);
+ASL_EXTERN ACPI_PARSE_OBJECT *Gbl_FirstLevelInsertionNode;
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_FileType, 0);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_Signature, NULL);
+ASL_EXTERN char *Gbl_TemplateSignature;
+
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentHexColumn, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentAmlOffset, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLine, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_DisabledMessagesIndex, 0);
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_HexBytesWereWritten, FALSE);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_NumNamespaceObjects, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_ReservedMethods, 0);
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_TableSignature, "NO_SIG");
+ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_TableId, "NO_ID");
+ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_PruneDepth, 0);
+ASL_EXTERN UINT16 ASL_INIT_GLOBAL (Gbl_PruneType, 0);
+
+
+/* Static structures */
+
+ASL_EXTERN ASL_ANALYSIS_WALK_INFO AnalysisWalkInfo;
+ASL_EXTERN ACPI_TABLE_HEADER TableHeader;
+
+/* Event timing */
+
+#define ASL_NUM_EVENTS 20
+ASL_EXTERN ASL_EVENT_INFO AslGbl_Events[ASL_NUM_EVENTS];
+ASL_EXTERN UINT8 AslGbl_NextEvent;
+ASL_EXTERN UINT8 AslGbl_NamespaceEvent;
+
+/* Scratch buffers */
+
+ASL_EXTERN UINT8 Gbl_AmlBuffer[HEX_LISTING_LINE_SIZE];
+ASL_EXTERN char MsgBuffer[ASL_MSG_BUFFER_SIZE];
+ASL_EXTERN char StringBuffer[ASL_MSG_BUFFER_SIZE];
+ASL_EXTERN char StringBuffer2[ASL_MSG_BUFFER_SIZE];
+ASL_EXTERN UINT32 Gbl_DisabledMessages[ASL_MAX_DISABLED_MESSAGES];
+
+
+#endif /* __ASLGLOBAL_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslhex.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslhex.c
new file mode 100644
index 0000000000..f24de1cd54
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslhex.c
@@ -0,0 +1,402 @@
+/******************************************************************************
+ *
+ * Module Name: aslhex - ASCII hex output file generation (C, ASM, and ASL)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("ashex")
+
+/*
+ * This module emits ASCII hex output files in either C, ASM, or ASL format
+ */
+
+
+/* Local prototypes */
+
+static void
+HxDoHexOutputC (
+ void);
+
+static void
+HxDoHexOutputAsl (
+ void);
+
+static void
+HxDoHexOutputAsm (
+ void);
+
+static UINT32
+HxReadAmlOutputFile (
+ UINT8 *Buffer);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: HxDoHexOutput
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the hex output file. Note: data is obtained by reading
+ * the entire AML output file that was previously generated.
+ *
+ ******************************************************************************/
+
+void
+HxDoHexOutput (
+ void)
+{
+
+ switch (Gbl_HexOutputFlag)
+ {
+ case HEX_OUTPUT_C:
+
+ HxDoHexOutputC ();
+ break;
+
+ case HEX_OUTPUT_ASM:
+
+ HxDoHexOutputAsm ();
+ break;
+
+ case HEX_OUTPUT_ASL:
+
+ HxDoHexOutputAsl ();
+ break;
+
+ default:
+
+ /* No other output types supported */
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: HxReadAmlOutputFile
+ *
+ * PARAMETERS: Buffer - Where to return data
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Read a line of the AML output prior to formatting the data
+ *
+ ******************************************************************************/
+
+static UINT32
+HxReadAmlOutputFile (
+ UINT8 *Buffer)
+{
+ UINT32 Actual;
+
+
+ Actual = fread (Buffer, 1, HEX_TABLE_LINE_SIZE,
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
+
+ if (ferror (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle))
+ {
+ FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
+ AslAbort ();
+ }
+
+ return (Actual);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: HxDoHexOutputC
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the hex output file. This is the same data as the AML
+ * output file, but formatted into hex/ascii bytes suitable for
+ * inclusion into a C source file.
+ *
+ ******************************************************************************/
+
+static void
+HxDoHexOutputC (
+ void)
+{
+ UINT8 FileData[HEX_TABLE_LINE_SIZE];
+ UINT32 LineLength;
+ UINT32 Offset = 0;
+ UINT32 AmlFileSize;
+ UINT32 i;
+
+
+ /* Get AML size, seek back to start */
+
+ AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
+ AmlFileSize);
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n");
+
+ while (Offset < AmlFileSize)
+ {
+ /* Read enough bytes needed for one output line */
+
+ LineLength = HxReadAmlOutputFile (FileData);
+ if (!LineLength)
+ {
+ break;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
+
+ for (i = 0; i < LineLength; i++)
+ {
+ /*
+ * Print each hex byte.
+ * Add a comma until the very last byte of the AML file
+ * (Some C compilers complain about a trailing comma)
+ */
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
+ if ((Offset + i + 1) < AmlFileSize)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
+ }
+ else
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
+ }
+ }
+
+ /* Add fill spaces if needed for last line */
+
+ if (LineLength < HEX_TABLE_LINE_SIZE)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
+ 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
+ }
+
+ /* Emit the offset and ascii dump for the entire line */
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
+ LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
+ HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
+
+ Offset += LineLength;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: HxDoHexOutputAsl
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the hex output file. This is the same data as the AML
+ * output file, but formatted into hex/ascii bytes suitable for
+ * inclusion into a C source file.
+ *
+ ******************************************************************************/
+
+static void
+HxDoHexOutputAsl (
+ void)
+{
+ UINT8 FileData[HEX_TABLE_LINE_SIZE];
+ UINT32 LineLength;
+ UINT32 Offset = 0;
+ UINT32 AmlFileSize;
+ UINT32 i;
+
+
+ /* Get AML size, seek back to start */
+
+ AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " * ASL source code output\n");
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
+ AmlFileSize);
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " Name (BUF1, Buffer()\n {\n");
+
+ while (Offset < AmlFileSize)
+ {
+ /* Read enough bytes needed for one output line */
+
+ LineLength = HxReadAmlOutputFile (FileData);
+ if (!LineLength)
+ {
+ break;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
+
+ for (i = 0; i < LineLength; i++)
+ {
+ /*
+ * Print each hex byte.
+ * Add a comma until the very last byte of the AML file
+ * (Some C compilers complain about a trailing comma)
+ */
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]);
+ if ((Offset + i + 1) < AmlFileSize)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
+ }
+ else
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
+ }
+ }
+
+ /* Add fill spaces if needed for last line */
+
+ if (LineLength < HEX_TABLE_LINE_SIZE)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
+ 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
+ }
+
+ /* Emit the offset and ascii dump for the entire line */
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset);
+ LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n",
+ HEX_TABLE_LINE_SIZE - LineLength + 1, " ");
+
+ Offset += LineLength;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " })\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: HxDoHexOutputAsm
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the hex output file. This is the same data as the AML
+ * output file, but formatted into hex/ascii bytes suitable for
+ * inclusion into a ASM source file.
+ *
+ ******************************************************************************/
+
+static void
+HxDoHexOutputAsm (
+ void)
+{
+ UINT8 FileData[HEX_TABLE_LINE_SIZE];
+ UINT32 LineLength;
+ UINT32 Offset = 0;
+ UINT32 AmlFileSize;
+ UINT32 i;
+
+
+ /* Get AML size, seek back to start */
+
+ AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
+ AmlFileSize);
+
+ while (Offset < AmlFileSize)
+ {
+ /* Read enough bytes needed for one output line */
+
+ LineLength = HxReadAmlOutputFile (FileData);
+ if (!LineLength)
+ {
+ break;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " db ");
+
+ for (i = 0; i < LineLength; i++)
+ {
+ /*
+ * Print each hex byte.
+ * Add a comma until the last byte of the line
+ */
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "0%2.2Xh", FileData[i]);
+ if ((i + 1) < LineLength)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
+ }
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ");
+
+ /* Add fill spaces if needed for last line */
+
+ if (LineLength < HEX_TABLE_LINE_SIZE)
+ {
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s",
+ 5 * (HEX_TABLE_LINE_SIZE - LineLength), " ");
+ }
+
+ /* Emit the offset and ascii dump for the entire line */
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, " ; %8.8X", Offset);
+ LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData);
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
+
+ Offset += LineLength;
+ }
+
+ FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asllength.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllength.c
new file mode 100644
index 0000000000..618b63f4c2
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllength.c
@@ -0,0 +1,456 @@
+/******************************************************************************
+ *
+ * Module Name: asllength - Tree walk to determine package and opcode lengths
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asllength")
+
+/* Local prototypes */
+
+static UINT8
+CgGetPackageLenByteCount (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 PackageLength);
+
+static void
+CgGenerateAmlOpcodeLength (
+ ACPI_PARSE_OBJECT *Op);
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+LnAdjustLengthToRoot (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 LengthDelta);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LnInitLengthsWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk callback to initialize (and re-initialize) the node
+ * subtree length(s) to zero. The Subtree lengths are bubbled
+ * up to the root node in order to get a total AML length.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LnInitLengthsWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ Op->Asl.AmlSubtreeLength = 0;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LnPackageLengthWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk callback to calculate the total AML length.
+ * 1) Calculate the AML lengths (opcode, package length, etc.) for
+ * THIS node.
+ * 2) Bubbble up all of these lengths to the parent node by summing
+ * them all into the parent subtree length.
+ *
+ * Note: The SubtreeLength represents the total AML length of all child nodes
+ * in all subtrees under a given node. Therefore, once this walk is
+ * complete, the Root Node subtree length is the AML length of the entire
+ * tree (and thus, the entire ACPI table)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LnPackageLengthWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ /* Generate the AML lengths for this node */
+
+ CgGenerateAmlLengths (Op);
+
+ /* Bubble up all lengths (this node and all below it) to the parent */
+
+ if ((Op->Asl.Parent) &&
+ (Op->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+ {
+ Op->Asl.Parent->Asl.AmlSubtreeLength += (Op->Asl.AmlLength +
+ Op->Asl.AmlOpcodeLength +
+ Op->Asl.AmlPkgLenBytes +
+ Op->Asl.AmlSubtreeLength);
+ }
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgGetPackageLenByteCount
+ *
+ * PARAMETERS: Op - Parse node
+ * PackageLength - Length to be encoded
+ *
+ * RETURN: Required length of the package length encoding
+ *
+ * DESCRIPTION: Calculate the number of bytes required to encode the given
+ * package length.
+ *
+ ******************************************************************************/
+
+static UINT8
+CgGetPackageLenByteCount (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 PackageLength)
+{
+
+ /*
+ * Determine the number of bytes required to encode the package length
+ * Note: the package length includes the number of bytes used to encode
+ * the package length, so we must account for this also.
+ */
+ if (PackageLength <= (0x0000003F - 1))
+ {
+ return (1);
+ }
+ else if (PackageLength <= (0x00000FFF - 2))
+ {
+ return (2);
+ }
+ else if (PackageLength <= (0x000FFFFF - 3))
+ {
+ return (3);
+ }
+ else if (PackageLength <= (0x0FFFFFFF - 4))
+ {
+ return (4);
+ }
+ else
+ {
+ /* Fatal error - the package length is too large to encode */
+
+ AslError (ASL_ERROR, ASL_MSG_ENCODING_LENGTH, Op, NULL);
+ }
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgGenerateAmlOpcodeLength
+ *
+ * PARAMETERS: Op - Parse node whose AML opcode lengths will be
+ * calculated
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Calculate the AmlOpcodeLength, AmlPkgLenBytes, and AmlLength
+ * fields for this node.
+ *
+ ******************************************************************************/
+
+static void
+CgGenerateAmlOpcodeLength (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* Check for two-byte opcode */
+
+ if (Op->Asl.AmlOpcode > 0x00FF)
+ {
+ Op->Asl.AmlOpcodeLength = 2;
+ }
+ else
+ {
+ Op->Asl.AmlOpcodeLength = 1;
+ }
+
+ /* Does this opcode have an associated "PackageLength" field? */
+
+ Op->Asl.AmlPkgLenBytes = 0;
+ if (Op->Asl.CompileFlags & NODE_AML_PACKAGE)
+ {
+ Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount (
+ Op, Op->Asl.AmlSubtreeLength);
+ }
+
+ /* Data opcode lengths are easy */
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_BYTE_OP:
+
+ Op->Asl.AmlLength = 1;
+ break;
+
+ case AML_WORD_OP:
+
+ Op->Asl.AmlLength = 2;
+ break;
+
+ case AML_DWORD_OP:
+
+ Op->Asl.AmlLength = 4;
+ break;
+
+ case AML_QWORD_OP:
+
+ Op->Asl.AmlLength = 8;
+ break;
+
+ default:
+
+ /* All data opcodes must be above */
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: CgGenerateAmlLengths
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Generate internal length fields based on the AML opcode or
+ * parse opcode.
+ *
+ ******************************************************************************/
+
+void
+CgGenerateAmlLengths (
+ ACPI_PARSE_OBJECT *Op)
+{
+ char *Buffer;
+ ACPI_STATUS Status;
+
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_RAW_DATA_BYTE:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlLength = 1;
+ return;
+
+ case AML_RAW_DATA_WORD:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlLength = 2;
+ return;
+
+ case AML_RAW_DATA_DWORD:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlLength = 4;
+ return;
+
+ case AML_RAW_DATA_QWORD:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlLength = 8;
+ return;
+
+ case AML_RAW_DATA_BUFFER:
+
+ /* Aml length is/was set by creator */
+
+ Op->Asl.AmlOpcodeLength = 0;
+ return;
+
+ case AML_RAW_DATA_CHAIN:
+
+ /* Aml length is/was set by creator */
+
+ Op->Asl.AmlOpcodeLength = 0;
+ return;
+
+ default:
+
+ break;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ Gbl_TableLength = sizeof (ACPI_TABLE_HEADER) +
+ Op->Asl.AmlSubtreeLength;
+ break;
+
+ case PARSEOP_NAMESEG:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlLength = 4;
+ Op->Asl.ExternalName = Op->Asl.Value.String;
+ break;
+
+ case PARSEOP_NAMESTRING:
+ case PARSEOP_METHODCALL:
+
+ if (Op->Asl.CompileFlags & NODE_NAME_INTERNALIZED)
+ {
+ break;
+ }
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Status = UtInternalizeName (Op->Asl.Value.String, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Failure from internalize name %X\n", Status);
+ break;
+ }
+
+ Op->Asl.ExternalName = Op->Asl.Value.String;
+ Op->Asl.Value.String = Buffer;
+ Op->Asl.CompileFlags |= NODE_NAME_INTERNALIZED;
+
+ Op->Asl.AmlLength = strlen (Buffer);
+
+ /*
+ * Check for single backslash reference to root,
+ * make it a null terminated string in the AML
+ */
+ if (Op->Asl.AmlLength == 1)
+ {
+ Op->Asl.AmlLength = 2;
+ }
+ break;
+
+ case PARSEOP_STRING_LITERAL:
+
+ Op->Asl.AmlOpcodeLength = 1;
+
+ /* Get null terminator */
+
+ Op->Asl.AmlLength = strlen (Op->Asl.Value.String) + 1;
+ break;
+
+ case PARSEOP_PACKAGE_LENGTH:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount (Op,
+ (UINT32) Op->Asl.Value.Integer);
+ break;
+
+ case PARSEOP_RAW_DATA:
+
+ Op->Asl.AmlOpcodeLength = 0;
+ break;
+
+ case PARSEOP_DEFAULT_ARG:
+ case PARSEOP_EXTERNAL:
+ case PARSEOP_INCLUDE:
+ case PARSEOP_INCLUDE_END:
+
+ /* Ignore the "default arg" nodes, they are extraneous at this point */
+
+ break;
+
+ default:
+
+ CgGenerateAmlOpcodeLength (Op);
+ break;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: LnAdjustLengthToRoot
+ *
+ * PARAMETERS: Op - Node whose Length was changed
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Change the Subtree length of the given node, and bubble the
+ * change all the way up to the root node. This allows for
+ * last second changes to a package length (for example, if the
+ * package length encoding gets shorter or longer.)
+ *
+ ******************************************************************************/
+
+void
+LnAdjustLengthToRoot (
+ ACPI_PARSE_OBJECT *SubtreeOp,
+ UINT32 LengthDelta)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ /* Adjust all subtree lengths up to the root */
+
+ Op = SubtreeOp->Asl.Parent;
+ while (Op)
+ {
+ Op->Asl.AmlSubtreeLength -= LengthDelta;
+ Op = Op->Asl.Parent;
+ }
+
+ /* Adjust the global table length */
+
+ Gbl_TableLength -= LengthDelta;
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asllisting.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllisting.c
new file mode 100644
index 0000000000..a8fe2de771
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllisting.c
@@ -0,0 +1,657 @@
+/******************************************************************************
+ *
+ * Module Name: asllisting - Listing file generation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asllisting")
+
+
+/* Local prototypes */
+
+static void
+LsGenerateListing (
+ UINT32 FileId);
+
+static ACPI_STATUS
+LsAmlListingWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+LsTreeWriteWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static void
+LsWriteNodeToListing (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 FileId);
+
+static void
+LsFinishSourceListing (
+ UINT32 FileId);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsDoListings
+ *
+ * PARAMETERS: None. Examines the various output file global flags.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generate all requested listing files.
+ *
+ ******************************************************************************/
+
+void
+LsDoListings (
+ void)
+{
+
+ if (Gbl_C_OutputFlag)
+ {
+ LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT);
+ }
+
+ if (Gbl_ListingFlag)
+ {
+ LsGenerateListing (ASL_FILE_LISTING_OUTPUT);
+ }
+
+ if (Gbl_AsmOutputFlag)
+ {
+ LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT);
+ }
+
+ if (Gbl_C_IncludeOutputFlag)
+ {
+ LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT);
+ }
+
+ if (Gbl_AsmIncludeOutputFlag)
+ {
+ LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT);
+ }
+
+ if (Gbl_C_OffsetTableFlag)
+ {
+ LsGenerateListing (ASL_FILE_C_OFFSET_OUTPUT);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsGenerateListing
+ *
+ * PARAMETERS: FileId - ID of listing file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generate a listing file. This can be one of the several types
+ * of "listings" supported.
+ *
+ ******************************************************************************/
+
+static void
+LsGenerateListing (
+ UINT32 FileId)
+{
+
+ /* Start at the beginning of both the source and AML files */
+
+ FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+ Gbl_SourceLine = 0;
+ Gbl_CurrentHexColumn = 0;
+ LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename);
+
+ if (FileId == ASL_FILE_C_OFFSET_OUTPUT)
+ {
+ Gbl_CurrentAmlOffset = 0;
+
+ /* Offset table file has a special header and footer */
+
+ LsDoOffsetTableHeader (FileId);
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlOffsetWalk,
+ NULL, (void *) ACPI_TO_POINTER (FileId));
+ LsDoOffsetTableFooter (FileId);
+ return;
+ }
+
+ /* Process all parse nodes */
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk,
+ NULL, (void *) ACPI_TO_POINTER (FileId));
+
+ /* Final processing */
+
+ LsFinishSourceListing (FileId);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsAmlListingWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Process one node during a listing file generation.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LsAmlListingWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ UINT8 FileByte;
+ UINT32 i;
+ UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context);
+
+
+ LsWriteNodeToListing (Op, FileId);
+
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA)
+ {
+ /* Buffer is a resource template, don't dump the data all at once */
+
+ return (AE_OK);
+ }
+
+ /* Write the hex bytes to the listing file(s) (if requested) */
+
+ for (i = 0; i < Op->Asl.FinalAmlLength; i++)
+ {
+ if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1)))
+ {
+ FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ);
+ AslAbort ();
+ }
+ LsWriteListingHexBytes (&FileByte, 1, FileId);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsDumpParseTree, LsTreeWriteWalk
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump entire parse tree, for compiler debug only
+ *
+ ******************************************************************************/
+
+void
+LsDumpParseTree (
+ void)
+{
+
+ if (!Gbl_DebugFlag)
+ {
+ return;
+ }
+
+ DbgPrint (ASL_TREE_OUTPUT, "\nOriginal parse tree from parser:\n\n");
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ LsTreeWriteWalk, NULL, NULL);
+}
+
+
+static ACPI_STATUS
+LsTreeWriteWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ /* Debug output */
+
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
+
+ UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
+
+ DbgPrint (ASL_TREE_OUTPUT, " (%.4X) Flags %8.8X",
+ Op->Asl.ParseOpcode, Op->Asl.CompileFlags);
+ TrPrintNodeCompileFlags (Op->Asl.CompileFlags);
+ DbgPrint (ASL_TREE_OUTPUT, "\n");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsWriteNodeToListing
+ *
+ * PARAMETERS: Op - Parse node to write to the listing file.
+ * FileId - ID of current listing file
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Write "a node" to the listing file. This means to
+ * 1) Write out all of the source text associated with the node
+ * 2) Write out all of the AML bytes associated with the node
+ * 3) Write any compiler exceptions associated with the node
+ *
+ ******************************************************************************/
+
+static void
+LsWriteNodeToListing (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 FileId)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 OpClass;
+ char *Pathname;
+ UINT32 Length;
+ UINT32 i;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ OpClass = OpInfo->Class;
+
+ /* TBD: clean this up with a single flag that says:
+ * I start a named output block
+ */
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+ case PARSEOP_METHODCALL:
+ case PARSEOP_INCLUDE:
+ case PARSEOP_INCLUDE_END:
+ case PARSEOP_DEFAULT_ARG:
+
+ break;
+
+ default:
+
+ switch (OpClass)
+ {
+ case AML_CLASS_NAMED_OBJECT:
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_SCOPE_OP:
+ case AML_ALIAS_OP:
+
+ break;
+
+ default:
+
+ if (Op->Asl.ExternalName)
+ {
+ LsFlushListingBuffer (FileId);
+ FlPrintFile (FileId, " };\n");
+ }
+ break;
+ }
+ break;
+
+ default:
+
+ /* Don't care about other objects */
+
+ break;
+ }
+ break;
+ }
+ }
+
+ /* These cases do not have a corresponding AML opcode */
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId);
+
+ /* Use the table Signature and TableId to build a unique name */
+
+ if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "%s_%s_Header \\\n",
+ Gbl_TableSignature, Gbl_TableId);
+ }
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ " unsigned char %s_%s_Header [] =\n {\n",
+ Gbl_TableSignature, Gbl_TableId);
+ }
+ if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "extrn %s_%s_Header : byte\n",
+ Gbl_TableSignature, Gbl_TableId);
+ }
+ if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "extern unsigned char %s_%s_Header [];\n",
+ Gbl_TableSignature, Gbl_TableId);
+ }
+ return;
+
+
+ case PARSEOP_METHODCALL:
+
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+ return;
+
+
+ case PARSEOP_INCLUDE:
+
+ /* Flush everything up to and including the include source line */
+
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+
+ /* Create a new listing node and push it */
+
+ LsPushNode (Op->Asl.Child->Asl.Value.String);
+ return;
+
+
+ case PARSEOP_INCLUDE_END:
+
+ /* Flush out the rest of the include file */
+
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+
+ /* Pop off this listing node and go back to the parent file */
+
+ (void) LsPopNode ();
+ return;
+
+
+ case PARSEOP_DEFAULT_ARG:
+
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
+ {
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine,
+ FileId);
+ }
+ return;
+
+
+ default:
+
+ /* All other opcodes have an AML opcode */
+
+ break;
+ }
+
+ /*
+ * Otherwise, we look at the AML opcode because we can
+ * switch on the opcode type, getting an entire class
+ * at once
+ */
+ switch (OpClass)
+ {
+ case AML_CLASS_ARGUMENT: /* argument type only */
+ case AML_CLASS_INTERNAL:
+
+ break;
+
+ case AML_CLASS_NAMED_OBJECT:
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+ /*
+ * For fields, we want to dump all the AML after the
+ * entire definition
+ */
+ LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
+ FileId);
+ break;
+
+ case AML_NAME_OP:
+
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
+ {
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+ }
+ else
+ {
+ /*
+ * For fields, we want to dump all the AML after the
+ * entire definition
+ */
+ LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine,
+ FileId);
+ }
+ break;
+
+ default:
+
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+ break;
+ }
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_SCOPE_OP:
+ case AML_ALIAS_OP:
+
+ /* These opcodes do not declare a new object, ignore them */
+
+ break;
+
+ default:
+
+ /* All other named object opcodes come here */
+
+ switch (FileId)
+ {
+ case ASL_FILE_ASM_SOURCE_OUTPUT:
+ case ASL_FILE_C_SOURCE_OUTPUT:
+ case ASL_FILE_ASM_INCLUDE_OUTPUT:
+ case ASL_FILE_C_INCLUDE_OUTPUT:
+ /*
+ * For named objects, we will create a valid symbol so that the
+ * AML code can be referenced from C or ASM
+ */
+ if (Op->Asl.ExternalName)
+ {
+ /* Get the full pathname associated with this node */
+
+ Pathname = AcpiNsGetExternalPathname (Op->Asl.Node);
+ Length = strlen (Pathname);
+ if (Length >= 4)
+ {
+ /* Convert all dots in the path to underscores */
+
+ for (i = 0; i < Length; i++)
+ {
+ if (Pathname[i] == '.')
+ {
+ Pathname[i] = '_';
+ }
+ }
+
+ /* Create the appropriate symbol in the output file */
+
+ if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "%s_%s_%s \\\n",
+ Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
+ }
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ " unsigned char %s_%s_%s [] =\n {\n",
+ Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
+ }
+ if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "extrn %s_%s_%s : byte\n",
+ Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
+ }
+ if (FileId == ASL_FILE_C_INCLUDE_OUTPUT)
+ {
+ FlPrintFile (FileId,
+ "extern unsigned char %s_%s_%s [];\n",
+ Gbl_TableSignature, Gbl_TableId, &Pathname[1]);
+ }
+ }
+ ACPI_FREE (Pathname);
+ }
+ break;
+
+ default:
+
+ /* Nothing to do for listing file */
+
+ break;
+ }
+ }
+ break;
+
+ case AML_CLASS_EXECUTE:
+ case AML_CLASS_CREATE:
+ default:
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) &&
+ (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC))
+ {
+ return;
+ }
+
+ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber,
+ FileId);
+ break;
+
+ case AML_CLASS_UNKNOWN:
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsFinishSourceListing
+ *
+ * PARAMETERS: FileId - ID of current listing file.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML
+ * listing buffer, and flush out any remaining lines in the
+ * source input file.
+ *
+ ******************************************************************************/
+
+static void
+LsFinishSourceListing (
+ UINT32 FileId)
+{
+
+ if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
+ (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
+ {
+ return;
+ }
+
+ LsFlushListingBuffer (FileId);
+ Gbl_CurrentAmlOffset = 0;
+
+ /* Flush any remaining text in the source file */
+
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, " /*\n");
+ }
+
+ while (LsWriteOneSourceLine (FileId))
+ { ; }
+
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, "\n */\n };\n");
+ }
+
+ FlPrintFile (FileId, "\n");
+
+ if (FileId == ASL_FILE_LISTING_OUTPUT)
+ {
+ /* Print a summary of the compile exceptions */
+
+ FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
+ AePrintErrorLog (FileId);
+ FlPrintFile (FileId, "\n");
+ UtDisplaySummary (FileId);
+ FlPrintFile (FileId, "\n");
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asllistsup.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllistsup.c
new file mode 100644
index 0000000000..694fbc87ea
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllistsup.c
@@ -0,0 +1,710 @@
+/******************************************************************************
+ *
+ * Module Name: asllistsup - Listing file support utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslistsup")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsDumpAscii
+ *
+ * PARAMETERS: FileId - ID of current listing file
+ * Count - Number of bytes to convert
+ * Buffer - Buffer of bytes to convert
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert hex bytes to ascii
+ *
+ ******************************************************************************/
+
+void
+LsDumpAscii (
+ UINT32 FileId,
+ UINT32 Count,
+ UINT8 *Buffer)
+{
+ UINT8 BufChar;
+ UINT32 i;
+
+
+ FlPrintFile (FileId, " \"");
+ for (i = 0; i < Count; i++)
+ {
+ BufChar = Buffer[i];
+ if (isprint (BufChar))
+ {
+ FlPrintFile (FileId, "%c", BufChar);
+ }
+ else
+ {
+ /* Not a printable character, just put out a dot */
+
+ FlPrintFile (FileId, ".");
+ }
+ }
+ FlPrintFile (FileId, "\"");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsDumpAsciiInComment
+ *
+ * PARAMETERS: FileId - ID of current listing file
+ * Count - Number of bytes to convert
+ * Buffer - Buffer of bytes to convert
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert hex bytes to ascii
+ *
+ ******************************************************************************/
+
+void
+LsDumpAsciiInComment (
+ UINT32 FileId,
+ UINT32 Count,
+ UINT8 *Buffer)
+{
+ UINT8 BufChar = 0;
+ UINT8 LastChar;
+ UINT32 i;
+
+
+ FlPrintFile (FileId, " \"");
+ for (i = 0; i < Count; i++)
+ {
+ LastChar = BufChar;
+ BufChar = Buffer[i];
+
+ if (isprint (BufChar))
+ {
+ /* Handle embedded C comment sequences */
+
+ if (((LastChar == '*') && (BufChar == '/')) ||
+ ((LastChar == '/') && (BufChar == '*')))
+ {
+ /* Insert a space to break the sequence */
+
+ FlPrintFile (FileId, ".", BufChar);
+ }
+
+ FlPrintFile (FileId, "%c", BufChar);
+ }
+ else
+ {
+ /* Not a printable character, just put out a dot */
+
+ FlPrintFile (FileId, ".");
+ }
+ }
+
+ FlPrintFile (FileId, "\"");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsCheckException
+ *
+ * PARAMETERS: LineNumber - Current logical (cumulative) line #
+ * FileId - ID of output listing file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check if there is an exception for this line, and if there is,
+ * put it in the listing immediately. Handles multiple errors
+ * per line. Gbl_NextError points to the next error in the
+ * sorted (by line #) list of compile errors/warnings.
+ *
+ ******************************************************************************/
+
+void
+LsCheckException (
+ UINT32 LineNumber,
+ UINT32 FileId)
+{
+
+ if ((!Gbl_NextError) ||
+ (LineNumber < Gbl_NextError->LogicalLineNumber ))
+ {
+ return;
+ }
+
+ /* Handle multiple errors per line */
+
+ if (FileId == ASL_FILE_LISTING_OUTPUT)
+ {
+ while (Gbl_NextError &&
+ (LineNumber >= Gbl_NextError->LogicalLineNumber))
+ {
+ AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n");
+
+ Gbl_NextError = Gbl_NextError->Next;
+ }
+
+ FlPrintFile (FileId, "\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsWriteListingHexBytes
+ *
+ * PARAMETERS: Buffer - AML code buffer
+ * Length - Number of AML bytes to write
+ * FileId - ID of current listing file.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write the contents of the AML buffer to the listing file via
+ * the listing buffer. The listing buffer is flushed every 16
+ * AML bytes.
+ *
+ ******************************************************************************/
+
+void
+LsWriteListingHexBytes (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 FileId)
+{
+ UINT32 i;
+
+
+ /* Transfer all requested bytes */
+
+ for (i = 0; i < Length; i++)
+ {
+ /* Print line header when buffer is empty */
+
+ if (Gbl_CurrentHexColumn == 0)
+ {
+ if (Gbl_HasIncludeFiles)
+ {
+ FlPrintFile (FileId, "%*s", 10, " ");
+ }
+
+ switch (FileId)
+ {
+ case ASL_FILE_LISTING_OUTPUT:
+
+ FlPrintFile (FileId, "%8.8X%s", Gbl_CurrentAmlOffset,
+ ASL_LISTING_LINE_PREFIX);
+ break;
+
+ case ASL_FILE_ASM_SOURCE_OUTPUT:
+
+ FlPrintFile (FileId, " db ");
+ break;
+
+ case ASL_FILE_C_SOURCE_OUTPUT:
+
+ FlPrintFile (FileId, " ");
+ break;
+
+ default:
+
+ /* No other types supported */
+
+ return;
+ }
+ }
+
+ /* Transfer AML byte and update counts */
+
+ Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i];
+
+ Gbl_CurrentHexColumn++;
+ Gbl_CurrentAmlOffset++;
+
+ /* Flush buffer when it is full */
+
+ if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE)
+ {
+ LsFlushListingBuffer (FileId);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsWriteSourceLines
+ *
+ * PARAMETERS: ToLineNumber -
+ * ToLogicalLineNumber - Write up to this source line number
+ * FileId - ID of current listing file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Read then write source lines to the listing file until we have
+ * reached the specified logical (cumulative) line number. This
+ * automatically echos out comment blocks and other non-AML
+ * generating text until we get to the actual AML-generating line
+ * of ASL code specified by the logical line number.
+ *
+ ******************************************************************************/
+
+void
+LsWriteSourceLines (
+ UINT32 ToLineNumber,
+ UINT32 ToLogicalLineNumber,
+ UINT32 FileId)
+{
+
+ /* Nothing to do for these file types */
+
+ if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) ||
+ (FileId == ASL_FILE_C_INCLUDE_OUTPUT))
+ {
+ return;
+ }
+
+ Gbl_CurrentLine = ToLogicalLineNumber;
+
+ /* Flush any hex bytes remaining from the last opcode */
+
+ LsFlushListingBuffer (FileId);
+
+ /* Read lines and write them as long as we are not caught up */
+
+ if (Gbl_SourceLine < Gbl_CurrentLine)
+ {
+ /*
+ * If we just completed writing some AML hex bytes, output a linefeed
+ * to add some whitespace for readability.
+ */
+ if (Gbl_HexBytesWereWritten)
+ {
+ FlPrintFile (FileId, "\n");
+ Gbl_HexBytesWereWritten = FALSE;
+ }
+
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, " /*\n");
+ }
+
+ /* Write one line at a time until we have reached the target line # */
+
+ while ((Gbl_SourceLine < Gbl_CurrentLine) &&
+ LsWriteOneSourceLine (FileId))
+ { ; }
+
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, " */");
+ }
+
+ FlPrintFile (FileId, "\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsWriteOneSourceLine
+ *
+ * PARAMETERS: FileId - ID of current listing file
+ *
+ * RETURN: FALSE on EOF (input source file), TRUE otherwise
+ *
+ * DESCRIPTION: Read one line from the input source file and echo it to the
+ * listing file, prefixed with the line number, and if the source
+ * file contains include files, prefixed with the current filename
+ *
+ ******************************************************************************/
+
+UINT32
+LsWriteOneSourceLine (
+ UINT32 FileId)
+{
+ UINT8 FileByte;
+ UINT32 Column = 0;
+ UINT32 Index = 16;
+ BOOLEAN StartOfLine = FALSE;
+ BOOLEAN ProcessLongLine = FALSE;
+
+
+ Gbl_SourceLine++;
+ Gbl_ListingNode->LineNumber++;
+
+ /* Ignore lines that are completely blank (but count the line above) */
+
+ if (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) != AE_OK)
+ {
+ return (0);
+ }
+ if (FileByte == '\n')
+ {
+ return (1);
+ }
+
+ /*
+ * This is a non-empty line, we will print the entire line with
+ * the line number and possibly other prefixes and transforms.
+ */
+
+ /* Line prefixes for special files, C and ASM output */
+
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, " *");
+ }
+ if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT)
+ {
+ FlPrintFile (FileId, "; ");
+ }
+
+ if (Gbl_HasIncludeFiles)
+ {
+ /*
+ * This file contains "include" statements, print the current
+ * filename and line number within the current file
+ */
+ FlPrintFile (FileId, "%12s %5d%s",
+ Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber,
+ ASL_LISTING_LINE_PREFIX);
+ }
+ else
+ {
+ /* No include files, just print the line number */
+
+ FlPrintFile (FileId, "%8u%s", Gbl_SourceLine,
+ ASL_LISTING_LINE_PREFIX);
+ }
+
+ /* Read the rest of this line (up to a newline or EOF) */
+
+ do
+ {
+ if (FileId == ASL_FILE_C_SOURCE_OUTPUT)
+ {
+ if (FileByte == '/')
+ {
+ FileByte = '*';
+ }
+ }
+
+ /* Split long input lines for readability in the listing */
+
+ Column++;
+ if (Column >= 128)
+ {
+ if (!ProcessLongLine)
+ {
+ if ((FileByte != '}') &&
+ (FileByte != '{'))
+ {
+ goto WriteByte;
+ }
+
+ ProcessLongLine = TRUE;
+ }
+
+ if (FileByte == '{')
+ {
+ FlPrintFile (FileId, "\n%*s{\n", Index, " ");
+ StartOfLine = TRUE;
+ Index += 4;
+ continue;
+ }
+
+ else if (FileByte == '}')
+ {
+ if (!StartOfLine)
+ {
+ FlPrintFile (FileId, "\n");
+ }
+
+ StartOfLine = TRUE;
+ Index -= 4;
+ FlPrintFile (FileId, "%*s}\n", Index, " ");
+ continue;
+ }
+
+ /* Ignore spaces/tabs at the start of line */
+
+ else if ((FileByte == ' ') && StartOfLine)
+ {
+ continue;
+ }
+
+ else if (StartOfLine)
+ {
+ StartOfLine = FALSE;
+ FlPrintFile (FileId, "%*s", Index, " ");
+ }
+
+WriteByte:
+ FlWriteFile (FileId, &FileByte, 1);
+ if (FileByte == '\n')
+ {
+ /*
+ * This line has been completed.
+ * Check if an error occurred on this source line during the compile.
+ * If so, we print the error message after the source line.
+ */
+ LsCheckException (Gbl_SourceLine, FileId);
+ return (1);
+ }
+ }
+ else
+ {
+ FlWriteFile (FileId, &FileByte, 1);
+ if (FileByte == '\n')
+ {
+ /*
+ * This line has been completed.
+ * Check if an error occurred on this source line during the compile.
+ * If so, we print the error message after the source line.
+ */
+ LsCheckException (Gbl_SourceLine, FileId);
+ return (1);
+ }
+ }
+
+ } while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK);
+
+ /* EOF on the input file was reached */
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsFlushListingBuffer
+ *
+ * PARAMETERS: FileId - ID of the listing file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code
+ * buffer. Usually called at the termination of a single line
+ * of source code or when the buffer is full.
+ *
+ ******************************************************************************/
+
+void
+LsFlushListingBuffer (
+ UINT32 FileId)
+{
+ UINT32 i;
+
+
+ if (Gbl_CurrentHexColumn == 0)
+ {
+ return;
+ }
+
+ /* Write the hex bytes */
+
+ switch (FileId)
+ {
+ case ASL_FILE_LISTING_OUTPUT:
+
+ for (i = 0; i < Gbl_CurrentHexColumn; i++)
+ {
+ FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]);
+ }
+
+ for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++)
+ {
+ FlWriteFile (FileId, ".", 1);
+ }
+
+ /* Write the ASCII character associated with each of the bytes */
+
+ LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
+ break;
+
+
+ case ASL_FILE_ASM_SOURCE_OUTPUT:
+
+ for (i = 0; i < Gbl_CurrentHexColumn; i++)
+ {
+ if (i > 0)
+ {
+ FlPrintFile (FileId, ",");
+ }
+ FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]);
+ }
+
+ for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
+ {
+ FlWriteFile (FileId, " ", 1);
+ }
+
+ FlPrintFile (FileId, " ;%8.8X",
+ Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE);
+
+ /* Write the ASCII character associated with each of the bytes */
+
+ LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
+ break;
+
+
+ case ASL_FILE_C_SOURCE_OUTPUT:
+
+ for (i = 0; i < Gbl_CurrentHexColumn; i++)
+ {
+ FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]);
+ }
+
+ /* Pad hex output with spaces if line is shorter than max line size */
+
+ for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++)
+ {
+ FlWriteFile (FileId, " ", 1);
+ }
+
+ /* AML offset for the start of the line */
+
+ FlPrintFile (FileId, " /* %8.8X",
+ Gbl_CurrentAmlOffset - Gbl_CurrentHexColumn);
+
+ /* Write the ASCII character associated with each of the bytes */
+
+ LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer);
+ FlPrintFile (FileId, " */");
+ break;
+
+ default:
+
+ /* No other types supported */
+
+ return;
+ }
+
+ FlPrintFile (FileId, "\n");
+
+ Gbl_CurrentHexColumn = 0;
+ Gbl_HexBytesWereWritten = TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsPushNode
+ *
+ * PARAMETERS: Filename - Pointer to the include filename
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push a listing node on the listing/include file stack. This
+ * stack enables tracking of include files (infinitely nested)
+ * and resumption of the listing of the parent file when the
+ * include file is finished.
+ *
+ ******************************************************************************/
+
+void
+LsPushNode (
+ char *Filename)
+{
+ ASL_LISTING_NODE *Lnode;
+
+
+ /* Create a new node */
+
+ Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE));
+
+ /* Initialize */
+
+ Lnode->Filename = Filename;
+ Lnode->LineNumber = 0;
+
+ /* Link (push) */
+
+ Lnode->Next = Gbl_ListingNode;
+ Gbl_ListingNode = Lnode;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsPopNode
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: List head after current head is popped off
+ *
+ * DESCRIPTION: Pop the current head of the list, free it, and return the
+ * next node on the stack (the new current node).
+ *
+ ******************************************************************************/
+
+ASL_LISTING_NODE *
+LsPopNode (
+ void)
+{
+ ASL_LISTING_NODE *Lnode;
+
+
+ /* Just grab the node at the head of the list */
+
+ Lnode = Gbl_ListingNode;
+ if ((!Lnode) ||
+ (!Lnode->Next))
+ {
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL,
+ "Could not pop empty listing stack");
+ return (Gbl_ListingNode);
+ }
+
+ Gbl_ListingNode = Lnode->Next;
+ ACPI_FREE (Lnode);
+
+ /* New "Current" node is the new head */
+
+ return (Gbl_ListingNode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslload.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslload.c
new file mode 100644
index 0000000000..c8ae3adf7b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslload.c
@@ -0,0 +1,925 @@
+/******************************************************************************
+ *
+ * Module Name: dswload - Dispatcher namespace load callbacks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslload")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+LdLoadFieldElements (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+LdLoadResourceElements (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+LdNamespace1Begin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+LdNamespace2Begin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+LdCommonNamespaceEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdLoadNamespace
+ *
+ * PARAMETERS: RootOp - Root of the parse tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
+ * named ASL/AML objects into the namespace. The namespace is
+ * constructed in order to resolve named references and references
+ * to named fields within resource templates/descriptors.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LdLoadNamespace (
+ ACPI_PARSE_OBJECT *RootOp)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
+
+ /* Create a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Walk the entire parse tree, first pass */
+
+ TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
+ LdCommonNamespaceEnd, WalkState);
+
+ /* Second pass to handle forward references */
+
+ TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
+ LdCommonNamespaceEnd, WalkState);
+
+ /* Dump the namespace if debug is enabled */
+
+ AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
+ ACPI_FREE (WalkState);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdLoadFieldElements
+ *
+ * PARAMETERS: Op - Parent node (Field)
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter the named elements of the field (children of the parent)
+ * into the namespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LdLoadFieldElements (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Child = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Get the first named field element */
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_BANK_FIELD_OP:
+
+ Child = UtGetArg (Op, 6);
+ break;
+
+ case AML_INDEX_FIELD_OP:
+
+ Child = UtGetArg (Op, 5);
+ break;
+
+ case AML_FIELD_OP:
+
+ Child = UtGetArg (Op, 4);
+ break;
+
+ default:
+
+ /* No other opcodes should arrive here */
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Enter all elements into the namespace */
+
+ while (Child)
+ {
+ switch (Child->Asl.AmlOpcode)
+ {
+ case AML_INT_RESERVEDFIELD_OP:
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_CONNECTION_OP:
+ break;
+
+ default:
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Child->Asl.Value.String,
+ ACPI_TYPE_LOCAL_REGION_FIELD,
+ ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND,
+ NULL, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status != AE_ALREADY_EXISTS)
+ {
+ AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
+ Child->Asl.Value.String);
+ return (Status);
+ }
+
+ /*
+ * The name already exists in this scope
+ * But continue processing the elements
+ */
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
+ Child->Asl.Value.String);
+ }
+ else
+ {
+ Child->Asl.Node = Node;
+ Node->Op = Child;
+ }
+ break;
+ }
+
+ Child = Child->Asl.Next;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdLoadResourceElements
+ *
+ * PARAMETERS: Op - Parent node (Resource Descriptor)
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter the named elements of the resource descriptor (children
+ * of the parent) into the namespace.
+ *
+ * NOTE: In the real AML namespace, these named elements never exist. But
+ * we simply use the namespace here as a symbol table so we can look
+ * them up as they are referenced.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LdLoadResourceElements (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *InitializerOp = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /*
+ * Enter the resource name into the namespace. Name must not already exist.
+ * This opens a scope, so later field names are guaranteed to be new/unique.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
+ ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
+ WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ /* Actual node causing the error was saved in ParentMethod */
+
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
+ (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
+ return (AE_OK);
+ }
+ return (Status);
+ }
+
+ Node->Value = (UINT32) Op->Asl.Value.Integer;
+ Node->Op = Op;
+ Op->Asl.Node = Node;
+
+ /*
+ * Now enter the predefined fields, for easy lookup when referenced
+ * by the source ASL
+ */
+ InitializerOp = ASL_GET_CHILD_NODE (Op);
+ while (InitializerOp)
+ {
+ if (InitializerOp->Asl.ExternalName)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ InitializerOp->Asl.ExternalName,
+ ACPI_TYPE_LOCAL_RESOURCE_FIELD,
+ ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Store the field offset and length in the namespace node
+ * so it can be used when the field is referenced
+ */
+ Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
+ Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
+ InitializerOp->Asl.Node = Node;
+ Node->Op = InitializerOp;
+ }
+
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdNamespace1Begin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the parse tree walk. If this
+ * is a named AML opcode, enter into the namespace
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LdNamespace1Begin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY;
+ char *Path;
+ UINT32 Flags = ACPI_NS_NO_UPSEARCH;
+ ACPI_PARSE_OBJECT *Arg;
+ UINT32 i;
+ BOOLEAN ForceNewScope = FALSE;
+
+
+ ACPI_FUNCTION_NAME (LdNamespace1Begin);
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
+ Op, Op->Asl.ParseOpName));
+
+ /*
+ * We are only interested in opcodes that have an associated name
+ * (or multiple names)
+ */
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_FIELD_OP:
+
+ Status = LdLoadFieldElements (Op, WalkState);
+ return (Status);
+
+ case AML_INT_CONNECTION_OP:
+
+
+ if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ break;
+ }
+ Arg = Op->Asl.Child;
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ if (Node->Type == ACPI_TYPE_BUFFER)
+ {
+ Arg->Asl.Node = Node;
+
+ Arg = Node->Op->Asl.Child; /* Get namepath */
+ Arg = Arg->Asl.Next; /* Get actual buffer */
+ Arg = Arg->Asl.Child; /* Buffer length */
+ Arg = Arg->Asl.Next; /* RAW_DATA buffer */
+ }
+ break;
+
+ default:
+
+ /* All other opcodes go below */
+
+ break;
+ }
+
+ /* Check if this object has already been installed in the namespace */
+
+ if (Op->Asl.Node)
+ {
+ return (AE_OK);
+ }
+
+ Path = Op->Asl.Namepath;
+ if (!Path)
+ {
+ return (AE_OK);
+ }
+
+ /* Map the raw opcode into an internal object type */
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_NAME:
+
+ Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */
+ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */
+
+ /*
+ * If this name refers to a ResourceTemplate, we will need to open
+ * a new scope so that the resource subfield names can be entered into
+ * the namespace underneath this name
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
+ {
+ ForceNewScope = TRUE;
+ }
+
+ /* Get the data type associated with the named object, not the name itself */
+
+ /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
+
+ ObjectType = 1;
+ for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
+ {
+ ObjectType++;
+ }
+ break;
+
+
+ case PARSEOP_EXTERNAL:
+ /*
+ * "External" simply enters a name and type into the namespace.
+ * We must be careful to not open a new scope, however, no matter
+ * what type the external name refers to (e.g., a method)
+ *
+ * first child is name, next child is ObjectType
+ */
+ ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
+ ObjectType = ACPI_TYPE_ANY;
+
+ /*
+ * We will mark every new node along the path as "External". This
+ * allows some or all of the nodes to be created later in the ASL
+ * code. Handles cases like this:
+ *
+ * External (\_SB_.PCI0.ABCD, IntObj)
+ * Scope (_SB_)
+ * {
+ * Device (PCI0)
+ * {
+ * }
+ * }
+ * Method (X)
+ * {
+ * Store (\_SB_.PCI0.ABCD, Local0)
+ * }
+ */
+ Flags |= ACPI_NS_EXTERNAL;
+ break;
+
+ case PARSEOP_DEFAULT_ARG:
+
+ if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
+ {
+ Status = LdLoadResourceElements (Op, WalkState);
+ return_ACPI_STATUS (Status);
+ }
+
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+ break;
+
+ case PARSEOP_SCOPE:
+ /*
+ * The name referenced by Scope(Name) must already exist at this point.
+ * In other words, forward references for Scope() are not supported.
+ * The only real reason for this is that the MS interpreter cannot
+ * handle this case. Perhaps someday this case can go away.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ /* The name was not found, go ahead and create it */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
+ ACPI_TYPE_LOCAL_SCOPE,
+ ACPI_IMODE_LOAD_PASS1, Flags,
+ WalkState, &(Node));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * However, this is an error -- primarily because the MS
+ * interpreter can't handle a forward reference from the
+ * Scope() operator.
+ */
+ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
+ Op->Asl.ExternalName);
+ AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
+ Op->Asl.ExternalName);
+ goto FinishNode;
+ }
+
+ AslCoreSubsystemError (Op, Status,
+ "Failure from namespace lookup", FALSE);
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* We found a node with this name, now check the type */
+
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_LOCAL_SCOPE:
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+
+ /* These are acceptable types - they all open a new scope */
+ break;
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * These types we will allow, but we will change the type.
+ * This enables some existing code of the form:
+ *
+ * Name (DEB, 0)
+ * Scope (DEB) { ... }
+ *
+ * Which is used to workaround the fact that the MS interpreter
+ * does not allow Scope() forward references.
+ */
+ sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
+ Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
+ AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
+
+ /* Switch the type to scope, open the new scope */
+
+ Node->Type = ACPI_TYPE_LOCAL_SCOPE;
+ Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ break;
+
+ default:
+
+ /* All other types are an error */
+
+ sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
+ AcpiUtGetTypeName (Node->Type));
+ AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
+
+ /*
+ * However, switch the type to be an actual scope so
+ * that compilation can continue without generating a whole
+ * cascade of additional errors. Open the new scope.
+ */
+ Node->Type = ACPI_TYPE_LOCAL_SCOPE;
+ Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ break;
+ }
+
+ Status = AE_OK;
+ goto FinishNode;
+
+
+ default:
+
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+ break;
+ }
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
+ Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
+
+ /* The name must not already exist */
+
+ Flags |= ACPI_NS_ERROR_IF_FOUND;
+
+ /*
+ * Enter the named type into the internal namespace. We enter the name
+ * as we go downward in the parse tree. Any necessary subobjects that
+ * involve arguments to the opcode must be created as we go back up the
+ * parse tree later.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ /* The name already exists in this scope */
+
+ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
+ {
+ /* Allow multiple references to the same scope */
+
+ Node->Type = (UINT8) ObjectType;
+ Status = AE_OK;
+ }
+ else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
+ (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
+ {
+ /*
+ * Allow one create on an object or segment that was
+ * previously declared External
+ */
+ Node->Flags &= ~ANOBJ_IS_EXTERNAL;
+ Node->Type = (UINT8) ObjectType;
+
+ /* Just retyped a node, probably will need to open a scope */
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ Status = AE_OK;
+ }
+ else
+ {
+ /* Valid error, object already exists */
+
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName);
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+ else
+ {
+ AslCoreSubsystemError (Op, Status,
+ "Failure from namespace lookup", FALSE);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ if (ForceNewScope)
+ {
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+FinishNode:
+ /*
+ * Point the parse node to the new namespace node, and point
+ * the Node back to the original Parse node
+ */
+ Op->Asl.Node = Node;
+ Node->Op = Op;
+
+ /* Set the actual data type if appropriate (EXTERNAL term only) */
+
+ if (ActualObjectType != ACPI_TYPE_ANY)
+ {
+ Node->Type = (UINT8) ActualObjectType;
+ Node->Value = ASL_EXTERNAL_METHOD;
+ }
+
+ if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
+ {
+ /*
+ * Get the method argument count from "Extra" and save
+ * it in the namespace node
+ */
+ Node->Value = (UINT32) Op->Asl.Extra;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdNamespace2Begin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
+ * Second pass resolves some forward references.
+ *
+ * Notes:
+ * Currently only needs to handle the Alias operator.
+ * Could be used to allow forward references from the Scope() operator, but
+ * the MS interpreter does not allow this, so this compiler does not either.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LdNamespace2Begin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OBJECT_TYPE ObjectType;
+ BOOLEAN ForceNewScope = FALSE;
+ ACPI_PARSE_OBJECT *Arg;
+ char *Path;
+ ACPI_NAMESPACE_NODE *TargetNode;
+
+
+ ACPI_FUNCTION_NAME (LdNamespace2Begin);
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
+ Op, Op->Asl.ParseOpName));
+
+
+ /* Ignore Ops with no namespace node */
+
+ Node = Op->Asl.Node;
+ if (!Node)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the type to determine if we should push the scope */
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
+ (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
+ {
+ ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
+ }
+ else
+ {
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+ }
+
+ /* Push scope for Resource Templates */
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
+ {
+ ForceNewScope = TRUE;
+ }
+ }
+
+ /* Push the scope stack */
+
+ if (ForceNewScope || AcpiNsOpensScope (ObjectType))
+ {
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
+ {
+ /* Complete the alias node by getting and saving the target node */
+
+ /* First child is the alias target */
+
+ Arg = Op->Asl.Child;
+
+ /* Get the target pathname */
+
+ Path = Arg->Asl.Namepath;
+ if (!Path)
+ {
+ Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ /* Get the NS node associated with the target. It must exist. */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &TargetNode);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
+ Op->Asl.ExternalName);
+
+ /*
+ * The name was not found, go ahead and create it.
+ * This prevents more errors later.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
+ ACPI_TYPE_ANY,
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
+ WalkState, &(Node));
+ return (AE_OK);
+ }
+
+ AslCoreSubsystemError (Op, Status,
+ "Failure from namespace lookup", FALSE);
+ return (AE_OK);
+ }
+
+ /* Save the target node within the alias node */
+
+ Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LdCommonNamespaceEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ * We only need to worry about managing the scope stack here.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LdCommonNamespaceEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
+ ACPI_OBJECT_TYPE ObjectType;
+ BOOLEAN ForceNewScope = FALSE;
+
+
+ ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
+
+
+ /* We are only interested in opcodes that have an associated name */
+
+ if (!Op->Asl.Namepath)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the type to determine if we should pop the scope */
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
+ (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
+ {
+ /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
+
+ ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
+ }
+ else
+ {
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+ }
+
+ /* Pop scope that was pushed for Resource Templates */
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
+ {
+ ForceNewScope = TRUE;
+ }
+ }
+
+ /* Pop the scope stack */
+
+ if (ForceNewScope || AcpiNsOpensScope (ObjectType))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "(%s): Popping scope for Op [%s] %p\n",
+ AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
+
+ (void) AcpiDsScopeStackPop (WalkState);
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asllookup.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllookup.c
new file mode 100644
index 0000000000..0937abe960
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asllookup.c
@@ -0,0 +1,314 @@
+/******************************************************************************
+ *
+ * Module Name: asllookup- Namespace lookup functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asllookup")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+LkIsObjectUsed (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_PARSE_OBJECT *
+LkGetNameOp (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LkFindUnreferencedObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Namespace walk to find objects that are not referenced in any
+ * way. Must be called after the namespace has been cross
+ * referenced.
+ *
+ ******************************************************************************/
+
+void
+LkFindUnreferencedObjects (
+ void)
+{
+
+ /* Walk entire namespace from the supplied root */
+
+ (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
+ NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LkIsObjectUsed
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
+ * We have to be careful, because some types and names are
+ * typically or always unreferenced, we don't want to issue
+ * excessive warnings. Note: Names that are declared within a
+ * control method are temporary, so we always issue a remark
+ * if they are not referenced.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+LkIsObjectUsed (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ACPI_NAMESPACE_NODE *Next;
+ ASL_METHOD_LOCAL *MethodLocals;
+ ASL_METHOD_LOCAL *MethodArgs;
+ UINT32 i;
+
+
+ if (Node->Type == ACPI_TYPE_METHOD)
+ {
+ if (!Node->Op || !Node->MethodLocals)
+ {
+ return (AE_OK);
+ }
+
+ MethodLocals = (ASL_METHOD_LOCAL *) Node->MethodLocals;
+ MethodArgs = (ASL_METHOD_LOCAL *) Node->MethodArgs;
+
+ /*
+ * Analysis of LocalX variables
+ */
+ for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
+ {
+ /* Warn for Locals that are set but never referenced */
+
+ if ((MethodLocals[i].Flags & ASL_LOCAL_INITIALIZED) &&
+ (!(MethodLocals[i].Flags & ASL_LOCAL_REFERENCED)))
+ {
+ sprintf (MsgBuffer, "Local%u", i);
+ AslError (ASL_WARNING, ASL_MSG_LOCAL_NOT_USED,
+ MethodLocals[i].Op, MsgBuffer);
+ }
+ }
+
+ /*
+ * Analysis of ArgX variables (standard method arguments,
+ * and remaining unused ArgX can also be used as locals)
+ */
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ if (MethodArgs[i].Flags & ASL_ARG_IS_LOCAL)
+ {
+ /* Warn if ArgX is being used as a local, but not referenced */
+
+ if ((MethodArgs[i].Flags & ASL_ARG_INITIALIZED) &&
+ (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
+ {
+ sprintf (MsgBuffer, "Arg%u", i);
+ AslError (ASL_WARNING, ASL_MSG_ARG_AS_LOCAL_NOT_USED,
+ MethodArgs[i].Op, MsgBuffer);
+ }
+ }
+ else
+ {
+ /*
+ * Remark if a normal method ArgX is not referenced.
+ * We ignore the predefined methods since often, not
+ * all arguments are needed or used.
+ */
+ if ((Node->Name.Ascii[0] != '_') &&
+ (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
+ {
+ sprintf (MsgBuffer, "Arg%u", i);
+ AslError (ASL_REMARK, ASL_MSG_ARG_NOT_USED,
+ MethodArgs[i].Op, MsgBuffer);
+ }
+ }
+ }
+ }
+
+ /* Referenced flag is set during the namespace xref */
+
+ if (Node->Flags & ANOBJ_IS_REFERENCED)
+ {
+ return (AE_OK);
+ }
+
+ if (!Node->Op)
+ {
+ return (AE_OK);
+ }
+
+ /* These types are typically never directly referenced, ignore them */
+
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_THERMAL:
+ case ACPI_TYPE_LOCAL_RESOURCE:
+
+ return (AE_OK);
+
+ default:
+
+ break;
+ }
+
+ /* Determine if the name is within a control method */
+
+ Next = Node->Parent;
+ while (Next)
+ {
+ if (Next->Type == ACPI_TYPE_METHOD)
+ {
+ /*
+ * Name is within a method, therefore it is temporary.
+ * Issue a remark even if it is a reserved name (starts
+ * with an underscore).
+ */
+ sprintf (MsgBuffer, "Name is within method [%4.4s]",
+ Next->Name.Ascii);
+ AslError (ASL_REMARK, ASL_MSG_NOT_REFERENCED,
+ LkGetNameOp (Node->Op), MsgBuffer);
+ return (AE_OK);
+ }
+
+ Next = Next->Parent;
+ }
+
+ /* The name is not within a control method */
+
+ /*
+ * Ignore names that start with an underscore. These are the reserved
+ * ACPI names and are typically not referenced since they are meant
+ * to be called by the host OS.
+ */
+ if (Node->Name.Ascii[0] == '_')
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * What remains is an unresolved user name that is not within a method.
+ * However, the object could be referenced via another table, so issue
+ * the warning at level 2.
+ */
+ AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED,
+ LkGetNameOp (Node->Op), NULL);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LkGetNameOp
+ *
+ * PARAMETERS: Op - Current Op
+ *
+ * RETURN: NameOp associated with the input op
+ *
+ * DESCRIPTION: Find the name declaration op associated with the operator
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+LkGetNameOp (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_PARSE_OBJECT *NameOp = Op;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+
+
+ /* Get the NamePath from the appropriate place */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ /* For nearly all NAMED operators, the name reference is the first child */
+
+ NameOp = Op->Asl.Child;
+ if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
+ {
+ /*
+ * ALIAS is the only oddball opcode, the name declaration
+ * (alias name) is the second operand
+ */
+ NameOp = Op->Asl.Child->Asl.Next;
+ }
+ }
+ else if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Name must appear as the last parameter */
+
+ NameOp = Op->Asl.Child;
+ while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
+ {
+ NameOp = NameOp->Asl.Next;
+ }
+ }
+
+ return (NameOp);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmain.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmain.c
new file mode 100644
index 0000000000..47b8b6ca8c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -0,0 +1,424 @@
+/******************************************************************************
+ *
+ * Module Name: aslmain - compiler main and utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <signal.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmain")
+
+/*
+ * Main routine for the iASL compiler.
+ *
+ * Portability note: The compiler depends upon the host for command-line
+ * wildcard support - it is not implemented locally. For example:
+ *
+ * Linux/Unix systems: Shell expands wildcards automatically.
+ *
+ * Windows: The setargv.obj module must be linked in to automatically
+ * expand wildcards.
+ */
+
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+AslSignalHandler (
+ int Sig);
+
+static void
+AslInitialize (
+ void);
+
+UINT8
+AcpiIsBigEndianMachine (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiIsBigEndianMachine
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: TRUE if machine is big endian
+ * FALSE if machine is little endian
+ *
+ * DESCRIPTION: Detect whether machine is little endian or big endian.
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiIsBigEndianMachine (
+ void)
+{
+ union {
+ UINT32 Integer;
+ UINT8 Bytes[4];
+ } Overlay = {0xFF000000};
+
+ return (Overlay.Bytes[0]); /* Returns 0xFF (TRUE) for big endian */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Usage
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display option help message.
+ * Optional items in square brackets.
+ *
+ ******************************************************************************/
+
+void
+Usage (
+ void)
+{
+ printf ("%s\n\n", ASL_COMPLIANCE);
+ ACPI_USAGE_HEADER ("iasl [Options] [Files]");
+
+ printf ("\nGeneral:\n");
+ ACPI_OPTION ("-@ <file>", "Specify command file");
+ ACPI_OPTION ("-I <dir>", "Specify additional include directory");
+ ACPI_OPTION ("-T <sig>|ALL|*", "Create table template file for ACPI <Sig>");
+ ACPI_OPTION ("-p <prefix>", "Specify path/filename prefix for all output files");
+ ACPI_OPTION ("-v", "Display compiler version");
+ ACPI_OPTION ("-vo", "Enable optimization comments");
+ ACPI_OPTION ("-vs", "Disable signon");
+
+ printf ("\nHelp:\n");
+ ACPI_OPTION ("-h", "This message");
+ ACPI_OPTION ("-hc", "Display operators allowed in constant expressions");
+ ACPI_OPTION ("-hf", "Display help for output filename generation");
+ ACPI_OPTION ("-hr", "Display ACPI reserved method names");
+ ACPI_OPTION ("-ht", "Display currently supported ACPI table names");
+
+ printf ("\nPreprocessor:\n");
+ ACPI_OPTION ("-D <symbol>", "Define symbol for preprocessor use");
+ ACPI_OPTION ("-li", "Create preprocessed output file (*.i)");
+ ACPI_OPTION ("-P", "Preprocess only and create preprocessor output file (*.i)");
+ ACPI_OPTION ("-Pn", "Disable preprocessor");
+
+ printf ("\nErrors, Warnings, and Remarks:\n");
+ ACPI_OPTION ("-va", "Disable all errors/warnings/remarks");
+ ACPI_OPTION ("-ve", "Report only errors (ignore warnings and remarks)");
+ ACPI_OPTION ("-vi", "Less verbose errors and warnings for use with IDEs");
+ ACPI_OPTION ("-vr", "Disable remarks");
+ ACPI_OPTION ("-vw <messageid>", "Disable specific warning or remark");
+ ACPI_OPTION ("-w1 -w2 -w3", "Set warning reporting level");
+ ACPI_OPTION ("-we", "Report warnings as errors");
+
+ printf ("\nAML Code Generation (*.aml):\n");
+ ACPI_OPTION ("-oa", "Disable all optimizations (compatibility mode)");
+ ACPI_OPTION ("-of", "Disable constant folding");
+ ACPI_OPTION ("-oi", "Disable integer optimization to Zero/One/Ones");
+ ACPI_OPTION ("-on", "Disable named reference string optimization");
+ ACPI_OPTION ("-cr", "Disable Resource Descriptor error checking");
+ ACPI_OPTION ("-in", "Ignore NoOp operators");
+ ACPI_OPTION ("-r <revision>", "Override table header Revision (1-255)");
+
+ printf ("\nOptional Source Code Output Files:\n");
+ ACPI_OPTION ("-sc -sa", "Create source file in C or assembler (*.c or *.asm)");
+ ACPI_OPTION ("-ic -ia", "Create include file in C or assembler (*.h or *.inc)");
+ ACPI_OPTION ("-tc -ta -ts", "Create hex AML table in C, assembler, or ASL (*.hex)");
+ ACPI_OPTION ("-so", "Create offset table in C (*.offset.h)");
+
+ printf ("\nOptional Listing Files:\n");
+ ACPI_OPTION ("-l", "Create mixed listing file (ASL source and AML) (*.lst)");
+ ACPI_OPTION ("-lm", "Create hardware summary map file (*.map)");
+ ACPI_OPTION ("-ln", "Create namespace file (*.nsp)");
+ ACPI_OPTION ("-ls", "Create combined source file (expanded includes) (*.src)");
+
+ printf ("\nData Table Compiler:\n");
+ ACPI_OPTION ("-G", "Compile custom table that contains generic operators");
+ ACPI_OPTION ("-vt", "Create verbose template files (full disassembly)");
+
+ printf ("\nAML Disassembler:\n");
+ ACPI_OPTION ("-d <f1 f2 ...>", "Disassemble or decode binary ACPI tables to file (*.dsl)");
+ ACPI_OPTION ("", " (Optional, file type is automatically detected)");
+ ACPI_OPTION ("-da <f1 f2 ...>", "Disassemble multiple tables from single namespace");
+ ACPI_OPTION ("-db", "Do not translate Buffers to Resource Templates");
+ ACPI_OPTION ("-dc <f1 f2 ...>", "Disassemble AML and immediately compile it");
+ ACPI_OPTION ("", " (Obtain DSDT from current system if no input file)");
+ ACPI_OPTION ("-df", "Force disassembler to assume table contains valid AML");
+ ACPI_OPTION ("-dl", "Emit legacy ASL code only (no C-style operators)");
+ ACPI_OPTION ("-e <f1 f2 ...>", "Include ACPI table(s) for external symbol resolution");
+ ACPI_OPTION ("-fe <file>", "Specify external symbol declaration file");
+ ACPI_OPTION ("-in", "Ignore NoOp opcodes");
+ ACPI_OPTION ("-l", "Disassemble to mixed ASL and AML code");
+ ACPI_OPTION ("-vt", "Dump binary table data in hex format within output file");
+
+ printf ("\nDebug Options:\n");
+ ACPI_OPTION ("-bf", "Create debug file (full output) (*.txt)");
+ ACPI_OPTION ("-bs", "Create debug file (parse tree only) (*.txt)");
+ ACPI_OPTION ("-bp <depth>", "Prune ASL parse tree");
+ ACPI_OPTION ("-bt <type>", "Object type to be pruned from the parse tree");
+ ACPI_OPTION ("-f", "Ignore errors, force creation of AML output file(s)");
+ ACPI_OPTION ("-m <size>", "Set internal line buffer size (in Kbytes)");
+ ACPI_OPTION ("-n", "Parse only, no output generation");
+ ACPI_OPTION ("-ot", "Display compile times and statistics");
+ ACPI_OPTION ("-x <level>", "Set debug level for trace output");
+ ACPI_OPTION ("-z", "Do not insert new compiler ID for DataTables");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FilenameHelp
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display help message for output filename generation
+ *
+ ******************************************************************************/
+
+void
+AslFilenameHelp (
+ void)
+{
+
+ printf ("\nAML output filename generation:\n");
+ printf (" Output filenames are generated by appending an extension to a common\n");
+ printf (" filename prefix. The filename prefix is obtained via one of the\n");
+ printf (" following methods (in priority order):\n");
+ printf (" 1) The -p option specifies the prefix\n");
+ printf (" 2) The prefix of the AMLFileName in the ASL Definition Block\n");
+ printf (" 3) The prefix of the input filename\n");
+ printf ("\n");
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AslSignalHandler
+ *
+ * PARAMETERS: Sig - Signal that invoked this handler
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Control-C handler. Delete any intermediate files and any
+ * output files that may be left in an indeterminate state.
+ *
+ *****************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AslSignalHandler (
+ int Sig)
+{
+ UINT32 i;
+
+
+ signal (Sig, SIG_IGN);
+ printf ("Aborting\n\n");
+
+ /* Close all open files */
+
+ Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .pre file is same as source file */
+
+ for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
+ {
+ FlCloseFile (i);
+ }
+
+ /* Delete any output files */
+
+ for (i = ASL_FILE_AML_OUTPUT; i < ASL_MAX_FILE_TYPE; i++)
+ {
+ FlDeleteFile (i);
+ }
+
+ exit (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize compiler globals
+ *
+ ******************************************************************************/
+
+static void
+AslInitialize (
+ void)
+{
+ UINT32 i;
+
+
+ AcpiGbl_DmOpt_Verbose = FALSE;
+
+ for (i = 0; i < ASL_NUM_FILES; i++)
+ {
+ Gbl_Files[i].Handle = NULL;
+ Gbl_Files[i].Filename = NULL;
+ }
+
+ Gbl_Files[ASL_FILE_STDOUT].Handle = stdout;
+ Gbl_Files[ASL_FILE_STDOUT].Filename = "STDOUT";
+
+ Gbl_Files[ASL_FILE_STDERR].Handle = stderr;
+ Gbl_Files[ASL_FILE_STDERR].Filename = "STDERR";
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: main
+ *
+ * PARAMETERS: Standard argc/argv
+ *
+ * RETURN: Program termination code
+ *
+ * DESCRIPTION: C main routine for the Asl Compiler. Handle command line
+ * options and begin the compile for each file on the command line
+ *
+ ******************************************************************************/
+
+int ACPI_SYSTEM_XFACE
+main (
+ int argc,
+ char **argv)
+{
+ ACPI_STATUS Status;
+ int Index1;
+ int Index2;
+ int ReturnStatus = 0;
+
+
+ /*
+ * Big-endian machines are not currently supported. ACPI tables must
+ * be little-endian, and support for big-endian machines needs to
+ * be implemented.
+ */
+ if (AcpiIsBigEndianMachine ())
+ {
+ fprintf (stderr,
+ "iASL is not currently supported on big-endian machines.\n");
+ return (-1);
+ }
+
+ AcpiOsInitialize ();
+ ACPI_DEBUG_INITIALIZE (); /* For debug version only */
+
+ /* Initialize preprocessor and compiler before command line processing */
+
+ signal (SIGINT, AslSignalHandler);
+ AcpiGbl_ExternalFileList = NULL;
+ AcpiDbgLevel = 0;
+ PrInitializePreprocessor ();
+ AslInitialize ();
+
+ Index1 = Index2 = AslCommandLine (argc, argv);
+
+ /* Allocate the line buffer(s), must be after command line */
+
+ Gbl_LineBufferSize /= 2;
+ UtExpandLineBuffers ();
+
+ /* Perform global actions first/only */
+
+ if (Gbl_DisassembleAll)
+ {
+ while (argv[Index1])
+ {
+ Status = AcpiDmAddToExternalFileList (argv[Index1]);
+ if (ACPI_FAILURE (Status))
+ {
+ return (-1);
+ }
+
+ Index1++;
+ }
+ }
+
+ /* Process each pathname/filename in the list, with possible wildcards */
+
+ while (argv[Index2])
+ {
+ /*
+ * If -p not specified, we will use the input filename as the
+ * output filename prefix
+ */
+ if (Gbl_UseDefaultAmlFilename)
+ {
+ Gbl_OutputFilenamePrefix = argv[Index2];
+ UtConvertBackslashes (Gbl_OutputFilenamePrefix);
+ }
+
+ Status = AslDoOneFile (argv[Index2]);
+ if (ACPI_FAILURE (Status))
+ {
+ ReturnStatus = -1;
+ goto CleanupAndExit;
+ }
+
+ Index2++;
+ }
+
+
+CleanupAndExit:
+
+ UtFreeLineBuffers ();
+ AslParserCleanup ();
+
+ if (AcpiGbl_ExternalFileList)
+ {
+ AcpiDmClearExternalFileList();
+ }
+
+ return (ReturnStatus);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmap.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmap.c
new file mode 100644
index 0000000000..90252cb7b5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmap.c
@@ -0,0 +1,483 @@
+/******************************************************************************
+ *
+ * Module Name: aslmap - parser to AML opcode mapping table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmap")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslMapNamedOpcodeToDataType
+ *
+ * PARAMETERS: Opcode - The Named AML opcode to map
+ *
+ * RETURN: The ACPI type associated with the named opcode
+ *
+ * DESCRIPTION: Convert a raw Named AML opcode to the associated data type.
+ * Named opcodes are a subset of the AML opcodes.
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AslMapNamedOpcodeToDataType (
+ UINT16 Opcode)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ /*
+ * There are some differences from the opcode table types, we
+ * catch them here.
+ */
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+
+ if (Opcode == AML_INT_NAMEPATH_OP)
+ {
+ return (ACPI_TYPE_ANY);
+ }
+
+ if (Opcode == AML_INT_METHODCALL_OP)
+ {
+ return (ACPI_TYPE_ANY);
+ }
+
+ if (OpInfo->Flags & AML_NSOBJECT)
+ {
+ return (OpInfo->ObjectType);
+ }
+
+ return (ACPI_TYPE_ANY);
+}
+
+
+/*******************************************************************************
+ *
+ * DATA STRUCTURE: AslKeywordMapping
+ *
+ * DESCRIPTION: Maps the ParseOpcode to the actual AML opcode. The parse
+ * opcodes are generated from Bison, and this table must
+ * track any additions to them.
+ *
+ * Each entry in the table contains the following items:
+ *
+ * AML opcode - Opcode that is written to the AML file
+ * Value - Value of the object to be written (if applicable)
+ * Flags - 1) Whether this opcode opens an AML "package".
+ *
+ ******************************************************************************/
+/*
+ * TBD:
+ * AccessAttrib
+ * AccessType
+ * AMlop for DMA?
+ * ObjectType keywords
+ * Register
+ */
+
+const ASL_MAPPING_ENTRY AslKeywordMapping [] =
+{
+/*! [Begin] no source code translation (keep the table structure) */
+
+
+/* ACCESSAS */ OP_TABLE_ENTRY (AML_INT_ACCESSFIELD_OP, 0, 0, 0),
+/* ACCESSATTRIB_BLOCK */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_BLOCK, 0, 0),
+/* ACCESSATTRIB_BLOCK_CALL */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_BLOCK_CALL, 0, 0),
+/* ACCESSATTRIB_BYTE */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_BYTE, 0, 0),
+/* ACCESSATTRIB_MULTIBYTE */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_MULTIBYTE, 0, 0),
+/* ACCESSATTRIB_QUICK */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_QUICK, 0, 0),
+/* ACCESSATTRIB_RAW_BYTES */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_RAW_BYTES, 0, 0),
+/* ACCESSATTRIB_RAW_PROCESS */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_RAW_PROCESS, 0, 0),
+/* ACCESSATTRIB_SND_RCV */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_SEND_RCV, 0, 0),
+/* ACCESSATTRIB_WORD */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_WORD, 0, 0),
+/* ACCESSATTRIB_WORD_CALL */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ATTRIB_WORD_CALL, 0, 0),
+/* ACCESSTYPE_ANY */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_ANY, 0, 0),
+/* ACCESSTYPE_BUF */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_BUFFER, 0, 0),
+/* ACCESSTYPE_BYTE */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_BYTE, 0, 0),
+/* ACCESSTYPE_DWORD */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_DWORD, 0, 0),
+/* ACCESSTYPE_QWORD */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_QWORD, 0, 0),
+/* ACCESSTYPE_WORD */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_ACCESS_WORD, 0, 0),
+/* ACQUIRE */ OP_TABLE_ENTRY (AML_ACQUIRE_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ADD */ OP_TABLE_ENTRY (AML_ADD_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ADDRESSINGMODE_7BIT */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* ADDRESSINGMODE_10BIT */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* ADDRESSTYPE_ACPI */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* ADDRESSTYPE_MEMORY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* ADDRESSTYPE_NVS */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* ADDRESSTYPE_RESERVED */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* ALIAS */ OP_TABLE_ENTRY (AML_ALIAS_OP, 0, 0, 0),
+/* AND */ OP_TABLE_ENTRY (AML_BIT_AND_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ARG0 */ OP_TABLE_ENTRY (AML_ARG0, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG1 */ OP_TABLE_ENTRY (AML_ARG1, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG2 */ OP_TABLE_ENTRY (AML_ARG2, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG3 */ OP_TABLE_ENTRY (AML_ARG3, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG4 */ OP_TABLE_ENTRY (AML_ARG4, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG5 */ OP_TABLE_ENTRY (AML_ARG5, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* ARG6 */ OP_TABLE_ENTRY (AML_ARG6, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* BANKFIELD */ OP_TABLE_ENTRY (AML_BANK_FIELD_OP, 0, NODE_AML_PACKAGE, 0),
+/* BITSPERBYTE_EIGHT */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* BITSPERBYTE_FIVE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* BITSPERBYTE_NINE */ OP_TABLE_ENTRY (AML_BYTE_OP, 4, 0, 0),
+/* BITSPERBYTE_SEVEN */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* BITSPERBYTE_SIX */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* BREAK */ OP_TABLE_ENTRY (AML_BREAK_OP, 0, 0, 0),
+/* BREAKPOINT */ OP_TABLE_ENTRY (AML_BREAK_POINT_OP, 0, 0, 0),
+/* BUFFER */ OP_TABLE_ENTRY (AML_BUFFER_OP, 0, NODE_AML_PACKAGE, ACPI_BTYPE_BUFFER),
+/* BUSMASTERTYPE_MASTER */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* BUSMASTERTYPE_NOTMASTER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* BYTECONST */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, 0, 0, ACPI_BTYPE_INTEGER),
+/* CASE */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* CLOCKPHASE_FIRST */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* CLOCKPHASE_SECOND */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* CLOCKPOLARITY_HIGH */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* CLOCKPOLARITY_LOW */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* CONCATENATE */ OP_TABLE_ENTRY (AML_CONCAT_OP, 0, 0, ACPI_BTYPE_COMPUTE_DATA),
+/* CONCATENATERESTEMPLATE */ OP_TABLE_ENTRY (AML_CONCAT_RES_OP, 0, 0, ACPI_BTYPE_BUFFER),
+/* CONDREFOF */ OP_TABLE_ENTRY (AML_COND_REF_OF_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* CONNECTION */ OP_TABLE_ENTRY (AML_INT_CONNECTION_OP, 0, 0, 0),
+/* CONTINUE */ OP_TABLE_ENTRY (AML_CONTINUE_OP, 0, 0, 0),
+/* COPY */ OP_TABLE_ENTRY (AML_COPY_OP, 0, 0, ACPI_BTYPE_DATA_REFERENCE),
+/* CREATEBITFIELD */ OP_TABLE_ENTRY (AML_CREATE_BIT_FIELD_OP, 0, 0, 0),
+/* CREATEBYTEFIELD */ OP_TABLE_ENTRY (AML_CREATE_BYTE_FIELD_OP, 0, 0, 0),
+/* CREATEDWORDFIELD */ OP_TABLE_ENTRY (AML_CREATE_DWORD_FIELD_OP, 0, 0, 0),
+/* CREATEFIELD */ OP_TABLE_ENTRY (AML_CREATE_FIELD_OP, 0, 0, 0),
+/* CREATEQWORDFIELD */ OP_TABLE_ENTRY (AML_CREATE_QWORD_FIELD_OP, 0, 0, 0),
+/* CREATEWORDFIELD */ OP_TABLE_ENTRY (AML_CREATE_WORD_FIELD_OP, 0, 0, 0),
+/* DATABUFFER */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DATATABLEREGION */ OP_TABLE_ENTRY (AML_DATA_REGION_OP, 0, 0, 0),
+/* DEBUG */ OP_TABLE_ENTRY (AML_DEBUG_OP, 0, 0, ACPI_BTYPE_DEBUG_OBJECT),
+/* DECODETYPE_POS */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* DECODETYPE_SUB */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* DECREMENT */ OP_TABLE_ENTRY (AML_DECREMENT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* DEFAULT */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DEFAULT_ARG */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DEFINITIONBLOCK */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DEREFOF */ OP_TABLE_ENTRY (AML_DEREF_OF_OP, 0, 0, ACPI_BTYPE_DATA_REFERENCE | ACPI_BTYPE_STRING),
+/* DEVICE */ OP_TABLE_ENTRY (AML_DEVICE_OP, 0, NODE_AML_PACKAGE, 0),
+/* DEVICEPOLARITY_HIGH */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* DEVICEPOLARITY_LOW */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* DIVIDE */ OP_TABLE_ENTRY (AML_DIVIDE_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* DMA */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DMATYPE_A */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* DMATYPE_COMPATIBILITY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* DMATYPE_B */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* DMATYPE_F */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* DWORDCONST */ OP_TABLE_ENTRY (AML_RAW_DATA_DWORD, 0, 0, ACPI_BTYPE_INTEGER),
+/* DWORDIO */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DWORDMEMORY */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* DWORDSPACE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* EISAID */ OP_TABLE_ENTRY (AML_DWORD_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ELSE */ OP_TABLE_ENTRY (AML_ELSE_OP, 0, NODE_AML_PACKAGE, 0),
+/* ELSEIF */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, NODE_AML_PACKAGE, 0),
+/* ENDDEPENDENTFN */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* ENDIAN_BIG */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* ENDIAN_LITTLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* ENDTAG */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* ERRORNODE */ OP_TABLE_ENTRY (AML_NOOP_OP, 0, 0, 0),
+/* EVENT */ OP_TABLE_ENTRY (AML_EVENT_OP, 0, 0, 0),
+/* EXTENDEDIO */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* EXTENDEDMEMORY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* EXTENDEDSPACE */ OP_TABLE_ENTRY (AML_RAW_DATA_QWORD, 0, 0, ACPI_BTYPE_INTEGER),
+/* EXTERNAL */ OP_TABLE_ENTRY (AML_EXTERNAL_OP, 0, 0, 0),
+/* FATAL */ OP_TABLE_ENTRY (AML_FATAL_OP, 0, 0, 0),
+/* FIELD */ OP_TABLE_ENTRY (AML_FIELD_OP, 0, NODE_AML_PACKAGE, 0),
+/* FINDSETLEFTBIT */ OP_TABLE_ENTRY (AML_FIND_SET_LEFT_BIT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* FINDSETRIGHTBIT */ OP_TABLE_ENTRY (AML_FIND_SET_RIGHT_BIT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* FIXEDDMA */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* FIXEDIO */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* FLOWCONTROL_HW */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* FLOWCONTROL_NONE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* FLOWCONTROL_SW */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* FROMBCD */ OP_TABLE_ENTRY (AML_FROM_BCD_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* FUNCTION */ OP_TABLE_ENTRY (AML_METHOD_OP, 0, NODE_AML_PACKAGE, 0),
+/* GPIOINT */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* GPIOIO */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* I2CSERIALBUS */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* IF */ OP_TABLE_ENTRY (AML_IF_OP, 0, NODE_AML_PACKAGE, 0),
+/* INCLUDE */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* INCLUDE_END */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* INCREMENT */ OP_TABLE_ENTRY (AML_INCREMENT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* INDEX */ OP_TABLE_ENTRY (AML_INDEX_OP, 0, 0, ACPI_BTYPE_REFERENCE),
+/* INDEXFIELD */ OP_TABLE_ENTRY (AML_INDEX_FIELD_OP, 0, NODE_AML_PACKAGE, 0),
+/* INTEGER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* INTERRUPT */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* INTLEVEL_ACTIVEBOTH */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* INTLEVEL_ACTIVEHIGH */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* INTLEVEL_ACTIVELOW */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* INTTYPE_EDGE */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* INTTYPE_LEVEL */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* IO */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* IODECODETYPE_10 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* IODECODETYPE_16 */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* IORESTRICT_IN */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* IORESTRICT_NONE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* IORESTRICT_OUT */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* IORESTRICT_PRESERVE */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* IRQ */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* IRQNOFLAGS */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* LAND */ OP_TABLE_ENTRY (AML_LAND_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LEQUAL */ OP_TABLE_ENTRY (AML_LEQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LGREATER */ OP_TABLE_ENTRY (AML_LGREATER_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LGREATEREQUAL */ OP_TABLE_ENTRY (AML_LGREATEREQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LLESS */ OP_TABLE_ENTRY (AML_LLESS_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LLESSEQUAL */ OP_TABLE_ENTRY (AML_LLESSEQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LNOT */ OP_TABLE_ENTRY (AML_LNOT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LNOTEQUAL */ OP_TABLE_ENTRY (AML_LNOTEQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* LOAD */ OP_TABLE_ENTRY (AML_LOAD_OP, 0, 0, 0),
+/* LOADTABLE */ OP_TABLE_ENTRY (AML_LOAD_TABLE_OP, 0, 0, ACPI_BTYPE_DDB_HANDLE),
+/* LOCAL0 */ OP_TABLE_ENTRY (AML_LOCAL0, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL1 */ OP_TABLE_ENTRY (AML_LOCAL1, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL2 */ OP_TABLE_ENTRY (AML_LOCAL2, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL3 */ OP_TABLE_ENTRY (AML_LOCAL3, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL4 */ OP_TABLE_ENTRY (AML_LOCAL4, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL5 */ OP_TABLE_ENTRY (AML_LOCAL5, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL6 */ OP_TABLE_ENTRY (AML_LOCAL6, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCAL7 */ OP_TABLE_ENTRY (AML_LOCAL7, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* LOCKRULE_LOCK */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_LOCK_ALWAYS, 0, 0),
+/* LOCKRULE_NOLOCK */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_LOCK_NEVER, 0, 0),
+/* LOR */ OP_TABLE_ENTRY (AML_LOR_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* MATCH */ OP_TABLE_ENTRY (AML_MATCH_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MEQ */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MEQ, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MGE */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MGE, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MGT */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MGT, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MLE */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MLE, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MLT */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MLT, 0, ACPI_BTYPE_INTEGER),
+/* MATCHTYPE_MTR */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, MATCH_MTR, 0, ACPI_BTYPE_INTEGER),
+/* MAXTYPE_FIXED */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* MAXTYPE_NOTFIXED */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* MEMORY24 */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* MEMORY32 */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* MEMORY32FIXED */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* MEMTYPE_CACHEABLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* MEMTYPE_NONCACHEABLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* MEMTYPE_PREFETCHABLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* MEMTYPE_WRITECOMBINING */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* METHOD */ OP_TABLE_ENTRY (AML_METHOD_OP, 0, NODE_AML_PACKAGE, 0),
+/* METHODCALL */ OP_TABLE_ENTRY (AML_INT_METHODCALL_OP, 0, 0, ACPI_BTYPE_OBJECTS_AND_REFS),
+/* MID */ OP_TABLE_ENTRY (AML_MID_OP, 0, 0, ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER),
+/* MINTYPE_FIXED */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* MINTYPE_NOTFIXED */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* MOD */ OP_TABLE_ENTRY (AML_MOD_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* MULTIPLY */ OP_TABLE_ENTRY (AML_MULTIPLY_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* MUTEX */ OP_TABLE_ENTRY (AML_MUTEX_OP, 0, 0, 0),
+/* NAME */ OP_TABLE_ENTRY (AML_NAME_OP, 0, 0, 0),
+/* NAMESEG */ OP_TABLE_ENTRY (AML_INT_NAMEPATH_OP, 0, 0, 0),
+/* NAMESTRING */ OP_TABLE_ENTRY (AML_INT_NAMEPATH_OP, 0, 0, 0),
+/* NAND */ OP_TABLE_ENTRY (AML_BIT_NAND_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* NOOP */ OP_TABLE_ENTRY (AML_NOOP_OP, 0, 0, 0),
+/* NOR */ OP_TABLE_ENTRY (AML_BIT_NOR_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* NOT */ OP_TABLE_ENTRY (AML_BIT_NOT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* NOTIFY */ OP_TABLE_ENTRY (AML_NOTIFY_OP, 0, 0, 0),
+/* OBJECTTYPE */ OP_TABLE_ENTRY (AML_TYPE_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* OBJECTTYPE_BFF */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_BUFFER_FIELD, 0, 0),
+/* OBJECTTYPE_BUF */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_BUFFER, 0, 0),
+/* OBJECTTYPE_DDB */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_DDB_HANDLE, 0, 0),
+/* OBJECTTYPE_DEV */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_DEVICE, 0, 0),
+/* OBJECTTYPE_EVT */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_EVENT, 0, 0),
+/* OBJECTTYPE_FLD */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_FIELD_UNIT, 0, 0),
+/* OBJECTTYPE_INT */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_INTEGER, 0, 0),
+/* OBJECTTYPE_MTH */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_METHOD, 0, 0),
+/* OBJECTTYPE_MTX */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_MUTEX, 0, 0),
+/* OBJECTTYPE_OPR */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_REGION, 0, 0),
+/* OBJECTTYPE_PKG */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_PACKAGE, 0, 0),
+/* OBJECTTYPE_POW */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_POWER, 0, 0),
+/* OBJECTTYPE_PRO */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_PROCESSOR, 0, 0),
+/* OBJECTTYPE_STR */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_STRING, 0, 0),
+/* OBJECTTYPE_THZ */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_THERMAL, 0, 0),
+/* OBJECTTYPE_UNK */ OP_TABLE_ENTRY (AML_BYTE_OP, ACPI_TYPE_ANY, 0, 0),
+/* OFFSET */ OP_TABLE_ENTRY (AML_INT_RESERVEDFIELD_OP, 0, 0, 0),
+/* ONE */ OP_TABLE_ENTRY (AML_ONE_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ONES */ OP_TABLE_ENTRY (AML_ONES_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* OPERATIONREGION */ OP_TABLE_ENTRY (AML_REGION_OP, 0, 0, 0),
+/* OR */ OP_TABLE_ENTRY (AML_BIT_OR_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* PACKAGE */ OP_TABLE_ENTRY (AML_PACKAGE_OP, 0, NODE_AML_PACKAGE, ACPI_BTYPE_PACKAGE),
+/* PACKAGEP_LENGTH */ OP_TABLE_ENTRY (AML_PACKAGE_LENGTH, 0, NODE_AML_PACKAGE, 0),
+/* PARITYTYPE_EVEN */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* PARITYTYPE_MARK */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* PARITYTYPE_NONE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* PARITYTYPE_ODD */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* PARITYTYPE_SPACE */ OP_TABLE_ENTRY (AML_BYTE_OP, 4, 0, 0),
+/* PIN_NOPULL */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* PIN_PULLDEFAULT */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* PIN_PULLDOWN */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* PIN_PULLUP */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* POWERRESOURCE */ OP_TABLE_ENTRY (AML_POWER_RES_OP, 0, NODE_AML_PACKAGE, 0),
+/* PROCESSOR */ OP_TABLE_ENTRY (AML_PROCESSOR_OP, 0, NODE_AML_PACKAGE, 0),
+/* QWORDCONST */ OP_TABLE_ENTRY (AML_RAW_DATA_QWORD, 0, 0, ACPI_BTYPE_INTEGER),
+/* QWORDIO */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* QWORDMEMORY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* QWORDSPACE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* RANGE_TYPE_ENTIRE */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* RANGE_TYPE_ISAONLY */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* RANGE_TYPE_NONISAONLY */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* RAW_DATA */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* READWRITETYPE_BOTH */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* READWRITETYPE_READONLY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* REFOF */ OP_TABLE_ENTRY (AML_REF_OF_OP, 0, 0, ACPI_BTYPE_REFERENCE),
+/* REGIONSPACE_CMOS */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_CMOS, 0, 0),
+/* REGIONSPACE_EC */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_EC, 0, 0),
+/* REGIONSPACE_FFIXEDHW */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_FIXED_HARDWARE, 0, 0),
+/* REGIONSPACE_GPIO */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_GPIO, 0, 0),
+/* REGIONSPACE_GSBUS */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_GSBUS, 0, 0),
+/* REGIONSPACE_IO */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SYSTEM_IO, 0, 0),
+/* REGIONSPACE_IPMI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_IPMI, 0, 0),
+/* REGIONSPACE_MEM */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SYSTEM_MEMORY, 0, 0),
+/* REGIONSPACE_PCC */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PLATFORM_COMM, 0, 0),
+/* REGIONSPACE_PCI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PCI_CONFIG, 0, 0),
+/* REGIONSPACE_PCIBAR */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PCI_BAR_TARGET, 0, 0),
+/* REGIONSPACE_SMBUS */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SMBUS, 0, 0),
+/* REGISTER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* RELEASE */ OP_TABLE_ENTRY (AML_RELEASE_OP, 0, 0, 0),
+/* RESERVED_BYTES */ OP_TABLE_ENTRY (AML_INT_RESERVEDFIELD_OP, 0, 0, 0),
+/* RESET */ OP_TABLE_ENTRY (AML_RESET_OP, 0, 0, 0),
+/* RESOURCETEMPLATE */ OP_TABLE_ENTRY (AML_BUFFER_OP, 0, 0, ACPI_BTYPE_BUFFER),
+/* RESOURCETYPE_CONSUMER */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* RESOURCETYPE_PRODUCER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* RETURN */ OP_TABLE_ENTRY (AML_RETURN_OP, 0, 0, 0),
+/* REVISION */ OP_TABLE_ENTRY (AML_REVISION_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* SCOPE */ OP_TABLE_ENTRY (AML_SCOPE_OP, 0, NODE_AML_PACKAGE, 0),
+/* SERIALIZERULE_NOTSERIAL */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* SERIALIZERULE_SERIAL */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* SHARETYPE_EXCLUSIVE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* SHARETYPE_EXCLUSIVEWAKE */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* SHARETYPE_SHARED */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* SHARETYPE_SHAREDWAKE */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* SHIFTLEFT */ OP_TABLE_ENTRY (AML_SHIFT_LEFT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* SHIFTRIGHT */ OP_TABLE_ENTRY (AML_SHIFT_RIGHT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* SIGNAL */ OP_TABLE_ENTRY (AML_SIGNAL_OP, 0, 0, 0),
+/* SIZEOF */ OP_TABLE_ENTRY (AML_SIZE_OF_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* SLAVEMODE_CONTROLLERINIT */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* SLAVEMODE_DEVICEINIT */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* SLEEP */ OP_TABLE_ENTRY (AML_SLEEP_OP, 0, 0, 0),
+/* SPISERIALBUS */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* STALL */ OP_TABLE_ENTRY (AML_STALL_OP, 0, 0, 0),
+/* STARTDEPENDENTFN */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* STARTDEPENDENTFN_NOPRI */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* STOPBITS_ONE */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* STOPBITS_ONEPLUSHALF */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* STOPBITS_TWO */ OP_TABLE_ENTRY (AML_BYTE_OP, 3, 0, 0),
+/* STOPBITS_ZERO */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* STORE */ OP_TABLE_ENTRY (AML_STORE_OP, 0, 0, ACPI_BTYPE_DATA_REFERENCE),
+/* STRING_LITERAL */ OP_TABLE_ENTRY (AML_STRING_OP, 0, 0, ACPI_BTYPE_STRING),
+/* SUBTRACT */ OP_TABLE_ENTRY (AML_SUBTRACT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* SWITCH */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* THERMALZONE */ OP_TABLE_ENTRY (AML_THERMAL_ZONE_OP, 0, NODE_AML_PACKAGE, 0),
+/* TIMER */ OP_TABLE_ENTRY (AML_TIMER_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* TOBCD */ OP_TABLE_ENTRY (AML_TO_BCD_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* TOBUFFER */ OP_TABLE_ENTRY (AML_TO_BUFFER_OP, 0, 0, ACPI_BTYPE_BUFFER),
+/* TODECIMALSTRING */ OP_TABLE_ENTRY (AML_TO_DECSTRING_OP, 0, 0, ACPI_BTYPE_STRING),
+/* TOHEXSTRING */ OP_TABLE_ENTRY (AML_TO_HEXSTRING_OP, 0, 0, ACPI_BTYPE_STRING),
+/* TOINTEGER */ OP_TABLE_ENTRY (AML_TO_INTEGER_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* TOSTRING */ OP_TABLE_ENTRY (AML_TO_STRING_OP, 0, 0, ACPI_BTYPE_STRING),
+/* TOUUID */ OP_TABLE_ENTRY (AML_DWORD_OP, 0, NODE_AML_PACKAGE, ACPI_BTYPE_INTEGER),
+/* TRANSLATIONTYPE_DENSE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* TRANSLATIONTYPE_SPARSE */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* TYPE_STATIC */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* TYPE_TRANSLATION */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* UART_SERIALBUS */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
+/* UNICODE */ OP_TABLE_ENTRY (AML_BUFFER_OP, 0, NODE_AML_PACKAGE, 0),
+/* UNLOAD */ OP_TABLE_ENTRY (AML_UNLOAD_OP, 0, 0, 0),
+/* UPDATERULE_ONES */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_UPDATE_WRITE_AS_ONES, 0, 0),
+/* UPDATERULE_PRESERVE */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_UPDATE_PRESERVE, 0, 0),
+/* UPDATERULE_ZEROS */ OP_TABLE_ENTRY (AML_BYTE_OP, AML_FIELD_UPDATE_WRITE_AS_ZEROS,0, 0),
+/* VAR_PACKAGE */ OP_TABLE_ENTRY (AML_VAR_PACKAGE_OP, 0, NODE_AML_PACKAGE, ACPI_BTYPE_PACKAGE),
+/* VENDORLONG */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* VENDORSHORT */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* WAIT */ OP_TABLE_ENTRY (AML_WAIT_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* WHILE */ OP_TABLE_ENTRY (AML_WHILE_OP, 0, NODE_AML_PACKAGE, 0),
+/* WIREMODE_FOUR */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* WIREMODE_THREE */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* WORDBUSNUMBER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* WORDCONST */ OP_TABLE_ENTRY (AML_RAW_DATA_WORD, 0, 0, ACPI_BTYPE_INTEGER),
+/* WORDIO */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* WORDSPACE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_8 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_16 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_32 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_64 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_128 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERSIZE_256 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERTYPE_8 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* XFERTYPE_8_16 */ OP_TABLE_ENTRY (AML_BYTE_OP, 1, 0, 0),
+/* XFERTYPE_16 */ OP_TABLE_ENTRY (AML_BYTE_OP, 2, 0, 0),
+/* XOR */ OP_TABLE_ENTRY (AML_BIT_XOR_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* ZERO */ OP_TABLE_ENTRY (AML_ZERO_OP, 0, 0, ACPI_BTYPE_INTEGER),
+/* TOPLD */ OP_TABLE_ENTRY (AML_DWORD_OP, 0, NODE_AML_PACKAGE, ACPI_BTYPE_INTEGER),
+/* XFERSIZE_128 */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* REVISION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* IGNORECOLOR */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* RED */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* GREEN */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* BLUE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* WIDTH */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* HEIGHT */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* USERVISIBLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* DOCK */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* LID */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* PANEL */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* VERTICALPOSITION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* HORIZONTALPOSITION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* SHAPE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* GROUPORIENTATION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* GROUPTOKEN */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* GROUPPOSITION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* BAY */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* EJECTABLE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* EJECTREQUIRED */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* CABINETNUMBER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* CARDCAGENUMBER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* REFERENCE */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* ROTATION */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* ORDER */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* RESERVED */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* VERTICALOFFSET */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* HORIZONTALOFFSET */ OP_TABLE_ENTRY (AML_BYTE_OP, 0, 0, 0),
+/* PRINTF */ OP_TABLE_ENTRY (AML_STORE_OP, 0, 0, ACPI_BTYPE_DATA_REFERENCE),
+/* FPRINTF */ OP_TABLE_ENTRY (AML_STORE_OP, 0, 0, ACPI_BTYPE_DATA_REFERENCE),
+/*! [End] no source code translation !*/
+
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapenter.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapenter.c
new file mode 100644
index 0000000000..2d2b863acd
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapenter.c
@@ -0,0 +1,348 @@
+/******************************************************************************
+ *
+ * Module Name: aslmapenter - Build resource descriptor/device maps
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmapenter")
+
+/* Local prototypes */
+
+static ACPI_GPIO_INFO *
+MpCreateGpioInfo (
+ UINT16 PinNumber,
+ char *DeviceName);
+
+static ACPI_SERIAL_INFO *
+MpCreateSerialInfo (
+ char *DeviceName,
+ UINT16 Address);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpSaveGpioInfo
+ *
+ * PARAMETERS: Resource - GPIO resource descriptor
+ * PinCount - From GPIO descriptor
+ * PinList - From GPIO descriptor
+ * DeviceName - The "ResourceSource" name
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: External Interface.
+ * Save GPIO resource descriptor information.
+ * Creates new GPIO info blocks, one for each pin defined by the
+ * GPIO descriptor.
+ *
+ ******************************************************************************/
+
+void
+MpSaveGpioInfo (
+ ACPI_PARSE_OBJECT *Op,
+ AML_RESOURCE *Resource,
+ UINT32 PinCount,
+ UINT16 *PinList,
+ char *DeviceName)
+{
+ ACPI_GPIO_INFO *Info;
+ UINT32 i;
+
+
+ /* Mapfile option enabled? */
+
+ if (!Gbl_MapfileFlag)
+ {
+ return;
+ }
+
+ /* Create an info block for each pin defined in the descriptor */
+
+ for (i = 0; i < PinCount; i++)
+ {
+ Info = MpCreateGpioInfo (PinList[i], DeviceName);
+
+ Info->Op = Op;
+ Info->DeviceName = DeviceName;
+ Info->PinCount = PinCount;
+ Info->PinIndex = i;
+ Info->PinNumber = PinList[i];
+ Info->Type = Resource->Gpio.ConnectionType;
+ Info->Direction = (UINT8) (Resource->Gpio.IntFlags & 0x0003); /* _IOR, for IO descriptor */
+ Info->Polarity = (UINT8) ((Resource->Gpio.IntFlags >> 1) & 0x0003); /* _POL, for INT descriptor */
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpSaveSerialInfo
+ *
+ * PARAMETERS: Resource - A Serial resource descriptor
+ * DeviceName - The "ResourceSource" name.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: External Interface.
+ * Save serial resource descriptor information.
+ * Creates a new serial info block.
+ *
+ ******************************************************************************/
+
+void
+MpSaveSerialInfo (
+ ACPI_PARSE_OBJECT *Op,
+ AML_RESOURCE *Resource,
+ char *DeviceName)
+{
+ ACPI_SERIAL_INFO *Info;
+ UINT16 Address;
+ UINT32 Speed;
+
+
+ /* Mapfile option enabled? */
+
+ if (!Gbl_MapfileFlag)
+ {
+ return;
+ }
+
+ if (Resource->DescriptorType != ACPI_RESOURCE_NAME_SERIAL_BUS)
+ {
+ return;
+ }
+
+ /* Extract address and speed from the resource descriptor */
+
+ switch (Resource->CommonSerialBus.Type)
+ {
+ case AML_RESOURCE_I2C_SERIALBUSTYPE:
+
+ Address = Resource->I2cSerialBus.SlaveAddress;
+ Speed = Resource->I2cSerialBus.ConnectionSpeed;
+ break;
+
+ case AML_RESOURCE_SPI_SERIALBUSTYPE:
+
+ Address = Resource->SpiSerialBus.DeviceSelection;
+ Speed = Resource->SpiSerialBus.ConnectionSpeed;
+ break;
+
+ case AML_RESOURCE_UART_SERIALBUSTYPE:
+
+ Address = 0;
+ Speed = Resource->UartSerialBus.DefaultBaudRate;
+ break;
+
+ default: /* Invalid bus subtype */
+ return;
+ }
+
+ Info = MpCreateSerialInfo (DeviceName, Address);
+
+ Info->Op = Op;
+ Info->DeviceName = DeviceName;
+ Info->Resource = Resource;
+ Info->Address = Address;
+ Info->Speed = Speed;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpCreateGpioInfo
+ *
+ * PARAMETERS: PinNumber - GPIO pin number
+ * DeviceName - The "ResourceSource" name
+ *
+ * RETURN: New GPIO info block.
+ *
+ * DESCRIPTION: Create a new GPIO info block and place it on the global list.
+ * The list is sorted by GPIO device names first, and pin numbers
+ * secondarily.
+ *
+ ******************************************************************************/
+
+static ACPI_GPIO_INFO *
+MpCreateGpioInfo (
+ UINT16 PinNumber,
+ char *DeviceName)
+{
+ ACPI_GPIO_INFO *Info;
+ ACPI_GPIO_INFO *NextGpio;
+ ACPI_GPIO_INFO *PrevGpio;
+ char *Buffer;
+
+
+ /*
+ * Allocate a new info block and insert it into the global GPIO list
+ * sorted by both source device name and then the pin number. There is
+ * one block per pin.
+ */
+ Buffer = UtStringCacheCalloc (sizeof (ACPI_GPIO_INFO));
+ Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Buffer);
+
+ NextGpio = Gbl_GpioList;
+ PrevGpio = NULL;
+ if (!Gbl_GpioList)
+ {
+ Gbl_GpioList = Info;
+ Info->Next = NULL;
+ return (Info);
+ }
+
+ /* Sort on source DeviceName first */
+
+ while (NextGpio &&
+ (strcmp (DeviceName, NextGpio->DeviceName) > 0))
+ {
+ PrevGpio = NextGpio;
+ NextGpio = NextGpio->Next;
+ }
+
+ /* Now sort on the PinNumber */
+
+ while (NextGpio &&
+ (NextGpio->PinNumber < PinNumber) &&
+ !strcmp (DeviceName, NextGpio->DeviceName))
+ {
+ PrevGpio = NextGpio;
+ NextGpio = NextGpio->Next;
+ }
+
+ /* Finish the list insertion */
+
+ if (PrevGpio)
+ {
+ PrevGpio->Next = Info;
+ }
+ else
+ {
+ Gbl_GpioList = Info;
+ }
+
+ Info->Next = NextGpio;
+ return (Info);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpCreateSerialInfo
+ *
+ * PARAMETERS: DeviceName - The "ResourceSource" name.
+ * Address - Physical address for the device
+ *
+ * RETURN: New Serial info block.
+ *
+ * DESCRIPTION: Create a new Serial info block and place it on the global list.
+ * The list is sorted by Serial device names first, and addresses
+ * secondarily.
+ *
+ ******************************************************************************/
+
+static ACPI_SERIAL_INFO *
+MpCreateSerialInfo (
+ char *DeviceName,
+ UINT16 Address)
+{
+ ACPI_SERIAL_INFO *Info;
+ ACPI_SERIAL_INFO *NextSerial;
+ ACPI_SERIAL_INFO *PrevSerial;
+ char *Buffer;
+
+
+ /*
+ * Allocate a new info block and insert it into the global Serial list
+ * sorted by both source device name and then the address.
+ */
+ Buffer = UtStringCacheCalloc (sizeof (ACPI_SERIAL_INFO));
+ Info = ACPI_CAST_PTR (ACPI_SERIAL_INFO, Buffer);
+
+ NextSerial = Gbl_SerialList;
+ PrevSerial = NULL;
+ if (!Gbl_SerialList)
+ {
+ Gbl_SerialList = Info;
+ Info->Next = NULL;
+ return (Info);
+ }
+
+ /* Sort on source DeviceName */
+
+ while (NextSerial &&
+ (strcmp (DeviceName, NextSerial->DeviceName) > 0))
+ {
+ PrevSerial = NextSerial;
+ NextSerial = NextSerial->Next;
+ }
+
+ /* Now sort on the Address */
+
+ while (NextSerial &&
+ (NextSerial->Address < Address) &&
+ !strcmp (DeviceName, NextSerial->DeviceName))
+ {
+ PrevSerial = NextSerial;
+ NextSerial = NextSerial->Next;
+ }
+
+ /* Finish the list insertion */
+
+ if (PrevSerial)
+ {
+ PrevSerial->Next = Info;
+ }
+ else
+ {
+ Gbl_SerialList = Info;
+ }
+
+ Info->Next = NextSerial;
+ return (Info);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapoutput.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapoutput.c
new file mode 100644
index 0000000000..1cf1e536b7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmapoutput.c
@@ -0,0 +1,642 @@
+/******************************************************************************
+ *
+ * Module Name: aslmapoutput - Output/emit the resource descriptor/device maps
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmapoutput")
+
+/* Local prototypes */
+
+static void
+MpEmitGpioInfo (
+ void);
+
+static void
+MpEmitSerialInfo (
+ void);
+
+static void
+MpEmitDeviceTree (
+ void);
+
+static ACPI_STATUS
+MpEmitOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static void
+MpXrefDevices (
+ ACPI_GPIO_INFO *Info);
+
+static ACPI_STATUS
+MpNamespaceXrefBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+
+/* Strings used to decode flag bits */
+
+const char *DirectionDecode[] =
+{
+ "Both I/O ",
+ "InputOnly ",
+ "OutputOnly ",
+ "Preserve "
+};
+
+const char *PolarityDecode[] =
+{
+ "ActiveHigh",
+ "ActiveLow ",
+ "ActiveBoth",
+ "Reserved "
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpEmitMappingInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: External interface.
+ * Map file has already been opened. Emit all of the collected
+ * hardware mapping information. Includes: GPIO information,
+ * Serial information, and a dump of the entire ACPI device tree.
+ *
+ ******************************************************************************/
+
+void
+MpEmitMappingInfo (
+ void)
+{
+
+ /* Mapfile option enabled? */
+
+ if (!Gbl_MapfileFlag)
+ {
+ return;
+ }
+
+ if (!Gbl_GpioList)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT,
+ "\nNo GPIO devices found\n");
+ }
+
+ if (!Gbl_SerialList)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT,
+ "\nNo Serial devices found (I2C/SPI/UART)\n");
+ }
+
+ if (!Gbl_GpioList && !Gbl_SerialList)
+ {
+ return;
+ }
+
+ /* Headers */
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\nResource Descriptor Connectivity Map\n");
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "------------------------------------\n");
+
+ /* Emit GPIO and Serial descriptors, then entire ACPI device tree */
+
+ MpEmitGpioInfo ();
+ MpEmitSerialInfo ();
+ MpEmitDeviceTree ();
+
+ /* Clear the lists - no need to free memory here */
+
+ Gbl_SerialList = NULL;
+ Gbl_GpioList = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpEmitGpioInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit the info about all GPIO devices found during the
+ * compile or disassembly.
+ *
+ ******************************************************************************/
+
+static void
+MpEmitGpioInfo (
+ void)
+{
+ ACPI_GPIO_INFO *Info;
+ char *Type;
+ char *PrevDeviceName = NULL;
+ const char *Direction;
+ const char *Polarity;
+ char *ParentPathname;
+ const char *Description;
+ char *HidString;
+ const AH_DEVICE_ID *HidInfo;
+
+
+ /* Walk the GPIO descriptor list */
+
+ Info = Gbl_GpioList;
+ while (Info)
+ {
+ HidString = MpGetHidViaNamestring (Info->DeviceName);
+
+ /* Print header info for the controller itself */
+
+ if (!PrevDeviceName ||
+ strcmp (PrevDeviceName, Info->DeviceName))
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT,
+ "\n\nGPIO Controller: %-8s %-28s",
+ HidString, Info->DeviceName);
+
+ HidInfo = AcpiAhMatchHardwareId (HidString);
+ if (HidInfo)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s",
+ HidInfo->Description);
+ }
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT,
+ "\n\nPin Type Direction Polarity"
+ " Dest _HID Destination\n");
+ }
+
+ PrevDeviceName = Info->DeviceName;
+
+ /* Setup various strings based upon the type (GpioInt or GpioIo) */
+
+ switch (Info->Type)
+ {
+ case AML_RESOURCE_GPIO_TYPE_INT:
+
+ Type = "GpioInt";
+ Direction = "-Interrupt-";
+ Polarity = PolarityDecode[Info->Polarity];
+ break;
+
+ case AML_RESOURCE_GPIO_TYPE_IO:
+
+ Type = "GpioIo ";
+ Direction = DirectionDecode[Info->Direction];
+ Polarity = " ";
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Emit the GPIO info */
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%4.4X %s %s %s ",
+ Info->PinNumber, Type, Direction, Polarity);
+
+ ParentPathname = NULL;
+ HidString = MpGetConnectionInfo (Info->Op, Info->PinIndex,
+ &Info->TargetNode, &ParentPathname);
+ if (HidString)
+ {
+ /*
+ * This is a Connection() field
+ * Attempt to find all references to the field.
+ */
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s",
+ HidString, ParentPathname);
+
+ MpXrefDevices (Info);
+ }
+ else
+ {
+ /*
+ * For Devices, attempt to get the _HID description string.
+ * Failing that (many _HIDs are not recognized), attempt to
+ * get the _DDN description string.
+ */
+ HidString = MpGetParentDeviceHid (Info->Op, &Info->TargetNode,
+ &ParentPathname);
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s",
+ HidString, ParentPathname);
+
+ /* Get the _HID description or _DDN string */
+
+ HidInfo = AcpiAhMatchHardwareId (HidString);
+ if (HidInfo)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s",
+ HidInfo->Description);
+ }
+ else if ((Description = MpGetDdnValue (ParentPathname)))
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)",
+ Description);
+ }
+ }
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n");
+ ACPI_FREE (ParentPathname);
+ Info = Info->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpEmitSerialInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit the info about all Serial devices found during the
+ * compile or disassembly.
+ *
+ ******************************************************************************/
+
+static void
+MpEmitSerialInfo (
+ void)
+{
+ ACPI_SERIAL_INFO *Info;
+ char *Type;
+ char *ParentPathname;
+ char *PrevDeviceName = NULL;
+ char *HidString;
+ const AH_DEVICE_ID *HidInfo;
+ const char *Description;
+ AML_RESOURCE *Resource;
+
+
+ /* Walk the constructed serial descriptor list */
+
+ Info = Gbl_SerialList;
+ while (Info)
+ {
+ Resource = Info->Resource;
+ switch (Resource->CommonSerialBus.Type)
+ {
+ case AML_RESOURCE_I2C_SERIALBUSTYPE:
+ Type = "I2C ";
+ break;
+
+ case AML_RESOURCE_SPI_SERIALBUSTYPE:
+ Type = "SPI ";
+ break;
+
+ case AML_RESOURCE_UART_SERIALBUSTYPE:
+ Type = "UART";
+ break;
+
+ default:
+ Type = "UNKN";
+ break;
+ }
+
+ HidString = MpGetHidViaNamestring (Info->DeviceName);
+
+ /* Print header info for the controller itself */
+
+ if (!PrevDeviceName ||
+ strcmp (PrevDeviceName, Info->DeviceName))
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\n%s Controller: ",
+ Type);
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%-8s %-28s",
+ HidString, Info->DeviceName);
+
+ HidInfo = AcpiAhMatchHardwareId (HidString);
+ if (HidInfo)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s",
+ HidInfo->Description);
+ }
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\n");
+ FlPrintFile (ASL_FILE_MAP_OUTPUT,
+ "Type Address Speed Dest _HID Destination\n");
+ }
+
+ PrevDeviceName = Info->DeviceName;
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%s %4.4X %8.8X ",
+ Type, Info->Address, Info->Speed);
+
+ ParentPathname = NULL;
+ HidString = MpGetConnectionInfo (Info->Op, 0, &Info->TargetNode,
+ &ParentPathname);
+ if (HidString)
+ {
+ /*
+ * This is a Connection() field
+ * Attempt to find all references to the field.
+ */
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s",
+ HidString, ParentPathname);
+ }
+ else
+ {
+ /* Normal resource template */
+
+ HidString = MpGetParentDeviceHid (Info->Op, &Info->TargetNode,
+ &ParentPathname);
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s",
+ HidString, ParentPathname);
+
+ /* Get the _HID description or _DDN string */
+
+ HidInfo = AcpiAhMatchHardwareId (HidString);
+ if (HidInfo)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s",
+ HidInfo->Description);
+ }
+ else if ((Description = MpGetDdnValue (ParentPathname)))
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)",
+ Description);
+ }
+ }
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n");
+ ACPI_FREE (ParentPathname);
+ Info = Info->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpEmitDeviceTree
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit information about all devices within the ACPI namespace.
+ *
+ ******************************************************************************/
+
+static void
+MpEmitDeviceTree (
+ void)
+{
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\nACPI Device Tree\n");
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "----------------\n\n");
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "Device Pathname "
+ "_HID Description\n\n");
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, MpEmitOneDevice, NULL, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpEmitOneDevice
+ *
+ * PARAMETERS: ACPI_NAMESPACE_WALK callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Emit information about one ACPI device in the namespace. Used
+ * during dump of all device objects within the namespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+MpEmitOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ char *DevicePathname;
+ char *DdnString;
+ char *HidString;
+ const AH_DEVICE_ID *HidInfo;
+
+
+ /* Device pathname */
+
+ DevicePathname = AcpiNsGetExternalPathname (
+ ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle));
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%-32s", DevicePathname);
+
+ /* _HID or _DDN */
+
+ HidString = MpGetHidValue (
+ ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle));
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s", HidString);
+
+ HidInfo = AcpiAhMatchHardwareId (HidString);
+ if (HidInfo)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s",
+ HidInfo->Description);
+ }
+ else if ((DdnString = MpGetDdnValue (DevicePathname)))
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)", DdnString);
+ }
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n");
+ ACPI_FREE (DevicePathname);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpXrefDevices
+ *
+ * PARAMETERS: Info - A GPIO Info block
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Cross-reference the parse tree and find all references to the
+ * specified GPIO device.
+ *
+ ******************************************************************************/
+
+static void
+MpXrefDevices (
+ ACPI_GPIO_INFO *Info)
+{
+
+ /* Walk the entire parse tree */
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ MpNamespaceXrefBegin, NULL, Info);
+
+ if (!Info->References)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // **** No references in table");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpNamespaceXrefBegin
+ *
+ * PARAMETERS: WALK_PARSE_TREE callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk parse tree callback used to cross-reference GPIO pins.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+MpNamespaceXrefBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_GPIO_INFO *Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Context);
+ const ACPI_OPCODE_INFO *OpInfo;
+ char *DevicePathname;
+ ACPI_PARSE_OBJECT *ParentOp;
+ char *HidString;
+
+
+ ACPI_FUNCTION_TRACE_PTR (MpNamespaceXrefBegin, Op);
+
+ /*
+ * If this node is the actual declaration of a name
+ * [such as the XXXX name in "Method (XXXX)"],
+ * we are not interested in it here. We only care about names that
+ * are references to other objects within the namespace and the
+ * parent objects of name declarations
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
+ {
+ return (AE_OK);
+ }
+
+ /* We are only interested in opcodes that have an associated name */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+
+ if ((OpInfo->Flags & AML_NAMED) ||
+ (OpInfo->Flags & AML_CREATE))
+ {
+ return (AE_OK);
+ }
+
+ if ((Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
+ (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
+ (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
+ {
+ return (AE_OK);
+ }
+
+ if (!Op->Asl.Node)
+ {
+ return (AE_OK);
+ }
+
+ ParentOp = Op->Asl.Parent;
+ if (ParentOp->Asl.ParseOpcode == PARSEOP_FIELD)
+ {
+ return (AE_OK);
+ }
+
+ if (Op->Asl.Node == Info->TargetNode)
+ {
+ while (ParentOp && (!ParentOp->Asl.Node))
+ {
+ ParentOp = ParentOp->Asl.Parent;
+ }
+
+ if (ParentOp)
+ {
+ DevicePathname = AcpiNsGetExternalPathname (
+ ParentOp->Asl.Node);
+
+ if (!Info->References)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " // References:");
+ }
+
+ HidString = MpGetHidViaNamestring (DevicePathname);
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " %s [%s]",
+ DevicePathname, HidString);
+
+ Info->References++;
+
+ ACPI_FREE (DevicePathname);
+ }
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmaputils.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmaputils.c
new file mode 100644
index 0000000000..7b2e61185b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmaputils.c
@@ -0,0 +1,402 @@
+/******************************************************************************
+ *
+ * Module Name: aslmaputils - Utilities for the resource descriptor/device maps
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+/* This module used for application-level code only */
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmaputils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetHidFromParseTree
+ *
+ * PARAMETERS: HidNode - Node for a _HID object
+ *
+ * RETURN: An _HID string value. Automatically converts _HID integers
+ * to strings. Never NULL.
+ *
+ * DESCRIPTION: Extract a _HID value from the parse tree, not the namespace.
+ * Used when a fully initialized namespace is not available.
+ *
+ ******************************************************************************/
+
+char *
+MpGetHidFromParseTree (
+ ACPI_NAMESPACE_NODE *HidNode)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_PARSE_OBJECT *Arg;
+ char *HidString;
+
+
+ Op = HidNode->Op;
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_NAME:
+
+ Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */
+ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */
+
+ switch (Arg->Asl.ParseOpcode)
+ {
+ case PARSEOP_STRING_LITERAL:
+
+ return (Arg->Asl.Value.String);
+
+ case PARSEOP_INTEGER:
+
+ /* Convert EISAID to a string */
+
+ HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
+ AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer);
+ return (HidString);
+
+ default:
+
+ return ("UNKNOWN");
+ }
+
+ default:
+ return ("-No HID-");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetHidValue
+ *
+ * PARAMETERS: DeviceNode - Node for parent device
+ *
+ * RETURN: An _HID string value. Automatically converts _HID integers
+ * to strings. Never NULL.
+ *
+ * DESCRIPTION: Extract _HID value from within a device scope. Does not
+ * actually execute a method, just gets the string or integer
+ * value for the _HID.
+ *
+ ******************************************************************************/
+
+char *
+MpGetHidValue (
+ ACPI_NAMESPACE_NODE *DeviceNode)
+{
+ ACPI_NAMESPACE_NODE *HidNode;
+ char *HidString;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__HID,
+ ACPI_NS_NO_UPSEARCH, &HidNode);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* If only partial namespace, get the _HID from the parse tree */
+
+ if (!HidNode->Object)
+ {
+ return (MpGetHidFromParseTree (HidNode));
+ }
+
+ /* Handle the different _HID flavors */
+
+ switch (HidNode->Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ return (HidNode->Object->String.Pointer);
+
+ case ACPI_TYPE_INTEGER:
+
+ /* Convert EISAID to a string */
+
+ HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
+ AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value);
+ return (HidString);
+
+ case ACPI_TYPE_METHOD:
+
+ return ("-Method-");
+
+ default:
+
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, "BAD HID TYPE: %u", HidNode->Type);
+ break;
+ }
+
+
+ErrorExit:
+ return ("-No HID-");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetHidViaNamestring
+ *
+ * PARAMETERS: DeviceName - Namepath for parent device
+ *
+ * RETURN: _HID string. Never NULL.
+ *
+ * DESCRIPTION: Get a _HID value via a device pathname (instead of just simply
+ * a device node.)
+ *
+ ******************************************************************************/
+
+char *
+MpGetHidViaNamestring (
+ char *DeviceName)
+{
+ ACPI_NAMESPACE_NODE *DeviceNode;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
+ &DeviceNode);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ return (MpGetHidValue (DeviceNode));
+
+
+ErrorExit:
+ return ("-No HID-");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetParentDeviceHid
+ *
+ * PARAMETERS: Op - Parse Op to be examined
+ * TargetNode - Where the field node is returned
+ * ParentDeviceName - Where the node path is returned
+ *
+ * RETURN: _HID string. Never NULL.
+ *
+ * DESCRIPTION: Find the parent Device or Scope Op, get the full pathname to
+ * the parent, and get the _HID associated with the parent.
+ *
+ ******************************************************************************/
+
+char *
+MpGetParentDeviceHid (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE **TargetNode,
+ char **ParentDeviceName)
+{
+ ACPI_NAMESPACE_NODE *DeviceNode;
+
+
+ /* Find parent Device() or Scope() Op */
+
+ while (Op &&
+ (Op->Asl.AmlOpcode != AML_DEVICE_OP) &&
+ (Op->Asl.AmlOpcode != AML_SCOPE_OP))
+ {
+ Op = Op->Asl.Parent;
+ }
+
+ if (!Op)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device ");
+ goto ErrorExit;
+ }
+
+ /* Get the full pathname to the device and the _HID */
+
+ DeviceNode = Op->Asl.Node;
+ if (!DeviceNode)
+ {
+ FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node ");
+ goto ErrorExit;
+ }
+
+ *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode);
+ return (MpGetHidValue (DeviceNode));
+
+
+ErrorExit:
+ return ("-No HID-");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetDdnValue
+ *
+ * PARAMETERS: DeviceName - Namepath for parent device
+ *
+ * RETURN: _DDN description string. NULL on failure.
+ *
+ * DESCRIPTION: Execute the _DDN method for the device.
+ *
+ ******************************************************************************/
+
+char *
+MpGetDdnValue (
+ char *DeviceName)
+{
+ ACPI_NAMESPACE_NODE *DeviceNode;
+ ACPI_NAMESPACE_NODE *DdnNode;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
+ &DeviceNode);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__DDN, ACPI_NS_NO_UPSEARCH,
+ &DdnNode);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ if ((DdnNode->Type != ACPI_TYPE_STRING) ||
+ !DdnNode->Object)
+ {
+ goto ErrorExit;
+ }
+
+ return (DdnNode->Object->String.Pointer);
+
+
+ErrorExit:
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MpGetConnectionInfo
+ *
+ * PARAMETERS: Op - Parse Op to be examined
+ * PinIndex - Index into GPIO PinList
+ * TargetNode - Where the field node is returned
+ * TargetName - Where the node path is returned
+ *
+ * RETURN: A substitute _HID string, indicating that the name is actually
+ * a field. NULL if the Op does not refer to a Connection.
+ *
+ * DESCRIPTION: Get the Field Unit that corresponds to the PinIndex after
+ * a Connection() invocation.
+ *
+ ******************************************************************************/
+
+char *
+MpGetConnectionInfo (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 PinIndex,
+ ACPI_NAMESPACE_NODE **TargetNode,
+ char **TargetName)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /*
+ * Handle Connection() here. Find the next named FieldUnit.
+ * Note: we look at the ParseOpcode for the compiler, look
+ * at the AmlOpcode for the disassembler.
+ */
+ if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) ||
+ (Op->Asl.ParseOpcode == PARSEOP_CONNECTION))
+ {
+ /* Find the correct field unit definition */
+
+ NextOp = Op;
+ for (i = 0; i <= PinIndex;)
+ {
+ NextOp = NextOp->Asl.Next;
+ while (NextOp &&
+ (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
+ (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP))
+ {
+ NextOp = NextOp->Asl.Next;
+ }
+
+ if (!NextOp)
+ {
+ return ("UNKNOWN");
+ }
+
+ /* Add length of this field to the current pin index */
+
+ if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
+ {
+ i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer;
+ }
+ else /* AML_INT_NAMEDFIELD_OP */
+ {
+ i += (UINT32) NextOp->Asl.Value.Integer;
+ }
+ }
+
+ /* Return the node and pathname for the field unit */
+
+ *TargetNode = NextOp->Asl.Node;
+ *TargetName = AcpiNsGetExternalPathname (*TargetNode);
+ return ("-Field-");
+ }
+
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.c
new file mode 100644
index 0000000000..cf09d7de2f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.c
@@ -0,0 +1,414 @@
+/******************************************************************************
+ *
+ * Module Name: aslmessages.c - Compiler error/warning message strings
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmessages")
+
+
+/*
+ * Strings for message reporting levels, must match error
+ * type string tables in aslmessages.c
+ */
+const char *AslErrorLevel [ASL_NUM_REPORT_LEVELS] = {
+ "Optimize",
+ "Remark ",
+ "Warning ",
+ "Warning ",
+ "Warning ",
+ "Error "
+};
+
+/* All lowercase versions for IDEs */
+
+const char *AslErrorLevelIde [ASL_NUM_REPORT_LEVELS] = {
+ "optimize",
+ "remark ",
+ "warning ",
+ "warning ",
+ "warning ",
+ "error "
+};
+
+
+/*
+ * Actual message strings for each compiler message ID. There are currently
+ * three distinct blocks of error messages (so that they can be expanded
+ * individually):
+ * Main ASL compiler
+ * Data Table compiler
+ * Preprocessor
+ *
+ * NOTE1: These tables must match the enum list of message IDs in the file
+ * aslmessages.h exactly.
+ *
+ * NOTE2: With the introduction of the -vw option to disable specific messages,
+ * new messages should only be added to the end of this list, so that values
+ * for existing messages are not disturbed.
+ */
+
+/* ASL compiler */
+
+const char *AslCompilerMsgs [] =
+{
+/* The zeroth message is reserved */ "",
+/* ASL_MSG_ALIGNMENT */ "Must be a multiple of alignment/granularity value",
+/* ASL_MSG_ALPHANUMERIC_STRING */ "String must be entirely alphanumeric",
+/* ASL_MSG_AML_NOT_IMPLEMENTED */ "Opcode is not implemented in compiler AML code generator",
+/* ASL_MSG_ARG_COUNT_HI */ "Too many arguments",
+/* ASL_MSG_ARG_COUNT_LO */ "Too few arguments",
+/* ASL_MSG_ARG_INIT */ "Method argument is not initialized",
+/* ASL_MSG_BACKWARDS_OFFSET */ "Invalid backwards offset",
+/* ASL_MSG_BUFFER_LENGTH */ "Effective AML buffer length is zero",
+/* ASL_MSG_CLOSE */ "Could not close file",
+/* ASL_MSG_COMPILER_INTERNAL */ "Internal compiler error",
+/* ASL_MSG_COMPILER_RESERVED */ "Use of compiler reserved name",
+/* ASL_MSG_CONNECTION_MISSING */ "A Connection operator is required for this field SpaceId",
+/* ASL_MSG_CONNECTION_INVALID */ "Invalid OpRegion SpaceId for use of Connection operator",
+/* ASL_MSG_CONSTANT_EVALUATION */ "Could not evaluate constant expression",
+/* ASL_MSG_CONSTANT_FOLDED */ "Constant expression evaluated and reduced",
+/* ASL_MSG_CORE_EXCEPTION */ "From ACPICA Subsystem",
+/* ASL_MSG_DEBUG_FILE_OPEN */ "Could not open debug file",
+/* ASL_MSG_DEBUG_FILENAME */ "Could not create debug filename",
+/* ASL_MSG_DEPENDENT_NESTING */ "Dependent function macros cannot be nested",
+/* ASL_MSG_DMA_CHANNEL */ "Invalid DMA channel (must be 0-7)",
+/* ASL_MSG_DMA_LIST */ "Too many DMA channels (8 max)",
+/* ASL_MSG_DUPLICATE_CASE */ "Case value already specified",
+/* ASL_MSG_DUPLICATE_ITEM */ "Duplicate value in list",
+/* ASL_MSG_EARLY_EOF */ "Premature end-of-file reached",
+/* ASL_MSG_ENCODING_LENGTH */ "Package length too long to encode",
+/* ASL_MSG_EX_INTERRUPT_LIST */ "Too many interrupts (255 max)",
+/* ASL_MSG_EX_INTERRUPT_LIST_MIN */ "Too few interrupts (1 minimum required)",
+/* ASL_MSG_EX_INTERRUPT_NUMBER */ "Invalid interrupt number (must be 32 bits)",
+/* ASL_MSG_FIELD_ACCESS_WIDTH */ "Access width is greater than region size",
+/* ASL_MSG_FIELD_UNIT_ACCESS_WIDTH */ "Access width of Field Unit extends beyond region limit",
+/* ASL_MSG_FIELD_UNIT_OFFSET */ "Field Unit extends beyond region limit",
+/* ASL_MSG_GPE_NAME_CONFLICT */ "Name conflicts with a previous GPE method",
+/* ASL_MSG_HID_LENGTH */ "_HID string must be exactly 7 or 8 characters",
+/* ASL_MSG_HID_PREFIX */ "_HID prefix must be all uppercase or decimal digits",
+/* ASL_MSG_HID_SUFFIX */ "_HID suffix must be all hex digits",
+/* ASL_MSG_INCLUDE_FILE_OPEN */ "Could not open include file",
+/* ASL_MSG_INPUT_FILE_OPEN */ "Could not open input file",
+/* ASL_MSG_INTEGER_LENGTH */ "64-bit integer in 32-bit table, truncating (DSDT version < 2)",
+/* ASL_MSG_INTEGER_OPTIMIZATION */ "Integer optimized to single-byte AML opcode",
+/* ASL_MSG_INTERRUPT_LIST */ "Too many interrupts (16 max)",
+/* ASL_MSG_INTERRUPT_NUMBER */ "Invalid interrupt number (must be 0-15)",
+/* ASL_MSG_INVALID_ACCESS_SIZE */ "Invalid AccessSize (Maximum is 4 - QWord access)",
+/* ASL_MSG_INVALID_ADDR_FLAGS */ "Invalid combination of Length and Min/Max fixed flags",
+/* ASL_MSG_INVALID_CONSTANT_OP */ "Invalid operator in constant expression (not type 3/4/5)",
+/* ASL_MSG_INVALID_EISAID */ "EISAID string must be of the form \"UUUXXXX\" (3 uppercase, 4 hex digits)",
+/* ASL_MSG_INVALID_ESCAPE */ "Invalid or unknown escape sequence",
+/* ASL_MSG_INVALID_GRAN_FIXED */ "Granularity must be zero for fixed Min/Max",
+/* ASL_MSG_INVALID_GRANULARITY */ "Granularity must be zero or a power of two minus one",
+/* ASL_MSG_INVALID_LENGTH */ "Length is larger than Min/Max window",
+/* ASL_MSG_INVALID_LENGTH_FIXED */ "Length is not equal to fixed Min/Max window",
+/* ASL_MSG_INVALID_MIN_MAX */ "Address Min is greater than Address Max",
+/* ASL_MSG_INVALID_OPERAND */ "Invalid operand",
+/* ASL_MSG_INVALID_PERFORMANCE */ "Invalid performance/robustness value",
+/* ASL_MSG_INVALID_PRIORITY */ "Invalid priority value",
+/* ASL_MSG_INVALID_STRING */ "Invalid Hex/Octal Escape - Non-ASCII or NULL",
+/* ASL_MSG_INVALID_TARGET */ "Target operand not allowed in constant expression",
+/* ASL_MSG_INVALID_TIME */ "Time parameter too long (255 max)",
+/* ASL_MSG_INVALID_TYPE */ "Invalid type",
+/* ASL_MSG_INVALID_UUID */ "UUID string must be of the form \"aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\"",
+/* ASL_MSG_ISA_ADDRESS */ "Maximum 10-bit ISA address (0x3FF)",
+/* ASL_MSG_LEADING_ASTERISK */ "Invalid leading asterisk",
+/* ASL_MSG_LIST_LENGTH_LONG */ "Initializer list longer than declared package length",
+/* ASL_MSG_LIST_LENGTH_SHORT */ "Initializer list shorter than declared package length",
+/* ASL_MSG_LISTING_FILE_OPEN */ "Could not open listing file",
+/* ASL_MSG_LISTING_FILENAME */ "Could not create listing filename",
+/* ASL_MSG_LOCAL_INIT */ "Method local variable is not initialized",
+/* ASL_MSG_LOCAL_OUTSIDE_METHOD */ "Local or Arg used outside a control method",
+/* ASL_MSG_LONG_LINE */ "Splitting long input line",
+/* ASL_MSG_MEMORY_ALLOCATION */ "Memory allocation failure",
+/* ASL_MSG_MISSING_ENDDEPENDENT */ "Missing EndDependentFn() macro in dependent resource list",
+/* ASL_MSG_MISSING_STARTDEPENDENT */ "Missing StartDependentFn() macro in dependent resource list",
+/* ASL_MSG_MULTIPLE_DEFAULT */ "More than one Default statement within Switch construct",
+/* ASL_MSG_MULTIPLE_TYPES */ "Multiple types",
+/* ASL_MSG_NAME_EXISTS */ "Name already exists in scope",
+/* ASL_MSG_NAME_OPTIMIZATION */ "NamePath optimized",
+/* ASL_MSG_NAMED_OBJECT_IN_WHILE */ "Creating a named object in a While loop",
+/* ASL_MSG_NESTED_COMMENT */ "Nested comment found",
+/* ASL_MSG_NO_CASES */ "No Case statements under Switch",
+/* ASL_MSG_NO_REGION */ "_REG has no corresponding Operation Region",
+/* ASL_MSG_NO_RETVAL */ "Called method returns no value",
+/* ASL_MSG_NO_WHILE */ "No enclosing While statement",
+/* ASL_MSG_NON_ASCII */ "Invalid characters found in file",
+/* ASL_MSG_NON_ZERO */ "Operand evaluates to zero",
+/* ASL_MSG_NOT_EXIST */ "Object does not exist",
+/* ASL_MSG_NOT_FOUND */ "Object not found or not accessible from scope",
+/* ASL_MSG_NOT_METHOD */ "Not a control method, cannot invoke",
+/* ASL_MSG_NOT_PARAMETER */ "Not a parameter, used as local only",
+/* ASL_MSG_NOT_REACHABLE */ "Object is not accessible from this scope",
+/* ASL_MSG_NOT_REFERENCED */ "Object is not referenced",
+/* ASL_MSG_NULL_DESCRIPTOR */ "Min/Max/Length/Gran are all zero, but no resource tag",
+/* ASL_MSG_NULL_STRING */ "Invalid zero-length (null) string",
+/* ASL_MSG_OPEN */ "Could not open file",
+/* ASL_MSG_OUTPUT_FILE_OPEN */ "Could not open output AML file",
+/* ASL_MSG_OUTPUT_FILENAME */ "Could not create output filename",
+/* ASL_MSG_PACKAGE_LENGTH */ "Effective AML package length is zero",
+/* ASL_MSG_PREPROCESSOR_FILENAME */ "Could not create preprocessor filename",
+/* ASL_MSG_READ */ "Could not read file",
+/* ASL_MSG_RECURSION */ "Recursive method call",
+/* ASL_MSG_REGION_BUFFER_ACCESS */ "Host Operation Region requires BufferAcc access",
+/* ASL_MSG_REGION_BYTE_ACCESS */ "Host Operation Region requires ByteAcc access",
+/* ASL_MSG_RESERVED_ARG_COUNT_HI */ "Reserved method has too many arguments",
+/* ASL_MSG_RESERVED_ARG_COUNT_LO */ "Reserved method has too few arguments",
+/* ASL_MSG_RESERVED_METHOD */ "Reserved name must be a control method",
+/* ASL_MSG_RESERVED_NO_RETURN_VAL */ "Reserved method should not return a value",
+/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name",
+/* ASL_MSG_RESERVED_PACKAGE_LENGTH */ "Invalid package length for reserved name",
+/* ASL_MSG_RESERVED_RETURN_VALUE */ "Reserved method must return a value",
+/* ASL_MSG_RESERVED_USE */ "Invalid use of reserved name",
+/* ASL_MSG_RESERVED_WORD */ "Use of reserved name",
+/* ASL_MSG_RESOURCE_FIELD */ "Resource field name cannot be used as a target",
+/* ASL_MSG_RESOURCE_INDEX */ "Missing ResourceSourceIndex (required)",
+/* ASL_MSG_RESOURCE_LIST */ "Too many resource items (internal error)",
+/* ASL_MSG_RESOURCE_SOURCE */ "Missing ResourceSource string (required)",
+/* ASL_MSG_RESULT_NOT_USED */ "Result is not used, operator has no effect",
+/* ASL_MSG_RETURN_TYPES */ "Not all control paths return a value",
+/* ASL_MSG_SCOPE_FWD_REF */ "Forward references from Scope operator not allowed",
+/* ASL_MSG_SCOPE_TYPE */ "Existing object has invalid type for Scope operator",
+/* ASL_MSG_SEEK */ "Could not seek file",
+/* ASL_MSG_SERIALIZED */ "Control Method marked Serialized",
+/* ASL_MSG_SERIALIZED_REQUIRED */ "Control Method should be made Serialized",
+/* ASL_MSG_SINGLE_NAME_OPTIMIZATION */ "NamePath optimized to NameSeg (uses run-time search path)",
+/* ASL_MSG_SOME_NO_RETVAL */ "Called method may not always return a value",
+/* ASL_MSG_STRING_LENGTH */ "String literal too long",
+/* ASL_MSG_SWITCH_TYPE */ "Switch expression is not a static Integer/Buffer/String data type, defaulting to Integer",
+/* ASL_MSG_SYNC_LEVEL */ "SyncLevel must be in the range 0-15",
+/* ASL_MSG_SYNTAX */ "",
+/* ASL_MSG_TABLE_SIGNATURE */ "Invalid Table Signature",
+/* ASL_MSG_TAG_LARGER */ "ResourceTag larger than Field",
+/* ASL_MSG_TAG_SMALLER */ "ResourceTag smaller than Field",
+/* ASL_MSG_TIMEOUT */ "Result is not used, possible operator timeout will be missed",
+/* ASL_MSG_TOO_MANY_TEMPS */ "Method requires too many temporary variables (_T_x)",
+/* ASL_MSG_TRUNCATION */ "64-bit return value will be truncated to 32 bits (DSDT version < 2)",
+/* ASL_MSG_UNKNOWN_RESERVED_NAME */ "Unknown reserved name",
+/* ASL_MSG_UNREACHABLE_CODE */ "Statement is unreachable",
+/* ASL_MSG_UNSUPPORTED */ "Unsupported feature",
+/* ASL_MSG_UPPER_CASE */ "Non-hex letters must be upper case",
+/* ASL_MSG_VENDOR_LIST */ "Too many vendor data bytes (7 max)",
+/* ASL_MSG_WRITE */ "Could not write file",
+/* ASL_MSG_RANGE */ "Constant out of range",
+/* ASL_MSG_BUFFER_ALLOCATION */ "Could not allocate line buffer",
+/* ASL_MSG_MISSING_DEPENDENCY */ "Missing dependency",
+/* ASL_MSG_ILLEGAL_FORWARD_REF */ "Illegal forward reference within a method",
+/* ASL_MSG_ILLEGAL_METHOD_REF */ "Illegal reference across two methods",
+/* ASL_MSG_LOCAL_NOT_USED */ "Method Local is set but never used",
+/* ASL_MSG_ARG_AS_LOCAL_NOT_USED */ "Method Argument (as a local) is set but never used",
+/* ASL_MSG_ARG_NOT_USED */ "Method Argument is never used"
+
+};
+
+/* Table compiler */
+
+const char *AslTableCompilerMsgs [] =
+{
+/* ASL_MSG_BUFFER_ELEMENT */ "Invalid element in buffer initializer list",
+/* ASL_MSG_DIVIDE_BY_ZERO */ "Expression contains divide-by-zero",
+/* ASL_MSG_FLAG_VALUE */ "Flag value is too large",
+/* ASL_MSG_INTEGER_SIZE */ "Integer too large for target",
+/* ASL_MSG_INVALID_EXPRESSION */ "Invalid expression",
+/* ASL_MSG_INVALID_FIELD_NAME */ "Invalid Field Name",
+/* ASL_MSG_INVALID_HEX_INTEGER */ "Invalid hex integer constant",
+/* ASL_MSG_OEM_TABLE */ "OEM table - unknown contents",
+/* ASL_MSG_RESERVED_VALUE */ "Reserved field",
+/* ASL_MSG_UNKNOWN_LABEL */ "Label is undefined",
+/* ASL_MSG_UNKNOWN_SUBTABLE */ "Unknown subtable type",
+/* ASL_MSG_UNKNOWN_TABLE */ "Unknown ACPI table signature",
+/* ASL_MSG_ZERO_VALUE */ "Value must be non-zero"
+};
+
+/* Preprocessor */
+
+const char *AslPreprocessorMsgs [] =
+{
+/* ASL_MSG_DIRECTIVE_SYNTAX */ "Invalid directive syntax",
+/* ASL_MSG_ENDIF_MISMATCH */ "Mismatched #endif",
+/* ASL_MSG_ERROR_DIRECTIVE */ "#error",
+/* ASL_MSG_EXISTING_NAME */ "Name is already defined",
+/* ASL_MSG_INVALID_INVOCATION */ "Invalid macro invocation",
+/* ASL_MSG_MACRO_SYNTAX */ "Invalid macro syntax",
+/* ASL_MSG_TOO_MANY_ARGUMENTS */ "Too many macro arguments",
+/* ASL_MSG_UNKNOWN_DIRECTIVE */ "Unknown directive",
+/* ASL_MSG_UNKNOWN_PRAGMA */ "Unknown pragma",
+/* ASL_MSG_WARNING_DIRECTIVE */ "#warning",
+/* ASL_MSG_INCLUDE_FILE */ "Found a # preprocessor directive in ASL Include() file"
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeDecodeMessageId
+ *
+ * PARAMETERS: MessageId - ASL message ID (exception code) to be
+ * formatted. Possibly fully encoded.
+ *
+ * RETURN: A string containing the exception message text.
+ *
+ * DESCRIPTION: This function validates and translates an ASL message ID into
+ * an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+AeDecodeMessageId (
+ UINT16 MessageId)
+{
+ UINT32 Index;
+ const char **MessageTable;
+
+
+ /* Main ASL Compiler messages */
+
+ if (MessageId <= ASL_MSG_MAIN_COMPILER_END)
+ {
+ MessageTable = AslCompilerMsgs;
+ Index = MessageId;
+
+ if (Index >= ACPI_ARRAY_LENGTH (AslCompilerMsgs))
+ {
+ return ("[Unknown ASL Compiler exception ID]");
+ }
+ }
+
+ /* Data Table Compiler messages */
+
+ else if (MessageId <= ASL_MSG_TABLE_COMPILER_END)
+ {
+ MessageTable = AslTableCompilerMsgs;
+ Index = MessageId - ASL_MSG_TABLE_COMPILER;
+
+ if (Index >= ACPI_ARRAY_LENGTH (AslTableCompilerMsgs))
+ {
+ return ("[Unknown Table Compiler exception ID]");
+ }
+ }
+
+ /* Preprocessor messages */
+
+ else if (MessageId <= ASL_MSG_PREPROCESSOR_END)
+ {
+ MessageTable = AslPreprocessorMsgs;
+ Index = MessageId - ASL_MSG_PREPROCESSOR;
+
+ if (Index >= ACPI_ARRAY_LENGTH (AslPreprocessorMsgs))
+ {
+ return ("[Unknown Preprocessor exception ID]");
+ }
+ }
+
+ /* Everything else is unknown */
+
+ else
+ {
+ return ("[Unknown exception/component ID]");
+ }
+
+ return (MessageTable[Index]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeDecodeExceptionLevel
+ *
+ * PARAMETERS: Level - The ASL error level to be decoded
+ *
+ * RETURN: A string containing the error level text
+ *
+ * DESCRIPTION: This function validates and translates an ASL error level into
+ * an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+AeDecodeExceptionLevel (
+ UINT8 Level)
+{
+ /* Range check on Level */
+
+ if (Level >= ACPI_ARRAY_LENGTH (AslErrorLevel))
+ {
+ return ("Unknown exception level");
+ }
+
+ /* Differentiate the string type to be used (IDE is all lower case) */
+
+ if (Gbl_VerboseErrors)
+ {
+ return (AslErrorLevel[Level]);
+ }
+
+ return (AslErrorLevelIde[Level]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeBuildFullExceptionCode
+ *
+ * PARAMETERS: Level - ASL error level
+ * MessageId - ASL exception code to be formatted
+ *
+ * RETURN: Fully encoded exception code
+ *
+ * DESCRIPTION: Build the full exception code from the error level and the
+ * actual message ID.
+ *
+ ******************************************************************************/
+
+UINT16
+AeBuildFullExceptionCode (
+ UINT8 Level,
+ UINT16 MessageId)
+{
+
+ /*
+ * Error level is in the thousands slot (error/warning/remark, etc.)
+ * Error codes are 0 - 999
+ */
+ return (((Level + 1) * 1000) + MessageId);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.h
new file mode 100644
index 0000000000..d7e3dd06e8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmessages.h
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ * Module Name: aslmessages.h - Compiler error/warning messages
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ASLMESSAGES_H
+#define __ASLMESSAGES_H
+
+
+/* These values must match error type string tables in aslmessages.c */
+
+typedef enum
+{
+ ASL_OPTIMIZATION = 0,
+ ASL_REMARK,
+ ASL_WARNING,
+ ASL_WARNING2,
+ ASL_WARNING3,
+ ASL_ERROR,
+ ASL_NUM_REPORT_LEVELS
+
+} ASL_MESSAGE_TYPES;
+
+
+#define ASL_ERROR_LEVEL_LENGTH 8 /* Length of strings for types above */
+
+/*
+ * Exception code blocks, 0 - 999
+ * Available for new exception blocks: 600 - 999
+ */
+#define ASL_MSG_MAIN_COMPILER 0 /* 0 - 299 */
+#define ASL_MSG_MAIN_COMPILER_END 299
+
+#define ASL_MSG_TABLE_COMPILER 300 /* 300 - 499 */
+#define ASL_MSG_TABLE_COMPILER_END 499
+
+#define ASL_MSG_PREPROCESSOR 500 /* 500 - 599 */
+#define ASL_MSG_PREPROCESSOR_END 599
+
+
+/*
+ * Values (message IDs) for all compiler messages. There are currently
+ * three distinct blocks of error messages (so that they can be expanded
+ * individually):
+ * Main ASL compiler
+ * Data Table compiler
+ * Preprocessor
+ *
+ * NOTE1: This list must match the tables of message strings in the file
+ * aslmessages.c exactly.
+ *
+ * NOTE2: With the introduction of the -vw option to disable specific
+ * messages, new messages should only be added to the end of these
+ * lists, so that values for existing messages are not disturbed.
+ */
+typedef enum
+{
+ ASL_MSG_RESERVED = ASL_MSG_MAIN_COMPILER,
+
+ ASL_MSG_ALIGNMENT,
+ ASL_MSG_ALPHANUMERIC_STRING,
+ ASL_MSG_AML_NOT_IMPLEMENTED,
+ ASL_MSG_ARG_COUNT_HI,
+ ASL_MSG_ARG_COUNT_LO,
+ ASL_MSG_ARG_INIT,
+ ASL_MSG_BACKWARDS_OFFSET,
+ ASL_MSG_BUFFER_LENGTH,
+ ASL_MSG_CLOSE,
+ ASL_MSG_COMPILER_INTERNAL,
+ ASL_MSG_COMPILER_RESERVED,
+ ASL_MSG_CONNECTION_MISSING,
+ ASL_MSG_CONNECTION_INVALID,
+ ASL_MSG_CONSTANT_EVALUATION,
+ ASL_MSG_CONSTANT_FOLDED,
+ ASL_MSG_CORE_EXCEPTION,
+ ASL_MSG_DEBUG_FILE_OPEN,
+ ASL_MSG_DEBUG_FILENAME,
+ ASL_MSG_DEPENDENT_NESTING,
+ ASL_MSG_DMA_CHANNEL,
+ ASL_MSG_DMA_LIST,
+ ASL_MSG_DUPLICATE_CASE,
+ ASL_MSG_DUPLICATE_ITEM,
+ ASL_MSG_EARLY_EOF,
+ ASL_MSG_ENCODING_LENGTH,
+ ASL_MSG_EX_INTERRUPT_LIST,
+ ASL_MSG_EX_INTERRUPT_LIST_MIN,
+ ASL_MSG_EX_INTERRUPT_NUMBER,
+ ASL_MSG_FIELD_ACCESS_WIDTH,
+ ASL_MSG_FIELD_UNIT_ACCESS_WIDTH,
+ ASL_MSG_FIELD_UNIT_OFFSET,
+ ASL_MSG_GPE_NAME_CONFLICT,
+ ASL_MSG_HID_LENGTH,
+ ASL_MSG_HID_PREFIX,
+ ASL_MSG_HID_SUFFIX,
+ ASL_MSG_INCLUDE_FILE_OPEN,
+ ASL_MSG_INPUT_FILE_OPEN,
+ ASL_MSG_INTEGER_LENGTH,
+ ASL_MSG_INTEGER_OPTIMIZATION,
+ ASL_MSG_INTERRUPT_LIST,
+ ASL_MSG_INTERRUPT_NUMBER,
+ ASL_MSG_INVALID_ACCESS_SIZE,
+ ASL_MSG_INVALID_ADDR_FLAGS,
+ ASL_MSG_INVALID_CONSTANT_OP,
+ ASL_MSG_INVALID_EISAID,
+ ASL_MSG_INVALID_ESCAPE,
+ ASL_MSG_INVALID_GRAN_FIXED,
+ ASL_MSG_INVALID_GRANULARITY,
+ ASL_MSG_INVALID_LENGTH,
+ ASL_MSG_INVALID_LENGTH_FIXED,
+ ASL_MSG_INVALID_MIN_MAX,
+ ASL_MSG_INVALID_OPERAND,
+ ASL_MSG_INVALID_PERFORMANCE,
+ ASL_MSG_INVALID_PRIORITY,
+ ASL_MSG_INVALID_STRING,
+ ASL_MSG_INVALID_TARGET,
+ ASL_MSG_INVALID_TIME,
+ ASL_MSG_INVALID_TYPE,
+ ASL_MSG_INVALID_UUID,
+ ASL_MSG_ISA_ADDRESS,
+ ASL_MSG_LEADING_ASTERISK,
+ ASL_MSG_LIST_LENGTH_LONG,
+ ASL_MSG_LIST_LENGTH_SHORT,
+ ASL_MSG_LISTING_FILE_OPEN,
+ ASL_MSG_LISTING_FILENAME,
+ ASL_MSG_LOCAL_INIT,
+ ASL_MSG_LOCAL_OUTSIDE_METHOD,
+ ASL_MSG_LONG_LINE,
+ ASL_MSG_MEMORY_ALLOCATION,
+ ASL_MSG_MISSING_ENDDEPENDENT,
+ ASL_MSG_MISSING_STARTDEPENDENT,
+ ASL_MSG_MULTIPLE_DEFAULT,
+ ASL_MSG_MULTIPLE_TYPES,
+ ASL_MSG_NAME_EXISTS,
+ ASL_MSG_NAME_OPTIMIZATION,
+ ASL_MSG_NAMED_OBJECT_IN_WHILE,
+ ASL_MSG_NESTED_COMMENT,
+ ASL_MSG_NO_CASES,
+ ASL_MSG_NO_REGION,
+ ASL_MSG_NO_RETVAL,
+ ASL_MSG_NO_WHILE,
+ ASL_MSG_NON_ASCII,
+ ASL_MSG_NON_ZERO,
+ ASL_MSG_NOT_EXIST,
+ ASL_MSG_NOT_FOUND,
+ ASL_MSG_NOT_METHOD,
+ ASL_MSG_NOT_PARAMETER,
+ ASL_MSG_NOT_REACHABLE,
+ ASL_MSG_NOT_REFERENCED,
+ ASL_MSG_NULL_DESCRIPTOR,
+ ASL_MSG_NULL_STRING,
+ ASL_MSG_OPEN,
+ ASL_MSG_OUTPUT_FILE_OPEN,
+ ASL_MSG_OUTPUT_FILENAME,
+ ASL_MSG_PACKAGE_LENGTH,
+ ASL_MSG_PREPROCESSOR_FILENAME,
+ ASL_MSG_READ,
+ ASL_MSG_RECURSION,
+ ASL_MSG_REGION_BUFFER_ACCESS,
+ ASL_MSG_REGION_BYTE_ACCESS,
+ ASL_MSG_RESERVED_ARG_COUNT_HI,
+ ASL_MSG_RESERVED_ARG_COUNT_LO,
+ ASL_MSG_RESERVED_METHOD,
+ ASL_MSG_RESERVED_NO_RETURN_VAL,
+ ASL_MSG_RESERVED_OPERAND_TYPE,
+ ASL_MSG_RESERVED_PACKAGE_LENGTH,
+ ASL_MSG_RESERVED_RETURN_VALUE,
+ ASL_MSG_RESERVED_USE,
+ ASL_MSG_RESERVED_WORD,
+ ASL_MSG_RESOURCE_FIELD,
+ ASL_MSG_RESOURCE_INDEX,
+ ASL_MSG_RESOURCE_LIST,
+ ASL_MSG_RESOURCE_SOURCE,
+ ASL_MSG_RESULT_NOT_USED,
+ ASL_MSG_RETURN_TYPES,
+ ASL_MSG_SCOPE_FWD_REF,
+ ASL_MSG_SCOPE_TYPE,
+ ASL_MSG_SEEK,
+ ASL_MSG_SERIALIZED,
+ ASL_MSG_SERIALIZED_REQUIRED,
+ ASL_MSG_SINGLE_NAME_OPTIMIZATION,
+ ASL_MSG_SOME_NO_RETVAL,
+ ASL_MSG_STRING_LENGTH,
+ ASL_MSG_SWITCH_TYPE,
+ ASL_MSG_SYNC_LEVEL,
+ ASL_MSG_SYNTAX,
+ ASL_MSG_TABLE_SIGNATURE,
+ ASL_MSG_TAG_LARGER,
+ ASL_MSG_TAG_SMALLER,
+ ASL_MSG_TIMEOUT,
+ ASL_MSG_TOO_MANY_TEMPS,
+ ASL_MSG_TRUNCATION,
+ ASL_MSG_UNKNOWN_RESERVED_NAME,
+ ASL_MSG_UNREACHABLE_CODE,
+ ASL_MSG_UNSUPPORTED,
+ ASL_MSG_UPPER_CASE,
+ ASL_MSG_VENDOR_LIST,
+ ASL_MSG_WRITE,
+ ASL_MSG_RANGE,
+ ASL_MSG_BUFFER_ALLOCATION,
+ ASL_MSG_MISSING_DEPENDENCY,
+ ASL_MSG_ILLEGAL_FORWARD_REF,
+ ASL_MSG_ILLEGAL_METHOD_REF,
+ ASL_MSG_LOCAL_NOT_USED,
+ ASL_MSG_ARG_AS_LOCAL_NOT_USED,
+ ASL_MSG_ARG_NOT_USED,
+
+ /* These messages are used by the Data Table compiler only */
+
+ ASL_MSG_BUFFER_ELEMENT = ASL_MSG_TABLE_COMPILER,
+ ASL_MSG_DIVIDE_BY_ZERO,
+ ASL_MSG_FLAG_VALUE,
+ ASL_MSG_INTEGER_SIZE,
+ ASL_MSG_INVALID_EXPRESSION,
+ ASL_MSG_INVALID_FIELD_NAME,
+ ASL_MSG_INVALID_HEX_INTEGER,
+ ASL_MSG_OEM_TABLE,
+ ASL_MSG_RESERVED_VALUE,
+ ASL_MSG_UNKNOWN_LABEL,
+ ASL_MSG_UNKNOWN_SUBTABLE,
+ ASL_MSG_UNKNOWN_TABLE,
+ ASL_MSG_ZERO_VALUE,
+
+ /* These messages are used by the Preprocessor only */
+
+ ASL_MSG_DIRECTIVE_SYNTAX = ASL_MSG_PREPROCESSOR,
+ ASL_MSG_ENDIF_MISMATCH,
+ ASL_MSG_ERROR_DIRECTIVE,
+ ASL_MSG_EXISTING_NAME,
+ ASL_MSG_INVALID_INVOCATION,
+ ASL_MSG_MACRO_SYNTAX,
+ ASL_MSG_TOO_MANY_ARGUMENTS,
+ ASL_MSG_UNKNOWN_DIRECTIVE,
+ ASL_MSG_UNKNOWN_PRAGMA,
+ ASL_MSG_WARNING_DIRECTIVE,
+ ASL_MSG_INCLUDE_FILE
+
+} ASL_MESSAGE_IDS;
+
+
+#endif /* __ASLMESSAGES_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmethod.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmethod.c
new file mode 100644
index 0000000000..227ce37045
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslmethod.c
@@ -0,0 +1,726 @@
+/******************************************************************************
+ *
+ * Module Name: aslmethod.c - Control method analysis walk
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslmethod")
+
+
+/* Local prototypes */
+
+void
+MtCheckNamedObjectInMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MtMethodAnalysisWalkBegin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
+ * 1) Initialized local variables
+ * 2) Valid arguments
+ * 3) Return types
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+MtMethodAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
+ ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
+ ACPI_PARSE_OBJECT *Next;
+ UINT32 RegisterNumber;
+ UINT32 i;
+ char LocalName[] = "Local0";
+ char ArgName[] = "Arg0";
+ ACPI_PARSE_OBJECT *ArgNode;
+ ACPI_PARSE_OBJECT *NextType;
+ ACPI_PARSE_OBJECT *NextParamType;
+ UINT8 ActualArgs = 0;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ TotalMethods++;
+
+ /* Create and init method info */
+
+ MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
+ MethodInfo->Next = WalkInfo->MethodStack;
+ MethodInfo->Op = Op;
+
+ WalkInfo->MethodStack = MethodInfo;
+
+ /*
+ * Special handling for _PSx methods. Dependency rules (same scope):
+ *
+ * 1) _PS0 - One of these must exist: _PS1, _PS2, _PS3
+ * 2) _PS1/_PS2/_PS3: A _PS0 must exist
+ */
+ if (ACPI_COMPARE_NAME (METHOD_NAME__PS0, Op->Asl.NameSeg))
+ {
+ /* For _PS0, one of _PS1/_PS2/_PS3 must exist */
+
+ if ((!ApFindNameInScope (METHOD_NAME__PS1, Op)) &&
+ (!ApFindNameInScope (METHOD_NAME__PS2, Op)) &&
+ (!ApFindNameInScope (METHOD_NAME__PS3, Op)))
+ {
+ AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
+ "_PS0 requires one of _PS1/_PS2/_PS3 in same scope");
+ }
+ }
+ else if (
+ ACPI_COMPARE_NAME (METHOD_NAME__PS1, Op->Asl.NameSeg) ||
+ ACPI_COMPARE_NAME (METHOD_NAME__PS2, Op->Asl.NameSeg) ||
+ ACPI_COMPARE_NAME (METHOD_NAME__PS3, Op->Asl.NameSeg))
+ {
+ /* For _PS1/_PS2/_PS3, a _PS0 must exist */
+
+ if (!ApFindNameInScope (METHOD_NAME__PS0, Op))
+ {
+ sprintf (MsgBuffer,
+ "%4.4s requires _PS0 in same scope", Op->Asl.NameSeg);
+
+ AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
+ MsgBuffer);
+ }
+ }
+
+ /* Get the name node */
+
+ Next = Op->Asl.Child;
+
+ /* Get the NumArguments node */
+
+ Next = Next->Asl.Next;
+ MethodInfo->NumArguments = (UINT8)
+ (((UINT8) Next->Asl.Value.Integer) & 0x07);
+
+ /* Get the SerializeRule and SyncLevel nodes, ignored here */
+
+ Next = Next->Asl.Next;
+ MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer;
+
+ Next = Next->Asl.Next;
+ ArgNode = Next;
+
+ /* Get the ReturnType node */
+
+ Next = Next->Asl.Next;
+
+ NextType = Next->Asl.Child;
+ while (NextType)
+ {
+ /* Get and map each of the ReturnTypes */
+
+ MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
+ NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ NextType = NextType->Asl.Next;
+ }
+
+ /* Get the ParameterType node */
+
+ Next = Next->Asl.Next;
+
+ NextType = Next->Asl.Child;
+ while (NextType)
+ {
+ if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ NextParamType = NextType->Asl.Child;
+ while (NextParamType)
+ {
+ MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
+ NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ NextParamType = NextParamType->Asl.Next;
+ }
+ }
+ else
+ {
+ MethodInfo->ValidArgTypes[ActualArgs] =
+ AnMapObjTypeToBtype (NextType);
+ NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ ActualArgs++;
+ }
+
+ NextType = NextType->Asl.Next;
+ }
+
+ if ((MethodInfo->NumArguments) &&
+ (MethodInfo->NumArguments != ActualArgs))
+ {
+ /* error: Param list did not match number of args */
+ }
+
+ /* Allow numarguments == 0 for Function() */
+
+ if ((!MethodInfo->NumArguments) && (ActualArgs))
+ {
+ MethodInfo->NumArguments = ActualArgs;
+ ArgNode->Asl.Value.Integer |= ActualArgs;
+ }
+
+ /*
+ * Actual arguments are initialized at method entry.
+ * All other ArgX "registers" can be used as locals, so we
+ * track their initialization.
+ */
+ for (i = 0; i < MethodInfo->NumArguments; i++)
+ {
+ MethodInfo->ArgInitialized[i] = TRUE;
+ }
+ break;
+
+ case PARSEOP_METHODCALL:
+
+ if (MethodInfo &&
+ (Op->Asl.Node == MethodInfo->Op->Asl.Node))
+ {
+ AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
+ }
+ break;
+
+ case PARSEOP_LOCAL0:
+ case PARSEOP_LOCAL1:
+ case PARSEOP_LOCAL2:
+ case PARSEOP_LOCAL3:
+ case PARSEOP_LOCAL4:
+ case PARSEOP_LOCAL5:
+ case PARSEOP_LOCAL6:
+ case PARSEOP_LOCAL7:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Local was used outside a control method, or there was an error
+ * in the method declaration.
+ */
+ AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
+ return (AE_ERROR);
+ }
+
+ RegisterNumber = (Op->Asl.AmlOpcode & 0x0007);
+
+ /*
+ * If the local is being used as a target, mark the local
+ * initialized
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
+ }
+
+ /*
+ * Otherwise, this is a reference, check if the local
+ * has been previously initialized.
+ *
+ * The only operator that accepts an uninitialized value is ObjectType()
+ */
+ else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
+ (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
+ {
+ LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
+ AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
+ }
+ break;
+
+ case PARSEOP_ARG0:
+ case PARSEOP_ARG1:
+ case PARSEOP_ARG2:
+ case PARSEOP_ARG3:
+ case PARSEOP_ARG4:
+ case PARSEOP_ARG5:
+ case PARSEOP_ARG6:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Arg was used outside a control method, or there was an error
+ * in the method declaration.
+ */
+ AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
+ return (AE_ERROR);
+ }
+
+ RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
+ ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
+
+ /*
+ * If the Arg is being used as a target, mark the local
+ * initialized
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
+ }
+
+ /*
+ * Otherwise, this is a reference, check if the Arg
+ * has been previously initialized.
+ *
+ * The only operator that accepts an uninitialized value is ObjectType()
+ */
+ else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
+ (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
+ {
+ AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
+ }
+
+ /* Flag this arg if it is not a "real" argument to the method */
+
+ if (RegisterNumber >= MethodInfo->NumArguments)
+ {
+ AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
+ }
+ break;
+
+ case PARSEOP_RETURN:
+
+ if (!MethodInfo)
+ {
+ /*
+ * Probably was an error in the method declaration,
+ * no additional error here
+ */
+ ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
+ return (AE_ERROR);
+ }
+
+ /*
+ * A child indicates a possible return value. A simple Return or
+ * Return() is marked with NODE_IS_NULL_RETURN by the parser so
+ * that it is not counted as a "real" return-with-value, although
+ * the AML code that is actually emitted is Return(0). The AML
+ * definition of Return has a required parameter, so we are
+ * forced to convert a null return to Return(0).
+ */
+ if ((Op->Asl.Child) &&
+ (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (!(Op->Asl.Child->Asl.CompileFlags & NODE_IS_NULL_RETURN)))
+ {
+ MethodInfo->NumReturnWithValue++;
+ }
+ else
+ {
+ MethodInfo->NumReturnNoValue++;
+ }
+ break;
+
+ case PARSEOP_BREAK:
+ case PARSEOP_CONTINUE:
+
+ Next = Op->Asl.Parent;
+ while (Next)
+ {
+ if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
+ {
+ break;
+ }
+ Next = Next->Asl.Parent;
+ }
+
+ if (!Next)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
+ }
+ break;
+
+ case PARSEOP_STALL:
+
+ /* We can range check if the argument is an integer */
+
+ if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
+ (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
+ }
+ break;
+
+ case PARSEOP_DEVICE:
+
+ Next = Op->Asl.Child;
+
+ if (!ApFindNameInScope (METHOD_NAME__HID, Next) &&
+ !ApFindNameInScope (METHOD_NAME__ADR, Next))
+ {
+ AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op,
+ "Device object requires a _HID or _ADR in same scope");
+ }
+ break;
+
+ case PARSEOP_EVENT:
+ case PARSEOP_MUTEX:
+ case PARSEOP_OPERATIONREGION:
+ case PARSEOP_POWERRESOURCE:
+ case PARSEOP_PROCESSOR:
+ case PARSEOP_THERMALZONE:
+
+ /*
+ * The first operand is a name to be created in the namespace.
+ * Check against the reserved list.
+ */
+ i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
+ if (i < ACPI_VALID_RESERVED_NAME_MAX)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
+ }
+ break;
+
+ case PARSEOP_NAME:
+
+ /* Typecheck any predefined names statically defined with Name() */
+
+ ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
+
+ /* Special typechecking for _HID */
+
+ if (!strcmp (METHOD_NAME__HID, Op->Asl.NameSeg))
+ {
+ Next = Op->Asl.Child->Asl.Next;
+ AnCheckId (Next, ASL_TYPE_HID);
+ }
+
+ /* Special typechecking for _CID */
+
+ else if (!strcmp (METHOD_NAME__CID, Op->Asl.NameSeg))
+ {
+ Next = Op->Asl.Child->Asl.Next;
+
+ if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
+ (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
+ {
+ Next = Next->Asl.Child;
+ while (Next)
+ {
+ AnCheckId (Next, ASL_TYPE_CID);
+ Next = Next->Asl.Next;
+ }
+ }
+ else
+ {
+ AnCheckId (Next, ASL_TYPE_CID);
+ }
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Check for named object creation within a non-serialized method */
+
+ MtCheckNamedObjectInMethod (Op, MethodInfo);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MtCheckNamedObjectInMethod
+ *
+ * PARAMETERS: Op - Current parser op
+ * MethodInfo - Info for method being parsed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Detect if a non-serialized method is creating a named object,
+ * which could possibly cause problems if two threads execute
+ * the method concurrently. Emit a remark in this case.
+ *
+ ******************************************************************************/
+
+void
+MtCheckNamedObjectInMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ /* We don't care about actual method declarations */
+
+ if (Op->Asl.AmlOpcode == AML_METHOD_OP)
+ {
+ return;
+ }
+
+ /* Determine if we are creating a named object */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
+ {
+ /*
+ * If we have a named object created within a non-serialized method,
+ * emit a remark that the method should be serialized.
+ *
+ * Reason: If a thread blocks within the method for any reason, and
+ * another thread enters the method, the method will fail because an
+ * attempt will be made to create the same object twice.
+ */
+ if (MethodInfo && !MethodInfo->ShouldBeSerialized)
+ {
+ AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op,
+ "due to creation of named objects within");
+
+ /* Emit message only ONCE per method */
+
+ MethodInfo->ShouldBeSerialized = TRUE;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: MtMethodAnalysisWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for analysis walk. Complete method
+ * return analysis.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+MtMethodAnalysisWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
+ ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+ case PARSEOP_RETURN:
+
+ if (!MethodInfo)
+ {
+ printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "No method info for this method");
+
+ CmCleanupAndExit ();
+ return (AE_AML_INTERNAL);
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ WalkInfo->MethodStack = MethodInfo->Next;
+
+ /*
+ * Check if there is no return statement at the end of the
+ * method AND we can actually get there -- i.e., the execution
+ * of the method can possibly terminate without a return statement.
+ */
+ if ((!AnLastStatementIsReturn (Op)) &&
+ (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
+ {
+ /*
+ * No return statement, and execution can possibly exit
+ * via this path. This is equivalent to Return ()
+ */
+ MethodInfo->NumReturnNoValue++;
+ }
+
+ /*
+ * Check for case where some return statements have a return value
+ * and some do not. Exit without a return statement is a return with
+ * no value
+ */
+ if (MethodInfo->NumReturnNoValue &&
+ MethodInfo->NumReturnWithValue)
+ {
+ AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
+ Op->Asl.ExternalName);
+ }
+
+ /*
+ * If there are any RETURN() statements with no value, or there is a
+ * control path that allows the method to exit without a return value,
+ * we mark the method as a method that does not return a value. This
+ * knowledge can be used to check method invocations that expect a
+ * returned value.
+ */
+ if (MethodInfo->NumReturnNoValue)
+ {
+ if (MethodInfo->NumReturnWithValue)
+ {
+ Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
+ }
+ else
+ {
+ Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
+ }
+ }
+
+ /*
+ * Check predefined method names for correct return behavior
+ * and correct number of arguments. Also, some special checks
+ * For GPE and _REG methods.
+ */
+ if (ApCheckForPredefinedMethod (Op, MethodInfo))
+ {
+ /* Special check for two names like _L01 and _E01 in same scope */
+
+ ApCheckForGpeNameConflict (Op);
+
+ /*
+ * Special check for _REG: Must have an operation region definition
+ * within the same scope!
+ */
+ ApCheckRegMethod (Op);
+ }
+
+ ACPI_FREE (MethodInfo);
+ break;
+
+ case PARSEOP_NAME:
+
+ /* Special check for two names like _L01 and _E01 in same scope */
+
+ ApCheckForGpeNameConflict (Op);
+ break;
+
+ case PARSEOP_RETURN:
+
+ /*
+ * If the parent is a predefined method name, attempt to typecheck
+ * the return value. Only static types can be validated.
+ */
+ ApCheckPredefinedReturnValue (Op, MethodInfo);
+
+ /*
+ * The parent block does not "exit" and continue execution -- the
+ * method is terminated here with the Return() statement.
+ */
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+
+ /* Used in the "typing" pass later */
+
+ Op->Asl.ParentMethod = MethodInfo->Op;
+
+ /*
+ * If there is a peer node after the return statement, then this
+ * node is unreachable code -- i.e., it won't be executed because of
+ * the preceding Return() statement.
+ */
+ if (Op->Asl.Next)
+ {
+ AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
+ }
+ break;
+
+ case PARSEOP_IF:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.Next) &&
+ (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
+ {
+ /*
+ * This IF has a corresponding ELSE. The IF block has no exit,
+ * (it contains an unconditional Return)
+ * mark the ELSE block to remember this fact.
+ */
+ Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
+ }
+ break;
+
+ case PARSEOP_ELSE:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
+ {
+ /*
+ * This ELSE block has no exit and the corresponding IF block
+ * has no exit either. Therefore, the parent node has no exit.
+ */
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+ }
+ break;
+
+
+ default:
+
+ if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
+ (Op->Asl.Parent))
+ {
+ /* If this node has no exit, then the parent has no exit either */
+
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
+ }
+ break;
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslnamesp.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslnamesp.c
new file mode 100644
index 0000000000..1e65ab70e5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslnamesp.c
@@ -0,0 +1,422 @@
+/******************************************************************************
+ *
+ * Module Name: aslnamesp - Namespace output file generation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslnamesp")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+NsDoOneNamespaceObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+NsDoOnePathname (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: NsSetupNamespaceListing
+ *
+ * PARAMETERS: Handle - local file handle
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the namespace output file to the input handle
+ *
+ ******************************************************************************/
+
+void
+NsSetupNamespaceListing (
+ void *Handle)
+{
+
+ Gbl_NsOutputFlag = TRUE;
+ Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: NsDisplayNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk the namespace an display information about each node
+ * in the tree. Information is written to the optional
+ * namespace output file.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+NsDisplayNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ if (!Gbl_NsOutputFlag)
+ {
+ return (AE_OK);
+ }
+
+ Gbl_NumNamespaceObjects = 0;
+
+ /* File header */
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n");
+
+ /* Walk entire namespace from the root */
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, NsDoOneNamespaceObject, NULL,
+ NULL, NULL);
+
+ /* Print the full pathname for each namespace node */
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, NsDoOnePathname, NULL,
+ NULL, NULL);
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: NsDoOneNamespaceObject
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dump a namespace object to the namespace output file.
+ * Called during the walk of the namespace to dump all objects.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+NsDoOneNamespaceObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PARSE_OBJECT *Op;
+
+
+ Gbl_NumNamespaceObjects++;
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u [%u] %*s %4.4s - %s",
+ Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
+ &Node->Name,
+ AcpiUtGetTypeName (Node->Type));
+
+ Op = Node->Op;
+ ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
+
+ if (!Op)
+ {
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
+ return (AE_OK);
+ }
+
+
+ if ((ObjDesc) &&
+ (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
+ {
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Value 0x%8.8X%8.8X]",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Value \"%s\"]",
+ ObjDesc->String.Pointer);
+ break;
+
+ default:
+
+ /* Nothing to do for other types */
+
+ break;
+ }
+
+ }
+ else
+ {
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ Op = Op->Asl.Child;
+ }
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
+ {
+ Op = Op->Asl.Next;
+ }
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Value 0x%8.8X%8.8X]",
+ ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ Op = Op->Asl.Child;
+ }
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
+ {
+ Op = Op->Asl.Next;
+ }
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Value \"%s\"]",
+ Op->Asl.Value.String);
+ break;
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
+ {
+ Op = Op->Asl.Child;
+ }
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Offset 0x%04X Length 0x%04X bits]",
+ Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_CREATEBYTEFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BYTE ( 8 bit)]");
+ break;
+
+ case PARSEOP_CREATEDWORDFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [DWORD (32 bit)]");
+ break;
+
+ case PARSEOP_CREATEQWORDFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [QWORD (64 bit)]");
+ break;
+
+ case PARSEOP_CREATEWORDFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [WORD (16 bit)]");
+ break;
+
+ case PARSEOP_CREATEBITFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BIT ( 1 bit)]");
+ break;
+
+ case PARSEOP_CREATEFIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Arbitrary Bit Field]");
+ break;
+
+ default:
+
+ break;
+
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ Op = Op->Asl.Child;
+ }
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
+ {
+ Op = Op->Asl.Next;
+ }
+ Op = Op->Asl.Child;
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
+ (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
+ {
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Length 0x%.2X elements]",
+ Op->Asl.Value.Integer);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_NAME)
+ {
+ Op = Op->Asl.Child;
+ }
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
+ {
+ Op = Op->Asl.Next;
+ }
+ Op = Op->Asl.Child;
+
+ if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
+ {
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Initial Length 0x%.2X bytes]",
+ Op->Asl.Value.Integer);
+ }
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Code Length 0x%.4X bytes]",
+ Op->Asl.AmlSubtreeLength);
+ break;
+
+ case ACPI_TYPE_LOCAL_RESOURCE:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Desc Offset 0x%.4X Bytes]", Node->Value);
+ break;
+
+ case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ " [Field Offset 0x%.4X Bits 0x%.4X Bytes] ",
+ Node->Value, Node->Value / 8);
+
+ if (Node->Flags & ANOBJ_IS_REFERENCED)
+ {
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ "Referenced");
+ }
+ else
+ {
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
+ "Name not referenced");
+ }
+ break;
+
+ default:
+
+ /* Nothing to do for other types */
+
+ break;
+ }
+ }
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: NsDoOnePathname
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Print the full pathname for a namespace node.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+NsDoOnePathname (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_STATUS Status;
+ ACPI_BUFFER TargetPath;
+
+
+ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (Node, &TargetPath, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
+ ACPI_FREE (TargetPath.Pointer);
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asloffset.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloffset.c
new file mode 100644
index 0000000000..afc62585e4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloffset.c
@@ -0,0 +1,472 @@
+/******************************************************************************
+ *
+ * Module Name: asloffset - Generate a C "offset table" for BIOS use.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asloffset")
+
+
+/* Local prototypes */
+
+static void
+LsEmitOffsetTableEntry (
+ UINT32 FileId,
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 NamepathOffset,
+ UINT32 Offset,
+ char *OpName,
+ UINT64 Value,
+ UINT8 AmlOpcode,
+ UINT16 ParentOpcode);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsAmlOffsetWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Process one node during a offset table file generation.
+ *
+ * Three types of objects are currently emitted to the offset table:
+ * 1) Tagged (named) resource descriptors
+ * 2) Named integer objects with constant integer values
+ * 3) Named package objects
+ * 4) Operation Regions that have constant Offset (address) parameters
+ * 5) Control methods
+ *
+ * The offset table allows the BIOS to dynamically update the values of these
+ * objects at boot time.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LsAmlOffsetWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context);
+ ACPI_NAMESPACE_NODE *Node;
+ UINT32 Length;
+ UINT32 NamepathOffset;
+ UINT32 DataOffset;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Ignore actual data blocks for resource descriptors */
+
+ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA)
+ {
+ return (AE_OK); /* Do NOT update the global AML offset */
+ }
+
+ /* We are only interested in named objects (have a namespace node) */
+
+ Node = Op->Asl.Node;
+ if (!Node)
+ {
+ Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength;
+ return (AE_OK);
+ }
+
+ /* Named resource descriptor (has a descriptor tag) */
+
+ if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE) &&
+ (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC))
+ {
+ LsEmitOffsetTableEntry (FileId, Node, 0, Gbl_CurrentAmlOffset,
+ Op->Asl.ParseOpName, 0, Op->Asl.Extra, AML_BUFFER_OP);
+
+ Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength;
+ return (AE_OK);
+ }
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_NAME_OP:
+
+ /* Named object -- Name (NameString, DataRefObject) */
+
+ if (!Op->Asl.Child)
+ {
+ FlPrintFile (FileId, "%s NO CHILD!\n", MsgBuffer);
+ return (AE_OK);
+ }
+
+ Length = Op->Asl.FinalAmlLength;
+ NamepathOffset = Gbl_CurrentAmlOffset + Length;
+
+ /* Get to the NameSeg/NamePath Op (and length of the name) */
+
+ Op = Op->Asl.Child;
+
+ /* Get offset of last nameseg and the actual data */
+
+ NamepathOffset = Gbl_CurrentAmlOffset + Length +
+ (Op->Asl.FinalAmlLength - ACPI_NAME_SIZE);
+
+ DataOffset = Gbl_CurrentAmlOffset + Length +
+ Op->Asl.FinalAmlLength;
+
+ /* Get actual value associated with the name */
+
+ Op = Op->Asl.Next;
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_BYTE_OP:
+ case AML_WORD_OP:
+ case AML_DWORD_OP:
+ case AML_QWORD_OP:
+
+ /* The +1 is to handle the integer size prefix (opcode) */
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, (DataOffset + 1),
+ Op->Asl.ParseOpName, Op->Asl.Value.Integer,
+ (UINT8) Op->Asl.AmlOpcode, AML_NAME_OP);
+ break;
+
+ case AML_ONE_OP:
+ case AML_ONES_OP:
+ case AML_ZERO_OP:
+
+ /* For these, offset will point to the opcode */
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, DataOffset,
+ Op->Asl.ParseOpName, Op->Asl.Value.Integer,
+ (UINT8) Op->Asl.AmlOpcode, AML_NAME_OP);
+ break;
+
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ /* Get the package element count */
+
+ NextOp = Op->Asl.Child;
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, DataOffset,
+ Op->Asl.ParseOpName, NextOp->Asl.Value.Integer,
+ (UINT8) Op->Asl.AmlOpcode, AML_NAME_OP);
+ break;
+
+ default:
+ break;
+ }
+
+ Gbl_CurrentAmlOffset += Length;
+ return (AE_OK);
+
+ case AML_REGION_OP:
+
+ /* OperationRegion (NameString, RegionSpace, RegionOffset, RegionLength) */
+
+ Length = Op->Asl.FinalAmlLength;
+
+ /* Get the name/namepath node */
+
+ NextOp = Op->Asl.Child;
+
+ /* Get offset of last nameseg and the actual data */
+
+ NamepathOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength - ACPI_NAME_SIZE);
+
+ DataOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength + 1);
+
+ /* Get the SpaceId node, then the Offset (address) node */
+
+ NextOp = NextOp->Asl.Next;
+ NextOp = NextOp->Asl.Next;
+
+ switch (NextOp->Asl.AmlOpcode)
+ {
+ /*
+ * We are only interested in integer constants that can be changed
+ * at boot time. Note, the One/Ones/Zero opcodes are considered
+ * non-changeable, so we ignore them here.
+ */
+ case AML_BYTE_OP:
+ case AML_WORD_OP:
+ case AML_DWORD_OP:
+ case AML_QWORD_OP:
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, (DataOffset + 1),
+ Op->Asl.ParseOpName, NextOp->Asl.Value.Integer,
+ (UINT8) NextOp->Asl.AmlOpcode, AML_REGION_OP);
+
+ Gbl_CurrentAmlOffset += Length;
+ return (AE_OK);
+
+ default:
+ break;
+ }
+ break;
+
+ case AML_METHOD_OP:
+
+ /* Method (Namepath, ...) */
+
+ Length = Op->Asl.FinalAmlLength;
+
+ /* Get the NameSeg/NamePath Op */
+
+ NextOp = Op->Asl.Child;
+
+ /* Get offset of last nameseg and the actual data (flags byte) */
+
+ NamepathOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength - ACPI_NAME_SIZE);
+
+ DataOffset = Gbl_CurrentAmlOffset + Length +
+ NextOp->Asl.FinalAmlLength;
+
+ /* Get the flags byte Op */
+
+ NextOp = NextOp->Asl.Next;
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, DataOffset,
+ Op->Asl.ParseOpName, NextOp->Asl.Value.Integer,
+ (UINT8) Op->Asl.AmlOpcode, AML_METHOD_OP);
+ break;
+
+ case AML_PROCESSOR_OP:
+
+ /* Processor (Namepath, ProcessorId, Address, Length) */
+
+ Length = Op->Asl.FinalAmlLength;
+ NextOp = Op->Asl.Child; /* Get Namepath */
+
+ /* Get offset of last nameseg and the actual data (PBlock address) */
+
+ NamepathOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength - ACPI_NAME_SIZE);
+
+ DataOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength + 1);
+
+ NextOp = NextOp->Asl.Next; /* Get ProcessorID (BYTE) */
+ NextOp = NextOp->Asl.Next; /* Get Address (DWORD) */
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, DataOffset,
+ Op->Asl.ParseOpName, NextOp->Asl.Value.Integer,
+ (UINT8) AML_DWORD_OP, AML_PROCESSOR_OP);
+ break;
+
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_THERMAL_ZONE_OP:
+
+ /* Device/Scope/ThermalZone (Namepath) */
+
+ Length = Op->Asl.FinalAmlLength;
+ NextOp = Op->Asl.Child; /* Get Namepath */
+
+ /* Get offset of last nameseg */
+
+ NamepathOffset = Gbl_CurrentAmlOffset + Length +
+ (NextOp->Asl.FinalAmlLength - ACPI_NAME_SIZE);
+
+ LsEmitOffsetTableEntry (FileId, Node, NamepathOffset, 0,
+ Op->Asl.ParseOpName, 0, (UINT8) 0, Op->Asl.AmlOpcode);
+ break;
+
+ default:
+ break;
+ }
+
+ Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsEmitOffsetTableEntry
+ *
+ * PARAMETERS: FileId - ID of current listing file
+ * Node - Namespace node associated with the name
+ * Offset - Offset of the value within the AML table
+ * OpName - Name of the AML opcode
+ * Value - Current value of the AML field
+ * AmlOpcode - Opcode associated with the field
+ * ObjectType - ACPI object type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a line of the offset table (-so option)
+ *
+ ******************************************************************************/
+
+static void
+LsEmitOffsetTableEntry (
+ UINT32 FileId,
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 NamepathOffset,
+ UINT32 Offset,
+ char *OpName,
+ UINT64 Value,
+ UINT8 AmlOpcode,
+ UINT16 ParentOpcode)
+{
+ ACPI_BUFFER TargetPath;
+ ACPI_STATUS Status;
+
+
+ /* Get the full pathname to the namespace node */
+
+ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (Node, &TargetPath, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* [1] - Skip the opening backslash for the path */
+
+ strcpy (MsgBuffer, "\"");
+ strcat (MsgBuffer, &((char *) TargetPath.Pointer)[1]);
+ strcat (MsgBuffer, "\",");
+ ACPI_FREE (TargetPath.Pointer);
+
+ /*
+ * Max offset is 4G, constrained by 32-bit ACPI table length.
+ * Max Length for Integers is 8 bytes.
+ */
+ FlPrintFile (FileId,
+ " {%-29s 0x%4.4X, 0x%8.8X, 0x%2.2X, 0x%8.8X, 0x%8.8X%8.8X}, /* %s */\n",
+ MsgBuffer, ParentOpcode, NamepathOffset, AmlOpcode,
+ Offset, ACPI_FORMAT_UINT64 (Value), OpName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: LsDoOffsetTableHeader, LsDoOffsetTableFooter
+ *
+ * PARAMETERS: FileId - ID of current listing file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Header and footer for the offset table file.
+ *
+ ******************************************************************************/
+
+void
+LsDoOffsetTableHeader (
+ UINT32 FileId)
+{
+
+ FlPrintFile (FileId,
+ "#ifndef __AML_OFFSET_TABLE_H\n"
+ "#define __AML_OFFSET_TABLE_H\n\n");
+
+ FlPrintFile (FileId, "typedef struct {\n"
+ " char *Pathname; /* Full pathname (from root) to the object */\n"
+ " unsigned short ParentOpcode; /* AML opcode for the parent object */\n"
+ " unsigned long NamesegOffset; /* Offset of last nameseg in the parent namepath */\n"
+ " unsigned char Opcode; /* AML opcode for the data */\n"
+ " unsigned long Offset; /* Offset for the data */\n"
+ " unsigned long long Value; /* Original value of the data (as applicable) */\n"
+ "} AML_OFFSET_TABLE_ENTRY;\n\n");
+
+ FlPrintFile (FileId,
+ "#endif /* __AML_OFFSET_TABLE_H */\n\n");
+
+ FlPrintFile (FileId,
+ "/*\n"
+ " * Information specific to the supported object types:\n"
+ " *\n"
+ " * Integers:\n"
+ " * Opcode is the integer prefix, indicates length of the data\n"
+ " * (One of: BYTE, WORD, DWORD, QWORD, ZERO, ONE, ONES)\n"
+ " * Offset points to the actual integer data\n"
+ " * Value is the existing value in the AML\n"
+ " *\n"
+ " * Packages:\n"
+ " * Opcode is the package or var_package opcode\n"
+ " * Offset points to the package opcode\n"
+ " * Value is the package element count\n"
+ " *\n"
+ " * Operation Regions:\n"
+ " * Opcode is the address integer prefix, indicates length of the data\n"
+ " * Offset points to the region address\n"
+ " * Value is the existing address value in the AML\n"
+ " *\n"
+ " * Control Methods:\n"
+ " * Offset points to the method flags byte\n"
+ " * Value is the existing flags value in the AML\n"
+ " *\n"
+ " * Processors:\n"
+ " * Offset points to the first byte of the PBlock Address\n"
+ " *\n"
+ " * Resource Descriptors:\n"
+ " * Opcode is the descriptor type\n"
+ " * Offset points to the start of the descriptor\n"
+ " *\n"
+ " * Scopes/Devices/ThermalZones:\n"
+ " * Nameseg offset only\n"
+ " */\n");
+
+ FlPrintFile (FileId,
+ "AML_OFFSET_TABLE_ENTRY %s_%s_OffsetTable[] =\n{\n",
+ Gbl_TableSignature, Gbl_TableId);
+}
+
+
+void
+LsDoOffsetTableFooter (
+ UINT32 FileId)
+{
+
+ FlPrintFile (FileId,
+ " {NULL,0,0,0,0,0} /* Table terminator */\n};\n\n");
+ Gbl_CurrentAmlOffset = 0;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopcodes.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopcodes.c
new file mode 100644
index 0000000000..8ee89abf1c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopcodes.c
@@ -0,0 +1,1536 @@
+/******************************************************************************
+ *
+ * Module Name: aslopcode - AML opcode generation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslopcodes")
+
+
+/* Local prototypes */
+
+static void
+OpcDoAccessAs (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpcDoConnection (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpcDoUnicode (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpcDoEisaId (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpcDoPld (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpcDoUuId (
+ ACPI_PARSE_OBJECT *Op);
+
+static UINT8 *
+OpcEncodePldBuffer (
+ ACPI_PLD_INFO *PldInfo);
+
+
+/* ToPld strings */
+
+static char *AslPldPanelList[] =
+{
+ "TOP",
+ "BOTTOM",
+ "LEFT",
+ "RIGHT",
+ "FRONT",
+ "BACK",
+ "UNKNOWN",
+ NULL
+};
+
+static char *AslPldVerticalPositionList[] =
+{
+ "UPPER",
+ "CENTER",
+ "LOWER",
+ NULL
+};
+
+static char *AslPldHorizontalPositionList[] =
+{
+ "LEFT",
+ "CENTER",
+ "RIGHT",
+ NULL
+};
+
+static char *AslPldShapeList[] =
+{
+ "ROUND",
+ "OVAL",
+ "SQUARE",
+ "VERTICALRECTANGLE",
+ "HORIZONTALRECTANGLE",
+ "VERTICALTRAPEZOID",
+ "HORIZONTALTRAPEZOID",
+ "UNKNOWN",
+ "CHAMFERED",
+ NULL
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlOpcodeUpdateWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Opcode update walk, ascending callback
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+OpcAmlOpcodeUpdateWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ /*
+ * Handle the Package() case where the actual opcode cannot be determined
+ * until the PackageLength operand has been folded and minimized.
+ * (PackageOp versus VarPackageOp)
+ *
+ * This is (as of ACPI 3.0) the only case where the AML opcode can change
+ * based upon the value of a parameter.
+ *
+ * The parser always inserts a VarPackage opcode, which can possibly be
+ * optimized to a Package opcode.
+ */
+ if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
+ {
+ OpnDoPackage (Op);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcAmlOpcodeWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
+ * operands.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+OpcAmlOpcodeWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ TotalParseNodes++;
+
+ OpcGenerateAmlOpcode (Op);
+ OpnGenerateAmlOperands (Op);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcGetIntegerWidth
+ *
+ * PARAMETERS: Op - DEFINITION BLOCK op
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Extract integer width from the table revision
+ *
+ ******************************************************************************/
+
+void
+OpcGetIntegerWidth (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Child;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ if (Gbl_RevisionOverride)
+ {
+ AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
+ }
+ else
+ {
+ Child = Op->Asl.Child;
+ Child = Child->Asl.Next;
+ Child = Child->Asl.Next;
+
+ /* Use the revision to set the integer width */
+
+ AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcSetOptimalIntegerSize
+ *
+ * PARAMETERS: Op - A parse tree node
+ *
+ * RETURN: Integer width, in bytes. Also sets the node AML opcode to the
+ * optimal integer AML prefix opcode.
+ *
+ * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
+ * zeros can be truncated to squeeze the integer into the
+ * minimal number of AML bytes.
+ *
+ ******************************************************************************/
+
+UINT32
+OpcSetOptimalIntegerSize (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+#if 0
+ /*
+ * TBD: - we don't want to optimize integers in the block header, but the
+ * code below does not work correctly.
+ */
+ if (Op->Asl.Parent &&
+ Op->Asl.Parent->Asl.Parent &&
+ (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK))
+ {
+ return (0);
+ }
+#endif
+
+ /*
+ * Check for the special AML integers first - Zero, One, Ones.
+ * These are single-byte opcodes that are the smallest possible
+ * representation of an integer.
+ *
+ * This optimization is optional.
+ */
+ if (Gbl_IntegerOptimizationFlag)
+ {
+ switch (Op->Asl.Value.Integer)
+ {
+ case 0:
+
+ Op->Asl.AmlOpcode = AML_ZERO_OP;
+ AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
+ Op, "Zero");
+ return (1);
+
+ case 1:
+
+ Op->Asl.AmlOpcode = AML_ONE_OP;
+ AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
+ Op, "One");
+ return (1);
+
+ case ACPI_UINT32_MAX:
+
+ /* Check for table integer width (32 or 64) */
+
+ if (AcpiGbl_IntegerByteWidth == 4)
+ {
+ Op->Asl.AmlOpcode = AML_ONES_OP;
+ AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
+ Op, "Ones");
+ return (1);
+ }
+ break;
+
+ case ACPI_UINT64_MAX:
+
+ /* Check for table integer width (32 or 64) */
+
+ if (AcpiGbl_IntegerByteWidth == 8)
+ {
+ Op->Asl.AmlOpcode = AML_ONES_OP;
+ AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
+ Op, "Ones");
+ return (1);
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+
+ /* Find the best fit using the various AML integer prefixes */
+
+ if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
+ {
+ Op->Asl.AmlOpcode = AML_BYTE_OP;
+ return (1);
+ }
+ if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
+ {
+ Op->Asl.AmlOpcode = AML_WORD_OP;
+ return (2);
+ }
+ if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
+ {
+ Op->Asl.AmlOpcode = AML_DWORD_OP;
+ return (4);
+ }
+ else
+ {
+ if (AcpiGbl_IntegerByteWidth == 4)
+ {
+ AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
+ Op, NULL);
+
+ if (!Gbl_IgnoreErrors)
+ {
+ /* Truncate the integer to 32-bit */
+ Op->Asl.AmlOpcode = AML_DWORD_OP;
+ return (4);
+ }
+ }
+
+ Op->Asl.AmlOpcode = AML_QWORD_OP;
+ return (8);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoAccessAs
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
+ *
+ ******************************************************************************/
+
+static void
+OpcDoAccessAs (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *TypeOp;
+ ACPI_PARSE_OBJECT *AttribOp;
+ ACPI_PARSE_OBJECT *LengthOp;
+ UINT8 Attribute;
+
+
+ Op->Asl.AmlOpcodeLength = 1;
+ TypeOp = Op->Asl.Child;
+
+ /* First child is the access type */
+
+ TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+
+ /* Second child is the optional access attribute */
+
+ AttribOp = TypeOp->Asl.Next;
+ if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ AttribOp->Asl.Value.Integer = 0;
+ }
+ AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+
+ /* Only a few AccessAttributes support AccessLength */
+
+ Attribute = (UINT8) AttribOp->Asl.Value.Integer;
+ if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
+ (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
+ (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
+ {
+ return;
+ }
+
+ Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
+
+ /*
+ * Child of Attributes is the AccessLength (required for Multibyte,
+ * RawBytes, RawProcess.)
+ */
+ LengthOp = AttribOp->Asl.Child;
+ if (!LengthOp)
+ {
+ return;
+ }
+
+ /* TBD: probably can remove */
+
+ if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ LengthOp->Asl.Value.Integer = 16;
+ }
+
+ LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoConnection
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implement the Connection ASL keyword.
+ *
+ ******************************************************************************/
+
+static void
+OpcDoConnection (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ASL_RESOURCE_NODE *Rnode;
+ ACPI_PARSE_OBJECT *BufferOp;
+ ACPI_PARSE_OBJECT *BufferLengthOp;
+ ACPI_PARSE_OBJECT *BufferDataOp;
+ ASL_RESOURCE_INFO Info;
+ UINT8 State;
+
+
+ Op->Asl.AmlOpcodeLength = 1;
+
+ if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ BufferOp = Op->Asl.Child;
+ BufferLengthOp = BufferOp->Asl.Child;
+ BufferDataOp = BufferLengthOp->Asl.Next;
+
+ Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
+ Info.CurrentByteOffset = 0;
+ State = ACPI_RSTATE_NORMAL;
+ Rnode = RsDoOneResourceDescriptor (&Info, &State);
+ if (!Rnode)
+ {
+ return; /* error */
+ }
+
+ /*
+ * Transform the nodes into the following
+ *
+ * Op -> AML_BUFFER_OP
+ * First Child -> BufferLength
+ * Second Child -> Descriptor Buffer (raw byte data)
+ */
+ BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER;
+ BufferOp->Asl.AmlOpcode = AML_BUFFER_OP;
+ BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
+ UtSetParseOpName (BufferOp);
+
+ BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
+ BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
+ (void) OpcSetOptimalIntegerSize (BufferLengthOp);
+ UtSetParseOpName (BufferLengthOp);
+
+ BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+ BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
+ BufferDataOp->Asl.AmlOpcodeLength = 0;
+ BufferDataOp->Asl.AmlLength = Rnode->BufferLength;
+ BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode;
+ UtSetParseOpName (BufferDataOp);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoUnicode
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string
+ * to a unicode buffer. There is no Unicode AML opcode.
+ *
+ * Note: The Unicode string is 16 bits per character, no leading signature,
+ * with a 16-bit terminating NULL.
+ *
+ ******************************************************************************/
+
+static void
+OpcDoUnicode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *InitializerOp;
+ UINT32 Length;
+ UINT32 Count;
+ UINT32 i;
+ UINT8 *AsciiString;
+ UINT16 *UnicodeString;
+ ACPI_PARSE_OBJECT *BufferLengthOp;
+
+
+ /* Change op into a buffer object */
+
+ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
+ Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+ UtSetParseOpName (Op);
+
+ /* Buffer Length is first, followed by the string */
+
+ BufferLengthOp = Op->Asl.Child;
+ InitializerOp = BufferLengthOp->Asl.Next;
+
+ AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
+
+ /* Create a new buffer for the Unicode string */
+
+ Count = strlen (InitializerOp->Asl.Value.String) + 1;
+ Length = Count * sizeof (UINT16);
+ UnicodeString = UtLocalCalloc (Length);
+
+ /* Convert to Unicode string (including null terminator) */
+
+ for (i = 0; i < Count; i++)
+ {
+ UnicodeString[i] = (UINT16) AsciiString[i];
+ }
+
+ /*
+ * Just set the buffer size node to be the buffer length, regardless
+ * of whether it was previously an integer or a default_arg placeholder
+ */
+ BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
+ BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
+ BufferLengthOp->Asl.Value.Integer = Length;
+ UtSetParseOpName (BufferLengthOp);
+
+ (void) OpcSetOptimalIntegerSize (BufferLengthOp);
+
+ /* The Unicode string is a raw data buffer */
+
+ InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString;
+ InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ InitializerOp->Asl.AmlLength = Length;
+ InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+ InitializerOp->Asl.Child = NULL;
+ UtSetParseOpName (InitializerOp);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoEisaId
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
+ * Pnp BIOS Specification for details. Here is an excerpt:
+ *
+ * A seven character ASCII representation of the product
+ * identifier compressed into a 32-bit identifier. The seven
+ * character ID consists of a three character manufacturer code,
+ * a three character hexadecimal product identifier, and a one
+ * character hexadecimal revision number. The manufacturer code
+ * is a 3 uppercase character code that is compressed into 3 5-bit
+ * values as follows:
+ * 1) Find hex ASCII value for each letter
+ * 2) Subtract 40h from each ASCII value
+ * 3) Retain 5 least significant bits for each letter by
+ * discarding upper 3 bits because they are always 0.
+ * 4) Compressed code = concatenate 0 and the 3 5-bit values
+ *
+ * The format of the compressed product identifier is as follows:
+ * Byte 0: Bit 7 - Reserved (0)
+ * Bits 6-2: - 1st character of compressed mfg code
+ * Bits 1-0 - Upper 2 bits of 2nd character of mfg code
+ * Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code
+ * Bits 4-0 - 3rd character of mfg code
+ * Byte 2: Bits 7-4 - 1st hex digit of product number
+ * Bits 3-0 - 2nd hex digit of product number
+ * Byte 3: Bits 7-4 - 3st hex digit of product number
+ * Bits 3-0 - Hex digit of the revision number
+ *
+ ******************************************************************************/
+
+static void
+OpcDoEisaId (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 EisaId = 0;
+ UINT32 BigEndianId;
+ char *InString;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 i;
+
+
+ InString = (char *) Op->Asl.Value.String;
+
+ /*
+ * The EISAID string must be exactly 7 characters and of the form
+ * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
+ */
+ if (strlen (InString) != 7)
+ {
+ Status = AE_BAD_PARAMETER;
+ }
+ else
+ {
+ /* Check all 7 characters for correct format */
+
+ for (i = 0; i < 7; i++)
+ {
+ /* First 3 characters must be uppercase letters */
+
+ if (i < 3)
+ {
+ if (!isupper ((int) InString[i]))
+ {
+ Status = AE_BAD_PARAMETER;
+ }
+ }
+
+ /* Last 4 characters must be hex digits */
+
+ else if (!isxdigit ((int) InString[i]))
+ {
+ Status = AE_BAD_PARAMETER;
+ }
+ }
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
+ }
+ else
+ {
+ /* Create ID big-endian first (bits are contiguous) */
+
+ BigEndianId =
+ (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
+ (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
+ (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
+
+ (AcpiUtAsciiCharToHex (InString[3])) << 12 |
+ (AcpiUtAsciiCharToHex (InString[4])) << 8 |
+ (AcpiUtAsciiCharToHex (InString[5])) << 4 |
+ AcpiUtAsciiCharToHex (InString[6]);
+
+ /* Swap to little-endian to get final ID (see function header) */
+
+ EisaId = AcpiUtDwordByteSwap (BigEndianId);
+ }
+
+ /*
+ * Morph the Op into an integer, regardless of whether there
+ * was an error in the EISAID string
+ */
+ Op->Asl.Value.Integer = EisaId;
+
+ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
+ Op->Asl.ParseOpcode = PARSEOP_INTEGER;
+ (void) OpcSetOptimalIntegerSize (Op);
+
+ /* Op is now an integer */
+
+ UtSetParseOpName (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcEncodePldBuffer
+ *
+ * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct)
+ *
+ * RETURN: Encode _PLD buffer suitable for return value from _PLD
+ *
+ * DESCRIPTION: Bit-packs a _PLD buffer struct.
+ *
+ ******************************************************************************/
+
+static UINT8 *
+OpcEncodePldBuffer (
+ ACPI_PLD_INFO *PldInfo)
+{
+ UINT32 *Buffer;
+ UINT32 Dword;
+
+
+ Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
+ if (!Buffer)
+ {
+ return (NULL);
+ }
+
+ /* First 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_REVISION (&Dword, PldInfo->Revision);
+ ACPI_PLD_SET_IGNORE_COLOR (&Dword, PldInfo->IgnoreColor);
+ ACPI_PLD_SET_RED (&Dword, PldInfo->Red);
+ ACPI_PLD_SET_GREEN (&Dword, PldInfo->Green);
+ ACPI_PLD_SET_BLUE (&Dword, PldInfo->Blue);
+ ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword);
+
+ /* Second 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_WIDTH (&Dword, PldInfo->Width);
+ ACPI_PLD_SET_HEIGHT (&Dword, PldInfo->Height);
+ ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword);
+
+ /* Third 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_USER_VISIBLE (&Dword, PldInfo->UserVisible);
+ ACPI_PLD_SET_DOCK (&Dword, PldInfo->Dock);
+ ACPI_PLD_SET_LID (&Dword, PldInfo->Lid);
+ ACPI_PLD_SET_PANEL (&Dword, PldInfo->Panel);
+ ACPI_PLD_SET_VERTICAL (&Dword, PldInfo->VerticalPosition);
+ ACPI_PLD_SET_HORIZONTAL (&Dword, PldInfo->HorizontalPosition);
+ ACPI_PLD_SET_SHAPE (&Dword, PldInfo->Shape);
+ ACPI_PLD_SET_ORIENTATION (&Dword, PldInfo->GroupOrientation);
+ ACPI_PLD_SET_TOKEN (&Dword, PldInfo->GroupToken);
+ ACPI_PLD_SET_POSITION (&Dword, PldInfo->GroupPosition);
+ ACPI_PLD_SET_BAY (&Dword, PldInfo->Bay);
+ ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword);
+
+ /* Fourth 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_EJECTABLE (&Dword, PldInfo->Ejectable);
+ ACPI_PLD_SET_OSPM_EJECT (&Dword, PldInfo->OspmEjectRequired);
+ ACPI_PLD_SET_CABINET (&Dword, PldInfo->CabinetNumber);
+ ACPI_PLD_SET_CARD_CAGE (&Dword, PldInfo->CardCageNumber);
+ ACPI_PLD_SET_REFERENCE (&Dword, PldInfo->Reference);
+ ACPI_PLD_SET_ROTATION (&Dword, PldInfo->Rotation);
+ ACPI_PLD_SET_ORDER (&Dword, PldInfo->Order);
+ ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword);
+
+ if (PldInfo->Revision >= 2)
+ {
+ /* Fifth 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_VERT_OFFSET (&Dword, PldInfo->VerticalOffset);
+ ACPI_PLD_SET_HORIZ_OFFSET (&Dword, PldInfo->HorizontalOffset);
+ ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword);
+ }
+
+ return (ACPI_CAST_PTR (UINT8, Buffer));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcFindName
+ *
+ * PARAMETERS: List - Array of char strings to be searched
+ * Name - Char string to string for
+ * Index - Index value to set if found
+ *
+ * RETURN: TRUE if any names matched, FALSE otherwise
+ *
+ * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
+ * equivalent parameter value.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+OpcFindName (
+ char **List,
+ char *Name,
+ UINT64 *Index)
+{
+ char *Str;
+ UINT32 i;
+
+
+ AcpiUtStrupr (Name);
+
+ for (i = 0, Str = List[0]; Str; i++, Str = List[i])
+ {
+ if (!(strncmp (Str, Name, strlen (Name))))
+ {
+ *Index = i;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoPld
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
+ *
+ ******************************************************************************/
+
+static void
+OpcDoPld (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *Buffer;
+ ACPI_PARSE_OBJECT *Node;
+ ACPI_PLD_INFO PldInfo;
+ ACPI_PARSE_OBJECT *NewOp;
+
+
+ if (!Op)
+ {
+ AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
+ return;
+ }
+
+ if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
+ return;
+ }
+
+ memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
+
+ Node = Op->Asl.Child;
+ while (Node)
+ {
+ switch (Node->Asl.ParseOpcode)
+ {
+ case PARSEOP_PLD_REVISION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 127)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_IGNORECOLOR:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 1)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_RED:
+ case PARSEOP_PLD_GREEN:
+ case PARSEOP_PLD_BLUE:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 255)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
+ {
+ PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
+ {
+ PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_BLUE */
+ {
+ PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ break;
+
+ case PARSEOP_PLD_WIDTH:
+ case PARSEOP_PLD_HEIGHT:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 65535)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
+ {
+ PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_HEIGHT */
+ {
+ PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ case PARSEOP_PLD_USERVISIBLE:
+ case PARSEOP_PLD_DOCK:
+ case PARSEOP_PLD_LID:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 1)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
+ {
+ PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
+ {
+ PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else
+ {
+ PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ case PARSEOP_PLD_PANEL:
+
+ if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ if (Node->Asl.Child->Asl.Value.Integer > 6)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+ }
+ else /* PARSEOP_STRING */
+ {
+ if (!OpcFindName(AslPldPanelList,
+ Node->Asl.Child->Asl.Value.String,
+ &Node->Asl.Child->Asl.Value.Integer))
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
+ break;
+ }
+ }
+
+ PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_VERTICALPOSITION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ if (Node->Asl.Child->Asl.Value.Integer > 2)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+ }
+ else /* PARSEOP_STRING */
+ {
+ if (!OpcFindName(AslPldVerticalPositionList,
+ Node->Asl.Child->Asl.Value.String,
+ &Node->Asl.Child->Asl.Value.Integer))
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
+ break;
+ }
+ }
+
+ PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_HORIZONTALPOSITION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ if (Node->Asl.Child->Asl.Value.Integer > 2)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+ }
+ else /* PARSEOP_STRING */
+ {
+ if (!OpcFindName(AslPldHorizontalPositionList,
+ Node->Asl.Child->Asl.Value.String,
+ &Node->Asl.Child->Asl.Value.Integer))
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
+ break;
+ }
+ }
+
+ PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_SHAPE:
+
+ if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ if (Node->Asl.Child->Asl.Value.Integer > 8)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+ }
+ else /* PARSEOP_STRING */
+ {
+ if (!OpcFindName(AslPldShapeList,
+ Node->Asl.Child->Asl.Value.String,
+ &Node->Asl.Child->Asl.Value.Integer))
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
+ break;
+ }
+ }
+
+ PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_GROUPORIENTATION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 1)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_GROUPTOKEN:
+ case PARSEOP_PLD_GROUPPOSITION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 255)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
+ {
+ PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_GROUPPOSITION */
+ {
+ PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ case PARSEOP_PLD_BAY:
+ case PARSEOP_PLD_EJECTABLE:
+ case PARSEOP_PLD_EJECTREQUIRED:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 1)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
+ {
+ PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
+ {
+ PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_EJECTREQUIRED */
+ {
+ PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ case PARSEOP_PLD_CABINETNUMBER:
+ case PARSEOP_PLD_CARDCAGENUMBER:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 255)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
+ {
+ PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_CARDCAGENUMBER */
+ {
+ PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ case PARSEOP_PLD_REFERENCE:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 1)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_ROTATION:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 7)
+ {
+ switch (Node->Asl.Child->Asl.Value.Integer)
+ {
+ case 45:
+
+ Node->Asl.Child->Asl.Value.Integer = 1;
+ break;
+
+ case 90:
+
+ Node->Asl.Child->Asl.Value.Integer = 2;
+ break;
+
+ case 135:
+
+ Node->Asl.Child->Asl.Value.Integer = 3;
+ break;
+
+ case 180:
+
+ Node->Asl.Child->Asl.Value.Integer = 4;
+ break;
+
+ case 225:
+
+ Node->Asl.Child->Asl.Value.Integer = 5;
+ break;
+
+ case 270:
+
+ Node->Asl.Child->Asl.Value.Integer = 6;
+ break;
+
+ case 315:
+
+ Node->Asl.Child->Asl.Value.Integer = 7;
+ break;
+
+ default:
+
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+ }
+
+ PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_ORDER:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 31)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
+ break;
+
+ case PARSEOP_PLD_VERTICALOFFSET:
+ case PARSEOP_PLD_HORIZONTALOFFSET:
+
+ if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.Child->Asl.Value.Integer > 65535)
+ {
+ AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
+ break;
+ }
+
+ if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
+ {
+ PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
+ }
+ else /* PARSEOP_PLD_HORIZONTALOFFSET */
+ {
+ PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
+ }
+
+ break;
+
+ default:
+
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
+ break;
+ }
+
+ Node = Node->Asl.Next;
+ }
+
+ Buffer = OpcEncodePldBuffer(&PldInfo);
+
+ /* Change Op to a Buffer */
+
+ Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+ Op->Common.AmlOpcode = AML_BUFFER_OP;
+
+ /* Disable further optimization */
+
+ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
+ UtSetParseOpName (Op);
+
+ /* Child node is the buffer length */
+
+ NewOp = TrAllocateNode (PARSEOP_INTEGER);
+
+ NewOp->Asl.AmlOpcode = AML_BYTE_OP;
+ NewOp->Asl.Value.Integer = 20;
+ NewOp->Asl.Parent = Op;
+
+ Op->Asl.Child = NewOp;
+ Op = NewOp;
+
+ /* Peer to the child is the raw buffer data */
+
+ NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
+ NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ NewOp->Asl.AmlLength = 20;
+ NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer);
+ NewOp->Asl.Parent = Op->Asl.Parent;
+
+ Op->Asl.Next = NewOp;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoUuId
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert UUID string to 16-byte buffer
+ *
+ ******************************************************************************/
+
+static void
+OpcDoUuId (
+ ACPI_PARSE_OBJECT *Op)
+{
+ char *InString;
+ UINT8 *Buffer;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *NewOp;
+
+
+ InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
+ Buffer = UtLocalCalloc (16);
+
+ Status = AuValidateUuid (InString);
+ if (ACPI_FAILURE (Status))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
+ }
+ else
+ {
+ AcpiUtConvertStringToUuid (InString, Buffer);
+ }
+
+ /* Change Op to a Buffer */
+
+ Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+ Op->Common.AmlOpcode = AML_BUFFER_OP;
+
+ /* Disable further optimization */
+
+ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
+ UtSetParseOpName (Op);
+
+ /* Child node is the buffer length */
+
+ NewOp = TrAllocateNode (PARSEOP_INTEGER);
+
+ NewOp->Asl.AmlOpcode = AML_BYTE_OP;
+ NewOp->Asl.Value.Integer = 16;
+ NewOp->Asl.Parent = Op;
+
+ Op->Asl.Child = NewOp;
+ Op = NewOp;
+
+ /* Peer to the child is the raw buffer data */
+
+ NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
+ NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ NewOp->Asl.AmlLength = 16;
+ NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer);
+ NewOp->Asl.Parent = Op->Asl.Parent;
+
+ Op->Asl.Next = NewOp;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcGenerateAmlOpcode
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generate the AML opcode associated with the node and its
+ * parse (lex/flex) keyword opcode. Essentially implements
+ * a mapping between the parse opcodes and the actual AML opcodes.
+ *
+ ******************************************************************************/
+
+void
+OpcGenerateAmlOpcode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT16 Index;
+
+
+ Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
+
+ Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode;
+ Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype;
+ Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
+
+ if (!Op->Asl.Value.Integer)
+ {
+ Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
+ }
+
+ /* Special handling for some opcodes */
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_INTEGER:
+ /*
+ * Set the opcode based on the size of the integer
+ */
+ (void) OpcSetOptimalIntegerSize (Op);
+ break;
+
+ case PARSEOP_OFFSET:
+
+ Op->Asl.AmlOpcodeLength = 1;
+ break;
+
+ case PARSEOP_ACCESSAS:
+
+ OpcDoAccessAs (Op);
+ break;
+
+ case PARSEOP_CONNECTION:
+
+ OpcDoConnection (Op);
+ break;
+
+ case PARSEOP_EISAID:
+
+ OpcDoEisaId (Op);
+ break;
+
+ case PARSEOP_PRINTF:
+
+ OpcDoPrintf (Op);
+ break;
+
+ case PARSEOP_FPRINTF:
+
+ OpcDoFprintf (Op);
+ break;
+
+ case PARSEOP_TOPLD:
+
+ OpcDoPld (Op);
+ break;
+
+ case PARSEOP_TOUUID:
+
+ OpcDoUuId (Op);
+ break;
+
+ case PARSEOP_UNICODE:
+
+ OpcDoUnicode (Op);
+ break;
+
+ case PARSEOP_INCLUDE:
+
+ Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ Gbl_HasIncludeFiles = TRUE;
+ break;
+
+ case PARSEOP_EXTERNAL:
+
+ Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ break;
+
+ case PARSEOP_TIMER:
+
+ if (AcpiGbl_IntegerBitWidth == 32)
+ {
+ AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
+ }
+ break;
+
+ default:
+
+ /* Nothing to do for other opcodes */
+
+ break;
+ }
+
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asloperands.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloperands.c
new file mode 100644
index 0000000000..5b16ea16e7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloperands.c
@@ -0,0 +1,1199 @@
+/******************************************************************************
+ *
+ * Module Name: asloperands - AML operand processing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asloperands")
+
+/* Local prototypes */
+
+static void
+OpnDoField (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoBankField (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoBuffer (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoDefinitionBlock (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoFieldCommon (
+ ACPI_PARSE_OBJECT *FieldOp,
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoIndexField (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoLoadTable (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoMutex (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnDoRegion (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+OpnAttachNameToNode (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoMutex
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the operands for the MUTEX ASL keyword.
+ *
+ ******************************************************************************/
+
+static void
+OpnDoMutex (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ Next = Op->Asl.Child;
+ Next = Next->Asl.Next;
+
+ if (Next->Asl.Value.Integer > 15)
+ {
+ AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
+ }
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoMethod
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the operands for the METHOD ASL keyword.
+ *
+ ******************************************************************************/
+
+static void
+OpnDoMethod (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+ /* Optional arguments for this opcode with defaults */
+
+ UINT8 NumArgs = 0;
+ UINT8 Serialized = 0;
+ UINT8 Concurrency = 0;
+ UINT8 MethodFlags;
+
+
+ /* Opcode and package length first */
+ /* Method name */
+
+ Next = Op->Asl.Child;
+
+ /* Num args */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ NumArgs = (UINT8) Next->Asl.Value.Integer;
+ Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ }
+
+ /* Serialized Flag */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Serialized = (UINT8) Next->Asl.Value.Integer;
+ Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ }
+
+ /* Concurrency value (valid values are 0-15) */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* This is a ByteConstExpr, so eval the constant now */
+
+ OpcAmlConstantWalk (Next, 0, NULL);
+
+ if (Next->Asl.Value.Integer > 15)
+ {
+ AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
+ }
+ Concurrency = (UINT8) Next->Asl.Value.Integer;
+ }
+
+ /* Put the bits in their proper places */
+
+ MethodFlags = (UINT8) ((NumArgs & 0x7) |
+ ((Serialized & 0x1) << 3) |
+ ((Concurrency & 0xF) << 4));
+
+ /* Use the last node for the combined flags byte */
+
+ Next->Asl.Value.Integer = MethodFlags;
+ Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ Next->Asl.AmlLength = 1;
+ Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+
+ /* Save the arg count in the first node */
+
+ Op->Asl.Extra = NumArgs;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoFieldCommon
+ *
+ * PARAMETERS: FieldOp - Node for an ASL field
+ * Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the various field keywords,
+ * FIELD, BANKFIELD, INDEXFIELD
+ *
+ ******************************************************************************/
+
+static void
+OpnDoFieldCommon (
+ ACPI_PARSE_OBJECT *FieldOp,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_PARSE_OBJECT *PkgLengthNode;
+ UINT32 CurrentBitOffset;
+ UINT32 NewBitOffset;
+ UINT8 AccessType;
+ UINT8 LockRule;
+ UINT8 UpdateRule;
+ UINT8 FieldFlags;
+ UINT32 MinimumLength;
+
+
+ /* AccessType -- not optional, so no need to check for DEFAULT_ARG */
+
+ AccessType = (UINT8) Op->Asl.Value.Integer;
+ Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+
+ /* Set the access type in the parent (field) node for use later */
+
+ FieldOp->Asl.Value.Integer = AccessType;
+
+ /* LockRule -- not optional, so no need to check for DEFAULT_ARG */
+
+ Next = Op->Asl.Next;
+ LockRule = (UINT8) Next->Asl.Value.Integer;
+ Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+
+ /* UpdateRule -- not optional, so no need to check for DEFAULT_ARG */
+
+ Next = Next->Asl.Next;
+ UpdateRule = (UINT8) Next->Asl.Value.Integer;
+
+ /*
+ * Generate the flags byte. The various fields are already
+ * in the right bit position via translation from the
+ * keywords by the parser.
+ */
+ FieldFlags = (UINT8) (AccessType | LockRule | UpdateRule);
+
+ /* Use the previous node to be the FieldFlags node */
+
+ /* Set the node to RAW_DATA */
+
+ Next->Asl.Value.Integer = FieldFlags;
+ Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ Next->Asl.AmlLength = 1;
+ Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+
+ /* Process the FieldUnitList */
+
+ Next = Next->Asl.Next;
+ CurrentBitOffset = 0;
+
+ while (Next)
+ {
+ /* Save the offset of this field unit */
+
+ Next->Asl.ExtraValue = CurrentBitOffset;
+
+ switch (Next->Asl.ParseOpcode)
+ {
+ case PARSEOP_ACCESSAS:
+
+ PkgLengthNode = Next->Asl.Child;
+ AccessType = (UINT8) PkgLengthNode->Asl.Value.Integer;
+
+ /* Nothing additional to do */
+ break;
+
+ case PARSEOP_OFFSET:
+
+ /* New offset into the field */
+
+ PkgLengthNode = Next->Asl.Child;
+ NewBitOffset = ((UINT32) PkgLengthNode->Asl.Value.Integer) * 8;
+
+ /*
+ * Examine the specified offset in relation to the
+ * current offset counter.
+ */
+ if (NewBitOffset < CurrentBitOffset)
+ {
+ /*
+ * Not allowed to specify a backwards offset!
+ * Issue error and ignore this node.
+ */
+ AslError (ASL_ERROR, ASL_MSG_BACKWARDS_OFFSET, PkgLengthNode,
+ NULL);
+ Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ }
+ else if (NewBitOffset == CurrentBitOffset)
+ {
+ /*
+ * Offset is redundant; we don't need to output an
+ * offset opcode. Just set these nodes to default
+ */
+ Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ }
+ else
+ {
+ /*
+ * Valid new offset - set the value to be inserted into the AML
+ * and update the offset counter.
+ */
+ PkgLengthNode->Asl.Value.Integer =
+ NewBitOffset - CurrentBitOffset;
+ CurrentBitOffset = NewBitOffset;
+ }
+ break;
+
+ case PARSEOP_NAMESEG:
+ case PARSEOP_RESERVED_BYTES:
+
+ /* Named or reserved field entry */
+
+ PkgLengthNode = Next->Asl.Child;
+ NewBitOffset = (UINT32) PkgLengthNode->Asl.Value.Integer;
+ CurrentBitOffset += NewBitOffset;
+
+ /* Save the current AccessAs value for error checking later */
+
+ switch (AccessType)
+ {
+ case AML_FIELD_ACCESS_ANY:
+ case AML_FIELD_ACCESS_BYTE:
+ case AML_FIELD_ACCESS_BUFFER:
+ default:
+
+ MinimumLength = 8;
+ break;
+
+ case AML_FIELD_ACCESS_WORD:
+ MinimumLength = 16;
+ break;
+
+ case AML_FIELD_ACCESS_DWORD:
+ MinimumLength = 32;
+ break;
+
+ case AML_FIELD_ACCESS_QWORD:
+ MinimumLength = 64;
+ break;
+ }
+
+ PkgLengthNode->Asl.ExtraValue = MinimumLength;
+ break;
+
+ default:
+
+ /* All supported field opcodes must appear above */
+
+ break;
+ }
+
+ /* Move on to next entry in the field list */
+
+ Next = Next->Asl.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoField
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the FIELD ASL keyword
+ *
+ ******************************************************************************/
+
+static void
+OpnDoField (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Opcode is parent node */
+ /* First child is field name */
+
+ Next = Op->Asl.Child;
+
+ /* Second child is the AccessType */
+
+ OpnDoFieldCommon (Op, Next->Asl.Next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoIndexField
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the INDEXFIELD ASL keyword
+ *
+ ******************************************************************************/
+
+static void
+OpnDoIndexField (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Opcode is parent node */
+ /* First child is the index name */
+
+ Next = Op->Asl.Child;
+
+ /* Second child is the data name */
+
+ Next = Next->Asl.Next;
+
+ /* Third child is the AccessType */
+
+ OpnDoFieldCommon (Op, Next->Asl.Next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoBankField
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the BANKFIELD ASL keyword
+ *
+ ******************************************************************************/
+
+static void
+OpnDoBankField (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Opcode is parent node */
+ /* First child is the region name */
+
+ Next = Op->Asl.Child;
+
+ /* Second child is the bank name */
+
+ Next = Next->Asl.Next;
+
+ /* Third child is the bank value */
+
+ Next = Next->Asl.Next;
+
+ /* Fourth child is the AccessType */
+
+ OpnDoFieldCommon (Op, Next->Asl.Next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoRegion
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Tries to get the length of the region. Can only do this at
+ * compile time if the length is a constant.
+ *
+ ******************************************************************************/
+
+static void
+OpnDoRegion (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Opcode is parent node */
+ /* First child is the region name */
+
+ Next = Op->Asl.Child;
+
+ /* Second child is the space ID*/
+
+ Next = Next->Asl.Next;
+
+ /* Third child is the region offset */
+
+ Next = Next->Asl.Next;
+
+ /* Fourth child is the region length */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ Op->Asl.Value.Integer = Next->Asl.Value.Integer;
+ }
+ else
+ {
+ Op->Asl.Value.Integer = ACPI_UINT64_MAX;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoBuffer
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the BUFFER ASL keyword. We
+ * build a single raw byte buffer from the initialization nodes,
+ * each parse node contains a buffer byte.
+ *
+ ******************************************************************************/
+
+static void
+OpnDoBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *BufferLengthOp;
+
+ /* Optional arguments for this opcode with defaults */
+
+ UINT32 BufferLength = 0;
+
+
+ /* Opcode and package length first */
+ /* Buffer Length is next, followed by the initializer list */
+
+ BufferLengthOp = Op->Asl.Child;
+ InitializerOp = BufferLengthOp->Asl.Next;
+
+ /*
+ * If the BufferLength is not an INTEGER or was not specified in the ASL
+ * (DEFAULT_ARG), it is a TermArg that is
+ * evaluated at run-time, and we are therefore finished.
+ */
+ if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) &&
+ (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+ {
+ return;
+ }
+
+ /*
+ * We want to count the number of items in the initializer list, because if
+ * it is larger than the buffer length, we will define the buffer size
+ * to be the size of the initializer list (as per the ACPI Specification)
+ */
+ switch (InitializerOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_INTEGER:
+ case PARSEOP_BYTECONST:
+ case PARSEOP_WORDCONST:
+ case PARSEOP_DWORDCONST:
+
+ /* The peer list contains the byte list (if any...) */
+
+ while (InitializerOp)
+ {
+ /* For buffers, this is a list of raw bytes */
+
+ InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ InitializerOp->Asl.AmlLength = 1;
+ InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+
+ BufferLength++;
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+ }
+ break;
+
+ case PARSEOP_STRING_LITERAL:
+
+ /*
+ * Only one initializer, the string. Buffer must be big enough to hold
+ * the string plus the null termination byte
+ */
+ BufferLength = strlen (InitializerOp->Asl.Value.String) + 1;
+
+ InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ InitializerOp->Asl.AmlLength = BufferLength;
+ InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+ break;
+
+ case PARSEOP_RAW_DATA:
+
+ /* Buffer nodes are already initialized (e.g. Unicode operator) */
+ return;
+
+ case PARSEOP_DEFAULT_ARG:
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp,
+ "Unknown buffer initializer opcode");
+ printf ("Unknown buffer initializer opcode [%s]\n",
+ UtGetOpName (InitializerOp->Asl.ParseOpcode));
+ return;
+ }
+
+ /* Check if initializer list is longer than the buffer length */
+
+ if (BufferLengthOp->Asl.Value.Integer > BufferLength)
+ {
+ BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer;
+ }
+
+ if (!BufferLength)
+ {
+ /* No length AND no items -- issue notice */
+
+ AslError (ASL_REMARK, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL);
+
+ /* But go ahead and put the buffer length of zero into the AML */
+ }
+
+ /*
+ * Just set the buffer size node to be the buffer length, regardless
+ * of whether it was previously an integer or a default_arg placeholder
+ */
+ BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
+ BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
+ BufferLengthOp->Asl.Value.Integer = BufferLength;
+
+ (void) OpcSetOptimalIntegerSize (BufferLengthOp);
+
+ /* Remaining nodes are handled via the tree walk */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoPackage
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the PACKAGE ASL keyword. NOTE:
+ * can only be called after constants have been folded, to ensure
+ * that the PackageLength operand has been fully reduced.
+ *
+ ******************************************************************************/
+
+void
+OpnDoPackage (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *PackageLengthOp;
+ UINT32 PackageLength = 0;
+
+
+ /* Opcode and package length first, followed by the initializer list */
+
+ PackageLengthOp = Op->Asl.Child;
+ InitializerOp = PackageLengthOp->Asl.Next;
+
+ /* Count the number of items in the initializer list */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* The peer list contains the byte list (if any...) */
+
+ while (InitializerOp)
+ {
+ PackageLength++;
+ InitializerOp = InitializerOp->Asl.Next;
+ }
+ }
+
+ /* If package length is a constant, compare to the initializer list */
+
+ if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
+ (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST))
+ {
+ if (PackageLengthOp->Asl.Value.Integer > PackageLength)
+ {
+ /*
+ * Allow package length to be longer than the initializer
+ * list -- but if the length of initializer list is nonzero,
+ * issue a message since this is probably a coding error,
+ * even though technically legal.
+ */
+ if (PackageLength > 0)
+ {
+ AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT,
+ PackageLengthOp, NULL);
+ }
+
+ PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer;
+ }
+ else if (PackageLengthOp->Asl.Value.Integer < PackageLength)
+ {
+ /*
+ * The package length is smaller than the length of the
+ * initializer list. This is an error as per the ACPI spec.
+ */
+ AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG,
+ PackageLengthOp, NULL);
+ }
+ }
+
+ if (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /*
+ * This is the case if the PackageLength was left empty - Package()
+ * The package length becomes the length of the initializer list
+ */
+ Op->Asl.Child->Asl.ParseOpcode = PARSEOP_INTEGER;
+ Op->Asl.Child->Asl.Value.Integer = PackageLength;
+
+ /* Set the AML opcode */
+
+ (void) OpcSetOptimalIntegerSize (Op->Asl.Child);
+ }
+
+ /* If not a variable-length package, check for a zero package length */
+
+ if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
+ (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST) ||
+ (PackageLengthOp->Asl.ParseOpcode == PARSEOP_ZERO) ||
+ (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG))
+ {
+ if (!PackageLength)
+ {
+ /* No length AND no initializer list -- issue a remark */
+
+ AslError (ASL_REMARK, ASL_MSG_PACKAGE_LENGTH,
+ PackageLengthOp, NULL);
+
+ /* But go ahead and put the buffer length of zero into the AML */
+ }
+ }
+
+ /*
+ * If the PackageLength is a constant <= 255, we can change the
+ * AML opcode from VarPackage to a simple (ACPI 1.0) Package opcode.
+ */
+ if (((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
+ (Op->Asl.Child->Asl.Value.Integer <= 255)) ||
+ (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONE) ||
+ (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONES)||
+ (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ZERO))
+ {
+ Op->Asl.AmlOpcode = AML_PACKAGE_OP;
+ Op->Asl.ParseOpcode = PARSEOP_PACKAGE;
+
+ /*
+ * Just set the package size node to be the package length, regardless
+ * of whether it was previously an integer or a default_arg placeholder
+ */
+ PackageLengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+ PackageLengthOp->Asl.AmlLength = 1;
+ PackageLengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+ PackageLengthOp->Asl.Value.Integer = PackageLength;
+ }
+
+ /* Remaining nodes are handled via the tree walk */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoLoadTable
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the LOADTABLE ASL keyword.
+ *
+ ******************************************************************************/
+
+static void
+OpnDoLoadTable (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ /* Opcode is parent node */
+ /* First child is the table signature */
+
+ Next = Op->Asl.Child;
+
+ /* Second child is the OEM ID*/
+
+ Next = Next->Asl.Next;
+
+ /* Third child is the OEM table ID */
+
+ Next = Next->Asl.Next;
+
+ /* Fourth child is the RootPath string */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ Next->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
+ Next->Asl.Value.String = "\\";
+ Next->Asl.AmlLength = 2;
+ OpcGenerateAmlOpcode (Next);
+ }
+
+#ifdef ASL_FUTURE_IMPLEMENTATION
+
+ /* TBD: NOT IMPLEMENTED */
+ /* Fifth child is the [optional] ParameterPathString */
+ /* Sixth child is the [optional] ParameterData */
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode == DEFAULT_ARG)
+ {
+ Next->Asl.AmlLength = 1;
+ Next->Asl.ParseOpcode = ZERO;
+ OpcGenerateAmlOpcode (Next);
+ }
+
+
+ Next = Next->Asl.Next;
+ if (Next->Asl.ParseOpcode == DEFAULT_ARG)
+ {
+ Next->Asl.AmlLength = 1;
+ Next->Asl.ParseOpcode = ZERO;
+ OpcGenerateAmlOpcode (Next);
+ }
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnDoDefinitionBlock
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct the AML operands for the DEFINITIONBLOCK ASL keyword
+ *
+ ******************************************************************************/
+
+static void
+OpnDoDefinitionBlock (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_SIZE Length;
+ UINT32 i;
+ char *Filename;
+
+
+ /*
+ * These nodes get stuffed into the table header. They are special
+ * cased when the table is written to the output file.
+ *
+ * Mark all of these nodes as non-usable so they won't get output
+ * as AML opcodes!
+ */
+
+ /* Get AML filename. Use it if non-null */
+
+ Child = Op->Asl.Child;
+ if (Child->Asl.Value.Buffer &&
+ *Child->Asl.Value.Buffer &&
+ (Gbl_UseDefaultAmlFilename))
+ {
+ /*
+ * We will use the AML filename that is embedded in the source file
+ * for the output filename.
+ */
+ Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) +
+ strlen ((char *) Child->Asl.Value.Buffer) + 1);
+
+ /* Prepend the current directory path */
+
+ strcpy (Filename, Gbl_DirectoryPath);
+ strcat (Filename, (char *) Child->Asl.Value.Buffer);
+
+ Gbl_OutputFilenamePrefix = Filename;
+ UtConvertBackslashes (Gbl_OutputFilenamePrefix);
+ }
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+
+ /* Signature */
+
+ Child = Child->Asl.Next;
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ if (Child->Asl.Value.String)
+ {
+ Gbl_TableSignature = Child->Asl.Value.String;
+ if (strlen (Gbl_TableSignature) != ACPI_NAME_SIZE)
+ {
+ AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
+ "Length is not exactly 4");
+ }
+
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (!isalnum ((int) Gbl_TableSignature[i]))
+ {
+ AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
+ "Contains non-alphanumeric characters");
+ }
+ }
+ }
+
+ /* Revision */
+
+ Child = Child->Asl.Next;
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ /*
+ * We used the revision to set the integer width earlier
+ */
+
+ /* OEMID */
+
+ Child = Child->Asl.Next;
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+
+ /* OEM TableID */
+
+ Child = Child->Asl.Next;
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ if (Child->Asl.Value.String)
+ {
+ Length = strlen (Child->Asl.Value.String);
+ Gbl_TableId = UtStringCacheCalloc (Length + 1);
+ strcpy (Gbl_TableId, Child->Asl.Value.String);
+
+ /*
+ * Convert anything non-alphanumeric to an underscore. This
+ * allows us to use the TableID to generate unique C symbols.
+ */
+ for (i = 0; i < Length; i++)
+ {
+ if (!isalnum ((int) Gbl_TableId[i]))
+ {
+ Gbl_TableId[i] = '_';
+ }
+ }
+ }
+
+ /* OEM Revision */
+
+ Child = Child->Asl.Next;
+ Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtGetArg
+ *
+ * PARAMETERS: Op - Get an argument for this op
+ * Argn - Nth argument to get
+ *
+ * RETURN: The argument (as an Op object). NULL if argument does not exist
+ *
+ * DESCRIPTION: Get the specified op's argument (peer)
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+UtGetArg (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Argn)
+{
+ ACPI_PARSE_OBJECT *Arg = NULL;
+
+
+ /* Get the requested argument object */
+
+ Arg = Op->Asl.Child;
+ while (Arg && Argn)
+ {
+ Argn--;
+ Arg = Arg->Asl.Next;
+ }
+
+ return (Arg);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnAttachNameToNode
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: For the named ASL/AML operators, get the actual name from the
+ * argument list and attach it to the parent node so that we
+ * can get to it quickly later.
+ *
+ ******************************************************************************/
+
+static void
+OpnAttachNameToNode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Child = NULL;
+
+
+ if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
+ {
+ Child = UtGetArg (Op, 0);
+ }
+ else switch (Op->Asl.AmlOpcode)
+ {
+ case AML_DATA_REGION_OP:
+ case AML_DEVICE_OP:
+ case AML_EVENT_OP:
+ case AML_METHOD_OP:
+ case AML_MUTEX_OP:
+ case AML_REGION_OP:
+ case AML_POWER_RES_OP:
+ case AML_PROCESSOR_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_NAME_OP:
+ case AML_SCOPE_OP:
+
+ Child = UtGetArg (Op, 0);
+ break;
+
+ case AML_ALIAS_OP:
+
+ Child = UtGetArg (Op, 1);
+ break;
+
+ case AML_CREATE_BIT_FIELD_OP:
+ case AML_CREATE_BYTE_FIELD_OP:
+ case AML_CREATE_WORD_FIELD_OP:
+ case AML_CREATE_DWORD_FIELD_OP:
+ case AML_CREATE_QWORD_FIELD_OP:
+
+ Child = UtGetArg (Op, 2);
+ break;
+
+ case AML_CREATE_FIELD_OP:
+
+ Child = UtGetArg (Op, 3);
+ break;
+
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_FIELD_OP:
+
+ return;
+
+ default:
+
+ return;
+ }
+
+ if (Child)
+ {
+ UtAttachNamepathToOwner (Op, Child);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpnGenerateAmlOperands
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
+ * complex AML opcodes require processing of the child nodes
+ * (arguments/operands).
+ *
+ ******************************************************************************/
+
+void
+OpnGenerateAmlOperands (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+
+ if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
+ {
+ return;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ OpnDoDefinitionBlock (Op);
+ break;
+
+ case PARSEOP_METHOD:
+
+ OpnDoMethod (Op);
+ break;
+
+ case PARSEOP_MUTEX:
+
+ OpnDoMutex (Op);
+ break;
+
+ case PARSEOP_FIELD:
+
+ OpnDoField (Op);
+ break;
+
+ case PARSEOP_INDEXFIELD:
+
+ OpnDoIndexField (Op);
+ break;
+
+ case PARSEOP_BANKFIELD:
+
+ OpnDoBankField (Op);
+ break;
+
+ case PARSEOP_BUFFER:
+
+ OpnDoBuffer (Op);
+ break;
+
+ case PARSEOP_LOADTABLE:
+
+ OpnDoLoadTable (Op);
+ break;
+
+ case PARSEOP_OPERATIONREGION:
+
+ OpnDoRegion (Op);
+ break;
+
+ case PARSEOP_RESOURCETEMPLATE:
+
+ RsDoResourceTemplate (Op);
+ break;
+
+ case PARSEOP_NAMESEG:
+ case PARSEOP_NAMESTRING:
+ case PARSEOP_METHODCALL:
+ case PARSEOP_STRING_LITERAL:
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* TBD: move */
+
+ OpnAttachNameToNode (Op);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopt.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopt.c
new file mode 100644
index 0000000000..b2d8d8bf15
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslopt.c
@@ -0,0 +1,806 @@
+/******************************************************************************
+ *
+ * Module Name: aslopt- Compiler optimizations
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslopt")
+
+
+static UINT32 OptTotal = 0;
+
+/* Local prototypes */
+
+static ACPI_STATUS
+OptSearchToRoot (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ ACPI_BUFFER *TargetPath,
+ char **NewPath);
+
+static ACPI_STATUS
+OptBuildShortestPath (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ ACPI_BUFFER *CurrentPath,
+ ACPI_BUFFER *TargetPath,
+ ACPI_SIZE AmlNameStringLength,
+ UINT8 IsDeclaration,
+ char **ReturnNewPath);
+
+static ACPI_STATUS
+OptOptimizeNameDeclaration (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ char *AmlNameString,
+ char **NewPath);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OptSearchToRoot
+ *
+ * PARAMETERS: Op - Current parser op
+ * WalkState - Current state
+ * CurrentNode - Where we are in the namespace
+ * TargetNode - Node to which we are referring
+ * TargetPath - External full path to the target node
+ * NewPath - Where the optimized path is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI
+ * name utilizing the search-to-root name resolution algorithm
+ * that is used by AML interpreters.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OptSearchToRoot (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ ACPI_BUFFER *TargetPath,
+ char **NewPath)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GENERIC_STATE ScopeInfo;
+ ACPI_STATUS Status;
+ char *Path;
+
+
+ ACPI_FUNCTION_NAME (OptSearchToRoot);
+
+
+ /*
+ * Check if search-to-root can be utilized. Use the last NameSeg of
+ * the NamePath and 1) See if can be found and 2) If found, make
+ * sure that it is the same node that we want. If there is another
+ * name in the search path before the one we want, the nodes will
+ * not match, and we cannot use this optimization.
+ */
+ Path = &(((char *) TargetPath->Pointer)[TargetPath->Length -
+ ACPI_NAME_SIZE]),
+ ScopeInfo.Scope.Node = CurrentNode;
+
+ /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */
+
+ Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &(Node));
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * We found the name, but we must check to make sure that the node
+ * matches. Otherwise, there is another identical name in the search
+ * path that precludes the use of this optimization.
+ */
+ if (Node != TargetNode)
+ {
+ /*
+ * This means that another object with the same name was found first,
+ * and we cannot use this optimization.
+ */
+ return (AE_NOT_FOUND);
+ }
+
+ /* Found the node, we can use this optimization */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "NAMESEG: %-24s", Path));
+
+ /* We must allocate a new string for the name (TargetPath gets deleted) */
+
+ *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
+ strcpy (*NewPath, Path);
+
+ if (strncmp (*NewPath, "_T_", 3))
+ {
+ AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, Op,
+ *NewPath);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OptBuildShortestPath
+ *
+ * PARAMETERS: Op - Current parser op
+ * WalkState - Current state
+ * CurrentNode - Where we are in the namespace
+ * TargetNode - Node to which we are referring
+ * CurrentPath - External full path to the current node
+ * TargetPath - External full path to the target node
+ * AmlNameStringLength - Length of the original namepath
+ * IsDeclaration - TRUE for declaration, FALSE for reference
+ * ReturnNewPath - Where the optimized path is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Build an optimal NamePath using carats
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OptBuildShortestPath (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ ACPI_BUFFER *CurrentPath,
+ ACPI_BUFFER *TargetPath,
+ ACPI_SIZE AmlNameStringLength,
+ UINT8 IsDeclaration,
+ char **ReturnNewPath)
+{
+ UINT32 NumCommonSegments;
+ UINT32 MaxCommonSegments;
+ UINT32 Index;
+ UINT32 NumCarats;
+ UINT32 i;
+ char *NewPath;
+ char *NewPathExternal;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GENERIC_STATE ScopeInfo;
+ ACPI_STATUS Status;
+ BOOLEAN SubPath = FALSE;
+
+
+ ACPI_FUNCTION_NAME (OptBuildShortestPath);
+
+
+ ScopeInfo.Scope.Node = CurrentNode;
+
+ /*
+ * Determine the maximum number of NameSegs that the Target and Current paths
+ * can possibly have in common. (To optimize, we have to have at least 1)
+ *
+ * Note: The external NamePath string lengths are always a multiple of 5
+ * (ACPI_NAME_SIZE + separator)
+ */
+ MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH;
+ if (CurrentPath->Length < TargetPath->Length)
+ {
+ MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH;
+ }
+
+ /*
+ * Determine how many NameSegs the two paths have in common.
+ * (Starting from the root)
+ */
+ for (NumCommonSegments = 0;
+ NumCommonSegments < MaxCommonSegments;
+ NumCommonSegments++)
+ {
+ /* Compare two single NameSegs */
+
+ if (!ACPI_COMPARE_NAME (
+ &((char *) TargetPath->Pointer)[
+ (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1],
+ &((char *) CurrentPath->Pointer)[
+ (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1]))
+ {
+ /* Mismatch */
+
+ break;
+ }
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u",
+ NumCommonSegments));
+
+ /* There must be at least 1 common NameSeg in order to optimize */
+
+ if (NumCommonSegments == 0)
+ {
+ return (AE_NOT_FOUND);
+ }
+
+ if (NumCommonSegments == MaxCommonSegments)
+ {
+ if (CurrentPath->Length == TargetPath->Length)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH"));
+ return (AE_NOT_FOUND);
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH"));
+ SubPath = TRUE;
+ }
+ }
+
+ /* Determine how many prefix Carats are required */
+
+ NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) -
+ NumCommonSegments;
+
+ /*
+ * Construct a new target string
+ */
+ NewPathExternal = ACPI_ALLOCATE_ZEROED (
+ TargetPath->Length + NumCarats + 1);
+
+ /* Insert the Carats into the Target string */
+
+ for (i = 0; i < NumCarats; i++)
+ {
+ NewPathExternal[i] = AML_PARENT_PREFIX;
+ }
+
+ /*
+ * Copy only the necessary (optimal) segments from the original
+ * target string
+ */
+ Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1;
+
+ /* Special handling for exact subpath in a name declaration */
+
+ if (IsDeclaration && SubPath && (CurrentPath->Length > TargetPath->Length))
+ {
+ /*
+ * The current path is longer than the target, and the target is a
+ * subpath of the current path. We must include one more NameSeg of
+ * the target path
+ */
+ Index -= ACPI_PATH_SEGMENT_LENGTH;
+
+ /* Special handling for Scope() operator */
+
+ if (Op->Asl.AmlOpcode == AML_SCOPE_OP)
+ {
+ NewPathExternal[i] = AML_PARENT_PREFIX;
+ i++;
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)"));
+ }
+ }
+
+ /* Make sure we haven't gone off the end of the target path */
+
+ if (Index > TargetPath->Length)
+ {
+ Index = TargetPath->Length;
+ }
+
+ strcpy (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]);
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal));
+
+ /*
+ * Internalize the new target string and check it against the original
+ * string to make sure that this is in fact an optimization. If the
+ * original string is already optimal, there is no point in continuing.
+ */
+ Status = AcpiNsInternalizeName (NewPathExternal, &NewPath);
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status, "Internalizing new NamePath",
+ ASL_NO_ABORT);
+ ACPI_FREE (NewPathExternal);
+ return (Status);
+ }
+
+ if (strlen (NewPath) >= AmlNameStringLength)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ " NOT SHORTER (New %u old %u)",
+ (UINT32) strlen (NewPath), (UINT32) AmlNameStringLength));
+ ACPI_FREE (NewPathExternal);
+ return (AE_NOT_FOUND);
+ }
+
+ /*
+ * Check to make sure that the optimization finds the node we are
+ * looking for. This is simply a sanity check on the new
+ * path that has been created.
+ */
+ Status = AcpiNsLookup (&ScopeInfo, NewPath,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Found the namepath, but make sure the node is correct */
+
+ if (Node == TargetNode)
+ {
+ /* The lookup matched the node, accept this optimization */
+
+ AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
+ Op, NewPathExternal);
+ *ReturnNewPath = NewPath;
+ }
+ else
+ {
+ /* Node is not correct, do not use this optimization */
+
+ Status = AE_NOT_FOUND;
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE"));
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
+ "Not using optimized name - found wrong node");
+ }
+ }
+ else
+ {
+ /* The lookup failed, we obviously cannot use this optimization */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND"));
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
+ "Not using optimized name - did not find node");
+ }
+
+ ACPI_FREE (NewPathExternal);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OptOptimizeNameDeclaration
+ *
+ * PARAMETERS: Op - Current parser op
+ * WalkState - Current state
+ * CurrentNode - Where we are in the namespace
+ * AmlNameString - Unoptimized namepath
+ * NewPath - Where the optimized path is returned
+ *
+ * RETURN: Status. AE_OK If path is optimized
+ *
+ * DESCRIPTION: Perform a simple optimization of removing an extraneous
+ * backslash prefix if we are already at the root scope.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OptOptimizeNameDeclaration (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *CurrentNode,
+ ACPI_NAMESPACE_NODE *TargetNode,
+ char *AmlNameString,
+ char **NewPath)
+{
+ ACPI_STATUS Status;
+ char *NewPathExternal;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration);
+
+
+ if (((CurrentNode == AcpiGbl_RootNode) ||
+ (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK)) &&
+ (ACPI_IS_ROOT_PREFIX (AmlNameString[0])))
+ {
+ /*
+ * The current scope is the root, and the namepath has a root prefix
+ * that is therefore extraneous. Remove it.
+ */
+ *NewPath = &AmlNameString[1];
+
+ /* Debug output */
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath,
+ NULL, &NewPathExternal);
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
+ ASL_NO_ABORT);
+ return (Status);
+ }
+
+ /*
+ * Check to make sure that the optimization finds the node we are
+ * looking for. This is simply a sanity check on the new
+ * path that has been created.
+ *
+ * We know that we are at the root, so NULL is used for the scope.
+ */
+ Status = AcpiNsLookup (NULL, *NewPath,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Found the namepath, but make sure the node is correct */
+
+ if (Node == TargetNode)
+ {
+ /* The lookup matched the node, accept this optimization */
+
+ AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
+ Op, NewPathExternal);
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "AT ROOT: %-24s", NewPathExternal));
+ }
+ else
+ {
+ /* Node is not correct, do not use this optimization */
+
+ Status = AE_NOT_FOUND;
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ " ***** WRONG NODE"));
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
+ "Not using optimized name - found wrong node");
+ }
+ }
+ else
+ {
+ /* The lookup failed, we obviously cannot use this optimization */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ " ***** NOT FOUND"));
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
+ "Not using optimized name - did not find node");
+ }
+
+ ACPI_FREE (NewPathExternal);
+ return (Status);
+ }
+
+ /* Could not optimize */
+
+ return (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OptOptimizeNamePath
+ *
+ * PARAMETERS: Op - Current parser op
+ * Flags - Opcode info flags
+ * WalkState - Current state
+ * AmlNameString - Unoptimized namepath
+ * TargetNode - Node to which AmlNameString refers
+ *
+ * RETURN: None. If path is optimized, the Op is updated with new path
+ *
+ * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length.
+ * Must take into account both the current location in the
+ * namespace and the actual reference path.
+ *
+ ******************************************************************************/
+
+void
+OptOptimizeNamePath (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Flags,
+ ACPI_WALK_STATE *WalkState,
+ char *AmlNameString,
+ ACPI_NAMESPACE_NODE *TargetNode)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER TargetPath;
+ ACPI_BUFFER CurrentPath;
+ ACPI_SIZE AmlNameStringLength;
+ ACPI_NAMESPACE_NODE *CurrentNode;
+ char *ExternalNameString;
+ char *NewPath = NULL;
+ ACPI_SIZE HowMuchShorter;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ ACPI_FUNCTION_TRACE (OptOptimizeNamePath);
+
+
+ /* This is an optional optimization */
+
+ if (!Gbl_ReferenceOptimizationFlag)
+ {
+ return_VOID;
+ }
+
+ /* Various required items */
+
+ if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent)
+ {
+ return_VOID;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "PATH OPTIMIZE: Line %5d ParentOp [%12.12s] ThisOp [%12.12s] ",
+ Op->Asl.LogicalLineNumber,
+ AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode),
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
+
+ if (!(Flags & (AML_NAMED | AML_CREATE)))
+ {
+ if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
+ {
+ /* We don't want to fuss with actual name declaration nodes here */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "******* NAME DECLARATION\n"));
+ return_VOID;
+ }
+ }
+
+ /*
+ * The original path must be longer than one NameSeg (4 chars) for there
+ * to be any possibility that it can be optimized to a shorter string
+ */
+ AmlNameStringLength = strlen (AmlNameString);
+ if (AmlNameStringLength <= ACPI_NAME_SIZE)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "NAMESEG %4.4s\n", AmlNameString));
+ return_VOID;
+ }
+
+ /*
+ * We need to obtain the node that represents the current scope -- where
+ * we are right now in the namespace. We will compare this path
+ * against the Namepath, looking for commonality.
+ */
+ CurrentNode = AcpiGbl_RootNode;
+ if (WalkState->ScopeInfo)
+ {
+ CurrentNode = WalkState->ScopeInfo->Scope.Node;
+ }
+
+ if (Flags & (AML_NAMED | AML_CREATE))
+ {
+ /* This is the declaration of a new name */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME\n"));
+
+ /*
+ * The node of interest is the parent of this node (the containing
+ * scope). The actual namespace node may be up more than one level
+ * of parse op or it may not exist at all (if we traverse back
+ * up to the root.)
+ */
+ NextOp = Op->Asl.Parent;
+ while (NextOp && (!NextOp->Asl.Node))
+ {
+ NextOp = NextOp->Asl.Parent;
+ }
+ if (NextOp && NextOp->Asl.Node)
+ {
+ CurrentNode = NextOp->Asl.Node;
+ }
+ else
+ {
+ CurrentNode = AcpiGbl_RootNode;
+ }
+ }
+ else
+ {
+ /* This is a reference to an existing named object */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REFERENCE\n"));
+ }
+
+ /*
+ * Obtain the full paths to the two nodes that we are interested in
+ * (Target and current namespace location) in external
+ * format -- something we can easily manipulate
+ */
+ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (TargetNode, &TargetPath, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status, "Getting Target NamePath",
+ ASL_NO_ABORT);
+ return_VOID;
+ }
+ TargetPath.Length--; /* Subtract one for null terminator */
+
+ /* CurrentPath is the path to this scope (where we are in the namespace) */
+
+ CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status, "Getting Current NamePath",
+ ASL_NO_ABORT);
+ return_VOID;
+ }
+ CurrentPath.Length--; /* Subtract one for null terminator */
+
+ /* Debug output only */
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString,
+ NULL, &ExternalNameString);
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
+ ASL_NO_ABORT);
+ return_VOID;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ "CURRENT SCOPE: (%2u) %-37s FULL PATH TO NAME: (%2u) %-32s ACTUAL AML:%-32s\n",
+ (UINT32) CurrentPath.Length, (char *) CurrentPath.Pointer,
+ (UINT32) TargetPath.Length, (char *) TargetPath.Pointer,
+ ExternalNameString));
+
+ ACPI_FREE (ExternalNameString);
+
+ /*
+ * Attempt an optmization depending on the type of namepath
+ */
+ if (Flags & (AML_NAMED | AML_CREATE))
+ {
+ /*
+ * This is a named opcode and the namepath is a name declaration, not
+ * a reference.
+ */
+ Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode,
+ TargetNode, AmlNameString, &NewPath);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * 2) now attempt to
+ * optimize the namestring with carats (up-arrow)
+ */
+ Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
+ TargetNode, &CurrentPath, &TargetPath,
+ AmlNameStringLength, 1, &NewPath);
+ }
+ }
+ else
+ {
+ /*
+ * This is a reference to an existing named object
+ *
+ * 1) Check if search-to-root can be utilized using the last
+ * NameSeg of the NamePath
+ */
+ Status = OptSearchToRoot (Op, WalkState, CurrentNode,
+ TargetNode, &TargetPath, &NewPath);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * 2) Search-to-root could not be used, now attempt to
+ * optimize the namestring with carats (up-arrow)
+ */
+ Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
+ TargetNode, &CurrentPath, &TargetPath,
+ AmlNameStringLength, 0, &NewPath);
+ }
+ }
+
+ /*
+ * Success from above indicates that the NamePath was successfully
+ * optimized. We need to update the parse op with the new name
+ */
+ if (ACPI_SUCCESS (Status))
+ {
+ HowMuchShorter = (AmlNameStringLength - strlen (NewPath));
+ OptTotal += HowMuchShorter;
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
+ " REDUCED BY %2u (TOTAL SAVED %2u)",
+ (UINT32) HowMuchShorter, OptTotal));
+
+ if (Flags & AML_NAMED)
+ {
+ if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
+ {
+ /*
+ * ALIAS is the only oddball opcode, the name declaration
+ * (alias name) is the second operand
+ */
+ Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath;
+ Op->Asl.Child->Asl.Next->Asl.AmlLength = strlen (NewPath);
+ }
+ else
+ {
+ Op->Asl.Child->Asl.Value.String = NewPath;
+ Op->Asl.Child->Asl.AmlLength = strlen (NewPath);
+ }
+ }
+ else if (Flags & AML_CREATE)
+ {
+ /* Name must appear as the last parameter */
+
+ NextOp = Op->Asl.Child;
+ while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
+ {
+ NextOp = NextOp->Asl.Next;
+ }
+ /* Update the parse node with the new NamePath */
+
+ NextOp->Asl.Value.String = NewPath;
+ NextOp->Asl.AmlLength = strlen (NewPath);
+ }
+ else
+ {
+ /* Update the parse node with the new NamePath */
+
+ Op->Asl.Value.String = NewPath;
+ Op->Asl.AmlLength = strlen (NewPath);
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL"));
+ }
+
+ /* Cleanup path buffers */
+
+ ACPI_FREE (TargetPath.Pointer);
+ ACPI_FREE (CurrentPath.Pointer);
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n"));
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asloptions.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloptions.c
new file mode 100644
index 0000000000..a211749c73
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asloptions.c
@@ -0,0 +1,873 @@
+/******************************************************************************
+ *
+ * Module Name: asloptions - compiler command line processing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asloption")
+
+
+/* Local prototypes */
+
+static int
+AslDoOptions (
+ int argc,
+ char **argv,
+ BOOLEAN IsResponseFile);
+
+static void
+AslMergeOptionTokens (
+ char *InBuffer,
+ char *OutBuffer);
+
+static int
+AslDoResponseFile (
+ char *Filename);
+
+
+#define ASL_TOKEN_SEPARATORS " \t\n"
+#define ASL_SUPPORTED_OPTIONS "@:b|c|d^D:e:f^gh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z"
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCommandLine
+ *
+ * PARAMETERS: argc/argv
+ *
+ * RETURN: Last argv index
+ *
+ * DESCRIPTION: Command line processing
+ *
+ ******************************************************************************/
+
+int
+AslCommandLine (
+ int argc,
+ char **argv)
+{
+ int BadCommandLine = 0;
+ ACPI_STATUS Status;
+
+
+ /* Minimum command line contains at least the command and an input file */
+
+ if (argc < 2)
+ {
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
+ Usage ();
+ exit (1);
+ }
+
+ /* Process all command line options */
+
+ BadCommandLine = AslDoOptions (argc, argv, FALSE);
+
+ if (Gbl_DoTemplates)
+ {
+ Status = DtCreateTemplates (Gbl_TemplateSignature);
+ if (ACPI_FAILURE (Status))
+ {
+ exit (-1);
+ }
+ exit (1);
+ }
+
+ /* Next parameter must be the input filename */
+
+ if (!argv[AcpiGbl_Optind] &&
+ !Gbl_DisasmFlag)
+ {
+ printf ("Missing input filename\n");
+ BadCommandLine = TRUE;
+ }
+
+ if (Gbl_DoSignon)
+ {
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
+ if (Gbl_IgnoreErrors)
+ {
+ printf ("Ignoring all errors, forcing AML file generation\n\n");
+ }
+ }
+
+ if (BadCommandLine)
+ {
+ printf ("Use -h option for help information\n");
+ exit (1);
+ }
+
+ return (AcpiGbl_Optind);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoOptions
+ *
+ * PARAMETERS: argc/argv - Standard argc/argv
+ * IsResponseFile - TRUE if executing a response file.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Command line option processing
+ *
+ ******************************************************************************/
+
+static int
+AslDoOptions (
+ int argc,
+ char **argv,
+ BOOLEAN IsResponseFile)
+{
+ ACPI_STATUS Status;
+ UINT32 j;
+
+
+ /* Get the command line options */
+
+ while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j)
+ {
+ case '@': /* Begin a response file */
+
+ if (IsResponseFile)
+ {
+ printf ("Nested command files are not supported\n");
+ return (-1);
+ }
+
+ if (AslDoResponseFile (AcpiGbl_Optarg))
+ {
+ return (-1);
+ }
+ break;
+
+ case 'b': /* Debug options */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'f':
+
+ AslCompilerdebug = 1; /* same as yydebug */
+ DtParserdebug = 1;
+ PrParserdebug = 1;
+ Gbl_DebugFlag = TRUE;
+ Gbl_KeepPreprocessorTempFile = TRUE;
+ break;
+
+ case 'p': /* Prune ASL parse tree */
+
+ /* Get the required argument */
+
+ if (AcpiGetoptArgument (argc, argv))
+ {
+ return (-1);
+ }
+
+ Gbl_PruneParseTree = TRUE;
+ Gbl_PruneDepth = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
+ break;
+
+ case 's':
+
+ Gbl_DebugFlag = TRUE;
+ break;
+
+ case 't':
+
+ /* Get the required argument */
+
+ if (AcpiGetoptArgument (argc, argv))
+ {
+ return (-1);
+ }
+
+ Gbl_PruneType = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
+ break;
+
+ default:
+
+ printf ("Unknown option: -b%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+
+ break;
+
+ case 'c':
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'r':
+
+ Gbl_NoResourceChecking = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'd': /* Disassembler */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^':
+
+ Gbl_DoCompile = FALSE;
+ break;
+
+ case 'a':
+
+ Gbl_DoCompile = FALSE;
+ Gbl_DisassembleAll = TRUE;
+ break;
+
+ case 'b': /* Do not convert buffers to resource descriptors */
+
+ AcpiGbl_NoResourceDisassembly = TRUE;
+ break;
+
+ case 'c':
+
+ break;
+
+ case 'f':
+
+ AcpiGbl_ForceAmlDisassembly = TRUE;
+ break;
+
+ case 'l': /* Use legacy ASL code (not ASL+) for disassembly */
+
+ Gbl_DoCompile = FALSE;
+ AcpiGbl_CstyleDisassembly = FALSE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -d%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+
+ Gbl_DisasmFlag = TRUE;
+ break;
+
+ case 'D': /* Define a symbol */
+
+ PrAddDefine (AcpiGbl_Optarg, NULL, TRUE);
+ break;
+
+ case 'e': /* External files for disassembler */
+
+ /* Get entire list of external files */
+
+ AcpiGbl_Optind--;
+ argv[AcpiGbl_Optind] = AcpiGbl_Optarg;
+
+ while (argv[AcpiGbl_Optind] &&
+ (argv[AcpiGbl_Optind][0] != '-'))
+ {
+ Status = AcpiDmAddToExternalFileList (argv[AcpiGbl_Optind]);
+ if (ACPI_FAILURE (Status))
+ {
+ printf ("Could not add %s to external list\n", argv[AcpiGbl_Optind]);
+ return (-1);
+ }
+
+ AcpiGbl_Optind++;
+ }
+ break;
+
+ case 'f':
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^': /* Ignore errors and force creation of aml file */
+
+ Gbl_IgnoreErrors = TRUE;
+ break;
+
+ case 'e': /* Disassembler: Get external declaration file */
+
+ if (AcpiGetoptArgument (argc, argv))
+ {
+ return (-1);
+ }
+
+ Gbl_ExternalRefFilename = AcpiGbl_Optarg;
+ break;
+
+ default:
+
+ printf ("Unknown option: -f%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'G':
+
+ Gbl_CompileGeneric = TRUE;
+ break;
+
+ case 'g': /* Get all ACPI tables */
+
+ printf ("-g option is deprecated, use acpidump utility instead\n");
+ exit (1);
+
+ case 'h':
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^':
+
+ Usage ();
+ exit (0);
+
+ case 'c':
+
+ UtDisplayConstantOpcodes ();
+ exit (0);
+
+ case 'f':
+
+ AslFilenameHelp ();
+ exit (0);
+
+ case 'r':
+
+ /* reserved names */
+
+ ApDisplayReservedNames ();
+ exit (0);
+
+ case 't':
+
+ UtDisplaySupportedTables ();
+ exit (0);
+
+ default:
+
+ printf ("Unknown option: -h%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+
+ case 'I': /* Add an include file search directory */
+
+ FlAddIncludeDirectory (AcpiGbl_Optarg);
+ break;
+
+ case 'i': /* Output AML as an include file */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'a':
+
+ /* Produce assembly code include file */
+
+ Gbl_AsmIncludeOutputFlag = TRUE;
+ break;
+
+ case 'c':
+
+ /* Produce C include file */
+
+ Gbl_C_IncludeOutputFlag = TRUE;
+ break;
+
+ case 'n':
+
+ /* Compiler/Disassembler: Ignore the NOOP operator */
+
+ AcpiGbl_IgnoreNoopOperator = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -i%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'l': /* Listing files */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^':
+
+ /* Produce listing file (Mixed source/aml) */
+
+ Gbl_ListingFlag = TRUE;
+ AcpiGbl_DmOpt_Listing = TRUE;
+ break;
+
+ case 'i':
+
+ /* Produce preprocessor output file */
+
+ Gbl_PreprocessorOutputFlag = TRUE;
+ break;
+
+ case 'm':
+
+ /* Produce hardware map summary file */
+
+ Gbl_MapfileFlag = TRUE;
+ break;
+
+ case 'n':
+
+ /* Produce namespace file */
+
+ Gbl_NsOutputFlag = TRUE;
+ break;
+
+ case 's':
+
+ /* Produce combined source file */
+
+ Gbl_SourceOutputFlag = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -l%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'm': /* Set line buffer size */
+
+ Gbl_LineBufferSize = (UINT32) strtoul (AcpiGbl_Optarg, NULL, 0) * 1024;
+ if (Gbl_LineBufferSize < ASL_DEFAULT_LINE_BUFFER_SIZE)
+ {
+ Gbl_LineBufferSize = ASL_DEFAULT_LINE_BUFFER_SIZE;
+ }
+ printf ("Line Buffer Size: %u\n", Gbl_LineBufferSize);
+ break;
+
+ case 'n': /* Parse only */
+
+ Gbl_ParseOnlyFlag = TRUE;
+ break;
+
+ case 'o': /* Control compiler AML optimizations */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'a':
+
+ /* Disable all optimizations */
+
+ Gbl_FoldConstants = FALSE;
+ Gbl_IntegerOptimizationFlag = FALSE;
+ Gbl_ReferenceOptimizationFlag = FALSE;
+ break;
+
+ case 'f':
+
+ /* Disable folding on "normal" expressions */
+
+ Gbl_FoldConstants = FALSE;
+ break;
+
+ case 'i':
+
+ /* Disable integer optimization to constants */
+
+ Gbl_IntegerOptimizationFlag = FALSE;
+ break;
+
+ case 'n':
+
+ /* Disable named reference optimization */
+
+ Gbl_ReferenceOptimizationFlag = FALSE;
+ break;
+
+ case 't':
+
+ /* Display compile time(s) */
+
+ Gbl_CompileTimesFlag = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'P': /* Preprocessor options */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^': /* Proprocess only, emit (.i) file */
+
+ Gbl_PreprocessOnly = TRUE;
+ Gbl_PreprocessorOutputFlag = TRUE;
+ break;
+
+ case 'n': /* Disable preprocessor */
+
+ Gbl_PreprocessFlag = FALSE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -P%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'p': /* Override default AML output filename */
+
+ Gbl_OutputFilenamePrefix = AcpiGbl_Optarg;
+ UtConvertBackslashes (Gbl_OutputFilenamePrefix);
+ Gbl_UseDefaultAmlFilename = FALSE;
+ break;
+
+ case 'r': /* Override revision found in table header */
+
+ Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
+ break;
+
+ case 's': /* Create AML in a source code file */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'a':
+
+ /* Produce assembly code output file */
+
+ Gbl_AsmOutputFlag = TRUE;
+ break;
+
+ case 'c':
+
+ /* Produce C hex output file */
+
+ Gbl_C_OutputFlag = TRUE;
+ break;
+
+ case 'o':
+
+ /* Produce AML offset table in C */
+
+ Gbl_C_OffsetTableFlag = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -s%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 't': /* Produce hex table output file */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case 'a':
+
+ Gbl_HexOutputFlag = HEX_OUTPUT_ASM;
+ break;
+
+ case 'c':
+
+ Gbl_HexOutputFlag = HEX_OUTPUT_C;
+ break;
+
+ case 's':
+
+ Gbl_HexOutputFlag = HEX_OUTPUT_ASL;
+ break;
+
+ default:
+
+ printf ("Unknown option: -t%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'T': /* Create a ACPI table template file */
+
+ Gbl_DoTemplates = TRUE;
+ Gbl_TemplateSignature = AcpiGbl_Optarg;
+ break;
+
+ case 'v': /* Version and verbosity settings */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^':
+
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
+ exit (0);
+
+ case 'a':
+
+ /* Disable all error/warning/remark messages */
+
+ Gbl_NoErrors = TRUE;
+ break;
+
+ case 'e':
+
+ /* Disable all warning/remark messages (errors only) */
+
+ Gbl_DisplayRemarks = FALSE;
+ Gbl_DisplayWarnings = FALSE;
+ break;
+
+ case 'i':
+ /*
+ * Support for integrated development environment(s).
+ *
+ * 1) No compiler signon
+ * 2) Send stderr messages to stdout
+ * 3) Less verbose error messages (single line only for each)
+ * 4) Error/warning messages are formatted appropriately to
+ * be recognized by MS Visual Studio
+ */
+ Gbl_VerboseErrors = FALSE;
+ Gbl_DoSignon = FALSE;
+ Gbl_Files[ASL_FILE_STDERR].Handle = stdout;
+ break;
+
+ case 'o':
+
+ Gbl_DisplayOptimizations = TRUE;
+ break;
+
+ case 'r':
+
+ Gbl_DisplayRemarks = FALSE;
+ break;
+
+ case 's':
+
+ Gbl_DoSignon = FALSE;
+ break;
+
+ case 't':
+
+ Gbl_VerboseTemplates = TRUE;
+ break;
+
+ case 'w':
+
+ /* Get the required argument */
+
+ if (AcpiGetoptArgument (argc, argv))
+ {
+ return (-1);
+ }
+
+ Status = AslDisableException (AcpiGbl_Optarg);
+ if (ACPI_FAILURE (Status))
+ {
+ return (-1);
+ }
+ break;
+
+ default:
+
+ printf ("Unknown option: -v%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'w': /* Set warning levels */
+
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '1':
+
+ Gbl_WarningLevel = ASL_WARNING;
+ break;
+
+ case '2':
+
+ Gbl_WarningLevel = ASL_WARNING2;
+ break;
+
+ case '3':
+
+ Gbl_WarningLevel = ASL_WARNING3;
+ break;
+
+ case 'e':
+
+ Gbl_WarningsAsErrors = TRUE;
+ break;
+
+ default:
+
+ printf ("Unknown option: -w%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
+ break;
+
+ case 'x': /* Set debug print output level */
+
+ AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16);
+ break;
+
+ case 'z':
+
+ Gbl_UseOriginalCompilerId = TRUE;
+ break;
+
+ default:
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslMergeOptionTokens
+ *
+ * PARAMETERS: InBuffer - Input containing an option string
+ * OutBuffer - Merged output buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove all whitespace from an option string.
+ *
+ ******************************************************************************/
+
+static void
+AslMergeOptionTokens (
+ char *InBuffer,
+ char *OutBuffer)
+{
+ char *Token;
+
+
+ *OutBuffer = 0;
+
+ Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS);
+ while (Token)
+ {
+ strcat (OutBuffer, Token);
+ Token = strtok (NULL, ASL_TOKEN_SEPARATORS);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoResponseFile
+ *
+ * PARAMETERS: Filename - Name of the response file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Open a response file and process all options within.
+ *
+ ******************************************************************************/
+
+static int
+AslDoResponseFile (
+ char *Filename)
+{
+ char *argv = StringBuffer2;
+ FILE *ResponseFile;
+ int OptStatus = 0;
+ int Opterr;
+ int Optind;
+
+
+ ResponseFile = fopen (Filename, "r");
+ if (!ResponseFile)
+ {
+ printf ("Could not open command file %s, %s\n",
+ Filename, strerror (errno));
+ return (-1);
+ }
+
+ /* Must save the current GetOpt globals */
+
+ Opterr = AcpiGbl_Opterr;
+ Optind = AcpiGbl_Optind;
+
+ /*
+ * Process all lines in the response file. There must be one complete
+ * option per line
+ */
+ while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile))
+ {
+ /* Compress all tokens, allowing us to use a single argv entry */
+
+ AslMergeOptionTokens (StringBuffer, StringBuffer2);
+
+ /* Process the option */
+
+ AcpiGbl_Opterr = 0;
+ AcpiGbl_Optind = 0;
+
+ OptStatus = AslDoOptions (1, &argv, TRUE);
+ if (OptStatus)
+ {
+ printf ("Invalid option in command file %s: %s\n",
+ Filename, StringBuffer);
+ break;
+ }
+ }
+
+ /* Restore the GetOpt globals */
+
+ AcpiGbl_Opterr = Opterr;
+ AcpiGbl_Optind = Optind;
+
+ fclose (ResponseFile);
+ return (OptStatus);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslparser.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslparser.y
new file mode 100644
index 0000000000..223a49de57
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslparser.y
@@ -0,0 +1,131 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: aslparser.y - Master Bison/Yacc input file for iASL
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslparse")
+
+/*
+ * Global Notes:
+ *
+ * October 2005: The following list terms have been optimized (from the
+ * original ASL grammar in the ACPI specification) to force the immediate
+ * reduction of each list item so that the parse stack use doesn't increase on
+ * each list element and possibly overflow on very large lists (>4000 items).
+ * This dramatically reduces use of the parse stack overall.
+ *
+ * ArgList, TermList, Objectlist, ByteList, DWordList, PackageList,
+ * ResourceMacroList, and FieldUnitList
+ */
+
+void *
+AslLocalAllocate (
+ unsigned int Size);
+
+/* Bison/yacc configuration */
+
+#define static
+#undef malloc
+#define malloc AslLocalAllocate
+#undef alloca
+#define alloca AslLocalAllocate
+#define yytname AslCompilername
+
+#define YYINITDEPTH 600 /* State stack depth */
+#define YYDEBUG 1 /* Enable debug output */
+#define YYERROR_VERBOSE 1 /* Verbose error messages */
+#define YYFLAG -32768
+
+/* Define YYMALLOC/YYFREE to prevent redefinition errors */
+
+#define YYMALLOC AslLocalAllocate
+#define YYFREE ACPI_FREE
+%}
+
+/*
+ * Declare the type of values in the grammar
+ */
+%union {
+ UINT64 i;
+ char *s;
+ ACPI_PARSE_OBJECT *n;
+}
+
+/*
+ * These shift/reduce conflicts are expected. There should be zero
+ * reduce/reduce conflicts.
+ */
+%expect 89
+
+/*! [Begin] no source code translation */
+
+/*
+ * The M4 macro processor is used to bring in the parser items,
+ * in order to keep this master file smaller, and to break up
+ * the various parser items.
+ */
+m4_define(NoEcho)
+
+/* Token types */
+
+m4_include(asltokens.y)
+
+/* Production types/names */
+
+m4_include(asltypes.y)
+%%
+
+/* Production rules */
+
+m4_include(aslrules.y)
+%%
+
+/*! [End] no source code translation !*/
+
+/* Local support functions in C */
+
+m4_include(aslsupport.y)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslpredef.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslpredef.c
new file mode 100644
index 0000000000..9a6778dc59
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslpredef.c
@@ -0,0 +1,787 @@
+/******************************************************************************
+ *
+ * Module Name: aslpredef - support for ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 ACPI_CREATE_PREDEFINED_TABLE
+#define ACPI_CREATE_RESOURCE_TABLE
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acpredef.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslpredef")
+
+
+/* Local prototypes */
+
+static void
+ApCheckForUnexpectedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+static UINT32
+ApCheckForSpecialName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedMethod
+ *
+ * PARAMETERS: Op - A parse node of type "METHOD".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If method is a predefined name, check that the number of
+ * arguments and the return type (returns a value or not)
+ * is correct.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+ApCheckForPredefinedMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ UINT32 Index;
+ UINT32 RequiredArgCount;
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ /* Check for a match against the predefined name list */
+
+ Index = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
+
+ switch (Index)
+ {
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+
+ /* Just return, nothing to do */
+ return (FALSE);
+
+
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx/_Exx/_Wxx/_Qxx methods */
+
+ Gbl_ReservedMethods++;
+
+ /* NumArguments must be zero for all _Lxx/_Exx/_Wxx/_Qxx methods */
+
+ if (MethodInfo->NumArguments != 0)
+ {
+ sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName, 0);
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
+ MsgBuffer);
+ }
+ break;
+
+
+ default:
+ /*
+ * Matched a predefined method name - validate the ASL-defined
+ * argument count against the ACPI specification.
+ *
+ * Some methods are allowed to have a "minimum" number of args
+ * (_SCP) because their definition in ACPI has changed over time.
+ */
+ Gbl_ReservedMethods++;
+ ThisName = &AcpiGbl_PredefinedMethods[Index];
+ RequiredArgCount = METHOD_GET_ARG_COUNT (ThisName->Info.ArgumentList);
+
+ if (MethodInfo->NumArguments != RequiredArgCount)
+ {
+ sprintf (MsgBuffer, "%4.4s requires %u",
+ ThisName->Info.Name, RequiredArgCount);
+
+ if (MethodInfo->NumArguments < RequiredArgCount)
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
+ MsgBuffer);
+ }
+ else if ((MethodInfo->NumArguments > RequiredArgCount) &&
+ !(ThisName->Info.ArgumentList & ARG_COUNT_IS_MINIMUM))
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
+ MsgBuffer);
+ }
+ }
+
+ /*
+ * Check if method returns no value, but the predefined name is
+ * required to return a value
+ */
+ if (MethodInfo->NumReturnNoValue &&
+ ThisName->Info.ExpectedBtypes)
+ {
+ AcpiUtGetExpectedReturnTypes (StringBuffer,
+ ThisName->Info.ExpectedBtypes);
+
+ sprintf (MsgBuffer, "%s required for %4.4s",
+ StringBuffer, ThisName->Info.Name);
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
+ MsgBuffer);
+ }
+ break;
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForUnexpectedReturnValue
+ *
+ * PARAMETERS: Op - A parse node of type "RETURN".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for an unexpected return value from a predefined method.
+ * Invoked for predefined methods that are defined to not return
+ * any value. If there is a return value, issue a remark, since
+ * the ASL writer may be confused as to the method definition
+ * and/or functionality.
+ *
+ * Note: We ignore all return values of "Zero", since this is what a standalone
+ * Return() statement will always generate -- so we ignore it here --
+ * i.e., there is no difference between Return() and Return(Zero).
+ * Also, a null Return() will be disassembled to return(Zero) -- so, we
+ * don't want to generate extraneous remarks/warnings for a disassembled
+ * ASL file.
+ *
+ ******************************************************************************/
+
+static void
+ApCheckForUnexpectedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ ACPI_PARSE_OBJECT *ReturnValueOp;
+
+
+ /* Ignore Return() and Return(Zero) (they are the same) */
+
+ ReturnValueOp = Op->Asl.Child;
+ if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ return;
+ }
+
+ /* We have a valid return value, but the reserved name did not expect it */
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_NO_RETURN_VAL,
+ Op, MethodInfo->Op->Asl.ExternalName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckPredefinedReturnValue
+ *
+ * PARAMETERS: Op - A parse node of type "RETURN".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If method is a predefined name, attempt to validate the return
+ * value. Only "static" types can be validated - a simple return
+ * of an integer/string/buffer/package or a named reference to
+ * a static object. Values such as a Localx or Argx or a control
+ * method invocation are not checked. Issue a warning if there is
+ * a valid return value, but the reserved method defines no
+ * return value.
+ *
+ ******************************************************************************/
+
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ UINT32 Index;
+ ACPI_PARSE_OBJECT *ReturnValueOp;
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ /*
+ * Check parent method for a match against the predefined name list.
+ *
+ * Note: Disable compiler errors/warnings because any errors will be
+ * caught when analyzing the parent method. Eliminates duplicate errors.
+ */
+ Gbl_AllExceptionsDisabled = TRUE;
+ Index = ApCheckForPredefinedName (MethodInfo->Op,
+ MethodInfo->Op->Asl.NameSeg);
+ Gbl_AllExceptionsDisabled = FALSE;
+
+ switch (Index)
+ {
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx/_Exx/_Wxx/_Qxx methods */
+
+ /* No return value expected, warn if there is one */
+
+ ApCheckForUnexpectedReturnValue (Op, MethodInfo);
+ return;
+
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+
+ /* Just return, nothing to do */
+ return;
+
+ default: /* A standard predefined ACPI name */
+
+ ThisName = &AcpiGbl_PredefinedMethods[Index];
+ if (!ThisName->Info.ExpectedBtypes)
+ {
+ /* No return value expected, warn if there is one */
+
+ ApCheckForUnexpectedReturnValue (Op, MethodInfo);
+ return;
+ }
+
+ /* Get the object returned, it is the next argument */
+
+ ReturnValueOp = Op->Asl.Child;
+ switch (ReturnValueOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
+ case PARSEOP_INTEGER:
+ case PARSEOP_STRING_LITERAL:
+ case PARSEOP_BUFFER:
+ case PARSEOP_PACKAGE:
+
+ /* Static data return object - check against expected type */
+
+ ApCheckObjectType (ThisName->Info.Name, ReturnValueOp,
+ ThisName->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
+
+ /* For packages, check the individual package elements */
+
+ if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_PACKAGE)
+ {
+ ApCheckPackage (ReturnValueOp, ThisName);
+ }
+ break;
+
+ default:
+ /*
+ * All other ops are very difficult or impossible to typecheck at
+ * compile time. These include all Localx, Argx, and method
+ * invocations. Also, NAMESEG and NAMESTRING because the type of
+ * any named object can be changed at runtime (for example,
+ * CopyObject will change the type of the target object.)
+ */
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedObject
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - The ACPI name to be checked
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for a predefined name for a static object (created via
+ * the ASL Name operator). If it is a predefined ACPI name, ensure
+ * that the name does not require any arguments (which would
+ * require a control method implemenation of the name), and that
+ * the type of the object is one of the expected types for the
+ * predefined name.
+ *
+ ******************************************************************************/
+
+void
+ApCheckForPredefinedObject (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+ UINT32 Index;
+ ACPI_PARSE_OBJECT *ObjectOp;
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ /*
+ * Check for a real predefined name -- not a resource descriptor name
+ * or a predefined scope name
+ */
+ Index = ApCheckForPredefinedName (Op, Name);
+
+ switch (Index)
+ {
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+
+ /* Nothing to do */
+ return;
+
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx/_Exx/_Wxx/_Qxx methods */
+
+ /*
+ * These names must be control methods, by definition in ACPI spec.
+ * Also because they are defined to return no value. None of them
+ * require any arguments.
+ */
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
+ "with zero arguments");
+ return;
+
+ default:
+
+ break;
+ }
+
+ /* A standard predefined ACPI name */
+
+ /*
+ * If this predefined name requires input arguments, then
+ * it must be implemented as a control method
+ */
+ ThisName = &AcpiGbl_PredefinedMethods[Index];
+ if (METHOD_GET_ARG_COUNT (ThisName->Info.ArgumentList) > 0)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
+ "with arguments");
+ return;
+ }
+
+ /*
+ * If no return value is expected from this predefined name, then
+ * it follows that it must be implemented as a control method
+ * (with zero args, because the args > 0 case was handled above)
+ * Examples are: _DIS, _INI, _IRC, _OFF, _ON, _PSx
+ */
+ if (!ThisName->Info.ExpectedBtypes)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
+ "with zero arguments");
+ return;
+ }
+
+ /* Typecheck the actual object, it is the next argument */
+
+ ObjectOp = Op->Asl.Child->Asl.Next;
+ ApCheckObjectType (ThisName->Info.Name, Op->Asl.Child->Asl.Next,
+ ThisName->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
+
+ /* For packages, check the individual package elements */
+
+ if (ObjectOp->Asl.ParseOpcode == PARSEOP_PACKAGE)
+ {
+ ApCheckPackage (ObjectOp, ThisName);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedName
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - NameSeg to check
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check a NameSeg against the reserved list.
+ *
+ ******************************************************************************/
+
+UINT32
+ApCheckForPredefinedName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+ UINT32 i;
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ if (Name[0] == 0)
+ {
+ AcpiOsPrintf ("Found a null name, external = %s\n",
+ Op->Asl.ExternalName);
+ }
+
+ /* All reserved names are prefixed with a single underscore */
+
+ if (Name[0] != '_')
+ {
+ return (ACPI_NOT_RESERVED_NAME);
+ }
+
+ /* Check for a standard predefined method name */
+
+ ThisName = AcpiGbl_PredefinedMethods;
+ for (i = 0; ThisName->Info.Name[0]; i++)
+ {
+ if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name))
+ {
+ /* Return index into predefined array */
+ return (i);
+ }
+
+ ThisName++; /* Does not account for extra package data, but is OK */
+ }
+
+ /* Check for resource names and predefined scope names */
+
+ ThisName = AcpiGbl_ResourceNames;
+ while (ThisName->Info.Name[0])
+ {
+ if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name))
+ {
+ return (ACPI_PREDEFINED_NAME);
+ }
+
+ ThisName++;
+ }
+
+ ThisName = AcpiGbl_ScopeNames;
+ while (ThisName->Info.Name[0])
+ {
+ if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name))
+ {
+ return (ACPI_PREDEFINED_NAME);
+ }
+
+ ThisName++;
+ }
+
+ /* Check for _Lxx/_Exx/_Wxx/_Qxx/_T_x. Warning if unknown predefined name */
+
+ return (ApCheckForSpecialName (Op, Name));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForSpecialName
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - NameSeg to check
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for the "special" predefined names -
+ * _Lxx, _Exx, _Qxx, _Wxx, and _T_x
+ *
+ ******************************************************************************/
+
+static UINT32
+ApCheckForSpecialName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+
+ /*
+ * Check for the "special" predefined names. We already know that the
+ * first character is an underscore.
+ * GPE: _Lxx
+ * GPE: _Exx
+ * GPE: _Wxx
+ * EC: _Qxx
+ */
+ if ((Name[1] == 'L') ||
+ (Name[1] == 'E') ||
+ (Name[1] == 'W') ||
+ (Name[1] == 'Q'))
+ {
+ /* The next two characters must be hex digits */
+
+ if ((isxdigit ((int) Name[2])) &&
+ (isxdigit ((int) Name[3])))
+ {
+ return (ACPI_EVENT_RESERVED_NAME);
+ }
+ }
+
+ /* Check for the names reserved for the compiler itself: _T_x */
+
+ else if ((Op->Asl.ExternalName[1] == 'T') &&
+ (Op->Asl.ExternalName[2] == '_'))
+ {
+ /* Ignore if actually emitted by the compiler */
+
+ if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
+ {
+ return (ACPI_NOT_RESERVED_NAME);
+ }
+
+ /*
+ * Was not actually emitted by the compiler. This is a special case,
+ * however. If the ASL code being compiled was the result of a
+ * dissasembly, it may possibly contain valid compiler-emitted names
+ * of the form "_T_x". We don't want to issue an error or even a
+ * warning and force the user to manually change the names. So, we
+ * will issue a remark instead.
+ */
+ AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
+ return (ACPI_COMPILER_RESERVED_NAME);
+ }
+
+ /*
+ * The name didn't match any of the known predefined names. Flag it as a
+ * warning, since the entire namespace starting with an underscore is
+ * reserved by the ACPI spec.
+ */
+ AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
+ Op->Asl.ExternalName);
+
+ return (ACPI_NOT_RESERVED_NAME);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckObjectType
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object we are checking
+ * Op - Current parse node
+ * ExpectedBtypes - Bitmap of expected return type(s)
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check if the object type is one of the types that is expected
+ * by the predefined name. Only a limited number of object types
+ * can be returned by the predefined names.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+ApCheckObjectType (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex)
+{
+ UINT32 ReturnBtype;
+ char *TypeName;
+
+
+ if (!Op)
+ {
+ return (AE_TYPE);
+ }
+
+ /* Map the parse opcode to a bitmapped return type (RTYPE) */
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
+ case PARSEOP_INTEGER:
+
+ ReturnBtype = ACPI_RTYPE_INTEGER;
+ TypeName = "Integer";
+ break;
+
+ case PARSEOP_STRING_LITERAL:
+
+ ReturnBtype = ACPI_RTYPE_STRING;
+ TypeName = "String";
+ break;
+
+ case PARSEOP_BUFFER:
+
+ ReturnBtype = ACPI_RTYPE_BUFFER;
+ TypeName = "Buffer";
+ break;
+
+ case PARSEOP_PACKAGE:
+ case PARSEOP_VAR_PACKAGE:
+
+ ReturnBtype = ACPI_RTYPE_PACKAGE;
+ TypeName = "Package";
+ break;
+
+ case PARSEOP_NAMESEG:
+ case PARSEOP_NAMESTRING:
+ /*
+ * Ignore any named references within a package object.
+ *
+ * For Package objects, references are allowed instead of any of the
+ * standard data types (Integer/String/Buffer/Package). These
+ * references are resolved at runtime. NAMESEG and NAMESTRING are
+ * impossible to typecheck at compile time because the type of
+ * any named object can be changed at runtime (for example,
+ * CopyObject will change the type of the target object).
+ */
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ return (AE_OK);
+ }
+
+ ReturnBtype = ACPI_RTYPE_REFERENCE;
+ TypeName = "Reference";
+ break;
+
+ default:
+
+ /* Not one of the supported object types */
+
+ TypeName = UtGetOpName (Op->Asl.ParseOpcode);
+ goto TypeErrorExit;
+ }
+
+ /* Exit if the object is one of the expected types */
+
+ if (ReturnBtype & ExpectedBtypes)
+ {
+ return (AE_OK);
+ }
+
+
+TypeErrorExit:
+
+ /* Format the expected types and emit an error message */
+
+ AcpiUtGetExpectedReturnTypes (StringBuffer, ExpectedBtypes);
+
+ if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ sprintf (MsgBuffer, "%4.4s: found %s, %s required",
+ PredefinedName, TypeName, StringBuffer);
+ }
+ else
+ {
+ sprintf (MsgBuffer, "%4.4s: found %s at index %u, %s required",
+ PredefinedName, TypeName, PackageIndex, StringBuffer);
+ }
+
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer);
+ return (AE_TYPE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApDisplayReservedNames
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump information about the ACPI predefined names and predefined
+ * resource descriptor names.
+ *
+ ******************************************************************************/
+
+void
+ApDisplayReservedNames (
+ void)
+{
+ const ACPI_PREDEFINED_INFO *ThisName;
+ UINT32 Count;
+ UINT32 NumTypes;
+
+
+ /*
+ * Predefined names/methods
+ */
+ printf ("\nPredefined Name Information\n\n");
+
+ Count = 0;
+ ThisName = AcpiGbl_PredefinedMethods;
+ while (ThisName->Info.Name[0])
+ {
+ AcpiUtDisplayPredefinedMethod (MsgBuffer, ThisName, FALSE);
+ Count++;
+ ThisName = AcpiUtGetNextPredefinedMethod (ThisName);
+ }
+
+ printf ("%u Predefined Names are recognized\n", Count);
+
+ /*
+ * Resource Descriptor names
+ */
+ printf ("\nPredefined Names for Resource Descriptor Fields\n\n");
+
+ Count = 0;
+ ThisName = AcpiGbl_ResourceNames;
+ while (ThisName->Info.Name[0])
+ {
+ NumTypes = AcpiUtGetResourceBitWidth (MsgBuffer,
+ ThisName->Info.ArgumentList);
+
+ printf ("%4.4s Field is %s bits wide%s\n",
+ ThisName->Info.Name, MsgBuffer,
+ (NumTypes > 1) ? " (depending on descriptor type)" : "");
+
+ Count++;
+ ThisName++;
+ }
+
+ printf ("%u Resource Descriptor Field Names are recognized\n", Count);
+
+ /*
+ * Predefined scope names
+ */
+ printf ("\nPredefined Scope/Device Names (automatically created at root)\n\n");
+
+ ThisName = AcpiGbl_ScopeNames;
+ while (ThisName->Info.Name[0])
+ {
+ printf ("%4.4s Scope/Device\n", ThisName->Info.Name);
+ ThisName++;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprepkg.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprepkg.c
new file mode 100644
index 0000000000..be0a4c4728
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprepkg.c
@@ -0,0 +1,779 @@
+/******************************************************************************
+ *
+ * Module Name: aslprepkg - support for ACPI predefined name package objects
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslprepkg")
+
+
+/* Local prototypes */
+
+static void
+ApCheckPackageElements (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Type1,
+ UINT32 Count1,
+ UINT8 Type2,
+ UINT32 Count2);
+
+static void
+ApCheckPackageList (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *ParentOp,
+ const ACPI_PREDEFINED_INFO *Package,
+ UINT32 StartIndex,
+ UINT32 Count);
+
+static void
+ApPackageTooSmall (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Count,
+ UINT32 ExpectedCount);
+
+static void
+ApZeroLengthPackage (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+ApPackageTooLarge (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Count,
+ UINT32 ExpectedCount);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckPackage
+ *
+ * PARAMETERS: ParentOp - Parser op for the package
+ * Predefined - Pointer to package-specific info for
+ * the method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Top-level validation for predefined name return package
+ * objects.
+ *
+ ******************************************************************************/
+
+void
+ApCheckPackage (
+ ACPI_PARSE_OBJECT *ParentOp,
+ const ACPI_PREDEFINED_INFO *Predefined)
+{
+ ACPI_PARSE_OBJECT *Op;
+ const ACPI_PREDEFINED_INFO *Package;
+ ACPI_STATUS Status;
+ UINT32 ExpectedCount;
+ UINT32 Count;
+ UINT32 i;
+
+
+ /* The package info for this name is in the next table entry */
+
+ Package = Predefined + 1;
+
+ /* First child is the package length */
+
+ Op = ParentOp->Asl.Child;
+ Count = (UINT32) Op->Asl.Value.Integer;
+
+ /*
+ * Many of the variable-length top-level packages are allowed to simply
+ * have zero elements. This allows the BIOS to tell the host that even
+ * though the predefined name/method exists, the feature is not supported.
+ * Other package types require one or more elements. In any case, there
+ * is no need to continue validation.
+ */
+ if (!Count)
+ {
+ switch (Package->RetInfo.Type)
+ {
+ case ACPI_PTYPE1_FIXED:
+ case ACPI_PTYPE1_OPTION:
+ case ACPI_PTYPE2_PKG_COUNT:
+ case ACPI_PTYPE2_REV_FIXED:
+
+ ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
+ break;
+
+ case ACPI_PTYPE1_VAR:
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_COUNT:
+ case ACPI_PTYPE2_FIXED:
+ case ACPI_PTYPE2_MIN:
+ case ACPI_PTYPE2_FIX_VAR:
+ case ACPI_PTYPE2_VAR_VAR:
+ default:
+
+ break;
+ }
+
+ return;
+ }
+
+ /* Get the first element of the package */
+
+ Op = Op->Asl.Next;
+
+ /* Decode the package type */
+
+ switch (Package->RetInfo.Type)
+ {
+ case ACPI_PTYPE1_FIXED:
+ /*
+ * The package count is fixed and there are no subpackages
+ *
+ * If package is too small, exit.
+ * If package is larger than expected, issue warning but continue
+ */
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+ else if (Count > ExpectedCount)
+ {
+ ApPackageTooLarge (Predefined->Info.Name, ParentOp,
+ Count, ExpectedCount);
+ }
+
+ /* Validate all elements of the package */
+
+ ApCheckPackageElements (Predefined->Info.Name, Op,
+ Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
+ break;
+
+ case ACPI_PTYPE1_VAR:
+ /*
+ * The package count is variable, there are no subpackages,
+ * and all elements must be of the same type
+ */
+ for (i = 0; i < Count; i++)
+ {
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo.ObjectType1, i);
+ Op = Op->Asl.Next;
+ }
+ break;
+
+ case ACPI_PTYPE1_OPTION:
+ /*
+ * The package count is variable, there are no subpackages.
+ * There are a fixed number of required elements, and a variable
+ * number of optional elements.
+ *
+ * Check if package is at least as large as the minimum required
+ */
+ ExpectedCount = Package->RetInfo3.Count;
+ if (Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ /* Variable number of sub-objects */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (i < Package->RetInfo3.Count)
+ {
+ /* These are the required package elements (0, 1, or 2) */
+
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo3.ObjectType[i], i);
+ }
+ else
+ {
+ /* These are the optional package elements */
+
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo3.TailObjectType, i);
+ }
+ Op = Op->Asl.Next;
+ }
+ break;
+
+ case ACPI_PTYPE2_REV_FIXED:
+
+ /* First element is the (Integer) revision */
+
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ ACPI_RTYPE_INTEGER, 0);
+
+ Op = Op->Asl.Next;
+ Count--;
+
+ /* Examine the subpackages */
+
+ ApCheckPackageList (Predefined->Info.Name, Op,
+ Package, 1, Count);
+ break;
+
+ case ACPI_PTYPE2_PKG_COUNT:
+
+ /* First element is the (Integer) count of subpackages to follow */
+
+ Status = ApCheckObjectType (Predefined->Info.Name, Op,
+ ACPI_RTYPE_INTEGER, 0);
+
+ /* We must have an integer count from above (otherwise, use Count) */
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Count cannot be larger than the parent package length, but
+ * allow it to be smaller. The >= accounts for the Integer above.
+ */
+ ExpectedCount = (UINT32) Op->Asl.Value.Integer;
+ if (ExpectedCount >= Count)
+ {
+ goto PackageTooSmall;
+ }
+
+ Count = ExpectedCount;
+ }
+
+ Op = Op->Asl.Next;
+
+ /* Examine the subpackages */
+
+ ApCheckPackageList (Predefined->Info.Name, Op,
+ Package, 1, Count);
+ break;
+
+ case ACPI_PTYPE2_UUID_PAIR:
+
+ /* The package contains a variable list of UUID Buffer/Package pairs */
+
+ /* The length of the package must be even */
+
+ if (Count & 1)
+ {
+ sprintf (MsgBuffer, "%4.4s: Package length, %d, must be even.",
+ Predefined->Info.Name, Count);
+
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
+ ParentOp->Asl.Child, MsgBuffer);
+ }
+
+ /* Validate the alternating types */
+
+ for (i = 0; i < Count; ++i)
+ {
+ if (i & 1)
+ {
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo.ObjectType2, i);
+ }
+ else
+ {
+ ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo.ObjectType1, i);
+ }
+
+ Op = Op->Asl.Next;
+ }
+
+ break;
+
+ case ACPI_PTYPE2_VAR_VAR:
+
+ /* Check for minimum size (ints at beginning + 1 subpackage) */
+
+ ExpectedCount = Package->RetInfo4.Count1 + 1;
+ if (Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ /* Check the non-package elements at beginning of main package */
+
+ for (i = 0; i < Package->RetInfo4.Count1; ++i)
+ {
+ Status = ApCheckObjectType (Predefined->Info.Name, Op,
+ Package->RetInfo4.ObjectType1, i);
+ Op = Op->Asl.Next;
+ }
+
+ /* Examine the variable-length list of subpackages */
+
+ ApCheckPackageList (Predefined->Info.Name, Op,
+ Package, Package->RetInfo4.Count1, Count);
+
+ break;
+
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_FIXED:
+ case ACPI_PTYPE2_MIN:
+ case ACPI_PTYPE2_COUNT:
+ case ACPI_PTYPE2_FIX_VAR:
+ /*
+ * These types all return a single Package that consists of a
+ * variable number of subpackages.
+ */
+
+ /* Examine the subpackages */
+
+ ApCheckPackageList (Predefined->Info.Name, Op,
+ Package, 0, Count);
+ break;
+
+ default:
+ return;
+ }
+
+ return;
+
+PackageTooSmall:
+ ApPackageTooSmall (Predefined->Info.Name, ParentOp,
+ Count, ExpectedCount);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckPackageElements
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object
+ * Op - Parser op for the package
+ * Type1 - Object type for first group
+ * Count1 - Count for first group
+ * Type2 - Object type for second group
+ * Count2 - Count for second group
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate all elements of a package. Works with packages that
+ * are defined to contain up to two groups of different object
+ * types.
+ *
+ ******************************************************************************/
+
+static void
+ApCheckPackageElements (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Type1,
+ UINT32 Count1,
+ UINT8 Type2,
+ UINT32 Count2)
+{
+ UINT32 i;
+
+
+ /*
+ * Up to two groups of package elements are supported by the data
+ * structure. All elements in each group must be of the same type.
+ * The second group can have a count of zero.
+ *
+ * Aborts check upon a NULL package element, as this means (at compile
+ * time) that the remainder of the package elements are also NULL
+ * (This is the only way to create NULL package elements.)
+ */
+ for (i = 0; (i < Count1) && Op; i++)
+ {
+ ApCheckObjectType (PredefinedName, Op, Type1, i);
+ Op = Op->Asl.Next;
+ }
+
+ for (i = 0; (i < Count2) && Op; i++)
+ {
+ ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
+ Op = Op->Asl.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckPackageList
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object
+ * ParentOp - Parser op of the parent package
+ * Package - Package info for this predefined name
+ * StartIndex - Index in parent package where list begins
+ * ParentCount - Element count of parent package
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate the individual package elements for a predefined name.
+ * Handles the cases where the predefined name is defined as a
+ * Package of Packages (subpackages). These are the types:
+ *
+ * ACPI_PTYPE2
+ * ACPI_PTYPE2_FIXED
+ * ACPI_PTYPE2_MIN
+ * ACPI_PTYPE2_COUNT
+ * ACPI_PTYPE2_FIX_VAR
+ * ACPI_PTYPE2_VAR_VAR
+ *
+ ******************************************************************************/
+
+static void
+ApCheckPackageList (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *ParentOp,
+ const ACPI_PREDEFINED_INFO *Package,
+ UINT32 StartIndex,
+ UINT32 ParentCount)
+{
+ ACPI_PARSE_OBJECT *SubPackageOp = ParentOp;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_STATUS Status;
+ UINT32 Count;
+ UINT32 ExpectedCount;
+ UINT32 i;
+ UINT32 j;
+
+
+ /*
+ * Validate each subpackage in the parent Package
+ *
+ * Note: We ignore NULL package elements on the assumption that
+ * they will be initialized by the BIOS or other ASL code.
+ */
+ for (i = 0; (i < ParentCount) && SubPackageOp; i++)
+ {
+ /* Each object in the list must be of type Package */
+
+ Status = ApCheckObjectType (PredefinedName, SubPackageOp,
+ ACPI_RTYPE_PACKAGE, i + StartIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto NextSubpackage;
+ }
+
+ /* Examine the different types of expected subpackages */
+
+ Op = SubPackageOp->Asl.Child;
+
+ /* First child is the package length */
+
+ Count = (UINT32) Op->Asl.Value.Integer;
+ Op = Op->Asl.Next;
+
+ /*
+ * Most subpackage must have at least one element, with
+ * only rare exceptions. (_RDI)
+ */
+ if (!Count &&
+ (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
+ {
+ ApZeroLengthPackage (PredefinedName, SubPackageOp);
+ goto NextSubpackage;
+ }
+
+ /*
+ * Decode the package type.
+ * PTYPE2 indicates that a "package of packages" is expected for
+ * this name. The various flavors of PTYPE2 indicate the number
+ * and format of the subpackages.
+ */
+ switch (Package->RetInfo.Type)
+ {
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_PKG_COUNT:
+ case ACPI_PTYPE2_REV_FIXED:
+
+ /* Each subpackage has a fixed number of elements */
+
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (Count < ExpectedCount)
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+ if (Count > ExpectedCount)
+ {
+ ApPackageTooLarge (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+
+ ApCheckPackageElements (PredefinedName, Op,
+ Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
+ break;
+
+ case ACPI_PTYPE2_FIX_VAR:
+ /*
+ * Each subpackage has a fixed number of elements and an
+ * optional element
+ */
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (Count < ExpectedCount)
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+
+ ApCheckPackageElements (PredefinedName, Op,
+ Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2,
+ Count - Package->RetInfo.Count1);
+ break;
+
+ case ACPI_PTYPE2_VAR_VAR:
+ /*
+ * Must have at least the minimum number elements.
+ * A zero PkgCount means the number of elements is variable.
+ */
+ ExpectedCount = Package->RetInfo4.PkgCount;
+ if (ExpectedCount && (Count < ExpectedCount))
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, 1);
+ break;
+ }
+
+ ApCheckPackageElements (PredefinedName, Op,
+ Package->RetInfo4.SubObjectTypes,
+ Package->RetInfo4.PkgCount,
+ 0, 0);
+ break;
+
+ case ACPI_PTYPE2_FIXED:
+
+ /* Each subpackage has a fixed length */
+
+ ExpectedCount = Package->RetInfo2.Count;
+ if (Count < ExpectedCount)
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+ if (Count > ExpectedCount)
+ {
+ ApPackageTooLarge (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+
+ /* Check each object/type combination */
+
+ for (j = 0; j < ExpectedCount; j++)
+ {
+ ApCheckObjectType (PredefinedName, Op,
+ Package->RetInfo2.ObjectType[j], j);
+
+ Op = Op->Asl.Next;
+ }
+ break;
+
+ case ACPI_PTYPE2_MIN:
+
+ /* Each subpackage has a variable but minimum length */
+
+ ExpectedCount = Package->RetInfo.Count1;
+ if (Count < ExpectedCount)
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+
+ /* Check the type of each subpackage element */
+
+ ApCheckPackageElements (PredefinedName, Op,
+ Package->RetInfo.ObjectType1, Count, 0, 0);
+ break;
+
+ case ACPI_PTYPE2_COUNT:
+ /*
+ * First element is the (Integer) count of elements, including
+ * the count field (the ACPI name is NumElements)
+ */
+ Status = ApCheckObjectType (PredefinedName, Op,
+ ACPI_RTYPE_INTEGER, 0);
+
+ /* We must have an integer count from above (otherwise, use Count) */
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Make sure package is large enough for the Count and is
+ * is as large as the minimum size
+ */
+ ExpectedCount = (UINT32) Op->Asl.Value.Integer;
+
+ if (Count < ExpectedCount)
+ {
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+ else if (Count > ExpectedCount)
+ {
+ ApPackageTooLarge (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ }
+
+ /* Some names of this type have a minimum length */
+
+ if (Count < Package->RetInfo.Count1)
+ {
+ ExpectedCount = Package->RetInfo.Count1;
+ ApPackageTooSmall (PredefinedName, SubPackageOp,
+ Count, ExpectedCount);
+ break;
+ }
+
+ Count = ExpectedCount;
+ }
+
+ /* Check the type of each subpackage element */
+
+ Op = Op->Asl.Next;
+ ApCheckPackageElements (PredefinedName, Op,
+ Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
+ break;
+
+ default:
+ break;
+ }
+
+NextSubpackage:
+ SubPackageOp = SubPackageOp->Asl.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApPackageTooSmall
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object
+ * Op - Current parser op
+ * Count - Actual package element count
+ * ExpectedCount - Expected package element count
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Issue error message for a package that is smaller than
+ * required.
+ *
+ ******************************************************************************/
+
+static void
+ApPackageTooSmall (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Count,
+ UINT32 ExpectedCount)
+{
+
+ sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
+ PredefinedName, Count, ExpectedCount);
+
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApZeroLengthPackage
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object
+ * Op - Current parser op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Issue error message for a zero-length package (a package that
+ * is required to have a non-zero length). Variable length
+ * packages seem to be allowed to have zero length, however.
+ * Even if not allowed, BIOS code does it.
+ *
+ ******************************************************************************/
+
+static void
+ApZeroLengthPackage (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
+
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApPackageTooLarge
+ *
+ * PARAMETERS: PredefinedName - Name of the predefined object
+ * Op - Current parser op
+ * Count - Actual package element count
+ * ExpectedCount - Expected package element count
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Issue a remark for a package that is larger than expected.
+ *
+ ******************************************************************************/
+
+static void
+ApPackageTooLarge (
+ const char *PredefinedName,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Count,
+ UINT32 ExpectedCount)
+{
+
+ sprintf (MsgBuffer, "%s: length is %u, only %u required",
+ PredefinedName, Count, ExpectedCount);
+
+ AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprintf.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprintf.c
new file mode 100644
index 0000000000..1d8d4d7fcf
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprintf.c
@@ -0,0 +1,380 @@
+/******************************************************************************
+ *
+ * Module Name: aslprintf - ASL Printf/Fprintf macro support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslprintf")
+
+
+/* Local prototypes */
+
+static void
+OpcCreateConcatenateNode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Node);
+
+static void
+OpcParsePrintf (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *DestOp);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoPrintf
+ *
+ * PARAMETERS: Op - printf parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert printf macro to a Store(..., Debug) AML operation.
+ *
+ ******************************************************************************/
+
+void
+OpcDoPrintf (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *DestOp;
+
+
+ /* Store destination is the Debug op */
+
+ DestOp = TrAllocateNode (PARSEOP_DEBUG);
+ DestOp->Asl.AmlOpcode = AML_DEBUG_OP;
+ DestOp->Asl.Parent = Op;
+ DestOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber;
+
+ OpcParsePrintf (Op, DestOp);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcDoFprintf
+ *
+ * PARAMETERS: Op - fprintf parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert fprintf macro to a Store AML operation.
+ *
+ ******************************************************************************/
+
+void
+OpcDoFprintf (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *DestOp;
+
+
+ /* Store destination is the first argument of fprintf */
+
+ DestOp = Op->Asl.Child;
+ Op->Asl.Child = DestOp->Asl.Next;
+ DestOp->Asl.Next = NULL;
+
+ OpcParsePrintf (Op, DestOp);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcParsePrintf
+ *
+ * PARAMETERS: Op - Printf parse node
+ * DestOp - Destination of Store operation
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert printf macro to a Store AML operation. The printf
+ * macro parse tree is layed out as follows:
+ *
+ * Op - printf parse op
+ * Op->Child - Format string
+ * Op->Next - Format string arguments
+ *
+ ******************************************************************************/
+
+static void
+OpcParsePrintf (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *DestOp)
+{
+ char *Format;
+ char *StartPosition = NULL;
+ ACPI_PARSE_OBJECT *ArgNode;
+ ACPI_PARSE_OBJECT *NextNode;
+ UINT32 StringLength = 0;
+ char *NewString;
+ BOOLEAN StringToProcess = FALSE;
+ ACPI_PARSE_OBJECT *NewOp;
+
+
+ /* Get format string */
+
+ Format = ACPI_CAST_PTR (char, Op->Asl.Child->Asl.Value.String);
+ ArgNode = Op->Asl.Child->Asl.Next;
+
+ /*
+ * Detach argument list so that we can use a NULL check to distinguish
+ * the first concatenation operation we need to make
+ */
+ Op->Asl.Child = NULL;
+
+ for (; *Format; ++Format)
+ {
+ if (*Format != '%')
+ {
+ if (!StringToProcess)
+ {
+ /* Mark the beginning of a string */
+
+ StartPosition = Format;
+ StringToProcess = TRUE;
+ }
+
+ ++StringLength;
+ continue;
+ }
+
+ /* Save string, if any, to new string object and concat it */
+
+ if (StringToProcess)
+ {
+ NewString = UtStringCacheCalloc (StringLength + 1);
+ strncpy (NewString, StartPosition, StringLength);
+
+ NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL);
+ NewOp->Asl.Value.String = NewString;
+ NewOp->Asl.AmlOpcode = AML_STRING_OP;
+ NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING;
+ NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber;
+
+ OpcCreateConcatenateNode(Op, NewOp);
+
+ StringLength = 0;
+ StringToProcess = FALSE;
+ }
+
+ ++Format;
+
+ /*
+ * We have a format parameter and will need an argument to go
+ * with it
+ */
+ if (!ArgNode ||
+ ArgNode->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ AslError(ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, NULL);
+ return;
+ }
+
+ /*
+ * We do not support sub-specifiers of printf (flags, width,
+ * precision, length). For specifiers we only support %x/%X for
+ * hex or %s for strings. Also, %o for generic "acpi object".
+ */
+ switch (*Format)
+ {
+ case 's':
+
+ if (ArgNode->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
+ {
+ AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgNode,
+ "String required");
+ return;
+ }
+
+ NextNode = ArgNode->Asl.Next;
+ ArgNode->Asl.Next = NULL;
+ OpcCreateConcatenateNode(Op, ArgNode);
+ ArgNode = NextNode;
+ continue;
+
+ case 'X':
+ case 'x':
+ case 'o':
+
+ NextNode = ArgNode->Asl.Next;
+ ArgNode->Asl.Next = NULL;
+
+ /*
+ * Append an empty string if the first argument is
+ * not a string. This will implicitly conver the 2nd
+ * concat source to a string per the ACPI specification.
+ */
+ if (!Op->Asl.Child)
+ {
+ NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL);
+ NewOp->Asl.Value.String = "";
+ NewOp->Asl.AmlOpcode = AML_STRING_OP;
+ NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING;
+ NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber;
+
+ OpcCreateConcatenateNode(Op, NewOp);
+ }
+
+ OpcCreateConcatenateNode(Op, ArgNode);
+ ArgNode = NextNode;
+ break;
+
+ default:
+
+ AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Op,
+ "Unrecognized format specifier");
+ continue;
+ }
+ }
+
+ /* Process any remaining string */
+
+ if (StringToProcess)
+ {
+ NewString = UtStringCacheCalloc (StringLength + 1);
+ strncpy (NewString, StartPosition, StringLength);
+
+ NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL);
+ NewOp->Asl.Value.String = NewString;
+ NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING;
+ NewOp->Asl.AmlOpcode = AML_STRING_OP;
+ NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber;
+
+ OpcCreateConcatenateNode(Op, NewOp);
+ }
+
+ /*
+ * If we get here and there's no child node then Format
+ * was an empty string. Just make a no op.
+ */
+ if (!Op->Asl.Child)
+ {
+ Op->Asl.ParseOpcode = PARSEOP_NOOP;
+ AslError(ASL_WARNING, ASL_MSG_NULL_STRING, Op,
+ "Converted to NOOP");
+ return;
+ }
+
+ /* Check for erroneous extra arguments */
+
+ if (ArgNode &&
+ ArgNode->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ AslError(ASL_WARNING, ASL_MSG_ARG_COUNT_HI, ArgNode,
+ "Extra arguments ignored");
+ }
+
+ /* Change Op to a Store */
+
+ Op->Asl.ParseOpcode = PARSEOP_STORE;
+ Op->Common.AmlOpcode = AML_STORE_OP;
+ Op->Asl.CompileFlags = 0;
+
+ /* Disable further optimization */
+
+ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
+ UtSetParseOpName (Op);
+
+ /* Set Store destination */
+
+ Op->Asl.Child->Asl.Next = DestOp;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: OpcCreateConcatenateNode
+ *
+ * PARAMETERS: Op - Parse node
+ * Node - Parse node to be concatenated
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Make Node the child of Op. If child node already exists, then
+ * concat child with Node and makes concat node the child of Op.
+ *
+ ******************************************************************************/
+
+static void
+OpcCreateConcatenateNode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Node)
+{
+ ACPI_PARSE_OBJECT *NewConcatOp;
+
+
+ if (!Op->Asl.Child)
+ {
+ Op->Asl.Child = Node;
+ Node->Asl.Parent = Op;
+ return;
+ }
+
+ NewConcatOp = TrAllocateNode (PARSEOP_CONCATENATE);
+ NewConcatOp->Asl.AmlOpcode = AML_CONCAT_OP;
+ NewConcatOp->Asl.AcpiBtype = 0x7;
+ NewConcatOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber;
+
+ /* First arg is child of Op*/
+
+ NewConcatOp->Asl.Child = Op->Asl.Child;
+ Op->Asl.Child->Asl.Parent = NewConcatOp;
+
+ /* Second arg is Node */
+
+ NewConcatOp->Asl.Child->Asl.Next = Node;
+ Node->Asl.Parent = NewConcatOp;
+
+ /* Third arg is Zero (not used) */
+
+ NewConcatOp->Asl.Child->Asl.Next->Asl.Next =
+ TrAllocateNode (PARSEOP_ZERO);
+ NewConcatOp->Asl.Child->Asl.Next->Asl.Next->Asl.Parent =
+ NewConcatOp;
+
+ Op->Asl.Child = NewConcatOp;
+ NewConcatOp->Asl.Parent = Op;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprune.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprune.c
new file mode 100644
index 0000000000..1a36928a14
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslprune.c
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ * Module Name: aslprune - Parse tree prune utility
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslprune")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+PrTreePruneWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static void
+PrPrintObjectAtLevel (
+ UINT32 Level,
+ const char *ObjectName);
+
+
+typedef struct acpi_prune_info
+{
+ UINT32 PruneLevel;
+ UINT16 ParseOpcode;
+ UINT16 Count;
+
+} ACPI_PRUNE_INFO;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPruneParseTree
+ *
+ * PARAMETERS: PruneDepth - Number of levels to prune
+ * Type - Prune type (Device, Method, etc.)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Prune off one or more levels of the ASL parse tree
+ *
+ ******************************************************************************/
+
+void
+AslPruneParseTree (
+ UINT32 PruneDepth,
+ UINT32 Type)
+{
+ ACPI_PRUNE_INFO PruneObj;
+
+
+ PruneObj.PruneLevel = PruneDepth;
+ PruneObj.Count = 0;
+
+ switch (Type)
+ {
+ case 0:
+ PruneObj.ParseOpcode = (UINT16) PARSEOP_DEVICE;
+ break;
+
+ case 1:
+ PruneObj.ParseOpcode = (UINT16) PARSEOP_METHOD;
+ break;
+
+ case 2:
+ PruneObj.ParseOpcode = (UINT16) PARSEOP_IF;
+ break;
+
+ default:
+ AcpiOsPrintf ("Unsupported type: %u\n", Type);
+ return;
+ }
+
+ AcpiOsPrintf ("Pruning parse tree, from depth %u\n",
+ PruneDepth);
+
+ AcpiOsPrintf ("\nRemoving Objects:\n");
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
+ PrTreePruneWalk, NULL, ACPI_CAST_PTR (void, &PruneObj));
+
+ AcpiOsPrintf ("\n%u Total Objects Removed\n", PruneObj.Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrPrintObjectAtLevel
+ *
+ * PARAMETERS: Level - Current nesting level
+ * ObjectName - ACPI name for the object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print object name with indent
+ *
+ ******************************************************************************/
+
+static void
+PrPrintObjectAtLevel (
+ UINT32 Level,
+ const char *ObjectName)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < Level; i++)
+ {
+ AcpiOsPrintf (" ");
+ }
+
+ AcpiOsPrintf ("[%s] at Level [%u]\n", ObjectName, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrTreePruneWalk
+ *
+ * PARAMETERS: Parse tree walk callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Prune off one or more levels of the ASL parse tree
+ *
+ * Current objects that can be pruned are: Devices, Methods, and If/Else
+ * blocks.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+PrTreePruneWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_PRUNE_INFO *PruneObj = (ACPI_PRUNE_INFO *) Context;
+
+
+ /* We only care about objects below the Prune Level threshold */
+
+ if (Level <= PruneObj->PruneLevel)
+ {
+ return (AE_OK);
+ }
+
+ if ((Op->Asl.ParseOpcode != PruneObj->ParseOpcode) &&
+ !(Op->Asl.ParseOpcode == PARSEOP_ELSE &&
+ PruneObj->ParseOpcode == PARSEOP_IF))
+ {
+ return (AE_OK);
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ AcpiOsPrintf ("Method");
+ PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name);
+ Op->Asl.Child->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next = NULL;
+ PruneObj->Count++;
+ break;
+
+ case PARSEOP_DEVICE:
+
+ AcpiOsPrintf ("Device");
+ PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name);
+ Op->Asl.Child->Asl.Next = NULL;
+ PruneObj->Count++;
+ break;
+
+ case PARSEOP_IF:
+ case PARSEOP_ELSE:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_ELSE)
+ {
+ PrPrintObjectAtLevel(Level, "Else");
+ Op->Asl.Child = NULL;
+ }
+ else
+ {
+ PrPrintObjectAtLevel(Level, "If");
+ Op->Asl.Child->Asl.Next = NULL;
+ }
+
+ PruneObj->Count++;
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslresource.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslresource.c
new file mode 100644
index 0000000000..5f513d7ade
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslresource.c
@@ -0,0 +1,1090 @@
+/******************************************************************************
+ *
+ * Module Name: aslresource - Resource template/descriptor utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslresource")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsSmallAddressCheck
+ *
+ * PARAMETERS: Minimum - Address Min value
+ * Maximum - Address Max value
+ * Length - Address range value
+ * Alignment - Address alignment value
+ * MinOp - Original Op for Address Min
+ * MaxOp - Original Op for Address Max
+ * LengthOp - Original Op for address range
+ * AlignOp - Original Op for address alignment. If
+ * NULL, means "zero value for alignment is
+ * OK, and means 64K alignment" (for
+ * Memory24 descriptor)
+ * Op - Parent Op for entire construct
+ *
+ * RETURN: None. Adds error messages to error log if necessary
+ *
+ * DESCRIPTION: Perform common value checks for "small" address descriptors.
+ * Currently:
+ * Io, Memory24, Memory32
+ *
+ ******************************************************************************/
+
+void
+RsSmallAddressCheck (
+ UINT8 Type,
+ UINT32 Minimum,
+ UINT32 Maximum,
+ UINT32 Length,
+ UINT32 Alignment,
+ ACPI_PARSE_OBJECT *MinOp,
+ ACPI_PARSE_OBJECT *MaxOp,
+ ACPI_PARSE_OBJECT *LengthOp,
+ ACPI_PARSE_OBJECT *AlignOp,
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Gbl_NoResourceChecking)
+ {
+ return;
+ }
+
+ /*
+ * Check for a so-called "null descriptor". These are descriptors that are
+ * created with most fields set to zero. The intent is that the descriptor
+ * will be updated/completed at runtime via a BufferField.
+ *
+ * If the descriptor does NOT have a resource tag, it cannot be referenced
+ * by a BufferField and we will flag this as an error. Conversely, if
+ * the descriptor has a resource tag, we will assume that a BufferField
+ * will be used to dynamically update it, so no error.
+ *
+ * A possible enhancement to this check would be to verify that in fact
+ * a BufferField is created using the resource tag, and perhaps even
+ * verify that a Store is performed to the BufferField.
+ *
+ * Note: for these descriptors, Alignment is allowed to be zero
+ */
+ if (!Minimum && !Maximum && !Length)
+ {
+ if (!Op->Asl.ExternalName)
+ {
+ /* No resource tag. Descriptor is fixed and is also illegal */
+
+ AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
+ }
+
+ return;
+ }
+
+ /*
+ * Range checks for Memory24 and Memory32.
+ * IO descriptor has different definition of min/max, don't check.
+ */
+ if (Type != ACPI_RESOURCE_NAME_IO)
+ {
+ /* Basic checks on Min/Max/Length */
+
+ if (Minimum > Maximum)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
+ }
+ else if (Length > (Maximum - Minimum + 1))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
+ }
+
+ /* Special case for Memory24, min/max values are compressed */
+
+ if (Type == ACPI_RESOURCE_NAME_MEMORY24)
+ {
+ if (!Alignment) /* Alignment==0 means 64K alignment */
+ {
+ Alignment = ACPI_UINT16_MAX + 1;
+ }
+
+ Minimum <<= 8;
+ Maximum <<= 8;
+ }
+ }
+
+ /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
+
+ if (!Alignment)
+ {
+ Alignment = 1;
+ }
+
+ /* Addresses must be an exact multiple of the alignment value */
+
+ if (Minimum % Alignment)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
+ }
+ if (Maximum % Alignment)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsLargeAddressCheck
+ *
+ * PARAMETERS: Minimum - Address Min value
+ * Maximum - Address Max value
+ * Length - Address range value
+ * Granularity - Address granularity value
+ * Flags - General flags for address descriptors:
+ * _MIF, _MAF, _DEC
+ * MinOp - Original Op for Address Min
+ * MaxOp - Original Op for Address Max
+ * LengthOp - Original Op for address range
+ * GranOp - Original Op for address granularity
+ * Op - Parent Op for entire construct
+ *
+ * RETURN: None. Adds error messages to error log if necessary
+ *
+ * DESCRIPTION: Perform common value checks for "large" address descriptors.
+ * Currently:
+ * WordIo, WordBusNumber, WordSpace
+ * DWordIo, DWordMemory, DWordSpace
+ * QWordIo, QWordMemory, QWordSpace
+ * ExtendedIo, ExtendedMemory, ExtendedSpace
+ *
+ * _MIF flag set means that the minimum address is fixed and is not relocatable
+ * _MAF flag set means that the maximum address is fixed and is not relocatable
+ * Length of zero means that the record size is variable
+ *
+ * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
+ * of the ACPI 4.0a specification. Added 04/2010.
+ *
+ ******************************************************************************/
+
+void
+RsLargeAddressCheck (
+ UINT64 Minimum,
+ UINT64 Maximum,
+ UINT64 Length,
+ UINT64 Granularity,
+ UINT8 Flags,
+ ACPI_PARSE_OBJECT *MinOp,
+ ACPI_PARSE_OBJECT *MaxOp,
+ ACPI_PARSE_OBJECT *LengthOp,
+ ACPI_PARSE_OBJECT *GranOp,
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Gbl_NoResourceChecking)
+ {
+ return;
+ }
+
+ /*
+ * Check for a so-called "null descriptor". These are descriptors that are
+ * created with most fields set to zero. The intent is that the descriptor
+ * will be updated/completed at runtime via a BufferField.
+ *
+ * If the descriptor does NOT have a resource tag, it cannot be referenced
+ * by a BufferField and we will flag this as an error. Conversely, if
+ * the descriptor has a resource tag, we will assume that a BufferField
+ * will be used to dynamically update it, so no error.
+ *
+ * A possible enhancement to this check would be to verify that in fact
+ * a BufferField is created using the resource tag, and perhaps even
+ * verify that a Store is performed to the BufferField.
+ */
+ if (!Minimum && !Maximum && !Length && !Granularity)
+ {
+ if (!Op->Asl.ExternalName)
+ {
+ /* No resource tag. Descriptor is fixed and is also illegal */
+
+ AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
+ }
+
+ return;
+ }
+
+ /* Basic checks on Min/Max/Length */
+
+ if (Minimum > Maximum)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
+ return;
+ }
+ else if (Length > (Maximum - Minimum + 1))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
+ return;
+ }
+
+ /* If specified (non-zero), ensure granularity is a power-of-two minus one */
+
+ if (Granularity)
+ {
+ if ((Granularity + 1) &
+ Granularity)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
+ return;
+ }
+ }
+
+ /*
+ * Check the various combinations of Length, MinFixed, and MaxFixed
+ */
+ if (Length)
+ {
+ /* Fixed non-zero length */
+
+ switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
+ {
+ case 0:
+ /*
+ * Fixed length, variable locations (both _MIN and _MAX).
+ * Length must be a multiple of granularity
+ */
+ if (Granularity & Length)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
+ }
+ break;
+
+ case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
+
+ /* Fixed length, fixed location. Granularity must be zero */
+
+ if (Granularity != 0)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
+ }
+
+ /* Length must be exactly the size of the min/max window */
+
+ if (Length != (Maximum - Minimum + 1))
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
+ }
+ break;
+
+ /* All other combinations are invalid */
+
+ case ACPI_RESOURCE_FLAG_MIF:
+ case ACPI_RESOURCE_FLAG_MAF:
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
+ }
+ }
+ else
+ {
+ /* Variable length (length==0) */
+
+ switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
+ {
+ case 0:
+ /*
+ * Both _MIN and _MAX are variable.
+ * No additional requirements, just exit
+ */
+ break;
+
+ case ACPI_RESOURCE_FLAG_MIF:
+
+ /* _MIN is fixed. _MIN must be multiple of _GRA */
+
+ /*
+ * The granularity is defined by the ACPI specification to be a
+ * power-of-two minus one, therefore the granularity is a
+ * bitmask which can be used to easily validate the addresses.
+ */
+ if (Granularity & Minimum)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
+ }
+ break;
+
+ case ACPI_RESOURCE_FLAG_MAF:
+
+ /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
+
+ if (Granularity & (Maximum + 1))
+ {
+ AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
+ }
+ break;
+
+ /* Both MIF/MAF set is invalid if length is zero */
+
+ case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsGetStringDataLength
+ *
+ * PARAMETERS: InitializerOp - Start of a subtree of init nodes
+ *
+ * RETURN: Valid string length if a string node is found (otherwise 0)
+ *
+ * DESCRIPTION: In a list of peer nodes, find the first one that contains a
+ * string and return the length of the string.
+ *
+ ******************************************************************************/
+
+UINT16
+RsGetStringDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp)
+{
+
+ while (InitializerOp)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
+ {
+ return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
+ }
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+ }
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsAllocateResourceNode
+ *
+ * PARAMETERS: Size - Size of node in bytes
+ *
+ * RETURN: The allocated node - aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a resource description node and the resource
+ * descriptor itself (the nodes are used to link descriptors).
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsAllocateResourceNode (
+ UINT32 Size)
+{
+ ASL_RESOURCE_NODE *Rnode;
+
+
+ /* Allocate the node */
+
+ Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
+
+ /* Allocate the resource descriptor itself */
+
+ Rnode->Buffer = UtLocalCalloc (Size);
+ Rnode->BufferLength = Size;
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsCreateResourceField
+ *
+ * PARAMETERS: Op - Resource field node
+ * Name - Name of the field (Used only to reference
+ * the field in the ASL, not in the AML)
+ * ByteOffset - Offset from the field start
+ * BitOffset - Additional bit offset
+ * BitLength - Number of bits in the field
+ *
+ * RETURN: None, sets fields within the input node
+ *
+ * DESCRIPTION: Utility function to generate a named bit field within a
+ * resource descriptor. Mark a node as 1) a field in a resource
+ * descriptor, and 2) set the value to be a BIT offset
+ *
+ ******************************************************************************/
+
+void
+RsCreateResourceField (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name,
+ UINT32 ByteOffset,
+ UINT32 BitOffset,
+ UINT32 BitLength)
+{
+
+ Op->Asl.ExternalName = Name;
+ Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
+
+
+ Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
+ Op->Asl.Value.Tag.BitLength = BitLength;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsSetFlagBits
+ *
+ * PARAMETERS: *Flags - Pointer to the flag byte
+ * Op - Flag initialization node
+ * Position - Bit position within the flag byte
+ * Default - Used if the node is DEFAULT.
+ *
+ * RETURN: Sets bits within the *Flags output byte.
+ *
+ * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
+ * node. Will use a default value if the node is DEFAULT, meaning
+ * that no value was specified in the ASL. Used to merge multiple
+ * keywords into a single flags byte.
+ *
+ ******************************************************************************/
+
+void
+RsSetFlagBits (
+ UINT8 *Flags,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Position,
+ UINT8 DefaultBit)
+{
+
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /* Use the default bit */
+
+ *Flags |= (DefaultBit << Position);
+ }
+ else
+ {
+ /* Use the bit specified in the initialization node */
+
+ *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
+ }
+}
+
+
+void
+RsSetFlagBits16 (
+ UINT16 *Flags,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 Position,
+ UINT8 DefaultBit)
+{
+
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /* Use the default bit */
+
+ *Flags |= (DefaultBit << Position);
+ }
+ else
+ {
+ /* Use the bit specified in the initialization node */
+
+ *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsCompleteNodeAndGetNext
+ *
+ * PARAMETERS: Op - Resource node to be completed
+ *
+ * RETURN: The next peer to the input node.
+ *
+ * DESCRIPTION: Mark the current node completed and return the next peer.
+ * The node ParseOpcode is set to DEFAULT_ARG, meaning that
+ * this node is to be ignored from now on.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+RsCompleteNodeAndGetNext (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* Mark this node unused */
+
+ Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+
+ /* Move on to the next peer node in the initializer list */
+
+ return (ASL_GET_PEER_NODE (Op));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsCheckListForDuplicates
+ *
+ * PARAMETERS: Op - First op in the initializer list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
+ * if any duplicates are found.
+ *
+ ******************************************************************************/
+
+void
+RsCheckListForDuplicates (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextValueOp = Op;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 Value;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Search list once for each value in the list */
+
+ while (NextValueOp)
+ {
+ Value = (UINT32) NextValueOp->Asl.Value.Integer;
+
+ /* Compare this value to all remaining values in the list */
+
+ NextOp = ASL_GET_PEER_NODE (NextValueOp);
+ while (NextOp)
+ {
+ if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* Compare values */
+
+ if (Value == (UINT32) NextOp->Asl.Value.Integer)
+ {
+ /* Emit error only once per duplicate node */
+
+ if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
+ {
+ NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
+ AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
+ NextOp, NULL);
+ }
+ }
+ }
+
+ NextOp = ASL_GET_PEER_NODE (NextOp);
+ }
+
+ NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoOneResourceDescriptor
+ *
+ * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor
+ * CurrentByteOffset - Offset in the resource descriptor
+ * buffer.
+ *
+ * RETURN: A valid resource node for the descriptor
+ *
+ * DESCRIPTION: Dispatches the processing of one resource descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoOneResourceDescriptor (
+ ASL_RESOURCE_INFO *Info,
+ UINT8 *State)
+{
+ ASL_RESOURCE_NODE *Rnode = NULL;
+
+
+ /* Construct the resource */
+
+ switch (Info->DescriptorTypeOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_DMA:
+
+ Rnode = RsDoDmaDescriptor (Info);
+ break;
+
+ case PARSEOP_FIXEDDMA:
+
+ Rnode = RsDoFixedDmaDescriptor (Info);
+ break;
+
+ case PARSEOP_DWORDIO:
+
+ Rnode = RsDoDwordIoDescriptor (Info);
+ break;
+
+ case PARSEOP_DWORDMEMORY:
+
+ Rnode = RsDoDwordMemoryDescriptor (Info);
+ break;
+
+ case PARSEOP_DWORDSPACE:
+
+ Rnode = RsDoDwordSpaceDescriptor (Info);
+ break;
+
+ case PARSEOP_ENDDEPENDENTFN:
+
+ switch (*State)
+ {
+ case ACPI_RSTATE_NORMAL:
+
+ AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
+ Info->DescriptorTypeOp, NULL);
+ break;
+
+ case ACPI_RSTATE_START_DEPENDENT:
+
+ AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
+ Info->DescriptorTypeOp, NULL);
+ break;
+
+ case ACPI_RSTATE_DEPENDENT_LIST:
+ default:
+
+ break;
+ }
+
+ *State = ACPI_RSTATE_NORMAL;
+ Rnode = RsDoEndDependentDescriptor (Info);
+ break;
+
+ case PARSEOP_ENDTAG:
+
+ Rnode = RsDoEndTagDescriptor (Info);
+ break;
+
+ case PARSEOP_EXTENDEDIO:
+
+ Rnode = RsDoExtendedIoDescriptor (Info);
+ break;
+
+ case PARSEOP_EXTENDEDMEMORY:
+
+ Rnode = RsDoExtendedMemoryDescriptor (Info);
+ break;
+
+ case PARSEOP_EXTENDEDSPACE:
+
+ Rnode = RsDoExtendedSpaceDescriptor (Info);
+ break;
+
+ case PARSEOP_FIXEDIO:
+
+ Rnode = RsDoFixedIoDescriptor (Info);
+ break;
+
+ case PARSEOP_INTERRUPT:
+
+ Rnode = RsDoInterruptDescriptor (Info);
+ break;
+
+ case PARSEOP_IO:
+
+ Rnode = RsDoIoDescriptor (Info);
+ break;
+
+ case PARSEOP_IRQ:
+
+ Rnode = RsDoIrqDescriptor (Info);
+ break;
+
+ case PARSEOP_IRQNOFLAGS:
+
+ Rnode = RsDoIrqNoFlagsDescriptor (Info);
+ break;
+
+ case PARSEOP_MEMORY24:
+
+ Rnode = RsDoMemory24Descriptor (Info);
+ break;
+
+ case PARSEOP_MEMORY32:
+
+ Rnode = RsDoMemory32Descriptor (Info);
+ break;
+
+ case PARSEOP_MEMORY32FIXED:
+
+ Rnode = RsDoMemory32FixedDescriptor (Info);
+ break;
+
+ case PARSEOP_QWORDIO:
+
+ Rnode = RsDoQwordIoDescriptor (Info);
+ break;
+
+ case PARSEOP_QWORDMEMORY:
+
+ Rnode = RsDoQwordMemoryDescriptor (Info);
+ break;
+
+ case PARSEOP_QWORDSPACE:
+
+ Rnode = RsDoQwordSpaceDescriptor (Info);
+ break;
+
+ case PARSEOP_REGISTER:
+
+ Rnode = RsDoGeneralRegisterDescriptor (Info);
+ break;
+
+ case PARSEOP_STARTDEPENDENTFN:
+
+ switch (*State)
+ {
+ case ACPI_RSTATE_START_DEPENDENT:
+
+ AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
+ Info->DescriptorTypeOp, NULL);
+ break;
+
+ case ACPI_RSTATE_NORMAL:
+ case ACPI_RSTATE_DEPENDENT_LIST:
+ default:
+
+ break;
+ }
+
+ *State = ACPI_RSTATE_START_DEPENDENT;
+ Rnode = RsDoStartDependentDescriptor (Info);
+ *State = ACPI_RSTATE_DEPENDENT_LIST;
+ break;
+
+ case PARSEOP_STARTDEPENDENTFN_NOPRI:
+
+ switch (*State)
+ {
+ case ACPI_RSTATE_START_DEPENDENT:
+
+ AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
+ Info->DescriptorTypeOp, NULL);
+ break;
+
+ case ACPI_RSTATE_NORMAL:
+ case ACPI_RSTATE_DEPENDENT_LIST:
+ default:
+
+ break;
+ }
+
+ *State = ACPI_RSTATE_START_DEPENDENT;
+ Rnode = RsDoStartDependentNoPriDescriptor (Info);
+ *State = ACPI_RSTATE_DEPENDENT_LIST;
+ break;
+
+ case PARSEOP_VENDORLONG:
+
+ Rnode = RsDoVendorLargeDescriptor (Info);
+ break;
+
+ case PARSEOP_VENDORSHORT:
+
+ Rnode = RsDoVendorSmallDescriptor (Info);
+ break;
+
+ case PARSEOP_WORDBUSNUMBER:
+
+ Rnode = RsDoWordBusNumberDescriptor (Info);
+ break;
+
+ case PARSEOP_WORDIO:
+
+ Rnode = RsDoWordIoDescriptor (Info);
+ break;
+
+ case PARSEOP_WORDSPACE:
+
+ Rnode = RsDoWordSpaceDescriptor (Info);
+ break;
+
+ case PARSEOP_GPIO_INT:
+
+ Rnode = RsDoGpioIntDescriptor (Info);
+ break;
+
+ case PARSEOP_GPIO_IO:
+
+ Rnode = RsDoGpioIoDescriptor (Info);
+ break;
+
+ case PARSEOP_I2C_SERIALBUS:
+
+ Rnode = RsDoI2cSerialBusDescriptor (Info);
+ break;
+
+ case PARSEOP_SPI_SERIALBUS:
+
+ Rnode = RsDoSpiSerialBusDescriptor (Info);
+ break;
+
+ case PARSEOP_UART_SERIALBUS:
+
+ Rnode = RsDoUartSerialBusDescriptor (Info);
+ break;
+
+ case PARSEOP_DEFAULT_ARG:
+
+ /* Just ignore any of these, they are used as fillers/placeholders */
+ break;
+
+ default:
+
+ printf ("Unknown resource descriptor type [%s]\n",
+ Info->DescriptorTypeOp->Asl.ParseOpName);
+ break;
+ }
+
+ /*
+ * Mark original node as unused, but head of a resource descriptor.
+ * This allows the resource to be installed in the namespace so that
+ * references to the descriptor can be resolved.
+ */
+ Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ Info->DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
+ Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset;
+
+ if (Rnode)
+ {
+ Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
+ Info->DescriptorTypeOp->Asl.Extra = ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsLinkDescriptorChain
+ *
+ * PARAMETERS: PreviousRnode - Pointer to the node that will be previous
+ * to the linked node, At exit, set to the
+ * last node in the new chain.
+ * Rnode - Resource node to link into the list
+ *
+ * RETURN: Cumulative buffer byte offset of the new segment of chain
+ *
+ * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
+ *
+ ******************************************************************************/
+
+UINT32
+RsLinkDescriptorChain (
+ ASL_RESOURCE_NODE **PreviousRnode,
+ ASL_RESOURCE_NODE *Rnode)
+{
+ ASL_RESOURCE_NODE *LastRnode;
+ UINT32 CurrentByteOffset;
+
+
+ /* Anything to do? */
+
+ if (!Rnode)
+ {
+ return (0);
+ }
+
+ /* Point the previous node to the new node */
+
+ (*PreviousRnode)->Next = Rnode;
+ CurrentByteOffset = Rnode->BufferLength;
+
+ /* Walk to the end of the chain headed by Rnode */
+
+ LastRnode = Rnode;
+ while (LastRnode->Next)
+ {
+ LastRnode = LastRnode->Next;
+ CurrentByteOffset += LastRnode->BufferLength;
+ }
+
+ /* Previous node becomes the last node in the chain */
+
+ *PreviousRnode = LastRnode;
+ return (CurrentByteOffset);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoResourceTemplate
+ *
+ * PARAMETERS: Op - Parent of a resource template list
+ *
+ * RETURN: None. Sets input node to point to a list of AML code
+ *
+ * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
+ * in preparation for output to the AML output file.
+ *
+ ******************************************************************************/
+
+void
+RsDoResourceTemplate (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *BufferLengthOp;
+ ACPI_PARSE_OBJECT *BufferOp;
+ ACPI_PARSE_OBJECT *DescriptorTypeOp;
+ ACPI_PARSE_OBJECT *LastOp = NULL;
+ UINT32 CurrentByteOffset = 0;
+ ASL_RESOURCE_NODE HeadRnode;
+ ASL_RESOURCE_NODE *PreviousRnode;
+ ASL_RESOURCE_NODE *Rnode;
+ ASL_RESOURCE_INFO Info;
+ UINT8 State;
+
+
+ /* Mark parent as containing a resource template */
+
+ if (Op->Asl.Parent)
+ {
+ Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
+ }
+
+ /* ResourceTemplate Opcode is first (Op) */
+ /* Buffer Length node is first child */
+
+ BufferLengthOp = ASL_GET_CHILD_NODE (Op);
+
+ /* Buffer Op is first peer */
+
+ BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
+
+ /* First Descriptor type is next */
+
+ DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
+
+ /*
+ * Process all resource descriptors in the list
+ * Note: It is assumed that the EndTag node has been automatically
+ * inserted at the end of the template by the parser.
+ */
+ State = ACPI_RSTATE_NORMAL;
+ PreviousRnode = &HeadRnode;
+ while (DescriptorTypeOp)
+ {
+ /* Save information for optional mapfile */
+
+ if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
+ {
+ Info.MappingOp = Op->Asl.Parent;
+ }
+ else
+ {
+ Info.MappingOp = DescriptorTypeOp;
+ }
+
+ Info.DescriptorTypeOp = DescriptorTypeOp;
+ Info.CurrentByteOffset = CurrentByteOffset;
+
+ DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
+ Rnode = RsDoOneResourceDescriptor (&Info, &State);
+
+ /*
+ * Update current byte offset to indicate the number of bytes from the
+ * start of the buffer. Buffer can include multiple descriptors, we
+ * must keep track of the offset of not only each descriptor, but each
+ * element (field) within each descriptor as well.
+ */
+ CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
+
+ /* Get the next descriptor in the list */
+
+ LastOp = DescriptorTypeOp;
+ DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
+ }
+
+ if (State == ACPI_RSTATE_DEPENDENT_LIST)
+ {
+ if (LastOp)
+ {
+ LastOp = LastOp->Asl.Parent;
+ }
+ AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
+ }
+
+ /*
+ * Transform the nodes into the following
+ *
+ * Op -> AML_BUFFER_OP
+ * First Child -> BufferLength
+ * Second Child -> Descriptor Buffer (raw byte data)
+ */
+ Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+ Op->Asl.AmlOpcode = AML_BUFFER_OP;
+ Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
+ UtSetParseOpName (Op);
+
+ BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
+ BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
+ (void) OpcSetOptimalIntegerSize (BufferLengthOp);
+ UtSetParseOpName (BufferLengthOp);
+
+ BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
+ BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
+ BufferOp->Asl.AmlOpcodeLength = 0;
+ BufferOp->Asl.AmlLength = CurrentByteOffset;
+ BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next;
+ BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA;
+ UtSetParseOpName (BufferOp);
+
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1.c
new file mode 100644
index 0000000000..4ac063528e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1.c
@@ -0,0 +1,642 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype1 - Miscellaneous small resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype1")
+
+/*
+ * This module contains miscellaneous small resource descriptors:
+ *
+ * EndTag
+ * EndDependentFn
+ * Memory24
+ * Memory32
+ * Memory32Fixed
+ * StartDependentFn
+ * StartDependentFnNoPri
+ * VendorShort
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoEndTagDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "EndDependentFn" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoEndTagDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ASL_RESOURCE_NODE *Rnode;
+
+
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_END_TAG));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->EndTag.DescriptorType = ACPI_RESOURCE_NAME_END_TAG |
+ ASL_RDESC_END_TAG_SIZE;
+ Descriptor->EndTag.Checksum = 0;
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoEndDependentDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "EndDependentFn" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoEndDependentDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ASL_RESOURCE_NODE *Rnode;
+
+
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_END_DEPENDENT));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->EndDpf.DescriptorType = ACPI_RESOURCE_NAME_END_DEPENDENT |
+ ASL_RDESC_END_DEPEND_SIZE;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoMemory24Descriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "Memory24" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoMemory24Descriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_MEMORY24));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Memory24.DescriptorType = ACPI_RESOURCE_NAME_MEMORY24;
+ Descriptor->Memory24.ResourceLength = 9;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Read/Write type */
+
+ RsSetFlagBits (&Descriptor->Memory24.Flags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Flags), 0);
+ break;
+
+ case 1: /* Min Address */
+
+ Descriptor->Memory24.Minimum = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 2: /* Max Address */
+
+ Descriptor->Memory24.Maximum = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 3: /* Alignment */
+
+ Descriptor->Memory24.Alignment = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Alignment));
+ break;
+
+ case 4: /* Length */
+
+ Descriptor->Memory24.AddressLength = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 5: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Align values (Alignment==0 means 64K) */
+
+ RsSmallAddressCheck (ACPI_RESOURCE_NAME_MEMORY24,
+ Descriptor->Memory24.Minimum,
+ Descriptor->Memory24.Maximum,
+ Descriptor->Memory24.AddressLength,
+ Descriptor->Memory24.Alignment,
+ MinOp, MaxOp, LengthOp, NULL, Info->DescriptorTypeOp);
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoMemory32Descriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "Memory32" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoMemory32Descriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *AlignOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_MEMORY32));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Memory32.DescriptorType = ACPI_RESOURCE_NAME_MEMORY32;
+ Descriptor->Memory32.ResourceLength = 17;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Read/Write type */
+
+ RsSetFlagBits (&Descriptor->Memory32.Flags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Flags), 0);
+ break;
+
+ case 1: /* Min Address */
+
+ Descriptor->Memory32.Minimum = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 2: /* Max Address */
+
+ Descriptor->Memory32.Maximum = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 3: /* Alignment */
+
+ Descriptor->Memory32.Alignment = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Alignment));
+ AlignOp = InitializerOp;
+ break;
+
+ case 4: /* Length */
+
+ Descriptor->Memory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 5: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Align values */
+
+ RsSmallAddressCheck (ACPI_RESOURCE_NAME_MEMORY32,
+ Descriptor->Memory32.Minimum,
+ Descriptor->Memory32.Maximum,
+ Descriptor->Memory32.AddressLength,
+ Descriptor->Memory32.Alignment,
+ MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp);
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoMemory32FixedDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "Memory32Fixed" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoMemory32FixedDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_MEMORY32));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->FixedMemory32.DescriptorType = ACPI_RESOURCE_NAME_FIXED_MEMORY32;
+ Descriptor->FixedMemory32.ResourceLength = 9;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Read/Write type */
+
+ RsSetFlagBits (&Descriptor->FixedMemory32.Flags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Flags), 0);
+ break;
+
+ case 1: /* Address */
+
+ Descriptor->FixedMemory32.Address = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Address));
+ break;
+
+ case 2: /* Length */
+
+ Descriptor->FixedMemory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.AddressLength));
+ break;
+
+ case 3: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoStartDependentDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "StartDependentFn" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoStartDependentDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ ASL_RESOURCE_NODE *PreviousRnode;
+ ASL_RESOURCE_NODE *NextRnode;
+ ASL_RESOURCE_INFO NextInfo;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ UINT8 State;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_START_DEPENDENT));
+
+ PreviousRnode = Rnode;
+ Descriptor = Rnode->Buffer;
+
+ /* Increment offset past StartDependent descriptor */
+
+ CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT);
+
+ /* Descriptor has priority byte */
+
+ Descriptor->StartDpf.DescriptorType = ACPI_RESOURCE_NAME_START_DEPENDENT |
+ (ASL_RDESC_ST_DEPEND_SIZE + 0x01);
+
+ /* Process all child initialization nodes */
+
+ State = ACPI_RSTATE_START_DEPENDENT;
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Compatibility Priority */
+
+ if ((UINT8) InitializerOp->Asl.Value.Integer > 2)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_PRIORITY,
+ InitializerOp, NULL);
+ }
+
+ RsSetFlagBits (&Descriptor->StartDpf.Flags, InitializerOp, 0, 0);
+ break;
+
+ case 1: /* Performance/Robustness Priority */
+
+ if ((UINT8) InitializerOp->Asl.Value.Integer > 2)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_PERFORMANCE,
+ InitializerOp, NULL);
+ }
+
+ RsSetFlagBits (&Descriptor->StartDpf.Flags, InitializerOp, 2, 0);
+ break;
+
+ default:
+
+ NextInfo.CurrentByteOffset = CurrentByteOffset;
+ NextInfo.DescriptorTypeOp = InitializerOp;
+
+ NextRnode = RsDoOneResourceDescriptor (&NextInfo, &State);
+
+ /*
+ * Update current byte offset to indicate the number of bytes from the
+ * start of the buffer. Buffer can include multiple descriptors, we
+ * must keep track of the offset of not only each descriptor, but each
+ * element (field) within each descriptor as well.
+ */
+ CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode,
+ NextRnode);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoStartDependentNoPriDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "StartDependentNoPri" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoStartDependentNoPriDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ ASL_RESOURCE_NODE *PreviousRnode;
+ ASL_RESOURCE_NODE *NextRnode;
+ ASL_RESOURCE_INFO NextInfo;
+ UINT32 CurrentByteOffset;
+ UINT8 State;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->StartDpf.DescriptorType = ACPI_RESOURCE_NAME_START_DEPENDENT |
+ ASL_RDESC_ST_DEPEND_SIZE;
+ PreviousRnode = Rnode;
+
+ /* Increment offset past StartDependentNoPri descriptor */
+
+ CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO);
+
+ /* Process all child initialization nodes */
+
+ State = ACPI_RSTATE_START_DEPENDENT;
+ while (InitializerOp)
+ {
+ NextInfo.CurrentByteOffset = CurrentByteOffset;
+ NextInfo.DescriptorTypeOp = InitializerOp;
+
+ NextRnode = RsDoOneResourceDescriptor (&NextInfo, &State);
+
+ /*
+ * Update current byte offset to indicate the number of bytes from the
+ * start of the buffer. Buffer can include multiple descriptors, we
+ * must keep track of the offset of not only each descriptor, but each
+ * element (field) within each descriptor as well.
+ */
+ CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, NextRnode);
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoVendorSmallDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "VendorShort" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoVendorSmallDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *VendorData;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+
+ /* Allocate worst case - 7 vendor bytes */
+
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_SMALL) + 7);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->VendorSmall.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_SMALL;
+ VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_SMALL_HEADER);
+
+ /* Process all child initialization nodes */
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ for (i = 0; InitializerOp; i++)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ break;
+ }
+
+ /* Maximum 7 vendor data bytes allowed (0-6) */
+
+ if (i >= 7)
+ {
+ AslError (ASL_ERROR, ASL_MSG_VENDOR_LIST, InitializerOp, NULL);
+
+ /* Eat the excess initializers */
+
+ while (InitializerOp)
+ {
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+ break;
+ }
+
+ VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer;
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Adjust the Rnode buffer size, so correct number of bytes are emitted */
+
+ Rnode->BufferLength -= (7 - i);
+
+ /* Set the length in the Type Tag */
+
+ Descriptor->VendorSmall.DescriptorType |= (UINT8) i;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1i.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1i.c
new file mode 100644
index 0000000000..36e2400cea
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype1i.c
@@ -0,0 +1,665 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype1i - Small I/O-related resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype1i")
+
+/*
+ * This module contains the I/O-related small resource descriptors:
+ *
+ * DMA
+ * FixedDMA
+ * FixedIO
+ * IO
+ * IRQ
+ * IRQNoFlags
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoDmaDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "DMA" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoDmaDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ UINT8 DmaChannelMask = 0;
+ UINT8 DmaChannels = 0;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Dma.DescriptorType = ACPI_RESOURCE_NAME_DMA |
+ ASL_RDESC_DMA_SIZE;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* DMA type */
+
+ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
+ break;
+
+ case 1: /* Bus Master */
+
+ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
+ break;
+
+ case 2: /* Xfer Type (transfer width) */
+
+ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
+ break;
+
+ case 3: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ /* All DMA channel bytes are handled here, after flags and name */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* Up to 8 channels can be specified in the list */
+
+ DmaChannels++;
+ if (DmaChannels > 8)
+ {
+ AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
+ InitializerOp, NULL);
+ return (Rnode);
+ }
+
+ /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
+
+ if (InitializerOp->Asl.Value.Integer > 7)
+ {
+ AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
+ InitializerOp, NULL);
+ }
+
+ /* Build the mask */
+
+ DmaChannelMask |=
+ (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
+ }
+
+ if (i == 4) /* case 4: First DMA byte */
+ {
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
+ CurrentByteOffset +
+ ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
+ }
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Now we can set the channel mask */
+
+ Descriptor->Dma.DmaChannelMask = DmaChannelMask;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoFixedDmaDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "FixedDMA" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoFixedDmaDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->FixedDma.DescriptorType =
+ ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* DMA Request Lines [WORD] (_DMA) */
+
+ Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
+ break;
+
+ case 1: /* DMA Channel [WORD] (_TYP) */
+
+ Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
+ break;
+
+ case 2: /* Transfer Width [BYTE] (_SIZ) */
+
+ Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
+ break;
+
+ case 3: /* Descriptor Name (optional) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default: /* Ignore any extra nodes */
+
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoFixedIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "FixedIO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoFixedIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *AddressOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO |
+ ASL_RDESC_FIXED_IO_SIZE;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Base Address */
+
+ Descriptor->FixedIo.Address =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
+ AddressOp = InitializerOp;
+ break;
+
+ case 1: /* Length */
+
+ Descriptor->FixedIo.AddressLength =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
+ break;
+
+ case 2: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Error checks */
+
+ if (Descriptor->FixedIo.Address > 0x03FF)
+ {
+ AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
+ }
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "IO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *AlignOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO |
+ ASL_RDESC_IO_SIZE;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Decode size */
+
+ RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
+ break;
+
+ case 1: /* Min Address */
+
+ Descriptor->Io.Minimum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 2: /* Max Address */
+
+ Descriptor->Io.Maximum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 3: /* Alignment */
+
+ Descriptor->Io.Alignment =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
+ AlignOp = InitializerOp;
+ break;
+
+ case 4: /* Length */
+
+ Descriptor->Io.AddressLength =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 5: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Align values */
+
+ RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
+ Descriptor->Io.Minimum,
+ Descriptor->Io.Maximum,
+ Descriptor->Io.AddressLength,
+ Descriptor->Io.Alignment,
+ MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp);
+
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoIrqDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "IRQ" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoIrqDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 Interrupts = 0;
+ UINT16 IrqMask = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
+
+ /* Length = 3 (with flag byte) */
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
+ (ASL_RDESC_IRQ_SIZE + 0x01);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Interrupt Type (or Mode - edge/level) */
+
+ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
+ break;
+
+ case 1: /* Interrupt Level (or Polarity - Active high/low) */
+
+ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
+ break;
+
+ case 2: /* Share Type - Default: exclusive (0) */
+
+ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
+ break;
+
+ case 3: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ /* All IRQ bytes are handled here, after the flags and name */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* Up to 16 interrupts can be specified in the list */
+
+ Interrupts++;
+ if (Interrupts > 16)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
+ InitializerOp, NULL);
+ return (Rnode);
+ }
+
+ /* Only interrupts 0-15 are allowed (mask is 16 bits) */
+
+ if (InitializerOp->Asl.Value.Integer > 15)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
+ InitializerOp, NULL);
+ }
+ else
+ {
+ IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
+ }
+ }
+
+ /* Case 4: First IRQ value in list */
+
+ if (i == 4)
+ {
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
+ }
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Now we can set the channel mask */
+
+ Descriptor->Irq.IrqMask = IrqMask;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoIrqNoFlagsDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoIrqNoFlagsDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 IrqMask = 0;
+ UINT32 Interrupts = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
+ ASL_RDESC_IRQ_SIZE;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Name */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ /* IRQ bytes are handled here, after the flags and name */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* Up to 16 interrupts can be specified in the list */
+
+ Interrupts++;
+ if (Interrupts > 16)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
+ InitializerOp, NULL);
+ return (Rnode);
+ }
+
+ /* Only interrupts 0-15 are allowed (mask is 16 bits) */
+
+ if (InitializerOp->Asl.Value.Integer > 15)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
+ InitializerOp, NULL);
+ }
+ else
+ {
+ IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
+ }
+ }
+
+ /* Case 1: First IRQ value in list */
+
+ if (i == 1)
+ {
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
+ }
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Now we can set the interrupt mask */
+
+ Descriptor->Irq.IrqMask = IrqMask;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2.c
new file mode 100644
index 0000000000..af93a9e90e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2.c
@@ -0,0 +1,455 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2 - Miscellaneous Large resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2")
+
+/*
+ * This module contains miscellaneous large resource descriptors:
+ *
+ * Register
+ * Interrupt
+ * VendorLong
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoGeneralRegisterDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "Register" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoGeneralRegisterDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER;
+ Descriptor->GenericReg.ResourceLength = 12;
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Address space */
+
+ Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId));
+ break;
+
+ case 1: /* Register Bit Width */
+
+ Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth));
+ break;
+
+ case 2: /* Register Bit Offset */
+
+ Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset));
+ break;
+
+ case 3: /* Register Address */
+
+ Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address));
+ break;
+
+ case 4: /* Access Size (ACPI 3.0) */
+
+ Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize));
+
+ if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD)
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE,
+ InitializerOp, NULL);
+ }
+ break;
+
+ case 5: /* ResourceTag (ACPI 3.0b) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoInterruptDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "Interrupt" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoInterruptDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ AML_RESOURCE *Rover = NULL;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN HasResSourceIndex = FALSE;
+ UINT8 ResSourceIndex = 0;
+ UINT8 *ResSourceString = NULL;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+ StringLength = RsGetStringDataLength (InitializerOp);
+
+ /* Count the interrupt numbers */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+
+ if (i <= 6)
+ {
+ if (i == 3 &&
+ InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /*
+ * ResourceSourceIndex was specified, always make room for
+ * it, even if the ResourceSource was omitted.
+ */
+ OptionIndex++;
+ }
+
+ continue;
+ }
+
+ OptionIndex += 4;
+ }
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) +
+ 1 + OptionIndex + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */
+ Descriptor->ExtendedIrq.InterruptCount = 0;
+
+ Rover = ACPI_CAST_PTR (AML_RESOURCE,
+ (&(Descriptor->ExtendedIrq.Interrupts[0])));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage (Default: consumer (1) */
+
+ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* Interrupt Type (or Mode - edge/level) */
+
+ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1);
+ break;
+
+ case 2: /* Interrupt Level (or Polarity - Active high/low) */
+
+ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2);
+ break;
+
+ case 3: /* Share Type - Default: exclusive (0) */
+
+ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3);
+ break;
+
+ case 4: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ HasResSourceIndex = TRUE;
+ ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 5: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String;
+ }
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!HasResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (HasResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 6: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+ /*
+ * Interrupt Numbers come through here, repeatedly
+ */
+
+ /* Maximum 255 interrupts allowed for this descriptor */
+
+ if (Descriptor->ExtendedIrq.InterruptCount == 255)
+ {
+ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST,
+ InitializerOp, NULL);
+ return (Rnode);
+ }
+
+ /* Each interrupt number must be a 32-bit value */
+
+ if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX)
+ {
+ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER,
+ InitializerOp, NULL);
+ }
+
+ /* Save the integer and move pointer to the next one */
+
+ Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer;
+ Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4);
+ Descriptor->ExtendedIrq.InterruptCount++;
+ Descriptor->ExtendedIrq.ResourceLength += 4;
+
+ /* Case 7: First interrupt number in list */
+
+ if (i == 7)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /* Must be at least one interrupt */
+
+ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
+ InitializerOp, NULL);
+ }
+
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
+ CurrentByteOffset +
+ ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]));
+ }
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+
+ /* Add optional ResSourceIndex if present */
+
+ if (HasResSourceIndex)
+ {
+ Rover->ByteItem = ResSourceIndex;
+ Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1);
+ Descriptor->ExtendedIrq.ResourceLength += 1;
+ }
+
+ /* Add optional ResSource string if present */
+
+ if (StringLength && ResSourceString)
+ {
+
+ strcpy ((char *) Rover, (char *) ResSourceString);
+ Rover = ACPI_ADD_PTR (
+ AML_RESOURCE, &(Rover->ByteItem), StringLength);
+
+ Descriptor->ExtendedIrq.ResourceLength = (UINT16)
+ (Descriptor->ExtendedIrq.ResourceLength + StringLength);
+ }
+
+ Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) -
+ ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType))
+ + OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoVendorLargeDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "VendorLong" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoVendorLargeDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *VendorData;
+ UINT32 i;
+
+
+ /* Count the number of data bytes */
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+
+ for (i = 0; InitializerOp; i++)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ break;
+ }
+ InitializerOp = InitializerOp->Asl.Next;
+ }
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE;
+ Descriptor->VendorLarge.ResourceLength = (UINT16) i;
+
+ /* Point to end-of-descriptor for vendor data */
+
+ VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ break;
+ }
+
+ VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer;
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2d.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2d.c
new file mode 100644
index 0000000000..25cbed950a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2d.c
@@ -0,0 +1,737 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2d - Large DWord address resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2d")
+
+/*
+ * This module contains the Dword (32-bit) address space descriptors:
+ *
+ * DwordIO
+ * DwordMemory
+ * DwordSpace
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoDwordIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "DwordIO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoDwordIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT8 *OptionalFields;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS32) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address32.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS32;
+ Descriptor->Address32.ResourceType = ACPI_ADDRESS_TYPE_IO_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS32);
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS32) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 2);
+ break;
+
+ case 2: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 3);
+ break;
+
+ case 3: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 1);
+ break;
+
+ case 4: /* Range Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 0, 3);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 0, 2);
+ break;
+
+ case 5: /* Address Granularity */
+
+ Descriptor->Address32.Granularity =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 6: /* Address Min */
+
+ Descriptor->Address32.Minimum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 7: /* Address Max */
+
+ Descriptor->Address32.Maximum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 8: /* Translation Offset */
+
+ Descriptor->Address32.TranslationOffset =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.TranslationOffset));
+ break;
+
+ case 9: /* Address Length */
+
+ Descriptor->Address32.AddressLength =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 10: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ /* Found a valid ResourceSourceIndex */
+
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address32.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 11: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ /* Found a valid ResourceSource */
+
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (Descriptor->Address32.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 12: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 13: /* Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 4, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 4);
+ break;
+
+ case 14: /* Translation Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address32.Minimum,
+ (UINT64) Descriptor->Address32.Maximum,
+ (UINT64) Descriptor->Address32.AddressLength,
+ (UINT64) Descriptor->Address32.Granularity,
+ Descriptor->Address32.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS32) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoDwordMemoryDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "DwordMemory" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoDwordMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS32) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address32.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS32;
+ Descriptor->Address32.ResourceType = ACPI_ADDRESS_TYPE_MEMORY_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS32);
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS32) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 1);
+ break;
+
+ case 2: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 2);
+ break;
+
+ case 3: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 3);
+ break;
+
+ case 4: /* Memory Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 1, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 1, 2);
+ break;
+
+ case 5: /* Read/Write Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 0);
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->Address32.Granularity =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->Address32.Minimum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->Address32.Maximum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->Address32.TranslationOffset =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->Address32.AddressLength =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address32.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 12: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (Descriptor->Address32.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 13: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+
+ case 14: /* Address Range */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 3, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 3, 2);
+ break;
+
+ case 15: /* Type */
+
+ RsSetFlagBits (&Descriptor->Address32.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address32.Minimum,
+ (UINT64) Descriptor->Address32.Maximum,
+ (UINT64) Descriptor->Address32.AddressLength,
+ (UINT64) Descriptor->Address32.Granularity,
+ Descriptor->Address32.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS32) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoDwordSpaceDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "DwordSpace" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoDwordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS32) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address32.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS32;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS32);
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS32) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Type */
+
+ Descriptor->Address32.ResourceType =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 1: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 2: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 1);
+ break;
+
+ case 3: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 2);
+ break;
+
+ case 4: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address32.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Flags), 3);
+ break;
+
+ case 5: /* Type-Specific flags */
+
+ Descriptor->Address32.SpecificFlags =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->Address32.Granularity =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->Address32.Minimum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->Address32.Maximum =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->Address32.TranslationOffset =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->Address32.AddressLength =
+ (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address32.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address32.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 12: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address32.ResourceLength = (UINT16)
+ (Descriptor->Address32.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 13: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST,
+ InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address32.Minimum,
+ (UINT64) Descriptor->Address32.Maximum,
+ (UINT64) Descriptor->Address32.AddressLength,
+ (UINT64) Descriptor->Address32.Granularity,
+ Descriptor->Address32.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS32) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2e.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2e.c
new file mode 100644
index 0000000000..ddb7ea37a1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2e.c
@@ -0,0 +1,571 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2e - Large Extended address resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2e")
+
+/*
+ * This module contains the Extended (64-bit) address space descriptors:
+ *
+ * ExtendedIO
+ * ExtendedMemory
+ * ExtendedSpace
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoExtendedIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "ExtendedIO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoExtendedIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 StringLength = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->ExtAddress64.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64;
+ Descriptor->ExtAddress64.ResourceType = ACPI_ADDRESS_TYPE_IO_RANGE;
+ Descriptor->ExtAddress64.RevisionID = AML_RESOURCE_EXTENDED_ADDRESS_REVISION;
+
+ Descriptor->ExtAddress64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* MinType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 2);
+ break;
+
+ case 2: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 3);
+ break;
+
+ case 3: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 1);
+ break;
+
+ case 4: /* Range Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 0, 3);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 0, 2);
+ break;
+
+ case 5: /* Address Granularity */
+
+ Descriptor->ExtAddress64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 6: /* Address Min */
+
+ Descriptor->ExtAddress64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 7: /* Address Max */
+
+ Descriptor->ExtAddress64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 8: /* Translation Offset */
+
+ Descriptor->ExtAddress64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TranslationOffset));
+ break;
+
+ case 9: /* Address Length */
+
+ Descriptor->ExtAddress64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 10: /* Type-Specific Attributes */
+
+ Descriptor->ExtAddress64.TypeSpecific = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TYPESPECIFICATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TypeSpecific));
+ break;
+
+ case 11: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 12: /* Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 4, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 4);
+ break;
+
+ case 13: /* Translation Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->ExtAddress64.Minimum,
+ Descriptor->ExtAddress64.Maximum,
+ Descriptor->ExtAddress64.AddressLength,
+ Descriptor->ExtAddress64.Granularity,
+ Descriptor->ExtAddress64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) +
+ StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoExtendedMemoryDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "ExtendedMemory" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoExtendedMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 StringLength = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->ExtAddress64.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64;
+ Descriptor->ExtAddress64.ResourceType = ACPI_ADDRESS_TYPE_MEMORY_RANGE;
+ Descriptor->ExtAddress64.RevisionID = AML_RESOURCE_EXTENDED_ADDRESS_REVISION;
+
+ Descriptor->ExtAddress64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 1);
+ break;
+
+ case 2: /* MinType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 2);
+ break;
+
+ case 3: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 3);
+ break;
+
+ case 4: /* Memory Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 1, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 1, 2);
+ break;
+
+ case 5: /* Read/Write Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 0);
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->ExtAddress64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->ExtAddress64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->ExtAddress64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->ExtAddress64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->ExtAddress64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* Type-Specific Attributes */
+
+ Descriptor->ExtAddress64.TypeSpecific = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TYPESPECIFICATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TypeSpecific));
+ break;
+
+ case 12: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+
+ case 13: /* Address Range */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 3, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 3, 2);
+ break;
+
+ case 14: /* Type */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->ExtAddress64.Minimum,
+ Descriptor->ExtAddress64.Maximum,
+ Descriptor->ExtAddress64.AddressLength,
+ Descriptor->ExtAddress64.Granularity,
+ Descriptor->ExtAddress64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) +
+ StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoExtendedSpaceDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "ExtendedSpace" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoExtendedSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT16 StringLength = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->ExtAddress64.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64;
+ Descriptor->ExtAddress64.RevisionID = AML_RESOURCE_EXTENDED_ADDRESS_REVISION;
+
+ Descriptor->ExtAddress64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Type */
+
+ Descriptor->ExtAddress64.ResourceType =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 1: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 2: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 1);
+ break;
+
+ case 3: /* MinType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 2);
+ break;
+
+ case 4: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 3);
+ break;
+
+ case 5: /* Type-Specific flags */
+
+ Descriptor->ExtAddress64.SpecificFlags =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->ExtAddress64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->ExtAddress64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->ExtAddress64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->ExtAddress64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->ExtAddress64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* Type-Specific Attributes */
+
+ Descriptor->ExtAddress64.TypeSpecific = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TYPESPECIFICATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TypeSpecific));
+ break;
+
+ case 12: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->ExtAddress64.Minimum,
+ Descriptor->ExtAddress64.Maximum,
+ Descriptor->ExtAddress64.AddressLength,
+ Descriptor->ExtAddress64.Granularity,
+ Descriptor->ExtAddress64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) +
+ StringLength;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2q.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2q.c
new file mode 100644
index 0000000000..16398e5ec2
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2q.c
@@ -0,0 +1,716 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2q - Large QWord address resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2q")
+
+/*
+ * This module contains the QWord (64-bit) address space descriptors:
+ *
+ * QWordIO
+ * QWordMemory
+ * QWordSpace
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoQwordIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "QwordIO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoQwordIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address64.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS64;
+ Descriptor->Address64.ResourceType = ACPI_ADDRESS_TYPE_IO_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
+ break;
+
+ case 2: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
+ break;
+
+ case 3: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
+ break;
+
+ case 4: /* Range Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 0, 3);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 0, 2);
+ break;
+
+ case 5: /* Address Granularity */
+
+ Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 6: /* Address Min */
+
+ Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 7: /* Address Max */
+
+ Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 8: /* Translation Offset */
+
+ Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
+ break;
+
+ case 9: /* Address Length */
+
+ Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 10: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address64.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 11: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (Descriptor->Address64.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 12: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 13: /* Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 4, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 4);
+ break;
+
+ case 14: /* Translation Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->Address64.Minimum,
+ Descriptor->Address64.Maximum,
+ Descriptor->Address64.AddressLength,
+ Descriptor->Address64.Granularity,
+ Descriptor->Address64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoQwordMemoryDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "QwordMemory" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoQwordMemoryDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address64.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS64;
+ Descriptor->Address64.ResourceType = ACPI_ADDRESS_TYPE_MEMORY_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
+ break;
+
+ case 2: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
+ break;
+
+ case 3: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
+ break;
+
+ case 4: /* Memory Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 1, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 1, 2);
+ break;
+
+ case 5: /* Read/Write Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 0, 1);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 0);
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address64.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 12: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (Descriptor->Address64.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 13: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+
+ case 14: /* Address Range */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 3, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMATTRIBUTES,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 3, 2);
+ break;
+
+ case 15: /* Type */
+
+ RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->Address64.Minimum,
+ Descriptor->Address64.Maximum,
+ Descriptor->Address64.AddressLength,
+ Descriptor->Address64.Granularity,
+ Descriptor->Address64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoQwordSpaceDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "QwordSpace" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoQwordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address64.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS64;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS64) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Type */
+
+ Descriptor->Address64.ResourceType =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 1: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 2: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
+ break;
+
+ case 3: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
+ break;
+
+ case 4: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
+ break;
+
+ case 5: /* Type-Specific flags */
+
+ Descriptor->Address64.SpecificFlags =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
+ RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address64.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 12: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address64.ResourceLength = (UINT16)
+ (Descriptor->Address64.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 13: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ Descriptor->Address64.Minimum,
+ Descriptor->Address64.Maximum,
+ Descriptor->Address64.AddressLength,
+ Descriptor->Address64.Granularity,
+ Descriptor->Address64.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2s.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2s.c
new file mode 100644
index 0000000000..73680c2204
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2s.c
@@ -0,0 +1,1197 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2s - Serial Large resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2s")
+
+
+static UINT16
+RsGetBufferDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp);
+
+static UINT16
+RsGetInterruptDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp);
+
+static BOOLEAN
+RsGetVendorData (
+ ACPI_PARSE_OBJECT *InitializerOp,
+ UINT8 *VendorData,
+ ACPI_SIZE DescriptorOffset);
+
+/*
+ * This module contains descriptors for serial buses and GPIO:
+ *
+ * GpioInt
+ * GpioIo
+ * I2cSerialBus
+ * SpiSerialBus
+ * UartSerialBus
+ */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsGetBufferDataLength
+ *
+ * PARAMETERS: InitializerOp - Current parse op, start of the resource
+ * descriptor
+ *
+ * RETURN: Length of the data buffer
+ *
+ * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data.
+ *
+ ******************************************************************************/
+
+static UINT16
+RsGetBufferDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp)
+{
+ UINT16 ExtraDataSize = 0;
+ ACPI_PARSE_OBJECT *DataList;
+
+
+ /* Find the byte-initializer list */
+
+ while (InitializerOp)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER)
+ {
+ /* First child is the optional length (ignore it here) */
+
+ DataList = InitializerOp->Asl.Child;
+ DataList = ASL_GET_PEER_NODE (DataList);
+
+ /* Count the data items (each one is a byte of data) */
+
+ while (DataList)
+ {
+ ExtraDataSize++;
+ DataList = ASL_GET_PEER_NODE (DataList);
+ }
+
+ return (ExtraDataSize);
+ }
+
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+ }
+
+ return (ExtraDataSize);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsGetInterruptDataLength
+ *
+ * PARAMETERS: InitializerOp - Current parse op, start of the resource
+ * descriptor
+ *
+ * RETURN: Length of the interrupt data list
+ *
+ * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO
+ * descriptors.
+ *
+ ******************************************************************************/
+
+static UINT16
+RsGetInterruptDataLength (
+ ACPI_PARSE_OBJECT *InitializerOp)
+{
+ UINT16 InterruptLength;
+ UINT32 i;
+
+
+ /* Count the interrupt numbers */
+
+ InterruptLength = 0;
+ for (i = 0; InitializerOp; i++)
+ {
+ InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
+
+ /* Interrupt list starts at offset 10 (Gpio descriptors) */
+
+ if (i >= 10)
+ {
+ InterruptLength += 2;
+ }
+ }
+
+ return (InterruptLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsGetVendorData
+ *
+ * PARAMETERS: InitializerOp - Current parse op, start of the resource
+ * descriptor.
+ * VendorData - Where the vendor data is returned
+ * DescriptorOffset - Where vendor data begins in descriptor
+ *
+ * RETURN: TRUE if valid vendor data was returned, FALSE otherwise.
+ *
+ * DESCRIPTION: Extract the vendor data and construct a vendor data buffer.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+RsGetVendorData (
+ ACPI_PARSE_OBJECT *InitializerOp,
+ UINT8 *VendorData,
+ ACPI_SIZE DescriptorOffset)
+{
+ ACPI_PARSE_OBJECT *BufferOp;
+ UINT32 SpecifiedLength = ACPI_UINT32_MAX;
+ UINT16 ActualLength = 0;
+
+
+ /* Vendor Data field is always optional */
+
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ return (FALSE);
+ }
+
+ BufferOp = InitializerOp->Asl.Child;
+ if (!BufferOp)
+ {
+ AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, "");
+ return (FALSE);
+ }
+
+ /* First child is the optional buffer length (WORD) */
+
+ if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer;
+ }
+
+ /* Insert field tag _VEN */
+
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA,
+ (UINT16) DescriptorOffset);
+
+ /* Walk the list of buffer initializers (each is one byte) */
+
+ BufferOp = RsCompleteNodeAndGetNext (BufferOp);
+ if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ while (BufferOp)
+ {
+ *VendorData = (UINT8) BufferOp->Asl.Value.Integer;
+ VendorData++;
+ ActualLength++;
+ BufferOp = RsCompleteNodeAndGetNext (BufferOp);
+ }
+ }
+
+ /* Length validation. Buffer cannot be of zero length */
+
+ if ((SpecifiedLength == 0) ||
+ ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0)))
+ {
+ AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL);
+ return (FALSE);
+ }
+
+ if (SpecifiedLength != ACPI_UINT32_MAX)
+ {
+ /* ActualLength > SpecifiedLength -> error */
+
+ if (ActualLength > SpecifiedLength)
+ {
+ AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL);
+ return (FALSE);
+ }
+
+ /* ActualLength < SpecifiedLength -> remark */
+
+ else if (ActualLength < SpecifiedLength)
+ {
+ AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL);
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoGpioIntDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "GpioInt" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoGpioIntDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ char *ResourceSource = NULL;
+ UINT8 *VendorData = NULL;
+ UINT16 *InterruptList = NULL;
+ UINT16 *PinList = NULL;
+ UINT16 ResSourceLength;
+ UINT16 VendorLength;
+ UINT16 InterruptLength;
+ UINT16 DescriptorSize;
+ UINT32 CurrentByteOffset;
+ UINT32 PinCount = 0;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ /*
+ * Calculate lengths for fields that have variable length:
+ * 1) Resource Source string
+ * 2) Vendor Data buffer
+ * 3) PIN (interrupt) list
+ */
+ ResSourceLength = RsGetStringDataLength (InitializerOp);
+ VendorLength = RsGetBufferDataLength (InitializerOp);
+ InterruptLength = RsGetInterruptDataLength (InitializerOp);
+
+ DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
+ ResSourceLength + VendorLength + InterruptLength;
+
+ /* Allocate the local resource node and initialize */
+
+ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Gpio.ResourceLength = DescriptorSize;
+ Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
+ Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
+ Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT;
+
+ /* Build pointers to optional areas */
+
+ InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
+ PinList = InterruptList;
+ ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
+ VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
+
+ /* Setup offsets within the descriptor */
+
+ Descriptor->Gpio.PinTableOffset = (UINT16)
+ ACPI_PTR_DIFF (InterruptList, Descriptor);
+
+ Descriptor->Gpio.ResSourceOffset = (UINT16)
+ ACPI_PTR_DIFF (ResourceSource, Descriptor);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, IntLen: %.2X\n",
+ "GpioInt", Descriptor->Gpio.ResourceLength, (UINT16) sizeof (AML_RESOURCE_GPIO),
+ ResSourceLength, VendorLength, InterruptLength);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0);
+ break;
+
+ case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2);
+ break;
+
+ case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2);
+ break;
+
+ case 3: /* Pin Config [BYTE] (_PPI) */
+
+ Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
+ break;
+
+ case 4: /* Debounce Timeout [WORD] (_DBT) */
+
+ Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
+ break;
+
+ case 5: /* ResSource [Optional Field - STRING] */
+
+ if (ResSourceLength)
+ {
+ /* Copy string to the descriptor */
+
+ strcpy (ResourceSource,
+ InitializerOp->Asl.Value.String);
+ }
+ break;
+
+ case 6: /* Resource Index */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 7: /* Resource Usage (consumer/producer) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 8: /* Resource Tag (Descriptor Name) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
+
+ /*
+ * Always set the VendorOffset even if there is no Vendor Data.
+ * This field is required in order to calculate the length
+ * of the ResourceSource at runtime.
+ */
+ Descriptor->Gpio.VendorOffset = (UINT16)
+ ACPI_PTR_DIFF (VendorData, Descriptor);
+
+ if (RsGetVendorData (InitializerOp, VendorData,
+ (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
+ {
+ Descriptor->Gpio.VendorLength = VendorLength;
+ }
+ break;
+
+ default:
+ /*
+ * PINs come through here, repeatedly. Each PIN must be a DWORD.
+ * NOTE: there is no "length" field for this, so from ACPI spec:
+ * The number of pins in the table can be calculated from:
+ * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
+ * (implies resource source must immediately follow the pin list.)
+ * Name: _PIN
+ */
+ *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
+ InterruptList++;
+ PinCount++;
+
+ /* Case 10: First interrupt number in list */
+
+ if (i == 10)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /* Must be at least one interrupt */
+
+ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
+ InitializerOp, NULL);
+ }
+
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_PIN,
+ CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
+ }
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ MpSaveGpioInfo (Info->MappingOp, Descriptor, PinCount, PinList, ResourceSource);
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoGpioIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "GpioIo" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoGpioIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ char *ResourceSource = NULL;
+ UINT8 *VendorData = NULL;
+ UINT16 *InterruptList = NULL;
+ UINT16 *PinList = NULL;
+ UINT16 ResSourceLength;
+ UINT16 VendorLength;
+ UINT16 InterruptLength;
+ UINT16 DescriptorSize;
+ UINT32 CurrentByteOffset;
+ UINT32 PinCount = 0;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ /*
+ * Calculate lengths for fields that have variable length:
+ * 1) Resource Source string
+ * 2) Vendor Data buffer
+ * 3) PIN (interrupt) list
+ */
+ ResSourceLength = RsGetStringDataLength (InitializerOp);
+ VendorLength = RsGetBufferDataLength (InitializerOp);
+ InterruptLength = RsGetInterruptDataLength (InitializerOp);
+ PinList = InterruptList;
+
+ DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
+ ResSourceLength + VendorLength + InterruptLength;
+
+ /* Allocate the local resource node and initialize */
+
+ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Gpio.ResourceLength = DescriptorSize;
+ Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
+ Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
+ Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO;
+
+ /* Build pointers to optional areas */
+
+ InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
+ PinList = InterruptList;
+ ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
+ VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
+
+ /* Setup offsets within the descriptor */
+
+ Descriptor->Gpio.PinTableOffset = (UINT16)
+ ACPI_PTR_DIFF (InterruptList, Descriptor);
+
+ Descriptor->Gpio.ResSourceOffset = (UINT16)
+ ACPI_PTR_DIFF (ResourceSource, Descriptor);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, IntLen: %.2X\n",
+ "GpioIo", Descriptor->Gpio.ResourceLength, (UINT16) sizeof (AML_RESOURCE_GPIO),
+ ResSourceLength, VendorLength, InterruptLength);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Share Type [Flags] (_SHR) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3);
+ break;
+
+ case 1: /* Pin Config [BYTE] (_PPI) */
+
+ Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
+ break;
+
+ case 2: /* Debounce Timeout [WORD] (_DBT) */
+
+ Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
+ break;
+
+ case 3: /* Drive Strength [WORD] (_DRS) */
+
+ Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength));
+ break;
+
+ case 4: /* I/O Restriction [Flag] (_IOR) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2);
+ break;
+
+ case 5: /* ResSource [Optional Field - STRING] */
+
+ if (ResSourceLength)
+ {
+ /* Copy string to the descriptor */
+
+ strcpy (ResourceSource,
+ InitializerOp->Asl.Value.String);
+ }
+ break;
+
+ case 6: /* Resource Index */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 7: /* Resource Usage (consumer/producer) */
+
+ RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 8: /* Resource Tag (Descriptor Name) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
+ /*
+ * Always set the VendorOffset even if there is no Vendor Data.
+ * This field is required in order to calculate the length
+ * of the ResourceSource at runtime.
+ */
+ Descriptor->Gpio.VendorOffset = (UINT16)
+ ACPI_PTR_DIFF (VendorData, Descriptor);
+
+ if (RsGetVendorData (InitializerOp, VendorData,
+ (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
+ {
+ Descriptor->Gpio.VendorLength = VendorLength;
+ }
+ break;
+
+ default:
+ /*
+ * PINs come through here, repeatedly. Each PIN must be a DWORD.
+ * NOTE: there is no "length" field for this, so from ACPI spec:
+ * The number of pins in the table can be calculated from:
+ * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
+ * (implies resource source must immediately follow the pin list.)
+ * Name: _PIN
+ */
+ *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
+ InterruptList++;
+ PinCount++;
+
+ /* Case 10: First interrupt number in list */
+
+ if (i == 10)
+ {
+ if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ /* Must be at least one interrupt */
+
+ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
+ InitializerOp, NULL);
+ }
+
+ /* Check now for duplicates in list */
+
+ RsCheckListForDuplicates (InitializerOp);
+
+ /* Create a named field at the start of the list */
+
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_PIN,
+ CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
+ }
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ MpSaveGpioInfo (Info->MappingOp, Descriptor, PinCount, PinList, ResourceSource);
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoI2cSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "I2cSerialBus" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoI2cSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ char *ResourceSource = NULL;
+ UINT8 *VendorData = NULL;
+ UINT16 ResSourceLength;
+ UINT16 VendorLength;
+ UINT16 DescriptorSize;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ /*
+ * Calculate lengths for fields that have variable length:
+ * 1) Resource Source string
+ * 2) Vendor Data buffer
+ */
+ ResSourceLength = RsGetStringDataLength (InitializerOp);
+ VendorLength = RsGetBufferDataLength (InitializerOp);
+
+ DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) +
+ ResSourceLength + VendorLength;
+
+ /* Allocate the local resource node and initialize */
+
+ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->I2cSerialBus.ResourceLength = DescriptorSize;
+ Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
+ Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION;
+ Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION;
+ Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE;
+ Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength;
+
+ /* Build pointers to optional areas */
+
+ VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS));
+ ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, TypLen: %.2X\n",
+ "I2cSerialBus", Descriptor->I2cSerialBus.ResourceLength,
+ (UINT16) sizeof (AML_RESOURCE_I2C_SERIALBUS), ResSourceLength,
+ VendorLength, Descriptor->I2cSerialBus.TypeDataLength);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Slave Address [WORD] (_ADR) */
+
+ Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress));
+ break;
+
+ case 1: /* Slave Mode [Flag] (_SLV) */
+
+ RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
+ break;
+
+ case 2: /* Connection Speed [DWORD] (_SPE) */
+
+ Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed));
+ break;
+
+ case 3: /* Addressing Mode [Flag] (_MOD) */
+
+ RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0);
+ break;
+
+ case 4: /* ResSource [Optional Field - STRING] */
+
+ if (ResSourceLength)
+ {
+ /* Copy string to the descriptor */
+
+ strcpy (ResourceSource,
+ InitializerOp->Asl.Value.String);
+ }
+ break;
+
+ case 5: /* Resource Index */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Descriptor->I2cSerialBus.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 6: /* Resource Usage (consumer/producer) */
+
+ RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1);
+ break;
+
+ case 7: /* Resource Tag (Descriptor Name) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
+
+ RsGetVendorData (InitializerOp, VendorData,
+ CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS));
+ break;
+
+ default: /* Ignore any extra nodes */
+
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoSpiSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoSpiSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ char *ResourceSource = NULL;
+ UINT8 *VendorData = NULL;
+ UINT16 ResSourceLength;
+ UINT16 VendorLength;
+ UINT16 DescriptorSize;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ /*
+ * Calculate lengths for fields that have variable length:
+ * 1) Resource Source string
+ * 2) Vendor Data buffer
+ */
+ ResSourceLength = RsGetStringDataLength (InitializerOp);
+ VendorLength = RsGetBufferDataLength (InitializerOp);
+
+ DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) +
+ ResSourceLength + VendorLength;
+
+ /* Allocate the local resource node and initialize */
+
+ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->SpiSerialBus.ResourceLength = DescriptorSize;
+ Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
+ Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION;
+ Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION;
+ Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE;
+ Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength;
+
+ /* Build pointers to optional areas */
+
+ VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_SPI_SERIALBUS));
+ ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, TypLen: %.2X\n",
+ "SpiSerialBus", Descriptor->SpiSerialBus.ResourceLength,
+ (UINT16) sizeof (AML_RESOURCE_SPI_SERIALBUS), ResSourceLength,
+ VendorLength, Descriptor->SpiSerialBus.TypeDataLength);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Device Selection [WORD] (_ADR) */
+
+ Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection));
+ break;
+
+ case 1: /* Device Polarity [Flag] (_DPL) */
+
+ RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1);
+ break;
+
+ case 2: /* Wire Mode [Flag] (_MOD) */
+
+ RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0);
+ break;
+
+ case 3: /* Device Bit Length [BYTE] (_LEN) */
+
+ Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength));
+ break;
+
+ case 4: /* Slave Mode [Flag] (_SLV) */
+
+ RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0);
+ break;
+
+ case 5: /* Connection Speed [DWORD] (_SPE) */
+
+ Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed));
+ break;
+
+ case 6: /* Clock Polarity [BYTE] (_POL) */
+
+ Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity));
+ break;
+
+ case 7: /* Clock Phase [BYTE] (_PHA) */
+
+ Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase));
+ break;
+
+ case 8: /* ResSource [Optional Field - STRING] */
+
+ if (ResSourceLength)
+ {
+ /* Copy string to the descriptor */
+
+ strcpy (ResourceSource,
+ InitializerOp->Asl.Value.String);
+ }
+ break;
+
+ case 9: /* Resource Index */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Descriptor->SpiSerialBus.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 10: /* Resource Usage (consumer/producer) */
+
+ RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1);
+ break;
+
+ case 11: /* Resource Tag (Descriptor Name) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 12: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
+
+ RsGetVendorData (InitializerOp, VendorData,
+ CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS));
+ break;
+
+ default: /* Ignore any extra nodes */
+
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoUartSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "UART Serial Bus" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoUartSerialBusDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ASL_RESOURCE_NODE *Rnode;
+ char *ResourceSource = NULL;
+ UINT8 *VendorData = NULL;
+ UINT16 ResSourceLength;
+ UINT16 VendorLength;
+ UINT16 DescriptorSize;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ /*
+ * Calculate lengths for fields that have variable length:
+ * 1) Resource Source string
+ * 2) Vendor Data buffer
+ */
+ ResSourceLength = RsGetStringDataLength (InitializerOp);
+ VendorLength = RsGetBufferDataLength (InitializerOp);
+
+ DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) +
+ ResSourceLength + VendorLength;
+
+ /* Allocate the local resource node and initialize */
+
+ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->UartSerialBus.ResourceLength = DescriptorSize;
+ Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
+ Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION;
+ Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION;
+ Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE;
+ Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength;
+
+ /* Build pointers to optional areas */
+
+ VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS));
+ ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, TypLen: %.2X\n",
+ "UartSerialBus", Descriptor->UartSerialBus.ResourceLength,
+ (UINT16) sizeof (AML_RESOURCE_UART_SERIALBUS), ResSourceLength,
+ VendorLength, Descriptor->UartSerialBus.TypeDataLength);
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */
+
+ Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer;
+ RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate));
+ break;
+
+ case 1: /* Bits Per Byte [Flags] (_LEN) */
+
+ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3);
+ break;
+
+ case 2: /* Stop Bits [Flags] (_STB) */
+
+ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2);
+ break;
+
+ case 3: /* Lines In Use [BYTE] (_LIN) */
+
+ Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled));
+ break;
+
+ case 4: /* Endianness [Flag] (_END) */
+
+ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7);
+ break;
+
+ case 5: /* Parity [BYTE] (_PAR) */
+
+ Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer;
+ RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity));
+ break;
+
+ case 6: /* Flow Control [Flags] (_FLC) */
+
+ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2);
+ break;
+
+ case 7: /* Rx Buffer Size [WORD] (_RXL) */
+
+ Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize));
+ break;
+
+ case 8: /* Tx Buffer Size [WORD] (_TXL) */
+
+ Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize));
+ break;
+
+ case 9: /* ResSource [Optional Field - STRING] */
+
+ if (ResSourceLength)
+ {
+ /* Copy string to the descriptor */
+
+ strcpy (ResourceSource,
+ InitializerOp->Asl.Value.String);
+ }
+ break;
+
+ case 10: /* Resource Index */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ Descriptor->UartSerialBus.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
+ }
+ break;
+
+ case 11: /* Resource Usage (consumer/producer) */
+
+ RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1);
+
+ /*
+ * Slave Mode [Flag] (_SLV)
+ *
+ * Note: There is no SlaveMode argument to the UartSerialBus macro, but
+ * we add this name anyway to allow the flag to be set by ASL in the
+ * rare case where there is a slave mode associated with the UART.
+ */
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0);
+ break;
+
+ case 12: /* Resource Tag (Descriptor Name) */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
+
+ RsGetVendorData (InitializerOp, VendorData,
+ CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS));
+ break;
+
+ default: /* Ignore any extra nodes */
+
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2w.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2w.c
new file mode 100644
index 0000000000..a9f4771fe1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrestype2w.c
@@ -0,0 +1,697 @@
+/******************************************************************************
+ *
+ * Module Name: aslrestype2w - Large Word address resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslrestype2w")
+
+/*
+ * This module contains the Word (16-bit) address space descriptors:
+ *
+ * WordIO
+ * WordMemory
+ * WordSpace
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoWordIoDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "WordIO" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoWordIoDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
+ Descriptor->Address16.ResourceType = ACPI_ADDRESS_TYPE_IO_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS16) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
+ break;
+
+ case 2: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
+ break;
+
+ case 3: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
+ break;
+
+ case 4: /* Range Type */
+
+ RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 0, 3);
+ RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 0, 2);
+ break;
+
+ case 5: /* Address Granularity */
+
+ Descriptor->Address16.Granularity = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 6: /* Address Min */
+
+ Descriptor->Address16.Minimum = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 7: /* Address Max */
+
+ Descriptor->Address16.Maximum = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 8: /* Translation Offset */
+
+ Descriptor->Address16.TranslationOffset = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
+ break;
+
+ case 9: /* Address Length */
+
+ Descriptor->Address16.AddressLength = (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 10: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address16.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 11: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (Descriptor->Address16.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 12: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ case 13: /* Type */
+
+ RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 4, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 4);
+ break;
+
+ case 14: /* Translation Type */
+
+ RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 5, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 5);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address16.Minimum,
+ (UINT64) Descriptor->Address16.Maximum,
+ (UINT64) Descriptor->Address16.AddressLength,
+ (UINT64) Descriptor->Address16.Granularity,
+ Descriptor->Address16.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoWordBusNumberDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "WordBusNumber" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoWordBusNumberDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
+ Descriptor->Address16.ResourceType = ACPI_ADDRESS_TYPE_BUS_NUMBER_RANGE;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS16) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 1: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
+ break;
+
+ case 2: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
+ break;
+
+ case 3: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
+ break;
+
+ case 4: /* Address Granularity */
+
+ Descriptor->Address16.Granularity =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 5: /* Min Address */
+
+ Descriptor->Address16.Minimum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 6: /* Max Address */
+
+ Descriptor->Address16.Maximum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 7: /* Translation Offset */
+
+ Descriptor->Address16.TranslationOffset =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
+ break;
+
+ case 8: /* Address Length */
+
+ Descriptor->Address16.AddressLength =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 9: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address16.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 10: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (Descriptor->Address16.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 11: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address16.Minimum,
+ (UINT64) Descriptor->Address16.Maximum,
+ (UINT64) Descriptor->Address16.AddressLength,
+ (UINT64) Descriptor->Address16.Granularity,
+ Descriptor->Address16.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: RsDoWordSpaceDescriptor
+ *
+ * PARAMETERS: Info - Parse Op and resource template offset
+ *
+ * RETURN: Completed resource node
+ *
+ * DESCRIPTION: Construct a long "WordSpace" descriptor
+ *
+ ******************************************************************************/
+
+ASL_RESOURCE_NODE *
+RsDoWordSpaceDescriptor (
+ ASL_RESOURCE_INFO *Info)
+{
+ AML_RESOURCE *Descriptor;
+ ACPI_PARSE_OBJECT *InitializerOp;
+ ACPI_PARSE_OBJECT *MinOp = NULL;
+ ACPI_PARSE_OBJECT *MaxOp = NULL;
+ ACPI_PARSE_OBJECT *LengthOp = NULL;
+ ACPI_PARSE_OBJECT *GranOp = NULL;
+ ASL_RESOURCE_NODE *Rnode;
+ UINT8 *OptionalFields;
+ UINT16 StringLength = 0;
+ UINT32 OptionIndex = 0;
+ UINT32 CurrentByteOffset;
+ UINT32 i;
+ BOOLEAN ResSourceIndex = FALSE;
+
+
+ InitializerOp = Info->DescriptorTypeOp->Asl.Child;
+ StringLength = RsGetStringDataLength (InitializerOp);
+ CurrentByteOffset = Info->CurrentByteOffset;
+
+ Rnode = RsAllocateResourceNode (
+ sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
+
+ Descriptor = Rnode->Buffer;
+ Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
+
+ /*
+ * Initial descriptor length -- may be enlarged if there are
+ * optional fields present
+ */
+ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (sizeof (AML_RESOURCE_ADDRESS16) -
+ sizeof (AML_RESOURCE_LARGE_HEADER));
+
+ /* Process all child initialization nodes */
+
+ for (i = 0; InitializerOp; i++)
+ {
+ switch (i)
+ {
+ case 0: /* Resource Type */
+
+ Descriptor->Address16.ResourceType =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 1: /* Resource Usage */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
+ break;
+
+ case 2: /* DecodeType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
+ break;
+
+ case 3: /* MinType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
+ break;
+
+ case 4: /* MaxType */
+
+ RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
+ RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
+ break;
+
+ case 5: /* Type-Specific flags */
+
+ Descriptor->Address16.SpecificFlags =
+ (UINT8) InitializerOp->Asl.Value.Integer;
+ break;
+
+ case 6: /* Address Granularity */
+
+ Descriptor->Address16.Granularity =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
+ GranOp = InitializerOp;
+ break;
+
+ case 7: /* Min Address */
+
+ Descriptor->Address16.Minimum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
+ MinOp = InitializerOp;
+ break;
+
+ case 8: /* Max Address */
+
+ Descriptor->Address16.Maximum =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
+ MaxOp = InitializerOp;
+ break;
+
+ case 9: /* Translation Offset */
+
+ Descriptor->Address16.TranslationOffset =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
+ break;
+
+ case 10: /* Address Length */
+
+ Descriptor->Address16.AddressLength =
+ (UINT16) InitializerOp->Asl.Value.Integer;
+ RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
+ CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
+ LengthOp = InitializerOp;
+ break;
+
+ case 11: /* ResSourceIndex [Optional Field - BYTE] */
+
+ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
+ {
+ OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
+ OptionIndex++;
+ Descriptor->Address16.ResourceLength++;
+ ResSourceIndex = TRUE;
+ }
+ break;
+
+ case 12: /* ResSource [Optional Field - STRING] */
+
+ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
+ (InitializerOp->Asl.Value.String))
+ {
+ if (StringLength)
+ {
+ Descriptor->Address16.ResourceLength = (UINT16)
+ (Descriptor->Address16.ResourceLength + StringLength);
+
+ strcpy ((char *)
+ &OptionalFields[OptionIndex],
+ InitializerOp->Asl.Value.String);
+
+ /* ResourceSourceIndex must also be valid */
+
+ if (!ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
+ InitializerOp, NULL);
+ }
+ }
+ }
+
+#if 0
+ /*
+ * Not a valid ResourceSource, ResourceSourceIndex must also
+ * be invalid
+ */
+ else if (ResSourceIndex)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
+ InitializerOp, NULL);
+ }
+#endif
+ break;
+
+ case 13: /* ResourceTag */
+
+ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
+ break;
+ }
+
+ InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
+ }
+
+ /* Validate the Min/Max/Len/Gran values */
+
+ RsLargeAddressCheck (
+ (UINT64) Descriptor->Address16.Minimum,
+ (UINT64) Descriptor->Address16.Maximum,
+ (UINT64) Descriptor->Address16.AddressLength,
+ (UINT64) Descriptor->Address16.Granularity,
+ Descriptor->Address16.Flags,
+ MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
+
+ Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
+ OptionIndex + StringLength;
+ return (Rnode);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrules.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrules.y
new file mode 100644
index 0000000000..dbe0882ca8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslrules.y
@@ -0,0 +1,2991 @@
+NoEcho('
+/******************************************************************************
+ *
+ * Module Name: aslrules.y - Bison/Yacc production rules
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+')
+
+/*******************************************************************************
+ *
+ * Production rules start here
+ *
+ ******************************************************************************/
+
+/*
+ * ASL Names
+ *
+ * Root rule. Allow multiple #line directives before the definition block
+ * to handle output from preprocessors
+ */
+ASLCode
+ : DefinitionBlockTerm
+ | error {YYABORT; $$ = NULL;}
+ ;
+
+/*
+ * Blocks, Data, and Opcodes
+ */
+
+/*
+ * Note concerning support for "module-level code".
+ *
+ * ACPI 1.0 allowed Type1 and Type2 executable opcodes outside of control
+ * methods (the so-called module-level code.) This support was explicitly
+ * removed in ACPI 2.0, but this type of code continues to be created by
+ * BIOS vendors. In order to support the disassembly and recompilation of
+ * such code (and the porting of ASL code to iASL), iASL supports this
+ * code in violation of the current ACPI specification.
+ *
+ * The grammar change to support module-level code is to revert the
+ * {ObjectList} portion of the DefinitionBlockTerm in ACPI 2.0 to the
+ * original use of {TermList} instead (see below.) This allows the use
+ * of Type1 and Type2 opcodes at module level.
+ */
+DefinitionBlockTerm
+ : PARSEOP_DEFINITIONBLOCK '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFINITIONBLOCK);}
+ String ','
+ String ','
+ ByteConst ','
+ String ','
+ String ','
+ DWordConst
+ ')' {TrSetEndLineNumber ($<n>3);}
+ '{' TermList '}' {$$ = TrLinkChildren ($<n>3,7,$4,$6,$8,$10,$12,$14,$18);}
+ ;
+
+ /*
+ * ASL Extensions: C-style math/logical operators and expressions.
+ * The implementation transforms these operators into the standard
+ * AML opcodes and syntax.
+ *
+ * Supported operators and precedence rules (high-to-low)
+ *
+ * NOTE: The operator precedence and associativity rules are
+ * implemented by the tokens in asltokens.y
+ *
+ * (left-to-right):
+ * 1) ( ) expr++ expr--
+ *
+ * (right-to-left):
+ * 2) ! ~
+ *
+ * (left-to-right):
+ * 3) * / %
+ * 4) + -
+ * 5) >> <<
+ * 6) < > <= >=
+ * 7) == !=
+ * 8) &
+ * 9) ^
+ * 10) |
+ * 11) &&
+ * 12) ||
+ *
+ * (right-to-left):
+ * 13) = += -= *= /= %= <<= >>= &= ^= |=
+ */
+Expression
+
+ /* Unary operators */
+
+ : PARSEOP_EXP_LOGICAL_NOT {$<n>$ = TrCreateLeafNode (PARSEOP_LNOT);}
+ TermArg {$$ = TrLinkChildren ($<n>2,1,$3);}
+ | PARSEOP_EXP_NOT {$<n>$ = TrCreateLeafNode (PARSEOP_NOT);}
+ TermArg {$$ = TrLinkChildren ($<n>2,2,$3,TrCreateNullTarget ());}
+
+ | SuperName PARSEOP_EXP_INCREMENT {$<n>$ = TrCreateLeafNode (PARSEOP_INCREMENT);}
+ {$$ = TrLinkChildren ($<n>3,1,$1);}
+ | SuperName PARSEOP_EXP_DECREMENT {$<n>$ = TrCreateLeafNode (PARSEOP_DECREMENT);}
+ {$$ = TrLinkChildren ($<n>3,1,$1);}
+
+ /* Binary operators: math and logical */
+
+ | TermArg PARSEOP_EXP_ADD {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_DIVIDE {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);}
+ TermArg {$$ = TrLinkChildren ($<n>3,4,$1,$4,TrCreateNullTarget (),
+ TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_MODULO {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_MULTIPLY {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_SHIFT_LEFT {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_SHIFT_RIGHT {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_SUBTRACT {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+
+ | TermArg PARSEOP_EXP_AND {$<n>$ = TrCreateLeafNode (PARSEOP_AND);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_OR {$<n>$ = TrCreateLeafNode (PARSEOP_OR);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+ | TermArg PARSEOP_EXP_XOR {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateNullTarget ());}
+
+ | TermArg PARSEOP_EXP_GREATER {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+ | TermArg PARSEOP_EXP_GREATER_EQUAL {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATEREQUAL);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+ | TermArg PARSEOP_EXP_LESS {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+ | TermArg PARSEOP_EXP_LESS_EQUAL {$<n>$ = TrCreateLeafNode (PARSEOP_LLESSEQUAL);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+
+ | TermArg PARSEOP_EXP_EQUAL {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+ | TermArg PARSEOP_EXP_NOT_EQUAL {$<n>$ = TrCreateLeafNode (PARSEOP_LNOTEQUAL);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+
+ | TermArg PARSEOP_EXP_LOGICAL_AND {$<n>$ = TrCreateLeafNode (PARSEOP_LAND);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+ | TermArg PARSEOP_EXP_LOGICAL_OR {$<n>$ = TrCreateLeafNode (PARSEOP_LOR);}
+ TermArg {$$ = TrLinkChildren ($<n>3,2,$1,$4);}
+
+ /* Parentheses */
+
+ | '(' TermArg ')' { $$ = $2;}
+ ;
+
+EqualsTerm
+
+ /* All assignment-type operations */
+
+ : SuperName PARSEOP_EXP_EQUALS
+ TermArg {$$ = TrCreateAssignmentNode ($1, $3);}
+
+ | TermArg PARSEOP_EXP_ADD_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_DIV_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);}
+ TermArg {$$ = TrLinkChildren ($<n>3,4,$1,$4,TrCreateNullTarget (),
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_MOD_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_MUL_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_SHL_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_SHR_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_SUB_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_AND_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_AND);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_OR_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_OR);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+
+ | TermArg PARSEOP_EXP_XOR_EQ {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);}
+ TermArg {$$ = TrLinkChildren ($<n>3,3,$1,$4,
+ TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));}
+ ;
+
+
+/* ACPI 3.0 -- allow semicolons between terms */
+
+TermList
+ : {$$ = NULL;}
+ | TermList Term {$$ = TrLinkPeerNode (TrSetNodeFlags ($1, NODE_RESULT_NOT_USED),$2);}
+ | TermList Term ';' {$$ = TrLinkPeerNode (TrSetNodeFlags ($1, NODE_RESULT_NOT_USED),$2);}
+ | TermList ';' Term {$$ = TrLinkPeerNode (TrSetNodeFlags ($1, NODE_RESULT_NOT_USED),$3);}
+ | TermList ';' Term ';' {$$ = TrLinkPeerNode (TrSetNodeFlags ($1, NODE_RESULT_NOT_USED),$3);}
+ ;
+
+Term
+ : Object {}
+ | Type1Opcode {}
+ | Type2Opcode {}
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Type2StringOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Type2BufferOpcode {}
+ | Type2BufferOrStringOpcode {}
+ | error {$$ = AslDoError(); yyclearin;}
+ ;
+
+CompilerDirective
+ : IncludeTerm {}
+ | ExternalTerm {}
+ ;
+
+ObjectList
+ : {$$ = NULL;}
+ | ObjectList Object {$$ = TrLinkPeerNode ($1,$2);}
+ | error {$$ = AslDoError(); yyclearin;}
+ ;
+
+Object
+ : CompilerDirective {}
+ | NamedObject {}
+ | NameSpaceModifier {}
+ ;
+
+DataObject
+ : BufferData {}
+ | PackageData {}
+ | IntegerData {}
+ | StringData {}
+ ;
+
+BufferData
+ : Type5Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Type2BufferOrStringOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Type2BufferOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | BufferTerm {}
+ ;
+
+PackageData
+ : PackageTerm {}
+ ;
+
+IntegerData
+ : Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Type3Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | Integer {}
+ | ConstTerm {}
+ ;
+
+StringData
+ : Type2StringOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | String {}
+ ;
+
+NamedObject
+ : BankFieldTerm {}
+ | CreateBitFieldTerm {}
+ | CreateByteFieldTerm {}
+ | CreateDWordFieldTerm {}
+ | CreateFieldTerm {}
+ | CreateQWordFieldTerm {}
+ | CreateWordFieldTerm {}
+ | DataRegionTerm {}
+ | DeviceTerm {}
+ | EventTerm {}
+ | FieldTerm {}
+ | FunctionTerm {}
+ | IndexFieldTerm {}
+ | MethodTerm {}
+ | MutexTerm {}
+ | OpRegionTerm {}
+ | PowerResTerm {}
+ | ProcessorTerm {}
+ | ThermalZoneTerm {}
+ ;
+
+NameSpaceModifier
+ : AliasTerm {}
+ | NameTerm {}
+ | ScopeTerm {}
+ ;
+
+MethodInvocationTerm
+ : NameString '(' {TrUpdateNode (PARSEOP_METHODCALL, $1);}
+ ArgList ')' {$$ = TrLinkChildNode ($1,$4);}
+ ;
+
+ArgList
+ : {$$ = NULL;}
+ | TermArg
+ | ArgList ',' /* Allows a trailing comma at list end */
+ | ArgList ','
+ TermArg {$$ = TrLinkPeerNode ($1,$3);}
+ ;
+
+/*
+Removed from TermArg due to reduce/reduce conflicts
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | Type2StringOpcode {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | Type2BufferOpcode {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | Type2BufferOrStringOpcode {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+
+*/
+
+TermArg
+ : Type2Opcode {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | DataObject {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | NameString {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | ArgTerm {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ | LocalTerm {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}
+ ;
+
+Target
+ : {$$ = TrCreateNullTarget ();} /* Placeholder is a ZeroOp object */
+ | ',' {$$ = TrCreateNullTarget ();} /* Placeholder is a ZeroOp object */
+ | ',' SuperName {$$ = TrSetNodeFlags ($2, NODE_IS_TARGET);}
+ ;
+
+RequiredTarget
+ : ',' SuperName {$$ = TrSetNodeFlags ($2, NODE_IS_TARGET);}
+ ;
+
+SimpleTarget
+ : NameString {}
+ | LocalTerm {}
+ | ArgTerm {}
+ ;
+
+/* Rules for specifying the type of one method argument or return value */
+
+ParameterTypePackage
+ : {$$ = NULL;}
+ | ObjectTypeKeyword {$$ = $1;}
+ | ParameterTypePackage ','
+ ObjectTypeKeyword {$$ = TrLinkPeerNodes (2,$1,$3);}
+ ;
+
+ParameterTypePackageList
+ : {$$ = NULL;}
+ | ObjectTypeKeyword {$$ = $1;}
+ | '{' ParameterTypePackage '}' {$$ = $2;}
+ ;
+
+OptionalParameterTypePackage
+ : {$$ = TrCreateLeafNode (PARSEOP_DEFAULT_ARG);}
+ | ',' ParameterTypePackageList {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_DEFAULT_ARG),1,$2);}
+ ;
+
+/* Rules for specifying the types for method arguments */
+
+ParameterTypesPackage
+ : ParameterTypePackageList {$$ = $1;}
+ | ParameterTypesPackage ','
+ ParameterTypePackageList {$$ = TrLinkPeerNodes (2,$1,$3);}
+ ;
+
+ParameterTypesPackageList
+ : {$$ = NULL;}
+ | ObjectTypeKeyword {$$ = $1;}
+ | '{' ParameterTypesPackage '}' {$$ = $2;}
+ ;
+
+OptionalParameterTypesPackage
+ : {$$ = TrCreateLeafNode (PARSEOP_DEFAULT_ARG);}
+ | ',' ParameterTypesPackageList {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_DEFAULT_ARG),1,$2);}
+ ;
+
+
+/* Opcode types */
+
+Type1Opcode
+ : BreakTerm {}
+ | BreakPointTerm {}
+ | ContinueTerm {}
+ | FatalTerm {}
+ | IfElseTerm {}
+ | LoadTerm {}
+ | NoOpTerm {}
+ | NotifyTerm {}
+ | ReleaseTerm {}
+ | ResetTerm {}
+ | ReturnTerm {}
+ | SignalTerm {}
+ | SleepTerm {}
+ | StallTerm {}
+ | SwitchTerm {}
+ | UnloadTerm {}
+ | WhileTerm {}
+ ;
+
+Type2Opcode
+ : AcquireTerm {}
+ | CondRefOfTerm {}
+ | CopyObjectTerm {}
+ | DerefOfTerm {}
+ | ObjectTypeTerm {}
+ | RefOfTerm {}
+ | SizeOfTerm {}
+ | StoreTerm {}
+ | EqualsTerm {}
+ | TimerTerm {}
+ | WaitTerm {}
+ | MethodInvocationTerm {}
+ ;
+
+/*
+ * Type 3/4/5 opcodes
+ */
+
+Type2IntegerOpcode /* "Type3" opcodes */
+ : Expression {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | AddTerm {}
+ | AndTerm {}
+ | DecTerm {}
+ | DivideTerm {}
+ | FindSetLeftBitTerm {}
+ | FindSetRightBitTerm {}
+ | FromBCDTerm {}
+ | IncTerm {}
+ | IndexTerm {}
+ | LAndTerm {}
+ | LEqualTerm {}
+ | LGreaterTerm {}
+ | LGreaterEqualTerm {}
+ | LLessTerm {}
+ | LLessEqualTerm {}
+ | LNotTerm {}
+ | LNotEqualTerm {}
+ | LoadTableTerm {}
+ | LOrTerm {}
+ | MatchTerm {}
+ | ModTerm {}
+ | MultiplyTerm {}
+ | NAndTerm {}
+ | NOrTerm {}
+ | NotTerm {}
+ | OrTerm {}
+ | ShiftLeftTerm {}
+ | ShiftRightTerm {}
+ | SubtractTerm {}
+ | ToBCDTerm {}
+ | ToIntegerTerm {}
+ | XOrTerm {}
+ ;
+
+Type2StringOpcode /* "Type4" Opcodes */
+ : ToDecimalStringTerm {}
+ | ToHexStringTerm {}
+ | ToStringTerm {}
+ ;
+
+Type2BufferOpcode /* "Type5" Opcodes */
+ : ToBufferTerm {}
+ | ConcatResTerm {}
+ ;
+
+Type2BufferOrStringOpcode
+ : ConcatTerm {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST);}
+ | PrintfTerm {}
+ | FprintfTerm {}
+ | MidTerm {}
+ ;
+
+/*
+ * A type 3 opcode evaluates to an Integer and cannot have a destination operand
+ */
+
+Type3Opcode
+ : EISAIDTerm {}
+ ;
+
+/* Obsolete
+Type4Opcode
+ : ConcatTerm {}
+ | ToDecimalStringTerm {}
+ | ToHexStringTerm {}
+ | MidTerm {}
+ | ToStringTerm {}
+ ;
+*/
+
+
+Type5Opcode
+ : ResourceTemplateTerm {}
+ | UnicodeTerm {}
+ | ToPLDTerm {}
+ | ToUUIDTerm {}
+ ;
+
+Type6Opcode
+ : RefOfTerm {}
+ | DerefOfTerm {}
+ | IndexTerm {}
+ | MethodInvocationTerm {}
+ ;
+
+IncludeTerm
+ : PARSEOP_INCLUDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCLUDE);}
+ String ')' {TrLinkChildren ($<n>3,1,$4);FlOpenIncludeFile ($4);}
+ TermList
+ IncludeEndTerm {$$ = TrLinkPeerNodes (3,$<n>3,$7,$8);}
+ ;
+
+IncludeEndTerm
+ : PARSEOP_INCLUDE_END {$$ = TrCreateLeafNode (PARSEOP_INCLUDE_END);}
+ ;
+
+ExternalTerm
+ : PARSEOP_EXTERNAL '('
+ NameString
+ OptionalObjectTypeKeyword
+ OptionalParameterTypePackage
+ OptionalParameterTypesPackage
+ ')' {$$ = TrCreateNode (PARSEOP_EXTERNAL,4,$3,$4,$5,$6);}
+ | PARSEOP_EXTERNAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Named Objects *******************************************************/
+
+
+BankFieldTerm
+ : PARSEOP_BANKFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_BANKFIELD);}
+ NameString
+ NameStringItem
+ TermArgItem
+ ',' AccessTypeKeyword
+ ',' LockRuleKeyword
+ ',' UpdateRuleKeyword
+ ')' '{'
+ FieldUnitList '}' {$$ = TrLinkChildren ($<n>3,7,$4,$5,$6,$8,$10,$12,$15);}
+ | PARSEOP_BANKFIELD '('
+ error ')' '{' error '}' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FieldUnitList
+ : {$$ = NULL;}
+ | FieldUnit
+ | FieldUnitList ',' /* Allows a trailing comma at list end */
+ | FieldUnitList ','
+ FieldUnit {$$ = TrLinkPeerNode ($1,$3);}
+ ;
+
+FieldUnit
+ : FieldUnitEntry {}
+ | OffsetTerm {}
+ | AccessAsTerm {}
+ | ConnectionTerm {}
+ ;
+
+FieldUnitEntry
+ : ',' AmlPackageLengthTerm {$$ = TrCreateNode (PARSEOP_RESERVED_BYTES,1,$2);}
+ | NameSeg ','
+ AmlPackageLengthTerm {$$ = TrLinkChildNode ($1,$3);}
+ ;
+
+OffsetTerm
+ : PARSEOP_OFFSET '('
+ AmlPackageLengthTerm
+ ')' {$$ = TrCreateNode (PARSEOP_OFFSET,1,$3);}
+ | PARSEOP_OFFSET '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+AccessAsTerm
+ : PARSEOP_ACCESSAS '('
+ AccessTypeKeyword
+ OptionalAccessAttribTerm
+ ')' {$$ = TrCreateNode (PARSEOP_ACCESSAS,2,$3,$4);}
+ | PARSEOP_ACCESSAS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ConnectionTerm
+ : PARSEOP_CONNECTION '('
+ NameString
+ ')' {$$ = TrCreateNode (PARSEOP_CONNECTION,1,$3);}
+ | PARSEOP_CONNECTION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONNECTION);}
+ ResourceMacroTerm
+ ')' {$$ = TrLinkChildren ($<n>3, 1,
+ TrLinkChildren (TrCreateLeafNode (PARSEOP_RESOURCETEMPLATE), 3,
+ TrCreateLeafNode (PARSEOP_DEFAULT_ARG),
+ TrCreateLeafNode (PARSEOP_DEFAULT_ARG),
+ $4));}
+ | PARSEOP_CONNECTION '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateBitFieldTerm
+ : PARSEOP_CREATEBITFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBITFIELD);}
+ TermArg
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,TrSetNodeFlags ($6, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEBITFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateByteFieldTerm
+ : PARSEOP_CREATEBYTEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBYTEFIELD);}
+ TermArg
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,TrSetNodeFlags ($6, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEBYTEFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateDWordFieldTerm
+ : PARSEOP_CREATEDWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEDWORDFIELD);}
+ TermArg
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,TrSetNodeFlags ($6, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEDWORDFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateFieldTerm
+ : PARSEOP_CREATEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEFIELD);}
+ TermArg
+ TermArgItem
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,4,$4,$5,$6,TrSetNodeFlags ($7, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateQWordFieldTerm
+ : PARSEOP_CREATEQWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEQWORDFIELD);}
+ TermArg
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,TrSetNodeFlags ($6, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEQWORDFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CreateWordFieldTerm
+ : PARSEOP_CREATEWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEWORDFIELD);}
+ TermArg
+ TermArgItem
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,TrSetNodeFlags ($6, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_CREATEWORDFIELD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DataRegionTerm
+ : PARSEOP_DATATABLEREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DATATABLEREGION);}
+ NameString
+ TermArgItem
+ TermArgItem
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,4,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$5,$6,$7);}
+ | PARSEOP_DATATABLEREGION '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DeviceTerm
+ : PARSEOP_DEVICE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEVICE);}
+ NameString
+ ')' '{'
+ ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
+ | PARSEOP_DEVICE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+EventTerm
+ : PARSEOP_EVENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EVENT);}
+ NameString
+ ')' {$$ = TrLinkChildren ($<n>3,1,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_EVENT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FieldTerm
+ : PARSEOP_FIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FIELD);}
+ NameString
+ ',' AccessTypeKeyword
+ ',' LockRuleKeyword
+ ',' UpdateRuleKeyword
+ ')' '{'
+ FieldUnitList '}' {$$ = TrLinkChildren ($<n>3,5,$4,$6,$8,$10,$13);}
+ | PARSEOP_FIELD '('
+ error ')' '{' error '}' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FunctionTerm
+ : PARSEOP_FUNCTION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
+ NameString
+ OptionalParameterTypePackage
+ OptionalParameterTypesPackage
+ ')' '{'
+ TermList '}' {$$ = TrLinkChildren ($<n>3,7,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),
+ TrCreateValuedLeafNode (PARSEOP_BYTECONST, 0),
+ TrCreateLeafNode (PARSEOP_SERIALIZERULE_NOTSERIAL),
+ TrCreateValuedLeafNode (PARSEOP_BYTECONST, 0),$5,$6,$9);}
+ | PARSEOP_FUNCTION '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IndexFieldTerm
+ : PARSEOP_INDEXFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEXFIELD);}
+ NameString
+ NameStringItem
+ ',' AccessTypeKeyword
+ ',' LockRuleKeyword
+ ',' UpdateRuleKeyword
+ ')' '{'
+ FieldUnitList '}' {$$ = TrLinkChildren ($<n>3,6,$4,$5,$7,$9,$11,$14);}
+ | PARSEOP_INDEXFIELD '('
+ error ')' '{' error '}' {$$ = AslDoError(); yyclearin;}
+ ;
+
+MethodTerm
+ : PARSEOP_METHOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
+ NameString
+ OptionalByteConstExpr {UtCheckIntegerRange ($5, 0, 7);}
+ OptionalSerializeRuleKeyword
+ OptionalByteConstExpr
+ OptionalParameterTypePackage
+ OptionalParameterTypesPackage
+ ')' '{'
+ TermList '}' {$$ = TrLinkChildren ($<n>3,7,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$5,$7,$8,$9,$10,$13);}
+ | PARSEOP_METHOD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+MutexTerm
+ : PARSEOP_MUTEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MUTEX);}
+ NameString
+ ',' ByteConstExpr
+ ')' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6);}
+ | PARSEOP_MUTEX '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+OpRegionTerm
+ : PARSEOP_OPERATIONREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OPERATIONREGION);}
+ NameString
+ ',' OpRegionSpaceIdTerm
+ TermArgItem
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,4,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6,$7,$8);}
+ | PARSEOP_OPERATIONREGION '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+OpRegionSpaceIdTerm
+ : RegionSpaceKeyword {}
+ | ByteConst {$$ = UtCheckIntegerRange ($1, 0x80, 0xFF);}
+ ;
+
+PowerResTerm
+ : PARSEOP_POWERRESOURCE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_POWERRESOURCE);}
+ NameString
+ ',' ByteConstExpr
+ ',' WordConstExpr
+ ')' '{'
+ ObjectList '}' {$$ = TrLinkChildren ($<n>3,4,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6,$8,$11);}
+ | PARSEOP_POWERRESOURCE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ProcessorTerm
+ : PARSEOP_PROCESSOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_PROCESSOR);}
+ NameString
+ ',' ByteConstExpr
+ OptionalDWordConstExpr
+ OptionalByteConstExpr
+ ')' '{'
+ ObjectList '}' {$$ = TrLinkChildren ($<n>3,5,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6,$7,$8,$11);}
+ | PARSEOP_PROCESSOR '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ThermalZoneTerm
+ : PARSEOP_THERMALZONE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_THERMALZONE);}
+ NameString
+ ')' '{'
+ ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
+ | PARSEOP_THERMALZONE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Namespace modifiers *************************************************/
+
+
+AliasTerm
+ : PARSEOP_ALIAS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ALIAS);}
+ NameString
+ NameStringItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($5, NODE_IS_NAME_DECLARATION));}
+ | PARSEOP_ALIAS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+NameTerm
+ : PARSEOP_NAME '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAME);}
+ NameString
+ ',' DataObject
+ ')' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6);}
+ | PARSEOP_NAME '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ScopeTerm
+ : PARSEOP_SCOPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SCOPE);}
+ NameString
+ ')' '{'
+ ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
+ | PARSEOP_SCOPE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Type 1 opcodes *******************************************************/
+
+
+BreakTerm
+ : PARSEOP_BREAK {$$ = TrCreateNode (PARSEOP_BREAK, 0);}
+ ;
+
+BreakPointTerm
+ : PARSEOP_BREAKPOINT {$$ = TrCreateNode (PARSEOP_BREAKPOINT, 0);}
+ ;
+
+ContinueTerm
+ : PARSEOP_CONTINUE {$$ = TrCreateNode (PARSEOP_CONTINUE, 0);}
+ ;
+
+FatalTerm
+ : PARSEOP_FATAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FATAL);}
+ ByteConstExpr
+ ',' DWordConstExpr
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$6,$7);}
+ | PARSEOP_FATAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IfElseTerm
+ : IfTerm ElseTerm {$$ = TrLinkPeerNode ($1,$2);}
+ ;
+
+IfTerm
+ : PARSEOP_IF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
+ TermArg
+ ')' '{'
+ TermList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+
+ | PARSEOP_IF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ElseTerm
+ : {$$ = NULL;}
+ | PARSEOP_ELSE '{' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
+ TermList '}' {$$ = TrLinkChildren ($<n>3,1,$4);}
+
+ | PARSEOP_ELSE '{'
+ error '}' {$$ = AslDoError(); yyclearin;}
+
+ | PARSEOP_ELSE
+ error {$$ = AslDoError(); yyclearin;}
+
+ | PARSEOP_ELSEIF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
+ TermArg {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
+ ')' '{'
+ TermList '}' {TrLinkChildren ($<n>5,2,$4,$8);}
+ ElseTerm {TrLinkPeerNode ($<n>5,$11);}
+ {$$ = TrLinkChildren ($<n>3,1,$<n>5);}
+
+ | PARSEOP_ELSEIF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+
+ | PARSEOP_ELSEIF
+ error {$$ = AslDoError(); yyclearin;}
+ ;
+
+LoadTerm
+ : PARSEOP_LOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOAD);}
+ NameString
+ RequiredTarget
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LOAD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+NoOpTerm
+ : PARSEOP_NOOP {$$ = TrCreateNode (PARSEOP_NOOP, 0);}
+ ;
+
+NotifyTerm
+ : PARSEOP_NOTIFY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOTIFY);}
+ SuperName
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_NOTIFY '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ReleaseTerm
+ : PARSEOP_RELEASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RELEASE);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_RELEASE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ResetTerm
+ : PARSEOP_RESET '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RESET);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_RESET '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ReturnTerm
+ : PARSEOP_RETURN '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RETURN);}
+ OptionalReturnArg
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_RETURN {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_RETURN),1,TrSetNodeFlags (TrCreateLeafNode (PARSEOP_ZERO), NODE_IS_NULL_RETURN));}
+ | PARSEOP_RETURN '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SignalTerm
+ : PARSEOP_SIGNAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIGNAL);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_SIGNAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SleepTerm
+ : PARSEOP_SLEEP '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SLEEP);}
+ TermArg
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_SLEEP '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+StallTerm
+ : PARSEOP_STALL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STALL);}
+ TermArg
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_STALL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SwitchTerm
+ : PARSEOP_SWITCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SWITCH);}
+ TermArg
+ ')' '{'
+ CaseDefaultTermList '}'
+ {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_SWITCH '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+/*
+ * Case-Default list; allow only one Default term and unlimited Case terms
+ */
+
+CaseDefaultTermList
+ : {$$ = NULL;}
+ | CaseTerm {}
+ | DefaultTerm {}
+ | CaseDefaultTermList
+ CaseTerm {$$ = TrLinkPeerNode ($1,$2);}
+ | CaseDefaultTermList
+ DefaultTerm {$$ = TrLinkPeerNode ($1,$2);}
+
+/* Original - attempts to force zero or one default term within the switch */
+
+/*
+CaseDefaultTermList
+ : {$$ = NULL;}
+ | CaseTermList
+ DefaultTerm
+ CaseTermList {$$ = TrLinkPeerNode ($1,TrLinkPeerNode ($2, $3));}
+ | CaseTermList
+ CaseTerm {$$ = TrLinkPeerNode ($1,$2);}
+ ;
+
+CaseTermList
+ : {$$ = NULL;}
+ | CaseTerm {}
+ | CaseTermList
+ CaseTerm {$$ = TrLinkPeerNode ($1,$2);}
+ ;
+*/
+
+CaseTerm
+ : PARSEOP_CASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CASE);}
+ DataObject
+ ')' '{'
+ TermList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_CASE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DefaultTerm
+ : PARSEOP_DEFAULT '{' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFAULT);}
+ TermList '}' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_DEFAULT '{'
+ error '}' {$$ = AslDoError(); yyclearin;}
+ ;
+
+UnloadTerm
+ : PARSEOP_UNLOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_UNLOAD);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_UNLOAD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+WhileTerm
+ : PARSEOP_WHILE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WHILE);}
+ TermArg
+ ')' '{' TermList '}'
+ {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_WHILE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Type 2 opcodes *******************************************************/
+
+AcquireTerm
+ : PARSEOP_ACQUIRE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACQUIRE);}
+ SuperName
+ ',' WordConstExpr
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$6);}
+ | PARSEOP_ACQUIRE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+AddTerm
+ : PARSEOP_ADD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_ADD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+AndTerm
+ : PARSEOP_AND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_AND);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_AND '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ConcatTerm
+ : PARSEOP_CONCATENATE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONCATENATE);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_CONCATENATE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ConcatResTerm
+ : PARSEOP_CONCATENATERESTEMPLATE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONCATENATERESTEMPLATE);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_CONCATENATERESTEMPLATE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CondRefOfTerm
+ : PARSEOP_CONDREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONDREFOF);}
+ SuperName
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_CONDREFOF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+CopyObjectTerm
+ : PARSEOP_COPYOBJECT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_COPYOBJECT);}
+ TermArg
+ ',' SimpleTarget
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($6, NODE_IS_TARGET));}
+ | PARSEOP_COPYOBJECT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DecTerm
+ : PARSEOP_DECREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DECREMENT);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_DECREMENT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DerefOfTerm
+ : PARSEOP_DEREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEREFOF);}
+ TermArg
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_DEREFOF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DivideTerm
+ : PARSEOP_DIVIDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);}
+ TermArg
+ TermArgItem
+ Target
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,4,$4,$5,$6,$7);}
+ | PARSEOP_DIVIDE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FindSetLeftBitTerm
+ : PARSEOP_FINDSETLEFTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETLEFTBIT);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_FINDSETLEFTBIT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FindSetRightBitTerm
+ : PARSEOP_FINDSETRIGHTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETRIGHTBIT);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_FINDSETRIGHTBIT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FromBCDTerm
+ : PARSEOP_FROMBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FROMBCD);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_FROMBCD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IncTerm
+ : PARSEOP_INCREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCREMENT);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_INCREMENT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IndexTerm
+ : PARSEOP_INDEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEX);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_INDEX '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LAndTerm
+ : PARSEOP_LAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LAND);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LAND '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LEqualTerm
+ : PARSEOP_LEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LEQUAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LGreaterTerm
+ : PARSEOP_LGREATER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LGREATER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LGreaterEqualTerm
+ : PARSEOP_LGREATEREQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
+ | PARSEOP_LGREATEREQUAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LLessTerm
+ : PARSEOP_LLESS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LLESS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LLessEqualTerm
+ : PARSEOP_LLESSEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
+ | PARSEOP_LLESSEQUAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LNotTerm
+ : PARSEOP_LNOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LNOT);}
+ TermArg
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_LNOT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LNotEqualTerm
+ : PARSEOP_LNOTEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
+ | PARSEOP_LNOTEQUAL '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LoadTableTerm
+ : PARSEOP_LOADTABLE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOADTABLE);}
+ TermArg
+ TermArgItem
+ TermArgItem
+ OptionalListString
+ OptionalListString
+ OptionalReference
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$5,$6,$7,$8,$9);}
+ | PARSEOP_LOADTABLE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+LOrTerm
+ : PARSEOP_LOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOR);}
+ TermArg
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_LOR '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+MatchTerm
+ : PARSEOP_MATCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MATCH);}
+ TermArg
+ ',' MatchOpKeyword
+ TermArgItem
+ ',' MatchOpKeyword
+ TermArgItem
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$6,$7,$9,$10,$11);}
+ | PARSEOP_MATCH '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+MidTerm
+ : PARSEOP_MID '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MID);}
+ TermArg
+ TermArgItem
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,4,$4,$5,$6,$7);}
+ | PARSEOP_MID '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ModTerm
+ : PARSEOP_MOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_MOD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+MultiplyTerm
+ : PARSEOP_MULTIPLY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_MULTIPLY '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+NAndTerm
+ : PARSEOP_NAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAND);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_NAND '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+NOrTerm
+ : PARSEOP_NOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOR);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_NOR '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+NotTerm
+ : PARSEOP_NOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOT);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_NOT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ObjectTypeTerm
+ : PARSEOP_OBJECTTYPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE);}
+ ObjectTypeName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_OBJECTTYPE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+OrTerm
+ : PARSEOP_OR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OR);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_OR '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+/*
+ * In RefOf, the node isn't really a target, but we can't keep track of it after
+ * we've taken a pointer to it. (hard to tell if a local becomes initialized this way.)
+ */
+RefOfTerm
+ : PARSEOP_REFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_REFOF);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,TrSetNodeFlags ($4, NODE_IS_TARGET));}
+ | PARSEOP_REFOF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ShiftLeftTerm
+ : PARSEOP_SHIFTLEFT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_SHIFTLEFT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ShiftRightTerm
+ : PARSEOP_SHIFTRIGHT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_SHIFTRIGHT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SizeOfTerm
+ : PARSEOP_SIZEOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIZEOF);}
+ SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_SIZEOF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+StoreTerm
+ : PARSEOP_STORE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STORE);}
+ TermArg
+ ',' SuperName
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($6, NODE_IS_TARGET));}
+ | PARSEOP_STORE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SubtractTerm
+ : PARSEOP_SUBTRACT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_SUBTRACT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+TimerTerm
+ : PARSEOP_TIMER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TIMER);}
+ ')' {$$ = TrLinkChildren ($<n>3,0);}
+ | PARSEOP_TIMER {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_TIMER),0);}
+ | PARSEOP_TIMER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToBCDTerm
+ : PARSEOP_TOBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBCD);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_TOBCD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToBufferTerm
+ : PARSEOP_TOBUFFER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBUFFER);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_TOBUFFER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToDecimalStringTerm
+ : PARSEOP_TODECIMALSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TODECIMALSTRING);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_TODECIMALSTRING '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToHexStringTerm
+ : PARSEOP_TOHEXSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOHEXSTRING);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_TOHEXSTRING '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToIntegerTerm
+ : PARSEOP_TOINTEGER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOINTEGER);}
+ TermArg
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_TOINTEGER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+PldKeyword
+ : PARSEOP_PLD_REVISION {$$ = TrCreateLeafNode (PARSEOP_PLD_REVISION);}
+ | PARSEOP_PLD_IGNORECOLOR {$$ = TrCreateLeafNode (PARSEOP_PLD_IGNORECOLOR);}
+ | PARSEOP_PLD_RED {$$ = TrCreateLeafNode (PARSEOP_PLD_RED);}
+ | PARSEOP_PLD_GREEN {$$ = TrCreateLeafNode (PARSEOP_PLD_GREEN);}
+ | PARSEOP_PLD_BLUE {$$ = TrCreateLeafNode (PARSEOP_PLD_BLUE);}
+ | PARSEOP_PLD_WIDTH {$$ = TrCreateLeafNode (PARSEOP_PLD_WIDTH);}
+ | PARSEOP_PLD_HEIGHT {$$ = TrCreateLeafNode (PARSEOP_PLD_HEIGHT);}
+ | PARSEOP_PLD_USERVISIBLE {$$ = TrCreateLeafNode (PARSEOP_PLD_USERVISIBLE);}
+ | PARSEOP_PLD_DOCK {$$ = TrCreateLeafNode (PARSEOP_PLD_DOCK);}
+ | PARSEOP_PLD_LID {$$ = TrCreateLeafNode (PARSEOP_PLD_LID);}
+ | PARSEOP_PLD_PANEL {$$ = TrCreateLeafNode (PARSEOP_PLD_PANEL);}
+ | PARSEOP_PLD_VERTICALPOSITION {$$ = TrCreateLeafNode (PARSEOP_PLD_VERTICALPOSITION);}
+ | PARSEOP_PLD_HORIZONTALPOSITION {$$ = TrCreateLeafNode (PARSEOP_PLD_HORIZONTALPOSITION);}
+ | PARSEOP_PLD_SHAPE {$$ = TrCreateLeafNode (PARSEOP_PLD_SHAPE);}
+ | PARSEOP_PLD_GROUPORIENTATION {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPORIENTATION);}
+ | PARSEOP_PLD_GROUPTOKEN {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPTOKEN);}
+ | PARSEOP_PLD_GROUPPOSITION {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPPOSITION);}
+ | PARSEOP_PLD_BAY {$$ = TrCreateLeafNode (PARSEOP_PLD_BAY);}
+ | PARSEOP_PLD_EJECTABLE {$$ = TrCreateLeafNode (PARSEOP_PLD_EJECTABLE);}
+ | PARSEOP_PLD_EJECTREQUIRED {$$ = TrCreateLeafNode (PARSEOP_PLD_EJECTREQUIRED);}
+ | PARSEOP_PLD_CABINETNUMBER {$$ = TrCreateLeafNode (PARSEOP_PLD_CABINETNUMBER);}
+ | PARSEOP_PLD_CARDCAGENUMBER {$$ = TrCreateLeafNode (PARSEOP_PLD_CARDCAGENUMBER);}
+ | PARSEOP_PLD_REFERENCE {$$ = TrCreateLeafNode (PARSEOP_PLD_REFERENCE);}
+ | PARSEOP_PLD_ROTATION {$$ = TrCreateLeafNode (PARSEOP_PLD_ROTATION);}
+ | PARSEOP_PLD_ORDER {$$ = TrCreateLeafNode (PARSEOP_PLD_ORDER);}
+ | PARSEOP_PLD_RESERVED {$$ = TrCreateLeafNode (PARSEOP_PLD_RESERVED);}
+ | PARSEOP_PLD_VERTICALOFFSET {$$ = TrCreateLeafNode (PARSEOP_PLD_VERTICALOFFSET);}
+ | PARSEOP_PLD_HORIZONTALOFFSET {$$ = TrCreateLeafNode (PARSEOP_PLD_HORIZONTALOFFSET);}
+ ;
+
+PldKeywordList
+ : {$$ = NULL;}
+ | PldKeyword
+ PARSEOP_EXP_EQUALS Integer {$$ = TrLinkChildren ($1,1,$3);}
+ | PldKeyword
+ PARSEOP_EXP_EQUALS String {$$ = TrLinkChildren ($1,1,$3);}
+ | PldKeywordList ',' /* Allows a trailing comma at list end */
+ | PldKeywordList ','
+ PldKeyword
+ PARSEOP_EXP_EQUALS Integer {$$ = TrLinkPeerNode ($1,TrLinkChildren ($3,1,$5));}
+ | PldKeywordList ','
+ PldKeyword
+ PARSEOP_EXP_EQUALS String {$$ = TrLinkPeerNode ($1,TrLinkChildren ($3,1,$5));}
+ ;
+
+ToPLDTerm
+ : PARSEOP_TOPLD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOPLD);}
+ PldKeywordList
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_TOPLD '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+PrintfArgList
+ : {$$ = NULL;}
+ | TermArg {$$ = $1;}
+ | PrintfArgList ','
+ TermArg {$$ = TrLinkPeerNode ($1, $3);}
+ ;
+
+PrintfTerm
+ : PARSEOP_PRINTF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_PRINTF);}
+ StringData
+ PrintfArgList
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_PRINTF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FprintfTerm
+ : PARSEOP_FPRINTF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FPRINTF);}
+ TermArg ','
+ StringData
+ PrintfArgList
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$6,$7);}
+ | PARSEOP_FPRINTF '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToStringTerm
+ : PARSEOP_TOSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOSTRING);}
+ TermArg
+ OptionalCount
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_TOSTRING '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ToUUIDTerm
+ : PARSEOP_TOUUID '('
+ StringData ')' {$$ = TrUpdateNode (PARSEOP_TOUUID, $3);}
+ | PARSEOP_TOUUID '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+WaitTerm
+ : PARSEOP_WAIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WAIT);}
+ SuperName
+ TermArgItem
+ ')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
+ | PARSEOP_WAIT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+XOrTerm
+ : PARSEOP_XOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);}
+ TermArg
+ TermArgItem
+ Target
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$5,$6);}
+ | PARSEOP_XOR '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Keywords *************************************************************/
+
+
+AccessAttribKeyword
+ : PARSEOP_ACCESSATTRIB_BLOCK {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_BLOCK);}
+ | PARSEOP_ACCESSATTRIB_BLOCK_CALL {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_BLOCK_CALL);}
+ | PARSEOP_ACCESSATTRIB_BYTE {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_BYTE);}
+ | PARSEOP_ACCESSATTRIB_QUICK {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_QUICK );}
+ | PARSEOP_ACCESSATTRIB_SND_RCV {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_SND_RCV);}
+ | PARSEOP_ACCESSATTRIB_WORD {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_WORD);}
+ | PARSEOP_ACCESSATTRIB_WORD_CALL {$$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_WORD_CALL);}
+ | PARSEOP_ACCESSATTRIB_MULTIBYTE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_MULTIBYTE);}
+ ByteConst
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_ACCESSATTRIB_RAW_BYTES '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_RAW_BYTES);}
+ ByteConst
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ | PARSEOP_ACCESSATTRIB_RAW_PROCESS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACCESSATTRIB_RAW_PROCESS);}
+ ByteConst
+ ')' {$$ = TrLinkChildren ($<n>3,1,$4);}
+ ;
+
+AccessTypeKeyword
+ : PARSEOP_ACCESSTYPE_ANY {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_ANY);}
+ | PARSEOP_ACCESSTYPE_BYTE {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_BYTE);}
+ | PARSEOP_ACCESSTYPE_WORD {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_WORD);}
+ | PARSEOP_ACCESSTYPE_DWORD {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_DWORD);}
+ | PARSEOP_ACCESSTYPE_QWORD {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_QWORD);}
+ | PARSEOP_ACCESSTYPE_BUF {$$ = TrCreateLeafNode (PARSEOP_ACCESSTYPE_BUF);}
+ ;
+
+AddressingModeKeyword
+ : PARSEOP_ADDRESSINGMODE_7BIT {$$ = TrCreateLeafNode (PARSEOP_ADDRESSINGMODE_7BIT);}
+ | PARSEOP_ADDRESSINGMODE_10BIT {$$ = TrCreateLeafNode (PARSEOP_ADDRESSINGMODE_10BIT);}
+ ;
+
+AddressKeyword
+ : PARSEOP_ADDRESSTYPE_MEMORY {$$ = TrCreateLeafNode (PARSEOP_ADDRESSTYPE_MEMORY);}
+ | PARSEOP_ADDRESSTYPE_RESERVED {$$ = TrCreateLeafNode (PARSEOP_ADDRESSTYPE_RESERVED);}
+ | PARSEOP_ADDRESSTYPE_NVS {$$ = TrCreateLeafNode (PARSEOP_ADDRESSTYPE_NVS);}
+ | PARSEOP_ADDRESSTYPE_ACPI {$$ = TrCreateLeafNode (PARSEOP_ADDRESSTYPE_ACPI);}
+ ;
+
+AddressSpaceKeyword
+ : ByteConst {$$ = UtCheckIntegerRange ($1, 0x0A, 0xFF);}
+ | RegionSpaceKeyword {}
+ ;
+
+BitsPerByteKeyword
+ : PARSEOP_BITSPERBYTE_FIVE {$$ = TrCreateLeafNode (PARSEOP_BITSPERBYTE_FIVE);}
+ | PARSEOP_BITSPERBYTE_SIX {$$ = TrCreateLeafNode (PARSEOP_BITSPERBYTE_SIX);}
+ | PARSEOP_BITSPERBYTE_SEVEN {$$ = TrCreateLeafNode (PARSEOP_BITSPERBYTE_SEVEN);}
+ | PARSEOP_BITSPERBYTE_EIGHT {$$ = TrCreateLeafNode (PARSEOP_BITSPERBYTE_EIGHT);}
+ | PARSEOP_BITSPERBYTE_NINE {$$ = TrCreateLeafNode (PARSEOP_BITSPERBYTE_NINE);}
+ ;
+
+ClockPhaseKeyword
+ : PARSEOP_CLOCKPHASE_FIRST {$$ = TrCreateLeafNode (PARSEOP_CLOCKPHASE_FIRST);}
+ | PARSEOP_CLOCKPHASE_SECOND {$$ = TrCreateLeafNode (PARSEOP_CLOCKPHASE_SECOND);}
+ ;
+
+ClockPolarityKeyword
+ : PARSEOP_CLOCKPOLARITY_LOW {$$ = TrCreateLeafNode (PARSEOP_CLOCKPOLARITY_LOW);}
+ | PARSEOP_CLOCKPOLARITY_HIGH {$$ = TrCreateLeafNode (PARSEOP_CLOCKPOLARITY_HIGH);}
+ ;
+
+DecodeKeyword
+ : PARSEOP_DECODETYPE_POS {$$ = TrCreateLeafNode (PARSEOP_DECODETYPE_POS);}
+ | PARSEOP_DECODETYPE_SUB {$$ = TrCreateLeafNode (PARSEOP_DECODETYPE_SUB);}
+ ;
+
+DevicePolarityKeyword
+ : PARSEOP_DEVICEPOLARITY_LOW {$$ = TrCreateLeafNode (PARSEOP_DEVICEPOLARITY_LOW);}
+ | PARSEOP_DEVICEPOLARITY_HIGH {$$ = TrCreateLeafNode (PARSEOP_DEVICEPOLARITY_HIGH);}
+ ;
+
+DMATypeKeyword
+ : PARSEOP_DMATYPE_A {$$ = TrCreateLeafNode (PARSEOP_DMATYPE_A);}
+ | PARSEOP_DMATYPE_COMPATIBILITY {$$ = TrCreateLeafNode (PARSEOP_DMATYPE_COMPATIBILITY);}
+ | PARSEOP_DMATYPE_B {$$ = TrCreateLeafNode (PARSEOP_DMATYPE_B);}
+ | PARSEOP_DMATYPE_F {$$ = TrCreateLeafNode (PARSEOP_DMATYPE_F);}
+ ;
+
+EndianKeyword
+ : PARSEOP_ENDIAN_LITTLE {$$ = TrCreateLeafNode (PARSEOP_ENDIAN_LITTLE);}
+ | PARSEOP_ENDIAN_BIG {$$ = TrCreateLeafNode (PARSEOP_ENDIAN_BIG);}
+ ;
+
+FlowControlKeyword
+ : PARSEOP_FLOWCONTROL_HW {$$ = TrCreateLeafNode (PARSEOP_FLOWCONTROL_HW);}
+ | PARSEOP_FLOWCONTROL_NONE {$$ = TrCreateLeafNode (PARSEOP_FLOWCONTROL_NONE);}
+ | PARSEOP_FLOWCONTROL_SW {$$ = TrCreateLeafNode (PARSEOP_FLOWCONTROL_SW);}
+ ;
+
+InterruptLevel
+ : PARSEOP_INTLEVEL_ACTIVEBOTH {$$ = TrCreateLeafNode (PARSEOP_INTLEVEL_ACTIVEBOTH);}
+ | PARSEOP_INTLEVEL_ACTIVEHIGH {$$ = TrCreateLeafNode (PARSEOP_INTLEVEL_ACTIVEHIGH);}
+ | PARSEOP_INTLEVEL_ACTIVELOW {$$ = TrCreateLeafNode (PARSEOP_INTLEVEL_ACTIVELOW);}
+ ;
+
+InterruptTypeKeyword
+ : PARSEOP_INTTYPE_EDGE {$$ = TrCreateLeafNode (PARSEOP_INTTYPE_EDGE);}
+ | PARSEOP_INTTYPE_LEVEL {$$ = TrCreateLeafNode (PARSEOP_INTTYPE_LEVEL);}
+ ;
+
+IODecodeKeyword
+ : PARSEOP_IODECODETYPE_16 {$$ = TrCreateLeafNode (PARSEOP_IODECODETYPE_16);}
+ | PARSEOP_IODECODETYPE_10 {$$ = TrCreateLeafNode (PARSEOP_IODECODETYPE_10);}
+ ;
+
+IoRestrictionKeyword
+ : PARSEOP_IORESTRICT_IN {$$ = TrCreateLeafNode (PARSEOP_IORESTRICT_IN);}
+ | PARSEOP_IORESTRICT_OUT {$$ = TrCreateLeafNode (PARSEOP_IORESTRICT_OUT);}
+ | PARSEOP_IORESTRICT_NONE {$$ = TrCreateLeafNode (PARSEOP_IORESTRICT_NONE);}
+ | PARSEOP_IORESTRICT_PRESERVE {$$ = TrCreateLeafNode (PARSEOP_IORESTRICT_PRESERVE);}
+ ;
+
+LockRuleKeyword
+ : PARSEOP_LOCKRULE_LOCK {$$ = TrCreateLeafNode (PARSEOP_LOCKRULE_LOCK);}
+ | PARSEOP_LOCKRULE_NOLOCK {$$ = TrCreateLeafNode (PARSEOP_LOCKRULE_NOLOCK);}
+ ;
+
+MatchOpKeyword
+ : PARSEOP_MATCHTYPE_MTR {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MTR);}
+ | PARSEOP_MATCHTYPE_MEQ {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MEQ);}
+ | PARSEOP_MATCHTYPE_MLE {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MLE);}
+ | PARSEOP_MATCHTYPE_MLT {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MLT);}
+ | PARSEOP_MATCHTYPE_MGE {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MGE);}
+ | PARSEOP_MATCHTYPE_MGT {$$ = TrCreateLeafNode (PARSEOP_MATCHTYPE_MGT);}
+ ;
+
+MaxKeyword
+ : PARSEOP_MAXTYPE_FIXED {$$ = TrCreateLeafNode (PARSEOP_MAXTYPE_FIXED);}
+ | PARSEOP_MAXTYPE_NOTFIXED {$$ = TrCreateLeafNode (PARSEOP_MAXTYPE_NOTFIXED);}
+ ;
+
+MemTypeKeyword
+ : PARSEOP_MEMTYPE_CACHEABLE {$$ = TrCreateLeafNode (PARSEOP_MEMTYPE_CACHEABLE);}
+ | PARSEOP_MEMTYPE_WRITECOMBINING {$$ = TrCreateLeafNode (PARSEOP_MEMTYPE_WRITECOMBINING);}
+ | PARSEOP_MEMTYPE_PREFETCHABLE {$$ = TrCreateLeafNode (PARSEOP_MEMTYPE_PREFETCHABLE);}
+ | PARSEOP_MEMTYPE_NONCACHEABLE {$$ = TrCreateLeafNode (PARSEOP_MEMTYPE_NONCACHEABLE);}
+ ;
+
+MinKeyword
+ : PARSEOP_MINTYPE_FIXED {$$ = TrCreateLeafNode (PARSEOP_MINTYPE_FIXED);}
+ | PARSEOP_MINTYPE_NOTFIXED {$$ = TrCreateLeafNode (PARSEOP_MINTYPE_NOTFIXED);}
+ ;
+
+ObjectTypeKeyword
+ : PARSEOP_OBJECTTYPE_UNK {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_UNK);}
+ | PARSEOP_OBJECTTYPE_INT {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_INT);}
+ | PARSEOP_OBJECTTYPE_STR {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_STR);}
+ | PARSEOP_OBJECTTYPE_BUF {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_BUF);}
+ | PARSEOP_OBJECTTYPE_PKG {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_PKG);}
+ | PARSEOP_OBJECTTYPE_FLD {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_FLD);}
+ | PARSEOP_OBJECTTYPE_DEV {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_DEV);}
+ | PARSEOP_OBJECTTYPE_EVT {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_EVT);}
+ | PARSEOP_OBJECTTYPE_MTH {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_MTH);}
+ | PARSEOP_OBJECTTYPE_MTX {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_MTX);}
+ | PARSEOP_OBJECTTYPE_OPR {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_OPR);}
+ | PARSEOP_OBJECTTYPE_POW {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_POW);}
+ | PARSEOP_OBJECTTYPE_PRO {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_PRO);}
+ | PARSEOP_OBJECTTYPE_THZ {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_THZ);}
+ | PARSEOP_OBJECTTYPE_BFF {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_BFF);}
+ | PARSEOP_OBJECTTYPE_DDB {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_DDB);}
+ ;
+
+ParityTypeKeyword
+ : PARSEOP_PARITYTYPE_SPACE {$$ = TrCreateLeafNode (PARSEOP_PARITYTYPE_SPACE);}
+ | PARSEOP_PARITYTYPE_MARK {$$ = TrCreateLeafNode (PARSEOP_PARITYTYPE_MARK);}
+ | PARSEOP_PARITYTYPE_ODD {$$ = TrCreateLeafNode (PARSEOP_PARITYTYPE_ODD);}
+ | PARSEOP_PARITYTYPE_EVEN {$$ = TrCreateLeafNode (PARSEOP_PARITYTYPE_EVEN);}
+ | PARSEOP_PARITYTYPE_NONE {$$ = TrCreateLeafNode (PARSEOP_PARITYTYPE_NONE);}
+ ;
+
+PinConfigByte
+ : PinConfigKeyword {$$ = $1;}
+ | ByteConstExpr {$$ = UtCheckIntegerRange ($1, 0x80, 0xFF);}
+ ;
+
+PinConfigKeyword
+ : PARSEOP_PIN_NOPULL {$$ = TrCreateLeafNode (PARSEOP_PIN_NOPULL);}
+ | PARSEOP_PIN_PULLDOWN {$$ = TrCreateLeafNode (PARSEOP_PIN_PULLDOWN);}
+ | PARSEOP_PIN_PULLUP {$$ = TrCreateLeafNode (PARSEOP_PIN_PULLUP);}
+ | PARSEOP_PIN_PULLDEFAULT {$$ = TrCreateLeafNode (PARSEOP_PIN_PULLDEFAULT);}
+ ;
+
+RangeTypeKeyword
+ : PARSEOP_RANGETYPE_ISAONLY {$$ = TrCreateLeafNode (PARSEOP_RANGETYPE_ISAONLY);}
+ | PARSEOP_RANGETYPE_NONISAONLY {$$ = TrCreateLeafNode (PARSEOP_RANGETYPE_NONISAONLY);}
+ | PARSEOP_RANGETYPE_ENTIRE {$$ = TrCreateLeafNode (PARSEOP_RANGETYPE_ENTIRE);}
+ ;
+
+RegionSpaceKeyword
+ : PARSEOP_REGIONSPACE_IO {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_IO);}
+ | PARSEOP_REGIONSPACE_MEM {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_MEM);}
+ | PARSEOP_REGIONSPACE_PCI {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_PCI);}
+ | PARSEOP_REGIONSPACE_EC {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_EC);}
+ | PARSEOP_REGIONSPACE_SMBUS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_SMBUS);}
+ | PARSEOP_REGIONSPACE_CMOS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_CMOS);}
+ | PARSEOP_REGIONSPACE_PCIBAR {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_PCIBAR);}
+ | PARSEOP_REGIONSPACE_IPMI {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_IPMI);}
+ | PARSEOP_REGIONSPACE_GPIO {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_GPIO);}
+ | PARSEOP_REGIONSPACE_GSBUS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_GSBUS);}
+ | PARSEOP_REGIONSPACE_PCC {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_PCC);}
+ | PARSEOP_REGIONSPACE_FFIXEDHW {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_FFIXEDHW);}
+ ;
+
+ResourceTypeKeyword
+ : PARSEOP_RESOURCETYPE_CONSUMER {$$ = TrCreateLeafNode (PARSEOP_RESOURCETYPE_CONSUMER);}
+ | PARSEOP_RESOURCETYPE_PRODUCER {$$ = TrCreateLeafNode (PARSEOP_RESOURCETYPE_PRODUCER);}
+ ;
+
+SerializeRuleKeyword
+ : PARSEOP_SERIALIZERULE_SERIAL {$$ = TrCreateLeafNode (PARSEOP_SERIALIZERULE_SERIAL);}
+ | PARSEOP_SERIALIZERULE_NOTSERIAL {$$ = TrCreateLeafNode (PARSEOP_SERIALIZERULE_NOTSERIAL);}
+ ;
+
+ShareTypeKeyword
+ : PARSEOP_SHARETYPE_SHARED {$$ = TrCreateLeafNode (PARSEOP_SHARETYPE_SHARED);}
+ | PARSEOP_SHARETYPE_EXCLUSIVE {$$ = TrCreateLeafNode (PARSEOP_SHARETYPE_EXCLUSIVE);}
+ | PARSEOP_SHARETYPE_SHAREDWAKE {$$ = TrCreateLeafNode (PARSEOP_SHARETYPE_SHAREDWAKE);}
+ | PARSEOP_SHARETYPE_EXCLUSIVEWAKE {$$ = TrCreateLeafNode (PARSEOP_SHARETYPE_EXCLUSIVEWAKE);}
+ ;
+
+SlaveModeKeyword
+ : PARSEOP_SLAVEMODE_CONTROLLERINIT {$$ = TrCreateLeafNode (PARSEOP_SLAVEMODE_CONTROLLERINIT);}
+ | PARSEOP_SLAVEMODE_DEVICEINIT {$$ = TrCreateLeafNode (PARSEOP_SLAVEMODE_DEVICEINIT);}
+ ;
+
+StopBitsKeyword
+ : PARSEOP_STOPBITS_TWO {$$ = TrCreateLeafNode (PARSEOP_STOPBITS_TWO);}
+ | PARSEOP_STOPBITS_ONEPLUSHALF {$$ = TrCreateLeafNode (PARSEOP_STOPBITS_ONEPLUSHALF);}
+ | PARSEOP_STOPBITS_ONE {$$ = TrCreateLeafNode (PARSEOP_STOPBITS_ONE);}
+ | PARSEOP_STOPBITS_ZERO {$$ = TrCreateLeafNode (PARSEOP_STOPBITS_ZERO);}
+ ;
+
+TranslationKeyword
+ : PARSEOP_TRANSLATIONTYPE_SPARSE {$$ = TrCreateLeafNode (PARSEOP_TRANSLATIONTYPE_SPARSE);}
+ | PARSEOP_TRANSLATIONTYPE_DENSE {$$ = TrCreateLeafNode (PARSEOP_TRANSLATIONTYPE_DENSE);}
+ ;
+
+TypeKeyword
+ : PARSEOP_TYPE_TRANSLATION {$$ = TrCreateLeafNode (PARSEOP_TYPE_TRANSLATION);}
+ | PARSEOP_TYPE_STATIC {$$ = TrCreateLeafNode (PARSEOP_TYPE_STATIC);}
+ ;
+
+UpdateRuleKeyword
+ : PARSEOP_UPDATERULE_PRESERVE {$$ = TrCreateLeafNode (PARSEOP_UPDATERULE_PRESERVE);}
+ | PARSEOP_UPDATERULE_ONES {$$ = TrCreateLeafNode (PARSEOP_UPDATERULE_ONES);}
+ | PARSEOP_UPDATERULE_ZEROS {$$ = TrCreateLeafNode (PARSEOP_UPDATERULE_ZEROS);}
+ ;
+
+WireModeKeyword
+ : PARSEOP_WIREMODE_FOUR {$$ = TrCreateLeafNode (PARSEOP_WIREMODE_FOUR);}
+ | PARSEOP_WIREMODE_THREE {$$ = TrCreateLeafNode (PARSEOP_WIREMODE_THREE);}
+ ;
+
+XferSizeKeyword
+ : PARSEOP_XFERSIZE_8 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_8, 0);}
+ | PARSEOP_XFERSIZE_16 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_16, 1);}
+ | PARSEOP_XFERSIZE_32 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_32, 2);}
+ | PARSEOP_XFERSIZE_64 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_64, 3);}
+ | PARSEOP_XFERSIZE_128 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_128, 4);}
+ | PARSEOP_XFERSIZE_256 {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_256, 5);}
+ ;
+
+XferTypeKeyword
+ : PARSEOP_XFERTYPE_8 {$$ = TrCreateLeafNode (PARSEOP_XFERTYPE_8);}
+ | PARSEOP_XFERTYPE_8_16 {$$ = TrCreateLeafNode (PARSEOP_XFERTYPE_8_16);}
+ | PARSEOP_XFERTYPE_16 {$$ = TrCreateLeafNode (PARSEOP_XFERTYPE_16);}
+ ;
+
+
+/******* Miscellaneous Types **************************************************/
+
+
+SuperName
+ : NameString {}
+ | ArgTerm {}
+ | LocalTerm {}
+ | DebugTerm {}
+ | Type6Opcode {}
+
+/* For ObjectType: SuperName except for MethodInvocationTerm */
+
+ObjectTypeName
+ : NameString {}
+ | ArgTerm {}
+ | LocalTerm {}
+ | DebugTerm {}
+ | RefOfTerm {}
+ | DerefOfTerm {}
+ | IndexTerm {}
+
+/* | MethodInvocationTerm {} */ /* Caused reduce/reduce with Type6Opcode->MethodInvocationTerm */
+ ;
+
+ArgTerm
+ : PARSEOP_ARG0 {$$ = TrCreateLeafNode (PARSEOP_ARG0);}
+ | PARSEOP_ARG1 {$$ = TrCreateLeafNode (PARSEOP_ARG1);}
+ | PARSEOP_ARG2 {$$ = TrCreateLeafNode (PARSEOP_ARG2);}
+ | PARSEOP_ARG3 {$$ = TrCreateLeafNode (PARSEOP_ARG3);}
+ | PARSEOP_ARG4 {$$ = TrCreateLeafNode (PARSEOP_ARG4);}
+ | PARSEOP_ARG5 {$$ = TrCreateLeafNode (PARSEOP_ARG5);}
+ | PARSEOP_ARG6 {$$ = TrCreateLeafNode (PARSEOP_ARG6);}
+ ;
+
+LocalTerm
+ : PARSEOP_LOCAL0 {$$ = TrCreateLeafNode (PARSEOP_LOCAL0);}
+ | PARSEOP_LOCAL1 {$$ = TrCreateLeafNode (PARSEOP_LOCAL1);}
+ | PARSEOP_LOCAL2 {$$ = TrCreateLeafNode (PARSEOP_LOCAL2);}
+ | PARSEOP_LOCAL3 {$$ = TrCreateLeafNode (PARSEOP_LOCAL3);}
+ | PARSEOP_LOCAL4 {$$ = TrCreateLeafNode (PARSEOP_LOCAL4);}
+ | PARSEOP_LOCAL5 {$$ = TrCreateLeafNode (PARSEOP_LOCAL5);}
+ | PARSEOP_LOCAL6 {$$ = TrCreateLeafNode (PARSEOP_LOCAL6);}
+ | PARSEOP_LOCAL7 {$$ = TrCreateLeafNode (PARSEOP_LOCAL7);}
+ ;
+
+DebugTerm
+ : PARSEOP_DEBUG {$$ = TrCreateLeafNode (PARSEOP_DEBUG);}
+ ;
+
+
+ByteConst
+ : Integer {$$ = TrUpdateNode (PARSEOP_BYTECONST, $1);}
+ ;
+
+WordConst
+ : Integer {$$ = TrUpdateNode (PARSEOP_WORDCONST, $1);}
+ ;
+
+DWordConst
+ : Integer {$$ = TrUpdateNode (PARSEOP_DWORDCONST, $1);}
+ ;
+
+QWordConst
+ : Integer {$$ = TrUpdateNode (PARSEOP_QWORDCONST, $1);}
+ ;
+
+Integer
+ : PARSEOP_INTEGER {$$ = TrCreateValuedLeafNode (PARSEOP_INTEGER, AslCompilerlval.i);}
+ ;
+
+String
+ : PARSEOP_STRING_LITERAL {$$ = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL, (ACPI_NATIVE_INT) AslCompilerlval.s);}
+ ;
+
+ConstTerm
+ : ConstExprTerm {}
+ | PARSEOP_REVISION {$$ = TrCreateLeafNode (PARSEOP_REVISION);}
+ ;
+
+ConstExprTerm
+ : PARSEOP_ZERO {$$ = TrCreateValuedLeafNode (PARSEOP_ZERO, 0);}
+ | PARSEOP_ONE {$$ = TrCreateValuedLeafNode (PARSEOP_ONE, 1);}
+ | PARSEOP_ONES {$$ = TrCreateValuedLeafNode (PARSEOP_ONES, ACPI_UINT64_MAX);}
+ | PARSEOP___DATE__ {$$ = TrCreateConstantLeafNode (PARSEOP___DATE__);}
+ | PARSEOP___FILE__ {$$ = TrCreateConstantLeafNode (PARSEOP___FILE__);}
+ | PARSEOP___LINE__ {$$ = TrCreateConstantLeafNode (PARSEOP___LINE__);}
+ | PARSEOP___PATH__ {$$ = TrCreateConstantLeafNode (PARSEOP___PATH__);}
+ ;
+
+/*
+ * The NODE_COMPILE_TIME_CONST flag in the following constant expressions
+ * enables compile-time constant folding to reduce the Type3Opcodes/Type2IntegerOpcodes
+ * to simple integers. It is an error if these types of expressions cannot be
+ * reduced, since the AML grammar for ****ConstExpr requires a simple constant.
+ * Note: The required byte length of the constant is passed through to the
+ * constant folding code in the node AmlLength field.
+ */
+ByteConstExpr
+ : Type3Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 1);}
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 1);}
+ | ConstExprTerm {$$ = TrUpdateNode (PARSEOP_BYTECONST, $1);}
+ | ByteConst {}
+ ;
+
+WordConstExpr
+ : Type3Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 2);}
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 2);}
+ | ConstExprTerm {$$ = TrUpdateNode (PARSEOP_WORDCONST, $1);}
+ | WordConst {}
+ ;
+
+DWordConstExpr
+ : Type3Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 4);}
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 4);}
+ | ConstExprTerm {$$ = TrUpdateNode (PARSEOP_DWORDCONST, $1);}
+ | DWordConst {}
+ ;
+
+QWordConstExpr
+ : Type3Opcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 8);}
+ | Type2IntegerOpcode {$$ = TrSetNodeFlags ($1, NODE_COMPILE_TIME_CONST); TrSetNodeAmlLength ($1, 8);}
+ | ConstExprTerm {$$ = TrUpdateNode (PARSEOP_QWORDCONST, $1);}
+ | QWordConst {}
+ ;
+
+/* OptionalCount must appear before ByteList or an incorrect reduction will result */
+
+OptionalCount
+ : {$$ = TrCreateLeafNode (PARSEOP_ONES);} /* Placeholder is a OnesOp object */
+ | ',' {$$ = TrCreateLeafNode (PARSEOP_ONES);} /* Placeholder is a OnesOp object */
+ | ',' TermArg {$$ = $2;}
+ ;
+
+BufferTerm
+ : PARSEOP_BUFFER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_BUFFER);}
+ OptionalTermArg
+ ')' '{'
+ BufferTermData '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_BUFFER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+BufferTermData
+ : ByteList {}
+ | StringData {}
+ ;
+
+ByteList
+ : {$$ = NULL;}
+ | ByteConstExpr
+ | ByteList ',' /* Allows a trailing comma at list end */
+ | ByteList ','
+ ByteConstExpr {$$ = TrLinkPeerNode ($1,$3);}
+ ;
+
+DataBufferTerm
+ : PARSEOP_DATABUFFER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DATABUFFER);}
+ OptionalWordConst
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_DATABUFFER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DWordList
+ : {$$ = NULL;}
+ | DWordConstExpr
+ | DWordList ',' /* Allows a trailing comma at list end */
+ | DWordList ','
+ DWordConstExpr {$$ = TrLinkPeerNode ($1,$3);}
+ ;
+
+PackageTerm
+ : PARSEOP_PACKAGE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_VAR_PACKAGE);}
+ VarPackageLengthTerm
+ ')' '{'
+ PackageList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_PACKAGE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+PackageList
+ : {$$ = NULL;}
+ | PackageElement
+ | PackageList ',' /* Allows a trailing comma at list end */
+ | PackageList ','
+ PackageElement {$$ = TrLinkPeerNode ($1,$3);}
+ ;
+
+PackageElement
+ : DataObject {}
+ | NameString {}
+ ;
+
+VarPackageLengthTerm
+ : {$$ = TrCreateLeafNode (PARSEOP_DEFAULT_ARG);}
+ | TermArg {$$ = $1;}
+ ;
+
+
+/******* Macros ***********************************************/
+
+
+EISAIDTerm
+ : PARSEOP_EISAID '('
+ StringData ')' {$$ = TrUpdateNode (PARSEOP_EISAID, $3);}
+ | PARSEOP_EISAID '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+UnicodeTerm
+ : PARSEOP_UNICODE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_UNICODE);}
+ StringData
+ ')' {$$ = TrLinkChildren ($<n>3,2,0,$4);}
+ | PARSEOP_UNICODE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Resources and Memory ***********************************************/
+
+
+/*
+ * Note: Create two default nodes to allow conversion to a Buffer AML opcode
+ * Also, insert the EndTag at the end of the template.
+ */
+ResourceTemplateTerm
+ : PARSEOP_RESOURCETEMPLATE '(' ')'
+ '{'
+ ResourceMacroList '}' {$$ = TrCreateNode (PARSEOP_RESOURCETEMPLATE,4,
+ TrCreateLeafNode (PARSEOP_DEFAULT_ARG),
+ TrCreateLeafNode (PARSEOP_DEFAULT_ARG),
+ $5,
+ TrCreateLeafNode (PARSEOP_ENDTAG));}
+ ;
+
+ResourceMacroList
+ : {$$ = NULL;}
+ | ResourceMacroList
+ ResourceMacroTerm {$$ = TrLinkPeerNode ($1,$2);}
+ ;
+
+ResourceMacroTerm
+ : DMATerm {}
+ | DWordIOTerm {}
+ | DWordMemoryTerm {}
+ | DWordSpaceTerm {}
+ | EndDependentFnTerm {}
+ | ExtendedIOTerm {}
+ | ExtendedMemoryTerm {}
+ | ExtendedSpaceTerm {}
+ | FixedDmaTerm {}
+ | FixedIOTerm {}
+ | GpioIntTerm {}
+ | GpioIoTerm {}
+ | I2cSerialBusTerm {}
+ | InterruptTerm {}
+ | IOTerm {}
+ | IRQNoFlagsTerm {}
+ | IRQTerm {}
+ | Memory24Term {}
+ | Memory32FixedTerm {}
+ | Memory32Term {}
+ | QWordIOTerm {}
+ | QWordMemoryTerm {}
+ | QWordSpaceTerm {}
+ | RegisterTerm {}
+ | SpiSerialBusTerm {}
+ | StartDependentFnNoPriTerm {}
+ | StartDependentFnTerm {}
+ | UartSerialBusTerm {}
+ | VendorLongTerm {}
+ | VendorShortTerm {}
+ | WordBusNumberTerm {}
+ | WordIOTerm {}
+ | WordSpaceTerm {}
+ ;
+
+DMATerm
+ : PARSEOP_DMA '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DMA);}
+ DMATypeKeyword
+ OptionalBusMasterKeyword
+ ',' XferTypeKeyword
+ OptionalNameString_Last
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,5,$4,$5,$7,$8,$11);}
+ | PARSEOP_DMA '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DWordIOTerm
+ : PARSEOP_DWORDIO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DWORDIO);}
+ OptionalResourceType_First
+ OptionalMinType
+ OptionalMaxType
+ OptionalDecodeType
+ OptionalRangeType
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString
+ OptionalType
+ OptionalTranslationType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,15,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$19,$20,$21,$22,$23);}
+ | PARSEOP_DWORDIO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DWordMemoryTerm
+ : PARSEOP_DWORDMEMORY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DWORDMEMORY);}
+ OptionalResourceType_First
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ OptionalMemType
+ ',' OptionalReadWriteKeyword
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString
+ OptionalAddressRange
+ OptionalType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,16,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$20,$21,$22,$23,$24,$25);}
+ | PARSEOP_DWORDMEMORY '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+DWordSpaceTerm
+ : PARSEOP_DWORDSPACE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DWORDSPACE);}
+ ByteConstExpr {UtCheckIntegerRange ($4, 0xC0, 0xFF);}
+ OptionalResourceType
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ ',' ByteConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,14,$4,$6,$7,$8,$9,$11,$13,$15,$17,$19,$21,$22,$23,$24);}
+ | PARSEOP_DWORDSPACE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+EndDependentFnTerm
+ : PARSEOP_ENDDEPENDENTFN '('
+ ')' {$$ = TrCreateLeafNode (PARSEOP_ENDDEPENDENTFN);}
+ | PARSEOP_ENDDEPENDENTFN '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ExtendedIOTerm
+ : PARSEOP_EXTENDEDIO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EXTENDEDIO);}
+ OptionalResourceType_First
+ OptionalMinType
+ OptionalMaxType
+ OptionalDecodeType
+ OptionalRangeType
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalQWordConstExpr
+ OptionalNameString
+ OptionalType
+ OptionalTranslationType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,14,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$19,$20,$21,$22);}
+ | PARSEOP_EXTENDEDIO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ExtendedMemoryTerm
+ : PARSEOP_EXTENDEDMEMORY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EXTENDEDMEMORY);}
+ OptionalResourceType_First
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ OptionalMemType
+ ',' OptionalReadWriteKeyword
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalQWordConstExpr
+ OptionalNameString
+ OptionalAddressRange
+ OptionalType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,15,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$20,$21,$22,$23,$24);}
+ | PARSEOP_EXTENDEDMEMORY '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+ExtendedSpaceTerm
+ : PARSEOP_EXTENDEDSPACE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EXTENDEDSPACE);}
+ ByteConstExpr {UtCheckIntegerRange ($4, 0xC0, 0xFF);}
+ OptionalResourceType
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ ',' ByteConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalQWordConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,13,$4,$6,$7,$8,$9,$11,$13,$15,$17,$19,$21,$22,$23);}
+ | PARSEOP_EXTENDEDSPACE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FixedDmaTerm
+ : PARSEOP_FIXEDDMA '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FIXEDDMA);}
+ WordConstExpr /* 04: DMA RequestLines */
+ ',' WordConstExpr /* 06: DMA Channels */
+ OptionalXferSize /* 07: DMA TransferSize */
+ OptionalNameString /* 08: DescriptorName */
+ ')' {$$ = TrLinkChildren ($<n>3,4,$4,$6,$7,$8);}
+ | PARSEOP_FIXEDDMA '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+FixedIOTerm
+ : PARSEOP_FIXEDIO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FIXEDIO);}
+ WordConstExpr
+ ',' ByteConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,3,$4,$6,$7);}
+ | PARSEOP_FIXEDIO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+GpioIntTerm
+ : PARSEOP_GPIO_INT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_GPIO_INT);}
+ InterruptTypeKeyword /* 04: InterruptType */
+ ',' InterruptLevel /* 06: InterruptLevel */
+ OptionalShareType /* 07: SharedType */
+ ',' PinConfigByte /* 09: PinConfig */
+ OptionalWordConstExpr /* 10: DebounceTimeout */
+ ',' StringData /* 12: ResourceSource */
+ OptionalByteConstExpr /* 13: ResourceSourceIndex */
+ OptionalResourceType /* 14: ResourceType */
+ OptionalNameString /* 15: DescriptorName */
+ OptionalBuffer_Last /* 16: VendorData */
+ ')' '{'
+ DWordConstExpr '}' {$$ = TrLinkChildren ($<n>3,11,$4,$6,$7,$9,$10,$12,$13,$14,$15,$16,$19);}
+ | PARSEOP_GPIO_INT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+GpioIoTerm
+ : PARSEOP_GPIO_IO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_GPIO_IO);}
+ OptionalShareType_First /* 04: SharedType */
+ ',' PinConfigByte /* 06: PinConfig */
+ OptionalWordConstExpr /* 07: DebounceTimeout */
+ OptionalWordConstExpr /* 08: DriveStrength */
+ OptionalIoRestriction /* 09: IoRestriction */
+ ',' StringData /* 11: ResourceSource */
+ OptionalByteConstExpr /* 12: ResourceSourceIndex */
+ OptionalResourceType /* 13: ResourceType */
+ OptionalNameString /* 14: DescriptorName */
+ OptionalBuffer_Last /* 15: VendorData */
+ ')' '{'
+ DWordList '}' {$$ = TrLinkChildren ($<n>3,11,$4,$6,$7,$8,$9,$11,$12,$13,$14,$15,$18);}
+ | PARSEOP_GPIO_IO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+I2cSerialBusTerm
+ : PARSEOP_I2C_SERIALBUS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_I2C_SERIALBUS);}
+ WordConstExpr /* 04: SlaveAddress */
+ OptionalSlaveMode /* 05: SlaveMode */
+ ',' DWordConstExpr /* 07: ConnectionSpeed */
+ OptionalAddressingMode /* 08: AddressingMode */
+ ',' StringData /* 10: ResourceSource */
+ OptionalByteConstExpr /* 11: ResourceSourceIndex */
+ OptionalResourceType /* 12: ResourceType */
+ OptionalNameString /* 13: DescriptorName */
+ OptionalBuffer_Last /* 14: VendorData */
+ ')' {$$ = TrLinkChildren ($<n>3,9,$4,$5,$7,$8,$10,$11,$12,$13,$14);}
+ | PARSEOP_I2C_SERIALBUS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+InterruptTerm
+ : PARSEOP_INTERRUPT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INTERRUPT);}
+ OptionalResourceType_First
+ ',' InterruptTypeKeyword
+ ',' InterruptLevel
+ OptionalShareType
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString_Last
+ ')' '{'
+ DWordList '}' {$$ = TrLinkChildren ($<n>3,8,$4,$6,$8,$9,$10,$11,$12,$15);}
+ | PARSEOP_INTERRUPT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IOTerm
+ : PARSEOP_IO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IO);}
+ IODecodeKeyword
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' ByteConstExpr
+ ',' ByteConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$6,$8,$10,$12,$13);}
+ | PARSEOP_IO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IRQNoFlagsTerm
+ : PARSEOP_IRQNOFLAGS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IRQNOFLAGS);}
+ OptionalNameString_First
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_IRQNOFLAGS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+IRQTerm
+ : PARSEOP_IRQ '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IRQ);}
+ InterruptTypeKeyword
+ ',' InterruptLevel
+ OptionalShareType
+ OptionalNameString_Last
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,5,$4,$6,$7,$8,$11);}
+ | PARSEOP_IRQ '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+Memory24Term
+ : PARSEOP_MEMORY24 '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MEMORY24);}
+ OptionalReadWriteKeyword
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$6,$8,$10,$12,$13);}
+ | PARSEOP_MEMORY24 '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+Memory32FixedTerm
+ : PARSEOP_MEMORY32FIXED '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MEMORY32FIXED);}
+ OptionalReadWriteKeyword
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,4,$4,$6,$8,$9);}
+ | PARSEOP_MEMORY32FIXED '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+Memory32Term
+ : PARSEOP_MEMORY32 '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MEMORY32);}
+ OptionalReadWriteKeyword
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ ',' DWordConstExpr
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$6,$8,$10,$12,$13);}
+ | PARSEOP_MEMORY32 '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+QWordIOTerm
+ : PARSEOP_QWORDIO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_QWORDIO);}
+ OptionalResourceType_First
+ OptionalMinType
+ OptionalMaxType
+ OptionalDecodeType
+ OptionalRangeType
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString
+ OptionalType
+ OptionalTranslationType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,15,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$19,$20,$21,$22,$23);}
+ | PARSEOP_QWORDIO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+QWordMemoryTerm
+ : PARSEOP_QWORDMEMORY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_QWORDMEMORY);}
+ OptionalResourceType_First
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ OptionalMemType
+ ',' OptionalReadWriteKeyword
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString
+ OptionalAddressRange
+ OptionalType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,16,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$20,$21,$22,$23,$24,$25);}
+ | PARSEOP_QWORDMEMORY '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+QWordSpaceTerm
+ : PARSEOP_QWORDSPACE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_QWORDSPACE);}
+ ByteConstExpr {UtCheckIntegerRange ($4, 0xC0, 0xFF);}
+ OptionalResourceType
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ ',' ByteConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ ',' QWordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,14,$4,$6,$7,$8,$9,$11,$13,$15,$17,$19,$21,$22,$23,$24);}
+ | PARSEOP_QWORDSPACE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+RegisterTerm
+ : PARSEOP_REGISTER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_REGISTER);}
+ AddressSpaceKeyword
+ ',' ByteConstExpr
+ ',' ByteConstExpr
+ ',' QWordConstExpr
+ OptionalAccessSize
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,6,$4,$6,$8,$10,$11,$12);}
+ | PARSEOP_REGISTER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+SpiSerialBusTerm
+ : PARSEOP_SPI_SERIALBUS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SPI_SERIALBUS);}
+ WordConstExpr /* 04: DeviceSelection */
+ OptionalDevicePolarity /* 05: DevicePolarity */
+ OptionalWireMode /* 06: WireMode */
+ ',' ByteConstExpr /* 08: DataBitLength */
+ OptionalSlaveMode /* 09: SlaveMode */
+ ',' DWordConstExpr /* 11: ConnectionSpeed */
+ ',' ClockPolarityKeyword /* 13: ClockPolarity */
+ ',' ClockPhaseKeyword /* 15: ClockPhase */
+ ',' StringData /* 17: ResourceSource */
+ OptionalByteConstExpr /* 18: ResourceSourceIndex */
+ OptionalResourceType /* 19: ResourceType */
+ OptionalNameString /* 20: DescriptorName */
+ OptionalBuffer_Last /* 21: VendorData */
+ ')' {$$ = TrLinkChildren ($<n>3,13,$4,$5,$6,$8,$9,$11,$13,$15,$17,$18,$19,$20,$21);}
+ | PARSEOP_SPI_SERIALBUS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+StartDependentFnNoPriTerm
+ : PARSEOP_STARTDEPENDENTFN_NOPRI '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STARTDEPENDENTFN_NOPRI);}
+ ')' '{'
+ ResourceMacroList '}' {$$ = TrLinkChildren ($<n>3,1,$6);}
+ | PARSEOP_STARTDEPENDENTFN_NOPRI '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+StartDependentFnTerm
+ : PARSEOP_STARTDEPENDENTFN '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STARTDEPENDENTFN);}
+ ByteConstExpr
+ ',' ByteConstExpr
+ ')' '{'
+ ResourceMacroList '}' {$$ = TrLinkChildren ($<n>3,3,$4,$6,$9);}
+ | PARSEOP_STARTDEPENDENTFN '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+UartSerialBusTerm
+ : PARSEOP_UART_SERIALBUS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_UART_SERIALBUS);}
+ DWordConstExpr /* 04: ConnectionSpeed */
+ OptionalBitsPerByte /* 05: BitsPerByte */
+ OptionalStopBits /* 06: StopBits */
+ ',' ByteConstExpr /* 08: LinesInUse */
+ OptionalEndian /* 09: Endianess */
+ OptionalParityType /* 10: Parity */
+ OptionalFlowControl /* 11: FlowControl */
+ ',' WordConstExpr /* 13: Rx BufferSize */
+ ',' WordConstExpr /* 15: Tx BufferSize */
+ ',' StringData /* 17: ResourceSource */
+ OptionalByteConstExpr /* 18: ResourceSourceIndex */
+ OptionalResourceType /* 19: ResourceType */
+ OptionalNameString /* 20: DescriptorName */
+ OptionalBuffer_Last /* 21: VendorData */
+ ')' {$$ = TrLinkChildren ($<n>3,14,$4,$5,$6,$8,$9,$10,$11,$13,$15,$17,$18,$19,$20,$21);}
+ | PARSEOP_UART_SERIALBUS '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+VendorLongTerm
+ : PARSEOP_VENDORLONG '(' {$<n>$ = TrCreateLeafNode (PARSEOP_VENDORLONG);}
+ OptionalNameString_First
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_VENDORLONG '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+VendorShortTerm
+ : PARSEOP_VENDORSHORT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_VENDORSHORT);}
+ OptionalNameString_First
+ ')' '{'
+ ByteList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
+ | PARSEOP_VENDORSHORT '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+WordBusNumberTerm
+ : PARSEOP_WORDBUSNUMBER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WORDBUSNUMBER);}
+ OptionalResourceType_First
+ OptionalMinType
+ OptionalMaxType
+ OptionalDecodeType
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,12,$4,$5,$6,$7,$9,$11,$13,$15,$17,$18,$19,$20);}
+ | PARSEOP_WORDBUSNUMBER '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+WordIOTerm
+ : PARSEOP_WORDIO '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WORDIO);}
+ OptionalResourceType_First
+ OptionalMinType
+ OptionalMaxType
+ OptionalDecodeType
+ OptionalRangeType
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString
+ OptionalType
+ OptionalTranslationType_Last
+ ')' {$$ = TrLinkChildren ($<n>3,15,$4,$5,$6,$7,$8,$10,$12,$14,$16,$18,$19,$20,$21,$22,$23);}
+ | PARSEOP_WORDIO '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+WordSpaceTerm
+ : PARSEOP_WORDSPACE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WORDSPACE);}
+ ByteConstExpr {UtCheckIntegerRange ($4, 0xC0, 0xFF);}
+ OptionalResourceType
+ OptionalDecodeType
+ OptionalMinType
+ OptionalMaxType
+ ',' ByteConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ ',' WordConstExpr
+ OptionalByteConstExpr
+ OptionalStringData
+ OptionalNameString_Last
+ ')' {$$ = TrLinkChildren ($<n>3,14,$4,$6,$7,$8,$9,$11,$13,$15,$17,$19,$21,$22,$23,$24);}
+ | PARSEOP_WORDSPACE '('
+ error ')' {$$ = AslDoError(); yyclearin;}
+ ;
+
+
+/******* Object References ***********************************************/
+
+/* Allow IO, DMA, IRQ Resource macro names to also be used as identifiers */
+
+NameString
+ : NameSeg {}
+ | PARSEOP_NAMESTRING {$$ = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, (ACPI_NATIVE_INT) AslCompilerlval.s);}
+ | PARSEOP_IO {$$ = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, (ACPI_NATIVE_INT) "IO");}
+ | PARSEOP_DMA {$$ = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, (ACPI_NATIVE_INT) "DMA");}
+ | PARSEOP_IRQ {$$ = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, (ACPI_NATIVE_INT) "IRQ");}
+ ;
+
+NameSeg
+ : PARSEOP_NAMESEG {$$ = TrCreateValuedLeafNode (PARSEOP_NAMESEG, (ACPI_NATIVE_INT) AslCompilerlval.s);}
+ ;
+
+
+/******* Helper rules ****************************************************/
+
+
+AmlPackageLengthTerm
+ : Integer {$$ = TrUpdateNode (PARSEOP_PACKAGE_LENGTH,(ACPI_PARSE_OBJECT *) $1);}
+ ;
+
+NameStringItem
+ : ',' NameString {$$ = $2;}
+ | ',' error {$$ = AslDoError (); yyclearin;}
+ ;
+
+TermArgItem
+ : ',' TermArg {$$ = $2;}
+ | ',' error {$$ = AslDoError (); yyclearin;}
+ ;
+
+OptionalBusMasterKeyword
+ : ',' {$$ = TrCreateLeafNode (PARSEOP_BUSMASTERTYPE_MASTER);}
+ | ',' PARSEOP_BUSMASTERTYPE_MASTER {$$ = TrCreateLeafNode (PARSEOP_BUSMASTERTYPE_MASTER);}
+ | ',' PARSEOP_BUSMASTERTYPE_NOTMASTER {$$ = TrCreateLeafNode (PARSEOP_BUSMASTERTYPE_NOTMASTER);}
+ ;
+
+OptionalAccessAttribTerm
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' ByteConstExpr {$$ = $2;}
+ | ',' AccessAttribKeyword {$$ = $2;}
+ ;
+
+OptionalAccessSize
+ : {$$ = TrCreateValuedLeafNode (PARSEOP_BYTECONST, 0);}
+ | ',' {$$ = TrCreateValuedLeafNode (PARSEOP_BYTECONST, 0);}
+ | ',' ByteConstExpr {$$ = $2;}
+ ;
+
+OptionalAddressingMode
+ : ',' {$$ = NULL;}
+ | ',' AddressingModeKeyword {$$ = $2;}
+ ;
+
+OptionalAddressRange
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' AddressKeyword {$$ = $2;}
+ ;
+
+OptionalBitsPerByte
+ : ',' {$$ = NULL;}
+ | ',' BitsPerByteKeyword {$$ = $2;}
+ ;
+
+OptionalBuffer_Last
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' DataBufferTerm {$$ = $2;}
+ ;
+
+OptionalByteConstExpr
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' ByteConstExpr {$$ = $2;}
+ ;
+
+OptionalDecodeType
+ : ',' {$$ = NULL;}
+ | ',' DecodeKeyword {$$ = $2;}
+ ;
+
+OptionalDevicePolarity
+ : ',' {$$ = NULL;}
+ | ',' DevicePolarityKeyword {$$ = $2;}
+ ;
+
+OptionalDWordConstExpr
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' DWordConstExpr {$$ = $2;}
+ ;
+
+OptionalEndian
+ : ',' {$$ = NULL;}
+ | ',' EndianKeyword {$$ = $2;}
+ ;
+
+OptionalFlowControl
+ : ',' {$$ = NULL;}
+ | ',' FlowControlKeyword {$$ = $2;}
+ ;
+
+OptionalIoRestriction
+ : ',' {$$ = NULL;}
+ | ',' IoRestrictionKeyword {$$ = $2;}
+ ;
+
+OptionalListString
+ : {$$ = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL, ACPI_TO_INTEGER (""));} /* Placeholder is a NULL string */
+ | ',' {$$ = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL, ACPI_TO_INTEGER (""));} /* Placeholder is a NULL string */
+ | ',' TermArg {$$ = $2;}
+ ;
+
+OptionalMaxType
+ : ',' {$$ = NULL;}
+ | ',' MaxKeyword {$$ = $2;}
+ ;
+
+OptionalMemType
+ : ',' {$$ = NULL;}
+ | ',' MemTypeKeyword {$$ = $2;}
+ ;
+
+OptionalMinType
+ : ',' {$$ = NULL;}
+ | ',' MinKeyword {$$ = $2;}
+ ;
+
+OptionalNameString
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' NameString {$$ = $2;}
+ ;
+
+OptionalNameString_Last
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' NameString {$$ = $2;}
+ ;
+
+OptionalNameString_First
+ : {$$ = TrCreateLeafNode (PARSEOP_ZERO);}
+ | NameString {$$ = $1;}
+ ;
+
+OptionalObjectTypeKeyword
+ : {$$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE_UNK);}
+ | ',' ObjectTypeKeyword {$$ = $2;}
+ ;
+
+OptionalParityType
+ : ',' {$$ = NULL;}
+ | ',' ParityTypeKeyword {$$ = $2;}
+ ;
+
+OptionalQWordConstExpr
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' QWordConstExpr {$$ = $2;}
+ ;
+
+OptionalRangeType
+ : ',' {$$ = NULL;}
+ | ',' RangeTypeKeyword {$$ = $2;}
+ ;
+
+OptionalReadWriteKeyword
+ : {$$ = TrCreateLeafNode (PARSEOP_READWRITETYPE_BOTH);}
+ | PARSEOP_READWRITETYPE_BOTH {$$ = TrCreateLeafNode (PARSEOP_READWRITETYPE_BOTH);}
+ | PARSEOP_READWRITETYPE_READONLY {$$ = TrCreateLeafNode (PARSEOP_READWRITETYPE_READONLY);}
+ ;
+
+OptionalReference
+ : {$$ = TrCreateLeafNode (PARSEOP_ZERO);} /* Placeholder is a ZeroOp object */
+ | ',' {$$ = TrCreateLeafNode (PARSEOP_ZERO);} /* Placeholder is a ZeroOp object */
+ | ',' TermArg {$$ = $2;}
+ ;
+
+OptionalResourceType_First
+ : {$$ = TrCreateLeafNode (PARSEOP_RESOURCETYPE_CONSUMER);}
+ | ResourceTypeKeyword {$$ = $1;}
+ ;
+
+OptionalResourceType
+ : {$$ = TrCreateLeafNode (PARSEOP_RESOURCETYPE_CONSUMER);}
+ | ',' {$$ = TrCreateLeafNode (PARSEOP_RESOURCETYPE_CONSUMER);}
+ | ',' ResourceTypeKeyword {$$ = $2;}
+ ;
+
+OptionalReturnArg
+ : {$$ = TrSetNodeFlags (TrCreateLeafNode (PARSEOP_ZERO), NODE_IS_NULL_RETURN);} /* Placeholder is a ZeroOp object */
+ | TermArg {$$ = $1;}
+ ;
+
+OptionalSerializeRuleKeyword
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' SerializeRuleKeyword {$$ = $2;}
+ ;
+
+OptionalSlaveMode
+ : ',' {$$ = NULL;}
+ | ',' SlaveModeKeyword {$$ = $2;}
+ ;
+
+OptionalShareType
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' ShareTypeKeyword {$$ = $2;}
+ ;
+
+OptionalShareType_First
+ : {$$ = NULL;}
+ | ShareTypeKeyword {$$ = $1;}
+ ;
+
+OptionalStopBits
+ : ',' {$$ = NULL;}
+ | ',' StopBitsKeyword {$$ = $2;}
+ ;
+
+OptionalStringData
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' StringData {$$ = $2;}
+ ;
+
+OptionalTermArg
+ : {$$ = NULL;}
+ | TermArg {$$ = $1;}
+ ;
+
+OptionalType
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' TypeKeyword {$$ = $2;}
+ ;
+
+OptionalType_Last
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' TypeKeyword {$$ = $2;}
+ ;
+
+OptionalTranslationType_Last
+ : {$$ = NULL;}
+ | ',' {$$ = NULL;}
+ | ',' TranslationKeyword {$$ = $2;}
+ ;
+
+OptionalWireMode
+ : ',' {$$ = NULL;}
+ | ',' WireModeKeyword {$$ = $2;}
+ ;
+
+OptionalWordConst
+ : {$$ = NULL;}
+ | WordConst {$$ = $1;}
+ ;
+
+OptionalWordConstExpr
+ : ',' {$$ = NULL;}
+ | ',' WordConstExpr {$$ = $2;}
+ ;
+
+OptionalXferSize
+ : {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_32, 2);}
+ | ',' {$$ = TrCreateValuedLeafNode (PARSEOP_XFERSIZE_32, 2);}
+ | ',' XferSizeKeyword {$$ = $2;}
+ ;
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstartup.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstartup.c
new file mode 100644
index 0000000000..39fad4f7d7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstartup.c
@@ -0,0 +1,524 @@
+/******************************************************************************
+ *
+ * Module Name: aslstartup - Compiler startup routines, called from main
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslstartup")
+
+
+/* Local prototypes */
+
+static UINT8
+AslDetectSourceFileType (
+ ASL_FILE_INFO *Info);
+
+static ACPI_STATUS
+AslDoDisassembly (
+ void);
+
+
+/* Globals */
+
+static BOOLEAN AslToFile = TRUE;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslInitializeGlobals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Re-initialize globals needed to restart the compiler. This
+ * allows multiple files to be disassembled and/or compiled.
+ *
+ ******************************************************************************/
+
+void
+AslInitializeGlobals (
+ void)
+{
+ UINT32 i;
+
+
+ /* Init compiler globals */
+
+ Gbl_SyntaxError = 0;
+ Gbl_CurrentColumn = 0;
+ Gbl_CurrentLineNumber = 1;
+ Gbl_LogicalLineNumber = 1;
+ Gbl_CurrentLineOffset = 0;
+ Gbl_InputFieldCount = 0;
+ Gbl_InputByteCount = 0;
+ Gbl_NsLookupCount = 0;
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+
+ Gbl_ErrorLog = NULL;
+ Gbl_NextError = NULL;
+ Gbl_Signature = NULL;
+ Gbl_FileType = 0;
+
+ TotalExecutableOpcodes = 0;
+ TotalNamedObjects = 0;
+ TotalKeywords = 0;
+ TotalParseNodes = 0;
+ TotalMethods = 0;
+ TotalAllocations = 0;
+ TotalAllocated = 0;
+ TotalFolds = 0;
+
+ AslGbl_NextEvent = 0;
+ for (i = 0; i < ASL_NUM_REPORT_LEVELS; i++)
+ {
+ Gbl_ExceptionCount[i] = 0;
+ }
+
+ for (i = ASL_FILE_INPUT; i <= ASL_MAX_FILE_TYPE; i++)
+ {
+ Gbl_Files[i].Handle = NULL;
+ Gbl_Files[i].Filename = NULL;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDetectSourceFileType
+ *
+ * PARAMETERS: Info - Name/Handle for the file (must be open)
+ *
+ * RETURN: File Type
+ *
+ * DESCRIPTION: Determine the type of the input file. Either binary (contains
+ * non-ASCII characters), ASL file, or an ACPI Data Table file.
+ *
+ ******************************************************************************/
+
+static UINT8
+AslDetectSourceFileType (
+ ASL_FILE_INFO *Info)
+{
+ char *FileChar;
+ UINT8 Type;
+ ACPI_STATUS Status;
+
+
+ /* Check for a valid binary ACPI table */
+
+ Status = FlCheckForAcpiTable (Info->Handle);
+ if (ACPI_SUCCESS (Status))
+ {
+ Type = ASL_INPUT_TYPE_ACPI_TABLE;
+ goto Cleanup;
+ }
+
+ /* Check for 100% ASCII source file (comments are ignored) */
+
+ Status = FlCheckForAscii (Info->Filename, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ printf ("Invalid characters in input file - %s\n", Info->Filename);
+
+ if (!Gbl_IgnoreErrors)
+ {
+ Type = ASL_INPUT_TYPE_BINARY;
+ goto Cleanup;
+ }
+ }
+
+ /*
+ * File is ASCII. Determine if this is an ASL file or an ACPI data
+ * table file.
+ */
+ while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle))
+ {
+ /* Uppercase the buffer for caseless compare */
+
+ FileChar = Gbl_CurrentLineBuffer;
+ while (*FileChar)
+ {
+ *FileChar = (char) toupper ((int) *FileChar);
+ FileChar++;
+ }
+
+ /* Presence of "DefinitionBlock" indicates actual ASL code */
+
+ if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK"))
+ {
+ /* Appears to be an ASL file */
+
+ Type = ASL_INPUT_TYPE_ASCII_ASL;
+ goto Cleanup;
+ }
+ }
+
+ /* Not an ASL source file, default to a data table source file */
+
+ Type = ASL_INPUT_TYPE_ASCII_DATA;
+
+Cleanup:
+
+ /* Must seek back to the start of the file */
+
+ fseek (Info->Handle, 0, SEEK_SET);
+ return (Type);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoDisassembly
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initiate AML file disassembly. Uses ACPICA subsystem to build
+ * namespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AslDoDisassembly (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* ACPICA subsystem initialization */
+
+ Status = AdInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiAllocateRootTable (4);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not initialize ACPI Table Manager, %s\n",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /* Handle additional output files for disassembler */
+
+ Gbl_FileType = ASL_INPUT_TYPE_ACPI_TABLE;
+ Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
+
+ /* This is where the disassembly happens */
+
+ AcpiGbl_DmOpt_Disasm = TRUE;
+ Status = AdAmlDisassemble (AslToFile,
+ Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_OutputFilenamePrefix,
+ &Gbl_Files[ASL_FILE_INPUT].Filename);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Check if any control methods were unresolved */
+
+ AcpiDmUnresolvedWarning (0);
+
+ /* Shutdown compiler and ACPICA subsystem */
+
+ AeClearErrorLog ();
+ (void) AcpiTerminate ();
+
+ /*
+ * Gbl_Files[ASL_FILE_INPUT].Filename was replaced with the
+ * .DSL disassembly file, which can now be compiled if requested
+ */
+ if (Gbl_DoCompile)
+ {
+ AcpiOsPrintf ("\nCompiling \"%s\"\n",
+ Gbl_Files[ASL_FILE_INPUT].Filename);
+ return (AE_CTRL_CONTINUE);
+ }
+
+ /* No need to free the filename string */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
+
+ CmDeleteCaches ();
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoOneFile
+ *
+ * PARAMETERS: Filename - Name of the file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Process a single file - either disassemble, compile, or both
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AslDoOneFile (
+ char *Filename)
+{
+ ACPI_STATUS Status;
+
+
+ /* Re-initialize "some" compiler/preprocessor globals */
+
+ AslInitializeGlobals ();
+ PrInitializeGlobals ();
+
+ /*
+ * Extract the directory path. This path is used for possible include
+ * files and the optional AML filename embedded in the input file
+ * DefinitionBlock declaration.
+ */
+ Status = FlSplitInputPathname (Filename, &Gbl_DirectoryPath, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Take a copy of the input filename, convert any backslashes */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename =
+ UtStringCacheCalloc (strlen (Filename) + 1);
+
+ strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
+ UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename);
+
+ /*
+ * AML Disassembly (Optional)
+ */
+ if (Gbl_DisasmFlag)
+ {
+ Status = AslDoDisassembly ();
+ if (Status != AE_CTRL_CONTINUE)
+ {
+ return (Status);
+ }
+ }
+
+ /*
+ * Open the input file. Here, this should be an ASCII source file,
+ * either an ASL file or a Data Table file
+ */
+ Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
+ if (ACPI_FAILURE (Status))
+ {
+ AePrintErrorLog (ASL_FILE_STDERR);
+ return (AE_ERROR);
+ }
+
+ Gbl_OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT);
+
+ /* Determine input file type */
+
+ Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
+ if (Gbl_FileType == ASL_INPUT_TYPE_BINARY)
+ {
+ return (AE_ERROR);
+ }
+
+ /*
+ * If -p not specified, we will use the input filename as the
+ * output filename prefix
+ */
+ if (Gbl_UseDefaultAmlFilename)
+ {
+ Gbl_OutputFilenamePrefix = Gbl_Files[ASL_FILE_INPUT].Filename;
+ }
+
+ /* Open the optional output files (listings, etc.) */
+
+ Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
+ if (ACPI_FAILURE (Status))
+ {
+ AePrintErrorLog (ASL_FILE_STDERR);
+ return (AE_ERROR);
+ }
+
+ /*
+ * Compilation of ASL source versus DataTable source uses different
+ * compiler subsystems
+ */
+ switch (Gbl_FileType)
+ {
+ /*
+ * Data Table Compilation
+ */
+ case ASL_INPUT_TYPE_ASCII_DATA:
+
+ Status = DtDoCompile ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Gbl_Signature)
+ {
+ Gbl_Signature = NULL;
+ }
+
+ /* Check if any errors occurred during compile */
+
+ Status = AslCheckForErrorExit ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Cleanup (for next source file) and exit */
+
+ AeClearErrorLog ();
+ PrTerminatePreprocessor ();
+ return (Status);
+
+ /*
+ * ASL Compilation
+ */
+ case ASL_INPUT_TYPE_ASCII_ASL:
+
+ /* ACPICA subsystem initialization */
+
+ Status = AdInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ (void) CmDoCompile ();
+ (void) AcpiTerminate ();
+
+ /* Check if any errors occurred during compile */
+
+ Status = AslCheckForErrorExit ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Cleanup (for next source file) and exit */
+
+ AeClearErrorLog ();
+ PrTerminatePreprocessor ();
+ return (AE_OK);
+
+ /*
+ * Binary ACPI table was auto-detected, disassemble it
+ */
+ case ASL_INPUT_TYPE_ACPI_TABLE:
+
+ /* We have what appears to be an ACPI table, disassemble it */
+
+ FlCloseFile (ASL_FILE_INPUT);
+ Gbl_DoCompile = FALSE;
+ Gbl_DisasmFlag = TRUE;
+ Status = AslDoDisassembly ();
+ return (Status);
+
+ /* Unknown binary table */
+
+ case ASL_INPUT_TYPE_BINARY:
+
+ AePrintErrorLog (ASL_FILE_STDERR);
+ return (AE_ERROR);
+
+ default:
+
+ printf ("Unknown file type %X\n", Gbl_FileType);
+ return (AE_ERROR);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCheckForErrorExit
+ *
+ * PARAMETERS: None. Examines global exception count array
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if compiler should abort with error status
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AslCheckForErrorExit (
+ void)
+{
+
+ /*
+ * Return non-zero exit code if there have been errors, unless the
+ * global ignore error flag has been set
+ */
+ if (!Gbl_IgnoreErrors)
+ {
+ if (Gbl_ExceptionCount[ASL_ERROR] > 0)
+ {
+ return (AE_ERROR);
+ }
+
+ /* Optionally treat warnings as errors */
+
+ if (Gbl_WarningsAsErrors)
+ {
+ if ((Gbl_ExceptionCount[ASL_WARNING] > 0) ||
+ (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
+ (Gbl_ExceptionCount[ASL_WARNING3] > 0))
+ {
+ return (AE_ERROR);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstubs.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstubs.c
new file mode 100644
index 0000000000..b0b4010f27
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslstubs.c
@@ -0,0 +1,272 @@
+/******************************************************************************
+ *
+ * Module Name: aslstubs - Stubs used to link to Aml interpreter
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslstubs")
+
+
+/*
+ * Stubs to simplify linkage to the ACPICA core subsystem.
+ * Things like Events, Global Lock, etc. are not used
+ * by the compiler, so they are stubbed out here.
+ */
+void
+AcpiNsExecModuleCodeList (
+ void)
+{
+}
+
+ACPI_STATUS
+AcpiHwReadPort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 *Value,
+ UINT32 Width)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiHwWritePort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 Value,
+ UINT32 Width)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiDsMethodError (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState)
+{
+ return (Status);
+}
+
+ACPI_STATUS
+AcpiDsMethodDataGetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **DestDesc)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiDsMethodDataGetNode (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiDsStoreObjectToLocal (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *SrcDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiEvQueueNotifyRequest (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 NotifyValue)
+{
+ return (AE_OK);
+}
+
+BOOLEAN
+AcpiEvIsNotifyObject (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ return (FALSE);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+ACPI_STATUS
+AcpiEvDeleteGpeBlock (
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiEvAcquireGlobalLock (
+ UINT16 Timeout)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiEvReleaseGlobalLock (
+ void)
+{
+ return (AE_OK);
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ACPI_STATUS
+AcpiEvInitializeRegion (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsLocked)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiExReadDataFromField (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **RetBufferDesc)
+{
+ return (AE_SUPPORT);
+}
+
+ACPI_STATUS
+AcpiExWriteDataToField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc)
+{
+ return (AE_SUPPORT);
+}
+
+ACPI_STATUS
+AcpiExLoadTableOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **ReturnDesc)
+{
+ return (AE_SUPPORT);
+}
+
+ACPI_STATUS
+AcpiExUnloadTable (
+ ACPI_OPERAND_OBJECT *DdbHandle)
+{
+ return (AE_SUPPORT);
+}
+
+ACPI_STATUS
+AcpiExLoadOp (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *Target,
+ ACPI_WALK_STATE *WalkState)
+{
+ return (AE_SUPPORT);
+}
+
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index)
+{
+ return;
+}
+
+void
+AcpiExStartTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ return;
+}
+
+void
+AcpiExStopTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ return;
+}
+
+void
+AcpiExStartTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ return;
+}
+
+void
+AcpiExStopTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+
+{
+ return;
+}
+
+void
+AcpiExTracePoint (
+ ACPI_TRACE_EVENT_TYPE Type,
+ BOOLEAN Begin,
+ UINT8 *Aml,
+ char *Pathname)
+{
+ return;
+}
+
+ACPI_STATUS
+AcpiTbFindTable (
+ char *Signature,
+ char *OemId,
+ char *OemTableId,
+ UINT32 *TableIndex)
+{
+ return (AE_SUPPORT);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.l b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.l
new file mode 100644
index 0000000000..0016626e41
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.l
@@ -0,0 +1,848 @@
+/******************************************************************************
+ *
+ * Module Name: aslsupport.l - Flex/lex scanner C support routines.
+ * NOTE: Included into aslcompile.l, not compiled by itself.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/* Configuration */
+
+#define ASL_SPACES_PER_TAB 4
+
+#define ASL_NORMAL_CHAR 0
+#define ASL_ESCAPE_SEQUENCE 1
+#define ASL_OCTAL_CONSTANT 2
+#define ASL_HEX_CONSTANT 3
+
+
+/* File node - used for "Include" operator file stack */
+
+typedef struct asl_file_node
+{
+ FILE *File;
+ UINT32 CurrentLineNumber;
+ YY_BUFFER_STATE State;
+ char *Filename;
+ struct asl_file_node *Next;
+
+} ASL_FILE_NODE;
+
+/* File stack for the "Include" operator (NOT #include operator) */
+
+ASL_FILE_NODE *Gbl_IncludeFileStack = NULL;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslParserCleanup
+ *
+ * Used to delete the current buffer
+ *
+ ******************************************************************************/
+
+void
+AslParserCleanup (
+ void)
+{
+
+ yy_delete_buffer (YY_CURRENT_BUFFER);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoLineDirective
+ *
+ * PARAMETERS: None. Uses input() to access current source code line
+ *
+ * RETURN: Updates global line number and filename
+ *
+ * DESCRIPTION: Handle #line directives emitted by the preprocessor.
+ *
+ * The #line directive is emitted by the preprocesser, and is used to
+ * pass through line numbers from the original source code file to the
+ * preprocessor output file (.i). This allows any compiler-generated
+ * error messages to be displayed with the correct line number.
+ *
+ ******************************************************************************/
+
+static void
+AslDoLineDirective (
+ void)
+{
+ int c;
+ char *Token;
+ UINT32 LineNumber;
+ char *Filename;
+ UINT32 i;
+
+ Gbl_HasIncludeFiles = TRUE;
+
+ /* Eat the entire line that contains the #line directive */
+
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+
+ while ((c = input()) != '\n' && c != EOF)
+ {
+ *Gbl_LineBufPtr = c;
+ Gbl_LineBufPtr++;
+ }
+ *Gbl_LineBufPtr = 0;
+
+ /* First argument is the actual line number */
+
+ Token = strtok (Gbl_CurrentLineBuffer, " ");
+ if (!Token)
+ {
+ goto ResetAndExit;
+ }
+
+ /* First argument is the line number */
+
+ LineNumber = (UINT32) UtDoConstant (Token);
+
+ /* Emit the appropriate number of newlines */
+
+ Gbl_CurrentColumn = 0;
+ if (LineNumber > Gbl_CurrentLineNumber)
+ {
+ for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
+ {
+ FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
+ Gbl_CurrentColumn++;
+ }
+ }
+
+ FlSetLineNumber (LineNumber);
+
+ /* Second argument is the optional filename (in double quotes) */
+
+ Token = strtok (NULL, " \"");
+ if (Token)
+ {
+ Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
+ strcpy (Filename, Token);
+ FlSetFilename (Filename);
+ }
+
+ /* Third argument is not supported at this time */
+
+ResetAndExit:
+
+ /* Reset globals for a new line */
+
+ Gbl_CurrentLineOffset += Gbl_CurrentColumn;
+ Gbl_CurrentColumn = 0;
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPopInputFileStack
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: 0 if a node was popped, -1 otherwise
+ *
+ * DESCRIPTION: Pop the top of the input file stack and point the parser to
+ * the saved parse buffer contained in the fnode. Also, set the
+ * global line counters to the saved values. This function is
+ * called when an include file reaches EOF.
+ *
+ ******************************************************************************/
+
+int
+AslPopInputFileStack (
+ void)
+{
+ ASL_FILE_NODE *Fnode;
+
+
+ Fnode = Gbl_IncludeFileStack;
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nPop InputFile Stack, Fnode %p\n\n", Fnode);
+
+ if (!Fnode)
+ {
+ return (-1);
+ }
+
+ /* Close the current include file */
+
+ fclose (yyin);
+
+ /* Update the top-of-stack */
+
+ Gbl_IncludeFileStack = Fnode->Next;
+
+ /* Reset global line counter and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
+ Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
+
+ /* Point the parser to the popped file */
+
+ yy_delete_buffer (YY_CURRENT_BUFFER);
+ yy_switch_to_buffer (Fnode->State);
+
+ /* All done with this node */
+
+ ACPI_FREE (Fnode);
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPushInputFileStack
+ *
+ * PARAMETERS: InputFile - Open file pointer
+ * Filename - Name of the file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
+ * to this file. Called when an include file is successfully
+ * opened.
+ *
+ ******************************************************************************/
+
+void
+AslPushInputFileStack (
+ FILE *InputFile,
+ char *Filename)
+{
+ ASL_FILE_NODE *Fnode;
+ YY_BUFFER_STATE State;
+
+
+ /* Save the current state in an Fnode */
+
+ Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
+
+ Fnode->File = yyin;
+ Fnode->Next = Gbl_IncludeFileStack;
+ Fnode->State = YY_CURRENT_BUFFER;
+ Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
+ Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
+
+ /* Push it on the stack */
+
+ Gbl_IncludeFileStack = Fnode;
+
+ /* Point the parser to this file */
+
+ State = yy_create_buffer (InputFile, YY_BUF_SIZE);
+ yy_switch_to_buffer (State);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nPush InputFile Stack, returning %p\n\n", InputFile);
+
+ /* Reset the global line count and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename =
+ UtStringCacheCalloc (strlen (Filename) + 1);
+
+ strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
+
+ Gbl_CurrentLineNumber = 1;
+ yyin = InputFile;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslResetCurrentLineBuffer
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
+ *
+ ******************************************************************************/
+
+void
+AslResetCurrentLineBuffer (
+ void)
+{
+
+ if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
+ {
+ FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
+ Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
+ }
+
+ Gbl_CurrentLineOffset += Gbl_CurrentColumn;
+ Gbl_CurrentColumn = 0;
+
+ Gbl_CurrentLineNumber++;
+ Gbl_LogicalLineNumber++;
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslInsertLineBuffer
+ *
+ * PARAMETERS: SourceChar - One char from the input ASL source file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Put one character of the source file into the temp line buffer
+ *
+ ******************************************************************************/
+
+void
+AslInsertLineBuffer (
+ int SourceChar)
+{
+ UINT32 i;
+ UINT32 Count = 1;
+
+
+ if (SourceChar == EOF)
+ {
+ return;
+ }
+
+ Gbl_InputByteCount++;
+
+ /* Handle tabs. Convert to spaces */
+
+ if (SourceChar == '\t')
+ {
+ SourceChar = ' ';
+ Count = ASL_SPACES_PER_TAB -
+ (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
+ }
+
+ for (i = 0; i < Count; i++)
+ {
+ Gbl_CurrentColumn++;
+
+ /* Insert the character into the line buffer */
+
+ *Gbl_LineBufPtr = (UINT8) SourceChar;
+ Gbl_LineBufPtr++;
+
+ if (Gbl_LineBufPtr >
+ (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
+ {
+#if 0
+ /*
+ * Warning if we have split a long source line.
+ * <Probably overkill>
+ */
+ sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
+ AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
+#endif
+
+ AslResetCurrentLineBuffer ();
+ }
+ else if (SourceChar == '\n')
+ {
+ /* End of line */
+
+ AslResetCurrentLineBuffer ();
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: count
+ *
+ * PARAMETERS: yytext - Contains the matched keyword.
+ * Type - Keyword/Character type:
+ * 0 = anything except a keyword
+ * 1 = pseudo-keywords
+ * 2 = non-executable ASL keywords
+ * 3 = executable ASL keywords
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Count keywords and put them into the line buffer
+ *
+ ******************************************************************************/
+
+static void
+count (
+ int Type)
+{
+ int i;
+
+
+ switch (Type)
+ {
+ case 2:
+
+ TotalKeywords++;
+ TotalNamedObjects++;
+ break;
+
+ case 3:
+
+ TotalKeywords++;
+ TotalExecutableOpcodes++;
+ break;
+
+ default:
+
+ break;
+ }
+
+ for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
+ {
+ AslInsertLineBuffer (yytext[i]);
+ *Gbl_LineBufPtr = 0;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoComment
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a standard comment.
+ *
+ ******************************************************************************/
+
+static char
+AslDoComment (
+ void)
+{
+ int c;
+ int c1 = 0;
+
+
+ AslInsertLineBuffer ('/');
+ AslInsertLineBuffer ('*');
+
+loop:
+
+ /* Eat chars until end-of-comment */
+
+ while (((c = input ()) != '*') && (c != EOF))
+ {
+ AslInsertLineBuffer (c);
+ c1 = c;
+ }
+
+ if (c == EOF)
+ {
+ goto EarlyEOF;
+ }
+
+ /*
+ * Check for nested comment -- can help catch cases where a previous
+ * comment was accidently left unterminated
+ */
+ if ((c1 == '/') && (c == '*'))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+
+ /* Comment is closed only if the NEXT character is a slash */
+
+ AslInsertLineBuffer (c);
+
+ if (((c1 = input ()) != '/') && (c1 != EOF))
+ {
+ unput(c1);
+ goto loop;
+ }
+
+ if (c1 == EOF)
+ {
+ goto EarlyEOF;
+ }
+
+ AslInsertLineBuffer (c1);
+ return (TRUE);
+
+
+EarlyEOF:
+ /*
+ * Premature End-Of-File
+ */
+ AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoCommentType2
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a new "//" comment.
+ *
+ ******************************************************************************/
+
+static char
+AslDoCommentType2 (
+ void)
+{
+ int c;
+
+
+ AslInsertLineBuffer ('/');
+ AslInsertLineBuffer ('/');
+
+ while (((c = input ()) != '\n') && (c != EOF))
+ {
+ AslInsertLineBuffer (c);
+ }
+
+ if (c == EOF)
+ {
+ /* End of file is OK, change to newline. Let parser detect EOF later */
+
+ c = '\n';
+ }
+
+ AslInsertLineBuffer (c);
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoStringLiteral
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a string literal (surrounded by quotes)
+ *
+ ******************************************************************************/
+
+static char
+AslDoStringLiteral (
+ void)
+{
+ char *StringBuffer = MsgBuffer;
+ char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
+ char *CleanString;
+ int StringChar;
+ UINT32 State = ASL_NORMAL_CHAR;
+ UINT32 i = 0;
+ UINT8 Digit;
+ char ConvertBuffer[4];
+
+
+ /*
+ * Eat chars until end-of-literal.
+ * NOTE: Put back the original surrounding quotes into the
+ * source line buffer.
+ */
+ AslInsertLineBuffer ('\"');
+ while ((StringChar = input()) != EOF)
+ {
+ AslInsertLineBuffer (StringChar);
+
+DoCharacter:
+ switch (State)
+ {
+ case ASL_NORMAL_CHAR:
+
+ switch (StringChar)
+ {
+ case '\\':
+ /*
+ * Special handling for backslash-escape sequence. We will
+ * toss the backslash and translate the escape char(s).
+ */
+ State = ASL_ESCAPE_SEQUENCE;
+ continue;
+
+ case '\"':
+
+ /* String terminator */
+
+ goto CompletedString;
+
+ default:
+
+ break;
+ }
+ break;
+
+
+ case ASL_ESCAPE_SEQUENCE:
+
+ State = ASL_NORMAL_CHAR;
+ switch (StringChar)
+ {
+ case 'a':
+
+ StringChar = 0x07; /* BELL */
+ break;
+
+ case 'b':
+
+ StringChar = 0x08; /* BACKSPACE */
+ break;
+
+ case 'f':
+
+ StringChar = 0x0C; /* FORMFEED */
+ break;
+
+ case 'n':
+
+ StringChar = 0x0A; /* LINEFEED */
+ break;
+
+ case 'r':
+
+ StringChar = 0x0D; /* CARRIAGE RETURN*/
+ break;
+
+ case 't':
+
+ StringChar = 0x09; /* HORIZONTAL TAB */
+ break;
+
+ case 'v':
+
+ StringChar = 0x0B; /* VERTICAL TAB */
+ break;
+
+ case 'x':
+
+ State = ASL_HEX_CONSTANT;
+ i = 0;
+ continue;
+
+ case '\'': /* Single Quote */
+ case '\"': /* Double Quote */
+ case '\\': /* Backslash */
+
+ break;
+
+ default:
+
+ /* Check for an octal digit (0-7) */
+
+ if (ACPI_IS_OCTAL_DIGIT (StringChar))
+ {
+ State = ASL_OCTAL_CONSTANT;
+ ConvertBuffer[0] = StringChar;
+ i = 1;
+ continue;
+ }
+
+ /* Unknown escape sequence issue warning, but use the character */
+
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ break;
+ }
+ break;
+
+
+ case ASL_OCTAL_CONSTANT:
+
+ /* Up to three octal digits allowed */
+
+ if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
+ (i > 2))
+ {
+ /*
+ * Reached end of the constant. Convert the assembled ASCII
+ * string and resume processing of the next character
+ */
+ ConvertBuffer[i] = 0;
+ Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
+
+ /* Check for NULL or non-ascii character (ignore if so) */
+
+ if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+ else
+ {
+ *StringBuffer = (char) Digit;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ State = ASL_NORMAL_CHAR;
+ goto DoCharacter;
+ break;
+ }
+
+ /* Append another digit of the constant */
+
+ ConvertBuffer[i] = StringChar;
+ i++;
+ continue;
+
+ case ASL_HEX_CONSTANT:
+
+ /* Up to two hex digits allowed */
+
+ if (!isxdigit (StringChar) ||
+ (i > 1))
+ {
+ /*
+ * Reached end of the constant. Convert the assembled ASCII
+ * string and resume processing of the next character
+ */
+ ConvertBuffer[i] = 0;
+ Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
+
+ /* Check for NULL or non-ascii character (ignore if so) */
+
+ if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+ else
+ {
+ *StringBuffer = (char) Digit;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ State = ASL_NORMAL_CHAR;
+ goto DoCharacter;
+ break;
+ }
+
+ /* Append another digit of the constant */
+
+ ConvertBuffer[i] = StringChar;
+ i++;
+ continue;
+
+ default:
+
+ break;
+ }
+
+ /* Save the finished character */
+
+ *StringBuffer = StringChar;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ /*
+ * Premature End-Of-File
+ */
+ AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+
+
+CompletedString:
+ /*
+ * Null terminate the input string and copy string to a new buffer
+ */
+ *StringBuffer = 0;
+
+ CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
+ if (!CleanString)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+ }
+
+ strcpy (CleanString, MsgBuffer);
+ AslCompilerlval.s = CleanString;
+ return (TRUE);
+
+
+BufferOverflow:
+
+ /* Literal was too long */
+
+ AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
+ return (FALSE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.y
new file mode 100644
index 0000000000..ba81b7d5ac
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslsupport.y
@@ -0,0 +1,120 @@
+NoEcho('
+/******************************************************************************
+ *
+ * Module Name: aslsupport.y - Bison/Yacc C support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+')
+
+/******************************************************************************
+ *
+ * Local support functions
+ *
+ *****************************************************************************/
+
+/*! [Begin] no source code translation */
+int
+AslCompilerwrap(void)
+{
+ return (1);
+}
+/*! [End] no source code translation !*/
+
+
+void *
+AslLocalAllocate (
+ unsigned int Size)
+{
+ void *Mem;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nAslLocalAllocate: Expanding Stack to %u\n\n", Size);
+
+ Mem = ACPI_ALLOCATE_ZEROED (Size);
+ if (!Mem)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ exit (1);
+ }
+
+ return (Mem);
+}
+
+ACPI_PARSE_OBJECT *
+AslDoError (
+ void)
+{
+
+ return (TrCreateLeafNode (PARSEOP_ERRORNODE));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtGetOpName
+ *
+ * PARAMETERS: ParseOpcode - Parser keyword ID
+ *
+ * RETURN: Pointer to the opcode name
+ *
+ * DESCRIPTION: Get the ascii name of the parse opcode
+ *
+ ******************************************************************************/
+
+char *
+UtGetOpName (
+ UINT32 ParseOpcode)
+{
+#ifdef ASL_YYTNAME_START
+ /*
+ * First entries (ASL_YYTNAME_START) in yytname are special reserved names.
+ * Ignore first 8 characters of the name
+ */
+ return ((char *) yytname
+ [(ParseOpcode - ASL_FIRST_PARSE_OPCODE) + ASL_YYTNAME_START] + 8);
+#else
+ return ("[Unknown parser generator]");
+#endif
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asltokens.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltokens.y
new file mode 100644
index 0000000000..511fa9bd53
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltokens.y
@@ -0,0 +1,468 @@
+NoEcho('
+/******************************************************************************
+ *
+ * Module Name: asltokens.y - Bison/Yacc token types
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+')
+
+/******************************************************************************
+ *
+ * Token types: These are returned by the lexer
+ *
+ * NOTE: This list MUST match the AslKeywordMapping table found
+ * in aslmap.c EXACTLY! Double check any changes!
+ *
+ *****************************************************************************/
+
+%token <i> PARSEOP_ACCESSAS
+%token <i> PARSEOP_ACCESSATTRIB_BLOCK
+%token <i> PARSEOP_ACCESSATTRIB_BLOCK_CALL
+%token <i> PARSEOP_ACCESSATTRIB_BYTE
+%token <i> PARSEOP_ACCESSATTRIB_MULTIBYTE
+%token <i> PARSEOP_ACCESSATTRIB_QUICK
+%token <i> PARSEOP_ACCESSATTRIB_RAW_BYTES
+%token <i> PARSEOP_ACCESSATTRIB_RAW_PROCESS
+%token <i> PARSEOP_ACCESSATTRIB_SND_RCV
+%token <i> PARSEOP_ACCESSATTRIB_WORD
+%token <i> PARSEOP_ACCESSATTRIB_WORD_CALL
+%token <i> PARSEOP_ACCESSTYPE_ANY
+%token <i> PARSEOP_ACCESSTYPE_BUF
+%token <i> PARSEOP_ACCESSTYPE_BYTE
+%token <i> PARSEOP_ACCESSTYPE_DWORD
+%token <i> PARSEOP_ACCESSTYPE_QWORD
+%token <i> PARSEOP_ACCESSTYPE_WORD
+%token <i> PARSEOP_ACQUIRE
+%token <i> PARSEOP_ADD
+%token <i> PARSEOP_ADDRESSINGMODE_7BIT
+%token <i> PARSEOP_ADDRESSINGMODE_10BIT
+%token <i> PARSEOP_ADDRESSTYPE_ACPI
+%token <i> PARSEOP_ADDRESSTYPE_MEMORY
+%token <i> PARSEOP_ADDRESSTYPE_NVS
+%token <i> PARSEOP_ADDRESSTYPE_RESERVED
+%token <i> PARSEOP_ALIAS
+%token <i> PARSEOP_AND
+%token <i> PARSEOP_ARG0
+%token <i> PARSEOP_ARG1
+%token <i> PARSEOP_ARG2
+%token <i> PARSEOP_ARG3
+%token <i> PARSEOP_ARG4
+%token <i> PARSEOP_ARG5
+%token <i> PARSEOP_ARG6
+%token <i> PARSEOP_BANKFIELD
+%token <i> PARSEOP_BITSPERBYTE_EIGHT
+%token <i> PARSEOP_BITSPERBYTE_FIVE
+%token <i> PARSEOP_BITSPERBYTE_NINE
+%token <i> PARSEOP_BITSPERBYTE_SEVEN
+%token <i> PARSEOP_BITSPERBYTE_SIX
+%token <i> PARSEOP_BREAK
+%token <i> PARSEOP_BREAKPOINT
+%token <i> PARSEOP_BUFFER
+%token <i> PARSEOP_BUSMASTERTYPE_MASTER
+%token <i> PARSEOP_BUSMASTERTYPE_NOTMASTER
+%token <i> PARSEOP_BYTECONST
+%token <i> PARSEOP_CASE
+%token <i> PARSEOP_CLOCKPHASE_FIRST
+%token <i> PARSEOP_CLOCKPHASE_SECOND
+%token <i> PARSEOP_CLOCKPOLARITY_HIGH
+%token <i> PARSEOP_CLOCKPOLARITY_LOW
+%token <i> PARSEOP_CONCATENATE
+%token <i> PARSEOP_CONCATENATERESTEMPLATE
+%token <i> PARSEOP_CONDREFOF
+%token <i> PARSEOP_CONNECTION
+%token <i> PARSEOP_CONTINUE
+%token <i> PARSEOP_COPYOBJECT
+%token <i> PARSEOP_CREATEBITFIELD
+%token <i> PARSEOP_CREATEBYTEFIELD
+%token <i> PARSEOP_CREATEDWORDFIELD
+%token <i> PARSEOP_CREATEFIELD
+%token <i> PARSEOP_CREATEQWORDFIELD
+%token <i> PARSEOP_CREATEWORDFIELD
+%token <i> PARSEOP_DATABUFFER
+%token <i> PARSEOP_DATATABLEREGION
+%token <i> PARSEOP_DEBUG
+%token <i> PARSEOP_DECODETYPE_POS
+%token <i> PARSEOP_DECODETYPE_SUB
+%token <i> PARSEOP_DECREMENT
+%token <i> PARSEOP_DEFAULT
+%token <i> PARSEOP_DEFAULT_ARG
+%token <i> PARSEOP_DEFINITIONBLOCK
+%token <i> PARSEOP_DEREFOF
+%token <i> PARSEOP_DEVICE
+%token <i> PARSEOP_DEVICEPOLARITY_HIGH
+%token <i> PARSEOP_DEVICEPOLARITY_LOW
+%token <i> PARSEOP_DIVIDE
+%token <i> PARSEOP_DMA
+%token <i> PARSEOP_DMATYPE_A
+%token <i> PARSEOP_DMATYPE_COMPATIBILITY
+%token <i> PARSEOP_DMATYPE_B
+%token <i> PARSEOP_DMATYPE_F
+%token <i> PARSEOP_DWORDCONST
+%token <i> PARSEOP_DWORDIO
+%token <i> PARSEOP_DWORDMEMORY
+%token <i> PARSEOP_DWORDSPACE
+%token <i> PARSEOP_EISAID
+%token <i> PARSEOP_ELSE
+%token <i> PARSEOP_ELSEIF
+%token <i> PARSEOP_ENDDEPENDENTFN
+%token <i> PARSEOP_ENDIAN_BIG
+%token <i> PARSEOP_ENDIAN_LITTLE
+%token <i> PARSEOP_ENDTAG
+%token <i> PARSEOP_ERRORNODE
+%token <i> PARSEOP_EVENT
+%token <i> PARSEOP_EXTENDEDIO
+%token <i> PARSEOP_EXTENDEDMEMORY
+%token <i> PARSEOP_EXTENDEDSPACE
+%token <i> PARSEOP_EXTERNAL
+%token <i> PARSEOP_FATAL
+%token <i> PARSEOP_FIELD
+%token <i> PARSEOP_FINDSETLEFTBIT
+%token <i> PARSEOP_FINDSETRIGHTBIT
+%token <i> PARSEOP_FIXEDDMA
+%token <i> PARSEOP_FIXEDIO
+%token <i> PARSEOP_FLOWCONTROL_HW
+%token <i> PARSEOP_FLOWCONTROL_NONE
+%token <i> PARSEOP_FLOWCONTROL_SW
+%token <i> PARSEOP_FROMBCD
+%token <i> PARSEOP_FUNCTION
+%token <i> PARSEOP_GPIO_INT
+%token <i> PARSEOP_GPIO_IO
+%token <i> PARSEOP_I2C_SERIALBUS
+%token <i> PARSEOP_IF
+%token <i> PARSEOP_INCLUDE
+%token <i> PARSEOP_INCLUDE_END
+%token <i> PARSEOP_INCREMENT
+%token <i> PARSEOP_INDEX
+%token <i> PARSEOP_INDEXFIELD
+%token <i> PARSEOP_INTEGER
+%token <i> PARSEOP_INTERRUPT
+%token <i> PARSEOP_INTLEVEL_ACTIVEBOTH
+%token <i> PARSEOP_INTLEVEL_ACTIVEHIGH
+%token <i> PARSEOP_INTLEVEL_ACTIVELOW
+%token <i> PARSEOP_INTTYPE_EDGE
+%token <i> PARSEOP_INTTYPE_LEVEL
+%token <i> PARSEOP_IO
+%token <i> PARSEOP_IODECODETYPE_10
+%token <i> PARSEOP_IODECODETYPE_16
+%token <i> PARSEOP_IORESTRICT_IN
+%token <i> PARSEOP_IORESTRICT_NONE
+%token <i> PARSEOP_IORESTRICT_OUT
+%token <i> PARSEOP_IORESTRICT_PRESERVE
+%token <i> PARSEOP_IRQ
+%token <i> PARSEOP_IRQNOFLAGS
+%token <i> PARSEOP_LAND
+%token <i> PARSEOP_LEQUAL
+%token <i> PARSEOP_LGREATER
+%token <i> PARSEOP_LGREATEREQUAL
+%token <i> PARSEOP_LLESS
+%token <i> PARSEOP_LLESSEQUAL
+%token <i> PARSEOP_LNOT
+%token <i> PARSEOP_LNOTEQUAL
+%token <i> PARSEOP_LOAD
+%token <i> PARSEOP_LOADTABLE
+%token <i> PARSEOP_LOCAL0
+%token <i> PARSEOP_LOCAL1
+%token <i> PARSEOP_LOCAL2
+%token <i> PARSEOP_LOCAL3
+%token <i> PARSEOP_LOCAL4
+%token <i> PARSEOP_LOCAL5
+%token <i> PARSEOP_LOCAL6
+%token <i> PARSEOP_LOCAL7
+%token <i> PARSEOP_LOCKRULE_LOCK
+%token <i> PARSEOP_LOCKRULE_NOLOCK
+%token <i> PARSEOP_LOR
+%token <i> PARSEOP_MATCH
+%token <i> PARSEOP_MATCHTYPE_MEQ
+%token <i> PARSEOP_MATCHTYPE_MGE
+%token <i> PARSEOP_MATCHTYPE_MGT
+%token <i> PARSEOP_MATCHTYPE_MLE
+%token <i> PARSEOP_MATCHTYPE_MLT
+%token <i> PARSEOP_MATCHTYPE_MTR
+%token <i> PARSEOP_MAXTYPE_FIXED
+%token <i> PARSEOP_MAXTYPE_NOTFIXED
+%token <i> PARSEOP_MEMORY24
+%token <i> PARSEOP_MEMORY32
+%token <i> PARSEOP_MEMORY32FIXED
+%token <i> PARSEOP_MEMTYPE_CACHEABLE
+%token <i> PARSEOP_MEMTYPE_NONCACHEABLE
+%token <i> PARSEOP_MEMTYPE_PREFETCHABLE
+%token <i> PARSEOP_MEMTYPE_WRITECOMBINING
+%token <i> PARSEOP_METHOD
+%token <i> PARSEOP_METHODCALL
+%token <i> PARSEOP_MID
+%token <i> PARSEOP_MINTYPE_FIXED
+%token <i> PARSEOP_MINTYPE_NOTFIXED
+%token <i> PARSEOP_MOD
+%token <i> PARSEOP_MULTIPLY
+%token <i> PARSEOP_MUTEX
+%token <i> PARSEOP_NAME
+%token <s> PARSEOP_NAMESEG
+%token <s> PARSEOP_NAMESTRING
+%token <i> PARSEOP_NAND
+%token <i> PARSEOP_NOOP
+%token <i> PARSEOP_NOR
+%token <i> PARSEOP_NOT
+%token <i> PARSEOP_NOTIFY
+%token <i> PARSEOP_OBJECTTYPE
+%token <i> PARSEOP_OBJECTTYPE_BFF
+%token <i> PARSEOP_OBJECTTYPE_BUF
+%token <i> PARSEOP_OBJECTTYPE_DDB
+%token <i> PARSEOP_OBJECTTYPE_DEV
+%token <i> PARSEOP_OBJECTTYPE_EVT
+%token <i> PARSEOP_OBJECTTYPE_FLD
+%token <i> PARSEOP_OBJECTTYPE_INT
+%token <i> PARSEOP_OBJECTTYPE_MTH
+%token <i> PARSEOP_OBJECTTYPE_MTX
+%token <i> PARSEOP_OBJECTTYPE_OPR
+%token <i> PARSEOP_OBJECTTYPE_PKG
+%token <i> PARSEOP_OBJECTTYPE_POW
+%token <i> PARSEOP_OBJECTTYPE_PRO
+%token <i> PARSEOP_OBJECTTYPE_STR
+%token <i> PARSEOP_OBJECTTYPE_THZ
+%token <i> PARSEOP_OBJECTTYPE_UNK
+%token <i> PARSEOP_OFFSET
+%token <i> PARSEOP_ONE
+%token <i> PARSEOP_ONES
+%token <i> PARSEOP_OPERATIONREGION
+%token <i> PARSEOP_OR
+%token <i> PARSEOP_PACKAGE
+%token <i> PARSEOP_PACKAGE_LENGTH
+%token <i> PARSEOP_PARITYTYPE_EVEN
+%token <i> PARSEOP_PARITYTYPE_MARK
+%token <i> PARSEOP_PARITYTYPE_NONE
+%token <i> PARSEOP_PARITYTYPE_ODD
+%token <i> PARSEOP_PARITYTYPE_SPACE
+%token <i> PARSEOP_PIN_NOPULL
+%token <i> PARSEOP_PIN_PULLDEFAULT
+%token <i> PARSEOP_PIN_PULLDOWN
+%token <i> PARSEOP_PIN_PULLUP
+%token <i> PARSEOP_POWERRESOURCE
+%token <i> PARSEOP_PROCESSOR
+%token <i> PARSEOP_QWORDCONST
+%token <i> PARSEOP_QWORDIO
+%token <i> PARSEOP_QWORDMEMORY
+%token <i> PARSEOP_QWORDSPACE
+%token <i> PARSEOP_RANGETYPE_ENTIRE
+%token <i> PARSEOP_RANGETYPE_ISAONLY
+%token <i> PARSEOP_RANGETYPE_NONISAONLY
+%token <i> PARSEOP_RAW_DATA
+%token <i> PARSEOP_READWRITETYPE_BOTH
+%token <i> PARSEOP_READWRITETYPE_READONLY
+%token <i> PARSEOP_REFOF
+%token <i> PARSEOP_REGIONSPACE_CMOS
+%token <i> PARSEOP_REGIONSPACE_EC
+%token <i> PARSEOP_REGIONSPACE_FFIXEDHW
+%token <i> PARSEOP_REGIONSPACE_GPIO
+%token <i> PARSEOP_REGIONSPACE_GSBUS
+%token <i> PARSEOP_REGIONSPACE_IO
+%token <i> PARSEOP_REGIONSPACE_IPMI
+%token <i> PARSEOP_REGIONSPACE_MEM
+%token <i> PARSEOP_REGIONSPACE_PCC
+%token <i> PARSEOP_REGIONSPACE_PCI
+%token <i> PARSEOP_REGIONSPACE_PCIBAR
+%token <i> PARSEOP_REGIONSPACE_SMBUS
+%token <i> PARSEOP_REGISTER
+%token <i> PARSEOP_RELEASE
+%token <i> PARSEOP_RESERVED_BYTES
+%token <i> PARSEOP_RESET
+%token <i> PARSEOP_RESOURCETEMPLATE
+%token <i> PARSEOP_RESOURCETYPE_CONSUMER
+%token <i> PARSEOP_RESOURCETYPE_PRODUCER
+%token <i> PARSEOP_RETURN
+%token <i> PARSEOP_REVISION
+%token <i> PARSEOP_SCOPE
+%token <i> PARSEOP_SERIALIZERULE_NOTSERIAL
+%token <i> PARSEOP_SERIALIZERULE_SERIAL
+%token <i> PARSEOP_SHARETYPE_EXCLUSIVE
+%token <i> PARSEOP_SHARETYPE_EXCLUSIVEWAKE
+%token <i> PARSEOP_SHARETYPE_SHARED
+%token <i> PARSEOP_SHARETYPE_SHAREDWAKE
+%token <i> PARSEOP_SHIFTLEFT
+%token <i> PARSEOP_SHIFTRIGHT
+%token <i> PARSEOP_SIGNAL
+%token <i> PARSEOP_SIZEOF
+%token <i> PARSEOP_SLAVEMODE_CONTROLLERINIT
+%token <i> PARSEOP_SLAVEMODE_DEVICEINIT
+%token <i> PARSEOP_SLEEP
+%token <i> PARSEOP_SPI_SERIALBUS
+%token <i> PARSEOP_STALL
+%token <i> PARSEOP_STARTDEPENDENTFN
+%token <i> PARSEOP_STARTDEPENDENTFN_NOPRI
+%token <i> PARSEOP_STOPBITS_ONE
+%token <i> PARSEOP_STOPBITS_ONEPLUSHALF
+%token <i> PARSEOP_STOPBITS_TWO
+%token <i> PARSEOP_STOPBITS_ZERO
+%token <i> PARSEOP_STORE
+%token <s> PARSEOP_STRING_LITERAL
+%token <i> PARSEOP_SUBTRACT
+%token <i> PARSEOP_SWITCH
+%token <i> PARSEOP_THERMALZONE
+%token <i> PARSEOP_TIMER
+%token <i> PARSEOP_TOBCD
+%token <i> PARSEOP_TOBUFFER
+%token <i> PARSEOP_TODECIMALSTRING
+%token <i> PARSEOP_TOHEXSTRING
+%token <i> PARSEOP_TOINTEGER
+%token <i> PARSEOP_TOSTRING
+%token <i> PARSEOP_TOUUID
+%token <i> PARSEOP_TRANSLATIONTYPE_DENSE
+%token <i> PARSEOP_TRANSLATIONTYPE_SPARSE
+%token <i> PARSEOP_TYPE_STATIC
+%token <i> PARSEOP_TYPE_TRANSLATION
+%token <i> PARSEOP_UART_SERIALBUS
+%token <i> PARSEOP_UNICODE
+%token <i> PARSEOP_UNLOAD
+%token <i> PARSEOP_UPDATERULE_ONES
+%token <i> PARSEOP_UPDATERULE_PRESERVE
+%token <i> PARSEOP_UPDATERULE_ZEROS
+%token <i> PARSEOP_VAR_PACKAGE
+%token <i> PARSEOP_VENDORLONG
+%token <i> PARSEOP_VENDORSHORT
+%token <i> PARSEOP_WAIT
+%token <i> PARSEOP_WHILE
+%token <i> PARSEOP_WIREMODE_FOUR
+%token <i> PARSEOP_WIREMODE_THREE
+%token <i> PARSEOP_WORDBUSNUMBER
+%token <i> PARSEOP_WORDCONST
+%token <i> PARSEOP_WORDIO
+%token <i> PARSEOP_WORDSPACE
+%token <i> PARSEOP_XFERSIZE_8
+%token <i> PARSEOP_XFERSIZE_16
+%token <i> PARSEOP_XFERSIZE_32
+%token <i> PARSEOP_XFERSIZE_64
+%token <i> PARSEOP_XFERSIZE_128
+%token <i> PARSEOP_XFERSIZE_256
+%token <i> PARSEOP_XFERTYPE_8
+%token <i> PARSEOP_XFERTYPE_8_16
+%token <i> PARSEOP_XFERTYPE_16
+%token <i> PARSEOP_XOR
+%token <i> PARSEOP_ZERO
+
+/* ToPld macro */
+
+%token <i> PARSEOP_TOPLD
+%token <i> PARSEOP_PLD_REVISION
+%token <i> PARSEOP_PLD_IGNORECOLOR
+%token <i> PARSEOP_PLD_RED
+%token <i> PARSEOP_PLD_GREEN
+%token <i> PARSEOP_PLD_BLUE
+%token <i> PARSEOP_PLD_WIDTH
+%token <i> PARSEOP_PLD_HEIGHT
+%token <i> PARSEOP_PLD_USERVISIBLE
+%token <i> PARSEOP_PLD_DOCK
+%token <i> PARSEOP_PLD_LID
+%token <i> PARSEOP_PLD_PANEL
+%token <i> PARSEOP_PLD_VERTICALPOSITION
+%token <i> PARSEOP_PLD_HORIZONTALPOSITION
+%token <i> PARSEOP_PLD_SHAPE
+%token <i> PARSEOP_PLD_GROUPORIENTATION
+%token <i> PARSEOP_PLD_GROUPTOKEN
+%token <i> PARSEOP_PLD_GROUPPOSITION
+%token <i> PARSEOP_PLD_BAY
+%token <i> PARSEOP_PLD_EJECTABLE
+%token <i> PARSEOP_PLD_EJECTREQUIRED
+%token <i> PARSEOP_PLD_CABINETNUMBER
+%token <i> PARSEOP_PLD_CARDCAGENUMBER
+%token <i> PARSEOP_PLD_REFERENCE
+%token <i> PARSEOP_PLD_ROTATION
+%token <i> PARSEOP_PLD_ORDER
+%token <i> PARSEOP_PLD_RESERVED
+%token <i> PARSEOP_PLD_VERTICALOFFSET
+%token <i> PARSEOP_PLD_HORIZONTALOFFSET
+
+/*
+ * C-style expression parser. These must appear after all of the
+ * standard ASL operators and keywords.
+ *
+ * Note: The order of these tokens implements the precedence rules
+ * (low precedence to high). See aslrules.y for an exhaustive list.
+ */
+%right <i> PARSEOP_EXP_EQUALS
+ PARSEOP_EXP_ADD_EQ
+ PARSEOP_EXP_SUB_EQ
+ PARSEOP_EXP_MUL_EQ
+ PARSEOP_EXP_DIV_EQ
+ PARSEOP_EXP_MOD_EQ
+ PARSEOP_EXP_SHL_EQ
+ PARSEOP_EXP_SHR_EQ
+ PARSEOP_EXP_AND_EQ
+ PARSEOP_EXP_XOR_EQ
+ PARSEOP_EXP_OR_EQ
+
+%left <i> PARSEOP_EXP_LOGICAL_OR
+%left <i> PARSEOP_EXP_LOGICAL_AND
+%left <i> PARSEOP_EXP_OR
+%left <i> PARSEOP_EXP_XOR
+%left <i> PARSEOP_EXP_AND
+%left <i> PARSEOP_EXP_EQUAL
+ PARSEOP_EXP_NOT_EQUAL
+%left <i> PARSEOP_EXP_GREATER
+ PARSEOP_EXP_LESS
+ PARSEOP_EXP_GREATER_EQUAL
+ PARSEOP_EXP_LESS_EQUAL
+%left <i> PARSEOP_EXP_SHIFT_RIGHT
+ PARSEOP_EXP_SHIFT_LEFT
+%left <i> PARSEOP_EXP_ADD
+ PARSEOP_EXP_SUBTRACT
+%left <i> PARSEOP_EXP_MULTIPLY
+ PARSEOP_EXP_DIVIDE
+ PARSEOP_EXP_MODULO
+
+%right <i> PARSEOP_EXP_NOT
+ PARSEOP_EXP_LOGICAL_NOT
+
+%left <i> PARSEOP_EXP_INCREMENT
+ PARSEOP_EXP_DECREMENT
+
+%token <i> PARSEOP_PRINTF
+%token <i> PARSEOP_FPRINTF
+/* Specific parentheses tokens are not used at this time */
+ /* PARSEOP_EXP_PAREN_OPEN */
+ /* PARSEOP_EXP_PAREN_CLOSE */
+
+/*
+ * Special functions. These should probably stay at the end of this
+ * table.
+ */
+%token <i> PARSEOP___DATE__
+%token <i> PARSEOP___FILE__
+%token <i> PARSEOP___LINE__
+%token <i> PARSEOP___PATH__
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asltransform.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltransform.c
new file mode 100644
index 0000000000..c46801b929
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltransform.c
@@ -0,0 +1,775 @@
+/******************************************************************************
+ *
+ * Module Name: asltransform - Parse tree transforms
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asltransform")
+
+/* Local prototypes */
+
+static void
+TrTransformSubtree (
+ ACPI_PARSE_OBJECT *Op);
+
+static char *
+TrAmlGetNextTempName (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *TempCount);
+
+static void
+TrAmlInitLineNumbers (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Neighbor);
+
+static void
+TrAmlInitNode (
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 ParseOpcode);
+
+static void
+TrAmlSetSubtreeParent (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Parent);
+
+static void
+TrAmlInsertPeer (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *NewPeer);
+
+static void
+TrDoDefinitionBlock (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+TrDoSwitch (
+ ACPI_PARSE_OBJECT *StartNode);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlGetNextTempName
+ *
+ * PARAMETERS: Op - Current parse op
+ * TempCount - Current temporary counter. Was originally
+ * per-module; Currently per method, could be
+ * expanded to per-scope.
+ *
+ * RETURN: A pointer to name (allocated here).
+ *
+ * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are
+ * reserved for use by the ASL compiler. (_T_0 through _T_Z)
+ *
+ ******************************************************************************/
+
+static char *
+TrAmlGetNextTempName (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *TempCount)
+{
+ char *TempName;
+
+
+ if (*TempCount >= (10+26)) /* 0-35 valid: 0-9 and A-Z for TempName[3] */
+ {
+ /* Too many temps */
+
+ AslError (ASL_ERROR, ASL_MSG_TOO_MANY_TEMPS, Op, NULL);
+ return (NULL);
+ }
+
+ TempName = UtLocalCalloc (5);
+
+ if (*TempCount < 10) /* 0-9 */
+ {
+ TempName[3] = (char) (*TempCount + '0');
+ }
+ else /* 10-35: A-Z */
+ {
+ TempName[3] = (char) (*TempCount + ('A' - 10));
+ }
+ (*TempCount)++;
+
+ /* First three characters are always "_T_" */
+
+ TempName[0] = '_';
+ TempName[1] = 'T';
+ TempName[2] = '_';
+
+ return (TempName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlInitLineNumbers
+ *
+ * PARAMETERS: Op - Op to be initialized
+ * Neighbor - Op used for initialization values
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialized the various line numbers for a parse node.
+ *
+ ******************************************************************************/
+
+static void
+TrAmlInitLineNumbers (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Neighbor)
+{
+
+ Op->Asl.EndLine = Neighbor->Asl.EndLine;
+ Op->Asl.EndLogicalLine = Neighbor->Asl.EndLogicalLine;
+ Op->Asl.LineNumber = Neighbor->Asl.LineNumber;
+ Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset;
+ Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlInitNode
+ *
+ * PARAMETERS: Op - Op to be initialized
+ * ParseOpcode - Opcode for this node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a node with the parse opcode and opcode name.
+ *
+ ******************************************************************************/
+
+static void
+TrAmlInitNode (
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 ParseOpcode)
+{
+
+ Op->Asl.ParseOpcode = ParseOpcode;
+ UtSetParseOpName (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlSetSubtreeParent
+ *
+ * PARAMETERS: Op - First node in a list of peer nodes
+ * Parent - Parent of the subtree
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the parent for all peer nodes in a subtree
+ *
+ ******************************************************************************/
+
+static void
+TrAmlSetSubtreeParent (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Parent)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ Next = Op;
+ while (Next)
+ {
+ Next->Asl.Parent = Parent;
+ Next = Next->Asl.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlInsertPeer
+ *
+ * PARAMETERS: Op - First node in a list of peer nodes
+ * NewPeer - Peer node to insert
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a new peer node into a list of peers.
+ *
+ ******************************************************************************/
+
+static void
+TrAmlInsertPeer (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *NewPeer)
+{
+
+ NewPeer->Asl.Next = Op->Asl.Next;
+ Op->Asl.Next = NewPeer;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAmlTransformWalk
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
+ * operands.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+TrAmlTransformWalk (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+
+ TrTransformSubtree (Op);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrTransformSubtree
+ *
+ * PARAMETERS: Op - The parent parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
+ * complex AML opcodes require processing of the child nodes
+ * (arguments/operands).
+ *
+ ******************************************************************************/
+
+static void
+TrTransformSubtree (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
+ {
+ return;
+ }
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ TrDoDefinitionBlock (Op);
+ break;
+
+ case PARSEOP_SWITCH:
+
+ TrDoSwitch (Op);
+ break;
+
+ case PARSEOP_METHOD:
+ /*
+ * TBD: Zero the tempname (_T_x) count. Probably shouldn't be a global,
+ * however
+ */
+ Gbl_TempCount = 0;
+ break;
+
+ default:
+
+ /* Nothing to do here for other opcodes */
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrDoDefinitionBlock
+ *
+ * PARAMETERS: Op - Parse node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Find the end of the definition block and set a global to this
+ * node. It is used by the compiler to insert compiler-generated
+ * names at the root level of the namespace.
+ *
+ ******************************************************************************/
+
+static void
+TrDoDefinitionBlock (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ UINT32 i;
+
+
+ Next = Op->Asl.Child;
+ for (i = 0; i < 5; i++)
+ {
+ Next = Next->Asl.Next;
+ if (i == 0)
+ {
+ /*
+ * This is the table signature. Only the DSDT can be assumed
+ * to be at the root of the namespace; Therefore, namepath
+ * optimization can only be performed on the DSDT.
+ */
+ if (!ACPI_COMPARE_NAME (Next->Asl.Value.String, ACPI_SIG_DSDT))
+ {
+ Gbl_ReferenceOptimizationFlag = FALSE;
+ }
+ }
+ }
+
+ Gbl_FirstLevelInsertionNode = Next;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrDoSwitch
+ *
+ * PARAMETERS: StartNode - Parse node for SWITCH
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is
+ * no actual AML opcode for SWITCH -- it must be simulated.
+ *
+ ******************************************************************************/
+
+static void
+TrDoSwitch (
+ ACPI_PARSE_OBJECT *StartNode)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_PARSE_OBJECT *CaseOp = NULL;
+ ACPI_PARSE_OBJECT *CaseBlock = NULL;
+ ACPI_PARSE_OBJECT *DefaultOp = NULL;
+ ACPI_PARSE_OBJECT *CurrentParentNode;
+ ACPI_PARSE_OBJECT *Conditional = NULL;
+ ACPI_PARSE_OBJECT *Predicate;
+ ACPI_PARSE_OBJECT *Peer;
+ ACPI_PARSE_OBJECT *NewOp;
+ ACPI_PARSE_OBJECT *NewOp2;
+ ACPI_PARSE_OBJECT *MethodOp;
+ ACPI_PARSE_OBJECT *StoreOp;
+ ACPI_PARSE_OBJECT *BreakOp;
+ ACPI_PARSE_OBJECT *BufferOp;
+ char *PredicateValueName;
+ UINT16 Index;
+ UINT32 Btype;
+
+
+ /* Start node is the Switch() node */
+
+ CurrentParentNode = StartNode;
+
+ /* Create a new temp name of the form _T_x */
+
+ PredicateValueName = TrAmlGetNextTempName (StartNode, &Gbl_TempCount);
+ if (!PredicateValueName)
+ {
+ return;
+ }
+
+ /* First child is the Switch() predicate */
+
+ Next = StartNode->Asl.Child;
+
+ /*
+ * Examine the return type of the Switch Value -
+ * must be Integer/Buffer/String
+ */
+ Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
+ Btype = AslKeywordMapping[Index].AcpiBtype;
+ if ((Btype != ACPI_BTYPE_INTEGER) &&
+ (Btype != ACPI_BTYPE_STRING) &&
+ (Btype != ACPI_BTYPE_BUFFER))
+ {
+ AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);
+ Btype = ACPI_BTYPE_INTEGER;
+ }
+
+ /* CASE statements start at next child */
+
+ Peer = Next->Asl.Next;
+ while (Peer)
+ {
+ Next = Peer;
+ Peer = Next->Asl.Next;
+
+ if (Next->Asl.ParseOpcode == PARSEOP_CASE)
+ {
+ if (CaseOp)
+ {
+ /* Add an ELSE to complete the previous CASE */
+
+ NewOp = TrCreateLeafNode (PARSEOP_ELSE);
+ NewOp->Asl.Parent = Conditional->Asl.Parent;
+ TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);
+
+ /* Link ELSE node as a peer to the previous IF */
+
+ TrAmlInsertPeer (Conditional, NewOp);
+ CurrentParentNode = NewOp;
+ }
+
+ CaseOp = Next;
+ Conditional = CaseOp;
+ CaseBlock = CaseOp->Asl.Child->Asl.Next;
+ Conditional->Asl.Child->Asl.Next = NULL;
+ Predicate = CaseOp->Asl.Child;
+
+ if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
+ (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
+ {
+ /*
+ * Convert the package declaration to this form:
+ *
+ * If (LNotEqual (Match (Package(<size>){<data>},
+ * MEQ, _T_x, MTR, Zero, Zero), Ones))
+ */
+ NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MEQ);
+ Predicate->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,
+ (UINT64) ACPI_TO_INTEGER (PredicateValueName));
+ NewOp->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Predicate);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MTR);
+ NewOp->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Predicate);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateLeafNode (PARSEOP_ZERO);
+ NewOp->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Predicate);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateLeafNode (PARSEOP_ZERO);
+ NewOp->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Predicate);
+
+ NewOp2 = TrCreateLeafNode (PARSEOP_MATCH);
+ NewOp2->Asl.Child = Predicate; /* PARSEOP_PACKAGE */
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+ TrAmlSetSubtreeParent (Predicate, NewOp2);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateLeafNode (PARSEOP_ONES);
+ NewOp->Asl.Next = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+
+ NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL);
+ NewOp2->Asl.Child = NewOp;
+ NewOp->Asl.Parent = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+ TrAmlSetSubtreeParent (NewOp, NewOp2);
+
+ NewOp = NewOp2;
+ NewOp2 = TrCreateLeafNode (PARSEOP_LNOT);
+ NewOp2->Asl.Child = NewOp;
+ NewOp2->Asl.Parent = Conditional;
+ NewOp->Asl.Parent = NewOp2;
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+
+ Conditional->Asl.Child = NewOp2;
+ NewOp2->Asl.Next = CaseBlock;
+ }
+ else
+ {
+ /*
+ * Integer and Buffer case.
+ *
+ * Change CaseOp() to: If (LEqual (SwitchValue, CaseValue)) {...}
+ * Note: SwitchValue is first to allow the CaseValue to be implicitly
+ * converted to the type of SwitchValue if necessary.
+ *
+ * CaseOp->Child is the case value
+ * CaseOp->Child->Peer is the beginning of the case block
+ */
+ NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,
+ (UINT64) ACPI_TO_INTEGER (PredicateValueName));
+ NewOp->Asl.Next = Predicate;
+ TrAmlInitLineNumbers (NewOp, Predicate);
+
+ NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL);
+ NewOp2->Asl.Parent = Conditional;
+ NewOp2->Asl.Child = NewOp;
+ TrAmlInitLineNumbers (NewOp2, Conditional);
+
+ TrAmlSetSubtreeParent (NewOp, NewOp2);
+
+ Predicate = NewOp2;
+ Predicate->Asl.Next = CaseBlock;
+
+ TrAmlSetSubtreeParent (Predicate, Conditional);
+ Conditional->Asl.Child = Predicate;
+ }
+
+ /* Reinitialize the CASE node to an IF node */
+
+ TrAmlInitNode (Conditional, PARSEOP_IF);
+
+ /*
+ * The first CASE(IF) is not nested under an ELSE.
+ * All other CASEs are children of a parent ELSE.
+ */
+ if (CurrentParentNode == StartNode)
+ {
+ Conditional->Asl.Next = NULL;
+ }
+ else
+ {
+ /*
+ * The IF is a child of previous IF/ELSE. It
+ * is therefore without peer.
+ */
+ CurrentParentNode->Asl.Child = Conditional;
+ Conditional->Asl.Parent = CurrentParentNode;
+ Conditional->Asl.Next = NULL;
+ }
+ }
+ else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)
+ {
+ if (DefaultOp)
+ {
+ /*
+ * More than one Default
+ * (Parser does not catch this, must check here)
+ */
+ AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);
+ }
+ else
+ {
+ /* Save the DEFAULT node for later, after CASEs */
+
+ DefaultOp = Next;
+ }
+ }
+ else
+ {
+ /* Unknown peer opcode */
+
+ AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%u)\n",
+ Next->Asl.ParseOpName, Next->Asl.ParseOpcode);
+ }
+ }
+
+ /* Add the default case at the end of the if/else construct */
+
+ if (DefaultOp)
+ {
+ /* If no CASE statements, this is an error - see below */
+
+ if (CaseOp)
+ {
+ /* Convert the DEFAULT node to an ELSE */
+
+ TrAmlInitNode (DefaultOp, PARSEOP_ELSE);
+ DefaultOp->Asl.Parent = Conditional->Asl.Parent;
+
+ /* Link ELSE node as a peer to the previous IF */
+
+ TrAmlInsertPeer (Conditional, DefaultOp);
+ }
+ }
+
+ if (!CaseOp)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);
+ }
+
+
+ /*
+ * Create a Name(_T_x, ...) statement. This statement must appear at the
+ * method level, in case a loop surrounds the switch statement and could
+ * cause the name to be created twice (error).
+ */
+
+ /* Create the Name node */
+
+ Predicate = StartNode->Asl.Child;
+ NewOp = TrCreateLeafNode (PARSEOP_NAME);
+ TrAmlInitLineNumbers (NewOp, StartNode);
+
+ /* Find the parent method */
+
+ Next = StartNode;
+ while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&
+ (Next->Asl.ParseOpcode != PARSEOP_DEFINITIONBLOCK))
+ {
+ Next = Next->Asl.Parent;
+ }
+ MethodOp = Next;
+
+ NewOp->Asl.CompileFlags |= NODE_COMPILER_EMITTED;
+ NewOp->Asl.Parent = Next;
+
+ /* Insert name after the method name and arguments */
+
+ Next = Next->Asl.Child; /* Name */
+ Next = Next->Asl.Next; /* NumArgs */
+ Next = Next->Asl.Next; /* SerializeRule */
+
+ /*
+ * If method is not Serialized, we must make is so, because of the way
+ * that Switch() must be implemented -- we cannot allow multiple threads
+ * to execute this method concurrently since we need to create local
+ * temporary name(s).
+ */
+ if (Next->Asl.ParseOpcode != PARSEOP_SERIALIZERULE_SERIAL)
+ {
+ AslError (ASL_REMARK, ASL_MSG_SERIALIZED, MethodOp, "Due to use of Switch operator");
+ Next->Asl.ParseOpcode = PARSEOP_SERIALIZERULE_SERIAL;
+ }
+
+ Next = Next->Asl.Next; /* SyncLevel */
+ Next = Next->Asl.Next; /* ReturnType */
+ Next = Next->Asl.Next; /* ParameterTypes */
+
+ TrAmlInsertPeer (Next, NewOp);
+ TrAmlInitLineNumbers (NewOp, Next);
+
+ /* Create the NameSeg child for the Name node */
+
+ NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESEG,
+ (UINT64) ACPI_TO_INTEGER (PredicateValueName));
+ TrAmlInitLineNumbers (NewOp2, NewOp);
+ NewOp2->Asl.CompileFlags |= NODE_IS_NAME_DECLARATION;
+ NewOp->Asl.Child = NewOp2;
+
+ /* Create the initial value for the Name. Btype was already validated above */
+
+ switch (Btype)
+ {
+ case ACPI_BTYPE_INTEGER:
+
+ NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_ZERO,
+ (UINT64) 0);
+ TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
+ break;
+
+ case ACPI_BTYPE_STRING:
+
+ NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL,
+ (UINT64) ACPI_TO_INTEGER (""));
+ TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
+ break;
+
+ case ACPI_BTYPE_BUFFER:
+
+ (void) TrLinkPeerNode (NewOp2, TrCreateValuedLeafNode (PARSEOP_BUFFER,
+ (UINT64) 0));
+ Next = NewOp2->Asl.Next;
+ TrAmlInitLineNumbers (Next, NewOp2);
+ (void) TrLinkChildren (Next, 1, TrCreateValuedLeafNode (PARSEOP_ZERO,
+ (UINT64) 1));
+ TrAmlInitLineNumbers (Next->Asl.Child, Next);
+
+ BufferOp = TrCreateValuedLeafNode (PARSEOP_DEFAULT_ARG, (UINT64) 0);
+ TrAmlInitLineNumbers (BufferOp, Next->Asl.Child);
+ (void) TrLinkPeerNode (Next->Asl.Child, BufferOp);
+
+ TrAmlSetSubtreeParent (Next->Asl.Child, Next);
+ break;
+
+ default:
+
+ break;
+ }
+
+ TrAmlSetSubtreeParent (NewOp2, NewOp);
+
+ /*
+ * Transform the Switch() into a While(One)-Break node.
+ * And create a Store() node which will be used to save the
+ * Switch() value. The store is of the form: Store (Value, _T_x)
+ * where _T_x is the temp variable.
+ */
+ TrAmlInitNode (StartNode, PARSEOP_WHILE);
+ NewOp = TrCreateLeafNode (PARSEOP_ONE);
+ TrAmlInitLineNumbers (NewOp, StartNode);
+ NewOp->Asl.Next = Predicate->Asl.Next;
+ NewOp->Asl.Parent = StartNode;
+ StartNode->Asl.Child = NewOp;
+
+ /* Create a Store() node */
+
+ StoreOp = TrCreateLeafNode (PARSEOP_STORE);
+ TrAmlInitLineNumbers (StoreOp, NewOp);
+ StoreOp->Asl.Parent = StartNode;
+ TrAmlInsertPeer (NewOp, StoreOp);
+
+ /* Complete the Store subtree */
+
+ StoreOp->Asl.Child = Predicate;
+ Predicate->Asl.Parent = StoreOp;
+
+ NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESEG,
+ (UINT64) ACPI_TO_INTEGER (PredicateValueName));
+ TrAmlInitLineNumbers (NewOp, StoreOp);
+ NewOp->Asl.Parent = StoreOp;
+ Predicate->Asl.Next = NewOp;
+
+ /* Create a Break() node and insert it into the end of While() */
+
+ Conditional = StartNode->Asl.Child;
+ while (Conditional->Asl.Next)
+ {
+ Conditional = Conditional->Asl.Next;
+ }
+
+ BreakOp = TrCreateLeafNode (PARSEOP_BREAK);
+ TrAmlInitLineNumbers (BreakOp, NewOp);
+ BreakOp->Asl.Parent = StartNode;
+ TrAmlInsertPeer (Conditional, BreakOp);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asltree.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltree.c
new file mode 100644
index 0000000000..68d807232a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltree.c
@@ -0,0 +1,1570 @@
+/******************************************************************************
+ *
+ * Module Name: asltree - parse tree management
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acapps.h>
+#include <time.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asltree")
+
+/* Local prototypes */
+
+static ACPI_PARSE_OBJECT *
+TrGetNextNode (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrGetNextNode
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New parse node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a new parse node for the parse tree. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+TrGetNextNode (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_ParseOpCacheList;
+ Gbl_ParseOpCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer);
+ Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE;
+ }
+
+ Gbl_ParseOpCount++;
+ return (Gbl_ParseOpCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrAllocateNode
+ *
+ * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
+ *
+ * RETURN: New parse node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrAllocateNode (
+ UINT32 ParseOpcode)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ Op = TrGetNextNode ();
+
+ Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
+ Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
+ Op->Asl.LineNumber = Gbl_CurrentLineNumber;
+ Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
+ Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
+ Op->Asl.Column = Gbl_CurrentColumn;
+
+ UtSetParseOpName (Op);
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrReleaseNode
+ *
+ * PARAMETERS: Op - Op to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: "release" a node. In truth, nothing is done since the node
+ * is part of a larger buffer
+ *
+ ******************************************************************************/
+
+void
+TrReleaseNode (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrUpdateNode
+ *
+ * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
+ * Op - An existing parse node
+ *
+ * RETURN: The updated node
+ *
+ * DESCRIPTION: Change the parse opcode assigned to a node. Usually used to
+ * change an opcode to DEFAULT_ARG so that the node is ignored
+ * during the code generation. Also used to set generic integers
+ * to a specific size (8, 16, 32, or 64 bits)
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrUpdateNode (
+ UINT32 ParseOpcode,
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nUpdateNode: Old - %s, New - %s\n",
+ UtGetOpName (Op->Asl.ParseOpcode),
+ UtGetOpName (ParseOpcode));
+
+ /* Assign new opcode and name */
+
+ if (Op->Asl.ParseOpcode == PARSEOP_ONES)
+ {
+ switch (ParseOpcode)
+ {
+ case PARSEOP_BYTECONST:
+
+ Op->Asl.Value.Integer = ACPI_UINT8_MAX;
+ break;
+
+ case PARSEOP_WORDCONST:
+
+ Op->Asl.Value.Integer = ACPI_UINT16_MAX;
+ break;
+
+ case PARSEOP_DWORDCONST:
+
+ Op->Asl.Value.Integer = ACPI_UINT32_MAX;
+ break;
+
+ /* Don't need to do the QWORD case */
+
+ default:
+
+ /* Don't care about others */
+ break;
+ }
+ }
+
+ Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
+ UtSetParseOpName (Op);
+
+ /*
+ * For the BYTE, WORD, and DWORD constants, make sure that the integer
+ * that was passed in will actually fit into the data type
+ */
+ switch (ParseOpcode)
+ {
+ case PARSEOP_BYTECONST:
+
+ UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX);
+ Op->Asl.Value.Integer &= ACPI_UINT8_MAX;
+ break;
+
+ case PARSEOP_WORDCONST:
+
+ UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX);
+ Op->Asl.Value.Integer &= ACPI_UINT16_MAX;
+ break;
+
+ case PARSEOP_DWORDCONST:
+
+ UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX);
+ Op->Asl.Value.Integer &= ACPI_UINT32_MAX;
+ break;
+
+ default:
+
+ /* Don't care about others, don't need to check QWORD */
+
+ break;
+ }
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrPrintNodeCompileFlags
+ *
+ * PARAMETERS: Flags - Flags word to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a flags word to text. Displays all flags that are set.
+ *
+ ******************************************************************************/
+
+void
+TrPrintNodeCompileFlags (
+ UINT32 Flags)
+{
+ UINT32 i;
+ UINT32 FlagBit = 1;
+ char *FlagName = NULL;
+
+
+ for (i = 0; i < 32; i++)
+ {
+ switch (Flags & FlagBit)
+ {
+ case NODE_VISITED:
+
+ FlagName = "NODE_VISITED";
+ break;
+
+ case NODE_AML_PACKAGE:
+
+ FlagName = "NODE_AML_PACKAGE";
+ break;
+
+ case NODE_IS_TARGET:
+
+ FlagName = "NODE_IS_TARGET";
+ break;
+
+ case NODE_IS_RESOURCE_DESC:
+
+ FlagName = "NODE_IS_RESOURCE_DESC";
+ break;
+
+ case NODE_IS_RESOURCE_FIELD:
+
+ FlagName = "NODE_IS_RESOURCE_FIELD";
+ break;
+
+ case NODE_HAS_NO_EXIT:
+
+ FlagName = "NODE_HAS_NO_EXIT";
+ break;
+
+ case NODE_IF_HAS_NO_EXIT:
+
+ FlagName = "NODE_IF_HAS_NO_EXIT";
+ break;
+
+ case NODE_NAME_INTERNALIZED:
+
+ FlagName = "NODE_NAME_INTERNALIZED";
+ break;
+
+ case NODE_METHOD_NO_RETVAL:
+
+ FlagName = "NODE_METHOD_NO_RETVAL";
+ break;
+
+ case NODE_METHOD_SOME_NO_RETVAL:
+
+ FlagName = "NODE_METHOD_SOME_NO_RETVAL";
+ break;
+
+ case NODE_RESULT_NOT_USED:
+
+ FlagName = "NODE_RESULT_NOT_USED";
+ break;
+
+ case NODE_METHOD_TYPED:
+
+ FlagName = "NODE_METHOD_TYPED";
+ break;
+
+ case NODE_COMPILE_TIME_CONST:
+
+ FlagName = "NODE_COMPILE_TIME_CONST";
+ break;
+
+ case NODE_IS_TERM_ARG:
+
+ FlagName = "NODE_IS_TERM_ARG";
+ break;
+
+ case NODE_WAS_ONES_OP:
+
+ FlagName = "NODE_WAS_ONES_OP";
+ break;
+
+ case NODE_IS_NAME_DECLARATION:
+
+ FlagName = "NODE_IS_NAME_DECLARATION";
+ break;
+
+ case NODE_COMPILER_EMITTED:
+
+ FlagName = "NODE_COMPILER_EMITTED";
+ break;
+
+ case NODE_IS_DUPLICATE:
+
+ FlagName = "NODE_IS_DUPLICATE";
+ break;
+
+ case NODE_IS_RESOURCE_DATA:
+
+ FlagName = "NODE_IS_RESOURCE_DATA";
+ break;
+
+ case NODE_IS_NULL_RETURN:
+
+ FlagName = "NODE_IS_NULL_RETURN";
+ break;
+
+ default:
+ break;
+ }
+
+ if (FlagName)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, " %s", FlagName);
+ FlagName = NULL;
+ }
+
+ FlagBit <<= 1;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrSetNodeFlags
+ *
+ * PARAMETERS: Op - An existing parse node
+ * Flags - New flags word
+ *
+ * RETURN: The updated parser op
+ *
+ * DESCRIPTION: Set bits in the node flags word. Will not clear bits, only set
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrSetNodeFlags (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Flags)
+{
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nSetNodeFlags: %s Op %p, %8.8X", Op->Asl.ParseOpName, Op, Flags);
+
+ TrPrintNodeCompileFlags (Flags);
+ DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
+
+ Op->Asl.CompileFlags |= Flags;
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrSetNodeAmlLength
+ *
+ * PARAMETERS: Op - An existing parse node
+ * Length - AML Length
+ *
+ * RETURN: The updated parser op
+ *
+ * DESCRIPTION: Set the AML Length in a node. Used by the parser to indicate
+ * the presence of a node that must be reduced to a fixed length
+ * constant.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrSetNodeAmlLength (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Length)
+{
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nSetNodeAmlLength: Op %p, %8.8X\n", Op, Length);
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ Op->Asl.AmlLength = Length;
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrSetEndLineNumber
+ *
+ * PARAMETERS: Op - An existing parse node
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
+ * parse node to the current line numbers.
+ *
+ ******************************************************************************/
+
+void
+TrSetEndLineNumber (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* If the end line # is already set, just return */
+
+ if (Op->Asl.EndLine)
+ {
+ return;
+ }
+
+ Op->Asl.EndLine = Gbl_CurrentLineNumber;
+ Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateAssignmentNode
+ *
+ * PARAMETERS: Target - Assignment target
+ * Source - Assignment source
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Implements the C-style '=' operator. It changes the parse
+ * tree if possible to utilize the last argument of the math
+ * operators which is a target operand -- thus saving invocation
+ * of and additional Store() operator. An optimization.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateAssignmentNode (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Source)
+{
+ ACPI_PARSE_OBJECT *TargetOp;
+ ACPI_PARSE_OBJECT *SourceOp1;
+ ACPI_PARSE_OBJECT *SourceOp2;
+ ACPI_PARSE_OBJECT *Operator;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nTrCreateAssignmentNode Line [%u to %u] Source %s Target %s\n",
+ Source->Asl.LineNumber, Source->Asl.EndLine,
+ UtGetOpName (Source->Asl.ParseOpcode),
+ UtGetOpName (Target->Asl.ParseOpcode));
+
+ TrSetNodeFlags (Target, NODE_IS_TARGET);
+
+ switch (Source->Asl.ParseOpcode)
+ {
+ /*
+ * Only these operators can be optimized because they have
+ * a target operand
+ */
+ case PARSEOP_ADD:
+ case PARSEOP_AND:
+ case PARSEOP_DIVIDE:
+ case PARSEOP_MOD:
+ case PARSEOP_MULTIPLY:
+ case PARSEOP_NOT:
+ case PARSEOP_OR:
+ case PARSEOP_SHIFTLEFT:
+ case PARSEOP_SHIFTRIGHT:
+ case PARSEOP_SUBTRACT:
+ case PARSEOP_XOR:
+
+ break;
+
+ /* Otherwise, just create a normal Store operator */
+
+ default:
+
+ goto CannotOptimize;
+ }
+
+ /*
+ * Transform the parse tree such that the target is moved to the
+ * last operand of the operator
+ */
+ SourceOp1 = Source->Asl.Child;
+ SourceOp2 = SourceOp1->Asl.Next;
+
+ /* NOT only has one operand, but has a target */
+
+ if (Source->Asl.ParseOpcode == PARSEOP_NOT)
+ {
+ SourceOp2 = SourceOp1;
+ }
+
+ /* DIVIDE has an extra target operand (remainder) */
+
+ if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
+ {
+ SourceOp2 = SourceOp2->Asl.Next;
+ }
+
+ TargetOp = SourceOp2->Asl.Next;
+
+ /*
+ * Can't perform this optimization if there already is a target
+ * for the operator (ZERO is a "no target" placeholder).
+ */
+ if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
+ {
+ goto CannotOptimize;
+ }
+
+ /* Link in the target as the final operand */
+
+ SourceOp2->Asl.Next = Target;
+ Target->Asl.Parent = Source;
+
+ return (Source);
+
+
+CannotOptimize:
+
+ Operator = TrAllocateNode (PARSEOP_STORE);
+ TrLinkChildren (Operator, 2, Source, Target);
+
+ /* Set the appropriate line numbers for the new node */
+
+ Operator->Asl.LineNumber = Target->Asl.LineNumber;
+ Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
+ Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
+ Operator->Asl.Column = Target->Asl.Column;
+
+ return (Operator);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateLeafNode
+ *
+ * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
+ * assigned to the node)
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateLeafNode (
+ UINT32 ParseOpcode)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ Op = TrAllocateNode (ParseOpcode);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateLeafNode Ln/Col %u/%u NewNode %p Op %s\n\n",
+ Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode));
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateNullTarget
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a "null" target node. This is defined by the ACPI
+ * specification to be a zero AML opcode, and indicates that
+ * no target has been specified for the parent operation
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateNullTarget (
+ void)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ Op = TrAllocateNode (PARSEOP_ZERO);
+ Op->Asl.CompileFlags |= (NODE_IS_TARGET | NODE_COMPILE_TIME_CONST);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateNullTarget Ln/Col %u/%u NewNode %p Op %s\n",
+ Op->Asl.LineNumber, Op->Asl.Column, Op,
+ UtGetOpName (Op->Asl.ParseOpcode));
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateConstantLeafNode
+ *
+ * PARAMETERS: ParseOpcode - The constant opcode
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a leaf node (no children or peers) for one of the
+ * special constants - __LINE__, __FILE__, and __DATE__.
+ *
+ * Note: An implemenation of __FUNC__ cannot happen here because we don't
+ * have a full parse tree at this time and cannot find the parent control
+ * method. If it is ever needed, __FUNC__ must be implemented later, after
+ * the parse tree has been fully constructed.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateConstantLeafNode (
+ UINT32 ParseOpcode)
+{
+ ACPI_PARSE_OBJECT *Op = NULL;
+ time_t CurrentTime;
+ char *StaticTimeString;
+ char *TimeString;
+ char *Filename;
+
+
+ switch (ParseOpcode)
+ {
+ case PARSEOP___LINE__:
+
+ Op = TrAllocateNode (PARSEOP_INTEGER);
+ Op->Asl.Value.Integer = Op->Asl.LineNumber;
+ break;
+
+ case PARSEOP___PATH__:
+
+ Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
+
+ /* Op.Asl.Filename contains the full pathname to the file */
+
+ Op->Asl.Value.String = Op->Asl.Filename;
+ break;
+
+ case PARSEOP___FILE__:
+
+ Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
+
+ /* Get the simple filename from the full path */
+
+ FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename);
+ Op->Asl.Value.String = Filename;
+ break;
+
+ case PARSEOP___DATE__:
+
+ Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
+
+ /* Get a copy of the current time */
+
+ CurrentTime = time (NULL);
+ StaticTimeString = ctime (&CurrentTime);
+ TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
+ strcpy (TimeString, StaticTimeString);
+
+ TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
+ Op->Asl.Value.String = TimeString;
+ break;
+
+ default: /* This would be an internal error */
+
+ return (NULL);
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateConstantLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X \n",
+ Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
+ ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateTargetOperand
+ *
+ * PARAMETERS: OriginalOp - Op to be copied
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Copy an existing node (and subtree). Used in ASL+ (C-style)
+ * expressions where the target is the same as one of the
+ * operands. A new node and subtree must be created from the
+ * original so that the parse tree can be linked properly.
+ *
+ * NOTE: This code is specific to target operands that are the last
+ * operand in an ASL/AML operator. Meaning that the top-level
+ * parse Op in a possible subtree has a NULL Next pointer.
+ * This simplifies the recursion.
+ *
+ * Subtree example:
+ * DeRefOf (Local1) += 32
+ *
+ * This gets converted to:
+ * Add (DeRefOf (Local1), 32, DeRefOf (Local1))
+ *
+ * Each DeRefOf has a single child, Local1. Even more complex
+ * subtrees can be created via the Index and DeRefOf operators.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateTargetOperand (
+ ACPI_PARSE_OBJECT *OriginalOp,
+ ACPI_PARSE_OBJECT *ParentOp)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ if (!OriginalOp)
+ {
+ return (NULL);
+ }
+
+ Op = TrGetNextNode ();
+
+ /* Copy the pertinent values (omit link pointer fields) */
+
+ Op->Asl.Value = OriginalOp->Asl.Value;
+ Op->Asl.Filename = OriginalOp->Asl.Filename;
+ Op->Asl.LineNumber = OriginalOp->Asl.LineNumber;
+ Op->Asl.LogicalLineNumber = OriginalOp->Asl.LogicalLineNumber;
+ Op->Asl.LogicalByteOffset = OriginalOp->Asl.LogicalByteOffset;
+ Op->Asl.Column = OriginalOp->Asl.Column;
+ Op->Asl.Flags = OriginalOp->Asl.Flags;
+ Op->Asl.CompileFlags = OriginalOp->Asl.CompileFlags;
+ Op->Asl.AmlOpcode = OriginalOp->Asl.AmlOpcode;
+ Op->Asl.ParseOpcode = OriginalOp->Asl.ParseOpcode;
+ Op->Asl.Parent = ParentOp;
+ UtSetParseOpName (Op);
+
+ /* Copy a possible subtree below this node */
+
+ if (OriginalOp->Asl.Child)
+ {
+ Op->Asl.Child = TrCreateTargetOperand (OriginalOp->Asl.Child, Op);
+ }
+
+ if (OriginalOp->Asl.Next) /* Null for top-level node */
+ {
+ Op->Asl.Next = TrCreateTargetOperand (OriginalOp->Asl.Next, ParentOp);
+ }
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateValuedLeafNode
+ *
+ * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
+ * Value - Value to be assigned to the node
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a leaf node (no children or peers) with a value
+ * assigned to it
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateValuedLeafNode (
+ UINT32 ParseOpcode,
+ UINT64 Value)
+{
+ ACPI_PARSE_OBJECT *Op;
+
+
+ Op = TrAllocateNode (ParseOpcode);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateValuedLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X ",
+ Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
+ ACPI_FORMAT_UINT64 (Value));
+ Op->Asl.Value.Integer = Value;
+
+ switch (ParseOpcode)
+ {
+ case PARSEOP_STRING_LITERAL:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
+ break;
+
+ case PARSEOP_NAMESEG:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
+ break;
+
+ case PARSEOP_NAMESTRING:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
+ break;
+
+ case PARSEOP_EISAID:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
+ break;
+
+ case PARSEOP_METHOD:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
+ break;
+
+ case PARSEOP_INTEGER:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Value));
+ break;
+
+ default:
+
+ break;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrCreateNode
+ *
+ * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
+ * NumChildren - Number of children to follow
+ * ... - A list of child nodes to link to the new
+ * node. NumChildren long.
+ *
+ * RETURN: Pointer to the new node. Aborts on allocation failure
+ *
+ * DESCRIPTION: Create a new parse node and link together a list of child
+ * nodes underneath the new node.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrCreateNode (
+ UINT32 ParseOpcode,
+ UINT32 NumChildren,
+ ...)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_PARSE_OBJECT *PrevChild;
+ va_list ap;
+ UINT32 i;
+ BOOLEAN FirstChild;
+
+
+ va_start (ap, NumChildren);
+
+ /* Allocate one new node */
+
+ Op = TrAllocateNode (ParseOpcode);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nCreateNode Ln/Col %u/%u NewParent %p Child %u Op %s ",
+ Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode));
+
+ /* Some extra debug output based on the parse opcode */
+
+ switch (ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ RootNode = Op;
+ DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
+ break;
+
+ case PARSEOP_OPERATIONREGION:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
+ break;
+
+ case PARSEOP_OR:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "OR->");
+ break;
+
+ default:
+
+ /* Nothing to do for other opcodes */
+
+ break;
+ }
+
+ /* Link the new node to its children */
+
+ PrevChild = NULL;
+ FirstChild = TRUE;
+ for (i = 0; i < NumChildren; i++)
+ {
+ /* Get the next child */
+
+ Child = va_arg (ap, ACPI_PARSE_OBJECT *);
+ DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
+
+ /*
+ * If child is NULL, this means that an optional argument
+ * was omitted. We must create a placeholder with a special
+ * opcode (DEFAULT_ARG) so that the code generator will know
+ * that it must emit the correct default for this argument
+ */
+ if (!Child)
+ {
+ Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
+ }
+
+ /* Link first child to parent */
+
+ if (FirstChild)
+ {
+ FirstChild = FALSE;
+ Op->Asl.Child = Child;
+ }
+
+ /* Point all children to parent */
+
+ Child->Asl.Parent = Op;
+
+ /* Link children in a peer list */
+
+ if (PrevChild)
+ {
+ PrevChild->Asl.Next = Child;
+ };
+
+ /*
+ * This child might be a list, point all nodes in the list
+ * to the same parent
+ */
+ while (Child->Asl.Next)
+ {
+ Child = Child->Asl.Next;
+ Child->Asl.Parent = Op;
+ }
+
+ PrevChild = Child;
+ }
+ va_end(ap);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\n");
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrLinkChildren
+ *
+ * PARAMETERS: Op - An existing parse node
+ * NumChildren - Number of children to follow
+ * ... - A list of child nodes to link to the new
+ * node. NumChildren long.
+ *
+ * RETURN: The updated (linked) node
+ *
+ * DESCRIPTION: Link a group of nodes to an existing parse node
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrLinkChildren (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 NumChildren,
+ ...)
+{
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_PARSE_OBJECT *PrevChild;
+ va_list ap;
+ UINT32 i;
+ BOOLEAN FirstChild;
+
+
+ va_start (ap, NumChildren);
+
+
+ TrSetEndLineNumber (Op);
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nLinkChildren Line [%u to %u] NewParent %p Child %u Op %s ",
+ Op->Asl.LineNumber, Op->Asl.EndLine,
+ Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode));
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_DEFINITIONBLOCK:
+
+ RootNode = Op;
+ DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
+ break;
+
+ case PARSEOP_OPERATIONREGION:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
+ break;
+
+ case PARSEOP_OR:
+
+ DbgPrint (ASL_PARSE_OUTPUT, "OR->");
+ break;
+
+ default:
+
+ /* Nothing to do for other opcodes */
+
+ break;
+ }
+
+ /* Link the new node to it's children */
+
+ PrevChild = NULL;
+ FirstChild = TRUE;
+ for (i = 0; i < NumChildren; i++)
+ {
+ Child = va_arg (ap, ACPI_PARSE_OBJECT *);
+
+ if ((Child == PrevChild) && (Child != NULL))
+ {
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child,
+ "Child node list invalid");
+ va_end(ap);
+ return (Op);
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
+
+ /*
+ * If child is NULL, this means that an optional argument
+ * was omitted. We must create a placeholder with a special
+ * opcode (DEFAULT_ARG) so that the code generator will know
+ * that it must emit the correct default for this argument
+ */
+ if (!Child)
+ {
+ Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
+ }
+
+ /* Link first child to parent */
+
+ if (FirstChild)
+ {
+ FirstChild = FALSE;
+ Op->Asl.Child = Child;
+ }
+
+ /* Point all children to parent */
+
+ Child->Asl.Parent = Op;
+
+ /* Link children in a peer list */
+
+ if (PrevChild)
+ {
+ PrevChild->Asl.Next = Child;
+ };
+
+ /*
+ * This child might be a list, point all nodes in the list
+ * to the same parent
+ */
+ while (Child->Asl.Next)
+ {
+ Child = Child->Asl.Next;
+ Child->Asl.Parent = Op;
+ }
+ PrevChild = Child;
+ }
+
+ va_end(ap);
+ DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrLinkPeerNode
+ *
+ * PARAMETERS: Op1 - First peer
+ * Op2 - Second peer
+ *
+ * RETURN: Op1 or the non-null node.
+ *
+ * DESCRIPTION: Link two nodes as peers. Handles cases where one peer is null.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrLinkPeerNode (
+ ACPI_PARSE_OBJECT *Op1,
+ ACPI_PARSE_OBJECT *Op2)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n",
+ Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL,
+ Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL);
+
+
+ if ((!Op1) && (!Op2))
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n");
+ return (Op1);
+ }
+
+ /* If one of the nodes is null, just return the non-null node */
+
+ if (!Op2)
+ {
+ return (Op1);
+ }
+
+ if (!Op1)
+ {
+ return (Op2);
+ }
+
+ if (Op1 == Op2)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "\n************* Internal error, linking node to itself %p\n",
+ Op1);
+ AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1,
+ "Linking node to itself");
+ return (Op1);
+ }
+
+ Op1->Asl.Parent = Op2->Asl.Parent;
+
+ /*
+ * Op 1 may already have a peer list (such as an IF/ELSE pair),
+ * so we must walk to the end of the list and attach the new
+ * peer at the end
+ */
+ Next = Op1;
+ while (Next->Asl.Next)
+ {
+ Next = Next->Asl.Next;
+ }
+
+ Next->Asl.Next = Op2;
+ return (Op1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrLinkPeerNodes
+ *
+ * PARAMETERS: NumPeers - The number of nodes in the list to follow
+ * ... - A list of nodes to link together as peers
+ *
+ * RETURN: The first node in the list (head of the peer list)
+ *
+ * DESCRIPTION: Link together an arbitrary number of peer nodes.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrLinkPeerNodes (
+ UINT32 NumPeers,
+ ...)
+{
+ ACPI_PARSE_OBJECT *This;
+ ACPI_PARSE_OBJECT *Next;
+ va_list ap;
+ UINT32 i;
+ ACPI_PARSE_OBJECT *Start;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nLinkPeerNodes: (%u) ", NumPeers);
+
+ va_start (ap, NumPeers);
+ This = va_arg (ap, ACPI_PARSE_OBJECT *);
+ Start = This;
+
+ /*
+ * Link all peers
+ */
+ for (i = 0; i < (NumPeers -1); i++)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This);
+
+ while (This->Asl.Next)
+ {
+ This = This->Asl.Next;
+ }
+
+ /* Get another peer node */
+
+ Next = va_arg (ap, ACPI_PARSE_OBJECT *);
+ if (!Next)
+ {
+ Next = TrAllocateNode (PARSEOP_DEFAULT_ARG);
+ }
+
+ /* link new node to the current node */
+
+ This->Asl.Next = Next;
+ This = Next;
+ }
+ va_end (ap);
+
+ DbgPrint (ASL_PARSE_OUTPUT,"\n");
+ return (Start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrLinkChildNode
+ *
+ * PARAMETERS: Op1 - Parent node
+ * Op2 - Op to become a child
+ *
+ * RETURN: The parent node
+ *
+ * DESCRIPTION: Link two nodes together as a parent and child
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+TrLinkChildNode (
+ ACPI_PARSE_OBJECT *Op1,
+ ACPI_PARSE_OBJECT *Op2)
+{
+ ACPI_PARSE_OBJECT *Next;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n",
+ Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL,
+ Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL);
+
+ if (!Op1 || !Op2)
+ {
+ return (Op1);
+ }
+
+ Op1->Asl.Child = Op2;
+
+ /* Set the child and all peers of the child to point to the parent */
+
+ Next = Op2;
+ while (Next)
+ {
+ Next->Asl.Parent = Op1;
+ Next = Next->Asl.Next;
+ }
+
+ return (Op1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: TrWalkParseTree
+ *
+ * PARAMETERS: Visitation - Type of walk
+ * DescendingCallback - Called during tree descent
+ * AscendingCallback - Called during tree ascent
+ * Context - To be passed to the callbacks
+ *
+ * RETURN: Status from callback(s)
+ *
+ * DESCRIPTION: Walk the entire parse tree.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+TrWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Visitation,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context)
+{
+ UINT32 Level;
+ BOOLEAN NodePreviouslyVisited;
+ ACPI_PARSE_OBJECT *StartOp = Op;
+ ACPI_STATUS Status;
+
+
+ if (!RootNode)
+ {
+ return (AE_OK);
+ }
+
+ Level = 0;
+ NodePreviouslyVisited = FALSE;
+
+ switch (Visitation)
+ {
+ case ASL_WALK_VISIT_DOWNWARD:
+
+ while (Op)
+ {
+ if (!NodePreviouslyVisited)
+ {
+ /* Let the callback process the node. */
+
+ Status = DescendingCallback (Op, Level, Context);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Visit children first, once */
+
+ if (Op->Asl.Child)
+ {
+ Level++;
+ Op = Op->Asl.Child;
+ continue;
+ }
+ }
+ else if (Status != AE_CTRL_DEPTH)
+ {
+ /* Exit immediately on any error */
+
+ return (Status);
+ }
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Asl.Next)
+ {
+ Op = Op->Asl.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No children or peers, re-visit parent */
+
+ if (Level != 0 )
+ {
+ Level--;
+ }
+ Op = Op->Asl.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+ break;
+
+ case ASL_WALK_VISIT_UPWARD:
+
+ while (Op)
+ {
+ /* Visit leaf node (no children) or parent node on return trip */
+
+ if ((!Op->Asl.Child) ||
+ (NodePreviouslyVisited))
+ {
+ /* Let the callback process the node. */
+
+ Status = AscendingCallback (Op, Level, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Visit children first, once */
+
+ Level++;
+ Op = Op->Asl.Child;
+ continue;
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Asl.Next)
+ {
+ Op = Op->Asl.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No children or peers, re-visit parent */
+
+ if (Level != 0 )
+ {
+ Level--;
+ }
+ Op = Op->Asl.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+ break;
+
+ case ASL_WALK_VISIT_TWICE:
+
+ while (Op)
+ {
+ if (NodePreviouslyVisited)
+ {
+ Status = AscendingCallback (Op, Level, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Let the callback process the node. */
+
+ Status = DescendingCallback (Op, Level, Context);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Visit children first, once */
+
+ if (Op->Asl.Child)
+ {
+ Level++;
+ Op = Op->Asl.Child;
+ continue;
+ }
+ }
+ else if (Status != AE_CTRL_DEPTH)
+ {
+ /* Exit immediately on any error */
+
+ return (Status);
+ }
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Asl.Next)
+ {
+ Op = Op->Asl.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No children or peers, re-visit parent */
+
+ if (Level != 0 )
+ {
+ Level--;
+ }
+ Op = Op->Asl.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+ break;
+
+ default:
+ /* No other types supported */
+ break;
+ }
+
+ /* If we get here, the walk completed with no errors */
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.h
new file mode 100644
index 0000000000..ce2f75888f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.h
@@ -0,0 +1,320 @@
+/******************************************************************************
+ *
+ * Module Name: asltypes.h - compiler data types and struct definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ASLTYPES_H
+#define __ASLTYPES_H
+
+
+/*******************************************************************************
+ *
+ * Structure definitions
+ *
+ ******************************************************************************/
+
+
+/* Op flags for the ACPI_PARSE_OBJECT */
+
+#define NODE_VISITED 0x00000001
+#define NODE_AML_PACKAGE 0x00000002
+#define NODE_IS_TARGET 0x00000004
+#define NODE_IS_RESOURCE_DESC 0x00000008
+#define NODE_IS_RESOURCE_FIELD 0x00000010
+#define NODE_HAS_NO_EXIT 0x00000020
+#define NODE_IF_HAS_NO_EXIT 0x00000040
+#define NODE_NAME_INTERNALIZED 0x00000080
+#define NODE_METHOD_NO_RETVAL 0x00000100
+#define NODE_METHOD_SOME_NO_RETVAL 0x00000200
+#define NODE_RESULT_NOT_USED 0x00000400
+#define NODE_METHOD_TYPED 0x00000800
+#define NODE_UNUSED_FLAG 0x00001000
+#define NODE_COMPILE_TIME_CONST 0x00002000
+#define NODE_IS_TERM_ARG 0x00004000
+#define NODE_WAS_ONES_OP 0x00008000
+#define NODE_IS_NAME_DECLARATION 0x00010000
+#define NODE_COMPILER_EMITTED 0x00020000
+#define NODE_IS_DUPLICATE 0x00040000
+#define NODE_IS_RESOURCE_DATA 0x00080000
+#define NODE_IS_NULL_RETURN 0x00100000
+
+/* Keeps information about individual control methods */
+
+typedef struct asl_method_info
+{
+ ACPI_PARSE_OBJECT *Op;
+ struct asl_method_info *Next;
+ UINT32 ValidArgTypes[ACPI_METHOD_NUM_ARGS];
+ UINT32 ValidReturnTypes;
+ UINT32 NumReturnNoValue;
+ UINT32 NumReturnWithValue;
+ UINT8 NumArguments;
+ UINT8 LocalInitialized[ACPI_METHOD_NUM_LOCALS];
+ UINT8 ArgInitialized[ACPI_METHOD_NUM_ARGS];
+ UINT8 HasBeenTyped;
+ UINT8 ShouldBeSerialized;
+
+} ASL_METHOD_INFO;
+
+
+/* Parse tree walk info for control method analysis */
+
+typedef struct asl_analysis_walk_info
+{
+ ASL_METHOD_INFO *MethodStack;
+
+} ASL_ANALYSIS_WALK_INFO;
+
+
+/* An entry in the ParseOpcode to AmlOpcode mapping table */
+
+typedef struct asl_mapping_entry
+{
+ UINT32 Value;
+ UINT32 AcpiBtype; /* Object type or return type */
+ UINT16 AmlOpcode;
+ UINT8 Flags;
+
+} ASL_MAPPING_ENTRY;
+
+
+/* Parse tree walk info structure */
+
+typedef struct asl_walk_info
+{
+ ACPI_PARSE_OBJECT **NodePtr;
+ UINT32 *LevelPtr;
+
+} ASL_WALK_INFO;
+
+
+/* File info */
+
+typedef struct asl_file_info
+{
+ FILE *Handle;
+ char *Filename;
+ const char *ShortDescription;
+ const char *Description;
+
+} ASL_FILE_INFO;
+
+typedef struct asl_file_status
+{
+ UINT32 Line;
+ UINT32 Offset;
+
+} ASL_FILE_STATUS;
+
+
+/*
+ * File types. Note: Any changes to this table must also be reflected
+ * in the Gbl_Files array.
+ *
+ * Corresponding filename suffixes are in comments
+ *
+ * NOTE: Don't move the first 4 file types
+ */
+typedef enum
+{
+ ASL_FILE_STDOUT = 0,
+ ASL_FILE_STDERR,
+ ASL_FILE_INPUT, /* .asl */
+ ASL_FILE_AML_OUTPUT, /* .aml */
+ ASL_FILE_SOURCE_OUTPUT, /* .src */
+ ASL_FILE_PREPROCESSOR, /* .pre */
+ ASL_FILE_PREPROCESSOR_USER, /* .i */
+ ASL_FILE_LISTING_OUTPUT, /* .lst */
+ ASL_FILE_HEX_OUTPUT, /* .hex */
+ ASL_FILE_NAMESPACE_OUTPUT, /* .nsp */
+ ASL_FILE_DEBUG_OUTPUT, /* .txt */
+ ASL_FILE_ASM_SOURCE_OUTPUT, /* .asm */
+ ASL_FILE_C_SOURCE_OUTPUT, /* .c */
+ ASL_FILE_ASM_INCLUDE_OUTPUT,/* .inc */
+ ASL_FILE_C_INCLUDE_OUTPUT, /* .h */
+ ASL_FILE_C_OFFSET_OUTPUT, /* offset.h */
+ ASL_FILE_MAP_OUTPUT /* .map */
+
+} ASL_FILE_TYPES;
+
+
+#define ASL_MAX_FILE_TYPE 16
+#define ASL_NUM_FILES (ASL_MAX_FILE_TYPE + 1)
+
+/* filename suffixes for output files */
+
+#define FILE_SUFFIX_PREPROC_USER "i "
+#define FILE_SUFFIX_PREPROCESSOR "pre"
+#define FILE_SUFFIX_AML_CODE "aml"
+#define FILE_SUFFIX_MAP "map"
+#define FILE_SUFFIX_LISTING "lst"
+#define FILE_SUFFIX_HEX_DUMP "hex"
+#define FILE_SUFFIX_DEBUG "txt"
+#define FILE_SUFFIX_SOURCE "src"
+#define FILE_SUFFIX_NAMESPACE "nsp"
+#define FILE_SUFFIX_ASM_SOURCE "asm"
+#define FILE_SUFFIX_C_SOURCE "c"
+#define FILE_SUFFIX_DISASSEMBLY "dsl"
+#define FILE_SUFFIX_ASM_INCLUDE "inc"
+#define FILE_SUFFIX_C_INCLUDE "h"
+#define FILE_SUFFIX_ASL_CODE "asl"
+#define FILE_SUFFIX_C_OFFSET "offset.h"
+
+
+/* Cache block structure for ParseOps and Strings */
+
+typedef struct asl_cache_info
+{
+ void *Next;
+ char Buffer[1];
+
+} ASL_CACHE_INFO;
+
+
+typedef struct asl_include_dir
+{
+ char *Dir;
+ struct asl_include_dir *Next;
+
+} ASL_INCLUDE_DIR;
+
+
+/* An entry in the exception list, one for each error/warning */
+
+typedef struct asl_error_msg
+{
+ UINT32 LineNumber;
+ UINT32 LogicalLineNumber;
+ UINT32 LogicalByteOffset;
+ UINT32 Column;
+ char *Message;
+ struct asl_error_msg *Next;
+ char *Filename;
+ char *SourceLine;
+ UINT32 FilenameLength;
+ UINT16 MessageId;
+ UINT8 Level;
+
+} ASL_ERROR_MSG;
+
+
+/* An entry in the listing file stack (for include files) */
+
+typedef struct asl_listing_node
+{
+ char *Filename;
+ UINT32 LineNumber;
+ struct asl_listing_node *Next;
+
+} ASL_LISTING_NODE;
+
+
+/* Callback interface for a parse tree walk */
+
+/*
+ * TBD - another copy of this is in adisasm.h, fix
+ */
+#ifndef ASL_WALK_CALLBACK_DEFINED
+typedef
+ACPI_STATUS (*ASL_WALK_CALLBACK) (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+#define ASL_WALK_CALLBACK_DEFINED
+#endif
+
+
+typedef struct asl_event_info
+{
+ UINT64 StartTime;
+ UINT64 EndTime;
+ char *EventName;
+ BOOLEAN Valid;
+
+} ASL_EVENT_INFO;
+
+
+/* Hardware mapping file structures */
+
+typedef struct acpi_gpio_info
+{
+ struct acpi_gpio_info *Next;
+ ACPI_PARSE_OBJECT *Op;
+ char *DeviceName;
+ ACPI_NAMESPACE_NODE *TargetNode;
+ UINT32 References;
+ UINT32 PinCount;
+ UINT32 PinIndex;
+ UINT16 PinNumber;
+ UINT8 Type;
+ UINT8 Direction;
+ UINT8 Polarity;
+
+} ACPI_GPIO_INFO;
+
+typedef struct acpi_serial_info
+{
+ struct acpi_serial_info *Next;
+ ACPI_PARSE_OBJECT *Op;
+ char *DeviceName;
+ ACPI_NAMESPACE_NODE *TargetNode;
+ AML_RESOURCE *Resource;
+ UINT32 Speed;
+ UINT16 Address;
+
+} ACPI_SERIAL_INFO;
+
+typedef struct asl_method_local
+{
+ ACPI_PARSE_OBJECT *Op;
+ UINT8 Flags;
+
+} ASL_METHOD_LOCAL;
+
+/* Values for Flags field above */
+
+#define ASL_LOCAL_INITIALIZED (1)
+#define ASL_LOCAL_REFERENCED (1<<1)
+#define ASL_ARG_IS_LOCAL (1<<2)
+#define ASL_ARG_INITIALIZED (1<<3)
+#define ASL_ARG_REFERENCED (1<<4)
+
+#endif /* __ASLTYPES_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.y
new file mode 100644
index 0000000000..650b856152
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asltypes.y
@@ -0,0 +1,393 @@
+NoEcho('
+/******************************************************************************
+ *
+ * Module Name: asltypes.y - Bison/Yacc production types/names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+')
+
+/******************************************************************************
+ *
+ * Production names
+ *
+ *****************************************************************************/
+
+%type <n> ArgList
+%type <n> ASLCode
+%type <n> BufferData
+%type <n> BufferTermData
+%type <n> CompilerDirective
+%type <n> DataObject
+%type <n> DefinitionBlockTerm
+%type <n> IntegerData
+%type <n> NamedObject
+%type <n> NameSpaceModifier
+%type <n> Object
+%type <n> ObjectList
+%type <n> PackageData
+%type <n> ParameterTypePackage
+%type <n> ParameterTypePackageList
+%type <n> ParameterTypesPackage
+%type <n> ParameterTypesPackageList
+%type <n> RequiredTarget
+%type <n> SimpleTarget
+%type <n> StringData
+%type <n> Target
+%type <n> Term
+%type <n> TermArg
+%type <n> TermList
+%type <n> MethodInvocationTerm
+
+/* Type4Opcode is obsolete */
+
+%type <n> Type1Opcode
+%type <n> Type2BufferOpcode
+%type <n> Type2BufferOrStringOpcode
+%type <n> Type2IntegerOpcode
+%type <n> Type2Opcode
+%type <n> Type2StringOpcode
+%type <n> Type3Opcode
+%type <n> Type5Opcode
+%type <n> Type6Opcode
+
+%type <n> AccessAsTerm
+%type <n> ExternalTerm
+%type <n> FieldUnit
+%type <n> FieldUnitEntry
+%type <n> FieldUnitList
+%type <n> IncludeTerm
+%type <n> OffsetTerm
+%type <n> OptionalAccessAttribTerm
+
+/* Named Objects */
+
+%type <n> BankFieldTerm
+%type <n> CreateBitFieldTerm
+%type <n> CreateByteFieldTerm
+%type <n> CreateDWordFieldTerm
+%type <n> CreateFieldTerm
+%type <n> CreateQWordFieldTerm
+%type <n> CreateWordFieldTerm
+%type <n> DataRegionTerm
+%type <n> DeviceTerm
+%type <n> EventTerm
+%type <n> FieldTerm
+%type <n> FunctionTerm
+%type <n> IndexFieldTerm
+%type <n> MethodTerm
+%type <n> MutexTerm
+%type <n> OpRegionTerm
+%type <n> OpRegionSpaceIdTerm
+%type <n> PowerResTerm
+%type <n> ProcessorTerm
+%type <n> ThermalZoneTerm
+
+/* Namespace modifiers */
+
+%type <n> AliasTerm
+%type <n> NameTerm
+%type <n> ScopeTerm
+
+/* Type 1 opcodes */
+
+%type <n> BreakPointTerm
+%type <n> BreakTerm
+%type <n> CaseDefaultTermList
+%type <n> CaseTerm
+%type <n> ContinueTerm
+%type <n> DefaultTerm
+%type <n> ElseTerm
+%type <n> FatalTerm
+%type <n> IfElseTerm
+%type <n> IfTerm
+%type <n> LoadTerm
+%type <n> NoOpTerm
+%type <n> NotifyTerm
+%type <n> ReleaseTerm
+%type <n> ResetTerm
+%type <n> ReturnTerm
+%type <n> SignalTerm
+%type <n> SleepTerm
+%type <n> StallTerm
+%type <n> SwitchTerm
+%type <n> UnloadTerm
+%type <n> WhileTerm
+/* %type <n> CaseTermList */
+
+/* Type 2 opcodes */
+
+%type <n> AcquireTerm
+%type <n> AddTerm
+%type <n> AndTerm
+%type <n> ConcatResTerm
+%type <n> ConcatTerm
+%type <n> CondRefOfTerm
+%type <n> CopyObjectTerm
+%type <n> DecTerm
+%type <n> DerefOfTerm
+%type <n> DivideTerm
+%type <n> FindSetLeftBitTerm
+%type <n> FindSetRightBitTerm
+%type <n> FromBCDTerm
+%type <n> IncTerm
+%type <n> IndexTerm
+%type <n> LAndTerm
+%type <n> LEqualTerm
+%type <n> LGreaterEqualTerm
+%type <n> LGreaterTerm
+%type <n> LLessEqualTerm
+%type <n> LLessTerm
+%type <n> LNotEqualTerm
+%type <n> LNotTerm
+%type <n> LoadTableTerm
+%type <n> LOrTerm
+%type <n> MatchTerm
+%type <n> MidTerm
+%type <n> ModTerm
+%type <n> MultiplyTerm
+%type <n> NAndTerm
+%type <n> NOrTerm
+%type <n> NotTerm
+%type <n> ObjectTypeTerm
+%type <n> OrTerm
+%type <n> RefOfTerm
+%type <n> ShiftLeftTerm
+%type <n> ShiftRightTerm
+%type <n> SizeOfTerm
+%type <n> StoreTerm
+%type <n> SubtractTerm
+%type <n> TimerTerm
+%type <n> ToBCDTerm
+%type <n> ToBufferTerm
+%type <n> ToDecimalStringTerm
+%type <n> ToHexStringTerm
+%type <n> ToIntegerTerm
+%type <n> ToStringTerm
+%type <n> WaitTerm
+%type <n> XOrTerm
+
+/* Keywords */
+
+%type <n> AccessAttribKeyword
+%type <n> AccessTypeKeyword
+%type <n> AddressingModeKeyword
+%type <n> AddressKeyword
+%type <n> AddressSpaceKeyword
+%type <n> BitsPerByteKeyword
+%type <n> ClockPhaseKeyword
+%type <n> ClockPolarityKeyword
+%type <n> DecodeKeyword
+%type <n> DevicePolarityKeyword
+%type <n> DMATypeKeyword
+%type <n> EndianKeyword
+%type <n> FlowControlKeyword
+%type <n> InterruptLevel
+%type <n> InterruptTypeKeyword
+%type <n> IODecodeKeyword
+%type <n> IoRestrictionKeyword
+%type <n> LockRuleKeyword
+%type <n> MatchOpKeyword
+%type <n> MaxKeyword
+%type <n> MemTypeKeyword
+%type <n> MinKeyword
+%type <n> ObjectTypeKeyword
+%type <n> OptionalBusMasterKeyword
+%type <n> OptionalReadWriteKeyword
+%type <n> ParityTypeKeyword
+%type <n> PinConfigByte
+%type <n> PinConfigKeyword
+%type <n> RangeTypeKeyword
+%type <n> RegionSpaceKeyword
+%type <n> ResourceTypeKeyword
+%type <n> SerializeRuleKeyword
+%type <n> ShareTypeKeyword
+%type <n> SlaveModeKeyword
+%type <n> StopBitsKeyword
+%type <n> TranslationKeyword
+%type <n> TypeKeyword
+%type <n> UpdateRuleKeyword
+%type <n> WireModeKeyword
+%type <n> XferSizeKeyword
+%type <n> XferTypeKeyword
+
+/* Types */
+
+%type <n> SuperName
+%type <n> ObjectTypeName
+%type <n> ArgTerm
+%type <n> LocalTerm
+%type <n> DebugTerm
+
+%type <n> Integer
+%type <n> ByteConst
+%type <n> WordConst
+%type <n> DWordConst
+%type <n> QWordConst
+%type <n> String
+
+%type <n> ConstTerm
+%type <n> ConstExprTerm
+%type <n> ByteConstExpr
+%type <n> WordConstExpr
+%type <n> DWordConstExpr
+%type <n> QWordConstExpr
+
+%type <n> DWordList
+%type <n> BufferTerm
+%type <n> ByteList
+
+%type <n> PackageElement
+%type <n> PackageList
+%type <n> PackageTerm
+%type <n> VarPackageLengthTerm
+
+/* Macros */
+
+%type <n> EISAIDTerm
+%type <n> ResourceMacroList
+%type <n> ResourceMacroTerm
+%type <n> ResourceTemplateTerm
+%type <n> PldKeyword
+%type <n> PldKeywordList
+%type <n> ToPLDTerm
+%type <n> ToUUIDTerm
+%type <n> UnicodeTerm
+%type <n> PrintfArgList
+%type <n> PrintfTerm
+%type <n> FprintfTerm
+
+/* Resource Descriptors */
+
+%type <n> ConnectionTerm
+%type <n> DataBufferTerm
+%type <n> DMATerm
+%type <n> DWordIOTerm
+%type <n> DWordMemoryTerm
+%type <n> DWordSpaceTerm
+%type <n> EndDependentFnTerm
+%type <n> ExtendedIOTerm
+%type <n> ExtendedMemoryTerm
+%type <n> ExtendedSpaceTerm
+%type <n> FixedDmaTerm
+%type <n> FixedIOTerm
+%type <n> GpioIntTerm
+%type <n> GpioIoTerm
+%type <n> I2cSerialBusTerm
+%type <n> InterruptTerm
+%type <n> IOTerm
+%type <n> IRQNoFlagsTerm
+%type <n> IRQTerm
+%type <n> Memory24Term
+%type <n> Memory32FixedTerm
+%type <n> Memory32Term
+%type <n> NameSeg
+%type <n> NameString
+%type <n> QWordIOTerm
+%type <n> QWordMemoryTerm
+%type <n> QWordSpaceTerm
+%type <n> RegisterTerm
+%type <n> SpiSerialBusTerm
+%type <n> StartDependentFnNoPriTerm
+%type <n> StartDependentFnTerm
+%type <n> UartSerialBusTerm
+%type <n> VendorLongTerm
+%type <n> VendorShortTerm
+%type <n> WordBusNumberTerm
+%type <n> WordIOTerm
+%type <n> WordSpaceTerm
+
+/* Local types that help construct the AML, not in ACPI spec */
+
+%type <n> AmlPackageLengthTerm
+%type <n> IncludeEndTerm
+%type <n> NameStringItem
+%type <n> TermArgItem
+
+%type <n> OptionalAccessSize
+%type <n> OptionalAddressingMode
+%type <n> OptionalAddressRange
+%type <n> OptionalBitsPerByte
+%type <n> OptionalBuffer_Last
+%type <n> OptionalByteConstExpr
+%type <n> OptionalCount
+%type <n> OptionalDecodeType
+%type <n> OptionalDevicePolarity
+%type <n> OptionalDWordConstExpr
+%type <n> OptionalEndian
+%type <n> OptionalFlowControl
+%type <n> OptionalIoRestriction
+%type <n> OptionalListString
+%type <n> OptionalMaxType
+%type <n> OptionalMemType
+%type <n> OptionalMinType
+%type <n> OptionalNameString
+%type <n> OptionalNameString_First
+%type <n> OptionalNameString_Last
+%type <n> OptionalObjectTypeKeyword
+%type <n> OptionalParameterTypePackage
+%type <n> OptionalParameterTypesPackage
+%type <n> OptionalParityType
+%type <n> OptionalQWordConstExpr
+%type <n> OptionalRangeType
+%type <n> OptionalReference
+%type <n> OptionalResourceType
+%type <n> OptionalResourceType_First
+%type <n> OptionalReturnArg
+%type <n> OptionalSerializeRuleKeyword
+%type <n> OptionalShareType
+%type <n> OptionalShareType_First
+%type <n> OptionalSlaveMode
+%type <n> OptionalStopBits
+%type <n> OptionalStringData
+%type <n> OptionalTermArg
+%type <n> OptionalTranslationType_Last
+%type <n> OptionalType
+%type <n> OptionalType_Last
+%type <n> OptionalWireMode
+%type <n> OptionalWordConst
+%type <n> OptionalWordConstExpr
+%type <n> OptionalXferSize
+
+/*
+ * C-style expression parser
+ */
+%type <n> Expression
+%type <n> EqualsTerm
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslutils.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslutils.c
new file mode 100644
index 0000000000..956a488a8c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslutils.c
@@ -0,0 +1,1144 @@
+/******************************************************************************
+ *
+ * Module Name: aslutils -- compiler utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslutils")
+
+
+/* Local prototypes */
+
+static void
+UtPadNameWithUnderscores (
+ char *NameSeg,
+ char *PaddedNameSeg);
+
+static void
+UtAttachNameseg (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtDisplaySupportedTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print all supported ACPI table names.
+ *
+ ******************************************************************************/
+
+void
+UtDisplaySupportedTables (
+ void)
+{
+ const AH_TABLE *TableData;
+ UINT32 i;
+
+
+ printf ("\nACPI tables supported by iASL version %8.8X:\n"
+ " (Compiler, Disassembler, Template Generator)\n\n",
+ ACPI_CA_VERSION);
+
+ /* All ACPI tables with the common table header */
+
+ printf ("\n Supported ACPI tables:\n");
+ for (TableData = AcpiSupportedTables, i = 1;
+ TableData->Signature; TableData++, i++)
+ {
+ printf ("%8u) %s %s\n", i,
+ TableData->Signature, TableData->Description);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtDisplayConstantOpcodes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
+ *
+ ******************************************************************************/
+
+void
+UtDisplayConstantOpcodes (
+ void)
+{
+ UINT32 i;
+
+
+ printf ("Constant expression opcode information\n\n");
+
+ for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
+ {
+ if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
+ {
+ printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtLocalCalloc
+ *
+ * PARAMETERS: Size - Bytes to be allocated
+ *
+ * RETURN: Pointer to the allocated memory. Guaranteed to be valid.
+ *
+ * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
+ * allocation failure, on the assumption that nothing more can be
+ * accomplished.
+ *
+ ******************************************************************************/
+
+void *
+UtLocalCalloc (
+ UINT32 Size)
+{
+ void *Allocated;
+
+
+ Allocated = ACPI_ALLOCATE_ZEROED (Size);
+ if (!Allocated)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+
+ CmCleanupAndExit ();
+ exit (1);
+ }
+
+ TotalAllocations++;
+ TotalAllocated += Size;
+ return (Allocated);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtBeginEvent
+ *
+ * PARAMETERS: Name - Ascii name of this event
+ *
+ * RETURN: Event number (integer index)
+ *
+ * DESCRIPTION: Saves the current time with this event
+ *
+ ******************************************************************************/
+
+UINT8
+UtBeginEvent (
+ char *Name)
+{
+
+ if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
+ {
+ AcpiOsPrintf ("Ran out of compiler event structs!\n");
+ return (AslGbl_NextEvent);
+ }
+
+ /* Init event with current (start) time */
+
+ AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
+ AslGbl_Events[AslGbl_NextEvent].EventName = Name;
+ AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
+
+ return (AslGbl_NextEvent++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtEndEvent
+ *
+ * PARAMETERS: Event - Event number (integer index)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Saves the current time (end time) with this event
+ *
+ ******************************************************************************/
+
+void
+UtEndEvent (
+ UINT8 Event)
+{
+
+ if (Event >= ASL_NUM_EVENTS)
+ {
+ return;
+ }
+
+ /* Insert end time for event */
+
+ AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtConvertByteToHex
+ *
+ * PARAMETERS: RawByte - Binary data
+ * Buffer - Pointer to where the hex bytes will be
+ * stored
+ *
+ * RETURN: Ascii hex byte is stored in Buffer.
+ *
+ * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
+ * with "0x"
+ *
+ ******************************************************************************/
+
+void
+UtConvertByteToHex (
+ UINT8 RawByte,
+ UINT8 *Buffer)
+{
+
+ Buffer[0] = '0';
+ Buffer[1] = 'x';
+
+ Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
+ Buffer[3] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtConvertByteToAsmHex
+ *
+ * PARAMETERS: RawByte - Binary data
+ * Buffer - Pointer to where the hex bytes will be
+ * stored
+ *
+ * RETURN: Ascii hex byte is stored in Buffer.
+ *
+ * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
+ * with '0', and a trailing 'h' is added.
+ *
+ ******************************************************************************/
+
+void
+UtConvertByteToAsmHex (
+ UINT8 RawByte,
+ UINT8 *Buffer)
+{
+
+ Buffer[0] = '0';
+ Buffer[1] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 4);
+ Buffer[2] = (UINT8) AcpiUtHexToAsciiChar (RawByte, 0);
+ Buffer[3] = 'h';
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DbgPrint
+ *
+ * PARAMETERS: Type - Type of output
+ * Fmt - Printf format string
+ * ... - variable printf list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Conditional print statement. Prints to stderr only if the
+ * debug flag is set.
+ *
+ ******************************************************************************/
+
+void
+DbgPrint (
+ UINT32 Type,
+ char *Fmt,
+ ...)
+{
+ va_list Args;
+
+
+ if (!Gbl_DebugFlag)
+ {
+ return;
+ }
+
+ if ((Type == ASL_PARSE_OUTPUT) &&
+ (!(AslCompilerdebug)))
+ {
+ return;
+ }
+
+ va_start (Args, Fmt);
+ (void) vfprintf (stderr, Fmt, Args);
+ va_end (Args);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtPrintFormattedName
+ *
+ * PARAMETERS: ParseOpcode - Parser keyword ID
+ * Level - Indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print the ascii name of the parse opcode.
+ *
+ ******************************************************************************/
+
+#define TEXT_OFFSET 10
+
+void
+UtPrintFormattedName (
+ UINT16 ParseOpcode,
+ UINT32 Level)
+{
+
+ if (Level)
+ {
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%*s", (3 * Level), " ");
+ }
+ DbgPrint (ASL_TREE_OUTPUT,
+ " %-20.20s", UtGetOpName (ParseOpcode));
+
+ if (Level < TEXT_OFFSET)
+ {
+ DbgPrint (ASL_TREE_OUTPUT,
+ "%*s", (TEXT_OFFSET - Level) * 3, " ");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtSetParseOpName
+ *
+ * PARAMETERS: Op - Parse op to be named.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert the ascii name of the parse opcode
+ *
+ ******************************************************************************/
+
+void
+UtSetParseOpName (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
+ ACPI_MAX_PARSEOP_NAME);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtDisplaySummary
+ *
+ * PARAMETERS: FileID - ID of outpout file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display compilation statistics
+ *
+ ******************************************************************************/
+
+void
+UtDisplaySummary (
+ UINT32 FileId)
+{
+ UINT32 i;
+
+
+ if (FileId != ASL_FILE_STDOUT)
+ {
+ /* Compiler name and version number */
+
+ FlPrintFile (FileId, "%s version %X%s\n\n",
+ ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH);
+ }
+
+ /* Summary of main input and output files */
+
+ if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
+ {
+ FlPrintFile (FileId,
+ "%-14s %s - %u lines, %u bytes, %u fields\n",
+ "Table Input:",
+ Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
+ Gbl_InputByteCount, Gbl_InputFieldCount);
+
+ if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
+ {
+ FlPrintFile (FileId,
+ "%-14s %s - %u bytes\n",
+ "Binary Output:",
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
+ }
+ }
+ else
+ {
+ FlPrintFile (FileId,
+ "%-14s %s - %u lines, %u bytes, %u keywords\n",
+ "ASL Input:",
+ Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
+ Gbl_OriginalInputFileSize, TotalKeywords);
+
+ /* AML summary */
+
+ if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
+ {
+ if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
+ {
+ FlPrintFile (FileId,
+ "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
+ "AML Output:",
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
+ TotalNamedObjects, TotalExecutableOpcodes);
+ }
+ }
+ }
+
+ /* Display summary of any optional files */
+
+ for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
+ {
+ if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
+ {
+ continue;
+ }
+
+ /* .SRC is a temp file unless specifically requested */
+
+ if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
+ {
+ continue;
+ }
+
+ /* .PRE is the preprocessor intermediate file */
+
+ if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_KeepPreprocessorTempFile))
+ {
+ continue;
+ }
+
+ FlPrintFile (FileId, "%14s %s - %u bytes\n",
+ Gbl_Files[i].ShortDescription,
+ Gbl_Files[i].Filename, FlGetFileSize (i));
+ }
+
+ /* Error summary */
+
+ FlPrintFile (FileId,
+ "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
+ Gbl_ExceptionCount[ASL_ERROR],
+ Gbl_ExceptionCount[ASL_WARNING] +
+ Gbl_ExceptionCount[ASL_WARNING2] +
+ Gbl_ExceptionCount[ASL_WARNING3],
+ Gbl_ExceptionCount[ASL_REMARK]);
+
+ if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
+ {
+ FlPrintFile (FileId, ", %u Optimizations",
+ Gbl_ExceptionCount[ASL_OPTIMIZATION]);
+
+ if (TotalFolds)
+ {
+ FlPrintFile (FileId, ", %u Constants Folded", TotalFolds);
+ }
+ }
+
+ FlPrintFile (FileId, "\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtCheckIntegerRange
+ *
+ * PARAMETERS: Op - Integer parse node
+ * LowValue - Smallest allowed value
+ * HighValue - Largest allowed value
+ *
+ * RETURN: Op if OK, otherwise NULL
+ *
+ * DESCRIPTION: Check integer for an allowable range
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+UtCheckIntegerRange (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 LowValue,
+ UINT32 HighValue)
+{
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ if ((Op->Asl.Value.Integer < LowValue) ||
+ (Op->Asl.Value.Integer > HighValue))
+ {
+ sprintf (MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
+ (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
+
+ AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
+ return (NULL);
+ }
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtStringCacheCalloc
+ *
+ * PARAMETERS: Length - Size of buffer requested
+ *
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a string buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+char *
+UtStringCacheCalloc (
+ UINT32 Length)
+{
+ char *Buffer;
+ ASL_CACHE_INFO *Cache;
+ UINT32 CacheSize = ASL_STRING_CACHE_SIZE;
+
+
+ if (Length > CacheSize)
+ {
+ CacheSize = Length;
+
+ if (Gbl_StringCacheList)
+ {
+ Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
+
+ /* Link new cache buffer just following head of list */
+
+ Cache->Next = Gbl_StringCacheList->Next;
+ Gbl_StringCacheList->Next = Cache;
+
+ /* Leave cache management pointers alone as they pertain to head */
+
+ Gbl_StringCount++;
+ Gbl_StringSize += Length;
+
+ return (Cache->Buffer);
+ }
+ }
+
+ if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_StringCacheList;
+ Gbl_StringCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_StringCacheNext = Cache->Buffer;
+ Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
+ }
+
+ Gbl_StringCount++;
+ Gbl_StringSize += Length;
+
+ Buffer = Gbl_StringCacheNext;
+ Gbl_StringCacheNext += Length;
+ return (Buffer);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: UtExpandLineBuffers
+ *
+ * PARAMETERS: None. Updates global line buffer pointers.
+ *
+ * RETURN: None. Reallocates the global line buffers
+ *
+ * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
+ * all global line buffers and updates Gbl_LineBufferSize. NOTE:
+ * Also used for the initial allocation of the buffers, when
+ * all of the buffer pointers are NULL. Initial allocations are
+ * of size ASL_DEFAULT_LINE_BUFFER_SIZE
+ *
+ *****************************************************************************/
+
+void
+UtExpandLineBuffers (
+ void)
+{
+ UINT32 NewSize;
+
+
+ /* Attempt to double the size of all line buffers */
+
+ NewSize = Gbl_LineBufferSize * 2;
+ if (Gbl_CurrentLineBuffer)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Increasing line buffer size from %u to %u\n",
+ Gbl_LineBufferSize, NewSize);
+ }
+
+ Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize);
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+ if (!Gbl_CurrentLineBuffer)
+ {
+ goto ErrorExit;
+ }
+
+ Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize);
+ if (!Gbl_MainTokenBuffer)
+ {
+ goto ErrorExit;
+ }
+
+ Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize);
+ if (!Gbl_MacroTokenBuffer)
+ {
+ goto ErrorExit;
+ }
+
+ Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize);
+ if (!Gbl_ExpressionTokenBuffer)
+ {
+ goto ErrorExit;
+ }
+
+ Gbl_LineBufferSize = NewSize;
+ return;
+
+
+ /* On error above, simply issue error messages and abort, cannot continue */
+
+ErrorExit:
+ printf ("Could not increase line buffer size from %u to %u\n",
+ Gbl_LineBufferSize, Gbl_LineBufferSize * 2);
+
+ AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION,
+ NULL, NULL);
+ AslAbort ();
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: UtFreeLineBuffers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Free all line buffers
+ *
+ *****************************************************************************/
+
+void
+UtFreeLineBuffers (
+ void)
+{
+
+ free (Gbl_CurrentLineBuffer);
+ free (Gbl_MainTokenBuffer);
+ free (Gbl_MacroTokenBuffer);
+ free (Gbl_ExpressionTokenBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtInternalizeName
+ *
+ * PARAMETERS: ExternalName - Name to convert
+ * ConvertedName - Where the converted name is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+UtInternalizeName (
+ char *ExternalName,
+ char **ConvertedName)
+{
+ ACPI_NAMESTRING_INFO Info;
+ ACPI_STATUS Status;
+
+
+ if (!ExternalName)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the length of the new internal name */
+
+ Info.ExternalName = ExternalName;
+ AcpiNsGetInternalNameLength (&Info);
+
+ /* We need a segment to store the internal name */
+
+ Info.InternalName = UtStringCacheCalloc (Info.Length);
+ if (!Info.InternalName)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Build the name */
+
+ Status = AcpiNsBuildInternalName (&Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *ConvertedName = Info.InternalName;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtPadNameWithUnderscores
+ *
+ * PARAMETERS: NameSeg - Input nameseg
+ * PaddedNameSeg - Output padded nameseg
+ *
+ * RETURN: Padded nameseg.
+ *
+ * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
+ * ACPI_NAME.
+ *
+ ******************************************************************************/
+
+static void
+UtPadNameWithUnderscores (
+ char *NameSeg,
+ char *PaddedNameSeg)
+{
+ UINT32 i;
+
+
+ for (i = 0; (i < ACPI_NAME_SIZE); i++)
+ {
+ if (*NameSeg)
+ {
+ *PaddedNameSeg = *NameSeg;
+ NameSeg++;
+ }
+ else
+ {
+ *PaddedNameSeg = '_';
+ }
+ PaddedNameSeg++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtAttachNameseg
+ *
+ * PARAMETERS: Op - Parent parse node
+ * Name - Full ExternalName
+ *
+ * RETURN: None; Sets the NameSeg field in parent node
+ *
+ * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
+ * in the NameSeg field of the Op.
+ *
+ ******************************************************************************/
+
+static void
+UtAttachNameseg (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+ char *NameSeg;
+ char PaddedNameSeg[4];
+
+
+ if (!Name)
+ {
+ return;
+ }
+
+ /* Look for the last dot in the namepath */
+
+ NameSeg = strrchr (Name, '.');
+ if (NameSeg)
+ {
+ /* Found last dot, we have also found the final nameseg */
+
+ NameSeg++;
+ UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
+ }
+ else
+ {
+ /* No dots in the namepath, there is only a single nameseg. */
+ /* Handle prefixes */
+
+ while (ACPI_IS_ROOT_PREFIX (*Name) ||
+ ACPI_IS_PARENT_PREFIX (*Name))
+ {
+ Name++;
+ }
+
+ /* Remaining string should be one single nameseg */
+
+ UtPadNameWithUnderscores (Name, PaddedNameSeg);
+ }
+
+ ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtAttachNamepathToOwner
+ *
+ * PARAMETERS: Op - Parent parse node
+ * NameOp - Node that contains the name
+ *
+ * RETURN: Sets the ExternalName and Namepath in the parent node
+ *
+ * DESCRIPTION: Store the name in two forms in the parent node: The original
+ * (external) name, and the internalized name that is used within
+ * the ACPI namespace manager.
+ *
+ ******************************************************************************/
+
+void
+UtAttachNamepathToOwner (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *NameOp)
+{
+ ACPI_STATUS Status;
+
+
+ /* Full external path */
+
+ Op->Asl.ExternalName = NameOp->Asl.Value.String;
+
+ /* Save the NameOp for possible error reporting later */
+
+ Op->Asl.ParentMethod = (void *) NameOp;
+
+ /* Last nameseg of the path */
+
+ UtAttachNameseg (Op, Op->Asl.ExternalName);
+
+ /* Create internalized path */
+
+ Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
+ if (ACPI_FAILURE (Status))
+ {
+ /* TBD: abort on no memory */
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtDoConstant
+ *
+ * PARAMETERS: String - Hex, Octal, or Decimal string
+ *
+ * RETURN: Converted Integer
+ *
+ * DESCRIPTION: Convert a string to an integer, with error checking.
+ *
+ ******************************************************************************/
+
+UINT64
+UtDoConstant (
+ char *String)
+{
+ ACPI_STATUS Status;
+ UINT64 Converted;
+ char ErrBuf[64];
+
+
+ Status = stroul64 (String, 0, &Converted);
+ if (ACPI_FAILURE (Status))
+ {
+ sprintf (ErrBuf, "%s %s\n", "Conversion error:",
+ AcpiFormatException (Status));
+ AslCompilererror (ErrBuf);
+ }
+
+ return (Converted);
+}
+
+
+/* TBD: use version in ACPICA main code base? */
+
+/*******************************************************************************
+ *
+ * FUNCTION: stroul64
+ *
+ * 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
+stroul64 (
+ 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);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/asluuid.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/asluuid.c
new file mode 100644
index 0000000000..850ac6a36e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/asluuid.c
@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ * Module Name: asluuid-- compiler UUID support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("asluuid")
+
+
+extern UINT8 AcpiGbl_MapToUuidOffset[UUID_BUFFER_LENGTH];
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AuValiduateUuid
+ *
+ * PARAMETERS: InString - 36-byte formatted UUID string
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check all 36 characters for correct format
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AuValidateUuid (
+ char *InString)
+{
+ UINT32 i;
+
+
+ if (!InString || (strlen (InString) != UUID_STRING_LENGTH))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Check all 36 characters for correct format */
+
+ for (i = 0; i < UUID_STRING_LENGTH; i++)
+ {
+ /* Must have 4 hyphens (dashes) in these positions: */
+
+ if ((i == UUID_HYPHEN1_OFFSET) ||
+ (i == UUID_HYPHEN2_OFFSET) ||
+ (i == UUID_HYPHEN3_OFFSET) ||
+ (i == UUID_HYPHEN4_OFFSET))
+ {
+ if (InString[i] != '-')
+ {
+ return (AE_BAD_PARAMETER);
+ }
+ }
+
+ /* All other positions must contain hex digits */
+
+ else
+ {
+ if (!isxdigit ((int) InString[i]))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AuConvertUuidToString
+ *
+ * PARAMETERS: UuidBuffer - 16-byte UUID buffer
+ * OutString - 36-byte formatted UUID string
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert 16-byte UUID buffer to 36-byte formatted UUID string
+ * OutString must be 37 bytes to include null terminator.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AuConvertUuidToString (
+ char *UuidBuffer,
+ char *OutString)
+{
+ UINT32 i;
+
+
+ if (!UuidBuffer || !OutString)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ for (i = 0; i < UUID_BUFFER_LENGTH; i++)
+ {
+ OutString[AcpiGbl_MapToUuidOffset[i]] =
+ AcpiUtHexToAsciiChar (UuidBuffer[i], 4);
+
+ OutString[AcpiGbl_MapToUuidOffset[i] + 1] =
+ AcpiUtHexToAsciiChar (UuidBuffer[i], 0);
+ }
+
+ /* Insert required hyphens (dashes) */
+
+ OutString[UUID_HYPHEN1_OFFSET] =
+ OutString[UUID_HYPHEN2_OFFSET] =
+ OutString[UUID_HYPHEN3_OFFSET] =
+ OutString[UUID_HYPHEN4_OFFSET] = '-';
+
+ OutString[UUID_STRING_LENGTH] = 0; /* Null terminate */
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslwalks.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslwalks.c
new file mode 100644
index 0000000000..c59895d70f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslwalks.c
@@ -0,0 +1,692 @@
+/******************************************************************************
+ *
+ * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslwalks")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnMethodTypingWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for typing walk. Complete the method
+ * return analysis. Check methods for:
+ * 1) Initialized local variables
+ * 2) Valid arguments
+ * 3) Return types
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnMethodTypingWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ UINT32 ThisNodeBtype;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_METHOD:
+
+ Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
+ break;
+
+ case PARSEOP_RETURN:
+
+ if ((Op->Asl.Child) &&
+ (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+ {
+ ThisNodeBtype = AnGetBtype (Op->Asl.Child);
+
+ if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
+ (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
+ {
+ /*
+ * The called method is untyped at this time (typically a
+ * forward reference).
+ *
+ * Check for a recursive method call first.
+ */
+ if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
+ {
+ /* We must type the method here */
+
+ TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
+ ASL_WALK_VISIT_UPWARD, NULL,
+ AnMethodTypingWalkEnd, NULL);
+
+ ThisNodeBtype = AnGetBtype (Op->Asl.Child);
+ }
+ }
+
+ /* Returns a value, save the value type */
+
+ if (Op->Asl.ParentMethod)
+ {
+ Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
+ }
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnOperandTypecheckWalkEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback for analysis walk. Complete method
+ * return analysis.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnOperandTypecheckWalkEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 RuntimeArgTypes;
+ UINT32 RuntimeArgTypes2;
+ UINT32 RequiredBtypes;
+ UINT32 ThisNodeBtype;
+ UINT32 CommonBtypes;
+ UINT32 OpcodeClass;
+ ACPI_PARSE_OBJECT *ArgOp;
+ UINT32 ArgType;
+
+
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_RAW_DATA_BYTE:
+ case AML_RAW_DATA_WORD:
+ case AML_RAW_DATA_DWORD:
+ case AML_RAW_DATA_QWORD:
+ case AML_RAW_DATA_BUFFER:
+ case AML_RAW_DATA_CHAIN:
+ case AML_PACKAGE_LENGTH:
+ case AML_UNASSIGNED_OPCODE:
+ case AML_DEFAULT_ARG_OP:
+
+ /* Ignore the internal (compiler-only) AML opcodes */
+
+ return (AE_OK);
+
+ default:
+
+ break;
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ if (!OpInfo)
+ {
+ return (AE_OK);
+ }
+
+ ArgOp = Op->Asl.Child;
+ RuntimeArgTypes = OpInfo->RuntimeArgs;
+ OpcodeClass = OpInfo->Class;
+
+#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
+ /*
+ * Update 11/2008: In practice, we can't perform this check. A simple
+ * analysis is not sufficient. Also, it can cause errors when compiling
+ * disassembled code because of the way Switch operators are implemented
+ * (a While(One) loop with a named temp variable created within.)
+ */
+
+ /*
+ * If we are creating a named object, check if we are within a while loop
+ * by checking if the parent is a WHILE op. This is a simple analysis, but
+ * probably sufficient for many cases.
+ *
+ * Allow Scope(), Buffer(), and Package().
+ */
+ if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
+ ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
+ {
+ if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
+ }
+ }
+#endif
+
+ /*
+ * Special case for control opcodes IF/RETURN/WHILE since they
+ * have no runtime arg list (at this time)
+ */
+ switch (Op->Asl.AmlOpcode)
+ {
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_RETURN_OP:
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ /* Check for an internal method */
+
+ if (AnIsInternalMethod (ArgOp))
+ {
+ return (AE_OK);
+ }
+
+ /* The lone arg is a method call, check it */
+
+ RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
+ if (Op->Asl.AmlOpcode == AML_RETURN_OP)
+ {
+ RequiredBtypes = 0xFFFFFFFF;
+ }
+
+ ThisNodeBtype = AnGetBtype (ArgOp);
+ if (ThisNodeBtype == ACPI_UINT32_MAX)
+ {
+ return (AE_OK);
+ }
+ AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
+ RequiredBtypes, ThisNodeBtype);
+ }
+ return (AE_OK);
+
+ case AML_EXTERNAL_OP:
+ /*
+ * Not really a "runtime" opcode since it used by disassembler only.
+ * The parser will find any issues with the operands.
+ */
+ return (AE_OK);
+
+ default:
+
+ break;
+ }
+
+ /* Ignore the non-executable opcodes */
+
+ if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
+ {
+ return (AE_OK);
+ }
+
+ switch (OpcodeClass)
+ {
+ case AML_CLASS_EXECUTE:
+ case AML_CLASS_CREATE:
+ case AML_CLASS_CONTROL:
+ case AML_CLASS_RETURN_VALUE:
+
+ /* TBD: Change class or fix typechecking for these */
+
+ if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) ||
+ (Op->Asl.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ break;
+ }
+
+ /* Reverse the runtime argument list */
+
+ RuntimeArgTypes2 = 0;
+ while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
+ {
+ RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
+ RuntimeArgTypes2 |= ArgType;
+ INCREMENT_ARG_LIST (RuntimeArgTypes);
+ }
+
+ while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
+ {
+ RequiredBtypes = AnMapArgTypeToBtype (ArgType);
+
+ if (!ArgOp)
+ {
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
+ "Null ArgOp in argument loop");
+ AslAbort ();
+ }
+
+ ThisNodeBtype = AnGetBtype (ArgOp);
+ if (ThisNodeBtype == ACPI_UINT32_MAX)
+ {
+ goto NextArgument;
+ }
+
+ /* Examine the arg based on the required type of the arg */
+
+ switch (ArgType)
+ {
+ case ARGI_TARGETREF:
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ /* ZERO is the placeholder for "don't store result" */
+
+ ThisNodeBtype = RequiredBtypes;
+ break;
+ }
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
+ {
+ /*
+ * This is the case where an original reference to a resource
+ * descriptor field has been replaced by an (Integer) offset.
+ * These named fields are supported at compile-time only;
+ * the names are not passed to the interpreter (via the AML).
+ */
+ if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
+ (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
+ }
+ else
+ {
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
+ }
+ break;
+ }
+
+ if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
+ (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
+ {
+ break;
+ }
+
+ ThisNodeBtype = RequiredBtypes;
+ break;
+
+
+ case ARGI_REFERENCE: /* References */
+ case ARGI_INTEGER_REF:
+ case ARGI_OBJECT_REF:
+ case ARGI_DEVICE_REF:
+
+ switch (ArgOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_LOCAL0:
+ case PARSEOP_LOCAL1:
+ case PARSEOP_LOCAL2:
+ case PARSEOP_LOCAL3:
+ case PARSEOP_LOCAL4:
+ case PARSEOP_LOCAL5:
+ case PARSEOP_LOCAL6:
+ case PARSEOP_LOCAL7:
+
+ /* TBD: implement analysis of current value (type) of the local */
+ /* For now, just treat any local as a typematch */
+
+ /*ThisNodeBtype = RequiredBtypes;*/
+ break;
+
+ case PARSEOP_ARG0:
+ case PARSEOP_ARG1:
+ case PARSEOP_ARG2:
+ case PARSEOP_ARG3:
+ case PARSEOP_ARG4:
+ case PARSEOP_ARG5:
+ case PARSEOP_ARG6:
+
+ /* Hard to analyze argument types, sow we won't */
+ /* For now, just treat any arg as a typematch */
+
+ /* ThisNodeBtype = RequiredBtypes; */
+ break;
+
+ case PARSEOP_DEBUG:
+ case PARSEOP_REFOF:
+ case PARSEOP_INDEX:
+ default:
+
+ break;
+
+ }
+ break;
+
+ case ARGI_INTEGER:
+ default:
+
+ break;
+ }
+
+
+ CommonBtypes = ThisNodeBtype & RequiredBtypes;
+
+ if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
+ {
+ if (AnIsInternalMethod (ArgOp))
+ {
+ return (AE_OK);
+ }
+
+ /* Check a method call for a valid return value */
+
+ AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
+ RequiredBtypes, ThisNodeBtype);
+ }
+
+ /*
+ * Now check if the actual type(s) match at least one
+ * bit to the required type
+ */
+ else if (!CommonBtypes)
+ {
+ /* No match -- this is a type mismatch error */
+
+ AnFormatBtype (StringBuffer, ThisNodeBtype);
+ AnFormatBtype (StringBuffer2, RequiredBtypes);
+
+ sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
+ StringBuffer, OpInfo->Name, StringBuffer2);
+
+ AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
+ }
+
+ NextArgument:
+ ArgOp = ArgOp->Asl.Next;
+ INCREMENT_ARG_LIST (RuntimeArgTypes2);
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AnOtherSemanticAnalysisWalkBegin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback for the analysis walk. Checks for
+ * miscellaneous issues in the code.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AnOtherSemanticAnalysisWalkBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_PARSE_OBJECT *ArgNode;
+ ACPI_PARSE_OBJECT *PrevArgNode = NULL;
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+
+ /*
+ * Determine if an execution class operator actually does something by
+ * checking if it has a target and/or the function return value is used.
+ * (Target is optional, so a standalone statement can actually do nothing.)
+ */
+ if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
+ (OpInfo->Flags & AML_HAS_RETVAL) &&
+ (!AnIsResultUsed (Op)))
+ {
+ if (OpInfo->Flags & AML_HAS_TARGET)
+ {
+ /*
+ * Find the target node, it is always the last child. If the traget
+ * is not specified in the ASL, a default node of type Zero was
+ * created by the parser.
+ */
+ ArgNode = Op->Asl.Child;
+ while (ArgNode->Asl.Next)
+ {
+ PrevArgNode = ArgNode;
+ ArgNode = ArgNode->Asl.Next;
+ }
+
+ /* Divide() is the only weird case, it has two targets */
+
+ if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
+ {
+ if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
+ (PrevArgNode) &&
+ (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ }
+ }
+ else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
+ {
+ AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ }
+ }
+ else
+ {
+ /*
+ * Has no target and the result is not used. Only a couple opcodes
+ * can have this combination.
+ */
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ACQUIRE:
+ case PARSEOP_WAIT:
+ case PARSEOP_LOADTABLE:
+
+ break;
+
+ default:
+
+ AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
+ Op, Op->Asl.ExternalName);
+ break;
+ }
+ }
+ }
+
+
+ /*
+ * Semantic checks for individual ASL operators
+ */
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ACQUIRE:
+ case PARSEOP_WAIT:
+ /*
+ * Emit a warning if the timeout parameter for these operators is not
+ * ACPI_WAIT_FOREVER, and the result value from the operator is not
+ * checked, meaning that a timeout could happen, but the code
+ * would not know about it.
+ */
+
+ /* First child is the namepath, 2nd child is timeout */
+
+ ArgNode = Op->Asl.Child;
+ ArgNode = ArgNode->Asl.Next;
+
+ /*
+ * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
+ * 0xFFFF or greater
+ */
+ if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
+ (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) &&
+ (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
+ {
+ break;
+ }
+
+ /*
+ * The operation could timeout. If the return value is not used
+ * (indicates timeout occurred), issue a warning
+ */
+ if (!AnIsResultUsed (Op))
+ {
+ AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode,
+ Op->Asl.ExternalName);
+ }
+ break;
+
+ case PARSEOP_CREATEFIELD:
+ /*
+ * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
+ */
+ ArgNode = Op->Asl.Child;
+ ArgNode = ArgNode->Asl.Next;
+ ArgNode = ArgNode->Asl.Next;
+
+ if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
+ ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
+ (ArgNode->Asl.Value.Integer == 0)))
+ {
+ AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
+ }
+ break;
+
+ case PARSEOP_CONNECTION:
+ /*
+ * Ensure that the referenced operation region has the correct SPACE_ID.
+ * From the grammar/parser, we know the parent is a FIELD definition.
+ */
+ ArgNode = Op->Asl.Parent; /* Field definition */
+ ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */
+ Node = ArgNode->Asl.Node; /* OpRegion namespace node */
+ if (!Node)
+ {
+ break;
+ }
+
+ ArgNode = Node->Op; /* OpRegion definition */
+ ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */
+ ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */
+
+ /*
+ * The Connection() operator is only valid for the following operation
+ * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
+ */
+ if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
+ (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
+ {
+ AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
+ }
+ break;
+
+ case PARSEOP_FIELD:
+ /*
+ * Ensure that fields for GeneralPurposeIo and GenericSerialBus
+ * contain at least one Connection() operator
+ */
+ ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */
+ Node = ArgNode->Asl.Node; /* OpRegion namespace node */
+ if (!Node)
+ {
+ break;
+ }
+
+ ArgNode = Node->Op; /* OpRegion definition */
+ ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */
+ ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */
+
+ /* We are only interested in GeneralPurposeIo and GenericSerialBus */
+
+ if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
+ (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
+ {
+ break;
+ }
+
+ ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */
+ ArgNode = ArgNode->Asl.Next; /* AccessType */
+ ArgNode = ArgNode->Asl.Next; /* LockRule */
+ ArgNode = ArgNode->Asl.Next; /* UpdateRule */
+ ArgNode = ArgNode->Asl.Next; /* Start of FieldUnitList */
+
+ /* Walk the FieldUnitList */
+
+ while (ArgNode)
+ {
+ if (ArgNode->Asl.ParseOpcode == PARSEOP_CONNECTION)
+ {
+ break;
+ }
+ else if (ArgNode->Asl.ParseOpcode == PARSEOP_NAMESEG)
+ {
+ AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgNode, NULL);
+ break;
+ }
+
+ ArgNode = ArgNode->Asl.Next;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/aslxref.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslxref.c
new file mode 100644
index 0000000000..910a1132b3
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/aslxref.c
@@ -0,0 +1,1269 @@
+/******************************************************************************
+ *
+ * Module Name: aslxref - Namespace cross-reference
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslxref")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+XfNamespaceLocateBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+XfNamespaceLocateEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_PARSE_OBJECT *
+XfGetParentMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+static BOOLEAN
+XfObjectExists (
+ char *Name);
+
+static ACPI_STATUS
+XfCompareOneNamespaceObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+static void
+XfCheckFieldRange (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 RegionBitLength,
+ UINT32 FieldBitOffset,
+ UINT32 FieldBitLength,
+ UINT32 AccessBitWidth);
+
+#ifdef __UNDER_DEVELOPMENT
+static ACPI_PARSE_OBJECT *
+XfGetParentMethod (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+XfCheckIllegalReference (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *Node);
+
+static BOOLEAN
+XfIsObjectParental (
+ ACPI_PARSE_OBJECT *MethodOp1,
+ ACPI_PARSE_OBJECT *MethodOp2);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfCrossReferenceNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform a cross reference check of the parse tree against the
+ * namespace. Every named referenced within the parse tree
+ * should be get resolved with a namespace lookup. If not, the
+ * original reference in the ASL code is invalid -- i.e., refers
+ * to a non-existent object.
+ *
+ * NOTE: The ASL "External" operator causes the name to be inserted into the
+ * namespace so that references to the external name will be resolved
+ * correctly here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+XfCrossReferenceNamespace (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
+
+ /*
+ * Create a new walk state for use when looking up names
+ * within the namespace (Passed as context to the callbacks)
+ */
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Walk the entire parse tree */
+
+ TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, XfNamespaceLocateBegin,
+ XfNamespaceLocateEnd, WalkState);
+
+ ACPI_FREE (WalkState);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfObjectExists
+ *
+ * PARAMETERS: Name - 4 char ACPI name
+ *
+ * RETURN: TRUE if name exists in namespace
+ *
+ * DESCRIPTION: Walk the namespace to find an object
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+XfObjectExists (
+ char *Name)
+{
+ ACPI_STATUS Status;
+
+
+ /* Walk entire namespace from the supplied root */
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
+ Name, NULL);
+ if (Status == AE_CTRL_TRUE)
+ {
+ /* At least one instance of the name was found */
+
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfCompareOneNamespaceObject
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compare name of one object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+XfCompareOneNamespaceObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+
+
+ /* Simply check the name */
+
+ if (*((UINT32 *) (Context)) == Node->Name.Integer)
+ {
+ /* Abort walk if we found one instance */
+
+ return (AE_CTRL_TRUE);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfCheckFieldRange
+ *
+ * PARAMETERS: RegionBitLength - Length of entire parent region
+ * FieldBitOffset - Start of the field unit (within region)
+ * FieldBitLength - Entire length of field unit
+ * AccessBitWidth - Access width of the field unit
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check one field unit to make sure it fits in the parent
+ * op region.
+ *
+ * Note: AccessBitWidth must be either 8,16,32, or 64
+ *
+ ******************************************************************************/
+
+static void
+XfCheckFieldRange (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 RegionBitLength,
+ UINT32 FieldBitOffset,
+ UINT32 FieldBitLength,
+ UINT32 AccessBitWidth)
+{
+ UINT32 FieldEndBitOffset;
+
+
+ /*
+ * Check each field unit against the region size. The entire
+ * field unit (start offset plus length) must fit within the
+ * region.
+ */
+ FieldEndBitOffset = FieldBitOffset + FieldBitLength;
+
+ if (FieldEndBitOffset > RegionBitLength)
+ {
+ /* Field definition itself is beyond the end-of-region */
+
+ AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
+ return;
+ }
+
+ /*
+ * Now check that the field plus AccessWidth doesn't go beyond
+ * the end-of-region. Assumes AccessBitWidth is a power of 2
+ */
+ FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
+
+ if (FieldEndBitOffset > RegionBitLength)
+ {
+ /* Field definition combined with the access is beyond EOR */
+
+ AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfGetParentMethod
+ *
+ * PARAMETERS: Op - Parse Op to be checked
+ *
+ * RETURN: Control method Op if found. NULL otherwise
+ *
+ * DESCRIPTION: Find the control method parent of a parse op. Returns NULL if
+ * the input Op is not within a control method.
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+XfGetParentMethod (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ NextOp = Op->Asl.Parent;
+ while (NextOp)
+ {
+ if (NextOp->Asl.AmlOpcode == AML_METHOD_OP)
+ {
+ return (NextOp);
+ }
+
+ NextOp = NextOp->Asl.Parent;
+ }
+
+ return (NULL); /* No parent method found */
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfNamespaceLocateBegin
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during cross-reference. For named
+ * object references, attempt to locate the name in the
+ * namespace.
+ *
+ * NOTE: ASL references to named fields within resource descriptors are
+ * resolved to integer values here. Therefore, this step is an
+ * important part of the code generation. We don't know that the
+ * name refers to a resource descriptor until now.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+XfNamespaceLocateBegin (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE ObjectType;
+ char *Path;
+ UINT8 PassedArgs;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *OwningOp;
+ ACPI_PARSE_OBJECT *SpaceIdOp;
+ UINT32 MinimumLength;
+ UINT32 Offset;
+ UINT32 FieldBitLength;
+ UINT32 TagBitLength;
+ UINT8 Message = 0;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 Flags;
+ ASL_METHOD_LOCAL *MethodLocals = NULL;
+ ASL_METHOD_LOCAL *MethodArgs = NULL;
+ int RegisterNumber;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
+
+
+ if ((Op->Asl.AmlOpcode == AML_METHOD_OP) && Op->Asl.Node)
+ {
+ Node = Op->Asl.Node;
+
+ /* Support for method LocalX/ArgX analysis */
+
+ if (!Node->MethodLocals)
+ {
+ /* Create local/arg info blocks */
+
+ MethodLocals = UtLocalCalloc (
+ sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_LOCALS);
+ Node->MethodLocals = MethodLocals;
+
+ MethodArgs = UtLocalCalloc (
+ sizeof (ASL_METHOD_LOCAL) * ACPI_METHOD_NUM_ARGS);
+ Node->MethodArgs = MethodArgs;
+
+ /*
+ * Get the method argument count
+ * First, get the name node
+ */
+ NextOp = Op->Asl.Child;
+
+ /* Get the NumArguments node */
+
+ NextOp = NextOp->Asl.Next;
+ Node->ArgCount = (UINT8)
+ (((UINT8) NextOp->Asl.Value.Integer) & 0x07);
+
+ /* We will track all posible ArgXs */
+
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ if (i < Node->ArgCount)
+ {
+ /* Real Args are always "initialized" */
+
+ MethodArgs[i].Flags = ASL_ARG_INITIALIZED;
+ }
+ else
+ {
+ /* Other ArgXs can be used as locals */
+
+ MethodArgs[i].Flags = ASL_ARG_IS_LOCAL;
+ }
+
+ MethodArgs[i].Op = Op;
+ }
+ }
+ }
+
+ /*
+ * If this node is the actual declaration of a name
+ * [such as the XXXX name in "Method (XXXX)"],
+ * we are not interested in it here. We only care about names that are
+ * references to other objects within the namespace and the parent objects
+ * of name declarations
+ */
+ if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+
+ /* Check method LocalX variables */
+
+ if (OpInfo->Type == AML_TYPE_LOCAL_VARIABLE)
+ {
+ /* Find parent method Op */
+
+ NextOp = XfGetParentMethod (Op);
+ if (!NextOp)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get method node */
+
+ Node = NextOp->Asl.Node;
+
+ RegisterNumber = Op->Asl.AmlOpcode & 0x0007; /* 0x60 through 0x67 */
+ MethodLocals = Node->MethodLocals;
+
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ /* Local is being initialized */
+
+ MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_INITIALIZED;
+ MethodLocals[RegisterNumber].Op = Op;
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Mark this Local as referenced */
+
+ MethodLocals[RegisterNumber].Flags |= ASL_LOCAL_REFERENCED;
+ MethodLocals[RegisterNumber].Op = Op;
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Check method ArgX variables */
+
+ if (OpInfo->Type == AML_TYPE_METHOD_ARGUMENT)
+ {
+ /* Find parent method Op */
+
+ NextOp = XfGetParentMethod (Op);
+ if (!NextOp)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get method node */
+
+ Node = NextOp->Asl.Node;
+
+ /* Get Arg # */
+
+ RegisterNumber = Op->Asl.AmlOpcode - AML_ARG0; /* 0x68 through 0x6F */
+ MethodArgs = Node->MethodArgs;
+
+ if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+ {
+ /* Arg is being initialized */
+
+ MethodArgs[RegisterNumber].Flags |= ASL_ARG_INITIALIZED;
+ MethodArgs[RegisterNumber].Op = Op;
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Mark this Arg as referenced */
+
+ MethodArgs[RegisterNumber].Flags |= ASL_ARG_REFERENCED;
+ MethodArgs[RegisterNumber].Op = Op;
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * After method ArgX and LocalX, we are only interested in opcodes
+ * that have an associated name
+ */
+ if ((!(OpInfo->Flags & AML_NAMED)) &&
+ (!(OpInfo->Flags & AML_CREATE)) &&
+ (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
+ (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
+ (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * One special case: CondRefOf operator - we don't care if the name exists
+ * or not at this point, just ignore it, the point of the operator is to
+ * determine if the name exists at runtime.
+ */
+ if ((Op->Asl.Parent) &&
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * We must enable the "search-to-root" for single NameSegs, but
+ * we have to be very careful about opening up scopes
+ */
+ Flags = ACPI_NS_SEARCH_PARENT;
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
+ {
+ /*
+ * These are name references, do not push the scope stack
+ * for them.
+ */
+ Flags |= ACPI_NS_DONT_OPEN_SCOPE;
+ }
+
+ /* Get the NamePath from the appropriate place */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ /* For nearly all NAMED operators, the name reference is the first child */
+
+ Path = Op->Asl.Child->Asl.Value.String;
+ if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
+ {
+ /*
+ * ALIAS is the only oddball opcode, the name declaration
+ * (alias name) is the second operand
+ */
+ Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
+ }
+ }
+ else if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Name must appear as the last parameter */
+
+ NextOp = Op->Asl.Child;
+ while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
+ {
+ NextOp = NextOp->Asl.Next;
+ }
+ Path = NextOp->Asl.Value.String;
+ }
+ else
+ {
+ Path = Op->Asl.Value.String;
+ }
+
+ ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
+
+ /*
+ * Lookup the name in the namespace. Name must exist at this point, or it
+ * is an invalid reference.
+ *
+ * The namespace is also used as a lookup table for references to resource
+ * descriptors and the fields within them.
+ */
+ Gbl_NsLookupCount++;
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ /*
+ * We didn't find the name reference by path -- we can qualify this
+ * a little better before we print an error message
+ */
+ if (strlen (Path) == ACPI_NAME_SIZE)
+ {
+ /* A simple, one-segment ACPI name */
+
+ if (XfObjectExists (Path))
+ {
+ /*
+ * There exists such a name, but we couldn't get to it
+ * from this scope
+ */
+ AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
+ Op->Asl.ExternalName);
+ }
+ else
+ {
+ /* The name doesn't exist, period */
+
+ AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
+ Op, Op->Asl.ExternalName);
+ }
+ }
+ else
+ {
+ /* Check for a fully qualified path */
+
+ if (Path[0] == AML_ROOT_PREFIX)
+ {
+ /* Gave full path, the object does not exist */
+
+ AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
+ Op->Asl.ExternalName);
+ }
+ else
+ {
+ /*
+ * We can't tell whether it doesn't exist or just
+ * can't be reached.
+ */
+ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
+ Op->Asl.ExternalName);
+ }
+ }
+
+ Status = AE_OK;
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Check for a reference vs. name declaration */
+
+ if (!(OpInfo->Flags & AML_NAMED) &&
+ !(OpInfo->Flags & AML_CREATE))
+ {
+ /* This node has been referenced, mark it for reference check */
+
+ Node->Flags |= ANOBJ_IS_REFERENCED;
+
+#ifdef __UNDER_DEVELOPMENT
+
+ /* Check for an illegal reference */
+
+ XfCheckIllegalReference (Op, Node);
+#endif
+ }
+
+ /* Attempt to optimize the NamePath */
+
+ OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
+
+ /*
+ * 1) Dereference an alias (A name reference that is an alias)
+ * Aliases are not nested, the alias always points to the final object
+ */
+ if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
+ (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
+ {
+ /* This node points back to the original PARSEOP_ALIAS */
+
+ NextOp = Node->Op;
+
+ /* The first child is the alias target op */
+
+ NextOp = NextOp->Asl.Child;
+
+ /* That in turn points back to original target alias node */
+
+ if (NextOp->Asl.Node)
+ {
+ Node = NextOp->Asl.Node;
+ }
+
+ /* Else - forward reference to alias, will be resolved later */
+ }
+
+ /* 2) Check for a reference to a resource descriptor */
+
+ if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
+ (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
+ {
+ /*
+ * This was a reference to a field within a resource descriptor.
+ * Extract the associated field offset (either a bit or byte
+ * offset depending on the field type) and change the named
+ * reference into an integer for AML code generation
+ */
+ Offset = Node->Value;
+ TagBitLength = Node->Length;
+
+ /*
+ * If a field is being created, generate the length (in bits) of
+ * the field. Note: Opcodes other than CreateXxxField and Index
+ * can come through here. For other opcodes, we just need to
+ * convert the resource tag reference to an integer offset.
+ */
+ switch (Op->Asl.Parent->Asl.AmlOpcode)
+ {
+ case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
+ /*
+ * We know the length operand is an integer constant because
+ * we know that it contains a reference to a resource
+ * descriptor tag.
+ */
+ FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
+ break;
+
+ case AML_CREATE_BIT_FIELD_OP:
+
+ FieldBitLength = 1;
+ break;
+
+ case AML_CREATE_BYTE_FIELD_OP:
+ case AML_INDEX_OP:
+
+ FieldBitLength = 8;
+ break;
+
+ case AML_CREATE_WORD_FIELD_OP:
+
+ FieldBitLength = 16;
+ break;
+
+ case AML_CREATE_DWORD_FIELD_OP:
+
+ FieldBitLength = 32;
+ break;
+
+ case AML_CREATE_QWORD_FIELD_OP:
+
+ FieldBitLength = 64;
+ break;
+
+ default:
+
+ FieldBitLength = 0;
+ break;
+ }
+
+ /* Check the field length against the length of the resource tag */
+
+ if (FieldBitLength)
+ {
+ if (TagBitLength < FieldBitLength)
+ {
+ Message = ASL_MSG_TAG_SMALLER;
+ }
+ else if (TagBitLength > FieldBitLength)
+ {
+ Message = ASL_MSG_TAG_LARGER;
+ }
+
+ if (Message)
+ {
+ sprintf (MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
+ TagBitLength, (TagBitLength > 1) ? "s" : "",
+ FieldBitLength, (FieldBitLength > 1) ? "s" : "");
+
+ AslError (ASL_WARNING, Message, Op, MsgBuffer);
+ }
+ }
+
+ /* Convert the BitOffset to a ByteOffset for certain opcodes */
+
+ switch (Op->Asl.Parent->Asl.AmlOpcode)
+ {
+ case AML_CREATE_BYTE_FIELD_OP:
+ case AML_CREATE_WORD_FIELD_OP:
+ case AML_CREATE_DWORD_FIELD_OP:
+ case AML_CREATE_QWORD_FIELD_OP:
+ case AML_INDEX_OP:
+
+ Offset = ACPI_DIV_8 (Offset);
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Now convert this node to an integer whose value is the field offset */
+
+ Op->Asl.AmlLength = 0;
+ Op->Asl.ParseOpcode = PARSEOP_INTEGER;
+ Op->Asl.Value.Integer = (UINT64) Offset;
+ Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
+
+ OpcGenerateAmlOpcode (Op);
+ }
+
+ /* 3) Check for a method invocation */
+
+ else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
+ (Node->Type == ACPI_TYPE_METHOD) &&
+ (Op->Asl.Parent) &&
+ (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) ||
+
+ (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
+ {
+ /*
+ * A reference to a method within one of these opcodes is not an
+ * invocation of the method, it is simply a reference to the method.
+ */
+ if ((Op->Asl.Parent) &&
+ ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) ||
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF) ||
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+ /*
+ * There are two types of method invocation:
+ * 1) Invocation with arguments -- the parser recognizes this
+ * as a METHODCALL.
+ * 2) Invocation with no arguments --the parser cannot determine that
+ * this is a method invocation, therefore we have to figure it out
+ * here.
+ */
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ sprintf (MsgBuffer, "%s is a %s",
+ Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
+
+ AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Save the method node in the caller's op */
+
+ Op->Asl.Node = Node;
+ if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * This is a method invocation, with or without arguments.
+ * Count the number of arguments, each appears as a child
+ * under the parent node
+ */
+ Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
+ UtSetParseOpName (Op);
+
+ PassedArgs = 0;
+ NextOp = Op->Asl.Child;
+
+ while (NextOp)
+ {
+ PassedArgs++;
+ NextOp = NextOp->Asl.Next;
+ }
+
+ if (Node->Value != ASL_EXTERNAL_METHOD)
+ {
+ /*
+ * Check the parsed arguments with the number expected by the
+ * method declaration itself
+ */
+ if (PassedArgs != Node->Value)
+ {
+ sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
+ Node->Value);
+
+ if (PassedArgs < Node->Value)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
+ }
+ else
+ {
+ AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
+ }
+ }
+ }
+ }
+
+ /* 4) Check for an ASL Field definition */
+
+ else if ((Op->Asl.Parent) &&
+ ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) ||
+ (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
+ {
+ /*
+ * Offset checking for fields. If the parent operation region has a
+ * constant length (known at compile time), we can check fields
+ * defined in that region against the region length. This will catch
+ * fields and field units that cannot possibly fit within the region.
+ *
+ * Note: Index fields do not directly reference an operation region,
+ * thus they are not included in this check.
+ */
+ if (Op == Op->Asl.Parent->Asl.Child)
+ {
+ /*
+ * This is the first child of the field node, which is
+ * the name of the region. Get the parse node for the
+ * region -- which contains the length of the region.
+ */
+ OwningOp = Node->Op;
+ Op->Asl.Parent->Asl.ExtraValue =
+ ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
+
+ /* Examine the field access width */
+
+ switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
+ {
+ case AML_FIELD_ACCESS_ANY:
+ case AML_FIELD_ACCESS_BYTE:
+ case AML_FIELD_ACCESS_BUFFER:
+ default:
+
+ MinimumLength = 1;
+ break;
+
+ case AML_FIELD_ACCESS_WORD:
+
+ MinimumLength = 2;
+ break;
+
+ case AML_FIELD_ACCESS_DWORD:
+
+ MinimumLength = 4;
+ break;
+
+ case AML_FIELD_ACCESS_QWORD:
+
+ MinimumLength = 8;
+ break;
+ }
+
+ /*
+ * Is the region at least as big as the access width?
+ * Note: DataTableRegions have 0 length
+ */
+ if (((UINT32) OwningOp->Asl.Value.Integer) &&
+ ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
+ {
+ AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
+ }
+
+ /*
+ * Check EC/CMOS/SMBUS fields to make sure that the correct
+ * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
+ */
+ SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
+ switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
+ {
+ case ACPI_ADR_SPACE_EC:
+ case ACPI_ADR_SPACE_CMOS:
+ case ACPI_ADR_SPACE_GPIO:
+
+ if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
+ {
+ AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
+ }
+ break;
+
+ case ACPI_ADR_SPACE_SMBUS:
+ case ACPI_ADR_SPACE_IPMI:
+ case ACPI_ADR_SPACE_GSBUS:
+
+ if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
+ {
+ AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
+ }
+ break;
+
+ default:
+
+ /* Nothing to do for other address spaces */
+
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * This is one element of the field list. Check to make sure
+ * that it does not go beyond the end of the parent operation region.
+ *
+ * In the code below:
+ * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits)
+ * Op->Asl.ExtraValue - Field start offset (bits)
+ * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits)
+ * Op->Asl.Child->Asl.ExtraValue - Field access width (bits)
+ */
+ if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
+ {
+ XfCheckFieldRange (Op,
+ Op->Asl.Parent->Asl.ExtraValue,
+ Op->Asl.ExtraValue,
+ (UINT32) Op->Asl.Child->Asl.Value.Integer,
+ Op->Asl.Child->Asl.ExtraValue);
+ }
+ }
+ }
+
+ /* 5) Check for a connection object */
+#if 0
+ else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
+ {
+ return_ACPI_STATUS (Status);
+ }
+#endif
+
+ Op->Asl.Node = Node;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfNamespaceLocateEnd
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback used during cross reference. We only
+ * need to worry about scope management here.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+XfNamespaceLocateEnd (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
+
+
+ /* We are only interested in opcodes that have an associated name */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
+ if (!(OpInfo->Flags & AML_NAMED))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Not interested in name references, we did not open a scope for them */
+
+ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
+ (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
+ (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Pop the scope stack if necessary */
+
+ if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
+ {
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "%s: Popping scope for Op %p\n",
+ AcpiUtGetTypeName (OpInfo->ObjectType), Op));
+
+ (void) AcpiDsScopeStackPop (WalkState);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+#ifdef __UNDER_DEVELOPMENT
+/*******************************************************************************
+ *
+ * FUNCTION: XfIsObjectParental
+ *
+ * PARAMETERS: ChildOp - Op to be checked
+ * PossibleParentOp - Determine if this op is in the family
+ *
+ * RETURN: TRUE if ChildOp is a descendent of PossibleParentOp
+ *
+ * DESCRIPTION: Determine if an Op is a descendent of another Op. Used to
+ * detect if a method is declared within another method.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+XfIsObjectParental (
+ ACPI_PARSE_OBJECT *ChildOp,
+ ACPI_PARSE_OBJECT *PossibleParentOp)
+{
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ /* Search upwards through the tree for possible parent */
+
+ ParentOp = ChildOp;
+ while (ParentOp)
+ {
+ if (ParentOp == PossibleParentOp)
+ {
+ return (TRUE);
+ }
+
+ ParentOp = ParentOp->Asl.Parent;
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfGetParentMethod
+ *
+ * PARAMETERS: Op - Op to be checked
+ *
+ * RETURN: Op for parent method. NULL if object is not within a method.
+ *
+ * DESCRIPTION: Determine if an object is within a control method. Used to
+ * implement special rules for named references from within a
+ * control method.
+ *
+ * NOTE: It would be better to have the parser set a flag in the Op if possible.
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+XfGetParentMethod (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
+ {
+ return (NULL);
+ }
+
+ /* Walk upwards through the parse tree, up to the root if necessary */
+
+ ParentOp = Op;
+ while (ParentOp)
+ {
+ if (ParentOp->Asl.ParseOpcode == PARSEOP_METHOD)
+ {
+ return (ParentOp);
+ }
+
+ ParentOp = ParentOp->Asl.Parent;
+ }
+
+ /* Object is not within a method */
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: XfCheckIllegalReference
+ *
+ * PARAMETERS: Op - Op referring to the target
+ * TargetNode - Target of the reference
+ *
+ * RETURN: None. Emits error message for an illegal reference
+ *
+ * DESCRIPTION: Determine if a named reference is legal. A "named" reference
+ * is something like: Store(ABCD, ...), where ABCD is an AML
+ * Nameseg or Namepath.
+ *
+ * NOTE: Caller must ensure that the name Op is in fact a reference, and not
+ * an actual name declaration (creation of a named object).
+ *
+ ******************************************************************************/
+
+static void
+XfCheckIllegalReference (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *TargetNode)
+{
+ ACPI_PARSE_OBJECT *MethodOp1;
+ ACPI_PARSE_OBJECT *MethodOp2;
+ ACPI_PARSE_OBJECT *TargetOp;
+
+
+ /*
+ * Check for an illegal reference to a named object:
+ *
+ * 1) References from one control method to another, non-parent
+ * method are not allowed, they will fail at runtime.
+ *
+ * 2) Forward references within a control method are not allowed.
+ * AML interpreters use a one-pass parse of control methods
+ * so these forward references will fail at runtime.
+ */
+ TargetOp = TargetNode->Op;
+
+ MethodOp1 = XfGetParentMethod (Op);
+ MethodOp2 = XfGetParentMethod (TargetOp);
+
+ /* Are both objects within control method(s)? */
+
+ if (!MethodOp1 || !MethodOp2)
+ {
+ return;
+ }
+
+ /* Objects not in the same method? */
+
+ if (MethodOp1 != MethodOp2)
+ {
+ /*
+ * 1) Cross-method named reference
+ *
+ * This is OK if and only if the target reference is within in a
+ * method that is a parent of current method
+ */
+ if (!XfIsObjectParental (MethodOp1, MethodOp2))
+ {
+ AslError (ASL_ERROR, ASL_MSG_ILLEGAL_METHOD_REF, Op,
+ Op->Asl.ExternalName);
+ }
+ }
+
+ /*
+ * 2) Both reference and target are in the same method. Check if this is
+ * an (illegal) forward reference by examining the exact source code
+ * location of each (the referenced object and the object declaration).
+ * This is a bit nasty, yet effective.
+ */
+ else if (Op->Asl.LogicalByteOffset < TargetOp->Asl.LogicalByteOffset)
+ {
+ AslError (ASL_ERROR, ASL_MSG_ILLEGAL_FORWARD_REF, Op,
+ Op->Asl.ExternalName);
+ }
+
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompile.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompile.c
new file mode 100644
index 0000000000..506c4cd6c0
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompile.c
@@ -0,0 +1,677 @@
+/******************************************************************************
+ *
+ * Module Name: dtcompile.c - Front-end for data table compiler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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_DT_GLOBALS
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtcompile")
+
+static char VersionString[9];
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+DtInitialize (
+ void);
+
+static ACPI_STATUS
+DtCompileDataTable (
+ DT_FIELD **Field);
+
+static void
+DtInsertCompilerIds (
+ DT_FIELD *FieldList);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDoCompile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Main entry point for the data table compiler.
+ *
+ * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
+ * open at seek offset zero.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtDoCompile (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT8 Event;
+ DT_FIELD *FieldList;
+
+
+ /* Initialize globals */
+
+ Status = DtInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ printf ("Error during compiler initialization, 0x%X\n", Status);
+ return (Status);
+ }
+
+ /* Preprocessor */
+
+ if (Gbl_PreprocessFlag)
+ {
+ /* Preprocessor */
+
+ Event = UtBeginEvent ("Preprocess input file");
+ PrDoPreprocess ();
+ UtEndEvent (Event);
+
+ if (Gbl_PreprocessOnly)
+ {
+ return (AE_OK);
+ }
+ }
+
+ /*
+ * Scan the input file (file is already open) and
+ * build the parse tree
+ */
+ Event = UtBeginEvent ("Scan and parse input file");
+ FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
+ UtEndEvent (Event);
+
+ /* Did the parse tree get successfully constructed? */
+
+ if (!FieldList)
+ {
+ /* TBD: temporary error message. Msgs should come from function above */
+
+ DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
+ "Input file does not appear to be an ASL or data table source file");
+
+ Status = AE_ERROR;
+ goto CleanupAndExit;
+ }
+
+ Event = UtBeginEvent ("Compile parse tree");
+
+ /*
+ * Compile the parse tree
+ */
+ Status = DtCompileDataTable (&FieldList);
+ UtEndEvent (Event);
+
+ if (ACPI_FAILURE (Status))
+ {
+ /* TBD: temporary error message. Msgs should come from function above */
+
+ DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
+ "Could not compile input file");
+
+ goto CleanupAndExit;
+ }
+
+ /* Create/open the binary output file */
+
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
+ Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
+ if (ACPI_FAILURE (Status))
+ {
+ goto CleanupAndExit;
+ }
+
+ /* Write the binary, then the optional hex file */
+
+ DtOutputBinary (Gbl_RootTable);
+ HxDoHexOutput ();
+ DtWriteTableToListing ();
+
+CleanupAndExit:
+
+ AcpiUtDeleteCaches ();
+ DtDeleteCaches ();
+ CmCleanupAndExit ();
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize data table compiler globals. Enables multiple
+ * compiles per invocation.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+DtInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtInitGlobals ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Gbl_FieldList = NULL;
+ Gbl_RootTable = NULL;
+ Gbl_SubtableStack = NULL;
+
+ sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInsertCompilerIds
+ *
+ * PARAMETERS: FieldList - Current field list pointer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
+ * the original ACPI table header.
+ *
+ *****************************************************************************/
+
+static void
+DtInsertCompilerIds (
+ DT_FIELD *FieldList)
+{
+ DT_FIELD *Next;
+ UINT32 i;
+
+
+ /*
+ * Don't insert current compiler ID if requested. Used for compiler
+ * debug/validation only.
+ */
+ if (Gbl_UseOriginalCompilerId)
+ {
+ return;
+ }
+
+ /* Walk to the Compiler fields at the end of the header */
+
+ Next = FieldList;
+ for (i = 0; i < 7; i++)
+ {
+ Next = Next->Next;
+ }
+
+ Next->Value = ASL_CREATOR_ID;
+ Next->Flags = DT_FIELD_NOT_ALLOCATED;
+
+ Next = Next->Next;
+ Next->Value = VersionString;
+ Next->Flags = DT_FIELD_NOT_ALLOCATED;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileDataTable
+ *
+ * PARAMETERS: FieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Entry point to compile one data table
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+DtCompileDataTable (
+ DT_FIELD **FieldList)
+{
+ const ACPI_DMTABLE_DATA *TableData;
+ DT_SUBTABLE *Subtable;
+ char *Signature;
+ ACPI_TABLE_HEADER *AcpiTableHeader;
+ ACPI_STATUS Status;
+ DT_FIELD *RootField = *FieldList;
+
+
+ /* Verify that we at least have a table signature and save it */
+
+ Signature = DtGetFieldValue (*FieldList);
+ if (!Signature)
+ {
+ sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
+ DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
+ *FieldList, MsgBuffer);
+ return (AE_ERROR);
+ }
+
+ Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1);
+ strcpy (Gbl_Signature, Signature);
+
+ /*
+ * Handle tables that don't use the common ACPI table header structure.
+ * Currently, these are the FACS and RSDP. Also check for an OEMx table,
+ * these tables have user-defined contents.
+ */
+ if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
+ {
+ Status = DtCompileFacs (FieldList);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtSetTableLength ();
+ return (Status);
+ }
+ else if (ACPI_VALIDATE_RSDP_SIG (Signature))
+ {
+ Status = DtCompileRsdp (FieldList);
+ return (Status);
+ }
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
+ {
+ Status = DtCompileS3pt (FieldList);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtSetTableLength ();
+ return (Status);
+ }
+
+ /*
+ * All other tables must use the common ACPI table header. Insert the
+ * current iASL IDs (name, version), and compile the header now.
+ */
+ DtInsertCompilerIds (*FieldList);
+
+ Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
+ &Gbl_RootTable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtPushSubtable (Gbl_RootTable);
+
+ /* Validate the signature via the ACPI table list */
+
+ TableData = AcpiDmGetTableData (Signature);
+ if (!TableData || Gbl_CompileGeneric)
+ {
+ /* Unknown table signature and/or force generic compile */
+
+ DtCompileGeneric ((void **) FieldList, NULL, NULL);
+ goto FinishHeader;
+ }
+
+ /* Dispatch to per-table compile */
+
+ if (TableData->CmTableHandler)
+ {
+ /* Complex table, has a handler */
+
+ Status = TableData->CmTableHandler ((void **) FieldList);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else if (TableData->TableInfo)
+ {
+ /* Simple table, just walk the info table */
+
+ Subtable = NULL;
+ Status = DtCompileTable (FieldList, TableData->TableInfo,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (Gbl_RootTable, Subtable);
+ DtPopSubtable ();
+ }
+ else
+ {
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
+ "Missing table dispatch info");
+ return (AE_ERROR);
+ }
+
+FinishHeader:
+
+ /* Set the final table length and then the checksum */
+
+ DtSetTableLength ();
+ AcpiTableHeader = ACPI_CAST_PTR (
+ ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
+ DtSetTableChecksum (&AcpiTableHeader->Checksum);
+
+ DtDumpFieldList (RootField);
+ DtDumpSubtableList ();
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileTable
+ *
+ * PARAMETERS: Field - Current field list pointer
+ * Info - Info table for this ACPI table
+ * RetSubtable - Compile result of table
+ * Required - If this subtable must exist
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile a subtable
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileTable (
+ DT_FIELD **Field,
+ ACPI_DMTABLE_INFO *Info,
+ DT_SUBTABLE **RetSubtable,
+ BOOLEAN Required)
+{
+ DT_FIELD *LocalField;
+ UINT32 Length;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *InlineSubtable = NULL;
+ UINT32 FieldLength = 0;
+ UINT8 FieldType;
+ UINT8 *Buffer;
+ UINT8 *FlagBuffer = NULL;
+ char *String;
+ UINT32 CurrentFlagByteOffset = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ if (!Field || !*Field)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Ignore optional subtable if name does not match */
+
+ if ((Info->Flags & DT_OPTIONAL) &&
+ strcmp ((*Field)->Name, Info->Name))
+ {
+ *RetSubtable = NULL;
+ return (AE_OK);
+ }
+
+ Length = DtGetSubtableLength (*Field, Info);
+ if (Length == ASL_EOF)
+ {
+ return (AE_ERROR);
+ }
+
+ Subtable = UtSubtableCacheCalloc ();
+
+ if (Length > 0)
+ {
+ String = UtStringCacheCalloc (Length);
+ Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
+ }
+
+ Subtable->Length = Length;
+ Subtable->TotalLength = Length;
+ Buffer = Subtable->Buffer;
+
+ LocalField = *Field;
+ Subtable->Name = LocalField->Name;
+
+ /*
+ * Main loop walks the info table for this ACPI table or subtable
+ */
+ for (; Info->Name; Info++)
+ {
+ if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
+ {
+ continue;
+ }
+
+ if (!LocalField)
+ {
+ sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
+ Info->Name);
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
+ Status = AE_BAD_DATA;
+ goto Error;
+ }
+
+ /* Maintain table offsets */
+
+ LocalField->TableOffset = Gbl_CurrentTableOffset;
+ FieldLength = DtGetFieldLength (LocalField, Info);
+ Gbl_CurrentTableOffset += FieldLength;
+
+ FieldType = DtGetFieldType (Info);
+ Gbl_InputFieldCount++;
+
+ switch (FieldType)
+ {
+ case DT_FIELD_TYPE_FLAGS_INTEGER:
+ /*
+ * Start of the definition of a flags field.
+ * This master flags integer starts at value zero, in preparation
+ * to compile and insert the flag fields from the individual bits
+ */
+ LocalField = LocalField->Next;
+ *Field = LocalField;
+
+ FlagBuffer = Buffer;
+ CurrentFlagByteOffset = Info->Offset;
+ break;
+
+ case DT_FIELD_TYPE_FLAG:
+
+ /* Individual Flag field, can be multiple bits */
+
+ if (FlagBuffer)
+ {
+ /*
+ * We must increment the FlagBuffer when we have crossed
+ * into the next flags byte within the flags field
+ * of type DT_FIELD_TYPE_FLAGS_INTEGER.
+ */
+ FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
+ CurrentFlagByteOffset = Info->Offset;
+
+ DtCompileFlag (FlagBuffer, LocalField, Info);
+ }
+ else
+ {
+ /* TBD - this is an internal error */
+ }
+
+ LocalField = LocalField->Next;
+ *Field = LocalField;
+ break;
+
+ case DT_FIELD_TYPE_INLINE_SUBTABLE:
+ /*
+ * Recursion (one level max): compile GAS (Generic Address)
+ * or Notify in-line subtable
+ */
+ *Field = LocalField;
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_GAS:
+
+ Status = DtCompileTable (Field, AcpiDmTableInfoGas,
+ &InlineSubtable, TRUE);
+ break;
+
+ case ACPI_DMT_HESTNTFY:
+
+ Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
+ &InlineSubtable, TRUE);
+ break;
+
+ case ACPI_DMT_IORTMEM:
+
+ Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc,
+ &InlineSubtable, TRUE);
+ break;
+
+ default:
+ sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X",
+ Info->Opcode);
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
+ Status = AE_BAD_DATA;
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto Error;
+ }
+
+ DtSetSubtableLength (InlineSubtable);
+
+ memcpy (Buffer, InlineSubtable->Buffer, FieldLength);
+ LocalField = *Field;
+ break;
+
+ case DT_FIELD_TYPE_LABEL:
+
+ DtWriteFieldToListing (Buffer, LocalField, 0);
+ LocalField = LocalField->Next;
+ break;
+
+ default:
+
+ /* Normal case for most field types (Integer, String, etc.) */
+
+ DtCompileOneField (Buffer, LocalField,
+ FieldLength, FieldType, Info->Flags);
+
+ DtWriteFieldToListing (Buffer, LocalField, FieldLength);
+ LocalField = LocalField->Next;
+
+ if (Info->Flags & DT_LENGTH)
+ {
+ /* Field is an Integer that will contain a subtable length */
+
+ Subtable->LengthField = Buffer;
+ Subtable->SizeOfLengthField = FieldLength;
+ }
+ break;
+ }
+
+ Buffer += FieldLength;
+ }
+
+ *Field = LocalField;
+ *RetSubtable = Subtable;
+ return (AE_OK);
+
+Error:
+ ACPI_FREE (Subtable->Buffer);
+ ACPI_FREE (Subtable);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompilePadding
+ *
+ * PARAMETERS: Length - Padding field size
+ * RetSubtable - Compile result of table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile a subtable for padding purpose
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompilePadding (
+ UINT32 Length,
+ DT_SUBTABLE **RetSubtable)
+{
+ DT_SUBTABLE *Subtable;
+ /* UINT8 *Buffer; */
+ char *String;
+
+
+ Subtable = UtSubtableCacheCalloc ();
+
+ if (Length > 0)
+ {
+ String = UtStringCacheCalloc (Length);
+ Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
+ }
+
+ Subtable->Length = Length;
+ Subtable->TotalLength = Length;
+ /* Buffer = Subtable->Buffer; */
+
+ *RetSubtable = Subtable;
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompiler.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompiler.h
new file mode 100644
index 0000000000..be52b16961
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtcompiler.h
@@ -0,0 +1,627 @@
+/******************************************************************************
+ *
+ * Module Name: dtcompiler.h - header for data table compiler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 __DTCOMPILER_H__
+
+#ifndef _DTCOMPILER
+#define _DTCOMPILER
+
+#include <stdio.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define ASL_FIELD_CACHE_SIZE 512
+#define ASL_SUBTABLE_CACHE_SIZE 128
+
+
+#undef DT_EXTERN
+
+#ifdef _DECLARE_DT_GLOBALS
+#define DT_EXTERN
+#define DT_INIT_GLOBAL(a,b) (a)=(b)
+#else
+#define DT_EXTERN extern
+#define DT_INIT_GLOBAL(a,b) (a)
+#endif
+
+
+/* Types for individual fields (one per input line) */
+
+#define DT_FIELD_TYPE_STRING 0
+#define DT_FIELD_TYPE_INTEGER 1
+#define DT_FIELD_TYPE_BUFFER 2
+#define DT_FIELD_TYPE_PCI_PATH 3
+#define DT_FIELD_TYPE_FLAG 4
+#define DT_FIELD_TYPE_FLAGS_INTEGER 5
+#define DT_FIELD_TYPE_INLINE_SUBTABLE 6
+#define DT_FIELD_TYPE_UUID 7
+#define DT_FIELD_TYPE_UNICODE 8
+#define DT_FIELD_TYPE_DEVICE_PATH 9
+#define DT_FIELD_TYPE_LABEL 10
+
+
+/*
+ * Structure used for each individual field within an ACPI table
+ */
+typedef struct dt_field
+{
+ char *Name; /* Field name (from name : value) */
+ char *Value; /* Field value (from name : value) */
+ UINT32 StringLength;/* Length of Value */
+ struct dt_field *Next; /* Next field */
+ struct dt_field *NextLabel; /* If field is a label, next label */
+ UINT32 Line; /* Line number for this field */
+ UINT32 ByteOffset; /* Offset in source file for field */
+ UINT32 NameColumn; /* Start column for field name */
+ UINT32 Column; /* Start column for field value */
+ UINT32 TableOffset; /* Binary offset within ACPI table */
+ UINT8 Flags;
+
+} DT_FIELD;
+
+/* Flags for above */
+
+#define DT_FIELD_NOT_ALLOCATED 1
+
+
+/*
+ * Structure used for individual subtables within an ACPI table
+ */
+typedef struct dt_subtable
+{
+ struct dt_subtable *Parent;
+ struct dt_subtable *Child;
+ struct dt_subtable *Peer;
+ struct dt_subtable *StackTop;
+ UINT8 *Buffer;
+ UINT8 *LengthField;
+ char *Name;
+ UINT32 Length;
+ UINT32 TotalLength;
+ UINT32 SizeOfLengthField;
+ UINT16 Depth;
+ UINT8 Flags;
+
+} DT_SUBTABLE;
+
+
+/*
+ * Globals
+ */
+
+/* List of all field names and values from the input source */
+
+DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_FieldList, NULL);
+
+/* List of all compiled tables and subtables */
+
+DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_RootTable, NULL);
+
+/* Stack for subtables */
+
+DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableStack, NULL);
+
+/* List for defined labels */
+
+DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_LabelList, NULL);
+
+/* Current offset within the binary output table */
+
+DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_CurrentTableOffset, 0);
+
+/* Local caches */
+
+DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_SubtableCount, 0);
+DT_EXTERN ASL_CACHE_INFO DT_INIT_GLOBAL (*Gbl_SubtableCacheList, NULL);
+DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableCacheNext, NULL);
+DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableCacheLast, NULL);
+
+DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_FieldCount, 0);
+DT_EXTERN ASL_CACHE_INFO DT_INIT_GLOBAL (*Gbl_FieldCacheList, NULL);
+DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_FieldCacheNext, NULL);
+DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_FieldCacheLast, NULL);
+
+
+/* dtcompiler - main module */
+
+ACPI_STATUS
+DtCompileTable (
+ DT_FIELD **Field,
+ ACPI_DMTABLE_INFO *Info,
+ DT_SUBTABLE **RetSubtable,
+ BOOLEAN Required);
+
+ACPI_STATUS
+DtCompilePadding (
+ UINT32 Length,
+ DT_SUBTABLE **RetSubtable);
+
+
+/* dtio - binary and text input/output */
+
+UINT32
+DtGetNextLine (
+ FILE *Handle,
+ UINT32 Flags);
+
+/* Flags for DtGetNextLine */
+
+#define DT_ALLOW_MULTILINE_QUOTES 0x01
+
+
+DT_FIELD *
+DtScanFile (
+ FILE *Handle);
+
+void
+DtOutputBinary (
+ DT_SUBTABLE *RootTable);
+
+void
+DtDumpSubtableList (
+ void);
+
+void
+DtDumpFieldList (
+ DT_FIELD *Field);
+
+void
+DtWriteFieldToListing (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 Length);
+
+void
+DtWriteTableToListing (
+ void);
+
+
+/* dtsubtable - compile subtables */
+
+void
+DtCreateSubtable (
+ UINT8 *Buffer,
+ UINT32 Length,
+ DT_SUBTABLE **RetSubtable);
+
+UINT32
+DtGetSubtableLength (
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info);
+
+void
+DtSetSubtableLength (
+ DT_SUBTABLE *Subtable);
+
+void
+DtPushSubtable (
+ DT_SUBTABLE *Subtable);
+
+void
+DtPopSubtable (
+ void);
+
+DT_SUBTABLE *
+DtPeekSubtable (
+ void);
+
+void
+DtInsertSubtable (
+ DT_SUBTABLE *ParentTable,
+ DT_SUBTABLE *Subtable);
+
+DT_SUBTABLE *
+DtGetNextSubtable (
+ DT_SUBTABLE *ParentTable,
+ DT_SUBTABLE *ChildTable);
+
+DT_SUBTABLE *
+DtGetParentSubtable (
+ DT_SUBTABLE *Subtable);
+
+
+/* dtexpress - Integer expressions and labels */
+
+ACPI_STATUS
+DtResolveIntegerExpression (
+ DT_FIELD *Field,
+ UINT64 *ReturnValue);
+
+UINT64
+DtDoOperator (
+ UINT64 LeftValue,
+ UINT32 Operator,
+ UINT64 RightValue);
+
+UINT64
+DtResolveLabel (
+ char *LabelString);
+
+void
+DtDetectAllLabels (
+ DT_FIELD *FieldList);
+
+
+/* dtfield - Compile individual fields within a table */
+
+void
+DtCompileOneField (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength,
+ UINT8 Type,
+ UINT8 Flags);
+
+void
+DtCompileInteger (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength,
+ UINT8 Flags);
+
+UINT32
+DtCompileBuffer (
+ UINT8 *Buffer,
+ char *Value,
+ DT_FIELD *Field,
+ UINT32 ByteLength);
+
+void
+DtCompileFlag (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info);
+
+
+/* dtparser - lex/yacc files */
+
+UINT64
+DtEvaluateExpression (
+ char *ExprString);
+
+int
+DtInitLexer (
+ char *String);
+
+void
+DtTerminateLexer (
+ void);
+
+char *
+DtGetOpName (
+ UINT32 ParseOpcode);
+
+
+/* dtutils - Miscellaneous utilities */
+
+typedef
+void (*DT_WALK_CALLBACK) (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue);
+
+void
+DtWalkTableTree (
+ DT_SUBTABLE *StartTable,
+ DT_WALK_CALLBACK UserFunction,
+ void *Context,
+ void *ReturnValue);
+
+void
+DtError (
+ UINT8 Level,
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage);
+
+void
+DtNameError (
+ UINT8 Level,
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage);
+
+void
+DtFatal (
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage);
+
+ACPI_STATUS
+DtStrtoul64 (
+ char *String,
+ UINT64 *ReturnInteger);
+
+char*
+DtGetFieldValue (
+ DT_FIELD *Field);
+
+UINT8
+DtGetFieldType (
+ ACPI_DMTABLE_INFO *Info);
+
+UINT32
+DtGetBufferLength (
+ char *Buffer);
+
+UINT32
+DtGetFieldLength (
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info);
+
+void
+DtSetTableChecksum (
+ UINT8 *ChecksumPointer);
+
+void
+DtSetTableLength(
+ void);
+
+DT_SUBTABLE *
+UtSubtableCacheCalloc (
+ void);
+
+DT_FIELD *
+UtFieldCacheCalloc (
+ void);
+
+void
+DtDeleteCaches (
+ void);
+
+
+/* dttable - individual table compilation */
+
+ACPI_STATUS
+DtCompileFacs (
+ DT_FIELD **PFieldList);
+
+ACPI_STATUS
+DtCompileRsdp (
+ DT_FIELD **PFieldList);
+
+ACPI_STATUS
+DtCompileAsf (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileCpep (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileCsrt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileDbg2 (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileDmar (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileDrtm (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileEinj (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileErst (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileFadt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileFpdt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileGtdt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileHest (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileIort (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileIvrs (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileLpit (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileMadt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileMcfg (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileMpst (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileMsct (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileMtmr (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileNfit (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompilePmtt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompilePcct (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileRsdt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileS3pt (
+ DT_FIELD **PFieldList);
+
+ACPI_STATUS
+DtCompileSlic (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileSlit (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileSrat (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileStao (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileTcpa (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileUefi (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileVrtc (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileWdat (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileWpbt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileXsdt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompileGeneric (
+ void **PFieldList,
+ char *TermFieldName,
+ UINT32 *PFieldLength);
+
+ACPI_DMTABLE_INFO *
+DtGetGenericTableInfo (
+ char *Name);
+
+/* ACPI Table templates */
+
+extern const unsigned char TemplateAsf[];
+extern const unsigned char TemplateBoot[];
+extern const unsigned char TemplateBert[];
+extern const unsigned char TemplateBgrt[];
+extern const unsigned char TemplateCpep[];
+extern const unsigned char TemplateCsrt[];
+extern const unsigned char TemplateDbg2[];
+extern const unsigned char TemplateDbgp[];
+extern const unsigned char TemplateDmar[];
+extern const unsigned char TemplateDrtm[];
+extern const unsigned char TemplateEcdt[];
+extern const unsigned char TemplateEinj[];
+extern const unsigned char TemplateErst[];
+extern const unsigned char TemplateFadt[];
+extern const unsigned char TemplateFpdt[];
+extern const unsigned char TemplateGtdt[];
+extern const unsigned char TemplateHest[];
+extern const unsigned char TemplateHpet[];
+extern const unsigned char TemplateIort[];
+extern const unsigned char TemplateIvrs[];
+extern const unsigned char TemplateLpit[];
+extern const unsigned char TemplateMadt[];
+extern const unsigned char TemplateMcfg[];
+extern const unsigned char TemplateMchi[];
+extern const unsigned char TemplateMpst[];
+extern const unsigned char TemplateMsct[];
+extern const unsigned char TemplateMsdm[];
+extern const unsigned char TemplateMtmr[];
+extern const unsigned char TemplateNfit[];
+extern const unsigned char TemplatePcct[];
+extern const unsigned char TemplatePmtt[];
+extern const unsigned char TemplateRsdt[];
+extern const unsigned char TemplateS3pt[];
+extern const unsigned char TemplateSbst[];
+extern const unsigned char TemplateSlic[];
+extern const unsigned char TemplateSlit[];
+extern const unsigned char TemplateSpcr[];
+extern const unsigned char TemplateSpmi[];
+extern const unsigned char TemplateSrat[];
+extern const unsigned char TemplateStao[];
+extern const unsigned char TemplateTcpa[];
+extern const unsigned char TemplateTpm2[];
+extern const unsigned char TemplateUefi[];
+extern const unsigned char TemplateVrtc[];
+extern const unsigned char TemplateWaet[];
+extern const unsigned char TemplateWdat[];
+extern const unsigned char TemplateWddt[];
+extern const unsigned char TemplateWdrt[];
+extern const unsigned char TemplateWpbt[];
+extern const unsigned char TemplateXenv[];
+extern const unsigned char TemplateXsdt[];
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtexpress.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtexpress.c
new file mode 100644
index 0000000000..4316b791ac
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtexpress.c
@@ -0,0 +1,424 @@
+/******************************************************************************
+ *
+ * Module Name: dtexpress.c - Support for integer expressions and labels
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+#include "dtparser.y.h"
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtexpress")
+
+
+/* Local prototypes */
+
+static void
+DtInsertLabelField (
+ DT_FIELD *Field);
+
+static DT_FIELD *
+DtLookupLabel (
+ char *Name);
+
+/* Global used for errors during parse and related functions */
+
+DT_FIELD *Gbl_CurrentField;
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtResolveIntegerExpression
+ *
+ * PARAMETERS: Field - Field object with Integer expression
+ * ReturnValue - Where the integer is returned
+ *
+ * RETURN: Status, and the resolved 64-bit integer value
+ *
+ * DESCRIPTION: Resolve an integer expression to a single value. Supports
+ * both integer constants and labels.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtResolveIntegerExpression (
+ DT_FIELD *Field,
+ UINT64 *ReturnValue)
+{
+ UINT64 Result;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Full Integer expression: %s\n",
+ Field->Value);
+
+ Gbl_CurrentField = Field;
+
+ Result = DtEvaluateExpression (Field->Value);
+ *ReturnValue = Result;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDoOperator
+ *
+ * PARAMETERS: LeftValue - First 64-bit operand
+ * Operator - Parse token for the operator (EXPOP_*)
+ * RightValue - Second 64-bit operand
+ *
+ * RETURN: 64-bit result of the requested operation
+ *
+ * DESCRIPTION: Perform the various 64-bit integer math functions
+ *
+ *****************************************************************************/
+
+UINT64
+DtDoOperator (
+ UINT64 LeftValue,
+ UINT32 Operator,
+ UINT64 RightValue)
+{
+ UINT64 Result;
+
+
+ /* Perform the requested operation */
+
+ switch (Operator)
+ {
+ case EXPOP_ONES_COMPLIMENT:
+
+ Result = ~RightValue;
+ break;
+
+ case EXPOP_LOGICAL_NOT:
+
+ Result = !RightValue;
+ break;
+
+ case EXPOP_MULTIPLY:
+
+ Result = LeftValue * RightValue;
+ break;
+
+ case EXPOP_DIVIDE:
+
+ if (!RightValue)
+ {
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO,
+ Gbl_CurrentField, NULL);
+ return (0);
+ }
+ Result = LeftValue / RightValue;
+ break;
+
+ case EXPOP_MODULO:
+
+ if (!RightValue)
+ {
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO,
+ Gbl_CurrentField, NULL);
+ return (0);
+ }
+ Result = LeftValue % RightValue;
+ break;
+
+ case EXPOP_ADD:
+ Result = LeftValue + RightValue;
+ break;
+
+ case EXPOP_SUBTRACT:
+
+ Result = LeftValue - RightValue;
+ break;
+
+ case EXPOP_SHIFT_RIGHT:
+
+ Result = LeftValue >> RightValue;
+ break;
+
+ case EXPOP_SHIFT_LEFT:
+
+ Result = LeftValue << RightValue;
+ break;
+
+ case EXPOP_LESS:
+
+ Result = LeftValue < RightValue;
+ break;
+
+ case EXPOP_GREATER:
+
+ Result = LeftValue > RightValue;
+ break;
+
+ case EXPOP_LESS_EQUAL:
+
+ Result = LeftValue <= RightValue;
+ break;
+
+ case EXPOP_GREATER_EQUAL:
+
+ Result = LeftValue >= RightValue;
+ break;
+
+ case EXPOP_EQUAL:
+
+ Result = LeftValue == RightValue;
+ break;
+
+ case EXPOP_NOT_EQUAL:
+
+ Result = LeftValue != RightValue;
+ break;
+
+ case EXPOP_AND:
+
+ Result = LeftValue & RightValue;
+ break;
+
+ case EXPOP_XOR:
+
+ Result = LeftValue ^ RightValue;
+ break;
+
+ case EXPOP_OR:
+
+ Result = LeftValue | RightValue;
+ break;
+
+ case EXPOP_LOGICAL_AND:
+
+ Result = LeftValue && RightValue;
+ break;
+
+ case EXPOP_LOGICAL_OR:
+
+ Result = LeftValue || RightValue;
+ break;
+
+ default:
+
+ /* Unknown operator */
+
+ DtFatal (ASL_MSG_INVALID_EXPRESSION,
+ Gbl_CurrentField, NULL);
+ return (0);
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "IntegerEval: (%8.8X%8.8X %s %8.8X%8.8X) = %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (LeftValue),
+ DtGetOpName (Operator),
+ ACPI_FORMAT_UINT64 (RightValue),
+ ACPI_FORMAT_UINT64 (Result));
+
+ return (Result);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtResolveLabel
+ *
+ * PARAMETERS: LabelString - Contains the label
+ *
+ * RETURN: Table offset associated with the label
+ *
+ * DESCRIPTION: Lookup a lable and return its value.
+ *
+ *****************************************************************************/
+
+UINT64
+DtResolveLabel (
+ char *LabelString)
+{
+ DT_FIELD *LabelField;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Resolve Label: %s\n", LabelString);
+
+ /* Resolve a label reference to an integer (table offset) */
+
+ if (*LabelString != '$')
+ {
+ return (0);
+ }
+
+ LabelField = DtLookupLabel (LabelString);
+ if (!LabelField)
+ {
+ DtError (ASL_ERROR, ASL_MSG_UNKNOWN_LABEL,
+ Gbl_CurrentField, LabelString);
+ return (0);
+ }
+
+ /* All we need from the label is the offset in the table */
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Resolved Label: 0x%8.8X\n",
+ LabelField->TableOffset);
+
+ return (LabelField->TableOffset);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDetectAllLabels
+ *
+ * PARAMETERS: FieldList - Field object at start of generic list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Detect all labels in a list of "generic" opcodes (such as
+ * a UEFI table.) and insert them into the global label list.
+ *
+ *****************************************************************************/
+
+void
+DtDetectAllLabels (
+ DT_FIELD *FieldList)
+{
+ ACPI_DMTABLE_INFO *Info;
+ DT_FIELD *GenericField;
+ UINT32 TableOffset;
+
+
+ TableOffset = Gbl_CurrentTableOffset;
+ GenericField = FieldList;
+
+ /*
+ * Process all "Label:" fields within the parse tree. We need
+ * to know the offsets for all labels before we can compile
+ * the parse tree in order to handle forward references. Traverse
+ * tree and get/set all field lengths of all operators in order to
+ * determine the label offsets.
+ */
+ while (GenericField)
+ {
+ Info = DtGetGenericTableInfo (GenericField->Name);
+ if (Info)
+ {
+ /* Maintain table offsets */
+
+ GenericField->TableOffset = TableOffset;
+ TableOffset += DtGetFieldLength (GenericField, Info);
+
+ /* Insert all labels in the global label list */
+
+ if (Info->Opcode == ACPI_DMT_LABEL)
+ {
+ DtInsertLabelField (GenericField);
+ }
+ }
+
+ GenericField = GenericField->Next;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInsertLabelField
+ *
+ * PARAMETERS: Field - Field object with Label to be inserted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a label field into the global label list
+ *
+ *****************************************************************************/
+
+static void
+DtInsertLabelField (
+ DT_FIELD *Field)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "DtInsertLabelField: Found Label : %s at output table offset %X\n",
+ Field->Value, Field->TableOffset);
+
+ Field->NextLabel = Gbl_LabelList;
+ Gbl_LabelList = Field;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtLookupLabel
+ *
+ * PARAMETERS: Name - Label to be resolved
+ *
+ * RETURN: Field object associated with the label
+ *
+ * DESCRIPTION: Lookup a label in the global label list. Used during the
+ * resolution of integer expressions.
+ *
+ *****************************************************************************/
+
+static DT_FIELD *
+DtLookupLabel (
+ char *Name)
+{
+ DT_FIELD *LabelField;
+
+
+ /* Skip a leading $ */
+
+ if (*Name == '$')
+ {
+ Name++;
+ }
+
+ /* Search global list */
+
+ LabelField = Gbl_LabelList;
+ while (LabelField)
+ {
+ if (!strcmp (Name, LabelField->Value))
+ {
+ return (LabelField);
+ }
+ LabelField = LabelField->NextLabel;
+ }
+
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtfield.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtfield.c
new file mode 100644
index 0000000000..621636c937
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtfield.c
@@ -0,0 +1,586 @@
+/******************************************************************************
+ *
+ * Module Name: dtfield.c - Code generation for individual source fields
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtfield")
+
+
+/* Local prototypes */
+
+static void
+DtCompileString (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength);
+
+static void
+DtCompileUnicode (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength);
+
+static ACPI_STATUS
+DtCompileUuid (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength);
+
+static char *
+DtNormalizeBuffer (
+ char *Buffer,
+ UINT32 *Count);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileOneField
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - Field to be compiled
+ * ByteLength - Byte length of the field
+ * Type - Field type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Compile a field value to binary
+ *
+ *****************************************************************************/
+
+void
+DtCompileOneField (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength,
+ UINT8 Type,
+ UINT8 Flags)
+{
+ ACPI_STATUS Status;
+
+ switch (Type)
+ {
+ case DT_FIELD_TYPE_INTEGER:
+
+ DtCompileInteger (Buffer, Field, ByteLength, Flags);
+ break;
+
+ case DT_FIELD_TYPE_STRING:
+
+ DtCompileString (Buffer, Field, ByteLength);
+ break;
+
+ case DT_FIELD_TYPE_UUID:
+
+ Status = DtCompileUuid (Buffer, Field, ByteLength);
+ if (ACPI_SUCCESS (Status))
+ {
+ break;
+ }
+
+ /* Fall through. */
+
+ case DT_FIELD_TYPE_BUFFER:
+
+ DtCompileBuffer (Buffer, Field->Value, Field, ByteLength);
+ break;
+
+ case DT_FIELD_TYPE_UNICODE:
+
+ DtCompileUnicode (Buffer, Field, ByteLength);
+ break;
+
+ case DT_FIELD_TYPE_DEVICE_PATH:
+
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type");
+ break;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileString
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - String to be copied to buffer
+ * ByteLength - Maximum length of string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Copy string to the buffer
+ *
+ *****************************************************************************/
+
+static void
+DtCompileString (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength)
+{
+ UINT32 Length;
+
+
+ Length = strlen (Field->Value);
+
+ /* Check if the string is too long for the field */
+
+ if (Length > ByteLength)
+ {
+ sprintf (MsgBuffer, "Maximum %u characters", ByteLength);
+ DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, MsgBuffer);
+ Length = ByteLength;
+ }
+
+ memcpy (Buffer, Field->Value, Length);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileUnicode
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - String to be copied to buffer
+ * ByteLength - Maximum length of string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert ASCII string to Unicode string
+ *
+ * Note: The Unicode string is 16 bits per character, no leading signature,
+ * with a 16-bit terminating NULL.
+ *
+ *****************************************************************************/
+
+static void
+DtCompileUnicode (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength)
+{
+ UINT32 Count;
+ UINT32 i;
+ char *AsciiString;
+ UINT16 *UnicodeString;
+
+
+ AsciiString = Field->Value;
+ UnicodeString = (UINT16 *) Buffer;
+ Count = strlen (AsciiString) + 1;
+
+ /* Convert to Unicode string (including null terminator) */
+
+ for (i = 0; i < Count; i++)
+ {
+ UnicodeString[i] = (UINT16) AsciiString[i];
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtCompileUuid
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - String to be copied to buffer
+ * ByteLength - Maximum length of string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert UUID string to 16-byte buffer
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+DtCompileUuid (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength)
+{
+ char *InString;
+ ACPI_STATUS Status;
+
+
+ InString = Field->Value;
+
+ Status = AuValidateUuid (InString);
+ if (ACPI_FAILURE (Status))
+ {
+ sprintf (MsgBuffer, "%s", Field->Value);
+ DtNameError (ASL_ERROR, ASL_MSG_INVALID_UUID, Field, MsgBuffer);
+ }
+ else
+ {
+ AcpiUtConvertStringToUuid (InString, Buffer);
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileInteger
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - Field obj with Integer to be compiled
+ * ByteLength - Byte length of the integer
+ * Flags - Additional compile info
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Compile an integer. Supports integer expressions with C-style
+ * operators.
+ *
+ *****************************************************************************/
+
+void
+DtCompileInteger (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 ByteLength,
+ UINT8 Flags)
+{
+ UINT64 Value;
+ UINT64 MaxValue;
+ ACPI_STATUS Status;
+
+
+ /* Output buffer byte length must be in range 1-8 */
+
+ if ((ByteLength > 8) || (ByteLength == 0))
+ {
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, Field,
+ "Invalid internal Byte length");
+ return;
+ }
+
+ /* Resolve integer expression to a single integer value */
+
+ Status = DtResolveIntegerExpression (Field, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /*
+ * Ensure that reserved fields are set properly. Note: uses
+ * the DT_NON_ZERO flag to indicate that the reserved value
+ * must be exactly one. Otherwise, the value must be zero.
+ * This is sufficient for now.
+ */
+
+ /* TBD: Should use a flag rather than compare "Reserved" */
+
+ if (!strcmp (Field->Name, "Reserved"))
+ {
+ if (Flags & DT_NON_ZERO)
+ {
+ if (Value != 1)
+ {
+ DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
+ "Must be one, setting to one");
+ Value = 1;
+ }
+ }
+ else if (Value != 0)
+ {
+ DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
+ "Must be zero, setting to zero");
+ Value = 0;
+ }
+ }
+
+ /* Check if the value must be non-zero */
+
+ else if ((Flags & DT_NON_ZERO) && (Value == 0))
+ {
+ DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL);
+ }
+
+ /*
+ * Generate the maximum value for the data type (ByteLength)
+ * Note: construct chosen for maximum portability
+ */
+ MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8));
+
+ /* Validate that the input value is within range of the target */
+
+ if (Value > MaxValue)
+ {
+ sprintf (MsgBuffer, "%8.8X%8.8X - max %u bytes",
+ ACPI_FORMAT_UINT64 (Value), ByteLength);
+ DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
+ }
+
+ memcpy (Buffer, &Value, ByteLength);
+ return;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtNormalizeBuffer
+ *
+ * PARAMETERS: Buffer - Input buffer
+ * Count - Output the count of hex number in
+ * the Buffer
+ *
+ * RETURN: The normalized buffer, freed by caller
+ *
+ * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized
+ * to 1A 2B 3C 4D
+ *
+ *****************************************************************************/
+
+static char *
+DtNormalizeBuffer (
+ char *Buffer,
+ UINT32 *Count)
+{
+ char *NewBuffer;
+ char *TmpBuffer;
+ UINT32 BufferCount = 0;
+ BOOLEAN Separator = TRUE;
+ char c;
+
+
+ NewBuffer = UtLocalCalloc (strlen (Buffer) + 1);
+ TmpBuffer = NewBuffer;
+
+ while ((c = *Buffer++))
+ {
+ switch (c)
+ {
+ /* Valid separators */
+
+ case '[':
+ case ']':
+ case ' ':
+ case ',':
+
+ Separator = TRUE;
+ break;
+
+ default:
+
+ if (Separator)
+ {
+ /* Insert blank as the standard separator */
+
+ if (NewBuffer[0])
+ {
+ *TmpBuffer++ = ' ';
+ BufferCount++;
+ }
+
+ Separator = FALSE;
+ }
+
+ *TmpBuffer++ = c;
+ break;
+ }
+ }
+
+ *Count = BufferCount + 1;
+ return (NewBuffer);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileBuffer
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * StringValue - Integer list to be compiled
+ * Field - Current field object
+ * ByteLength - Byte length of the integer list
+ *
+ * RETURN: Count of remaining data in the input list
+ *
+ * DESCRIPTION: Compile and pack an integer list, for example
+ * "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
+ *
+ *****************************************************************************/
+
+UINT32
+DtCompileBuffer (
+ UINT8 *Buffer,
+ char *StringValue,
+ DT_FIELD *Field,
+ UINT32 ByteLength)
+{
+ ACPI_STATUS Status;
+ char Hex[3];
+ UINT64 Value;
+ UINT32 i;
+ UINT32 Count;
+
+
+ /* Allow several different types of value separators */
+
+ StringValue = DtNormalizeBuffer (StringValue, &Count);
+
+ Hex[2] = 0;
+ for (i = 0; i < Count; i++)
+ {
+ /* Each element of StringValue is three chars */
+
+ Hex[0] = StringValue[(3 * i)];
+ Hex[1] = StringValue[(3 * i) + 1];
+
+ /* Convert one hex byte */
+
+ Value = 0;
+ Status = DtStrtoul64 (Hex, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, MsgBuffer);
+ goto Exit;
+ }
+
+ Buffer[i] = (UINT8) Value;
+ }
+
+Exit:
+ ACPI_FREE (StringValue);
+ return (ByteLength - Count);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileFlag
+ *
+ * PARAMETERS: Buffer - Output buffer
+ * Field - Field to be compiled
+ * Info - Flag info
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Compile a flag
+ *
+ *****************************************************************************/
+
+void
+DtCompileFlag (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info)
+{
+ UINT64 Value = 0;
+ UINT32 BitLength = 1;
+ UINT8 BitPosition = 0;
+ ACPI_STATUS Status;
+
+
+ Status = DtStrtoul64 (Field->Value, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL);
+ }
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_FLAG0:
+ case ACPI_DMT_FLAG1:
+ case ACPI_DMT_FLAG2:
+ case ACPI_DMT_FLAG3:
+ case ACPI_DMT_FLAG4:
+ case ACPI_DMT_FLAG5:
+ case ACPI_DMT_FLAG6:
+ case ACPI_DMT_FLAG7:
+
+ BitPosition = Info->Opcode;
+ BitLength = 1;
+ break;
+
+ case ACPI_DMT_FLAGS0:
+
+ BitPosition = 0;
+ BitLength = 2;
+ break;
+
+
+ case ACPI_DMT_FLAGS1:
+
+ BitPosition = 1;
+ BitLength = 2;
+ break;
+
+
+ case ACPI_DMT_FLAGS2:
+
+ BitPosition = 2;
+ BitLength = 2;
+ break;
+
+ case ACPI_DMT_FLAGS4:
+
+ BitPosition = 4;
+ BitLength = 2;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode");
+ break;
+ }
+
+ /* Check range of the input flag value */
+
+ if (Value >= ((UINT64) 1 << BitLength))
+ {
+ sprintf (MsgBuffer, "Maximum %u bit", BitLength);
+ DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, MsgBuffer);
+ Value = 0;
+ }
+
+ *Buffer |= (UINT8) (Value << BitPosition);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtio.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtio.c
new file mode 100644
index 0000000000..fed99250ad
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtio.c
@@ -0,0 +1,1144 @@
+/******************************************************************************
+ *
+ * Module Name: dtio.c - File I/O support for data table compiler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtio")
+
+
+/* Local prototypes */
+
+static char *
+DtTrim (
+ char *String);
+
+static void
+DtLinkField (
+ DT_FIELD *Field);
+
+static ACPI_STATUS
+DtParseLine (
+ char *LineBuffer,
+ UINT32 Line,
+ UINT32 Offset);
+
+static void
+DtWriteBinary (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue);
+
+static void
+DtDumpBuffer (
+ UINT32 FileId,
+ UINT8 *Buffer,
+ UINT32 Offset,
+ UINT32 Length);
+
+static void
+DtDumpSubtableInfo (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue);
+
+static void
+DtDumpSubtableTree (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue);
+
+
+/* States for DtGetNextLine */
+
+#define DT_NORMAL_TEXT 0
+#define DT_START_QUOTED_STRING 1
+#define DT_START_COMMENT 2
+#define DT_SLASH_ASTERISK_COMMENT 3
+#define DT_SLASH_SLASH_COMMENT 4
+#define DT_END_COMMENT 5
+#define DT_MERGE_LINES 6
+#define DT_ESCAPE_SEQUENCE 7
+
+static UINT32 Gbl_NextLineOffset;
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtTrim
+ *
+ * PARAMETERS: String - Current source code line to trim
+ *
+ * RETURN: Trimmed line. Must be freed by caller.
+ *
+ * DESCRIPTION: Trim left and right spaces
+ *
+ *****************************************************************************/
+
+static char *
+DtTrim (
+ char *String)
+{
+ char *Start;
+ char *End;
+ char *ReturnString;
+ ACPI_SIZE Length;
+
+
+ /* Skip lines that start with a space */
+
+ if (!strcmp (String, " "))
+ {
+ ReturnString = UtStringCacheCalloc (1);
+ return (ReturnString);
+ }
+
+ /* Setup pointers to start and end of input string */
+
+ Start = String;
+ End = String + strlen (String) - 1;
+
+ /* Find first non-whitespace character */
+
+ while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
+ {
+ Start++;
+ }
+
+ /* Find last non-space character */
+
+ while (End >= Start)
+ {
+ if (*End == '\r' || *End == '\n')
+ {
+ End--;
+ continue;
+ }
+
+ if (*End != ' ')
+ {
+ break;
+ }
+
+ End--;
+ }
+
+ /* Remove any quotes around the string */
+
+ if (*Start == '\"')
+ {
+ Start++;
+ }
+ if (*End == '\"')
+ {
+ End--;
+ }
+
+ /* Create the trimmed return string */
+
+ Length = ACPI_PTR_DIFF (End, Start) + 1;
+ ReturnString = UtStringCacheCalloc (Length + 1);
+ if (strlen (Start))
+ {
+ strncpy (ReturnString, Start, Length);
+ }
+
+ ReturnString[Length] = 0;
+ return (ReturnString);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtLinkField
+ *
+ * PARAMETERS: Field - New field object to link
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Link one field name and value to the list
+ *
+ *****************************************************************************/
+
+static void
+DtLinkField (
+ DT_FIELD *Field)
+{
+ DT_FIELD *Prev;
+ DT_FIELD *Next;
+
+
+ Prev = Next = Gbl_FieldList;
+
+ while (Next)
+ {
+ Prev = Next;
+ Next = Next->Next;
+ }
+
+ if (Prev)
+ {
+ Prev->Next = Field;
+ }
+ else
+ {
+ Gbl_FieldList = Field;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtParseLine
+ *
+ * PARAMETERS: LineBuffer - Current source code line
+ * Line - Current line number in the source
+ * Offset - Current byte offset of the line
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse one source line
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+DtParseLine (
+ char *LineBuffer,
+ UINT32 Line,
+ UINT32 Offset)
+{
+ char *Start;
+ char *End;
+ char *TmpName;
+ char *TmpValue;
+ char *Name;
+ char *Value;
+ char *Colon;
+ UINT32 Length;
+ DT_FIELD *Field;
+ UINT32 Column;
+ UINT32 NameColumn;
+ BOOLEAN IsNullString = FALSE;
+
+
+ if (!LineBuffer)
+ {
+ return (AE_OK);
+ }
+
+ /* All lines after "Raw Table Data" are ingored */
+
+ if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
+ {
+ return (AE_NOT_FOUND);
+ }
+
+ Colon = strchr (LineBuffer, ':');
+ if (!Colon)
+ {
+ return (AE_OK);
+ }
+
+ Start = LineBuffer;
+ End = Colon;
+
+ while (Start < Colon)
+ {
+ if (*Start == '[')
+ {
+ /* Found left bracket, go to the right bracket */
+
+ while (Start < Colon && *Start != ']')
+ {
+ Start++;
+ }
+ }
+ else if (*Start != ' ')
+ {
+ break;
+ }
+
+ Start++;
+ }
+
+ /*
+ * There are two column values. One for the field name,
+ * and one for the field value.
+ */
+ Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
+ NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
+
+ Length = ACPI_PTR_DIFF (End, Start);
+
+ TmpName = UtLocalCalloc (Length + 1);
+ strncpy (TmpName, Start, Length);
+ Name = DtTrim (TmpName);
+ ACPI_FREE (TmpName);
+
+ Start = End = (Colon + 1);
+ while (*End)
+ {
+ /* Found left quotation, go to the right quotation and break */
+
+ if (*End == '"')
+ {
+ End++;
+
+ /* Check for an explicit null string */
+
+ if (*End == '"')
+ {
+ IsNullString = TRUE;
+ }
+ while (*End && (*End != '"'))
+ {
+ End++;
+ }
+
+ End++;
+ break;
+ }
+
+ /*
+ * Special "comment" fields at line end, ignore them.
+ * Note: normal slash-slash and slash-asterisk comments are
+ * stripped already by the DtGetNextLine parser.
+ *
+ * TBD: Perhaps DtGetNextLine should parse the following type
+ * of comments also.
+ */
+ if (*End == '[')
+ {
+ End--;
+ break;
+ }
+ End++;
+ }
+
+ Length = ACPI_PTR_DIFF (End, Start);
+ TmpValue = UtLocalCalloc (Length + 1);
+
+ strncpy (TmpValue, Start, Length);
+ Value = DtTrim (TmpValue);
+ ACPI_FREE (TmpValue);
+
+ /* Create a new field object only if we have a valid value field */
+
+ if ((Value && *Value) || IsNullString)
+ {
+ Field = UtFieldCacheCalloc ();
+ Field->Name = Name;
+ Field->Value = Value;
+ Field->Line = Line;
+ Field->ByteOffset = Offset;
+ Field->NameColumn = NameColumn;
+ Field->Column = Column;
+ Field->StringLength = Length;
+
+ DtLinkField (Field);
+ }
+ /* Else -- Ignore this field, it has no valid data */
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetNextLine
+ *
+ * PARAMETERS: Handle - Open file handle for the source file
+ *
+ * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
+ *
+ * DESCRIPTION: Get the next valid source line. Removes all comments.
+ * Ignores empty lines.
+ *
+ * Handles both slash-asterisk and slash-slash comments.
+ * Also, quoted strings, but no escapes within.
+ *
+ * Line is returned in Gbl_CurrentLineBuffer.
+ * Line number in original file is returned in Gbl_CurrentLineNumber.
+ *
+ *****************************************************************************/
+
+UINT32
+DtGetNextLine (
+ FILE *Handle,
+ UINT32 Flags)
+{
+ BOOLEAN LineNotAllBlanks = FALSE;
+ UINT32 State = DT_NORMAL_TEXT;
+ UINT32 CurrentLineOffset;
+ UINT32 i;
+ int c;
+
+
+ memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
+ for (i = 0; ;)
+ {
+ /*
+ * If line is too long, expand the line buffers. Also increases
+ * Gbl_LineBufferSize.
+ */
+ if (i >= Gbl_LineBufferSize)
+ {
+ UtExpandLineBuffers ();
+ }
+
+ c = getc (Handle);
+ if (c == EOF)
+ {
+ switch (State)
+ {
+ case DT_START_QUOTED_STRING:
+ case DT_SLASH_ASTERISK_COMMENT:
+
+ AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Standalone EOF is OK */
+
+ if (i == 0)
+ {
+ return (ASL_EOF);
+ }
+
+ /*
+ * Received an EOF in the middle of a line. Terminate the
+ * line with a newline. The next call to this function will
+ * return a standalone EOF. Thus, the upper parsing software
+ * never has to deal with an EOF within a valid line (or
+ * the last line does not get tossed on the floor.)
+ */
+ c = '\n';
+ State = DT_NORMAL_TEXT;
+ }
+
+ switch (State)
+ {
+ case DT_NORMAL_TEXT:
+
+ /* Normal text, insert char into line buffer */
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ switch (c)
+ {
+ case '/':
+
+ State = DT_START_COMMENT;
+ break;
+
+ case '"':
+
+ State = DT_START_QUOTED_STRING;
+ LineNotAllBlanks = TRUE;
+ i++;
+ break;
+
+ case '\\':
+ /*
+ * The continuation char MUST be last char on this line.
+ * Otherwise, it will be assumed to be a valid ASL char.
+ */
+ State = DT_MERGE_LINES;
+ break;
+
+ case '\n':
+
+ CurrentLineOffset = Gbl_NextLineOffset;
+ Gbl_NextLineOffset = (UINT32) ftell (Handle);
+ Gbl_CurrentLineNumber++;
+
+ /*
+ * Exit if line is complete. Ignore empty lines (only \n)
+ * or lines that contain nothing but blanks.
+ */
+ if ((i != 0) && LineNotAllBlanks)
+ {
+ if ((i + 1) >= Gbl_LineBufferSize)
+ {
+ UtExpandLineBuffers ();
+ }
+
+ Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
+ return (CurrentLineOffset);
+ }
+
+ /* Toss this line and start a new one */
+
+ i = 0;
+ LineNotAllBlanks = FALSE;
+ break;
+
+ default:
+
+ if (c != ' ')
+ {
+ LineNotAllBlanks = TRUE;
+ }
+
+ i++;
+ break;
+ }
+ break;
+
+ case DT_START_QUOTED_STRING:
+
+ /* Insert raw chars until end of quoted string */
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ i++;
+
+ switch (c)
+ {
+ case '"':
+
+ State = DT_NORMAL_TEXT;
+ break;
+
+ case '\\':
+
+ State = DT_ESCAPE_SEQUENCE;
+ break;
+
+ case '\n':
+
+ if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
+ {
+ AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n",
+ Gbl_CurrentLineNumber++);
+ State = DT_NORMAL_TEXT;
+ }
+ break;
+
+ default: /* Get next character */
+
+ break;
+ }
+ break;
+
+ case DT_ESCAPE_SEQUENCE:
+
+ /* Just copy the escaped character. TBD: sufficient for table compiler? */
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ i++;
+ State = DT_START_QUOTED_STRING;
+ break;
+
+ case DT_START_COMMENT:
+
+ /* Open comment if this character is an asterisk or slash */
+
+ switch (c)
+ {
+ case '*':
+
+ State = DT_SLASH_ASTERISK_COMMENT;
+ break;
+
+ case '/':
+
+ State = DT_SLASH_SLASH_COMMENT;
+ break;
+
+ default: /* Not a comment */
+
+ i++; /* Save the preceding slash */
+ if (i >= Gbl_LineBufferSize)
+ {
+ UtExpandLineBuffers ();
+ }
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ i++;
+ State = DT_NORMAL_TEXT;
+ break;
+ }
+ break;
+
+ case DT_SLASH_ASTERISK_COMMENT:
+
+ /* Ignore chars until an asterisk-slash is found */
+
+ switch (c)
+ {
+ case '\n':
+
+ Gbl_NextLineOffset = (UINT32) ftell (Handle);
+ Gbl_CurrentLineNumber++;
+ break;
+
+ case '*':
+
+ State = DT_END_COMMENT;
+ break;
+
+ default:
+
+ break;
+ }
+ break;
+
+ case DT_SLASH_SLASH_COMMENT:
+
+ /* Ignore chars until end-of-line */
+
+ if (c == '\n')
+ {
+ /* We will exit via the NORMAL_TEXT path */
+
+ ungetc (c, Handle);
+ State = DT_NORMAL_TEXT;
+ }
+ break;
+
+ case DT_END_COMMENT:
+
+ /* End comment if this char is a slash */
+
+ switch (c)
+ {
+ case '/':
+
+ State = DT_NORMAL_TEXT;
+ break;
+
+ case '\n':
+
+ CurrentLineOffset = Gbl_NextLineOffset;
+ Gbl_NextLineOffset = (UINT32) ftell (Handle);
+ Gbl_CurrentLineNumber++;
+ break;
+
+ case '*':
+
+ /* Consume all adjacent asterisks */
+ break;
+
+ default:
+
+ State = DT_SLASH_ASTERISK_COMMENT;
+ break;
+ }
+ break;
+
+ case DT_MERGE_LINES:
+
+ if (c != '\n')
+ {
+ /*
+ * This is not a continuation backslash, it is a normal
+ * normal ASL backslash - for example: Scope(\_SB_)
+ */
+ i++; /* Keep the backslash that is already in the buffer */
+
+ ungetc (c, Handle);
+ State = DT_NORMAL_TEXT;
+ }
+ else
+ {
+ /*
+ * This is a continuation line -- a backlash followed
+ * immediately by a newline. Insert a space between the
+ * lines (overwrite the backslash)
+ */
+ Gbl_CurrentLineBuffer[i] = ' ';
+ i++;
+
+ /* Ignore newline, this will merge the lines */
+
+ CurrentLineOffset = Gbl_NextLineOffset;
+ Gbl_NextLineOffset = (UINT32) ftell (Handle);
+ Gbl_CurrentLineNumber++;
+ State = DT_NORMAL_TEXT;
+ }
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
+ return (ASL_EOF);
+ }
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtScanFile
+ *
+ * PARAMETERS: Handle - Open file handle for the source file
+ *
+ * RETURN: Pointer to start of the constructed parse tree.
+ *
+ * DESCRIPTION: Scan source file, link all field names and values
+ * to the global parse tree: Gbl_FieldList
+ *
+ *****************************************************************************/
+
+DT_FIELD *
+DtScanFile (
+ FILE *Handle)
+{
+ ACPI_STATUS Status;
+ UINT32 Offset;
+
+
+ ACPI_FUNCTION_NAME (DtScanFile);
+
+
+ /* Get the file size */
+
+ Gbl_InputByteCount = CmGetFileSize (Handle);
+ if (Gbl_InputByteCount == ACPI_UINT32_MAX)
+ {
+ AslAbort ();
+ }
+
+ Gbl_CurrentLineNumber = 0;
+ Gbl_CurrentLineOffset = 0;
+ Gbl_NextLineOffset = 0;
+
+ /* Scan line-by-line */
+
+ while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
+ Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
+
+ Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset);
+ if (Status == AE_NOT_FOUND)
+ {
+ break;
+ }
+ }
+
+ /* Dump the parse tree if debug enabled */
+
+ DtDumpFieldList (Gbl_FieldList);
+ return (Gbl_FieldList);
+}
+
+
+/*
+ * Output functions
+ */
+
+/******************************************************************************
+ *
+ * FUNCTION: DtWriteBinary
+ *
+ * PARAMETERS: DT_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write one subtable of a binary ACPI table
+ *
+ *****************************************************************************/
+
+static void
+DtWriteBinary (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue)
+{
+
+ FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtOutputBinary
+ *
+ * PARAMETERS:
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write entire binary ACPI table (result of compilation)
+ *
+ *****************************************************************************/
+
+void
+DtOutputBinary (
+ DT_SUBTABLE *RootTable)
+{
+
+ if (!RootTable)
+ {
+ return;
+ }
+
+ /* Walk the entire parse tree, emitting the binary data */
+
+ DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
+
+ Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
+ if (Gbl_TableLength == ACPI_UINT32_MAX)
+ {
+ AslAbort ();
+ }
+}
+
+
+/*
+ * Listing support
+ */
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDumpBuffer
+ *
+ * PARAMETERS: FileID - Where to write buffer data
+ * Buffer - Buffer to dump
+ * Offset - Offset in current table
+ * Length - Buffer Length
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
+ *
+ * TBD: merge dump buffer routines
+ *
+ *****************************************************************************/
+
+static void
+DtDumpBuffer (
+ UINT32 FileId,
+ UINT8 *Buffer,
+ UINT32 Offset,
+ UINT32 Length)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT8 BufChar;
+
+
+ FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
+ Offset, Offset, Length);
+
+ i = 0;
+ while (i < Length)
+ {
+ if (i >= 16)
+ {
+ FlPrintFile (FileId, "%24s", "");
+ }
+
+ /* Print 16 hex chars */
+
+ for (j = 0; j < 16;)
+ {
+ if (i + j >= Length)
+ {
+ /* Dump fill spaces */
+
+ FlPrintFile (FileId, " ");
+ j++;
+ continue;
+ }
+
+ FlPrintFile (FileId, "%02X ", Buffer[i+j]);
+ j++;
+ }
+
+ FlPrintFile (FileId, " ");
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j >= Length)
+ {
+ FlPrintFile (FileId, "\n\n");
+ return;
+ }
+
+ BufChar = Buffer[(ACPI_SIZE) i + j];
+ if (isprint (BufChar))
+ {
+ FlPrintFile (FileId, "%c", BufChar);
+ }
+ else
+ {
+ FlPrintFile (FileId, ".");
+ }
+ }
+
+ /* Done with that line. */
+
+ FlPrintFile (FileId, "\n");
+ i += 16;
+ }
+
+ FlPrintFile (FileId, "\n\n");
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDumpFieldList
+ *
+ * PARAMETERS: Field - Root field
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the entire field list
+ *
+ *****************************************************************************/
+
+void
+DtDumpFieldList (
+ DT_FIELD *Field)
+{
+
+ if (!Gbl_DebugFlag || !Field)
+ {
+ return;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\nField List:\n"
+ "LineNo ByteOff NameCol Column TableOff "
+ "Flags %32s : %s\n\n", "Name", "Value");
+ while (Field)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%.08X %.08X %.08X %.08X %.08X %2.2X %32s : %s\n",
+ Field->Line, Field->ByteOffset, Field->NameColumn,
+ Field->Column, Field->TableOffset, Field->Flags,
+ Field->Name, Field->Value);
+
+ Field = Field->Next;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n\n");
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDumpSubtableInfo, DtDumpSubtableTree
+ *
+ * PARAMETERS: DT_WALK_CALLBACK
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Info - dump a subtable tree entry with extra information.
+ * Tree - dump a subtable tree formatted by depth indentation.
+ *
+ *****************************************************************************/
+
+static void
+DtDumpSubtableInfo (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "[%.04X] %24s %.08X %.08X %.08X %.08X %.08X %p %p %p\n",
+ Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
+ Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
+ Subtable->Parent, Subtable->Child, Subtable->Peer);
+}
+
+static void
+DtDumpSubtableTree (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "[%.04X] %24s %*s%08X (%.02X) - (%.02X)\n",
+ Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
+ Subtable, Subtable->Length, Subtable->TotalLength);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtDumpSubtableList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the raw list of subtables with information, and also
+ * dump the subtable list in formatted tree format. Assists with
+ * the development of new table code.
+ *
+ *****************************************************************************/
+
+void
+DtDumpSubtableList (
+ void)
+{
+
+ if (!Gbl_DebugFlag || !Gbl_RootTable)
+ {
+ return;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Subtable Info:\n"
+ "Depth Name Length TotalLen LenSize Flags "
+ "This Parent Child Peer\n\n");
+ DtWalkTableTree (Gbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength)\n\n");
+ DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL);
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n");
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtWriteFieldToListing
+ *
+ * PARAMETERS: Buffer - Contains the compiled data
+ * Field - Field node for the input line
+ * Length - Length of the output data
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write one field to the listing file (if listing is enabled).
+ *
+ *****************************************************************************/
+
+void
+DtWriteFieldToListing (
+ UINT8 *Buffer,
+ DT_FIELD *Field,
+ UINT32 Length)
+{
+ UINT8 FileByte;
+
+
+ if (!Gbl_ListingFlag || !Field)
+ {
+ return;
+ }
+
+ /* Dump the original source line */
+
+ FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: ");
+ FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
+
+ while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
+ {
+ FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
+ if (FileByte == '\n')
+ {
+ break;
+ }
+ }
+
+ /* Dump the line as parsed and represented internally */
+
+ FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
+ Field->Column-4, Field->Name, Field->Value);
+
+ if (strlen (Field->Value) > 64)
+ {
+ FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
+ strlen (Field->Value));
+ }
+ FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
+
+ /* Dump the hex data that will be output for this field */
+
+ DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtWriteTableToListing
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write the entire compiled table to the listing file
+ * in hex format
+ *
+ *****************************************************************************/
+
+void
+DtWriteTableToListing (
+ void)
+{
+ UINT8 *Buffer;
+
+
+ if (!Gbl_ListingFlag)
+ {
+ return;
+ }
+
+ /* Read the entire table from the output file */
+
+ Buffer = UtLocalCalloc (Gbl_TableLength);
+ FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
+ FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
+
+ /* Dump the raw table data */
+
+ AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
+
+ AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
+ ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
+ AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0);
+
+ AcpiOsRedirectOutput (stdout);
+ ACPI_FREE (Buffer);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.l b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.l
new file mode 100644
index 0000000000..c6c29ae6a9
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.l
@@ -0,0 +1,133 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: dtparser.l - Flex input file for table compiler lexer
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "dtparser.y.h"
+
+#define YY_NO_INPUT /* No file input, we use strings only */
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("dtscanner")
+%}
+
+%option noyywrap
+%option nounput
+
+Number [0-9a-fA-F]+
+HexNumber 0[xX][0-9a-fA-F]+
+DecimalNumber 0[dD][0-9]+
+LabelRef $[a-zA-Z][0-9a-zA-Z]*
+WhiteSpace [ \t\v\r]+
+NewLine [\n]
+
+%%
+
+\( return (EXPOP_PAREN_OPEN);
+\) return (EXPOP_PAREN_CLOSE);
+\~ return (EXPOP_ONES_COMPLIMENT);
+\! return (EXPOP_LOGICAL_NOT);
+\* return (EXPOP_MULTIPLY);
+\/ return (EXPOP_DIVIDE);
+\% return (EXPOP_MODULO);
+\+ return (EXPOP_ADD);
+\- return (EXPOP_SUBTRACT);
+">>" return (EXPOP_SHIFT_RIGHT);
+"<<" return (EXPOP_SHIFT_LEFT);
+\< return (EXPOP_LESS);
+\> return (EXPOP_GREATER);
+"<=" return (EXPOP_LESS_EQUAL);
+">=" return (EXPOP_GREATER_EQUAL);
+"==" return (EXPOP_EQUAL);
+"!=" return (EXPOP_NOT_EQUAL);
+\& return (EXPOP_AND);
+\^ return (EXPOP_XOR);
+\| return (EXPOP_OR);
+"&&" return (EXPOP_LOGICAL_AND);
+"||" return (EXPOP_LOGICAL_OR);
+<<EOF>> return (EXPOP_EOF); /* null end-of-string */
+
+{LabelRef} return (EXPOP_LABEL);
+{Number} return (EXPOP_NUMBER);
+{HexNumber} return (EXPOP_HEX_NUMBER);
+{NewLine} return (EXPOP_NEW_LINE);
+{WhiteSpace} /* Ignore */
+
+. return (EXPOP_EOF);
+
+%%
+
+/*
+ * Local support functions
+ */
+YY_BUFFER_STATE LexBuffer;
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInitLexer, DtTerminateLexer
+ *
+ * PARAMETERS: String - Input string to be parsed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialization and termination routines for lexer. Lexer needs
+ * a buffer to handle strings instead of a file.
+ *
+ *****************************************************************************/
+
+int
+DtInitLexer (
+ char *String)
+{
+
+ LexBuffer = yy_scan_string (String);
+ return (LexBuffer == NULL);
+}
+
+void
+DtTerminateLexer (
+ void)
+{
+
+ yy_delete_buffer (LexBuffer);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.y
new file mode 100644
index 0000000000..9d6f1e2217
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtparser.y
@@ -0,0 +1,284 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: dtparser.y - Bison input file for table compiler parser
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtparser")
+
+void * AslLocalAllocate (unsigned int Size);
+
+/* Bison/yacc configuration */
+
+#undef alloca
+#define alloca AslLocalAllocate
+
+int DtParserlex (void);
+int DtParserparse (void);
+void DtParsererror (char const *msg);
+extern char *DtParsertext;
+extern DT_FIELD *Gbl_CurrentField;
+
+UINT64 DtParserResult; /* Expression return value */
+
+/* Bison/yacc configuration */
+
+#define yytname DtParsername
+#define YYDEBUG 1 /* Enable debug output */
+#define YYERROR_VERBOSE 1 /* Verbose error messages */
+#define YYFLAG -32768
+
+/* Define YYMALLOC/YYFREE to prevent redefinition errors */
+
+#define YYMALLOC malloc
+#define YYFREE free
+%}
+
+%union
+{
+ UINT64 value;
+ UINT32 op;
+}
+
+/*! [Begin] no source code translation */
+
+%type <value> Expression
+
+%token <op> EXPOP_EOF
+%token <op> EXPOP_NEW_LINE
+%token <op> EXPOP_NUMBER
+%token <op> EXPOP_HEX_NUMBER
+%token <op> EXPOP_DECIMAL_NUMBER
+%token <op> EXPOP_LABEL
+%token <op> EXPOP_PAREN_OPEN
+%token <op> EXPOP_PAREN_CLOSE
+
+%left <op> EXPOP_LOGICAL_OR
+%left <op> EXPOP_LOGICAL_AND
+%left <op> EXPOP_OR
+%left <op> EXPOP_XOR
+%left <op> EXPOP_AND
+%left <op> EXPOP_EQUAL EXPOP_NOT_EQUAL
+%left <op> EXPOP_GREATER EXPOP_LESS EXPOP_GREATER_EQUAL EXPOP_LESS_EQUAL
+%left <op> EXPOP_SHIFT_RIGHT EXPOP_SHIFT_LEFT
+%left <op> EXPOP_ADD EXPOP_SUBTRACT
+%left <op> EXPOP_MULTIPLY EXPOP_DIVIDE EXPOP_MODULO
+%right <op> EXPOP_ONES_COMPLIMENT EXPOP_LOGICAL_NOT
+
+%%
+
+/*
+ * Operator precedence rules (from K&R)
+ *
+ * 1) ( )
+ * 2) ! ~ (unary operators that are supported here)
+ * 3) * / %
+ * 4) + -
+ * 5) >> <<
+ * 6) < > <= >=
+ * 7) == !=
+ * 8) &
+ * 9) ^
+ * 10) |
+ * 11) &&
+ * 12) ||
+ */
+Value
+ : Expression EXPOP_NEW_LINE { DtParserResult=$1; return 0; } /* End of line (newline) */
+ | Expression EXPOP_EOF { DtParserResult=$1; return 0; } /* End of string (0) */
+ ;
+
+Expression
+
+ /* Unary operators */
+
+ : EXPOP_LOGICAL_NOT Expression { $$ = DtDoOperator ($2, EXPOP_LOGICAL_NOT, $2);}
+ | EXPOP_ONES_COMPLIMENT Expression { $$ = DtDoOperator ($2, EXPOP_ONES_COMPLIMENT, $2);}
+
+ /* Binary operators */
+
+ | Expression EXPOP_MULTIPLY Expression { $$ = DtDoOperator ($1, EXPOP_MULTIPLY, $3);}
+ | Expression EXPOP_DIVIDE Expression { $$ = DtDoOperator ($1, EXPOP_DIVIDE, $3);}
+ | Expression EXPOP_MODULO Expression { $$ = DtDoOperator ($1, EXPOP_MODULO, $3);}
+ | Expression EXPOP_ADD Expression { $$ = DtDoOperator ($1, EXPOP_ADD, $3);}
+ | Expression EXPOP_SUBTRACT Expression { $$ = DtDoOperator ($1, EXPOP_SUBTRACT, $3);}
+ | Expression EXPOP_SHIFT_RIGHT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_RIGHT, $3);}
+ | Expression EXPOP_SHIFT_LEFT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_LEFT, $3);}
+ | Expression EXPOP_GREATER Expression { $$ = DtDoOperator ($1, EXPOP_GREATER, $3);}
+ | Expression EXPOP_LESS Expression { $$ = DtDoOperator ($1, EXPOP_LESS, $3);}
+ | Expression EXPOP_GREATER_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_GREATER_EQUAL, $3);}
+ | Expression EXPOP_LESS_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_LESS_EQUAL, $3);}
+ | Expression EXPOP_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_EQUAL, $3);}
+ | Expression EXPOP_NOT_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_NOT_EQUAL, $3);}
+ | Expression EXPOP_AND Expression { $$ = DtDoOperator ($1, EXPOP_AND, $3);}
+ | Expression EXPOP_XOR Expression { $$ = DtDoOperator ($1, EXPOP_XOR, $3);}
+ | Expression EXPOP_OR Expression { $$ = DtDoOperator ($1, EXPOP_OR, $3);}
+ | Expression EXPOP_LOGICAL_AND Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_AND, $3);}
+ | Expression EXPOP_LOGICAL_OR Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_OR, $3);}
+
+ /* Parentheses: '(' Expression ')' */
+
+ | EXPOP_PAREN_OPEN Expression
+ EXPOP_PAREN_CLOSE { $$ = $2;}
+
+ /* Label references (prefixed with $) */
+
+ | EXPOP_LABEL { $$ = DtResolveLabel (DtParsertext);}
+
+ /* Default base for a non-prefixed integer is 16 */
+
+ | EXPOP_NUMBER { stroul64 (DtParsertext, 16, &$$);}
+
+ /* Standard hex number (0x1234) */
+
+ | EXPOP_HEX_NUMBER { stroul64 (DtParsertext, 16, &$$);}
+
+ /* TBD: Decimal number with prefix (0d1234) - Not supported by stroul64 at this time */
+
+ | EXPOP_DECIMAL_NUMBER { stroul64 (DtParsertext, 10, &$$);}
+ ;
+%%
+
+/*! [End] no source code translation !*/
+
+/*
+ * Local support functions, including parser entry point
+ */
+#define PR_FIRST_PARSE_OPCODE EXPOP_EOF
+#define PR_YYTNAME_START 3
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtParsererror
+ *
+ * PARAMETERS: Message - Parser-generated error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Handler for parser errors
+ *
+ *****************************************************************************/
+
+void
+DtParsererror (
+ char const *Message)
+{
+ DtError (ASL_ERROR, ASL_MSG_SYNTAX,
+ Gbl_CurrentField, (char *) Message);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetOpName
+ *
+ * PARAMETERS: ParseOpcode - Parser token (EXPOP_*)
+ *
+ * RETURN: Pointer to the opcode name
+ *
+ * DESCRIPTION: Get the ascii name of the parse opcode for debug output
+ *
+ *****************************************************************************/
+
+char *
+DtGetOpName (
+ UINT32 ParseOpcode)
+{
+#ifdef ASL_YYTNAME_START
+ /*
+ * First entries (PR_YYTNAME_START) in yytname are special reserved names.
+ * Ignore first 6 characters of name (EXPOP_)
+ */
+ return ((char *) yytname
+ [(ParseOpcode - PR_FIRST_PARSE_OPCODE) + PR_YYTNAME_START] + 6);
+#else
+ return ("[Unknown parser generator]");
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtEvaluateExpression
+ *
+ * PARAMETERS: ExprString - Expression to be evaluated. Must be
+ * terminated by either a newline or a NUL
+ * string terminator
+ *
+ * RETURN: 64-bit value for the expression
+ *
+ * DESCRIPTION: Main entry point for the DT expression parser
+ *
+ *****************************************************************************/
+
+UINT64
+DtEvaluateExpression (
+ char *ExprString)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "**** Input expression: %s (Base 16)\n", ExprString);
+
+ /* Point lexer to the input string */
+
+ if (DtInitLexer (ExprString))
+ {
+ DtError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
+ Gbl_CurrentField, "Could not initialize lexer");
+ return (0);
+ }
+
+ /* Parse/Evaluate the input string (value returned in DtParserResult) */
+
+ DtParserparse ();
+ DtTerminateLexer ();
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "**** Parser returned value: %u (%8.8X%8.8X)\n",
+ (UINT32) DtParserResult, ACPI_FORMAT_UINT64 (DtParserResult));
+
+ return (DtParserResult);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtsubtable.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtsubtable.c
new file mode 100644
index 0000000000..8cb5253c90
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtsubtable.c
@@ -0,0 +1,384 @@
+/******************************************************************************
+ *
+ * Module Name: dtsubtable.c - handling of subtables within ACPI tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtsubtable")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCreateSubtable
+ *
+ * PARAMETERS: Buffer - Input buffer
+ * Length - Buffer length
+ * RetSubtable - Returned newly created subtable
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO
+ * For example, FACS has 24 bytes reserved at the end
+ * and it's not listed at AcpiDmTableInfoFacs
+ *
+ *****************************************************************************/
+
+void
+DtCreateSubtable (
+ UINT8 *Buffer,
+ UINT32 Length,
+ DT_SUBTABLE **RetSubtable)
+{
+ DT_SUBTABLE *Subtable;
+ char *String;
+
+
+ Subtable = UtSubtableCacheCalloc ();
+
+ /* Create a new buffer for the subtable data */
+
+ String = UtStringCacheCalloc (Length);
+ Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
+ memcpy (Subtable->Buffer, Buffer, Length);
+
+ Subtable->Length = Length;
+ Subtable->TotalLength = Length;
+
+ *RetSubtable = Subtable;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtInsertSubtable
+ *
+ * PARAMETERS: ParentTable - The Parent of the new subtable
+ * Subtable - The new subtable to insert
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert the new subtable to the parent table
+ *
+ *****************************************************************************/
+
+void
+DtInsertSubtable (
+ DT_SUBTABLE *ParentTable,
+ DT_SUBTABLE *Subtable)
+{
+ DT_SUBTABLE *ChildTable;
+
+
+ Subtable->Peer = NULL;
+ Subtable->Parent = ParentTable;
+ Subtable->Depth = ParentTable->Depth + 1;
+
+ /* Link the new entry into the child list */
+
+ if (!ParentTable->Child)
+ {
+ ParentTable->Child = Subtable;
+ }
+ else
+ {
+ /* Walk to the end of the child list */
+
+ ChildTable = ParentTable->Child;
+ while (ChildTable->Peer)
+ {
+ ChildTable = ChildTable->Peer;
+ }
+
+ /* Add new subtable at the end of the child list */
+
+ ChildTable->Peer = Subtable;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtPushSubtable
+ *
+ * PARAMETERS: Subtable - Subtable to push
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push a subtable onto a subtable stack
+ *
+ *****************************************************************************/
+
+void
+DtPushSubtable (
+ DT_SUBTABLE *Subtable)
+{
+
+ Subtable->StackTop = Gbl_SubtableStack;
+ Gbl_SubtableStack = Subtable;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtPopSubtable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack
+ *
+ *****************************************************************************/
+
+void
+DtPopSubtable (
+ void)
+{
+ DT_SUBTABLE *Subtable;
+
+
+ Subtable = Gbl_SubtableStack;
+
+ if (Subtable)
+ {
+ Gbl_SubtableStack = Subtable->StackTop;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtPeekSubtable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: The subtable on top of stack
+ *
+ * DESCRIPTION: Get the subtable on top of stack
+ *
+ *****************************************************************************/
+
+DT_SUBTABLE *
+DtPeekSubtable (
+ void)
+{
+
+ return (Gbl_SubtableStack);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetNextSubtable
+ *
+ * PARAMETERS: ParentTable - Parent table whose children we are
+ * getting
+ * ChildTable - Previous child that was found.
+ * The NEXT child will be returned
+ *
+ * RETURN: Pointer to the NEXT child or NULL if none is found.
+ *
+ * DESCRIPTION: Return the next peer subtable within the tree.
+ *
+ *****************************************************************************/
+
+DT_SUBTABLE *
+DtGetNextSubtable (
+ DT_SUBTABLE *ParentTable,
+ DT_SUBTABLE *ChildTable)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!ChildTable)
+ {
+ /* It's really the parent's _scope_ that we want */
+
+ return (ParentTable->Child);
+ }
+
+ /* Otherwise just return the next peer (NULL if at end-of-list) */
+
+ return (ChildTable->Peer);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetParentSubtable
+ *
+ * PARAMETERS: Subtable - Current subtable
+ *
+ * RETURN: Parent of the given subtable
+ *
+ * DESCRIPTION: Get the parent of the given subtable in the tree
+ *
+ *****************************************************************************/
+
+DT_SUBTABLE *
+DtGetParentSubtable (
+ DT_SUBTABLE *Subtable)
+{
+
+ if (!Subtable)
+ {
+ return (NULL);
+ }
+
+ return (Subtable->Parent);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetSubtableLength
+ *
+ * PARAMETERS: Field - Current field list pointer
+ * Info - Data table info
+ *
+ * RETURN: Subtable length
+ *
+ * DESCRIPTION: Get length of bytes needed to compile the subtable
+ *
+ *****************************************************************************/
+
+UINT32
+DtGetSubtableLength (
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info)
+{
+ UINT32 ByteLength = 0;
+ UINT8 Step;
+ UINT8 i;
+
+
+ /* Walk entire Info table; Null name terminates */
+
+ for (; Info->Name; Info++)
+ {
+ if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
+ {
+ continue;
+ }
+
+ if (!Field)
+ {
+ goto Error;
+ }
+
+ ByteLength += DtGetFieldLength (Field, Info);
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_GAS:
+
+ Step = 5;
+ break;
+
+ case ACPI_DMT_HESTNTFY:
+
+ Step = 9;
+ break;
+
+ case ACPI_DMT_IORTMEM:
+
+ Step = 10;
+ break;
+
+ default:
+
+ Step = 1;
+ break;
+ }
+
+ for (i = 0; i < Step; i++)
+ {
+ if (!Field)
+ {
+ goto Error;
+ }
+
+ Field = Field->Next;
+ }
+ }
+
+ return (ByteLength);
+
+Error:
+ if (!Field)
+ {
+ sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
+ Info->Name);
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
+ }
+
+ return (ASL_EOF);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtSetSubtableLength
+ *
+ * PARAMETERS: Subtable - Subtable
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set length of the subtable into its length field
+ *
+ *****************************************************************************/
+
+void
+DtSetSubtableLength (
+ DT_SUBTABLE *Subtable)
+{
+
+ if (!Subtable->LengthField)
+ {
+ return;
+ }
+
+ memcpy (Subtable->LengthField, &Subtable->TotalLength,
+ Subtable->SizeOfLengthField);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dttable.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttable.c
new file mode 100644
index 0000000000..7987328fe9
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttable.c
@@ -0,0 +1,3524 @@
+/******************************************************************************
+ *
+ * Module Name: dttable.c - handling for specific ACPI tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/* Compile all complex data tables */
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dttable")
+
+
+/* TBD: merge these into dmtbinfo.c? */
+
+static ACPI_DMTABLE_INFO TableInfoAsfAddress[] =
+{
+ {ACPI_DMT_BUFFER, 0, "Addresses", 0},
+ {ACPI_DMT_EXIT, 0, NULL, 0}
+};
+
+static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] =
+{
+ {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0},
+ {ACPI_DMT_EXIT, 0, NULL, 0}
+};
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+DtCompileTwoSubtables (
+ void **List,
+ ACPI_DMTABLE_INFO *TableInfo1,
+ ACPI_DMTABLE_INFO *TableInfo2);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileTwoSubtables
+ *
+ * PARAMETERS: List - Current field list pointer
+ * TableInfo1 - Info table 1
+ * TableInfo1 - Info table 2
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile tables with a header and one or more same subtables.
+ * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+DtCompileTwoSubtables (
+ void **List,
+ ACPI_DMTABLE_INFO *TableInfo1,
+ ACPI_DMTABLE_INFO *TableInfo2)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+
+
+ Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileFacs
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile FACS.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileFacs (
+ DT_FIELD **PFieldList)
+{
+ DT_SUBTABLE *Subtable;
+ UINT8 *ReservedBuffer;
+ ACPI_STATUS Status;
+ UINT32 ReservedSize;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
+ &Gbl_RootTable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Large FACS reserved area at the end of the table */
+
+ ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
+ ReservedBuffer = UtLocalCalloc (ReservedSize);
+
+ DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
+
+ ACPI_FREE (ReservedBuffer);
+ DtInsertSubtable (Gbl_RootTable, Subtable);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileRsdp
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile RSDP.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileRsdp (
+ DT_FIELD **PFieldList)
+{
+ DT_SUBTABLE *Subtable;
+ ACPI_TABLE_RSDP *Rsdp;
+ ACPI_RSDP_EXTENSION *RsdpExtension;
+ ACPI_STATUS Status;
+
+
+ /* Compile the "common" RSDP (ACPI 1.0) */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
+ &Gbl_RootTable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
+ DtSetTableChecksum (&Rsdp->Checksum);
+
+ if (Rsdp->Revision > 0)
+ {
+ /* Compile the "extended" part of the RSDP as a subtable */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (Gbl_RootTable, Subtable);
+
+ /* Set length and extended checksum for entire RSDP */
+
+ RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
+ RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
+ DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileAsf
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile ASF!.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileAsf (
+ void **List)
+{
+ ACPI_ASF_INFO *AsfTable;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_DMTABLE_INFO *DataInfoTable = NULL;
+ UINT32 DataCount = 0;
+ ACPI_STATUS Status;
+ UINT32 i;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
+
+ switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
+ {
+ case ACPI_ASF_TYPE_INFO:
+
+ InfoTable = AcpiDmTableInfoAsf0;
+ break;
+
+ case ACPI_ASF_TYPE_ALERT:
+
+ InfoTable = AcpiDmTableInfoAsf1;
+ break;
+
+ case ACPI_ASF_TYPE_CONTROL:
+
+ InfoTable = AcpiDmTableInfoAsf2;
+ break;
+
+ case ACPI_ASF_TYPE_BOOT:
+
+ InfoTable = AcpiDmTableInfoAsf3;
+ break;
+
+ case ACPI_ASF_TYPE_ADDRESS:
+
+ InfoTable = AcpiDmTableInfoAsf4;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
+ {
+ case ACPI_ASF_TYPE_INFO:
+
+ DataInfoTable = NULL;
+ break;
+
+ case ACPI_ASF_TYPE_ALERT:
+
+ DataInfoTable = AcpiDmTableInfoAsf1a;
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
+ ACPI_SUB_PTR (UINT8, Subtable->Buffer,
+ sizeof (ACPI_ASF_HEADER)))->Alerts;
+ break;
+
+ case ACPI_ASF_TYPE_CONTROL:
+
+ DataInfoTable = AcpiDmTableInfoAsf2a;
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
+ ACPI_SUB_PTR (UINT8, Subtable->Buffer,
+ sizeof (ACPI_ASF_HEADER)))->Controls;
+ break;
+
+ case ACPI_ASF_TYPE_BOOT:
+
+ DataInfoTable = NULL;
+ break;
+
+ case ACPI_ASF_TYPE_ADDRESS:
+
+ DataInfoTable = TableInfoAsfAddress;
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
+ ACPI_SUB_PTR (UINT8, Subtable->Buffer,
+ sizeof (ACPI_ASF_HEADER)))->Devices;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
+ return (AE_ERROR);
+ }
+
+ if (DataInfoTable)
+ {
+ switch (AsfTable->Header.Type & 0x7F)
+ {
+ case ACPI_ASF_TYPE_ADDRESS:
+
+ while (DataCount > 0)
+ {
+ Status = DtCompileTable (PFieldList, DataInfoTable,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ DataCount = DataCount - Subtable->Length;
+ }
+ break;
+
+ default:
+
+ for (i = 0; i < DataCount; i++)
+ {
+ Status = DtCompileTable (PFieldList, DataInfoTable,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ break;
+ }
+ }
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileCpep
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile CPEP.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileCpep (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileCsrt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile CSRT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileCsrt (
+ void **List)
+{
+ ACPI_STATUS Status = AE_OK;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ UINT32 DescriptorCount;
+ UINT32 GroupLength;
+
+
+ /* Subtables (Resource Groups) */
+
+ ParentTable = DtPeekSubtable ();
+ while (*PFieldList)
+ {
+ /* Resource group subtable */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Compute the number of resource descriptors */
+
+ GroupLength =
+ (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
+ Subtable->Buffer))->Length -
+ (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
+ Subtable->Buffer))->SharedInfoLength -
+ sizeof (ACPI_CSRT_GROUP);
+
+ DescriptorCount = (GroupLength /
+ sizeof (ACPI_CSRT_DESCRIPTOR));
+
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+
+ /* Shared info subtable (One per resource group) */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Sub-Subtables (Resource Descriptors) */
+
+ while (*PFieldList && DescriptorCount)
+ {
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+ if (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ }
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+
+ DescriptorCount--;
+ }
+
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileDbg2
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile DBG2.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileDbg2 (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ UINT32 SubtableCount;
+ ACPI_DBG2_HEADER *Dbg2Header;
+ ACPI_DBG2_DEVICE *DeviceInfo;
+ UINT16 CurrentOffset;
+ UINT32 i;
+
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Main table fields */
+
+ Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
+ Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
+ ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
+
+ SubtableCount = Dbg2Header->InfoCount;
+ DtPushSubtable (Subtable);
+
+ /* Process all Device Information subtables (Count = InfoCount) */
+
+ while (*PFieldList && SubtableCount)
+ {
+ /* Subtable: Debug Device Information */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
+ CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ ParentTable = DtPeekSubtable ();
+
+ /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
+
+ DeviceInfo->BaseAddressOffset = CurrentOffset;
+ for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ /* AddressSize array (Required, size = RegisterCount) */
+
+ DeviceInfo->AddressSizeOffset = CurrentOffset;
+ for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ CurrentOffset += (UINT16) sizeof (UINT32);
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ /* NamespaceString device identifier (Required, size = NamePathLength) */
+
+ DeviceInfo->NamepathOffset = CurrentOffset;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Update the device info header */
+
+ DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
+ CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* OemData - Variable-length data (Optional, size = OemDataLength) */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Update the device info header (zeros if no OEM data present) */
+
+ DeviceInfo->OemDataOffset = 0;
+ DeviceInfo->OemDataLength = 0;
+
+ /* Optional subtable (OemData) */
+
+ if (Subtable && Subtable->Length)
+ {
+ DeviceInfo->OemDataOffset = CurrentOffset;
+ DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ SubtableCount--;
+ DtPopSubtable (); /* Get next Device Information subtable */
+ }
+
+ DtPopSubtable ();
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileDmar
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile DMAR.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileDmar (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_DMAR_HEADER *DmarHeader;
+ ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
+ UINT32 DeviceScopeLength;
+ UINT32 PciPathLength;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ while (*PFieldList)
+ {
+ /* DMAR Header */
+
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
+
+ switch (DmarHeader->Type)
+ {
+ case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+
+ InfoTable = AcpiDmTableInfoDmar0;
+ break;
+
+ case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+
+ InfoTable = AcpiDmTableInfoDmar1;
+ break;
+
+ case ACPI_DMAR_TYPE_ROOT_ATS:
+
+ InfoTable = AcpiDmTableInfoDmar2;
+ break;
+
+ case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoDmar3;
+ break;
+
+ case ACPI_DMAR_TYPE_NAMESPACE:
+
+ InfoTable = AcpiDmTableInfoDmar4;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
+ return (AE_ERROR);
+ }
+
+ /* DMAR Subtable */
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Optional Device Scope subtables
+ */
+ if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
+ (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
+ {
+ /* These types do not support device scopes */
+
+ DtPopSubtable ();
+ continue;
+ }
+
+ DtPushSubtable (Subtable);
+ DeviceScopeLength = DmarHeader->Length - Subtable->Length -
+ ParentTable->Length;
+ while (DeviceScopeLength)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
+ &Subtable, FALSE);
+ if (Status == AE_NOT_FOUND)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
+
+ /* Optional PCI Paths */
+
+ PciPathLength = DmarDeviceScope->Length - Subtable->Length;
+ while (PciPathLength)
+ {
+ Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
+ &Subtable, FALSE);
+ if (Status == AE_NOT_FOUND)
+ {
+ DtPopSubtable ();
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ PciPathLength -= Subtable->Length;
+ }
+
+ DtPopSubtable ();
+ DeviceScopeLength -= DmarDeviceScope->Length;
+ }
+
+ DtPopSubtable ();
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileDrtm
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile DRTM.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileDrtm (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ UINT32 Count;
+ /* ACPI_TABLE_DRTM *Drtm; */
+ ACPI_DRTM_VTABLE_LIST *DrtmVtl;
+ ACPI_DRTM_RESOURCE_LIST *DrtmRl;
+ /* ACPI_DRTM_DPS_ID *DrtmDps; */
+
+
+ ParentTable = DtPeekSubtable ();
+
+ /* Compile DRTM header */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
+ * should be taken to avoid accessing ACPI_TABLE_HADER fields.
+ */
+#if 0
+ Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
+ Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
+#endif
+ /* Compile VTL */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+ Count = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ Count++;
+ }
+ DrtmVtl->ValidatedTableCount = Count;
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+
+ /* Compile RL */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+ Count = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ Count++;
+ }
+ DrtmRl->ResourceCount = Count;
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+
+ /* Compile DPS */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
+
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileEinj
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile EINJ.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileEinj (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileErst
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile ERST.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileErst (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileFadt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile FADT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileFadt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_TABLE_HEADER *Table;
+ UINT8 Revision;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
+ Revision = Table->Revision;
+
+ if (Revision == 2)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ else if (Revision >= 2)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+
+ if (Revision >= 5)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ if (Revision >= 6)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ }
+
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileGtdt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile GTDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileGtdt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SUBTABLE_HEADER *GtdtHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 GtCount;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
+
+ switch (GtdtHeader->Type)
+ {
+ case ACPI_GTDT_TYPE_TIMER_BLOCK:
+
+ InfoTable = AcpiDmTableInfoGtdt0;
+ break;
+
+ case ACPI_GTDT_TYPE_WATCHDOG:
+
+ InfoTable = AcpiDmTableInfoGtdt1;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Additional GT block subtable data
+ */
+
+ switch (GtdtHeader->Type)
+ {
+ case ACPI_GTDT_TYPE_TIMER_BLOCK:
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+
+ GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
+ Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
+ while (GtCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+
+ DtInsertSubtable (ParentTable, Subtable);
+ GtCount--;
+ }
+ DtPopSubtable ();
+ break;
+
+ default:
+
+ break;
+ }
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileFpdt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile FPDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileFpdt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ ACPI_FPDT_HEADER *FpdtHeader;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
+
+ switch (FpdtHeader->Type)
+ {
+ case ACPI_FPDT_TYPE_BOOT:
+
+ InfoTable = AcpiDmTableInfoFpdt0;
+ break;
+
+ case ACPI_FPDT_TYPE_S3PERF:
+
+ InfoTable = AcpiDmTableInfoFpdt1;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
+ return (AE_ERROR);
+ break;
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileHest
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile HEST.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileHest (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT16 Type;
+ UINT32 BankCount;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ /* Get subtable type */
+
+ SubtableStart = *PFieldList;
+ DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
+
+ switch (Type)
+ {
+ case ACPI_HEST_TYPE_IA32_CHECK:
+
+ InfoTable = AcpiDmTableInfoHest0;
+ break;
+
+ case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
+
+ InfoTable = AcpiDmTableInfoHest1;
+ break;
+
+ case ACPI_HEST_TYPE_IA32_NMI:
+
+ InfoTable = AcpiDmTableInfoHest2;
+ break;
+
+ case ACPI_HEST_TYPE_AER_ROOT_PORT:
+
+ InfoTable = AcpiDmTableInfoHest6;
+ break;
+
+ case ACPI_HEST_TYPE_AER_ENDPOINT:
+
+ InfoTable = AcpiDmTableInfoHest7;
+ break;
+
+ case ACPI_HEST_TYPE_AER_BRIDGE:
+
+ InfoTable = AcpiDmTableInfoHest8;
+ break;
+
+ case ACPI_HEST_TYPE_GENERIC_ERROR:
+
+ InfoTable = AcpiDmTableInfoHest9;
+ break;
+
+ default:
+
+ /* Cannot continue on unknown type */
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Additional subtable data - IA32 Error Bank(s)
+ */
+ BankCount = 0;
+ switch (Type)
+ {
+ case ACPI_HEST_TYPE_IA32_CHECK:
+
+ BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
+ Subtable->Buffer))->NumHardwareBanks;
+ break;
+
+ case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
+
+ BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
+ Subtable->Buffer))->NumHardwareBanks;
+ break;
+
+ default:
+
+ break;
+ }
+
+ while (BankCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ BankCount--;
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileIort
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile IORT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileIort (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_TABLE_IORT *Iort;
+ ACPI_IORT_NODE *IortNode;
+ ACPI_IORT_ITS_GROUP *IortItsGroup;
+ ACPI_IORT_SMMU *IortSmmu;
+ UINT32 NodeNumber;
+ UINT32 NodeLength;
+ UINT32 IdMappingNumber;
+ UINT32 ItsNumber;
+ UINT32 ContextIrptNumber;
+ UINT32 PmuIrptNumber;
+ UINT32 PaddingLength;
+
+
+ ParentTable = DtPeekSubtable ();
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
+ * should be taken to avoid accessing ACPI_TABLE_HADER fields.
+ */
+ Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
+ Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
+
+ /*
+ * OptionalPadding - Variable-length data
+ * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
+ * Optionally allows the generic data types to be used for filling
+ * this field.
+ */
+ Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ Iort->NodeOffset += Subtable->Length;
+ }
+ else
+ {
+ Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
+ AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ Iort->NodeOffset += PaddingLength;
+ }
+
+ NodeNumber = 0;
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
+ NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+
+ switch (IortNode->Type)
+ {
+ case ACPI_IORT_NODE_ITS_GROUP:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
+ NodeLength += Subtable->Length;
+
+ ItsNumber = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ ItsNumber++;
+ }
+
+ IortItsGroup->ItsCount = ItsNumber;
+ break;
+
+ case ACPI_IORT_NODE_NAMED_COMPONENT:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+
+ /*
+ * Padding - Variable-length data
+ * Optionally allows the offset of the ID mappings to be used
+ * for filling this field.
+ */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ }
+ else
+ {
+ if (NodeLength > IortNode->MappingOffset)
+ {
+ return (AE_BAD_DATA);
+ }
+ if (NodeLength < IortNode->MappingOffset)
+ {
+ Status = DtCompilePadding (
+ IortNode->MappingOffset - NodeLength,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength = IortNode->MappingOffset;
+ }
+ }
+ break;
+
+ case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ break;
+
+ case ACPI_IORT_NODE_SMMU:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
+ NodeLength += Subtable->Length;
+
+ /* Compile global interrupt array */
+
+ IortSmmu->GlobalInterruptOffset = NodeLength;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+
+ /* Compile context interrupt array */
+
+ ContextIrptNumber = 0;
+ IortSmmu->ContextInterruptOffset = NodeLength;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ ContextIrptNumber++;
+ }
+ IortSmmu->ContextInterruptCount = ContextIrptNumber;
+
+ /* Compile PMU interrupt array */
+
+ PmuIrptNumber = 0;
+ IortSmmu->PmuInterruptOffset = NodeLength;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ PmuIrptNumber++;
+ }
+ IortSmmu->PmuInterruptCount = PmuIrptNumber;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
+ return (AE_ERROR);
+ }
+
+ /* Compile Array of ID mappings */
+
+ IortNode->MappingOffset = NodeLength;
+ IdMappingNumber = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
+ IdMappingNumber++;
+ }
+ IortNode->MappingCount = IdMappingNumber;
+
+ /*
+ * Node length can be determined by DT_LENGTH option
+ * IortNode->Length = NodeLength;
+ */
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+ NodeNumber++;
+ }
+ Iort->NodeCount = NodeNumber;
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileIvrs
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile IVRS.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileIvrs (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_IVRS_HEADER *IvrsHeader;
+ UINT8 EntryType;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
+
+ switch (IvrsHeader->Type)
+ {
+ case ACPI_IVRS_TYPE_HARDWARE:
+
+ InfoTable = AcpiDmTableInfoIvrs0;
+ break;
+
+ case ACPI_IVRS_TYPE_MEMORY1:
+ case ACPI_IVRS_TYPE_MEMORY2:
+ case ACPI_IVRS_TYPE_MEMORY3:
+
+ InfoTable = AcpiDmTableInfoIvrs1;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
+ {
+ while (*PFieldList &&
+ !strcmp ((*PFieldList)->Name, "Entry Type"))
+ {
+ SubtableStart = *PFieldList;
+ DtCompileInteger (&EntryType, *PFieldList, 1, 0);
+
+ switch (EntryType)
+ {
+ /* 4-byte device entries */
+
+ case ACPI_IVRS_TYPE_PAD4:
+ case ACPI_IVRS_TYPE_ALL:
+ case ACPI_IVRS_TYPE_SELECT:
+ case ACPI_IVRS_TYPE_START:
+ case ACPI_IVRS_TYPE_END:
+
+ InfoTable = AcpiDmTableInfoIvrs4;
+ break;
+
+ /* 8-byte entries, type A */
+
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
+ case ACPI_IVRS_TYPE_ALIAS_START:
+
+ InfoTable = AcpiDmTableInfoIvrs8a;
+ break;
+
+ /* 8-byte entries, type B */
+
+ case ACPI_IVRS_TYPE_PAD8:
+ case ACPI_IVRS_TYPE_EXT_SELECT:
+ case ACPI_IVRS_TYPE_EXT_START:
+
+ InfoTable = AcpiDmTableInfoIvrs8b;
+ break;
+
+ /* 8-byte entries, type C */
+
+ case ACPI_IVRS_TYPE_SPECIAL:
+
+ InfoTable = AcpiDmTableInfoIvrs8c;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
+ "IVRS Device Entry");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ }
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileLpit
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile LPIT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileLpit (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_LPIT_HEADER *LpitHeader;
+
+
+ /* Note: Main table consists only of the standard ACPI table header */
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+
+ /* LPIT Subtable header */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
+
+ switch (LpitHeader->Type)
+ {
+ case ACPI_LPIT_TYPE_NATIVE_CSTATE:
+
+ InfoTable = AcpiDmTableInfoLpit0;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
+ return (AE_ERROR);
+ }
+
+ /* LPIT Subtable */
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMadt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MADT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMadt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SUBTABLE_HEADER *MadtHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
+
+ switch (MadtHeader->Type)
+ {
+ case ACPI_MADT_TYPE_LOCAL_APIC:
+
+ InfoTable = AcpiDmTableInfoMadt0;
+ break;
+
+ case ACPI_MADT_TYPE_IO_APIC:
+
+ InfoTable = AcpiDmTableInfoMadt1;
+ break;
+
+ case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
+
+ InfoTable = AcpiDmTableInfoMadt2;
+ break;
+
+ case ACPI_MADT_TYPE_NMI_SOURCE:
+
+ InfoTable = AcpiDmTableInfoMadt3;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+
+ InfoTable = AcpiDmTableInfoMadt4;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
+
+ InfoTable = AcpiDmTableInfoMadt5;
+ break;
+
+ case ACPI_MADT_TYPE_IO_SAPIC:
+
+ InfoTable = AcpiDmTableInfoMadt6;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_SAPIC:
+
+ InfoTable = AcpiDmTableInfoMadt7;
+ break;
+
+ case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
+
+ InfoTable = AcpiDmTableInfoMadt8;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+
+ InfoTable = AcpiDmTableInfoMadt9;
+ break;
+
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+
+ InfoTable = AcpiDmTableInfoMadt10;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+
+ InfoTable = AcpiDmTableInfoMadt11;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+
+ InfoTable = AcpiDmTableInfoMadt12;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+
+ InfoTable = AcpiDmTableInfoMadt13;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+
+ InfoTable = AcpiDmTableInfoMadt14;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
+
+ InfoTable = AcpiDmTableInfoMadt15;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMcfg
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MCFG.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMcfg (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMpst
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MPST.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMpst (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_MPST_CHANNEL *MpstChannelInfo;
+ ACPI_MPST_POWER_NODE *MpstPowerNode;
+ ACPI_MPST_DATA_HDR *MpstDataHeader;
+ UINT16 SubtableCount;
+ UINT32 PowerStateCount;
+ UINT32 ComponentCount;
+
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
+ SubtableCount = MpstChannelInfo->PowerNodeCount;
+
+ while (*PFieldList && SubtableCount)
+ {
+ /* Subtable: Memory Power Node(s) */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
+ PowerStateCount = MpstPowerNode->NumPowerStates;
+ ComponentCount = MpstPowerNode->NumPhysicalComponents;
+
+ ParentTable = DtPeekSubtable ();
+
+ /* Sub-subtables - Memory Power State Structure(s) */
+
+ while (*PFieldList && PowerStateCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ PowerStateCount--;
+ }
+
+ /* Sub-subtables - Physical Component ID Structure(s) */
+
+ while (*PFieldList && ComponentCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ ComponentCount--;
+ }
+
+ SubtableCount--;
+ DtPopSubtable ();
+ }
+
+ /* Subtable: Count of Memory Power State Characteristic structures */
+
+ DtPopSubtable ();
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
+ SubtableCount = MpstDataHeader->CharacteristicsCount;
+
+ ParentTable = DtPeekSubtable ();
+
+ /* Subtable: Memory Power State Characteristics structure(s) */
+
+ while (*PFieldList && SubtableCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ SubtableCount--;
+ }
+
+ DtPopSubtable ();
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMsct
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MSCT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMsct (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMtmr
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MTMR.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMtmr (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileNfit
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile NFIT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileNfit (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_NFIT_HEADER *NfitHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 Count;
+ ACPI_NFIT_INTERLEAVE *Interleave = NULL;
+ ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ /* Subtables */
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
+
+ switch (NfitHeader->Type)
+ {
+ case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
+
+ InfoTable = AcpiDmTableInfoNfit0;
+ break;
+
+ case ACPI_NFIT_TYPE_MEMORY_MAP:
+
+ InfoTable = AcpiDmTableInfoNfit1;
+ break;
+
+ case ACPI_NFIT_TYPE_INTERLEAVE:
+
+ Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
+ InfoTable = AcpiDmTableInfoNfit2;
+ break;
+
+ case ACPI_NFIT_TYPE_SMBIOS:
+
+ InfoTable = AcpiDmTableInfoNfit3;
+ break;
+
+ case ACPI_NFIT_TYPE_CONTROL_REGION:
+
+ InfoTable = AcpiDmTableInfoNfit4;
+ break;
+
+ case ACPI_NFIT_TYPE_DATA_REGION:
+
+ InfoTable = AcpiDmTableInfoNfit5;
+ break;
+
+ case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
+
+ Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
+ InfoTable = AcpiDmTableInfoNfit6;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+
+ switch (NfitHeader->Type)
+ {
+ case ACPI_NFIT_TYPE_INTERLEAVE:
+
+ Count = 0;
+ DtPushSubtable (Subtable);
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
+ &Subtable, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ DtPopSubtable ();
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ Count++;
+ }
+
+ Interleave->LineCount = Count;
+ DtPopSubtable ();
+ break;
+
+ case ACPI_NFIT_TYPE_SMBIOS:
+
+ if (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ }
+ break;
+
+ case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
+
+ Count = 0;
+ DtPushSubtable (Subtable);
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
+ &Subtable, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ DtPopSubtable ();
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ Count++;
+ }
+
+ Hint->HintCount = (UINT16) Count;
+ DtPopSubtable ();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompilePcct
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile PCCT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompilePcct (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SUBTABLE_HEADER *PcctHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Subtables */
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
+
+ switch (PcctHeader->Type)
+ {
+ case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
+
+ InfoTable = AcpiDmTableInfoPcct0;
+ break;
+
+ case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
+
+ InfoTable = AcpiDmTableInfoPcct1;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompilePmtt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile PMTT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompilePmtt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_PMTT_HEADER *PmttHeader;
+ ACPI_PMTT_CONTROLLER *PmttController;
+ UINT16 DomainCount;
+ UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET;
+
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
+ while (PrevType >= PmttHeader->Type)
+ {
+ DtPopSubtable ();
+
+ if (PrevType == ACPI_PMTT_TYPE_SOCKET)
+ {
+ break;
+ }
+ PrevType--;
+ }
+ PrevType = PmttHeader->Type;
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ switch (PmttHeader->Type)
+ {
+ case ACPI_PMTT_TYPE_SOCKET:
+
+ /* Subtable: Socket Structure */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ break;
+
+ case ACPI_PMTT_TYPE_CONTROLLER:
+
+ /* Subtable: Memory Controller Structure */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
+ (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
+ DomainCount = PmttController->DomainCount;
+
+ while (DomainCount)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ DomainCount--;
+ }
+ break;
+
+ case ACPI_PMTT_TYPE_DIMM:
+
+ /* Subtable: Physical Component Structure */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
+ return (AE_ERROR);
+ }
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileRsdt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile RSDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileRsdt (
+ void **List)
+{
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD *FieldList = *(DT_FIELD **) List;
+ UINT32 Address;
+
+
+ ParentTable = DtPeekSubtable ();
+
+ while (FieldList)
+ {
+ DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
+
+ DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
+ DtInsertSubtable (ParentTable, Subtable);
+ FieldList = FieldList->Next;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileS3pt
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileS3pt (
+ DT_FIELD **PFieldList)
+{
+ ACPI_STATUS Status;
+ ACPI_S3PT_HEADER *S3ptHeader;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ DT_FIELD *SubtableStart;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
+ &Gbl_RootTable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtPushSubtable (Gbl_RootTable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
+
+ switch (S3ptHeader->Type)
+ {
+ case ACPI_S3PT_TYPE_RESUME:
+
+ InfoTable = AcpiDmTableInfoS3pt0;
+ break;
+
+ case ACPI_S3PT_TYPE_SUSPEND:
+
+ InfoTable = AcpiDmTableInfoS3pt1;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileSlic
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile SLIC.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileSlic (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+
+
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileSlit
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile SLIT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileSlit (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *FieldList;
+ UINT32 Localities;
+ UINT8 *LocalityBuffer;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
+ LocalityBuffer = UtLocalCalloc (Localities);
+
+ /* Compile each locality buffer */
+
+ FieldList = *PFieldList;
+ while (FieldList)
+ {
+ DtCompileBuffer (LocalityBuffer,
+ FieldList->Value, FieldList, Localities);
+
+ DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
+ DtInsertSubtable (ParentTable, Subtable);
+ FieldList = FieldList->Next;
+ }
+
+ ACPI_FREE (LocalityBuffer);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileSrat
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile SRAT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileSrat (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SUBTABLE_HEADER *SratHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
+
+ switch (SratHeader->Type)
+ {
+ case ACPI_SRAT_TYPE_CPU_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat0;
+ break;
+
+ case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat1;
+ break;
+
+ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat2;
+ break;
+
+ case ACPI_SRAT_TYPE_GICC_AFFINITY:
+
+ InfoTable = AcpiDmTableInfoSrat3;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileStao
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile STAO.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileStao (
+ void **List)
+{
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_STATUS Status;
+
+
+ /* Compile the main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Compile each ASCII namestring as a subtable */
+
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileTcpa
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile TCPA.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileTcpa (
+ void **List)
+{
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_SUBTABLE *Subtable;
+ ACPI_TABLE_TCPA_HDR *TcpaHeader;
+ DT_SUBTABLE *ParentTable;
+ ACPI_STATUS Status;
+
+
+ /* Compile the main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Examine the PlatformClass field to determine the table type.
+ * Either a client or server table. Only one.
+ */
+ TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
+
+ switch (TcpaHeader->PlatformClass)
+ {
+ case ACPI_TCPA_CLIENT_TABLE:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
+ &Subtable, TRUE);
+ break;
+
+ case ACPI_TCPA_SERVER_TABLE:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
+ &Subtable, TRUE);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
+ TcpaHeader->PlatformClass);
+ Status = AE_ERROR;
+ break;
+ }
+
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetGenericTableInfo
+ *
+ * PARAMETERS: Name - Generic type name
+ *
+ * RETURN: Info entry
+ *
+ * DESCRIPTION: Obtain table info for a generic name entry
+ *
+ *****************************************************************************/
+
+ACPI_DMTABLE_INFO *
+DtGetGenericTableInfo (
+ char *Name)
+{
+ ACPI_DMTABLE_INFO *Info;
+ UINT32 i;
+
+
+ if (!Name)
+ {
+ return (NULL);
+ }
+
+ /* Search info table for name match */
+
+ for (i = 0; ; i++)
+ {
+ Info = AcpiDmTableInfoGeneric[i];
+ if (Info->Opcode == ACPI_DMT_EXIT)
+ {
+ Info = NULL;
+ break;
+ }
+
+ /* Use caseless compare for generic keywords */
+
+ if (!AcpiUtStricmp (Name, Info->Name))
+ {
+ break;
+ }
+ }
+
+ return (Info);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileUefi
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile UEFI.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileUefi (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ UINT16 *DataOffset;
+
+
+ /* Compile the predefined portion of the UEFI table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DataOffset = (UINT16 *) (Subtable->Buffer + 16);
+ *DataOffset = sizeof (ACPI_TABLE_UEFI);
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Compile the "generic" portion of the UEFI table. This
+ * part of the table is not predefined and any of the generic
+ * operators may be used.
+ */
+
+ DtCompileGeneric ((void **) PFieldList, NULL, NULL);
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileVrtc
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile VRTC.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileVrtc (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileWdat
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile WDAT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileWdat (
+ void **List)
+{
+ ACPI_STATUS Status;
+
+
+ Status = DtCompileTwoSubtables (List,
+ AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileWpbt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile WPBT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileWpbt (
+ void **List)
+{
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_TABLE_WPBT *Table;
+ ACPI_STATUS Status;
+ UINT16 Length;
+
+
+ /* Compile the main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Compile the argument list subtable */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Extract the length of the Arguments buffer, insert into main table */
+
+ Length = (UINT16) Subtable->TotalLength;
+ Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
+ Table->ArgumentsLength = Length;
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileXsdt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile XSDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileXsdt (
+ void **List)
+{
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD *FieldList = *(DT_FIELD **) List;
+ UINT64 Address;
+
+
+ ParentTable = DtPeekSubtable ();
+
+ while (FieldList)
+ {
+ DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
+
+ DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
+ DtInsertSubtable (ParentTable, Subtable);
+ FieldList = FieldList->Next;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileGeneric
+ *
+ * PARAMETERS: List - Current field list pointer
+ * Name - Field name to end generic compiling
+ * Length - Compiled table length to return
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile generic unknown table.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileGeneric (
+ void **List,
+ char *Name,
+ UINT32 *Length)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_DMTABLE_INFO *Info;
+
+
+ ParentTable = DtPeekSubtable ();
+
+ /*
+ * Compile the "generic" portion of the table. This
+ * part of the table is not predefined and any of the generic
+ * operators may be used.
+ */
+
+ /* Find any and all labels in the entire generic portion */
+
+ DtDetectAllLabels (*PFieldList);
+
+ /* Now we can actually compile the parse tree */
+
+ if (Length && *Length)
+ {
+ *Length = 0;
+ }
+ while (*PFieldList)
+ {
+ if (Name && !strcmp ((*PFieldList)->Name, Name))
+ {
+ break;
+ }
+ Info = DtGetGenericTableInfo ((*PFieldList)->Name);
+ if (!Info)
+ {
+ sprintf (MsgBuffer, "Generic data type \"%s\" not found",
+ (*PFieldList)->Name);
+ DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
+ (*PFieldList), MsgBuffer);
+
+ *PFieldList = (*PFieldList)->Next;
+ continue;
+ }
+
+ Status = DtCompileTable (PFieldList, Info,
+ &Subtable, TRUE);
+ if (ACPI_SUCCESS (Status))
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ if (Length)
+ {
+ *Length += Subtable->Length;
+ }
+ }
+ else
+ {
+ *PFieldList = (*PFieldList)->Next;
+
+ if (Status == AE_NOT_FOUND)
+ {
+ sprintf (MsgBuffer, "Generic data type \"%s\" not found",
+ (*PFieldList)->Name);
+ DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
+ (*PFieldList), MsgBuffer);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.c
new file mode 100644
index 0000000000..07e930fb53
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.c
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * Module Name: dttemplate - ACPI table template generation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+#include <contrib/dev/acpica/compiler/dttemplate.h> /* Contains the hex ACPI table templates */
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dttemplate")
+
+
+/* Local prototypes */
+
+static BOOLEAN
+AcpiUtIsSpecialTable (
+ char *Signature);
+
+static ACPI_STATUS
+DtCreateOneTemplate (
+ char *Signature,
+ const ACPI_DMTABLE_DATA *TableData);
+
+static ACPI_STATUS
+DtCreateAllTemplates (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtIsSpecialTable
+ *
+ * PARAMETERS: Signature - ACPI table signature
+ *
+ * RETURN: TRUE if signature is a special ACPI table
+ *
+ * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
+ * table data structure (AcpiDmTableData).
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiUtIsSpecialTable (
+ char *Signature)
+{
+
+ if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
+ ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT) ||
+ ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
+ ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
+ ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtCreateTemplates
+ *
+ * PARAMETERS: Signature - ACPI table signature
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create one or more template files.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+DtCreateTemplates (
+ char *Signature)
+{
+ const ACPI_DMTABLE_DATA *TableData;
+ ACPI_STATUS Status;
+
+
+ AslInitializeGlobals ();
+
+ /* Default (no signature) is DSDT */
+
+ if (!Signature)
+ {
+ Signature = "DSDT";
+ goto GetTemplate;
+ }
+
+ AcpiUtStrupr (Signature);
+ if (!strcmp (Signature, "ALL") ||
+ !strcmp (Signature, "*"))
+ {
+ /* Create all available/known templates */
+
+ Status = DtCreateAllTemplates ();
+ return (Status);
+ }
+
+ /*
+ * Validate signature and get the template data:
+ * 1) Signature must be 4 characters
+ * 2) Signature must be a recognized ACPI table
+ * 3) There must be a template associated with the signature
+ */
+ if (strlen (Signature) != ACPI_NAME_SIZE)
+ {
+ fprintf (stderr,
+ "%s: Invalid ACPI table signature (length must be 4 characters)\n",
+ Signature);
+ return (AE_ERROR);
+ }
+
+ /*
+ * Some slack for the two strange tables whose name is different than
+ * their signatures: MADT->APIC and FADT->FACP.
+ */
+ if (!strcmp (Signature, "MADT"))
+ {
+ Signature = "APIC";
+ }
+ else if (!strcmp (Signature, "FADT"))
+ {
+ Signature = "FACP";
+ }
+
+GetTemplate:
+ TableData = AcpiDmGetTableData (Signature);
+ if (TableData)
+ {
+ if (!TableData->Template)
+ {
+ fprintf (stderr, "%4.4s: No template available\n", Signature);
+ return (AE_ERROR);
+ }
+ }
+ else if (!AcpiUtIsSpecialTable (Signature))
+ {
+ fprintf (stderr,
+ "%4.4s: Unrecognized ACPI table signature\n", Signature);
+ return (AE_ERROR);
+ }
+
+ Status = AdInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = DtCreateOneTemplate (Signature, TableData);
+
+
+ /* Shutdown ACPICA subsystem */
+
+ (void) AcpiTerminate ();
+ CmDeleteCaches ();
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtCreateAllTemplates
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create all currently defined template files
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+DtCreateAllTemplates (
+ void)
+{
+ const ACPI_DMTABLE_DATA *TableData;
+ ACPI_STATUS Status;
+
+
+ Status = AdInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ fprintf (stderr, "Creating all supported Template files\n");
+
+ /* Walk entire ACPI table data structure */
+
+ for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
+ {
+ /* If table has a template, create the template file */
+
+ if (TableData->Template)
+ {
+ Status = DtCreateOneTemplate (TableData->Signature,
+ TableData);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ /*
+ * Create the special ACPI tables:
+ * 1) DSDT/SSDT are AML tables, not data tables
+ * 2) FACS and RSDP have non-standard headers
+ */
+ Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtCreateOneTemplate
+ *
+ * PARAMETERS: Signature - ACPI signature, NULL terminated.
+ * TableData - Entry in ACPI table data structure.
+ * NULL if a special ACPI table.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create one template source file for the requested ACPI table.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+DtCreateOneTemplate (
+ char *Signature,
+ const ACPI_DMTABLE_DATA *TableData)
+{
+ char *DisasmFilename;
+ FILE *File;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_SIZE Actual;
+
+
+ /* New file will have a .asl suffix */
+
+ DisasmFilename = FlGenerateFilename (
+ Signature, FILE_SUFFIX_ASL_CODE);
+ if (!DisasmFilename)
+ {
+ fprintf (stderr, "Could not generate output filename\n");
+ return (AE_ERROR);
+ }
+
+ /* Probably should prompt to overwrite the file */
+
+ AcpiUtStrlwr (DisasmFilename);
+ File = fopen (DisasmFilename, "w+");
+ if (!File)
+ {
+ fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
+ return (AE_ERROR);
+ }
+
+ /* Emit the common file header */
+
+ AcpiOsRedirectOutput (File);
+
+ AcpiOsPrintf ("/*\n");
+ AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
+
+ AcpiOsPrintf (" * Template for [%4.4s] ACPI Table",
+ Signature);
+
+ /* Dump the actual ACPI table */
+
+ if (TableData)
+ {
+ /* Normal case, tables that appear in AcpiDmTableData */
+
+ AcpiOsPrintf (" (static data table)\n");
+
+ if (Gbl_VerboseTemplates)
+ {
+ AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
+ " FieldName : HexFieldValue\n */\n\n");
+ }
+ else
+ {
+ AcpiOsPrintf (" * Format: [ByteLength]"
+ " FieldName : HexFieldValue\n */\n");
+ }
+
+ AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
+ TableData->Template));
+ }
+ else
+ {
+ /* Special ACPI tables - DSDT, SSDT, OSDT, FADT, RSDP */
+
+ AcpiOsPrintf (" (AML byte code table)\n");
+
+ AcpiOsPrintf (" */\n");
+ if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
+ {
+ Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File);
+ if (Actual != sizeof (TemplateDsdt) -1)
+ {
+ fprintf (stderr,
+ "Could not write to output file %s\n", DisasmFilename);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+ }
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
+ {
+ Actual = fwrite (TemplateSsdt, 1, sizeof (TemplateSsdt) -1, File);
+ if (Actual != sizeof (TemplateSsdt) -1)
+ {
+ fprintf (stderr,
+ "Could not write to output file %s\n", DisasmFilename);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+ }
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT))
+ {
+ Actual = fwrite (TemplateOsdt, 1, sizeof (TemplateOsdt) -1, File);
+ if (Actual != sizeof (TemplateOsdt) -1)
+ {
+ fprintf (stderr,
+ "Could not write to output file %s\n", DisasmFilename);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+ }
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */
+ {
+ AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
+ TemplateFacs));
+ }
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
+ {
+ AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
+ TemplateRsdp));
+ }
+ else
+ {
+ fprintf (stderr,
+ "%4.4s, Unrecognized ACPI table signature\n", Signature);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+ }
+
+ fprintf (stderr,
+ "Created ACPI table template for [%4.4s], written to \"%s\"\n",
+ Signature, DisasmFilename);
+
+Cleanup:
+ fclose (File);
+ AcpiOsRedirectOutput (stdout);
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.h
new file mode 100644
index 0000000000..6f3ed64070
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dttemplate.h
@@ -0,0 +1,1299 @@
+/******************************************************************************
+ *
+ * Module Name: dttemplate.h - ACPI table template definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __DTTEMPLATE_H
+#define __DTTEMPLATE_H
+
+
+/* Special templates for the ASL/AML tables: DSDT, SSDT, and OSDT */
+
+const char TemplateDsdt[] =
+ "DefinitionBlock (\"dsdt.aml\", \"DSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n"
+ "{\n"
+ " Method (MAIN, 0, NotSerialized)\n"
+ " {\n"
+ " Return (Zero)\n"
+ " }\n"
+ "}\n\n";
+
+const char TemplateSsdt[] =
+ "DefinitionBlock (\"ssdt.aml\", \"SSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n"
+ "{\n"
+ " Method (MAIN, 0, NotSerialized)\n"
+ " {\n"
+ " Return (Zero)\n"
+ " }\n"
+ "}\n\n";
+
+const char TemplateOsdt[] =
+ "DefinitionBlock (\"osdt.aml\", \"OSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n"
+ "{\n"
+ " Method (MAIN, 0, NotSerialized)\n"
+ " {\n"
+ " Return (Zero)\n"
+ " }\n"
+ "}\n\n";
+
+
+/* Templates for ACPI data tables */
+
+const unsigned char TemplateAsf[] =
+{
+ 0x41,0x53,0x46,0x21,0x72,0x00,0x00,0x00, /* 00000000 "ASF!r..." */
+ 0x10,0x0B,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x10,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x14,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x01,0x0C,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x02,0x00,0x0C,0x00,0x01,0x04,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x17,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x84,0x00,0x07,0x00,0x00, /* 00000068 "........" */
+ 0x01,0x00 /* 00000070 ".." */
+};
+
+const unsigned char TemplateBgrt[] =
+{
+ 0x42,0x47,0x52,0x54,0x38,0x00,0x00,0x00, /* 00000000 "BGRT8..." */
+ 0x01,0x0D,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x23,0x06,0x11,0x20,0x01,0x00,0x00,0x00, /* 00000020 "#.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000030 "........" */
+};
+
+const unsigned char TemplateBert[] =
+{
+ 0x42,0x45,0x52,0x54,0x30,0x00,0x00,0x00, /* 00000000 "BERT0..." */
+ 0x01,0x15,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000028 "........" */
+};
+
+const unsigned char TemplateBoot[] =
+{
+ 0x42,0x4F,0x4F,0x54,0x28,0x00,0x00,0x00, /* 00000000 "BOOT(..." */
+ 0x01,0x0D,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x04,0x06,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00 /* 00000020 "(.. ...." */
+};
+
+const unsigned char TemplateCpep[] =
+{
+ 0x43,0x50,0x45,0x50,0x34,0x00,0x00,0x00, /* 00000000 "CPEP4..." */
+ 0x01,0x0F,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000030 "...." */
+};
+
+const unsigned char TemplateCsrt[] =
+{
+ 0x43,0x53,0x52,0x54,0x4C,0x01,0x00,0x00, /* 00000000 "CSRTL..." */
+ 0x01,0x0D,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x14,0x11,0x12,0x20,0x88,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x49,0x4E,0x54,0x4C,0x00,0x00,0x00,0x00, /* 00000028 "INTL...." */
+ 0x60,0x9C,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000030 "`......." */
+ 0x1C,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0xA0,0xB3,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x2A,0x00,0x00,0x00,0x02,0x00,0x06,0x20, /* 00000048 "*...... " */
+ 0x00,0x00,0x10,0x00,0xFF,0x0F,0x00,0x00, /* 00000050 "........" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x01,0x00, /* 00000058 "........" */
+ 0x53,0x50,0x49,0x20,0x0C,0x00,0x00,0x00, /* 00000060 "SPI ...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x30, /* 00000068 "....CHA0" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x43,0x48,0x41,0x31,0x0C,0x00,0x00,0x00, /* 00000078 "CHA1...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x32, /* 00000080 "....CHA2" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x43,0x48,0x41,0x33,0x0C,0x00,0x00,0x00, /* 00000090 "CHA3...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x34, /* 00000098 "....CHA4" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x43,0x48,0x41,0x35,0xA0,0x00,0x00,0x00, /* 000000A8 "CHA5...." */
+ 0x49,0x4E,0x54,0x4C,0x00,0x00,0x00,0x00, /* 000000B0 "INTL...." */
+ 0x60,0x9C,0x00,0x00,0x03,0x00,0x00,0x00, /* 000000B8 "`......." */
+ 0x1C,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x2B,0x00,0x00,0x00,0x02,0x00,0x08,0x20, /* 000000D0 "+...... " */
+ 0x10,0x00,0x10,0x00,0xFF,0x0F,0x00,0x00, /* 000000D8 "........" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x01,0x00, /* 000000E0 "........" */
+ 0x49,0x32,0x43,0x20,0x0C,0x00,0x00,0x00, /* 000000E8 "I2C ...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x30, /* 000000F0 "....CHA0" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x43,0x48,0x41,0x31,0x0C,0x00,0x00,0x00, /* 00000100 "CHA1...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x32, /* 00000108 "....CHA2" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x43,0x48,0x41,0x33,0x0C,0x00,0x00,0x00, /* 00000118 "CHA3...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x34, /* 00000120 "....CHA4" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 00000128 "........" */
+ 0x43,0x48,0x41,0x35,0x0C,0x00,0x00,0x00, /* 00000130 "CHA5...." */
+ 0x03,0x00,0x00,0x00,0x43,0x48,0x41,0x36, /* 00000138 "....CHA6" */
+ 0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 00000140 "........" */
+ 0x43,0x48,0x41,0x37 /* 00000148 "CHA7" */
+};
+
+const unsigned char TemplateDbg2[] =
+{
+ 0x44,0x42,0x47,0x32,0xB2,0x00,0x00,0x00, /* 00000000 "DBG2...." */
+ 0x01,0xBA,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x15,0x11,0x13,0x20,0x2C,0x00,0x00,0x00, /* 00000020 "... ,..." */
+ 0x02,0x00,0x00,0x00,0xEE,0x3F,0x00,0x02, /* 00000028 ".....?.." */
+ 0x09,0x00,0x36,0x00,0x00,0x00,0x00,0x00, /* 00000030 "..6....." */
+ 0x00,0x80,0x00,0x00,0x00,0x00,0x16,0x00, /* 00000038 "........" */
+ 0x2E,0x00,0x01,0x32,0x00,0x03,0x88,0x77, /* 00000040 "...2...w" */
+ 0x66,0x55,0x44,0x33,0x22,0x11,0x01,0x64, /* 00000048 "fUD3"..d" */
+ 0x00,0x04,0x11,0x00,0xFF,0xEE,0xDD,0xCC, /* 00000050 "........" */
+ 0xBB,0xAA,0x10,0x32,0x54,0x76,0x98,0xBA, /* 00000058 "...2Tv.." */
+ 0xDC,0xFE,0x4D,0x79,0x44,0x65,0x76,0x69, /* 00000060 "..MyDevi" */
+ 0x63,0x65,0x00,0xEE,0x47,0x00,0x01,0x11, /* 00000068 "ce..G..." */
+ 0x00,0x26,0x00,0x10,0x00,0x37,0x00,0x00, /* 00000070 ".&...7.." */
+ 0x80,0x00,0x00,0x00,0x00,0x16,0x00,0x22, /* 00000078 "......."" */
+ 0x00,0x01,0x64,0x00,0x04,0x11,0x00,0xFF, /* 00000080 "..d....." */
+ 0xEE,0xDD,0xCC,0xBB,0xAA,0x98,0xBA,0xDC, /* 00000088 "........" */
+ 0xFE,0x5C,0x5C,0x5F,0x53,0x42,0x5F,0x2E, /* 00000090 ".\\_SB_." */
+ 0x50,0x43,0x49,0x30,0x2E,0x44,0x42,0x47, /* 00000098 "PCI0.DBG" */
+ 0x50,0x00,0x41,0x42,0x43,0x44,0x45,0x46, /* 000000A0 "P.ABCDEF" */
+ 0x47,0x48,0x49,0x50,0x51,0x52,0x53,0x54, /* 000000A8 "GHIPQRST" */
+ 0x55,0x56 /* 000000B0 "UV" */
+};
+
+const unsigned char TemplateDbgp[] =
+{
+ 0x44,0x42,0x47,0x50,0x34,0x00,0x00,0x00, /* 00000000 "DBGP4..." */
+ 0x01,0x1A,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000030 "...." */
+};
+
+const unsigned char TemplateDmar[] =
+{
+ 0x44,0x4D,0x41,0x52,0x8C,0x00,0x00,0x00, /* 00000000 "DMAR...." */
+ 0x01,0x03,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x17,0x05,0x13,0x20,0x2F,0x01,0x00,0x00, /* 00000020 "... /..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x18,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x03,0x08,0x00,0x00,0x08,0x00,0x00,0x01, /* 00000040 "........" */
+ 0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00, /* 00000048 ".. ....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x02, /* 00000060 "........" */
+ 0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x02,0x08,0x00,0x00,0x00,0x00,0x00,0x03, /* 00000070 "........" */
+ 0x03,0x00,0x14,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000088 "...." */
+};
+
+const unsigned char TemplateDrtm[] =
+{
+ 0x44,0x52,0x54,0x4D,0x94,0x00,0x00,0x00, /* 00000000 "DRTM...." */
+ 0x01,0xB9,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000090 "...." */
+};
+
+const unsigned char TemplateEcdt[] =
+{
+ 0x45,0x43,0x44,0x54,0x42,0x00,0x00,0x00, /* 00000000 "ECDTB..." */
+ 0x01,0x2D,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".-INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x01,0x08,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "f......." */
+ 0x01,0x08,0x00,0x00,0x62,0x00,0x00,0x00, /* 00000030 "....b..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x09,0x00 /* 00000040 ".." */
+};
+
+const unsigned char TemplateEinj[] =
+{
+ 0x45,0x49,0x4E,0x4A,0x30,0x01,0x00,0x00, /* 00000000 "EINJ0..." */
+ 0x01,0x09,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x30,0x00,0x00,0x00, /* 00000020 "(.. 0..." */
+ 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000030 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000048 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000050 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000068 "........" */
+ 0x02,0x02,0x01,0x00,0x00,0x40,0x00,0x04, /* 00000070 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000088 "........" */
+ 0x03,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000090 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000A8 "........" */
+ 0x04,0x03,0x01,0x00,0x00,0x40,0x00,0x04, /* 000000B0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000C8 "........" */
+ 0x05,0x03,0x01,0x00,0x01,0x10,0x00,0x02, /* 000000D0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000E8 "........" */
+ 0x06,0x01,0x00,0x00,0x00,0x40,0x00,0x04, /* 000000F0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000108 "........" */
+ 0x07,0x00,0x01,0x00,0x00,0x40,0x00,0x04, /* 00000110 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF /* 00000128 "........" */
+};
+
+const unsigned char TemplateErst[] =
+{
+ 0x45,0x52,0x53,0x54,0x30,0x02,0x00,0x00, /* 00000000 "ERST0..." */
+ 0x01,0xAB,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x30,0x00,0x00,0x00, /* 00000020 "(.. 0..." */
+ 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x03,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000030 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000048 "........" */
+ 0x01,0x03,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000050 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000068 "........" */
+ 0x02,0x03,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000070 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000088 "........" */
+ 0x03,0x04,0x01,0x00,0x00,0x40,0x00,0x04, /* 00000090 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000A8 "........" */
+ 0x04,0x02,0x00,0x00,0x00,0x40,0x00,0x04, /* 000000B0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000C8 "........" */
+ 0x05,0x03,0x00,0x00,0x01,0x08,0x00,0x01, /* 000000D0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000000E8 "........" */
+ 0x06,0x01,0x00,0x00,0x00,0x40,0x00,0x04, /* 000000F0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000108 "........" */
+ 0x07,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000110 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000128 "........" */
+ 0x08,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000130 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000140 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000148 "........" */
+ 0x09,0x02,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000150 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000160 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000168 "........" */
+ 0x0A,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000170 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000180 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000188 "........" */
+ 0x0B,0x03,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000190 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000198 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001A0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000001A8 "........" */
+ 0x0C,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 000001B0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001B8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001C0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000001C8 "........" */
+ 0x0D,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 000001D0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001E0 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 000001E8 "........" */
+ 0x0E,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 000001F0 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000200 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000208 "........" */
+ 0x0F,0x00,0x00,0x00,0x00,0x40,0x00,0x04, /* 00000210 ".....@.." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000218 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000220 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF /* 00000228 "........" */
+};
+
+const unsigned char TemplateFacs[] =
+{
+ 0x46,0x41,0x43,0x53,0x40,0x00,0x00,0x00, /* 00000000 "FACS@..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000008 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000010 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000018 "........" */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000020 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000038 "........" */
+};
+
+/* Version 5 FADT */
+
+const unsigned char TemplateFadt[] =
+{
+ 0x46,0x41,0x43,0x50,0x14,0x01,0x00,0x00, /* 00000000 "FACP...." */
+ 0x06,0x8A,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x01,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x04,0x02,0x01,0x04,0x08,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x01, /* 00000070 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x02, /* 00000090 "..... .." */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x10,0x00,0x02, /* 000000A8 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x00, /* 000000C0 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x01,0x20,0x00,0x03,0x01,0x00,0x00,0x00, /* 000000D0 ". ......" */
+ 0x00,0x00,0x00,0x00,0x01,0x40,0x00,0x01, /* 000000D8 ".....@.." */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x01, /* 000000F0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x01,0x08,0x00,0x01,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000110 "...." */
+};
+
+const unsigned char TemplateFpdt[] =
+{
+ 0x46,0x50,0x44,0x54,0x64,0x00,0x00,0x00, /* 00000000 "FPDTd..." */
+ 0x01,0xBD,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x04,0x08,0x11,0x20,0x00,0x00,0x30,0x01, /* 00000020 "... ..0." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x01, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000060 "...." */
+};
+
+const unsigned char TemplateGtdt[] =
+{
+ 0x47,0x54,0x44,0x54,0xe0,0x00,0x00,0x00, /* 00000000 "GTDT...." */
+ 0x02,0xb0,0x4c,0x49,0x4e,0x41,0x52,0x4f, /* 00000008 "..LINARO" */
+ 0x52,0x54,0x53,0x4d,0x56,0x45,0x56,0x38, /* 00000010 "RTSMVEV8" */
+ 0x01,0x00,0x00,0x00,0x49,0x4e,0x54,0x4c, /* 00000018 "....INTL" */
+ 0x24,0x04,0x14,0x20,0x00,0x00,0x00,0x00, /* 00000020 "$.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x1d,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x1b,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x1a,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x02,0x00,0x00,0x00,0x60,0x00,0x00,0x00, /* 00000058 "....`..." */
+ 0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 ".d......" */
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000a0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000a8 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000b0 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000b8 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x1c,0x00,0x00, /* 000000c0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000c8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000d0 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000d8 "........" */
+};
+
+const unsigned char TemplateHest[] =
+{
+ 0x48,0x45,0x53,0x54,0xD4,0x01,0x00,0x00, /* 00000000 "HEST...." */
+ 0x01,0x20,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ". INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x04,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, /* 00000028 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01, /* 00000088 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000D0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x01, /* 000000F0 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00, /* 00000120 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000128 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000140 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000148 "........" */
+ 0x00,0x00,0x00,0x00,0x09,0x00,0x02,0x00, /* 00000150 "........" */
+ 0xFF,0xFF,0x00,0x01,0x01,0x00,0x00,0x00, /* 00000158 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00, /* 00000160 "........" */
+ 0x00,0x40,0x00,0x04,0x00,0x00,0x00,0x00, /* 00000168 ".@......" */
+ 0x00,0x00,0x00,0x00,0x03,0x1C,0x00,0x00, /* 00000170 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000180 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000188 "........" */
+ 0x00,0x10,0x00,0x00,0x09,0x00,0x03,0x00, /* 00000190 "........" */
+ 0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00, /* 00000198 "........" */
+ 0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00, /* 000001A0 "........" */
+ 0x00,0x40,0x00,0x04,0x00,0x00,0x00,0x00, /* 000001A8 ".@......" */
+ 0x00,0x00,0x00,0x00,0x04,0x1C,0x00,0x00, /* 000001B0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001B8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001C8 "........" */
+ 0x00,0x10,0x00,0x00 /* 000001D0 "...." */
+};
+
+const unsigned char TemplateHpet[] =
+{
+ 0x48,0x50,0x45,0x54,0x38,0x00,0x00,0x00, /* 00000000 "HPET8..." */
+ 0x01,0x09,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000030 "........" */
+};
+
+const unsigned char TemplateIort[] =
+{
+ 0x49,0x4F,0x52,0x54,0x0C,0x01,0x00,0x00, /* 00000000 "IORT...." */
+ 0x00,0xBC,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x04,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "4......." */
+ 0x00,0x00,0x00,0x00,0x00,0x2C,0x00,0x00, /* 00000030 ".....,.." */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x18,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 ".0......" */
+ 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00, /* 00000068 "....0..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x5C,0x5F,0x53, /* 00000078 ".....\_S" */
+ 0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,0x44, /* 00000080 "B.PCI0.D" */
+ 0x45,0x56,0x30,0x00,0x00,0x00,0x00,0x00, /* 00000088 "EV0....." */
+ 0x02,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 ". ......" */
+ 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, /* 00000098 ".... ..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x03,0x5C,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 ".\......" */
+ 0x00,0x00,0x00,0x00,0x5C,0x00,0x00,0x00, /* 000000B8 "....\..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */
+ 0x3C,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000D8 "<......." */
+ 0x4C,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000E0 "L......." */
+ 0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "T......." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000108 "...." */
+};
+
+const unsigned char TemplateIvrs[] =
+{
+ 0x49,0x56,0x52,0x53,0xBC,0x00,0x00,0x00, /* 00000000 "IVRS...." */
+ 0x01,0x87,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x10,0x14,0x34,0x00,0x00,0x00,0x00,0x00, /* 00000030 "..4....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 00000048 "....@..." */
+ 0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00, /* 00000050 "....B..." */
+ 0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00, /* 00000058 "....H..." */
+ 0x00,0x00,0x00,0x00,0x20,0x08,0x20,0x00, /* 00000060 ".... . ." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x21,0x04,0x20,0x00, /* 00000080 "....!. ." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x10,0x14,0x18,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x00,0x00,0x00,0x00 /* 000000B8 "...." */
+};
+
+const unsigned char TemplateLpit[] =
+{
+ 0x4C,0x50,0x49,0x54,0x94,0x00,0x00,0x00, /* 00000000 "LPIT...." */
+ 0x00,0xD8,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "8......." */
+ 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x01, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x7F,0x40,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 ".@......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "8......." */
+ 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x01, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x7F,0x40,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 ".@......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000090 "...." */
+};
+
+/* MADT with ACPI 6.0 subtables */
+
+const unsigned char TemplateMadt[] =
+{
+ 0x41,0x50,0x49,0x43,0x5A,0x01,0x00,0x00, /* 00000000 "APICZ..." */
+ 0x03,0xEA,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x00, /* 00000028 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x0C,0x01,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x02,0x0A,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x03,0x08,0x0D,0x00,0x01,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x04,0x06,0x00,0x05,0x00,0x01, /* 00000050 "........" */
+ 0x05,0x0C,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x06,0x10,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x07,0x16,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x5C,0x43,0x50,0x55, /* 00000080 "....\CPU" */
+ 0x30,0x00,0x08,0x10,0x05,0x00,0x00,0x00, /* 00000088 "0......." */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x09,0x10,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x0A,0x0C,0x05,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x50, /* 000000B0 ".......P" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x18, /* 00000100 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x0D,0x18, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, /* 00000128 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x10, /* 00000130 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x14, /* 00000140 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000148 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000150 "........" */
+ 0x00,0x00 /* 00000158 ".." */
+};
+
+const unsigned char TemplateMcfg[] =
+{
+ 0x4D,0x43,0x46,0x47,0x3C,0x00,0x00,0x00, /* 00000000 "MCFG<..." */
+ 0x01,0x19,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000038 "...." */
+};
+
+const unsigned char TemplateMchi[] =
+{
+ 0x4D,0x43,0x48,0x49,0x45,0x00,0x00,0x00, /* 00000000 "MCHIE..." */
+ 0x01,0xE4,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x15,0x07,0x00,0x02,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x01,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x08,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00 /* 00000040 "....." */
+};
+
+const unsigned char TemplateMsdm[] =
+{
+ 0x4D,0x53,0x44,0x4D,0x64,0x00,0x00,0x00, /* 00000000 "MSDMd..." */
+ 0x01,0x34,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 ".4Intel." */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x03,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x04,0x02,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x0A,0x10,0x16,0x17,0x18,0x19,0x1A,0x1B, /* 00000028 "........" */
+ 0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23, /* 00000030 ".... !"#" */
+ 0x24,0x25,0x26,0x27,0x10,0x0A,0x15,0x16, /* 00000038 "$%&'...." */
+ 0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E, /* 00000040 "........" */
+ 0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26, /* 00000048 ". !"#$%&" */
+ 0x16,0x15,0x0A,0x10,0x16,0x17,0x18,0x19, /* 00000050 "........" */
+ 0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21, /* 00000058 "...... !" */
+ 0x22,0x23,0x24,0x25 /* 00000060 ""#$%" */
+};
+
+const unsigned char TemplateMpst[] =
+{
+ 0x4D,0x50,0x53,0x54,0xB6,0x00,0x00,0x00, /* 00000000 "MPST...." */
+ 0x01,0x77,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".wINTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x13,0x09,0x12,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00 /* 000000B0 "......" */
+};
+
+const unsigned char TemplateMsct[] =
+{
+ 0x4D,0x53,0x43,0x54,0x90,0x00,0x00,0x00, /* 00000000 "MSCT...." */
+ 0x01,0xB7,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x38,0x00,0x00,0x00, /* 00000020 "(.. 8..." */
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00, /* 00000030 "........" */
+ 0x01,0x16,0x00,0x00,0x00,0x00,0x03,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x40,0x00,0x00,0x00,0x01,0x16, /* 00000048 "..@....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x16,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x01,0x16,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000088 "........" */
+};
+
+const unsigned char TemplateNfit[] =
+{
+ 0x4E,0x46,0x49,0x54,0x70,0x01,0x00,0x00, /* 00000000 "NFITp..." */
+ 0x01,0x53,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".SINTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x38,0x00,0x01,0x00,0x00,0x00, /* 00000028 "..8....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x30,0x05,0xAF,0x91,0x86,0x5D,0x0E,0x47, /* 00000038 "0....].G" */
+ 0xA6,0xB0,0x0A,0x2D,0xB9,0x40,0x82,0x49, /* 00000040 "...-.@.I" */
+ 0x00,0x00,0x00,0x7C,0x03,0x00,0x00,0x00, /* 00000048 "...|...." */
+ 0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x01,0x00,0x30,0x00,0x01,0x00,0x00,0x00, /* 00000060 "..0....." */
+ 0x04,0x00,0x00,0x00,0x01,0x00,0x01,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x01,0x00,0x03,0x00,0x2A,0x00,0x00,0x00, /* 00000088 "....*..." */
+ 0x02,0x00,0x20,0x00,0x01,0x00,0x00,0x00, /* 00000090 ".. ....." */
+ 0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x06,0x00,0x00,0x00,0x09,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x03,0x00,0x28,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "..(....." */
+ 0xB4,0x13,0x5D,0x40,0x91,0x0B,0x29,0x93, /* 000000B8 "..]@..)." */
+ 0x67,0xE8,0x23,0x4C,0x00,0x00,0x00,0x88, /* 000000C0 "g.#L...." */
+ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, /* 000000C8 ".."3DUfw" */
+ 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, /* 000000D0 "........" */
+ 0x04,0x00,0x50,0x00,0x01,0x00,0x86,0x80, /* 000000D8 "..P....." */
+ 0x17,0x20,0x01,0x00,0x86,0x80,0x17,0x20, /* 000000E0 ". ..... " */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x89,0x00,0x54,0x76,0x01,0x03,0x00,0x01, /* 000000F0 "..Tv...." */
+ 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 ". ......" */
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x10,0x80,0x00,0x00,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0x05,0x00,0x28,0x00,0x01,0x00,0x00,0x01, /* 00000128 "..(....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */
+ 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 ". ......" */
+ 0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00, /* 00000140 "........" */
+ 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00, /* 00000148 "........" */
+ 0x06,0x00,0x20,0x00,0x01,0x00,0x00,0x00, /* 00000150 ".. ....." */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
+ 0x00,0x00,0x00,0x18,0x04,0x00,0x00,0x00, /* 00000160 "........" */
+ 0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x00 /* 00000168 "........" */
+};
+
+const unsigned char TemplateMtmr[] =
+{
+ 0x4D,0x54,0x4D,0x52,0x4C,0x00,0x00,0x00, /* 00000000 "MTMRL..." */
+ 0x01,0xB0,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x03,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x17,0x01,0x13,0x20,0x00,0x20,0x00,0x03, /* 00000020 "... . .." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x20,0x00,0x03,0x00,0x00,0x00,0x00, /* 00000038 ". ......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000048 "...." */
+};
+
+const unsigned char TemplatePcct[] =
+{
+ 0x50,0x43,0x43,0x54,0xAC,0x00,0x00,0x00, /* 00000000 "PCCT...." */
+ 0x01,0xCF,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x27,0x06,0x14,0x20,0x01,0x00,0x00,0x00, /* 00000020 "'.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 ".>......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x01,0x32,0x00,0x03,0x00,0x00,0x00,0x00, /* 00000048 ".2......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, /* 00000058 "........" */
+ 0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x3E, /* 00000068 ".......>" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x32, /* 00000080 ".......2" */
+ 0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* 00000098 "........" */
+ 0xFF,0xFF,0x01,0x00,0x00,0x00,0x01,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x01,0x00 /* 000000A8 "...." */
+};
+
+const unsigned char TemplatePmtt[] =
+{
+ 0x50,0x4D,0x54,0x54,0xB4,0x00,0x00,0x00, /* 00000000 "PMTT...." */
+ 0x01,0x3A,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".:INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x26,0x08,0x11,0x20,0x00,0x00,0x00,0x00, /* 00000020 "&.. ...." */
+ 0x00,0x00,0x80,0x00,0x01,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x54,0x00, /* 00000030 "......T." */
+ 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x02,0x00,0x14,0x00,0x02,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x14,0x00, /* 00000070 "........" */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x01,0x00,0x20,0x00,0x01,0x00,0x00,0x00, /* 00000088 ".. ....." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x0C,0x00,0x01,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00 /* 000000B0 "...." */
+};
+
+const unsigned char TemplateRsdp[] =
+{
+ 0x52,0x53,0x44,0x20,0x50,0x54,0x52,0x20, /* 00000000 "RSD PTR " */
+ 0x43,0x49,0x4E,0x54,0x45,0x4C,0x20,0x02, /* 00000008 "CINTEL ." */
+ 0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x00, /* 00000010 "....$..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000018 "........" */
+ 0xDC,0x00,0x00,0x00 /* 00000020 "...." */
+};
+
+const unsigned char TemplateRsdt[] =
+{
+ 0x52,0x53,0x44,0x54,0x44,0x00,0x00,0x00, /* 00000000 "RSDTD..." */
+ 0x01,0xB1,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x10,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x20,0x00,0x00,0x00,0x30,0x00,0x00,0x00, /* 00000028 " ...0..." */
+ 0x40,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 00000030 "@...P..." */
+ 0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00, /* 00000038 "`...p..." */
+ 0x80,0x00,0x00,0x00 /* 00000040 "...." */
+};
+
+const unsigned char TemplateS3pt[] =
+{
+ 0x53,0x33,0x50,0x54,0x34,0x00,0x00,0x00, /* 00000000 "S3PT4..." */
+ 0x00,0x00,0x18,0x01,0x00,0x00,0x00,0x00, /* 00000008 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000010 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000018 "........" */
+ 0x01,0x00,0x14,0x01,0x00,0x00,0x00,0x00, /* 00000020 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000030 "...." */
+};
+
+const unsigned char TemplateSbst[] =
+{
+ 0x53,0x42,0x53,0x54,0x30,0x00,0x00,0x00, /* 00000000 "SBST0..." */
+ 0x01,0x06,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000028 "........" */
+};
+
+const unsigned char TemplateSlic[] =
+{
+ 0x53,0x4C,0x49,0x43,0x76,0x01,0x00,0x00, /* 00000000 "SLICv..." */
+ 0x01,0x07,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x11,0x02,0x11,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x9C,0x00,0x00,0x00,0x06,0x02,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x31, /* 00000030 ".$..RSA1" */
+ 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x01,0x00,0x00,0x00,0xB6,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x02,0x00,0x49,0x4E,0x54,0x45, /* 000000C8 "....INTE" */
+ 0x4C,0x20,0x54,0x45,0x4D,0x50,0x4C,0x41, /* 000000D0 "L TEMPLA" */
+ 0x54,0x45,0x57,0x49,0x4E,0x44,0x4F,0x57, /* 000000D8 "TEWINDOW" */
+ 0x53,0x20,0x01,0x00,0x02,0x00,0x00,0x00, /* 000000E0 "S ......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000128 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000140 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000148 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000150 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000160 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000168 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00 /* 00000170 "......" */
+};
+
+const unsigned char TemplateSlit[] =
+{
+ 0x53,0x4C,0x49,0x54,0xBC,0x01,0x00,0x00, /* 00000000 "SLIT...." */
+ 0x01,0x00,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x16,0x03,0x11,0x20,0x14,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x00,0x0A,0x10,0x16,0x17, /* 00000028 "........" */
+ 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, /* 00000030 "........" */
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, /* 00000038 " !"#$%&'" */
+ 0x10,0x0A,0x15,0x16,0x17,0x18,0x19,0x1A, /* 00000040 "........" */
+ 0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, /* 00000048 "..... !"" */
+ 0x23,0x24,0x25,0x26,0x16,0x15,0x0A,0x10, /* 00000050 "#$%&...." */
+ 0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D, /* 00000058 "........" */
+ 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25, /* 00000060 ".. !"#$%" */
+ 0x17,0x16,0x10,0x0A,0x15,0x16,0x17,0x18, /* 00000068 "........" */
+ 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20, /* 00000070 "....... " */
+ 0x21,0x22,0x23,0x24,0x18,0x17,0x16,0x15, /* 00000078 "!"#$...." */
+ 0x0A,0x10,0x16,0x17,0x18,0x19,0x1A,0x1B, /* 00000080 "........" */
+ 0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23, /* 00000088 ".... !"#" */
+ 0x19,0x18,0x17,0x16,0x10,0x0A,0x15,0x16, /* 00000090 "........" */
+ 0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E, /* 00000098 "........" */
+ 0x1F,0x20,0x21,0x22,0x1A,0x19,0x18,0x17, /* 000000A0 ". !"...." */
+ 0x16,0x15,0x0A,0x10,0x16,0x17,0x18,0x19, /* 000000A8 "........" */
+ 0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21, /* 000000B0 "...... !" */
+ 0x1B,0x1A,0x19,0x18,0x17,0x16,0x10,0x0A, /* 000000B8 "........" */
+ 0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C, /* 000000C0 "........" */
+ 0x1D,0x1E,0x1F,0x20,0x1C,0x1B,0x1A,0x19, /* 000000C8 "... ...." */
+ 0x18,0x17,0x16,0x15,0x0A,0x10,0x16,0x17, /* 000000D0 "........" */
+ 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, /* 000000D8 "........" */
+ 0x1D,0x1C,0x1B,0x1A,0x19,0x18,0x17,0x16, /* 000000E0 "........" */
+ 0x10,0x0A,0x15,0x16,0x17,0x18,0x19,0x1A, /* 000000E8 "........" */
+ 0x1B,0x1C,0x1D,0x1E,0x1E,0x1D,0x1C,0x1B, /* 000000F0 "........" */
+ 0x1A,0x19,0x18,0x17,0x16,0x15,0x0A,0x10, /* 000000F8 "........" */
+ 0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D, /* 00000100 "........" */
+ 0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18, /* 00000108 "........" */
+ 0x17,0x16,0x10,0x0A,0x15,0x16,0x17,0x18, /* 00000110 "........" */
+ 0x19,0x1A,0x1B,0x1C,0x20,0x1F,0x1E,0x1D, /* 00000118 ".... ..." */
+ 0x1C,0x1B,0x1A,0x19,0x18,0x17,0x16,0x15, /* 00000120 "........" */
+ 0x0A,0x10,0x16,0x17,0x18,0x19,0x1A,0x1B, /* 00000128 "........" */
+ 0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x1A, /* 00000130 "! ......" */
+ 0x19,0x18,0x17,0x16,0x10,0x0A,0x15,0x16, /* 00000138 "........" */
+ 0x17,0x18,0x19,0x1A,0x22,0x21,0x20,0x1F, /* 00000140 "...."! ." */
+ 0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18,0x17, /* 00000148 "........" */
+ 0x16,0x15,0x0A,0x10,0x16,0x17,0x18,0x19, /* 00000150 "........" */
+ 0x23,0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C, /* 00000158 "#"! ...." */
+ 0x1B,0x1A,0x19,0x18,0x17,0x16,0x10,0x0A, /* 00000160 "........" */
+ 0x15,0x16,0x17,0x18,0x24,0x23,0x22,0x21, /* 00000168 "....$#"!" */
+ 0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19, /* 00000170 " ......." */
+ 0x18,0x17,0x16,0x15,0x0A,0x10,0x16,0x17, /* 00000178 "........" */
+ 0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E, /* 00000180 "%$#"! .." */
+ 0x1D,0x1C,0x1B,0x1A,0x19,0x18,0x17,0x16, /* 00000188 "........" */
+ 0x10,0x0A,0x15,0x16,0x26,0x25,0x24,0x23, /* 00000190 "....&%$#" */
+ 0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x1B, /* 00000198 ""! ....." */
+ 0x1A,0x19,0x18,0x17,0x16,0x15,0x0A,0x10, /* 000001A0 "........" */
+ 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, /* 000001A8 "'&%$#"! " */
+ 0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18, /* 000001B0 "........" */
+ 0x17,0x16,0x10,0x0A /* 000001B8 "...." */
+};
+
+const unsigned char TemplateSpcr[] =
+{
+ 0x53,0x50,0x43,0x52,0x50,0x00,0x00,0x00, /* 00000000 "SPCRP..." */
+ 0x01,0xE3,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000048 "........" */
+};
+
+const unsigned char TemplateSpmi[] =
+{
+ 0x53,0x50,0x4D,0x49,0x41,0x00,0x00,0x00, /* 00000000 "SPMIA..." */
+ 0x04,0x00,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x14,0x01,0x14,0x20,0x00,0x01,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00 /* 00000040 "." */
+};
+
+const unsigned char TemplateSrat[] =
+{
+ 0x53,0x52,0x41,0x54,0x92,0x00,0x00,0x00, /* 00000000 "SRAT...." */
+ 0x03,0x50,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".PINTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x24,0x07,0x14,0x20,0x01,0x00,0x00,0x00, /* 00000020 "$.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x10,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x01,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 ".(......" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0xFC,0x09,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
+ 0x02,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000070 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
+ 0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
+ 0x00,0x00 /* 00000090 ".." */
+};
+
+const unsigned char TemplateStao[] =
+{
+ 0x53,0x54,0x41,0x4F,0x7E,0x00,0x00,0x00, /* 00000000 "STAO~..." */
+ 0x01,0x7F,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x01,0x5C,0x5F,0x53, /* 00000020 "... .\_S" */
+ 0x42,0x30,0x2E,0x42,0x55,0x53,0x30,0x2E, /* 00000028 "B0.BUS0." */
+ 0x44,0x45,0x56,0x31,0x00,0x5C,0x5F,0x53, /* 00000030 "DEV1.\_S" */
+ 0x42,0x30,0x2E,0x42,0x55,0x53,0x30,0x2E, /* 00000038 "B0.BUS0." */
+ 0x44,0x45,0x56,0x32,0x00,0x5C,0x5F,0x53, /* 00000040 "DEV2.\_S" */
+ 0x42,0x30,0x2E,0x42,0x55,0x53,0x31,0x2E, /* 00000048 "B0.BUS1." */
+ 0x44,0x45,0x56,0x31,0x2E,0x44,0x45,0x56, /* 00000050 "DEV1.DEV" */
+ 0x32,0x00,0x5C,0x5F,0x53,0x42,0x30,0x2E, /* 00000058 "2.\_SB0." */
+ 0x42,0x55,0x53,0x31,0x2E,0x44,0x45,0x56, /* 00000060 "BUS1.DEV" */
+ 0x32,0x2E,0x44,0x45,0x56,0x32,0x00,0x5C, /* 00000068 "2.DEV2.\" */
+ 0x55,0x53,0x42,0x31,0x2E,0x48,0x55,0x42, /* 00000070 "USB1.HUB" */
+ 0x31,0x2E,0x50,0x54,0x31,0x00 /* 00000078 "1.PT1." */
+};
+
+const unsigned char TemplateTcpa[] =
+{
+ 0x54,0x43,0x50,0x41,0x64,0x00,0x00,0x00, /* 00000000 "TCPAd..." */
+ 0x02,0xFF,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x80,0x31,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 ".1..INTL" */
+ 0x19,0x06,0x15,0x20,0x01,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x11,0x00,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA, /* 00000030 "........" */
+ 0x02,0x01,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x03, /* 00000040 "..... .." */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x03, /* 00000050 "..... .." */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x01,0x01,0x01,0x01 /* 00000060 "...." */
+};
+
+const unsigned char TemplateTpm2[] =
+{
+ 0x54,0x50,0x4D,0x32,0x34,0x00,0x00,0x00, /* 00000000 "TPM24..." */
+ 0x03,0x42,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".BINTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x14,0x11,0x12,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00, /* 00000028 "wfUD3".." */
+ 0x01,0x00,0x00,0x00 /* 00000030 "...." */
+};
+
+const unsigned char TemplateUefi[] =
+{
+ 0x55,0x45,0x46,0x49,0x36,0x00,0x00,0x00, /* 00000000 "UEFI6..." */
+ 0x01,0x9B,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x01,0x02,0x03, /* 00000020 "(.. ...." */
+ 0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B, /* 00000028 "........" */
+ 0x0C,0x0D,0x0E,0x0F,0x00,0x00 /* 00000030 "......" */
+};
+
+const unsigned char TemplateVrtc[] =
+{
+ 0x56,0x52,0x54,0x43,0x44,0x00,0x00,0x00, /* 00000000 "VRTCD..." */
+ 0x01,0xEF,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x03,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x17,0x01,0x13,0x20,0x00,0x08,0x00,0x00, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000040 "...." */
+};
+
+const unsigned char TemplateWaet[] =
+{
+ 0x57,0x41,0x45,0x54,0x28,0x00,0x00,0x00, /* 00000000 "WAET(..." */
+ 0x01,0x19,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00 /* 00000020 "(.. ...." */
+};
+
+const unsigned char TemplateWdat[] =
+{
+ 0x57,0x44,0x41,0x54,0x5C,0x00,0x00,0x00, /* 00000000 "WDAT\..." */
+ 0x01,0xE3,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x20,0x00,0x00,0x00, /* 00000020 "(.. ..." */
+ 0xFF,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x58,0x02,0x00,0x00,0xFF,0x03,0x00,0x00, /* 00000030 "X......." */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
+ 0x0E,0x00,0x00,0x00,0x01,0x02,0x00,0x00, /* 00000040 "........" */
+ 0x01,0x10,0x00,0x02,0x60,0x04,0x00,0x00, /* 00000048 "....`..." */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000050 "........" */
+ 0x01,0x00,0x00,0x00 /* 00000058 "...." */
+};
+
+const unsigned char TemplateWddt[] =
+{
+ 0x57,0x44,0x44,0x54,0x40,0x00,0x00,0x00, /* 00000000 "WDDT@..." */
+ 0x01,0x00,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x01,0xFF,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000038 "........" */
+};
+
+const unsigned char TemplateWdrt[] =
+{
+ 0x57,0x44,0x52,0x54,0x47,0x00,0x00,0x00, /* 00000000 "WDRTG..." */
+ 0x01,0xB0,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x00,0x20,0x00,0x00, /* 00000020 "(.. . .." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 ". ......" */
+ 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, /* 00000038 "........" */
+ 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00 /* 00000040 "......." */
+};
+
+const unsigned char TemplateWpbt[] =
+{
+ 0x57,0x50,0x42,0x54,0x98,0x00,0x00,0x00, /* 00000000 "WPBT...." */
+ 0x01,0x83,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x78,0x56,0x34,0x12, /* 00000020 "... xV4." */
+ 0x00,0x00,0x00,0xBB,0x00,0x00,0x00,0xAA, /* 00000028 "........" */
+ 0x33,0x88,0x64,0x00,0x34,0x00,0x20,0x00, /* 00000030 "3.d.4. ." */
+ 0x73,0x00,0x63,0x00,0x6F,0x00,0x72,0x00, /* 00000038 "s.c.o.r." */
+ 0x65,0x00,0x20,0x00,0x61,0x00,0x6E,0x00, /* 00000040 "e. .a.n." */
+ 0x64,0x00,0x20,0x00,0x37,0x00,0x20,0x00, /* 00000048 "d. .7. ." */
+ 0x79,0x00,0x65,0x00,0x61,0x00,0x72,0x00, /* 00000050 "y.e.a.r." */
+ 0x73,0x00,0x20,0x00,0x61,0x00,0x67,0x00, /* 00000058 "s. .a.g." */
+ 0x6F,0x00,0x20,0x00,0x6F,0x00,0x75,0x00, /* 00000060 "o. .o.u." */
+ 0x72,0x00,0x20,0x00,0x66,0x00,0x61,0x00, /* 00000068 "r. .f.a." */
+ 0x74,0x00,0x68,0x00,0x65,0x00,0x72,0x00, /* 00000070 "t.h.e.r." */
+ 0x73,0x00,0x20,0x00,0x62,0x00,0x72,0x00, /* 00000078 "s. .b.r." */
+ 0x6F,0x00,0x75,0x00,0x67,0x00,0x68,0x00, /* 00000080 "o.u.g.h." */
+ 0x74,0x00,0x20,0x00,0x66,0x00,0x6F,0x00, /* 00000088 "t. .f.o." */
+ 0x72,0x00,0x74,0x00,0x68,0x00,0x00,0x00 /* 00000090 "r.t.h..." */
+};
+
+const unsigned char TemplateXenv[] =
+{
+ 0x58,0x45,0x4E,0x56,0x39,0x00,0x00,0x00, /* 00000000 "XENV9..." */
+ 0x01,0x3A,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".:INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x10, /* 00000020 "... ...." */
+ 0x00,0x00,0x00,0x0A,0x00,0x20,0x00,0x00, /* 00000028 "..... .." */
+ 0x00,0x00,0x00,0x0B,0x25,0x00,0xBB,0xAA, /* 00000030 "....%..." */
+ 0x03 /* 00000038 "." */
+};
+
+const unsigned char TemplateXsdt[] =
+{
+ 0x58,0x53,0x44,0x54,0x64,0x00,0x00,0x00, /* 00000000 "XSDTd..." */
+ 0x01,0x8B,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x28,0x05,0x10,0x20,0x10,0x00,0x00,0x00, /* 00000020 "(.. ...." */
+ 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, /* 00000028 ".... ..." */
+ 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00, /* 00000030 "....0..." */
+ 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, /* 00000038 "....@..." */
+ 0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00, /* 00000040 "....P..." */
+ 0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00, /* 00000048 "....`..." */
+ 0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00, /* 00000050 "....p..." */
+ 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* 00000058 "........" */
+ 0x00,0x00,0x00,0x00 /* 00000060 "...." */
+};
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/dtutils.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtutils.c
new file mode 100644
index 0000000000..ce996c46df
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/dtutils.c
@@ -0,0 +1,1001 @@
+/******************************************************************************
+ *
+ * Module Name: dtutils.c - Utility routines for the data table compiler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT DT_COMPILER
+ ACPI_MODULE_NAME ("dtutils")
+
+/* Local prototypes */
+
+static void
+DtSum (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * Op - Parse node where error happened
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Common error interface for data table compiler
+ *
+ *****************************************************************************/
+
+void
+DtError (
+ UINT8 Level,
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage)
+{
+
+ /* Check if user wants to ignore this exception */
+
+ if (AslIsExceptionDisabled (Level, MessageId))
+ {
+ return;
+ }
+
+ if (FieldObject)
+ {
+ AslCommonError (Level, MessageId,
+ FieldObject->Line,
+ FieldObject->Line,
+ FieldObject->ByteOffset,
+ FieldObject->Column,
+ Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
+ }
+ else
+ {
+ AslCommonError (Level, MessageId, 0,
+ 0, 0, 0, 0, ExtraMessage);
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtNameError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * Op - Parse node where error happened
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Error interface for named objects
+ *
+ *****************************************************************************/
+
+void
+DtNameError (
+ UINT8 Level,
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage)
+{
+
+ switch (Level)
+ {
+ case ASL_WARNING2:
+ case ASL_WARNING3:
+
+ if (Gbl_WarningLevel < Level)
+ {
+ return;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ if (FieldObject)
+ {
+ AslCommonError (Level, MessageId,
+ FieldObject->Line,
+ FieldObject->Line,
+ FieldObject->ByteOffset,
+ FieldObject->NameColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
+ }
+ else
+ {
+ AslCommonError (Level, MessageId, 0,
+ 0, 0, 0, 0, ExtraMessage);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtFatal
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
+ * compile or I/O errors
+ *
+ ******************************************************************************/
+
+void
+DtFatal (
+ UINT16 MessageId,
+ DT_FIELD *FieldObject,
+ char *ExtraMessage)
+{
+
+ DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
+
+/*
+ * TBD: remove this entire function, DtFatal
+ *
+ * We cannot abort the compiler on error, because we may be compiling a
+ * list of files. We must move on to the next file.
+ */
+#ifdef __OBSOLETE
+ CmCleanupAndExit ();
+ exit (1);
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtStrtoul64
+ *
+ * PARAMETERS: String - Null terminated string
+ * ReturnInteger - Where the converted integer is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
+ * value. Assumes no leading "0x" for the constant.
+ *
+ * Portability note: The reason this function exists is because a 64-bit
+ * sscanf is not available in all environments.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtStrtoul64 (
+ char *String,
+ UINT64 *ReturnInteger)
+{
+ char *ThisChar = String;
+ UINT32 ThisDigit;
+ UINT64 ReturnValue = 0;
+ int DigitCount = 0;
+
+
+ /* Skip over any white space in the buffer */
+
+ while ((*ThisChar == ' ') || (*ThisChar == '\t'))
+ {
+ ThisChar++;
+ }
+
+ /* Skip leading zeros */
+
+ while ((*ThisChar) == '0')
+ {
+ ThisChar++;
+ }
+
+ /* Convert character-by-character */
+
+ while (*ThisChar)
+ {
+ if (isdigit ((int) *ThisChar))
+ {
+ /* Convert ASCII 0-9 to Decimal value */
+
+ ThisDigit = ((UINT8) *ThisChar) - '0';
+ }
+ else /* Letter */
+ {
+ ThisDigit = (UINT32) toupper ((int) *ThisChar);
+ if (!isxdigit ((int) ThisDigit))
+ {
+ /* Not A-F */
+
+ return (AE_BAD_CHARACTER);
+ }
+
+ /* Convert ASCII Hex char (A-F) to value */
+
+ ThisDigit = (ThisDigit - 'A') + 10;
+ }
+
+ /* Insert the 4-bit hex digit */
+
+ ReturnValue <<= 4;
+ ReturnValue += ThisDigit;
+
+ ThisChar++;
+ DigitCount++;
+ if (DigitCount > 16)
+ {
+ /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
+
+ return (AE_LIMIT);
+ }
+ }
+
+ *ReturnInteger = ReturnValue;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetFieldValue
+ *
+ * PARAMETERS: Field - Current field list pointer
+ *
+ * RETURN: Field value
+ *
+ * DESCRIPTION: Get field value
+ *
+ *****************************************************************************/
+
+char *
+DtGetFieldValue (
+ DT_FIELD *Field)
+{
+ if (!Field)
+ {
+ return (NULL);
+ }
+
+ return (Field->Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetFieldType
+ *
+ * PARAMETERS: Info - Data table info
+ *
+ * RETURN: Field type
+ *
+ * DESCRIPTION: Get field type
+ *
+ *****************************************************************************/
+
+UINT8
+DtGetFieldType (
+ ACPI_DMTABLE_INFO *Info)
+{
+ UINT8 Type;
+
+
+ /* DT_FLAG means that this is the start of a block of flag bits */
+ /* TBD - we can make these a separate opcode later */
+
+ if (Info->Flags & DT_FLAG)
+ {
+ return (DT_FIELD_TYPE_FLAGS_INTEGER);
+ }
+
+ /* Type is based upon the opcode for this field in the info table */
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_FLAG0:
+ case ACPI_DMT_FLAG1:
+ case ACPI_DMT_FLAG2:
+ case ACPI_DMT_FLAG3:
+ case ACPI_DMT_FLAG4:
+ case ACPI_DMT_FLAG5:
+ case ACPI_DMT_FLAG6:
+ case ACPI_DMT_FLAG7:
+ case ACPI_DMT_FLAGS0:
+ case ACPI_DMT_FLAGS1:
+ case ACPI_DMT_FLAGS2:
+ case ACPI_DMT_FLAGS4:
+
+ Type = DT_FIELD_TYPE_FLAG;
+ break;
+
+ case ACPI_DMT_NAME4:
+ case ACPI_DMT_SIG:
+ case ACPI_DMT_NAME6:
+ case ACPI_DMT_NAME8:
+ case ACPI_DMT_STRING:
+
+ Type = DT_FIELD_TYPE_STRING;
+ break;
+
+ case ACPI_DMT_BUFFER:
+ case ACPI_DMT_RAW_BUFFER:
+ case ACPI_DMT_BUF7:
+ case ACPI_DMT_BUF10:
+ case ACPI_DMT_BUF16:
+ case ACPI_DMT_BUF128:
+ case ACPI_DMT_PCI_PATH:
+
+ Type = DT_FIELD_TYPE_BUFFER;
+ break;
+
+ case ACPI_DMT_GAS:
+ case ACPI_DMT_HESTNTFY:
+ case ACPI_DMT_IORTMEM:
+
+ Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
+ break;
+
+ case ACPI_DMT_UNICODE:
+
+ Type = DT_FIELD_TYPE_UNICODE;
+ break;
+
+ case ACPI_DMT_UUID:
+
+ Type = DT_FIELD_TYPE_UUID;
+ break;
+
+ case ACPI_DMT_DEVICE_PATH:
+
+ Type = DT_FIELD_TYPE_DEVICE_PATH;
+ break;
+
+ case ACPI_DMT_LABEL:
+
+ Type = DT_FIELD_TYPE_LABEL;
+ break;
+
+ default:
+
+ Type = DT_FIELD_TYPE_INTEGER;
+ break;
+ }
+
+ return (Type);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetBufferLength
+ *
+ * PARAMETERS: Buffer - List of integers,
+ * for example "10 3A 4F 2E"
+ *
+ * RETURN: Count of integer
+ *
+ * DESCRIPTION: Get length of bytes needed to store the integers
+ *
+ *****************************************************************************/
+
+UINT32
+DtGetBufferLength (
+ char *Buffer)
+{
+ UINT32 ByteLength = 0;
+
+
+ while (*Buffer)
+ {
+ if (*Buffer == ' ')
+ {
+ ByteLength++;
+
+ while (*Buffer == ' ')
+ {
+ Buffer++;
+ }
+ }
+
+ Buffer++;
+ }
+
+ return (++ByteLength);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtGetFieldLength
+ *
+ * PARAMETERS: Field - Current field
+ * Info - Data table info
+ *
+ * RETURN: Field length
+ *
+ * DESCRIPTION: Get length of bytes needed to compile the field
+ *
+ * Note: This function must remain in sync with AcpiDmDumpTable.
+ *
+ *****************************************************************************/
+
+UINT32
+DtGetFieldLength (
+ DT_FIELD *Field,
+ ACPI_DMTABLE_INFO *Info)
+{
+ UINT32 ByteLength = 0;
+ char *Value;
+
+
+ /* Length is based upon the opcode for this field in the info table */
+
+ switch (Info->Opcode)
+ {
+ case ACPI_DMT_FLAG0:
+ case ACPI_DMT_FLAG1:
+ case ACPI_DMT_FLAG2:
+ case ACPI_DMT_FLAG3:
+ case ACPI_DMT_FLAG4:
+ case ACPI_DMT_FLAG5:
+ case ACPI_DMT_FLAG6:
+ case ACPI_DMT_FLAG7:
+ case ACPI_DMT_FLAGS0:
+ case ACPI_DMT_FLAGS1:
+ case ACPI_DMT_FLAGS2:
+ case ACPI_DMT_FLAGS4:
+ case ACPI_DMT_LABEL:
+ case ACPI_DMT_EXTRA_TEXT:
+
+ ByteLength = 0;
+ break;
+
+ case ACPI_DMT_UINT8:
+ case ACPI_DMT_CHKSUM:
+ case ACPI_DMT_SPACEID:
+ case ACPI_DMT_ACCWIDTH:
+ case ACPI_DMT_IVRS:
+ case ACPI_DMT_GTDT:
+ case ACPI_DMT_MADT:
+ case ACPI_DMT_PCCT:
+ case ACPI_DMT_PMTT:
+ case ACPI_DMT_SRAT:
+ case ACPI_DMT_ASF:
+ case ACPI_DMT_HESTNTYP:
+ case ACPI_DMT_FADTPM:
+ case ACPI_DMT_EINJACT:
+ case ACPI_DMT_EINJINST:
+ case ACPI_DMT_ERSTACT:
+ case ACPI_DMT_ERSTINST:
+ case ACPI_DMT_DMAR_SCOPE:
+
+ ByteLength = 1;
+ break;
+
+ case ACPI_DMT_UINT16:
+ case ACPI_DMT_DMAR:
+ case ACPI_DMT_HEST:
+ case ACPI_DMT_NFIT:
+ case ACPI_DMT_PCI_PATH:
+
+ ByteLength = 2;
+ break;
+
+ case ACPI_DMT_UINT24:
+
+ ByteLength = 3;
+ break;
+
+ case ACPI_DMT_UINT32:
+ case ACPI_DMT_NAME4:
+ case ACPI_DMT_SIG:
+ case ACPI_DMT_LPIT:
+
+ ByteLength = 4;
+ break;
+
+ case ACPI_DMT_UINT40:
+
+ ByteLength = 5;
+ break;
+
+ case ACPI_DMT_UINT48:
+ case ACPI_DMT_NAME6:
+
+ ByteLength = 6;
+ break;
+
+ case ACPI_DMT_UINT56:
+ case ACPI_DMT_BUF7:
+
+ ByteLength = 7;
+ break;
+
+ case ACPI_DMT_UINT64:
+ case ACPI_DMT_NAME8:
+
+ ByteLength = 8;
+ break;
+
+ case ACPI_DMT_STRING:
+
+ Value = DtGetFieldValue (Field);
+ if (Value)
+ {
+ ByteLength = strlen (Value) + 1;
+ }
+ else
+ { /* At this point, this is a fatal error */
+
+ sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
+ return (0);
+ }
+ break;
+
+ case ACPI_DMT_GAS:
+
+ ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
+ break;
+
+ case ACPI_DMT_HESTNTFY:
+
+ ByteLength = sizeof (ACPI_HEST_NOTIFY);
+ break;
+
+ case ACPI_DMT_IORTMEM:
+
+ ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
+ break;
+
+ case ACPI_DMT_BUFFER:
+ case ACPI_DMT_RAW_BUFFER:
+
+ Value = DtGetFieldValue (Field);
+ if (Value)
+ {
+ ByteLength = DtGetBufferLength (Value);
+ }
+ else
+ { /* At this point, this is a fatal error */
+
+ sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
+ return (0);
+ }
+ break;
+
+ case ACPI_DMT_BUF10:
+
+ ByteLength = 10;
+ break;
+
+ case ACPI_DMT_BUF16:
+ case ACPI_DMT_UUID:
+
+ ByteLength = 16;
+ break;
+
+ case ACPI_DMT_BUF128:
+
+ ByteLength = 128;
+ break;
+
+ case ACPI_DMT_UNICODE:
+
+ Value = DtGetFieldValue (Field);
+
+ /* TBD: error if Value is NULL? (as below?) */
+
+ ByteLength = (strlen (Value) + 1) * sizeof(UINT16);
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
+ return (0);
+ }
+
+ return (ByteLength);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtSum
+ *
+ * PARAMETERS: DT_WALK_CALLBACK:
+ * Subtable - Subtable
+ * Context - Unused
+ * ReturnValue - Store the checksum of subtable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the checksum of subtable
+ *
+ *****************************************************************************/
+
+static void
+DtSum (
+ DT_SUBTABLE *Subtable,
+ void *Context,
+ void *ReturnValue)
+{
+ UINT8 Checksum;
+ UINT8 *Sum = ReturnValue;
+
+
+ Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
+ *Sum = (UINT8) (*Sum + Checksum);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtSetTableChecksum
+ *
+ * PARAMETERS: ChecksumPointer - Where to return the checksum
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set checksum of the whole data table into the checksum field
+ *
+ *****************************************************************************/
+
+void
+DtSetTableChecksum (
+ UINT8 *ChecksumPointer)
+{
+ UINT8 Checksum = 0;
+ UINT8 OldSum;
+
+
+ DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
+
+ OldSum = *ChecksumPointer;
+ Checksum = (UINT8) (Checksum - OldSum);
+
+ /* Compute the final checksum */
+
+ Checksum = (UINT8) (0 - Checksum);
+ *ChecksumPointer = Checksum;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtSetTableLength
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Walk the subtables and set all the length fields
+ *
+ *****************************************************************************/
+
+void
+DtSetTableLength (
+ void)
+{
+ DT_SUBTABLE *ParentTable;
+ DT_SUBTABLE *ChildTable;
+
+
+ ParentTable = Gbl_RootTable;
+ ChildTable = NULL;
+
+ if (!ParentTable)
+ {
+ return;
+ }
+
+ DtSetSubtableLength (ParentTable);
+
+ while (1)
+ {
+ ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
+ if (ChildTable)
+ {
+ if (ChildTable->LengthField)
+ {
+ DtSetSubtableLength (ChildTable);
+ }
+
+ if (ChildTable->Child)
+ {
+ ParentTable = ChildTable;
+ ChildTable = NULL;
+ }
+ else
+ {
+ ParentTable->TotalLength += ChildTable->TotalLength;
+ if (ParentTable->LengthField)
+ {
+ DtSetSubtableLength (ParentTable);
+ }
+ }
+ }
+ else
+ {
+ ChildTable = ParentTable;
+
+ if (ChildTable == Gbl_RootTable)
+ {
+ break;
+ }
+
+ ParentTable = DtGetParentSubtable (ParentTable);
+
+ ParentTable->TotalLength += ChildTable->TotalLength;
+ if (ParentTable->LengthField)
+ {
+ DtSetSubtableLength (ParentTable);
+ }
+ }
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtWalkTableTree
+ *
+ * PARAMETERS: StartTable - Subtable in the tree where walking begins
+ * UserFunction - Called during the walk
+ * Context - Passed to user function
+ * ReturnValue - The return value of UserFunction
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Performs a depth-first walk of the subtable tree
+ *
+ *****************************************************************************/
+
+void
+DtWalkTableTree (
+ DT_SUBTABLE *StartTable,
+ DT_WALK_CALLBACK UserFunction,
+ void *Context,
+ void *ReturnValue)
+{
+ DT_SUBTABLE *ParentTable;
+ DT_SUBTABLE *ChildTable;
+
+
+ ParentTable = StartTable;
+ ChildTable = NULL;
+
+ if (!ParentTable)
+ {
+ return;
+ }
+
+ UserFunction (ParentTable, Context, ReturnValue);
+
+ while (1)
+ {
+ ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
+ if (ChildTable)
+ {
+ UserFunction (ChildTable, Context, ReturnValue);
+
+ if (ChildTable->Child)
+ {
+ ParentTable = ChildTable;
+ ChildTable = NULL;
+ }
+ }
+ else
+ {
+ ChildTable = ParentTable;
+ if (ChildTable == Gbl_RootTable)
+ {
+ break;
+ }
+
+ ParentTable = DtGetParentSubtable (ParentTable);
+
+ if (ChildTable->Peer == StartTable)
+ {
+ break;
+ }
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtSubtableCacheCalloc
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a subtable object buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+DT_SUBTABLE *
+UtSubtableCacheCalloc (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_SubtableCacheList;
+ Gbl_SubtableCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer);
+ Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE;
+ }
+
+ Gbl_SubtableCount++;
+ return (Gbl_SubtableCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtFieldCacheCalloc
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a field object buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+DT_FIELD *
+UtFieldCacheCalloc (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_FieldCacheList;
+ Gbl_FieldCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer);
+ Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE;
+ }
+
+ Gbl_FieldCount++;
+ return (Gbl_FieldCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: DtDeleteCaches
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all local cache buffer blocks
+ *
+ ******************************************************************************/
+
+void
+DtDeleteCaches (
+ void)
+{
+ UINT32 BufferCount;
+ ASL_CACHE_INFO *Next;
+
+
+ /* Field cache */
+
+ BufferCount = 0;
+ while (Gbl_FieldCacheList)
+ {
+ Next = Gbl_FieldCacheList->Next;
+ ACPI_FREE (Gbl_FieldCacheList);
+ Gbl_FieldCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n",
+ Gbl_FieldCount, ASL_FIELD_CACHE_SIZE,
+ (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount);
+
+ Gbl_FieldCount = 0;
+ Gbl_FieldCacheNext = NULL;
+ Gbl_FieldCacheLast = NULL;
+
+ /* Subtable cache */
+
+ BufferCount = 0;
+ while (Gbl_SubtableCacheList)
+ {
+ Next = Gbl_SubtableCacheList->Next;
+ ACPI_FREE (Gbl_SubtableCacheList);
+ Gbl_SubtableCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n",
+ Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE,
+ (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount);
+
+ Gbl_SubtableCount = 0;
+ Gbl_SubtableCacheNext = NULL;
+ Gbl_SubtableCacheLast = NULL;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/preprocess.h b/usr/src/boot/sys/contrib/dev/acpica/compiler/preprocess.h
new file mode 100644
index 0000000000..9dc2bdbb0e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/preprocess.h
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * Module Name: preprocess.h - header for iASL Preprocessor
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 __PREPROCESS_H__
+
+#ifndef _PREPROCESS
+#define _PREPROCESS
+
+#undef PR_EXTERN
+
+#ifdef _DECLARE_PR_GLOBALS
+#define PR_EXTERN
+#define PR_INIT_GLOBAL(a,b) (a)=(b)
+#else
+#define PR_EXTERN extern
+#define PR_INIT_GLOBAL(a,b) (a)
+#endif
+
+
+/*
+ * Configuration
+ */
+#define PR_MAX_MACRO_ARGS 32 /* Max number of macro args */
+#define PR_MAX_ARG_INSTANCES 24 /* Max instances of any one arg */
+#define PR_LINES_PER_BLOCK 4096 /* Max input source lines per block */
+
+
+/*
+ * Local defines and macros
+ */
+#define PR_TOKEN_SEPARATORS " ,(){}\t\n"
+#define PR_MACRO_SEPARATORS " ,(){}~!*/%+-<>=&^|\"\t\n"
+#define PR_MACRO_ARGUMENTS " ,\t\n"
+#define PR_EXPR_SEPARATORS " ,(){}~!*/%+-<>=&^|\"\t\n"
+
+#define PR_PREFIX_ID "Pr(%.4u) - " /* Used for debug output */
+
+#define THIS_TOKEN_OFFSET(t) ((t-Gbl_MainTokenBuffer) + 1)
+
+
+/*
+ * Preprocessor structures
+ */
+typedef struct pr_macro_arg
+{
+ char *Name;
+ UINT32 Offset[PR_MAX_ARG_INSTANCES];
+ UINT16 UseCount;
+
+} PR_MACRO_ARG;
+
+typedef struct pr_define_info
+{
+ struct pr_define_info *Previous;
+ struct pr_define_info *Next;
+ char *Identifier;
+ char *Replacement;
+ char *Body; /* Macro body */
+ PR_MACRO_ARG *Args; /* Macro arg list */
+ UINT16 ArgCount; /* Macro arg count */
+ BOOLEAN Persist; /* Keep for entire compiler run */
+
+} PR_DEFINE_INFO;
+
+typedef struct pr_directive_info
+{
+ char *Name; /* Directive name */
+ UINT8 ArgCount; /* Required # of args */
+
+} PR_DIRECTIVE_INFO;
+
+typedef struct pr_operator_info
+{
+ char *Op;
+
+} PR_OPERATOR_INFO;
+
+typedef struct pr_file_node
+{
+ struct pr_file_node *Next;
+ FILE *File;
+ char *Filename;
+ UINT32 CurrentLineNumber;
+
+} PR_FILE_NODE;
+
+#define MAX_ARGUMENT_LENGTH 24
+
+typedef struct directive_info
+{
+ struct directive_info *Next;
+ char Argument[MAX_ARGUMENT_LENGTH];
+ int Directive;
+ BOOLEAN IgnoringThisCodeBlock;
+
+} DIRECTIVE_INFO;
+
+
+/*
+ * Globals
+ */
+#if 0 /* TBD for macros */
+PR_EXTERN char PR_INIT_GLOBAL (*XXXEvalBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */
+#endif
+
+PR_EXTERN char PR_INIT_GLOBAL (*Gbl_MainTokenBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */
+PR_EXTERN char PR_INIT_GLOBAL (*Gbl_MacroTokenBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */
+PR_EXTERN char PR_INIT_GLOBAL (*Gbl_ExpressionTokenBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */
+
+PR_EXTERN UINT32 Gbl_PreprocessorLineNumber;
+PR_EXTERN int Gbl_IfDepth;
+PR_EXTERN PR_FILE_NODE *Gbl_InputFileList;
+PR_EXTERN PR_DEFINE_INFO PR_INIT_GLOBAL (*Gbl_DefineList, NULL);
+PR_EXTERN BOOLEAN PR_INIT_GLOBAL (Gbl_PreprocessorError, FALSE);
+PR_EXTERN BOOLEAN PR_INIT_GLOBAL (Gbl_IgnoringThisCodeBlock, FALSE);
+PR_EXTERN DIRECTIVE_INFO PR_INIT_GLOBAL (*Gbl_DirectiveStack, NULL);
+
+/*
+ * prscan - Preprocessor entry
+ */
+void
+PrInitializePreprocessor (
+ void);
+
+void
+PrInitializeGlobals (
+ void);
+
+void
+PrTerminatePreprocessor (
+ void);
+
+void
+PrDoPreprocess (
+ void);
+
+UINT64
+PrIsDefined (
+ char *Identifier);
+
+UINT64
+PrResolveDefine (
+ char *Identifier);
+
+int
+PrInitLexer (
+ char *String);
+
+void
+PrTerminateLexer (
+ void);
+
+
+/*
+ * prmacros - Support for #defines and macros
+ */
+void
+PrDumpPredefinedNames (
+ void);
+
+PR_DEFINE_INFO *
+PrAddDefine (
+ char *Token,
+ char *Token2,
+ BOOLEAN Persist);
+
+void
+PrRemoveDefine (
+ char *DefineName);
+
+PR_DEFINE_INFO *
+PrMatchDefine (
+ char *MatchString);
+
+void
+PrAddMacro (
+ char *Name,
+ char **Next);
+
+void
+PrDoMacroInvocation (
+ char *TokenBuffer,
+ char *MacroStart,
+ PR_DEFINE_INFO *DefineInfo,
+ char **Next);
+
+
+/*
+ * prexpress - #if expression support
+ */
+ACPI_STATUS
+PrResolveIntegerExpression (
+ char *Line,
+ UINT64 *ReturnValue);
+
+char *
+PrPrioritizeExpression (
+ char *OriginalLine);
+
+/*
+ * prparser - lex/yacc expression parser
+ */
+UINT64
+PrEvaluateExpression (
+ char *ExprString);
+
+
+/*
+ * prutils - Preprocesor utilities
+ */
+char *
+PrGetNextToken (
+ char *Buffer,
+ char *MatchString,
+ char **Next);
+
+void
+PrError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 Column);
+
+void
+PrReplaceData (
+ char *Buffer,
+ UINT32 LengthToRemove,
+ char *BufferToAdd,
+ UINT32 LengthToAdd);
+
+FILE *
+PrOpenIncludeFile (
+ char *Filename,
+ char *OpenMode,
+ char **FullPathname);
+
+FILE *
+PrOpenIncludeWithPrefix (
+ char *PrefixDir,
+ char *Filename,
+ char *OpenMode,
+ char **FullPathname);
+
+void
+PrPushInputFileStack (
+ FILE *InputFile,
+ char *Filename);
+
+BOOLEAN
+PrPopInputFileStack (
+ void);
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prexpress.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/prexpress.c
new file mode 100644
index 0000000000..0f0d93881b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prexpress.c
@@ -0,0 +1,305 @@
+/******************************************************************************
+ *
+ * Module Name: prexpress - Preprocessor #if expression support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+
+#define _COMPONENT ASL_PREPROCESSOR
+ ACPI_MODULE_NAME ("prexpress")
+
+/* Local prototypes */
+
+static char *
+PrExpandMacros (
+ char *Line);
+
+
+#ifdef _UNDER_DEVELOPMENT
+/******************************************************************************
+ *
+ * FUNCTION: PrUnTokenize
+ *
+ * PARAMETERS: Buffer - Token Buffer
+ * Next - "Next" buffer from GetNextToken
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Un-tokenized the current token buffer. The implementation is
+ * to simply set the null inserted by GetNextToken to a blank.
+ * If Next is NULL, there were no tokens found in the Buffer,
+ * so there is nothing to do.
+ *
+ *****************************************************************************/
+
+static void
+PrUnTokenize (
+ char *Buffer,
+ char *Next)
+{
+ UINT32 Length = strlen (Buffer);
+
+
+ if (!Next)
+ {
+ return;
+ }
+ if (Buffer[Length] != '\n')
+ {
+ Buffer[strlen(Buffer)] = ' ';
+ }
+}
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrExpandMacros
+ *
+ * PARAMETERS: Line - Pointer into the current line
+ *
+ * RETURN: Updated pointer into the current line
+ *
+ * DESCRIPTION: Expand any macros found in the current line buffer.
+ *
+ *****************************************************************************/
+
+static char *
+PrExpandMacros (
+ char *Line)
+{
+ char *Token;
+ char *ReplaceString;
+ PR_DEFINE_INFO *DefineInfo;
+ ACPI_SIZE TokenOffset;
+ char *Next;
+ int OffsetAdjust;
+
+
+ strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer);
+ Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next);
+ OffsetAdjust = 0;
+
+ while (Token)
+ {
+ DefineInfo = PrMatchDefine (Token);
+ if (DefineInfo)
+ {
+ if (DefineInfo->Body)
+ {
+ /* This is a macro. TBD: Is this allowed? */
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Matched Macro: %s->%s\n",
+ Gbl_CurrentLineNumber, DefineInfo->Identifier,
+ DefineInfo->Replacement);
+
+ PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token,
+ DefineInfo, &Next);
+ }
+ else
+ {
+ ReplaceString = DefineInfo->Replacement;
+
+ /* Replace the name in the original line buffer */
+
+ TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust;
+ PrReplaceData (
+ &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
+ ReplaceString, strlen (ReplaceString));
+
+ /* Adjust for length difference between old and new name length */
+
+ OffsetAdjust += strlen (ReplaceString) - strlen (Token);
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Matched #define within expression: %s->%s\n",
+ Gbl_CurrentLineNumber, Token,
+ *ReplaceString ? ReplaceString : "(NULL STRING)");
+ }
+ }
+
+ Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next);
+ }
+
+ return (Line);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrIsDefined
+ *
+ * PARAMETERS: Identifier - Name to be resolved
+ *
+ * RETURN: 64-bit boolean integer value
+ *
+ * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
+ *
+ *****************************************************************************/
+
+UINT64
+PrIsDefined (
+ char *Identifier)
+{
+ UINT64 Value;
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "**** Is defined?: %s\n", Gbl_CurrentLineNumber, Identifier);
+
+ Value = 0; /* Default is "Not defined" -- FALSE */
+
+ DefineInfo = PrMatchDefine (Identifier);
+ if (DefineInfo)
+ {
+ Value = ACPI_UINT64_MAX; /* TRUE */
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "[#if defined %s] resolved to: %8.8X%8.8X\n",
+ Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
+
+ return (Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrResolveDefine
+ *
+ * PARAMETERS: Identifier - Name to be resolved
+ *
+ * RETURN: A 64-bit boolean integer value
+ *
+ * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
+ *
+ *****************************************************************************/
+
+UINT64
+PrResolveDefine (
+ char *Identifier)
+{
+ UINT64 Value;
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "**** Resolve #define: %s\n", Gbl_CurrentLineNumber, Identifier);
+
+ Value = 0; /* Default is "Not defined" -- FALSE */
+
+ DefineInfo = PrMatchDefine (Identifier);
+ if (DefineInfo)
+ {
+ Value = ACPI_UINT64_MAX; /* TRUE */
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "[#if defined %s] resolved to: %8.8X%8.8X\n",
+ Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
+
+ return (Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrResolveIntegerExpression
+ *
+ * PARAMETERS: Line - Pointer to integer expression
+ * ReturnValue - Where the resolved 64-bit integer is
+ * returned.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Resolve an integer expression to a single value. Supports
+ * both integer constants and labels.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+PrResolveIntegerExpression (
+ char *Line,
+ UINT64 *ReturnValue)
+{
+ UINT64 Result;
+ char *ExpandedLine;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "**** Resolve #if: %s\n", Gbl_CurrentLineNumber, Line);
+
+ /* Expand all macros within the expression first */
+
+ ExpandedLine = PrExpandMacros (Line);
+
+ /* Now we can evaluate the expression */
+
+ Result = PrEvaluateExpression (ExpandedLine);
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "**** Expression Resolved to: %8.8X%8.8X\n",
+ Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result));
+
+ *ReturnValue = Result;
+ return (AE_OK);
+
+#if 0
+InvalidExpression:
+
+ ACPI_FREE (EvalBuffer);
+ PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0);
+ return (AE_ERROR);
+
+
+NormalExit:
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "**** Expression Resolved to: %8.8X%8.8X\n",
+ Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1));
+
+ *ReturnValue = Value1;
+ return (AE_OK);
+#endif
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prmacros.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/prmacros.c
new file mode 100644
index 0000000000..866d08943a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prmacros.c
@@ -0,0 +1,581 @@
+/******************************************************************************
+ *
+ * Module Name: prmacros - Preprocessor #define macro support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+
+#define _COMPONENT ASL_PREPROCESSOR
+ ACPI_MODULE_NAME ("prmacros")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDumpPredefinedNames
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the list of #defines. Used as the preprocessor starts, to
+ * display the names that were defined on the command line.
+ * Debug information only.
+ *
+ ******************************************************************************/
+
+void
+PrDumpPredefinedNames (
+ void)
+{
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ DefineInfo = Gbl_DefineList;
+ while (DefineInfo)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Predefined #define: %s->%s\n",
+ 0, DefineInfo->Identifier, DefineInfo->Replacement);
+
+ DefineInfo = DefineInfo->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrAddDefine
+ *
+ * PARAMETERS: Identifier - Name to be replaced
+ * Replacement - Replacement for Identifier
+ * Persist - Keep define across multiple compiles?
+ *
+ * RETURN: A new define_info struct. NULL on error.
+ *
+ * DESCRIPTION: Add a new #define to the global list
+ *
+ ******************************************************************************/
+
+PR_DEFINE_INFO *
+PrAddDefine (
+ char *Identifier,
+ char *Replacement,
+ BOOLEAN Persist)
+{
+ char *IdentifierString;
+ char *ReplacementString;
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ if (!Replacement)
+ {
+ Replacement = "";
+ }
+
+ /* Check for already-defined first */
+
+ DefineInfo = PrMatchDefine (Identifier);
+ if (DefineInfo)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID,
+ "#define: name already exists: %s\n",
+ Gbl_CurrentLineNumber, Identifier);
+
+ /*
+ * Name already exists. This is only an error if the target name
+ * is different.
+ */
+ if (strcmp (Replacement, DefineInfo->Replacement))
+ {
+ PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME,
+ THIS_TOKEN_OFFSET (Identifier));
+
+ return (NULL);
+ }
+
+ return (DefineInfo);
+ }
+
+ /* Copy input strings */
+
+ IdentifierString = UtLocalCalloc (strlen (Identifier) + 1);
+ strcpy (IdentifierString, Identifier);
+
+ ReplacementString = UtLocalCalloc (strlen (Replacement) + 1);
+ strcpy (ReplacementString, Replacement);
+
+ /* Init and link new define info struct */
+
+ DefineInfo = UtLocalCalloc (sizeof (PR_DEFINE_INFO));
+ DefineInfo->Replacement = ReplacementString;
+ DefineInfo->Identifier = IdentifierString;
+ DefineInfo->Persist = Persist;
+
+ if (Gbl_DefineList)
+ {
+ Gbl_DefineList->Previous = DefineInfo;
+ }
+
+ DefineInfo->Next = Gbl_DefineList;
+ Gbl_DefineList = DefineInfo;
+ return (DefineInfo);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrRemoveDefine
+ *
+ * PARAMETERS: DefineName - Name of define to be removed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implements #undef. Remove a #define if found in the global
+ * list. No error if the target of the #undef does not exist,
+ * as per the C #undef definition.
+ *
+ ******************************************************************************/
+
+void
+PrRemoveDefine (
+ char *DefineName)
+{
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ /* Match name and delete the node */
+
+ DefineInfo = Gbl_DefineList;
+ while (DefineInfo)
+ {
+ if (!strcmp (DefineName, DefineInfo->Identifier))
+ {
+ /* Remove from linked list */
+
+ if (DefineInfo->Previous)
+ {
+ (DefineInfo->Previous)->Next = DefineInfo->Next;
+ }
+ else
+ {
+ Gbl_DefineList = DefineInfo->Next;
+ }
+
+ if (DefineInfo->Next)
+ {
+ (DefineInfo->Next)->Previous = DefineInfo->Previous;
+ }
+
+ free (DefineInfo);
+ return;
+ }
+
+ DefineInfo = DefineInfo->Next;
+ }
+
+ /*
+ * Name was not found. By definition of #undef, this is not
+ * an error, however.
+ */
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "#undef: could not find %s\n",
+ Gbl_CurrentLineNumber, DefineName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrMatchDefine
+ *
+ * PARAMETERS: MatchString - Name associated with the #define
+ *
+ * RETURN: Matched string if found. NULL otherwise.
+ *
+ * DESCRIPTION: Find a name in global #define list
+ *
+ ******************************************************************************/
+
+PR_DEFINE_INFO *
+PrMatchDefine (
+ char *MatchString)
+{
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ DefineInfo = Gbl_DefineList;
+ while (DefineInfo)
+ {
+ if (!strcmp (MatchString, DefineInfo->Identifier))
+ {
+ return (DefineInfo);
+ }
+
+ DefineInfo = DefineInfo->Next;
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrAddMacro
+ *
+ * PARAMETERS: Name - Start of the macro definition
+ * Next - "Next" buffer from GetNextToken
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a new macro to the list of #defines. Handles argument
+ * processing.
+ *
+ ******************************************************************************/
+
+void
+PrAddMacro (
+ char *Name,
+ char **Next)
+{
+ char *Token = NULL;
+ ACPI_SIZE TokenOffset;
+ ACPI_SIZE MacroBodyOffset;
+ PR_DEFINE_INFO *DefineInfo;
+ PR_MACRO_ARG *Args;
+ char *Body;
+ char *BodyInSource;
+ UINT32 i;
+ UINT16 UseCount = 0;
+ UINT16 ArgCount = 0;
+ UINT32 Depth = 1;
+ UINT32 EndOfArgList;
+ char BufferChar;
+
+
+ /* Find the end of the arguments list */
+
+ TokenOffset = Name - Gbl_MainTokenBuffer + strlen (Name) + 1;
+ while (1)
+ {
+ BufferChar = Gbl_CurrentLineBuffer[TokenOffset];
+ if (BufferChar == '(')
+ {
+ Depth++;
+ }
+ else if (BufferChar == ')')
+ {
+ Depth--;
+ }
+ else if (BufferChar == 0)
+ {
+ PrError (ASL_ERROR, ASL_MSG_MACRO_SYNTAX, TokenOffset);
+ return;
+ }
+
+ if (Depth == 0)
+ {
+ /* Found arg list end */
+
+ EndOfArgList = TokenOffset;
+ break;
+ }
+
+ TokenOffset++;
+ }
+
+ /* At this point, we know that we have a reasonable argument list */
+
+ Args = UtLocalCalloc (sizeof (PR_MACRO_ARG) * PR_MAX_MACRO_ARGS);
+
+ /* Get the macro argument names */
+
+ for (i = 0; i < PR_MAX_MACRO_ARGS; i++)
+ {
+ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
+ if (!Token)
+ {
+ /* This is the case for a NULL macro body */
+
+ BodyInSource = "";
+ goto AddMacroToList;
+ }
+
+ /* Don't go beyond the argument list */
+
+ TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token);
+ if (TokenOffset > EndOfArgList)
+ {
+ break;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Macro arg: %s \n",
+ Gbl_CurrentLineNumber, Token);
+
+ Args[i].Name = UtLocalCalloc (strlen (Token) + 1);
+ strcpy (Args[i].Name, Token);
+
+ Args[i].UseCount = 0;
+
+ ArgCount++;
+ if (ArgCount >= PR_MAX_MACRO_ARGS)
+ {
+ PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, TokenOffset);
+ goto ErrorExit;
+ }
+ }
+
+ /* Get the macro body. Token now points to start of body */
+
+ MacroBodyOffset = Token - Gbl_MainTokenBuffer;
+
+ /* Match each method arg in the macro body for later use */
+
+ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
+ while (Token)
+ {
+ /* Search the macro arg list for matching arg */
+
+ for (i = 0; Args[i].Name && (i < PR_MAX_MACRO_ARGS); i++)
+ {
+ /*
+ * Save argument offset within macro body. This is the mechanism
+ * used to expand the macro upon invocation.
+ *
+ * Handles multiple instances of the same argument
+ */
+ if (!strcmp (Token, Args[i].Name))
+ {
+ UseCount = Args[i].UseCount;
+
+ Args[i].Offset[UseCount] = (Token - Gbl_MainTokenBuffer) - MacroBodyOffset;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Macro Arg #%u: %s UseCount %u Offset %u \n",
+ Gbl_CurrentLineNumber, i, Token,
+ UseCount+1, Args[i].Offset[UseCount]);
+
+ Args[i].UseCount++;
+ if (Args[i].UseCount >= PR_MAX_ARG_INSTANCES)
+ {
+ PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS,
+ THIS_TOKEN_OFFSET (Token));
+
+ goto ErrorExit;
+ }
+ break;
+ }
+ }
+
+ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
+ }
+
+ BodyInSource = &Gbl_CurrentLineBuffer[MacroBodyOffset];
+
+
+AddMacroToList:
+
+ /* Check if name is already defined first */
+
+ DefineInfo = PrMatchDefine (Name);
+ if (DefineInfo)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "#define: macro name already exists: %s\n",
+ Gbl_CurrentLineNumber, Name);
+
+ /* Error only if not exactly the same macro */
+
+ if (strcmp (DefineInfo->Body, BodyInSource) ||
+ (DefineInfo->ArgCount != ArgCount))
+ {
+ PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME,
+ THIS_TOKEN_OFFSET (Name));
+ }
+
+ goto ErrorExit;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Macro body: %s \n",
+ Gbl_CurrentLineNumber, BodyInSource);
+
+ /* Add macro to the #define list */
+
+ DefineInfo = PrAddDefine (Name, BodyInSource, FALSE);
+ if (DefineInfo)
+ {
+ Body = UtLocalCalloc (strlen (BodyInSource) + 1);
+ strcpy (Body, BodyInSource);
+
+ DefineInfo->Body = Body;
+ DefineInfo->Args = Args;
+ DefineInfo->ArgCount = ArgCount;
+ }
+
+ return;
+
+
+ErrorExit:
+ ACPI_FREE (Args);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDoMacroInvocation
+ *
+ * PARAMETERS: TokenBuffer - Current line buffer
+ * MacroStart - Start of the macro invocation within
+ * the token buffer
+ * DefineInfo - Info for this macro
+ * Next - "Next" buffer from GetNextToken
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Expand a macro invocation
+ *
+ ******************************************************************************/
+
+void
+PrDoMacroInvocation (
+ char *TokenBuffer,
+ char *MacroStart,
+ PR_DEFINE_INFO *DefineInfo,
+ char **Next)
+{
+ PR_MACRO_ARG *Args;
+ char *Token = NULL;
+ UINT32 TokenOffset;
+ UINT32 Length;
+ UINT32 i;
+
+
+ /* Take a copy of the macro body for expansion */
+
+ strcpy (Gbl_MacroTokenBuffer, DefineInfo->Body);
+
+ /* Replace each argument within the prototype body */
+
+ Args = DefineInfo->Args;
+ if (!Args->Name)
+ {
+ /* This macro has no arguments */
+
+ Token = PrGetNextToken (NULL, PR_MACRO_ARGUMENTS, Next);
+ if (!Token)
+ {
+ goto BadInvocation;
+ }
+
+ TokenOffset = (MacroStart - TokenBuffer);
+ Length = Token - MacroStart + strlen (Token) + 1;
+
+ PrReplaceData (
+ &Gbl_CurrentLineBuffer[TokenOffset], Length,
+ Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer));
+ return;
+ }
+
+ while (Args->Name)
+ {
+ /* Get the next argument from macro invocation */
+
+ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
+ if (!Token)
+ {
+ goto BadInvocation;
+ }
+
+ /* Replace all instances of this argument */
+
+ for (i = 0; i < Args->UseCount; i++)
+ {
+ /* Offset zero indicates "arg not used" */
+ /* TBD: Not really needed now, with UseCount available */
+
+ if (Args->Offset[i] == 0)
+ {
+ break;
+ }
+
+ PrReplaceData (
+ &Gbl_MacroTokenBuffer[Args->Offset[i]], strlen (Args->Name),
+ Token, strlen (Token));
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "ExpandArg: %s \n",
+ Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer);
+ }
+
+ Args++;
+ }
+
+ /* TBD: need to make sure macro was not invoked with too many arguments */
+
+ if (!Token)
+ {
+ return;
+ }
+
+ /* Replace the entire macro invocation with the expanded macro */
+
+ TokenOffset = (MacroStart - TokenBuffer);
+ Length = Token - MacroStart + strlen (Token) + 1;
+
+ PrReplaceData (
+ &Gbl_CurrentLineBuffer[TokenOffset], Length,
+ Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer));
+
+ return;
+
+
+BadInvocation:
+ PrError (ASL_ERROR, ASL_MSG_INVALID_INVOCATION,
+ THIS_TOKEN_OFFSET (MacroStart));
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Bad macro invocation: %s \n",
+ Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer);
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.l b/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.l
new file mode 100644
index 0000000000..ed77a05fb4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.l
@@ -0,0 +1,236 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: prparser.l - Flex input file for preprocessor lexer
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "prparser.y.h"
+
+/* Buffer to pass strings to the parser */
+
+#define STRING_SETUP strcpy (StringBuffer, PrParsertext);\
+ PrParserlval.str = StringBuffer
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("prscanner")
+
+
+/* Local prototypes */
+
+static char
+PrDoCommentType1 (
+ void);
+
+static char
+PrDoCommentType2 (
+ void);
+%}
+
+%option noyywrap
+
+Number [0-9a-fA-F]+
+HexNumber 0[xX][0-9a-fA-F]+
+WhiteSpace [ \t\v\r]+
+NewLine [\n]
+Identifier [a-zA-Z][0-9a-zA-Z]*
+
+%%
+"/*" { if (!PrDoCommentType1 ()) {yyterminate ();} }
+"//" { if (!PrDoCommentType2 ()) {yyterminate ();} }
+
+\( return (EXPOP_PAREN_OPEN);
+\) return (EXPOP_PAREN_CLOSE);
+\~ return (EXPOP_ONES_COMPLIMENT);
+\! return (EXPOP_LOGICAL_NOT);
+\* return (EXPOP_MULTIPLY);
+\/ return (EXPOP_DIVIDE);
+\% return (EXPOP_MODULO);
+\+ return (EXPOP_ADD);
+\- return (EXPOP_SUBTRACT);
+">>" return (EXPOP_SHIFT_RIGHT);
+"<<" return (EXPOP_SHIFT_LEFT);
+\< return (EXPOP_LESS);
+\> return (EXPOP_GREATER);
+"<=" return (EXPOP_LESS_EQUAL);
+">=" return (EXPOP_GREATER_EQUAL);
+"==" return (EXPOP_EQUAL);
+"!=" return (EXPOP_NOT_EQUAL);
+\& return (EXPOP_AND);
+\^ return (EXPOP_XOR);
+\| return (EXPOP_OR);
+"&&" return (EXPOP_LOGICAL_AND);
+"||" return (EXPOP_LOGICAL_OR);
+
+"defined" return (EXPOP_DEFINE);
+{Identifier} {STRING_SETUP; return (EXPOP_IDENTIFIER);}
+
+<<EOF>> return (EXPOP_EOF); /* null end-of-string */
+
+{Number} return (EXPOP_NUMBER);
+{HexNumber} return (EXPOP_HEX_NUMBER);
+{NewLine} return (EXPOP_NEW_LINE);
+{WhiteSpace} /* Ignore */
+
+. return (EXPOP_EOF);
+%%
+
+/*
+ * Local support functions
+ */
+YY_BUFFER_STATE LexBuffer;
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrInitLexer
+ *
+ * PARAMETERS: String - Input string to be parsed
+ *
+ * RETURN: TRUE if parser returns NULL. FALSE otherwise.
+ *
+ * DESCRIPTION: Initialization routine for lexer. The lexer needs
+ * a buffer to handle strings instead of a file.
+ *
+ *****************************************************************************/
+
+int
+PrInitLexer (
+ char *String)
+{
+
+ LexBuffer = yy_scan_string (String);
+ return (LexBuffer == NULL);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrTerminateLexer
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Termination routine for thelexer.
+ *
+ *****************************************************************************/
+
+void
+PrTerminateLexer (
+ void)
+{
+
+ yy_delete_buffer (LexBuffer);
+}
+
+
+/********************************************************************************
+ *
+ * FUNCTION: PrDoCommentType1
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a new legacy comment. Just toss it.
+ *
+ ******************************************************************************/
+
+static char
+PrDoCommentType1 (
+ void)
+{
+ int c;
+
+
+Loop:
+ while (((c = input ()) != '*') && (c != EOF))
+ {
+ }
+ if (c == EOF)
+ {
+ return (FALSE);
+ }
+
+ if (((c = input ()) != '/') && (c != EOF))
+ {
+ unput (c);
+ goto Loop;
+ }
+ if (c == EOF)
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/********************************************************************************
+ *
+ * FUNCTION: PrDoCommentType2
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a new "//" comment. Just toss it.
+ *
+ ******************************************************************************/
+
+static char
+PrDoCommentType2 (
+ void)
+{
+ int c;
+
+
+ while (((c = input ()) != '\n') && (c != EOF))
+ {
+ }
+ if (c == EOF)
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.y b/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.y
new file mode 100644
index 0000000000..ce9391615b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prparser.y
@@ -0,0 +1,294 @@
+%{
+/******************************************************************************
+ *
+ * Module Name: prparser.y - Bison input file for preprocessor parser
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+#define _COMPONENT ASL_PREPROCESSOR
+ ACPI_MODULE_NAME ("prparser")
+
+void * AslLocalAllocate (unsigned int Size);
+
+/* Bison/yacc configuration */
+
+#undef alloca
+#define alloca AslLocalAllocate
+
+int PrParserlex (void);
+int PrParserparse (void);
+void PrParsererror (char const *msg);
+extern char *PrParsertext;
+
+UINT64 PrParserResult; /* Expression return value */
+
+/* Bison/yacc configuration */
+
+#define yytname PrParsername
+#define YYDEBUG 1 /* Enable debug output */
+#define YYERROR_VERBOSE 1 /* Verbose error messages */
+#define YYFLAG -32768
+
+/* Define YYMALLOC/YYFREE to prevent redefinition errors */
+
+#define YYMALLOC malloc
+#define YYFREE free
+%}
+
+%union
+{
+ UINT64 value;
+ UINT32 op;
+ char *str;
+}
+
+/*! [Begin] no source code translation */
+
+%type <value> Expression
+
+%token <op> EXPOP_EOF
+%token <op> EXPOP_NEW_LINE
+%token <op> EXPOP_NUMBER
+%token <op> EXPOP_HEX_NUMBER
+%token <op> EXPOP_RESERVED1
+%token <op> EXPOP_RESERVED2
+%token <op> EXPOP_PAREN_OPEN
+%token <op> EXPOP_PAREN_CLOSE
+
+%left <op> EXPOP_LOGICAL_OR
+%left <op> EXPOP_LOGICAL_AND
+%left <op> EXPOP_OR
+%left <op> EXPOP_XOR
+%left <op> EXPOP_AND
+%left <op> EXPOP_EQUAL EXPOP_NOT_EQUAL
+%left <op> EXPOP_GREATER EXPOP_LESS EXPOP_GREATER_EQUAL EXPOP_LESS_EQUAL
+%left <op> EXPOP_SHIFT_RIGHT EXPOP_SHIFT_LEFT
+%left <op> EXPOP_ADD EXPOP_SUBTRACT
+%left <op> EXPOP_MULTIPLY EXPOP_DIVIDE EXPOP_MODULO
+%right <op> EXPOP_ONES_COMPLIMENT EXPOP_LOGICAL_NOT
+
+/* Tokens above must be kept in synch with dtparser.y */
+
+%token <op> EXPOP_DEFINE
+%token <op> EXPOP_IDENTIFIER
+
+%%
+
+/*
+ * Operator precedence rules (from K&R)
+ *
+ * 1) ( )
+ * 2) ! ~ (unary operators that are supported here)
+ * 3) * / %
+ * 4) + -
+ * 5) >> <<
+ * 6) < > <= >=
+ * 7) == !=
+ * 8) &
+ * 9) ^
+ * 10) |
+ * 11) &&
+ * 12) ||
+ */
+
+/*! [End] no source code translation !*/
+
+Value
+ : Expression EXPOP_NEW_LINE { PrParserResult=$1; return 0; } /* End of line (newline) */
+ | Expression EXPOP_EOF { PrParserResult=$1; return 0; } /* End of string (0) */
+ ;
+
+Expression
+
+ /* Unary operators */
+
+ : EXPOP_LOGICAL_NOT Expression { $$ = DtDoOperator ($2, EXPOP_LOGICAL_NOT, $2);}
+ | EXPOP_ONES_COMPLIMENT Expression { $$ = DtDoOperator ($2, EXPOP_ONES_COMPLIMENT, $2);}
+
+ /* Binary operators */
+
+ | Expression EXPOP_MULTIPLY Expression { $$ = DtDoOperator ($1, EXPOP_MULTIPLY, $3);}
+ | Expression EXPOP_DIVIDE Expression { $$ = DtDoOperator ($1, EXPOP_DIVIDE, $3);}
+ | Expression EXPOP_MODULO Expression { $$ = DtDoOperator ($1, EXPOP_MODULO, $3);}
+ | Expression EXPOP_ADD Expression { $$ = DtDoOperator ($1, EXPOP_ADD, $3);}
+ | Expression EXPOP_SUBTRACT Expression { $$ = DtDoOperator ($1, EXPOP_SUBTRACT, $3);}
+ | Expression EXPOP_SHIFT_RIGHT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_RIGHT, $3);}
+ | Expression EXPOP_SHIFT_LEFT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_LEFT, $3);}
+ | Expression EXPOP_GREATER Expression { $$ = DtDoOperator ($1, EXPOP_GREATER, $3);}
+ | Expression EXPOP_LESS Expression { $$ = DtDoOperator ($1, EXPOP_LESS, $3);}
+ | Expression EXPOP_GREATER_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_GREATER_EQUAL, $3);}
+ | Expression EXPOP_LESS_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_LESS_EQUAL, $3);}
+ | Expression EXPOP_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_EQUAL, $3);}
+ | Expression EXPOP_NOT_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_NOT_EQUAL, $3);}
+ | Expression EXPOP_AND Expression { $$ = DtDoOperator ($1, EXPOP_AND, $3);}
+ | Expression EXPOP_XOR Expression { $$ = DtDoOperator ($1, EXPOP_XOR, $3);}
+ | Expression EXPOP_OR Expression { $$ = DtDoOperator ($1, EXPOP_OR, $3);}
+ | Expression EXPOP_LOGICAL_AND Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_AND, $3);}
+ | Expression EXPOP_LOGICAL_OR Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_OR, $3);}
+
+ /* Parentheses: '(' Expression ')' */
+
+ | EXPOP_PAREN_OPEN Expression
+ EXPOP_PAREN_CLOSE { $$ = $2;}
+
+ /* #if defined (ID) or #if defined ID */
+
+ | EXPOP_DEFINE EXPOP_PAREN_OPEN EXPOP_IDENTIFIER
+ EXPOP_PAREN_CLOSE { $$ = PrIsDefined (PrParserlval.str);}
+
+ | EXPOP_DEFINE EXPOP_IDENTIFIER { $$ = PrIsDefined (PrParserlval.str);}
+
+ | EXPOP_IDENTIFIER { $$ = PrResolveDefine (PrParserlval.str);}
+
+ /* Default base for a non-prefixed integer is 10 */
+
+ | EXPOP_NUMBER { stroul64 (PrParsertext, 10, &$$);}
+
+ /* Standard hex number (0x1234) */
+
+ | EXPOP_HEX_NUMBER { stroul64 (PrParsertext, 16, &$$);}
+ ;
+%%
+
+/*
+ * Local support functions, including parser entry point
+ */
+#define PR_FIRST_PARSE_OPCODE EXPOP_EOF
+#define PR_YYTNAME_START 3
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrParsererror
+ *
+ * PARAMETERS: Message - Parser-generated error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Handler for parser errors
+ *
+ *****************************************************************************/
+
+void
+PrParsererror (
+ char const *Message)
+{
+
+ sprintf (StringBuffer, "Preprocessor Parser : %s (near line %u)",
+ Message, Gbl_CurrentLineNumber);
+ DtError (ASL_ERROR, ASL_MSG_SYNTAX,
+ NULL, (char *) StringBuffer);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrGetOpName
+ *
+ * PARAMETERS: ParseOpcode - Parser token (EXPOP_*)
+ *
+ * RETURN: Pointer to the opcode name
+ *
+ * DESCRIPTION: Get the ascii name of the parse opcode for debug output
+ *
+ *****************************************************************************/
+
+char *
+PrGetOpName (
+ UINT32 ParseOpcode)
+{
+#ifdef ASL_YYTNAME_START
+ /*
+ * First entries (PR_YYTNAME_START) in yytname are special reserved names.
+ * Ignore first 6 characters of name (EXPOP_)
+ */
+ return ((char *) yytname
+ [(ParseOpcode - PR_FIRST_PARSE_OPCODE) + PR_YYTNAME_START] + 6);
+#else
+ return ("[Unknown parser generator]");
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrEvaluateExpression
+ *
+ * PARAMETERS: ExprString - Expression to be evaluated. Must be
+ * terminated by either a newline or a NUL
+ * string terminator
+ *
+ * RETURN: 64-bit value for the expression
+ *
+ * DESCRIPTION: Main entry point for the DT expression parser
+ *
+ *****************************************************************************/
+
+UINT64
+PrEvaluateExpression (
+ char *ExprString)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "**** Input expression: %s\n", ExprString);
+
+ /* Point lexer to the input string */
+
+ if (PrInitLexer (ExprString))
+ {
+ DtError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
+ NULL, "Could not initialize lexer");
+ return (0);
+ }
+
+ /* Parse/Evaluate the input string (value returned in PrParserResult) */
+
+ PrParserparse ();
+ PrTerminateLexer ();
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "**** Parser returned value: %u (%8.8X%8.8X)\n",
+ (UINT32) PrParserResult, ACPI_FORMAT_UINT64 (PrParserResult));
+
+ return (PrParserResult);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prscan.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/prscan.c
new file mode 100644
index 0000000000..1fb7f6fbb4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prscan.c
@@ -0,0 +1,1251 @@
+/******************************************************************************
+ *
+ * Module Name: prscan - Preprocessor start-up and file scan module
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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_PR_GLOBALS
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+/*
+ * TBDs:
+ *
+ * No nested macros, maybe never
+ * Implement ASL "Include" as well as "#include" here?
+ */
+#define _COMPONENT ASL_PREPROCESSOR
+ ACPI_MODULE_NAME ("prscan")
+
+
+/* Local prototypes */
+
+static void
+PrPreprocessInputFile (
+ void);
+
+static void
+PrDoDirective (
+ char *DirectiveToken,
+ char **Next);
+
+static void
+PrGetNextLineInit (
+ void);
+
+static UINT32
+PrGetNextLine (
+ FILE *Handle);
+
+static int
+PrMatchDirective (
+ char *Directive);
+
+static void
+PrPushDirective (
+ int Directive,
+ char *Argument);
+
+static ACPI_STATUS
+PrPopDirective (
+ void);
+
+static void
+PrDbgPrint (
+ char *Action,
+ char *DirectiveName);
+
+static void
+PrDoIncludeBuffer (
+ char *Pathname,
+ char *BufferName);
+
+static void
+PrDoIncludeFile (
+ char *Pathname);
+
+
+/*
+ * Supported preprocessor directives
+ * Each entry is of the form "Name, ArgumentCount"
+ */
+static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] =
+{
+ {"define", 1},
+ {"elif", 0}, /* Converted to #else..#if internally */
+ {"else", 0},
+ {"endif", 0},
+ {"error", 1},
+ {"if", 1},
+ {"ifdef", 1},
+ {"ifndef", 1},
+ {"include", 0}, /* Argument is not standard format, so just use 0 here */
+ {"includebuffer", 0}, /* Argument is not standard format, so just use 0 here */
+ {"line", 1},
+ {"pragma", 1},
+ {"undef", 1},
+ {"warning", 1},
+ {NULL, 0}
+};
+
+/* This table must match ordering of above table exactly */
+
+enum Gbl_DirectiveIndexes
+{
+ PR_DIRECTIVE_DEFINE = 0,
+ PR_DIRECTIVE_ELIF,
+ PR_DIRECTIVE_ELSE,
+ PR_DIRECTIVE_ENDIF,
+ PR_DIRECTIVE_ERROR,
+ PR_DIRECTIVE_IF,
+ PR_DIRECTIVE_IFDEF,
+ PR_DIRECTIVE_IFNDEF,
+ PR_DIRECTIVE_INCLUDE,
+ PR_DIRECTIVE_INCLUDEBUFFER,
+ PR_DIRECTIVE_LINE,
+ PR_DIRECTIVE_PRAGMA,
+ PR_DIRECTIVE_UNDEF,
+ PR_DIRECTIVE_WARNING
+};
+
+#define ASL_DIRECTIVE_NOT_FOUND -1
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrInitializePreprocessor
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Startup initialization for the Preprocessor.
+ *
+ ******************************************************************************/
+
+void
+PrInitializePreprocessor (
+ void)
+{
+ /* Init globals and the list of #defines */
+
+ PrInitializeGlobals ();
+ Gbl_DefineList = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrInitializeGlobals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup
+ * initialization and re-initialization between compiles during
+ * a multiple source file compile.
+ *
+ ******************************************************************************/
+
+void
+PrInitializeGlobals (
+ void)
+{
+ /* Init globals */
+
+ Gbl_InputFileList = NULL;
+ Gbl_CurrentLineNumber = 1;
+ Gbl_PreprocessorLineNumber = 1;
+ Gbl_PreprocessorError = FALSE;
+
+ /* These are used to track #if/#else blocks (possibly nested) */
+
+ Gbl_IfDepth = 0;
+ Gbl_IgnoringThisCodeBlock = FALSE;
+ Gbl_DirectiveStack = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrTerminatePreprocessor
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any
+ * defines that were specified on the command line, in order to
+ * support multiple compiles with a single compiler invocation.
+ *
+ ******************************************************************************/
+
+void
+PrTerminatePreprocessor (
+ void)
+{
+ PR_DEFINE_INFO *DefineInfo;
+
+
+ /*
+ * The persistent defines (created on the command line) are always at the
+ * end of the list. We save them.
+ */
+ while ((Gbl_DefineList) && (!Gbl_DefineList->Persist))
+ {
+ DefineInfo = Gbl_DefineList;
+ Gbl_DefineList = DefineInfo->Next;
+
+ ACPI_FREE (DefineInfo->Replacement);
+ ACPI_FREE (DefineInfo->Identifier);
+ ACPI_FREE (DefineInfo);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDoPreprocess
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must
+ * be already open. Handles multiple input files via the
+ * #include directive.
+ *
+ ******************************************************************************/
+
+void
+PrDoPreprocess (
+ void)
+{
+ BOOLEAN MoreInputFiles;
+
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n");
+
+
+ FlSeekFile (ASL_FILE_INPUT, 0);
+ PrDumpPredefinedNames ();
+
+ /* Main preprocessor loop, handles include files */
+
+ do
+ {
+ PrPreprocessInputFile ();
+ MoreInputFiles = PrPopInputFileStack ();
+
+ } while (MoreInputFiles);
+
+ /* Point compiler input to the new preprocessor output file (.pre) */
+
+ FlCloseFile (ASL_FILE_INPUT);
+ Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle;
+ AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
+
+ /* Reset globals to allow compiler to run */
+
+ FlSeekFile (ASL_FILE_INPUT, 0);
+ if (!Gbl_PreprocessOnly)
+ {
+ Gbl_CurrentLineNumber = 0;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrPreprocessInputFile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Preprocess one entire file, line-by-line.
+ *
+ * Input: Raw user ASL from ASL_FILE_INPUT
+ * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and
+ * (optionally) ASL_FILE_PREPROCESSOR_USER
+ *
+ ******************************************************************************/
+
+static void
+PrPreprocessInputFile (
+ void)
+{
+ UINT32 Status;
+ char *Token;
+ char *ReplaceString;
+ PR_DEFINE_INFO *DefineInfo;
+ ACPI_SIZE TokenOffset;
+ char *Next;
+ int OffsetAdjust;
+
+
+ PrGetNextLineInit ();
+
+ /* Scan source line-by-line and process directives. Then write the .i file */
+
+ while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
+ {
+ Gbl_CurrentLineNumber++;
+ Gbl_LogicalLineNumber++;
+
+ if ((Status == ASL_WITHIN_COMMENT) ||
+ (Status == ASL_BLANK_LINE))
+ {
+ goto WriteEntireLine;
+ }
+
+ /* Need a copy of the input line for strok() */
+
+ strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer);
+ Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next);
+ OffsetAdjust = 0;
+
+ /* All preprocessor directives must begin with '#' */
+
+ if (Token && (*Token == '#'))
+ {
+ if (strlen (Token) == 1)
+ {
+ Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
+ }
+ else
+ {
+ Token++; /* Skip leading # */
+ }
+
+ /* Execute the directive, do not write line to output file */
+
+ PrDoDirective (Token, &Next);
+ continue;
+ }
+
+ /*
+ * If we are currently within the part of an IF/ELSE block that is
+ * FALSE, ignore the line and do not write it to the output file.
+ * This continues until an #else or #endif is encountered.
+ */
+ if (Gbl_IgnoringThisCodeBlock)
+ {
+ continue;
+ }
+
+ /* Match and replace all #defined names within this source line */
+
+ while (Token)
+ {
+ DefineInfo = PrMatchDefine (Token);
+ if (DefineInfo)
+ {
+ if (DefineInfo->Body)
+ {
+ /* This is a macro */
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Matched Macro: %s->%s\n",
+ Gbl_CurrentLineNumber, DefineInfo->Identifier,
+ DefineInfo->Replacement);
+
+ PrDoMacroInvocation (Gbl_MainTokenBuffer, Token,
+ DefineInfo, &Next);
+ }
+ else
+ {
+ ReplaceString = DefineInfo->Replacement;
+
+ /* Replace the name in the original line buffer */
+
+ TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust;
+ PrReplaceData (
+ &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
+ ReplaceString, strlen (ReplaceString));
+
+ /* Adjust for length difference between old and new name length */
+
+ OffsetAdjust += strlen (ReplaceString) - strlen (Token);
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "Matched #define: %s->%s\n",
+ Gbl_CurrentLineNumber, Token,
+ *ReplaceString ? ReplaceString : "(NULL STRING)");
+ }
+ }
+
+ Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
+ }
+
+ Gbl_PreprocessorLineNumber++;
+
+
+WriteEntireLine:
+ /*
+ * Now we can write the possibly modified source line to the
+ * preprocessor file(s).
+ */
+ FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
+ strlen (Gbl_CurrentLineBuffer));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDoDirective
+ *
+ * PARAMETERS: Directive - Pointer to directive name token
+ * Next - "Next" buffer from GetNextToken
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Main processing for all preprocessor directives
+ *
+ ******************************************************************************/
+
+static void
+PrDoDirective (
+ char *DirectiveToken,
+ char **Next)
+{
+ char *Token = Gbl_MainTokenBuffer;
+ char *Token2 = NULL;
+ char *End;
+ UINT64 Value;
+ ACPI_SIZE TokenOffset;
+ int Directive;
+ ACPI_STATUS Status;
+
+
+ if (!DirectiveToken)
+ {
+ goto SyntaxError;
+ }
+
+ Directive = PrMatchDirective (DirectiveToken);
+ if (Directive == ASL_DIRECTIVE_NOT_FOUND)
+ {
+ PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE,
+ THIS_TOKEN_OFFSET (DirectiveToken));
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "#%s: Unknown directive\n",
+ Gbl_CurrentLineNumber, DirectiveToken);
+ return;
+ }
+
+ /*
+ * Emit a line directive into the preprocessor file (.pre) after
+ * every matched directive. This is passed through to the compiler
+ * so that error/warning messages are kept in sync with the
+ * original source file.
+ */
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n",
+ Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename,
+ Gbl_DirectiveInfo[Directive].Name);
+
+ /*
+ * If we are currently ignoring this block and we encounter a #else or
+ * #elif, we must ignore their blocks also if the parent block is also
+ * being ignored.
+ */
+ if (Gbl_IgnoringThisCodeBlock)
+ {
+ switch (Directive)
+ {
+ case PR_DIRECTIVE_ELSE:
+ case PR_DIRECTIVE_ELIF:
+
+ if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock)
+ {
+ PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Need to always check for #else, #elif, #endif regardless of
+ * whether we are ignoring the current code block, since these
+ * are conditional code block terminators.
+ */
+ switch (Directive)
+ {
+ case PR_DIRECTIVE_ELSE:
+
+ Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
+ PrDbgPrint ("Executing", "else block");
+ return;
+
+ case PR_DIRECTIVE_ELIF:
+
+ Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
+ Directive = PR_DIRECTIVE_IF;
+
+ if (Gbl_IgnoringThisCodeBlock == TRUE)
+ {
+ /* Not executing the ELSE part -- all done here */
+ PrDbgPrint ("Ignoring", "elif block");
+ return;
+ }
+
+ /*
+ * After this, we will execute the IF part further below.
+ * First, however, pop off the original #if directive.
+ */
+ if (ACPI_FAILURE (PrPopDirective ()))
+ {
+ PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
+ THIS_TOKEN_OFFSET (DirectiveToken));
+ }
+
+ PrDbgPrint ("Executing", "elif block");
+ break;
+
+ case PR_DIRECTIVE_ENDIF:
+
+ PrDbgPrint ("Executing", "endif");
+
+ /* Pop the owning #if/#ifdef/#ifndef */
+
+ if (ACPI_FAILURE (PrPopDirective ()))
+ {
+ PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH,
+ THIS_TOKEN_OFFSET (DirectiveToken));
+ }
+ return;
+
+ default:
+ break;
+ }
+
+ /* Most directives have at least one argument */
+
+ if (Gbl_DirectiveInfo[Directive].ArgCount >= 1)
+ {
+ Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
+ if (!Token)
+ {
+ goto SyntaxError;
+ }
+ }
+
+ if (Gbl_DirectiveInfo[Directive].ArgCount >= 2)
+ {
+ Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
+ if (!Token2)
+ {
+ goto SyntaxError;
+ }
+ }
+
+ /*
+ * At this point, if we are ignoring the current code block,
+ * do not process any more directives (i.e., ignore them also.)
+ * For "if" style directives, open/push a new block anyway. We
+ * must do this to keep track of #endif directives
+ */
+ if (Gbl_IgnoringThisCodeBlock)
+ {
+ switch (Directive)
+ {
+ case PR_DIRECTIVE_IF:
+ case PR_DIRECTIVE_IFDEF:
+ case PR_DIRECTIVE_IFNDEF:
+
+ PrPushDirective (Directive, Token);
+ PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+ }
+
+ /*
+ * Execute the directive
+ */
+ PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name);
+
+ switch (Directive)
+ {
+ case PR_DIRECTIVE_IF:
+
+ TokenOffset = Token - Gbl_MainTokenBuffer;
+
+ /* Need to expand #define macros in the expression string first */
+
+ Status = PrResolveIntegerExpression (
+ &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ PrPushDirective (Directive, Token);
+ if (!Value)
+ {
+ Gbl_IgnoringThisCodeBlock = TRUE;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Resolved #if: %8.8X%8.8X %s\n",
+ Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value),
+ Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>");
+ break;
+
+ case PR_DIRECTIVE_IFDEF:
+
+ PrPushDirective (Directive, Token);
+ if (!PrMatchDefine (Token))
+ {
+ Gbl_IgnoringThisCodeBlock = TRUE;
+ }
+
+ PrDbgPrint ("Evaluated", "ifdef");
+ break;
+
+ case PR_DIRECTIVE_IFNDEF:
+
+ PrPushDirective (Directive, Token);
+ if (PrMatchDefine (Token))
+ {
+ Gbl_IgnoringThisCodeBlock = TRUE;
+ }
+
+ PrDbgPrint ("Evaluated", "ifndef");
+ break;
+
+ case PR_DIRECTIVE_DEFINE:
+ /*
+ * By definition, if first char after the name is a paren,
+ * this is a function macro.
+ */
+ TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token);
+ if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(')
+ {
+#ifndef MACROS_SUPPORTED
+ AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n",
+ Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber);
+ exit(1);
+#else
+ PrAddMacro (Token, Next);
+#endif
+ }
+ else
+ {
+ /* Use the remainder of the line for the #define */
+
+ Token2 = *Next;
+ if (Token2)
+ {
+ while ((*Token2 == ' ') || (*Token2 == '\t'))
+ {
+ Token2++;
+ }
+ End = Token2;
+ while (*End != '\n')
+ {
+ End++;
+ }
+ *End = 0;
+ }
+ else
+ {
+ Token2 = "";
+ }
+#if 0
+ Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next);
+ if (!Token2)
+ {
+ Token2 = "";
+ }
+#endif
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "New #define: %s->%s\n",
+ Gbl_LogicalLineNumber, Token, Token2);
+
+ PrAddDefine (Token, Token2, FALSE);
+ }
+ break;
+
+ case PR_DIRECTIVE_ERROR:
+
+ /* Note: No macro expansion */
+
+ PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE,
+ THIS_TOKEN_OFFSET (Token));
+
+ Gbl_SourceLine = 0;
+ Gbl_NextError = Gbl_ErrorLog;
+ CmCleanupAndExit ();
+ exit(1);
+
+ case PR_DIRECTIVE_INCLUDE:
+
+ Token = PrGetNextToken (NULL, " \"<>", Next);
+ if (!Token)
+ {
+ goto SyntaxError;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Start #include file \"%s\"\n", Gbl_CurrentLineNumber,
+ Token, Gbl_CurrentLineNumber);
+
+ PrDoIncludeFile (Token);
+ break;
+
+ case PR_DIRECTIVE_INCLUDEBUFFER:
+
+ Token = PrGetNextToken (NULL, " \"<>", Next);
+ if (!Token)
+ {
+ goto SyntaxError;
+ }
+
+ Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
+ if (!Token2)
+ {
+ goto SyntaxError;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Start #includebuffer input from file \"%s\", buffer name %s\n",
+ Gbl_CurrentLineNumber, Token, Token2);
+
+ PrDoIncludeBuffer (Token, Token2);
+ break;
+
+ case PR_DIRECTIVE_LINE:
+
+ TokenOffset = Token - Gbl_MainTokenBuffer;
+
+ Status = PrResolveIntegerExpression (
+ &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "User #line invocation %s\n", Gbl_CurrentLineNumber,
+ Token);
+
+ Gbl_CurrentLineNumber = (UINT32) Value;
+
+ /* Emit #line into the preprocessor file */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
+ Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename);
+ break;
+
+ case PR_DIRECTIVE_PRAGMA:
+
+ if (!strcmp (Token, "disable"))
+ {
+ Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
+ if (!Token)
+ {
+ goto SyntaxError;
+ }
+
+ TokenOffset = Token - Gbl_MainTokenBuffer;
+ AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]);
+ }
+ else if (!strcmp (Token, "message"))
+ {
+ Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
+ if (!Token)
+ {
+ goto SyntaxError;
+ }
+
+ TokenOffset = Token - Gbl_MainTokenBuffer;
+ AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]);
+ }
+ else
+ {
+ PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA,
+ THIS_TOKEN_OFFSET (Token));
+ return;
+ }
+
+ break;
+
+ case PR_DIRECTIVE_UNDEF:
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "#undef: %s\n", Gbl_CurrentLineNumber, Token);
+
+ PrRemoveDefine (Token);
+ break;
+
+ case PR_DIRECTIVE_WARNING:
+
+ PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE,
+ THIS_TOKEN_OFFSET (Token));
+
+ Gbl_SourceLine = 0;
+ Gbl_NextError = Gbl_ErrorLog;
+ break;
+
+ default:
+
+ /* Should never get here */
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Unrecognized directive: %u\n",
+ Gbl_CurrentLineNumber, Directive);
+ break;
+ }
+
+ return;
+
+SyntaxError:
+
+ PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX,
+ THIS_TOKEN_OFFSET (DirectiveToken));
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrGetNextLine, PrGetNextLineInit
+ *
+ * PARAMETERS: Handle - Open file handle for the source file
+ *
+ * RETURN: Status of the GetLine operation:
+ * AE_OK - Normal line, OK status
+ * ASL_WITHIN_COMMENT - Line is part of a multi-line comment
+ * ASL_EOF - End-of-file reached
+ *
+ * DESCRIPTION: Get the next text line from the input file. Does not strip
+ * comments.
+ *
+ ******************************************************************************/
+
+#define PR_NORMAL_TEXT 0
+#define PR_MULTI_LINE_COMMENT 1
+#define PR_SINGLE_LINE_COMMENT 2
+#define PR_QUOTED_STRING 3
+
+static UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+
+static void
+PrGetNextLineInit (
+ void)
+{
+ AcpiGbl_LineScanState = 0;
+}
+
+static UINT32
+PrGetNextLine (
+ FILE *Handle)
+{
+ UINT32 i;
+ int c = 0;
+ int PreviousChar;
+
+
+ /* Always clear the global line buffer */
+
+ memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
+ for (i = 0; ;)
+ {
+ /*
+ * If line is too long, expand the line buffers. Also increases
+ * Gbl_LineBufferSize.
+ */
+ if (i >= Gbl_LineBufferSize)
+ {
+ UtExpandLineBuffers ();
+ }
+
+ PreviousChar = c;
+ c = getc (Handle);
+ if (c == EOF)
+ {
+ return (ASL_EOF);
+ }
+
+ /* Update state machine as necessary */
+
+ switch (AcpiGbl_LineScanState)
+ {
+ case PR_NORMAL_TEXT:
+
+ /* Check for multi-line comment start */
+
+ if ((PreviousChar == '/') && (c == '*'))
+ {
+ AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT;
+ }
+
+ /* Check for single-line comment start */
+
+ else if ((PreviousChar == '/') && (c == '/'))
+ {
+ AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT;
+ }
+
+ /* Check for quoted string start */
+
+ else if (PreviousChar == '"')
+ {
+ AcpiGbl_LineScanState = PR_QUOTED_STRING;
+ }
+ break;
+
+ case PR_QUOTED_STRING:
+
+ if (PreviousChar == '"')
+ {
+ AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+ }
+ break;
+
+ case PR_MULTI_LINE_COMMENT:
+
+ /* Check for multi-line comment end */
+
+ if ((PreviousChar == '*') && (c == '/'))
+ {
+ AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+ }
+ break;
+
+ case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */
+ default:
+ break;
+ }
+
+ /* Always copy the character into line buffer */
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ i++;
+
+ /* Always exit on end-of-line */
+
+ if (c == '\n')
+ {
+ /* Handle multi-line comments */
+
+ if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT)
+ {
+ return (ASL_WITHIN_COMMENT);
+ }
+
+ /* End of single-line comment */
+
+ if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT)
+ {
+ AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+ return (AE_OK);
+ }
+
+ /* Blank line */
+
+ if (i == 1)
+ {
+ return (ASL_BLANK_LINE);
+ }
+ return (AE_OK);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrMatchDirective
+ *
+ * PARAMETERS: Directive - Pointer to directive name token
+ *
+ * RETURN: Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Lookup the incoming directive in the known directives table.
+ *
+ ******************************************************************************/
+
+static int
+PrMatchDirective (
+ char *Directive)
+{
+ int i;
+
+
+ if (!Directive || Directive[0] == 0)
+ {
+ return (ASL_DIRECTIVE_NOT_FOUND);
+ }
+
+ for (i = 0; Gbl_DirectiveInfo[i].Name; i++)
+ {
+ if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive))
+ {
+ return (i);
+ }
+ }
+
+ return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrPushDirective
+ *
+ * PARAMETERS: Directive - Encoded directive ID
+ * Argument - String containing argument to the
+ * directive
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push an item onto the directive stack. Used for processing
+ * nested #if/#else type conditional compilation directives.
+ * Specifically: Used on detection of #if/#ifdef/#ifndef to open
+ * a block.
+ *
+ ******************************************************************************/
+
+static void
+PrPushDirective (
+ int Directive,
+ char *Argument)
+{
+ DIRECTIVE_INFO *Info;
+
+
+ /* Allocate and populate a stack info item */
+
+ Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO));
+
+ Info->Next = Gbl_DirectiveStack;
+ Info->Directive = Directive;
+ Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock;
+ strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n",
+ Gbl_CurrentLineNumber, Gbl_IfDepth,
+ Gbl_IgnoringThisCodeBlock ? "I" : "E",
+ Gbl_IfDepth * 4, " ",
+ Gbl_DirectiveInfo[Directive].Name,
+ Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
+
+ /* Push new item */
+
+ Gbl_DirectiveStack = Info;
+ Gbl_IfDepth++;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrPopDirective
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status. Error if the stack is empty.
+ *
+ * DESCRIPTION: Pop an item off the directive stack. Used for processing
+ * nested #if/#else type conditional compilation directives.
+ * Specifically: Used on detection of #elif and #endif to remove
+ * the original #if/#ifdef/#ifndef from the stack and close
+ * the block.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+PrPopDirective (
+ void)
+{
+ DIRECTIVE_INFO *Info;
+
+
+ /* Check for empty stack */
+
+ Info = Gbl_DirectiveStack;
+ if (!Info)
+ {
+ return (AE_ERROR);
+ }
+
+ /* Pop one item, keep globals up-to-date */
+
+ Gbl_IfDepth--;
+ Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock;
+ Gbl_DirectiveStack = Info->Next;
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n",
+ Gbl_CurrentLineNumber, Gbl_IfDepth,
+ Gbl_IgnoringThisCodeBlock ? "I" : "E",
+ Gbl_IfDepth * 4, " ",
+ Gbl_DirectiveInfo[Info->Directive].Name,
+ Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
+
+ ACPI_FREE (Info);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDbgPrint
+ *
+ * PARAMETERS: Action - Action being performed
+ * DirectiveName - Directive being processed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Special debug print for directive processing.
+ *
+ ******************************************************************************/
+
+static void
+PrDbgPrint (
+ char *Action,
+ char *DirectiveName)
+{
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] "
+ "%*s %s #%s, IfDepth %u\n",
+ Gbl_CurrentLineNumber, Gbl_IfDepth,
+ Gbl_IgnoringThisCodeBlock ? "I" : "E",
+ Gbl_IfDepth * 4, " ",
+ Action, DirectiveName, Gbl_IfDepth);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDoIncludeFile
+ *
+ * PARAMETERS: Pathname - Name of the input file
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Open an include file, from #include.
+ *
+ ******************************************************************************/
+
+static void
+PrDoIncludeFile (
+ char *Pathname)
+{
+ char *FullPathname;
+
+
+ (void) PrOpenIncludeFile (Pathname, "r", &FullPathname);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrDoIncludeBuffer
+ *
+ * PARAMETERS: Pathname - Name of the input binary file
+ * BufferName - ACPI namepath of the buffer
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Create an ACPI buffer object from a binary file. The contents
+ * of the file are emitted into the buffer object as ascii
+ * hex data. From #includebuffer.
+ *
+ ******************************************************************************/
+
+static void
+PrDoIncludeBuffer (
+ char *Pathname,
+ char *BufferName)
+{
+ char *FullPathname;
+ FILE *BinaryBufferFile;
+ UINT32 i = 0;
+ UINT8 c;
+
+
+ BinaryBufferFile = PrOpenIncludeFile (Pathname, "rb", &FullPathname);
+ if (!BinaryBufferFile)
+ {
+ return;
+ }
+
+ /* Emit "Name (XXXX, Buffer() {" header */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "Name (%s, Buffer()\n{", BufferName);
+
+ /* Dump the entire file in ascii hex format */
+
+ while (fread (&c, 1, 1, BinaryBufferFile))
+ {
+ if (!(i % 8))
+ {
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "\n ", c);
+ }
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, " 0x%2.2X,", c);
+ i++;
+ }
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "#includebuffer: read %u bytes from %s\n",
+ Gbl_CurrentLineNumber, i, FullPathname);
+
+ /* Close the Name() operator */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "\n})\n", BufferName);
+ fclose (BinaryBufferFile);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/compiler/prutils.c b/usr/src/boot/sys/contrib/dev/acpica/compiler/prutils.c
new file mode 100644
index 0000000000..751d1a042d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/compiler/prutils.c
@@ -0,0 +1,475 @@
+/******************************************************************************
+ *
+ * Module Name: prutils - Preprocessor utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
+
+
+#define _COMPONENT ASL_PREPROCESSOR
+ ACPI_MODULE_NAME ("prutils")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: PrGetNextToken
+ *
+ * PARAMETERS: Buffer - Current line buffer
+ * MatchString - String with valid token delimiters
+ * Next - Set to next possible token in buffer
+ *
+ * RETURN: Next token (null-terminated). Modifies the input line.
+ * Remainder of line is stored in *Next.
+ *
+ * DESCRIPTION: Local implementation of strtok() with local storage for the
+ * next pointer. Not only thread-safe, but allows multiple
+ * parsing of substrings such as expressions.
+ *
+ *****************************************************************************/
+
+char *
+PrGetNextToken (
+ char *Buffer,
+ char *MatchString,
+ char **Next)
+{
+ char *TokenStart;
+
+
+ if (!Buffer)
+ {
+ /* Use Next if it is valid */
+
+ Buffer = *Next;
+ if (!(*Next))
+ {
+ return (NULL);
+ }
+ }
+
+ /* Skip any leading delimiters */
+
+ while (*Buffer)
+ {
+ if (strchr (MatchString, *Buffer))
+ {
+ Buffer++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Anything left on the line? */
+
+ if (!(*Buffer))
+ {
+ *Next = NULL;
+ return (NULL);
+ }
+
+ TokenStart = Buffer;
+
+ /* Find the end of this token */
+
+ while (*Buffer)
+ {
+ if (strchr (MatchString, *Buffer))
+ {
+ *Buffer = 0;
+ *Next = Buffer+1;
+ if (!**Next)
+ {
+ *Next = NULL;
+ }
+ return (TokenStart);
+ }
+ Buffer++;
+ }
+
+ *Next = NULL;
+ return (TokenStart);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * Column - Column in current line
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Preprocessor error reporting. Front end to AslCommonError2
+ *
+ ******************************************************************************/
+
+void
+PrError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 Column)
+{
+#if 0
+ AcpiOsPrintf ("%s (%u) : %s", Gbl_Files[ASL_FILE_INPUT].Filename,
+ Gbl_CurrentLineNumber, Gbl_CurrentLineBuffer);
+#endif
+
+
+ if (Column > 120)
+ {
+ Column = 0;
+ }
+
+ /* TBD: Need Logical line number? */
+
+ AslCommonError2 (Level, MessageId,
+ Gbl_CurrentLineNumber, Column,
+ Gbl_CurrentLineBuffer,
+ Gbl_Files[ASL_FILE_INPUT].Filename, "Preprocessor");
+
+ Gbl_PreprocessorError = TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrReplaceData
+ *
+ * PARAMETERS: Buffer - Original(target) buffer pointer
+ * LengthToRemove - Length to be removed from target buffer
+ * BufferToAdd - Data to be inserted into target buffer
+ * LengthToAdd - Length of BufferToAdd
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generic buffer data replacement.
+ *
+ ******************************************************************************/
+
+void
+PrReplaceData (
+ char *Buffer,
+ UINT32 LengthToRemove,
+ char *BufferToAdd,
+ UINT32 LengthToAdd)
+{
+ UINT32 BufferLength;
+
+
+ /* Buffer is a string, so the length must include the terminating zero */
+
+ BufferLength = strlen (Buffer) + 1;
+
+ if (LengthToRemove != LengthToAdd)
+ {
+ /*
+ * Move some of the existing data
+ * 1) If adding more bytes than removing, make room for the new data
+ * 2) if removing more bytes than adding, delete the extra space
+ */
+ if (LengthToRemove > 0)
+ {
+ memmove ((Buffer + LengthToAdd), (Buffer + LengthToRemove),
+ (BufferLength - LengthToRemove));
+ }
+ }
+
+ /* Now we can move in the new data */
+
+ if (LengthToAdd > 0)
+ {
+ memmove (Buffer, BufferToAdd, LengthToAdd);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: PrOpenIncludeFile
+ *
+ * PARAMETERS: Filename - Filename or pathname for include file
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Open an include file and push it on the input file stack.
+ *
+ ******************************************************************************/
+
+FILE *
+PrOpenIncludeFile (
+ char *Filename,
+ char *OpenMode,
+ char **FullPathname)
+{
+ FILE *IncludeFile;
+ ASL_INCLUDE_DIR *NextDir;
+
+
+ /* Start the actual include file on the next line */
+
+ Gbl_CurrentLineOffset++;
+
+ /* Attempt to open the include file */
+ /* If the file specifies an absolute path, just open it */
+
+ if ((Filename[0] == '/') ||
+ (Filename[0] == '\\') ||
+ (Filename[1] == ':'))
+ {
+ IncludeFile = PrOpenIncludeWithPrefix (
+ "", Filename, OpenMode, FullPathname);
+ if (!IncludeFile)
+ {
+ goto ErrorExit;
+ }
+ return (IncludeFile);
+ }
+
+ /*
+ * The include filename is not an absolute path.
+ *
+ * First, search for the file within the "local" directory -- meaning
+ * the same directory that contains the source file.
+ *
+ * Construct the file pathname from the global directory name.
+ */
+ IncludeFile = PrOpenIncludeWithPrefix (
+ Gbl_DirectoryPath, Filename, OpenMode, FullPathname);
+ if (IncludeFile)
+ {
+ return (IncludeFile);
+ }
+
+ /*
+ * Second, search for the file within the (possibly multiple)
+ * directories specified by the -I option on the command line.
+ */
+ NextDir = Gbl_IncludeDirList;
+ while (NextDir)
+ {
+ IncludeFile = PrOpenIncludeWithPrefix (
+ NextDir->Dir, Filename, OpenMode, FullPathname);
+ if (IncludeFile)
+ {
+ return (IncludeFile);
+ }
+
+ NextDir = NextDir->Next;
+ }
+
+ /* We could not open the include file after trying very hard */
+
+ErrorExit:
+ sprintf (Gbl_MainTokenBuffer, "%s, %s", Filename, strerror (errno));
+ PrError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, 0);
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlOpenIncludeWithPrefix
+ *
+ * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero
+ * length string.
+ * Filename - The include filename from the source ASL.
+ *
+ * RETURN: Valid file descriptor if successful. Null otherwise.
+ *
+ * DESCRIPTION: Open an include file and push it on the input file stack.
+ *
+ ******************************************************************************/
+
+FILE *
+PrOpenIncludeWithPrefix (
+ char *PrefixDir,
+ char *Filename,
+ char *OpenMode,
+ char **FullPathname)
+{
+ FILE *IncludeFile;
+ char *Pathname;
+
+
+ /* Build the full pathname to the file */
+
+ Pathname = FlMergePathnames (PrefixDir, Filename);
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Include: Opening file - \"%s\"\n",
+ Gbl_CurrentLineNumber, Pathname);
+
+ /* Attempt to open the file, push if successful */
+
+ IncludeFile = fopen (Pathname, OpenMode);
+ if (!IncludeFile)
+ {
+ fprintf (stderr, "Could not open include file %s\n", Pathname);
+ return (NULL);
+ }
+
+ /* Push the include file on the open input file stack */
+
+ PrPushInputFileStack (IncludeFile, Pathname);
+ *FullPathname = Pathname;
+ return (IncludeFile);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPushInputFileStack
+ *
+ * PARAMETERS: InputFile - Open file pointer
+ * Filename - Name of the file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
+ * to this file. Called when an include file is successfully
+ * opened.
+ *
+ ******************************************************************************/
+
+void
+PrPushInputFileStack (
+ FILE *InputFile,
+ char *Filename)
+{
+ PR_FILE_NODE *Fnode;
+
+
+ Gbl_HasIncludeFiles = TRUE;
+
+ /* Save the current state in an Fnode */
+
+ Fnode = UtLocalCalloc (sizeof (PR_FILE_NODE));
+
+ Fnode->File = Gbl_Files[ASL_FILE_INPUT].Handle;
+ Fnode->Next = Gbl_InputFileList;
+ Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
+ Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
+
+ /* Push it on the stack */
+
+ Gbl_InputFileList = Fnode;
+
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Push InputFile Stack: handle %p\n\n",
+ Gbl_CurrentLineNumber, InputFile);
+
+ /* Reset the global line count and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename =
+ UtStringCacheCalloc (strlen (Filename) + 1);
+ strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
+
+ Gbl_Files[ASL_FILE_INPUT].Handle = InputFile;
+ Gbl_CurrentLineNumber = 1;
+
+ /* Emit a new #line directive for the include file */
+
+ Gbl_CurrentLineNumber = 1;
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", 1, Filename);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPopInputFileStack
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: 0 if a node was popped, -1 otherwise
+ *
+ * DESCRIPTION: Pop the top of the input file stack and point the parser to
+ * the saved parse buffer contained in the fnode. Also, set the
+ * global line counters to the saved values. This function is
+ * called when an include file reaches EOF.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+PrPopInputFileStack (
+ void)
+{
+ PR_FILE_NODE *Fnode;
+
+
+ Fnode = Gbl_InputFileList;
+ DbgPrint (ASL_PARSE_OUTPUT, "\n" PR_PREFIX_ID
+ "Pop InputFile Stack, Fnode %p\n\n",
+ Gbl_CurrentLineNumber, Fnode);
+
+ if (!Fnode)
+ {
+ return (FALSE);
+ }
+
+ /* Close the current include file */
+
+ fclose (Gbl_Files[ASL_FILE_INPUT].Handle);
+
+ /* Update the top-of-stack */
+
+ Gbl_InputFileList = Fnode->Next;
+
+ /* Reset global line counter and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
+ Gbl_Files[ASL_FILE_INPUT].Handle = Fnode->File;
+ Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
+
+ /* Emit a new #line directive after the include file */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
+ Gbl_CurrentLineNumber, Fnode->Filename);
+
+ /* All done with this node */
+
+ ACPI_FREE (Fnode);
+ return (TRUE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbcmds.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbcmds.c
new file mode 100644
index 0000000000..e504130c62
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbcmds.c
@@ -0,0 +1,1350 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbcmds")
+
+
+/* Local prototypes */
+
+static void
+AcpiDmCompareAmlResources (
+ UINT8 *Aml1Buffer,
+ ACPI_RSDESC_SIZE Aml1BufferLength,
+ UINT8 *Aml2Buffer,
+ ACPI_RSDESC_SIZE Aml2BufferLength);
+
+static ACPI_STATUS
+AcpiDmTestResourceConversion (
+ ACPI_NAMESPACE_NODE *Node,
+ char *Name);
+
+static ACPI_STATUS
+AcpiDbResourceCallback (
+ ACPI_RESOURCE *Resource,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDbDeviceResources (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static void
+AcpiDbDoOneSleepState (
+ UINT8 SleepState);
+
+
+static char *AcpiDbTraceMethodName = NULL;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToNode
+ *
+ * PARAMETERS: InString - String to convert
+ *
+ * RETURN: Pointer to a NS node
+ *
+ * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
+ * alphanumeric strings.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiDbConvertToNode (
+ char *InString)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_SIZE Address;
+
+
+ if ((*InString >= 0x30) && (*InString <= 0x39))
+ {
+ /* Numeric argument, convert */
+
+ Address = strtoul (InString, NULL, 16);
+ Node = ACPI_TO_POINTER (Address);
+ if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf ("Address %p is invalid",
+ Node);
+ return (NULL);
+ }
+
+ /* Make sure pointer is valid NS node */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf ("Address %p is not a valid namespace node [%s]\n",
+ Node, AcpiUtGetDescriptorName (Node));
+ return (NULL);
+ }
+ }
+ else
+ {
+ /*
+ * Alpha argument: The parameter is a name string that must be
+ * resolved to a Namespace object.
+ */
+ Node = AcpiDbLocalNsLookup (InString);
+ if (!Node)
+ {
+ AcpiOsPrintf (
+ "Could not find [%s] in namespace, defaulting to root node\n",
+ InString);
+ Node = AcpiGbl_RootNode;
+ }
+ }
+
+ return (Node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSleep
+ *
+ * PARAMETERS: ObjectArg - Desired sleep state (0-5). NULL means
+ * invoke all possible sleep states.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simulate sleep/wake sequences
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSleep (
+ char *ObjectArg)
+{
+ UINT8 SleepState;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDbSleep);
+
+
+ /* Null input (no arguments) means to invoke all sleep states */
+
+ if (!ObjectArg)
+ {
+ AcpiOsPrintf ("Invoking all possible sleep states, 0-%d\n",
+ ACPI_S_STATES_MAX);
+
+ for (i = 0; i <= ACPI_S_STATES_MAX; i++)
+ {
+ AcpiDbDoOneSleepState ((UINT8) i);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Convert argument to binary and invoke the sleep state */
+
+ SleepState = (UINT8) strtoul (ObjectArg, NULL, 0);
+ AcpiDbDoOneSleepState (SleepState);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDoOneSleepState
+ *
+ * PARAMETERS: SleepState - Desired sleep state (0-5)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Simulate a sleep/wake sequence
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDoOneSleepState (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+ UINT8 SleepTypeA;
+ UINT8 SleepTypeB;
+
+
+ /* Validate parameter */
+
+ if (SleepState > ACPI_S_STATES_MAX)
+ {
+ AcpiOsPrintf ("Sleep state %d out of range (%d max)\n",
+ SleepState, ACPI_S_STATES_MAX);
+ return;
+ }
+
+ AcpiOsPrintf ("\n---- Invoking sleep state S%d (%s):\n",
+ SleepState, AcpiGbl_SleepStateNames[SleepState]);
+
+ /* Get the values for the sleep type registers (for display only) */
+
+ Status = AcpiGetSleepTypeData (SleepState, &SleepTypeA, &SleepTypeB);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate [%s] method, %s\n",
+ AcpiGbl_SleepStateNames[SleepState],
+ AcpiFormatException (Status));
+ return;
+ }
+
+ AcpiOsPrintf (
+ "Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
+ SleepState, SleepTypeA, SleepTypeB);
+
+ /* Invoke the various sleep/wake interfaces */
+
+ AcpiOsPrintf ("**** Sleep: Prepare to sleep (S%d) ****\n",
+ SleepState);
+ Status = AcpiEnterSleepStatePrep (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Sleep: Going to sleep (S%d) ****\n",
+ SleepState);
+ Status = AcpiEnterSleepState (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Wake: Prepare to return from sleep (S%d) ****\n",
+ SleepState);
+ Status = AcpiLeaveSleepStatePrep (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Wake: Return from sleep (S%d) ****\n",
+ SleepState);
+ Status = AcpiLeaveSleepState (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ return;
+
+
+ErrorExit:
+ ACPI_EXCEPTION ((AE_INFO, Status, "During invocation of sleep state S%d",
+ SleepState));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayLocks
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayLocks (
+ void)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < ACPI_MAX_MUTEX; i++)
+ {
+ AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
+ AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
+ ? "Locked" : "Unlocked");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayTableInfo
+ *
+ * PARAMETERS: TableArg - Name of table to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about loaded tables. Current
+ * implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayTableInfo (
+ char *TableArg)
+{
+ UINT32 i;
+ ACPI_TABLE_DESC *TableDesc;
+ ACPI_STATUS Status;
+
+
+ /* Header */
+
+ AcpiOsPrintf ("Idx ID Status Type "
+ "TableHeader (Sig, Address, Length, Misc)\n");
+
+ /* Walk the entire root table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ TableDesc = &AcpiGbl_RootTableList.Tables[i];
+
+ /* Index and Table ID */
+
+ AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
+
+ /* Decode the table flags */
+
+ if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
+ {
+ AcpiOsPrintf ("NotLoaded ");
+ }
+ else
+ {
+ AcpiOsPrintf (" Loaded ");
+ }
+
+ switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+ AcpiOsPrintf ("External/virtual ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+ AcpiOsPrintf ("Internal/physical ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+
+ AcpiOsPrintf ("Internal/virtual ");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("INVALID TYPE ");
+ break;
+ }
+
+ /* Make sure that the table is mapped */
+
+ Status = AcpiTbValidateTable (TableDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Dump the table header */
+
+ if (TableDesc->Pointer)
+ {
+ AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
+ }
+ else
+ {
+ /* If the pointer is null, the table has been unloaded */
+
+ ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
+ TableDesc->Signature.Ascii));
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUnloadAcpiTable
+ *
+ * PARAMETERS: ObjectName - Namespace pathname for an object that
+ * is owned by the table to be unloaded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ * by the table.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbUnloadAcpiTable (
+ char *ObjectName)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Translate name to an Named object */
+
+ Node = AcpiDbConvertToNode (ObjectName);
+ if (!Node)
+ {
+ return;
+ }
+
+ Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
+ ObjectName, Node);
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
+ AcpiFormatException (Status), ObjectName);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSendNotify
+ *
+ * PARAMETERS: Name - Name of ACPI object where to send notify
+ * Value - Value of the notify to send.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
+ * named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSendNotify (
+ char *Name,
+ UINT32 Value)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Translate name to an Named object */
+
+ Node = AcpiDbConvertToNode (Name);
+ if (!Node)
+ {
+ return;
+ }
+
+ /* Dispatch the notify if legal */
+
+ if (AcpiEvIsNotifyObject (Node))
+ {
+ Status = AcpiEvQueueNotifyRequest (Node, Value);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not queue notify\n");
+ }
+ }
+ else
+ {
+ AcpiOsPrintf (
+ "Named object [%4.4s] Type %s, "
+ "must be Device/Thermal/Processor type\n",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayInterfaces
+ *
+ * PARAMETERS: ActionArg - Null, "install", or "remove"
+ * InterfaceNameArg - Name for install/remove options
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display or modify the global _OSI interface list
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayInterfaces (
+ char *ActionArg,
+ char *InterfaceNameArg)
+{
+ ACPI_INTERFACE_INFO *NextInterface;
+ char *SubString;
+ ACPI_STATUS Status;
+
+
+ /* If no arguments, just display current interface list */
+
+ if (!ActionArg)
+ {
+ (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+ while (NextInterface)
+ {
+ if (!(NextInterface->Flags & ACPI_OSI_INVALID))
+ {
+ AcpiOsPrintf ("%s\n", NextInterface->Name);
+ }
+
+ NextInterface = NextInterface->Next;
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return;
+ }
+
+ /* If ActionArg exists, so must InterfaceNameArg */
+
+ if (!InterfaceNameArg)
+ {
+ AcpiOsPrintf ("Missing Interface Name argument\n");
+ return;
+ }
+
+ /* Uppercase the action for match below */
+
+ AcpiUtStrupr (ActionArg);
+
+ /* Install - install an interface */
+
+ SubString = strstr ("INSTALL", ActionArg);
+ if (SubString)
+ {
+ Status = AcpiInstallInterface (InterfaceNameArg);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, while installing \"%s\"\n",
+ AcpiFormatException (Status), InterfaceNameArg);
+ }
+ return;
+ }
+
+ /* Remove - remove an interface */
+
+ SubString = strstr ("REMOVE", ActionArg);
+ if (SubString)
+ {
+ Status = AcpiRemoveInterface (InterfaceNameArg);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, while removing \"%s\"\n",
+ AcpiFormatException (Status), InterfaceNameArg);
+ }
+ return;
+ }
+
+ /* Invalid ActionArg */
+
+ AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayTemplate
+ *
+ * PARAMETERS: BufferArg - Buffer name or address
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer that contains a resource template
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayTemplate (
+ char *BufferArg)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnBuffer;
+
+
+ /* Translate BufferArg to an Named object */
+
+ Node = AcpiDbConvertToNode (BufferArg);
+ if (!Node || (Node == AcpiGbl_RootNode))
+ {
+ AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
+ return;
+ }
+
+ /* We must have a buffer object */
+
+ if (Node->Type != ACPI_TYPE_BUFFER)
+ {
+ AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
+ BufferArg);
+ return;
+ }
+
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+
+ /* Attempt to convert the raw buffer to a resource list */
+
+ Status = AcpiRsCreateResourceList (Node->Object, &ReturnBuffer);
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiDbgLevel |= ACPI_LV_RESOURCES;
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf (
+ "Could not convert Buffer to a resource list: %s, %s\n",
+ BufferArg, AcpiFormatException (Status));
+ goto DumpBuffer;
+ }
+
+ /* Now we can dump the resource list */
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
+ ReturnBuffer.Pointer));
+
+DumpBuffer:
+ AcpiOsPrintf ("\nRaw data buffer:\n");
+ AcpiUtDebugDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
+ Node->Object->Buffer.Length,
+ DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCompareAmlResources
+ *
+ * PARAMETERS: Aml1Buffer - Contains first resource list
+ * Aml1BufferLength - Length of first resource list
+ * Aml2Buffer - Contains second resource list
+ * Aml2BufferLength - Length of second resource list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
+ * order to isolate a miscompare to an individual resource)
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmCompareAmlResources (
+ UINT8 *Aml1Buffer,
+ ACPI_RSDESC_SIZE Aml1BufferLength,
+ UINT8 *Aml2Buffer,
+ ACPI_RSDESC_SIZE Aml2BufferLength)
+{
+ UINT8 *Aml1;
+ UINT8 *Aml2;
+ UINT8 *Aml1End;
+ UINT8 *Aml2End;
+ ACPI_RSDESC_SIZE Aml1Length;
+ ACPI_RSDESC_SIZE Aml2Length;
+ ACPI_RSDESC_SIZE Offset = 0;
+ UINT8 ResourceType;
+ UINT32 Count = 0;
+ UINT32 i;
+
+
+ /* Compare overall buffer sizes (may be different due to size rounding) */
+
+ if (Aml1BufferLength != Aml2BufferLength)
+ {
+ AcpiOsPrintf (
+ "**** Buffer length mismatch in converted "
+ "AML: Original %X, New %X ****\n",
+ Aml1BufferLength, Aml2BufferLength);
+ }
+
+ Aml1 = Aml1Buffer;
+ Aml2 = Aml2Buffer;
+ Aml1End = Aml1Buffer + Aml1BufferLength;
+ Aml2End = Aml2Buffer + Aml2BufferLength;
+
+ /* Walk the descriptor lists, comparing each descriptor */
+
+ while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
+ {
+ /* Get the lengths of each descriptor */
+
+ Aml1Length = AcpiUtGetDescriptorLength (Aml1);
+ Aml2Length = AcpiUtGetDescriptorLength (Aml2);
+ ResourceType = AcpiUtGetResourceType (Aml1);
+
+ /* Check for descriptor length match */
+
+ if (Aml1Length != Aml2Length)
+ {
+ AcpiOsPrintf (
+ "**** Length mismatch in descriptor [%.2X] type %2.2X, "
+ "Offset %8.8X Len1 %X, Len2 %X ****\n",
+ Count, ResourceType, Offset, Aml1Length, Aml2Length);
+ }
+
+ /* Check for descriptor byte match */
+
+ else if (memcmp (Aml1, Aml2, Aml1Length))
+ {
+ AcpiOsPrintf (
+ "**** Data mismatch in descriptor [%.2X] type %2.2X, "
+ "Offset %8.8X ****\n",
+ Count, ResourceType, Offset);
+
+ for (i = 0; i < Aml1Length; i++)
+ {
+ if (Aml1[i] != Aml2[i])
+ {
+ AcpiOsPrintf (
+ "Mismatch at byte offset %.2X: is %2.2X, "
+ "should be %2.2X\n",
+ i, Aml2[i], Aml1[i]);
+ }
+ }
+ }
+
+ /* Exit on EndTag descriptor */
+
+ if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
+ {
+ return;
+ }
+
+ /* Point to next descriptor in each buffer */
+
+ Count++;
+ Offset += Aml1Length;
+ Aml1 += Aml1Length;
+ Aml2 += Aml2Length;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmTestResourceConversion
+ *
+ * PARAMETERS: Node - Parent device node
+ * Name - resource method name (_CRS)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compare the original AML with a conversion of the AML to
+ * internal resource list, then back to AML.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmTestResourceConversion (
+ ACPI_NAMESPACE_NODE *Node,
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnBuffer;
+ ACPI_BUFFER ResourceBuffer;
+ ACPI_BUFFER NewAml;
+ ACPI_OBJECT *OriginalAml;
+
+
+ AcpiOsPrintf ("Resource Conversion Comparison:\n");
+
+ NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ ResourceBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ /* Get the original _CRS AML resource template */
+
+ Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not obtain %s: %s\n",
+ Name, AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /* Get the AML resource template, converted to internal resource structs */
+
+ Status = AcpiGetCurrentResources (Node, &ResourceBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Exit1;
+ }
+
+ /* Convert internal resource list to external AML resource template */
+
+ Status = AcpiRsCreateAmlResources (&ResourceBuffer, &NewAml);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Exit2;
+ }
+
+ /* Compare original AML to the newly created AML resource list */
+
+ OriginalAml = ReturnBuffer.Pointer;
+
+ AcpiDmCompareAmlResources (OriginalAml->Buffer.Pointer,
+ (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
+ NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
+
+ /* Cleanup and exit */
+
+ ACPI_FREE (NewAml.Pointer);
+Exit2:
+ ACPI_FREE (ResourceBuffer.Pointer);
+Exit1:
+ ACPI_FREE (ReturnBuffer.Pointer);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbResourceCallback
+ *
+ * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simple callback to exercise AcpiWalkResources and
+ * AcpiWalkResourceBuffer.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbResourceCallback (
+ ACPI_RESOURCE *Resource,
+ void *Context)
+{
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDeviceResources
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbDeviceResources (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *PrtNode = NULL;
+ ACPI_NAMESPACE_NODE *CrsNode = NULL;
+ ACPI_NAMESPACE_NODE *PrsNode = NULL;
+ ACPI_NAMESPACE_NODE *AeiNode = NULL;
+ char *ParentPath;
+ ACPI_BUFFER ReturnBuffer;
+ ACPI_STATUS Status;
+
+
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ParentPath = AcpiNsGetExternalPathname (Node);
+ if (!ParentPath)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get handles to the resource methods for this device */
+
+ (void) AcpiGetHandle (Node, METHOD_NAME__PRT,
+ ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__CRS,
+ ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__PRS,
+ ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__AEI,
+ ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
+
+ if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
+ {
+ goto Cleanup; /* Nothing to do */
+ }
+
+ AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
+
+ /* Prepare for a return object of arbitrary size */
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+
+ /* _PRT */
+
+ if (PrtNode)
+ {
+ AcpiOsPrintf ("Evaluating _PRT\n");
+
+ Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
+ AcpiFormatException (Status));
+ goto GetCrs;
+ }
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetIrqRoutingTable (Node, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetCrs;
+ }
+
+ AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
+ }
+
+
+ /* _CRS */
+
+GetCrs:
+ if (CrsNode)
+ {
+ AcpiOsPrintf ("Evaluating _CRS\n");
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* This code exercises the AcpiWalkResources interface */
+
+ Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
+ AcpiDbResourceCallback, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* Get the _CRS resource list (test ALLOCATE buffer) */
+
+ ReturnBuffer.Pointer = NULL;
+ ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ Status = AcpiGetCurrentResources (Node, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* This code exercises the AcpiWalkResourceBuffer interface */
+
+ Status = AcpiWalkResourceBuffer (&ReturnBuffer,
+ AcpiDbResourceCallback, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiWalkResourceBuffer failed: %s\n",
+ AcpiFormatException (Status));
+ goto EndCrs;
+ }
+
+ /* Dump the _CRS resource list */
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
+ ReturnBuffer.Pointer));
+
+ /*
+ * Perform comparison of original AML to newly created AML. This
+ * tests both the AML->Resource conversion and the Resource->AML
+ * conversion.
+ */
+ (void) AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
+
+ /* Execute _SRS with the resource list */
+
+ AcpiOsPrintf ("Evaluating _SRS\n");
+
+ Status = AcpiSetCurrentResources (Node, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto EndCrs;
+ }
+
+EndCrs:
+ ACPI_FREE (ReturnBuffer.Pointer);
+ }
+
+
+ /* _PRS */
+
+GetPrs:
+ if (PrsNode)
+ {
+ AcpiOsPrintf ("Evaluating _PRS\n");
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
+ AcpiFormatException (Status));
+ goto GetAei;
+ }
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetPossibleResources (Node, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetAei;
+ }
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (
+ ACPI_RESOURCE, AcpiGbl_DbBuffer));
+ }
+
+
+ /* _AEI */
+
+GetAei:
+ if (AeiNode)
+ {
+ AcpiOsPrintf ("Evaluating _AEI\n");
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ ReturnBuffer.Pointer = AcpiGbl_DbBuffer;
+ ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetEventResources (Node, &ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (
+ ACPI_RESOURCE, AcpiGbl_DbBuffer));
+ }
+
+
+Cleanup:
+ ACPI_FREE (ParentPath);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResources
+ *
+ * PARAMETERS: ObjectArg - String object name or object pointer.
+ * NULL or "*" means "display resources for
+ * all devices"
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the resource objects associated with a device.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResources (
+ char *ObjectArg)
+{
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiDbgLevel |= ACPI_LV_RESOURCES;
+
+ /* Asterisk means "display resources for all devices" */
+
+ if (!ObjectArg || (!strcmp (ObjectArg, "*")))
+ {
+ (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
+ }
+ else
+ {
+ /* Convert string to object pointer */
+
+ Node = AcpiDbConvertToNode (ObjectArg);
+ if (Node)
+ {
+ if (Node->Type != ACPI_TYPE_DEVICE)
+ {
+ AcpiOsPrintf (
+ "%4.4s: Name is not a device object (%s)\n",
+ Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
+ }
+ else
+ {
+ (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
+ }
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGenerateGpe
+ *
+ * PARAMETERS: GpeArg - Raw GPE number, ascii string
+ * BlockArg - GPE block number, ascii string
+ * 0 or 1 for FADT GPE blocks
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Simulate firing of a GPE
+ *
+ ******************************************************************************/
+
+void
+AcpiDbGenerateGpe (
+ char *GpeArg,
+ char *BlockArg)
+{
+ UINT32 BlockNumber = 0;
+ UINT32 GpeNumber;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+
+
+ GpeNumber = strtoul (GpeArg, NULL, 0);
+
+ /*
+ * If no block arg, or block arg == 0 or 1, use the FADT-defined
+ * GPE blocks.
+ */
+ if (BlockArg)
+ {
+ BlockNumber = strtoul (BlockArg, NULL, 0);
+ if (BlockNumber == 1)
+ {
+ BlockNumber = 0;
+ }
+ }
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
+ GpeNumber);
+ if (!GpeEventInfo)
+ {
+ AcpiOsPrintf ("Invalid GPE\n");
+ return;
+ }
+
+ (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGenerateSci
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbGenerateSci (
+ void)
+{
+ AcpiEvSciDispatch ();
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTrace
+ *
+ * PARAMETERS: EnableArg - ENABLE/AML to enable tracer
+ * DISABLE to disable tracer
+ * MethodArg - Method to trace
+ * OnceArg - Whether trace once
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Control method tracing facility
+ *
+ ******************************************************************************/
+
+void
+AcpiDbTrace (
+ char *EnableArg,
+ char *MethodArg,
+ char *OnceArg)
+{
+ UINT32 DebugLevel = 0;
+ UINT32 DebugLayer = 0;
+ UINT32 Flags = 0;
+
+
+ if (EnableArg)
+ {
+ AcpiUtStrupr (EnableArg);
+ }
+
+ if (OnceArg)
+ {
+ AcpiUtStrupr (OnceArg);
+ }
+
+ if (MethodArg)
+ {
+ if (AcpiDbTraceMethodName)
+ {
+ ACPI_FREE (AcpiDbTraceMethodName);
+ AcpiDbTraceMethodName = NULL;
+ }
+
+ AcpiDbTraceMethodName = ACPI_ALLOCATE (strlen (MethodArg) + 1);
+ if (!AcpiDbTraceMethodName)
+ {
+ AcpiOsPrintf ("Failed to allocate method name (%s)\n",
+ MethodArg);
+ return;
+ }
+
+ strcpy (AcpiDbTraceMethodName, MethodArg);
+ }
+
+ if (!strcmp (EnableArg, "ENABLE") ||
+ !strcmp (EnableArg, "METHOD") ||
+ !strcmp (EnableArg, "OPCODE"))
+ {
+ if (!strcmp (EnableArg, "ENABLE"))
+ {
+ /* Inherit current console settings */
+
+ DebugLevel = AcpiGbl_DbConsoleDebugLevel;
+ DebugLayer = AcpiDbgLayer;
+ }
+ else
+ {
+ /* Restrict console output to trace points only */
+
+ DebugLevel = ACPI_LV_TRACE_POINT;
+ DebugLayer = ACPI_EXECUTER;
+ }
+
+ Flags = ACPI_TRACE_ENABLED;
+
+ if (!strcmp (EnableArg, "OPCODE"))
+ {
+ Flags |= ACPI_TRACE_OPCODE;
+ }
+
+ if (OnceArg && !strcmp (OnceArg, "ONCE"))
+ {
+ Flags |= ACPI_TRACE_ONESHOT;
+ }
+ }
+
+ (void) AcpiDebugTrace (AcpiDbTraceMethodName,
+ DebugLevel, DebugLayer, Flags);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbconvert.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbconvert.c
new file mode 100644
index 0000000000..bb024e0a9b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbconvert.c
@@ -0,0 +1,529 @@
+/*******************************************************************************
+ *
+ * Module Name: dbconvert - debugger miscellaneous conversion routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbconvert")
+
+
+#define DB_DEFAULT_PKG_ELEMENTS 33
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbHexCharToValue
+ *
+ * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F
+ * ReturnValue - Where the converted value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbHexCharToValue (
+ int HexChar,
+ UINT8 *ReturnValue)
+{
+ UINT8 Value;
+
+
+ /* Digit must be ascii [0-9a-fA-F] */
+
+ if (!isxdigit (HexChar))
+ {
+ return (AE_BAD_HEX_CONSTANT);
+ }
+
+ if (HexChar <= 0x39)
+ {
+ Value = (UINT8) (HexChar - 0x30);
+ }
+ else
+ {
+ Value = (UINT8) (toupper (HexChar) - 0x37);
+ }
+
+ *ReturnValue = Value;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbHexByteToBinary
+ *
+ * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format:
+ * HiByte then LoByte.
+ * ReturnValue - Where the converted value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbHexByteToBinary (
+ char *HexByte,
+ UINT8 *ReturnValue)
+{
+ UINT8 Local0;
+ UINT8 Local1;
+ ACPI_STATUS Status;
+
+
+ /* High byte */
+
+ Status = AcpiDbHexCharToValue (HexByte[0], &Local0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Low byte */
+
+ Status = AcpiDbHexCharToValue (HexByte[1], &Local1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *ReturnValue = (UINT8) ((Local0 << 4) | Local1);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToBuffer
+ *
+ * PARAMETERS: String - Input string to be converted
+ * Object - Where the buffer object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a string to a buffer object. String is treated a list
+ * of buffer elements, each separated by a space or comma.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbConvertToBuffer (
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 Length;
+ UINT8 *Buffer;
+ ACPI_STATUS Status;
+
+
+ /* Generate the final buffer length */
+
+ for (i = 0, Length = 0; String[i];)
+ {
+ i+=2;
+ Length++;
+
+ while (String[i] &&
+ ((String[i] == ',') || (String[i] == ' ')))
+ {
+ i++;
+ }
+ }
+
+ Buffer = ACPI_ALLOCATE (Length);
+ if (!Buffer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Convert the command line bytes to the buffer */
+
+ for (i = 0, j = 0; String[i];)
+ {
+ Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (Buffer);
+ return (Status);
+ }
+
+ j++;
+ i+=2;
+ while (String[i] &&
+ ((String[i] == ',') || (String[i] == ' ')))
+ {
+ i++;
+ }
+ }
+
+ Object->Type = ACPI_TYPE_BUFFER;
+ Object->Buffer.Pointer = Buffer;
+ Object->Buffer.Length = Length;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToPackage
+ *
+ * PARAMETERS: String - Input string to be converted
+ * Object - Where the package object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a string to a package object. Handles nested packages
+ * via recursion with AcpiDbConvertToObject.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbConvertToPackage (
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ char *This;
+ char *Next;
+ UINT32 i;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_OBJECT *Elements;
+ ACPI_STATUS Status;
+
+
+ Elements = ACPI_ALLOCATE_ZEROED (
+ DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
+
+ This = String;
+ for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
+ {
+ This = AcpiDbGetNextToken (This, &Next, &Type);
+ if (!This)
+ {
+ break;
+ }
+
+ /* Recursive call to convert each package element */
+
+ Status = AcpiDbConvertToObject (Type, This, &Elements[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDbDeleteObjects (i + 1, Elements);
+ ACPI_FREE (Elements);
+ return (Status);
+ }
+
+ This = Next;
+ }
+
+ Object->Type = ACPI_TYPE_PACKAGE;
+ Object->Package.Count = i;
+ Object->Package.Elements = Elements;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToObject
+ *
+ * PARAMETERS: Type - Object type as determined by parser
+ * String - Input string to be converted
+ * Object - Where the new object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing:
+ * 1) String objects were surrounded by quotes.
+ * 2) Buffer objects were surrounded by parentheses.
+ * 3) Package objects were surrounded by brackets "[]".
+ * 4) All standalone tokens are treated as integers.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbConvertToObject (
+ ACPI_OBJECT_TYPE Type,
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ switch (Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ Object->Type = ACPI_TYPE_STRING;
+ Object->String.Pointer = String;
+ Object->String.Length = (UINT32) strlen (String);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiDbConvertToBuffer (String, Object);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ Status = AcpiDbConvertToPackage (String, Object);
+ break;
+
+ default:
+
+ Object->Type = ACPI_TYPE_INTEGER;
+ Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value);
+ break;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbEncodePldBuffer
+ *
+ * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct)
+ *
+ * RETURN: Encode _PLD buffer suitable for return value from _PLD
+ *
+ * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros
+ *
+ ******************************************************************************/
+
+UINT8 *
+AcpiDbEncodePldBuffer (
+ ACPI_PLD_INFO *PldInfo)
+{
+ UINT32 *Buffer;
+ UINT32 Dword;
+
+
+ Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
+ if (!Buffer)
+ {
+ return (NULL);
+ }
+
+ /* First 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_REVISION (&Dword, PldInfo->Revision);
+ ACPI_PLD_SET_IGNORE_COLOR (&Dword, PldInfo->IgnoreColor);
+ ACPI_PLD_SET_RED (&Dword, PldInfo->Red);
+ ACPI_PLD_SET_GREEN (&Dword, PldInfo->Green);
+ ACPI_PLD_SET_BLUE (&Dword, PldInfo->Blue);
+ ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword);
+
+ /* Second 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_WIDTH (&Dword, PldInfo->Width);
+ ACPI_PLD_SET_HEIGHT (&Dword, PldInfo->Height);
+ ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword);
+
+ /* Third 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_USER_VISIBLE (&Dword, PldInfo->UserVisible);
+ ACPI_PLD_SET_DOCK (&Dword, PldInfo->Dock);
+ ACPI_PLD_SET_LID (&Dword, PldInfo->Lid);
+ ACPI_PLD_SET_PANEL (&Dword, PldInfo->Panel);
+ ACPI_PLD_SET_VERTICAL (&Dword, PldInfo->VerticalPosition);
+ ACPI_PLD_SET_HORIZONTAL (&Dword, PldInfo->HorizontalPosition);
+ ACPI_PLD_SET_SHAPE (&Dword, PldInfo->Shape);
+ ACPI_PLD_SET_ORIENTATION (&Dword, PldInfo->GroupOrientation);
+ ACPI_PLD_SET_TOKEN (&Dword, PldInfo->GroupToken);
+ ACPI_PLD_SET_POSITION (&Dword, PldInfo->GroupPosition);
+ ACPI_PLD_SET_BAY (&Dword, PldInfo->Bay);
+ ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword);
+
+ /* Fourth 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_EJECTABLE (&Dword, PldInfo->Ejectable);
+ ACPI_PLD_SET_OSPM_EJECT (&Dword, PldInfo->OspmEjectRequired);
+ ACPI_PLD_SET_CABINET (&Dword, PldInfo->CabinetNumber);
+ ACPI_PLD_SET_CARD_CAGE (&Dword, PldInfo->CardCageNumber);
+ ACPI_PLD_SET_REFERENCE (&Dword, PldInfo->Reference);
+ ACPI_PLD_SET_ROTATION (&Dword, PldInfo->Rotation);
+ ACPI_PLD_SET_ORDER (&Dword, PldInfo->Order);
+ ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword);
+
+ if (PldInfo->Revision >= 2)
+ {
+ /* Fifth 32 bits */
+
+ Dword = 0;
+ ACPI_PLD_SET_VERT_OFFSET (&Dword, PldInfo->VerticalOffset);
+ ACPI_PLD_SET_HORIZ_OFFSET (&Dword, PldInfo->HorizontalOffset);
+ ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword);
+ }
+
+ return (ACPI_CAST_PTR (UINT8, Buffer));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpPldBuffer
+ *
+ * PARAMETERS: ObjDesc - Object returned from _PLD method
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Dumps formatted contents of a _PLD return buffer.
+ *
+ ******************************************************************************/
+
+#define ACPI_PLD_OUTPUT "%20s : %-6X\n"
+
+void
+AcpiDbDumpPldBuffer (
+ ACPI_OBJECT *ObjDesc)
+{
+ ACPI_OBJECT *BufferDesc;
+ ACPI_PLD_INFO *PldInfo;
+ UINT8 *NewBuffer;
+ ACPI_STATUS Status;
+
+
+ /* Object must be of type Package with at least one Buffer element */
+
+ if (ObjDesc->Type != ACPI_TYPE_PACKAGE)
+ {
+ return;
+ }
+
+ BufferDesc = &ObjDesc->Package.Elements[0];
+ if (BufferDesc->Type != ACPI_TYPE_BUFFER)
+ {
+ return;
+ }
+
+ /* Convert _PLD buffer to local _PLD struct */
+
+ Status = AcpiDecodePldBuffer (BufferDesc->Buffer.Pointer,
+ BufferDesc->Buffer.Length, &PldInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Encode local _PLD struct back to a _PLD buffer */
+
+ NewBuffer = AcpiDbEncodePldBuffer (PldInfo);
+ if (!NewBuffer)
+ {
+ return;
+ }
+
+ /* The two bit-packed buffers should match */
+
+ if (memcmp (NewBuffer, BufferDesc->Buffer.Pointer,
+ BufferDesc->Buffer.Length))
+ {
+ AcpiOsPrintf ("Converted _PLD buffer does not compare. New:\n");
+
+ AcpiUtDumpBuffer (NewBuffer,
+ BufferDesc->Buffer.Length, DB_BYTE_DISPLAY, 0);
+ }
+
+ /* First 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Revision", PldInfo->Revision);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_IgnoreColor", PldInfo->IgnoreColor);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Red", PldInfo->Red);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Green", PldInfo->Green);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Blue", PldInfo->Blue);
+
+ /* Second 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Width", PldInfo->Width);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Height", PldInfo->Height);
+
+ /* Third 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_UserVisible", PldInfo->UserVisible);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Dock", PldInfo->Dock);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Lid", PldInfo->Lid);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Panel", PldInfo->Panel);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_VerticalPosition", PldInfo->VerticalPosition);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_HorizontalPosition", PldInfo->HorizontalPosition);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Shape", PldInfo->Shape);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_GroupOrientation", PldInfo->GroupOrientation);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_GroupToken", PldInfo->GroupToken);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_GroupPosition", PldInfo->GroupPosition);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Bay", PldInfo->Bay);
+
+ /* Fourth 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Ejectable", PldInfo->Ejectable);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_EjectRequired", PldInfo->OspmEjectRequired);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_CabinetNumber", PldInfo->CabinetNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_CardCageNumber", PldInfo->CardCageNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Reference", PldInfo->Reference);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Rotation", PldInfo->Rotation);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_Order", PldInfo->Order);
+
+ /* Fifth 32-bit dword */
+
+ if (BufferDesc->Buffer.Length > 16)
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_VerticalOffset", PldInfo->VerticalOffset);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);
+ }
+
+ ACPI_FREE (PldInfo);
+ ACPI_FREE (NewBuffer);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbdisply.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbdisply.c
new file mode 100644
index 0000000000..697cb21cef
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbdisply.c
@@ -0,0 +1,1201 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisply - debug display commands
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbdisply")
+
+/* Local prototypes */
+
+static void
+AcpiDbDumpParserDescriptor (
+ ACPI_PARSE_OBJECT *Op);
+
+static void *
+AcpiDbGetPointer (
+ void *Target);
+
+static ACPI_STATUS
+AcpiDbDisplayNonRootHandlers (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+/*
+ * System handler information.
+ * Used for Handlers command, in AcpiDbDisplayHandlers.
+ */
+#define ACPI_PREDEFINED_PREFIX "%25s (%.2X) : "
+#define ACPI_HANDLER_NAME_STRING "%30s : "
+#define ACPI_HANDLER_PRESENT_STRING "%-9s (%p)\n"
+#define ACPI_HANDLER_PRESENT_STRING2 "%-9s (%p)"
+#define ACPI_HANDLER_NOT_PRESENT_STRING "%-9s\n"
+
+/* All predefined Address Space IDs */
+
+static ACPI_ADR_SPACE_TYPE AcpiGbl_SpaceIdList[] =
+{
+ ACPI_ADR_SPACE_SYSTEM_MEMORY,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_ADR_SPACE_EC,
+ ACPI_ADR_SPACE_SMBUS,
+ ACPI_ADR_SPACE_CMOS,
+ ACPI_ADR_SPACE_PCI_BAR_TARGET,
+ ACPI_ADR_SPACE_IPMI,
+ ACPI_ADR_SPACE_GPIO,
+ ACPI_ADR_SPACE_GSBUS,
+ ACPI_ADR_SPACE_DATA_TABLE,
+ ACPI_ADR_SPACE_FIXED_HARDWARE
+};
+
+/* Global handler information */
+
+typedef struct acpi_handler_info
+{
+ void *Handler;
+ char *Name;
+
+} ACPI_HANDLER_INFO;
+
+static ACPI_HANDLER_INFO AcpiGbl_HandlerList[] =
+{
+ {&AcpiGbl_GlobalNotify[0].Handler, "System Notifications"},
+ {&AcpiGbl_GlobalNotify[1].Handler, "Device Notifications"},
+ {&AcpiGbl_TableHandler, "ACPI Table Events"},
+ {&AcpiGbl_ExceptionHandler, "Control Method Exceptions"},
+ {&AcpiGbl_InterfaceHandler, "OSI Invocations"}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetPointer
+ *
+ * PARAMETERS: Target - Pointer to string to be converted
+ *
+ * RETURN: Converted pointer
+ *
+ * DESCRIPTION: Convert an ascii pointer value to a real value
+ *
+ ******************************************************************************/
+
+static void *
+AcpiDbGetPointer (
+ void *Target)
+{
+ void *ObjPtr;
+ ACPI_SIZE Address;
+
+
+ Address = strtoul (Target, NULL, 16);
+ ObjPtr = ACPI_TO_POINTER (Address);
+ return (ObjPtr);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpParserDescriptor
+ *
+ * PARAMETERS: Op - A parser Op descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display a formatted parser object
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDumpParserDescriptor (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *Info;
+
+
+ Info = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ AcpiOsPrintf ("Parser Op Descriptor:\n");
+ AcpiOsPrintf ("%20.20s : %4.4X\n", "Opcode", Op->Common.AmlOpcode);
+
+ ACPI_DEBUG_ONLY_MEMBERS (AcpiOsPrintf ("%20.20s : %s\n", "Opcode Name",
+ Info->Name));
+
+ AcpiOsPrintf ("%20.20s : %p\n", "Value/ArgList", Op->Common.Value.Arg);
+ AcpiOsPrintf ("%20.20s : %p\n", "Parent", Op->Common.Parent);
+ AcpiOsPrintf ("%20.20s : %p\n", "NextOp", Op->Common.Next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeAndDisplayObject
+ *
+ * PARAMETERS: Target - String with object to be displayed. Names
+ * and hex pointers are supported.
+ * OutputType - Byte, Word, Dword, or Qword (B|W|D|Q)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display a formatted ACPI object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDecodeAndDisplayObject (
+ char *Target,
+ char *OutputType)
+{
+ void *ObjPtr;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 Display = DB_BYTE_DISPLAY;
+ char Buffer[80];
+ ACPI_BUFFER RetBuf;
+ ACPI_STATUS Status;
+ UINT32 Size;
+
+
+ if (!Target)
+ {
+ return;
+ }
+
+ /* Decode the output type */
+
+ if (OutputType)
+ {
+ AcpiUtStrupr (OutputType);
+ if (OutputType[0] == 'W')
+ {
+ Display = DB_WORD_DISPLAY;
+ }
+ else if (OutputType[0] == 'D')
+ {
+ Display = DB_DWORD_DISPLAY;
+ }
+ else if (OutputType[0] == 'Q')
+ {
+ Display = DB_QWORD_DISPLAY;
+ }
+ }
+
+ RetBuf.Length = sizeof (Buffer);
+ RetBuf.Pointer = Buffer;
+
+ /* Differentiate between a number and a name */
+
+ if ((Target[0] >= 0x30) && (Target[0] <= 0x39))
+ {
+ ObjPtr = AcpiDbGetPointer (Target);
+ if (!AcpiOsReadable (ObjPtr, 16))
+ {
+ AcpiOsPrintf (
+ "Address %p is invalid in this address space\n",
+ ObjPtr);
+ return;
+ }
+
+ /* Decode the object type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjPtr))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+
+ /* This is a namespace Node */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf (
+ "Cannot read entire Named object at address %p\n",
+ ObjPtr);
+ return;
+ }
+
+ Node = ObjPtr;
+ goto DumpNode;
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ /* This is a ACPI OPERAND OBJECT */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_OPERAND_OBJECT)))
+ {
+ AcpiOsPrintf (
+ "Cannot read entire ACPI object at address %p\n",
+ ObjPtr);
+ return;
+ }
+
+ AcpiUtDebugDumpBuffer (ObjPtr, sizeof (ACPI_OPERAND_OBJECT),
+ Display, ACPI_UINT32_MAX);
+ AcpiExDumpObjectDescriptor (ObjPtr, 1);
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+
+ /* This is a Parser Op object */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_PARSE_OBJECT)))
+ {
+ AcpiOsPrintf (
+ "Cannot read entire Parser object at address %p\n",
+ ObjPtr);
+ return;
+ }
+
+ AcpiUtDebugDumpBuffer (ObjPtr, sizeof (ACPI_PARSE_OBJECT),
+ Display, ACPI_UINT32_MAX);
+ AcpiDbDumpParserDescriptor ((ACPI_PARSE_OBJECT *) ObjPtr);
+ break;
+
+ default:
+
+ /* Is not a recognizeable object */
+
+ AcpiOsPrintf (
+ "Not a known ACPI internal object, descriptor type %2.2X\n",
+ ACPI_GET_DESCRIPTOR_TYPE (ObjPtr));
+
+ Size = 16;
+ if (AcpiOsReadable (ObjPtr, 64))
+ {
+ Size = 64;
+ }
+
+ /* Just dump some memory */
+
+ AcpiUtDebugDumpBuffer (ObjPtr, Size, Display, ACPI_UINT32_MAX);
+ break;
+ }
+
+ return;
+ }
+
+ /* The parameter is a name string that must be resolved to a Named obj */
+
+ Node = AcpiDbLocalNsLookup (Target);
+ if (!Node)
+ {
+ return;
+ }
+
+
+DumpNode:
+ /* Now dump the NS node */
+
+ Status = AcpiGetName (Node, ACPI_FULL_PATHNAME_NO_TRAILING, &RetBuf);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not convert name to pathname\n");
+ }
+
+ else
+ {
+ AcpiOsPrintf ("Object (%p) Pathname: %s\n",
+ Node, (char *) RetBuf.Pointer);
+ }
+
+ if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf ("Invalid Named object at address %p\n", Node);
+ return;
+ }
+
+ AcpiUtDebugDumpBuffer ((void *) Node, sizeof (ACPI_NAMESPACE_NODE),
+ Display, ACPI_UINT32_MAX);
+ AcpiExDumpNamespaceNode (Node, 1);
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ AcpiOsPrintf ("\nAttached Object (%p):\n", ObjDesc);
+ if (!AcpiOsReadable (ObjDesc, sizeof (ACPI_OPERAND_OBJECT)))
+ {
+ AcpiOsPrintf ("Invalid internal ACPI Object at address %p\n",
+ ObjDesc);
+ return;
+ }
+
+ AcpiUtDebugDumpBuffer ((void *) ObjDesc,
+ sizeof (ACPI_OPERAND_OBJECT), Display, ACPI_UINT32_MAX);
+ AcpiExDumpObjectDescriptor (ObjDesc, 1);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayMethodInfo
+ *
+ * PARAMETERS: StartOp - Root of the control method parse tree
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about the current method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayMethodInfo (
+ ACPI_PARSE_OBJECT *StartOp)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *RootOp;
+ ACPI_PARSE_OBJECT *Op;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 NumOps = 0;
+ UINT32 NumOperands = 0;
+ UINT32 NumOperators = 0;
+ UINT32 NumRemainingOps = 0;
+ UINT32 NumRemainingOperands = 0;
+ UINT32 NumRemainingOperators = 0;
+ BOOLEAN CountRemaining = FALSE;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ AcpiOsPrintf ("Currently executing control method is [%4.4s]\n",
+ AcpiUtGetNodeName (Node));
+ AcpiOsPrintf ("%X Arguments, SyncLevel = %X\n",
+ (UINT32) ObjDesc->Method.ParamCount,
+ (UINT32) ObjDesc->Method.SyncLevel);
+
+
+ RootOp = StartOp;
+ while (RootOp->Common.Parent)
+ {
+ RootOp = RootOp->Common.Parent;
+ }
+
+ Op = RootOp;
+
+ while (Op)
+ {
+ if (Op == StartOp)
+ {
+ CountRemaining = TRUE;
+ }
+
+ NumOps++;
+ if (CountRemaining)
+ {
+ NumRemainingOps++;
+ }
+
+ /* Decode the opcode */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ switch (OpInfo->Class)
+ {
+ case AML_CLASS_ARGUMENT:
+
+ if (CountRemaining)
+ {
+ NumRemainingOperands++;
+ }
+
+ NumOperands++;
+ break;
+
+ case AML_CLASS_UNKNOWN:
+
+ /* Bad opcode or ASCII character */
+
+ continue;
+
+ default:
+
+ if (CountRemaining)
+ {
+ NumRemainingOperators++;
+ }
+
+ NumOperators++;
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (StartOp, Op);
+ }
+
+ AcpiOsPrintf (
+ "Method contains: %X AML Opcodes - %X Operators, %X Operands\n",
+ NumOps, NumOperators, NumOperands);
+
+ AcpiOsPrintf (
+ "Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n",
+ NumRemainingOps, NumRemainingOperators, NumRemainingOperands);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayLocals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayLocals (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiDbDecodeLocals (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayArguments
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayArguments (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiDbDecodeArguments (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResults
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display current contents of a method result stack
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResults (
+ void)
+{
+ UINT32 i;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 ResultCount = 0;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GENERIC_STATE *Frame;
+ UINT32 Index; /* Index onto current frame */
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ if (WalkState->Results)
+ {
+ ResultCount = WalkState->ResultCount;
+ }
+
+ AcpiOsPrintf ("Method [%4.4s] has %X stacked result objects\n",
+ AcpiUtGetNodeName (Node), ResultCount);
+
+ /* From the top element of result stack */
+
+ Frame = WalkState->Results;
+ Index = (ResultCount - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
+
+ for (i = 0; i < ResultCount; i++)
+ {
+ ObjDesc = Frame->Results.ObjDesc[Index];
+ AcpiOsPrintf ("Result%u: ", i);
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+
+ if (Index == 0)
+ {
+ Frame = Frame->Results.Next;
+ Index = ACPI_RESULTS_FRAME_OBJ_NUM;
+ }
+
+ Index--;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayCallingTree
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display current calling tree of nested control methods
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayCallingTree (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ Node = WalkState->MethodNode;
+ AcpiOsPrintf ("Current Control Method Call Tree\n");
+
+ while (WalkState)
+ {
+ Node = WalkState->MethodNode;
+ AcpiOsPrintf (" [%4.4s]\n", AcpiUtGetNodeName (Node));
+
+ WalkState = WalkState->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayObjectType
+ *
+ * PARAMETERS: Name - User entered NS node handle or name
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display type of an arbitrary NS node
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayObjectType (
+ char *Name)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_DEVICE_INFO *Info;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ Node = AcpiDbConvertToNode (Name);
+ if (!Node)
+ {
+ return;
+ }
+
+ Status = AcpiGetObjectInfo (ACPI_CAST_PTR (ACPI_HANDLE, Node), &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get object info, %s\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ if (Info->Valid & ACPI_VALID_ADR)
+ {
+ AcpiOsPrintf ("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n",
+ ACPI_FORMAT_UINT64 (Info->Address),
+ Info->CurrentStatus, Info->Flags);
+ }
+ if (Info->Valid & ACPI_VALID_SXDS)
+ {
+ AcpiOsPrintf ("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
+ Info->HighestDstates[0], Info->HighestDstates[1],
+ Info->HighestDstates[2], Info->HighestDstates[3]);
+ }
+ if (Info->Valid & ACPI_VALID_SXWS)
+ {
+ AcpiOsPrintf ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
+ Info->LowestDstates[0], Info->LowestDstates[1],
+ Info->LowestDstates[2], Info->LowestDstates[3],
+ Info->LowestDstates[4]);
+ }
+
+ if (Info->Valid & ACPI_VALID_HID)
+ {
+ AcpiOsPrintf ("HID: %s\n", Info->HardwareId.String);
+ }
+
+ if (Info->Valid & ACPI_VALID_UID)
+ {
+ AcpiOsPrintf ("UID: %s\n", Info->UniqueId.String);
+ }
+
+ if (Info->Valid & ACPI_VALID_SUB)
+ {
+ AcpiOsPrintf ("SUB: %s\n", Info->SubsystemId.String);
+ }
+
+ if (Info->Valid & ACPI_VALID_CID)
+ {
+ for (i = 0; i < Info->CompatibleIdList.Count; i++)
+ {
+ AcpiOsPrintf ("CID %u: %s\n", i,
+ Info->CompatibleIdList.Ids[i].String);
+ }
+ }
+
+ ACPI_FREE (Info);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResultObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ * Note: Curently only displays the result object if we are single stepping.
+ * However, this output may be useful in other contexts and could be enabled
+ * to do so if needed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResultObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ /* Only display if single stepping */
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("ResultObj: ");
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayArgumentObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayArgumentObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("ArgObj: ");
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the current GPE structures
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayGpes (
+ void)
+{
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ char *GpeType;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ UINT32 GpeIndex;
+ UINT32 Block = 0;
+ UINT32 i;
+ UINT32 j;
+ UINT32 Count;
+ char Buffer[80];
+ ACPI_BUFFER RetBuf;
+ ACPI_STATUS Status;
+
+
+ RetBuf.Length = sizeof (Buffer);
+ RetBuf.Pointer = Buffer;
+
+ Block = 0;
+
+ /* Walk the GPE lists */
+
+ GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+ while (GpeXruptInfo)
+ {
+ GpeBlock = GpeXruptInfo->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ Status = AcpiGetName (GpeBlock->Node,
+ ACPI_FULL_PATHNAME_NO_TRAILING, &RetBuf);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not convert name to pathname\n");
+ }
+
+ if (GpeBlock->Node == AcpiGbl_FadtGpeDevice)
+ {
+ GpeType = "FADT-defined GPE block";
+ }
+ else
+ {
+ GpeType = "GPE Block Device";
+ }
+
+ AcpiOsPrintf (
+ "\nBlock %u - Info %p DeviceNode %p [%s] - %s\n",
+ Block, GpeBlock, GpeBlock->Node, Buffer, GpeType);
+
+ AcpiOsPrintf (
+ " Registers: %u (%u GPEs)\n",
+ GpeBlock->RegisterCount, GpeBlock->GpeCount);
+
+ AcpiOsPrintf (
+ " GPE range: 0x%X to 0x%X on interrupt %u\n",
+ GpeBlock->BlockBaseNumber,
+ GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
+ GpeXruptInfo->InterruptNumber);
+
+ AcpiOsPrintf (
+ " RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ GpeBlock->RegisterInfo,
+ ACPI_FORMAT_UINT64 (
+ GpeBlock->RegisterInfo->StatusAddress.Address),
+ ACPI_FORMAT_UINT64 (
+ GpeBlock->RegisterInfo->EnableAddress.Address));
+
+ AcpiOsPrintf (" EventInfo: %p\n", GpeBlock->EventInfo);
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
+
+ AcpiOsPrintf (
+ " Reg %u: (GPE %.2X-%.2X) "
+ "RunEnable %2.2X WakeEnable %2.2X"
+ " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ i, GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber +
+ (ACPI_GPE_REGISTER_WIDTH - 1),
+ GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake,
+ ACPI_FORMAT_UINT64 (
+ GpeRegisterInfo->StatusAddress.Address),
+ ACPI_FORMAT_UINT64 (
+ GpeRegisterInfo->EnableAddress.Address));
+
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+ GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
+
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ /* This GPE is not used (no method or handler), ignore it */
+
+ continue;
+ }
+
+ AcpiOsPrintf (
+ " GPE %.2X: %p RunRefs %2.2X Flags %2.2X (",
+ GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
+ GpeEventInfo->RuntimeCount, GpeEventInfo->Flags);
+
+ /* Decode the flags byte */
+
+ if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
+ {
+ AcpiOsPrintf ("Level, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("Edge, ");
+ }
+
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
+ {
+ AcpiOsPrintf ("CanWake, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("RunOnly, ");
+ }
+
+ switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
+ {
+ case ACPI_GPE_DISPATCH_NONE:
+
+ AcpiOsPrintf ("NotUsed");
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+
+ AcpiOsPrintf ("Method");
+ break;
+
+ case ACPI_GPE_DISPATCH_HANDLER:
+
+ AcpiOsPrintf ("Handler");
+ break;
+
+ case ACPI_GPE_DISPATCH_NOTIFY:
+
+ Count = 0;
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
+ {
+ Count++;
+ Notify = Notify->Next;
+ }
+
+ AcpiOsPrintf ("Implicit Notify on %u devices",
+ Count);
+ break;
+
+ case ACPI_GPE_DISPATCH_RAW_HANDLER:
+
+ AcpiOsPrintf ("RawHandler");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("UNKNOWN: %X",
+ ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags));
+ break;
+ }
+
+ AcpiOsPrintf (")\n");
+ }
+ }
+
+ Block++;
+ GpeBlock = GpeBlock->Next;
+ }
+
+ GpeXruptInfo = GpeXruptInfo->Next;
+ }
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHandlers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the currently installed global handlers
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayHandlers (
+ void)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_ADR_SPACE_TYPE SpaceId;
+ UINT32 i;
+
+
+ /* Operation region handlers */
+
+ AcpiOsPrintf ("\nOperation Region Handlers at the namespace root:\n");
+
+ ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
+ if (ObjDesc)
+ {
+ for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiGbl_SpaceIdList); i++)
+ {
+ SpaceId = AcpiGbl_SpaceIdList[i];
+ HandlerObj = ObjDesc->Device.Handler;
+
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,
+ AcpiUtGetRegionName ((UINT8) SpaceId), SpaceId);
+
+ while (HandlerObj)
+ {
+ if (AcpiGbl_SpaceIdList[i] ==
+ HandlerObj->AddressSpace.SpaceId)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING,
+ (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ?
+ "Default" : "User",
+ HandlerObj->AddressSpace.Handler);
+
+ goto FoundHandler;
+ }
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+
+ /* There is no handler for this SpaceId */
+
+ AcpiOsPrintf ("None\n");
+
+ FoundHandler:;
+ }
+
+ /* Find all handlers for user-defined SpaceIDs */
+
+ HandlerObj = ObjDesc->Device.Handler;
+ while (HandlerObj)
+ {
+ if (HandlerObj->AddressSpace.SpaceId >= ACPI_USER_REGION_BEGIN)
+ {
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,
+ "User-defined ID", HandlerObj->AddressSpace.SpaceId);
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING,
+ (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ?
+ "Default" : "User",
+ HandlerObj->AddressSpace.Handler);
+ }
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* Fixed event handlers */
+
+ AcpiOsPrintf ("\nFixed Event Handlers:\n");
+
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX, AcpiUtGetEventName (i), i);
+ if (AcpiGbl_FixedEventHandlers[i].Handler)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, "User",
+ AcpiGbl_FixedEventHandlers[i].Handler);
+ }
+ else
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+ }
+ }
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /* Miscellaneous global handlers */
+
+ AcpiOsPrintf ("\nMiscellaneous Global Handlers:\n");
+
+ for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiGbl_HandlerList); i++)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NAME_STRING,
+ AcpiGbl_HandlerList[i].Name);
+
+ if (AcpiGbl_HandlerList[i].Handler)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, "User",
+ AcpiGbl_HandlerList[i].Handler);
+ }
+ else
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+ }
+ }
+
+
+ /* Other handlers that are installed throughout the namespace */
+
+ AcpiOsPrintf ("\nOperation Region Handlers for specific devices:\n");
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbDisplayNonRootHandlers,
+ NULL, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayNonRootHandlers
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display information about all handlers installed for a
+ * device object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbDisplayNonRootHandlers (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ char *Pathname;
+
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ /* Display all handlers associated with this device */
+
+ HandlerObj = ObjDesc->Device.Handler;
+ while (HandlerObj)
+ {
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,
+ AcpiUtGetRegionName ((UINT8) HandlerObj->AddressSpace.SpaceId),
+ HandlerObj->AddressSpace.SpaceId);
+
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING2,
+ (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User",
+ HandlerObj->AddressSpace.Handler);
+
+ AcpiOsPrintf (" Device Name: %s (%p)\n", Pathname, Node);
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+
+ ACPI_FREE (Pathname);
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbexec.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbexec.c
new file mode 100644
index 0000000000..c4bcbb4a00
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbexec.c
@@ -0,0 +1,827 @@
+/*******************************************************************************
+ *
+ * Module Name: dbexec - debugger control method execution
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbexec")
+
+
+static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo;
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbExecuteMethod (
+ ACPI_DB_METHOD_INFO *Info,
+ ACPI_BUFFER *ReturnObj);
+
+static ACPI_STATUS
+AcpiDbExecuteSetup (
+ ACPI_DB_METHOD_INFO *Info);
+
+static UINT32
+AcpiDbGetOutstandingAllocations (
+ void);
+
+static void ACPI_SYSTEM_XFACE
+AcpiDbMethodThread (
+ void *Context);
+
+static ACPI_STATUS
+AcpiDbExecutionWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDeleteObjects
+ *
+ * PARAMETERS: Count - Count of objects in the list
+ * Objects - Array of ACPI_OBJECTs to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
+ * packages via recursion.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDeleteObjects (
+ UINT32 Count,
+ ACPI_OBJECT *Objects)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < Count; i++)
+ {
+ switch (Objects[i].Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ ACPI_FREE (Objects[i].Buffer.Pointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ /* Recursive call to delete package elements */
+
+ AcpiDbDeleteObjects (Objects[i].Package.Count,
+ Objects[i].Package.Elements);
+
+ /* Free the elements array */
+
+ ACPI_FREE (Objects[i].Package.Elements);
+ break;
+
+ default:
+
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteMethod
+ *
+ * PARAMETERS: Info - Valid info segment
+ * ReturnObj - Where to put return object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbExecuteMethod (
+ ACPI_DB_METHOD_INFO *Info,
+ ACPI_BUFFER *ReturnObj)
+{
+ ACPI_STATUS Status;
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[ACPI_DEBUGGER_MAX_ARGS + 1];
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (DbExecuteMethod);
+
+
+ if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
+ {
+ AcpiOsPrintf ("Warning: debug output is not enabled!\n");
+ }
+
+ ParamObjects.Count = 0;
+ ParamObjects.Pointer = NULL;
+
+ /* Pass through any command-line arguments */
+
+ if (Info->Args && Info->Args[0])
+ {
+ /* Get arguments passed on the command line */
+
+ for (i = 0; (Info->Args[i] && *(Info->Args[i])); i++)
+ {
+ /* Convert input string (token) to an actual ACPI_OBJECT */
+
+ Status = AcpiDbConvertToObject (Info->Types[i],
+ Info->Args[i], &Params[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While parsing method arguments"));
+ goto Cleanup;
+ }
+ }
+
+ ParamObjects.Count = i;
+ ParamObjects.Pointer = Params;
+ }
+
+ /* Prepare for a return object of arbitrary size */
+
+ ReturnObj->Pointer = AcpiGbl_DbBuffer;
+ ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ /* Do the actual method execution */
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AcpiEvaluateObject (NULL, Info->Pathname,
+ &ParamObjects, ReturnObj);
+
+ AcpiGbl_CmSingleStep = FALSE;
+ AcpiGbl_MethodExecuting = FALSE;
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while executing %s from debugger", Info->Pathname));
+
+ if (Status == AE_BUFFER_OVERFLOW)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Possible overflow of internal debugger "
+ "buffer (size 0x%X needed 0x%X)",
+ ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
+ }
+ }
+
+Cleanup:
+ AcpiDbDeleteObjects (ParamObjects.Count, Params);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteSetup
+ *
+ * PARAMETERS: Info - Valid method info
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Setup info segment prior to method execution
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbExecuteSetup (
+ ACPI_DB_METHOD_INFO *Info)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (DbExecuteSetup);
+
+
+ /* Catenate the current scope to the supplied name */
+
+ Info->Pathname[0] = 0;
+ if ((Info->Name[0] != '\\') &&
+ (Info->Name[0] != '/'))
+ {
+ if (AcpiUtSafeStrcat (Info->Pathname, sizeof (Info->Pathname),
+ AcpiGbl_DbScopeBuf))
+ {
+ Status = AE_BUFFER_OVERFLOW;
+ goto ErrorExit;
+ }
+ }
+
+ if (AcpiUtSafeStrcat (Info->Pathname, sizeof (Info->Pathname),
+ Info->Name))
+ {
+ Status = AE_BUFFER_OVERFLOW;
+ goto ErrorExit;
+ }
+
+ AcpiDbPrepNamestring (Info->Pathname);
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("Evaluating %s\n", Info->Pathname);
+
+ if (Info->Flags & EX_SINGLE_STEP)
+ {
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ }
+
+ else
+ {
+ /* No single step, allow redirection to a file */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ }
+
+ return (AE_OK);
+
+ErrorExit:
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "During setup for method execution"));
+ return (Status);
+}
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+UINT32
+AcpiDbGetCacheInfo (
+ ACPI_MEMORY_LIST *Cache)
+{
+
+ return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetOutstandingAllocations
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Current global allocation count minus cache entries
+ *
+ * DESCRIPTION: Determine the current number of "outstanding" allocations --
+ * those allocations that have not been freed and also are not
+ * in one of the various object caches.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbGetOutstandingAllocations (
+ void)
+{
+ UINT32 Outstanding = 0;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache);
+#endif
+
+ return (Outstanding);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecutionWalk
+ *
+ * PARAMETERS: WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ * scope.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbExecutionWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc->Method.ParamCount)
+ {
+ return (AE_OK);
+ }
+
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ AcpiNsPrintNodePathname (Node, "Evaluating");
+
+ /* Do the actual method execution */
+
+ AcpiOsPrintf ("\n");
+ AcpiGbl_MethodExecuting = TRUE;
+
+ Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj);
+
+ AcpiOsPrintf ("Evaluation of [%4.4s] returned %s\n",
+ AcpiUtGetNodeName (Node),
+ AcpiFormatException (Status));
+
+ AcpiGbl_MethodExecuting = FALSE;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecute
+ *
+ * PARAMETERS: Name - Name of method to execute
+ * Args - Parameters to the method
+ * Types -
+ * Flags - single step/no single step
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ * scope.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbExecute (
+ char *Name,
+ char **Args,
+ ACPI_OBJECT_TYPE *Types,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnObj;
+ char *NameString;
+
+#ifdef ACPI_DEBUG_OUTPUT
+ UINT32 PreviousAllocations;
+ UINT32 Allocations;
+
+
+ /* Memory allocation tracking */
+
+ PreviousAllocations = AcpiDbGetOutstandingAllocations ();
+#endif
+
+ if (*Name == '*')
+ {
+ (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
+ return;
+ }
+ else
+ {
+ NameString = ACPI_ALLOCATE (strlen (Name) + 1);
+ if (!NameString)
+ {
+ return;
+ }
+
+ memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+
+ strcpy (NameString, Name);
+ AcpiUtStrupr (NameString);
+ AcpiGbl_DbMethodInfo.Name = NameString;
+ AcpiGbl_DbMethodInfo.Args = Args;
+ AcpiGbl_DbMethodInfo.Types = Types;
+ AcpiGbl_DbMethodInfo.Flags = Flags;
+
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (NameString);
+ return;
+ }
+
+ /* Get the NS node, determines existence also */
+
+ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
+ &AcpiGbl_DbMethodInfo.Method);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo,
+ &ReturnObj);
+ }
+ ACPI_FREE (NameString);
+ }
+
+ /*
+ * Allow any handlers in separate threads to complete.
+ * (Such as Notify handlers invoked from AML executed above).
+ */
+ AcpiOsSleep ((UINT64) 10);
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+ /* Memory allocation tracking */
+
+ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+
+ if (Allocations > 0)
+ {
+ AcpiOsPrintf (
+ "0x%X Outstanding allocations after evaluation of %s\n",
+ Allocations, AcpiGbl_DbMethodInfo.Pathname);
+ }
+#endif
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Evaluation of %s failed with status %s\n",
+ AcpiGbl_DbMethodInfo.Pathname,
+ AcpiFormatException (Status));
+ }
+ else
+ {
+ /* Display a return object, if any */
+
+ if (ReturnObj.Length)
+ {
+ AcpiOsPrintf (
+ "Evaluation of %s returned object %p, "
+ "external buffer length %X\n",
+ AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
+ (UINT32) ReturnObj.Length);
+
+ AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
+
+ /* Dump a _PLD buffer if present */
+
+ if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ AcpiGbl_DbMethodInfo.Method)->Name.Ascii),
+ METHOD_NAME__PLD))
+ {
+ AcpiDbDumpPldBuffer (ReturnObj.Pointer);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("No object was returned from evaluation of %s\n",
+ AcpiGbl_DbMethodInfo.Pathname);
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMethodThread
+ *
+ * PARAMETERS: Context - Execution info segment
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiDbMethodThread (
+ void *Context)
+{
+ ACPI_STATUS Status;
+ ACPI_DB_METHOD_INFO *Info = Context;
+ ACPI_DB_METHOD_INFO LocalInfo;
+ UINT32 i;
+ UINT8 Allow;
+ ACPI_BUFFER ReturnObj;
+
+
+ /*
+ * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
+ * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
+ * concurrently.
+ *
+ * Note: The arguments we are passing are used by the ASL test suite
+ * (aslts). Do not change them without updating the tests.
+ */
+ (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
+
+ if (Info->InitArgs)
+ {
+ AcpiDbUint32ToHexString (Info->NumCreated,
+ Info->IndexOfThreadStr);
+ AcpiDbUint32ToHexString ((UINT32) AcpiOsGetThreadId (),
+ Info->IdOfThreadStr);
+ }
+
+ if (Info->Threads && (Info->NumCreated < Info->NumThreads))
+ {
+ Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
+ }
+
+ LocalInfo = *Info;
+ LocalInfo.Args = LocalInfo.Arguments;
+ LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
+ LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
+ LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
+ LocalInfo.Arguments[3] = NULL;
+
+ LocalInfo.Types = LocalInfo.ArgTypes;
+
+ (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
+
+ for (i = 0; i < Info->NumLoops; i++)
+ {
+ Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s During evaluation of %s at iteration %X\n",
+ AcpiFormatException (Status), Info->Pathname, i);
+ if (Status == AE_ABORT_METHOD)
+ {
+ break;
+ }
+ }
+
+#if 0
+ if ((i % 100) == 0)
+ {
+ AcpiOsPrintf ("%u loops, Thread 0x%x\n",
+ i, AcpiOsGetThreadId ());
+ }
+
+ if (ReturnObj.Length)
+ {
+ AcpiOsPrintf ("Evaluation of %s returned object %p Buflen %X\n",
+ Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
+ AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
+ }
+#endif
+ }
+
+ /* Signal our completion */
+
+ Allow = 0;
+ (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate,
+ 1, ACPI_WAIT_FOREVER);
+ Info->NumCompleted++;
+
+ if (Info->NumCompleted == Info->NumThreads)
+ {
+ /* Do signal for main thread once only */
+ Allow = 1;
+ }
+
+ (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
+
+ if (Allow)
+ {
+ Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf (
+ "Could not signal debugger thread sync semaphore, %s\n",
+ AcpiFormatException (Status));
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCreateExecutionThreads
+ *
+ * PARAMETERS: NumThreadsArg - Number of threads to create
+ * NumLoopsArg - Loop count for the thread(s)
+ * MethodNameArg - Control method to execute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create threads to execute method(s)
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCreateExecutionThreads (
+ char *NumThreadsArg,
+ char *NumLoopsArg,
+ char *MethodNameArg)
+{
+ ACPI_STATUS Status;
+ UINT32 NumThreads;
+ UINT32 NumLoops;
+ UINT32 i;
+ UINT32 Size;
+ ACPI_MUTEX MainThreadGate;
+ ACPI_MUTEX ThreadCompleteGate;
+ ACPI_MUTEX InfoGate;
+
+
+ /* Get the arguments */
+
+ NumThreads = strtoul (NumThreadsArg, NULL, 0);
+ NumLoops = strtoul (NumLoopsArg, NULL, 0);
+
+ if (!NumThreads || !NumLoops)
+ {
+ AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
+ NumThreads, NumLoops);
+ return;
+ }
+
+ /*
+ * Create the semaphore for synchronization of
+ * the created threads with the main thread.
+ */
+ Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for "
+ "synchronization with the main thread, %s\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ /*
+ * Create the semaphore for synchronization
+ * between the created threads.
+ */
+ Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for "
+ "synchronization between the created threads, %s\n",
+ AcpiFormatException (Status));
+
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ return;
+ }
+
+ Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for "
+ "synchronization of AcpiGbl_DbMethodInfo, %s\n",
+ AcpiFormatException (Status));
+
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ return;
+ }
+
+ memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+
+ /* Array to store IDs of threads */
+
+ AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
+ Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
+
+ AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
+ if (AcpiGbl_DbMethodInfo.Threads == NULL)
+ {
+ AcpiOsPrintf ("No memory for thread IDs array\n");
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (InfoGate);
+ return;
+ }
+ memset (AcpiGbl_DbMethodInfo.Threads, 0, Size);
+
+ /* Setup the context to be passed to each thread */
+
+ AcpiGbl_DbMethodInfo.Name = MethodNameArg;
+ AcpiGbl_DbMethodInfo.Flags = 0;
+ AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
+ AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
+ AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
+ AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
+
+ /* Init arguments to be passed to method */
+
+ AcpiGbl_DbMethodInfo.InitArgs = 1;
+ AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
+ AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
+ AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
+ AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
+ AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
+
+ AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
+ AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER;
+ AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
+ AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
+
+ AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
+
+ Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ goto CleanupAndExit;
+ }
+
+ /* Get the NS node, determines existence also */
+
+ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
+ &AcpiGbl_DbMethodInfo.Method);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s Could not get handle for %s\n",
+ AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname);
+ goto CleanupAndExit;
+ }
+
+ /* Create the threads */
+
+ AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
+ NumThreads, NumLoops);
+
+ for (i = 0; i < (NumThreads); i++)
+ {
+ Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
+ &AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+
+ /* Wait for all threads to complete */
+
+ (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+CleanupAndExit:
+
+ /* Cleanup and exit */
+
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (InfoGate);
+
+ AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
+ AcpiGbl_DbMethodInfo.Threads = NULL;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbfileio.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbfileio.c
new file mode 100644
index 0000000000..ff9c870e36
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbfileio.c
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ *
+ * Module Name: dbfileio - Debugger file I/O commands. These can't usually
+ * be used when running the debugger in Ring 0 (Kernel mode)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbfileio")
+
+
+#ifdef ACPI_DEBUGGER
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCloseDebugFile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If open, close the current debug output file
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCloseDebugFile (
+ void)
+{
+
+#ifdef ACPI_APPLICATION
+
+ if (AcpiGbl_DebugFile)
+ {
+ fclose (AcpiGbl_DebugFile);
+ AcpiGbl_DebugFile = NULL;
+ AcpiGbl_DbOutputToFile = FALSE;
+ AcpiOsPrintf ("Debug output file %s closed\n",
+ AcpiGbl_DbDebugFilename);
+ }
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbOpenDebugFile
+ *
+ * PARAMETERS: Name - Filename to open
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Open a file where debug output will be directed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbOpenDebugFile (
+ char *Name)
+{
+
+#ifdef ACPI_APPLICATION
+
+ AcpiDbCloseDebugFile ();
+ AcpiGbl_DebugFile = fopen (Name, "w+");
+ if (!AcpiGbl_DebugFile)
+ {
+ AcpiOsPrintf ("Could not open debug file %s\n", Name);
+ return;
+ }
+
+ AcpiOsPrintf ("Debug output file %s opened\n", Name);
+ strncpy (AcpiGbl_DbDebugFilename, Name,
+ sizeof (AcpiGbl_DbDebugFilename));
+ AcpiGbl_DbOutputToFile = TRUE;
+
+#endif
+}
+#endif
+
+
+#ifdef ACPI_APPLICATION
+#include <contrib/dev/acpica/include/acapps.h>
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeLocalLoadTable
+ *
+ * PARAMETERS: Table - pointer to a buffer containing the entire
+ * table to be loaded
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ * buffer. The buffer must contain an entire ACPI Table including
+ * a valid header. The header fields will be verified, and if it
+ * is determined that the table is invalid, the call will fail.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AeLocalLoadTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AeLocalLoadTable);
+
+#if 0
+/* ACPI_TABLE_DESC TableInfo; */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ TableInfo.Pointer = Table;
+ Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the new table into the local data structures */
+
+ Status = AcpiTbInitTableDescriptor (&TableInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ /* Table already exists, no error */
+
+ Status = AE_OK;
+ }
+
+ /* Free table allocated by AcpiTbGetTable */
+
+ AcpiTbDeleteSingleTable (&TableInfo);
+ return_ACPI_STATUS (Status);
+ }
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+ Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Uninstall table and free the buffer */
+
+ AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
+ return_ACPI_STATUS (Status);
+ }
+#endif
+#endif
+
+ return_ACPI_STATUS (Status);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetTableFromFile
+ *
+ * PARAMETERS: Filename - File where table is located
+ * ReturnTable - Where a pointer to the table is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load an ACPI table from a file
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbGetTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **ReturnTable,
+ BOOLEAN MustBeAmlFile)
+{
+#ifdef ACPI_APPLICATION
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER *Table;
+ BOOLEAN IsAmlTable = TRUE;
+
+
+ Status = AcpiUtReadTableFromFile (Filename, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (MustBeAmlFile)
+ {
+ IsAmlTable = AcpiUtIsAmlTable (Table);
+ if (!IsAmlTable)
+ {
+ ACPI_EXCEPTION ((AE_INFO, AE_OK,
+ "Input for -e is not an AML table: "
+ "\"%4.4s\" (must be DSDT/SSDT)",
+ Table->Signature));
+ return (AE_TYPE);
+ }
+ }
+
+ if (IsAmlTable)
+ {
+ /* Attempt to recognize and install the table */
+
+ Status = AeLocalLoadTable (Table);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ AcpiOsPrintf ("Table %4.4s is already installed\n",
+ Table->Signature);
+ }
+ else
+ {
+ AcpiOsPrintf ("Could not install table, %s\n",
+ AcpiFormatException (Status));
+ }
+
+ return (Status);
+ }
+
+ AcpiTbPrintTableHeader (0, Table);
+
+ fprintf (stderr,
+ "Acpi table [%4.4s] successfully installed and loaded\n",
+ Table->Signature);
+ }
+
+ AcpiGbl_AcpiHardwarePresent = FALSE;
+ if (ReturnTable)
+ {
+ *ReturnTable = Table;
+ }
+
+
+#endif /* ACPI_APPLICATION */
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbhistry.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbhistry.c
new file mode 100644
index 0000000000..2d602d1c0c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbhistry.c
@@ -0,0 +1,271 @@
+/******************************************************************************
+ *
+ * Module Name: dbhistry - debugger HISTORY command
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbhistry")
+
+
+#define HI_NO_HISTORY 0
+#define HI_RECORD_HISTORY 1
+#define HISTORY_SIZE 40
+
+
+typedef struct HistoryInfo
+{
+ char *Command;
+ UINT32 CmdNum;
+
+} HISTORY_INFO;
+
+
+static HISTORY_INFO AcpiGbl_HistoryBuffer[HISTORY_SIZE];
+static UINT16 AcpiGbl_LoHistory = 0;
+static UINT16 AcpiGbl_NumHistory = 0;
+static UINT16 AcpiGbl_NextHistoryIndex = 0;
+UINT32 AcpiGbl_NextCmdNum = 1;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbAddToHistory
+ *
+ * PARAMETERS: CommandLine - Command to add
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a command line to the history buffer.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbAddToHistory (
+ char *CommandLine)
+{
+ UINT16 CmdLen;
+ UINT16 BufferLen;
+
+ /* Put command into the next available slot */
+
+ CmdLen = (UINT16) strlen (CommandLine);
+ if (!CmdLen)
+ {
+ return;
+ }
+
+ if (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command != NULL)
+ {
+ BufferLen = (UINT16) strlen (
+ AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command);
+
+ if (CmdLen > BufferLen)
+ {
+ AcpiOsFree (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].
+ Command);
+ AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command =
+ AcpiOsAllocate (CmdLen + 1);
+ }
+ }
+ else
+ {
+ AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command =
+ AcpiOsAllocate (CmdLen + 1);
+ }
+
+ strcpy (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
+ CommandLine);
+
+ AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum =
+ AcpiGbl_NextCmdNum;
+
+ /* Adjust indexes */
+
+ if ((AcpiGbl_NumHistory == HISTORY_SIZE) &&
+ (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory))
+ {
+ AcpiGbl_LoHistory++;
+ if (AcpiGbl_LoHistory >= HISTORY_SIZE)
+ {
+ AcpiGbl_LoHistory = 0;
+ }
+ }
+
+ AcpiGbl_NextHistoryIndex++;
+ if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE)
+ {
+ AcpiGbl_NextHistoryIndex = 0;
+ }
+
+ AcpiGbl_NextCmdNum++;
+ if (AcpiGbl_NumHistory < HISTORY_SIZE)
+ {
+ AcpiGbl_NumHistory++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHistory
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the contents of the history buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayHistory (
+ void)
+{
+ UINT32 i;
+ UINT16 HistoryIndex;
+
+
+ HistoryIndex = AcpiGbl_LoHistory;
+
+ /* Dump entire history buffer */
+
+ for (i = 0; i < AcpiGbl_NumHistory; i++)
+ {
+ if (AcpiGbl_HistoryBuffer[HistoryIndex].Command)
+ {
+ AcpiOsPrintf ("%3ld %s\n",
+ AcpiGbl_HistoryBuffer[HistoryIndex].CmdNum,
+ AcpiGbl_HistoryBuffer[HistoryIndex].Command);
+ }
+
+ HistoryIndex++;
+ if (HistoryIndex >= HISTORY_SIZE)
+ {
+ HistoryIndex = 0;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetFromHistory
+ *
+ * PARAMETERS: CommandNumArg - String containing the number of the
+ * command to be retrieved
+ *
+ * RETURN: Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *
+AcpiDbGetFromHistory (
+ char *CommandNumArg)
+{
+ UINT32 CmdNum;
+
+
+ if (CommandNumArg == NULL)
+ {
+ CmdNum = AcpiGbl_NextCmdNum - 1;
+ }
+
+ else
+ {
+ CmdNum = strtoul (CommandNumArg, NULL, 0);
+ }
+
+ return (AcpiDbGetHistoryByIndex (CmdNum));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetHistoryByIndex
+ *
+ * PARAMETERS: CmdNum - Index of the desired history entry.
+ * Values are 0...(AcpiGbl_NextCmdNum - 1)
+ *
+ * RETURN: Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *
+AcpiDbGetHistoryByIndex (
+ UINT32 CmdNum)
+{
+ UINT32 i;
+ UINT16 HistoryIndex;
+
+
+ /* Search history buffer */
+
+ HistoryIndex = AcpiGbl_LoHistory;
+ for (i = 0; i < AcpiGbl_NumHistory; i++)
+ {
+ if (AcpiGbl_HistoryBuffer[HistoryIndex].CmdNum == CmdNum)
+ {
+ /* Found the command, return it */
+
+ return (AcpiGbl_HistoryBuffer[HistoryIndex].Command);
+ }
+
+ /* History buffer is circular */
+
+ HistoryIndex++;
+ if (HistoryIndex >= HISTORY_SIZE)
+ {
+ HistoryIndex = 0;
+ }
+ }
+
+ AcpiOsPrintf ("Invalid history number: %u\n", HistoryIndex);
+ return (NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbinput.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbinput.c
new file mode 100644
index 0000000000..447f5d208a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbinput.c
@@ -0,0 +1,1365 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbinput")
+
+
+/* Local prototypes */
+
+static UINT32
+AcpiDbGetLine (
+ char *InputBuffer);
+
+static UINT32
+AcpiDbMatchCommand (
+ char *UserCommand);
+
+static void
+AcpiDbSingleThread (
+ void);
+
+static void
+AcpiDbDisplayCommandInfo (
+ char *Command,
+ BOOLEAN DisplayAll);
+
+static void
+AcpiDbDisplayHelp (
+ char *Command);
+
+static BOOLEAN
+AcpiDbMatchCommandHelp (
+ char *Command,
+ const ACPI_DB_COMMAND_HELP *Help);
+
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+enum AcpiExDebuggerCommands
+{
+ CMD_NOT_FOUND = 0,
+ CMD_NULL,
+ CMD_ALLOCATIONS,
+ CMD_ARGS,
+ CMD_ARGUMENTS,
+ CMD_BREAKPOINT,
+ CMD_BUSINFO,
+ CMD_CALL,
+ CMD_DEBUG,
+ CMD_DISASSEMBLE,
+ CMD_DISASM,
+ CMD_DUMP,
+ CMD_EVALUATE,
+ CMD_EXECUTE,
+ CMD_EXIT,
+ CMD_FIND,
+ CMD_GO,
+ CMD_HANDLERS,
+ CMD_HELP,
+ CMD_HELP2,
+ CMD_HISTORY,
+ CMD_HISTORY_EXE,
+ CMD_HISTORY_LAST,
+ CMD_INFORMATION,
+ CMD_INTEGRITY,
+ CMD_INTO,
+ CMD_LEVEL,
+ CMD_LIST,
+ CMD_LOCALS,
+ CMD_LOCKS,
+ CMD_METHODS,
+ CMD_NAMESPACE,
+ CMD_NOTIFY,
+ CMD_OBJECTS,
+ CMD_OSI,
+ CMD_OWNER,
+ CMD_PATHS,
+ CMD_PREFIX,
+ CMD_QUIT,
+ CMD_REFERENCES,
+ CMD_RESOURCES,
+ CMD_RESULTS,
+ CMD_SET,
+ CMD_STATS,
+ CMD_STOP,
+ CMD_TABLES,
+ CMD_TEMPLATE,
+ CMD_TRACE,
+ CMD_TREE,
+ CMD_TYPE,
+#ifdef ACPI_APPLICATION
+ CMD_ENABLEACPI,
+ CMD_EVENT,
+ CMD_GPE,
+ CMD_GPES,
+ CMD_SCI,
+ CMD_SLEEP,
+
+ CMD_CLOSE,
+ CMD_LOAD,
+ CMD_OPEN,
+ CMD_UNLOAD,
+
+ CMD_TERMINATE,
+ CMD_THREADS,
+
+ CMD_PREDEFINED,
+ CMD_TEST,
+#endif
+};
+
+#define CMD_FIRST_VALID 2
+
+
+/* Second parameter is the required argument count */
+
+static const ACPI_DB_COMMAND_INFO AcpiGbl_DbCommands[] =
+{
+ {"<NOT FOUND>", 0},
+ {"<NULL>", 0},
+ {"ALLOCATIONS", 0},
+ {"ARGS", 0},
+ {"ARGUMENTS", 0},
+ {"BREAKPOINT", 1},
+ {"BUSINFO", 0},
+ {"CALL", 0},
+ {"DEBUG", 1},
+ {"DISASSEMBLE", 1},
+ {"DISASM", 1},
+ {"DUMP", 1},
+ {"EVALUATE", 1},
+ {"EXECUTE", 1},
+ {"EXIT", 0},
+ {"FIND", 1},
+ {"GO", 0},
+ {"HANDLERS", 0},
+ {"HELP", 0},
+ {"?", 0},
+ {"HISTORY", 0},
+ {"!", 1},
+ {"!!", 0},
+ {"INFORMATION", 0},
+ {"INTEGRITY", 0},
+ {"INTO", 0},
+ {"LEVEL", 0},
+ {"LIST", 0},
+ {"LOCALS", 0},
+ {"LOCKS", 0},
+ {"METHODS", 0},
+ {"NAMESPACE", 0},
+ {"NOTIFY", 2},
+ {"OBJECTS", 0},
+ {"OSI", 0},
+ {"OWNER", 1},
+ {"PATHS", 0},
+ {"PREFIX", 0},
+ {"QUIT", 0},
+ {"REFERENCES", 1},
+ {"RESOURCES", 0},
+ {"RESULTS", 0},
+ {"SET", 3},
+ {"STATS", 1},
+ {"STOP", 0},
+ {"TABLES", 0},
+ {"TEMPLATE", 1},
+ {"TRACE", 1},
+ {"TREE", 0},
+ {"TYPE", 1},
+#ifdef ACPI_APPLICATION
+ {"ENABLEACPI", 0},
+ {"EVENT", 1},
+ {"GPE", 1},
+ {"GPES", 0},
+ {"SCI", 0},
+ {"SLEEP", 0},
+
+ {"CLOSE", 0},
+ {"LOAD", 1},
+ {"OPEN", 1},
+ {"UNLOAD", 1},
+
+ {"TERMINATE", 0},
+ {"THREADS", 3},
+
+ {"PREDEFINED", 0},
+ {"TEST", 1},
+#endif
+ {NULL, 0}
+};
+
+/*
+ * Help for all debugger commands. First argument is the number of lines
+ * of help to output for the command.
+ */
+static const ACPI_DB_COMMAND_HELP AcpiGbl_DbCommandHelp[] =
+{
+ {0, "\nGeneral-Purpose Commands:", "\n"},
+ {1, " Allocations", "Display list of current memory allocations\n"},
+ {2, " Dump <Address>|<Namepath>", "\n"},
+ {0, " [Byte|Word|Dword|Qword]", "Display ACPI objects or memory\n"},
+ {1, " Handlers", "Info about global handlers\n"},
+ {1, " Help [Command]", "This help screen or individual command\n"},
+ {1, " History", "Display command history buffer\n"},
+ {1, " Level <DebugLevel>] [console]", "Get/Set debug level for file or console\n"},
+ {1, " Locks", "Current status of internal mutexes\n"},
+ {1, " Osi [Install|Remove <name>]", "Display or modify global _OSI list\n"},
+ {1, " Quit or Exit", "Exit this command\n"},
+ {8, " Stats <SubCommand>", "Display namespace and memory statistics\n"},
+ {1, " Allocations", "Display list of current memory allocations\n"},
+ {1, " Memory", "Dump internal memory lists\n"},
+ {1, " Misc", "Namespace search and mutex stats\n"},
+ {1, " Objects", "Summary of namespace objects\n"},
+ {1, " Sizes", "Sizes for each of the internal objects\n"},
+ {1, " Stack", "Display CPU stack usage\n"},
+ {1, " Tables", "Info about current ACPI table(s)\n"},
+ {1, " Tables", "Display info about loaded ACPI tables\n"},
+ {1, " ! <CommandNumber>", "Execute command from history buffer\n"},
+ {1, " !!", "Execute last command again\n"},
+
+ {0, "\nNamespace Access Commands:", "\n"},
+ {1, " Businfo", "Display system bus info\n"},
+ {1, " Disassemble <Method>", "Disassemble a control method\n"},
+ {1, " Find <AcpiName> (? is wildcard)", "Find ACPI name(s) with wildcards\n"},
+ {1, " Integrity", "Validate namespace integrity\n"},
+ {1, " Methods", "Display list of loaded control methods\n"},
+ {1, " Namespace [Object] [Depth]", "Display loaded namespace tree/subtree\n"},
+ {1, " Notify <Object> <Value>", "Send a notification on Object\n"},
+ {1, " Objects [ObjectType]", "Display summary of all objects or just given type\n"},
+ {1, " Owner <OwnerId> [Depth]", "Display loaded namespace by object owner\n"},
+ {1, " Paths", "Display full pathnames of namespace objects\n"},
+ {1, " Predefined", "Check all predefined names\n"},
+ {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
+ {1, " References <Addr>", "Find all references to object at addr\n"},
+ {1, " Resources [DeviceName]", "Display Device resources (no arg = all devices)\n"},
+ {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"},
+ {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
+ {1, " Type <Object>", "Display object type\n"},
+
+ {0, "\nControl Method Execution Commands:","\n"},
+ {1, " Arguments (or Args)", "Display method arguments\n"},
+ {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
+ {1, " Call", "Run to next control method invocation\n"},
+ {1, " Debug <Namepath> [Arguments]", "Single Step a control method\n"},
+ {6, " Evaluate", "Synonym for Execute\n"},
+ {5, " Execute <Namepath> [Arguments]", "Execute control method\n"},
+ {1, " Hex Integer", "Integer method argument\n"},
+ {1, " \"Ascii String\"", "String method argument\n"},
+ {1, " (Hex Byte List)", "Buffer method argument\n"},
+ {1, " [Package Element List]", "Package method argument\n"},
+ {1, " Go", "Allow method to run to completion\n"},
+ {1, " Information", "Display info about the current method\n"},
+ {1, " Into", "Step into (not over) a method call\n"},
+ {1, " List [# of Aml Opcodes]", "Display method ASL statements\n"},
+ {1, " Locals", "Display method local variables\n"},
+ {1, " Results", "Display method result stack\n"},
+ {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
+ {1, " Stop", "Terminate control method\n"},
+ {5, " Trace <State> [<Namepath>] [Once]", "Trace control method execution\n"},
+ {1, " Enable", "Enable all messages\n"},
+ {1, " Disable", "Disable tracing\n"},
+ {1, " Method", "Enable method execution messages\n"},
+ {1, " Opcode", "Enable opcode execution messages\n"},
+ {1, " Tree", "Display control method calling tree\n"},
+ {1, " <Enter>", "Single step next AML opcode (over calls)\n"},
+
+#ifdef ACPI_APPLICATION
+ {0, "\nHardware Simulation Commands:", "\n"},
+ {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"},
+ {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
+ {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
+ {1, " Gpes", "Display info on all GPE devices\n"},
+ {1, " Sci", "Generate an SCI\n"},
+ {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
+
+ {0, "\nFile I/O Commands:", "\n"},
+ {1, " Close", "Close debug output file\n"},
+ {1, " Load <Input Filename>", "Load ACPI table from a file\n"},
+ {1, " Open <Output Filename>", "Open a file for debug output\n"},
+ {1, " Unload <Namepath>", "Unload an ACPI table via namespace object\n"},
+
+ {0, "\nUser Space Commands:", "\n"},
+ {1, " Terminate", "Delete namespace and all internal objects\n"},
+ {1, " Thread <Threads><Loops><NamePath>", "Spawn threads to execute method(s)\n"},
+
+ {0, "\nDebug Test Commands:", "\n"},
+ {3, " Test <TestName>", "Invoke a debug test\n"},
+ {1, " Objects", "Read/write/compare all namespace data objects\n"},
+ {1, " Predefined", "Execute all ACPI predefined names (_STA, etc.)\n"},
+#endif
+ {0, NULL, NULL}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMatchCommandHelp
+ *
+ * PARAMETERS: Command - Command string to match
+ * Help - Help table entry to attempt match
+ *
+ * RETURN: TRUE if command matched, FALSE otherwise
+ *
+ * DESCRIPTION: Attempt to match a command in the help table in order to
+ * print help information for a single command.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDbMatchCommandHelp (
+ char *Command,
+ const ACPI_DB_COMMAND_HELP *Help)
+{
+ char *Invocation = Help->Invocation;
+ UINT32 LineCount;
+
+
+ /* Valid commands in the help table begin with a couple of spaces */
+
+ if (*Invocation != ' ')
+ {
+ return (FALSE);
+ }
+
+ while (*Invocation == ' ')
+ {
+ Invocation++;
+ }
+
+ /* Match command name (full command or substring) */
+
+ while ((*Command) && (*Invocation) && (*Invocation != ' '))
+ {
+ if (tolower ((int) *Command) != tolower ((int) *Invocation))
+ {
+ return (FALSE);
+ }
+
+ Invocation++;
+ Command++;
+ }
+
+ /* Print the appropriate number of help lines */
+
+ LineCount = Help->LineCount;
+ while (LineCount)
+ {
+ AcpiOsPrintf ("%-38s : %s", Help->Invocation, Help->Description);
+ Help++;
+ LineCount--;
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayCommandInfo
+ *
+ * PARAMETERS: Command - Command string to match
+ * DisplayAll - Display all matching commands, or just
+ * the first one (substring match)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display help information for a Debugger command.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDisplayCommandInfo (
+ char *Command,
+ BOOLEAN DisplayAll)
+{
+ const ACPI_DB_COMMAND_HELP *Next;
+ BOOLEAN Matched;
+
+
+ Next = AcpiGbl_DbCommandHelp;
+ while (Next->Invocation)
+ {
+ Matched = AcpiDbMatchCommandHelp (Command, Next);
+ if (!DisplayAll && Matched)
+ {
+ return;
+ }
+
+ Next++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHelp
+ *
+ * PARAMETERS: Command - Optional command string to display help.
+ * if not specified, all debugger command
+ * help strings are displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display help for a single debugger command, or all of them.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDisplayHelp (
+ char *Command)
+{
+ const ACPI_DB_COMMAND_HELP *Next = AcpiGbl_DbCommandHelp;
+
+
+ if (!Command)
+ {
+ /* No argument to help, display help for all commands */
+
+ while (Next->Invocation)
+ {
+ AcpiOsPrintf ("%-38s%s", Next->Invocation, Next->Description);
+ Next++;
+ }
+ }
+ else
+ {
+ /* Display help for all commands that match the subtring */
+
+ AcpiDbDisplayCommandInfo (Command, TRUE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetNextToken
+ *
+ * PARAMETERS: String - Command buffer
+ * Next - Return value, end of next token
+ *
+ * RETURN: Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing. Get the next token on the command line
+ *
+ ******************************************************************************/
+
+char *
+AcpiDbGetNextToken (
+ char *String,
+ char **Next,
+ ACPI_OBJECT_TYPE *ReturnType)
+{
+ char *Start;
+ UINT32 Depth;
+ ACPI_OBJECT_TYPE Type = ACPI_TYPE_INTEGER;
+
+
+ /* At end of buffer? */
+
+ if (!String || !(*String))
+ {
+ return (NULL);
+ }
+
+ /* Remove any spaces at the beginning */
+
+ if (*String == ' ')
+ {
+ while (*String && (*String == ' '))
+ {
+ String++;
+ }
+
+ if (!(*String))
+ {
+ return (NULL);
+ }
+ }
+
+ switch (*String)
+ {
+ case '"':
+
+ /* This is a quoted string, scan until closing quote */
+
+ String++;
+ Start = String;
+ Type = ACPI_TYPE_STRING;
+
+ /* Find end of string */
+
+ while (*String && (*String != '"'))
+ {
+ String++;
+ }
+ break;
+
+ case '(':
+
+ /* This is the start of a buffer, scan until closing paren */
+
+ String++;
+ Start = String;
+ Type = ACPI_TYPE_BUFFER;
+
+ /* Find end of buffer */
+
+ while (*String && (*String != ')'))
+ {
+ String++;
+ }
+ break;
+
+ case '[':
+
+ /* This is the start of a package, scan until closing bracket */
+
+ String++;
+ Depth = 1;
+ Start = String;
+ Type = ACPI_TYPE_PACKAGE;
+
+ /* Find end of package (closing bracket) */
+
+ while (*String)
+ {
+ /* Handle String package elements */
+
+ if (*String == '"')
+ {
+ /* Find end of string */
+
+ String++;
+ while (*String && (*String != '"'))
+ {
+ String++;
+ }
+ if (!(*String))
+ {
+ break;
+ }
+ }
+ else if (*String == '[')
+ {
+ Depth++; /* A nested package declaration */
+ }
+ else if (*String == ']')
+ {
+ Depth--;
+ if (Depth == 0) /* Found final package closing bracket */
+ {
+ break;
+ }
+ }
+
+ String++;
+ }
+ break;
+
+ default:
+
+ Start = String;
+
+ /* Find end of token */
+
+ while (*String && (*String != ' '))
+ {
+ String++;
+ }
+ break;
+ }
+
+ if (!(*String))
+ {
+ *Next = NULL;
+ }
+ else
+ {
+ *String = 0;
+ *Next = String + 1;
+ }
+
+ *ReturnType = Type;
+ return (Start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetLine
+ *
+ * PARAMETERS: InputBuffer - Command line buffer
+ *
+ * RETURN: Count of arguments to the command
+ *
+ * DESCRIPTION: Get the next command line from the user. Gets entire line
+ * up to the next newline
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbGetLine (
+ char *InputBuffer)
+{
+ UINT32 i;
+ UINT32 Count;
+ char *Next;
+ char *This;
+
+
+ if (AcpiUtSafeStrcpy (AcpiGbl_DbParsedBuf, sizeof (AcpiGbl_DbParsedBuf),
+ InputBuffer))
+ {
+ AcpiOsPrintf (
+ "Buffer overflow while parsing input line (max %u characters)\n",
+ sizeof (AcpiGbl_DbParsedBuf));
+ return (0);
+ }
+
+ This = AcpiGbl_DbParsedBuf;
+ for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
+ {
+ AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
+ &AcpiGbl_DbArgTypes[i]);
+ if (!AcpiGbl_DbArgs[i])
+ {
+ break;
+ }
+
+ This = Next;
+ }
+
+ /* Uppercase the actual command */
+
+ if (AcpiGbl_DbArgs[0])
+ {
+ AcpiUtStrupr (AcpiGbl_DbArgs[0]);
+ }
+
+ Count = i;
+ if (Count)
+ {
+ Count--; /* Number of args only */
+ }
+
+ return (Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMatchCommand
+ *
+ * PARAMETERS: UserCommand - User command line
+ *
+ * RETURN: Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbMatchCommand (
+ char *UserCommand)
+{
+ UINT32 i;
+
+
+ if (!UserCommand || UserCommand[0] == 0)
+ {
+ return (CMD_NULL);
+ }
+
+ for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
+ {
+ if (strstr (AcpiGbl_DbCommands[i].Name, UserCommand) ==
+ AcpiGbl_DbCommands[i].Name)
+ {
+ return (i);
+ }
+ }
+
+ /* Command not recognized */
+
+ return (CMD_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCommandDispatch
+ *
+ * PARAMETERS: InputBuffer - Command line buffer
+ * WalkState - Current walk
+ * Op - Current (executing) parse op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Command dispatcher.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbCommandDispatch (
+ char *InputBuffer,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Temp;
+ UINT32 CommandIndex;
+ UINT32 ParamCount;
+ char *CommandLine;
+ ACPI_STATUS Status = AE_CTRL_TRUE;
+
+
+ /* If AcpiTerminate has been called, terminate this thread */
+
+ if (AcpiGbl_DbTerminateThreads)
+ {
+ return (AE_CTRL_TERMINATE);
+ }
+
+ /* Find command and add to the history buffer */
+
+ ParamCount = AcpiDbGetLine (InputBuffer);
+ CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
+ Temp = 0;
+
+ /*
+ * We don't want to add the !! command to the history buffer. It
+ * would cause an infinite loop because it would always be the
+ * previous command.
+ */
+ if (CommandIndex != CMD_HISTORY_LAST)
+ {
+ AcpiDbAddToHistory (InputBuffer);
+ }
+
+ /* Verify that we have the minimum number of params */
+
+ if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
+ {
+ AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
+ ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
+ AcpiGbl_DbCommands[CommandIndex].MinArgs);
+
+ AcpiDbDisplayCommandInfo (
+ AcpiGbl_DbCommands[CommandIndex].Name, FALSE);
+ return (AE_CTRL_TRUE);
+ }
+
+ /* Decode and dispatch the command */
+
+ switch (CommandIndex)
+ {
+ case CMD_NULL:
+
+ if (Op)
+ {
+ return (AE_OK);
+ }
+ break;
+
+ case CMD_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiUtDumpAllocations ((UINT32) -1, NULL);
+#endif
+ break;
+
+ case CMD_ARGS:
+ case CMD_ARGUMENTS:
+
+ AcpiDbDisplayArguments ();
+ break;
+
+ case CMD_BREAKPOINT:
+
+ AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
+ break;
+
+ case CMD_BUSINFO:
+
+ AcpiDbGetBusInfo ();
+ break;
+
+ case CMD_CALL:
+
+ AcpiDbSetMethodCallBreakpoint (Op);
+ Status = AE_OK;
+ break;
+
+ case CMD_DEBUG:
+
+ AcpiDbExecute (AcpiGbl_DbArgs[1],
+ &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
+ break;
+
+ case CMD_DISASSEMBLE:
+ case CMD_DISASM:
+
+ (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_DUMP:
+
+ AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_EVALUATE:
+ case CMD_EXECUTE:
+
+ AcpiDbExecute (AcpiGbl_DbArgs[1],
+ &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
+ break;
+
+ case CMD_FIND:
+
+ Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_GO:
+
+ AcpiGbl_CmSingleStep = FALSE;
+ return (AE_OK);
+
+ case CMD_HANDLERS:
+
+ AcpiDbDisplayHandlers ();
+ break;
+
+ case CMD_HELP:
+ case CMD_HELP2:
+
+ AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_HISTORY:
+
+ AcpiDbDisplayHistory ();
+ break;
+
+ case CMD_HISTORY_EXE: /* ! command */
+
+ CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
+ if (!CommandLine)
+ {
+ return (AE_CTRL_TRUE);
+ }
+
+ Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
+ return (Status);
+
+ case CMD_HISTORY_LAST: /* !! command */
+
+ CommandLine = AcpiDbGetFromHistory (NULL);
+ if (!CommandLine)
+ {
+ return (AE_CTRL_TRUE);
+ }
+
+ Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
+ return (Status);
+
+ case CMD_INFORMATION:
+
+ AcpiDbDisplayMethodInfo (Op);
+ break;
+
+ case CMD_INTEGRITY:
+
+ AcpiDbCheckIntegrity ();
+ break;
+
+ case CMD_INTO:
+
+ if (Op)
+ {
+ AcpiGbl_CmSingleStep = TRUE;
+ return (AE_OK);
+ }
+ break;
+
+ case CMD_LEVEL:
+
+ if (ParamCount == 0)
+ {
+ AcpiOsPrintf (
+ "Current debug level for file output is: %8.8lX\n",
+ AcpiGbl_DbDebugLevel);
+ AcpiOsPrintf (
+ "Current debug level for console output is: %8.8lX\n",
+ AcpiGbl_DbConsoleDebugLevel);
+ }
+ else if (ParamCount == 2)
+ {
+ Temp = AcpiGbl_DbConsoleDebugLevel;
+ AcpiGbl_DbConsoleDebugLevel = strtoul (AcpiGbl_DbArgs[1],
+ NULL, 16);
+ AcpiOsPrintf (
+ "Debug Level for console output was %8.8lX, now %8.8lX\n",
+ Temp, AcpiGbl_DbConsoleDebugLevel);
+ }
+ else
+ {
+ Temp = AcpiGbl_DbDebugLevel;
+ AcpiGbl_DbDebugLevel = strtoul (AcpiGbl_DbArgs[1], NULL, 16);
+ AcpiOsPrintf (
+ "Debug Level for file output was %8.8lX, now %8.8lX\n",
+ Temp, AcpiGbl_DbDebugLevel);
+ }
+ break;
+
+ case CMD_LIST:
+
+ AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
+ break;
+
+ case CMD_LOCKS:
+
+ AcpiDbDisplayLocks ();
+ break;
+
+ case CMD_LOCALS:
+
+ AcpiDbDisplayLocals ();
+ break;
+
+ case CMD_METHODS:
+
+ Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_NAMESPACE:
+
+ AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_NOTIFY:
+
+ Temp = strtoul (AcpiGbl_DbArgs[2], NULL, 0);
+ AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
+ break;
+
+ case CMD_OBJECTS:
+
+ AcpiUtStrupr (AcpiGbl_DbArgs[1]);
+ Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_OSI:
+
+ AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_OWNER:
+
+ AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_PATHS:
+
+ AcpiDbDumpNamespacePaths ();
+ break;
+
+ case CMD_PREFIX:
+
+ AcpiDbSetScope (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_REFERENCES:
+
+ AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_RESOURCES:
+
+ AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_RESULTS:
+
+ AcpiDbDisplayResults ();
+ break;
+
+ case CMD_SET:
+
+ AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
+ AcpiGbl_DbArgs[3]);
+ break;
+
+ case CMD_STATS:
+
+ Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_STOP:
+
+ return (AE_NOT_IMPLEMENTED);
+
+ case CMD_TABLES:
+
+ AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_TEMPLATE:
+
+ AcpiDbDisplayTemplate (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_TRACE:
+
+ AcpiDbTrace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]);
+ break;
+
+ case CMD_TREE:
+
+ AcpiDbDisplayCallingTree ();
+ break;
+
+ case CMD_TYPE:
+
+ AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
+ break;
+
+#ifdef ACPI_APPLICATION
+
+ /* Hardware simulation commands. */
+
+ case CMD_ENABLEACPI:
+#if (!ACPI_REDUCED_HARDWARE)
+
+ Status = AcpiEnable();
+ if (ACPI_FAILURE(Status))
+ {
+ AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
+ return (Status);
+ }
+#endif /* !ACPI_REDUCED_HARDWARE */
+ break;
+
+ case CMD_EVENT:
+
+ AcpiOsPrintf ("Event command not implemented\n");
+ break;
+
+ case CMD_GPE:
+
+ AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_GPES:
+
+ AcpiDbDisplayGpes ();
+ break;
+
+ case CMD_SCI:
+
+ AcpiDbGenerateSci ();
+ break;
+
+ case CMD_SLEEP:
+
+ Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
+ break;
+
+ /* File I/O commands. */
+
+ case CMD_CLOSE:
+
+ AcpiDbCloseDebugFile ();
+ break;
+
+ case CMD_LOAD:
+
+ Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL, FALSE);
+ break;
+
+ case CMD_OPEN:
+
+ AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
+ break;
+
+ /* User space commands. */
+
+ case CMD_TERMINATE:
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiUtSubsystemShutdown ();
+
+ /*
+ * TBD: [Restructure] Need some way to re-initialize without
+ * re-creating the semaphores!
+ */
+
+ /* AcpiInitialize (NULL); */
+ break;
+
+ case CMD_THREADS:
+
+ AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
+ AcpiGbl_DbArgs[3]);
+ break;
+
+ /* Debug test commands. */
+
+ case CMD_PREDEFINED:
+
+ AcpiDbCheckPredefinedNames ();
+ break;
+
+ case CMD_TEST:
+
+ AcpiDbExecuteTest (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_UNLOAD:
+
+ AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]);
+ break;
+#endif
+
+ case CMD_EXIT:
+ case CMD_QUIT:
+
+ if (Op)
+ {
+ AcpiOsPrintf ("Method execution terminated\n");
+ return (AE_CTRL_TERMINATE);
+ }
+
+ if (!AcpiGbl_DbOutputToFile)
+ {
+ AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
+ }
+
+#ifdef ACPI_APPLICATION
+ AcpiDbCloseDebugFile ();
+#endif
+ AcpiGbl_DbTerminateThreads = TRUE;
+ return (AE_CTRL_TERMINATE);
+
+ case CMD_NOT_FOUND:
+ default:
+
+ AcpiOsPrintf ("%s: unknown command\n", AcpiGbl_DbArgs[0]);
+ return (AE_CTRL_TRUE);
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AE_CTRL_TRUE;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteThread
+ *
+ * PARAMETERS: Context - Not used
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+void ACPI_SYSTEM_XFACE
+AcpiDbExecuteThread (
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_STATUS MStatus;
+
+
+ while (Status != AE_CTRL_TERMINATE)
+ {
+ AcpiGbl_MethodExecuting = FALSE;
+ AcpiGbl_StepToNextCall = FALSE;
+
+ MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (MStatus))
+ {
+ return;
+ }
+
+ Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
+
+ MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (MStatus))
+ {
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSingleThread
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbSingleThread (
+ void)
+{
+
+ AcpiGbl_MethodExecuting = FALSE;
+ AcpiGbl_StepToNextCall = FALSE;
+
+ (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUserCommands
+ *
+ * PARAMETERS: Prompt - User prompt (depends on mode)
+ * Op - Current executing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger. Commands are
+ * matched and dispatched here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbUserCommands (
+ char Prompt,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ AcpiOsPrintf ("\n");
+
+ /* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+ while (!AcpiGbl_DbTerminateThreads)
+ {
+ /* Force output to console until a command is entered */
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+ /* Different prompt if method is executing */
+
+ if (!AcpiGbl_MethodExecuting)
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+ }
+ else
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+ }
+
+ /* Get the user input line */
+
+ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
+ ACPI_DB_LINE_BUFFER_SIZE, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
+ return (Status);
+ }
+
+ /* Check for single or multithreaded debug */
+
+ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
+ {
+ /*
+ * Signal the debug thread that we have a command to execute,
+ * and wait for the command to complete.
+ */
+ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Just call to the command line interpreter */
+
+ AcpiDbSingleThread ();
+ }
+ }
+
+ /* Shut down the debugger */
+
+ AcpiTerminateDebugger ();
+
+ /*
+ * Only this thread (the original thread) should actually terminate the
+ * subsystem, because all the semaphores are deleted during termination
+ */
+ Status = AcpiTerminate ();
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbmethod.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbmethod.c
new file mode 100644
index 0000000000..243a66da5e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbmethod.c
@@ -0,0 +1,416 @@
+/*******************************************************************************
+ *
+ * Module Name: dbmethod - Debug commands for control methods
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbmethod")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodBreakpoint
+ *
+ * PARAMETERS: Location - AML offset of breakpoint
+ * WalkState - Current walk info
+ * Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ * AML offset
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodBreakpoint (
+ char *Location,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Address;
+ UINT32 AmlOffset;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ /* Get and verify the breakpoint address */
+
+ Address = strtoul (Location, NULL, 16);
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
+ WalkState->ParserState.AmlStart);
+ if (Address <= AmlOffset)
+ {
+ AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
+ Address, AmlOffset);
+ }
+
+ /* Save breakpoint in current walk */
+
+ WalkState->UserBreakpoint = Address;
+ AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodCallBreakpoint
+ *
+ * PARAMETERS: Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ * AML offset
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodCallBreakpoint (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiGbl_StepToNextCall = TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodData
+ *
+ * PARAMETERS: TypeArg - L for local, A for argument
+ * IndexArg - which one
+ * ValueArg - Value to set.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a local or argument for the running control method.
+ * NOTE: only object supported is Number.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodData (
+ char *TypeArg,
+ char *IndexArg,
+ char *ValueArg)
+{
+ char Type;
+ UINT32 Index;
+ UINT32 Value;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /* Validate TypeArg */
+
+ AcpiUtStrupr (TypeArg);
+ Type = TypeArg[0];
+ if ((Type != 'L') &&
+ (Type != 'A') &&
+ (Type != 'N'))
+ {
+ AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
+ return;
+ }
+
+ Value = strtoul (ValueArg, NULL, 16);
+
+ if (Type == 'N')
+ {
+ Node = AcpiDbConvertToNode (IndexArg);
+ if (!Node)
+ {
+ return;
+ }
+
+ if (Node->Type != ACPI_TYPE_INTEGER)
+ {
+ AcpiOsPrintf ("Can only set Integer nodes\n");
+ return;
+ }
+ ObjDesc = Node->Object;
+ ObjDesc->Integer.Value = Value;
+ return;
+ }
+
+ /* Get the index and value */
+
+ Index = strtoul (IndexArg, NULL, 16);
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ /* Create and initialize the new object */
+
+ ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value);
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("Could not create an internal object\n");
+ return;
+ }
+
+ /* Store the new object into the target */
+
+ switch (Type)
+ {
+ case 'A':
+
+ /* Set a method argument */
+
+ if (Index > ACPI_METHOD_MAX_ARG)
+ {
+ AcpiOsPrintf ("Arg%u - Invalid argument name\n",
+ Index);
+ goto Cleanup;
+ }
+
+ Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG,
+ Index, ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc = WalkState->Arguments[Index].Object;
+
+ AcpiOsPrintf ("Arg%u: ", Index);
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+ break;
+
+ case 'L':
+
+ /* Set a method local */
+
+ if (Index > ACPI_METHOD_MAX_LOCAL)
+ {
+ AcpiOsPrintf ("Local%u - Invalid local variable name\n",
+ Index);
+ goto Cleanup;
+ }
+
+ Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL,
+ Index, ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc = WalkState->LocalVariables[Index].Object;
+
+ AcpiOsPrintf ("Local%u: ", Index);
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+ break;
+
+ default:
+
+ break;
+ }
+
+Cleanup:
+ AcpiUtRemoveReference (ObjDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisassembleAml
+ *
+ * PARAMETERS: Statements - Number of statements to disassemble
+ * Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ * of statements specified.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisassembleAml (
+ char *Statements,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 NumStatements = 8;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ if (Statements)
+ {
+ NumStatements = strtoul (Statements, NULL, 0);
+ }
+
+#ifdef ACPI_DISASSEMBLER
+ AcpiDmDisassemble (NULL, Op, NumStatements);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisassembleMethod
+ *
+ * PARAMETERS: Name - Name of control method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ * of statements specified.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisassembleMethod (
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Method;
+
+
+ Method = AcpiDbConvertToNode (Name);
+ if (!Method)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (Method->Type != ACPI_TYPE_METHOD)
+ {
+ ACPI_ERROR ((AE_INFO, "%s (%s): Object must be a control method",
+ Name, AcpiUtGetTypeName (Method->Type)));
+ return (AE_BAD_PARAMETER);
+ }
+
+ ObjDesc = Method->Object;
+
+ Op = AcpiPsCreateScopeOp (ObjDesc->Method.AmlStart);
+ if (!Op)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
+ ObjDesc->Method.AmlStart,
+ ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
+ WalkState->OwnerId = ObjDesc->Method.OwnerId;
+
+ /* Push start scope on scope stack and make it current */
+
+ Status = AcpiDsScopeStackPush (Method,
+ Method->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Parse the entire method AML including deferred operators */
+
+ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
+ WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
+
+ Status = AcpiPsParseAml (WalkState);
+
+#ifdef ACPI_DISASSEMBLER
+ (void) AcpiDmParseDeferredOps (Op);
+
+ /* Now we can disassemble the method */
+
+ AcpiGbl_DmOpt_Verbose = FALSE;
+ AcpiDmDisassemble (NULL, Op, 0);
+ AcpiGbl_DmOpt_Verbose = TRUE;
+#endif
+
+ AcpiPsDeleteParseTree (Op);
+
+ /* Method cleanup */
+
+ AcpiNsDeleteNamespaceSubtree (Method);
+ AcpiNsDeleteNamespaceByOwner (ObjDesc->Method.OwnerId);
+ AcpiUtReleaseOwnerId (&ObjDesc->Method.OwnerId);
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbnames.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbnames.c
new file mode 100644
index 0000000000..e152be5b64
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbnames.c
@@ -0,0 +1,1071 @@
+/*******************************************************************************
+ *
+ * Module Name: dbnames - Debugger commands for the acpi namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbnames")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbWalkAndMatchName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForPredefinedNames (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForSpecificObjects (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForObjectCounts (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbIntegrityWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForReferences (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbBusWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+/*
+ * Arguments for the Objects command
+ * These object types map directly to the ACPI_TYPES
+ */
+static ACPI_DB_ARGUMENT_INFO AcpiDbObjectTypes [] =
+{
+ {"ANY"},
+ {"INTEGERS"},
+ {"STRINGS"},
+ {"BUFFERS"},
+ {"PACKAGES"},
+ {"FIELDS"},
+ {"DEVICES"},
+ {"EVENTS"},
+ {"METHODS"},
+ {"MUTEXES"},
+ {"REGIONS"},
+ {"POWERRESOURCES"},
+ {"PROCESSORS"},
+ {"THERMALZONES"},
+ {"BUFFERFIELDS"},
+ {"DDBHANDLES"},
+ {"DEBUG"},
+ {"REGIONFIELDS"},
+ {"BANKFIELDS"},
+ {"INDEXFIELDS"},
+ {"REFERENCES"},
+ {"ALIASES"},
+ {"METHODALIASES"},
+ {"NOTIFY"},
+ {"ADDRESSHANDLER"},
+ {"RESOURCE"},
+ {"RESOURCEFIELD"},
+ {"SCOPES"},
+ {NULL} /* Must be null terminated */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetScope
+ *
+ * PARAMETERS: Name - New scope path
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set the "current scope" as maintained by this utility.
+ * The scope is used as a prefix to ACPI paths.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetScope (
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if (!Name || Name[0] == 0)
+ {
+ AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
+ return;
+ }
+
+ AcpiDbPrepNamestring (Name);
+
+ if (ACPI_IS_ROOT_PREFIX (Name[0]))
+ {
+ /* Validate new scope from the root */
+
+ Status = AcpiNsGetNode (AcpiGbl_RootNode, Name,
+ ACPI_NS_NO_UPSEARCH, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiGbl_DbScopeBuf[0] = 0;
+ }
+ else
+ {
+ /* Validate new scope relative to old scope */
+
+ Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name,
+ ACPI_NS_NO_UPSEARCH, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+ }
+
+ /* Build the final pathname */
+
+ if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf),
+ Name))
+ {
+ Status = AE_BUFFER_OVERFLOW;
+ goto ErrorExit;
+ }
+
+ if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf),
+ "\\"))
+ {
+ Status = AE_BUFFER_OVERFLOW;
+ goto ErrorExit;
+ }
+
+ AcpiGbl_DbScopeNode = Node;
+ AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
+ return;
+
+ErrorExit:
+
+ AcpiOsPrintf ("Could not attach scope: %s, %s\n",
+ Name, AcpiFormatException (Status));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpNamespace
+ *
+ * PARAMETERS: StartArg - Node to begin namespace dump
+ * DepthArg - Maximum tree depth to be dumped
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
+ * with type and other information.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpNamespace (
+ char *StartArg,
+ char *DepthArg)
+{
+ ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
+ UINT32 MaxDepth = ACPI_UINT32_MAX;
+
+
+ /* No argument given, just start at the root and dump entire namespace */
+
+ if (StartArg)
+ {
+ SubtreeEntry = AcpiDbConvertToNode (StartArg);
+ if (!SubtreeEntry)
+ {
+ return;
+ }
+
+ /* Now we can check for the depth argument */
+
+ if (DepthArg)
+ {
+ MaxDepth = strtoul (DepthArg, NULL, 0);
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
+ ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
+
+ /* Display the subtree */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
+ ACPI_OWNER_ID_MAX, SubtreeEntry);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpNamespacePaths
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump entire namespace with full object pathnames and object
+ * type information. Alternative to "namespace" command.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpNamespacePaths (
+ void)
+{
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("ACPI Namespace (from root):\n");
+
+ /* Display the entire namespace */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiNsDumpObjectPaths (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
+ ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode);
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpNamespaceByOwner
+ *
+ * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed
+ * DepthArg - Maximum tree depth to be dumped
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpNamespaceByOwner (
+ char *OwnerArg,
+ char *DepthArg)
+{
+ ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
+ UINT32 MaxDepth = ACPI_UINT32_MAX;
+ ACPI_OWNER_ID OwnerId;
+
+
+ OwnerId = (ACPI_OWNER_ID) strtoul (OwnerArg, NULL, 0);
+
+ /* Now we can check for the depth argument */
+
+ if (DepthArg)
+ {
+ MaxDepth = strtoul (DepthArg, NULL, 0);
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
+
+ /* Display the subtree */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
+ OwnerId, SubtreeEntry);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkAndMatchName
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
+ * are supported -- '?' matches any character.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkAndMatchName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_STATUS Status;
+ char *RequestedName = (char *) Context;
+ UINT32 i;
+ ACPI_BUFFER Buffer;
+ ACPI_WALK_INFO Info;
+
+
+ /* Check for a name match */
+
+ for (i = 0; i < 4; i++)
+ {
+ /* Wildcard support */
+
+ if ((RequestedName[i] != '?') &&
+ (RequestedName[i] != ((ACPI_NAMESPACE_NODE *)
+ ObjHandle)->Name.Ascii[i]))
+ {
+ /* No match, just exit */
+
+ return (AE_OK);
+ }
+ }
+
+ /* Get the full pathname to this object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n",
+ ObjHandle);
+ }
+ else
+ {
+ Info.OwnerId = ACPI_OWNER_ID_MAX;
+ Info.DebugLevel = ACPI_UINT32_MAX;
+ Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+ AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
+ (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
+ ACPI_FREE (Buffer.Pointer);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbFindNameInNamespace
+ *
+ * PARAMETERS: NameArg - The 4-character ACPI name to find.
+ * wildcards are supported.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Search the namespace for a given name (with wildcards)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbFindNameInNamespace (
+ char *NameArg)
+{
+ char AcpiName[5] = "____";
+ char *AcpiNamePtr = AcpiName;
+
+
+ if (strlen (NameArg) > ACPI_NAME_SIZE)
+ {
+ AcpiOsPrintf ("Name must be no longer than 4 characters\n");
+ return (AE_OK);
+ }
+
+ /* Pad out name with underscores as necessary to create a 4-char name */
+
+ AcpiUtStrupr (NameArg);
+ while (*NameArg)
+ {
+ *AcpiNamePtr = *NameArg;
+ AcpiNamePtr++;
+ NameArg++;
+ }
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForPredefinedNames
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Detect and display predefined ACPI names (names that start with
+ * an underscore)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForPredefinedNames (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ UINT32 *Count = (UINT32 *) Context;
+ const ACPI_PREDEFINED_INFO *Predefined;
+ const ACPI_PREDEFINED_INFO *Package = NULL;
+ char *Pathname;
+ char StringBuffer[48];
+
+
+ Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
+ if (!Predefined)
+ {
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ /* If method returns a package, the info is in the next table entry */
+
+ if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
+ {
+ Package = Predefined + 1;
+ }
+
+ AcpiUtGetExpectedReturnTypes (StringBuffer,
+ Predefined->Info.ExpectedBtypes);
+
+ AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname,
+ METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList),
+ StringBuffer);
+
+ if (Package)
+ {
+ AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
+ Package->RetInfo.Type, Package->RetInfo.ObjectType1,
+ Package->RetInfo.Count1);
+ }
+
+ AcpiOsPrintf("\n");
+
+ /* Check that the declared argument count matches the ACPI spec */
+
+ AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined);
+
+ ACPI_FREE (Pathname);
+ (*Count)++;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCheckPredefinedNames
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate all predefined names in the namespace
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCheckPredefinedNames (
+ void)
+{
+ UINT32 Count = 0;
+
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL);
+
+ AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForObjectCounts
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForObjectCounts (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OBJECT_INFO *Info = (ACPI_OBJECT_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+
+
+ if (Node->Type > ACPI_TYPE_NS_NODE_MAX)
+ {
+ AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n",
+ Node->Name.Ascii, Node->Type);
+ }
+ else
+ {
+ Info->Types[Node->Type]++;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForSpecificObjects
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForSpecificObjects (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
+ ACPI_BUFFER Buffer;
+ ACPI_STATUS Status;
+
+
+ Info->Count++;
+
+ /* Get and display the full pathname to this object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
+ ACPI_FREE (Buffer.Pointer);
+
+ /* Dump short info about the object */
+
+ (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayObjects
+ *
+ * PARAMETERS: ObjTypeArg - Type of object to display
+ * DisplayCountArg - Max depth to display
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display objects in the namespace of the requested type
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisplayObjects (
+ char *ObjTypeArg,
+ char *DisplayCountArg)
+{
+ ACPI_WALK_INFO Info;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_OBJECT_INFO *ObjectInfo;
+ UINT32 i;
+ UINT32 TotalObjects = 0;
+
+
+ /* No argument means display summary/count of all object types */
+
+ if (!ObjTypeArg)
+ {
+ ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
+ (void *) ObjectInfo, NULL);
+
+ AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
+
+ for (i = 0; i < ACPI_TOTAL_TYPES; i++)
+ {
+ AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i],
+ AcpiUtGetTypeName (i));
+
+ TotalObjects += ObjectInfo->Types[i];
+ }
+
+ AcpiOsPrintf ("\n%8u Total namespace objects\n\n",
+ TotalObjects);
+
+ ACPI_FREE (ObjectInfo);
+ return (AE_OK);
+ }
+
+ /* Get the object type */
+
+ Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
+ if (Type == ACPI_TYPE_NOT_FOUND)
+ {
+ AcpiOsPrintf ("Invalid or unsupported argument\n");
+ return (AE_OK);
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf (
+ "Objects of type [%s] defined in the current ACPI Namespace:\n",
+ AcpiUtGetTypeName (Type));
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+
+ Info.Count = 0;
+ Info.OwnerId = ACPI_OWNER_ID_MAX;
+ Info.DebugLevel = ACPI_UINT32_MAX;
+ Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
+
+ AcpiOsPrintf (
+ "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
+ Info.Count, AcpiUtGetTypeName (Type));
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbIntegrityWalk
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Examine one NS node for valid values.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbIntegrityWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_OPERAND_OBJECT *Object;
+ BOOLEAN Alias = TRUE;
+
+
+ Info->Nodes++;
+
+ /* Verify the NS node, and dereference aliases */
+
+ while (Alias)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf (
+ "Invalid Descriptor Type for Node %p [%s] - "
+ "is %2.2X should be %2.2X\n",
+ Node, AcpiUtGetDescriptorName (Node),
+ ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
+ return (AE_OK);
+ }
+
+ if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) ||
+ (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
+ {
+ Node = (ACPI_NAMESPACE_NODE *) Node->Object;
+ }
+ else
+ {
+ Alias = FALSE;
+ }
+ }
+
+ if (Node->Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
+ Node, Node->Type);
+ return (AE_OK);
+ }
+
+ if (!AcpiUtValidAcpiName (Node->Name.Ascii))
+ {
+ AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
+ return (AE_OK);
+ }
+
+ Object = AcpiNsGetAttachedObject (Node);
+ if (Object)
+ {
+ Info->Objects++;
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
+ Object, AcpiUtGetDescriptorName (Object));
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCheckIntegrity
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check entire namespace for data structure integrity
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCheckIntegrity (
+ void)
+{
+ ACPI_INTEGRITY_INFO Info = {0,0};
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
+
+ AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
+ Info.Nodes, Info.Objects);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForReferences
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check if this namespace object refers to the target object
+ * that is passed in as the context value.
+ *
+ * Note: Currently doesn't check subobjects within the Node's object
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForReferences (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+
+
+ /* Check for match against the namespace node itself */
+
+ if (Node == (void *) ObjDesc)
+ {
+ AcpiOsPrintf ("Object is a Node [%4.4s]\n",
+ AcpiUtGetNodeName (Node));
+ }
+
+ /* Check for match against the object attached to the node */
+
+ if (AcpiNsGetAttachedObject (Node) == ObjDesc)
+ {
+ AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
+ Node, AcpiUtGetNodeName (Node));
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbFindReferences
+ *
+ * PARAMETERS: ObjectArg - String with hex value of the object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Search namespace for all references to the input object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbFindReferences (
+ char *ObjectArg)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_SIZE Address;
+
+
+ /* Convert string to object pointer */
+
+ Address = strtoul (ObjectArg, NULL, 16);
+ ObjDesc = ACPI_TO_POINTER (Address);
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
+ (void *) ObjDesc, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbBusWalk
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display info about device objects that have a corresponding
+ * _PRT method.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbBusWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_STATUS Status;
+ ACPI_BUFFER Buffer;
+ ACPI_NAMESPACE_NODE *TempNode;
+ ACPI_DEVICE_INFO *Info;
+ UINT32 i;
+
+
+ if ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_PROCESSOR))
+ {
+ return (AE_OK);
+ }
+
+ /* Exit if there is no _PRT under this device */
+
+ Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
+ ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /* Get the full path to this device object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n",
+ ObjHandle);
+ return (AE_OK);
+ }
+
+ Status = AcpiGetObjectInfo (ObjHandle, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /* Display the full path */
+
+ AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
+ ACPI_FREE (Buffer.Pointer);
+
+ if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
+ {
+ AcpiOsPrintf (" - Is PCI Root Bridge");
+ }
+ AcpiOsPrintf ("\n");
+
+ /* _PRT info */
+
+ AcpiOsPrintf ("_PRT: %p\n", TempNode);
+
+ /* Dump _ADR, _HID, _UID, _CID */
+
+ if (Info->Valid & ACPI_VALID_ADR)
+ {
+ AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Info->Address));
+ }
+ else
+ {
+ AcpiOsPrintf ("_ADR: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_HID)
+ {
+ AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
+ }
+ else
+ {
+ AcpiOsPrintf ("_HID: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_UID)
+ {
+ AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
+ }
+ else
+ {
+ AcpiOsPrintf ("_UID: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_CID)
+ {
+ for (i = 0; i < Info->CompatibleIdList.Count; i++)
+ {
+ AcpiOsPrintf ("_CID: %s\n",
+ Info->CompatibleIdList.Ids[i].String);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("_CID: <Not Present>\n");
+ }
+
+ ACPI_FREE (Info);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetBusInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display info about system busses.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbGetBusInfo (
+ void)
+{
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbobject.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbobject.c
new file mode 100644
index 0000000000..f93778c968
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbobject.c
@@ -0,0 +1,527 @@
+/*******************************************************************************
+ *
+ * Module Name: dbobject - ACPI object decode and display
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbobject")
+
+
+/* Local prototypes */
+
+static void
+AcpiDbDecodeNode (
+ ACPI_NAMESPACE_NODE *Node);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpMethodInfo
+ *
+ * PARAMETERS: Status - Method execution status
+ * WalkState - Current state of the parse tree walk
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ * Dumps the method execution stack, and the method locals/args,
+ * and disassembles the AML opcode that failed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpMethodInfo (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_THREAD_STATE *Thread;
+
+
+ /* Ignore control codes, they are not errors */
+
+ if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
+ {
+ return;
+ }
+
+ /* We may be executing a deferred opcode */
+
+ if (WalkState->DeferredNode)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ /*
+ * If there is no Thread, we are not actually executing a method.
+ * This can happen when the iASL compiler calls the interpreter
+ * to perform constant folding.
+ */
+ Thread = WalkState->Thread;
+ if (!Thread)
+ {
+ return;
+ }
+
+ /* Display the method locals and arguments */
+
+ AcpiOsPrintf ("\n");
+ AcpiDbDecodeLocals (WalkState);
+ AcpiOsPrintf ("\n");
+ AcpiDbDecodeArguments (WalkState);
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeInternalObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDecodeInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf (" Uninitialized");
+ return;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf (" %p [%s]", ObjDesc,
+ AcpiUtGetDescriptorName (ObjDesc));
+ return;
+ }
+
+ AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc));
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf (" %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("(%u) \"%.24s",
+ ObjDesc->String.Length, ObjDesc->String.Pointer);
+
+ if (ObjDesc->String.Length > 24)
+ {
+ AcpiOsPrintf ("...");
+ }
+ else
+ {
+ AcpiOsPrintf ("\"");
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length);
+ for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++)
+ {
+ AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]);
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf (" %p", ObjDesc);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeNode
+ *
+ * PARAMETERS: Node - Object to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of a namespace node
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDecodeNode (
+ ACPI_NAMESPACE_NODE *Node)
+{
+
+ AcpiOsPrintf ("<Node> Name %4.4s",
+ AcpiUtGetNodeName (Node));
+
+ if (Node->Flags & ANOBJ_METHOD_ARG)
+ {
+ AcpiOsPrintf (" [Method Arg]");
+ }
+ if (Node->Flags & ANOBJ_METHOD_LOCAL)
+ {
+ AcpiOsPrintf (" [Method Local]");
+ }
+
+ switch (Node->Type)
+ {
+ /* These types have no attached object */
+
+ case ACPI_TYPE_DEVICE:
+
+ AcpiOsPrintf (" Device");
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ AcpiOsPrintf (" Thermal Zone");
+ break;
+
+ default:
+
+ AcpiDbDecodeInternalObject (AcpiNsGetAttachedObject (Node));
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayInternalObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of an internal object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT8 Type;
+
+
+ AcpiOsPrintf ("%p ", ObjDesc);
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("<Null Object>\n");
+ return;
+ }
+
+ /* Decode the object type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_PARSER:
+
+ AcpiOsPrintf ("<Parser> ");
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+
+ AcpiDbDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc);
+ break;
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ Type = ObjDesc->Common.Type;
+ if (Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type);
+ return;
+ }
+
+ /* Decode the ACPI object type */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc));
+
+ /* Decode the refererence */
+
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_LOCAL:
+
+ AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
+ if (WalkState)
+ {
+ ObjDesc = WalkState->LocalVariables
+ [ObjDesc->Reference.Value].Object;
+ AcpiOsPrintf ("%p", ObjDesc);
+ AcpiDbDecodeInternalObject (ObjDesc);
+ }
+ break;
+
+ case ACPI_REFCLASS_ARG:
+
+ AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
+ if (WalkState)
+ {
+ ObjDesc = WalkState->Arguments
+ [ObjDesc->Reference.Value].Object;
+ AcpiOsPrintf ("%p", ObjDesc);
+ AcpiDbDecodeInternalObject (ObjDesc);
+ }
+ break;
+
+ case ACPI_REFCLASS_INDEX:
+
+ switch (ObjDesc->Reference.TargetType)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ AcpiOsPrintf ("%p", ObjDesc->Reference.Object);
+ AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("%p", ObjDesc->Reference.Where);
+ if (!ObjDesc->Reference.Where)
+ {
+ AcpiOsPrintf (" Uninitialized WHERE pointer");
+ }
+ else
+ {
+ AcpiDbDecodeInternalObject (
+ *(ObjDesc->Reference.Where));
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown index target type");
+ break;
+ }
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ if (!ObjDesc->Reference.Object)
+ {
+ AcpiOsPrintf (
+ "Uninitialized reference subobject pointer");
+ break;
+ }
+
+ /* Reference can be to a Node or an Operand object */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+
+ AcpiDbDecodeNode (ObjDesc->Reference.Object);
+ break;
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case ACPI_REFCLASS_NAME:
+
+ AcpiDbDecodeNode (ObjDesc->Reference.Node);
+ break;
+
+ case ACPI_REFCLASS_DEBUG:
+ case ACPI_REFCLASS_TABLE:
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ default: /* Unknown reference class */
+
+ AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class);
+ break;
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("<Obj> ");
+ AcpiDbDecodeInternalObject (ObjDesc);
+ break;
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]",
+ AcpiUtGetDescriptorName (ObjDesc));
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeLocals
+ *
+ * PARAMETERS: WalkState - State for current method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDecodeLocals (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ if (!Node)
+ {
+ AcpiOsPrintf (
+ "No method node (Executing subtree for buffer or opregion)\n");
+ return;
+ }
+
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ AcpiOsPrintf ("Local Variables for method [%4.4s]:\n",
+ AcpiUtGetNodeName (Node));
+
+ for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
+ {
+ ObjDesc = WalkState->LocalVariables[i].Object;
+ AcpiOsPrintf (" Local%X: ", i);
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeArguments
+ *
+ * PARAMETERS: WalkState - State for current method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDecodeArguments (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ if (!Node)
+ {
+ AcpiOsPrintf (
+ "No method node (Executing subtree for buffer or opregion)\n");
+ return;
+ }
+
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ AcpiOsPrintf (
+ "Arguments for Method [%4.4s]: "
+ "(%X arguments defined, max concurrency = %X)\n",
+ AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount,
+ ObjDesc->Method.SyncLevel);
+
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ ObjDesc = WalkState->Arguments[i].Object;
+ AcpiOsPrintf (" Arg%u: ", i);
+ AcpiDbDisplayInternalObject (ObjDesc, WalkState);
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbstats.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbstats.c
new file mode 100644
index 0000000000..7a89b4a7fe
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbstats.c
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ *
+ * Module Name: dbstats - Generation and display of ACPI table statistics
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbstats")
+
+
+/* Local prototypes */
+
+static void
+AcpiDbCountNamespaceObjects (
+ void);
+
+static void
+AcpiDbEnumerateObject (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+static ACPI_STATUS
+AcpiDbClassifyOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+static void
+AcpiDbListInfo (
+ ACPI_MEMORY_LIST *List);
+#endif
+
+
+/*
+ * Statistics subcommands
+ */
+static ACPI_DB_ARGUMENT_INFO AcpiDbStatTypes [] =
+{
+ {"ALLOCATIONS"},
+ {"OBJECTS"},
+ {"MEMORY"},
+ {"MISC"},
+ {"TABLES"},
+ {"SIZES"},
+ {"STACK"},
+ {NULL} /* Must be null terminated */
+};
+
+#define CMD_STAT_ALLOCATIONS 0
+#define CMD_STAT_OBJECTS 1
+#define CMD_STAT_MEMORY 2
+#define CMD_STAT_MISC 3
+#define CMD_STAT_TABLES 4
+#define CMD_STAT_SIZES 5
+#define CMD_STAT_STACK 6
+
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbListInfo
+ *
+ * PARAMETERS: List - Memory list/cache to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about the input memory list or cache.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbListInfo (
+ ACPI_MEMORY_LIST *List)
+{
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ UINT32 Outstanding;
+#endif
+
+ AcpiOsPrintf ("\n%s\n", List->ListName);
+
+ /* MaxDepth > 0 indicates a cache object */
+
+ if (List->MaxDepth > 0)
+ {
+ AcpiOsPrintf (
+ " Cache: [Depth MaxD Avail Size] "
+ "%8.2X %8.2X %8.2X %8.2X\n",
+ List->CurrentDepth,
+ List->MaxDepth,
+ List->MaxDepth - List->CurrentDepth,
+ (List->CurrentDepth * List->ObjectSize));
+ }
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ if (List->MaxDepth > 0)
+ {
+ AcpiOsPrintf (
+ " Cache: [Requests Hits Misses ObjSize] "
+ "%8.2X %8.2X %8.2X %8.2X\n",
+ List->Requests,
+ List->Hits,
+ List->Requests - List->Hits,
+ List->ObjectSize);
+ }
+
+ Outstanding = AcpiDbGetCacheInfo (List);
+
+ if (List->ObjectSize)
+ {
+ AcpiOsPrintf (
+ " Mem: [Alloc Free Max CurSize Outstanding] "
+ "%8.2X %8.2X %8.2X %8.2X %8.2X\n",
+ List->TotalAllocated,
+ List->TotalFreed,
+ List->MaxOccupied,
+ Outstanding * List->ObjectSize,
+ Outstanding);
+ }
+ else
+ {
+ AcpiOsPrintf (
+ " Mem: [Alloc Free Max CurSize Outstanding Total] "
+ "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
+ List->TotalAllocated,
+ List->TotalFreed,
+ List->MaxOccupied,
+ List->CurrentTotalSize,
+ Outstanding,
+ List->TotalSize);
+ }
+#endif
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbEnumerateObject
+ *
+ * PARAMETERS: ObjDesc - Object to be counted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add this object to the global counts, by object type.
+ * Limited recursion handles subobjects and packages, and this
+ * is probably acceptable within the AML debugger only.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbEnumerateObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ return;
+ }
+
+ /* Enumerate this object first */
+
+ AcpiGbl_NumObjects++;
+
+ if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
+ {
+ AcpiGbl_ObjTypeCountMisc++;
+ }
+ else
+ {
+ AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
+ }
+
+ /* Count the sub-objects */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_PACKAGE:
+
+ for (i = 0; i < ObjDesc->Package.Count; i++)
+ {
+ AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
+ }
+ break;
+
+ case ACPI_TYPE_DEVICE:
+
+ AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
+ AcpiDbEnumerateObject (ObjDesc->Device.Handler);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ if (AcpiNsGetSecondaryObject (ObjDesc))
+ {
+ AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
+ }
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
+ AcpiDbEnumerateObject (ObjDesc->Region.Handler);
+ break;
+
+ case ACPI_TYPE_POWER:
+
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
+ AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
+ break;
+
+ default:
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbClassifyOneObject
+ *
+ * PARAMETERS: Callback for WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
+ * the parent namespace node.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbClassifyOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 Type;
+
+
+ AcpiGbl_NumNodes++;
+
+ Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+
+ AcpiDbEnumerateObject (ObjDesc);
+
+ Type = Node->Type;
+ if (Type > ACPI_TYPE_NS_NODE_MAX)
+ {
+ AcpiGbl_NodeTypeCountMisc++;
+ }
+ else
+ {
+ AcpiGbl_NodeTypeCount [Type]++;
+ }
+
+ return (AE_OK);
+
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+ /* TBD: These need to be counted during the initial parsing phase */
+
+ if (AcpiPsIsNamedOp (Op->Opcode))
+ {
+ NumNodes++;
+ }
+
+ if (IsMethod)
+ {
+ NumMethodElements++;
+ }
+
+ NumGrammarElements++;
+ Op = AcpiPsGetDepthNext (Root, Op);
+
+ SizeOfParseTree = (NumGrammarElements - NumMethodElements) *
+ (UINT32) sizeof (ACPI_PARSE_OBJECT);
+ SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
+ SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
+ SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCountNamespaceObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Count and classify the entire namespace, including all
+ * namespace nodes and attached objects.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbCountNamespaceObjects (
+ void)
+{
+ UINT32 i;
+
+
+ AcpiGbl_NumNodes = 0;
+ AcpiGbl_NumObjects = 0;
+
+ AcpiGbl_ObjTypeCountMisc = 0;
+ for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
+ {
+ AcpiGbl_ObjTypeCount [i] = 0;
+ AcpiGbl_NodeTypeCount [i] = 0;
+ }
+
+ (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayStatistics
+ *
+ * PARAMETERS: TypeArg - Subcommand
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display various statistics
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisplayStatistics (
+ char *TypeArg)
+{
+ UINT32 i;
+ UINT32 Temp;
+
+
+ AcpiUtStrupr (TypeArg);
+ Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
+ if (Temp == ACPI_TYPE_NOT_FOUND)
+ {
+ AcpiOsPrintf ("Invalid or unsupported argument\n");
+ return (AE_OK);
+ }
+
+
+ switch (Temp)
+ {
+ case CMD_STAT_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiUtDumpAllocationInfo ();
+#endif
+ break;
+
+ case CMD_STAT_TABLES:
+
+ AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
+ break;
+
+ case CMD_STAT_OBJECTS:
+
+ AcpiDbCountNamespaceObjects ();
+
+ AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
+
+ AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
+ "ACPI_TYPE", "NODES", "OBJECTS");
+
+ for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
+ {
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
+ AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
+ }
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+ AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
+
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
+ AcpiGbl_NumNodes, AcpiGbl_NumObjects);
+ break;
+
+ case CMD_STAT_MEMORY:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
+
+ AcpiDbListInfo (AcpiGbl_GlobalList);
+ AcpiDbListInfo (AcpiGbl_NsNodeList);
+#endif
+
+#ifdef ACPI_USE_LOCAL_CACHE
+ AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
+ AcpiDbListInfo (AcpiGbl_OperandCache);
+ AcpiDbListInfo (AcpiGbl_PsNodeCache);
+ AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
+ AcpiDbListInfo (AcpiGbl_StateCache);
+#endif
+
+ break;
+
+ case CMD_STAT_MISC:
+
+ AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
+ AcpiOsPrintf ("Calls to AcpiPsFind:.. ........% 7ld\n",
+ AcpiGbl_PsFindCount);
+ AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
+ AcpiGbl_NsLookupCount);
+
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("Mutex usage:\n\n");
+ for (i = 0; i < ACPI_NUM_MUTEX; i++)
+ {
+ AcpiOsPrintf ("%-28s: % 7ld\n",
+ AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
+ }
+ break;
+
+ case CMD_STAT_SIZES:
+
+ AcpiOsPrintf ("\nInternal object sizes:\n\n");
+
+ AcpiOsPrintf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON));
+ AcpiOsPrintf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER));
+ AcpiOsPrintf ("String %3d\n", sizeof (ACPI_OBJECT_STRING));
+ AcpiOsPrintf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER));
+ AcpiOsPrintf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
+ AcpiOsPrintf ("BufferField %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
+ AcpiOsPrintf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE));
+ AcpiOsPrintf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT));
+ AcpiOsPrintf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD));
+ AcpiOsPrintf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX));
+ AcpiOsPrintf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION));
+ AcpiOsPrintf ("PowerResource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
+ AcpiOsPrintf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
+ AcpiOsPrintf ("ThermalZone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
+ AcpiOsPrintf ("RegionField %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
+ AcpiOsPrintf ("BankField %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
+ AcpiOsPrintf ("IndexField %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
+ AcpiOsPrintf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
+ AcpiOsPrintf ("Notify %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
+ AcpiOsPrintf ("AddressSpace %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
+ AcpiOsPrintf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA));
+ AcpiOsPrintf ("Data %3d\n", sizeof (ACPI_OBJECT_DATA));
+
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("ParseObject %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
+ AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
+ AcpiOsPrintf ("ParseObjectAsl %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
+ AcpiOsPrintf ("OperandObject %3d\n", sizeof (ACPI_OPERAND_OBJECT));
+ AcpiOsPrintf ("NamespaceNode %3d\n", sizeof (ACPI_NAMESPACE_NODE));
+ AcpiOsPrintf ("AcpiObject %3d\n", sizeof (ACPI_OBJECT));
+
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("Generic State %3d\n", sizeof (ACPI_GENERIC_STATE));
+ AcpiOsPrintf ("Common State %3d\n", sizeof (ACPI_COMMON_STATE));
+ AcpiOsPrintf ("Control State %3d\n", sizeof (ACPI_CONTROL_STATE));
+ AcpiOsPrintf ("Update State %3d\n", sizeof (ACPI_UPDATE_STATE));
+ AcpiOsPrintf ("Scope State %3d\n", sizeof (ACPI_SCOPE_STATE));
+ AcpiOsPrintf ("Parse Scope %3d\n", sizeof (ACPI_PSCOPE_STATE));
+ AcpiOsPrintf ("Package State %3d\n", sizeof (ACPI_PKG_STATE));
+ AcpiOsPrintf ("Thread State %3d\n", sizeof (ACPI_THREAD_STATE));
+ AcpiOsPrintf ("Result Values %3d\n", sizeof (ACPI_RESULT_VALUES));
+ AcpiOsPrintf ("Notify Info %3d\n", sizeof (ACPI_NOTIFY_INFO));
+ break;
+
+ case CMD_STAT_STACK:
+#if defined(ACPI_DEBUG_OUTPUT)
+
+ Temp = (UINT32) ACPI_PTR_DIFF (
+ AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
+
+ AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
+ AcpiOsPrintf ("Entry Stack Pointer %p\n", AcpiGbl_EntryStackPointer);
+ AcpiOsPrintf ("Lowest Stack Pointer %p\n", AcpiGbl_LowestStackPointer);
+ AcpiOsPrintf ("Stack Use %X (%u)\n", Temp, Temp);
+ AcpiOsPrintf ("Deepest Procedure Nesting %u\n", AcpiGbl_DeepestNesting);
+#endif
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbtest.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbtest.c
new file mode 100644
index 0000000000..a859c64019
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbtest.c
@@ -0,0 +1,1141 @@
+/*******************************************************************************
+ *
+ * Module Name: dbtest - Various debug-related tests
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbtest")
+
+
+/* Local prototypes */
+
+static void
+AcpiDbTestAllObjects (
+ void);
+
+static ACPI_STATUS
+AcpiDbTestOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbTestIntegerType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 BitLength);
+
+static ACPI_STATUS
+AcpiDbTestBufferType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 BitLength);
+
+static ACPI_STATUS
+AcpiDbTestStringType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 ByteLength);
+
+static ACPI_STATUS
+AcpiDbReadFromObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE ExpectedType,
+ ACPI_OBJECT **Value);
+
+static ACPI_STATUS
+AcpiDbWriteToObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT *Value);
+
+static void
+AcpiDbEvaluateAllPredefinedNames (
+ char *CountArg);
+
+static ACPI_STATUS
+AcpiDbEvaluateOnePredefinedName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+/*
+ * Test subcommands
+ */
+static ACPI_DB_ARGUMENT_INFO AcpiDbTestTypes [] =
+{
+ {"OBJECTS"},
+ {"PREDEFINED"},
+ {NULL} /* Must be null terminated */
+};
+
+#define CMD_TEST_OBJECTS 0
+#define CMD_TEST_PREDEFINED 1
+
+#define BUFFER_FILL_VALUE 0xFF
+
+/*
+ * Support for the special debugger read/write control methods.
+ * These methods are installed into the current namespace and are
+ * used to read and write the various namespace objects. The point
+ * is to force the AML interpreter do all of the work.
+ */
+#define ACPI_DB_READ_METHOD "\\_T98"
+#define ACPI_DB_WRITE_METHOD "\\_T99"
+
+static ACPI_HANDLE ReadHandle = NULL;
+static ACPI_HANDLE WriteHandle = NULL;
+
+/* ASL Definitions of the debugger read/write control methods */
+
+#if 0
+DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+ Method (_T98, 1, NotSerialized) /* Read */
+ {
+ Return (DeRefOf (Arg0))
+ }
+}
+DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+ Method (_T99, 2, NotSerialized) /* Write */
+ {
+ Store (Arg1, Arg0)
+ }
+}
+#endif
+
+static unsigned char ReadMethodCode[] =
+{
+ 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
+ 0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
+ 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
+ 0x39,0x38,0x01,0xA4,0x83,0x68 /* 00000028 "98...h" */
+};
+
+static unsigned char WriteMethodCode[] =
+{
+ 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
+ 0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
+ 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
+ 0x39,0x39,0x02,0x70,0x69,0x68 /* 00000028 "99.pih" */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteTest
+ *
+ * PARAMETERS: TypeArg - Subcommand
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Execute various debug tests.
+ *
+ * Note: Code is prepared for future expansion of the TEST command.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbExecuteTest (
+ char *TypeArg)
+{
+ UINT32 Temp;
+
+
+ AcpiUtStrupr (TypeArg);
+ Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
+ if (Temp == ACPI_TYPE_NOT_FOUND)
+ {
+ AcpiOsPrintf ("Invalid or unsupported argument\n");
+ return;
+ }
+
+ switch (Temp)
+ {
+ case CMD_TEST_OBJECTS:
+
+ AcpiDbTestAllObjects ();
+ break;
+
+ case CMD_TEST_PREDEFINED:
+
+ AcpiDbEvaluateAllPredefinedNames (NULL);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTestAllObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
+ * namespace by reading/writing/comparing all data objects such
+ * as integers, strings, buffers, fields, buffer fields, etc.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbTestAllObjects (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* Install the debugger read-object control method if necessary */
+
+ if (!ReadHandle)
+ {
+ Status = AcpiInstallMethod (ReadMethodCode);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, Could not install debugger read method\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
+ ACPI_DB_READ_METHOD);
+ return;
+ }
+ }
+
+ /* Install the debugger write-object control method if necessary */
+
+ if (!WriteHandle)
+ {
+ Status = AcpiInstallMethod (WriteMethodCode);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, Could not install debugger write method\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
+ ACPI_DB_WRITE_METHOD);
+ return;
+ }
+ }
+
+ /* Walk the entire namespace, testing each supported named data object */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTestOneObject
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Test one namespace object. Supported types are Integer,
+ * String, Buffer, BufferField, and FieldUnit. All other object
+ * types are simply ignored.
+ *
+ * Note: Support for Packages is not implemented.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbTestOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *RegionObj;
+ ACPI_OBJECT_TYPE LocalType;
+ UINT32 BitLength = 0;
+ UINT32 ByteLength = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ObjDesc = Node->Object;
+
+ /*
+ * For the supported types, get the actual bit length or
+ * byte length. Map the type to one of Integer/String/Buffer.
+ */
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* Integer width is either 32 or 64 */
+
+ LocalType = ACPI_TYPE_INTEGER;
+ BitLength = AcpiGbl_IntegerBitWidth;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ LocalType = ACPI_TYPE_STRING;
+ ByteLength = ObjDesc->String.Length;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ LocalType = ACPI_TYPE_BUFFER;
+ ByteLength = ObjDesc->Buffer.Length;
+ BitLength = ByteLength * 8;
+ break;
+
+ case ACPI_TYPE_FIELD_UNIT:
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ LocalType = ACPI_TYPE_INTEGER;
+ if (ObjDesc)
+ {
+ /*
+ * Returned object will be a Buffer if the field length
+ * is larger than the size of an Integer (32 or 64 bits
+ * depending on the DSDT version).
+ */
+ BitLength = ObjDesc->CommonField.BitLength;
+ ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
+ if (BitLength > AcpiGbl_IntegerBitWidth)
+ {
+ LocalType = ACPI_TYPE_BUFFER;
+ }
+ }
+ break;
+
+ default:
+
+ /* Ignore all other types */
+
+ return (AE_OK);
+ }
+
+ /* Emit the common prefix: Type:Name */
+
+ AcpiOsPrintf ("%14s: %4.4s",
+ AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf (" Ignoring, no attached object\n");
+ return (AE_OK);
+ }
+
+ /*
+ * Check for unsupported region types. Note: AcpiExec simulates
+ * access to SystemMemory, SystemIO, PCI_Config, and EC.
+ */
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ RegionObj = ObjDesc->Field.RegionObj;
+ switch (RegionObj->Region.SpaceId)
+ {
+ case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+ case ACPI_ADR_SPACE_SYSTEM_IO:
+ case ACPI_ADR_SPACE_PCI_CONFIG:
+ case ACPI_ADR_SPACE_EC:
+
+ break;
+
+ default:
+
+ AcpiOsPrintf (" %s space is not supported [%4.4s]\n",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId),
+ RegionObj->Region.Node->Name.Ascii);
+ return (AE_OK);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* At this point, we have resolved the object to one of the major types */
+
+ switch (LocalType)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ Status = AcpiDbTestIntegerType (Node, BitLength);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Status = AcpiDbTestStringType (Node, ByteLength);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiDbTestBufferType (Node, BitLength);
+ break;
+
+ default:
+
+ AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
+ LocalType);
+ break;
+ }
+
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ RegionObj = ObjDesc->Field.RegionObj;
+ AcpiOsPrintf (" (%s)",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId));
+ break;
+
+ default:
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTestIntegerType
+ *
+ * PARAMETERS: Node - Parent NS node for the object
+ * BitLength - Actual length of the object. Used for
+ * support of arbitrary length FieldUnit
+ * and BufferField objects.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
+ * write/read/compare of an arbitrary new value, then performs
+ * a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbTestIntegerType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 BitLength)
+{
+ ACPI_OBJECT *Temp1 = NULL;
+ ACPI_OBJECT *Temp2 = NULL;
+ ACPI_OBJECT *Temp3 = NULL;
+ ACPI_OBJECT WriteValue;
+ UINT64 ValueToWrite;
+ ACPI_STATUS Status;
+
+
+ if (BitLength > 64)
+ {
+ AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
+ return (AE_OK);
+ }
+
+ /* Read the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
+ BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
+ ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
+
+ ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
+ if (Temp1->Integer.Value == ValueToWrite)
+ {
+ ValueToWrite = 0;
+ }
+
+ /* Write a new value */
+
+ WriteValue.Type = ACPI_TYPE_INTEGER;
+ WriteValue.Integer.Value = ValueToWrite;
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the new value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (Temp2->Integer.Value != ValueToWrite)
+ {
+ AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
+ ACPI_FORMAT_UINT64 (ValueToWrite));
+ }
+
+ /* Write back the original value */
+
+ WriteValue.Integer.Value = Temp1->Integer.Value;
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (Temp3->Integer.Value != Temp1->Integer.Value)
+ {
+ AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
+ ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
+ }
+
+Exit:
+ if (Temp1) {AcpiOsFree (Temp1);}
+ if (Temp2) {AcpiOsFree (Temp2);}
+ if (Temp3) {AcpiOsFree (Temp3);}
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTestBufferType
+ *
+ * PARAMETERS: Node - Parent NS node for the object
+ * BitLength - Actual length of the object.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
+ * write/read/compare of an arbitrary new value, then performs
+ * a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbTestBufferType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 BitLength)
+{
+ ACPI_OBJECT *Temp1 = NULL;
+ ACPI_OBJECT *Temp2 = NULL;
+ ACPI_OBJECT *Temp3 = NULL;
+ UINT8 *Buffer;
+ ACPI_OBJECT WriteValue;
+ ACPI_STATUS Status;
+ UINT32 ByteLength;
+ UINT32 i;
+ UINT8 ExtraBits;
+
+
+ ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
+ if (ByteLength == 0)
+ {
+ AcpiOsPrintf (" Ignoring zero length buffer");
+ return (AE_OK);
+ }
+
+ /* Allocate a local buffer */
+
+ Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
+ if (!Buffer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Read the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Emit a few bytes of the buffer */
+
+ AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
+ for (i = 0; ((i < 4) && (i < ByteLength)); i++)
+ {
+ AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
+ }
+ AcpiOsPrintf ("... ");
+
+ /*
+ * Write a new value.
+ *
+ * Handle possible extra bits at the end of the buffer. Can
+ * happen for FieldUnits larger than an integer, but the bit
+ * count is not an integral number of bytes. Zero out the
+ * unused bits.
+ */
+ memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
+ ExtraBits = BitLength % 8;
+ if (ExtraBits)
+ {
+ Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
+ }
+
+ WriteValue.Type = ACPI_TYPE_BUFFER;
+ WriteValue.Buffer.Length = ByteLength;
+ WriteValue.Buffer.Pointer = Buffer;
+
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the new value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
+ {
+ AcpiOsPrintf (" MISMATCH 2: New buffer value");
+ }
+
+ /* Write back the original value */
+
+ WriteValue.Buffer.Length = ByteLength;
+ WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
+
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (memcmp (Temp1->Buffer.Pointer,
+ Temp3->Buffer.Pointer, ByteLength))
+ {
+ AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
+ }
+
+Exit:
+ ACPI_FREE (Buffer);
+ if (Temp1) {AcpiOsFree (Temp1);}
+ if (Temp2) {AcpiOsFree (Temp2);}
+ if (Temp3) {AcpiOsFree (Temp3);}
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTestStringType
+ *
+ * PARAMETERS: Node - Parent NS node for the object
+ * ByteLength - Actual length of the object.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Test read/write for an String-valued object. Performs a
+ * write/read/compare of an arbitrary new value, then performs
+ * a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbTestStringType (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 ByteLength)
+{
+ ACPI_OBJECT *Temp1 = NULL;
+ ACPI_OBJECT *Temp2 = NULL;
+ ACPI_OBJECT *Temp3 = NULL;
+ char *ValueToWrite = "Test String from AML Debugger";
+ ACPI_OBJECT WriteValue;
+ ACPI_STATUS Status;
+
+
+ /* Read the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
+ Temp1->String.Length, Temp1->String.Pointer);
+
+ /* Write a new value */
+
+ WriteValue.Type = ACPI_TYPE_STRING;
+ WriteValue.String.Length = strlen (ValueToWrite);
+ WriteValue.String.Pointer = ValueToWrite;
+
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the new value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (strcmp (Temp2->String.Pointer, ValueToWrite))
+ {
+ AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
+ Temp2->String.Pointer, ValueToWrite);
+ }
+
+ /* Write back the original value */
+
+ WriteValue.String.Length = strlen (Temp1->String.Pointer);
+ WriteValue.String.Pointer = Temp1->String.Pointer;
+
+ Status = AcpiDbWriteToObject (Node, &WriteValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Ensure that we can read back the original value */
+
+ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
+ {
+ AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
+ Temp3->String.Pointer, Temp1->String.Pointer);
+ }
+
+Exit:
+ if (Temp1) {AcpiOsFree (Temp1);}
+ if (Temp2) {AcpiOsFree (Temp2);}
+ if (Temp3) {AcpiOsFree (Temp3);}
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbReadFromObject
+ *
+ * PARAMETERS: Node - Parent NS node for the object
+ * ExpectedType - Object type expected from the read
+ * Value - Where the value read is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Performs a read from the specified object by invoking the
+ * special debugger control method that reads the object. Thus,
+ * the AML interpreter is doing all of the work, increasing the
+ * validity of the test.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbReadFromObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE ExpectedType,
+ ACPI_OBJECT **Value)
+{
+ ACPI_OBJECT *RetValue;
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[2];
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+
+
+ Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
+ Params[0].Reference.ActualType = Node->Type;
+ Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
+
+ ParamObjects.Count = 1;
+ ParamObjects.Pointer = Params;
+
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AcpiEvaluateObject (ReadHandle, NULL,
+ &ParamObjects, &ReturnObj);
+ AcpiGbl_MethodExecuting = FALSE;
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not read from object, %s",
+ AcpiFormatException (Status));
+ return (Status);
+ }
+
+ RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
+
+ switch (RetValue->Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_STRING:
+ /*
+ * Did we receive the type we wanted? Most important for the
+ * Integer/Buffer case (when a field is larger than an Integer,
+ * it should return a Buffer).
+ */
+ if (RetValue->Type != ExpectedType)
+ {
+ AcpiOsPrintf (" Type mismatch: Expected %s, Received %s",
+ AcpiUtGetTypeName (ExpectedType),
+ AcpiUtGetTypeName (RetValue->Type));
+
+ return (AE_TYPE);
+ }
+
+ *Value = RetValue;
+ break;
+
+ default:
+
+ AcpiOsPrintf (" Unsupported return object type, %s",
+ AcpiUtGetTypeName (RetValue->Type));
+
+ AcpiOsFree (ReturnObj.Pointer);
+ return (AE_TYPE);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWriteToObject
+ *
+ * PARAMETERS: Node - Parent NS node for the object
+ * Value - Value to be written
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Performs a write to the specified object by invoking the
+ * special debugger control method that writes the object. Thus,
+ * the AML interpreter is doing all of the work, increasing the
+ * validity of the test.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWriteToObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT *Value)
+{
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[2];
+ ACPI_STATUS Status;
+
+
+ Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
+ Params[0].Reference.ActualType = Node->Type;
+ Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
+
+ /* Copy the incoming user parameter */
+
+ memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
+
+ ParamObjects.Count = 2;
+ ParamObjects.Pointer = Params;
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
+ AcpiGbl_MethodExecuting = FALSE;
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not write to object, %s",
+ AcpiFormatException (Status));
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbEvaluateAllPredefinedNames
+ *
+ * PARAMETERS: CountArg - Max number of methods to execute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Namespace batch execution. Execute predefined names in the
+ * namespace, up to the max count, if specified.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbEvaluateAllPredefinedNames (
+ char *CountArg)
+{
+ ACPI_DB_EXECUTE_WALK Info;
+
+
+ Info.Count = 0;
+ Info.MaxCount = ACPI_UINT32_MAX;
+
+ if (CountArg)
+ {
+ Info.MaxCount = strtoul (CountArg, NULL, 0);
+ }
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbEvaluateOnePredefinedName, NULL,
+ (void *) &Info, NULL);
+
+ AcpiOsPrintf ("Evaluated %u predefined names in the namespace\n", Info.Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbEvaluateOnePredefinedName
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Batch execution module. Currently only executes predefined
+ * ACPI names.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbEvaluateOnePredefinedName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context;
+ char *Pathname;
+ const ACPI_PREDEFINED_INFO *Predefined;
+ ACPI_DEVICE_INFO *ObjInfo;
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS];
+ ACPI_OBJECT *ThisParam;
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+ UINT16 ArgTypeList;
+ UINT8 ArgCount;
+ UINT8 ArgType;
+ UINT32 i;
+
+
+ /* The name must be a predefined ACPI name */
+
+ Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
+ if (!Predefined)
+ {
+ return (AE_OK);
+ }
+
+ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
+ {
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the object info for number of method parameters */
+
+ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (Pathname);
+ return (Status);
+ }
+
+ ParamObjects.Count = 0;
+ ParamObjects.Pointer = NULL;
+
+ if (ObjInfo->Type == ACPI_TYPE_METHOD)
+ {
+ /* Setup default parameters (with proper types) */
+
+ ArgTypeList = Predefined->Info.ArgumentList;
+ ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
+
+ /*
+ * Setup the ACPI-required number of arguments, regardless of what
+ * the actual method defines. If there is a difference, then the
+ * method is wrong and a warning will be issued during execution.
+ */
+ ThisParam = Params;
+ for (i = 0; i < ArgCount; i++)
+ {
+ ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
+ ThisParam->Type = ArgType;
+
+ switch (ArgType)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ ThisParam->Integer.Value = 1;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ ThisParam->String.Pointer =
+ "This is the default argument string";
+ ThisParam->String.Length =
+ strlen (ThisParam->String.Pointer);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
+ ThisParam->Buffer.Length = 48;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ThisParam->Package.Elements = NULL;
+ ThisParam->Package.Count = 0;
+ break;
+
+ default:
+
+ AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
+ Pathname, ArgType);
+ break;
+ }
+
+ ThisParam++;
+ }
+
+ ParamObjects.Count = ArgCount;
+ ParamObjects.Pointer = Params;
+ }
+
+ ACPI_FREE (ObjInfo);
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ /* Do the actual method execution */
+
+ AcpiGbl_MethodExecuting = TRUE;
+
+ Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
+
+ AcpiOsPrintf ("%-32s returned %s\n",
+ Pathname, AcpiFormatException (Status));
+ AcpiGbl_MethodExecuting = FALSE;
+ ACPI_FREE (Pathname);
+
+ /* Ignore status from method execution */
+
+ Status = AE_OK;
+
+ /* Update count, check if we have executed enough methods */
+
+ Info->Count++;
+ if (Info->Count >= Info->MaxCount)
+ {
+ Status = AE_CTRL_TERMINATE;
+ }
+
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbutils.c
new file mode 100644
index 0000000000..8e9725424f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbutils.c
@@ -0,0 +1,512 @@
+/*******************************************************************************
+ *
+ * Module Name: dbutils - AML debugger utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbutils")
+
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_STATUS
+AcpiDbSecondPassParse (
+ ACPI_PARSE_OBJECT *Root);
+
+void
+AcpiDbDumpBuffer (
+ UINT32 Address);
+#endif
+
+static char *Gbl_HexToAscii = "0123456789ABCDEF";
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMatchArgument
+ *
+ * PARAMETERS: UserArgument - User command line
+ * Arguments - Array of commands to match against
+ *
+ * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AcpiDbMatchArgument (
+ char *UserArgument,
+ ACPI_DB_ARGUMENT_INFO *Arguments)
+{
+ UINT32 i;
+
+
+ if (!UserArgument || UserArgument[0] == 0)
+ {
+ return (ACPI_TYPE_NOT_FOUND);
+ }
+
+ for (i = 0; Arguments[i].Name; i++)
+ {
+ if (strstr (Arguments[i].Name, UserArgument) == Arguments[i].Name)
+ {
+ return (i);
+ }
+ }
+
+ /* Argument not recognized */
+
+ return (ACPI_TYPE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetOutputDestination
+ *
+ * PARAMETERS: OutputFlags - Current flags word
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the current destination for debugger output. Also sets
+ * the debug output level accordingly.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetOutputDestination (
+ UINT32 OutputFlags)
+{
+
+ AcpiGbl_DbOutputFlags = (UINT8) OutputFlags;
+
+ if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
+ AcpiGbl_DbOutputToFile)
+ {
+ AcpiDbgLevel = AcpiGbl_DbDebugLevel;
+ }
+ else
+ {
+ AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpExternalObject
+ *
+ * PARAMETERS: ObjDesc - External ACPI object to dump
+ * Level - Nesting level.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the contents of an ACPI external object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpExternalObject (
+ ACPI_OBJECT *ObjDesc,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("[Null Object]\n");
+ return;
+ }
+
+ for (i = 0; i < Level; i++)
+ {
+ AcpiOsPrintf (" ");
+ }
+
+ switch (ObjDesc->Type)
+ {
+ case ACPI_TYPE_ANY:
+
+ AcpiOsPrintf ("[Null Object] (Type=0)\n");
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
+ if (ObjDesc->Buffer.Length)
+ {
+ if (ObjDesc->Buffer.Length > 16)
+ {
+ AcpiOsPrintf ("\n");
+ }
+ AcpiUtDebugDumpBuffer (
+ ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
+ ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT);
+ }
+ else
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("[Package] Contains %u Elements:\n",
+ ObjDesc->Package.Count);
+
+ for (i = 0; i < ObjDesc->Package.Count; i++)
+ {
+ AcpiDbDumpExternalObject (
+ &ObjDesc->Package.Elements[i], Level+1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[Object Reference] = ");
+ AcpiDbDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiOsPrintf ("[Processor]\n");
+ break;
+
+ case ACPI_TYPE_POWER:
+
+ AcpiOsPrintf ("[Power Resource]\n");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbPrepNamestring
+ *
+ * PARAMETERS: Name - String to prepare
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Translate all forward slashes and dots to backslashes.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbPrepNamestring (
+ char *Name)
+{
+
+ if (!Name)
+ {
+ return;
+ }
+
+ AcpiUtStrupr (Name);
+
+ /* Convert a leading forward slash to a backslash */
+
+ if (*Name == '/')
+ {
+ *Name = '\\';
+ }
+
+ /* Ignore a leading backslash, this is the root prefix */
+
+ if (ACPI_IS_ROOT_PREFIX (*Name))
+ {
+ Name++;
+ }
+
+ /* Convert all slash path separators to dots */
+
+ while (*Name)
+ {
+ if ((*Name == '/') ||
+ (*Name == '\\'))
+ {
+ *Name = '.';
+ }
+
+ Name++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbLocalNsLookup
+ *
+ * PARAMETERS: Name - Name to lookup
+ *
+ * RETURN: Pointer to a namespace node, null on failure
+ *
+ * DESCRIPTION: Lookup a name in the ACPI namespace
+ *
+ * Note: Currently begins search from the root. Could be enhanced to use
+ * the current prefix (scope) node as the search beginning point.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiDbLocalNsLookup (
+ char *Name)
+{
+ char *InternalPath;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node = NULL;
+
+
+ AcpiDbPrepNamestring (Name);
+
+ /* Build an internal namestring */
+
+ Status = AcpiNsInternalizeName (Name, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Invalid namestring: %s\n", Name);
+ return (NULL);
+ }
+
+ /*
+ * Lookup the name.
+ * (Uses root node as the search starting point)
+ */
+ Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not locate name: %s, %s\n",
+ Name, AcpiFormatException (Status));
+ }
+
+ ACPI_FREE (InternalPath);
+ return (Node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUint32ToHexString
+ *
+ * PARAMETERS: Value - The value to be converted to string
+ * Buffer - Buffer for result (not less than 11 bytes)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
+ *
+ * NOTE: It is the caller's responsibility to ensure that the length of buffer
+ * is sufficient.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbUint32ToHexString (
+ UINT32 Value,
+ char *Buffer)
+{
+ int i;
+
+
+ if (Value == 0)
+ {
+ strcpy (Buffer, "0");
+ return;
+ }
+
+ Buffer[8] = '\0';
+
+ for (i = 7; i >= 0; i--)
+ {
+ Buffer[i] = Gbl_HexToAscii [Value & 0x0F];
+ Value = Value >> 4;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSecondPassParse
+ *
+ * PARAMETERS: Root - Root of the parse tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
+ * second pass to parse the control methods
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSecondPassParse (
+ ACPI_PARSE_OBJECT *Root)
+{
+ ACPI_PARSE_OBJECT *Op = Root;
+ ACPI_PARSE_OBJECT *Method;
+ ACPI_PARSE_OBJECT *SearchOp;
+ ACPI_PARSE_OBJECT *StartOp;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 BaseAmlOffset;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ AcpiOsPrintf ("Pass two parse ....\n");
+
+ while (Op)
+ {
+ if (Op->Common.AmlOpcode == AML_METHOD_OP)
+ {
+ Method = Op;
+
+ /* Create a new walk state for the parse */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Init the Walk State */
+
+ WalkState->ParserState.Aml =
+ WalkState->ParserState.AmlStart = Method->Named.Data;
+ WalkState->ParserState.AmlEnd =
+ WalkState->ParserState.PkgEnd = Method->Named.Data +
+ Method->Named.Length;
+ WalkState->ParserState.StartScope = Op;
+
+ WalkState->DescendingCallback = AcpiDsLoad1BeginOp;
+ WalkState->AscendingCallback = AcpiDsLoad1EndOp;
+
+ /* Perform the AML parse */
+
+ Status = AcpiPsParseAml (WalkState);
+
+ BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
+ StartOp = (Method->Common.Value.Arg)->Common.Next;
+ SearchOp = StartOp;
+
+ while (SearchOp)
+ {
+ SearchOp->Common.AmlOffset += BaseAmlOffset;
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+ }
+
+ if (Op->Common.AmlOpcode == AML_REGION_OP)
+ {
+ /* TBD: [Investigate] this isn't quite the right thing to do! */
+ /*
+ *
+ * Method = (ACPI_DEFERRED_OP *) Op;
+ * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
+ */
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (Root, Op);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpBuffer
+ *
+ * PARAMETERS: Address - Pointer to the buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a portion of a buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpBuffer (
+ UINT32 Address)
+{
+
+ AcpiOsPrintf ("\nLocation %X:\n", Address);
+
+ AcpiDbgLevel |= ACPI_LV_TABLES;
+ AcpiUtDebugDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
+ ACPI_UINT32_MAX);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbxface.c
new file mode 100644
index 0000000000..09024349ff
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/debugger/dbxface.c
@@ -0,0 +1,543 @@
+/*******************************************************************************
+ *
+ * Module Name: dbxface - AML Debugger external interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbxface")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbStartCommand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiDbMethodEnd (
+ ACPI_WALK_STATE *WalkState);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbStartCommand
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - Current executing Op, from AML interpreter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter debugger command loop
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbStartCommand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+
+
+ /* TBD: [Investigate] are there namespace locking issues here? */
+
+ /* AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); */
+
+ /* Go into the command loop and await next user command */
+
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AE_CTRL_TRUE;
+ while (Status == AE_CTRL_TRUE)
+ {
+ if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED)
+ {
+ /* Handshake with the front-end that gets user command lines */
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Single threaded, we must get a command line ourselves */
+
+ /* Force output to console until a command is entered */
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+ /* Different prompt if method is executing */
+
+ if (!AcpiGbl_MethodExecuting)
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+ }
+ else
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+ }
+
+ /* Get the user input line */
+
+ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
+ ACPI_DB_LINE_BUFFER_SIZE, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While parsing command line"));
+ return (Status);
+ }
+ }
+
+ Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, WalkState, Op);
+ }
+
+ /* AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); */
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSingleStep
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - Current executing op (from aml interpreter)
+ * OpcodeClass - Class of the current AML Opcode
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called just before execution of an AML opcode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSingleStep (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 OpcodeClass)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 OriginalDebugLevel;
+ ACPI_PARSE_OBJECT *DisplayOp;
+ ACPI_PARSE_OBJECT *ParentOp;
+ UINT32 AmlOffset;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Check the abort flag */
+
+ if (AcpiGbl_AbortMethod)
+ {
+ AcpiGbl_AbortMethod = FALSE;
+ return (AE_ABORT_METHOD);
+ }
+
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
+ WalkState->ParserState.AmlStart);
+
+ /* Check for single-step breakpoint */
+
+ if (WalkState->MethodBreakpoint &&
+ (WalkState->MethodBreakpoint <= AmlOffset))
+ {
+ /* Check if the breakpoint has been reached or passed */
+ /* Hit the breakpoint, resume single step, reset breakpoint */
+
+ AcpiOsPrintf ("***Break*** at AML offset %X\n", AmlOffset);
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiGbl_StepToNextCall = FALSE;
+ WalkState->MethodBreakpoint = 0;
+ }
+
+ /* Check for user breakpoint (Must be on exact Aml offset) */
+
+ else if (WalkState->UserBreakpoint &&
+ (WalkState->UserBreakpoint == AmlOffset))
+ {
+ AcpiOsPrintf ("***UserBreakpoint*** at AML offset %X\n",
+ AmlOffset);
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiGbl_StepToNextCall = FALSE;
+ WalkState->MethodBreakpoint = 0;
+ }
+
+ /*
+ * Check if this is an opcode that we are interested in --
+ * namely, opcodes that have arguments
+ */
+ if (Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ return (AE_OK);
+ }
+
+ switch (OpcodeClass)
+ {
+ case AML_CLASS_UNKNOWN:
+ case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */
+
+ return (AE_OK);
+
+ default:
+
+ /* All other opcodes -- continue */
+ break;
+ }
+
+ /*
+ * Under certain debug conditions, display this opcode and its operands
+ */
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiGbl_CmSingleStep) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ AcpiOsPrintf ("\n[AmlDebug] Next AML Opcode to execute:\n");
+ }
+
+ /*
+ * Display this op (and only this op - zero out the NEXT field
+ * temporarily, and disable parser trace output for the duration of
+ * the display because we don't want the extraneous debug output)
+ */
+ OriginalDebugLevel = AcpiDbgLevel;
+ AcpiDbgLevel &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
+ Next = Op->Common.Next;
+ Op->Common.Next = NULL;
+
+
+ DisplayOp = Op;
+ ParentOp = Op->Common.Parent;
+ if (ParentOp)
+ {
+ if ((WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_PREDICATE_EXECUTING))
+ {
+ /*
+ * We are executing the predicate of an IF or WHILE statement
+ * Search upwards for the containing IF or WHILE so that the
+ * entire predicate can be displayed.
+ */
+ while (ParentOp)
+ {
+ if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ DisplayOp = ParentOp;
+ break;
+ }
+ ParentOp = ParentOp->Common.Parent;
+ }
+ }
+ else
+ {
+ while (ParentOp)
+ {
+ if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_ELSE_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_SCOPE_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_METHOD_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ break;
+ }
+ DisplayOp = ParentOp;
+ ParentOp = ParentOp->Common.Parent;
+ }
+ }
+ }
+
+ /* Now we can display it */
+
+#ifdef ACPI_DISASSEMBLER
+ AcpiDmDisassemble (WalkState, DisplayOp, ACPI_UINT32_MAX);
+#endif
+
+ if ((Op->Common.AmlOpcode == AML_IF_OP) ||
+ (Op->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ if (WalkState->ControlState->Common.Value)
+ {
+ AcpiOsPrintf ("Predicate = [True], IF block was executed\n");
+ }
+ else
+ {
+ AcpiOsPrintf ("Predicate = [False], Skipping IF block\n");
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_ELSE_OP)
+ {
+ AcpiOsPrintf ("Predicate = [False], ELSE block was executed\n");
+ }
+
+ /* Restore everything */
+
+ Op->Common.Next = Next;
+ AcpiOsPrintf ("\n");
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ AcpiDbgLevel = OriginalDebugLevel;
+ }
+
+ /* If we are not single stepping, just continue executing the method */
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * If we are executing a step-to-call command,
+ * Check if this is a method call.
+ */
+ if (AcpiGbl_StepToNextCall)
+ {
+ if (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP)
+ {
+ /* Not a method call, just keep executing */
+
+ return (AE_OK);
+ }
+
+ /* Found a method call, stop executing */
+
+ AcpiGbl_StepToNextCall = FALSE;
+ }
+
+ /*
+ * If the next opcode is a method call, we will "step over" it
+ * by default.
+ */
+ if (Op->Common.AmlOpcode == AML_INT_METHODCALL_OP)
+ {
+ /* Force no more single stepping while executing called method */
+
+ AcpiGbl_CmSingleStep = FALSE;
+
+ /*
+ * Set the breakpoint on/before the call, it will stop execution
+ * as soon as we return
+ */
+ WalkState->MethodBreakpoint = 1; /* Must be non-zero! */
+ }
+
+
+ Status = AcpiDbStartCommand (WalkState, Op);
+
+ /* User commands complete, continue execution of the interrupted method */
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInitializeDebugger
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Init and start debugger
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInitializeDebugger (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInitializeDebugger);
+
+
+ /* Init globals */
+
+ AcpiGbl_DbBuffer = NULL;
+ AcpiGbl_DbFilename = NULL;
+ AcpiGbl_DbOutputToFile = FALSE;
+
+ AcpiGbl_DbDebugLevel = ACPI_LV_VERBOSITY2;
+ AcpiGbl_DbConsoleDebugLevel = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
+ AcpiGbl_DbOutputFlags = ACPI_DB_CONSOLE_OUTPUT;
+
+ AcpiGbl_DbOpt_NoIniMethods = FALSE;
+
+ AcpiGbl_DbBuffer = AcpiOsAllocate (ACPI_DEBUG_BUFFER_SIZE);
+ if (!AcpiGbl_DbBuffer)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ memset (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE);
+
+ /* Initial scope is the root */
+
+ AcpiGbl_DbScopeBuf [0] = AML_ROOT_PREFIX;
+ AcpiGbl_DbScopeBuf [1] = 0;
+ AcpiGbl_DbScopeNode = AcpiGbl_RootNode;
+
+ /*
+ * If configured for multi-thread support, the debug executor runs in
+ * a separate thread so that the front end can be in another address
+ * space, environment, or even another machine.
+ */
+ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
+ {
+ /* These were created with one unit, grab it */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get debugger mutex\n");
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get debugger mutex\n");
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Create the debug execution thread to execute commands */
+
+ Status = AcpiOsExecute (OSL_DEBUGGER_THREAD,
+ AcpiDbExecuteThread, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not start debugger thread"));
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInitializeDebugger)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTerminateDebugger
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Stop debugger
+ *
+ ******************************************************************************/
+
+void
+AcpiTerminateDebugger (
+ void)
+{
+
+ if (AcpiGbl_DbBuffer)
+ {
+ AcpiOsFree (AcpiGbl_DbBuffer);
+ AcpiGbl_DbBuffer = NULL;
+ }
+
+ /* Ensure that debug output is now disabled */
+
+ AcpiGbl_DbOutputFlags = ACPI_DB_DISABLE_OUTPUT;
+}
+
+ACPI_EXPORT_SYMBOL (AcpiTerminateDebugger)
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMethodEnd
+ *
+ * PARAMETERS: WalkState - Current walk
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called at method termination
+ *
+ ******************************************************************************/
+
+void
+AcpiDbMethodEnd (
+ ACPI_WALK_STATE *WalkState)
+{
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("<Method Terminating>\n");
+
+ AcpiDbStartCommand (WalkState, NULL);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
new file mode 100644
index 0000000000..1b0f495e3f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
@@ -0,0 +1,1027 @@
+/*******************************************************************************
+ *
+ * Module Name: dmbuffer - AML disassembler, buffer and string support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acutils.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmbuffer")
+
+/* Local prototypes */
+
+static void
+AcpiDmUuid (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmGetHardwareIdType (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmPldBuffer (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount);
+
+
+#define ACPI_BUFFER_BYTES_PER_LINE 8
+
+
+/* Strings for ToPld */
+
+static char *DmPanelList[] =
+{
+ "TOP",
+ "BOTTOM",
+ "LEFT",
+ "RIGHT",
+ "FRONT",
+ "BACK",
+ "UNKNOWN",
+ NULL
+};
+
+static char *DmVerticalPositionList[] =
+{
+ "UPPER",
+ "CENTER",
+ "LOWER",
+ NULL
+};
+
+static char *DmHorizontalPositionList[] =
+{
+ "LEFT",
+ "CENTER",
+ "RIGHT",
+ NULL
+};
+
+static char *DmShapeList[] =
+{
+ "ROUND",
+ "OVAL",
+ "SQUARE",
+ "VERTICALRECTANGLE",
+ "HORIZONTALRECTANGLE",
+ "VERTICALTRAPEZOID",
+ "HORIZONTALTRAPEZOID",
+ "UNKNOWN",
+ "CHAMFERED",
+ NULL
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisasmByteList
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ * ByteData - Pointer to the byte list
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed
+ * with the hex buffer offset.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisasmByteList (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 CurrentIndex;
+ UINT8 BufChar;
+
+
+ if (!ByteCount)
+ {
+ return;
+ }
+
+ for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE)
+ {
+ /* Line indent and offset prefix for each new line */
+
+ AcpiDmIndent (Level);
+ if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE)
+ {
+ AcpiOsPrintf ("/* %04X */ ", i);
+ }
+
+ /* Dump the actual hex values */
+
+ for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
+ {
+ CurrentIndex = i + j;
+ if (CurrentIndex >= ByteCount)
+ {
+ /* Dump fill spaces */
+
+ AcpiOsPrintf (" ");
+ continue;
+ }
+
+ AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]);
+
+ /* Add comma if there are more bytes to display */
+
+ if (CurrentIndex < (ByteCount - 1))
+ {
+ AcpiOsPrintf (",");
+ }
+ else
+ {
+ AcpiOsPrintf (" ");
+ }
+ }
+
+ /* Dump the ASCII equivalents within a comment */
+
+ AcpiOsPrintf (" /* ");
+ for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
+ {
+ CurrentIndex = i + j;
+ if (CurrentIndex >= ByteCount)
+ {
+ break;
+ }
+
+ BufChar = ByteData[CurrentIndex];
+ if (isprint (BufChar))
+ {
+ AcpiOsPrintf ("%c", BufChar);
+ }
+ else
+ {
+ AcpiOsPrintf (".");
+ }
+ }
+
+ /* Finished with this line */
+
+ AcpiOsPrintf (" */\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmByteList
+ *
+ * PARAMETERS: Info - Parse tree walk info
+ * Op - Byte list op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.
+ * Buffer type must be already set in the Op DisasmOpcode.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmByteList (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+
+
+ ByteData = Op->Named.Data;
+ ByteCount = (UINT32) Op->Common.Value.Integer;
+
+ /*
+ * The byte list belongs to a buffer, and can be produced by either
+ * a ResourceTemplate, Unicode, quoted string, or a plain byte list.
+ */
+ switch (Op->Common.Parent->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_RESOURCE:
+
+ AcpiDmResourceTemplate (Info, Op->Common.Parent, ByteData, ByteCount);
+ break;
+
+ case ACPI_DASM_STRING:
+
+ AcpiDmIndent (Info->Level);
+ AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DASM_UUID:
+
+ AcpiDmUuid (Op);
+ break;
+
+ case ACPI_DASM_UNICODE:
+
+ AcpiDmUnicode (Op);
+ break;
+
+ case ACPI_DASM_PLD_METHOD:
+#if 0
+ AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+#endif
+ AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);
+ break;
+
+ case ACPI_DASM_BUFFER:
+ default:
+ /*
+ * Not a resource, string, or unicode string.
+ * Just dump the buffer
+ */
+ AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsUuidBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a UUID
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a UUID
+ *
+ * To help determine whether the buffer is a UUID versus a raw data buffer,
+ * there a are a couple bytes we can look at:
+ *
+ * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
+ *
+ * The variant covered by the UUID specification is indicated by the two most
+ * significant bits of N being 1 0 (i.e., the hexadecimal N will always be
+ * 8, 9, A, or B).
+ *
+ * The variant covered by the UUID specification has five versions. For this
+ * variant, the four bits of M indicates the UUID version (i.e., the
+ * hexadecimal M will be either 1, 2, 3, 4, or 5).
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsUuidBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+
+ /* Byte count must be exactly 16 */
+
+ if (ByteCount != UUID_BUFFER_LENGTH)
+ {
+ return (FALSE);
+ }
+
+ /* Check for valid "M" and "N" values (see function header above) */
+
+ if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */
+ ((ByteData[7] & 0xF0) > 0x50) ||
+ ((ByteData[8] & 0xF0) < 0x80) || /* N={8,9,A,B} */
+ ((ByteData[8] & 0xF0) > 0xB0))
+ {
+ return (FALSE);
+ }
+
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUuid
+ *
+ * PARAMETERS: Op - Byte List op containing a UUID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string.
+ *
+ * Output Format:
+ * In its canonical form, the UUID is represented by a string containing 32
+ * lowercase hexadecimal digits, displayed in 5 groups separated by hyphens.
+ * The complete form is 8-4-4-4-12 for a total of 36 characters (32
+ * alphanumeric characters representing hex digits and 4 hyphens). In bytes,
+ * 4-2-2-2-6. Example:
+ *
+ * ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644")
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUuid (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *Data;
+ const char *Description;
+
+
+ Data = ACPI_CAST_PTR (UINT8, Op->Named.Data);
+
+ /* Emit the 36-byte UUID string in the proper format/order */
+
+ AcpiOsPrintf (
+ "\"%2.2x%2.2x%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")",
+ Data[3], Data[2], Data[1], Data[0],
+ Data[5], Data[4],
+ Data[7], Data[6],
+ Data[8], Data[9],
+ Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);
+
+ /* Dump the UUID description string if available */
+
+ Description = AcpiAhMatchUuid (Data);
+ if (Description)
+ {
+ AcpiOsPrintf (" /* %s */", Description);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsUnicodeBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a UNICODE string
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a Unicode string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsUnicodeBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ UINT32 WordCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+ WordCount = ACPI_DIV_2 (ByteCount);
+
+ /*
+ * Unicode string must have an even number of bytes and last
+ * word must be zero
+ */
+ if ((!ByteCount) ||
+ (ByteCount < 4) ||
+ (ByteCount & 1) ||
+ ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)
+ {
+ return (FALSE);
+ }
+
+ /* For each word, 1st byte must be ascii (1-0x7F), 2nd byte must be zero */
+
+ for (i = 0; i < (ByteCount - 2); i += 2)
+ {
+ if ((ByteData[i] == 0) ||
+ (ByteData[i] > 0x7F) ||
+ (ByteData[(ACPI_SIZE) i + 1] != 0))
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsStringBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a ASCII string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsStringBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+
+ /* Last byte must be the null terminator */
+
+ if ((!ByteCount) ||
+ (ByteCount < 2) ||
+ (ByteData[ByteCount-1] != 0))
+ {
+ return (FALSE);
+ }
+
+ for (i = 0; i < (ByteCount - 1); i++)
+ {
+ /* TBD: allow some escapes (non-ascii chars).
+ * they will be handled in the string output routine
+ */
+
+ if (!isprint (ByteData[i]))
+ {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsPldBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a _PLD structure
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsPldBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ ParentOp = Op->Common.Parent;
+ if (!ParentOp)
+ {
+ return (FALSE);
+ }
+
+ /* Check for form: Name(_PLD, Buffer() {}). Not legal, however */
+
+ if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
+ {
+ Node = ParentOp->Common.Node;
+
+ if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
+ {
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+ }
+
+ return (FALSE);
+ }
+
+ /* Check for proper form: Name(_PLD, Package() {Buffer() {}}) */
+
+ if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP)
+ {
+ ParentOp = ParentOp->Common.Parent;
+ if (!ParentOp)
+ {
+ return (FALSE);
+ }
+
+ if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
+ {
+ Node = ParentOp->Common.Node;
+
+ if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
+ {
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+ }
+ }
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFindNameByIndex
+ *
+ * PARAMETERS: Index - Index of array to check
+ * List - Array to reference
+ *
+ * RETURN: String from List or empty string
+ *
+ * DESCRIPTION: Finds and returns the char string located at the given index
+ * position in List.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmFindNameByIndex (
+ UINT64 Index,
+ char **List)
+{
+ char *Str;
+ UINT32 i;
+
+
+ /* Bounds check */
+
+ Str = List[0];
+ i = 0;
+
+ while(Str)
+ {
+ i++;
+ Str = List[i];
+ }
+
+ if (Index >= i)
+ {
+ /* TBD: Add error msg */
+
+ return ("");
+ }
+
+ return (List[Index]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPldBuffer
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ * ByteData - Pointer to the byte list
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump and format the contents of a _PLD buffer object
+ *
+ ******************************************************************************/
+
+#define ACPI_PLD_OUTPUT08 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT08P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT24 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUTSTR "%*.s%-18s = \"%s\",\n", ACPI_MUL_4 (Level), " "
+
+static void
+AcpiDmPldBuffer (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ ACPI_PLD_INFO *PldInfo;
+ ACPI_STATUS Status;
+
+
+ /* Check for valid byte count */
+
+ if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)
+ {
+ return;
+ }
+
+ /* Convert _PLD buffer to local _PLD struct */
+
+ Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+
+ /* First 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Revision", PldInfo->Revision);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_IgnoreColor", PldInfo->IgnoreColor);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Red", PldInfo->Red);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Green", PldInfo->Green);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Blue", PldInfo->Blue);
+
+ /* Second 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Width", PldInfo->Width);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Height", PldInfo->Height);
+
+ /* Third 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_UserVisible", PldInfo->UserVisible);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Dock", PldInfo->Dock);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Lid", PldInfo->Lid);
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Panel",
+ AcpiDmFindNameByIndex(PldInfo->Panel, DmPanelList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition",
+ AcpiDmFindNameByIndex(PldInfo->VerticalPosition, DmVerticalPositionList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition",
+ AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, DmHorizontalPositionList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape",
+ AcpiDmFindNameByIndex(PldInfo->Shape, DmShapeList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupOrientation", PldInfo->GroupOrientation);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupToken", PldInfo->GroupToken);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupPosition", PldInfo->GroupPosition);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Bay", PldInfo->Bay);
+
+ /* Fourth 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Ejectable", PldInfo->Ejectable);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_EjectRequired", PldInfo->OspmEjectRequired);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CabinetNumber", PldInfo->CabinetNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CardCageNumber", PldInfo->CardCageNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Reference", PldInfo->Reference);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Rotation", PldInfo->Rotation);
+
+ if (ByteCount >= ACPI_PLD_REV2_BUFFER_SIZE)
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order);
+
+ /* Fifth 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);
+ }
+ else /* Rev 1 buffer */
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order);
+ }
+
+ ACPI_FREE (PldInfo);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUnicode
+ *
+ * PARAMETERS: Op - Byte List op containing Unicode string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove
+ * the extra zero bytes).
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT16 *WordData;
+ UINT32 WordCount;
+ UINT32 i;
+ int OutputValue;
+
+
+ /* Extract the buffer info as a WORD buffer */
+
+ WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);
+ WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));
+
+ /* Write every other byte as an ASCII character */
+
+ AcpiOsPrintf ("\"");
+ for (i = 0; i < (WordCount - 1); i++)
+ {
+ OutputValue = (int) WordData[i];
+
+ /* Handle values that must be escaped */
+
+ if ((OutputValue == '\"') ||
+ (OutputValue == '\\'))
+ {
+ AcpiOsPrintf ("\\%c", OutputValue);
+ }
+ else if (!isprint (OutputValue))
+ {
+ AcpiOsPrintf ("\\x%2.2X", OutputValue);
+ }
+ else
+ {
+ AcpiOsPrintf ("%c", OutputValue);
+ }
+ }
+
+ AcpiOsPrintf ("\")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetHardwareIdType
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine the type of the argument to a _HID or _CID
+ * 1) Strings are allowed
+ * 2) If Integer, determine if it is a valid EISAID
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGetHardwareIdType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 BigEndianId;
+ UINT32 Prefix[3];
+ UINT32 i;
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_STRING_OP:
+
+ /* Mark this string as an _HID/_CID string */
+
+ Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING;
+ break;
+
+ case AML_WORD_OP:
+ case AML_DWORD_OP:
+
+ /* Determine if a Word/Dword is a valid encoded EISAID */
+
+ /* Swap from little-endian to big-endian to simplify conversion */
+
+ BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);
+
+ /* Create the 3 leading ASCII letters */
+
+ Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;
+ Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;
+ Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;
+
+ /* Verify that all 3 are ascii and alpha */
+
+ for (i = 0; i < 3; i++)
+ {
+ if (!ACPI_IS_ASCII (Prefix[i]) ||
+ !isalpha (Prefix[i]))
+ {
+ return;
+ }
+ }
+
+ /* Mark this node as convertable to an EISA ID string */
+
+ Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckForHardwareId
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine if a Name() Op is a _HID/_CID.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCheckForHardwareId (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Get the NameSegment */
+
+ Name = AcpiPsGetName (Op);
+ if (!Name)
+ {
+ return;
+ }
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Check for _HID - has one argument */
+
+ if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID))
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ return;
+ }
+
+ /* Exit if not _CID */
+
+ if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID))
+ {
+ return;
+ }
+
+ /* _CID can contain a single argument or a package */
+
+ if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ return;
+ }
+
+ /* _CID with Package: get the package length, check all elements */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Don't need to use the length, just walk the peer list */
+
+ NextOp = NextOp->Common.Next;
+ while (NextOp)
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ NextOp = NextOp->Common.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecompressEisaId
+ *
+ * PARAMETERS: EncodedId - Raw encoded EISA ID.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String
+ * and emit the correct ASL statement. If the ID is known, emit
+ * a description of the ID as a comment.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecompressEisaId (
+ UINT32 EncodedId)
+{
+ char IdBuffer[ACPI_EISAID_STRING_SIZE];
+ const AH_DEVICE_ID *Info;
+
+
+ /* Convert EISAID to a string an emit the statement */
+
+ AcpiExEisaIdToString (IdBuffer, EncodedId);
+ AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer);
+
+ /* If we know about the ID, emit the description */
+
+ Info = AcpiAhMatchHardwareId (IdBuffer);
+ if (Info)
+ {
+ AcpiOsPrintf (" /* %s */", Info->Description);
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
new file mode 100644
index 0000000000..e758283597
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
@@ -0,0 +1,826 @@
+/*******************************************************************************
+ *
+ * Module Name: dmcstyle - Support for C-style operator disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmcstyle")
+
+
+/* Local prototypes */
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AslOpcode);
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target);
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Op);
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckForSymbolicOpcode
+ *
+ * PARAMETERS: Op - Current parse object
+ * Walk - Current parse tree walk info
+ *
+ * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
+ *
+ * DESCRIPTION: This is the main code that implements disassembly of AML code
+ * to C-style operators. Called during descending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCheckForSymbolicOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OP_WALK_INFO *Info)
+{
+ char *OperatorSymbol = NULL;
+ ACPI_PARSE_OBJECT *Child1;
+ ACPI_PARSE_OBJECT *Child2;
+ ACPI_PARSE_OBJECT *Target;
+
+
+ /* Exit immediately if ASL+ not enabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ return (FALSE);
+ }
+
+ /* Get the first operand */
+
+ Child1 = AcpiPsGetArg (Op, 0);
+ if (!Child1)
+ {
+ return (FALSE);
+ }
+
+ /* Get the second operand */
+
+ Child2 = Child1->Common.Next;
+
+ /* Setup the operator string for this opcode */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ OperatorSymbol = " + ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ OperatorSymbol = " - ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ OperatorSymbol = " * ";
+ break;
+
+ case AML_DIVIDE_OP:
+ OperatorSymbol = " / ";
+ break;
+
+ case AML_MOD_OP:
+ OperatorSymbol = " % ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ OperatorSymbol = " << ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ OperatorSymbol = " >> ";
+ break;
+
+ case AML_BIT_AND_OP:
+ OperatorSymbol = " & ";
+ break;
+
+ case AML_BIT_OR_OP:
+ OperatorSymbol = " | ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ OperatorSymbol = " ^ ";
+ break;
+
+ /* Logical operators, no target */
+
+ case AML_LAND_OP:
+ OperatorSymbol = " && ";
+ break;
+
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " == ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " > ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " < ";
+ break;
+
+ case AML_LOR_OP:
+ OperatorSymbol = " || ";
+ break;
+
+ case AML_LNOT_OP:
+ /*
+ * Check for the LNOT sub-opcodes. These correspond to
+ * LNotEqual, LLessEqual, and LGreaterEqual. There are
+ * no actual AML opcodes for these operators.
+ */
+ switch (Child1->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " != ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " <= ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " >= ";
+ break;
+
+ default:
+
+ /* Unary LNOT case, emit "!" immediately */
+
+ AcpiOsPrintf ("!");
+ return (TRUE);
+ }
+
+ Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+
+ /* Save symbol string in the next child (not peer) */
+
+ Child2 = AcpiPsGetArg (Child1, 0);
+ if (!Child2)
+ {
+ return (FALSE);
+ }
+
+ Child2->Common.OperatorSymbol = OperatorSymbol;
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+ Child1->Common.OperatorSymbol = " [";
+ Child2->Common.OperatorSymbol = "]";
+ break;
+#endif
+
+ /* Unary operators */
+
+ case AML_DECREMENT_OP:
+ OperatorSymbol = "--";
+ break;
+
+ case AML_INCREMENT_OP:
+ OperatorSymbol = "++";
+ break;
+
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ OperatorSymbol = NULL;
+ break;
+
+ default:
+ return (FALSE);
+ }
+
+ if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
+ {
+ return (TRUE);
+ }
+
+ /*
+ * This is the key to how the disassembly of the C-style operators
+ * works. We save the operator symbol in the first child, thus
+ * deferring symbol output until after the first operand has been
+ * emitted.
+ */
+ if (!Child1->Common.OperatorSymbol)
+ {
+ Child1->Common.OperatorSymbol = OperatorSymbol;
+ }
+
+ /*
+ * Check for a valid target as the 3rd (or sometimes 2nd) operand
+ *
+ * Compound assignment operator support:
+ * Attempt to optimize constructs of the form:
+ * Add (Local1, 0xFF, Local1)
+ * to:
+ * Local1 += 0xFF
+ *
+ * Only the math operators and Store() have a target.
+ * Logicals have no target.
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+
+ /* Target is 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
+ {
+ /*
+ * Divide has an extra target operand (Remainder).
+ * If this extra target is specified, it cannot be converted
+ * to a C-style operator
+ */
+ if (AcpiDmIsValidTarget (Target))
+ {
+ Child1->Common.OperatorSymbol = NULL;
+ return (FALSE);
+ }
+
+ Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ Target = Target->Common.Next;
+ }
+
+ /* Parser should ensure there is at least a placeholder target */
+
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (!AcpiDmIsValidTarget (Target))
+ {
+ /* Not a valid target (placeholder only, from parser) */
+ break;
+ }
+
+ /*
+ * Promote the target up to the first child in the parse
+ * tree. This is done because the target will be output
+ * first, in the form:
+ * <Target> = Operands...
+ */
+ AcpiDmPromoteTarget (Op, Target);
+
+ /* Check operands for conversion to a "Compound Assignment" */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ /* Commutative operators */
+
+ case AML_ADD_OP:
+ case AML_MULTIPLY_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ /*
+ * For the commutative operators, we can convert to a
+ * compound statement only if at least one (either) operand
+ * is the same as the target.
+ *
+ * Add (A, B, A) --> A += B
+ * Add (B, A, A) --> A += B
+ * Add (B, C, A) --> A = (B + C)
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
+ (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ /* Non-commutative operators */
+
+ case AML_SUBTRACT_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ /*
+ * For the non-commutative operators, we can convert to a
+ * compound statement only if the target is the same as the
+ * first operand.
+ *
+ * Subtract (A, B, A) --> A -= B
+ * Subtract (B, A, A) --> A = (B - A)
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * If we are within a C-style expression, emit an extra open
+ * paren. Implemented by examining the parent op.
+ */
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
+ AcpiOsPrintf ("(");
+ break;
+
+ default:
+ break;
+ }
+
+ /* Normal output for ASL/AML operators with a target operand */
+
+ Target->Common.OperatorSymbol = " = (";
+ return (TRUE);
+
+ /* Binary operators, no parens */
+
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+
+ /* Target is optional, 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (AcpiDmIsValidTarget (Target))
+ {
+ AcpiDmPromoteTarget (Op, Target);
+
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ }
+ return (TRUE);
+#endif
+
+ case AML_STORE_OP:
+ /*
+ * Target is the 2nd operand.
+ * We know the target is valid, it is not optional.
+ * In the parse tree, simply swap the target with the
+ * source so that the target is processed first.
+ */
+ Target = Child1->Common.Next;
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ AcpiDmPromoteTarget (Op, Target);
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ return (TRUE);
+
+ case AML_BIT_NOT_OP:
+
+ /* Target is optional, 2nd operand */
+
+ Target = Child1->Common.Next;
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (AcpiDmIsValidTarget (Target))
+ {
+ /* Valid target, not a placeholder */
+
+ AcpiDmPromoteTarget (Op, Target);
+ Target->Common.OperatorSymbol = " = ~";
+ }
+ else
+ {
+ /* No target. Emit this prefix operator immediately */
+
+ AcpiOsPrintf ("~");
+ }
+ return (TRUE);
+
+ default:
+ break;
+ }
+
+ /* All other operators, emit an open paren */
+
+ AcpiOsPrintf ("(");
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCloseOperator
+ *
+ * PARAMETERS: Op - Current parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Closes an operator by adding a closing parentheses if and
+ * when necessary. Called during ascending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCloseOperator (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* Always emit paren if ASL+ disassembly disabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ AcpiOsPrintf (")");
+ return;
+ }
+
+ /* Check if we need to add an additional closing paren */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ /* Emit paren only if this is not a compound assignment */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
+ {
+ return;
+ }
+
+ /* Emit extra close paren for assignment within an expression */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
+ {
+ AcpiOsPrintf (")");
+ }
+ break;
+
+
+ /* No need for parens for these */
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+#endif
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ case AML_LNOT_OP:
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ return;
+
+ default:
+
+ /* Always emit paren for non-ASL+ operators */
+ break;
+ }
+
+ AcpiOsPrintf (")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetCompoundSymbol
+ *
+ * PARAMETERS: AslOpcode
+ *
+ * RETURN: String containing the compound assignment symbol
+ *
+ * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
+ * return the appropriate operator string.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AmlOpcode)
+{
+ char *Symbol;
+
+
+ switch (AmlOpcode)
+ {
+ case AML_ADD_OP:
+ Symbol = " += ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ Symbol = " -= ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ Symbol = " *= ";
+ break;
+
+ case AML_DIVIDE_OP:
+ Symbol = " /= ";
+ break;
+
+ case AML_MOD_OP:
+ Symbol = " %= ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ Symbol = " <<= ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ Symbol = " >>= ";
+ break;
+
+ case AML_BIT_AND_OP:
+ Symbol = " &= ";
+ break;
+
+ case AML_BIT_OR_OP:
+ Symbol = " |= ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ Symbol = " ^= ";
+ break;
+
+ default:
+
+ /* No operator string for all other opcodes */
+ return (NULL);
+ }
+
+ return (Symbol);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPromoteTarget
+ *
+ * PARAMETERS: Op - Operator parse object
+ * Target - Target associate with the Op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Transform the parse tree by moving the target up to the first
+ * child of the Op.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target)
+{
+ ACPI_PARSE_OBJECT *Child;
+
+
+ /* Link target directly to the Op as first child */
+
+ Child = Op->Common.Value.Arg;
+ Op->Common.Value.Arg = Target;
+ Target->Common.Next = Child;
+
+ /* Find the last peer, it is linked to the target. Unlink it. */
+
+ while (Child->Common.Next != Target)
+ {
+ Child = Child->Common.Next;
+ }
+
+ Child->Common.Next = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsValidTarget
+ *
+ * PARAMETERS: Target - Target Op from the parse tree
+ *
+ * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
+ * Op that was inserted by the parser.
+ *
+ * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
+ * In other words, determine if the optional target is used or
+ * not. Note: If Target is NULL, something is seriously wrong,
+ * probably with the parse tree.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Target)
+{
+
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (Target->Common.Value.Arg == NULL))
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsTargetAnOperand
+ *
+ * PARAMETERS: Target - Target associated with the expression
+ * Operand - An operand associated with expression
+ *
+ * RETURN: TRUE if expression can be converted to a compound assignment.
+ * FALSE otherwise.
+ *
+ * DESCRIPTION: Determine if the Target duplicates the operand, in order to
+ * detect if the expression can be converted to a compound
+ * assigment. (+=, *=, etc.)
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ BOOLEAN Same;
+
+
+ /*
+ * Opcodes must match. Note: ignoring the difference between nameseg
+ * and namepath for now. May be needed later.
+ */
+ if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
+ {
+ return (FALSE);
+ }
+
+ /* Nodes should match, even if they are NULL */
+
+ if (Target->Common.Node != Operand->Common.Node)
+ {
+ return (FALSE);
+ }
+
+ /* Determine if a child exists */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
+ Operand->Common.Value.Arg, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Check the next peer, as long as we are not at the top level */
+
+ if ((!TopLevel) &&
+ Target->Common.Next)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
+ Operand->Common.Next, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Supress the duplicate operand at the top-level */
+
+ if (TopLevel)
+ {
+ Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ }
+ return (TRUE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c
new file mode 100644
index 0000000000..f1597e35bf
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c
@@ -0,0 +1,263 @@
+/******************************************************************************
+ *
+ * Module Name: dmdeferred - Disassembly of deferred AML opcodes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmdeferred")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDmDeferredParse (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *Aml,
+ UINT32 AmlLength);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDmParseDeferredOps
+ *
+ * PARAMETERS: Root - Root of the parse tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiDmParseDeferredOps (
+ ACPI_PARSE_OBJECT *Root)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_PARSE_OBJECT *Op = Root;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Traverse the entire parse tree */
+
+ while (Op)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_DEFER))
+ {
+ Op = AcpiPsGetDepthNext (Root, Op);
+ continue;
+ }
+
+ /* Now we know we have a deferred opcode */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ Status = AcpiDmDeferredParse (Op, Op->Named.Data, Op->Named.Length);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ /* We don't need to do anything for these deferred opcodes */
+
+ case AML_REGION_OP:
+ case AML_DATA_REGION_OP:
+ case AML_CREATE_QWORD_FIELD_OP:
+ case AML_CREATE_DWORD_FIELD_OP:
+ case AML_CREATE_WORD_FIELD_OP:
+ case AML_CREATE_BYTE_FIELD_OP:
+ case AML_CREATE_BIT_FIELD_OP:
+ case AML_CREATE_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]",
+ Op->Common.AmlOpcode));
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (Root, Op);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDmDeferredParse
+ *
+ * PARAMETERS: Op - Root Op of the deferred opcode
+ * Aml - Pointer to the raw AML
+ * AmlLength - Length of the AML
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse one deferred opcode
+ * (Methods, operation regions, etc.)
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDeferredParse (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *Aml,
+ UINT32 AmlLength)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *SearchOp;
+ ACPI_PARSE_OBJECT *StartOp;
+ ACPI_PARSE_OBJECT *NewRootOp;
+ ACPI_PARSE_OBJECT *ExtraOp;
+
+
+ ACPI_FUNCTION_TRACE (DmDeferredParse);
+
+
+ if (!Aml || !AmlLength)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n",
+ Op->Common.AmlOpName, (char *) &Op->Named.Name));
+
+ /* Need a new walk state to parse the AML */
+
+ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
+ if (!WalkState)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
+ AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Parse the AML for this deferred opcode */
+
+ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
+ WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
+ Status = AcpiPsParseAml (WalkState);
+
+ StartOp = (Op->Common.Value.Arg)->Common.Next;
+ SearchOp = StartOp;
+ while (SearchOp)
+ {
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+
+ /*
+ * For Buffer and Package opcodes, link the newly parsed subtree
+ * into the main parse tree
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_PACKAGE_OP:
+
+ ExtraOp = Op->Common.Value.Arg;
+ NewRootOp = ExtraOp->Common.Next;
+ ACPI_FREE (ExtraOp);
+ break;
+
+ case AML_VAR_PACKAGE_OP:
+ case AML_BUFFER_OP:
+ default:
+
+ NewRootOp = Op->Common.Value.Arg;
+ break;
+ }
+
+ Op->Common.Value.Arg = NewRootOp->Common.Value.Arg;
+
+ /* Must point all parents to the main tree */
+
+ StartOp = Op;
+ SearchOp = StartOp;
+ while (SearchOp)
+ {
+ if (SearchOp->Common.Parent == NewRootOp)
+ {
+ SearchOp->Common.Parent = Op;
+ }
+
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+
+ ACPI_FREE (NewRootOp);
+ break;
+
+ default:
+
+ break;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmnames.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmnames.c
new file mode 100644
index 0000000000..5537778d0b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmnames.c
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ *
+ * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmnames")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: Final length of name
+ *
+ * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmDumpName (
+ UINT32 Name)
+{
+ UINT32 i;
+ UINT32 Length;
+ char NewName[4];
+
+
+ /* Copy name locally in case the original name is not writeable */
+
+ *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
+
+ /* Ensure that the name is printable, even if we have to fix it */
+
+ AcpiUtRepairName (NewName);
+
+ /* Remove all trailing underscores from the name */
+
+ Length = ACPI_NAME_SIZE;
+ for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
+ {
+ if (NewName[i] == '_')
+ {
+ Length--;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Dump the name, up to the start of the trailing underscores */
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%c", NewName[i]);
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsDisplayObjectPathname
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Object whose pathname is to be obtained
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Diplay the pathname associated with a named object. Two
+ * versions. One searches the parse tree (for parser-only
+ * applications suchas AcpiDump), and the other searches the
+ * ACPI namespace (the parse tree is probably deleted)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsDisplayObjectPathname (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_BUFFER Buffer;
+ UINT32 DebugLevel;
+
+
+ /* Save current debug level so we don't get extraneous debug output */
+
+ DebugLevel = AcpiDbgLevel;
+ AcpiDbgLevel = 0;
+
+ /* Just get the Node out of the Op object */
+
+ Node = Op->Common.Node;
+ if (!Node)
+ {
+ /* Node not defined in this scope, look it up */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * We can't get the pathname since the object
+ * is not in the namespace. This can happen during single
+ * stepping where a dynamic named object is *about* to be created.
+ */
+ AcpiOsPrintf (" [Path not found]");
+ goto Exit;
+ }
+
+ /* Save it for next time. */
+
+ Op->Common.Node = Node;
+ }
+
+ /* Convert NamedDesc/handle to a full pathname */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("****Could not get pathname****)");
+ goto Exit;
+ }
+
+ AcpiOsPrintf (" (Path %s)", (char *) Buffer.Pointer);
+ ACPI_FREE (Buffer.Pointer);
+
+
+Exit:
+ /* Restore the debug level */
+
+ AcpiDbgLevel = DebugLevel;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNamestring
+ *
+ * PARAMETERS: Name - ACPI Name string to store
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
+ *
+ ******************************************************************************/
+
+void
+AcpiDmNamestring (
+ char *Name)
+{
+ UINT32 SegCount;
+
+
+ if (!Name)
+ {
+ return;
+ }
+
+ /* Handle all Scope Prefix operators */
+
+ while (ACPI_IS_ROOT_PREFIX (ACPI_GET8 (Name)) ||
+ ACPI_IS_PARENT_PREFIX (ACPI_GET8 (Name)))
+ {
+ /* Append prefix character */
+
+ AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
+ Name++;
+ }
+
+ switch (ACPI_GET8 (Name))
+ {
+ case 0:
+
+ SegCount = 0;
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+
+ SegCount = 2;
+ Name++;
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ SegCount = (UINT32) ACPI_GET8 (Name + 1);
+ Name += 2;
+ break;
+
+ default:
+
+ SegCount = 1;
+ break;
+ }
+
+ while (SegCount)
+ {
+ /* Append Name segment */
+
+ AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
+
+ SegCount--;
+ if (SegCount)
+ {
+ /* Not last name, append dot separator */
+
+ AcpiOsPrintf (".");
+ }
+ Name += ACPI_NAME_SIZE;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayPath
+ *
+ * PARAMETERS: Op - Named Op whose path is to be constructed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Walk backwards from current scope and display the name
+ * of each previous level of scope up to the root scope
+ * (like "pwd" does with file systems)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Prev;
+ ACPI_PARSE_OBJECT *Search;
+ UINT32 Name;
+ BOOLEAN DoDot = FALSE;
+ ACPI_PARSE_OBJECT *NamePath;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ /* We are only interested in named objects */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_NSNODE))
+ {
+ return;
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Field creation - check for a fully qualified namepath */
+
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String) &&
+ (ACPI_IS_ROOT_PREFIX (NamePath->Common.Value.String[0])))
+ {
+ AcpiDmNamestring (NamePath->Common.Value.String);
+ return;
+ }
+ }
+
+ Prev = NULL; /* Start with Root Node */
+
+ while (Prev != Op)
+ {
+ /* Search upwards in the tree to find scope with "prev" as its parent */
+
+ Search = Op;
+ for (; ;)
+ {
+ if (Search->Common.Parent == Prev)
+ {
+ break;
+ }
+
+ /* Go up one level */
+
+ Search = Search->Common.Parent;
+ }
+
+ if (Prev)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_FIELD))
+ {
+ /* Below root scope, append scope name */
+
+ if (DoDot)
+ {
+ /* Append dot */
+
+ AcpiOsPrintf (".");
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String))
+ {
+ AcpiDmDumpName (NamePath->Common.Value.String);
+ }
+ }
+ else
+ {
+ Name = AcpiPsGetName (Search);
+ AcpiDmDumpName ((char *) &Name);
+ }
+
+ DoDot = TRUE;
+ }
+ }
+ Prev = Search;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmValidateName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Lookup the name
+ *
+ ******************************************************************************/
+
+void
+AcpiDmValidateName (
+ char *Name,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *TargetOp;
+
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ if (!Op->Common.Node)
+ {
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ TargetOp = AcpiPsFind (Op, Name, 0, 0);
+ if (!TargetOp)
+ {
+ /*
+ * Didn't find the name in the parse tree. This may be
+ * a problem, or it may simply be one of the predefined names
+ * (such as _OS_). Rather than worry about looking up all
+ * the predefined names, just display the name as given
+ */
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmopcode.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
new file mode 100644
index 0000000000..9df0b37a58
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
@@ -0,0 +1,978 @@
+/*******************************************************************************
+ *
+ * Module Name: dmopcode - AML disassembler, specific AML opcodes
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmopcode")
+
+
+/* Local prototypes */
+
+static void
+AcpiDmMatchKeyword (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayTargetPathname
+ *
+ * PARAMETERS: Op - Parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: For AML opcodes that have a target operand, display the full
+ * pathname for the target, in a comment field. Handles Return()
+ * statements also.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayTargetPathname (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *PrevOp = NULL;
+ char *Pathname;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (Op->Common.AmlOpcode == AML_RETURN_OP)
+ {
+ PrevOp = Op->Asl.Value.Arg;
+ }
+ else
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_HAS_TARGET))
+ {
+ return;
+ }
+
+ /* Target is the last Op in the arg list */
+
+ NextOp = Op->Asl.Value.Arg;
+ while (NextOp)
+ {
+ PrevOp = NextOp;
+ NextOp = PrevOp->Asl.Next;
+ }
+ }
+
+ if (!PrevOp)
+ {
+ return;
+ }
+
+ /* We must have a namepath AML opcode */
+
+ if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* A null string is the "no target specified" case */
+
+ if (!PrevOp->Asl.Value.String)
+ {
+ return;
+ }
+
+ /* No node means "unresolved external reference" */
+
+ if (!PrevOp->Asl.Node)
+ {
+ AcpiOsPrintf (" /* External reference */");
+ return;
+ }
+
+ /* Ignore if path is already from the root */
+
+ if (*PrevOp->Asl.Value.String == '\\')
+ {
+ return;
+ }
+
+ /* Now: we can get the full pathname */
+
+ Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
+ if (!Pathname)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (" /* %s */", Pathname);
+ ACPI_FREE (Pathname);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNotifyDescription
+ *
+ * PARAMETERS: Op - Name() parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for the value associated with a
+ * Notify() operator.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmNotifyDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT8 NotifyValue;
+ UINT8 Type = ACPI_TYPE_ANY;
+
+
+ /* The notify value is the second argument */
+
+ NextOp = Op->Asl.Value.Arg;
+ NextOp = NextOp->Asl.Next;
+
+ switch (NextOp->Common.AmlOpcode)
+ {
+ case AML_ZERO_OP:
+ case AML_ONE_OP:
+
+ NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
+ break;
+
+ case AML_BYTE_OP:
+
+ NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
+ break;
+
+ default:
+ return;
+ }
+
+ /*
+ * Attempt to get the namespace node so we can determine the object type.
+ * Some notify values are dependent on the object type (Device, Thermal,
+ * or Processor).
+ */
+ Node = Op->Asl.Node;
+ if (Node)
+ {
+ Type = Node->Type;
+ }
+
+ AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPredefinedDescription
+ *
+ * PARAMETERS: Op - Name() parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a predefined ACPI name.
+ * Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ const AH_PREDEFINED_NAME *Info;
+ char *NameString;
+ int LastCharIsDigit;
+ int LastCharsAreHex;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEF_CHECKED;
+
+ /* Predefined name must start with an underscore */
+
+ NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
+ if (NameString[0] != '_')
+ {
+ return;
+ }
+
+ /*
+ * Check for the special ACPI names:
+ * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
+ * (where d=decimal_digit, x=hex_digit, a=anything)
+ *
+ * Convert these to the generic name for table lookup.
+ * Note: NameString is guaranteed to be upper case here.
+ */
+ LastCharIsDigit =
+ (isdigit ((int) NameString[3])); /* d */
+ LastCharsAreHex =
+ (isxdigit ((int) NameString[2]) && /* xx */
+ isxdigit ((int) NameString[3]));
+
+ switch (NameString[1])
+ {
+ case 'A':
+
+ if ((NameString[2] == 'C') && (LastCharIsDigit))
+ {
+ NameString = "_ACx";
+ }
+ else if ((NameString[2] == 'L') && (LastCharIsDigit))
+ {
+ NameString = "_ALx";
+ }
+ break;
+
+ case 'E':
+
+ if ((NameString[2] == 'J') && (LastCharIsDigit))
+ {
+ NameString = "_EJx";
+ }
+ else if (LastCharsAreHex)
+ {
+ NameString = "_Exx";
+ }
+ break;
+
+ case 'L':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Lxx";
+ }
+ break;
+
+ case 'Q':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Qxx";
+ }
+ break;
+
+ case 'T':
+
+ if (NameString[2] == '_')
+ {
+ NameString = "_T_x";
+ }
+ break;
+
+ case 'W':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Wxx";
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Match the name in the info table */
+
+ Info = AcpiAhMatchPredefinedName (NameString);
+ if (Info)
+ {
+ AcpiOsPrintf (" // %4.4s: %s",
+ NameString, ACPI_CAST_PTR (char, Info->Description));
+ }
+
+#endif
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldPredefinedDescription
+ *
+ * PARAMETERS: Op - Parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a resource descriptor tag
+ * (which is a predefined ACPI name.) Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ ACPI_PARSE_OBJECT *IndexOp;
+ char *Tag;
+ const ACPI_OPCODE_INFO *OpInfo;
+ const AH_PREDEFINED_NAME *Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEF_CHECKED;
+
+ /*
+ * Op must be one of the Create* operators: CreateField, CreateBitField,
+ * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
+ */
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_CREATE))
+ {
+ return;
+ }
+
+ /* Second argument is the Index argument */
+
+ IndexOp = Op->Common.Value.Arg;
+ IndexOp = IndexOp->Common.Next;
+
+ /* Index argument must be a namepath */
+
+ if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* Major cheat: We previously put the Tag ptr in the Node field */
+
+ Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
+ if (!Tag)
+ {
+ return;
+ }
+
+ /* Match the name in the info table */
+
+ Info = AcpiAhMatchPredefinedName (Tag);
+ if (Info)
+ {
+ AcpiOsPrintf (" // %4.4s: %s", Tag,
+ ACPI_CAST_PTR (char, Info->Description));
+ }
+
+#endif
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMethodFlags
+ *
+ * PARAMETERS: Op - Method Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode control method flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMethodFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+ UINT32 Args;
+
+
+ /* The next Op contains the flags */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Flags = (UINT8) Op->Common.Value.Integer;
+ Args = Flags & 0x07;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ /* 1) Method argument count */
+
+ AcpiOsPrintf (", %u, ", Args);
+
+ /* 2) Serialize rule */
+
+ if (!(Flags & 0x08))
+ {
+ AcpiOsPrintf ("Not");
+ }
+
+ AcpiOsPrintf ("Serialized");
+
+ /* 3) SyncLevel */
+
+ if (Flags & 0xF0)
+ {
+ AcpiOsPrintf (", %u", Flags >> 4);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldFlags
+ *
+ * PARAMETERS: Op - Field Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Field definition flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+
+
+ Op = Op->Common.Next;
+ Flags = (UINT8) Op->Common.Value.Integer;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
+ AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
+ AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressSpace
+ *
+ * PARAMETERS: SpaceId - ID to be translated
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddressSpace (
+ UINT8 SpaceId)
+{
+
+ if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
+ {
+ if (SpaceId == 0x7F)
+ {
+ AcpiOsPrintf ("FFixedHW, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%.2X, ", SpaceId);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmRegionFlags
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode OperationRegion flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmRegionFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* The next Op contains the SpaceId */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf (", ");
+ AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchOp
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMatchOp (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp = NextOp->Common.Next;
+
+ if (!NextOp)
+ {
+ /* Handle partial tree during single-step */
+
+ return;
+ }
+
+ /* Mark the two nodes that contain the encoding for the match keywords */
+
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+
+ NextOp = NextOp->Common.Next;
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchKeyword
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMatchKeyword (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
+ {
+ AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
+ }
+ else
+ {
+ AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
+ AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassembleOneOp
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Info - Parse tree walk info
+ * Op - Op that is to be printed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble a single AML opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassembleOneOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo = NULL;
+ UINT32 Offset;
+ UINT32 Length;
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_STATUS Status;
+ UINT8 *Aml;
+ const AH_DEVICE_ID *IdInfo;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("<NULL OP PTR>");
+ return;
+ }
+
+ switch (Op->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_MATCHOP:
+
+ AcpiDmMatchKeyword (Op);
+ return;
+
+ case ACPI_DASM_LNOT_SUFFIX:
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ AcpiOsPrintf ("LNotEqual");
+ break;
+
+ case AML_LGREATER_OP:
+ AcpiOsPrintf ("LLessEqual");
+ break;
+
+ case AML_LLESS_OP:
+ AcpiOsPrintf ("LGreaterEqual");
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ Op->Common.DisasmOpcode = 0;
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return;
+
+ default:
+ break;
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* The op and arguments */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LNOT_OP:
+
+ Child = Op->Common.Value.Arg;
+ if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
+ (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
+ (Child->Common.AmlOpcode == AML_LLESS_OP))
+ {
+ Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+ }
+ else
+ {
+ AcpiOsPrintf ("%s", OpInfo->Name);
+ }
+ break;
+
+ case AML_BYTE_OP:
+
+ AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+ case AML_WORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
+ }
+ break;
+
+ case AML_DWORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
+ }
+ break;
+
+ case AML_QWORD_OP:
+
+ AcpiOsPrintf ("0x%8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
+ break;
+
+ case AML_STRING_OP:
+
+ AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
+
+ /* For _HID/_CID strings, attempt to output a descriptive comment */
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
+ {
+ /* If we know about the ID, emit the description */
+
+ IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
+ if (IdInfo)
+ {
+ AcpiOsPrintf (" /* %s */", IdInfo->Description);
+ }
+ }
+ break;
+
+ case AML_BUFFER_OP:
+ /*
+ * Determine the type of buffer. We can have one of the following:
+ *
+ * 1) ResourceTemplate containing Resource Descriptors.
+ * 2) Unicode String buffer
+ * 3) ASCII String buffer
+ * 4) Raw data buffer (if none of the above)
+ *
+ * Since there are no special AML opcodes to differentiate these
+ * types of buffers, we have to closely look at the data in the
+ * buffer to determine the type.
+ */
+ if (!AcpiGbl_NoResourceDisassembly)
+ {
+ Status = AcpiDmIsResourceTemplate (WalkState, Op);
+ if (ACPI_SUCCESS (Status))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+ AcpiOsPrintf ("ResourceTemplate");
+ break;
+ }
+ else if (Status == AE_AML_NO_RESOURCE_END_TAG)
+ {
+ AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
+ }
+ }
+
+ if (AcpiDmIsUuidBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UUID;
+ AcpiOsPrintf ("ToUUID (");
+ }
+ else if (AcpiDmIsUnicodeBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
+ AcpiOsPrintf ("Unicode (");
+ }
+ else if (AcpiDmIsStringBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_STRING;
+ AcpiOsPrintf ("Buffer");
+ }
+ else if (AcpiDmIsPldBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
+ AcpiOsPrintf ("ToPLD (");
+ }
+ else
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
+ AcpiOsPrintf ("Buffer");
+ }
+ break;
+
+ case AML_INT_NAMEPATH_OP:
+
+ AcpiDmNamestring (Op->Common.Value.Name);
+ break;
+
+ case AML_INT_NAMEDFIELD_OP:
+
+ Length = AcpiDmDumpName (Op->Named.Name);
+ AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ",
+ (UINT32) Op->Common.Value.Integer);
+ AcpiDmCommaIfFieldMember (Op);
+
+ Info->BitOffset += (UINT32) Op->Common.Value.Integer;
+ break;
+
+ case AML_INT_RESERVEDFIELD_OP:
+
+ /* Offset() -- Must account for previous offsets */
+
+ Offset = (UINT32) Op->Common.Value.Integer;
+ Info->BitOffset += Offset;
+
+ if (Info->BitOffset % 8 == 0)
+ {
+ AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
+ }
+ else
+ {
+ AcpiOsPrintf (" , %u", Offset);
+ }
+
+ AcpiDmCommaIfFieldMember (Op);
+ break;
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+
+ AcpiOsPrintf ("AccessAs (%s, ",
+ AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
+
+ AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
+
+ if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
+ {
+ AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op->Common.Value.Integer >> 16) & 0xFF));
+ }
+
+ AcpiOsPrintf (")");
+ AcpiDmCommaIfFieldMember (Op);
+ break;
+
+ case AML_INT_CONNECTION_OP:
+ /*
+ * Two types of Connection() - one with a buffer object, the
+ * other with a namestring that points to a buffer object.
+ */
+ AcpiOsPrintf ("Connection (");
+ Child = Op->Common.Value.Arg;
+
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ AcpiOsPrintf ("\n");
+
+ Aml = Child->Named.Data;
+ Length = (UINT32) Child->Common.Value.Integer;
+
+ Info->Level += 1;
+ Info->MappingOp = Op;
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+
+ AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
+
+ Info->Level -= 1;
+ AcpiDmIndent (Info->Level);
+ }
+ else
+ {
+ AcpiDmNamestring (Child->Common.Value.Name);
+ }
+
+ AcpiOsPrintf (")");
+ AcpiDmCommaIfFieldMember (Op);
+ AcpiOsPrintf ("\n");
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
+ Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ case AML_INT_BYTELIST_OP:
+
+ AcpiDmByteList (Info, Op);
+ break;
+
+ case AML_INT_METHODCALL_OP:
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiDmNamestring (Op->Common.Value.Name);
+ break;
+
+ default:
+
+ /* Just get the opcode name and print it */
+
+ AcpiOsPrintf ("%s", OpInfo->Name);
+
+
+#ifdef ACPI_DEBUGGER
+
+ if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
+ (WalkState) &&
+ (WalkState->Results) &&
+ (WalkState->ResultCount))
+ {
+ AcpiDbDecodeInternalObject (
+ WalkState->Results->Results.ObjDesc [
+ (WalkState->ResultCount - 1) %
+ ACPI_RESULTS_FRAME_OBJ_NUM]);
+ }
+#endif
+
+ break;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrc.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
new file mode 100644
index 0000000000..7d826219f8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrc.c - Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrc")
+
+
+/* Dispatch tables for Resource disassembly functions */
+
+static ACPI_RESOURCE_HANDLER AcpiGbl_DmResourceDispatch [] =
+{
+ /* Small descriptors */
+
+ NULL, /* 0x00, Reserved */
+ NULL, /* 0x01, Reserved */
+ NULL, /* 0x02, Reserved */
+ NULL, /* 0x03, Reserved */
+ AcpiDmIrqDescriptor, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
+ AcpiDmDmaDescriptor, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
+ AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+ AcpiDmEndDependentDescriptor, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+ AcpiDmIoDescriptor, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
+ AcpiDmFixedIoDescriptor, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
+ AcpiDmFixedDmaDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
+ NULL, /* 0x0B, Reserved */
+ NULL, /* 0x0C, Reserved */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmVendorSmallDescriptor, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
+ NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
+
+ /* Large descriptors */
+
+ NULL, /* 0x00, Reserved */
+ AcpiDmMemory24Descriptor, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
+ AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+ NULL, /* 0x03, Reserved */
+ AcpiDmVendorLargeDescriptor, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
+ AcpiDmMemory32Descriptor, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
+ AcpiDmFixedMemory32Descriptor, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
+ AcpiDmDwordDescriptor, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
+ AcpiDmWordDescriptor, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
+ AcpiDmInterruptDescriptor, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
+ AcpiDmQwordDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
+ AcpiDmExtendedDescriptor, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
+ AcpiDmGpioDescriptor, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmSerialBusDescriptor /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS */
+};
+
+
+/* Only used for single-threaded applications */
+/* TBD: remove when name is passed as parameter to the dump functions */
+
+static UINT32 ResourceName;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescriptorName
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
+ * by the name being changed from the default name.) A name is only
+ * emitted if a reference to the descriptor has been made somewhere
+ * in the original ASL code.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDescriptorName (
+ void)
+{
+
+ if (ResourceName == ACPI_DEFAULT_RESNAME)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpInteger*
+ *
+ * PARAMETERS: Value - Value to emit
+ * Name - Associated name (emitted as a comment)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Integer output helper functions
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpInteger8 (
+ UINT8 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%2.2X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger16 (
+ UINT16 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%4.4X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger32 (
+ UINT32 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger64 (
+ UINT64 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBitList
+ *
+ * PARAMETERS: Mask - 16-bit value corresponding to 16 interrupt
+ * or DMA values
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmBitList (
+ UINT16 Mask)
+{
+ UINT32 i;
+ BOOLEAN Previous = FALSE;
+
+
+ /* Open the initializer list */
+
+ AcpiOsPrintf ("{");
+
+ /* Examine each bit */
+
+ for (i = 0; i < 16; i++)
+ {
+ /* Only interested in bits that are set to 1 */
+
+ if (Mask & 1)
+ {
+ if (Previous)
+ {
+ AcpiOsPrintf (",");
+ }
+ Previous = TRUE;
+ AcpiOsPrintf ("%u", i);
+ }
+
+ Mask >>= 1;
+ }
+
+ /* Close list */
+
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceTemplate
+ *
+ * PARAMETERS: Info - Curent parse tree walk info
+ * ByteData - Pointer to the byte list data
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the contents of a Resource Template containing a set of
+ * Resource Descriptors.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmResourceTemplate (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ ACPI_STATUS Status;
+ UINT32 CurrentByteOffset;
+ UINT8 ResourceType;
+ UINT32 ResourceLength;
+ void *Aml;
+ UINT32 Level;
+ BOOLEAN DependentFns = FALSE;
+ UINT8 ResourceIndex;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if (Op->Asl.AmlOpcode != AML_FIELD_OP)
+ {
+ Info->MappingOp = Op;
+ }
+
+ Level = Info->Level;
+ ResourceName = ACPI_DEFAULT_RESNAME;
+ Node = Op->Common.Node;
+ if (Node)
+ {
+ Node = Node->Child;
+ }
+
+ for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
+ {
+ Aml = &ByteData[CurrentByteOffset];
+
+ /* Get the descriptor type and length */
+
+ ResourceType = AcpiUtGetResourceType (Aml);
+ ResourceLength = AcpiUtGetResourceLength (Aml);
+
+ /* Validate the Resource Type and Resource Length */
+
+ Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
+ ResourceType, AcpiFormatException (Status));
+ return;
+ }
+
+ /* Point to next descriptor */
+
+ CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
+
+ /* Descriptor pre-processing */
+
+ switch (ResourceType)
+ {
+ case ACPI_RESOURCE_NAME_START_DEPENDENT:
+
+ /* Finish a previous StartDependentFns */
+
+ if (DependentFns)
+ {
+ Level--;
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ }
+ break;
+
+ case ACPI_RESOURCE_NAME_END_DEPENDENT:
+
+ Level--;
+ DependentFns = FALSE;
+ break;
+
+ case ACPI_RESOURCE_NAME_END_TAG:
+
+ /* Normal exit, the resource list is finished */
+
+ if (DependentFns)
+ {
+ /*
+ * Close an open StartDependentDescriptor. This indicates a
+ * missing EndDependentDescriptor.
+ */
+ Level--;
+ DependentFns = FALSE;
+
+ /* Go ahead and insert EndDependentFn() */
+
+ AcpiDmEndDependentDescriptor (Info, Aml, ResourceLength, Level);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf (
+ "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
+ }
+ return;
+
+ default:
+
+ break;
+ }
+
+ /* Disassemble the resource structure */
+
+ if (Node)
+ {
+ ResourceName = Node->Name.Integer;
+ Node = Node->Peer;
+ }
+
+ AcpiGbl_DmResourceDispatch [ResourceIndex] (
+ Info, Aml, ResourceLength, Level);
+
+ /* Descriptor post-processing */
+
+ if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
+ {
+ DependentFns = TRUE;
+ Level++;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsResourceTemplate
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Op - Buffer Op to be examined
+ *
+ * RETURN: Status. AE_OK if valid template
+ *
+ * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
+ * of resource descriptors. Nothing is output.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDmIsResourceTemplate (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT8 *Aml;
+ UINT8 *EndAml;
+ ACPI_SIZE Length;
+
+
+ /* This op must be a buffer */
+
+ if (Op->Common.AmlOpcode != AML_BUFFER_OP)
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the ByteData list and length */
+
+ NextOp = Op->Common.Value.Arg;
+ if (!NextOp)
+ {
+ AcpiOsPrintf ("NULL byte list in buffer\n");
+ return (AE_TYPE);
+ }
+
+ NextOp = NextOp->Common.Next;
+ if (!NextOp)
+ {
+ return (AE_TYPE);
+ }
+
+ Aml = NextOp->Named.Data;
+ Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
+
+ /* Walk the byte list, abort on any invalid descriptor type or length */
+
+ Status = AcpiUtWalkAmlResources (WalkState, Aml, Length,
+ NULL, ACPI_CAST_INDIRECT_PTR (void, &EndAml));
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_TYPE);
+ }
+
+ /*
+ * For the resource template to be valid, one EndTag must appear
+ * at the very end of the ByteList, not before. (For proper disassembly
+ * of a ResourceTemplate, the buffer must not have any extra data after
+ * the EndTag.)
+ */
+ if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
+ {
+ return (AE_AML_NO_RESOURCE_END_TAG);
+ }
+
+ /*
+ * All resource descriptors are valid, therefore this list appears
+ * to be a valid resource template
+ */
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c
new file mode 100644
index 0000000000..9dd5ef64d8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl.c
@@ -0,0 +1,1079 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl.c - "Large" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl")
+
+
+/* Common names for address and memory descriptors */
+
+static char *AcpiDmAddressNames[] =
+{
+ "Granularity",
+ "Range Minimum",
+ "Range Maximum",
+ "Translation Offset",
+ "Length"
+};
+
+static char *AcpiDmMemoryNames[] =
+{
+ "Range Minimum",
+ "Range Maximum",
+ "Alignment",
+ "Length"
+};
+
+
+/* Local prototypes */
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumLength,
+ UINT32 Length);
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type);
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16 or 32 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to Memory24 and Memory32 descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < 4; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ case 32:
+
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ default:
+
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16, 32, or 64 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiOsPrintf ("\n");
+
+ for (i = 0; i < 5; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 32:
+
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 64:
+
+ AcpiDmDumpInteger64 (ACPI_CAST_PTR (UINT64, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ default:
+
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressPrefix
+ *
+ * PARAMETERS: Type - Descriptor type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit name prefix representing the address descriptor type
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type)
+{
+
+ switch (Type)
+ {
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+
+ AcpiOsPrintf ("Word");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+
+ AcpiOsPrintf ("DWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+
+ AcpiOsPrintf ("QWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+
+ AcpiOsPrintf ("Extended");
+ break;
+
+ default:
+
+ return;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressCommon
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * Type - Descriptor type
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit common name and flag fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT8 ResourceType;
+ UINT8 SpecificFlags;
+ UINT8 Flags;
+
+
+ ResourceType = Resource->Address.ResourceType;
+ SpecificFlags = Resource->Address.SpecificFlags;
+ Flags = Resource->Address.Flags;
+
+ AcpiDmIndent (Level);
+
+ /* Validate ResourceType */
+
+ if ((ResourceType > 2) && (ResourceType < 0xC0))
+ {
+ AcpiOsPrintf ("/**** Invalid Resource Type: 0x%X ****/", ResourceType);
+ return;
+ }
+
+ /* Prefix is either Word, DWord, QWord, or Extended */
+
+ AcpiDmAddressPrefix (Type);
+
+ /* Resource Types above 0xC0 are vendor-defined */
+
+ if (ResourceType > 2)
+ {
+ AcpiOsPrintf ("Space (0x%2.2X, ", ResourceType);
+ AcpiDmSpaceFlags (Flags);
+ AcpiOsPrintf (" 0x%2.2X,", SpecificFlags);
+ return;
+ }
+
+ /* This is either a Memory, IO, or BusNumber descriptor (0,1,2) */
+
+ AcpiOsPrintf ("%s (", AcpiGbl_WordDecode [ACPI_GET_2BIT_FLAG (ResourceType)]);
+
+ /* Decode the general and type-specific flags */
+
+ if (ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags (Flags, SpecificFlags);
+ }
+ else /* IO range or BusNumberRange */
+ {
+ AcpiDmIoFlags (Flags);
+ if (ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiOsPrintf (" %s,", AcpiGbl_RngDecode [ACPI_GET_2BIT_FLAG (SpecificFlags)]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFlags
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit flags common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource)
+{
+
+ if (Resource->Address.ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiDmIoFlags2 (Resource->Address.SpecificFlags);
+ }
+ else if (Resource->Address.ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags2 (Resource->Address.SpecificFlags);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpaceFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to Space Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags)
+{
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TtpDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 4)]);
+
+ /* TRS is only used if TTP is TypeTranslation */
+
+ if (SpecificFlags & 0x10)
+ {
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TrsDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 5)]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ * SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)],
+ AcpiGbl_MemDecode [ACPI_EXTRACT_2BIT_FLAG (SpecificFlags, 1)],
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (SpecificFlags)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s, %s",
+ AcpiGbl_MtpDecode [ACPI_EXTRACT_2BIT_FLAG (SpecificFlags, 3)],
+ AcpiGbl_TtpDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 5)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceSource
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * MinimumLength - descriptor length without optional fields
+ * ResourceLength
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional ResourceSource fields of an address descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumTotalLength,
+ UINT32 ResourceLength)
+{
+ UINT8 *AmlResourceSource;
+ UINT32 TotalLength;
+
+
+ TotalLength = ResourceLength + sizeof (AML_RESOURCE_LARGE_HEADER);
+
+ /* Check if the optional ResourceSource fields are present */
+
+ if (TotalLength <= MinimumTotalLength)
+ {
+ /* The two optional fields are not used */
+
+ AcpiOsPrintf (",, ");
+ return;
+ }
+
+ /* Get a pointer to the ResourceSource */
+
+ AmlResourceSource = ACPI_ADD_PTR (UINT8, Resource, MinimumTotalLength);
+
+ /*
+ * Always emit the ResourceSourceIndex (Byte)
+ *
+ * NOTE: Some ASL compilers always create a 0 byte (in the AML) for the
+ * Index even if the String does not exist. Although this is in violation
+ * of the ACPI specification, it is very important to emit ASL code that
+ * can be compiled back to the identical AML. There may be fields and/or
+ * indexes into the resource template buffer that are compiled to absolute
+ * offsets, and these will be broken if the AML length is changed.
+ */
+ AcpiOsPrintf ("0x%2.2X,", (UINT32) AmlResourceSource[0]);
+
+ /* Make sure that the ResourceSource string exists before dumping it */
+
+ if (TotalLength > (MinimumTotalLength + 1))
+ {
+ AcpiOsPrintf (" ");
+ AcpiUtPrintString ((char *) &AmlResourceSource[1], ACPI_UINT16_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Word Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS16, Level);
+
+ /* Dump the 5 contiguous WORD values */
+
+ AcpiDmAddressFields (&Resource->Address16.Granularity, 16, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS16), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDwordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS32, Level);
+
+ /* Dump the 5 contiguous DWORD values */
+
+ AcpiDmAddressFields (&Resource->Address32.Granularity, 32, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS32), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmQwordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a QWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmQwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->Address64.Granularity, 64, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS64), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmExtendedDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Extended Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmExtendedDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->ExtAddress64.Granularity, 64, Level);
+
+ /* Extra field for this descriptor only */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->ExtAddress64.TypeSpecific,
+ "Type-Specific Attributes");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory24Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory24 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory24Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory24 (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->Memory24.Flags)]);
+
+ /* Dump the 4 contiguous WORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory24.Minimum, 16, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory32Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32 (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->Memory32.Flags)]);
+
+ /* Dump the 4 contiguous DWORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory32.Minimum, 32, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedMemory32Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32Fixed (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->FixedMemory32.Flags)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.Address, "Address Base");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.AddressLength, "Address Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGenericRegisterDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Generic Register descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGenericRegisterDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Register (");
+ AcpiDmAddressSpace (Resource->GenericReg.AddressSpaceId);
+ AcpiOsPrintf ("\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitWidth, "Bit Width");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitOffset, "Bit Offset");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->GenericReg.Address, "Address");
+
+ /* Optional field for ACPI 3.0 */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->GenericReg.AccessSize)
+ {
+ AcpiOsPrintf ("0x%2.2X, // %s\n",
+ Resource->GenericReg.AccessSize, "Access Size");
+ AcpiDmIndent (Level + 1);
+ }
+ else
+ {
+ AcpiOsPrintf (",");
+ }
+
+ /* DescriptorName was added for ACPI 3.0+ */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmInterruptDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a extended Interrupt descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmInterruptDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Interrupt (%s, %s, %s, %s, ",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Resource->ExtendedIrq.Flags)],
+ AcpiGbl_HeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->ExtendedIrq.Flags, 1)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->ExtendedIrq.Flags, 2)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->ExtendedIrq.Flags, 3)]);
+
+ /*
+ * The ResourceSource fields are optional and appear after the interrupt
+ * list. Must compute length based on length of the list. First xrupt
+ * is included in the struct (reason for -1 below)
+ */
+ AcpiDmResourceSource (Resource,
+ sizeof (AML_RESOURCE_EXTENDED_IRQ) +
+ ((UINT32) Resource->ExtendedIrq.InterruptCount - 1) * sizeof (UINT32),
+ Resource->ExtendedIrq.ResourceLength);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ for (i = 0; i < Resource->ExtendedIrq.InterruptCount; i++)
+ {
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%8.8X,\n",
+ (UINT32) Resource->ExtendedIrq.Interrupts[i]);
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorCommon
+ *
+ * PARAMETERS: Name - Descriptor name suffix
+ * ByteData - Pointer to the vendor byte data
+ * Length - Length of the byte data
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor descriptor, both Large and Small
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorCommon (
+ char *Name,
+ UINT8 *ByteData,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump macro name */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Vendor%s (", Name);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (") // Length = 0x%.2X\n", Length);
+
+ /* Dump the vendor bytes */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+
+ AcpiDmDisasmByteList (Level + 1, ByteData, Length);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorLargeDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Large descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorLargeDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Long ",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_LARGE_HEADER)),
+ Length, Level);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c
new file mode 100644
index 0000000000..171e6a14e0
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcl2.c
@@ -0,0 +1,734 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl2.c - "Large" Resource Descriptor disassembly (#2)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl2")
+
+/* Local prototypes */
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmGpioCommon (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Level);
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level);
+
+
+/* Dispatch table for the serial bus descriptors */
+
+static ACPI_RESOURCE_HANDLER SerialBusResourceDispatch [] =
+{
+ NULL,
+ AcpiDmI2cSerialBusDescriptor,
+ AcpiDmSpiSerialBusDescriptor,
+ AcpiDmUartSerialBusDescriptor
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpRawDataBuffer
+ *
+ * PARAMETERS: Buffer - Pointer to the data bytes
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a data buffer as a RawDataBuffer() object. Used for
+ * vendor data bytes.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 Index;
+ UINT32 i;
+ UINT32 j;
+
+
+ if (!Length)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("RawDataBuffer (0x%.2X) // Vendor Data", Length);
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{\n");
+ AcpiDmIndent (Level + 2);
+
+ for (i = 0; i < Length;)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ Index = i + j;
+ if (Index >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf ("0x%2.2X", Buffer[Index]);
+ if ((Index + 1) >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf (", ");
+ }
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 2);
+
+ i += 8;
+ }
+
+Finish:
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioCommon
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode common parts of a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioCommon (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT16 *PinList;
+ UINT8 *VendorData;
+ char *DeviceName = NULL;
+ UINT32 PinCount;
+ UINT32 i;
+
+
+ /* ResourceSource, ResourceSourceIndex, ResourceType */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->Gpio.ResSourceOffset)
+ {
+ DeviceName = ACPI_ADD_PTR (char, Resource, Resource->Gpio.ResSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.ResSourceIndex);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Resource->Gpio.Flags)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",");
+
+ /* Dump the vendor data */
+
+ if (Resource->Gpio.VendorOffset)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ Resource->Gpio.VendorOffset);
+
+ AcpiDmDumpRawDataBuffer (VendorData,
+ Resource->Gpio.VendorLength, Level);
+ }
+
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{ // Pin list\n");
+
+ PinCount = ((UINT32) (Resource->Gpio.ResSourceOffset -
+ Resource->Gpio.PinTableOffset)) /
+ sizeof (UINT16);
+
+ PinList = (UINT16 *) ACPI_ADD_PTR (char, Resource,
+ Resource->Gpio.PinTableOffset);
+
+ for (i = 0; i < PinCount; i++)
+ {
+ AcpiDmIndent (Level + 2);
+ AcpiOsPrintf ("0x%4.4X%s\n", PinList[i], ((i + 1) < PinCount) ? "," : "");
+ }
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}\n");
+
+#ifndef _KERNEL
+ MpSaveGpioInfo (Info->MappingOp, Resource, PinCount, PinList, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIntDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIntDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioInt-specific portion of the descriptor */
+
+ /* EdgeLevel, ActiveLevel, Shared */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioInt (%s, %s, %s, ",
+ AcpiGbl_HeDecode [ACPI_GET_1BIT_FLAG (Resource->Gpio.IntFlags)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 1)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 3)]);
+
+ /* PinConfig, DebounceTimeout */
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+ AcpiOsPrintf ("0x%4.4X,\n", Resource->Gpio.DebounceTimeout);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Info, Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO I/O descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioIo-specific portion of the descriptor */
+
+ /* Shared, PinConfig */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioIo (%s, ",
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 3)]);
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+
+ /* DebounceTimeout, DriveStrength, IoRestriction */
+
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DebounceTimeout);
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DriveStrength);
+ AcpiOsPrintf ("%s,\n",
+ AcpiGbl_IorDecode [ACPI_GET_2BIT_FLAG (Resource->Gpio.IntFlags)]);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Info, Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GpioInt/GpioIo GPIO Interrupt/IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGpioDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT8 ConnectionType;
+
+
+ ConnectionType = Resource->Gpio.ConnectionType;
+
+ switch (ConnectionType)
+ {
+ case AML_RESOURCE_GPIO_TYPE_INT:
+
+ AcpiDmGpioIntDescriptor (Info, Resource, Length, Level);
+ break;
+
+ case AML_RESOURCE_GPIO_TYPE_IO:
+
+ AcpiDmGpioIoDescriptor (Info, Resource, Length, Level);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown GPIO type\n");
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSerialBusVendorData
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional serial bus vendor data
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpSerialBusVendorData (
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT8 *VendorData;
+ UINT32 VendorLength;
+
+
+ /* Get the (optional) vendor data and length */
+
+ switch (Resource->CommonSerialBus.Type)
+ {
+ case AML_RESOURCE_I2C_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_I2C_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_SPI_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_SPI_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_SPI_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_UART_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_UART_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_UART_SERIALBUS));
+ break;
+
+ default:
+
+ return;
+ }
+
+ /* Dump the vendor bytes as a RawDataBuffer object */
+
+ AcpiDmDumpRawDataBuffer (VendorData, VendorLength, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmI2cSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* SlaveAddress, SlaveMode, ConnectionSpeed, AddressingMode */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("I2cSerialBus (0x%4.4X, %s, 0x%8.8X,\n",
+ Resource->I2cSerialBus.SlaveAddress,
+ AcpiGbl_SmDecode [ACPI_GET_1BIT_FLAG (Resource->I2cSerialBus.Flags)],
+ Resource->I2cSerialBus.ConnectionSpeed);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_AmDecode [ACPI_GET_1BIT_FLAG (Resource->I2cSerialBus.TypeSpecificFlags)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->I2cSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->I2cSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifndef _KERNEL
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpiSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SPI serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* DeviceSelection, DeviceSelectionPolarity, WireMode, DataBitLength */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("SpiSerialBus (0x%4.4X, %s, %s, 0x%2.2X,\n",
+ Resource->SpiSerialBus.DeviceSelection,
+ AcpiGbl_DpDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->SpiSerialBus.TypeSpecificFlags, 1)],
+ AcpiGbl_WmDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.TypeSpecificFlags)],
+ Resource->SpiSerialBus.DataBitLength);
+
+ /* SlaveMode, ConnectionSpeed, ClockPolarity, ClockPhase */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, 0x%8.8X, %s,\n",
+ AcpiGbl_SmDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.Flags)],
+ Resource->SpiSerialBus.ConnectionSpeed,
+ AcpiGbl_CpoDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.ClockPolarity)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_CphDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.ClockPhase)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->SpiSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->SpiSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifndef _KERNEL
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUartSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* ConnectionSpeed, BitsPerByte, StopBits */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("UartSerialBus (0x%8.8X, %s, %s,\n",
+ Resource->UartSerialBus.DefaultBaudRate,
+ AcpiGbl_BpbDecode [ACPI_EXTRACT_3BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 4)],
+ AcpiGbl_SbDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 2)]);
+
+ /* LinesInUse, IsBigEndian, Parity, FlowControl */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, %s, %s, %s,\n",
+ Resource->UartSerialBus.LinesEnabled,
+ AcpiGbl_EdDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 7)],
+ AcpiGbl_PtDecode [ACPI_GET_3BIT_FLAG (Resource->UartSerialBus.Parity)],
+ AcpiGbl_FcDecode [ACPI_GET_2BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags)]);
+
+ /* ReceiveBufferSize, TransmitBufferSize */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%4.4X, 0x%4.4X, ",
+ Resource->UartSerialBus.RxFifoSize,
+ Resource->UartSerialBus.TxFifoSize);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->UartSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->UartSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifndef _KERNEL
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C/SPI/UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ SerialBusResourceDispatch [Resource->CommonSerialBus.Type] (
+ Info, Resource, Length, Level);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c
new file mode 100644
index 0000000000..6902f03a77
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmresrcs.c
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcs.c - "Small" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIrqDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a IRQ descriptor, either Irq() or IrqNoFlags()
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIrqDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("%s (",
+ AcpiGbl_IrqDecode [ACPI_GET_1BIT_FLAG (Length)]);
+
+ /* Decode flags byte if present */
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("%s, %s, %s, ",
+ AcpiGbl_HeDecode [ACPI_GET_1BIT_FLAG (Resource->Irq.Flags)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->Irq.Flags, 3)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Irq.Flags, 4)]);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Irq.IrqMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDmaDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("DMA (%s, %s, %s, ",
+ AcpiGbl_TypDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Dma.Flags, 5)],
+ AcpiGbl_BmDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->Dma.Flags, 2)],
+ AcpiGbl_SizDecode [ACPI_GET_2BIT_FLAG (Resource->Dma.Flags)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Dma.DmaChannelMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedDmaDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a FixedDMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedDMA (0x%4.4X, 0x%4.4X, ",
+ Resource->FixedDma.RequestLines,
+ Resource->FixedDma.Channels);
+
+ if (Resource->FixedDma.Width <= 5)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_DtsDecode [Resource->FixedDma.Width]);
+ }
+ else
+ {
+ AcpiOsPrintf ("%X /* INVALID DMA WIDTH */, ", Resource->FixedDma.Width);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("IO (%s,\n",
+ AcpiGbl_IoDecode [ACPI_GET_1BIT_FLAG (Resource->Io.Flags)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Minimum, "Range Minimum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Maximum, "Range Maximum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.Alignment, "Alignment");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedIO (\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->FixedIo.Address, "Address");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->FixedIo.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmStartDependentDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Start Dependendent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmStartDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("StartDependentFn (0x%2.2X, 0x%2.2X)\n",
+ (UINT32) ACPI_GET_2BIT_FLAG (Resource->StartDpf.Flags),
+ (UINT32) ACPI_EXTRACT_2BIT_FLAG (Resource->StartDpf.Flags, 2));
+ }
+ else
+ {
+ AcpiOsPrintf ("StartDependentFnNoPri ()\n");
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmEndDependentDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an End Dependent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmEndDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("EndDependentFn ()\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorSmallDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Small Descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorSmallDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Short",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_SMALL_HEADER)),
+ Length, Level);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmutils.c
new file mode 100644
index 0000000000..876f4043e4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmutils.c
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ *
+ * Module Name: dmutils - AML disassembler utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/include/acnamesp.h>
+#endif
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmutils")
+
+
+/* Data used in keeping track of fields */
+#if 0
+const char *AcpiGbl_FENames[] =
+{
+ "skip",
+ "?access?"
+}; /* FE = Field Element */
+#endif
+
+/* Operators for Match() */
+
+const char *AcpiGbl_MatchOps[] =
+{
+ "MTR",
+ "MEQ",
+ "MLE",
+ "MLT",
+ "MGE",
+ "MGT"
+};
+
+/* Access type decoding */
+
+const char *AcpiGbl_AccessTypes[] =
+{
+ "AnyAcc",
+ "ByteAcc",
+ "WordAcc",
+ "DWordAcc",
+ "QWordAcc",
+ "BufferAcc",
+ "InvalidAccType",
+ "InvalidAccType"
+};
+
+/* Lock rule decoding */
+
+const char *AcpiGbl_LockRule[] =
+{
+ "NoLock",
+ "Lock"
+};
+
+/* Update rule decoding */
+
+const char *AcpiGbl_UpdateRules[] =
+{
+ "Preserve",
+ "WriteAsOnes",
+ "WriteAsZeros",
+ "InvalidUpdateRule"
+};
+
+/* Strings used to decode resource descriptors */
+
+const char *AcpiGbl_WordDecode[] =
+{
+ "Memory",
+ "IO",
+ "BusNumber",
+ "UnknownResourceType"
+};
+
+const char *AcpiGbl_IrqDecode[] =
+{
+ "IRQNoFlags",
+ "IRQ"
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecodeAttribute
+ *
+ * PARAMETERS: Attribute - Attribute field of AccessAs keyword
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the AccessAs attribute byte. (Mostly SMBus and
+ * GenericSerialBus stuff.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecodeAttribute (
+ UINT8 Attribute)
+{
+
+ switch (Attribute)
+ {
+ case AML_FIELD_ATTRIB_QUICK:
+
+ AcpiOsPrintf ("AttribQuick");
+ break;
+
+ case AML_FIELD_ATTRIB_SEND_RCV:
+
+ AcpiOsPrintf ("AttribSendReceive");
+ break;
+
+ case AML_FIELD_ATTRIB_BYTE:
+
+ AcpiOsPrintf ("AttribByte");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD:
+
+ AcpiOsPrintf ("AttribWord");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK:
+
+ AcpiOsPrintf ("AttribBlock");
+ break;
+
+ case AML_FIELD_ATTRIB_MULTIBYTE:
+
+ AcpiOsPrintf ("AttribBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD_CALL:
+
+ AcpiOsPrintf ("AttribProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK_CALL:
+
+ AcpiOsPrintf ("AttribBlockProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_BYTES:
+
+ AcpiOsPrintf ("AttribRawBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+ AcpiOsPrintf ("AttribRawProcessBytes");
+ break;
+
+ default:
+
+ /* A ByteConst is allowed by the grammar */
+
+ AcpiOsPrintf ("0x%2.2X", Attribute);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIndent
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Indent 4 spaces per indentation level.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIndent (
+ UINT32 Level)
+{
+
+ if (!Level)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%*.s", ACPI_MUL_4 (Level), " ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfListMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: TRUE if a comma was inserted
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of an argument list.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCommaIfListMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (!Op->Common.Next)
+ {
+ return (FALSE);
+ }
+
+ if (AcpiDmListType (Op->Common.Parent) & BLOCK_COMMA_LIST)
+ {
+ /* Exit if Target has been marked IGNORE */
+
+ if (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ return (FALSE);
+ }
+
+ /* Check for a NULL target operand */
+
+ if ((Op->Common.Next->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (!Op->Common.Next->Common.Value.String))
+ {
+ /*
+ * To handle the Divide() case where there are two optional
+ * targets, look ahead one more op. If null, this null target
+ * is the one and only target -- no comma needed. Otherwise,
+ * we need a comma to prepare for the next target.
+ */
+ if (!Op->Common.Next->Common.Next)
+ {
+ return (FALSE);
+ }
+ }
+
+ if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
+ (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)))
+ {
+ return (FALSE);
+ }
+
+ /* Emit comma only if this is not a C-style operator */
+
+ if (!Op->Common.OperatorSymbol)
+ {
+ AcpiOsPrintf (", ");
+ }
+
+ return (TRUE);
+ }
+
+ else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf (", ");
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfFieldMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of a Field argument list.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCommaIfFieldMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (", ");
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmwalk.c b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
new file mode 100644
index 0000000000..fd2d28b236
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
@@ -0,0 +1,1067 @@
+/*******************************************************************************
+ *
+ * Module Name: dmwalk - AML disassembly tree walk
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmwalk")
+
+
+#define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: "
+
+/* Stub for non-compiler code */
+
+#ifndef ACPI_ASL_COMPILER
+void
+AcpiDmEmitExternals (
+ void)
+{
+ return;
+}
+#endif
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassemble
+ *
+ * PARAMETERS: WalkState - Current state
+ * Origin - Starting object
+ * NumOpcodes - Max number of opcodes to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble parser object and its children. This is the
+ * main entry point of the disassembler.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassemble (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Origin,
+ UINT32 NumOpcodes)
+{
+ ACPI_PARSE_OBJECT *Op = Origin;
+ ACPI_OP_WALK_INFO Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ memset (&Info, 0, sizeof (ACPI_OP_WALK_INFO));
+ Info.WalkState = WalkState;
+ Info.StartAml = Op->Common.Aml - sizeof (ACPI_TABLE_HEADER);
+ Info.AmlOffset = Op->Common.Aml - Info.StartAml;
+
+ AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWalkParseTree
+ *
+ * PARAMETERS: Op - Root Op object
+ * DescendingCallback - Called during tree descent
+ * AscendingCallback - Called during tree ascent
+ * Context - To be passed to the callbacks
+ *
+ * RETURN: Status from callback(s)
+ *
+ * DESCRIPTION: Walk the entire parse tree.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context)
+{
+ BOOLEAN NodePreviouslyVisited;
+ ACPI_PARSE_OBJECT *StartOp = Op;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_OP_WALK_INFO *Info = Context;
+
+
+ Info->Level = 0;
+ NodePreviouslyVisited = FALSE;
+
+ while (Op)
+ {
+ if (NodePreviouslyVisited)
+ {
+ if (AscendingCallback)
+ {
+ Status = AscendingCallback (Op, Info->Level, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Let the callback process the node */
+
+ Status = DescendingCallback (Op, Info->Level, Context);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Visit children first, once */
+
+ Next = AcpiPsGetArg (Op, 0);
+ if (Next)
+ {
+ Info->Level++;
+ Op = Next;
+ continue;
+ }
+ }
+ else if (Status != AE_CTRL_DEPTH)
+ {
+ /* Exit immediately on any error */
+
+ return;
+ }
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, re-visit this node */
+
+ if (!NodePreviouslyVisited)
+ {
+ NodePreviouslyVisited = TRUE;
+ continue;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Common.Next)
+ {
+ Op = Op->Common.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No peers, re-visit parent */
+
+ if (Info->Level != 0 )
+ {
+ Info->Level--;
+ }
+
+ Op = Op->Common.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+
+ /* If we get here, the walk completed with no errors */
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBlockType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: BlockType - not a block, parens, braces, or even both.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ELSE_OP:
+
+ return (BLOCK_BRACE);
+
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_PROCESSOR_OP:
+ case AML_POWER_RES_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_BUFFER_OP:
+
+ if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) ||
+ (Op->Common.DisasmOpcode == ACPI_DASM_UUID) ||
+ (Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD))
+ {
+ return (BLOCK_NONE);
+ }
+
+ /*lint -fallthrough */
+
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_EVENT_OP:
+
+ return (BLOCK_PAREN);
+
+ case AML_INT_METHODCALL_OP:
+
+ if (Op->Common.Parent &&
+ ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ /* This is a reference to a method, not an invocation */
+
+ return (BLOCK_NONE);
+ }
+
+ /*lint -fallthrough */
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_PAREN);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmListType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: ListType - has commas or not.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmListType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+
+ case AML_ELSE_OP:
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_POWER_RES_OP:
+ case AML_PROCESSOR_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_NONE);
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_COMMA_LIST);
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_COMMA_LIST);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: First visitation of a parse object during tree descent.
+ * Decode opcode name and begin parameter list(s), if any.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 AmlOffset;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* Listing support to dump the AML code after the ASL statement */
+
+ if (AcpiGbl_DmOpt_Listing)
+ {
+ /* We only care about these classes of objects */
+
+ if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) ||
+ (OpInfo->Class == AML_CLASS_CONTROL) ||
+ (OpInfo->Class == AML_CLASS_CREATE) ||
+ ((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next)))
+ {
+ if (AcpiGbl_DmOpt_Listing && Info->PreviousAml)
+ {
+ /* Dump the AML byte code for the previous Op */
+
+ if (Op->Common.Aml > Info->PreviousAml)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiUtDumpBuffer (
+ (Info->StartAml + Info->AmlOffset),
+ (Op->Common.Aml - Info->PreviousAml),
+ DB_BYTE_DISPLAY,
+ Info->AmlOffset);
+ AcpiOsPrintf ("\n");
+ }
+
+ Info->AmlOffset = (Op->Common.Aml - Info->StartAml);
+ }
+
+ Info->PreviousAml = Op->Common.Aml;
+ }
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_CTRL_DEPTH);
+ }
+
+ /* Level 0 is at the Definition Block level */
+
+ if (Level == 0)
+ {
+ /* In verbose mode, print the AML offset, opcode and depth count */
+
+ if (Info->WalkState)
+ {
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
+ Info->WalkState->ParserState.AmlStart);
+ if (AcpiGbl_DmOpt_Verbose)
+ {
+ AcpiOsPrintf (DB_FULL_OP_INFO,
+ (Info->WalkState->MethodNode ?
+ Info->WalkState->MethodNode->Name.Ascii : " "),
+ AmlOffset, (UINT32) Op->Common.AmlOpcode);
+ }
+ }
+
+ if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
+ /* This is the beginning of the Definition Block */
+
+ AcpiOsPrintf ("{\n");
+
+ /* Emit all External() declarations here */
+
+ AcpiDmEmitExternals ();
+ return (AE_OK);
+ }
+ }
+ else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list,
+ * indent a new line
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_NOOP_OP:
+ /*
+ * Optionally just ignore this opcode. Some tables use
+ * NoOp opcodes for "padding" out packages that the BIOS
+ * changes dynamically. This can leave hundreds or
+ * thousands of NoOp opcodes that if disassembled,
+ * cannot be compiled because they are syntactically
+ * incorrect.
+ */
+ if (AcpiGbl_IgnoreNoopOperator)
+ {
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (AE_OK);
+ }
+
+ /* Fallthrough */
+
+ default:
+
+ AcpiDmIndent (Level);
+ break;
+ }
+
+ Info->LastLevel = Level;
+ Info->Count = 0;
+ }
+
+ /*
+ * This is an inexpensive mechanism to try and keep lines from getting
+ * too long. When the limit is hit, start a new line at the previous
+ * indent plus one. A better but more expensive mechanism would be to
+ * keep track of the current column.
+ */
+ Info->Count++;
+ if (Info->Count /* +Info->LastLevel */ > 12)
+ {
+ Info->Count = 0;
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Info->LastLevel + 1);
+ }
+
+ /* If ASL+ is enabled, check for a C-style operator */
+
+ if (AcpiDmCheckForSymbolicOpcode (Op, Info))
+ {
+ return (AE_OK);
+ }
+
+ /* Print the opcode name */
+
+ AcpiDmDisassembleOneOp (NULL, Info, Op);
+
+ if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
+ (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
+ {
+ return (AE_OK);
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ Info->Level--;
+ }
+
+ /* Start the opcode argument list if necessary */
+
+ if ((OpInfo->Flags & AML_HAS_ARGS) ||
+ (Op->Common.AmlOpcode == AML_EVENT_OP))
+ {
+ /* This opcode has an argument list */
+
+ if (AcpiDmBlockType (Op) & BLOCK_PAREN)
+ {
+ AcpiOsPrintf (" (");
+ }
+
+ /* If this is a named opcode, print the associated name value */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ALIAS_OP:
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+
+ /*lint -fallthrough */
+
+ default:
+
+ Name = AcpiPsGetName (Op);
+ if (Op->Named.Path)
+ {
+ AcpiDmNamestring ((char *) Op->Named.Path);
+ }
+ else
+ {
+ AcpiDmDumpName (Name);
+ }
+
+ if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
+ {
+ if (AcpiGbl_DmOpt_Verbose)
+ {
+ (void) AcpiPsDisplayObjectPathname (NULL, Op);
+ }
+ }
+ break;
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+
+ AcpiDmMethodFlags (Op);
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Method() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
+ break;
+
+ case AML_NAME_OP:
+
+ /* Check for _HID and related EISAID() */
+
+ AcpiDmCheckForHardwareId (Op);
+ AcpiOsPrintf (", ");
+ break;
+
+ case AML_REGION_OP:
+
+ AcpiDmRegionFlags (Op);
+ break;
+
+ case AML_POWER_RES_OP:
+
+ /* Mark the next two Ops as part of the parameter list */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+ case AML_PROCESSOR_OP:
+
+ /* Mark the next three Ops as part of the parameter list */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+ case AML_MUTEX_OP:
+ case AML_DATA_REGION_OP:
+
+ AcpiOsPrintf (", ");
+ return (AE_OK);
+
+ case AML_EVENT_OP:
+ case AML_ALIAS_OP:
+
+ return (AE_OK);
+
+ case AML_SCOPE_OP:
+ case AML_DEVICE_OP:
+ case AML_THERMAL_ZONE_OP:
+
+ AcpiOsPrintf (")");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("*** Unhandled named opcode %X\n",
+ Op->Common.AmlOpcode);
+ break;
+ }
+ }
+
+ else switch (Op->Common.AmlOpcode)
+ {
+ case AML_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+
+ Info->BitOffset = 0;
+
+ /* Name of the parent OperationRegion */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BANK_FIELD_OP:
+
+ /* Namestring - Bank Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+
+ /*
+ * Bank Value. This is a TermArg in the middle of the parameter
+ * list, must handle it here.
+ *
+ * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
+ * eliminates newline in the output.
+ */
+ NextOp = NextOp->Common.Next;
+
+ Info->Flags = ACPI_PARSEOP_PARAMLIST;
+ AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
+ AcpiDmAscendingOp, Info);
+ Info->Flags = 0;
+ Info->Level = Level;
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+ break;
+
+ case AML_INDEX_FIELD_OP:
+
+ /* Namestring - Data Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiDmFieldFlags (NextOp);
+ break;
+
+ case AML_BUFFER_OP:
+
+ /* The next op is the size parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ /* Single-step support */
+
+ return (AE_OK);
+ }
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
+ {
+ /*
+ * We have a resource list. Don't need to output
+ * the buffer size Op. Open up a new block
+ */
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ NextOp = NextOp->Common.Next;
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op->Asl.Parent);
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Info->Level);
+ AcpiOsPrintf ("{\n");
+ return (AE_OK);
+ }
+
+ /* Normal Buffer, mark size as in the parameter list */
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+ case AML_VAR_PACKAGE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+
+ /* The next op is the size or predicate parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ }
+ return (AE_OK);
+
+ case AML_PACKAGE_OP:
+
+ /* The next op is the size parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ }
+ return (AE_OK);
+
+ case AML_MATCH_OP:
+
+ AcpiDmMatchOp (Op);
+ break;
+
+ default:
+
+ break;
+ }
+
+ if (AcpiDmBlockType (Op) & BLOCK_BRACE)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAscendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Second visitation of a parse object, during ascent of parse
+ * tree. Close out any parameter lists and complete the opcode.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_OK);
+ }
+
+ if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
+ {
+ /* Indicates the end of the current descriptor block (table) */
+
+ AcpiOsPrintf ("}\n\n");
+ return (AE_OK);
+ }
+
+ switch (AcpiDmBlockType (Op))
+ {
+ case BLOCK_PAREN:
+
+ /* Completed an op that has arguments, add closing paren if needed */
+
+ AcpiDmCloseOperator (Op);
+
+ if (Op->Common.AmlOpcode == AML_NAME_OP)
+ {
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
+ }
+ else
+ {
+ /* For Create* operators, attempt to emit resource tag description */
+
+ AcpiDmFieldPredefinedDescription (Op);
+ }
+
+ /* Decode Notify() values */
+
+ if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
+ {
+ AcpiDmNotifyDescription (Op);
+ }
+
+ AcpiDmDisplayTargetPathname (Op);
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ }
+ }
+ break;
+
+ case BLOCK_BRACE:
+ case (BLOCK_BRACE | BLOCK_PAREN):
+
+ /* Completed an op that has a term list, add closing brace */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
+ {
+ AcpiOsPrintf ("}");
+ }
+ else
+ {
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}");
+ }
+
+ AcpiDmCommaIfListMember (Op);
+
+ if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
+ {
+ AcpiOsPrintf ("\n");
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
+ {
+ if ((Op->Common.AmlOpcode == AML_IF_OP) &&
+ (Op->Common.Next) &&
+ (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
+ {
+ break;
+ }
+
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!Op->Common.Next))
+ {
+ break;
+ }
+ AcpiOsPrintf ("\n");
+ }
+ }
+ break;
+
+ case BLOCK_NONE:
+ default:
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ AcpiOsPrintf ("\n");
+ }
+ }
+ else if (Op->Common.Parent)
+ {
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+ break;
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
+ {
+ if ((Op->Common.Next) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * The parent Op is guaranteed to be valid because of the flag
+ * ACPI_PARSEOP_PARAMLIST -- which means that this op is part of
+ * a parameter list and thus has a valid parent.
+ */
+ ParentOp = Op->Common.Parent;
+
+ /*
+ * Just completed a parameter node for something like "Buffer (param)".
+ * Close the paren and open up the term list block with a brace
+ */
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (")");
+
+ /*
+ * Emit a description comment for a Name() operator that is a
+ * predefined ACPI name. Must check the grandparent.
+ */
+ ParentOp = ParentOp->Common.Parent;
+ if (ParentOp &&
+ (ParentOp->Asl.AmlOpcode == AML_NAME_OP))
+ {
+ AcpiDmPredefinedDescription (ParentOp);
+ }
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level - 1);
+ AcpiOsPrintf ("{\n");
+ }
+ else
+ {
+ ParentOp->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
+ AcpiOsPrintf (") {");
+ }
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ Info->Level++;
+ }
+
+ /*
+ * For ASL+, check for and emit a C-style symbol. If valid, the
+ * symbol string has been deferred until after the first operand
+ */
+ if (AcpiGbl_CstyleDisassembly)
+ {
+ if (Op->Asl.OperatorSymbol)
+ {
+ AcpiOsPrintf ("%s", Op->Asl.OperatorSymbol);
+ Op->Asl.OperatorSymbol = NULL;
+ }
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsargs.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsargs.c
new file mode 100644
index 0000000000..a3be06b8d7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsargs.c
@@ -0,0 +1,436 @@
+/******************************************************************************
+ *
+ * Module Name: dsargs - Support for execution of dynamic arguments for static
+ * objects (regions, fields, buffer fields, etc.)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsargs")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_NAMESPACE_NODE *ScopeNode,
+ UINT32 AmlLength,
+ UINT8 *AmlStart);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecuteArguments
+ *
+ * PARAMETERS: Node - Object NS node
+ * ScopeNode - Parent NS node
+ * AmlLength - Length of executable AML
+ * AmlStart - Pointer to the AML
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Late (deferred) execution of region or field arguments
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_NAMESPACE_NODE *ScopeNode,
+ UINT32 AmlLength,
+ UINT8 *AmlStart)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE (DsExecuteArguments);
+
+
+ /* Allocate a new parser op to be the root of the parsed tree */
+
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Save the Node for use in AcpiPsParseAml */
+
+ Op->Common.Node = ScopeNode;
+
+ /* Create and initialize a new parser state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+ AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /* Mark this parse as a deferred opcode */
+
+ WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
+ WalkState->DeferredNode = Node;
+
+ /* Pass1: Parse the entire declaration */
+
+ Status = AcpiPsParseAml (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Get and init the Op created above */
+
+ Op->Common.Node = Node;
+ AcpiPsDeleteParseTree (Op);
+
+ /* Evaluate the deferred arguments */
+
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Op->Common.Node = ScopeNode;
+
+ /* Create and initialize a new parser state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Execute the opcode and arguments */
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+ AmlLength, NULL, ACPI_IMODE_EXECUTE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /* Mark this execution as a deferred opcode */
+
+ WalkState->DeferredNode = Node;
+ Status = AcpiPsParseAml (WalkState);
+
+Cleanup:
+ AcpiPsDeleteParseTree (Op);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBufferFieldArguments
+ *
+ * PARAMETERS: ObjDesc - A valid BufferField object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
+ * evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the AML pointer (method object) and BufferField node */
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ Node = ObjDesc->BufferField.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD,
+ Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
+ AcpiUtGetNodeName (Node)));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node->Parent,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBankFieldArguments
+ *
+ * PARAMETERS: ObjDesc - A valid BankField object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get BankField BankValue. This implements the late
+ * evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBankFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the AML pointer (method object) and BankField node */
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ Node = ObjDesc->BankField.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD,
+ Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
+ AcpiUtGetNodeName (Node)));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node->Parent,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBufferArguments
+ *
+ * PARAMETERS: ObjDesc - A valid Buffer object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get Buffer length and initializer byte list. This implements
+ * the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the Buffer node */
+
+ Node = ObjDesc->Buffer.Node;
+ if (!Node)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No pointer back to namespace node in buffer object %p", ObjDesc));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node,
+ ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetPackageArguments
+ *
+ * PARAMETERS: ObjDesc - A valid Package object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get Package length and initializer byte list. This implements
+ * the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetPackageArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the Package node */
+
+ Node = ObjDesc->Package.Node;
+ if (!Node)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No pointer back to namespace node in package %p", ObjDesc));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node,
+ ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetRegionArguments
+ *
+ * PARAMETERS: ObjDesc - A valid region object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get region address and length. This implements the late
+ * evaluation of these region attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetRegionArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
+
+
+ if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ if (!ExtraDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Get the Region node */
+
+ Node = ObjDesc->Region.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
+ AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
+
+ /* Execute the argument AML */
+
+ Status = AcpiDsExecuteArguments (Node, ExtraDesc->Extra.ScopeNode,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
+ ObjDesc->Region.Address, ObjDesc->Region.Length,
+ Node);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
new file mode 100644
index 0000000000..5986183884
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
@@ -0,0 +1,414 @@
+/******************************************************************************
+ *
+ * Module Name: dscontrol - Support for execution control opcodes -
+ * if/else/while/return
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dscontrol")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecBeginControlOp
+ *
+ * PARAMETERS: WalkList - The list that owns the walk stack
+ * Op - The control Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ * execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecBeginControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *ControlState;
+
+
+ ACPI_FUNCTION_NAME (DsExecBeginControlOp);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
+ Op, Op->Common.AmlOpcode, WalkState));
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_WHILE_OP:
+ /*
+ * If this is an additional iteration of a while loop, continue.
+ * There is no need to allocate a new control state.
+ */
+ if (WalkState->ControlState)
+ {
+ if (WalkState->ControlState->Control.AmlPredicateStart ==
+ (WalkState->ParserState.Aml - 1))
+ {
+ /* Reset the state to start-of-loop */
+
+ WalkState->ControlState->Common.State =
+ ACPI_CONTROL_CONDITIONAL_EXECUTING;
+ break;
+ }
+ }
+
+ /*lint -fallthrough */
+
+ case AML_IF_OP:
+ /*
+ * IF/WHILE: Create a new control state to manage these
+ * constructs. We need to manage these as a stack, in order
+ * to handle nesting.
+ */
+ ControlState = AcpiUtCreateControlState ();
+ if (!ControlState)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+ /*
+ * Save a pointer to the predicate for multiple executions
+ * of a loop
+ */
+ ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
+ ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
+ ControlState->Control.Opcode = Op->Common.AmlOpcode;
+
+
+ /* Push the control state on this walk's control stack */
+
+ AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
+ break;
+
+ case AML_ELSE_OP:
+
+ /* Predicate is in the state object */
+ /* If predicate is true, the IF was executed, ignore ELSE part */
+
+ if (WalkState->LastPredicate)
+ {
+ Status = AE_CTRL_TRUE;
+ }
+
+ break;
+
+ case AML_RETURN_OP:
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecEndControlOp
+ *
+ * PARAMETERS: WalkList - The list that owns the walk stack
+ * Op - The control Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ * execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecEndControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *ControlState;
+
+
+ ACPI_FUNCTION_NAME (DsExecEndControlOp);
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_IF_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
+
+ /*
+ * Save the result of the predicate in case there is an
+ * ELSE to come
+ */
+ WalkState->LastPredicate =
+ (BOOLEAN) WalkState->ControlState->Common.Value;
+
+ /*
+ * Pop the control state that was created at the start
+ * of the IF and free it
+ */
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ break;
+
+ case AML_ELSE_OP:
+
+ break;
+
+ case AML_WHILE_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
+
+ ControlState = WalkState->ControlState;
+ if (ControlState->Common.Value)
+ {
+ /* Predicate was true, the body of the loop was just executed */
+
+ /*
+ * This loop counter mechanism allows the interpreter to escape
+ * possibly infinite loops. This can occur in poorly written AML
+ * when the hardware does not respond within a while loop and the
+ * loop does not implement a timeout.
+ */
+ ControlState->Control.LoopCount++;
+ if (ControlState->Control.LoopCount > AcpiGbl_MaxLoopIterations)
+ {
+ Status = AE_AML_INFINITE_LOOP;
+ break;
+ }
+
+ /*
+ * Go back and evaluate the predicate and maybe execute the loop
+ * another time
+ */
+ Status = AE_CTRL_PENDING;
+ WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
+ break;
+ }
+
+ /* Predicate was false, terminate this while loop */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[WHILE_OP] termination! Op=%p\n",Op));
+
+ /* Pop this control state and free it */
+
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ break;
+
+ case AML_RETURN_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
+
+ /*
+ * One optional operand -- the return value
+ * It can be either an immediate operand or a result that
+ * has been bubbled up the tree
+ */
+ if (Op->Common.Value.Arg)
+ {
+ /* Since we have a real Return(), delete any implicit return */
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+ /* Return statement has an immediate operand */
+
+ Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * If value being returned is a Reference (such as
+ * an arg or local), resolve it now because it may
+ * cease to exist at the end of the method.
+ */
+ Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Get the return value and save as the last result
+ * value. This is the only place where WalkState->ReturnDesc
+ * is set to anything other than zero!
+ */
+ WalkState->ReturnDesc = WalkState->Operands[0];
+ }
+ else if (WalkState->ResultCount)
+ {
+ /* Since we have a real Return(), delete any implicit return */
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+ /*
+ * The return value has come from a previous calculation.
+ *
+ * If value being returned is a Reference (such as
+ * an arg or local), resolve it now because it may
+ * cease to exist at the end of the method.
+ *
+ * Allow references created by the Index operator to return
+ * unchanged.
+ */
+ if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
+ ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
+ {
+ Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
+ }
+ else
+ {
+ /* No return operand */
+
+ if (WalkState->NumOperands)
+ {
+ AcpiUtRemoveReference (WalkState->Operands [0]);
+ }
+
+ WalkState->Operands [0] = NULL;
+ WalkState->NumOperands = 0;
+ WalkState->ReturnDesc = NULL;
+ }
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Completed RETURN_OP State=%p, RetVal=%p\n",
+ WalkState, WalkState->ReturnDesc));
+
+ /* End the control method execution right now */
+
+ Status = AE_CTRL_TERMINATE;
+ break;
+
+ case AML_NOOP_OP:
+
+ /* Just do nothing! */
+
+ break;
+
+ case AML_BREAK_POINT_OP:
+
+ /*
+ * Set the single-step flag. This will cause the debugger (if present)
+ * to break to the console within the AML debugger at the start of the
+ * next AML instruction.
+ */
+ ACPI_DEBUGGER_EXEC (
+ AcpiGbl_CmSingleStep = TRUE);
+ ACPI_DEBUGGER_EXEC (
+ AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
+
+ /* Call to the OSL in case OS wants a piece of the action */
+
+ Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
+ "Executed AML Breakpoint opcode");
+ break;
+
+ case AML_BREAK_OP:
+ case AML_CONTINUE_OP: /* ACPI 2.0 */
+
+ /* Pop and delete control states until we find a while */
+
+ while (WalkState->ControlState &&
+ (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
+ {
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ }
+
+ /* No while found? */
+
+ if (!WalkState->ControlState)
+ {
+ return (AE_AML_NO_WHILE);
+ }
+
+ /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
+
+ WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
+
+ /* Return status depending on opcode */
+
+ if (Op->Common.AmlOpcode == AML_BREAK_OP)
+ {
+ Status = AE_CTRL_BREAK;
+ }
+ else
+ {
+ Status = AE_CTRL_CONTINUE;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
+ Op->Common.AmlOpcode, Op));
+
+ Status = AE_AML_BAD_OPCODE;
+ break;
+ }
+
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c
new file mode 100644
index 0000000000..78206c0cf5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsdebug.c
@@ -0,0 +1,249 @@
+/******************************************************************************
+ *
+ * Module Name: dsdebug - Parser/Interpreter interface - debugging
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsdebug")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/* Local prototypes */
+
+static void
+AcpiDsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Message);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsPrintNodePathname
+ *
+ * PARAMETERS: Node - Object
+ * Message - Prefix message
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ * Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+static void
+AcpiDsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Message)
+{
+ ACPI_BUFFER Buffer;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DsPrintNodePathname);
+
+ if (!Node)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]"));
+ return_VOID;
+ }
+
+ /* Convert handle to full pathname and print it (with supplied message) */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
+ if (ACPI_SUCCESS (Status))
+ {
+ if (Message)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)",
+ (char *) Buffer.Pointer, Node));
+ ACPI_FREE (Buffer.Pointer);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDumpMethodStack
+ *
+ * PARAMETERS: Status - Method execution status
+ * WalkState - Current state of the parse tree walk
+ * Op - Executing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ * Dumps the method execution stack.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsDumpMethodStack (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_THREAD_STATE *Thread;
+ ACPI_WALK_STATE *NextWalkState;
+ ACPI_NAMESPACE_NODE *PreviousMethod = NULL;
+ ACPI_OPERAND_OBJECT *MethodDesc;
+
+
+ ACPI_FUNCTION_TRACE (DsDumpMethodStack);
+
+ /* Ignore control codes, they are not errors */
+
+ if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
+ {
+ return_VOID;
+ }
+
+ /* We may be executing a deferred opcode */
+
+ if (WalkState->DeferredNode)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Executing subtree for Buffer/Package/Region\n"));
+ return_VOID;
+ }
+
+ /*
+ * If there is no Thread, we are not actually executing a method.
+ * This can happen when the iASL compiler calls the interpreter
+ * to perform constant folding.
+ */
+ Thread = WalkState->Thread;
+ if (!Thread)
+ {
+ return_VOID;
+ }
+
+ /* Display exception and method name */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "\n**** Exception %s during execution of method ",
+ AcpiFormatException (Status)));
+ AcpiDsPrintNodePathname (WalkState->MethodNode, NULL);
+
+ /* Display stack of executing methods */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH,
+ "\n\nMethod Execution Stack:\n"));
+ NextWalkState = Thread->WalkStateList;
+
+ /* Walk list of linked walk states */
+
+ while (NextWalkState)
+ {
+ MethodDesc = NextWalkState->MethodDesc;
+ if (MethodDesc)
+ {
+ AcpiExStopTraceMethod (
+ (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
+ MethodDesc, WalkState);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ " Method [%4.4s] executing: ",
+ AcpiUtGetNodeName (NextWalkState->MethodNode)));
+
+ /* First method is the currently executing method */
+
+ if (NextWalkState == WalkState)
+ {
+ if (Op)
+ {
+ /* Display currently executing ASL statement */
+
+ Next = Op->Common.Next;
+ Op->Common.Next = NULL;
+
+#ifdef ACPI_DISASSEMBLER
+ AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
+#endif
+ Op->Common.Next = Next;
+ }
+ }
+ else
+ {
+ /*
+ * This method has called another method
+ * NOTE: the method call parse subtree is already deleted at this
+ * point, so we cannot disassemble the method invocation.
+ */
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method "));
+ AcpiDsPrintNodePathname (PreviousMethod, NULL);
+ }
+
+ PreviousMethod = NextWalkState->MethodNode;
+ NextWalkState = NextWalkState->Next;
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n"));
+ }
+
+ return_VOID;
+}
+
+#else
+
+void
+AcpiDsDumpMethodStack (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ return;
+}
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsfield.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
new file mode 100644
index 0000000000..81cf410001
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
@@ -0,0 +1,834 @@
+/******************************************************************************
+ *
+ * Module Name: dsfield - Dispatcher field routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsfield")
+
+/* Local prototypes */
+
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node);
+#endif
+
+static ACPI_STATUS
+AcpiDsGetFieldNames (
+ ACPI_CREATE_FIELD_INFO *Info,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg);
+
+
+#ifdef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only)
+ *
+ * PARAMETERS: LookupStatus - Status from NsLookup operation
+ * Op - Op containing the Field definition and args
+ * Path - Pathname of the region
+ * ` WalkState - Current method state
+ * Node - Where the new region node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
+ * region node/object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ if (LookupStatus != AE_NOT_FOUND)
+ {
+ return (LookupStatus);
+ }
+
+ /*
+ * Table disassembly:
+ * OperationRegion not found. Generate an External for it, and
+ * insert the name into the namespace.
+ */
+ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Must create and install a region object for the new node */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ if (!ObjDesc)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Region.Node = *Node;
+ Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
+ return (Status);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateBufferField
+ *
+ * PARAMETERS: Op - Current parse op (CreateXXField)
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute the CreateField operators:
+ * CreateBitFieldOp,
+ * CreateByteFieldOp,
+ * CreateWordFieldOp,
+ * CreateDwordFieldOp,
+ * CreateQwordFieldOp,
+ * CreateFieldOp (all of which define a field in a buffer)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateBufferField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *SecondDesc = NULL;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE (DsCreateBufferField);
+
+
+ /*
+ * Get the NameString argument (name of the new BufferField)
+ */
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ /* For CreateField, name is the 4th argument */
+
+ Arg = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ /* For all other CreateXXXField operators, name is the 3rd argument */
+
+ Arg = AcpiPsGetArg (Op, 2);
+ }
+
+ if (!Arg)
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ if (WalkState->DeferredNode)
+ {
+ Node = WalkState->DeferredNode;
+ Status = AE_OK;
+ }
+ else
+ {
+ /* Execute flag should always be set when this function is entered */
+
+ if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
+ {
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /* Creating new namespace node, should not already exist */
+
+ Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND;
+
+ /*
+ * Mark node temporary if we are executing a normal control
+ * method. (Don't mark if this is a module-level code method)
+ */
+ if (WalkState->MethodNode &&
+ !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ Flags |= ACPI_NS_TEMPORARY;
+ }
+
+ /* Enter the NameString into the namespace */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
+ Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * We could put the returned object (Node) on the object stack for later,
+ * but for now, we will put it in the "op" object that the parser uses,
+ * so we can get it again at the end of this scope.
+ */
+ Op->Common.Node = Node;
+
+ /*
+ * If there is no object attached to the node, this node was just created
+ * and we need to create the field object. Otherwise, this was a lookup
+ * of an existing node and we don't want to create the field object again.
+ */
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * The Field definition is not fully parsed at this time.
+ * (We must save the address of the AML for the buffer and index operands)
+ */
+
+ /* Create the buffer field object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Remember location in AML stream of the field unit opcode and operands --
+ * since the buffer and index operands must be evaluated.
+ */
+ SecondDesc = ObjDesc->Common.NextObject;
+ SecondDesc->Extra.AmlStart = Op->Named.Data;
+ SecondDesc->Extra.AmlLength = Op->Named.Length;
+ ObjDesc->BufferField.Node = Node;
+
+ /* Attach constructed field descriptors to parent node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetFieldNames
+ *
+ * PARAMETERS: Info - CreateField info structure
+ * ` WalkState - Current method state
+ * Arg - First parser arg for the field name list
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Process all named fields in a field declaration. Names are
+ * entered into the namespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsGetFieldNames (
+ ACPI_CREATE_FIELD_INFO *Info,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg)
+{
+ ACPI_STATUS Status;
+ UINT64 Position;
+ ACPI_PARSE_OBJECT *Child;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
+
+
+ /* First field starts at bit zero */
+
+ Info->FieldBitPosition = 0;
+
+ /* Process all elements in the field list (of parse nodes) */
+
+ while (Arg)
+ {
+ /*
+ * Four types of field elements are handled:
+ * 1) Name - Enters a new named field into the namespace
+ * 2) Offset - specifies a bit offset
+ * 3) AccessAs - changes the access mode/attributes
+ * 4) Connection - Associate a resource template with the field
+ */
+ switch (Arg->Common.AmlOpcode)
+ {
+ case AML_INT_RESERVEDFIELD_OP:
+
+ Position = (UINT64) Info->FieldBitPosition
+ + (UINT64) Arg->Common.Value.Size;
+
+ if (Position > ACPI_UINT32_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Bit offset within field too large (> 0xFFFFFFFF)"));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ Info->FieldBitPosition = (UINT32) Position;
+ break;
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+ /*
+ * Get new AccessType, AccessAttribute, and AccessLength fields
+ * -- to be used for all field units that follow, until the
+ * end-of-field or another AccessAs keyword is encountered.
+ * NOTE. These three bytes are encoded in the integer value
+ * of the parseop for convenience.
+ *
+ * In FieldFlags, preserve the flag bits other than the
+ * ACCESS_TYPE bits.
+ */
+
+ /* AccessType (ByteAcc, WordAcc, etc.) */
+
+ Info->FieldFlags = (UINT8)
+ ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+ ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
+
+ /* AccessAttribute (AttribQuick, AttribByte, etc.) */
+
+ Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF);
+
+ /* AccessLength (for serial/buffer protocols) */
+
+ Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF);
+ break;
+
+ case AML_INT_CONNECTION_OP:
+ /*
+ * Clear any previous connection. New connection is used for all
+ * fields that follow, similar to AccessAs
+ */
+ Info->ResourceBuffer = NULL;
+ Info->ConnectionNode = NULL;
+ Info->PinNumberIndex = 0;
+
+ /*
+ * A Connection() is either an actual resource descriptor (buffer)
+ * or a named reference to a resource template
+ */
+ Child = Arg->Common.Value.Arg;
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ Info->ResourceBuffer = Child->Named.Data;
+ Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
+ }
+ else
+ {
+ /* Lookup the Connection() namepath, it should already exist */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Child->Common.Value.Name, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Info->ConnectionNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+ break;
+
+ case AML_INT_NAMEDFIELD_OP:
+
+ /* Lookup the name, it should already exist */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Info->FieldType,
+ ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Info->FieldNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ else
+ {
+ Arg->Common.Node = Info->FieldNode;
+ Info->FieldBitLength = Arg->Common.Value.Size;
+
+ /*
+ * If there is no object attached to the node, this node was
+ * just created and we need to create the field object.
+ * Otherwise, this was a lookup of an existing node and we
+ * don't want to create the field object again.
+ */
+ if (!AcpiNsGetAttachedObject (Info->FieldNode))
+ {
+ Status = AcpiExPrepFieldValue (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
+ /* Keep track of bit position for the next field */
+
+ Position = (UINT64) Info->FieldBitPosition
+ + (UINT64) Arg->Common.Value.Size;
+
+ if (Position > ACPI_UINT32_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
+ ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ Info->FieldBitPosition += Info->FieldBitLength;
+ Info->PinNumberIndex++; /* Index relative to previous Connection() */
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
+ return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ }
+
+ Arg = Arg->Common.Next;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
+
+
+ /* First arg is the name of the parent OpRegion (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+
+ if (!RegionNode)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
+ ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
+
+ /* Second arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+ Info.Attribute = 0;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
+ Info.RegionNode = RegionNode;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitFieldObjects
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: For each "Field Unit" name in the argument list that is
+ * part of the field declaration, enter the name into the
+ * namespace.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitFieldObjects (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT8 Type = 0;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
+
+
+ /* Execute flag should always be set when this function is entered */
+
+ if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
+ {
+ if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
+ {
+ /* BankField Op is deferred, just return OK */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /*
+ * Get the FieldList argument for this opcode. This is the start of the
+ * list of field elements.
+ */
+ switch (WalkState->Opcode)
+ {
+ case AML_FIELD_OP:
+
+ Arg = AcpiPsGetArg (Op, 2);
+ Type = ACPI_TYPE_LOCAL_REGION_FIELD;
+ break;
+
+ case AML_BANK_FIELD_OP:
+
+ Arg = AcpiPsGetArg (Op, 4);
+ Type = ACPI_TYPE_LOCAL_BANK_FIELD;
+ break;
+
+ case AML_INDEX_FIELD_OP:
+
+ Arg = AcpiPsGetArg (Op, 3);
+ Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Creating new namespace node(s), should not already exist */
+
+ Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND;
+
+ /*
+ * Mark node(s) temporary if we are executing a normal control
+ * method. (Don't mark if this is a module-level code method)
+ */
+ if (WalkState->MethodNode &&
+ !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ Flags |= ACPI_NS_TEMPORARY;
+ }
+
+ /*
+ * Walk the list of entries in the FieldList
+ * Note: FieldList can be of zero length. In this case, Arg will be NULL.
+ */
+ while (Arg)
+ {
+ /*
+ * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
+ * in the field names in order to enter them into the namespace.
+ */
+ if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
+ Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ if (Status != AE_ALREADY_EXISTS)
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Name already exists, just ignore this error */
+
+ Status = AE_OK;
+ }
+
+ Arg->Common.Node = Node;
+ }
+
+ /* Get the next field element in the list */
+
+ Arg = Arg->Common.Next;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateBankField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new bank field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateBankField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
+
+
+ /* First arg is the name of the parent OpRegion (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+ if (!RegionNode)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
+ ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Second arg is the Bank Register (Field) (must already exist) */
+
+ Arg = Arg->Common.Next;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Third arg is the BankValue
+ * This arg is a TermArg, not a constant
+ * It will be evaluated later, by AcpiDsEvalBankFieldOperands
+ */
+ Arg = Arg->Common.Next;
+
+ /* Fourth arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
+ Info.RegionNode = RegionNode;
+
+ /*
+ * Use Info.DataRegisterNode to store BankField Op
+ * It's safe because DataRegisterNode will never be used when create bank field
+ * We store AmlStart and AmlLength in the BankField Op for late evaluation
+ * Used in AcpiExPrepFieldValue(Info)
+ *
+ * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
+ */
+ Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateIndexField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new index field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateIndexField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
+
+
+ /* First arg is the name of the Index register (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Second arg is the data register (must already exist) */
+
+ Arg = Arg->Common.Next;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Next arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
+ Info.RegionNode = RegionNode;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsinit.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
new file mode 100644
index 0000000000..48b2799ac7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ * Module Name: dsinit - Object initialization namespace walk
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsinit")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitOneObject
+ *
+ * PARAMETERS: ObjHandle - Node for the object
+ * Level - Current nesting level
+ * Context - Points to a init info struct
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
+ * within the namespace.
+ *
+ * Currently, the only objects that require initialization are:
+ * 1) Methods
+ * 2) Operation Regions
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * We are only interested in NS nodes owned by the table that
+ * was just loaded
+ */
+ if (Node->OwnerId != Info->OwnerId)
+ {
+ return (AE_OK);
+ }
+
+ Info->ObjectCount++;
+
+ /* And even then, we are only interested in a few object types */
+
+ switch (AcpiNsGetType (ObjHandle))
+ {
+ case ACPI_TYPE_REGION:
+
+ Status = AcpiDsInitializeRegion (ObjHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "During Region initialization %p [%4.4s]",
+ ObjHandle, AcpiUtGetNodeName (ObjHandle)));
+ }
+
+ Info->OpRegionCount++;
+ break;
+
+ case ACPI_TYPE_METHOD:
+ /*
+ * Auto-serialization support. We will examine each method that is
+ * NotSerialized to determine if it creates any Named objects. If
+ * it does, it will be marked serialized to prevent problems if
+ * the method is entered by two or more threads and an attempt is
+ * made to create the same named object twice -- which results in
+ * an AE_ALREADY_EXISTS exception and method abort.
+ */
+ Info->MethodCount++;
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ break;
+ }
+
+ /* Ignore if already serialized */
+
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
+ {
+ Info->SerialMethodCount++;
+ break;
+ }
+
+ if (AcpiGbl_AutoSerializeMethods)
+ {
+ /* Parse/scan method and serialize it if necessary */
+
+ AcpiDsAutoSerializeMethod (Node, ObjDesc);
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
+ {
+ /* Method was just converted to Serialized */
+
+ Info->SerialMethodCount++;
+ Info->SerializedMethodCount++;
+ break;
+ }
+ }
+
+ Info->NonSerialMethodCount++;
+ break;
+
+ case ACPI_TYPE_DEVICE:
+
+ Info->DeviceCount++;
+ break;
+
+ default:
+
+ break;
+ }
+
+ /*
+ * We ignore errors from above, and always return OK, since
+ * we don't want to abort the walk on a single error.
+ */
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitializeObjects
+ *
+ * PARAMETERS: TableDesc - Descriptor for parent ACPI table
+ * StartNode - Root of subtree to be initialized.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
+ * necessary initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitializeObjects (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode)
+{
+ ACPI_STATUS Status;
+ ACPI_INIT_WALK_INFO Info;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_OWNER_ID OwnerId;
+
+
+ ACPI_FUNCTION_TRACE (DsInitializeObjects);
+
+
+ Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "**** Starting initialization of namespace objects ****\n"));
+
+ /* Set all init info to zero */
+
+ memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+
+ Info.OwnerId = OwnerId;
+ Info.TableIndex = TableIndex;
+
+ /* Walk entire namespace from the supplied root */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * We don't use AcpiWalkNamespace since we do not want to acquire
+ * the namespace reader lock.
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
+ }
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* DSDT is always the first AML table */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\nInitializing Namespace objects:\n"));
+ }
+
+ /* Summary of objects initialized */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "Table [%4.4s:%8.8s] (id %.2X) - %4u Objects with %3u Devices, "
+ "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",
+ Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount, Info.DeviceCount,
+ Info.OpRegionCount, Info.MethodCount, Info.SerialMethodCount,
+ Info.NonSerialMethodCount, Info.SerializedMethodCount));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
+ Info.MethodCount, Info.OpRegionCount));
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c
new file mode 100644
index 0000000000..eafe1a5383
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c
@@ -0,0 +1,884 @@
+/******************************************************************************
+ *
+ * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsmethod")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsDetectNamedOpcodes (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp);
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+ ACPI_OPERAND_OBJECT *MethodDesc);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsAutoSerializeMethod
+ *
+ * PARAMETERS: Node - Namespace Node of the method
+ * ObjDesc - Method object attached to node
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse a control method AML to scan for control methods that
+ * need serialization due to the creation of named objects.
+ *
+ * NOTE: It is a bit of overkill to mark all such methods serialized, since
+ * there is only a problem if the method actually blocks during execution.
+ * A blocking operation is, for example, a Sleep() operation, or any access
+ * to an operation region. However, it is probably not possible to easily
+ * detect whether a method will block or not, so we simply mark all suspicious
+ * methods as serialized.
+ *
+ * NOTE2: This code is essentially a generic routine for parsing a single
+ * control method.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsAutoSerializeMethod (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op = NULL;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsAutoSerializeMethod, Node);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Method auto-serialization parse [%4.4s] %p\n",
+ AcpiUtGetNodeName (Node), Node));
+
+ /* Create/Init a root op for the method parse tree */
+
+ Op = AcpiPsAllocOp (AML_METHOD_OP, ObjDesc->Method.AmlStart);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ AcpiPsSetName (Op, Node->Name.Integer);
+ Op->Common.Node = Node;
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (Node->OwnerId, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ AcpiPsFreeOp (Op);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, Node, ObjDesc->Method.AmlStart,
+ ObjDesc->Method.AmlLength, NULL, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ AcpiPsFreeOp (Op);
+ return_ACPI_STATUS (Status);
+ }
+
+ WalkState->DescendingCallback = AcpiDsDetectNamedOpcodes;
+
+ /* Parse the method, scan for creation of named objects */
+
+ Status = AcpiPsParseAml (WalkState);
+
+ AcpiPsDeleteParseTree (Op);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDetectNamedOpcodes
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * OutOp - Unused, required for parser interface
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ * Currently used to detect methods that must be marked serialized
+ * in order to avoid problems with the creation of named objects.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsDetectNamedOpcodes (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp)
+{
+
+ ACPI_FUNCTION_NAME (AcpiDsDetectNamedOpcodes);
+
+
+ /* We are only interested in opcodes that create a new name */
+
+ if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_FIELD)))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * At this point, we know we have a Named object opcode.
+ * Mark the method as serialized. Later code will create a mutex for
+ * this method to enforce serialization.
+ *
+ * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the
+ * Sync Level mechanism for this method, even though it is now serialized.
+ * Otherwise, there can be conflicts with existing ASL code that actually
+ * uses sync levels.
+ */
+ WalkState->MethodDesc->Method.SyncLevel = 0;
+ WalkState->MethodDesc->Method.InfoFlags |=
+ (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Method serialized [%4.4s] %p - [%s] (%4.4X)\n",
+ WalkState->MethodNode->Name.Ascii, WalkState->MethodNode,
+ WalkState->OpInfo->Name, WalkState->Opcode));
+
+ /* Abort the parse, no need to examine this method any further */
+
+ return (AE_CTRL_TERMINATE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodError
+ *
+ * PARAMETERS: Status - Execution status
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called on method error. Invoke the global exception handler if
+ * present, dump the method data if the debugger is configured
+ *
+ * Note: Allows the exception handler to change the status code
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodError (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 AmlOffset;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Ignore AE_OK and control exception codes */
+
+ if (ACPI_SUCCESS (Status) ||
+ (Status & AE_CODE_CONTROL))
+ {
+ return (Status);
+ }
+
+ /* Invoke the global exception handler */
+
+ if (AcpiGbl_ExceptionHandler)
+ {
+ /* Exit the interpreter, allow handler to execute methods */
+
+ AcpiExExitInterpreter ();
+
+ /*
+ * Handler can map the exception code to anything it wants, including
+ * AE_OK, in which case the executing method will not be aborted.
+ */
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
+ WalkState->ParserState.AmlStart);
+
+ Status = AcpiGbl_ExceptionHandler (Status,
+ WalkState->MethodNode ?
+ WalkState->MethodNode->Name.Integer : 0,
+ WalkState->Opcode, AmlOffset, NULL);
+ AcpiExEnterInterpreter ();
+ }
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDumpMethodStack (Status, WalkState, WalkState->Op);
+
+ /* Display method locals/args if debugger is present */
+
+#ifdef ACPI_DEBUGGER
+ AcpiDbDumpMethodInfo (Status, WalkState);
+#endif
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateMethodMutex
+ *
+ * PARAMETERS: ObjDesc - The method object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a mutex object for a serialized control method
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+ ACPI_OPERAND_OBJECT *MethodDesc)
+{
+ ACPI_OPERAND_OBJECT *MutexDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DsCreateMethodMutex);
+
+
+ /* Create the new mutex object */
+
+ MutexDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
+ if (!MutexDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Create the actual OS Mutex */
+
+ Status = AcpiOsCreateMutex (&MutexDesc->Mutex.OsMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtDeleteObjectDesc (MutexDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+ MutexDesc->Mutex.SyncLevel = MethodDesc->Method.SyncLevel;
+ MethodDesc->Method.Mutex = MutexDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBeginMethodExecution
+ *
+ * PARAMETERS: MethodNode - Node of the method
+ * ObjDesc - The method object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
+ * increments the thread count, and waits at the method semaphore
+ * for clearance to execute.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBeginMethodExecution (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
+
+
+ if (!MethodNode)
+ {
+ return_ACPI_STATUS (AE_NULL_ENTRY);
+ }
+
+ AcpiExStartTraceMethod (MethodNode, ObjDesc, WalkState);
+
+ /* Prevent wraparound of thread count */
+
+ if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Method reached maximum reentrancy limit (255)"));
+ return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
+ }
+
+ /*
+ * If this method is serialized, we need to acquire the method mutex.
+ */
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
+ {
+ /*
+ * Create a mutex for the method if it is defined to be Serialized
+ * and a mutex has not already been created. We defer the mutex creation
+ * until a method is actually executed, to minimize the object count
+ */
+ if (!ObjDesc->Method.Mutex)
+ {
+ Status = AcpiDsCreateMethodMutex (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * The CurrentSyncLevel (per-thread) must be less than or equal to
+ * the sync level of the method. This mechanism provides some
+ * deadlock prevention.
+ *
+ * If the method was auto-serialized, we just ignore the sync level
+ * mechanism, because auto-serialization of methods can interfere
+ * with ASL code that actually uses sync levels.
+ *
+ * Top-level method invocation has no walk state at this point
+ */
+ if (WalkState &&
+ (!(ObjDesc->Method.InfoFlags & ACPI_METHOD_IGNORE_SYNC_LEVEL)) &&
+ (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
+ AcpiUtGetNodeName (MethodNode),
+ WalkState->Thread->CurrentSyncLevel));
+
+ return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ }
+
+ /*
+ * Obtain the method mutex if necessary. Do not acquire mutex for a
+ * recursive call.
+ */
+ if (!WalkState ||
+ !ObjDesc->Method.Mutex->Mutex.ThreadId ||
+ (WalkState->Thread->ThreadId != ObjDesc->Method.Mutex->Mutex.ThreadId))
+ {
+ /*
+ * Acquire the method mutex. This releases the interpreter if we
+ * block (and reacquires it before it returns)
+ */
+ Status = AcpiExSystemWaitMutex (ObjDesc->Method.Mutex->Mutex.OsMutex,
+ ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Update the mutex and walk info and save the original SyncLevel */
+
+ if (WalkState)
+ {
+ ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+ WalkState->Thread->CurrentSyncLevel;
+
+ ObjDesc->Method.Mutex->Mutex.ThreadId = WalkState->Thread->ThreadId;
+ WalkState->Thread->CurrentSyncLevel = ObjDesc->Method.SyncLevel;
+ }
+ else
+ {
+ ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+ ObjDesc->Method.Mutex->Mutex.SyncLevel;
+ }
+ }
+
+ /* Always increase acquisition depth */
+
+ ObjDesc->Method.Mutex->Mutex.AcquisitionDepth++;
+ }
+
+ /*
+ * Allocate an Owner ID for this method, only if this is the first thread
+ * to begin concurrent execution. We only need one OwnerId, even if the
+ * method is invoked recursively.
+ */
+ if (!ObjDesc->Method.OwnerId)
+ {
+ Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ /*
+ * Increment the method parse tree thread count since it has been
+ * reentered one more time (even if it is the same thread)
+ */
+ ObjDesc->Method.ThreadCount++;
+ AcpiMethodCount++;
+ return_ACPI_STATUS (Status);
+
+
+Cleanup:
+ /* On error, must release the method mutex (if present) */
+
+ if (ObjDesc->Method.Mutex)
+ {
+ AcpiOsReleaseMutex (ObjDesc->Method.Mutex->Mutex.OsMutex);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCallControlMethod
+ *
+ * PARAMETERS: Thread - Info for this thread
+ * ThisWalkState - Current walk state
+ * Op - Current Op to be walked
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transfer execution to a called control method
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCallControlMethod (
+ ACPI_THREAD_STATE *Thread,
+ ACPI_WALK_STATE *ThisWalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *MethodNode;
+ ACPI_WALK_STATE *NextWalkState = NULL;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_EVALUATE_INFO *Info;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n",
+ ThisWalkState->PrevOp, ThisWalkState));
+
+ /*
+ * Get the namespace entry for the control method we are about to call
+ */
+ MethodNode = ThisWalkState->MethodCallNode;
+ if (!MethodNode)
+ {
+ return_ACPI_STATUS (AE_NULL_ENTRY);
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (MethodNode);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Init for new method, possibly wait on method mutex */
+
+ Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
+ ThisWalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Begin method parse/execution. Create a new walk state */
+
+ NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
+ NULL, ObjDesc, Thread);
+ if (!NextWalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * The resolved arguments were put on the previous walk state's operand
+ * stack. Operands on the previous walk state stack always
+ * start at index 0. Also, null terminate the list of arguments
+ */
+ ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
+
+ /*
+ * Allocate and initialize the evaluation information block
+ * TBD: this is somewhat inefficient, should change interface to
+ * DsInitAmlWalk. For now, keeps this struct off the CPU stack
+ */
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ Info->Parameters = &ThisWalkState->Operands[0];
+
+ Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
+ ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
+ Info, ACPI_IMODE_EXECUTE);
+
+ ACPI_FREE (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Delete the operands on the previous walkstate operand stack
+ * (they were copied to new objects)
+ */
+ for (i = 0; i < ObjDesc->Method.ParamCount; i++)
+ {
+ AcpiUtRemoveReference (ThisWalkState->Operands [i]);
+ ThisWalkState->Operands [i] = NULL;
+ }
+
+ /* Clear the operand stack */
+
+ ThisWalkState->NumOperands = 0;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
+ MethodNode->Name.Ascii, NextWalkState));
+
+ /* Invoke an internal method if necessary */
+
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
+ {
+ Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
+ if (Status == AE_OK)
+ {
+ Status = AE_CTRL_TERMINATE;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+
+
+Cleanup:
+
+ /* On error, we must terminate the method properly */
+
+ AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
+ AcpiDsDeleteWalkState (NextWalkState);
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsRestartControlMethod
+ *
+ * PARAMETERS: WalkState - State for preempted method (caller)
+ * ReturnDesc - Return value from the called method
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Restart a method that was preempted by another (nested) method
+ * invocation. Handle the return value (if any) from the callee.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsRestartControlMethod (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ReturnDesc)
+{
+ ACPI_STATUS Status;
+ int SameAsImplicitReturn;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsRestartControlMethod, WalkState);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
+ AcpiUtGetNodeName (WalkState->MethodNode),
+ WalkState->MethodCallOp, ReturnDesc));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
+ WalkState->ReturnUsed,
+ WalkState->Results, WalkState));
+
+ /* Did the called method return a value? */
+
+ if (ReturnDesc)
+ {
+ /* Is the implicit return object the same as the return desc? */
+
+ SameAsImplicitReturn = (WalkState->ImplicitReturnObj == ReturnDesc);
+
+ /* Are we actually going to use the return value? */
+
+ if (WalkState->ReturnUsed)
+ {
+ /* Save the return value from the previous method */
+
+ Status = AcpiDsResultPush (ReturnDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Save as THIS method's return value in case it is returned
+ * immediately to yet another method
+ */
+ WalkState->ReturnDesc = ReturnDesc;
+ }
+
+ /*
+ * The following code is the optional support for the so-called
+ * "implicit return". Some AML code assumes that the last value of the
+ * method is "implicitly" returned to the caller, in the absence of an
+ * explicit return value.
+ *
+ * Just save the last result of the method as the return value.
+ *
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
+ */
+ else if (!AcpiDsDoImplicitReturn (ReturnDesc, WalkState, FALSE) ||
+ SameAsImplicitReturn)
+ {
+ /*
+ * Delete the return value if it will not be used by the
+ * calling method or remove one reference if the explicit return
+ * is the same as the implicit return value.
+ */
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsTerminateControlMethod
+ *
+ * PARAMETERS: MethodDesc - Method object
+ * WalkState - State associated with the method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Terminate a control method. Delete everything that the method
+ * created, delete all locals and arguments, and delete the parse
+ * tree if requested.
+ *
+ * MUTEX: Interpreter is locked
+ *
+ ******************************************************************************/
+
+void
+AcpiDsTerminateControlMethod (
+ ACPI_OPERAND_OBJECT *MethodDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ ACPI_FUNCTION_TRACE_PTR (DsTerminateControlMethod, WalkState);
+
+
+ /* MethodDesc is required, WalkState is optional */
+
+ if (!MethodDesc)
+ {
+ return_VOID;
+ }
+
+ if (WalkState)
+ {
+ /* Delete all arguments and locals */
+
+ AcpiDsMethodDataDeleteAll (WalkState);
+
+ /*
+ * If method is serialized, release the mutex and restore the
+ * current sync level for this thread
+ */
+ if (MethodDesc->Method.Mutex)
+ {
+ /* Acquisition Depth handles recursive calls */
+
+ MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--;
+ if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth)
+ {
+ WalkState->Thread->CurrentSyncLevel =
+ MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
+
+ AcpiOsReleaseMutex (MethodDesc->Method.Mutex->Mutex.OsMutex);
+ MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
+ }
+ }
+
+ /*
+ * Delete any namespace objects created anywhere within the
+ * namespace by the execution of this method. Unless:
+ * 1) This method is a module-level executable code method, in which
+ * case we want make the objects permanent.
+ * 2) There are other threads executing the method, in which case we
+ * will wait until the last thread has completed.
+ */
+ if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
+ (MethodDesc->Method.ThreadCount == 1))
+ {
+ /* Delete any direct children of (created by) this method */
+
+ AcpiNsDeleteNamespaceSubtree (WalkState->MethodNode);
+
+ /*
+ * Delete any objects that were created by this method
+ * elsewhere in the namespace (if any were created).
+ * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the
+ * deletion such that we don't have to perform an entire
+ * namespace walk for every control method execution.
+ */
+ if (MethodDesc->Method.InfoFlags & ACPI_METHOD_MODIFIED_NAMESPACE)
+ {
+ AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId);
+ MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_MODIFIED_NAMESPACE;
+ }
+ }
+ }
+
+ /* Decrement the thread count on the method */
+
+ if (MethodDesc->Method.ThreadCount)
+ {
+ MethodDesc->Method.ThreadCount--;
+ }
+ else
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid zero thread count in method"));
+ }
+
+ /* Are there any other threads currently executing this method? */
+
+ if (MethodDesc->Method.ThreadCount)
+ {
+ /*
+ * Additional threads. Do not release the OwnerId in this case,
+ * we immediately reuse it for the next thread executing this method
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "*** Completed execution of one thread, %u threads remaining\n",
+ MethodDesc->Method.ThreadCount));
+ }
+ else
+ {
+ /* This is the only executing thread for this method */
+
+ /*
+ * Support to dynamically change a method from NotSerialized to
+ * Serialized if it appears that the method is incorrectly written and
+ * does not support multiple thread execution. The best example of this
+ * is if such a method creates namespace objects and blocks. A second
+ * thread will fail with an AE_ALREADY_EXISTS exception.
+ *
+ * This code is here because we must wait until the last thread exits
+ * before marking the method as serialized.
+ */
+ if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING)
+ {
+ if (WalkState)
+ {
+ ACPI_INFO ((AE_INFO,
+ "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
+ WalkState->MethodNode->Name.Ascii));
+ }
+
+ /*
+ * Method tried to create an object twice and was marked as
+ * "pending serialized". The probable cause is that the method
+ * cannot handle reentrancy.
+ *
+ * The method was created as NotSerialized, but it tried to create
+ * a named object and then blocked, causing the second thread
+ * entrance to begin and then fail. Workaround this problem by
+ * marking the method permanently as Serialized when the last
+ * thread exits here.
+ */
+ MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_SERIALIZED_PENDING;
+ MethodDesc->Method.InfoFlags |=
+ (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL);
+ MethodDesc->Method.SyncLevel = 0;
+ }
+
+ /* No more threads, we can free the OwnerId */
+
+ if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
+ {
+ AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
+ }
+ }
+
+ AcpiExStopTraceMethod ((ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
+ MethodDesc, WalkState);
+
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c
new file mode 100644
index 0000000000..4b998d94c6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsmthdat.c
@@ -0,0 +1,768 @@
+/*******************************************************************************
+ *
+ * Module Name: dsmthdat - control method arguments and local variables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsmthdat")
+
+/* Local prototypes */
+
+static void
+AcpiDsMethodDataDeleteValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+AcpiDsMethodDataSetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_OBJECT_TYPE
+AcpiDsMethodDataGetType (
+ UINT16 Opcode,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataInit
+ *
+ * PARAMETERS: WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the data structures that hold the method's arguments
+ * and locals. The data struct is an array of namespace nodes for
+ * each - this allows RefOf and DeRefOf to work properly for these
+ * special data types.
+ *
+ * NOTES: WalkState fields are initialized to zero by the
+ * ACPI_ALLOCATE_ZEROED().
+ *
+ * A pseudo-Namespace Node is assigned to each argument and local
+ * so that RefOf() can return a pointer to the Node.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsMethodDataInit (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataInit);
+
+
+ /* Init the method arguments */
+
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
+ WalkState->Arguments[i].Name.Integer |= (i << 24);
+ WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
+ WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
+ WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
+ }
+
+ /* Init the method locals */
+
+ for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
+ {
+ ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
+
+ WalkState->LocalVariables[i].Name.Integer |= (i << 24);
+ WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
+ WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
+ WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataDeleteAll
+ *
+ * PARAMETERS: WalkState - Current walk state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete method locals and arguments. Arguments are only
+ * deleted if this method was called from another method.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsMethodDataDeleteAll (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 Index;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
+
+
+ /* Detach the locals */
+
+ for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
+ {
+ if (WalkState->LocalVariables[Index].Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
+ Index, WalkState->LocalVariables[Index].Object));
+
+ /* Detach object (if present) and remove a reference */
+
+ AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
+ }
+ }
+
+ /* Detach the arguments */
+
+ for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
+ {
+ if (WalkState->Arguments[Index].Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
+ Index, WalkState->Arguments[Index].Object));
+
+ /* Detach object (if present) and remove a reference */
+
+ AcpiNsDetachObject (&WalkState->Arguments[Index]);
+ }
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataInitArgs
+ *
+ * PARAMETERS: *Params - Pointer to a parameter list for the method
+ * MaxParamCount - The arg count for this method
+ * WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
+ * of ACPI operand objects, either null terminated or whose length
+ * is defined by MaxParamCount.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataInitArgs (
+ ACPI_OPERAND_OBJECT **Params,
+ UINT32 MaxParamCount,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ UINT32 Index = 0;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
+
+
+ if (!Params)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Copy passed parameters into the new method stack frame */
+
+ while ((Index < ACPI_METHOD_NUM_ARGS) &&
+ (Index < MaxParamCount) &&
+ Params[Index])
+ {
+ /*
+ * A valid parameter.
+ * Store the argument in the method/walk descriptor.
+ * Do not copy the arg in order to implement call by reference
+ */
+ Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
+ Params[Index], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Index++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetNode
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg whose type to get
+ * WalkState - Current walk state object
+ * Node - Where the node is returned.
+ *
+ * RETURN: Status and node
+ *
+ * DESCRIPTION: Get the Node associated with a local or arg.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataGetNode (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
+
+
+ /*
+ * Method Locals and Arguments are supported
+ */
+ switch (Type)
+ {
+ case ACPI_REFCLASS_LOCAL:
+
+ if (Index > ACPI_METHOD_MAX_LOCAL)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Local index %u is invalid (max %u)",
+ Index, ACPI_METHOD_MAX_LOCAL));
+ return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ }
+
+ /* Return a pointer to the pseudo-node */
+
+ *Node = &WalkState->LocalVariables[Index];
+ break;
+
+ case ACPI_REFCLASS_ARG:
+
+ if (Index > ACPI_METHOD_MAX_ARG)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Arg index %u is invalid (max %u)",
+ Index, ACPI_METHOD_MAX_ARG));
+ return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ }
+
+ /* Return a pointer to the pseudo-node */
+
+ *Node = &WalkState->Arguments[Index];
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataSetValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg to get
+ * Object - Object to be inserted into the stack entry
+ * WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
+ * Note: There is no "implicit conversion" for locals.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsMethodDataSetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
+ Type, Object->Common.ReferenceCount,
+ AcpiUtGetTypeName (Object->Common.Type)));
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Increment ref count so object can't be deleted while installed.
+ * NOTE: We do not copy the object in order to preserve the call by
+ * reference semantics of ACPI Control Method invocation.
+ * (See ACPI Specification 2.0C)
+ */
+ AcpiUtAddReference (Object);
+
+ /* Install the object */
+
+ Node->Object = Object;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which localVar or argument to get
+ * WalkState - Current walk state object
+ * DestDesc - Where Arg or Local value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve value of selected Arg or Local for this method
+ * Used only in AcpiExResolveToValue().
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataGetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **DestDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
+
+
+ /* Validate the object descriptor */
+
+ if (!DestDesc)
+ {
+ ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the object from the node */
+
+ Object = Node->Object;
+
+ /* Examine the returned object, it must be valid. */
+
+ if (!Object)
+ {
+ /*
+ * Index points to uninitialized object.
+ * This means that either 1) The expected argument was
+ * not passed to the method, or 2) A local variable
+ * was referenced by the method (via the ASL)
+ * before it was initialized. Either case is an error.
+ */
+
+ /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
+
+ if (AcpiGbl_EnableInterpreterSlack)
+ {
+ Object = AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!Object)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Node->Object = Object;
+ }
+
+ /* Otherwise, return the error */
+
+ else switch (Type)
+ {
+ case ACPI_REFCLASS_ARG:
+
+ ACPI_ERROR ((AE_INFO,
+ "Uninitialized Arg[%u] at node %p",
+ Index, Node));
+
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
+
+ case ACPI_REFCLASS_LOCAL:
+ /*
+ * No error message for this case, will be trapped again later to
+ * detect and ignore cases of Store(LocalX,LocalX)
+ */
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+ }
+
+ /*
+ * The Index points to an initialized and valid object.
+ * Return an additional reference to the object
+ */
+ *DestDesc = Object;
+ AcpiUtAddReference (Object);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataDeleteValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which localVar or argument to delete
+ * WalkState - Current walk state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
+ * a null into the stack slot after the object is deleted.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDsMethodDataDeleteValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
+
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /* Get the associated object */
+
+ Object = AcpiNsGetAttachedObject (Node);
+
+ /*
+ * Undefine the Arg or Local by setting its descriptor
+ * pointer to NULL. Locals/Args can contain both
+ * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
+ */
+ Node->Object = NULL;
+
+ if ((Object) &&
+ (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
+ {
+ /*
+ * There is a valid object.
+ * Decrement the reference count by one to balance the
+ * increment when the object was stored.
+ */
+ AcpiUtRemoveReference (Object);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsStoreObjectToLocal
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg to set
+ * ObjDesc - Value to be stored
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed
+ * as the new value for the Arg or Local and the reference count
+ * for ObjDesc is incremented.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsStoreObjectToLocal (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *CurrentObjDesc;
+ ACPI_OPERAND_OBJECT *NewObjDesc;
+
+
+ ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
+ Type, Index, ObjDesc));
+
+ /* Parameter validation */
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ CurrentObjDesc = AcpiNsGetAttachedObject (Node);
+ if (CurrentObjDesc == ObjDesc)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
+ ObjDesc));
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * If the reference count on the object is more than one, we must
+ * take a copy of the object before we store. A reference count
+ * of exactly 1 means that the object was just created during the
+ * evaluation of an expression, and we can safely use it since it
+ * is not used anywhere else.
+ */
+ NewObjDesc = ObjDesc;
+ if (ObjDesc->Common.ReferenceCount > 1)
+ {
+ Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * If there is an object already in this slot, we either
+ * have to delete it, or if this is an argument and there
+ * is an object reference stored there, we have to do
+ * an indirect store!
+ */
+ if (CurrentObjDesc)
+ {
+ /*
+ * Check for an indirect store if an argument
+ * contains an object reference (stored as an Node).
+ * We don't allow this automatic dereferencing for
+ * locals, since a store to a local should overwrite
+ * anything there, including an object reference.
+ *
+ * If both Arg0 and Local0 contain RefOf (Local4):
+ *
+ * Store (1, Arg0) - Causes indirect store to local4
+ * Store (1, Local0) - Stores 1 in local0, overwriting
+ * the reference to local4
+ * Store (1, DeRefof (Local0)) - Causes indirect store to local4
+ *
+ * Weird, but true.
+ */
+ if (Type == ACPI_REFCLASS_ARG)
+ {
+ /*
+ * If we have a valid reference object that came from RefOf(),
+ * do the indirect store
+ */
+ if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
+ (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Arg (%p) is an ObjRef(Node), storing in node %p\n",
+ NewObjDesc, CurrentObjDesc));
+
+ /*
+ * Store this object to the Node (perform the indirect store)
+ * NOTE: No implicit conversion is performed, as per the ACPI
+ * specification rules on storing to Locals/Args.
+ */
+ Status = AcpiExStoreObjectToNode (NewObjDesc,
+ CurrentObjDesc->Reference.Object, WalkState,
+ ACPI_NO_IMPLICIT_CONVERSION);
+
+ /* Remove local reference if we copied the object above */
+
+ if (NewObjDesc != ObjDesc)
+ {
+ AcpiUtRemoveReference (NewObjDesc);
+ }
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Delete the existing object before storing the new one */
+
+ AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
+ }
+
+ /*
+ * Install the Obj descriptor (*NewObjDesc) into
+ * the descriptor for the Arg or Local.
+ * (increments the object reference count by one)
+ */
+ Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
+
+ /* Remove local reference if we copied the object above */
+
+ if (NewObjDesc != ObjDesc)
+ {
+ AcpiUtRemoveReference (NewObjDesc);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetType
+ *
+ * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
+ * Index - Which Local or Arg whose type to get
+ * WalkState - Current walk state object
+ *
+ * RETURN: Data type of current value of the selected Arg or Local
+ *
+ * DESCRIPTION: Get the type of the object stored in the Local or Arg
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AcpiDsMethodDataGetType (
+ UINT16 Opcode,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataGetType);
+
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VALUE ((ACPI_TYPE_NOT_FOUND));
+ }
+
+ /* Get the object */
+
+ Object = AcpiNsGetAttachedObject (Node);
+ if (!Object)
+ {
+ /* Uninitialized local/arg, return TYPE_ANY */
+
+ return_VALUE (ACPI_TYPE_ANY);
+ }
+
+ /* Get the object type */
+
+ return_VALUE (Object->Type);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsobject.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
new file mode 100644
index 0000000000..33d0392752
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
@@ -0,0 +1,862 @@
+/******************************************************************************
+ *
+ * Module Name: dsobject - Dispatcher object management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsobject")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsBuildInternalObject (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT **ObjDescPtr);
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalObject
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
+ * Simple objects are any objects other than a package object!
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsBuildInternalObject (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE Type;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalObject);
+
+
+ *ObjDescPtr = NULL;
+ if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ /*
+ * This is a named object reference. If this name was
+ * previously looked up in the namespace, it was stored in this op.
+ * Otherwise, go ahead and look it up now
+ */
+ if (!Op->Common.Node)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Op->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
+ if (ACPI_FAILURE (Status))
+ {
+ /* Check if we are resolving a named reference within a package */
+
+ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
+
+ ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ /*
+ * We didn't find the target and we are populating elements
+ * of a package - ignore if slack enabled. Some ASL code
+ * contains dangling invalid references in packages and
+ * expects that no exception will be issued. Leave the
+ * element as a null element. It cannot be used, but it
+ * can be overwritten by subsequent ASL code - this is
+ * typically the case.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Ignoring unresolved reference in package [%4.4s]\n",
+ WalkState->ScopeInfo->Scope.Node->Name.Ascii));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+ else
+ {
+ ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Special object resolution for elements of a package */
+
+ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ /*
+ * Attempt to resolve the node to a value before we insert it into
+ * the package. If this is a reference to a common data type,
+ * resolve it immediately. According to the ACPI spec, package
+ * elements can only be "data objects" or method references.
+ * Attempt to resolve to an Integer, Buffer, String or Package.
+ * If cannot, return the named reference (for things like Devices,
+ * Methods, etc.) Buffer Fields and Fields will resolve to simple
+ * objects (int/buf/str/pkg).
+ *
+ * NOTE: References to things like Devices, Methods, Mutexes, etc.
+ * will remain as named references. This behavior is not described
+ * in the ACPI spec, but it appears to be an oversight.
+ */
+ ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
+
+ Status = AcpiExResolveNodeToValue (
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Special handling for Alias objects. We need to setup the type
+ * and the Op->Common.Node to point to the Alias target. Note,
+ * Alias has at most one level of indirection internally.
+ */
+ Type = Op->Common.Node->Type;
+ if (Type == ACPI_TYPE_LOCAL_ALIAS)
+ {
+ Type = ObjDesc->Common.Type;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ Op->Common.Node->Object);
+ }
+
+ switch (Type)
+ {
+ /*
+ * For these types, we need the actual node, not the subobject.
+ * However, the subobject did not get an extra reference count above.
+ *
+ * TBD: should ExResolveNodeToValue be changed to fix this?
+ */
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_THERMAL:
+
+ AcpiUtAddReference (Op->Common.Node->Object);
+
+ /*lint -fallthrough */
+ /*
+ * For these types, we need the actual node, not the subobject.
+ * The subobject got an extra reference count in ExResolveNodeToValue.
+ */
+ case ACPI_TYPE_MUTEX:
+ case ACPI_TYPE_METHOD:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_EVENT:
+ case ACPI_TYPE_REGION:
+
+ /* We will create a reference object for these types below */
+ break;
+
+ default:
+ /*
+ * All other types - the node was resolved to an actual
+ * object, we are done.
+ */
+ goto Exit;
+ }
+ }
+ }
+
+ /* Create and init a new internal ACPI object */
+
+ ObjDesc = AcpiUtCreateInternalObject (
+ (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode,
+ &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+Exit:
+ *ObjDescPtr = ObjDesc;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalBufferObj
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * BufferLength - Length of the buffer
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBuildInternalBufferObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 BufferLength,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PARSE_OBJECT *ByteList;
+ UINT32 ByteListLength = 0;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
+
+
+ /*
+ * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
+ * The buffer object already exists (from the NS node), otherwise it must
+ * be created.
+ */
+ ObjDesc = *ObjDescPtr;
+ if (!ObjDesc)
+ {
+ /* Create a new buffer object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
+ *ObjDescPtr = ObjDesc;
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+
+ /*
+ * Second arg is the buffer data (optional) ByteList can be either
+ * individual bytes or a string initializer. In either case, a
+ * ByteList appears in the AML.
+ */
+ Arg = Op->Common.Value.Arg; /* skip first arg */
+
+ ByteList = Arg->Named.Next;
+ if (ByteList)
+ {
+ if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Expecting bytelist, found AML opcode 0x%X in op %p",
+ ByteList->Common.AmlOpcode, ByteList));
+
+ AcpiUtRemoveReference (ObjDesc);
+ return (AE_TYPE);
+ }
+
+ ByteListLength = (UINT32) ByteList->Common.Value.Integer;
+ }
+
+ /*
+ * The buffer length (number of bytes) will be the larger of:
+ * 1) The specified buffer length and
+ * 2) The length of the initializer byte list
+ */
+ ObjDesc->Buffer.Length = BufferLength;
+ if (ByteListLength > BufferLength)
+ {
+ ObjDesc->Buffer.Length = ByteListLength;
+ }
+
+ /* Allocate the buffer */
+
+ if (ObjDesc->Buffer.Length == 0)
+ {
+ ObjDesc->Buffer.Pointer = NULL;
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Buffer defined with zero length in AML, creating\n"));
+ }
+ else
+ {
+ ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED (
+ ObjDesc->Buffer.Length);
+ if (!ObjDesc->Buffer.Pointer)
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize buffer from the ByteList (if present) */
+
+ if (ByteList)
+ {
+ memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
+ ByteListLength);
+ }
+ }
+
+ ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalPackageObj
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * ElementCount - Number of elements in the package - this is
+ * the NumElements argument to Package()
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
+ *
+ * NOTE: The number of elements in the package will be always be the NumElements
+ * count, regardless of the number of elements in the package list. If
+ * NumElements is smaller, only that many package list elements are used.
+ * if NumElements is larger, the Package object is padded out with
+ * objects of type Uninitialized (as per ACPI spec.)
+ *
+ * Even though the ASL compilers do not allow NumElements to be smaller
+ * than the Package list length (for the fixed length package opcode), some
+ * BIOS code modifies the AML on the fly to adjust the NumElements, and
+ * this code compensates for that. This also provides compatibility with
+ * other AML interpreters.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBuildInternalPackageObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ElementCount,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_PARSE_OBJECT *Parent;
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 i;
+ UINT16 Index;
+ UINT16 ReferenceCount;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
+
+
+ /* Find the parent of a possibly nested package */
+
+ Parent = Op->Common.Parent;
+ while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ Parent = Parent->Common.Parent;
+ }
+
+ /*
+ * If we are evaluating a Named package object "Name (xxxx, Package)",
+ * the package object already exists, otherwise it must be created.
+ */
+ ObjDesc = *ObjDescPtr;
+ if (!ObjDesc)
+ {
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
+ *ObjDescPtr = ObjDesc;
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Package.Node = Parent->Common.Node;
+ }
+
+ /*
+ * Allocate the element array (array of pointers to the individual
+ * objects) based on the NumElements parameter. Add an extra pointer slot
+ * so that the list is always null terminated.
+ */
+ ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
+
+ if (!ObjDesc->Package.Elements)
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Package.Count = ElementCount;
+
+ /*
+ * Initialize the elements of the package, up to the NumElements count.
+ * Package is automatically padded with uninitialized (NULL) elements
+ * if NumElements is greater than the package list length. Likewise,
+ * Package is truncated if NumElements is less than the list length.
+ */
+ Arg = Op->Common.Value.Arg;
+ Arg = Arg->Common.Next;
+ for (i = 0; Arg && (i < ElementCount); i++)
+ {
+ if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
+ {
+ if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
+ {
+ /*
+ * A method reference "looks" to the parser to be a method
+ * invocation, so we special case it here
+ */
+ Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
+ Status = AcpiDsBuildInternalObject (WalkState, Arg,
+ &ObjDesc->Package.Elements[i]);
+ }
+ else
+ {
+ /* This package element is already built, just get it */
+
+ ObjDesc->Package.Elements[i] =
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
+ }
+ }
+ else
+ {
+ Status = AcpiDsBuildInternalObject (WalkState, Arg,
+ &ObjDesc->Package.Elements[i]);
+ }
+
+ if (*ObjDescPtr)
+ {
+ /* Existing package, get existing reference count */
+
+ ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
+ if (ReferenceCount > 1)
+ {
+ /* Make new element ref count match original ref count */
+
+ for (Index = 0; Index < (ReferenceCount - 1); Index++)
+ {
+ AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
+ }
+ }
+ }
+
+ Arg = Arg->Common.Next;
+ }
+
+ /* Check for match between NumElements and actual length of PackageList */
+
+ if (Arg)
+ {
+ /*
+ * NumElements was exhausted, but there are remaining elements in the
+ * PackageList. Truncate the package to NumElements.
+ *
+ * Note: technically, this is an error, from ACPI spec: "It is an error
+ * for NumElements to be less than the number of elements in the
+ * PackageList". However, we just print a message and
+ * no exception is returned. This provides Windows compatibility. Some
+ * BIOSs will alter the NumElements on the fly, creating this type
+ * of ill-formed package object.
+ */
+ while (Arg)
+ {
+ /*
+ * We must delete any package elements that were created earlier
+ * and are not going to be used because of the package truncation.
+ */
+ if (Arg->Common.Node)
+ {
+ AcpiUtRemoveReference (
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
+ Arg->Common.Node = NULL;
+ }
+
+ /* Find out how many elements there really are */
+
+ i++;
+ Arg = Arg->Common.Next;
+ }
+
+ ACPI_INFO ((AE_INFO,
+ "Actual Package length (%u) is larger than NumElements field (%u), truncated",
+ i, ElementCount));
+ }
+ else if (i < ElementCount)
+ {
+ /*
+ * Arg list (elements) was exhausted, but we did not reach NumElements count.
+ * Note: this is not an error, the package is padded out with NULLs.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
+ i, ElementCount));
+ }
+
+ ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateNode
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Node - NS Node to be initialized
+ * Op - Parser object to be translated
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the object to be associated with a namespace node
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateNode (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
+
+
+ /*
+ * Because of the execution pass through the non-control-method
+ * parts of the table, we can arrive here twice. Only init
+ * the named object node the first time through
+ */
+ if (AcpiNsGetAttachedObject (Node))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (!Op->Common.Value.Arg)
+ {
+ /* No arguments, there is nothing to do */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Build an internal object for the argument(s) */
+
+ Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg,
+ &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Re-type the object according to its argument */
+
+ Node->Type = ObjDesc->Common.Type;
+
+ /* Attach obj to node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitObjectFromOp
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser op used to init the internal object
+ * Opcode - AML opcode associated with the object
+ * RetObjDesc - Namespace object to be initialized
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize a namespace object from a parser Op and its
+ * associated arguments. The namespace object is a more compact
+ * representation of the Op and its arguments.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitObjectFromOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT **RetObjDesc)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
+
+
+ ObjDesc = *RetObjDesc;
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+ if (OpInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ /* Unknown opcode */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Perform per-object initialization */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+ /*
+ * Defer evaluation of Buffer TermArg operand
+ */
+ ObjDesc->Buffer.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ WalkState->Operands[0]);
+ ObjDesc->Buffer.AmlStart = Op->Named.Data;
+ ObjDesc->Buffer.AmlLength = Op->Named.Length;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * Defer evaluation of Package TermArg operand
+ */
+ ObjDesc->Package.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ WalkState->Operands[0]);
+ ObjDesc->Package.AmlStart = Op->Named.Data;
+ ObjDesc->Package.AmlLength = Op->Named.Length;
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ switch (OpInfo->Type)
+ {
+ case AML_TYPE_CONSTANT:
+ /*
+ * Resolve AML Constants here - AND ONLY HERE!
+ * All constants are integers.
+ * We mark the integer with a flag that indicates that it started
+ * life as a constant -- so that stores to constants will perform
+ * as expected (noop). ZeroOp is used as a placeholder for optional
+ * target operands.
+ */
+ ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
+
+ switch (Opcode)
+ {
+ case AML_ZERO_OP:
+
+ ObjDesc->Integer.Value = 0;
+ break;
+
+ case AML_ONE_OP:
+
+ ObjDesc->Integer.Value = 1;
+ break;
+
+ case AML_ONES_OP:
+
+ ObjDesc->Integer.Value = ACPI_UINT64_MAX;
+
+ /* Truncate value if we are executing from a 32-bit ACPI table */
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ (void) AcpiExTruncateFor32bitTable (ObjDesc);
+#endif
+ break;
+
+ case AML_REVISION_OP:
+
+ ObjDesc->Integer.Value = ACPI_CA_VERSION;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown constant opcode 0x%X", Opcode));
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+ break;
+
+ case AML_TYPE_LITERAL:
+
+ ObjDesc->Integer.Value = Op->Common.Value.Integer;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ if (AcpiExTruncateFor32bitTable (ObjDesc))
+ {
+ /* Warn if we found a 64-bit constant in a 32-bit table */
+
+ ACPI_WARNING ((AE_INFO,
+ "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
+ ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
+ (UINT32) ObjDesc->Integer.Value));
+ }
+#endif
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
+ OpInfo->Type));
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ ObjDesc->String.Pointer = Op->Common.Value.String;
+ ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);
+
+ /*
+ * The string is contained in the ACPI table, don't ever try
+ * to delete it
+ */
+ ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
+ break;
+
+ case ACPI_TYPE_METHOD:
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ switch (OpInfo->Type)
+ {
+ case AML_TYPE_LOCAL_VARIABLE:
+
+ /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
+
+ ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
+ ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
+ ObjDesc->Reference.Value, WalkState,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
+ &ObjDesc->Reference.Object));
+#endif
+ break;
+
+ case AML_TYPE_METHOD_ARGUMENT:
+
+ /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
+
+ ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP;
+ ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
+ ObjDesc->Reference.Value, WalkState,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
+ &ObjDesc->Reference.Object));
+#endif
+ break;
+
+ default: /* Object name or Debug object */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_INT_NAMEPATH_OP:
+
+ /* Node was saved in Op */
+
+ ObjDesc->Reference.Node = Op->Common.Node;
+ ObjDesc->Reference.Object = Op->Common.Node->Object;
+ ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
+ break;
+
+ case AML_DEBUG_OP:
+
+ ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ break;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
+ ObjDesc->Common.Type));
+
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
new file mode 100644
index 0000000000..c69d9bd3c5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
@@ -0,0 +1,817 @@
+/******************************************************************************
+ *
+ * Module Name: dsopcode - Dispatcher support for regions and fields
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsopcode")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsInitBufferField (
+ UINT16 AmlOpcode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *BufferDesc,
+ ACPI_OPERAND_OBJECT *OffsetDesc,
+ ACPI_OPERAND_OBJECT *LengthDesc,
+ ACPI_OPERAND_OBJECT *ResultDesc);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitializeRegion
+ *
+ * PARAMETERS: ObjHandle - Region namespace node
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Front end to EvInitializeRegion
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitializeRegion (
+ ACPI_HANDLE ObjHandle)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
+
+ /* Namespace is NOT locked */
+
+ Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitBufferField
+ *
+ * PARAMETERS: AmlOpcode - CreateXxxField
+ * ObjDesc - BufferField object
+ * BufferDesc - Host Buffer
+ * OffsetDesc - Offset into buffer
+ * LengthDesc - Length of field (CREATE_FIELD_OP only)
+ * ResultDesc - Where to store the result
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform actual initialization of a buffer field
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsInitBufferField (
+ UINT16 AmlOpcode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *BufferDesc,
+ ACPI_OPERAND_OBJECT *OffsetDesc,
+ ACPI_OPERAND_OBJECT *LengthDesc,
+ ACPI_OPERAND_OBJECT *ResultDesc)
+{
+ UINT32 Offset;
+ UINT32 BitOffset;
+ UINT32 BitCount;
+ UINT8 FieldFlags;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
+
+
+ /* Host object must be a Buffer */
+
+ if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Target of Create Field is not a Buffer object - %s",
+ AcpiUtGetObjectTypeName (BufferDesc)));
+
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+
+ /*
+ * The last parameter to all of these opcodes (ResultDesc) started
+ * out as a NameString, and should therefore now be a NS node
+ * after resolution in AcpiExResolveOperands().
+ */
+ if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "(%s) destination not a NS Node [%s]",
+ AcpiPsGetOpcodeName (AmlOpcode),
+ AcpiUtGetDescriptorName (ResultDesc)));
+
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+
+ Offset = (UINT32) OffsetDesc->Integer.Value;
+
+ /*
+ * Setup the Bit offsets and counts, according to the opcode
+ */
+ switch (AmlOpcode)
+ {
+ case AML_CREATE_FIELD_OP:
+
+ /* Offset is in bits, count is in bits */
+
+ FieldFlags = AML_FIELD_ACCESS_BYTE;
+ BitOffset = Offset;
+ BitCount = (UINT32) LengthDesc->Integer.Value;
+
+ /* Must have a valid (>0) bit count */
+
+ if (BitCount == 0)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Attempt to CreateField of length zero"));
+ Status = AE_AML_OPERAND_VALUE;
+ goto Cleanup;
+ }
+ break;
+
+ case AML_CREATE_BIT_FIELD_OP:
+
+ /* Offset is in bits, Field is one bit */
+
+ BitOffset = Offset;
+ BitCount = 1;
+ FieldFlags = AML_FIELD_ACCESS_BYTE;
+ break;
+
+ case AML_CREATE_BYTE_FIELD_OP:
+
+ /* Offset is in bytes, field is one byte */
+
+ BitOffset = 8 * Offset;
+ BitCount = 8;
+ FieldFlags = AML_FIELD_ACCESS_BYTE;
+ break;
+
+ case AML_CREATE_WORD_FIELD_OP:
+
+ /* Offset is in bytes, field is one word */
+
+ BitOffset = 8 * Offset;
+ BitCount = 16;
+ FieldFlags = AML_FIELD_ACCESS_WORD;
+ break;
+
+ case AML_CREATE_DWORD_FIELD_OP:
+
+ /* Offset is in bytes, field is one dword */
+
+ BitOffset = 8 * Offset;
+ BitCount = 32;
+ FieldFlags = AML_FIELD_ACCESS_DWORD;
+ break;
+
+ case AML_CREATE_QWORD_FIELD_OP:
+
+ /* Offset is in bytes, field is one qword */
+
+ BitOffset = 8 * Offset;
+ BitCount = 64;
+ FieldFlags = AML_FIELD_ACCESS_QWORD;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown field creation opcode 0x%02X",
+ AmlOpcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+ /* Entire field must fit within the current length of the buffer */
+
+ if ((BitOffset + BitCount) >
+ (8 * (UINT32) BufferDesc->Buffer.Length))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
+ AcpiUtGetNodeName (ResultDesc),
+ BitOffset + BitCount,
+ AcpiUtGetNodeName (BufferDesc->Buffer.Node),
+ 8 * (UINT32) BufferDesc->Buffer.Length));
+ Status = AE_AML_BUFFER_LIMIT;
+ goto Cleanup;
+ }
+
+ /*
+ * Initialize areas of the field object that are common to all fields
+ * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
+ * UPDATE_RULE = 0 (UPDATE_PRESERVE)
+ */
+ Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
+ BitOffset, BitCount);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc->BufferField.BufferObj = BufferDesc;
+
+ /* Reference count for BufferDesc inherits ObjDesc count */
+
+ BufferDesc->Common.ReferenceCount = (UINT16)
+ (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
+
+
+Cleanup:
+
+ /* Always delete the operands */
+
+ AcpiUtRemoveReference (OffsetDesc);
+ AcpiUtRemoveReference (BufferDesc);
+
+ if (AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ AcpiUtRemoveReference (LengthDesc);
+ }
+
+ /* On failure, delete the result descriptor */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ResultDesc); /* Result descriptor */
+ }
+ else
+ {
+ /* Now the address and length are valid for this BufferField */
+
+ ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsEvalBufferFieldOperands
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - A valid BufferField Op object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get BufferField Buffer and Index
+ * Called from AcpiDsExecEndOp during BufferField parse tree walk
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvalBufferFieldOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
+
+
+ /*
+ * This is where we evaluate the address and length fields of the
+ * CreateXxxField declaration
+ */
+ Node = Op->Common.Node;
+
+ /* NextOp points to the op that holds the Buffer */
+
+ NextOp = Op->Common.Value.Arg;
+
+ /* Evaluate/create the address and length operands */
+
+ Status = AcpiDsCreateOperands (WalkState, NextOp);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Resolve the operands */
+
+ Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
+ ACPI_WALK_OPERANDS, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Initialize the Buffer Field */
+
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ /* NOTE: Slightly different operands for this opcode */
+
+ Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
+ WalkState->Operands[0], WalkState->Operands[1],
+ WalkState->Operands[2], WalkState->Operands[3]);
+ }
+ else
+ {
+ /* All other, CreateXxxField opcodes */
+
+ Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
+ WalkState->Operands[0], WalkState->Operands[1],
+ NULL, WalkState->Operands[2]);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsEvalRegionOperands
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - A valid region Op object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get region address and length
+ * Called from AcpiDsExecEndOp during OpRegion parse tree walk
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvalRegionOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *OperandDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
+
+
+ /*
+ * This is where we evaluate the address and length fields of the
+ * OpRegion declaration
+ */
+ Node = Op->Common.Node;
+
+ /* NextOp points to the op that holds the SpaceID */
+
+ NextOp = Op->Common.Value.Arg;
+
+ /* NextOp points to address op */
+
+ NextOp = NextOp->Common.Next;
+
+ /* Evaluate/create the address and length operands */
+
+ Status = AcpiDsCreateOperands (WalkState, NextOp);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Resolve the length and address operands to numbers */
+
+ Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
+ ACPI_WALK_OPERANDS, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /*
+ * Get the length operand and save it
+ * (at Top of stack)
+ */
+ OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
+
+ ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
+ AcpiUtRemoveReference (OperandDesc);
+
+ /*
+ * Get the address and save it
+ * (at top of stack - 1)
+ */
+ OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
+
+ ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
+ OperandDesc->Integer.Value;
+ AcpiUtRemoveReference (OperandDesc);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
+ ObjDesc,
+ ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
+ ObjDesc->Region.Length));
+
+ /* Now the address and length are valid for this opregion */
+
+ ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsEvalTableRegionOperands
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - A valid region Op object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get region address and length.
+ * Called from AcpiDsExecEndOp during DataTableRegion parse
+ * tree walk.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvalTableRegionOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT **Operand;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_TABLE_HEADER *Table;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
+
+
+ /*
+ * This is where we evaluate the Signature string, OemId string,
+ * and OemTableId string of the Data Table Region declaration
+ */
+ Node = Op->Common.Node;
+
+ /* NextOp points to Signature string op */
+
+ NextOp = Op->Common.Value.Arg;
+
+ /*
+ * Evaluate/create the Signature string, OemId string,
+ * and OemTableId string operands
+ */
+ Status = AcpiDsCreateOperands (WalkState, NextOp);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Operand = &WalkState->Operands[0];
+
+ /*
+ * Resolve the Signature string, OemId string,
+ * and OemTableId string operands
+ */
+ Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
+ ACPI_WALK_OPERANDS, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Find the ACPI table */
+
+ Status = AcpiTbFindTable (
+ Operand[0]->String.Pointer,
+ Operand[1]->String.Pointer,
+ Operand[2]->String.Pointer, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
+ Operand[0]->String.Pointer,
+ Operand[1]->String.Pointer,
+ Operand[2]->String.Pointer));
+ }
+ goto Cleanup;
+ }
+
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ Status = AE_NOT_EXIST;
+ goto Cleanup;
+ }
+
+ ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
+ ObjDesc->Region.Length = Table->Length;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
+ ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
+ ObjDesc->Region.Length));
+
+ /* Now the address and length are valid for this opregion */
+
+ ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
+
+Cleanup:
+ AcpiUtRemoveReference (Operand[0]);
+ AcpiUtRemoveReference (Operand[1]);
+ AcpiUtRemoveReference (Operand[2]);
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsEvalDataObjectOperands
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - A valid DataObject Op object
+ * ObjDesc - DataObject
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the operands and complete the following data object types:
+ * Buffer, Package.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvalDataObjectOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ArgDesc;
+ UINT32 Length;
+
+
+ ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
+
+
+ /* The first operand (for all of these data objects) is the length */
+
+ /*
+ * Set proper index into operand stack for AcpiDsObjStackPush
+ * invoked inside AcpiDsCreateOperand.
+ */
+ WalkState->OperandIndex = WalkState->NumOperands;
+
+ Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiExResolveOperands (WalkState->Opcode,
+ &(WalkState->Operands [WalkState->NumOperands -1]),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Extract length operand */
+
+ ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
+ Length = (UINT32) ArgDesc->Integer.Value;
+
+ /* Cleanup for length operand */
+
+ Status = AcpiDsObjStackPop (1, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiUtRemoveReference (ArgDesc);
+
+ /*
+ * Create the actual data object
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BUFFER_OP:
+
+ Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
+ break;
+
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Return the object in the WalkState, unless the parent is a package -
+ * in this case, the return object will be stored in the parse tree
+ * for the package.
+ */
+ if ((!Op->Common.Parent) ||
+ ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
+ (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
+ (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
+ {
+ WalkState->ResultObj = ObjDesc;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsEvalBankFieldOperands
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - A valid BankField Op object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get BankField BankValue
+ * Called from AcpiDsExecEndOp during BankField parse tree walk
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvalBankFieldOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *OperandDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *Arg;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
+
+
+ /*
+ * This is where we evaluate the BankValue field of the
+ * BankField declaration
+ */
+
+ /* NextOp points to the op that holds the Region */
+
+ NextOp = Op->Common.Value.Arg;
+
+ /* NextOp points to the op that holds the Bank Register */
+
+ NextOp = NextOp->Common.Next;
+
+ /* NextOp points to the op that holds the Bank Value */
+
+ NextOp = NextOp->Common.Next;
+
+ /*
+ * Set proper index into operand stack for AcpiDsObjStackPush
+ * invoked inside AcpiDsCreateOperand.
+ *
+ * We use WalkState->Operands[0] to store the evaluated BankValue
+ */
+ WalkState->OperandIndex = 0;
+
+ Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
+ /*
+ * Get the BankValue operand and save it
+ * (at Top of stack)
+ */
+ OperandDesc = WalkState->Operands[0];
+
+ /* Arg points to the start Bank Field */
+
+ Arg = AcpiPsGetArg (Op, 4);
+ while (Arg)
+ {
+ /* Ignore OFFSET and ACCESSAS terms here */
+
+ if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ Node = Arg->Common.Node;
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
+ }
+
+ /* Move to next field in the list */
+
+ Arg = Arg->Common.Next;
+ }
+
+ AcpiUtRemoveReference (OperandDesc);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
new file mode 100644
index 0000000000..9b23c11bcf
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
@@ -0,0 +1,940 @@
+/*******************************************************************************
+ *
+ * Module Name: dsutils - Dispatcher utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsClearImplicitReturn
+ *
+ * PARAMETERS: WalkState - Current State
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
+ * to delete "stale" return values (if enabled, the return value
+ * from every operator is saved at least momentarily, in case the
+ * parent method exits.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDsClearImplicitReturn (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_FUNCTION_NAME (DsClearImplicitReturn);
+
+
+ /*
+ * Slack must be enabled for this feature
+ */
+ if (!AcpiGbl_EnableInterpreterSlack)
+ {
+ return;
+ }
+
+ if (WalkState->ImplicitReturnObj)
+ {
+ /*
+ * Delete any "stale" implicit return. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Removing reference on stale implicit return obj %p\n",
+ WalkState->ImplicitReturnObj));
+
+ AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
+ WalkState->ImplicitReturnObj = NULL;
+ }
+}
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDoImplicitReturn
+ *
+ * PARAMETERS: ReturnDesc - The return value
+ * WalkState - Current State
+ * AddReference - True if a reference should be added to the
+ * return object
+ *
+ * RETURN: TRUE if implicit return enabled, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the optional "implicit return". We save the result
+ * of every ASL operator and control method invocation in case the
+ * parent method exit. Before storing a new return value, we
+ * delete the previous return value.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDsDoImplicitReturn (
+ ACPI_OPERAND_OBJECT *ReturnDesc,
+ ACPI_WALK_STATE *WalkState,
+ BOOLEAN AddReference)
+{
+ ACPI_FUNCTION_NAME (DsDoImplicitReturn);
+
+
+ /*
+ * Slack must be enabled for this feature, and we must
+ * have a valid return object
+ */
+ if ((!AcpiGbl_EnableInterpreterSlack) ||
+ (!ReturnDesc))
+ {
+ return (FALSE);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result %p will be implicitly returned; Prev=%p\n",
+ ReturnDesc,
+ WalkState->ImplicitReturnObj));
+
+ /*
+ * Delete any "stale" implicit return value first. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels, so we don't clear the value if it
+ * is the same as the ReturnDesc.
+ */
+ if (WalkState->ImplicitReturnObj)
+ {
+ if (WalkState->ImplicitReturnObj == ReturnDesc)
+ {
+ return (TRUE);
+ }
+ AcpiDsClearImplicitReturn (WalkState);
+ }
+
+ /* Save the implicit return value, add a reference if requested */
+
+ WalkState->ImplicitReturnObj = ReturnDesc;
+ if (AddReference)
+ {
+ AcpiUtAddReference (ReturnDesc);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsIsResultUsed
+ *
+ * PARAMETERS: Op - Current Op
+ * WalkState - Current State
+ *
+ * RETURN: TRUE if result is used, FALSE otherwise
+ *
+ * DESCRIPTION: Check if a result object will be used by the parent
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDsIsResultUsed (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ const ACPI_OPCODE_INFO *ParentInfo;
+
+ ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
+
+
+ /* Must have both an Op and a Result Object */
+
+ if (!Op)
+ {
+ ACPI_ERROR ((AE_INFO, "Null Op"));
+ return_UINT8 (TRUE);
+ }
+
+ /*
+ * We know that this operator is not a
+ * Return() operator (would not come here.) The following code is the
+ * optional support for a so-called "implicit return". Some AML code
+ * assumes that the last value of the method is "implicitly" returned
+ * to the caller. Just save the last result as the return value.
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
+ */
+ (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
+
+ /*
+ * Now determine if the parent will use the result
+ *
+ * If there is no parent, or the parent is a ScopeOp, we are executing
+ * at the method level. An executing method typically has no parent,
+ * since each method is parsed separately. A method invoked externally
+ * via ExecuteControlMethod has a ScopeOp as the parent.
+ */
+ if ((!Op->Common.Parent) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
+ {
+ /* No parent, the return value cannot possibly be used */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "At Method level, result of [%s] not used\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
+ return_UINT8 (FALSE);
+ }
+
+ /* Get info on the parent. The RootOp is AML_SCOPE */
+
+ ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
+ if (ParentInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Unknown parent opcode Op=%p", Op));
+ return_UINT8 (FALSE);
+ }
+
+ /*
+ * Decide what to do with the result based on the parent. If
+ * the parent opcode will not use the result, delete the object.
+ * Otherwise leave it as is, it will be deleted when it is used
+ * as an operand later.
+ */
+ switch (ParentInfo->Class)
+ {
+ case AML_CLASS_CONTROL:
+
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_RETURN_OP:
+
+ /* Never delete the return value associated with a return opcode */
+
+ goto ResultUsed;
+
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ /*
+ * If we are executing the predicate AND this is the predicate op,
+ * we will use the return value
+ */
+ if ((WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING) &&
+ (WalkState->ControlState->Control.PredicateOp == Op))
+ {
+ goto ResultUsed;
+ }
+ break;
+
+ default:
+
+ /* Ignore other control opcodes */
+
+ break;
+ }
+
+ /* The general control opcode returns no result */
+
+ goto ResultNotUsed;
+
+ case AML_CLASS_CREATE:
+ /*
+ * These opcodes allow TermArg(s) as operands and therefore
+ * the operands can be method calls. The result is used.
+ */
+ goto ResultUsed;
+
+ case AML_CLASS_NAMED_OBJECT:
+
+ if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
+ {
+ /*
+ * These opcodes allow TermArg(s) as operands and therefore
+ * the operands can be method calls. The result is used.
+ */
+ goto ResultUsed;
+ }
+
+ goto ResultNotUsed;
+
+ default:
+ /*
+ * In all other cases. the parent will actually use the return
+ * object, so keep it.
+ */
+ goto ResultUsed;
+ }
+
+
+ResultUsed:
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] used by Parent [%s] Op=%p\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
+ AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
+
+ return_UINT8 (TRUE);
+
+
+ResultNotUsed:
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] not used by Parent [%s] Op=%p\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
+ AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
+
+ return_UINT8 (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDeleteResultIfNotUsed
+ *
+ * PARAMETERS: Op - Current parse Op
+ * ResultObj - Result of the operation
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
+ * result descriptor, check if the parent opcode will actually use
+ * this result. If not, delete the result now so that it will
+ * not become orphaned.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsDeleteResultIfNotUsed (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ResultObj,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
+
+
+ if (!Op)
+ {
+ ACPI_ERROR ((AE_INFO, "Null Op"));
+ return_VOID;
+ }
+
+ if (!ResultObj)
+ {
+ return_VOID;
+ }
+
+ if (!AcpiDsIsResultUsed (Op, WalkState))
+ {
+ /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
+
+ Status = AcpiDsResultPop (&ObjDesc, WalkState);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiUtRemoveReference (ResultObj);
+ }
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsResolveOperands
+ *
+ * PARAMETERS: WalkState - Current walk state with operands on stack
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Resolve all operands to their values. Used to prepare
+ * arguments to a control method invocation (a call from one
+ * method to another.)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsResolveOperands (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
+
+
+ /*
+ * Attempt to resolve each of the valid operands
+ * Method arguments are passed by reference, not by value. This means
+ * that the actual objects are passed, not copies of the objects.
+ */
+ for (i = 0; i < WalkState->NumOperands; i++)
+ {
+ Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsClearOperands
+ *
+ * PARAMETERS: WalkState - Current walk state with operands on stack
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Clear all operands on the current walk state operand stack.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsClearOperands (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
+
+
+ /* Remove a reference on each operand on the stack */
+
+ for (i = 0; i < WalkState->NumOperands; i++)
+ {
+ /*
+ * Remove a reference to all operands, including both
+ * "Arguments" and "Targets".
+ */
+ AcpiUtRemoveReference (WalkState->Operands[i]);
+ WalkState->Operands[i] = NULL;
+ }
+
+ WalkState->NumOperands = 0;
+ return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateOperand
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Arg - Parse object for the argument
+ * ArgIndex - Which argument (zero based)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parse tree object that is an argument to an AML
+ * opcode to the equivalent interpreter object. This may include
+ * looking up a name or entering a new name into the internal
+ * namespace.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateOperand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg,
+ UINT32 ArgIndex)
+{
+ ACPI_STATUS Status = AE_OK;
+ char *NameString;
+ UINT32 NameLength;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PARSE_OBJECT *ParentOp;
+ UINT16 Opcode;
+ ACPI_INTERPRETER_MODE InterpreterMode;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
+
+
+ /* A valid name must be looked up in the namespace */
+
+ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (Arg->Common.Value.String) &&
+ !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
+
+ /* Get the entire name string from the AML stream */
+
+ Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer,
+ &NameString, &NameLength);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* All prefixes have been handled, and the name is in NameString */
+
+ /*
+ * Special handling for BufferField declarations. This is a deferred
+ * opcode that unfortunately defines the field name as the last
+ * parameter instead of the first. We get here when we are performing
+ * the deferred execution, so the actual name of the field is already
+ * in the namespace. We don't want to attempt to look it up again
+ * because we may be executing in a different scope than where the
+ * actual opcode exists.
+ */
+ if ((WalkState->DeferredNode) &&
+ (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
+ (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
+ {
+ ObjDesc = ACPI_CAST_PTR (
+ ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
+ Status = AE_OK;
+ }
+ else /* All other opcodes */
+ {
+ /*
+ * Differentiate between a namespace "create" operation
+ * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
+ * IMODE_EXECUTE) in order to support the creation of
+ * namespace objects during the execution of control methods.
+ */
+ ParentOp = Arg->Common.Parent;
+ OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
+ if ((OpInfo->Flags & AML_NSNODE) &&
+ (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
+ (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
+ (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
+ {
+ /* Enter name into namespace if not found */
+
+ InterpreterMode = ACPI_IMODE_LOAD_PASS2;
+ }
+ else
+ {
+ /* Return a failure if name not found */
+
+ InterpreterMode = ACPI_IMODE_EXECUTE;
+ }
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
+ ACPI_TYPE_ANY, InterpreterMode,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
+ /*
+ * The only case where we pass through (ignore) a NOT_FOUND
+ * error is for the CondRefOf opcode.
+ */
+ if (Status == AE_NOT_FOUND)
+ {
+ if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP)
+ {
+ /*
+ * For the Conditional Reference op, it's OK if
+ * the name is not found; We just need a way to
+ * indicate this to the interpreter, set the
+ * object to the root
+ */
+ ObjDesc = ACPI_CAST_PTR (
+ ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
+ Status = AE_OK;
+ }
+ else if (ParentOp->Common.AmlOpcode == AML_EXTERNAL_OP)
+ {
+ /* TBD: May only be temporary */
+
+ ObjDesc = AcpiUtCreateStringObject ((ACPI_SIZE) NameLength);
+
+ strncpy (ObjDesc->String.Pointer, NameString, NameLength);
+ Status = AE_OK;
+ }
+ else
+ {
+ /*
+ * We just plain didn't find it -- which is a
+ * very serious error at this point
+ */
+ Status = AE_AML_NAME_NOT_FOUND;
+ }
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (NameString, Status);
+ }
+ }
+
+ /* Free the namestring created above */
+
+ ACPI_FREE (NameString);
+
+ /* Check status from the lookup */
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Put the resulting object onto the current object stack */
+
+ Status = AcpiDsObjStackPush (ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
+ }
+ else
+ {
+ /* Check for null name case */
+
+ if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
+ {
+ /*
+ * If the name is null, this means that this is an
+ * optional result parameter that was not specified
+ * in the original ASL. Create a Zero Constant for a
+ * placeholder. (Store to a constant is a Noop.)
+ */
+ Opcode = AML_ZERO_OP; /* Has no arguments! */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Null namepath: Arg=%p\n", Arg));
+ }
+ else
+ {
+ Opcode = Arg->Common.AmlOpcode;
+ }
+
+ /* Get the object type of the argument */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+ if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
+ {
+ return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ }
+
+ if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Argument previously created, already stacked\n"));
+
+ ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (
+ WalkState->Operands [WalkState->NumOperands - 1], WalkState));
+
+ /*
+ * Use value that was already previously returned
+ * by the evaluation of this argument
+ */
+ Status = AcpiDsResultPop (&ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * Only error is underflow, and this indicates
+ * a missing or null operand!
+ */
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Missing or null operand"));
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ /* Create an ACPI_INTERNAL_OBJECT for the argument */
+
+ ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize the new object */
+
+ Status = AcpiDsInitObjectFromOp (
+ WalkState, Arg, Opcode, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Put the operand object on the object stack */
+
+ Status = AcpiDsObjStackPush (ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateOperands
+ *
+ * PARAMETERS: WalkState - Current state
+ * FirstArg - First argument of a parser argument tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an operator's arguments from a parse tree format to
+ * namespace objects and place those argument object on the object
+ * stack in preparation for evaluation by the interpreter.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *FirstArg)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_PARSE_OBJECT *Arguments[ACPI_OBJ_NUM_OPERANDS];
+ UINT32 ArgCount = 0;
+ UINT32 Index = WalkState->NumOperands;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
+
+
+ /* Get all arguments in the list */
+
+ Arg = FirstArg;
+ while (Arg)
+ {
+ if (Index >= ACPI_OBJ_NUM_OPERANDS)
+ {
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ Arguments[Index] = Arg;
+ WalkState->Operands [Index] = NULL;
+
+ /* Move on to next argument, if any */
+
+ Arg = Arg->Common.Next;
+ ArgCount++;
+ Index++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "NumOperands %d, ArgCount %d, Index %d\n",
+ WalkState->NumOperands, ArgCount, Index));
+
+ /* Create the interpreter arguments, in reverse order */
+
+ Index--;
+ for (i = 0; i < ArgCount; i++)
+ {
+ Arg = Arguments[Index];
+ WalkState->OperandIndex = (UINT8) Index;
+
+ Status = AcpiDsCreateOperand (WalkState, Arg, Index);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Created Arg #%u (%p) %u args total\n",
+ Index, Arg, ArgCount));
+ Index--;
+ }
+
+ return_ACPI_STATUS (Status);
+
+
+Cleanup:
+ /*
+ * We must undo everything done above; meaning that we must
+ * pop everything off of the operand stack and delete those
+ * objects
+ */
+ AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
+ return_ACPI_STATUS (Status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiDsEvaluateNamePath
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk,
+ * the opcode of current operation should be
+ * AML_INT_NAMEPATH_OP
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
+ * interpreter object, convert it to value, if needed, duplicate
+ * it, if needed, and push it onto the current result stack.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiDsEvaluateNamePath (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Op = WalkState->Op;
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *NewObjDesc;
+ UINT8 Type;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
+
+
+ if (!Op->Common.Parent)
+ {
+ /* This happens after certain exception processing */
+
+ goto Exit;
+ }
+
+ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
+ {
+ /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
+
+ goto Exit;
+ }
+
+ Status = AcpiDsCreateOperand (WalkState, Op, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
+ {
+ NewObjDesc = *Operand;
+ goto PushResult;
+ }
+
+ Type = (*Operand)->Common.Type;
+
+ Status = AcpiExResolveToValue (Operand, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ if (Type == ACPI_TYPE_INTEGER)
+ {
+ /* It was incremented by AcpiExResolveToValue */
+
+ AcpiUtRemoveReference (*Operand);
+
+ Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+ }
+ else
+ {
+ /*
+ * The object either was anew created or is
+ * a Namespace node - don't decrement it.
+ */
+ NewObjDesc = *Operand;
+ }
+
+ /* Cleanup for name-path operand */
+
+ Status = AcpiDsObjStackPop (1, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ WalkState->ResultObj = NewObjDesc;
+ goto Exit;
+ }
+
+PushResult:
+
+ WalkState->ResultObj = NewObjDesc;
+
+ Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Force to take it from stack */
+
+ Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
+ }
+
+Exit:
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswexec.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
new file mode 100644
index 0000000000..f391fe0e02
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
@@ -0,0 +1,782 @@
+/******************************************************************************
+ *
+ * Module Name: dswexec - Dispatcher method execution callbacks;
+ * dispatch to interpreter.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dswexec")
+
+/*
+ * Dispatch table for opcode classes
+ */
+static ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] =
+{
+ AcpiExOpcode_0A_0T_1R,
+ AcpiExOpcode_1A_0T_0R,
+ AcpiExOpcode_1A_0T_1R,
+ AcpiExOpcode_1A_1T_0R,
+ AcpiExOpcode_1A_1T_1R,
+ AcpiExOpcode_2A_0T_0R,
+ AcpiExOpcode_2A_0T_1R,
+ AcpiExOpcode_2A_1T_1R,
+ AcpiExOpcode_2A_2T_1R,
+ AcpiExOpcode_3A_0T_0R,
+ AcpiExOpcode_3A_1T_1R,
+ AcpiExOpcode_6A_0T_1R
+};
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiDsGetPredicateValue
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * ResultObj - if non-zero, pop result from result stack
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the result of a predicate evaluation
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetPredicateValue (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ResultObj)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *LocalObjDesc = NULL;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
+
+
+ WalkState->ControlState->Common.State = 0;
+
+ if (ResultObj)
+ {
+ Status = AcpiDsResultPop (&ObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not get result from predicate evaluation"));
+
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ObjDesc = WalkState->Operands [0];
+ }
+
+ if (!ObjDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No predicate ObjDesc=%p State=%p",
+ ObjDesc, WalkState));
+
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ /*
+ * Result of predicate evaluation must be an Integer
+ * object. Implicitly convert the argument if necessary.
+ */
+ Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
+ ObjDesc, WalkState, ObjDesc->Common.Type));
+
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+
+ /* Truncate the predicate to 32-bits if necessary */
+
+ (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
+
+ /*
+ * Save the result of the predicate evaluation on
+ * the control stack
+ */
+ if (LocalObjDesc->Integer.Value)
+ {
+ WalkState->ControlState->Common.Value = TRUE;
+ }
+ else
+ {
+ /*
+ * Predicate is FALSE, we will just toss the
+ * rest of the package
+ */
+ WalkState->ControlState->Common.Value = FALSE;
+ Status = AE_CTRL_FALSE;
+ }
+
+ /* Predicate can be used for an implicit return value */
+
+ (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
+
+
+Cleanup:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
+ WalkState->ControlState->Common.Value, WalkState->Op));
+
+ /* Break to debugger to display result */
+
+ ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState));
+
+ /*
+ * Delete the predicate result object (we know that
+ * we don't need it anymore)
+ */
+ if (LocalObjDesc != ObjDesc)
+ {
+ AcpiUtRemoveReference (LocalObjDesc);
+ }
+ AcpiUtRemoveReference (ObjDesc);
+
+ WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiDsExecBeginOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * OutOp - Where to return op if a new one is created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the execution of control
+ * methods. This is where most operators and operands are
+ * dispatched to the interpreter.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecBeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 OpcodeClass;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
+
+
+ Op = WalkState->Op;
+ if (!Op)
+ {
+ Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ Op = *OutOp;
+ WalkState->Op = Op;
+ WalkState->Opcode = Op->Common.AmlOpcode;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "(%s) Popping scope for Op %p\n",
+ AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
+
+ Status = AcpiDsScopeStackPop (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+ }
+ }
+
+ if (Op == WalkState->Origin)
+ {
+ if (OutOp)
+ {
+ *OutOp = Op;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * If the previous opcode was a conditional, this opcode
+ * must be the beginning of the associated predicate.
+ * Save this knowledge in the current scope descriptor
+ */
+ if ((WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_CONDITIONAL_EXECUTING))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
+ Op, WalkState));
+
+ WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING;
+
+ /* Save start of predicate */
+
+ WalkState->ControlState->Control.PredicateOp = Op;
+ }
+
+
+ OpcodeClass = WalkState->OpInfo->Class;
+
+ /* We want to send namepaths to the load code */
+
+ if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ OpcodeClass = AML_CLASS_NAMED_OBJECT;
+ }
+
+ /*
+ * Handle the opcode based upon the opcode type
+ */
+ switch (OpcodeClass)
+ {
+ case AML_CLASS_CONTROL:
+
+ Status = AcpiDsExecBeginControlOp (WalkState, Op);
+ break;
+
+ case AML_CLASS_NAMED_OBJECT:
+
+ if (WalkState->WalkType & ACPI_WALK_METHOD)
+ {
+ /*
+ * Found a named object declaration during method execution;
+ * we must enter this object into the namespace. The created
+ * object is temporary and will be deleted upon completion of
+ * the execution of this method.
+ *
+ * Note 10/2010: Except for the Scope() op. This opcode does
+ * not actually create a new object, it refers to an existing
+ * object. However, for Scope(), we want to indeed open a
+ * new scope.
+ */
+ if (Op->Common.AmlOpcode != AML_SCOPE_OP)
+ {
+ Status = AcpiDsLoad2BeginOp (WalkState, NULL);
+ }
+ else
+ {
+ Status = AcpiDsScopeStackPush (Op->Named.Node,
+ Op->Named.Node->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+ break;
+
+ case AML_CLASS_EXECUTE:
+ case AML_CLASS_CREATE:
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Nothing to do here during method execution */
+
+ return_ACPI_STATUS (Status);
+
+
+ErrorExit:
+ Status = AcpiDsMethodError (Status, WalkState);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiDsExecEndOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback used during the execution of control
+ * methods. The only thing we really need to do here is to
+ * notice the beginning of IF, ELSE, and WHILE blocks.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecEndOp (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 OpType;
+ UINT32 OpClass;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *FirstArg;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
+
+
+ Op = WalkState->Op;
+ OpType = WalkState->OpInfo->Type;
+ OpClass = WalkState->OpInfo->Class;
+
+ if (OpClass == AML_CLASS_UNKNOWN)
+ {
+ ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
+ return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ }
+
+ FirstArg = Op->Common.Value.Arg;
+
+ /* Init the walk state */
+
+ WalkState->NumOperands = 0;
+ WalkState->OperandIndex = 0;
+ WalkState->ReturnDesc = NULL;
+ WalkState->ResultObj = NULL;
+
+ /* Call debugger for single step support (DEBUG build only) */
+
+ ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass));
+ ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);});
+
+ /* Decode the Opcode Class */
+
+ switch (OpClass)
+ {
+ case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
+
+ if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
+ {
+ Status = AcpiDsEvaluateNamePath (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+ break;
+
+ case AML_CLASS_EXECUTE: /* Most operators with arguments */
+
+ /* Build resolved operand stack */
+
+ Status = AcpiDsCreateOperands (WalkState, FirstArg);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * All opcodes require operand resolution, with the only exceptions
+ * being the ObjectType and SizeOf operators.
+ */
+ if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE))
+ {
+ /* Resolve all operands */
+
+ Status = AcpiExResolveOperands (WalkState->Opcode,
+ &(WalkState->Operands [WalkState->NumOperands -1]),
+ WalkState);
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Dispatch the request to the appropriate interpreter handler
+ * routine. There is one routine per opcode "type" based upon the
+ * number of opcode arguments and return type.
+ */
+ Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
+ }
+ else
+ {
+ /*
+ * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
+ * Local is uninitialized.
+ */
+ if ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
+ (WalkState->Opcode == AML_STORE_OP) &&
+ (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (WalkState->Operands[0]->Reference.Class ==
+ WalkState->Operands[1]->Reference.Class) &&
+ (WalkState->Operands[0]->Reference.Value ==
+ WalkState->Operands[1]->Reference.Value))
+ {
+ Status = AE_OK;
+ }
+ else
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While resolving operands for [%s]",
+ AcpiPsGetOpcodeName (WalkState->Opcode)));
+ }
+ }
+
+ /* Always delete the argument objects and clear the operand stack */
+
+ AcpiDsClearOperands (WalkState);
+
+ /*
+ * If a result object was returned from above, push it on the
+ * current result stack
+ */
+ if (ACPI_SUCCESS (Status) &&
+ WalkState->ResultObj)
+ {
+ Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
+ }
+ break;
+
+ default:
+
+ switch (OpType)
+ {
+ case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
+
+ /* 1 Operand, 0 ExternalResult, 0 InternalResult */
+
+ Status = AcpiDsExecEndControlOp (WalkState, Op);
+
+ break;
+
+ case AML_TYPE_METHOD_CALL:
+ /*
+ * If the method is referenced from within a package
+ * declaration, it is not a invocation of the method, just
+ * a reference to it.
+ */
+ if ((Op->Asl.Parent) &&
+ ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Method Reference in a Package, Op=%p\n", Op));
+
+ Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node;
+ AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Method invocation, Op=%p\n", Op));
+
+ /*
+ * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
+ * the method Node pointer
+ */
+ /* NextOp points to the op that holds the method name */
+
+ NextOp = FirstArg;
+
+ /* NextOp points to first argument op */
+
+ NextOp = NextOp->Common.Next;
+
+ /*
+ * Get the method's arguments and put them on the operand stack
+ */
+ Status = AcpiDsCreateOperands (WalkState, NextOp);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ /*
+ * Since the operands will be passed to another control method,
+ * we must resolve all local references here (Local variables,
+ * arguments to *this* method, etc.)
+ */
+ Status = AcpiDsResolveOperands (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ /* On error, clear all resolved operands */
+
+ AcpiDsClearOperands (WalkState);
+ break;
+ }
+
+ /*
+ * Tell the walk loop to preempt this running method and
+ * execute the new method
+ */
+ Status = AE_CTRL_TRANSFER;
+
+ /*
+ * Return now; we don't want to disturb anything,
+ * especially the operand count!
+ */
+ return_ACPI_STATUS (Status);
+
+ case AML_TYPE_CREATE_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Executing CreateField Buffer/Index Op=%p\n", Op));
+
+ Status = AcpiDsLoad2EndOp (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
+ break;
+
+
+ case AML_TYPE_CREATE_OBJECT:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Executing CreateObject (Buffer/Package) Op=%p\n", Op));
+
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_NAME_OP:
+ /*
+ * Put the Node on the object stack (Contains the ACPI Name
+ * of this object)
+ */
+ WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node;
+ WalkState->NumOperands = 1;
+
+ Status = AcpiDsCreateNode (WalkState,
+ Op->Common.Parent->Common.Node,
+ Op->Common.Parent);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ /* Fall through */
+ /*lint -fallthrough */
+
+ case AML_INT_EVAL_SUBTREE_OP:
+
+ Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
+ AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
+ break;
+
+ default:
+
+ Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
+ break;
+ }
+
+ /*
+ * If a result object was returned from above, push it on the
+ * current result stack
+ */
+ if (WalkState->ResultObj)
+ {
+ Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
+ }
+ break;
+
+ case AML_TYPE_NAMED_FIELD:
+ case AML_TYPE_NAMED_COMPLEX:
+ case AML_TYPE_NAMED_SIMPLE:
+ case AML_TYPE_NAMED_NO_OBJ:
+
+ Status = AcpiDsLoad2EndOp (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ if (Op->Common.AmlOpcode == AML_REGION_OP)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Executing OpRegion Address/Length Op=%p\n", Op));
+
+ Status = AcpiDsEvalRegionOperands (WalkState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Executing DataTableRegion Strings Op=%p\n", Op));
+
+ Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Executing BankField Op=%p\n", Op));
+
+ Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+ break;
+
+ case AML_TYPE_UNDEFINED:
+
+ ACPI_ERROR ((AE_INFO,
+ "Undefined opcode type Op=%p", Op));
+ return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+
+ case AML_TYPE_BOGUS:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Internal opcode=%X type Op=%p\n",
+ WalkState->Opcode, Op));
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unimplemented opcode, class=0x%X type=0x%X Opcode=0x%X Op=%p",
+ OpClass, OpType, Op->Common.AmlOpcode, Op));
+
+ Status = AE_NOT_IMPLEMENTED;
+ break;
+ }
+ }
+
+ /*
+ * ACPI 2.0 support for 64-bit integers: Truncate numeric
+ * result value if we are executing from a 32-bit ACPI table
+ */
+ (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
+
+ /*
+ * Check if we just completed the evaluation of a
+ * conditional predicate
+ */
+ if ((ACPI_SUCCESS (Status)) &&
+ (WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_PREDICATE_EXECUTING) &&
+ (WalkState->ControlState->Control.PredicateOp == Op))
+ {
+ Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
+ WalkState->ResultObj = NULL;
+ }
+
+
+Cleanup:
+
+ if (WalkState->ResultObj)
+ {
+ /* Break to debugger to display result */
+
+ ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj,
+ WalkState));
+
+ /*
+ * Delete the result op if and only if:
+ * Parent will not use the result -- such as any
+ * non-nested type2 op in a method (parent will be method)
+ */
+ AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
+ }
+
+#ifdef _UNDER_DEVELOPMENT
+
+ if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
+ {
+ AcpiDbMethodEnd (WalkState);
+ }
+#endif
+
+ /* Invoke exception handler on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AcpiDsMethodError (Status, WalkState);
+ }
+
+ /* Always clear the object stack */
+
+ WalkState->NumOperands = 0;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload.c
new file mode 100644
index 0000000000..c9b512453a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload.c
@@ -0,0 +1,589 @@
+/******************************************************************************
+ *
+ * Module Name: dswload - Dispatcher first pass namespace load callbacks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/include/acdisasm.h>
+#endif
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dswload")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitCallbacks
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * PassNumber - 1, 2, or 3
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Init walk state callbacks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitCallbacks (
+ ACPI_WALK_STATE *WalkState,
+ UINT32 PassNumber)
+{
+
+ switch (PassNumber)
+ {
+ case 0:
+
+ /* Parse only - caller will setup callbacks */
+
+ WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE |
+ ACPI_PARSE_DISASSEMBLE;
+ WalkState->DescendingCallback = NULL;
+ WalkState->AscendingCallback = NULL;
+ break;
+
+ case 1:
+
+ /* Load pass 1 */
+
+ WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
+ WalkState->DescendingCallback = AcpiDsLoad1BeginOp;
+ WalkState->AscendingCallback = AcpiDsLoad1EndOp;
+ break;
+
+ case 2:
+
+ /* Load pass 2 */
+
+ WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
+ WalkState->DescendingCallback = AcpiDsLoad2BeginOp;
+ WalkState->AscendingCallback = AcpiDsLoad2EndOp;
+ break;
+
+ case 3:
+
+ /* Execution pass */
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ WalkState->ParseFlags |= ACPI_PARSE_EXECUTE |
+ ACPI_PARSE_DELETE_TREE;
+ WalkState->DescendingCallback = AcpiDsExecBeginOp;
+ WalkState->AscendingCallback = AcpiDsExecEndOp;
+#endif
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsLoad1BeginOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * OutOp - Where to return op if a new one is created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad1BeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE ObjectType;
+ char *Path;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE (DsLoad1BeginOp);
+
+
+ Op = WalkState->Op;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
+
+ /* We are only interested in opcodes that have an associated name */
+
+ if (Op)
+ {
+ if (!(WalkState->OpInfo->Flags & AML_NAMED))
+ {
+ *OutOp = Op;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Check if this object has already been installed in the namespace */
+
+ if (Op->Common.Node)
+ {
+ *OutOp = Op;
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ Path = AcpiPsGetNextNamestring (&WalkState->ParserState);
+
+ /* Map the raw opcode into an internal object type */
+
+ ObjectType = WalkState->OpInfo->ObjectType;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "State=%p Op=%p [%s]\n", WalkState, Op, AcpiUtGetTypeName (ObjectType)));
+
+ switch (WalkState->Opcode)
+ {
+ case AML_SCOPE_OP:
+ /*
+ * The target name of the Scope() operator must exist at this point so
+ * that we can actually open the scope to enter new names underneath it.
+ * Allow search-to-root for single namesegs.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node));
+#ifdef ACPI_ASL_COMPILER
+ if (Status == AE_NOT_FOUND)
+ {
+ /*
+ * Table disassembly:
+ * Target of Scope() not found. Generate an External for it, and
+ * insert the name into the namespace.
+ */
+ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0, 0);
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
+ WalkState, &Node);
+ }
+#endif
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Path, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Check to make sure that the target is
+ * one of the opcodes that actually opens a scope
+ */
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_ANY:
+ case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+
+ /* These are acceptable types */
+ break;
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * These types we will allow, but we will change the type.
+ * This enables some existing code of the form:
+ *
+ * Name (DEB, 0)
+ * Scope (DEB) { ... }
+ *
+ * Note: silently change the type here. On the second pass,
+ * we will report a warning
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Type override - [%4.4s] had invalid type (%s) "
+ "for Scope operator, changed to type ANY\n",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
+
+ Node->Type = ACPI_TYPE_ANY;
+ WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
+ break;
+
+ case ACPI_TYPE_METHOD:
+ /*
+ * Allow scope change to root during execution of module-level
+ * code. Root is typed METHOD during this time.
+ */
+ if ((Node == AcpiGbl_RootNode) &&
+ (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ break;
+ }
+
+ /*lint -fallthrough */
+
+ default:
+
+ /* All other types are an error */
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid type (%s) for target of "
+ "Scope operator [%4.4s] (Cannot override)",
+ AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ break;
+
+ default:
+ /*
+ * For all other named opcodes, we will enter the name into
+ * the namespace.
+ *
+ * Setup the search flags.
+ * Since we are entering a name into the namespace, we do not want to
+ * enable the search-to-root upsearch.
+ *
+ * There are only two conditions where it is acceptable that the name
+ * already exists:
+ * 1) the Scope() operator can reopen a scoping object that was
+ * previously defined (Scope, Method, Device, etc.)
+ * 2) Whenever we are parsing a deferred opcode (OpRegion, Buffer,
+ * BufferField, or Package), the name of the object is already
+ * in the namespace.
+ */
+ if (WalkState->DeferredNode)
+ {
+ /* This name is already in the namespace, get the node */
+
+ Node = WalkState->DeferredNode;
+ Status = AE_OK;
+ break;
+ }
+
+ /*
+ * If we are executing a method, do not create any namespace objects
+ * during the load phase, only during execution.
+ */
+ if (WalkState->MethodNode)
+ {
+ Node = NULL;
+ Status = AE_OK;
+ break;
+ }
+
+ Flags = ACPI_NS_NO_UPSEARCH;
+ if ((WalkState->Opcode != AML_SCOPE_OP) &&
+ (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)))
+ {
+ if (WalkState->NamespaceOverride)
+ {
+ Flags |= ACPI_NS_OVERRIDE_IF_FOUND;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Override allowed\n",
+ AcpiUtGetTypeName (ObjectType)));
+ }
+ else
+ {
+ Flags |= ACPI_NS_ERROR_IF_FOUND;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
+ AcpiUtGetTypeName (ObjectType)));
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[%s] Both Find or Create allowed\n",
+ AcpiUtGetTypeName (ObjectType)));
+ }
+
+ /*
+ * Enter the named type into the internal namespace. We enter the name
+ * as we go downward in the parse tree. Any necessary subobjects that
+ * involve arguments to the opcode must be created as we go back up the
+ * parse tree later.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
+ ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ /* The name already exists in this scope */
+
+ if (Node->Flags & ANOBJ_IS_EXTERNAL)
+ {
+ /*
+ * Allow one create on an object or segment that was
+ * previously declared External
+ */
+ Node->Flags &= ~ANOBJ_IS_EXTERNAL;
+ Node->Type = (UINT8) ObjectType;
+
+ /* Just retyped a node, probably will need to open a scope */
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ Status = AE_OK;
+ }
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Path, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+ break;
+ }
+
+ /* Common exit */
+
+ if (!Op)
+ {
+ /* Create a new op */
+
+ Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+
+ /* Initialize the op */
+
+#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
+ Op->Named.Path = ACPI_CAST_PTR (UINT8, Path);
+#endif
+
+ if (Node)
+ {
+ /*
+ * Put the Node in the "op" object that the parser uses, so we
+ * can get it again quickly when this scope is closed
+ */
+ Op->Common.Node = Node;
+ Op->Named.Name = Node->Name.Integer;
+ }
+
+ AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op);
+ *OutOp = Op;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsLoad1EndOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ * both control methods and everything else.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad1EndOp (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (DsLoad1EndOp);
+
+
+ Op = WalkState->Op;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
+
+ /* We are only interested in opcodes that have an associated name */
+
+ if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_FIELD)))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the object type to determine if we should pop the scope */
+
+ ObjectType = WalkState->OpInfo->ObjectType;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ if (WalkState->OpInfo->Flags & AML_FIELD)
+ {
+ /*
+ * If we are executing a method, do not create any namespace objects
+ * during the load phase, only during execution.
+ */
+ if (!WalkState->MethodNode)
+ {
+ if (WalkState->Opcode == AML_FIELD_OP ||
+ WalkState->Opcode == AML_BANK_FIELD_OP ||
+ WalkState->Opcode == AML_INDEX_FIELD_OP)
+ {
+ Status = AcpiDsInitFieldObjects (Op, WalkState);
+ }
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * If we are executing a method, do not create any namespace objects
+ * during the load phase, only during execution.
+ */
+ if (!WalkState->MethodNode)
+ {
+ if (Op->Common.AmlOpcode == AML_REGION_OP)
+ {
+ Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
+ (ACPI_ADR_SPACE_TYPE) ((Op->Common.Value.Arg)->Common.Value.Integer),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
+ {
+ Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
+ ACPI_ADR_SPACE_DATA_TABLE, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+#endif
+
+ if (Op->Common.AmlOpcode == AML_NAME_OP)
+ {
+ /* For Name opcode, get the object type from the argument */
+
+ if (Op->Common.Value.Arg)
+ {
+ ObjectType = (AcpiPsGetOpcodeInfo (
+ (Op->Common.Value.Arg)->Common.AmlOpcode))->ObjectType;
+
+ /* Set node type if we have a namespace node */
+
+ if (Op->Common.Node)
+ {
+ Op->Common.Node->Type = (UINT8) ObjectType;
+ }
+ }
+ }
+
+ /*
+ * If we are executing a method, do not create any namespace objects
+ * during the load phase, only during execution.
+ */
+ if (!WalkState->MethodNode)
+ {
+ if (Op->Common.AmlOpcode == AML_METHOD_OP)
+ {
+ /*
+ * MethodOp PkgLength NameString MethodFlags TermList
+ *
+ * Note: We must create the method node/object pair as soon as we
+ * see the method declaration. This allows later pass1 parsing
+ * of invocations of the method (need to know the number of
+ * arguments.)
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
+ WalkState, Op, Op->Named.Node));
+
+ if (!AcpiNsGetAttachedObject (Op->Named.Node))
+ {
+ WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
+ WalkState->NumOperands = 1;
+
+ Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiExCreateMethod (Op->Named.Data,
+ Op->Named.Length, WalkState);
+ }
+
+ WalkState->Operands[0] = NULL;
+ WalkState->NumOperands = 0;
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+ }
+
+ /* Pop the scope stack (only if loading a table) */
+
+ if (!WalkState->MethodNode &&
+ AcpiNsOpensScope (ObjectType))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
+ AcpiUtGetTypeName (ObjectType), Op));
+
+ Status = AcpiDsScopeStackPop (WalkState);
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload2.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
new file mode 100644
index 0000000000..b244263d12
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
@@ -0,0 +1,755 @@
+/******************************************************************************
+ *
+ * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dswload2")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsLoad2BeginOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ * OutOp - Wher to return op if a new one is created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad2BeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE ObjectType;
+ char *BufferPtr;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE (DsLoad2BeginOp);
+
+
+ Op = WalkState->Op;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
+
+ if (Op)
+ {
+ if ((WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_CONDITIONAL_EXECUTING))
+ {
+ /* We are executing a while loop outside of a method */
+
+ Status = AcpiDsExecBeginOp (WalkState, OutOp);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* We only care about Namespace opcodes here */
+
+ if ((!(WalkState->OpInfo->Flags & AML_NSOPCODE) &&
+ (WalkState->Opcode != AML_INT_NAMEPATH_OP)) ||
+ (!(WalkState->OpInfo->Flags & AML_NAMED)))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the name we are going to enter or lookup in the namespace */
+
+ if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
+ {
+ /* For Namepath op, get the path string */
+
+ BufferPtr = Op->Common.Value.String;
+ if (!BufferPtr)
+ {
+ /* No name, just exit */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+ else
+ {
+ /* Get name from the op */
+
+ BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name);
+ }
+ }
+ else
+ {
+ /* Get the namestring from the raw AML */
+
+ BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState);
+ }
+
+ /* Map the opcode into an internal object type */
+
+ ObjectType = WalkState->OpInfo->ObjectType;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType));
+
+ switch (WalkState->Opcode)
+ {
+ case AML_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+
+ Node = NULL;
+ Status = AE_OK;
+ break;
+
+ case AML_INT_NAMEPATH_OP:
+ /*
+ * The NamePath is an object reference to an existing object.
+ * Don't enter the name into the namespace, but look it up
+ * for use later.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+ break;
+
+ case AML_SCOPE_OP:
+
+ /* Special case for Scope(\) -> refers to the Root node */
+
+ if (Op && (Op->Named.Node == AcpiGbl_RootNode))
+ {
+ Node = Op->Named.Node;
+
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ /*
+ * The Path is an object reference to an existing object.
+ * Don't enter the name into the namespace, but look it up
+ * for use later.
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+ if (ACPI_FAILURE (Status))
+ {
+#ifdef ACPI_ASL_COMPILER
+ if (Status == AE_NOT_FOUND)
+ {
+ Status = AE_OK;
+ }
+ else
+ {
+ ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+ }
+#else
+ ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+#endif
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * We must check to make sure that the target is
+ * one of the opcodes that actually opens a scope
+ */
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_ANY:
+ case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+
+ /* These are acceptable types */
+ break;
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+
+ /*
+ * These types we will allow, but we will change the type.
+ * This enables some existing code of the form:
+ *
+ * Name (DEB, 0)
+ * Scope (DEB) { ... }
+ */
+ ACPI_WARNING ((AE_INFO,
+ "Type override - [%4.4s] had invalid type (%s) "
+ "for Scope operator, changed to type ANY",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
+
+ Node->Type = ACPI_TYPE_ANY;
+ WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ /*
+ * Allow scope change to root during execution of module-level
+ * code. Root is typed METHOD during this time.
+ */
+ if ((Node == AcpiGbl_RootNode) &&
+ (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ break;
+ }
+
+ /*lint -fallthrough */
+
+ default:
+
+ /* All other types are an error */
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid type (%s) for target of "
+ "Scope operator [%4.4s] (Cannot override)",
+ AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ break;
+
+ default:
+
+ /* All other opcodes */
+
+ if (Op && Op->Common.Node)
+ {
+ /* This op/node was previously entered into the namespace */
+
+ Node = Op->Common.Node;
+
+ if (AcpiNsOpensScope (ObjectType))
+ {
+ Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Enter the named type into the internal namespace. We enter the name
+ * as we go downward in the parse tree. Any necessary subobjects that
+ * involve arguments to the opcode must be created as we go back up the
+ * parse tree later.
+ *
+ * Note: Name may already exist if we are executing a deferred opcode.
+ */
+ if (WalkState->DeferredNode)
+ {
+ /* This name is already in the namespace, get the node */
+
+ Node = WalkState->DeferredNode;
+ Status = AE_OK;
+ break;
+ }
+
+ Flags = ACPI_NS_NO_UPSEARCH;
+ if (WalkState->PassNumber == ACPI_IMODE_EXECUTE)
+ {
+ /* Execution mode, node cannot already exist, node is temporary */
+
+ Flags |= ACPI_NS_ERROR_IF_FOUND;
+
+ if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ Flags |= ACPI_NS_TEMPORARY;
+ }
+ }
+
+ /* Add new entry or lookup existing entry */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+ ACPI_IMODE_LOAD_PASS2, Flags, WalkState, &Node);
+
+ if (ACPI_SUCCESS (Status) && (Flags & ACPI_NS_TEMPORARY))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "***New Node [%4.4s] %p is temporary\n",
+ AcpiUtGetNodeName (Node), Node));
+ }
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!Op)
+ {
+ /* Create a new op */
+
+ Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize the new op */
+
+ if (Node)
+ {
+ Op->Named.Name = Node->Name.Integer;
+ }
+ *OutOp = Op;
+ }
+
+ /*
+ * Put the Node in the "op" object that the parser uses, so we
+ * can get it again quickly when this scope is closed
+ */
+ Op->Common.Node = Node;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsLoad2EndOp
+ *
+ * PARAMETERS: WalkState - Current state of the parse tree walk
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ * both control methods and everything else.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad2EndOp (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OBJECT_TYPE ObjectType;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_NAMESPACE_NODE *NewNode;
+#ifndef ACPI_NO_METHOD_EXECUTION
+ UINT32 i;
+ UINT8 RegionSpace;
+#endif
+
+
+ ACPI_FUNCTION_TRACE (DsLoad2EndOp);
+
+ Op = WalkState->Op;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
+ WalkState->OpInfo->Name, Op, WalkState));
+
+ /* Check if opcode had an associated namespace object */
+
+ if (!(WalkState->OpInfo->Flags & AML_NSOBJECT))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Ending scope Op=%p State=%p\n", Op, WalkState));
+ }
+
+ ObjectType = WalkState->OpInfo->ObjectType;
+
+ /*
+ * Get the Node/name from the earlier lookup
+ * (It was saved in the *op structure)
+ */
+ Node = Op->Common.Node;
+
+ /*
+ * Put the Node on the object stack (Contains the ACPI Name of
+ * this object)
+ */
+ WalkState->Operands[0] = (void *) Node;
+ WalkState->NumOperands = 1;
+
+ /* Pop the scope stack */
+
+ if (AcpiNsOpensScope (ObjectType) &&
+ (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+ AcpiUtGetTypeName (ObjectType), Op));
+
+ Status = AcpiDsScopeStackPop (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ /*
+ * Named operations are as follows:
+ *
+ * AML_ALIAS
+ * AML_BANKFIELD
+ * AML_CREATEBITFIELD
+ * AML_CREATEBYTEFIELD
+ * AML_CREATEDWORDFIELD
+ * AML_CREATEFIELD
+ * AML_CREATEQWORDFIELD
+ * AML_CREATEWORDFIELD
+ * AML_DATA_REGION
+ * AML_DEVICE
+ * AML_EVENT
+ * AML_FIELD
+ * AML_INDEXFIELD
+ * AML_METHOD
+ * AML_METHODCALL
+ * AML_MUTEX
+ * AML_NAME
+ * AML_NAMEDFIELD
+ * AML_OPREGION
+ * AML_POWERRES
+ * AML_PROCESSOR
+ * AML_SCOPE
+ * AML_THERMALZONE
+ */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode), WalkState, Op, Node));
+
+ /* Decode the opcode */
+
+ Arg = Op->Common.Value.Arg;
+
+ switch (WalkState->OpInfo->Type)
+ {
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+ case AML_TYPE_CREATE_FIELD:
+ /*
+ * Create the field object, but the field buffer and index must
+ * be evaluated later during the execution phase
+ */
+ Status = AcpiDsCreateBufferField (Op, WalkState);
+ break;
+
+ case AML_TYPE_NAMED_FIELD:
+ /*
+ * If we are executing a method, initialize the field
+ */
+ if (WalkState->MethodNode)
+ {
+ Status = AcpiDsInitFieldObjects (Op, WalkState);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_INDEX_FIELD_OP:
+
+ Status = AcpiDsCreateIndexField (Op, (ACPI_HANDLE) Arg->Common.Node,
+ WalkState);
+ break;
+
+ case AML_BANK_FIELD_OP:
+
+ Status = AcpiDsCreateBankField (Op, Arg->Common.Node, WalkState);
+ break;
+
+ case AML_FIELD_OP:
+
+ Status = AcpiDsCreateField (Op, Arg->Common.Node, WalkState);
+ break;
+
+ default:
+
+ /* All NAMED_FIELD opcodes must be handled above */
+ break;
+ }
+ break;
+
+ case AML_TYPE_NAMED_SIMPLE:
+
+ Status = AcpiDsCreateOperands (WalkState, Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_PROCESSOR_OP:
+
+ Status = AcpiExCreateProcessor (WalkState);
+ break;
+
+ case AML_POWER_RES_OP:
+
+ Status = AcpiExCreatePowerResource (WalkState);
+ break;
+
+ case AML_MUTEX_OP:
+
+ Status = AcpiExCreateMutex (WalkState);
+ break;
+
+ case AML_EVENT_OP:
+
+ Status = AcpiExCreateEvent (WalkState);
+ break;
+
+ case AML_ALIAS_OP:
+
+ Status = AcpiExCreateAlias (WalkState);
+ break;
+
+ default:
+
+ /* Unknown opcode */
+
+ Status = AE_OK;
+ goto Cleanup;
+ }
+
+ /* Delete operands */
+
+ for (i = 1; i < WalkState->NumOperands; i++)
+ {
+ AcpiUtRemoveReference (WalkState->Operands[i]);
+ WalkState->Operands[i] = NULL;
+ }
+
+ break;
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+ case AML_TYPE_NAMED_COMPLEX:
+
+ switch (Op->Common.AmlOpcode)
+ {
+#ifndef ACPI_NO_METHOD_EXECUTION
+ case AML_REGION_OP:
+ case AML_DATA_REGION_OP:
+
+ if (Op->Common.AmlOpcode == AML_REGION_OP)
+ {
+ RegionSpace = (ACPI_ADR_SPACE_TYPE)
+ ((Op->Common.Value.Arg)->Common.Value.Integer);
+ }
+ else
+ {
+ RegionSpace = ACPI_ADR_SPACE_DATA_TABLE;
+ }
+
+ /*
+ * The OpRegion is not fully parsed at this time. The only valid
+ * argument is the SpaceId. (We must save the address of the
+ * AML of the address and length operands)
+ *
+ * If we have a valid region, initialize it. The namespace is
+ * unlocked at this point.
+ *
+ * Need to unlock interpreter if it is locked (if we are running
+ * a control method), in order to allow _REG methods to be run
+ * during AcpiEvInitializeRegion.
+ */
+ if (WalkState->MethodNode)
+ {
+ /*
+ * Executing a method: initialize the region and unlock
+ * the interpreter
+ */
+ Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
+ RegionSpace, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiExExitInterpreter ();
+ }
+
+ Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node),
+ FALSE);
+ if (WalkState->MethodNode)
+ {
+ AcpiExEnterInterpreter ();
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * If AE_NOT_EXIST is returned, it is not fatal
+ * because many regions get created before a handler
+ * is installed for said region.
+ */
+ if (AE_NOT_EXIST == Status)
+ {
+ Status = AE_OK;
+ }
+ }
+ break;
+
+ case AML_NAME_OP:
+
+ Status = AcpiDsCreateNode (WalkState, Node, Op);
+ break;
+
+ case AML_METHOD_OP:
+ /*
+ * MethodOp PkgLength NameString MethodFlags TermList
+ *
+ * Note: We must create the method node/object pair as soon as we
+ * see the method declaration. This allows later pass1 parsing
+ * of invocations of the method (need to know the number of
+ * arguments.)
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
+ WalkState, Op, Op->Named.Node));
+
+ if (!AcpiNsGetAttachedObject (Op->Named.Node))
+ {
+ WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
+ WalkState->NumOperands = 1;
+
+ Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiExCreateMethod (Op->Named.Data,
+ Op->Named.Length, WalkState);
+ }
+ WalkState->Operands[0] = NULL;
+ WalkState->NumOperands = 0;
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ break;
+
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+ default:
+
+ /* All NAMED_COMPLEX opcodes must be handled above */
+ break;
+ }
+ break;
+
+ case AML_CLASS_INTERNAL:
+
+ /* case AML_INT_NAMEPATH_OP: */
+ break;
+
+ case AML_CLASS_METHOD_CALL:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
+ WalkState, Op, Node));
+
+ /*
+ * Lookup the method name and save the Node
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &(NewNode));
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Make sure that what we found is indeed a method
+ * We didn't search for a method on purpose, to see if the name
+ * would resolve
+ */
+ if (NewNode->Type != ACPI_TYPE_METHOD)
+ {
+ Status = AE_AML_OPERAND_TYPE;
+ }
+
+ /* We could put the returned object (Node) on the object stack for
+ * later, but for now, we will put it in the "op" object that the
+ * parser uses, so we can get it again at the end of this scope
+ */
+ Op->Common.Node = NewNode;
+ }
+ else
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ }
+ break;
+
+
+ default:
+
+ break;
+ }
+
+Cleanup:
+
+ /* Remove the Node pushed at the very beginning */
+
+ WalkState->Operands[0] = NULL;
+ WalkState->NumOperands = 0;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswscope.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswscope.c
new file mode 100644
index 0000000000..dc1fedc9b9
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswscope.c
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Module Name: dswscope - Scope stack manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dswscope")
+
+
+/****************************************************************************
+ *
+ * FUNCTION: AcpiDsScopeStackClear
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Pop (and free) everything on the scope stack except the
+ * root scope object (which remains at the stack top.)
+ *
+ ***************************************************************************/
+
+void
+AcpiDsScopeStackClear (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *ScopeInfo;
+
+ ACPI_FUNCTION_NAME (DsScopeStackClear);
+
+
+ while (WalkState->ScopeInfo)
+ {
+ /* Pop a scope off the stack */
+
+ ScopeInfo = WalkState->ScopeInfo;
+ WalkState->ScopeInfo = ScopeInfo->Scope.Next;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Popped object type (%s)\n",
+ AcpiUtGetTypeName (ScopeInfo->Common.Value)));
+ AcpiUtDeleteGenericState (ScopeInfo);
+ }
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION: AcpiDsScopeStackPush
+ *
+ * PARAMETERS: Node - Name to be made current
+ * Type - Type of frame being pushed
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push the current scope on the scope stack, and make the
+ * passed Node current.
+ *
+ ***************************************************************************/
+
+ACPI_STATUS
+AcpiDsScopeStackPush (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *ScopeInfo;
+ ACPI_GENERIC_STATE *OldScopeInfo;
+
+
+ ACPI_FUNCTION_TRACE (DsScopeStackPush);
+
+
+ if (!Node)
+ {
+ /* Invalid scope */
+
+ ACPI_ERROR ((AE_INFO, "Null scope parameter"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Make sure object type is valid */
+
+ if (!AcpiUtValidObjectType (Type))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Invalid object type: 0x%X", Type));
+ }
+
+ /* Allocate a new scope object */
+
+ ScopeInfo = AcpiUtCreateGenericState ();
+ if (!ScopeInfo)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Init new scope object */
+
+ ScopeInfo->Common.DescriptorType = ACPI_DESC_TYPE_STATE_WSCOPE;
+ ScopeInfo->Scope.Node = Node;
+ ScopeInfo->Common.Value = (UINT16) Type;
+
+ WalkState->ScopeDepth++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[%.2d] Pushed scope ", (UINT32) WalkState->ScopeDepth));
+
+ OldScopeInfo = WalkState->ScopeInfo;
+ if (OldScopeInfo)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+ "[%4.4s] (%s)",
+ AcpiUtGetNodeName (OldScopeInfo->Scope.Node),
+ AcpiUtGetTypeName (OldScopeInfo->Common.Value)));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+ "[\\___] (%s)", "ROOT"));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+ ", New scope -> [%4.4s] (%s)\n",
+ AcpiUtGetNodeName (ScopeInfo->Scope.Node),
+ AcpiUtGetTypeName (ScopeInfo->Common.Value)));
+
+ /* Push new scope object onto stack */
+
+ AcpiUtPushGenericState (&WalkState->ScopeInfo, ScopeInfo);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION: AcpiDsScopeStackPop
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop the scope stack once.
+ *
+ ***************************************************************************/
+
+ACPI_STATUS
+AcpiDsScopeStackPop (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *ScopeInfo;
+ ACPI_GENERIC_STATE *NewScopeInfo;
+
+
+ ACPI_FUNCTION_TRACE (DsScopeStackPop);
+
+
+ /*
+ * Pop scope info object off the stack.
+ */
+ ScopeInfo = AcpiUtPopGenericState (&WalkState->ScopeInfo);
+ if (!ScopeInfo)
+ {
+ return_ACPI_STATUS (AE_STACK_UNDERFLOW);
+ }
+
+ WalkState->ScopeDepth--;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
+ (UINT32) WalkState->ScopeDepth,
+ AcpiUtGetNodeName (ScopeInfo->Scope.Node),
+ AcpiUtGetTypeName (ScopeInfo->Common.Value)));
+
+ NewScopeInfo = WalkState->ScopeInfo;
+ if (NewScopeInfo)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+ "[%4.4s] (%s)\n",
+ AcpiUtGetNodeName (NewScopeInfo->Scope.Node),
+ AcpiUtGetTypeName (NewScopeInfo->Common.Value)));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+ "[\\___] (ROOT)\n"));
+ }
+
+ AcpiUtDeleteGenericState (ScopeInfo);
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswstate.c b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswstate.c
new file mode 100644
index 0000000000..5211666acb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/dispatcher/dswstate.c
@@ -0,0 +1,841 @@
+/******************************************************************************
+ *
+ * Module Name: dswstate - Dispatcher parse tree walk management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dswstate")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsResultStackPush (
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+AcpiDsResultStackPop (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsResultPop
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop an object off the top of this walk's result stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsResultPop (
+ ACPI_OPERAND_OBJECT **Object,
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 Index;
+ ACPI_GENERIC_STATE *State;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (DsResultPop);
+
+
+ State = WalkState->Results;
+
+ /* Incorrect state of result stack */
+
+ if (State && !WalkState->ResultCount)
+ {
+ ACPI_ERROR ((AE_INFO, "No results on result stack"));
+ return (AE_AML_INTERNAL);
+ }
+
+ if (!State && WalkState->ResultCount)
+ {
+ ACPI_ERROR ((AE_INFO, "No result state for result stack"));
+ return (AE_AML_INTERNAL);
+ }
+
+ /* Empty result stack */
+
+ if (!State)
+ {
+ ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
+ return (AE_AML_NO_RETURN_VALUE);
+ }
+
+ /* Return object of the top element and clean that top element result stack */
+
+ WalkState->ResultCount--;
+ Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
+
+ *Object = State->Results.ObjDesc [Index];
+ if (!*Object)
+ {
+ ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
+ WalkState));
+ return (AE_AML_NO_RETURN_VALUE);
+ }
+
+ State->Results.ObjDesc [Index] = NULL;
+ if (Index == 0)
+ {
+ Status = AcpiDsResultStackPop (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
+ AcpiUtGetObjectTypeName (*Object),
+ Index, WalkState, WalkState->ResultCount));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsResultPush
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push an object onto the current result stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsResultPush (
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *State;
+ ACPI_STATUS Status;
+ UINT32 Index;
+
+
+ ACPI_FUNCTION_NAME (DsResultPush);
+
+
+ if (WalkState->ResultCount > WalkState->ResultSize)
+ {
+ ACPI_ERROR ((AE_INFO, "Result stack is full"));
+ return (AE_AML_INTERNAL);
+ }
+ else if (WalkState->ResultCount == WalkState->ResultSize)
+ {
+ /* Extend the result stack */
+
+ Status = AcpiDsResultStackPush (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
+ return (Status);
+ }
+ }
+
+ if (!(WalkState->ResultCount < WalkState->ResultSize))
+ {
+ ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
+ return (AE_AML_INTERNAL);
+ }
+
+ State = WalkState->Results;
+ if (!State)
+ {
+ ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
+ return (AE_AML_INTERNAL);
+ }
+
+ if (!Object)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Null Object! Obj=%p State=%p Num=%u",
+ Object, WalkState, WalkState->ResultCount));
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Assign the address of object to the top free element of result stack */
+
+ Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
+ State->Results.ObjDesc [Index] = Object;
+ WalkState->ResultCount++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+ Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
+ WalkState, WalkState->ResultCount, WalkState->CurrentResult));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsResultStackPush
+ *
+ * PARAMETERS: WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push an object onto the WalkState result stack
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsResultStackPush (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_NAME (DsResultStackPush);
+
+
+ /* Check for stack overflow */
+
+ if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
+ ACPI_RESULTS_OBJ_NUM_MAX)
+ {
+ ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
+ WalkState, WalkState->ResultSize));
+ return (AE_STACK_OVERFLOW);
+ }
+
+ State = AcpiUtCreateGenericState ();
+ if (!State)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
+ AcpiUtPushGenericState (&WalkState->Results, State);
+
+ /* Increase the length of the result stack by the length of frame */
+
+ WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
+ State, WalkState));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsResultStackPop
+ *
+ * PARAMETERS: WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop an object off of the WalkState result stack
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsResultStackPop (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_NAME (DsResultStackPop);
+
+
+ /* Check for stack underflow */
+
+ if (WalkState->Results == NULL)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n",
+ WalkState));
+ return (AE_AML_NO_OPERAND);
+ }
+
+ if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
+ {
+ ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
+ return (AE_AML_INTERNAL);
+ }
+
+ State = AcpiUtPopGenericState (&WalkState->Results);
+ AcpiUtDeleteGenericState (State);
+
+ /* Decrease the length of result stack by the length of frame */
+
+ WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Result=%p RemainingResults=%X State=%p\n",
+ State, WalkState->ResultCount, WalkState));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsObjStackPush
+ *
+ * PARAMETERS: Object - Object to push
+ * WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push an object onto this walk's object/operand stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsObjStackPush (
+ void *Object,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_FUNCTION_NAME (DsObjStackPush);
+
+
+ /* Check for stack overflow */
+
+ if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Object stack overflow! Obj=%p State=%p #Ops=%u",
+ Object, WalkState, WalkState->NumOperands));
+ return (AE_STACK_OVERFLOW);
+ }
+
+ /* Put the object onto the stack */
+
+ WalkState->Operands [WalkState->OperandIndex] = Object;
+ WalkState->NumOperands++;
+
+ /* For the usual order of filling the operand stack */
+
+ WalkState->OperandIndex++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+ Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
+ WalkState, WalkState->NumOperands));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsObjStackPop
+ *
+ * PARAMETERS: PopCount - Number of objects/entries to pop
+ * WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
+ * deleted by this routine.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsObjStackPop (
+ UINT32 PopCount,
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (DsObjStackPop);
+
+
+ for (i = 0; i < PopCount; i++)
+ {
+ /* Check for stack underflow */
+
+ if (WalkState->NumOperands == 0)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Object stack underflow! Count=%X State=%p #Ops=%u",
+ PopCount, WalkState, WalkState->NumOperands));
+ return (AE_STACK_UNDERFLOW);
+ }
+
+ /* Just set the stack entry to null */
+
+ WalkState->NumOperands--;
+ WalkState->Operands [WalkState->NumOperands] = NULL;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
+ PopCount, WalkState, WalkState->NumOperands));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsObjStackPopAndDelete
+ *
+ * PARAMETERS: PopCount - Number of objects/entries to pop
+ * WalkState - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop this walk's object stack and delete each object that is
+ * popped off.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsObjStackPopAndDelete (
+ UINT32 PopCount,
+ ACPI_WALK_STATE *WalkState)
+{
+ INT32 i;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
+
+
+ if (PopCount == 0)
+ {
+ return;
+ }
+
+ for (i = (INT32) PopCount - 1; i >= 0; i--)
+ {
+ if (WalkState->NumOperands == 0)
+ {
+ return;
+ }
+
+ /* Pop the stack and delete an object if present in this stack entry */
+
+ WalkState->NumOperands--;
+ ObjDesc = WalkState->Operands [i];
+ if (ObjDesc)
+ {
+ AcpiUtRemoveReference (WalkState->Operands [i]);
+ WalkState->Operands [i] = NULL;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+ PopCount, WalkState, WalkState->NumOperands));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetCurrentWalkState
+ *
+ * PARAMETERS: Thread - Get current active state for this Thread
+ *
+ * RETURN: Pointer to the current walk state
+ *
+ * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
+ * walk state.)
+ *
+ ******************************************************************************/
+
+ACPI_WALK_STATE *
+AcpiDsGetCurrentWalkState (
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
+
+
+ if (!Thread)
+ {
+ return (NULL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
+ Thread->WalkStateList));
+
+ return (Thread->WalkStateList);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsPushWalkState
+ *
+ * PARAMETERS: WalkState - State to push
+ * Thread - Thread state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Place the Thread state at the head of the state list
+ *
+ ******************************************************************************/
+
+void
+AcpiDsPushWalkState (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_FUNCTION_TRACE (DsPushWalkState);
+
+
+ WalkState->Next = Thread->WalkStateList;
+ Thread->WalkStateList = WalkState;
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsPopWalkState
+ *
+ * PARAMETERS: Thread - Current thread state
+ *
+ * RETURN: A WalkState object popped from the thread's stack
+ *
+ * DESCRIPTION: Remove and return the walkstate object that is at the head of
+ * the walk stack for the given walk list. NULL indicates that
+ * the list is empty.
+ *
+ ******************************************************************************/
+
+ACPI_WALK_STATE *
+AcpiDsPopWalkState (
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE (DsPopWalkState);
+
+
+ WalkState = Thread->WalkStateList;
+
+ if (WalkState)
+ {
+ /* Next walk state becomes the current walk state */
+
+ Thread->WalkStateList = WalkState->Next;
+
+ /*
+ * Don't clear the NEXT field, this serves as an indicator
+ * that there is a parent WALK STATE
+ * Do Not: WalkState->Next = NULL;
+ */
+ }
+
+ return_PTR (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateWalkState
+ *
+ * PARAMETERS: OwnerId - ID for object creation
+ * Origin - Starting point for this walk
+ * MethodDesc - Method object
+ * Thread - Current thread state
+ *
+ * RETURN: Pointer to the new walk state.
+ *
+ * DESCRIPTION: Allocate and initialize a new walk state. The current walk
+ * state is set to this new state.
+ *
+ ******************************************************************************/
+
+ACPI_WALK_STATE *
+AcpiDsCreateWalkState (
+ ACPI_OWNER_ID OwnerId,
+ ACPI_PARSE_OBJECT *Origin,
+ ACPI_OPERAND_OBJECT *MethodDesc,
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE (DsCreateWalkState);
+
+
+ WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
+ if (!WalkState)
+ {
+ return_PTR (NULL);
+ }
+
+ WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
+ WalkState->MethodDesc = MethodDesc;
+ WalkState->OwnerId = OwnerId;
+ WalkState->Origin = Origin;
+ WalkState->Thread = Thread;
+
+ WalkState->ParserState.StartOp = Origin;
+
+ /* Init the method args/local */
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+ AcpiDsMethodDataInit (WalkState);
+#endif
+
+ /* Put the new state at the head of the walk list */
+
+ if (Thread)
+ {
+ AcpiDsPushWalkState (WalkState, Thread);
+ }
+
+ return_PTR (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitAmlWalk
+ *
+ * PARAMETERS: WalkState - New state to be initialized
+ * Op - Current parse op
+ * MethodNode - Control method NS node, if any
+ * AmlStart - Start of AML
+ * AmlLength - Length of AML
+ * Info - Method info block (params, etc.)
+ * PassNumber - 1, 2, or 3
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitAmlWalk (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *MethodNode,
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_EVALUATE_INFO *Info,
+ UINT8 PassNumber)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
+ ACPI_PARSE_OBJECT *ExtraOp;
+
+
+ ACPI_FUNCTION_TRACE (DsInitAmlWalk);
+
+
+ WalkState->ParserState.Aml =
+ WalkState->ParserState.AmlStart = AmlStart;
+ WalkState->ParserState.AmlEnd =
+ WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
+
+ /* The NextOp of the NextWalk will be the beginning of the method */
+
+ WalkState->NextOp = NULL;
+ WalkState->PassNumber = PassNumber;
+
+ if (Info)
+ {
+ WalkState->Params = Info->Parameters;
+ WalkState->CallerReturnDesc = &Info->ReturnObject;
+ }
+
+ Status = AcpiPsInitScope (&WalkState->ParserState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (MethodNode)
+ {
+ WalkState->ParserState.StartNode = MethodNode;
+ WalkState->WalkType = ACPI_WALK_METHOD;
+ WalkState->MethodNode = MethodNode;
+ WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
+
+ /* Push start scope on scope stack and make it current */
+
+ Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Init the method arguments */
+
+ Status = AcpiDsMethodDataInitArgs (WalkState->Params,
+ ACPI_METHOD_NUM_ARGS, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ /*
+ * Setup the current scope.
+ * Find a Named Op that has a namespace node associated with it.
+ * search upwards from this Op. Current scope is the first
+ * Op with a namespace node.
+ */
+ ExtraOp = ParserState->StartOp;
+ while (ExtraOp && !ExtraOp->Common.Node)
+ {
+ ExtraOp = ExtraOp->Common.Parent;
+ }
+
+ if (!ExtraOp)
+ {
+ ParserState->StartNode = NULL;
+ }
+ else
+ {
+ ParserState->StartNode = ExtraOp->Common.Node;
+ }
+
+ if (ParserState->StartNode)
+ {
+ /* Push start scope on scope stack and make it current */
+
+ Status = AcpiDsScopeStackPush (ParserState->StartNode,
+ ParserState->StartNode->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
+ Status = AcpiDsInitCallbacks (WalkState, PassNumber);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDeleteWalkState
+ *
+ * PARAMETERS: WalkState - State to delete
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete a walk state including all internal data structures
+ *
+ ******************************************************************************/
+
+void
+AcpiDsDeleteWalkState (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
+
+
+ if (!WalkState)
+ {
+ return_VOID;
+ }
+
+ if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
+ {
+ ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
+ WalkState));
+ return_VOID;
+ }
+
+ /* There should not be any open scopes */
+
+ if (WalkState->ParserState.Scope)
+ {
+ ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
+ WalkState));
+ AcpiPsCleanupScope (&WalkState->ParserState);
+ }
+
+ /* Always must free any linked control states */
+
+ while (WalkState->ControlState)
+ {
+ State = WalkState->ControlState;
+ WalkState->ControlState = State->Common.Next;
+
+ AcpiUtDeleteGenericState (State);
+ }
+
+ /* Always must free any linked parse states */
+
+ while (WalkState->ScopeInfo)
+ {
+ State = WalkState->ScopeInfo;
+ WalkState->ScopeInfo = State->Common.Next;
+
+ AcpiUtDeleteGenericState (State);
+ }
+
+ /* Always must free any stacked result states */
+
+ while (WalkState->Results)
+ {
+ State = WalkState->Results;
+ WalkState->Results = State->Common.Next;
+
+ AcpiUtDeleteGenericState (State);
+ }
+
+ ACPI_FREE (WalkState);
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evevent.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evevent.c
new file mode 100644
index 0000000000..45d227cbf5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evevent.c
@@ -0,0 +1,336 @@
+/******************************************************************************
+ *
+ * Module Name: evevent - Fixed Event handling and dispatch
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evevent")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiEvFixedEventInitialize (
+ void);
+
+static UINT32
+AcpiEvFixedEventDispatch (
+ UINT32 Event);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInitializeEvents
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitializeEvents (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvInitializeEvents);
+
+
+ /* If Hardware Reduced flag is set, there are no fixed events */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Initialize the Fixed and General Purpose Events. This is done prior to
+ * enabling SCIs to prevent interrupts from occurring before the handlers
+ * are installed.
+ */
+ Status = AcpiEvFixedEventInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to initialize fixed events"));
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiEvGpeInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to initialize general purpose events"));
+ return_ACPI_STATUS (Status);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallXruptHandlers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInstallXruptHandlers (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallXruptHandlers);
+
+
+ /* If Hardware Reduced flag is set, there is no ACPI h/w */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Install the SCI handler */
+
+ Status = AcpiEvInstallSciHandler ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to install System Control Interrupt handler"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the handler for the Global Lock */
+
+ Status = AcpiEvInitGlobalLockHandler ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to initialize Global Lock handler"));
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiGbl_EventsInitialized = TRUE;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvFixedEventInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvFixedEventInitialize (
+ void)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ /*
+ * Initialize the structure that keeps track of fixed event handlers and
+ * enable the fixed events.
+ */
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ AcpiGbl_FixedEventHandlers[i].Handler = NULL;
+ AcpiGbl_FixedEventHandlers[i].Context = NULL;
+
+ /* Disable the fixed event */
+
+ if (AcpiGbl_FixedEventInfo[i].EnableRegisterId != 0xFF)
+ {
+ Status = AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[i].EnableRegisterId,
+ ACPI_DISABLE_EVENT);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvFixedEventDetect
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Checks the PM status register for active fixed events
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiEvFixedEventDetect (
+ void)
+{
+ UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
+ UINT32 FixedStatus;
+ UINT32 FixedEnable;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (EvFixedEventDetect);
+
+
+ /*
+ * Read the fixed feature status and enable registers, as all the cases
+ * depend on their values. Ignore errors here.
+ */
+ (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_STATUS, &FixedStatus);
+ (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_ENABLE, &FixedEnable);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+ "Fixed Event Block: Enable %08X Status %08X\n",
+ FixedEnable, FixedStatus));
+
+ /*
+ * Check for all possible Fixed Events and dispatch those that are active
+ */
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ /* Both the status and enable bits must be on for this event */
+
+ if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) &&
+ (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask))
+ {
+ /*
+ * Found an active (signalled) event. Invoke global event
+ * handler if present.
+ */
+ AcpiFixedEventCount[i]++;
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL,
+ i, AcpiGbl_GlobalEventHandlerContext);
+ }
+
+ IntStatus |= AcpiEvFixedEventDispatch (i);
+ }
+ }
+
+ return (IntStatus);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvFixedEventDispatch
+ *
+ * PARAMETERS: Event - Event type
+ *
+ * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Clears the status bit for the requested event, calls the
+ * handler that previously registered for the event.
+ * NOTE: If there is no handler for the event, the event is
+ * disabled to prevent further interrupts.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiEvFixedEventDispatch (
+ UINT32 Event)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Clear the status bit */
+
+ (void) AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
+ ACPI_CLEAR_STATUS);
+
+ /*
+ * Make sure that a handler exists. If not, report an error
+ * and disable the event to prevent further interrupts.
+ */
+ if (!AcpiGbl_FixedEventHandlers[Event].Handler)
+ {
+ (void) AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
+ ACPI_DISABLE_EVENT);
+
+ ACPI_ERROR ((AE_INFO,
+ "No installed handler for fixed event - %s (%u), disabling",
+ AcpiUtGetEventName (Event), Event));
+
+ return (ACPI_INTERRUPT_NOT_HANDLED);
+ }
+
+ /* Invoke the Fixed Event handler */
+
+ return ((AcpiGbl_FixedEventHandlers[Event].Handler)(
+ AcpiGbl_FixedEventHandlers[Event].Context));
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evglock.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evglock.c
new file mode 100644
index 0000000000..a9855c98aa
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evglock.c
@@ -0,0 +1,378 @@
+/******************************************************************************
+ *
+ * Module Name: evglock - Global Lock support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evglock")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static UINT32
+AcpiEvGlobalLockHandler (
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInitGlobalLockHandler
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for the global lock release event
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitGlobalLockHandler (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
+
+
+ /* If Hardware Reduced flag is set, there is no global lock */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Attempt installation of the global lock handler */
+
+ Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
+ AcpiEvGlobalLockHandler, NULL);
+
+ /*
+ * If the global lock does not exist on this platform, the attempt to
+ * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
+ * Map to AE_OK, but mark global lock as not present. Any attempt to
+ * actually use the global lock will be flagged with an error.
+ */
+ AcpiGbl_GlobalLockPresent = FALSE;
+ if (Status == AE_NO_HARDWARE_RESPONSE)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No response from Global Lock hardware, disabling lock"));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ Status = AcpiOsCreateLock (&AcpiGbl_GlobalLockPendingLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiGbl_GlobalLockPending = FALSE;
+ AcpiGbl_GlobalLockPresent = TRUE;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvRemoveGlobalLockHandler
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove the handler for the Global Lock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvRemoveGlobalLockHandler (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
+
+ AcpiGbl_GlobalLockPresent = FALSE;
+ Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
+ AcpiEvGlobalLockHandler);
+
+ AcpiOsDeleteLock (AcpiGbl_GlobalLockPendingLock);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGlobalLockHandler
+ *
+ * PARAMETERS: Context - From thread interface, not used
+ *
+ * RETURN: ACPI_INTERRUPT_HANDLED
+ *
+ * DESCRIPTION: Invoked directly from the SCI handler when a global lock
+ * release interrupt occurs. If there is actually a pending
+ * request for the lock, signal the waiting thread.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiEvGlobalLockHandler (
+ void *Context)
+{
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+ /*
+ * If a request for the global lock is not actually pending,
+ * we are done. This handles "spurious" global lock interrupts
+ * which are possible (and have been seen) with bad BIOSs.
+ */
+ if (!AcpiGbl_GlobalLockPending)
+ {
+ goto CleanupAndExit;
+ }
+
+ /*
+ * Send a unit to the global lock semaphore. The actual acquisition
+ * of the global lock will be performed by the waiting thread.
+ */
+ Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
+ }
+
+ AcpiGbl_GlobalLockPending = FALSE;
+
+
+CleanupAndExit:
+
+ AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+ return (ACPI_INTERRUPT_HANDLED);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEvAcquireGlobalLock
+ *
+ * PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Attempt to gain ownership of the Global Lock.
+ *
+ * MUTEX: Interpreter must be locked
+ *
+ * Note: The original implementation allowed multiple threads to "acquire" the
+ * Global Lock, and the OS would hold the lock until the last thread had
+ * released it. However, this could potentially starve the BIOS out of the
+ * lock, especially in the case where there is a tight handshake between the
+ * Embedded Controller driver and the BIOS. Therefore, this implementation
+ * allows only one thread to acquire the HW Global Lock at a time, and makes
+ * the global lock appear as a standard mutex on the OS side.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiEvAcquireGlobalLock (
+ UINT16 Timeout)
+{
+ ACPI_CPU_FLAGS Flags;
+ ACPI_STATUS Status;
+ BOOLEAN Acquired = FALSE;
+
+
+ ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
+
+
+ /*
+ * Only one thread can acquire the GL at a time, the GlobalLockMutex
+ * enforces this. This interface releases the interpreter if we must wait.
+ */
+ Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
+ Timeout);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Update the global lock handle and check for wraparound. The handle is
+ * only used for the external global lock interfaces, but it is updated
+ * here to properly handle the case where a single thread may acquire the
+ * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
+ * handle is therefore updated on the first acquire from a given thread
+ * regardless of where the acquisition request originated.
+ */
+ AcpiGbl_GlobalLockHandle++;
+ if (AcpiGbl_GlobalLockHandle == 0)
+ {
+ AcpiGbl_GlobalLockHandle = 1;
+ }
+
+ /*
+ * Make sure that a global lock actually exists. If not, just
+ * treat the lock as a standard mutex.
+ */
+ if (!AcpiGbl_GlobalLockPresent)
+ {
+ AcpiGbl_GlobalLockAcquired = TRUE;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+ do
+ {
+ /* Attempt to acquire the actual hardware lock */
+
+ ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
+ if (Acquired)
+ {
+ AcpiGbl_GlobalLockAcquired = TRUE;
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Acquired hardware Global Lock\n"));
+ break;
+ }
+
+ /*
+ * Did not get the lock. The pending bit was set above, and
+ * we must now wait until we receive the global lock
+ * released interrupt.
+ */
+ AcpiGbl_GlobalLockPending = TRUE;
+ AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Waiting for hardware Global Lock\n"));
+
+ /*
+ * Wait for handshake with the global lock interrupt handler.
+ * This interface releases the interpreter if we must wait.
+ */
+ Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
+ ACPI_WAIT_FOREVER);
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+ } while (ACPI_SUCCESS (Status));
+
+ AcpiGbl_GlobalLockPending = FALSE;
+ AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvReleaseGlobalLock
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Releases ownership of the Global Lock.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvReleaseGlobalLock (
+ void)
+{
+ BOOLEAN Pending = FALSE;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
+
+
+ /* Lock must be already acquired */
+
+ if (!AcpiGbl_GlobalLockAcquired)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Cannot release the ACPI Global Lock, it has not been acquired"));
+ return_ACPI_STATUS (AE_NOT_ACQUIRED);
+ }
+
+ if (AcpiGbl_GlobalLockPresent)
+ {
+ /* Allow any thread to release the lock */
+
+ ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
+
+ /*
+ * If the pending bit was set, we must write GBL_RLS to the control
+ * register
+ */
+ if (Pending)
+ {
+ Status = AcpiWriteBitRegister (
+ ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
+ }
+
+ AcpiGbl_GlobalLockAcquired = FALSE;
+
+ /* Release the local GL mutex */
+
+ AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpe.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpe.c
new file mode 100644
index 0000000000..0083e60ab6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpe.c
@@ -0,0 +1,843 @@
+/******************************************************************************
+ *
+ * Module Name: evgpe - General Purpose Event handling and dispatch
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evgpe")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvAsynchExecuteGpeMethod (
+ void *Context);
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvAsynchEnableGpe (
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvUpdateGpeEnableMask
+ *
+ * PARAMETERS: GpeEventInfo - GPE to update
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Updates GPE register enable mask based upon whether there are
+ * runtime references to this GPE
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvUpdateGpeEnableMask (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ UINT32 RegisterBit;
+
+
+ ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
+
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+ if (!GpeRegisterInfo)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
+
+ /* Clear the run bit up front */
+
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
+
+ /* Set the mask bit only if there are references to this GPE */
+
+ if (GpeEventInfo->RuntimeCount)
+ {
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
+ }
+ GpeRegisterInfo->EnableMask = GpeRegisterInfo->EnableForRun;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvEnableGpe
+ *
+ * PARAMETERS: GpeEventInfo - GPE to enable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear a GPE of stale events and enable it.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvEnableGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvEnableGpe);
+
+
+ /* Clear the GPE (of stale events) */
+
+ Status = AcpiHwClearGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Enable the requested GPE */
+
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvAddGpeReference
+ *
+ * PARAMETERS: GpeEventInfo - Add a reference to this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvAddGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvAddGpeReference);
+
+
+ if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
+ {
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ GpeEventInfo->RuntimeCount++;
+ if (GpeEventInfo->RuntimeCount == 1)
+ {
+ /* Enable on first reference */
+
+ Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount--;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvRemoveGpeReference
+ *
+ * PARAMETERS: GpeEventInfo - Remove a reference to this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, the GPE is hardware-disabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvRemoveGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
+
+
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ GpeEventInfo->RuntimeCount--;
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ /* Disable on last reference */
+
+ Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount++;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvLowGetGpeInfo
+ *
+ * PARAMETERS: GpeNumber - Raw GPE number
+ * GpeBlock - A GPE info block
+ *
+ * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
+ * is not within the specified GPE block)
+ *
+ * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
+ * the low-level implementation of EvGetGpeEventInfo.
+ *
+ ******************************************************************************/
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+ UINT32 GpeNumber,
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ UINT32 GpeIndex;
+
+
+ /*
+ * Validate that the GpeNumber is within the specified GpeBlock.
+ * (Two steps)
+ */
+ if (!GpeBlock ||
+ (GpeNumber < GpeBlock->BlockBaseNumber))
+ {
+ return (NULL);
+ }
+
+ GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
+ if (GpeIndex >= GpeBlock->GpeCount)
+ {
+ return (NULL);
+ }
+
+ return (&GpeBlock->EventInfo[GpeIndex]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGetGpeEventInfo
+ *
+ * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
+ * GpeNumber - Raw GPE number
+ *
+ * RETURN: A GPE EventInfo struct. NULL if not a valid GPE
+ *
+ * DESCRIPTION: Returns the EventInfo struct associated with this GPE.
+ * Validates the GpeBlock and the GpeNumber
+ *
+ * Should be called only when the GPE lists are semaphore locked
+ * and not subject to change.
+ *
+ ******************************************************************************/
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvGetGpeEventInfo (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_GPE_EVENT_INFO *GpeInfo;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* A NULL GpeDevice means use the FADT-defined GPE block(s) */
+
+ if (!GpeDevice)
+ {
+ /* Examine GPE Block 0 and 1 (These blocks are permanent) */
+
+ for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
+ {
+ GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
+ AcpiGbl_GpeFadtBlocks[i]);
+ if (GpeInfo)
+ {
+ return (GpeInfo);
+ }
+ }
+
+ /* The GpeNumber was not in the range of either FADT GPE block */
+
+ return (NULL);
+ }
+
+ /* A Non-NULL GpeDevice means this is a GPE Block Device */
+
+ ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice);
+ if (!ObjDesc ||
+ !ObjDesc->Device.GpeBlock)
+ {
+ return (NULL);
+ }
+
+ return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGpeDetect
+ *
+ * PARAMETERS: GpeXruptList - Interrupt block for this interrupt.
+ * Can have multiple GPE blocks attached.
+ *
+ * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Detect if any GP events have occurred. This function is
+ * executed at interrupt level.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiEvGpeDetect (
+ ACPI_GPE_XRUPT_INFO *GpeXruptList)
+{
+ ACPI_STATUS Status;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_NAMESPACE_NODE *GpeDevice;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ UINT32 GpeNumber;
+ ACPI_GPE_HANDLER_INFO *GpeHandlerInfo;
+ UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
+ UINT8 EnabledStatusByte;
+ UINT32 StatusReg;
+ UINT32 EnableReg;
+ ACPI_CPU_FLAGS Flags;
+ UINT32 i;
+ UINT32 j;
+
+
+ ACPI_FUNCTION_NAME (EvGpeDetect);
+
+ /* Check for the case where there are no GPEs */
+
+ if (!GpeXruptList)
+ {
+ return (IntStatus);
+ }
+
+ /*
+ * We need to obtain the GPE lock for both the data structs and registers
+ * Note: Not necessary to obtain the hardware lock, since the GPE
+ * registers are owned by the GpeLock.
+ */
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Examine all GPE blocks attached to this interrupt level */
+
+ GpeBlock = GpeXruptList->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ GpeDevice = GpeBlock->Node;
+
+ /*
+ * Read all of the 8-bit GPE status and enable registers in this GPE
+ * block, saving all of them. Find all currently active GP events.
+ */
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Get the next status/enable pair */
+
+ GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
+
+ /*
+ * Optimization: If there are no GPEs enabled within this
+ * register, we can safely ignore the entire register.
+ */
+ if (!(GpeRegisterInfo->EnableForRun |
+ GpeRegisterInfo->EnableForWake))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+ "Ignore disabled registers for GPE %02X-%02X: "
+ "RunEnable=%02X, WakeEnable=%02X\n",
+ GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
+ GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake));
+ continue;
+ }
+
+ /* Read the Status Register */
+
+ Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Read the Enable Register */
+
+ Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+ "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, "
+ "RunEnable=%02X, WakeEnable=%02X\n",
+ GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
+ StatusReg, EnableReg,
+ GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake));
+
+ /* Check if there is anything active at all in this register */
+
+ EnabledStatusByte = (UINT8) (StatusReg & EnableReg);
+ if (!EnabledStatusByte)
+ {
+ /* No active GPEs in this register, move on */
+
+ continue;
+ }
+
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ /* Examine one GPE bit */
+
+ GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
+ ACPI_GPE_REGISTER_WIDTH) + j];
+ GpeNumber = j + GpeRegisterInfo->BaseGpeNumber;
+
+ if (EnabledStatusByte & (1 << j))
+ {
+ /* Invoke global event handler if present */
+
+ AcpiGpeCount++;
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE,
+ GpeDevice, GpeNumber,
+ AcpiGbl_GlobalEventHandlerContext);
+ }
+
+ /* Found an active GPE */
+
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_RAW_HANDLER)
+ {
+ /* Dispatch the event to a raw handler */
+
+ GpeHandlerInfo = GpeEventInfo->Dispatch.Handler;
+
+ /*
+ * There is no protection around the namespace node
+ * and the GPE handler to ensure a safe destruction
+ * because:
+ * 1. The namespace node is expected to always
+ * exist after loading a table.
+ * 2. The GPE handler is expected to be flushed by
+ * AcpiOsWaitEventsComplete() before the
+ * destruction.
+ */
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ IntStatus |= GpeHandlerInfo->Address (
+ GpeDevice, GpeNumber, GpeHandlerInfo->Context);
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ }
+ else
+ {
+ /*
+ * Dispatch the event to a standard handler or
+ * method.
+ */
+ IntStatus |= AcpiEvGpeDispatch (GpeDevice,
+ GpeEventInfo, GpeNumber);
+ }
+ }
+ }
+ }
+
+ GpeBlock = GpeBlock->Next;
+ }
+
+UnlockAndExit:
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return (IntStatus);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvAsynchExecuteGpeMethod
+ *
+ * PARAMETERS: Context (GpeEventInfo) - Info for this GPE
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Perform the actual execution of a GPE control method. This
+ * function is called from an invocation of AcpiOsExecute and
+ * therefore does NOT execute at interrupt level - so that
+ * the control method itself is not executed in the context of
+ * an interrupt handler.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvAsynchExecuteGpeMethod (
+ void *Context)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo = Context;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+
+
+ ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);
+
+
+ /* Do the correct dispatch - normal method or implicit notify */
+
+ switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
+ {
+ case ACPI_GPE_DISPATCH_NOTIFY:
+ /*
+ * Implicit notify.
+ * Dispatch a DEVICE_WAKE notify to the appropriate handler.
+ * NOTE: the request is queued for execution after this method
+ * completes. The notify handlers are NOT invoked synchronously
+ * from this thread -- because handlers may in turn run other
+ * control methods.
+ *
+ * June 2012: Expand implicit notify mechanism to support
+ * notifies on multiple device objects.
+ */
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (ACPI_SUCCESS (Status) && Notify)
+ {
+ Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode,
+ ACPI_NOTIFY_DEVICE_WAKE);
+
+ Notify = Notify->Next;
+ }
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+
+ /* Allocate the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ else
+ {
+ /*
+ * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
+ * _Lxx/_Exx control method that corresponds to this GPE
+ */
+ Info->PrefixNode = GpeEventInfo->Dispatch.MethodNode;
+ Info->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ Status = AcpiNsEvaluate (Info);
+ ACPI_FREE (Info);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while evaluating GPE method [%4.4s]",
+ AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode)));
+ }
+ break;
+
+ default:
+
+ goto ErrorExit; /* Should never happen */
+ }
+
+ /* Defer enabling of GPE until all notify handlers are done */
+
+ Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
+ AcpiEvAsynchEnableGpe, GpeEventInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ return_VOID;
+ }
+
+ErrorExit:
+ AcpiEvAsynchEnableGpe (GpeEventInfo);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvAsynchEnableGpe
+ *
+ * PARAMETERS: Context (GpeEventInfo) - Info for this GPE
+ * Callback from AcpiOsExecute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
+ * complete (i.e., finish execution of Notify)
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvAsynchEnableGpe (
+ void *Context)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo = Context;
+ ACPI_CPU_FLAGS Flags;
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ (void) AcpiEvFinishGpe (GpeEventInfo);
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvFinishGpe
+ *
+ * PARAMETERS: GpeEventInfo - Info for this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
+ * of a GPE method or a synchronous or asynchronous GPE handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvFinishGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status;
+
+
+ if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_LEVEL_TRIGGERED)
+ {
+ /*
+ * GPE is level-triggered, we clear the GPE status bit after
+ * handling the event.
+ */
+ Status = AcpiHwClearGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ /*
+ * Enable this GPE, conditionally. This means that the GPE will
+ * only be physically enabled if the EnableMask bit is set
+ * in the EventInfo.
+ */
+ (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGpeDispatch
+ *
+ * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
+ * GpeEventInfo - Info for this GPE
+ * GpeNumber - Number relative to the parent GPE block
+ *
+ * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
+ * or method (e.g. _Lxx/_Exx) handler.
+ *
+ * This function executes at interrupt level.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiEvGpeDispatch (
+ ACPI_NAMESPACE_NODE *GpeDevice,
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status;
+ UINT32 ReturnValue;
+
+
+ ACPI_FUNCTION_TRACE (EvGpeDispatch);
+
+
+ /*
+ * Always disable the GPE so that it does not keep firing before
+ * any asynchronous activity completes (either from the execution
+ * of a GPE method or an asynchronous GPE handler.)
+ *
+ * If there is no handler or method to run, just disable the
+ * GPE and leave it disabled permanently to prevent further such
+ * pointless events from firing.
+ */
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to disable GPE %02X", GpeNumber));
+ return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
+ }
+
+ /*
+ * If edge-triggered, clear the GPE status bit now. Note that
+ * level-triggered events are cleared after the GPE is serviced.
+ */
+ if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_EDGE_TRIGGERED)
+ {
+ Status = AcpiHwClearGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to clear GPE %02X", GpeNumber));
+ (void) AcpiHwLowSetGpe (GpeEventInfo,
+ ACPI_GPE_CONDITIONAL_ENABLE);
+ return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
+ }
+ }
+
+ /*
+ * Dispatch the GPE to either an installed handler or the control
+ * method associated with this GPE (_Lxx or _Exx). If a handler
+ * exists, we invoke it and do not attempt to run the method.
+ * If there is neither a handler nor a method, leave the GPE
+ * disabled.
+ */
+ switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
+ {
+ case ACPI_GPE_DISPATCH_HANDLER:
+
+ /* Invoke the installed handler (at interrupt level) */
+
+ ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
+ GpeDevice, GpeNumber,
+ GpeEventInfo->Dispatch.Handler->Context);
+
+ /* If requested, clear (if level-triggered) and reenable the GPE */
+
+ if (ReturnValue & ACPI_REENABLE_GPE)
+ {
+ (void) AcpiEvFinishGpe (GpeEventInfo);
+ }
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+ case ACPI_GPE_DISPATCH_NOTIFY:
+ /*
+ * Execute the method associated with the GPE
+ * NOTE: Level-triggered GPEs are cleared after the method completes.
+ */
+ Status = AcpiOsExecute (OSL_GPE_HANDLER,
+ AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to queue handler for GPE %02X - event disabled",
+ GpeNumber));
+ }
+ break;
+
+ default:
+ /*
+ * No handler or method to run!
+ * 03/2010: This case should no longer be possible. We will not allow
+ * a GPE to be enabled if it has no handler or method.
+ */
+ ACPI_ERROR ((AE_INFO,
+ "No handler or method for GPE %02X, disabling event",
+ GpeNumber));
+ break;
+ }
+
+ return_UINT32 (ACPI_INTERRUPT_HANDLED);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeblk.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeblk.c
new file mode 100644
index 0000000000..53528c6fcc
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeblk.c
@@ -0,0 +1,554 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeblk - GPE block creation and initialization.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evgpeblk")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiEvInstallGpeBlock (
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ UINT32 InterruptNumber);
+
+static ACPI_STATUS
+AcpiEvCreateGpeInfoBlocks (
+ ACPI_GPE_BLOCK_INFO *GpeBlock);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallGpeBlock
+ *
+ * PARAMETERS: GpeBlock - New GPE block
+ * InterruptNumber - Xrupt to be associated with this
+ * GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install new GPE block with mutex support
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvInstallGpeBlock (
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ UINT32 InterruptNumber)
+{
+ ACPI_GPE_BLOCK_INFO *NextGpeBlock;
+ ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiEvGetGpeXruptBlock (InterruptNumber, &GpeXruptBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Install the new block at the end of the list with lock */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ if (GpeXruptBlock->GpeBlockListHead)
+ {
+ NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
+ while (NextGpeBlock->Next)
+ {
+ NextGpeBlock = NextGpeBlock->Next;
+ }
+
+ NextGpeBlock->Next = GpeBlock;
+ GpeBlock->Previous = NextGpeBlock;
+ }
+ else
+ {
+ GpeXruptBlock->GpeBlockListHead = GpeBlock;
+ }
+
+ GpeBlock->XruptBlock = GpeXruptBlock;
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvDeleteGpeBlock
+ *
+ * PARAMETERS: GpeBlock - Existing GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a GPE block
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeBlock (
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Disable all GPEs in this block */
+
+ Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock, NULL);
+
+ if (!GpeBlock->Previous && !GpeBlock->Next)
+ {
+ /* This is the last GpeBlock on this interrupt */
+
+ Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+ else
+ {
+ /* Remove the block on this interrupt with lock */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ if (GpeBlock->Previous)
+ {
+ GpeBlock->Previous->Next = GpeBlock->Next;
+ }
+ else
+ {
+ GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next;
+ }
+
+ if (GpeBlock->Next)
+ {
+ GpeBlock->Next->Previous = GpeBlock->Previous;
+ }
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ }
+
+ AcpiCurrentGpeCount -= GpeBlock->GpeCount;
+
+ /* Free the GpeBlock */
+
+ ACPI_FREE (GpeBlock->RegisterInfo);
+ ACPI_FREE (GpeBlock->EventInfo);
+ ACPI_FREE (GpeBlock);
+
+UnlockAndExit:
+ Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvCreateGpeInfoBlocks
+ *
+ * PARAMETERS: GpeBlock - New GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvCreateGpeInfoBlocks (
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL;
+ ACPI_GPE_EVENT_INFO *ThisEvent;
+ ACPI_GPE_REGISTER_INFO *ThisRegister;
+ UINT32 i;
+ UINT32 j;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks);
+
+
+ /* Allocate the GPE register information block */
+
+ GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
+ (ACPI_SIZE) GpeBlock->RegisterCount *
+ sizeof (ACPI_GPE_REGISTER_INFO));
+ if (!GpeRegisterInfo)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not allocate the GpeRegisterInfo table"));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Allocate the GPE EventInfo block. There are eight distinct GPEs
+ * per register. Initialization to zeros is sufficient.
+ */
+ GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
+ sizeof (ACPI_GPE_EVENT_INFO));
+ if (!GpeEventInfo)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not allocate the GpeEventInfo table"));
+ Status = AE_NO_MEMORY;
+ goto ErrorExit;
+ }
+
+ /* Save the new Info arrays in the GPE block */
+
+ GpeBlock->RegisterInfo = GpeRegisterInfo;
+ GpeBlock->EventInfo = GpeEventInfo;
+
+ /*
+ * Initialize the GPE Register and Event structures. A goal of these
+ * tables is to hide the fact that there are two separate GPE register
+ * sets in a given GPE hardware block, the status registers occupy the
+ * first half, and the enable registers occupy the second half.
+ */
+ ThisRegister = GpeRegisterInfo;
+ ThisEvent = GpeEventInfo;
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Init the RegisterInfo for this GPE register (8 GPEs) */
+
+ ThisRegister->BaseGpeNumber = (UINT16)
+ (GpeBlock->BlockBaseNumber + (i * ACPI_GPE_REGISTER_WIDTH));
+
+ ThisRegister->StatusAddress.Address =
+ GpeBlock->Address + i;
+
+ ThisRegister->EnableAddress.Address =
+ GpeBlock->Address + i + GpeBlock->RegisterCount;
+
+ ThisRegister->StatusAddress.SpaceId = GpeBlock->SpaceId;
+ ThisRegister->EnableAddress.SpaceId = GpeBlock->SpaceId;
+ ThisRegister->StatusAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH;
+ ThisRegister->EnableAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH;
+ ThisRegister->StatusAddress.BitOffset = 0;
+ ThisRegister->EnableAddress.BitOffset = 0;
+
+ /* Init the EventInfo for each GPE within this register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j);
+ ThisEvent->RegisterInfo = ThisRegister;
+ ThisEvent++;
+ }
+
+ /* Disable all GPEs within this register */
+
+ Status = AcpiHwWrite (0x00, &ThisRegister->EnableAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* Clear any pending GPE events within this register */
+
+ Status = AcpiHwWrite (0xFF, &ThisRegister->StatusAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ ThisRegister++;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+
+
+ErrorExit:
+ if (GpeRegisterInfo)
+ {
+ ACPI_FREE (GpeRegisterInfo);
+ }
+ if (GpeEventInfo)
+ {
+ ACPI_FREE (GpeEventInfo);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvCreateGpeBlock
+ *
+ * PARAMETERS: GpeDevice - Handle to the parent GPE block
+ * GpeBlockAddress - Address and SpaceID
+ * RegisterCount - Number of GPE register pairs in the block
+ * GpeBlockBaseNumber - Starting GPE number for the block
+ * InterruptNumber - H/W interrupt for the block
+ * ReturnGpeBlock - Where the new block descriptor is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
+ * the block are disabled at exit.
+ * Note: Assumes namespace is locked.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvCreateGpeBlock (
+ ACPI_NAMESPACE_NODE *GpeDevice,
+ UINT64 Address,
+ UINT8 SpaceId,
+ UINT32 RegisterCount,
+ UINT16 GpeBlockBaseNumber,
+ UINT32 InterruptNumber,
+ ACPI_GPE_BLOCK_INFO **ReturnGpeBlock)
+{
+ ACPI_STATUS Status;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_WALK_INFO WalkInfo;
+
+
+ ACPI_FUNCTION_TRACE (EvCreateGpeBlock);
+
+
+ if (!RegisterCount)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Allocate a new GPE block */
+
+ GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
+ if (!GpeBlock)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize the new GPE block */
+
+ GpeBlock->Address = Address;
+ GpeBlock->SpaceId = SpaceId;
+ GpeBlock->Node = GpeDevice;
+ GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
+ GpeBlock->Initialized = FALSE;
+ GpeBlock->RegisterCount = RegisterCount;
+ GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
+
+ /*
+ * Create the RegisterInfo and EventInfo sub-structures
+ * Note: disables and clears all GPEs in the block
+ */
+ Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (GpeBlock);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the new block in the global lists */
+
+ Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (GpeBlock->RegisterInfo);
+ ACPI_FREE (GpeBlock->EventInfo);
+ ACPI_FREE (GpeBlock);
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiGbl_AllGpesInitialized = FALSE;
+
+ /* Find all GPE methods (_Lxx or_Exx) for this block */
+
+ WalkInfo.GpeBlock = GpeBlock;
+ WalkInfo.GpeDevice = GpeDevice;
+ WalkInfo.ExecuteByOwnerId = FALSE;
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
+ AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
+
+ /* Return the new block */
+
+ if (ReturnGpeBlock)
+ {
+ (*ReturnGpeBlock) = GpeBlock;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
+ (UINT32) GpeBlock->BlockBaseNumber,
+ (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
+ GpeDevice->Name.Ascii, GpeBlock->RegisterCount, InterruptNumber,
+ InterruptNumber == AcpiGbl_FADT.SciInterrupt ? " (SCI)" : ""));
+
+ /* Update global count of currently available GPEs */
+
+ AcpiCurrentGpeCount += GpeBlock->GpeCount;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInitializeGpeBlock
+ *
+ * PARAMETERS: ACPI_GPE_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
+ * associated methods.
+ * Note: Assumes namespace is locked.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitializeGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Ignored)
+{
+ ACPI_STATUS Status;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ UINT32 GpeEnabledCount;
+ UINT32 GpeIndex;
+ UINT32 i;
+ UINT32 j;
+
+
+ ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
+
+
+ /*
+ * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
+ * any GPE blocks that have been initialized already.
+ */
+ if (!GpeBlock || GpeBlock->Initialized)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Enable all GPEs that have a corresponding method and have the
+ * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
+ * must be enabled via the acpi_enable_gpe() interface.
+ */
+ GpeEnabledCount = 0;
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ /* Get the info block for this particular GPE */
+
+ GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+ GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
+
+ /*
+ * Ignore GPEs that have no corresponding _Lxx/_Exx method
+ * and GPEs that are used to wake the system
+ */
+ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NONE) ||
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_HANDLER) ||
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_RAW_HANDLER) ||
+ (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
+ {
+ continue;
+ }
+
+ Status = AcpiEvAddGpeReference (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not enable GPE 0x%02X",
+ GpeIndex + GpeBlock->BlockBaseNumber));
+ continue;
+ }
+
+ GpeEnabledCount++;
+ }
+ }
+
+ if (GpeEnabledCount)
+ {
+ ACPI_INFO ((AE_INFO,
+ "Enabled %u GPEs in block %02X to %02X", GpeEnabledCount,
+ (UINT32) GpeBlock->BlockBaseNumber,
+ (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1))));
+ }
+
+ GpeBlock->Initialized = TRUE;
+ return_ACPI_STATUS (AE_OK);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeinit.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeinit.c
new file mode 100644
index 0000000000..63a4c4a458
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeinit.c
@@ -0,0 +1,466 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeinit - System GPE initialization and update
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evgpeinit")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/*
+ * Note: History of _PRW support in ACPICA
+ *
+ * Originally (2000 - 2010), the GPE initialization code performed a walk of
+ * the entire namespace to execute the _PRW methods and detect all GPEs
+ * capable of waking the system.
+ *
+ * As of 10/2010, the _PRW method execution has been removed since it is
+ * actually unnecessary. The host OS must in fact execute all _PRW methods
+ * in order to identify the device/power-resource dependencies. We now put
+ * the onus on the host OS to identify the wake GPEs as part of this process
+ * and to inform ACPICA of these GPEs via the AcpiSetupGpeForWake interface. This
+ * not only reduces the complexity of the ACPICA initialization code, but in
+ * some cases (on systems with very large namespaces) it should reduce the
+ * kernel boot time as well.
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGpeInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the GPE data structures and the FADT GPE 0/1 blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGpeInitialize (
+ void)
+{
+ UINT32 RegisterCount0 = 0;
+ UINT32 RegisterCount1 = 0;
+ UINT32 GpeNumberMax = 0;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvGpeInitialize);
+
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "Initializing General Purpose Events (GPEs):\n"));
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Initialize the GPE Block(s) defined in the FADT
+ *
+ * Why the GPE register block lengths are divided by 2: From the ACPI
+ * Spec, section "General-Purpose Event Registers", we have:
+ *
+ * "Each register block contains two registers of equal length
+ * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
+ * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
+ * The length of the GPE1_STS and GPE1_EN registers is equal to
+ * half the GPE1_LEN. If a generic register block is not supported
+ * then its respective block pointer and block length values in the
+ * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
+ * to be the same size."
+ */
+
+ /*
+ * Determine the maximum GPE number for this machine.
+ *
+ * Note: both GPE0 and GPE1 are optional, and either can exist without
+ * the other.
+ *
+ * If EITHER the register length OR the block address are zero, then that
+ * particular block is not supported.
+ */
+ if (AcpiGbl_FADT.Gpe0BlockLength &&
+ AcpiGbl_FADT.XGpe0Block.Address)
+ {
+ /* GPE block 0 exists (has both length and address > 0) */
+
+ RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2);
+ GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;
+
+ /* Install GPE Block 0 */
+
+ Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
+ AcpiGbl_FADT.XGpe0Block.Address,
+ AcpiGbl_FADT.XGpe0Block.SpaceId,
+ RegisterCount0, 0,
+ AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]);
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not create GPE Block 0"));
+ }
+ }
+
+ if (AcpiGbl_FADT.Gpe1BlockLength &&
+ AcpiGbl_FADT.XGpe1Block.Address)
+ {
+ /* GPE block 1 exists (has both length and address > 0) */
+
+ RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2);
+
+ /* Check for GPE0/GPE1 overlap (if both banks exist) */
+
+ if ((RegisterCount0) &&
+ (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
+ "(GPE %u to %u) - Ignoring GPE1",
+ GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
+ AcpiGbl_FADT.Gpe1Base +
+ ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+
+ /* Ignore GPE1 block by setting the register count to zero */
+
+ RegisterCount1 = 0;
+ }
+ else
+ {
+ /* Install GPE Block 1 */
+
+ Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
+ AcpiGbl_FADT.XGpe1Block.Address,
+ AcpiGbl_FADT.XGpe1Block.SpaceId,
+ RegisterCount1,
+ AcpiGbl_FADT.Gpe1Base,
+ AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]);
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not create GPE Block 1"));
+ }
+
+ /*
+ * GPE0 and GPE1 do not have to be contiguous in the GPE number
+ * space. However, GPE0 always starts at GPE number zero.
+ */
+ GpeNumberMax = AcpiGbl_FADT.Gpe1Base +
+ ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+ }
+ }
+
+ /* Exit if there are no GPE registers */
+
+ if ((RegisterCount0 + RegisterCount1) == 0)
+ {
+ /* GPEs are not required by ACPI, this is OK */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "There are no GPE blocks defined in the FADT\n"));
+ Status = AE_OK;
+ goto Cleanup;
+ }
+
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvUpdateGpes
+ *
+ * PARAMETERS: TableOwnerId - ID of the newly-loaded ACPI table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
+ * result of a Load() or LoadTable() operation. If new GPE
+ * methods have been installed, register the new methods.
+ *
+ ******************************************************************************/
+
+void
+AcpiEvUpdateGpes (
+ ACPI_OWNER_ID TableOwnerId)
+{
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_WALK_INFO WalkInfo;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /*
+ * Find any _Lxx/_Exx GPE methods that have just been loaded.
+ *
+ * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
+ * enabled.
+ *
+ * Examine the namespace underneath each GpeDevice within the
+ * GpeBlock lists.
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ WalkInfo.Count = 0;
+ WalkInfo.OwnerId = TableOwnerId;
+ WalkInfo.ExecuteByOwnerId = TRUE;
+
+ /* Walk the interrupt level descriptor list */
+
+ GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+ while (GpeXruptInfo)
+ {
+ /* Walk all Gpe Blocks attached to this interrupt level */
+
+ GpeBlock = GpeXruptInfo->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ WalkInfo.GpeBlock = GpeBlock;
+ WalkInfo.GpeDevice = GpeBlock->Node;
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD,
+ WalkInfo.GpeDevice, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_NO_UNLOCK, AcpiEvMatchGpeMethod,
+ NULL, &WalkInfo, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While decoding _Lxx/_Exx methods"));
+ }
+
+ GpeBlock = GpeBlock->Next;
+ }
+
+ GpeXruptInfo = GpeXruptInfo->Next;
+ }
+
+ if (WalkInfo.Count)
+ {
+ ACPI_INFO ((AE_INFO, "Enabled %u new GPEs", WalkInfo.Count));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvMatchGpeMethod
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
+ * control method under the _GPE portion of the namespace.
+ * Extract the name and GPE type from the object, saving this
+ * information for quick lookup during GPE dispatch. Allows a
+ * per-OwnerId evaluation if ExecuteByOwnerId is TRUE in the
+ * WalkInfo parameter block.
+ *
+ * The name of each GPE control method is of the form:
+ * "_Lxx" or "_Exx", where:
+ * L - means that the GPE is level triggered
+ * E - means that the GPE is edge triggered
+ * xx - is the GPE number [in HEX]
+ *
+ * If WalkInfo->ExecuteByOwnerId is TRUE, we only execute examine GPE methods
+ * with that owner.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvMatchGpeMethod (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ACPI_GPE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context);
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ UINT32 GpeNumber;
+ char Name[ACPI_NAME_SIZE + 1];
+ UINT8 Type;
+
+
+ ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
+
+
+ /* Check if requested OwnerId matches this OwnerId */
+
+ if ((WalkInfo->ExecuteByOwnerId) &&
+ (MethodNode->OwnerId != WalkInfo->OwnerId))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Match and decode the _Lxx and _Exx GPE method names
+ *
+ * 1) Extract the method name and null terminate it
+ */
+ ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
+ Name[ACPI_NAME_SIZE] = 0;
+
+ /* 2) Name must begin with an underscore */
+
+ if (Name[0] != '_')
+ {
+ return_ACPI_STATUS (AE_OK); /* Ignore this method */
+ }
+
+ /*
+ * 3) Edge/Level determination is based on the 2nd character
+ * of the method name
+ */
+ switch (Name[1])
+ {
+ case 'L':
+
+ Type = ACPI_GPE_LEVEL_TRIGGERED;
+ break;
+
+ case 'E':
+
+ Type = ACPI_GPE_EDGE_TRIGGERED;
+ break;
+
+ default:
+
+ /* Unknown method type, just ignore it */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+ "Ignoring unknown GPE method type: %s "
+ "(name not of form _Lxx or _Exx)", Name));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* 4) The last two characters of the name are the hex GPE Number */
+
+ GpeNumber = strtoul (&Name[2], NULL, 16);
+ if (GpeNumber == ACPI_UINT32_MAX)
+ {
+ /* Conversion failed; invalid method, just ignore it */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+ "Could not extract GPE number from name: %s "
+ "(name is not of form _Lxx or _Exx)", Name));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Ensure that we have a valid GPE number for this GPE block */
+
+ GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, WalkInfo->GpeBlock);
+ if (!GpeEventInfo)
+ {
+ /*
+ * This GpeNumber is not valid for this GPE block, just ignore it.
+ * However, it may be valid for a different GPE block, since GPE0
+ * and GPE1 methods both appear under \_GPE.
+ */
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_HANDLER) ||
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_RAW_HANDLER))
+ {
+ /* If there is already a handler, ignore this GPE method */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_METHOD)
+ {
+ /*
+ * If there is already a method, ignore this method. But check
+ * for a type mismatch (if both the _Lxx AND _Exx exist)
+ */
+ if (Type != (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "For GPE 0x%.2X, found both _L%2.2X and _E%2.2X methods",
+ GpeNumber, GpeNumber, GpeNumber));
+ }
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Disable the GPE in case it's been enabled already. */
+
+ (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+
+ /*
+ * Add the GPE information from above to the GpeEventInfo block for
+ * use during dispatch of this GPE.
+ */
+ GpeEventInfo->Flags &= ~(ACPI_GPE_DISPATCH_MASK);
+ GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
+ GpeEventInfo->Dispatch.MethodNode = MethodNode;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+ "Registered GPE method %s as GPE number 0x%.2X\n",
+ Name, GpeNumber));
+ return_ACPI_STATUS (AE_OK);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeutil.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeutil.c
new file mode 100644
index 0000000000..1f0385935c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evgpeutil.c
@@ -0,0 +1,397 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeutil - GPE utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evgpeutil")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvWalkGpeList
+ *
+ * PARAMETERS: GpeWalkCallback - Routine called for each GPE block
+ * Context - Value passed to callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk the GPE lists.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvWalkGpeList (
+ ACPI_GPE_CALLBACK GpeWalkCallback,
+ void *Context)
+{
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvWalkGpeList);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Walk the interrupt level descriptor list */
+
+ GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+ while (GpeXruptInfo)
+ {
+ /* Walk all Gpe Blocks attached to this interrupt level */
+
+ GpeBlock = GpeXruptInfo->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ /* One callback per GPE block */
+
+ Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_END) /* Callback abort */
+ {
+ Status = AE_OK;
+ }
+ goto UnlockAndExit;
+ }
+
+ GpeBlock = GpeBlock->Next;
+ }
+
+ GpeXruptInfo = GpeXruptInfo->Next;
+ }
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGetGpeDevice
+ *
+ * PARAMETERS: GPE_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
+ * block device. NULL if the GPE is one of the FADT-defined GPEs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGetGpeDevice (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ ACPI_GPE_DEVICE_INFO *Info = Context;
+
+
+ /* Increment Index by the number of GPEs in this block */
+
+ Info->NextBlockBaseIndex += GpeBlock->GpeCount;
+
+ if (Info->Index < Info->NextBlockBaseIndex)
+ {
+ /*
+ * The GPE index is within this block, get the node. Leave the node
+ * NULL for the FADT-defined GPEs
+ */
+ if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
+ {
+ Info->GpeDevice = GpeBlock->Node;
+ }
+
+ Info->Status = AE_OK;
+ return (AE_CTRL_END);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGetGpeXruptBlock
+ *
+ * PARAMETERS: InterruptNumber - Interrupt for a GPE block
+ * GpeXruptBlock - Where the block is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
+ * block per unique interrupt level used for GPEs. Should be
+ * called only when the GPE lists are semaphore locked and not
+ * subject to change.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGetGpeXruptBlock (
+ UINT32 InterruptNumber,
+ ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
+{
+ ACPI_GPE_XRUPT_INFO *NextGpeXrupt;
+ ACPI_GPE_XRUPT_INFO *GpeXrupt;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
+
+
+ /* No need for lock since we are not changing any list elements here */
+
+ NextGpeXrupt = AcpiGbl_GpeXruptListHead;
+ while (NextGpeXrupt)
+ {
+ if (NextGpeXrupt->InterruptNumber == InterruptNumber)
+ {
+ *GpeXruptBlock = NextGpeXrupt;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ NextGpeXrupt = NextGpeXrupt->Next;
+ }
+
+ /* Not found, must allocate a new xrupt descriptor */
+
+ GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
+ if (!GpeXrupt)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ GpeXrupt->InterruptNumber = InterruptNumber;
+
+ /* Install new interrupt descriptor with spin lock */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ if (AcpiGbl_GpeXruptListHead)
+ {
+ NextGpeXrupt = AcpiGbl_GpeXruptListHead;
+ while (NextGpeXrupt->Next)
+ {
+ NextGpeXrupt = NextGpeXrupt->Next;
+ }
+
+ NextGpeXrupt->Next = GpeXrupt;
+ GpeXrupt->Previous = NextGpeXrupt;
+ }
+ else
+ {
+ AcpiGbl_GpeXruptListHead = GpeXrupt;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ /* Install new interrupt handler if not SCI_INT */
+
+ if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
+ {
+ Status = AcpiOsInstallInterruptHandler (InterruptNumber,
+ AcpiEvGpeXruptHandler, GpeXrupt);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not install GPE interrupt handler at level 0x%X",
+ InterruptNumber));
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ *GpeXruptBlock = GpeXrupt;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvDeleteGpeXrupt
+ *
+ * PARAMETERS: GpeXrupt - A GPE interrupt info block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
+ * interrupt handler if not the SCI interrupt.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeXrupt (
+ ACPI_GPE_XRUPT_INFO *GpeXrupt)
+{
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
+
+
+ /* We never want to remove the SCI interrupt handler */
+
+ if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
+ {
+ GpeXrupt->GpeBlockListHead = NULL;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Disable this interrupt */
+
+ Status = AcpiOsRemoveInterruptHandler (
+ GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Unlink the interrupt block with lock */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ if (GpeXrupt->Previous)
+ {
+ GpeXrupt->Previous->Next = GpeXrupt->Next;
+ }
+ else
+ {
+ /* No previous, update list head */
+
+ AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
+ }
+
+ if (GpeXrupt->Next)
+ {
+ GpeXrupt->Next->Previous = GpeXrupt->Previous;
+ }
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ /* Free the block */
+
+ ACPI_FREE (GpeXrupt);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvDeleteGpeHandlers
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ * Used only prior to termination.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeHandlers (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ ACPI_GPE_NOTIFY_INFO *Next;
+ UINT32 i;
+ UINT32 j;
+
+
+ ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
+ ACPI_GPE_REGISTER_WIDTH) + j];
+
+ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_HANDLER) ||
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_RAW_HANDLER))
+ {
+ /* Delete an installed handler block */
+
+ ACPI_FREE (GpeEventInfo->Dispatch.Handler);
+ GpeEventInfo->Dispatch.Handler = NULL;
+ GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
+ }
+ else if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_NOTIFY)
+ {
+ /* Delete the implicit notification device list */
+
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
+ {
+ Next = Notify->Next;
+ ACPI_FREE (Notify);
+ Notify = Next;
+ }
+ GpeEventInfo->Dispatch.NotifyList = NULL;
+ GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
+ }
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evhandler.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evhandler.c
new file mode 100644
index 0000000000..419936bc2f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evhandler.c
@@ -0,0 +1,582 @@
+/******************************************************************************
+ *
+ * Module Name: evhandler - Support for Address Space handlers
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evhandler")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiEvInstallHandler (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+/* These are the address spaces that will get default handlers */
+
+UINT8 AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] =
+{
+ ACPI_ADR_SPACE_SYSTEM_MEMORY,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_ADR_SPACE_DATA_TABLE
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallRegionHandlers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Installs the core subsystem default address space handlers.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInstallRegionHandlers (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallRegionHandlers);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * All address spaces (PCI Config, EC, SMBus) are scope dependent and
+ * registration must occur for a specific device.
+ *
+ * In the case of the system memory and IO address spaces there is
+ * currently no device associated with the address space. For these we
+ * use the root.
+ *
+ * We install the default PCI config space handler at the root so that
+ * this space is immediately available even though the we have not
+ * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
+ * specification which states that the PCI config space must be always
+ * available -- even though we are nowhere near ready to find the PCI root
+ * buses at this point.
+ *
+ * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
+ * has already been installed (via AcpiInstallAddressSpaceHandler).
+ * Similar for AE_SAME_HANDLER.
+ */
+ for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
+ {
+ Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode,
+ AcpiGbl_DefaultAddressSpaces[i],
+ ACPI_DEFAULT_HANDLER, NULL, NULL);
+ switch (Status)
+ {
+ case AE_OK:
+ case AE_SAME_HANDLER:
+ case AE_ALREADY_EXISTS:
+
+ /* These exceptions are all OK */
+
+ Status = AE_OK;
+ break;
+
+ default:
+
+ goto UnlockAndExit;
+ }
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvHasDefaultHandler
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * SpaceId - The address space ID
+ *
+ * RETURN: TRUE if default handler is installed, FALSE otherwise
+ *
+ * DESCRIPTION: Check if the default handler is installed for the requested
+ * space ID.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiEvHasDefaultHandler (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+
+
+ /* Must have an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ HandlerObj = ObjDesc->Device.Handler;
+
+ /* Walk the linked list of handlers for this object */
+
+ while (HandlerObj)
+ {
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
+ {
+ if (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+ {
+ return (TRUE);
+ }
+ }
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallHandler
+ *
+ * PARAMETERS: WalkNamespace callback
+ *
+ * DESCRIPTION: This routine installs an address handler into objects that are
+ * of type Region or Device.
+ *
+ * If the Object is a Device, and the device has a handler of
+ * the same type then the search is terminated in that branch.
+ *
+ * This is because the existing handler is closer in proximity
+ * to any more regions than the one we are trying to install.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvInstallHandler (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *NextHandlerObj;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (EvInstallHandler);
+
+
+ HandlerObj = (ACPI_OPERAND_OBJECT *) Context;
+
+ /* Parameter validation */
+
+ if (!HandlerObj)
+ {
+ return (AE_OK);
+ }
+
+ /* Convert and validate the device handle */
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * We only care about regions and objects that are allowed to have
+ * address space handlers
+ */
+ if ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_REGION) &&
+ (Node != AcpiGbl_RootNode))
+ {
+ return (AE_OK);
+ }
+
+ /* Check for an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /* No object, just exit */
+
+ return (AE_OK);
+ }
+
+ /* Devices are handled different than regions */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_DEVICE)
+ {
+ /* Check if this Device already has a handler for this address space */
+
+ NextHandlerObj = ObjDesc->Device.Handler;
+ while (NextHandlerObj)
+ {
+ /* Found a handler, is it for the same address space? */
+
+ if (NextHandlerObj->AddressSpace.SpaceId ==
+ HandlerObj->AddressSpace.SpaceId)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Found handler for region [%s] in device %p(%p) "
+ "handler %p\n",
+ AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId),
+ ObjDesc, NextHandlerObj, HandlerObj));
+
+ /*
+ * Since the object we found it on was a device, then it
+ * means that someone has already installed a handler for
+ * the branch of the namespace from this device on. Just
+ * bail out telling the walk routine to not traverse this
+ * branch. This preserves the scoping rule for handlers.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+
+ /* Walk the linked list of handlers attached to this device */
+
+ NextHandlerObj = NextHandlerObj->AddressSpace.Next;
+ }
+
+ /*
+ * As long as the device didn't have a handler for this space we
+ * don't care about it. We just ignore it and proceed.
+ */
+ return (AE_OK);
+ }
+
+ /* Object is a Region */
+
+ if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId)
+ {
+ /* This region is for a different address space, just ignore it */
+
+ return (AE_OK);
+ }
+
+ /*
+ * Now we have a region and it is for the handler's address space type.
+ *
+ * First disconnect region for any previous handler (if any)
+ */
+ AcpiEvDetachRegion (ObjDesc, FALSE);
+
+ /* Connect the region to the new handler */
+
+ Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallSpaceHandler
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * SpaceId - The address space ID
+ * Handler - Address of the handler
+ * Setup - Address of the setup function
+ * Context - Value passed to the handler on each access
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
+ * Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInstallSpaceHandler (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE Type;
+ UINT8 Flags = 0;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallSpaceHandler);
+
+
+ /*
+ * This registration is valid for only the types below and the root. This
+ * is where the default handlers get placed.
+ */
+ if ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_PROCESSOR) &&
+ (Node->Type != ACPI_TYPE_THERMAL) &&
+ (Node != AcpiGbl_RootNode))
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ if (Handler == ACPI_DEFAULT_HANDLER)
+ {
+ Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+ switch (SpaceId)
+ {
+ case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+
+ Handler = AcpiExSystemMemorySpaceHandler;
+ Setup = AcpiEvSystemMemoryRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_SYSTEM_IO:
+
+ Handler = AcpiExSystemIoSpaceHandler;
+ Setup = AcpiEvIoSpaceRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_CONFIG:
+
+ Handler = AcpiExPciConfigSpaceHandler;
+ Setup = AcpiEvPciConfigRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_CMOS:
+
+ Handler = AcpiExCmosSpaceHandler;
+ Setup = AcpiEvCmosRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+
+ Handler = AcpiExPciBarSpaceHandler;
+ Setup = AcpiEvPciBarRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_DATA_TABLE:
+
+ Handler = AcpiExDataTableSpaceHandler;
+ Setup = NULL;
+ break;
+
+ default:
+
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+ }
+
+ /* If the caller hasn't specified a setup routine, use the default */
+
+ if (!Setup)
+ {
+ Setup = AcpiEvDefaultRegionSetup;
+ }
+
+ /* Check for an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ /*
+ * The attached device object already exists. Make sure the handler
+ * is not already installed.
+ */
+ HandlerObj = ObjDesc->Device.Handler;
+
+ /* Walk the handler list for this device */
+
+ while (HandlerObj)
+ {
+ /* Same SpaceId indicates a handler already installed */
+
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
+ {
+ if (HandlerObj->AddressSpace.Handler == Handler)
+ {
+ /*
+ * It is (relatively) OK to attempt to install the SAME
+ * handler twice. This can easily happen with the
+ * PCI_Config space.
+ */
+ Status = AE_SAME_HANDLER;
+ goto UnlockAndExit;
+ }
+ else
+ {
+ /* A handler is already installed */
+
+ Status = AE_ALREADY_EXISTS;
+ }
+ goto UnlockAndExit;
+ }
+
+ /* Walk the linked list of handlers */
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Creating object on Device %p while installing handler\n", Node));
+
+ /* ObjDesc does not exist, create one */
+
+ if (Node->Type == ACPI_TYPE_ANY)
+ {
+ Type = ACPI_TYPE_DEVICE;
+ }
+ else
+ {
+ Type = Node->Type;
+ }
+
+ ObjDesc = AcpiUtCreateInternalObject (Type);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /* Init new descriptor */
+
+ ObjDesc->Common.Type = (UINT8) Type;
+
+ /* Attach the new object to the Node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, Type);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+ AcpiUtGetRegionName (SpaceId), SpaceId,
+ AcpiUtGetNodeName (Node), Node, ObjDesc));
+
+ /*
+ * Install the handler
+ *
+ * At this point there is no existing handler. Just allocate the object
+ * for the handler and link it into the list.
+ */
+ HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+ if (!HandlerObj)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /* Init handler obj */
+
+ HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
+ HandlerObj->AddressSpace.HandlerFlags = Flags;
+ HandlerObj->AddressSpace.RegionList = NULL;
+ HandlerObj->AddressSpace.Node = Node;
+ HandlerObj->AddressSpace.Handler = Handler;
+ HandlerObj->AddressSpace.Context = Context;
+ HandlerObj->AddressSpace.Setup = Setup;
+
+ /* Install at head of Device.AddressSpace list */
+
+ HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler;
+
+ /*
+ * The Device object is the first reference on the HandlerObj.
+ * Each region that uses the handler adds a reference.
+ */
+ ObjDesc->Device.Handler = HandlerObj;
+
+ /*
+ * Walk the namespace finding all of the regions this
+ * handler will manage.
+ *
+ * Start at the device and search the branch toward
+ * the leaf nodes until either the leaf is encountered or
+ * a device is detected that has an address handler of the
+ * same type.
+ *
+ * In either case, back up and search down the remainder
+ * of the branch
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL,
+ HandlerObj, NULL);
+
+UnlockAndExit:
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evmisc.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evmisc.c
new file mode 100644
index 0000000000..b178543613
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evmisc.c
@@ -0,0 +1,331 @@
+/******************************************************************************
+ *
+ * Module Name: evmisc - Miscellaneous event manager support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evmisc")
+
+
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvNotifyDispatch (
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvIsNotifyObject
+ *
+ * PARAMETERS: Node - Node to check
+ *
+ * RETURN: TRUE if notifies allowed on this object
+ *
+ * DESCRIPTION: Check type of node for a object that supports notifies.
+ *
+ * TBD: This could be replaced by a flag bit in the node.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiEvIsNotifyObject (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+ /*
+ * These are the ONLY objects that can receive ACPI notifications
+ */
+ return (TRUE);
+
+ default:
+
+ return (FALSE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvQueueNotifyRequest
+ *
+ * PARAMETERS: Node - NS node for the notified object
+ * NotifyValue - Value from the Notify() request
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dispatch a device notification event to a previously
+ * installed handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvQueueNotifyRequest (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 NotifyValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerListHead = NULL;
+ ACPI_GENERIC_STATE *Info;
+ UINT8 HandlerListId = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
+
+
+ /* Are Notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the correct notify list type (System or Device) */
+
+ if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
+ {
+ HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
+ }
+ else
+ {
+ HandlerListId = ACPI_DEVICE_HANDLER_LIST;
+ }
+
+ /* Get the notify object attached to the namespace Node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ /* We have an attached object, Get the correct handler list */
+
+ HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
+ }
+
+ /*
+ * If there is no notify handler (Global or Local)
+ * for this object, just ignore the notify
+ */
+ if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
+ AcpiUtGetNodeName (Node), NotifyValue, Node));
+
+ return (AE_OK);
+ }
+
+ /* Setup notify info and schedule the notify dispatcher */
+
+ Info = AcpiUtCreateGenericState ();
+ if (!Info)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
+
+ Info->Notify.Node = Node;
+ Info->Notify.Value = (UINT16) NotifyValue;
+ Info->Notify.HandlerListId = HandlerListId;
+ Info->Notify.HandlerListHead = HandlerListHead;
+ Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
+ NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node));
+
+ Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
+ Info);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtDeleteGenericState (Info);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvNotifyDispatch
+ *
+ * PARAMETERS: Context - To be passed to the notify handler
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Dispatch a device notification event to a previously
+ * installed handler.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiEvNotifyDispatch (
+ void *Context)
+{
+ ACPI_GENERIC_STATE *Info = (ACPI_GENERIC_STATE *) Context;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Invoke a global notify handler if installed */
+
+ if (Info->Notify.Global->Handler)
+ {
+ Info->Notify.Global->Handler (Info->Notify.Node,
+ Info->Notify.Value,
+ Info->Notify.Global->Context);
+ }
+
+ /* Now invoke the local notify handler(s) if any are installed */
+
+ HandlerObj = Info->Notify.HandlerListHead;
+ while (HandlerObj)
+ {
+ HandlerObj->Notify.Handler (Info->Notify.Node,
+ Info->Notify.Value,
+ HandlerObj->Notify.Context);
+
+ HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId];
+ }
+
+ /* All done with the info object */
+
+ AcpiUtDeleteGenericState (Info);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEvTerminate
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Disable events and free memory allocated for table storage.
+ *
+ ******************************************************************************/
+
+void
+AcpiEvTerminate (
+ void)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvTerminate);
+
+
+ if (AcpiGbl_EventsInitialized)
+ {
+ /*
+ * Disable all event-related functionality. In all cases, on error,
+ * print a message but obviously we don't abort.
+ */
+
+ /* Disable all fixed events */
+
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ Status = AcpiDisableEvent (i, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not disable fixed event %u", (UINT32) i));
+ }
+ }
+
+ /* Disable all GPEs in all GPE blocks */
+
+ Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
+
+ Status = AcpiEvRemoveGlobalLockHandler ();
+ if (ACPI_FAILURE(Status))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not remove Global Lock handler"));
+ }
+
+ AcpiGbl_EventsInitialized = FALSE;
+ }
+
+ /* Remove SCI handlers */
+
+ Status = AcpiEvRemoveAllSciHandlers ();
+ if (ACPI_FAILURE(Status))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not remove SCI handler"));
+ }
+
+ /* Deallocate all handler objects installed within GPE info structs */
+
+ Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);
+
+ /* Return to original mode if necessary */
+
+ if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY)
+ {
+ Status = AcpiDisable ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO, "AcpiDisable failed"));
+ }
+ }
+ return_VOID;
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evregion.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evregion.c
new file mode 100644
index 0000000000..5904e31442
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evregion.c
@@ -0,0 +1,859 @@
+/******************************************************************************
+ *
+ * Module Name: evregion - Operation Region support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evregion")
+
+
+extern UINT8 AcpiGbl_DefaultAddressSpaces[];
+
+/* Local prototypes */
+
+static void
+AcpiEvOrphanEcRegMethod (
+ ACPI_NAMESPACE_NODE *EcDeviceNode);
+
+static ACPI_STATUS
+AcpiEvRegRun (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInitializeOpRegions
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute _REG methods for all Operation Regions that have
+ * an installed default region handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitializeOpRegions (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (EvInitializeOpRegions);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Run the _REG methods for OpRegions in each default address space */
+
+ for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
+ {
+ /*
+ * Make sure the installed handler is the DEFAULT handler. If not the
+ * default, the _REG methods will have already been run (when the
+ * handler was installed)
+ */
+ if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode,
+ AcpiGbl_DefaultAddressSpaces[i]))
+ {
+ Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode,
+ AcpiGbl_DefaultAddressSpaces[i]);
+ }
+ }
+
+ AcpiGbl_RegMethodsExecuted = TRUE;
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvAddressSpaceDispatch
+ *
+ * PARAMETERS: RegionObj - Internal region object
+ * FieldObj - Corresponding field. Can be NULL.
+ * Function - Read or Write operation
+ * RegionOffset - Where in the region to read or write
+ * BitWidth - Field width in bits (8, 16, 32, or 64)
+ * Value - Pointer to in or out value, must be
+ * a full 64-bit integer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dispatch an address space or operation region access to
+ * a previously installed handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvAddressSpaceDispatch (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ ACPI_OPERAND_OBJECT *FieldObj,
+ UINT32 Function,
+ UINT32 RegionOffset,
+ UINT32 BitWidth,
+ UINT64 *Value)
+{
+ ACPI_STATUS Status;
+ ACPI_ADR_SPACE_HANDLER Handler;
+ ACPI_ADR_SPACE_SETUP RegionSetup;
+ ACPI_OPERAND_OBJECT *HandlerDesc;
+ ACPI_OPERAND_OBJECT *RegionObj2;
+ void *RegionContext = NULL;
+ ACPI_CONNECTION_INFO *Context;
+ ACPI_PHYSICAL_ADDRESS Address;
+
+
+ ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
+
+
+ RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
+ if (!RegionObj2)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Ensure that there is a handler associated with this region */
+
+ HandlerDesc = RegionObj->Region.Handler;
+ if (!HandlerDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No handler for Region [%4.4s] (%p) [%s]",
+ AcpiUtGetNodeName (RegionObj->Region.Node),
+ RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ Context = HandlerDesc->AddressSpace.Context;
+
+ /*
+ * It may be the case that the region has never been initialized.
+ * Some types of regions require special init code
+ */
+ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
+ {
+ /* This region has not been initialized yet, do it */
+
+ RegionSetup = HandlerDesc->AddressSpace.Setup;
+ if (!RegionSetup)
+ {
+ /* No initialization routine, exit with error */
+
+ ACPI_ERROR ((AE_INFO,
+ "No init routine for region(%p) [%s]",
+ RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /*
+ * We must exit the interpreter because the region setup will
+ * potentially execute control methods (for example, the _REG method
+ * for this region)
+ */
+ AcpiExExitInterpreter ();
+
+ Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
+ Context, &RegionContext);
+
+ /* Re-enter the interpreter */
+
+ AcpiExEnterInterpreter ();
+
+ /* Check for failure of the Region Setup */
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "During region initialization: [%s]",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Region initialization may have been completed by RegionSetup */
+
+ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
+ {
+ RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
+
+ /*
+ * Save the returned context for use in all accesses to
+ * the handler for this particular region
+ */
+ if (!(RegionObj2->Extra.RegionContext))
+ {
+ RegionObj2->Extra.RegionContext = RegionContext;
+ }
+ }
+ }
+
+ /* We have everything we need, we can invoke the address space handler */
+
+ Handler = HandlerDesc->AddressSpace.Handler;
+ Address = (RegionObj->Region.Address + RegionOffset);
+
+ /*
+ * Special handling for GenericSerialBus and GeneralPurposeIo:
+ * There are three extra parameters that must be passed to the
+ * handler via the context:
+ * 1) Connection buffer, a resource template from Connection() op
+ * 2) Length of the above buffer
+ * 3) Actual access length from the AccessAs() op
+ *
+ * In addition, for GeneralPurposeIo, the Address and BitWidth fields
+ * are defined as follows:
+ * 1) Address is the pin number index of the field (bit offset from
+ * the previous Connection)
+ * 2) BitWidth is the actual bit length of the field (number of pins)
+ */
+ if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) &&
+ Context &&
+ FieldObj)
+ {
+ /* Get the Connection (ResourceTemplate) buffer */
+
+ Context->Connection = FieldObj->Field.ResourceBuffer;
+ Context->Length = FieldObj->Field.ResourceLength;
+ Context->AccessLength = FieldObj->Field.AccessLength;
+ }
+ if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) &&
+ Context &&
+ FieldObj)
+ {
+ /* Get the Connection (ResourceTemplate) buffer */
+
+ Context->Connection = FieldObj->Field.ResourceBuffer;
+ Context->Length = FieldObj->Field.ResourceLength;
+ Context->AccessLength = FieldObj->Field.AccessLength;
+ Address = FieldObj->Field.PinNumberIndex;
+ BitWidth = FieldObj->Field.BitLength;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+ &RegionObj->Region.Handler->AddressSpace, Handler,
+ ACPI_FORMAT_UINT64 (Address),
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+
+ if (!(HandlerDesc->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
+ {
+ /*
+ * For handlers other than the default (supplied) handlers, we must
+ * exit the interpreter because the handler *might* block -- we don't
+ * know what it will do, so we can't hold the lock on the intepreter.
+ */
+ AcpiExExitInterpreter();
+ }
+
+ /* Call the handler */
+
+ Status = Handler (Function, Address, BitWidth, Value, Context,
+ RegionObj2->Extra.RegionContext);
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+ }
+
+ if (!(HandlerDesc->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
+ {
+ /*
+ * We just returned from a non-default handler, we must re-enter the
+ * interpreter
+ */
+ AcpiExEnterInterpreter ();
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvDetachRegion
+ *
+ * PARAMETERS: RegionObj - Region Object
+ * AcpiNsIsLocked - Namespace Region Already Locked?
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Break the association between the handler and the region
+ * this is a two way association.
+ *
+ ******************************************************************************/
+
+void
+AcpiEvDetachRegion(
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsIsLocked)
+{
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *StartDesc;
+ ACPI_OPERAND_OBJECT **LastObjPtr;
+ ACPI_ADR_SPACE_SETUP RegionSetup;
+ void **RegionContext;
+ ACPI_OPERAND_OBJECT *RegionObj2;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvDetachRegion);
+
+
+ RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
+ if (!RegionObj2)
+ {
+ return_VOID;
+ }
+ RegionContext = &RegionObj2->Extra.RegionContext;
+
+ /* Get the address handler from the region object */
+
+ HandlerObj = RegionObj->Region.Handler;
+ if (!HandlerObj)
+ {
+ /* This region has no handler, all done */
+
+ return_VOID;
+ }
+
+ /* Find this region in the handler's list */
+
+ ObjDesc = HandlerObj->AddressSpace.RegionList;
+ StartDesc = ObjDesc;
+ LastObjPtr = &HandlerObj->AddressSpace.RegionList;
+
+ while (ObjDesc)
+ {
+ /* Is this the correct Region? */
+
+ if (ObjDesc == RegionObj)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Removing Region %p from address handler %p\n",
+ RegionObj, HandlerObj));
+
+ /* This is it, remove it from the handler's list */
+
+ *LastObjPtr = ObjDesc->Region.Next;
+ ObjDesc->Region.Next = NULL; /* Must clear field */
+
+ if (AcpiNsIsLocked)
+ {
+ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+ }
+
+ /* Now stop region accesses by executing the _REG method */
+
+ Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+ }
+
+ if (AcpiNsIsLocked)
+ {
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+ }
+
+ /*
+ * If the region has been activated, call the setup handler with
+ * the deactivate notification
+ */
+ if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
+ {
+ RegionSetup = HandlerObj->AddressSpace.Setup;
+ Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
+ HandlerObj->AddressSpace.Context, RegionContext);
+
+ /*
+ * RegionContext should have been released by the deactivate
+ * operation. We don't need access to it anymore here.
+ */
+ if (RegionContext)
+ {
+ *RegionContext = NULL;
+ }
+
+ /* Init routine may fail, Just ignore errors */
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "from region handler - deactivate, [%s]",
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+ }
+
+ RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
+ }
+
+ /*
+ * Remove handler reference in the region
+ *
+ * NOTE: this doesn't mean that the region goes away, the region
+ * is just inaccessible as indicated to the _REG method
+ *
+ * If the region is on the handler's list, this must be the
+ * region's handler
+ */
+ RegionObj->Region.Handler = NULL;
+ AcpiUtRemoveReference (HandlerObj);
+
+ return_VOID;
+ }
+
+ /* Walk the linked list of handlers */
+
+ LastObjPtr = &ObjDesc->Region.Next;
+ ObjDesc = ObjDesc->Region.Next;
+
+ /* Prevent infinite loop if list is corrupted */
+
+ if (ObjDesc == StartDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Circular handler list in region object %p",
+ RegionObj));
+ return_VOID;
+ }
+ }
+
+ /* If we get here, the region was not in the handler's region list */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Cannot remove region %p from address handler %p\n",
+ RegionObj, HandlerObj));
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvAttachRegion
+ *
+ * PARAMETERS: HandlerObj - Handler Object
+ * RegionObj - Region Object
+ * AcpiNsIsLocked - Namespace Region Already Locked?
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create the association between the handler and the region
+ * this is a two way association.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvAttachRegion (
+ ACPI_OPERAND_OBJECT *HandlerObj,
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsIsLocked)
+{
+
+ ACPI_FUNCTION_TRACE (EvAttachRegion);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Adding Region [%4.4s] %p to address handler %p [%s]\n",
+ AcpiUtGetNodeName (RegionObj->Region.Node),
+ RegionObj, HandlerObj,
+ AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+
+ /* Link this region to the front of the handler's list */
+
+ RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
+ HandlerObj->AddressSpace.RegionList = RegionObj;
+
+ /* Install the region's handler */
+
+ if (RegionObj->Region.Handler)
+ {
+ return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ }
+
+ RegionObj->Region.Handler = HandlerObj;
+ AcpiUtAddReference (HandlerObj);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvExecuteRegMethod
+ *
+ * PARAMETERS: RegionObj - Region object
+ * Function - Passed to _REG: On (1) or Off (0)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute _REG method for a region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvExecuteRegMethod (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ UINT32 Function)
+{
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_OPERAND_OBJECT *Args[3];
+ ACPI_OPERAND_OBJECT *RegionObj2;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvExecuteRegMethod);
+
+
+ RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
+ if (!RegionObj2)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ if (RegionObj2->Extra.Method_REG == NULL)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Allocate and initialize the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Info->PrefixNode = RegionObj2->Extra.Method_REG;
+ Info->RelativePathname = NULL;
+ Info->Parameters = Args;
+ Info->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ /*
+ * The _REG method has two arguments:
+ *
+ * Arg0 - Integer:
+ * Operation region space ID Same value as RegionObj->Region.SpaceId
+ *
+ * Arg1 - Integer:
+ * connection status 1 for connecting the handler, 0 for disconnecting
+ * the handler (Passed as a parameter)
+ */
+ Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId);
+ if (!Args[0])
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup1;
+ }
+
+ Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function);
+ if (!Args[1])
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup2;
+ }
+
+ Args[2] = NULL; /* Terminate list */
+
+ /* Execute the method, no return value */
+
+ ACPI_DEBUG_EXEC (
+ AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL));
+
+ Status = AcpiNsEvaluate (Info);
+ AcpiUtRemoveReference (Args[1]);
+
+Cleanup2:
+ AcpiUtRemoveReference (Args[0]);
+
+Cleanup1:
+ ACPI_FREE (Info);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvExecuteRegMethods
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * SpaceId - The address space ID
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Run all _REG methods for the input Space ID;
+ * Note: assumes namespace is locked, or system init time.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvExecuteRegMethods (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId)
+{
+ ACPI_STATUS Status;
+ ACPI_REG_WALK_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE (EvExecuteRegMethods);
+
+ Info.SpaceId = SpaceId;
+ Info.RegRunCount = 0;
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
+ " Running _REG methods for SpaceId %s\n",
+ AcpiUtGetRegionName (Info.SpaceId)));
+
+ /*
+ * Run all _REG methods for all Operation Regions for this space ID. This
+ * is a separate walk in order to handle any interdependencies between
+ * regions and _REG methods. (i.e. handlers must be installed for all
+ * regions of this Space ID before we can run any _REG methods)
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL);
+
+ /* Special case for EC: handle "orphan" _REG methods with no region */
+
+ if (SpaceId == ACPI_ADR_SPACE_EC)
+ {
+ AcpiEvOrphanEcRegMethod (Node);
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
+ " Executed %u _REG methods for SpaceId %s\n",
+ Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvRegRun
+ *
+ * PARAMETERS: WalkNamespace callback
+ *
+ * DESCRIPTION: Run _REG method for region objects of the requested spaceID
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvRegRun (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_REG_WALK_INFO *Info;
+
+
+ Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context);
+
+ /* Convert and validate the device handle */
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * We only care about regions.and objects that are allowed to have address
+ * space handlers
+ */
+ if ((Node->Type != ACPI_TYPE_REGION) &&
+ (Node != AcpiGbl_RootNode))
+ {
+ return (AE_OK);
+ }
+
+ /* Check for an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /* No object, just exit */
+
+ return (AE_OK);
+ }
+
+ /* Object is a Region */
+
+ if (ObjDesc->Region.SpaceId != Info->SpaceId)
+ {
+ /* This region is for a different address space, just ignore it */
+
+ return (AE_OK);
+ }
+
+ Info->RegRunCount++;
+ Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvOrphanEcRegMethod
+ *
+ * PARAMETERS: EcDeviceNode - Namespace node for an EC device
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
+ * device. This is a _REG method that has no corresponding region
+ * within the EC device scope. The orphan _REG method appears to
+ * have been enabled by the description of the ECDT in the ACPI
+ * specification: "The availability of the region space can be
+ * detected by providing a _REG method object underneath the
+ * Embedded Controller device."
+ *
+ * To quickly access the EC device, we use the EcDeviceNode used
+ * during EC handler installation. Otherwise, we would need to
+ * perform a time consuming namespace walk, executing _HID
+ * methods to find the EC device.
+ *
+ * MUTEX: Assumes the namespace is locked
+ *
+ ******************************************************************************/
+
+static void
+AcpiEvOrphanEcRegMethod (
+ ACPI_NAMESPACE_NODE *EcDeviceNode)
+{
+ ACPI_HANDLE RegMethod;
+ ACPI_NAMESPACE_NODE *NextNode;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_LIST Args;
+ ACPI_OBJECT Objects[2];
+
+
+ ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod);
+
+
+ if (!EcDeviceNode)
+ {
+ return_VOID;
+ }
+
+ /* Namespace is currently locked, must release */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ /* Get a handle to a _REG method immediately under the EC device */
+
+ Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit; /* There is no _REG method present */
+ }
+
+ /*
+ * Execute the _REG method only if there is no Operation Region in
+ * this scope with the Embedded Controller space ID. Otherwise, it
+ * will already have been executed. Note, this allows for Regions
+ * with other space IDs to be present; but the code below will then
+ * execute the _REG method with the EmbeddedControl SpaceID argument.
+ */
+ NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL);
+ while (NextNode)
+ {
+ if ((NextNode->Type == ACPI_TYPE_REGION) &&
+ (NextNode->Object) &&
+ (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC))
+ {
+ goto Exit; /* Do not execute the _REG */
+ }
+
+ NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode);
+ }
+
+ /* Evaluate the _REG(EmbeddedControl,Connect) method */
+
+ Args.Count = 2;
+ Args.Pointer = Objects;
+ Objects[0].Type = ACPI_TYPE_INTEGER;
+ Objects[0].Integer.Value = ACPI_ADR_SPACE_EC;
+ Objects[1].Type = ACPI_TYPE_INTEGER;
+ Objects[1].Integer.Value = ACPI_REG_CONNECT;
+
+ Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
+
+Exit:
+ /* We ignore all errors from above, don't care */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evrgnini.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evrgnini.c
new file mode 100644
index 0000000000..2984e8c924
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evrgnini.c
@@ -0,0 +1,730 @@
+/******************************************************************************
+ *
+ * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evrgnini")
+
+/* Local prototypes */
+
+static BOOLEAN
+AcpiEvIsPciRootBridge (
+ ACPI_NAMESPACE_NODE *Node);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvSystemMemoryRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Setup a SystemMemory operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvSystemMemoryRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_OPERAND_OBJECT *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
+ ACPI_MEM_SPACE_CONTEXT *LocalRegionContext;
+
+
+ ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
+
+
+ if (Function == ACPI_REGION_DEACTIVATE)
+ {
+ if (*RegionContext)
+ {
+ LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
+
+ /* Delete a cached mapping if present */
+
+ if (LocalRegionContext->MappedLength)
+ {
+ AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
+ LocalRegionContext->MappedLength);
+ }
+ ACPI_FREE (LocalRegionContext);
+ *RegionContext = NULL;
+ }
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Create a new context */
+
+ LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
+ if (!(LocalRegionContext))
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Save the region length and address for use in the handler */
+
+ LocalRegionContext->Length = RegionDesc->Region.Length;
+ LocalRegionContext->Address = RegionDesc->Region.Address;
+
+ *RegionContext = LocalRegionContext;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvIoSpaceRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Setup a IO operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvIoSpaceRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
+
+
+ if (Function == ACPI_REGION_DEACTIVATE)
+ {
+ *RegionContext = NULL;
+ }
+ else
+ {
+ *RegionContext = HandlerContext;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvPciConfigRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Setup a PCI_Config operation region
+ *
+ * MUTEX: Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvPciConfigRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT64 PciValue;
+ ACPI_PCI_ID *PciId = *RegionContext;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_NAMESPACE_NODE *PciRootNode;
+ ACPI_NAMESPACE_NODE *PciDeviceNode;
+ ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle;
+
+
+ ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
+
+
+ HandlerObj = RegionObj->Region.Handler;
+ if (!HandlerObj)
+ {
+ /*
+ * No installed handler. This shouldn't happen because the dispatch
+ * routine checks before we get here, but we check again just in case.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Attempting to init a region %p, with no handler\n", RegionObj));
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ *RegionContext = NULL;
+ if (Function == ACPI_REGION_DEACTIVATE)
+ {
+ if (PciId)
+ {
+ ACPI_FREE (PciId);
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ ParentNode = RegionObj->Region.Node->Parent;
+
+ /*
+ * Get the _SEG and _BBN values from the device upon which the handler
+ * is installed.
+ *
+ * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
+ * This is the device the handler has been registered to handle.
+ */
+
+ /*
+ * If the AddressSpace.Node is still pointing to the root, we need
+ * to scan upward for a PCI Root bridge and re-associate the OpRegion
+ * handlers with that device.
+ */
+ if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
+ {
+ /* Start search from the parent object */
+
+ PciRootNode = ParentNode;
+ while (PciRootNode != AcpiGbl_RootNode)
+ {
+ /* Get the _HID/_CID in order to detect a RootBridge */
+
+ if (AcpiEvIsPciRootBridge (PciRootNode))
+ {
+ /* Install a handler for this PCI root bridge */
+
+ Status = AcpiInstallAddressSpaceHandler (
+ (ACPI_HANDLE) PciRootNode,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_SAME_HANDLER)
+ {
+ /*
+ * It is OK if the handler is already installed on the
+ * root bridge. Still need to return a context object
+ * for the new PCI_Config operation region, however.
+ */
+ Status = AE_OK;
+ }
+ else
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not install PciConfig handler "
+ "for Root Bridge %4.4s",
+ AcpiUtGetNodeName (PciRootNode)));
+ }
+ }
+ break;
+ }
+
+ PciRootNode = PciRootNode->Parent;
+ }
+
+ /* PCI root bridge not found, use namespace root node */
+ }
+ else
+ {
+ PciRootNode = HandlerObj->AddressSpace.Node;
+ }
+
+ /*
+ * If this region is now initialized, we are done.
+ * (InstallAddressSpaceHandler could have initialized it)
+ */
+ if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Region is still not initialized. Create a new context */
+
+ PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
+ if (!PciId)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * For PCI_Config space access, we need the segment, bus, device and
+ * function numbers. Acquire them here.
+ *
+ * Find the parent device object. (This allows the operation region to be
+ * within a subscope under the device, such as a control method.)
+ */
+ PciDeviceNode = RegionObj->Region.Node;
+ while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
+ {
+ PciDeviceNode = PciDeviceNode->Parent;
+ }
+
+ if (!PciDeviceNode)
+ {
+ ACPI_FREE (PciId);
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * Get the PCI device and function numbers from the _ADR object
+ * contained in the parent's scope.
+ */
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
+ PciDeviceNode, &PciValue);
+
+ /*
+ * The default is zero, and since the allocation above zeroed the data,
+ * just do nothing on failure.
+ */
+ if (ACPI_SUCCESS (Status))
+ {
+ PciId->Device = ACPI_HIWORD (ACPI_LODWORD (PciValue));
+ PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
+ }
+
+ /* The PCI segment number comes from the _SEG method */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
+ PciRootNode, &PciValue);
+ if (ACPI_SUCCESS (Status))
+ {
+ PciId->Segment = ACPI_LOWORD (PciValue);
+ }
+
+ /* The PCI bus number comes from the _BBN method */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
+ PciRootNode, &PciValue);
+ if (ACPI_SUCCESS (Status))
+ {
+ PciId->Bus = ACPI_LOWORD (PciValue);
+ }
+
+ /* Complete/update the PCI ID for this device */
+
+ Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (PciId);
+ return_ACPI_STATUS (Status);
+ }
+
+ *RegionContext = PciId;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvIsPciRootBridge
+ *
+ * PARAMETERS: Node - Device node being examined
+ *
+ * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
+ *
+ * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
+ * examining the _HID and _CID for the device.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiEvIsPciRootBridge (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_STATUS Status;
+ ACPI_PNP_DEVICE_ID *Hid;
+ ACPI_PNP_DEVICE_ID_LIST *Cid;
+ UINT32 i;
+ BOOLEAN Match;
+
+
+ /* Get the _HID and check for a PCI Root Bridge */
+
+ Status = AcpiUtExecute_HID (Node, &Hid);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+
+ Match = AcpiUtIsPciRootBridge (Hid->String);
+ ACPI_FREE (Hid);
+
+ if (Match)
+ {
+ return (TRUE);
+ }
+
+ /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
+
+ Status = AcpiUtExecute_CID (Node, &Cid);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+
+ /* Check all _CIDs in the returned list */
+
+ for (i = 0; i < Cid->Count; i++)
+ {
+ if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
+ {
+ ACPI_FREE (Cid);
+ return (TRUE);
+ }
+ }
+
+ ACPI_FREE (Cid);
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvPciBarRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Setup a PciBAR operation region
+ *
+ * MUTEX: Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvPciBarRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
+
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvCmosRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Setup a CMOS operation region
+ *
+ * MUTEX: Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvCmosRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
+
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvDefaultRegionSetup
+ *
+ * PARAMETERS: Handle - Region we are interested in
+ * Function - Start or stop
+ * HandlerContext - Address space handler context
+ * RegionContext - Region specific context
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Default region initialization
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDefaultRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext)
+{
+ ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
+
+
+ if (Function == ACPI_REGION_DEACTIVATE)
+ {
+ *RegionContext = NULL;
+ }
+ else
+ {
+ *RegionContext = HandlerContext;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInitializeRegion
+ *
+ * PARAMETERS: RegionObj - Region we are initializing
+ * AcpiNsLocked - Is namespace locked?
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
+ * for execution at a later time
+ *
+ * Get the appropriate address space handler for a newly
+ * created region.
+ *
+ * This also performs address space specific initialization. For
+ * example, PCI regions must have an _ADR object that contains
+ * a PCI address in the scope of the definition. This address is
+ * required to perform an access to PCI config space.
+ *
+ * MUTEX: Interpreter should be unlocked, because we may run the _REG
+ * method for this region.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitializeRegion (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsLocked)
+{
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_ADR_SPACE_TYPE SpaceId;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *MethodNode;
+ ACPI_NAME *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
+ ACPI_OPERAND_OBJECT *RegionObj2;
+
+
+ ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
+
+
+ if (!RegionObj)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
+ if (!RegionObj2)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ Node = RegionObj->Region.Node->Parent;
+ SpaceId = RegionObj->Region.SpaceId;
+
+ /* Setup defaults */
+
+ RegionObj->Region.Handler = NULL;
+ RegionObj2->Extra.Method_REG = NULL;
+ RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
+ RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
+
+ /* Find any "_REG" method associated with this region definition */
+
+ Status = AcpiNsSearchOneScope (
+ *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * The _REG method is optional and there can be only one per region
+ * definition. This will be executed when the handler is attached
+ * or removed
+ */
+ RegionObj2->Extra.Method_REG = MethodNode;
+ }
+
+ /*
+ * The following loop depends upon the root Node having no parent
+ * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
+ */
+ while (Node)
+ {
+ /* Check to see if a handler exists */
+
+ HandlerObj = NULL;
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ /* Can only be a handler if the object exists */
+
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_DEVICE:
+
+ HandlerObj = ObjDesc->Device.Handler;
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ HandlerObj = ObjDesc->Processor.Handler;
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ HandlerObj = ObjDesc->ThermalZone.Handler;
+ break;
+
+ case ACPI_TYPE_METHOD:
+ /*
+ * If we are executing module level code, the original
+ * Node's object was replaced by this Method object and we
+ * saved the handler in the method object.
+ *
+ * See AcpiNsExecModuleCode
+ */
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
+ {
+ HandlerObj = ObjDesc->Method.Dispatch.Handler;
+ }
+ break;
+
+ default:
+
+ /* Ignore other objects */
+
+ break;
+ }
+
+ while (HandlerObj)
+ {
+ /* Is this handler of the correct type? */
+
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
+ {
+ /* Found correct handler */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Found handler %p for region %p in obj %p\n",
+ HandlerObj, RegionObj, ObjDesc));
+
+ Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
+ AcpiNsLocked);
+
+ /*
+ * Tell all users that this region is usable by
+ * running the _REG method
+ */
+ if (AcpiNsLocked)
+ {
+ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
+
+ if (AcpiNsLocked)
+ {
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Try next handler in the list */
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+
+ /* This node does not have the handler we need; Pop up one level */
+
+ Node = Node->Parent;
+ }
+
+ /* If we get here, there is no handler for this region */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "No handler for RegionType %s(%X) (RegionObj %p)\n",
+ AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
+
+ return_ACPI_STATUS (AE_NOT_EXIST);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evsci.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evsci.c
new file mode 100644
index 0000000000..70920a52bb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evsci.c
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ *
+ * Module Name: evsci - System Control Interrupt configuration and
+ * legacy to ACPI mode state transition functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evsci")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static UINT32 ACPI_SYSTEM_XFACE
+AcpiEvSciXruptHandler (
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvSciDispatch
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status code indicates whether interrupt was handled.
+ *
+ * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiEvSciDispatch (
+ void)
+{
+ ACPI_SCI_HANDLER_INFO *SciHandler;
+ ACPI_CPU_FLAGS Flags;
+ UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
+
+
+ ACPI_FUNCTION_NAME (EvSciDispatch);
+
+
+ /* Are there any host-installed SCI handlers? */
+
+ if (!AcpiGbl_SciHandlerList)
+ {
+ return (IntStatus);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Invoke all host-installed SCI handlers */
+
+ SciHandler = AcpiGbl_SciHandlerList;
+ while (SciHandler)
+ {
+ /* Invoke the installed handler (at interrupt level) */
+
+ IntStatus |= SciHandler->Address (
+ SciHandler->Context);
+
+ SciHandler = SciHandler->Next;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return (IntStatus);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvSciXruptHandler
+ *
+ * PARAMETERS: Context - Calling Context
+ *
+ * RETURN: Status code indicates whether interrupt was handled.
+ *
+ * DESCRIPTION: Interrupt handler that will figure out what function or
+ * control method to call to deal with a SCI.
+ *
+ ******************************************************************************/
+
+static UINT32 ACPI_SYSTEM_XFACE
+AcpiEvSciXruptHandler (
+ void *Context)
+{
+ ACPI_GPE_XRUPT_INFO *GpeXruptList = Context;
+ UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED;
+
+
+ ACPI_FUNCTION_TRACE (EvSciXruptHandler);
+
+
+ /*
+ * We are guaranteed by the ACPICA initialization/shutdown code that
+ * if this interrupt handler is installed, ACPI is enabled.
+ */
+
+ /*
+ * Fixed Events:
+ * Check for and dispatch any Fixed Events that have occurred
+ */
+ InterruptHandled |= AcpiEvFixedEventDetect ();
+
+ /*
+ * General Purpose Events:
+ * Check for and dispatch any GPEs that have occurred
+ */
+ InterruptHandled |= AcpiEvGpeDetect (GpeXruptList);
+
+ /* Invoke all host-installed SCI handlers */
+
+ InterruptHandled |= AcpiEvSciDispatch ();
+
+ AcpiSciCount++;
+ return_UINT32 (InterruptHandled);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvGpeXruptHandler
+ *
+ * PARAMETERS: Context - Calling Context
+ *
+ * RETURN: Status code indicates whether interrupt was handled.
+ *
+ * DESCRIPTION: Handler for GPE Block Device interrupts
+ *
+ ******************************************************************************/
+
+UINT32 ACPI_SYSTEM_XFACE
+AcpiEvGpeXruptHandler (
+ void *Context)
+{
+ ACPI_GPE_XRUPT_INFO *GpeXruptList = Context;
+ UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED;
+
+
+ ACPI_FUNCTION_TRACE (EvGpeXruptHandler);
+
+
+ /*
+ * We are guaranteed by the ACPICA initialization/shutdown code that
+ * if this interrupt handler is installed, ACPI is enabled.
+ */
+
+ /* GPEs: Check for and dispatch any GPEs that have occurred */
+
+ InterruptHandled |= AcpiEvGpeDetect (GpeXruptList);
+ return_UINT32 (InterruptHandled);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallSciHandler
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Installs SCI handler.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiEvInstallSciHandler (
+ void)
+{
+ UINT32 Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallSciHandler);
+
+
+ Status = AcpiOsInstallInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt,
+ AcpiEvSciXruptHandler, AcpiGbl_GpeXruptListHead);
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEvRemoveAllSciHandlers
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not
+ * installed to begin with
+ *
+ * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be
+ * taken. Remove all host-installed SCI handlers.
+ *
+ * Note: It doesn't seem important to disable all events or set the event
+ * enable registers to their original values. The OS should disable
+ * the SCI interrupt level when the handler is removed, so no more
+ * events will come in.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvRemoveAllSciHandlers (
+ void)
+{
+ ACPI_SCI_HANDLER_INFO *SciHandler;
+ ACPI_CPU_FLAGS Flags;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (EvRemoveAllSciHandlers);
+
+
+ /* Just let the OS remove the handler and disable the level */
+
+ Status = AcpiOsRemoveInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt,
+ AcpiEvSciXruptHandler);
+
+ if (!AcpiGbl_SciHandlerList)
+ {
+ return (Status);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Free all host-installed SCI handlers */
+
+ while (AcpiGbl_SciHandlerList)
+ {
+ SciHandler = AcpiGbl_SciHandlerList;
+ AcpiGbl_SciHandlerList = SciHandler->Next;
+ ACPI_FREE (SciHandler);
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxface.c
new file mode 100644
index 0000000000..6a4b254764
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxface.c
@@ -0,0 +1,1259 @@
+/******************************************************************************
+ *
+ * Module Name: evxface - External interfaces for ACPI events
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evxface")
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiEvInstallGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ BOOLEAN IsRawHandler,
+ ACPI_GPE_HANDLER Address,
+ void *Context);
+
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallNotifyHandler
+ *
+ * PARAMETERS: Device - The device for which notifies will be handled
+ * HandlerType - The type of handler:
+ * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
+ * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
+ * ACPI_ALL_NOTIFY: Both System and Device
+ * Handler - Address of the handler
+ * Context - Value passed to the handler on each GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for notifications on an ACPI Device,
+ * ThermalZone, or Processor object.
+ *
+ * NOTES: The Root namespace object may have only one handler for each
+ * type of notify (System/Device). Device/Thermal/Processor objects
+ * may have one device notify handler, and multiple system notify
+ * handlers.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallNotifyHandler (
+ ACPI_HANDLE Device,
+ UINT32 HandlerType,
+ ACPI_NOTIFY_HANDLER Handler,
+ void *Context)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
+
+
+ /* Parameter validation */
+
+ if ((!Device) || (!Handler) || (!HandlerType) ||
+ (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Root Object:
+ * Registering a notify handler on the root object indicates that the
+ * caller wishes to receive notifications for all objects. Note that
+ * only one global handler can be registered per notify type.
+ * Ensure that a handler is not already installed.
+ */
+ if (Device == ACPI_ROOT_OBJECT)
+ {
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ if (AcpiGbl_GlobalNotify[i].Handler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+
+ AcpiGbl_GlobalNotify[i].Handler = Handler;
+ AcpiGbl_GlobalNotify[i].Context = Context;
+ }
+ }
+
+ goto UnlockAndExit; /* Global notify handler installed, all done */
+ }
+
+ /*
+ * All Other Objects:
+ * Caller will only receive notifications specific to the target
+ * object. Note that only certain object types are allowed to
+ * receive notifications.
+ */
+
+ /* Are Notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ /* Check for an existing internal object, might not exist */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /* Create a new object */
+
+ ObjDesc = AcpiUtCreateInternalObject (Node->Type);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /* Attach new object to the Node, remove local reference */
+
+ Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
+ AcpiUtRemoveReference (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+
+ /* Ensure that the handler is not already installed in the lists */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
+ while (HandlerObj)
+ {
+ if (HandlerObj->Notify.Handler == Handler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+
+ HandlerObj = HandlerObj->Notify.Next[i];
+ }
+ }
+ }
+
+ /* Create and populate a new notify handler object */
+
+ HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
+ if (!HandlerObj)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ HandlerObj->Notify.Node = Node;
+ HandlerObj->Notify.HandlerType = HandlerType;
+ HandlerObj->Notify.Handler = Handler;
+ HandlerObj->Notify.Context = Context;
+
+ /* Install the handler at the list head(s) */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ HandlerObj->Notify.Next[i] =
+ ObjDesc->CommonNotify.NotifyList[i];
+
+ ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
+ }
+ }
+
+ /* Add an extra reference if handler was installed in both lists */
+
+ if (HandlerType == ACPI_ALL_NOTIFY)
+ {
+ AcpiUtAddReference (HandlerObj);
+ }
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveNotifyHandler
+ *
+ * PARAMETERS: Device - The device for which the handler is installed
+ * HandlerType - The type of handler:
+ * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
+ * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
+ * ACPI_ALL_NOTIFY: Both System and Device
+ * Handler - Address of the handler
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a handler for notifies on an ACPI device
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveNotifyHandler (
+ ACPI_HANDLE Device,
+ UINT32 HandlerType,
+ ACPI_NOTIFY_HANDLER Handler)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *PreviousHandlerObj;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
+
+
+ /* Parameter validation */
+
+ if ((!Device) || (!Handler) || (!HandlerType) ||
+ (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Root Object. Global handlers are removed here */
+
+ if (Device == ACPI_ROOT_OBJECT)
+ {
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!AcpiGbl_GlobalNotify[i].Handler ||
+ (AcpiGbl_GlobalNotify[i].Handler != Handler))
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Removing global notify handler\n"));
+
+ AcpiGbl_GlobalNotify[i].Handler = NULL;
+ AcpiGbl_GlobalNotify[i].Context = NULL;
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ /* Make sure all deferred notify tasks are completed */
+
+ AcpiOsWaitEventsComplete ();
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* All other objects: Are Notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
+ {
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Must have an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Internal object exists. Find the handler and remove it */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
+ PreviousHandlerObj = NULL;
+
+ /* Attempt to find the handler in the handler list */
+
+ while (HandlerObj &&
+ (HandlerObj->Notify.Handler != Handler))
+ {
+ PreviousHandlerObj = HandlerObj;
+ HandlerObj = HandlerObj->Notify.Next[i];
+ }
+
+ if (!HandlerObj)
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ /* Remove the handler object from the list */
+
+ if (PreviousHandlerObj) /* Handler is not at the list head */
+ {
+ PreviousHandlerObj->Notify.Next[i] =
+ HandlerObj->Notify.Next[i];
+ }
+ else /* Handler is at the list head */
+ {
+ ObjDesc->CommonNotify.NotifyList[i] =
+ HandlerObj->Notify.Next[i];
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ /* Make sure all deferred notify tasks are completed */
+
+ AcpiOsWaitEventsComplete ();
+ AcpiUtRemoveReference (HandlerObj);
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallExceptionHandler
+ *
+ * PARAMETERS: Handler - Pointer to the handler function for the
+ * event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallExceptionHandler (
+ ACPI_EXCEPTION_HANDLER Handler)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Don't allow two handlers. */
+
+ if (AcpiGbl_ExceptionHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ /* Install the handler */
+
+ AcpiGbl_ExceptionHandler = Handler;
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallSciHandler
+ *
+ * PARAMETERS: Address - Address of the handler
+ * Context - Value passed to the handler on each SCI
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for a System Control Interrupt.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallSciHandler (
+ ACPI_SCI_HANDLER Address,
+ void *Context)
+{
+ ACPI_SCI_HANDLER_INFO *NewSciHandler;
+ ACPI_SCI_HANDLER_INFO *SciHandler;
+ ACPI_CPU_FLAGS Flags;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
+
+
+ if (!Address)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Allocate and init a handler object */
+
+ NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
+ if (!NewSciHandler)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ NewSciHandler->Address = Address;
+ NewSciHandler->Context = Context;
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Lock list during installation */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ SciHandler = AcpiGbl_SciHandlerList;
+
+ /* Ensure handler does not already exist */
+
+ while (SciHandler)
+ {
+ if (Address == SciHandler->Address)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+
+ SciHandler = SciHandler->Next;
+ }
+
+ /* Install the new handler into the global list (at head) */
+
+ NewSciHandler->Next = AcpiGbl_SciHandlerList;
+ AcpiGbl_SciHandlerList = NewSciHandler;
+
+
+UnlockAndExit:
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+Exit:
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (NewSciHandler);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveSciHandler
+ *
+ * PARAMETERS: Address - Address of the handler
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a handler for a System Control Interrupt.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveSciHandler (
+ ACPI_SCI_HANDLER Address)
+{
+ ACPI_SCI_HANDLER_INFO *PrevSciHandler;
+ ACPI_SCI_HANDLER_INFO *NextSciHandler;
+ ACPI_CPU_FLAGS Flags;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
+
+
+ if (!Address)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Remove the SCI handler with lock */
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ PrevSciHandler = NULL;
+ NextSciHandler = AcpiGbl_SciHandlerList;
+ while (NextSciHandler)
+ {
+ if (NextSciHandler->Address == Address)
+ {
+ /* Unlink and free the SCI handler info block */
+
+ if (PrevSciHandler)
+ {
+ PrevSciHandler->Next = NextSciHandler->Next;
+ }
+ else
+ {
+ AcpiGbl_SciHandlerList = NextSciHandler->Next;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ ACPI_FREE (NextSciHandler);
+ goto UnlockAndExit;
+ }
+
+ PrevSciHandler = NextSciHandler;
+ NextSciHandler = NextSciHandler->Next;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ Status = AE_NOT_EXIST;
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallGlobalEventHandler
+ *
+ * PARAMETERS: Handler - Pointer to the global event handler function
+ * Context - Value passed to the handler on each event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function. The global handler
+ * is invoked upon each incoming GPE and Fixed Event. It is
+ * invoked at interrupt level at the time of the event dispatch.
+ * Can be used to update event counters, etc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGlobalEventHandler (
+ ACPI_GBL_EVENT_HANDLER Handler,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
+
+
+ /* Parameter validation */
+
+ if (!Handler)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Don't allow two handlers. */
+
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ AcpiGbl_GlobalEventHandler = Handler;
+ AcpiGbl_GlobalEventHandlerContext = Context;
+
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallFixedEventHandler
+ *
+ * PARAMETERS: Event - Event type to enable.
+ * Handler - Pointer to the handler function for the
+ * event
+ * Context - Value passed to the handler on each GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function and then enables the
+ * event.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallFixedEventHandler (
+ UINT32 Event,
+ ACPI_EVENT_HANDLER Handler,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
+
+
+ /* Parameter validation */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Do not allow multiple handlers */
+
+ if (AcpiGbl_FixedEventHandlers[Event].Handler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ /* Install the handler before enabling the event */
+
+ AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
+ AcpiGbl_FixedEventHandlers[Event].Context = Context;
+
+ Status = AcpiEnableEvent (Event, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Could not enable fixed event - %s (%u)",
+ AcpiUtGetEventName (Event), Event));
+
+ /* Remove the handler */
+
+ AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
+ AcpiGbl_FixedEventHandlers[Event].Context = NULL;
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Enabled fixed event %s (%X), Handler=%p\n",
+ AcpiUtGetEventName (Event), Event, Handler));
+ }
+
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveFixedEventHandler
+ *
+ * PARAMETERS: Event - Event type to disable.
+ * Handler - Address of the handler
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disables the event and unregisters the event handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveFixedEventHandler (
+ UINT32 Event,
+ ACPI_EVENT_HANDLER Handler)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
+
+
+ /* Parameter validation */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Disable the event before removing the handler */
+
+ Status = AcpiDisableEvent (Event, 0);
+
+ /* Always Remove the handler */
+
+ AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
+ AcpiGbl_FixedEventHandlers[Event].Context = NULL;
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Could not disable fixed event - %s (%u)",
+ AcpiUtGetEventName (Event), Event));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Disabled fixed event - %s (%X)\n",
+ AcpiUtGetEventName (Event), Event));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallGpeHandler
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * GpeNumber - The GPE number within the GPE block
+ * Type - Whether this GPE should be treated as an
+ * edge- or level-triggered interrupt.
+ * IsRawHandler - Whether this GPE should be handled using
+ * the special GPE handler mode.
+ * Address - Address of the handler
+ * Context - Value passed to the handler on each GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Internal function to install a handler for a General Purpose
+ * Event.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiEvInstallGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ BOOLEAN IsRawHandler,
+ ACPI_GPE_HANDLER Address,
+ void *Context)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_HANDLER_INFO *Handler;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
+
+
+ /* Parameter validation */
+
+ if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Allocate and init handler object (before lock) */
+
+ Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
+ if (!Handler)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto FreeAndExit;
+ }
+
+ /* Make sure that there isn't a handler there already */
+
+ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_HANDLER) ||
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_RAW_HANDLER))
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto FreeAndExit;
+ }
+
+ Handler->Address = Address;
+ Handler->Context = Context;
+ Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
+ Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
+ (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
+
+ /*
+ * If the GPE is associated with a method, it may have been enabled
+ * automatically during initialization, in which case it has to be
+ * disabled now to avoid spurious execution of the handler.
+ */
+ if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
+ ACPI_GPE_DISPATCH_METHOD) ||
+ (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
+ ACPI_GPE_DISPATCH_NOTIFY)) &&
+ GpeEventInfo->RuntimeCount)
+ {
+ Handler->OriginallyEnabled = TRUE;
+ (void) AcpiEvRemoveGpeReference (GpeEventInfo);
+
+ /* Sanity check of original type against new type */
+
+ if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
+ {
+ ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
+ }
+ }
+
+ /* Install the handler */
+
+ GpeEventInfo->Dispatch.Handler = Handler;
+
+ /* Setup up dispatch flags to indicate handler (vs. method/notify) */
+
+ GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
+ GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
+ ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+
+FreeAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ ACPI_FREE (Handler);
+ goto UnlockAndExit;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallGpeHandler
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * GpeNumber - The GPE number within the GPE block
+ * Type - Whether this GPE should be treated as an
+ * edge- or level-triggered interrupt.
+ * Address - Address of the handler
+ * Context - Value passed to the handler on each GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for a General Purpose Event.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ ACPI_GPE_HANDLER Address,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
+
+
+ Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, FALSE,
+ Address, Context);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallGpeRawHandler
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * GpeNumber - The GPE number within the GPE block
+ * Type - Whether this GPE should be treated as an
+ * edge- or level-triggered interrupt.
+ * Address - Address of the handler
+ * Context - Value passed to the handler on each GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for a General Purpose Event.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGpeRawHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ ACPI_GPE_HANDLER Address,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler);
+
+
+ Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, TRUE,
+ Address, Context);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveGpeHandler
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * GpeNumber - The event to remove a handler
+ * Address - Address of the handler
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_GPE_HANDLER Address)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_HANDLER_INFO *Handler;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
+
+
+ /* Parameter validation */
+
+ if (!Address)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Make sure that a handler is indeed installed */
+
+ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
+ ACPI_GPE_DISPATCH_HANDLER) &&
+ (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
+ ACPI_GPE_DISPATCH_RAW_HANDLER))
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ /* Make sure that the installed handler is the same */
+
+ if (GpeEventInfo->Dispatch.Handler->Address != Address)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Remove the handler */
+
+ Handler = GpeEventInfo->Dispatch.Handler;
+ GpeEventInfo->Dispatch.Handler = NULL;
+
+ /* Restore Method node (if any), set dispatch flags */
+
+ GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
+ GpeEventInfo->Flags &=
+ ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
+ GpeEventInfo->Flags |= Handler->OriginalFlags;
+
+ /*
+ * If the GPE was previously associated with a method and it was
+ * enabled, it should be enabled at this point to restore the
+ * post-initialization configuration.
+ */
+ if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
+ ACPI_GPE_DISPATCH_METHOD) ||
+ (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
+ ACPI_GPE_DISPATCH_NOTIFY)) &&
+ Handler->OriginallyEnabled)
+ {
+ (void) AcpiEvAddGpeReference (GpeEventInfo);
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ /* Make sure all deferred GPE tasks are completed */
+
+ AcpiOsWaitEventsComplete ();
+
+ /* Now we can free the handler object */
+
+ ACPI_FREE (Handler);
+ return_ACPI_STATUS (Status);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAcquireGlobalLock
+ *
+ * PARAMETERS: Timeout - How long the caller is willing to wait
+ * Handle - Where the handle to the lock is returned
+ * (if acquired)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire the ACPI Global Lock
+ *
+ * Note: Allows callers with the same thread ID to acquire the global lock
+ * multiple times. In other words, externally, the behavior of the global lock
+ * is identical to an AML mutex. On the first acquire, a new handle is
+ * returned. On any subsequent calls to acquire by the same thread, the same
+ * handle is returned.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiAcquireGlobalLock (
+ UINT16 Timeout,
+ UINT32 *Handle)
+{
+ ACPI_STATUS Status;
+
+
+ if (!Handle)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Must lock interpreter to prevent race conditions */
+
+ AcpiExEnterInterpreter ();
+
+ Status = AcpiExAcquireMutexObject (Timeout,
+ AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
+
+ *Handle = AcpiGbl_GlobalLockHandle;
+ }
+
+ AcpiExExitInterpreter ();
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiReleaseGlobalLock
+ *
+ * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReleaseGlobalLock (
+ UINT32 Handle)
+{
+ ACPI_STATUS Status;
+
+
+ if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
+ {
+ return (AE_NOT_ACQUIRED);
+ }
+
+ Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfevnt.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfevnt.c
new file mode 100644
index 0000000000..5515922f75
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfevnt.c
@@ -0,0 +1,428 @@
+/******************************************************************************
+ *
+ * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evxfevnt")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transfers the system into ACPI mode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnable (
+ void)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnable);
+
+
+ /* ACPI tables must be present */
+
+ if (!AcpiTbTablesLoaded ())
+ {
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ }
+
+ /* If the Hardware Reduced flag is set, machine is always in acpi mode */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Check current mode */
+
+ if (AcpiHwGetMode() == ACPI_SYS_MODE_ACPI)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
+ }
+ else
+ {
+ /* Transition to ACPI mode */
+
+ Status = AcpiHwSetMode (ACPI_SYS_MODE_ACPI);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not transition to ACPI mode"));
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Transition to ACPI mode successful\n"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDisable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisable (
+ void)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisable);
+
+
+ /* If the Hardware Reduced flag is set, machine is always in acpi mode */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (AcpiHwGetMode() == ACPI_SYS_MODE_LEGACY)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "System is already in legacy (non-ACPI) mode\n"));
+ }
+ else
+ {
+ /* Transition to LEGACY mode */
+
+ Status = AcpiHwSetMode (ACPI_SYS_MODE_LEGACY);
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not exit ACPI mode to legacy mode"));
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnableEvent
+ *
+ * PARAMETERS: Event - The fixed eventto be enabled
+ * Flags - Reserved
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableEvent (
+ UINT32 Event,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Value;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableEvent);
+
+
+ /* Decode the Fixed Event */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Enable the requested fixed event (by writing a one to the enable
+ * register bit)
+ */
+ Status = AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
+ ACPI_ENABLE_EVENT);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Make sure that the hardware responded */
+
+ Status = AcpiReadBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (Value != 1)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not enable %s event", AcpiUtGetEventName (Event)));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDisableEvent
+ *
+ * PARAMETERS: Event - The fixed event to be disabled
+ * Flags - Reserved
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableEvent (
+ UINT32 Event,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Value;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisableEvent);
+
+
+ /* Decode the Fixed Event */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Disable the requested fixed event (by writing a zero to the enable
+ * register bit)
+ */
+ Status = AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
+ ACPI_DISABLE_EVENT);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiReadBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (Value != 0)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not disable %s events", AcpiUtGetEventName (Event)));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisableEvent)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiClearEvent
+ *
+ * PARAMETERS: Event - The fixed event to be cleared
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiClearEvent (
+ UINT32 Event)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiClearEvent);
+
+
+ /* Decode the Fixed Event */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Clear the requested fixed event (By writing a one to the status
+ * register bit)
+ */
+ Status = AcpiWriteBitRegister (
+ AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
+ ACPI_CLEAR_STATUS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiClearEvent)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetEventStatus
+ *
+ * PARAMETERS: Event - The fixed event
+ * EventStatus - Where the current status of the event will
+ * be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtains and returns the current status of the event
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetEventStatus (
+ UINT32 Event,
+ ACPI_EVENT_STATUS *EventStatus)
+{
+ ACPI_STATUS Status;
+ ACPI_EVENT_STATUS LocalEventStatus = 0;
+ UINT32 InByte;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetEventStatus);
+
+
+ if (!EventStatus)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Decode the Fixed Event */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Fixed event currently can be dispatched? */
+
+ if (AcpiGbl_FixedEventHandlers[Event].Handler)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_HAS_HANDLER;
+ }
+
+ /* Fixed event currently enabled? */
+
+ Status = AcpiReadBitRegister (
+ AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &InByte);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (InByte)
+ {
+ LocalEventStatus |=
+ (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET);
+ }
+
+ /* Fixed event currently active? */
+
+ Status = AcpiReadBitRegister (
+ AcpiGbl_FixedEventInfo[Event].StatusRegisterId, &InByte);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (InByte)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_STATUS_SET;
+ }
+
+ (*EventStatus) = LocalEventStatus;
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfgpe.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfgpe.c
new file mode 100644
index 0000000000..f09d56a4ae
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfgpe.c
@@ -0,0 +1,1101 @@
+/******************************************************************************
+ *
+ * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evxfgpe")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUpdateAllGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
+ * associated _Lxx or _Exx methods and are not pointed to by any
+ * device _PRW methods (this indicates that these GPEs are
+ * generally intended for system or device wakeup. Such GPEs
+ * have to be enabled directly when the devices whose _PRW
+ * methods point to them are set up for wakeup signaling.)
+ *
+ * NOTE: Should be called after any GPEs are added to the system. Primarily,
+ * after the system _PRW methods have been run, but also after a GPE Block
+ * Device has been added or if any new GPE methods have been added via a
+ * dynamic table load.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUpdateAllGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (AcpiGbl_AllGpesInitialized)
+ {
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiGbl_AllGpesInitialized = TRUE;
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnableGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /*
+ * Ensure that we have a valid GPE number and that there is some way
+ * of handling the GPE (handler or a GPE method). In other words, we
+ * won't allow a valid GPE to be enabled if there is no way to handle it.
+ */
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ Status = AcpiEvAddGpeReference (GpeEventInfo);
+ }
+ else
+ {
+ Status = AE_NO_HANDLER;
+ }
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDisableGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, only then is the GPE disabled (for runtime GPEs), or
+ * the GPE mask bit disabled (for wake GPEs)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisableGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ Status = AcpiEvRemoveGpeReference (GpeEventInfo);
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
+ * the reference count mechanism used in the AcpiEnableGpe(),
+ * AcpiDisableGpe() interfaces.
+ * This API is typically used by the GPE raw handler mode driver
+ * to switch between the polling mode and the interrupt mode after
+ * the driver has enabled the GPE.
+ * The APIs should be invoked in this order:
+ * AcpiEnableGpe() <- Ensure the reference count > 0
+ * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
+ * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode
+ * AcpiDisableGpe() <- Decrease the reference count
+ *
+ * Note: If a GPE is shared by 2 silicon components, then both the drivers
+ * should support GPE polling mode or disabling the GPE for long period
+ * for one driver may break the other. So use it with care since all
+ * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Perform the action */
+
+ switch (Action)
+ {
+ case ACPI_GPE_ENABLE:
+
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
+ break;
+
+ case ACPI_GPE_DISABLE:
+
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+ break;
+
+ default:
+
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiMarkGpeForWake
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
+ * sets the ACPI_GPE_CAN_WAKE flag.
+ *
+ * Some potential callers of AcpiSetupGpeForWake may know in advance that
+ * there won't be any notify handlers installed for device wake notifications
+ * from the given GPE (one example is a button GPE in Linux). For these cases,
+ * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
+ * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
+ * setup implicit wake notification for it (since there's no handler method).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiMarkGpeForWake (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ /* Mark the GPE as a possible wake event */
+
+ GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
+ Status = AE_OK;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetupGpeForWake
+ *
+ * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
+ * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
+ * interface is intended to be used as the host executes the
+ * _PRW methods (Power Resources for Wake) in the system tables.
+ * Each _PRW appears under a Device Object (The WakeDevice), and
+ * contains the info for the wake GPE associated with the
+ * WakeDevice.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetupGpeForWake (
+ ACPI_HANDLE WakeDevice,
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_NAMESPACE_NODE *DeviceNode;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ ACPI_GPE_NOTIFY_INFO *NewNotify;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
+
+
+ /* Parameter Validation */
+
+ if (!WakeDevice)
+ {
+ /*
+ * By forcing WakeDevice to be valid, we automatically enable the
+ * implicit notify feature on all hosts.
+ */
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Handle root object case */
+
+ if (WakeDevice == ACPI_ROOT_OBJECT)
+ {
+ DeviceNode = AcpiGbl_RootNode;
+ }
+ else
+ {
+ DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
+ }
+
+ /* Validate WakeDevice is of type Device */
+
+ if (DeviceNode->Type != ACPI_TYPE_DEVICE)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Allocate a new notify object up front, in case it is needed.
+ * Memory allocation while holding a spinlock is a big no-no
+ * on some hosts.
+ */
+ NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
+ if (!NewNotify)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * If there is no method or handler for this GPE, then the
+ * WakeDevice will be notified whenever this GPE fires. This is
+ * known as an "implicit notify". Note: The GPE is assumed to be
+ * level-triggered (for windows compatibility).
+ */
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ /*
+ * This is the first device for implicit notify on this GPE.
+ * Just set the flags here, and enter the NOTIFY block below.
+ */
+ GpeEventInfo->Flags =
+ (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
+ }
+
+ /*
+ * If we already have an implicit notify on this GPE, add
+ * this device to the notify list.
+ */
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
+ ACPI_GPE_DISPATCH_NOTIFY)
+ {
+ /* Ensure that the device is not already in the list */
+
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
+ {
+ if (Notify->DeviceNode == DeviceNode)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+ Notify = Notify->Next;
+ }
+
+ /* Add this device to the notify list for this GPE */
+
+ NewNotify->DeviceNode = DeviceNode;
+ NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
+ GpeEventInfo->Dispatch.NotifyList = NewNotify;
+ NewNotify = NULL;
+ }
+
+ /* Mark the GPE as a possible wake event */
+
+ GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
+ Status = AE_OK;
+
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ /* Delete the notify object if it was not used above */
+
+ if (NewNotify)
+ {
+ ACPI_FREE (NewNotify);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetGpeWakeMask
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * Action - Enable or Disable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
+ * already be marked as a WAKE GPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetGpeWakeMask (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_CPU_FLAGS Flags;
+ UINT32 RegisterBit;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /*
+ * Ensure that we have a valid GPE number and that this GPE is in
+ * fact a wake GPE
+ */
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+ if (!GpeRegisterInfo)
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
+
+ /* Perform the action */
+
+ switch (Action)
+ {
+ case ACPI_GPE_ENABLE:
+
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
+ break;
+
+ case ACPI_GPE_DISABLE:
+
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiClearGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiClearGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiClearGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiHwClearGpe (GpeEventInfo);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiClearGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetGpeStatus
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * EventStatus - Where the current status of the event
+ * will be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetGpeStatus (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_EVENT_STATUS *EventStatus)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Obtain status on the requested GPE number */
+
+ Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiFinishGpe
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE Block
+ * (NULL for FADT defined GPEs)
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
+ * processing. Intended for use by asynchronous host-installed
+ * GPE handlers. The GPE is only reenabled if the EnableForRun bit
+ * is set in the GPE info.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiFinishGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiFinishGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiEvFinishGpe (GpeEventInfo);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDisableAllGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableAllGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwDisableAllGpes ();
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEnableAllRuntimeGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableAllRuntimeGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwEnableAllRuntimeGpes ();
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEnableAllWakeupGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
+ * all GPE blocks.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableAllWakeupGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwEnableAllWakeupGpes ();
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallGpeBlock
+ *
+ * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
+ * GpeBlockAddress - Address and SpaceID
+ * RegisterCount - Number of GPE register pairs in the block
+ * InterruptNumber - H/W interrupt for the block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
+ * enabled here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGpeBlock (
+ ACPI_HANDLE GpeDevice,
+ ACPI_GENERIC_ADDRESS *GpeBlockAddress,
+ UINT32 RegisterCount,
+ UINT32 InterruptNumber)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
+
+
+ if ((!GpeDevice) ||
+ (!GpeBlockAddress) ||
+ (!RegisterCount))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Node = AcpiNsValidateHandle (GpeDevice);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Validate the parent device */
+
+ if (Node->Type != ACPI_TYPE_DEVICE)
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ if (Node->Object)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * For user-installed GPE Block Devices, the GpeBlockBaseNumber
+ * is always zero
+ */
+ Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
+ GpeBlockAddress->SpaceId, RegisterCount,
+ 0, InterruptNumber, &GpeBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Install block in the DeviceObject attached to the node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /*
+ * No object, create a new one (Device nodes do not always have
+ * an attached object)
+ */
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+
+ /* Now install the GPE block in the DeviceObject */
+
+ ObjDesc->Device.GpeBlock = GpeBlock;
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveGpeBlock
+ *
+ * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveGpeBlock (
+ ACPI_HANDLE GpeDevice)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
+
+
+ if (!GpeDevice)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Node = AcpiNsValidateHandle (GpeDevice);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Validate the parent device */
+
+ if (Node->Type != ACPI_TYPE_DEVICE)
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ /* Get the DeviceObject attached to the node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc ||
+ !ObjDesc->Device.GpeBlock)
+ {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Delete the GPE block (but not the DeviceObject) */
+
+ Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
+ if (ACPI_SUCCESS (Status))
+ {
+ ObjDesc->Device.GpeBlock = NULL;
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetGpeDevice
+ *
+ * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
+ * GpeDevice - Where the parent GPE Device is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
+ * gpe device indicates that the gpe number is contained in one of
+ * the FADT-defined gpe blocks. Otherwise, the GPE block device.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetGpeDevice (
+ UINT32 Index,
+ ACPI_HANDLE *GpeDevice)
+{
+ ACPI_GPE_DEVICE_INFO Info;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
+
+
+ if (!GpeDevice)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (Index >= AcpiCurrentGpeCount)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Setup and walk the GPE list */
+
+ Info.Index = Index;
+ Info.Status = AE_NOT_EXIST;
+ Info.GpeDevice = NULL;
+ Info.NextBlockBaseIndex = 0;
+
+ Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
+ return_ACPI_STATUS (Info.Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfregn.c b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfregn.c
new file mode 100644
index 0000000000..8b0d80e348
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/events/evxfregn.c
@@ -0,0 +1,313 @@
+/******************************************************************************
+ *
+ * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
+ * Address Spaces.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evxfregn")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallAddressSpaceHandler
+ *
+ * PARAMETERS: Device - Handle for the device
+ * SpaceId - The address space ID
+ * Handler - Address of the handler
+ * Setup - Address of the setup function
+ * Context - Value passed to the handler on each access
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
+ *
+ * NOTE: This function should only be called after AcpiEnableSubsystem has
+ * been called. This is because any _REG methods associated with the Space ID
+ * are executed here, and these methods can only be safely executed after
+ * the default handlers have been installed and the hardware has been
+ * initialized (via AcpiEnableSubsystem.)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallAddressSpaceHandler (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallAddressSpaceHandler);
+
+
+ /* Parameter validation */
+
+ if (!Device)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Convert and validate the device handle */
+
+ Node = AcpiNsValidateHandle (Device);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Install the handler for all Regions for this Space ID */
+
+ Status = AcpiEvInstallSpaceHandler (Node, SpaceId, Handler, Setup, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /*
+ * For the default SpaceIDs, (the IDs for which there are default region handlers
+ * installed) Only execute the _REG methods if the global initialization _REG
+ * methods have already been run (via AcpiInitializeObjects). In other words,
+ * we will defer the execution of the _REG methods for these SpaceIDs until
+ * execution of AcpiInitializeObjects. This is done because we need the handlers
+ * for the default spaces (mem/io/pci/table) to be installed before we can run
+ * any control methods (or _REG methods). There is known BIOS code that depends
+ * on this.
+ *
+ * For all other SpaceIDs, we can safely execute the _REG methods immediately.
+ * This means that for IDs like EmbeddedController, this function should be called
+ * only after AcpiEnableSubsystem has been called.
+ */
+ switch (SpaceId)
+ {
+ case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+ case ACPI_ADR_SPACE_SYSTEM_IO:
+ case ACPI_ADR_SPACE_PCI_CONFIG:
+ case ACPI_ADR_SPACE_DATA_TABLE:
+
+ if (!AcpiGbl_RegMethodsExecuted)
+ {
+ /* We will defer execution of the _REG methods for this space */
+ goto UnlockAndExit;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Run all _REG methods for this address space */
+
+ Status = AcpiEvExecuteRegMethods (Node, SpaceId);
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveAddressSpaceHandler
+ *
+ * PARAMETERS: Device - Handle for the device
+ * SpaceId - The address space ID
+ * Handler - Address of the handler
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a previously installed handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveAddressSpaceHandler (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *RegionObj;
+ ACPI_OPERAND_OBJECT **LastObjPtr;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveAddressSpaceHandler);
+
+
+ /* Parameter validation */
+
+ if (!Device)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Convert and validate the device handle */
+
+ Node = AcpiNsValidateHandle (Device);
+ if (!Node ||
+ ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_PROCESSOR) &&
+ (Node->Type != ACPI_TYPE_THERMAL) &&
+ (Node != AcpiGbl_RootNode)))
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Make sure the internal object exists */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ /* Find the address handler the user requested */
+
+ HandlerObj = ObjDesc->Device.Handler;
+ LastObjPtr = &ObjDesc->Device.Handler;
+ while (HandlerObj)
+ {
+ /* We have a handler, see if user requested this one */
+
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
+ {
+ /* Handler must be the same as the installed handler */
+
+ if (HandlerObj->AddressSpace.Handler != Handler)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Matched SpaceId, first dereference this in the Regions */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Removing address handler %p(%p) for region %s "
+ "on Device %p(%p)\n",
+ HandlerObj, Handler, AcpiUtGetRegionName (SpaceId),
+ Node, ObjDesc));
+
+ RegionObj = HandlerObj->AddressSpace.RegionList;
+
+ /* Walk the handler's region list */
+
+ while (RegionObj)
+ {
+ /*
+ * First disassociate the handler from the region.
+ *
+ * NOTE: this doesn't mean that the region goes away
+ * The region is just inaccessible as indicated to
+ * the _REG method
+ */
+ AcpiEvDetachRegion (RegionObj, TRUE);
+
+ /*
+ * Walk the list: Just grab the head because the
+ * DetachRegion removed the previous head.
+ */
+ RegionObj = HandlerObj->AddressSpace.RegionList;
+
+ }
+
+ /* Remove this Handler object from the list */
+
+ *LastObjPtr = HandlerObj->AddressSpace.Next;
+
+ /* Now we can delete the handler object */
+
+ AcpiUtRemoveReference (HandlerObj);
+ goto UnlockAndExit;
+ }
+
+ /* Walk the linked list of handlers */
+
+ LastObjPtr = &HandlerObj->AddressSpace.Next;
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+
+ /* The handler does not exist */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
+ Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc));
+
+ Status = AE_NOT_EXIST;
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconfig.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconfig.c
new file mode 100644
index 0000000000..c78f1a29a5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconfig.c
@@ -0,0 +1,680 @@
+/******************************************************************************
+ *
+ * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exconfig")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiExAddTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_OPERAND_OBJECT **DdbHandle);
+
+static ACPI_STATUS
+AcpiExRegionRead (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Length,
+ UINT8 *Buffer);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAddTable
+ *
+ * PARAMETERS: Table - Pointer to raw table
+ * ParentNode - Where to load the table (scope)
+ * DdbHandle - Where to return the table handle.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common function to Install and Load an ACPI table with a
+ * returned table handle.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExAddTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_OPERAND_OBJECT **DdbHandle)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_OWNER_ID OwnerId;
+
+
+ ACPI_FUNCTION_TRACE (ExAddTable);
+
+
+ /* Create an object to be the table handle */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Init the table handle */
+
+ ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
+ ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
+ *DdbHandle = ObjDesc;
+
+ /* Install the new table into the local data structures */
+
+ ObjDesc->Reference.Value = TableIndex;
+
+ /* Add the table to the namespace */
+
+ Status = AcpiNsLoadTable (TableIndex, ParentNode);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ *DdbHandle = NULL;
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Execute any module-level code that was found in the table */
+
+ AcpiExExitInterpreter ();
+ AcpiNsExecModuleCodeList ();
+ AcpiExEnterInterpreter ();
+
+ /*
+ * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
+ * responsible for discovering any new wake GPEs by running _PRW methods
+ * that may have been loaded by this table.
+ */
+ Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiEvUpdateGpes (OwnerId);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExLoadTableOp
+ *
+ * PARAMETERS: WalkState - Current state with operands
+ * ReturnDesc - Where to store the return object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExLoadTableOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **ReturnDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_NAMESPACE_NODE *StartNode;
+ ACPI_NAMESPACE_NODE *ParameterNode = NULL;
+ ACPI_OPERAND_OBJECT *DdbHandle;
+ ACPI_TABLE_HEADER *Table;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (ExLoadTableOp);
+
+
+ /* Find the ACPI table in the RSDT/XSDT */
+
+ Status = AcpiTbFindTable (
+ Operand[0]->String.Pointer,
+ Operand[1]->String.Pointer,
+ Operand[2]->String.Pointer, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status != AE_NOT_FOUND)
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Table not found, return an Integer=0 and AE_OK */
+
+ DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!DdbHandle)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ *ReturnDesc = DdbHandle;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Default nodes */
+
+ StartNode = WalkState->ScopeInfo->Scope.Node;
+ ParentNode = AcpiGbl_RootNode;
+
+ /* RootPath (optional parameter) */
+
+ if (Operand[3]->String.Length > 0)
+ {
+ /*
+ * Find the node referenced by the RootPathString. This is the
+ * location within the namespace where the table will be loaded.
+ */
+ Status = AcpiNsGetNode (StartNode, Operand[3]->String.Pointer,
+ ACPI_NS_SEARCH_PARENT, &ParentNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* ParameterPath (optional parameter) */
+
+ if (Operand[4]->String.Length > 0)
+ {
+ if ((Operand[4]->String.Pointer[0] != AML_ROOT_PREFIX) &&
+ (Operand[4]->String.Pointer[0] != AML_PARENT_PREFIX))
+ {
+ /*
+ * Path is not absolute, so it will be relative to the node
+ * referenced by the RootPathString (or the NS root if omitted)
+ */
+ StartNode = ParentNode;
+ }
+
+ /* Find the node referenced by the ParameterPathString */
+
+ Status = AcpiNsGetNode (StartNode, Operand[4]->String.Pointer,
+ ACPI_NS_SEARCH_PARENT, &ParameterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Load the table into the namespace */
+
+ Status = AcpiExAddTable (TableIndex, ParentNode, &DdbHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Parameter Data (optional) */
+
+ if (ParameterNode)
+ {
+ /* Store the parameter data into the optional parameter object */
+
+ Status = AcpiExStore (Operand[5],
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ (void) AcpiExUnloadTable (DdbHandle);
+
+ AcpiUtRemoveReference (DdbHandle);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_SUCCESS (Status))
+ {
+ ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
+ AcpiTbPrintTableHeader (0, Table);
+ }
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+
+ *ReturnDesc = DdbHandle;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExRegionRead
+ *
+ * PARAMETERS: ObjDesc - Region descriptor
+ * Length - Number of bytes to read
+ * Buffer - Pointer to where to put the data
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read data from an operation region. The read starts from the
+ * beginning of the region.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExRegionRead (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Length,
+ UINT8 *Buffer)
+{
+ ACPI_STATUS Status;
+ UINT64 Value;
+ UINT32 RegionOffset = 0;
+ UINT32 i;
+
+
+ /* Bytewise reads */
+
+ for (i = 0; i < Length; i++)
+ {
+ Status = AcpiEvAddressSpaceDispatch (ObjDesc, NULL, ACPI_READ,
+ RegionOffset, 8, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *Buffer = (UINT8) Value;
+ Buffer++;
+ RegionOffset++;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExLoadOp
+ *
+ * PARAMETERS: ObjDesc - Region or Buffer/Field where the table will be
+ * obtained
+ * Target - Where a handle to the table will be stored
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load an ACPI table from a field or operation region
+ *
+ * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
+ * objects before this code is reached.
+ *
+ * If source is an operation region, it must refer to SystemMemory, as
+ * per the ACPI specification.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExLoadOp (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *Target,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *DdbHandle;
+ ACPI_TABLE_HEADER *TableHeader;
+ ACPI_TABLE_HEADER *Table;
+ UINT32 TableIndex;
+ ACPI_STATUS Status;
+ UINT32 Length;
+
+
+ ACPI_FUNCTION_TRACE (ExLoadOp);
+
+
+ /* Source Object can be either an OpRegion or a Buffer/Field */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_REGION:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Load table from Region %p\n", ObjDesc));
+
+ /* Region must be SystemMemory (from ACPI spec) */
+
+ if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * If the Region Address and Length have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetRegionArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Get the table header first so we can get the table length */
+
+ TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
+ if (!TableHeader)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
+ ACPI_CAST_PTR (UINT8, TableHeader));
+ Length = TableHeader->Length;
+ ACPI_FREE (TableHeader);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Must have at least an ACPI table header */
+
+ if (Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ }
+
+ /*
+ * The original implementation simply mapped the table, with no copy.
+ * However, the memory region is not guaranteed to remain stable and
+ * we must copy the table to a local buffer. For example, the memory
+ * region is corrupted after suspend on some machines. Dynamically
+ * loaded tables are usually small, so this overhead is minimal.
+ *
+ * The latest implementation (5/2009) does not use a mapping at all.
+ * We use the low-level operation region interface to read the table
+ * instead of the obvious optimization of using a direct mapping.
+ * This maintains a consistent use of operation regions across the
+ * entire subsystem. This is important if additional processing must
+ * be performed in the (possibly user-installed) operation region
+ * handler. For example, AcpiExec and ASLTS depend on this.
+ */
+
+ /* Allocate a buffer for the table */
+
+ Table = ACPI_ALLOCATE (Length);
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Read the entire table */
+
+ Status = AcpiExRegionRead (ObjDesc, Length,
+ ACPI_CAST_PTR (UINT8, Table));
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (Table);
+ return_ACPI_STATUS (Status);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Load table from Buffer or Field %p\n", ObjDesc));
+
+ /* Must have at least an ACPI table header */
+
+ if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ }
+
+ /* Get the actual table length from the table header */
+
+ TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
+ Length = TableHeader->Length;
+
+ /* Table cannot extend beyond the buffer */
+
+ if (Length > ObjDesc->Buffer.Length)
+ {
+ return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+ }
+ if (Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ }
+
+ /*
+ * Copy the table from the buffer because the buffer could be modified
+ * or even deleted in the future
+ */
+ Table = ACPI_ALLOCATE (Length);
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ memcpy (Table, TableHeader, Length);
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Install the new table into the local data structures */
+
+ ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
+ ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, TRUE, TRUE,
+ &TableIndex);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Delete allocated table buffer */
+
+ ACPI_FREE (Table);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Note: Now table is "INSTALLED", it must be validated before
+ * loading.
+ */
+ Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Add the table to the namespace.
+ *
+ * Note: Load the table objects relative to the root of the namespace.
+ * This appears to go against the ACPI specification, but we do it for
+ * compatibility with other ACPI implementations.
+ */
+ Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ /* On error, TablePtr was deallocated above */
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Store the DdbHandle into the Target operand */
+
+ Status = AcpiExStore (DdbHandle, Target, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ (void) AcpiExUnloadTable (DdbHandle);
+
+ /* TablePtr was deallocated above */
+
+ AcpiUtRemoveReference (DdbHandle);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Remove the reference by added by AcpiExStore above */
+
+ AcpiUtRemoveReference (DdbHandle);
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExUnloadTable
+ *
+ * PARAMETERS: DdbHandle - Handle to a previously loaded table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Unload an ACPI table
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExUnloadTable (
+ ACPI_OPERAND_OBJECT *DdbHandle)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *TableDesc = DdbHandle;
+ UINT32 TableIndex;
+ ACPI_TABLE_HEADER *Table;
+
+
+ ACPI_FUNCTION_TRACE (ExUnloadTable);
+
+
+ /*
+ * Temporarily emit a warning so that the ASL for the machine can be
+ * hopefully obtained. This is to say that the Unload() operator is
+ * extremely rare if not completely unused.
+ */
+ ACPI_WARNING ((AE_INFO,
+ "Received request to unload an ACPI table"));
+
+ /*
+ * Validate the handle
+ * Although the handle is partially validated in AcpiExReconfiguration()
+ * when it calls AcpiExResolveOperands(), the handle is more completely
+ * validated here.
+ *
+ * Handle must be a valid operand object of type reference. Also, the
+ * DdbHandle must still be marked valid (table has not been previously
+ * unloaded)
+ */
+ if ((!DdbHandle) ||
+ (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
+ (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
+ (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Get the table index from the DdbHandle */
+
+ TableIndex = TableDesc->Reference.Value;
+
+ /* Ensure the table is still loaded */
+
+ if (!AcpiTbIsTableLoaded (TableIndex))
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_SUCCESS (Status))
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+ }
+
+ /* Delete the portion of the namespace owned by this table */
+
+ Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ (void) AcpiTbReleaseOwnerId (TableIndex);
+ AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
+
+ /*
+ * Invalidate the handle. We do this because the handle may be stored
+ * in a named object and may not be actually deleted until much later.
+ */
+ DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconvrt.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconvrt.c
new file mode 100644
index 0000000000..ac881cbd3c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exconvrt.c
@@ -0,0 +1,744 @@
+/******************************************************************************
+ *
+ * Module Name: exconvrt - Object conversion routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exconvrt")
+
+/* Local prototypes */
+
+static UINT32
+AcpiExConvertToAscii (
+ UINT64 Integer,
+ UINT16 Base,
+ UINT8 *String,
+ UINT8 MaxLength);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConvertToInteger
+ *
+ * PARAMETERS: ObjDesc - Object to be converted. Must be an
+ * Integer, Buffer, or String
+ * ResultDesc - Where the new Integer object is returned
+ * Flags - Used for string conversion
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to an integer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExConvertToInteger (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ UINT32 Flags)
+{
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ UINT8 *Pointer;
+ UINT64 Result;
+ UINT32 i;
+ UINT32 Count;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
+
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* No conversion necessary */
+
+ *ResultDesc = ObjDesc;
+ return_ACPI_STATUS (AE_OK);
+
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_STRING:
+
+ /* Note: Takes advantage of common buffer/string fields */
+
+ Pointer = ObjDesc->Buffer.Pointer;
+ Count = ObjDesc->Buffer.Length;
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /*
+ * Convert the buffer/string to an integer. Note that both buffers and
+ * strings are treated as raw data - we don't convert ascii to hex for
+ * strings.
+ *
+ * There are two terminating conditions for the loop:
+ * 1) The size of an integer has been reached, or
+ * 2) The end of the buffer or string has been reached
+ */
+ Result = 0;
+
+ /* String conversion is different than Buffer conversion */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+ /*
+ * Convert string to an integer - for most cases, the string must be
+ * hexadecimal as per the ACPI specification. The only exception (as
+ * of ACPI 3.0) is that the ToInteger() operator allows both decimal
+ * and hexadecimal strings (hex prefixed with "0x").
+ */
+ Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, &Result);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* Check for zero-length buffer */
+
+ if (!Count)
+ {
+ return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+ }
+
+ /* Transfer no more than an integer's worth of data */
+
+ if (Count > AcpiGbl_IntegerByteWidth)
+ {
+ Count = AcpiGbl_IntegerByteWidth;
+ }
+
+ /*
+ * Convert buffer to an integer - we simply grab enough raw data
+ * from the buffer to fill an integer
+ */
+ for (i = 0; i < Count; i++)
+ {
+ /*
+ * Get next byte and shift it into the Result.
+ * Little endian is used, meaning that the first byte of the buffer
+ * is the LSB of the integer
+ */
+ Result |= (((UINT64) Pointer[i]) << (i * 8));
+ }
+ break;
+
+ default:
+
+ /* No other types can get here */
+
+ break;
+ }
+
+ /* Create a new integer */
+
+ ReturnDesc = AcpiUtCreateIntegerObject (Result);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Result)));
+
+ /* Save the Result */
+
+ (void) AcpiExTruncateFor32bitTable (ReturnDesc);
+ *ResultDesc = ReturnDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConvertToBuffer
+ *
+ * PARAMETERS: ObjDesc - Object to be converted. Must be an
+ * Integer, Buffer, or String
+ * ResultDesc - Where the new buffer object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to a Buffer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExConvertToBuffer (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc)
+{
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ UINT8 *NewBuf;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc);
+
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ /* No conversion necessary */
+
+ *ResultDesc = ObjDesc;
+ return_ACPI_STATUS (AE_OK);
+
+
+ case ACPI_TYPE_INTEGER:
+ /*
+ * Create a new Buffer object.
+ * Need enough space for one integer
+ */
+ ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy the integer to the buffer, LSB first */
+
+ NewBuf = ReturnDesc->Buffer.Pointer;
+ memcpy (NewBuf,
+ &ObjDesc->Integer.Value,
+ AcpiGbl_IntegerByteWidth);
+ break;
+
+ case ACPI_TYPE_STRING:
+ /*
+ * Create a new Buffer object
+ * Size will be the string length
+ *
+ * NOTE: Add one to the string length to include the null terminator.
+ * The ACPI spec is unclear on this subject, but there is existing
+ * ASL/AML code that depends on the null being transferred to the new
+ * buffer.
+ */
+ ReturnDesc = AcpiUtCreateBufferObject (
+ (ACPI_SIZE) ObjDesc->String.Length + 1);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy the string to the buffer */
+
+ NewBuf = ReturnDesc->Buffer.Pointer;
+ strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
+ ObjDesc->String.Length);
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Mark buffer initialized */
+
+ ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID;
+ *ResultDesc = ReturnDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConvertToAscii
+ *
+ * PARAMETERS: Integer - Value to be converted
+ * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
+ * String - Where the string is returned
+ * DataWidth - Size of data item to be converted, in bytes
+ *
+ * RETURN: Actual string length
+ *
+ * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiExConvertToAscii (
+ UINT64 Integer,
+ UINT16 Base,
+ UINT8 *String,
+ UINT8 DataWidth)
+{
+ UINT64 Digit;
+ UINT32 i;
+ UINT32 j;
+ UINT32 k = 0;
+ UINT32 HexLength;
+ UINT32 DecimalLength;
+ UINT32 Remainder;
+ BOOLEAN SupressZeros;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ switch (Base)
+ {
+ case 10:
+
+ /* Setup max length for the decimal number */
+
+ switch (DataWidth)
+ {
+ case 1:
+
+ DecimalLength = ACPI_MAX8_DECIMAL_DIGITS;
+ break;
+
+ case 4:
+
+ DecimalLength = ACPI_MAX32_DECIMAL_DIGITS;
+ break;
+
+ case 8:
+ default:
+
+ DecimalLength = ACPI_MAX64_DECIMAL_DIGITS;
+ break;
+ }
+
+ SupressZeros = TRUE; /* No leading zeros */
+ Remainder = 0;
+
+ for (i = DecimalLength; i > 0; i--)
+ {
+ /* Divide by nth factor of 10 */
+
+ Digit = Integer;
+ for (j = 0; j < i; j++)
+ {
+ (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder);
+ }
+
+ /* Handle leading zeros */
+
+ if (Remainder != 0)
+ {
+ SupressZeros = FALSE;
+ }
+
+ if (!SupressZeros)
+ {
+ String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder);
+ k++;
+ }
+ }
+ break;
+
+ case 16:
+
+ /* HexLength: 2 ascii hex chars per data byte */
+
+ HexLength = ACPI_MUL_2 (DataWidth);
+ for (i = 0, j = (HexLength-1); i < HexLength; i++, j--)
+ {
+ /* Get one hex digit, most significant digits first */
+
+ String[k] = (UINT8) AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j));
+ k++;
+ }
+ break;
+
+ default:
+ return (0);
+ }
+
+ /*
+ * Since leading zeros are suppressed, we must check for the case where
+ * the integer equals 0
+ *
+ * Finally, null terminate the string and return the length
+ */
+ if (!k)
+ {
+ String [0] = ACPI_ASCII_ZERO;
+ k = 1;
+ }
+
+ String [k] = 0;
+ return ((UINT32) k);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConvertToString
+ *
+ * PARAMETERS: ObjDesc - Object to be converted. Must be an
+ * Integer, Buffer, or String
+ * ResultDesc - Where the string object is returned
+ * Type - String flags (base and conversion type)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to a string
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExConvertToString (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ UINT32 Type)
+{
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ UINT8 *NewBuf;
+ UINT32 i;
+ UINT32 StringLength = 0;
+ UINT16 Base = 16;
+ UINT8 Separator = ',';
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc);
+
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ /* No conversion necessary */
+
+ *ResultDesc = ObjDesc;
+ return_ACPI_STATUS (AE_OK);
+
+ case ACPI_TYPE_INTEGER:
+
+ switch (Type)
+ {
+ case ACPI_EXPLICIT_CONVERT_DECIMAL:
+
+ /* Make room for maximum decimal number */
+
+ StringLength = ACPI_MAX_DECIMAL_DIGITS;
+ Base = 10;
+ break;
+
+ default:
+
+ /* Two hex string characters for each integer byte */
+
+ StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth);
+ break;
+ }
+
+ /*
+ * Create a new String
+ * Need enough space for one ASCII integer (plus null terminator)
+ */
+ ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ NewBuf = ReturnDesc->Buffer.Pointer;
+
+ /* Convert integer to string */
+
+ StringLength = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base,
+ NewBuf, AcpiGbl_IntegerByteWidth);
+
+ /* Null terminate at the correct place */
+
+ ReturnDesc->String.Length = StringLength;
+ NewBuf [StringLength] = 0;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* Setup string length, base, and separator */
+
+ switch (Type)
+ {
+ case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */
+ /*
+ * From ACPI: "If Data is a buffer, it is converted to a string of
+ * decimal values separated by commas."
+ */
+ Base = 10;
+
+ /*
+ * Calculate the final string length. Individual string values
+ * are variable length (include separator for each)
+ */
+ for (i = 0; i < ObjDesc->Buffer.Length; i++)
+ {
+ if (ObjDesc->Buffer.Pointer[i] >= 100)
+ {
+ StringLength += 4;
+ }
+ else if (ObjDesc->Buffer.Pointer[i] >= 10)
+ {
+ StringLength += 3;
+ }
+ else
+ {
+ StringLength += 2;
+ }
+ }
+ break;
+
+ case ACPI_IMPLICIT_CONVERT_HEX:
+ /*
+ * From the ACPI spec:
+ *"The entire contents of the buffer are converted to a string of
+ * two-character hexadecimal numbers, each separated by a space."
+ */
+ Separator = ' ';
+ StringLength = (ObjDesc->Buffer.Length * 3);
+ break;
+
+ case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString */
+ /*
+ * From ACPI: "If Data is a buffer, it is converted to a string of
+ * hexadecimal values separated by commas."
+ */
+ StringLength = (ObjDesc->Buffer.Length * 3);
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Create a new string object and string buffer
+ * (-1 because of extra separator included in StringLength from above)
+ * Allow creation of zero-length strings from zero-length buffers.
+ */
+ if (StringLength)
+ {
+ StringLength--;
+ }
+
+ ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ NewBuf = ReturnDesc->Buffer.Pointer;
+
+ /*
+ * Convert buffer bytes to hex or decimal values
+ * (separated by commas or spaces)
+ */
+ for (i = 0; i < ObjDesc->Buffer.Length; i++)
+ {
+ NewBuf += AcpiExConvertToAscii (
+ (UINT64) ObjDesc->Buffer.Pointer[i], Base,
+ NewBuf, 1);
+ *NewBuf++ = Separator; /* each separated by a comma or space */
+ }
+
+ /*
+ * Null terminate the string
+ * (overwrites final comma/space from above)
+ */
+ if (ObjDesc->Buffer.Length)
+ {
+ NewBuf--;
+ }
+ *NewBuf = 0;
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ *ResultDesc = ReturnDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConvertToTargetType
+ *
+ * PARAMETERS: DestinationType - Current type of the destination
+ * SourceDesc - Source object to be converted.
+ * ResultDesc - Where the converted object is returned
+ * WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExConvertToTargetType (
+ ACPI_OBJECT_TYPE DestinationType,
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExConvertToTargetType);
+
+
+ /* Default behavior */
+
+ *ResultDesc = SourceDesc;
+
+ /*
+ * If required by the target,
+ * perform implicit conversion on the source before we store it.
+ */
+ switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs))
+ {
+ case ARGI_SIMPLE_TARGET:
+ case ARGI_FIXED_TARGET:
+ case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
+
+ switch (DestinationType)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ /*
+ * Named field can always handle conversions
+ */
+ break;
+
+ default:
+
+ /* No conversion allowed for these types */
+
+ if (DestinationType != SourceDesc->Common.Type)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Explicit operator, will store (%s) over existing type (%s)\n",
+ AcpiUtGetObjectTypeName (SourceDesc),
+ AcpiUtGetTypeName (DestinationType)));
+ Status = AE_TYPE;
+ }
+ }
+ break;
+
+ case ARGI_TARGETREF:
+
+ switch (DestinationType)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ /*
+ * These types require an Integer operand. We can convert
+ * a Buffer or a String to an Integer if necessary.
+ */
+ Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
+ 16);
+ break;
+
+ case ACPI_TYPE_STRING:
+ /*
+ * The operand must be a String. We can convert an
+ * Integer or Buffer if necessary
+ */
+ Status = AcpiExConvertToString (SourceDesc, ResultDesc,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ /*
+ * The operand must be a Buffer. We can convert an
+ * Integer or String if necessary
+ */
+ Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X",
+ DestinationType));
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+ break;
+
+ case ARGI_REFERENCE:
+ /*
+ * CreateXxxxField cases - we are storing the field object into the name
+ */
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
+ GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
+ WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
+ Status = AE_AML_INTERNAL;
+ }
+
+ /*
+ * Source-to-Target conversion semantics:
+ *
+ * If conversion to the target type cannot be performed, then simply
+ * overwrite the target with the new object and type.
+ */
+ if (Status == AE_TYPE)
+ {
+ Status = AE_OK;
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/excreate.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/excreate.c
new file mode 100644
index 0000000000..9f3f2cca2d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/excreate.c
@@ -0,0 +1,568 @@
+/******************************************************************************
+ *
+ * Module Name: excreate - Named object creation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("excreate")
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateAlias
+ *
+ * PARAMETERS: WalkState - Current state, contains operands
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new named alias
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateAlias (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_NAMESPACE_NODE *TargetNode;
+ ACPI_NAMESPACE_NODE *AliasNode;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExCreateAlias);
+
+
+ /* Get the source/alias operands (both namespace nodes) */
+
+ AliasNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0];
+ TargetNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1];
+
+ if ((TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS) ||
+ (TargetNode->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
+ {
+ /*
+ * Dereference an existing alias so that we don't create a chain
+ * of aliases. With this code, we guarantee that an alias is
+ * always exactly one level of indirection away from the
+ * actual aliased name.
+ */
+ TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object);
+ }
+
+ /*
+ * For objects that can never change (i.e., the NS node will
+ * permanently point to the same object), we can simply attach
+ * the object to the new NS node. For other objects (such as
+ * Integers, buffers, etc.), we have to point the Alias node
+ * to the original Node.
+ */
+ switch (TargetNode->Type)
+ {
+
+ /* For these types, the sub-object can change dynamically via a Store */
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_PACKAGE:
+ case ACPI_TYPE_BUFFER_FIELD:
+ /*
+ * These types open a new scope, so we need the NS node in order to access
+ * any children.
+ */
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+ case ACPI_TYPE_LOCAL_SCOPE:
+ /*
+ * The new alias has the type ALIAS and points to the original
+ * NS node, not the object itself.
+ */
+ AliasNode->Type = ACPI_TYPE_LOCAL_ALIAS;
+ AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
+ break;
+
+ case ACPI_TYPE_METHOD:
+ /*
+ * Control method aliases need to be differentiated
+ */
+ AliasNode->Type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
+ AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
+ break;
+
+ default:
+
+ /* Attach the original source object to the new Alias Node */
+
+ /*
+ * The new alias assumes the type of the target, and it points
+ * to the same object. The reference count of the object has an
+ * additional reference to prevent deletion out from under either the
+ * target node or the alias Node
+ */
+ Status = AcpiNsAttachObject (AliasNode,
+ AcpiNsGetAttachedObject (TargetNode), TargetNode->Type);
+ break;
+ }
+
+ /* Since both operands are Nodes, we don't need to delete them */
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateEvent
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new event object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateEvent (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE (ExCreateEvent);
+
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_EVENT);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Create the actual OS semaphore, with zero initial units -- meaning
+ * that the event is created in an unsignalled state
+ */
+ Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
+ &ObjDesc->Event.OsSemaphore);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Attach object to the Node */
+
+ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) WalkState->Operands[0],
+ ObjDesc, ACPI_TYPE_EVENT);
+
+Cleanup:
+ /*
+ * Remove local reference to the object (on error, will cause deletion
+ * of both object and semaphore if present.)
+ */
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateMutex
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new mutex object
+ *
+ * Mutex (Name[0], SyncLevel[1])
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateMutex (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExCreateMutex, ACPI_WALK_OPERANDS);
+
+
+ /* Create the new mutex object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Create the actual OS Mutex */
+
+ Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Init object and attach to NS node */
+
+ ObjDesc->Mutex.SyncLevel = (UINT8) WalkState->Operands[1]->Integer.Value;
+ ObjDesc->Mutex.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0];
+
+ Status = AcpiNsAttachObject (ObjDesc->Mutex.Node, ObjDesc, ACPI_TYPE_MUTEX);
+
+
+Cleanup:
+ /*
+ * Remove local reference to the object (on error, will cause deletion
+ * of both object and semaphore if present.)
+ */
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateRegion
+ *
+ * PARAMETERS: AmlStart - Pointer to the region declaration AML
+ * AmlLength - Max length of the declaration AML
+ * SpaceId - Address space ID for the region
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new operation region object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateRegion (
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ UINT8 SpaceId,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *RegionObj2;
+
+
+ ACPI_FUNCTION_TRACE (ExCreateRegion);
+
+
+ /* Get the Namespace Node */
+
+ Node = WalkState->Op->Common.Node;
+
+ /*
+ * If the region object is already attached to this node,
+ * just return
+ */
+ if (AcpiNsGetAttachedObject (Node))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Space ID must be one of the predefined IDs, or in the user-defined
+ * range
+ */
+ if (!AcpiIsValidSpaceId (SpaceId))
+ {
+ /*
+ * Print an error message, but continue. We don't want to abort
+ * a table load for this exception. Instead, if the region is
+ * actually used at runtime, abort the executing method.
+ */
+ ACPI_ERROR ((AE_INFO, "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n",
+ AcpiUtGetRegionName (SpaceId), SpaceId));
+
+ /* Create the region descriptor */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Remember location in AML stream of address & length
+ * operands since they need to be evaluated at run time.
+ */
+ RegionObj2 = ObjDesc->Common.NextObject;
+ RegionObj2->Extra.AmlStart = AmlStart;
+ RegionObj2->Extra.AmlLength = AmlLength;
+ if (WalkState->ScopeInfo)
+ {
+ RegionObj2->Extra.ScopeNode = WalkState->ScopeInfo->Scope.Node;
+ }
+ else
+ {
+ RegionObj2->Extra.ScopeNode = Node;
+ }
+
+ /* Init the region from the operands */
+
+ ObjDesc->Region.SpaceId = SpaceId;
+ ObjDesc->Region.Address = 0;
+ ObjDesc->Region.Length = 0;
+ ObjDesc->Region.Node = Node;
+
+ /* Install the new region object in the parent Node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_REGION);
+
+
+Cleanup:
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateProcessor
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new processor object and populate the fields
+ *
+ * Processor (Name[0], CpuID[1], PblockAddr[2], PblockLength[3])
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateProcessor (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExCreateProcessor, WalkState);
+
+
+ /* Create the processor object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PROCESSOR);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize the processor object from the operands */
+
+ ObjDesc->Processor.ProcId = (UINT8) Operand[1]->Integer.Value;
+ ObjDesc->Processor.Length = (UINT8) Operand[3]->Integer.Value;
+ ObjDesc->Processor.Address = (ACPI_IO_ADDRESS) Operand[2]->Integer.Value;
+
+ /* Install the processor object in the parent Node */
+
+ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
+ ObjDesc, ACPI_TYPE_PROCESSOR);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreatePowerResource
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new PowerResource object and populate the fields
+ *
+ * PowerResource (Name[0], SystemLevel[1], ResourceOrder[2])
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreatePowerResource (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExCreatePowerResource, WalkState);
+
+
+ /* Create the power resource object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_POWER);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize the power object from the operands */
+
+ ObjDesc->PowerResource.SystemLevel = (UINT8) Operand[1]->Integer.Value;
+ ObjDesc->PowerResource.ResourceOrder = (UINT16) Operand[2]->Integer.Value;
+
+ /* Install the power resource object in the parent Node */
+
+ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
+ ObjDesc, ACPI_TYPE_POWER);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCreateMethod
+ *
+ * PARAMETERS: AmlStart - First byte of the method's AML
+ * AmlLength - AML byte count for this method
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new method object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCreateMethod (
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ UINT8 MethodFlags;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExCreateMethod, WalkState);
+
+
+ /* Create a new method object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Exit;
+ }
+
+ /* Save the method's AML pointer and length */
+
+ ObjDesc->Method.AmlStart = AmlStart;
+ ObjDesc->Method.AmlLength = AmlLength;
+ ObjDesc->Method.Node = Operand[0];
+
+ /*
+ * Disassemble the method flags. Split off the ArgCount, Serialized
+ * flag, and SyncLevel for efficiency.
+ */
+ MethodFlags = (UINT8) Operand[1]->Integer.Value;
+ ObjDesc->Method.ParamCount = (UINT8) (MethodFlags & AML_METHOD_ARG_COUNT);
+
+ /*
+ * Get the SyncLevel. If method is serialized, a mutex will be
+ * created for this method when it is parsed.
+ */
+ if (MethodFlags & AML_METHOD_SERIALIZED)
+ {
+ ObjDesc->Method.InfoFlags = ACPI_METHOD_SERIALIZED;
+
+ /*
+ * ACPI 1.0: SyncLevel = 0
+ * ACPI 2.0: SyncLevel = SyncLevel in method declaration
+ */
+ ObjDesc->Method.SyncLevel = (UINT8)
+ ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
+ }
+
+ /* Attach the new object to the method Node */
+
+ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
+ ObjDesc, ACPI_TYPE_METHOD);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+
+Exit:
+ /* Remove a reference to the operand */
+
+ AcpiUtRemoveReference (Operand[1]);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdebug.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdebug.c
new file mode 100644
index 0000000000..6acda90118
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdebug.c
@@ -0,0 +1,688 @@
+/******************************************************************************
+ *
+ * Module Name: exdebug - Support for stores to the AML Debug Object
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exdebug")
+
+
+static ACPI_OPERAND_OBJECT *AcpiGbl_TraceMethodObject = NULL;
+
+/* Local prototypes */
+
+#ifdef ACPI_DEBUG_OUTPUT
+static const char *
+AcpiExGetTraceEventName (
+ ACPI_TRACE_EVENT_TYPE Type);
+#endif
+
+
+#ifndef ACPI_NO_ERROR_MESSAGES
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoDebugObject
+ *
+ * PARAMETERS: SourceDesc - Object to be output to "Debug Object"
+ * Level - Indentation level (used for packages)
+ * Index - Current package element, zero if not pkg
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Handles stores to the AML Debug Object. For example:
+ * Store(INT1, Debug)
+ *
+ * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
+ *
+ * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or
+ * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal
+ * operational case, stores to the debug object are ignored but can be easily
+ * enabled if necessary.
+ *
+ ******************************************************************************/
+
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index)
+{
+ UINT32 i;
+ UINT32 Timer;
+ ACPI_OPERAND_OBJECT *ObjectDesc;
+ UINT32 Value;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
+
+
+ /* Output must be enabled via the DebugObject global or the DbgLevel */
+
+ if (!AcpiGbl_EnableAmlDebugObject &&
+ !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
+ {
+ return_VOID;
+ }
+
+ /*
+ * We will emit the current timer value (in microseconds) with each
+ * debug output. Only need the lower 26 bits. This allows for 67
+ * million microseconds or 67 seconds before rollover.
+ */
+ Timer = ((UINT32) AcpiOsGetTimer () / 10); /* (100 nanoseconds to microseconds) */
+ Timer &= 0x03FFFFFF;
+
+ /*
+ * Print line header as long as we are not in the middle of an
+ * object display
+ */
+ if (!((Level > 0) && Index == 0))
+ {
+ AcpiOsPrintf ("[ACPI Debug %.8u] %*s", Timer, Level, " ");
+ }
+
+ /* Display the index for package output only */
+
+ if (Index > 0)
+ {
+ AcpiOsPrintf ("(%.2u) ", Index-1);
+ }
+
+ if (!SourceDesc)
+ {
+ AcpiOsPrintf ("[Null Object]\n");
+ return_VOID;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));
+
+ if (!AcpiUtValidInternalObject (SourceDesc))
+ {
+ AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
+ return_VOID;
+ }
+ }
+ else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf ("%s: %p\n",
+ AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
+ SourceDesc);
+ return_VOID;
+ }
+ else
+ {
+ return_VOID;
+ }
+
+ /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
+
+ switch (SourceDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* Output correct integer width */
+
+ if (AcpiGbl_IntegerByteWidth == 4)
+ {
+ AcpiOsPrintf ("0x%8.8X\n",
+ (UINT32) SourceDesc->Integer.Value);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
+ AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer,
+ (SourceDesc->Buffer.Length < 256) ?
+ SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("[0x%.2X] \"%s\"\n",
+ SourceDesc->String.Length, SourceDesc->String.Pointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("[Contains 0x%.2X Elements]\n",
+ SourceDesc->Package.Count);
+
+ /* Output the entire contents of the package */
+
+ for (i = 0; i < SourceDesc->Package.Count; i++)
+ {
+ AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
+ Level+4, i+1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
+
+ /* Decode the reference */
+
+ switch (SourceDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_INDEX:
+
+ AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
+ break;
+
+ case ACPI_REFCLASS_TABLE:
+
+ /* Case for DdbHandle */
+
+ AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
+ return_VOID;
+
+ default:
+
+ break;
+ }
+
+ AcpiOsPrintf (" ");
+
+ /* Check for valid node first, then valid object */
+
+ if (SourceDesc->Reference.Node)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
+ ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf (" %p - Not a valid namespace node\n",
+ SourceDesc->Reference.Node);
+ }
+ else
+ {
+ AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
+ (SourceDesc->Reference.Node)->Name.Ascii);
+
+ switch ((SourceDesc->Reference.Node)->Type)
+ {
+ /* These types have no attached object */
+
+ case ACPI_TYPE_DEVICE:
+ AcpiOsPrintf ("Device\n");
+ break;
+
+ case ACPI_TYPE_THERMAL:
+ AcpiOsPrintf ("Thermal Zone\n");
+ break;
+
+ default:
+
+ AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
+ Level+4, 0);
+ break;
+ }
+ }
+ }
+ else if (SourceDesc->Reference.Object)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
+ ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
+ SourceDesc->Reference.Object)->Object,
+ Level+4, 0);
+ }
+ else
+ {
+ ObjectDesc = SourceDesc->Reference.Object;
+ Value = SourceDesc->Reference.Value;
+
+ switch (ObjectDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n",
+ Value, *SourceDesc->Reference.IndexPointer);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n",
+ Value, *SourceDesc->Reference.IndexPointer,
+ *SourceDesc->Reference.IndexPointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("Package[%u] = ", Value);
+ AcpiExDoDebugObject (*SourceDesc->Reference.Where,
+ Level+4, 0);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown Reference object type %X\n",
+ ObjectDesc->Common.Type);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("%p\n", SourceDesc);
+ break;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+ return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExInterpreterTraceEnabled
+ *
+ * PARAMETERS: Name - Whether method name should be matched,
+ * this should be checked before starting
+ * the tracer
+ *
+ * RETURN: TRUE if interpreter trace is enabled.
+ *
+ * DESCRIPTION: Check whether interpreter trace is enabled
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiExInterpreterTraceEnabled (
+ char *Name)
+{
+
+ /* Check if tracing is enabled */
+
+ if (!(AcpiGbl_TraceFlags & ACPI_TRACE_ENABLED))
+ {
+ return (FALSE);
+ }
+
+ /*
+ * Check if tracing is filtered:
+ *
+ * 1. If the tracer is started, AcpiGbl_TraceMethodObject should have
+ * been filled by the trace starter
+ * 2. If the tracer is not started, AcpiGbl_TraceMethodName should be
+ * matched if it is specified
+ * 3. If the tracer is oneshot style, AcpiGbl_TraceMethodName should
+ * not be cleared by the trace stopper during the first match
+ */
+ if (AcpiGbl_TraceMethodObject)
+ {
+ return (TRUE);
+ }
+ if (Name &&
+ (AcpiGbl_TraceMethodName &&
+ strcmp (AcpiGbl_TraceMethodName, Name)))
+ {
+ return (FALSE);
+ }
+ if ((AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT) &&
+ !AcpiGbl_TraceMethodName)
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGetTraceEventName
+ *
+ * PARAMETERS: Type - Trace event type
+ *
+ * RETURN: Trace event name.
+ *
+ * DESCRIPTION: Used to obtain the full trace event name.
+ *
+ ******************************************************************************/
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+static const char *
+AcpiExGetTraceEventName (
+ ACPI_TRACE_EVENT_TYPE Type)
+{
+ switch (Type)
+ {
+ case ACPI_TRACE_AML_METHOD:
+
+ return "Method";
+
+ case ACPI_TRACE_AML_OPCODE:
+
+ return "Opcode";
+
+ case ACPI_TRACE_AML_REGION:
+
+ return "Region";
+
+ default:
+
+ return "";
+ }
+}
+
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExTracePoint
+ *
+ * PARAMETERS: Type - Trace event type
+ * Begin - TRUE if before execution
+ * Aml - Executed AML address
+ * Pathname - Object path
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Internal interpreter execution trace.
+ *
+ ******************************************************************************/
+
+void
+AcpiExTracePoint (
+ ACPI_TRACE_EVENT_TYPE Type,
+ BOOLEAN Begin,
+ UINT8 *Aml,
+ char *Pathname)
+{
+
+ ACPI_FUNCTION_NAME (ExTracePoint);
+
+
+ if (Pathname)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
+ "%s %s [0x%p:%s] execution.\n",
+ AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
+ Aml, Pathname));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
+ "%s %s [0x%p] execution.\n",
+ AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
+ Aml));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStartTraceMethod
+ *
+ * PARAMETERS: MethodNode - Node of the method
+ * ObjDesc - The method object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Start control method execution trace
+ *
+ ******************************************************************************/
+
+void
+AcpiExStartTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ char *Pathname = NULL;
+ BOOLEAN Enabled = FALSE;
+
+
+ ACPI_FUNCTION_NAME (ExStartTraceMethod);
+
+
+ if (MethodNode)
+ {
+ Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ Enabled = AcpiExInterpreterTraceEnabled (Pathname);
+ if (Enabled && !AcpiGbl_TraceMethodObject)
+ {
+ AcpiGbl_TraceMethodObject = ObjDesc;
+ AcpiGbl_OriginalDbgLevel = AcpiDbgLevel;
+ AcpiGbl_OriginalDbgLayer = AcpiDbgLayer;
+ AcpiDbgLevel = ACPI_TRACE_LEVEL_ALL;
+ AcpiDbgLayer = ACPI_TRACE_LAYER_ALL;
+
+ if (AcpiGbl_TraceDbgLevel)
+ {
+ AcpiDbgLevel = AcpiGbl_TraceDbgLevel;
+ }
+ if (AcpiGbl_TraceDbgLayer)
+ {
+ AcpiDbgLayer = AcpiGbl_TraceDbgLayer;
+ }
+ }
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+Exit:
+ if (Enabled)
+ {
+ ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, TRUE,
+ ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
+ }
+ if (Pathname)
+ {
+ ACPI_FREE (Pathname);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStopTraceMethod
+ *
+ * PARAMETERS: MethodNode - Node of the method
+ * ObjDesc - The method object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Stop control method execution trace
+ *
+ ******************************************************************************/
+
+void
+AcpiExStopTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ char *Pathname = NULL;
+ BOOLEAN Enabled;
+
+
+ ACPI_FUNCTION_NAME (ExStopTraceMethod);
+
+
+ if (MethodNode)
+ {
+ Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ExitPath;
+ }
+
+ Enabled = AcpiExInterpreterTraceEnabled (NULL);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ if (Enabled)
+ {
+ ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE,
+ ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ExitPath;
+ }
+
+ /* Check whether the tracer should be stopped */
+
+ if (AcpiGbl_TraceMethodObject == ObjDesc)
+ {
+ /* Disable further tracing if type is one-shot */
+
+ if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT)
+ {
+ AcpiGbl_TraceMethodName = NULL;
+ }
+
+ AcpiDbgLevel = AcpiGbl_OriginalDbgLevel;
+ AcpiDbgLayer = AcpiGbl_OriginalDbgLayer;
+ AcpiGbl_TraceMethodObject = NULL;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ExitPath:
+ if (Pathname)
+ {
+ ACPI_FREE (Pathname);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStartTraceOpcode
+ *
+ * PARAMETERS: Op - The parser opcode object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Start opcode execution trace
+ *
+ ******************************************************************************/
+
+void
+AcpiExStartTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ ACPI_FUNCTION_NAME (ExStartTraceOpcode);
+
+
+ if (AcpiExInterpreterTraceEnabled (NULL) &&
+ (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
+ {
+ ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, TRUE,
+ Op->Common.Aml, Op->Common.AmlOpName);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStopTraceOpcode
+ *
+ * PARAMETERS: Op - The parser opcode object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Stop opcode execution trace
+ *
+ ******************************************************************************/
+
+void
+AcpiExStopTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ ACPI_FUNCTION_NAME (ExStopTraceOpcode);
+
+
+ if (AcpiExInterpreterTraceEnabled (NULL) &&
+ (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
+ {
+ ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, FALSE,
+ Op->Common.Aml, Op->Common.AmlOpName);
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdump.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdump.c
new file mode 100644
index 0000000000..eacbdc442e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exdump.c
@@ -0,0 +1,1272 @@
+/******************************************************************************
+ *
+ * Module Name: exdump - Interpreter debug output routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exdump")
+
+/*
+ * The following routines are used for debug output only
+ */
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/* Local prototypes */
+
+static void
+AcpiExOutString (
+ char *Title,
+ char *Value);
+
+static void
+AcpiExOutPointer (
+ char *Title,
+ void *Value);
+
+static void
+AcpiExDumpObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_EXDUMP_INFO *Info);
+
+static void
+AcpiExDumpReferenceObj (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+static void
+AcpiExDumpPackageObj (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Level,
+ UINT32 Index);
+
+
+/*******************************************************************************
+ *
+ * Object Descriptor info tables
+ *
+ * Note: The first table entry must be an INIT opcode and must contain
+ * the table length (number of table entries)
+ *
+ ******************************************************************************/
+
+static ACPI_EXDUMP_INFO AcpiExDumpInteger[2] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpInteger), NULL},
+ {ACPI_EXD_UINT64, ACPI_EXD_OFFSET (Integer.Value), "Value"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpString[4] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpString), NULL},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (String.Length), "Length"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (String.Pointer), "Pointer"},
+ {ACPI_EXD_STRING, 0, NULL}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpBuffer[5] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpBuffer), NULL},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Buffer.Length), "Length"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Buffer.Pointer), "Pointer"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Buffer.Node), "Parent Node"},
+ {ACPI_EXD_BUFFER, 0, NULL}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpPackage[6] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpPackage), NULL},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Package.Node), "Parent Node"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Package.Flags), "Flags"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Package.Count), "Elements"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Package.Elements), "Element List"},
+ {ACPI_EXD_PACKAGE, 0, NULL}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpDevice[4] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpDevice), NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.NotifyList[1]), "Device Notify"},
+ {ACPI_EXD_HDLR_LIST,ACPI_EXD_OFFSET (Device.Handler), "Handler"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpEvent[2] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpEvent), NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Event.OsSemaphore), "OsSemaphore"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpMethod[9] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpMethod), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Method.InfoFlags), "Info Flags"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Method.ParamCount), "Parameter Count"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Method.SyncLevel), "Sync Level"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Method.Mutex), "Mutex"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Method.OwnerId), "Owner Id"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Method.ThreadCount), "Thread Count"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Method.AmlLength), "Aml Length"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Method.AmlStart), "Aml Start"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpMutex[6] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpMutex), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Mutex.SyncLevel), "Sync Level"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Mutex.OriginalSyncLevel), "Original Sync Level"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Mutex.OwnerThread), "Owner Thread"},
+ {ACPI_EXD_UINT16, ACPI_EXD_OFFSET (Mutex.AcquisitionDepth), "Acquire Depth"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Mutex.OsMutex), "OsMutex"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpRegion[8] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpRegion), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Region.SpaceId), "Space Id"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Region.Flags), "Flags"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Region.Node), "Parent Node"},
+ {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET (Region.Address), "Address"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Region.Length), "Length"},
+ {ACPI_EXD_HDLR_LIST,ACPI_EXD_OFFSET (Region.Handler), "Handler"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Region.Next), "Next"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpPower[6] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpPower), NULL},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (PowerResource.SystemLevel), "System Level"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (PowerResource.ResourceOrder), "Resource Order"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.NotifyList[1]), "Device Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.Handler), "Handler"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpProcessor[7] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpProcessor), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Processor.ProcId), "Processor ID"},
+ {ACPI_EXD_UINT8 , ACPI_EXD_OFFSET (Processor.Length), "Length"},
+ {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET (Processor.Address), "Address"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.NotifyList[1]), "Device Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.Handler), "Handler"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpThermal[4] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpThermal), NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.NotifyList[1]), "Device Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.Handler), "Handler"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpBufferField[3] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpBufferField), NULL},
+ {ACPI_EXD_FIELD, 0, NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (BufferField.BufferObj), "Buffer Object"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpRegionField[5] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpRegionField), NULL},
+ {ACPI_EXD_FIELD, 0, NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Field.AccessLength), "AccessLength"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Field.RegionObj), "Region Object"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Field.ResourceBuffer), "ResourceBuffer"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpBankField[5] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpBankField), NULL},
+ {ACPI_EXD_FIELD, 0, NULL},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (BankField.Value), "Value"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (BankField.RegionObj), "Region Object"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (BankField.BankObj), "Bank Object"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpIndexField[5] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpBankField), NULL},
+ {ACPI_EXD_FIELD, 0, NULL},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (IndexField.Value), "Value"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (IndexField.IndexObj), "Index Object"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (IndexField.DataObj), "Data Object"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpReference[9] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpReference), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Reference.Class), "Class"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Reference.TargetType), "Target Type"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Reference.Value), "Value"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.Object), "Object Desc"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Reference.Node), "Node"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.Where), "Where"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.IndexPointer), "Index Pointer"},
+ {ACPI_EXD_REFERENCE,0, NULL}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpAddressHandler[6] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpAddressHandler), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (AddressSpace.SpaceId), "Space Id"},
+ {ACPI_EXD_HDLR_LIST,ACPI_EXD_OFFSET (AddressSpace.Next), "Next"},
+ {ACPI_EXD_RGN_LIST, ACPI_EXD_OFFSET (AddressSpace.RegionList), "Region List"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (AddressSpace.Node), "Node"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (AddressSpace.Context), "Context"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpNotify[7] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpNotify), NULL},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Notify.Node), "Node"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Notify.HandlerType), "Handler Type"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Handler), "Handler"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Context), "Context"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Next[0]), "Next System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Next[1]), "Next Device Notify"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpExtra[6] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpExtra), NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Extra.Method_REG), "_REG Method"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (Extra.ScopeNode), "Scope Node"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Extra.RegionContext), "Region Context"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Extra.AmlStart), "Aml Start"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Extra.AmlLength), "Aml Length"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpData[3] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpData), NULL},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Data.Handler), "Handler"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Data.Pointer), "Raw Data"}
+};
+
+/* Miscellaneous tables */
+
+static ACPI_EXDUMP_INFO AcpiExDumpCommon[5] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpCommon), NULL},
+ {ACPI_EXD_TYPE , 0, NULL},
+ {ACPI_EXD_UINT16, ACPI_EXD_OFFSET (Common.ReferenceCount), "Reference Count"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Common.Flags), "Flags"},
+ {ACPI_EXD_LIST, ACPI_EXD_OFFSET (Common.NextObject), "Object List"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpFieldCommon[7] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpFieldCommon), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (CommonField.FieldFlags), "Field Flags"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (CommonField.AccessByteWidth), "Access Byte Width"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (CommonField.BitLength), "Bit Length"},
+ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (CommonField.StartFieldBitOffset),"Field Bit Offset"},
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (CommonField.BaseByteOffset), "Base Byte Offset"},
+ {ACPI_EXD_NODE, ACPI_EXD_OFFSET (CommonField.Node), "Parent Node"}
+};
+
+static ACPI_EXDUMP_INFO AcpiExDumpNode[7] =
+{
+ {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpNode), NULL},
+ {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET (Flags), "Flags"},
+ {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET (OwnerId), "Owner Id"},
+ {ACPI_EXD_LIST, ACPI_EXD_NSOFFSET (Object), "Object List"},
+ {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET (Parent), "Parent"},
+ {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET (Child), "Child"},
+ {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET (Peer), "Peer"}
+};
+
+
+/* Dispatch table, indexed by object type */
+
+static ACPI_EXDUMP_INFO *AcpiExDumpInfo[] =
+{
+ NULL,
+ AcpiExDumpInteger,
+ AcpiExDumpString,
+ AcpiExDumpBuffer,
+ AcpiExDumpPackage,
+ NULL,
+ AcpiExDumpDevice,
+ AcpiExDumpEvent,
+ AcpiExDumpMethod,
+ AcpiExDumpMutex,
+ AcpiExDumpRegion,
+ AcpiExDumpPower,
+ AcpiExDumpProcessor,
+ AcpiExDumpThermal,
+ AcpiExDumpBufferField,
+ NULL,
+ NULL,
+ AcpiExDumpRegionField,
+ AcpiExDumpBankField,
+ AcpiExDumpIndexField,
+ AcpiExDumpReference,
+ NULL,
+ NULL,
+ AcpiExDumpNotify,
+ AcpiExDumpAddressHandler,
+ NULL,
+ NULL,
+ NULL,
+ AcpiExDumpExtra,
+ AcpiExDumpData
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpObject
+ *
+ * PARAMETERS: ObjDesc - Descriptor to dump
+ * Info - Info table corresponding to this object
+ * type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Walk the info table for this object
+ *
+ ******************************************************************************/
+
+static void
+AcpiExDumpObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_EXDUMP_INFO *Info)
+{
+ UINT8 *Target;
+ char *Name;
+ const char *ReferenceName;
+ UINT8 Count;
+ ACPI_OPERAND_OBJECT *Start;
+ ACPI_OPERAND_OBJECT *Data = NULL;
+ ACPI_OPERAND_OBJECT *Next;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if (!Info)
+ {
+ AcpiOsPrintf (
+ "ExDumpObject: Display not implemented for object type %s\n",
+ AcpiUtGetObjectTypeName (ObjDesc));
+ return;
+ }
+
+ /* First table entry must contain the table length (# of table entries) */
+
+ Count = Info->Offset;
+
+ while (Count)
+ {
+ Target = ACPI_ADD_PTR (UINT8, ObjDesc, Info->Offset);
+ Name = Info->Name;
+
+ switch (Info->Opcode)
+ {
+ case ACPI_EXD_INIT:
+
+ break;
+
+ case ACPI_EXD_TYPE:
+
+ AcpiOsPrintf ("%20s : %2.2X [%s]\n", "Type",
+ ObjDesc->Common.Type, AcpiUtGetObjectTypeName (ObjDesc));
+ break;
+
+ case ACPI_EXD_UINT8:
+
+ AcpiOsPrintf ("%20s : %2.2X\n", Name, *Target);
+ break;
+
+ case ACPI_EXD_UINT16:
+
+ AcpiOsPrintf ("%20s : %4.4X\n", Name, ACPI_GET16 (Target));
+ break;
+
+ case ACPI_EXD_UINT32:
+
+ AcpiOsPrintf ("%20s : %8.8X\n", Name, ACPI_GET32 (Target));
+ break;
+
+ case ACPI_EXD_UINT64:
+
+ AcpiOsPrintf ("%20s : %8.8X%8.8X\n", "Value",
+ ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
+ break;
+
+ case ACPI_EXD_POINTER:
+ case ACPI_EXD_ADDRESS:
+
+ AcpiExOutPointer (Name, *ACPI_CAST_PTR (void *, Target));
+ break;
+
+ case ACPI_EXD_STRING:
+
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_EXD_BUFFER:
+
+ ACPI_DUMP_BUFFER (ObjDesc->Buffer.Pointer, ObjDesc->Buffer.Length);
+ break;
+
+ case ACPI_EXD_PACKAGE:
+
+ /* Dump the package contents */
+
+ AcpiOsPrintf ("\nPackage Contents:\n");
+ AcpiExDumpPackageObj (ObjDesc, 0, 0);
+ break;
+
+ case ACPI_EXD_FIELD:
+
+ AcpiExDumpObject (ObjDesc, AcpiExDumpFieldCommon);
+ break;
+
+ case ACPI_EXD_REFERENCE:
+
+ ReferenceName = AcpiUtGetReferenceName (ObjDesc);
+ AcpiExOutString ("Class Name", ACPI_CAST_PTR (char, ReferenceName));
+ AcpiExDumpReferenceObj (ObjDesc);
+ break;
+
+ case ACPI_EXD_LIST:
+
+ Start = *ACPI_CAST_PTR (void *, Target);
+ Next = Start;
+
+ AcpiOsPrintf ("%20s : %p", Name, Next);
+ if (Next)
+ {
+ AcpiOsPrintf ("(%s %2.2X)",
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ while (Next->Common.NextObject)
+ {
+ if ((Next->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ !Data)
+ {
+ Data = Next;
+ }
+
+ Next = Next->Common.NextObject;
+ AcpiOsPrintf ("->%p(%s %2.2X)", Next,
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ if ((Next == Start) || (Next == Data))
+ {
+ AcpiOsPrintf ("\n**** Error: Object list appears to be circular linked");
+ break;
+ }
+ }
+ }
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_EXD_HDLR_LIST:
+
+ Start = *ACPI_CAST_PTR (void *, Target);
+ Next = Start;
+
+ AcpiOsPrintf ("%20s : %p", Name, Next);
+ if (Next)
+ {
+ AcpiOsPrintf ("(%s %2.2X)",
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ while (Next->AddressSpace.Next)
+ {
+ if ((Next->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ !Data)
+ {
+ Data = Next;
+ }
+
+ Next = Next->AddressSpace.Next;
+ AcpiOsPrintf ("->%p(%s %2.2X)", Next,
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ if ((Next == Start) || (Next == Data))
+ {
+ AcpiOsPrintf ("\n**** Error: Handler list appears to be circular linked");
+ break;
+ }
+ }
+ }
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_EXD_RGN_LIST:
+
+ Start = *ACPI_CAST_PTR (void *, Target);
+ Next = Start;
+
+ AcpiOsPrintf ("%20s : %p", Name, Next);
+ if (Next)
+ {
+ AcpiOsPrintf ("(%s %2.2X)",
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ while (Next->Region.Next)
+ {
+ if ((Next->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ !Data)
+ {
+ Data = Next;
+ }
+
+ Next = Next->Region.Next;
+ AcpiOsPrintf ("->%p(%s %2.2X)", Next,
+ AcpiUtGetObjectTypeName (Next), Next->Common.Type);
+
+ if ((Next == Start) || (Next == Data))
+ {
+ AcpiOsPrintf ("\n**** Error: Region list appears to be circular linked");
+ break;
+ }
+ }
+ }
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_EXD_NODE:
+
+ Node = *ACPI_CAST_PTR (ACPI_NAMESPACE_NODE *, Target);
+
+ AcpiOsPrintf ("%20s : %p", Name, Node);
+ if (Node)
+ {
+ AcpiOsPrintf (" [%4.4s]", Node->Name.Ascii);
+ }
+ AcpiOsPrintf ("\n");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n",
+ Info->Opcode);
+ return;
+ }
+
+ Info++;
+ Count--;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpOperand
+ *
+ * PARAMETERS: *ObjDesc - Pointer to entry to be dumped
+ * Depth - Current nesting depth
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an operand object
+ *
+ ******************************************************************************/
+
+void
+AcpiExDumpOperand (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Depth)
+{
+ UINT32 Length;
+ UINT32 Index;
+
+
+ ACPI_FUNCTION_NAME (ExDumpOperand)
+
+
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_EXEC, _COMPONENT))
+ {
+ return;
+ }
+
+ if (!ObjDesc)
+ {
+ /* This could be a null element of a package */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+ return;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p Namespace Node: ", ObjDesc));
+ ACPI_DUMP_ENTRY (ObjDesc, ACPI_LV_EXEC);
+ return;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "%p is not a node or operand object: [%s]\n",
+ ObjDesc, AcpiUtGetDescriptorName (ObjDesc)));
+ ACPI_DUMP_BUFFER (ObjDesc, sizeof (ACPI_OPERAND_OBJECT));
+ return;
+ }
+
+ /* ObjDesc is a valid object */
+
+ if (Depth > 0)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
+ Depth, " ", Depth, ObjDesc));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", ObjDesc));
+ }
+
+ /* Decode object type */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("Reference: [%s] ", AcpiUtGetReferenceName (ObjDesc));
+
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_DEBUG:
+
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_REFCLASS_INDEX:
+
+ AcpiOsPrintf ("%p\n", ObjDesc->Reference.Object);
+ break;
+
+ case ACPI_REFCLASS_TABLE:
+
+ AcpiOsPrintf ("Table Index %X\n", ObjDesc->Reference.Value);
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ AcpiOsPrintf ("%p [%s]\n", ObjDesc->Reference.Object,
+ AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *)
+ ObjDesc->Reference.Object)->Common.Type));
+ break;
+
+ case ACPI_REFCLASS_NAME:
+
+ AcpiOsPrintf ("- [%4.4s]\n", ObjDesc->Reference.Node->Name.Ascii);
+ break;
+
+ case ACPI_REFCLASS_ARG:
+ case ACPI_REFCLASS_LOCAL:
+
+ AcpiOsPrintf ("%X\n", ObjDesc->Reference.Value);
+ break;
+
+ default: /* Unknown reference class */
+
+ AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class);
+ break;
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("Buffer length %.2X @ %p\n",
+ ObjDesc->Buffer.Length, ObjDesc->Buffer.Pointer);
+
+ /* Debug only -- dump the buffer contents */
+
+ if (ObjDesc->Buffer.Pointer)
+ {
+ Length = ObjDesc->Buffer.Length;
+ if (Length > 128)
+ {
+ Length = 128;
+ }
+
+ AcpiOsPrintf ("Buffer Contents: (displaying length 0x%.2X)\n",
+ Length);
+ ACPI_DUMP_BUFFER (ObjDesc->Buffer.Pointer, Length);
+ }
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf ("Integer %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("Package [Len %X] ElementArray %p\n",
+ ObjDesc->Package.Count, ObjDesc->Package.Elements);
+
+ /*
+ * If elements exist, package element pointer is valid,
+ * and debug_level exceeds 1, dump package's elements.
+ */
+ if (ObjDesc->Package.Count &&
+ ObjDesc->Package.Elements &&
+ AcpiDbgLevel > 1)
+ {
+ for (Index = 0; Index < ObjDesc->Package.Count; Index++)
+ {
+ AcpiExDumpOperand (ObjDesc->Package.Elements[Index], Depth+1);
+ }
+ }
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ AcpiOsPrintf ("Region %s (%X)",
+ AcpiUtGetRegionName (ObjDesc->Region.SpaceId),
+ ObjDesc->Region.SpaceId);
+
+ /*
+ * If the address and length have not been evaluated,
+ * don't print them.
+ */
+ if (!(ObjDesc->Region.Flags & AOPOBJ_DATA_VALID))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ else
+ {
+ AcpiOsPrintf (" base %8.8X%8.8X Length %X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
+ ObjDesc->Region.Length);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("String length %X @ %p ",
+ ObjDesc->String.Length,
+ ObjDesc->String.Pointer);
+
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ AcpiOsPrintf ("BankField\n");
+ break;
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ AcpiOsPrintf ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+ "byte=%X bit=%X of below:\n",
+ ObjDesc->Field.BitLength,
+ ObjDesc->Field.AccessByteWidth,
+ ObjDesc->Field.FieldFlags & AML_FIELD_LOCK_RULE_MASK,
+ ObjDesc->Field.FieldFlags & AML_FIELD_UPDATE_RULE_MASK,
+ ObjDesc->Field.BaseByteOffset,
+ ObjDesc->Field.StartFieldBitOffset);
+
+ AcpiExDumpOperand (ObjDesc->Field.RegionObj, Depth+1);
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ AcpiOsPrintf ("IndexField\n");
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ AcpiOsPrintf ("BufferField: %X bits at byte %X bit %X of\n",
+ ObjDesc->BufferField.BitLength,
+ ObjDesc->BufferField.BaseByteOffset,
+ ObjDesc->BufferField.StartFieldBitOffset);
+
+ if (!ObjDesc->BufferField.BufferObj)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL*\n"));
+ }
+ else if ((ObjDesc->BufferField.BufferObj)->Common.Type !=
+ ACPI_TYPE_BUFFER)
+ {
+ AcpiOsPrintf ("*not a Buffer*\n");
+ }
+ else
+ {
+ AcpiExDumpOperand (ObjDesc->BufferField.BufferObj, Depth+1);
+ }
+ break;
+
+ case ACPI_TYPE_EVENT:
+
+ AcpiOsPrintf ("Event\n");
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ AcpiOsPrintf ("Method(%X) @ %p:%X\n",
+ ObjDesc->Method.ParamCount,
+ ObjDesc->Method.AmlStart,
+ ObjDesc->Method.AmlLength);
+ break;
+
+ case ACPI_TYPE_MUTEX:
+
+ AcpiOsPrintf ("Mutex\n");
+ break;
+
+ case ACPI_TYPE_DEVICE:
+
+ AcpiOsPrintf ("Device\n");
+ break;
+
+ case ACPI_TYPE_POWER:
+
+ AcpiOsPrintf ("Power\n");
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiOsPrintf ("Processor\n");
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ AcpiOsPrintf ("Thermal\n");
+ break;
+
+ default:
+
+ /* Unknown Type */
+
+ AcpiOsPrintf ("Unknown Type %X\n", ObjDesc->Common.Type);
+ break;
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpOperands
+ *
+ * PARAMETERS: Operands - A list of Operand objects
+ * OpcodeName - AML opcode name
+ * NumOperands - Operand count for this opcode
+ *
+ * DESCRIPTION: Dump the operands associated with the opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiExDumpOperands (
+ ACPI_OPERAND_OBJECT **Operands,
+ const char *OpcodeName,
+ UINT32 NumOperands)
+{
+ ACPI_FUNCTION_NAME (ExDumpOperands);
+
+
+ if (!OpcodeName)
+ {
+ OpcodeName = "UNKNOWN";
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "**** Start operand dump for opcode [%s], %u operands\n",
+ OpcodeName, NumOperands));
+
+ if (NumOperands == 0)
+ {
+ NumOperands = 1;
+ }
+
+ /* Dump the individual operands */
+
+ while (NumOperands)
+ {
+ AcpiExDumpOperand (*Operands, 0);
+ Operands++;
+ NumOperands--;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "**** End operand dump for [%s]\n", OpcodeName));
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOut* functions
+ *
+ * PARAMETERS: Title - Descriptive text
+ * Value - Value to be displayed
+ *
+ * DESCRIPTION: Object dump output formatting functions. These functions
+ * reduce the number of format strings required and keeps them
+ * all in one place for easy modification.
+ *
+ ******************************************************************************/
+
+static void
+AcpiExOutString (
+ char *Title,
+ char *Value)
+{
+ AcpiOsPrintf ("%20s : %s\n", Title, Value);
+}
+
+static void
+AcpiExOutPointer (
+ char *Title,
+ void *Value)
+{
+ AcpiOsPrintf ("%20s : %p\n", Title, Value);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpNamespaceNode
+ *
+ * PARAMETERS: Node - Descriptor to dump
+ * Flags - Force display if TRUE
+ *
+ * DESCRIPTION: Dumps the members of the given.Node
+ *
+ ******************************************************************************/
+
+void
+AcpiExDumpNamespaceNode (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 Flags)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!Flags)
+ {
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_OBJECTS, _COMPONENT))
+ {
+ return;
+ }
+ }
+
+ AcpiOsPrintf ("%20s : %4.4s\n", "Name", AcpiUtGetNodeName (Node));
+ AcpiOsPrintf ("%20s : %2.2X [%s]\n", "Type",
+ Node->Type, AcpiUtGetTypeName (Node->Type));
+
+ AcpiExDumpObject (ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node),
+ AcpiExDumpNode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpReferenceObj
+ *
+ * PARAMETERS: Object - Descriptor to dump
+ *
+ * DESCRIPTION: Dumps a reference object
+ *
+ ******************************************************************************/
+
+static void
+AcpiExDumpReferenceObj (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_BUFFER RetBuf;
+ ACPI_STATUS Status;
+
+
+ RetBuf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ if (ObjDesc->Reference.Class == ACPI_REFCLASS_NAME)
+ {
+ AcpiOsPrintf (" %p ", ObjDesc->Reference.Node);
+
+ Status = AcpiNsHandleToPathname (ObjDesc->Reference.Node,
+ &RetBuf, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf (" Could not convert name to pathname\n");
+ }
+ else
+ {
+ AcpiOsPrintf ("%s\n", (char *) RetBuf.Pointer);
+ ACPI_FREE (RetBuf.Pointer);
+ }
+ }
+ else if (ObjDesc->Reference.Object)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf ("%22s %p", "Target :",
+ ObjDesc->Reference.Object);
+ if (ObjDesc->Reference.Class == ACPI_REFCLASS_TABLE)
+ {
+ AcpiOsPrintf (" Table Index: %X\n",
+ ObjDesc->Reference.Value);
+ }
+ else
+ {
+ AcpiOsPrintf (" [%s]\n",
+ AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *)
+ ObjDesc->Reference.Object)->Common.Type));
+ }
+ }
+ else
+ {
+ AcpiOsPrintf (" Target: %p\n", ObjDesc->Reference.Object);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpPackageObj
+ *
+ * PARAMETERS: ObjDesc - Descriptor to dump
+ * Level - Indentation Level
+ * Index - Package index for this object
+ *
+ * DESCRIPTION: Dumps the elements of the package
+ *
+ ******************************************************************************/
+
+static void
+AcpiExDumpPackageObj (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Level,
+ UINT32 Index)
+{
+ UINT32 i;
+
+
+ /* Indentation and index output */
+
+ if (Level > 0)
+ {
+ for (i = 0; i < Level; i++)
+ {
+ AcpiOsPrintf (" ");
+ }
+
+ AcpiOsPrintf ("[%.2d] ", Index);
+ }
+
+ AcpiOsPrintf ("%p ", ObjDesc);
+
+ /* Null package elements are allowed */
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("[Null Object]\n");
+ return;
+ }
+
+ /* Packages may only contain a few object types */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("[String] Value: ");
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
+ if (ObjDesc->Buffer.Length)
+ {
+ AcpiUtDebugDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
+ ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT);
+ }
+ else
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("[Package] Contains %u Elements:\n",
+ ObjDesc->Package.Count);
+
+ for (i = 0; i < ObjDesc->Package.Count; i++)
+ {
+ AcpiExDumpPackageObj (ObjDesc->Package.Elements[i], Level+1, i);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[Object Reference] Type [%s] %2.2X",
+ AcpiUtGetReferenceName (ObjDesc),
+ ObjDesc->Reference.Class);
+ AcpiExDumpReferenceObj (ObjDesc);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Common.Type);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDumpObjectDescriptor
+ *
+ * PARAMETERS: ObjDesc - Descriptor to dump
+ * Flags - Force display if TRUE
+ *
+ * DESCRIPTION: Dumps the members of the object descriptor given.
+ *
+ ******************************************************************************/
+
+void
+AcpiExDumpObjectDescriptor (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Flags)
+{
+ ACPI_FUNCTION_TRACE (ExDumpObjectDescriptor);
+
+
+ if (!ObjDesc)
+ {
+ return_VOID;
+ }
+
+ if (!Flags)
+ {
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_OBJECTS, _COMPONENT))
+ {
+ return_VOID;
+ }
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiExDumpNamespaceNode ((ACPI_NAMESPACE_NODE *) ObjDesc, Flags);
+
+ AcpiOsPrintf ("\nAttached Object (%p):\n",
+ ((ACPI_NAMESPACE_NODE *) ObjDesc)->Object);
+
+ ObjDesc = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Object;
+ goto DumpObject;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf (
+ "%p is not an ACPI operand object: [%s]\n",
+ ObjDesc, AcpiUtGetDescriptorName (ObjDesc));
+ return_VOID;
+ }
+
+ /* Validate the object type */
+
+ if (ObjDesc->Common.Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf ("Not a known object type: %2.2X\n",
+ ObjDesc->Common.Type);
+ return_VOID;
+ }
+
+
+DumpObject:
+
+ /* Common Fields */
+
+ AcpiExDumpObject (ObjDesc, AcpiExDumpCommon);
+
+ /* Object-specific fields */
+
+ AcpiExDumpObject (ObjDesc, AcpiExDumpInfo[ObjDesc->Common.Type]);
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_REGION)
+ {
+ ObjDesc = ObjDesc->Common.NextObject;
+ if (ObjDesc->Common.Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf ("Secondary object is not a known object type: %2.2X\n",
+ ObjDesc->Common.Type);
+
+ return_VOID;
+ }
+
+ AcpiOsPrintf ("\nExtra attached Object (%p):\n", ObjDesc);
+ AcpiExDumpObject (ObjDesc, AcpiExDumpInfo[ObjDesc->Common.Type]);
+ }
+
+ return_VOID;
+}
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfield.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfield.c
new file mode 100644
index 0000000000..ad2d05ad4c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfield.c
@@ -0,0 +1,566 @@
+/******************************************************************************
+ *
+ * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exfield")
+
+/* Local prototypes */
+
+static UINT32
+AcpiExGetSerialAccessLength (
+ UINT32 AccessorType,
+ UINT32 AccessLength);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGetSerialAccessLength
+ *
+ * PARAMETERS: AccessorType - The type of the protocol indicated by region
+ * field access attributes
+ * AccessLength - The access length of the region field
+ *
+ * RETURN: Decoded access length
+ *
+ * DESCRIPTION: This routine returns the length of the GenericSerialBus
+ * protocol bytes
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiExGetSerialAccessLength (
+ UINT32 AccessorType,
+ UINT32 AccessLength)
+{
+ UINT32 Length;
+
+
+ switch (AccessorType)
+ {
+ case AML_FIELD_ATTRIB_QUICK:
+
+ Length = 0;
+ break;
+
+ case AML_FIELD_ATTRIB_SEND_RCV:
+ case AML_FIELD_ATTRIB_BYTE:
+
+ Length = 1;
+ break;
+
+ case AML_FIELD_ATTRIB_WORD:
+ case AML_FIELD_ATTRIB_WORD_CALL:
+
+ Length = 2;
+ break;
+
+ case AML_FIELD_ATTRIB_MULTIBYTE:
+ case AML_FIELD_ATTRIB_RAW_BYTES:
+ case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+ Length = AccessLength;
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK:
+ case AML_FIELD_ATTRIB_BLOCK_CALL:
+ default:
+
+ Length = ACPI_GSBUS_BUFFER_SIZE - 2;
+ break;
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReadDataFromField
+ *
+ * PARAMETERS: WalkState - Current execution state
+ * ObjDesc - The named field
+ * RetBufferDesc - Where the return data object is stored
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from a named field. Returns either an Integer or a
+ * Buffer, depending on the size of the field.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReadDataFromField (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **RetBufferDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *BufferDesc;
+ ACPI_SIZE Length;
+ void *Buffer;
+ UINT32 Function;
+ UINT16 AccessorType;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExReadDataFromField, ObjDesc);
+
+
+ /* Parameter validation */
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+ if (!RetBufferDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
+ {
+ /*
+ * If the BufferField arguments have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+ else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
+ ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS ||
+ ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
+ {
+ /*
+ * This is an SMBus, GSBus or IPMI read. We must create a buffer to hold
+ * the data and then directly access the region handler.
+ *
+ * Note: SMBus and GSBus protocol value is passed in upper 16-bits of Function
+ */
+ if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
+ {
+ Length = ACPI_SMBUS_BUFFER_SIZE;
+ Function = ACPI_READ | (ObjDesc->Field.Attribute << 16);
+ }
+ else if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS)
+ {
+ AccessorType = ObjDesc->Field.Attribute;
+ Length = AcpiExGetSerialAccessLength (AccessorType,
+ ObjDesc->Field.AccessLength);
+
+ /*
+ * Add additional 2 bytes for the GenericSerialBus data buffer:
+ *
+ * Status; (Byte 0 of the data buffer)
+ * Length; (Byte 1 of the data buffer)
+ * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
+ */
+ Length += 2;
+ Function = ACPI_READ | (AccessorType << 16);
+ }
+ else /* IPMI */
+ {
+ Length = ACPI_IPMI_BUFFER_SIZE;
+ Function = ACPI_READ;
+ }
+
+ BufferDesc = AcpiUtCreateBufferObject (Length);
+ if (!BufferDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /* Call the region handler for the read */
+
+ Status = AcpiExAccessRegion (ObjDesc, 0,
+ ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer),
+ Function);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+ goto Exit;
+ }
+
+ /*
+ * Allocate a buffer for the contents of the field.
+ *
+ * If the field is larger than the current integer width, create
+ * a BUFFER to hold it. Otherwise, use an INTEGER. This allows
+ * the use of arithmetic operators on the returned value if the
+ * field size is equal or smaller than an Integer.
+ *
+ * Note: Field.length is in bits.
+ */
+ Length = (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->Field.BitLength);
+ if (Length > AcpiGbl_IntegerByteWidth)
+ {
+ /* Field is too large for an Integer, create a Buffer instead */
+
+ BufferDesc = AcpiUtCreateBufferObject (Length);
+ if (!BufferDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ Buffer = BufferDesc->Buffer.Pointer;
+ }
+ else
+ {
+ /* Field will fit within an Integer (normal case) */
+
+ BufferDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!BufferDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Length = AcpiGbl_IntegerByteWidth;
+ Buffer = &BufferDesc->Integer.Value;
+ }
+
+ if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO))
+ {
+ /*
+ * For GPIO (GeneralPurposeIo), the Address will be the bit offset
+ * from the previous Connection() operator, making it effectively a
+ * pin number index. The BitLength is the length of the field, which
+ * is thus the number of pins.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "GPIO FieldRead [FROM]: Pin %u Bits %u\n",
+ ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength));
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /* Perform the write */
+
+ Status = AcpiExAccessRegion (ObjDesc, 0,
+ (UINT64 *) Buffer, ACPI_READ);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (BufferDesc);
+ }
+ else
+ {
+ *RetBufferDesc = BufferDesc;
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
+ ObjDesc, ObjDesc->Common.Type, Buffer, (UINT32) Length));
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
+ ObjDesc->CommonField.BitLength,
+ ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BaseByteOffset));
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /* Read from the field */
+
+ Status = AcpiExExtractFromField (ObjDesc, Buffer, (UINT32) Length);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+
+Exit:
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (BufferDesc);
+ }
+ else
+ {
+ *RetBufferDesc = BufferDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExWriteDataToField
+ *
+ * PARAMETERS: SourceDesc - Contains data to write
+ * ObjDesc - The named field
+ * ResultDesc - Where the return value is returned, if any
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to a named field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExWriteDataToField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc)
+{
+ ACPI_STATUS Status;
+ UINT32 Length;
+ void *Buffer;
+ ACPI_OPERAND_OBJECT *BufferDesc;
+ UINT32 Function;
+ UINT16 AccessorType;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExWriteDataToField, ObjDesc);
+
+
+ /* Parameter validation */
+
+ if (!SourceDesc || !ObjDesc)
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
+ {
+ /*
+ * If the BufferField arguments have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+ else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
+ ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS ||
+ ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
+ {
+ /*
+ * This is an SMBus, GSBus or IPMI write. We will bypass the entire field
+ * mechanism and handoff the buffer directly to the handler. For
+ * these address spaces, the buffer is bi-directional; on a write,
+ * return data is returned in the same buffer.
+ *
+ * Source must be a buffer of sufficient size:
+ * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE.
+ *
+ * Note: SMBus and GSBus protocol type is passed in upper 16-bits of Function
+ */
+ if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "SMBus/IPMI/GenericSerialBus write requires Buffer, found type %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
+ {
+ Length = ACPI_SMBUS_BUFFER_SIZE;
+ Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16);
+ }
+ else if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS)
+ {
+ AccessorType = ObjDesc->Field.Attribute;
+ Length = AcpiExGetSerialAccessLength (AccessorType,
+ ObjDesc->Field.AccessLength);
+
+ /*
+ * Add additional 2 bytes for the GenericSerialBus data buffer:
+ *
+ * Status; (Byte 0 of the data buffer)
+ * Length; (Byte 1 of the data buffer)
+ * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
+ */
+ Length += 2;
+ Function = ACPI_WRITE | (AccessorType << 16);
+ }
+ else /* IPMI */
+ {
+ Length = ACPI_IPMI_BUFFER_SIZE;
+ Function = ACPI_WRITE;
+ }
+
+ if (SourceDesc->Buffer.Length < Length)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "SMBus/IPMI/GenericSerialBus write requires Buffer of length %u, found length %u",
+ Length, SourceDesc->Buffer.Length));
+
+ return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+ }
+
+ /* Create the bi-directional buffer */
+
+ BufferDesc = AcpiUtCreateBufferObject (Length);
+ if (!BufferDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Buffer = BufferDesc->Buffer.Pointer;
+ memcpy (Buffer, SourceDesc->Buffer.Pointer, Length);
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /*
+ * Perform the write (returns status and perhaps data in the
+ * same buffer)
+ */
+ Status = AcpiExAccessRegion (ObjDesc, 0,
+ (UINT64 *) Buffer, Function);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ *ResultDesc = BufferDesc;
+ return_ACPI_STATUS (Status);
+ }
+ else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO))
+ {
+ /*
+ * For GPIO (GeneralPurposeIo), we will bypass the entire field
+ * mechanism and handoff the bit address and bit width directly to
+ * the handler. The Address will be the bit offset
+ * from the previous Connection() operator, making it effectively a
+ * pin number index. The BitLength is the length of the field, which
+ * is thus the number of pins.
+ */
+ if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n",
+ AcpiUtGetTypeName (SourceDesc->Common.Type),
+ SourceDesc->Common.Type, (UINT32) SourceDesc->Integer.Value,
+ ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength));
+
+ Buffer = &SourceDesc->Integer.Value;
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /* Perform the write */
+
+ Status = AcpiExAccessRegion (ObjDesc, 0,
+ (UINT64 *) Buffer, ACPI_WRITE);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get a pointer to the data to be written */
+
+ switch (SourceDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ Buffer = &SourceDesc->Integer.Value;
+ Length = sizeof (SourceDesc->Integer.Value);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Buffer = SourceDesc->Buffer.Pointer;
+ Length = SourceDesc->Buffer.Length;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Buffer = SourceDesc->String.Pointer;
+ Length = SourceDesc->String.Length;
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
+ SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type),
+ SourceDesc->Common.Type, Buffer, Length));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
+ ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type),
+ ObjDesc->Common.Type,
+ ObjDesc->CommonField.BitLength,
+ ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BaseByteOffset));
+
+ /* Lock entire transaction if requested */
+
+ AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ /* Write to the field */
+
+ Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length);
+ AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfldio.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfldio.c
new file mode 100644
index 0000000000..31727de90a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exfldio.c
@@ -0,0 +1,1054 @@
+/******************************************************************************
+ *
+ * Module Name: exfldio - Aml Field I/O
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exfldio")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiExFieldDatumIo (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset,
+ UINT64 *Value,
+ UINT32 ReadWrite);
+
+static BOOLEAN
+AcpiExRegisterOverflow (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT64 Value);
+
+static ACPI_STATUS
+AcpiExSetupRegion (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSetupRegion
+ *
+ * PARAMETERS: ObjDesc - Field to be read or written
+ * FieldDatumByteOffset - Byte offset of this datum within the
+ * parent field
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common processing for AcpiExExtractFromField and
+ * AcpiExInsertIntoField. Initialize the Region if necessary and
+ * validate the request.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExSetupRegion (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *RgnDesc;
+ UINT8 SpaceId;
+
+
+ ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
+
+
+ RgnDesc = ObjDesc->CommonField.RegionObj;
+
+ /* We must have a valid region */
+
+ if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
+ {
+ ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
+ RgnDesc->Common.Type,
+ AcpiUtGetObjectTypeName (RgnDesc)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ SpaceId = RgnDesc->Region.SpaceId;
+
+ /* Validate the Space ID */
+
+ if (!AcpiIsValidSpaceId (SpaceId))
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
+ return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
+ }
+
+ /*
+ * If the Region Address and Length have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetRegionArguments (RgnDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
+ * address space and the request cannot be directly validated
+ */
+ if (SpaceId == ACPI_ADR_SPACE_SMBUS ||
+ SpaceId == ACPI_ADR_SPACE_GSBUS ||
+ SpaceId == ACPI_ADR_SPACE_IPMI)
+ {
+ /* SMBus or IPMI has a non-linear address space */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+ /*
+ * If the Field access is AnyAcc, we can now compute the optimal
+ * access (because we know know the length of the parent region)
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+#endif
+
+ /*
+ * Validate the request. The entire request from the byte offset for a
+ * length of one field datum (access width) must fit within the region.
+ * (Region length is specified in bytes)
+ */
+ if (RgnDesc->Region.Length <
+ (ObjDesc->CommonField.BaseByteOffset + FieldDatumByteOffset +
+ ObjDesc->CommonField.AccessByteWidth))
+ {
+ if (AcpiGbl_EnableInterpreterSlack)
+ {
+ /*
+ * Slack mode only: We will go ahead and allow access to this
+ * field if it is within the region length rounded up to the next
+ * access width boundary. ACPI_SIZE cast for 64-bit compile.
+ */
+ if (ACPI_ROUND_UP (RgnDesc->Region.Length,
+ ObjDesc->CommonField.AccessByteWidth) >=
+ ((ACPI_SIZE) ObjDesc->CommonField.BaseByteOffset +
+ ObjDesc->CommonField.AccessByteWidth +
+ FieldDatumByteOffset))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ if (RgnDesc->Region.Length < ObjDesc->CommonField.AccessByteWidth)
+ {
+ /*
+ * This is the case where the AccessType (AccWord, etc.) is wider
+ * than the region itself. For example, a region of length one
+ * byte, and a field with Dword access specified.
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
+ AcpiUtGetNodeName (ObjDesc->CommonField.Node),
+ ObjDesc->CommonField.AccessByteWidth,
+ AcpiUtGetNodeName (RgnDesc->Region.Node),
+ RgnDesc->Region.Length));
+ }
+
+ /*
+ * Offset rounded up to next multiple of field width
+ * exceeds region length, indicate an error
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Field [%4.4s] Base+Offset+Width %u+%u+%u is beyond end of region [%4.4s] (length %u)",
+ AcpiUtGetNodeName (ObjDesc->CommonField.Node),
+ ObjDesc->CommonField.BaseByteOffset,
+ FieldDatumByteOffset, ObjDesc->CommonField.AccessByteWidth,
+ AcpiUtGetNodeName (RgnDesc->Region.Node),
+ RgnDesc->Region.Length));
+
+ return_ACPI_STATUS (AE_AML_REGION_LIMIT);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAccessRegion
+ *
+ * PARAMETERS: ObjDesc - Field to be read
+ * FieldDatumByteOffset - Byte offset of this datum within the
+ * parent field
+ * Value - Where to store value (must at least
+ * 64 bits)
+ * Function - Read or Write flag plus other region-
+ * dependent flags
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read or Write a single field datum to an Operation Region.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExAccessRegion (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset,
+ UINT64 *Value,
+ UINT32 Function)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *RgnDesc;
+ UINT32 RegionOffset;
+
+
+ ACPI_FUNCTION_TRACE (ExAccessRegion);
+
+
+ /*
+ * Ensure that the region operands are fully evaluated and verify
+ * the validity of the request
+ */
+ Status = AcpiExSetupRegion (ObjDesc, FieldDatumByteOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * The physical address of this field datum is:
+ *
+ * 1) The base of the region, plus
+ * 2) The base offset of the field, plus
+ * 3) The current offset into the field
+ */
+ RgnDesc = ObjDesc->CommonField.RegionObj;
+ RegionOffset =
+ ObjDesc->CommonField.BaseByteOffset +
+ FieldDatumByteOffset;
+
+ if ((Function & ACPI_IO_MASK) == ACPI_READ)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
+ " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId,
+ ObjDesc->CommonField.AccessByteWidth,
+ ObjDesc->CommonField.BaseByteOffset,
+ FieldDatumByteOffset,
+ ACPI_FORMAT_UINT64 (RgnDesc->Region.Address + RegionOffset)));
+
+ /* Invoke the appropriate AddressSpace/OpRegion handler */
+
+ Status = AcpiEvAddressSpaceDispatch (RgnDesc, ObjDesc,
+ Function, RegionOffset,
+ ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
+
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_IMPLEMENTED)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Region %s (ID=%u) not implemented",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+ else if (Status == AE_NOT_EXIST)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Region %s (ID=%u) has no handler",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExRegisterOverflow
+ *
+ * PARAMETERS: ObjDesc - Register(Field) to be written
+ * Value - Value to be stored
+ *
+ * RETURN: TRUE if value overflows the field, FALSE otherwise
+ *
+ * DESCRIPTION: Check if a value is out of range of the field being written.
+ * Used to check if the values written to Index and Bank registers
+ * are out of range. Normally, the value is simply truncated
+ * to fit the field, but this case is most likely a serious
+ * coding error in the ASL.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiExRegisterOverflow (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT64 Value)
+{
+
+ if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE)
+ {
+ /*
+ * The field is large enough to hold the maximum integer, so we can
+ * never overflow it.
+ */
+ return (FALSE);
+ }
+
+ if (Value >= ((UINT64) 1 << ObjDesc->CommonField.BitLength))
+ {
+ /*
+ * The Value is larger than the maximum value that can fit into
+ * the register.
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Index value 0x%8.8X%8.8X overflows field width 0x%X",
+ ACPI_FORMAT_UINT64 (Value),
+ ObjDesc->CommonField.BitLength));
+
+ return (TRUE);
+ }
+
+ /* The Value will fit into the field with no truncation */
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExFieldDatumIo
+ *
+ * PARAMETERS: ObjDesc - Field to be read
+ * FieldDatumByteOffset - Byte offset of this datum within the
+ * parent field
+ * Value - Where to store value (must be 64 bits)
+ * ReadWrite - Read or Write flag
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read or Write a single datum of a field. The FieldType is
+ * demultiplexed here to handle the different types of fields
+ * (BufferField, RegionField, IndexField, BankField)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExFieldDatumIo (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset,
+ UINT64 *Value,
+ UINT32 ReadWrite)
+{
+ ACPI_STATUS Status;
+ UINT64 LocalValue;
+
+
+ ACPI_FUNCTION_TRACE_U32 (ExFieldDatumIo, FieldDatumByteOffset);
+
+
+ if (ReadWrite == ACPI_READ)
+ {
+ if (!Value)
+ {
+ LocalValue = 0;
+
+ /* To support reads without saving return value */
+ Value = &LocalValue;
+ }
+
+ /* Clear the entire return buffer first, [Very Important!] */
+
+ *Value = 0;
+ }
+
+ /*
+ * The four types of fields are:
+ *
+ * BufferField - Read/write from/to a Buffer
+ * RegionField - Read/write from/to a Operation Region.
+ * BankField - Write to a Bank Register, then read/write from/to an
+ * OperationRegion
+ * IndexField - Write to an Index Register, then read/write from/to a
+ * Data Register
+ */
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+ /*
+ * If the BufferField arguments have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ if (ReadWrite == ACPI_READ)
+ {
+ /*
+ * Copy the data from the source buffer.
+ * Length is the field width in bytes.
+ */
+ memcpy (Value,
+ (ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
+ ObjDesc->BufferField.BaseByteOffset +
+ FieldDatumByteOffset,
+ ObjDesc->CommonField.AccessByteWidth);
+ }
+ else
+ {
+ /*
+ * Copy the data to the target buffer.
+ * Length is the field width in bytes.
+ */
+ memcpy ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
+ ObjDesc->BufferField.BaseByteOffset +
+ FieldDatumByteOffset,
+ Value, ObjDesc->CommonField.AccessByteWidth);
+ }
+
+ Status = AE_OK;
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ /*
+ * Ensure that the BankValue is not beyond the capacity of
+ * the register
+ */
+ if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,
+ (UINT64) ObjDesc->BankField.Value))
+ {
+ return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+ }
+
+ /*
+ * For BankFields, we must write the BankValue to the BankRegister
+ * (itself a RegionField) before we can access the data.
+ */
+ Status = AcpiExInsertIntoField (ObjDesc->BankField.BankObj,
+ &ObjDesc->BankField.Value,
+ sizeof (ObjDesc->BankField.Value));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Now that the Bank has been selected, fall through to the
+ * RegionField case and write the datum to the Operation Region
+ */
+
+ /*lint -fallthrough */
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ /*
+ * For simple RegionFields, we just directly access the owning
+ * Operation Region.
+ */
+ Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
+ ReadWrite);
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ /*
+ * Ensure that the IndexValue is not beyond the capacity of
+ * the register
+ */
+ if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,
+ (UINT64) ObjDesc->IndexField.Value))
+ {
+ return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+ }
+
+ /* Write the index value to the IndexRegister (itself a RegionField) */
+
+ FieldDatumByteOffset += ObjDesc->IndexField.Value;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Write to Index Register: Value %8.8X\n",
+ FieldDatumByteOffset));
+
+ Status = AcpiExInsertIntoField (ObjDesc->IndexField.IndexObj,
+ &FieldDatumByteOffset,
+ sizeof (FieldDatumByteOffset));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ReadWrite == ACPI_READ)
+ {
+ /* Read the datum from the DataRegister */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Read from Data Register\n"));
+
+ Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj,
+ Value, sizeof (UINT64));
+ }
+ else
+ {
+ /* Write the datum to the DataRegister */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Write to Data Register: Value %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (*Value)));
+
+ Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
+ Value, sizeof (UINT64));
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
+ ObjDesc->Common.Type));
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ if (ReadWrite == ACPI_READ)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Value Read %8.8X%8.8X, Width %u\n",
+ ACPI_FORMAT_UINT64 (*Value),
+ ObjDesc->CommonField.AccessByteWidth));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Value Written %8.8X%8.8X, Width %u\n",
+ ACPI_FORMAT_UINT64 (*Value),
+ ObjDesc->CommonField.AccessByteWidth));
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExWriteWithUpdateRule
+ *
+ * PARAMETERS: ObjDesc - Field to be written
+ * Mask - bitmask within field datum
+ * FieldValue - Value to write
+ * FieldDatumByteOffset - Offset of datum within field
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Apply the field update rule to a field write
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExWriteWithUpdateRule (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT64 Mask,
+ UINT64 FieldValue,
+ UINT32 FieldDatumByteOffset)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT64 MergedValue;
+ UINT64 CurrentValue;
+
+
+ ACPI_FUNCTION_TRACE_U32 (ExWriteWithUpdateRule, Mask);
+
+
+ /* Start with the new bits */
+
+ MergedValue = FieldValue;
+
+ /* If the mask is all ones, we don't need to worry about the update rule */
+
+ if (Mask != ACPI_UINT64_MAX)
+ {
+ /* Decode the update rule */
+
+ switch (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)
+ {
+ case AML_FIELD_UPDATE_PRESERVE:
+ /*
+ * Check if update rule needs to be applied (not if mask is all
+ * ones) The left shift drops the bits we want to ignore.
+ */
+ if ((~Mask << (ACPI_MUL_8 (sizeof (Mask)) -
+ ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth))) != 0)
+ {
+ /*
+ * Read the current contents of the byte/word/dword containing
+ * the field, and merge with the new field value.
+ */
+ Status = AcpiExFieldDatumIo (ObjDesc, FieldDatumByteOffset,
+ &CurrentValue, ACPI_READ);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ MergedValue |= (CurrentValue & ~Mask);
+ }
+ break;
+
+ case AML_FIELD_UPDATE_WRITE_AS_ONES:
+
+ /* Set positions outside the field to all ones */
+
+ MergedValue |= ~Mask;
+ break;
+
+ case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
+
+ /* Set positions outside the field to all zeros */
+
+ MergedValue &= Mask;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown UpdateRule value: 0x%X",
+ (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)));
+ return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (Mask),
+ FieldDatumByteOffset,
+ ObjDesc->CommonField.AccessByteWidth,
+ ACPI_FORMAT_UINT64 (FieldValue),
+ ACPI_FORMAT_UINT64 (MergedValue)));
+
+ /* Write the merged value */
+
+ Status = AcpiExFieldDatumIo (ObjDesc, FieldDatumByteOffset,
+ &MergedValue, ACPI_WRITE);
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExExtractFromField
+ *
+ * PARAMETERS: ObjDesc - Field to be read
+ * Buffer - Where to store the field data
+ * BufferLength - Length of Buffer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve the current value of the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExExtractFromField (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ void *Buffer,
+ UINT32 BufferLength)
+{
+ ACPI_STATUS Status;
+ UINT64 RawDatum;
+ UINT64 MergedDatum;
+ UINT32 FieldOffset = 0;
+ UINT32 BufferOffset = 0;
+ UINT32 BufferTailBits;
+ UINT32 DatumCount;
+ UINT32 FieldDatumCount;
+ UINT32 AccessBitWidth;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (ExExtractFromField);
+
+
+ /* Validate target buffer and clear it */
+
+ if (BufferLength <
+ ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Field size %u (bits) is too large for buffer (%u)",
+ ObjDesc->CommonField.BitLength, BufferLength));
+
+ return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ }
+
+ memset (Buffer, 0, BufferLength);
+ AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
+
+ /* Handle the simple case here */
+
+ if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
+ (ObjDesc->CommonField.BitLength == AccessBitWidth))
+ {
+ if (BufferLength >= sizeof (UINT64))
+ {
+ Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
+ }
+ else
+ {
+ /* Use RawDatum (UINT64) to handle buffers < 64 bits */
+
+ Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
+ memcpy (Buffer, &RawDatum, BufferLength);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+/* TBD: Move to common setup code */
+
+ /* Field algorithm is limited to sizeof(UINT64), truncate if needed */
+
+ if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
+ {
+ ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
+ AccessBitWidth = sizeof (UINT64) * 8;
+ }
+
+ /* Compute the number of datums (access width data items) */
+
+ DatumCount = ACPI_ROUND_UP_TO (
+ ObjDesc->CommonField.BitLength, AccessBitWidth);
+
+ FieldDatumCount = ACPI_ROUND_UP_TO (
+ ObjDesc->CommonField.BitLength +
+ ObjDesc->CommonField.StartFieldBitOffset, AccessBitWidth);
+
+ /* Priming read from the field */
+
+ Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset, &RawDatum, ACPI_READ);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
+
+ /* Read the rest of the field */
+
+ for (i = 1; i < FieldDatumCount; i++)
+ {
+ /* Get next input datum from the field */
+
+ FieldOffset += ObjDesc->CommonField.AccessByteWidth;
+ Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset,
+ &RawDatum, ACPI_READ);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Merge with previous datum if necessary.
+ *
+ * Note: Before the shift, check if the shift value will be larger than
+ * the integer size. If so, there is no need to perform the operation.
+ * This avoids the differences in behavior between different compilers
+ * concerning shift values larger than the target data width.
+ */
+ if (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset <
+ ACPI_INTEGER_BIT_SIZE)
+ {
+ MergedDatum |= RawDatum <<
+ (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
+ }
+
+ if (i == DatumCount)
+ {
+ break;
+ }
+
+ /* Write merged datum to target buffer */
+
+ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
+ ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
+ BufferLength - BufferOffset));
+
+ BufferOffset += ObjDesc->CommonField.AccessByteWidth;
+ MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
+ }
+
+ /* Mask off any extra bits in the last datum */
+
+ BufferTailBits = ObjDesc->CommonField.BitLength % AccessBitWidth;
+ if (BufferTailBits)
+ {
+ MergedDatum &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
+ }
+
+ /* Write the last datum to the buffer */
+
+ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
+ ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
+ BufferLength - BufferOffset));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExInsertIntoField
+ *
+ * PARAMETERS: ObjDesc - Field to be written
+ * Buffer - Data to be written
+ * BufferLength - Length of Buffer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the Buffer contents into the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExInsertIntoField (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ void *Buffer,
+ UINT32 BufferLength)
+{
+ void *NewBuffer;
+ ACPI_STATUS Status;
+ UINT64 Mask;
+ UINT64 WidthMask;
+ UINT64 MergedDatum;
+ UINT64 RawDatum = 0;
+ UINT32 FieldOffset = 0;
+ UINT32 BufferOffset = 0;
+ UINT32 BufferTailBits;
+ UINT32 DatumCount;
+ UINT32 FieldDatumCount;
+ UINT32 AccessBitWidth;
+ UINT32 RequiredLength;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (ExInsertIntoField);
+
+
+ /* Validate input buffer */
+
+ NewBuffer = NULL;
+ RequiredLength = ACPI_ROUND_BITS_UP_TO_BYTES (
+ ObjDesc->CommonField.BitLength);
+ /*
+ * We must have a buffer that is at least as long as the field
+ * we are writing to. This is because individual fields are
+ * indivisible and partial writes are not supported -- as per
+ * the ACPI specification.
+ */
+ if (BufferLength < RequiredLength)
+ {
+ /* We need to create a new buffer */
+
+ NewBuffer = ACPI_ALLOCATE_ZEROED (RequiredLength);
+ if (!NewBuffer)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Copy the original data to the new buffer, starting
+ * at Byte zero. All unused (upper) bytes of the
+ * buffer will be 0.
+ */
+ memcpy ((char *) NewBuffer, (char *) Buffer, BufferLength);
+ Buffer = NewBuffer;
+ BufferLength = RequiredLength;
+ }
+
+/* TBD: Move to common setup code */
+
+ /* Algo is limited to sizeof(UINT64), so cut the AccessByteWidth */
+ if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
+ {
+ ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
+ }
+
+ AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
+
+ /*
+ * Create the bitmasks used for bit insertion.
+ * Note: This if/else is used to bypass compiler differences with the
+ * shift operator
+ */
+ if (AccessBitWidth == ACPI_INTEGER_BIT_SIZE)
+ {
+ WidthMask = ACPI_UINT64_MAX;
+ }
+ else
+ {
+ WidthMask = ACPI_MASK_BITS_ABOVE (AccessBitWidth);
+ }
+
+ Mask = WidthMask &
+ ACPI_MASK_BITS_BELOW (ObjDesc->CommonField.StartFieldBitOffset);
+
+ /* Compute the number of datums (access width data items) */
+
+ DatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength,
+ AccessBitWidth);
+
+ FieldDatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength +
+ ObjDesc->CommonField.StartFieldBitOffset,
+ AccessBitWidth);
+
+ /* Get initial Datum from the input buffer */
+
+ memcpy (&RawDatum, Buffer,
+ ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
+ BufferLength - BufferOffset));
+
+ MergedDatum = RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
+
+ /* Write the entire field */
+
+ for (i = 1; i < FieldDatumCount; i++)
+ {
+ /* Write merged datum to the target field */
+
+ MergedDatum &= Mask;
+ Status = AcpiExWriteWithUpdateRule (ObjDesc, Mask,
+ MergedDatum, FieldOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ FieldOffset += ObjDesc->CommonField.AccessByteWidth;
+
+ /*
+ * Start new output datum by merging with previous input datum
+ * if necessary.
+ *
+ * Note: Before the shift, check if the shift value will be larger than
+ * the integer size. If so, there is no need to perform the operation.
+ * This avoids the differences in behavior between different compilers
+ * concerning shift values larger than the target data width.
+ */
+ if ((AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset) <
+ ACPI_INTEGER_BIT_SIZE)
+ {
+ MergedDatum = RawDatum >>
+ (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
+ }
+ else
+ {
+ MergedDatum = 0;
+ }
+
+ Mask = WidthMask;
+
+ if (i == DatumCount)
+ {
+ break;
+ }
+
+ /* Get the next input datum from the buffer */
+
+ BufferOffset += ObjDesc->CommonField.AccessByteWidth;
+ memcpy (&RawDatum, ((char *) Buffer) + BufferOffset,
+ ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
+ BufferLength - BufferOffset));
+
+ MergedDatum |= RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
+ }
+
+ /* Mask off any extra bits in the last datum */
+
+ BufferTailBits = (ObjDesc->CommonField.BitLength +
+ ObjDesc->CommonField.StartFieldBitOffset) % AccessBitWidth;
+ if (BufferTailBits)
+ {
+ Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
+ }
+
+ /* Write the last datum to the field */
+
+ MergedDatum &= Mask;
+ Status = AcpiExWriteWithUpdateRule (ObjDesc,
+ Mask, MergedDatum, FieldOffset);
+
+Exit:
+ /* Free temporary buffer if we used one */
+
+ if (NewBuffer)
+ {
+ ACPI_FREE (NewBuffer);
+ }
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmisc.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmisc.c
new file mode 100644
index 0000000000..df02e034bc
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmisc.c
@@ -0,0 +1,794 @@
+/******************************************************************************
+ *
+ * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/amlresrc.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGetObjectReference
+ *
+ * PARAMETERS: ObjDesc - Create a reference to this object
+ * ReturnDesc - Where to store the reference
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtain and return a "reference" to the target object
+ * Common code for the RefOfOp and the CondRefOfOp.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExGetObjectReference (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ReturnDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *ReferenceObj;
+ ACPI_OPERAND_OBJECT *ReferencedObj;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
+
+
+ *ReturnDesc = NULL;
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ if (ObjDesc->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * Must be a reference to a Local or Arg
+ */
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_ARG:
+ case ACPI_REFCLASS_DEBUG:
+
+ /* The referenced object is the pseudo-node for the local/arg */
+
+ ReferencedObj = ObjDesc->Reference.Object;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
+ ObjDesc->Reference.Class));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+ /*
+ * A named reference that has already been resolved to a Node
+ */
+ ReferencedObj = ObjDesc;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
+ ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+
+ /* Create a new reference object */
+
+ ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
+ if (!ReferenceObj)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
+ ReferenceObj->Reference.Object = ReferencedObj;
+ *ReturnDesc = ReferenceObj;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Object %p Type [%s], returning Reference %p\n",
+ ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExConcatTemplate
+ *
+ * PARAMETERS: Operand0 - First source object
+ * Operand1 - Second source object
+ * ActualReturnDesc - Where to place the return object
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Concatenate two resource templates
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExConcatTemplate (
+ ACPI_OPERAND_OBJECT *Operand0,
+ ACPI_OPERAND_OBJECT *Operand1,
+ ACPI_OPERAND_OBJECT **ActualReturnDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ UINT8 *NewBuf;
+ UINT8 *EndTag;
+ ACPI_SIZE Length0;
+ ACPI_SIZE Length1;
+ ACPI_SIZE NewLength;
+
+
+ ACPI_FUNCTION_TRACE (ExConcatTemplate);
+
+
+ /*
+ * Find the EndTag descriptor in each resource template.
+ * Note1: returned pointers point TO the EndTag, not past it.
+ * Note2: zero-length buffers are allowed; treated like one EndTag
+ */
+
+ /* Get the length of the first resource template */
+
+ Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
+
+ /* Get the length of the second resource template */
+
+ Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
+
+ /* Combine both lengths, minimum size will be 2 for EndTag */
+
+ NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
+
+ /* Create a new buffer object for the result (with one EndTag) */
+
+ ReturnDesc = AcpiUtCreateBufferObject (NewLength);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Copy the templates to the new buffer, 0 first, then 1 follows. One
+ * EndTag descriptor is copied from Operand1.
+ */
+ NewBuf = ReturnDesc->Buffer.Pointer;
+ memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
+ memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
+
+ /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
+
+ NewBuf[NewLength - 1] = 0;
+ NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
+
+ /* Return the completed resource template */
+
+ *ActualReturnDesc = ReturnDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoConcatenate
+ *
+ * PARAMETERS: Operand0 - First source object
+ * Operand1 - Second source object
+ * ActualReturnDesc - Where to place the return object
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExDoConcatenate (
+ ACPI_OPERAND_OBJECT *Operand0,
+ ACPI_OPERAND_OBJECT *Operand1,
+ ACPI_OPERAND_OBJECT **ActualReturnDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ char *NewBuf;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExDoConcatenate);
+
+
+ /*
+ * Convert the second operand if necessary. The first operand
+ * determines the type of the second operand, (See the Data Types
+ * section of the ACPI specification.) Both object types are
+ * guaranteed to be either Integer/String/Buffer by the operand
+ * resolution mechanism.
+ */
+ switch (Operand0->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Status = AcpiExConvertToString (Operand1, &LocalOperand1,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
+ Operand0->Common.Type));
+ Status = AE_AML_INTERNAL;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Both operands are now known to be the same object type
+ * (Both are Integer, String, or Buffer), and we can now perform the
+ * concatenation.
+ */
+
+ /*
+ * There are three cases to handle:
+ *
+ * 1) Two Integers concatenated to produce a new Buffer
+ * 2) Two Strings concatenated to produce a new String
+ * 3) Two Buffers concatenated to produce a new Buffer
+ */
+ switch (Operand0->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* Result of two Integers is a Buffer */
+ /* Need enough buffer space for two integers */
+
+ ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
+ ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ NewBuf = (char *) ReturnDesc->Buffer.Pointer;
+
+ /* Copy the first integer, LSB first */
+
+ memcpy (NewBuf, &Operand0->Integer.Value,
+ AcpiGbl_IntegerByteWidth);
+
+ /* Copy the second integer (LSB first) after the first */
+
+ memcpy (NewBuf + AcpiGbl_IntegerByteWidth,
+ &LocalOperand1->Integer.Value,
+ AcpiGbl_IntegerByteWidth);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ /* Result of two Strings is a String */
+
+ ReturnDesc = AcpiUtCreateStringObject (
+ ((ACPI_SIZE) Operand0->String.Length +
+ LocalOperand1->String.Length));
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ NewBuf = ReturnDesc->String.Pointer;
+
+ /* Concatenate the strings */
+
+ strcpy (NewBuf, Operand0->String.Pointer);
+ strcpy (NewBuf + Operand0->String.Length,
+ LocalOperand1->String.Pointer);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* Result of two Buffers is a Buffer */
+
+ ReturnDesc = AcpiUtCreateBufferObject (
+ ((ACPI_SIZE) Operand0->Buffer.Length +
+ LocalOperand1->Buffer.Length));
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ NewBuf = (char *) ReturnDesc->Buffer.Pointer;
+
+ /* Concatenate the buffers */
+
+ memcpy (NewBuf, Operand0->Buffer.Pointer,
+ Operand0->Buffer.Length);
+ memcpy (NewBuf + Operand0->Buffer.Length,
+ LocalOperand1->Buffer.Pointer,
+ LocalOperand1->Buffer.Length);
+ break;
+
+ default:
+
+ /* Invalid object type, should not happen here */
+
+ ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
+ Operand0->Common.Type));
+ Status =AE_AML_INTERNAL;
+ goto Cleanup;
+ }
+
+ *ActualReturnDesc = ReturnDesc;
+
+Cleanup:
+ if (LocalOperand1 != Operand1)
+ {
+ AcpiUtRemoveReference (LocalOperand1);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoMathOp
+ *
+ * PARAMETERS: Opcode - AML opcode
+ * Integer0 - Integer operand #0
+ * Integer1 - Integer operand #1
+ *
+ * RETURN: Integer result of the operation
+ *
+ * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
+ * math functions here is to prevent a lot of pointer dereferencing
+ * to obtain the operands.
+ *
+ ******************************************************************************/
+
+UINT64
+AcpiExDoMathOp (
+ UINT16 Opcode,
+ UINT64 Integer0,
+ UINT64 Integer1)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ switch (Opcode)
+ {
+ case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
+
+ return (Integer0 + Integer1);
+
+ case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
+
+ return (Integer0 & Integer1);
+
+ case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
+
+ return (~(Integer0 & Integer1));
+
+ case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
+
+ return (Integer0 | Integer1);
+
+ case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
+
+ return (~(Integer0 | Integer1));
+
+ case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
+
+ return (Integer0 ^ Integer1);
+
+ case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
+
+ return (Integer0 * Integer1);
+
+ case AML_SHIFT_LEFT_OP: /* ShiftLeft (Operand, ShiftCount, Result)*/
+
+ /*
+ * We need to check if the shiftcount is larger than the integer bit
+ * width since the behavior of this is not well-defined in the C language.
+ */
+ if (Integer1 >= AcpiGbl_IntegerBitWidth)
+ {
+ return (0);
+ }
+ return (Integer0 << Integer1);
+
+ case AML_SHIFT_RIGHT_OP: /* ShiftRight (Operand, ShiftCount, Result) */
+
+ /*
+ * We need to check if the shiftcount is larger than the integer bit
+ * width since the behavior of this is not well-defined in the C language.
+ */
+ if (Integer1 >= AcpiGbl_IntegerBitWidth)
+ {
+ return (0);
+ }
+ return (Integer0 >> Integer1);
+
+ case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
+
+ return (Integer0 - Integer1);
+
+ default:
+
+ return (0);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoLogicalNumericOp
+ *
+ * PARAMETERS: Opcode - AML opcode
+ * Integer0 - Integer operand #0
+ * Integer1 - Integer operand #1
+ * LogicalResult - TRUE/FALSE result of the operation
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
+ * operators (LAnd and LOr), both operands must be integers.
+ *
+ * Note: cleanest machine code seems to be produced by the code
+ * below, rather than using statements of the form:
+ * Result = (Integer0 && Integer1);
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExDoLogicalNumericOp (
+ UINT16 Opcode,
+ UINT64 Integer0,
+ UINT64 Integer1,
+ BOOLEAN *LogicalResult)
+{
+ ACPI_STATUS Status = AE_OK;
+ BOOLEAN LocalResult = FALSE;
+
+
+ ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
+
+
+ switch (Opcode)
+ {
+ case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
+
+ if (Integer0 && Integer1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ case AML_LOR_OP: /* LOr (Integer0, Integer1) */
+
+ if (Integer0 || Integer1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ default:
+
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+
+ /* Return the logical result and status */
+
+ *LogicalResult = LocalResult;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoLogicalOp
+ *
+ * PARAMETERS: Opcode - AML opcode
+ * Operand0 - operand #0
+ * Operand1 - operand #1
+ * LogicalResult - TRUE/FALSE result of the operation
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
+ * functions here is to prevent a lot of pointer dereferencing
+ * to obtain the operands and to simplify the generation of the
+ * logical value. For the Numeric operators (LAnd and LOr), both
+ * operands must be integers. For the other logical operators,
+ * operands can be any combination of Integer/String/Buffer. The
+ * first operand determines the type to which the second operand
+ * will be converted.
+ *
+ * Note: cleanest machine code seems to be produced by the code
+ * below, rather than using statements of the form:
+ * Result = (Operand0 == Operand1);
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExDoLogicalOp (
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT *Operand0,
+ ACPI_OPERAND_OBJECT *Operand1,
+ BOOLEAN *LogicalResult)
+{
+ ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
+ UINT64 Integer0;
+ UINT64 Integer1;
+ UINT32 Length0;
+ UINT32 Length1;
+ ACPI_STATUS Status = AE_OK;
+ BOOLEAN LocalResult = FALSE;
+ int Compare;
+
+
+ ACPI_FUNCTION_TRACE (ExDoLogicalOp);
+
+
+ /*
+ * Convert the second operand if necessary. The first operand
+ * determines the type of the second operand, (See the Data Types
+ * section of the ACPI 3.0+ specification.) Both object types are
+ * guaranteed to be either Integer/String/Buffer by the operand
+ * resolution mechanism.
+ */
+ switch (Operand0->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Status = AcpiExConvertToString (Operand1, &LocalOperand1,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
+ break;
+
+ default:
+
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Two cases: 1) Both Integers, 2) Both Strings or Buffers
+ */
+ if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ /*
+ * 1) Both operands are of type integer
+ * Note: LocalOperand1 may have changed above
+ */
+ Integer0 = Operand0->Integer.Value;
+ Integer1 = LocalOperand1->Integer.Value;
+
+ switch (Opcode)
+ {
+ case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
+
+ if (Integer0 == Integer1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
+
+ if (Integer0 > Integer1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
+
+ if (Integer0 < Integer1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ default:
+
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * 2) Both operands are Strings or both are Buffers
+ * Note: Code below takes advantage of common Buffer/String
+ * object fields. LocalOperand1 may have changed above. Use
+ * memcmp to handle nulls in buffers.
+ */
+ Length0 = Operand0->Buffer.Length;
+ Length1 = LocalOperand1->Buffer.Length;
+
+ /* Lexicographic compare: compare the data bytes */
+
+ Compare = memcmp (Operand0->Buffer.Pointer,
+ LocalOperand1->Buffer.Pointer,
+ (Length0 > Length1) ? Length1 : Length0);
+
+ switch (Opcode)
+ {
+ case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
+
+ /* Length and all bytes must be equal */
+
+ if ((Length0 == Length1) &&
+ (Compare == 0))
+ {
+ /* Length and all bytes match ==> TRUE */
+
+ LocalResult = TRUE;
+ }
+ break;
+
+ case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
+
+ if (Compare > 0)
+ {
+ LocalResult = TRUE;
+ goto Cleanup; /* TRUE */
+ }
+ if (Compare < 0)
+ {
+ goto Cleanup; /* FALSE */
+ }
+
+ /* Bytes match (to shortest length), compare lengths */
+
+ if (Length0 > Length1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
+
+ if (Compare > 0)
+ {
+ goto Cleanup; /* FALSE */
+ }
+ if (Compare < 0)
+ {
+ LocalResult = TRUE;
+ goto Cleanup; /* TRUE */
+ }
+
+ /* Bytes match (to shortest length), compare lengths */
+
+ if (Length0 < Length1)
+ {
+ LocalResult = TRUE;
+ }
+ break;
+
+ default:
+
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+ }
+
+Cleanup:
+
+ /* New object was created if implicit conversion performed - delete */
+
+ if (LocalOperand1 != Operand1)
+ {
+ AcpiUtRemoveReference (LocalOperand1);
+ }
+
+ /* Return the logical result and status */
+
+ *LogicalResult = LocalResult;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmutex.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmutex.c
new file mode 100644
index 0000000000..cf82b04752
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exmutex.c
@@ -0,0 +1,554 @@
+/******************************************************************************
+ *
+ * Module Name: exmutex - ASL Mutex Acquire/Release functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exmutex")
+
+/* Local prototypes */
+
+static void
+AcpiExLinkMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_THREAD_STATE *Thread);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExUnlinkMutex
+ *
+ * PARAMETERS: ObjDesc - The mutex to be unlinked
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
+ *
+ ******************************************************************************/
+
+void
+AcpiExUnlinkMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_THREAD_STATE *Thread = ObjDesc->Mutex.OwnerThread;
+
+
+ if (!Thread)
+ {
+ return;
+ }
+
+ /* Doubly linked list */
+
+ if (ObjDesc->Mutex.Next)
+ {
+ (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
+ }
+
+ if (ObjDesc->Mutex.Prev)
+ {
+ (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
+
+ /*
+ * Migrate the previous sync level associated with this mutex to
+ * the previous mutex on the list so that it may be preserved.
+ * This handles the case where several mutexes have been acquired
+ * at the same level, but are not released in opposite order.
+ */
+ (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
+ ObjDesc->Mutex.OriginalSyncLevel;
+ }
+ else
+ {
+ Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExLinkMutex
+ *
+ * PARAMETERS: ObjDesc - The mutex to be linked
+ * Thread - Current executing thread object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
+ *
+ ******************************************************************************/
+
+static void
+AcpiExLinkMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_OPERAND_OBJECT *ListHead;
+
+
+ ListHead = Thread->AcquiredMutexList;
+
+ /* This object will be the first object in the list */
+
+ ObjDesc->Mutex.Prev = NULL;
+ ObjDesc->Mutex.Next = ListHead;
+
+ /* Update old first object to point back to this object */
+
+ if (ListHead)
+ {
+ ListHead->Mutex.Prev = ObjDesc;
+ }
+
+ /* Update list head */
+
+ Thread->AcquiredMutexList = ObjDesc;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAcquireMutexObject
+ *
+ * PARAMETERS: Timeout - Timeout in milliseconds
+ * ObjDesc - Mutex object
+ * ThreadId - Current thread state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
+ * path that supports multiple acquires by the same thread.
+ *
+ * MUTEX: Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From AcpiExAcquireMutex, via an AML Acquire() operator
+ * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the
+ * global lock
+ * 3) From the external interface, AcpiAcquireGlobalLock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExAcquireMutexObject (
+ UINT16 Timeout,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_THREAD_ID ThreadId)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
+
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Support for multiple acquires by the owning thread */
+
+ if (ObjDesc->Mutex.ThreadId == ThreadId)
+ {
+ /*
+ * The mutex is already owned by this thread, just increment the
+ * acquisition depth
+ */
+ ObjDesc->Mutex.AcquisitionDepth++;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Acquire the mutex, wait if necessary. Special case for Global Lock */
+
+ if (ObjDesc == AcpiGbl_GlobalLockMutex)
+ {
+ Status = AcpiEvAcquireGlobalLock (Timeout);
+ }
+ else
+ {
+ Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
+ Timeout);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ /* Includes failure from a timeout on TimeDesc */
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Acquired the mutex: update mutex object */
+
+ ObjDesc->Mutex.ThreadId = ThreadId;
+ ObjDesc->Mutex.AcquisitionDepth = 1;
+ ObjDesc->Mutex.OriginalSyncLevel = 0;
+ ObjDesc->Mutex.OwnerThread = NULL; /* Used only for AML Acquire() */
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAcquireMutex
+ *
+ * PARAMETERS: TimeDesc - Timeout integer
+ * ObjDesc - Mutex object
+ * WalkState - Current method execution state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire an AML mutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExAcquireMutex (
+ ACPI_OPERAND_OBJECT *TimeDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
+
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Must have a valid thread state struct */
+
+ if (!WalkState->Thread)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot acquire Mutex [%4.4s], null thread info",
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /*
+ * Current sync level must be less than or equal to the sync level of the
+ * mutex. This mechanism provides some deadlock prevention
+ */
+ if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+ WalkState->Thread->CurrentSyncLevel));
+ return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ }
+
+ Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
+ ObjDesc, WalkState->Thread->ThreadId);
+ if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
+ {
+ /* Save Thread object, original/current sync levels */
+
+ ObjDesc->Mutex.OwnerThread = WalkState->Thread;
+ ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;
+ WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;
+
+ /* Link the mutex to the current thread for force-unlock at method exit */
+
+ AcpiExLinkMutex (ObjDesc, WalkState->Thread);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReleaseMutexObject
+ *
+ * PARAMETERS: ObjDesc - The object descriptor for this op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex, low level interface.
+ * Provides a common path that supports multiple releases (after
+ * previous multiple acquires) by the same thread.
+ *
+ * MUTEX: Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From AcpiExReleaseMutex, via an AML Acquire() operator
+ * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the
+ * global lock
+ * 3) From the external interface, AcpiReleaseGlobalLock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReleaseMutexObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
+
+
+ if (ObjDesc->Mutex.AcquisitionDepth == 0)
+ {
+ return_ACPI_STATUS (AE_NOT_ACQUIRED);
+ }
+
+ /* Match multiple Acquires with multiple Releases */
+
+ ObjDesc->Mutex.AcquisitionDepth--;
+ if (ObjDesc->Mutex.AcquisitionDepth != 0)
+ {
+ /* Just decrement the depth and return */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (ObjDesc->Mutex.OwnerThread)
+ {
+ /* Unlink the mutex from the owner's list */
+
+ AcpiExUnlinkMutex (ObjDesc);
+ ObjDesc->Mutex.OwnerThread = NULL;
+ }
+
+ /* Release the mutex, special case for Global Lock */
+
+ if (ObjDesc == AcpiGbl_GlobalLockMutex)
+ {
+ Status = AcpiEvReleaseGlobalLock ();
+ }
+ else
+ {
+ AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
+ }
+
+ /* Clear mutex info */
+
+ ObjDesc->Mutex.ThreadId = 0;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReleaseMutex
+ *
+ * PARAMETERS: ObjDesc - The object descriptor for this op
+ * WalkState - Current method execution state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReleaseMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT8 PreviousSyncLevel;
+ ACPI_THREAD_STATE *OwnerThread;
+
+
+ ACPI_FUNCTION_TRACE (ExReleaseMutex);
+
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ OwnerThread = ObjDesc->Mutex.OwnerThread;
+
+ /* The mutex must have been previously acquired in order to release it */
+
+ if (!OwnerThread)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot release Mutex [%4.4s], not acquired",
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+ return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
+ }
+
+ /* Must have a valid thread ID */
+
+ if (!WalkState->Thread)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot release Mutex [%4.4s], null thread info",
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /*
+ * The Mutex is owned, but this thread must be the owner.
+ * Special case for Global Lock, any thread can release
+ */
+ if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
+ (ObjDesc != AcpiGbl_GlobalLockMutex))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
+ (UINT32) WalkState->Thread->ThreadId,
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+ (UINT32) OwnerThread->ThreadId));
+ return_ACPI_STATUS (AE_AML_NOT_OWNER);
+ }
+
+ /*
+ * The sync level of the mutex must be equal to the current sync level. In
+ * other words, the current level means that at least one mutex at that
+ * level is currently being held. Attempting to release a mutex of a
+ * different level can only mean that the mutex ordering rule is being
+ * violated. This behavior is clarified in ACPI 4.0 specification.
+ */
+ if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
+ AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+ ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
+ return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ }
+
+ /*
+ * Get the previous SyncLevel from the head of the acquired mutex list.
+ * This handles the case where several mutexes at the same level have been
+ * acquired, but are not released in reverse order.
+ */
+ PreviousSyncLevel =
+ OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
+
+ Status = AcpiExReleaseMutexObject (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ObjDesc->Mutex.AcquisitionDepth == 0)
+ {
+ /* Restore the previous SyncLevel */
+
+ OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReleaseAllMutexes
+ *
+ * PARAMETERS: Thread - Current executing thread object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release all mutexes held by this thread
+ *
+ * NOTE: This function is called as the thread is exiting the interpreter.
+ * Mutexes are not released when an individual control method is exited, but
+ * only when the parent thread actually exits the interpreter. This allows one
+ * method to acquire a mutex, and a different method to release it, as long as
+ * this is performed underneath a single parent control method.
+ *
+ ******************************************************************************/
+
+void
+AcpiExReleaseAllMutexes (
+ ACPI_THREAD_STATE *Thread)
+{
+ ACPI_OPERAND_OBJECT *Next = Thread->AcquiredMutexList;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_NAME (ExReleaseAllMutexes);
+
+
+ /* Traverse the list of owned mutexes, releasing each one */
+
+ while (Next)
+ {
+ ObjDesc = Next;
+ Next = ObjDesc->Mutex.Next;
+
+ ObjDesc->Mutex.Prev = NULL;
+ ObjDesc->Mutex.Next = NULL;
+ ObjDesc->Mutex.AcquisitionDepth = 0;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Force-releasing held mutex: %p\n", ObjDesc));
+
+ /* Release the mutex, special case for Global Lock */
+
+ if (ObjDesc == AcpiGbl_GlobalLockMutex)
+ {
+ /* Ignore errors */
+
+ (void) AcpiEvReleaseGlobalLock ();
+ }
+ else
+ {
+ AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
+ }
+
+ /* Mark mutex unowned */
+
+ ObjDesc->Mutex.OwnerThread = NULL;
+ ObjDesc->Mutex.ThreadId = 0;
+
+ /* Update Thread SyncLevel (Last mutex is the important one) */
+
+ Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exnames.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exnames.c
new file mode 100644
index 0000000000..a6c9e6b083
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exnames.c
@@ -0,0 +1,478 @@
+/******************************************************************************
+ *
+ * Module Name: exnames - interpreter/scanner name load/execute
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exnames")
+
+/* Local prototypes */
+
+static char *
+AcpiExAllocateNameString (
+ UINT32 PrefixCount,
+ UINT32 NumNameSegs);
+
+static ACPI_STATUS
+AcpiExNameSegment (
+ UINT8 **InAmlAddress,
+ char *NameString);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAllocateNameString
+ *
+ * PARAMETERS: PrefixCount - Count of parent levels. Special cases:
+ * (-1)==root, 0==none
+ * NumNameSegs - count of 4-character name segments
+ *
+ * RETURN: A pointer to the allocated string segment. This segment must
+ * be deleted by the caller.
+ *
+ * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
+ * string is long enough, and set up prefix if any.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiExAllocateNameString (
+ UINT32 PrefixCount,
+ UINT32 NumNameSegs)
+{
+ char *TempPtr;
+ char *NameString;
+ UINT32 SizeNeeded;
+
+ ACPI_FUNCTION_TRACE (ExAllocateNameString);
+
+
+ /*
+ * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix.
+ * Also, one byte for the null terminator.
+ * This may actually be somewhat longer than needed.
+ */
+ if (PrefixCount == ACPI_UINT32_MAX)
+ {
+ /* Special case for root */
+
+ SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
+ }
+ else
+ {
+ SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
+ }
+
+ /*
+ * Allocate a buffer for the name.
+ * This buffer must be deleted by the caller!
+ */
+ NameString = ACPI_ALLOCATE (SizeNeeded);
+ if (!NameString)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not allocate size %u", SizeNeeded));
+ return_PTR (NULL);
+ }
+
+ TempPtr = NameString;
+
+ /* Set up Root or Parent prefixes if needed */
+
+ if (PrefixCount == ACPI_UINT32_MAX)
+ {
+ *TempPtr++ = AML_ROOT_PREFIX;
+ }
+ else
+ {
+ while (PrefixCount--)
+ {
+ *TempPtr++ = AML_PARENT_PREFIX;
+ }
+ }
+
+
+ /* Set up Dual or Multi prefixes if needed */
+
+ if (NumNameSegs > 2)
+ {
+ /* Set up multi prefixes */
+
+ *TempPtr++ = AML_MULTI_NAME_PREFIX_OP;
+ *TempPtr++ = (char) NumNameSegs;
+ }
+ else if (2 == NumNameSegs)
+ {
+ /* Set up dual prefixes */
+
+ *TempPtr++ = AML_DUAL_NAME_PREFIX;
+ }
+
+ /*
+ * Terminate string following prefixes. AcpiExNameSegment() will
+ * append the segment(s)
+ */
+ *TempPtr = 0;
+
+ return_PTR (NameString);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExNameSegment
+ *
+ * PARAMETERS: InAmlAddress - Pointer to the name in the AML code
+ * NameString - Where to return the name. The name is appended
+ * to any existing string to form a namepath
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExNameSegment (
+ UINT8 **InAmlAddress,
+ char *NameString)
+{
+ char *AmlAddress = (void *) *InAmlAddress;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Index;
+ char CharBuf[5];
+
+
+ ACPI_FUNCTION_TRACE (ExNameSegment);
+
+
+ /*
+ * If first character is a digit, then we know that we aren't looking at a
+ * valid name segment
+ */
+ CharBuf[0] = *AmlAddress;
+
+ if ('0' <= CharBuf[0] && CharBuf[0] <= '9')
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0]));
+ return_ACPI_STATUS (AE_CTRL_PENDING);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
+
+ for (Index = 0;
+ (Index < ACPI_NAME_SIZE) && (AcpiUtValidAcpiChar (*AmlAddress, 0));
+ Index++)
+ {
+ CharBuf[Index] = *AmlAddress++;
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", CharBuf[Index]));
+ }
+
+
+ /* Valid name segment */
+
+ if (Index == 4)
+ {
+ /* Found 4 valid characters */
+
+ CharBuf[4] = '\0';
+
+ if (NameString)
+ {
+ strcat (NameString, CharBuf);
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Appended to - %s\n", NameString));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "No Name string - %s\n", CharBuf));
+ }
+ }
+ else if (Index == 0)
+ {
+ /*
+ * First character was not a valid name character,
+ * so we are looking at something other than a name.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Leading character is not alpha: %02Xh (not a name)\n",
+ CharBuf[0]));
+ Status = AE_CTRL_PENDING;
+ }
+ else
+ {
+ /*
+ * Segment started with one or more valid characters, but fewer than
+ * the required 4
+ */
+ Status = AE_AML_BAD_NAME;
+ ACPI_ERROR ((AE_INFO,
+ "Bad character 0x%02x in name, at %p",
+ *AmlAddress, AmlAddress));
+ }
+
+ *InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGetNameString
+ *
+ * PARAMETERS: DataType - Object type to be associated with this
+ * name
+ * InAmlAddress - Pointer to the namestring in the AML code
+ * OutNameString - Where the namestring is returned
+ * OutNameLength - Length of the returned string
+ *
+ * RETURN: Status, namestring and length
+ *
+ * DESCRIPTION: Extract a full namepath from the AML byte stream,
+ * including any prefixes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExGetNameString (
+ ACPI_OBJECT_TYPE DataType,
+ UINT8 *InAmlAddress,
+ char **OutNameString,
+ UINT32 *OutNameLength)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT8 *AmlAddress = InAmlAddress;
+ char *NameString = NULL;
+ UINT32 NumSegments;
+ UINT32 PrefixCount = 0;
+ BOOLEAN HasPrefix = FALSE;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress);
+
+
+ if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType ||
+ ACPI_TYPE_LOCAL_BANK_FIELD == DataType ||
+ ACPI_TYPE_LOCAL_INDEX_FIELD == DataType)
+ {
+ /* Disallow prefixes for types associated with FieldUnit names */
+
+ NameString = AcpiExAllocateNameString (0, 1);
+ if (!NameString)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ else
+ {
+ Status = AcpiExNameSegment (&AmlAddress, NameString);
+ }
+ }
+ else
+ {
+ /*
+ * DataType is not a field name.
+ * Examine first character of name for root or parent prefix operators
+ */
+ switch (*AmlAddress)
+ {
+ case AML_ROOT_PREFIX:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n",
+ AmlAddress));
+
+ /*
+ * Remember that we have a RootPrefix --
+ * see comment in AcpiExAllocateNameString()
+ */
+ AmlAddress++;
+ PrefixCount = ACPI_UINT32_MAX;
+ HasPrefix = TRUE;
+ break;
+
+ case AML_PARENT_PREFIX:
+
+ /* Increment past possibly multiple parent prefixes */
+
+ do
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n",
+ AmlAddress));
+
+ AmlAddress++;
+ PrefixCount++;
+
+ } while (*AmlAddress == AML_PARENT_PREFIX);
+
+ HasPrefix = TRUE;
+ break;
+
+ default:
+
+ /* Not a prefix character */
+
+ break;
+ }
+
+ /* Examine first character of name for name segment prefix operator */
+
+ switch (*AmlAddress)
+ {
+ case AML_DUAL_NAME_PREFIX:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n",
+ AmlAddress));
+
+ AmlAddress++;
+ NameString = AcpiExAllocateNameString (PrefixCount, 2);
+ if (!NameString)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+
+ /* Indicate that we processed a prefix */
+
+ HasPrefix = TRUE;
+
+ Status = AcpiExNameSegment (&AmlAddress, NameString);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiExNameSegment (&AmlAddress, NameString);
+ }
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n",
+ AmlAddress));
+
+ /* Fetch count of segments remaining in name path */
+
+ AmlAddress++;
+ NumSegments = *AmlAddress;
+
+ NameString = AcpiExAllocateNameString (PrefixCount, NumSegments);
+ if (!NameString)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+
+ /* Indicate that we processed a prefix */
+
+ AmlAddress++;
+ HasPrefix = TRUE;
+
+ while (NumSegments &&
+ (Status = AcpiExNameSegment (&AmlAddress, NameString)) ==
+ AE_OK)
+ {
+ NumSegments--;
+ }
+
+ break;
+
+ case 0:
+
+ /* NullName valid as of 8-12-98 ASL/AML Grammar Update */
+
+ if (PrefixCount == ACPI_UINT32_MAX)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "NameSeg is \"\\\" followed by NULL\n"));
+ }
+
+ /* Consume the NULL byte */
+
+ AmlAddress++;
+ NameString = AcpiExAllocateNameString (PrefixCount, 0);
+ if (!NameString)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+
+ break;
+
+ default:
+
+ /* Name segment string */
+
+ NameString = AcpiExAllocateNameString (PrefixCount, 1);
+ if (!NameString)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+
+ Status = AcpiExNameSegment (&AmlAddress, NameString);
+ break;
+ }
+ }
+
+ if (AE_CTRL_PENDING == Status && HasPrefix)
+ {
+ /* Ran out of segments after processing a prefix */
+
+ ACPI_ERROR ((AE_INFO,
+ "Malformed Name at %p", NameString));
+ Status = AE_AML_BAD_NAME;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ if (NameString)
+ {
+ ACPI_FREE (NameString);
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ *OutNameString = NameString;
+ *OutNameLength = (UINT32) (AmlAddress - InAmlAddress);
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg1.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg1.c
new file mode 100644
index 0000000000..dc35c1711a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg1.c
@@ -0,0 +1,1116 @@
+/******************************************************************************
+ *
+ * Module Name: exoparg1 - AML execution - opcodes with 1 argument
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exoparg1")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ * AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS: The number of arguments (input operands) that are
+ * required for this opcode type (0 through 6 args).
+ * yT - TARGETS: The number of targets (output operands) that are required
+ * for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ * as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_0A_0T_1R
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute operator with no operands, one return value
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_0A_0T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the AML opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_TIMER_OP: /* Timer () */
+
+ /* Create a return object of type Integer */
+
+ ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ break;
+
+ default: /* Unknown opcode */
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ break;
+ }
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ WalkState->ResultObj = NULL;
+ }
+ else
+ {
+ /* Save the return value */
+
+ WalkState->ResultObj = ReturnDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_1A_0T_0R
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
+ * object stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_1A_0T_0R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the AML opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_RELEASE_OP: /* Release (MutexObject) */
+
+ Status = AcpiExReleaseMutex (Operand[0], WalkState);
+ break;
+
+ case AML_RESET_OP: /* Reset (EventObject) */
+
+ Status = AcpiExSystemResetEvent (Operand[0]);
+ break;
+
+ case AML_SIGNAL_OP: /* Signal (EventObject) */
+
+ Status = AcpiExSystemSignalEvent (Operand[0]);
+ break;
+
+ case AML_SLEEP_OP: /* Sleep (MsecTime) */
+
+ Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
+ break;
+
+ case AML_STALL_OP: /* Stall (UsecTime) */
+
+ Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
+ break;
+
+ case AML_UNLOAD_OP: /* Unload (Handle) */
+
+ Status = AcpiExUnloadTable (Operand[0]);
+ break;
+
+ default: /* Unknown opcode */
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_1A_1T_0R
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, one target, and no
+ * return value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_1A_1T_0R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the AML opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_LOAD_OP:
+
+ Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
+ break;
+
+ default: /* Unknown opcode */
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_1A_1T_1R
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, one target, and a
+ * return value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_1A_1T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL;
+ UINT32 Temp32;
+ UINT32 i;
+ UINT64 PowerOfTen;
+ UINT64 Digit;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the AML opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_BIT_NOT_OP:
+ case AML_FIND_SET_LEFT_BIT_OP:
+ case AML_FIND_SET_RIGHT_BIT_OP:
+ case AML_FROM_BCD_OP:
+ case AML_TO_BCD_OP:
+ case AML_COND_REF_OF_OP:
+
+ /* Create a return object of type Integer for these opcodes */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ switch (WalkState->Opcode)
+ {
+ case AML_BIT_NOT_OP: /* Not (Operand, Result) */
+
+ ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
+ break;
+
+ case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */
+
+ ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
+
+ /*
+ * Acpi specification describes Integer type as a little
+ * endian unsigned value, so this boundary condition is valid.
+ */
+ for (Temp32 = 0; ReturnDesc->Integer.Value &&
+ Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
+ {
+ ReturnDesc->Integer.Value >>= 1;
+ }
+
+ ReturnDesc->Integer.Value = Temp32;
+ break;
+
+ case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
+
+ ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
+
+ /*
+ * The Acpi specification describes Integer type as a little
+ * endian unsigned value, so this boundary condition is valid.
+ */
+ for (Temp32 = 0; ReturnDesc->Integer.Value &&
+ Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
+ {
+ ReturnDesc->Integer.Value <<= 1;
+ }
+
+ /* Since the bit position is one-based, subtract from 33 (65) */
+
+ ReturnDesc->Integer.Value =
+ Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
+ break;
+
+ case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */
+ /*
+ * The 64-bit ACPI integer can hold 16 4-bit BCD characters
+ * (if table is 32-bit, integer can hold 8 BCD characters)
+ * Convert each 4-bit BCD value
+ */
+ PowerOfTen = 1;
+ ReturnDesc->Integer.Value = 0;
+ Digit = Operand[0]->Integer.Value;
+
+ /* Convert each BCD digit (each is one nybble wide) */
+
+ for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
+ {
+ /* Get the least significant 4-bit BCD digit */
+
+ Temp32 = ((UINT32) Digit) & 0xF;
+
+ /* Check the range of the digit */
+
+ if (Temp32 > 9)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "BCD digit too large (not decimal): 0x%X",
+ Temp32));
+
+ Status = AE_AML_NUMERIC_OVERFLOW;
+ goto Cleanup;
+ }
+
+ /* Sum the digit into the result with the current power of 10 */
+
+ ReturnDesc->Integer.Value +=
+ (((UINT64) Temp32) * PowerOfTen);
+
+ /* Shift to next BCD digit */
+
+ Digit >>= 4;
+
+ /* Next power of 10 */
+
+ PowerOfTen *= 10;
+ }
+ break;
+
+ case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */
+
+ ReturnDesc->Integer.Value = 0;
+ Digit = Operand[0]->Integer.Value;
+
+ /* Each BCD digit is one nybble wide */
+
+ for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
+ {
+ (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
+
+ /*
+ * Insert the BCD digit that resides in the
+ * remainder from above
+ */
+ ReturnDesc->Integer.Value |=
+ (((UINT64) Temp32) << ACPI_MUL_4 (i));
+ }
+
+ /* Overflow if there is any data left in Digit */
+
+ if (Digit > 0)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Integer too large to convert to BCD: 0x%8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
+ Status = AE_AML_NUMERIC_OVERFLOW;
+ goto Cleanup;
+ }
+ break;
+
+ case AML_COND_REF_OF_OP: /* CondRefOf (SourceObject, Result) */
+ /*
+ * This op is a little strange because the internal return value is
+ * different than the return value stored in the result descriptor
+ * (There are really two return values)
+ */
+ if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
+ {
+ /*
+ * This means that the object does not exist in the namespace,
+ * return FALSE
+ */
+ ReturnDesc->Integer.Value = 0;
+ goto Cleanup;
+ }
+
+ /* Get the object reference, store it, and remove our reference */
+
+ Status = AcpiExGetObjectReference (Operand[0],
+ &ReturnDesc2, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
+ AcpiUtRemoveReference (ReturnDesc2);
+
+ /* The object exists in the namespace, return TRUE */
+
+ ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
+ goto Cleanup;
+
+
+ default:
+
+ /* No other opcodes get here */
+
+ break;
+ }
+ break;
+
+ case AML_STORE_OP: /* Store (Source, Target) */
+ /*
+ * A store operand is typically a number, string, buffer or lvalue
+ * Be careful about deleting the source object,
+ * since the object itself may have been stored.
+ */
+ Status = AcpiExStore (Operand[0], Operand[1], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* It is possible that the Store already produced a return object */
+
+ if (!WalkState->ResultObj)
+ {
+ /*
+ * Normally, we would remove a reference on the Operand[0]
+ * parameter; But since it is being used as the internal return
+ * object (meaning we would normally increment it), the two
+ * cancel out, and we simply don't do anything.
+ */
+ WalkState->ResultObj = Operand[0];
+ WalkState->Operands[0] = NULL; /* Prevent deletion */
+ }
+ return_ACPI_STATUS (Status);
+
+ /*
+ * ACPI 2.0 Opcodes
+ */
+ case AML_COPY_OP: /* Copy (Source, Target) */
+
+ Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc,
+ WalkState);
+ break;
+
+ case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */
+
+ Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
+ ACPI_EXPLICIT_CONVERT_DECIMAL);
+ if (ReturnDesc == Operand[0])
+ {
+ /* No conversion performed, add ref to handle return value */
+ AcpiUtAddReference (ReturnDesc);
+ }
+ break;
+
+ case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */
+
+ Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
+ ACPI_EXPLICIT_CONVERT_HEX);
+ if (ReturnDesc == Operand[0])
+ {
+ /* No conversion performed, add ref to handle return value */
+ AcpiUtAddReference (ReturnDesc);
+ }
+ break;
+
+ case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */
+
+ Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
+ if (ReturnDesc == Operand[0])
+ {
+ /* No conversion performed, add ref to handle return value */
+ AcpiUtAddReference (ReturnDesc);
+ }
+ break;
+
+ case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */
+
+ Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc,
+ ACPI_ANY_BASE);
+ if (ReturnDesc == Operand[0])
+ {
+ /* No conversion performed, add ref to handle return value */
+ AcpiUtAddReference (ReturnDesc);
+ }
+ break;
+
+ case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */
+ case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */
+
+ /* These are two obsolete opcodes */
+
+ ACPI_ERROR ((AE_INFO,
+ "%s is obsolete and not implemented",
+ AcpiPsGetOpcodeName (WalkState->Opcode)));
+ Status = AE_SUPPORT;
+ goto Cleanup;
+
+ default: /* Unknown opcode */
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Store the return value computed above into the target object */
+
+ Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
+ }
+
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+
+ /* Save return object on success */
+
+ else if (!WalkState->ResultObj)
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_1A_0T_1R
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, no target, and a return value
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_1A_0T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *TempDesc;
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Type;
+ UINT64 Value;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the AML opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_LNOT_OP: /* LNot (Operand) */
+
+ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Set result to ONES (TRUE) if Value == 0. Note:
+ * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
+ */
+ if (!Operand[0]->Integer.Value)
+ {
+ ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
+ }
+ break;
+
+ case AML_DECREMENT_OP: /* Decrement (Operand) */
+ case AML_INCREMENT_OP: /* Increment (Operand) */
+ /*
+ * Create a new integer. Can't just get the base integer and
+ * increment it because it may be an Arg or Field.
+ */
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Since we are expecting a Reference operand, it can be either a
+ * NS Node or an internal object.
+ */
+ TempDesc = Operand[0];
+ if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
+ {
+ /* Internal reference object - prevent deletion */
+
+ AcpiUtAddReference (TempDesc);
+ }
+
+ /*
+ * Convert the Reference operand to an Integer (This removes a
+ * reference on the Operand[0] object)
+ *
+ * NOTE: We use LNOT_OP here in order to force resolution of the
+ * reference operand to an actual integer.
+ */
+ Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While resolving operands for [%s]",
+ AcpiPsGetOpcodeName (WalkState->Opcode)));
+
+ goto Cleanup;
+ }
+
+ /*
+ * TempDesc is now guaranteed to be an Integer object --
+ * Perform the actual increment or decrement
+ */
+ if (WalkState->Opcode == AML_INCREMENT_OP)
+ {
+ ReturnDesc->Integer.Value = TempDesc->Integer.Value +1;
+ }
+ else
+ {
+ ReturnDesc->Integer.Value = TempDesc->Integer.Value -1;
+ }
+
+ /* Finished with this Integer object */
+
+ AcpiUtRemoveReference (TempDesc);
+
+ /*
+ * Store the result back (indirectly) through the original
+ * Reference object
+ */
+ Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
+ break;
+
+ case AML_TYPE_OP: /* ObjectType (SourceObject) */
+ /*
+ * Note: The operand is not resolved at this point because we want to
+ * get the associated object, not its value. For example, we don't
+ * want to resolve a FieldUnit to its value, we want the actual
+ * FieldUnit object.
+ */
+
+ /* Get the type of the base object */
+
+ Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Allocate a descriptor to hold the type. */
+
+ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ break;
+
+ case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */
+ /*
+ * Note: The operand is not resolved at this point because we want to
+ * get the associated object, not its value.
+ */
+
+ /* Get the base object */
+
+ Status = AcpiExResolveMultiple (WalkState,
+ Operand[0], &Type, &TempDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * The type of the base object must be integer, buffer, string, or
+ * package. All others are not supported.
+ *
+ * NOTE: Integer is not specifically supported by the ACPI spec,
+ * but is supported implicitly via implicit operand conversion.
+ * rather than bother with conversion, we just use the byte width
+ * global (4 or 8 bytes).
+ */
+ switch (Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ Value = AcpiGbl_IntegerByteWidth;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Value = TempDesc->String.Length;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* Buffer arguments may not be evaluated at this point */
+
+ Status = AcpiDsGetBufferArguments (TempDesc);
+ Value = TempDesc->Buffer.Length;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ /* Package arguments may not be evaluated at this point */
+
+ Status = AcpiDsGetPackageArguments (TempDesc);
+ Value = TempDesc->Package.Count;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Operand must be Buffer/Integer/String/Package - found type %s",
+ AcpiUtGetTypeName (Type)));
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Now that we have the size of the object, create a result
+ * object to hold the value
+ */
+ ReturnDesc = AcpiUtCreateIntegerObject (Value);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ break;
+
+
+ case AML_REF_OF_OP: /* RefOf (SourceObject) */
+
+ Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ break;
+
+
+ case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */
+
+ /* Check for a method local or argument, or standalone String */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
+ {
+ TempDesc = AcpiNsGetAttachedObject (
+ (ACPI_NAMESPACE_NODE *) Operand[0]);
+ if (TempDesc &&
+ ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
+ (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
+ {
+ Operand[0] = TempDesc;
+ AcpiUtAddReference (TempDesc);
+ }
+ else
+ {
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+ }
+ else
+ {
+ switch ((Operand[0])->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ /*
+ * This is a DerefOf (LocalX | ArgX)
+ *
+ * Must resolve/dereference the local/arg reference first
+ */
+ switch (Operand[0]->Reference.Class)
+ {
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_ARG:
+
+ /* Set Operand[0] to the value of the local/arg */
+
+ Status = AcpiDsMethodDataGetValue (
+ Operand[0]->Reference.Class,
+ Operand[0]->Reference.Value,
+ WalkState, &TempDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Delete our reference to the input object and
+ * point to the object just retrieved
+ */
+ AcpiUtRemoveReference (Operand[0]);
+ Operand[0] = TempDesc;
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ /* Get the object to which the reference refers */
+
+ TempDesc = Operand[0]->Reference.Object;
+ AcpiUtRemoveReference (Operand[0]);
+ Operand[0] = TempDesc;
+ break;
+
+ default:
+
+ /* Must be an Index op - handled below */
+ break;
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ break;
+
+ default:
+
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
+ {
+ if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
+ {
+ /*
+ * This is a DerefOf (String). The string is a reference
+ * to a named ACPI object.
+ *
+ * 1) Find the owning Node
+ * 2) Dereference the node to an actual object. Could be a
+ * Field, so we need to resolve the node to a value.
+ */
+ Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
+ Operand[0]->String.Pointer,
+ ACPI_NS_SEARCH_PARENT,
+ ACPI_CAST_INDIRECT_PTR (
+ ACPI_NAMESPACE_NODE, &ReturnDesc));
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ Status = AcpiExResolveNodeToValue (
+ ACPI_CAST_INDIRECT_PTR (
+ ACPI_NAMESPACE_NODE, &ReturnDesc),
+ WalkState);
+ goto Cleanup;
+ }
+ }
+
+ /* Operand[0] may have changed from the code above */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
+ {
+ /*
+ * This is a DerefOf (ObjectReference)
+ * Get the actual object from the Node (This is the dereference).
+ * This case may only happen when a LocalX or ArgX is
+ * dereferenced above.
+ */
+ ReturnDesc = AcpiNsGetAttachedObject (
+ (ACPI_NAMESPACE_NODE *) Operand[0]);
+ AcpiUtAddReference (ReturnDesc);
+ }
+ else
+ {
+ /*
+ * This must be a reference object produced by either the
+ * Index() or RefOf() operator
+ */
+ switch (Operand[0]->Reference.Class)
+ {
+ case ACPI_REFCLASS_INDEX:
+ /*
+ * The target type for the Index operator must be
+ * either a Buffer or a Package
+ */
+ switch (Operand[0]->Reference.TargetType)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ TempDesc = Operand[0]->Reference.Object;
+
+ /*
+ * Create a new object that contains one element of the
+ * buffer -- the element pointed to by the index.
+ *
+ * NOTE: index into a buffer is NOT a pointer to a
+ * sub-buffer of the main buffer, it is only a pointer to a
+ * single element (byte) of the buffer!
+ *
+ * Since we are returning the value of the buffer at the
+ * indexed location, we don't need to add an additional
+ * reference to the buffer itself.
+ */
+ ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
+ TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * Return the referenced element of the package. We must
+ * add another reference to the referenced object, however.
+ */
+ ReturnDesc = *(Operand[0]->Reference.Where);
+ if (!ReturnDesc)
+ {
+ /*
+ * Element is NULL, do not allow the dereference.
+ * This provides compatibility with other ACPI
+ * implementations.
+ */
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT);
+ }
+
+ AcpiUtAddReference (ReturnDesc);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown Index TargetType 0x%X in reference object %p",
+ Operand[0]->Reference.TargetType, Operand[0]));
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ ReturnDesc = Operand[0]->Reference.Object;
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
+ ACPI_DESC_TYPE_NAMED)
+ {
+ ReturnDesc = AcpiNsGetAttachedObject (
+ (ACPI_NAMESPACE_NODE *) ReturnDesc);
+ if (!ReturnDesc)
+ {
+ break;
+ }
+
+ /*
+ * June 2013:
+ * BufferFields/FieldUnits require additional resolution
+ */
+ switch (ReturnDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ Status = AcpiExReadDataFromField (WalkState,
+ ReturnDesc, &TempDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ReturnDesc = TempDesc;
+ break;
+
+ default:
+
+ /* Add another reference to the object */
+
+ AcpiUtAddReference (ReturnDesc);
+ break;
+ }
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown class in reference(%p) - 0x%2.2X",
+ Operand[0], Operand[0]->Reference.Class));
+
+ Status = AE_TYPE;
+ goto Cleanup;
+ }
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+
+ /* Save return object on success */
+
+ else
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg2.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg2.c
new file mode 100644
index 0000000000..e11c0b38ed
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg2.c
@@ -0,0 +1,635 @@
+/******************************************************************************
+ *
+ * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exoparg2")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ * AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS: The number of arguments (input operands) that are
+ * required for this opcode type (1 through 6 args).
+ * yT - TARGETS: The number of targets (output operands) that are required
+ * for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ * as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_2A_0T_0R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with two arguments, no target, and no return
+ * value.
+ *
+ * ALLOCATION: Deletes both operands
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_2A_0T_0R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_NAMESPACE_NODE *Node;
+ UINT32 Value;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_0R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Examine the opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_NOTIFY_OP: /* Notify (NotifyObject, NotifyValue) */
+
+ /* The first operand is a namespace node */
+
+ Node = (ACPI_NAMESPACE_NODE *) Operand[0];
+
+ /* Second value is the notify value */
+
+ Value = (UINT32) Operand[1]->Integer.Value;
+
+ /* Are notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Unexpected notify object type [%s]",
+ AcpiUtGetTypeName (Node->Type)));
+
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ /*
+ * Dispatch the notify to the appropriate handler
+ * NOTE: the request is queued for execution after this method
+ * completes. The notify handlers are NOT invoked synchronously
+ * from this thread -- because handlers may in turn run other
+ * control methods.
+ */
+ Status = AcpiEvQueueNotifyRequest (Node, Value);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_2A_2T_1R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
+ * and one implicit return value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_2A_2T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc1 = NULL;
+ ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_2T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Execute the opcode */
+
+ switch (WalkState->Opcode)
+ {
+ case AML_DIVIDE_OP:
+
+ /* Divide (Dividend, Divisor, RemainderResult QuotientResult) */
+
+ ReturnDesc1 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc1)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ ReturnDesc2 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc2)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Quotient to ReturnDesc1, remainder to ReturnDesc2 */
+
+ Status = AcpiUtDivide (Operand[0]->Integer.Value,
+ Operand[1]->Integer.Value,
+ &ReturnDesc1->Integer.Value,
+ &ReturnDesc2->Integer.Value);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+ /* Store the results to the target reference operands */
+
+ Status = AcpiExStore (ReturnDesc2, Operand[2], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ Status = AcpiExStore (ReturnDesc1, Operand[3], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+Cleanup:
+ /*
+ * Since the remainder is not returned indirectly, remove a reference to
+ * it. Only the quotient is returned indirectly.
+ */
+ AcpiUtRemoveReference (ReturnDesc2);
+
+ if (ACPI_FAILURE (Status))
+ {
+ /* Delete the return object */
+
+ AcpiUtRemoveReference (ReturnDesc1);
+ }
+
+ /* Save return object (the remainder) on success */
+
+ else
+ {
+ WalkState->ResultObj = ReturnDesc1;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_2A_1T_1R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with two arguments, one target, and a return
+ * value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_2A_1T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ UINT64 Index;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_SIZE Length = 0;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_1T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Execute the opcode */
+
+ if (WalkState->OpInfo->Flags & AML_MATH)
+ {
+ /* All simple math opcodes (add, etc.) */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ ReturnDesc->Integer.Value = AcpiExDoMathOp (WalkState->Opcode,
+ Operand[0]->Integer.Value,
+ Operand[1]->Integer.Value);
+ goto StoreResultToTarget;
+ }
+
+ switch (WalkState->Opcode)
+ {
+ case AML_MOD_OP: /* Mod (Dividend, Divisor, RemainderResult (ACPI 2.0) */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* ReturnDesc will contain the remainder */
+
+ Status = AcpiUtDivide (Operand[0]->Integer.Value,
+ Operand[1]->Integer.Value,
+ NULL,
+ &ReturnDesc->Integer.Value);
+ break;
+
+ case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
+
+ Status = AcpiExDoConcatenate (Operand[0], Operand[1],
+ &ReturnDesc, WalkState);
+ break;
+
+ case AML_TO_STRING_OP: /* ToString (Buffer, Length, Result) (ACPI 2.0) */
+ /*
+ * Input object is guaranteed to be a buffer at this point (it may have
+ * been converted.) Copy the raw buffer data to a new object of
+ * type String.
+ */
+
+ /*
+ * Get the length of the new string. It is the smallest of:
+ * 1) Length of the input buffer
+ * 2) Max length as specified in the ToString operator
+ * 3) Length of input buffer up to a zero byte (null terminator)
+ *
+ * NOTE: A length of zero is ok, and will create a zero-length, null
+ * terminated string.
+ */
+ while ((Length < Operand[0]->Buffer.Length) &&
+ (Length < Operand[1]->Integer.Value) &&
+ (Operand[0]->Buffer.Pointer[Length]))
+ {
+ Length++;
+ }
+
+ /* Allocate a new string object */
+
+ ReturnDesc = AcpiUtCreateStringObject (Length);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Copy the raw buffer data with no transform.
+ * (NULL terminated already)
+ */
+ memcpy (ReturnDesc->String.Pointer,
+ Operand[0]->Buffer.Pointer, Length);
+ break;
+
+ case AML_CONCAT_RES_OP:
+
+ /* ConcatenateResTemplate (Buffer, Buffer, Result) (ACPI 2.0) */
+
+ Status = AcpiExConcatTemplate (Operand[0], Operand[1],
+ &ReturnDesc, WalkState);
+ break;
+
+ case AML_INDEX_OP: /* Index (Source Index Result) */
+
+ /* Create the internal return object */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Initialize the Index reference object */
+
+ Index = Operand[1]->Integer.Value;
+ ReturnDesc->Reference.Value = (UINT32) Index;
+ ReturnDesc->Reference.Class = ACPI_REFCLASS_INDEX;
+
+ /*
+ * At this point, the Source operand is a String, Buffer, or Package.
+ * Verify that the index is within range.
+ */
+ switch ((Operand[0])->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ if (Index >= Operand[0]->String.Length)
+ {
+ Length = Operand[0]->String.Length;
+ Status = AE_AML_STRING_LIMIT;
+ }
+
+ ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
+ ReturnDesc->Reference.IndexPointer =
+ &(Operand[0]->Buffer.Pointer [Index]);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ if (Index >= Operand[0]->Buffer.Length)
+ {
+ Length = Operand[0]->Buffer.Length;
+ Status = AE_AML_BUFFER_LIMIT;
+ }
+
+ ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
+ ReturnDesc->Reference.IndexPointer =
+ &(Operand[0]->Buffer.Pointer [Index]);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ if (Index >= Operand[0]->Package.Count)
+ {
+ Length = Operand[0]->Package.Count;
+ Status = AE_AML_PACKAGE_LIMIT;
+ }
+
+ ReturnDesc->Reference.TargetType = ACPI_TYPE_PACKAGE;
+ ReturnDesc->Reference.Where =
+ &Operand[0]->Package.Elements [Index];
+ break;
+
+ default:
+
+ Status = AE_AML_INTERNAL;
+ goto Cleanup;
+ }
+
+ /* Failure means that the Index was beyond the end of the object */
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Index (0x%X%8.8X) is beyond end of object (length 0x%X)",
+ ACPI_FORMAT_UINT64 (Index), (UINT32) Length));
+ goto Cleanup;
+ }
+
+ /*
+ * Save the target object and add a reference to it for the life
+ * of the index
+ */
+ ReturnDesc->Reference.Object = Operand[0];
+ AcpiUtAddReference (Operand[0]);
+
+ /* Store the reference to the Target */
+
+ Status = AcpiExStore (ReturnDesc, Operand[2], WalkState);
+
+ /* Return the reference */
+
+ WalkState->ResultObj = ReturnDesc;
+ goto Cleanup;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ break;
+ }
+
+
+StoreResultToTarget:
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * Store the result of the operation (which is now in ReturnDesc) into
+ * the Target descriptor.
+ */
+ Status = AcpiExStore (ReturnDesc, Operand[2], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ if (!WalkState->ResultObj)
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+ }
+
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ WalkState->ResultObj = NULL;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_2A_0T_1R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_2A_0T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ ACPI_STATUS Status = AE_OK;
+ BOOLEAN LogicalResult = FALSE;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ /* Create the internal return object */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Execute the Opcode */
+
+ if (WalkState->OpInfo->Flags & AML_LOGICAL_NUMERIC)
+ {
+ /* LogicalOp (Operand0, Operand1) */
+
+ Status = AcpiExDoLogicalNumericOp (WalkState->Opcode,
+ Operand[0]->Integer.Value, Operand[1]->Integer.Value,
+ &LogicalResult);
+ goto StoreLogicalResult;
+ }
+ else if (WalkState->OpInfo->Flags & AML_LOGICAL)
+ {
+ /* LogicalOp (Operand0, Operand1) */
+
+ Status = AcpiExDoLogicalOp (WalkState->Opcode, Operand[0],
+ Operand[1], &LogicalResult);
+ goto StoreLogicalResult;
+ }
+
+ switch (WalkState->Opcode)
+ {
+ case AML_ACQUIRE_OP: /* Acquire (MutexObject, Timeout) */
+
+ Status = AcpiExAcquireMutex (Operand[1], Operand[0], WalkState);
+ if (Status == AE_TIME)
+ {
+ LogicalResult = TRUE; /* TRUE = Acquire timed out */
+ Status = AE_OK;
+ }
+ break;
+
+
+ case AML_WAIT_OP: /* Wait (EventObject, Timeout) */
+
+ Status = AcpiExSystemWaitEvent (Operand[1], Operand[0]);
+ if (Status == AE_TIME)
+ {
+ LogicalResult = TRUE; /* TRUE, Wait timed out */
+ Status = AE_OK;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+
+StoreLogicalResult:
+ /*
+ * Set return value to according to LogicalResult. logical TRUE (all ones)
+ * Default is FALSE (zero)
+ */
+ if (LogicalResult)
+ {
+ ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
+ }
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+
+ /* Save return object on success */
+
+ else
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg3.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg3.c
new file mode 100644
index 0000000000..54636bc19c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg3.c
@@ -0,0 +1,307 @@
+/******************************************************************************
+ *
+ * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exoparg3")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ * AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS: The number of arguments (input operands) that are
+ * required for this opcode type (1 through 6 args).
+ * yT - TARGETS: The number of targets (output operands) that are required
+ * for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ * as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_3A_0T_0R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute Triadic operator (3 operands)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_3A_0T_0R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_SIGNAL_FATAL_INFO *Fatal;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_3A_0T_0R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ switch (WalkState->Opcode)
+ {
+ case AML_FATAL_OP: /* Fatal (FatalType FatalCode FatalArg) */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "FatalOp: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
+ (UINT32) Operand[0]->Integer.Value,
+ (UINT32) Operand[1]->Integer.Value,
+ (UINT32) Operand[2]->Integer.Value));
+
+ Fatal = ACPI_ALLOCATE (sizeof (ACPI_SIGNAL_FATAL_INFO));
+ if (Fatal)
+ {
+ Fatal->Type = (UINT32) Operand[0]->Integer.Value;
+ Fatal->Code = (UINT32) Operand[1]->Integer.Value;
+ Fatal->Argument = (UINT32) Operand[2]->Integer.Value;
+ }
+
+ /* Always signal the OS! */
+
+ Status = AcpiOsSignal (ACPI_SIGNAL_FATAL, Fatal);
+
+ /* Might return while OS is shutting down, just continue */
+
+ ACPI_FREE (Fatal);
+ goto Cleanup;
+
+ case AML_EXTERNAL_OP:
+ /*
+ * If the interpreter sees this opcode, just ignore it. The External
+ * op is intended for use by disassemblers in order to properly
+ * disassemble control method invocations. The opcode or group of
+ * opcodes should be surrounded by an "if (0)" clause to ensure that
+ * AML interpreters never see the opcode.
+ */
+ Status = AE_OK;
+ goto Cleanup;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_3A_1T_1R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute Triadic operator (3 operands)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_3A_1T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ char *Buffer = NULL;
+ ACPI_STATUS Status = AE_OK;
+ UINT64 Index;
+ ACPI_SIZE Length;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_3A_1T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ switch (WalkState->Opcode)
+ {
+ case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
+ /*
+ * Create the return object. The Source operand is guaranteed to be
+ * either a String or a Buffer, so just use its type.
+ */
+ ReturnDesc = AcpiUtCreateInternalObject (
+ (Operand[0])->Common.Type);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Get the Integer values from the objects */
+
+ Index = Operand[1]->Integer.Value;
+ Length = (ACPI_SIZE) Operand[2]->Integer.Value;
+
+ /*
+ * If the index is beyond the length of the String/Buffer, or if the
+ * requested length is zero, return a zero-length String/Buffer
+ */
+ if (Index >= Operand[0]->String.Length)
+ {
+ Length = 0;
+ }
+
+ /* Truncate request if larger than the actual String/Buffer */
+
+ else if ((Index + Length) > Operand[0]->String.Length)
+ {
+ Length = (ACPI_SIZE) Operand[0]->String.Length -
+ (ACPI_SIZE) Index;
+ }
+
+ /* Strings always have a sub-pointer, not so for buffers */
+
+ switch ((Operand[0])->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ /* Always allocate a new buffer for the String */
+
+ Buffer = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) Length + 1);
+ if (!Buffer)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* If the requested length is zero, don't allocate a buffer */
+
+ if (Length > 0)
+ {
+ /* Allocate a new buffer for the Buffer */
+
+ Buffer = ACPI_ALLOCATE_ZEROED (Length);
+ if (!Buffer)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+ }
+ break;
+
+ default: /* Should not happen */
+
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup;
+ }
+
+ if (Buffer)
+ {
+ /* We have a buffer, copy the portion requested */
+
+ memcpy (Buffer, Operand[0]->String.Pointer + Index,
+ Length);
+ }
+
+ /* Set the length of the new String/Buffer */
+
+ ReturnDesc->String.Pointer = Buffer;
+ ReturnDesc->String.Length = (UINT32) Length;
+
+ /* Mark buffer initialized */
+
+ ReturnDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+ /* Store the result in the target */
+
+ Status = AcpiExStore (ReturnDesc, Operand[3], WalkState);
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status) || WalkState->ResultObj)
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ WalkState->ResultObj = NULL;
+ }
+
+ /* Set the return object and exit */
+
+ else
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg6.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg6.c
new file mode 100644
index 0000000000..4ff355c900
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exoparg6.c
@@ -0,0 +1,355 @@
+/******************************************************************************
+ *
+ * Module Name: exoparg6 - AML execution - opcodes with 6 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exoparg6")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ * AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS: The number of arguments (input operands) that are
+ * required for this opcode type (1 through 6 args).
+ * yT - TARGETS: The number of targets (output operands) that are required
+ * for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ * as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+/* Local prototypes */
+
+static BOOLEAN
+AcpiExDoMatch (
+ UINT32 MatchOp,
+ ACPI_OPERAND_OBJECT *PackageObj,
+ ACPI_OPERAND_OBJECT *MatchObj);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoMatch
+ *
+ * PARAMETERS: MatchOp - The AML match operand
+ * PackageObj - Object from the target package
+ * MatchObj - Object to be matched
+ *
+ * RETURN: TRUE if the match is successful, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the low-level match for the ASL Match operator.
+ * Package elements will be implicitly converted to the type of
+ * the match object (Integer/Buffer/String).
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiExDoMatch (
+ UINT32 MatchOp,
+ ACPI_OPERAND_OBJECT *PackageObj,
+ ACPI_OPERAND_OBJECT *MatchObj)
+{
+ BOOLEAN LogicalResult = TRUE;
+ ACPI_STATUS Status;
+
+
+ /*
+ * Note: Since the PackageObj/MatchObj ordering is opposite to that of
+ * the standard logical operators, we have to reverse them when we call
+ * DoLogicalOp in order to make the implicit conversion rules work
+ * correctly. However, this means we have to flip the entire equation
+ * also. A bit ugly perhaps, but overall, better than fussing the
+ * parameters around at runtime, over and over again.
+ *
+ * Below, P[i] refers to the package element, M refers to the Match object.
+ */
+ switch (MatchOp)
+ {
+ case MATCH_MTR:
+
+ /* Always true */
+
+ break;
+
+ case MATCH_MEQ:
+ /*
+ * True if equal: (P[i] == M)
+ * Change to: (M == P[i])
+ */
+ Status = AcpiExDoLogicalOp (AML_LEQUAL_OP, MatchObj, PackageObj,
+ &LogicalResult);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+ break;
+
+ case MATCH_MLE:
+ /*
+ * True if less than or equal: (P[i] <= M) (P[i] NotGreater than M)
+ * Change to: (M >= P[i]) (M NotLess than P[i])
+ */
+ Status = AcpiExDoLogicalOp (AML_LLESS_OP, MatchObj, PackageObj,
+ &LogicalResult);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+ LogicalResult = (BOOLEAN) !LogicalResult;
+ break;
+
+ case MATCH_MLT:
+ /*
+ * True if less than: (P[i] < M)
+ * Change to: (M > P[i])
+ */
+ Status = AcpiExDoLogicalOp (AML_LGREATER_OP, MatchObj, PackageObj,
+ &LogicalResult);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+ break;
+
+ case MATCH_MGE:
+ /*
+ * True if greater than or equal: (P[i] >= M) (P[i] NotLess than M)
+ * Change to: (M <= P[i]) (M NotGreater than P[i])
+ */
+ Status = AcpiExDoLogicalOp (AML_LGREATER_OP, MatchObj, PackageObj,
+ &LogicalResult);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+ LogicalResult = (BOOLEAN)!LogicalResult;
+ break;
+
+ case MATCH_MGT:
+ /*
+ * True if greater than: (P[i] > M)
+ * Change to: (M < P[i])
+ */
+ Status = AcpiExDoLogicalOp (AML_LLESS_OP, MatchObj, PackageObj,
+ &LogicalResult);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+ break;
+
+ default:
+
+ /* Undefined */
+
+ return (FALSE);
+ }
+
+ return (LogicalResult);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExOpcode_6A_0T_1R
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExOpcode_6A_0T_1R (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
+ ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
+ ACPI_STATUS Status = AE_OK;
+ UINT64 Index;
+ ACPI_OPERAND_OBJECT *ThisElement;
+
+
+ ACPI_FUNCTION_TRACE_STR (ExOpcode_6A_0T_1R,
+ AcpiPsGetOpcodeName (WalkState->Opcode));
+
+
+ switch (WalkState->Opcode)
+ {
+ case AML_MATCH_OP:
+ /*
+ * Match (SearchPkg[0], MatchOp1[1], MatchObj1[2],
+ * MatchOp2[3], MatchObj2[4], StartIndex[5])
+ */
+
+ /* Validate both Match Term Operators (MTR, MEQ, etc.) */
+
+ if ((Operand[1]->Integer.Value > MAX_MATCH_OPERATOR) ||
+ (Operand[3]->Integer.Value > MAX_MATCH_OPERATOR))
+ {
+ ACPI_ERROR ((AE_INFO, "Match operator out of range"));
+ Status = AE_AML_OPERAND_VALUE;
+ goto Cleanup;
+ }
+
+ /* Get the package StartIndex, validate against the package length */
+
+ Index = Operand[5]->Integer.Value;
+ if (Index >= Operand[0]->Package.Count)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Index (0x%8.8X%8.8X) beyond package end (0x%X)",
+ ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count));
+ Status = AE_AML_PACKAGE_LIMIT;
+ goto Cleanup;
+ }
+
+ /* Create an integer for the return value */
+ /* Default return value is ACPI_UINT64_MAX if no match found */
+
+ ReturnDesc = AcpiUtCreateIntegerObject (ACPI_UINT64_MAX);
+ if (!ReturnDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+
+ }
+
+ /*
+ * Examine each element until a match is found. Both match conditions
+ * must be satisfied for a match to occur. Within the loop,
+ * "continue" signifies that the current element does not match
+ * and the next should be examined.
+ *
+ * Upon finding a match, the loop will terminate via "break" at
+ * the bottom. If it terminates "normally", MatchValue will be
+ * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no
+ * match was found.
+ */
+ for ( ; Index < Operand[0]->Package.Count; Index++)
+ {
+ /* Get the current package element */
+
+ ThisElement = Operand[0]->Package.Elements[Index];
+
+ /* Treat any uninitialized (NULL) elements as non-matching */
+
+ if (!ThisElement)
+ {
+ continue;
+ }
+
+ /*
+ * Both match conditions must be satisfied. Execution of a continue
+ * (proceed to next iteration of enclosing for loop) signifies a
+ * non-match.
+ */
+ if (!AcpiExDoMatch ((UINT32) Operand[1]->Integer.Value,
+ ThisElement, Operand[2]))
+ {
+ continue;
+ }
+
+ if (!AcpiExDoMatch ((UINT32) Operand[3]->Integer.Value,
+ ThisElement, Operand[4]))
+ {
+ continue;
+ }
+
+ /* Match found: Index is the return value */
+
+ ReturnDesc->Integer.Value = Index;
+ break;
+ }
+ break;
+
+ case AML_LOAD_TABLE_OP:
+
+ Status = AcpiExLoadTableOp (WalkState, &ReturnDesc);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ WalkState->Opcode));
+ Status = AE_AML_BAD_OPCODE;
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ /* Delete return object on error */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+
+ /* Save return object on success */
+
+ else
+ {
+ WalkState->ResultObj = ReturnDesc;
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exprep.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exprep.c
new file mode 100644
index 0000000000..c949d8a95e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exprep.c
@@ -0,0 +1,651 @@
+/******************************************************************************
+ *
+ * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exprep")
+
+/* Local prototypes */
+
+static UINT32
+AcpiExDecodeFieldAccess (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 FieldFlags,
+ UINT32 *ReturnByteAlignment);
+
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+
+static UINT32
+AcpiExGenerateAccess (
+ UINT32 FieldBitOffset,
+ UINT32 FieldBitLength,
+ UINT32 RegionLength);
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGenerateAccess
+ *
+ * PARAMETERS: FieldBitOffset - Start of field within parent region/buffer
+ * FieldBitLength - Length of field in bits
+ * RegionLength - Length of parent in bytes
+ *
+ * RETURN: Field granularity (8, 16, 32 or 64) and
+ * ByteAlignment (1, 2, 3, or 4)
+ *
+ * DESCRIPTION: Generate an optimal access width for fields defined with the
+ * AnyAcc keyword.
+ *
+ * NOTE: Need to have the RegionLength in order to check for boundary
+ * conditions (end-of-region). However, the RegionLength is a deferred
+ * operation. Therefore, to complete this implementation, the generation
+ * of this access width must be deferred until the region length has
+ * been evaluated.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiExGenerateAccess (
+ UINT32 FieldBitOffset,
+ UINT32 FieldBitLength,
+ UINT32 RegionLength)
+{
+ UINT32 FieldByteLength;
+ UINT32 FieldByteOffset;
+ UINT32 FieldByteEndOffset;
+ UINT32 AccessByteWidth;
+ UINT32 FieldStartOffset;
+ UINT32 FieldEndOffset;
+ UINT32 MinimumAccessWidth = 0xFFFFFFFF;
+ UINT32 MinimumAccesses = 0xFFFFFFFF;
+ UINT32 Accesses;
+
+
+ ACPI_FUNCTION_TRACE (ExGenerateAccess);
+
+
+ /* Round Field start offset and length to "minimal" byte boundaries */
+
+ FieldByteOffset = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8));
+ FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP (FieldBitLength +
+ FieldBitOffset, 8));
+ FieldByteLength = FieldByteEndOffset - FieldByteOffset;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Bit length %u, Bit offset %u\n",
+ FieldBitLength, FieldBitOffset));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Byte Length %u, Byte Offset %u, End Offset %u\n",
+ FieldByteLength, FieldByteOffset, FieldByteEndOffset));
+
+ /*
+ * Iterative search for the maximum access width that is both aligned
+ * and does not go beyond the end of the region
+ *
+ * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes)
+ */
+ for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1)
+ {
+ /*
+ * 1) Round end offset up to next access boundary and make sure that
+ * this does not go beyond the end of the parent region.
+ * 2) When the Access width is greater than the FieldByteLength, we
+ * are done. (This does not optimize for the perfectly aligned
+ * case yet).
+ */
+ if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength)
+ {
+ FieldStartOffset =
+ ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) /
+ AccessByteWidth;
+
+ FieldEndOffset =
+ ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset),
+ AccessByteWidth) / AccessByteWidth;
+
+ Accesses = FieldEndOffset - FieldStartOffset;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "AccessWidth %u end is within region\n", AccessByteWidth));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Field Start %u, Field End %u -- requires %u accesses\n",
+ FieldStartOffset, FieldEndOffset, Accesses));
+
+ /* Single access is optimal */
+
+ if (Accesses <= 1)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Entire field can be accessed with one operation of size %u\n",
+ AccessByteWidth));
+ return_VALUE (AccessByteWidth);
+ }
+
+ /*
+ * Fits in the region, but requires more than one read/write.
+ * try the next wider access on next iteration
+ */
+ if (Accesses < MinimumAccesses)
+ {
+ MinimumAccesses = Accesses;
+ MinimumAccessWidth = AccessByteWidth;
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "AccessWidth %u end is NOT within region\n", AccessByteWidth));
+ if (AccessByteWidth == 1)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Field goes beyond end-of-region!\n"));
+
+ /* Field does not fit in the region at all */
+
+ return_VALUE (0);
+ }
+
+ /*
+ * This width goes beyond the end-of-region, back off to
+ * previous access
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Backing off to previous optimal access width of %u\n",
+ MinimumAccessWidth));
+ return_VALUE (MinimumAccessWidth);
+ }
+ }
+
+ /*
+ * Could not read/write field with one operation,
+ * just use max access width
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Cannot access field in one operation, using width 8\n"));
+ return_VALUE (8);
+}
+#endif /* ACPI_UNDER_DEVELOPMENT */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDecodeFieldAccess
+ *
+ * PARAMETERS: ObjDesc - Field object
+ * FieldFlags - Encoded fieldflags (contains access bits)
+ * ReturnByteAlignment - Where the byte alignment is returned
+ *
+ * RETURN: Field granularity (8, 16, 32 or 64) and
+ * ByteAlignment (1, 2, 3, or 4)
+ *
+ * DESCRIPTION: Decode the AccessType bits of a field definition.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiExDecodeFieldAccess (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 FieldFlags,
+ UINT32 *ReturnByteAlignment)
+{
+ UINT32 Access;
+ UINT32 ByteAlignment;
+ UINT32 BitLength;
+
+
+ ACPI_FUNCTION_TRACE (ExDecodeFieldAccess);
+
+
+ Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK);
+
+ switch (Access)
+ {
+ case AML_FIELD_ACCESS_ANY:
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+ ByteAlignment =
+ AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BitLength,
+ 0xFFFFFFFF /* Temp until we pass RegionLength as parameter */);
+ BitLength = ByteAlignment * 8;
+#endif
+
+ ByteAlignment = 1;
+ BitLength = 8;
+ break;
+
+ case AML_FIELD_ACCESS_BYTE:
+ case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
+
+ ByteAlignment = 1;
+ BitLength = 8;
+ break;
+
+ case AML_FIELD_ACCESS_WORD:
+
+ ByteAlignment = 2;
+ BitLength = 16;
+ break;
+
+ case AML_FIELD_ACCESS_DWORD:
+
+ ByteAlignment = 4;
+ BitLength = 32;
+ break;
+
+ case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
+
+ ByteAlignment = 8;
+ BitLength = 64;
+ break;
+
+ default:
+
+ /* Invalid field access type */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown field access type 0x%X",
+ Access));
+ return_UINT32 (0);
+ }
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
+ {
+ /*
+ * BufferField access can be on any byte boundary, so the
+ * ByteAlignment is always 1 byte -- regardless of any ByteAlignment
+ * implied by the field access type.
+ */
+ ByteAlignment = 1;
+ }
+
+ *ReturnByteAlignment = ByteAlignment;
+ return_UINT32 (BitLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExPrepCommonFieldObject
+ *
+ * PARAMETERS: ObjDesc - The field object
+ * FieldFlags - Access, LockRule, and UpdateRule.
+ * The format of a FieldFlag is described
+ * in the ACPI specification
+ * FieldAttribute - Special attributes (not used)
+ * FieldBitPosition - Field start position
+ * FieldBitLength - Field length in number of bits
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the areas of the field object that are common
+ * to the various types of fields. Note: This is very "sensitive"
+ * code because we are solving the general case for field
+ * alignment.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExPrepCommonFieldObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 FieldFlags,
+ UINT8 FieldAttribute,
+ UINT32 FieldBitPosition,
+ UINT32 FieldBitLength)
+{
+ UINT32 AccessBitWidth;
+ UINT32 ByteAlignment;
+ UINT32 NearestByteAddress;
+
+
+ ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject);
+
+
+ /*
+ * Note: the structure being initialized is the
+ * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common
+ * area are initialized by this procedure.
+ */
+ ObjDesc->CommonField.FieldFlags = FieldFlags;
+ ObjDesc->CommonField.Attribute = FieldAttribute;
+ ObjDesc->CommonField.BitLength = FieldBitLength;
+
+ /*
+ * Decode the access type so we can compute offsets. The access type gives
+ * two pieces of information - the width of each field access and the
+ * necessary ByteAlignment (address granularity) of the access.
+ *
+ * For AnyAcc, the AccessBitWidth is the largest width that is both
+ * necessary and possible in an attempt to access the whole field in one
+ * I/O operation. However, for AnyAcc, the ByteAlignment is always one
+ * byte.
+ *
+ * For all Buffer Fields, the ByteAlignment is always one byte.
+ *
+ * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
+ * the same (equivalent) as the ByteAlignment.
+ */
+ AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags,
+ &ByteAlignment);
+ if (!AccessBitWidth)
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ }
+
+ /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
+
+ ObjDesc->CommonField.AccessByteWidth = (UINT8)
+ ACPI_DIV_8 (AccessBitWidth);
+
+ /*
+ * BaseByteOffset is the address of the start of the field within the
+ * region. It is the byte address of the first *datum* (field-width data
+ * unit) of the field. (i.e., the first datum that contains at least the
+ * first *bit* of the field.)
+ *
+ * Note: ByteAlignment is always either equal to the AccessBitWidth or 8
+ * (Byte access), and it defines the addressing granularity of the parent
+ * region or buffer.
+ */
+ NearestByteAddress =
+ ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition);
+ ObjDesc->CommonField.BaseByteOffset = (UINT32)
+ ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment);
+
+ /*
+ * StartFieldBitOffset is the offset of the first bit of the field within
+ * a field datum.
+ */
+ ObjDesc->CommonField.StartFieldBitOffset = (UINT8)
+ (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExPrepFieldValue
+ *
+ * PARAMETERS: Info - Contains all field creation info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a
+ * subtype of DefField and connect it to the parent Node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExPrepFieldValue (
+ ACPI_CREATE_FIELD_INFO *Info)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *SecondDesc = NULL;
+ ACPI_STATUS Status;
+ UINT32 AccessByteWidth;
+ UINT32 Type;
+
+
+ ACPI_FUNCTION_TRACE (ExPrepFieldValue);
+
+
+ /* Parameter validation */
+
+ if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD)
+ {
+ if (!Info->RegionNode)
+ {
+ ACPI_ERROR ((AE_INFO, "Null RegionNode"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ Type = AcpiNsGetType (Info->RegionNode);
+ if (Type != ACPI_TYPE_REGION)
+ {
+ ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
+ Type, AcpiUtGetTypeName (Type)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ }
+
+ /* Allocate a new field object */
+
+ ObjDesc = AcpiUtCreateInternalObject (Info->FieldType);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize areas of the object that are common to all fields */
+
+ ObjDesc->CommonField.Node = Info->FieldNode;
+ Status = AcpiExPrepCommonFieldObject (ObjDesc,
+ Info->FieldFlags, Info->Attribute,
+ Info->FieldBitPosition, Info->FieldBitLength);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Initialize areas of the object that are specific to the field type */
+
+ switch (Info->FieldType)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
+
+ /* Fields specific to GenericSerialBus fields */
+
+ ObjDesc->Field.AccessLength = Info->AccessLength;
+
+ if (Info->ConnectionNode)
+ {
+ SecondDesc = Info->ConnectionNode->Object;
+ if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferArguments (SecondDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ ObjDesc->Field.ResourceBuffer = SecondDesc->Buffer.Pointer;
+ ObjDesc->Field.ResourceLength = (UINT16) SecondDesc->Buffer.Length;
+ }
+ else if (Info->ResourceBuffer)
+ {
+ ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer;
+ ObjDesc->Field.ResourceLength = Info->ResourceLength;
+ }
+
+ ObjDesc->Field.PinNumberIndex = Info->PinNumberIndex;
+
+ /* Allow full data read from EC address space */
+
+ if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
+ (ObjDesc->CommonField.BitLength > 8))
+ {
+ AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES (
+ ObjDesc->CommonField.BitLength);
+
+ /* Maximum byte width supported is 255 */
+
+ if (AccessByteWidth < 256)
+ {
+ ObjDesc->CommonField.AccessByteWidth = (UINT8) AccessByteWidth;
+ }
+ }
+
+ /* An additional reference for the container */
+
+ AcpiUtAddReference (ObjDesc->Field.RegionObj);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
+ ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset,
+ ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj));
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ ObjDesc->BankField.Value = Info->BankValue;
+ ObjDesc->BankField.RegionObj =
+ AcpiNsGetAttachedObject (Info->RegionNode);
+ ObjDesc->BankField.BankObj =
+ AcpiNsGetAttachedObject (Info->RegisterNode);
+
+ /* An additional reference for the attached objects */
+
+ AcpiUtAddReference (ObjDesc->BankField.RegionObj);
+ AcpiUtAddReference (ObjDesc->BankField.BankObj);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
+ ObjDesc->BankField.StartFieldBitOffset,
+ ObjDesc->BankField.BaseByteOffset,
+ ObjDesc->Field.AccessByteWidth,
+ ObjDesc->BankField.RegionObj,
+ ObjDesc->BankField.BankObj));
+
+ /*
+ * Remember location in AML stream of the field unit
+ * opcode and operands -- since the BankValue
+ * operands must be evaluated.
+ */
+ SecondDesc = ObjDesc->Common.NextObject;
+ SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
+ Info->DataRegisterNode)->Named.Data;
+ SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
+ Info->DataRegisterNode)->Named.Length;
+
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ /* Get the Index and Data registers */
+
+ ObjDesc->IndexField.IndexObj =
+ AcpiNsGetAttachedObject (Info->RegisterNode);
+ ObjDesc->IndexField.DataObj =
+ AcpiNsGetAttachedObject (Info->DataRegisterNode);
+
+ if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
+ {
+ ACPI_ERROR ((AE_INFO, "Null Index Object during field prep"));
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /* An additional reference for the attached objects */
+
+ AcpiUtAddReference (ObjDesc->IndexField.DataObj);
+ AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
+
+ /*
+ * April 2006: Changed to match MS behavior
+ *
+ * The value written to the Index register is the byte offset of the
+ * target field in units of the granularity of the IndexField
+ *
+ * Previously, the value was calculated as an index in terms of the
+ * width of the Data register, as below:
+ *
+ * ObjDesc->IndexField.Value = (UINT32)
+ * (Info->FieldBitPosition / ACPI_MUL_8 (
+ * ObjDesc->Field.AccessByteWidth));
+ *
+ * February 2006: Tried value as a byte offset:
+ * ObjDesc->IndexField.Value = (UINT32)
+ * ACPI_DIV_8 (Info->FieldBitPosition);
+ */
+ ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN (
+ ACPI_DIV_8 (Info->FieldBitPosition),
+ ObjDesc->IndexField.AccessByteWidth);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
+ ObjDesc->IndexField.StartFieldBitOffset,
+ ObjDesc->IndexField.BaseByteOffset,
+ ObjDesc->IndexField.Value,
+ ObjDesc->Field.AccessByteWidth,
+ ObjDesc->IndexField.IndexObj,
+ ObjDesc->IndexField.DataObj));
+ break;
+
+ default:
+
+ /* No other types should get here */
+
+ break;
+ }
+
+ /*
+ * Store the constructed descriptor (ObjDesc) into the parent Node,
+ * preserving the current type of that NamedObj.
+ */
+ Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc,
+ AcpiNsGetType (Info->FieldNode));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n",
+ Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc));
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exregion.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exregion.c
new file mode 100644
index 0000000000..6bfdf7bf18
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exregion.c
@@ -0,0 +1,577 @@
+/******************************************************************************
+ *
+ * Module Name: exregion - ACPI default OpRegion (address space) handlers
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exregion")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemMemorySpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the System Memory address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemMemorySpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+ void *LogicalAddrPtr = NULL;
+ ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext;
+ UINT32 Length;
+ ACPI_SIZE MapLength;
+ ACPI_SIZE PageBoundaryMapLength;
+#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
+ UINT32 Remainder;
+#endif
+
+
+ ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
+
+
+ /* Validate and translate the bit width */
+
+ switch (BitWidth)
+ {
+ case 8:
+
+ Length = 1;
+ break;
+
+ case 16:
+
+ Length = 2;
+ break;
+
+ case 32:
+
+ Length = 4;
+ break;
+
+ case 64:
+
+ Length = 8;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
+ BitWidth));
+ return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ }
+
+#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
+ /*
+ * Hardware does not support non-aligned data transfers, we must verify
+ * the request.
+ */
+ (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder);
+ if (Remainder != 0)
+ {
+ return_ACPI_STATUS (AE_AML_ALIGNMENT);
+ }
+#endif
+
+ /*
+ * Does the request fit into the cached memory mapping?
+ * Is 1) Address below the current mapping? OR
+ * 2) Address beyond the current mapping?
+ */
+ if ((Address < MemInfo->MappedPhysicalAddress) ||
+ (((UINT64) Address + Length) >
+ ((UINT64)
+ MemInfo->MappedPhysicalAddress + MemInfo->MappedLength)))
+ {
+ /*
+ * The request cannot be resolved by the current memory mapping;
+ * Delete the existing mapping and create a new one.
+ */
+ if (MemInfo->MappedLength)
+ {
+ /* Valid mapping, delete it */
+
+ AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress,
+ MemInfo->MappedLength);
+ }
+
+ /*
+ * October 2009: Attempt to map from the requested address to the
+ * end of the region. However, we will never map more than one
+ * page, nor will we cross a page boundary.
+ */
+ MapLength = (ACPI_SIZE)
+ ((MemInfo->Address + MemInfo->Length) - Address);
+
+ /*
+ * If mapping the entire remaining portion of the region will cross
+ * a page boundary, just map up to the page boundary, do not cross.
+ * On some systems, crossing a page boundary while mapping regions
+ * can cause warnings if the pages have different attributes
+ * due to resource management.
+ *
+ * This has the added benefit of constraining a single mapping to
+ * one page, which is similar to the original code that used a 4k
+ * maximum window.
+ */
+ PageBoundaryMapLength = (ACPI_SIZE)
+ (ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address);
+ if (PageBoundaryMapLength == 0)
+ {
+ PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
+ }
+
+ if (MapLength > PageBoundaryMapLength)
+ {
+ MapLength = PageBoundaryMapLength;
+ }
+
+ /* Create a new mapping starting at the address given */
+
+ MemInfo->MappedLogicalAddress = AcpiOsMapMemory (Address, MapLength);
+ if (!MemInfo->MappedLogicalAddress)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not map memory at 0x%8.8X%8.8X, size %u",
+ ACPI_FORMAT_UINT64 (Address), (UINT32) MapLength));
+ MemInfo->MappedLength = 0;
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Save the physical address and mapping size */
+
+ MemInfo->MappedPhysicalAddress = Address;
+ MemInfo->MappedLength = MapLength;
+ }
+
+ /*
+ * Generate a logical pointer corresponding to the address we want to
+ * access
+ */
+ LogicalAddrPtr = MemInfo->MappedLogicalAddress +
+ ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
+ BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
+
+ /*
+ * Perform the memory read or write
+ *
+ * Note: For machines that do not support non-aligned transfers, the target
+ * address was checked for alignment above. We do not attempt to break the
+ * transfer up into smaller (byte-size) chunks because the AML specifically
+ * asked for a transfer width that the hardware may require.
+ */
+ switch (Function)
+ {
+ case ACPI_READ:
+
+ *Value = 0;
+ switch (BitWidth)
+ {
+ case 8:
+
+ *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
+ break;
+
+ case 16:
+
+ *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
+ break;
+
+ case 32:
+
+ *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
+ break;
+
+ case 64:
+
+ *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
+ break;
+
+ default:
+
+ /* BitWidth was already validated */
+
+ break;
+ }
+ break;
+
+ case ACPI_WRITE:
+
+ switch (BitWidth)
+ {
+ case 8:
+
+ ACPI_SET8 (LogicalAddrPtr, *Value);
+ break;
+
+ case 16:
+
+ ACPI_SET16 (LogicalAddrPtr, *Value);
+ break;
+
+ case 32:
+
+ ACPI_SET32 (LogicalAddrPtr, *Value);
+ break;
+
+ case 64:
+
+ ACPI_SET64 (LogicalAddrPtr, *Value);
+ break;
+
+ default:
+
+ /* BitWidth was already validated */
+
+ break;
+ }
+ break;
+
+ default:
+
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemIoSpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the System IO address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemIoSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Value32;
+
+
+ ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
+ BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
+
+ /* Decode the function parameter */
+
+ switch (Function)
+ {
+ case ACPI_READ:
+
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
+ &Value32, BitWidth);
+ *Value = Value32;
+ break;
+
+ case ACPI_WRITE:
+
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
+ (UINT32) *Value, BitWidth);
+ break;
+
+ default:
+
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExPciConfigSpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the PCI Config address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExPciConfigSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PCI_ID *PciId;
+ UINT16 PciRegister;
+
+
+ ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
+
+
+ /*
+ * The arguments to AcpiOs(Read|Write)PciConfiguration are:
+ *
+ * PciSegment is the PCI bus segment range 0-31
+ * PciBus is the PCI bus number range 0-255
+ * PciDevice is the PCI device number range 0-31
+ * PciFunction is the PCI device function number
+ * PciRegister is the Config space register range 0-255 bytes
+ *
+ * Value - input value for write, output address for read
+ *
+ */
+ PciId = (ACPI_PCI_ID *) RegionContext;
+ PciRegister = (UINT16) (UINT32) Address;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
+ Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
+ PciId->Function, PciRegister));
+
+ switch (Function)
+ {
+ case ACPI_READ:
+
+ *Value = 0;
+ Status = AcpiOsReadPciConfiguration (PciId, PciRegister,
+ Value, BitWidth);
+ break;
+
+ case ACPI_WRITE:
+
+ Status = AcpiOsWritePciConfiguration (PciId, PciRegister,
+ *Value, BitWidth);
+ break;
+
+ default:
+
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCmosSpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the CMOS address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCmosSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
+
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExPciBarSpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExPciBarSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
+
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDataTableSpaceHandler
+ *
+ * PARAMETERS: Function - Read or Write operation
+ * Address - Where in the space to read or write
+ * BitWidth - Field width in bits (8, 16, or 32)
+ * Value - Pointer to in or out value
+ * HandlerContext - Pointer to Handler's context
+ * RegionContext - Pointer to context specific to the
+ * accessed region
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handler for the Data Table address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExDataTableSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext)
+{
+ ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
+
+
+ /*
+ * Perform the memory read or write. The BitWidth was already
+ * validated.
+ */
+ switch (Function)
+ {
+ case ACPI_READ:
+
+ memcpy (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
+ ACPI_DIV_8 (BitWidth));
+ break;
+
+ case ACPI_WRITE:
+
+ memcpy (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
+ ACPI_DIV_8 (BitWidth));
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresnte.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresnte.c
new file mode 100644
index 0000000000..ee4f8190e6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresnte.c
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * Module Name: exresnte - AML Interpreter object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exresnte")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveNodeToValue
+ *
+ * PARAMETERS: ObjectPtr - Pointer to a location that contains
+ * a pointer to a NS node, and will receive a
+ * pointer to the resolved object.
+ * WalkState - Current state. Valid only if executing AML
+ * code. NULL if simply resolving an object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Resolve a Namespace node to a valued object
+ *
+ * Note: for some of the data types, the pointer attached to the Node
+ * can be either a pointer to an actual internal object or a pointer into the
+ * AML stream itself. These types are currently:
+ *
+ * ACPI_TYPE_INTEGER
+ * ACPI_TYPE_STRING
+ * ACPI_TYPE_BUFFER
+ * ACPI_TYPE_MUTEX
+ * ACPI_TYPE_PACKAGE
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExResolveNodeToValue (
+ ACPI_NAMESPACE_NODE **ObjectPtr,
+ ACPI_WALK_STATE *WalkState)
+
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *SourceDesc;
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OBJECT_TYPE EntryType;
+
+
+ ACPI_FUNCTION_TRACE (ExResolveNodeToValue);
+
+
+ /*
+ * The stack pointer points to a ACPI_NAMESPACE_NODE (Node). Get the
+ * object that is attached to the Node.
+ */
+ Node = *ObjectPtr;
+ SourceDesc = AcpiNsGetAttachedObject (Node);
+ EntryType = AcpiNsGetType ((ACPI_HANDLE) Node);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n",
+ Node, SourceDesc, AcpiUtGetTypeName (EntryType)));
+
+ if ((EntryType == ACPI_TYPE_LOCAL_ALIAS) ||
+ (EntryType == ACPI_TYPE_LOCAL_METHOD_ALIAS))
+ {
+ /* There is always exactly one level of indirection */
+
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object);
+ SourceDesc = AcpiNsGetAttachedObject (Node);
+ EntryType = AcpiNsGetType ((ACPI_HANDLE) Node);
+ *ObjectPtr = Node;
+ }
+
+ /*
+ * Several object types require no further processing:
+ * 1) Device/Thermal objects don't have a "real" subobject, return the Node
+ * 2) Method locals and arguments have a pseudo-Node
+ * 3) 10/2007: Added method type to assist with Package construction.
+ */
+ if ((EntryType == ACPI_TYPE_DEVICE) ||
+ (EntryType == ACPI_TYPE_THERMAL) ||
+ (EntryType == ACPI_TYPE_METHOD) ||
+ (Node->Flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL)))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (!SourceDesc)
+ {
+ ACPI_ERROR ((AE_INFO, "No object attached to node [%4.4s] %p",
+ Node->Name.Ascii, Node));
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_NODE);
+ }
+
+ /*
+ * Action is based on the type of the Node, which indicates the type
+ * of the attached object or pointer
+ */
+ switch (EntryType)
+ {
+ case ACPI_TYPE_PACKAGE:
+
+ if (SourceDesc->Common.Type != ACPI_TYPE_PACKAGE)
+ {
+ ACPI_ERROR ((AE_INFO, "Object not a Package, type %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ Status = AcpiDsGetPackageArguments (SourceDesc);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)
+ {
+ ACPI_ERROR ((AE_INFO, "Object not a Buffer, type %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ Status = AcpiDsGetBufferArguments (SourceDesc);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ if (SourceDesc->Common.Type != ACPI_TYPE_STRING)
+ {
+ ACPI_ERROR ((AE_INFO, "Object not a String, type %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ ACPI_ERROR ((AE_INFO, "Object not a Integer, type %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "FieldRead Node=%p SourceDesc=%p Type=%X\n",
+ Node, SourceDesc, EntryType));
+
+ Status = AcpiExReadDataFromField (WalkState, SourceDesc, &ObjDesc);
+ break;
+
+ /* For these objects, just return the object attached to the Node */
+
+ case ACPI_TYPE_MUTEX:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_EVENT:
+ case ACPI_TYPE_REGION:
+
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ break;
+
+ /* TYPE_ANY is untyped, and thus there is no object associated with it */
+
+ case ACPI_TYPE_ANY:
+
+ ACPI_ERROR ((AE_INFO,
+ "Untyped entry %p, no attached object!", Node));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ switch (SourceDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_TABLE: /* This is a DdbHandle */
+ case ACPI_REFCLASS_REFOF:
+ case ACPI_REFCLASS_INDEX:
+
+ /* Return an additional reference to the object */
+
+ ObjDesc = SourceDesc;
+ AcpiUtAddReference (ObjDesc);
+ break;
+
+ default:
+
+ /* No named references are allowed here */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unsupported Reference type 0x%X",
+ SourceDesc->Reference.Class));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ break;
+
+ default:
+
+ /* Default case is for unknown types */
+
+ ACPI_ERROR ((AE_INFO,
+ "Node %p - Unknown object type 0x%X",
+ Node, EntryType));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+
+ } /* switch (EntryType) */
+
+
+ /* Return the object descriptor */
+
+ *ObjectPtr = (void *) ObjDesc;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresolv.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresolv.c
new file mode 100644
index 0000000000..bead3e44f5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresolv.c
@@ -0,0 +1,575 @@
+/******************************************************************************
+ *
+ * Module Name: exresolv - AML Interpreter object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exresolv")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiExResolveObjectToValue (
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveToValue
+ *
+ * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
+ * be either an (ACPI_OPERAND_OBJECT *)
+ * or an ACPI_HANDLE.
+ * WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert Reference objects to values
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExResolveToValue (
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr);
+
+
+ if (!StackPtr || !*StackPtr)
+ {
+ ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ /*
+ * The entity pointed to by the StackPtr can be either
+ * 1) A valid ACPI_OPERAND_OBJECT, or
+ * 2) A ACPI_NAMESPACE_NODE (NamedObj)
+ */
+ if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND)
+ {
+ Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!*StackPtr)
+ {
+ ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+ }
+
+ /*
+ * Object on the stack may have changed if AcpiExResolveObjectToValue()
+ * was called (i.e., we can't use an _else_ here.)
+ */
+ if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED)
+ {
+ Status = AcpiExResolveNodeToValue (
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveObjectToValue
+ *
+ * PARAMETERS: StackPtr - Pointer to an internal object
+ * WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve the value from an internal object. The Reference type
+ * uses the associated AML opcode to determine the value.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExResolveObjectToValue (
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *StackDesc;
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ UINT8 RefType;
+
+
+ ACPI_FUNCTION_TRACE (ExResolveObjectToValue);
+
+
+ StackDesc = *StackPtr;
+
+ /* This is an object of type ACPI_OPERAND_OBJECT */
+
+ switch (StackDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ RefType = StackDesc->Reference.Class;
+
+ switch (RefType)
+ {
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_ARG:
+ /*
+ * Get the local from the method's state info
+ * Note: this increments the local's object reference count
+ */
+ Status = AcpiDsMethodDataGetValue (RefType,
+ StackDesc->Reference.Value, WalkState, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
+ StackDesc->Reference.Value, ObjDesc));
+
+ /*
+ * Now we can delete the original Reference Object and
+ * replace it with the resolved value
+ */
+ AcpiUtRemoveReference (StackDesc);
+ *StackPtr = ObjDesc;
+ break;
+
+ case ACPI_REFCLASS_INDEX:
+
+ switch (StackDesc->Reference.TargetType)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ /* Just return - do not dereference */
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ /* If method call or CopyObject - do not dereference */
+
+ if ((WalkState->Opcode == AML_INT_METHODCALL_OP) ||
+ (WalkState->Opcode == AML_COPY_OP))
+ {
+ break;
+ }
+
+ /* Otherwise, dereference the PackageIndex to a package element */
+
+ ObjDesc = *StackDesc->Reference.Where;
+ if (ObjDesc)
+ {
+ /*
+ * Valid object descriptor, copy pointer to return value
+ * (i.e., dereference the package index)
+ * Delete the ref object, increment the returned object
+ */
+ AcpiUtRemoveReference (StackDesc);
+ AcpiUtAddReference (ObjDesc);
+ *StackPtr = ObjDesc;
+ }
+ else
+ {
+ /*
+ * A NULL object descriptor means an uninitialized element of
+ * the package, can't dereference it
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Attempt to dereference an Index to NULL package element Idx=%p",
+ StackDesc));
+ Status = AE_AML_UNINITIALIZED_ELEMENT;
+ }
+ break;
+
+ default:
+
+ /* Invalid reference object */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown TargetType 0x%X in Index/Reference object %p",
+ StackDesc->Reference.TargetType, StackDesc));
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+ case ACPI_REFCLASS_DEBUG:
+ case ACPI_REFCLASS_TABLE:
+
+ /* Just leave the object as-is, do not dereference */
+
+ break;
+
+ case ACPI_REFCLASS_NAME: /* Reference to a named object */
+
+ /* Dereference the name */
+
+ if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) ||
+ (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL))
+ {
+ /* These node types do not have 'real' subobjects */
+
+ *StackPtr = (void *) StackDesc->Reference.Node;
+ }
+ else
+ {
+ /* Get the object pointed to by the namespace node */
+
+ *StackPtr = (StackDesc->Reference.Node)->Object;
+ AcpiUtAddReference (*StackPtr);
+ }
+
+ AcpiUtRemoveReference (StackDesc);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown Reference type 0x%X in %p", RefType, StackDesc));
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiDsGetBufferArguments (StackDesc);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ Status = AcpiDsGetPackageArguments (StackDesc);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead SourceDesc=%p Type=%X\n",
+ StackDesc, StackDesc->Common.Type));
+
+ Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
+
+ /* Remove a reference to the original operand, then override */
+
+ AcpiUtRemoveReference (*StackPtr);
+ *StackPtr = (void *) ObjDesc;
+ break;
+
+ default:
+
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveMultiple
+ *
+ * PARAMETERS: WalkState - Current state (contains AML opcode)
+ * Operand - Starting point for resolution
+ * ReturnType - Where the object type is returned
+ * ReturnDesc - Where the resolved object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Return the base object and type. Traverse a reference list if
+ * necessary to get to the base object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExResolveMultiple (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *Operand,
+ ACPI_OBJECT_TYPE *ReturnType,
+ ACPI_OPERAND_OBJECT **ReturnDesc)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc = ACPI_CAST_PTR (void, Operand);
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Operand);
+ ACPI_OBJECT_TYPE Type;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);
+
+
+ /* Operand can be either a namespace node or an operand descriptor */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ Type = ObjDesc->Common.Type;
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+
+ Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+
+ /* If we had an Alias node, use the attached object for type info */
+
+ if (Type == ACPI_TYPE_LOCAL_ALIAS)
+ {
+ Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
+ ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
+ }
+
+ if (!ObjDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "[%4.4s] Node is unresolved or uninitialized",
+ AcpiUtGetNodeName (Node)));
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_NODE);
+ }
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* If type is anything other than a reference, we are done */
+
+ if (Type != ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ goto Exit;
+ }
+
+ /*
+ * For reference objects created via the RefOf, Index, or Load/LoadTable
+ * operators, we need to get to the base object (as per the ACPI
+ * specification of the ObjectType and SizeOf operators). This means
+ * traversing the list of possibly many nested references.
+ */
+ while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_REFOF:
+ case ACPI_REFCLASS_NAME:
+
+ /* Dereference the reference pointer */
+
+ if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
+ {
+ Node = ObjDesc->Reference.Object;
+ }
+ else /* AML_INT_NAMEPATH_OP */
+ {
+ Node = ObjDesc->Reference.Node;
+ }
+
+ /* All "References" point to a NS node */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Not a namespace node %p [%s]",
+ Node, AcpiUtGetDescriptorName (Node)));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /* Get the attached object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /* No object, use the NS node type */
+
+ Type = AcpiNsGetType (Node);
+ goto Exit;
+ }
+
+ /* Check for circular references */
+
+ if (ObjDesc == Operand)
+ {
+ return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
+ }
+ break;
+
+ case ACPI_REFCLASS_INDEX:
+
+ /* Get the type of this reference (index into another object) */
+
+ Type = ObjDesc->Reference.TargetType;
+ if (Type != ACPI_TYPE_PACKAGE)
+ {
+ goto Exit;
+ }
+
+ /*
+ * The main object is a package, we want to get the type
+ * of the individual package element that is referenced by
+ * the index.
+ *
+ * This could of course in turn be another reference object.
+ */
+ ObjDesc = *(ObjDesc->Reference.Where);
+ if (!ObjDesc)
+ {
+ /* NULL package elements are allowed */
+
+ Type = 0; /* Uninitialized */
+ goto Exit;
+ }
+ break;
+
+ case ACPI_REFCLASS_TABLE:
+
+ Type = ACPI_TYPE_DDB_HANDLE;
+ goto Exit;
+
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_ARG:
+
+ if (ReturnDesc)
+ {
+ Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
+ ObjDesc->Reference.Value, WalkState, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ else
+ {
+ Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
+ ObjDesc->Reference.Value, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ Type = ACPI_TYPE_ANY;
+ goto Exit;
+ }
+ }
+ break;
+
+ case ACPI_REFCLASS_DEBUG:
+
+ /* The Debug Object is of type "DebugObject" */
+
+ Type = ACPI_TYPE_DEBUG_OBJECT;
+ goto Exit;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+ }
+
+ /*
+ * Now we are guaranteed to have an object that has not been created
+ * via the RefOf or Index operators.
+ */
+ Type = ObjDesc->Common.Type;
+
+
+Exit:
+ /* Convert internal types to external types */
+
+ switch (Type)
+ {
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ Type = ACPI_TYPE_FIELD_UNIT;
+ break;
+
+ case ACPI_TYPE_LOCAL_SCOPE:
+
+ /* Per ACPI Specification, Scope is untyped */
+
+ Type = ACPI_TYPE_ANY;
+ break;
+
+ default:
+
+ /* No change to Type required */
+
+ break;
+ }
+
+ *ReturnType = Type;
+ if (ReturnDesc)
+ {
+ *ReturnDesc = ObjDesc;
+ }
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresop.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresop.c
new file mode 100644
index 0000000000..5171f56201
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exresop.c
@@ -0,0 +1,722 @@
+/******************************************************************************
+ *
+ * Module Name: exresop - AML Interpreter operand/object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exresop")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiExCheckObjectType (
+ ACPI_OBJECT_TYPE TypeNeeded,
+ ACPI_OBJECT_TYPE ThisType,
+ void *Object);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExCheckObjectType
+ *
+ * PARAMETERS: TypeNeeded Object type needed
+ * ThisType Actual object type
+ * Object Object pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check required type against actual type
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExCheckObjectType (
+ ACPI_OBJECT_TYPE TypeNeeded,
+ ACPI_OBJECT_TYPE ThisType,
+ void *Object)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (TypeNeeded == ACPI_TYPE_ANY)
+ {
+ /* All types OK, so we don't perform any typechecks */
+
+ return (AE_OK);
+ }
+
+ if (TypeNeeded == ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ /*
+ * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
+ * objects and thus allow them to be targets. (As per the ACPI
+ * specification, a store to a constant is a noop.)
+ */
+ if ((ThisType == ACPI_TYPE_INTEGER) &&
+ (((ACPI_OPERAND_OBJECT *) Object)->Common.Flags & AOPOBJ_AML_CONSTANT))
+ {
+ return (AE_OK);
+ }
+ }
+
+ if (TypeNeeded != ThisType)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Needed type [%s], found [%s] %p",
+ AcpiUtGetTypeName (TypeNeeded),
+ AcpiUtGetTypeName (ThisType), Object));
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveOperands
+ *
+ * PARAMETERS: Opcode - Opcode being interpreted
+ * StackPtr - Pointer to the operand stack to be
+ * resolved
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert multiple input operands to the types required by the
+ * target operator.
+ *
+ * Each 5-bit group in ArgTypes represents one required
+ * operand and indicates the required Type. The corresponding operand
+ * will be converted to the required type if possible, otherwise we
+ * abort with an exception.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExResolveOperands (
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status = AE_OK;
+ UINT8 ObjectType;
+ UINT32 ArgTypes;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 ThisArgType;
+ ACPI_OBJECT_TYPE TypeNeeded;
+ UINT16 TargetOp = 0;
+
+
+ ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode);
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+ if (OpInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ }
+
+ ArgTypes = OpInfo->RuntimeArgs;
+ if (ArgTypes == ARGI_INVALID_OPCODE)
+ {
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
+ Opcode));
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
+ Opcode, OpInfo->Name, ArgTypes));
+
+ /*
+ * Normal exit is with (ArgTypes == 0) at end of argument list.
+ * Function will return an exception from within the loop upon
+ * finding an entry which is not (or cannot be converted
+ * to) the required type; if stack underflows; or upon
+ * finding a NULL stack entry (which should not happen).
+ */
+ while (GET_CURRENT_ARG_TYPE (ArgTypes))
+ {
+ if (!StackPtr || !*StackPtr)
+ {
+ ACPI_ERROR ((AE_INFO, "Null stack entry at %p",
+ StackPtr));
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /* Extract useful items */
+
+ ObjDesc = *StackPtr;
+
+ /* Decode the descriptor type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+
+ /* Namespace Node */
+
+ ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
+
+ /*
+ * Resolve an alias object. The construction of these objects
+ * guarantees that there is only one level of alias indirection;
+ * thus, the attached object is always the aliased namespace node
+ */
+ if (ObjectType == ACPI_TYPE_LOCAL_ALIAS)
+ {
+ ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
+ *StackPtr = ObjDesc;
+ ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
+ }
+ break;
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ /* ACPI internal object */
+
+ ObjectType = ObjDesc->Common.Type;
+
+ /* Check for bad ACPI_OBJECT_TYPE */
+
+ if (!AcpiUtValidObjectType (ObjectType))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Bad operand object type [0x%X]", ObjectType));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ if (ObjectType == (UINT8) ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ /* Validate the Reference */
+
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_DEBUG:
+
+ TargetOp = AML_DEBUG_OP;
+
+ /*lint -fallthrough */
+
+ case ACPI_REFCLASS_ARG:
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_INDEX:
+ case ACPI_REFCLASS_REFOF:
+ case ACPI_REFCLASS_TABLE: /* DdbHandle from LOAD_OP or LOAD_TABLE_OP */
+ case ACPI_REFCLASS_NAME: /* Reference to a named object */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Operand is a Reference, Class [%s] %2.2X\n",
+ AcpiUtGetReferenceName (ObjDesc),
+ ObjDesc->Reference.Class));
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown Reference Class 0x%2.2X in %p",
+ ObjDesc->Reference.Class, ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ }
+ break;
+
+ default:
+
+ /* Invalid descriptor */
+
+ ACPI_ERROR ((AE_INFO, "Invalid descriptor %p [%s]",
+ ObjDesc, AcpiUtGetDescriptorName (ObjDesc)));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Get one argument type, point to the next */
+
+ ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes);
+ INCREMENT_ARG_LIST (ArgTypes);
+
+ /*
+ * Handle cases where the object does not need to be
+ * resolved to a value
+ */
+ switch (ThisArgType)
+ {
+ case ARGI_REF_OR_STRING: /* Can be a String or Reference */
+
+ if ((ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
+ (ObjDesc->Common.Type == ACPI_TYPE_STRING))
+ {
+ /*
+ * String found - the string references a named object and
+ * must be resolved to a node
+ */
+ goto NextOperand;
+ }
+
+ /*
+ * Else not a string - fall through to the normal Reference
+ * case below
+ */
+ /*lint -fallthrough */
+
+ case ARGI_REFERENCE: /* References: */
+ case ARGI_INTEGER_REF:
+ case ARGI_OBJECT_REF:
+ case ARGI_DEVICE_REF:
+ case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
+ case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
+ case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
+ /*
+ * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
+ * A Namespace Node is OK as-is
+ */
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ goto NextOperand;
+ }
+
+ Status = AcpiExCheckObjectType (ACPI_TYPE_LOCAL_REFERENCE,
+ ObjectType, ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ goto NextOperand;
+
+ case ARGI_DATAREFOBJ: /* Store operator only */
+ /*
+ * We don't want to resolve IndexOp reference objects during
+ * a store because this would be an implicit DeRefOf operation.
+ * Instead, we just want to store the reference object.
+ * -- All others must be resolved below.
+ */
+ if ((Opcode == AML_STORE_OP) &&
+ ((*StackPtr)->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ ((*StackPtr)->Reference.Class == ACPI_REFCLASS_INDEX))
+ {
+ goto NextOperand;
+ }
+ break;
+
+ default:
+
+ /* All cases covered above */
+
+ break;
+ }
+
+ /*
+ * Resolve this object to a value
+ */
+ Status = AcpiExResolveToValue (StackPtr, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the resolved object */
+
+ ObjDesc = *StackPtr;
+
+ /*
+ * Check the resulting object (value) type
+ */
+ switch (ThisArgType)
+ {
+ /*
+ * For the simple cases, only one type of resolved object
+ * is allowed
+ */
+ case ARGI_MUTEX:
+
+ /* Need an operand of type ACPI_TYPE_MUTEX */
+
+ TypeNeeded = ACPI_TYPE_MUTEX;
+ break;
+
+ case ARGI_EVENT:
+
+ /* Need an operand of type ACPI_TYPE_EVENT */
+
+ TypeNeeded = ACPI_TYPE_EVENT;
+ break;
+
+ case ARGI_PACKAGE: /* Package */
+
+ /* Need an operand of type ACPI_TYPE_PACKAGE */
+
+ TypeNeeded = ACPI_TYPE_PACKAGE;
+ break;
+
+ case ARGI_ANYTYPE:
+
+ /* Any operand type will do */
+
+ TypeNeeded = ACPI_TYPE_ANY;
+ break;
+
+ case ARGI_DDBHANDLE:
+
+ /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
+
+ TypeNeeded = ACPI_TYPE_LOCAL_REFERENCE;
+ break;
+
+
+ /*
+ * The more complex cases allow multiple resolved object types
+ */
+ case ARGI_INTEGER:
+
+ /*
+ * Need an operand of type ACPI_TYPE_INTEGER,
+ * But we can implicitly convert from a STRING or BUFFER
+ * Aka - "Implicit Source Operand Conversion"
+ */
+ Status = AcpiExConvertToInteger (ObjDesc, StackPtr, 16);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_TYPE)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Integer/String/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ObjDesc != *StackPtr)
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ goto NextOperand;
+
+ case ARGI_BUFFER:
+ /*
+ * Need an operand of type ACPI_TYPE_BUFFER,
+ * But we can implicitly convert from a STRING or INTEGER
+ * Aka - "Implicit Source Operand Conversion"
+ */
+ Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_TYPE)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Integer/String/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ObjDesc != *StackPtr)
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ goto NextOperand;
+
+ case ARGI_STRING:
+ /*
+ * Need an operand of type ACPI_TYPE_STRING,
+ * But we can implicitly convert from a BUFFER or INTEGER
+ * Aka - "Implicit Source Operand Conversion"
+ */
+ Status = AcpiExConvertToString (ObjDesc, StackPtr,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_TYPE)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Integer/String/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ObjDesc != *StackPtr)
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ goto NextOperand;
+
+ case ARGI_COMPUTEDATA:
+
+ /* Need an operand of type INTEGER, STRING or BUFFER */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+
+ /* Valid operand */
+ break;
+
+ default:
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Integer/String/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ case ARGI_BUFFER_OR_STRING:
+
+ /* Need an operand of type STRING or BUFFER */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+
+ /* Valid operand */
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ /* Highest priority conversion is to type Buffer */
+
+ Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (ObjDesc != *StackPtr)
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ break;
+
+ default:
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Integer/String/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ case ARGI_DATAOBJECT:
+ /*
+ * ARGI_DATAOBJECT is only used by the SizeOf operator.
+ * Need a buffer, string, package, or RefOf reference.
+ *
+ * The only reference allowed here is a direct reference to
+ * a namespace node.
+ */
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_PACKAGE:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /* Valid operand */
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Buffer/String/Package/Reference], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ case ARGI_COMPLEXOBJ:
+
+ /* Need a buffer or package or (ACPI 2.0) String */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_PACKAGE:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+
+ /* Valid operand */
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Buffer/String/Package], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
+
+ /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_REGION:
+
+ /* Valid operand */
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Needed [Region/Buffer], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ case ARGI_DATAREFOBJ:
+
+ /* Used by the Store() operator only */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_PACKAGE:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ case ACPI_TYPE_DDB_HANDLE:
+
+ /* Valid operand */
+ break;
+
+ default:
+
+ if (AcpiGbl_EnableInterpreterSlack)
+ {
+ /*
+ * Enable original behavior of Store(), allowing any and all
+ * objects as the source operand. The ACPI spec does not
+ * allow this, however.
+ */
+ break;
+ }
+
+ if (TargetOp == AML_DEBUG_OP)
+ {
+ /* Allow store of any object to the Debug object */
+
+ break;
+ }
+
+ ACPI_ERROR ((AE_INFO,
+ "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
+ AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+ goto NextOperand;
+
+ default:
+
+ /* Unknown type */
+
+ ACPI_ERROR ((AE_INFO,
+ "Internal - Unknown ARGI (required operand) type 0x%X",
+ ThisArgType));
+
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Make sure that the original object was resolved to the
+ * required object type (Simple cases only).
+ */
+ Status = AcpiExCheckObjectType (TypeNeeded,
+ (*StackPtr)->Common.Type, *StackPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+NextOperand:
+ /*
+ * If more operands needed, decrement StackPtr to point
+ * to next operand on stack
+ */
+ if (GET_CURRENT_ARG_TYPE (ArgTypes))
+ {
+ StackPtr--;
+ }
+ }
+
+ ACPI_DUMP_OPERANDS (WalkState->Operands,
+ AcpiPsGetOpcodeName (Opcode), WalkState->NumOperands);
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstore.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstore.c
new file mode 100644
index 0000000000..e14ab9474e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstore.c
@@ -0,0 +1,582 @@
+/******************************************************************************
+ *
+ * Module Name: exstore - AML Interpreter object store support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exstore")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiExStoreObjectToIndex (
+ ACPI_OPERAND_OBJECT *ValDesc,
+ ACPI_OPERAND_OBJECT *DestDesc,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+AcpiExStoreDirectToNode (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStore
+ *
+ * PARAMETERS: *SourceDesc - Value to be stored
+ * *DestDesc - Where to store it. Must be an NS node
+ * or ACPI_OPERAND_OBJECT of type
+ * Reference;
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the value described by SourceDesc into the location
+ * described by DestDesc. Called by various interpreter
+ * functions to store the result of an operation into
+ * the destination operand -- not just simply the actual "Store"
+ * ASL operator.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExStore (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *DestDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *RefDesc = DestDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc);
+
+
+ /* Validate parameters */
+
+ if (!SourceDesc || !DestDesc)
+ {
+ ACPI_ERROR ((AE_INFO, "Null parameter"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ /* DestDesc can be either a namespace node or an ACPI object */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ /*
+ * Dest is a namespace node,
+ * Storing an object into a Named node.
+ */
+ Status = AcpiExStoreObjectToNode (SourceDesc,
+ (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
+ ACPI_IMPLICIT_CONVERSION);
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Destination object must be a Reference or a Constant object */
+
+ switch (DestDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ /* Allow stores to Constants -- a Noop as per ACPI spec */
+
+ if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*lint -fallthrough */
+
+ default:
+
+ /* Destination is not a Reference object */
+
+ ACPI_ERROR ((AE_INFO,
+ "Target is not a Reference or Constant object - %s [%p]",
+ AcpiUtGetObjectTypeName (DestDesc), DestDesc));
+
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * Examine the Reference class. These cases are handled:
+ *
+ * 1) Store to Name (Change the object associated with a name)
+ * 2) Store to an indexed area of a Buffer or Package
+ * 3) Store to a Method Local or Arg
+ * 4) Store to the debug object
+ */
+ switch (RefDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_REFOF:
+
+ /* Storing an object into a Name "container" */
+
+ Status = AcpiExStoreObjectToNode (SourceDesc,
+ RefDesc->Reference.Object,
+ WalkState, ACPI_IMPLICIT_CONVERSION);
+ break;
+
+ case ACPI_REFCLASS_INDEX:
+
+ /* Storing to an Index (pointer into a packager or buffer) */
+
+ Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
+ break;
+
+ case ACPI_REFCLASS_LOCAL:
+ case ACPI_REFCLASS_ARG:
+
+ /* Store to a method local/arg */
+
+ Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
+ RefDesc->Reference.Value, SourceDesc, WalkState);
+ break;
+
+ case ACPI_REFCLASS_DEBUG:
+ /*
+ * Storing to the Debug object causes the value stored to be
+ * displayed and otherwise has no effect -- see ACPI Specification
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "**** Write to Debug Object: Object %p %s ****:\n\n",
+ SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
+
+ ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
+ RefDesc->Reference.Class));
+ ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
+
+ Status = AE_AML_INTERNAL;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreObjectToIndex
+ *
+ * PARAMETERS: *SourceDesc - Value to be stored
+ * *DestDesc - Named object to receive the value
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the object to indexed Buffer or Package element
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExStoreObjectToIndex (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *IndexDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *NewDesc;
+ UINT8 Value = 0;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (ExStoreObjectToIndex);
+
+
+ /*
+ * Destination must be a reference pointer, and
+ * must point to either a buffer or a package
+ */
+ switch (IndexDesc->Reference.TargetType)
+ {
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * Storing to a package element. Copy the object and replace
+ * any existing object with the new object. No implicit
+ * conversion is performed.
+ *
+ * The object at *(IndexDesc->Reference.Where) is the
+ * element within the package that is to be modified.
+ * The parent package object is at IndexDesc->Reference.Object
+ */
+ ObjDesc = *(IndexDesc->Reference.Where);
+
+ if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE &&
+ SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
+ {
+ /* This is a DDBHandle, just add a reference to it */
+
+ AcpiUtAddReference (SourceDesc);
+ NewDesc = SourceDesc;
+ }
+ else
+ {
+ /* Normal object, copy it */
+
+ Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ if (ObjDesc)
+ {
+ /* Decrement reference count by the ref count of the parent package */
+
+ for (i = 0;
+ i < ((ACPI_OPERAND_OBJECT *)
+ IndexDesc->Reference.Object)->Common.ReferenceCount;
+ i++)
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ }
+
+ *(IndexDesc->Reference.Where) = NewDesc;
+
+ /* Increment ref count by the ref count of the parent package-1 */
+
+ for (i = 1;
+ i < ((ACPI_OPERAND_OBJECT *)
+ IndexDesc->Reference.Object)->Common.ReferenceCount;
+ i++)
+ {
+ AcpiUtAddReference (NewDesc);
+ }
+
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+ /*
+ * Store into a Buffer or String (not actually a real BufferField)
+ * at a location defined by an Index.
+ *
+ * The first 8-bit element of the source object is written to the
+ * 8-bit Buffer location defined by the Index destination object,
+ * according to the ACPI 2.0 specification.
+ */
+
+ /*
+ * Make sure the target is a Buffer or String. An error should
+ * not happen here, since the ReferenceObject was constructed
+ * by the INDEX_OP code.
+ */
+ ObjDesc = IndexDesc->Reference.Object;
+ if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) &&
+ (ObjDesc->Common.Type != ACPI_TYPE_STRING))
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * The assignment of the individual elements will be slightly
+ * different for each source type.
+ */
+ switch (SourceDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* Use the least-significant byte of the integer */
+
+ Value = (UINT8) (SourceDesc->Integer.Value);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_STRING:
+
+ /* Note: Takes advantage of common string/buffer fields */
+
+ Value = SourceDesc->Buffer.Pointer[0];
+ break;
+
+ default:
+
+ /* All other types are invalid */
+
+ ACPI_ERROR ((AE_INFO,
+ "Source must be Integer/Buffer/String type, not %s",
+ AcpiUtGetObjectTypeName (SourceDesc)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Store the source value into the target buffer byte */
+
+ ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
+ break;
+
+ default:
+ ACPI_ERROR ((AE_INFO,
+ "Target is not a Package or BufferField"));
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreObjectToNode
+ *
+ * PARAMETERS: SourceDesc - Value to be stored
+ * Node - Named object to receive the value
+ * WalkState - Current walk state
+ * ImplicitConversion - Perform implicit conversion (yes/no)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ * The Assignment of an object to a named object is handled here
+ * The value passed in will replace the current value (if any)
+ * with the input value.
+ *
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation. A CopyObject can change
+ * the target type, however.
+ *
+ * The ImplicitConversion flag is set to NO/FALSE only when
+ * storing to an ArgX -- as per the rules of the ACPI spec.
+ *
+ * Assumes parameters are already validated.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExStoreObjectToNode (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_WALK_STATE *WalkState,
+ UINT8 ImplicitConversion)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *TargetDesc;
+ ACPI_OPERAND_OBJECT *NewDesc;
+ ACPI_OBJECT_TYPE TargetType;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc);
+
+
+ /* Get current type of the node, and object attached to Node */
+
+ TargetType = AcpiNsGetType (Node);
+ TargetDesc = AcpiNsGetAttachedObject (Node);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
+ SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
+ Node, AcpiUtGetTypeName (TargetType)));
+
+ /*
+ * Resolve the source object to an actual value
+ * (If it is a reference object)
+ */
+ Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Do the actual store operation */
+
+ switch (TargetType)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * The simple data types all support implicit source operand
+ * conversion before the store.
+ */
+
+ if ((WalkState->Opcode == AML_COPY_OP) ||
+ !ImplicitConversion)
+ {
+ /*
+ * However, CopyObject and Stores to ArgX do not perform
+ * an implicit conversion, as per the ACPI specification.
+ * A direct store is performed instead.
+ */
+ Status = AcpiExStoreDirectToNode (SourceDesc, Node,
+ WalkState);
+ break;
+ }
+
+ /* Store with implicit source operand conversion support */
+
+ Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
+ &NewDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (NewDesc != TargetDesc)
+ {
+ /*
+ * Store the new NewDesc as the new value of the Name, and set
+ * the Name's type to that of the value being stored in it.
+ * SourceDesc reference count is incremented by AttachObject.
+ *
+ * Note: This may change the type of the node if an explicit
+ * store has been performed such that the node/object type
+ * has been changed.
+ */
+ Status = AcpiNsAttachObject (Node, NewDesc,
+ NewDesc->Common.Type);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Store %s into %s via Convert/Attach\n",
+ AcpiUtGetObjectTypeName (SourceDesc),
+ AcpiUtGetObjectTypeName (NewDesc)));
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ /*
+ * For all fields, always write the source data to the target
+ * field. Any required implicit source operand conversion is
+ * performed in the function below as necessary. Note, field
+ * objects must retain their original type permanently.
+ */
+ Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
+ &WalkState->ResultObj);
+ break;
+
+ default:
+ /*
+ * No conversions for all other types. Directly store a copy of
+ * the source object. This is the ACPI spec-defined behavior for
+ * the CopyObject operator.
+ *
+ * NOTE: For the Store operator, this is a departure from the
+ * ACPI spec, which states "If conversion is impossible, abort
+ * the running control method". Instead, this code implements
+ * "If conversion is impossible, treat the Store operation as
+ * a CopyObject".
+ */
+ Status = AcpiExStoreDirectToNode (SourceDesc, Node,
+ WalkState);
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreDirectToNode
+ *
+ * PARAMETERS: SourceDesc - Value to be stored
+ * Node - Named object to receive the value
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: "Store" an object directly to a node. This involves a copy
+ * and an attach.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExStoreDirectToNode (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *NewDesc;
+
+
+ ACPI_FUNCTION_TRACE (ExStoreDirectToNode);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Storing [%s] (%p) directly into node [%s] (%p)"
+ " with no implicit conversion\n",
+ AcpiUtGetObjectTypeName (SourceDesc), SourceDesc,
+ AcpiUtGetTypeName (Node->Type), Node));
+
+ /* Copy the source object to a new object */
+
+ Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Attach the new object to the node */
+
+ Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
+ AcpiUtRemoveReference (NewDesc);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstoren.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstoren.c
new file mode 100644
index 0000000000..cc56fbd431
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstoren.c
@@ -0,0 +1,303 @@
+/******************************************************************************
+ *
+ * Module Name: exstoren - AML Interpreter object store support,
+ * Store to Node (namespace object)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exstoren")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExResolveObject
+ *
+ * PARAMETERS: SourceDescPtr - Pointer to the source object
+ * TargetType - Current type of the target
+ * WalkState - Current walk state
+ *
+ * RETURN: Status, resolved object in SourceDescPtr.
+ *
+ * DESCRIPTION: Resolve an object. If the object is a reference, dereference
+ * it and return the actual object in the SourceDescPtr.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExResolveObject (
+ ACPI_OPERAND_OBJECT **SourceDescPtr,
+ ACPI_OBJECT_TYPE TargetType,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *SourceDesc = *SourceDescPtr;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExResolveObject);
+
+
+ /* Ensure we have a Target that can be stored to */
+
+ switch (TargetType)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ /*
+ * These cases all require only Integers or values that
+ * can be converted to Integers (Strings or Buffers)
+ */
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * Stores into a Field/Region or into a Integer/Buffer/String
+ * are all essentially the same. This case handles the
+ * "interchangeable" types Integer, String, and Buffer.
+ */
+ if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ /* Resolve a reference object first */
+
+ Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+
+ /* For CopyObject, no further validation necessary */
+
+ if (WalkState->Opcode == AML_COPY_OP)
+ {
+ break;
+ }
+
+ /* Must have a Integer, Buffer, or String */
+
+ if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) &&
+ (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) &&
+ (SourceDesc->Common.Type != ACPI_TYPE_STRING) &&
+ !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
+ {
+ /* Conversion successful but still not a valid type */
+
+ ACPI_ERROR ((AE_INFO,
+ "Cannot assign type %s to %s (must be type Int/Str/Buf)",
+ AcpiUtGetObjectTypeName (SourceDesc),
+ AcpiUtGetTypeName (TargetType)));
+ Status = AE_AML_OPERAND_TYPE;
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_ALIAS:
+ case ACPI_TYPE_LOCAL_METHOD_ALIAS:
+ /*
+ * All aliases should have been resolved earlier, during the
+ * operand resolution phase.
+ */
+ ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
+ Status = AE_AML_INTERNAL;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ default:
+ /*
+ * All other types than Alias and the various Fields come here,
+ * including the untyped case - ACPI_TYPE_ANY.
+ */
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreObjectToObject
+ *
+ * PARAMETERS: SourceDesc - Object to store
+ * DestDesc - Object to receive a copy of the source
+ * NewDesc - New object if DestDesc is obsoleted
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: "Store" an object to another object. This may include
+ * converting the source type to the target type (implicit
+ * conversion), and a copy of the value of the source to
+ * the target.
+ *
+ * The Assignment of an object to another (not named) object
+ * is handled here.
+ * The Source passed in will replace the current value (if any)
+ * with the input value.
+ *
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation.
+ *
+ * This module allows destination types of Number, String,
+ * Buffer, and Package.
+ *
+ * Assumes parameters are already validated. NOTE: SourceDesc
+ * resolution (from a reference object) must be performed by
+ * the caller if necessary.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExStoreObjectToObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *DestDesc,
+ ACPI_OPERAND_OBJECT **NewDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *ActualSrcDesc;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
+
+
+ ActualSrcDesc = SourceDesc;
+ if (!DestDesc)
+ {
+ /*
+ * There is no destination object (An uninitialized node or
+ * package element), so we can simply copy the source object
+ * creating a new destination object
+ */
+ Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
+ return_ACPI_STATUS (Status);
+ }
+
+ if (SourceDesc->Common.Type != DestDesc->Common.Type)
+ {
+ /*
+ * The source type does not match the type of the destination.
+ * Perform the "implicit conversion" of the source to the current type
+ * of the target as per the ACPI specification.
+ *
+ * If no conversion performed, ActualSrcDesc = SourceDesc.
+ * Otherwise, ActualSrcDesc is a temporary object to hold the
+ * converted object.
+ */
+ Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
+ SourceDesc, &ActualSrcDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (SourceDesc == ActualSrcDesc)
+ {
+ /*
+ * No conversion was performed. Return the SourceDesc as the
+ * new object.
+ */
+ *NewDesc = SourceDesc;
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ /*
+ * We now have two objects of identical types, and we can perform a
+ * copy of the *value* of the source object.
+ */
+ switch (DestDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
+
+ /* Truncate value if we are executing from a 32-bit ACPI table */
+
+ (void) AcpiExTruncateFor32bitTable (DestDesc);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
+ WalkState);
+ break;
+
+ default:
+ /*
+ * All other types come here.
+ */
+ ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
+ AcpiUtGetObjectTypeName (DestDesc)));
+
+ Status = AE_NOT_IMPLEMENTED;
+ break;
+ }
+
+ if (ActualSrcDesc != SourceDesc)
+ {
+ /* Delete the intermediate (temporary) source object */
+
+ AcpiUtRemoveReference (ActualSrcDesc);
+ }
+
+ *NewDesc = DestDesc;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstorob.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstorob.c
new file mode 100644
index 0000000000..683bfce92c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exstorob.c
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ * Module Name: exstorob - AML Interpreter object store support, store to object
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exstorob")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreBufferToBuffer
+ *
+ * PARAMETERS: SourceDesc - Source object to copy
+ * TargetDesc - Destination object of the copy
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy a buffer object to another buffer object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExStoreBufferToBuffer (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc)
+{
+ UINT32 Length;
+ UINT8 *Buffer;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc);
+
+
+ /* If Source and Target are the same, just return */
+
+ if (SourceDesc == TargetDesc)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* We know that SourceDesc is a buffer by now */
+
+ Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer);
+ Length = SourceDesc->Buffer.Length;
+
+ /*
+ * If target is a buffer of length zero or is a static buffer,
+ * allocate a new buffer of the proper length
+ */
+ if ((TargetDesc->Buffer.Length == 0) ||
+ (TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))
+ {
+ TargetDesc->Buffer.Pointer = ACPI_ALLOCATE (Length);
+ if (!TargetDesc->Buffer.Pointer)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ TargetDesc->Buffer.Length = Length;
+ }
+
+ /* Copy source buffer to target buffer */
+
+ if (Length <= TargetDesc->Buffer.Length)
+ {
+ /* Clear existing buffer and copy in the new one */
+
+ memset (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
+ memcpy (TargetDesc->Buffer.Pointer, Buffer, Length);
+
+#ifdef ACPI_OBSOLETE_BEHAVIOR
+ /*
+ * NOTE: ACPI versions up to 3.0 specified that the buffer must be
+ * truncated if the string is smaller than the buffer. However, "other"
+ * implementations of ACPI never did this and thus became the defacto
+ * standard. ACPI 3.0A changes this behavior such that the buffer
+ * is no longer truncated.
+ */
+
+ /*
+ * OBSOLETE BEHAVIOR:
+ * If the original source was a string, we must truncate the buffer,
+ * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
+ * copy must not truncate the original buffer.
+ */
+ if (OriginalSrcType == ACPI_TYPE_STRING)
+ {
+ /* Set the new length of the target */
+
+ TargetDesc->Buffer.Length = Length;
+ }
+#endif
+ }
+ else
+ {
+ /* Truncate the source, copy only what will fit */
+
+ memcpy (TargetDesc->Buffer.Pointer, Buffer,
+ TargetDesc->Buffer.Length);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Truncating source buffer from %X to %X\n",
+ Length, TargetDesc->Buffer.Length));
+ }
+
+ /* Copy flags */
+
+ TargetDesc->Buffer.Flags = SourceDesc->Buffer.Flags;
+ TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExStoreStringToString
+ *
+ * PARAMETERS: SourceDesc - Source object to copy
+ * TargetDesc - Destination object of the copy
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy a String object to another String object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExStoreStringToString (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc)
+{
+ UINT32 Length;
+ UINT8 *Buffer;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc);
+
+
+ /* If Source and Target are the same, just return */
+
+ if (SourceDesc == TargetDesc)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* We know that SourceDesc is a string by now */
+
+ Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer);
+ Length = SourceDesc->String.Length;
+
+ /*
+ * Replace existing string value if it will fit and the string
+ * pointer is not a static pointer (part of an ACPI table)
+ */
+ if ((Length < TargetDesc->String.Length) &&
+ (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
+ {
+ /*
+ * String will fit in existing non-static buffer.
+ * Clear old string and copy in the new one
+ */
+ memset (TargetDesc->String.Pointer, 0,
+ (ACPI_SIZE) TargetDesc->String.Length + 1);
+ memcpy (TargetDesc->String.Pointer, Buffer, Length);
+ }
+ else
+ {
+ /*
+ * Free the current buffer, then allocate a new buffer
+ * large enough to hold the value
+ */
+ if (TargetDesc->String.Pointer &&
+ (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
+ {
+ /* Only free if not a pointer into the DSDT */
+
+ ACPI_FREE (TargetDesc->String.Pointer);
+ }
+
+ TargetDesc->String.Pointer = ACPI_ALLOCATE_ZEROED (
+ (ACPI_SIZE) Length + 1);
+ if (!TargetDesc->String.Pointer)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
+ memcpy (TargetDesc->String.Pointer, Buffer, Length);
+ }
+
+ /* Set the new target length */
+
+ TargetDesc->String.Length = Length;
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exsystem.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exsystem.c
new file mode 100644
index 0000000000..aa661e747d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exsystem.c
@@ -0,0 +1,351 @@
+/******************************************************************************
+ *
+ * Module Name: exsystem - Interface to OS services
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exsystem")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemWaitSemaphore
+ *
+ * PARAMETERS: Semaphore - Semaphore to wait on
+ * Timeout - Max time to wait
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Implements a semaphore wait with a check to see if the
+ * semaphore is available immediately. If it is not, the
+ * interpreter is released before waiting.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemWaitSemaphore (
+ ACPI_SEMAPHORE Semaphore,
+ UINT16 Timeout)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExSystemWaitSemaphore);
+
+
+ Status = AcpiOsWaitSemaphore (Semaphore, 1, ACPI_DO_NOT_WAIT);
+ if (ACPI_SUCCESS (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (Status == AE_TIME)
+ {
+ /* We must wait, so unlock the interpreter */
+
+ AcpiExExitInterpreter ();
+
+ Status = AcpiOsWaitSemaphore (Semaphore, 1, Timeout);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "*** Thread awake after blocking, %s\n",
+ AcpiFormatException (Status)));
+
+ /* Reacquire the interpreter */
+
+ AcpiExEnterInterpreter ();
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemWaitMutex
+ *
+ * PARAMETERS: Mutex - Mutex to wait on
+ * Timeout - Max time to wait
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Implements a mutex wait with a check to see if the
+ * mutex is available immediately. If it is not, the
+ * interpreter is released before waiting.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemWaitMutex (
+ ACPI_MUTEX Mutex,
+ UINT16 Timeout)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExSystemWaitMutex);
+
+
+ Status = AcpiOsAcquireMutex (Mutex, ACPI_DO_NOT_WAIT);
+ if (ACPI_SUCCESS (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (Status == AE_TIME)
+ {
+ /* We must wait, so unlock the interpreter */
+
+ AcpiExExitInterpreter ();
+
+ Status = AcpiOsAcquireMutex (Mutex, Timeout);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "*** Thread awake after blocking, %s\n",
+ AcpiFormatException (Status)));
+
+ /* Reacquire the interpreter */
+
+ AcpiExEnterInterpreter ();
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemDoStall
+ *
+ * PARAMETERS: HowLong - The amount of time to stall,
+ * in microseconds
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Suspend running thread for specified amount of time.
+ * Note: ACPI specification requires that Stall() does not
+ * relinquish the processor, and delays longer than 100 usec
+ * should use Sleep() instead. We allow stalls up to 255 usec
+ * for compatibility with other interpreters and existing BIOSs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemDoStall (
+ UINT32 HowLong)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (HowLong > 255) /* 255 microseconds */
+ {
+ /*
+ * Longer than 255 usec, this is an error
+ *
+ * (ACPI specifies 100 usec as max, but this gives some slack in
+ * order to support existing BIOSs)
+ */
+ ACPI_ERROR ((AE_INFO, "Time parameter is too large (%u)",
+ HowLong));
+ Status = AE_AML_OPERAND_VALUE;
+ }
+ else
+ {
+ AcpiOsStall (HowLong);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemDoSleep
+ *
+ * PARAMETERS: HowLong - The amount of time to sleep,
+ * in milliseconds
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Sleep the running thread for specified amount of time.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemDoSleep (
+ UINT64 HowLong)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Since this thread will sleep, we must release the interpreter */
+
+ AcpiExExitInterpreter ();
+
+ /*
+ * For compatibility with other ACPI implementations and to prevent
+ * accidental deep sleeps, limit the sleep time to something reasonable.
+ */
+ if (HowLong > ACPI_MAX_SLEEP)
+ {
+ HowLong = ACPI_MAX_SLEEP;
+ }
+
+ AcpiOsSleep (HowLong);
+
+ /* And now we must get the interpreter again */
+
+ AcpiExEnterInterpreter ();
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemSignalEvent
+ *
+ * PARAMETERS: ObjDesc - The object descriptor for this op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ * within the AML.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemSignalEvent (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExSystemSignalEvent);
+
+
+ if (ObjDesc)
+ {
+ Status = AcpiOsSignalSemaphore (ObjDesc->Event.OsSemaphore, 1);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemWaitEvent
+ *
+ * PARAMETERS: TimeDesc - The 'time to delay' object descriptor
+ * ObjDesc - The object descriptor for this op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ * within the AML. This operation is a request to wait for an
+ * event.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemWaitEvent (
+ ACPI_OPERAND_OBJECT *TimeDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (ExSystemWaitEvent);
+
+
+ if (ObjDesc)
+ {
+ Status = AcpiExSystemWaitSemaphore (ObjDesc->Event.OsSemaphore,
+ (UINT16) TimeDesc->Integer.Value);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSystemResetEvent
+ *
+ * PARAMETERS: ObjDesc - The object descriptor for this op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reset an event to a known state.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExSystemResetEvent (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_SEMAPHORE TempSemaphore;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * We are going to simply delete the existing semaphore and
+ * create a new one!
+ */
+ Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, &TempSemaphore);
+ if (ACPI_SUCCESS (Status))
+ {
+ (void) AcpiOsDeleteSemaphore (ObjDesc->Event.OsSemaphore);
+ ObjDesc->Event.OsSemaphore = TempSemaphore;
+ }
+
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/executer/exutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exutils.c
new file mode 100644
index 0000000000..1cd60fa32c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/executer/exutils.c
@@ -0,0 +1,500 @@
+/******************************************************************************
+ *
+ * Module Name: exutils - interpreter/scanner utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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_AML_GLOBALS is tested in amlcode.h
+ * to determine whether certain global names should be "defined" or only
+ * "declared" in the current compilation. This enhances maintainability
+ * by enabling a single header file to embody all knowledge of the names
+ * in question.
+ *
+ * Exactly one module of any executable should #define DEFINE_GLOBALS
+ * before #including the header files which use this convention. The
+ * names in question will be defined and initialized in that module,
+ * and declared as extern in all other modules which #include those
+ * header files.
+ */
+
+#define DEFINE_AML_GLOBALS
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exutils")
+
+/* Local prototypes */
+
+static UINT32
+AcpiExDigitsNeeded (
+ UINT64 Value,
+ UINT32 Base);
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExEnterInterpreter
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Enter the interpreter execution region. Failure to enter
+ * the interpreter region is a fatal system error. Used in
+ * conjunction with ExitInterpreter.
+ *
+ ******************************************************************************/
+
+void
+AcpiExEnterInterpreter (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExEnterInterpreter);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not acquire AML Interpreter mutex"));
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExExitInterpreter
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Exit the interpreter execution region. This is the top level
+ * routine used to exit the interpreter when all processing has
+ * been completed, or when the method blocks.
+ *
+ * Cases where the interpreter is unlocked internally:
+ * 1) Method will be blocked on a Sleep() AML opcode
+ * 2) Method will be blocked on an Acquire() AML opcode
+ * 3) Method will be blocked on a Wait() AML opcode
+ * 4) Method will be blocked to acquire the global lock
+ * 5) Method will be blocked waiting to execute a serialized control
+ * method that is currently executing
+ * 6) About to invoke a user-installed opregion handler
+ *
+ ******************************************************************************/
+
+void
+AcpiExExitInterpreter (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExExitInterpreter);
+
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not release AML Interpreter mutex"));
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExTruncateFor32bitTable
+ *
+ * PARAMETERS: ObjDesc - Object to be truncated
+ *
+ * RETURN: TRUE if a truncation was performed, FALSE otherwise.
+ *
+ * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
+ * 32-bit, as determined by the revision of the DSDT.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiExTruncateFor32bitTable (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Object must be a valid number and we must be executing
+ * a control method. Object could be NS node for AML_INT_NAMEPATH_OP.
+ */
+ if ((!ObjDesc) ||
+ (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) ||
+ (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
+ {
+ return (FALSE);
+ }
+
+ if ((AcpiGbl_IntegerByteWidth == 4) &&
+ (ObjDesc->Integer.Value > (UINT64) ACPI_UINT32_MAX))
+ {
+ /*
+ * We are executing in a 32-bit ACPI table.
+ * Truncate the value to 32 bits by zeroing out the upper 32-bit field
+ */
+ ObjDesc->Integer.Value &= (UINT64) ACPI_UINT32_MAX;
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExAcquireGlobalLock
+ *
+ * PARAMETERS: FieldFlags - Flags with Lock rule:
+ * AlwaysLock or NeverLock
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
+ * flags specifiy that it is to be obtained before field access.
+ *
+ ******************************************************************************/
+
+void
+AcpiExAcquireGlobalLock (
+ UINT32 FieldFlags)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExAcquireGlobalLock);
+
+
+ /* Only use the lock if the AlwaysLock bit is set */
+
+ if (!(FieldFlags & AML_FIELD_LOCK_RULE_MASK))
+ {
+ return_VOID;
+ }
+
+ /* Attempt to get the global lock, wait forever */
+
+ Status = AcpiExAcquireMutexObject (ACPI_WAIT_FOREVER,
+ AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not acquire Global Lock"));
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReleaseGlobalLock
+ *
+ * PARAMETERS: FieldFlags - Flags with Lock rule:
+ * AlwaysLock or NeverLock
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release the ACPI hardware Global Lock
+ *
+ ******************************************************************************/
+
+void
+AcpiExReleaseGlobalLock (
+ UINT32 FieldFlags)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (ExReleaseGlobalLock);
+
+
+ /* Only use the lock if the AlwaysLock bit is set */
+
+ if (!(FieldFlags & AML_FIELD_LOCK_RULE_MASK))
+ {
+ return_VOID;
+ }
+
+ /* Release the global lock */
+
+ Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Report the error, but there isn't much else we can do */
+
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not release Global Lock"));
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDigitsNeeded
+ *
+ * PARAMETERS: Value - Value to be represented
+ * Base - Base of representation
+ *
+ * RETURN: The number of digits.
+ *
+ * DESCRIPTION: Calculate the number of digits needed to represent the Value
+ * in the given Base (Radix)
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiExDigitsNeeded (
+ UINT64 Value,
+ UINT32 Base)
+{
+ UINT32 NumDigits;
+ UINT64 CurrentValue;
+
+
+ ACPI_FUNCTION_TRACE (ExDigitsNeeded);
+
+
+ /* UINT64 is unsigned, so we don't worry about a '-' prefix */
+
+ if (Value == 0)
+ {
+ return_UINT32 (1);
+ }
+
+ CurrentValue = Value;
+ NumDigits = 0;
+
+ /* Count the digits in the requested base */
+
+ while (CurrentValue)
+ {
+ (void) AcpiUtShortDivide (CurrentValue, Base, &CurrentValue, NULL);
+ NumDigits++;
+ }
+
+ return_UINT32 (NumDigits);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExEisaIdToString
+ *
+ * PARAMETERS: CompressedId - EISAID to be converted
+ * OutString - Where to put the converted string (8 bytes)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert a numeric EISAID to string representation. Return
+ * buffer must be large enough to hold the string. The string
+ * returned is always exactly of length ACPI_EISAID_STRING_SIZE
+ * (includes null terminator). The EISAID is always 32 bits.
+ *
+ ******************************************************************************/
+
+void
+AcpiExEisaIdToString (
+ char *OutString,
+ UINT64 CompressedId)
+{
+ UINT32 SwappedId;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* The EISAID should be a 32-bit integer */
+
+ if (CompressedId > ACPI_UINT32_MAX)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating",
+ ACPI_FORMAT_UINT64 (CompressedId)));
+ }
+
+ /* Swap ID to big-endian to get contiguous bits */
+
+ SwappedId = AcpiUtDwordByteSwap ((UINT32) CompressedId);
+
+ /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */
+
+ OutString[0] = (char) (0x40 + (((unsigned long) SwappedId >> 26) & 0x1F));
+ OutString[1] = (char) (0x40 + ((SwappedId >> 21) & 0x1F));
+ OutString[2] = (char) (0x40 + ((SwappedId >> 16) & 0x1F));
+ OutString[3] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 12);
+ OutString[4] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 8);
+ OutString[5] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 4);
+ OutString[6] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 0);
+ OutString[7] = 0;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExIntegerToString
+ *
+ * PARAMETERS: OutString - Where to put the converted string. At least
+ * 21 bytes are needed to hold the largest
+ * possible 64-bit integer.
+ * Value - Value to be converted
+ *
+ * RETURN: None, string
+ *
+ * DESCRIPTION: Convert a 64-bit integer to decimal string representation.
+ * Assumes string buffer is large enough to hold the string. The
+ * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1).
+ *
+ ******************************************************************************/
+
+void
+AcpiExIntegerToString (
+ char *OutString,
+ UINT64 Value)
+{
+ UINT32 Count;
+ UINT32 DigitsNeeded;
+ UINT32 Remainder;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ DigitsNeeded = AcpiExDigitsNeeded (Value, 10);
+ OutString[DigitsNeeded] = 0;
+
+ for (Count = DigitsNeeded; Count > 0; Count--)
+ {
+ (void) AcpiUtShortDivide (Value, 10, &Value, &Remainder);
+ OutString[Count-1] = (char) ('0' + Remainder);\
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExPciClsToString
+ *
+ * PARAMETERS: OutString - Where to put the converted string (7 bytes)
+ * PARAMETERS: ClassCode - PCI class code to be converted (3 bytes)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert 3-bytes PCI class code to string representation.
+ * Return buffer must be large enough to hold the string. The
+ * string returned is always exactly of length
+ * ACPI_PCICLS_STRING_SIZE (includes null terminator).
+ *
+ ******************************************************************************/
+
+void
+AcpiExPciClsToString (
+ char *OutString,
+ UINT8 ClassCode[3])
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* All 3 bytes are hexadecimal */
+
+ OutString[0] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 4);
+ OutString[1] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 0);
+ OutString[2] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 4);
+ OutString[3] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 0);
+ OutString[4] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 4);
+ OutString[5] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 0);
+ OutString[6] = 0;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiIsValidSpaceId
+ *
+ * PARAMETERS: SpaceId - ID to be validated
+ *
+ * RETURN: TRUE if valid/supported ID.
+ *
+ * DESCRIPTION: Validate an operation region SpaceID.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiIsValidSpaceId (
+ UINT8 SpaceId)
+{
+
+ if ((SpaceId >= ACPI_NUM_PREDEFINED_REGIONS) &&
+ (SpaceId < ACPI_USER_REGION_BEGIN) &&
+ (SpaceId != ACPI_ADR_SPACE_DATA_TABLE) &&
+ (SpaceId != ACPI_ADR_SPACE_FIXED_HARDWARE))
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwacpi.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwacpi.c
new file mode 100644
index 0000000000..a91b66fa94
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwacpi.c
@@ -0,0 +1,221 @@
+/******************************************************************************
+ *
+ * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwacpi")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwSetMode
+ *
+ * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transitions the system into the requested mode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwSetMode (
+ UINT32 Mode)
+{
+
+ ACPI_STATUS Status;
+ UINT32 Retry;
+
+
+ ACPI_FUNCTION_TRACE (HwSetMode);
+
+
+ /* If the Hardware Reduced flag is set, machine is always in acpi mode */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
+ * system does not support mode transition.
+ */
+ if (!AcpiGbl_FADT.SmiCommand)
+ {
+ ACPI_ERROR ((AE_INFO, "No SMI_CMD in FADT, mode transition failed"));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
+
+ /*
+ * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
+ * in FADT: If it is zero, enabling or disabling is not supported.
+ * As old systems may have used zero for mode transition,
+ * we make sure both the numbers are zero to determine these
+ * transitions are not supported.
+ */
+ if (!AcpiGbl_FADT.AcpiEnable && !AcpiGbl_FADT.AcpiDisable)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No ACPI mode transition supported in this system "
+ "(enable/disable both zero)"));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ switch (Mode)
+ {
+ case ACPI_SYS_MODE_ACPI:
+
+ /* BIOS should have disabled ALL fixed and GP events */
+
+ Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
+ (UINT32) AcpiGbl_FADT.AcpiEnable, 8);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
+ break;
+
+ case ACPI_SYS_MODE_LEGACY:
+ /*
+ * BIOS should clear all fixed status bits and restore fixed event
+ * enable bits to default
+ */
+ Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
+ (UINT32) AcpiGbl_FADT.AcpiDisable, 8);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Attempting to enable Legacy (non-ACPI) mode\n"));
+ break;
+
+ default:
+
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not write ACPI mode change"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Some hardware takes a LONG time to switch modes. Give them 3 sec to
+ * do so, but allow faster systems to proceed more quickly.
+ */
+ Retry = 3000;
+ while (Retry)
+ {
+ if (AcpiHwGetMode () == Mode)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n",
+ Mode));
+ return_ACPI_STATUS (AE_OK);
+ }
+ AcpiOsStall (ACPI_USEC_PER_MSEC);
+ Retry--;
+ }
+
+ ACPI_ERROR ((AE_INFO, "Hardware did not change modes"));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwGetMode
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * DESCRIPTION: Return current operating state of system. Determined by
+ * querying the SCI_EN bit.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiHwGetMode (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 Value;
+
+
+ ACPI_FUNCTION_TRACE (HwGetMode);
+
+
+ /* If the Hardware Reduced flag is set, machine is always in acpi mode */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return_UINT32 (ACPI_SYS_MODE_ACPI);
+ }
+
+ /*
+ * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
+ * system does not support mode transition.
+ */
+ if (!AcpiGbl_FADT.SmiCommand)
+ {
+ return_UINT32 (ACPI_SYS_MODE_ACPI);
+ }
+
+ Status = AcpiReadBitRegister (ACPI_BITREG_SCI_ENABLE, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return_UINT32 (ACPI_SYS_MODE_LEGACY);
+ }
+
+ if (Value)
+ {
+ return_UINT32 (ACPI_SYS_MODE_ACPI);
+ }
+ else
+ {
+ return_UINT32 (ACPI_SYS_MODE_LEGACY);
+ }
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwesleep.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwesleep.c
new file mode 100644
index 0000000000..460b6ffaab
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwesleep.c
@@ -0,0 +1,258 @@
+/******************************************************************************
+ *
+ * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the
+ * extended FADT-V5 sleep registers.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwesleep")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwExecuteSleepMethod
+ *
+ * PARAMETERS: MethodPathname - Pathname of method to execute
+ * IntegerArgument - Argument to pass to the method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Execute a sleep/wake related method with one integer argument
+ * and no return value.
+ *
+ ******************************************************************************/
+
+void
+AcpiHwExecuteSleepMethod (
+ char *MethodPathname,
+ UINT32 IntegerArgument)
+{
+ ACPI_OBJECT_LIST ArgList;
+ ACPI_OBJECT Arg;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwExecuteSleepMethod);
+
+
+ /* One argument, IntegerArgument; No return value expected */
+
+ ArgList.Count = 1;
+ ArgList.Pointer = &Arg;
+ Arg.Type = ACPI_TYPE_INTEGER;
+ Arg.Integer.Value = (UINT64) IntegerArgument;
+
+ Status = AcpiEvaluateObject (NULL, MethodPathname, &ArgList, NULL);
+ if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "While executing method %s",
+ MethodPathname));
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwExtendedSleep
+ *
+ * PARAMETERS: SleepState - Which sleep state to enter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter a system sleep state via the extended FADT sleep
+ * registers (V5 FADT).
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwExtendedSleep (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+ UINT8 SleepTypeValue;
+ UINT64 SleepStatus;
+
+
+ ACPI_FUNCTION_TRACE (HwExtendedSleep);
+
+
+ /* Extended sleep registers must be valid */
+
+ if (!AcpiGbl_FADT.SleepControl.Address ||
+ !AcpiGbl_FADT.SleepStatus.Address)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Clear wake status (WAK_STS) */
+
+ Status = AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiGbl_SystemAwakeAndRunning = FALSE;
+
+ /* Flush caches, as per ACPI specification */
+
+ ACPI_FLUSH_CPU_CACHE ();
+
+ /*
+ * Set the SLP_TYP and SLP_EN bits.
+ *
+ * Note: We only use the first value returned by the \_Sx method
+ * (AcpiGbl_SleepTypeA) - As per ACPI specification.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Entering sleep state [S%u]\n", SleepState));
+
+ SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
+ ACPI_X_SLEEP_TYPE_MASK);
+
+ Status = AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
+ &AcpiGbl_FADT.SleepControl);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Wait for transition back to Working State */
+
+ do
+ {
+ Status = AcpiRead (&SleepStatus, &AcpiGbl_FADT.SleepStatus);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ } while (!(((UINT8) SleepStatus) & ACPI_X_WAKE_STATUS));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwExtendedWakePrep
+ *
+ * PARAMETERS: SleepState - Which sleep state we just exited
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after
+ * a sleep. Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwExtendedWakePrep (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+ UINT8 SleepTypeValue;
+
+
+ ACPI_FUNCTION_TRACE (HwExtendedWakePrep);
+
+
+ Status = AcpiGetSleepTypeData (ACPI_STATE_S0,
+ &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
+ if (ACPI_SUCCESS (Status))
+ {
+ SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
+ ACPI_X_SLEEP_TYPE_MASK);
+
+ (void) AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
+ &AcpiGbl_FADT.SleepControl);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwExtendedWake
+ *
+ * PARAMETERS: SleepState - Which sleep state we just exited
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
+ * Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwExtendedWake (
+ UINT8 SleepState)
+{
+ ACPI_FUNCTION_TRACE (HwExtendedWake);
+
+
+ /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */
+
+ AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID;
+
+ /* Execute the wake methods */
+
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING);
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState);
+
+ /*
+ * Some BIOS code assumes that WAK_STS will be cleared on resume
+ * and use it to determine whether the system is rebooting or
+ * resuming. Clear WAK_STS for compatibility.
+ */
+ (void) AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
+ AcpiGbl_SystemAwakeAndRunning = TRUE;
+
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwgpe.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwgpe.c
new file mode 100644
index 0000000000..c293bef8cc
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwgpe.c
@@ -0,0 +1,601 @@
+/******************************************************************************
+ *
+ * Module Name: hwgpe - Low level GPE enable/disable/clear functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwgpe")
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiHwEnableWakeupGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+static ACPI_STATUS
+AcpiHwGpeEnableWrite (
+ UINT8 EnableMask,
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwGetGpeRegisterBit
+ *
+ * PARAMETERS: GpeEventInfo - Info block for the GPE
+ *
+ * RETURN: Register mask with a one in the GPE bit position
+ *
+ * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
+ * correct position for the input GPE.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiHwGetGpeRegisterBit (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+
+ return ((UINT32) 1 <<
+ (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwLowSetGpe
+ *
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to be disabled
+ * Action - Enable or disable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
+ * The EnableMask field of the involved GPE register must be
+ * updated by the caller if necessary.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwLowSetGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ UINT32 Action)
+{
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_STATUS Status;
+ UINT32 EnableMask;
+ UINT32 RegisterBit;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Get the info block for the entire GPE register */
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+ if (!GpeRegisterInfo)
+ {
+ return (AE_NOT_EXIST);
+ }
+
+ /* Get current value of the enable register that contains this GPE */
+
+ Status = AcpiHwRead (&EnableMask, &GpeRegisterInfo->EnableAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Set or clear just the bit that corresponds to this GPE */
+
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
+ switch (Action)
+ {
+ case ACPI_GPE_CONDITIONAL_ENABLE:
+
+ /* Only enable if the corresponding EnableMask bit is set */
+
+ if (!(RegisterBit & GpeRegisterInfo->EnableMask))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*lint -fallthrough */
+
+ case ACPI_GPE_ENABLE:
+
+ ACPI_SET_BIT (EnableMask, RegisterBit);
+ break;
+
+ case ACPI_GPE_DISABLE:
+
+ ACPI_CLEAR_BIT (EnableMask, RegisterBit);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid GPE Action, %u", Action));
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Write the updated enable mask */
+
+ Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwClearGpe
+ *
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to be cleared
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear the status bit for a single GPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwClearGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_STATUS Status;
+ UINT32 RegisterBit;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+ /* Get the info block for the entire GPE register */
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+ if (!GpeRegisterInfo)
+ {
+ return (AE_NOT_EXIST);
+ }
+
+ /*
+ * Write a one to the appropriate bit in the status register to
+ * clear this GPE.
+ */
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
+
+ Status = AcpiHwWrite (RegisterBit,
+ &GpeRegisterInfo->StatusAddress);
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwGetGpeStatus
+ *
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to queried
+ * EventStatus - Where the GPE status is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Return the status of a single GPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwGetGpeStatus (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ ACPI_EVENT_STATUS *EventStatus)
+{
+ UINT32 InByte;
+ UINT32 RegisterBit;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_EVENT_STATUS LocalEventStatus = 0;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!EventStatus)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* GPE currently handled? */
+
+ if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_HAS_HANDLER;
+ }
+
+ /* Get the info block for the entire GPE register */
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+
+ /* Get the register bitmask for this GPE */
+
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
+
+ /* GPE currently enabled? (enabled for runtime?) */
+
+ if (RegisterBit & GpeRegisterInfo->EnableForRun)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED;
+ }
+
+ /* GPE enabled for wake? */
+
+ if (RegisterBit & GpeRegisterInfo->EnableForWake)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED;
+ }
+
+ /* GPE currently enabled (enable bit == 1)? */
+
+ Status = AcpiHwRead (&InByte, &GpeRegisterInfo->EnableAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (RegisterBit & InByte)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_ENABLE_SET;
+ }
+
+ /* GPE currently active (status bit == 1)? */
+
+ Status = AcpiHwRead (&InByte, &GpeRegisterInfo->StatusAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (RegisterBit & InByte)
+ {
+ LocalEventStatus |= ACPI_EVENT_FLAG_STATUS_SET;
+ }
+
+ /* Set return value */
+
+ (*EventStatus) = LocalEventStatus;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwGpeEnableWrite
+ *
+ * PARAMETERS: EnableMask - Bit mask to write to the GPE register
+ * GpeRegisterInfo - Gpe Register info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write the enable mask byte to the given GPE register.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwGpeEnableWrite (
+ UINT8 EnableMask,
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo)
+{
+ ACPI_STATUS Status;
+
+
+ GpeRegisterInfo->EnableMask = EnableMask;
+ Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwDisableGpeBlock
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable all GPEs within a single GPE block
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwDisableGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Disable all GPEs in this register */
+
+ Status = AcpiHwGpeEnableWrite (0x00, &GpeBlock->RegisterInfo[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwClearGpeBlock
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwClearGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Clear status on all GPEs in this register */
+
+ Status = AcpiHwWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwEnableRuntimeGpeBlock
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
+ * combination wake/run GPEs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwEnableRuntimeGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+
+
+ /* NOTE: assumes that all GPEs are currently disabled */
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
+ if (!GpeRegisterInfo->EnableForRun)
+ {
+ continue;
+ }
+
+ /* Enable all "runtime" GPEs in this register */
+
+ Status = AcpiHwGpeEnableWrite (GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwEnableWakeupGpeBlock
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
+ * combination wake/run GPEs.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwEnableWakeupGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
+
+ /*
+ * Enable all "wake" GPEs in this register and disable the
+ * remaining ones.
+ */
+ Status = AcpiHwGpeEnableWrite (GpeRegisterInfo->EnableForWake,
+ GpeRegisterInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwDisableAllGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwDisableAllGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwDisableAllGpes);
+
+
+ Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
+ Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwEnableAllRuntimeGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwEnableAllRuntimeGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes);
+
+
+ Status = AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock, NULL);
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwEnableAllWakeupGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwEnableAllWakeupGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes);
+
+
+ Status = AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock, NULL);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwpci.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwpci.c
new file mode 100644
index 0000000000..c19100b67c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwpci.c
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ *
+ * Module Name: hwpci - Obtain PCI bus, device, and function numbers
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("hwpci")
+
+
+/* PCI configuration space values */
+
+#define PCI_CFG_HEADER_TYPE_REG 0x0E
+#define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18
+#define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19
+
+/* PCI header values */
+
+#define PCI_HEADER_TYPE_MASK 0x7F
+#define PCI_TYPE_BRIDGE 0x01
+#define PCI_TYPE_CARDBUS_BRIDGE 0x02
+
+typedef struct acpi_pci_device
+{
+ ACPI_HANDLE Device;
+ struct acpi_pci_device *Next;
+
+} ACPI_PCI_DEVICE;
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiHwBuildPciList (
+ ACPI_HANDLE RootPciDevice,
+ ACPI_HANDLE PciRegion,
+ ACPI_PCI_DEVICE **ReturnListHead);
+
+static ACPI_STATUS
+AcpiHwProcessPciList (
+ ACPI_PCI_ID *PciId,
+ ACPI_PCI_DEVICE *ListHead);
+
+static void
+AcpiHwDeletePciList (
+ ACPI_PCI_DEVICE *ListHead);
+
+static ACPI_STATUS
+AcpiHwGetPciDeviceInfo (
+ ACPI_PCI_ID *PciId,
+ ACPI_HANDLE PciDevice,
+ UINT16 *BusNumber,
+ BOOLEAN *IsBridge);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwDerivePciId
+ *
+ * PARAMETERS: PciId - Initial values for the PCI ID. May be
+ * modified by this function.
+ * RootPciDevice - A handle to a PCI device object. This
+ * object must be a PCI Root Bridge having a
+ * _HID value of either PNP0A03 or PNP0A08
+ * PciRegion - A handle to a PCI configuration space
+ * Operation Region being initialized
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function derives a full PCI ID for a PCI device,
+ * consisting of a Segment number, Bus number, Device number,
+ * and function code.
+ *
+ * The PCI hardware dynamically configures PCI bus numbers
+ * depending on the bus topology discovered during system
+ * initialization. This function is invoked during configuration
+ * of a PCI_Config Operation Region in order to (possibly) update
+ * the Bus/Device/Function numbers in the PciId with the actual
+ * values as determined by the hardware and operating system
+ * configuration.
+ *
+ * The PciId parameter is initially populated during the Operation
+ * Region initialization. This function is then called, and is
+ * will make any necessary modifications to the Bus, Device, or
+ * Function number PCI ID subfields as appropriate for the
+ * current hardware and OS configuration.
+ *
+ * NOTE: Created 08/2010. Replaces the previous OSL AcpiOsDerivePciId
+ * interface since this feature is OS-independent. This module
+ * specifically avoids any use of recursion by building a local
+ * temporary device list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwDerivePciId (
+ ACPI_PCI_ID *PciId,
+ ACPI_HANDLE RootPciDevice,
+ ACPI_HANDLE PciRegion)
+{
+ ACPI_STATUS Status;
+ ACPI_PCI_DEVICE *ListHead;
+
+
+ ACPI_FUNCTION_TRACE (HwDerivePciId);
+
+
+ if (!PciId)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Build a list of PCI devices, from PciRegion up to RootPciDevice */
+
+ Status = AcpiHwBuildPciList (RootPciDevice, PciRegion, &ListHead);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Walk the list, updating the PCI device/function/bus numbers */
+
+ Status = AcpiHwProcessPciList (PciId, ListHead);
+
+ /* Delete the list */
+
+ AcpiHwDeletePciList (ListHead);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwBuildPciList
+ *
+ * PARAMETERS: RootPciDevice - A handle to a PCI device object. This
+ * object is guaranteed to be a PCI Root
+ * Bridge having a _HID value of either
+ * PNP0A03 or PNP0A08
+ * PciRegion - A handle to the PCI configuration space
+ * Operation Region
+ * ReturnListHead - Where the PCI device list is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Builds a list of devices from the input PCI region up to the
+ * Root PCI device for this namespace subtree.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwBuildPciList (
+ ACPI_HANDLE RootPciDevice,
+ ACPI_HANDLE PciRegion,
+ ACPI_PCI_DEVICE **ReturnListHead)
+{
+ ACPI_HANDLE CurrentDevice;
+ ACPI_HANDLE ParentDevice;
+ ACPI_STATUS Status;
+ ACPI_PCI_DEVICE *ListElement;
+
+
+ /*
+ * Ascend namespace branch until the RootPciDevice is reached, building
+ * a list of device nodes. Loop will exit when either the PCI device is
+ * found, or the root of the namespace is reached.
+ */
+ *ReturnListHead = NULL;
+ CurrentDevice = PciRegion;
+ while (1)
+ {
+ Status = AcpiGetParent (CurrentDevice, &ParentDevice);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Must delete the list before exit */
+
+ AcpiHwDeletePciList (*ReturnListHead);
+ return (Status);
+ }
+
+ /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */
+
+ if (ParentDevice == RootPciDevice)
+ {
+ return (AE_OK);
+ }
+
+ ListElement = ACPI_ALLOCATE (sizeof (ACPI_PCI_DEVICE));
+ if (!ListElement)
+ {
+ /* Must delete the list before exit */
+
+ AcpiHwDeletePciList (*ReturnListHead);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Put new element at the head of the list */
+
+ ListElement->Next = *ReturnListHead;
+ ListElement->Device = ParentDevice;
+ *ReturnListHead = ListElement;
+
+ CurrentDevice = ParentDevice;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwProcessPciList
+ *
+ * PARAMETERS: PciId - Initial values for the PCI ID. May be
+ * modified by this function.
+ * ListHead - Device list created by
+ * AcpiHwBuildPciList
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk downward through the PCI device list, getting the device
+ * info for each, via the PCI configuration space and updating
+ * the PCI ID as necessary. Deletes the list during traversal.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwProcessPciList (
+ ACPI_PCI_ID *PciId,
+ ACPI_PCI_DEVICE *ListHead)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PCI_DEVICE *Info;
+ UINT16 BusNumber;
+ BOOLEAN IsBridge = TRUE;
+
+
+ ACPI_FUNCTION_NAME (HwProcessPciList);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n",
+ PciId->Segment, PciId->Bus, PciId->Device, PciId->Function));
+
+ BusNumber = PciId->Bus;
+
+ /*
+ * Descend down the namespace tree, collecting PCI device, function,
+ * and bus numbers. BusNumber is only important for PCI bridges.
+ * Algorithm: As we descend the tree, use the last valid PCI device,
+ * function, and bus numbers that are discovered, and assign them
+ * to the PCI ID for the target device.
+ */
+ Info = ListHead;
+ while (Info)
+ {
+ Status = AcpiHwGetPciDeviceInfo (PciId, Info->Device,
+ &BusNumber, &IsBridge);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Info = Info->Next;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X "
+ "Status %X BusNumber %X IsBridge %X\n",
+ PciId->Segment, PciId->Bus, PciId->Device, PciId->Function,
+ Status, BusNumber, IsBridge));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwDeletePciList
+ *
+ * PARAMETERS: ListHead - Device list created by
+ * AcpiHwBuildPciList
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Free the entire PCI list.
+ *
+ ******************************************************************************/
+
+static void
+AcpiHwDeletePciList (
+ ACPI_PCI_DEVICE *ListHead)
+{
+ ACPI_PCI_DEVICE *Next;
+ ACPI_PCI_DEVICE *Previous;
+
+
+ Next = ListHead;
+ while (Next)
+ {
+ Previous = Next;
+ Next = Previous->Next;
+ ACPI_FREE (Previous);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwGetPciDeviceInfo
+ *
+ * PARAMETERS: PciId - Initial values for the PCI ID. May be
+ * modified by this function.
+ * PciDevice - Handle for the PCI device object
+ * BusNumber - Where a PCI bridge bus number is returned
+ * IsBridge - Return value, indicates if this PCI
+ * device is a PCI bridge
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the device info for a single PCI device object. Get the
+ * _ADR (contains PCI device and function numbers), and for PCI
+ * bridge devices, get the bus number from PCI configuration
+ * space.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwGetPciDeviceInfo (
+ ACPI_PCI_ID *PciId,
+ ACPI_HANDLE PciDevice,
+ UINT16 *BusNumber,
+ BOOLEAN *IsBridge)
+{
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE ObjectType;
+ UINT64 ReturnValue;
+ UINT64 PciValue;
+
+
+ /* We only care about objects of type Device */
+
+ Status = AcpiGetType (PciDevice, &ObjectType);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (ObjectType != ACPI_TYPE_DEVICE)
+ {
+ return (AE_OK);
+ }
+
+ /* We need an _ADR. Ignore device if not present */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
+ PciDevice, &ReturnValue);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * From _ADR, get the PCI Device and Function and
+ * update the PCI ID.
+ */
+ PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue));
+ PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue));
+
+ /*
+ * If the previous device was a bridge, use the previous
+ * device bus number
+ */
+ if (*IsBridge)
+ {
+ PciId->Bus = *BusNumber;
+ }
+
+ /*
+ * Get the bus numbers from PCI Config space:
+ *
+ * First, get the PCI HeaderType
+ */
+ *IsBridge = FALSE;
+ Status = AcpiOsReadPciConfiguration (PciId,
+ PCI_CFG_HEADER_TYPE_REG, &PciValue, 8);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */
+
+ PciValue &= PCI_HEADER_TYPE_MASK;
+
+ if ((PciValue != PCI_TYPE_BRIDGE) &&
+ (PciValue != PCI_TYPE_CARDBUS_BRIDGE))
+ {
+ return (AE_OK);
+ }
+
+ /* Bridge: Get the Primary BusNumber */
+
+ Status = AcpiOsReadPciConfiguration (PciId,
+ PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *IsBridge = TRUE;
+ PciId->Bus = (UINT16) PciValue;
+
+ /* Bridge: Get the Secondary BusNumber */
+
+ Status = AcpiOsReadPciConfiguration (PciId,
+ PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *BusNumber = (UINT16) PciValue;
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwregs.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwregs.c
new file mode 100644
index 0000000000..9d601c53af
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwregs.c
@@ -0,0 +1,728 @@
+/*******************************************************************************
+ *
+ * Module Name: hwregs - Read/write access functions for the various ACPI
+ * control and status registers.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwregs")
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+/* Local Prototypes */
+
+static ACPI_STATUS
+AcpiHwReadMultiple (
+ UINT32 *Value,
+ ACPI_GENERIC_ADDRESS *RegisterA,
+ ACPI_GENERIC_ADDRESS *RegisterB);
+
+static ACPI_STATUS
+AcpiHwWriteMultiple (
+ UINT32 Value,
+ ACPI_GENERIC_ADDRESS *RegisterA,
+ ACPI_GENERIC_ADDRESS *RegisterB);
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwValidateRegister
+ *
+ * PARAMETERS: Reg - GAS register structure
+ * MaxBitWidth - Max BitWidth supported (32 or 64)
+ * Address - Pointer to where the gas->address
+ * is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
+ * pointer, Address, SpaceId, BitWidth, and BitOffset.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwValidateRegister (
+ ACPI_GENERIC_ADDRESS *Reg,
+ UINT8 MaxBitWidth,
+ UINT64 *Address)
+{
+
+ /* Must have a valid pointer to a GAS structure */
+
+ if (!Reg)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Copy the target address. This handles possible alignment issues.
+ * Address must not be null. A null address also indicates an optional
+ * ACPI register that is not supported, so no error message.
+ */
+ ACPI_MOVE_64_TO_64 (Address, &Reg->Address);
+ if (!(*Address))
+ {
+ return (AE_BAD_ADDRESS);
+ }
+
+ /* Validate the SpaceID */
+
+ if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
+ (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Unsupported address space: 0x%X", Reg->SpaceId));
+ return (AE_SUPPORT);
+ }
+
+ /* Validate the BitWidth */
+
+ if ((Reg->BitWidth != 8) &&
+ (Reg->BitWidth != 16) &&
+ (Reg->BitWidth != 32) &&
+ (Reg->BitWidth != MaxBitWidth))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Unsupported register bit width: 0x%X", Reg->BitWidth));
+ return (AE_SUPPORT);
+ }
+
+ /* Validate the BitOffset. Just a warning for now. */
+
+ if (Reg->BitOffset != 0)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Unsupported register bit offset: 0x%X", Reg->BitOffset));
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwRead
+ *
+ * PARAMETERS: Value - Where the value is returned
+ * Reg - GAS register structure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
+ * version of AcpiRead, used internally since the overhead of
+ * 64-bit values is not needed.
+ *
+ * LIMITATIONS: <These limitations also apply to AcpiHwWrite>
+ * BitWidth must be exactly 8, 16, or 32.
+ * SpaceID must be SystemMemory or SystemIO.
+ * BitOffset and AccessWidth are currently ignored, as there has
+ * not been a need to implement these.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwRead (
+ UINT32 *Value,
+ ACPI_GENERIC_ADDRESS *Reg)
+{
+ UINT64 Address;
+ UINT64 Value64;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (HwRead);
+
+
+ /* Validate contents of the GAS register */
+
+ Status = AcpiHwValidateRegister (Reg, 32, &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Initialize entire 32-bit return value to zero */
+
+ *Value = 0;
+
+ /*
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
+ */
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+ {
+ Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, &Value64, Reg->BitWidth);
+
+ *Value = (UINT32) Value64;
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
+ Address, Value, Reg->BitWidth);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
+ *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
+ AcpiUtGetRegionName (Reg->SpaceId)));
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwWrite
+ *
+ * PARAMETERS: Value - Value to be written
+ * Reg - GAS register structure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
+ * version of AcpiWrite, used internally since the overhead of
+ * 64-bit values is not needed.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwWrite (
+ UINT32 Value,
+ ACPI_GENERIC_ADDRESS *Reg)
+{
+ UINT64 Address;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (HwWrite);
+
+
+ /* Validate contents of the GAS register */
+
+ Status = AcpiHwValidateRegister (Reg, 32, &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
+ */
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+ {
+ Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, (UINT64) Value, Reg->BitWidth);
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
+ Address, Value, Reg->BitWidth);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
+ Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
+ AcpiUtGetRegionName (Reg->SpaceId)));
+
+ return (Status);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwClearAcpiStatus
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clears all fixed and general purpose status bits
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwClearAcpiStatus (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS LockFlags = 0;
+
+
+ ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
+ ACPI_BITMASK_ALL_FIXED_STATUS,
+ ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
+
+ LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
+
+ /* Clear the fixed events in PM1 A/B */
+
+ Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITMASK_ALL_FIXED_STATUS);
+
+ AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Clear the GPE Bits in all GPE registers in all GPE blocks */
+
+ Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
+
+Exit:
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwGetBitRegisterInfo
+ *
+ * PARAMETERS: RegisterId - Index of ACPI Register to access
+ *
+ * RETURN: The bitmask to be used when accessing the register
+ *
+ * DESCRIPTION: Map RegisterId into a register bitmask.
+ *
+ ******************************************************************************/
+
+ACPI_BIT_REGISTER_INFO *
+AcpiHwGetBitRegisterInfo (
+ UINT32 RegisterId)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (RegisterId > ACPI_BITREG_MAX)
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
+ return (NULL);
+ }
+
+ return (&AcpiGbl_BitRegisterInfo[RegisterId]);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwWritePm1Control
+ *
+ * PARAMETERS: Pm1aControl - Value to be written to PM1A control
+ * Pm1bControl - Value to be written to PM1B control
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ * different than than the PM1 A/B status and enable registers
+ * in that different values can be written to the A/B registers.
+ * Most notably, the SLP_TYP bits can be different, as per the
+ * values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwWritePm1Control (
+ UINT32 Pm1aControl,
+ UINT32 Pm1bControl)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwWritePm1Control);
+
+
+ Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (AcpiGbl_FADT.XPm1bControlBlock.Address)
+ {
+ Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwRegisterRead
+ *
+ * PARAMETERS: RegisterId - ACPI Register ID
+ * ReturnValue - Where the register value is returned
+ *
+ * RETURN: Status and the value read.
+ *
+ * DESCRIPTION: Read from the specified ACPI register
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwRegisterRead (
+ UINT32 RegisterId,
+ UINT32 *ReturnValue)
+{
+ UINT32 Value = 0;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwRegisterRead);
+
+
+ switch (RegisterId)
+ {
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
+
+ Status = AcpiHwReadMultiple (&Value,
+ &AcpiGbl_XPm1aStatus,
+ &AcpiGbl_XPm1bStatus);
+ break;
+
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
+
+ Status = AcpiHwReadMultiple (&Value,
+ &AcpiGbl_XPm1aEnable,
+ &AcpiGbl_XPm1bEnable);
+ break;
+
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
+
+ Status = AcpiHwReadMultiple (&Value,
+ &AcpiGbl_FADT.XPm1aControlBlock,
+ &AcpiGbl_FADT.XPm1bControlBlock);
+
+ /*
+ * Zero the write-only bits. From the ACPI specification, "Hardware
+ * Write-Only Bits": "Upon reads to registers with write-only bits,
+ * software masks out all write-only bits."
+ */
+ Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
+ break;
+
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
+
+ Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
+ break;
+
+ case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
+
+ Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
+ break;
+
+ case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
+
+ Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
+ RegisterId));
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ *ReturnValue = Value;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwRegisterWrite
+ *
+ * PARAMETERS: RegisterId - ACPI Register ID
+ * Value - The value to write
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to the specified ACPI register
+ *
+ * NOTE: In accordance with the ACPI specification, this function automatically
+ * preserves the value of the following bits, meaning that these bits cannot be
+ * changed via this interface:
+ *
+ * PM1_CONTROL[0] = SCI_EN
+ * PM1_CONTROL[9]
+ * PM1_STATUS[11]
+ *
+ * ACPI References:
+ * 1) Hardware Ignored Bits: When software writes to a register with ignored
+ * bit fields, it preserves the ignored bit fields
+ * 2) SCI_EN: OSPM always preserves this bit position
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwRegisterWrite (
+ UINT32 RegisterId,
+ UINT32 Value)
+{
+ ACPI_STATUS Status;
+ UINT32 ReadValue;
+
+
+ ACPI_FUNCTION_TRACE (HwRegisterWrite);
+
+
+ switch (RegisterId)
+ {
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
+ /*
+ * Handle the "ignored" bit in PM1 Status. According to the ACPI
+ * specification, ignored bits are to be preserved when writing.
+ * Normally, this would mean a read/modify/write sequence. However,
+ * preserving a bit in the status register is different. Writing a
+ * one clears the status, and writing a zero preserves the status.
+ * Therefore, we must always write zero to the ignored bit.
+ *
+ * This behavior is clarified in the ACPI 4.0 specification.
+ */
+ Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
+
+ Status = AcpiHwWriteMultiple (Value,
+ &AcpiGbl_XPm1aStatus,
+ &AcpiGbl_XPm1bStatus);
+ break;
+
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
+
+ Status = AcpiHwWriteMultiple (Value,
+ &AcpiGbl_XPm1aEnable,
+ &AcpiGbl_XPm1bEnable);
+ break;
+
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
+ /*
+ * Perform a read first to preserve certain bits (per ACPI spec)
+ * Note: This includes SCI_EN, we never want to change this bit
+ */
+ Status = AcpiHwReadMultiple (&ReadValue,
+ &AcpiGbl_FADT.XPm1aControlBlock,
+ &AcpiGbl_FADT.XPm1bControlBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Insert the bits to be preserved */
+
+ ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue);
+
+ /* Now we can write the data */
+
+ Status = AcpiHwWriteMultiple (Value,
+ &AcpiGbl_FADT.XPm1aControlBlock,
+ &AcpiGbl_FADT.XPm1bControlBlock);
+ break;
+
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
+ /*
+ * For control registers, all reserved bits must be preserved,
+ * as per the ACPI spec.
+ */
+ Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Insert the bits to be preserved */
+
+ ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue);
+
+ Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
+ break;
+
+ case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
+
+ Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
+ break;
+
+ case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
+
+ /* SMI_CMD is currently always in IO space */
+
+ Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
+ RegisterId));
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+Exit:
+ return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwReadMultiple
+ *
+ * PARAMETERS: Value - Where the register value is returned
+ * RegisterA - First ACPI register (required)
+ * RegisterB - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwReadMultiple (
+ UINT32 *Value,
+ ACPI_GENERIC_ADDRESS *RegisterA,
+ ACPI_GENERIC_ADDRESS *RegisterB)
+{
+ UINT32 ValueA = 0;
+ UINT32 ValueB = 0;
+ ACPI_STATUS Status;
+
+
+ /* The first register is always required */
+
+ Status = AcpiHwRead (&ValueA, RegisterA);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Second register is optional */
+
+ if (RegisterB->Address)
+ {
+ Status = AcpiHwRead (&ValueB, RegisterB);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ /*
+ * OR the two return values together. No shifting or masking is necessary,
+ * because of how the PM1 registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ *Value = (ValueA | ValueB);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwWriteMultiple
+ *
+ * PARAMETERS: Value - The value to write
+ * RegisterA - First ACPI register (required)
+ * RegisterB - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwWriteMultiple (
+ UINT32 Value,
+ ACPI_GENERIC_ADDRESS *RegisterA,
+ ACPI_GENERIC_ADDRESS *RegisterB)
+{
+ ACPI_STATUS Status;
+
+
+ /* The first register is always required */
+
+ Status = AcpiHwWrite (Value, RegisterA);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Second register is optional
+ *
+ * No bit shifting or clearing is necessary, because of how the PM1
+ * registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ if (RegisterB->Address)
+ {
+ Status = AcpiHwWrite (Value, RegisterB);
+ }
+
+ return (Status);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwsleep.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwsleep.c
new file mode 100644
index 0000000000..2bc434eda7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwsleep.c
@@ -0,0 +1,354 @@
+/******************************************************************************
+ *
+ * Name: hwsleep.c - ACPI Hardware Sleep/Wake Support functions for the
+ * original/legacy sleep/PM registers.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwsleep")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwLegacySleep
+ *
+ * PARAMETERS: SleepState - Which sleep state to enter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter a system sleep state via the legacy FADT PM registers
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwLegacySleep (
+ UINT8 SleepState)
+{
+ ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo;
+ ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo;
+ UINT32 Pm1aControl;
+ UINT32 Pm1bControl;
+ UINT32 InValue;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwLegacySleep);
+
+
+ SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
+ SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
+
+ /* Clear wake status */
+
+ Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Clear all fixed and general purpose status bits */
+
+ Status = AcpiHwClearAcpiStatus ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * 1) Disable/Clear all GPEs
+ * 2) Enable all wakeup GPEs
+ */
+ Status = AcpiHwDisableAllGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ AcpiGbl_SystemAwakeAndRunning = FALSE;
+
+ Status = AcpiHwEnableAllWakeupGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get current value of PM1A control */
+
+ Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL,
+ &Pm1aControl);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Entering sleep state [S%u]\n", SleepState));
+
+ /* Clear the SLP_EN and SLP_TYP fields */
+
+ Pm1aControl &= ~(SleepTypeRegInfo->AccessBitMask |
+ SleepEnableRegInfo->AccessBitMask);
+ Pm1bControl = Pm1aControl;
+
+ /* Insert the SLP_TYP bits */
+
+ Pm1aControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition);
+ Pm1bControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition);
+
+ /*
+ * We split the writes of SLP_TYP and SLP_EN to workaround
+ * poorly implemented hardware.
+ */
+
+ /* Write #1: write the SLP_TYP data to the PM1 Control registers */
+
+ Status = AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Insert the sleep enable (SLP_EN) bit */
+
+ Pm1aControl |= SleepEnableRegInfo->AccessBitMask;
+ Pm1bControl |= SleepEnableRegInfo->AccessBitMask;
+
+ /* Flush caches, as per ACPI specification */
+
+ ACPI_FLUSH_CPU_CACHE ();
+
+ /* Write #2: Write both SLP_TYP + SLP_EN */
+
+ Status = AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (SleepState > ACPI_STATE_S3)
+ {
+ /*
+ * We wanted to sleep > S3, but it didn't happen (by virtue of the
+ * fact that we are still executing!)
+ *
+ * Wait ten seconds, then try again. This is to get S4/S5 to work on
+ * all machines.
+ *
+ * We wait so long to allow chipsets that poll this reg very slowly
+ * to still read the right value. Ideally, this block would go
+ * away entirely.
+ */
+ AcpiOsStall (10 * ACPI_USEC_PER_SEC);
+
+ Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_CONTROL,
+ SleepEnableRegInfo->AccessBitMask);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Wait for transition back to Working State */
+
+ do
+ {
+ Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ } while (!InValue);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwLegacyWakePrep
+ *
+ * PARAMETERS: SleepState - Which sleep state we just exited
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
+ * sleep.
+ * Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwLegacyWakePrep (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+ ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo;
+ ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo;
+ UINT32 Pm1aControl;
+ UINT32 Pm1bControl;
+
+
+ ACPI_FUNCTION_TRACE (HwLegacyWakePrep);
+
+ /*
+ * Set SLP_TYPE and SLP_EN to state S0.
+ * This is unclear from the ACPI Spec, but it is required
+ * by some machines.
+ */
+ Status = AcpiGetSleepTypeData (ACPI_STATE_S0,
+ &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
+ if (ACPI_SUCCESS (Status))
+ {
+ SleepTypeRegInfo =
+ AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
+ SleepEnableRegInfo =
+ AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
+
+ /* Get current value of PM1A control */
+
+ Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL,
+ &Pm1aControl);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Clear the SLP_EN and SLP_TYP fields */
+
+ Pm1aControl &= ~(SleepTypeRegInfo->AccessBitMask |
+ SleepEnableRegInfo->AccessBitMask);
+ Pm1bControl = Pm1aControl;
+
+ /* Insert the SLP_TYP bits */
+
+ Pm1aControl |= (AcpiGbl_SleepTypeA <<
+ SleepTypeRegInfo->BitPosition);
+ Pm1bControl |= (AcpiGbl_SleepTypeB <<
+ SleepTypeRegInfo->BitPosition);
+
+ /* Write the control registers and ignore any errors */
+
+ (void) AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwLegacyWake
+ *
+ * PARAMETERS: SleepState - Which sleep state we just exited
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
+ * Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwLegacyWake (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (HwLegacyWake);
+
+
+ /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */
+
+ AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID;
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING);
+
+ /*
+ * GPEs must be enabled before _WAK is called as GPEs
+ * might get fired there
+ *
+ * Restore the GPEs:
+ * 1) Disable/Clear all GPEs
+ * 2) Enable all runtime GPEs
+ */
+ Status = AcpiHwDisableAllGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwEnableAllRuntimeGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Now we can execute _WAK, etc. Some machines require that the GPEs
+ * are enabled before the wake methods are executed.
+ */
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState);
+
+ /*
+ * Some BIOS code assumes that WAK_STS will be cleared on resume
+ * and use it to determine whether the system is rebooting or
+ * resuming. Clear WAK_STS for compatibility.
+ */
+ (void) AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
+ AcpiGbl_SystemAwakeAndRunning = TRUE;
+
+ /* Enable power button */
+
+ (void) AcpiWriteBitRegister(
+ AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId,
+ ACPI_ENABLE_EVENT);
+
+ (void) AcpiWriteBitRegister(
+ AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId,
+ ACPI_CLEAR_STATUS);
+
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwtimer.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwtimer.c
new file mode 100644
index 0000000000..39c9e57187
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwtimer.c
@@ -0,0 +1,233 @@
+/******************************************************************************
+ *
+ * Name: hwtimer.c - ACPI Power Management Timer Interface
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwtimer")
+
+
+#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetTimerResolution
+ *
+ * PARAMETERS: Resolution - Where the resolution is returned
+ *
+ * RETURN: Status and timer resolution
+ *
+ * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTimerResolution (
+ UINT32 *Resolution)
+{
+ ACPI_FUNCTION_TRACE (AcpiGetTimerResolution);
+
+
+ if (!Resolution)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
+ {
+ *Resolution = 24;
+ }
+ else
+ {
+ *Resolution = 32;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTimerResolution)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetTimer
+ *
+ * PARAMETERS: Ticks - Where the timer value is returned
+ *
+ * RETURN: Status and current timer value (ticks)
+ *
+ * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTimer (
+ UINT32 *Ticks)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetTimer);
+
+
+ if (!Ticks)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* ACPI 5.0A: PM Timer is optional */
+
+ if (!AcpiGbl_FADT.XPmTimerBlock.Address)
+ {
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTimer)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetTimerDuration
+ *
+ * PARAMETERS: StartTicks - Starting timestamp
+ * EndTicks - End timestamp
+ * TimeElapsed - Where the elapsed time is returned
+ *
+ * RETURN: Status and TimeElapsed
+ *
+ * DESCRIPTION: Computes the time elapsed (in microseconds) between two
+ * PM Timer time stamps, taking into account the possibility of
+ * rollovers, the timer resolution, and timer frequency.
+ *
+ * The PM Timer's clock ticks at roughly 3.6 times per
+ * _microsecond_, and its clock continues through Cx state
+ * transitions (unlike many CPU timestamp counters) -- making it
+ * a versatile and accurate timer.
+ *
+ * Note that this function accommodates only a single timer
+ * rollover. Thus for 24-bit timers, this function should only
+ * be used for calculating durations less than ~4.6 seconds
+ * (~20 minutes for 32-bit timers) -- calculations below:
+ *
+ * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
+ * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTimerDuration (
+ UINT32 StartTicks,
+ UINT32 EndTicks,
+ UINT32 *TimeElapsed)
+{
+ ACPI_STATUS Status;
+ UINT32 DeltaTicks;
+ UINT64 Quotient;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetTimerDuration);
+
+
+ if (!TimeElapsed)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* ACPI 5.0A: PM Timer is optional */
+
+ if (!AcpiGbl_FADT.XPmTimerBlock.Address)
+ {
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ /*
+ * Compute Tick Delta:
+ * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
+ */
+ if (StartTicks < EndTicks)
+ {
+ DeltaTicks = EndTicks - StartTicks;
+ }
+ else if (StartTicks > EndTicks)
+ {
+ if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
+ {
+ /* 24-bit Timer */
+
+ DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
+ }
+ else
+ {
+ /* 32-bit Timer */
+
+ DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
+ }
+ }
+ else /* StartTicks == EndTicks */
+ {
+ *TimeElapsed = 0;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Compute Duration (Requires a 64-bit multiply and divide):
+ *
+ * TimeElapsed (microseconds) =
+ * (DeltaTicks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
+ */
+ Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * ACPI_USEC_PER_SEC,
+ ACPI_PM_TIMER_FREQUENCY, &Quotient, NULL);
+
+ *TimeElapsed = (UINT32) Quotient;
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTimerDuration)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwvalid.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwvalid.c
new file mode 100644
index 0000000000..3b6b567086
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwvalid.c
@@ -0,0 +1,363 @@
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwvalid")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiHwValidateIoRequest (
+ ACPI_IO_ADDRESS Address,
+ UINT32 BitWidth);
+
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a WinXP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ * DMA: DMA controller
+ * PIC0: Programmable Interrupt Controller (8259A)
+ * PIT1: System Timer 1
+ * PIT2: System Timer 2 failsafe
+ * RTC: Real-time clock
+ * CMOS: Extended CMOS
+ * DMA1: DMA 1 page registers
+ * DMA1L: DMA 1 Ch 0 low page
+ * DMA2: DMA 2 page registers
+ * DMA2L: DMA 2 low page refresh
+ * ARBC: Arbitration control
+ * SETUP: Reserved system board setup
+ * POS: POS channel select
+ * PIC1: Cascaded PIC
+ * IDMA: ISA DMA
+ * ELCR: PIC edge/level registers
+ * PCI: PCI configuration space
+ */
+static const ACPI_PORT_INFO AcpiProtectedPorts[] =
+{
+ {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+ {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+ {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+ {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+ {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+ {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+ {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+ {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+ {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+ {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+ {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+ {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+ {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+ {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+ {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+ {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+ {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (AcpiProtectedPorts)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwValidateIoRequest
+ *
+ * PARAMETERS: Address Address of I/O port/register
+ * BitWidth Number of bits (8,16,32)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ * always illegal and some ports are only illegal depending on
+ * the requests the BIOS AML code makes to the predefined
+ * _OSI method.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwValidateIoRequest (
+ ACPI_IO_ADDRESS Address,
+ UINT32 BitWidth)
+{
+ UINT32 i;
+ UINT32 ByteWidth;
+ ACPI_IO_ADDRESS LastAddress;
+ const ACPI_PORT_INFO *PortInfo;
+
+
+ ACPI_FUNCTION_TRACE (HwValidateIoRequest);
+
+
+ /* Supported widths are 8/16/32 */
+
+ if ((BitWidth != 8) &&
+ (BitWidth != 16) &&
+ (BitWidth != 32))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Bad BitWidth parameter: %8.8X", BitWidth));
+ return (AE_BAD_PARAMETER);
+ }
+
+ PortInfo = AcpiProtectedPorts;
+ ByteWidth = ACPI_DIV_8 (BitWidth);
+ LastAddress = Address + ByteWidth - 1;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Address %8.8X%8.8X LastAddress %8.8X%8.8X Length %X",
+ ACPI_FORMAT_UINT64 (Address), ACPI_FORMAT_UINT64 (LastAddress),
+ ByteWidth));
+
+ /* Maximum 16-bit address in I/O space */
+
+ if (LastAddress > ACPI_UINT16_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Illegal I/O port address/length above 64K: %8.8X%8.8X/0x%X",
+ ACPI_FORMAT_UINT64 (Address), ByteWidth));
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ /* Exit if requested address is not within the protected port table */
+
+ if (Address > AcpiProtectedPorts[ACPI_PORT_INFO_ENTRIES - 1].End)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Check request against the list of protected I/O ports */
+
+ for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, PortInfo++)
+ {
+ /*
+ * Check if the requested address range will write to a reserved
+ * port. Four cases to consider:
+ *
+ * 1) Address range is contained completely in the port address range
+ * 2) Address range overlaps port range at the port range start
+ * 3) Address range overlaps port range at the port range end
+ * 4) Address range completely encompasses the port range
+ */
+ if ((Address <= PortInfo->End) && (LastAddress >= PortInfo->Start))
+ {
+ /* Port illegality may depend on the _OSI calls made by the BIOS */
+
+ if (AcpiGbl_OsiData >= PortInfo->OsiDependency)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_FORMAT_UINT64 (Address), ByteWidth, PortInfo->Name,
+ PortInfo->Start, PortInfo->End));
+
+ return_ACPI_STATUS (AE_AML_ILLEGAL_ADDRESS);
+ }
+ }
+
+ /* Finished if address range ends before the end of this port */
+
+ if (LastAddress <= PortInfo->End)
+ {
+ break;
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwReadPort
+ *
+ * PARAMETERS: Address Address of I/O port/register to read
+ * Value Where value is placed
+ * Width Number of bits
+ *
+ * RETURN: Status and value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ * to AcpiOsReadPort that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiHwReadPort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 *Value,
+ UINT32 Width)
+{
+ ACPI_STATUS Status;
+ UINT32 OneByte;
+ UINT32 i;
+
+
+ /* Truncate address to 16 bits if requested */
+
+ if (AcpiGbl_TruncateIoAddresses)
+ {
+ Address &= ACPI_UINT16_MAX;
+ }
+
+ /* Validate the entire request and perform the I/O */
+
+ Status = AcpiHwValidateIoRequest (Address, Width);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiOsReadPort (Address, Value, Width);
+ return (Status);
+ }
+
+ if (Status != AE_AML_ILLEGAL_ADDRESS)
+ {
+ return (Status);
+ }
+
+ /*
+ * There has been a protection violation within the request. Fall
+ * back to byte granularity port I/O and ignore the failing bytes.
+ * This provides Windows compatibility.
+ */
+ for (i = 0, *Value = 0; i < Width; i += 8)
+ {
+ /* Validate and read one byte */
+
+ if (AcpiHwValidateIoRequest (Address, 8) == AE_OK)
+ {
+ Status = AcpiOsReadPort (Address, &OneByte, 8);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *Value |= (OneByte << i);
+ }
+
+ Address++;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwWritePort
+ *
+ * PARAMETERS: Address Address of I/O port/register to write
+ * Value Value to write
+ * Width Number of bits
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ * to AcpiOsWritePort that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiHwWritePort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 Value,
+ UINT32 Width)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /* Truncate address to 16 bits if requested */
+
+ if (AcpiGbl_TruncateIoAddresses)
+ {
+ Address &= ACPI_UINT16_MAX;
+ }
+
+ /* Validate the entire request and perform the I/O */
+
+ Status = AcpiHwValidateIoRequest (Address, Width);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiOsWritePort (Address, Value, Width);
+ return (Status);
+ }
+
+ if (Status != AE_AML_ILLEGAL_ADDRESS)
+ {
+ return (Status);
+ }
+
+ /*
+ * There has been a protection violation within the request. Fall
+ * back to byte granularity port I/O and ignore the failing bytes.
+ * This provides Windows compatibility.
+ */
+ for (i = 0; i < Width; i += 8)
+ {
+ /* Validate and write one byte */
+
+ if (AcpiHwValidateIoRequest (Address, 8) == AE_OK)
+ {
+ Status = AcpiOsWritePort (Address, (Value >> i) & 0xFF, 8);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ Address++;
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxface.c
new file mode 100644
index 0000000000..fcd5c9e852
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxface.c
@@ -0,0 +1,653 @@
+/******************************************************************************
+ *
+ * Module Name: hwxface - Public ACPICA hardware interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwxface")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiReset
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
+ * support reset register in PCI config space, this must be
+ * handled separately.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReset (
+ void)
+{
+ ACPI_GENERIC_ADDRESS *ResetReg;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiReset);
+
+
+ ResetReg = &AcpiGbl_FADT.ResetRegister;
+
+ /* Check if the reset register is supported */
+
+ if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
+ !ResetReg->Address)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
+ {
+ /*
+ * For I/O space, write directly to the OSL. This bypasses the port
+ * validation mechanism, which may block a valid write to the reset
+ * register.
+ *
+ * NOTE:
+ * The ACPI spec requires the reset register width to be 8, so we
+ * hardcode it here and ignore the FADT value. This maintains
+ * compatibility with other ACPI implementations that have allowed
+ * BIOS code with bad register width values to go unnoticed.
+ */
+ Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
+ AcpiGbl_FADT.ResetValue, ACPI_RESET_REGISTER_WIDTH);
+ }
+ else
+ {
+ /* Write the reset value to the reset register */
+
+ Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiReset)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiRead
+ *
+ * PARAMETERS: Value - Where the value is returned
+ * Reg - GAS register structure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from either memory or IO space.
+ *
+ * LIMITATIONS: <These limitations also apply to AcpiWrite>
+ * BitWidth must be exactly 8, 16, 32, or 64.
+ * SpaceID must be SystemMemory or SystemIO.
+ * BitOffset and AccessWidth are currently ignored, as there has
+ * not been a need to implement these.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRead (
+ UINT64 *ReturnValue,
+ ACPI_GENERIC_ADDRESS *Reg)
+{
+ UINT32 ValueLo;
+ UINT32 ValueHi;
+ UINT32 Width;
+ UINT64 Address;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (AcpiRead);
+
+
+ if (!ReturnValue)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Validate contents of the GAS register. Allow 64-bit transfers */
+
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Two address spaces supported: Memory or I/O. PCI_Config is
+ * not supported here because the GAS structure is insufficient
+ */
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+ {
+ Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, ReturnValue, Reg->BitWidth);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ ValueLo = 0;
+ ValueHi = 0;
+
+ Width = Reg->BitWidth;
+ if (Width == 64)
+ {
+ Width = 32; /* Break into two 32-bit transfers */
+ }
+
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
+ Address, &ValueLo, Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Reg->BitWidth == 64)
+ {
+ /* Read the top 32 bits */
+
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
+ (Address + 4), &ValueHi, 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ /* Set the return value only if status is AE_OK */
+
+ *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
+ ACPI_FORMAT_UINT64 (Address),
+ AcpiUtGetRegionName (Reg->SpaceId)));
+
+ return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRead)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiWrite
+ *
+ * PARAMETERS: Value - Value to be written
+ * Reg - GAS register structure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to either memory or IO space.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiWrite (
+ UINT64 Value,
+ ACPI_GENERIC_ADDRESS *Reg)
+{
+ UINT32 Width;
+ UINT64 Address;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (AcpiWrite);
+
+
+ /* Validate contents of the GAS register. Allow 64-bit transfers */
+
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
+ */
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+ {
+ Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, Value, Reg->BitWidth);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ Width = Reg->BitWidth;
+ if (Width == 64)
+ {
+ Width = 32; /* Break into two 32-bit transfers */
+ }
+
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
+ Address, ACPI_LODWORD (Value), Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Reg->BitWidth == 64)
+ {
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
+ (Address + 4), ACPI_HIDWORD (Value), 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
+ ACPI_FORMAT_UINT64 (Address),
+ AcpiUtGetRegionName (Reg->SpaceId)));
+
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiWrite)
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiReadBitRegister
+ *
+ * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
+ * ReturnValue - Value that was read from the register,
+ * normalized to bit position zero.
+ *
+ * RETURN: Status and the value read from the specified Register. Value
+ * returned is normalized to bit0 (is shifted all the way right)
+ *
+ * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
+ *
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ * since almost all of them are single bit and it does not matter that
+ * the parent hardware register can be split across two physical
+ * registers. The only multi-bit field is SLP_TYP in the PM1 control
+ * register, but this field does not cross an 8-bit boundary (nor does
+ * it make much sense to actually read this field.)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReadBitRegister (
+ UINT32 RegisterId,
+ UINT32 *ReturnValue)
+{
+ ACPI_BIT_REGISTER_INFO *BitRegInfo;
+ UINT32 RegisterValue;
+ UINT32 Value;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_U32 (AcpiReadBitRegister, RegisterId);
+
+
+ /* Get the info structure corresponding to the requested ACPI Register */
+
+ BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
+ if (!BitRegInfo)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Read the entire parent register */
+
+ Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
+ &RegisterValue);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Normalize the value that was read, mask off other bits */
+
+ Value = ((RegisterValue & BitRegInfo->AccessBitMask)
+ >> BitRegInfo->BitPosition);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+ RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
+
+ *ReturnValue = Value;
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiWriteBitRegister
+ *
+ * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
+ * Value - Value to write to the register, in bit
+ * position zero. The bit is automatically
+ * shifted to the correct position.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ * since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiWriteBitRegister (
+ UINT32 RegisterId,
+ UINT32 Value)
+{
+ ACPI_BIT_REGISTER_INFO *BitRegInfo;
+ ACPI_CPU_FLAGS LockFlags;
+ UINT32 RegisterValue;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_U32 (AcpiWriteBitRegister, RegisterId);
+
+
+ /* Get the info structure corresponding to the requested ACPI Register */
+
+ BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
+ if (!BitRegInfo)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
+
+ /*
+ * At this point, we know that the parent register is one of the
+ * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
+ */
+ if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS)
+ {
+ /*
+ * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+ *
+ * Perform a register read to preserve the bits that we are not
+ * interested in
+ */
+ Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
+ &RegisterValue);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Insert the input bit into the value that was just read
+ * and write the register
+ */
+ ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
+ BitRegInfo->AccessBitMask, Value);
+
+ Status = AcpiHwRegisterWrite (BitRegInfo->ParentRegister,
+ RegisterValue);
+ }
+ else
+ {
+ /*
+ * 2) Case for PM1 Status
+ *
+ * The Status register is different from the rest. Clear an event
+ * by writing 1, writing 0 has no effect. So, the only relevant
+ * information is the single bit we're interested in, all others
+ * should be written as 0 so they will be left unchanged.
+ */
+ RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value,
+ BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
+
+ /* No need to write the register if value is all zeros */
+
+ if (RegisterValue)
+ {
+ Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
+ RegisterValue);
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+ RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
+
+
+UnlockAndExit:
+
+ AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetSleepTypeData
+ *
+ * PARAMETERS: SleepState - Numeric sleep state
+ * *SleepTypeA - Where SLP_TYPa is returned
+ * *SleepTypeB - Where SLP_TYPb is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
+ * sleep state via the appropriate \_Sx object.
+ *
+ * The sleep state package returned from the corresponding \_Sx_ object
+ * must contain at least one integer.
+ *
+ * March 2005:
+ * Added support for a package that contains two integers. This
+ * goes against the ACPI specification which defines this object as a
+ * package with one encoded DWORD integer. However, existing practice
+ * by many BIOS vendors is to return a package with 2 or more integer
+ * elements, at least one per sleep type (A/B).
+ *
+ * January 2013:
+ * Therefore, we must be prepared to accept a package with either a
+ * single integer or multiple integers.
+ *
+ * The single integer DWORD format is as follows:
+ * BYTE 0 - Value for the PM1A SLP_TYP register
+ * BYTE 1 - Value for the PM1B SLP_TYP register
+ * BYTE 2-3 - Reserved
+ *
+ * The dual integer format is as follows:
+ * Integer 0 - Value for the PM1A SLP_TYP register
+ * Integer 1 - Value for the PM1A SLP_TYP register
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetSleepTypeData (
+ UINT8 SleepState,
+ UINT8 *SleepTypeA,
+ UINT8 *SleepTypeB)
+{
+ ACPI_STATUS Status;
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_OPERAND_OBJECT **Elements;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
+
+
+ /* Validate parameters */
+
+ if ((SleepState > ACPI_S_STATES_MAX) ||
+ !SleepTypeA || !SleepTypeB)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Allocate the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Evaluate the \_Sx namespace object containing the register values
+ * for this state
+ */
+ Info->RelativePathname = ACPI_CAST_PTR (
+ char, AcpiGbl_SleepStateNames[SleepState]);
+ Status = AcpiNsEvaluate (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Must have a return object */
+
+ if (!Info->ReturnObject)
+ {
+ ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
+ Info->RelativePathname));
+ Status = AE_AML_NO_RETURN_VALUE;
+ goto Cleanup;
+ }
+
+ /* Return object must be of type Package */
+
+ if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
+ {
+ ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
+ Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup1;
+ }
+
+ /*
+ * Any warnings about the package length or the object types have
+ * already been issued by the predefined name module -- there is no
+ * need to repeat them here.
+ */
+ Elements = Info->ReturnObject->Package.Elements;
+ switch (Info->ReturnObject->Package.Count)
+ {
+ case 0:
+
+ Status = AE_AML_PACKAGE_LIMIT;
+ break;
+
+ case 1:
+
+ if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ /* A valid _Sx_ package with one integer */
+
+ *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
+ *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8);
+ break;
+
+ case 2:
+ default:
+
+ if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) ||
+ (Elements[1]->Common.Type != ACPI_TYPE_INTEGER))
+ {
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ /* A valid _Sx_ package with two integers */
+
+ *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
+ *SleepTypeB = (UINT8) Elements[1]->Integer.Value;
+ break;
+ }
+
+Cleanup1:
+ AcpiUtRemoveReference (Info->ReturnObject);
+
+Cleanup:
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While evaluating Sleep State [%s]", Info->RelativePathname));
+ }
+
+ ACPI_FREE (Info);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
new file mode 100644
index 0000000000..e6d99e46c4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
@@ -0,0 +1,500 @@
+/******************************************************************************
+ *
+ * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_HARDWARE
+ ACPI_MODULE_NAME ("hwxfsleep")
+
+/* Local prototypes */
+
+#if (!ACPI_REDUCED_HARDWARE)
+static ACPI_STATUS
+AcpiHwSetFirmwareWakingVector (
+ ACPI_TABLE_FACS *Facs,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64);
+#endif
+
+static ACPI_STATUS
+AcpiHwSleepDispatch (
+ UINT8 SleepState,
+ UINT32 FunctionId);
+
+/*
+ * Dispatch table used to efficiently branch to the various sleep
+ * functions.
+ */
+#define ACPI_SLEEP_FUNCTION_ID 0
+#define ACPI_WAKE_PREP_FUNCTION_ID 1
+#define ACPI_WAKE_FUNCTION_ID 2
+
+/* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */
+
+static ACPI_SLEEP_FUNCTIONS AcpiSleepDispatch[] =
+{
+ {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacySleep), AcpiHwExtendedSleep},
+ {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWakePrep), AcpiHwExtendedWakePrep},
+ {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWake), AcpiHwExtendedWake}
+};
+
+
+/*
+ * These functions are removed for the ACPI_REDUCED_HARDWARE case:
+ * AcpiSetFirmwareWakingVector
+ * AcpiEnterSleepStateS4bios
+ */
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwSetFirmwareWakingVector
+ *
+ * PARAMETERS: Facs - Pointer to FACS table
+ * PhysicalAddress - 32-bit physical address of ACPI real mode
+ * entry point
+ * PhysicalAddress64 - 64-bit physical address of ACPI protected
+ * entry point
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwSetFirmwareWakingVector (
+ ACPI_TABLE_FACS *Facs,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64)
+{
+ ACPI_FUNCTION_TRACE (AcpiHwSetFirmwareWakingVector);
+
+
+ /*
+ * According to the ACPI specification 2.0c and later, the 64-bit
+ * waking vector should be cleared and the 32-bit waking vector should
+ * be used, unless we want the wake-up code to be called by the BIOS in
+ * Protected Mode. Some systems (for example HP dv5-1004nr) are known
+ * to fail to resume if the 64-bit vector is used.
+ */
+
+ /* Set the 32-bit vector */
+
+ Facs->FirmwareWakingVector = (UINT32) PhysicalAddress;
+
+ if (Facs->Length > 32)
+ {
+ if (Facs->Version >= 1)
+ {
+ /* Set the 64-bit vector */
+
+ Facs->XFirmwareWakingVector = PhysicalAddress64;
+ }
+ else
+ {
+ /* Clear the 64-bit vector if it exists */
+
+ Facs->XFirmwareWakingVector = 0;
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetFirmwareWakingVector
+ *
+ * PARAMETERS: PhysicalAddress - 32-bit physical address of ACPI real mode
+ * entry point
+ * PhysicalAddress64 - 64-bit physical address of ACPI protected
+ * entry point
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetFirmwareWakingVector (
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64)
+{
+
+ ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
+
+ if (AcpiGbl_FACS)
+ {
+ (void) AcpiHwSetFirmwareWakingVector (AcpiGbl_FACS,
+ PhysicalAddress, PhysicalAddress64);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnterSleepStateS4bios
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform a S4 bios request.
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnterSleepStateS4bios (
+ void)
+{
+ UINT32 InValue;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios);
+
+
+ /* Clear the wake status bit (PM1) */
+
+ Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwClearAcpiStatus ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * 1) Disable/Clear all GPEs
+ * 2) Enable all wakeup GPEs
+ */
+ Status = AcpiHwDisableAllGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ AcpiGbl_SystemAwakeAndRunning = FALSE;
+
+ Status = AcpiHwEnableAllWakeupGpes ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_FLUSH_CPU_CACHE ();
+
+ Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
+ (UINT32) AcpiGbl_FADT.S4BiosRequest, 8);
+
+ do {
+ AcpiOsStall (ACPI_USEC_PER_MSEC);
+ Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ } while (!InValue);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios)
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiHwSleepDispatch
+ *
+ * PARAMETERS: SleepState - Which sleep state to enter/exit
+ * FunctionId - Sleep, WakePrep, or Wake
+ *
+ * RETURN: Status from the invoked sleep handling function.
+ *
+ * DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling
+ * function.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwSleepDispatch (
+ UINT8 SleepState,
+ UINT32 FunctionId)
+{
+ ACPI_STATUS Status;
+ ACPI_SLEEP_FUNCTIONS *SleepFunctions = &AcpiSleepDispatch[FunctionId];
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+ /*
+ * If the Hardware Reduced flag is set (from the FADT), we must
+ * use the extended sleep registers (FADT). Note: As per the ACPI
+ * specification, these extended registers are to be used for HW-reduced
+ * platforms only. They are not general-purpose replacements for the
+ * legacy PM register sleep support.
+ */
+ if (AcpiGbl_ReducedHardware)
+ {
+ Status = SleepFunctions->ExtendedFunction (SleepState);
+ }
+ else
+ {
+ /* Legacy sleep */
+
+ Status = SleepFunctions->LegacyFunction (SleepState);
+ }
+
+ return (Status);
+
+#else
+ /*
+ * For the case where reduced-hardware-only code is being generated,
+ * we know that only the extended sleep registers are available
+ */
+ Status = SleepFunctions->ExtendedFunction (SleepState);
+ return (Status);
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnterSleepStatePrep
+ *
+ * PARAMETERS: SleepState - Which sleep state to enter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Prepare to enter a system sleep state.
+ * This function must execute with interrupts enabled.
+ * We break sleeping into 2 stages so that OSPM can handle
+ * various OS-specific tasks between the two steps.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnterSleepStatePrep (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+ ACPI_OBJECT_LIST ArgList;
+ ACPI_OBJECT Arg;
+ UINT32 SstValue;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep);
+
+
+ Status = AcpiGetSleepTypeData (SleepState,
+ &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Execute the _PTS method (Prepare To Sleep) */
+
+ ArgList.Count = 1;
+ ArgList.Pointer = &Arg;
+ Arg.Type = ACPI_TYPE_INTEGER;
+ Arg.Integer.Value = SleepState;
+
+ Status = AcpiEvaluateObject (NULL, METHOD_PATHNAME__PTS, &ArgList, NULL);
+ if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Setup the argument to the _SST method (System STatus) */
+
+ switch (SleepState)
+ {
+ case ACPI_STATE_S0:
+
+ SstValue = ACPI_SST_WORKING;
+ break;
+
+ case ACPI_STATE_S1:
+ case ACPI_STATE_S2:
+ case ACPI_STATE_S3:
+
+ SstValue = ACPI_SST_SLEEPING;
+ break;
+
+ case ACPI_STATE_S4:
+
+ SstValue = ACPI_SST_SLEEP_CONTEXT;
+ break;
+
+ default:
+
+ SstValue = ACPI_SST_INDICATOR_OFF; /* Default is off */
+ break;
+ }
+
+ /*
+ * Set the system indicators to show the desired sleep state.
+ * _SST is an optional method (return no error if not found)
+ */
+ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, SstValue);
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnterSleepState
+ *
+ * PARAMETERS: SleepState - Which sleep state to enter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter a system sleep state
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnterSleepState (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnterSleepState);
+
+
+ if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) ||
+ (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))
+ {
+ ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
+ AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));
+ return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ }
+
+ Status = AcpiHwSleepDispatch (SleepState, ACPI_SLEEP_FUNCTION_ID);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnterSleepState)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLeaveSleepStatePrep
+ *
+ * PARAMETERS: SleepState - Which sleep state we are exiting
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
+ * sleep. Called with interrupts DISABLED.
+ * We break wake/resume into 2 stages so that OSPM can handle
+ * various OS-specific tasks between the two steps.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLeaveSleepStatePrep (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLeaveSleepStatePrep);
+
+
+ Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_PREP_FUNCTION_ID);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLeaveSleepStatePrep)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLeaveSleepState
+ *
+ * PARAMETERS: SleepState - Which sleep state we are exiting
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
+ * Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLeaveSleepState (
+ UINT8 SleepState)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLeaveSleepState);
+
+
+ Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_FUNCTION_ID);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsaccess.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsaccess.c
new file mode 100644
index 0000000000..46a64f5c25
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsaccess.c
@@ -0,0 +1,704 @@
+/*******************************************************************************
+ *
+ * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsaccess")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsRootInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate and initialize the default root named objects
+ *
+ * MUTEX: Locks namespace for entire execution
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsRootInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+ const ACPI_PREDEFINED_NAMES *InitVal = NULL;
+ ACPI_NAMESPACE_NODE *NewNode;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STRING Val = NULL;
+
+
+ ACPI_FUNCTION_TRACE (NsRootInitialize);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * The global root ptr is initially NULL, so a non-NULL value indicates
+ * that AcpiNsRootInitialize() has already been called; just return.
+ */
+ if (AcpiGbl_RootNode)
+ {
+ Status = AE_OK;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Tell the rest of the subsystem that the root is initialized
+ * (This is OK because the namespace is locked)
+ */
+ AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
+
+ /* Enter the pre-defined names in the name table */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Entering predefined entries into namespace\n"));
+
+ for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
+ {
+ /* _OSI is optional for now, will be permanent later */
+
+ if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
+ {
+ continue;
+ }
+
+ Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
+ ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
+ NULL, &NewNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not create predefined name %s",
+ InitVal->Name));
+ continue;
+ }
+
+ /*
+ * Name entered successfully. If entry in PreDefinedNames[] specifies
+ * an initial value, create the initial value.
+ */
+ if (InitVal->Val)
+ {
+ Status = AcpiOsPredefinedOverride (InitVal, &Val);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not override predefined %s",
+ InitVal->Name));
+ }
+
+ if (!Val)
+ {
+ Val = InitVal->Val;
+ }
+
+ /*
+ * Entry requests an initial value, allocate a
+ * descriptor for it.
+ */
+ ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Convert value string from table entry to
+ * internal representation. Only types actually
+ * used for initial values are implemented here.
+ */
+ switch (InitVal->Type)
+ {
+ case ACPI_TYPE_METHOD:
+
+ ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val);
+ ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
+
+#if defined (ACPI_ASL_COMPILER)
+
+ /* Save the parameter count for the iASL compiler */
+
+ NewNode->Value = ObjDesc->Method.ParamCount;
+#else
+ /* Mark this as a very SPECIAL method */
+
+ ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY;
+ ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation;
+#endif
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ /* Build an object around the static string */
+
+ ObjDesc->String.Length = (UINT32) strlen (Val);
+ ObjDesc->String.Pointer = Val;
+ ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
+ break;
+
+ case ACPI_TYPE_MUTEX:
+
+ ObjDesc->Mutex.Node = NewNode;
+ ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1);
+
+ /* Create a mutex */
+
+ Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ goto UnlockAndExit;
+ }
+
+ /* Special case for ACPI Global Lock */
+
+ if (strcmp (InitVal->Name, "_GL_") == 0)
+ {
+ AcpiGbl_GlobalLockMutex = ObjDesc;
+
+ /* Create additional counting semaphore for global lock */
+
+ Status = AcpiOsCreateSemaphore (
+ 1, 0, &AcpiGbl_GlobalLockSemaphore);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ goto UnlockAndExit;
+ }
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
+ InitVal->Type));
+ AcpiUtRemoveReference (ObjDesc);
+ ObjDesc = NULL;
+ continue;
+ }
+
+ /* Store pointer to value descriptor in the Node */
+
+ Status = AcpiNsAttachObject (NewNode, ObjDesc,
+ ObjDesc->Common.Type);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ }
+ }
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ /* Save a handle to "_GPE", it is always present */
+
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
+ &AcpiGbl_FadtGpeDevice);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsLookup
+ *
+ * PARAMETERS: ScopeInfo - Current scope info block
+ * Pathname - Search pathname, in internal format
+ * (as represented in the AML stream)
+ * Type - Type associated with name
+ * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
+ * Flags - Flags describing the search restrictions
+ * WalkState - Current state of the walk
+ * ReturnNode - Where the Node is placed (if found
+ * or created successfully)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Find or enter the passed name in the name space.
+ * Log an error if name not found in Exec mode.
+ *
+ * MUTEX: Assumes namespace is locked.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsLookup (
+ ACPI_GENERIC_STATE *ScopeInfo,
+ char *Pathname,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_INTERPRETER_MODE InterpreterMode,
+ UINT32 Flags,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_STATUS Status;
+ char *Path = Pathname;
+ ACPI_NAMESPACE_NODE *PrefixNode;
+ ACPI_NAMESPACE_NODE *CurrentNode = NULL;
+ ACPI_NAMESPACE_NODE *ThisNode = NULL;
+ UINT32 NumSegments;
+ UINT32 NumCarats;
+ ACPI_NAME SimpleName;
+ ACPI_OBJECT_TYPE TypeToCheckFor;
+ ACPI_OBJECT_TYPE ThisSearchType;
+ UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT;
+ UINT32 LocalFlags;
+
+
+ ACPI_FUNCTION_TRACE (NsLookup);
+
+
+ if (!ReturnNode)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ LocalFlags = Flags &
+ ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
+ ACPI_NS_SEARCH_PARENT);
+ *ReturnNode = ACPI_ENTRY_NOT_FOUND;
+ AcpiGbl_NsLookupCount++;
+
+ if (!AcpiGbl_RootNode)
+ {
+ return_ACPI_STATUS (AE_NO_NAMESPACE);
+ }
+
+ /* Get the prefix scope. A null scope means use the root scope */
+
+ if ((!ScopeInfo) ||
+ (!ScopeInfo->Scope.Node))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Null scope prefix, using root node (%p)\n",
+ AcpiGbl_RootNode));
+
+ PrefixNode = AcpiGbl_RootNode;
+ }
+ else
+ {
+ PrefixNode = ScopeInfo->Scope.Node;
+ if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]",
+ PrefixNode, AcpiUtGetDescriptorName (PrefixNode)));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE))
+ {
+ /*
+ * This node might not be a actual "scope" node (such as a
+ * Device/Method, etc.) It could be a Package or other object
+ * node. Backup up the tree to find the containing scope node.
+ */
+ while (!AcpiNsOpensScope (PrefixNode->Type) &&
+ PrefixNode->Type != ACPI_TYPE_ANY)
+ {
+ PrefixNode = PrefixNode->Parent;
+ }
+ }
+ }
+
+ /* Save type. TBD: may be no longer necessary */
+
+ TypeToCheckFor = Type;
+
+ /*
+ * Begin examination of the actual pathname
+ */
+ if (!Pathname)
+ {
+ /* A Null NamePath is allowed and refers to the root */
+
+ NumSegments = 0;
+ ThisNode = AcpiGbl_RootNode;
+ Path = "";
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Null Pathname (Zero segments), Flags=%X\n", Flags));
+ }
+ else
+ {
+ /*
+ * Name pointer is valid (and must be in internal name format)
+ *
+ * Check for scope prefixes:
+ *
+ * As represented in the AML stream, a namepath consists of an
+ * optional scope prefix followed by a name segment part.
+ *
+ * If present, the scope prefix is either a Root Prefix (in
+ * which case the name is fully qualified), or one or more
+ * Parent Prefixes (in which case the name's scope is relative
+ * to the current scope).
+ */
+ if (*Path == (UINT8) AML_ROOT_PREFIX)
+ {
+ /* Pathname is fully qualified, start from the root */
+
+ ThisNode = AcpiGbl_RootNode;
+ SearchParentFlag = ACPI_NS_NO_UPSEARCH;
+
+ /* Point to name segment part */
+
+ Path++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Path is absolute from root [%p]\n", ThisNode));
+ }
+ else
+ {
+ /* Pathname is relative to current scope, start there */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Searching relative to prefix scope [%4.4s] (%p)\n",
+ AcpiUtGetNodeName (PrefixNode), PrefixNode));
+
+ /*
+ * Handle multiple Parent Prefixes (carat) by just getting
+ * the parent node for each prefix instance.
+ */
+ ThisNode = PrefixNode;
+ NumCarats = 0;
+ while (*Path == (UINT8) AML_PARENT_PREFIX)
+ {
+ /* Name is fully qualified, no search rules apply */
+
+ SearchParentFlag = ACPI_NS_NO_UPSEARCH;
+
+ /*
+ * Point past this prefix to the name segment
+ * part or the next Parent Prefix
+ */
+ Path++;
+
+ /* Backup to the parent node */
+
+ NumCarats++;
+ ThisNode = ThisNode->Parent;
+ if (!ThisNode)
+ {
+ /* Current scope has no parent scope */
+
+ ACPI_ERROR ((AE_INFO,
+ "%s: Path has too many parent prefixes (^) "
+ "- reached beyond root node", Pathname));
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+ }
+
+ if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Search scope is [%4.4s], path has %u carat(s)\n",
+ AcpiUtGetNodeName (ThisNode), NumCarats));
+ }
+ }
+
+ /*
+ * Determine the number of ACPI name segments in this pathname.
+ *
+ * The segment part consists of either:
+ * - A Null name segment (0)
+ * - A DualNamePrefix followed by two 4-byte name segments
+ * - A MultiNamePrefix followed by a byte indicating the
+ * number of segments and the segments themselves.
+ * - A single 4-byte name segment
+ *
+ * Examine the name prefix opcode, if any, to determine the number of
+ * segments.
+ */
+ switch (*Path)
+ {
+ case 0:
+ /*
+ * Null name after a root or parent prefixes. We already
+ * have the correct target node and there are no name segments.
+ */
+ NumSegments = 0;
+ Type = ThisNode->Type;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Prefix-only Pathname (Zero name segments), Flags=%X\n",
+ Flags));
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+
+ /* More than one NameSeg, search rules do not apply */
+
+ SearchParentFlag = ACPI_NS_NO_UPSEARCH;
+
+ /* Two segments, point to first name segment */
+
+ NumSegments = 2;
+ Path++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Dual Pathname (2 segments, Flags=%X)\n", Flags));
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ /* More than one NameSeg, search rules do not apply */
+
+ SearchParentFlag = ACPI_NS_NO_UPSEARCH;
+
+ /* Extract segment count, point to first name segment */
+
+ Path++;
+ NumSegments = (UINT32) (UINT8) *Path;
+ Path++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Multi Pathname (%u Segments, Flags=%X)\n",
+ NumSegments, Flags));
+ break;
+
+ default:
+ /*
+ * Not a Null name, no Dual or Multi prefix, hence there is
+ * only one name segment and Pathname is already pointing to it.
+ */
+ NumSegments = 1;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Simple Pathname (1 segment, Flags=%X)\n", Flags));
+ break;
+ }
+
+ ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
+ }
+
+
+ /*
+ * Search namespace for each segment of the name. Loop through and
+ * verify (or add to the namespace) each name segment.
+ *
+ * The object type is significant only at the last name
+ * segment. (We don't care about the types along the path, only
+ * the type of the final target object.)
+ */
+ ThisSearchType = ACPI_TYPE_ANY;
+ CurrentNode = ThisNode;
+ while (NumSegments && CurrentNode)
+ {
+ NumSegments--;
+ if (!NumSegments)
+ {
+ /* This is the last segment, enable typechecking */
+
+ ThisSearchType = Type;
+
+ /*
+ * Only allow automatic parent search (search rules) if the caller
+ * requested it AND we have a single, non-fully-qualified NameSeg
+ */
+ if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
+ (Flags & ACPI_NS_SEARCH_PARENT))
+ {
+ LocalFlags |= ACPI_NS_SEARCH_PARENT;
+ }
+
+ /* Set error flag according to caller */
+
+ if (Flags & ACPI_NS_ERROR_IF_FOUND)
+ {
+ LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
+ }
+
+ /* Set override flag according to caller */
+
+ if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
+ {
+ LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND;
+ }
+ }
+
+ /* Extract one ACPI name from the front of the pathname */
+
+ ACPI_MOVE_32_TO_32 (&SimpleName, Path);
+
+ /* Try to find the single (4 character) ACPI name */
+
+ Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
+ InterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ /* Name not found in ACPI namespace */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Name [%4.4s] not found in scope [%4.4s] %p\n",
+ (char *) &SimpleName, (char *) &CurrentNode->Name,
+ CurrentNode));
+ }
+
+ *ReturnNode = ThisNode;
+ return_ACPI_STATUS (Status);
+ }
+
+ /* More segments to follow? */
+
+ if (NumSegments > 0)
+ {
+ /*
+ * If we have an alias to an object that opens a scope (such as a
+ * device or processor), we need to dereference the alias here so
+ * that we can access any children of the original node (via the
+ * remaining segments).
+ */
+ if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS)
+ {
+ if (!ThisNode->Object)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *)
+ ThisNode->Object)->Type))
+ {
+ ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
+ }
+ }
+ }
+
+ /* Special handling for the last segment (NumSegments == 0) */
+
+ else
+ {
+ /*
+ * Sanity typecheck of the target object:
+ *
+ * If 1) This is the last segment (NumSegments == 0)
+ * 2) And we are looking for a specific type
+ * (Not checking for TYPE_ANY)
+ * 3) Which is not an alias
+ * 4) Which is not a local type (TYPE_SCOPE)
+ * 5) And the type of target object is known (not TYPE_ANY)
+ * 6) And target object does not match what we are looking for
+ *
+ * Then we have a type mismatch. Just warn and ignore it.
+ */
+ if ((TypeToCheckFor != ACPI_TYPE_ANY) &&
+ (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) &&
+ (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) &&
+ (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) &&
+ (ThisNode->Type != ACPI_TYPE_ANY) &&
+ (ThisNode->Type != TypeToCheckFor))
+ {
+ /* Complain about a type mismatch */
+
+ ACPI_WARNING ((AE_INFO,
+ "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
+ ACPI_CAST_PTR (char, &SimpleName),
+ AcpiUtGetTypeName (ThisNode->Type),
+ AcpiUtGetTypeName (TypeToCheckFor)));
+ }
+
+ /*
+ * If this is the last name segment and we are not looking for a
+ * specific type, but the type of found object is known, use that
+ * type to (later) see if it opens a scope.
+ */
+ if (Type == ACPI_TYPE_ANY)
+ {
+ Type = ThisNode->Type;
+ }
+ }
+
+ /* Point to next name segment and make this node current */
+
+ Path += ACPI_NAME_SIZE;
+ CurrentNode = ThisNode;
+ }
+
+ /* Always check if we need to open a new scope */
+
+ if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
+ {
+ /*
+ * If entry is a type which opens a scope, push the new scope on the
+ * scope stack.
+ */
+ if (AcpiNsOpensScope (Type))
+ {
+ Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
+ *ReturnNode = ThisNode;
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsalloc.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsalloc.c
new file mode 100644
index 0000000000..2a1e09e20c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsalloc.c
@@ -0,0 +1,594 @@
+/*******************************************************************************
+ *
+ * Module Name: nsalloc - Namespace allocation and deletion utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsalloc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCreateNode
+ *
+ * PARAMETERS: Name - Name of the new node (4 char ACPI name)
+ *
+ * RETURN: New namespace node (Null on failure)
+ *
+ * DESCRIPTION: Create a namespace node
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiNsCreateNode (
+ UINT32 Name)
+{
+ ACPI_NAMESPACE_NODE *Node;
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ UINT32 Temp;
+#endif
+
+
+ ACPI_FUNCTION_TRACE (NsCreateNode);
+
+
+ Node = AcpiOsAcquireObject (AcpiGbl_NamespaceCache);
+ if (!Node)
+ {
+ return_PTR (NULL);
+ }
+
+ ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalAllocated++);
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ Temp = AcpiGbl_NsNodeList->TotalAllocated -
+ AcpiGbl_NsNodeList->TotalFreed;
+ if (Temp > AcpiGbl_NsNodeList->MaxOccupied)
+ {
+ AcpiGbl_NsNodeList->MaxOccupied = Temp;
+ }
+#endif
+
+ Node->Name.Integer = Name;
+ ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED);
+ return_PTR (Node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDeleteNode
+ *
+ * PARAMETERS: Node - Node to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete a namespace node. All node deletions must come through
+ * here. Detaches any attached objects, including any attached
+ * data. If a handler is associated with attached data, it is
+ * invoked before the node is deleted.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDeleteNode (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *NextDesc;
+
+
+ ACPI_FUNCTION_NAME (NsDeleteNode);
+
+
+ /* Detach an object if there is one */
+
+ AcpiNsDetachObject (Node);
+
+ /*
+ * Delete an attached data object list if present (objects that were
+ * attached via AcpiAttachData). Note: After any normal object is
+ * detached above, the only possible remaining object(s) are data
+ * objects, in a linked list.
+ */
+ ObjDesc = Node->Object;
+ while (ObjDesc &&
+ (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ /* Invoke the attached data deletion handler if present */
+
+ if (ObjDesc->Data.Handler)
+ {
+ ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer);
+ }
+
+ NextDesc = ObjDesc->Common.NextObject;
+ AcpiUtRemoveReference (ObjDesc);
+ ObjDesc = NextDesc;
+ }
+
+ /* Special case for the statically allocated root node */
+
+ if (Node == AcpiGbl_RootNode)
+ {
+ return;
+ }
+
+ /* Now we can delete the node */
+
+ (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
+
+ ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
+ Node, AcpiGbl_CurrentNodeCount));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsRemoveNode
+ *
+ * PARAMETERS: Node - Node to be removed/deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove (unlink) and delete a namespace node
+ *
+ ******************************************************************************/
+
+void
+AcpiNsRemoveNode (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_NAMESPACE_NODE *PrevNode;
+ ACPI_NAMESPACE_NODE *NextNode;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node);
+
+
+ ParentNode = Node->Parent;
+
+ PrevNode = NULL;
+ NextNode = ParentNode->Child;
+
+ /* Find the node that is the previous peer in the parent's child list */
+
+ while (NextNode != Node)
+ {
+ PrevNode = NextNode;
+ NextNode = NextNode->Peer;
+ }
+
+ if (PrevNode)
+ {
+ /* Node is not first child, unlink it */
+
+ PrevNode->Peer = Node->Peer;
+ }
+ else
+ {
+ /*
+ * Node is first child (has no previous peer).
+ * Link peer list to parent
+ */
+ ParentNode->Child = Node->Peer;
+ }
+
+ /* Delete the node and any attached objects */
+
+ AcpiNsDeleteNode (Node);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInstallNode
+ *
+ * PARAMETERS: WalkState - Current state of the walk
+ * ParentNode - The parent of the new Node
+ * Node - The new Node to install
+ * Type - ACPI object type of the new Node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a new namespace node and install it amongst
+ * its peers.
+ *
+ * Note: Current namespace lookup is linear search. This appears
+ * to be sufficient as namespace searches consume only a small
+ * fraction of the execution time of the ACPI subsystem.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsInstallNode (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *ParentNode, /* Parent */
+ ACPI_NAMESPACE_NODE *Node, /* New Child*/
+ ACPI_OBJECT_TYPE Type)
+{
+ ACPI_OWNER_ID OwnerId = 0;
+ ACPI_NAMESPACE_NODE *ChildNode;
+
+
+ ACPI_FUNCTION_TRACE (NsInstallNode);
+
+
+ if (WalkState)
+ {
+ /*
+ * Get the owner ID from the Walk state. The owner ID is used to
+ * track table deletion and deletion of objects created by methods.
+ */
+ OwnerId = WalkState->OwnerId;
+
+ if ((WalkState->MethodDesc) &&
+ (ParentNode != WalkState->MethodNode))
+ {
+ /*
+ * A method is creating a new node that is not a child of the
+ * method (it is non-local). Mark the executing method as having
+ * modified the namespace. This is used for cleanup when the
+ * method exits.
+ */
+ WalkState->MethodDesc->Method.InfoFlags |= ACPI_METHOD_MODIFIED_NAMESPACE;
+ }
+ }
+
+ /* Link the new entry into the parent and existing children */
+
+ Node->Peer = NULL;
+ Node->Parent = ParentNode;
+ ChildNode = ParentNode->Child;
+
+ if (!ChildNode)
+ {
+ ParentNode->Child = Node;
+ }
+ else
+ {
+ /* Add node to the end of the peer list */
+
+ while (ChildNode->Peer)
+ {
+ ChildNode = ChildNode->Peer;
+ }
+
+ ChildNode->Peer = Node;
+ }
+
+ /* Init the new entry */
+
+ Node->OwnerId = OwnerId;
+ Node->Type = (UINT8) Type;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId,
+ AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type),
+ ParentNode));
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDeleteChildren
+ *
+ * PARAMETERS: ParentNode - Delete this objects children
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete all children of the parent object. In other words,
+ * deletes a "scope".
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDeleteChildren (
+ ACPI_NAMESPACE_NODE *ParentNode)
+{
+ ACPI_NAMESPACE_NODE *NextNode;
+ ACPI_NAMESPACE_NODE *NodeToDelete;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode);
+
+
+ if (!ParentNode)
+ {
+ return_VOID;
+ }
+
+ /* Deallocate all children at this level */
+
+ NextNode = ParentNode->Child;
+ while (NextNode)
+ {
+ /* Grandchildren should have all been deleted already */
+
+ if (NextNode->Child)
+ {
+ ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p",
+ ParentNode, NextNode));
+ }
+
+ /*
+ * Delete this child node and move on to the next child in the list.
+ * No need to unlink the node since we are deleting the entire branch.
+ */
+ NodeToDelete = NextNode;
+ NextNode = NextNode->Peer;
+ AcpiNsDeleteNode (NodeToDelete);
+ };
+
+ /* Clear the parent's child pointer */
+
+ ParentNode->Child = NULL;
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDeleteNamespaceSubtree
+ *
+ * PARAMETERS: ParentNode - Root of the subtree to be deleted
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete a subtree of the namespace. This includes all objects
+ * stored within the subtree.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDeleteNamespaceSubtree (
+ ACPI_NAMESPACE_NODE *ParentNode)
+{
+ ACPI_NAMESPACE_NODE *ChildNode = NULL;
+ UINT32 Level = 1;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree);
+
+
+ if (!ParentNode)
+ {
+ return_VOID;
+ }
+
+ /* Lock namespace for possible update */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /*
+ * Traverse the tree of objects until we bubble back up
+ * to where we started.
+ */
+ while (Level > 0)
+ {
+ /* Get the next node in this scope (NULL if none) */
+
+ ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
+ if (ChildNode)
+ {
+ /* Found a child node - detach any attached object */
+
+ AcpiNsDetachObject (ChildNode);
+
+ /* Check if this node has any children */
+
+ if (ChildNode->Child)
+ {
+ /*
+ * There is at least one child of this node,
+ * visit the node
+ */
+ Level++;
+ ParentNode = ChildNode;
+ ChildNode = NULL;
+ }
+ }
+ else
+ {
+ /*
+ * No more children of this parent node.
+ * Move up to the grandparent.
+ */
+ Level--;
+
+ /*
+ * Now delete all of the children of this parent
+ * all at the same time.
+ */
+ AcpiNsDeleteChildren (ParentNode);
+
+ /* New "last child" is this parent node */
+
+ ChildNode = ParentNode;
+
+ /* Move up the tree to the grandparent */
+
+ ParentNode = ParentNode->Parent;
+ }
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDeleteNamespaceByOwner
+ *
+ * PARAMETERS: OwnerId - All nodes with this owner will be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete entries within the namespace that are owned by a
+ * specific ID. Used to delete entire ACPI tables. All
+ * reference counts are updated.
+ *
+ * MUTEX: Locks namespace during deletion walk.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDeleteNamespaceByOwner (
+ ACPI_OWNER_ID OwnerId)
+{
+ ACPI_NAMESPACE_NODE *ChildNode;
+ ACPI_NAMESPACE_NODE *DeletionNode;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ UINT32 Level;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId);
+
+
+ if (OwnerId == 0)
+ {
+ return_VOID;
+ }
+
+ /* Lock namespace for possible update */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ DeletionNode = NULL;
+ ParentNode = AcpiGbl_RootNode;
+ ChildNode = NULL;
+ Level = 1;
+
+ /*
+ * Traverse the tree of nodes until we bubble back up
+ * to where we started.
+ */
+ while (Level > 0)
+ {
+ /*
+ * Get the next child of this parent node. When ChildNode is NULL,
+ * the first child of the parent is returned
+ */
+ ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
+
+ if (DeletionNode)
+ {
+ AcpiNsDeleteChildren (DeletionNode);
+ AcpiNsRemoveNode (DeletionNode);
+ DeletionNode = NULL;
+ }
+
+ if (ChildNode)
+ {
+ if (ChildNode->OwnerId == OwnerId)
+ {
+ /* Found a matching child node - detach any attached object */
+
+ AcpiNsDetachObject (ChildNode);
+ }
+
+ /* Check if this node has any children */
+
+ if (ChildNode->Child)
+ {
+ /*
+ * There is at least one child of this node,
+ * visit the node
+ */
+ Level++;
+ ParentNode = ChildNode;
+ ChildNode = NULL;
+ }
+ else if (ChildNode->OwnerId == OwnerId)
+ {
+ DeletionNode = ChildNode;
+ }
+ }
+ else
+ {
+ /*
+ * No more children of this parent node.
+ * Move up to the grandparent.
+ */
+ Level--;
+ if (Level != 0)
+ {
+ if (ParentNode->OwnerId == OwnerId)
+ {
+ DeletionNode = ParentNode;
+ }
+ }
+
+ /* New "last child" is this parent node */
+
+ ChildNode = ParentNode;
+
+ /* Move up the tree to the grandparent */
+
+ ParentNode = ParentNode->Parent;
+ }
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsarguments.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsarguments.c
new file mode 100644
index 0000000000..5d41bb012d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsarguments.c
@@ -0,0 +1,303 @@
+/******************************************************************************
+ *
+ * Module Name: nsarguments - Validation of args for ACPI predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsarguments")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckArgumentTypes
+ *
+ * PARAMETERS: Info - Method execution information block
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check the incoming argument count and all argument types
+ * against the argument type list for a predefined name.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsCheckArgumentTypes (
+ ACPI_EVALUATE_INFO *Info)
+{
+ UINT16 ArgTypeList;
+ UINT8 ArgCount;
+ UINT8 ArgType;
+ UINT8 UserArgType;
+ UINT32 i;
+
+
+ /* If not a predefined name, cannot typecheck args */
+
+ if (!Info->Predefined)
+ {
+ return;
+ }
+
+ ArgTypeList = Info->Predefined->Info.ArgumentList;
+ ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
+
+ /* Typecheck all arguments */
+
+ for (i = 0; ((i < ArgCount) && (i < Info->ParamCount)); i++)
+ {
+ ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
+ UserArgType = Info->Parameters[i]->Common.Type;
+
+ if (UserArgType != ArgType)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS,
+ "Argument #%u type mismatch - "
+ "Found [%s], ACPI requires [%s]", (i + 1),
+ AcpiUtGetTypeName (UserArgType),
+ AcpiUtGetTypeName (ArgType)));
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckAcpiCompliance
+ *
+ * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * Node - Namespace node for the method/object
+ * Predefined - Pointer to entry in predefined name table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
+ * predefined name is what is expected (matches what is defined in
+ * the ACPI specification for this predefined name.)
+ *
+ ******************************************************************************/
+
+void
+AcpiNsCheckAcpiCompliance (
+ char *Pathname,
+ ACPI_NAMESPACE_NODE *Node,
+ const ACPI_PREDEFINED_INFO *Predefined)
+{
+ UINT32 AmlParamCount;
+ UINT32 RequiredParamCount;
+
+
+ if (!Predefined)
+ {
+ return;
+ }
+
+ /* Get the ACPI-required arg count from the predefined info table */
+
+ RequiredParamCount = METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList);
+
+ /*
+ * If this object is not a control method, we can check if the ACPI
+ * spec requires that it be a method.
+ */
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ if (RequiredParamCount > 0)
+ {
+ /* Object requires args, must be implemented as a method */
+
+ ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Object (%s) must be a control method with %u arguments",
+ AcpiUtGetTypeName (Node->Type), RequiredParamCount));
+ }
+ else if (!RequiredParamCount && !Predefined->Info.ExpectedBtypes)
+ {
+ /* Object requires no args and no return value, must be a method */
+
+ ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Object (%s) must be a control method "
+ "with no arguments and no return value",
+ AcpiUtGetTypeName (Node->Type)));
+ }
+
+ return;
+ }
+
+ /*
+ * This is a control method.
+ * Check that the ASL/AML-defined parameter count for this method
+ * matches the ACPI-required parameter count
+ *
+ * Some methods are allowed to have a "minimum" number of args (_SCP)
+ * because their definition in ACPI has changed over time.
+ *
+ * Note: These are BIOS errors in the declaration of the object
+ */
+ AmlParamCount = Node->Object->Method.ParamCount;
+
+ if (AmlParamCount < RequiredParamCount)
+ {
+ ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Insufficient arguments - "
+ "ASL declared %u, ACPI requires %u",
+ AmlParamCount, RequiredParamCount));
+ }
+ else if ((AmlParamCount > RequiredParamCount) &&
+ !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM))
+ {
+ ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Excess arguments - "
+ "ASL declared %u, ACPI requires %u",
+ AmlParamCount, RequiredParamCount));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckArgumentCount
+ *
+ * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * Node - Namespace node for the method/object
+ * UserParamCount - Number of args passed in by the caller
+ * Predefined - Pointer to entry in predefined name table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check that incoming argument count matches the declared
+ * parameter count (in the ASL/AML) for an object.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsCheckArgumentCount (
+ char *Pathname,
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 UserParamCount,
+ const ACPI_PREDEFINED_INFO *Predefined)
+{
+ UINT32 AmlParamCount;
+ UINT32 RequiredParamCount;
+
+
+ if (!Predefined)
+ {
+ /*
+ * Not a predefined name. Check the incoming user argument count
+ * against the count that is specified in the method/object.
+ */
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ if (UserParamCount)
+ {
+ ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "%u arguments were passed to a non-method ACPI object (%s)",
+ UserParamCount, AcpiUtGetTypeName (Node->Type)));
+ }
+
+ return;
+ }
+
+ /*
+ * This is a control method. Check the parameter count.
+ * We can only check the incoming argument count against the
+ * argument count declared for the method in the ASL/AML.
+ *
+ * Emit a message if too few or too many arguments have been passed
+ * by the caller.
+ *
+ * Note: Too many arguments will not cause the method to
+ * fail. However, the method will fail if there are too few
+ * arguments and the method attempts to use one of the missing ones.
+ */
+ AmlParamCount = Node->Object->Method.ParamCount;
+
+ if (UserParamCount < AmlParamCount)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Insufficient arguments - "
+ "Caller passed %u, method requires %u",
+ UserParamCount, AmlParamCount));
+ }
+ else if (UserParamCount > AmlParamCount)
+ {
+ ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Excess arguments - "
+ "Caller passed %u, method requires %u",
+ UserParamCount, AmlParamCount));
+ }
+
+ return;
+ }
+
+ /*
+ * This is a predefined name. Validate the user-supplied parameter
+ * count against the ACPI specification. We don't validate against
+ * the method itself because what is important here is that the
+ * caller is in conformance with the spec. (The arg count for the
+ * method was checked against the ACPI spec earlier.)
+ *
+ * Some methods are allowed to have a "minimum" number of args (_SCP)
+ * because their definition in ACPI has changed over time.
+ */
+ RequiredParamCount = METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList);
+
+ if (UserParamCount < RequiredParamCount)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Insufficient arguments - "
+ "Caller passed %u, ACPI requires %u",
+ UserParamCount, RequiredParamCount));
+ }
+ else if ((UserParamCount > RequiredParamCount) &&
+ !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM))
+ {
+ ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Excess arguments - "
+ "Caller passed %u, ACPI requires %u",
+ UserParamCount, RequiredParamCount));
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsconvert.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsconvert.c
new file mode 100644
index 0000000000..99883c26d5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsconvert.c
@@ -0,0 +1,482 @@
+/******************************************************************************
+ *
+ * Module Name: nsconvert - Object conversions for objects returned by
+ * predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+#include <contrib/dev/acpica/include/amlresrc.h>
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsconvert")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToInteger
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsConvertToInteger (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_STATUS Status;
+ UINT64 Value = 0;
+ UINT32 i;
+
+
+ switch (OriginalObject->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ /* String-to-Integer conversion */
+
+ Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer,
+ ACPI_ANY_BASE, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
+
+ if (OriginalObject->Buffer.Length > 8)
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Extract each buffer byte to create the integer */
+
+ for (i = 0; i < OriginalObject->Buffer.Length; i++)
+ {
+ Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8));
+ }
+ break;
+
+ default:
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ NewObject = AcpiUtCreateIntegerObject (Value);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToString
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsConvertToString (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_SIZE Length;
+ ACPI_STATUS Status;
+
+
+ switch (OriginalObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ /*
+ * Integer-to-String conversion. Commonly, convert
+ * an integer of value 0 to a NULL string. The last element of
+ * _BIF and _BIX packages occasionally need this fix.
+ */
+ if (OriginalObject->Integer.Value == 0)
+ {
+ /* Allocate a new NULL string object */
+
+ NewObject = AcpiUtCreateStringObject (0);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+ }
+ else
+ {
+ Status = AcpiExConvertToString (OriginalObject, &NewObject,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ /*
+ * Buffer-to-String conversion. Use a ToString
+ * conversion, no transform performed on the buffer data. The best
+ * example of this is the _BIF method, where the string data from
+ * the battery is often (incorrectly) returned as buffer object(s).
+ */
+ Length = 0;
+ while ((Length < OriginalObject->Buffer.Length) &&
+ (OriginalObject->Buffer.Pointer[Length]))
+ {
+ Length++;
+ }
+
+ /* Allocate a new string object */
+
+ NewObject = AcpiUtCreateStringObject (Length);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /*
+ * Copy the raw buffer data with no transform. String is already NULL
+ * terminated at Length+1.
+ */
+ memcpy (NewObject->String.Pointer,
+ OriginalObject->Buffer.Pointer, Length);
+ break;
+
+ default:
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToBuffer
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsConvertToBuffer (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT **Elements;
+ UINT32 *DwordBuffer;
+ UINT32 Count;
+ UINT32 i;
+
+
+ switch (OriginalObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ /*
+ * Integer-to-Buffer conversion.
+ * Convert the Integer to a packed-byte buffer. _MAT and other
+ * objects need this sometimes, if a read has been performed on a
+ * Field object that is less than or equal to the global integer
+ * size (32 or 64 bits).
+ */
+ Status = AcpiExConvertToBuffer (OriginalObject, &NewObject);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ /* String-to-Buffer conversion. Simple data copy */
+
+ NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ memcpy (NewObject->Buffer.Pointer,
+ OriginalObject->String.Pointer, OriginalObject->String.Length);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * This case is often seen for predefined names that must return a
+ * Buffer object with multiple DWORD integers within. For example,
+ * _FDE and _GTM. The Package can be converted to a Buffer.
+ */
+
+ /* All elements of the Package must be integers */
+
+ Elements = OriginalObject->Package.Elements;
+ Count = OriginalObject->Package.Count;
+
+ for (i = 0; i < Count; i++)
+ {
+ if ((!*Elements) ||
+ ((*Elements)->Common.Type != ACPI_TYPE_INTEGER))
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+ Elements++;
+ }
+
+ /* Create the new buffer object to replace the Package */
+
+ NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count));
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Copy the package elements (integers) to the buffer as DWORDs */
+
+ Elements = OriginalObject->Package.Elements;
+ DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer);
+
+ for (i = 0; i < Count; i++)
+ {
+ *DwordBuffer = (UINT32) (*Elements)->Integer.Value;
+ DwordBuffer++;
+ Elements++;
+ }
+ break;
+
+ default:
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToUnicode
+ *
+ * PARAMETERS: OriginalObject - ASCII String Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a String object to a Unicode string Buffer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsConvertToUnicode (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ char *AsciiString;
+ UINT16 *UnicodeBuffer;
+ UINT32 UnicodeLength;
+ UINT32 i;
+
+
+ if (!OriginalObject)
+ {
+ return (AE_OK);
+ }
+
+ /* If a Buffer was returned, it must be at least two bytes long */
+
+ if (OriginalObject->Common.Type == ACPI_TYPE_BUFFER)
+ {
+ if (OriginalObject->Buffer.Length < 2)
+ {
+ return (AE_AML_OPERAND_VALUE);
+ }
+
+ *ReturnObject = NULL;
+ return (AE_OK);
+ }
+
+ /*
+ * The original object is an ASCII string. Convert this string to
+ * a unicode buffer.
+ */
+ AsciiString = OriginalObject->String.Pointer;
+ UnicodeLength = (OriginalObject->String.Length * 2) + 2;
+
+ /* Create a new buffer object for the Unicode data */
+
+ NewObject = AcpiUtCreateBufferObject (UnicodeLength);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ UnicodeBuffer = ACPI_CAST_PTR (UINT16, NewObject->Buffer.Pointer);
+
+ /* Convert ASCII to Unicode */
+
+ for (i = 0; i < OriginalObject->String.Length; i++)
+ {
+ UnicodeBuffer[i] = (UINT16) AsciiString[i];
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToResource
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful
+ *
+ * DESCRIPTION: Attempt to convert a Integer object to a ResourceTemplate
+ * Buffer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsConvertToResource (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ UINT8 *Buffer;
+
+
+ /*
+ * We can fix the following cases for an expected resource template:
+ * 1. No return value (interpreter slack mode is disabled)
+ * 2. A "Return (Zero)" statement
+ * 3. A "Return empty buffer" statement
+ *
+ * We will return a buffer containing a single EndTag
+ * resource descriptor.
+ */
+ if (OriginalObject)
+ {
+ switch (OriginalObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* We can only repair an Integer==0 */
+
+ if (OriginalObject->Integer.Value)
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ if (OriginalObject->Buffer.Length)
+ {
+ /* Additional checks can be added in the future */
+
+ *ReturnObject = NULL;
+ return (AE_OK);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+ default:
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+ }
+
+ /* Create the new buffer object for the resource descriptor */
+
+ NewObject = AcpiUtCreateBufferObject (2);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Buffer = ACPI_CAST_PTR (UINT8, NewObject->Buffer.Pointer);
+
+ /* Initialize the Buffer with a single EndTag descriptor */
+
+ Buffer[0] = (ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE);
+ Buffer[1] = 0x00;
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdump.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdump.c
new file mode 100644
index 0000000000..f3f3fed37a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdump.c
@@ -0,0 +1,937 @@
+/******************************************************************************
+ *
+ * Module Name: nsdump - table dumping routines for debug
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acoutput.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsdump")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiNsDumpRootDevices (
+ void);
+
+static ACPI_STATUS
+AcpiNsDumpOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+#endif
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+static ACPI_STATUS
+AcpiNsDumpOneObjectPath (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiNsGetMaxDepth (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsPrintPathname
+ *
+ * PARAMETERS: NumSegments - Number of ACPI name segments
+ * Pathname - The compressed (internal) path
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ *
+ ******************************************************************************/
+
+void
+AcpiNsPrintPathname (
+ UINT32 NumSegments,
+ char *Pathname)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsPrintPathname);
+
+
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_NAMES, ACPI_NAMESPACE))
+ {
+ return;
+ }
+
+ /* Print the entire name */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
+
+ while (NumSegments)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ isprint ((int) Pathname[i]) ?
+ AcpiOsPrintf ("%c", Pathname[i]) :
+ AcpiOsPrintf ("?");
+ }
+
+ Pathname += ACPI_NAME_SIZE;
+ NumSegments--;
+ if (NumSegments)
+ {
+ AcpiOsPrintf (".");
+ }
+ }
+
+ AcpiOsPrintf ("]\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpPathname
+ *
+ * PARAMETERS: Handle - Object
+ * Msg - Prefix message
+ * Level - Desired debug level
+ * Component - Caller's component ID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ * Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpPathname (
+ ACPI_HANDLE Handle,
+ char *Msg,
+ UINT32 Level,
+ UINT32 Component)
+{
+
+ ACPI_FUNCTION_TRACE (NsDumpPathname);
+
+
+ /* Do this only if the requested debug level and component are enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (Level, Component))
+ {
+ return_VOID;
+ }
+
+ /* Convert handle to a full pathname and print it (with supplied message) */
+
+ AcpiNsPrintNodePathname (Handle, Msg);
+ AcpiOsPrintf ("\n");
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpOneObject
+ *
+ * PARAMETERS: ObjHandle - Node to be dumped
+ * Level - Nesting level of the handle
+ * Context - Passed into WalkNamespace
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dump a single Node
+ * This procedure is a UserFunction called by AcpiNsWalkNamespace.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsDumpOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
+ ACPI_NAMESPACE_NODE *ThisNode;
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_OBJECT_TYPE ObjType;
+ ACPI_OBJECT_TYPE Type;
+ UINT32 BytesToDump;
+ UINT32 DbgLevel;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsDumpOneObject);
+
+
+ /* Is output enabled? */
+
+ if (!(AcpiDbgLevel & Info->DebugLevel))
+ {
+ return (AE_OK);
+ }
+
+ if (!ObjHandle)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
+ return (AE_OK);
+ }
+
+ ThisNode = AcpiNsValidateHandle (ObjHandle);
+ if (!ThisNode)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n",
+ ObjHandle));
+ return (AE_OK);
+ }
+
+ Type = ThisNode->Type;
+
+ /* Check if the owner matches */
+
+ if ((Info->OwnerId != ACPI_OWNER_ID_MAX) &&
+ (Info->OwnerId != ThisNode->OwnerId))
+ {
+ return (AE_OK);
+ }
+
+ if (!(Info->DisplayType & ACPI_DISPLAY_SHORT))
+ {
+ /* Indent the object according to the level */
+
+ AcpiOsPrintf ("%2d%*s", (UINT32) Level - 1, (int) Level * 2, " ");
+
+ /* Check the node type and name */
+
+ if (Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type 0x%08X", Type));
+ }
+
+ AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode));
+ }
+
+ /* Now we can print out the pertinent information */
+
+ AcpiOsPrintf (" %-12s %p %2.2X ",
+ AcpiUtGetTypeName (Type), ThisNode, ThisNode->OwnerId);
+
+ DbgLevel = AcpiDbgLevel;
+ AcpiDbgLevel = 0;
+ ObjDesc = AcpiNsGetAttachedObject (ThisNode);
+ AcpiDbgLevel = DbgLevel;
+
+ /* Temp nodes are those nodes created by a control method */
+
+ if (ThisNode->Flags & ANOBJ_TEMPORARY)
+ {
+ AcpiOsPrintf ("(T) ");
+ }
+
+ switch (Info->DisplayType & ACPI_DISPLAY_MASK)
+ {
+ case ACPI_DISPLAY_SUMMARY:
+
+ if (!ObjDesc)
+ {
+ /* No attached object. Some types should always have an object */
+
+ switch (Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_PACKAGE:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_METHOD:
+
+ AcpiOsPrintf ("<No attached object>");
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+ }
+
+ switch (Type)
+ {
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiOsPrintf ("ID %02X Len %02X Addr %8.8X%8.8X\n",
+ ObjDesc->Processor.ProcId, ObjDesc->Processor.Length,
+ ACPI_FORMAT_UINT64 (ObjDesc->Processor.Address));
+ break;
+
+ case ACPI_TYPE_DEVICE:
+
+ AcpiOsPrintf ("Notify Object: %p\n", ObjDesc);
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ AcpiOsPrintf ("Args %X Len %.4X Aml %p\n",
+ (UINT32) ObjDesc->Method.ParamCount,
+ ObjDesc->Method.AmlLength, ObjDesc->Method.AmlStart);
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf ("= %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ AcpiOsPrintf ("Elements %.2X\n",
+ ObjDesc->Package.Count);
+ }
+ else
+ {
+ AcpiOsPrintf ("[Length not yet evaluated]\n");
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ AcpiOsPrintf ("Len %.2X",
+ ObjDesc->Buffer.Length);
+
+ /* Dump some of the buffer */
+
+ if (ObjDesc->Buffer.Length > 0)
+ {
+ AcpiOsPrintf (" =");
+ for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++)
+ {
+ AcpiOsPrintf (" %.2hX", ObjDesc->Buffer.Pointer[i]);
+ }
+ }
+ AcpiOsPrintf ("\n");
+ }
+ else
+ {
+ AcpiOsPrintf ("[Length not yet evaluated]\n");
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length);
+ AcpiUtPrintString (ObjDesc->String.Pointer, 32);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ AcpiOsPrintf ("[%s]",
+ AcpiUtGetRegionName (ObjDesc->Region.SpaceId));
+ if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
+ {
+ AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
+ ObjDesc->Region.Length);
+ }
+ else
+ {
+ AcpiOsPrintf (" [Address/Length not yet evaluated]\n");
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[%s]\n", AcpiUtGetReferenceName (ObjDesc));
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ if (ObjDesc->BufferField.BufferObj &&
+ ObjDesc->BufferField.BufferObj->Buffer.Node)
+ {
+ AcpiOsPrintf ("Buf [%4.4s]",
+ AcpiUtGetNodeName (
+ ObjDesc->BufferField.BufferObj->Buffer.Node));
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ AcpiOsPrintf ("Rgn [%4.4s]",
+ AcpiUtGetNodeName (
+ ObjDesc->CommonField.RegionObj->Region.Node));
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]",
+ AcpiUtGetNodeName (
+ ObjDesc->CommonField.RegionObj->Region.Node),
+ AcpiUtGetNodeName (
+ ObjDesc->BankField.BankObj->CommonField.Node));
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]",
+ AcpiUtGetNodeName (
+ ObjDesc->IndexField.IndexObj->CommonField.Node),
+ AcpiUtGetNodeName (
+ ObjDesc->IndexField.DataObj->CommonField.Node));
+ break;
+
+ case ACPI_TYPE_LOCAL_ALIAS:
+ case ACPI_TYPE_LOCAL_METHOD_ALIAS:
+
+ AcpiOsPrintf ("Target %4.4s (%p)\n",
+ AcpiUtGetNodeName (ObjDesc), ObjDesc);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Object %p\n", ObjDesc);
+ break;
+ }
+
+ /* Common field handling */
+
+ switch (Type)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ AcpiOsPrintf (" Off %.3X Len %.2X Acc %.2hd\n",
+ (ObjDesc->CommonField.BaseByteOffset * 8)
+ + ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BitLength,
+ ObjDesc->CommonField.AccessByteWidth);
+ break;
+
+ default:
+
+ break;
+ }
+ break;
+
+ case ACPI_DISPLAY_OBJECTS:
+
+ AcpiOsPrintf ("O:%p", ObjDesc);
+ if (!ObjDesc)
+ {
+ /* No attached object, we are done */
+
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf ("(R%u)", ObjDesc->Common.ReferenceCount);
+
+ switch (Type)
+ {
+ case ACPI_TYPE_METHOD:
+
+ /* Name is a Method and its AML offset/length are set */
+
+ AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart,
+ ObjDesc->Method.AmlLength);
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf (" I:%8.8X8.8%X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer,
+ ObjDesc->String.Length);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer,
+ ObjDesc->Buffer.Length);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("\n");
+ break;
+ }
+ break;
+
+ default:
+ AcpiOsPrintf ("\n");
+ break;
+ }
+
+ /* If debug turned off, done */
+
+ if (!(AcpiDbgLevel & ACPI_LV_VALUES))
+ {
+ return (AE_OK);
+ }
+
+ /* If there is an attached object, display it */
+
+ DbgLevel = AcpiDbgLevel;
+ AcpiDbgLevel = 0;
+ ObjDesc = AcpiNsGetAttachedObject (ThisNode);
+ AcpiDbgLevel = DbgLevel;
+
+ /* Dump attached objects */
+
+ while (ObjDesc)
+ {
+ ObjType = ACPI_TYPE_INVALID;
+ AcpiOsPrintf ("Attached Object %p: ", ObjDesc);
+
+ /* Decode the type of attached object and dump the contents */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+
+ AcpiOsPrintf ("(Ptr to Node)\n");
+ BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
+ ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
+ break;
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ ObjType = ObjDesc->Common.Type;
+
+ if (ObjType > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
+ ObjType);
+ BytesToDump = 32;
+ }
+ else
+ {
+ AcpiOsPrintf ("(Pointer to ACPI Object type %.2X [%s])\n",
+ ObjType, AcpiUtGetTypeName (ObjType));
+ BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
+ }
+
+ ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* If value is NOT an internal object, we are done */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
+ {
+ goto Cleanup;
+ }
+
+ /* Valid object, get the pointer to next level, if any */
+
+ switch (ObjType)
+ {
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_STRING:
+ /*
+ * NOTE: takes advantage of common fields between string/buffer
+ */
+ BytesToDump = ObjDesc->String.Length;
+ ObjDesc = (void *) ObjDesc->String.Pointer;
+ AcpiOsPrintf ( "(Buffer/String pointer %p length %X)\n",
+ ObjDesc, BytesToDump);
+ ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);
+ goto Cleanup;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ObjDesc = (void *) ObjDesc->Package.Elements;
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ ObjDesc = (void *) ObjDesc->Method.AmlStart;
+ break;
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ ObjDesc = (void *) ObjDesc->Field.RegionObj;
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ ObjDesc = (void *) ObjDesc->BankField.RegionObj;
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ ObjDesc = (void *) ObjDesc->IndexField.IndexObj;
+ break;
+
+ default:
+
+ goto Cleanup;
+ }
+
+ ObjType = ACPI_TYPE_INVALID; /* Terminate loop after next pass */
+ }
+
+Cleanup:
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpObjects
+ *
+ * PARAMETERS: Type - Object type to be dumped
+ * DisplayType - 0 or ACPI_DISPLAY_SUMMARY
+ * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX
+ * for an effectively unlimited depth.
+ * OwnerId - Dump only objects owned by this ID. Use
+ * ACPI_UINT32_MAX to match all owners.
+ * StartHandle - Where in namespace to start/end search
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObject.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpObjects (
+ ACPI_OBJECT_TYPE Type,
+ UINT8 DisplayType,
+ UINT32 MaxDepth,
+ ACPI_OWNER_ID OwnerId,
+ ACPI_HANDLE StartHandle)
+{
+ ACPI_WALK_INFO Info;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Just lock the entire namespace for the duration of the dump.
+ * We don't want any changes to the namespace during this time,
+ * especially the temporary nodes since we are going to display
+ * them also.
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not acquire namespace mutex\n");
+ return;
+ }
+
+ Info.DebugLevel = ACPI_LV_TABLES;
+ Info.OwnerId = OwnerId;
+ Info.DisplayType = DisplayType;
+
+ (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
+ ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
+ AcpiNsDumpOneObject, NULL, (void *) &Info, NULL);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpOneObjectPath, AcpiNsGetMaxDepth
+ *
+ * PARAMETERS: ObjHandle - Node to be dumped
+ * Level - Nesting level of the handle
+ * Context - Passed into WalkNamespace
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dump the full pathname to a namespace object. AcpNsGetMaxDepth
+ * computes the maximum nesting depth in the namespace tree, in
+ * order to simplify formatting in AcpiNsDumpOneObjectPath.
+ * These procedures are UserFunctions called by AcpiNsWalkNamespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsDumpOneObjectPath (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ UINT32 MaxLevel = *((UINT32 *) Context);
+ char *Pathname;
+ ACPI_NAMESPACE_NODE *Node;
+ int PathIndent;
+
+
+ if (!ObjHandle)
+ {
+ return (AE_OK);
+ }
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ /* Ignore bad node during namespace walk */
+
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+
+ PathIndent = 1;
+ if (Level <= MaxLevel)
+ {
+ PathIndent = MaxLevel - Level + 1;
+ }
+
+ AcpiOsPrintf ("%2d%*s%-12s%*s",
+ Level, Level, " ", AcpiUtGetTypeName (Node->Type),
+ PathIndent, " ");
+
+ AcpiOsPrintf ("%s\n", &Pathname[1]);
+ ACPI_FREE (Pathname);
+ return (AE_OK);
+}
+
+
+static ACPI_STATUS
+AcpiNsGetMaxDepth (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ UINT32 *MaxLevel = (UINT32 *) Context;
+
+
+ if (Level > *MaxLevel)
+ {
+ *MaxLevel = Level;
+ }
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpObjectPaths
+ *
+ * PARAMETERS: Type - Object type to be dumped
+ * DisplayType - 0 or ACPI_DISPLAY_SUMMARY
+ * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX
+ * for an effectively unlimited depth.
+ * OwnerId - Dump only objects owned by this ID. Use
+ * ACPI_UINT32_MAX to match all owners.
+ * StartHandle - Where in namespace to start/end search
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses
+ * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObjectPath.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpObjectPaths (
+ ACPI_OBJECT_TYPE Type,
+ UINT8 DisplayType,
+ UINT32 MaxDepth,
+ ACPI_OWNER_ID OwnerId,
+ ACPI_HANDLE StartHandle)
+{
+ ACPI_STATUS Status;
+ UINT32 MaxLevel = 0;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Just lock the entire namespace for the duration of the dump.
+ * We don't want any changes to the namespace during this time,
+ * especially the temporary nodes since we are going to display
+ * them also.
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not acquire namespace mutex\n");
+ return;
+ }
+
+ /* Get the max depth of the namespace tree, for formatting later */
+
+ (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
+ ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
+ AcpiNsGetMaxDepth, NULL, (void *) &MaxLevel, NULL);
+
+ /* Now dump the entire namespace */
+
+ (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
+ ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
+ AcpiNsDumpOneObjectPath, NULL, (void *) &MaxLevel, NULL);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpEntry
+ *
+ * PARAMETERS: Handle - Node to be dumped
+ * DebugLevel - Output level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a single Node
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpEntry (
+ ACPI_HANDLE Handle,
+ UINT32 DebugLevel)
+{
+ ACPI_WALK_INFO Info;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Info.DebugLevel = DebugLevel;
+ Info.OwnerId = ACPI_OWNER_ID_MAX;
+ Info.DisplayType = ACPI_DISPLAY_SUMMARY;
+
+ (void) AcpiNsDumpOneObject (Handle, 1, &Info, NULL);
+}
+
+
+#ifdef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpTables
+ *
+ * PARAMETERS: SearchBase - Root of subtree to be dumped, or
+ * NS_ALL to dump the entire namespace
+ * MaxDepth - Maximum depth of dump. Use INT_MAX
+ * for an effectively unlimited depth.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the name space, or a portion of it.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpTables (
+ ACPI_HANDLE SearchBase,
+ UINT32 MaxDepth)
+{
+ ACPI_HANDLE SearchHandle = SearchBase;
+
+
+ ACPI_FUNCTION_TRACE (NsDumpTables);
+
+
+ if (!AcpiGbl_RootNode)
+ {
+ /*
+ * If the name space has not been initialized,
+ * there is nothing to dump.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "namespace not initialized!\n"));
+ return_VOID;
+ }
+
+ if (ACPI_NS_ALL == SearchBase)
+ {
+ /* Entire namespace */
+
+ SearchHandle = AcpiGbl_RootNode;
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
+ }
+
+ AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, MaxDepth,
+ ACPI_OWNER_ID_MAX, SearchHandle);
+ return_VOID;
+}
+#endif
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c
new file mode 100644
index 0000000000..05daaab138
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsdumpdv.c
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Module Name: nsdump - table dumping routines for debug
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+
+
+/* TBD: This entire module is apparently obsolete and should be removed */
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsdumpdv")
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpOneDevice
+ *
+ * PARAMETERS: Handle - Node to be dumped
+ * Level - Nesting level of the handle
+ * Context - Passed into WalkNamespace
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dump a single Node that represents a device
+ * This procedure is a UserFunction called by AcpiNsWalkNamespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsDumpOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_BUFFER Buffer;
+ ACPI_DEVICE_INFO *Info;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsDumpOneDevice);
+
+
+ Status = AcpiNsDumpOneObject (ObjHandle, Level, Context, ReturnValue);
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiGetObjectInfo (ObjHandle, &Buffer);
+ if (ACPI_SUCCESS (Status))
+ {
+ Info = Buffer.Pointer;
+ for (i = 0; i < Level; i++)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES,
+ " HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
+ Info->HardwareId.Value, ACPI_FORMAT_UINT64 (Info->Address),
+ Info->CurrentStatus));
+ ACPI_FREE (Info);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDumpRootDevices
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump all objects of type "device"
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDumpRootDevices (
+ void)
+{
+ ACPI_HANDLE SysBusHandle;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (NsDumpRootDevices);
+
+
+ /* Only dump the table if tracing is enabled */
+
+ if (!(ACPI_LV_TABLES & AcpiDbgLevel))
+ {
+ return;
+ }
+
+ Status = AcpiGetHandle (NULL, METHOD_NAME__SB_, &SysBusHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
+ "Display of all devices in the namespace:\n"));
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
+ AcpiNsDumpOneDevice, NULL, NULL, NULL);
+}
+
+#endif
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nseval.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nseval.c
new file mode 100644
index 0000000000..a8c9d89616
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nseval.c
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ *
+ * Module Name: nseval - Object evaluation, includes control method execution
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nseval")
+
+/* Local prototypes */
+
+static void
+AcpiNsExecModuleCode (
+ ACPI_OPERAND_OBJECT *MethodObj,
+ ACPI_EVALUATE_INFO *Info);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsEvaluate
+ *
+ * PARAMETERS: Info - Evaluation info block, contains these fields
+ * and more:
+ * PrefixNode - Prefix or Method/Object Node to execute
+ * RelativePath - Name of method to execute, If NULL, the
+ * Node is the object to execute
+ * Parameters - List of parameters to pass to the method,
+ * terminated by NULL. Params itself may be
+ * NULL if no parameters are being passed.
+ * ParameterType - Type of Parameter list
+ * ReturnObject - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * Flags - ACPI_IGNORE_RETURN_VALUE to delete return
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method or return the current value of an
+ * ACPI namespace object.
+ *
+ * MUTEX: Locks interpreter
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsEvaluate (
+ ACPI_EVALUATE_INFO *Info)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsEvaluate);
+
+
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (!Info->Node)
+ {
+ /*
+ * Get the actual namespace node for the target object if we
+ * need to. Handles these cases:
+ *
+ * 1) Null node, valid pathname from root (absolute path)
+ * 2) Node and valid pathname (path relative to Node)
+ * 3) Node, Null pathname
+ */
+ Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname,
+ ACPI_NS_NO_UPSEARCH, &Info->Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * For a method alias, we must grab the actual method node so that
+ * proper scoping context will be established before execution.
+ */
+ if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
+ {
+ Info->Node = ACPI_CAST_PTR (
+ ACPI_NAMESPACE_NODE, Info->Node->Object);
+ }
+
+ /* Complete the info block initialization */
+
+ Info->ReturnObject = NULL;
+ Info->NodeFlags = Info->Node->Flags;
+ Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+ Info->RelativePathname, Info->Node,
+ AcpiNsGetAttachedObject (Info->Node)));
+
+ /* Get info if we have a predefined name (_HID, etc.) */
+
+ Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii);
+
+ /* Get the full pathname to the object, for use in warning messages */
+
+ Info->FullPathname = AcpiNsGetExternalPathname (Info->Node);
+ if (!Info->FullPathname)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Count the number of arguments being passed in */
+
+ Info->ParamCount = 0;
+ if (Info->Parameters)
+ {
+ while (Info->Parameters[Info->ParamCount])
+ {
+ Info->ParamCount++;
+ }
+
+ /* Warn on impossible argument count */
+
+ if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS,
+ "Excess arguments (%u) - using only %u",
+ Info->ParamCount, ACPI_METHOD_NUM_ARGS));
+
+ Info->ParamCount = ACPI_METHOD_NUM_ARGS;
+ }
+ }
+
+ /*
+ * For predefined names: Check that the declared argument count
+ * matches the ACPI spec -- otherwise this is a BIOS error.
+ */
+ AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node,
+ Info->Predefined);
+
+ /*
+ * For all names: Check that the incoming argument count for
+ * this method/object matches the actual ASL/AML definition.
+ */
+ AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node,
+ Info->ParamCount, Info->Predefined);
+
+ /* For predefined names: Typecheck all incoming arguments */
+
+ AcpiNsCheckArgumentTypes (Info);
+
+ /*
+ * Three major evaluation cases:
+ *
+ * 1) Object types that cannot be evaluated by definition
+ * 2) The object is a control method -- execute it
+ * 3) The object is not a method -- just return it's current value
+ */
+ switch (AcpiNsGetType (Info->Node))
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_EVENT:
+ case ACPI_TYPE_MUTEX:
+ case ACPI_TYPE_REGION:
+ case ACPI_TYPE_THERMAL:
+ case ACPI_TYPE_LOCAL_SCOPE:
+ /*
+ * 1) Disallow evaluation of certain object types. For these,
+ * object evaluation is undefined and not supported.
+ */
+ ACPI_ERROR ((AE_INFO,
+ "%s: Evaluation of object type [%s] is not supported",
+ Info->FullPathname,
+ AcpiUtGetTypeName (Info->Node->Type)));
+
+ Status = AE_TYPE;
+ goto Cleanup;
+
+ case ACPI_TYPE_METHOD:
+ /*
+ * 2) Object is a control method - execute it
+ */
+
+ /* Verify that there is a method object associated with this node */
+
+ if (!Info->ObjDesc)
+ {
+ ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object",
+ Info->FullPathname));
+ Status = AE_NULL_OBJECT;
+ goto Cleanup;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "**** Execute method [%s] at AML address %p length %X\n",
+ Info->FullPathname,
+ Info->ObjDesc->Method.AmlStart + 1,
+ Info->ObjDesc->Method.AmlLength - 1));
+
+ /*
+ * Any namespace deletion must acquire both the namespace and
+ * interpreter locks to ensure that no thread is using the portion of
+ * the namespace that is being deleted.
+ *
+ * Execute the method via the interpreter. The interpreter is locked
+ * here before calling into the AML parser
+ */
+ AcpiExEnterInterpreter ();
+ Status = AcpiPsExecuteMethod (Info);
+ AcpiExExitInterpreter ();
+ break;
+
+ default:
+ /*
+ * 3) All other non-method objects -- get the current object value
+ */
+
+ /*
+ * Some objects require additional resolution steps (e.g., the Node
+ * may be a field that must be read, etc.) -- we can't just grab
+ * the object out of the node.
+ *
+ * Use ResolveNodeToValue() to get the associated value.
+ *
+ * NOTE: we can get away with passing in NULL for a walk state because
+ * the Node is guaranteed to not be a reference to either a method
+ * local or a method argument (because this interface is never called
+ * from a running method.)
+ *
+ * Even though we do not directly invoke the interpreter for object
+ * resolution, we must lock it because we could access an OpRegion.
+ * The OpRegion access code assumes that the interpreter is locked.
+ */
+ AcpiExEnterInterpreter ();
+
+ /* TBD: ResolveNodeToValue has a strange interface, fix */
+
+ Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node);
+
+ Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR (
+ ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL);
+ AcpiExExitInterpreter ();
+
+ if (ACPI_FAILURE (Status))
+ {
+ Info->ReturnObject = NULL;
+ goto Cleanup;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n",
+ Info->ReturnObject,
+ AcpiUtGetObjectTypeName (Info->ReturnObject)));
+
+ Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */
+ break;
+ }
+
+ /*
+ * For predefined names, check the return value against the ACPI
+ * specification. Some incorrect return value types are repaired.
+ */
+ (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount,
+ Status, &Info->ReturnObject);
+
+ /* Check if there is a return value that must be dealt with */
+
+ if (Status == AE_CTRL_RETURN_VALUE)
+ {
+ /* If caller does not want the return value, delete it */
+
+ if (Info->Flags & ACPI_IGNORE_RETURN_VALUE)
+ {
+ AcpiUtRemoveReference (Info->ReturnObject);
+ Info->ReturnObject = NULL;
+ }
+
+ /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
+
+ Status = AE_OK;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "*** Completed evaluation of object %s ***\n",
+ Info->RelativePathname));
+
+Cleanup:
+ /*
+ * Namespace was unlocked by the handling AcpiNs* function, so we
+ * just free the pathname and return
+ */
+ ACPI_FREE (Info->FullPathname);
+ Info->FullPathname = NULL;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsExecModuleCodeList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None. Exceptions during method execution are ignored, since
+ * we cannot abort a table load.
+ *
+ * DESCRIPTION: Execute all elements of the global module-level code list.
+ * Each element is executed as a single control method.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsExecModuleCodeList (
+ void)
+{
+ ACPI_OPERAND_OBJECT *Prev;
+ ACPI_OPERAND_OBJECT *Next;
+ ACPI_EVALUATE_INFO *Info;
+ UINT32 MethodCount = 0;
+
+
+ ACPI_FUNCTION_TRACE (NsExecModuleCodeList);
+
+
+ /* Exit now if the list is empty */
+
+ Next = AcpiGbl_ModuleCodeList;
+ if (!Next)
+ {
+ return_VOID;
+ }
+
+ /* Allocate the evaluation information block */
+
+ Info = ACPI_ALLOCATE (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_VOID;
+ }
+
+ /* Walk the list, executing each "method" */
+
+ while (Next)
+ {
+ Prev = Next;
+ Next = Next->Method.Mutex;
+
+ /* Clear the link field and execute the method */
+
+ Prev->Method.Mutex = NULL;
+ AcpiNsExecModuleCode (Prev, Info);
+ MethodCount++;
+
+ /* Delete the (temporary) method object */
+
+ AcpiUtRemoveReference (Prev);
+ }
+
+ ACPI_INFO ((AE_INFO,
+ "Executed %u blocks of module-level executable AML code",
+ MethodCount));
+
+ ACPI_FREE (Info);
+ AcpiGbl_ModuleCodeList = NULL;
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsExecModuleCode
+ *
+ * PARAMETERS: MethodObj - Object container for the module-level code
+ * Info - Info block for method evaluation
+ *
+ * RETURN: None. Exceptions during method execution are ignored, since
+ * we cannot abort a table load.
+ *
+ * DESCRIPTION: Execute a control method containing a block of module-level
+ * executable AML code. The control method is temporarily
+ * installed to the root node, then evaluated.
+ *
+ ******************************************************************************/
+
+static void
+AcpiNsExecModuleCode (
+ ACPI_OPERAND_OBJECT *MethodObj,
+ ACPI_EVALUATE_INFO *Info)
+{
+ ACPI_OPERAND_OBJECT *ParentObj;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsExecModuleCode);
+
+
+ /*
+ * Get the parent node. We cheat by using the NextObject field
+ * of the method object descriptor.
+ */
+ ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ MethodObj->Method.NextObject);
+ Type = AcpiNsGetType (ParentNode);
+
+ /*
+ * Get the region handler and save it in the method object. We may need
+ * this if an operation region declaration causes a _REG method to be run.
+ *
+ * We can't do this in AcpiPsLinkModuleCode because
+ * AcpiGbl_RootNode->Object is NULL at PASS1.
+ */
+ if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object)
+ {
+ MethodObj->Method.Dispatch.Handler =
+ ParentNode->Object->Device.Handler;
+ }
+
+ /* Must clear NextObject (AcpiNsAttachObject needs the field) */
+
+ MethodObj->Method.NextObject = NULL;
+
+ /* Initialize the evaluation information block */
+
+ memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
+ Info->PrefixNode = ParentNode;
+
+ /*
+ * Get the currently attached parent object. Add a reference, because the
+ * ref count will be decreased when the method object is installed to
+ * the parent node.
+ */
+ ParentObj = AcpiNsGetAttachedObject (ParentNode);
+ if (ParentObj)
+ {
+ AcpiUtAddReference (ParentObj);
+ }
+
+ /* Install the method (module-level code) in the parent node */
+
+ Status = AcpiNsAttachObject (ParentNode, MethodObj,
+ ACPI_TYPE_METHOD);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /* Execute the parent node as a control method */
+
+ Status = AcpiNsEvaluate (Info);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT_NAMES,
+ "Executed module-level code at %p\n",
+ MethodObj->Method.AmlStart));
+
+ /* Delete a possible implicit return value (in slack mode) */
+
+ if (Info->ReturnObject)
+ {
+ AcpiUtRemoveReference (Info->ReturnObject);
+ }
+
+ /* Detach the temporary method object */
+
+ AcpiNsDetachObject (ParentNode);
+
+ /* Restore the original parent object */
+
+ if (ParentObj)
+ {
+ Status = AcpiNsAttachObject (ParentNode, ParentObj, Type);
+ }
+ else
+ {
+ ParentNode->Type = (UINT8) Type;
+ }
+
+Exit:
+ if (ParentObj)
+ {
+ AcpiUtRemoveReference (ParentObj);
+ }
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsinit.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsinit.c
new file mode 100644
index 0000000000..cbfc4a6fea
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsinit.c
@@ -0,0 +1,656 @@
+/******************************************************************************
+ *
+ * Module Name: nsinit - namespace initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsinit")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiNsInitOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiNsFindIniMethods (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInitializeObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk the entire namespace and perform any necessary
+ * initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsInitializeObjects (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_INIT_WALK_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE (NsInitializeObjects);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "**** Starting initialization of namespace objects ****\n"));
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "Completing Region/Field/Buffer/Package initialization:\n"));
+
+ /* Set all init info to zero */
+
+ memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+
+ /* Walk entire namespace from the supplied root */
+
+ Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL,
+ &Info, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ " Initialized %u/%u Regions %u/%u Fields %u/%u "
+ "Buffers %u/%u Packages (%u nodes)\n",
+ Info.OpRegionInit, Info.OpRegionCount,
+ Info.FieldInit, Info.FieldCount,
+ Info.BufferInit, Info.BufferCount,
+ Info.PackageInit, Info.PackageCount, Info.ObjectCount));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "%u Control Methods found\n%u Op Regions found\n",
+ Info.MethodCount, Info.OpRegionCount));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInitializeDevices
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
+ * This means running _INI on all present devices.
+ *
+ * Note: We install PCI config space handler on region access,
+ * not here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsInitializeDevices (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_DEVICE_WALK_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE (NsInitializeDevices);
+
+
+ /* Init counters */
+
+ Info.DeviceCount = 0;
+ Info.Num_STA = 0;
+ Info.Num_INI = 0;
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "Initializing Device/Processor/Thermal objects "
+ "and executing _INI/_STA methods:\n"));
+
+ /* Tree analysis: find all subtrees that contain _INI methods */
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* Allocate the evaluation information block */
+
+ Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info.EvaluateInfo)
+ {
+ Status = AE_NO_MEMORY;
+ goto ErrorExit;
+ }
+
+ /*
+ * Execute the "global" _INI method that may appear at the root. This
+ * support is provided for Windows compatibility (Vista+) and is not
+ * part of the ACPI specification.
+ */
+ Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
+ Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
+ Info.EvaluateInfo->Parameters = NULL;
+ Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ Status = AcpiNsEvaluate (Info.EvaluateInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ Info.Num_INI++;
+ }
+
+ /* Walk namespace to execute all _INIs on present devices */
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
+
+ /*
+ * Any _OSI requests should be completed by now. If the BIOS has
+ * requested any Windows OSI strings, we will always truncate
+ * I/O addresses to 16 bits -- for Windows compatibility.
+ */
+ if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
+ {
+ AcpiGbl_TruncateIoAddresses = TRUE;
+ }
+
+ ACPI_FREE (Info.EvaluateInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ " Executed %u _INI methods requiring %u _STA executions "
+ "(examined %u objects)\n",
+ Info.Num_INI, Info.Num_STA, Info.DeviceCount));
+
+ return_ACPI_STATUS (Status);
+
+
+ErrorExit:
+ ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInitOneObject
+ *
+ * PARAMETERS: ObjHandle - Node
+ * Level - Current nesting level
+ * Context - Points to a init info struct
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
+ * within the namespace.
+ *
+ * Currently, the only objects that require initialization are:
+ * 1) Methods
+ * 2) Op Regions
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OBJECT_TYPE Type;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_NAME (NsInitOneObject);
+
+
+ Info->ObjectCount++;
+
+ /* And even then, we are only interested in a few object types */
+
+ Type = AcpiNsGetType (ObjHandle);
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ return (AE_OK);
+ }
+
+ /* Increment counters for object types we are looking for */
+
+ switch (Type)
+ {
+ case ACPI_TYPE_REGION:
+
+ Info->OpRegionCount++;
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ Info->FieldCount++;
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ Info->FieldCount++;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Info->BufferCount++;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ Info->PackageCount++;
+ break;
+
+ default:
+
+ /* No init required, just exit now */
+
+ return (AE_OK);
+ }
+
+ /* If the object is already initialized, nothing else to do */
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return (AE_OK);
+ }
+
+ /* Must lock the interpreter before executing AML code */
+
+ AcpiExEnterInterpreter ();
+
+ /*
+ * Each of these types can contain executable AML code within the
+ * declaration.
+ */
+ switch (Type)
+ {
+ case ACPI_TYPE_REGION:
+
+ Info->OpRegionInit++;
+ Status = AcpiDsGetRegionArguments (ObjDesc);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ Info->FieldInit++;
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ Info->FieldInit++;
+ Status = AcpiDsGetBankFieldArguments (ObjDesc);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Info->BufferInit++;
+ Status = AcpiDsGetBufferArguments (ObjDesc);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ Info->PackageInit++;
+ Status = AcpiDsGetPackageArguments (ObjDesc);
+ break;
+
+ default:
+
+ /* No other types can get here */
+
+ break;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not execute arguments for [%4.4s] (%s)",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
+ }
+
+ /*
+ * We ignore errors from above, and always return OK, since we don't want
+ * to abort the walk on any single error.
+ */
+ AcpiExExitInterpreter ();
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsFindIniMethods
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
+ * device/processor/thermal objects, and marks the entire subtree
+ * with a SUBTREE_HAS_INI flag. This flag is used during the
+ * subsequent device initialization walk to avoid entire subtrees
+ * that do not contain an _INI.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsFindIniMethods (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *ParentNode;
+
+
+ /* Keep count of device/processor/thermal objects */
+
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ if ((Node->Type == ACPI_TYPE_DEVICE) ||
+ (Node->Type == ACPI_TYPE_PROCESSOR) ||
+ (Node->Type == ACPI_TYPE_THERMAL))
+ {
+ Info->DeviceCount++;
+ return (AE_OK);
+ }
+
+ /* We are only looking for methods named _INI */
+
+ if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * The only _INI methods that we care about are those that are
+ * present under Device, Processor, and Thermal objects.
+ */
+ ParentNode = Node->Parent;
+ switch (ParentNode->Type)
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+
+ /* Mark parent and bubble up the INI present flag to the root */
+
+ while (ParentNode)
+ {
+ ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
+ ParentNode = ParentNode->Parent;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInitOneDevice
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: This is called once per device soon after ACPI is enabled
+ * to initialize each device. It determines if the device is
+ * present, and if so, calls _INI.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsInitOneDevice (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
+ ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo;
+ UINT32 Flags;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *DeviceNode;
+
+
+ ACPI_FUNCTION_TRACE (NsInitOneDevice);
+
+
+ /* We are interested in Devices, Processors and ThermalZones only */
+
+ DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ if ((DeviceNode->Type != ACPI_TYPE_DEVICE) &&
+ (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
+ (DeviceNode->Type != ACPI_TYPE_THERMAL))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Because of an earlier namespace analysis, all subtrees that contain an
+ * _INI method are tagged.
+ *
+ * If this device subtree does not contain any _INI methods, we
+ * can exit now and stop traversing this entire subtree.
+ */
+ if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
+ {
+ return_ACPI_STATUS (AE_CTRL_DEPTH);
+ }
+
+ /*
+ * Run _STA to determine if this device is present and functioning. We
+ * must know this information for two important reasons (from ACPI spec):
+ *
+ * 1) We can only run _INI if the device is present.
+ * 2) We must abort the device tree walk on this subtree if the device is
+ * not present and is not functional (we will not examine the children)
+ *
+ * The _STA method is not required to be present under the device, we
+ * assume the device is present if _STA does not exist.
+ */
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
+ ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
+
+ Status = AcpiUtExecute_STA (DeviceNode, &Flags);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Ignore error and move on to next device */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Flags == -1 means that _STA was not found. In this case, we assume that
+ * the device is both present and functional.
+ *
+ * From the ACPI spec, description of _STA:
+ *
+ * "If a device object (including the processor object) does not have an
+ * _STA object, then OSPM assumes that all of the above bits are set (in
+ * other words, the device is present, ..., and functioning)"
+ */
+ if (Flags != ACPI_UINT32_MAX)
+ {
+ WalkInfo->Num_STA++;
+ }
+
+ /*
+ * Examine the PRESENT and FUNCTIONING status bits
+ *
+ * Note: ACPI spec does not seem to specify behavior for the present but
+ * not functioning case, so we assume functioning if present.
+ */
+ if (!(Flags & ACPI_STA_DEVICE_PRESENT))
+ {
+ /* Device is not present, we must examine the Functioning bit */
+
+ if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
+ {
+ /*
+ * Device is not present but is "functioning". In this case,
+ * we will not run _INI, but we continue to examine the children
+ * of this device.
+ *
+ * From the ACPI spec, description of _STA: (Note - no mention
+ * of whether to run _INI or not on the device in question)
+ *
+ * "_STA may return bit 0 clear (not present) with bit 3 set
+ * (device is functional). This case is used to indicate a valid
+ * device for which no device driver should be loaded (for example,
+ * a bridge device.) Children of this device may be present and
+ * valid. OSPM should continue enumeration below a device whose
+ * _STA returns this bit combination"
+ */
+ return_ACPI_STATUS (AE_OK);
+ }
+ else
+ {
+ /*
+ * Device is not present and is not functioning. We must abort the
+ * walk of this subtree immediately -- don't look at the children
+ * of such a device.
+ *
+ * From the ACPI spec, description of _INI:
+ *
+ * "If the _STA method indicates that the device is not present,
+ * OSPM will not run the _INI and will not examine the children
+ * of the device for _INI methods"
+ */
+ return_ACPI_STATUS (AE_CTRL_DEPTH);
+ }
+ }
+
+ /*
+ * The device is present or is assumed present if no _STA exists.
+ * Run the _INI if it exists (not required to exist)
+ *
+ * Note: We know there is an _INI within this subtree, but it may not be
+ * under this particular device, it may be lower in the branch.
+ */
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
+ ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
+
+ memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
+ Info->PrefixNode = DeviceNode;
+ Info->RelativePathname = METHOD_NAME__INI;
+ Info->Parameters = NULL;
+ Info->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ Status = AcpiNsEvaluate (Info);
+ if (ACPI_SUCCESS (Status))
+ {
+ WalkInfo->Num_INI++;
+ }
+
+#ifdef ACPI_DEBUG_OUTPUT
+ else if (Status != AE_NOT_FOUND)
+ {
+ /* Ignore error and move on to next device */
+
+ char *ScopeName = AcpiNsGetExternalPathname (Info->Node);
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
+ ScopeName));
+ ACPI_FREE (ScopeName);
+ }
+#endif
+
+ /* Ignore errors from above */
+
+ Status = AE_OK;
+
+ /*
+ * The _INI method has been run if present; call the Global Initialization
+ * Handler for this device.
+ */
+ if (AcpiGbl_InitHandler)
+ {
+ Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsload.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsload.c
new file mode 100644
index 0000000000..4b4dc13241
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsload.c
@@ -0,0 +1,367 @@
+/******************************************************************************
+ *
+ * Module Name: nsload - namespace loading/expanding/contracting procedures
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsload")
+
+/* Local prototypes */
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+ACPI_STATUS
+AcpiNsUnloadNamespace (
+ ACPI_HANDLE Handle);
+
+static ACPI_STATUS
+AcpiNsDeleteSubtree (
+ ACPI_HANDLE StartHandle);
+#endif
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsLoadTable
+ *
+ * PARAMETERS: TableIndex - Index for table to be loaded
+ * Node - Owning NS node
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load one ACPI table into the namespace
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsLoadTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsLoadTable);
+
+
+ /*
+ * Parse the table and load the namespace with all named
+ * objects found within. Control methods are NOT parsed
+ * at this time. In fact, the control methods cannot be
+ * parsed until the entire namespace is loaded, because
+ * if a control method makes a forward reference (call)
+ * to another control method, we can't continue parsing
+ * because we don't know how many arguments to parse next!
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* If table already loaded into namespace, just return */
+
+ if (AcpiTbIsTableLoaded (TableIndex))
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Unlock;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "**** Loading table into namespace ****\n"));
+
+ Status = AcpiTbAllocateOwnerId (TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Unlock;
+ }
+
+ Status = AcpiNsParseTable (TableIndex, Node);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiTbSetTableLoadedFlag (TableIndex, TRUE);
+ }
+ else
+ {
+ /*
+ * On error, delete any namespace objects created by this table.
+ * We cannot initialize these objects, so delete them. There are
+ * a couple of expecially bad cases:
+ * AE_ALREADY_EXISTS - namespace collision.
+ * AE_NOT_FOUND - the target of a Scope operator does not
+ * exist. This target of Scope must already exist in the
+ * namespace, as per the ACPI specification.
+ */
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ AcpiNsDeleteNamespaceByOwner (
+ AcpiGbl_RootTableList.Tables[TableIndex].OwnerId);
+ AcpiTbReleaseOwnerId (TableIndex);
+
+ return_ACPI_STATUS (Status);
+ }
+
+Unlock:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Now we can parse the control methods. We always parse
+ * them here for a sanity check, and if configured for
+ * just-in-time parsing, we delete the control method
+ * parse trees.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "**** Begin Table Object Initialization\n"));
+
+ Status = AcpiDsInitializeObjects (TableIndex, Node);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "**** Completed Table Object Initialization\n"));
+
+ return_ACPI_STATUS (Status);
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
+ * (DSDT points to either the BIOS or a buffer.)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsLoadNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadNameSpace);
+
+
+ /* There must be at least a DSDT installed */
+
+ if (AcpiGbl_DSDT == NULL)
+ {
+ ACPI_ERROR ((AE_INFO, "DSDT is not in memory"));
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ }
+
+ /*
+ * Load the namespace. The DSDT is required,
+ * but the SSDT and PSDT tables are optional.
+ */
+ Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Ignore exceptions from these */
+
+ (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT);
+ (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT);
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "ACPI Namespace successfully loaded at root %p\n",
+ AcpiGbl_RootNode));
+
+ return_ACPI_STATUS (Status);
+}
+#endif
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDeleteSubtree
+ *
+ * PARAMETERS: StartHandle - Handle in namespace where search begins
+ *
+ * RETURNS Status
+ *
+ * DESCRIPTION: Walks the namespace starting at the given handle and deletes
+ * all objects, entries, and scopes in the entire subtree.
+ *
+ * Namespace/Interpreter should be locked or the subsystem should
+ * be in shutdown before this routine is called.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsDeleteSubtree (
+ ACPI_HANDLE StartHandle)
+{
+ ACPI_STATUS Status;
+ ACPI_HANDLE ChildHandle;
+ ACPI_HANDLE ParentHandle;
+ ACPI_HANDLE NextChildHandle;
+ ACPI_HANDLE Dummy;
+ UINT32 Level;
+
+
+ ACPI_FUNCTION_TRACE (NsDeleteSubtree);
+
+
+ ParentHandle = StartHandle;
+ ChildHandle = NULL;
+ Level = 1;
+
+ /*
+ * Traverse the tree of objects until we bubble back up
+ * to where we started.
+ */
+ while (Level > 0)
+ {
+ /* Attempt to get the next object in this scope */
+
+ Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle,
+ ChildHandle, &NextChildHandle);
+
+ ChildHandle = NextChildHandle;
+
+ /* Did we get a new object? */
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Check if this object has any children */
+
+ if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle,
+ NULL, &Dummy)))
+ {
+ /*
+ * There is at least one child of this object,
+ * visit the object
+ */
+ Level++;
+ ParentHandle = ChildHandle;
+ ChildHandle = NULL;
+ }
+ }
+ else
+ {
+ /*
+ * No more children in this object, go back up to
+ * the object's parent
+ */
+ Level--;
+
+ /* Delete all children now */
+
+ AcpiNsDeleteChildren (ChildHandle);
+
+ ChildHandle = ParentHandle;
+ Status = AcpiGetParent (ParentHandle, &ParentHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
+ /* Now delete the starting object, and we are done */
+
+ AcpiNsRemoveNode (ChildHandle);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsUnloadNameSpace
+ *
+ * PARAMETERS: Handle - Root of namespace subtree to be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Shrinks the namespace, typically in response to an undocking
+ * event. Deletes an entire subtree starting from (and
+ * including) the given handle.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsUnloadNamespace (
+ ACPI_HANDLE Handle)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsUnloadNameSpace);
+
+
+ /* Parameter validation */
+
+ if (!AcpiGbl_RootNode)
+ {
+ return_ACPI_STATUS (AE_NO_NAMESPACE);
+ }
+
+ if (!Handle)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* This function does the real work */
+
+ Status = AcpiNsDeleteSubtree (Handle);
+
+ return_ACPI_STATUS (Status);
+}
+#endif
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsnames.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsnames.c
new file mode 100644
index 0000000000..047cc8db9a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsnames.c
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ *
+ * Module Name: nsnames - Name manipulation and search
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsnames")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetExternalPathname
+ *
+ * PARAMETERS: Node - Namespace node whose pathname is needed
+ *
+ * RETURN: Pointer to storage containing the fully qualified name of
+ * the node, In external format (name segments separated by path
+ * separators.)
+ *
+ * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
+ * for error and debug statements.
+ *
+ ******************************************************************************/
+
+char *
+AcpiNsGetExternalPathname (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ char *NameBuffer;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
+
+
+ NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE);
+
+ return_PTR (NameBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetPathnameLength
+ *
+ * PARAMETERS: Node - Namespace node
+ *
+ * RETURN: Length of path, including prefix
+ *
+ * DESCRIPTION: Get the length of the pathname string for this node
+ *
+ ******************************************************************************/
+
+ACPI_SIZE
+AcpiNsGetPathnameLength (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_SIZE Size;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE);
+
+ return (Size);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsHandleToPathname
+ *
+ * PARAMETERS: TargetHandle - Handle of named object whose name is
+ * to be found
+ * Buffer - Where the pathname is returned
+ * NoTrailing - Remove trailing '_' for each name
+ * segment
+ *
+ * RETURN: Status, Buffer is filled with pathname if status is AE_OK
+ *
+ * DESCRIPTION: Build and return a full namespace pathname
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsHandleToPathname (
+ ACPI_HANDLE TargetHandle,
+ ACPI_BUFFER *Buffer,
+ BOOLEAN NoTrailing)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_SIZE RequiredSize;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
+
+
+ Node = AcpiNsValidateHandle (TargetHandle);
+ if (!Node)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Determine size required for the caller buffer */
+
+ RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
+ if (!RequiredSize)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (Buffer, RequiredSize);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Build the path in the caller buffer */
+
+ (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer,
+ RequiredSize, NoTrailing);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",
+ (char *) Buffer->Pointer, (UINT32) RequiredSize));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsBuildNormalizedPath
+ *
+ * PARAMETERS: Node - Namespace node
+ * FullPath - Where the path name is returned
+ * PathSize - Size of returned path name buffer
+ * NoTrailing - Remove trailing '_' from each name segment
+ *
+ * RETURN: Return 1 if the AML path is empty, otherwise returning (length
+ * of pathname + 1) which means the 'FullPath' contains a trailing
+ * null.
+ *
+ * DESCRIPTION: Build and return a full namespace pathname.
+ * Note that if the size of 'FullPath' isn't large enough to
+ * contain the namespace node's path name, the actual required
+ * buffer length is returned, and it should be greater than
+ * 'PathSize'. So callers are able to check the returning value
+ * to determine the buffer size of 'FullPath'.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiNsBuildNormalizedPath (
+ ACPI_NAMESPACE_NODE *Node,
+ char *FullPath,
+ UINT32 PathSize,
+ BOOLEAN NoTrailing)
+{
+ UINT32 Length = 0, i;
+ char Name[ACPI_NAME_SIZE];
+ BOOLEAN DoNoTrailing;
+ char c, *Left, *Right;
+ ACPI_NAMESPACE_NODE *NextNode;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node);
+
+
+#define ACPI_PATH_PUT8(Path, Size, Byte, Length) \
+ do { \
+ if ((Length) < (Size)) \
+ { \
+ (Path)[(Length)] = (Byte); \
+ } \
+ (Length)++; \
+ } while (0)
+
+ /*
+ * Make sure the PathSize is correct, so that we don't need to
+ * validate both FullPath and PathSize.
+ */
+ if (!FullPath)
+ {
+ PathSize = 0;
+ }
+
+ if (!Node)
+ {
+ goto BuildTrailingNull;
+ }
+
+ NextNode = Node;
+ while (NextNode && NextNode != AcpiGbl_RootNode)
+ {
+ if (NextNode != Node)
+ {
+ ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length);
+ }
+ ACPI_MOVE_32_TO_32 (Name, &NextNode->Name);
+ DoNoTrailing = NoTrailing;
+ for (i = 0; i < 4; i++)
+ {
+ c = Name[4-i-1];
+ if (DoNoTrailing && c != '_')
+ {
+ DoNoTrailing = FALSE;
+ }
+ if (!DoNoTrailing)
+ {
+ ACPI_PATH_PUT8(FullPath, PathSize, c, Length);
+ }
+ }
+ NextNode = NextNode->Parent;
+ }
+ ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length);
+
+ /* Reverse the path string */
+
+ if (Length <= PathSize)
+ {
+ Left = FullPath;
+ Right = FullPath+Length-1;
+ while (Left < Right)
+ {
+ c = *Left;
+ *Left++ = *Right;
+ *Right-- = c;
+ }
+ }
+
+ /* Append the trailing null */
+
+BuildTrailingNull:
+ ACPI_PATH_PUT8(FullPath, PathSize, '\0', Length);
+
+#undef ACPI_PATH_PUT8
+
+ return_UINT32 (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetNormalizedPathname
+ *
+ * PARAMETERS: Node - Namespace node whose pathname is needed
+ * NoTrailing - Remove trailing '_' from each name segment
+ *
+ * RETURN: Pointer to storage containing the fully qualified name of
+ * the node, In external format (name segments separated by path
+ * separators.)
+ *
+ * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
+ * for error and debug statements. All trailing '_' will be
+ * removed from the full pathname if 'NoTrailing' is specified..
+ *
+ ******************************************************************************/
+
+char *
+AcpiNsGetNormalizedPathname (
+ ACPI_NAMESPACE_NODE *Node,
+ BOOLEAN NoTrailing)
+{
+ char *NameBuffer;
+ ACPI_SIZE Size;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node);
+
+
+ /* Calculate required buffer size based on depth below root */
+
+ Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
+ if (!Size)
+ {
+ return_PTR (NULL);
+ }
+
+ /* Allocate a buffer to be returned to caller */
+
+ NameBuffer = ACPI_ALLOCATE_ZEROED (Size);
+ if (!NameBuffer)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not allocate %u bytes", (UINT32) Size));
+ return_PTR (NULL);
+ }
+
+ /* Build the path in the allocated buffer */
+
+ (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, Size, NoTrailing);
+
+ return_PTR (NameBuffer);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsobject.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsobject.c
new file mode 100644
index 0000000000..8327b7602c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsobject.c
@@ -0,0 +1,515 @@
+/*******************************************************************************
+ *
+ * Module Name: nsobject - Utilities for objects attached to namespace
+ * table entries
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsobject")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsAttachObject
+ *
+ * PARAMETERS: Node - Parent Node
+ * Object - Object to be attached
+ * Type - Type of object, or ACPI_TYPE_ANY if not
+ * known
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Record the given object as the value associated with the
+ * name whose ACPI_HANDLE is passed. If Object is NULL
+ * and Type is ACPI_TYPE_ANY, set the name as having no value.
+ * Note: Future may require that the Node->Flags field be passed
+ * as a parameter.
+ *
+ * MUTEX: Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsAttachObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_OBJECT_TYPE Type)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *LastObjDesc;
+ ACPI_OBJECT_TYPE ObjectType = ACPI_TYPE_ANY;
+
+
+ ACPI_FUNCTION_TRACE (NsAttachObject);
+
+
+ /*
+ * Parameter validation
+ */
+ if (!Node)
+ {
+ /* Invalid handle */
+
+ ACPI_ERROR ((AE_INFO, "Null NamedObj handle"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (!Object && (ACPI_TYPE_ANY != Type))
+ {
+ /* Null object */
+
+ ACPI_ERROR ((AE_INFO,
+ "Null object, but type not ACPI_TYPE_ANY"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ /* Not a name handle */
+
+ ACPI_ERROR ((AE_INFO, "Invalid handle %p [%s]",
+ Node, AcpiUtGetDescriptorName (Node)));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Check if this object is already attached */
+
+ if (Node->Object == Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Obj %p already installed in NameObj %p\n",
+ Object, Node));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* If null object, we will just install it */
+
+ if (!Object)
+ {
+ ObjDesc = NULL;
+ ObjectType = ACPI_TYPE_ANY;
+ }
+
+ /*
+ * If the source object is a namespace Node with an attached object,
+ * we will use that (attached) object
+ */
+ else if ((ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) &&
+ ((ACPI_NAMESPACE_NODE *) Object)->Object)
+ {
+ /*
+ * Value passed is a name handle and that name has a
+ * non-null value. Use that name's value and type.
+ */
+ ObjDesc = ((ACPI_NAMESPACE_NODE *) Object)->Object;
+ ObjectType = ((ACPI_NAMESPACE_NODE *) Object)->Type;
+ }
+
+ /*
+ * Otherwise, we will use the parameter object, but we must type
+ * it first
+ */
+ else
+ {
+ ObjDesc = (ACPI_OPERAND_OBJECT *) Object;
+
+ /* Use the given type */
+
+ ObjectType = Type;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
+ ObjDesc, Node, AcpiUtGetNodeName (Node)));
+
+ /* Detach an existing attached object if present */
+
+ if (Node->Object)
+ {
+ AcpiNsDetachObject (Node);
+ }
+
+ if (ObjDesc)
+ {
+ /*
+ * Must increment the new value's reference count
+ * (if it is an internal object)
+ */
+ AcpiUtAddReference (ObjDesc);
+
+ /*
+ * Handle objects with multiple descriptors - walk
+ * to the end of the descriptor list
+ */
+ LastObjDesc = ObjDesc;
+ while (LastObjDesc->Common.NextObject)
+ {
+ LastObjDesc = LastObjDesc->Common.NextObject;
+ }
+
+ /* Install the object at the front of the object list */
+
+ LastObjDesc->Common.NextObject = Node->Object;
+ }
+
+ Node->Type = (UINT8) ObjectType;
+ Node->Object = ObjDesc;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDetachObject
+ *
+ * PARAMETERS: Node - A Namespace node whose object will be detached
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Detach/delete an object associated with a namespace node.
+ * if the object is an allocated object, it is freed.
+ * Otherwise, the field is simply cleared.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsDetachObject (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE (NsDetachObject);
+
+
+ ObjDesc = Node->Object;
+
+ if (!ObjDesc ||
+ (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ return_VOID;
+ }
+
+ if (Node->Flags & ANOBJ_ALLOCATED_BUFFER)
+ {
+ /* Free the dynamic aml buffer */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_METHOD)
+ {
+ ACPI_FREE (ObjDesc->Method.AmlStart);
+ }
+ }
+
+ /* Clear the Node entry in all cases */
+
+ Node->Object = NULL;
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
+ {
+ /* Unlink object from front of possible object list */
+
+ Node->Object = ObjDesc->Common.NextObject;
+
+ /* Handle possible 2-descriptor object */
+
+ if (Node->Object &&
+ (Node->Object->Common.Type != ACPI_TYPE_LOCAL_DATA))
+ {
+ Node->Object = Node->Object->Common.NextObject;
+ }
+
+ /*
+ * Detach the object from any data objects (which are still held by
+ * the namespace node)
+ */
+ if (ObjDesc->Common.NextObject &&
+ ((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ ObjDesc->Common.NextObject = NULL;
+ }
+ }
+
+ /* Reset the node type to untyped */
+
+ Node->Type = ACPI_TYPE_ANY;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
+ Node, AcpiUtGetNodeName (Node), ObjDesc));
+
+ /* Remove one reference on the object (and all subobjects) */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetAttachedObject
+ *
+ * PARAMETERS: Node - Namespace node
+ *
+ * RETURN: Current value of the object field from the Node whose
+ * handle is passed
+ *
+ * DESCRIPTION: Obtain the object attached to a namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiNsGetAttachedObject (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_FUNCTION_TRACE_PTR (NsGetAttachedObject, Node);
+
+
+ if (!Node)
+ {
+ ACPI_WARNING ((AE_INFO, "Null Node ptr"));
+ return_PTR (NULL);
+ }
+
+ if (!Node->Object ||
+ ((ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_OPERAND) &&
+ (ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_NAMED)) ||
+ ((Node->Object)->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ return_PTR (NULL);
+ }
+
+ return_PTR (Node->Object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetSecondaryObject
+ *
+ * PARAMETERS: Node - Namespace node
+ *
+ * RETURN: Current value of the object field from the Node whose
+ * handle is passed.
+ *
+ * DESCRIPTION: Obtain a secondary object associated with a namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiNsGetSecondaryObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_FUNCTION_TRACE_PTR (NsGetSecondaryObject, ObjDesc);
+
+
+ if ((!ObjDesc) ||
+ (ObjDesc->Common.Type== ACPI_TYPE_LOCAL_DATA) ||
+ (!ObjDesc->Common.NextObject) ||
+ ((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ return_PTR (NULL);
+ }
+
+ return_PTR (ObjDesc->Common.NextObject);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsAttachData
+ *
+ * PARAMETERS: Node - Namespace node
+ * Handler - Handler to be associated with the data
+ * Data - Data to be attached
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Low-level attach data. Create and attach a Data object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsAttachData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler,
+ void *Data)
+{
+ ACPI_OPERAND_OBJECT *PrevObjDesc;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *DataDesc;
+
+
+ /* We only allow one attachment per handler */
+
+ PrevObjDesc = NULL;
+ ObjDesc = Node->Object;
+ while (ObjDesc)
+ {
+ if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ (ObjDesc->Data.Handler == Handler))
+ {
+ return (AE_ALREADY_EXISTS);
+ }
+
+ PrevObjDesc = ObjDesc;
+ ObjDesc = ObjDesc->Common.NextObject;
+ }
+
+ /* Create an internal object for the data */
+
+ DataDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_DATA);
+ if (!DataDesc)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ DataDesc->Data.Handler = Handler;
+ DataDesc->Data.Pointer = Data;
+
+ /* Install the data object */
+
+ if (PrevObjDesc)
+ {
+ PrevObjDesc->Common.NextObject = DataDesc;
+ }
+ else
+ {
+ Node->Object = DataDesc;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsDetachData
+ *
+ * PARAMETERS: Node - Namespace node
+ * Handler - Handler associated with the data
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
+ * is responsible for the actual data.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsDetachData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *PrevObjDesc;
+
+
+ PrevObjDesc = NULL;
+ ObjDesc = Node->Object;
+ while (ObjDesc)
+ {
+ if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ (ObjDesc->Data.Handler == Handler))
+ {
+ if (PrevObjDesc)
+ {
+ PrevObjDesc->Common.NextObject = ObjDesc->Common.NextObject;
+ }
+ else
+ {
+ Node->Object = ObjDesc->Common.NextObject;
+ }
+
+ AcpiUtRemoveReference (ObjDesc);
+ return (AE_OK);
+ }
+
+ PrevObjDesc = ObjDesc;
+ ObjDesc = ObjDesc->Common.NextObject;
+ }
+
+ return (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetAttachedData
+ *
+ * PARAMETERS: Node - Namespace node
+ * Handler - Handler associated with the data
+ * Data - Where the data is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Low level interface to obtain data previously associated with
+ * a namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsGetAttachedData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler,
+ void **Data)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ObjDesc = Node->Object;
+ while (ObjDesc)
+ {
+ if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
+ (ObjDesc->Data.Handler == Handler))
+ {
+ *Data = ObjDesc->Data.Pointer;
+ return (AE_OK);
+ }
+
+ ObjDesc = ObjDesc->Common.NextObject;
+ }
+
+ return (AE_NOT_FOUND);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsparse.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsparse.c
new file mode 100644
index 0000000000..a05567ff13
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsparse.c
@@ -0,0 +1,225 @@
+/******************************************************************************
+ *
+ * Module Name: nsparse - namespace interface to AML parser
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsparse")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: NsOneCompleteParse
+ *
+ * PARAMETERS: PassNumber - 1 or 2
+ * TableDesc - The table to be parsed.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsOneCompleteParse (
+ UINT32 PassNumber,
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode)
+{
+ ACPI_PARSE_OBJECT *ParseRoot;
+ ACPI_STATUS Status;
+ UINT32 AmlLength;
+ UINT8 *AmlStart;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_OWNER_ID OwnerId;
+
+
+ ACPI_FUNCTION_TRACE (NsOneCompleteParse);
+
+
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Table must consist of at least a complete header */
+
+ if (Table->Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ return_ACPI_STATUS (AE_BAD_HEADER);
+ }
+
+ AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
+ AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
+
+ Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Create and init a Root Node */
+
+ ParseRoot = AcpiPsCreateScopeOp (AmlStart);
+ if (!ParseRoot)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ AcpiPsFreeOp (ParseRoot);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL,
+ AmlStart, AmlLength, NULL, (UINT8) PassNumber);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /* Found OSDT table, enable the namespace override feature */
+
+ if (ACPI_COMPARE_NAME(Table->Signature, ACPI_SIG_OSDT) &&
+ PassNumber == ACPI_IMODE_LOAD_PASS1)
+ {
+ WalkState->NamespaceOverride = TRUE;
+ }
+
+ /* StartNode is the default location to load the table */
+
+ if (StartNode && StartNode != AcpiGbl_RootNode)
+ {
+ Status = AcpiDsScopeStackPush (StartNode, ACPI_TYPE_METHOD, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+ }
+
+ /* Parse the AML */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", PassNumber));
+ Status = AcpiPsParseAml (WalkState);
+
+Cleanup:
+ AcpiPsDeleteParseTree (ParseRoot);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsParseTable
+ *
+ * PARAMETERS: TableDesc - An ACPI table descriptor for table to parse
+ * StartNode - Where to enter the table into the namespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsParseTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsParseTable);
+
+
+ /*
+ * AML Parse, pass 1
+ *
+ * In this pass, we load most of the namespace. Control methods
+ * are not parsed until later. A parse tree is not created. Instead,
+ * each Parser Op subtree is deleted when it is finished. This saves
+ * a great deal of memory, and allows a small cache of parse objects
+ * to service the entire parse. The second pass of the parse then
+ * performs another complete parse of the AML.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
+ Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
+ TableIndex, StartNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * AML Parse, pass 2
+ *
+ * In this pass, we resolve forward references and other things
+ * that could not be completed during the first pass.
+ * Another complete parse of the AML is performed, but the
+ * overhead of this is compensated for by the fact that the
+ * parse objects are all cached.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
+ Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
+ TableIndex, StartNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nspredef.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nspredef.c
new file mode 100644
index 0000000000..d885e5ae4e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nspredef.c
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Module Name: nspredef - Validation of ACPI predefined methods and objects
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 ACPI_CREATE_PREDEFINED_TABLE
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nspredef")
+
+
+/*******************************************************************************
+ *
+ * This module validates predefined ACPI objects that appear in the namespace,
+ * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
+ * validation is to detect problems with BIOS-exposed predefined ACPI objects
+ * before the results are returned to the ACPI-related drivers.
+ *
+ * There are several areas that are validated:
+ *
+ * 1) The number of input arguments as defined by the method/object in the
+ * ASL is validated against the ACPI specification.
+ * 2) The type of the return object (if any) is validated against the ACPI
+ * specification.
+ * 3) For returned package objects, the count of package elements is
+ * validated, as well as the type of each package element. Nested
+ * packages are supported.
+ *
+ * For any problems found, a warning message is issued.
+ *
+ ******************************************************************************/
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsCheckReference (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *ReturnObject);
+
+static UINT32
+AcpiNsGetBitmappedType (
+ ACPI_OPERAND_OBJECT *ReturnObject);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckReturnValue
+ *
+ * PARAMETERS: Node - Namespace node for the method/object
+ * Info - Method execution information block
+ * UserParamCount - Number of parameters actually passed
+ * ReturnStatus - Status from the object evaluation
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check the value returned from a predefined name.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsCheckReturnValue (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 UserParamCount,
+ ACPI_STATUS ReturnStatus,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_STATUS Status;
+ const ACPI_PREDEFINED_INFO *Predefined;
+
+
+ /* If not a predefined name, we cannot validate the return object */
+
+ Predefined = Info->Predefined;
+ if (!Predefined)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * If the method failed or did not actually return an object, we cannot
+ * validate the return object
+ */
+ if ((ReturnStatus != AE_OK) &&
+ (ReturnStatus != AE_CTRL_RETURN_VALUE))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Return value validation and possible repair.
+ *
+ * 1) Don't perform return value validation/repair if this feature
+ * has been disabled via a global option.
+ *
+ * 2) We have a return value, but if one wasn't expected, just exit,
+ * this is not a problem. For example, if the "Implicit Return"
+ * feature is enabled, methods will always return a value.
+ *
+ * 3) If the return value can be of any type, then we cannot perform
+ * any validation, just exit.
+ */
+ if (AcpiGbl_DisableAutoRepair ||
+ (!Predefined->Info.ExpectedBtypes) ||
+ (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Check that the type of the main return object is what is expected
+ * for this predefined name
+ */
+ Status = AcpiNsCheckObjectType (Info, ReturnObjectPtr,
+ Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
+
+ /*
+ *
+ * 4) If there is no return value and it is optional, just return
+ * AE_OK (_WAK).
+ */
+ if (!(*ReturnObjectPtr))
+ {
+ goto Exit;
+ }
+
+ /*
+ * For returned Package objects, check the type of all sub-objects.
+ * Note: Package may have been newly created by call above.
+ */
+ if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ Info->ParentPackage = *ReturnObjectPtr;
+ Status = AcpiNsCheckPackage (Info, ReturnObjectPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ /* We might be able to fix some errors */
+
+ if ((Status != AE_AML_OPERAND_TYPE) &&
+ (Status != AE_AML_OPERAND_VALUE))
+ {
+ goto Exit;
+ }
+ }
+ }
+
+ /*
+ * The return object was OK, or it was successfully repaired above.
+ * Now make some additional checks such as verifying that package
+ * objects are sorted correctly (if required) or buffer objects have
+ * the correct data width (bytes vs. dwords). These repairs are
+ * performed on a per-name basis, i.e., the code is specific to
+ * particular predefined names.
+ */
+ Status = AcpiNsComplexRepairs (Info, Node, Status, ReturnObjectPtr);
+
+Exit:
+ /*
+ * If the object validation failed or if we successfully repaired one
+ * or more objects, mark the parent node to suppress further warning
+ * messages during the next evaluation of the same method/object.
+ */
+ if (ACPI_FAILURE (Status) ||
+ (Info->ReturnFlags & ACPI_OBJECT_REPAIRED))
+ {
+ Node->Flags |= ANOBJ_EVALUATED;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckObjectType
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ * ExpectedBtypes - Bitmap of expected return type(s)
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check the type of the return object against the expected object
+ * type(s). Use of Btype allows multiple expected object types.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsCheckObjectType (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_STATUS Status = AE_OK;
+ char TypeBuffer[48]; /* Room for 5 types */
+
+
+ /* A Namespace node should not get here, but make sure */
+
+ if (ReturnObject &&
+ ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Invalid return type - Found a Namespace node [%4.4s] type %s",
+ ReturnObject->Node.Name.Ascii,
+ AcpiUtGetTypeName (ReturnObject->Node.Type)));
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
+ * The bitmapped type allows multiple possible return types.
+ *
+ * Note, the cases below must handle all of the possible types returned
+ * from all of the predefined names (including elements of returned
+ * packages)
+ */
+ Info->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject);
+ if (Info->ReturnBtype == ACPI_RTYPE_ANY)
+ {
+ /* Not one of the supported objects, must be incorrect */
+ goto TypeErrorExit;
+ }
+
+ /* For reference objects, check that the reference type is correct */
+
+ if ((Info->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE)
+ {
+ Status = AcpiNsCheckReference (Info, ReturnObject);
+ return (Status);
+ }
+
+ /* Attempt simple repair of the returned object if necessary */
+
+ Status = AcpiNsSimpleRepair (Info, ExpectedBtypes,
+ PackageIndex, ReturnObjectPtr);
+ if (ACPI_SUCCESS (Status))
+ {
+ return (AE_OK); /* Successful repair */
+ }
+
+
+TypeErrorExit:
+
+ /* Create a string with all expected types for this predefined object */
+
+ AcpiUtGetExpectedReturnTypes (TypeBuffer, ExpectedBtypes);
+
+ if (!ReturnObject)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Expected return object of type %s",
+ TypeBuffer));
+ }
+ else if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return type mismatch - found %s, expected %s",
+ AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
+ }
+ else
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return Package type mismatch at index %u - "
+ "found %s, expected %s", PackageIndex,
+ AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
+ }
+
+ return (AE_AML_OPERAND_TYPE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckReference
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObject - Object returned from the evaluation of a
+ * method or object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check a returned reference object for the correct reference
+ * type. The only reference type that can be returned from a
+ * predefined method is a named reference. All others are invalid.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckReference (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *ReturnObject)
+{
+
+ /*
+ * Check the reference object for the correct reference type (opcode).
+ * The only type of reference that can be converted to an ACPI_OBJECT is
+ * a reference to a named object (reference class: NAME)
+ */
+ if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
+ {
+ return (AE_OK);
+ }
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return type mismatch - unexpected reference object type [%s] %2.2X",
+ AcpiUtGetReferenceName (ReturnObject),
+ ReturnObject->Reference.Class));
+
+ return (AE_AML_OPERAND_TYPE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetBitmappedType
+ *
+ * PARAMETERS: ReturnObject - Object returned from method/obj evaluation
+ *
+ * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object
+ * type is not supported. ACPI_RTYPE_NONE indicates that no
+ * object was returned (ReturnObject is NULL).
+ *
+ * DESCRIPTION: Convert object type into a bitmapped object return type.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiNsGetBitmappedType (
+ ACPI_OPERAND_OBJECT *ReturnObject)
+{
+ UINT32 ReturnBtype;
+
+
+ if (!ReturnObject)
+ {
+ return (ACPI_RTYPE_NONE);
+ }
+
+ /* Map ACPI_OBJECT_TYPE to internal bitmapped type */
+
+ switch (ReturnObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ ReturnBtype = ACPI_RTYPE_INTEGER;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ReturnBtype = ACPI_RTYPE_BUFFER;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ ReturnBtype = ACPI_RTYPE_STRING;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ReturnBtype = ACPI_RTYPE_PACKAGE;
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ ReturnBtype = ACPI_RTYPE_REFERENCE;
+ break;
+
+ default:
+
+ /* Not one of the supported objects, must be incorrect */
+
+ ReturnBtype = ACPI_RTYPE_ANY;
+ break;
+ }
+
+ return (ReturnBtype);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsprepkg.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsprepkg.c
new file mode 100644
index 0000000000..905fe648b1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsprepkg.c
@@ -0,0 +1,684 @@
+/******************************************************************************
+ *
+ * Module Name: nsprepkg - Validation of package objects for predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsprepkg")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsCheckPackageList (
+ ACPI_EVALUATE_INFO *Info,
+ const ACPI_PREDEFINED_INFO *Package,
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT32 Count);
+
+static ACPI_STATUS
+AcpiNsCheckPackageElements (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT8 Type1,
+ UINT32 Count1,
+ UINT8 Type2,
+ UINT32 Count2,
+ UINT32 StartIndex);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckPackage
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check a returned package object for the correct count and
+ * correct type of all sub-objects.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsCheckPackage (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ const ACPI_PREDEFINED_INFO *Package;
+ ACPI_OPERAND_OBJECT **Elements;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 ExpectedCount;
+ UINT32 Count;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsCheckPackage);
+
+
+ /* The package info for this name is in the next table entry */
+
+ Package = Info->Predefined + 1;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "%s Validating return Package of Type %X, Count %X\n",
+ Info->FullPathname, Package->RetInfo.Type,
+ ReturnObject->Package.Count));
+
+ /*
+ * For variable-length Packages, we can safely remove all embedded
+ * and trailing NULL package elements
+ */
+ AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject);
+
+ /* Extract package count and elements array */
+
+ Elements = ReturnObject->Package.Elements;
+ Count = ReturnObject->Package.Count;
+
+ /*
+ * Most packages must have at least one element. The only exception
+ * is the variable-length package (ACPI_PTYPE1_VAR).
+ */
+ if (!Count)
+ {
+ if (Package->RetInfo.Type == ACPI_PTYPE1_VAR)
+ {
+ return (AE_OK);
+ }
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return Package has no elements (empty)"));
+
+ return (AE_AML_OPERAND_VALUE);
+ }
+
+ /*
+ * Decode the type of the expected package contents
+ *
+ * PTYPE1 packages contain no subpackages
+ * PTYPE2 packages contain subpackages
+ */
+ switch (Package->RetInfo.Type)
+ {
+ case ACPI_PTYPE1_FIXED:
+ /*
+ * The package count is fixed and there are no subpackages
+ *
+ * If package is too small, exit.
+ * If package is larger than expected, issue warning but continue
+ */
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+ else if (Count > ExpectedCount)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Return Package is larger than needed - "
+ "found %u, expected %u\n",
+ Info->FullPathname, Count, ExpectedCount));
+ }
+
+ /* Validate all elements of the returned package */
+
+ Status = AcpiNsCheckPackageElements (Info, Elements,
+ Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
+ break;
+
+ case ACPI_PTYPE1_VAR:
+ /*
+ * The package count is variable, there are no subpackages, and all
+ * elements must be of the same type
+ */
+ for (i = 0; i < Count; i++)
+ {
+ Status = AcpiNsCheckObjectType (Info, Elements,
+ Package->RetInfo.ObjectType1, i);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ Elements++;
+ }
+ break;
+
+ case ACPI_PTYPE1_OPTION:
+ /*
+ * The package count is variable, there are no subpackages. There are
+ * a fixed number of required elements, and a variable number of
+ * optional elements.
+ *
+ * Check if package is at least as large as the minimum required
+ */
+ ExpectedCount = Package->RetInfo3.Count;
+ if (Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ /* Variable number of sub-objects */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (i < Package->RetInfo3.Count)
+ {
+ /* These are the required package elements (0, 1, or 2) */
+
+ Status = AcpiNsCheckObjectType (Info, Elements,
+ Package->RetInfo3.ObjectType[i], i);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* These are the optional package elements */
+
+ Status = AcpiNsCheckObjectType (Info, Elements,
+ Package->RetInfo3.TailObjectType, i);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ Elements++;
+ }
+ break;
+
+ case ACPI_PTYPE2_REV_FIXED:
+
+ /* First element is the (Integer) revision */
+
+ Status = AcpiNsCheckObjectType (Info, Elements,
+ ACPI_RTYPE_INTEGER, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Elements++;
+ Count--;
+
+ /* Examine the subpackages */
+
+ Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+ break;
+
+ case ACPI_PTYPE2_PKG_COUNT:
+
+ /* First element is the (Integer) count of subpackages to follow */
+
+ Status = AcpiNsCheckObjectType (Info, Elements,
+ ACPI_RTYPE_INTEGER, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Count cannot be larger than the parent package length, but allow it
+ * to be smaller. The >= accounts for the Integer above.
+ */
+ ExpectedCount = (UINT32) (*Elements)->Integer.Value;
+ if (ExpectedCount >= Count)
+ {
+ goto PackageTooSmall;
+ }
+
+ Count = ExpectedCount;
+ Elements++;
+
+ /* Examine the subpackages */
+
+ Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+ break;
+
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_FIXED:
+ case ACPI_PTYPE2_MIN:
+ case ACPI_PTYPE2_COUNT:
+ case ACPI_PTYPE2_FIX_VAR:
+ /*
+ * These types all return a single Package that consists of a
+ * variable number of subpackages.
+ *
+ * First, ensure that the first element is a subpackage. If not,
+ * the BIOS may have incorrectly returned the object as a single
+ * package instead of a Package of Packages (a common error if
+ * there is only one entry). We may be able to repair this by
+ * wrapping the returned Package with a new outer Package.
+ */
+ if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
+ {
+ /* Create the new outer package and populate it */
+
+ Status = AcpiNsWrapWithPackage (Info, ReturnObject, ReturnObjectPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Update locals to point to the new package (of 1 element) */
+
+ ReturnObject = *ReturnObjectPtr;
+ Elements = ReturnObject->Package.Elements;
+ Count = 1;
+ }
+
+ /* Examine the subpackages */
+
+ Status = AcpiNsCheckPackageList (Info, Package, Elements, Count);
+ break;
+
+ case ACPI_PTYPE2_VAR_VAR:
+ /*
+ * Returns a variable list of packages, each with a variable list
+ * of objects.
+ */
+ break;
+
+ case ACPI_PTYPE2_UUID_PAIR:
+
+ /* The package must contain pairs of (UUID + type) */
+
+ if (Count & 1)
+ {
+ ExpectedCount = Count + 1;
+ goto PackageTooSmall;
+ }
+
+ while (Count > 0)
+ {
+ Status = AcpiNsCheckObjectType(Info, Elements,
+ Package->RetInfo.ObjectType1, 0);
+ if (ACPI_FAILURE(Status))
+ {
+ return (Status);
+ }
+
+ /* Validate length of the UUID buffer */
+
+ if ((*Elements)->Buffer.Length != 16)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
+ Info->NodeFlags, "Invalid length for UUID Buffer"));
+ return (AE_AML_OPERAND_VALUE);
+ }
+
+ Status = AcpiNsCheckObjectType(Info, Elements + 1,
+ Package->RetInfo.ObjectType2, 0);
+ if (ACPI_FAILURE(Status))
+ {
+ return (Status);
+ }
+
+ Elements += 2;
+ Count -= 2;
+ }
+ break;
+
+ default:
+
+ /* Should not get here if predefined info table is correct */
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Invalid internal return type in table entry: %X",
+ Package->RetInfo.Type));
+
+ return (AE_AML_INTERNAL);
+ }
+
+ return (Status);
+
+
+PackageTooSmall:
+
+ /* Error exit for the case with an incorrect package count */
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return Package is too small - found %u elements, expected %u",
+ Count, ExpectedCount));
+
+ return (AE_AML_OPERAND_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckPackageList
+ *
+ * PARAMETERS: Info - Method execution information block
+ * Package - Pointer to package-specific info for method
+ * Elements - Element list of parent package. All elements
+ * of this list should be of type Package.
+ * Count - Count of subpackages
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Examine a list of subpackages
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckPackageList (
+ ACPI_EVALUATE_INFO *Info,
+ const ACPI_PREDEFINED_INFO *Package,
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT32 Count)
+{
+ ACPI_OPERAND_OBJECT *SubPackage;
+ ACPI_OPERAND_OBJECT **SubElements;
+ ACPI_STATUS Status;
+ UINT32 ExpectedCount;
+ UINT32 i;
+ UINT32 j;
+
+
+ /*
+ * Validate each subpackage in the parent Package
+ *
+ * NOTE: assumes list of subpackages contains no NULL elements.
+ * Any NULL elements should have been removed by earlier call
+ * to AcpiNsRemoveNullElements.
+ */
+ for (i = 0; i < Count; i++)
+ {
+ SubPackage = *Elements;
+ SubElements = SubPackage->Package.Elements;
+ Info->ParentPackage = SubPackage;
+
+ /* Each sub-object must be of type Package */
+
+ Status = AcpiNsCheckObjectType (Info, &SubPackage,
+ ACPI_RTYPE_PACKAGE, i);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Examine the different types of expected subpackages */
+
+ Info->ParentPackage = SubPackage;
+ switch (Package->RetInfo.Type)
+ {
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_PKG_COUNT:
+ case ACPI_PTYPE2_REV_FIXED:
+
+ /* Each subpackage has a fixed number of elements */
+
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (SubPackage->Package.Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ Status = AcpiNsCheckPackageElements (Info, SubElements,
+ Package->RetInfo.ObjectType1,
+ Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2,
+ Package->RetInfo.Count2, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_PTYPE2_FIX_VAR:
+ /*
+ * Each subpackage has a fixed number of elements and an
+ * optional element
+ */
+ ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
+ if (SubPackage->Package.Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ Status = AcpiNsCheckPackageElements (Info, SubElements,
+ Package->RetInfo.ObjectType1,
+ Package->RetInfo.Count1,
+ Package->RetInfo.ObjectType2,
+ SubPackage->Package.Count - Package->RetInfo.Count1, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_PTYPE2_VAR_VAR:
+ /*
+ * Each subpackage has a fixed or variable number of elements
+ */
+ break;
+
+ case ACPI_PTYPE2_FIXED:
+
+ /* Each subpackage has a fixed length */
+
+ ExpectedCount = Package->RetInfo2.Count;
+ if (SubPackage->Package.Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ /* Check the type of each subpackage element */
+
+ for (j = 0; j < ExpectedCount; j++)
+ {
+ Status = AcpiNsCheckObjectType (Info, &SubElements[j],
+ Package->RetInfo2.ObjectType[j], j);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ break;
+
+ case ACPI_PTYPE2_MIN:
+
+ /* Each subpackage has a variable but minimum length */
+
+ ExpectedCount = Package->RetInfo.Count1;
+ if (SubPackage->Package.Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+
+ /* Check the type of each subpackage element */
+
+ Status = AcpiNsCheckPackageElements (Info, SubElements,
+ Package->RetInfo.ObjectType1,
+ SubPackage->Package.Count, 0, 0, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_PTYPE2_COUNT:
+ /*
+ * First element is the (Integer) count of elements, including
+ * the count field (the ACPI name is NumElements)
+ */
+ Status = AcpiNsCheckObjectType (Info, SubElements,
+ ACPI_RTYPE_INTEGER, 0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Make sure package is large enough for the Count and is
+ * is as large as the minimum size
+ */
+ ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
+ if (SubPackage->Package.Count < ExpectedCount)
+ {
+ goto PackageTooSmall;
+ }
+ if (SubPackage->Package.Count < Package->RetInfo.Count1)
+ {
+ ExpectedCount = Package->RetInfo.Count1;
+ goto PackageTooSmall;
+ }
+ if (ExpectedCount == 0)
+ {
+ /*
+ * Either the NumEntries element was originally zero or it was
+ * a NULL element and repaired to an Integer of value zero.
+ * In either case, repair it by setting NumEntries to be the
+ * actual size of the subpackage.
+ */
+ ExpectedCount = SubPackage->Package.Count;
+ (*SubElements)->Integer.Value = ExpectedCount;
+ }
+
+ /* Check the type of each subpackage element */
+
+ Status = AcpiNsCheckPackageElements (Info, (SubElements + 1),
+ Package->RetInfo.ObjectType1,
+ (ExpectedCount - 1), 0, 0, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ default: /* Should not get here, type was validated by caller */
+
+ return (AE_AML_INTERNAL);
+ }
+
+ Elements++;
+ }
+
+ return (AE_OK);
+
+
+PackageTooSmall:
+
+ /* The subpackage count was smaller than required */
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Return SubPackage[%u] is too small - found %u elements, expected %u",
+ i, SubPackage->Package.Count, ExpectedCount));
+
+ return (AE_AML_OPERAND_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckPackageElements
+ *
+ * PARAMETERS: Info - Method execution information block
+ * Elements - Pointer to the package elements array
+ * Type1 - Object type for first group
+ * Count1 - Count for first group
+ * Type2 - Object type for second group
+ * Count2 - Count for second group
+ * StartIndex - Start of the first group of elements
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check that all elements of a package are of the correct object
+ * type. Supports up to two groups of different object types.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckPackageElements (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT8 Type1,
+ UINT32 Count1,
+ UINT8 Type2,
+ UINT32 Count2,
+ UINT32 StartIndex)
+{
+ ACPI_OPERAND_OBJECT **ThisElement = Elements;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /*
+ * Up to two groups of package elements are supported by the data
+ * structure. All elements in each group must be of the same type.
+ * The second group can have a count of zero.
+ */
+ for (i = 0; i < Count1; i++)
+ {
+ Status = AcpiNsCheckObjectType (Info, ThisElement,
+ Type1, i + StartIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ ThisElement++;
+ }
+
+ for (i = 0; i < Count2; i++)
+ {
+ Status = AcpiNsCheckObjectType (Info, ThisElement,
+ Type2, (i + Count1 + StartIndex));
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ ThisElement++;
+ }
+
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair.c
new file mode 100644
index 0000000000..b4c2c99b37
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair.c
@@ -0,0 +1,630 @@
+/******************************************************************************
+ *
+ * Module Name: nsrepair - Repair for objects returned by predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+#include <contrib/dev/acpica/include/amlresrc.h>
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsrepair")
+
+
+/*******************************************************************************
+ *
+ * This module attempts to repair or convert objects returned by the
+ * predefined methods to an object type that is expected, as per the ACPI
+ * specification. The need for this code is dictated by the many machines that
+ * return incorrect types for the standard predefined methods. Performing these
+ * conversions here, in one place, eliminates the need for individual ACPI
+ * device drivers to do the same. Note: Most of these conversions are different
+ * than the internal object conversion routines used for implicit object
+ * conversion.
+ *
+ * The following conversions can be performed as necessary:
+ *
+ * Integer -> String
+ * Integer -> Buffer
+ * String -> Integer
+ * String -> Buffer
+ * Buffer -> Integer
+ * Buffer -> String
+ * Buffer -> Package of Integers
+ * Package -> Package of one Package
+ *
+ * Additional conversions that are available:
+ * Convert a null return or zero return value to an EndTag descriptor
+ * Convert an ASCII string to a Unicode buffer
+ *
+ * An incorrect standalone object is wrapped with required outer package
+ *
+ * Additional possible repairs:
+ * Required package elements that are NULL replaced by Integer/String/Buffer
+ *
+ ******************************************************************************/
+
+
+/* Local prototypes */
+
+static const ACPI_SIMPLE_REPAIR_INFO *
+AcpiNsMatchSimpleRepair (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 ReturnBtype,
+ UINT32 PackageIndex);
+
+
+/*
+ * Special but simple repairs for some names.
+ *
+ * 2nd argument: Unexpected types that can be repaired
+ */
+static const ACPI_SIMPLE_REPAIR_INFO AcpiObjectRepairInfo[] =
+{
+ /* Resource descriptor conversions */
+
+ { "_CRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE,
+ ACPI_NOT_PACKAGE_ELEMENT,
+ AcpiNsConvertToResource },
+ { "_DMA", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE,
+ ACPI_NOT_PACKAGE_ELEMENT,
+ AcpiNsConvertToResource },
+ { "_PRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE,
+ ACPI_NOT_PACKAGE_ELEMENT,
+ AcpiNsConvertToResource },
+
+ /* Unicode conversions */
+
+ { "_MLS", ACPI_RTYPE_STRING, 1,
+ AcpiNsConvertToUnicode },
+ { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER,
+ ACPI_NOT_PACKAGE_ELEMENT,
+ AcpiNsConvertToUnicode },
+ { {0,0,0,0}, 0, 0, NULL } /* Table terminator */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsSimpleRepair
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ExpectedBtypes - Object types expected
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if repair was successful.
+ *
+ * DESCRIPTION: Attempt to repair/convert a return object of a type that was
+ * not expected.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsSimpleRepair (
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT *NewObject = NULL;
+ ACPI_STATUS Status;
+ const ACPI_SIMPLE_REPAIR_INFO *Predefined;
+
+
+ ACPI_FUNCTION_NAME (NsSimpleRepair);
+
+
+ /*
+ * Special repairs for certain names that are in the repair table.
+ * Check if this name is in the list of repairable names.
+ */
+ Predefined = AcpiNsMatchSimpleRepair (Info->Node,
+ Info->ReturnBtype, PackageIndex);
+ if (Predefined)
+ {
+ if (!ReturnObject)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
+ ACPI_WARN_ALWAYS, "Missing expected return value"));
+ }
+
+ Status = Predefined->ObjectConverter (ReturnObject, &NewObject);
+ if (ACPI_FAILURE (Status))
+ {
+ /* A fatal error occurred during a conversion */
+
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "During return object analysis"));
+ return (Status);
+ }
+ if (NewObject)
+ {
+ goto ObjectRepaired;
+ }
+ }
+
+ /*
+ * Do not perform simple object repair unless the return type is not
+ * expected.
+ */
+ if (Info->ReturnBtype & ExpectedBtypes)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * At this point, we know that the type of the returned object was not
+ * one of the expected types for this predefined name. Attempt to
+ * repair the object by converting it to one of the expected object
+ * types for this predefined name.
+ */
+
+ /*
+ * If there is no return value, check if we require a return value for
+ * this predefined name. Either one return value is expected, or none,
+ * for both methods and other objects.
+ *
+ * Try to fix if there was no return object. Warning if failed to fix.
+ */
+ if (!ReturnObject)
+ {
+ if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE)))
+ {
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
+ ACPI_WARN_ALWAYS, "Found unexpected NULL package element"));
+
+ Status = AcpiNsRepairNullElement (Info, ExpectedBtypes,
+ PackageIndex, ReturnObjectPtr);
+ if (ACPI_SUCCESS (Status))
+ {
+ return (AE_OK); /* Repair was successful */
+ }
+ }
+ else
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname,
+ ACPI_WARN_ALWAYS, "Missing expected return value"));
+ }
+
+ return (AE_AML_NO_RETURN_VALUE);
+ }
+ }
+
+ if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
+ {
+ Status = AcpiNsConvertToInteger (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_STRING)
+ {
+ Status = AcpiNsConvertToString (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
+ {
+ Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
+ {
+ /*
+ * A package is expected. We will wrap the existing object with a
+ * new package object. It is often the case that if a variable-length
+ * package is required, but there is only a single object needed, the
+ * BIOS will return that object instead of wrapping it with a Package
+ * object. Note: after the wrapping, the package will be validated
+ * for correct contents (expected object type or types).
+ */
+ Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * The original object just had its reference count
+ * incremented for being inserted into the new package.
+ */
+ *ReturnObjectPtr = NewObject; /* New Package object */
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+ }
+ }
+
+ /* We cannot repair this object */
+
+ return (AE_AML_OPERAND_TYPE);
+
+
+ObjectRepaired:
+
+ /* Object was successfully repaired */
+
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ /*
+ * The original object is a package element. We need to
+ * decrement the reference count of the original object,
+ * for removing it from the package.
+ *
+ * However, if the original object was just wrapped with a
+ * package object as part of the repair, we don't need to
+ * change the reference count.
+ */
+ if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED))
+ {
+ NewObject->Common.ReferenceCount =
+ ReturnObject->Common.ReferenceCount;
+
+ if (ReturnObject->Common.ReferenceCount > 1)
+ {
+ ReturnObject->Common.ReferenceCount--;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Converted %s to expected %s at Package index %u\n",
+ Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject), PackageIndex));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Converted %s to expected %s\n",
+ Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject)));
+ }
+
+ /* Delete old object, install the new return object */
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = NewObject;
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsMatchSimpleRepair
+ *
+ * PARAMETERS: Node - Namespace node for the method/object
+ * ReturnBtype - Object type that was returned
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ *
+ * RETURN: Pointer to entry in repair table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the repairable object list.
+ *
+ *****************************************************************************/
+
+static const ACPI_SIMPLE_REPAIR_INFO *
+AcpiNsMatchSimpleRepair (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 ReturnBtype,
+ UINT32 PackageIndex)
+{
+ const ACPI_SIMPLE_REPAIR_INFO *ThisName;
+
+
+ /* Search info table for a repairable predefined method/object name */
+
+ ThisName = AcpiObjectRepairInfo;
+ while (ThisName->ObjectConverter)
+ {
+ if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
+ {
+ /* Check if we can actually repair this name/type combination */
+
+ if ((ReturnBtype & ThisName->UnexpectedBtypes) &&
+ (PackageIndex == ThisName->PackageIndex))
+ {
+ return (ThisName);
+ }
+
+ return (NULL);
+ }
+ ThisName++;
+ }
+
+ return (NULL); /* Name was not found in the repair table */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepairNullElement
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ExpectedBtypes - Object types expected
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if repair was successful.
+ *
+ * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsRepairNullElement (
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT *NewObject;
+
+
+ ACPI_FUNCTION_NAME (NsRepairNullElement);
+
+
+ /* No repair needed if return object is non-NULL */
+
+ if (ReturnObject)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Attempt to repair a NULL element of a Package object. This applies to
+ * predefined names that return a fixed-length package and each element
+ * is required. It does not apply to variable-length packages where NULL
+ * elements are allowed, especially at the end of the package.
+ */
+ if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
+ {
+ /* Need an Integer - create a zero-value integer */
+
+ NewObject = AcpiUtCreateIntegerObject ((UINT64) 0);
+ }
+ else if (ExpectedBtypes & ACPI_RTYPE_STRING)
+ {
+ /* Need a String - create a NULL string */
+
+ NewObject = AcpiUtCreateStringObject (0);
+ }
+ else if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
+ {
+ /* Need a Buffer - create a zero-length buffer */
+
+ NewObject = AcpiUtCreateBufferObject (0);
+ }
+ else
+ {
+ /* Error for all other expected types */
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Set the reference count according to the parent Package object */
+
+ NewObject->Common.ReferenceCount = Info->ParentPackage->Common.ReferenceCount;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Converted NULL package element to expected %s at index %u\n",
+ Info->FullPathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex));
+
+ *ReturnObjectPtr = NewObject;
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRemoveNullElements
+ *
+ * PARAMETERS: Info - Method execution information block
+ * PackageType - An AcpiReturnPackageTypes value
+ * ObjDesc - A Package object
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Remove all NULL package elements from packages that contain
+ * a variable number of subpackages. For these types of
+ * packages, NULL elements can be safely removed.
+ *
+ *****************************************************************************/
+
+void
+AcpiNsRemoveNullElements (
+ ACPI_EVALUATE_INFO *Info,
+ UINT8 PackageType,
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_OPERAND_OBJECT **Source;
+ ACPI_OPERAND_OBJECT **Dest;
+ UINT32 Count;
+ UINT32 NewCount;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRemoveNullElements);
+
+
+ /*
+ * We can safely remove all NULL elements from these package types:
+ * PTYPE1_VAR packages contain a variable number of simple data types.
+ * PTYPE2 packages contain a variable number of subpackages.
+ */
+ switch (PackageType)
+ {
+ case ACPI_PTYPE1_VAR:
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_COUNT:
+ case ACPI_PTYPE2_PKG_COUNT:
+ case ACPI_PTYPE2_FIXED:
+ case ACPI_PTYPE2_MIN:
+ case ACPI_PTYPE2_REV_FIXED:
+ case ACPI_PTYPE2_FIX_VAR:
+ break;
+
+ default:
+ case ACPI_PTYPE2_VAR_VAR:
+ case ACPI_PTYPE1_FIXED:
+ case ACPI_PTYPE1_OPTION:
+ return;
+ }
+
+ Count = ObjDesc->Package.Count;
+ NewCount = Count;
+
+ Source = ObjDesc->Package.Elements;
+ Dest = Source;
+
+ /* Examine all elements of the package object, remove nulls */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (!*Source)
+ {
+ NewCount--;
+ }
+ else
+ {
+ *Dest = *Source;
+ Dest++;
+ }
+ Source++;
+ }
+
+ /* Update parent package if any null elements were removed */
+
+ if (NewCount < Count)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Found and removed %u NULL elements\n",
+ Info->FullPathname, (Count - NewCount)));
+
+ /* NULL terminate list and update the package count */
+
+ *Dest = NULL;
+ ObjDesc->Package.Count = NewCount;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsWrapWithPackage
+ *
+ * PARAMETERS: Info - Method execution information block
+ * OriginalObject - Pointer to the object to repair.
+ * ObjDescPtr - The new package object is returned here
+ *
+ * RETURN: Status, new object in *ObjDescPtr
+ *
+ * DESCRIPTION: Repair a common problem with objects that are defined to
+ * return a variable-length Package of sub-objects. If there is
+ * only one sub-object, some BIOS code mistakenly simply declares
+ * the single object instead of a Package with one sub-object.
+ * This function attempts to repair this error by wrapping a
+ * Package object around the original object, creating the
+ * correct and expected Package with one sub-object.
+ *
+ * Names that can be repaired in this manner include:
+ * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS,
+ * _BCL, _DOD, _FIX, _Sx
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsWrapWithPackage (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_OPERAND_OBJECT *PkgObjDesc;
+
+
+ ACPI_FUNCTION_NAME (NsWrapWithPackage);
+
+
+ /*
+ * Create the new outer package and populate it. The new package will
+ * have a single element, the lone sub-object.
+ */
+ PkgObjDesc = AcpiUtCreatePackageObject (1);
+ if (!PkgObjDesc)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ PkgObjDesc->Package.Elements[0] = OriginalObject;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Wrapped %s with expected Package object\n",
+ Info->FullPathname, AcpiUtGetObjectTypeName (OriginalObject)));
+
+ /* Return the new object in the object pointer */
+
+ *ObjDescPtr = PkgObjDesc;
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair2.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
new file mode 100644
index 0000000000..24ac8b48f0
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
@@ -0,0 +1,1074 @@
+/******************************************************************************
+ *
+ * Module Name: nsrepair2 - Repair for objects returned by specific
+ * predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsrepair2")
+
+
+/*
+ * Information structure and handler for ACPI predefined names that can
+ * be repaired on a per-name basis.
+ */
+typedef
+ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+typedef struct acpi_repair_info
+{
+ char Name[ACPI_NAME_SIZE];
+ ACPI_REPAIR_FUNCTION RepairFunction;
+
+} ACPI_REPAIR_INFO;
+
+
+/* Local prototypes */
+
+static const ACPI_REPAIR_INFO *
+AcpiNsMatchComplexRepair (
+ ACPI_NAMESPACE_NODE *Node);
+
+static ACPI_STATUS
+AcpiNsRepair_ALR (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_CID (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_CST (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_FDE (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_HID (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_PRT (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_PSS (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsRepair_TSS (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
+AcpiNsCheckSortedList (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *ReturnObject,
+ UINT32 StartIndex,
+ UINT32 ExpectedCount,
+ UINT32 SortIndex,
+ UINT8 SortDirection,
+ char *SortKeyName);
+
+/* Values for SortDirection above */
+
+#define ACPI_SORT_ASCENDING 0
+#define ACPI_SORT_DESCENDING 1
+
+static void
+AcpiNsRemoveElement (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Index);
+
+static void
+AcpiNsSortList (
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT32 Count,
+ UINT32 Index,
+ UINT8 SortDirection);
+
+
+/*
+ * This table contains the names of the predefined methods for which we can
+ * perform more complex repairs.
+ *
+ * As necessary:
+ *
+ * _ALR: Sort the list ascending by AmbientIlluminance
+ * _CID: Strings: uppercase all, remove any leading asterisk
+ * _CST: Sort the list ascending by C state type
+ * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _HID: Strings: uppercase all, remove any leading asterisk
+ * _PRT: Fix reversed SourceName and SourceIndex
+ * _PSS: Sort the list descending by Power
+ * _TSS: Sort the list descending by Power
+ *
+ * Names that must be packages, but cannot be sorted:
+ *
+ * _BCL: Values are tied to the Package index where they appear, and cannot
+ * be moved or sorted. These index values are used for _BQC and _BCM.
+ * However, we can fix the case where a buffer is returned, by converting
+ * it to a Package of integers.
+ */
+static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
+{
+ {"_ALR", AcpiNsRepair_ALR},
+ {"_CID", AcpiNsRepair_CID},
+ {"_CST", AcpiNsRepair_CST},
+ {"_FDE", AcpiNsRepair_FDE},
+ {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
+ {"_HID", AcpiNsRepair_HID},
+ {"_PRT", AcpiNsRepair_PRT},
+ {"_PSS", AcpiNsRepair_PSS},
+ {"_TSS", AcpiNsRepair_TSS},
+ {{0,0,0,0}, NULL} /* Table terminator */
+};
+
+
+#define ACPI_FDE_FIELD_COUNT 5
+#define ACPI_FDE_BYTE_BUFFER_SIZE 5
+#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsComplexRepairs
+ *
+ * PARAMETERS: Info - Method execution information block
+ * Node - Namespace node for the method/object
+ * ValidateStatus - Original status of earlier validation
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if repair was successful. If name is not
+ * matched, ValidateStatus is returned.
+ *
+ * DESCRIPTION: Attempt to repair/convert a return object of a type that was
+ * not expected.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiNsComplexRepairs (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_STATUS ValidateStatus,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ const ACPI_REPAIR_INFO *Predefined;
+ ACPI_STATUS Status;
+
+
+ /* Check if this name is in the list of repairable names */
+
+ Predefined = AcpiNsMatchComplexRepair (Node);
+ if (!Predefined)
+ {
+ return (ValidateStatus);
+ }
+
+ Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsMatchComplexRepair
+ *
+ * PARAMETERS: Node - Namespace node for the method/object
+ *
+ * RETURN: Pointer to entry in repair table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the repairable object list.
+ *
+ *****************************************************************************/
+
+static const ACPI_REPAIR_INFO *
+AcpiNsMatchComplexRepair (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ const ACPI_REPAIR_INFO *ThisName;
+
+
+ /* Search info table for a repairable predefined method/object name */
+
+ ThisName = AcpiNsRepairableNames;
+ while (ThisName->RepairFunction)
+ {
+ if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
+ {
+ return (ThisName);
+ }
+ ThisName++;
+ }
+
+ return (NULL); /* Not found */
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_ALR
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
+ * ascending by the ambient illuminance values.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_ALR (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
+ ACPI_SORT_ASCENDING, "AmbientIlluminance");
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_FDE
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
+ * value is a Buffer of 5 DWORDs. This function repairs a common
+ * problem where the return value is a Buffer of BYTEs, not
+ * DWORDs.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_FDE (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT *BufferObject;
+ UINT8 *ByteBuffer;
+ UINT32 *DwordBuffer;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRepair_FDE);
+
+
+ switch (ReturnObject->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ /* This is the expected type. Length should be (at least) 5 DWORDs */
+
+ if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
+ {
+ return (AE_OK);
+ }
+
+ /* We can only repair if we have exactly 5 BYTEs */
+
+ if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Incorrect return buffer length %u, expected %u",
+ ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Create the new (larger) buffer object */
+
+ BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
+ if (!BufferObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Expand each byte to a DWORD */
+
+ ByteBuffer = ReturnObject->Buffer.Pointer;
+ DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
+
+ for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
+ {
+ *DwordBuffer = (UINT32) *ByteBuffer;
+ DwordBuffer++;
+ ByteBuffer++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s Expanded Byte Buffer to expected DWord Buffer\n",
+ Info->FullPathname));
+ break;
+
+ default:
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Delete the original return object, return the new buffer object */
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = BufferObject;
+
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_CID
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
+ * letters are uppercase and that there is no leading asterisk.
+ * If a Package, ensure same for all string elements.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_CID (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **ElementPtr;
+ ACPI_OPERAND_OBJECT *OriginalElement;
+ UINT16 OriginalRefCount;
+ UINT32 i;
+
+
+ /* Check for _CID as a simple string */
+
+ if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
+ {
+ Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
+ return (Status);
+ }
+
+ /* Exit if not a Package */
+
+ if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
+ {
+ return (AE_OK);
+ }
+
+ /* Examine each element of the _CID package */
+
+ ElementPtr = ReturnObject->Package.Elements;
+ for (i = 0; i < ReturnObject->Package.Count; i++)
+ {
+ OriginalElement = *ElementPtr;
+ OriginalRefCount = OriginalElement->Common.ReferenceCount;
+
+ Status = AcpiNsRepair_HID (Info, ElementPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Take care with reference counts */
+
+ if (OriginalElement != *ElementPtr)
+ {
+ /* Element was replaced */
+
+ (*ElementPtr)->Common.ReferenceCount =
+ OriginalRefCount;
+
+ AcpiUtRemoveReference (OriginalElement);
+ }
+
+ ElementPtr++;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_CST
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _CST object:
+ * 1. Sort the list ascending by C state type
+ * 2. Ensure type cannot be zero
+ * 3. A subpackage count of zero means _CST is meaningless
+ * 4. Count must match the number of C state subpackages
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_CST (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **OuterElements;
+ UINT32 OuterElementCount;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ BOOLEAN Removing;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRepair_CST);
+
+
+ /*
+ * Check if the C-state type values are proportional.
+ */
+ OuterElementCount = ReturnObject->Package.Count - 1;
+ i = 0;
+ while (i < OuterElementCount)
+ {
+ OuterElements = &ReturnObject->Package.Elements[i + 1];
+ Removing = FALSE;
+
+ if ((*OuterElements)->Package.Count == 0)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "SubPackage[%u] - removing entry due to zero count", i));
+ Removing = TRUE;
+ goto RemoveElement;
+ }
+
+ ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
+ if ((UINT32) ObjDesc->Integer.Value == 0)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "SubPackage[%u] - removing entry due to invalid Type(0)", i));
+ Removing = TRUE;
+ }
+
+RemoveElement:
+ if (Removing)
+ {
+ AcpiNsRemoveElement (ReturnObject, i + 1);
+ OuterElementCount--;
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ /* Update top-level package count, Type "Integer" checked elsewhere */
+
+ ObjDesc = ReturnObject->Package.Elements[0];
+ ObjDesc->Integer.Value = OuterElementCount;
+
+ /*
+ * Entries (subpackages) in the _CST Package must be sorted by the
+ * C-state type, in ascending order.
+ */
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
+ ACPI_SORT_ASCENDING, "C-State Type");
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_HID
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
+ * letters are uppercase and that there is no leading asterisk.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_HID (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT *NewString;
+ char *Source;
+ char *Dest;
+
+
+ ACPI_FUNCTION_NAME (NsRepair_HID);
+
+
+ /* We only care about string _HID objects (not integers) */
+
+ if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
+ {
+ return (AE_OK);
+ }
+
+ if (ReturnObject->String.Length == 0)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "Invalid zero-length _HID or _CID string"));
+
+ /* Return AE_OK anyway, let driver handle it */
+
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+ }
+
+ /* It is simplest to always create a new string object */
+
+ NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
+ if (!NewString)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /*
+ * Remove a leading asterisk if present. For some unknown reason, there
+ * are many machines in the field that contains IDs like this.
+ *
+ * Examples: "*PNP0C03", "*ACPI0003"
+ */
+ Source = ReturnObject->String.Pointer;
+ if (*Source == '*')
+ {
+ Source++;
+ NewString->String.Length--;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Removed invalid leading asterisk\n", Info->FullPathname));
+ }
+
+ /*
+ * Copy and uppercase the string. From the ACPI 5.0 specification:
+ *
+ * A valid PNP ID must be of the form "AAA####" where A is an uppercase
+ * letter and # is a hex digit. A valid ACPI ID must be of the form
+ * "NNNN####" where N is an uppercase letter or decimal digit, and
+ * # is a hex digit.
+ */
+ for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
+ {
+ *Dest = (char) toupper ((int) *Source);
+ }
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = NewString;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_PRT
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
+ * SourceName and SourceIndex field, a common BIOS bug.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_PRT (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **TopObjectList;
+ ACPI_OPERAND_OBJECT **SubObjectList;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *SubPackage;
+ UINT32 ElementCount;
+ UINT32 Index;
+
+
+ /* Each element in the _PRT package is a subpackage */
+
+ TopObjectList = PackageObject->Package.Elements;
+ ElementCount = PackageObject->Package.Count;
+
+ /* Examine each subpackage */
+
+ for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
+ {
+ SubPackage = *TopObjectList;
+ SubObjectList = SubPackage->Package.Elements;
+
+ /* Check for minimum required element count */
+
+ if (SubPackage->Package.Count < 4)
+ {
+ continue;
+ }
+
+ /*
+ * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
+ * and the SourceIndex (index 3), fix it. _PRT is important enough to
+ * workaround this BIOS error. This also provides compatibility with
+ * other ACPI implementations.
+ */
+ ObjDesc = SubObjectList[3];
+ if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
+ {
+ SubObjectList[3] = SubObjectList[2];
+ SubObjectList[2] = ObjDesc;
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+
+ ACPI_WARN_PREDEFINED ((AE_INFO,
+ Info->FullPathname, Info->NodeFlags,
+ "PRT[%X]: Fixed reversed SourceName and SourceIndex",
+ Index));
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_PSS
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
+ * by the CPU frequencies. Check that the power dissipation values
+ * are all proportional to CPU frequency (i.e., sorting by
+ * frequency should be the same as sorting by power.)
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_PSS (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **OuterElements;
+ UINT32 OuterElementCount;
+ ACPI_OPERAND_OBJECT **Elements;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 PreviousValue;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /*
+ * Entries (subpackages) in the _PSS Package must be sorted by power
+ * dissipation, in descending order. If it appears that the list is
+ * incorrectly sorted, sort it. We sort by CpuFrequency, since this
+ * should be proportional to the power.
+ */
+ Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
+ ACPI_SORT_DESCENDING, "CpuFrequency");
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * We now know the list is correctly sorted by CPU frequency. Check if
+ * the power dissipation values are proportional.
+ */
+ PreviousValue = ACPI_UINT32_MAX;
+ OuterElements = ReturnObject->Package.Elements;
+ OuterElementCount = ReturnObject->Package.Count;
+
+ for (i = 0; i < OuterElementCount; i++)
+ {
+ Elements = (*OuterElements)->Package.Elements;
+ ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
+
+ if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "SubPackage[%u,%u] - suspicious power dissipation values",
+ i-1, i));
+ }
+
+ PreviousValue = (UINT32) ObjDesc->Integer.Value;
+ OuterElements++;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRepair_TSS
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ * descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_TSS (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /*
+ * We can only sort the _TSS return package if there is no _PSS in the
+ * same scope. This is because if _PSS is present, the ACPI specification
+ * dictates that the _TSS Power Dissipation field is to be ignored, and
+ * therefore some BIOSs leave garbage values in the _TSS Power field(s).
+ * In this case, it is best to just return the _TSS package as-is.
+ * (May, 2011)
+ */
+ Status = AcpiNsGetNode (Info->Node, "^_PSS",
+ ACPI_NS_NO_UPSEARCH, &Node);
+ if (ACPI_SUCCESS (Status))
+ {
+ return (AE_OK);
+ }
+
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
+ ACPI_SORT_DESCENDING, "PowerDissipation");
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsCheckSortedList
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObject - Pointer to the top-level returned object
+ * StartIndex - Index of the first subpackage
+ * ExpectedCount - Minimum length of each subpackage
+ * SortIndex - Subpackage entry to sort on
+ * SortDirection - Ascending or descending
+ * SortKeyName - Name of the SortIndex field
+ *
+ * RETURN: Status. AE_OK if the list is valid and is sorted correctly or
+ * has been repaired by sorting the list.
+ *
+ * DESCRIPTION: Check if the package list is valid and sorted correctly by the
+ * SortIndex. If not, then sort the list.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsCheckSortedList (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *ReturnObject,
+ UINT32 StartIndex,
+ UINT32 ExpectedCount,
+ UINT32 SortIndex,
+ UINT8 SortDirection,
+ char *SortKeyName)
+{
+ UINT32 OuterElementCount;
+ ACPI_OPERAND_OBJECT **OuterElements;
+ ACPI_OPERAND_OBJECT **Elements;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 i;
+ UINT32 PreviousValue;
+
+
+ ACPI_FUNCTION_NAME (NsCheckSortedList);
+
+
+ /* The top-level object must be a package */
+
+ if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * NOTE: assumes list of subpackages contains no NULL elements.
+ * Any NULL elements should have been removed by earlier call
+ * to AcpiNsRemoveNullElements.
+ */
+ OuterElementCount = ReturnObject->Package.Count;
+ if (!OuterElementCount || StartIndex >= OuterElementCount)
+ {
+ return (AE_AML_PACKAGE_LIMIT);
+ }
+
+ OuterElements = &ReturnObject->Package.Elements[StartIndex];
+ OuterElementCount -= StartIndex;
+
+ PreviousValue = 0;
+ if (SortDirection == ACPI_SORT_DESCENDING)
+ {
+ PreviousValue = ACPI_UINT32_MAX;
+ }
+
+ /* Examine each subpackage */
+
+ for (i = 0; i < OuterElementCount; i++)
+ {
+ /* Each element of the top-level package must also be a package */
+
+ if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Each subpackage must have the minimum length */
+
+ if ((*OuterElements)->Package.Count < ExpectedCount)
+ {
+ return (AE_AML_PACKAGE_LIMIT);
+ }
+
+ Elements = (*OuterElements)->Package.Elements;
+ ObjDesc = Elements[SortIndex];
+
+ if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * The list must be sorted in the specified order. If we detect a
+ * discrepancy, sort the entire list.
+ */
+ if (((SortDirection == ACPI_SORT_ASCENDING) &&
+ (ObjDesc->Integer.Value < PreviousValue)) ||
+ ((SortDirection == ACPI_SORT_DESCENDING) &&
+ (ObjDesc->Integer.Value > PreviousValue)))
+ {
+ AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
+ OuterElementCount, SortIndex, SortDirection);
+
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Repaired unsorted list - now sorted by %s\n",
+ Info->FullPathname, SortKeyName));
+ return (AE_OK);
+ }
+
+ PreviousValue = (UINT32) ObjDesc->Integer.Value;
+ OuterElements++;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsSortList
+ *
+ * PARAMETERS: Elements - Package object element list
+ * Count - Element count for above
+ * Index - Sort by which package element
+ * SortDirection - Ascending or Descending sort
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Sort the objects that are in a package element list.
+ *
+ * NOTE: Assumes that all NULL elements have been removed from the package,
+ * and that all elements have been verified to be of type Integer.
+ *
+ *****************************************************************************/
+
+static void
+AcpiNsSortList (
+ ACPI_OPERAND_OBJECT **Elements,
+ UINT32 Count,
+ UINT32 Index,
+ UINT8 SortDirection)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc1;
+ ACPI_OPERAND_OBJECT *ObjDesc2;
+ ACPI_OPERAND_OBJECT *TempObj;
+ UINT32 i;
+ UINT32 j;
+
+
+ /* Simple bubble sort */
+
+ for (i = 1; i < Count; i++)
+ {
+ for (j = (Count - 1); j >= i; j--)
+ {
+ ObjDesc1 = Elements[j-1]->Package.Elements[Index];
+ ObjDesc2 = Elements[j]->Package.Elements[Index];
+
+ if (((SortDirection == ACPI_SORT_ASCENDING) &&
+ (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
+
+ ((SortDirection == ACPI_SORT_DESCENDING) &&
+ (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
+ {
+ TempObj = Elements[j-1];
+ Elements[j-1] = Elements[j];
+ Elements[j] = TempObj;
+ }
+ }
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRemoveElement
+ *
+ * PARAMETERS: ObjDesc - Package object element list
+ * Index - Index of element to remove
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove the requested element of a package and delete it.
+ *
+ *****************************************************************************/
+
+static void
+AcpiNsRemoveElement (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Index)
+{
+ ACPI_OPERAND_OBJECT **Source;
+ ACPI_OPERAND_OBJECT **Dest;
+ UINT32 Count;
+ UINT32 NewCount;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRemoveElement);
+
+
+ Count = ObjDesc->Package.Count;
+ NewCount = Count - 1;
+
+ Source = ObjDesc->Package.Elements;
+ Dest = Source;
+
+ /* Examine all elements of the package object, remove matched index */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (i == Index)
+ {
+ AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
+ AcpiUtRemoveReference (*Source);
+ }
+ else
+ {
+ *Dest = *Source;
+ Dest++;
+ }
+ Source++;
+ }
+
+ /* NULL terminate list and update the package count */
+
+ *Dest = NULL;
+ ObjDesc->Package.Count = NewCount;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nssearch.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nssearch.c
new file mode 100644
index 0000000000..a1e6d1a0f1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nssearch.c
@@ -0,0 +1,453 @@
+/*******************************************************************************
+ *
+ * Module Name: nssearch - Namespace search
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/include/amlcode.h>
+#endif
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nssearch")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsSearchParentTree (
+ UINT32 TargetName,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE **ReturnNode);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsSearchOneScope
+ *
+ * PARAMETERS: TargetName - Ascii ACPI name to search for
+ * ParentNode - Starting node where search will begin
+ * Type - Object type to match
+ * ReturnNode - Where the matched Named obj is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Search a single level of the namespace. Performs a
+ * simple search of the specified level, and does not add
+ * entries or search parents.
+ *
+ *
+ * Named object lists are built (and subsequently dumped) in the
+ * order in which the names are encountered during the namespace load;
+ *
+ * All namespace searching is linear in this implementation, but
+ * could be easily modified to support any improved search
+ * algorithm. However, the linear search was chosen for simplicity
+ * and because the trees are small and the other interpreter
+ * execution overhead is relatively high.
+ *
+ * Note: CPU execution analysis has shown that the AML interpreter spends
+ * a very small percentage of its time searching the namespace. Therefore,
+ * the linear search seems to be sufficient, as there would seem to be
+ * little value in improving the search.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsSearchOneScope (
+ UINT32 TargetName,
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (NsSearchOneScope);
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+ if (ACPI_LV_NAMES & AcpiDbgLevel)
+ {
+ char *ScopeName;
+
+ ScopeName = AcpiNsGetExternalPathname (ParentNode);
+ if (ScopeName)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Searching %s (%p) For [%4.4s] (%s)\n",
+ ScopeName, ParentNode, ACPI_CAST_PTR (char, &TargetName),
+ AcpiUtGetTypeName (Type)));
+
+ ACPI_FREE (ScopeName);
+ }
+ }
+#endif
+
+ /*
+ * Search for name at this namespace level, which is to say that we
+ * must search for the name among the children of this object
+ */
+ Node = ParentNode->Child;
+ while (Node)
+ {
+ /* Check for match against the name */
+
+ if (Node->Name.Integer == TargetName)
+ {
+ /* Resolve a control method alias if any */
+
+ if (AcpiNsGetType (Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
+ {
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object);
+ }
+
+ /* Found matching entry */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
+ ACPI_CAST_PTR (char, &TargetName),
+ AcpiUtGetTypeName (Node->Type),
+ Node, AcpiUtGetNodeName (ParentNode), ParentNode));
+
+ *ReturnNode = Node;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Didn't match name, move on to the next peer object */
+
+ Node = Node->Peer;
+ }
+
+ /* Searched entire namespace level, not found */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+ "%p first child %p\n",
+ ACPI_CAST_PTR (char, &TargetName), AcpiUtGetTypeName (Type),
+ AcpiUtGetNodeName (ParentNode), ParentNode, ParentNode->Child));
+
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsSearchParentTree
+ *
+ * PARAMETERS: TargetName - Ascii ACPI name to search for
+ * Node - Starting node where search will begin
+ * Type - Object type to match
+ * ReturnNode - Where the matched Node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called when a name has not been found in the current namespace
+ * level. Before adding it or giving up, ACPI scope rules require
+ * searching enclosing scopes in cases identified by AcpiNsLocal().
+ *
+ * "A name is located by finding the matching name in the current
+ * name space, and then in the parent name space. If the parent
+ * name space does not contain the name, the search continues
+ * recursively until either the name is found or the name space
+ * does not have a parent (the root of the name space). This
+ * indicates that the name is not found" (From ACPI Specification,
+ * section 5.3)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsSearchParentTree (
+ UINT32 TargetName,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *ParentNode;
+
+
+ ACPI_FUNCTION_TRACE (NsSearchParentTree);
+
+
+ ParentNode = Node->Parent;
+
+ /*
+ * If there is no parent (i.e., we are at the root) or type is "local",
+ * we won't be searching the parent tree.
+ */
+ if (!ParentNode)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
+ ACPI_CAST_PTR (char, &TargetName)));
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+
+ if (AcpiNsLocal (Type))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
+ ACPI_CAST_PTR (char, &TargetName), AcpiUtGetTypeName (Type)));
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+
+ /* Search the parent tree */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Searching parent [%4.4s] for [%4.4s]\n",
+ AcpiUtGetNodeName (ParentNode), ACPI_CAST_PTR (char, &TargetName)));
+
+ /* Search parents until target is found or we have backed up to the root */
+
+ while (ParentNode)
+ {
+ /*
+ * Search parent scope. Use TYPE_ANY because we don't care about the
+ * object type at this point, we only care about the existence of
+ * the actual name we are searching for. Typechecking comes later.
+ */
+ Status = AcpiNsSearchOneScope (
+ TargetName, ParentNode, ACPI_TYPE_ANY, ReturnNode);
+ if (ACPI_SUCCESS (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Not found here, go up another level (until we reach the root) */
+
+ ParentNode = ParentNode->Parent;
+ }
+
+ /* Not found in parent tree */
+
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsSearchAndEnter
+ *
+ * PARAMETERS: TargetName - Ascii ACPI name to search for (4 chars)
+ * WalkState - Current state of the walk
+ * Node - Starting node where search will begin
+ * InterpreterMode - Add names only in ACPI_MODE_LOAD_PASS_x.
+ * Otherwise,search only.
+ * Type - Object type to match
+ * Flags - Flags describing the search restrictions
+ * ReturnNode - Where the Node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Search for a name segment in a single namespace level,
+ * optionally adding it if it is not found. If the passed
+ * Type is not Any and the type previously stored in the
+ * entry was Any (i.e. unknown), update the stored type.
+ *
+ * In ACPI_IMODE_EXECUTE, search only.
+ * In other modes, search and add if not found.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsSearchAndEnter (
+ UINT32 TargetName,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_INTERPRETER_MODE InterpreterMode,
+ ACPI_OBJECT_TYPE Type,
+ UINT32 Flags,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *NewNode;
+
+
+ ACPI_FUNCTION_TRACE (NsSearchAndEnter);
+
+
+ /* Parameter validation */
+
+ if (!Node || !TargetName || !ReturnNode)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Null parameter: Node %p Name 0x%X ReturnNode %p",
+ Node, TargetName, ReturnNode));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Name must consist of valid ACPI characters. We will repair the name if
+ * necessary because we don't want to abort because of this, but we want
+ * all namespace names to be printable. A warning message is appropriate.
+ *
+ * This issue came up because there are in fact machines that exhibit
+ * this problem, and we want to be able to enable ACPI support for them,
+ * even though there are a few bad names.
+ */
+ AcpiUtRepairName (ACPI_CAST_PTR (char, &TargetName));
+
+ /* Try to find the name in the namespace level specified by the caller */
+
+ *ReturnNode = ACPI_ENTRY_NOT_FOUND;
+ Status = AcpiNsSearchOneScope (TargetName, Node, Type, ReturnNode);
+ if (Status != AE_NOT_FOUND)
+ {
+ /*
+ * If we found it AND the request specifies that a find is an error,
+ * return the error
+ */
+ if (Status == AE_OK)
+ {
+ /* The node was found in the namespace */
+
+ /*
+ * If the namespace override feature is enabled for this node,
+ * delete any existing attached sub-object and make the node
+ * look like a new node that is owned by the override table.
+ */
+ if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Namespace override: %4.4s pass %u type %X Owner %X\n",
+ ACPI_CAST_PTR(char, &TargetName), InterpreterMode,
+ (*ReturnNode)->Type, WalkState->OwnerId));
+
+ AcpiNsDeleteChildren (*ReturnNode);
+ if (AcpiGbl_RuntimeNamespaceOverride)
+ {
+ AcpiUtRemoveReference ((*ReturnNode)->Object);
+ (*ReturnNode)->Object = NULL;
+ (*ReturnNode)->OwnerId = WalkState->OwnerId;
+ }
+ else
+ {
+ AcpiNsRemoveNode (*ReturnNode);
+ *ReturnNode = ACPI_ENTRY_NOT_FOUND;
+ }
+ }
+
+ /* Return an error if we don't expect to find the object */
+
+ else if (Flags & ACPI_NS_ERROR_IF_FOUND)
+ {
+ Status = AE_ALREADY_EXISTS;
+ }
+ }
+
+#ifdef ACPI_ASL_COMPILER
+ if (*ReturnNode && (*ReturnNode)->Type == ACPI_TYPE_ANY)
+ {
+ (*ReturnNode)->Flags |= ANOBJ_IS_EXTERNAL;
+ }
+#endif
+
+ /* Either found it or there was an error: finished either way */
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * The name was not found. If we are NOT performing the first pass
+ * (name entry) of loading the namespace, search the parent tree (all the
+ * way to the root if necessary.) We don't want to perform the parent
+ * search when the namespace is actually being loaded. We want to perform
+ * the search when namespace references are being resolved (load pass 2)
+ * and during the execution phase.
+ */
+ if ((InterpreterMode != ACPI_IMODE_LOAD_PASS1) &&
+ (Flags & ACPI_NS_SEARCH_PARENT))
+ {
+ /*
+ * Not found at this level - search parent tree according to the
+ * ACPI specification
+ */
+ Status = AcpiNsSearchParentTree (TargetName, Node, Type, ReturnNode);
+ if (ACPI_SUCCESS (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* In execute mode, just search, never add names. Exit now */
+
+ if (InterpreterMode == ACPI_IMODE_EXECUTE)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "%4.4s Not found in %p [Not adding]\n",
+ ACPI_CAST_PTR (char, &TargetName), Node));
+
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+
+ /* Create the new named object */
+
+ NewNode = AcpiNsCreateNode (TargetName);
+ if (!NewNode)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+#ifdef ACPI_ASL_COMPILER
+
+ /* Node is an object defined by an External() statement */
+
+ if (Flags & ACPI_NS_EXTERNAL ||
+ (WalkState && WalkState->Opcode == AML_SCOPE_OP))
+ {
+ NewNode->Flags |= ANOBJ_IS_EXTERNAL;
+ }
+#endif
+
+ if (Flags & ACPI_NS_TEMPORARY)
+ {
+ NewNode->Flags |= ANOBJ_TEMPORARY;
+ }
+
+ /* Install the new object into the parent's list of children */
+
+ AcpiNsInstallNode (WalkState, Node, NewNode, Type);
+ *ReturnNode = NewNode;
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsutils.c
new file mode 100644
index 0000000000..2b9ffa19b8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsutils.c
@@ -0,0 +1,863 @@
+/******************************************************************************
+ *
+ * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
+ * parents and siblings and Scope manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsutils")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_NAME
+AcpiNsFindParentName (
+ ACPI_NAMESPACE_NODE *NodeToSearch);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsPrintNodePathname
+ *
+ * PARAMETERS: Node - Object
+ * Message - Prefix message
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ * Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiNsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Message)
+{
+ ACPI_BUFFER Buffer;
+ ACPI_STATUS Status;
+
+
+ if (!Node)
+ {
+ AcpiOsPrintf ("[NULL NAME]");
+ return;
+ }
+
+ /* Convert handle to full pathname and print it (with supplied message) */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
+ if (ACPI_SUCCESS (Status))
+ {
+ if (Message)
+ {
+ AcpiOsPrintf ("%s ", Message);
+ }
+
+ AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
+ ACPI_FREE (Buffer.Pointer);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetType
+ *
+ * PARAMETERS: Node - Parent Node to be examined
+ *
+ * RETURN: Type field from Node whose handle is passed
+ *
+ * DESCRIPTION: Return the type of a Namespace node
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AcpiNsGetType (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_FUNCTION_TRACE (NsGetType);
+
+
+ if (!Node)
+ {
+ ACPI_WARNING ((AE_INFO, "Null Node parameter"));
+ return_UINT8 (ACPI_TYPE_ANY);
+ }
+
+ return_UINT8 (Node->Type);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsLocal
+ *
+ * PARAMETERS: Type - A namespace object type
+ *
+ * RETURN: LOCAL if names must be found locally in objects of the
+ * passed type, 0 if enclosing scopes should be searched
+ *
+ * DESCRIPTION: Returns scope rule for the given object type.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiNsLocal (
+ ACPI_OBJECT_TYPE Type)
+{
+ ACPI_FUNCTION_TRACE (NsLocal);
+
+
+ if (!AcpiUtValidObjectType (Type))
+ {
+ /* Type code out of range */
+
+ ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
+ return_UINT32 (ACPI_NS_NORMAL);
+ }
+
+ return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetInternalNameLength
+ *
+ * PARAMETERS: Info - Info struct initialized with the
+ * external name pointer.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Calculate the length of the internal (AML) namestring
+ * corresponding to the external (ASL) namestring.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsGetInternalNameLength (
+ ACPI_NAMESTRING_INFO *Info)
+{
+ const char *NextExternalChar;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ NextExternalChar = Info->ExternalName;
+ Info->NumCarats = 0;
+ Info->NumSegments = 0;
+ Info->FullyQualified = FALSE;
+
+ /*
+ * For the internal name, the required length is 4 bytes per segment, plus
+ * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
+ * (which is not really needed, but no there's harm in putting it there)
+ *
+ * strlen() + 1 covers the first NameSeg, which has no path separator
+ */
+ if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
+ {
+ Info->FullyQualified = TRUE;
+ NextExternalChar++;
+
+ /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
+
+ while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
+ {
+ NextExternalChar++;
+ }
+ }
+ else
+ {
+ /* Handle Carat prefixes */
+
+ while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
+ {
+ Info->NumCarats++;
+ NextExternalChar++;
+ }
+ }
+
+ /*
+ * Determine the number of ACPI name "segments" by counting the number of
+ * path separators within the string. Start with one segment since the
+ * segment count is [(# separators) + 1], and zero separators is ok.
+ */
+ if (*NextExternalChar)
+ {
+ Info->NumSegments = 1;
+ for (i = 0; NextExternalChar[i]; i++)
+ {
+ if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
+ {
+ Info->NumSegments++;
+ }
+ }
+ }
+
+ Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
+ 4 + Info->NumCarats;
+
+ Info->NextExternalChar = NextExternalChar;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsBuildInternalName
+ *
+ * PARAMETERS: Info - Info struct fully initialized
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Construct the internal (AML) namestring
+ * corresponding to the external (ASL) namestring.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsBuildInternalName (
+ ACPI_NAMESTRING_INFO *Info)
+{
+ UINT32 NumSegments = Info->NumSegments;
+ char *InternalName = Info->InternalName;
+ const char *ExternalName = Info->NextExternalChar;
+ char *Result = NULL;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (NsBuildInternalName);
+
+
+ /* Setup the correct prefixes, counts, and pointers */
+
+ if (Info->FullyQualified)
+ {
+ InternalName[0] = AML_ROOT_PREFIX;
+
+ if (NumSegments <= 1)
+ {
+ Result = &InternalName[1];
+ }
+ else if (NumSegments == 2)
+ {
+ InternalName[1] = AML_DUAL_NAME_PREFIX;
+ Result = &InternalName[2];
+ }
+ else
+ {
+ InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
+ InternalName[2] = (char) NumSegments;
+ Result = &InternalName[3];
+ }
+ }
+ else
+ {
+ /*
+ * Not fully qualified.
+ * Handle Carats first, then append the name segments
+ */
+ i = 0;
+ if (Info->NumCarats)
+ {
+ for (i = 0; i < Info->NumCarats; i++)
+ {
+ InternalName[i] = AML_PARENT_PREFIX;
+ }
+ }
+
+ if (NumSegments <= 1)
+ {
+ Result = &InternalName[i];
+ }
+ else if (NumSegments == 2)
+ {
+ InternalName[i] = AML_DUAL_NAME_PREFIX;
+ Result = &InternalName[(ACPI_SIZE) i+1];
+ }
+ else
+ {
+ InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
+ InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
+ Result = &InternalName[(ACPI_SIZE) i+2];
+ }
+ }
+
+ /* Build the name (minus path separators) */
+
+ for (; NumSegments; NumSegments--)
+ {
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
+ (*ExternalName == 0))
+ {
+ /* Pad the segment with underscore(s) if segment is short */
+
+ Result[i] = '_';
+ }
+ else
+ {
+ /* Convert the character to uppercase and save it */
+
+ Result[i] = (char) toupper ((int) *ExternalName);
+ ExternalName++;
+ }
+ }
+
+ /* Now we must have a path separator, or the pathname is bad */
+
+ if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
+ (*ExternalName != 0))
+ {
+ return_ACPI_STATUS (AE_BAD_PATHNAME);
+ }
+
+ /* Move on the next segment */
+
+ ExternalName++;
+ Result += ACPI_NAME_SIZE;
+ }
+
+ /* Terminate the string */
+
+ *Result = 0;
+
+ if (Info->FullyQualified)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
+ InternalName, InternalName));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
+ InternalName, InternalName));
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsInternalizeName
+ *
+ * PARAMETERS: *ExternalName - External representation of name
+ * **Converted Name - Where to return the resulting
+ * internal represention of the name
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
+ * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ *
+ *******************************************************************************/
+
+ACPI_STATUS
+AcpiNsInternalizeName (
+ const char *ExternalName,
+ char **ConvertedName)
+{
+ char *InternalName;
+ ACPI_NAMESTRING_INFO Info;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsInternalizeName);
+
+
+ if ((!ExternalName) ||
+ (*ExternalName == 0) ||
+ (!ConvertedName))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the length of the new internal name */
+
+ Info.ExternalName = ExternalName;
+ AcpiNsGetInternalNameLength (&Info);
+
+ /* We need a segment to store the internal name */
+
+ InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
+ if (!InternalName)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Build the name */
+
+ Info.InternalName = InternalName;
+ Status = AcpiNsBuildInternalName (&Info);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (InternalName);
+ return_ACPI_STATUS (Status);
+ }
+
+ *ConvertedName = InternalName;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsExternalizeName
+ *
+ * PARAMETERS: InternalNameLength - Lenth of the internal name below
+ * InternalName - Internal representation of name
+ * ConvertedNameLength - Where the length is returned
+ * ConvertedName - Where the resulting external name
+ * is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ * to its external (printable) form (e.g. "\_PR_.CPU0")
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsExternalizeName (
+ UINT32 InternalNameLength,
+ const char *InternalName,
+ UINT32 *ConvertedNameLength,
+ char **ConvertedName)
+{
+ UINT32 NamesIndex = 0;
+ UINT32 NumSegments = 0;
+ UINT32 RequiredLength;
+ UINT32 PrefixLength = 0;
+ UINT32 i = 0;
+ UINT32 j = 0;
+
+
+ ACPI_FUNCTION_TRACE (NsExternalizeName);
+
+
+ if (!InternalNameLength ||
+ !InternalName ||
+ !ConvertedName)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Check for a prefix (one '\' | one or more '^') */
+
+ switch (InternalName[0])
+ {
+ case AML_ROOT_PREFIX:
+
+ PrefixLength = 1;
+ break;
+
+ case AML_PARENT_PREFIX:
+
+ for (i = 0; i < InternalNameLength; i++)
+ {
+ if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
+ {
+ PrefixLength = i + 1;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (i == InternalNameLength)
+ {
+ PrefixLength = i;
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ /*
+ * Check for object names. Note that there could be 0-255 of these
+ * 4-byte elements.
+ */
+ if (PrefixLength < InternalNameLength)
+ {
+ switch (InternalName[PrefixLength])
+ {
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ /* <count> 4-byte names */
+
+ NamesIndex = PrefixLength + 2;
+ NumSegments = (UINT8)
+ InternalName[(ACPI_SIZE) PrefixLength + 1];
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+
+ /* Two 4-byte names */
+
+ NamesIndex = PrefixLength + 1;
+ NumSegments = 2;
+ break;
+
+ case 0:
+
+ /* NullName */
+
+ NamesIndex = 0;
+ NumSegments = 0;
+ break;
+
+ default:
+
+ /* one 4-byte name */
+
+ NamesIndex = PrefixLength;
+ NumSegments = 1;
+ break;
+ }
+ }
+
+ /*
+ * Calculate the length of ConvertedName, which equals the length
+ * of the prefix, length of all object names, length of any required
+ * punctuation ('.') between object names, plus the NULL terminator.
+ */
+ RequiredLength = PrefixLength + (4 * NumSegments) +
+ ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
+
+ /*
+ * Check to see if we're still in bounds. If not, there's a problem
+ * with InternalName (invalid format).
+ */
+ if (RequiredLength > InternalNameLength)
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid internal name"));
+ return_ACPI_STATUS (AE_BAD_PATHNAME);
+ }
+
+ /* Build the ConvertedName */
+
+ *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
+ if (!(*ConvertedName))
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ j = 0;
+
+ for (i = 0; i < PrefixLength; i++)
+ {
+ (*ConvertedName)[j++] = InternalName[i];
+ }
+
+ if (NumSegments > 0)
+ {
+ for (i = 0; i < NumSegments; i++)
+ {
+ if (i > 0)
+ {
+ (*ConvertedName)[j++] = '.';
+ }
+
+ /* Copy and validate the 4-char name segment */
+
+ ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]);
+ AcpiUtRepairName (&(*ConvertedName)[j]);
+
+ j += ACPI_NAME_SIZE;
+ NamesIndex += ACPI_NAME_SIZE;
+ }
+ }
+
+ if (ConvertedNameLength)
+ {
+ *ConvertedNameLength = (UINT32) RequiredLength;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsValidateHandle
+ *
+ * PARAMETERS: Handle - Handle to be validated and typecast to a
+ * namespace node.
+ *
+ * RETURN: A pointer to a namespace node
+ *
+ * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
+ * cases for the root node.
+ *
+ * NOTE: Real integer handles would allow for more verification
+ * and keep all pointers within this subsystem - however this introduces
+ * more overhead and has not been necessary to this point. Drivers
+ * holding handles are typically notified before a node becomes invalid
+ * due to a table unload.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiNsValidateHandle (
+ ACPI_HANDLE Handle)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Parameter validation */
+
+ if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
+ {
+ return (AcpiGbl_RootNode);
+ }
+
+ /* We can at least attempt to verify the handle */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
+ {
+ return (NULL);
+ }
+
+ return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsTerminate
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
+ *
+ ******************************************************************************/
+
+void
+AcpiNsTerminate (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (NsTerminate);
+
+
+#ifdef ACPI_EXEC_APP
+ {
+ ACPI_OPERAND_OBJECT *Prev;
+ ACPI_OPERAND_OBJECT *Next;
+
+ /* Delete any module-level code blocks */
+
+ Next = AcpiGbl_ModuleCodeList;
+ while (Next)
+ {
+ Prev = Next;
+ Next = Next->Method.Mutex;
+ Prev->Method.Mutex = NULL; /* Clear the Mutex (cheated) field */
+ AcpiUtRemoveReference (Prev);
+ }
+ }
+#endif
+
+ /*
+ * Free the entire namespace -- all nodes and all objects
+ * attached to the nodes
+ */
+ AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
+
+ /* Delete any objects attached to the root node */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ AcpiNsDeleteNode (AcpiGbl_RootNode);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsOpensScope
+ *
+ * PARAMETERS: Type - A valid namespace type
+ *
+ * RETURN: NEWSCOPE if the passed type "opens a name scope" according
+ * to the ACPI specification, else 0
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiNsOpensScope (
+ ACPI_OBJECT_TYPE Type)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ /* type code out of range */
+
+ ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
+ return (ACPI_NS_NORMAL);
+ }
+
+ return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetNode
+ *
+ * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
+ * \ (backslash) and ^ (carat) prefixes, and the
+ * . (period) to separate segments are supported.
+ * PrefixNode - Root of subtree to be searched, or NS_ALL for the
+ * root of the name space. If Name is fully
+ * qualified (first INT8 is '\'), the passed value
+ * of Scope will not be accessed.
+ * Flags - Used to indicate whether to perform upsearch or
+ * not.
+ * ReturnNode - Where the Node is returned
+ *
+ * DESCRIPTION: Look up a name relative to a given scope and return the
+ * corresponding Node. NOTE: Scope can be null.
+ *
+ * MUTEX: Locks namespace
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsGetNode (
+ ACPI_NAMESPACE_NODE *PrefixNode,
+ const char *Pathname,
+ UINT32 Flags,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_GENERIC_STATE ScopeInfo;
+ ACPI_STATUS Status;
+ char *InternalPath;
+
+
+ ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
+
+
+ /* Simplest case is a null pathname */
+
+ if (!Pathname)
+ {
+ *ReturnNode = PrefixNode;
+ if (!PrefixNode)
+ {
+ *ReturnNode = AcpiGbl_RootNode;
+ }
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Quick check for a reference to the root */
+
+ if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
+ {
+ *ReturnNode = AcpiGbl_RootNode;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Convert path to internal representation */
+
+ Status = AcpiNsInternalizeName (Pathname, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Must lock namespace during lookup */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Setup lookup scope (search starting point) */
+
+ ScopeInfo.Scope.Node = PrefixNode;
+
+ /* Lookup the name in the namespace */
+
+ Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
+ NULL, ReturnNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
+ Pathname, AcpiFormatException (Status)));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+Cleanup:
+ ACPI_FREE (InternalPath);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nswalk.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nswalk.c
new file mode 100644
index 0000000000..1674998250
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nswalk.c
@@ -0,0 +1,381 @@
+/******************************************************************************
+ *
+ * Module Name: nswalk - Functions for walking the ACPI namespace
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nswalk")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetNextNode
+ *
+ * PARAMETERS: ParentNode - Parent node whose children we are
+ * getting
+ * ChildNode - Previous child that was found.
+ * The NEXT child will be returned
+ *
+ * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
+ * none is found.
+ *
+ * DESCRIPTION: Return the next peer node within the namespace. If Handle
+ * is valid, Scope is ignored. Otherwise, the first node
+ * within Scope is returned.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiNsGetNextNode (
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_NAMESPACE_NODE *ChildNode)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!ChildNode)
+ {
+ /* It's really the parent's _scope_ that we want */
+
+ return (ParentNode->Child);
+ }
+
+ /* Otherwise just return the next peer */
+
+ return (ChildNode->Peer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetNextNodeTyped
+ *
+ * PARAMETERS: Type - Type of node to be searched for
+ * ParentNode - Parent node whose children we are
+ * getting
+ * ChildNode - Previous child that was found.
+ * The NEXT child will be returned
+ *
+ * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
+ * none is found.
+ *
+ * DESCRIPTION: Return the next peer node within the namespace. If Handle
+ * is valid, Scope is ignored. Otherwise, the first node
+ * within Scope is returned.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiNsGetNextNodeTyped (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_NAMESPACE_NODE *ChildNode)
+{
+ ACPI_NAMESPACE_NODE *NextNode = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ NextNode = AcpiNsGetNextNode (ParentNode, ChildNode);
+
+ /* If any type is OK, we are done */
+
+ if (Type == ACPI_TYPE_ANY)
+ {
+ /* NextNode is NULL if we are at the end-of-list */
+
+ return (NextNode);
+ }
+
+ /* Must search for the node -- but within this scope only */
+
+ while (NextNode)
+ {
+ /* If type matches, we are done */
+
+ if (NextNode->Type == Type)
+ {
+ return (NextNode);
+ }
+
+ /* Otherwise, move on to the next peer node */
+
+ NextNode = NextNode->Peer;
+ }
+
+ /* Not found */
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsWalkNamespace
+ *
+ * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
+ * StartNode - Handle in namespace where search begins
+ * MaxDepth - Depth to which search is to reach
+ * Flags - Whether to unlock the NS before invoking
+ * the callback routine
+ * DescendingCallback - Called during tree descent
+ * when an object of "Type" is found
+ * AscendingCallback - Called during tree ascent
+ * when an object of "Type" is found
+ * Context - Passed to user function(s) above
+ * ReturnValue - from the UserFunction if terminated
+ * early. Otherwise, returns NULL.
+ * RETURNS: Status
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ * starting (and ending) at the node specified by StartHandle.
+ * The callback function is called whenever a node that matches
+ * the type parameter is found. If the callback function returns
+ * a non-zero value, the search is terminated immediately and
+ * this value is returned to the caller.
+ *
+ * The point of this procedure is to provide a generic namespace
+ * walk routine that can be called from multiple places to
+ * provide multiple services; the callback function(s) can be
+ * tailored to each task, whether it is a print function,
+ * a compare function, etc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsWalkNamespace (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE StartNode,
+ UINT32 MaxDepth,
+ UINT32 Flags,
+ ACPI_WALK_CALLBACK DescendingCallback,
+ ACPI_WALK_CALLBACK AscendingCallback,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_STATUS Status;
+ ACPI_STATUS MutexStatus;
+ ACPI_NAMESPACE_NODE *ChildNode;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_OBJECT_TYPE ChildType;
+ UINT32 Level;
+ BOOLEAN NodePreviouslyVisited = FALSE;
+
+
+ ACPI_FUNCTION_TRACE (NsWalkNamespace);
+
+
+ /* Special case for the namespace Root Node */
+
+ if (StartNode == ACPI_ROOT_OBJECT)
+ {
+ StartNode = AcpiGbl_RootNode;
+ }
+
+ /* Null child means "get first node" */
+
+ ParentNode = StartNode;
+ ChildNode = AcpiNsGetNextNode (ParentNode, NULL);
+ ChildType = ACPI_TYPE_ANY;
+ Level = 1;
+
+ /*
+ * Traverse the tree of nodes until we bubble back up to where we
+ * started. When Level is zero, the loop is done because we have
+ * bubbled up to (and passed) the original parent handle (StartEntry)
+ */
+ while (Level > 0 && ChildNode)
+ {
+ Status = AE_OK;
+
+ /* Found next child, get the type if we are not searching for ANY */
+
+ if (Type != ACPI_TYPE_ANY)
+ {
+ ChildType = ChildNode->Type;
+ }
+
+ /*
+ * Ignore all temporary namespace nodes (created during control
+ * method execution) unless told otherwise. These temporary nodes
+ * can cause a race condition because they can be deleted during
+ * the execution of the user function (if the namespace is
+ * unlocked before invocation of the user function.) Only the
+ * debugger namespace dump will examine the temporary nodes.
+ */
+ if ((ChildNode->Flags & ANOBJ_TEMPORARY) &&
+ !(Flags & ACPI_NS_WALK_TEMP_NODES))
+ {
+ Status = AE_CTRL_DEPTH;
+ }
+
+ /* Type must match requested type */
+
+ else if (ChildType == Type)
+ {
+ /*
+ * Found a matching node, invoke the user callback function.
+ * Unlock the namespace if flag is set.
+ */
+ if (Flags & ACPI_NS_WALK_UNLOCK)
+ {
+ MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (MutexStatus))
+ {
+ return_ACPI_STATUS (MutexStatus);
+ }
+ }
+
+ /*
+ * Invoke the user function, either descending, ascending,
+ * or both.
+ */
+ if (!NodePreviouslyVisited)
+ {
+ if (DescendingCallback)
+ {
+ Status = DescendingCallback (ChildNode, Level,
+ Context, ReturnValue);
+ }
+ }
+ else
+ {
+ if (AscendingCallback)
+ {
+ Status = AscendingCallback (ChildNode, Level,
+ Context, ReturnValue);
+ }
+ }
+
+ if (Flags & ACPI_NS_WALK_UNLOCK)
+ {
+ MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (MutexStatus))
+ {
+ return_ACPI_STATUS (MutexStatus);
+ }
+ }
+
+ switch (Status)
+ {
+ case AE_OK:
+ case AE_CTRL_DEPTH:
+
+ /* Just keep going */
+ break;
+
+ case AE_CTRL_TERMINATE:
+
+ /* Exit now, with OK status */
+
+ return_ACPI_STATUS (AE_OK);
+
+ default:
+
+ /* All others are valid exceptions */
+
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Depth first search: Attempt to go down another level in the
+ * namespace if we are allowed to. Don't go any further if we have
+ * reached the caller specified maximum depth or if the user
+ * function has specified that the maximum depth has been reached.
+ */
+ if (!NodePreviouslyVisited &&
+ (Level < MaxDepth) &&
+ (Status != AE_CTRL_DEPTH))
+ {
+ if (ChildNode->Child)
+ {
+ /* There is at least one child of this node, visit it */
+
+ Level++;
+ ParentNode = ChildNode;
+ ChildNode = AcpiNsGetNextNode (ParentNode, NULL);
+ continue;
+ }
+ }
+
+ /* No more children, re-visit this node */
+
+ if (!NodePreviouslyVisited)
+ {
+ NodePreviouslyVisited = TRUE;
+ continue;
+ }
+
+ /* No more children, visit peers */
+
+ ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
+ if (ChildNode)
+ {
+ NodePreviouslyVisited = FALSE;
+ }
+
+ /* No peers, re-visit parent */
+
+ else
+ {
+ /*
+ * No more children of this node (AcpiNsGetNextNode failed), go
+ * back upwards in the namespace tree to the node's parent.
+ */
+ Level--;
+ ChildNode = ParentNode;
+ ParentNode = ParentNode->Parent;
+
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+
+ /* Complete walk, not terminated by user function */
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfeval.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
new file mode 100644
index 0000000000..9b4d2db370
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
@@ -0,0 +1,1074 @@
+/*******************************************************************************
+ *
+ * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
+ * ACPI Object evaluation interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsxfeval")
+
+/* Local prototypes */
+
+static void
+AcpiNsResolveReferences (
+ ACPI_EVALUATE_INFO *Info);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvaluateObjectTyped
+ *
+ * PARAMETERS: Handle - Object handle (optional)
+ * Pathname - Object pathname (optional)
+ * ExternalParams - List of parameters to pass to method,
+ * terminated by NULL. May be NULL
+ * if no parameters are being passed.
+ * ReturnBuffer - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * ReturnType - Expected type of return object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Find and evaluate the given object, passing the given
+ * parameters if necessary. One of "Handle" or "Pathname" must
+ * be valid (non-null)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvaluateObjectTyped (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ ACPI_OBJECT_LIST *ExternalParams,
+ ACPI_BUFFER *ReturnBuffer,
+ ACPI_OBJECT_TYPE ReturnType)
+{
+ ACPI_STATUS Status;
+ BOOLEAN FreeBufferOnError = FALSE;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
+
+
+ /* Return buffer must be valid */
+
+ if (!ReturnBuffer)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
+ {
+ FreeBufferOnError = TRUE;
+ }
+
+ /* Evaluate the object */
+
+ Status = AcpiEvaluateObject (Handle, Pathname,
+ ExternalParams, ReturnBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Type ANY means "don't care" */
+
+ if (ReturnType == ACPI_TYPE_ANY)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (ReturnBuffer->Length == 0)
+ {
+ /* Error because caller specifically asked for a return value */
+
+ ACPI_ERROR ((AE_INFO, "No return value"));
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Examine the object type returned from EvaluateObject */
+
+ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Return object type does not match requested type */
+
+ ACPI_ERROR ((AE_INFO,
+ "Incorrect return type [%s] requested [%s]",
+ AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
+ AcpiUtGetTypeName (ReturnType)));
+
+ if (FreeBufferOnError)
+ {
+ /*
+ * Free a buffer created via ACPI_ALLOCATE_BUFFER.
+ * Note: We use AcpiOsFree here because AcpiOsAllocate was used
+ * to allocate the buffer. This purposefully bypasses the
+ * (optionally enabled) allocation tracking mechanism since we
+ * only want to track internal allocations.
+ */
+ AcpiOsFree (ReturnBuffer->Pointer);
+ ReturnBuffer->Pointer = NULL;
+ }
+
+ ReturnBuffer->Length = 0;
+ return_ACPI_STATUS (AE_TYPE);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvaluateObject
+ *
+ * PARAMETERS: Handle - Object handle (optional)
+ * Pathname - Object pathname (optional)
+ * ExternalParams - List of parameters to pass to method,
+ * terminated by NULL. May be NULL
+ * if no parameters are being passed.
+ * ReturnBuffer - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Find and evaluate the given object, passing the given
+ * parameters if necessary. One of "Handle" or "Pathname" must
+ * be valid (non-null)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvaluateObject (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ ACPI_OBJECT_LIST *ExternalParams,
+ ACPI_BUFFER *ReturnBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_SIZE BufferSpaceNeeded;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
+
+
+ /* Allocate and initialize the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Convert and validate the device handle */
+
+ Info->PrefixNode = AcpiNsValidateHandle (Handle);
+ if (!Info->PrefixNode)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto Cleanup;
+ }
+
+ /*
+ * Get the actual namespace node for the target object.
+ * Handles these cases:
+ *
+ * 1) Null node, valid pathname from root (absolute path)
+ * 2) Node and valid pathname (path relative to Node)
+ * 3) Node, Null pathname
+ */
+ if ((Pathname) &&
+ (ACPI_IS_ROOT_PREFIX (Pathname[0])))
+ {
+ /* The path is fully qualified, just evaluate by name */
+
+ Info->PrefixNode = NULL;
+ }
+ else if (!Handle)
+ {
+ /*
+ * A handle is optional iff a fully qualified pathname is specified.
+ * Since we've already handled fully qualified names above, this is
+ * an error.
+ */
+ if (!Pathname)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Both Handle and Pathname are NULL"));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Null Handle with relative pathname [%s]", Pathname));
+ }
+
+ Status = AE_BAD_PARAMETER;
+ goto Cleanup;
+ }
+
+ Info->RelativePathname = Pathname;
+
+ /*
+ * Convert all external objects passed as arguments to the
+ * internal version(s).
+ */
+ if (ExternalParams && ExternalParams->Count)
+ {
+ Info->ParamCount = (UINT16) ExternalParams->Count;
+
+ /* Warn on impossible argument count */
+
+ if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Excess arguments (%u) - using only %u",
+ Info->ParamCount, ACPI_METHOD_NUM_ARGS));
+
+ Info->ParamCount = ACPI_METHOD_NUM_ARGS;
+ }
+
+ /*
+ * Allocate a new parameter block for the internal objects
+ * Add 1 to count to allow for null terminated internal list
+ */
+ Info->Parameters = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
+ if (!Info->Parameters)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Convert each external object in the list to an internal object */
+
+ for (i = 0; i < Info->ParamCount; i++)
+ {
+ Status = AcpiUtCopyEobjectToIobject (
+ &ExternalParams->Pointer[i], &Info->Parameters[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ Info->Parameters[Info->ParamCount] = NULL;
+ }
+
+
+#if 0
+
+ /*
+ * Begin incoming argument count analysis. Check for too few args
+ * and too many args.
+ */
+
+ switch (AcpiNsGetType (Info->Node))
+ {
+ case ACPI_TYPE_METHOD:
+
+ /* Check incoming argument count against the method definition */
+
+ if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Insufficient arguments (%u) - %u are required",
+ Info->ParamCount,
+ Info->ObjDesc->Method.ParamCount));
+
+ Status = AE_MISSING_ARGUMENTS;
+ goto Cleanup;
+ }
+
+ else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Excess arguments (%u) - only %u are required",
+ Info->ParamCount,
+ Info->ObjDesc->Method.ParamCount));
+
+ /* Just pass the required number of arguments */
+
+ Info->ParamCount = Info->ObjDesc->Method.ParamCount;
+ }
+
+ /*
+ * Any incoming external objects to be passed as arguments to the
+ * method must be converted to internal objects
+ */
+ if (Info->ParamCount)
+ {
+ /*
+ * Allocate a new parameter block for the internal objects
+ * Add 1 to count to allow for null terminated internal list
+ */
+ Info->Parameters = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
+ if (!Info->Parameters)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Convert each external object in the list to an internal object */
+
+ for (i = 0; i < Info->ParamCount; i++)
+ {
+ Status = AcpiUtCopyEobjectToIobject (
+ &ExternalParams->Pointer[i], &Info->Parameters[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ Info->Parameters[Info->ParamCount] = NULL;
+ }
+ break;
+
+ default:
+
+ /* Warn if arguments passed to an object that is not a method */
+
+ if (Info->ParamCount)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "%u arguments were passed to a non-method ACPI object",
+ Info->ParamCount));
+ }
+ break;
+ }
+
+#endif
+
+
+ /* Now we can evaluate the object */
+
+ Status = AcpiNsEvaluate (Info);
+
+ /*
+ * If we are expecting a return value, and all went well above,
+ * copy the return value to an external object.
+ */
+ if (ReturnBuffer)
+ {
+ if (!Info->ReturnObject)
+ {
+ ReturnBuffer->Length = 0;
+ }
+ else
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
+ ACPI_DESC_TYPE_NAMED)
+ {
+ /*
+ * If we received a NS Node as a return object, this means that
+ * the object we are evaluating has nothing interesting to
+ * return (such as a mutex, etc.) We return an error because
+ * these types are essentially unsupported by this interface.
+ * We don't check up front because this makes it easier to add
+ * support for various types at a later date if necessary.
+ */
+ Status = AE_TYPE;
+ Info->ReturnObject = NULL; /* No need to delete a NS Node */
+ ReturnBuffer->Length = 0;
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Dereference Index and RefOf references */
+
+ AcpiNsResolveReferences (Info);
+
+ /* Get the size of the returned object */
+
+ Status = AcpiUtGetObjectSize (Info->ReturnObject,
+ &BufferSpaceNeeded);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (ReturnBuffer,
+ BufferSpaceNeeded);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * Caller's buffer is too small or a new one can't
+ * be allocated
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Needed buffer size %X, %s\n",
+ (UINT32) BufferSpaceNeeded,
+ AcpiFormatException (Status)));
+ }
+ else
+ {
+ /* We have enough space for the object, build it */
+
+ Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
+ ReturnBuffer);
+ }
+ }
+ }
+ }
+ }
+
+ if (Info->ReturnObject)
+ {
+ /*
+ * Delete the internal return object. NOTE: Interpreter must be
+ * locked to avoid race condition.
+ */
+ AcpiExEnterInterpreter ();
+
+ /* Remove one reference on the return object (should delete it) */
+
+ AcpiUtRemoveReference (Info->ReturnObject);
+ AcpiExExitInterpreter ();
+ }
+
+
+Cleanup:
+
+ /* Free the input parameter list (if we created one) */
+
+ if (Info->Parameters)
+ {
+ /* Free the allocated parameter block */
+
+ AcpiUtDeleteInternalObjectList (Info->Parameters);
+ }
+
+ ACPI_FREE (Info);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsResolveReferences
+ *
+ * PARAMETERS: Info - Evaluation info block
+ *
+ * RETURN: Info->ReturnObject is replaced with the dereferenced object
+ *
+ * DESCRIPTION: Dereference certain reference objects. Called before an
+ * internal return object is converted to an external ACPI_OBJECT.
+ *
+ * Performs an automatic dereference of Index and RefOf reference objects.
+ * These reference objects are not supported by the ACPI_OBJECT, so this is a
+ * last resort effort to return something useful. Also, provides compatibility
+ * with other ACPI implementations.
+ *
+ * NOTE: does not handle references within returned package objects or nested
+ * references, but this support could be added later if found to be necessary.
+ *
+ ******************************************************************************/
+
+static void
+AcpiNsResolveReferences (
+ ACPI_EVALUATE_INFO *Info)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /* We are interested in reference objects only */
+
+ if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ return;
+ }
+
+ /*
+ * Two types of references are supported - those created by Index and
+ * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
+ * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
+ * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
+ * an ACPI_OBJECT.
+ */
+ switch (Info->ReturnObject->Reference.Class)
+ {
+ case ACPI_REFCLASS_INDEX:
+
+ ObjDesc = *(Info->ReturnObject->Reference.Where);
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ Node = Info->ReturnObject->Reference.Object;
+ if (Node)
+ {
+ ObjDesc = Node->Object;
+ }
+ break;
+
+ default:
+
+ return;
+ }
+
+ /* Replace the existing reference object */
+
+ if (ObjDesc)
+ {
+ AcpiUtAddReference (ObjDesc);
+ AcpiUtRemoveReference (Info->ReturnObject);
+ Info->ReturnObject = ObjDesc;
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiWalkNamespace
+ *
+ * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
+ * StartObject - Handle in namespace where search begins
+ * MaxDepth - Depth to which search is to reach
+ * DescendingCallback - Called during tree descent
+ * when an object of "Type" is found
+ * AscendingCallback - Called during tree ascent
+ * when an object of "Type" is found
+ * Context - Passed to user function(s) above
+ * ReturnValue - Location where return value of
+ * UserFunction is put if terminated early
+ *
+ * RETURNS Return value from the UserFunction if terminated early.
+ * Otherwise, returns NULL.
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ * starting (and ending) at the object specified by StartHandle.
+ * The callback function is called whenever an object that matches
+ * the type parameter is found. If the callback function returns
+ * a non-zero value, the search is terminated immediately and this
+ * value is returned to the caller.
+ *
+ * The point of this procedure is to provide a generic namespace
+ * walk routine that can be called from multiple places to
+ * provide multiple services; the callback function(s) can be
+ * tailored to each task, whether it is a print function,
+ * a compare function, etc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiWalkNamespace (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE StartObject,
+ UINT32 MaxDepth,
+ ACPI_WALK_CALLBACK DescendingCallback,
+ ACPI_WALK_CALLBACK AscendingCallback,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
+
+
+ /* Parameter validation */
+
+ if ((Type > ACPI_TYPE_LOCAL_MAX) ||
+ (!MaxDepth) ||
+ (!DescendingCallback && !AscendingCallback))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Need to acquire the namespace reader lock to prevent interference
+ * with any concurrent table unloads (which causes the deletion of
+ * namespace objects). We cannot allow the deletion of a namespace node
+ * while the user function is using it. The exception to this are the
+ * nodes created and deleted during control method execution -- these
+ * nodes are marked as temporary nodes and are ignored by the namespace
+ * walk. Thus, control methods can be executed while holding the
+ * namespace deletion lock (and the user function can execute control
+ * methods.)
+ */
+ Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Lock the namespace around the walk. The namespace will be
+ * unlocked/locked around each call to the user function - since the user
+ * function must be allowed to make ACPICA calls itself (for example, it
+ * will typically execute control methods during device enumeration.)
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Now we can validate the starting node */
+
+ if (!AcpiNsValidateHandle (StartObject))
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit2;
+ }
+
+ Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
+ ACPI_NS_WALK_UNLOCK, DescendingCallback,
+ AscendingCallback, Context, ReturnValue);
+
+UnlockAndExit2:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+UnlockAndExit:
+ (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetDeviceCallback
+ *
+ * PARAMETERS: Callback from AcpiGetDevice
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
+ * present devices, or if they specified a HID, it filters based
+ * on that.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsGetDeviceCallback (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_GET_DEVICES_INFO *Info = Context;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT32 Flags;
+ ACPI_PNP_DEVICE_ID *Hid;
+ ACPI_PNP_DEVICE_ID_LIST *Cid;
+ UINT32 i;
+ BOOLEAN Found;
+ int NoMatch;
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (!Node)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * First, filter based on the device HID and CID.
+ *
+ * 01/2010: For this case where a specific HID is requested, we don't
+ * want to run _STA until we have an actual HID match. Thus, we will
+ * not unnecessarily execute _STA on devices for which the caller
+ * doesn't care about. Previously, _STA was executed unconditionally
+ * on all devices found here.
+ *
+ * A side-effect of this change is that now we will continue to search
+ * for a matching HID even under device trees where the parent device
+ * would have returned a _STA that indicates it is not present or
+ * not functioning (thus aborting the search on that branch).
+ */
+ if (Info->Hid != NULL)
+ {
+ Status = AcpiUtExecute_HID (Node, &Hid);
+ if (Status == AE_NOT_FOUND)
+ {
+ return (AE_OK);
+ }
+ else if (ACPI_FAILURE (Status))
+ {
+ return (AE_CTRL_DEPTH);
+ }
+
+ NoMatch = strcmp (Hid->String, Info->Hid);
+ ACPI_FREE (Hid);
+
+ if (NoMatch)
+ {
+ /*
+ * HID does not match, attempt match within the
+ * list of Compatible IDs (CIDs)
+ */
+ Status = AcpiUtExecute_CID (Node, &Cid);
+ if (Status == AE_NOT_FOUND)
+ {
+ return (AE_OK);
+ }
+ else if (ACPI_FAILURE (Status))
+ {
+ return (AE_CTRL_DEPTH);
+ }
+
+ /* Walk the CID list */
+
+ Found = FALSE;
+ for (i = 0; i < Cid->Count; i++)
+ {
+ if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
+ {
+ /* Found a matching CID */
+
+ Found = TRUE;
+ break;
+ }
+ }
+
+ ACPI_FREE (Cid);
+ if (!Found)
+ {
+ return (AE_OK);
+ }
+ }
+ }
+
+ /* Run _STA to determine if device is present */
+
+ Status = AcpiUtExecute_STA (Node, &Flags);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_CTRL_DEPTH);
+ }
+
+ if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
+ !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
+ {
+ /*
+ * Don't examine the children of the device only when the
+ * device is neither present nor functional. See ACPI spec,
+ * description of _STA for more information.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+
+ /* We have a valid device, invoke the user function */
+
+ Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
+ ReturnValue);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetDevices
+ *
+ * PARAMETERS: HID - HID to search for. Can be NULL.
+ * UserFunction - Called when a matching object is found
+ * Context - Passed to user function
+ * ReturnValue - Location where return value of
+ * UserFunction is put if terminated early
+ *
+ * RETURNS Return value from the UserFunction if terminated early.
+ * Otherwise, returns NULL.
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ * starting (and ending) at the object specified by StartHandle.
+ * The UserFunction is called whenever an object of type
+ * Device is found. If the user function returns
+ * a non-zero value, the search is terminated immediately and this
+ * value is returned to the caller.
+ *
+ * This is a wrapper for WalkNamespace, but the callback performs
+ * additional filtering. Please see AcpiNsGetDeviceCallback.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetDevices (
+ char *HID,
+ ACPI_WALK_CALLBACK UserFunction,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_STATUS Status;
+ ACPI_GET_DEVICES_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetDevices);
+
+
+ /* Parameter validation */
+
+ if (!UserFunction)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * We're going to call their callback from OUR callback, so we need
+ * to know what it is, and their context parameter.
+ */
+ Info.Hid = HID;
+ Info.Context = Context;
+ Info.UserFunction = UserFunction;
+
+ /*
+ * Lock the namespace around the walk.
+ * The namespace will be unlocked/locked around each call
+ * to the user function - since this function
+ * must be allowed to make Acpi calls itself.
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
+ AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetDevices)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAttachData
+ *
+ * PARAMETERS: ObjHandle - Namespace node
+ * Handler - Handler for this attachment
+ * Data - Pointer to data to be attached
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiAttachData (
+ ACPI_HANDLE ObjHandle,
+ ACPI_OBJECT_HANDLER Handler,
+ void *Data)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!ObjHandle ||
+ !Handler ||
+ !Data)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Convert and validate the handle */
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsAttachData (Node, Handler, Data);
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiAttachData)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDetachData
+ *
+ * PARAMETERS: ObjHandle - Namespace node handle
+ * Handler - Handler used in call to AcpiAttachData
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove data that was previously attached to a node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDetachData (
+ ACPI_HANDLE ObjHandle,
+ ACPI_OBJECT_HANDLER Handler)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!ObjHandle ||
+ !Handler)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Convert and validate the handle */
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsDetachData (Node, Handler);
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDetachData)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetData
+ *
+ * PARAMETERS: ObjHandle - Namespace node
+ * Handler - Handler used in call to AttachData
+ * Data - Where the data is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetData (
+ ACPI_HANDLE ObjHandle,
+ ACPI_OBJECT_HANDLER Handler,
+ void **Data)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!ObjHandle ||
+ !Handler ||
+ !Data)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Convert and validate the handle */
+
+ Node = AcpiNsValidateHandle (ObjHandle);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsGetAttachedData (Node, Handler, Data);
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetData)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfname.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfname.c
new file mode 100644
index 0000000000..24eca77b0d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfname.c
@@ -0,0 +1,752 @@
+/******************************************************************************
+ *
+ * Module Name: nsxfname - Public interfaces to the ACPI subsystem
+ * ACPI Namespace oriented interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsxfname")
+
+/* Local prototypes */
+
+static char *
+AcpiNsCopyDeviceId (
+ ACPI_PNP_DEVICE_ID *Dest,
+ ACPI_PNP_DEVICE_ID *Source,
+ char *StringArea);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetHandle
+ *
+ * PARAMETERS: Parent - Object to search under (search scope).
+ * Pathname - Pointer to an asciiz string containing the
+ * name
+ * RetHandle - Where the return handle is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This routine will search for a caller specified name in the
+ * name space. The caller can restrict the search region by
+ * specifying a non NULL parent. The parent value is itself a
+ * namespace handle.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetHandle (
+ ACPI_HANDLE Parent,
+ ACPI_STRING Pathname,
+ ACPI_HANDLE *RetHandle)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node = NULL;
+ ACPI_NAMESPACE_NODE *PrefixNode = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Parameter Validation */
+
+ if (!RetHandle || !Pathname)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Convert a parent handle to a prefix node */
+
+ if (Parent)
+ {
+ PrefixNode = AcpiNsValidateHandle (Parent);
+ if (!PrefixNode)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+ }
+
+ /*
+ * Valid cases are:
+ * 1) Fully qualified pathname
+ * 2) Parent + Relative pathname
+ *
+ * Error for <null Parent + relative path>
+ */
+ if (ACPI_IS_ROOT_PREFIX (Pathname[0]))
+ {
+ /* Pathname is fully qualified (starts with '\') */
+
+ /* Special case for root-only, since we can't search for it */
+
+ if (!strcmp (Pathname, ACPI_NS_ROOT_PATH))
+ {
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
+ return (AE_OK);
+ }
+ }
+ else if (!PrefixNode)
+ {
+ /* Relative path with null prefix is disallowed */
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Find the Node and convert to a handle */
+
+ Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node);
+ if (ACPI_SUCCESS (Status))
+ {
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
+ }
+
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetHandle)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetName
+ *
+ * PARAMETERS: Handle - Handle to be converted to a pathname
+ * NameType - Full pathname or single segment
+ * Buffer - Buffer for returned path
+ *
+ * RETURN: Pointer to a string containing the fully qualified Name.
+ *
+ * DESCRIPTION: This routine returns the fully qualified name associated with
+ * the Handle parameter. This and the AcpiPathnameToHandle are
+ * complementary functions.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetName (
+ ACPI_HANDLE Handle,
+ UINT32 NameType,
+ ACPI_BUFFER *Buffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ char *NodeName;
+
+
+ /* Parameter validation */
+
+ if (NameType > ACPI_NAME_TYPE_MAX)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtValidateBuffer (Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (NameType == ACPI_FULL_PATHNAME ||
+ NameType == ACPI_FULL_PATHNAME_NO_TRAILING)
+ {
+ /* Get the full pathname (From the namespace root) */
+
+ Status = AcpiNsHandleToPathname (Handle, Buffer,
+ NameType == ACPI_FULL_PATHNAME ? FALSE : TRUE);
+ return (Status);
+ }
+
+ /*
+ * Wants the single segment ACPI name.
+ * Validate handle and convert to a namespace Node
+ */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Node = AcpiNsValidateHandle (Handle);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Just copy the ACPI name from the Node and zero terminate it */
+
+ NodeName = AcpiUtGetNodeName (Node);
+ ACPI_MOVE_NAME (Buffer->Pointer, NodeName);
+ ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0;
+ Status = AE_OK;
+
+
+UnlockAndExit:
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetName)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsCopyDeviceId
+ *
+ * PARAMETERS: Dest - Pointer to the destination PNP_DEVICE_ID
+ * Source - Pointer to the source PNP_DEVICE_ID
+ * StringArea - Pointer to where to copy the dest string
+ *
+ * RETURN: Pointer to the next string area
+ *
+ * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiNsCopyDeviceId (
+ ACPI_PNP_DEVICE_ID *Dest,
+ ACPI_PNP_DEVICE_ID *Source,
+ char *StringArea)
+{
+
+ /* Create the destination PNP_DEVICE_ID */
+
+ Dest->String = StringArea;
+ Dest->Length = Source->Length;
+
+ /* Copy actual string and return a pointer to the next string area */
+
+ memcpy (StringArea, Source->String, Source->Length);
+ return (StringArea + Source->Length);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiGetObjectInfo
+ *
+ * PARAMETERS: Handle - Object Handle
+ * ReturnBuffer - Where the info is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Returns information about an object as gleaned from the
+ * namespace node and possibly by running several standard
+ * control methods (Such as in the case of a device.)
+ *
+ * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB,
+ * _CLS, _STA, _ADR, _SxW, and _SxD methods.
+ *
+ * Note: Allocates the return buffer, must be freed by the caller.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetObjectInfo (
+ ACPI_HANDLE Handle,
+ ACPI_DEVICE_INFO **ReturnBuffer)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_DEVICE_INFO *Info;
+ ACPI_PNP_DEVICE_ID_LIST *CidList = NULL;
+ ACPI_PNP_DEVICE_ID *Hid = NULL;
+ ACPI_PNP_DEVICE_ID *Uid = NULL;
+ ACPI_PNP_DEVICE_ID *Sub = NULL;
+ ACPI_PNP_DEVICE_ID *Cls = NULL;
+ char *NextIdString;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_NAME Name;
+ UINT8 ParamCount= 0;
+ UINT16 Valid = 0;
+ UINT32 InfoSize;
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!Handle || !ReturnBuffer)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Node = AcpiNsValidateHandle (Handle);
+ if (!Node)
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Get the namespace node data while the namespace is locked */
+
+ InfoSize = sizeof (ACPI_DEVICE_INFO);
+ Type = Node->Type;
+ Name = Node->Name.Integer;
+
+ if (Node->Type == ACPI_TYPE_METHOD)
+ {
+ ParamCount = Node->Object->Method.ParamCount;
+ }
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if ((Type == ACPI_TYPE_DEVICE) ||
+ (Type == ACPI_TYPE_PROCESSOR))
+ {
+ /*
+ * Get extra info for ACPI Device/Processor objects only:
+ * Run the Device _HID, _UID, _SUB, _CID, and _CLS methods.
+ *
+ * Note: none of these methods are required, so they may or may
+ * not be present for this device. The Info->Valid bitfield is used
+ * to indicate which methods were found and run successfully.
+ */
+
+ /* Execute the Device._HID method */
+
+ Status = AcpiUtExecute_HID (Node, &Hid);
+ if (ACPI_SUCCESS (Status))
+ {
+ InfoSize += Hid->Length;
+ Valid |= ACPI_VALID_HID;
+ }
+
+ /* Execute the Device._UID method */
+
+ Status = AcpiUtExecute_UID (Node, &Uid);
+ if (ACPI_SUCCESS (Status))
+ {
+ InfoSize += Uid->Length;
+ Valid |= ACPI_VALID_UID;
+ }
+
+ /* Execute the Device._SUB method */
+
+ Status = AcpiUtExecute_SUB (Node, &Sub);
+ if (ACPI_SUCCESS (Status))
+ {
+ InfoSize += Sub->Length;
+ Valid |= ACPI_VALID_SUB;
+ }
+
+ /* Execute the Device._CID method */
+
+ Status = AcpiUtExecute_CID (Node, &CidList);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Add size of CID strings and CID pointer array */
+
+ InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST));
+ Valid |= ACPI_VALID_CID;
+ }
+
+ /* Execute the Device._CLS method */
+
+ Status = AcpiUtExecute_CLS (Node, &Cls);
+ if (ACPI_SUCCESS (Status))
+ {
+ InfoSize += Cls->Length;
+ Valid |= ACPI_VALID_CLS;
+ }
+ }
+
+ /*
+ * Now that we have the variable-length data, we can allocate the
+ * return buffer
+ */
+ Info = ACPI_ALLOCATE_ZEROED (InfoSize);
+ if (!Info)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Get the fixed-length data */
+
+ if ((Type == ACPI_TYPE_DEVICE) ||
+ (Type == ACPI_TYPE_PROCESSOR))
+ {
+ /*
+ * Get extra info for ACPI Device/Processor objects only:
+ * Run the _STA, _ADR and, SxW, and _SxD methods.
+ *
+ * Notes: none of these methods are required, so they may or may
+ * not be present for this device. The Info->Valid bitfield is used
+ * to indicate which methods were found and run successfully.
+ *
+ * For _STA, if the method does not exist, then (as per the ACPI
+ * specification), the returned CurrentStatus flags will indicate
+ * that the device is present/functional/enabled. Otherwise, the
+ * CurrentStatus flags reflect the value returned from _STA.
+ */
+
+ /* Execute the Device._STA method */
+
+ Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
+ if (ACPI_SUCCESS (Status))
+ {
+ Valid |= ACPI_VALID_STA;
+ }
+
+ /* Execute the Device._ADR method */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
+ &Info->Address);
+ if (ACPI_SUCCESS (Status))
+ {
+ Valid |= ACPI_VALID_ADR;
+ }
+
+ /* Execute the Device._SxW methods */
+
+ Status = AcpiUtExecutePowerMethods (Node,
+ AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
+ Info->LowestDstates);
+ if (ACPI_SUCCESS (Status))
+ {
+ Valid |= ACPI_VALID_SXWS;
+ }
+
+ /* Execute the Device._SxD methods */
+
+ Status = AcpiUtExecutePowerMethods (Node,
+ AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
+ Info->HighestDstates);
+ if (ACPI_SUCCESS (Status))
+ {
+ Valid |= ACPI_VALID_SXDS;
+ }
+ }
+
+ /*
+ * Create a pointer to the string area of the return buffer.
+ * Point to the end of the base ACPI_DEVICE_INFO structure.
+ */
+ NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
+ if (CidList)
+ {
+ /* Point past the CID PNP_DEVICE_ID array */
+
+ NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID));
+ }
+
+ /*
+ * Copy the HID, UID, SUB, and CIDs to the return buffer.
+ * The variable-length strings are copied to the reserved area
+ * at the end of the buffer.
+ *
+ * For HID and CID, check if the ID is a PCI Root Bridge.
+ */
+ if (Hid)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
+ Hid, NextIdString);
+
+ if (AcpiUtIsPciRootBridge (Hid->String))
+ {
+ Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
+ }
+ }
+
+ if (Uid)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
+ Uid, NextIdString);
+ }
+
+ if (Sub)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->SubsystemId,
+ Sub, NextIdString);
+ }
+
+ if (CidList)
+ {
+ Info->CompatibleIdList.Count = CidList->Count;
+ Info->CompatibleIdList.ListSize = CidList->ListSize;
+
+ /* Copy each CID */
+
+ for (i = 0; i < CidList->Count; i++)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
+ &CidList->Ids[i], NextIdString);
+
+ if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
+ {
+ Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
+ }
+ }
+ }
+
+ if (Cls)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->ClassCode,
+ Cls, NextIdString);
+ }
+
+ /* Copy the fixed-length data */
+
+ Info->InfoSize = InfoSize;
+ Info->Type = Type;
+ Info->Name = Name;
+ Info->ParamCount = ParamCount;
+ Info->Valid = Valid;
+
+ *ReturnBuffer = Info;
+ Status = AE_OK;
+
+
+Cleanup:
+ if (Hid)
+ {
+ ACPI_FREE (Hid);
+ }
+ if (Uid)
+ {
+ ACPI_FREE (Uid);
+ }
+ if (Sub)
+ {
+ ACPI_FREE (Sub);
+ }
+ if (CidList)
+ {
+ ACPI_FREE (CidList);
+ }
+ if (Cls)
+ {
+ ACPI_FREE (Cls);
+ }
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetObjectInfo)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiInstallMethod
+ *
+ * PARAMETERS: Buffer - An ACPI table containing one control method
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a control method into the namespace. If the method
+ * name already exists in the namespace, it is overwritten. The
+ * input buffer must contain a valid DSDT or SSDT containing a
+ * single control method.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallMethod (
+ UINT8 *Buffer)
+{
+ ACPI_TABLE_HEADER *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer);
+ UINT8 *AmlBuffer;
+ UINT8 *AmlStart;
+ char *Path;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *MethodObj;
+ ACPI_PARSE_STATE ParserState;
+ UINT32 AmlLength;
+ UINT16 Opcode;
+ UINT8 MethodFlags;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!Buffer)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Table must be a DSDT or SSDT */
+
+ if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) &&
+ !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
+ {
+ return (AE_BAD_HEADER);
+ }
+
+ /* First AML opcode in the table must be a control method */
+
+ ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER);
+ Opcode = AcpiPsPeekOpcode (&ParserState);
+ if (Opcode != AML_METHOD_OP)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Extract method information from the raw AML */
+
+ ParserState.Aml += AcpiPsGetOpcodeSize (Opcode);
+ ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState);
+ Path = AcpiPsGetNextNamestring (&ParserState);
+ MethodFlags = *ParserState.Aml++;
+ AmlStart = ParserState.Aml;
+ AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart);
+
+ /*
+ * Allocate resources up-front. We don't want to have to delete a new
+ * node from the namespace if we cannot allocate memory.
+ */
+ AmlBuffer = ACPI_ALLOCATE (AmlLength);
+ if (!AmlBuffer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ if (!MethodObj)
+ {
+ ACPI_FREE (AmlBuffer);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Lock namespace for AcpiNsLookup, we may be creating a new node */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ /* The lookup either returns an existing node or creates a new one */
+
+ Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ if (ACPI_FAILURE (Status)) /* NsLookup */
+ {
+ if (Status != AE_ALREADY_EXISTS)
+ {
+ goto ErrorExit;
+ }
+
+ /* Node existed previously, make sure it is a method node */
+
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ Status = AE_TYPE;
+ goto ErrorExit;
+ }
+ }
+
+ /* Copy the method AML to the local buffer */
+
+ memcpy (AmlBuffer, AmlStart, AmlLength);
+
+ /* Initialize the method object with the new method's information */
+
+ MethodObj->Method.AmlStart = AmlBuffer;
+ MethodObj->Method.AmlLength = AmlLength;
+
+ MethodObj->Method.ParamCount = (UINT8)
+ (MethodFlags & AML_METHOD_ARG_COUNT);
+
+ if (MethodFlags & AML_METHOD_SERIALIZED)
+ {
+ MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED;
+
+ MethodObj->Method.SyncLevel = (UINT8)
+ ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
+ }
+
+ /*
+ * Now that it is complete, we can attach the new method object to
+ * the method Node (detaches/deletes any existing object)
+ */
+ Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD);
+
+ /*
+ * Flag indicates AML buffer is dynamic, must be deleted later.
+ * Must be set only after attach above.
+ */
+ Node->Flags |= ANOBJ_ALLOCATED_BUFFER;
+
+ /* Remove local reference to the method object */
+
+ AcpiUtRemoveReference (MethodObj);
+ return (Status);
+
+
+ErrorExit:
+
+ ACPI_FREE (AmlBuffer);
+ ACPI_FREE (MethodObj);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallMethod)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfobj.c b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfobj.c
new file mode 100644
index 0000000000..2481e7af43
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/namespace/nsxfobj.c
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ *
+ * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
+ * ACPI Object oriented interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME ("nsxfobj")
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetType
+ *
+ * PARAMETERS: Handle - Handle of object whose type is desired
+ * RetType - Where the type will be placed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This routine returns the type associatd with a particular handle
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetType (
+ ACPI_HANDLE Handle,
+ ACPI_OBJECT_TYPE *RetType)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Parameter Validation */
+
+ if (!RetType)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Special case for the predefined Root Node
+ * (return type ANY)
+ */
+ if (Handle == ACPI_ROOT_OBJECT)
+ {
+ *RetType = ACPI_TYPE_ANY;
+ return (AE_OK);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Convert and validate the handle */
+
+ Node = AcpiNsValidateHandle (Handle);
+ if (!Node)
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (AE_BAD_PARAMETER);
+ }
+
+ *RetType = Node->Type;
+
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetType)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetParent
+ *
+ * PARAMETERS: Handle - Handle of object whose parent is desired
+ * RetHandle - Where the parent handle will be placed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Returns a handle to the parent of the object represented by
+ * Handle.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetParent (
+ ACPI_HANDLE Handle,
+ ACPI_HANDLE *RetHandle)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_STATUS Status;
+
+
+ if (!RetHandle)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Special case for the predefined Root Node (no parent) */
+
+ if (Handle == ACPI_ROOT_OBJECT)
+ {
+ return (AE_NULL_ENTRY);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Convert and validate the handle */
+
+ Node = AcpiNsValidateHandle (Handle);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Get the parent entry */
+
+ ParentNode = Node->Parent;
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, ParentNode);
+
+ /* Return exception if parent is null */
+
+ if (!ParentNode)
+ {
+ Status = AE_NULL_ENTRY;
+ }
+
+
+UnlockAndExit:
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetParent)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetNextObject
+ *
+ * PARAMETERS: Type - Type of object to be searched for
+ * Parent - Parent object whose children we are getting
+ * LastChild - Previous child that was found.
+ * The NEXT child will be returned
+ * RetHandle - Where handle to the next object is placed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Return the next peer object within the namespace. If Handle is
+ * valid, Scope is ignored. Otherwise, the first object within
+ * Scope is returned.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetNextObject (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE Parent,
+ ACPI_HANDLE Child,
+ ACPI_HANDLE *RetHandle)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *ParentNode = NULL;
+ ACPI_NAMESPACE_NODE *ChildNode = NULL;
+
+
+ /* Parameter validation */
+
+ if (Type > ACPI_TYPE_EXTERNAL_MAX)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* If null handle, use the parent */
+
+ if (!Child)
+ {
+ /* Start search at the beginning of the specified scope */
+
+ ParentNode = AcpiNsValidateHandle (Parent);
+ if (!ParentNode)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+ }
+ else
+ {
+ /* Non-null handle, ignore the parent */
+ /* Convert and validate the handle */
+
+ ChildNode = AcpiNsValidateHandle (Child);
+ if (!ChildNode)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+ }
+
+ /* Internal function does the real work */
+
+ Node = AcpiNsGetNextNodeTyped (Type, ParentNode, ChildNode);
+ if (!Node)
+ {
+ Status = AE_NOT_FOUND;
+ goto UnlockAndExit;
+ }
+
+ if (RetHandle)
+ {
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
+ }
+
+
+UnlockAndExit:
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetNextObject)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psargs.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psargs.c
new file mode 100644
index 0000000000..5bf8a1a3b5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psargs.c
@@ -0,0 +1,932 @@
+/******************************************************************************
+ *
+ * Module Name: psargs - Parse AML opcode arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psargs")
+
+/* Local prototypes */
+
+static UINT32
+AcpiPsGetNextPackageLength (
+ ACPI_PARSE_STATE *ParserState);
+
+static ACPI_PARSE_OBJECT *
+AcpiPsGetNextField (
+ ACPI_PARSE_STATE *ParserState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextPackageLength
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: Decoded package length. On completion, the AML pointer points
+ * past the length byte or bytes.
+ *
+ * DESCRIPTION: Decode and return a package length field.
+ * Note: Largest package length is 28 bits, from ACPI specification
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiPsGetNextPackageLength (
+ ACPI_PARSE_STATE *ParserState)
+{
+ UINT8 *Aml = ParserState->Aml;
+ UINT32 PackageLength = 0;
+ UINT32 ByteCount;
+ UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */
+
+
+ ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
+
+
+ /*
+ * Byte 0 bits [6:7] contain the number of additional bytes
+ * used to encode the package length, either 0,1,2, or 3
+ */
+ ByteCount = (Aml[0] >> 6);
+ ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
+
+ /* Get bytes 3, 2, 1 as needed */
+
+ while (ByteCount)
+ {
+ /*
+ * Final bit positions for the package length bytes:
+ * Byte3->[20:27]
+ * Byte2->[12:19]
+ * Byte1->[04:11]
+ * Byte0->[00:03]
+ */
+ PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
+
+ ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
+ ByteCount--;
+ }
+
+ /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
+
+ PackageLength |= (Aml[0] & ByteZeroMask);
+ return_UINT32 (PackageLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextPackageEnd
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: Pointer to end-of-package +1
+ *
+ * DESCRIPTION: Get next package length and return a pointer past the end of
+ * the package. Consumes the package length field
+ *
+ ******************************************************************************/
+
+UINT8 *
+AcpiPsGetNextPackageEnd (
+ ACPI_PARSE_STATE *ParserState)
+{
+ UINT8 *Start = ParserState->Aml;
+ UINT32 PackageLength;
+
+
+ ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
+
+
+ /* Function below updates ParserState->Aml */
+
+ PackageLength = AcpiPsGetNextPackageLength (ParserState);
+
+ return_PTR (Start + PackageLength); /* end of package */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextNamestring
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: Pointer to the start of the name string (pointer points into
+ * the AML.
+ *
+ * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
+ * prefix characters. Set parser state to point past the string.
+ * (Name is consumed from the AML.)
+ *
+ ******************************************************************************/
+
+char *
+AcpiPsGetNextNamestring (
+ ACPI_PARSE_STATE *ParserState)
+{
+ UINT8 *Start = ParserState->Aml;
+ UINT8 *End = ParserState->Aml;
+
+
+ ACPI_FUNCTION_TRACE (PsGetNextNamestring);
+
+
+ /* Point past any namestring prefix characters (backslash or carat) */
+
+ while (ACPI_IS_ROOT_PREFIX (*End) ||
+ ACPI_IS_PARENT_PREFIX (*End))
+ {
+ End++;
+ }
+
+ /* Decode the path prefix character */
+
+ switch (*End)
+ {
+ case 0:
+
+ /* NullName */
+
+ if (End == Start)
+ {
+ Start = NULL;
+ }
+ End++;
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+
+ /* Two name segments */
+
+ End += 1 + (2 * ACPI_NAME_SIZE);
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ /* Multiple name segments, 4 chars each, count in next byte */
+
+ End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
+ break;
+
+ default:
+
+ /* Single name segment */
+
+ End += ACPI_NAME_SIZE;
+ break;
+ }
+
+ ParserState->Aml = End;
+ return_PTR ((char *) Start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextNamepath
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ * Arg - Where the namepath will be stored
+ * ArgCount - If the namepath points to a control method
+ * the method's argument is returned here.
+ * PossibleMethodCall - Whether the namepath can possibly be the
+ * start of a method call
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get next name (if method call, return # of required args).
+ * Names are looked up in the internal namespace to determine
+ * if the name represents a control method. If a method
+ * is found, the number of arguments to the method is returned.
+ * This information is critical for parsing to continue correctly.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsGetNextNamepath (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *Arg,
+ BOOLEAN PossibleMethodCall)
+{
+ ACPI_STATUS Status;
+ char *Path;
+ ACPI_PARSE_OBJECT *NameOp;
+ ACPI_OPERAND_OBJECT *MethodDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT8 *Start = ParserState->Aml;
+
+
+ ACPI_FUNCTION_TRACE (PsGetNextNamepath);
+
+
+ Path = AcpiPsGetNextNamestring (ParserState);
+ AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
+
+ /* Null path case is allowed, just exit */
+
+ if (!Path)
+ {
+ Arg->Common.Value.Name = Path;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Lookup the name in the internal namespace, starting with the current
+ * scope. We don't want to add anything new to the namespace here,
+ * however, so we use MODE_EXECUTE.
+ * Allow searching of the parent tree, but don't open a new scope -
+ * we just want to lookup the object (must be mode EXECUTE to perform
+ * the upsearch)
+ */
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
+
+ /*
+ * If this name is a control method invocation, we must
+ * setup the method call
+ */
+ if (ACPI_SUCCESS (Status) &&
+ PossibleMethodCall &&
+ (Node->Type == ACPI_TYPE_METHOD))
+ {
+ if (WalkState->Opcode == AML_UNLOAD_OP)
+ {
+ /*
+ * AcpiPsGetNextNamestring has increased the AML pointer,
+ * so we need to restore the saved AML pointer for method call.
+ */
+ WalkState->ParserState.Aml = Start;
+ WalkState->ArgCount = 1;
+ AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* This name is actually a control method invocation */
+
+ MethodDesc = AcpiNsGetAttachedObject (Node);
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
+
+ NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
+ if (!NameOp)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Change Arg into a METHOD CALL and attach name to it */
+
+ AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
+ NameOp->Common.Value.Name = Path;
+
+ /* Point METHODCALL/NAME to the METHOD Node */
+
+ NameOp->Common.Node = Node;
+ AcpiPsAppendArg (Arg, NameOp);
+
+ if (!MethodDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Control Method %p has no attached object",
+ Node));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Control Method - %p Args %X\n",
+ Node, MethodDesc->Method.ParamCount));
+
+ /* Get the number of arguments to expect */
+
+ WalkState->ArgCount = MethodDesc->Method.ParamCount;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Special handling if the name was not found during the lookup -
+ * some NotFound cases are allowed
+ */
+ if (Status == AE_NOT_FOUND)
+ {
+ /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
+
+ if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
+ ACPI_PARSE_EXECUTE)
+ {
+ Status = AE_OK;
+ }
+
+ /* 2) NotFound during a CondRefOf(x) is ok by definition */
+
+ else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
+ {
+ Status = AE_OK;
+ }
+
+ /*
+ * 3) NotFound while building a Package is ok at this point, we
+ * may flag as an error later if slack mode is not enabled.
+ * (Some ASL code depends on allowing this behavior)
+ */
+ else if ((Arg->Common.Parent) &&
+ ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ Status = AE_OK;
+ }
+ }
+
+ /* Final exception check (may have been changed from code above) */
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Path, Status);
+
+ if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
+ ACPI_PARSE_EXECUTE)
+ {
+ /* Report a control method execution error */
+
+ Status = AcpiDsMethodError (Status, WalkState);
+ }
+ }
+
+ /* Save the namepath */
+
+ Arg->Common.Value.Name = Path;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextSimpleArg
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ * ArgType - The argument type (AML_*_ARG)
+ * Arg - Where the argument is returned
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
+ *
+ ******************************************************************************/
+
+void
+AcpiPsGetNextSimpleArg (
+ ACPI_PARSE_STATE *ParserState,
+ UINT32 ArgType,
+ ACPI_PARSE_OBJECT *Arg)
+{
+ UINT32 Length;
+ UINT16 Opcode;
+ UINT8 *Aml = ParserState->Aml;
+
+
+ ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
+
+
+ switch (ArgType)
+ {
+ case ARGP_BYTEDATA:
+
+ /* Get 1 byte from the AML stream */
+
+ Opcode = AML_BYTE_OP;
+ Arg->Common.Value.Integer = (UINT64) *Aml;
+ Length = 1;
+ break;
+
+ case ARGP_WORDDATA:
+
+ /* Get 2 bytes from the AML stream */
+
+ Opcode = AML_WORD_OP;
+ ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 2;
+ break;
+
+ case ARGP_DWORDDATA:
+
+ /* Get 4 bytes from the AML stream */
+
+ Opcode = AML_DWORD_OP;
+ ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 4;
+ break;
+
+ case ARGP_QWORDDATA:
+
+ /* Get 8 bytes from the AML stream */
+
+ Opcode = AML_QWORD_OP;
+ ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 8;
+ break;
+
+ case ARGP_CHARLIST:
+
+ /* Get a pointer to the string, point past the string */
+
+ Opcode = AML_STRING_OP;
+ Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
+
+ /* Find the null terminator */
+
+ Length = 0;
+ while (Aml[Length])
+ {
+ Length++;
+ }
+ Length++;
+ break;
+
+ case ARGP_NAME:
+ case ARGP_NAMESTRING:
+
+ AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
+ Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
+ return_VOID;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
+ return_VOID;
+ }
+
+ AcpiPsInitOp (Arg, Opcode);
+ ParserState->Aml += Length;
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextField
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: A newly allocated FIELD op
+ *
+ * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+AcpiPsGetNextField (
+ ACPI_PARSE_STATE *ParserState)
+{
+ UINT8 *Aml;
+ ACPI_PARSE_OBJECT *Field;
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ UINT16 Opcode;
+ UINT32 Name;
+ UINT8 AccessType;
+ UINT8 AccessAttribute;
+ UINT8 AccessLength;
+ UINT32 PkgLength;
+ UINT8 *PkgEnd;
+ UINT32 BufferLength;
+
+
+ ACPI_FUNCTION_TRACE (PsGetNextField);
+
+
+ Aml = ParserState->Aml;
+
+ /* Determine field type */
+
+ switch (ACPI_GET8 (ParserState->Aml))
+ {
+ case AML_FIELD_OFFSET_OP:
+
+ Opcode = AML_INT_RESERVEDFIELD_OP;
+ ParserState->Aml++;
+ break;
+
+ case AML_FIELD_ACCESS_OP:
+
+ Opcode = AML_INT_ACCESSFIELD_OP;
+ ParserState->Aml++;
+ break;
+
+ case AML_FIELD_CONNECTION_OP:
+
+ Opcode = AML_INT_CONNECTION_OP;
+ ParserState->Aml++;
+ break;
+
+ case AML_FIELD_EXT_ACCESS_OP:
+
+ Opcode = AML_INT_EXTACCESSFIELD_OP;
+ ParserState->Aml++;
+ break;
+
+ default:
+
+ Opcode = AML_INT_NAMEDFIELD_OP;
+ break;
+ }
+
+ /* Allocate a new field op */
+
+ Field = AcpiPsAllocOp (Opcode, Aml);
+ if (!Field)
+ {
+ return_PTR (NULL);
+ }
+
+ /* Decode the field type */
+
+ switch (Opcode)
+ {
+ case AML_INT_NAMEDFIELD_OP:
+
+ /* Get the 4-character name */
+
+ ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
+ AcpiPsSetName (Field, Name);
+ ParserState->Aml += ACPI_NAME_SIZE;
+
+ /* Get the length which is encoded as a package length */
+
+ Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
+ break;
+
+
+ case AML_INT_RESERVEDFIELD_OP:
+
+ /* Get the length which is encoded as a package length */
+
+ Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
+ break;
+
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+
+ /*
+ * Get AccessType and AccessAttrib and merge into the field Op
+ * AccessType is first operand, AccessAttribute is second. stuff
+ * these bytes into the node integer value for convenience.
+ */
+
+ /* Get the two bytes (Type/Attribute) */
+
+ AccessType = ACPI_GET8 (ParserState->Aml);
+ ParserState->Aml++;
+ AccessAttribute = ACPI_GET8 (ParserState->Aml);
+ ParserState->Aml++;
+
+ Field->Common.Value.Integer = (UINT8) AccessType;
+ Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
+
+ /* This opcode has a third byte, AccessLength */
+
+ if (Opcode == AML_INT_EXTACCESSFIELD_OP)
+ {
+ AccessLength = ACPI_GET8 (ParserState->Aml);
+ ParserState->Aml++;
+
+ Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
+ }
+ break;
+
+
+ case AML_INT_CONNECTION_OP:
+
+ /*
+ * Argument for Connection operator can be either a Buffer
+ * (resource descriptor), or a NameString.
+ */
+ Aml = ParserState->Aml;
+ if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
+ {
+ ParserState->Aml++;
+
+ PkgEnd = ParserState->Aml;
+ PkgLength = AcpiPsGetNextPackageLength (ParserState);
+ PkgEnd += PkgLength;
+
+ if (ParserState->Aml < PkgEnd)
+ {
+ /* Non-empty list */
+
+ Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
+ if (!Arg)
+ {
+ AcpiPsFreeOp (Field);
+ return_PTR (NULL);
+ }
+
+ /* Get the actual buffer length argument */
+
+ Opcode = ACPI_GET8 (ParserState->Aml);
+ ParserState->Aml++;
+
+ switch (Opcode)
+ {
+ case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
+
+ BufferLength = ACPI_GET8 (ParserState->Aml);
+ ParserState->Aml += 1;
+ break;
+
+ case AML_WORD_OP: /* AML_WORDDATA_ARG */
+
+ BufferLength = ACPI_GET16 (ParserState->Aml);
+ ParserState->Aml += 2;
+ break;
+
+ case AML_DWORD_OP: /* AML_DWORDATA_ARG */
+
+ BufferLength = ACPI_GET32 (ParserState->Aml);
+ ParserState->Aml += 4;
+ break;
+
+ default:
+
+ BufferLength = 0;
+ break;
+ }
+
+ /* Fill in bytelist data */
+
+ Arg->Named.Value.Size = BufferLength;
+ Arg->Named.Data = ParserState->Aml;
+ }
+
+ /* Skip to End of byte data */
+
+ ParserState->Aml = PkgEnd;
+ }
+ else
+ {
+ Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
+ if (!Arg)
+ {
+ AcpiPsFreeOp (Field);
+ return_PTR (NULL);
+ }
+
+ /* Get the Namestring argument */
+
+ Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
+ }
+
+ /* Link the buffer/namestring to parent (CONNECTION_OP) */
+
+ AcpiPsAppendArg (Field, Arg);
+ break;
+
+
+ default:
+
+ /* Opcode was set in previous switch */
+ break;
+ }
+
+ return_PTR (Field);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetNextArg
+ *
+ * PARAMETERS: WalkState - Current state
+ * ParserState - Current parser state object
+ * ArgType - The argument type (AML_*_ARG)
+ * ReturnArg - Where the next arg is returned
+ *
+ * RETURN: Status, and an op object containing the next argument.
+ *
+ * DESCRIPTION: Get next argument (including complex list arguments that require
+ * pushing the parser stack)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsGetNextArg (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_STATE *ParserState,
+ UINT32 ArgType,
+ ACPI_PARSE_OBJECT **ReturnArg)
+{
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ ACPI_PARSE_OBJECT *Prev = NULL;
+ ACPI_PARSE_OBJECT *Field;
+ UINT32 Subop;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
+
+
+ switch (ArgType)
+ {
+ case ARGP_BYTEDATA:
+ case ARGP_WORDDATA:
+ case ARGP_DWORDDATA:
+ case ARGP_CHARLIST:
+ case ARGP_NAME:
+ case ARGP_NAMESTRING:
+
+ /* Constants, strings, and namestrings are all the same size */
+
+ Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
+ if (!Arg)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
+ break;
+
+ case ARGP_PKGLENGTH:
+
+ /* Package length, nothing returned */
+
+ ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
+ break;
+
+ case ARGP_FIELDLIST:
+
+ if (ParserState->Aml < ParserState->PkgEnd)
+ {
+ /* Non-empty list */
+
+ while (ParserState->Aml < ParserState->PkgEnd)
+ {
+ Field = AcpiPsGetNextField (ParserState);
+ if (!Field)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ if (Prev)
+ {
+ Prev->Common.Next = Field;
+ }
+ else
+ {
+ Arg = Field;
+ }
+ Prev = Field;
+ }
+
+ /* Skip to End of byte data */
+
+ ParserState->Aml = ParserState->PkgEnd;
+ }
+ break;
+
+ case ARGP_BYTELIST:
+
+ if (ParserState->Aml < ParserState->PkgEnd)
+ {
+ /* Non-empty list */
+
+ Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
+ ParserState->Aml);
+ if (!Arg)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Fill in bytelist data */
+
+ Arg->Common.Value.Size = (UINT32)
+ ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
+ Arg->Named.Data = ParserState->Aml;
+
+ /* Skip to End of byte data */
+
+ ParserState->Aml = ParserState->PkgEnd;
+ }
+ break;
+
+ case ARGP_TARGET:
+ case ARGP_SUPERNAME:
+ case ARGP_SIMPLENAME:
+
+ Subop = AcpiPsPeekOpcode (ParserState);
+ if (Subop == 0 ||
+ AcpiPsIsLeadingChar (Subop) ||
+ ACPI_IS_ROOT_PREFIX (Subop) ||
+ ACPI_IS_PARENT_PREFIX (Subop))
+ {
+ /* NullName or NameString */
+
+ Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
+ if (!Arg)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* To support SuperName arg of Unload */
+
+ if (WalkState->Opcode == AML_UNLOAD_OP)
+ {
+ Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
+
+ /*
+ * If the SuperName arg of Unload is a method call,
+ * we have restored the AML pointer, just free this Arg
+ */
+ if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
+ {
+ AcpiPsFreeOp (Arg);
+ Arg = NULL;
+ }
+ }
+ else
+ {
+ Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
+ }
+ }
+ else
+ {
+ /* Single complex argument, nothing returned */
+
+ WalkState->ArgCount = 1;
+ }
+ break;
+
+ case ARGP_DATAOBJ:
+ case ARGP_TERMARG:
+
+ /* Single complex argument, nothing returned */
+
+ WalkState->ArgCount = 1;
+ break;
+
+ case ARGP_DATAOBJLIST:
+ case ARGP_TERMLIST:
+ case ARGP_OBJLIST:
+
+ if (ParserState->Aml < ParserState->PkgEnd)
+ {
+ /* Non-empty list of variable arguments, nothing returned */
+
+ WalkState->ArgCount = ACPI_VAR_ARGS;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
+ *ReturnArg = Arg;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psloop.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psloop.c
new file mode 100644
index 0000000000..01b84b983d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psloop.c
@@ -0,0 +1,637 @@
+/******************************************************************************
+ *
+ * Module Name: psloop - Main AML parse loop
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/*
+ * Parse the AML and build an operation tree as most interpreters, (such as
+ * Perl) do. Parsing is done by hand rather than with a YACC generated parser
+ * to tightly constrain stack and dynamic memory usage. Parsing is kept
+ * flexible and the code fairly compact by parsing based on a list of AML
+ * opcode templates in AmlOpInfo[].
+ */
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psloop")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiPsGetArguments (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiPsLinkModuleCode (
+ ACPI_PARSE_OBJECT *ParentOp,
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_OWNER_ID OwnerId);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetArguments
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Op start in AML
+ * Op - Current Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get arguments for passed Op.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiPsGetArguments (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
+ case AML_WORD_OP: /* AML_WORDDATA_ARG */
+ case AML_DWORD_OP: /* AML_DWORDATA_ARG */
+ case AML_QWORD_OP: /* AML_QWORDATA_ARG */
+ case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
+
+ /* Fill in constant or string argument directly */
+
+ AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
+ break;
+
+ case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
+
+ Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ WalkState->ArgTypes = 0;
+ break;
+
+ default:
+ /*
+ * Op is not a constant or string, append each argument to the Op
+ */
+ while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
+ {
+ WalkState->Aml = WalkState->ParserState.Aml;
+
+ Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (Arg)
+ {
+ AcpiPsAppendArg (Op, Arg);
+ }
+
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
+ }
+
+
+ /*
+ * Handle executable code at "module-level". This refers to
+ * executable opcodes that appear outside of any control method.
+ */
+ if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) &&
+ ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
+ {
+ /*
+ * We want to skip If/Else/While constructs during Pass1 because we
+ * want to actually conditionally execute the code during Pass2.
+ *
+ * Except for disassembly, where we always want to walk the
+ * If/Else/While packages
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_IF_OP:
+ case AML_ELSE_OP:
+ case AML_WHILE_OP:
+ /*
+ * Currently supported module-level opcodes are:
+ * IF/ELSE/WHILE. These appear to be the most common,
+ * and easiest to support since they open an AML
+ * package.
+ */
+ if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1)
+ {
+ AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart,
+ (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart),
+ WalkState->OwnerId);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Pass1: Skipping an If/Else/While body\n"));
+
+ /* Skip body of if/else/while in pass 1 */
+
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
+ break;
+
+ default:
+ /*
+ * Check for an unsupported executable opcode at module
+ * level. We must be in PASS1, the parent must be a SCOPE,
+ * The opcode class must be EXECUTE, and the opcode must
+ * not be an argument to another opcode.
+ */
+ if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) &&
+ (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
+ (!Arg))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Unsupported module-level executable opcode "
+ "0x%.2X at table offset 0x%.4X",
+ Op->Common.AmlOpcode,
+ (UINT32) (ACPI_PTR_DIFF (AmlOpStart,
+ WalkState->ParserState.AmlStart) +
+ sizeof (ACPI_TABLE_HEADER))));
+ }
+ }
+ break;
+ }
+ }
+
+ /* Special processing for certain opcodes */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+ /*
+ * Skip parsing of control method because we don't have enough
+ * info in the first pass to parse it correctly.
+ *
+ * Save the length and address of the body
+ */
+ Op->Named.Data = WalkState->ParserState.Aml;
+ Op->Named.Length = (UINT32)
+ (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
+
+ /* Skip body of method */
+
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
+ break;
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ if ((Op->Common.Parent) &&
+ (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
+ (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
+ {
+ /*
+ * Skip parsing of Buffers and Packages because we don't have
+ * enough info in the first pass to parse them correctly.
+ */
+ Op->Named.Data = AmlOpStart;
+ Op->Named.Length = (UINT32)
+ (WalkState->ParserState.PkgEnd - AmlOpStart);
+
+ /* Skip body */
+
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
+ }
+ break;
+
+ case AML_WHILE_OP:
+
+ if (WalkState->ControlState)
+ {
+ WalkState->ControlState->Control.PackageEnd =
+ WalkState->ParserState.PkgEnd;
+ }
+ break;
+
+ default:
+
+ /* No action for all other opcodes */
+
+ break;
+ }
+
+ break;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsLinkModuleCode
+ *
+ * PARAMETERS: ParentOp - Parent parser op
+ * AmlStart - Pointer to the AML
+ * AmlLength - Length of executable AML
+ * OwnerId - OwnerId of module level code
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Wrap the module-level code with a method object and link the
+ * object to the global list. Note, the mutex field of the method
+ * object is used to link multiple module-level code objects.
+ *
+ ******************************************************************************/
+
+static void
+AcpiPsLinkModuleCode (
+ ACPI_PARSE_OBJECT *ParentOp,
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_OWNER_ID OwnerId)
+{
+ ACPI_OPERAND_OBJECT *Prev;
+ ACPI_OPERAND_OBJECT *Next;
+ ACPI_OPERAND_OBJECT *MethodObj;
+ ACPI_NAMESPACE_NODE *ParentNode;
+
+
+ ACPI_FUNCTION_TRACE (PsLinkModuleCode);
+
+
+ /* Get the tail of the list */
+
+ Prev = Next = AcpiGbl_ModuleCodeList;
+ while (Next)
+ {
+ Prev = Next;
+ Next = Next->Method.Mutex;
+ }
+
+ /*
+ * Insert the module level code into the list. Merge it if it is
+ * adjacent to the previous element.
+ */
+ if (!Prev ||
+ ((Prev->Method.AmlStart + Prev->Method.AmlLength) != AmlStart))
+ {
+ /* Create, initialize, and link a new temporary method object */
+
+ MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ if (!MethodObj)
+ {
+ return_VOID;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Create/Link new code block: %p\n", MethodObj));
+
+ if (ParentOp->Common.Node)
+ {
+ ParentNode = ParentOp->Common.Node;
+ }
+ else
+ {
+ ParentNode = AcpiGbl_RootNode;
+ }
+
+ MethodObj->Method.AmlStart = AmlStart;
+ MethodObj->Method.AmlLength = AmlLength;
+ MethodObj->Method.OwnerId = OwnerId;
+ MethodObj->Method.InfoFlags |= ACPI_METHOD_MODULE_LEVEL;
+
+ /*
+ * Save the parent node in NextObject. This is cheating, but we
+ * don't want to expand the method object.
+ */
+ MethodObj->Method.NextObject =
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParentNode);
+
+ if (!Prev)
+ {
+ AcpiGbl_ModuleCodeList = MethodObj;
+ }
+ else
+ {
+ Prev->Method.Mutex = MethodObj;
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Appending to existing code block: %p\n", Prev));
+
+ Prev->Method.AmlLength += AmlLength;
+ }
+
+ return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsParseLoop
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
+ * a tree of ops.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsParseLoop (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Op = NULL; /* current op */
+ ACPI_PARSE_STATE *ParserState;
+ UINT8 *AmlOpStart = NULL;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
+
+
+ if (WalkState->DescendingCallback == NULL)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ ParserState = &WalkState->ParserState;
+ WalkState->ArgTypes = 0;
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+ if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
+ {
+ /* We are restarting a preempted control method */
+
+ if (AcpiPsHasCompletedScope (ParserState))
+ {
+ /*
+ * We must check if a predicate to an IF or WHILE statement
+ * was just completed
+ */
+ if ((ParserState->Scope->ParseScope.Op) &&
+ ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
+ (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
+ (WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_PREDICATE_EXECUTING))
+ {
+ /*
+ * A predicate was just completed, get the value of the
+ * predicate and branch based on that value
+ */
+ WalkState->Op = NULL;
+ Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
+ if (ACPI_FAILURE (Status) &&
+ ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
+ {
+ if (Status == AE_AML_NO_RETURN_VALUE)
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Invoked method did not return a value"));
+ }
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiPsNextParseState (WalkState, Op, Status);
+ }
+
+ AcpiPsPopScope (ParserState, &Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
+ }
+ else if (WalkState->PrevOp)
+ {
+ /* We were in the middle of an op */
+
+ Op = WalkState->PrevOp;
+ WalkState->ArgTypes = WalkState->PrevArgTypes;
+ }
+ }
+#endif
+
+ /* Iterative parsing loop, while there is more AML to process: */
+
+ while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
+ {
+ AmlOpStart = ParserState->Aml;
+ if (!Op)
+ {
+ Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_PARSE_CONTINUE)
+ {
+ continue;
+ }
+
+ if (Status == AE_CTRL_PARSE_PENDING)
+ {
+ Status = AE_OK;
+ }
+
+ if (Status == AE_CTRL_TERMINATE)
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+
+ AcpiExStartTraceOpcode (Op, WalkState);
+ }
+
+
+ /*
+ * Start ArgCount at zero because we don't know if there are
+ * any args yet
+ */
+ WalkState->ArgCount = 0;
+
+ /* Are there any arguments that must be processed? */
+
+ if (WalkState->ArgTypes)
+ {
+ /* Get arguments */
+
+ Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+ }
+
+ /* Check for arguments that need to be processed */
+
+ if (WalkState->ArgCount)
+ {
+ /*
+ * There are arguments (complex ones), push Op and
+ * prepare for argument
+ */
+ Status = AcpiPsPushScope (ParserState, Op,
+ WalkState->ArgTypes, WalkState->ArgCount);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+
+ Op = NULL;
+ continue;
+ }
+
+ /*
+ * All arguments have been processed -- Op is complete,
+ * prepare for next
+ */
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (WalkState->OpInfo->Flags & AML_NAMED)
+ {
+ if (Op->Common.AmlOpcode == AML_REGION_OP ||
+ Op->Common.AmlOpcode == AML_DATA_REGION_OP)
+ {
+ /*
+ * Skip parsing of control method or opregion body,
+ * because we don't have enough info in the first pass
+ * to parse them correctly.
+ *
+ * Completed parsing an OpRegion declaration, we now
+ * know the length.
+ */
+ Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
+ }
+ }
+
+ if (WalkState->OpInfo->Flags & AML_CREATE)
+ {
+ /*
+ * Backup to beginning of CreateXXXfield declaration (1 for
+ * Opcode)
+ *
+ * BodyLength is unknown until we parse the body
+ */
+ Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
+ }
+
+ if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
+ {
+ /*
+ * Backup to beginning of BankField declaration
+ *
+ * BodyLength is unknown until we parse the body
+ */
+ Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
+ }
+
+ /* This op complete, notify the dispatcher */
+
+ if (WalkState->AscendingCallback != NULL)
+ {
+ WalkState->Op = Op;
+ WalkState->Opcode = Op->Common.AmlOpcode;
+
+ Status = WalkState->AscendingCallback (WalkState);
+ Status = AcpiPsNextParseState (WalkState, Op, Status);
+ if (Status == AE_CTRL_PENDING)
+ {
+ Status = AE_OK;
+ }
+ }
+
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ } /* while ParserState->Aml */
+
+ Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psobject.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psobject.c
new file mode 100644
index 0000000000..07a6b28021
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psobject.c
@@ -0,0 +1,685 @@
+/******************************************************************************
+ *
+ * Module Name: psobject - Support for parse objects
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psobject")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiPsGetAmlOpcode (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetAmlOpcode
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Extract the next AML opcode from the input stream.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiPsGetAmlOpcode (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 AmlOffset;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
+
+
+ WalkState->Aml = WalkState->ParserState.Aml;
+ WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
+
+ /*
+ * First cut to determine what we have found:
+ * 1) A valid AML opcode
+ * 2) A name string
+ * 3) An unknown/invalid opcode
+ */
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
+
+ switch (WalkState->OpInfo->Class)
+ {
+ case AML_CLASS_ASCII:
+ case AML_CLASS_PREFIX:
+ /*
+ * Starts with a valid prefix or ASCII char, this is a name
+ * string. Convert the bare name string to a namepath.
+ */
+ WalkState->Opcode = AML_INT_NAMEPATH_OP;
+ WalkState->ArgTypes = ARGP_NAMESTRING;
+ break;
+
+ case AML_CLASS_UNKNOWN:
+
+ /* The opcode is unrecognized. Complain and skip unknown opcodes */
+
+ if (WalkState->PassNumber == 2)
+ {
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
+ WalkState->ParserState.AmlStart);
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
+ WalkState->Opcode,
+ (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))));
+
+ ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48);
+
+#ifdef ACPI_ASL_COMPILER
+ /*
+ * This is executed for the disassembler only. Output goes
+ * to the disassembled ASL output file.
+ */
+ AcpiOsPrintf (
+ "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
+ WalkState->Opcode,
+ (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)));
+
+ /* Dump the context surrounding the invalid opcode */
+
+ AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
+ 48, DB_BYTE_DISPLAY,
+ (AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16));
+ AcpiOsPrintf (" */\n");
+#endif
+ }
+
+ /* Increment past one-byte or two-byte opcode */
+
+ WalkState->ParserState.Aml++;
+ if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
+ {
+ WalkState->ParserState.Aml++;
+ }
+
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+
+ default:
+
+ /* Found opcode info, this is a normal opcode */
+
+ WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
+ WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
+ break;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsBuildNamedOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Begin of named Op in AML
+ * UnnamedOp - Early Op (not a named Op)
+ * Op - Returned Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse a named Op
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsBuildNamedOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *UnnamedOp,
+ ACPI_PARSE_OBJECT **Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Arg = NULL;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
+
+
+ UnnamedOp->Common.Value.Arg = NULL;
+ UnnamedOp->Common.ArgListLength = 0;
+ UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
+
+ /*
+ * Get and append arguments until we find the node that contains
+ * the name (the type ARGP_NAME).
+ */
+ while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
+ (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
+ {
+ Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiPsAppendArg (UnnamedOp, Arg);
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
+ }
+
+ /*
+ * Make sure that we found a NAME and didn't run out of arguments
+ */
+ if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ /* We know that this arg is a name, move to next arg */
+
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
+
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ WalkState->Op = NULL;
+
+ Status = WalkState->DescendingCallback (WalkState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status != AE_CTRL_TERMINATE)
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!*Op)
+ {
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+ }
+
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_PENDING)
+ {
+ Status = AE_CTRL_PARSE_PENDING;
+ }
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
+
+ if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
+ (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
+ {
+ /*
+ * Defer final parsing of an OperationRegion body, because we don't
+ * have enough info in the first pass to parse it correctly (i.e.,
+ * there may be method calls within the TermArg elements of the body.)
+ *
+ * However, we must continue parsing because the opregion is not a
+ * standalone package -- we don't know where the end is at this point.
+ *
+ * (Length is unknown until parse of the body complete)
+ */
+ (*Op)->Named.Data = AmlOpStart;
+ (*Op)->Named.Length = 0;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCreateOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Op start in AML
+ * NewOp - Returned Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get Op from AML
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsCreateOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT **NewOp)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_PARSE_OBJECT *NamedOp = NULL;
+ ACPI_PARSE_OBJECT *ParentScope;
+ UINT8 ArgumentCount;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
+
+
+ Status = AcpiPsGetAmlOpcode (WalkState);
+ if (Status == AE_CTRL_PARSE_CONTINUE)
+ {
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+ }
+
+ /* Create Op structure and append to parent's argument list */
+
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
+ Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ if (WalkState->OpInfo->Flags & AML_NAMED)
+ {
+ Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
+ AcpiPsFreeOp (Op);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ *NewOp = NamedOp;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Not a named opcode, just allocate Op and append to parent */
+
+ if (WalkState->OpInfo->Flags & AML_CREATE)
+ {
+ /*
+ * Backup to beginning of CreateXXXfield declaration
+ * BodyLength is unknown until we parse the body
+ */
+ Op->Named.Data = AmlOpStart;
+ Op->Named.Length = 0;
+ }
+
+ if (WalkState->Opcode == AML_BANK_FIELD_OP)
+ {
+ /*
+ * Backup to beginning of BankField declaration
+ * BodyLength is unknown until we parse the body
+ */
+ Op->Named.Data = AmlOpStart;
+ Op->Named.Length = 0;
+ }
+
+ ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
+ AcpiPsAppendArg (ParentScope, Op);
+
+ if (ParentScope)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_TARGET)
+ {
+ ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
+ if (ParentScope->Common.ArgListLength > ArgumentCount)
+ {
+ Op->Common.Flags |= ACPI_PARSEOP_TARGET;
+ }
+ }
+ else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
+ {
+ Op->Common.Flags |= ACPI_PARSEOP_TARGET;
+ }
+ }
+
+ if (WalkState->DescendingCallback != NULL)
+ {
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ WalkState->Op = *NewOp = Op;
+
+ Status = WalkState->DescendingCallback (WalkState, &Op);
+ Status = AcpiPsNextParseState (WalkState, Op, Status);
+ if (Status == AE_CTRL_PENDING)
+ {
+ Status = AE_CTRL_PARSE_PENDING;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCompleteOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * Op - Returned Op
+ * Status - Parse status before complete Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete Op
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsCompleteOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **Op,
+ ACPI_STATUS Status)
+{
+ ACPI_STATUS Status2;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
+
+
+ /*
+ * Finished one argument of the containing scope
+ */
+ WalkState->ParserState.Scope->ParseScope.ArgCount--;
+
+ /* Close this Op (will result in parse subtree deletion) */
+
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+
+ *Op = NULL;
+
+ switch (Status)
+ {
+ case AE_OK:
+
+ break;
+
+ case AE_CTRL_TRANSFER:
+
+ /* We are about to transfer to a called method */
+
+ WalkState->PrevOp = NULL;
+ WalkState->PrevArgTypes = WalkState->ArgTypes;
+ return_ACPI_STATUS (Status);
+
+ case AE_CTRL_END:
+
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+
+ if (*Op)
+ {
+ WalkState->Op = *Op;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
+ WalkState->Opcode = (*Op)->Common.AmlOpcode;
+
+ Status = WalkState->AscendingCallback (WalkState);
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
+
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+ }
+
+ Status = AE_OK;
+ break;
+
+ case AE_CTRL_BREAK:
+ case AE_CTRL_CONTINUE:
+
+ /* Pop off scopes until we find the While */
+
+ while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
+ {
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ }
+
+ /* Close this iteration of the While loop */
+
+ WalkState->Op = *Op;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
+ WalkState->Opcode = (*Op)->Common.AmlOpcode;
+
+ Status = WalkState->AscendingCallback (WalkState);
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
+
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+
+ Status = AE_OK;
+ break;
+
+ case AE_CTRL_TERMINATE:
+
+ /* Clean up */
+ do
+ {
+ if (*Op)
+ {
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+
+ AcpiUtDeleteGenericState (
+ AcpiUtPopGenericState (&WalkState->ControlState));
+ }
+
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+
+ } while (*Op);
+
+ return_ACPI_STATUS (AE_OK);
+
+ default: /* All other non-AE_OK status */
+
+ do
+ {
+ if (*Op)
+ {
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+ }
+
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+
+ } while (*Op);
+
+
+#if 0
+ /*
+ * TBD: Cleanup parse ops on error
+ */
+ if (*Op == NULL)
+ {
+ AcpiPsPopScope (ParserState, Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ }
+#endif
+ WalkState->PrevOp = NULL;
+ WalkState->PrevArgTypes = WalkState->ArgTypes;
+ return_ACPI_STATUS (Status);
+ }
+
+ /* This scope complete? */
+
+ if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
+ {
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
+ }
+ else
+ {
+ *Op = NULL;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCompleteFinalOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * Op - Current Op
+ * Status - Current parse status before complete last
+ * Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete last Op.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsCompleteFinalOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status)
+{
+ ACPI_STATUS Status2;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
+
+
+ /*
+ * Complete the last Op (if not completed), and clear the scope stack.
+ * It is easily possible to end an AML "package" with an unbounded number
+ * of open scopes (such as when several ASL blocks are closed with
+ * sequential closing braces). We want to terminate each one cleanly.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
+ do
+ {
+ if (Op)
+ {
+ if (WalkState->AscendingCallback != NULL)
+ {
+ WalkState->Op = Op;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ WalkState->Opcode = Op->Common.AmlOpcode;
+
+ Status = WalkState->AscendingCallback (WalkState);
+ Status = AcpiPsNextParseState (WalkState, Op, Status);
+ if (Status == AE_CTRL_PENDING)
+ {
+ Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ if (Status == AE_CTRL_TERMINATE)
+ {
+ Status = AE_OK;
+
+ /* Clean up */
+ do
+ {
+ if (Op)
+ {
+ Status2 = AcpiPsCompleteThisOp (WalkState, Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+ }
+
+ AcpiPsPopScope (&(WalkState->ParserState), &Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+
+ } while (Op);
+
+ return_ACPI_STATUS (Status);
+ }
+
+ else if (ACPI_FAILURE (Status))
+ {
+ /* First error is most important */
+
+ (void) AcpiPsCompleteThisOp (WalkState, Op);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ Status2 = AcpiPsCompleteThisOp (WalkState, Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
+ }
+
+ AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
+ &WalkState->ArgCount);
+
+ } while (Op);
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopcode.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopcode.c
new file mode 100644
index 0000000000..e351e4c59a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopcode.c
@@ -0,0 +1,343 @@
+/******************************************************************************
+ *
+ * Module Name: psopcode - Parser/Interpreter opcode information table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acopcode.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psopcode")
+
+
+/*******************************************************************************
+ *
+ * NAME: AcpiGbl_AmlOpInfo
+ *
+ * DESCRIPTION: Opcode table. Each entry contains <opcode, type, name, operands>
+ * The name is a simple ascii string, the operand specifier is an
+ * ascii string with one letter per operand. The letter specifies
+ * the operand type.
+ *
+ ******************************************************************************/
+
+/*
+ * Summary of opcode types/flags
+ *
+
+ Opcodes that have associated namespace objects (AML_NSOBJECT flag)
+
+ AML_SCOPE_OP
+ AML_DEVICE_OP
+ AML_THERMAL_ZONE_OP
+ AML_METHOD_OP
+ AML_POWER_RES_OP
+ AML_PROCESSOR_OP
+ AML_FIELD_OP
+ AML_INDEX_FIELD_OP
+ AML_BANK_FIELD_OP
+ AML_NAME_OP
+ AML_ALIAS_OP
+ AML_MUTEX_OP
+ AML_EVENT_OP
+ AML_REGION_OP
+ AML_CREATE_FIELD_OP
+ AML_CREATE_BIT_FIELD_OP
+ AML_CREATE_BYTE_FIELD_OP
+ AML_CREATE_WORD_FIELD_OP
+ AML_CREATE_DWORD_FIELD_OP
+ AML_CREATE_QWORD_FIELD_OP
+ AML_INT_NAMEDFIELD_OP
+ AML_INT_METHODCALL_OP
+ AML_INT_NAMEPATH_OP
+
+ Opcodes that are "namespace" opcodes (AML_NSOPCODE flag)
+
+ AML_SCOPE_OP
+ AML_DEVICE_OP
+ AML_THERMAL_ZONE_OP
+ AML_METHOD_OP
+ AML_POWER_RES_OP
+ AML_PROCESSOR_OP
+ AML_FIELD_OP
+ AML_INDEX_FIELD_OP
+ AML_BANK_FIELD_OP
+ AML_NAME_OP
+ AML_ALIAS_OP
+ AML_MUTEX_OP
+ AML_EVENT_OP
+ AML_REGION_OP
+ AML_INT_NAMEDFIELD_OP
+
+ Opcodes that have an associated namespace node (AML_NSNODE flag)
+
+ AML_SCOPE_OP
+ AML_DEVICE_OP
+ AML_THERMAL_ZONE_OP
+ AML_METHOD_OP
+ AML_POWER_RES_OP
+ AML_PROCESSOR_OP
+ AML_NAME_OP
+ AML_ALIAS_OP
+ AML_MUTEX_OP
+ AML_EVENT_OP
+ AML_REGION_OP
+ AML_CREATE_FIELD_OP
+ AML_CREATE_BIT_FIELD_OP
+ AML_CREATE_BYTE_FIELD_OP
+ AML_CREATE_WORD_FIELD_OP
+ AML_CREATE_DWORD_FIELD_OP
+ AML_CREATE_QWORD_FIELD_OP
+ AML_INT_NAMEDFIELD_OP
+ AML_INT_METHODCALL_OP
+ AML_INT_NAMEPATH_OP
+
+ Opcodes that define named ACPI objects (AML_NAMED flag)
+
+ AML_SCOPE_OP
+ AML_DEVICE_OP
+ AML_THERMAL_ZONE_OP
+ AML_METHOD_OP
+ AML_POWER_RES_OP
+ AML_PROCESSOR_OP
+ AML_NAME_OP
+ AML_ALIAS_OP
+ AML_MUTEX_OP
+ AML_EVENT_OP
+ AML_REGION_OP
+ AML_INT_NAMEDFIELD_OP
+
+ Opcodes that contain executable AML as part of the definition that
+ must be deferred until needed
+
+ AML_METHOD_OP
+ AML_VAR_PACKAGE_OP
+ AML_CREATE_FIELD_OP
+ AML_CREATE_BIT_FIELD_OP
+ AML_CREATE_BYTE_FIELD_OP
+ AML_CREATE_WORD_FIELD_OP
+ AML_CREATE_DWORD_FIELD_OP
+ AML_CREATE_QWORD_FIELD_OP
+ AML_REGION_OP
+ AML_BUFFER_OP
+
+ Field opcodes
+
+ AML_CREATE_FIELD_OP
+ AML_FIELD_OP
+ AML_INDEX_FIELD_OP
+ AML_BANK_FIELD_OP
+
+ Field "Create" opcodes
+
+ AML_CREATE_FIELD_OP
+ AML_CREATE_BIT_FIELD_OP
+ AML_CREATE_BYTE_FIELD_OP
+ AML_CREATE_WORD_FIELD_OP
+ AML_CREATE_DWORD_FIELD_OP
+ AML_CREATE_QWORD_FIELD_OP
+
+ ******************************************************************************/
+
+
+/*
+ * Master Opcode information table. A summary of everything we know about each
+ * opcode, all in one place.
+ */
+const ACPI_OPCODE_INFO AcpiGbl_AmlOpInfo[AML_NUM_OPCODES] =
+{
+/*! [Begin] no source code translation */
+/* Index Name Parser Args Interpreter Args ObjectType Class Type Flags */
+
+/* 00 */ ACPI_OP ("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+/* 01 */ ACPI_OP ("One", ARGP_ONE_OP, ARGI_ONE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+/* 02 */ ACPI_OP ("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP, ACPI_TYPE_LOCAL_ALIAS, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 03 */ ACPI_OP ("Name", ARGP_NAME_OP, ARGI_NAME_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 04 */ ACPI_OP ("ByteConst", ARGP_BYTE_OP, ARGI_BYTE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
+/* 05 */ ACPI_OP ("WordConst", ARGP_WORD_OP, ARGI_WORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
+/* 06 */ ACPI_OP ("DwordConst", ARGP_DWORD_OP, ARGI_DWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
+/* 07 */ ACPI_OP ("String", ARGP_STRING_OP, ARGI_STRING_OP, ACPI_TYPE_STRING, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
+/* 08 */ ACPI_OP ("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_LOCAL_SCOPE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 09 */ ACPI_OP ("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP, ACPI_TYPE_BUFFER, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0A */ ACPI_OP ("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0B */ ACPI_OP ("Method", ARGP_METHOD_OP, ARGI_METHOD_OP, ACPI_TYPE_METHOD, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 0C */ ACPI_OP ("Local0", ARGP_LOCAL0, ARGI_LOCAL0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0D */ ACPI_OP ("Local1", ARGP_LOCAL1, ARGI_LOCAL1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0E */ ACPI_OP ("Local2", ARGP_LOCAL2, ARGI_LOCAL2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 0F */ ACPI_OP ("Local3", ARGP_LOCAL3, ARGI_LOCAL3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 10 */ ACPI_OP ("Local4", ARGP_LOCAL4, ARGI_LOCAL4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 11 */ ACPI_OP ("Local5", ARGP_LOCAL5, ARGI_LOCAL5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 12 */ ACPI_OP ("Local6", ARGP_LOCAL6, ARGI_LOCAL6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 13 */ ACPI_OP ("Local7", ARGP_LOCAL7, ARGI_LOCAL7, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0),
+/* 14 */ ACPI_OP ("Arg0", ARGP_ARG0, ARGI_ARG0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 15 */ ACPI_OP ("Arg1", ARGP_ARG1, ARGI_ARG1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 16 */ ACPI_OP ("Arg2", ARGP_ARG2, ARGI_ARG2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 17 */ ACPI_OP ("Arg3", ARGP_ARG3, ARGI_ARG3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 18 */ ACPI_OP ("Arg4", ARGP_ARG4, ARGI_ARG4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 19 */ ACPI_OP ("Arg5", ARGP_ARG5, ARGI_ARG5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1A */ ACPI_OP ("Arg6", ARGP_ARG6, ARGI_ARG6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1B */ ACPI_OP ("Store", ARGP_STORE_OP, ARGI_STORE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
+/* 1C */ ACPI_OP ("RefOf", ARGP_REF_OF_OP, ARGI_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
+/* 1D */ ACPI_OP ("Add", ARGP_ADD_OP, ARGI_ADD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 1E */ ACPI_OP ("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 1F */ ACPI_OP ("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 20 */ ACPI_OP ("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 21 */ ACPI_OP ("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 22 */ ACPI_OP ("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 23 */ ACPI_OP ("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_2T_1R, AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT),
+/* 24 */ ACPI_OP ("ShiftLeft", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 25 */ ACPI_OP ("ShiftRight", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 26 */ ACPI_OP ("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 27 */ ACPI_OP ("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 28 */ ACPI_OP ("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 29 */ ACPI_OP ("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2A */ ACPI_OP ("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2B */ ACPI_OP ("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2C */ ACPI_OP ("FindSetLeftBit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2D */ ACPI_OP ("FindSetRightBit", ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2E */ ACPI_OP ("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
+/* 2F */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R),
+/* 30 */ ACPI_OP ("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R),
+/* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
+/* 33 */ ACPI_OP ("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 34 */ ACPI_OP ("CreateWordField", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+/* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3D */ ACPI_OP ("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3E */ ACPI_OP ("If", ARGP_IF_OP, ARGI_IF_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 3F */ ACPI_OP ("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 40 */ ACPI_OP ("While", ARGP_WHILE_OP, ARGI_WHILE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 41 */ ACPI_OP ("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 42 */ ACPI_OP ("Return", ARGP_RETURN_OP, ARGI_RETURN_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
+/* 43 */ ACPI_OP ("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 44 */ ACPI_OP ("BreakPoint", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 45 */ ACPI_OP ("Ones", ARGP_ONES_OP, ARGI_ONES_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
+
+/* Prefixed opcodes (Two-byte opcodes with a prefix op) */
+
+/* 46 */ ACPI_OP ("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, ACPI_TYPE_MUTEX, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 47 */ ACPI_OP ("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, ACPI_TYPE_EVENT, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
+/* 48 */ ACPI_OP ("CondRefOf", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
+/* 49 */ ACPI_OP ("CreateField", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_FIELD | AML_CREATE),
+/* 4A */ ACPI_OP ("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R, AML_FLAGS_EXEC_1A_1T_0R),
+/* 4B */ ACPI_OP ("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 4C */ ACPI_OP ("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 4D */ ACPI_OP ("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
+/* 4E */ ACPI_OP ("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 4F */ ACPI_OP ("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
+/* 50 */ ACPI_OP ("Reset", ARGP_RESET_OP, ARGI_RESET_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 51 */ ACPI_OP ("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 52 */ ACPI_OP ("FromBCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 53 */ ACPI_OP ("ToBCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 54 */ ACPI_OP ("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
+/* 55 */ ACPI_OP ("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0),
+/* 56 */ ACPI_OP ("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0),
+/* 57 */ ACPI_OP ("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R, AML_FLAGS_EXEC_3A_0T_0R),
+/* 58 */ ACPI_OP ("OperationRegion", ARGP_REGION_OP, ARGI_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 59 */ ACPI_OP ("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+/* 5A */ ACPI_OP ("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP, ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5B */ ACPI_OP ("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP, ACPI_TYPE_PROCESSOR, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5C */ ACPI_OP ("PowerResource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP, ACPI_TYPE_POWER, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5D */ ACPI_OP ("ThermalZone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP, ACPI_TYPE_THERMAL, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5E */ ACPI_OP ("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+/* 5F */ ACPI_OP ("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD | AML_DEFER),
+
+/* Internal opcodes that map to invalid AML opcodes */
+
+/* 60 */ ACPI_OP ("LNotEqual", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
+/* 61 */ ACPI_OP ("LLessEqual", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
+/* 62 */ ACPI_OP ("LGreaterEqual", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
+/* 63 */ ACPI_OP ("-NamePath-", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE ),
+/* 64 */ ACPI_OP ("-MethodCall-", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP, ACPI_TYPE_METHOD, AML_CLASS_METHOD_CALL, AML_TYPE_METHOD_CALL, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE),
+/* 65 */ ACPI_OP ("-ByteList-", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP, ACPI_TYPE_ANY, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0),
+/* 66 */ ACPI_OP ("-ReservedField-", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 67 */ ACPI_OP ("-NamedField-", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
+/* 68 */ ACPI_OP ("-AccessField-", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 69 */ ACPI_OP ("-StaticString", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+/* 6A */ ACPI_OP ("-Return Value-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN, AML_HAS_ARGS | AML_HAS_RETVAL),
+/* 6B */ ACPI_OP ("-UNKNOWN_OP-", ARG_NONE, ARG_NONE, ACPI_TYPE_INVALID, AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 6C */ ACPI_OP ("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 6D */ ACPI_OP ("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS),
+
+/* ACPI 2.0 opcodes */
+
+/* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
+/* 6F */ ACPI_OP ("Package", /* Var */ ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER),
+/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 72 */ ACPI_OP ("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 73 */ ACPI_OP ("ToBuffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 74 */ ACPI_OP ("ToDecimalString", ARGP_TO_DEC_STR_OP, ARGI_TO_DEC_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 75 */ ACPI_OP ("ToHexString", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 76 */ ACPI_OP ("ToInteger", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 77 */ ACPI_OP ("ToString", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 78 */ ACPI_OP ("CopyObject", ARGP_COPY_OP, ARGI_COPY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
+/* 79 */ ACPI_OP ("Mid", ARGP_MID_OP, ARGI_MID_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R, AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT),
+/* 7A */ ACPI_OP ("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
+/* 7B */ ACPI_OP ("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
+/* 7C */ ACPI_OP ("DataTableRegion", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 7D */ ACPI_OP ("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE),
+
+/* ACPI 3.0 opcodes */
+
+/* 7E */ ACPI_OP ("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, AML_FLAGS_EXEC_0A_0T_1R),
+
+/* ACPI 5.0 opcodes */
+
+/* 7F */ ACPI_OP ("-ConnectField-", ARGP_CONNECTFIELD_OP, ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS),
+/* 80 */ ACPI_OP ("-ExtAccessField-", ARGP_CONNECTFIELD_OP, ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
+
+/* ACPI 6.0 opcodes */
+
+/* 81 */ ACPI_OP ("External", ARGP_EXTERNAL_OP, ARGI_EXTERNAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE,/* ? */ AML_TYPE_EXEC_3A_0T_0R, AML_FLAGS_EXEC_3A_0T_0R)
+
+/*! [End] no source code translation !*/
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopinfo.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopinfo.c
new file mode 100644
index 0000000000..f7f62488ea
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psopinfo.c
@@ -0,0 +1,284 @@
+/******************************************************************************
+ *
+ * Module Name: psopinfo - AML opcode information functions and dispatch tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acopcode.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psopinfo")
+
+
+static const UINT8 AcpiGbl_ArgumentCount[] = {0,1,1,1,1,2,2,2,2,3,3,6};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetOpcodeInfo
+ *
+ * PARAMETERS: Opcode - The AML opcode
+ *
+ * RETURN: A pointer to the info about the opcode.
+ *
+ * DESCRIPTION: Find AML opcode description based on the opcode.
+ * NOTE: This procedure must ALWAYS return a valid pointer!
+ *
+ ******************************************************************************/
+
+const ACPI_OPCODE_INFO *
+AcpiPsGetOpcodeInfo (
+ UINT16 Opcode)
+{
+#ifdef ACPI_DEBUG_OUTPUT
+ const char *OpcodeName = "Unknown AML opcode";
+#endif
+
+ ACPI_FUNCTION_NAME (PsGetOpcodeInfo);
+
+
+ /*
+ * Detect normal 8-bit opcode or extended 16-bit opcode
+ */
+ if (!(Opcode & 0xFF00))
+ {
+ /* Simple (8-bit) opcode: 0-255, can't index beyond table */
+
+ return (&AcpiGbl_AmlOpInfo [AcpiGbl_ShortOpIndex [(UINT8) Opcode]]);
+ }
+
+ if (((Opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
+ (((UINT8) Opcode) <= MAX_EXTENDED_OPCODE))
+ {
+ /* Valid extended (16-bit) opcode */
+
+ return (&AcpiGbl_AmlOpInfo [AcpiGbl_LongOpIndex [(UINT8) Opcode]]);
+ }
+
+#if defined ACPI_ASL_COMPILER && defined ACPI_DEBUG_OUTPUT
+#include <contrib/dev/acpica/compiler/asldefine.h>
+
+ switch (Opcode)
+ {
+ case AML_RAW_DATA_BYTE:
+ OpcodeName = "-Raw Data Byte-";
+ break;
+
+ case AML_RAW_DATA_WORD:
+ OpcodeName = "-Raw Data Word-";
+ break;
+
+ case AML_RAW_DATA_DWORD:
+ OpcodeName = "-Raw Data Dword-";
+ break;
+
+ case AML_RAW_DATA_QWORD:
+ OpcodeName = "-Raw Data Qword-";
+ break;
+
+ case AML_RAW_DATA_BUFFER:
+ OpcodeName = "-Raw Data Buffer-";
+ break;
+
+ case AML_RAW_DATA_CHAIN:
+ OpcodeName = "-Raw Data Buffer Chain-";
+ break;
+
+ case AML_PACKAGE_LENGTH:
+ OpcodeName = "-Package Length-";
+ break;
+
+ case AML_UNASSIGNED_OPCODE:
+ OpcodeName = "-Unassigned Opcode-";
+ break;
+
+ case AML_DEFAULT_ARG_OP:
+ OpcodeName = "-Default Arg-";
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ /* Unknown AML opcode */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "%s [%4.4X]\n", OpcodeName, Opcode));
+
+ return (&AcpiGbl_AmlOpInfo [_UNK]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetOpcodeName
+ *
+ * PARAMETERS: Opcode - The AML opcode
+ *
+ * RETURN: A pointer to the name of the opcode (ASCII String)
+ * Note: Never returns NULL.
+ *
+ * DESCRIPTION: Translate an opcode into a human-readable string
+ *
+ ******************************************************************************/
+
+char *
+AcpiPsGetOpcodeName (
+ UINT16 Opcode)
+{
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+
+ const ACPI_OPCODE_INFO *Op;
+
+
+ Op = AcpiPsGetOpcodeInfo (Opcode);
+
+ /* Always guaranteed to return a valid pointer */
+
+ return (Op->Name);
+
+#else
+ return ("OpcodeName unavailable");
+
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetArgumentCount
+ *
+ * PARAMETERS: OpType - Type associated with the AML opcode
+ *
+ * RETURN: Argument count
+ *
+ * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiPsGetArgumentCount (
+ UINT32 OpType)
+{
+
+ if (OpType <= AML_TYPE_EXEC_6A_0T_1R)
+ {
+ return (AcpiGbl_ArgumentCount[OpType]);
+ }
+
+ return (0);
+}
+
+
+/*
+ * This table is directly indexed by the opcodes It returns
+ * an index into the opcode table (AcpiGbl_AmlOpInfo)
+ */
+const UINT8 AcpiGbl_ShortOpIndex[256] =
+{
+/* 0 1 2 3 4 5 6 7 */
+/* 8 9 A B C D E F */
+/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
+/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
+/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, 0x81, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
+/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
+/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
+/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
+/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
+/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
+/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
+/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
+/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
+/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
+};
+
+/*
+ * This table is indexed by the second opcode of the extended opcode
+ * pair. It returns an index into the opcode table (AcpiGbl_AmlOpInfo)
+ */
+const UINT8 AcpiGbl_LongOpIndex[NUM_EXTENDED_OPCODE] =
+{
+/* 0 1 2 3 4 5 6 7 */
+/* 8 9 A B C D E F */
+/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
+/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+/* 0x88 */ 0x7C,
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psparse.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psparse.c
new file mode 100644
index 0000000000..7d160a478d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psparse.c
@@ -0,0 +1,707 @@
+/******************************************************************************
+ *
+ * Module Name: psparse - Parser top level AML parse routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/*
+ * Parse the AML and build an operation tree as most interpreters,
+ * like Perl, do. Parsing is done by hand rather than with a YACC
+ * generated parser to tightly constrain stack and dynamic memory
+ * usage. At the same time, parsing is kept flexible and the code
+ * fairly compact by parsing based on a list of AML opcode
+ * templates in AmlOpInfo[]
+ */
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psparse")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetOpcodeSize
+ *
+ * PARAMETERS: Opcode - An AML opcode
+ *
+ * RETURN: Size of the opcode, in bytes (1 or 2)
+ *
+ * DESCRIPTION: Get the size of the current opcode.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiPsGetOpcodeSize (
+ UINT32 Opcode)
+{
+
+ /* Extended (2-byte) opcode if > 255 */
+
+ if (Opcode > 0x00FF)
+ {
+ return (2);
+ }
+
+ /* Otherwise, just a single byte opcode */
+
+ return (1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsPeekOpcode
+ *
+ * PARAMETERS: ParserState - A parser state object
+ *
+ * RETURN: Next AML opcode
+ *
+ * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
+ *
+ ******************************************************************************/
+
+UINT16
+AcpiPsPeekOpcode (
+ ACPI_PARSE_STATE *ParserState)
+{
+ UINT8 *Aml;
+ UINT16 Opcode;
+
+
+ Aml = ParserState->Aml;
+ Opcode = (UINT16) ACPI_GET8 (Aml);
+
+ if (Opcode == AML_EXTENDED_OP_PREFIX)
+ {
+ /* Extended opcode, get the second opcode byte */
+
+ Aml++;
+ Opcode = (UINT16) ((Opcode << 8) | ACPI_GET8 (Aml));
+ }
+
+ return (Opcode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCompleteThisOp
+ *
+ * PARAMETERS: WalkState - Current State
+ * Op - Op to complete
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform any cleanup at the completion of an Op.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsCompleteThisOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Prev;
+ ACPI_PARSE_OBJECT *Next;
+ const ACPI_OPCODE_INFO *ParentInfo;
+ ACPI_PARSE_OBJECT *ReplacementOp = NULL;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCompleteThisOp, Op);
+
+
+ /* Check for null Op, can happen if AML code is corrupt */
+
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_OK); /* OK for now */
+ }
+
+ AcpiExStopTraceOpcode (Op, WalkState);
+
+ /* Delete this op and the subtree below it if asked to */
+
+ if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
+ (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Make sure that we only delete this subtree */
+
+ if (Op->Common.Parent)
+ {
+ Prev = Op->Common.Parent->Common.Value.Arg;
+ if (!Prev)
+ {
+ /* Nothing more to do */
+
+ goto Cleanup;
+ }
+
+ /*
+ * Check if we need to replace the operator and its subtree
+ * with a return value op (placeholder op)
+ */
+ ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
+
+ switch (ParentInfo->Class)
+ {
+ case AML_CLASS_CONTROL:
+
+ break;
+
+ case AML_CLASS_CREATE:
+ /*
+ * These opcodes contain TermArg operands. The current
+ * op must be replaced by a placeholder return op
+ */
+ ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
+ Op->Common.Aml);
+ if (!ReplacementOp)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ break;
+
+ case AML_CLASS_NAMED_OBJECT:
+ /*
+ * These opcodes contain TermArg operands. The current
+ * op must be replaced by a placeholder return op
+ */
+ if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
+ Op->Common.Aml);
+ if (!ReplacementOp)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ }
+ else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
+ (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
+ {
+ if ((Op->Common.AmlOpcode == AML_BUFFER_OP) ||
+ (Op->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode,
+ Op->Common.Aml);
+ if (!ReplacementOp)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ else
+ {
+ ReplacementOp->Named.Data = Op->Named.Data;
+ ReplacementOp->Named.Length = Op->Named.Length;
+ }
+ }
+ }
+ break;
+
+ default:
+
+ ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP,
+ Op->Common.Aml);
+ if (!ReplacementOp)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ }
+
+ /* We must unlink this op from the parent tree */
+
+ if (Prev == Op)
+ {
+ /* This op is the first in the list */
+
+ if (ReplacementOp)
+ {
+ ReplacementOp->Common.Parent = Op->Common.Parent;
+ ReplacementOp->Common.Value.Arg = NULL;
+ ReplacementOp->Common.Node = Op->Common.Node;
+ Op->Common.Parent->Common.Value.Arg = ReplacementOp;
+ ReplacementOp->Common.Next = Op->Common.Next;
+ }
+ else
+ {
+ Op->Common.Parent->Common.Value.Arg = Op->Common.Next;
+ }
+ }
+
+ /* Search the parent list */
+
+ else while (Prev)
+ {
+ /* Traverse all siblings in the parent's argument list */
+
+ Next = Prev->Common.Next;
+ if (Next == Op)
+ {
+ if (ReplacementOp)
+ {
+ ReplacementOp->Common.Parent = Op->Common.Parent;
+ ReplacementOp->Common.Value.Arg = NULL;
+ ReplacementOp->Common.Node = Op->Common.Node;
+ Prev->Common.Next = ReplacementOp;
+ ReplacementOp->Common.Next = Op->Common.Next;
+ Next = NULL;
+ }
+ else
+ {
+ Prev->Common.Next = Op->Common.Next;
+ Next = NULL;
+ }
+ }
+ Prev = Next;
+ }
+ }
+
+
+Cleanup:
+
+ /* Now we can actually delete the subtree rooted at Op */
+
+ AcpiPsDeleteParseTree (Op);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsNextParseState
+ *
+ * PARAMETERS: WalkState - Current state
+ * Op - Current parse op
+ * CallbackStatus - Status from previous operation
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Update the parser state based upon the return exception from
+ * the parser callback.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsNextParseState (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS CallbackStatus)
+{
+ ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
+ ACPI_STATUS Status = AE_CTRL_PENDING;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsNextParseState, Op);
+
+
+ switch (CallbackStatus)
+ {
+ case AE_CTRL_TERMINATE:
+ /*
+ * A control method was terminated via a RETURN statement.
+ * The walk of this method is complete.
+ */
+ ParserState->Aml = ParserState->AmlEnd;
+ Status = AE_CTRL_TERMINATE;
+ break;
+
+ case AE_CTRL_BREAK:
+
+ ParserState->Aml = WalkState->AmlLastWhile;
+ WalkState->ControlState->Common.Value = FALSE;
+ Status = AE_CTRL_BREAK;
+ break;
+
+ case AE_CTRL_CONTINUE:
+
+ ParserState->Aml = WalkState->AmlLastWhile;
+ Status = AE_CTRL_CONTINUE;
+ break;
+
+ case AE_CTRL_PENDING:
+
+ ParserState->Aml = WalkState->AmlLastWhile;
+ break;
+
+#if 0
+ case AE_CTRL_SKIP:
+
+ ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
+ Status = AE_OK;
+ break;
+#endif
+
+ case AE_CTRL_TRUE:
+ /*
+ * Predicate of an IF was true, and we are at the matching ELSE.
+ * Just close out this package
+ */
+ ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);
+ Status = AE_CTRL_PENDING;
+ break;
+
+ case AE_CTRL_FALSE:
+ /*
+ * Either an IF/WHILE Predicate was false or we encountered a BREAK
+ * opcode. In both cases, we do not execute the rest of the
+ * package; We simply close out the parent (finishing the walk of
+ * this branch of the tree) and continue execution at the parent
+ * level.
+ */
+ ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
+
+ /* In the case of a BREAK, just force a predicate (if any) to FALSE */
+
+ WalkState->ControlState->Common.Value = FALSE;
+ Status = AE_CTRL_END;
+ break;
+
+ case AE_CTRL_TRANSFER:
+
+ /* A method call (invocation) -- transfer control */
+
+ Status = AE_CTRL_TRANSFER;
+ WalkState->PrevOp = Op;
+ WalkState->MethodCallOp = Op;
+ WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;
+
+ /* Will return value (if any) be used by the caller? */
+
+ WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
+ break;
+
+ default:
+
+ Status = CallbackStatus;
+ if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
+ {
+ Status = AE_OK;
+ }
+ break;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsParseAml
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse raw AML and return a tree of ops
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsParseAml (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_THREAD_STATE *Thread;
+ ACPI_THREAD_STATE *PrevWalkList = AcpiGbl_CurrentWalkList;
+ ACPI_WALK_STATE *PreviousWalkState;
+
+
+ ACPI_FUNCTION_TRACE (PsParseAml);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Entered with WalkState=%p Aml=%p size=%X\n",
+ WalkState, WalkState->ParserState.Aml,
+ WalkState->ParserState.AmlSize));
+
+ if (!WalkState->ParserState.Aml)
+ {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Create and initialize a new thread state */
+
+ Thread = AcpiUtCreateThreadState ();
+ if (!Thread)
+ {
+ if (WalkState->MethodDesc)
+ {
+ /* Executing a control method - additional cleanup */
+
+ AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
+ }
+
+ AcpiDsDeleteWalkState (WalkState);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ WalkState->Thread = Thread;
+
+ /*
+ * If executing a method, the starting SyncLevel is this method's
+ * SyncLevel
+ */
+ if (WalkState->MethodDesc)
+ {
+ WalkState->Thread->CurrentSyncLevel = WalkState->MethodDesc->Method.SyncLevel;
+ }
+
+ AcpiDsPushWalkState (WalkState, Thread);
+
+ /*
+ * This global allows the AML debugger to get a handle to the currently
+ * executing control method.
+ */
+ AcpiGbl_CurrentWalkList = Thread;
+
+ /*
+ * Execute the walk loop as long as there is a valid Walk State. This
+ * handles nested control method invocations without recursion.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", WalkState));
+
+ Status = AE_OK;
+ while (WalkState)
+ {
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * The ParseLoop executes AML until the method terminates
+ * or calls another method.
+ */
+ Status = AcpiPsParseLoop (WalkState);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Completed one call to walk loop, %s State=%p\n",
+ AcpiFormatException (Status), WalkState));
+
+ if (Status == AE_CTRL_TRANSFER)
+ {
+ /*
+ * A method call was detected.
+ * Transfer control to the called control method
+ */
+ Status = AcpiDsCallControlMethod (Thread, WalkState, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AcpiDsMethodError (Status, WalkState);
+ }
+
+ /*
+ * If the transfer to the new method method call worked, a new walk
+ * state was created -- get it
+ */
+ WalkState = AcpiDsGetCurrentWalkState (Thread);
+ continue;
+ }
+ else if (Status == AE_CTRL_TERMINATE)
+ {
+ Status = AE_OK;
+ }
+ else if ((Status != AE_OK) && (WalkState->MethodDesc))
+ {
+ /* Either the method parse or actual execution failed */
+
+ ACPI_ERROR_METHOD ("Method parse/execution failed",
+ WalkState->MethodNode, NULL, Status);
+
+ /* Check for possible multi-thread reentrancy problem */
+
+ if ((Status == AE_ALREADY_EXISTS) &&
+ (!(WalkState->MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)))
+ {
+ /*
+ * Method is not serialized and tried to create an object
+ * twice. The probable cause is that the method cannot
+ * handle reentrancy. Mark as "pending serialized" now, and
+ * then mark "serialized" when the last thread exits.
+ */
+ WalkState->MethodDesc->Method.InfoFlags |=
+ ACPI_METHOD_SERIALIZED_PENDING;
+ }
+ }
+
+ /* We are done with this walk, move on to the parent if any */
+
+ WalkState = AcpiDsPopWalkState (Thread);
+
+ /* Reset the current scope to the beginning of scope stack */
+
+ AcpiDsScopeStackClear (WalkState);
+
+ /*
+ * If we just returned from the execution of a control method or if we
+ * encountered an error during the method parse phase, there's lots of
+ * cleanup to do
+ */
+ if (((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) ||
+ (ACPI_FAILURE (Status)))
+ {
+ AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
+ }
+
+ /* Delete this walk state and all linked control states */
+
+ AcpiPsCleanupScope (&WalkState->ParserState);
+ PreviousWalkState = WalkState;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "ReturnValue=%p, ImplicitValue=%p State=%p\n",
+ WalkState->ReturnDesc, WalkState->ImplicitReturnObj, WalkState));
+
+ /* Check if we have restarted a preempted walk */
+
+ WalkState = AcpiDsGetCurrentWalkState (Thread);
+ if (WalkState)
+ {
+ if (ACPI_SUCCESS (Status))
+ {
+ /*
+ * There is another walk state, restart it.
+ * If the method return value is not used by the parent,
+ * The object is deleted
+ */
+ if (!PreviousWalkState->ReturnDesc)
+ {
+ /*
+ * In slack mode execution, if there is no return value
+ * we should implicitly return zero (0) as a default value.
+ */
+ if (AcpiGbl_EnableInterpreterSlack &&
+ !PreviousWalkState->ImplicitReturnObj)
+ {
+ PreviousWalkState->ImplicitReturnObj =
+ AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!PreviousWalkState->ImplicitReturnObj)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+
+ /* Restart the calling control method */
+
+ Status = AcpiDsRestartControlMethod (WalkState,
+ PreviousWalkState->ImplicitReturnObj);
+ }
+ else
+ {
+ /*
+ * We have a valid return value, delete any implicit
+ * return value.
+ */
+ AcpiDsClearImplicitReturn (PreviousWalkState);
+
+ Status = AcpiDsRestartControlMethod (WalkState,
+ PreviousWalkState->ReturnDesc);
+ }
+ if (ACPI_SUCCESS (Status))
+ {
+ WalkState->WalkType |= ACPI_WALK_METHOD_RESTART;
+ }
+ }
+ else
+ {
+ /* On error, delete any return object or implicit return */
+
+ AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
+ AcpiDsClearImplicitReturn (PreviousWalkState);
+ }
+ }
+
+ /*
+ * Just completed a 1st-level method, save the final internal return
+ * value (if any)
+ */
+ else if (PreviousWalkState->CallerReturnDesc)
+ {
+ if (PreviousWalkState->ImplicitReturnObj)
+ {
+ *(PreviousWalkState->CallerReturnDesc) =
+ PreviousWalkState->ImplicitReturnObj;
+ }
+ else
+ {
+ /* NULL if no return value */
+
+ *(PreviousWalkState->CallerReturnDesc) =
+ PreviousWalkState->ReturnDesc;
+ }
+ }
+ else
+ {
+ if (PreviousWalkState->ReturnDesc)
+ {
+ /* Caller doesn't want it, must delete it */
+
+ AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
+ }
+ if (PreviousWalkState->ImplicitReturnObj)
+ {
+ /* Caller doesn't want it, must delete it */
+
+ AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);
+ }
+ }
+
+ AcpiDsDeleteWalkState (PreviousWalkState);
+ }
+
+ /* Normal exit */
+
+ AcpiExReleaseAllMutexes (Thread);
+ AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));
+ AcpiGbl_CurrentWalkList = PrevWalkList;
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psscope.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psscope.c
new file mode 100644
index 0000000000..87e897e47a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psscope.c
@@ -0,0 +1,300 @@
+/******************************************************************************
+ *
+ * Module Name: psscope - Parser scope stack management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psscope")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetParentScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: Pointer to an Op object
+ *
+ * DESCRIPTION: Get parent of current op being parsed
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetParentScope (
+ ACPI_PARSE_STATE *ParserState)
+{
+
+ return (ParserState->Scope->ParseScope.Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsHasCompletedScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: Boolean, TRUE = scope completed.
+ *
+ * DESCRIPTION: Is parsing of current argument complete? Determined by
+ * 1) AML pointer is at or beyond the end of the scope
+ * 2) The scope argument count has reached zero.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiPsHasCompletedScope (
+ ACPI_PARSE_STATE *ParserState)
+{
+
+ return ((BOOLEAN)
+ ((ParserState->Aml >= ParserState->Scope->ParseScope.ArgEnd ||
+ !ParserState->Scope->ParseScope.ArgCount)));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsInitScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ * Root - the Root Node of this new scope
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate and init a new scope object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsInitScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *RootOp)
+{
+ ACPI_GENERIC_STATE *Scope;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsInitScope, RootOp);
+
+
+ Scope = AcpiUtCreateGenericState ();
+ if (!Scope)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Scope->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RPSCOPE;
+ Scope->ParseScope.Op = RootOp;
+ Scope->ParseScope.ArgCount = ACPI_VAR_ARGS;
+ Scope->ParseScope.ArgEnd = ParserState->AmlEnd;
+ Scope->ParseScope.PkgEnd = ParserState->AmlEnd;
+
+ ParserState->Scope = Scope;
+ ParserState->StartOp = RootOp;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsPushScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ * Op - Current op to be pushed
+ * RemainingArgs - List of args remaining
+ * ArgCount - Fixed or variable number of args
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push current op to begin parsing its argument
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsPushScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 RemainingArgs,
+ UINT32 ArgCount)
+{
+ ACPI_GENERIC_STATE *Scope;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsPushScope, Op);
+
+
+ Scope = AcpiUtCreateGenericState ();
+ if (!Scope)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Scope->Common.DescriptorType = ACPI_DESC_TYPE_STATE_PSCOPE;
+ Scope->ParseScope.Op = Op;
+ Scope->ParseScope.ArgList = RemainingArgs;
+ Scope->ParseScope.ArgCount = ArgCount;
+ Scope->ParseScope.PkgEnd = ParserState->PkgEnd;
+
+ /* Push onto scope stack */
+
+ AcpiUtPushGenericState (&ParserState->Scope, Scope);
+
+ if (ArgCount == ACPI_VAR_ARGS)
+ {
+ /* Multiple arguments */
+
+ Scope->ParseScope.ArgEnd = ParserState->PkgEnd;
+ }
+ else
+ {
+ /* Single argument */
+
+ Scope->ParseScope.ArgEnd = ACPI_TO_POINTER (ACPI_MAX_PTR);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsPopScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ * Op - Where the popped op is returned
+ * ArgList - Where the popped "next argument" is
+ * returned
+ * ArgCount - Count of objects in ArgList
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Return to parsing a previous op
+ *
+ ******************************************************************************/
+
+void
+AcpiPsPopScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT **Op,
+ UINT32 *ArgList,
+ UINT32 *ArgCount)
+{
+ ACPI_GENERIC_STATE *Scope = ParserState->Scope;
+
+
+ ACPI_FUNCTION_TRACE (PsPopScope);
+
+
+ /* Only pop the scope if there is in fact a next scope */
+
+ if (Scope->Common.Next)
+ {
+ Scope = AcpiUtPopGenericState (&ParserState->Scope);
+
+ /* Return to parsing previous op */
+
+ *Op = Scope->ParseScope.Op;
+ *ArgList = Scope->ParseScope.ArgList;
+ *ArgCount = Scope->ParseScope.ArgCount;
+ ParserState->PkgEnd = Scope->ParseScope.PkgEnd;
+
+ /* All done with this scope state structure */
+
+ AcpiUtDeleteGenericState (Scope);
+ }
+ else
+ {
+ /* Empty parse stack, prepare to fetch next opcode */
+
+ *Op = NULL;
+ *ArgList = 0;
+ *ArgCount = 0;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Popped Op %p Args %X\n", *Op, *ArgCount));
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCleanupScope
+ *
+ * PARAMETERS: ParserState - Current parser state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Destroy available list, remaining stack levels, and return
+ * root scope
+ *
+ ******************************************************************************/
+
+void
+AcpiPsCleanupScope (
+ ACPI_PARSE_STATE *ParserState)
+{
+ ACPI_GENERIC_STATE *Scope;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCleanupScope, ParserState);
+
+
+ if (!ParserState)
+ {
+ return_VOID;
+ }
+
+ /* Delete anything on the scope stack */
+
+ while (ParserState->Scope)
+ {
+ Scope = AcpiUtPopGenericState (&ParserState->Scope);
+ AcpiUtDeleteGenericState (Scope);
+ }
+
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/pstree.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/pstree.c
new file mode 100644
index 0000000000..daec8f30a0
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/pstree.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ * Module Name: pstree - Parser op tree manipulation/traversal/search
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("pstree")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_PARSE_OBJECT *
+AcpiPsGetChild (
+ ACPI_PARSE_OBJECT *op);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetArg
+ *
+ * PARAMETERS: Op - Get an argument for this op
+ * Argn - Nth argument to get
+ *
+ * RETURN: The argument (as an Op object). NULL if argument does not exist
+ *
+ * DESCRIPTION: Get the specified op's argument.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetArg (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Argn)
+{
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+/*
+ if (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP)
+ {
+ return (Op->Common.Value.Arg);
+ }
+*/
+ /* Get the info structure for this opcode */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ /* Invalid opcode or ASCII character */
+
+ return (NULL);
+ }
+
+ /* Check if this opcode requires argument sub-objects */
+
+ if (!(OpInfo->Flags & AML_HAS_ARGS))
+ {
+ /* Has no linked argument objects */
+
+ return (NULL);
+ }
+
+ /* Get the requested argument object */
+
+ Arg = Op->Common.Value.Arg;
+ while (Arg && Argn)
+ {
+ Argn--;
+ Arg = Arg->Common.Next;
+ }
+
+ return (Arg);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsAppendArg
+ *
+ * PARAMETERS: Op - Append an argument to this Op.
+ * Arg - Argument Op to append
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
+ *
+ ******************************************************************************/
+
+void
+AcpiPsAppendArg (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Arg)
+{
+ ACPI_PARSE_OBJECT *PrevArg;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Get the info structure for this opcode */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ /* Invalid opcode */
+
+ ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
+ Op->Common.AmlOpcode));
+ return;
+ }
+
+ /* Check if this opcode requires argument sub-objects */
+
+ if (!(OpInfo->Flags & AML_HAS_ARGS))
+ {
+ /* Has no linked argument objects */
+
+ return;
+ }
+
+ /* Append the argument to the linked argument list */
+
+ if (Op->Common.Value.Arg)
+ {
+ /* Append to existing argument list */
+
+ PrevArg = Op->Common.Value.Arg;
+ while (PrevArg->Common.Next)
+ {
+ PrevArg = PrevArg->Common.Next;
+ }
+ PrevArg->Common.Next = Arg;
+ }
+ else
+ {
+ /* No argument list, this will be the first argument */
+
+ Op->Common.Value.Arg = Arg;
+ }
+
+ /* Set the parent in this arg and any args linked after it */
+
+ while (Arg)
+ {
+ Arg->Common.Parent = Op;
+ Arg = Arg->Common.Next;
+
+ Op->Common.ArgListLength++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetDepthNext
+ *
+ * PARAMETERS: Origin - Root of subtree to search
+ * Op - Last (previous) Op that was found
+ *
+ * RETURN: Next Op found in the search.
+ *
+ * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
+ * Return NULL when reaching "origin" or when walking up from root
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetDepthNext (
+ ACPI_PARSE_OBJECT *Origin,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next = NULL;
+ ACPI_PARSE_OBJECT *Parent;
+ ACPI_PARSE_OBJECT *Arg;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!Op)
+ {
+ return (NULL);
+ }
+
+ /* Look for an argument or child */
+
+ Next = AcpiPsGetArg (Op, 0);
+ if (Next)
+ {
+ return (Next);
+ }
+
+ /* Look for a sibling */
+
+ Next = Op->Common.Next;
+ if (Next)
+ {
+ return (Next);
+ }
+
+ /* Look for a sibling of parent */
+
+ Parent = Op->Common.Parent;
+
+ while (Parent)
+ {
+ Arg = AcpiPsGetArg (Parent, 0);
+ while (Arg && (Arg != Origin) && (Arg != Op))
+ {
+ Arg = Arg->Common.Next;
+ }
+
+ if (Arg == Origin)
+ {
+ /* Reached parent of origin, end search */
+
+ return (NULL);
+ }
+
+ if (Parent->Common.Next)
+ {
+ /* Found sibling of parent */
+
+ return (Parent->Common.Next);
+ }
+
+ Op = Parent;
+ Parent = Parent->Common.Parent;
+ }
+
+ return (Next);
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetChild
+ *
+ * PARAMETERS: Op - Get the child of this Op
+ *
+ * RETURN: Child Op, Null if none is found.
+ *
+ * DESCRIPTION: Get op's children or NULL if none
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetChild (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Child = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_SCOPE_OP:
+ case AML_ELSE_OP:
+ case AML_DEVICE_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_INT_METHODCALL_OP:
+
+ Child = AcpiPsGetArg (Op, 0);
+ break;
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_METHOD_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+
+ Child = AcpiPsGetArg (Op, 1);
+ break;
+
+ case AML_POWER_RES_OP:
+ case AML_INDEX_FIELD_OP:
+
+ Child = AcpiPsGetArg (Op, 2);
+ break;
+
+ case AML_PROCESSOR_OP:
+ case AML_BANK_FIELD_OP:
+
+ Child = AcpiPsGetArg (Op, 3);
+ break;
+
+ default:
+
+ /* All others have no children */
+
+ break;
+ }
+
+ return (Child);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psutils.c
new file mode 100644
index 0000000000..d4b5dc5c21
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psutils.c
@@ -0,0 +1,280 @@
+/******************************************************************************
+ *
+ * Module Name: psutils - Parser miscellaneous utilities (Parser only)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCreateScopeOp
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: A new Scope object, null on failure
+ *
+ * DESCRIPTION: Create a Scope and associated namepath op with the root name
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+AcpiPsCreateScopeOp (
+ UINT8 *Aml)
+{
+ ACPI_PARSE_OBJECT *ScopeOp;
+
+
+ ScopeOp = AcpiPsAllocOp (AML_SCOPE_OP, Aml);
+ if (!ScopeOp)
+ {
+ return (NULL);
+ }
+
+ ScopeOp->Named.Name = ACPI_ROOT_NAME;
+ return (ScopeOp);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsInitOp
+ *
+ * PARAMETERS: Op - A newly allocated Op object
+ * Opcode - Opcode to store in the Op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a parse (Op) object
+ *
+ ******************************************************************************/
+
+void
+AcpiPsInitOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 Opcode)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Op->Common.DescriptorType = ACPI_DESC_TYPE_PARSER;
+ Op->Common.AmlOpcode = Opcode;
+
+ ACPI_DISASM_ONLY_MEMBERS (strncpy (Op->Common.AmlOpName,
+ (AcpiPsGetOpcodeInfo (Opcode))->Name,
+ sizeof (Op->Common.AmlOpName)));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsAllocOp
+ *
+ * PARAMETERS: Opcode - Opcode that will be stored in the new Op
+ * Aml - Address of the opcode
+ *
+ * RETURN: Pointer to the new Op, null on failure
+ *
+ * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
+ * opcode. A cache of opcodes is available for the pure
+ * GENERIC_OP, since this is by far the most commonly used.
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT*
+AcpiPsAllocOp (
+ UINT16 Opcode,
+ UINT8 *Aml)
+{
+ ACPI_PARSE_OBJECT *Op;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT8 Flags = ACPI_PARSEOP_GENERIC;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+
+ /* Determine type of ParseOp required */
+
+ if (OpInfo->Flags & AML_DEFER)
+ {
+ Flags = ACPI_PARSEOP_DEFERRED;
+ }
+ else if (OpInfo->Flags & AML_NAMED)
+ {
+ Flags = ACPI_PARSEOP_NAMED;
+ }
+ else if (Opcode == AML_INT_BYTELIST_OP)
+ {
+ Flags = ACPI_PARSEOP_BYTELIST;
+ }
+
+ /* Allocate the minimum required size object */
+
+ if (Flags == ACPI_PARSEOP_GENERIC)
+ {
+ /* The generic op (default) is by far the most common (16 to 1) */
+
+ Op = AcpiOsAcquireObject (AcpiGbl_PsNodeCache);
+ }
+ else
+ {
+ /* Extended parseop */
+
+ Op = AcpiOsAcquireObject (AcpiGbl_PsNodeExtCache);
+ }
+
+ /* Initialize the Op */
+
+ if (Op)
+ {
+ AcpiPsInitOp (Op, Opcode);
+ Op->Common.Aml = Aml;
+ Op->Common.Flags = Flags;
+ }
+
+ return (Op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsFreeOp
+ *
+ * PARAMETERS: Op - Op to be freed
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
+ * or actually free it.
+ *
+ ******************************************************************************/
+
+void
+AcpiPsFreeOp (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_FUNCTION_NAME (PsFreeOp);
+
+
+ if (Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", Op));
+ }
+
+ if (Op->Common.Flags & ACPI_PARSEOP_GENERIC)
+ {
+ (void) AcpiOsReleaseObject (AcpiGbl_PsNodeCache, Op);
+ }
+ else
+ {
+ (void) AcpiOsReleaseObject (AcpiGbl_PsNodeExtCache, Op);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Utility functions
+ *
+ * DESCRIPTION: Low level character and object functions
+ *
+ ******************************************************************************/
+
+
+/*
+ * Is "c" a namestring lead character?
+ */
+BOOLEAN
+AcpiPsIsLeadingChar (
+ UINT32 c)
+{
+ return ((BOOLEAN) (c == '_' || (c >= 'A' && c <= 'Z')));
+}
+
+
+/*
+ * Get op's name (4-byte name segment) or 0 if unnamed
+ */
+UINT32
+AcpiPsGetName (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* The "generic" object has no name associated with it */
+
+ if (Op->Common.Flags & ACPI_PARSEOP_GENERIC)
+ {
+ return (0);
+ }
+
+ /* Only the "Extended" parse objects have a name */
+
+ return (Op->Named.Name);
+}
+
+
+/*
+ * Set op's name
+ */
+void
+AcpiPsSetName (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 name)
+{
+
+ /* The "generic" object has no name associated with it */
+
+ if (Op->Common.Flags & ACPI_PARSEOP_GENERIC)
+ {
+ return;
+ }
+
+ Op->Named.Name = name;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/pswalk.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/pswalk.c
new file mode 100644
index 0000000000..044b0683af
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/pswalk.c
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ * Module Name: pswalk - Parser routines to walk parsed op tree(s)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("pswalk")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsDeleteParseTree
+ *
+ * PARAMETERS: SubtreeRoot - Root of tree (or subtree) to delete
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
+ *
+ ******************************************************************************/
+
+void
+AcpiPsDeleteParseTree (
+ ACPI_PARSE_OBJECT *SubtreeRoot)
+{
+ ACPI_PARSE_OBJECT *Op = SubtreeRoot;
+ ACPI_PARSE_OBJECT *Next = NULL;
+ ACPI_PARSE_OBJECT *Parent = NULL;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsDeleteParseTree, SubtreeRoot);
+
+
+ /* Visit all nodes in the subtree */
+
+ while (Op)
+ {
+ /* Check if we are not ascending */
+
+ if (Op != Parent)
+ {
+ /* Look for an argument or child of the current op */
+
+ Next = AcpiPsGetArg (Op, 0);
+ if (Next)
+ {
+ /* Still going downward in tree (Op is not completed yet) */
+
+ Op = Next;
+ continue;
+ }
+ }
+
+ /* No more children, this Op is complete. */
+
+ Next = Op->Common.Next;
+ Parent = Op->Common.Parent;
+
+ AcpiPsFreeOp (Op);
+
+ /* If we are back to the starting point, the walk is complete. */
+
+ if (Op == SubtreeRoot)
+ {
+ return_VOID;
+ }
+ if (Next)
+ {
+ Op = Next;
+ }
+ else
+ {
+ Op = Parent;
+ }
+ }
+
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/parser/psxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psxface.c
new file mode 100644
index 0000000000..8195a56f20
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/parser/psxface.c
@@ -0,0 +1,309 @@
+/******************************************************************************
+ *
+ * Module Name: psxface - Parser external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdispat.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_PARSER
+ ACPI_MODULE_NAME ("psxface")
+
+/* Local Prototypes */
+
+static void
+AcpiPsUpdateParameterList (
+ ACPI_EVALUATE_INFO *Info,
+ UINT16 Action);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDebugTrace
+ *
+ * PARAMETERS: MethodName - Valid ACPI name string
+ * DebugLevel - Optional level mask. 0 to use default
+ * DebugLayer - Optional layer mask. 0 to use default
+ * Flags - bit 1: one shot(1) or persistent(0)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: External interface to enable debug tracing during control
+ * method execution
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDebugTrace (
+ const char *Name,
+ UINT32 DebugLevel,
+ UINT32 DebugLayer,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiGbl_TraceMethodName = Name;
+ AcpiGbl_TraceFlags = Flags;
+ AcpiGbl_TraceDbgLevel = DebugLevel;
+ AcpiGbl_TraceDbgLayer = DebugLayer;
+ Status = AE_OK;
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsExecuteMethod
+ *
+ * PARAMETERS: Info - Method info block, contains:
+ * Node - Method Node to execute
+ * ObjDesc - Method object
+ * Parameters - List of parameters to pass to the method,
+ * terminated by NULL. Params itself may be
+ * NULL if no parameters are being passed.
+ * ReturnObject - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * ParameterType - Type of Parameter list
+ * ReturnObject - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * PassNumber - Parse or execute pass
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsExecuteMethod (
+ ACPI_EVALUATE_INFO *Info)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE (PsExecuteMethod);
+
+
+ /* Quick validation of DSDT header */
+
+ AcpiTbCheckDsdtHeader ();
+
+ /* Validate the Info and method Node */
+
+ if (!Info || !Info->Node)
+ {
+ return_ACPI_STATUS (AE_NULL_ENTRY);
+ }
+
+ /* Init for new method, wait on concurrency semaphore */
+
+ Status = AcpiDsBeginMethodExecution (Info->Node, Info->ObjDesc, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * The caller "owns" the parameters, so give each one an extra reference
+ */
+ AcpiPsUpdateParameterList (Info, REF_INCREMENT);
+
+ /*
+ * Execute the method. Performs parse simultaneously
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
+ Info->Node->Name.Ascii, Info->Node, Info->ObjDesc));
+
+ /* Create and init a Root Node */
+
+ Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart);
+ if (!Op)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Create and initialize a new walk state */
+
+ Info->PassNumber = ACPI_IMODE_EXECUTE;
+ WalkState = AcpiDsCreateWalkState (
+ Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node,
+ Info->ObjDesc->Method.AmlStart,
+ Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
+ {
+ WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL;
+ }
+
+ /* Invoke an internal method if necessary */
+
+ if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
+ {
+ Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState);
+ Info->ReturnObject = WalkState->ReturnDesc;
+
+ /* Cleanup states */
+
+ AcpiDsScopeStackClear (WalkState);
+ AcpiPsCleanupScope (&WalkState->ParserState);
+ AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /*
+ * Start method evaluation with an implicit return of zero.
+ * This is done for Windows compatibility.
+ */
+ if (AcpiGbl_EnableInterpreterSlack)
+ {
+ WalkState->ImplicitReturnObj =
+ AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!WalkState->ImplicitReturnObj)
+ {
+ Status = AE_NO_MEMORY;
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+ }
+
+ /* Parse the AML */
+
+ Status = AcpiPsParseAml (WalkState);
+
+ /* WalkState was deleted by ParseAml */
+
+Cleanup:
+ AcpiPsDeleteParseTree (Op);
+
+ /* Take away the extra reference that we gave the parameters above */
+
+ AcpiPsUpdateParameterList (Info, REF_DECREMENT);
+
+ /* Exit now if error above */
+
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * If the method has returned an object, signal this to the caller with
+ * a control exception code
+ */
+ if (Info->ReturnObject)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
+ Info->ReturnObject));
+ ACPI_DUMP_STACK_ENTRY (Info->ReturnObject);
+
+ Status = AE_CTRL_RETURN_VALUE;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsUpdateParameterList
+ *
+ * PARAMETERS: Info - See ACPI_EVALUATE_INFO
+ * (Used: ParameterType and Parameters)
+ * Action - Add or Remove reference
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Update reference count on all method parameter objects
+ *
+ ******************************************************************************/
+
+static void
+AcpiPsUpdateParameterList (
+ ACPI_EVALUATE_INFO *Info,
+ UINT16 Action)
+{
+ UINT32 i;
+
+
+ if (Info->Parameters)
+ {
+ /* Update reference count for each parameter */
+
+ for (i = 0; Info->Parameters[i]; i++)
+ {
+ /* Ignore errors, just do them all */
+
+ (void) AcpiUtUpdateObjectReference (Info->Parameters[i], Action);
+ }
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsaddr.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsaddr.c
new file mode 100644
index 0000000000..decd9a653d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsaddr.c
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ *
+ * Module Name: rsaddr - Address resource descriptors (16/32/64)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsaddr")
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertAddress16 - All WORD (16-bit) address resources
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertAddress16[5] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS16),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress16)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
+ sizeof (AML_RESOURCE_ADDRESS16),
+ 0},
+
+ /* Resource Type, General Flags, and Type-Specific Flags */
+
+ {ACPI_RSC_ADDRESS, 0, 0, 0},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.Address16.Address.Granularity),
+ AML_OFFSET (Address16.Granularity),
+ 5},
+
+ /* Optional ResourceSource (Index and String) */
+
+ {ACPI_RSC_SOURCE, ACPI_RS_OFFSET (Data.Address16.ResourceSource),
+ 0,
+ sizeof (AML_RESOURCE_ADDRESS16)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertAddress32 - All DWORD (32-bit) address resources
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertAddress32[5] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS32),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress32)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
+ sizeof (AML_RESOURCE_ADDRESS32),
+ 0},
+
+ /* Resource Type, General Flags, and Type-Specific Flags */
+
+ {ACPI_RSC_ADDRESS, 0, 0, 0},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.Address32.Address.Granularity),
+ AML_OFFSET (Address32.Granularity),
+ 5},
+
+ /* Optional ResourceSource (Index and String) */
+
+ {ACPI_RSC_SOURCE, ACPI_RS_OFFSET (Data.Address32.ResourceSource),
+ 0,
+ sizeof (AML_RESOURCE_ADDRESS32)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertAddress64 - All QWORD (64-bit) address resources
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertAddress64[5] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS64),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress64)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
+ sizeof (AML_RESOURCE_ADDRESS64),
+ 0},
+
+ /* Resource Type, General Flags, and Type-Specific Flags */
+
+ {ACPI_RSC_ADDRESS, 0, 0, 0},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ {ACPI_RSC_MOVE64, ACPI_RS_OFFSET (Data.Address64.Address.Granularity),
+ AML_OFFSET (Address64.Granularity),
+ 5},
+
+ /* Optional ResourceSource (Index and String) */
+
+ {ACPI_RSC_SOURCE, ACPI_RS_OFFSET (Data.Address64.ResourceSource),
+ 0,
+ sizeof (AML_RESOURCE_ADDRESS64)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertExtAddress64 - All Extended (64-bit) address resources
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertExtAddress64[5] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
+ ACPI_RS_SIZE (ACPI_RESOURCE_EXTENDED_ADDRESS64),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertExtAddress64)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
+ sizeof (AML_RESOURCE_EXTENDED_ADDRESS64),
+ 0},
+
+ /* Resource Type, General Flags, and Type-Specific Flags */
+
+ {ACPI_RSC_ADDRESS, 0, 0, 0},
+
+ /* Revision ID */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.ExtAddress64.RevisionID),
+ AML_OFFSET (ExtAddress64.RevisionID),
+ 1},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ * Type-Specific Attribute
+ */
+ {ACPI_RSC_MOVE64, ACPI_RS_OFFSET (Data.ExtAddress64.Address.Granularity),
+ AML_OFFSET (ExtAddress64.Granularity),
+ 6}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertGeneralFlags - Flags common to all address descriptors
+ *
+ ******************************************************************************/
+
+static ACPI_RSCONVERT_INFO AcpiRsConvertGeneralFlags[6] =
+{
+ {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.Flags),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertGeneralFlags)},
+
+ /* Resource Type (Memory, Io, BusNumber, etc.) */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Address.ResourceType),
+ AML_OFFSET (Address.ResourceType),
+ 1},
+
+ /* General Flags - Consume, Decode, MinFixed, MaxFixed */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.ProducerConsumer),
+ AML_OFFSET (Address.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Decode),
+ AML_OFFSET (Address.Flags),
+ 1},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.MinAddressFixed),
+ AML_OFFSET (Address.Flags),
+ 2},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.MaxAddressFixed),
+ AML_OFFSET (Address.Flags),
+ 3}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertMemFlags - Flags common to Memory address descriptors
+ *
+ ******************************************************************************/
+
+static ACPI_RSCONVERT_INFO AcpiRsConvertMemFlags[5] =
+{
+ {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.SpecificFlags),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertMemFlags)},
+
+ /* Memory-specific flags */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.WriteProtect),
+ AML_OFFSET (Address.SpecificFlags),
+ 0},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.Caching),
+ AML_OFFSET (Address.SpecificFlags),
+ 1},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.RangeType),
+ AML_OFFSET (Address.SpecificFlags),
+ 3},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.Translation),
+ AML_OFFSET (Address.SpecificFlags),
+ 5}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertIoFlags - Flags common to I/O address descriptors
+ *
+ ******************************************************************************/
+
+static ACPI_RSCONVERT_INFO AcpiRsConvertIoFlags[4] =
+{
+ {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.SpecificFlags),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertIoFlags)},
+
+ /* I/O-specific flags */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.RangeType),
+ AML_OFFSET (Address.SpecificFlags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.Translation),
+ AML_OFFSET (Address.SpecificFlags),
+ 4},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.TranslationType),
+ AML_OFFSET (Address.SpecificFlags),
+ 5}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetAddressCommon
+ *
+ * PARAMETERS: Resource - Pointer to the internal resource struct
+ * Aml - Pointer to the AML resource descriptor
+ *
+ * RETURN: TRUE if the ResourceType field is OK, FALSE otherwise
+ *
+ * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
+ * to an internal resource descriptor
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiRsGetAddressCommon (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Validate the Resource Type */
+
+ if ((Aml->Address.ResourceType > 2) && (Aml->Address.ResourceType < 0xC0))
+ {
+ return (FALSE);
+ }
+
+ /* Get the Resource Type and General Flags */
+
+ (void) AcpiRsConvertAmlToResource (Resource, Aml, AcpiRsConvertGeneralFlags);
+
+ /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
+
+ if (Resource->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
+ {
+ (void) AcpiRsConvertAmlToResource (Resource, Aml, AcpiRsConvertMemFlags);
+ }
+ else if (Resource->Data.Address.ResourceType == ACPI_IO_RANGE)
+ {
+ (void) AcpiRsConvertAmlToResource (Resource, Aml, AcpiRsConvertIoFlags);
+ }
+ else
+ {
+ /* Generic resource type, just grab the TypeSpecific byte */
+
+ Resource->Data.Address.Info.TypeSpecific = Aml->Address.SpecificFlags;
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsSetAddressCommon
+ *
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * Resource - Pointer to the internal resource struct
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert common flag fields from a resource descriptor to an
+ * AML descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiRsSetAddressCommon (
+ AML_RESOURCE *Aml,
+ ACPI_RESOURCE *Resource)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Set the Resource Type and General Flags */
+
+ (void) AcpiRsConvertResourceToAml (Resource, Aml, AcpiRsConvertGeneralFlags);
+
+ /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
+
+ if (Resource->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
+ {
+ (void) AcpiRsConvertResourceToAml (Resource, Aml, AcpiRsConvertMemFlags);
+ }
+ else if (Resource->Data.Address.ResourceType == ACPI_IO_RANGE)
+ {
+ (void) AcpiRsConvertResourceToAml (Resource, Aml, AcpiRsConvertIoFlags);
+ }
+ else
+ {
+ /* Generic resource type, just copy the TypeSpecific byte */
+
+ Aml->Address.SpecificFlags = Resource->Data.Address.Info.TypeSpecific;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscalc.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscalc.c
new file mode 100644
index 0000000000..38db8c1ed8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscalc.c
@@ -0,0 +1,752 @@
+/*******************************************************************************
+ *
+ * Module Name: rscalc - Calculate stream and list lengths
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rscalc")
+
+
+/* Local prototypes */
+
+static UINT8
+AcpiRsCountSetBits (
+ UINT16 BitField);
+
+static ACPI_RS_LENGTH
+AcpiRsStructOptionLength (
+ ACPI_RESOURCE_SOURCE *ResourceSource);
+
+static UINT32
+AcpiRsStreamOptionLength (
+ UINT32 ResourceLength,
+ UINT32 MinimumTotalLength);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsCountSetBits
+ *
+ * PARAMETERS: BitField - Field in which to count bits
+ *
+ * RETURN: Number of bits set within the field
+ *
+ * DESCRIPTION: Count the number of bits set in a resource field. Used for
+ * (Short descriptor) interrupt and DMA lists.
+ *
+ ******************************************************************************/
+
+static UINT8
+AcpiRsCountSetBits (
+ UINT16 BitField)
+{
+ UINT8 BitsSet;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ for (BitsSet = 0; BitField; BitsSet++)
+ {
+ /* Zero the least significant bit that is set */
+
+ BitField &= (UINT16) (BitField - 1);
+ }
+
+ return (BitsSet);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsStructOptionLength
+ *
+ * PARAMETERS: ResourceSource - Pointer to optional descriptor field
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
+ * ResourceSource fields in some Large descriptors. Used during
+ * list-to-stream conversion
+ *
+ ******************************************************************************/
+
+static ACPI_RS_LENGTH
+AcpiRsStructOptionLength (
+ ACPI_RESOURCE_SOURCE *ResourceSource)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * If the ResourceSource string is valid, return the size of the string
+ * (StringLength includes the NULL terminator) plus the size of the
+ * ResourceSourceIndex (1).
+ */
+ if (ResourceSource->StringPtr)
+ {
+ return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
+ }
+
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsStreamOptionLength
+ *
+ * PARAMETERS: ResourceLength - Length from the resource header
+ * MinimumTotalLength - Minimum length of this resource, before
+ * any optional fields. Includes header size
+ *
+ * RETURN: Length of optional string (0 if no string present)
+ *
+ * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
+ * ResourceSource fields in some Large descriptors. Used during
+ * stream-to-list conversion
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiRsStreamOptionLength (
+ UINT32 ResourceLength,
+ UINT32 MinimumAmlResourceLength)
+{
+ UINT32 StringLength = 0;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * The ResourceSourceIndex and ResourceSource are optional elements of some
+ * Large-type resource descriptors.
+ */
+
+ /*
+ * If the length of the actual resource descriptor is greater than the ACPI
+ * spec-defined minimum length, it means that a ResourceSourceIndex exists
+ * and is followed by a (required) null terminated string. The string length
+ * (including the null terminator) is the resource length minus the minimum
+ * length, minus one byte for the ResourceSourceIndex itself.
+ */
+ if (ResourceLength > MinimumAmlResourceLength)
+ {
+ /* Compute the length of the optional string */
+
+ StringLength = ResourceLength - MinimumAmlResourceLength - 1;
+ }
+
+ /*
+ * Round the length up to a multiple of the native word in order to
+ * guarantee that the entire resource descriptor is native word aligned
+ */
+ return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetAmlLength
+ *
+ * PARAMETERS: Resource - Pointer to the resource linked list
+ * ResourceListSize - Size of the resource linked list
+ * SizeNeeded - Where the required size is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Takes a linked list of internal resource descriptors and
+ * calculates the size buffer needed to hold the corresponding
+ * external resource byte stream.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetAmlLength (
+ ACPI_RESOURCE *Resource,
+ ACPI_SIZE ResourceListSize,
+ ACPI_SIZE *SizeNeeded)
+{
+ ACPI_SIZE AmlSizeNeeded = 0;
+ ACPI_RESOURCE *ResourceEnd;
+ ACPI_RS_LENGTH TotalSize;
+
+
+ ACPI_FUNCTION_TRACE (RsGetAmlLength);
+
+
+ /* Traverse entire list of internal resource descriptors */
+
+ ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize);
+ while (Resource < ResourceEnd)
+ {
+ /* Validate the descriptor type */
+
+ if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
+ {
+ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ }
+
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!Resource->Length)
+ {
+ return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
+ /* Get the base size of the (external stream) resource descriptor */
+
+ TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
+
+ /*
+ * Augment the base size for descriptors with optional and/or
+ * variable-length fields
+ */
+ switch (Resource->Type)
+ {
+ case ACPI_RESOURCE_TYPE_IRQ:
+
+ /* Length can be 3 or 2 */
+
+ if (Resource->Data.Irq.DescriptorLength == 2)
+ {
+ TotalSize--;
+ }
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+
+ /* Length can be 1 or 0 */
+
+ if (Resource->Data.Irq.DescriptorLength == 0)
+ {
+ TotalSize--;
+ }
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_VENDOR:
+ /*
+ * Vendor Defined Resource:
+ * For a Vendor Specific resource, if the Length is between 1 and 7
+ * it will be created as a Small Resource data type, otherwise it
+ * is a Large Resource data type.
+ */
+ if (Resource->Data.Vendor.ByteLength > 7)
+ {
+ /* Base size of a Large resource descriptor */
+
+ TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
+ }
+
+ /* Add the size of the vendor-specific data */
+
+ TotalSize = (ACPI_RS_LENGTH)
+ (TotalSize + Resource->Data.Vendor.ByteLength);
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_END_TAG:
+ /*
+ * End Tag:
+ * We are done -- return the accumulated total size.
+ */
+ *SizeNeeded = AmlSizeNeeded + TotalSize;
+
+ /* Normal exit */
+
+ return_ACPI_STATUS (AE_OK);
+
+
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+ /*
+ * 16-Bit Address Resource:
+ * Add the size of the optional ResourceSource info
+ */
+ TotalSize = (ACPI_RS_LENGTH)
+ (TotalSize + AcpiRsStructOptionLength (
+ &Resource->Data.Address16.ResourceSource));
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ /*
+ * 32-Bit Address Resource:
+ * Add the size of the optional ResourceSource info
+ */
+ TotalSize = (ACPI_RS_LENGTH)
+ (TotalSize + AcpiRsStructOptionLength (
+ &Resource->Data.Address32.ResourceSource));
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ /*
+ * 64-Bit Address Resource:
+ * Add the size of the optional ResourceSource info
+ */
+ TotalSize = (ACPI_RS_LENGTH)
+ (TotalSize + AcpiRsStructOptionLength (
+ &Resource->Data.Address64.ResourceSource));
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ /*
+ * Extended IRQ Resource:
+ * Add the size of each additional optional interrupt beyond the
+ * required 1 (4 bytes for each UINT32 interrupt number)
+ */
+ TotalSize = (ACPI_RS_LENGTH)
+ (TotalSize +
+ ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
+
+ /* Add the size of the optional ResourceSource info */
+
+ AcpiRsStructOptionLength (
+ &Resource->Data.ExtendedIrq.ResourceSource));
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_GPIO:
+
+ TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) +
+ Resource->Data.Gpio.ResourceSource.StringLength +
+ Resource->Data.Gpio.VendorLength);
+
+ break;
+
+
+ case ACPI_RESOURCE_TYPE_SERIAL_BUS:
+
+ TotalSize = AcpiGbl_AmlResourceSerialBusSizes [Resource->Data.CommonSerialBus.Type];
+
+ TotalSize = (ACPI_RS_LENGTH) (TotalSize +
+ Resource->Data.I2cSerialBus.ResourceSource.StringLength +
+ Resource->Data.I2cSerialBus.VendorLength);
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Update the total */
+
+ AmlSizeNeeded += TotalSize;
+
+ /* Point to the next object */
+
+ Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
+ }
+
+ /* Did not find an EndTag resource descriptor */
+
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetListLength
+ *
+ * PARAMETERS: AmlBuffer - Pointer to the resource byte stream
+ * AmlBufferLength - Size of AmlBuffer
+ * SizeNeeded - Where the size needed is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Takes an external resource byte stream and calculates the size
+ * buffer needed to hold the corresponding internal resource
+ * descriptor linked list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetListLength (
+ UINT8 *AmlBuffer,
+ UINT32 AmlBufferLength,
+ ACPI_SIZE *SizeNeeded)
+{
+ ACPI_STATUS Status;
+ UINT8 *EndAml;
+ UINT8 *Buffer;
+ UINT32 BufferSize;
+ UINT16 Temp16;
+ UINT16 ResourceLength;
+ UINT32 ExtraStructBytes;
+ UINT8 ResourceIndex;
+ UINT8 MinimumAmlResourceLength;
+ AML_RESOURCE *AmlResource;
+
+
+ ACPI_FUNCTION_TRACE (RsGetListLength);
+
+
+ *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */
+ EndAml = AmlBuffer + AmlBufferLength;
+
+ /* Walk the list of AML resource descriptors */
+
+ while (AmlBuffer < EndAml)
+ {
+ /* Validate the Resource Type and Resource Length */
+
+ Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * Exit on failure. Cannot continue because the descriptor length
+ * may be bogus also.
+ */
+ return_ACPI_STATUS (Status);
+ }
+
+ AmlResource = (void *) AmlBuffer;
+
+ /* Get the resource length and base (minimum) AML size */
+
+ ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
+ MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
+
+ /*
+ * Augment the size for descriptors with optional
+ * and/or variable length fields
+ */
+ ExtraStructBytes = 0;
+ Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
+
+ switch (AcpiUtGetResourceType (AmlBuffer))
+ {
+ case ACPI_RESOURCE_NAME_IRQ:
+ /*
+ * IRQ Resource:
+ * Get the number of bits set in the 16-bit IRQ mask
+ */
+ ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
+ ExtraStructBytes = AcpiRsCountSetBits (Temp16);
+ break;
+
+
+ case ACPI_RESOURCE_NAME_DMA:
+ /*
+ * DMA Resource:
+ * Get the number of bits set in the 8-bit DMA mask
+ */
+ ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
+ break;
+
+
+ case ACPI_RESOURCE_NAME_VENDOR_SMALL:
+ case ACPI_RESOURCE_NAME_VENDOR_LARGE:
+ /*
+ * Vendor Resource:
+ * Get the number of vendor data bytes
+ */
+ ExtraStructBytes = ResourceLength;
+
+ /*
+ * There is already one byte included in the minimum
+ * descriptor size. If there are extra struct bytes,
+ * subtract one from the count.
+ */
+ if (ExtraStructBytes)
+ {
+ ExtraStructBytes--;
+ }
+ break;
+
+
+ case ACPI_RESOURCE_NAME_END_TAG:
+ /*
+ * End Tag: This is the normal exit
+ */
+ return_ACPI_STATUS (AE_OK);
+
+
+ case ACPI_RESOURCE_NAME_ADDRESS32:
+ case ACPI_RESOURCE_NAME_ADDRESS16:
+ case ACPI_RESOURCE_NAME_ADDRESS64:
+ /*
+ * Address Resource:
+ * Add the size of the optional ResourceSource
+ */
+ ExtraStructBytes = AcpiRsStreamOptionLength (
+ ResourceLength, MinimumAmlResourceLength);
+ break;
+
+
+ case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
+ /*
+ * Extended IRQ Resource:
+ * Using the InterruptTableLength, add 4 bytes for each additional
+ * interrupt. Note: at least one interrupt is required and is
+ * included in the minimum descriptor size (reason for the -1)
+ */
+ ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
+
+ /* Add the size of the optional ResourceSource */
+
+ ExtraStructBytes += AcpiRsStreamOptionLength (
+ ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
+ break;
+
+ case ACPI_RESOURCE_NAME_GPIO:
+
+ /* Vendor data is optional */
+
+ if (AmlResource->Gpio.VendorLength)
+ {
+ ExtraStructBytes += AmlResource->Gpio.VendorOffset -
+ AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength;
+ }
+ else
+ {
+ ExtraStructBytes += AmlResource->LargeHeader.ResourceLength +
+ sizeof (AML_RESOURCE_LARGE_HEADER) -
+ AmlResource->Gpio.PinTableOffset;
+ }
+ break;
+
+ case ACPI_RESOURCE_NAME_SERIAL_BUS:
+
+ MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[
+ AmlResource->CommonSerialBus.Type];
+ ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength -
+ MinimumAmlResourceLength;
+ break;
+
+ default:
+
+ break;
+ }
+
+ /*
+ * Update the required buffer size for the internal descriptor structs
+ *
+ * Important: Round the size up for the appropriate alignment. This
+ * is a requirement on IA64.
+ */
+ if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS)
+ {
+ BufferSize = AcpiGbl_ResourceStructSerialBusSizes[
+ AmlResource->CommonSerialBus.Type] + ExtraStructBytes;
+ }
+ else
+ {
+ BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
+ ExtraStructBytes;
+ }
+ BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
+
+ *SizeNeeded += BufferSize;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
+ "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
+ AcpiUtGetResourceType (AmlBuffer),
+ AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
+
+ /*
+ * Point to the next resource within the AML stream using the length
+ * contained in the resource descriptor header
+ */
+ AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
+ }
+
+ /* Did not find an EndTag resource descriptor */
+
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetPciRoutingTableLength
+ *
+ * PARAMETERS: PackageObject - Pointer to the package object
+ * BufferSizeNeeded - UINT32 pointer of the size buffer
+ * needed to properly return the
+ * parsed data
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Given a package representing a PCI routing table, this
+ * calculates the size of the corresponding linked list of
+ * descriptions.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetPciRoutingTableLength (
+ ACPI_OPERAND_OBJECT *PackageObject,
+ ACPI_SIZE *BufferSizeNeeded)
+{
+ UINT32 NumberOfElements;
+ ACPI_SIZE TempSizeNeeded = 0;
+ ACPI_OPERAND_OBJECT **TopObjectList;
+ UINT32 Index;
+ ACPI_OPERAND_OBJECT *PackageElement;
+ ACPI_OPERAND_OBJECT **SubObjectList;
+ BOOLEAN NameFound;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
+
+
+ NumberOfElements = PackageObject->Package.Count;
+
+ /*
+ * Calculate the size of the return buffer.
+ * The base size is the number of elements * the sizes of the
+ * structures. Additional space for the strings is added below.
+ * The minus one is to subtract the size of the UINT8 Source[1]
+ * member because it is added below.
+ *
+ * But each PRT_ENTRY structure has a pointer to a string and
+ * the size of that string must be found.
+ */
+ TopObjectList = PackageObject->Package.Elements;
+
+ for (Index = 0; Index < NumberOfElements; Index++)
+ {
+ /* Dereference the subpackage */
+
+ PackageElement = *TopObjectList;
+
+ /* We must have a valid Package object */
+
+ if (!PackageElement ||
+ (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
+ {
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
+
+ /*
+ * The SubObjectList will now point to an array of the
+ * four IRQ elements: Address, Pin, Source and SourceIndex
+ */
+ SubObjectList = PackageElement->Package.Elements;
+
+ /* Scan the IrqTableElements for the Source Name String */
+
+ NameFound = FALSE;
+
+ for (TableIndex = 0;
+ TableIndex < PackageElement->Package.Count && !NameFound;
+ TableIndex++)
+ {
+ if (*SubObjectList && /* Null object allowed */
+
+ ((ACPI_TYPE_STRING ==
+ (*SubObjectList)->Common.Type) ||
+
+ ((ACPI_TYPE_LOCAL_REFERENCE ==
+ (*SubObjectList)->Common.Type) &&
+
+ ((*SubObjectList)->Reference.Class ==
+ ACPI_REFCLASS_NAME))))
+ {
+ NameFound = TRUE;
+ }
+ else
+ {
+ /* Look at the next element */
+
+ SubObjectList++;
+ }
+ }
+
+ TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
+
+ /* Was a String type found? */
+
+ if (NameFound)
+ {
+ if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
+ {
+ /*
+ * The length String.Length field does not include the
+ * terminating NULL, add 1
+ */
+ TempSizeNeeded += ((ACPI_SIZE)
+ (*SubObjectList)->String.Length + 1);
+ }
+ else
+ {
+ TempSizeNeeded += AcpiNsGetPathnameLength (
+ (*SubObjectList)->Reference.Node);
+ }
+ }
+ else
+ {
+ /*
+ * If no name was found, then this is a NULL, which is
+ * translated as a UINT32 zero.
+ */
+ TempSizeNeeded += sizeof (UINT32);
+ }
+
+ /* Round up the size since each element must be aligned */
+
+ TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
+
+ /* Point to the next ACPI_OPERAND_OBJECT */
+
+ TopObjectList++;
+ }
+
+ /*
+ * Add an extra element to the end of the list, essentially a
+ * NULL terminator
+ */
+ *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscreate.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscreate.c
new file mode 100644
index 0000000000..2461bb446f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rscreate.c
@@ -0,0 +1,505 @@
+/*******************************************************************************
+ *
+ * Module Name: rscreate - Create resource lists/tables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rscreate")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiBufferToResource
+ *
+ * PARAMETERS: AmlBuffer - Pointer to the resource byte stream
+ * AmlBufferLength - Length of the AmlBuffer
+ * ResourcePtr - Where the converted resource is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a raw AML buffer to a resource list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiBufferToResource (
+ UINT8 *AmlBuffer,
+ UINT16 AmlBufferLength,
+ ACPI_RESOURCE **ResourcePtr)
+{
+ ACPI_STATUS Status;
+ ACPI_SIZE ListSizeNeeded;
+ void *Resource;
+ void *CurrentResourcePtr;
+
+
+ ACPI_FUNCTION_TRACE (AcpiBufferToResource);
+
+
+ /*
+ * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag
+ * is not required here.
+ */
+
+ /* Get the required length for the converted resource */
+
+ Status = AcpiRsGetListLength (AmlBuffer, AmlBufferLength,
+ &ListSizeNeeded);
+ if (Status == AE_AML_NO_RESOURCE_END_TAG)
+ {
+ Status = AE_OK;
+ }
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Allocate a buffer for the converted resource */
+
+ Resource = ACPI_ALLOCATE_ZEROED (ListSizeNeeded);
+ CurrentResourcePtr = Resource;
+ if (!Resource)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Perform the AML-to-Resource conversion */
+
+ Status = AcpiUtWalkAmlResources (NULL, AmlBuffer, AmlBufferLength,
+ AcpiRsConvertAmlToResources, &CurrentResourcePtr);
+ if (Status == AE_AML_NO_RESOURCE_END_TAG)
+ {
+ Status = AE_OK;
+ }
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (Resource);
+ }
+ else
+ {
+ *ResourcePtr = Resource;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiBufferToResource)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsCreateResourceList
+ *
+ * PARAMETERS: AmlBuffer - Pointer to the resource byte stream
+ * OutputBuffer - Pointer to the user's buffer
+ *
+ * RETURN: Status: AE_OK if okay, else a valid ACPI_STATUS code
+ * If OutputBuffer is not large enough, OutputBufferLength
+ * indicates how large OutputBuffer should be, else it
+ * indicates how may UINT8 elements of OutputBuffer are valid.
+ *
+ * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
+ * execution and parses the stream to create a linked list
+ * of device resources.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsCreateResourceList (
+ ACPI_OPERAND_OBJECT *AmlBuffer,
+ ACPI_BUFFER *OutputBuffer)
+{
+
+ ACPI_STATUS Status;
+ UINT8 *AmlStart;
+ ACPI_SIZE ListSizeNeeded = 0;
+ UINT32 AmlBufferLength;
+ void *Resource;
+
+
+ ACPI_FUNCTION_TRACE (RsCreateResourceList);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AmlBuffer = %p\n",
+ AmlBuffer));
+
+ /* Params already validated, so we don't re-validate here */
+
+ AmlBufferLength = AmlBuffer->Buffer.Length;
+ AmlStart = AmlBuffer->Buffer.Pointer;
+
+ /*
+ * Pass the AmlBuffer into a module that can calculate
+ * the buffer size needed for the linked list
+ */
+ Status = AcpiRsGetListLength (AmlStart, AmlBufferLength,
+ &ListSizeNeeded);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n",
+ Status, (UINT32) ListSizeNeeded));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (OutputBuffer, ListSizeNeeded);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Do the conversion */
+
+ Resource = OutputBuffer->Pointer;
+ Status = AcpiUtWalkAmlResources (NULL, AmlStart, AmlBufferLength,
+ AcpiRsConvertAmlToResources, &Resource);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
+ OutputBuffer->Pointer, (UINT32) OutputBuffer->Length));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsCreatePciRoutingTable
+ *
+ * PARAMETERS: PackageObject - Pointer to a package containing one
+ * of more ACPI_OPERAND_OBJECTs
+ * OutputBuffer - Pointer to the user's buffer
+ *
+ * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code.
+ * If the OutputBuffer is too small, the error will be
+ * AE_BUFFER_OVERFLOW and OutputBuffer->Length will point
+ * to the size buffer needed.
+ *
+ * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
+ * linked list of PCI interrupt descriptions
+ *
+ * NOTE: It is the caller's responsibility to ensure that the start of the
+ * output buffer is aligned properly (if necessary).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsCreatePciRoutingTable (
+ ACPI_OPERAND_OBJECT *PackageObject,
+ ACPI_BUFFER *OutputBuffer)
+{
+ UINT8 *Buffer;
+ ACPI_OPERAND_OBJECT **TopObjectList;
+ ACPI_OPERAND_OBJECT **SubObjectList;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_SIZE BufferSizeNeeded = 0;
+ UINT32 NumberOfElements;
+ UINT32 Index;
+ ACPI_PCI_ROUTING_TABLE *UserPrt;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_BUFFER PathBuffer;
+
+
+ ACPI_FUNCTION_TRACE (RsCreatePciRoutingTable);
+
+
+ /* Params already validated, so we don't re-validate here */
+
+ /* Get the required buffer length */
+
+ Status = AcpiRsGetPciRoutingTableLength (PackageObject,
+ &BufferSizeNeeded);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "BufferSizeNeeded = %X\n",
+ (UINT32) BufferSizeNeeded));
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (OutputBuffer, BufferSizeNeeded);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
+ * package that in turn contains an UINT64 Address, a UINT8 Pin,
+ * a Name, and a UINT8 SourceIndex.
+ */
+ TopObjectList = PackageObject->Package.Elements;
+ NumberOfElements = PackageObject->Package.Count;
+ Buffer = OutputBuffer->Pointer;
+ UserPrt = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);
+
+ for (Index = 0; Index < NumberOfElements; Index++)
+ {
+ /*
+ * Point UserPrt past this current structure
+ *
+ * NOTE: On the first iteration, UserPrt->Length will
+ * be zero because we cleared the return buffer earlier
+ */
+ Buffer += UserPrt->Length;
+ UserPrt = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);
+
+ /*
+ * Fill in the Length field with the information we have at this point.
+ * The minus four is to subtract the size of the UINT8 Source[4] member
+ * because it is added below.
+ */
+ UserPrt->Length = (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
+
+ /* Each subpackage must be of length 4 */
+
+ if ((*TopObjectList)->Package.Count != 4)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "(PRT[%u]) Need package of length 4, found length %u",
+ Index, (*TopObjectList)->Package.Count));
+ return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
+ }
+
+ /*
+ * Dereference the subpackage.
+ * The SubObjectList will now point to an array of the four IRQ
+ * elements: [Address, Pin, Source, SourceIndex]
+ */
+ SubObjectList = (*TopObjectList)->Package.Elements;
+
+ /* 1) First subobject: Dereference the PRT.Address */
+
+ ObjDesc = SubObjectList[0];
+ if (!ObjDesc || ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ ACPI_ERROR ((AE_INFO, "(PRT[%u].Address) Need Integer, found %s",
+ Index, AcpiUtGetObjectTypeName (ObjDesc)));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ UserPrt->Address = ObjDesc->Integer.Value;
+
+ /* 2) Second subobject: Dereference the PRT.Pin */
+
+ ObjDesc = SubObjectList[1];
+ if (!ObjDesc || ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ ACPI_ERROR ((AE_INFO, "(PRT[%u].Pin) Need Integer, found %s",
+ Index, AcpiUtGetObjectTypeName (ObjDesc)));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ UserPrt->Pin = (UINT32) ObjDesc->Integer.Value;
+
+ /*
+ * 3) Third subobject: Dereference the PRT.SourceName
+ * The name may be unresolved (slack mode), so allow a null object
+ */
+ ObjDesc = SubObjectList[2];
+ if (ObjDesc)
+ {
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ if (ObjDesc->Reference.Class != ACPI_REFCLASS_NAME)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "(PRT[%u].Source) Need name, found Reference Class 0x%X",
+ Index, ObjDesc->Reference.Class));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ Node = ObjDesc->Reference.Node;
+
+ /* Use *remaining* length of the buffer as max for pathname */
+
+ PathBuffer.Length = OutputBuffer->Length -
+ (UINT32) ((UINT8 *) UserPrt->Source -
+ (UINT8 *) OutputBuffer->Pointer);
+ PathBuffer.Pointer = UserPrt->Source;
+
+ Status = AcpiNsHandleToPathname ((ACPI_HANDLE) Node,
+ &PathBuffer, FALSE);
+
+ /* +1 to include null terminator */
+
+ UserPrt->Length += (UINT32) strlen (UserPrt->Source) + 1;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ strcpy (UserPrt->Source, ObjDesc->String.Pointer);
+
+ /*
+ * Add to the Length field the length of the string
+ * (add 1 for terminator)
+ */
+ UserPrt->Length += ObjDesc->String.Length + 1;
+ break;
+
+ case ACPI_TYPE_INTEGER:
+ /*
+ * If this is a number, then the Source Name is NULL, since the
+ * entire buffer was zeroed out, we can leave this alone.
+ *
+ * Add to the Length field the length of the UINT32 NULL
+ */
+ UserPrt->Length += sizeof (UINT32);
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "(PRT[%u].Source) Need Ref/String/Integer, found %s",
+ Index, AcpiUtGetObjectTypeName (ObjDesc)));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+ }
+
+ /* Now align the current length */
+
+ UserPrt->Length = (UINT32) ACPI_ROUND_UP_TO_64BIT (UserPrt->Length);
+
+ /* 4) Fourth subobject: Dereference the PRT.SourceIndex */
+
+ ObjDesc = SubObjectList[3];
+ if (!ObjDesc || ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "(PRT[%u].SourceIndex) Need Integer, found %s",
+ Index, AcpiUtGetObjectTypeName (ObjDesc)));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ UserPrt->SourceIndex = (UINT32) ObjDesc->Integer.Value;
+
+ /* Point to the next ACPI_OPERAND_OBJECT in the top level package */
+
+ TopObjectList++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
+ OutputBuffer->Pointer, (UINT32) OutputBuffer->Length));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsCreateAmlResources
+ *
+ * PARAMETERS: ResourceList - Pointer to the resource list buffer
+ * OutputBuffer - Where the AML buffer is returned
+ *
+ * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code.
+ * If the OutputBuffer is too small, the error will be
+ * AE_BUFFER_OVERFLOW and OutputBuffer->Length will point
+ * to the size buffer needed.
+ *
+ * DESCRIPTION: Converts a list of device resources to an AML bytestream
+ * to be used as input for the _SRS control method.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsCreateAmlResources (
+ ACPI_BUFFER *ResourceList,
+ ACPI_BUFFER *OutputBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_SIZE AmlSizeNeeded = 0;
+
+
+ ACPI_FUNCTION_TRACE (RsCreateAmlResources);
+
+
+ /* Params already validated, no need to re-validate here */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
+ ResourceList->Pointer));
+
+ /* Get the buffer size needed for the AML byte stream */
+
+ Status = AcpiRsGetAmlLength (ResourceList->Pointer,
+ ResourceList->Length, &AmlSizeNeeded);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
+ (UINT32) AmlSizeNeeded, AcpiFormatException (Status)));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (OutputBuffer, AmlSizeNeeded);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Do the conversion */
+
+ Status = AcpiRsConvertResourcesToAml (ResourceList->Pointer,
+ AmlSizeNeeded, OutputBuffer->Pointer);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
+ OutputBuffer->Pointer, (UINT32) OutputBuffer->Length));
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdump.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdump.c
new file mode 100644
index 0000000000..c88ff7cf4f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdump.c
@@ -0,0 +1,668 @@
+/*******************************************************************************
+ *
+ * Module Name: rsdump - AML debugger support for resource structures.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsdump")
+
+/*
+ * All functions in this module are used by the AML Debugger only
+ */
+
+/* Local prototypes */
+
+static void
+AcpiRsOutString (
+ char *Title,
+ char *Value);
+
+static void
+AcpiRsOutInteger8 (
+ char *Title,
+ UINT8 Value);
+
+static void
+AcpiRsOutInteger16 (
+ char *Title,
+ UINT16 Value);
+
+static void
+AcpiRsOutInteger32 (
+ char *Title,
+ UINT32 Value);
+
+static void
+AcpiRsOutInteger64 (
+ char *Title,
+ UINT64 Value);
+
+static void
+AcpiRsOutTitle (
+ char *Title);
+
+static void
+AcpiRsDumpByteList (
+ UINT16 Length,
+ UINT8 *Data);
+
+static void
+AcpiRsDumpWordList (
+ UINT16 Length,
+ UINT16 *Data);
+
+static void
+AcpiRsDumpDwordList (
+ UINT8 Length,
+ UINT32 *Data);
+
+static void
+AcpiRsDumpShortByteList (
+ UINT8 Length,
+ UINT8 *Data);
+
+static void
+AcpiRsDumpResourceSource (
+ ACPI_RESOURCE_SOURCE *ResourceSource);
+
+static void
+AcpiRsDumpAddressCommon (
+ ACPI_RESOURCE_DATA *Resource);
+
+static void
+AcpiRsDumpDescriptor (
+ void *Resource,
+ ACPI_RSDUMP_INFO *Table);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDumpResourceList
+ *
+ * PARAMETERS: ResourceList - Pointer to a resource descriptor list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dispatches the structure to the correct dump routine.
+ *
+ ******************************************************************************/
+
+void
+AcpiRsDumpResourceList (
+ ACPI_RESOURCE *ResourceList)
+{
+ UINT32 Count = 0;
+ UINT32 Type;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
+ {
+ return;
+ }
+
+ /* Walk list and dump all resource descriptors (END_TAG terminates) */
+
+ do
+ {
+ AcpiOsPrintf ("\n[%02X] ", Count);
+ Count++;
+
+ /* Validate Type before dispatch */
+
+ Type = ResourceList->Type;
+ if (Type > ACPI_RESOURCE_TYPE_MAX)
+ {
+ AcpiOsPrintf (
+ "Invalid descriptor type (%X) in resource list\n",
+ ResourceList->Type);
+ return;
+ }
+
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!ResourceList->Length)
+ {
+ AcpiOsPrintf (
+ "Invalid zero length descriptor in resource list\n");
+ return;
+ }
+
+ /* Dump the resource descriptor */
+
+ if (Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
+ {
+ AcpiRsDumpDescriptor (&ResourceList->Data,
+ AcpiGbl_DumpSerialBusDispatch[
+ ResourceList->Data.CommonSerialBus.Type]);
+ }
+ else
+ {
+ AcpiRsDumpDescriptor (&ResourceList->Data,
+ AcpiGbl_DumpResourceDispatch[Type]);
+ }
+
+ /* Point to the next resource structure */
+
+ ResourceList = ACPI_NEXT_RESOURCE (ResourceList);
+
+ /* Exit when END_TAG descriptor is reached */
+
+ } while (Type != ACPI_RESOURCE_TYPE_END_TAG);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDumpIrqList
+ *
+ * PARAMETERS: RouteTable - Pointer to the routing table to dump.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print IRQ routing table
+ *
+ ******************************************************************************/
+
+void
+AcpiRsDumpIrqList (
+ UINT8 *RouteTable)
+{
+ ACPI_PCI_ROUTING_TABLE *PrtElement;
+ UINT8 Count;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Check if debug output enabled */
+
+ if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
+ {
+ return;
+ }
+
+ PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, RouteTable);
+
+ /* Dump all table elements, Exit on zero length element */
+
+ for (Count = 0; PrtElement->Length; Count++)
+ {
+ AcpiOsPrintf ("\n[%02X] PCI IRQ Routing Table Package\n", Count);
+ AcpiRsDumpDescriptor (PrtElement, AcpiRsDumpPrt);
+
+ PrtElement = ACPI_ADD_PTR (ACPI_PCI_ROUTING_TABLE,
+ PrtElement, PrtElement->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDumpDescriptor
+ *
+ * PARAMETERS: Resource - Buffer containing the resource
+ * Table - Table entry to decode the resource
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
+ *
+ ******************************************************************************/
+
+static void
+AcpiRsDumpDescriptor (
+ void *Resource,
+ ACPI_RSDUMP_INFO *Table)
+{
+ UINT8 *Target = NULL;
+ UINT8 *PreviousTarget;
+ char *Name;
+ UINT8 Count;
+
+
+ /* First table entry must contain the table length (# of table entries) */
+
+ Count = Table->Offset;
+
+ while (Count)
+ {
+ PreviousTarget = Target;
+ Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset);
+ Name = Table->Name;
+
+ switch (Table->Opcode)
+ {
+ case ACPI_RSD_TITLE:
+ /*
+ * Optional resource title
+ */
+ if (Table->Name)
+ {
+ AcpiOsPrintf ("%s Resource\n", Name);
+ }
+ break;
+
+ /* Strings */
+
+ case ACPI_RSD_LITERAL:
+
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer));
+ break;
+
+ case ACPI_RSD_STRING:
+
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target));
+ break;
+
+ /* Data items, 8/16/32/64 bit */
+
+ case ACPI_RSD_UINT8:
+
+ if (Table->Pointer)
+ {
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char,
+ Table->Pointer [*Target]));
+ }
+ else
+ {
+ AcpiRsOutInteger8 (Name, ACPI_GET8 (Target));
+ }
+ break;
+
+ case ACPI_RSD_UINT16:
+
+ AcpiRsOutInteger16 (Name, ACPI_GET16 (Target));
+ break;
+
+ case ACPI_RSD_UINT32:
+
+ AcpiRsOutInteger32 (Name, ACPI_GET32 (Target));
+ break;
+
+ case ACPI_RSD_UINT64:
+
+ AcpiRsOutInteger64 (Name, ACPI_GET64 (Target));
+ break;
+
+ /* Flags: 1-bit and 2-bit flags supported */
+
+ case ACPI_RSD_1BITFLAG:
+
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char,
+ Table->Pointer [*Target & 0x01]));
+ break;
+
+ case ACPI_RSD_2BITFLAG:
+
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char,
+ Table->Pointer [*Target & 0x03]));
+ break;
+
+ case ACPI_RSD_3BITFLAG:
+
+ AcpiRsOutString (Name, ACPI_CAST_PTR (char,
+ Table->Pointer [*Target & 0x07]));
+ break;
+
+ case ACPI_RSD_SHORTLIST:
+ /*
+ * Short byte list (single line output) for DMA and IRQ resources
+ * Note: The list length is obtained from the previous table entry
+ */
+ if (PreviousTarget)
+ {
+ AcpiRsOutTitle (Name);
+ AcpiRsDumpShortByteList (*PreviousTarget, Target);
+ }
+ break;
+
+ case ACPI_RSD_SHORTLISTX:
+ /*
+ * Short byte list (single line output) for GPIO vendor data
+ * Note: The list length is obtained from the previous table entry
+ */
+ if (PreviousTarget)
+ {
+ AcpiRsOutTitle (Name);
+ AcpiRsDumpShortByteList (*PreviousTarget,
+ *(ACPI_CAST_INDIRECT_PTR (UINT8, Target)));
+ }
+ break;
+
+ case ACPI_RSD_LONGLIST:
+ /*
+ * Long byte list for Vendor resource data
+ * Note: The list length is obtained from the previous table entry
+ */
+ if (PreviousTarget)
+ {
+ AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target);
+ }
+ break;
+
+ case ACPI_RSD_DWORDLIST:
+ /*
+ * Dword list for Extended Interrupt resources
+ * Note: The list length is obtained from the previous table entry
+ */
+ if (PreviousTarget)
+ {
+ AcpiRsDumpDwordList (*PreviousTarget,
+ ACPI_CAST_PTR (UINT32, Target));
+ }
+ break;
+
+ case ACPI_RSD_WORDLIST:
+ /*
+ * Word list for GPIO Pin Table
+ * Note: The list length is obtained from the previous table entry
+ */
+ if (PreviousTarget)
+ {
+ AcpiRsDumpWordList (*PreviousTarget,
+ *(ACPI_CAST_INDIRECT_PTR (UINT16, Target)));
+ }
+ break;
+
+ case ACPI_RSD_ADDRESS:
+ /*
+ * Common flags for all Address resources
+ */
+ AcpiRsDumpAddressCommon (ACPI_CAST_PTR (
+ ACPI_RESOURCE_DATA, Target));
+ break;
+
+ case ACPI_RSD_SOURCE:
+ /*
+ * Optional ResourceSource for Address resources
+ */
+ AcpiRsDumpResourceSource (ACPI_CAST_PTR (
+ ACPI_RESOURCE_SOURCE, Target));
+ break;
+
+ default:
+
+ AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n",
+ Table->Opcode);
+ return;
+ }
+
+ Table++;
+ Count--;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDumpResourceSource
+ *
+ * PARAMETERS: ResourceSource - Pointer to a Resource Source struct
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Common routine for dumping the optional ResourceSource and the
+ * corresponding ResourceSourceIndex.
+ *
+ ******************************************************************************/
+
+static void
+AcpiRsDumpResourceSource (
+ ACPI_RESOURCE_SOURCE *ResourceSource)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (ResourceSource->Index == 0xFF)
+ {
+ return;
+ }
+
+ AcpiRsOutInteger8 ("Resource Source Index",
+ ResourceSource->Index);
+
+ AcpiRsOutString ("Resource Source",
+ ResourceSource->StringPtr ?
+ ResourceSource->StringPtr : "[Not Specified]");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDumpAddressCommon
+ *
+ * PARAMETERS: Resource - Pointer to an internal resource descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the fields that are common to all Address resource
+ * descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiRsDumpAddressCommon (
+ ACPI_RESOURCE_DATA *Resource)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Decode the type-specific flags */
+
+ switch (Resource->Address.ResourceType)
+ {
+ case ACPI_MEMORY_RANGE:
+
+ AcpiRsDumpDescriptor (Resource, AcpiRsDumpMemoryFlags);
+ break;
+
+ case ACPI_IO_RANGE:
+
+ AcpiRsDumpDescriptor (Resource, AcpiRsDumpIoFlags);
+ break;
+
+ case ACPI_BUS_NUMBER_RANGE:
+
+ AcpiRsOutString ("Resource Type", "Bus Number Range");
+ break;
+
+ default:
+
+ AcpiRsOutInteger8 ("Resource Type",
+ (UINT8) Resource->Address.ResourceType);
+ break;
+ }
+
+ /* Decode the general flags */
+
+ AcpiRsDumpDescriptor (Resource, AcpiRsDumpGeneralFlags);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsOut*
+ *
+ * PARAMETERS: Title - Name of the resource field
+ * Value - Value of the resource field
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Miscellaneous helper functions to consistently format the
+ * output of the resource dump routines
+ *
+ ******************************************************************************/
+
+static void
+AcpiRsOutString (
+ char *Title,
+ char *Value)
+{
+ AcpiOsPrintf ("%27s : %s", Title, Value);
+ if (!*Value)
+ {
+ AcpiOsPrintf ("[NULL NAMESTRING]");
+ }
+ AcpiOsPrintf ("\n");
+}
+
+static void
+AcpiRsOutInteger8 (
+ char *Title,
+ UINT8 Value)
+{
+ AcpiOsPrintf ("%27s : %2.2X\n", Title, Value);
+}
+
+static void
+AcpiRsOutInteger16 (
+ char *Title,
+ UINT16 Value)
+{
+ AcpiOsPrintf ("%27s : %4.4X\n", Title, Value);
+}
+
+static void
+AcpiRsOutInteger32 (
+ char *Title,
+ UINT32 Value)
+{
+ AcpiOsPrintf ("%27s : %8.8X\n", Title, Value);
+}
+
+static void
+AcpiRsOutInteger64 (
+ char *Title,
+ UINT64 Value)
+{
+ AcpiOsPrintf ("%27s : %8.8X%8.8X\n", Title,
+ ACPI_FORMAT_UINT64 (Value));
+}
+
+static void
+AcpiRsOutTitle (
+ char *Title)
+{
+ AcpiOsPrintf ("%27s : ", Title);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDump*List
+ *
+ * PARAMETERS: Length - Number of elements in the list
+ * Data - Start of the list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Miscellaneous functions to dump lists of raw data
+ *
+ ******************************************************************************/
+
+static void
+AcpiRsDumpByteList (
+ UINT16 Length,
+ UINT8 *Data)
+{
+ UINT8 i;
+
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%25s%2.2X : %2.2X\n",
+ "Byte", i, Data[i]);
+ }
+}
+
+static void
+AcpiRsDumpShortByteList (
+ UINT8 Length,
+ UINT8 *Data)
+{
+ UINT8 i;
+
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%X ", Data[i]);
+ }
+ AcpiOsPrintf ("\n");
+}
+
+static void
+AcpiRsDumpDwordList (
+ UINT8 Length,
+ UINT32 *Data)
+{
+ UINT8 i;
+
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%25s%2.2X : %8.8X\n",
+ "Dword", i, Data[i]);
+ }
+}
+
+static void
+AcpiRsDumpWordList (
+ UINT16 Length,
+ UINT16 *Data)
+{
+ UINT16 i;
+
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%25s%2.2X : %4.4X\n",
+ "Word", i, Data[i]);
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c
new file mode 100644
index 0000000000..dfa1a842fb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsdumpinfo.c
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ *
+ * Module Name: rsdumpinfo - Tables used to display resource descriptors.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsdumpinfo")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUGGER)
+
+
+#define ACPI_RSD_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_RESOURCE_DATA,f)
+#define ACPI_PRT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PCI_ROUTING_TABLE,f)
+#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (ACPI_RSDUMP_INFO))
+
+
+/*******************************************************************************
+ *
+ * Resource Descriptor info tables
+ *
+ * Note: The first table entry must be a Title or Literal and must contain
+ * the table length (number of table entries)
+ *
+ ******************************************************************************/
+
+ACPI_RSDUMP_INFO AcpiRsDumpIrq[7] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpIrq), "IRQ", NULL},
+ {ACPI_RSD_UINT8 , ACPI_RSD_OFFSET (Irq.DescriptorLength), "Descriptor Length", NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Irq.Triggering), "Triggering", AcpiGbl_HeDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Irq.Polarity), "Polarity", AcpiGbl_LlDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Irq.Sharable), "Sharing", AcpiGbl_ShrDecode},
+ {ACPI_RSD_UINT8 , ACPI_RSD_OFFSET (Irq.InterruptCount), "Interrupt Count", NULL},
+ {ACPI_RSD_SHORTLIST,ACPI_RSD_OFFSET (Irq.Interrupts[0]), "Interrupt List", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpDma[6] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpDma), "DMA", NULL},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Dma.Type), "Speed", AcpiGbl_TypDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Dma.BusMaster), "Mastering", AcpiGbl_BmDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Dma.Transfer), "Transfer Type", AcpiGbl_SizDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Dma.ChannelCount), "Channel Count", NULL},
+ {ACPI_RSD_SHORTLIST,ACPI_RSD_OFFSET (Dma.Channels[0]), "Channel List", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpStartDpf[4] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpStartDpf), "Start-Dependent-Functions",NULL},
+ {ACPI_RSD_UINT8 , ACPI_RSD_OFFSET (StartDpf.DescriptorLength), "Descriptor Length", NULL},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (StartDpf.CompatibilityPriority), "Compatibility Priority", AcpiGbl_ConfigDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (StartDpf.PerformanceRobustness), "Performance/Robustness", AcpiGbl_ConfigDecode}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpEndDpf[1] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpEndDpf), "End-Dependent-Functions", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpIo[6] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpIo), "I/O", NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Io.IoDecode), "Address Decoding", AcpiGbl_IoDecode},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Io.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Io.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Io.Alignment), "Alignment", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Io.AddressLength), "Address Length", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpFixedIo[3] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpFixedIo), "Fixed I/O", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (FixedIo.Address), "Address", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (FixedIo.AddressLength), "Address Length", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpVendor[3] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpVendor), "Vendor Specific", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Vendor.ByteLength), "Length", NULL},
+ {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET (Vendor.ByteData[0]), "Vendor Data", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpEndTag[1] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpEndTag), "EndTag", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpMemory24[6] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpMemory24), "24-Bit Memory Range", NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Memory24.WriteProtect), "Write Protect", AcpiGbl_RwDecode},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Memory24.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Memory24.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Memory24.Alignment), "Alignment", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Memory24.AddressLength), "Address Length", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpMemory32[6] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpMemory32), "32-Bit Memory Range", NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Memory32.WriteProtect), "Write Protect", AcpiGbl_RwDecode},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Memory32.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Memory32.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Memory32.Alignment), "Alignment", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Memory32.AddressLength), "Address Length", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpFixedMemory32[4] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpFixedMemory32), "32-Bit Fixed Memory Range",NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (FixedMemory32.WriteProtect), "Write Protect", AcpiGbl_RwDecode},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (FixedMemory32.Address), "Address", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (FixedMemory32.AddressLength), "Address Length", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpAddress16[8] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpAddress16), "16-Bit WORD Address Space",NULL},
+ {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Address16.Address.Granularity), "Granularity", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Address16.Address.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Address16.Address.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Address16.Address.TranslationOffset),
+ "Translation Offset", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Address16.Address.AddressLength), "Address Length", NULL},
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (Address16.ResourceSource), NULL, NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpAddress32[8] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpAddress32), "32-Bit DWORD Address Space", NULL},
+ {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Address32.Address.Granularity), "Granularity", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Address32.Address.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Address32.Address.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Address32.Address.TranslationOffset),
+ "Translation Offset", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (Address32.Address.AddressLength), "Address Length", NULL},
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (Address32.ResourceSource), NULL, NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpAddress64[8] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpAddress64), "64-Bit QWORD Address Space", NULL},
+ {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (Address64.Address.Granularity), "Granularity", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (Address64.Address.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (Address64.Address.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (Address64.Address.TranslationOffset),
+ "Translation Offset", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (Address64.Address.AddressLength), "Address Length", NULL},
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (Address64.ResourceSource), NULL, NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpExtAddress64[8] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpExtAddress64), "64-Bit Extended Address Space", NULL},
+ {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.Address.Granularity), "Granularity", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.Address.Minimum), "Address Minimum", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.Address.Maximum), "Address Maximum", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.Address.TranslationOffset),
+ "Translation Offset", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.Address.AddressLength),
+ "Address Length", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (ExtAddress64.TypeSpecific), "Type-Specific Attribute", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpExtIrq[8] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpExtIrq), "Extended IRQ", NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (ExtendedIrq.ProducerConsumer), "Type", AcpiGbl_ConsumeDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (ExtendedIrq.Triggering), "Triggering", AcpiGbl_HeDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (ExtendedIrq.Polarity), "Polarity", AcpiGbl_LlDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (ExtendedIrq.Sharable), "Sharing", AcpiGbl_ShrDecode},
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (ExtendedIrq.ResourceSource), NULL, NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (ExtendedIrq.InterruptCount), "Interrupt Count", NULL},
+ {ACPI_RSD_DWORDLIST,ACPI_RSD_OFFSET (ExtendedIrq.Interrupts[0]), "Interrupt List", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpGenericReg[6] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpGenericReg), "Generic Register", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (GenericReg.SpaceId), "Space ID", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (GenericReg.BitWidth), "Bit Width", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (GenericReg.BitOffset), "Bit Offset", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (GenericReg.AccessSize), "Access Size", NULL},
+ {ACPI_RSD_UINT64, ACPI_RSD_OFFSET (GenericReg.Address), "Address", NULL}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpGpio[16] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpGpio), "GPIO", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Gpio.RevisionId), "RevisionId", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Gpio.ConnectionType), "ConnectionType", AcpiGbl_CtDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Gpio.ProducerConsumer), "ProducerConsumer", AcpiGbl_ConsumeDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (Gpio.PinConfig), "PinConfig", AcpiGbl_PpcDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Gpio.Sharable), "Sharing", AcpiGbl_ShrDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Gpio.IoRestriction), "IoRestriction", AcpiGbl_IorDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Gpio.Triggering), "Triggering", AcpiGbl_HeDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Gpio.Polarity), "Polarity", AcpiGbl_LlDecode},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Gpio.DriveStrength), "DriveStrength", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Gpio.DebounceTimeout), "DebounceTimeout", NULL},
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (Gpio.ResourceSource), "ResourceSource", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Gpio.PinTableLength), "PinTableLength", NULL},
+ {ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET (Gpio.PinTable), "PinTable", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (Gpio.VendorLength), "VendorLength", NULL},
+ {ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (Gpio.VendorData), "VendorData", NULL},
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpFixedDma[4] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpFixedDma), "FixedDma", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (FixedDma.RequestLines), "RequestLines", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (FixedDma.Channels), "Channels", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (FixedDma.Width), "TransferWidth", AcpiGbl_DtsDecode},
+};
+
+#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (CommonSerialBus.RevisionId), "RevisionId", NULL}, \
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (CommonSerialBus.Type), "Type", AcpiGbl_SbtDecode}, \
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (CommonSerialBus.ProducerConsumer), "ProducerConsumer", AcpiGbl_ConsumeDecode}, \
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (CommonSerialBus.SlaveMode), "SlaveMode", AcpiGbl_SmDecode}, \
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (CommonSerialBus.TypeRevisionId), "TypeRevisionId", NULL}, \
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (CommonSerialBus.TypeDataLength), "TypeDataLength", NULL}, \
+ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (CommonSerialBus.ResourceSource), "ResourceSource", NULL}, \
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (CommonSerialBus.VendorLength), "VendorLength", NULL}, \
+ {ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (CommonSerialBus.VendorData), "VendorData", NULL},
+
+ACPI_RSDUMP_INFO AcpiRsDumpCommonSerialBus[10] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpCommonSerialBus), "Common Serial Bus", NULL},
+ ACPI_RS_DUMP_COMMON_SERIAL_BUS
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpI2cSerialBus[13] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpI2cSerialBus), "I2C Serial Bus", NULL},
+ ACPI_RS_DUMP_COMMON_SERIAL_BUS
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (I2cSerialBus.AccessMode), "AccessMode", AcpiGbl_AmDecode},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (I2cSerialBus.ConnectionSpeed), "ConnectionSpeed", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (I2cSerialBus.SlaveAddress), "SlaveAddress", NULL},
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpSpiSerialBus[17] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpSpiSerialBus), "Spi Serial Bus", NULL},
+ ACPI_RS_DUMP_COMMON_SERIAL_BUS
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (SpiSerialBus.WireMode), "WireMode", AcpiGbl_WmDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (SpiSerialBus.DevicePolarity), "DevicePolarity", AcpiGbl_DpDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (SpiSerialBus.DataBitLength), "DataBitLength", NULL},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (SpiSerialBus.ClockPhase), "ClockPhase", AcpiGbl_CphDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (SpiSerialBus.ClockPolarity), "ClockPolarity", AcpiGbl_CpoDecode},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (SpiSerialBus.DeviceSelection), "DeviceSelection", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (SpiSerialBus.ConnectionSpeed), "ConnectionSpeed", NULL},
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpUartSerialBus[19] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpUartSerialBus), "Uart Serial Bus", NULL},
+ ACPI_RS_DUMP_COMMON_SERIAL_BUS
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (UartSerialBus.FlowControl), "FlowControl", AcpiGbl_FcDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (UartSerialBus.StopBits), "StopBits", AcpiGbl_SbDecode},
+ {ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET (UartSerialBus.DataBits), "DataBits", AcpiGbl_BpbDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (UartSerialBus.Endian), "Endian", AcpiGbl_EdDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (UartSerialBus.Parity), "Parity", AcpiGbl_PtDecode},
+ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (UartSerialBus.LinesEnabled), "LinesEnabled", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (UartSerialBus.RxFifoSize), "RxFifoSize", NULL},
+ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (UartSerialBus.TxFifoSize), "TxFifoSize", NULL},
+ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET (UartSerialBus.DefaultBaudRate), "ConnectionSpeed", NULL},
+};
+
+/*
+ * Tables used for common address descriptor flag fields
+ */
+ACPI_RSDUMP_INFO AcpiRsDumpGeneralFlags[5] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpGeneralFlags), NULL, NULL},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.ProducerConsumer), "Consumer/Producer", AcpiGbl_ConsumeDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.Decode), "Address Decode", AcpiGbl_DecDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.MinAddressFixed), "Min Relocatability", AcpiGbl_MinDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.MaxAddressFixed), "Max Relocatability", AcpiGbl_MaxDecode}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpMemoryFlags[5] =
+{
+ {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE (AcpiRsDumpMemoryFlags), "Resource Type", (void *) "Memory Range"},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.Info.Mem.WriteProtect), "Write Protect", AcpiGbl_RwDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Address.Info.Mem.Caching), "Caching", AcpiGbl_MemDecode},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Address.Info.Mem.RangeType), "Range Type", AcpiGbl_MtpDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.Info.Mem.Translation), "Translation", AcpiGbl_TtpDecode}
+};
+
+ACPI_RSDUMP_INFO AcpiRsDumpIoFlags[4] =
+{
+ {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE (AcpiRsDumpIoFlags), "Resource Type", (void *) "I/O Range"},
+ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET (Address.Info.Io.RangeType), "Range Type", AcpiGbl_RngDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.Info.Io.Translation), "Translation", AcpiGbl_TtpDecode},
+ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (Address.Info.Io.TranslationType), "Translation Type", AcpiGbl_TrsDecode}
+};
+
+
+/*
+ * Table used to dump _PRT contents
+ */
+ACPI_RSDUMP_INFO AcpiRsDumpPrt[5] =
+{
+ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE (AcpiRsDumpPrt), NULL, NULL},
+ {ACPI_RSD_UINT64, ACPI_PRT_OFFSET (Address), "Address", NULL},
+ {ACPI_RSD_UINT32, ACPI_PRT_OFFSET (Pin), "Pin", NULL},
+ {ACPI_RSD_STRING, ACPI_PRT_OFFSET (Source[0]), "Source", NULL},
+ {ACPI_RSD_UINT32, ACPI_PRT_OFFSET (SourceIndex), "Source Index", NULL}
+};
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsinfo.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsinfo.c
new file mode 100644
index 0000000000..f34b905aa0
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsinfo.c
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ *
+ * Module Name: rsinfo - Dispatch and Info tables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsinfo")
+
+/*
+ * Resource dispatch and information tables. Any new resource types (either
+ * Large or Small) must be reflected in each of these tables, so they are here
+ * in one place.
+ *
+ * The tables for Large descriptors are indexed by bits 6:0 of the AML
+ * descriptor type byte. The tables for Small descriptors are indexed by
+ * bits 6:3 of the descriptor byte. The tables for internal resource
+ * descriptors are indexed by the ACPI_RESOURCE_TYPE field.
+ */
+
+
+/* Dispatch table for resource-to-AML (Set Resource) conversion functions */
+
+ACPI_RSCONVERT_INFO *AcpiGbl_SetResourceDispatch[] =
+{
+ AcpiRsSetIrq, /* 0x00, ACPI_RESOURCE_TYPE_IRQ */
+ AcpiRsConvertDma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */
+ AcpiRsSetStartDpf, /* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */
+ AcpiRsConvertEndDpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */
+ AcpiRsConvertIo, /* 0x04, ACPI_RESOURCE_TYPE_IO */
+ AcpiRsConvertFixedIo, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */
+ AcpiRsSetVendor, /* 0x06, ACPI_RESOURCE_TYPE_VENDOR */
+ AcpiRsConvertEndTag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */
+ AcpiRsConvertMemory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */
+ AcpiRsConvertMemory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */
+ AcpiRsConvertFixedMemory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+ AcpiRsConvertAddress16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */
+ AcpiRsConvertAddress32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */
+ AcpiRsConvertAddress64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */
+ AcpiRsConvertExtAddress64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+ AcpiRsConvertExtIrq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+ AcpiRsConvertGenericReg, /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+ AcpiRsConvertGpio, /* 0x11, ACPI_RESOURCE_TYPE_GPIO */
+ AcpiRsConvertFixedDma, /* 0x12, ACPI_RESOURCE_TYPE_FIXED_DMA */
+ NULL, /* 0x13, ACPI_RESOURCE_TYPE_SERIAL_BUS - Use subtype table below */
+};
+
+/* Dispatch tables for AML-to-resource (Get Resource) conversion functions */
+
+ACPI_RSCONVERT_INFO *AcpiGbl_GetResourceDispatch[] =
+{
+ /* Small descriptors */
+
+ NULL, /* 0x00, Reserved */
+ NULL, /* 0x01, Reserved */
+ NULL, /* 0x02, Reserved */
+ NULL, /* 0x03, Reserved */
+ AcpiRsGetIrq, /* 0x04, ACPI_RESOURCE_NAME_IRQ */
+ AcpiRsConvertDma, /* 0x05, ACPI_RESOURCE_NAME_DMA */
+ AcpiRsGetStartDpf, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+ AcpiRsConvertEndDpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+ AcpiRsConvertIo, /* 0x08, ACPI_RESOURCE_NAME_IO */
+ AcpiRsConvertFixedIo, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */
+ AcpiRsConvertFixedDma, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
+ NULL, /* 0x0B, Reserved */
+ NULL, /* 0x0C, Reserved */
+ NULL, /* 0x0D, Reserved */
+ AcpiRsGetVendorSmall, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */
+ AcpiRsConvertEndTag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */
+
+ /* Large descriptors */
+
+ NULL, /* 0x00, Reserved */
+ AcpiRsConvertMemory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */
+ AcpiRsConvertGenericReg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+ NULL, /* 0x03, Reserved */
+ AcpiRsGetVendorLarge, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */
+ AcpiRsConvertMemory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */
+ AcpiRsConvertFixedMemory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */
+ AcpiRsConvertAddress32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */
+ AcpiRsConvertAddress16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */
+ AcpiRsConvertExtIrq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */
+ AcpiRsConvertAddress64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */
+ AcpiRsConvertExtAddress64, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */
+ AcpiRsConvertGpio, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */
+ NULL, /* 0x0D, Reserved */
+ NULL, /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use subtype table below */
+};
+
+/* Subtype table for SerialBus -- I2C, SPI, and UART */
+
+ACPI_RSCONVERT_INFO *AcpiGbl_ConvertResourceSerialBusDispatch[] =
+{
+ NULL,
+ AcpiRsConvertI2cSerialBus,
+ AcpiRsConvertSpiSerialBus,
+ AcpiRsConvertUartSerialBus,
+};
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUGGER)
+
+/* Dispatch table for resource dump functions */
+
+ACPI_RSDUMP_INFO *AcpiGbl_DumpResourceDispatch[] =
+{
+ AcpiRsDumpIrq, /* ACPI_RESOURCE_TYPE_IRQ */
+ AcpiRsDumpDma, /* ACPI_RESOURCE_TYPE_DMA */
+ AcpiRsDumpStartDpf, /* ACPI_RESOURCE_TYPE_START_DEPENDENT */
+ AcpiRsDumpEndDpf, /* ACPI_RESOURCE_TYPE_END_DEPENDENT */
+ AcpiRsDumpIo, /* ACPI_RESOURCE_TYPE_IO */
+ AcpiRsDumpFixedIo, /* ACPI_RESOURCE_TYPE_FIXED_IO */
+ AcpiRsDumpVendor, /* ACPI_RESOURCE_TYPE_VENDOR */
+ AcpiRsDumpEndTag, /* ACPI_RESOURCE_TYPE_END_TAG */
+ AcpiRsDumpMemory24, /* ACPI_RESOURCE_TYPE_MEMORY24 */
+ AcpiRsDumpMemory32, /* ACPI_RESOURCE_TYPE_MEMORY32 */
+ AcpiRsDumpFixedMemory32, /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+ AcpiRsDumpAddress16, /* ACPI_RESOURCE_TYPE_ADDRESS16 */
+ AcpiRsDumpAddress32, /* ACPI_RESOURCE_TYPE_ADDRESS32 */
+ AcpiRsDumpAddress64, /* ACPI_RESOURCE_TYPE_ADDRESS64 */
+ AcpiRsDumpExtAddress64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+ AcpiRsDumpExtIrq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+ AcpiRsDumpGenericReg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+ AcpiRsDumpGpio, /* ACPI_RESOURCE_TYPE_GPIO */
+ AcpiRsDumpFixedDma, /* ACPI_RESOURCE_TYPE_FIXED_DMA */
+ NULL, /* ACPI_RESOURCE_TYPE_SERIAL_BUS */
+};
+
+ACPI_RSDUMP_INFO *AcpiGbl_DumpSerialBusDispatch[] =
+{
+ NULL,
+ AcpiRsDumpI2cSerialBus, /* AML_RESOURCE_I2C_BUS_TYPE */
+ AcpiRsDumpSpiSerialBus, /* AML_RESOURCE_SPI_BUS_TYPE */
+ AcpiRsDumpUartSerialBus, /* AML_RESOURCE_UART_BUS_TYPE */
+};
+#endif
+
+
+/*
+ * Base sizes for external AML resource descriptors, indexed by internal type.
+ * Includes size of the descriptor header (1 byte for small descriptors,
+ * 3 bytes for large descriptors)
+ */
+const UINT8 AcpiGbl_AmlResourceSizes[] =
+{
+ sizeof (AML_RESOURCE_IRQ), /* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */
+ sizeof (AML_RESOURCE_DMA), /* ACPI_RESOURCE_TYPE_DMA */
+ sizeof (AML_RESOURCE_START_DEPENDENT), /* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */
+ sizeof (AML_RESOURCE_END_DEPENDENT), /* ACPI_RESOURCE_TYPE_END_DEPENDENT */
+ sizeof (AML_RESOURCE_IO), /* ACPI_RESOURCE_TYPE_IO */
+ sizeof (AML_RESOURCE_FIXED_IO), /* ACPI_RESOURCE_TYPE_FIXED_IO */
+ sizeof (AML_RESOURCE_VENDOR_SMALL), /* ACPI_RESOURCE_TYPE_VENDOR */
+ sizeof (AML_RESOURCE_END_TAG), /* ACPI_RESOURCE_TYPE_END_TAG */
+ sizeof (AML_RESOURCE_MEMORY24), /* ACPI_RESOURCE_TYPE_MEMORY24 */
+ sizeof (AML_RESOURCE_MEMORY32), /* ACPI_RESOURCE_TYPE_MEMORY32 */
+ sizeof (AML_RESOURCE_FIXED_MEMORY32), /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+ sizeof (AML_RESOURCE_ADDRESS16), /* ACPI_RESOURCE_TYPE_ADDRESS16 */
+ sizeof (AML_RESOURCE_ADDRESS32), /* ACPI_RESOURCE_TYPE_ADDRESS32 */
+ sizeof (AML_RESOURCE_ADDRESS64), /* ACPI_RESOURCE_TYPE_ADDRESS64 */
+ sizeof (AML_RESOURCE_EXTENDED_ADDRESS64),/*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+ sizeof (AML_RESOURCE_EXTENDED_IRQ), /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+ sizeof (AML_RESOURCE_GENERIC_REGISTER), /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+ sizeof (AML_RESOURCE_GPIO), /* ACPI_RESOURCE_TYPE_GPIO */
+ sizeof (AML_RESOURCE_FIXED_DMA), /* ACPI_RESOURCE_TYPE_FIXED_DMA */
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS), /* ACPI_RESOURCE_TYPE_SERIAL_BUS */
+};
+
+
+const UINT8 AcpiGbl_ResourceStructSizes[] =
+{
+ /* Small descriptors */
+
+ 0,
+ 0,
+ 0,
+ 0,
+ ACPI_RS_SIZE (ACPI_RESOURCE_IRQ),
+ ACPI_RS_SIZE (ACPI_RESOURCE_DMA),
+ ACPI_RS_SIZE (ACPI_RESOURCE_START_DEPENDENT),
+ ACPI_RS_SIZE_MIN,
+ ACPI_RS_SIZE (ACPI_RESOURCE_IO),
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_IO),
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_DMA),
+ 0,
+ 0,
+ 0,
+ ACPI_RS_SIZE (ACPI_RESOURCE_VENDOR),
+ ACPI_RS_SIZE_MIN,
+
+ /* Large descriptors */
+
+ 0,
+ ACPI_RS_SIZE (ACPI_RESOURCE_MEMORY24),
+ ACPI_RS_SIZE (ACPI_RESOURCE_GENERIC_REGISTER),
+ 0,
+ ACPI_RS_SIZE (ACPI_RESOURCE_VENDOR),
+ ACPI_RS_SIZE (ACPI_RESOURCE_MEMORY32),
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_MEMORY32),
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS32),
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS16),
+ ACPI_RS_SIZE (ACPI_RESOURCE_EXTENDED_IRQ),
+ ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS64),
+ ACPI_RS_SIZE (ACPI_RESOURCE_EXTENDED_ADDRESS64),
+ ACPI_RS_SIZE (ACPI_RESOURCE_GPIO),
+ ACPI_RS_SIZE (ACPI_RESOURCE_COMMON_SERIALBUS)
+};
+
+const UINT8 AcpiGbl_AmlResourceSerialBusSizes[] =
+{
+ 0,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS),
+ sizeof (AML_RESOURCE_SPI_SERIALBUS),
+ sizeof (AML_RESOURCE_UART_SERIALBUS),
+};
+
+const UINT8 AcpiGbl_ResourceStructSerialBusSizes[] =
+{
+ 0,
+ ACPI_RS_SIZE (ACPI_RESOURCE_I2C_SERIALBUS),
+ ACPI_RS_SIZE (ACPI_RESOURCE_SPI_SERIALBUS),
+ ACPI_RS_SIZE (ACPI_RESOURCE_UART_SERIALBUS),
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsio.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsio.c
new file mode 100644
index 0000000000..473fe36e03
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsio.c
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ *
+ * Module Name: rsio - IO and DMA resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsio")
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertIo
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertIo[5] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO,
+ ACPI_RS_SIZE (ACPI_RESOURCE_IO),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertIo)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO,
+ sizeof (AML_RESOURCE_IO),
+ 0},
+
+ /* Decode flag */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Io.IoDecode),
+ AML_OFFSET (Io.Flags),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Alignment
+ * Length
+ * Minimum Base Address
+ * Maximum Base Address
+ */
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Io.Alignment),
+ AML_OFFSET (Io.Alignment),
+ 2},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.Io.Minimum),
+ AML_OFFSET (Io.Minimum),
+ 2}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertFixedIo
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertFixedIo[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO,
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_IO),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertFixedIo)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO,
+ sizeof (AML_RESOURCE_FIXED_IO),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Base Address
+ * Length
+ */
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.FixedIo.AddressLength),
+ AML_OFFSET (FixedIo.AddressLength),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.FixedIo.Address),
+ AML_OFFSET (FixedIo.Address),
+ 1}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertGenericReg
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertGenericReg[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER,
+ ACPI_RS_SIZE (ACPI_RESOURCE_GENERIC_REGISTER),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertGenericReg)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER,
+ sizeof (AML_RESOURCE_GENERIC_REGISTER),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Address Space ID
+ * Register Bit Width
+ * Register Bit Offset
+ * Access Size
+ */
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.GenericReg.SpaceId),
+ AML_OFFSET (GenericReg.AddressSpaceId),
+ 4},
+
+ /* Get the Register Address */
+
+ {ACPI_RSC_MOVE64, ACPI_RS_OFFSET (Data.GenericReg.Address),
+ AML_OFFSET (GenericReg.Address),
+ 1}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertEndDpf
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertEndDpf[2] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT,
+ ACPI_RS_SIZE_MIN,
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertEndDpf)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT,
+ sizeof (AML_RESOURCE_END_DEPENDENT),
+ 0}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertEndTag
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertEndTag[2] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG,
+ ACPI_RS_SIZE_MIN,
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertEndTag)},
+
+ /*
+ * Note: The checksum field is set to zero, meaning that the resource
+ * data is treated as if the checksum operation succeeded.
+ * (ACPI Spec 1.0b Section 6.4.2.8)
+ */
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG,
+ sizeof (AML_RESOURCE_END_TAG),
+ 0}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsGetStartDpf
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsGetStartDpf[6] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT,
+ ACPI_RS_SIZE (ACPI_RESOURCE_START_DEPENDENT),
+ ACPI_RSC_TABLE_SIZE (AcpiRsGetStartDpf)},
+
+ /* Defaults for Compatibility and Performance priorities */
+
+ {ACPI_RSC_SET8, ACPI_RS_OFFSET (Data.StartDpf.CompatibilityPriority),
+ ACPI_ACCEPTABLE_CONFIGURATION,
+ 2},
+
+ /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.StartDpf.DescriptorLength),
+ AML_OFFSET (StartDpf.DescriptorType),
+ 0},
+
+ /* All done if there is no flag byte present in the descriptor */
+
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1},
+
+ /* Flag byte is present, get the flags */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.StartDpf.CompatibilityPriority),
+ AML_OFFSET (StartDpf.Flags),
+ 0},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.StartDpf.PerformanceRobustness),
+ AML_OFFSET (StartDpf.Flags),
+ 2}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsSetStartDpf
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsSetStartDpf[10] =
+{
+ /* Start with a default descriptor of length 1 */
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT,
+ sizeof (AML_RESOURCE_START_DEPENDENT),
+ ACPI_RSC_TABLE_SIZE (AcpiRsSetStartDpf)},
+
+ /* Set the default flag values */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.StartDpf.CompatibilityPriority),
+ AML_OFFSET (StartDpf.Flags),
+ 0},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.StartDpf.PerformanceRobustness),
+ AML_OFFSET (StartDpf.Flags),
+ 2},
+ /*
+ * All done if the output descriptor length is required to be 1
+ * (i.e., optimization to 0 bytes cannot be attempted)
+ */
+ {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET(Data.StartDpf.DescriptorLength),
+ 1},
+
+ /* Set length to 0 bytes (no flags byte) */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO)},
+
+ /*
+ * All done if the output descriptor length is required to be 0.
+ *
+ * TBD: Perhaps we should check for error if input flags are not
+ * compatible with a 0-byte descriptor.
+ */
+ {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET(Data.StartDpf.DescriptorLength),
+ 0},
+
+ /* Reset length to 1 byte (descriptor with flags byte) */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_START_DEPENDENT)},
+
+
+ /*
+ * All done if flags byte is necessary -- if either priority value
+ * is not ACPI_ACCEPTABLE_CONFIGURATION
+ */
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET (Data.StartDpf.CompatibilityPriority),
+ ACPI_ACCEPTABLE_CONFIGURATION},
+
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET (Data.StartDpf.PerformanceRobustness),
+ ACPI_ACCEPTABLE_CONFIGURATION},
+
+ /* Flag byte is not necessary */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO)}
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsirq.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsirq.c
new file mode 100644
index 0000000000..cf91f3d144
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsirq.c
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ *
+ * Module Name: rsirq - IRQ resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsirq")
+
+
+/*******************************************************************************
+ *
+ * AcpiRsGetIrq
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsGetIrq[9] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
+ ACPI_RS_SIZE (ACPI_RESOURCE_IRQ),
+ ACPI_RSC_TABLE_SIZE (AcpiRsGetIrq)},
+
+ /* Get the IRQ mask (bytes 1:2) */
+
+ {ACPI_RSC_BITMASK16,ACPI_RS_OFFSET (Data.Irq.Interrupts[0]),
+ AML_OFFSET (Irq.IrqMask),
+ ACPI_RS_OFFSET (Data.Irq.InterruptCount)},
+
+ /* Set default flags (others are zero) */
+
+ {ACPI_RSC_SET8, ACPI_RS_OFFSET (Data.Irq.Triggering),
+ ACPI_EDGE_SENSITIVE,
+ 1},
+
+ /* Get the descriptor length (2 or 3 for IRQ descriptor) */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Irq.DescriptorLength),
+ AML_OFFSET (Irq.DescriptorType),
+ 0},
+
+ /* All done if no flag byte present in descriptor */
+
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
+
+ /* Get flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Triggering),
+ AML_OFFSET (Irq.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Polarity),
+ AML_OFFSET (Irq.Flags),
+ 3},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Sharable),
+ AML_OFFSET (Irq.Flags),
+ 4},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.WakeCapable),
+ AML_OFFSET (Irq.Flags),
+ 5}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsSetIrq
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsSetIrq[14] =
+{
+ /* Start with a default descriptor of length 3 */
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
+ sizeof (AML_RESOURCE_IRQ),
+ ACPI_RSC_TABLE_SIZE (AcpiRsSetIrq)},
+
+ /* Convert interrupt list to 16-bit IRQ bitmask */
+
+ {ACPI_RSC_BITMASK16,ACPI_RS_OFFSET (Data.Irq.Interrupts[0]),
+ AML_OFFSET (Irq.IrqMask),
+ ACPI_RS_OFFSET (Data.Irq.InterruptCount)},
+
+ /* Set flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Triggering),
+ AML_OFFSET (Irq.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Polarity),
+ AML_OFFSET (Irq.Flags),
+ 3},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.Sharable),
+ AML_OFFSET (Irq.Flags),
+ 4},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Irq.WakeCapable),
+ AML_OFFSET (Irq.Flags),
+ 5},
+
+ /*
+ * All done if the output descriptor length is required to be 3
+ * (i.e., optimization to 2 bytes cannot be attempted)
+ */
+ {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET(Data.Irq.DescriptorLength),
+ 3},
+
+ /* Set length to 2 bytes (no flags byte) */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_IRQ_NOFLAGS)},
+
+ /*
+ * All done if the output descriptor length is required to be 2.
+ *
+ * TBD: Perhaps we should check for error if input flags are not
+ * compatible with a 2-byte descriptor.
+ */
+ {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET(Data.Irq.DescriptorLength),
+ 2},
+
+ /* Reset length to 3 bytes (descriptor with flags byte) */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_IRQ)},
+
+ /*
+ * Check if the flags byte is necessary. Not needed if the flags are:
+ * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
+ */
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET (Data.Irq.Triggering),
+ ACPI_EDGE_SENSITIVE},
+
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET (Data.Irq.Polarity),
+ ACPI_ACTIVE_HIGH},
+
+ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+ ACPI_RS_OFFSET (Data.Irq.Sharable),
+ ACPI_EXCLUSIVE},
+
+ /* We can optimize to a 2-byte IrqNoFlags() descriptor */
+
+ {ACPI_RSC_LENGTH, 0, 0, sizeof (AML_RESOURCE_IRQ_NOFLAGS)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertExtIrq
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertExtIrq[10] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
+ ACPI_RS_SIZE (ACPI_RESOURCE_EXTENDED_IRQ),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertExtIrq)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ,
+ sizeof (AML_RESOURCE_EXTENDED_IRQ),
+ 0},
+
+ /*
+ * Flags: Producer/Consumer[0], Triggering[1], Polarity[2],
+ * Sharing[3], Wake[4]
+ */
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.ExtendedIrq.ProducerConsumer),
+ AML_OFFSET (ExtendedIrq.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.ExtendedIrq.Triggering),
+ AML_OFFSET (ExtendedIrq.Flags),
+ 1},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.ExtendedIrq.Polarity),
+ AML_OFFSET (ExtendedIrq.Flags),
+ 2},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.ExtendedIrq.Sharable),
+ AML_OFFSET (ExtendedIrq.Flags),
+ 3},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.ExtendedIrq.WakeCapable),
+ AML_OFFSET (ExtendedIrq.Flags),
+ 4},
+
+ /* IRQ Table length (Byte4) */
+
+ {ACPI_RSC_COUNT, ACPI_RS_OFFSET (Data.ExtendedIrq.InterruptCount),
+ AML_OFFSET (ExtendedIrq.InterruptCount),
+ sizeof (UINT32)},
+
+ /* Copy every IRQ in the table, each is 32 bits */
+
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.ExtendedIrq.Interrupts[0]),
+ AML_OFFSET (ExtendedIrq.Interrupts[0]),
+ 0},
+
+ /* Optional ResourceSource (Index and String) */
+
+ {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET (Data.ExtendedIrq.ResourceSource),
+ ACPI_RS_OFFSET (Data.ExtendedIrq.Interrupts[0]),
+ sizeof (AML_RESOURCE_EXTENDED_IRQ)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertDma
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertDma[6] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA,
+ ACPI_RS_SIZE (ACPI_RESOURCE_DMA),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertDma)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA,
+ sizeof (AML_RESOURCE_DMA),
+ 0},
+
+ /* Flags: transfer preference, bus mastering, channel speed */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Dma.Transfer),
+ AML_OFFSET (Dma.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Dma.BusMaster),
+ AML_OFFSET (Dma.Flags),
+ 2},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Dma.Type),
+ AML_OFFSET (Dma.Flags),
+ 5},
+
+ /* DMA channel mask bits */
+
+ {ACPI_RSC_BITMASK, ACPI_RS_OFFSET (Data.Dma.Channels[0]),
+ AML_OFFSET (Dma.DmaChannelMask),
+ ACPI_RS_OFFSET (Data.Dma.ChannelCount)}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertFixedDma
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertFixedDma[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_DMA,
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_DMA),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertFixedDma)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_DMA,
+ sizeof (AML_RESOURCE_FIXED_DMA),
+ 0},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * RequestLines
+ * Channels
+ */
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.FixedDma.RequestLines),
+ AML_OFFSET (FixedDma.RequestLines),
+ 2},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.FixedDma.Width),
+ AML_OFFSET (FixedDma.Width),
+ 1},
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rslist.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rslist.c
new file mode 100644
index 0000000000..82610585de
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rslist.c
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ *
+ * Module Name: rslist - Linked list utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rslist")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsConvertAmlToResources
+ *
+ * PARAMETERS: ACPI_WALK_AML_CALLBACK
+ * ResourcePtr - Pointer to the buffer that will
+ * contain the output structures
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an AML resource to an internal representation of the
+ * resource that is aligned and easier to access.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsConvertAmlToResources (
+ UINT8 *Aml,
+ UINT32 Length,
+ UINT32 Offset,
+ UINT8 ResourceIndex,
+ void **Context)
+{
+ ACPI_RESOURCE **ResourcePtr = ACPI_CAST_INDIRECT_PTR (
+ ACPI_RESOURCE, Context);
+ ACPI_RESOURCE *Resource;
+ AML_RESOURCE *AmlResource;
+ ACPI_RSCONVERT_INFO *ConversionTable;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsConvertAmlToResources);
+
+
+ /*
+ * Check that the input buffer and all subsequent pointers into it
+ * are aligned on a native word boundary. Most important on IA64
+ */
+ Resource = *ResourcePtr;
+ if (ACPI_IS_MISALIGNED (Resource))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Misaligned resource pointer %p", Resource));
+ }
+
+ /* Get the appropriate conversion info table */
+
+ AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
+ if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_SERIAL_BUS)
+ {
+ if (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)
+ {
+ ConversionTable = NULL;
+ }
+ else
+ {
+ /* This is an I2C, SPI, or UART SerialBus descriptor */
+
+ ConversionTable =
+ AcpiGbl_ConvertResourceSerialBusDispatch[
+ AmlResource->CommonSerialBus.Type];
+ }
+ }
+ else
+ {
+ ConversionTable =
+ AcpiGbl_GetResourceDispatch[ResourceIndex];
+ }
+
+ if (!ConversionTable)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+ ResourceIndex));
+ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ }
+
+ /* Convert the AML byte stream resource to a local resource struct */
+
+ Status = AcpiRsConvertAmlToResource (
+ Resource, AmlResource, ConversionTable);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not convert AML resource (Type 0x%X)", *Aml));
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
+ "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
+ AcpiUtGetResourceType (Aml), Length,
+ Resource->Length));
+
+ /* Point to the next structure in the output buffer */
+
+ *ResourcePtr = ACPI_NEXT_RESOURCE (Resource);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsConvertResourcesToAml
+ *
+ * PARAMETERS: Resource - Pointer to the resource linked list
+ * AmlSizeNeeded - Calculated size of the byte stream
+ * needed from calling AcpiRsGetAmlLength()
+ * The size of the OutputBuffer is
+ * guaranteed to be >= AmlSizeNeeded
+ * OutputBuffer - Pointer to the buffer that will
+ * contain the byte stream
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Takes the resource linked list and parses it, creating a
+ * byte stream of resources in the caller's output buffer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsConvertResourcesToAml (
+ ACPI_RESOURCE *Resource,
+ ACPI_SIZE AmlSizeNeeded,
+ UINT8 *OutputBuffer)
+{
+ UINT8 *Aml = OutputBuffer;
+ UINT8 *EndAml = OutputBuffer + AmlSizeNeeded;
+ ACPI_RSCONVERT_INFO *ConversionTable;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsConvertResourcesToAml);
+
+
+ /* Walk the resource descriptor list, convert each descriptor */
+
+ while (Aml < EndAml)
+ {
+ /* Validate the (internal) Resource Type */
+
+ if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid descriptor type (0x%X) in resource list",
+ Resource->Type));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!Resource->Length)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid zero length descriptor in resource list\n"));
+ return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
+ /* Perform the conversion */
+
+ if (Resource->Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
+ {
+ if (Resource->Data.CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)
+ {
+ ConversionTable = NULL;
+ }
+ else
+ {
+ /* This is an I2C, SPI, or UART SerialBus descriptor */
+
+ ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[
+ Resource->Data.CommonSerialBus.Type];
+ }
+ }
+ else
+ {
+ ConversionTable = AcpiGbl_SetResourceDispatch[Resource->Type];
+ }
+
+ if (!ConversionTable)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+ Resource->Type));
+ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ }
+
+ Status = AcpiRsConvertResourceToAml (Resource,
+ ACPI_CAST_PTR (AML_RESOURCE, Aml),
+ ConversionTable);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not convert resource (type 0x%X) to AML",
+ Resource->Type));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Perform final sanity check on the new AML resource descriptor */
+
+ Status = AcpiUtValidateResource (NULL,
+ ACPI_CAST_PTR (AML_RESOURCE, Aml), NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Check for end-of-list, normal exit */
+
+ if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
+ {
+ /* An End Tag indicates the end of the input Resource Template */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Extract the total length of the new descriptor and set the
+ * Aml to point to the next (output) resource descriptor
+ */
+ Aml += AcpiUtGetDescriptorLength (Aml);
+
+ /* Point to the next input resource descriptor */
+
+ Resource = ACPI_NEXT_RESOURCE (Resource);
+ }
+
+ /* Completed buffer, but did not find an EndTag resource descriptor */
+
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmemory.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmemory.c
new file mode 100644
index 0000000000..761a000c33
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmemory.c
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ *
+ * Module Name: rsmem24 - Memory resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsmemory")
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertMemory24
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertMemory24[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24,
+ ACPI_RS_SIZE (ACPI_RESOURCE_MEMORY24),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertMemory24)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24,
+ sizeof (AML_RESOURCE_MEMORY24),
+ 0},
+
+ /* Read/Write bit */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Memory24.WriteProtect),
+ AML_OFFSET (Memory24.Flags),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Minimum Base Address
+ * Maximum Base Address
+ * Address Base Alignment
+ * Range Length
+ */
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.Memory24.Minimum),
+ AML_OFFSET (Memory24.Minimum),
+ 4}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertMemory32
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertMemory32[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32,
+ ACPI_RS_SIZE (ACPI_RESOURCE_MEMORY32),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertMemory32)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32,
+ sizeof (AML_RESOURCE_MEMORY32),
+ 0},
+
+ /* Read/Write bit */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Memory32.WriteProtect),
+ AML_OFFSET (Memory32.Flags),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Minimum Base Address
+ * Maximum Base Address
+ * Address Base Alignment
+ * Range Length
+ */
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.Memory32.Minimum),
+ AML_OFFSET (Memory32.Minimum),
+ 4}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertFixedMemory32
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertFixedMemory32[4] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
+ ACPI_RS_SIZE (ACPI_RESOURCE_FIXED_MEMORY32),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertFixedMemory32)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32,
+ sizeof (AML_RESOURCE_FIXED_MEMORY32),
+ 0},
+
+ /* Read/Write bit */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.FixedMemory32.WriteProtect),
+ AML_OFFSET (FixedMemory32.Flags),
+ 0},
+ /*
+ * These fields are contiguous in both the source and destination:
+ * Base Address
+ * Range Length
+ */
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.FixedMemory32.Address),
+ AML_OFFSET (FixedMemory32.Address),
+ 2}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsGetVendorSmall
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsGetVendorSmall[3] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
+ ACPI_RS_SIZE (ACPI_RESOURCE_VENDOR),
+ ACPI_RSC_TABLE_SIZE (AcpiRsGetVendorSmall)},
+
+ /* Length of the vendor data (byte count) */
+
+ {ACPI_RSC_COUNT16, ACPI_RS_OFFSET (Data.Vendor.ByteLength),
+ 0,
+ sizeof (UINT8)},
+
+ /* Vendor data */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Vendor.ByteData[0]),
+ sizeof (AML_RESOURCE_SMALL_HEADER),
+ 0}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsGetVendorLarge
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsGetVendorLarge[3] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
+ ACPI_RS_SIZE (ACPI_RESOURCE_VENDOR),
+ ACPI_RSC_TABLE_SIZE (AcpiRsGetVendorLarge)},
+
+ /* Length of the vendor data (byte count) */
+
+ {ACPI_RSC_COUNT16, ACPI_RS_OFFSET (Data.Vendor.ByteLength),
+ 0,
+ sizeof (UINT8)},
+
+ /* Vendor data */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Vendor.ByteData[0]),
+ sizeof (AML_RESOURCE_LARGE_HEADER),
+ 0}
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsSetVendor
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsSetVendor[7] =
+{
+ /* Default is a small vendor descriptor */
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL,
+ sizeof (AML_RESOURCE_SMALL_HEADER),
+ ACPI_RSC_TABLE_SIZE (AcpiRsSetVendor)},
+
+ /* Get the length and copy the data */
+
+ {ACPI_RSC_COUNT16, ACPI_RS_OFFSET (Data.Vendor.ByteLength),
+ 0,
+ 0},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Vendor.ByteData[0]),
+ sizeof (AML_RESOURCE_SMALL_HEADER),
+ 0},
+
+ /*
+ * All done if the Vendor byte length is 7 or less, meaning that it will
+ * fit within a small descriptor
+ */
+ {ACPI_RSC_EXIT_LE, 0, 0, 7},
+
+ /* Must create a large vendor descriptor */
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE,
+ sizeof (AML_RESOURCE_LARGE_HEADER),
+ 0},
+
+ {ACPI_RSC_COUNT16, ACPI_RS_OFFSET (Data.Vendor.ByteLength),
+ 0,
+ 0},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Vendor.ByteData[0]),
+ sizeof (AML_RESOURCE_LARGE_HEADER),
+ 0}
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmisc.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmisc.c
new file mode 100644
index 0000000000..cef8000892
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsmisc.c
@@ -0,0 +1,812 @@
+/*******************************************************************************
+ *
+ * Module Name: rsmisc - Miscellaneous resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsmisc")
+
+
+#define INIT_RESOURCE_TYPE(i) i->ResourceOffset
+#define INIT_RESOURCE_LENGTH(i) i->AmlOffset
+#define INIT_TABLE_LENGTH(i) i->Value
+
+#define COMPARE_OPCODE(i) i->ResourceOffset
+#define COMPARE_TARGET(i) i->AmlOffset
+#define COMPARE_VALUE(i) i->Value
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsConvertAmlToResource
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
+ * Info - Pointer to appropriate conversion table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
+ * internal resource descriptor
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsConvertAmlToResource (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml,
+ ACPI_RSCONVERT_INFO *Info)
+{
+ ACPI_RS_LENGTH AmlResourceLength;
+ void *Source;
+ void *Destination;
+ char *Target;
+ UINT8 Count;
+ UINT8 FlagsMode = FALSE;
+ UINT16 ItemCount = 0;
+ UINT16 Temp16 = 0;
+
+
+ ACPI_FUNCTION_TRACE (RsConvertAmlToResource);
+
+
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (((ACPI_SIZE) Resource) & 0x3)
+ {
+ /* Each internal resource struct is expected to be 32-bit aligned */
+
+ ACPI_WARNING ((AE_INFO,
+ "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
+ Resource, Resource->Type, Resource->Length));
+ }
+
+ /* Extract the resource Length field (does not include header length) */
+
+ AmlResourceLength = AcpiUtGetResourceLength (Aml);
+
+ /*
+ * First table entry must be ACPI_RSC_INITxxx and must contain the
+ * table length (# of table entries)
+ */
+ Count = INIT_TABLE_LENGTH (Info);
+ while (Count)
+ {
+ /*
+ * Source is the external AML byte stream buffer,
+ * destination is the internal resource descriptor
+ */
+ Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
+ Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
+
+ switch (Info->Opcode)
+ {
+ case ACPI_RSC_INITGET:
+ /*
+ * Get the resource type and the initial (minimum) length
+ */
+ memset (Resource, 0, INIT_RESOURCE_LENGTH (Info));
+ Resource->Type = INIT_RESOURCE_TYPE (Info);
+ Resource->Length = INIT_RESOURCE_LENGTH (Info);
+ break;
+
+ case ACPI_RSC_INITSET:
+ break;
+
+ case ACPI_RSC_FLAGINIT:
+
+ FlagsMode = TRUE;
+ break;
+
+ case ACPI_RSC_1BITFLAG:
+ /*
+ * Mask and shift the flag bit
+ */
+ ACPI_SET8 (Destination,
+ ((ACPI_GET8 (Source) >> Info->Value) & 0x01));
+ break;
+
+ case ACPI_RSC_2BITFLAG:
+ /*
+ * Mask and shift the flag bits
+ */
+ ACPI_SET8 (Destination,
+ ((ACPI_GET8 (Source) >> Info->Value) & 0x03));
+ break;
+
+ case ACPI_RSC_3BITFLAG:
+ /*
+ * Mask and shift the flag bits
+ */
+ ACPI_SET8 (Destination,
+ ((ACPI_GET8 (Source) >> Info->Value) & 0x07));
+ break;
+
+ case ACPI_RSC_COUNT:
+
+ ItemCount = ACPI_GET8 (Source);
+ ACPI_SET8 (Destination, ItemCount);
+
+ Resource->Length = Resource->Length +
+ (Info->Value * (ItemCount - 1));
+ break;
+
+ case ACPI_RSC_COUNT16:
+
+ ItemCount = AmlResourceLength;
+ ACPI_SET16 (Destination, ItemCount);
+
+ Resource->Length = Resource->Length +
+ (Info->Value * (ItemCount - 1));
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_PIN:
+
+ Target = ACPI_ADD_PTR (void, Aml, Info->Value);
+ ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
+
+ Resource->Length = Resource->Length + ItemCount;
+ ItemCount = ItemCount / 2;
+ ACPI_SET16 (Destination, ItemCount);
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_VEN:
+
+ ItemCount = ACPI_GET8 (Source);
+ ACPI_SET8 (Destination, ItemCount);
+
+ Resource->Length = Resource->Length +
+ (Info->Value * ItemCount);
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_RES:
+ /*
+ * Vendor data is optional (length/offset may both be zero)
+ * Examine vendor data length field first
+ */
+ Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2));
+ if (ACPI_GET16 (Target))
+ {
+ /* Use vendor offset to get resource source length */
+
+ Target = ACPI_ADD_PTR (void, Aml, Info->Value);
+ ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
+ }
+ else
+ {
+ /* No vendor data to worry about */
+
+ ItemCount = Aml->LargeHeader.ResourceLength +
+ sizeof (AML_RESOURCE_LARGE_HEADER) -
+ ACPI_GET16 (Source);
+ }
+
+ Resource->Length = Resource->Length + ItemCount;
+ ACPI_SET16 (Destination, ItemCount);
+ break;
+
+ case ACPI_RSC_COUNT_SERIAL_VEN:
+
+ ItemCount = ACPI_GET16 (Source) - Info->Value;
+
+ Resource->Length = Resource->Length + ItemCount;
+ ACPI_SET16 (Destination, ItemCount);
+ break;
+
+ case ACPI_RSC_COUNT_SERIAL_RES:
+
+ ItemCount = (AmlResourceLength +
+ sizeof (AML_RESOURCE_LARGE_HEADER)) -
+ ACPI_GET16 (Source) - Info->Value;
+
+ Resource->Length = Resource->Length + ItemCount;
+ ACPI_SET16 (Destination, ItemCount);
+ break;
+
+ case ACPI_RSC_LENGTH:
+
+ Resource->Length = Resource->Length + Info->Value;
+ break;
+
+ case ACPI_RSC_MOVE8:
+ case ACPI_RSC_MOVE16:
+ case ACPI_RSC_MOVE32:
+ case ACPI_RSC_MOVE64:
+ /*
+ * Raw data move. Use the Info value field unless ItemCount has
+ * been previously initialized via a COUNT opcode
+ */
+ if (Info->Value)
+ {
+ ItemCount = Info->Value;
+ }
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_GPIO_PIN:
+
+ /* Generate and set the PIN data pointer */
+
+ Target = (char *) ACPI_ADD_PTR (void, Resource,
+ (Resource->Length - ItemCount * 2));
+ *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target);
+
+ /* Copy the PIN data */
+
+ Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
+ AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_GPIO_RES:
+
+ /* Generate and set the ResourceSource string pointer */
+
+ Target = (char *) ACPI_ADD_PTR (void, Resource,
+ (Resource->Length - ItemCount));
+ *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
+
+ /* Copy the ResourceSource string */
+
+ Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
+ AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_SERIAL_VEN:
+
+ /* Generate and set the Vendor Data pointer */
+
+ Target = (char *) ACPI_ADD_PTR (void, Resource,
+ (Resource->Length - ItemCount));
+ *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
+
+ /* Copy the Vendor Data */
+
+ Source = ACPI_ADD_PTR (void, Aml, Info->Value);
+ AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_SERIAL_RES:
+
+ /* Generate and set the ResourceSource string pointer */
+
+ Target = (char *) ACPI_ADD_PTR (void, Resource,
+ (Resource->Length - ItemCount));
+ *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
+
+ /* Copy the ResourceSource string */
+
+ Source = ACPI_ADD_PTR (void, Aml, (ACPI_GET16 (Source) + Info->Value));
+ AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_SET8:
+
+ memset (Destination, Info->AmlOffset, Info->Value);
+ break;
+
+ case ACPI_RSC_DATA8:
+
+ Target = ACPI_ADD_PTR (char, Resource, Info->Value);
+ memcpy (Destination, Source, ACPI_GET16 (Target));
+ break;
+
+ case ACPI_RSC_ADDRESS:
+ /*
+ * Common handler for address descriptor flags
+ */
+ if (!AcpiRsGetAddressCommon (Resource, Aml))
+ {
+ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+ }
+ break;
+
+ case ACPI_RSC_SOURCE:
+ /*
+ * Optional ResourceSource (Index and String)
+ */
+ Resource->Length +=
+ AcpiRsGetResourceSource (AmlResourceLength, Info->Value,
+ Destination, Aml, NULL);
+ break;
+
+ case ACPI_RSC_SOURCEX:
+ /*
+ * Optional ResourceSource (Index and String). This is the more
+ * complicated case used by the Interrupt() macro
+ */
+ Target = ACPI_ADD_PTR (char, Resource,
+ Info->AmlOffset + (ItemCount * 4));
+
+ Resource->Length +=
+ AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH)
+ (((ItemCount - 1) * sizeof (UINT32)) + Info->Value),
+ Destination, Aml, Target);
+ break;
+
+ case ACPI_RSC_BITMASK:
+ /*
+ * 8-bit encoded bitmask (DMA macro)
+ */
+ ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination);
+ if (ItemCount)
+ {
+ Resource->Length += (ItemCount - 1);
+ }
+
+ Target = ACPI_ADD_PTR (char, Resource, Info->Value);
+ ACPI_SET8 (Target, ItemCount);
+ break;
+
+ case ACPI_RSC_BITMASK16:
+ /*
+ * 16-bit encoded bitmask (IRQ macro)
+ */
+ ACPI_MOVE_16_TO_16 (&Temp16, Source);
+
+ ItemCount = AcpiRsDecodeBitmask (Temp16, Destination);
+ if (ItemCount)
+ {
+ Resource->Length += (ItemCount - 1);
+ }
+
+ Target = ACPI_ADD_PTR (char, Resource, Info->Value);
+ ACPI_SET8 (Target, ItemCount);
+ break;
+
+ case ACPI_RSC_EXIT_NE:
+ /*
+ * Control - Exit conversion if not equal
+ */
+ switch (Info->ResourceOffset)
+ {
+ case ACPI_RSC_COMPARE_AML_LENGTH:
+
+ if (AmlResourceLength != Info->Value)
+ {
+ goto Exit;
+ }
+ break;
+
+ case ACPI_RSC_COMPARE_VALUE:
+
+ if (ACPI_GET8 (Source) != Info->Value)
+ {
+ goto Exit;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Count--;
+ Info++;
+ }
+
+Exit:
+ if (!FlagsMode)
+ {
+ /* Round the resource struct length up to the next boundary (32 or 64) */
+
+ Resource->Length = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length);
+ }
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsConvertResourceToAml
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
+ * Info - Pointer to appropriate conversion table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ * external AML resource descriptor.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsConvertResourceToAml (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml,
+ ACPI_RSCONVERT_INFO *Info)
+{
+ void *Source = NULL;
+ void *Destination;
+ char *Target;
+ ACPI_RSDESC_SIZE AmlLength = 0;
+ UINT8 Count;
+ UINT16 Temp16 = 0;
+ UINT16 ItemCount = 0;
+
+
+ ACPI_FUNCTION_TRACE (RsConvertResourceToAml);
+
+
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * First table entry must be ACPI_RSC_INITxxx and must contain the
+ * table length (# of table entries)
+ */
+ Count = INIT_TABLE_LENGTH (Info);
+
+ while (Count)
+ {
+ /*
+ * Source is the internal resource descriptor,
+ * destination is the external AML byte stream buffer
+ */
+ Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
+ Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
+
+ switch (Info->Opcode)
+ {
+ case ACPI_RSC_INITSET:
+
+ memset (Aml, 0, INIT_RESOURCE_LENGTH (Info));
+ AmlLength = INIT_RESOURCE_LENGTH (Info);
+ AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_INITGET:
+ break;
+
+ case ACPI_RSC_FLAGINIT:
+ /*
+ * Clear the flag byte
+ */
+ ACPI_SET8 (Destination, 0);
+ break;
+
+ case ACPI_RSC_1BITFLAG:
+ /*
+ * Mask and shift the flag bit
+ */
+ ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
+ ((ACPI_GET8 (Source) & 0x01) << Info->Value));
+ break;
+
+ case ACPI_RSC_2BITFLAG:
+ /*
+ * Mask and shift the flag bits
+ */
+ ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
+ ((ACPI_GET8 (Source) & 0x03) << Info->Value));
+ break;
+
+ case ACPI_RSC_3BITFLAG:
+ /*
+ * Mask and shift the flag bits
+ */
+ ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
+ ((ACPI_GET8 (Source) & 0x07) << Info->Value));
+ break;
+
+ case ACPI_RSC_COUNT:
+
+ ItemCount = ACPI_GET8 (Source);
+ ACPI_SET8 (Destination, ItemCount);
+
+ AmlLength = (UINT16) (AmlLength + (Info->Value * (ItemCount - 1)));
+ break;
+
+ case ACPI_RSC_COUNT16:
+
+ ItemCount = ACPI_GET16 (Source);
+ AmlLength = (UINT16) (AmlLength + ItemCount);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_PIN:
+
+ ItemCount = ACPI_GET16 (Source);
+ ACPI_SET16 (Destination, AmlLength);
+
+ AmlLength = (UINT16) (AmlLength + ItemCount * 2);
+ Target = ACPI_ADD_PTR (void, Aml, Info->Value);
+ ACPI_SET16 (Target, AmlLength);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_VEN:
+
+ ItemCount = ACPI_GET16 (Source);
+ ACPI_SET16 (Destination, ItemCount);
+
+ AmlLength = (UINT16) (AmlLength + (Info->Value * ItemCount));
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_COUNT_GPIO_RES:
+
+ /* Set resource source string length */
+
+ ItemCount = ACPI_GET16 (Source);
+ ACPI_SET16 (Destination, AmlLength);
+
+ /* Compute offset for the Vendor Data */
+
+ AmlLength = (UINT16) (AmlLength + ItemCount);
+ Target = ACPI_ADD_PTR (void, Aml, Info->Value);
+
+ /* Set vendor offset only if there is vendor data */
+
+ if (Resource->Data.Gpio.VendorLength)
+ {
+ ACPI_SET16 (Target, AmlLength);
+ }
+
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_COUNT_SERIAL_VEN:
+
+ ItemCount = ACPI_GET16 (Source);
+ ACPI_SET16 (Destination, ItemCount + Info->Value);
+ AmlLength = (UINT16) (AmlLength + ItemCount);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_COUNT_SERIAL_RES:
+
+ ItemCount = ACPI_GET16 (Source);
+ AmlLength = (UINT16) (AmlLength + ItemCount);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_LENGTH:
+
+ AcpiRsSetResourceLength (Info->Value, Aml);
+ break;
+
+ case ACPI_RSC_MOVE8:
+ case ACPI_RSC_MOVE16:
+ case ACPI_RSC_MOVE32:
+ case ACPI_RSC_MOVE64:
+
+ if (Info->Value)
+ {
+ ItemCount = Info->Value;
+ }
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_GPIO_PIN:
+
+ Destination = (char *) ACPI_ADD_PTR (void, Aml,
+ ACPI_GET16 (Destination));
+ Source = * (UINT16 **) Source;
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_GPIO_RES:
+
+ /* Used for both ResourceSource string and VendorData */
+
+ Destination = (char *) ACPI_ADD_PTR (void, Aml,
+ ACPI_GET16 (Destination));
+ Source = * (UINT8 **) Source;
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_SERIAL_VEN:
+
+ Destination = (char *) ACPI_ADD_PTR (void, Aml,
+ (AmlLength - ItemCount));
+ Source = * (UINT8 **) Source;
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_MOVE_SERIAL_RES:
+
+ Destination = (char *) ACPI_ADD_PTR (void, Aml,
+ (AmlLength - ItemCount));
+ Source = * (UINT8 **) Source;
+ AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
+ break;
+
+ case ACPI_RSC_ADDRESS:
+
+ /* Set the Resource Type, General Flags, and Type-Specific Flags */
+
+ AcpiRsSetAddressCommon (Aml, Resource);
+ break;
+
+ case ACPI_RSC_SOURCEX:
+ /*
+ * Optional ResourceSource (Index and String)
+ */
+ AmlLength = AcpiRsSetResourceSource (
+ Aml, (ACPI_RS_LENGTH) AmlLength, Source);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_SOURCE:
+ /*
+ * Optional ResourceSource (Index and String). This is the more
+ * complicated case used by the Interrupt() macro
+ */
+ AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source);
+ AcpiRsSetResourceLength (AmlLength, Aml);
+ break;
+
+ case ACPI_RSC_BITMASK:
+ /*
+ * 8-bit encoded bitmask (DMA macro)
+ */
+ ACPI_SET8 (Destination,
+ AcpiRsEncodeBitmask (Source,
+ *ACPI_ADD_PTR (UINT8, Resource, Info->Value)));
+ break;
+
+ case ACPI_RSC_BITMASK16:
+ /*
+ * 16-bit encoded bitmask (IRQ macro)
+ */
+ Temp16 = AcpiRsEncodeBitmask (Source,
+ *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
+ ACPI_MOVE_16_TO_16 (Destination, &Temp16);
+ break;
+
+ case ACPI_RSC_EXIT_LE:
+ /*
+ * Control - Exit conversion if less than or equal
+ */
+ if (ItemCount <= Info->Value)
+ {
+ goto Exit;
+ }
+ break;
+
+ case ACPI_RSC_EXIT_NE:
+ /*
+ * Control - Exit conversion if not equal
+ */
+ switch (COMPARE_OPCODE (Info))
+ {
+ case ACPI_RSC_COMPARE_VALUE:
+
+ if (*ACPI_ADD_PTR (UINT8, Resource,
+ COMPARE_TARGET (Info)) != COMPARE_VALUE (Info))
+ {
+ goto Exit;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+ break;
+
+ case ACPI_RSC_EXIT_EQ:
+ /*
+ * Control - Exit conversion if equal
+ */
+ if (*ACPI_ADD_PTR (UINT8, Resource,
+ COMPARE_TARGET (Info)) == COMPARE_VALUE (Info))
+ {
+ goto Exit;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Count--;
+ Info++;
+ }
+
+Exit:
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+#if 0
+/* Previous resource validations */
+
+ if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
+ {
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
+ {
+ return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
+ }
+
+ if (((Aml->Irq.Flags & 0x09) == 0x00) ||
+ ((Aml->Irq.Flags & 0x09) == 0x09))
+ {
+ /*
+ * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
+ * polarity/trigger interrupts are allowed (ACPI spec, section
+ * "IRQ Format"), so 0x00 and 0x09 are illegal.
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Invalid interrupt polarity/trigger in resource list, 0x%X",
+ Aml->Irq.Flags));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+
+ Resource->Data.ExtendedIrq.InterruptCount = Temp8;
+ if (Temp8 < 1)
+ {
+ /* Must have at least one IRQ */
+
+ return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
+ if (Resource->Data.Dma.Transfer == 0x03)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid DMA.Transfer preference (3)"));
+ return_ACPI_STATUS (AE_BAD_DATA);
+ }
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsserial.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsserial.c
new file mode 100644
index 0000000000..00e18871c7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsserial.c
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ *
+ * Module Name: rsserial - GPIO/SerialBus resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsserial")
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertGpio
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertGpio[18] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GPIO,
+ ACPI_RS_SIZE (ACPI_RESOURCE_GPIO),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertGpio)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GPIO,
+ sizeof (AML_RESOURCE_GPIO),
+ 0},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * RevisionId
+ * ConnectionType
+ */
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Gpio.RevisionId),
+ AML_OFFSET (Gpio.RevisionId),
+ 2},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Gpio.ProducerConsumer),
+ AML_OFFSET (Gpio.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Gpio.Sharable),
+ AML_OFFSET (Gpio.IntFlags),
+ 3},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Gpio.WakeCapable),
+ AML_OFFSET (Gpio.IntFlags),
+ 4},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Gpio.IoRestriction),
+ AML_OFFSET (Gpio.IntFlags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Gpio.Triggering),
+ AML_OFFSET (Gpio.IntFlags),
+ 0},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Gpio.Polarity),
+ AML_OFFSET (Gpio.IntFlags),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Gpio.PinConfig),
+ AML_OFFSET (Gpio.PinConfig),
+ 1},
+
+ /*
+ * These fields are contiguous in both the source and destination:
+ * DriveStrength
+ * DebounceTimeout
+ */
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.Gpio.DriveStrength),
+ AML_OFFSET (Gpio.DriveStrength),
+ 2},
+
+ /* Pin Table */
+
+ {ACPI_RSC_COUNT_GPIO_PIN, ACPI_RS_OFFSET (Data.Gpio.PinTableLength),
+ AML_OFFSET (Gpio.PinTableOffset),
+ AML_OFFSET (Gpio.ResSourceOffset)},
+
+ {ACPI_RSC_MOVE_GPIO_PIN, ACPI_RS_OFFSET (Data.Gpio.PinTable),
+ AML_OFFSET (Gpio.PinTableOffset),
+ 0},
+
+ /* Resource Source */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.Gpio.ResourceSource.Index),
+ AML_OFFSET (Gpio.ResSourceIndex),
+ 1},
+
+ {ACPI_RSC_COUNT_GPIO_RES, ACPI_RS_OFFSET (Data.Gpio.ResourceSource.StringLength),
+ AML_OFFSET (Gpio.ResSourceOffset),
+ AML_OFFSET (Gpio.VendorOffset)},
+
+ {ACPI_RSC_MOVE_GPIO_RES, ACPI_RS_OFFSET (Data.Gpio.ResourceSource.StringPtr),
+ AML_OFFSET (Gpio.ResSourceOffset),
+ 0},
+
+ /* Vendor Data */
+
+ {ACPI_RSC_COUNT_GPIO_VEN, ACPI_RS_OFFSET (Data.Gpio.VendorLength),
+ AML_OFFSET (Gpio.VendorLength),
+ 1},
+
+ {ACPI_RSC_MOVE_GPIO_RES, ACPI_RS_OFFSET (Data.Gpio.VendorData),
+ AML_OFFSET (Gpio.VendorOffset),
+ 0},
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertI2cSerialBus
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertI2cSerialBus[16] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS,
+ ACPI_RS_SIZE (ACPI_RESOURCE_I2C_SERIALBUS),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertI2cSerialBus)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS),
+ 0},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.RevisionId),
+ AML_OFFSET (CommonSerialBus.RevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.Type),
+ AML_OFFSET (CommonSerialBus.Type),
+ 1},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.SlaveMode),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.ProducerConsumer),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeRevisionId),
+ AML_OFFSET (CommonSerialBus.TypeRevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeDataLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ 1},
+
+ /* Vendor data */
+
+ {ACPI_RSC_COUNT_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ AML_RESOURCE_I2C_MIN_DATA_LEN},
+
+ {ACPI_RSC_MOVE_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorData),
+ 0,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS)},
+
+ /* Resource Source */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.Index),
+ AML_OFFSET (CommonSerialBus.ResSourceIndex),
+ 1},
+
+ {ACPI_RSC_COUNT_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ {ACPI_RSC_MOVE_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringPtr),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ /* I2C bus type specific */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.I2cSerialBus.AccessMode),
+ AML_OFFSET (I2cSerialBus.TypeSpecificFlags),
+ 0},
+
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.I2cSerialBus.ConnectionSpeed),
+ AML_OFFSET (I2cSerialBus.ConnectionSpeed),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.I2cSerialBus.SlaveAddress),
+ AML_OFFSET (I2cSerialBus.SlaveAddress),
+ 1},
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertSpiSerialBus
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertSpiSerialBus[20] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS,
+ ACPI_RS_SIZE (ACPI_RESOURCE_SPI_SERIALBUS),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertSpiSerialBus)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS,
+ sizeof (AML_RESOURCE_SPI_SERIALBUS),
+ 0},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.RevisionId),
+ AML_OFFSET (CommonSerialBus.RevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.Type),
+ AML_OFFSET (CommonSerialBus.Type),
+ 1},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.SlaveMode),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.ProducerConsumer),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeRevisionId),
+ AML_OFFSET (CommonSerialBus.TypeRevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeDataLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ 1},
+
+ /* Vendor data */
+
+ {ACPI_RSC_COUNT_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ AML_RESOURCE_SPI_MIN_DATA_LEN},
+
+ {ACPI_RSC_MOVE_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorData),
+ 0,
+ sizeof (AML_RESOURCE_SPI_SERIALBUS)},
+
+ /* Resource Source */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.Index),
+ AML_OFFSET (CommonSerialBus.ResSourceIndex),
+ 1},
+
+ {ACPI_RSC_COUNT_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ {ACPI_RSC_MOVE_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringPtr),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ /* Spi bus type specific */
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.SpiSerialBus.WireMode),
+ AML_OFFSET (SpiSerialBus.TypeSpecificFlags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.SpiSerialBus.DevicePolarity),
+ AML_OFFSET (SpiSerialBus.TypeSpecificFlags),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.SpiSerialBus.DataBitLength),
+ AML_OFFSET (SpiSerialBus.DataBitLength),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.SpiSerialBus.ClockPhase),
+ AML_OFFSET (SpiSerialBus.ClockPhase),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.SpiSerialBus.ClockPolarity),
+ AML_OFFSET (SpiSerialBus.ClockPolarity),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.SpiSerialBus.DeviceSelection),
+ AML_OFFSET (SpiSerialBus.DeviceSelection),
+ 1},
+
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.SpiSerialBus.ConnectionSpeed),
+ AML_OFFSET (SpiSerialBus.ConnectionSpeed),
+ 1},
+};
+
+
+/*******************************************************************************
+ *
+ * AcpiRsConvertUartSerialBus
+ *
+ ******************************************************************************/
+
+ACPI_RSCONVERT_INFO AcpiRsConvertUartSerialBus[22] =
+{
+ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS,
+ ACPI_RS_SIZE (ACPI_RESOURCE_UART_SERIALBUS),
+ ACPI_RSC_TABLE_SIZE (AcpiRsConvertUartSerialBus)},
+
+ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS,
+ sizeof (AML_RESOURCE_UART_SERIALBUS),
+ 0},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.RevisionId),
+ AML_OFFSET (CommonSerialBus.RevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.Type),
+ AML_OFFSET (CommonSerialBus.Type),
+ 1},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.SlaveMode),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 0},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.CommonSerialBus.ProducerConsumer),
+ AML_OFFSET (CommonSerialBus.Flags),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeRevisionId),
+ AML_OFFSET (CommonSerialBus.TypeRevisionId),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.CommonSerialBus.TypeDataLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ 1},
+
+ /* Vendor data */
+
+ {ACPI_RSC_COUNT_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ AML_RESOURCE_UART_MIN_DATA_LEN},
+
+ {ACPI_RSC_MOVE_SERIAL_VEN, ACPI_RS_OFFSET (Data.CommonSerialBus.VendorData),
+ 0,
+ sizeof (AML_RESOURCE_UART_SERIALBUS)},
+
+ /* Resource Source */
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.Index),
+ AML_OFFSET (CommonSerialBus.ResSourceIndex),
+ 1},
+
+ {ACPI_RSC_COUNT_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringLength),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ {ACPI_RSC_MOVE_SERIAL_RES, ACPI_RS_OFFSET (Data.CommonSerialBus.ResourceSource.StringPtr),
+ AML_OFFSET (CommonSerialBus.TypeDataLength),
+ sizeof (AML_RESOURCE_COMMON_SERIALBUS)},
+
+ /* Uart bus type specific */
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.UartSerialBus.FlowControl),
+ AML_OFFSET (UartSerialBus.TypeSpecificFlags),
+ 0},
+
+ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.UartSerialBus.StopBits),
+ AML_OFFSET (UartSerialBus.TypeSpecificFlags),
+ 2},
+
+ {ACPI_RSC_3BITFLAG, ACPI_RS_OFFSET (Data.UartSerialBus.DataBits),
+ AML_OFFSET (UartSerialBus.TypeSpecificFlags),
+ 4},
+
+ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.UartSerialBus.Endian),
+ AML_OFFSET (UartSerialBus.TypeSpecificFlags),
+ 7},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.UartSerialBus.Parity),
+ AML_OFFSET (UartSerialBus.Parity),
+ 1},
+
+ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET (Data.UartSerialBus.LinesEnabled),
+ AML_OFFSET (UartSerialBus.LinesEnabled),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.UartSerialBus.RxFifoSize),
+ AML_OFFSET (UartSerialBus.RxFifoSize),
+ 1},
+
+ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET (Data.UartSerialBus.TxFifoSize),
+ AML_OFFSET (UartSerialBus.TxFifoSize),
+ 1},
+
+ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET (Data.UartSerialBus.DefaultBaudRate),
+ AML_OFFSET (UartSerialBus.DefaultBaudRate),
+ 1},
+};
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsutils.c
new file mode 100644
index 0000000000..1bab925a59
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsutils.c
@@ -0,0 +1,863 @@
+/*******************************************************************************
+ *
+ * Module Name: rsutils - Utilities for the resource manager
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsDecodeBitmask
+ *
+ * PARAMETERS: Mask - Bitmask to decode
+ * List - Where the converted list is returned
+ *
+ * RETURN: Count of bits set (length of list)
+ *
+ * DESCRIPTION: Convert a bit mask into a list of values
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiRsDecodeBitmask (
+ UINT16 Mask,
+ UINT8 *List)
+{
+ UINT8 i;
+ UINT8 BitCount;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Decode the mask bits */
+
+ for (i = 0, BitCount = 0; Mask; i++)
+ {
+ if (Mask & 0x0001)
+ {
+ List[BitCount] = i;
+ BitCount++;
+ }
+
+ Mask >>= 1;
+ }
+
+ return (BitCount);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsEncodeBitmask
+ *
+ * PARAMETERS: List - List of values to encode
+ * Count - Length of list
+ *
+ * RETURN: Encoded bitmask
+ *
+ * DESCRIPTION: Convert a list of values to an encoded bitmask
+ *
+ ******************************************************************************/
+
+UINT16
+AcpiRsEncodeBitmask (
+ UINT8 *List,
+ UINT8 Count)
+{
+ UINT32 i;
+ UINT16 Mask;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Encode the list into a single bitmask */
+
+ for (i = 0, Mask = 0; i < Count; i++)
+ {
+ Mask |= (0x1 << List[i]);
+ }
+
+ return (Mask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsMoveData
+ *
+ * PARAMETERS: Destination - Pointer to the destination descriptor
+ * Source - Pointer to the source descriptor
+ * ItemCount - How many items to move
+ * MoveType - Byte width
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
+ * alignment issues and endian issues if necessary, as configured
+ * via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
+ *
+ ******************************************************************************/
+
+void
+AcpiRsMoveData (
+ void *Destination,
+ void *Source,
+ UINT16 ItemCount,
+ UINT8 MoveType)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* One move per item */
+
+ for (i = 0; i < ItemCount; i++)
+ {
+ switch (MoveType)
+ {
+ /*
+ * For the 8-bit case, we can perform the move all at once
+ * since there are no alignment or endian issues
+ */
+ case ACPI_RSC_MOVE8:
+ case ACPI_RSC_MOVE_GPIO_RES:
+ case ACPI_RSC_MOVE_SERIAL_VEN:
+ case ACPI_RSC_MOVE_SERIAL_RES:
+
+ memcpy (Destination, Source, ItemCount);
+ return;
+
+ /*
+ * 16-, 32-, and 64-bit cases must use the move macros that perform
+ * endian conversion and/or accommodate hardware that cannot perform
+ * misaligned memory transfers
+ */
+ case ACPI_RSC_MOVE16:
+ case ACPI_RSC_MOVE_GPIO_PIN:
+
+ ACPI_MOVE_16_TO_16 (&ACPI_CAST_PTR (UINT16, Destination)[i],
+ &ACPI_CAST_PTR (UINT16, Source)[i]);
+ break;
+
+ case ACPI_RSC_MOVE32:
+
+ ACPI_MOVE_32_TO_32 (&ACPI_CAST_PTR (UINT32, Destination)[i],
+ &ACPI_CAST_PTR (UINT32, Source)[i]);
+ break;
+
+ case ACPI_RSC_MOVE64:
+
+ ACPI_MOVE_64_TO_64 (&ACPI_CAST_PTR (UINT64, Destination)[i],
+ &ACPI_CAST_PTR (UINT64, Source)[i]);
+ break;
+
+ default:
+
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsSetResourceLength
+ *
+ * PARAMETERS: TotalLength - Length of the AML descriptor, including
+ * the header and length fields.
+ * Aml - Pointer to the raw AML descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the ResourceLength field of an AML
+ * resource descriptor, both Large and Small descriptors are
+ * supported automatically. Note: Descriptor Type field must
+ * be valid.
+ *
+ ******************************************************************************/
+
+void
+AcpiRsSetResourceLength (
+ ACPI_RSDESC_SIZE TotalLength,
+ AML_RESOURCE *Aml)
+{
+ ACPI_RS_LENGTH ResourceLength;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Length is the total descriptor length minus the header length */
+
+ ResourceLength = (ACPI_RS_LENGTH)
+ (TotalLength - AcpiUtGetResourceHeaderLength (Aml));
+
+ /* Length is stored differently for large and small descriptors */
+
+ if (Aml->SmallHeader.DescriptorType & ACPI_RESOURCE_NAME_LARGE)
+ {
+ /* Large descriptor -- bytes 1-2 contain the 16-bit length */
+
+ ACPI_MOVE_16_TO_16 (&Aml->LargeHeader.ResourceLength, &ResourceLength);
+ }
+ else
+ {
+ /* Small descriptor -- bits 2:0 of byte 0 contain the length */
+
+ Aml->SmallHeader.DescriptorType = (UINT8)
+
+ /* Clear any existing length, preserving descriptor type bits */
+
+ ((Aml->SmallHeader.DescriptorType & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
+
+ | ResourceLength);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsSetResourceHeader
+ *
+ * PARAMETERS: DescriptorType - Byte to be inserted as the type
+ * TotalLength - Length of the AML descriptor, including
+ * the header and length fields.
+ * Aml - Pointer to the raw AML descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the DescriptorType and ResourceLength fields of an AML
+ * resource descriptor, both Large and Small descriptors are
+ * supported automatically
+ *
+ ******************************************************************************/
+
+void
+AcpiRsSetResourceHeader (
+ UINT8 DescriptorType,
+ ACPI_RSDESC_SIZE TotalLength,
+ AML_RESOURCE *Aml)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Set the Resource Type */
+
+ Aml->SmallHeader.DescriptorType = DescriptorType;
+
+ /* Set the Resource Length */
+
+ AcpiRsSetResourceLength (TotalLength, Aml);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsStrcpy
+ *
+ * PARAMETERS: Destination - Pointer to the destination string
+ * Source - Pointer to the source string
+ *
+ * RETURN: String length, including NULL terminator
+ *
+ * DESCRIPTION: Local string copy that returns the string length, saving a
+ * strcpy followed by a strlen.
+ *
+ ******************************************************************************/
+
+static UINT16
+AcpiRsStrcpy (
+ char *Destination,
+ char *Source)
+{
+ UINT16 i;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ for (i = 0; Source[i]; i++)
+ {
+ Destination[i] = Source[i];
+ }
+
+ Destination[i] = 0;
+
+ /* Return string length including the NULL terminator */
+
+ return ((UINT16) (i + 1));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetResourceSource
+ *
+ * PARAMETERS: ResourceLength - Length field of the descriptor
+ * MinimumLength - Minimum length of the descriptor (minus
+ * any optional fields)
+ * ResourceSource - Where the ResourceSource is returned
+ * Aml - Pointer to the raw AML descriptor
+ * StringPtr - (optional) where to store the actual
+ * ResourceSource string
+ *
+ * RETURN: Length of the string plus NULL terminator, rounded up to native
+ * word boundary
+ *
+ * DESCRIPTION: Copy the optional ResourceSource data from a raw AML descriptor
+ * to an internal resource descriptor
+ *
+ ******************************************************************************/
+
+ACPI_RS_LENGTH
+AcpiRsGetResourceSource (
+ ACPI_RS_LENGTH ResourceLength,
+ ACPI_RS_LENGTH MinimumLength,
+ ACPI_RESOURCE_SOURCE *ResourceSource,
+ AML_RESOURCE *Aml,
+ char *StringPtr)
+{
+ ACPI_RSDESC_SIZE TotalLength;
+ UINT8 *AmlResourceSource;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ TotalLength = ResourceLength + sizeof (AML_RESOURCE_LARGE_HEADER);
+ AmlResourceSource = ACPI_ADD_PTR (UINT8, Aml, MinimumLength);
+
+ /*
+ * ResourceSource is present if the length of the descriptor is longer than
+ * the minimum length.
+ *
+ * Note: Some resource descriptors will have an additional null, so
+ * we add 1 to the minimum length.
+ */
+ if (TotalLength > (ACPI_RSDESC_SIZE) (MinimumLength + 1))
+ {
+ /* Get the ResourceSourceIndex */
+
+ ResourceSource->Index = AmlResourceSource[0];
+
+ ResourceSource->StringPtr = StringPtr;
+ if (!StringPtr)
+ {
+ /*
+ * String destination pointer is not specified; Set the String
+ * pointer to the end of the current ResourceSource structure.
+ */
+ ResourceSource->StringPtr = ACPI_ADD_PTR (char, ResourceSource,
+ sizeof (ACPI_RESOURCE_SOURCE));
+ }
+
+ /*
+ * In order for the Resource length to be a multiple of the native
+ * word, calculate the length of the string (+1 for NULL terminator)
+ * and expand to the next word multiple.
+ *
+ * Zero the entire area of the buffer.
+ */
+ TotalLength = (UINT32) strlen (
+ ACPI_CAST_PTR (char, &AmlResourceSource[1])) + 1;
+ TotalLength = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (TotalLength);
+
+ memset (ResourceSource->StringPtr, 0, TotalLength);
+
+ /* Copy the ResourceSource string to the destination */
+
+ ResourceSource->StringLength = AcpiRsStrcpy (ResourceSource->StringPtr,
+ ACPI_CAST_PTR (char, &AmlResourceSource[1]));
+
+ return ((ACPI_RS_LENGTH) TotalLength);
+ }
+
+ /* ResourceSource is not present */
+
+ ResourceSource->Index = 0;
+ ResourceSource->StringLength = 0;
+ ResourceSource->StringPtr = NULL;
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsSetResourceSource
+ *
+ * PARAMETERS: Aml - Pointer to the raw AML descriptor
+ * MinimumLength - Minimum length of the descriptor (minus
+ * any optional fields)
+ * ResourceSource - Internal ResourceSource
+
+ *
+ * RETURN: Total length of the AML descriptor
+ *
+ * DESCRIPTION: Convert an optional ResourceSource from internal format to a
+ * raw AML resource descriptor
+ *
+ ******************************************************************************/
+
+ACPI_RSDESC_SIZE
+AcpiRsSetResourceSource (
+ AML_RESOURCE *Aml,
+ ACPI_RS_LENGTH MinimumLength,
+ ACPI_RESOURCE_SOURCE *ResourceSource)
+{
+ UINT8 *AmlResourceSource;
+ ACPI_RSDESC_SIZE DescriptorLength;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ DescriptorLength = MinimumLength;
+
+ /* Non-zero string length indicates presence of a ResourceSource */
+
+ if (ResourceSource->StringLength)
+ {
+ /* Point to the end of the AML descriptor */
+
+ AmlResourceSource = ACPI_ADD_PTR (UINT8, Aml, MinimumLength);
+
+ /* Copy the ResourceSourceIndex */
+
+ AmlResourceSource[0] = (UINT8) ResourceSource->Index;
+
+ /* Copy the ResourceSource string */
+
+ strcpy (ACPI_CAST_PTR (char, &AmlResourceSource[1]),
+ ResourceSource->StringPtr);
+
+ /*
+ * Add the length of the string (+ 1 for null terminator) to the
+ * final descriptor length
+ */
+ DescriptorLength += ((ACPI_RSDESC_SIZE) ResourceSource->StringLength + 1);
+ }
+
+ /* Return the new total length of the AML descriptor */
+
+ return (DescriptorLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetPrtMethodData
+ *
+ * PARAMETERS: Node - Device node
+ * RetBuffer - Pointer to a buffer structure for the
+ * results
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the _PRT value of an object
+ * contained in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetPrtMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsGetPrtMethodData);
+
+
+ /* Parameters guaranteed valid by caller */
+
+ /* Execute the method, no parameters */
+
+ Status = AcpiUtEvaluateObject (Node, METHOD_NAME__PRT,
+ ACPI_BTYPE_PACKAGE, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Create a resource linked list from the byte stream buffer that comes
+ * back from the _CRS method execution.
+ */
+ Status = AcpiRsCreatePciRoutingTable (ObjDesc, RetBuffer);
+
+ /* On exit, we must delete the object returned by EvaluateObject */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetCrsMethodData
+ *
+ * PARAMETERS: Node - Device node
+ * RetBuffer - Pointer to a buffer structure for the
+ * results
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the _CRS value of an object
+ * contained in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetCrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsGetCrsMethodData);
+
+
+ /* Parameters guaranteed valid by caller */
+
+ /* Execute the method, no parameters */
+
+ Status = AcpiUtEvaluateObject (Node, METHOD_NAME__CRS,
+ ACPI_BTYPE_BUFFER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Make the call to create a resource linked list from the
+ * byte stream buffer that comes back from the _CRS method
+ * execution.
+ */
+ Status = AcpiRsCreateResourceList (ObjDesc, RetBuffer);
+
+ /* On exit, we must delete the object returned by evaluateObject */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetPrsMethodData
+ *
+ * PARAMETERS: Node - Device node
+ * RetBuffer - Pointer to a buffer structure for the
+ * results
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the _PRS value of an object
+ * contained in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetPrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsGetPrsMethodData);
+
+
+ /* Parameters guaranteed valid by caller */
+
+ /* Execute the method, no parameters */
+
+ Status = AcpiUtEvaluateObject (Node, METHOD_NAME__PRS,
+ ACPI_BTYPE_BUFFER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Make the call to create a resource linked list from the
+ * byte stream buffer that comes back from the _CRS method
+ * execution.
+ */
+ Status = AcpiRsCreateResourceList (ObjDesc, RetBuffer);
+
+ /* On exit, we must delete the object returned by evaluateObject */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetAeiMethodData
+ *
+ * PARAMETERS: Node - Device node
+ * RetBuffer - Pointer to a buffer structure for the
+ * results
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the _AEI value of an object
+ * contained in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetAeiMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsGetAeiMethodData);
+
+
+ /* Parameters guaranteed valid by caller */
+
+ /* Execute the method, no parameters */
+
+ Status = AcpiUtEvaluateObject (Node, METHOD_NAME__AEI,
+ ACPI_BTYPE_BUFFER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Make the call to create a resource linked list from the
+ * byte stream buffer that comes back from the _CRS method
+ * execution.
+ */
+ Status = AcpiRsCreateResourceList (ObjDesc, RetBuffer);
+
+ /* On exit, we must delete the object returned by evaluateObject */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsGetMethodData
+ *
+ * PARAMETERS: Handle - Handle to the containing object
+ * Path - Path to method, relative to Handle
+ * RetBuffer - Pointer to a buffer structure for the
+ * results
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
+ * object contained in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsGetMethodData (
+ ACPI_HANDLE Handle,
+ char *Path,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (RsGetMethodData);
+
+
+ /* Parameters guaranteed valid by caller */
+
+ /* Execute the method, no parameters */
+
+ Status = AcpiUtEvaluateObject (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle),
+ Path, ACPI_BTYPE_BUFFER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Make the call to create a resource linked list from the
+ * byte stream buffer that comes back from the method
+ * execution.
+ */
+ Status = AcpiRsCreateResourceList (ObjDesc, RetBuffer);
+
+ /* On exit, we must delete the object returned by EvaluateObject */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsSetSrsMethodData
+ *
+ * PARAMETERS: Node - Device node
+ * InBuffer - Pointer to a buffer structure of the
+ * parameter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to set the _SRS of an object contained
+ * in an object specified by the handle passed in
+ *
+ * If the function fails an appropriate status will be returned
+ * and the contents of the callers buffer is undefined.
+ *
+ * Note: Parameters guaranteed valid by caller
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRsSetSrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *InBuffer)
+{
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_OPERAND_OBJECT *Args[2];
+ ACPI_STATUS Status;
+ ACPI_BUFFER Buffer;
+
+
+ ACPI_FUNCTION_TRACE (RsSetSrsMethodData);
+
+
+ /* Allocate and initialize the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Info->PrefixNode = Node;
+ Info->RelativePathname = METHOD_NAME__SRS;
+ Info->Parameters = Args;
+ Info->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ /*
+ * The InBuffer parameter will point to a linked list of
+ * resource parameters. It needs to be formatted into a
+ * byte stream to be sent in as an input parameter to _SRS
+ *
+ * Convert the linked list into a byte stream
+ */
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiRsCreateAmlResources (InBuffer, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Create and initialize the method parameter object */
+
+ Args[0] = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
+ if (!Args[0])
+ {
+ /*
+ * Must free the buffer allocated above (otherwise it is freed
+ * later)
+ */
+ ACPI_FREE (Buffer.Pointer);
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ Args[0]->Buffer.Length = (UINT32) Buffer.Length;
+ Args[0]->Buffer.Pointer = Buffer.Pointer;
+ Args[0]->Common.Flags = AOPOBJ_DATA_VALID;
+ Args[1] = NULL;
+
+ /* Execute the method, no return value is expected */
+
+ Status = AcpiNsEvaluate (Info);
+
+ /* Clean up and return the status from AcpiNsEvaluate */
+
+ AcpiUtRemoveReference (Args[0]);
+
+Cleanup:
+ ACPI_FREE (Info);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsxface.c
new file mode 100644
index 0000000000..66c26e1a9f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/resources/rsxface.c
@@ -0,0 +1,740 @@
+/*******************************************************************************
+ *
+ * Module Name: rsxface - Public interfaces to the resource manager
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_RESOURCES
+ ACPI_MODULE_NAME ("rsxface")
+
+/* Local macros for 16,32-bit to 64-bit conversion */
+
+#define ACPI_COPY_FIELD(Out, In, Field) ((Out)->Field = (In)->Field)
+#define ACPI_COPY_ADDRESS(Out, In) \
+ ACPI_COPY_FIELD(Out, In, ResourceType); \
+ ACPI_COPY_FIELD(Out, In, ProducerConsumer); \
+ ACPI_COPY_FIELD(Out, In, Decode); \
+ ACPI_COPY_FIELD(Out, In, MinAddressFixed); \
+ ACPI_COPY_FIELD(Out, In, MaxAddressFixed); \
+ ACPI_COPY_FIELD(Out, In, Info); \
+ ACPI_COPY_FIELD(Out, In, Address.Granularity); \
+ ACPI_COPY_FIELD(Out, In, Address.Minimum); \
+ ACPI_COPY_FIELD(Out, In, Address.Maximum); \
+ ACPI_COPY_FIELD(Out, In, Address.TranslationOffset); \
+ ACPI_COPY_FIELD(Out, In, Address.AddressLength); \
+ ACPI_COPY_FIELD(Out, In, ResourceSource);
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiRsMatchVendorResource (
+ ACPI_RESOURCE *Resource,
+ void *Context);
+
+static ACPI_STATUS
+AcpiRsValidateParameters (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *Buffer,
+ ACPI_NAMESPACE_NODE **ReturnNode);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsValidateParameters
+ *
+ * PARAMETERS: DeviceHandle - Handle to a device
+ * Buffer - Pointer to a data buffer
+ * ReturnNode - Pointer to where the device node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Common parameter validation for resource interfaces
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiRsValidateParameters (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *Buffer,
+ ACPI_NAMESPACE_NODE **ReturnNode)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (RsValidateParameters);
+
+
+ /*
+ * Must have a valid handle to an ACPI device
+ */
+ if (!DeviceHandle)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Node = AcpiNsValidateHandle (DeviceHandle);
+ if (!Node)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (Node->Type != ACPI_TYPE_DEVICE)
+ {
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /*
+ * Validate the user buffer object
+ *
+ * if there is a non-zero buffer length we also need a valid pointer in
+ * the buffer. If it's a zero buffer length, we'll be returning the
+ * needed buffer size (later), so keep going.
+ */
+ Status = AcpiUtValidateBuffer (Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ *ReturnNode = Node;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetIrqRoutingTable
+ *
+ * PARAMETERS: DeviceHandle - Handle to the Bus device we are querying
+ * RetBuffer - Pointer to a buffer to receive the
+ * current resources for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the IRQ routing table for a
+ * specific bus. The caller must first acquire a handle for the
+ * desired bus. The routine table is placed in the buffer pointed
+ * to by the RetBuffer variable parameter.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of RetBuffer is undefined.
+ *
+ * This function attempts to execute the _PRT method contained in
+ * the object indicated by the passed DeviceHandle.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetIrqRoutingTable (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
+
+
+ /* Validate parameters then dispatch to internal routine */
+
+ Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetCurrentResources
+ *
+ * PARAMETERS: DeviceHandle - Handle to the device object for the
+ * device we are querying
+ * RetBuffer - Pointer to a buffer to receive the
+ * current resources for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the current resources for a
+ * specific device. The caller must first acquire a handle for
+ * the desired device. The resource data is placed in the buffer
+ * pointed to by the RetBuffer variable parameter.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of RetBuffer is undefined.
+ *
+ * This function attempts to execute the _CRS method contained in
+ * the object indicated by the passed DeviceHandle.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetCurrentResources (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
+
+
+ /* Validate parameters then dispatch to internal routine */
+
+ Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetPossibleResources
+ *
+ * PARAMETERS: DeviceHandle - Handle to the device object for the
+ * device we are querying
+ * RetBuffer - Pointer to a buffer to receive the
+ * resources for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get a list of the possible resources
+ * for a specific device. The caller must first acquire a handle
+ * for the desired device. The resource data is placed in the
+ * buffer pointed to by the RetBuffer variable.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of RetBuffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetPossibleResources (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
+
+
+ /* Validate parameters then dispatch to internal routine */
+
+ Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetCurrentResources
+ *
+ * PARAMETERS: DeviceHandle - Handle to the device object for the
+ * device we are setting resources
+ * InBuffer - Pointer to a buffer containing the
+ * resources to be set for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to set the current resources for a
+ * specific device. The caller must first acquire a handle for
+ * the desired device. The resource data is passed to the routine
+ * the buffer pointed to by the InBuffer variable.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetCurrentResources (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *InBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
+
+
+ /* Validate the buffer, don't allow zero length */
+
+ if ((!InBuffer) ||
+ (!InBuffer->Pointer) ||
+ (!InBuffer->Length))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Validate parameters then dispatch to internal routine */
+
+ Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiRsSetSrsMethodData (Node, InBuffer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetEventResources
+ *
+ * PARAMETERS: DeviceHandle - Handle to the device object for the
+ * device we are getting resources
+ * InBuffer - Pointer to a buffer containing the
+ * resources to be set for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get the event resources for a
+ * specific device. The caller must first acquire a handle for
+ * the desired device. The resource data is passed to the routine
+ * the buffer pointed to by the InBuffer variable. Uses the
+ * _AEI method.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetEventResources (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetEventResources);
+
+
+ /* Validate parameters then dispatch to internal routine */
+
+ Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetEventResources)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiResourceToAddress64
+ *
+ * PARAMETERS: Resource - Pointer to a resource
+ * Out - Pointer to the users's return buffer
+ * (a struct acpi_resource_address64)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: If the resource is an address16, address32, or address64,
+ * copy it to the address64 return buffer. This saves the
+ * caller from having to duplicate code for different-sized
+ * addresses.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiResourceToAddress64 (
+ ACPI_RESOURCE *Resource,
+ ACPI_RESOURCE_ADDRESS64 *Out)
+{
+ ACPI_RESOURCE_ADDRESS16 *Address16;
+ ACPI_RESOURCE_ADDRESS32 *Address32;
+
+
+ if (!Resource || !Out)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Convert 16 or 32 address descriptor to 64 */
+
+ switch (Resource->Type)
+ {
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+
+ Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
+ ACPI_COPY_ADDRESS (Out, Address16);
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+
+ Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
+ ACPI_COPY_ADDRESS (Out, Address32);
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+
+ /* Simple copy for 64 bit source */
+
+ memcpy (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetVendorResource
+ *
+ * PARAMETERS: DeviceHandle - Handle for the parent device object
+ * Name - Method name for the parent resource
+ * (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ * Uuid - Pointer to the UUID to be matched.
+ * includes both subtype and 16-byte UUID
+ * RetBuffer - Where the vendor resource is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk a resource template for the specified device to find a
+ * vendor-defined resource that matches the supplied UUID and
+ * UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetVendorResource (
+ ACPI_HANDLE DeviceHandle,
+ char *Name,
+ ACPI_VENDOR_UUID *Uuid,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_VENDOR_WALK_INFO Info;
+ ACPI_STATUS Status;
+
+
+ /* Other parameters are validated by AcpiWalkResources */
+
+ if (!Uuid || !RetBuffer)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Info.Uuid = Uuid;
+ Info.Buffer = RetBuffer;
+ Info.Status = AE_NOT_EXIST;
+
+ /* Walk the _CRS or _PRS resource list for this device */
+
+ Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
+ &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ return (Info.Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRsMatchVendorResource
+ *
+ * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiRsMatchVendorResource (
+ ACPI_RESOURCE *Resource,
+ void *Context)
+{
+ ACPI_VENDOR_WALK_INFO *Info = Context;
+ ACPI_RESOURCE_VENDOR_TYPED *Vendor;
+ ACPI_BUFFER *Buffer;
+ ACPI_STATUS Status;
+
+
+ /* Ignore all descriptors except Vendor */
+
+ if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
+ {
+ return (AE_OK);
+ }
+
+ Vendor = &Resource->Data.VendorTyped;
+
+ /*
+ * For a valid match, these conditions must hold:
+ *
+ * 1) Length of descriptor data must be at least as long as a UUID struct
+ * 2) The UUID subtypes must match
+ * 3) The UUID data must match
+ */
+ if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
+ (Vendor->UuidSubtype != Info->Uuid->Subtype) ||
+ (memcmp (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
+ {
+ return (AE_OK);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Buffer = Info->Buffer;
+ Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Found the correct resource, copy and return it */
+
+ memcpy (Buffer->Pointer, Resource, Resource->Length);
+ Buffer->Length = Resource->Length;
+
+ /* Found the desired descriptor, terminate resource walk */
+
+ Info->Status = AE_OK;
+ return (AE_CTRL_TERMINATE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiWalkResourceBuffer
+ *
+ * PARAMETERS: Buffer - Formatted buffer returned by one of the
+ * various Get*Resource functions
+ * UserFunction - Called for each resource
+ * Context - Passed to UserFunction
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walks the input resource template. The UserFunction is called
+ * once for each resource in the list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiWalkResourceBuffer (
+ ACPI_BUFFER *Buffer,
+ ACPI_WALK_RESOURCE_CALLBACK UserFunction,
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_RESOURCE *Resource;
+ ACPI_RESOURCE *ResourceEnd;
+
+
+ ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
+
+
+ /* Parameter validation */
+
+ if (!Buffer || !Buffer->Pointer || !UserFunction)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Buffer contains the resource list and length */
+
+ Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
+ ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
+
+ /* Walk the resource list until the EndTag is found (or buffer end) */
+
+ while (Resource < ResourceEnd)
+ {
+ /* Sanity check the resource type */
+
+ if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
+ {
+ Status = AE_AML_INVALID_RESOURCE_TYPE;
+ break;
+ }
+
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!Resource->Length)
+ {
+ return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
+ /* Invoke the user function, abort on any error returned */
+
+ Status = UserFunction (Resource, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_TERMINATE)
+ {
+ /* This is an OK termination by the user function */
+
+ Status = AE_OK;
+ }
+ break;
+ }
+
+ /* EndTag indicates end-of-list */
+
+ if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
+ {
+ break;
+ }
+
+ /* Get the next resource descriptor */
+
+ Resource = ACPI_NEXT_RESOURCE (Resource);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiWalkResources
+ *
+ * PARAMETERS: DeviceHandle - Handle to the device object for the
+ * device we are querying
+ * Name - Method name of the resources we want.
+ * (METHOD_NAME__CRS, METHOD_NAME__PRS, or
+ * METHOD_NAME__AEI)
+ * UserFunction - Called for each resource
+ * Context - Passed to UserFunction
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieves the current or possible resource list for the
+ * specified device. The UserFunction is called once for
+ * each resource in the list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiWalkResources (
+ ACPI_HANDLE DeviceHandle,
+ char *Name,
+ ACPI_WALK_RESOURCE_CALLBACK UserFunction,
+ void *Context)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER Buffer;
+
+
+ ACPI_FUNCTION_TRACE (AcpiWalkResources);
+
+
+ /* Parameter validation */
+
+ if (!DeviceHandle || !UserFunction || !Name ||
+ (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
+ !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
+ !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the _CRS/_PRS/_AEI resource list */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Walk the resource list and cleanup */
+
+ Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
+ ACPI_FREE (Buffer.Pointer);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiWalkResources)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbdata.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbdata.c
new file mode 100644
index 0000000000..b44dec0db8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbdata.c
@@ -0,0 +1,868 @@
+/******************************************************************************
+ *
+ * Module Name: tbdata - Table manager data structure functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbdata")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInitTableDescriptor
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ * Address - Physical address of the table
+ * Flags - Allocation flags of the table
+ * Table - Pointer to the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a new table descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiTbInitTableDescriptor (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags,
+ ACPI_TABLE_HEADER *Table)
+{
+
+ /*
+ * Initialize the table descriptor. Set the pointer to NULL, since the
+ * table is not fully mapped at this time.
+ */
+ memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
+ TableDesc->Address = Address;
+ TableDesc->Length = Table->Length;
+ TableDesc->Flags = Flags;
+ ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbAcquireTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ * TablePtr - Where table is returned
+ * TableLength - Where table length is returned
+ * TableFlags - Where table allocation flags are returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
+ * maintained in the AcpiGbl_RootTableList.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbAcquireTable (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_TABLE_HEADER **TablePtr,
+ UINT32 *TableLength,
+ UINT8 *TableFlags)
+{
+ ACPI_TABLE_HEADER *Table = NULL;
+
+
+ switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+ Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+ Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
+ ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Table is not valid yet */
+
+ if (!Table)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Fill the return values */
+
+ *TablePtr = Table;
+ *TableLength = TableDesc->Length;
+ *TableFlags = TableDesc->Flags;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbReleaseTable
+ *
+ * PARAMETERS: Table - Pointer for the table
+ * TableLength - Length for the table
+ * TableFlags - Allocation flags for the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
+ *
+ ******************************************************************************/
+
+void
+AcpiTbReleaseTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 TableLength,
+ UINT8 TableFlags)
+{
+
+ switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+ AcpiOsUnmapMemory (Table, TableLength);
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+ default:
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbAcquireTempTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor to be acquired
+ * Address - Address of the table
+ * Flags - Allocation flags of the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function validates the table header to obtain the length
+ * of a table and fills the table descriptor to make its state as
+ * "INSTALLED". Such a table descriptor is only used for verified
+ * installation.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbAcquireTempTable (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags)
+{
+ ACPI_TABLE_HEADER *TableHeader;
+
+
+ switch (Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+ /* Get the length of the full table from the header */
+
+ TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
+ if (!TableHeader)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
+ AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
+ return (AE_OK);
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+ TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
+ ACPI_PHYSADDR_TO_PTR (Address));
+ if (!TableHeader)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
+ return (AE_OK);
+
+ default:
+
+ break;
+ }
+
+ /* Table is not valid yet */
+
+ return (AE_NO_MEMORY);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbReleaseTempTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor to be released
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
+ *
+ *****************************************************************************/
+
+void
+AcpiTbReleaseTempTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ /*
+ * Note that the .Address is maintained by the callers of
+ * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
+ * where .Address will be freed.
+ */
+ AcpiTbInvalidateTable (TableDesc);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiTbValidateTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to validate the table, the returned
+ * table descriptor is in "VALIDATED" state.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiTbValidateTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (TbValidateTable);
+
+
+ /* Validate the table if necessary */
+
+ if (!TableDesc->Pointer)
+ {
+ Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
+ &TableDesc->Length, &TableDesc->Flags);
+ if (!TableDesc->Pointer)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInvalidateTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
+ * AcpiTbValidateTable().
+ *
+ ******************************************************************************/
+
+void
+AcpiTbInvalidateTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ ACPI_FUNCTION_TRACE (TbInvalidateTable);
+
+
+ /* Table must be validated */
+
+ if (!TableDesc->Pointer)
+ {
+ return_VOID;
+ }
+
+ AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
+ TableDesc->Flags);
+ TableDesc->Pointer = NULL;
+
+ return_VOID;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiTbValidateTempTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to validate the table, the returned
+ * table descriptor is in "VALIDATED" state.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiTbValidateTempTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
+ {
+ /*
+ * Only validates the header of the table.
+ * Note that Length contains the size of the mapping after invoking
+ * this work around, this value is required by
+ * AcpiTbReleaseTempTable().
+ * We can do this because in AcpiInitTableDescriptor(), the Length
+ * field of the installed descriptor is filled with the actual
+ * table length obtaining from the table header.
+ */
+ TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
+ }
+
+ return (AcpiTbValidateTable (TableDesc));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiTbVerifyTempTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ * Signature - Table signature to verify
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to validate and verify the table, the
+ * returned table descriptor is in "VALIDATED" state.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiTbVerifyTempTable (
+ ACPI_TABLE_DESC *TableDesc,
+ char *Signature)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (TbVerifyTempTable);
+
+
+ /* Validate the table */
+
+ Status = AcpiTbValidateTempTable (TableDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* If a particular signature is expected (DSDT/FACS), it must match */
+
+ if (Signature &&
+ !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
+ {
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Invalid signature 0x%X for ACPI table, expected [%s]",
+ TableDesc->Signature.Integer, Signature));
+ Status = AE_BAD_SIGNATURE;
+ goto InvalidateAndExit;
+ }
+
+ /* Verify the checksum */
+
+ if (AcpiGbl_VerifyTableChecksum)
+ {
+ Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
+ "%4.4s 0x%8.8X%8.8X"
+ " Attempted table install failed",
+ AcpiUtValidAcpiName (TableDesc->Signature.Ascii) ?
+ TableDesc->Signature.Ascii : "????",
+ ACPI_FORMAT_UINT64 (TableDesc->Address)));
+ goto InvalidateAndExit;
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+
+InvalidateAndExit:
+ AcpiTbInvalidateTable (TableDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbResizeRootTableList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Expand the size of global table array
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbResizeRootTableList (
+ void)
+{
+ ACPI_TABLE_DESC *Tables;
+ UINT32 TableCount;
+
+
+ ACPI_FUNCTION_TRACE (TbResizeRootTableList);
+
+
+ /* AllowResize flag is a parameter to AcpiInitializeTables */
+
+ if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
+ {
+ ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ /* Increase the Table Array size */
+
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ TableCount = AcpiGbl_RootTableList.MaxTableCount;
+ }
+ else
+ {
+ TableCount = AcpiGbl_RootTableList.CurrentTableCount;
+ }
+
+ Tables = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof (ACPI_TABLE_DESC));
+ if (!Tables)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy and free the previous table array */
+
+ if (AcpiGbl_RootTableList.Tables)
+ {
+ memcpy (Tables, AcpiGbl_RootTableList.Tables,
+ (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
+
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ ACPI_FREE (AcpiGbl_RootTableList.Tables);
+ }
+ }
+
+ AcpiGbl_RootTableList.Tables = Tables;
+ AcpiGbl_RootTableList.MaxTableCount =
+ TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetNextTableDescriptor
+ *
+ * PARAMETERS: TableIndex - Where table index is returned
+ * TableDesc - Where table descriptor is returned
+ *
+ * RETURN: Status and table index/descriptor.
+ *
+ * DESCRIPTION: Allocate a new ACPI table entry to the global table list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbGetNextTableDescriptor (
+ UINT32 *TableIndex,
+ ACPI_TABLE_DESC **TableDesc)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /* Ensure that there is room for the table in the Root Table List */
+
+ if (AcpiGbl_RootTableList.CurrentTableCount >=
+ AcpiGbl_RootTableList.MaxTableCount)
+ {
+ Status = AcpiTbResizeRootTableList();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ i = AcpiGbl_RootTableList.CurrentTableCount;
+ AcpiGbl_RootTableList.CurrentTableCount++;
+
+ if (TableIndex)
+ {
+ *TableIndex = i;
+ }
+ if (TableDesc)
+ {
+ *TableDesc = &AcpiGbl_RootTableList.Tables[i];
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all internal ACPI tables
+ *
+ ******************************************************************************/
+
+void
+AcpiTbTerminate (
+ void)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (TbTerminate);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Delete the individual tables */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
+ }
+
+ /*
+ * Delete the root table array if allocated locally. Array cannot be
+ * mapped, so we don't need to check for that flag.
+ */
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ ACPI_FREE (AcpiGbl_RootTableList.Tables);
+ }
+
+ AcpiGbl_RootTableList.Tables = NULL;
+ AcpiGbl_RootTableList.Flags = 0;
+ AcpiGbl_RootTableList.CurrentTableCount = 0;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbDeleteNamespaceByOwner
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all namespace objects created when this table was loaded.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbDeleteNamespaceByOwner (
+ UINT32 TableIndex)
+{
+ ACPI_OWNER_ID OwnerId;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ /* The table index does not exist */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Get the owner ID for this table, used to delete namespace nodes */
+
+ OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Need to acquire the namespace writer lock to prevent interference
+ * with any concurrent namespace walks. The interpreter must be
+ * released during the deletion since the acquisition of the deletion
+ * lock may block, and also since the execution of a namespace walk
+ * must be allowed to use the interpreter.
+ */
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
+
+ AcpiNsDeleteNamespaceByOwner (OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbAllocateOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocates OwnerId in TableDesc
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbAllocateOwnerId (
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ Status = AcpiUtAllocateOwnerId (
+ &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbReleaseOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Releases OwnerId in TableDesc
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbReleaseOwnerId (
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ AcpiUtReleaseOwnerId (
+ &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
+ Status = AE_OK;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ * OwnerId - Where the table OwnerId is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: returns OwnerId for the ACPI table
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbGetOwnerId (
+ UINT32 TableIndex,
+ ACPI_OWNER_ID *OwnerId)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbGetOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
+ Status = AE_OK;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbIsTableLoaded
+ *
+ * PARAMETERS: TableIndex - Index into the root table
+ *
+ * RETURN: Table Loaded Flag
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiTbIsTableLoaded (
+ UINT32 TableIndex)
+{
+ BOOLEAN IsLoaded = FALSE;
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ IsLoaded = (BOOLEAN)
+ (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
+ ACPI_TABLE_IS_LOADED);
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return (IsLoaded);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbSetTableLoadedFlag
+ *
+ * PARAMETERS: TableIndex - Table index
+ * IsLoaded - TRUE if table is loaded, FALSE otherwise
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbSetTableLoadedFlag (
+ UINT32 TableIndex,
+ BOOLEAN IsLoaded)
+{
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ if (IsLoaded)
+ {
+ AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
+ ACPI_TABLE_IS_LOADED;
+ }
+ else
+ {
+ AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
+ ~ACPI_TABLE_IS_LOADED;
+ }
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfadt.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfadt.c
new file mode 100644
index 0000000000..f3b39ec1e6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfadt.c
@@ -0,0 +1,778 @@
+/******************************************************************************
+ *
+ * Module Name: tbfadt - FADT table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbfadt")
+
+/* Local prototypes */
+
+static void
+AcpiTbInitGenericAddress (
+ ACPI_GENERIC_ADDRESS *GenericAddress,
+ UINT8 SpaceId,
+ UINT8 ByteWidth,
+ UINT64 Address,
+ char *RegisterName,
+ UINT8 Flags);
+
+static void
+AcpiTbConvertFadt (
+ void);
+
+static void
+AcpiTbSetupFadtRegisters (
+ void);
+
+static UINT64
+AcpiTbSelectAddress (
+ char *RegisterName,
+ UINT32 Address32,
+ UINT64 Address64);
+
+
+/* Table for conversion of FADT to common internal format and FADT validation */
+
+typedef struct acpi_fadt_info
+{
+ char *Name;
+ UINT16 Address64;
+ UINT16 Address32;
+ UINT16 Length;
+ UINT8 DefaultLength;
+ UINT8 Flags;
+
+} ACPI_FADT_INFO;
+
+#define ACPI_FADT_OPTIONAL 0
+#define ACPI_FADT_REQUIRED 1
+#define ACPI_FADT_SEPARATE_LENGTH 2
+#define ACPI_FADT_GPE_REGISTER 4
+
+static ACPI_FADT_INFO FadtInfoTable[] =
+{
+ {"Pm1aEventBlock",
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ ACPI_FADT_OFFSET (Pm1aEventBlock),
+ ACPI_FADT_OFFSET (Pm1EventLength),
+ ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
+ ACPI_FADT_REQUIRED},
+
+ {"Pm1bEventBlock",
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ ACPI_FADT_OFFSET (Pm1bEventBlock),
+ ACPI_FADT_OFFSET (Pm1EventLength),
+ ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
+ ACPI_FADT_OPTIONAL},
+
+ {"Pm1aControlBlock",
+ ACPI_FADT_OFFSET (XPm1aControlBlock),
+ ACPI_FADT_OFFSET (Pm1aControlBlock),
+ ACPI_FADT_OFFSET (Pm1ControlLength),
+ ACPI_PM1_REGISTER_WIDTH,
+ ACPI_FADT_REQUIRED},
+
+ {"Pm1bControlBlock",
+ ACPI_FADT_OFFSET (XPm1bControlBlock),
+ ACPI_FADT_OFFSET (Pm1bControlBlock),
+ ACPI_FADT_OFFSET (Pm1ControlLength),
+ ACPI_PM1_REGISTER_WIDTH,
+ ACPI_FADT_OPTIONAL},
+
+ {"Pm2ControlBlock",
+ ACPI_FADT_OFFSET (XPm2ControlBlock),
+ ACPI_FADT_OFFSET (Pm2ControlBlock),
+ ACPI_FADT_OFFSET (Pm2ControlLength),
+ ACPI_PM2_REGISTER_WIDTH,
+ ACPI_FADT_SEPARATE_LENGTH},
+
+ {"PmTimerBlock",
+ ACPI_FADT_OFFSET (XPmTimerBlock),
+ ACPI_FADT_OFFSET (PmTimerBlock),
+ ACPI_FADT_OFFSET (PmTimerLength),
+ ACPI_PM_TIMER_WIDTH,
+ ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */
+
+ {"Gpe0Block",
+ ACPI_FADT_OFFSET (XGpe0Block),
+ ACPI_FADT_OFFSET (Gpe0Block),
+ ACPI_FADT_OFFSET (Gpe0BlockLength),
+ 0,
+ ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
+
+ {"Gpe1Block",
+ ACPI_FADT_OFFSET (XGpe1Block),
+ ACPI_FADT_OFFSET (Gpe1Block),
+ ACPI_FADT_OFFSET (Gpe1BlockLength),
+ 0,
+ ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
+};
+
+#define ACPI_FADT_INFO_ENTRIES \
+ (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
+
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info
+{
+ ACPI_GENERIC_ADDRESS *Target;
+ UINT16 Source;
+ UINT8 RegisterNum;
+
+} ACPI_FADT_PM_INFO;
+
+static ACPI_FADT_PM_INFO FadtPmInfoTable[] =
+{
+ {&AcpiGbl_XPm1aStatus,
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ 0},
+
+ {&AcpiGbl_XPm1aEnable,
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ 1},
+
+ {&AcpiGbl_XPm1bStatus,
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ 0},
+
+ {&AcpiGbl_XPm1bEnable,
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+ (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInitGenericAddress
+ *
+ * PARAMETERS: GenericAddress - GAS struct to be initialized
+ * SpaceId - ACPI Space ID for this register
+ * ByteWidth - Width of this register
+ * Address - Address of the register
+ * RegisterName - ASCII name of the ACPI register
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a Generic Address Structure (GAS)
+ * See the ACPI specification for a full description and
+ * definition of this structure.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbInitGenericAddress (
+ ACPI_GENERIC_ADDRESS *GenericAddress,
+ UINT8 SpaceId,
+ UINT8 ByteWidth,
+ UINT64 Address,
+ char *RegisterName,
+ UINT8 Flags)
+{
+ UINT8 BitWidth;
+
+
+ /*
+ * Bit width field in the GAS is only one byte long, 255 max.
+ * Check for BitWidth overflow in GAS.
+ */
+ BitWidth = (UINT8) (ByteWidth * 8);
+ if (ByteWidth > 31) /* (31*8)=248, (32*8)=256 */
+ {
+ /*
+ * No error for GPE blocks, because we do not use the BitWidth
+ * for GPEs, the legacy length (ByteWidth) is used instead to
+ * allow for a large number of GPEs.
+ */
+ if (!(Flags & ACPI_FADT_GPE_REGISTER))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
+ "to convert to GAS struct - 255 bits max, truncating",
+ RegisterName, ByteWidth, (ByteWidth * 8)));
+ }
+
+ BitWidth = 255;
+ }
+
+ /*
+ * The 64-bit Address field is non-aligned in the byte packed
+ * GAS struct.
+ */
+ ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
+
+ /* All other fields are byte-wide */
+
+ GenericAddress->SpaceId = SpaceId;
+ GenericAddress->BitWidth = BitWidth;
+ GenericAddress->BitOffset = 0;
+ GenericAddress->AccessWidth = 0; /* Access width ANY */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbSelectAddress
+ *
+ * PARAMETERS: RegisterName - ASCII name of the ACPI register
+ * Address32 - 32-bit address of the register
+ * Address64 - 64-bit address of the register
+ *
+ * RETURN: The resolved 64-bit address
+ *
+ * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
+ * the FADT. Used for the FACS and DSDT addresses.
+ *
+ * NOTES:
+ *
+ * Check for FACS and DSDT address mismatches. An address mismatch between
+ * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+ * DSDT/X_DSDT) could be a corrupted address field or it might indicate
+ * the presence of two FACS or two DSDT tables.
+ *
+ * November 2013:
+ * By default, as per the ACPICA specification, a valid 64-bit address is
+ * used regardless of the value of the 32-bit address. However, this
+ * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.
+ *
+ ******************************************************************************/
+
+static UINT64
+AcpiTbSelectAddress (
+ char *RegisterName,
+ UINT32 Address32,
+ UINT64 Address64)
+{
+
+ if (!Address64)
+ {
+ /* 64-bit address is zero, use 32-bit address */
+
+ return ((UINT64) Address32);
+ }
+
+ if (Address32 &&
+ (Address64 != (UINT64) Address32))
+ {
+ /* Address mismatch between 32-bit and 64-bit versions */
+
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X %s address mismatch in FADT: "
+ "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+ RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),
+ AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
+
+ /* 32-bit address override */
+
+ if (AcpiGbl_Use32BitFadtAddresses)
+ {
+ return ((UINT64) Address32);
+ }
+ }
+
+ /* Default is to use the 64-bit address */
+
+ return (Address64);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbParseFadt
+ *
+ * PARAMETERS: TableIndex - Index for the FADT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
+ * (FADT contains the addresses of the DSDT and FACS)
+ *
+ ******************************************************************************/
+
+void
+AcpiTbParseFadt (
+ UINT32 TableIndex)
+{
+ UINT32 Length;
+ ACPI_TABLE_HEADER *Table;
+
+
+ /*
+ * The FADT has multiple versions with different lengths,
+ * and it contains pointers to both the DSDT and FACS tables.
+ *
+ * Get a local copy of the FADT and convert it to a common format
+ * Map entire FADT, assumed to be smaller than one page.
+ */
+ Length = AcpiGbl_RootTableList.Tables[TableIndex].Length;
+
+ Table = AcpiOsMapMemory (
+ AcpiGbl_RootTableList.Tables[TableIndex].Address, Length);
+ if (!Table)
+ {
+ return;
+ }
+
+ /*
+ * Validate the FADT checksum before we copy the table. Ignore
+ * checksum error as we want to try to get the DSDT and FACS.
+ */
+ (void) AcpiTbVerifyChecksum (Table, Length);
+
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
+
+ AcpiTbCreateLocalFadt (Table, Length);
+
+ /* All done with the real FADT, unmap it */
+
+ AcpiOsUnmapMemory (Table, Length);
+
+ /* Obtain the DSDT and FACS tables via their addresses within the FADT */
+
+ AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
+ ACPI_SIG_DSDT, &AcpiGbl_DsdtIndex);
+
+ /* If Hardware Reduced flag is set, there is no FACS */
+
+ if (!AcpiGbl_ReducedHardware)
+ {
+ if (AcpiGbl_FADT.Facs)
+ {
+ AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,
+ ACPI_SIG_FACS, &AcpiGbl_FacsIndex);
+ }
+ if (AcpiGbl_FADT.XFacs)
+ {
+ AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
+ ACPI_SIG_FACS, &AcpiGbl_XFacsIndex);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCreateLocalFadt
+ *
+ * PARAMETERS: Table - Pointer to BIOS FADT
+ * Length - Length of the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
+ * Performs validation on some important FADT fields.
+ *
+ * NOTE: We create a local copy of the FADT regardless of the version.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbCreateLocalFadt (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length)
+{
+
+ /*
+ * Check if the FADT is larger than the largest table that we expect
+ * (the ACPI 5.0 version). If so, truncate the table, and issue
+ * a warning.
+ */
+ if (Length > sizeof (ACPI_TABLE_FADT))
+ {
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "FADT (revision %u) is longer than ACPI 5.0 version, "
+ "truncating length %u to %u",
+ Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
+ }
+
+ /* Clear the entire local FADT */
+
+ memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
+
+ /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
+
+ memcpy (&AcpiGbl_FADT, Table,
+ ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
+
+ /* Take a copy of the Hardware Reduced flag */
+
+ AcpiGbl_ReducedHardware = FALSE;
+ if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
+ {
+ AcpiGbl_ReducedHardware = TRUE;
+ }
+
+ /* Convert the local copy of the FADT to the common internal format */
+
+ AcpiTbConvertFadt ();
+
+ /* Initialize the global ACPI register structures */
+
+ AcpiTbSetupFadtRegisters ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbConvertFadt
+ *
+ * PARAMETERS: None - AcpiGbl_FADT is used.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Converts all versions of the FADT to a common internal format.
+ * Expand 32-bit addresses to 64-bit as necessary. Also validate
+ * important fields within the FADT.
+ *
+ * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
+ * contain a copy of the actual BIOS-provided FADT.
+ *
+ * Notes on 64-bit register addresses:
+ *
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
+ *
+ * The 64-bit X fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
+ * originally zero.
+ *
+ * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
+ * fields are expanded to the corresponding 64-bit X fields in the internal
+ * common FADT.
+ *
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields, if the 64-bit field is originally
+ * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
+ * field if the 64-bit field is valid, regardless of whether the host OS is
+ * 32-bit or 64-bit.
+ *
+ * Possible additional checks:
+ * (AcpiGbl_FADT.Pm1EventLength >= 4)
+ * (AcpiGbl_FADT.Pm1ControlLength >= 2)
+ * (AcpiGbl_FADT.PmTimerLength >= 4)
+ * Gpe block lengths must be multiple of 2
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbConvertFadt (
+ void)
+{
+ char *Name;
+ ACPI_GENERIC_ADDRESS *Address64;
+ UINT32 Address32;
+ UINT8 Length;
+ UINT8 Flags;
+ UINT32 i;
+
+
+ /*
+ * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
+ * should be zero are indeed zero. This will workaround BIOSs that
+ * inadvertently place values in these fields.
+ *
+ * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
+ * at offset 45, 55, 95, and the word located at offset 109, 110.
+ *
+ * Note: The FADT revision value is unreliable. Only the length can be
+ * trusted.
+ */
+ if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
+ {
+ AcpiGbl_FADT.PreferredProfile = 0;
+ AcpiGbl_FADT.PstateControl = 0;
+ AcpiGbl_FADT.CstControl = 0;
+ AcpiGbl_FADT.BootFlags = 0;
+ }
+
+ /*
+ * Now we can update the local FADT length to the length of the
+ * current FADT version as defined by the ACPI specification.
+ * Thus, we will have a common FADT internally.
+ */
+ AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
+
+ /*
+ * Expand the 32-bit DSDT addresses to 64-bit as necessary.
+ * Later ACPICA code will always use the X 64-bit field.
+ */
+ AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
+ AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
+
+ /* If Hardware Reduced flag is set, we are all done */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return;
+ }
+
+ /* Examine all of the 64-bit extended address fields (X fields) */
+
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
+ {
+ /*
+ * Get the 32-bit and 64-bit addresses, as well as the register
+ * length and register name.
+ */
+ Address32 = *ACPI_ADD_PTR (UINT32,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address32);
+
+ Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address64);
+
+ Length = *ACPI_ADD_PTR (UINT8,
+ &AcpiGbl_FADT, FadtInfoTable[i].Length);
+
+ Name = FadtInfoTable[i].Name;
+ Flags = FadtInfoTable[i].Flags;
+
+ /*
+ * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
+ * generic address structures as necessary. Later code will always use
+ * the 64-bit address structures.
+ *
+ * November 2013:
+ * Now always use the 64-bit address if it is valid (non-zero), in
+ * accordance with the ACPI specification which states that a 64-bit
+ * address supersedes the 32-bit version. This behavior can be
+ * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
+ *
+ * During 64-bit address construction and verification,
+ * these cases are handled:
+ *
+ * Address32 zero, Address64 [don't care] - Use Address64
+ *
+ * Address32 non-zero, Address64 zero - Copy/use Address32
+ * Address32 non-zero == Address64 non-zero - Use Address64
+ * Address32 non-zero != Address64 non-zero - Warning, use Address64
+ *
+ * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
+ * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
+ *
+ * Note: SpaceId is always I/O for 32-bit legacy address fields
+ */
+ if (Address32)
+ {
+ if (!Address64->Address)
+ {
+ /* 64-bit address is zero, use 32-bit address */
+
+ AcpiTbInitGenericAddress (Address64,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
+ FadtInfoTable[i].Length),
+ (UINT64) Address32, Name, Flags);
+ }
+ else if (Address64->Address != (UINT64) Address32)
+ {
+ /* Address mismatch */
+
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X address mismatch in FADT/%s: "
+ "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+ Name, Address32,
+ ACPI_FORMAT_UINT64 (Address64->Address),
+ AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
+
+ if (AcpiGbl_Use32BitFadtAddresses)
+ {
+ /* 32-bit address override */
+
+ AcpiTbInitGenericAddress (Address64,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
+ FadtInfoTable[i].Length),
+ (UINT64) Address32, Name, Flags);
+ }
+ }
+ }
+
+ /*
+ * For each extended field, check for length mismatch between the
+ * legacy length field and the corresponding 64-bit X length field.
+ * Note: If the legacy length field is > 0xFF bits, ignore this
+ * check. (GPE registers can be larger than the 64-bit GAS structure
+ * can accomodate, 0xFF bits).
+ */
+ if (Address64->Address &&
+ (ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
+ (Address64->BitWidth != ACPI_MUL_8 (Length)))
+ {
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X length mismatch in FADT/%s: %u/%u",
+ Name, ACPI_MUL_8 (Length), Address64->BitWidth));
+ }
+
+ if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
+ {
+ /*
+ * Field is required (PM1aEvent, PM1aControl).
+ * Both the address and length must be non-zero.
+ */
+ if (!Address64->Address || !Length)
+ {
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Required FADT field %s has zero address and/or length: "
+ "0x%8.8X%8.8X/0x%X",
+ Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
+ }
+ }
+ else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
+ {
+ /*
+ * Field is optional (PM2Control, GPE0, GPE1) AND has its own
+ * length field. If present, both the address and length must
+ * be valid.
+ */
+ if ((Address64->Address && !Length) ||
+ (!Address64->Address && Length))
+ {
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Optional FADT field %s has zero address or length: "
+ "0x%8.8X%8.8X/0x%X",
+ Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
+ }
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbSetupFadtRegisters
+ *
+ * PARAMETERS: None, uses AcpiGbl_FADT.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ * force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbSetupFadtRegisters (
+ void)
+{
+ ACPI_GENERIC_ADDRESS *Target64;
+ ACPI_GENERIC_ADDRESS *Source64;
+ UINT8 Pm1RegisterByteWidth;
+ UINT32 i;
+
+
+ /*
+ * Optionally check all register lengths against the default values and
+ * update them if they are incorrect.
+ */
+ if (AcpiGbl_UseDefaultRegisterWidths)
+ {
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
+ {
+ Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
+ FadtInfoTable[i].Address64);
+
+ /*
+ * If a valid register (Address != 0) and the (DefaultLength > 0)
+ * (Not a GPE register), then check the width against the default.
+ */
+ if ((Target64->Address) &&
+ (FadtInfoTable[i].DefaultLength > 0) &&
+ (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
+ {
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Invalid length for FADT/%s: %u, using default %u",
+ FadtInfoTable[i].Name, Target64->BitWidth,
+ FadtInfoTable[i].DefaultLength));
+
+ /* Incorrect size, set width to the default */
+
+ Target64->BitWidth = FadtInfoTable[i].DefaultLength;
+ }
+ }
+ }
+
+ /*
+ * Get the length of the individual PM1 registers (enable and status).
+ * Each register is defined to be (event block length / 2). Extra divide
+ * by 8 converts bits to bytes.
+ */
+ Pm1RegisterByteWidth = (UINT8)
+ ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
+
+ /*
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+ * registers. These addresses do not appear (directly) in the FADT, so it
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
+ *
+ * The PM event blocks are split into two register blocks, first is the
+ * PM Status Register block, followed immediately by the PM Enable
+ * Register block. Each is of length (Pm1EventLength/2)
+ *
+ * Note: The PM1A event block is required by the ACPI specification.
+ * However, the PM1B event block is optional and is rarely, if ever,
+ * used.
+ */
+
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
+ {
+ Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
+ FadtPmInfoTable[i].Source);
+
+ if (Source64->Address)
+ {
+ AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
+ Source64->SpaceId, Pm1RegisterByteWidth,
+ Source64->Address +
+ (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
+ "PmRegisters", 0);
+ }
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfind.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfind.c
new file mode 100644
index 0000000000..eff0167c19
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbfind.c
@@ -0,0 +1,156 @@
+/******************************************************************************
+ *
+ * Module Name: tbfind - find table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbfind")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbFindTable
+ *
+ * PARAMETERS: Signature - String with ACPI table signature
+ * OemId - String with the table OEM ID
+ * OemTableId - String with the OEM Table ID
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status and table index
+ *
+ * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
+ * Signature, OEM ID and OEM Table ID. Returns an index that can
+ * be used to get the table header or entire table.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbFindTable (
+ char *Signature,
+ char *OemId,
+ char *OemTableId,
+ UINT32 *TableIndex)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER Header;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (TbFindTable);
+
+
+ /* Validate the input table signature */
+
+ if (!AcpiIsValidSignature (Signature))
+ {
+ return_ACPI_STATUS (AE_BAD_SIGNATURE);
+ }
+
+ /* Don't allow the OEM strings to be too long */
+
+ if ((strlen (OemId) > ACPI_OEM_ID_SIZE) ||
+ (strlen (OemTableId) > ACPI_OEM_TABLE_ID_SIZE))
+ {
+ return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+ }
+
+ /* Normalize the input strings */
+
+ memset (&Header, 0, sizeof (ACPI_TABLE_HEADER));
+ ACPI_MOVE_NAME (Header.Signature, Signature);
+ strncpy (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
+ strncpy (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);
+
+ /* Search for the table */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if (memcmp (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Header.Signature, ACPI_NAME_SIZE))
+ {
+ /* Not the requested table */
+
+ continue;
+ }
+
+ /* Table with matching signature has been found */
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ /* Table is not currently mapped, map it */
+
+ Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ continue;
+ }
+ }
+
+ /* Check for table match on all IDs */
+
+ if (!memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
+ Header.Signature, ACPI_NAME_SIZE) &&
+ (!OemId[0] ||
+ !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
+ Header.OemId, ACPI_OEM_ID_SIZE)) &&
+ (!OemTableId[0] ||
+ !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
+ Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
+ {
+ *TableIndex = i;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+ Header.Signature));
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbinstal.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbinstal.c
new file mode 100644
index 0000000000..9484906a10
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbinstal.c
@@ -0,0 +1,525 @@
+/******************************************************************************
+ *
+ * Module Name: tbinstal - ACPI table installation and removal
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbinstal")
+
+/* Local prototypes */
+
+static BOOLEAN
+AcpiTbCompareTables (
+ ACPI_TABLE_DESC *TableDesc,
+ UINT32 TableIndex);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCompareTables
+ *
+ * PARAMETERS: TableDesc - Table 1 descriptor to be compared
+ * TableIndex - Index of table 2 to be compared
+ *
+ * RETURN: TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ * already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiTbCompareTables (
+ ACPI_TABLE_DESC *TableDesc,
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_OK;
+ BOOLEAN IsIdentical;
+ ACPI_TABLE_HEADER *Table;
+ UINT32 TableLength;
+ UINT8 TableFlags;
+
+
+ Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
+ &Table, &TableLength, &TableFlags);
+ if (ACPI_FAILURE (Status))
+ {
+ return (FALSE);
+ }
+
+ /*
+ * Check for a table match on the entire table length,
+ * not just the header.
+ */
+ IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
+ memcmp (TableDesc->Pointer, Table, TableLength)) ?
+ FALSE : TRUE);
+
+ /* Release the acquired table */
+
+ AcpiTbReleaseTable (Table, TableLength, TableFlags);
+ return (IsIdentical);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInstallTableWithOverride
+ *
+ * PARAMETERS: NewTableDesc - New table descriptor to install
+ * Override - Whether override should be performed
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ * table override mechanism is called to allow the host
+ * OS to replace any table before it is installed in the root
+ * table array.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbInstallTableWithOverride (
+ ACPI_TABLE_DESC *NewTableDesc,
+ BOOLEAN Override,
+ UINT32 *TableIndex)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiTbGetNextTableDescriptor (&i, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /*
+ * ACPI Table Override:
+ *
+ * Before we install the table, let the host OS override it with a new
+ * one if desired. Any table within the RSDT/XSDT can be replaced,
+ * including the DSDT which is pointed to by the FADT.
+ */
+ if (Override)
+ {
+ AcpiTbOverrideTable (NewTableDesc);
+ }
+
+ AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[i],
+ NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer);
+
+ AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer);
+
+ /* This synchronizes AcpiGbl_DsdtIndex */
+
+ *TableIndex = i;
+
+ /* Set the global integer width (based upon revision of the DSDT) */
+
+ if (i == AcpiGbl_DsdtIndex)
+ {
+ AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInstallFixedTable
+ *
+ * PARAMETERS: Address - Physical address of DSDT or FACS
+ * Signature - Table signature, NULL if no need to
+ * match
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
+ * structure.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbInstallFixedTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ char *Signature,
+ UINT32 *TableIndex)
+{
+ ACPI_TABLE_DESC NewTableDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (TbInstallFixedTable);
+
+
+ if (!Address)
+ {
+ ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]",
+ Signature));
+ return (AE_NO_MEMORY);
+ }
+
+ /* Fill a table descriptor for validation */
+
+ Status = AcpiTbAcquireTempTable (&NewTableDesc, Address,
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Address)));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Validate and verify a table before installation */
+
+ Status = AcpiTbVerifyTempTable (&NewTableDesc, Signature);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ReleaseAndExit;
+ }
+
+ /* Add the table to the global root table list */
+
+ AcpiTbInstallTableWithOverride (&NewTableDesc, TRUE, TableIndex);
+
+ReleaseAndExit:
+
+ /* Release the temporary table descriptor */
+
+ AcpiTbReleaseTempTable (&NewTableDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInstallStandardTable
+ *
+ * PARAMETERS: Address - Address of the table (might be a virtual
+ * address depending on the TableFlags)
+ * Flags - Flags for the table
+ * Reload - Whether reload should be performed
+ * Override - Whether override should be performed
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to install an ACPI table that is
+ * neither DSDT nor FACS (a "standard" table.)
+ * When this function is called by "Load" or "LoadTable" opcodes,
+ * or by AcpiLoadTable() API, the "Reload" parameter is set.
+ * After sucessfully returning from this function, table is
+ * "INSTALLED" but not "VALIDATED".
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbInstallStandardTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags,
+ BOOLEAN Reload,
+ BOOLEAN Override,
+ UINT32 *TableIndex)
+{
+ UINT32 i;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_TABLE_DESC NewTableDesc;
+
+
+ ACPI_FUNCTION_TRACE (TbInstallStandardTable);
+
+
+ /* Acquire a temporary table descriptor for validation */
+
+ Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Address)));
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Optionally do not load any SSDTs from the RSDT/XSDT. This can
+ * be useful for debugging ACPI problems on some machines.
+ */
+ if (!Reload &&
+ AcpiGbl_DisableSsdtTableInstall &&
+ ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT))
+ {
+ ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %8.8X%8.8X",
+ NewTableDesc.Signature.Ascii, ACPI_FORMAT_UINT64 (Address)));
+ goto ReleaseAndExit;
+ }
+
+ /* Validate and verify a table before installation */
+
+ Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ReleaseAndExit;
+ }
+
+ if (Reload)
+ {
+ /*
+ * Validate the incoming table signature.
+ *
+ * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
+ * 2) We added support for OEMx tables, signature "OEM".
+ * 3) Valid tables were encountered with a null signature, so we just
+ * gave up on validating the signature, (05/2008).
+ * 4) We encountered non-AML tables such as the MADT, which caused
+ * interpreter errors and kernel faults. So now, we once again allow
+ * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
+ */
+ if ((NewTableDesc.Signature.Ascii[0] != 0x00) &&
+ (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) &&
+ (strncmp (NewTableDesc.Signature.Ascii, "OEM", 3)))
+ {
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Table has invalid signature [%4.4s] (0x%8.8X), "
+ "must be SSDT or OEMx",
+ AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ?
+ NewTableDesc.Signature.Ascii : "????",
+ NewTableDesc.Signature.Integer));
+
+ Status = AE_BAD_SIGNATURE;
+ goto ReleaseAndExit;
+ }
+
+ /* Check if table is already registered */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ /*
+ * Check for a table match on the entire table length,
+ * not just the header.
+ */
+ if (!AcpiTbCompareTables (&NewTableDesc, i))
+ {
+ continue;
+ }
+
+ /*
+ * Note: the current mechanism does not unregister a table if it is
+ * dynamically unloaded. The related namespace entries are deleted,
+ * but the table remains in the root table list.
+ *
+ * The assumption here is that the number of different tables that
+ * will be loaded is actually small, and there is minimal overhead
+ * in just keeping the table in case it is needed again.
+ *
+ * If this assumption changes in the future (perhaps on large
+ * machines with many table load/unload operations), tables will
+ * need to be unregistered when they are unloaded, and slots in the
+ * root table list should be reused when empty.
+ */
+ if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
+ {
+ /* Table is still loaded, this is an error */
+
+ Status = AE_ALREADY_EXISTS;
+ goto ReleaseAndExit;
+ }
+ else
+ {
+ /*
+ * Table was unloaded, allow it to be reloaded.
+ * As we are going to return AE_OK to the caller, we should
+ * take the responsibility of freeing the input descriptor.
+ * Refill the input descriptor to ensure
+ * AcpiTbInstallTableWithOverride() can be called again to
+ * indicate the re-installation.
+ */
+ AcpiTbUninstallTable (&NewTableDesc);
+ *TableIndex = i;
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+ }
+
+ /* Add the table to the global root table list */
+
+ AcpiTbInstallTableWithOverride (&NewTableDesc, Override, TableIndex);
+
+ReleaseAndExit:
+
+ /* Release the temporary table descriptor */
+
+ AcpiTbReleaseTempTable (&NewTableDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbOverrideTable
+ *
+ * PARAMETERS: OldTableDesc - Validated table descriptor to be
+ * overridden
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Attempt table override by calling the OSL override functions.
+ * Note: If the table is overridden, then the entire new table
+ * is acquired and returned by this function.
+ * Before/after invocation, the table descriptor is in a state
+ * that is "VALIDATED".
+ *
+ ******************************************************************************/
+
+void
+AcpiTbOverrideTable (
+ ACPI_TABLE_DESC *OldTableDesc)
+{
+ ACPI_STATUS Status;
+ char *OverrideType;
+ ACPI_TABLE_DESC NewTableDesc;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 Length;
+
+
+ /* (1) Attempt logical override (returns a logical address) */
+
+ Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table);
+ if (ACPI_SUCCESS (Status) && Table)
+ {
+ AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table),
+ ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
+ OverrideType = "Logical";
+ goto FinishOverride;
+ }
+
+ /* (2) Attempt physical override (returns a physical address) */
+
+ Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer,
+ &Address, &Length);
+ if (ACPI_SUCCESS (Status) && Address && Length)
+ {
+ AcpiTbAcquireTempTable (&NewTableDesc, Address,
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
+ OverrideType = "Physical";
+ goto FinishOverride;
+ }
+
+ return; /* There was no override */
+
+
+FinishOverride:
+
+ /* Validate and verify a table before overriding */
+
+ Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ ACPI_INFO ((AE_INFO, "%4.4s 0x%8.8X%8.8X"
+ " %s table override, new table: 0x%8.8X%8.8X",
+ OldTableDesc->Signature.Ascii,
+ ACPI_FORMAT_UINT64 (OldTableDesc->Address),
+ OverrideType, ACPI_FORMAT_UINT64 (NewTableDesc.Address)));
+
+ /* We can now uninstall the original table */
+
+ AcpiTbUninstallTable (OldTableDesc);
+
+ /*
+ * Replace the original table descriptor and keep its state as
+ * "VALIDATED".
+ */
+ AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address,
+ NewTableDesc.Flags, NewTableDesc.Pointer);
+ AcpiTbValidateTempTable (OldTableDesc);
+
+ /* Release the temporary table descriptor */
+
+ AcpiTbReleaseTempTable (&NewTableDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbUninstallTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete one internal ACPI table
+ *
+ ******************************************************************************/
+
+void
+AcpiTbUninstallTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ ACPI_FUNCTION_TRACE (TbUninstallTable);
+
+
+ /* Table must be installed */
+
+ if (!TableDesc->Address)
+ {
+ return_VOID;
+ }
+
+ AcpiTbInvalidateTable (TableDesc);
+
+ if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
+ ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL)
+ {
+ ACPI_FREE (ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
+ }
+
+ TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL);
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbprint.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbprint.c
new file mode 100644
index 0000000000..f56d002a01
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbprint.c
@@ -0,0 +1,271 @@
+/******************************************************************************
+ *
+ * Module Name: tbprint - Table output utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/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 ((AE_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 ((AE_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 ((AE_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/boot/sys/contrib/dev/acpica/components/tables/tbutils.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbutils.c
new file mode 100644
index 0000000000..b57593305d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbutils.c
@@ -0,0 +1,477 @@
+/******************************************************************************
+ *
+ * Module Name: tbutils - ACPI Table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbutils")
+
+
+/* Local prototypes */
+
+static ACPI_PHYSICAL_ADDRESS
+AcpiTbGetRootTableEntry (
+ UINT8 *TableEntry,
+ UINT32 TableEntrySize);
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInitializeFacs
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
+ * for accessing the Global Lock and Firmware Waking Vector
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbInitializeFacs (
+ void)
+{
+ ACPI_TABLE_FACS *Facs;
+
+
+ /* If Hardware Reduced flag is set, there is no FACS */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ AcpiGbl_FACS = NULL;
+ return (AE_OK);
+ }
+ else if (AcpiGbl_FADT.XFacs &&
+ (!AcpiGbl_FADT.Facs || !AcpiGbl_Use32BitFacsAddresses))
+ {
+ (void) AcpiGetTableByIndex (AcpiGbl_XFacsIndex,
+ ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
+ AcpiGbl_FACS = Facs;
+ }
+ else if (AcpiGbl_FADT.Facs)
+ {
+ (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex,
+ ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
+ AcpiGbl_FACS = Facs;
+ }
+
+ /* If there is no FACS, just continue. There was already an error msg */
+
+ return (AE_OK);
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbTablesLoaded
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: TRUE if required ACPI tables are loaded
+ *
+ * DESCRIPTION: Determine if the minimum required ACPI tables are present
+ * (FADT, FACS, DSDT)
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiTbTablesLoaded (
+ void)
+{
+
+ if (AcpiGbl_RootTableList.CurrentTableCount >= 4)
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCheckDsdtHeader
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
+ * if the DSDT has been replaced from outside the OS and/or if
+ * the DSDT header has been corrupted.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbCheckDsdtHeader (
+ void)
+{
+
+ /* Compare original length and checksum to current values */
+
+ if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
+ AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
+ {
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "The DSDT has been corrupted or replaced - "
+ "old, new headers below"));
+ AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
+ AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
+
+ /* Disable further error messages */
+
+ AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
+ AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCopyDsdt
+ *
+ * PARAMETERS: TableDesc - Installed table to copy
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
+ * Some very bad BIOSs are known to either corrupt the DSDT or
+ * install a new, bad DSDT. This copy works around the problem.
+ *
+ ******************************************************************************/
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex)
+{
+ ACPI_TABLE_HEADER *NewTable;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
+
+ NewTable = ACPI_ALLOCATE (TableDesc->Length);
+ if (!NewTable)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
+ TableDesc->Length));
+ return (NULL);
+ }
+
+ memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
+ AcpiTbUninstallTable (TableDesc);
+
+ AcpiTbInitTableDescriptor (
+ &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
+ ACPI_PTR_TO_PHYSADDR (NewTable), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
+ NewTable);
+
+ ACPI_INFO ((AE_INFO,
+ "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
+ NewTable->Length));
+
+ return (NewTable);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetRootTableEntry
+ *
+ * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
+ * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT)
+ *
+ * RETURN: Physical address extracted from the root table
+ *
+ * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
+ * both 32-bit and 64-bit platforms
+ *
+ * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
+ * 64-bit platforms.
+ *
+ ******************************************************************************/
+
+static ACPI_PHYSICAL_ADDRESS
+AcpiTbGetRootTableEntry (
+ UINT8 *TableEntry,
+ UINT32 TableEntrySize)
+{
+ UINT64 Address64;
+
+
+ /*
+ * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
+ * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
+ */
+ if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
+ {
+ /*
+ * 32-bit platform, RSDT: Return 32-bit table entry
+ * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
+ */
+ return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry)));
+ }
+ else
+ {
+ /*
+ * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
+ * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+ * return 64-bit
+ */
+ ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
+
+#if ACPI_MACHINE_WIDTH == 32
+ if (Address64 > ACPI_UINT32_MAX)
+ {
+ /* Will truncate 64-bit address to 32 bits, issue warning */
+
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
+ " truncating",
+ ACPI_FORMAT_UINT64 (Address64)));
+ }
+#endif
+ return ((ACPI_PHYSICAL_ADDRESS) (Address64));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbParseRootTable
+ *
+ * PARAMETERS: Rsdp - Pointer to the RSDP
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to parse the Root System Description
+ * Table (RSDT or XSDT)
+ *
+ * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
+ * be mapped and cannot be copied because it contains the actual
+ * memory location of the ACPI Global Lock.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbParseRootTable (
+ ACPI_PHYSICAL_ADDRESS RsdpAddress)
+{
+ ACPI_TABLE_RSDP *Rsdp;
+ UINT32 TableEntrySize;
+ UINT32 i;
+ UINT32 TableCount;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 Length;
+ UINT8 *TableEntry;
+ ACPI_STATUS Status;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (TbParseRootTable);
+
+
+ /* Map the entire RSDP and extract the address of the RSDT or XSDT */
+
+ Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
+ if (!Rsdp)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ AcpiTbPrintTableHeader (RsdpAddress,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
+
+ /* Use XSDT if present and not overridden. Otherwise, use RSDT */
+
+ if ((Rsdp->Revision > 1) &&
+ Rsdp->XsdtPhysicalAddress &&
+ !AcpiGbl_DoNotUseXsdt)
+ {
+ /*
+ * RSDP contains an XSDT (64-bit physical addresses). We must use
+ * the XSDT if the revision is > 1 and the XSDT pointer is present,
+ * as per the ACPI specification.
+ */
+ Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
+ TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
+ }
+ else
+ {
+ /* Root table is an RSDT (32-bit physical addresses) */
+
+ Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
+ TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
+ }
+
+ /*
+ * It is not possible to map more than one entry in some environments,
+ * so unmap the RSDP here before mapping other tables
+ */
+ AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
+
+ /* Map the RSDT/XSDT table header to get the full table length */
+
+ Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ AcpiTbPrintTableHeader (Address, Table);
+
+ /*
+ * Validate length of the table, and map entire table.
+ * Minimum length table must contain at least one entry.
+ */
+ Length = Table->Length;
+ AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
+
+ if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
+ {
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Invalid table length 0x%X in RSDT/XSDT", Length));
+ return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ }
+
+ Table = AcpiOsMapMemory (Address, Length);
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Validate the root table checksum */
+
+ Status = AcpiTbVerifyChecksum (Table, Length);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsUnmapMemory (Table, Length);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the number of entries and pointer to first entry */
+
+ TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
+ TableEntrySize);
+ TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
+
+ /* Initialize the root table array from the RSDT/XSDT */
+
+ for (i = 0; i < TableCount; i++)
+ {
+ /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
+
+ Address = AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
+
+ /* Skip NULL entries in RSDT/XSDT */
+
+ if (!Address)
+ {
+ goto NextTable;
+ }
+
+ Status = AcpiTbInstallStandardTable (Address,
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE, &TableIndex);
+
+ if (ACPI_SUCCESS (Status) &&
+ ACPI_COMPARE_NAME (&AcpiGbl_RootTableList.Tables[TableIndex].Signature,
+ ACPI_SIG_FADT))
+ {
+ AcpiTbParseFadt (TableIndex);
+ }
+
+NextTable:
+
+ TableEntry += TableEntrySize;
+ }
+
+ AcpiOsUnmapMemory (Table, Length);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiIsValidSignature
+ *
+ * PARAMETERS: Signature - Sig string to be validated
+ *
+ * RETURN: TRUE if signature is correct length and has valid characters
+ *
+ * DESCRIPTION: Validate an ACPI table signature.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiIsValidSignature (
+ char *Signature)
+{
+ UINT32 i;
+
+
+ /* Validate the signature length */
+
+ if (strlen (Signature) != ACPI_NAME_SIZE)
+ {
+ return (FALSE);
+ }
+
+ /* Validate each character in the signature */
+
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (!AcpiUtValidAcpiChar (Signature[i], i))
+ {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxface.c
new file mode 100644
index 0000000000..67f6feae04
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -0,0 +1,527 @@
+/******************************************************************************
+ *
+ * Module Name: tbxface - ACPI table-oriented external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAllocateRootTable
+ *
+ * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of
+ * ACPI_TABLE_DESC structures
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
+ * AcpiInitializeTables.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiAllocateRootTable (
+ UINT32 InitialTableCount)
+{
+
+ AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
+ AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
+
+ return (AcpiTbResizeRootTableList ());
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInitializeTables
+ *
+ * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated
+ * ACPI_TABLE_DESC structures. If NULL, the
+ * array is dynamically allocated.
+ * InitialTableCount - Size of InitialTableArray, in number of
+ * ACPI_TABLE_DESC structures
+ * AllowResize - Flag to tell Table Manager if resize of
+ * pre-allocated array is allowed. Ignored
+ * if InitialTableArray is NULL.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
+ *
+ * NOTE: Allows static allocation of the initial table array in order
+ * to avoid the use of dynamic memory in confined environments
+ * such as the kernel boot sequence where it may not be available.
+ *
+ * If the host OS memory managers are initialized, use NULL for
+ * InitialTableArray, and the table will be dynamically allocated.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInitializeTables (
+ ACPI_TABLE_DESC *InitialTableArray,
+ UINT32 InitialTableCount,
+ BOOLEAN AllowResize)
+{
+ ACPI_PHYSICAL_ADDRESS RsdpAddress;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInitializeTables);
+
+
+ /*
+ * Setup the Root Table Array and allocate the table array
+ * if requested
+ */
+ if (!InitialTableArray)
+ {
+ Status = AcpiAllocateRootTable (InitialTableCount);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ /* Root Table Array has been statically allocated by the host */
+
+ memset (InitialTableArray, 0,
+ (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
+
+ AcpiGbl_RootTableList.Tables = InitialTableArray;
+ AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
+ AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
+ if (AllowResize)
+ {
+ AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
+ }
+ }
+
+ /* Get the address of the RSDP */
+
+ RsdpAddress = AcpiOsGetRootPointer ();
+ if (!RsdpAddress)
+ {
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+
+ /*
+ * Get the root table (RSDT or XSDT) and extract all entries to the local
+ * Root Table Array. This array contains the information of the RSDT/XSDT
+ * in a common, more useable format.
+ */
+ Status = AcpiTbParseRootTable (RsdpAddress);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiReallocateRootTable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
+ * root list from the previously provided scratch area. Should
+ * be called once dynamic memory allocation is available in the
+ * kernel.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReallocateRootTable (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
+
+
+ /*
+ * Only reallocate the root table if the host provided a static buffer
+ * for the table array in the call to AcpiInitializeTables.
+ */
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
+
+ Status = AcpiTbResizeRootTableList ();
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTableHeader
+ *
+ * PARAMETERS: Signature - ACPI signature of needed table
+ * Instance - Which instance (for SSDTs)
+ * OutTableHeader - The pointer to the table header to fill
+ *
+ * RETURN: Status and pointer to mapped table header
+ *
+ * DESCRIPTION: Finds an ACPI table header.
+ *
+ * NOTE: Caller is responsible in unmapping the header with
+ * AcpiOsUnmapMemory
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTableHeader (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER *OutTableHeader)
+{
+ UINT32 i;
+ UINT32 j;
+ ACPI_TABLE_HEADER *Header;
+
+
+ /* Parameter validation */
+
+ if (!Signature || !OutTableHeader)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Walk the root table list */
+
+ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Signature))
+ {
+ continue;
+ }
+
+ if (++j < Instance)
+ {
+ continue;
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ if ((AcpiGbl_RootTableList.Tables[i].Flags &
+ ACPI_TABLE_ORIGIN_MASK) ==
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
+ {
+ Header = AcpiOsMapMemory (
+ AcpiGbl_RootTableList.Tables[i].Address,
+ sizeof (ACPI_TABLE_HEADER));
+ if (!Header)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ memcpy (OutTableHeader, Header,
+ sizeof (ACPI_TABLE_HEADER));
+ AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
+ }
+ else
+ {
+ return (AE_NOT_FOUND);
+ }
+ }
+ else
+ {
+ memcpy (OutTableHeader,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ sizeof (ACPI_TABLE_HEADER));
+ }
+
+ return (AE_OK);
+ }
+
+ return (AE_NOT_FOUND);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTable
+ *
+ * PARAMETERS: Signature - ACPI signature of needed table
+ * Instance - Which instance (for SSDTs)
+ * OutTable - Where the pointer to the table is returned
+ *
+ * RETURN: Status and pointer to the requested table
+ *
+ * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
+ * RSDT/XSDT.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTable (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **OutTable)
+{
+ UINT32 i;
+ UINT32 j;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!Signature || !OutTable)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Walk the root table list */
+
+ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Signature))
+ {
+ continue;
+ }
+
+ if (++j < Instance)
+ {
+ continue;
+ }
+
+ Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
+ if (ACPI_SUCCESS (Status))
+ {
+ *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
+ }
+
+ return (Status);
+ }
+
+ return (AE_NOT_FOUND);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTableByIndex
+ *
+ * PARAMETERS: TableIndex - Table index
+ * Table - Where the pointer to the table is returned
+ *
+ * RETURN: Status and pointer to the requested table
+ *
+ * DESCRIPTION: Obtain a table by an index into the global table list. Used
+ * internally also.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTableByIndex (
+ UINT32 TableIndex,
+ ACPI_TABLE_HEADER **Table)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
+
+
+ /* Parameter validation */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Validate index */
+
+ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
+ {
+ /* Table is not mapped, map it */
+
+ Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
+ if (ACPI_FAILURE (Status))
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallTableHandler
+ *
+ * PARAMETERS: Handler - Table event handler
+ * Context - Value passed to the handler on each event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a global table event handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallTableHandler (
+ ACPI_TABLE_HANDLER Handler,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
+
+
+ if (!Handler)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Don't allow more than one handler */
+
+ if (AcpiGbl_TableHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ /* Install the handler */
+
+ AcpiGbl_TableHandler = Handler;
+ AcpiGbl_TableHandlerContext = Context;
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveTableHandler
+ *
+ * PARAMETERS: Handler - Table event handler that was installed
+ * previously.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a table event handler
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveTableHandler (
+ ACPI_TABLE_HANDLER Handler)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Make sure that the installed handler is the same */
+
+ if (!Handler ||
+ Handler != AcpiGbl_TableHandler)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto Cleanup;
+ }
+
+ /* Remove the handler */
+
+ AcpiGbl_TableHandler = NULL;
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfload.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfload.c
new file mode 100644
index 0000000000..52abb848b1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfload.c
@@ -0,0 +1,500 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfload - Table load/unload external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxfload")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTables (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTables);
+
+
+ /* Load the namespace from the tables */
+
+ Status = AcpiTbLoadNamespace ();
+
+ /* Don't let single failures abort the load */
+
+ if (Status == AE_CTRL_TERMINATE)
+ {
+ Status = AE_OK;
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While loading namespace from ACPI tables"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbLoadNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
+ * the RSDT/XSDT.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbLoadNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+ ACPI_TABLE_HEADER *NewDsdt;
+ ACPI_TABLE_DESC *Table;
+ UINT32 TablesLoaded = 0;
+ UINT32 TablesFailed = 0;
+
+
+ ACPI_FUNCTION_TRACE (TbLoadNamespace);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Load the namespace. The DSDT is required, but any SSDT and
+ * PSDT tables are optional. Verify the DSDT.
+ */
+ Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex];
+
+ if (!AcpiGbl_RootTableList.CurrentTableCount ||
+ !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) ||
+ ACPI_FAILURE (AcpiTbValidateTable (Table)))
+ {
+ Status = AE_NO_ACPI_TABLES;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Save the DSDT pointer for simple access. This is the mapped memory
+ * address. We must take care here because the address of the .Tables
+ * array can change dynamically as tables are loaded at run-time. Note:
+ * .Pointer field is not validated until after call to AcpiTbValidateTable.
+ */
+ AcpiGbl_DSDT = Table->Pointer;
+
+ /*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ if (AcpiGbl_CopyDsdtLocally)
+ {
+ NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex);
+ if (NewDsdt)
+ {
+ AcpiGbl_DSDT = NewDsdt;
+ }
+ }
+
+ /*
+ * Save the original DSDT header for detection of table corruption
+ * and/or replacement of the DSDT from outside the OS.
+ */
+ memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ sizeof (ACPI_TABLE_HEADER));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /* Load and parse tables */
+
+ Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed"));
+ TablesFailed++;
+ }
+ else
+ {
+ TablesLoaded++;
+ }
+
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ Table = &AcpiGbl_RootTableList.Tables[i];
+
+ if (!AcpiGbl_RootTableList.Tables[i].Address ||
+ (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) &&
+ !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) &&
+ !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) ||
+ ACPI_FAILURE (AcpiTbValidateTable (Table)))
+ {
+ continue;
+ }
+
+ /* Ignore errors while loading tables, get as many as possible */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table",
+ Table->Signature.Ascii, Table->Pointer->OemTableId));
+ TablesFailed++;
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
+ Table->Signature.Ascii, Table->Pointer->OemTableId));
+ }
+ else
+ {
+ TablesLoaded++;
+ }
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ }
+
+ if (!TablesFailed)
+ {
+ ACPI_INFO ((AE_INFO,
+ "%u ACPI AML tables successfully acquired and loaded",
+ TablesLoaded));
+ }
+ else
+ {
+ ACPI_ERROR ((AE_INFO,
+ "%u table load failures, %u successful",
+ TablesFailed, TablesLoaded));
+
+ /* Indicate at least one failure */
+
+ Status = AE_CTRL_TERMINATE;
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallTable
+ *
+ * PARAMETERS: Address - Address of the ACPI table to be installed.
+ * Physical - Whether the address is a physical table
+ * address or not
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dynamically install an ACPI table.
+ * Note: This function should only be invoked after
+ * AcpiInitializeTables() and before AcpiLoadTables().
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ BOOLEAN Physical)
+{
+ ACPI_STATUS Status;
+ UINT8 Flags;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallTable);
+
+
+ if (Physical)
+ {
+ Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
+ }
+ else
+ {
+ Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
+ }
+
+ Status = AcpiTbInstallStandardTable (Address, Flags,
+ FALSE, FALSE, &TableIndex);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTable
+ *
+ * PARAMETERS: Table - Pointer to a buffer containing the ACPI
+ * table to be loaded.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
+ * be a valid ACPI table with a valid ACPI table header.
+ * Note1: Mainly intended to support hotplug addition of SSDTs.
+ * Note2: Does not copy the incoming table. User is responsible
+ * to ensure that the table is not deleted or unmapped.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTable);
+
+
+ /* Parameter validation */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the table and load it into the namespace */
+
+ ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
+ ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE,
+ &TableIndex);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Note: Now table is "INSTALLED", it must be validated before
+ * using.
+ */
+ Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUnloadParentTable
+ *
+ * PARAMETERS: Object - Handle to any namespace object owned by
+ * the table to be unloaded
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
+ * the table and deletes all namespace objects associated with
+ * that table. Unloading of the DSDT is not allowed.
+ * Note: Mainly intended to support hotplug removal of SSDTs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object);
+ ACPI_STATUS Status = AE_NOT_EXIST;
+ ACPI_OWNER_ID OwnerId;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiUnloadParentTable);
+
+
+ /* Parameter validation */
+
+ if (!Object)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * The node OwnerId is currently the same as the parent table ID.
+ * However, this could change in the future.
+ */
+ OwnerId = Node->OwnerId;
+ if (!OwnerId)
+ {
+ /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Find the table in the global table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId)
+ {
+ continue;
+ }
+
+ /*
+ * Allow unload of SSDT and OEMx tables only. Do not allow unload
+ * of the DSDT. No other types of tables should get here, since
+ * only these types can contain AML and thus are the only types
+ * that can create namespace objects.
+ */
+ if (ACPI_COMPARE_NAME (
+ AcpiGbl_RootTableList.Tables[i].Signature.Ascii,
+ ACPI_SIG_DSDT))
+ {
+ Status = AE_TYPE;
+ break;
+ }
+
+ /* Ensure the table is actually loaded */
+
+ if (!AcpiTbIsTableLoaded (i))
+ {
+ Status = AE_NOT_EXIST;
+ break;
+ }
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ AcpiGbl_TableHandlerContext);
+ }
+
+ /*
+ * Delete all namespace objects owned by this table. Note that
+ * these objects can appear anywhere in the namespace by virtue
+ * of the AML "Scope" operator. Thus, we need to track ownership
+ * by an ID, not simply a position within the hierarchy.
+ */
+ Status = AcpiTbDeleteNamespaceByOwner (i);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Status = AcpiTbReleaseOwnerId (i);
+ AcpiTbSetTableLoadedFlag (i, FALSE);
+ break;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfroot.c b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfroot.c
new file mode 100644
index 0000000000..e3b93d39fd
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/tables/tbxfroot.c
@@ -0,0 +1,319 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfroot - Find the root ACPI table (RSDT)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/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/boot/sys/contrib/dev/acpica/components/utilities/utaddress.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utaddress.c
new file mode 100644
index 0000000000..5ed2b4d080
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utaddress.c
@@ -0,0 +1,324 @@
+/******************************************************************************
+ *
+ * Module Name: utaddress - OpRegion address range check
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utaddress")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAddAddressRange
+ *
+ * PARAMETERS: SpaceId - Address space ID
+ * Address - OpRegion start address
+ * Length - OpRegion length
+ * RegionNode - OpRegion namespace node
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add the Operation Region address range to the global list.
+ * The only supported Space IDs are Memory and I/O. Called when
+ * the OpRegion address/length operands are fully evaluated.
+ *
+ * MUTEX: Locks the namespace
+ *
+ * NOTE: Because this interface is only called when an OpRegion argument
+ * list is evaluated, there cannot be any duplicate RegionNodes.
+ * Duplicate Address/Length values are allowed, however, so that multiple
+ * address conflicts can be detected.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtAddAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 Length,
+ ACPI_NAMESPACE_NODE *RegionNode)
+{
+ ACPI_ADDRESS_RANGE *RangeInfo;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtAddAddressRange);
+
+
+ if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
+ (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Allocate/init a new info block, add it to the appropriate list */
+
+ RangeInfo = ACPI_ALLOCATE (sizeof (ACPI_ADDRESS_RANGE));
+ if (!RangeInfo)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ RangeInfo->StartAddress = Address;
+ RangeInfo->EndAddress = (Address + Length - 1);
+ RangeInfo->RegionNode = RegionNode;
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (RangeInfo);
+ return_ACPI_STATUS (Status);
+ }
+
+ RangeInfo->Next = AcpiGbl_AddressRangeList[SpaceId];
+ AcpiGbl_AddressRangeList[SpaceId] = RangeInfo;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "\nAdded [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
+ AcpiUtGetNodeName (RangeInfo->RegionNode),
+ ACPI_FORMAT_UINT64 (Address),
+ ACPI_FORMAT_UINT64 (RangeInfo->EndAddress)));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveAddressRange
+ *
+ * PARAMETERS: SpaceId - Address space ID
+ * RegionNode - OpRegion namespace node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove the Operation Region from the global list. The only
+ * supported Space IDs are Memory and I/O. Called when an
+ * OpRegion is deleted.
+ *
+ * MUTEX: Assumes the namespace is locked
+ *
+ ******************************************************************************/
+
+void
+AcpiUtRemoveAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_NAMESPACE_NODE *RegionNode)
+{
+ ACPI_ADDRESS_RANGE *RangeInfo;
+ ACPI_ADDRESS_RANGE *Prev;
+
+
+ ACPI_FUNCTION_TRACE (UtRemoveAddressRange);
+
+
+ if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
+ (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
+ {
+ return_VOID;
+ }
+
+ /* Get the appropriate list head and check the list */
+
+ RangeInfo = Prev = AcpiGbl_AddressRangeList[SpaceId];
+ while (RangeInfo)
+ {
+ if (RangeInfo->RegionNode == RegionNode)
+ {
+ if (RangeInfo == Prev) /* Found at list head */
+ {
+ AcpiGbl_AddressRangeList[SpaceId] = RangeInfo->Next;
+ }
+ else
+ {
+ Prev->Next = RangeInfo->Next;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "\nRemoved [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
+ AcpiUtGetNodeName (RangeInfo->RegionNode),
+ ACPI_FORMAT_UINT64 (RangeInfo->StartAddress),
+ ACPI_FORMAT_UINT64 (RangeInfo->EndAddress)));
+
+ ACPI_FREE (RangeInfo);
+ return_VOID;
+ }
+
+ Prev = RangeInfo;
+ RangeInfo = RangeInfo->Next;
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCheckAddressRange
+ *
+ * PARAMETERS: SpaceId - Address space ID
+ * Address - Start address
+ * Length - Length of address range
+ * Warn - TRUE if warning on overlap desired
+ *
+ * RETURN: Count of the number of conflicts detected. Zero is always
+ * returned for Space IDs other than Memory or I/O.
+ *
+ * DESCRIPTION: Check if the input address range overlaps any of the
+ * ASL operation region address ranges. The only supported
+ * Space IDs are Memory and I/O.
+ *
+ * MUTEX: Assumes the namespace is locked.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiUtCheckAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 Length,
+ BOOLEAN Warn)
+{
+ ACPI_ADDRESS_RANGE *RangeInfo;
+ ACPI_PHYSICAL_ADDRESS EndAddress;
+ char *Pathname;
+ UINT32 OverlapCount = 0;
+
+
+ ACPI_FUNCTION_TRACE (UtCheckAddressRange);
+
+
+ if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
+ (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
+ {
+ return_UINT32 (0);
+ }
+
+ RangeInfo = AcpiGbl_AddressRangeList[SpaceId];
+ EndAddress = Address + Length - 1;
+
+ /* Check entire list for all possible conflicts */
+
+ while (RangeInfo)
+ {
+ /*
+ * Check if the requested address/length overlaps this
+ * address range. There are four cases to consider:
+ *
+ * 1) Input address/length is contained completely in the
+ * address range
+ * 2) Input address/length overlaps range at the range start
+ * 3) Input address/length overlaps range at the range end
+ * 4) Input address/length completely encompasses the range
+ */
+ if ((Address <= RangeInfo->EndAddress) &&
+ (EndAddress >= RangeInfo->StartAddress))
+ {
+ /* Found an address range overlap */
+
+ OverlapCount++;
+ if (Warn) /* Optional warning message */
+ {
+ Pathname = AcpiNsGetExternalPathname (RangeInfo->RegionNode);
+
+ ACPI_WARNING ((AE_INFO,
+ "%s range 0x%8.8X%8.8X-0x%8.8X%8.8X conflicts with OpRegion 0x%8.8X%8.8X-0x%8.8X%8.8X (%s)",
+ AcpiUtGetRegionName (SpaceId),
+ ACPI_FORMAT_UINT64 (Address),
+ ACPI_FORMAT_UINT64 (EndAddress),
+ ACPI_FORMAT_UINT64 (RangeInfo->StartAddress),
+ ACPI_FORMAT_UINT64 (RangeInfo->EndAddress),
+ Pathname));
+ ACPI_FREE (Pathname);
+ }
+ }
+
+ RangeInfo = RangeInfo->Next;
+ }
+
+ return_UINT32 (OverlapCount);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteAddressLists
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all global address range lists (called during
+ * subsystem shutdown).
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDeleteAddressLists (
+ void)
+{
+ ACPI_ADDRESS_RANGE *Next;
+ ACPI_ADDRESS_RANGE *RangeInfo;
+ int i;
+
+
+ /* Delete all elements in all address range lists */
+
+ for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++)
+ {
+ Next = AcpiGbl_AddressRangeList[i];
+
+ while (Next)
+ {
+ RangeInfo = Next;
+ Next = RangeInfo->Next;
+ ACPI_FREE (RangeInfo);
+ }
+
+ AcpiGbl_AddressRangeList[i] = NULL;
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utalloc.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utalloc.c
new file mode 100644
index 0000000000..c26259d92f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utalloc.c
@@ -0,0 +1,364 @@
+/******************************************************************************
+ *
+ * Module Name: utalloc - local memory allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utalloc")
+
+
+#if !defined (USE_NATIVE_ALLOCATE_ZEROED)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsAllocateZeroed
+ *
+ * PARAMETERS: Size - Size of the allocation
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
+ * This is the default implementation. Can be overridden via the
+ * USE_NATIVE_ALLOCATE_ZEROED flag.
+ *
+ ******************************************************************************/
+
+void *
+AcpiOsAllocateZeroed (
+ ACPI_SIZE Size)
+{
+ void *Allocation;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Allocation = AcpiOsAllocate (Size);
+ if (Allocation)
+ {
+ /* Clear the memory block */
+
+ memset (Allocation, 0, Size);
+ }
+
+ return (Allocation);
+}
+
+#endif /* !USE_NATIVE_ALLOCATE_ZEROED */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateCaches
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create all local caches
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCreateCaches (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* Object Caches, for frequently used objects */
+
+ Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
+ ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE),
+ ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON),
+ ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED),
+ ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT),
+ ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ /* Memory allocation lists */
+
+ Status = AcpiUtCreateList ("Acpi-Global", 0,
+ &AcpiGbl_GlobalList);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
+ &AcpiGbl_NsNodeList);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+#endif
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteCaches
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Purge and delete all local caches
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtDeleteCaches (
+ void)
+{
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ char Buffer[7];
+
+ if (AcpiGbl_DisplayFinalMemStats)
+ {
+ strcpy (Buffer, "MEMORY");
+ (void) AcpiDbDisplayStatistics (Buffer);
+ }
+#endif
+
+ (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
+ AcpiGbl_NamespaceCache = NULL;
+
+ (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
+ AcpiGbl_StateCache = NULL;
+
+ (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
+ AcpiGbl_OperandCache = NULL;
+
+ (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
+ AcpiGbl_PsNodeCache = NULL;
+
+ (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
+ AcpiGbl_PsNodeExtCache = NULL;
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ /* Debug only - display leftover memory allocation, if any */
+
+ AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);
+
+ /* Free memory lists */
+
+ AcpiOsFree (AcpiGbl_GlobalList);
+ AcpiGbl_GlobalList = NULL;
+
+ AcpiOsFree (AcpiGbl_NsNodeList);
+ AcpiGbl_NsNodeList = NULL;
+#endif
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidateBuffer
+ *
+ * PARAMETERS: Buffer - Buffer descriptor to be validated
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtValidateBuffer (
+ ACPI_BUFFER *Buffer)
+{
+
+ /* Obviously, the structure pointer must be valid */
+
+ if (!Buffer)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Special semantics for the length */
+
+ if ((Buffer->Length == ACPI_NO_BUFFER) ||
+ (Buffer->Length == ACPI_ALLOCATE_BUFFER) ||
+ (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER))
+ {
+ return (AE_OK);
+ }
+
+ /* Length is valid, the buffer pointer must be also */
+
+ if (!Buffer->Pointer)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInitializeBuffer
+ *
+ * PARAMETERS: Buffer - Buffer to be validated
+ * RequiredLength - Length needed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate that the buffer is of the required length or
+ * allocate a new buffer. Returned buffer is always zeroed.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtInitializeBuffer (
+ ACPI_BUFFER *Buffer,
+ ACPI_SIZE RequiredLength)
+{
+ ACPI_SIZE InputBufferLength;
+
+
+ /* Parameter validation */
+
+ if (!Buffer || !RequiredLength)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Buffer->Length is used as both an input and output parameter. Get the
+ * input actual length and set the output required buffer length.
+ */
+ InputBufferLength = Buffer->Length;
+ Buffer->Length = RequiredLength;
+
+ /*
+ * The input buffer length contains the actual buffer length, or the type
+ * of buffer to be allocated by this routine.
+ */
+ switch (InputBufferLength)
+ {
+ case ACPI_NO_BUFFER:
+
+ /* Return the exception (and the required buffer length) */
+
+ return (AE_BUFFER_OVERFLOW);
+
+ case ACPI_ALLOCATE_BUFFER:
+ /*
+ * Allocate a new buffer. We directectly call AcpiOsAllocate here to
+ * purposefully bypass the (optionally enabled) internal allocation
+ * tracking mechanism since we only want to track internal
+ * allocations. Note: The caller should use AcpiOsFree to free this
+ * buffer created via ACPI_ALLOCATE_BUFFER.
+ */
+ Buffer->Pointer = AcpiOsAllocate (RequiredLength);
+ break;
+
+ case ACPI_ALLOCATE_LOCAL_BUFFER:
+
+ /* Allocate a new buffer with local interface to allow tracking */
+
+ Buffer->Pointer = ACPI_ALLOCATE (RequiredLength);
+ break;
+
+ default:
+
+ /* Existing buffer: Validate the size of the buffer */
+
+ if (InputBufferLength < RequiredLength)
+ {
+ return (AE_BUFFER_OVERFLOW);
+ }
+ break;
+ }
+
+ /* Validate allocation from above or input buffer pointer */
+
+ if (!Buffer->Pointer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Have a valid buffer, clear it */
+
+ memset (Buffer->Pointer, 0, RequiredLength);
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utbuffer.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utbuffer.c
new file mode 100644
index 0000000000..08a42cdc85
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utbuffer.c
@@ -0,0 +1,362 @@
+/******************************************************************************
+ *
+ * Module Name: utbuffer - Buffer dump routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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 ("%6.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, "%6.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/boot/sys/contrib/dev/acpica/components/utilities/utcache.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcache.c
new file mode 100644
index 0000000000..c252d8a282
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcache.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ * Module Name: utcache - local cache allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utcache")
+
+
+#ifdef ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsCreateCache
+ *
+ * PARAMETERS: CacheName - Ascii name for the cache
+ * ObjectSize - Size of each cached object
+ * MaxDepth - Maximum depth of the cache (in objects)
+ * ReturnCache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a cache object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiOsCreateCache (
+ char *CacheName,
+ UINT16 ObjectSize,
+ UINT16 MaxDepth,
+ ACPI_MEMORY_LIST **ReturnCache)
+{
+ ACPI_MEMORY_LIST *Cache;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!CacheName || !ReturnCache || (ObjectSize < 16))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Create the cache object */
+
+ Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST));
+ if (!Cache)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Populate the cache object and return it */
+
+ memset (Cache, 0, sizeof (ACPI_MEMORY_LIST));
+ Cache->ListName = CacheName;
+ Cache->ObjectSize = ObjectSize;
+ Cache->MaxDepth = MaxDepth;
+
+ *ReturnCache = Cache;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsPurgeCache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiOsPurgeCache (
+ ACPI_MEMORY_LIST *Cache)
+{
+ void *Next;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!Cache)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Walk the list of objects in this cache */
+
+ while (Cache->ListHead)
+ {
+ /* Delete and unlink one cached state object */
+
+ Next = ACPI_GET_DESCRIPTOR_PTR (Cache->ListHead);
+ ACPI_FREE (Cache->ListHead);
+
+ Cache->ListHead = Next;
+ Cache->CurrentDepth--;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsDeleteCache
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache and delete the
+ * cache object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiOsDeleteCache (
+ ACPI_MEMORY_LIST *Cache)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Purge all objects in the cache */
+
+ Status = AcpiOsPurgeCache (Cache);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Now we can delete the cache object */
+
+ AcpiOsFree (Cache);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsReleaseObject
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ * Object - The object to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release an object to the specified cache. If cache is full,
+ * the object is deleted.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiOsReleaseObject (
+ ACPI_MEMORY_LIST *Cache,
+ void *Object)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (!Cache || !Object)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* If cache is full, just free this object */
+
+ if (Cache->CurrentDepth >= Cache->MaxDepth)
+ {
+ ACPI_FREE (Object);
+ ACPI_MEM_TRACKING (Cache->TotalFreed++);
+ }
+
+ /* Otherwise put this object back into the cache */
+
+ else
+ {
+ Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Mark the object as cached */
+
+ memset (Object, 0xCA, Cache->ObjectSize);
+ ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_CACHED);
+
+ /* Put the object at the head of the cache list */
+
+ ACPI_SET_DESCRIPTOR_PTR (Object, Cache->ListHead);
+ Cache->ListHead = Object;
+ Cache->CurrentDepth++;
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsAcquireObject
+ *
+ * PARAMETERS: Cache - Handle to cache object
+ *
+ * RETURN: the acquired object. NULL on error
+ *
+ * DESCRIPTION: Get an object from the specified cache. If cache is empty,
+ * the object is allocated.
+ *
+ ******************************************************************************/
+
+void *
+AcpiOsAcquireObject (
+ ACPI_MEMORY_LIST *Cache)
+{
+ ACPI_STATUS Status;
+ void *Object;
+
+
+ ACPI_FUNCTION_NAME (OsAcquireObject);
+
+
+ if (!Cache)
+ {
+ return_PTR (NULL);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_PTR (NULL);
+ }
+
+ ACPI_MEM_TRACKING (Cache->Requests++);
+
+ /* Check the cache first */
+
+ if (Cache->ListHead)
+ {
+ /* There is an object available, use it */
+
+ Object = Cache->ListHead;
+ Cache->ListHead = ACPI_GET_DESCRIPTOR_PTR (Object);
+
+ Cache->CurrentDepth--;
+
+ ACPI_MEM_TRACKING (Cache->Hits++);
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Object %p from %s cache\n", Object, Cache->ListName));
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_PTR (NULL);
+ }
+
+ /* Clear (zero) the previously used Object */
+
+ memset (Object, 0, Cache->ObjectSize);
+ }
+ else
+ {
+ /* The cache is empty, create a new object */
+
+ ACPI_MEM_TRACKING (Cache->TotalAllocated++);
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ if ((Cache->TotalAllocated - Cache->TotalFreed) > Cache->MaxOccupied)
+ {
+ Cache->MaxOccupied = Cache->TotalAllocated - Cache->TotalFreed;
+ }
+#endif
+
+ /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_PTR (NULL);
+ }
+
+ Object = ACPI_ALLOCATE_ZEROED (Cache->ObjectSize);
+ if (!Object)
+ {
+ return_PTR (NULL);
+ }
+ }
+
+ return_PTR (Object);
+}
+#endif /* ACPI_USE_LOCAL_CACHE */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcopy.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcopy.c
new file mode 100644
index 0000000000..2032dd4110
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utcopy.c
@@ -0,0 +1,1072 @@
+/******************************************************************************
+ *
+ * Module Name: utcopy - Internal to external object translation utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utcopy")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtCopyIsimpleToEsimple (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_OBJECT *ExternalObject,
+ UINT8 *DataSpace,
+ ACPI_SIZE *BufferSpaceUsed);
+
+static ACPI_STATUS
+AcpiUtCopyIelementToIelement (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context);
+
+static ACPI_STATUS
+AcpiUtCopyIpackageToEpackage (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ UINT8 *Buffer,
+ ACPI_SIZE *SpaceUsed);
+
+static ACPI_STATUS
+AcpiUtCopyEsimpleToIsimple(
+ ACPI_OBJECT *UserObj,
+ ACPI_OPERAND_OBJECT **ReturnObj);
+
+static ACPI_STATUS
+AcpiUtCopyEpackageToIpackage (
+ ACPI_OBJECT *ExternalObject,
+ ACPI_OPERAND_OBJECT **InternalObject);
+
+static ACPI_STATUS
+AcpiUtCopySimpleObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *DestDesc);
+
+static ACPI_STATUS
+AcpiUtCopyIelementToEelement (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context);
+
+static ACPI_STATUS
+AcpiUtCopyIpackageToIpackage (
+ ACPI_OPERAND_OBJECT *SourceObj,
+ ACPI_OPERAND_OBJECT *DestObj,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIsimpleToEsimple
+ *
+ * PARAMETERS: InternalObject - Source object to be copied
+ * ExternalObject - Where to return the copied object
+ * DataSpace - Where object data is returned (such as
+ * buffer and string data)
+ * BufferSpaceUsed - Length of DataSpace that was used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to copy a simple internal object to
+ * an external object.
+ *
+ * The DataSpace buffer is assumed to have sufficient space for
+ * the object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyIsimpleToEsimple (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_OBJECT *ExternalObject,
+ UINT8 *DataSpace,
+ ACPI_SIZE *BufferSpaceUsed)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
+
+
+ *BufferSpaceUsed = 0;
+
+ /*
+ * Check for NULL object case (could be an uninitialized
+ * package element)
+ */
+ if (!InternalObject)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Always clear the external object */
+
+ memset (ExternalObject, 0, sizeof (ACPI_OBJECT));
+
+ /*
+ * In general, the external object will be the same type as
+ * the internal object
+ */
+ ExternalObject->Type = InternalObject->Common.Type;
+
+ /* However, only a limited number of external types are supported */
+
+ switch (InternalObject->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ ExternalObject->String.Pointer = (char *) DataSpace;
+ ExternalObject->String.Length = InternalObject->String.Length;
+ *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ (ACPI_SIZE) InternalObject->String.Length + 1);
+
+ memcpy ((void *) DataSpace,
+ (void *) InternalObject->String.Pointer,
+ (ACPI_SIZE) InternalObject->String.Length + 1);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ExternalObject->Buffer.Pointer = DataSpace;
+ ExternalObject->Buffer.Length = InternalObject->Buffer.Length;
+ *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ InternalObject->String.Length);
+
+ memcpy ((void *) DataSpace,
+ (void *) InternalObject->Buffer.Pointer,
+ InternalObject->Buffer.Length);
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ ExternalObject->Integer.Value = InternalObject->Integer.Value;
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /* This is an object reference. */
+
+ switch (InternalObject->Reference.Class)
+ {
+ case ACPI_REFCLASS_NAME:
+ /*
+ * For namepath, return the object handle ("reference")
+ * We are referring to the namespace node
+ */
+ ExternalObject->Reference.Handle =
+ InternalObject->Reference.Node;
+ ExternalObject->Reference.ActualType =
+ AcpiNsGetType (InternalObject->Reference.Node);
+ break;
+
+ default:
+
+ /* All other reference types are unsupported */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ ExternalObject->Processor.ProcId =
+ InternalObject->Processor.ProcId;
+ ExternalObject->Processor.PblkAddress =
+ InternalObject->Processor.Address;
+ ExternalObject->Processor.PblkLength =
+ InternalObject->Processor.Length;
+ break;
+
+ case ACPI_TYPE_POWER:
+
+ ExternalObject->PowerResource.SystemLevel =
+ InternalObject->PowerResource.SystemLevel;
+
+ ExternalObject->PowerResource.ResourceOrder =
+ InternalObject->PowerResource.ResourceOrder;
+ break;
+
+ default:
+ /*
+ * There is no corresponding external object type
+ */
+ ACPI_ERROR ((AE_INFO,
+ "Unsupported object type, cannot convert to external object: %s",
+ AcpiUtGetTypeName (InternalObject->Common.Type)));
+
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIelementToEelement
+ *
+ * PARAMETERS: ACPI_PKG_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyIelementToEelement (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context;
+ ACPI_SIZE ObjectSpace;
+ UINT32 ThisIndex;
+ ACPI_OBJECT *TargetObject;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ ThisIndex = State->Pkg.Index;
+ TargetObject = (ACPI_OBJECT *)
+ &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex];
+
+ switch (ObjectType)
+ {
+ case ACPI_COPY_TYPE_SIMPLE:
+ /*
+ * This is a simple or null object
+ */
+ Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
+ TargetObject, Info->FreeSpace, &ObjectSpace);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_COPY_TYPE_PACKAGE:
+ /*
+ * Build the package object
+ */
+ TargetObject->Type = ACPI_TYPE_PACKAGE;
+ TargetObject->Package.Count = SourceObject->Package.Count;
+ TargetObject->Package.Elements =
+ ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
+
+ /*
+ * Pass the new package object back to the package walk routine
+ */
+ State->Pkg.ThisTargetObj = TargetObject;
+
+ /*
+ * Save space for the array of objects (Package elements)
+ * update the buffer length counter
+ */
+ ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ (ACPI_SIZE) TargetObject->Package.Count *
+ sizeof (ACPI_OBJECT));
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ Info->FreeSpace += ObjectSpace;
+ Info->Length += ObjectSpace;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIpackageToEpackage
+ *
+ * PARAMETERS: InternalObject - Pointer to the object we are returning
+ * Buffer - Where the object is returned
+ * SpaceUsed - Where the object length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ * buffer. A package object by definition contains other objects.
+ *
+ * The buffer is assumed to have sufficient space for the object.
+ * The caller must have verified the buffer length needed using
+ * the AcpiUtGetObjectSize function before calling this function.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyIpackageToEpackage (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ UINT8 *Buffer,
+ ACPI_SIZE *SpaceUsed)
+{
+ ACPI_OBJECT *ExternalObject;
+ ACPI_STATUS Status;
+ ACPI_PKG_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
+
+
+ /*
+ * First package at head of the buffer
+ */
+ ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
+
+ /*
+ * Free space begins right after the first package
+ */
+ Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
+ Info.FreeSpace = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
+ sizeof (ACPI_OBJECT));
+ Info.ObjectSpace = 0;
+ Info.NumPackages = 1;
+
+ ExternalObject->Type = InternalObject->Common.Type;
+ ExternalObject->Package.Count = InternalObject->Package.Count;
+ ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT,
+ Info.FreeSpace);
+
+ /*
+ * Leave room for an array of ACPI_OBJECTS in the buffer
+ * and move the free space past it
+ */
+ Info.Length += (ACPI_SIZE) ExternalObject->Package.Count *
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
+ Info.FreeSpace += ExternalObject->Package.Count *
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
+
+ Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
+ AcpiUtCopyIelementToEelement, &Info);
+
+ *SpaceUsed = Info.Length;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIobjectToEobject
+ *
+ * PARAMETERS: InternalObject - The internal object to be converted
+ * RetBuffer - Where the object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to build an API object to be returned
+ * to the caller.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCopyIobjectToEobject (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_BUFFER *RetBuffer)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
+
+
+ if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ /*
+ * Package object: Copy all subobjects (including
+ * nested packages)
+ */
+ Status = AcpiUtCopyIpackageToEpackage (InternalObject,
+ RetBuffer->Pointer, &RetBuffer->Length);
+ }
+ else
+ {
+ /*
+ * Build a simple object (no nested objects)
+ */
+ Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
+ ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
+ ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
+ &RetBuffer->Length);
+ /*
+ * build simple does not include the object size in the length
+ * so we add it in here
+ */
+ RetBuffer->Length += sizeof (ACPI_OBJECT);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyEsimpleToIsimple
+ *
+ * PARAMETERS: ExternalObject - The external object to be converted
+ * RetInternalObject - Where the internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function copies an external object to an internal one.
+ * NOTE: Pointers can be copied, we don't need to copy data.
+ * (The pointers have to be valid in our address space no matter
+ * what we do with them!)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyEsimpleToIsimple (
+ ACPI_OBJECT *ExternalObject,
+ ACPI_OPERAND_OBJECT **RetInternalObject)
+{
+ ACPI_OPERAND_OBJECT *InternalObject;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
+
+
+ /*
+ * Simple types supported are: String, Buffer, Integer
+ */
+ switch (ExternalObject->Type)
+ {
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ InternalObject = AcpiUtCreateInternalObject (
+ (UINT8) ExternalObject->Type);
+ if (!InternalObject)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ break;
+
+ case ACPI_TYPE_ANY: /* This is the case for a NULL object */
+
+ *RetInternalObject = NULL;
+ return_ACPI_STATUS (AE_OK);
+
+ default:
+
+ /* All other types are not supported */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unsupported object type, cannot convert to internal object: %s",
+ AcpiUtGetTypeName (ExternalObject->Type)));
+
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+
+ /* Must COPY string and buffer contents */
+
+ switch (ExternalObject->Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ InternalObject->String.Pointer =
+ ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
+ ExternalObject->String.Length + 1);
+
+ if (!InternalObject->String.Pointer)
+ {
+ goto ErrorExit;
+ }
+
+ memcpy (InternalObject->String.Pointer,
+ ExternalObject->String.Pointer,
+ ExternalObject->String.Length);
+
+ InternalObject->String.Length = ExternalObject->String.Length;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ InternalObject->Buffer.Pointer =
+ ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
+ if (!InternalObject->Buffer.Pointer)
+ {
+ goto ErrorExit;
+ }
+
+ memcpy (InternalObject->Buffer.Pointer,
+ ExternalObject->Buffer.Pointer,
+ ExternalObject->Buffer.Length);
+
+ InternalObject->Buffer.Length = ExternalObject->Buffer.Length;
+
+ /* Mark buffer data valid */
+
+ InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
+ break;
+
+ case ACPI_TYPE_INTEGER:
+
+ InternalObject->Integer.Value = ExternalObject->Integer.Value;
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /* An incoming reference is defined to be a namespace node */
+
+ InternalObject->Reference.Class = ACPI_REFCLASS_REFOF;
+ InternalObject->Reference.Object = ExternalObject->Reference.Handle;
+ break;
+
+ default:
+
+ /* Other types can't get here */
+
+ break;
+ }
+
+ *RetInternalObject = InternalObject;
+ return_ACPI_STATUS (AE_OK);
+
+
+ErrorExit:
+ AcpiUtRemoveReference (InternalObject);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyEpackageToIpackage
+ *
+ * PARAMETERS: ExternalObject - The external object to be converted
+ * InternalObject - Where the internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy an external package object to an internal package.
+ * Handles nested packages.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyEpackageToIpackage (
+ ACPI_OBJECT *ExternalObject,
+ ACPI_OPERAND_OBJECT **InternalObject)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *PackageObject;
+ ACPI_OPERAND_OBJECT **PackageElements;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
+
+
+ /* Create the package object */
+
+ PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count);
+ if (!PackageObject)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ PackageElements = PackageObject->Package.Elements;
+
+ /*
+ * Recursive implementation. Probably ok, since nested external packages
+ * as parameters should be very rare.
+ */
+ for (i = 0; i < ExternalObject->Package.Count; i++)
+ {
+ Status = AcpiUtCopyEobjectToIobject (
+ &ExternalObject->Package.Elements[i],
+ &PackageElements[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Truncate package and delete it */
+
+ PackageObject->Package.Count = i;
+ PackageElements[i] = NULL;
+ AcpiUtRemoveReference (PackageObject);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Mark package data valid */
+
+ PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
+
+ *InternalObject = PackageObject;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyEobjectToIobject
+ *
+ * PARAMETERS: ExternalObject - The external object to be converted
+ * InternalObject - Where the internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Converts an external object to an internal object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCopyEobjectToIobject (
+ ACPI_OBJECT *ExternalObject,
+ ACPI_OPERAND_OBJECT **InternalObject)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
+
+
+ if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
+ {
+ Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject);
+ }
+ else
+ {
+ /*
+ * Build a simple object (no nested objects)
+ */
+ Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopySimpleObject
+ *
+ * PARAMETERS: SourceDesc - The internal object to be copied
+ * DestDesc - New target object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simple copy of one internal object to another. Reference count
+ * of the destination object is preserved.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopySimpleObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *DestDesc)
+{
+ UINT16 ReferenceCount;
+ ACPI_OPERAND_OBJECT *NextObject;
+ ACPI_STATUS Status;
+ ACPI_SIZE CopySize;
+
+
+ /* Save fields from destination that we don't want to overwrite */
+
+ ReferenceCount = DestDesc->Common.ReferenceCount;
+ NextObject = DestDesc->Common.NextObject;
+
+ /*
+ * Copy the entire source object over the destination object.
+ * Note: Source can be either an operand object or namespace node.
+ */
+ CopySize = sizeof (ACPI_OPERAND_OBJECT);
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ CopySize = sizeof (ACPI_NAMESPACE_NODE);
+ }
+
+ memcpy (ACPI_CAST_PTR (char, DestDesc),
+ ACPI_CAST_PTR (char, SourceDesc), CopySize);
+
+ /* Restore the saved fields */
+
+ DestDesc->Common.ReferenceCount = ReferenceCount;
+ DestDesc->Common.NextObject = NextObject;
+
+ /* New object is not static, regardless of source */
+
+ DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
+
+ /* Handle the objects with extra data */
+
+ switch (DestDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+ /*
+ * Allocate and copy the actual buffer if and only if:
+ * 1) There is a valid buffer pointer
+ * 2) The buffer has a length > 0
+ */
+ if ((SourceDesc->Buffer.Pointer) &&
+ (SourceDesc->Buffer.Length))
+ {
+ DestDesc->Buffer.Pointer =
+ ACPI_ALLOCATE (SourceDesc->Buffer.Length);
+ if (!DestDesc->Buffer.Pointer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Copy the actual buffer data */
+
+ memcpy (DestDesc->Buffer.Pointer,
+ SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+ /*
+ * Allocate and copy the actual string if and only if:
+ * 1) There is a valid string pointer
+ * (Pointer to a NULL string is allowed)
+ */
+ if (SourceDesc->String.Pointer)
+ {
+ DestDesc->String.Pointer =
+ ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
+ if (!DestDesc->String.Pointer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Copy the actual string data */
+
+ memcpy (DestDesc->String.Pointer, SourceDesc->String.Pointer,
+ (ACPI_SIZE) SourceDesc->String.Length + 1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ /*
+ * We copied the reference object, so we now must add a reference
+ * to the object pointed to by the reference
+ *
+ * DDBHandle reference (from Load/LoadTable) is a special reference,
+ * it does not have a Reference.Object, so does not need to
+ * increase the reference count
+ */
+ if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
+ {
+ break;
+ }
+
+ AcpiUtAddReference (SourceDesc->Reference.Object);
+ break;
+
+ case ACPI_TYPE_REGION:
+ /*
+ * We copied the Region Handler, so we now must add a reference
+ */
+ if (DestDesc->Region.Handler)
+ {
+ AcpiUtAddReference (DestDesc->Region.Handler);
+ }
+ break;
+
+ /*
+ * For Mutex and Event objects, we cannot simply copy the underlying
+ * OS object. We must create a new one.
+ */
+ case ACPI_TYPE_MUTEX:
+
+ Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_TYPE_EVENT:
+
+ Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
+ &DestDesc->Event.OsSemaphore);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ default:
+
+ /* Nothing to do for other simple objects */
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIelementToIelement
+ *
+ * PARAMETERS: ACPI_PKG_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyIelementToIelement (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT32 ThisIndex;
+ ACPI_OPERAND_OBJECT **ThisTargetPtr;
+ ACPI_OPERAND_OBJECT *TargetObject;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ ThisIndex = State->Pkg.Index;
+ ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
+ &State->Pkg.DestObject->Package.Elements[ThisIndex];
+
+ switch (ObjectType)
+ {
+ case ACPI_COPY_TYPE_SIMPLE:
+
+ /* A null source object indicates a (legal) null package element */
+
+ if (SourceObject)
+ {
+ /*
+ * This is a simple object, just copy it
+ */
+ TargetObject = AcpiUtCreateInternalObject (
+ SourceObject->Common.Type);
+ if (!TargetObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ *ThisTargetPtr = TargetObject;
+ }
+ else
+ {
+ /* Pass through a null element */
+
+ *ThisTargetPtr = NULL;
+ }
+ break;
+
+ case ACPI_COPY_TYPE_PACKAGE:
+ /*
+ * This object is a package - go down another nesting level
+ * Create and build the package object
+ */
+ TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count);
+ if (!TargetObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ TargetObject->Common.Flags = SourceObject->Common.Flags;
+
+ /* Pass the new package object back to the package walk routine */
+
+ State->Pkg.ThisTargetObj = TargetObject;
+
+ /* Store the object pointer in the parent package object */
+
+ *ThisTargetPtr = TargetObject;
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (Status);
+
+ErrorExit:
+ AcpiUtRemoveReference (TargetObject);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIpackageToIpackage
+ *
+ * PARAMETERS: SourceObj - Pointer to the source package object
+ * DestObj - Where the internal object is returned
+ * WalkState - Current Walk state descriptor
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to copy an internal package object
+ * into another internal package object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCopyIpackageToIpackage (
+ ACPI_OPERAND_OBJECT *SourceObj,
+ ACPI_OPERAND_OBJECT *DestObj,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
+
+
+ DestObj->Common.Type = SourceObj->Common.Type;
+ DestObj->Common.Flags = SourceObj->Common.Flags;
+ DestObj->Package.Count = SourceObj->Package.Count;
+
+ /*
+ * Create the object array and walk the source package tree
+ */
+ DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) SourceObj->Package.Count + 1) *
+ sizeof (void *));
+ if (!DestObj->Package.Elements)
+ {
+ ACPI_ERROR ((AE_INFO, "Package allocation failure"));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Copy the package element-by-element by walking the package "tree".
+ * This handles nested packages of arbitrary depth.
+ */
+ Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
+ AcpiUtCopyIelementToIelement, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ /* On failure, delete the destination package object */
+
+ AcpiUtRemoveReference (DestObj);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCopyIobjectToIobject
+ *
+ * PARAMETERS: SourceDesc - The internal object to be copied
+ * DestDesc - Where the copied object is returned
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy an internal object to a new internal object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCopyIobjectToIobject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT **DestDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
+
+
+ /* Create the top level object */
+
+ *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
+ if (!*DestDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy the object and possible subobjects */
+
+ if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc,
+ WalkState);
+ }
+ else
+ {
+ Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
+ }
+
+ /* Delete the allocated object if copy failed */
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference(*DestDesc);
+ }
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdebug.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdebug.c
new file mode 100644
index 0000000000..e91cc4d662
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdebug.c
@@ -0,0 +1,704 @@
+/******************************************************************************
+ *
+ * Module Name: utdebug - Debug print/trace routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utdebug")
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+static ACPI_THREAD_ID AcpiGbl_PrevThreadId = (ACPI_THREAD_ID) 0xFFFFFFFF;
+static char *AcpiGbl_FnEntryStr = "----Entry";
+static char *AcpiGbl_FnExitStr = "----Exit-";
+
+/* Local prototypes */
+
+static const char *
+AcpiUtTrimFunctionName (
+ const char *FunctionName);
+
+
+/*******************************************************************************
+ *
+ * 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_PrevThreadId)
+ {
+ if (ACPI_LV_THREADS & AcpiDbgLevel)
+ {
+ AcpiOsPrintf (
+ "\n**** Context Switch from TID %u to TID %u ****\n\n",
+ (UINT32) AcpiGbl_PrevThreadId, (UINT32) ThreadId);
+ }
+
+ AcpiGbl_PrevThreadId = 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_FnEntryStr);
+ }
+}
+
+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,
+ 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_FnEntryStr, 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,
+ 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_FnEntryStr, 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_FnEntryStr, 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_FnExitStr);
+ }
+
+ 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_FnExitStr,
+ AcpiFormatException (Status));
+ }
+ else
+ {
+ AcpiDebugPrint (ACPI_LV_FUNCTIONS,
+ LineNumber, FunctionName, ModuleName, ComponentId,
+ "%s ****Exception****: %s\n", AcpiGbl_FnExitStr,
+ 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_FnExitStr,
+ 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_FnExitStr, Ptr);
+ }
+
+ 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/boot/sys/contrib/dev/acpica/components/utilities/utdecode.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdecode.c
new file mode 100644
index 0000000000..c1887ee226
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdecode.c
@@ -0,0 +1,619 @@
+/******************************************************************************
+ *
+ * Module Name: utdecode - Utility decoding routines (value-to-string)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utdecode")
+
+
+/*
+ * Properties of the ACPI Object Types, both internal and external.
+ * The table is indexed by values of ACPI_OBJECT_TYPE
+ */
+const UINT8 AcpiGbl_NsProperties[ACPI_NUM_NS_TYPES] =
+{
+ ACPI_NS_NORMAL, /* 00 Any */
+ ACPI_NS_NORMAL, /* 01 Number */
+ ACPI_NS_NORMAL, /* 02 String */
+ ACPI_NS_NORMAL, /* 03 Buffer */
+ ACPI_NS_NORMAL, /* 04 Package */
+ ACPI_NS_NORMAL, /* 05 FieldUnit */
+ ACPI_NS_NEWSCOPE, /* 06 Device */
+ ACPI_NS_NORMAL, /* 07 Event */
+ ACPI_NS_NEWSCOPE, /* 08 Method */
+ ACPI_NS_NORMAL, /* 09 Mutex */
+ ACPI_NS_NORMAL, /* 10 Region */
+ ACPI_NS_NEWSCOPE, /* 11 Power */
+ ACPI_NS_NEWSCOPE, /* 12 Processor */
+ ACPI_NS_NEWSCOPE, /* 13 Thermal */
+ ACPI_NS_NORMAL, /* 14 BufferField */
+ ACPI_NS_NORMAL, /* 15 DdbHandle */
+ ACPI_NS_NORMAL, /* 16 Debug Object */
+ ACPI_NS_NORMAL, /* 17 DefField */
+ ACPI_NS_NORMAL, /* 18 BankField */
+ ACPI_NS_NORMAL, /* 19 IndexField */
+ ACPI_NS_NORMAL, /* 20 Reference */
+ ACPI_NS_NORMAL, /* 21 Alias */
+ ACPI_NS_NORMAL, /* 22 MethodAlias */
+ ACPI_NS_NORMAL, /* 23 Notify */
+ ACPI_NS_NORMAL, /* 24 Address Handler */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
+ ACPI_NS_NEWSCOPE, /* 27 Scope */
+ ACPI_NS_NORMAL, /* 28 Extra */
+ ACPI_NS_NORMAL, /* 29 Data */
+ ACPI_NS_NORMAL /* 30 Invalid */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetRegionName
+ *
+ * PARAMETERS: Space ID - ID for the region
+ *
+ * RETURN: Decoded region SpaceId name
+ *
+ * DESCRIPTION: Translate a Space ID into a name string (Debug only)
+ *
+ ******************************************************************************/
+
+/* Region type decoding */
+
+const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS] =
+{
+ "SystemMemory", /* 0x00 */
+ "SystemIO", /* 0x01 */
+ "PCI_Config", /* 0x02 */
+ "EmbeddedControl", /* 0x03 */
+ "SMBus", /* 0x04 */
+ "SystemCMOS", /* 0x05 */
+ "PCIBARTarget", /* 0x06 */
+ "IPMI", /* 0x07 */
+ "GeneralPurposeIo", /* 0x08 */
+ "GenericSerialBus", /* 0x09 */
+ "PCC" /* 0x0A */
+};
+
+
+char *
+AcpiUtGetRegionName (
+ UINT8 SpaceId)
+{
+
+ if (SpaceId >= ACPI_USER_REGION_BEGIN)
+ {
+ return ("UserDefinedRegion");
+ }
+ else if (SpaceId == ACPI_ADR_SPACE_DATA_TABLE)
+ {
+ return ("DataTable");
+ }
+ else if (SpaceId == ACPI_ADR_SPACE_FIXED_HARDWARE)
+ {
+ return ("FunctionalFixedHW");
+ }
+ else if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
+ {
+ return ("InvalidSpaceId");
+ }
+
+ return (ACPI_CAST_PTR (char, AcpiGbl_RegionTypes[SpaceId]));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetEventName
+ *
+ * PARAMETERS: EventId - Fixed event ID
+ *
+ * RETURN: Decoded event ID name
+ *
+ * DESCRIPTION: Translate a Event ID into a name string (Debug only)
+ *
+ ******************************************************************************/
+
+/* Event type decoding */
+
+static const char *AcpiGbl_EventTypes[ACPI_NUM_FIXED_EVENTS] =
+{
+ "PM_Timer",
+ "GlobalLock",
+ "PowerButton",
+ "SleepButton",
+ "RealTimeClock",
+};
+
+
+char *
+AcpiUtGetEventName (
+ UINT32 EventId)
+{
+
+ if (EventId > ACPI_EVENT_MAX)
+ {
+ return ("InvalidEventID");
+ }
+
+ return (ACPI_CAST_PTR (char, AcpiGbl_EventTypes[EventId]));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetTypeName
+ *
+ * PARAMETERS: Type - An ACPI object type
+ *
+ * RETURN: Decoded ACPI object type name
+ *
+ * DESCRIPTION: Translate a Type ID into a name string (Debug only)
+ *
+ ******************************************************************************/
+
+/*
+ * Elements of AcpiGbl_NsTypeNames below must match
+ * one-to-one with values of ACPI_OBJECT_TYPE
+ *
+ * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
+ * when stored in a table it really means that we have thus far seen no
+ * evidence to indicate what type is actually going to be stored for this entry.
+ */
+static const char AcpiGbl_BadType[] = "UNDEFINED";
+
+/* Printable names of the ACPI object types */
+
+static const char *AcpiGbl_NsTypeNames[] =
+{
+ /* 00 */ "Untyped",
+ /* 01 */ "Integer",
+ /* 02 */ "String",
+ /* 03 */ "Buffer",
+ /* 04 */ "Package",
+ /* 05 */ "FieldUnit",
+ /* 06 */ "Device",
+ /* 07 */ "Event",
+ /* 08 */ "Method",
+ /* 09 */ "Mutex",
+ /* 10 */ "Region",
+ /* 11 */ "Power",
+ /* 12 */ "Processor",
+ /* 13 */ "Thermal",
+ /* 14 */ "BufferField",
+ /* 15 */ "DdbHandle",
+ /* 16 */ "DebugObject",
+ /* 17 */ "RegionField",
+ /* 18 */ "BankField",
+ /* 19 */ "IndexField",
+ /* 20 */ "Reference",
+ /* 21 */ "Alias",
+ /* 22 */ "MethodAlias",
+ /* 23 */ "Notify",
+ /* 24 */ "AddrHandler",
+ /* 25 */ "ResourceDesc",
+ /* 26 */ "ResourceFld",
+ /* 27 */ "Scope",
+ /* 28 */ "Extra",
+ /* 29 */ "Data",
+ /* 30 */ "Invalid"
+};
+
+
+char *
+AcpiUtGetTypeName (
+ ACPI_OBJECT_TYPE Type)
+{
+
+ if (Type > ACPI_TYPE_INVALID)
+ {
+ return (ACPI_CAST_PTR (char, AcpiGbl_BadType));
+ }
+
+ return (ACPI_CAST_PTR (char, AcpiGbl_NsTypeNames[Type]));
+}
+
+
+char *
+AcpiUtGetObjectTypeName (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+
+ if (!ObjDesc)
+ {
+ return ("[NULL Object Descriptor]");
+ }
+
+ return (AcpiUtGetTypeName (ObjDesc->Common.Type));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetNodeName
+ *
+ * PARAMETERS: Object - A namespace node
+ *
+ * RETURN: ASCII name of the node
+ *
+ * DESCRIPTION: Validate the node and return the node's ACPI name.
+ *
+ ******************************************************************************/
+
+char *
+AcpiUtGetNodeName (
+ void *Object)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) Object;
+
+
+ /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
+
+ if (!Object)
+ {
+ return ("NULL");
+ }
+
+ /* Check for Root node */
+
+ if ((Object == ACPI_ROOT_OBJECT) ||
+ (Object == AcpiGbl_RootNode))
+ {
+ return ("\"\\\" ");
+ }
+
+ /* Descriptor must be a namespace node */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ return ("####");
+ }
+
+ /*
+ * Ensure name is valid. The name was validated/repaired when the node
+ * was created, but make sure it has not been corrupted.
+ */
+ AcpiUtRepairName (Node->Name.Ascii);
+
+ /* Return the name */
+
+ return (Node->Name.Ascii);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetDescriptorName
+ *
+ * PARAMETERS: Object - An ACPI object
+ *
+ * RETURN: Decoded name of the descriptor type
+ *
+ * DESCRIPTION: Validate object and return the descriptor type
+ *
+ ******************************************************************************/
+
+/* Printable names of object descriptor types */
+
+static const char *AcpiGbl_DescTypeNames[] =
+{
+ /* 00 */ "Not a Descriptor",
+ /* 01 */ "Cached",
+ /* 02 */ "State-Generic",
+ /* 03 */ "State-Update",
+ /* 04 */ "State-Package",
+ /* 05 */ "State-Control",
+ /* 06 */ "State-RootParseScope",
+ /* 07 */ "State-ParseScope",
+ /* 08 */ "State-WalkScope",
+ /* 09 */ "State-Result",
+ /* 10 */ "State-Notify",
+ /* 11 */ "State-Thread",
+ /* 12 */ "Walk",
+ /* 13 */ "Parser",
+ /* 14 */ "Operand",
+ /* 15 */ "Node"
+};
+
+
+char *
+AcpiUtGetDescriptorName (
+ void *Object)
+{
+
+ if (!Object)
+ {
+ return ("NULL OBJECT");
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) > ACPI_DESC_TYPE_MAX)
+ {
+ return ("Not a Descriptor");
+ }
+
+ return (ACPI_CAST_PTR (char,
+ AcpiGbl_DescTypeNames[ACPI_GET_DESCRIPTOR_TYPE (Object)]));
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetReferenceName
+ *
+ * PARAMETERS: Object - An ACPI reference object
+ *
+ * RETURN: Decoded name of the type of reference
+ *
+ * DESCRIPTION: Decode a reference object sub-type to a string.
+ *
+ ******************************************************************************/
+
+/* Printable names of reference object sub-types */
+
+static const char *AcpiGbl_RefClassNames[] =
+{
+ /* 00 */ "Local",
+ /* 01 */ "Argument",
+ /* 02 */ "RefOf",
+ /* 03 */ "Index",
+ /* 04 */ "DdbHandle",
+ /* 05 */ "Named Object",
+ /* 06 */ "Debug"
+};
+
+const char *
+AcpiUtGetReferenceName (
+ ACPI_OPERAND_OBJECT *Object)
+{
+
+ if (!Object)
+ {
+ return ("NULL Object");
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
+ {
+ return ("Not an Operand object");
+ }
+
+ if (Object->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ return ("Not a Reference object");
+ }
+
+ if (Object->Reference.Class > ACPI_REFCLASS_MAX)
+ {
+ return ("Unknown Reference class");
+ }
+
+ return (AcpiGbl_RefClassNames[Object->Reference.Class]);
+}
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+/*
+ * Strings and procedures used for debug only
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetMutexName
+ *
+ * PARAMETERS: MutexId - The predefined ID for this mutex.
+ *
+ * RETURN: Decoded name of the internal mutex
+ *
+ * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
+ *
+ ******************************************************************************/
+
+/* Names for internal mutex objects, used for debug output */
+
+static char *AcpiGbl_MutexNames[ACPI_NUM_MUTEX] =
+{
+ "ACPI_MTX_Interpreter",
+ "ACPI_MTX_Namespace",
+ "ACPI_MTX_Tables",
+ "ACPI_MTX_Events",
+ "ACPI_MTX_Caches",
+ "ACPI_MTX_Memory",
+ "ACPI_MTX_CommandComplete",
+ "ACPI_MTX_CommandReady"
+};
+
+char *
+AcpiUtGetMutexName (
+ UINT32 MutexId)
+{
+
+ if (MutexId > ACPI_MAX_MUTEX)
+ {
+ return ("Invalid Mutex ID");
+ }
+
+ return (AcpiGbl_MutexNames[MutexId]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetNotifyName
+ *
+ * PARAMETERS: NotifyValue - Value from the Notify() request
+ *
+ * RETURN: Decoded name for the notify value
+ *
+ * DESCRIPTION: Translate a Notify Value to a notify namestring.
+ *
+ ******************************************************************************/
+
+/* Names for Notify() values, used for debug output */
+
+static const char *AcpiGbl_GenericNotify[ACPI_NOTIFY_MAX + 1] =
+{
+ /* 00 */ "Bus Check",
+ /* 01 */ "Device Check",
+ /* 02 */ "Device Wake",
+ /* 03 */ "Eject Request",
+ /* 04 */ "Device Check Light",
+ /* 05 */ "Frequency Mismatch",
+ /* 06 */ "Bus Mode Mismatch",
+ /* 07 */ "Power Fault",
+ /* 08 */ "Capabilities Check",
+ /* 09 */ "Device PLD Check",
+ /* 0A */ "Reserved",
+ /* 0B */ "System Locality Update",
+ /* 0C */ "Shutdown Request",
+ /* 0D */ "System Resource Affinity Update"
+};
+
+static const char *AcpiGbl_DeviceNotify[4] =
+{
+ /* 80 */ "Status Change",
+ /* 81 */ "Information Change",
+ /* 82 */ "Device-Specific Change",
+ /* 83 */ "Device-Specific Change"
+};
+
+static const char *AcpiGbl_ProcessorNotify[4] =
+{
+ /* 80 */ "Performance Capability Change",
+ /* 81 */ "C-State Change",
+ /* 82 */ "Throttling Capability Change",
+ /* 83 */ "Device-Specific Change"
+};
+
+static const char *AcpiGbl_ThermalNotify[4] =
+{
+ /* 80 */ "Thermal Status Change",
+ /* 81 */ "Thermal Trip Point Change",
+ /* 82 */ "Thermal Device List Change",
+ /* 83 */ "Thermal Relationship Change"
+};
+
+
+const char *
+AcpiUtGetNotifyName (
+ UINT32 NotifyValue,
+ ACPI_OBJECT_TYPE Type)
+{
+
+ /* 00 - 0D are common to all object types */
+
+ if (NotifyValue <= ACPI_NOTIFY_MAX)
+ {
+ return (AcpiGbl_GenericNotify[NotifyValue]);
+ }
+
+ /* 0D - 7F are reserved */
+
+ if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
+ {
+ return ("Reserved");
+ }
+
+ /* 80 - 83 are per-object-type */
+
+ if (NotifyValue <= 0x83)
+ {
+ switch (Type)
+ {
+ case ACPI_TYPE_ANY:
+ case ACPI_TYPE_DEVICE:
+ return (AcpiGbl_DeviceNotify [NotifyValue - 0x80]);
+
+ case ACPI_TYPE_PROCESSOR:
+ return (AcpiGbl_ProcessorNotify [NotifyValue - 0x80]);
+
+ case ACPI_TYPE_THERMAL:
+ return (AcpiGbl_ThermalNotify [NotifyValue - 0x80]);
+
+ default:
+ return ("Target object type does not support notifies");
+ }
+ }
+
+ /* 84 - BF are device-specific */
+
+ if (NotifyValue <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY)
+ {
+ return ("Device-Specific");
+ }
+
+ /* C0 and above are hardware-specific */
+
+ return ("Hardware-Specific");
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidObjectType
+ *
+ * PARAMETERS: Type - Object type to be validated
+ *
+ * RETURN: TRUE if valid object type, FALSE otherwise
+ *
+ * DESCRIPTION: Validate an object type
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtValidObjectType (
+ ACPI_OBJECT_TYPE Type)
+{
+
+ if (Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ /* Note: Assumes all TYPEs are contiguous (external/local) */
+
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdelete.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdelete.c
new file mode 100644
index 0000000000..837a3f1966
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utdelete.c
@@ -0,0 +1,810 @@
+/*******************************************************************************
+ *
+ * Module Name: utdelete - object deletion and reference count utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utdelete")
+
+/* Local prototypes */
+
+static void
+AcpiUtDeleteInternalObj (
+ ACPI_OPERAND_OBJECT *Object);
+
+static void
+AcpiUtUpdateRefCount (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT32 Action);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteInternalObj
+ *
+ * PARAMETERS: Object - Object to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Low level object deletion, after reference counts have been
+ * updated (All reference counts, including sub-objects!)
+ *
+ ******************************************************************************/
+
+static void
+AcpiUtDeleteInternalObj (
+ ACPI_OPERAND_OBJECT *Object)
+{
+ void *ObjPointer = NULL;
+ ACPI_OPERAND_OBJECT *HandlerDesc;
+ ACPI_OPERAND_OBJECT *SecondDesc;
+ ACPI_OPERAND_OBJECT *NextDesc;
+ ACPI_OPERAND_OBJECT *StartDesc;
+ ACPI_OPERAND_OBJECT **LastObjPtr;
+
+
+ ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object);
+
+
+ if (!Object)
+ {
+ return_VOID;
+ }
+
+ /*
+ * Must delete or free any pointers within the object that are not
+ * actual ACPI objects (for example, a raw buffer pointer).
+ */
+ switch (Object->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
+ Object, Object->String.Pointer));
+
+ /* Free the actual string buffer */
+
+ if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
+ {
+ /* But only if it is NOT a pointer into an ACPI table */
+
+ ObjPointer = Object->String.Pointer;
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
+ Object, Object->Buffer.Pointer));
+
+ /* Free the actual buffer */
+
+ if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
+ {
+ /* But only if it is NOT a pointer into an ACPI table */
+
+ ObjPointer = Object->Buffer.Pointer;
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
+ Object->Package.Count));
+
+ /*
+ * Elements of the package are not handled here, they are deleted
+ * separately
+ */
+
+ /* Free the (variable length) element pointer array */
+
+ ObjPointer = Object->Package.Elements;
+ break;
+
+ /*
+ * These objects have a possible list of notify handlers.
+ * Device object also may have a GPE block.
+ */
+ case ACPI_TYPE_DEVICE:
+
+ if (Object->Device.GpeBlock)
+ {
+ (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
+ }
+
+ /*lint -fallthrough */
+
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_THERMAL:
+
+ /* Walk the address handler list for this object */
+
+ HandlerDesc = Object->CommonNotify.Handler;
+ while (HandlerDesc)
+ {
+ NextDesc = HandlerDesc->AddressSpace.Next;
+ AcpiUtRemoveReference (HandlerDesc);
+ HandlerDesc = NextDesc;
+ }
+ break;
+
+ case ACPI_TYPE_MUTEX:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Mutex %p, OS Mutex %p\n",
+ Object, Object->Mutex.OsMutex));
+
+ if (Object == AcpiGbl_GlobalLockMutex)
+ {
+ /* Global Lock has extra semaphore */
+
+ (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
+ AcpiGbl_GlobalLockSemaphore = NULL;
+
+ AcpiOsDeleteMutex (Object->Mutex.OsMutex);
+ AcpiGbl_GlobalLockMutex = NULL;
+ }
+ else
+ {
+ AcpiExUnlinkMutex (Object);
+ AcpiOsDeleteMutex (Object->Mutex.OsMutex);
+ }
+ break;
+
+ case ACPI_TYPE_EVENT:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Event %p, OS Semaphore %p\n",
+ Object, Object->Event.OsSemaphore));
+
+ (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
+ Object->Event.OsSemaphore = NULL;
+ break;
+
+ case ACPI_TYPE_METHOD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Method %p\n", Object));
+
+ /* Delete the method mutex if it exists */
+
+ if (Object->Method.Mutex)
+ {
+ AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
+ AcpiUtDeleteObjectDesc (Object->Method.Mutex);
+ Object->Method.Mutex = NULL;
+ }
+ if (Object->Method.Node)
+ {
+ Object->Method.Node = NULL;
+ }
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Region %p\n", Object));
+
+ /*
+ * Update AddressRange list. However, only permanent regions
+ * are installed in this list. (Not created within a method)
+ */
+ if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
+ {
+ AcpiUtRemoveAddressRange (Object->Region.SpaceId,
+ Object->Region.Node);
+ }
+
+ SecondDesc = AcpiNsGetSecondaryObject (Object);
+ if (SecondDesc)
+ {
+ /*
+ * Free the RegionContext if and only if the handler is one of the
+ * default handlers -- and therefore, we created the context object
+ * locally, it was not created by an external caller.
+ */
+ HandlerDesc = Object->Region.Handler;
+ if (HandlerDesc)
+ {
+ NextDesc = HandlerDesc->AddressSpace.RegionList;
+ StartDesc = NextDesc;
+ LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
+
+ /* Remove the region object from the handler list */
+
+ while (NextDesc)
+ {
+ if (NextDesc == Object)
+ {
+ *LastObjPtr = NextDesc->Region.Next;
+ break;
+ }
+
+ /* Walk the linked list of handlers */
+
+ LastObjPtr = &NextDesc->Region.Next;
+ NextDesc = NextDesc->Region.Next;
+
+ /* Prevent infinite loop if list is corrupted */
+
+ if (NextDesc == StartDesc)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Circular region list in address handler object %p",
+ HandlerDesc));
+ return_VOID;
+ }
+ }
+
+ if (HandlerDesc->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+ {
+ /* Deactivate region and free region context */
+
+ if (HandlerDesc->AddressSpace.Setup)
+ {
+ (void) HandlerDesc->AddressSpace.Setup (Object,
+ ACPI_REGION_DEACTIVATE,
+ HandlerDesc->AddressSpace.Context,
+ &SecondDesc->Extra.RegionContext);
+ }
+ }
+
+ AcpiUtRemoveReference (HandlerDesc);
+ }
+
+ /* Now we can free the Extra object */
+
+ AcpiUtDeleteObjectDesc (SecondDesc);
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Buffer Field %p\n", Object));
+
+ SecondDesc = AcpiNsGetSecondaryObject (Object);
+ if (SecondDesc)
+ {
+ AcpiUtDeleteObjectDesc (SecondDesc);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Bank Field %p\n", Object));
+
+ SecondDesc = AcpiNsGetSecondaryObject (Object);
+ if (SecondDesc)
+ {
+ AcpiUtDeleteObjectDesc (SecondDesc);
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Free any allocated memory (pointer within the object) found above */
+
+ if (ObjPointer)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
+ ObjPointer));
+ ACPI_FREE (ObjPointer);
+ }
+
+ /* Now the object can be safely deleted */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
+ Object, AcpiUtGetObjectTypeName (Object)));
+
+ AcpiUtDeleteObjectDesc (Object);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteInternalObjectList
+ *
+ * PARAMETERS: ObjList - Pointer to the list to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: This function deletes an internal object list, including both
+ * simple objects and package objects
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDeleteInternalObjectList (
+ ACPI_OPERAND_OBJECT **ObjList)
+{
+ ACPI_OPERAND_OBJECT **InternalObj;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Walk the null-terminated internal list */
+
+ for (InternalObj = ObjList; *InternalObj; InternalObj++)
+ {
+ AcpiUtRemoveReference (*InternalObj);
+ }
+
+ /* Free the combined parameter pointer list and object array */
+
+ ACPI_FREE (ObjList);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtUpdateRefCount
+ *
+ * PARAMETERS: Object - Object whose ref count is to be updated
+ * Action - What to do (REF_INCREMENT or REF_DECREMENT)
+ *
+ * RETURN: None. Sets new reference count within the object
+ *
+ * DESCRIPTION: Modify the reference count for an internal acpi object
+ *
+ ******************************************************************************/
+
+static void
+AcpiUtUpdateRefCount (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT32 Action)
+{
+ UINT16 OriginalCount;
+ UINT16 NewCount = 0;
+ ACPI_CPU_FLAGS LockFlags;
+
+
+ ACPI_FUNCTION_NAME (UtUpdateRefCount);
+
+
+ if (!Object)
+ {
+ return;
+ }
+
+ /*
+ * Always get the reference count lock. Note: Interpreter and/or
+ * Namespace is not always locked when this function is called.
+ */
+ LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
+ OriginalCount = Object->Common.ReferenceCount;
+
+ /* Perform the reference count action (increment, decrement) */
+
+ switch (Action)
+ {
+ case REF_INCREMENT:
+
+ NewCount = OriginalCount + 1;
+ Object->Common.ReferenceCount = NewCount;
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+
+ /* The current reference count should never be zero here */
+
+ if (!OriginalCount)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Obj %p, Reference Count was zero before increment\n",
+ Object));
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Type %.2X Refs %.2X [Incremented]\n",
+ Object, Object->Common.Type, NewCount));
+ break;
+
+ case REF_DECREMENT:
+
+ /* The current reference count must be non-zero */
+
+ if (OriginalCount)
+ {
+ NewCount = OriginalCount - 1;
+ Object->Common.ReferenceCount = NewCount;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+
+ if (!OriginalCount)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Obj %p, Reference Count is already zero, cannot decrement\n",
+ Object));
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Type %.2X Refs %.2X [Decremented]\n",
+ Object, Object->Common.Type, NewCount));
+
+ /* Actually delete the object on a reference count of zero */
+
+ if (NewCount == 0)
+ {
+ AcpiUtDeleteInternalObj (Object);
+ }
+ break;
+
+ default:
+
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
+ Action));
+ return;
+ }
+
+ /*
+ * Sanity check the reference count, for debug purposes only.
+ * (A deleted object will have a huge reference count)
+ */
+ if (NewCount > ACPI_MAX_REFERENCE_COUNT)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
+ NewCount, Object, Object->Common.Type));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtUpdateObjectReference
+ *
+ * PARAMETERS: Object - Increment ref count for this object
+ * and all sub-objects
+ * Action - Either REF_INCREMENT or REF_DECREMENT
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Increment the object reference count
+ *
+ * Object references are incremented when:
+ * 1) An object is attached to a Node (namespace object)
+ * 2) An object is copied (all subobjects must be incremented)
+ *
+ * Object references are decremented when:
+ * 1) An object is detached from an Node
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtUpdateObjectReference (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *StateList = NULL;
+ ACPI_OPERAND_OBJECT *NextObject = NULL;
+ ACPI_OPERAND_OBJECT *PrevObject;
+ ACPI_GENERIC_STATE *State;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (UtUpdateObjectReference);
+
+
+ while (Object)
+ {
+ /* Make sure that this isn't a namespace handle */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Object %p is NS handle\n", Object));
+ return (AE_OK);
+ }
+
+ /*
+ * All sub-objects must have their reference count incremented also.
+ * Different object types have different subobjects.
+ */
+ switch (Object->Common.Type)
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_THERMAL:
+ /*
+ * Update the notify objects for these types (if present)
+ * Two lists, system and device notify handlers.
+ */
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ PrevObject = Object->CommonNotify.NotifyList[i];
+ while (PrevObject)
+ {
+ NextObject = PrevObject->Notify.Next[i];
+ AcpiUtUpdateRefCount (PrevObject, Action);
+ PrevObject = NextObject;
+ }
+ }
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * We must update all the sub-objects of the package,
+ * each of whom may have their own sub-objects.
+ */
+ for (i = 0; i < Object->Package.Count; i++)
+ {
+ /*
+ * Null package elements are legal and can be simply
+ * ignored.
+ */
+ NextObject = Object->Package.Elements[i];
+ if (!NextObject)
+ {
+ continue;
+ }
+
+ switch (NextObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * For these very simple sub-objects, we can just
+ * update the reference count here and continue.
+ * Greatly increases performance of this operation.
+ */
+ AcpiUtUpdateRefCount (NextObject, Action);
+ break;
+
+ default:
+ /*
+ * For complex sub-objects, push them onto the stack
+ * for later processing (this eliminates recursion.)
+ */
+ Status = AcpiUtCreateUpdateStateAndPush (
+ NextObject, Action, &StateList);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+ break;
+ }
+ }
+ NextObject = NULL;
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ NextObject = Object->BufferField.BufferObj;
+ break;
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ NextObject = Object->Field.RegionObj;
+ break;
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ NextObject = Object->BankField.BankObj;
+ Status = AcpiUtCreateUpdateStateAndPush (
+ Object->BankField.RegionObj, Action, &StateList);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ NextObject = Object->IndexField.IndexObj;
+ Status = AcpiUtCreateUpdateStateAndPush (
+ Object->IndexField.DataObj, Action, &StateList);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ /*
+ * The target of an Index (a package, string, or buffer) or a named
+ * reference must track changes to the ref count of the index or
+ * target object.
+ */
+ if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
+ (Object->Reference.Class== ACPI_REFCLASS_NAME))
+ {
+ NextObject = Object->Reference.Object;
+ }
+ break;
+
+ case ACPI_TYPE_REGION:
+ default:
+
+ break; /* No subobjects for all other types */
+ }
+
+ /*
+ * Now we can update the count in the main object. This can only
+ * happen after we update the sub-objects in case this causes the
+ * main object to be deleted.
+ */
+ AcpiUtUpdateRefCount (Object, Action);
+ Object = NULL;
+
+ /* Move on to the next object to be updated */
+
+ if (NextObject)
+ {
+ Object = NextObject;
+ NextObject = NULL;
+ }
+ else if (StateList)
+ {
+ State = AcpiUtPopGenericState (&StateList);
+ Object = State->Update.Object;
+ AcpiUtDeleteGenericState (State);
+ }
+ }
+
+ return (AE_OK);
+
+
+ErrorExit:
+
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not update object reference count"));
+
+ /* Free any stacked Update State objects */
+
+ while (StateList)
+ {
+ State = AcpiUtPopGenericState (&StateList);
+ AcpiUtDeleteGenericState (State);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAddReference
+ *
+ * PARAMETERS: Object - Object whose reference count is to be
+ * incremented
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add one reference to an ACPI object
+ *
+ ******************************************************************************/
+
+void
+AcpiUtAddReference (
+ ACPI_OPERAND_OBJECT *Object)
+{
+
+ ACPI_FUNCTION_NAME (UtAddReference);
+
+
+ /* Ensure that we have a valid object */
+
+ if (!AcpiUtValidInternalObject (Object))
+ {
+ return;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Incremented]\n",
+ Object, Object->Common.ReferenceCount));
+
+ /* Increment the reference count */
+
+ (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveReference
+ *
+ * PARAMETERS: Object - Object whose ref count will be decremented
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decrement the reference count of an ACPI internal object
+ *
+ ******************************************************************************/
+
+void
+AcpiUtRemoveReference (
+ ACPI_OPERAND_OBJECT *Object)
+{
+
+ ACPI_FUNCTION_NAME (UtRemoveReference);
+
+
+ /*
+ * Allow a NULL pointer to be passed in, just ignore it. This saves
+ * each caller from having to check. Also, ignore NS nodes.
+ */
+ if (!Object ||
+ (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
+
+ {
+ return;
+ }
+
+ /* Ensure that we have a valid object */
+
+ if (!AcpiUtValidInternalObject (Object))
+ {
+ return;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Decremented]\n",
+ Object, Object->Common.ReferenceCount));
+
+ /*
+ * Decrement the reference count, and only actually delete the object
+ * if the reference count becomes 0. (Must also decrement the ref count
+ * of all subobjects!)
+ */
+ (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uterror.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uterror.c
new file mode 100644
index 0000000000..35e9ce67db
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uterror.c
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ *
+ * Module Name: uterror - Various internal error/warning output functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("uterror")
+
+
+/*
+ * This module contains internal error functions that may
+ * be configured out.
+ */
+#if !defined (ACPI_NO_ERROR_MESSAGES)
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPredefinedWarning
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Pathname - Full pathname to the node
+ * NodeFlags - From Namespace node for the method/object
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Warnings for the predefined validation module. Messages are
+ * only emitted the first time a problem with a particular
+ * method/object is detected. This prevents a flood of error
+ * messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ /*
+ * Warning messages for this method/object will be disabled after the
+ * first time a validation fails or an object is successfully repaired.
+ */
+ if (NodeFlags & ANOBJ_EVALUATED)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (ACPI_MSG_WARNING "%s: ", Pathname);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPredefinedInfo
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Pathname - Full pathname to the node
+ * NodeFlags - From Namespace node for the method/object
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Info messages for the predefined validation module. Messages
+ * are only emitted the first time a problem with a particular
+ * method/object is detected. This prevents a flood of
+ * messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedInfo (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ /*
+ * Warning messages for this method/object will be disabled after the
+ * first time a validation fails or an object is successfully repaired.
+ */
+ if (NodeFlags & ANOBJ_EVALUATED)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (ACPI_MSG_INFO "%s: ", Pathname);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPredefinedBiosError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Pathname - Full pathname to the node
+ * NodeFlags - From Namespace node for the method/object
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: BIOS error message for predefined names. Messages
+ * are only emitted the first time a problem with a particular
+ * method/object is detected. This prevents a flood of
+ * messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ /*
+ * Warning messages for this method/object will be disabled after the
+ * first time a validation fails or an object is successfully repaired.
+ */
+ if (NodeFlags & ANOBJ_EVALUATED)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (ACPI_MSG_BIOS_ERROR "%s: ", Pathname);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtNamespaceError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * InternalName - Name or path of the namespace node
+ * LookupStatus - Exception code from NS lookup
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the NS node.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtNamespaceError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *InternalName,
+ ACPI_STATUS LookupStatus)
+{
+ ACPI_STATUS Status;
+ UINT32 BadName;
+ char *Name = NULL;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_ERROR);
+
+ if (LookupStatus == AE_BAD_CHARACTER)
+ {
+ /* There is a non-ascii character in the name */
+
+ ACPI_MOVE_32_TO_32 (&BadName, ACPI_CAST_PTR (UINT32, InternalName));
+ AcpiOsPrintf ("[0x%.8X] (NON-ASCII)", BadName);
+ }
+ else
+ {
+ /* Convert path to external format */
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX,
+ InternalName, NULL, &Name);
+
+ /* Print target name */
+
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("[%s]", Name);
+ }
+ else
+ {
+ AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]");
+ }
+
+ if (Name)
+ {
+ ACPI_FREE (Name);
+ }
+ }
+
+ AcpiOsPrintf (" Namespace lookup failure, %s",
+ AcpiFormatException (LookupStatus));
+
+ ACPI_MSG_SUFFIX;
+ ACPI_MSG_REDIRECT_END;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtMethodError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Message - Error message to use on failure
+ * PrefixNode - Prefix relative to the path
+ * Path - Path to the node (optional)
+ * MethodStatus - Execution status
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the method.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtMethodError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Message,
+ ACPI_NAMESPACE_NODE *PrefixNode,
+ const char *Path,
+ ACPI_STATUS MethodStatus)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node = PrefixNode;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_ERROR);
+
+ if (Path)
+ {
+ Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH,
+ &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("[Could not get node by pathname]");
+ }
+ }
+
+ AcpiNsPrintNodePathname (Node, Message);
+ AcpiOsPrintf (", %s", AcpiFormatException (MethodStatus));
+
+ ACPI_MSG_SUFFIX;
+ ACPI_MSG_REDIRECT_END;
+}
+
+#endif /* ACPI_NO_ERROR_MESSAGES */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uteval.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uteval.c
new file mode 100644
index 0000000000..b9d63b4552
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uteval.c
@@ -0,0 +1,379 @@
+/******************************************************************************
+ *
+ * Module Name: uteval - Object evaluation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("uteval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtEvaluateObject
+ *
+ * PARAMETERS: PrefixNode - Starting node
+ * Path - Path to object from starting node
+ * ExpectedReturnTypes - Bitmap of allowed return types
+ * ReturnDesc - Where a return value is stored
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Evaluates a namespace object and verifies the type of the
+ * return object. Common code that simplifies accessing objects
+ * that have required return objects of fixed types.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtEvaluateObject (
+ ACPI_NAMESPACE_NODE *PrefixNode,
+ char *Path,
+ UINT32 ExpectedReturnBtypes,
+ ACPI_OPERAND_OBJECT **ReturnDesc)
+{
+ ACPI_EVALUATE_INFO *Info;
+ ACPI_STATUS Status;
+ UINT32 ReturnBtype;
+
+
+ ACPI_FUNCTION_TRACE (UtEvaluateObject);
+
+
+ /* Allocate the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Info->PrefixNode = PrefixNode;
+ Info->RelativePathname = Path;
+
+ /* Evaluate the object/method */
+
+ Status = AcpiNsEvaluate (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_NOT_FOUND)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
+ AcpiUtGetNodeName (PrefixNode), Path));
+ }
+ else
+ {
+ ACPI_ERROR_METHOD ("Method execution failed",
+ PrefixNode, Path, Status);
+ }
+
+ goto Cleanup;
+ }
+
+ /* Did we get a return object? */
+
+ if (!Info->ReturnObject)
+ {
+ if (ExpectedReturnBtypes)
+ {
+ ACPI_ERROR_METHOD ("No object was returned from",
+ PrefixNode, Path, AE_NOT_EXIST);
+
+ Status = AE_NOT_EXIST;
+ }
+
+ goto Cleanup;
+ }
+
+ /* Map the return object type to the bitmapped type */
+
+ switch ((Info->ReturnObject)->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ ReturnBtype = ACPI_BTYPE_INTEGER;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ReturnBtype = ACPI_BTYPE_BUFFER;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ ReturnBtype = ACPI_BTYPE_STRING;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ReturnBtype = ACPI_BTYPE_PACKAGE;
+ break;
+
+ default:
+
+ ReturnBtype = 0;
+ break;
+ }
+
+ if ((AcpiGbl_EnableInterpreterSlack) &&
+ (!ExpectedReturnBtypes))
+ {
+ /*
+ * We received a return object, but one was not expected. This can
+ * happen frequently if the "implicit return" feature is enabled.
+ * Just delete the return object and return AE_OK.
+ */
+ AcpiUtRemoveReference (Info->ReturnObject);
+ goto Cleanup;
+ }
+
+ /* Is the return object one of the expected types? */
+
+ if (!(ExpectedReturnBtypes & ReturnBtype))
+ {
+ ACPI_ERROR_METHOD ("Return object type is incorrect",
+ PrefixNode, Path, AE_TYPE);
+
+ ACPI_ERROR ((AE_INFO,
+ "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
+ Path, AcpiUtGetObjectTypeName (Info->ReturnObject),
+ ExpectedReturnBtypes));
+
+ /* On error exit, we must delete the return object */
+
+ AcpiUtRemoveReference (Info->ReturnObject);
+ Status = AE_TYPE;
+ goto Cleanup;
+ }
+
+ /* Object type is OK, return it */
+
+ *ReturnDesc = Info->ReturnObject;
+
+Cleanup:
+ ACPI_FREE (Info);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtEvaluateNumericObject
+ *
+ * PARAMETERS: ObjectName - Object name to be evaluated
+ * DeviceNode - Node for the device
+ * Value - Where the value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Evaluates a numeric namespace object for a selected device
+ * and stores result in *Value.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtEvaluateNumericObject (
+ char *ObjectName,
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ UINT64 *Value)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtEvaluateNumericObject);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, ObjectName,
+ ACPI_BTYPE_INTEGER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the returned Integer */
+
+ *Value = ObjDesc->Integer.Value;
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_STA
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * Flags - Where the status flags are returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ * *Flags. If _STA does not exist, then the device is assumed
+ * to be present/functional/enabled (as per the ACPI spec).
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_STA (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ UINT32 *Flags)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_STA);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA,
+ ACPI_BTYPE_INTEGER, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ if (AE_NOT_FOUND == Status)
+ {
+ /*
+ * if _STA does not exist, then (as per the ACPI specification),
+ * the returned flags will indicate that the device is present,
+ * functional, and enabled.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "_STA on %4.4s was not found, assuming device is present\n",
+ AcpiUtGetNodeName (DeviceNode)));
+
+ *Flags = ACPI_UINT32_MAX;
+ Status = AE_OK;
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Extract the status flags */
+
+ *Flags = (UINT32) ObjDesc->Integer.Value;
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecutePowerMethods
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * MethodNames - Array of power method names
+ * MethodCount - Number of methods to execute
+ * OutValues - Where the power method values are returned
+ *
+ * RETURN: Status, OutValues
+ *
+ * DESCRIPTION: Executes the specified power methods for the device and returns
+ * the result(s).
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecutePowerMethods (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ const char **MethodNames,
+ UINT8 MethodCount,
+ UINT8 *OutValues)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_STATUS FinalStatus = AE_NOT_FOUND;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (UtExecutePowerMethods);
+
+
+ for (i = 0; i < MethodCount; i++)
+ {
+ /*
+ * Execute the power method (_SxD or _SxW). The only allowable
+ * return type is an Integer.
+ */
+ Status = AcpiUtEvaluateObject (DeviceNode,
+ ACPI_CAST_PTR (char, MethodNames[i]),
+ ACPI_BTYPE_INTEGER, &ObjDesc);
+ if (ACPI_SUCCESS (Status))
+ {
+ OutValues[i] = (UINT8) ObjDesc->Integer.Value;
+
+ /* Delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ FinalStatus = AE_OK; /* At least one value is valid */
+ continue;
+ }
+
+ OutValues[i] = ACPI_UINT8_MAX;
+ if (Status == AE_NOT_FOUND)
+ {
+ continue; /* Ignore if not found */
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n",
+ ACPI_CAST_PTR (char, MethodNames[i]),
+ AcpiUtGetNodeName (DeviceNode), AcpiFormatException (Status)));
+ }
+
+ return_ACPI_STATUS (FinalStatus);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utexcep.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utexcep.c
new file mode 100644
index 0000000000..2a38cfff27
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utexcep.c
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ *
+ * Module Name: utexcep - Exception code support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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/boot/sys/contrib/dev/acpica/components/utilities/utfileio.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utfileio.c
new file mode 100644
index 0000000000..a0075adee1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utfileio.c
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ *
+ * Module Name: utfileio - simple file I/O routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <contrib/dev/acpica/include/acapps.h>
+
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#endif
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("utfileio")
+
+
+#ifdef ACPI_APPLICATION
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtCheckTextModeCorruption (
+ UINT8 *Table,
+ UINT32 TableLength,
+ UINT32 FileLength);
+
+static ACPI_STATUS
+AcpiUtReadTable (
+ FILE *fp,
+ ACPI_TABLE_HEADER **Table,
+ UINT32 *TableLength);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCheckTextModeCorruption
+ *
+ * PARAMETERS: Table - Table buffer
+ * TableLength - Length of table from the table header
+ * FileLength - Length of the file that contains the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check table for text mode file corruption where all linefeed
+ * characters (LF) have been replaced by carriage return linefeed
+ * pairs (CR/LF).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCheckTextModeCorruption (
+ UINT8 *Table,
+ UINT32 TableLength,
+ UINT32 FileLength)
+{
+ UINT32 i;
+ UINT32 Pairs = 0;
+
+
+ if (TableLength != FileLength)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "File length (0x%X) is not the same as the table length (0x%X)",
+ FileLength, TableLength));
+ }
+
+ /* Scan entire table to determine if each LF has been prefixed with a CR */
+
+ for (i = 1; i < FileLength; i++)
+ {
+ if (Table[i] == 0x0A)
+ {
+ if (Table[i - 1] != 0x0D)
+ {
+ /* The LF does not have a preceding CR, table not corrupted */
+
+ return (AE_OK);
+ }
+ else
+ {
+ /* Found a CR/LF pair */
+
+ Pairs++;
+ }
+ i++;
+ }
+ }
+
+ if (!Pairs)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Entire table scanned, each CR is part of a CR/LF pair --
+ * meaning that the table was treated as a text file somewhere.
+ *
+ * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
+ * original table are left untouched by the text conversion process --
+ * meaning that we cannot simply replace CR/LF pairs with LFs.
+ */
+ AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
+ AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
+ AcpiOsPrintf ("Table cannot be repaired!\n");
+ return (AE_BAD_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtReadTable
+ *
+ * PARAMETERS: fp - File that contains table
+ * Table - Return value, buffer with table
+ * TableLength - Return value, length of table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the DSDT from the file pointer
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtReadTable (
+ FILE *fp,
+ ACPI_TABLE_HEADER **Table,
+ UINT32 *TableLength)
+{
+ ACPI_TABLE_HEADER TableHeader;
+ UINT32 Actual;
+ ACPI_STATUS Status;
+ UINT32 FileSize;
+ BOOLEAN StandardHeader = TRUE;
+ INT32 Count;
+
+ /* Get the file size */
+
+ FileSize = CmGetFileSize (fp);
+ if (FileSize == ACPI_UINT32_MAX)
+ {
+ return (AE_ERROR);
+ }
+
+ if (FileSize < 4)
+ {
+ return (AE_BAD_HEADER);
+ }
+
+ /* Read the signature */
+
+ fseek (fp, 0, SEEK_SET);
+
+ Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp);
+ if (Count != sizeof (ACPI_TABLE_HEADER))
+ {
+ AcpiOsPrintf ("Could not read the table header\n");
+ return (AE_BAD_HEADER);
+ }
+
+ /* The RSDP table does not have standard ACPI header */
+
+ if (ACPI_VALIDATE_RSDP_SIG (TableHeader.Signature))
+ {
+ *TableLength = FileSize;
+ StandardHeader = FALSE;
+ }
+ else
+ {
+
+#if 0
+ /* Validate the table header/length */
+
+ Status = AcpiTbValidateTableHeader (&TableHeader);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Table header is invalid!\n");
+ return (Status);
+ }
+#endif
+
+ /* File size must be at least as long as the Header-specified length */
+
+ if (TableHeader.Length > FileSize)
+ {
+ AcpiOsPrintf (
+ "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
+ TableHeader.Length, FileSize);
+
+#ifdef ACPI_ASL_COMPILER
+ AcpiOsPrintf ("File is corrupt or is ASCII text -- "
+ "it must be a binary file\n");
+#endif
+ return (AE_BAD_HEADER);
+ }
+
+#ifdef ACPI_OBSOLETE_CODE
+ /* We only support a limited number of table types */
+
+ if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) &&
+ !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) &&
+ !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT))
+ {
+ AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
+ (char *) TableHeader.Signature);
+ ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
+ return (AE_ERROR);
+ }
+#endif
+
+ *TableLength = TableHeader.Length;
+ }
+
+ /* Allocate a buffer for the table */
+
+ *Table = AcpiOsAllocate ((size_t) FileSize);
+ if (!*Table)
+ {
+ AcpiOsPrintf (
+ "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
+ TableHeader.Signature, *TableLength);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get the rest of the table */
+
+ fseek (fp, 0, SEEK_SET);
+ Actual = fread (*Table, 1, (size_t) FileSize, fp);
+ if (Actual == FileSize)
+ {
+ if (StandardHeader)
+ {
+ /* Now validate the checksum */
+
+ Status = AcpiTbVerifyChecksum ((void *) *Table,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
+
+ if (Status == AE_BAD_CHECKSUM)
+ {
+ Status = AcpiUtCheckTextModeCorruption ((UINT8 *) *Table,
+ FileSize, (*Table)->Length);
+ return (Status);
+ }
+ }
+ return (AE_OK);
+ }
+
+ if (Actual > 0)
+ {
+ AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
+ FileSize, Actual);
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf ("Error - could not read the table file\n");
+ AcpiOsFree (*Table);
+ *Table = NULL;
+ *TableLength = 0;
+ return (AE_ERROR);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtReadTableFromFile
+ *
+ * PARAMETERS: Filename - File where table is located
+ * Table - Where a pointer to the table is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an ACPI table from a file
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtReadTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **Table)
+{
+ FILE *File;
+ UINT32 FileSize;
+ UINT32 TableLength;
+ ACPI_STATUS Status = AE_ERROR;
+
+
+ /* Open the file, get current size */
+
+ File = fopen (Filename, "rb");
+ if (!File)
+ {
+ perror ("Could not open input file");
+ return (Status);
+ }
+
+ FileSize = CmGetFileSize (File);
+ if (FileSize == ACPI_UINT32_MAX)
+ {
+ goto Exit;
+ }
+
+ /* Get the entire file */
+
+ fprintf (stderr,
+ "Reading ACPI table from file %12s - Length %.8u (0x%06X)\n",
+ Filename, FileSize, FileSize);
+
+ Status = AcpiUtReadTable (File, Table, &TableLength);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get table from the file\n");
+ }
+
+Exit:
+ fclose(File);
+ return (Status);
+}
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utglobal.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utglobal.c
new file mode 100644
index 0000000000..e027aa14b5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utglobal.c
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * Module Name: utglobal - Global variables for the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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"
+};
+
+
+/*******************************************************************************
+ *
+ * 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 */
+
+/* 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/boot/sys/contrib/dev/acpica/components/utilities/uthex.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uthex.c
new file mode 100644
index 0000000000..7eede9d43f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uthex.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * Module Name: uthex -- Hex/ASCII support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("uthex")
+
+
+/* Hex to ASCII conversion table */
+
+static char AcpiGbl_HexToAscii[] =
+{
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtHexToAsciiChar
+ *
+ * PARAMETERS: Integer - Contains the hex digit
+ * Position - bit position of the digit within the
+ * integer (multiple of 4)
+ *
+ * RETURN: The converted Ascii character
+ *
+ * DESCRIPTION: Convert a hex digit to an Ascii character
+ *
+ ******************************************************************************/
+
+char
+AcpiUtHexToAsciiChar (
+ UINT64 Integer,
+ UINT32 Position)
+{
+
+ return (AcpiGbl_HexToAscii[(Integer >> Position) & 0xF]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAsciiCharToHex
+ *
+ * PARAMETERS: HexChar - Hex character in Ascii
+ *
+ * RETURN: The binary value of the ascii/hex character
+ *
+ * DESCRIPTION: Perform ascii-to-hex translation
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiUtAsciiCharToHex (
+ int HexChar)
+{
+
+ if (HexChar <= 0x39)
+ {
+ return ((UINT8) (HexChar - 0x30));
+ }
+
+ if (HexChar <= 0x46)
+ {
+ return ((UINT8) (HexChar - 0x37));
+ }
+
+ return ((UINT8) (HexChar - 0x57));
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utids.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utids.c
new file mode 100644
index 0000000000..6378e265f8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utids.c
@@ -0,0 +1,545 @@
+/******************************************************************************
+ *
+ * Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utids")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_HID
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnId - Where the string HID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _HID control method that returns the hardware
+ * ID of the device. The HID is either an 32-bit encoded EISAID
+ * Integer or a String. A string is always returned. An EISAID
+ * is converted to a string.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_HID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PNP_DEVICE_ID *Hid;
+ UINT32 Length;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_HID);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ Length = ACPI_EISAID_STRING_SIZE;
+ }
+ else
+ {
+ Length = ObjDesc->String.Length + 1;
+ }
+
+ /* Allocate a buffer for the HID */
+
+ Hid = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
+ if (!Hid)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ Hid->String = ACPI_ADD_PTR (char, Hid, sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Convert EISAID to a string or simply copy existing string */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ AcpiExEisaIdToString (Hid->String, ObjDesc->Integer.Value);
+ }
+ else
+ {
+ strcpy (Hid->String, ObjDesc->String.Pointer);
+ }
+
+ Hid->Length = Length;
+ *ReturnId = Hid;
+
+
+Cleanup:
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_SUB
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnId - Where the _SUB is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _SUB control method that returns the subsystem
+ * ID of the device. The _SUB value is always a string containing
+ * either a valid PNP or ACPI ID.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_SUB (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PNP_DEVICE_ID *Sub;
+ UINT32 Length;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_SUB);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__SUB,
+ ACPI_BTYPE_STRING, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ Length = ObjDesc->String.Length + 1;
+
+ /* Allocate a buffer for the SUB */
+
+ Sub = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
+ if (!Sub)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ Sub->String = ACPI_ADD_PTR (char, Sub, sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Simply copy existing string */
+
+ strcpy (Sub->String, ObjDesc->String.Pointer);
+ Sub->Length = Length;
+ *ReturnId = Sub;
+
+
+Cleanup:
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_UID
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnId - Where the string UID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _UID control method that returns the unique
+ * ID of the device. The UID is either a 64-bit Integer (NOT an
+ * EISAID) or a string. Always returns a string. A 64-bit integer
+ * is converted to a decimal string.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_UID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PNP_DEVICE_ID *Uid;
+ UINT32 Length;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_UID);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ Length = ACPI_MAX64_DECIMAL_DIGITS + 1;
+ }
+ else
+ {
+ Length = ObjDesc->String.Length + 1;
+ }
+
+ /* Allocate a buffer for the UID */
+
+ Uid = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
+ if (!Uid)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ Uid->String = ACPI_ADD_PTR (char, Uid, sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Convert an Integer to string, or just copy an existing string */
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ AcpiExIntegerToString (Uid->String, ObjDesc->Integer.Value);
+ }
+ else
+ {
+ strcpy (Uid->String, ObjDesc->String.Pointer);
+ }
+
+ Uid->Length = Length;
+ *ReturnId = Uid;
+
+
+Cleanup:
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_CID
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnCidList - Where the CID list is returned
+ *
+ * RETURN: Status, list of CID strings
+ *
+ * DESCRIPTION: Executes the _CID control method that returns one or more
+ * compatible hardware IDs for the device.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ * A _CID method can return either a single compatible ID or a package of
+ * compatible IDs. Each compatible ID can be one of the following:
+ * 1) Integer (32 bit compressed EISA ID) or
+ * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
+ *
+ * The Integer CIDs are converted to string format by this function.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_CID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID_LIST **ReturnCidList)
+{
+ ACPI_OPERAND_OBJECT **CidObjects;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PNP_DEVICE_ID_LIST *CidList;
+ char *NextIdString;
+ UINT32 StringAreaSize;
+ UINT32 Length;
+ UINT32 CidListSize;
+ ACPI_STATUS Status;
+ UINT32 Count;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_CID);
+
+
+ /* Evaluate the _CID method for this device */
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
+ &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Get the count and size of the returned _CIDs. _CID can return either
+ * a Package of Integers/Strings or a single Integer or String.
+ * Note: This section also validates that all CID elements are of the
+ * correct type (Integer or String).
+ */
+ if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ Count = ObjDesc->Package.Count;
+ CidObjects = ObjDesc->Package.Elements;
+ }
+ else /* Single Integer or String CID */
+ {
+ Count = 1;
+ CidObjects = &ObjDesc;
+ }
+
+ StringAreaSize = 0;
+ for (i = 0; i < Count; i++)
+ {
+ /* String lengths include null terminator */
+
+ switch (CidObjects[i]->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ StringAreaSize += ACPI_EISAID_STRING_SIZE;
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ StringAreaSize += CidObjects[i]->String.Length + 1;
+ break;
+
+ default:
+
+ Status = AE_TYPE;
+ goto Cleanup;
+ }
+ }
+
+ /*
+ * Now that we know the length of the CIDs, allocate return buffer:
+ * 1) Size of the base structure +
+ * 2) Size of the CID PNP_DEVICE_ID array +
+ * 3) Size of the actual CID strings
+ */
+ CidListSize = sizeof (ACPI_PNP_DEVICE_ID_LIST) +
+ ((Count - 1) * sizeof (ACPI_PNP_DEVICE_ID)) +
+ StringAreaSize;
+
+ CidList = ACPI_ALLOCATE_ZEROED (CidListSize);
+ if (!CidList)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
+
+ NextIdString = ACPI_CAST_PTR (char, CidList->Ids) +
+ ((ACPI_SIZE) Count * sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Copy/convert the CIDs to the return buffer */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (CidObjects[i]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ /* Convert the Integer (EISAID) CID to a string */
+
+ AcpiExEisaIdToString (NextIdString, CidObjects[i]->Integer.Value);
+ Length = ACPI_EISAID_STRING_SIZE;
+ }
+ else /* ACPI_TYPE_STRING */
+ {
+ /* Copy the String CID from the returned object */
+
+ strcpy (NextIdString, CidObjects[i]->String.Pointer);
+ Length = CidObjects[i]->String.Length + 1;
+ }
+
+ CidList->Ids[i].String = NextIdString;
+ CidList->Ids[i].Length = Length;
+ NextIdString += Length;
+ }
+
+ /* Finish the CID list */
+
+ CidList->Count = Count;
+ CidList->ListSize = CidListSize;
+ *ReturnCidList = CidList;
+
+
+Cleanup:
+
+ /* On exit, we must delete the _CID return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_CLS
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnId - Where the _CLS is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _CLS control method that returns PCI-defined
+ * class code of the device. The _CLS value is always a package
+ * containing PCI class information as a list of integers.
+ * The returned string has format "BBSSPP", where:
+ * BB = Base-class code
+ * SS = Sub-class code
+ * PP = Programming Interface code
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_CLS (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT **ClsObjects;
+ UINT32 Count;
+ ACPI_PNP_DEVICE_ID *Cls;
+ UINT32 Length;
+ ACPI_STATUS Status;
+ UINT8 ClassCode[3] = {0, 0, 0};
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_CLS);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CLS,
+ ACPI_BTYPE_PACKAGE, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ Length = ACPI_PCICLS_STRING_SIZE;
+ ClsObjects = ObjDesc->Package.Elements;
+ Count = ObjDesc->Package.Count;
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ if (Count > 0 && ClsObjects[0]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[0] = (UINT8) ClsObjects[0]->Integer.Value;
+ }
+ if (Count > 1 && ClsObjects[1]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[1] = (UINT8) ClsObjects[1]->Integer.Value;
+ }
+ if (Count > 2 && ClsObjects[2]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[2] = (UINT8) ClsObjects[2]->Integer.Value;
+ }
+ }
+
+ /* Allocate a buffer for the CLS */
+
+ Cls = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
+ if (!Cls)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ Cls->String = ACPI_ADD_PTR (char, Cls, sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Simply copy existing string */
+
+ AcpiExPciClsToString (Cls->String, ClassCode);
+ Cls->Length = Length;
+ *ReturnId = Cls;
+
+
+Cleanup:
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utinit.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utinit.c
new file mode 100644
index 0000000000..ea961788eb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utinit.c
@@ -0,0 +1,342 @@
+/******************************************************************************
+ *
+ * Module Name: utinit - Common ACPI subsystem initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utinit")
+
+/* Local prototypes */
+
+static void AcpiUtTerminate (
+ void);
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+static void
+AcpiUtFreeGpeLists (
+ void);
+
+#else
+
+#define AcpiUtFreeGpeLists()
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/******************************************************************************
+ *
+ * FUNCTION: AcpiUtFreeGpeLists
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Free global GPE lists
+ *
+ ******************************************************************************/
+
+static void
+AcpiUtFreeGpeLists (
+ void)
+{
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_BLOCK_INFO *NextGpeBlock;
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
+ ACPI_GPE_XRUPT_INFO *NextGpeXruptInfo;
+
+
+ /* Free global GPE blocks and related info structures */
+
+ GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+ while (GpeXruptInfo)
+ {
+ GpeBlock = GpeXruptInfo->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ NextGpeBlock = GpeBlock->Next;
+ ACPI_FREE (GpeBlock->EventInfo);
+ ACPI_FREE (GpeBlock->RegisterInfo);
+ ACPI_FREE (GpeBlock);
+
+ GpeBlock = NextGpeBlock;
+ }
+ NextGpeXruptInfo = GpeXruptInfo->Next;
+ ACPI_FREE (GpeXruptInfo);
+ GpeXruptInfo = NextGpeXruptInfo;
+ }
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInitGlobals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
+ * initialization should be initialized here. This allows for
+ * a warm restart.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtInitGlobals (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (UtInitGlobals);
+
+
+ /* Create all memory caches */
+
+ Status = AcpiUtCreateCaches ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Address Range lists */
+
+ for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++)
+ {
+ AcpiGbl_AddressRangeList[i] = NULL;
+ }
+
+ /* Mutex locked flags */
+
+ for (i = 0; i < ACPI_NUM_MUTEX; i++)
+ {
+ AcpiGbl_MutexInfo[i].Mutex = NULL;
+ AcpiGbl_MutexInfo[i].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
+ AcpiGbl_MutexInfo[i].UseCount = 0;
+ }
+
+ for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++)
+ {
+ AcpiGbl_OwnerIdMask[i] = 0;
+ }
+
+ /* Last OwnerID is never valid */
+
+ AcpiGbl_OwnerIdMask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
+
+ /* Event counters */
+
+ AcpiMethodCount = 0;
+ AcpiSciCount = 0;
+ AcpiGpeCount = 0;
+
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ AcpiFixedEventCount[i] = 0;
+ }
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* GPE/SCI support */
+
+ AcpiGbl_AllGpesInitialized = FALSE;
+ AcpiGbl_GpeXruptListHead = NULL;
+ AcpiGbl_GpeFadtBlocks[0] = NULL;
+ AcpiGbl_GpeFadtBlocks[1] = NULL;
+ AcpiCurrentGpeCount = 0;
+
+ AcpiGbl_GlobalEventHandler = NULL;
+ AcpiGbl_SciHandlerList = NULL;
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /* Global handlers */
+
+ AcpiGbl_GlobalNotify[0].Handler = NULL;
+ AcpiGbl_GlobalNotify[1].Handler = NULL;
+ AcpiGbl_ExceptionHandler = NULL;
+ AcpiGbl_InitHandler = NULL;
+ AcpiGbl_TableHandler = NULL;
+ AcpiGbl_InterfaceHandler = NULL;
+
+ /* Global Lock support */
+
+ AcpiGbl_GlobalLockSemaphore = NULL;
+ AcpiGbl_GlobalLockMutex = NULL;
+ AcpiGbl_GlobalLockAcquired = FALSE;
+ AcpiGbl_GlobalLockHandle = 0;
+ AcpiGbl_GlobalLockPresent = FALSE;
+
+ /* Miscellaneous variables */
+
+ AcpiGbl_DSDT = NULL;
+ AcpiGbl_CmSingleStep = FALSE;
+ AcpiGbl_Shutdown = FALSE;
+ AcpiGbl_NsLookupCount = 0;
+ AcpiGbl_PsFindCount = 0;
+ AcpiGbl_AcpiHardwarePresent = TRUE;
+ AcpiGbl_LastOwnerIdIndex = 0;
+ AcpiGbl_NextOwnerIdOffset = 0;
+ AcpiGbl_DebuggerConfiguration = DEBUGGER_THREADING;
+ AcpiGbl_OsiMutex = NULL;
+ AcpiGbl_RegMethodsExecuted = FALSE;
+ AcpiGbl_MaxLoopIterations = 0xFFFF;
+
+ /* Hardware oriented */
+
+ AcpiGbl_EventsInitialized = FALSE;
+ AcpiGbl_SystemAwakeAndRunning = TRUE;
+
+ /* Namespace */
+
+ AcpiGbl_ModuleCodeList = NULL;
+ AcpiGbl_RootNode = NULL;
+ AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
+ AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
+ AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE;
+ AcpiGbl_RootNodeStruct.Parent = NULL;
+ AcpiGbl_RootNodeStruct.Child = NULL;
+ AcpiGbl_RootNodeStruct.Peer = NULL;
+ AcpiGbl_RootNodeStruct.Object = NULL;
+
+
+#ifdef ACPI_DISASSEMBLER
+ AcpiGbl_ExternalList = NULL;
+ AcpiGbl_NumExternalMethods = 0;
+ AcpiGbl_ResolvedExternalMethods = 0;
+#endif
+
+#ifdef ACPI_DEBUG_OUTPUT
+ AcpiGbl_LowestStackPointer = ACPI_CAST_PTR (ACPI_SIZE, ACPI_SIZE_MAX);
+#endif
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiGbl_DisplayFinalMemStats = FALSE;
+ AcpiGbl_DisableMemTracking = FALSE;
+#endif
+
+ ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = FALSE);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiUtTerminate
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Free global memory
+ *
+ ******************************************************************************/
+
+static void
+AcpiUtTerminate (
+ void)
+{
+ ACPI_FUNCTION_TRACE (UtTerminate);
+
+ AcpiUtFreeGpeLists ();
+ AcpiUtDeleteAddressLists ();
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtSubsystemShutdown
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Shutdown the various components. Do not delete the mutex
+ * objects here, because the AML debugger may be still running.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtSubsystemShutdown (
+ void)
+{
+ ACPI_FUNCTION_TRACE (UtSubsystemShutdown);
+
+
+#ifndef ACPI_ASL_COMPILER
+
+ /* Close the AcpiEvent Handling */
+
+ AcpiEvTerminate ();
+
+ /* Delete any dynamic _OSI interfaces */
+
+ AcpiUtInterfaceTerminate ();
+#endif
+
+ /* Close the Namespace */
+
+ AcpiNsTerminate ();
+
+ /* Delete the ACPI tables */
+
+ AcpiTbTerminate ();
+
+ /* Close the globals */
+
+ AcpiUtTerminate ();
+
+ /* Purge the local caches */
+
+ (void) AcpiUtDeleteCaches ();
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utlock.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utlock.c
new file mode 100644
index 0000000000..3903e99e87
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utlock.c
@@ -0,0 +1,202 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utlock")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateRwLock
+ * AcpiUtDeleteRwLock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCreateRwLock (
+ ACPI_RW_LOCK *Lock)
+{
+ ACPI_STATUS Status;
+
+
+ Lock->NumReaders = 0;
+ Status = AcpiOsCreateMutex (&Lock->ReaderMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiOsCreateMutex (&Lock->WriterMutex);
+ return (Status);
+}
+
+
+void
+AcpiUtDeleteRwLock (
+ ACPI_RW_LOCK *Lock)
+{
+
+ AcpiOsDeleteMutex (Lock->ReaderMutex);
+ AcpiOsDeleteMutex (Lock->WriterMutex);
+
+ Lock->NumReaders = 0;
+ Lock->ReaderMutex = NULL;
+ Lock->WriterMutex = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAcquireReadLock
+ * AcpiUtReleaseReadLock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ * only the first reader acquires the write mutex. On release,
+ * only the last reader releases the write mutex. Although this
+ * algorithm can in theory starve writers, this should not be a
+ * problem with ACPICA since the subsystem is infrequently used
+ * in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtAcquireReadLock (
+ ACPI_RW_LOCK *Lock)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Acquire the write lock only for the first reader */
+
+ Lock->NumReaders++;
+ if (Lock->NumReaders == 1)
+ {
+ Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
+ }
+
+ AcpiOsReleaseMutex (Lock->ReaderMutex);
+ return (Status);
+}
+
+
+ACPI_STATUS
+AcpiUtReleaseReadLock (
+ ACPI_RW_LOCK *Lock)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Release the write lock only for the very last reader */
+
+ Lock->NumReaders--;
+ if (Lock->NumReaders == 0)
+ {
+ AcpiOsReleaseMutex (Lock->WriterMutex);
+ }
+
+ AcpiOsReleaseMutex (Lock->ReaderMutex);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAcquireWriteLock
+ * AcpiUtReleaseWriteLock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ * release the writer mutex associated with the lock. Acquisition
+ * of the lock is fully exclusive and will block all readers and
+ * writers until it is released.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtAcquireWriteLock (
+ ACPI_RW_LOCK *Lock)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
+ return (Status);
+}
+
+
+void
+AcpiUtReleaseWriteLock (
+ ACPI_RW_LOCK *Lock)
+{
+
+ AcpiOsReleaseMutex (Lock->WriterMutex);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmath.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmath.c
new file mode 100644
index 0000000000..ce11f39fb8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmath.c
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ *
+ * Module Name: utmath - Integer math support routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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/boot/sys/contrib/dev/acpica/components/utilities/utmisc.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmisc.c
new file mode 100644
index 0000000000..47f37172fc
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmisc.c
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ *
+ * Module Name: utmisc - common utility procedures
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtIsPciRootBridge
+ *
+ * PARAMETERS: Id - The HID/CID in string format
+ *
+ * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
+ *
+ * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtIsPciRootBridge (
+ char *Id)
+{
+
+ /*
+ * Check if this is a PCI root bridge.
+ * ACPI 3.0+: check for a PCI Express root also.
+ */
+ if (!(strcmp (Id,
+ PCI_ROOT_HID_STRING)) ||
+
+ !(strcmp (Id,
+ PCI_EXPRESS_ROOT_HID_STRING)))
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtIsAmlTable
+ *
+ * PARAMETERS: Table - An ACPI table
+ *
+ * RETURN: TRUE if table contains executable AML; FALSE otherwise
+ *
+ * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
+ * Currently, these are DSDT,SSDT,PSDT. All other table types are
+ * data tables that do not contain AML code.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtIsAmlTable (
+ ACPI_TABLE_HEADER *Table)
+{
+
+ /* These are the only tables that contain executable AML */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
+ ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
+ ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) ||
+ ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_OSDT))
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDwordByteSwap
+ *
+ * PARAMETERS: Value - Value to be converted
+ *
+ * RETURN: UINT32 integer with bytes swapped
+ *
+ * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiUtDwordByteSwap (
+ UINT32 Value)
+{
+ union
+ {
+ UINT32 Value;
+ UINT8 Bytes[4];
+ } Out;
+ union
+ {
+ UINT32 Value;
+ UINT8 Bytes[4];
+ } In;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ In.Value = Value;
+
+ Out.Bytes[0] = In.Bytes[3];
+ Out.Bytes[1] = In.Bytes[2];
+ Out.Bytes[2] = In.Bytes[1];
+ Out.Bytes[3] = In.Bytes[0];
+
+ return (Out.Value);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtSetIntegerWidth
+ *
+ * PARAMETERS: Revision From DSDT header
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the global integer bit width based upon the revision
+ * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
+ * For Revision 2 and above, Integers are 64 bits. Yes, this
+ * makes a difference.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtSetIntegerWidth (
+ UINT8 Revision)
+{
+
+ if (Revision < 2)
+ {
+ /* 32-bit case */
+
+ AcpiGbl_IntegerBitWidth = 32;
+ AcpiGbl_IntegerNybbleWidth = 8;
+ AcpiGbl_IntegerByteWidth = 4;
+ }
+ else
+ {
+ /* 64-bit case (ACPI 2.0+) */
+
+ AcpiGbl_IntegerBitWidth = 64;
+ AcpiGbl_IntegerNybbleWidth = 16;
+ AcpiGbl_IntegerByteWidth = 8;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateUpdateStateAndPush
+ *
+ * PARAMETERS: Object - Object to be added to the new state
+ * Action - Increment/Decrement
+ * StateList - List the state will be added to
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCreateUpdateStateAndPush (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action,
+ ACPI_GENERIC_STATE **StateList)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Ignore null objects; these are expected */
+
+ if (!Object)
+ {
+ return (AE_OK);
+ }
+
+ State = AcpiUtCreateUpdateState (Object, Action);
+ if (!State)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ AcpiUtPushGenericState (StateList, State);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtWalkPackageTree
+ *
+ * PARAMETERS: SourceObject - The package to walk
+ * TargetObject - Target object (if package is being copied)
+ * WalkCallback - Called once for each package element
+ * Context - Passed to the callback function
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk through a package
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtWalkPackageTree (
+ ACPI_OPERAND_OBJECT *SourceObject,
+ void *TargetObject,
+ ACPI_PKG_CALLBACK WalkCallback,
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *StateList = NULL;
+ ACPI_GENERIC_STATE *State;
+ UINT32 ThisIndex;
+ ACPI_OPERAND_OBJECT *ThisSourceObj;
+
+
+ ACPI_FUNCTION_TRACE (UtWalkPackageTree);
+
+
+ State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
+ if (!State)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ while (State)
+ {
+ /* Get one element of the package */
+
+ ThisIndex = State->Pkg.Index;
+ ThisSourceObj = (ACPI_OPERAND_OBJECT *)
+ State->Pkg.SourceObject->Package.Elements[ThisIndex];
+
+ /*
+ * Check for:
+ * 1) An uninitialized package element. It is completely
+ * legal to declare a package and leave it uninitialized
+ * 2) Not an internal object - can be a namespace node instead
+ * 3) Any type other than a package. Packages are handled in else
+ * case below.
+ */
+ if ((!ThisSourceObj) ||
+ (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
+ (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
+ {
+ Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
+ State, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ State->Pkg.Index++;
+ while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
+ {
+ /*
+ * We've handled all of the objects at this level, This means
+ * that we have just completed a package. That package may
+ * have contained one or more packages itself.
+ *
+ * Delete this state and pop the previous state (package).
+ */
+ AcpiUtDeleteGenericState (State);
+ State = AcpiUtPopGenericState (&StateList);
+
+ /* Finished when there are no more states */
+
+ if (!State)
+ {
+ /*
+ * We have handled all of the objects in the top level
+ * package just add the length of the package objects
+ * and exit
+ */
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Go back up a level and move the index past the just
+ * completed package object.
+ */
+ State->Pkg.Index++;
+ }
+ }
+ else
+ {
+ /* This is a subobject of type package */
+
+ Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
+ State, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Push the current state and create a new one
+ * The callback above returned a new target package object.
+ */
+ AcpiUtPushGenericState (&StateList, State);
+ State = AcpiUtCreatePkgState (ThisSourceObj,
+ State->Pkg.ThisTargetObj, 0);
+ if (!State)
+ {
+ /* Free any stacked Update State objects */
+
+ while (StateList)
+ {
+ State = AcpiUtPopGenericState (&StateList);
+ AcpiUtDeleteGenericState (State);
+ }
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+ }
+
+ /* We should never get here */
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+}
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDisplayInitPathname
+ *
+ * PARAMETERS: Type - Object type of the node
+ * ObjHandle - Handle whose pathname will be displayed
+ * Path - Additional path string to be appended.
+ * (NULL if no extra path)
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDisplayInitPathname (
+ UINT8 Type,
+ ACPI_NAMESPACE_NODE *ObjHandle,
+ char *Path)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER Buffer;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Only print the path if the appropriate debug level is enabled */
+
+ if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
+ {
+ return;
+ }
+
+ /* Get the full pathname to the node */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Print what we're doing */
+
+ switch (Type)
+ {
+ case ACPI_TYPE_METHOD:
+
+ AcpiOsPrintf ("Executing ");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Initializing ");
+ break;
+ }
+
+ /* Print the object type and pathname */
+
+ AcpiOsPrintf ("%-12s %s",
+ AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
+
+ /* Extra path is used to append names like _STA, _INI, etc. */
+
+ if (Path)
+ {
+ AcpiOsPrintf (".%s", Path);
+ }
+ AcpiOsPrintf ("\n");
+
+ ACPI_FREE (Buffer.Pointer);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmutex.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmutex.c
new file mode 100644
index 0000000000..c7b162be89
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utmutex.c
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ *
+ * Module Name: utmutex - local mutex support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utmutex")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtCreateMutex (
+ ACPI_MUTEX_HANDLE MutexId);
+
+static void
+AcpiUtDeleteMutex (
+ ACPI_MUTEX_HANDLE MutexId);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtMutexInitialize
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtMutexInitialize (
+ void)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtMutexInitialize);
+
+
+ /* Create each of the predefined mutex objects */
+
+ for (i = 0; i < ACPI_NUM_MUTEX; i++)
+ {
+ Status = AcpiUtCreateMutex (i);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Create the spinlocks for use at interrupt level or for speed */
+
+ Status = AcpiOsCreateLock (&AcpiGbl_GpeLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiOsCreateLock (&AcpiGbl_ReferenceCountLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Mutex for _OSI support */
+
+ Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Create the reader/writer lock for namespace access */
+
+ Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtMutexTerminate
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtMutexTerminate (
+ void)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (UtMutexTerminate);
+
+
+ /* Delete each predefined mutex object */
+
+ for (i = 0; i < ACPI_NUM_MUTEX; i++)
+ {
+ AcpiUtDeleteMutex (i);
+ }
+
+ AcpiOsDeleteMutex (AcpiGbl_OsiMutex);
+
+ /* Delete the spinlocks */
+
+ AcpiOsDeleteLock (AcpiGbl_GpeLock);
+ AcpiOsDeleteLock (AcpiGbl_HardwareLock);
+ AcpiOsDeleteLock (AcpiGbl_ReferenceCountLock);
+
+ /* Delete the reader/writer lock */
+
+ AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateMutex
+ *
+ * PARAMETERS: MutexID - ID of the mutex to be created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a mutex object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtCreateMutex (
+ ACPI_MUTEX_HANDLE MutexId)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_U32 (UtCreateMutex, MutexId);
+
+
+ if (!AcpiGbl_MutexInfo[MutexId].Mutex)
+ {
+ Status = AcpiOsCreateMutex (&AcpiGbl_MutexInfo[MutexId].Mutex);
+ AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
+ AcpiGbl_MutexInfo[MutexId].UseCount = 0;
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteMutex
+ *
+ * PARAMETERS: MutexID - ID of the mutex to be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete a mutex object.
+ *
+ ******************************************************************************/
+
+static void
+AcpiUtDeleteMutex (
+ ACPI_MUTEX_HANDLE MutexId)
+{
+
+ ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId);
+
+
+ AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
+
+ AcpiGbl_MutexInfo[MutexId].Mutex = NULL;
+ AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAcquireMutex
+ *
+ * PARAMETERS: MutexID - ID of the mutex to be acquired
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtAcquireMutex (
+ ACPI_MUTEX_HANDLE MutexId)
+{
+ ACPI_STATUS Status;
+ ACPI_THREAD_ID ThisThreadId;
+
+
+ ACPI_FUNCTION_NAME (UtAcquireMutex);
+
+
+ if (MutexId > ACPI_MAX_MUTEX)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ ThisThreadId = AcpiOsGetThreadId ();
+
+#ifdef ACPI_MUTEX_DEBUG
+ {
+ UINT32 i;
+ /*
+ * Mutex debug code, for internal debugging only.
+ *
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than or equal to this one. If so, the thread has violated
+ * the mutex ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
+ {
+ if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId)
+ {
+ if (i == MutexId)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Mutex [%s] already acquired by this thread [%u]",
+ AcpiUtGetMutexName (MutexId),
+ (UINT32) ThisThreadId));
+
+ return (AE_ALREADY_ACQUIRED);
+ }
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid acquire order: Thread %u owns [%s], wants [%s]",
+ (UINT32) ThisThreadId, AcpiUtGetMutexName (i),
+ AcpiUtGetMutexName (MutexId)));
+
+ return (AE_ACQUIRE_DEADLOCK);
+ }
+ }
+ }
+#endif
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
+ "Thread %u attempting to acquire Mutex [%s]\n",
+ (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId)));
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_MutexInfo[MutexId].Mutex,
+ ACPI_WAIT_FOREVER);
+ if (ACPI_SUCCESS (Status))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u acquired Mutex [%s]\n",
+ (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId)));
+
+ AcpiGbl_MutexInfo[MutexId].UseCount++;
+ AcpiGbl_MutexInfo[MutexId].ThreadId = ThisThreadId;
+ }
+ else
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Thread %u could not acquire Mutex [0x%X]",
+ (UINT32) ThisThreadId, MutexId));
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtReleaseMutex
+ *
+ * PARAMETERS: MutexID - ID of the mutex to be released
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtReleaseMutex (
+ ACPI_MUTEX_HANDLE MutexId)
+{
+ ACPI_FUNCTION_NAME (UtReleaseMutex);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
+ (UINT32) AcpiOsGetThreadId (), AcpiUtGetMutexName (MutexId)));
+
+ if (MutexId > ACPI_MAX_MUTEX)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Mutex must be acquired in order to release it!
+ */
+ if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Mutex [0x%X] is not acquired, cannot release", MutexId));
+
+ return (AE_NOT_ACQUIRED);
+ }
+
+#ifdef ACPI_MUTEX_DEBUG
+ {
+ UINT32 i;
+ /*
+ * Mutex debug code, for internal debugging only.
+ *
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than this one. If so, the thread has violated the mutex
+ * ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
+ {
+ if (AcpiGbl_MutexInfo[i].ThreadId == AcpiOsGetThreadId ())
+ {
+ if (i == MutexId)
+ {
+ continue;
+ }
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid release order: owns [%s], releasing [%s]",
+ AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
+
+ return (AE_RELEASE_DEADLOCK);
+ }
+ }
+ }
+#endif
+
+ /* Mark unlocked FIRST */
+
+ AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
+
+ AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utnonansi.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utnonansi.c
new file mode 100644
index 0000000000..7bd69975d4
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utnonansi.c
@@ -0,0 +1,432 @@
+/*******************************************************************************
+ *
+ * Module Name: utnonansi - Non-ansi C library functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtStrtoul64
+ *
+ * PARAMETERS: String - Null terminated string
+ * Base - Radix of the string: 16 or ACPI_ANY_BASE;
+ * ACPI_ANY_BASE means 'in behalf of ToInteger'
+ * 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 current mode
+ * of the interpreter.
+ *
+ * NOTE: Does not support Octal strings, not needed.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtStrtoul64 (
+ char *String,
+ UINT32 Base,
+ UINT64 *RetInteger)
+{
+ UINT32 ThisDigit = 0;
+ UINT64 ReturnValue = 0;
+ UINT64 Quotient;
+ UINT64 Dividend;
+ UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE);
+ UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4);
+ UINT8 ValidDigits = 0;
+ UINT8 SignOf0x = 0;
+ UINT8 Term = 0;
+
+
+ ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
+
+
+ switch (Base)
+ {
+ case ACPI_ANY_BASE:
+ 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 (ToIntegerOp)
+ {
+ /*
+ * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
+ * 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 (ToIntegerOp)
+ {
+ goto ErrorExit;
+ }
+ else
+ {
+ goto AllDone;
+ }
+ }
+
+ /*
+ * Perform a 32-bit or 64-bit conversion, depending upon the current
+ * execution mode of the interpreter
+ */
+ Dividend = (Mode32) ? 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 (ToIntegerOp)
+ {
+ goto ErrorExit;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
+ {
+ /* Skip zeros */
+ String++;
+ continue;
+ }
+
+ ValidDigits++;
+
+ if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
+ {
+ /*
+ * This is ToInteger operation case.
+ * No any 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 (ToIntegerOp)
+ {
+ 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 */
+
+ if (Base == 10)
+ {
+ return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
+ }
+ else
+ {
+ return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
+ }
+}
+
+
+#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat
+ *
+ * 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);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utobject.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utobject.c
new file mode 100644
index 0000000000..4c80c40a68
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utobject.c
@@ -0,0 +1,776 @@
+/******************************************************************************
+ *
+ * Module Name: utobject - ACPI object create/delete/size/cache routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utobject")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtGetSimpleObjectSize (
+ ACPI_OPERAND_OBJECT *Obj,
+ ACPI_SIZE *ObjLength);
+
+static ACPI_STATUS
+AcpiUtGetPackageObjectSize (
+ ACPI_OPERAND_OBJECT *Obj,
+ ACPI_SIZE *ObjLength);
+
+static ACPI_STATUS
+AcpiUtGetElementLength (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateInternalObjectDbg
+ *
+ * PARAMETERS: ModuleName - Source file name of caller
+ * LineNumber - Line number of caller
+ * ComponentId - Component type of caller
+ * Type - ACPI Type of the new object
+ *
+ * RETURN: A new internal object, null on failure
+ *
+ * DESCRIPTION: Create and initialize a new internal object.
+ *
+ * NOTE: We always allocate the worst-case object descriptor because
+ * these objects are cached, and we want them to be
+ * one-size-satisifies-any-request. This in itself may not be
+ * the most memory efficient, but the efficiency of the object
+ * cache should more than make up for this!
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateInternalObjectDbg (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ UINT32 ComponentId,
+ ACPI_OBJECT_TYPE Type)
+{
+ ACPI_OPERAND_OBJECT *Object;
+ ACPI_OPERAND_OBJECT *SecondObject;
+
+
+ ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
+ AcpiUtGetTypeName (Type));
+
+
+ /* Allocate the raw object descriptor */
+
+ Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId);
+ if (!Object)
+ {
+ return_PTR (NULL);
+ }
+
+ switch (Type)
+ {
+ case ACPI_TYPE_REGION:
+ case ACPI_TYPE_BUFFER_FIELD:
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ /* These types require a secondary object */
+
+ SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName,
+ LineNumber, ComponentId);
+ if (!SecondObject)
+ {
+ AcpiUtDeleteObjectDesc (Object);
+ return_PTR (NULL);
+ }
+
+ SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
+ SecondObject->Common.ReferenceCount = 1;
+
+ /* Link the second object to the first */
+
+ Object->Common.NextObject = SecondObject;
+ break;
+
+ default:
+
+ /* All others have no secondary object */
+ break;
+ }
+
+ /* Save the object type in the object descriptor */
+
+ Object->Common.Type = (UINT8) Type;
+
+ /* Init the reference count */
+
+ Object->Common.ReferenceCount = 1;
+
+ /* Any per-type initialization should go here */
+
+ return_PTR (Object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreatePackageObject
+ *
+ * PARAMETERS: Count - Number of package elements
+ *
+ * RETURN: Pointer to a new Package object, null on failure
+ *
+ * DESCRIPTION: Create a fully initialized package object
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreatePackageObject (
+ UINT32 Count)
+{
+ ACPI_OPERAND_OBJECT *PackageDesc;
+ ACPI_OPERAND_OBJECT **PackageElements;
+
+
+ ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
+
+
+ /* Create a new Package object */
+
+ PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
+ if (!PackageDesc)
+ {
+ return_PTR (NULL);
+ }
+
+ /*
+ * Create the element array. Count+1 allows the array to be null
+ * terminated.
+ */
+ PackageElements = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) Count + 1) * sizeof (void *));
+ if (!PackageElements)
+ {
+ ACPI_FREE (PackageDesc);
+ return_PTR (NULL);
+ }
+
+ PackageDesc->Package.Count = Count;
+ PackageDesc->Package.Elements = PackageElements;
+ return_PTR (PackageDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateIntegerObject
+ *
+ * PARAMETERS: InitialValue - Initial value for the integer
+ *
+ * RETURN: Pointer to a new Integer object, null on failure
+ *
+ * DESCRIPTION: Create an initialized integer object
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateIntegerObject (
+ UINT64 InitialValue)
+{
+ ACPI_OPERAND_OBJECT *IntegerDesc;
+
+
+ ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
+
+
+ /* Create and initialize a new integer object */
+
+ IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!IntegerDesc)
+ {
+ return_PTR (NULL);
+ }
+
+ IntegerDesc->Integer.Value = InitialValue;
+ return_PTR (IntegerDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateBufferObject
+ *
+ * PARAMETERS: BufferSize - Size of buffer to be created
+ *
+ * RETURN: Pointer to a new Buffer object, null on failure
+ *
+ * DESCRIPTION: Create a fully initialized buffer object
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateBufferObject (
+ ACPI_SIZE BufferSize)
+{
+ ACPI_OPERAND_OBJECT *BufferDesc;
+ UINT8 *Buffer = NULL;
+
+
+ ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
+
+
+ /* Create a new Buffer object */
+
+ BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
+ if (!BufferDesc)
+ {
+ return_PTR (NULL);
+ }
+
+ /* Create an actual buffer only if size > 0 */
+
+ if (BufferSize > 0)
+ {
+ /* Allocate the actual buffer */
+
+ Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
+ if (!Buffer)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
+ (UINT32) BufferSize));
+ AcpiUtRemoveReference (BufferDesc);
+ return_PTR (NULL);
+ }
+ }
+
+ /* Complete buffer object initialization */
+
+ BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
+ BufferDesc->Buffer.Pointer = Buffer;
+ BufferDesc->Buffer.Length = (UINT32) BufferSize;
+
+ /* Return the new buffer descriptor */
+
+ return_PTR (BufferDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateStringObject
+ *
+ * PARAMETERS: StringSize - Size of string to be created. Does not
+ * include NULL terminator, this is added
+ * automatically.
+ *
+ * RETURN: Pointer to a new String object
+ *
+ * DESCRIPTION: Create a fully initialized string object
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateStringObject (
+ ACPI_SIZE StringSize)
+{
+ ACPI_OPERAND_OBJECT *StringDesc;
+ char *String;
+
+
+ ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
+
+
+ /* Create a new String object */
+
+ StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
+ if (!StringDesc)
+ {
+ return_PTR (NULL);
+ }
+
+ /*
+ * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
+ * NOTE: Zero-length strings are NULL terminated
+ */
+ String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
+ if (!String)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
+ (UINT32) StringSize));
+ AcpiUtRemoveReference (StringDesc);
+ return_PTR (NULL);
+ }
+
+ /* Complete string object initialization */
+
+ StringDesc->String.Pointer = String;
+ StringDesc->String.Length = (UINT32) StringSize;
+
+ /* Return the new string descriptor */
+
+ return_PTR (StringDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidInternalObject
+ *
+ * PARAMETERS: Object - Object to be validated
+ *
+ * RETURN: TRUE if object is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtValidInternalObject (
+ void *Object)
+{
+
+ ACPI_FUNCTION_NAME (UtValidInternalObject);
+
+
+ /* Check for a null pointer */
+
+ if (!Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
+ return (FALSE);
+ }
+
+ /* Check the descriptor type field */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
+ {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ /* The object appears to be a valid ACPI_OPERAND_OBJECT */
+
+ return (TRUE);
+
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "%p is not an ACPI operand obj [%s]\n",
+ Object, AcpiUtGetDescriptorName (Object)));
+ break;
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAllocateObjectDescDbg
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * ComponentId - Caller's component ID (for error output)
+ *
+ * RETURN: Pointer to newly allocated object descriptor. Null on error
+ *
+ * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
+ * error conditions.
+ *
+ ******************************************************************************/
+
+void *
+AcpiUtAllocateObjectDescDbg (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ UINT32 ComponentId)
+{
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
+
+
+ Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
+ if (!Object)
+ {
+ ACPI_ERROR ((ModuleName, LineNumber,
+ "Could not allocate an object descriptor"));
+
+ return_PTR (NULL);
+ }
+
+ /* Mark the descriptor type */
+
+ ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
+ Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
+
+ return_PTR (Object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteObjectDesc
+ *
+ * PARAMETERS: Object - An Acpi internal object to be deleted
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDeleteObjectDesc (
+ ACPI_OPERAND_OBJECT *Object)
+{
+ ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
+
+
+ /* Object must be of type ACPI_OPERAND_OBJECT */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "%p is not an ACPI Operand object [%s]", Object,
+ AcpiUtGetDescriptorName (Object)));
+ return_VOID;
+ }
+
+ (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetSimpleObjectSize
+ *
+ * PARAMETERS: InternalObject - An ACPI operand object
+ * ObjLength - Where the length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain a simple object for return to an external user.
+ *
+ * The length includes the object structure plus any additional
+ * needed space.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtGetSimpleObjectSize (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_SIZE *ObjLength)
+{
+ ACPI_SIZE Length;
+ ACPI_SIZE Size;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
+
+
+ /* Start with the length of the (external) Acpi object */
+
+ Length = sizeof (ACPI_OBJECT);
+
+ /* A NULL object is allowed, can be a legal uninitialized package element */
+
+ if (!InternalObject)
+ {
+ /*
+ * Object is NULL, just return the length of ACPI_OBJECT
+ * (A NULL ACPI_OBJECT is an object of all zeroes.)
+ */
+ *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* A Namespace Node should never appear here */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
+ {
+ /* A namespace node should never get here */
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /*
+ * The final length depends on the object type
+ * Strings and Buffers are packed right up against the parent object and
+ * must be accessed bytewise or there may be alignment problems on
+ * certain processors
+ */
+ switch (InternalObject->Common.Type)
+ {
+ case ACPI_TYPE_STRING:
+
+ Length += (ACPI_SIZE) InternalObject->String.Length + 1;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ Length += (ACPI_SIZE) InternalObject->Buffer.Length;
+ break;
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+
+ /* No extra data for these types */
+
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ switch (InternalObject->Reference.Class)
+ {
+ case ACPI_REFCLASS_NAME:
+ /*
+ * Get the actual length of the full pathname to this object.
+ * The reference will be converted to the pathname to the object
+ */
+ Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
+ if (!Size)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
+ break;
+
+ default:
+ /*
+ * No other reference opcodes are supported.
+ * Notably, Locals and Args are not supported, but this may be
+ * required eventually.
+ */
+ ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
+ "unsupported Reference Class [%s] 0x%X in object %p",
+ AcpiUtGetReferenceName (InternalObject),
+ InternalObject->Reference.Class, InternalObject));
+ Status = AE_TYPE;
+ break;
+ }
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
+ "unsupported type [%s] 0x%X in object %p",
+ AcpiUtGetObjectTypeName (InternalObject),
+ InternalObject->Common.Type, InternalObject));
+ Status = AE_TYPE;
+ break;
+ }
+
+ /*
+ * Account for the space required by the object rounded up to the next
+ * multiple of the machine word size. This keeps each object aligned
+ * on a machine word boundary. (preventing alignment faults on some
+ * machines.)
+ */
+ *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetElementLength
+ *
+ * PARAMETERS: ACPI_PKG_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the length of one package element.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtGetElementLength (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context;
+ ACPI_SIZE ObjectSpace;
+
+
+ switch (ObjectType)
+ {
+ case ACPI_COPY_TYPE_SIMPLE:
+ /*
+ * Simple object - just get the size (Null object/entry is handled
+ * here also) and sum it into the running package length
+ */
+ Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Info->Length += ObjectSpace;
+ break;
+
+ case ACPI_COPY_TYPE_PACKAGE:
+
+ /* Package object - nothing much to do here, let the walk handle it */
+
+ Info->NumPackages++;
+ State->Pkg.ThisTargetObj = NULL;
+ break;
+
+ default:
+
+ /* No other types allowed */
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetPackageObjectSize
+ *
+ * PARAMETERS: InternalObject - An ACPI internal object
+ * ObjLength - Where the length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain a package object for return to an external user.
+ *
+ * This is moderately complex since a package contains other
+ * objects including packages.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtGetPackageObjectSize (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_SIZE *ObjLength)
+{
+ ACPI_STATUS Status;
+ ACPI_PKG_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
+
+
+ Info.Length = 0;
+ Info.ObjectSpace = 0;
+ Info.NumPackages = 1;
+
+ Status = AcpiUtWalkPackageTree (InternalObject, NULL,
+ AcpiUtGetElementLength, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * We have handled all of the objects in all levels of the package.
+ * just add the length of the package objects themselves.
+ * Round up to the next machine word.
+ */
+ Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
+ (ACPI_SIZE) Info.NumPackages;
+
+ /* Return the total package length */
+
+ *ObjLength = Info.Length;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetObjectSize
+ *
+ * PARAMETERS: InternalObject - An ACPI internal object
+ * ObjLength - Where the length will be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain an object for return to an API user.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtGetObjectSize (
+ ACPI_OPERAND_OBJECT *InternalObject,
+ ACPI_SIZE *ObjLength)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
+ (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
+ {
+ Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
+ }
+ else
+ {
+ Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
+ }
+
+ return (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utosi.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utosi.c
new file mode 100644
index 0000000000..d0dd1dc753
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utosi.c
@@ -0,0 +1,532 @@
+/******************************************************************************
+ *
+ * Module Name: utosi - Support for the _OSI predefined control method
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utosi")
+
+
+/******************************************************************************
+ *
+ * ACPICA policy for new _OSI strings:
+ *
+ * It is the stated policy of ACPICA that new _OSI strings will be integrated
+ * into this module as soon as possible after they are defined. It is strongly
+ * recommended that all ACPICA hosts mirror this policy and integrate any
+ * changes to this module as soon as possible. There are several historical
+ * reasons behind this policy:
+ *
+ * 1) New BIOSs tend to test only the case where the host responds TRUE to
+ * the latest version of Windows, which would respond to the latest/newest
+ * _OSI string. Not responding TRUE to the latest version of Windows will
+ * risk executing untested code paths throughout the DSDT and SSDTs.
+ *
+ * 2) If a new _OSI string is recognized only after a significant delay, this
+ * has the potential to cause problems on existing working machines because
+ * of the possibility that a new and different path through the ASL code
+ * will be executed.
+ *
+ * 3) New _OSI strings are tending to come out about once per year. A delay
+ * in recognizing a new string for a significant amount of time risks the
+ * release of another string which only compounds the initial problem.
+ *
+ *****************************************************************************/
+
+
+/*
+ * Strings supported by the _OSI predefined control method (which is
+ * implemented internally within this module.)
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The last element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
+ */
+static ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] =
+{
+ /* Operating System Vendor Strings */
+
+ {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
+ {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
+ {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
+ {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
+ {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
+ {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
+ {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
+ {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
+ {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
+ {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
+ {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
+ {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
+ {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
+ {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */
+
+ /* Feature Group Strings */
+
+ {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
+
+ /*
+ * All "optional" feature group strings (features that are implemented
+ * by the host) should be dynamically modified to VALID by the host via
+ * AcpiInstallInterface or AcpiUpdateInterfaces. Such optional feature
+ * group strings are set as INVALID by default here.
+ */
+
+ {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
+ {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
+ {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
+ {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
+ {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInitializeInterfaces
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the global _OSI supported interfaces list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtInitializeInterfaces (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces;
+
+ /* Link the static list of supported interfaces */
+
+ for (i = 0; i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1); i++)
+ {
+ AcpiDefaultSupportedInterfaces[i].Next =
+ &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1];
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInterfaceTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all interfaces in the global list. Sets
+ * AcpiGbl_SupportedInterfaces to NULL.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtInterfaceTerminate (
+ void)
+{
+ ACPI_STATUS Status;
+ ACPI_INTERFACE_INFO *NextInterface;
+
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+ while (NextInterface)
+ {
+ AcpiGbl_SupportedInterfaces = NextInterface->Next;
+
+ if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
+ {
+ /* Only interfaces added at runtime can be freed */
+
+ ACPI_FREE (NextInterface->Name);
+ ACPI_FREE (NextInterface);
+ }
+ else
+ {
+ /* Interface is in static list. Reset it to invalid or valid. */
+
+ if (NextInterface->Flags & ACPI_OSI_DEFAULT_INVALID)
+ {
+ NextInterface->Flags |= ACPI_OSI_INVALID;
+ }
+ else
+ {
+ NextInterface->Flags &= ~ACPI_OSI_INVALID;
+ }
+ }
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInstallInterface
+ *
+ * PARAMETERS: InterfaceName - The interface to install
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install the interface into the global interface list.
+ * Caller MUST hold AcpiGbl_OsiMutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtInstallInterface (
+ ACPI_STRING InterfaceName)
+{
+ ACPI_INTERFACE_INFO *InterfaceInfo;
+
+
+ /* Allocate info block and space for the name string */
+
+ InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
+ if (!InterfaceInfo)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (strlen (InterfaceName) + 1);
+ if (!InterfaceInfo->Name)
+ {
+ ACPI_FREE (InterfaceInfo);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Initialize new info and insert at the head of the global list */
+
+ strcpy (InterfaceInfo->Name, InterfaceName);
+ InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
+ InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
+
+ AcpiGbl_SupportedInterfaces = InterfaceInfo;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveInterface
+ *
+ * PARAMETERS: InterfaceName - The interface to remove
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove the interface from the global interface list.
+ * Caller MUST hold AcpiGbl_OsiMutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtRemoveInterface (
+ ACPI_STRING InterfaceName)
+{
+ ACPI_INTERFACE_INFO *PreviousInterface;
+ ACPI_INTERFACE_INFO *NextInterface;
+
+
+ PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
+ while (NextInterface)
+ {
+ if (!strcmp (InterfaceName, NextInterface->Name))
+ {
+ /* Found: name is in either the static list or was added at runtime */
+
+ if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
+ {
+ /* Interface was added dynamically, remove and free it */
+
+ if (PreviousInterface == NextInterface)
+ {
+ AcpiGbl_SupportedInterfaces = NextInterface->Next;
+ }
+ else
+ {
+ PreviousInterface->Next = NextInterface->Next;
+ }
+
+ ACPI_FREE (NextInterface->Name);
+ ACPI_FREE (NextInterface);
+ }
+ else
+ {
+ /*
+ * Interface is in static list. If marked invalid, then it
+ * does not actually exist. Else, mark it invalid.
+ */
+ if (NextInterface->Flags & ACPI_OSI_INVALID)
+ {
+ return (AE_NOT_EXIST);
+ }
+
+ NextInterface->Flags |= ACPI_OSI_INVALID;
+ }
+
+ return (AE_OK);
+ }
+
+ PreviousInterface = NextInterface;
+ NextInterface = NextInterface->Next;
+ }
+
+ /* Interface was not found */
+
+ return (AE_NOT_EXIST);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtUpdateInterfaces
+ *
+ * PARAMETERS: Action - Actions to be performed during the
+ * update
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
+ * strings or/and feature group strings.
+ * Caller MUST hold AcpiGbl_OsiMutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtUpdateInterfaces (
+ UINT8 Action)
+{
+ ACPI_INTERFACE_INFO *NextInterface;
+
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+ while (NextInterface)
+ {
+ if (((NextInterface->Flags & ACPI_OSI_FEATURE) &&
+ (Action & ACPI_FEATURE_STRINGS)) ||
+ (!(NextInterface->Flags & ACPI_OSI_FEATURE) &&
+ (Action & ACPI_VENDOR_STRINGS)))
+ {
+ if (Action & ACPI_DISABLE_INTERFACES)
+ {
+ /* Mark the interfaces as invalid */
+
+ NextInterface->Flags |= ACPI_OSI_INVALID;
+ }
+ else
+ {
+ /* Mark the interfaces as valid */
+
+ NextInterface->Flags &= ~ACPI_OSI_INVALID;
+ }
+ }
+
+ NextInterface = NextInterface->Next;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetInterface
+ *
+ * PARAMETERS: InterfaceName - The interface to find
+ *
+ * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found.
+ *
+ * DESCRIPTION: Search for the specified interface name in the global list.
+ * Caller MUST hold AcpiGbl_OsiMutex
+ *
+ ******************************************************************************/
+
+ACPI_INTERFACE_INFO *
+AcpiUtGetInterface (
+ ACPI_STRING InterfaceName)
+{
+ ACPI_INTERFACE_INFO *NextInterface;
+
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+ while (NextInterface)
+ {
+ if (!strcmp (InterfaceName, NextInterface->Name))
+ {
+ return (NextInterface);
+ }
+
+ NextInterface = NextInterface->Next;
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtOsiImplementation
+ *
+ * PARAMETERS: WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Implementation of the _OSI predefined control method. When
+ * an invocation of _OSI is encountered in the system AML,
+ * control is transferred to this function.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtOsiImplementation (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_OPERAND_OBJECT *StringDesc;
+ ACPI_OPERAND_OBJECT *ReturnDesc;
+ ACPI_INTERFACE_INFO *InterfaceInfo;
+ ACPI_INTERFACE_HANDLER InterfaceHandler;
+ ACPI_STATUS Status;
+ UINT32 ReturnValue;
+
+
+ ACPI_FUNCTION_TRACE (UtOsiImplementation);
+
+
+ /* Validate the string input argument (from the AML caller) */
+
+ StringDesc = WalkState->Arguments[0].Object;
+ if (!StringDesc ||
+ (StringDesc->Common.Type != ACPI_TYPE_STRING))
+ {
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Create a return object */
+
+ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
+ if (!ReturnDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Default return value is 0, NOT SUPPORTED */
+
+ ReturnValue = 0;
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Lookup the interface in the global _OSI list */
+
+ InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer);
+ if (InterfaceInfo &&
+ !(InterfaceInfo->Flags & ACPI_OSI_INVALID))
+ {
+ /*
+ * The interface is supported.
+ * Update the OsiData if necessary. We keep track of the latest
+ * version of Windows that has been requested by the BIOS.
+ */
+ if (InterfaceInfo->Value > AcpiGbl_OsiData)
+ {
+ AcpiGbl_OsiData = InterfaceInfo->Value;
+ }
+
+ ReturnValue = ACPI_UINT32_MAX;
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+
+ /*
+ * Invoke an optional _OSI interface handler. The host OS may wish
+ * to do some interface-specific handling. For example, warn about
+ * certain interfaces or override the true/false support value.
+ */
+ InterfaceHandler = AcpiGbl_InterfaceHandler;
+ if (InterfaceHandler)
+ {
+ ReturnValue = InterfaceHandler (
+ StringDesc->String.Pointer, ReturnValue);
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+ "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
+ StringDesc->String.Pointer, ReturnValue == 0 ? "not " : ""));
+
+ /* Complete the return object */
+
+ ReturnDesc->Integer.Value = ReturnValue;
+ WalkState->ReturnDesc = ReturnDesc;
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utownerid.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utownerid.c
new file mode 100644
index 0000000000..34c0024736
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utownerid.c
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ *
+ * Module Name: utownerid - Support for Table/Method Owner IDs
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utownerid")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAllocateOwnerId
+ *
+ * PARAMETERS: OwnerId - Where the new owner ID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
+ * track objects created by the table or method, to be deleted
+ * when the method exits or the table is unloaded.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtAllocateOwnerId (
+ ACPI_OWNER_ID *OwnerId)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 k;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtAllocateOwnerId);
+
+
+ /* Guard against multiple allocations of ID to the same location */
+
+ if (*OwnerId)
+ {
+ ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
+ return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ }
+
+ /* Mutex for the global ID mask */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Find a free owner ID, cycle through all possible IDs on repeated
+ * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
+ * to be scanned twice.
+ */
+ for (i = 0, j = AcpiGbl_LastOwnerIdIndex;
+ i < (ACPI_NUM_OWNERID_MASKS + 1);
+ i++, j++)
+ {
+ if (j >= ACPI_NUM_OWNERID_MASKS)
+ {
+ j = 0; /* Wraparound to start of mask array */
+ }
+
+ for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++)
+ {
+ if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX)
+ {
+ /* There are no free IDs in this mask */
+
+ break;
+ }
+
+ if (!(AcpiGbl_OwnerIdMask[j] & (1 << k)))
+ {
+ /*
+ * Found a free ID. The actual ID is the bit index plus one,
+ * making zero an invalid Owner ID. Save this as the last ID
+ * allocated and update the global ID mask.
+ */
+ AcpiGbl_OwnerIdMask[j] |= (1 << k);
+
+ AcpiGbl_LastOwnerIdIndex = (UINT8) j;
+ AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1);
+
+ /*
+ * Construct encoded ID from the index and bit position
+ *
+ * Note: Last [j].k (bit 255) is never used and is marked
+ * permanently allocated (prevents +1 overflow)
+ */
+ *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
+ "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId));
+ goto Exit;
+ }
+ }
+
+ AcpiGbl_NextOwnerIdOffset = 0;
+ }
+
+ /*
+ * All OwnerIds have been allocated. This typically should
+ * not happen since the IDs are reused after deallocation. The IDs are
+ * allocated upon table load (one per table) and method execution, and
+ * they are released when a table is unloaded or a method completes
+ * execution.
+ *
+ * If this error happens, there may be very deep nesting of invoked control
+ * methods, or there may be a bug where the IDs are not released.
+ */
+ Status = AE_OWNER_ID_LIMIT;
+ ACPI_ERROR ((AE_INFO,
+ "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
+
+Exit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtReleaseOwnerId
+ *
+ * PARAMETERS: OwnerIdPtr - Pointer to a previously allocated OwnerID
+ *
+ * RETURN: None. No error is returned because we are either exiting a
+ * control method or unloading a table. Either way, we would
+ * ignore any error anyway.
+ *
+ * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
+ *
+ ******************************************************************************/
+
+void
+AcpiUtReleaseOwnerId (
+ ACPI_OWNER_ID *OwnerIdPtr)
+{
+ ACPI_OWNER_ID OwnerId = *OwnerIdPtr;
+ ACPI_STATUS Status;
+ UINT32 Index;
+ UINT32 Bit;
+
+
+ ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId);
+
+
+ /* Always clear the input OwnerId (zero is an invalid ID) */
+
+ *OwnerIdPtr = 0;
+
+ /* Zero is not a valid OwnerID */
+
+ if (OwnerId == 0)
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
+ return_VOID;
+ }
+
+ /* Mutex for the global ID mask */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /* Normalize the ID to zero */
+
+ OwnerId--;
+
+ /* Decode ID to index/offset pair */
+
+ Index = ACPI_DIV_32 (OwnerId);
+ Bit = 1 << ACPI_MOD_32 (OwnerId);
+
+ /* Free the owner ID only if it is valid */
+
+ if (AcpiGbl_OwnerIdMask[Index] & Bit)
+ {
+ AcpiGbl_OwnerIdMask[Index] ^= Bit;
+ }
+ else
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
+ return_VOID;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utpredef.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utpredef.c
new file mode 100644
index 0000000000..fed8154ac7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utpredef.c
@@ -0,0 +1,450 @@
+/******************************************************************************
+ *
+ * Module Name: utpredef - support functions for predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utpredef")
+
+
+/*
+ * Names for the types that can be returned by the predefined objects.
+ * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
+ */
+static const char *UtRtypeNames[] =
+{
+ "/Integer",
+ "/String",
+ "/Buffer",
+ "/Package",
+ "/Reference",
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetNextPredefinedMethod
+ *
+ * PARAMETERS: ThisName - Entry in the predefined method/name table
+ *
+ * RETURN: Pointer to next entry in predefined table.
+ *
+ * DESCRIPTION: Get the next entry in the predefine method table. Handles the
+ * cases where a package info entry follows a method name that
+ * returns a package.
+ *
+ ******************************************************************************/
+
+const ACPI_PREDEFINED_INFO *
+AcpiUtGetNextPredefinedMethod (
+ const ACPI_PREDEFINED_INFO *ThisName)
+{
+
+ /*
+ * Skip next entry in the table if this name returns a Package
+ * (next entry contains the package info)
+ */
+ if ((ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) &&
+ (ThisName->Info.ExpectedBtypes != ACPI_RTYPE_ALL))
+ {
+ ThisName++;
+ }
+
+ ThisName++;
+ return (ThisName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtMatchPredefinedMethod
+ *
+ * PARAMETERS: Name - Name to find
+ *
+ * RETURN: Pointer to entry in predefined table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the predefined object list.
+ *
+ ******************************************************************************/
+
+const ACPI_PREDEFINED_INFO *
+AcpiUtMatchPredefinedMethod (
+ char *Name)
+{
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ /* Quick check for a predefined name, first character must be underscore */
+
+ if (Name[0] != '_')
+ {
+ return (NULL);
+ }
+
+ /* Search info table for a predefined method/object name */
+
+ ThisName = AcpiGbl_PredefinedMethods;
+ while (ThisName->Info.Name[0])
+ {
+ if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name))
+ {
+ return (ThisName);
+ }
+
+ ThisName = AcpiUtGetNextPredefinedMethod (ThisName);
+ }
+
+ return (NULL); /* Not found */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetExpectedReturnTypes
+ *
+ * PARAMETERS: Buffer - Where the formatted string is returned
+ * ExpectedBTypes - Bitfield of expected data types
+ *
+ * RETURN: Formatted string in Buffer.
+ *
+ * DESCRIPTION: Format the expected object types into a printable string.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtGetExpectedReturnTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes)
+{
+ UINT32 ThisRtype;
+ UINT32 i;
+ UINT32 j;
+
+
+ if (!ExpectedBtypes)
+ {
+ strcpy (Buffer, "NONE");
+ return;
+ }
+
+ j = 1;
+ Buffer[0] = 0;
+ ThisRtype = ACPI_RTYPE_INTEGER;
+
+ for (i = 0; i < ACPI_NUM_RTYPES; i++)
+ {
+ /* If one of the expected types, concatenate the name of this type */
+
+ if (ExpectedBtypes & ThisRtype)
+ {
+ strcat (Buffer, &UtRtypeNames[i][j]);
+ j = 0; /* Use name separator from now on */
+ }
+
+ ThisRtype <<= 1; /* Next Rtype */
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * The remaining functions are used by iASL and AcpiHelp only
+ *
+ ******************************************************************************/
+
+#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP)
+#include <stdio.h>
+#include <string.h>
+
+/* Local prototypes */
+
+static UINT32
+AcpiUtGetArgumentTypes (
+ char *Buffer,
+ UINT16 ArgumentTypes);
+
+
+/* Types that can be returned externally by a predefined name */
+
+static const char *UtExternalTypeNames[] = /* Indexed by ACPI_TYPE_* */
+{
+ ", UNSUPPORTED-TYPE",
+ ", Integer",
+ ", String",
+ ", Buffer",
+ ", Package"
+};
+
+/* Bit widths for resource descriptor predefined names */
+
+static const char *UtResourceTypeNames[] =
+{
+ "/1",
+ "/2",
+ "/3",
+ "/8",
+ "/16",
+ "/32",
+ "/64",
+ "/variable",
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtMatchResourceName
+ *
+ * PARAMETERS: Name - Name to find
+ *
+ * RETURN: Pointer to entry in the resource table. NULL indicates not
+ * found.
+ *
+ * DESCRIPTION: Check an object name against the predefined resource
+ * descriptor object list.
+ *
+ ******************************************************************************/
+
+const ACPI_PREDEFINED_INFO *
+AcpiUtMatchResourceName (
+ char *Name)
+{
+ const ACPI_PREDEFINED_INFO *ThisName;
+
+
+ /* Quick check for a predefined name, first character must be underscore */
+
+ if (Name[0] != '_')
+ {
+ return (NULL);
+ }
+
+ /* Search info table for a predefined method/object name */
+
+ ThisName = AcpiGbl_ResourceNames;
+ while (ThisName->Info.Name[0])
+ {
+ if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name))
+ {
+ return (ThisName);
+ }
+
+ ThisName++;
+ }
+
+ return (NULL); /* Not found */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDisplayPredefinedMethod
+ *
+ * PARAMETERS: Buffer - Scratch buffer for this function
+ * ThisName - Entry in the predefined method/name table
+ * MultiLine - TRUE if output should be on >1 line
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about a predefined method. Number and
+ * type of the input arguments, and expected type(s) for the
+ * return value, if any.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDisplayPredefinedMethod (
+ char *Buffer,
+ const ACPI_PREDEFINED_INFO *ThisName,
+ BOOLEAN MultiLine)
+{
+ UINT32 ArgCount;
+
+ /*
+ * Get the argument count and the string buffer
+ * containing all argument types
+ */
+ ArgCount = AcpiUtGetArgumentTypes (Buffer,
+ ThisName->Info.ArgumentList);
+
+ if (MultiLine)
+ {
+ printf (" ");
+ }
+
+ printf ("%4.4s Requires %s%u argument%s",
+ ThisName->Info.Name,
+ (ThisName->Info.ArgumentList & ARG_COUNT_IS_MINIMUM) ?
+ "(at least) " : "",
+ ArgCount, ArgCount != 1 ? "s" : "");
+
+ /* Display the types for any arguments */
+
+ if (ArgCount > 0)
+ {
+ printf (" (%s)", Buffer);
+ }
+
+ if (MultiLine)
+ {
+ printf ("\n ");
+ }
+
+ /* Get the return value type(s) allowed */
+
+ if (ThisName->Info.ExpectedBtypes)
+ {
+ AcpiUtGetExpectedReturnTypes (Buffer, ThisName->Info.ExpectedBtypes);
+ printf (" Return value types: %s\n", Buffer);
+ }
+ else
+ {
+ printf (" No return value\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetArgumentTypes
+ *
+ * PARAMETERS: Buffer - Where to return the formatted types
+ * ArgumentTypes - Types field for this method
+ *
+ * RETURN: Count - the number of arguments required for this method
+ *
+ * DESCRIPTION: Format the required data types for this method (Integer,
+ * String, Buffer, or Package) and return the required argument
+ * count.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiUtGetArgumentTypes (
+ char *Buffer,
+ UINT16 ArgumentTypes)
+{
+ UINT16 ThisArgumentType;
+ UINT16 SubIndex;
+ UINT16 ArgCount;
+ UINT32 i;
+
+
+ *Buffer = 0;
+ SubIndex = 2;
+
+ /* First field in the types list is the count of args to follow */
+
+ ArgCount = METHOD_GET_ARG_COUNT (ArgumentTypes);
+ if (ArgCount > METHOD_PREDEF_ARGS_MAX)
+ {
+ printf ("**** Invalid argument count (%u) "
+ "in predefined info structure\n", ArgCount);
+ return (ArgCount);
+ }
+
+ /* Get each argument from the list, convert to ascii, store to buffer */
+
+ for (i = 0; i < ArgCount; i++)
+ {
+ ThisArgumentType = METHOD_GET_NEXT_TYPE (ArgumentTypes);
+
+ if (!ThisArgumentType || (ThisArgumentType > METHOD_MAX_ARG_TYPE))
+ {
+ printf ("**** Invalid argument type (%u) "
+ "in predefined info structure\n", ThisArgumentType);
+ return (ArgCount);
+ }
+
+ strcat (Buffer, UtExternalTypeNames[ThisArgumentType] + SubIndex);
+ SubIndex = 0;
+ }
+
+ return (ArgCount);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetResourceBitWidth
+ *
+ * PARAMETERS: Buffer - Where the formatted string is returned
+ * Types - Bitfield of expected data types
+ *
+ * RETURN: Count of return types. Formatted string in Buffer.
+ *
+ * DESCRIPTION: Format the resource bit widths into a printable string.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiUtGetResourceBitWidth (
+ char *Buffer,
+ UINT16 Types)
+{
+ UINT32 i;
+ UINT16 SubIndex;
+ UINT32 Found;
+
+
+ *Buffer = 0;
+ SubIndex = 1;
+ Found = 0;
+
+ for (i = 0; i < NUM_RESOURCE_WIDTHS; i++)
+ {
+ if (Types & 1)
+ {
+ strcat (Buffer, &(UtResourceTypeNames[i][SubIndex]));
+ SubIndex = 0;
+ Found++;
+ }
+
+ Types >>= 1;
+ }
+
+ return (Found);
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utprint.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utprint.c
new file mode 100644
index 0000000000..dee3a7134b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utprint.c
@@ -0,0 +1,814 @@
+/******************************************************************************
+ *
+ * Module Name: utprint - Formatted printing routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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);
+
+
+/* Module globals */
+
+static const char AcpiGbl_LowerHexDigits[] = "0123456789abcdef";
+static const char AcpiGbl_UpperHexDigits[] = "0123456789ABCDEF";
+
+
+/*******************************************************************************
+ *
+ * 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/boot/sys/contrib/dev/acpica/components/utilities/utresrc.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utresrc.c
new file mode 100644
index 0000000000..65b23f198a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utresrc.c
@@ -0,0 +1,924 @@
+/*******************************************************************************
+ *
+ * Module Name: utresrc - Resource management utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acresrc.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utresrc")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
+
+/*
+ * Strings used to decode resource descriptors.
+ * Used by both the disassembler and the debugger resource dump routines
+ */
+const char *AcpiGbl_BmDecode[] =
+{
+ "NotBusMaster",
+ "BusMaster"
+};
+
+const char *AcpiGbl_ConfigDecode[] =
+{
+ "0 - Good Configuration",
+ "1 - Acceptable Configuration",
+ "2 - Suboptimal Configuration",
+ "3 - ***Invalid Configuration***",
+};
+
+const char *AcpiGbl_ConsumeDecode[] =
+{
+ "ResourceProducer",
+ "ResourceConsumer"
+};
+
+const char *AcpiGbl_DecDecode[] =
+{
+ "PosDecode",
+ "SubDecode"
+};
+
+const char *AcpiGbl_HeDecode[] =
+{
+ "Level",
+ "Edge"
+};
+
+const char *AcpiGbl_IoDecode[] =
+{
+ "Decode10",
+ "Decode16"
+};
+
+const char *AcpiGbl_LlDecode[] =
+{
+ "ActiveHigh",
+ "ActiveLow",
+ "ActiveBoth",
+ "Reserved"
+};
+
+const char *AcpiGbl_MaxDecode[] =
+{
+ "MaxNotFixed",
+ "MaxFixed"
+};
+
+const char *AcpiGbl_MemDecode[] =
+{
+ "NonCacheable",
+ "Cacheable",
+ "WriteCombining",
+ "Prefetchable"
+};
+
+const char *AcpiGbl_MinDecode[] =
+{
+ "MinNotFixed",
+ "MinFixed"
+};
+
+const char *AcpiGbl_MtpDecode[] =
+{
+ "AddressRangeMemory",
+ "AddressRangeReserved",
+ "AddressRangeACPI",
+ "AddressRangeNVS"
+};
+
+const char *AcpiGbl_RngDecode[] =
+{
+ "InvalidRanges",
+ "NonISAOnlyRanges",
+ "ISAOnlyRanges",
+ "EntireRange"
+};
+
+const char *AcpiGbl_RwDecode[] =
+{
+ "ReadOnly",
+ "ReadWrite"
+};
+
+const char *AcpiGbl_ShrDecode[] =
+{
+ "Exclusive",
+ "Shared",
+ "ExclusiveAndWake", /* ACPI 5.0 */
+ "SharedAndWake" /* ACPI 5.0 */
+};
+
+const char *AcpiGbl_SizDecode[] =
+{
+ "Transfer8",
+ "Transfer8_16",
+ "Transfer16",
+ "InvalidSize"
+};
+
+const char *AcpiGbl_TrsDecode[] =
+{
+ "DenseTranslation",
+ "SparseTranslation"
+};
+
+const char *AcpiGbl_TtpDecode[] =
+{
+ "TypeStatic",
+ "TypeTranslation"
+};
+
+const char *AcpiGbl_TypDecode[] =
+{
+ "Compatibility",
+ "TypeA",
+ "TypeB",
+ "TypeF"
+};
+
+const char *AcpiGbl_PpcDecode[] =
+{
+ "PullDefault",
+ "PullUp",
+ "PullDown",
+ "PullNone"
+};
+
+const char *AcpiGbl_IorDecode[] =
+{
+ "IoRestrictionNone",
+ "IoRestrictionInputOnly",
+ "IoRestrictionOutputOnly",
+ "IoRestrictionNoneAndPreserve"
+};
+
+const char *AcpiGbl_DtsDecode[] =
+{
+ "Width8bit",
+ "Width16bit",
+ "Width32bit",
+ "Width64bit",
+ "Width128bit",
+ "Width256bit",
+};
+
+/* GPIO connection type */
+
+const char *AcpiGbl_CtDecode[] =
+{
+ "Interrupt",
+ "I/O"
+};
+
+/* Serial bus type */
+
+const char *AcpiGbl_SbtDecode[] =
+{
+ "/* UNKNOWN serial bus type */",
+ "I2C",
+ "SPI",
+ "UART"
+};
+
+/* I2C serial bus access mode */
+
+const char *AcpiGbl_AmDecode[] =
+{
+ "AddressingMode7Bit",
+ "AddressingMode10Bit"
+};
+
+/* I2C serial bus slave mode */
+
+const char *AcpiGbl_SmDecode[] =
+{
+ "ControllerInitiated",
+ "DeviceInitiated"
+};
+
+/* SPI serial bus wire mode */
+
+const char *AcpiGbl_WmDecode[] =
+{
+ "FourWireMode",
+ "ThreeWireMode"
+};
+
+/* SPI serial clock phase */
+
+const char *AcpiGbl_CphDecode[] =
+{
+ "ClockPhaseFirst",
+ "ClockPhaseSecond"
+};
+
+/* SPI serial bus clock polarity */
+
+const char *AcpiGbl_CpoDecode[] =
+{
+ "ClockPolarityLow",
+ "ClockPolarityHigh"
+};
+
+/* SPI serial bus device polarity */
+
+const char *AcpiGbl_DpDecode[] =
+{
+ "PolarityLow",
+ "PolarityHigh"
+};
+
+/* UART serial bus endian */
+
+const char *AcpiGbl_EdDecode[] =
+{
+ "LittleEndian",
+ "BigEndian"
+};
+
+/* UART serial bus bits per byte */
+
+const char *AcpiGbl_BpbDecode[] =
+{
+ "DataBitsFive",
+ "DataBitsSix",
+ "DataBitsSeven",
+ "DataBitsEight",
+ "DataBitsNine",
+ "/* UNKNOWN Bits per byte */",
+ "/* UNKNOWN Bits per byte */",
+ "/* UNKNOWN Bits per byte */"
+};
+
+/* UART serial bus stop bits */
+
+const char *AcpiGbl_SbDecode[] =
+{
+ "StopBitsZero",
+ "StopBitsOne",
+ "StopBitsOnePlusHalf",
+ "StopBitsTwo"
+};
+
+/* UART serial bus flow control */
+
+const char *AcpiGbl_FcDecode[] =
+{
+ "FlowControlNone",
+ "FlowControlHardware",
+ "FlowControlXON",
+ "/* UNKNOWN flow control keyword */"
+};
+
+/* UART serial bus parity type */
+
+const char *AcpiGbl_PtDecode[] =
+{
+ "ParityTypeNone",
+ "ParityTypeEven",
+ "ParityTypeOdd",
+ "ParityTypeMark",
+ "ParityTypeSpace",
+ "/* UNKNOWN parity keyword */",
+ "/* UNKNOWN parity keyword */",
+ "/* UNKNOWN parity keyword */"
+};
+
+#endif
+
+
+/*
+ * Base sizes of the raw AML resource descriptors, indexed by resource type.
+ * Zero indicates a reserved (and therefore invalid) resource type.
+ */
+const UINT8 AcpiGbl_ResourceAmlSizes[] =
+{
+ /* Small descriptors */
+
+ 0,
+ 0,
+ 0,
+ 0,
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_IRQ),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_DMA),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_START_DEPENDENT),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_DEPENDENT),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_IO),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_IO),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_DMA),
+ 0,
+ 0,
+ 0,
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_VENDOR_SMALL),
+ ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_TAG),
+
+ /* Large descriptors */
+
+ 0,
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY24),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_GENERIC_REGISTER),
+ 0,
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_VENDOR_LARGE),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY32),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_FIXED_MEMORY32),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS32),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS16),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_IRQ),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS64),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_ADDRESS64),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO),
+ 0,
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_COMMON_SERIALBUS),
+};
+
+const UINT8 AcpiGbl_ResourceAmlSerialBusSizes[] =
+{
+ 0,
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS),
+ ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS),
+};
+
+
+/*
+ * Resource types, used to validate the resource length field.
+ * The length of fixed-length types must match exactly, variable
+ * lengths must meet the minimum required length, etc.
+ * Zero indicates a reserved (and therefore invalid) resource type.
+ */
+static const UINT8 AcpiGbl_ResourceTypes[] =
+{
+ /* Small descriptors */
+
+ 0,
+ 0,
+ 0,
+ 0,
+ ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */
+ ACPI_FIXED_LENGTH, /* 05 DMA */
+ ACPI_SMALL_VARIABLE_LENGTH, /* 06 StartDependentFunctions */
+ ACPI_FIXED_LENGTH, /* 07 EndDependentFunctions */
+ ACPI_FIXED_LENGTH, /* 08 IO */
+ ACPI_FIXED_LENGTH, /* 09 FixedIO */
+ ACPI_FIXED_LENGTH, /* 0A FixedDMA */
+ 0,
+ 0,
+ 0,
+ ACPI_VARIABLE_LENGTH, /* 0E VendorShort */
+ ACPI_FIXED_LENGTH, /* 0F EndTag */
+
+ /* Large descriptors */
+
+ 0,
+ ACPI_FIXED_LENGTH, /* 01 Memory24 */
+ ACPI_FIXED_LENGTH, /* 02 GenericRegister */
+ 0,
+ ACPI_VARIABLE_LENGTH, /* 04 VendorLong */
+ ACPI_FIXED_LENGTH, /* 05 Memory32 */
+ ACPI_FIXED_LENGTH, /* 06 Memory32Fixed */
+ ACPI_VARIABLE_LENGTH, /* 07 Dword* address */
+ ACPI_VARIABLE_LENGTH, /* 08 Word* address */
+ ACPI_VARIABLE_LENGTH, /* 09 ExtendedIRQ */
+ ACPI_VARIABLE_LENGTH, /* 0A Qword* address */
+ ACPI_FIXED_LENGTH, /* 0B Extended* address */
+ ACPI_VARIABLE_LENGTH, /* 0C Gpio* */
+ 0,
+ ACPI_VARIABLE_LENGTH /* 0E *SerialBus */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtWalkAmlResources
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * PARAMETERS: Aml - Pointer to the raw AML resource template
+ * AmlLength - Length of the entire template
+ * UserFunction - Called once for each descriptor found. If
+ * NULL, a pointer to the EndTag is returned
+ * Context - Passed to UserFunction
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
+ * once for each resource found.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtWalkAmlResources (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *Aml,
+ ACPI_SIZE AmlLength,
+ ACPI_WALK_AML_CALLBACK UserFunction,
+ void **Context)
+{
+ ACPI_STATUS Status;
+ UINT8 *EndAml;
+ UINT8 ResourceIndex;
+ UINT32 Length;
+ UINT32 Offset = 0;
+ UINT8 EndTag[2] = {0x79, 0x00};
+
+
+ ACPI_FUNCTION_TRACE (UtWalkAmlResources);
+
+
+ /* The absolute minimum resource template is one EndTag descriptor */
+
+ if (AmlLength < sizeof (AML_RESOURCE_END_TAG))
+ {
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+ }
+
+ /* Point to the end of the resource template buffer */
+
+ EndAml = Aml + AmlLength;
+
+ /* Walk the byte list, abort on any invalid descriptor type or length */
+
+ while (Aml < EndAml)
+ {
+ /* Validate the Resource Type and Resource Length */
+
+ Status = AcpiUtValidateResource (WalkState, Aml, &ResourceIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * Exit on failure. Cannot continue because the descriptor length
+ * may be bogus also.
+ */
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the length of this descriptor */
+
+ Length = AcpiUtGetDescriptorLength (Aml);
+
+ /* Invoke the user function */
+
+ if (UserFunction)
+ {
+ Status = UserFunction (Aml, Length, Offset, ResourceIndex, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* An EndTag descriptor terminates this resource template */
+
+ if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_END_TAG)
+ {
+ /*
+ * There must be at least one more byte in the buffer for
+ * the 2nd byte of the EndTag
+ */
+ if ((Aml + 1) >= EndAml)
+ {
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+ }
+
+ /* Return the pointer to the EndTag if requested */
+
+ if (!UserFunction)
+ {
+ *Context = Aml;
+ }
+
+ /* Normal exit */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ Aml += Length;
+ Offset += Length;
+ }
+
+ /* Did not find an EndTag descriptor */
+
+ if (UserFunction)
+ {
+ /* Insert an EndTag anyway. AcpiRsGetListLength always leaves room */
+
+ (void) AcpiUtValidateResource (WalkState, EndTag, &ResourceIndex);
+ Status = UserFunction (EndTag, 2, Offset, ResourceIndex, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidateResource
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Aml - Pointer to the raw AML resource descriptor
+ * ReturnIndex - Where the resource index is returned. NULL
+ * if the index is not required.
+ *
+ * RETURN: Status, and optionally the Index into the global resource tables
+ *
+ * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
+ * Type and Resource Length. Returns an index into the global
+ * resource information/dispatch tables for later use.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtValidateResource (
+ ACPI_WALK_STATE *WalkState,
+ void *Aml,
+ UINT8 *ReturnIndex)
+{
+ AML_RESOURCE *AmlResource;
+ UINT8 ResourceType;
+ UINT8 ResourceIndex;
+ ACPI_RS_LENGTH ResourceLength;
+ ACPI_RS_LENGTH MinimumResourceLength;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * 1) Validate the ResourceType field (Byte 0)
+ */
+ ResourceType = ACPI_GET8 (Aml);
+
+ /*
+ * Byte 0 contains the descriptor name (Resource Type)
+ * Examine the large/small bit in the resource header
+ */
+ if (ResourceType & ACPI_RESOURCE_NAME_LARGE)
+ {
+ /* Verify the large resource type (name) against the max */
+
+ if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX)
+ {
+ goto InvalidResource;
+ }
+
+ /*
+ * Large Resource Type -- bits 6:0 contain the name
+ * Translate range 0x80-0x8B to index range 0x10-0x1B
+ */
+ ResourceIndex = (UINT8) (ResourceType - 0x70);
+ }
+ else
+ {
+ /*
+ * Small Resource Type -- bits 6:3 contain the name
+ * Shift range to index range 0x00-0x0F
+ */
+ ResourceIndex = (UINT8)
+ ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
+ }
+
+ /*
+ * Check validity of the resource type, via AcpiGbl_ResourceTypes. Zero
+ * indicates an invalid resource.
+ */
+ if (!AcpiGbl_ResourceTypes[ResourceIndex])
+ {
+ goto InvalidResource;
+ }
+
+ /*
+ * Validate the ResourceLength field. This ensures that the length
+ * is at least reasonable, and guarantees that it is non-zero.
+ */
+ ResourceLength = AcpiUtGetResourceLength (Aml);
+ MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
+
+ /* Validate based upon the type of resource - fixed length or variable */
+
+ switch (AcpiGbl_ResourceTypes[ResourceIndex])
+ {
+ case ACPI_FIXED_LENGTH:
+
+ /* Fixed length resource, length must match exactly */
+
+ if (ResourceLength != MinimumResourceLength)
+ {
+ goto BadResourceLength;
+ }
+ break;
+
+ case ACPI_VARIABLE_LENGTH:
+
+ /* Variable length resource, length must be at least the minimum */
+
+ if (ResourceLength < MinimumResourceLength)
+ {
+ goto BadResourceLength;
+ }
+ break;
+
+ case ACPI_SMALL_VARIABLE_LENGTH:
+
+ /* Small variable length resource, length can be (Min) or (Min-1) */
+
+ if ((ResourceLength > MinimumResourceLength) ||
+ (ResourceLength < (MinimumResourceLength - 1)))
+ {
+ goto BadResourceLength;
+ }
+ break;
+
+ default:
+
+ /* Shouldn't happen (because of validation earlier), but be sure */
+
+ goto InvalidResource;
+ }
+
+ AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
+ if (ResourceType == ACPI_RESOURCE_NAME_SERIAL_BUS)
+ {
+ /* Validate the BusType field */
+
+ if ((AmlResource->CommonSerialBus.Type == 0) ||
+ (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
+ {
+ if (WalkState)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
+ AmlResource->CommonSerialBus.Type));
+ }
+ return (AE_AML_INVALID_RESOURCE_TYPE);
+ }
+ }
+
+ /* Optionally return the resource table index */
+
+ if (ReturnIndex)
+ {
+ *ReturnIndex = ResourceIndex;
+ }
+
+ return (AE_OK);
+
+
+InvalidResource:
+
+ if (WalkState)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+ ResourceType));
+ }
+ return (AE_AML_INVALID_RESOURCE_TYPE);
+
+BadResourceLength:
+
+ if (WalkState)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid resource descriptor length: Type "
+ "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
+ ResourceType, ResourceLength, MinimumResourceLength));
+ }
+ return (AE_AML_BAD_RESOURCE_LENGTH);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetResourceType
+ *
+ * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
+ *
+ * RETURN: The Resource Type with no extraneous bits (except the
+ * Large/Small descriptor bit -- this is left alone)
+ *
+ * DESCRIPTION: Extract the Resource Type/Name from the first byte of
+ * a resource descriptor.
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiUtGetResourceType (
+ void *Aml)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Byte 0 contains the descriptor name (Resource Type)
+ * Examine the large/small bit in the resource header
+ */
+ if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
+ {
+ /* Large Resource Type -- bits 6:0 contain the name */
+
+ return (ACPI_GET8 (Aml));
+ }
+ else
+ {
+ /* Small Resource Type -- bits 6:3 contain the name */
+
+ return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetResourceLength
+ *
+ * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
+ *
+ * RETURN: Byte Length
+ *
+ * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
+ * definition, this does not include the size of the descriptor
+ * header or the length field itself.
+ *
+ ******************************************************************************/
+
+UINT16
+AcpiUtGetResourceLength (
+ void *Aml)
+{
+ ACPI_RS_LENGTH ResourceLength;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Byte 0 contains the descriptor name (Resource Type)
+ * Examine the large/small bit in the resource header
+ */
+ if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
+ {
+ /* Large Resource type -- bytes 1-2 contain the 16-bit length */
+
+ ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1));
+
+ }
+ else
+ {
+ /* Small Resource type -- bits 2:0 of byte 0 contain the length */
+
+ ResourceLength = (UINT16) (ACPI_GET8 (Aml) &
+ ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
+ }
+
+ return (ResourceLength);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetResourceHeaderLength
+ *
+ * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
+ *
+ * RETURN: Length of the AML header (depends on large/small descriptor)
+ *
+ * DESCRIPTION: Get the length of the header for this resource.
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiUtGetResourceHeaderLength (
+ void *Aml)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Examine the large/small bit in the resource header */
+
+ if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
+ {
+ return (sizeof (AML_RESOURCE_LARGE_HEADER));
+ }
+ else
+ {
+ return (sizeof (AML_RESOURCE_SMALL_HEADER));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetDescriptorLength
+ *
+ * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
+ *
+ * RETURN: Byte length
+ *
+ * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
+ * length of the descriptor header and the length field itself.
+ * Used to walk descriptor lists.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiUtGetDescriptorLength (
+ void *Aml)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Get the Resource Length (does not include header length) and add
+ * the header length (depends on if this is a small or large resource)
+ */
+ return (AcpiUtGetResourceLength (Aml) +
+ AcpiUtGetResourceHeaderLength (Aml));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetResourceEndTag
+ *
+ * PARAMETERS: ObjDesc - The resource template buffer object
+ * EndTag - Where the pointer to the EndTag is returned
+ *
+ * RETURN: Status, pointer to the end tag
+ *
+ * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template
+ * Note: allows a buffer length of zero.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtGetResourceEndTag (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 **EndTag)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (UtGetResourceEndTag);
+
+
+ /* Allow a buffer length of zero */
+
+ if (!ObjDesc->Buffer.Length)
+ {
+ *EndTag = ObjDesc->Buffer.Pointer;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Validate the template and get a pointer to the EndTag */
+
+ Status = AcpiUtWalkAmlResources (NULL, ObjDesc->Buffer.Pointer,
+ ObjDesc->Buffer.Length, NULL, (void **) EndTag);
+
+ return_ACPI_STATUS (Status);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstate.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstate.c
new file mode 100644
index 0000000000..339631965a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstate.c
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ *
+ * Module Name: utstate - state object support procedures
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utstate")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPushGenericState
+ *
+ * PARAMETERS: ListHead - Head of the state stack
+ * State - State object to push
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push a state object onto a state stack
+ *
+ ******************************************************************************/
+
+void
+AcpiUtPushGenericState (
+ ACPI_GENERIC_STATE **ListHead,
+ ACPI_GENERIC_STATE *State)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Push the state object onto the front of the list (stack) */
+
+ State->Common.Next = *ListHead;
+ *ListHead = State;
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPopGenericState
+ *
+ * PARAMETERS: ListHead - Head of the state stack
+ *
+ * RETURN: The popped state object
+ *
+ * DESCRIPTION: Pop a state object from a state stack
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+AcpiUtPopGenericState (
+ ACPI_GENERIC_STATE **ListHead)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Remove the state object at the head of the list (stack) */
+
+ State = *ListHead;
+ if (State)
+ {
+ /* Update the list head */
+
+ *ListHead = State->Common.Next;
+ }
+
+ return (State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateGenericState
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: The new state object. NULL on failure.
+ *
+ * DESCRIPTION: Create a generic state object. Attempt to obtain one from
+ * the global state cache; If none available, create a new one.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateGenericState (
+ void)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ State = AcpiOsAcquireObject (AcpiGbl_StateCache);
+ if (State)
+ {
+ /* Initialize */
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE;
+ }
+
+ return (State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateThreadState
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New Thread State. NULL on failure
+ *
+ * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
+ * to track per-thread info during method execution
+ *
+ ******************************************************************************/
+
+ACPI_THREAD_STATE *
+AcpiUtCreateThreadState (
+ void)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Create the generic state object */
+
+ State = AcpiUtCreateGenericState ();
+ if (!State)
+ {
+ return (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_THREAD;
+ State->Thread.ThreadId = AcpiOsGetThreadId ();
+
+ /* Check for invalid thread ID - zero is very bad, it will break things */
+
+ if (!State->Thread.ThreadId)
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
+ State->Thread.ThreadId = (ACPI_THREAD_ID) 1;
+ }
+
+ return ((ACPI_THREAD_STATE *) State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateUpdateState
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ * to update reference counts and delete complex objects such
+ * as packages.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateUpdateState (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Create the generic state object */
+
+ State = AcpiUtCreateGenericState ();
+ if (!State)
+ {
+ return (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_UPDATE;
+ State->Update.Object = Object;
+ State->Update.Value = Action;
+ return (State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreatePkgState
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create a "Package State"
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+AcpiUtCreatePkgState (
+ void *InternalObject,
+ void *ExternalObject,
+ UINT16 Index)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Create the generic state object */
+
+ State = AcpiUtCreateGenericState ();
+ if (!State)
+ {
+ return (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_PACKAGE;
+ State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
+ State->Pkg.DestObject = ExternalObject;
+ State->Pkg.Index= Index;
+ State->Pkg.NumPackages = 1;
+ return (State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateControlState
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New state object, null on failure
+ *
+ * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
+ * to support nested IF/WHILE constructs in the AML.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateControlState (
+ void)
+{
+ ACPI_GENERIC_STATE *State;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Create the generic state object */
+
+ State = AcpiUtCreateGenericState ();
+ if (!State)
+ {
+ return (NULL);
+ }
+
+ /* Init fields specific to the control struct */
+
+ State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_CONTROL;
+ State->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
+ return (State);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDeleteGenericState
+ *
+ * PARAMETERS: State - The state object to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release a state object to the state cache. NULL state objects
+ * are ignored.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDeleteGenericState (
+ ACPI_GENERIC_STATE *State)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Ignore null state */
+
+ if (State)
+ {
+ (void) AcpiOsReleaseObject (AcpiGbl_StateCache, State);
+ }
+ return;
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstring.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstring.c
new file mode 100644
index 0000000000..07525cb9bf
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utstring.c
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ *
+ * Module Name: utstring - Common functions for strings and characters
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utstring")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtPrintString
+ *
+ * PARAMETERS: String - Null terminated ASCII string
+ * MaxLength - Maximum output length. Used to constrain the
+ * length of strings during debug output only.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
+ * sequences.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtPrintString (
+ char *String,
+ UINT16 MaxLength)
+{
+ UINT32 i;
+
+
+ if (!String)
+ {
+ AcpiOsPrintf ("<\"NULL STRING PTR\">");
+ return;
+ }
+
+ AcpiOsPrintf ("\"");
+ for (i = 0; (i < MaxLength) && String[i]; i++)
+ {
+ /* Escape sequences */
+
+ switch (String[i])
+ {
+ case 0x07:
+
+ AcpiOsPrintf ("\\a"); /* BELL */
+ break;
+
+ case 0x08:
+
+ AcpiOsPrintf ("\\b"); /* BACKSPACE */
+ break;
+
+ case 0x0C:
+
+ AcpiOsPrintf ("\\f"); /* FORMFEED */
+ break;
+
+ case 0x0A:
+
+ AcpiOsPrintf ("\\n"); /* LINEFEED */
+ break;
+
+ case 0x0D:
+
+ AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/
+ break;
+
+ case 0x09:
+
+ AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */
+ break;
+
+ case 0x0B:
+
+ AcpiOsPrintf ("\\v"); /* VERTICAL TAB */
+ break;
+
+ case '\'': /* Single Quote */
+ case '\"': /* Double Quote */
+ case '\\': /* Backslash */
+
+ AcpiOsPrintf ("\\%c", (int) String[i]);
+ break;
+
+ default:
+
+ /* Check for printable character or hex escape */
+
+ if (isprint ((int) String[i]))
+ {
+ /* This is a normal character */
+
+ AcpiOsPrintf ("%c", (int) String[i]);
+ }
+ else
+ {
+ /* All others will be Hex escapes */
+
+ AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
+ }
+ break;
+ }
+ }
+ AcpiOsPrintf ("\"");
+
+ if (i == MaxLength && String[i])
+ {
+ AcpiOsPrintf ("...");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidAcpiChar
+ *
+ * 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
+AcpiUtValidAcpiChar (
+ 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: AcpiUtValidAcpiName
+ *
+ * PARAMETERS: Name - The name to be examined. Does not have to
+ * be NULL terminated string.
+ *
+ * RETURN: TRUE if the name is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
+ * 1) Upper case alpha
+ * 2) numeric
+ * 3) underscore
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtValidAcpiName (
+ char *Name)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (!AcpiUtValidAcpiChar (Name[i], i))
+ {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRepairName
+ *
+ * PARAMETERS: Name - The ACPI name to be repaired
+ *
+ * RETURN: Repaired version of the name
+ *
+ * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
+ * return the new name. NOTE: the Name parameter must reside in
+ * read/write memory, cannot be a const.
+ *
+ * An ACPI Name must consist of valid ACPI characters. We will repair the name
+ * if necessary because we don't want to abort because of this, but we want
+ * all namespace names to be printable. A warning message is appropriate.
+ *
+ * This issue came up because there are in fact machines that exhibit
+ * this problem, and we want to be able to enable ACPI support for them,
+ * even though there are a few bad names.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtRepairName (
+ char *Name)
+{
+ UINT32 i;
+ BOOLEAN FoundBadChar = FALSE;
+ UINT32 OriginalName;
+
+
+ ACPI_FUNCTION_NAME (UtRepairName);
+
+
+ ACPI_MOVE_NAME (&OriginalName, Name);
+
+ /* Check each character in the name */
+
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (AcpiUtValidAcpiChar (Name[i], i))
+ {
+ continue;
+ }
+
+ /*
+ * Replace a bad character with something printable, yet technically
+ * still invalid. This prevents any collisions with existing "good"
+ * names in the namespace.
+ */
+ Name[i] = '*';
+ FoundBadChar = TRUE;
+ }
+
+ if (FoundBadChar)
+ {
+ /* Report warning only if in strict mode or debug mode */
+
+ if (!AcpiGbl_EnableInterpreterSlack)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
+ OriginalName, Name));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
+ OriginalName, Name));
+ }
+ }
+}
+
+
+#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
+/*******************************************************************************
+ *
+ * FUNCTION: UtConvertBackslashes
+ *
+ * PARAMETERS: Pathname - File pathname string to be converted
+ *
+ * RETURN: Modifies the input Pathname
+ *
+ * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
+ * the entire input file pathname string.
+ *
+ ******************************************************************************/
+
+void
+UtConvertBackslashes (
+ char *Pathname)
+{
+
+ if (!Pathname)
+ {
+ return;
+ }
+
+ while (*Pathname)
+ {
+ if (*Pathname == '\\')
+ {
+ *Pathname = '/';
+ }
+
+ Pathname++;
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uttrack.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uttrack.c
new file mode 100644
index 0000000000..d7803974f3
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/uttrack.c
@@ -0,0 +1,780 @@
+/******************************************************************************
+ *
+ * Module Name: uttrack - Memory allocation tracking routines (debug only)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/*
+ * These procedures are used for tracking memory leaks in the subsystem, and
+ * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
+ *
+ * Each memory allocation is tracked via a doubly linked list. Each
+ * element contains the caller's component, module name, function name, and
+ * line number. AcpiUtAllocate and AcpiUtAllocateZeroed call
+ * AcpiUtTrackAllocation to add an element to the list; deletion
+ * occurs in the body of AcpiUtFree.
+ */
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("uttrack")
+
+
+/* Local prototypes */
+
+static ACPI_DEBUG_MEM_BLOCK *
+AcpiUtFindAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Allocation);
+
+static ACPI_STATUS
+AcpiUtTrackAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Address,
+ ACPI_SIZE Size,
+ UINT8 AllocType,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line);
+
+static ACPI_STATUS
+AcpiUtRemoveAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Address,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtCreateList
+ *
+ * PARAMETERS: CacheName - Ascii name for the cache
+ * ObjectSize - Size of each cached object
+ * ReturnCache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a local memory list for tracking purposed
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtCreateList (
+ char *ListName,
+ UINT16 ObjectSize,
+ ACPI_MEMORY_LIST **ReturnCache)
+{
+ ACPI_MEMORY_LIST *Cache;
+
+
+ Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST));
+ if (!Cache)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ memset (Cache, 0, sizeof (ACPI_MEMORY_LIST));
+
+ Cache->ListName = ListName;
+ Cache->ObjectSize = ObjectSize;
+
+ *ReturnCache = Cache;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAllocateAndTrack
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+AcpiUtAllocateAndTrack (
+ ACPI_SIZE Size,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line)
+{
+ ACPI_DEBUG_MEM_BLOCK *Allocation;
+ ACPI_STATUS Status;
+
+
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!Size)
+ {
+ ACPI_WARNING ((Module, Line,
+ "Attempt to allocate zero bytes, allocating 1 byte"));
+ Size = 1;
+ }
+
+ Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER));
+ if (!Allocation)
+ {
+ /* Report allocation error */
+
+ ACPI_WARNING ((Module, Line,
+ "Could not allocate size %u", (UINT32) Size));
+
+ return (NULL);
+ }
+
+ Status = AcpiUtTrackAllocation (Allocation, Size,
+ ACPI_MEM_MALLOC, Component, Module, Line);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsFree (Allocation);
+ return (NULL);
+ }
+
+ AcpiGbl_GlobalList->TotalAllocated++;
+ AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
+ AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
+ if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied)
+ {
+ AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize;
+ }
+
+ return ((void *) &Allocation->UserSpace);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtAllocateZeroedAndTrack
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+AcpiUtAllocateZeroedAndTrack (
+ ACPI_SIZE Size,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line)
+{
+ ACPI_DEBUG_MEM_BLOCK *Allocation;
+ ACPI_STATUS Status;
+
+
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!Size)
+ {
+ ACPI_WARNING ((Module, Line,
+ "Attempt to allocate zero bytes, allocating 1 byte"));
+ Size = 1;
+ }
+
+ Allocation = AcpiOsAllocateZeroed (Size + sizeof (ACPI_DEBUG_MEM_HEADER));
+ if (!Allocation)
+ {
+ /* Report allocation error */
+
+ ACPI_ERROR ((Module, Line,
+ "Could not allocate size %u", (UINT32) Size));
+ return (NULL);
+ }
+
+ Status = AcpiUtTrackAllocation (Allocation, Size,
+ ACPI_MEM_CALLOC, Component, Module, Line);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsFree (Allocation);
+ return (NULL);
+ }
+
+ AcpiGbl_GlobalList->TotalAllocated++;
+ AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
+ AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
+ if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied)
+ {
+ AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize;
+ }
+
+ return ((void *) &Allocation->UserSpace);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtFreeAndTrack
+ *
+ * PARAMETERS: Allocation - Address of the memory to deallocate
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Frees the memory at Allocation
+ *
+ ******************************************************************************/
+
+void
+AcpiUtFreeAndTrack (
+ void *Allocation,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line)
+{
+ ACPI_DEBUG_MEM_BLOCK *DebugBlock;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (UtFree, Allocation);
+
+
+ if (NULL == Allocation)
+ {
+ ACPI_ERROR ((Module, Line,
+ "Attempt to delete a NULL address"));
+
+ return_VOID;
+ }
+
+ DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK,
+ (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER)));
+
+ AcpiGbl_GlobalList->TotalFreed++;
+ AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size;
+
+ Status = AcpiUtRemoveAllocation (DebugBlock,
+ Component, Module, Line);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory"));
+ }
+
+ AcpiOsFree (DebugBlock);
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n",
+ Allocation, DebugBlock));
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtFindAllocation
+ *
+ * PARAMETERS: Allocation - Address of allocated memory
+ *
+ * RETURN: Three cases:
+ * 1) List is empty, NULL is returned.
+ * 2) Element was found. Returns Allocation parameter.
+ * 3) Element was not found. Returns position where it should be
+ * inserted into the list.
+ *
+ * DESCRIPTION: Searches for an element in the global allocation tracking list.
+ * If the element is not found, returns the location within the
+ * list where the element should be inserted.
+ *
+ * Note: The list is ordered by larger-to-smaller addresses.
+ *
+ * This global list is used to detect memory leaks in ACPICA as
+ * well as other issues such as an attempt to release the same
+ * internal object more than once. Although expensive as far
+ * as cpu time, this list is much more helpful for finding these
+ * types of issues than using memory leak detectors outside of
+ * the ACPICA code.
+ *
+ ******************************************************************************/
+
+static ACPI_DEBUG_MEM_BLOCK *
+AcpiUtFindAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Allocation)
+{
+ ACPI_DEBUG_MEM_BLOCK *Element;
+
+
+ Element = AcpiGbl_GlobalList->ListHead;
+ if (!Element)
+ {
+ return (NULL);
+ }
+
+ /*
+ * Search for the address.
+ *
+ * Note: List is ordered by larger-to-smaller addresses, on the
+ * assumption that a new allocation usually has a larger address
+ * than previous allocations.
+ */
+ while (Element > Allocation)
+ {
+ /* Check for end-of-list */
+
+ if (!Element->Next)
+ {
+ return (Element);
+ }
+
+ Element = Element->Next;
+ }
+
+ if (Element == Allocation)
+ {
+ return (Element);
+ }
+
+ return (Element->Previous);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtTrackAllocation
+ *
+ * PARAMETERS: Allocation - Address of allocated memory
+ * Size - Size of the allocation
+ * AllocType - MEM_MALLOC or MEM_CALLOC
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Inserts an element into the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtTrackAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Allocation,
+ ACPI_SIZE Size,
+ UINT8 AllocType,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line)
+{
+ ACPI_MEMORY_LIST *MemList;
+ ACPI_DEBUG_MEM_BLOCK *Element;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation);
+
+
+ if (AcpiGbl_DisableMemTracking)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ MemList = AcpiGbl_GlobalList;
+ Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Search the global list for this address to make sure it is not
+ * already present. This will catch several kinds of problems.
+ */
+ Element = AcpiUtFindAllocation (Allocation);
+ if (Element == Allocation)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "UtTrackAllocation: Allocation (%p) already present in global list!",
+ Allocation));
+ goto UnlockAndExit;
+ }
+
+ /* Fill in the instance data */
+
+ Allocation->Size = (UINT32) Size;
+ Allocation->AllocType = AllocType;
+ Allocation->Component = Component;
+ Allocation->Line = Line;
+
+ strncpy (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
+ Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
+
+ if (!Element)
+ {
+ /* Insert at list head */
+
+ if (MemList->ListHead)
+ {
+ ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation;
+ }
+
+ Allocation->Next = MemList->ListHead;
+ Allocation->Previous = NULL;
+
+ MemList->ListHead = Allocation;
+ }
+ else
+ {
+ /* Insert after element */
+
+ Allocation->Next = Element->Next;
+ Allocation->Previous = Element;
+
+ if (Element->Next)
+ {
+ (Element->Next)->Previous = Allocation;
+ }
+
+ Element->Next = Allocation;
+ }
+
+
+UnlockAndExit:
+ Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveAllocation
+ *
+ * PARAMETERS: Allocation - Address of allocated memory
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Deletes an element from the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtRemoveAllocation (
+ ACPI_DEBUG_MEM_BLOCK *Allocation,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line)
+{
+ ACPI_MEMORY_LIST *MemList;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_NAME (UtRemoveAllocation);
+
+
+ if (AcpiGbl_DisableMemTracking)
+ {
+ return (AE_OK);
+ }
+
+ MemList = AcpiGbl_GlobalList;
+ if (NULL == MemList->ListHead)
+ {
+ /* No allocations! */
+
+ ACPI_ERROR ((Module, Line,
+ "Empty allocation list, nothing to free!"));
+
+ return (AE_OK);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Unlink */
+
+ if (Allocation->Previous)
+ {
+ (Allocation->Previous)->Next = Allocation->Next;
+ }
+ else
+ {
+ MemList->ListHead = Allocation->Next;
+ }
+
+ if (Allocation->Next)
+ {
+ (Allocation->Next)->Previous = Allocation->Previous;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
+ &Allocation->UserSpace, Allocation->Size));
+
+ /* Mark the segment as deleted */
+
+ memset (&Allocation->UserSpace, 0xEA, Allocation->Size);
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDumpAllocationInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print some info about the outstanding allocations.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDumpAllocationInfo (
+ void)
+{
+/*
+ ACPI_MEMORY_LIST *MemList;
+*/
+
+ ACPI_FUNCTION_TRACE (UtDumpAllocationInfo);
+
+/*
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current allocations",
+ MemList->CurrentCount,
+ ROUND_UP_TO_1K (MemList->CurrentSize)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
+ MemList->MaxConcurrentCount,
+ ROUND_UP_TO_1K (MemList->MaxConcurrentSize)));
+
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
+ RunningObjectCount,
+ ROUND_UP_TO_1K (RunningObjectSize)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
+ RunningAllocCount,
+ ROUND_UP_TO_1K (RunningAllocSize)));
+
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current Nodes",
+ AcpiGbl_CurrentNodeCount,
+ ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max Nodes",
+ AcpiGbl_MaxConcurrentNodeCount,
+ ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount *
+ sizeof (ACPI_NAMESPACE_NODE)))));
+*/
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDumpAllocations
+ *
+ * PARAMETERS: Component - Component(s) to dump info for.
+ * Module - Module to dump info for. NULL means all.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a list of all outstanding allocations.
+ *
+ ******************************************************************************/
+
+void
+AcpiUtDumpAllocations (
+ UINT32 Component,
+ const char *Module)
+{
+ ACPI_DEBUG_MEM_BLOCK *Element;
+ ACPI_DESCRIPTOR *Descriptor;
+ UINT32 NumOutstanding = 0;
+ UINT8 DescriptorType;
+
+
+ ACPI_FUNCTION_TRACE (UtDumpAllocations);
+
+
+ if (AcpiGbl_DisableMemTracking)
+ {
+ return_VOID;
+ }
+
+ /*
+ * Walk the allocation list.
+ */
+ if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
+ {
+ return_VOID;
+ }
+
+ Element = AcpiGbl_GlobalList->ListHead;
+ while (Element)
+ {
+ if ((Element->Component & Component) &&
+ ((Module == NULL) || (0 == strcmp (Module, Element->Module))))
+ {
+ Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace);
+
+ if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR))
+ {
+ AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u "
+ "[Not a Descriptor - too small]\n",
+ Descriptor, Element->Size, Element->Module,
+ Element->Line);
+ }
+ else
+ {
+ /* Ignore allocated objects that are in a cache */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != ACPI_DESC_TYPE_CACHED)
+ {
+ AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ",
+ Descriptor, Element->Size, Element->Module,
+ Element->Line, AcpiUtGetDescriptorName (Descriptor));
+
+ /* Validate the descriptor type using Type field and length */
+
+ DescriptorType = 0; /* Not a valid descriptor type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
+ {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ if (Element->Size == sizeof (ACPI_OPERAND_OBJECT))
+ {
+ DescriptorType = ACPI_DESC_TYPE_OPERAND;
+ }
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+
+ if (Element->Size == sizeof (ACPI_PARSE_OBJECT))
+ {
+ DescriptorType = ACPI_DESC_TYPE_PARSER;
+ }
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+
+ if (Element->Size == sizeof (ACPI_NAMESPACE_NODE))
+ {
+ DescriptorType = ACPI_DESC_TYPE_NAMED;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Display additional info for the major descriptor types */
+
+ switch (DescriptorType)
+ {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ AcpiOsPrintf ("%12.12s RefCount 0x%04X\n",
+ AcpiUtGetTypeName (Descriptor->Object.Common.Type),
+ Descriptor->Object.Common.ReferenceCount);
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+
+ AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
+ Descriptor->Op.Asl.AmlOpcode);
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+
+ AcpiOsPrintf ("%4.4s\n",
+ AcpiUtGetNodeName (&Descriptor->Node));
+ break;
+
+ default:
+
+ AcpiOsPrintf ( "\n");
+ break;
+ }
+ }
+ }
+
+ NumOutstanding++;
+ }
+
+ Element = Element->Next;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
+
+ /* Print summary */
+
+ if (!NumOutstanding)
+ {
+ ACPI_INFO ((AE_INFO, "No outstanding allocations"));
+ }
+ else
+ {
+ ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
+ NumOutstanding, NumOutstanding));
+ }
+
+ return_VOID;
+}
+
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utuuid.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utuuid.c
new file mode 100644
index 0000000000..435c6c338f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utuuid.c
@@ -0,0 +1,103 @@
+/******************************************************************************
+ *
+ * Module Name: utuuid -- UUID support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("utuuid")
+
+
+#if (defined ACPI_ASL_COMPILER || defined ACPI_DISASSEMBLER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP)
+/*
+ * UUID support functions.
+ *
+ * This table is used to convert an input UUID ascii string to a 16 byte
+ * buffer and the reverse. The table maps a UUID buffer index 0-15 to
+ * the index within the 36-byte UUID string where the associated 2-byte
+ * hex value can be found.
+ *
+ * 36-byte UUID strings are of the form:
+ * aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+ * Where aa-pp are one byte hex numbers, made up of two hex digits
+ *
+ * Note: This table is basically the inverse of the string-to-offset table
+ * found in the ACPI spec in the description of the ToUUID macro.
+ */
+const UINT8 AcpiGbl_MapToUuidOffset[UUID_BUFFER_LENGTH] =
+{
+ 6,4,2,0,11,9,16,14,19,21,24,26,28,30,32,34
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtConvertStringToUuid
+ *
+ * PARAMETERS: InString - 36-byte formatted UUID string
+ * UuidBuffer - Where the 16-byte UUID buffer is returned
+ *
+ * RETURN: None. Output data is returned in the UuidBuffer
+ *
+ * DESCRIPTION: Convert a 36-byte formatted UUID string to 16-byte UUID buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiUtConvertStringToUuid (
+ char *InString,
+ UINT8 *UuidBuffer)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < UUID_BUFFER_LENGTH; i++)
+ {
+ UuidBuffer[i] =
+ (AcpiUtAsciiCharToHex (InString[AcpiGbl_MapToUuidOffset[i]]) << 4);
+
+ UuidBuffer[i] |=
+ AcpiUtAsciiCharToHex (InString[AcpiGbl_MapToUuidOffset[i] + 1]);
+ }
+}
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxface.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxface.c
new file mode 100644
index 0000000000..c3fc066484
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxface.c
@@ -0,0 +1,664 @@
+/******************************************************************************
+ *
+ * Module Name: utxface - External interfaces, miscellaneous utility functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTerminate (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiTerminate);
+
+
+ /* Just exit if subsystem is already shutdown */
+
+ if (AcpiGbl_Shutdown)
+ {
+ ACPI_ERROR ((AE_INFO, "ACPI Subsystem is already terminated"));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Subsystem appears active, go ahead and shut it down */
+
+ AcpiGbl_Shutdown = TRUE;
+ AcpiGbl_StartupFlags = 0;
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
+ /* Terminate the AML Debugger if present */
+
+ ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = TRUE);
+
+ /* Shutdown and free all resources */
+
+ AcpiUtSubsystemShutdown ();
+
+ /* Free the mutex objects */
+
+ AcpiUtMutexTerminate ();
+
+ /* Now we can shutdown the OS-dependent layer */
+
+ Status = AcpiOsTerminate ();
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiTerminate)
+
+
+#ifndef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSubsystemStatus
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status of the ACPI subsystem
+ *
+ * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
+ * before making any other calls, to ensure the subsystem
+ * initialized successfully.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSubsystemStatus (
+ void)
+{
+
+ if (AcpiGbl_StartupFlags & ACPI_INITIALIZED_OK)
+ {
+ return (AE_OK);
+ }
+ else
+ {
+ return (AE_ERROR);
+ }
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSubsystemStatus)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetSystemInfo
+ *
+ * PARAMETERS: OutBuffer - A buffer to receive the resources for the
+ * device
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: This function is called to get information about the current
+ * state of the ACPI subsystem. It will return system information
+ * in the OutBuffer.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of OutBuffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetSystemInfo (
+ ACPI_BUFFER *OutBuffer)
+{
+ ACPI_SYSTEM_INFO *InfoPtr;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetSystemInfo);
+
+
+ /* Parameter validation */
+
+ Status = AcpiUtValidateBuffer (OutBuffer);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ Status = AcpiUtInitializeBuffer (OutBuffer, sizeof (ACPI_SYSTEM_INFO));
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Populate the return buffer
+ */
+ InfoPtr = (ACPI_SYSTEM_INFO *) OutBuffer->Pointer;
+
+ InfoPtr->AcpiCaVersion = ACPI_CA_VERSION;
+
+ /* System flags (ACPI capabilities) */
+
+ InfoPtr->Flags = ACPI_SYS_MODE_ACPI;
+
+ /* Timer resolution - 24 or 32 bits */
+
+ if (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER)
+ {
+ InfoPtr->TimerResolution = 24;
+ }
+ else
+ {
+ InfoPtr->TimerResolution = 32;
+ }
+
+ /* Clear the reserved fields */
+
+ InfoPtr->Reserved1 = 0;
+ InfoPtr->Reserved2 = 0;
+
+ /* Current debug levels */
+
+ InfoPtr->DebugLayer = AcpiDbgLayer;
+ InfoPtr->DebugLevel = AcpiDbgLevel;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetSystemInfo)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetStatistics
+ *
+ * PARAMETERS: Stats - Where the statistics are returned
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: Get the contents of the various system counters
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetStatistics (
+ ACPI_STATISTICS *Stats)
+{
+ ACPI_FUNCTION_TRACE (AcpiGetStatistics);
+
+
+ /* Parameter validation */
+
+ if (!Stats)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Various interrupt-based event counters */
+
+ Stats->SciCount = AcpiSciCount;
+ Stats->GpeCount = AcpiGpeCount;
+
+ memcpy (Stats->FixedEventCount, AcpiFixedEventCount,
+ sizeof (AcpiFixedEventCount));
+
+
+ /* Other counters */
+
+ Stats->MethodCount = AcpiMethodCount;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetStatistics)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiInstallInitializationHandler
+ *
+ * PARAMETERS: Handler - Callback procedure
+ * Function - Not (currently) used, see below
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install an initialization handler
+ *
+ * TBD: When a second function is added, must save the Function also.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiInstallInitializationHandler (
+ ACPI_INIT_HANDLER Handler,
+ UINT32 Function)
+{
+
+ if (!Handler)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (AcpiGbl_InitHandler)
+ {
+ return (AE_ALREADY_EXISTS);
+ }
+
+ AcpiGbl_InitHandler = Handler;
+ return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallInitializationHandler)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiPurgeCachedObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Empty all caches (delete the cached objects)
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiPurgeCachedObjects (
+ void)
+{
+ ACPI_FUNCTION_TRACE (AcpiPurgeCachedObjects);
+
+
+ (void) AcpiOsPurgeCache (AcpiGbl_StateCache);
+ (void) AcpiOsPurgeCache (AcpiGbl_OperandCache);
+ (void) AcpiOsPurgeCache (AcpiGbl_PsNodeCache);
+ (void) AcpiOsPurgeCache (AcpiGbl_PsNodeExtCache);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiPurgeCachedObjects)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiInstallInterface
+ *
+ * PARAMETERS: InterfaceName - The interface to install
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install an _OSI interface to the global list
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiInstallInterface (
+ ACPI_STRING InterfaceName)
+{
+ ACPI_STATUS Status;
+ ACPI_INTERFACE_INFO *InterfaceInfo;
+
+
+ /* Parameter validation */
+
+ if (!InterfaceName || (strlen (InterfaceName) == 0))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Check if the interface name is already in the global list */
+
+ InterfaceInfo = AcpiUtGetInterface (InterfaceName);
+ if (InterfaceInfo)
+ {
+ /*
+ * The interface already exists in the list. This is OK if the
+ * interface has been marked invalid -- just clear the bit.
+ */
+ if (InterfaceInfo->Flags & ACPI_OSI_INVALID)
+ {
+ InterfaceInfo->Flags &= ~ACPI_OSI_INVALID;
+ Status = AE_OK;
+ }
+ else
+ {
+ Status = AE_ALREADY_EXISTS;
+ }
+ }
+ else
+ {
+ /* New interface name, install into the global list */
+
+ Status = AcpiUtInstallInterface (InterfaceName);
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallInterface)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiRemoveInterface
+ *
+ * PARAMETERS: InterfaceName - The interface to remove
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove an _OSI interface from the global list
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveInterface (
+ ACPI_STRING InterfaceName)
+{
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!InterfaceName || (strlen (InterfaceName) == 0))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtRemoveInterface (InterfaceName);
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveInterface)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiInstallInterfaceHandler
+ *
+ * PARAMETERS: Handler - The _OSI interface handler to install
+ * NULL means "remove existing handler"
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
+ * invoked during execution of the internal implementation of
+ * _OSI. A NULL handler simply removes any existing handler.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiInstallInterfaceHandler (
+ ACPI_INTERFACE_HANDLER Handler)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Handler && AcpiGbl_InterfaceHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ }
+ else
+ {
+ AcpiGbl_InterfaceHandler = Handler;
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallInterfaceHandler)
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiUpdateInterfaces
+ *
+ * PARAMETERS: Action - Actions to be performed during the
+ * update
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
+ * string or/and feature group strings.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+AcpiUpdateInterfaces (
+ UINT8 Action)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtUpdateInterfaces (Action);
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return (Status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: AcpiCheckAddressRange
+ *
+ * PARAMETERS: SpaceId - Address space ID
+ * Address - Start address
+ * Length - Length
+ * Warn - TRUE if warning on overlap desired
+ *
+ * RETURN: Count of the number of conflicts detected.
+ *
+ * DESCRIPTION: Check if the input address range overlaps any of the
+ * ASL operation region address ranges.
+ *
+ ****************************************************************************/
+
+UINT32
+AcpiCheckAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_SIZE Length,
+ BOOLEAN Warn)
+{
+ UINT32 Overlaps;
+ ACPI_STATUS Status;
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (0);
+ }
+
+ Overlaps = AcpiUtCheckAddressRange (SpaceId, Address,
+ (UINT32) Length, Warn);
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return (Overlaps);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiCheckAddressRange)
+
+#endif /* !ACPI_ASL_COMPILER */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDecodePldBuffer
+ *
+ * PARAMETERS: InBuffer - Buffer returned by _PLD method
+ * Length - Length of the InBuffer
+ * ReturnBuffer - Where the decode buffer is returned
+ *
+ * RETURN: Status and the decoded _PLD buffer. User must deallocate
+ * the buffer via ACPI_FREE.
+ *
+ * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
+ * a local struct that is much more useful to an ACPI driver.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDecodePldBuffer (
+ UINT8 *InBuffer,
+ ACPI_SIZE Length,
+ ACPI_PLD_INFO **ReturnBuffer)
+{
+ ACPI_PLD_INFO *PldInfo;
+ UINT32 *Buffer = ACPI_CAST_PTR (UINT32, InBuffer);
+ UINT32 Dword;
+
+
+ /* Parameter validation */
+
+ if (!InBuffer || !ReturnBuffer || (Length < ACPI_PLD_REV1_BUFFER_SIZE))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ PldInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PLD_INFO));
+ if (!PldInfo)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* First 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32 (&Dword, &Buffer[0]);
+ PldInfo->Revision = ACPI_PLD_GET_REVISION (&Dword);
+ PldInfo->IgnoreColor = ACPI_PLD_GET_IGNORE_COLOR (&Dword);
+ PldInfo->Red = ACPI_PLD_GET_RED (&Dword);
+ PldInfo->Green = ACPI_PLD_GET_GREEN (&Dword);
+ PldInfo->Blue = ACPI_PLD_GET_BLUE (&Dword);
+
+ /* Second 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32 (&Dword, &Buffer[1]);
+ PldInfo->Width = ACPI_PLD_GET_WIDTH (&Dword);
+ PldInfo->Height = ACPI_PLD_GET_HEIGHT(&Dword);
+
+ /* Third 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32 (&Dword, &Buffer[2]);
+ PldInfo->UserVisible = ACPI_PLD_GET_USER_VISIBLE (&Dword);
+ PldInfo->Dock = ACPI_PLD_GET_DOCK (&Dword);
+ PldInfo->Lid = ACPI_PLD_GET_LID (&Dword);
+ PldInfo->Panel = ACPI_PLD_GET_PANEL (&Dword);
+ PldInfo->VerticalPosition = ACPI_PLD_GET_VERTICAL (&Dword);
+ PldInfo->HorizontalPosition = ACPI_PLD_GET_HORIZONTAL (&Dword);
+ PldInfo->Shape = ACPI_PLD_GET_SHAPE (&Dword);
+ PldInfo->GroupOrientation = ACPI_PLD_GET_ORIENTATION (&Dword);
+ PldInfo->GroupToken = ACPI_PLD_GET_TOKEN (&Dword);
+ PldInfo->GroupPosition = ACPI_PLD_GET_POSITION (&Dword);
+ PldInfo->Bay = ACPI_PLD_GET_BAY (&Dword);
+
+ /* Fourth 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32 (&Dword, &Buffer[3]);
+ PldInfo->Ejectable = ACPI_PLD_GET_EJECTABLE (&Dword);
+ PldInfo->OspmEjectRequired = ACPI_PLD_GET_OSPM_EJECT (&Dword);
+ PldInfo->CabinetNumber = ACPI_PLD_GET_CABINET (&Dword);
+ PldInfo->CardCageNumber = ACPI_PLD_GET_CARD_CAGE (&Dword);
+ PldInfo->Reference = ACPI_PLD_GET_REFERENCE (&Dword);
+ PldInfo->Rotation = ACPI_PLD_GET_ROTATION (&Dword);
+ PldInfo->Order = ACPI_PLD_GET_ORDER (&Dword);
+
+ if (Length >= ACPI_PLD_REV2_BUFFER_SIZE)
+ {
+ /* Fifth 32-bit DWord (Revision 2 of _PLD) */
+
+ ACPI_MOVE_32_TO_32 (&Dword, &Buffer[4]);
+ PldInfo->VerticalOffset = ACPI_PLD_GET_VERT_OFFSET (&Dword);
+ PldInfo->HorizontalOffset = ACPI_PLD_GET_HORIZ_OFFSET (&Dword);
+ }
+
+ *ReturnBuffer = PldInfo;
+ return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDecodePldBuffer)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxferror.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxferror.c
new file mode 100644
index 0000000000..d39682b42b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxferror.c
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ *
+ * Module Name: utxferror - Various error/warning output functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/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 *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+#ifdef _KERNEL
+ /* Temporarily hide too verbose printfs. */
+ if (!bootverbose)
+ return;
+#endif
+
+ 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/boot/sys/contrib/dev/acpica/components/utilities/utxfinit.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfinit.c
new file mode 100644
index 0000000000..afeacddf59
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfinit.c
@@ -0,0 +1,370 @@
+/******************************************************************************
+ *
+ * Module Name: utxfinit - External interfaces for ACPICA initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acevents.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utxfinit")
+
+/* For AcpiExec only */
+void
+AeDoObjectOverrides (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInitializeSubsystem
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initializes all global variables. This is the first function
+ * called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInitializeSubsystem (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInitializeSubsystem);
+
+
+ AcpiGbl_StartupFlags = ACPI_SUBSYSTEM_INITIALIZE;
+ ACPI_DEBUG_EXEC (AcpiUtInitStackPtrTrace ());
+
+ /* Initialize the OS-Dependent layer */
+
+ Status = AcpiOsInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During OSL initialization"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Initialize all globals used by the subsystem */
+
+ Status = AcpiUtInitGlobals ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During initialization of globals"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Create the default mutex objects */
+
+ Status = AcpiUtMutexInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During Global Mutex creation"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Initialize the namespace manager and
+ * the root of the namespace tree
+ */
+ Status = AcpiNsRootInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During Namespace initialization"));
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Initialize the global OSI interfaces list with the static names */
+
+ Status = AcpiUtInitializeInterfaces ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During OSI interfaces initialization"));
+ return_ACPI_STATUS (Status);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeSubsystem)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnableSubsystem
+ *
+ * PARAMETERS: Flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ * Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableSubsystem (
+ UINT32 Flags)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableSubsystem);
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* Enable ACPI mode */
+
+ if (!(Flags & ACPI_NO_ACPI_ENABLE))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
+
+ AcpiGbl_OriginalMode = AcpiHwGetMode();
+
+ Status = AcpiEnable ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO, "AcpiEnable failed"));
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Obtain a permanent mapping for the FACS. This is required for the
+ * Global Lock and the Firmware Waking Vector
+ */
+ if (!(Flags & ACPI_NO_FACS_INIT))
+ {
+ Status = AcpiTbInitializeFacs ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO, "Could not map the FACS table"));
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /*
+ * Install the default OpRegion handlers. These are installed unless
+ * other handlers have already been installed via the
+ * InstallAddressSpaceHandler interface.
+ */
+ if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Installing default address space handlers\n"));
+
+ Status = AcpiEvInstallRegionHandlers ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+#if (!ACPI_REDUCED_HARDWARE)
+ /*
+ * Initialize ACPI Event handling (Fixed and General Purpose)
+ *
+ * Note1: We must have the hardware and events initialized before we can
+ * execute any control methods safely. Any control method can require
+ * ACPI hardware support, so the hardware must be fully initialized before
+ * any method execution!
+ *
+ * Note2: Fixed events are initialized and enabled here. GPEs are
+ * initialized, but cannot be enabled until after the hardware is
+ * completely initialized (SCI and GlobalLock activated) and the various
+ * initialization control methods are run (_REG, _STA, _INI) on the
+ * entire namespace.
+ */
+ if (!(Flags & ACPI_NO_EVENT_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI events\n"));
+
+ Status = AcpiEvInitializeEvents ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Install the SCI handler and Global Lock handler. This completes the
+ * hardware initialization.
+ */
+ if (!(Flags & ACPI_NO_HANDLER_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Installing SCI/GL handlers\n"));
+
+ Status = AcpiEvInstallXruptHandlers ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiEnableSubsystem)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInitializeObjects
+ *
+ * PARAMETERS: Flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ * objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInitializeObjects (
+ UINT32 Flags)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInitializeObjects);
+
+
+ /*
+ * Run all _REG methods
+ *
+ * Note: Any objects accessed by the _REG methods will be automatically
+ * initialized, even if they contain executable AML (see the call to
+ * AcpiNsInitializeObjects below).
+ */
+ if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Executing _REG OpRegion methods\n"));
+
+ Status = AcpiEvInitializeOpRegions ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+#ifdef ACPI_EXEC_APP
+ /*
+ * This call implements the "initialization file" option for AcpiExec.
+ * This is the precise point that we want to perform the overrides.
+ */
+ AeDoObjectOverrides ();
+#endif
+
+ /*
+ * Execute any module-level code that was detected during the table load
+ * phase. Although illegal since ACPI 2.0, there are many machines that
+ * contain this type of code. Each block of detected executable AML code
+ * outside of any control method is wrapped with a temporary control
+ * method object and placed on a global list. The methods on this list
+ * are executed below.
+ */
+ AcpiNsExecModuleCodeList ();
+
+ /*
+ * Initialize the objects that remain uninitialized. This runs the
+ * executable AML that may be part of the declaration of these objects:
+ * OperationRegions, BufferFields, Buffers, and Packages.
+ */
+ if (!(Flags & ACPI_NO_OBJECT_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Completing Initialization of ACPI Objects\n"));
+
+ Status = AcpiNsInitializeObjects ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Initialize all device objects in the namespace. This runs the device
+ * _STA and _INI methods.
+ */
+ if (!(Flags & ACPI_NO_DEVICE_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI Devices\n"));
+
+ Status = AcpiNsInitializeDevices ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Empty the caches (delete the cached objects) on the assumption that
+ * the table load filled them up more than they will be at runtime --
+ * thus wasting non-paged memory.
+ */
+ Status = AcpiPurgeCachedObjects ();
+
+ AcpiGbl_StartupFlags |= ACPI_INITIALIZED_OK;
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeObjects)
diff --git a/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfmutex.c b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfmutex.c
new file mode 100644
index 0000000000..559f4b45ef
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/components/utilities/utxfmutex.c
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ *
+ * Module Name: utxfmutex - external AML mutex access functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utxfmutex")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtGetMutexObject (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ ACPI_OPERAND_OBJECT **RetObj);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtGetMutexObject
+ *
+ * PARAMETERS: Handle - Mutex or prefix handle (optional)
+ * Pathname - Mutex pathname (optional)
+ * RetObj - Where the mutex object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an AML mutex object. The mutex node is pointed to by
+ * Handle:Pathname. Either Handle or Pathname can be NULL, but
+ * not both.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtGetMutexObject (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ ACPI_OPERAND_OBJECT **RetObj)
+{
+ ACPI_NAMESPACE_NODE *MutexNode;
+ ACPI_OPERAND_OBJECT *MutexObj;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!RetObj || (!Handle && !Pathname))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Get a the namespace node for the mutex */
+
+ MutexNode = Handle;
+ if (Pathname != NULL)
+ {
+ Status = AcpiGetHandle (Handle, Pathname,
+ ACPI_CAST_PTR (ACPI_HANDLE, &MutexNode));
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ /* Ensure that we actually have a Mutex object */
+
+ if (!MutexNode ||
+ (MutexNode->Type != ACPI_TYPE_MUTEX))
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the low-level mutex object */
+
+ MutexObj = AcpiNsGetAttachedObject (MutexNode);
+ if (!MutexObj)
+ {
+ return (AE_NULL_OBJECT);
+ }
+
+ *RetObj = MutexObj;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAcquireMutex
+ *
+ * PARAMETERS: Handle - Mutex or prefix handle (optional)
+ * Pathname - Mutex pathname (optional)
+ * Timeout - Max time to wait for the lock (millisec)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire an AML mutex. This is a device driver interface to
+ * AML mutex objects, and allows for transaction locking between
+ * drivers and AML code. The mutex node is pointed to by
+ * Handle:Pathname. Either Handle or Pathname can be NULL, but
+ * not both.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiAcquireMutex (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ UINT16 Timeout)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *MutexObj;
+
+
+ /* Get the low-level mutex associated with Handle:Pathname */
+
+ Status = AcpiUtGetMutexObject (Handle, Pathname, &MutexObj);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Acquire the OS mutex */
+
+ Status = AcpiOsAcquireMutex (MutexObj->Mutex.OsMutex, Timeout);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiReleaseMutex
+ *
+ * PARAMETERS: Handle - Mutex or prefix handle (optional)
+ * Pathname - Mutex pathname (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release an AML mutex. This is a device driver interface to
+ * AML mutex objects, and allows for transaction locking between
+ * drivers and AML code. The mutex node is pointed to by
+ * Handle:Pathname. Either Handle or Pathname can be NULL, but
+ * not both.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReleaseMutex (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *MutexObj;
+
+
+ /* Get the low-level mutex associated with Handle:Pathname */
+
+ Status = AcpiUtGetMutexObject (Handle, Pathname, &MutexObj);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Release the OS mutex */
+
+ AcpiOsReleaseMutex (MutexObj->Mutex.OsMutex);
+ return (AE_OK);
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acapps.h b/usr/src/boot/sys/contrib/dev/acpica/include/acapps.h
new file mode 100644
index 0000000000..7c4880a12d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acapps.h
@@ -0,0 +1,233 @@
+/******************************************************************************
+ *
+ * Module Name: acapps - common include for ACPI applications/tools
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACAPPS
+#define _ACAPPS
+
+
+#ifdef _MSC_VER /* disable some level-4 warnings */
+#pragma warning(disable:4100) /* warning C4100: unreferenced formal parameter */
+#endif
+
+/* Common info for tool signons */
+
+#define ACPICA_NAME "Intel ACPI Component Architecture"
+#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2015 Intel Corporation"
+
+#if ACPI_MACHINE_WIDTH == 64
+#define ACPI_WIDTH "-64"
+
+#elif ACPI_MACHINE_WIDTH == 32
+#define ACPI_WIDTH "-32"
+
+#else
+#error unknown ACPI_MACHINE_WIDTH
+#define ACPI_WIDTH "-??"
+
+#endif
+
+/* Macros for signons and file headers */
+
+#define ACPI_COMMON_SIGNON(UtilityName) \
+ "\n%s\n%s version %8.8X%s\n%s\n\n", \
+ ACPICA_NAME, \
+ UtilityName, ((UINT32) ACPI_CA_VERSION), ACPI_WIDTH, \
+ ACPICA_COPYRIGHT
+
+#define ACPI_COMMON_HEADER(UtilityName, Prefix) \
+ "%s%s\n%s%s version %8.8X%s\n%s%s\n%s\n", \
+ Prefix, ACPICA_NAME, \
+ Prefix, UtilityName, ((UINT32) ACPI_CA_VERSION), ACPI_WIDTH, \
+ Prefix, ACPICA_COPYRIGHT, \
+ Prefix
+
+/* Macros for usage messages */
+
+#define ACPI_USAGE_HEADER(Usage) \
+ AcpiOsPrintf ("Usage: %s\nOptions:\n", Usage);
+
+#define ACPI_USAGE_TEXT(Description) \
+ AcpiOsPrintf (Description);
+
+#define ACPI_OPTION(Name, Description) \
+ AcpiOsPrintf (" %-18s%s\n", Name, Description);
+
+
+#define FILE_SUFFIX_DISASSEMBLY "dsl"
+#define ACPI_TABLE_FILE_SUFFIX ".dat"
+
+
+/*
+ * getopt
+ */
+int
+AcpiGetopt(
+ int argc,
+ char **argv,
+ char *opts);
+
+int
+AcpiGetoptArgument (
+ int argc,
+ char **argv);
+
+extern int AcpiGbl_Optind;
+extern int AcpiGbl_Opterr;
+extern int AcpiGbl_SubOptChar;
+extern char *AcpiGbl_Optarg;
+
+
+/*
+ * cmfsize - Common get file size function
+ */
+UINT32
+CmGetFileSize (
+ ACPI_FILE File);
+
+
+#ifndef ACPI_DUMP_APP
+/*
+ * adisasm
+ */
+ACPI_STATUS
+AdAmlDisassemble (
+ BOOLEAN OutToFile,
+ char *Filename,
+ char *Prefix,
+ char **OutFilename);
+
+void
+AdPrintStatistics (
+ void);
+
+ACPI_STATUS
+AdFindDsdt(
+ UINT8 **DsdtPtr,
+ UINT32 *DsdtLength);
+
+void
+AdDumpTables (
+ void);
+
+ACPI_STATUS
+AdGetLocalTables (
+ void);
+
+ACPI_STATUS
+AdParseTable (
+ ACPI_TABLE_HEADER *Table,
+ ACPI_OWNER_ID *OwnerId,
+ BOOLEAN LoadTable,
+ BOOLEAN External);
+
+ACPI_STATUS
+AdDisplayTables (
+ char *Filename,
+ ACPI_TABLE_HEADER *Table);
+
+ACPI_STATUS
+AdDisplayStatistics (
+ void);
+
+
+/*
+ * adwalk
+ */
+void
+AcpiDmCrossReferenceNamespace (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot,
+ ACPI_OWNER_ID OwnerId);
+
+void
+AcpiDmDumpTree (
+ ACPI_PARSE_OBJECT *Origin);
+
+void
+AcpiDmFindOrphanMethods (
+ ACPI_PARSE_OBJECT *Origin);
+
+void
+AcpiDmFinishNamespaceLoad (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot,
+ ACPI_OWNER_ID OwnerId);
+
+void
+AcpiDmConvertResourceIndexes (
+ ACPI_PARSE_OBJECT *ParseTreeRoot,
+ ACPI_NAMESPACE_NODE *NamespaceRoot);
+
+
+/*
+ * adfile
+ */
+ACPI_STATUS
+AdInitialize (
+ void);
+
+char *
+FlGenerateFilename (
+ char *InputFilename,
+ char *Suffix);
+
+ACPI_STATUS
+FlSplitInputPathname (
+ char *InputPath,
+ char **OutDirectoryPath,
+ char **OutFilename);
+
+char *
+AdGenerateFilename (
+ char *Prefix,
+ char *TableId);
+
+void
+AdWriteTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length,
+ char *TableName,
+ char *OemTableId);
+#endif
+
+#endif /* _ACAPPS */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acbuffer.h b/usr/src/boot/sys/contrib/dev/acpica/include/acbuffer.h
new file mode 100644
index 0000000000..e52bc7d2c3
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acbuffer.h
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ * Name: acbuffer.h - Support for buffers returned by ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACBUFFER_H__
+#define __ACBUFFER_H__
+
+/*
+ * Contains buffer structures for these predefined names:
+ * _FDE, _GRT, _GTM, _PLD, _SRT
+ */
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+
+/* _FDE return value */
+
+typedef struct acpi_fde_info
+{
+ UINT32 Floppy0;
+ UINT32 Floppy1;
+ UINT32 Floppy2;
+ UINT32 Floppy3;
+ UINT32 Tape;
+
+} ACPI_FDE_INFO;
+
+/*
+ * _GRT return value
+ * _SRT input value
+ */
+typedef struct acpi_grt_info
+{
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+ UINT8 Valid;
+ UINT16 Milliseconds;
+ UINT16 Timezone;
+ UINT8 Daylight;
+ UINT8 Reserved[3];
+
+} ACPI_GRT_INFO;
+
+/* _GTM return value */
+
+typedef struct acpi_gtm_info
+{
+ UINT32 PioSpeed0;
+ UINT32 DmaSpeed0;
+ UINT32 PioSpeed1;
+ UINT32 DmaSpeed1;
+ UINT32 Flags;
+
+} ACPI_GTM_INFO;
+
+/*
+ * Formatted _PLD return value. The minimum size is a package containing
+ * one buffer.
+ * Revision 1: Buffer is 16 bytes (128 bits)
+ * Revision 2: Buffer is 20 bytes (160 bits)
+ *
+ * Note: This structure is returned from the AcpiDecodePldBuffer
+ * interface.
+ */
+typedef struct acpi_pld_info
+{
+ UINT8 Revision;
+ UINT8 IgnoreColor;
+ UINT8 Red;
+ UINT8 Green;
+ UINT8 Blue;
+ UINT16 Width;
+ UINT16 Height;
+ UINT8 UserVisible;
+ UINT8 Dock;
+ UINT8 Lid;
+ UINT8 Panel;
+ UINT8 VerticalPosition;
+ UINT8 HorizontalPosition;
+ UINT8 Shape;
+ UINT8 GroupOrientation;
+ UINT8 GroupToken;
+ UINT8 GroupPosition;
+ UINT8 Bay;
+ UINT8 Ejectable;
+ UINT8 OspmEjectRequired;
+ UINT8 CabinetNumber;
+ UINT8 CardCageNumber;
+ UINT8 Reference;
+ UINT8 Rotation;
+ UINT8 Order;
+ UINT8 Reserved;
+ UINT16 VerticalOffset;
+ UINT16 HorizontalOffset;
+
+} ACPI_PLD_INFO;
+
+
+/*
+ * Macros to:
+ * 1) Convert a _PLD buffer to internal ACPI_PLD_INFO format - ACPI_PLD_GET*
+ * (Used by AcpiDecodePldBuffer)
+ * 2) Construct a _PLD buffer - ACPI_PLD_SET*
+ * (Intended for BIOS use only)
+ */
+#define ACPI_PLD_REV1_BUFFER_SIZE 16 /* For Revision 1 of the buffer (From ACPI spec) */
+#define ACPI_PLD_REV2_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */
+#define ACPI_PLD_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */
+
+/* First 32-bit dword, bits 0:32 */
+
+#define ACPI_PLD_GET_REVISION(dword) ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK)
+#define ACPI_PLD_SET_REVISION(dword,value) ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value) /* Offset 0, Len 7 */
+
+#define ACPI_PLD_GET_IGNORE_COLOR(dword) ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_IGNORE_COLOR(dword,value) ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value) /* Offset 7, Len 1 */
+
+#define ACPI_PLD_GET_RED(dword) ACPI_GET_BITS (dword, 8, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_RED(dword,value) ACPI_SET_BITS (dword, 8, ACPI_8BIT_MASK, value) /* Offset 8, Len 8 */
+
+#define ACPI_PLD_GET_GREEN(dword) ACPI_GET_BITS (dword, 16, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_GREEN(dword,value) ACPI_SET_BITS (dword, 16, ACPI_8BIT_MASK, value) /* Offset 16, Len 8 */
+
+#define ACPI_PLD_GET_BLUE(dword) ACPI_GET_BITS (dword, 24, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_BLUE(dword,value) ACPI_SET_BITS (dword, 24, ACPI_8BIT_MASK, value) /* Offset 24, Len 8 */
+
+/* Second 32-bit dword, bits 33:63 */
+
+#define ACPI_PLD_GET_WIDTH(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_WIDTH(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 32+0=32, Len 16 */
+
+#define ACPI_PLD_GET_HEIGHT(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HEIGHT(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 32+16=48, Len 16 */
+
+/* Third 32-bit dword, bits 64:95 */
+
+#define ACPI_PLD_GET_USER_VISIBLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_USER_VISIBLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 64+0=64, Len 1 */
+
+#define ACPI_PLD_GET_DOCK(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_DOCK(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 64+1=65, Len 1 */
+
+#define ACPI_PLD_GET_LID(dword) ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_LID(dword,value) ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value) /* Offset 64+2=66, Len 1 */
+
+#define ACPI_PLD_GET_PANEL(dword) ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK)
+#define ACPI_PLD_SET_PANEL(dword,value) ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value) /* Offset 64+3=67, Len 3 */
+
+#define ACPI_PLD_GET_VERTICAL(dword) ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_VERTICAL(dword,value) ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value) /* Offset 64+6=70, Len 2 */
+
+#define ACPI_PLD_GET_HORIZONTAL(dword) ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_HORIZONTAL(dword,value) ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value) /* Offset 64+8=72, Len 2 */
+
+#define ACPI_PLD_GET_SHAPE(dword) ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_SHAPE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value) /* Offset 64+10=74, Len 4 */
+
+#define ACPI_PLD_GET_ORIENTATION(dword) ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_ORIENTATION(dword,value) ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value) /* Offset 64+14=78, Len 1 */
+
+#define ACPI_PLD_GET_TOKEN(dword) ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_TOKEN(dword,value) ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value) /* Offset 64+15=79, Len 8 */
+
+#define ACPI_PLD_GET_POSITION(dword) ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_POSITION(dword,value) ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value) /* Offset 64+23=87, Len 8 */
+
+#define ACPI_PLD_GET_BAY(dword) ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_BAY(dword,value) ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value) /* Offset 64+31=95, Len 1 */
+
+/* Fourth 32-bit dword, bits 96:127 */
+
+#define ACPI_PLD_GET_EJECTABLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_EJECTABLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 96+0=96, Len 1 */
+
+#define ACPI_PLD_GET_OSPM_EJECT(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_OSPM_EJECT(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 96+1=97, Len 1 */
+
+#define ACPI_PLD_GET_CABINET(dword) ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CABINET(dword,value) ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value) /* Offset 96+2=98, Len 8 */
+
+#define ACPI_PLD_GET_CARD_CAGE(dword) ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CARD_CAGE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value) /* Offset 96+10=106, Len 8 */
+
+#define ACPI_PLD_GET_REFERENCE(dword) ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_REFERENCE(dword,value) ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value) /* Offset 96+18=114, Len 1 */
+
+#define ACPI_PLD_GET_ROTATION(dword) ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_ROTATION(dword,value) ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value) /* Offset 96+19=115, Len 4 */
+
+#define ACPI_PLD_GET_ORDER(dword) ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK)
+#define ACPI_PLD_SET_ORDER(dword,value) ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value) /* Offset 96+23=119, Len 5 */
+
+/* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */
+
+#define ACPI_PLD_GET_VERT_OFFSET(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_VERT_OFFSET(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 128+0=128, Len 16 */
+
+#define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */
+
+
+#endif /* ACBUFFER_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acclib.h b/usr/src/boot/sys/contrib/dev/acpica/include/acclib.h
new file mode 100644
index 0000000000..ed310cc2fb
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acclib.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ *
+ * Name: acclib.h -- C library support. Prototypes for the (optional) local
+ * implementations of required C library functions.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACCLIB_H
+#define _ACCLIB_H
+
+
+/*
+ * Prototypes and macros for local implementations of C library functions
+ */
+
+/* is* functions. The AcpiGbl_Ctypes array is defined in utclib.c */
+
+extern const UINT8 AcpiGbl_Ctypes[];
+
+#define _ACPI_XA 0x00 /* extra alphabetic - not supported */
+#define _ACPI_XS 0x40 /* extra space */
+#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */
+#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */
+#define _ACPI_DI 0x04 /* '0'-'9' */
+#define _ACPI_LO 0x02 /* 'a'-'z' */
+#define _ACPI_PU 0x10 /* punctuation */
+#define _ACPI_SP 0x08 /* space, tab, CR, LF, VT, FF */
+#define _ACPI_UP 0x01 /* 'A'-'Z' */
+#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
+
+#define isdigit(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_DI))
+#define isspace(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_SP))
+#define isxdigit(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_XD))
+#define isupper(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_UP))
+#define islower(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO))
+#define isprint(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
+#define isalpha(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
+
+
+/* Strings */
+
+char *
+strcat (
+ char *DstString,
+ const char *SrcString);
+
+char *
+strchr (
+ const char *String,
+ int ch);
+
+char *
+strcpy (
+ char *DstString,
+ const char *SrcString);
+
+int
+strcmp (
+ const char *String1,
+ const char *String2);
+
+ACPI_SIZE
+strlen (
+ const char *String);
+
+char *
+strncat (
+ char *DstString,
+ const char *SrcString,
+ ACPI_SIZE Count);
+
+int
+strncmp (
+ const char *String1,
+ const char *String2,
+ ACPI_SIZE Count);
+
+char *
+strncpy (
+ char *DstString,
+ const char *SrcString,
+ ACPI_SIZE Count);
+
+char *
+strstr (
+ char *String1,
+ char *String2);
+
+
+/* Conversion */
+
+UINT32
+strtoul (
+ const char *String,
+ char **Terminator,
+ UINT32 Base);
+
+
+/* Memory */
+
+int
+memcmp (
+ void *Buffer1,
+ void *Buffer2,
+ ACPI_SIZE Count);
+
+void *
+memcpy (
+ void *Dest,
+ const void *Src,
+ ACPI_SIZE Count);
+
+void *
+memset (
+ void *Dest,
+ int Value,
+ ACPI_SIZE Count);
+
+
+/* upper/lower case */
+
+int
+tolower (
+ int c);
+
+int
+toupper (
+ int c);
+
+#endif /* _ACCLIB_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/accommon.h b/usr/src/boot/sys/contrib/dev/acpica/include/accommon.h
new file mode 100644
index 0000000000..322222a8fa
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/accommon.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Name: accommon.h - Common include files for generation of ACPICA source
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACCOMMON_H__
+#define __ACCOMMON_H__
+
+/*
+ * Common set of includes for all ACPICA source files.
+ * We put them here because we don't want to duplicate them
+ * in the the source code again and again.
+ *
+ * Note: The order of these include files is important.
+ */
+#include <contrib/dev/acpica/include/acconfig.h> /* Global configuration constants */
+#include <contrib/dev/acpica/include/acmacros.h> /* C macros */
+#include <contrib/dev/acpica/include/aclocal.h> /* Internal data types */
+#include <contrib/dev/acpica/include/acobject.h> /* ACPI internal object */
+#include <contrib/dev/acpica/include/acstruct.h> /* Common structures */
+#include <contrib/dev/acpica/include/acglobal.h> /* All global variables */
+#include <contrib/dev/acpica/include/achware.h> /* Hardware defines and interfaces */
+#include <contrib/dev/acpica/include/acutils.h> /* Utility interfaces */
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+#include <contrib/dev/acpica/include/acclib.h> /* C library interfaces */
+#endif /* !ACPI_USE_SYSTEM_CLIBRARY */
+
+
+#endif /* __ACCOMMON_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acconfig.h b/usr/src/boot/sys/contrib/dev/acpica/include/acconfig.h
new file mode 100644
index 0000000000..8441551c1c
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acconfig.h
@@ -0,0 +1,252 @@
+/******************************************************************************
+ *
+ * Name: acconfig.h - Global configuration constants
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACCONFIG_H
+#define _ACCONFIG_H
+
+
+/******************************************************************************
+ *
+ * Configuration options
+ *
+ *****************************************************************************/
+
+/*
+ * ACPI_DEBUG_OUTPUT - This switch enables all the debug facilities of the
+ * ACPI subsystem. This includes the DEBUG_PRINT output
+ * statements. When disabled, all DEBUG_PRINT
+ * statements are compiled out.
+ *
+ * ACPI_APPLICATION - Use this switch if the subsystem is going to be run
+ * at the application level.
+ *
+ */
+
+/*
+ * OS name, used for the _OS object. The _OS object is essentially obsolete,
+ * but there is a large base of ASL/AML code in existing machines that check
+ * for the string below. The use of this string usually guarantees that
+ * the ASL will execute down the most tested code path. Also, there is some
+ * code that will not execute the _OSI method unless _OS matches the string
+ * below. Therefore, change this string at your own risk.
+ */
+#define ACPI_OS_NAME "Microsoft Windows NT"
+
+/* Maximum objects in the various object caches */
+
+#define ACPI_MAX_STATE_CACHE_DEPTH 96 /* State objects */
+#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
+#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 96 /* Parse tree objects */
+#define ACPI_MAX_OBJECT_CACHE_DEPTH 96 /* Interpreter operand objects */
+#define ACPI_MAX_NAMESPACE_CACHE_DEPTH 96 /* Namespace objects */
+
+/*
+ * Should the subsystem abort the loading of an ACPI table if the
+ * table checksum is incorrect?
+ */
+#ifndef ACPI_CHECKSUM_ABORT
+#define ACPI_CHECKSUM_ABORT FALSE
+#endif
+
+/*
+ * Generate a version of ACPICA that only supports "reduced hardware"
+ * platforms (as defined in ACPI 5.0). Set to TRUE to generate a specialized
+ * version of ACPICA that ONLY supports the ACPI 5.0 "reduced hardware"
+ * model. In other words, no ACPI hardware is supported.
+ *
+ * If TRUE, this means no support for the following:
+ * PM Event and Control registers
+ * SCI interrupt (and handler)
+ * Fixed Events
+ * General Purpose Events (GPEs)
+ * Global Lock
+ * ACPI PM timer
+ * FACS table (Waking vectors and Global Lock)
+ */
+#ifndef ACPI_REDUCED_HARDWARE
+#define ACPI_REDUCED_HARDWARE FALSE
+#endif
+
+
+/******************************************************************************
+ *
+ * Subsystem Constants
+ *
+ *****************************************************************************/
+
+/* Version of ACPI supported */
+
+#define ACPI_CA_SUPPORT_LEVEL 5
+
+/* Maximum count for a semaphore object */
+
+#define ACPI_MAX_SEMAPHORE_COUNT 256
+
+/* Maximum object reference count (detects object deletion issues) */
+
+#define ACPI_MAX_REFERENCE_COUNT 0x800
+
+/* Default page size for use in mapping memory for operation regions */
+
+#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */
+
+/* OwnerId tracking. 8 entries allows for 255 OwnerIds */
+
+#define ACPI_NUM_OWNERID_MASKS 8
+
+/* Size of the root table array is increased by this increment */
+
+#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4
+
+/* Maximum sleep allowed via Sleep() operator */
+
+#define ACPI_MAX_SLEEP 2000 /* 2000 millisec == two seconds */
+
+/* Address Range lists are per-SpaceId (Memory and I/O only) */
+
+#define ACPI_ADDRESS_RANGE_MAX 2
+
+
+/******************************************************************************
+ *
+ * ACPI Specification constants (Do not change unless the specification changes)
+ *
+ *****************************************************************************/
+
+/* Method info (in WALK_STATE), containing local variables and argumetns */
+
+#define ACPI_METHOD_NUM_LOCALS 8
+#define ACPI_METHOD_MAX_LOCAL 7
+
+#define ACPI_METHOD_NUM_ARGS 7
+#define ACPI_METHOD_MAX_ARG 6
+
+/*
+ * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
+ */
+#define ACPI_OBJ_NUM_OPERANDS 8
+#define ACPI_OBJ_MAX_OPERAND 7
+
+/* Number of elements in the Result Stack frame, can be an arbitrary value */
+
+#define ACPI_RESULTS_FRAME_OBJ_NUM 8
+
+/*
+ * Maximal number of elements the Result Stack can contain,
+ * it may be an arbitray value not exceeding the types of
+ * ResultSize and ResultCount (now UINT8).
+ */
+#define ACPI_RESULTS_OBJ_NUM_MAX 255
+
+/* Constants used in searching for the RSDP in low memory */
+
+#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
+#define ACPI_EBDA_PTR_LENGTH 2
+#define ACPI_EBDA_WINDOW_SIZE 1024
+#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */
+#define ACPI_HI_RSDP_WINDOW_SIZE 0x00020000
+#define ACPI_RSDP_SCAN_STEP 16
+
+/* Operation regions */
+
+#define ACPI_USER_REGION_BEGIN 0x80
+
+/* Maximum SpaceIds for Operation Regions */
+
+#define ACPI_MAX_ADDRESS_SPACE 255
+#define ACPI_NUM_DEFAULT_SPACES 4
+
+/* Array sizes. Used for range checking also */
+
+#define ACPI_MAX_MATCH_OPCODE 5
+
+/* RSDP checksums */
+
+#define ACPI_RSDP_CHECKSUM_LENGTH 20
+#define ACPI_RSDP_XCHECKSUM_LENGTH 36
+
+/* SMBus, GSBus and IPMI bidirectional buffer size */
+
+#define ACPI_SMBUS_BUFFER_SIZE 34
+#define ACPI_GSBUS_BUFFER_SIZE 34
+#define ACPI_IPMI_BUFFER_SIZE 66
+
+/* _SxD and _SxW control methods */
+
+#define ACPI_NUM_SxD_METHODS 4
+#define ACPI_NUM_SxW_METHODS 5
+
+
+/******************************************************************************
+ *
+ * Miscellaneous constants
+ *
+ *****************************************************************************/
+
+/* UUID constants */
+
+#define UUID_BUFFER_LENGTH 16 /* Length of UUID in memory */
+#define UUID_STRING_LENGTH 36 /* Total length of a UUID string */
+
+/* Positions for required hyphens (dashes) in UUID strings */
+
+#define UUID_HYPHEN1_OFFSET 8
+#define UUID_HYPHEN2_OFFSET 13
+#define UUID_HYPHEN3_OFFSET 18
+#define UUID_HYPHEN4_OFFSET 23
+
+
+/******************************************************************************
+ *
+ * ACPI AML Debugger
+ *
+ *****************************************************************************/
+
+#define ACPI_DEBUGGER_MAX_ARGS ACPI_METHOD_NUM_ARGS + 4 /* Max command line arguments */
+#define ACPI_DB_LINE_BUFFER_SIZE 512
+
+#define ACPI_DEBUGGER_COMMAND_PROMPT '-'
+#define ACPI_DEBUGGER_EXECUTE_PROMPT '%'
+
+
+#endif /* _ACCONFIG_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acdebug.h b/usr/src/boot/sys/contrib/dev/acpica/include/acdebug.h
new file mode 100644
index 0000000000..cf989a80d8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acdebug.h
@@ -0,0 +1,492 @@
+/******************************************************************************
+ *
+ * Name: acdebug.h - ACPI/AML debugger
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACDEBUG_H__
+#define __ACDEBUG_H__
+
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include <contrib/dev/acpica/include/acdisasm.h>
+#endif
+
+
+#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */
+
+typedef struct acpi_db_command_info
+{
+ char *Name; /* Command Name */
+ UINT8 MinArgs; /* Minimum arguments required */
+
+} ACPI_DB_COMMAND_INFO;
+
+typedef struct acpi_db_command_help
+{
+ UINT8 LineCount; /* Number of help lines */
+ char *Invocation; /* Command Invocation */
+ char *Description; /* Command Description */
+
+} ACPI_DB_COMMAND_HELP;
+
+typedef struct acpi_db_argument_info
+{
+ char *Name; /* Argument Name */
+
+} ACPI_DB_ARGUMENT_INFO;
+
+typedef struct acpi_db_execute_walk
+{
+ UINT32 Count;
+ UINT32 MaxCount;
+
+} ACPI_DB_EXECUTE_WALK;
+
+
+#define PARAM_LIST(pl) pl
+
+#define EX_NO_SINGLE_STEP 1
+#define EX_SINGLE_STEP 2
+
+
+/*
+ * dbxface - external debugger interfaces
+ */
+ACPI_STATUS
+AcpiDbSingleStep (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 OpType);
+
+
+/*
+ * dbcmds - debug commands and output routines
+ */
+ACPI_NAMESPACE_NODE *
+AcpiDbConvertToNode (
+ char *InString);
+
+void
+AcpiDbDisplayTableInfo (
+ char *TableArg);
+
+void
+AcpiDbDisplayTemplate (
+ char *BufferArg);
+
+void
+AcpiDbUnloadAcpiTable (
+ char *Name);
+
+void
+AcpiDbSendNotify (
+ char *Name,
+ UINT32 Value);
+
+void
+AcpiDbDisplayInterfaces (
+ char *ActionArg,
+ char *InterfaceNameArg);
+
+ACPI_STATUS
+AcpiDbSleep (
+ char *ObjectArg);
+
+void
+AcpiDbTrace (
+ char *EnableArg,
+ char *MethodArg,
+ char *OnceArg);
+
+void
+AcpiDbDisplayLocks (
+ void);
+
+void
+AcpiDbDisplayResources (
+ char *ObjectArg);
+
+ACPI_HW_DEPENDENT_RETURN_VOID (
+void
+AcpiDbDisplayGpes (
+ void))
+
+void
+AcpiDbDisplayHandlers (
+ void);
+
+ACPI_HW_DEPENDENT_RETURN_VOID (
+void
+AcpiDbGenerateGpe (
+ char *GpeArg,
+ char *BlockArg))
+
+ACPI_HW_DEPENDENT_RETURN_VOID (
+void
+AcpiDbGenerateSci (
+ void))
+
+void
+AcpiDbExecuteTest (
+ char *TypeArg);
+
+
+/*
+ * dbconvert - miscellaneous conversion routines
+ */
+ACPI_STATUS
+AcpiDbHexCharToValue (
+ int HexChar,
+ UINT8 *ReturnValue);
+
+ACPI_STATUS
+AcpiDbConvertToPackage (
+ char *String,
+ ACPI_OBJECT *Object);
+
+ACPI_STATUS
+AcpiDbConvertToObject (
+ ACPI_OBJECT_TYPE Type,
+ char *String,
+ ACPI_OBJECT *Object);
+
+UINT8 *
+AcpiDbEncodePldBuffer (
+ ACPI_PLD_INFO *PldInfo);
+
+void
+AcpiDbDumpPldBuffer (
+ ACPI_OBJECT *ObjDesc);
+
+
+/*
+ * dbmethod - control method commands
+ */
+void
+AcpiDbSetMethodBreakpoint (
+ char *Location,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDbSetMethodCallBreakpoint (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDbSetMethodData (
+ char *TypeArg,
+ char *IndexArg,
+ char *ValueArg);
+
+ACPI_STATUS
+AcpiDbDisassembleMethod (
+ char *Name);
+
+void
+AcpiDbDisassembleAml (
+ char *Statements,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDbBatchExecute (
+ char *CountArg);
+
+
+/*
+ * dbnames - namespace commands
+ */
+void
+AcpiDbSetScope (
+ char *Name);
+
+void
+AcpiDbDumpNamespace (
+ char *StartArg,
+ char *DepthArg);
+
+void
+AcpiDbDumpNamespacePaths (
+ void);
+
+void
+AcpiDbDumpNamespaceByOwner (
+ char *OwnerArg,
+ char *DepthArg);
+
+ACPI_STATUS
+AcpiDbFindNameInNamespace (
+ char *NameArg);
+
+void
+AcpiDbCheckPredefinedNames (
+ void);
+
+ACPI_STATUS
+AcpiDbDisplayObjects (
+ char *ObjTypeArg,
+ char *DisplayCountArg);
+
+void
+AcpiDbCheckIntegrity (
+ void);
+
+void
+AcpiDbFindReferences (
+ char *ObjectArg);
+
+void
+AcpiDbGetBusInfo (
+ void);
+
+
+/*
+ * dbdisply - debug display commands
+ */
+void
+AcpiDbDisplayMethodInfo (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDbDecodeAndDisplayObject (
+ char *Target,
+ char *OutputType);
+
+void
+AcpiDbDisplayResultObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDbDisplayAllMethods (
+ char *DisplayCountArg);
+
+void
+AcpiDbDisplayArguments (
+ void);
+
+void
+AcpiDbDisplayLocals (
+ void);
+
+void
+AcpiDbDisplayResults (
+ void);
+
+void
+AcpiDbDisplayCallingTree (
+ void);
+
+void
+AcpiDbDisplayObjectType (
+ char *ObjectArg);
+
+void
+AcpiDbDisplayArgumentObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dbexec - debugger control method execution
+ */
+void
+AcpiDbExecute (
+ char *Name,
+ char **Args,
+ ACPI_OBJECT_TYPE *Types,
+ UINT32 Flags);
+
+void
+AcpiDbCreateExecutionThreads (
+ char *NumThreadsArg,
+ char *NumLoopsArg,
+ char *MethodNameArg);
+
+void
+AcpiDbDeleteObjects (
+ UINT32 Count,
+ ACPI_OBJECT *Objects);
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+UINT32
+AcpiDbGetCacheInfo (
+ ACPI_MEMORY_LIST *Cache);
+#endif
+
+
+/*
+ * dbfileio - Debugger file I/O commands
+ */
+ACPI_OBJECT_TYPE
+AcpiDbMatchArgument (
+ char *UserArgument,
+ ACPI_DB_ARGUMENT_INFO *Arguments);
+
+void
+AcpiDbCloseDebugFile (
+ void);
+
+void
+AcpiDbOpenDebugFile (
+ char *Name);
+
+ACPI_STATUS
+AcpiDbLoadAcpiTable (
+ char *Filename);
+
+ACPI_STATUS
+AcpiDbGetTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **Table,
+ BOOLEAN MustBeAmlTable);
+
+
+/*
+ * dbhistry - debugger HISTORY command
+ */
+void
+AcpiDbAddToHistory (
+ char *CommandLine);
+
+void
+AcpiDbDisplayHistory (
+ void);
+
+char *
+AcpiDbGetFromHistory (
+ char *CommandNumArg);
+
+char *
+AcpiDbGetHistoryByIndex (
+ UINT32 CommanddNum);
+
+
+/*
+ * dbinput - user front-end to the AML debugger
+ */
+ACPI_STATUS
+AcpiDbCommandDispatch (
+ char *InputBuffer,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+void ACPI_SYSTEM_XFACE
+AcpiDbExecuteThread (
+ void *Context);
+
+ACPI_STATUS
+AcpiDbUserCommands (
+ char Prompt,
+ ACPI_PARSE_OBJECT *Op);
+
+char *
+AcpiDbGetNextToken (
+ char *String,
+ char **Next,
+ ACPI_OBJECT_TYPE *ReturnType);
+
+
+/*
+ * dbobject
+ */
+void
+AcpiDbDecodeInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+void
+AcpiDbDisplayInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDbDecodeArguments (
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDbDecodeLocals (
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDbDumpMethodInfo (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dbstats - Generation and display of ACPI table statistics
+ */
+void
+AcpiDbGenerateStatistics (
+ ACPI_PARSE_OBJECT *Root,
+ BOOLEAN IsMethod);
+
+ACPI_STATUS
+AcpiDbDisplayStatistics (
+ char *TypeArg);
+
+
+/*
+ * dbutils - AML debugger utilities
+ */
+void
+AcpiDbSetOutputDestination (
+ UINT32 Where);
+
+void
+AcpiDbDumpExternalObject (
+ ACPI_OBJECT *ObjDesc,
+ UINT32 Level);
+
+void
+AcpiDbPrepNamestring (
+ char *Name);
+
+ACPI_NAMESPACE_NODE *
+AcpiDbLocalNsLookup (
+ char *Name);
+
+void
+AcpiDbUint32ToHexString (
+ UINT32 Value,
+ char *Buffer);
+
+#endif /* __ACDEBUG_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acdisasm.h b/usr/src/boot/sys/contrib/dev/acpica/include/acdisasm.h
new file mode 100644
index 0000000000..5bfe88155a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acdisasm.h
@@ -0,0 +1,1060 @@
+/******************************************************************************
+ *
+ * Name: acdisasm.h - AML disassembler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACDISASM_H__
+#define __ACDISASM_H__
+
+#include <contrib/dev/acpica/include/amlresrc.h>
+
+
+#define BLOCK_NONE 0
+#define BLOCK_PAREN 1
+#define BLOCK_BRACE 2
+#define BLOCK_COMMA_LIST 4
+#define ACPI_DEFAULT_RESNAME *(UINT32 *) "__RD"
+
+/*
+ * Raw table data header. Used by disassembler and data table compiler.
+ * Do not change.
+ */
+#define ACPI_RAW_TABLE_DATA_HEADER "Raw Table Data"
+
+
+typedef struct acpi_dmtable_info
+{
+ UINT8 Opcode;
+ UINT16 Offset;
+ char *Name;
+ UINT8 Flags;
+
+} ACPI_DMTABLE_INFO;
+
+/* Values for Flags field above */
+
+#define DT_LENGTH 0x01 /* Field is a subtable length */
+#define DT_FLAG 0x02 /* Field is a flag value */
+#define DT_NON_ZERO 0x04 /* Field must be non-zero */
+#define DT_OPTIONAL 0x08 /* Field is optional */
+#define DT_DESCRIBES_OPTIONAL 0x10 /* Field describes an optional field (length, etc.) */
+#define DT_COUNT 0x20 /* Currently not used */
+
+/*
+ * Values for Opcode above.
+ * Note: 0-7 must not change, they are used as a flag shift value. Other
+ * than those, new values can be added wherever appropriate.
+ */
+typedef enum
+{
+ /* Simple Data Types */
+
+ ACPI_DMT_FLAG0 = 0,
+ ACPI_DMT_FLAG1 = 1,
+ ACPI_DMT_FLAG2 = 2,
+ ACPI_DMT_FLAG3 = 3,
+ ACPI_DMT_FLAG4 = 4,
+ ACPI_DMT_FLAG5 = 5,
+ ACPI_DMT_FLAG6 = 6,
+ ACPI_DMT_FLAG7 = 7,
+ ACPI_DMT_FLAGS0,
+ ACPI_DMT_FLAGS1,
+ ACPI_DMT_FLAGS2,
+ ACPI_DMT_FLAGS4,
+ ACPI_DMT_UINT8,
+ ACPI_DMT_UINT16,
+ ACPI_DMT_UINT24,
+ ACPI_DMT_UINT32,
+ ACPI_DMT_UINT40,
+ ACPI_DMT_UINT48,
+ ACPI_DMT_UINT56,
+ ACPI_DMT_UINT64,
+ ACPI_DMT_BUF7,
+ ACPI_DMT_BUF10,
+ ACPI_DMT_BUF16,
+ ACPI_DMT_BUF128,
+ ACPI_DMT_SIG,
+ ACPI_DMT_STRING,
+ ACPI_DMT_NAME4,
+ ACPI_DMT_NAME6,
+ ACPI_DMT_NAME8,
+
+ /* Types that are decoded to strings and miscellaneous */
+
+ ACPI_DMT_ACCWIDTH,
+ ACPI_DMT_CHKSUM,
+ ACPI_DMT_GAS,
+ ACPI_DMT_SPACEID,
+ ACPI_DMT_UNICODE,
+ ACPI_DMT_UUID,
+
+ /* Types used only for the Data Table Compiler */
+
+ ACPI_DMT_BUFFER,
+ ACPI_DMT_RAW_BUFFER, /* Large, multiple line buffer */
+ ACPI_DMT_DEVICE_PATH,
+ ACPI_DMT_LABEL,
+ ACPI_DMT_PCI_PATH,
+
+ /* Types that are specific to particular ACPI tables */
+
+ ACPI_DMT_ASF,
+ ACPI_DMT_DMAR,
+ ACPI_DMT_DMAR_SCOPE,
+ ACPI_DMT_EINJACT,
+ ACPI_DMT_EINJINST,
+ ACPI_DMT_ERSTACT,
+ ACPI_DMT_ERSTINST,
+ ACPI_DMT_FADTPM,
+ ACPI_DMT_GTDT,
+ ACPI_DMT_HEST,
+ ACPI_DMT_HESTNTFY,
+ ACPI_DMT_HESTNTYP,
+ ACPI_DMT_IORTMEM,
+ ACPI_DMT_IVRS,
+ ACPI_DMT_LPIT,
+ ACPI_DMT_MADT,
+ ACPI_DMT_NFIT,
+ ACPI_DMT_PCCT,
+ ACPI_DMT_PMTT,
+ ACPI_DMT_SLIC,
+ ACPI_DMT_SRAT,
+
+ /* Special opcodes */
+
+ ACPI_DMT_EXTRA_TEXT,
+ ACPI_DMT_EXIT
+
+} ACPI_ENTRY_TYPES;
+
+typedef
+void (*ACPI_DMTABLE_HANDLER) (
+ ACPI_TABLE_HEADER *Table);
+
+typedef
+ACPI_STATUS (*ACPI_CMTABLE_HANDLER) (
+ void **PFieldList);
+
+typedef struct acpi_dmtable_data
+{
+ char *Signature;
+ ACPI_DMTABLE_INFO *TableInfo;
+ ACPI_DMTABLE_HANDLER TableHandler;
+ ACPI_CMTABLE_HANDLER CmTableHandler;
+ const unsigned char *Template;
+
+} ACPI_DMTABLE_DATA;
+
+
+typedef struct acpi_op_walk_info
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_PARSE_OBJECT *MappingOp;
+ UINT8 *PreviousAml;
+ UINT8 *StartAml;
+ UINT32 Level;
+ UINT32 LastLevel;
+ UINT32 Count;
+ UINT32 BitOffset;
+ UINT32 Flags;
+ UINT32 AmlOffset;
+
+} ACPI_OP_WALK_INFO;
+
+/*
+ * TBD - another copy of this is in asltypes.h, fix
+ */
+#ifndef ASL_WALK_CALLBACK_DEFINED
+typedef
+ACPI_STATUS (*ASL_WALK_CALLBACK) (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+#define ASL_WALK_CALLBACK_DEFINED
+#endif
+
+typedef
+void (*ACPI_RESOURCE_HANDLER) (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+typedef struct acpi_resource_tag
+{
+ UINT32 BitIndex;
+ char *Tag;
+
+} ACPI_RESOURCE_TAG;
+
+/* Strings used for decoding flags to ASL keywords */
+
+extern const char *AcpiGbl_WordDecode[];
+extern const char *AcpiGbl_IrqDecode[];
+extern const char *AcpiGbl_LockRule[];
+extern const char *AcpiGbl_AccessTypes[];
+extern const char *AcpiGbl_UpdateRules[];
+extern const char *AcpiGbl_MatchOps[];
+
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsf4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoAsfHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoBoot[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoBert[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoBgrt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCpep[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCpep0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Device[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Addr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Size[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2Name[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbg2OemData[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDbgp[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmarHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmarScope[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm0a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm1a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoEcdt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoEinj[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoEinj0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoErst[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoErst0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFacs[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFadt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFadt2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFadt3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFadt5[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFadt6[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFpdtHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGas[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGtdtHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt0a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHeader[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest9[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHestBank[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoHpet[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoLpitHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoLpit0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoLpit1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort0a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort1a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort3a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort3b[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIort3c[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIortAcc[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIortHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIortMap[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIortPad[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8b[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8c[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrsHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt5[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt6[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt7[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt8[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt9[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt11[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt12[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt13[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt14[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt15[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadtHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0A[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0B[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMpst2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMtmr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMtmr0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfitHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit2a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit3a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit5[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmttHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcctHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3ptHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlic[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlit[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSpmi[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSratHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat3[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoStao[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoStaoStr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaClient[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaServer[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWaet[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdat[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdat0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWddt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWpbt[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoWpbt0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoXenv[];
+
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2];
+
+/*
+ * dmtable and ahtable
+ */
+extern const ACPI_DMTABLE_DATA AcpiDmTableData[];
+extern const AH_TABLE AcpiSupportedTables[];
+
+UINT8
+AcpiDmGenerateChecksum (
+ void *Table,
+ UINT32 Length,
+ UINT8 OriginalChecksum);
+
+const ACPI_DMTABLE_DATA *
+AcpiDmGetTableData (
+ char *Signature);
+
+void
+AcpiDmDumpDataTable (
+ ACPI_TABLE_HEADER *Table);
+
+ACPI_STATUS
+AcpiDmDumpTable (
+ UINT32 TableLength,
+ UINT32 TableOffset,
+ void *Table,
+ UINT32 SubTableLength,
+ ACPI_DMTABLE_INFO *Info);
+
+void
+AcpiDmLineHeader (
+ UINT32 Offset,
+ UINT32 ByteLength,
+ char *Name);
+
+void
+AcpiDmLineHeader2 (
+ UINT32 Offset,
+ UINT32 ByteLength,
+ char *Name,
+ UINT32 Value);
+
+
+/*
+ * dmtbdump
+ */
+void
+AcpiDmDumpBuffer (
+ void *Table,
+ UINT32 BufferOffset,
+ UINT32 Length,
+ UINT32 AbsoluteOffset,
+ char *Header);
+
+void
+AcpiDmDumpUnicode (
+ void *Table,
+ UINT32 BufferOffset,
+ UINT32 ByteLength);
+
+void
+AcpiDmDumpAsf (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpCpep (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpCsrt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpDbg2 (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpDmar (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpDrtm (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpEinj (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpErst (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpFadt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpFpdt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpGtdt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpHest (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpIort (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpIvrs (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpLpit (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpMadt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpMcfg (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpMpst (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpMsct (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpMtmr (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpNfit (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpPcct (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpPmtt (
+ ACPI_TABLE_HEADER *Table);
+
+UINT32
+AcpiDmDumpRsdp (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpRsdt (
+ ACPI_TABLE_HEADER *Table);
+
+UINT32
+AcpiDmDumpS3pt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpSlic (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpSlit (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpSrat (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpStao (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpTcpa (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpVrtc (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpWdat (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpWpbt (
+ ACPI_TABLE_HEADER *Table);
+
+void
+AcpiDmDumpXsdt (
+ ACPI_TABLE_HEADER *Table);
+
+
+/*
+ * dmwalk
+ */
+void
+AcpiDmDisassemble (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Origin,
+ UINT32 NumOpcodes);
+
+void
+AcpiDmWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context);
+
+
+/*
+ * dmopcode
+ */
+void
+AcpiDmDisassembleOneOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AcpiDmListType (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmMethodFlags (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmDisplayTargetPathname (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmNotifyDescription (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmFieldPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmFieldFlags (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmAddressSpace (
+ UINT8 SpaceId);
+
+void
+AcpiDmRegionFlags (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmMatchOp (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * dmnames
+ */
+UINT32
+AcpiDmDumpName (
+ UINT32 Name);
+
+ACPI_STATUS
+AcpiPsDisplayObjectPathname (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmNamestring (
+ char *Name);
+
+
+/*
+ * dmbuffer
+ */
+void
+AcpiDmDisasmByteList (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount);
+
+void
+AcpiDmByteList (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmCheckForHardwareId (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmDecompressEisaId (
+ UINT32 EncodedId);
+
+BOOLEAN
+AcpiDmIsUuidBuffer (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AcpiDmIsUnicodeBuffer (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AcpiDmIsStringBuffer (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AcpiDmIsPldBuffer (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * dmdeferred
+ */
+ACPI_STATUS
+AcpiDmParseDeferredOps (
+ ACPI_PARSE_OBJECT *Root);
+
+
+/*
+ * dmextern
+ */
+ACPI_STATUS
+AcpiDmAddToExternalFileList (
+ char *PathList);
+
+void
+AcpiDmClearExternalFileList (
+ void);
+
+void
+AcpiDmAddOpToExternalList (
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags);
+
+void
+AcpiDmAddNodeToExternalList (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT8 Type,
+ UINT32 Value,
+ UINT16 Flags);
+
+void
+AcpiDmAddExternalsToNamespace (
+ void);
+
+UINT32
+AcpiDmGetExternalMethodCount (
+ void);
+
+void
+AcpiDmClearExternalList (
+ void);
+
+void
+AcpiDmEmitExternals (
+ void);
+
+void
+AcpiDmUnresolvedWarning (
+ UINT8 Type);
+
+void
+AcpiDmGetExternalsFromFile (
+ void);
+
+/*
+ * dmresrc
+ */
+void
+AcpiDmDumpInteger8 (
+ UINT8 Value,
+ char *Name);
+
+void
+AcpiDmDumpInteger16 (
+ UINT16 Value,
+ char *Name);
+
+void
+AcpiDmDumpInteger32 (
+ UINT32 Value,
+ char *Name);
+
+void
+AcpiDmDumpInteger64 (
+ UINT64 Value,
+ char *Name);
+
+void
+AcpiDmResourceTemplate (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *ByteData,
+ UINT32 ByteCount);
+
+ACPI_STATUS
+AcpiDmIsResourceTemplate (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmBitList (
+ UINT16 Mask);
+
+void
+AcpiDmDescriptorName (
+ void);
+
+
+/*
+ * dmresrcl
+ */
+void
+AcpiDmWordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmDwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmExtendedDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmQwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmMemory24Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmFixedMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmGenericRegisterDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmInterruptDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmVendorLargeDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmGpioDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmVendorCommon (
+ char *Name,
+ UINT8 *ByteData,
+ UINT32 Length,
+ UINT32 Level);
+
+
+/*
+ * dmresrcs
+ */
+void
+AcpiDmIrqDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmFixedDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmFixedIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmStartDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmEndDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+void
+AcpiDmVendorSmallDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+
+/*
+ * dmutils
+ */
+void
+AcpiDmDecodeAttribute (
+ UINT8 Attribute);
+
+void
+AcpiDmIndent (
+ UINT32 Level);
+
+BOOLEAN
+AcpiDmCommaIfListMember (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmCommaIfFieldMember (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * dmrestag
+ */
+void
+AcpiDmFindResources (
+ ACPI_PARSE_OBJECT *Root);
+
+void
+AcpiDmCheckResourceReference (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dmcstyle
+ */
+BOOLEAN
+AcpiDmCheckForSymbolicOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OP_WALK_INFO *Info);
+
+void
+AcpiDmCloseOperator (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * acdisasm
+ */
+void
+AdDisassemblerHeader (
+ char *Filename,
+ UINT8 TableType);
+
+#define ACPI_IS_AML_TABLE 0
+#define ACPI_IS_DATA_TABLE 1
+
+#endif /* __ACDISASM_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acdispat.h b/usr/src/boot/sys/contrib/dev/acpica/include/acdispat.h
new file mode 100644
index 0000000000..0a1b1ac4f6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acdispat.h
@@ -0,0 +1,474 @@
+/******************************************************************************
+ *
+ * Name: acdispat.h - dispatcher (parser to interpreter interface)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACDISPAT_H_
+#define _ACDISPAT_H_
+
+
+#define NAMEOF_LOCAL_NTE "__L0"
+#define NAMEOF_ARG_NTE "__A0"
+
+
+/*
+ * dsargs - execution of dynamic arguments for static objects
+ */
+ACPI_STATUS
+AcpiDsGetBufferFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsGetBankFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsGetRegionArguments (
+ ACPI_OPERAND_OBJECT *RgnDesc);
+
+ACPI_STATUS
+AcpiDsGetBufferArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsGetPackageArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+
+/*
+ * dscontrol - support for execution control opcodes
+ */
+ACPI_STATUS
+AcpiDsExecBeginControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsExecEndControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * dsopcode - support for late operand evaluation
+ */
+ACPI_STATUS
+AcpiDsEvalBufferFieldOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsEvalRegionOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsEvalTableRegionOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsEvalDataObjectOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsEvalBankFieldOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsInitializeRegion (
+ ACPI_HANDLE ObjHandle);
+
+
+/*
+ * dsexec - Parser/Interpreter interface, method execution callbacks
+ */
+ACPI_STATUS
+AcpiDsGetPredicateValue (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ResultObj);
+
+ACPI_STATUS
+AcpiDsExecBeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp);
+
+ACPI_STATUS
+AcpiDsExecEndOp (
+ ACPI_WALK_STATE *State);
+
+
+/*
+ * dsfield - Parser/Interpreter interface for AML fields
+ */
+ACPI_STATUS
+AcpiDsCreateField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsCreateBankField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsCreateIndexField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsCreateBufferField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsInitFieldObjects (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dsload - Parser/Interpreter interface
+ */
+ACPI_STATUS
+AcpiDsInitCallbacks (
+ ACPI_WALK_STATE *WalkState,
+ UINT32 PassNumber);
+
+/* dsload - pass 1 namespace load callbacks */
+
+ACPI_STATUS
+AcpiDsLoad1BeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp);
+
+ACPI_STATUS
+AcpiDsLoad1EndOp (
+ ACPI_WALK_STATE *WalkState);
+
+
+/* dsload - pass 2 namespace load callbacks */
+
+ACPI_STATUS
+AcpiDsLoad2BeginOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **OutOp);
+
+ACPI_STATUS
+AcpiDsLoad2EndOp (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dsmthdat - method data (locals/args)
+ */
+ACPI_STATUS
+AcpiDsStoreObjectToLocal (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *SrcDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsMethodDataGetEntry (
+ UINT16 Opcode,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT ***Node);
+
+void
+AcpiDsMethodDataDeleteAll (
+ ACPI_WALK_STATE *WalkState);
+
+BOOLEAN
+AcpiDsIsMethodValue (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsMethodDataGetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **DestDesc);
+
+ACPI_STATUS
+AcpiDsMethodDataInitArgs (
+ ACPI_OPERAND_OBJECT **Params,
+ UINT32 MaxParamCount,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsMethodDataGetNode (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node);
+
+void
+AcpiDsMethodDataInit (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dsmethod - Parser/Interpreter interface - control method parsing
+ */
+ACPI_STATUS
+AcpiDsAutoSerializeMethod (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiDsCallControlMethod (
+ ACPI_THREAD_STATE *Thread,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiDsRestartControlMethod (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ReturnDesc);
+
+void
+AcpiDsTerminateControlMethod (
+ ACPI_OPERAND_OBJECT *MethodDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsBeginMethodExecution (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsMethodError (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState);
+
+/*
+ * dsinit
+ */
+ACPI_STATUS
+AcpiDsInitializeObjects (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode);
+
+
+/*
+ * dsobject - Parser/Interpreter interface - object initialization and conversion
+ */
+ACPI_STATUS
+AcpiDsBuildInternalBufferObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 BufferLength,
+ ACPI_OPERAND_OBJECT **ObjDescPtr);
+
+ACPI_STATUS
+AcpiDsBuildInternalPackageObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *op,
+ UINT32 PackageLength,
+ ACPI_OPERAND_OBJECT **ObjDesc);
+
+ACPI_STATUS
+AcpiDsInitObjectFromOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT **ObjDesc);
+
+ACPI_STATUS
+AcpiDsCreateNode (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * dsutils - Parser/Interpreter interface utility routines
+ */
+void
+AcpiDsClearImplicitReturn (
+ ACPI_WALK_STATE *WalkState);
+
+BOOLEAN
+AcpiDsDoImplicitReturn (
+ ACPI_OPERAND_OBJECT *ReturnDesc,
+ ACPI_WALK_STATE *WalkState,
+ BOOLEAN AddReference);
+
+BOOLEAN
+AcpiDsIsResultUsed (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDsDeleteResultIfNotUsed (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT *ResultObj,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsCreateOperand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg,
+ UINT32 ArgsRemaining);
+
+ACPI_STATUS
+AcpiDsCreateOperands (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *FirstArg);
+
+ACPI_STATUS
+AcpiDsResolveOperands (
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDsClearOperands (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsEvaluateNamePath (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dswscope - Scope Stack manipulation
+ */
+ACPI_STATUS
+AcpiDsScopeStackPush (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_WALK_STATE *WalkState);
+
+
+ACPI_STATUS
+AcpiDsScopeStackPop (
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDsScopeStackClear (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dswstate - parser WALK_STATE management routines
+ */
+ACPI_STATUS
+AcpiDsObjStackPush (
+ void *Object,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsObjStackPop (
+ UINT32 PopCount,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_WALK_STATE *
+AcpiDsCreateWalkState (
+ ACPI_OWNER_ID OwnerId,
+ ACPI_PARSE_OBJECT *Origin,
+ ACPI_OPERAND_OBJECT *MthDesc,
+ ACPI_THREAD_STATE *Thread);
+
+ACPI_STATUS
+AcpiDsInitAmlWalk (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *MethodNode,
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_EVALUATE_INFO *Info,
+ UINT8 PassNumber);
+
+void
+AcpiDsObjStackPopAndDelete (
+ UINT32 PopCount,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiDsDeleteWalkState (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_WALK_STATE *
+AcpiDsPopWalkState (
+ ACPI_THREAD_STATE *Thread);
+
+void
+AcpiDsPushWalkState (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_THREAD_STATE *Thread);
+
+ACPI_STATUS
+AcpiDsResultStackClear (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_WALK_STATE *
+AcpiDsGetCurrentWalkState (
+ ACPI_THREAD_STATE *Thread);
+
+ACPI_STATUS
+AcpiDsResultPop (
+ ACPI_OPERAND_OBJECT **Object,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiDsResultPush (
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * dsdebug - parser debugging routines
+ */
+void
+AcpiDsDumpMethodStack (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+#endif /* _ACDISPAT_H_ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acevents.h b/usr/src/boot/sys/contrib/dev/acpica/include/acevents.h
new file mode 100644
index 0000000000..2ae0aca81a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acevents.h
@@ -0,0 +1,356 @@
+/******************************************************************************
+ *
+ * Name: acevents.h - Event subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACEVENTS_H__
+#define __ACEVENTS_H__
+
+
+/*
+ * evevent
+ */
+ACPI_STATUS
+AcpiEvInitializeEvents (
+ void);
+
+ACPI_STATUS
+AcpiEvInstallXruptHandlers (
+ void);
+
+UINT32
+AcpiEvFixedEventDetect (
+ void);
+
+
+/*
+ * evmisc
+ */
+BOOLEAN
+AcpiEvIsNotifyObject (
+ ACPI_NAMESPACE_NODE *Node);
+
+UINT32
+AcpiEvGetGpeNumberIndex (
+ UINT32 GpeNumber);
+
+ACPI_STATUS
+AcpiEvQueueNotifyRequest (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 NotifyValue);
+
+
+/*
+ * evglock - Global Lock support
+ */
+ACPI_STATUS
+AcpiEvInitGlobalLockHandler (
+ void);
+
+ACPI_HW_DEPENDENT_RETURN_OK (
+ACPI_STATUS
+AcpiEvAcquireGlobalLock(
+ UINT16 Timeout))
+
+ACPI_HW_DEPENDENT_RETURN_OK (
+ACPI_STATUS
+AcpiEvReleaseGlobalLock(
+ void))
+
+ACPI_STATUS
+AcpiEvRemoveGlobalLockHandler (
+ void);
+
+
+/*
+ * evgpe - Low-level GPE support
+ */
+UINT32
+AcpiEvGpeDetect (
+ ACPI_GPE_XRUPT_INFO *GpeXruptList);
+
+ACPI_STATUS
+AcpiEvUpdateGpeEnableMask (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiEvEnableGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiEvAddGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiEvRemoveGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvGetGpeEventInfo (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber);
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+ UINT32 GpeNumber,
+ ACPI_GPE_BLOCK_INFO *GpeBlock);
+
+ACPI_STATUS
+AcpiEvFinishGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+
+/*
+ * evgpeblk - Upper-level GPE block support
+ */
+ACPI_STATUS
+AcpiEvCreateGpeBlock (
+ ACPI_NAMESPACE_NODE *GpeDevice,
+ UINT64 Address,
+ UINT8 SpaceId,
+ UINT32 RegisterCount,
+ UINT16 GpeBlockBaseNumber,
+ UINT32 InterruptNumber,
+ ACPI_GPE_BLOCK_INFO **ReturnGpeBlock);
+
+ACPI_STATUS
+AcpiEvInitializeGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+ACPI_HW_DEPENDENT_RETURN_OK (
+ACPI_STATUS
+AcpiEvDeleteGpeBlock (
+ ACPI_GPE_BLOCK_INFO *GpeBlock))
+
+UINT32
+AcpiEvGpeDispatch (
+ ACPI_NAMESPACE_NODE *GpeDevice,
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ UINT32 GpeNumber);
+
+
+/*
+ * evgpeinit - GPE initialization and update
+ */
+ACPI_STATUS
+AcpiEvGpeInitialize (
+ void);
+
+ACPI_HW_DEPENDENT_RETURN_VOID (
+void
+AcpiEvUpdateGpes (
+ ACPI_OWNER_ID TableOwnerId))
+
+ACPI_STATUS
+AcpiEvMatchGpeMethod (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*
+ * evgpeutil - GPE utilities
+ */
+ACPI_STATUS
+AcpiEvWalkGpeList (
+ ACPI_GPE_CALLBACK GpeWalkCallback,
+ void *Context);
+
+ACPI_STATUS
+AcpiEvGetGpeDevice (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+ACPI_STATUS
+AcpiEvGetGpeXruptBlock (
+ UINT32 InterruptNumber,
+ ACPI_GPE_XRUPT_INFO **GpeXruptBlock);
+
+ACPI_STATUS
+AcpiEvDeleteGpeXrupt (
+ ACPI_GPE_XRUPT_INFO *GpeXrupt);
+
+ACPI_STATUS
+AcpiEvDeleteGpeHandlers (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+
+/*
+ * evhandler - Address space handling
+ */
+BOOLEAN
+AcpiEvHasDefaultHandler (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId);
+
+ACPI_STATUS
+AcpiEvInstallRegionHandlers (
+ void);
+
+ACPI_STATUS
+AcpiEvInstallSpaceHandler (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context);
+
+
+/*
+ * evregion - Operation region support
+ */
+ACPI_STATUS
+AcpiEvInitializeOpRegions (
+ void);
+
+ACPI_STATUS
+AcpiEvAddressSpaceDispatch (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ ACPI_OPERAND_OBJECT *FieldObj,
+ UINT32 Function,
+ UINT32 RegionOffset,
+ UINT32 BitWidth,
+ UINT64 *Value);
+
+ACPI_STATUS
+AcpiEvAttachRegion (
+ ACPI_OPERAND_OBJECT *HandlerObj,
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsIsLocked);
+
+void
+AcpiEvDetachRegion (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsIsLocked);
+
+ACPI_STATUS
+AcpiEvExecuteRegMethods (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId);
+
+ACPI_STATUS
+AcpiEvExecuteRegMethod (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ UINT32 Function);
+
+
+/*
+ * evregini - Region initialization and setup
+ */
+ACPI_STATUS
+AcpiEvSystemMemoryRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvIoSpaceRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvPciConfigRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvCmosRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvPciBarRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvDefaultRegionSetup (
+ ACPI_HANDLE Handle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+ACPI_STATUS
+AcpiEvInitializeRegion (
+ ACPI_OPERAND_OBJECT *RegionObj,
+ BOOLEAN AcpiNsLocked);
+
+
+/*
+ * evsci - SCI (System Control Interrupt) handling/dispatch
+ */
+UINT32 ACPI_SYSTEM_XFACE
+AcpiEvGpeXruptHandler (
+ void *Context);
+
+UINT32
+AcpiEvSciDispatch (
+ void);
+
+UINT32
+AcpiEvInstallSciHandler (
+ void);
+
+ACPI_STATUS
+AcpiEvRemoveAllSciHandlers (
+ void);
+
+ACPI_HW_DEPENDENT_RETURN_VOID (
+void
+AcpiEvTerminate (
+ void))
+
+#endif /* __ACEVENTS_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acexcep.h b/usr/src/boot/sys/contrib/dev/acpica/include/acexcep.h
new file mode 100644
index 0000000000..714e3b1bf3
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acexcep.h
@@ -0,0 +1,350 @@
+/******************************************************************************
+ *
+ * Name: acexcep.h - Exception codes returned by the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACEXCEP_H__
+#define __ACEXCEP_H__
+
+
+/* This module contains all possible exception codes for ACPI_STATUS */
+
+/*
+ * Exception code classes
+ */
+#define AE_CODE_ENVIRONMENTAL 0x0000 /* General ACPICA environment */
+#define AE_CODE_PROGRAMMER 0x1000 /* External ACPICA interface caller */
+#define AE_CODE_ACPI_TABLES 0x2000 /* ACPI tables */
+#define AE_CODE_AML 0x3000 /* From executing AML code */
+#define AE_CODE_CONTROL 0x4000 /* Internal control codes */
+
+#define AE_CODE_MAX 0x4000
+#define AE_CODE_MASK 0xF000
+
+/*
+ * Macros to insert the exception code classes
+ */
+#define EXCEP_ENV(code) ((ACPI_STATUS) (code | AE_CODE_ENVIRONMENTAL))
+#define EXCEP_PGM(code) ((ACPI_STATUS) (code | AE_CODE_PROGRAMMER))
+#define EXCEP_TBL(code) ((ACPI_STATUS) (code | AE_CODE_ACPI_TABLES))
+#define EXCEP_AML(code) ((ACPI_STATUS) (code | AE_CODE_AML))
+#define EXCEP_CTL(code) ((ACPI_STATUS) (code | AE_CODE_CONTROL))
+
+/*
+ * Exception info table. The "Description" field is used only by the
+ * ACPICA help application (acpihelp).
+ */
+typedef struct acpi_exception_info
+{
+ char *Name;
+
+#ifdef ACPI_HELP_APP
+ char *Description;
+#endif
+} ACPI_EXCEPTION_INFO;
+
+#ifdef ACPI_HELP_APP
+#define EXCEP_TXT(Name,Description) {Name, Description}
+#else
+#define EXCEP_TXT(Name,Description) {Name}
+#endif
+
+
+/*
+ * Success is always zero, failure is non-zero
+ */
+#define ACPI_SUCCESS(a) (!(a))
+#define ACPI_FAILURE(a) (a)
+
+#define AE_OK (ACPI_STATUS) 0x0000
+
+/*
+ * Environmental exceptions
+ */
+#define AE_ERROR EXCEP_ENV (0x0001)
+#define AE_NO_ACPI_TABLES EXCEP_ENV (0x0002)
+#define AE_NO_NAMESPACE EXCEP_ENV (0x0003)
+#define AE_NO_MEMORY EXCEP_ENV (0x0004)
+#define AE_NOT_FOUND EXCEP_ENV (0x0005)
+#define AE_NOT_EXIST EXCEP_ENV (0x0006)
+#define AE_ALREADY_EXISTS EXCEP_ENV (0x0007)
+#define AE_TYPE EXCEP_ENV (0x0008)
+#define AE_NULL_OBJECT EXCEP_ENV (0x0009)
+#define AE_NULL_ENTRY EXCEP_ENV (0x000A)
+#define AE_BUFFER_OVERFLOW EXCEP_ENV (0x000B)
+#define AE_STACK_OVERFLOW EXCEP_ENV (0x000C)
+#define AE_STACK_UNDERFLOW EXCEP_ENV (0x000D)
+#define AE_NOT_IMPLEMENTED EXCEP_ENV (0x000E)
+#define AE_SUPPORT EXCEP_ENV (0x000F)
+#define AE_LIMIT EXCEP_ENV (0x0010)
+#define AE_TIME EXCEP_ENV (0x0011)
+#define AE_ACQUIRE_DEADLOCK EXCEP_ENV (0x0012)
+#define AE_RELEASE_DEADLOCK EXCEP_ENV (0x0013)
+#define AE_NOT_ACQUIRED EXCEP_ENV (0x0014)
+#define AE_ALREADY_ACQUIRED EXCEP_ENV (0x0015)
+#define AE_NO_HARDWARE_RESPONSE EXCEP_ENV (0x0016)
+#define AE_NO_GLOBAL_LOCK EXCEP_ENV (0x0017)
+#define AE_ABORT_METHOD EXCEP_ENV (0x0018)
+#define AE_SAME_HANDLER EXCEP_ENV (0x0019)
+#define AE_NO_HANDLER EXCEP_ENV (0x001A)
+#define AE_OWNER_ID_LIMIT EXCEP_ENV (0x001B)
+#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
+#define AE_ACCESS EXCEP_ENV (0x001D)
+
+#define AE_CODE_ENV_MAX 0x001D
+
+
+/*
+ * Programmer exceptions
+ */
+#define AE_BAD_PARAMETER EXCEP_PGM (0x0001)
+#define AE_BAD_CHARACTER EXCEP_PGM (0x0002)
+#define AE_BAD_PATHNAME EXCEP_PGM (0x0003)
+#define AE_BAD_DATA EXCEP_PGM (0x0004)
+#define AE_BAD_HEX_CONSTANT EXCEP_PGM (0x0005)
+#define AE_BAD_OCTAL_CONSTANT EXCEP_PGM (0x0006)
+#define AE_BAD_DECIMAL_CONSTANT EXCEP_PGM (0x0007)
+#define AE_MISSING_ARGUMENTS EXCEP_PGM (0x0008)
+#define AE_BAD_ADDRESS EXCEP_PGM (0x0009)
+
+#define AE_CODE_PGM_MAX 0x0009
+
+
+/*
+ * Acpi table exceptions
+ */
+#define AE_BAD_SIGNATURE EXCEP_TBL (0x0001)
+#define AE_BAD_HEADER EXCEP_TBL (0x0002)
+#define AE_BAD_CHECKSUM EXCEP_TBL (0x0003)
+#define AE_BAD_VALUE EXCEP_TBL (0x0004)
+#define AE_INVALID_TABLE_LENGTH EXCEP_TBL (0x0005)
+
+#define AE_CODE_TBL_MAX 0x0005
+
+
+/*
+ * AML exceptions. These are caused by problems with
+ * the actual AML byte stream
+ */
+#define AE_AML_BAD_OPCODE EXCEP_AML (0x0001)
+#define AE_AML_NO_OPERAND EXCEP_AML (0x0002)
+#define AE_AML_OPERAND_TYPE EXCEP_AML (0x0003)
+#define AE_AML_OPERAND_VALUE EXCEP_AML (0x0004)
+#define AE_AML_UNINITIALIZED_LOCAL EXCEP_AML (0x0005)
+#define AE_AML_UNINITIALIZED_ARG EXCEP_AML (0x0006)
+#define AE_AML_UNINITIALIZED_ELEMENT EXCEP_AML (0x0007)
+#define AE_AML_NUMERIC_OVERFLOW EXCEP_AML (0x0008)
+#define AE_AML_REGION_LIMIT EXCEP_AML (0x0009)
+#define AE_AML_BUFFER_LIMIT EXCEP_AML (0x000A)
+#define AE_AML_PACKAGE_LIMIT EXCEP_AML (0x000B)
+#define AE_AML_DIVIDE_BY_ZERO EXCEP_AML (0x000C)
+#define AE_AML_BAD_NAME EXCEP_AML (0x000D)
+#define AE_AML_NAME_NOT_FOUND EXCEP_AML (0x000E)
+#define AE_AML_INTERNAL EXCEP_AML (0x000F)
+#define AE_AML_INVALID_SPACE_ID EXCEP_AML (0x0010)
+#define AE_AML_STRING_LIMIT EXCEP_AML (0x0011)
+#define AE_AML_NO_RETURN_VALUE EXCEP_AML (0x0012)
+#define AE_AML_METHOD_LIMIT EXCEP_AML (0x0013)
+#define AE_AML_NOT_OWNER EXCEP_AML (0x0014)
+#define AE_AML_MUTEX_ORDER EXCEP_AML (0x0015)
+#define AE_AML_MUTEX_NOT_ACQUIRED EXCEP_AML (0x0016)
+#define AE_AML_INVALID_RESOURCE_TYPE EXCEP_AML (0x0017)
+#define AE_AML_INVALID_INDEX EXCEP_AML (0x0018)
+#define AE_AML_REGISTER_LIMIT EXCEP_AML (0x0019)
+#define AE_AML_NO_WHILE EXCEP_AML (0x001A)
+#define AE_AML_ALIGNMENT EXCEP_AML (0x001B)
+#define AE_AML_NO_RESOURCE_END_TAG EXCEP_AML (0x001C)
+#define AE_AML_BAD_RESOURCE_VALUE EXCEP_AML (0x001D)
+#define AE_AML_CIRCULAR_REFERENCE EXCEP_AML (0x001E)
+#define AE_AML_BAD_RESOURCE_LENGTH EXCEP_AML (0x001F)
+#define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020)
+#define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021)
+#define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022)
+
+#define AE_CODE_AML_MAX 0x0022
+
+
+/*
+ * Internal exceptions used for control
+ */
+#define AE_CTRL_RETURN_VALUE EXCEP_CTL (0x0001)
+#define AE_CTRL_PENDING EXCEP_CTL (0x0002)
+#define AE_CTRL_TERMINATE EXCEP_CTL (0x0003)
+#define AE_CTRL_TRUE EXCEP_CTL (0x0004)
+#define AE_CTRL_FALSE EXCEP_CTL (0x0005)
+#define AE_CTRL_DEPTH EXCEP_CTL (0x0006)
+#define AE_CTRL_END EXCEP_CTL (0x0007)
+#define AE_CTRL_TRANSFER EXCEP_CTL (0x0008)
+#define AE_CTRL_BREAK EXCEP_CTL (0x0009)
+#define AE_CTRL_CONTINUE EXCEP_CTL (0x000A)
+#define AE_CTRL_SKIP EXCEP_CTL (0x000B)
+#define AE_CTRL_PARSE_CONTINUE EXCEP_CTL (0x000C)
+#define AE_CTRL_PARSE_PENDING EXCEP_CTL (0x000D)
+
+#define AE_CODE_CTRL_MAX 0x000D
+
+
+/* Exception strings for AcpiFormatException */
+
+#ifdef ACPI_DEFINE_EXCEPTION_TABLE
+
+/*
+ * String versions of the exception codes above
+ * These strings must match the corresponding defines exactly
+ */
+static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Env[] =
+{
+ EXCEP_TXT ("AE_OK", "No error"),
+ EXCEP_TXT ("AE_ERROR", "Unspecified error"),
+ EXCEP_TXT ("AE_NO_ACPI_TABLES", "ACPI tables could not be found"),
+ EXCEP_TXT ("AE_NO_NAMESPACE", "A namespace has not been loaded"),
+ EXCEP_TXT ("AE_NO_MEMORY", "Insufficient dynamic memory"),
+ EXCEP_TXT ("AE_NOT_FOUND", "A requested entity is not found"),
+ EXCEP_TXT ("AE_NOT_EXIST", "A required entity does not exist"),
+ EXCEP_TXT ("AE_ALREADY_EXISTS", "An entity already exists"),
+ EXCEP_TXT ("AE_TYPE", "The object type is incorrect"),
+ EXCEP_TXT ("AE_NULL_OBJECT", "A required object was missing"),
+ EXCEP_TXT ("AE_NULL_ENTRY", "The requested object does not exist"),
+ EXCEP_TXT ("AE_BUFFER_OVERFLOW", "The buffer provided is too small"),
+ EXCEP_TXT ("AE_STACK_OVERFLOW", "An internal stack overflowed"),
+ EXCEP_TXT ("AE_STACK_UNDERFLOW", "An internal stack underflowed"),
+ EXCEP_TXT ("AE_NOT_IMPLEMENTED", "The feature is not implemented"),
+ EXCEP_TXT ("AE_SUPPORT", "The feature is not supported"),
+ EXCEP_TXT ("AE_LIMIT", "A predefined limit was exceeded"),
+ EXCEP_TXT ("AE_TIME", "A time limit or timeout expired"),
+ EXCEP_TXT ("AE_ACQUIRE_DEADLOCK", "Internal error, attempt was made to acquire a mutex in improper order"),
+ EXCEP_TXT ("AE_RELEASE_DEADLOCK", "Internal error, attempt was made to release a mutex in improper order"),
+ EXCEP_TXT ("AE_NOT_ACQUIRED", "An attempt to release a mutex or Global Lock without a previous acquire"),
+ EXCEP_TXT ("AE_ALREADY_ACQUIRED", "Internal error, attempt was made to acquire a mutex twice"),
+ EXCEP_TXT ("AE_NO_HARDWARE_RESPONSE", "Hardware did not respond after an I/O operation"),
+ EXCEP_TXT ("AE_NO_GLOBAL_LOCK", "There is no FACS Global Lock"),
+ EXCEP_TXT ("AE_ABORT_METHOD", "A control method was aborted"),
+ EXCEP_TXT ("AE_SAME_HANDLER", "Attempt was made to install the same handler that is already installed"),
+ EXCEP_TXT ("AE_NO_HANDLER", "A handler for the operation is not installed"),
+ EXCEP_TXT ("AE_OWNER_ID_LIMIT", "There are no more Owner IDs available for ACPI tables or control methods"),
+ EXCEP_TXT ("AE_NOT_CONFIGURED", "The interface is not part of the current subsystem configuration"),
+ EXCEP_TXT ("AE_ACCESS", "Permission denied for the requested operation")
+};
+
+static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Pgm[] =
+{
+ EXCEP_TXT (NULL, NULL),
+ EXCEP_TXT ("AE_BAD_PARAMETER", "A parameter is out of range or invalid"),
+ EXCEP_TXT ("AE_BAD_CHARACTER", "An invalid character was found in a name"),
+ EXCEP_TXT ("AE_BAD_PATHNAME", "An invalid character was found in a pathname"),
+ EXCEP_TXT ("AE_BAD_DATA", "A package or buffer contained incorrect data"),
+ EXCEP_TXT ("AE_BAD_HEX_CONSTANT", "Invalid character in a Hex constant"),
+ EXCEP_TXT ("AE_BAD_OCTAL_CONSTANT", "Invalid character in an Octal constant"),
+ EXCEP_TXT ("AE_BAD_DECIMAL_CONSTANT", "Invalid character in a Decimal constant"),
+ EXCEP_TXT ("AE_MISSING_ARGUMENTS", "Too few arguments were passed to a control method"),
+ EXCEP_TXT ("AE_BAD_ADDRESS", "An illegal null I/O address")
+};
+
+static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Tbl[] =
+{
+ EXCEP_TXT (NULL, NULL),
+ EXCEP_TXT ("AE_BAD_SIGNATURE", "An ACPI table has an invalid signature"),
+ EXCEP_TXT ("AE_BAD_HEADER", "Invalid field in an ACPI table header"),
+ EXCEP_TXT ("AE_BAD_CHECKSUM", "An ACPI table checksum is not correct"),
+ EXCEP_TXT ("AE_BAD_VALUE", "An invalid value was found in a table"),
+ EXCEP_TXT ("AE_INVALID_TABLE_LENGTH", "The FADT or FACS has improper length")
+};
+
+static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Aml[] =
+{
+ EXCEP_TXT (NULL, NULL),
+ EXCEP_TXT ("AE_AML_BAD_OPCODE", "Invalid AML opcode encountered"),
+ EXCEP_TXT ("AE_AML_NO_OPERAND", "A required operand is missing"),
+ EXCEP_TXT ("AE_AML_OPERAND_TYPE", "An operand of an incorrect type was encountered"),
+ EXCEP_TXT ("AE_AML_OPERAND_VALUE", "The operand had an inappropriate or invalid value"),
+ EXCEP_TXT ("AE_AML_UNINITIALIZED_LOCAL", "Method tried to use an uninitialized local variable"),
+ EXCEP_TXT ("AE_AML_UNINITIALIZED_ARG", "Method tried to use an uninitialized argument"),
+ EXCEP_TXT ("AE_AML_UNINITIALIZED_ELEMENT", "Method tried to use an empty package element"),
+ EXCEP_TXT ("AE_AML_NUMERIC_OVERFLOW", "Overflow during BCD conversion or other"),
+ EXCEP_TXT ("AE_AML_REGION_LIMIT", "Tried to access beyond the end of an Operation Region"),
+ EXCEP_TXT ("AE_AML_BUFFER_LIMIT", "Tried to access beyond the end of a buffer"),
+ EXCEP_TXT ("AE_AML_PACKAGE_LIMIT", "Tried to access beyond the end of a package"),
+ EXCEP_TXT ("AE_AML_DIVIDE_BY_ZERO", "During execution of AML Divide operator"),
+ EXCEP_TXT ("AE_AML_BAD_NAME", "An ACPI name contains invalid character(s)"),
+ EXCEP_TXT ("AE_AML_NAME_NOT_FOUND", "Could not resolve a named reference"),
+ EXCEP_TXT ("AE_AML_INTERNAL", "An internal error within the interprete"),
+ EXCEP_TXT ("AE_AML_INVALID_SPACE_ID", "An Operation Region SpaceID is invalid"),
+ EXCEP_TXT ("AE_AML_STRING_LIMIT", "String is longer than 200 characters"),
+ EXCEP_TXT ("AE_AML_NO_RETURN_VALUE", "A method did not return a required value"),
+ EXCEP_TXT ("AE_AML_METHOD_LIMIT", "A control method reached the maximum reentrancy limit of 255"),
+ EXCEP_TXT ("AE_AML_NOT_OWNER", "A thread tried to release a mutex that it does not own"),
+ EXCEP_TXT ("AE_AML_MUTEX_ORDER", "Mutex SyncLevel release mismatch"),
+ EXCEP_TXT ("AE_AML_MUTEX_NOT_ACQUIRED", "Attempt to release a mutex that was not previously acquired"),
+ EXCEP_TXT ("AE_AML_INVALID_RESOURCE_TYPE", "Invalid resource type in resource list"),
+ EXCEP_TXT ("AE_AML_INVALID_INDEX", "Invalid Argx or Localx (x too large)"),
+ EXCEP_TXT ("AE_AML_REGISTER_LIMIT", "Bank value or Index value beyond range of register"),
+ EXCEP_TXT ("AE_AML_NO_WHILE", "Break or Continue without a While"),
+ EXCEP_TXT ("AE_AML_ALIGNMENT", "Non-aligned memory transfer on platform that does not support this"),
+ EXCEP_TXT ("AE_AML_NO_RESOURCE_END_TAG", "No End Tag in a resource list"),
+ EXCEP_TXT ("AE_AML_BAD_RESOURCE_VALUE", "Invalid value of a resource element"),
+ EXCEP_TXT ("AE_AML_CIRCULAR_REFERENCE", "Two references refer to each other"),
+ EXCEP_TXT ("AE_AML_BAD_RESOURCE_LENGTH", "The length of a Resource Descriptor in the AML is incorrect"),
+ EXCEP_TXT ("AE_AML_ILLEGAL_ADDRESS", "A memory, I/O, or PCI configuration address is invalid"),
+ EXCEP_TXT ("AE_AML_INFINITE_LOOP", "An apparent infinite AML While loop, method was aborted"),
+ EXCEP_TXT ("AE_AML_UNINITIALIZED_NODE", "A namespace node is uninitialized or unresolved")
+};
+
+static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Ctrl[] =
+{
+ EXCEP_TXT (NULL, NULL),
+ EXCEP_TXT ("AE_CTRL_RETURN_VALUE", "A Method returned a value"),
+ EXCEP_TXT ("AE_CTRL_PENDING", "Method is calling another method"),
+ EXCEP_TXT ("AE_CTRL_TERMINATE", "Terminate the executing method"),
+ EXCEP_TXT ("AE_CTRL_TRUE", "An If or While predicate result"),
+ EXCEP_TXT ("AE_CTRL_FALSE", "An If or While predicate result"),
+ EXCEP_TXT ("AE_CTRL_DEPTH", "Maximum search depth has been reached"),
+ EXCEP_TXT ("AE_CTRL_END", "An If or While predicate is false"),
+ EXCEP_TXT ("AE_CTRL_TRANSFER", "Transfer control to called method"),
+ EXCEP_TXT ("AE_CTRL_BREAK", "A Break has been executed"),
+ EXCEP_TXT ("AE_CTRL_CONTINUE", "A Continue has been executed"),
+ EXCEP_TXT ("AE_CTRL_SKIP", "Not currently used"),
+ EXCEP_TXT ("AE_CTRL_PARSE_CONTINUE", "Used to skip over bad opcodes"),
+ EXCEP_TXT ("AE_CTRL_PARSE_PENDING", "Used to implement AML While loops")
+};
+
+#endif /* EXCEPTION_TABLE */
+
+#endif /* __ACEXCEP_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acglobal.h b/usr/src/boot/sys/contrib/dev/acpica/include/acglobal.h
new file mode 100644
index 0000000000..08d60fd7b7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acglobal.h
@@ -0,0 +1,396 @@
+/******************************************************************************
+ *
+ * Name: acglobal.h - Declarations for global variables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACGLOBAL_H__
+#define __ACGLOBAL_H__
+
+
+/*****************************************************************************
+ *
+ * Globals related to the ACPI tables
+ *
+ ****************************************************************************/
+
+/* Master list of all ACPI tables that were found in the RSDT/XSDT */
+
+ACPI_GLOBAL (ACPI_TABLE_LIST, AcpiGbl_RootTableList);
+
+/* DSDT information. Used to check for DSDT corruption */
+
+ACPI_GLOBAL (ACPI_TABLE_HEADER *, AcpiGbl_DSDT);
+ACPI_GLOBAL (ACPI_TABLE_HEADER, AcpiGbl_OriginalDsdtHeader);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_DsdtIndex, ACPI_INVALID_TABLE_INDEX);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_FacsIndex, ACPI_INVALID_TABLE_INDEX);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_XFacsIndex, ACPI_INVALID_TABLE_INDEX);
+
+#if (!ACPI_REDUCED_HARDWARE)
+ACPI_GLOBAL (ACPI_TABLE_FACS *, AcpiGbl_FACS);
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+/* These addresses are calculated from the FADT Event Block addresses */
+
+ACPI_GLOBAL (ACPI_GENERIC_ADDRESS, AcpiGbl_XPm1aStatus);
+ACPI_GLOBAL (ACPI_GENERIC_ADDRESS, AcpiGbl_XPm1aEnable);
+
+ACPI_GLOBAL (ACPI_GENERIC_ADDRESS, AcpiGbl_XPm1bStatus);
+ACPI_GLOBAL (ACPI_GENERIC_ADDRESS, AcpiGbl_XPm1bEnable);
+
+/*
+ * Handle both ACPI 1.0 and ACPI 2.0+ Integer widths. The integer width is
+ * determined by the revision of the DSDT: If the DSDT revision is less than
+ * 2, use only the lower 32 bits of the internal 64-bit Integer.
+ */
+ACPI_GLOBAL (UINT8, AcpiGbl_IntegerBitWidth);
+ACPI_GLOBAL (UINT8, AcpiGbl_IntegerByteWidth);
+ACPI_GLOBAL (UINT8, AcpiGbl_IntegerNybbleWidth);
+
+
+/*****************************************************************************
+ *
+ * Mutual exclusion within ACPICA subsystem
+ *
+ ****************************************************************************/
+
+/*
+ * Predefined mutex objects. This array contains the
+ * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
+ * (The table maps local handles to the real OS handles)
+ */
+ACPI_GLOBAL (ACPI_MUTEX_INFO, AcpiGbl_MutexInfo[ACPI_NUM_MUTEX]);
+
+/*
+ * Global lock mutex is an actual AML mutex object
+ * Global lock semaphore works in conjunction with the actual global lock
+ * Global lock spinlock is used for "pending" handshake
+ */
+ACPI_GLOBAL (ACPI_OPERAND_OBJECT *, AcpiGbl_GlobalLockMutex);
+ACPI_GLOBAL (ACPI_SEMAPHORE, AcpiGbl_GlobalLockSemaphore);
+ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_GlobalLockPendingLock);
+ACPI_GLOBAL (UINT16, AcpiGbl_GlobalLockHandle);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_GlobalLockAcquired);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_GlobalLockPresent);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_GlobalLockPending);
+
+/*
+ * Spinlocks are used for interfaces that can be possibly called at
+ * interrupt level
+ */
+ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_GpeLock); /* For GPE data structs and registers */
+ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_HardwareLock); /* For ACPI H/W except GPE registers */
+ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_ReferenceCountLock);
+
+/* Mutex for _OSI support */
+
+ACPI_GLOBAL (ACPI_MUTEX, AcpiGbl_OsiMutex);
+
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_GLOBAL (ACPI_RW_LOCK, AcpiGbl_NamespaceRwLock);
+
+
+/*****************************************************************************
+ *
+ * Miscellaneous globals
+ *
+ ****************************************************************************/
+
+/* Object caches */
+
+ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_NamespaceCache);
+ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_StateCache);
+ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_PsNodeCache);
+ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_PsNodeExtCache);
+ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_OperandCache);
+
+/* System */
+
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_StartupFlags, 0);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_Shutdown, TRUE);
+
+/* Global handlers */
+
+ACPI_GLOBAL (ACPI_GLOBAL_NOTIFY_HANDLER,AcpiGbl_GlobalNotify[2]);
+ACPI_GLOBAL (ACPI_EXCEPTION_HANDLER, AcpiGbl_ExceptionHandler);
+ACPI_GLOBAL (ACPI_INIT_HANDLER, AcpiGbl_InitHandler);
+ACPI_GLOBAL (ACPI_TABLE_HANDLER, AcpiGbl_TableHandler);
+ACPI_GLOBAL (void *, AcpiGbl_TableHandlerContext);
+ACPI_GLOBAL (ACPI_INTERFACE_HANDLER, AcpiGbl_InterfaceHandler);
+ACPI_GLOBAL (ACPI_SCI_HANDLER_INFO *, AcpiGbl_SciHandlerList);
+
+/* Owner ID support */
+
+ACPI_GLOBAL (UINT32, AcpiGbl_OwnerIdMask[ACPI_NUM_OWNERID_MASKS]);
+ACPI_GLOBAL (UINT8, AcpiGbl_LastOwnerIdIndex);
+ACPI_GLOBAL (UINT8, AcpiGbl_NextOwnerIdOffset);
+
+/* Initialization sequencing */
+
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_RegMethodsExecuted);
+
+/* Misc */
+
+ACPI_GLOBAL (UINT32, AcpiGbl_OriginalMode);
+ACPI_GLOBAL (UINT32, AcpiGbl_NsLookupCount);
+ACPI_GLOBAL (UINT32, AcpiGbl_PsFindCount);
+ACPI_GLOBAL (UINT16, AcpiGbl_Pm1EnableRegisterSave);
+ACPI_GLOBAL (UINT8, AcpiGbl_DebuggerConfiguration);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_StepToNextCall);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_AcpiHardwarePresent);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_EventsInitialized);
+ACPI_GLOBAL (ACPI_INTERFACE_INFO *, AcpiGbl_SupportedInterfaces);
+ACPI_GLOBAL (ACPI_ADDRESS_RANGE *, AcpiGbl_AddressRangeList[ACPI_ADDRESS_RANGE_MAX]);
+
+/* Other miscellaneous, declared and initialized in utglobal */
+
+extern const char *AcpiGbl_SleepStateNames[ACPI_S_STATE_COUNT];
+extern const char *AcpiGbl_LowestDstateNames[ACPI_NUM_SxW_METHODS];
+extern const char *AcpiGbl_HighestDstateNames[ACPI_NUM_SxD_METHODS];
+extern const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS];
+extern const ACPI_OPCODE_INFO AcpiGbl_AmlOpInfo[AML_NUM_OPCODES];
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+/* Lists for tracking memory allocations (debug only) */
+
+ACPI_GLOBAL (ACPI_MEMORY_LIST *, AcpiGbl_GlobalList);
+ACPI_GLOBAL (ACPI_MEMORY_LIST *, AcpiGbl_NsNodeList);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DisplayFinalMemStats);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DisableMemTracking);
+#endif
+
+
+/*****************************************************************************
+ *
+ * Namespace globals
+ *
+ ****************************************************************************/
+
+#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#define NUM_PREDEFINED_NAMES 10
+#else
+#define NUM_PREDEFINED_NAMES 9
+#endif
+
+ACPI_GLOBAL (ACPI_NAMESPACE_NODE, AcpiGbl_RootNodeStruct);
+ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_RootNode);
+ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_FadtGpeDevice);
+ACPI_GLOBAL (ACPI_OPERAND_OBJECT *, AcpiGbl_ModuleCodeList);
+
+
+extern const UINT8 AcpiGbl_NsProperties [ACPI_NUM_NS_TYPES];
+extern const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames [NUM_PREDEFINED_NAMES];
+
+#ifdef ACPI_DEBUG_OUTPUT
+ACPI_GLOBAL (UINT32, AcpiGbl_CurrentNodeCount);
+ACPI_GLOBAL (UINT32, AcpiGbl_CurrentNodeSize);
+ACPI_GLOBAL (UINT32, AcpiGbl_MaxConcurrentNodeCount);
+ACPI_GLOBAL (ACPI_SIZE *, AcpiGbl_EntryStackPointer);
+ACPI_GLOBAL (ACPI_SIZE *, AcpiGbl_LowestStackPointer);
+ACPI_GLOBAL (UINT32, AcpiGbl_DeepestNesting);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_NestingLevel, 0);
+#endif
+
+
+/*****************************************************************************
+ *
+ * Interpreter globals
+ *
+ ****************************************************************************/
+
+ACPI_GLOBAL (ACPI_THREAD_STATE *, AcpiGbl_CurrentWalkList);
+
+/* Maximum number of While() loop iterations before forced abort */
+
+ACPI_GLOBAL (UINT16, AcpiGbl_MaxLoopIterations);
+
+/* Control method single step flag */
+
+ACPI_GLOBAL (UINT8, AcpiGbl_CmSingleStep);
+
+
+/*****************************************************************************
+ *
+ * Hardware globals
+ *
+ ****************************************************************************/
+
+extern ACPI_BIT_REGISTER_INFO AcpiGbl_BitRegisterInfo[ACPI_NUM_BITREG];
+
+ACPI_GLOBAL (UINT8, AcpiGbl_SleepTypeA);
+ACPI_GLOBAL (UINT8, AcpiGbl_SleepTypeB);
+
+
+/*****************************************************************************
+ *
+ * Event and GPE globals
+ *
+ ****************************************************************************/
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ACPI_GLOBAL (UINT8, AcpiGbl_AllGpesInitialized);
+ACPI_GLOBAL (ACPI_GPE_XRUPT_INFO *, AcpiGbl_GpeXruptListHead);
+ACPI_GLOBAL (ACPI_GPE_BLOCK_INFO *, AcpiGbl_GpeFadtBlocks[ACPI_MAX_GPE_BLOCKS]);
+ACPI_GLOBAL (ACPI_GBL_EVENT_HANDLER, AcpiGbl_GlobalEventHandler);
+ACPI_GLOBAL (void *, AcpiGbl_GlobalEventHandlerContext);
+ACPI_GLOBAL (ACPI_FIXED_EVENT_HANDLER, AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS]);
+
+extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS];
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+/*****************************************************************************
+ *
+ * Debug support
+ *
+ ****************************************************************************/
+
+/* Event counters */
+
+ACPI_GLOBAL (UINT32, AcpiMethodCount);
+ACPI_GLOBAL (UINT32, AcpiGpeCount);
+ACPI_GLOBAL (UINT32, AcpiSciCount);
+ACPI_GLOBAL (UINT32, AcpiFixedEventCount[ACPI_NUM_FIXED_EVENTS]);
+
+/* Support for dynamic control method tracing mechanism */
+
+ACPI_GLOBAL (UINT32, AcpiGbl_OriginalDbgLevel);
+ACPI_GLOBAL (UINT32, AcpiGbl_OriginalDbgLayer);
+
+
+/*****************************************************************************
+ *
+ * Debugger and Disassembler globals
+ *
+ ****************************************************************************/
+
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DbOutputFlags, ACPI_DB_CONSOLE_OUTPUT);
+
+#ifdef ACPI_DISASSEMBLER
+
+/* Do not disassemble buffers to resource descriptors */
+
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_NoResourceDisassembly, FALSE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_IgnoreNoopOperator, FALSE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_CstyleDisassembly, TRUE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ForceAmlDisassembly, FALSE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Verbose, TRUE);
+
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Disasm);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Listing);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_NumExternalMethods);
+ACPI_GLOBAL (UINT32, AcpiGbl_ResolvedExternalMethods);
+ACPI_GLOBAL (ACPI_EXTERNAL_LIST *, AcpiGbl_ExternalList);
+ACPI_GLOBAL (ACPI_EXTERNAL_FILE *, AcpiGbl_ExternalFileList);
+#endif
+
+#ifdef ACPI_DEBUGGER
+
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DbTerminateThreads, FALSE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_AbortMethod, FALSE);
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_MethodExecuting, FALSE);
+
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DbOpt_NoIniMethods);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DbOpt_NoRegionSupport);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_DbOutputToFile);
+ACPI_GLOBAL (char *, AcpiGbl_DbBuffer);
+ACPI_GLOBAL (char *, AcpiGbl_DbFilename);
+ACPI_GLOBAL (UINT32, AcpiGbl_DbDebugLevel);
+ACPI_GLOBAL (UINT32, AcpiGbl_DbConsoleDebugLevel);
+ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_DbScopeNode);
+
+ACPI_GLOBAL (char *, AcpiGbl_DbArgs[ACPI_DEBUGGER_MAX_ARGS]);
+ACPI_GLOBAL (ACPI_OBJECT_TYPE, AcpiGbl_DbArgTypes[ACPI_DEBUGGER_MAX_ARGS]);
+
+/* These buffers should all be the same size */
+
+ACPI_GLOBAL (char, AcpiGbl_DbLineBuf[ACPI_DB_LINE_BUFFER_SIZE]);
+ACPI_GLOBAL (char, AcpiGbl_DbParsedBuf[ACPI_DB_LINE_BUFFER_SIZE]);
+ACPI_GLOBAL (char, AcpiGbl_DbScopeBuf[ACPI_DB_LINE_BUFFER_SIZE]);
+ACPI_GLOBAL (char, AcpiGbl_DbDebugFilename[ACPI_DB_LINE_BUFFER_SIZE]);
+
+/*
+ * Statistic globals
+ */
+ACPI_GLOBAL (UINT16, AcpiGbl_ObjTypeCount[ACPI_TOTAL_TYPES]);
+ACPI_GLOBAL (UINT16, AcpiGbl_NodeTypeCount[ACPI_TOTAL_TYPES]);
+ACPI_GLOBAL (UINT16, AcpiGbl_ObjTypeCountMisc);
+ACPI_GLOBAL (UINT16, AcpiGbl_NodeTypeCountMisc);
+ACPI_GLOBAL (UINT32, AcpiGbl_NumNodes);
+ACPI_GLOBAL (UINT32, AcpiGbl_NumObjects);
+
+#endif /* ACPI_DEBUGGER */
+
+
+/*****************************************************************************
+ *
+ * Application globals
+ *
+ ****************************************************************************/
+
+#ifdef ACPI_APPLICATION
+
+ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_DebugFile, NULL);
+ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_OutputFile, NULL);
+
+/* Print buffer */
+
+ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_PrintLock); /* For print buffer */
+ACPI_GLOBAL (char, AcpiGbl_PrintBuffer[1024]);
+
+#endif /* ACPI_APPLICATION */
+
+
+/*****************************************************************************
+ *
+ * Info/help support
+ *
+ ****************************************************************************/
+
+extern const AH_PREDEFINED_NAME AslPredefinedInfo[];
+extern const AH_DEVICE_ID AslDeviceIds[];
+
+
+#endif /* __ACGLOBAL_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/achware.h b/usr/src/boot/sys/contrib/dev/acpica/include/achware.h
new file mode 100644
index 0000000000..6ab28b689f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/achware.h
@@ -0,0 +1,227 @@
+/******************************************************************************
+ *
+ * Name: achware.h -- hardware specific interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACHWARE_H__
+#define __ACHWARE_H__
+
+
+/* Values for the _SST predefined method */
+
+#define ACPI_SST_INDICATOR_OFF 0
+#define ACPI_SST_WORKING 1
+#define ACPI_SST_WAKING 2
+#define ACPI_SST_SLEEPING 3
+#define ACPI_SST_SLEEP_CONTEXT 4
+
+
+/*
+ * hwacpi - high level functions
+ */
+ACPI_STATUS
+AcpiHwSetMode (
+ UINT32 Mode);
+
+UINT32
+AcpiHwGetMode (
+ void);
+
+
+/*
+ * hwregs - ACPI Register I/O
+ */
+ACPI_STATUS
+AcpiHwValidateRegister (
+ ACPI_GENERIC_ADDRESS *Reg,
+ UINT8 MaxBitWidth,
+ UINT64 *Address);
+
+ACPI_STATUS
+AcpiHwRead (
+ UINT32 *Value,
+ ACPI_GENERIC_ADDRESS *Reg);
+
+ACPI_STATUS
+AcpiHwWrite (
+ UINT32 Value,
+ ACPI_GENERIC_ADDRESS *Reg);
+
+ACPI_BIT_REGISTER_INFO *
+AcpiHwGetBitRegisterInfo (
+ UINT32 RegisterId);
+
+ACPI_STATUS
+AcpiHwWritePm1Control (
+ UINT32 Pm1aControl,
+ UINT32 Pm1bControl);
+
+ACPI_STATUS
+AcpiHwRegisterRead (
+ UINT32 RegisterId,
+ UINT32 *ReturnValue);
+
+ACPI_STATUS
+AcpiHwRegisterWrite (
+ UINT32 RegisterId,
+ UINT32 Value);
+
+ACPI_STATUS
+AcpiHwClearAcpiStatus (
+ void);
+
+
+/*
+ * hwsleep - sleep/wake support (Legacy sleep registers)
+ */
+ACPI_STATUS
+AcpiHwLegacySleep (
+ UINT8 SleepState);
+
+ACPI_STATUS
+AcpiHwLegacyWakePrep (
+ UINT8 SleepState);
+
+ACPI_STATUS
+AcpiHwLegacyWake (
+ UINT8 SleepState);
+
+
+/*
+ * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers)
+ */
+void
+AcpiHwExecuteSleepMethod (
+ char *MethodName,
+ UINT32 IntegerArgument);
+
+ACPI_STATUS
+AcpiHwExtendedSleep (
+ UINT8 SleepState);
+
+ACPI_STATUS
+AcpiHwExtendedWakePrep (
+ UINT8 SleepState);
+
+ACPI_STATUS
+AcpiHwExtendedWake (
+ UINT8 SleepState);
+
+
+/*
+ * hwvalid - Port I/O with validation
+ */
+ACPI_STATUS
+AcpiHwReadPort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 *Value,
+ UINT32 Width);
+
+ACPI_STATUS
+AcpiHwWritePort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 Value,
+ UINT32 Width);
+
+
+/*
+ * hwgpe - GPE support
+ */
+UINT32
+AcpiHwGetGpeRegisterBit (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiHwLowSetGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ UINT32 Action);
+
+ACPI_STATUS
+AcpiHwDisableGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+ACPI_STATUS
+AcpiHwClearGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiHwClearGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+ACPI_STATUS
+AcpiHwGetGpeStatus (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo,
+ ACPI_EVENT_STATUS *EventStatus);
+
+ACPI_STATUS
+AcpiHwDisableAllGpes (
+ void);
+
+ACPI_STATUS
+AcpiHwEnableAllRuntimeGpes (
+ void);
+
+ACPI_STATUS
+AcpiHwEnableAllWakeupGpes (
+ void);
+
+ACPI_STATUS
+AcpiHwEnableRuntimeGpeBlock (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+
+/*
+ * hwpci - PCI configuration support
+ */
+ACPI_STATUS
+AcpiHwDerivePciId (
+ ACPI_PCI_ID *PciId,
+ ACPI_HANDLE RootPciDevice,
+ ACPI_HANDLE PciRegion);
+
+
+#endif /* __ACHWARE_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acinterp.h b/usr/src/boot/sys/contrib/dev/acpica/include/acinterp.h
new file mode 100644
index 0000000000..f53e6c58f8
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acinterp.h
@@ -0,0 +1,756 @@
+/******************************************************************************
+ *
+ * Name: acinterp.h - Interpreter subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACINTERP_H__
+#define __ACINTERP_H__
+
+
+#define ACPI_WALK_OPERANDS (&(WalkState->Operands [WalkState->NumOperands -1]))
+
+/* Macros for tables used for debug output */
+
+#define ACPI_EXD_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_OPERAND_OBJECT,f)
+#define ACPI_EXD_NSOFFSET(f) (UINT8) ACPI_OFFSET (ACPI_NAMESPACE_NODE,f)
+#define ACPI_EXD_TABLE_SIZE(name) (sizeof(name) / sizeof (ACPI_EXDUMP_INFO))
+
+/*
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
+ */
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
+#pragma pack(1)
+#endif
+
+typedef const struct acpi_exdump_info
+{
+ UINT8 Opcode;
+ UINT8 Offset;
+ char *Name;
+
+} ACPI_EXDUMP_INFO;
+
+/* Values for the Opcode field above */
+
+#define ACPI_EXD_INIT 0
+#define ACPI_EXD_TYPE 1
+#define ACPI_EXD_UINT8 2
+#define ACPI_EXD_UINT16 3
+#define ACPI_EXD_UINT32 4
+#define ACPI_EXD_UINT64 5
+#define ACPI_EXD_LITERAL 6
+#define ACPI_EXD_POINTER 7
+#define ACPI_EXD_ADDRESS 8
+#define ACPI_EXD_STRING 9
+#define ACPI_EXD_BUFFER 10
+#define ACPI_EXD_PACKAGE 11
+#define ACPI_EXD_FIELD 12
+#define ACPI_EXD_REFERENCE 13
+#define ACPI_EXD_LIST 14 /* Operand object list */
+#define ACPI_EXD_HDLR_LIST 15 /* Address Handler list */
+#define ACPI_EXD_RGN_LIST 16 /* Region list */
+#define ACPI_EXD_NODE 17 /* Namespace Node */
+
+/* restore default alignment */
+
+#pragma pack()
+
+
+/*
+ * exconvrt - object conversion
+ */
+ACPI_STATUS
+AcpiExConvertToInteger (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ UINT32 Flags);
+
+ACPI_STATUS
+AcpiExConvertToBuffer (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc);
+
+ACPI_STATUS
+AcpiExConvertToString (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ UINT32 Type);
+
+/* Types for ->String conversion */
+
+#define ACPI_EXPLICIT_BYTE_COPY 0x00000000
+#define ACPI_EXPLICIT_CONVERT_HEX 0x00000001
+#define ACPI_IMPLICIT_CONVERT_HEX 0x00000002
+#define ACPI_EXPLICIT_CONVERT_DECIMAL 0x00000003
+
+ACPI_STATUS
+AcpiExConvertToTargetType (
+ ACPI_OBJECT_TYPE DestinationType,
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exdebug - AML debug object
+ */
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index);
+
+void
+AcpiExStartTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiExStopTraceMethod (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiExStartTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiExStopTraceOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiExTracePoint (
+ ACPI_TRACE_EVENT_TYPE Type,
+ BOOLEAN Begin,
+ UINT8 *Aml,
+ char *Pathname);
+
+
+/*
+ * exfield - ACPI AML (p-code) execution - field manipulation
+ */
+ACPI_STATUS
+AcpiExCommonBufferSetup (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 BufferLength,
+ UINT32 *DatumCount);
+
+ACPI_STATUS
+AcpiExWriteWithUpdateRule (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT64 Mask,
+ UINT64 FieldValue,
+ UINT32 FieldDatumByteOffset);
+
+void
+AcpiExGetBufferDatum(
+ UINT64 *Datum,
+ void *Buffer,
+ UINT32 BufferLength,
+ UINT32 ByteGranularity,
+ UINT32 BufferOffset);
+
+void
+AcpiExSetBufferDatum (
+ UINT64 MergedDatum,
+ void *Buffer,
+ UINT32 BufferLength,
+ UINT32 ByteGranularity,
+ UINT32 BufferOffset);
+
+ACPI_STATUS
+AcpiExReadDataFromField (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **RetBufferDesc);
+
+ACPI_STATUS
+AcpiExWriteDataToField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ResultDesc);
+
+
+/*
+ * exfldio - low level field I/O
+ */
+ACPI_STATUS
+AcpiExExtractFromField (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ void *Buffer,
+ UINT32 BufferLength);
+
+ACPI_STATUS
+AcpiExInsertIntoField (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ void *Buffer,
+ UINT32 BufferLength);
+
+ACPI_STATUS
+AcpiExAccessRegion (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset,
+ UINT64 *Value,
+ UINT32 ReadWrite);
+
+
+/*
+ * exmisc - misc support routines
+ */
+ACPI_STATUS
+AcpiExGetObjectReference (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT **ReturnDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExConcatTemplate (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc2,
+ ACPI_OPERAND_OBJECT **ActualReturnDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExDoConcatenate (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc2,
+ ACPI_OPERAND_OBJECT **ActualReturnDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExDoLogicalNumericOp (
+ UINT16 Opcode,
+ UINT64 Integer0,
+ UINT64 Integer1,
+ BOOLEAN *LogicalResult);
+
+ACPI_STATUS
+AcpiExDoLogicalOp (
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT *Operand0,
+ ACPI_OPERAND_OBJECT *Operand1,
+ BOOLEAN *LogicalResult);
+
+UINT64
+AcpiExDoMathOp (
+ UINT16 Opcode,
+ UINT64 Operand0,
+ UINT64 Operand1);
+
+ACPI_STATUS
+AcpiExCreateMutex (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreateProcessor (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreatePowerResource (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreateRegion (
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ UINT8 RegionSpace,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreateEvent (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreateAlias (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExCreateMethod (
+ UINT8 *AmlStart,
+ UINT32 AmlLength,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exconfig - dynamic table load/unload
+ */
+ACPI_STATUS
+AcpiExLoadOp (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_OPERAND_OBJECT *Target,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExLoadTableOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **ReturnDesc);
+
+ACPI_STATUS
+AcpiExUnloadTable (
+ ACPI_OPERAND_OBJECT *DdbHandle);
+
+
+/*
+ * exmutex - mutex support
+ */
+ACPI_STATUS
+AcpiExAcquireMutex (
+ ACPI_OPERAND_OBJECT *TimeDesc,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExAcquireMutexObject (
+ UINT16 Timeout,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_THREAD_ID ThreadId);
+
+ACPI_STATUS
+AcpiExReleaseMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExReleaseMutexObject (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+void
+AcpiExReleaseAllMutexes (
+ ACPI_THREAD_STATE *Thread);
+
+void
+AcpiExUnlinkMutex (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+
+/*
+ * exprep - ACPI AML execution - prep utilities
+ */
+ACPI_STATUS
+AcpiExPrepCommonFieldObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 FieldFlags,
+ UINT8 FieldAttribute,
+ UINT32 FieldBitPosition,
+ UINT32 FieldBitLength);
+
+ACPI_STATUS
+AcpiExPrepFieldValue (
+ ACPI_CREATE_FIELD_INFO *Info);
+
+
+/*
+ * exsystem - Interface to OS services
+ */
+ACPI_STATUS
+AcpiExSystemDoNotifyOp (
+ ACPI_OPERAND_OBJECT *Value,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiExSystemDoSleep(
+ UINT64 Time);
+
+ACPI_STATUS
+AcpiExSystemDoStall (
+ UINT32 Time);
+
+ACPI_STATUS
+AcpiExSystemSignalEvent(
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiExSystemWaitEvent(
+ ACPI_OPERAND_OBJECT *Time,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiExSystemResetEvent(
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiExSystemWaitSemaphore (
+ ACPI_SEMAPHORE Semaphore,
+ UINT16 Timeout);
+
+ACPI_STATUS
+AcpiExSystemWaitMutex (
+ ACPI_MUTEX Mutex,
+ UINT16 Timeout);
+
+/*
+ * exoparg1 - ACPI AML execution, 1 operand
+ */
+ACPI_STATUS
+AcpiExOpcode_0A_0T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_1A_0T_0R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_1A_0T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_1A_1T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_1A_1T_0R (
+ ACPI_WALK_STATE *WalkState);
+
+/*
+ * exoparg2 - ACPI AML execution, 2 operands
+ */
+ACPI_STATUS
+AcpiExOpcode_2A_0T_0R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_2A_0T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_2A_1T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_2A_2T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exoparg3 - ACPI AML execution, 3 operands
+ */
+ACPI_STATUS
+AcpiExOpcode_3A_0T_0R (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExOpcode_3A_1T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exoparg6 - ACPI AML execution, 6 operands
+ */
+ACPI_STATUS
+AcpiExOpcode_6A_0T_1R (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exresolv - Object resolution and get value functions
+ */
+ACPI_STATUS
+AcpiExResolveToValue (
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExResolveMultiple (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *Operand,
+ ACPI_OBJECT_TYPE *ReturnType,
+ ACPI_OPERAND_OBJECT **ReturnDesc);
+
+
+/*
+ * exresnte - resolve namespace node
+ */
+ACPI_STATUS
+AcpiExResolveNodeToValue (
+ ACPI_NAMESPACE_NODE **StackPtr,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exresop - resolve operand to value
+ */
+ACPI_STATUS
+AcpiExResolveOperands (
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT **StackPtr,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exdump - Interpreter debug output routines
+ */
+void
+AcpiExDumpOperand (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Depth);
+
+void
+AcpiExDumpOperands (
+ ACPI_OPERAND_OBJECT **Operands,
+ const char *OpcodeName,
+ UINT32 NumOpcodes);
+
+void
+AcpiExDumpObjectDescriptor (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT32 Flags);
+
+void
+AcpiExDumpNamespaceNode (
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 Flags);
+
+
+/*
+ * exnames - AML namestring support
+ */
+ACPI_STATUS
+AcpiExGetNameString (
+ ACPI_OBJECT_TYPE DataType,
+ UINT8 *InAmlAddress,
+ char **OutNameString,
+ UINT32 *OutNameLength);
+
+
+/*
+ * exstore - Object store support
+ */
+ACPI_STATUS
+AcpiExStore (
+ ACPI_OPERAND_OBJECT *ValDesc,
+ ACPI_OPERAND_OBJECT *DestDesc,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExStoreObjectToNode (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_WALK_STATE *WalkState,
+ UINT8 ImplicitConversion);
+
+#define ACPI_IMPLICIT_CONVERSION TRUE
+#define ACPI_NO_IMPLICIT_CONVERSION FALSE
+
+
+/*
+ * exstoren - resolve/store object
+ */
+ACPI_STATUS
+AcpiExResolveObject (
+ ACPI_OPERAND_OBJECT **SourceDescPtr,
+ ACPI_OBJECT_TYPE TargetType,
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiExStoreObjectToObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *DestDesc,
+ ACPI_OPERAND_OBJECT **NewDesc,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * exstorob - store object - buffer/string
+ */
+ACPI_STATUS
+AcpiExStoreBufferToBuffer (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc);
+
+ACPI_STATUS
+AcpiExStoreStringToString (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc);
+
+
+/*
+ * excopy - object copy
+ */
+ACPI_STATUS
+AcpiExCopyIntegerToIndexField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc);
+
+ACPI_STATUS
+AcpiExCopyIntegerToBankField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc);
+
+ACPI_STATUS
+AcpiExCopyDataToNamedField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_NAMESPACE_NODE *Node);
+
+ACPI_STATUS
+AcpiExCopyIntegerToBufferField (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT *TargetDesc);
+
+
+/*
+ * exutils - interpreter/scanner utilities
+ */
+void
+AcpiExEnterInterpreter (
+ void);
+
+void
+AcpiExExitInterpreter (
+ void);
+
+BOOLEAN
+AcpiExTruncateFor32bitTable (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+void
+AcpiExAcquireGlobalLock (
+ UINT32 Rule);
+
+void
+AcpiExReleaseGlobalLock (
+ UINT32 Rule);
+
+void
+AcpiExEisaIdToString (
+ char *Dest,
+ UINT64 CompressedId);
+
+void
+AcpiExIntegerToString (
+ char *Dest,
+ UINT64 Value);
+
+void
+AcpiExPciClsToString (
+ char *Dest,
+ UINT8 ClassCode[3]);
+
+BOOLEAN
+AcpiIsValidSpaceId (
+ UINT8 SpaceId);
+
+
+/*
+ * exregion - default OpRegion handlers
+ */
+ACPI_STATUS
+AcpiExSystemMemorySpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExSystemIoSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExPciConfigSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExCmosSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExPciBarSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExEmbeddedControllerSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+ACPI_STATUS
+AcpiExSmBusSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+
+ACPI_STATUS
+AcpiExDataTableSpaceHandler (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+#endif /* __INTERP_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/aclocal.h b/usr/src/boot/sys/contrib/dev/acpica/include/aclocal.h
new file mode 100644
index 0000000000..ea3d21924d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/aclocal.h
@@ -0,0 +1,1415 @@
+/******************************************************************************
+ *
+ * Name: aclocal.h - Internal data types used across the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACLOCAL_H__
+#define __ACLOCAL_H__
+
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+#define ACPI_SERIALIZED 0xFF
+
+typedef UINT32 ACPI_MUTEX_HANDLE;
+#define ACPI_GLOBAL_LOCK (ACPI_SEMAPHORE) (-1)
+
+/* Total number of aml opcodes defined */
+
+#define AML_NUM_OPCODES 0x82
+
+
+/* Forward declarations */
+
+struct acpi_walk_state;
+struct acpi_obj_mutex;
+union acpi_parse_object;
+
+
+/*****************************************************************************
+ *
+ * Mutex typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/*
+ * Predefined handles for the mutex objects used within the subsystem
+ * All mutex objects are automatically created by AcpiUtMutexInitialize.
+ *
+ * The acquire/release ordering protocol is implied via this list. Mutexes
+ * with a lower value must be acquired before mutexes with a higher value.
+ *
+ * NOTE: any changes here must be reflected in the AcpiGbl_MutexNames
+ * table below also!
+ */
+#define ACPI_MTX_INTERPRETER 0 /* AML Interpreter, main lock */
+#define ACPI_MTX_NAMESPACE 1 /* ACPI Namespace */
+#define ACPI_MTX_TABLES 2 /* Data for ACPI tables */
+#define ACPI_MTX_EVENTS 3 /* Data for ACPI events */
+#define ACPI_MTX_CACHES 4 /* Internal caches, general purposes */
+#define ACPI_MTX_MEMORY 5 /* Debug memory tracking lists */
+#define ACPI_MTX_DEBUG_CMD_COMPLETE 6 /* AML debugger */
+#define ACPI_MTX_DEBUG_CMD_READY 7 /* AML debugger */
+
+#define ACPI_MAX_MUTEX 7
+#define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1
+
+
+/* Lock structure for reader/writer interfaces */
+
+typedef struct acpi_rw_lock
+{
+ ACPI_MUTEX WriterMutex;
+ ACPI_MUTEX ReaderMutex;
+ UINT32 NumReaders;
+
+} ACPI_RW_LOCK;
+
+
+/*
+ * Predefined handles for spinlocks used within the subsystem.
+ * These spinlocks are created by AcpiUtMutexInitialize
+ */
+#define ACPI_LOCK_GPES 0
+#define ACPI_LOCK_HARDWARE 1
+
+#define ACPI_MAX_LOCK 1
+#define ACPI_NUM_LOCK ACPI_MAX_LOCK+1
+
+
+/* This Thread ID means that the mutex is not in use (unlocked) */
+
+#define ACPI_MUTEX_NOT_ACQUIRED (ACPI_THREAD_ID) -1
+
+/* Table for the global mutexes */
+
+typedef struct acpi_mutex_info
+{
+ ACPI_MUTEX Mutex;
+ UINT32 UseCount;
+ ACPI_THREAD_ID ThreadId;
+
+} ACPI_MUTEX_INFO;
+
+
+/* Lock flag parameter for various interfaces */
+
+#define ACPI_MTX_DO_NOT_LOCK 0
+#define ACPI_MTX_LOCK 1
+
+
+/* Field access granularities */
+
+#define ACPI_FIELD_BYTE_GRANULARITY 1
+#define ACPI_FIELD_WORD_GRANULARITY 2
+#define ACPI_FIELD_DWORD_GRANULARITY 4
+#define ACPI_FIELD_QWORD_GRANULARITY 8
+
+
+#define ACPI_ENTRY_NOT_FOUND NULL
+
+
+/*****************************************************************************
+ *
+ * Namespace typedefs and structs
+ *
+ ****************************************************************************/
+
+/* Operational modes of the AML interpreter/scanner */
+
+typedef enum
+{
+ ACPI_IMODE_LOAD_PASS1 = 0x01,
+ ACPI_IMODE_LOAD_PASS2 = 0x02,
+ ACPI_IMODE_EXECUTE = 0x03
+
+} ACPI_INTERPRETER_MODE;
+
+
+/*
+ * The Namespace Node describes a named object that appears in the AML.
+ * DescriptorType is used to differentiate between internal descriptors.
+ *
+ * The node is optimized for both 32-bit and 64-bit platforms:
+ * 20 bytes for the 32-bit case, 32 bytes for the 64-bit case.
+ *
+ * Note: The DescriptorType and Type fields must appear in the identical
+ * position in both the ACPI_NAMESPACE_NODE and ACPI_OPERAND_OBJECT
+ * structures.
+ */
+typedef struct acpi_namespace_node
+{
+ union acpi_operand_object *Object; /* Interpreter object */
+ UINT8 DescriptorType; /* Differentiate object descriptor types */
+ UINT8 Type; /* ACPI Type associated with this name */
+ UINT8 Flags; /* Miscellaneous flags */
+ ACPI_OWNER_ID OwnerId; /* Node creator */
+ ACPI_NAME_UNION Name; /* ACPI Name, always 4 chars per ACPI spec */
+ struct acpi_namespace_node *Parent; /* Parent node */
+ struct acpi_namespace_node *Child; /* First child */
+ struct acpi_namespace_node *Peer; /* First peer */
+
+ /*
+ * The following fields are used by the ASL compiler and disassembler only
+ */
+#ifdef ACPI_LARGE_NAMESPACE_NODE
+ union acpi_parse_object *Op;
+ void *MethodLocals;
+ void *MethodArgs;
+ UINT32 Value;
+ UINT32 Length;
+ UINT8 ArgCount;
+
+#endif
+
+} ACPI_NAMESPACE_NODE;
+
+
+/* Namespace Node flags */
+
+#define ANOBJ_RESERVED 0x01 /* Available for use */
+#define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */
+#define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */
+#define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */
+#define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */
+#define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */
+#define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (InstallMethod) */
+
+#define ANOBJ_IS_EXTERNAL 0x08 /* iASL only: This object created via External() */
+#define ANOBJ_METHOD_NO_RETVAL 0x10 /* iASL only: Method has no return value */
+#define ANOBJ_METHOD_SOME_NO_RETVAL 0x20 /* iASL only: Method has at least one return value */
+#define ANOBJ_IS_REFERENCED 0x80 /* iASL only: Object was referenced */
+
+
+/* Internal ACPI table management - master table list */
+
+typedef struct acpi_table_list
+{
+ ACPI_TABLE_DESC *Tables; /* Table descriptor array */
+ UINT32 CurrentTableCount; /* Tables currently in the array */
+ UINT32 MaxTableCount; /* Max tables array will hold */
+ UINT8 Flags;
+
+} ACPI_TABLE_LIST;
+
+/* Flags for above */
+
+#define ACPI_ROOT_ORIGIN_UNKNOWN (0) /* ~ORIGIN_ALLOCATED */
+#define ACPI_ROOT_ORIGIN_ALLOCATED (1)
+#define ACPI_ROOT_ALLOW_RESIZE (2)
+
+
+/* Predefined table indexes */
+
+#define ACPI_INVALID_TABLE_INDEX (0xFFFFFFFF)
+
+
+typedef struct acpi_find_context
+{
+ char *SearchFor;
+ ACPI_HANDLE *List;
+ UINT32 *Count;
+
+} ACPI_FIND_CONTEXT;
+
+
+typedef struct acpi_ns_search_data
+{
+ ACPI_NAMESPACE_NODE *Node;
+
+} ACPI_NS_SEARCH_DATA;
+
+
+/* Object types used during package copies */
+
+#define ACPI_COPY_TYPE_SIMPLE 0
+#define ACPI_COPY_TYPE_PACKAGE 1
+
+
+/* Info structure used to convert external<->internal namestrings */
+
+typedef struct acpi_namestring_info
+{
+ const char *ExternalName;
+ const char *NextExternalChar;
+ char *InternalName;
+ UINT32 Length;
+ UINT32 NumSegments;
+ UINT32 NumCarats;
+ BOOLEAN FullyQualified;
+
+} ACPI_NAMESTRING_INFO;
+
+
+/* Field creation info */
+
+typedef struct acpi_create_field_info
+{
+ ACPI_NAMESPACE_NODE *RegionNode;
+ ACPI_NAMESPACE_NODE *FieldNode;
+ ACPI_NAMESPACE_NODE *RegisterNode;
+ ACPI_NAMESPACE_NODE *DataRegisterNode;
+ ACPI_NAMESPACE_NODE *ConnectionNode;
+ UINT8 *ResourceBuffer;
+ UINT32 BankValue;
+ UINT32 FieldBitPosition;
+ UINT32 FieldBitLength;
+ UINT16 ResourceLength;
+ UINT16 PinNumberIndex;
+ UINT8 FieldFlags;
+ UINT8 Attribute;
+ UINT8 FieldType;
+ UINT8 AccessLength;
+
+} ACPI_CREATE_FIELD_INFO;
+
+
+typedef
+ACPI_STATUS (*ACPI_INTERNAL_METHOD) (
+ struct acpi_walk_state *WalkState);
+
+
+/*
+ * Bitmapped ACPI types. Used internally only
+ */
+#define ACPI_BTYPE_ANY 0x00000000
+#define ACPI_BTYPE_INTEGER 0x00000001
+#define ACPI_BTYPE_STRING 0x00000002
+#define ACPI_BTYPE_BUFFER 0x00000004
+#define ACPI_BTYPE_PACKAGE 0x00000008
+#define ACPI_BTYPE_FIELD_UNIT 0x00000010
+#define ACPI_BTYPE_DEVICE 0x00000020
+#define ACPI_BTYPE_EVENT 0x00000040
+#define ACPI_BTYPE_METHOD 0x00000080
+#define ACPI_BTYPE_MUTEX 0x00000100
+#define ACPI_BTYPE_REGION 0x00000200
+#define ACPI_BTYPE_POWER 0x00000400
+#define ACPI_BTYPE_PROCESSOR 0x00000800
+#define ACPI_BTYPE_THERMAL 0x00001000
+#define ACPI_BTYPE_BUFFER_FIELD 0x00002000
+#define ACPI_BTYPE_DDB_HANDLE 0x00004000
+#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000
+#define ACPI_BTYPE_REFERENCE 0x00010000
+#define ACPI_BTYPE_RESOURCE 0x00020000
+
+#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
+
+#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE)
+#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
+#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */
+#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF
+
+#pragma pack(1)
+
+/*
+ * Information structure for ACPI predefined names.
+ * Each entry in the table contains the following items:
+ *
+ * Name - The ACPI reserved name
+ * ParamCount - Number of arguments to the method
+ * ExpectedReturnBtypes - Allowed type(s) for the return value
+ */
+typedef struct acpi_name_info
+{
+ char Name[ACPI_NAME_SIZE];
+ UINT16 ArgumentList;
+ UINT8 ExpectedBtypes;
+
+} ACPI_NAME_INFO;
+
+/*
+ * Secondary information structures for ACPI predefined objects that return
+ * package objects. This structure appears as the next entry in the table
+ * after the NAME_INFO structure above.
+ *
+ * The reason for this is to minimize the size of the predefined name table.
+ */
+
+/*
+ * Used for ACPI_PTYPE1_FIXED, ACPI_PTYPE1_VAR, ACPI_PTYPE2,
+ * ACPI_PTYPE2_MIN, ACPI_PTYPE2_PKG_COUNT, ACPI_PTYPE2_COUNT,
+ * ACPI_PTYPE2_FIX_VAR
+ */
+typedef struct acpi_package_info
+{
+ UINT8 Type;
+ UINT8 ObjectType1;
+ UINT8 Count1;
+ UINT8 ObjectType2;
+ UINT8 Count2;
+ UINT16 Reserved;
+
+} ACPI_PACKAGE_INFO;
+
+/* Used for ACPI_PTYPE2_FIXED */
+
+typedef struct acpi_package_info2
+{
+ UINT8 Type;
+ UINT8 Count;
+ UINT8 ObjectType[4];
+ UINT8 Reserved;
+
+} ACPI_PACKAGE_INFO2;
+
+/* Used for ACPI_PTYPE1_OPTION */
+
+typedef struct acpi_package_info3
+{
+ UINT8 Type;
+ UINT8 Count;
+ UINT8 ObjectType[2];
+ UINT8 TailObjectType;
+ UINT16 Reserved;
+
+} ACPI_PACKAGE_INFO3;
+
+typedef struct acpi_package_info4
+{
+ UINT8 Type;
+ UINT8 ObjectType1;
+ UINT8 Count1;
+ UINT8 SubObjectTypes;
+ UINT8 PkgCount;
+ UINT16 Reserved;
+
+} ACPI_PACKAGE_INFO4;
+
+typedef union acpi_predefined_info
+{
+ ACPI_NAME_INFO Info;
+ ACPI_PACKAGE_INFO RetInfo;
+ ACPI_PACKAGE_INFO2 RetInfo2;
+ ACPI_PACKAGE_INFO3 RetInfo3;
+ ACPI_PACKAGE_INFO4 RetInfo4;
+
+} ACPI_PREDEFINED_INFO;
+
+/* Reset to default packing */
+
+#pragma pack()
+
+
+/* Return object auto-repair info */
+
+typedef ACPI_STATUS (*ACPI_OBJECT_CONVERTER) (
+ union acpi_operand_object *OriginalObject,
+ union acpi_operand_object **ConvertedObject);
+
+typedef struct acpi_simple_repair_info
+{
+ char Name[ACPI_NAME_SIZE];
+ UINT32 UnexpectedBtypes;
+ UINT32 PackageIndex;
+ ACPI_OBJECT_CONVERTER ObjectConverter;
+
+} ACPI_SIMPLE_REPAIR_INFO;
+
+
+/*
+ * Bitmapped return value types
+ * Note: the actual data types must be contiguous, a loop in nspredef.c
+ * depends on this.
+ */
+#define ACPI_RTYPE_ANY 0x00
+#define ACPI_RTYPE_NONE 0x01
+#define ACPI_RTYPE_INTEGER 0x02
+#define ACPI_RTYPE_STRING 0x04
+#define ACPI_RTYPE_BUFFER 0x08
+#define ACPI_RTYPE_PACKAGE 0x10
+#define ACPI_RTYPE_REFERENCE 0x20
+#define ACPI_RTYPE_ALL 0x3F
+
+#define ACPI_NUM_RTYPES 5 /* Number of actual object types */
+
+
+/* Info for running the _REG methods */
+
+typedef struct acpi_reg_walk_info
+{
+ ACPI_ADR_SPACE_TYPE SpaceId;
+ UINT32 RegRunCount;
+
+} ACPI_REG_WALK_INFO;
+
+
+/*****************************************************************************
+ *
+ * Event typedefs and structs
+ *
+ ****************************************************************************/
+
+/* Dispatch info for each host-installed SCI handler */
+
+typedef struct acpi_sci_handler_info
+{
+ struct acpi_sci_handler_info *Next;
+ ACPI_SCI_HANDLER Address; /* Address of handler */
+ void *Context; /* Context to be passed to handler */
+
+} ACPI_SCI_HANDLER_INFO;
+
+/* Dispatch info for each GPE -- either a method or handler, cannot be both */
+
+typedef struct acpi_gpe_handler_info
+{
+ ACPI_GPE_HANDLER Address; /* Address of handler, if any */
+ void *Context; /* Context to be passed to handler */
+ ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level (saved) */
+ UINT8 OriginalFlags; /* Original (pre-handler) GPE info */
+ BOOLEAN OriginallyEnabled; /* True if GPE was originally enabled */
+
+} ACPI_GPE_HANDLER_INFO;
+
+/* Notify info for implicit notify, multiple device objects */
+
+typedef struct acpi_gpe_notify_info
+{
+ ACPI_NAMESPACE_NODE *DeviceNode; /* Device to be notified */
+ struct acpi_gpe_notify_info *Next;
+
+} ACPI_GPE_NOTIFY_INFO;
+
+/*
+ * GPE dispatch info. At any time, the GPE can have at most one type
+ * of dispatch - Method, Handler, or Implicit Notify.
+ */
+typedef union acpi_gpe_dispatch_info
+{
+ ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */
+ ACPI_GPE_HANDLER_INFO *Handler; /* Installed GPE handler */
+ ACPI_GPE_NOTIFY_INFO *NotifyList; /* List of _PRW devices for implicit notifies */
+
+} ACPI_GPE_DISPATCH_INFO;
+
+/*
+ * Information about a GPE, one per each GPE in an array.
+ * NOTE: Important to keep this struct as small as possible.
+ */
+typedef struct acpi_gpe_event_info
+{
+ union acpi_gpe_dispatch_info Dispatch; /* Either Method, Handler, or NotifyList */
+ struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */
+ UINT8 Flags; /* Misc info about this GPE */
+ UINT8 GpeNumber; /* This GPE */
+ UINT8 RuntimeCount; /* References to a run GPE */
+
+} ACPI_GPE_EVENT_INFO;
+
+/* Information about a GPE register pair, one per each status/enable pair in an array */
+
+typedef struct acpi_gpe_register_info
+{
+ ACPI_GENERIC_ADDRESS StatusAddress; /* Address of status reg */
+ ACPI_GENERIC_ADDRESS EnableAddress; /* Address of enable reg */
+ UINT16 BaseGpeNumber; /* Base GPE number for this register */
+ UINT8 EnableForWake; /* GPEs to keep enabled when sleeping */
+ UINT8 EnableForRun; /* GPEs to keep enabled when running */
+ UINT8 EnableMask; /* Current mask of enabled GPEs */
+
+} ACPI_GPE_REGISTER_INFO;
+
+/*
+ * Information about a GPE register block, one per each installed block --
+ * GPE0, GPE1, and one per each installed GPE Block Device.
+ */
+typedef struct acpi_gpe_block_info
+{
+ ACPI_NAMESPACE_NODE *Node;
+ struct acpi_gpe_block_info *Previous;
+ struct acpi_gpe_block_info *Next;
+ struct acpi_gpe_xrupt_info *XruptBlock; /* Backpointer to interrupt block */
+ ACPI_GPE_REGISTER_INFO *RegisterInfo; /* One per GPE register pair */
+ ACPI_GPE_EVENT_INFO *EventInfo; /* One for each GPE */
+ UINT64 Address; /* Base address of the block */
+ UINT32 RegisterCount; /* Number of register pairs in block */
+ UINT16 GpeCount; /* Number of individual GPEs in block */
+ UINT16 BlockBaseNumber;/* Base GPE number for this block */
+ UINT8 SpaceId;
+ BOOLEAN Initialized; /* TRUE if this block is initialized */
+
+} ACPI_GPE_BLOCK_INFO;
+
+/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
+
+typedef struct acpi_gpe_xrupt_info
+{
+ struct acpi_gpe_xrupt_info *Previous;
+ struct acpi_gpe_xrupt_info *Next;
+ ACPI_GPE_BLOCK_INFO *GpeBlockListHead; /* List of GPE blocks for this xrupt */
+ UINT32 InterruptNumber; /* System interrupt number */
+
+} ACPI_GPE_XRUPT_INFO;
+
+typedef struct acpi_gpe_walk_info
+{
+ ACPI_NAMESPACE_NODE *GpeDevice;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ UINT16 Count;
+ ACPI_OWNER_ID OwnerId;
+ BOOLEAN ExecuteByOwnerId;
+
+} ACPI_GPE_WALK_INFO;
+
+typedef struct acpi_gpe_device_info
+{
+ UINT32 Index;
+ UINT32 NextBlockBaseIndex;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *GpeDevice;
+
+} ACPI_GPE_DEVICE_INFO;
+
+typedef ACPI_STATUS (*ACPI_GPE_CALLBACK) (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
+
+/* Information about each particular fixed event */
+
+typedef struct acpi_fixed_event_handler
+{
+ ACPI_EVENT_HANDLER Handler; /* Address of handler. */
+ void *Context; /* Context to be passed to handler */
+
+} ACPI_FIXED_EVENT_HANDLER;
+
+typedef struct acpi_fixed_event_info
+{
+ UINT8 StatusRegisterId;
+ UINT8 EnableRegisterId;
+ UINT16 StatusBitMask;
+ UINT16 EnableBitMask;
+
+} ACPI_FIXED_EVENT_INFO;
+
+/* Information used during field processing */
+
+typedef struct acpi_field_info
+{
+ UINT8 SkipField;
+ UINT8 FieldFlag;
+ UINT32 PkgLength;
+
+} ACPI_FIELD_INFO;
+
+
+/*****************************************************************************
+ *
+ * Generic "state" object for stacks
+ *
+ ****************************************************************************/
+
+#define ACPI_CONTROL_NORMAL 0xC0
+#define ACPI_CONTROL_CONDITIONAL_EXECUTING 0xC1
+#define ACPI_CONTROL_PREDICATE_EXECUTING 0xC2
+#define ACPI_CONTROL_PREDICATE_FALSE 0xC3
+#define ACPI_CONTROL_PREDICATE_TRUE 0xC4
+
+
+#define ACPI_STATE_COMMON \
+ void *Next; \
+ UINT8 DescriptorType; /* To differentiate various internal objs */\
+ UINT8 Flags; \
+ UINT16 Value; \
+ UINT16 State;
+
+ /* There are 2 bytes available here until the next natural alignment boundary */
+
+typedef struct acpi_common_state
+{
+ ACPI_STATE_COMMON
+} ACPI_COMMON_STATE;
+
+
+/*
+ * Update state - used to traverse complex objects such as packages
+ */
+typedef struct acpi_update_state
+{
+ ACPI_STATE_COMMON
+ union acpi_operand_object *Object;
+
+} ACPI_UPDATE_STATE;
+
+
+/*
+ * Pkg state - used to traverse nested package structures
+ */
+typedef struct acpi_pkg_state
+{
+ ACPI_STATE_COMMON
+ UINT16 Index;
+ union acpi_operand_object *SourceObject;
+ union acpi_operand_object *DestObject;
+ struct acpi_walk_state *WalkState;
+ void *ThisTargetObj;
+ UINT32 NumPackages;
+
+} ACPI_PKG_STATE;
+
+
+/*
+ * Control state - one per if/else and while constructs.
+ * Allows nesting of these constructs
+ */
+typedef struct acpi_control_state
+{
+ ACPI_STATE_COMMON
+ UINT16 Opcode;
+ union acpi_parse_object *PredicateOp;
+ UINT8 *AmlPredicateStart; /* Start of if/while predicate */
+ UINT8 *PackageEnd; /* End of if/while block */
+ UINT32 LoopCount; /* While() loop counter */
+
+} ACPI_CONTROL_STATE;
+
+
+/*
+ * Scope state - current scope during namespace lookups
+ */
+typedef struct acpi_scope_state
+{
+ ACPI_STATE_COMMON
+ ACPI_NAMESPACE_NODE *Node;
+
+} ACPI_SCOPE_STATE;
+
+
+typedef struct acpi_pscope_state
+{
+ ACPI_STATE_COMMON
+ UINT32 ArgCount; /* Number of fixed arguments */
+ union acpi_parse_object *Op; /* Current op being parsed */
+ UINT8 *ArgEnd; /* Current argument end */
+ UINT8 *PkgEnd; /* Current package end */
+ UINT32 ArgList; /* Next argument to parse */
+
+} ACPI_PSCOPE_STATE;
+
+
+/*
+ * Thread state - one per thread across multiple walk states. Multiple walk
+ * states are created when there are nested control methods executing.
+ */
+typedef struct acpi_thread_state
+{
+ ACPI_STATE_COMMON
+ UINT8 CurrentSyncLevel; /* Mutex Sync (nested acquire) level */
+ struct acpi_walk_state *WalkStateList; /* Head of list of WalkStates for this thread */
+ union acpi_operand_object *AcquiredMutexList; /* List of all currently acquired mutexes */
+ ACPI_THREAD_ID ThreadId; /* Running thread ID */
+
+} ACPI_THREAD_STATE;
+
+
+/*
+ * Result values - used to accumulate the results of nested
+ * AML arguments
+ */
+typedef struct acpi_result_values
+{
+ ACPI_STATE_COMMON
+ union acpi_operand_object *ObjDesc [ACPI_RESULTS_FRAME_OBJ_NUM];
+
+} ACPI_RESULT_VALUES;
+
+
+typedef
+ACPI_STATUS (*ACPI_PARSE_DOWNWARDS) (
+ struct acpi_walk_state *WalkState,
+ union acpi_parse_object **OutOp);
+
+typedef
+ACPI_STATUS (*ACPI_PARSE_UPWARDS) (
+ struct acpi_walk_state *WalkState);
+
+
+/* Global handlers for AML Notifies */
+
+typedef struct acpi_global_notify_handler
+{
+ ACPI_NOTIFY_HANDLER Handler;
+ void *Context;
+
+} ACPI_GLOBAL_NOTIFY_HANDLER;
+
+/*
+ * Notify info - used to pass info to the deferred notify
+ * handler/dispatcher.
+ */
+typedef struct acpi_notify_info
+{
+ ACPI_STATE_COMMON
+ UINT8 HandlerListId;
+ ACPI_NAMESPACE_NODE *Node;
+ union acpi_operand_object *HandlerListHead;
+ ACPI_GLOBAL_NOTIFY_HANDLER *Global;
+
+} ACPI_NOTIFY_INFO;
+
+
+/* Generic state is union of structs above */
+
+typedef union acpi_generic_state
+{
+ ACPI_COMMON_STATE Common;
+ ACPI_CONTROL_STATE Control;
+ ACPI_UPDATE_STATE Update;
+ ACPI_SCOPE_STATE Scope;
+ ACPI_PSCOPE_STATE ParseScope;
+ ACPI_PKG_STATE Pkg;
+ ACPI_THREAD_STATE Thread;
+ ACPI_RESULT_VALUES Results;
+ ACPI_NOTIFY_INFO Notify;
+
+} ACPI_GENERIC_STATE;
+
+
+/*****************************************************************************
+ *
+ * Interpreter typedefs and structs
+ *
+ ****************************************************************************/
+
+typedef
+ACPI_STATUS (*ACPI_EXECUTE_OP) (
+ struct acpi_walk_state *WalkState);
+
+/* Address Range info block */
+
+typedef struct acpi_address_range
+{
+ struct acpi_address_range *Next;
+ ACPI_NAMESPACE_NODE *RegionNode;
+ ACPI_PHYSICAL_ADDRESS StartAddress;
+ ACPI_PHYSICAL_ADDRESS EndAddress;
+
+} ACPI_ADDRESS_RANGE;
+
+
+/*****************************************************************************
+ *
+ * Parser typedefs and structs
+ *
+ ****************************************************************************/
+
+/*
+ * AML opcode, name, and argument layout
+ */
+typedef struct acpi_opcode_info
+{
+#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT)
+ char *Name; /* Opcode name (disassembler/debug only) */
+#endif
+ UINT32 ParseArgs; /* Grammar/Parse time arguments */
+ UINT32 RuntimeArgs; /* Interpret time arguments */
+ UINT16 Flags; /* Misc flags */
+ UINT8 ObjectType; /* Corresponding internal object type */
+ UINT8 Class; /* Opcode class */
+ UINT8 Type; /* Opcode type */
+
+} ACPI_OPCODE_INFO;
+
+/* Structure for Resource Tag information */
+
+typedef struct acpi_tag_info
+{
+ UINT32 BitOffset;
+ UINT32 BitLength;
+
+} ACPI_TAG_INFO;
+
+/* Value associated with the parse object */
+
+typedef union acpi_parse_value
+{
+ UINT64 Integer; /* Integer constant (Up to 64 bits) */
+ UINT32 Size; /* bytelist or field size */
+ char *String; /* NULL terminated string */
+ UINT8 *Buffer; /* buffer or string */
+ char *Name; /* NULL terminated string */
+ union acpi_parse_object *Arg; /* arguments and contained ops */
+ ACPI_TAG_INFO Tag; /* Resource descriptor tag info */
+
+} ACPI_PARSE_VALUE;
+
+
+#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT)
+#define ACPI_DISASM_ONLY_MEMBERS(a) a;
+#else
+#define ACPI_DISASM_ONLY_MEMBERS(a)
+#endif
+
+#define ACPI_PARSE_COMMON \
+ union acpi_parse_object *Parent; /* Parent op */\
+ UINT8 DescriptorType; /* To differentiate various internal objs */\
+ UINT8 Flags; /* Type of Op */\
+ UINT16 AmlOpcode; /* AML opcode */\
+ UINT8 *Aml; /* Address of declaration in AML */\
+ union acpi_parse_object *Next; /* Next op */\
+ ACPI_NAMESPACE_NODE *Node; /* For use by interpreter */\
+ ACPI_PARSE_VALUE Value; /* Value or args associated with the opcode */\
+ UINT8 ArgListLength; /* Number of elements in the arg list */\
+ ACPI_DISASM_ONLY_MEMBERS (\
+ UINT8 DisasmFlags; /* Used during AML disassembly */\
+ UINT8 DisasmOpcode; /* Subtype used for disassembly */\
+ char *OperatorSymbol;/* Used for C-style operator name strings */\
+ char AmlOpName[16]) /* Op name (debug only) */
+
+
+/* Flags for DisasmFlags field above */
+
+#define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */
+#define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */
+#define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */
+#define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */
+#define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */
+#define ACPI_DASM_UUID 0x05 /* Buffer is a UUID/GUID */
+#define ACPI_DASM_EISAID 0x06 /* Integer is an EISAID */
+#define ACPI_DASM_MATCHOP 0x07 /* Parent opcode is a Match() operator */
+#define ACPI_DASM_LNOT_PREFIX 0x08 /* Start of a LNotEqual (etc.) pair of opcodes */
+#define ACPI_DASM_LNOT_SUFFIX 0x09 /* End of a LNotEqual (etc.) pair of opcodes */
+#define ACPI_DASM_HID_STRING 0x0A /* String is a _HID or _CID */
+#define ACPI_DASM_IGNORE 0x0B /* Not used at this time */
+
+/*
+ * Generic operation (for example: If, While, Store)
+ */
+typedef struct acpi_parse_obj_common
+{
+ ACPI_PARSE_COMMON
+} ACPI_PARSE_OBJ_COMMON;
+
+
+/*
+ * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and OpRegions),
+ * and bytelists.
+ */
+typedef struct acpi_parse_obj_named
+{
+ ACPI_PARSE_COMMON
+ UINT8 *Path;
+ UINT8 *Data; /* AML body or bytelist data */
+ UINT32 Length; /* AML length */
+ UINT32 Name; /* 4-byte name or zero if no name */
+
+} ACPI_PARSE_OBJ_NAMED;
+
+
+/* This version is used by the iASL compiler only */
+
+#define ACPI_MAX_PARSEOP_NAME 20
+
+typedef struct acpi_parse_obj_asl
+{
+ ACPI_PARSE_COMMON
+ union acpi_parse_object *Child;
+ union acpi_parse_object *ParentMethod;
+ char *Filename;
+ char *ExternalName;
+ char *Namepath;
+ char NameSeg[4];
+ UINT32 ExtraValue;
+ UINT32 Column;
+ UINT32 LineNumber;
+ UINT32 LogicalLineNumber;
+ UINT32 LogicalByteOffset;
+ UINT32 EndLine;
+ UINT32 EndLogicalLine;
+ UINT32 AcpiBtype;
+ UINT32 AmlLength;
+ UINT32 AmlSubtreeLength;
+ UINT32 FinalAmlLength;
+ UINT32 FinalAmlOffset;
+ UINT32 CompileFlags;
+ UINT16 ParseOpcode;
+ UINT8 AmlOpcodeLength;
+ UINT8 AmlPkgLenBytes;
+ UINT8 Extra;
+ char ParseOpName[ACPI_MAX_PARSEOP_NAME];
+
+} ACPI_PARSE_OBJ_ASL;
+
+typedef union acpi_parse_object
+{
+ ACPI_PARSE_OBJ_COMMON Common;
+ ACPI_PARSE_OBJ_NAMED Named;
+ ACPI_PARSE_OBJ_ASL Asl;
+
+} ACPI_PARSE_OBJECT;
+
+
+/*
+ * Parse state - one state per parser invocation and each control
+ * method.
+ */
+typedef struct acpi_parse_state
+{
+ UINT8 *AmlStart; /* First AML byte */
+ UINT8 *Aml; /* Next AML byte */
+ UINT8 *AmlEnd; /* (last + 1) AML byte */
+ UINT8 *PkgStart; /* Current package begin */
+ UINT8 *PkgEnd; /* Current package end */
+ union acpi_parse_object *StartOp; /* Root of parse tree */
+ struct acpi_namespace_node *StartNode;
+ union acpi_generic_state *Scope; /* Current scope */
+ union acpi_parse_object *StartScope;
+ UINT32 AmlSize;
+
+} ACPI_PARSE_STATE;
+
+
+/* Parse object flags */
+
+#define ACPI_PARSEOP_GENERIC 0x01
+#define ACPI_PARSEOP_NAMED 0x02
+#define ACPI_PARSEOP_DEFERRED 0x04
+#define ACPI_PARSEOP_BYTELIST 0x08
+#define ACPI_PARSEOP_IN_STACK 0x10
+#define ACPI_PARSEOP_TARGET 0x20
+#define ACPI_PARSEOP_IN_CACHE 0x80
+
+/* Parse object DisasmFlags */
+
+#define ACPI_PARSEOP_IGNORE 0x01
+#define ACPI_PARSEOP_PARAMLIST 0x02
+#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04
+#define ACPI_PARSEOP_PREDEF_CHECKED 0x08
+#define ACPI_PARSEOP_SPECIAL 0x10
+#define ACPI_PARSEOP_COMPOUND 0x20
+#define ACPI_PARSEOP_ASSIGNMENT 0x40
+
+
+/*****************************************************************************
+ *
+ * Hardware (ACPI registers) and PNP
+ *
+ ****************************************************************************/
+
+typedef struct acpi_bit_register_info
+{
+ UINT8 ParentRegister;
+ UINT8 BitPosition;
+ UINT16 AccessBitMask;
+
+} ACPI_BIT_REGISTER_INFO;
+
+
+/*
+ * Some ACPI registers have bits that must be ignored -- meaning that they
+ * must be preserved.
+ */
+#define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS 0x2004 /* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+/*
+ * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the
+ * ACPI specification to be a "preserved" bit - "OSPM always preserves this
+ * bit position", section 4.7.3.2.1. However, on some machines the OS must
+ * write a one to this bit after resume for the machine to work properly.
+ * To enable this, we no longer attempt to preserve this bit. No machines
+ * are known to fail if the bit is not preserved. (May 2009)
+ */
+#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */
+#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS 0xFFFFFFFE /* All except bit 0 */
+
+/*
+ * Register IDs
+ * These are the full ACPI registers
+ */
+#define ACPI_REGISTER_PM1_STATUS 0x01
+#define ACPI_REGISTER_PM1_ENABLE 0x02
+#define ACPI_REGISTER_PM1_CONTROL 0x03
+#define ACPI_REGISTER_PM2_CONTROL 0x04
+#define ACPI_REGISTER_PM_TIMER 0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK 0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x07
+
+
+/* Masks used to access the BitRegisters */
+
+#define ACPI_BITMASK_TIMER_STATUS 0x0001
+#define ACPI_BITMASK_BUS_MASTER_STATUS 0x0010
+#define ACPI_BITMASK_GLOBAL_LOCK_STATUS 0x0020
+#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100
+#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200
+#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400
+#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
+#define ACPI_BITMASK_WAKE_STATUS 0x8000
+
+#define ACPI_BITMASK_ALL_FIXED_STATUS (\
+ ACPI_BITMASK_TIMER_STATUS | \
+ ACPI_BITMASK_BUS_MASTER_STATUS | \
+ ACPI_BITMASK_GLOBAL_LOCK_STATUS | \
+ ACPI_BITMASK_POWER_BUTTON_STATUS | \
+ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
+ ACPI_BITMASK_RT_CLOCK_STATUS | \
+ ACPI_BITMASK_PCIEXP_WAKE_STATUS | \
+ ACPI_BITMASK_WAKE_STATUS)
+
+#define ACPI_BITMASK_TIMER_ENABLE 0x0001
+#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE 0x0020
+#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100
+#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200
+#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400
+#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
+
+#define ACPI_BITMASK_SCI_ENABLE 0x0001
+#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
+#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004
+#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
+#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
+
+#define ACPI_BITMASK_ARB_DISABLE 0x0001
+
+
+/* Raw bit position of each BitRegister */
+
+#define ACPI_BITPOSITION_TIMER_STATUS 0x00
+#define ACPI_BITPOSITION_BUS_MASTER_STATUS 0x04
+#define ACPI_BITPOSITION_GLOBAL_LOCK_STATUS 0x05
+#define ACPI_BITPOSITION_POWER_BUTTON_STATUS 0x08
+#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS 0x09
+#define ACPI_BITPOSITION_RT_CLOCK_STATUS 0x0A
+#define ACPI_BITPOSITION_PCIEXP_WAKE_STATUS 0x0E /* ACPI 3.0 */
+#define ACPI_BITPOSITION_WAKE_STATUS 0x0F
+
+#define ACPI_BITPOSITION_TIMER_ENABLE 0x00
+#define ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE 0x05
+#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE 0x08
+#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE 0x09
+#define ACPI_BITPOSITION_RT_CLOCK_ENABLE 0x0A
+#define ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE 0x0E /* ACPI 3.0 */
+
+#define ACPI_BITPOSITION_SCI_ENABLE 0x00
+#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01
+#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02
+#define ACPI_BITPOSITION_SLEEP_TYPE 0x0A
+#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D
+
+#define ACPI_BITPOSITION_ARB_DISABLE 0x00
+
+
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_ALWAYS_ILLEGAL 0x00
+
+typedef struct acpi_interface_info
+{
+ char *Name;
+ struct acpi_interface_info *Next;
+ UINT8 Flags;
+ UINT8 Value;
+
+} ACPI_INTERFACE_INFO;
+
+#define ACPI_OSI_INVALID 0x01
+#define ACPI_OSI_DYNAMIC 0x02
+#define ACPI_OSI_FEATURE 0x04
+#define ACPI_OSI_DEFAULT_INVALID 0x08
+#define ACPI_OSI_OPTIONAL_FEATURE (ACPI_OSI_FEATURE | ACPI_OSI_DEFAULT_INVALID | ACPI_OSI_INVALID)
+
+typedef struct acpi_port_info
+{
+ char *Name;
+ UINT16 Start;
+ UINT16 End;
+ UINT8 OsiDependency;
+
+} ACPI_PORT_INFO;
+
+
+/*****************************************************************************
+ *
+ * Resource descriptors
+ *
+ ****************************************************************************/
+
+/* ResourceType values */
+
+#define ACPI_ADDRESS_TYPE_MEMORY_RANGE 0
+#define ACPI_ADDRESS_TYPE_IO_RANGE 1
+#define ACPI_ADDRESS_TYPE_BUS_NUMBER_RANGE 2
+
+/* Resource descriptor types and masks */
+
+#define ACPI_RESOURCE_NAME_LARGE 0x80
+#define ACPI_RESOURCE_NAME_SMALL 0x00
+
+#define ACPI_RESOURCE_NAME_SMALL_MASK 0x78 /* Bits 6:3 contain the type */
+#define ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK 0x07 /* Bits 2:0 contain the length */
+#define ACPI_RESOURCE_NAME_LARGE_MASK 0x7F /* Bits 6:0 contain the type */
+
+
+/*
+ * Small resource descriptor "names" as defined by the ACPI specification.
+ * Note: Bits 2:0 are used for the descriptor length
+ */
+#define ACPI_RESOURCE_NAME_IRQ 0x20
+#define ACPI_RESOURCE_NAME_DMA 0x28
+#define ACPI_RESOURCE_NAME_START_DEPENDENT 0x30
+#define ACPI_RESOURCE_NAME_END_DEPENDENT 0x38
+#define ACPI_RESOURCE_NAME_IO 0x40
+#define ACPI_RESOURCE_NAME_FIXED_IO 0x48
+#define ACPI_RESOURCE_NAME_FIXED_DMA 0x50
+#define ACPI_RESOURCE_NAME_RESERVED_S2 0x58
+#define ACPI_RESOURCE_NAME_RESERVED_S3 0x60
+#define ACPI_RESOURCE_NAME_RESERVED_S4 0x68
+#define ACPI_RESOURCE_NAME_VENDOR_SMALL 0x70
+#define ACPI_RESOURCE_NAME_END_TAG 0x78
+
+/*
+ * Large resource descriptor "names" as defined by the ACPI specification.
+ * Note: includes the Large Descriptor bit in bit[7]
+ */
+#define ACPI_RESOURCE_NAME_MEMORY24 0x81
+#define ACPI_RESOURCE_NAME_GENERIC_REGISTER 0x82
+#define ACPI_RESOURCE_NAME_RESERVED_L1 0x83
+#define ACPI_RESOURCE_NAME_VENDOR_LARGE 0x84
+#define ACPI_RESOURCE_NAME_MEMORY32 0x85
+#define ACPI_RESOURCE_NAME_FIXED_MEMORY32 0x86
+#define ACPI_RESOURCE_NAME_ADDRESS32 0x87
+#define ACPI_RESOURCE_NAME_ADDRESS16 0x88
+#define ACPI_RESOURCE_NAME_EXTENDED_IRQ 0x89
+#define ACPI_RESOURCE_NAME_ADDRESS64 0x8A
+#define ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 0x8B
+#define ACPI_RESOURCE_NAME_GPIO 0x8C
+#define ACPI_RESOURCE_NAME_SERIAL_BUS 0x8E
+#define ACPI_RESOURCE_NAME_LARGE_MAX 0x8E
+
+
+/*****************************************************************************
+ *
+ * Miscellaneous
+ *
+ ****************************************************************************/
+
+#define ACPI_ASCII_ZERO 0x30
+
+
+/*****************************************************************************
+ *
+ * Disassembler
+ *
+ ****************************************************************************/
+
+typedef struct acpi_external_list
+{
+ char *Path;
+ char *InternalPath;
+ struct acpi_external_list *Next;
+ UINT32 Value;
+ UINT16 Length;
+ UINT16 Flags;
+ UINT8 Type;
+
+} ACPI_EXTERNAL_LIST;
+
+/* Values for Flags field above */
+
+#define ACPI_EXT_RESOLVED_REFERENCE 0x01 /* Object was resolved during cross ref */
+#define ACPI_EXT_ORIGIN_FROM_FILE 0x02 /* External came from a file */
+#define ACPI_EXT_INTERNAL_PATH_ALLOCATED 0x04 /* Deallocate internal path on completion */
+#define ACPI_EXT_EXTERNAL_EMITTED 0x08 /* External() statement has been emitted */
+
+
+typedef struct acpi_external_file
+{
+ char *Path;
+ struct acpi_external_file *Next;
+
+} ACPI_EXTERNAL_FILE;
+
+
+/*****************************************************************************
+ *
+ * Debugger
+ *
+ ****************************************************************************/
+
+typedef struct acpi_db_method_info
+{
+ ACPI_HANDLE Method;
+ ACPI_HANDLE MainThreadGate;
+ ACPI_HANDLE ThreadCompleteGate;
+ ACPI_HANDLE InfoGate;
+ ACPI_THREAD_ID *Threads;
+ UINT32 NumThreads;
+ UINT32 NumCreated;
+ UINT32 NumCompleted;
+
+ char *Name;
+ UINT32 Flags;
+ UINT32 NumLoops;
+ char Pathname[ACPI_DB_LINE_BUFFER_SIZE];
+ char **Args;
+ ACPI_OBJECT_TYPE *Types;
+
+ /*
+ * Arguments to be passed to method for the command
+ * Threads -
+ * the Number of threads, ID of current thread and
+ * Index of current thread inside all them created.
+ */
+ char InitArgs;
+#ifdef ACPI_DEBUGGER
+ ACPI_OBJECT_TYPE ArgTypes[4];
+#endif
+ char *Arguments[4];
+ char NumThreadsStr[11];
+ char IdOfThreadStr[11];
+ char IndexOfThreadStr[11];
+
+} ACPI_DB_METHOD_INFO;
+
+typedef struct acpi_integrity_info
+{
+ UINT32 Nodes;
+ UINT32 Objects;
+
+} ACPI_INTEGRITY_INFO;
+
+
+#define ACPI_DB_DISABLE_OUTPUT 0x00
+#define ACPI_DB_REDIRECTABLE_OUTPUT 0x01
+#define ACPI_DB_CONSOLE_OUTPUT 0x02
+#define ACPI_DB_DUPLICATE_OUTPUT 0x03
+
+
+typedef struct acpi_object_info
+{
+ UINT32 Types[ACPI_TOTAL_TYPES];
+
+} ACPI_OBJECT_INFO;
+
+
+/*****************************************************************************
+ *
+ * Debug
+ *
+ ****************************************************************************/
+
+/* Entry for a memory allocation (debug only) */
+
+#define ACPI_MEM_MALLOC 0
+#define ACPI_MEM_CALLOC 1
+#define ACPI_MAX_MODULE_NAME 16
+
+#define ACPI_COMMON_DEBUG_MEM_HEADER \
+ struct acpi_debug_mem_block *Previous; \
+ struct acpi_debug_mem_block *Next; \
+ UINT32 Size; \
+ UINT32 Component; \
+ UINT32 Line; \
+ char Module[ACPI_MAX_MODULE_NAME]; \
+ UINT8 AllocType;
+
+typedef struct acpi_debug_mem_header
+{
+ ACPI_COMMON_DEBUG_MEM_HEADER
+
+} ACPI_DEBUG_MEM_HEADER;
+
+typedef struct acpi_debug_mem_block
+{
+ ACPI_COMMON_DEBUG_MEM_HEADER
+ UINT64 UserSpace;
+
+} ACPI_DEBUG_MEM_BLOCK;
+
+
+#define ACPI_MEM_LIST_GLOBAL 0
+#define ACPI_MEM_LIST_NSNODE 1
+#define ACPI_MEM_LIST_MAX 1
+#define ACPI_NUM_MEM_LISTS 2
+
+
+/*****************************************************************************
+ *
+ * Info/help support
+ *
+ ****************************************************************************/
+
+typedef struct ah_predefined_name
+{
+ char *Name;
+ char *Description;
+#ifndef ACPI_ASL_COMPILER
+ char *Action;
+#endif
+
+} AH_PREDEFINED_NAME;
+
+typedef struct ah_device_id
+{
+ char *Name;
+ char *Description;
+
+} AH_DEVICE_ID;
+
+typedef struct ah_uuid
+{
+ char *Description;
+ char *String;
+
+} AH_UUID;
+
+typedef struct ah_table
+{
+ char *Signature;
+ char *Description;
+
+} AH_TABLE;
+
+#endif /* __ACLOCAL_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acmacros.h b/usr/src/boot/sys/contrib/dev/acpica/include/acmacros.h
new file mode 100644
index 0000000000..48620fb470
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acmacros.h
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Name: acmacros.h - C macros for the entire subsystem.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACMACROS_H__
+#define __ACMACROS_H__
+
+
+/*
+ * Extract data using a pointer. Any more than a byte and we
+ * get into potential aligment issues -- see the STORE macros below.
+ * Use with care.
+ */
+#define ACPI_CAST8(ptr) ACPI_CAST_PTR (UINT8, (ptr))
+#define ACPI_CAST16(ptr) ACPI_CAST_PTR (UINT16, (ptr))
+#define ACPI_CAST32(ptr) ACPI_CAST_PTR (UINT32, (ptr))
+#define ACPI_CAST64(ptr) ACPI_CAST_PTR (UINT64, (ptr))
+#define ACPI_GET8(ptr) (*ACPI_CAST8 (ptr))
+#define ACPI_GET16(ptr) (*ACPI_CAST16 (ptr))
+#define ACPI_GET32(ptr) (*ACPI_CAST32 (ptr))
+#define ACPI_GET64(ptr) (*ACPI_CAST64 (ptr))
+#define ACPI_SET8(ptr, val) (*ACPI_CAST8 (ptr) = (UINT8) (val))
+#define ACPI_SET16(ptr, val) (*ACPI_CAST16 (ptr) = (UINT16) (val))
+#define ACPI_SET32(ptr, val) (*ACPI_CAST32 (ptr) = (UINT32) (val))
+#define ACPI_SET64(ptr, val) (*ACPI_CAST64 (ptr) = (UINT64) (val))
+
+/*
+ * printf() format helper. This macros is a workaround for the difficulties
+ * with emitting 64-bit integers and 64-bit pointers with the same code
+ * for both 32-bit and 64-bit hosts.
+ */
+#define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i), ACPI_LODWORD(i)
+
+
+/*
+ * Macros for moving data around to/from buffers that are possibly unaligned.
+ * If the hardware supports the transfer of unaligned data, just do the store.
+ * Otherwise, we have to move one byte at a time.
+ */
+#ifdef ACPI_BIG_ENDIAN
+/*
+ * Macros for big-endian machines
+ */
+
+/* These macros reverse the bytes during the move, converting little-endian to big endian */
+
+ /* Big Endian <== Little Endian */
+ /* Hi...Lo Lo...Hi */
+/* 16-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_16_TO_16(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[1];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[0];}
+
+#define ACPI_MOVE_16_TO_32(d, s) {(*(UINT32 *)(void *)(d))=0;\
+ ((UINT8 *)(void *)(d))[2] = ((UINT8 *)(void *)(s))[1];\
+ ((UINT8 *)(void *)(d))[3] = ((UINT8 *)(void *)(s))[0];}
+
+#define ACPI_MOVE_16_TO_64(d, s) {(*(UINT64 *)(void *)(d))=0;\
+ ((UINT8 *)(void *)(d))[6] = ((UINT8 *)(void *)(s))[1];\
+ ((UINT8 *)(void *)(d))[7] = ((UINT8 *)(void *)(s))[0];}
+
+/* 32-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_32_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+
+#define ACPI_MOVE_32_TO_32(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[3];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[2];\
+ (( UINT8 *)(void *)(d))[2] = ((UINT8 *)(void *)(s))[1];\
+ (( UINT8 *)(void *)(d))[3] = ((UINT8 *)(void *)(s))[0];}
+
+#define ACPI_MOVE_32_TO_64(d, s) {(*(UINT64 *)(void *)(d))=0;\
+ ((UINT8 *)(void *)(d))[4] = ((UINT8 *)(void *)(s))[3];\
+ ((UINT8 *)(void *)(d))[5] = ((UINT8 *)(void *)(s))[2];\
+ ((UINT8 *)(void *)(d))[6] = ((UINT8 *)(void *)(s))[1];\
+ ((UINT8 *)(void *)(d))[7] = ((UINT8 *)(void *)(s))[0];}
+
+/* 64-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_64_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+
+#define ACPI_MOVE_64_TO_32(d, s) ACPI_MOVE_32_TO_32(d, s) /* Truncate to 32 */
+
+#define ACPI_MOVE_64_TO_64(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[7];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[6];\
+ (( UINT8 *)(void *)(d))[2] = ((UINT8 *)(void *)(s))[5];\
+ (( UINT8 *)(void *)(d))[3] = ((UINT8 *)(void *)(s))[4];\
+ (( UINT8 *)(void *)(d))[4] = ((UINT8 *)(void *)(s))[3];\
+ (( UINT8 *)(void *)(d))[5] = ((UINT8 *)(void *)(s))[2];\
+ (( UINT8 *)(void *)(d))[6] = ((UINT8 *)(void *)(s))[1];\
+ (( UINT8 *)(void *)(d))[7] = ((UINT8 *)(void *)(s))[0];}
+#else
+/*
+ * Macros for little-endian machines
+ */
+
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+
+/* The hardware supports unaligned transfers, just do the little-endian move */
+
+/* 16-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_16_TO_16(d, s) *(UINT16 *)(void *)(d) = *(UINT16 *)(void *)(s)
+#define ACPI_MOVE_16_TO_32(d, s) *(UINT32 *)(void *)(d) = *(UINT16 *)(void *)(s)
+#define ACPI_MOVE_16_TO_64(d, s) *(UINT64 *)(void *)(d) = *(UINT16 *)(void *)(s)
+
+/* 32-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_32_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_32(d, s) *(UINT32 *)(void *)(d) = *(UINT32 *)(void *)(s)
+#define ACPI_MOVE_32_TO_64(d, s) *(UINT64 *)(void *)(d) = *(UINT32 *)(void *)(s)
+
+/* 64-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_64_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d, s) ACPI_MOVE_32_TO_32(d, s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_64(d, s) *(UINT64 *)(void *)(d) = *(UINT64 *)(void *)(s)
+
+#else
+/*
+ * The hardware does not support unaligned transfers. We must move the
+ * data one byte at a time. These macros work whether the source or
+ * the destination (or both) is/are unaligned. (Little-endian move)
+ */
+
+/* 16-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_16_TO_16(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[0];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[1];}
+
+#define ACPI_MOVE_16_TO_32(d, s) {(*(UINT32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);}
+#define ACPI_MOVE_16_TO_64(d, s) {(*(UINT64 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);}
+
+/* 32-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_32_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+
+#define ACPI_MOVE_32_TO_32(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[0];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[1];\
+ (( UINT8 *)(void *)(d))[2] = ((UINT8 *)(void *)(s))[2];\
+ (( UINT8 *)(void *)(d))[3] = ((UINT8 *)(void *)(s))[3];}
+
+#define ACPI_MOVE_32_TO_64(d, s) {(*(UINT64 *)(void *)(d)) = 0; ACPI_MOVE_32_TO_32(d, s);}
+
+/* 64-bit source, 16/32/64 destination */
+
+#define ACPI_MOVE_64_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d, s) ACPI_MOVE_32_TO_32(d, s) /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_64(d, s) {(( UINT8 *)(void *)(d))[0] = ((UINT8 *)(void *)(s))[0];\
+ (( UINT8 *)(void *)(d))[1] = ((UINT8 *)(void *)(s))[1];\
+ (( UINT8 *)(void *)(d))[2] = ((UINT8 *)(void *)(s))[2];\
+ (( UINT8 *)(void *)(d))[3] = ((UINT8 *)(void *)(s))[3];\
+ (( UINT8 *)(void *)(d))[4] = ((UINT8 *)(void *)(s))[4];\
+ (( UINT8 *)(void *)(d))[5] = ((UINT8 *)(void *)(s))[5];\
+ (( UINT8 *)(void *)(d))[6] = ((UINT8 *)(void *)(s))[6];\
+ (( UINT8 *)(void *)(d))[7] = ((UINT8 *)(void *)(s))[7];}
+#endif
+#endif
+
+
+/*
+ * Fast power-of-two math macros for non-optimized compilers
+ */
+#define _ACPI_DIV(value, PowerOf2) ((UINT32) ((value) >> (PowerOf2)))
+#define _ACPI_MUL(value, PowerOf2) ((UINT32) ((value) << (PowerOf2)))
+#define _ACPI_MOD(value, Divisor) ((UINT32) ((value) & ((Divisor) -1)))
+
+#define ACPI_DIV_2(a) _ACPI_DIV(a, 1)
+#define ACPI_MUL_2(a) _ACPI_MUL(a, 1)
+#define ACPI_MOD_2(a) _ACPI_MOD(a, 2)
+
+#define ACPI_DIV_4(a) _ACPI_DIV(a, 2)
+#define ACPI_MUL_4(a) _ACPI_MUL(a, 2)
+#define ACPI_MOD_4(a) _ACPI_MOD(a, 4)
+
+#define ACPI_DIV_8(a) _ACPI_DIV(a, 3)
+#define ACPI_MUL_8(a) _ACPI_MUL(a, 3)
+#define ACPI_MOD_8(a) _ACPI_MOD(a, 8)
+
+#define ACPI_DIV_16(a) _ACPI_DIV(a, 4)
+#define ACPI_MUL_16(a) _ACPI_MUL(a, 4)
+#define ACPI_MOD_16(a) _ACPI_MOD(a, 16)
+
+#define ACPI_DIV_32(a) _ACPI_DIV(a, 5)
+#define ACPI_MUL_32(a) _ACPI_MUL(a, 5)
+#define ACPI_MOD_32(a) _ACPI_MOD(a, 32)
+
+/* Test for ASCII character */
+
+#define ACPI_IS_ASCII(c) ((c) < 0x80)
+
+/* Signed integers */
+
+#define ACPI_SIGN_POSITIVE 0
+#define ACPI_SIGN_NEGATIVE 1
+
+
+/*
+ * Rounding macros (Power of two boundaries only)
+ */
+#define ACPI_ROUND_DOWN(value, boundary) (((ACPI_SIZE)(value)) & \
+ (~(((ACPI_SIZE) boundary)-1)))
+
+#define ACPI_ROUND_UP(value, boundary) ((((ACPI_SIZE)(value)) + \
+ (((ACPI_SIZE) boundary)-1)) & \
+ (~(((ACPI_SIZE) boundary)-1)))
+
+/* Note: sizeof(ACPI_SIZE) evaluates to either 4 or 8 (32- vs 64-bit mode) */
+
+#define ACPI_ROUND_DOWN_TO_32BIT(a) ACPI_ROUND_DOWN(a, 4)
+#define ACPI_ROUND_DOWN_TO_64BIT(a) ACPI_ROUND_DOWN(a, 8)
+#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a, sizeof(ACPI_SIZE))
+
+#define ACPI_ROUND_UP_TO_32BIT(a) ACPI_ROUND_UP(a, 4)
+#define ACPI_ROUND_UP_TO_64BIT(a) ACPI_ROUND_UP(a, 8)
+#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a, sizeof(ACPI_SIZE))
+
+#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
+#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))
+
+#define ACPI_ROUND_UP_TO_1K(a) (((a) + 1023) >> 10)
+
+/* Generic (non-power-of-two) rounding */
+
+#define ACPI_ROUND_UP_TO(value, boundary) (((value) + ((boundary)-1)) / (boundary))
+
+#define ACPI_IS_MISALIGNED(value) (((ACPI_SIZE) value) & (sizeof(ACPI_SIZE)-1))
+
+/*
+ * Bitmask creation
+ * Bit positions start at zero.
+ * MASK_BITS_ABOVE creates a mask starting AT the position and above
+ * MASK_BITS_BELOW creates a mask starting one bit BELOW the position
+ */
+#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_UINT64_MAX) << ((UINT32) (position))))
+#define ACPI_MASK_BITS_BELOW(position) ((ACPI_UINT64_MAX) << ((UINT32) (position)))
+
+/* Bitfields within ACPI registers */
+
+#define ACPI_REGISTER_PREPARE_BITS(Val, Pos, Mask) \
+ ((Val << Pos) & Mask)
+
+#define ACPI_REGISTER_INSERT_VALUE(Reg, Pos, Mask, Val) \
+ Reg = (Reg & (~(Mask))) | ACPI_REGISTER_PREPARE_BITS(Val, Pos, Mask)
+
+#define ACPI_INSERT_BITS(Target, Mask, Source) \
+ Target = ((Target & (~(Mask))) | (Source & Mask))
+
+/* Generic bitfield macros and masks */
+
+#define ACPI_GET_BITS(SourcePtr, Position, Mask) \
+ ((*SourcePtr >> Position) & Mask)
+
+#define ACPI_SET_BITS(TargetPtr, Position, Mask, Value) \
+ (*TargetPtr |= ((Value & Mask) << Position))
+
+#define ACPI_1BIT_MASK 0x00000001
+#define ACPI_2BIT_MASK 0x00000003
+#define ACPI_3BIT_MASK 0x00000007
+#define ACPI_4BIT_MASK 0x0000000F
+#define ACPI_5BIT_MASK 0x0000001F
+#define ACPI_6BIT_MASK 0x0000003F
+#define ACPI_7BIT_MASK 0x0000007F
+#define ACPI_8BIT_MASK 0x000000FF
+#define ACPI_16BIT_MASK 0x0000FFFF
+#define ACPI_24BIT_MASK 0x00FFFFFF
+
+/* Macros to extract flag bits from position zero */
+
+#define ACPI_GET_1BIT_FLAG(Value) ((Value) & ACPI_1BIT_MASK)
+#define ACPI_GET_2BIT_FLAG(Value) ((Value) & ACPI_2BIT_MASK)
+#define ACPI_GET_3BIT_FLAG(Value) ((Value) & ACPI_3BIT_MASK)
+#define ACPI_GET_4BIT_FLAG(Value) ((Value) & ACPI_4BIT_MASK)
+
+/* Macros to extract flag bits from position one and above */
+
+#define ACPI_EXTRACT_1BIT_FLAG(Field, Position) (ACPI_GET_1BIT_FLAG ((Field) >> Position))
+#define ACPI_EXTRACT_2BIT_FLAG(Field, Position) (ACPI_GET_2BIT_FLAG ((Field) >> Position))
+#define ACPI_EXTRACT_3BIT_FLAG(Field, Position) (ACPI_GET_3BIT_FLAG ((Field) >> Position))
+#define ACPI_EXTRACT_4BIT_FLAG(Field, Position) (ACPI_GET_4BIT_FLAG ((Field) >> Position))
+
+/* ACPI Pathname helpers */
+
+#define ACPI_IS_ROOT_PREFIX(c) ((c) == (UINT8) 0x5C) /* Backslash */
+#define ACPI_IS_PARENT_PREFIX(c) ((c) == (UINT8) 0x5E) /* Carat */
+#define ACPI_IS_PATH_SEPARATOR(c) ((c) == (UINT8) 0x2E) /* Period (dot) */
+
+/*
+ * An object of type ACPI_NAMESPACE_NODE can appear in some contexts
+ * where a pointer to an object of type ACPI_OPERAND_OBJECT can also
+ * appear. This macro is used to distinguish them.
+ *
+ * The "DescriptorType" field is the second field in both structures.
+ */
+#define ACPI_GET_DESCRIPTOR_PTR(d) (((ACPI_DESCRIPTOR *)(void *)(d))->Common.CommonPointer)
+#define ACPI_SET_DESCRIPTOR_PTR(d, p) (((ACPI_DESCRIPTOR *)(void *)(d))->Common.CommonPointer = (p))
+#define ACPI_GET_DESCRIPTOR_TYPE(d) (((ACPI_DESCRIPTOR *)(void *)(d))->Common.DescriptorType)
+#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((ACPI_DESCRIPTOR *)(void *)(d))->Common.DescriptorType = (t))
+
+/*
+ * Macros for the master AML opcode table
+ */
+#if defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+#define ACPI_OP(Name, PArgs, IArgs, ObjType, Class, Type, Flags) \
+ {Name, (UINT32)(PArgs), (UINT32)(IArgs), (UINT32)(Flags), ObjType, Class, Type}
+#else
+#define ACPI_OP(Name, PArgs, IArgs, ObjType, Class, Type, Flags) \
+ {(UINT32)(PArgs), (UINT32)(IArgs), (UINT32)(Flags), ObjType, Class, Type}
+#endif
+
+#define ARG_TYPE_WIDTH 5
+#define ARG_1(x) ((UINT32)(x))
+#define ARG_2(x) ((UINT32)(x) << (1 * ARG_TYPE_WIDTH))
+#define ARG_3(x) ((UINT32)(x) << (2 * ARG_TYPE_WIDTH))
+#define ARG_4(x) ((UINT32)(x) << (3 * ARG_TYPE_WIDTH))
+#define ARG_5(x) ((UINT32)(x) << (4 * ARG_TYPE_WIDTH))
+#define ARG_6(x) ((UINT32)(x) << (5 * ARG_TYPE_WIDTH))
+
+#define ARGI_LIST1(a) (ARG_1(a))
+#define ARGI_LIST2(a, b) (ARG_1(b)|ARG_2(a))
+#define ARGI_LIST3(a, b, c) (ARG_1(c)|ARG_2(b)|ARG_3(a))
+#define ARGI_LIST4(a, b, c, d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
+#define ARGI_LIST5(a, b, c, d, e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
+#define ARGI_LIST6(a, b, c, d, e, f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
+
+#define ARGP_LIST1(a) (ARG_1(a))
+#define ARGP_LIST2(a, b) (ARG_1(a)|ARG_2(b))
+#define ARGP_LIST3(a, b, c) (ARG_1(a)|ARG_2(b)|ARG_3(c))
+#define ARGP_LIST4(a, b, c, d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
+#define ARGP_LIST5(a, b, c, d, e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
+#define ARGP_LIST6(a, b, c, d, e, f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
+
+#define GET_CURRENT_ARG_TYPE(List) (List & ((UINT32) 0x1F))
+#define INCREMENT_ARG_LIST(List) (List >>= ((UINT32) ARG_TYPE_WIDTH))
+
+/*
+ * Ascii error messages can be configured out
+ */
+#ifndef ACPI_NO_ERROR_MESSAGES
+/*
+ * Error reporting. Callers module and line number are inserted by AE_INFO,
+ * the plist contains a set of parens to allow variable-length lists.
+ * These macros are used for both the debug and non-debug versions of the code.
+ */
+#define ACPI_ERROR_NAMESPACE(s, e) AcpiUtNamespaceError (AE_INFO, s, e);
+#define ACPI_ERROR_METHOD(s, n, p, e) AcpiUtMethodError (AE_INFO, s, n, p, e);
+#define ACPI_WARN_PREDEFINED(plist) AcpiUtPredefinedWarning plist
+#define ACPI_INFO_PREDEFINED(plist) AcpiUtPredefinedInfo plist
+#define ACPI_BIOS_ERROR_PREDEFINED(plist) AcpiUtPredefinedBiosError plist
+
+#else
+
+/* No error messages */
+
+#define ACPI_ERROR_NAMESPACE(s, e)
+#define ACPI_ERROR_METHOD(s, n, p, e)
+#define ACPI_WARN_PREDEFINED(plist)
+#define ACPI_INFO_PREDEFINED(plist)
+#define ACPI_BIOS_ERROR_PREDEFINED(plist)
+
+#endif /* ACPI_NO_ERROR_MESSAGES */
+
+#if (!ACPI_REDUCED_HARDWARE)
+#define ACPI_HW_OPTIONAL_FUNCTION(addr) addr
+#else
+#define ACPI_HW_OPTIONAL_FUNCTION(addr) NULL
+#endif
+
+
+/*
+ * Some code only gets executed when the debugger is built in.
+ * Note that this is entirely independent of whether the
+ * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
+ */
+#ifdef ACPI_DEBUGGER
+#define ACPI_DEBUGGER_EXEC(a) a
+#else
+#define ACPI_DEBUGGER_EXEC(a)
+#endif
+
+
+/*
+ * Macros used for ACPICA utilities only
+ */
+
+/* Generate a UUID */
+
+#define ACPI_INIT_UUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+ (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \
+ (b) & 0xFF, ((b) >> 8) & 0xFF, \
+ (c) & 0xFF, ((c) >> 8) & 0xFF, \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)
+
+#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))
+
+
+#endif /* ACMACROS_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acnames.h b/usr/src/boot/sys/contrib/dev/acpica/include/acnames.h
new file mode 100644
index 0000000000..6887d42c92
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acnames.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+ *
+ * Name: acnames.h - Global names and strings
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACNAMES_H__
+#define __ACNAMES_H__
+
+/* Method names - these methods can appear anywhere in the namespace */
+
+#define METHOD_NAME__ADR "_ADR"
+#define METHOD_NAME__AEI "_AEI"
+#define METHOD_NAME__BBN "_BBN"
+#define METHOD_NAME__CBA "_CBA"
+#define METHOD_NAME__CID "_CID"
+#define METHOD_NAME__CLS "_CLS"
+#define METHOD_NAME__CRS "_CRS"
+#define METHOD_NAME__DDN "_DDN"
+#define METHOD_NAME__HID "_HID"
+#define METHOD_NAME__INI "_INI"
+#define METHOD_NAME__PLD "_PLD"
+#define METHOD_NAME__DSD "_DSD"
+#define METHOD_NAME__PRS "_PRS"
+#define METHOD_NAME__PRT "_PRT"
+#define METHOD_NAME__PRW "_PRW"
+#define METHOD_NAME__PS0 "_PS0"
+#define METHOD_NAME__PS1 "_PS1"
+#define METHOD_NAME__PS2 "_PS2"
+#define METHOD_NAME__PS3 "_PS3"
+#define METHOD_NAME__REG "_REG"
+#define METHOD_NAME__SB_ "_SB_"
+#define METHOD_NAME__SEG "_SEG"
+#define METHOD_NAME__SRS "_SRS"
+#define METHOD_NAME__STA "_STA"
+#define METHOD_NAME__SUB "_SUB"
+#define METHOD_NAME__UID "_UID"
+
+/* Method names - these methods must appear at the namespace root */
+
+#define METHOD_PATHNAME__PTS "\\_PTS"
+#define METHOD_PATHNAME__SST "\\_SI._SST"
+#define METHOD_PATHNAME__WAK "\\_WAK"
+
+/* Definitions of the predefined namespace names */
+
+#define ACPI_UNKNOWN_NAME (UINT32) 0x3F3F3F3F /* Unknown name is "????" */
+#define ACPI_ROOT_NAME (UINT32) 0x5F5F5F5C /* Root name is "\___" */
+
+#define ACPI_PREFIX_MIXED (UINT32) 0x69706341 /* "Acpi" */
+#define ACPI_PREFIX_LOWER (UINT32) 0x69706361 /* "acpi" */
+
+#define ACPI_NS_ROOT_PATH "\\"
+
+#endif /* __ACNAMES_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acnamesp.h b/usr/src/boot/sys/contrib/dev/acpica/include/acnamesp.h
new file mode 100644
index 0000000000..bea4ebf0ad
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acnamesp.h
@@ -0,0 +1,546 @@
+/******************************************************************************
+ *
+ * Name: acnamesp.h - Namespace subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACNAMESP_H__
+#define __ACNAMESP_H__
+
+
+/* To search the entire name space, pass this as SearchBase */
+
+#define ACPI_NS_ALL ((ACPI_HANDLE)0)
+
+/*
+ * Elements of AcpiNsProperties are bit significant
+ * and should be one-to-one with values of ACPI_OBJECT_TYPE
+ */
+#define ACPI_NS_NORMAL 0
+#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */
+#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */
+
+/* Flags for AcpiNsLookup, AcpiNsSearchAndEnter */
+
+#define ACPI_NS_NO_UPSEARCH 0
+#define ACPI_NS_SEARCH_PARENT 0x01
+#define ACPI_NS_DONT_OPEN_SCOPE 0x02
+#define ACPI_NS_NO_PEER_SEARCH 0x04
+#define ACPI_NS_ERROR_IF_FOUND 0x08
+#define ACPI_NS_PREFIX_IS_SCOPE 0x10
+#define ACPI_NS_EXTERNAL 0x20
+#define ACPI_NS_TEMPORARY 0x40
+#define ACPI_NS_OVERRIDE_IF_FOUND 0x80
+
+/* Flags for AcpiNsWalkNamespace */
+
+#define ACPI_NS_WALK_NO_UNLOCK 0
+#define ACPI_NS_WALK_UNLOCK 0x01
+#define ACPI_NS_WALK_TEMP_NODES 0x02
+
+/* Object is not a package element */
+
+#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX
+
+/* Always emit warning message, not dependent on node flags */
+
+#define ACPI_WARN_ALWAYS 0
+
+
+/*
+ * nsinit - Namespace initialization
+ */
+ACPI_STATUS
+AcpiNsInitializeObjects (
+ void);
+
+ACPI_STATUS
+AcpiNsInitializeDevices (
+ void);
+
+
+/*
+ * nsload - Namespace loading
+ */
+ACPI_STATUS
+AcpiNsLoadNamespace (
+ void);
+
+ACPI_STATUS
+AcpiNsLoadTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *Node);
+
+
+/*
+ * nswalk - walk the namespace
+ */
+ACPI_STATUS
+AcpiNsWalkNamespace (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE StartObject,
+ UINT32 MaxDepth,
+ UINT32 Flags,
+ ACPI_WALK_CALLBACK DescendingCallback,
+ ACPI_WALK_CALLBACK AscendingCallback,
+ void *Context,
+ void **ReturnValue);
+
+ACPI_NAMESPACE_NODE *
+AcpiNsGetNextNode (
+ ACPI_NAMESPACE_NODE *Parent,
+ ACPI_NAMESPACE_NODE *Child);
+
+ACPI_NAMESPACE_NODE *
+AcpiNsGetNextNodeTyped (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE *Parent,
+ ACPI_NAMESPACE_NODE *Child);
+
+/*
+ * nsparse - table parsing
+ */
+ACPI_STATUS
+AcpiNsParseTable (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode);
+
+ACPI_STATUS
+AcpiNsOneCompleteParse (
+ UINT32 PassNumber,
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode);
+
+
+/*
+ * nsaccess - Top-level namespace access
+ */
+ACPI_STATUS
+AcpiNsRootInitialize (
+ void);
+
+ACPI_STATUS
+AcpiNsLookup (
+ ACPI_GENERIC_STATE *ScopeInfo,
+ char *Name,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_INTERPRETER_MODE InterpreterMode,
+ UINT32 Flags,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **RetNode);
+
+
+/*
+ * nsalloc - Named object allocation/deallocation
+ */
+ACPI_NAMESPACE_NODE *
+AcpiNsCreateNode (
+ UINT32 Name);
+
+void
+AcpiNsDeleteNode (
+ ACPI_NAMESPACE_NODE *Node);
+
+void
+AcpiNsRemoveNode (
+ ACPI_NAMESPACE_NODE *Node);
+
+void
+AcpiNsDeleteNamespaceSubtree (
+ ACPI_NAMESPACE_NODE *ParentHandle);
+
+void
+AcpiNsDeleteNamespaceByOwner (
+ ACPI_OWNER_ID OwnerId);
+
+void
+AcpiNsDetachObject (
+ ACPI_NAMESPACE_NODE *Node);
+
+void
+AcpiNsDeleteChildren (
+ ACPI_NAMESPACE_NODE *Parent);
+
+int
+AcpiNsCompareNames (
+ char *Name1,
+ char *Name2);
+
+
+/*
+ * nsconvert - Dynamic object conversion routines
+ */
+ACPI_STATUS
+AcpiNsConvertToInteger (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+ACPI_STATUS
+AcpiNsConvertToString (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+ACPI_STATUS
+AcpiNsConvertToBuffer (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+ACPI_STATUS
+AcpiNsConvertToUnicode (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+ACPI_STATUS
+AcpiNsConvertToResource (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+
+/*
+ * nsdump - Namespace dump/print utilities
+ */
+void
+AcpiNsDumpTables (
+ ACPI_HANDLE SearchBase,
+ UINT32 MaxDepth);
+
+void
+AcpiNsDumpEntry (
+ ACPI_HANDLE Handle,
+ UINT32 DebugLevel);
+
+void
+AcpiNsDumpPathname (
+ ACPI_HANDLE Handle,
+ char *Msg,
+ UINT32 Level,
+ UINT32 Component);
+
+void
+AcpiNsPrintPathname (
+ UINT32 NumSegments,
+ char *Pathname);
+
+ACPI_STATUS
+AcpiNsDumpOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+void
+AcpiNsDumpObjects (
+ ACPI_OBJECT_TYPE Type,
+ UINT8 DisplayType,
+ UINT32 MaxDepth,
+ ACPI_OWNER_ID OwnerId,
+ ACPI_HANDLE StartHandle);
+
+void
+AcpiNsDumpObjectPaths (
+ ACPI_OBJECT_TYPE Type,
+ UINT8 DisplayType,
+ UINT32 MaxDepth,
+ ACPI_OWNER_ID OwnerId,
+ ACPI_HANDLE StartHandle);
+
+
+/*
+ * nseval - Namespace evaluation functions
+ */
+ACPI_STATUS
+AcpiNsEvaluate (
+ ACPI_EVALUATE_INFO *Info);
+
+void
+AcpiNsExecModuleCodeList (
+ void);
+
+
+/*
+ * nsarguments - Argument count/type checking for predefined/reserved names
+ */
+void
+AcpiNsCheckArgumentCount (
+ char *Pathname,
+ ACPI_NAMESPACE_NODE *Node,
+ UINT32 UserParamCount,
+ const ACPI_PREDEFINED_INFO *Info);
+
+void
+AcpiNsCheckAcpiCompliance (
+ char *Pathname,
+ ACPI_NAMESPACE_NODE *Node,
+ const ACPI_PREDEFINED_INFO *Predefined);
+
+void
+AcpiNsCheckArgumentTypes (
+ ACPI_EVALUATE_INFO *Info);
+
+
+/*
+ * nspredef - Return value checking for predefined/reserved names
+ */
+ACPI_STATUS
+AcpiNsCheckReturnValue (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 UserParamCount,
+ ACPI_STATUS ReturnStatus,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+ACPI_STATUS
+AcpiNsCheckObjectType (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex);
+
+
+/*
+ * nsprepkg - Validation of predefined name packages
+ */
+ACPI_STATUS
+AcpiNsCheckPackage (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+
+/*
+ * nsnames - Name and Scope manipulation
+ */
+UINT32
+AcpiNsOpensScope (
+ ACPI_OBJECT_TYPE Type);
+
+char *
+AcpiNsGetExternalPathname (
+ ACPI_NAMESPACE_NODE *Node);
+
+UINT32
+AcpiNsBuildNormalizedPath (
+ ACPI_NAMESPACE_NODE *Node,
+ char *FullPath,
+ UINT32 PathSize,
+ BOOLEAN NoTrailing);
+
+char *
+AcpiNsGetNormalizedPathname (
+ ACPI_NAMESPACE_NODE *Node,
+ BOOLEAN NoTrailing);
+
+char *
+AcpiNsNameOfCurrentScope (
+ ACPI_WALK_STATE *WalkState);
+
+ACPI_STATUS
+AcpiNsHandleToPathname (
+ ACPI_HANDLE TargetHandle,
+ ACPI_BUFFER *Buffer,
+ BOOLEAN NoTrailing);
+
+BOOLEAN
+AcpiNsPatternMatch (
+ ACPI_NAMESPACE_NODE *ObjNode,
+ char *SearchFor);
+
+ACPI_STATUS
+AcpiNsGetNode (
+ ACPI_NAMESPACE_NODE *PrefixNode,
+ const char *ExternalPathname,
+ UINT32 Flags,
+ ACPI_NAMESPACE_NODE **OutNode);
+
+ACPI_SIZE
+AcpiNsGetPathnameLength (
+ ACPI_NAMESPACE_NODE *Node);
+
+
+/*
+ * nsobject - Object management for namespace nodes
+ */
+ACPI_STATUS
+AcpiNsAttachObject (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_OBJECT_TYPE Type);
+
+ACPI_OPERAND_OBJECT *
+AcpiNsGetAttachedObject (
+ ACPI_NAMESPACE_NODE *Node);
+
+ACPI_OPERAND_OBJECT *
+AcpiNsGetSecondaryObject (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+ACPI_STATUS
+AcpiNsAttachData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler,
+ void *Data);
+
+ACPI_STATUS
+AcpiNsDetachData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler);
+
+ACPI_STATUS
+AcpiNsGetAttachedData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_HANDLER Handler,
+ void **Data);
+
+
+/*
+ * nsrepair - General return object repair for all
+ * predefined methods/objects
+ */
+ACPI_STATUS
+AcpiNsSimpleRepair (
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+ACPI_STATUS
+AcpiNsWrapWithPackage (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ObjDescPtr);
+
+ACPI_STATUS
+AcpiNsRepairNullElement (
+ ACPI_EVALUATE_INFO *Info,
+ UINT32 ExpectedBtypes,
+ UINT32 PackageIndex,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+void
+AcpiNsRemoveNullElements (
+ ACPI_EVALUATE_INFO *Info,
+ UINT8 PackageType,
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+
+/*
+ * nsrepair2 - Return object repair for specific
+ * predefined methods/objects
+ */
+ACPI_STATUS
+AcpiNsComplexRepairs (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_STATUS ValidateStatus,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+
+/*
+ * nssearch - Namespace searching and entry
+ */
+ACPI_STATUS
+AcpiNsSearchAndEnter (
+ UINT32 EntryName,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_INTERPRETER_MODE InterpreterMode,
+ ACPI_OBJECT_TYPE Type,
+ UINT32 Flags,
+ ACPI_NAMESPACE_NODE **RetNode);
+
+ACPI_STATUS
+AcpiNsSearchOneScope (
+ UINT32 EntryName,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type,
+ ACPI_NAMESPACE_NODE **RetNode);
+
+void
+AcpiNsInstallNode (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *ParentNode,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_OBJECT_TYPE Type);
+
+
+/*
+ * nsutils - Utility functions
+ */
+ACPI_OBJECT_TYPE
+AcpiNsGetType (
+ ACPI_NAMESPACE_NODE *Node);
+
+UINT32
+AcpiNsLocal (
+ ACPI_OBJECT_TYPE Type);
+
+void
+AcpiNsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Msg);
+
+ACPI_STATUS
+AcpiNsBuildInternalName (
+ ACPI_NAMESTRING_INFO *Info);
+
+void
+AcpiNsGetInternalNameLength (
+ ACPI_NAMESTRING_INFO *Info);
+
+ACPI_STATUS
+AcpiNsInternalizeName (
+ const char *DottedName,
+ char **ConvertedName);
+
+ACPI_STATUS
+AcpiNsExternalizeName (
+ UINT32 InternalNameLength,
+ const char *InternalName,
+ UINT32 *ConvertedNameLength,
+ char **ConvertedName);
+
+ACPI_NAMESPACE_NODE *
+AcpiNsValidateHandle (
+ ACPI_HANDLE Handle);
+
+void
+AcpiNsTerminate (
+ void);
+
+#endif /* __ACNAMESP_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acobject.h b/usr/src/boot/sys/contrib/dev/acpica/include/acobject.h
new file mode 100644
index 0000000000..adeb414034
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acobject.h
@@ -0,0 +1,590 @@
+/******************************************************************************
+ *
+ * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACOBJECT_H
+#define _ACOBJECT_H
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+
+/*
+ * The ACPI_OPERAND_OBJECT is used to pass AML operands from the dispatcher
+ * to the interpreter, and to keep track of the various handlers such as
+ * address space handlers and notify handlers. The object is a constant
+ * size in order to allow it to be cached and reused.
+ *
+ * Note: The object is optimized to be aligned and will not work if it is
+ * byte-packed.
+ */
+#if ACPI_MACHINE_WIDTH == 64
+#pragma pack(8)
+#else
+#pragma pack(4)
+#endif
+
+/*******************************************************************************
+ *
+ * Common Descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Common area for all objects.
+ *
+ * DescriptorType is used to differentiate between internal descriptors, and
+ * must be in the same place across all descriptors
+ *
+ * Note: The DescriptorType and Type fields must appear in the identical
+ * position in both the ACPI_NAMESPACE_NODE and ACPI_OPERAND_OBJECT
+ * structures.
+ */
+#define ACPI_OBJECT_COMMON_HEADER \
+ union acpi_operand_object *NextObject; /* Objects linked to parent NS node */\
+ UINT8 DescriptorType; /* To differentiate various internal objs */\
+ UINT8 Type; /* ACPI_OBJECT_TYPE */\
+ UINT16 ReferenceCount; /* For object deletion management */\
+ UINT8 Flags;
+ /*
+ * Note: There are 3 bytes available here before the
+ * next natural alignment boundary (for both 32/64 cases)
+ */
+
+/* Values for Flag byte above */
+
+#define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */
+#define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */
+#define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */
+#define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */
+#define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */
+#define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */
+
+
+/******************************************************************************
+ *
+ * Basic data types
+ *
+ *****************************************************************************/
+
+typedef struct acpi_object_common
+{
+ ACPI_OBJECT_COMMON_HEADER
+
+} ACPI_OBJECT_COMMON;
+
+
+typedef struct acpi_object_integer
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 Fill[3]; /* Prevent warning on some compilers */
+ UINT64 Value;
+
+} ACPI_OBJECT_INTEGER;
+
+
+/*
+ * Note: The String and Buffer object must be identical through the
+ * pointer and length elements. There is code that depends on this.
+ *
+ * Fields common to both Strings and Buffers
+ */
+#define ACPI_COMMON_BUFFER_INFO(_Type) \
+ _Type *Pointer; \
+ UINT32 Length;
+
+
+typedef struct acpi_object_string /* Null terminated, ASCII characters only */
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_BUFFER_INFO (char) /* String in AML stream or allocated string */
+
+} ACPI_OBJECT_STRING;
+
+
+typedef struct acpi_object_buffer
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_BUFFER_INFO (UINT8) /* Buffer in AML stream or allocated buffer */
+ UINT32 AmlLength;
+ UINT8 *AmlStart;
+ ACPI_NAMESPACE_NODE *Node; /* Link back to parent node */
+
+} ACPI_OBJECT_BUFFER;
+
+
+typedef struct acpi_object_package
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_NAMESPACE_NODE *Node; /* Link back to parent node */
+ union acpi_operand_object **Elements; /* Array of pointers to AcpiObjects */
+ UINT8 *AmlStart;
+ UINT32 AmlLength;
+ UINT32 Count; /* # of elements in package */
+
+} ACPI_OBJECT_PACKAGE;
+
+
+/******************************************************************************
+ *
+ * Complex data types
+ *
+ *****************************************************************************/
+
+typedef struct acpi_object_event
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_SEMAPHORE OsSemaphore; /* Actual OS synchronization object */
+
+} ACPI_OBJECT_EVENT;
+
+
+typedef struct acpi_object_mutex
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 SyncLevel; /* 0-15, specified in Mutex() call */
+ UINT16 AcquisitionDepth; /* Allow multiple Acquires, same thread */
+ ACPI_MUTEX OsMutex; /* Actual OS synchronization object */
+ ACPI_THREAD_ID ThreadId; /* Current owner of the mutex */
+ struct acpi_thread_state *OwnerThread; /* Current owner of the mutex */
+ union acpi_operand_object *Prev; /* Link for list of acquired mutexes */
+ union acpi_operand_object *Next; /* Link for list of acquired mutexes */
+ ACPI_NAMESPACE_NODE *Node; /* Containing namespace node */
+ UINT8 OriginalSyncLevel; /* Owner's original sync level (0-15) */
+
+} ACPI_OBJECT_MUTEX;
+
+
+typedef struct acpi_object_region
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 SpaceId;
+ ACPI_NAMESPACE_NODE *Node; /* Containing namespace node */
+ union acpi_operand_object *Handler; /* Handler for region access */
+ union acpi_operand_object *Next;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 Length;
+
+} ACPI_OBJECT_REGION;
+
+
+typedef struct acpi_object_method
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 InfoFlags;
+ UINT8 ParamCount;
+ UINT8 SyncLevel;
+ union acpi_operand_object *Mutex;
+ union acpi_operand_object *Node;
+ UINT8 *AmlStart;
+ union
+ {
+ ACPI_INTERNAL_METHOD Implementation;
+ union acpi_operand_object *Handler;
+ } Dispatch;
+
+ UINT32 AmlLength;
+ UINT8 ThreadCount;
+ ACPI_OWNER_ID OwnerId;
+
+} ACPI_OBJECT_METHOD;
+
+/* Flags for InfoFlags field above */
+
+#define ACPI_METHOD_MODULE_LEVEL 0x01 /* Method is actually module-level code */
+#define ACPI_METHOD_INTERNAL_ONLY 0x02 /* Method is implemented internally (_OSI) */
+#define ACPI_METHOD_SERIALIZED 0x04 /* Method is serialized */
+#define ACPI_METHOD_SERIALIZED_PENDING 0x08 /* Method is to be marked serialized */
+#define ACPI_METHOD_IGNORE_SYNC_LEVEL 0x10 /* Method was auto-serialized at table load time */
+#define ACPI_METHOD_MODIFIED_NAMESPACE 0x20 /* Method modified the namespace */
+
+
+/******************************************************************************
+ *
+ * Objects that can be notified. All share a common NotifyInfo area.
+ *
+ *****************************************************************************/
+
+/*
+ * Common fields for objects that support ASL notifications
+ */
+#define ACPI_COMMON_NOTIFY_INFO \
+ union acpi_operand_object *NotifyList[2]; /* Handlers for system/device notifies */\
+ union acpi_operand_object *Handler; /* Handler for Address space */
+
+
+typedef struct acpi_object_notify_common /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_NOTIFY_INFO
+
+} ACPI_OBJECT_NOTIFY_COMMON;
+
+
+typedef struct acpi_object_device
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_NOTIFY_INFO
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+
+} ACPI_OBJECT_DEVICE;
+
+
+typedef struct acpi_object_power_resource
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_NOTIFY_INFO
+ UINT32 SystemLevel;
+ UINT32 ResourceOrder;
+
+} ACPI_OBJECT_POWER_RESOURCE;
+
+
+typedef struct acpi_object_processor
+{
+ ACPI_OBJECT_COMMON_HEADER
+
+ /* The next two fields take advantage of the 3-byte space before NOTIFY_INFO */
+
+ UINT8 ProcId;
+ UINT8 Length;
+ ACPI_COMMON_NOTIFY_INFO
+ ACPI_IO_ADDRESS Address;
+
+} ACPI_OBJECT_PROCESSOR;
+
+
+typedef struct acpi_object_thermal_zone
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_NOTIFY_INFO
+
+} ACPI_OBJECT_THERMAL_ZONE;
+
+
+/******************************************************************************
+ *
+ * Fields. All share a common header/info field.
+ *
+ *****************************************************************************/
+
+/*
+ * Common bitfield for the field objects
+ * "Field Datum" -- a datum from the actual field object
+ * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field
+ */
+#define ACPI_COMMON_FIELD_INFO \
+ UINT8 FieldFlags; /* Access, update, and lock bits */\
+ UINT8 Attribute; /* From AccessAs keyword */\
+ UINT8 AccessByteWidth; /* Read/Write size in bytes */\
+ ACPI_NAMESPACE_NODE *Node; /* Link back to parent node */\
+ UINT32 BitLength; /* Length of field in bits */\
+ UINT32 BaseByteOffset; /* Byte offset within containing object */\
+ UINT32 Value; /* Value to store into the Bank or Index register */\
+ UINT8 StartFieldBitOffset;/* Bit offset within first field datum (0-63) */\
+ UINT8 AccessLength; /* For serial regions/fields */
+
+
+typedef struct acpi_object_field_common /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_FIELD_INFO
+ union acpi_operand_object *RegionObj; /* Parent Operation Region object (REGION/BANK fields only) */
+
+} ACPI_OBJECT_FIELD_COMMON;
+
+
+typedef struct acpi_object_region_field
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_FIELD_INFO
+ UINT16 ResourceLength;
+ union acpi_operand_object *RegionObj; /* Containing OpRegion object */
+ UINT8 *ResourceBuffer; /* ResourceTemplate for serial regions/fields */
+ UINT16 PinNumberIndex; /* Index relative to previous Connection/Template */
+
+} ACPI_OBJECT_REGION_FIELD;
+
+
+typedef struct acpi_object_bank_field
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_FIELD_INFO
+ union acpi_operand_object *RegionObj; /* Containing OpRegion object */
+ union acpi_operand_object *BankObj; /* BankSelect Register object */
+
+} ACPI_OBJECT_BANK_FIELD;
+
+
+typedef struct acpi_object_index_field
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_FIELD_INFO
+
+ /*
+ * No "RegionObj" pointer needed since the Index and Data registers
+ * are each field definitions unto themselves.
+ */
+ union acpi_operand_object *IndexObj; /* Index register */
+ union acpi_operand_object *DataObj; /* Data register */
+
+} ACPI_OBJECT_INDEX_FIELD;
+
+
+/* The BufferField is different in that it is part of a Buffer, not an OpRegion */
+
+typedef struct acpi_object_buffer_field
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_COMMON_FIELD_INFO
+ union acpi_operand_object *BufferObj; /* Containing Buffer object */
+
+} ACPI_OBJECT_BUFFER_FIELD;
+
+
+/******************************************************************************
+ *
+ * Objects for handlers
+ *
+ *****************************************************************************/
+
+typedef struct acpi_object_notify_handler
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_NAMESPACE_NODE *Node; /* Parent device */
+ UINT32 HandlerType; /* Type: Device/System/Both */
+ ACPI_NOTIFY_HANDLER Handler; /* Handler address */
+ void *Context;
+ union acpi_operand_object *Next[2]; /* Device and System handler lists */
+
+} ACPI_OBJECT_NOTIFY_HANDLER;
+
+
+typedef struct acpi_object_addr_handler
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 SpaceId;
+ UINT8 HandlerFlags;
+ ACPI_ADR_SPACE_HANDLER Handler;
+ ACPI_NAMESPACE_NODE *Node; /* Parent device */
+ void *Context;
+ ACPI_ADR_SPACE_SETUP Setup;
+ union acpi_operand_object *RegionList; /* Regions using this handler */
+ union acpi_operand_object *Next;
+
+} ACPI_OBJECT_ADDR_HANDLER;
+
+/* Flags for address handler (HandlerFlags) */
+
+#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED 0x01
+
+
+/******************************************************************************
+ *
+ * Special internal objects
+ *
+ *****************************************************************************/
+
+/*
+ * The Reference object is used for these opcodes:
+ * Arg[0-6], Local[0-7], IndexOp, NameOp, RefOfOp, LoadOp, LoadTableOp, DebugOp
+ * The Reference.Class differentiates these types.
+ */
+typedef struct acpi_object_reference
+{
+ ACPI_OBJECT_COMMON_HEADER
+ UINT8 Class; /* Reference Class */
+ UINT8 TargetType; /* Used for Index Op */
+ UINT8 Reserved;
+ void *Object; /* NameOp=>HANDLE to obj, IndexOp=>ACPI_OPERAND_OBJECT */
+ ACPI_NAMESPACE_NODE *Node; /* RefOf or Namepath */
+ union acpi_operand_object **Where; /* Target of Index */
+ UINT8 *IndexPointer; /* Used for Buffers and Strings */
+ UINT32 Value; /* Used for Local/Arg/Index/DdbHandle */
+
+} ACPI_OBJECT_REFERENCE;
+
+/* Values for Reference.Class above */
+
+typedef enum
+{
+ ACPI_REFCLASS_LOCAL = 0, /* Method local */
+ ACPI_REFCLASS_ARG = 1, /* Method argument */
+ ACPI_REFCLASS_REFOF = 2, /* Result of RefOf() TBD: Split to Ref/Node and Ref/OperandObj? */
+ ACPI_REFCLASS_INDEX = 3, /* Result of Index() */
+ ACPI_REFCLASS_TABLE = 4, /* DdbHandle - Load(), LoadTable() */
+ ACPI_REFCLASS_NAME = 5, /* Reference to a named object */
+ ACPI_REFCLASS_DEBUG = 6, /* Debug object */
+
+ ACPI_REFCLASS_MAX = 6
+
+} ACPI_REFERENCE_CLASSES;
+
+
+/*
+ * Extra object is used as additional storage for types that
+ * have AML code in their declarations (TermArgs) that must be
+ * evaluated at run time.
+ *
+ * Currently: Region and FieldUnit types
+ */
+typedef struct acpi_object_extra
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_NAMESPACE_NODE *Method_REG; /* _REG method for this region (if any) */
+ ACPI_NAMESPACE_NODE *ScopeNode;
+ void *RegionContext; /* Region-specific data */
+ UINT8 *AmlStart;
+ UINT32 AmlLength;
+
+} ACPI_OBJECT_EXTRA;
+
+
+/* Additional data that can be attached to namespace nodes */
+
+typedef struct acpi_object_data
+{
+ ACPI_OBJECT_COMMON_HEADER
+ ACPI_OBJECT_HANDLER Handler;
+ void *Pointer;
+
+} ACPI_OBJECT_DATA;
+
+
+/* Structure used when objects are cached for reuse */
+
+typedef struct acpi_object_cache_list
+{
+ ACPI_OBJECT_COMMON_HEADER
+ union acpi_operand_object *Next; /* Link for object cache and internal lists*/
+
+} ACPI_OBJECT_CACHE_LIST;
+
+
+/******************************************************************************
+ *
+ * ACPI_OPERAND_OBJECT Descriptor - a giant union of all of the above
+ *
+ *****************************************************************************/
+
+typedef union acpi_operand_object
+{
+ ACPI_OBJECT_COMMON Common;
+ ACPI_OBJECT_INTEGER Integer;
+ ACPI_OBJECT_STRING String;
+ ACPI_OBJECT_BUFFER Buffer;
+ ACPI_OBJECT_PACKAGE Package;
+ ACPI_OBJECT_EVENT Event;
+ ACPI_OBJECT_METHOD Method;
+ ACPI_OBJECT_MUTEX Mutex;
+ ACPI_OBJECT_REGION Region;
+ ACPI_OBJECT_NOTIFY_COMMON CommonNotify;
+ ACPI_OBJECT_DEVICE Device;
+ ACPI_OBJECT_POWER_RESOURCE PowerResource;
+ ACPI_OBJECT_PROCESSOR Processor;
+ ACPI_OBJECT_THERMAL_ZONE ThermalZone;
+ ACPI_OBJECT_FIELD_COMMON CommonField;
+ ACPI_OBJECT_REGION_FIELD Field;
+ ACPI_OBJECT_BUFFER_FIELD BufferField;
+ ACPI_OBJECT_BANK_FIELD BankField;
+ ACPI_OBJECT_INDEX_FIELD IndexField;
+ ACPI_OBJECT_NOTIFY_HANDLER Notify;
+ ACPI_OBJECT_ADDR_HANDLER AddressSpace;
+ ACPI_OBJECT_REFERENCE Reference;
+ ACPI_OBJECT_EXTRA Extra;
+ ACPI_OBJECT_DATA Data;
+ ACPI_OBJECT_CACHE_LIST Cache;
+
+ /*
+ * Add namespace node to union in order to simplify code that accepts both
+ * ACPI_OPERAND_OBJECTs and ACPI_NAMESPACE_NODEs. The structures share
+ * a common DescriptorType field in order to differentiate them.
+ */
+ ACPI_NAMESPACE_NODE Node;
+
+} ACPI_OPERAND_OBJECT;
+
+
+/******************************************************************************
+ *
+ * ACPI_DESCRIPTOR - objects that share a common descriptor identifier
+ *
+ *****************************************************************************/
+
+/* Object descriptor types */
+
+#define ACPI_DESC_TYPE_CACHED 0x01 /* Used only when object is cached */
+#define ACPI_DESC_TYPE_STATE 0x02
+#define ACPI_DESC_TYPE_STATE_UPDATE 0x03
+#define ACPI_DESC_TYPE_STATE_PACKAGE 0x04
+#define ACPI_DESC_TYPE_STATE_CONTROL 0x05
+#define ACPI_DESC_TYPE_STATE_RPSCOPE 0x06
+#define ACPI_DESC_TYPE_STATE_PSCOPE 0x07
+#define ACPI_DESC_TYPE_STATE_WSCOPE 0x08
+#define ACPI_DESC_TYPE_STATE_RESULT 0x09
+#define ACPI_DESC_TYPE_STATE_NOTIFY 0x0A
+#define ACPI_DESC_TYPE_STATE_THREAD 0x0B
+#define ACPI_DESC_TYPE_WALK 0x0C
+#define ACPI_DESC_TYPE_PARSER 0x0D
+#define ACPI_DESC_TYPE_OPERAND 0x0E
+#define ACPI_DESC_TYPE_NAMED 0x0F
+#define ACPI_DESC_TYPE_MAX 0x0F
+
+
+typedef struct acpi_common_descriptor
+{
+ void *CommonPointer;
+ UINT8 DescriptorType; /* To differentiate various internal objs */
+
+} ACPI_COMMON_DESCRIPTOR;
+
+typedef union acpi_descriptor
+{
+ ACPI_COMMON_DESCRIPTOR Common;
+ ACPI_OPERAND_OBJECT Object;
+ ACPI_NAMESPACE_NODE Node;
+ ACPI_PARSE_OBJECT Op;
+
+} ACPI_DESCRIPTOR;
+
+#pragma pack()
+
+#endif /* _ACOBJECT_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acopcode.h b/usr/src/boot/sys/contrib/dev/acpica/include/acopcode.h
new file mode 100644
index 0000000000..9432d61106
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acopcode.h
@@ -0,0 +1,331 @@
+/******************************************************************************
+ *
+ * Name: acopcode.h - AML opcode information for the AML parser and interpreter
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACOPCODE_H__
+#define __ACOPCODE_H__
+
+#define MAX_EXTENDED_OPCODE 0x88
+#define NUM_EXTENDED_OPCODE (MAX_EXTENDED_OPCODE + 1)
+#define MAX_INTERNAL_OPCODE
+#define NUM_INTERNAL_OPCODE (MAX_INTERNAL_OPCODE + 1)
+
+/* Used for non-assigned opcodes */
+
+#define _UNK 0x6B
+
+/*
+ * Reserved ASCII characters. Do not use any of these for
+ * internal opcodes, since they are used to differentiate
+ * name strings from AML opcodes
+ */
+#define _ASC 0x6C
+#define _NAM 0x6C
+#define _PFX 0x6D
+
+
+/*
+ * All AML opcodes and the parse-time arguments for each. Used by the AML
+ * parser Each list is compressed into a 32-bit number and stored in the
+ * master opcode table (in psopcode.c).
+ */
+#define ARGP_ACCESSFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_ACQUIRE_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_WORDDATA)
+#define ARGP_ADD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_ALIAS_OP ARGP_LIST2 (ARGP_NAMESTRING, ARGP_NAME)
+#define ARGP_ARG0 ARG_NONE
+#define ARGP_ARG1 ARG_NONE
+#define ARGP_ARG2 ARG_NONE
+#define ARGP_ARG3 ARG_NONE
+#define ARGP_ARG4 ARG_NONE
+#define ARGP_ARG5 ARG_NONE
+#define ARGP_ARG6 ARG_NONE
+#define ARGP_BANK_FIELD_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_TERMARG, ARGP_BYTEDATA, ARGP_FIELDLIST)
+#define ARGP_BIT_AND_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BIT_NAND_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BIT_NOR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BIT_NOT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BIT_OR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BIT_XOR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_BREAK_OP ARG_NONE
+#define ARGP_BREAK_POINT_OP ARG_NONE
+#define ARGP_BUFFER_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_BYTELIST)
+#define ARGP_BYTE_OP ARGP_LIST1 (ARGP_BYTEDATA)
+#define ARGP_BYTELIST_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME)
+#define ARGP_CONNECTFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_CONTINUE_OP ARG_NONE
+#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME)
+#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_CREATE_BYTE_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_CREATE_DWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_CREATE_FIELD_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_CREATE_QWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_CREATE_WORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
+#define ARGP_DATA_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_DEBUG_OP ARG_NONE
+#define ARGP_DECREMENT_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_DEREF_OF_OP ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_DEVICE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST)
+#define ARGP_DIVIDE_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET, ARGP_TARGET)
+#define ARGP_DWORD_OP ARGP_LIST1 (ARGP_DWORDDATA)
+#define ARGP_ELSE_OP ARGP_LIST2 (ARGP_PKGLENGTH, ARGP_TERMLIST)
+#define ARGP_EVENT_OP ARGP_LIST1 (ARGP_NAME)
+#define ARGP_EXTERNAL_OP ARGP_LIST3 (ARGP_NAMESTRING, ARGP_BYTEDATA, ARGP_BYTEDATA)
+#define ARGP_FATAL_OP ARGP_LIST3 (ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_TERMARG)
+#define ARGP_FIELD_OP ARGP_LIST4 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_BYTEDATA, ARGP_FIELDLIST)
+#define ARGP_FIND_SET_LEFT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_FIND_SET_RIGHT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_FROM_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_IF_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
+#define ARGP_INCREMENT_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_INDEX_FIELD_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_BYTEDATA, ARGP_FIELDLIST)
+#define ARGP_INDEX_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_LAND_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LGREATER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LGREATEREQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LLESS_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LLESSEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LNOT_OP ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_LNOTEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LOAD_OP ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME)
+#define ARGP_LOAD_TABLE_OP ARGP_LIST6 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_LOCAL0 ARG_NONE
+#define ARGP_LOCAL1 ARG_NONE
+#define ARGP_LOCAL2 ARG_NONE
+#define ARGP_LOCAL3 ARG_NONE
+#define ARGP_LOCAL4 ARG_NONE
+#define ARGP_LOCAL5 ARG_NONE
+#define ARGP_LOCAL6 ARG_NONE
+#define ARGP_LOCAL7 ARG_NONE
+#define ARGP_LOR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_MATCH_OP ARGP_LIST6 (ARGP_TERMARG, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_METHOD_OP ARGP_LIST4 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMLIST)
+#define ARGP_METHODCALL_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_MID_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_MOD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_MULTIPLY_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_MUTEX_OP ARGP_LIST2 (ARGP_NAME, ARGP_BYTEDATA)
+#define ARGP_NAME_OP ARGP_LIST2 (ARGP_NAME, ARGP_DATAOBJ)
+#define ARGP_NAMEDFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NAMEPATH_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NOOP_OP ARG_NONE
+#define ARGP_NOTIFY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
+#define ARGP_ONE_OP ARG_NONE
+#define ARGP_ONES_OP ARG_NONE
+#define ARGP_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST)
+#define ARGP_POWER_RES_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_WORDDATA, ARGP_OBJLIST)
+#define ARGP_PROCESSOR_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_BYTEDATA, ARGP_OBJLIST)
+#define ARGP_QWORD_OP ARGP_LIST1 (ARGP_QWORDDATA)
+#define ARGP_REF_OF_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_TERMARG)
+#define ARGP_RELEASE_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RESERVEDFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_RESET_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_REVISION_OP ARG_NONE
+#define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST)
+#define ARGP_SERIALFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SIZE_OF_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SLEEP_OP ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STALL_OP ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STATICSTRING_OP ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_STORE_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SUPERNAME)
+#define ARGP_STRING_OP ARGP_LIST1 (ARGP_CHARLIST)
+#define ARGP_SUBTRACT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_THERMAL_ZONE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST)
+#define ARGP_TIMER_OP ARG_NONE
+#define ARGP_TO_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_BUFFER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_DEC_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_HEX_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_INTEGER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_STRING_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TYPE_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_UNLOAD_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_VAR_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_DATAOBJLIST)
+#define ARGP_WAIT_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
+#define ARGP_WHILE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
+#define ARGP_WORD_OP ARGP_LIST1 (ARGP_WORDDATA)
+#define ARGP_ZERO_OP ARG_NONE
+
+
+/*
+ * All AML opcodes and the runtime arguments for each. Used by the AML
+ * interpreter Each list is compressed into a 32-bit number and stored
+ * in the master opcode table (in psopcode.c).
+ *
+ * (Used by PrepOperands procedure and the ASL Compiler)
+ */
+#define ARGI_ACCESSFIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_ACQUIRE_OP ARGI_LIST2 (ARGI_MUTEX, ARGI_INTEGER)
+#define ARGI_ADD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_ALIAS_OP ARGI_INVALID_OPCODE
+#define ARGI_ARG0 ARG_NONE
+#define ARGI_ARG1 ARG_NONE
+#define ARGI_ARG2 ARG_NONE
+#define ARGI_ARG3 ARG_NONE
+#define ARGI_ARG4 ARG_NONE
+#define ARGI_ARG5 ARG_NONE
+#define ARGI_ARG6 ARG_NONE
+#define ARGI_BANK_FIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BIT_NOT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BIT_OR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BIT_XOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_BREAK_OP ARG_NONE
+#define ARGI_BREAK_POINT_OP ARG_NONE
+#define ARGI_BUFFER_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_BYTE_OP ARGI_INVALID_OPCODE
+#define ARGI_BYTELIST_OP ARGI_INVALID_OPCODE
+#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF)
+#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF)
+#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
+#define ARGI_CONNECTFIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE
+#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET)
+#define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_CREATE_BYTE_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_CREATE_DWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_CREATE_FIELD_OP ARGI_LIST4 (ARGI_BUFFER, ARGI_INTEGER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_CREATE_QWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_CREATE_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
+#define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING)
+#define ARGI_DEBUG_OP ARG_NONE
+#define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_TARGETREF)
+#define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING)
+#define ARGI_DEVICE_OP ARGI_INVALID_OPCODE
+#define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF)
+#define ARGI_DWORD_OP ARGI_INVALID_OPCODE
+#define ARGI_ELSE_OP ARGI_INVALID_OPCODE
+#define ARGI_EVENT_OP ARGI_INVALID_OPCODE
+#define ARGI_EXTERNAL_OP ARGI_LIST3 (ARGI_STRING, ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_FATAL_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_FIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
+#define ARGI_IF_OP ARGI_INVALID_OPCODE
+#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_TARGETREF)
+#define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATEREQUAL_OP ARGI_INVALID_OPCODE
+#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE
+#define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE
+#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_BUFFER,ARGI_TARGETREF)
+#define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_ANYTYPE)
+#define ARGI_LOCAL0 ARG_NONE
+#define ARGI_LOCAL1 ARG_NONE
+#define ARGI_LOCAL2 ARG_NONE
+#define ARGI_LOCAL3 ARG_NONE
+#define ARGI_LOCAL4 ARG_NONE
+#define ARGI_LOCAL5 ARG_NONE
+#define ARGI_LOCAL6 ARG_NONE
+#define ARGI_LOCAL7 ARG_NONE
+#define ARGI_LOR_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_COMPUTEDATA, ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
+#define ARGI_METHOD_OP ARGI_INVALID_OPCODE
+#define ARGI_METHODCALL_OP ARGI_INVALID_OPCODE
+#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_MOD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_MULTIPLY_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_MUTEX_OP ARGI_INVALID_OPCODE
+#define ARGI_NAME_OP ARGI_INVALID_OPCODE
+#define ARGI_NAMEDFIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_NAMEPATH_OP ARGI_INVALID_OPCODE
+#define ARGI_NOOP_OP ARG_NONE
+#define ARGI_NOTIFY_OP ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER)
+#define ARGI_ONE_OP ARG_NONE
+#define ARGI_ONES_OP ARG_NONE
+#define ARGI_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_POWER_RES_OP ARGI_INVALID_OPCODE
+#define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE
+#define ARGI_QWORD_OP ARGI_INVALID_OPCODE
+#define ARGI_REF_OF_OP ARGI_LIST1 (ARGI_OBJECT_REF)
+#define ARGI_REGION_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_RELEASE_OP ARGI_LIST1 (ARGI_MUTEX)
+#define ARGI_RESERVEDFIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_RESET_OP ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_RETURN_OP ARGI_INVALID_OPCODE
+#define ARGI_REVISION_OP ARG_NONE
+#define ARGI_SCOPE_OP ARGI_INVALID_OPCODE
+#define ARGI_SERIALFIELD_OP ARGI_INVALID_OPCODE
+#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_SIZE_OF_OP ARGI_LIST1 (ARGI_DATAOBJECT)
+#define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE
+#define ARGI_STORE_OP ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STRING_OP ARGI_INVALID_OPCODE
+#define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
+#define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE
+#define ARGI_TIMER_OP ARG_NONE
+#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
+#define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET)
+#define ARGI_TYPE_OP ARGI_LIST1 (ARGI_ANYTYPE)
+#define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
+#define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER)
+#define ARGI_WHILE_OP ARGI_INVALID_OPCODE
+#define ARGI_WORD_OP ARGI_INVALID_OPCODE
+#define ARGI_ZERO_OP ARG_NONE
+
+#endif /* __ACOPCODE_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acoutput.h b/usr/src/boot/sys/contrib/dev/acpica/include/acoutput.h
new file mode 100644
index 0000000000..197f28b068
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acoutput.h
@@ -0,0 +1,496 @@
+/******************************************************************************
+ *
+ * Name: acoutput.h -- debug output
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACOUTPUT_H__
+#define __ACOUTPUT_H__
+
+/*
+ * Debug levels and component IDs. These are used to control the
+ * granularity of the output of the ACPI_DEBUG_PRINT macro -- on a
+ * per-component basis and a per-exception-type basis.
+ */
+
+/* Component IDs are used in the global "DebugLayer" */
+
+#define ACPI_UTILITIES 0x00000001
+#define ACPI_HARDWARE 0x00000002
+#define ACPI_EVENTS 0x00000004
+#define ACPI_TABLES 0x00000008
+#define ACPI_NAMESPACE 0x00000010
+#define ACPI_PARSER 0x00000020
+#define ACPI_DISPATCHER 0x00000040
+#define ACPI_EXECUTER 0x00000080
+#define ACPI_RESOURCES 0x00000100
+#define ACPI_CA_DEBUGGER 0x00000200
+#define ACPI_OS_SERVICES 0x00000400
+#define ACPI_CA_DISASSEMBLER 0x00000800
+
+/* Component IDs for ACPI tools and utilities */
+
+#define ACPI_COMPILER 0x00001000
+#define ACPI_TOOLS 0x00002000
+#define ACPI_EXAMPLE 0x00004000
+#define ACPI_DRIVER 0x00008000
+#define DT_COMPILER 0x00010000
+#define ASL_PREPROCESSOR 0x00020000
+
+#define ACPI_ALL_COMPONENTS 0x0001FFFF
+#define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS)
+
+/* Component IDs reserved for ACPI drivers */
+
+#define ACPI_ALL_DRIVERS 0xFFFF0000
+
+
+/*
+ * Raw debug output levels, do not use these in the ACPI_DEBUG_PRINT macros
+ */
+#define ACPI_LV_INIT 0x00000001
+#define ACPI_LV_DEBUG_OBJECT 0x00000002
+#define ACPI_LV_INFO 0x00000004
+#define ACPI_LV_REPAIR 0x00000008
+#define ACPI_LV_TRACE_POINT 0x00000010
+#define ACPI_LV_ALL_EXCEPTIONS 0x0000001F
+
+/* Trace verbosity level 1 [Standard Trace Level] */
+
+#define ACPI_LV_INIT_NAMES 0x00000020
+#define ACPI_LV_PARSE 0x00000040
+#define ACPI_LV_LOAD 0x00000080
+#define ACPI_LV_DISPATCH 0x00000100
+#define ACPI_LV_EXEC 0x00000200
+#define ACPI_LV_NAMES 0x00000400
+#define ACPI_LV_OPREGION 0x00000800
+#define ACPI_LV_BFIELD 0x00001000
+#define ACPI_LV_TABLES 0x00002000
+#define ACPI_LV_VALUES 0x00004000
+#define ACPI_LV_OBJECTS 0x00008000
+#define ACPI_LV_RESOURCES 0x00010000
+#define ACPI_LV_USER_REQUESTS 0x00020000
+#define ACPI_LV_PACKAGE 0x00040000
+#define ACPI_LV_VERBOSITY1 0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS
+
+/* Trace verbosity level 2 [Function tracing and memory allocation] */
+
+#define ACPI_LV_ALLOCATIONS 0x00100000
+#define ACPI_LV_FUNCTIONS 0x00200000
+#define ACPI_LV_OPTIMIZATIONS 0x00400000
+#define ACPI_LV_VERBOSITY2 0x00700000 | ACPI_LV_VERBOSITY1
+#define ACPI_LV_ALL ACPI_LV_VERBOSITY2
+
+/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
+
+#define ACPI_LV_MUTEX 0x01000000
+#define ACPI_LV_THREADS 0x02000000
+#define ACPI_LV_IO 0x04000000
+#define ACPI_LV_INTERRUPTS 0x08000000
+#define ACPI_LV_VERBOSITY3 0x0F000000 | ACPI_LV_VERBOSITY2
+
+/* Exceptionally verbose output -- also used in the global "DebugLevel" */
+
+#define ACPI_LV_AML_DISASSEMBLE 0x10000000
+#define ACPI_LV_VERBOSE_INFO 0x20000000
+#define ACPI_LV_FULL_TABLES 0x40000000
+#define ACPI_LV_EVENTS 0x80000000
+#define ACPI_LV_VERBOSE 0xF0000000
+
+
+/*
+ * Debug level macros that are used in the DEBUG_PRINT macros
+ */
+#define ACPI_DEBUG_LEVEL(dl) (UINT32) dl,ACPI_DEBUG_PARAMETERS
+
+/*
+ * Exception level -- used in the global "DebugLevel"
+ *
+ * Note: For errors, use the ACPI_ERROR or ACPI_EXCEPTION interfaces.
+ * For warnings, use ACPI_WARNING.
+ */
+#define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
+#define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
+#define ACPI_DB_REPAIR ACPI_DEBUG_LEVEL (ACPI_LV_REPAIR)
+#define ACPI_DB_TRACE_POINT ACPI_DEBUG_LEVEL (ACPI_LV_TRACE_POINT)
+#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
+
+/* Trace level -- also used in the global "DebugLevel" */
+
+#define ACPI_DB_INIT_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
+#define ACPI_DB_THREADS ACPI_DEBUG_LEVEL (ACPI_LV_THREADS)
+#define ACPI_DB_PARSE ACPI_DEBUG_LEVEL (ACPI_LV_PARSE)
+#define ACPI_DB_DISPATCH ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH)
+#define ACPI_DB_LOAD ACPI_DEBUG_LEVEL (ACPI_LV_LOAD)
+#define ACPI_DB_EXEC ACPI_DEBUG_LEVEL (ACPI_LV_EXEC)
+#define ACPI_DB_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_NAMES)
+#define ACPI_DB_OPREGION ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION)
+#define ACPI_DB_BFIELD ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD)
+#define ACPI_DB_TABLES ACPI_DEBUG_LEVEL (ACPI_LV_TABLES)
+#define ACPI_DB_FUNCTIONS ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS)
+#define ACPI_DB_OPTIMIZATIONS ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS)
+#define ACPI_DB_VALUES ACPI_DEBUG_LEVEL (ACPI_LV_VALUES)
+#define ACPI_DB_OBJECTS ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS)
+#define ACPI_DB_ALLOCATIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS)
+#define ACPI_DB_RESOURCES ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES)
+#define ACPI_DB_IO ACPI_DEBUG_LEVEL (ACPI_LV_IO)
+#define ACPI_DB_INTERRUPTS ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS)
+#define ACPI_DB_USER_REQUESTS ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
+#define ACPI_DB_PACKAGE ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
+#define ACPI_DB_MUTEX ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
+#define ACPI_DB_EVENTS ACPI_DEBUG_LEVEL (ACPI_LV_EVENTS)
+
+#define ACPI_DB_ALL ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
+
+/* Defaults for DebugLevel, debug and normal */
+
+#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR)
+#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR)
+#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
+
+
+/*
+ * Global trace flags
+ */
+#define ACPI_TRACE_ENABLED ((UINT32) 4)
+#define ACPI_TRACE_ONESHOT ((UINT32) 2)
+#define ACPI_TRACE_OPCODE ((UINT32) 1)
+
+/* Defaults for trace debugging level/layer */
+
+#define ACPI_TRACE_LEVEL_ALL ACPI_LV_ALL
+#define ACPI_TRACE_LAYER_ALL 0x000001FF
+#define ACPI_TRACE_LEVEL_DEFAULT ACPI_LV_TRACE_POINT
+#define ACPI_TRACE_LAYER_DEFAULT ACPI_EXECUTER
+
+
+#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES)
+/*
+ * The module name is used primarily for error and debug messages.
+ * The __FILE__ macro is not very useful for this, because it
+ * usually includes the entire pathname to the module making the
+ * debug output difficult to read.
+ */
+#define ACPI_MODULE_NAME(Name) static const char ACPI_UNUSED_VAR _AcpiModuleName[] = Name;
+#else
+/*
+ * For the no-debug and no-error-msg cases, we must at least define
+ * a null module name.
+ */
+#define ACPI_MODULE_NAME(Name)
+#define _AcpiModuleName ""
+#endif
+
+/*
+ * Ascii error messages can be configured out
+ */
+#ifndef ACPI_NO_ERROR_MESSAGES
+#define AE_INFO _AcpiModuleName, __LINE__
+
+/*
+ * Error reporting. Callers module and line number are inserted by AE_INFO,
+ * the plist contains a set of parens to allow variable-length lists.
+ * These macros are used for both the debug and non-debug versions of the code.
+ */
+#define ACPI_INFO(plist) AcpiInfo plist
+#define ACPI_WARNING(plist) AcpiWarning plist
+#define ACPI_EXCEPTION(plist) AcpiException plist
+#define ACPI_ERROR(plist) AcpiError plist
+#define ACPI_BIOS_WARNING(plist) AcpiBiosWarning plist
+#define ACPI_BIOS_ERROR(plist) AcpiBiosError plist
+#define ACPI_DEBUG_OBJECT(obj,l,i) AcpiExDoDebugObject(obj,l,i)
+
+#else
+
+/* No error messages */
+
+#define ACPI_INFO(plist)
+#define ACPI_WARNING(plist)
+#define ACPI_EXCEPTION(plist)
+#define ACPI_ERROR(plist)
+#define ACPI_BIOS_WARNING(plist)
+#define ACPI_BIOS_ERROR(plist)
+#define ACPI_DEBUG_OBJECT(obj,l,i)
+
+#endif /* ACPI_NO_ERROR_MESSAGES */
+
+
+/*
+ * Debug macros that are conditionally compiled
+ */
+#ifdef ACPI_DEBUG_OUTPUT
+
+/*
+ * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
+ * define it now. This is the case where there the compiler does not support
+ * a __FUNCTION__ macro or equivalent.
+ */
+#ifndef ACPI_GET_FUNCTION_NAME
+#define ACPI_GET_FUNCTION_NAME _AcpiFunctionName
+
+/*
+ * The Name parameter should be the procedure name as a quoted string.
+ * The function name is also used by the function exit macros below.
+ * Note: (const char) is used to be compatible with the debug interfaces
+ * and macros such as __FUNCTION__.
+ */
+#define ACPI_FUNCTION_NAME(Name) static const char _AcpiFunctionName[] = #Name;
+
+#else
+/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
+
+#define ACPI_FUNCTION_NAME(Name)
+#endif /* ACPI_GET_FUNCTION_NAME */
+
+/*
+ * Common parameters used for debug output functions:
+ * line number, function name, module(file) name, component ID
+ */
+#define ACPI_DEBUG_PARAMETERS \
+ __LINE__, ACPI_GET_FUNCTION_NAME, _AcpiModuleName, _COMPONENT
+
+/* Check if debug output is currently dynamically enabled */
+
+#define ACPI_IS_DEBUG_ENABLED(Level, Component) \
+ ((Level & AcpiDbgLevel) && (Component & AcpiDbgLayer))
+
+/*
+ * Master debug print macros
+ * Print message if and only if:
+ * 1) Debug print for the current component is enabled
+ * 2) Debug error level or trace level for the print statement is enabled
+ *
+ * November 2012: Moved the runtime check for whether to actually emit the
+ * debug message outside of the print function itself. This improves overall
+ * performance at a relatively small code cost. Implementation involves the
+ * use of variadic macros supported by C99.
+ *
+ * Note: the ACPI_DO_WHILE0 macro is used to prevent some compilers from
+ * complaining about these constructs. On other compilers the do...while
+ * adds some extra code, so this feature is optional.
+ */
+#ifdef ACPI_USE_DO_WHILE_0
+#define ACPI_DO_WHILE0(a) do a while(0)
+#else
+#define ACPI_DO_WHILE0(a) a
+#endif
+
+/* DEBUG_PRINT functions */
+
+#ifndef COMPILER_VA_MACRO
+
+#define ACPI_DEBUG_PRINT(plist) AcpiDebugPrint plist
+#define ACPI_DEBUG_PRINT_RAW(plist) AcpiDebugPrintRaw plist
+
+#else
+
+/* Helper macros for DEBUG_PRINT */
+
+#define ACPI_DO_DEBUG_PRINT(Function, Level, Line, Filename, Modulename, Component, ...) \
+ ACPI_DO_WHILE0 ({ \
+ if (ACPI_IS_DEBUG_ENABLED (Level, Component)) \
+ { \
+ Function (Level, Line, Filename, Modulename, Component, __VA_ARGS__); \
+ } \
+ })
+
+#define ACPI_ACTUAL_DEBUG(Level, Line, Filename, Modulename, Component, ...) \
+ ACPI_DO_DEBUG_PRINT (AcpiDebugPrint, Level, Line, \
+ Filename, Modulename, Component, __VA_ARGS__)
+
+#define ACPI_ACTUAL_DEBUG_RAW(Level, Line, Filename, Modulename, Component, ...) \
+ ACPI_DO_DEBUG_PRINT (AcpiDebugPrintRaw, Level, Line, \
+ Filename, Modulename, Component, __VA_ARGS__)
+
+#define ACPI_DEBUG_PRINT(plist) ACPI_ACTUAL_DEBUG plist
+#define ACPI_DEBUG_PRINT_RAW(plist) ACPI_ACTUAL_DEBUG_RAW plist
+
+#endif
+
+
+/*
+ * Function entry tracing
+ *
+ * The name of the function is emitted as a local variable that is
+ * intended to be used by both the entry trace and the exit trace.
+ */
+
+/* Helper macro */
+
+#define ACPI_TRACE_ENTRY(Name, Function, Type, Param) \
+ ACPI_FUNCTION_NAME (Name) \
+ Function (ACPI_DEBUG_PARAMETERS, (Type) (Param))
+
+/* The actual entry trace macros */
+
+#define ACPI_FUNCTION_TRACE(Name) \
+ ACPI_FUNCTION_NAME(Name) \
+ AcpiUtTrace (ACPI_DEBUG_PARAMETERS)
+
+#define ACPI_FUNCTION_TRACE_PTR(Name, Pointer) \
+ ACPI_TRACE_ENTRY (Name, AcpiUtTracePtr, void *, Pointer)
+
+#define ACPI_FUNCTION_TRACE_U32(Name, Value) \
+ ACPI_TRACE_ENTRY (Name, AcpiUtTraceU32, UINT32, Value)
+
+#define ACPI_FUNCTION_TRACE_STR(Name, String) \
+ ACPI_TRACE_ENTRY (Name, AcpiUtTraceStr, char *, String)
+
+#define ACPI_FUNCTION_ENTRY() \
+ AcpiUtTrackStackPtr()
+
+
+/*
+ * Function exit tracing
+ *
+ * These macros include a return statement. This is usually considered
+ * bad form, but having a separate exit macro before the actual return
+ * is very ugly and difficult to maintain.
+ *
+ * One of the FUNCTION_TRACE macros above must be used in conjunction
+ * with these macros so that "_AcpiFunctionName" is defined.
+ *
+ * There are two versions of most of the return macros. The default version is
+ * safer, since it avoids side-effects by guaranteeing that the argument will
+ * not be evaluated twice.
+ *
+ * A less-safe version of the macros is provided for optional use if the
+ * compiler uses excessive CPU stack (for example, this may happen in the
+ * debug case if code optimzation is disabled.)
+ */
+
+/* Exit trace helper macro */
+
+#ifndef ACPI_SIMPLE_RETURN_MACROS
+
+#define ACPI_TRACE_EXIT(Function, Type, Param) \
+ ACPI_DO_WHILE0 ({ \
+ register Type _Param = (Type) (Param); \
+ Function (ACPI_DEBUG_PARAMETERS, _Param); \
+ return (_Param); \
+ })
+
+#else /* Use original less-safe macros */
+
+#define ACPI_TRACE_EXIT(Function, Type, Param) \
+ ACPI_DO_WHILE0 ({ \
+ Function (ACPI_DEBUG_PARAMETERS, (Type) (Param)); \
+ return (Param); \
+ })
+
+#endif /* ACPI_SIMPLE_RETURN_MACROS */
+
+/* The actual exit macros */
+
+#define return_VOID \
+ ACPI_DO_WHILE0 ({ \
+ AcpiUtExit (ACPI_DEBUG_PARAMETERS); \
+ return; \
+ })
+
+#define return_ACPI_STATUS(Status) \
+ ACPI_TRACE_EXIT (AcpiUtStatusExit, ACPI_STATUS, Status)
+
+#define return_PTR(Pointer) \
+ ACPI_TRACE_EXIT (AcpiUtPtrExit, void *, Pointer)
+
+#define return_VALUE(Value) \
+ ACPI_TRACE_EXIT (AcpiUtValueExit, UINT64, Value)
+
+#define return_UINT32(Value) \
+ ACPI_TRACE_EXIT (AcpiUtValueExit, UINT32, Value)
+
+#define return_UINT8(Value) \
+ ACPI_TRACE_EXIT (AcpiUtValueExit, UINT8, Value)
+
+/* Conditional execution */
+
+#define ACPI_DEBUG_EXEC(a) a
+#define ACPI_DEBUG_ONLY_MEMBERS(a) a;
+#define _VERBOSE_STRUCTURES
+
+
+/* Various object display routines for debug */
+
+#define ACPI_DUMP_STACK_ENTRY(a) AcpiExDumpOperand((a), 0)
+#define ACPI_DUMP_OPERANDS(a, b ,c) AcpiExDumpOperands(a, b, c)
+#define ACPI_DUMP_ENTRY(a, b) AcpiNsDumpEntry (a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d) AcpiNsDumpPathname(a, b, c, d)
+#define ACPI_DUMP_BUFFER(a, b) AcpiUtDebugDumpBuffer((UINT8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
+
+#define ACPI_TRACE_POINT(a, b, c, d) AcpiTracePoint (a, b, c, d)
+
+#else /* ACPI_DEBUG_OUTPUT */
+/*
+ * This is the non-debug case -- make everything go away,
+ * leaving no executable debug code!
+ */
+#define ACPI_DEBUG_PRINT(pl)
+#define ACPI_DEBUG_PRINT_RAW(pl)
+#define ACPI_DEBUG_EXEC(a)
+#define ACPI_DEBUG_ONLY_MEMBERS(a)
+#define ACPI_FUNCTION_NAME(a)
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_TRACE_PTR(a, b)
+#define ACPI_FUNCTION_TRACE_U32(a, b)
+#define ACPI_FUNCTION_TRACE_STR(a, b)
+#define ACPI_FUNCTION_ENTRY()
+#define ACPI_DUMP_STACK_ENTRY(a)
+#define ACPI_DUMP_OPERANDS(a, b, c)
+#define ACPI_DUMP_ENTRY(a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d)
+#define ACPI_DUMP_BUFFER(a, b)
+#define ACPI_IS_DEBUG_ENABLED(Level, Component) 0
+#define ACPI_TRACE_POINT(a, b, c, d)
+
+/* Return macros must have a return statement at the minimum */
+
+#define return_VOID return
+#define return_ACPI_STATUS(s) return(s)
+#define return_PTR(s) return(s)
+#define return_VALUE(s) return(s)
+#define return_UINT8(s) return(s)
+#define return_UINT32(s) return(s)
+
+#endif /* ACPI_DEBUG_OUTPUT */
+
+
+#endif /* __ACOUTPUT_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acparser.h b/usr/src/boot/sys/contrib/dev/acpica/include/acparser.h
new file mode 100644
index 0000000000..a89c5c4c46
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acparser.h
@@ -0,0 +1,359 @@
+/******************************************************************************
+ *
+ * Module Name: acparser.h - AML Parser subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACPARSER_H__
+#define __ACPARSER_H__
+
+
+#define OP_HAS_RETURN_VALUE 1
+
+/* Variable number of arguments. This field must be 32 bits */
+
+#define ACPI_VAR_ARGS ACPI_UINT32_MAX
+
+
+#define ACPI_PARSE_DELETE_TREE 0x0001
+#define ACPI_PARSE_NO_TREE_DELETE 0x0000
+#define ACPI_PARSE_TREE_MASK 0x0001
+
+#define ACPI_PARSE_LOAD_PASS1 0x0010
+#define ACPI_PARSE_LOAD_PASS2 0x0020
+#define ACPI_PARSE_EXECUTE 0x0030
+#define ACPI_PARSE_MODE_MASK 0x0030
+
+#define ACPI_PARSE_DEFERRED_OP 0x0100
+#define ACPI_PARSE_DISASSEMBLE 0x0200
+
+#define ACPI_PARSE_MODULE_LEVEL 0x0400
+
+/******************************************************************************
+ *
+ * Parser interfaces
+ *
+ *****************************************************************************/
+
+extern const UINT8 AcpiGbl_ShortOpIndex[];
+extern const UINT8 AcpiGbl_LongOpIndex[];
+
+
+/*
+ * psxface - Parser external interfaces
+ */
+ACPI_STATUS
+AcpiPsExecuteMethod (
+ ACPI_EVALUATE_INFO *Info);
+
+
+/*
+ * psargs - Parse AML opcode arguments
+ */
+UINT8 *
+AcpiPsGetNextPackageEnd (
+ ACPI_PARSE_STATE *ParserState);
+
+char *
+AcpiPsGetNextNamestring (
+ ACPI_PARSE_STATE *ParserState);
+
+void
+AcpiPsGetNextSimpleArg (
+ ACPI_PARSE_STATE *ParserState,
+ UINT32 ArgType,
+ ACPI_PARSE_OBJECT *Arg);
+
+ACPI_STATUS
+AcpiPsGetNextNamepath (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *Arg,
+ BOOLEAN MethodCall);
+
+ACPI_STATUS
+AcpiPsGetNextArg (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_STATE *ParserState,
+ UINT32 ArgType,
+ ACPI_PARSE_OBJECT **ReturnArg);
+
+
+/*
+ * psfind
+ */
+ACPI_PARSE_OBJECT *
+AcpiPsFindName (
+ ACPI_PARSE_OBJECT *Scope,
+ UINT32 Name,
+ UINT32 Opcode);
+
+ACPI_PARSE_OBJECT*
+AcpiPsGetParent (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * psobject - support for parse object processing
+ */
+ACPI_STATUS
+AcpiPsBuildNamedOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *UnnamedOp,
+ ACPI_PARSE_OBJECT **Op);
+
+ACPI_STATUS
+AcpiPsCreateOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT **NewOp);
+
+ACPI_STATUS
+AcpiPsCompleteOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **Op,
+ ACPI_STATUS Status);
+
+ACPI_STATUS
+AcpiPsCompleteFinalOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status);
+
+
+/*
+ * psopinfo - AML Opcode information
+ */
+const ACPI_OPCODE_INFO *
+AcpiPsGetOpcodeInfo (
+ UINT16 Opcode);
+
+char *
+AcpiPsGetOpcodeName (
+ UINT16 Opcode);
+
+UINT8
+AcpiPsGetArgumentCount (
+ UINT32 OpType);
+
+
+/*
+ * psparse - top level parsing routines
+ */
+ACPI_STATUS
+AcpiPsParseAml (
+ ACPI_WALK_STATE *WalkState);
+
+UINT32
+AcpiPsGetOpcodeSize (
+ UINT32 Opcode);
+
+UINT16
+AcpiPsPeekOpcode (
+ ACPI_PARSE_STATE *state);
+
+ACPI_STATUS
+AcpiPsCompleteThisOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+ACPI_STATUS
+AcpiPsNextParseState (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS CallbackStatus);
+
+
+/*
+ * psloop - main parse loop
+ */
+ACPI_STATUS
+AcpiPsParseLoop (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * psscope - Scope stack management routines
+ */
+ACPI_STATUS
+AcpiPsInitScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *Root);
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetParentScope (
+ ACPI_PARSE_STATE *state);
+
+BOOLEAN
+AcpiPsHasCompletedScope (
+ ACPI_PARSE_STATE *ParserState);
+
+void
+AcpiPsPopScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT **Op,
+ UINT32 *ArgList,
+ UINT32 *ArgCount);
+
+ACPI_STATUS
+AcpiPsPushScope (
+ ACPI_PARSE_STATE *ParserState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 RemainingArgs,
+ UINT32 ArgCount);
+
+void
+AcpiPsCleanupScope (
+ ACPI_PARSE_STATE *state);
+
+
+/*
+ * pstree - parse tree manipulation routines
+ */
+void
+AcpiPsAppendArg(
+ ACPI_PARSE_OBJECT *op,
+ ACPI_PARSE_OBJECT *arg);
+
+ACPI_PARSE_OBJECT*
+AcpiPsFind (
+ ACPI_PARSE_OBJECT *Scope,
+ char *Path,
+ UINT16 Opcode,
+ UINT32 Create);
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetArg(
+ ACPI_PARSE_OBJECT *op,
+ UINT32 argn);
+
+ACPI_PARSE_OBJECT *
+AcpiPsGetDepthNext (
+ ACPI_PARSE_OBJECT *Origin,
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*
+ * pswalk - parse tree walk routines
+ */
+ACPI_STATUS
+AcpiPsWalkParsedAml (
+ ACPI_PARSE_OBJECT *StartOp,
+ ACPI_PARSE_OBJECT *EndOp,
+ ACPI_OPERAND_OBJECT *MthDesc,
+ ACPI_NAMESPACE_NODE *StartNode,
+ ACPI_OPERAND_OBJECT **Params,
+ ACPI_OPERAND_OBJECT **CallerReturnDesc,
+ ACPI_OWNER_ID OwnerId,
+ ACPI_PARSE_DOWNWARDS DescendingCallback,
+ ACPI_PARSE_UPWARDS AscendingCallback);
+
+ACPI_STATUS
+AcpiPsGetNextWalkOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_UPWARDS AscendingCallback);
+
+ACPI_STATUS
+AcpiPsDeleteCompletedOp (
+ ACPI_WALK_STATE *WalkState);
+
+void
+AcpiPsDeleteParseTree (
+ ACPI_PARSE_OBJECT *root);
+
+
+/*
+ * psutils - parser utilities
+ */
+ACPI_PARSE_OBJECT *
+AcpiPsCreateScopeOp (
+ UINT8 *Aml);
+
+void
+AcpiPsInitOp (
+ ACPI_PARSE_OBJECT *op,
+ UINT16 opcode);
+
+ACPI_PARSE_OBJECT *
+AcpiPsAllocOp (
+ UINT16 Opcode,
+ UINT8 *Aml);
+
+void
+AcpiPsFreeOp (
+ ACPI_PARSE_OBJECT *Op);
+
+BOOLEAN
+AcpiPsIsLeadingChar (
+ UINT32 c);
+
+UINT32
+AcpiPsGetName(
+ ACPI_PARSE_OBJECT *op);
+
+void
+AcpiPsSetName(
+ ACPI_PARSE_OBJECT *op,
+ UINT32 name);
+
+
+/*
+ * psdump - display parser tree
+ */
+UINT32
+AcpiPsSprintPath (
+ char *BufferStart,
+ UINT32 BufferSize,
+ ACPI_PARSE_OBJECT *Op);
+
+UINT32
+AcpiPsSprintOp (
+ char *BufferStart,
+ UINT32 BufferSize,
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiPsShow (
+ ACPI_PARSE_OBJECT *op);
+
+
+#endif /* __ACPARSER_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acpi.h b/usr/src/boot/sys/contrib/dev/acpica/include/acpi.h
new file mode 100644
index 0000000000..c57d4e332f
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acpi.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Name: acpi.h - Master public include file used to interface to ACPICA
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACPI_H__
+#define __ACPI_H__
+
+/*
+ * Public include files for use by code that will interface to ACPICA.
+ *
+ * Information includes the ACPICA data types, names, exceptions, and
+ * external interface prototypes. Also included are the definitions for
+ * all ACPI tables (FADT, MADT, etc.)
+ *
+ * Note: The order of these include files is important.
+ */
+#include <contrib/dev/acpica/include/platform/acenv.h> /* Environment-specific items */
+#include <contrib/dev/acpica/include/acnames.h> /* Common ACPI names and strings */
+#include <contrib/dev/acpica/include/actypes.h> /* ACPICA data types and structures */
+#include <contrib/dev/acpica/include/acexcep.h> /* ACPICA exceptions */
+#include <contrib/dev/acpica/include/actbl.h> /* ACPI table definitions */
+#include <contrib/dev/acpica/include/acoutput.h> /* Error output and Debug macros */
+#include <contrib/dev/acpica/include/acrestyp.h> /* Resource Descriptor structs */
+#include <contrib/dev/acpica/include/acpiosxf.h> /* OSL interfaces (ACPICA-to-OS) */
+#include <contrib/dev/acpica/include/acpixf.h> /* ACPI core subsystem external interfaces */
+#include <contrib/dev/acpica/include/platform/acenvex.h> /* Extra environment-specific items */
+
+#endif /* __ACPI_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acpiosxf.h b/usr/src/boot/sys/contrib/dev/acpica/include/acpiosxf.h
new file mode 100644
index 0000000000..4028a02e3d
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acpiosxf.h
@@ -0,0 +1,612 @@
+/******************************************************************************
+ *
+ * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These
+ * interfaces must be implemented by OSL to interface the
+ * ACPI components to the host operating system.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACPIOSXF_H__
+#define __ACPIOSXF_H__
+
+#include <contrib/dev/acpica/include/platform/acenv.h>
+#include <contrib/dev/acpica/include/actypes.h>
+
+
+/* Types for AcpiOsExecute */
+
+typedef enum
+{
+ OSL_GLOBAL_LOCK_HANDLER,
+ OSL_NOTIFY_HANDLER,
+ OSL_GPE_HANDLER,
+ OSL_DEBUGGER_THREAD,
+ OSL_EC_POLL_HANDLER,
+ OSL_EC_BURST_HANDLER
+
+} ACPI_EXECUTE_TYPE;
+
+#define ACPI_NO_UNIT_LIMIT ((UINT32) -1)
+#define ACPI_MUTEX_SEM 1
+
+
+/* Functions for AcpiOsSignal */
+
+#define ACPI_SIGNAL_FATAL 0
+#define ACPI_SIGNAL_BREAKPOINT 1
+
+typedef struct acpi_signal_fatal_info
+{
+ UINT32 Type;
+ UINT32 Code;
+ UINT32 Argument;
+
+} ACPI_SIGNAL_FATAL_INFO;
+
+
+/*
+ * OSL Initialization and shutdown primitives
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsInitialize
+ACPI_STATUS
+AcpiOsInitialize (
+ void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsTerminate
+ACPI_STATUS
+AcpiOsTerminate (
+ void);
+#endif
+
+
+/*
+ * ACPI Table interfaces
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetRootPointer
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer (
+ void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsPredefinedOverride
+ACPI_STATUS
+AcpiOsPredefinedOverride (
+ const ACPI_PREDEFINED_NAMES *InitVal,
+ ACPI_STRING *NewVal);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsTableOverride
+ACPI_STATUS
+AcpiOsTableOverride (
+ ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_TABLE_HEADER **NewTable);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsPhysicalTableOverride
+ACPI_STATUS
+AcpiOsPhysicalTableOverride (
+ ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_PHYSICAL_ADDRESS *NewAddress,
+ UINT32 *NewTableLength);
+#endif
+
+
+/*
+ * Spinlock primitives
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCreateLock
+ACPI_STATUS
+AcpiOsCreateLock (
+ ACPI_SPINLOCK *OutHandle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsDeleteLock
+void
+AcpiOsDeleteLock (
+ ACPI_SPINLOCK Handle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsAcquireLock
+ACPI_CPU_FLAGS
+AcpiOsAcquireLock (
+ ACPI_SPINLOCK Handle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReleaseLock
+void
+AcpiOsReleaseLock (
+ ACPI_SPINLOCK Handle,
+ ACPI_CPU_FLAGS Flags);
+#endif
+
+
+/*
+ * Semaphore primitives
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCreateSemaphore
+ACPI_STATUS
+AcpiOsCreateSemaphore (
+ UINT32 MaxUnits,
+ UINT32 InitialUnits,
+ ACPI_SEMAPHORE *OutHandle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsDeleteSemaphore
+ACPI_STATUS
+AcpiOsDeleteSemaphore (
+ ACPI_SEMAPHORE Handle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWaitSemaphore
+ACPI_STATUS
+AcpiOsWaitSemaphore (
+ ACPI_SEMAPHORE Handle,
+ UINT32 Units,
+ UINT16 Timeout);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsSignalSemaphore
+ACPI_STATUS
+AcpiOsSignalSemaphore (
+ ACPI_SEMAPHORE Handle,
+ UINT32 Units);
+#endif
+
+
+/*
+ * Mutex primitives. May be configured to use semaphores instead via
+ * ACPI_MUTEX_TYPE (see platform/acenv.h)
+ */
+#if (ACPI_MUTEX_TYPE != ACPI_BINARY_SEMAPHORE)
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCreateMutex
+ACPI_STATUS
+AcpiOsCreateMutex (
+ ACPI_MUTEX *OutHandle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsDeleteMutex
+void
+AcpiOsDeleteMutex (
+ ACPI_MUTEX Handle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsAcquireMutex
+ACPI_STATUS
+AcpiOsAcquireMutex (
+ ACPI_MUTEX Handle,
+ UINT16 Timeout);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReleaseMutex
+void
+AcpiOsReleaseMutex (
+ ACPI_MUTEX Handle);
+#endif
+
+#endif
+
+
+/*
+ * Memory allocation and mapping
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsAllocate
+void *
+AcpiOsAllocate (
+ ACPI_SIZE Size);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsAllocateZeroed
+void *
+AcpiOsAllocateZeroed (
+ ACPI_SIZE Size);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsFree
+void
+AcpiOsFree (
+ void * Memory);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsMapMemory
+void *
+AcpiOsMapMemory (
+ ACPI_PHYSICAL_ADDRESS Where,
+ ACPI_SIZE Length);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsUnmapMemory
+void
+AcpiOsUnmapMemory (
+ void *LogicalAddress,
+ ACPI_SIZE Size);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetPhysicalAddress
+ACPI_STATUS
+AcpiOsGetPhysicalAddress (
+ void *LogicalAddress,
+ ACPI_PHYSICAL_ADDRESS *PhysicalAddress);
+#endif
+
+
+/*
+ * Memory/Object Cache
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCreateCache
+ACPI_STATUS
+AcpiOsCreateCache (
+ char *CacheName,
+ UINT16 ObjectSize,
+ UINT16 MaxDepth,
+ ACPI_CACHE_T **ReturnCache);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsDeleteCache
+ACPI_STATUS
+AcpiOsDeleteCache (
+ ACPI_CACHE_T *Cache);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsPurgeCache
+ACPI_STATUS
+AcpiOsPurgeCache (
+ ACPI_CACHE_T *Cache);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsAcquireObject
+void *
+AcpiOsAcquireObject (
+ ACPI_CACHE_T *Cache);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReleaseObject
+ACPI_STATUS
+AcpiOsReleaseObject (
+ ACPI_CACHE_T *Cache,
+ void *Object);
+#endif
+
+
+/*
+ * Interrupt handlers
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsInstallInterruptHandler
+ACPI_STATUS
+AcpiOsInstallInterruptHandler (
+ UINT32 InterruptNumber,
+ ACPI_OSD_HANDLER ServiceRoutine,
+ void *Context);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsRemoveInterruptHandler
+ACPI_STATUS
+AcpiOsRemoveInterruptHandler (
+ UINT32 InterruptNumber,
+ ACPI_OSD_HANDLER ServiceRoutine);
+#endif
+
+
+/*
+ * Threads and Scheduling
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetThreadId
+ACPI_THREAD_ID
+AcpiOsGetThreadId (
+ void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsExecute
+ACPI_STATUS
+AcpiOsExecute (
+ ACPI_EXECUTE_TYPE Type,
+ ACPI_OSD_EXEC_CALLBACK Function,
+ void *Context);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWaitEventsComplete
+void
+AcpiOsWaitEventsComplete (
+ void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsSleep
+void
+AcpiOsSleep (
+ UINT64 Milliseconds);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsStall
+void
+AcpiOsStall (
+ UINT32 Microseconds);
+#endif
+
+
+/*
+ * Platform and hardware-independent I/O interfaces
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReadPort
+ACPI_STATUS
+AcpiOsReadPort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 *Value,
+ UINT32 Width);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWritePort
+ACPI_STATUS
+AcpiOsWritePort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 Value,
+ UINT32 Width);
+#endif
+
+
+/*
+ * Platform and hardware-independent physical memory interfaces
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReadMemory
+ACPI_STATUS
+AcpiOsReadMemory (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT64 *Value,
+ UINT32 Width);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWriteMemory
+ACPI_STATUS
+AcpiOsWriteMemory (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT64 Value,
+ UINT32 Width);
+#endif
+
+
+/*
+ * Platform and hardware-independent PCI configuration space access
+ * Note: Can't use "Register" as a parameter, changed to "Reg" --
+ * certain compilers complain.
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReadPciConfiguration
+ACPI_STATUS
+AcpiOsReadPciConfiguration (
+ ACPI_PCI_ID *PciId,
+ UINT32 Reg,
+ UINT64 *Value,
+ UINT32 Width);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWritePciConfiguration
+ACPI_STATUS
+AcpiOsWritePciConfiguration (
+ ACPI_PCI_ID *PciId,
+ UINT32 Reg,
+ UINT64 Value,
+ UINT32 Width);
+#endif
+
+
+/*
+ * Miscellaneous
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReadable
+BOOLEAN
+AcpiOsReadable (
+ void *Pointer,
+ ACPI_SIZE Length);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWritable
+BOOLEAN
+AcpiOsWritable (
+ void *Pointer,
+ ACPI_SIZE Length);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetTimer
+UINT64
+AcpiOsGetTimer (
+ void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsSignal
+ACPI_STATUS
+AcpiOsSignal (
+ UINT32 Function,
+ void *Info);
+#endif
+
+
+/*
+ * Debug print routines
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsPrintf
+void ACPI_INTERNAL_VAR_XFACE
+AcpiOsPrintf (
+ const char *Format,
+ ...);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsVprintf
+void
+AcpiOsVprintf (
+ const char *Format,
+ va_list Args);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsRedirectOutput
+void
+AcpiOsRedirectOutput (
+ void *Destination);
+#endif
+
+
+/*
+ * Debug input
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetLine
+ACPI_STATUS
+AcpiOsGetLine (
+ char *Buffer,
+ UINT32 BufferLength,
+ UINT32 *BytesRead);
+#endif
+
+
+/*
+ * Obtain ACPI table(s)
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetTableByName
+ACPI_STATUS
+AcpiOsGetTableByName (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **Table,
+ ACPI_PHYSICAL_ADDRESS *Address);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetTableByIndex
+ACPI_STATUS
+AcpiOsGetTableByIndex (
+ UINT32 Index,
+ ACPI_TABLE_HEADER **Table,
+ UINT32 *Instance,
+ ACPI_PHYSICAL_ADDRESS *Address);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetTableByAddress
+ACPI_STATUS
+AcpiOsGetTableByAddress (
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_TABLE_HEADER **Table);
+#endif
+
+
+/*
+ * Directory manipulation
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsOpenDirectory
+void *
+AcpiOsOpenDirectory (
+ char *Pathname,
+ char *WildcardSpec,
+ char RequestedFileType);
+#endif
+
+/* RequesteFileType values */
+
+#define REQUEST_FILE_ONLY 0
+#define REQUEST_DIR_ONLY 1
+
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetNextFilename
+char *
+AcpiOsGetNextFilename (
+ void *DirHandle);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCloseDirectory
+void
+AcpiOsCloseDirectory (
+ void *DirHandle);
+#endif
+
+
+/*
+ * File I/O and related support
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsOpenFile
+ACPI_FILE
+AcpiOsOpenFile (
+ const char *Path,
+ UINT8 Modes);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsCloseFile
+void
+AcpiOsCloseFile (
+ ACPI_FILE File);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsReadFile
+int
+AcpiOsReadFile (
+ ACPI_FILE File,
+ void *Buffer,
+ ACPI_SIZE Size,
+ ACPI_SIZE Count);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWriteFile
+int
+AcpiOsWriteFile (
+ ACPI_FILE File,
+ void *Buffer,
+ ACPI_SIZE Size,
+ ACPI_SIZE Count);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsGetFileOffset
+long
+AcpiOsGetFileOffset (
+ ACPI_FILE File);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsSetFileOffset
+ACPI_STATUS
+AcpiOsSetFileOffset (
+ ACPI_FILE File,
+ long Offset,
+ UINT8 From);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsTracePoint
+void
+AcpiOsTracePoint (
+ ACPI_TRACE_EVENT_TYPE Type,
+ BOOLEAN Begin,
+ UINT8 *Aml,
+ char *Pathname);
+#endif
+
+
+#endif /* __ACPIOSXF_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acpixf.h b/usr/src/boot/sys/contrib/dev/acpica/include/acpixf.h
new file mode 100644
index 0000000000..ca7c9057a5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acpixf.h
@@ -0,0 +1,1219 @@
+/******************************************************************************
+ *
+ * Name: acpixf.h - External interfaces to the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACXFACE_H__
+#define __ACXFACE_H__
+
+/* Current ACPICA subsystem version in YYYYMMDD format */
+
+#define ACPI_CA_VERSION 0x20150818
+
+#include <contrib/dev/acpica/include/acconfig.h>
+#include <contrib/dev/acpica/include/actypes.h>
+#include <contrib/dev/acpica/include/actbl.h>
+#include <contrib/dev/acpica/include/acbuffer.h>
+
+
+/*****************************************************************************
+ *
+ * Macros used for ACPICA globals and configuration
+ *
+ ****************************************************************************/
+
+/*
+ * Ensure that global variables are defined and initialized only once.
+ *
+ * The use of these macros allows for a single list of globals (here)
+ * in order to simplify maintenance of the code.
+ */
+#ifdef DEFINE_ACPI_GLOBALS
+#define ACPI_GLOBAL(type,name) \
+ extern type name; \
+ type name
+
+#define ACPI_INIT_GLOBAL(type,name,value) \
+ type name=value
+
+#else
+#ifndef ACPI_GLOBAL
+#define ACPI_GLOBAL(type,name) \
+ extern type name
+#endif
+
+#ifndef ACPI_INIT_GLOBAL
+#define ACPI_INIT_GLOBAL(type,name,value) \
+ extern type name
+#endif
+#endif
+
+/*
+ * These macros configure the various ACPICA interfaces. They are
+ * useful for generating stub inline functions for features that are
+ * configured out of the current kernel or ACPICA application.
+ */
+#ifndef ACPI_EXTERNAL_RETURN_STATUS
+#define ACPI_EXTERNAL_RETURN_STATUS(Prototype) \
+ Prototype;
+#endif
+
+#ifndef ACPI_EXTERNAL_RETURN_OK
+#define ACPI_EXTERNAL_RETURN_OK(Prototype) \
+ Prototype;
+#endif
+
+#ifndef ACPI_EXTERNAL_RETURN_VOID
+#define ACPI_EXTERNAL_RETURN_VOID(Prototype) \
+ Prototype;
+#endif
+
+#ifndef ACPI_EXTERNAL_RETURN_UINT32
+#define ACPI_EXTERNAL_RETURN_UINT32(Prototype) \
+ Prototype;
+#endif
+
+#ifndef ACPI_EXTERNAL_RETURN_PTR
+#define ACPI_EXTERNAL_RETURN_PTR(Prototype) \
+ Prototype;
+#endif
+
+
+/*****************************************************************************
+ *
+ * Public globals and runtime configuration options
+ *
+ ****************************************************************************/
+
+/*
+ * Enable "slack mode" of the AML interpreter? Default is FALSE, and the
+ * interpreter strictly follows the ACPI specification. Setting to TRUE
+ * allows the interpreter to ignore certain errors and/or bad AML constructs.
+ *
+ * Currently, these features are enabled by this flag:
+ *
+ * 1) Allow "implicit return" of last value in a control method
+ * 2) Allow access beyond the end of an operation region
+ * 3) Allow access to uninitialized locals/args (auto-init to integer 0)
+ * 4) Allow ANY object type to be a source operand for the Store() operator
+ * 5) Allow unresolved references (invalid target name) in package objects
+ * 6) Enable warning messages for behavior that is not ACPI spec compliant
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_EnableInterpreterSlack, FALSE);
+
+/*
+ * Automatically serialize all methods that create named objects? Default
+ * is TRUE, meaning that all NonSerialized methods are scanned once at
+ * table load time to determine those that create named objects. Methods
+ * that create named objects are marked Serialized in order to prevent
+ * possible run-time problems if they are entered by more than one thread.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_AutoSerializeMethods, TRUE);
+
+/*
+ * Create the predefined _OSI method in the namespace? Default is TRUE
+ * because ACPICA is fully compatible with other ACPI implementations.
+ * Changing this will revert ACPICA (and machine ASL) to pre-OSI behavior.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_CreateOsiMethod, TRUE);
+
+/*
+ * Optionally use default values for the ACPI register widths. Set this to
+ * TRUE to use the defaults, if an FADT contains incorrect widths/lengths.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_UseDefaultRegisterWidths, TRUE);
+
+/*
+ * Whether or not to verify the table checksum before installation. Set
+ * this to TRUE to verify the table checksum before install it to the table
+ * manager. Note that enabling this option causes errors to happen in some
+ * OSPMs during early initialization stages. Default behavior is to do such
+ * verification.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_VerifyTableChecksum, TRUE);
+
+/*
+ * Optionally enable output from the AML Debug Object.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_EnableAmlDebugObject, FALSE);
+
+/*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_CopyDsdtLocally, FALSE);
+
+/*
+ * Optionally ignore an XSDT if present and use the RSDT instead.
+ * Although the ACPI specification requires that an XSDT be used instead
+ * of the RSDT, the XSDT has been found to be corrupt or ill-formed on
+ * some machines. Default behavior is to use the XSDT if present.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DoNotUseXsdt, FALSE);
+
+/*
+ * Optionally use 32-bit FADT addresses if and when there is a conflict
+ * (address mismatch) between the 32-bit and 64-bit versions of the
+ * address. Although ACPICA adheres to the ACPI specification which
+ * requires the use of the corresponding 64-bit address if it is non-zero,
+ * some machines have been found to have a corrupted non-zero 64-bit
+ * address. Default is FALSE, do not favor the 32-bit addresses.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_Use32BitFadtAddresses, FALSE);
+
+/*
+ * Optionally use 32-bit FACS table addresses.
+ * It is reported that some platforms fail to resume from system suspending
+ * if 64-bit FACS table address is selected:
+ * https://bugzilla.kernel.org/show_bug.cgi?id=74021
+ * Default is TRUE, favor the 32-bit addresses.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_Use32BitFacsAddresses, TRUE);
+
+/*
+ * Optionally truncate I/O addresses to 16 bits. Provides compatibility
+ * with other ACPI implementations. NOTE: During ACPICA initialization,
+ * this value is set to TRUE if any Windows OSI strings have been
+ * requested by the BIOS.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_TruncateIoAddresses, FALSE);
+
+/*
+ * Disable runtime checking and repair of values returned by control methods.
+ * Use only if the repair is causing a problem on a particular machine.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DisableAutoRepair, FALSE);
+
+/*
+ * Optionally do not install any SSDTs from the RSDT/XSDT during initialization.
+ * This can be useful for debugging ACPI problems on some machines.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DisableSsdtTableInstall, FALSE);
+
+/*
+ * Optionally enable runtime namespace override.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_RuntimeNamespaceOverride, TRUE);
+
+/*
+ * We keep track of the latest version of Windows that has been requested by
+ * the BIOS. ACPI 5.0.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_OsiData, 0);
+
+/*
+ * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning
+ * that the ACPI hardware is no longer required. A flag in the FADT indicates
+ * a reduced HW machine, and that flag is duplicated here for convenience.
+ */
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ReducedHardware, FALSE);
+
+/*
+ * This mechanism is used to trace a specified AML method. The method is
+ * traced each time it is executed.
+ */
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_TraceFlags, 0);
+ACPI_INIT_GLOBAL (const char *, AcpiGbl_TraceMethodName, NULL);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_TraceDbgLevel, ACPI_TRACE_LEVEL_DEFAULT);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_TraceDbgLayer, ACPI_TRACE_LAYER_DEFAULT);
+
+/*
+ * Runtime configuration of debug output control masks. We want the debug
+ * switches statically initialized so they are already set when the debugger
+ * is entered.
+ */
+#ifdef ACPI_DEBUG_OUTPUT
+ACPI_INIT_GLOBAL (UINT32, AcpiDbgLevel, ACPI_DEBUG_DEFAULT);
+#else
+ACPI_INIT_GLOBAL (UINT32, AcpiDbgLevel, ACPI_NORMAL_DEFAULT);
+#endif
+ACPI_INIT_GLOBAL (UINT32, AcpiDbgLayer, ACPI_COMPONENT_DEFAULT);
+
+/*
+ * Other miscellaneous globals
+ */
+ACPI_GLOBAL (ACPI_TABLE_FADT, AcpiGbl_FADT);
+ACPI_GLOBAL (UINT32, AcpiCurrentGpeCount);
+ACPI_GLOBAL (BOOLEAN, AcpiGbl_SystemAwakeAndRunning);
+
+
+/*****************************************************************************
+ *
+ * ACPICA public interface configuration.
+ *
+ * Interfaces that are configured out of the ACPICA build are replaced
+ * by inlined stubs by default.
+ *
+ ****************************************************************************/
+
+/*
+ * Hardware-reduced prototypes (default: Not hardware reduced).
+ *
+ * All ACPICA hardware-related interfaces that use these macros will be
+ * configured out of the ACPICA build if the ACPI_REDUCED_HARDWARE flag
+ * is set to TRUE.
+ *
+ * Note: This static build option for reduced hardware is intended to
+ * reduce ACPICA code size if desired or necessary. However, even if this
+ * option is not specified, the runtime behavior of ACPICA is dependent
+ * on the actual FADT reduced hardware flag (HW_REDUCED_ACPI). If set,
+ * the flag will enable similar behavior -- ACPICA will not attempt
+ * to access any ACPI-relate hardware (SCI, GPEs, Fixed Events, etc.)
+ */
+#if (!ACPI_REDUCED_HARDWARE)
+#define ACPI_HW_DEPENDENT_RETURN_STATUS(Prototype) \
+ ACPI_EXTERNAL_RETURN_STATUS(Prototype)
+
+#define ACPI_HW_DEPENDENT_RETURN_OK(Prototype) \
+ ACPI_EXTERNAL_RETURN_OK(Prototype)
+
+#define ACPI_HW_DEPENDENT_RETURN_VOID(Prototype) \
+ ACPI_EXTERNAL_RETURN_VOID(Prototype)
+
+#else
+#define ACPI_HW_DEPENDENT_RETURN_STATUS(Prototype) \
+ static ACPI_INLINE Prototype {return(AE_NOT_CONFIGURED);}
+
+#define ACPI_HW_DEPENDENT_RETURN_OK(Prototype) \
+ static ACPI_INLINE Prototype {return(AE_OK);}
+
+#define ACPI_HW_DEPENDENT_RETURN_VOID(Prototype) \
+ static ACPI_INLINE Prototype {return;}
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*
+ * Error message prototypes (default: error messages enabled).
+ *
+ * All interfaces related to error and warning messages
+ * will be configured out of the ACPICA build if the
+ * ACPI_NO_ERROR_MESSAGE flag is defined.
+ */
+#ifndef ACPI_NO_ERROR_MESSAGES
+#define ACPI_MSG_DEPENDENT_RETURN_VOID(Prototype) \
+ Prototype;
+
+#else
+#define ACPI_MSG_DEPENDENT_RETURN_VOID(Prototype) \
+ static ACPI_INLINE Prototype {return;}
+
+#endif /* ACPI_NO_ERROR_MESSAGES */
+
+
+/*
+ * Debugging output prototypes (default: no debug output).
+ *
+ * All interfaces related to debug output messages
+ * will be configured out of the ACPICA build unless the
+ * ACPI_DEBUG_OUTPUT flag is defined.
+ */
+#ifdef ACPI_DEBUG_OUTPUT
+#define ACPI_DBG_DEPENDENT_RETURN_VOID(Prototype) \
+ Prototype;
+
+#else
+#define ACPI_DBG_DEPENDENT_RETURN_VOID(Prototype) \
+ static ACPI_INLINE Prototype {return;}
+
+#endif /* ACPI_DEBUG_OUTPUT */
+
+
+/*
+ * Application prototypes
+ *
+ * All interfaces used by application will be configured
+ * out of the ACPICA build unless the ACPI_APPLICATION
+ * flag is defined.
+ */
+#ifdef ACPI_APPLICATION
+#define ACPI_APP_DEPENDENT_RETURN_VOID(Prototype) \
+ Prototype;
+
+#else
+#define ACPI_APP_DEPENDENT_RETURN_VOID(Prototype) \
+ static ACPI_INLINE Prototype {return;}
+
+#endif /* ACPI_APPLICATION */
+
+
+/*****************************************************************************
+ *
+ * ACPICA public interface prototypes
+ *
+ ****************************************************************************/
+
+/*
+ * Initialization
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInitializeTables (
+ ACPI_TABLE_DESC *InitialStorage,
+ UINT32 InitialTableCount,
+ BOOLEAN AllowResize))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInitializeSubsystem (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnableSubsystem (
+ UINT32 Flags))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInitializeObjects (
+ UINT32 Flags))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiTerminate (
+ void))
+
+
+/*
+ * Miscellaneous global interfaces
+ */
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnable (
+ void))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiDisable (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiSubsystemStatus (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetSystemInfo (
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetStatistics (
+ ACPI_STATISTICS *Stats))
+
+ACPI_EXTERNAL_RETURN_PTR (
+const char *
+AcpiFormatException (
+ ACPI_STATUS Exception))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiPurgeCachedObjects (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallInterface (
+ ACPI_STRING InterfaceName))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveInterface (
+ ACPI_STRING InterfaceName))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiUpdateInterfaces (
+ UINT8 Action))
+
+ACPI_EXTERNAL_RETURN_UINT32 (
+UINT32
+AcpiCheckAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_SIZE Length,
+ BOOLEAN Warn))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiDecodePldBuffer (
+ UINT8 *InBuffer,
+ ACPI_SIZE Length,
+ ACPI_PLD_INFO **ReturnBuffer))
+
+
+/*
+ * ACPI table load/unload interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ BOOLEAN Physical))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiLoadTables (
+ void))
+
+
+/*
+ * ACPI table manipulation interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiReallocateRootTable (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiFindRootPointer (
+ ACPI_PHYSICAL_ADDRESS *RsdpAddress))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTableHeader (
+ ACPI_STRING Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER *OutTableHeader))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTable (
+ ACPI_STRING Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **OutTable))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTableByIndex (
+ UINT32 TableIndex,
+ ACPI_TABLE_HEADER **OutTable))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallTableHandler (
+ ACPI_TABLE_HANDLER Handler,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveTableHandler (
+ ACPI_TABLE_HANDLER Handler))
+
+
+/*
+ * Namespace and name interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiWalkNamespace (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE StartObject,
+ UINT32 MaxDepth,
+ ACPI_WALK_CALLBACK DescendingCallback,
+ ACPI_WALK_CALLBACK AscendingCallback,
+ void *Context,
+ void **ReturnValue))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetDevices (
+ char *HID,
+ ACPI_WALK_CALLBACK UserFunction,
+ void *Context,
+ void **ReturnValue))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetName (
+ ACPI_HANDLE Object,
+ UINT32 NameType,
+ ACPI_BUFFER *RetPathPtr))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetHandle (
+ ACPI_HANDLE Parent,
+ ACPI_STRING Pathname,
+ ACPI_HANDLE *RetHandle))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiAttachData (
+ ACPI_HANDLE Object,
+ ACPI_OBJECT_HANDLER Handler,
+ void *Data))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiDetachData (
+ ACPI_HANDLE Object,
+ ACPI_OBJECT_HANDLER Handler))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetData (
+ ACPI_HANDLE Object,
+ ACPI_OBJECT_HANDLER Handler,
+ void **Data))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiDebugTrace (
+ const char *Name,
+ UINT32 DebugLevel,
+ UINT32 DebugLayer,
+ UINT32 Flags))
+
+
+/*
+ * Object manipulation and enumeration
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiEvaluateObject (
+ ACPI_HANDLE Object,
+ ACPI_STRING Pathname,
+ ACPI_OBJECT_LIST *ParameterObjects,
+ ACPI_BUFFER *ReturnObjectBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiEvaluateObjectTyped (
+ ACPI_HANDLE Object,
+ ACPI_STRING Pathname,
+ ACPI_OBJECT_LIST *ExternalParams,
+ ACPI_BUFFER *ReturnBuffer,
+ ACPI_OBJECT_TYPE ReturnType))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetObjectInfo (
+ ACPI_HANDLE Object,
+ ACPI_DEVICE_INFO **ReturnBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallMethod (
+ UINT8 *Buffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetNextObject (
+ ACPI_OBJECT_TYPE Type,
+ ACPI_HANDLE Parent,
+ ACPI_HANDLE Child,
+ ACPI_HANDLE *OutHandle))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetType (
+ ACPI_HANDLE Object,
+ ACPI_OBJECT_TYPE *OutType))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetParent (
+ ACPI_HANDLE Object,
+ ACPI_HANDLE *OutHandle))
+
+
+/*
+ * Handler interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallInitializationHandler (
+ ACPI_INIT_HANDLER Handler,
+ UINT32 Function))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallSciHandler (
+ ACPI_SCI_HANDLER Address,
+ void *Context))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveSciHandler (
+ ACPI_SCI_HANDLER Address))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallGlobalEventHandler (
+ ACPI_GBL_EVENT_HANDLER Handler,
+ void *Context))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallFixedEventHandler (
+ UINT32 AcpiEvent,
+ ACPI_EVENT_HANDLER Handler,
+ void *Context))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveFixedEventHandler (
+ UINT32 AcpiEvent,
+ ACPI_EVENT_HANDLER Handler))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ ACPI_GPE_HANDLER Address,
+ void *Context))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallGpeRawHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ ACPI_GPE_HANDLER Address,
+ void *Context))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_GPE_HANDLER Address))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallNotifyHandler (
+ ACPI_HANDLE Device,
+ UINT32 HandlerType,
+ ACPI_NOTIFY_HANDLER Handler,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveNotifyHandler (
+ ACPI_HANDLE Device,
+ UINT32 HandlerType,
+ ACPI_NOTIFY_HANDLER Handler))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallAddressSpaceHandler (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveAddressSpaceHandler (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallExceptionHandler (
+ ACPI_EXCEPTION_HANDLER Handler))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallInterfaceHandler (
+ ACPI_INTERFACE_HANDLER Handler))
+
+
+/*
+ * Global Lock interfaces
+ */
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiAcquireGlobalLock (
+ UINT16 Timeout,
+ UINT32 *Handle))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiReleaseGlobalLock (
+ UINT32 Handle))
+
+
+/*
+ * Interfaces to AML mutex objects
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiAcquireMutex (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname,
+ UINT16 Timeout))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiReleaseMutex (
+ ACPI_HANDLE Handle,
+ ACPI_STRING Pathname))
+
+
+/*
+ * Fixed Event interfaces
+ */
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnableEvent (
+ UINT32 Event,
+ UINT32 Flags))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiDisableEvent (
+ UINT32 Event,
+ UINT32 Flags))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiClearEvent (
+ UINT32 Event))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetEventStatus (
+ UINT32 Event,
+ ACPI_EVENT_STATUS *EventStatus))
+
+
+/*
+ * General Purpose Event (GPE) Interfaces
+ */
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiUpdateAllGpes (
+ void))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiDisableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiClearGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiSetGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiFinishGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiMarkGpeForWake (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiSetupGpeForWake (
+ ACPI_HANDLE ParentDevice,
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiSetGpeWakeMask (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetGpeStatus (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_EVENT_STATUS *EventStatus))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiDisableAllGpes (
+ void))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnableAllRuntimeGpes (
+ void))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnableAllWakeupGpes (
+ void))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetGpeDevice (
+ UINT32 GpeIndex,
+ ACPI_HANDLE *GpeDevice))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiInstallGpeBlock (
+ ACPI_HANDLE GpeDevice,
+ ACPI_GENERIC_ADDRESS *GpeBlockAddress,
+ UINT32 RegisterCount,
+ UINT32 InterruptNumber))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiRemoveGpeBlock (
+ ACPI_HANDLE GpeDevice))
+
+
+/*
+ * Resource interfaces
+ */
+typedef
+ACPI_STATUS (*ACPI_WALK_RESOURCE_CALLBACK) (
+ ACPI_RESOURCE *Resource,
+ void *Context);
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetVendorResource (
+ ACPI_HANDLE Device,
+ char *Name,
+ ACPI_VENDOR_UUID *Uuid,
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetCurrentResources (
+ ACPI_HANDLE Device,
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetPossibleResources (
+ ACPI_HANDLE Device,
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetEventResources (
+ ACPI_HANDLE DeviceHandle,
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiWalkResourceBuffer (
+ ACPI_BUFFER *Buffer,
+ ACPI_WALK_RESOURCE_CALLBACK UserFunction,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiWalkResources (
+ ACPI_HANDLE Device,
+ char *Name,
+ ACPI_WALK_RESOURCE_CALLBACK UserFunction,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiSetCurrentResources (
+ ACPI_HANDLE Device,
+ ACPI_BUFFER *InBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetIrqRoutingTable (
+ ACPI_HANDLE Device,
+ ACPI_BUFFER *RetBuffer))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiResourceToAddress64 (
+ ACPI_RESOURCE *Resource,
+ ACPI_RESOURCE_ADDRESS64 *Out))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiBufferToResource (
+ UINT8 *AmlBuffer,
+ UINT16 AmlBufferLength,
+ ACPI_RESOURCE **ResourcePtr))
+
+
+/*
+ * Hardware (ACPI device) interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiReset (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiRead (
+ UINT64 *Value,
+ ACPI_GENERIC_ADDRESS *Reg))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiWrite (
+ UINT64 Value,
+ ACPI_GENERIC_ADDRESS *Reg))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiReadBitRegister (
+ UINT32 RegisterId,
+ UINT32 *ReturnValue))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiWriteBitRegister (
+ UINT32 RegisterId,
+ UINT32 Value))
+
+
+/*
+ * Sleep/Wake interfaces
+ */
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetSleepTypeData (
+ UINT8 SleepState,
+ UINT8 *Slp_TypA,
+ UINT8 *Slp_TypB))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnterSleepStatePrep (
+ UINT8 SleepState))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnterSleepState (
+ UINT8 SleepState))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiEnterSleepStateS4bios (
+ void))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiLeaveSleepStatePrep (
+ UINT8 SleepState))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiLeaveSleepState (
+ UINT8 SleepState))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiSetFirmwareWakingVector (
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64))
+
+
+/*
+ * ACPI Timer interfaces
+ */
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTimerResolution (
+ UINT32 *Resolution))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTimer (
+ UINT32 *Ticks))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS (
+ACPI_STATUS
+AcpiGetTimerDuration (
+ UINT32 StartTicks,
+ UINT32 EndTicks,
+ UINT32 *TimeElapsed))
+
+
+/*
+ * Error/Warning output
+ */
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(3)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...))
+
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(4)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiException (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ ACPI_STATUS Status,
+ const char *Format,
+ ...))
+
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(3)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...))
+
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(3)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiInfo (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...))
+
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(3)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...))
+
+ACPI_MSG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(3)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...))
+
+
+/*
+ * Debug output
+ */
+ACPI_DBG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(6)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiDebugPrint (
+ UINT32 RequestedDebugLevel,
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ const char *Format,
+ ...))
+
+ACPI_DBG_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(6)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiDebugPrintRaw (
+ UINT32 RequestedDebugLevel,
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ const char *Format,
+ ...))
+
+ACPI_DBG_DEPENDENT_RETURN_VOID (
+void
+AcpiTracePoint (
+ ACPI_TRACE_EVENT_TYPE Type,
+ BOOLEAN Begin,
+ UINT8 *Aml,
+ char *Pathname))
+
+ACPI_APP_DEPENDENT_RETURN_VOID (
+ACPI_PRINTF_LIKE(1)
+void ACPI_INTERNAL_VAR_XFACE
+AcpiLogError (
+ const char *Format,
+ ...))
+
+ACPI_STATUS
+AcpiInitializeDebugger (
+ void);
+
+void
+AcpiTerminateDebugger (
+ void);
+
+#endif /* __ACXFACE_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acpredef.h b/usr/src/boot/sys/contrib/dev/acpica/include/acpredef.h
new file mode 100644
index 0000000000..5dae6aae79
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acpredef.h
@@ -0,0 +1,1119 @@
+/******************************************************************************
+ *
+ * Name: acpredef - Information table for ACPI predefined methods and objects
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACPREDEF_H__
+#define __ACPREDEF_H__
+
+
+/******************************************************************************
+ *
+ * Return Package types
+ *
+ * 1) PTYPE1 packages do not contain subpackages.
+ *
+ * ACPI_PTYPE1_FIXED: Fixed-length length, 1 or 2 object types:
+ * object type
+ * count
+ * object type
+ * count
+ *
+ * ACPI_PTYPE1_VAR: Variable-length length. Zero-length package is allowed:
+ * object type (Int/Buf/Ref)
+ *
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ * (Used for _PRW)
+ *
+ *
+ * 2) PTYPE2 packages contain a Variable-length number of subpackages. Each
+ * of the different types describe the contents of each of the subpackages.
+ *
+ * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types. Zero-length
+ * parent package is allowed:
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
+ *
+ * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element.
+ * Zero-length parent package is allowed:
+ * object type
+ * (Used for _CSD,_PSD,_TSD)
+ *
+ * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _CST)
+ *
+ * ACPI_PTYPE2_FIXED: Each subpackage is of Fixed-length. Zero-length
+ * parent package is allowed.
+ * (Used for _PRT)
+ *
+ * ACPI_PTYPE2_MIN: Each subpackage has a Variable-length but minimum length.
+ * Zero-length parent package is allowed:
+ * (Used for _HPX)
+ *
+ * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length
+ * (Used for _ART, _FPS)
+ *
+ * ACPI_PTYPE2_FIX_VAR: Each subpackage consists of some fixed-length elements
+ * followed by an optional element. Zero-length parent package is allowed.
+ * object type
+ * count
+ * object type
+ * count = 0 (optional)
+ * (Used for _DLM)
+ *
+ * ACPI_PTYPE2_VAR_VAR: Variable number of subpackages, each of either a
+ * constant or variable length. The subpackages are preceded by a
+ * constant number of objects.
+ * (Used for _LPI, _RDI)
+ *
+ * ACPI_PTYPE2_UUID_PAIR: Each subpackage is preceded by a UUID Buffer. The UUID
+ * defines the format of the package. Zero-length parent package is
+ * allowed.
+ * (Used for _DSD)
+ *
+ *****************************************************************************/
+
+enum AcpiReturnPackageTypes
+{
+ ACPI_PTYPE1_FIXED = 1,
+ ACPI_PTYPE1_VAR = 2,
+ ACPI_PTYPE1_OPTION = 3,
+ ACPI_PTYPE2 = 4,
+ ACPI_PTYPE2_COUNT = 5,
+ ACPI_PTYPE2_PKG_COUNT = 6,
+ ACPI_PTYPE2_FIXED = 7,
+ ACPI_PTYPE2_MIN = 8,
+ ACPI_PTYPE2_REV_FIXED = 9,
+ ACPI_PTYPE2_FIX_VAR = 10,
+ ACPI_PTYPE2_VAR_VAR = 11,
+ ACPI_PTYPE2_UUID_PAIR = 12
+};
+
+
+/* Support macros for users of the predefined info table */
+
+#define METHOD_PREDEF_ARGS_MAX 4
+#define METHOD_ARG_BIT_WIDTH 3
+#define METHOD_ARG_MASK 0x0007
+#define ARG_COUNT_IS_MINIMUM 0x8000
+#define METHOD_MAX_ARG_TYPE ACPI_TYPE_PACKAGE
+
+#define METHOD_GET_ARG_COUNT(ArgList) ((ArgList) & METHOD_ARG_MASK)
+#define METHOD_GET_NEXT_TYPE(ArgList) (((ArgList) >>= METHOD_ARG_BIT_WIDTH) & METHOD_ARG_MASK)
+
+/* Macros used to build the predefined info table */
+
+#define METHOD_0ARGS 0
+#define METHOD_1ARGS(a1) (1 | (a1 << 3))
+#define METHOD_2ARGS(a1,a2) (2 | (a1 << 3) | (a2 << 6))
+#define METHOD_3ARGS(a1,a2,a3) (3 | (a1 << 3) | (a2 << 6) | (a3 << 9))
+#define METHOD_4ARGS(a1,a2,a3,a4) (4 | (a1 << 3) | (a2 << 6) | (a3 << 9) | (a4 << 12))
+
+#define METHOD_RETURNS(type) (type)
+#define METHOD_NO_RETURN_VALUE 0
+
+#define PACKAGE_INFO(a,b,c,d,e,f) {{{(a),(b),(c),(d)}, ((((UINT16)(f)) << 8) | (e)), 0}}
+
+
+/* Support macros for the resource descriptor info table */
+
+#define WIDTH_1 0x0001
+#define WIDTH_2 0x0002
+#define WIDTH_3 0x0004
+#define WIDTH_8 0x0008
+#define WIDTH_16 0x0010
+#define WIDTH_32 0x0020
+#define WIDTH_64 0x0040
+#define VARIABLE_DATA 0x0080
+#define NUM_RESOURCE_WIDTHS 8
+
+#define WIDTH_ADDRESS WIDTH_16 | WIDTH_32 | WIDTH_64
+
+
+#ifdef ACPI_CREATE_PREDEFINED_TABLE
+/******************************************************************************
+ *
+ * Predefined method/object information table.
+ *
+ * These are the names that can actually be evaluated via AcpiEvaluateObject.
+ * Not present in this table are the following:
+ *
+ * 1) Predefined/Reserved names that are not usually evaluated via
+ * AcpiEvaluateObject:
+ * _Lxx and _Exx GPE methods
+ * _Qxx EC methods
+ * _T_x compiler temporary variables
+ * _Wxx wake events
+ *
+ * 2) Predefined names that never actually exist within the AML code:
+ * Predefined resource descriptor field names
+ *
+ * 3) Predefined names that are implemented within ACPICA:
+ * _OSI
+ *
+ * The main entries in the table each contain the following items:
+ *
+ * Name - The ACPI reserved name
+ * ArgumentList - Contains (in 16 bits), the number of required
+ * arguments to the method (3 bits), and a 3-bit type
+ * field for each argument (up to 4 arguments). The
+ * METHOD_?ARGS macros generate the correct packed data.
+ * ExpectedBtypes - Allowed type(s) for the return value.
+ * 0 means that no return value is expected.
+ *
+ * For methods that return packages, the next entry in the table contains
+ * information about the expected structure of the package. This information
+ * is saved here (rather than in a separate table) in order to minimize the
+ * overall size of the stored data.
+ *
+ * Note: The additional braces are intended to promote portability.
+ *
+ * Note2: Table is used by the kernel-resident subsystem, the iASL compiler,
+ * and the AcpiHelp utility.
+ *
+ * TBD: _PRT - currently ignore reversed entries. Attempt to fix in nsrepair.
+ * Possibly fixing package elements like _BIF, etc.
+ *
+ *****************************************************************************/
+
+const ACPI_PREDEFINED_INFO AcpiGbl_PredefinedMethods[] =
+{
+ {{"_AC0", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC1", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC2", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC3", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC4", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC5", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC6", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC7", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC8", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AC9", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ADR", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_AEI", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_AL0", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL1", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL2", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL3", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL4", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL5", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL6", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL7", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL8", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_AL9", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_ALC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ALI", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ALP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ALR", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each 2 (Ints) */
+ PACKAGE_INFO (ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0,0,0),
+
+ {{"_ALT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ART", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (2 Ref/11 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER, 11,0),
+
+ {{"_BBN", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BCL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0,0,0),
+
+ {{"_BCM", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_BCT", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BDN", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BFS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_BIF", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (9 Int),(4 Str) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING, 4,0),
+
+ {{"_BIX", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (16 Int),(4 Str) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING, 4,0),
+
+ {{"_BLT", METHOD_3ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_BMA", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BMC", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_BMD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (5 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0,0,0),
+
+ {{"_BMS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BQC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BST", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0,0,0),
+
+ {{"_BTH", METHOD_1ARGS (ACPI_TYPE_INTEGER), /* ACPI 6.0 */
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_BTM", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_BTP", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_CBA", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* See PCI firmware spec 3.0 */
+
+ {{"_CCA", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* ACPI 5.1 */
+
+ {{"_CDM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_CID", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Strs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0,0,0),
+
+ {{"_CLS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (3 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3,0,0,0),
+
+ {{"_CPC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Bufs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER, 0,0,0,0),
+
+ {{"_CR3", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_CRS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_CRT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_CSD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(n), n-1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0,0,0),
+
+ {{"_CST", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER, 3,0),
+
+ {{"_CWS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_DCK", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_DCS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_DDC", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER)}},
+
+ {{"_DDN", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_STRING)}},
+
+ {{"_DEP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_DGS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_DIS", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_DLM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (1 Ref, 0/1 Optional Buf/Ref) */
+ PACKAGE_INFO (ACPI_PTYPE2_FIX_VAR, ACPI_RTYPE_REFERENCE, 1, ACPI_RTYPE_REFERENCE | ACPI_RTYPE_BUFFER, 0,0),
+
+ {{"_DMA", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_DOD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0,0,0),
+
+ {{"_DOS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_DSD", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */
+ PACKAGE_INFO (ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_PACKAGE, 1,0),
+
+ {{"_DSM", METHOD_4ARGS (ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_PACKAGE),
+ METHOD_RETURNS (ACPI_RTYPE_ALL)}}, /* Must return a value, but it can be of any type */
+
+ {{"_DSS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_DSW", METHOD_3ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_DTI", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EC_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_EDL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs)*/
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_EJ0", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EJ1", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EJ2", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EJ3", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EJ4", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_EJD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_STRING)}},
+
+ {{"_ERR", METHOD_3ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_STRING, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* Internal use only, used by ACPICA test suites */
+
+ {{"_EVT", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_FDE", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_FDI", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (16 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0,0,0),
+
+ {{"_FDM", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_FIF", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0,0,0),
+
+ {{"_FIX", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0,0,0),
+
+ {{"_FPS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (5 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2_REV_FIXED,ACPI_RTYPE_INTEGER, 5, 0,0,0),
+
+ {{"_FSL", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_FST", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (3 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3,0,0,0),
+
+ {{"_GAI", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GCP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GHL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GLK", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GPD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GPE", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* _GPE method, not _GPE scope */
+
+ {{"_GRT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_GSB", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_GTF", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_GTM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_GTS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_GWS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_HID", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING)}},
+
+ {{"_HOT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_HPP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0,0,0),
+
+ /*
+ * For _HPX, a single package is returned, containing a variable-length number
+ * of subpackages. Each subpackage contains a PCI record setting.
+ * There are several different type of record settings, of different
+ * lengths, but all elements of all settings are Integers.
+ */
+ {{"_HPX", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (var Ints) */
+ PACKAGE_INFO (ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5,0,0,0),
+
+ {{"_HRV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_IFT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* See IPMI spec */
+
+ {{"_INI", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_IRC", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_LCK", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_LID", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_LPD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (2 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 2,0,0,0),
+
+ {{"_LPI", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (3 Int, n Pkg (10 Int/Buf) */
+ PACKAGE_INFO (ACPI_PTYPE2_VAR_VAR, ACPI_RTYPE_INTEGER, 3,
+ ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER | ACPI_RTYPE_STRING, 10,0),
+
+ {{"_MAT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_MBM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (8 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8,0,0,0),
+
+ {{"_MLS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (1 Str/1 Buf) */
+ PACKAGE_INFO (ACPI_PTYPE2, ACPI_RTYPE_STRING, 1, ACPI_RTYPE_BUFFER, 1,0),
+
+ {{"_MSG", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_MSM", METHOD_4ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_MTL", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_NTT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_OFF", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_ON_", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_OS_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_STRING)}},
+
+ {{"_OSC", METHOD_4ARGS (ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_BUFFER),
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_OST", METHOD_3ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_BUFFER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PAI", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PCL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PCT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (2 Buf) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0,0,0),
+
+ {{"_PDC", METHOD_1ARGS (ACPI_TYPE_BUFFER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PDL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PIC", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PIF", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (3 Int),(3 Str) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, ACPI_RTYPE_STRING, 3,0),
+
+ {{"_PLD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Bufs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0,0,0),
+
+ {{"_PMC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (11 Int),(3 Str) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 11, ACPI_RTYPE_STRING, 3,0),
+
+ {{"_PMD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PMM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PPC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PPE", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* See dig64 spec */
+
+ {{"_PR0", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PR1", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PR2", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PR3", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PRE", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PRL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PRR", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Ref) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_REFERENCE, 1,0,0,0),
+
+ {{"_PRS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ /*
+ * For _PRT, many BIOSs reverse the 3rd and 4th Package elements (Source
+ * and SourceIndex). This bug is so prevalent that there is code in the
+ * ACPICA Resource Manager to detect this and switch them back. For now,
+ * do not allow and issue a warning. To allow this and eliminate the
+ * warning, add the ACPI_RTYPE_REFERENCE type to the 4th element (index 3)
+ * in the statement below.
+ */
+ {{"_PRT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */
+ PACKAGE_INFO (ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER, ACPI_RTYPE_INTEGER,
+ ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, ACPI_RTYPE_INTEGER),
+
+ {{"_PRW", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE,
+ ACPI_RTYPE_INTEGER, ACPI_RTYPE_REFERENCE, 0),
+
+ {{"_PS0", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PS1", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PS2", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PS3", METHOD_0ARGS,
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PSC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PSD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (5 Int) with count */
+ PACKAGE_INFO (ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0,0,0),
+
+ {{"_PSE", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PSL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_PSR", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PSS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each (6 Int) */
+ PACKAGE_INFO (ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6,0,0,0),
+
+ {{"_PSV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PSW", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PTC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (2 Buf) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0,0,0),
+
+ {{"_PTP", METHOD_2ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_PTS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_PUR", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (2 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0,0,0),
+
+ {{"_PXM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_RDI", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int, n Pkg (m Ref)) */
+ PACKAGE_INFO (ACPI_PTYPE2_VAR_VAR, ACPI_RTYPE_INTEGER, 1,
+ ACPI_RTYPE_REFERENCE,0,0),
+
+ {{"_REG", METHOD_2ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_REV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_RMV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_ROM", METHOD_2ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_RST", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_RTV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ /*
+ * For _S0_ through _S5_, the ACPI spec defines a return Package
+ * containing 1 Integer, but most DSDTs have it wrong - 2,3, or 4 integers.
+ * Allow this by making the objects "Variable-length length", but all elements
+ * must be Integers.
+ */
+ {{"_S0_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S1_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S2_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S3_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S4_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S5_", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0,0,0),
+
+ {{"_S1D", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S2D", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S3D", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S4D", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S0W", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S1W", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S2W", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S3W", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_S4W", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SBS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SCP", METHOD_1ARGS (ACPI_TYPE_INTEGER) | ARG_COUNT_IS_MINIMUM,
+ METHOD_NO_RETURN_VALUE}}, /* Acpi 1.0 allowed 1 integer arg. Acpi 3.0 expanded to 3 args. Allow both. */
+
+ {{"_SDD", METHOD_1ARGS (ACPI_TYPE_BUFFER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_SEG", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SHL", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SLI", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_SPD", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SRS", METHOD_1ARGS (ACPI_TYPE_BUFFER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_SRT", METHOD_1ARGS (ACPI_TYPE_BUFFER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SRV", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}}, /* See IPMI spec */
+
+ {{"_SST", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_STA", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_STM", METHOD_3ARGS (ACPI_TYPE_BUFFER, ACPI_TYPE_BUFFER, ACPI_TYPE_BUFFER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_STP", METHOD_2ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_STR", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_STV", METHOD_2ARGS (ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SUB", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_STRING)}},
+
+ {{"_SUN", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_SWS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TC1", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TC2", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TDL", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TFP", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TIP", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TIV", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TMP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TPC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TPT", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_TRT", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each 2 Ref/6 Int */
+ PACKAGE_INFO (ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER, 6, 0),
+
+ {{"_TSD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each 5 Int with count */
+ PACKAGE_INFO (ACPI_PTYPE2_COUNT,ACPI_RTYPE_INTEGER, 5,0,0,0),
+
+ {{"_TSN", METHOD_0ARGS, /* ACPI 6.0 */
+ METHOD_RETURNS (ACPI_RTYPE_REFERENCE)}},
+
+ {{"_TSP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TSS", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each 5 Int */
+ PACKAGE_INFO (ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5,0,0,0),
+
+ {{"_TST", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_TTS", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_NO_RETURN_VALUE}},
+
+ {{"_TZD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */
+ PACKAGE_INFO (ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0,0,0),
+
+ {{"_TZM", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_REFERENCE)}},
+
+ {{"_TZP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_UID", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING)}},
+
+ {{"_UPC", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0,0,0),
+
+ {{"_UPD", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_UPP", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ {{"_VPO", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER)}},
+
+ /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */
+
+ {{"_WAK", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE)}},
+ PACKAGE_INFO (ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0,0,0), /* Fixed-length (2 Int), but is optional */
+
+ /* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */
+
+ {{"_WDG", METHOD_0ARGS,
+ METHOD_RETURNS (ACPI_RTYPE_BUFFER)}},
+
+ {{"_WED", METHOD_1ARGS (ACPI_TYPE_INTEGER),
+ METHOD_RETURNS (ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER)}},
+
+ PACKAGE_INFO (0,0,0,0,0,0) /* Table terminator */
+};
+#else
+extern const ACPI_PREDEFINED_INFO AcpiGbl_PredefinedMethods[];
+#endif
+
+
+#if (defined ACPI_CREATE_RESOURCE_TABLE && defined ACPI_APPLICATION)
+/******************************************************************************
+ *
+ * Predefined names for use in Resource Descriptors. These names do not
+ * appear in the global Predefined Name table (since these names never
+ * appear in actual AML byte code, only in the original ASL)
+ *
+ * Note: Used by iASL compiler and AcpiHelp utility only.
+ *
+ *****************************************************************************/
+
+const ACPI_PREDEFINED_INFO AcpiGbl_ResourceNames[] =
+{
+ {{"_ADR", WIDTH_16 | WIDTH_64, 0}},
+ {{"_ALN", WIDTH_8 | WIDTH_16 | WIDTH_32, 0}},
+ {{"_ASI", WIDTH_8, 0}},
+ {{"_ASZ", WIDTH_8, 0}},
+ {{"_ATT", WIDTH_64, 0}},
+ {{"_BAS", WIDTH_16 | WIDTH_32, 0}},
+ {{"_BM_", WIDTH_1, 0}},
+ {{"_DBT", WIDTH_16, 0}}, /* Acpi 5.0 */
+ {{"_DEC", WIDTH_1, 0}},
+ {{"_DMA", WIDTH_8, 0}},
+ {{"_DPL", WIDTH_1, 0}}, /* Acpi 5.0 */
+ {{"_DRS", WIDTH_16, 0}}, /* Acpi 5.0 */
+ {{"_END", WIDTH_1, 0}}, /* Acpi 5.0 */
+ {{"_FLC", WIDTH_2, 0}}, /* Acpi 5.0 */
+ {{"_GRA", WIDTH_ADDRESS, 0}},
+ {{"_HE_", WIDTH_1, 0}},
+ {{"_INT", WIDTH_16 | WIDTH_32, 0}},
+ {{"_IOR", WIDTH_2, 0}}, /* Acpi 5.0 */
+ {{"_LEN", WIDTH_8 | WIDTH_ADDRESS, 0}},
+ {{"_LIN", WIDTH_8, 0}}, /* Acpi 5.0 */
+ {{"_LL_", WIDTH_1, 0}},
+ {{"_MAF", WIDTH_1, 0}},
+ {{"_MAX", WIDTH_ADDRESS, 0}},
+ {{"_MEM", WIDTH_2, 0}},
+ {{"_MIF", WIDTH_1, 0}},
+ {{"_MIN", WIDTH_ADDRESS, 0}},
+ {{"_MOD", WIDTH_1, 0}}, /* Acpi 5.0 */
+ {{"_MTP", WIDTH_2, 0}},
+ {{"_PAR", WIDTH_8, 0}}, /* Acpi 5.0 */
+ {{"_PHA", WIDTH_1, 0}}, /* Acpi 5.0 */
+ {{"_PIN", WIDTH_16, 0}}, /* Acpi 5.0 */
+ {{"_PPI", WIDTH_8, 0}}, /* Acpi 5.0 */
+ {{"_POL", WIDTH_1 | WIDTH_2, 0}}, /* Acpi 5.0 */
+ {{"_RBO", WIDTH_8, 0}},
+ {{"_RBW", WIDTH_8, 0}},
+ {{"_RNG", WIDTH_1, 0}},
+ {{"_RT_", WIDTH_8, 0}}, /* Acpi 3.0 */
+ {{"_RW_", WIDTH_1, 0}},
+ {{"_RXL", WIDTH_16, 0}}, /* Acpi 5.0 */
+ {{"_SHR", WIDTH_2, 0}},
+ {{"_SIZ", WIDTH_2, 0}},
+ {{"_SLV", WIDTH_1, 0}}, /* Acpi 5.0 */
+ {{"_SPE", WIDTH_32, 0}}, /* Acpi 5.0 */
+ {{"_STB", WIDTH_2, 0}}, /* Acpi 5.0 */
+ {{"_TRA", WIDTH_ADDRESS, 0}},
+ {{"_TRS", WIDTH_1, 0}},
+ {{"_TSF", WIDTH_8, 0}}, /* Acpi 3.0 */
+ {{"_TTP", WIDTH_1, 0}},
+ {{"_TXL", WIDTH_16, 0}}, /* Acpi 5.0 */
+ {{"_TYP", WIDTH_2 | WIDTH_16, 0}},
+ {{"_VEN", VARIABLE_DATA, 0}}, /* Acpi 5.0 */
+ PACKAGE_INFO (0,0,0,0,0,0) /* Table terminator */
+};
+
+static const ACPI_PREDEFINED_INFO AcpiGbl_ScopeNames[] = {
+ {{"_GPE", 0, 0}},
+ {{"_PR_", 0, 0}},
+ {{"_SB_", 0, 0}},
+ {{"_SI_", 0, 0}},
+ {{"_TZ_", 0, 0}},
+ PACKAGE_INFO (0,0,0,0,0,0) /* Table terminator */
+};
+#else
+extern const ACPI_PREDEFINED_INFO AcpiGbl_ResourceNames[];
+#endif
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acresrc.h b/usr/src/boot/sys/contrib/dev/acpica/include/acresrc.h
new file mode 100644
index 0000000000..ef3265876e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acresrc.h
@@ -0,0 +1,442 @@
+/******************************************************************************
+ *
+ * Name: acresrc.h - Resource Manager function prototypes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACRESRC_H__
+#define __ACRESRC_H__
+
+/* Need the AML resource descriptor structs */
+
+#include <contrib/dev/acpica/include/amlresrc.h>
+
+
+/*
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
+ */
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
+#pragma pack(1)
+#endif
+
+/*
+ * Individual entry for the resource conversion tables
+ */
+typedef const struct acpi_rsconvert_info
+{
+ UINT8 Opcode;
+ UINT8 ResourceOffset;
+ UINT8 AmlOffset;
+ UINT8 Value;
+
+} ACPI_RSCONVERT_INFO;
+
+/* Resource conversion opcodes */
+
+typedef enum
+{
+ ACPI_RSC_INITGET = 0,
+ ACPI_RSC_INITSET,
+ ACPI_RSC_FLAGINIT,
+ ACPI_RSC_1BITFLAG,
+ ACPI_RSC_2BITFLAG,
+ ACPI_RSC_3BITFLAG,
+ ACPI_RSC_ADDRESS,
+ ACPI_RSC_BITMASK,
+ ACPI_RSC_BITMASK16,
+ ACPI_RSC_COUNT,
+ ACPI_RSC_COUNT16,
+ ACPI_RSC_COUNT_GPIO_PIN,
+ ACPI_RSC_COUNT_GPIO_RES,
+ ACPI_RSC_COUNT_GPIO_VEN,
+ ACPI_RSC_COUNT_SERIAL_RES,
+ ACPI_RSC_COUNT_SERIAL_VEN,
+ ACPI_RSC_DATA8,
+ ACPI_RSC_EXIT_EQ,
+ ACPI_RSC_EXIT_LE,
+ ACPI_RSC_EXIT_NE,
+ ACPI_RSC_LENGTH,
+ ACPI_RSC_MOVE_GPIO_PIN,
+ ACPI_RSC_MOVE_GPIO_RES,
+ ACPI_RSC_MOVE_SERIAL_RES,
+ ACPI_RSC_MOVE_SERIAL_VEN,
+ ACPI_RSC_MOVE8,
+ ACPI_RSC_MOVE16,
+ ACPI_RSC_MOVE32,
+ ACPI_RSC_MOVE64,
+ ACPI_RSC_SET8,
+ ACPI_RSC_SOURCE,
+ ACPI_RSC_SOURCEX
+
+} ACPI_RSCONVERT_OPCODES;
+
+/* Resource Conversion sub-opcodes */
+
+#define ACPI_RSC_COMPARE_AML_LENGTH 0
+#define ACPI_RSC_COMPARE_VALUE 1
+
+#define ACPI_RSC_TABLE_SIZE(d) (sizeof (d) / sizeof (ACPI_RSCONVERT_INFO))
+
+#define ACPI_RS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_RESOURCE,f)
+#define AML_OFFSET(f) (UINT8) ACPI_OFFSET (AML_RESOURCE,f)
+
+
+/*
+ * Individual entry for the resource dump tables
+ */
+typedef const struct acpi_rsdump_info
+{
+ UINT8 Opcode;
+ UINT8 Offset;
+ char *Name;
+ const char **Pointer;
+
+} ACPI_RSDUMP_INFO;
+
+/* Values for the Opcode field above */
+
+typedef enum
+{
+ ACPI_RSD_TITLE = 0,
+ ACPI_RSD_1BITFLAG,
+ ACPI_RSD_2BITFLAG,
+ ACPI_RSD_3BITFLAG,
+ ACPI_RSD_ADDRESS,
+ ACPI_RSD_DWORDLIST,
+ ACPI_RSD_LITERAL,
+ ACPI_RSD_LONGLIST,
+ ACPI_RSD_SHORTLIST,
+ ACPI_RSD_SHORTLISTX,
+ ACPI_RSD_SOURCE,
+ ACPI_RSD_STRING,
+ ACPI_RSD_UINT8,
+ ACPI_RSD_UINT16,
+ ACPI_RSD_UINT32,
+ ACPI_RSD_UINT64,
+ ACPI_RSD_WORDLIST
+
+} ACPI_RSDUMP_OPCODES;
+
+/* restore default alignment */
+
+#pragma pack()
+
+
+/* Resource tables indexed by internal resource type */
+
+extern const UINT8 AcpiGbl_AmlResourceSizes[];
+extern const UINT8 AcpiGbl_AmlResourceSerialBusSizes[];
+extern ACPI_RSCONVERT_INFO *AcpiGbl_SetResourceDispatch[];
+
+/* Resource tables indexed by raw AML resource descriptor type */
+
+extern const UINT8 AcpiGbl_ResourceStructSizes[];
+extern const UINT8 AcpiGbl_ResourceStructSerialBusSizes[];
+extern ACPI_RSCONVERT_INFO *AcpiGbl_GetResourceDispatch[];
+
+extern ACPI_RSCONVERT_INFO *AcpiGbl_ConvertResourceSerialBusDispatch[];
+
+typedef struct acpi_vendor_walk_info
+{
+ ACPI_VENDOR_UUID *Uuid;
+ ACPI_BUFFER *Buffer;
+ ACPI_STATUS Status;
+
+} ACPI_VENDOR_WALK_INFO;
+
+
+/*
+ * rscreate
+ */
+ACPI_STATUS
+AcpiRsCreateResourceList (
+ ACPI_OPERAND_OBJECT *AmlBuffer,
+ ACPI_BUFFER *OutputBuffer);
+
+ACPI_STATUS
+AcpiRsCreateAmlResources (
+ ACPI_BUFFER *ResourceList,
+ ACPI_BUFFER *OutputBuffer);
+
+ACPI_STATUS
+AcpiRsCreatePciRoutingTable (
+ ACPI_OPERAND_OBJECT *PackageObject,
+ ACPI_BUFFER *OutputBuffer);
+
+
+/*
+ * rsutils
+ */
+ACPI_STATUS
+AcpiRsGetPrtMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiRsGetCrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiRsGetPrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiRsGetMethodData (
+ ACPI_HANDLE Handle,
+ char *Path,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiRsSetSrsMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiRsGetAeiMethodData (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_BUFFER *RetBuffer);
+
+/*
+ * rscalc
+ */
+ACPI_STATUS
+AcpiRsGetListLength (
+ UINT8 *AmlBuffer,
+ UINT32 AmlBufferLength,
+ ACPI_SIZE *SizeNeeded);
+
+ACPI_STATUS
+AcpiRsGetAmlLength (
+ ACPI_RESOURCE *ResourceList,
+ ACPI_SIZE ResourceListSize,
+ ACPI_SIZE *SizeNeeded);
+
+ACPI_STATUS
+AcpiRsGetPciRoutingTableLength (
+ ACPI_OPERAND_OBJECT *PackageObject,
+ ACPI_SIZE *BufferSizeNeeded);
+
+ACPI_STATUS
+AcpiRsConvertAmlToResources (
+ UINT8 *Aml,
+ UINT32 Length,
+ UINT32 Offset,
+ UINT8 ResourceIndex,
+ void **Context);
+
+ACPI_STATUS
+AcpiRsConvertResourcesToAml (
+ ACPI_RESOURCE *Resource,
+ ACPI_SIZE AmlSizeNeeded,
+ UINT8 *OutputBuffer);
+
+
+/*
+ * rsaddr
+ */
+void
+AcpiRsSetAddressCommon (
+ AML_RESOURCE *Aml,
+ ACPI_RESOURCE *Resource);
+
+BOOLEAN
+AcpiRsGetAddressCommon (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml);
+
+
+/*
+ * rsmisc
+ */
+ACPI_STATUS
+AcpiRsConvertAmlToResource (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml,
+ ACPI_RSCONVERT_INFO *Info);
+
+ACPI_STATUS
+AcpiRsConvertResourceToAml (
+ ACPI_RESOURCE *Resource,
+ AML_RESOURCE *Aml,
+ ACPI_RSCONVERT_INFO *Info);
+
+
+/*
+ * rsutils
+ */
+void
+AcpiRsMoveData (
+ void *Destination,
+ void *Source,
+ UINT16 ItemCount,
+ UINT8 MoveType);
+
+UINT8
+AcpiRsDecodeBitmask (
+ UINT16 Mask,
+ UINT8 *List);
+
+UINT16
+AcpiRsEncodeBitmask (
+ UINT8 *List,
+ UINT8 Count);
+
+ACPI_RS_LENGTH
+AcpiRsGetResourceSource (
+ ACPI_RS_LENGTH ResourceLength,
+ ACPI_RS_LENGTH MinimumLength,
+ ACPI_RESOURCE_SOURCE *ResourceSource,
+ AML_RESOURCE *Aml,
+ char *StringPtr);
+
+ACPI_RSDESC_SIZE
+AcpiRsSetResourceSource (
+ AML_RESOURCE *Aml,
+ ACPI_RS_LENGTH MinimumLength,
+ ACPI_RESOURCE_SOURCE *ResourceSource);
+
+void
+AcpiRsSetResourceHeader (
+ UINT8 DescriptorType,
+ ACPI_RSDESC_SIZE TotalLength,
+ AML_RESOURCE *Aml);
+
+void
+AcpiRsSetResourceLength (
+ ACPI_RSDESC_SIZE TotalLength,
+ AML_RESOURCE *Aml);
+
+
+/*
+ * rsdump - Debugger support
+ */
+#ifdef ACPI_DEBUGGER
+void
+AcpiRsDumpResourceList (
+ ACPI_RESOURCE *Resource);
+
+void
+AcpiRsDumpIrqList (
+ UINT8 *RouteTable);
+#endif
+
+
+/*
+ * Resource conversion tables
+ */
+extern ACPI_RSCONVERT_INFO AcpiRsConvertDma[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertEndDpf[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertIo[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertFixedIo[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertEndTag[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertMemory24[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertGenericReg[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertMemory32[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertFixedMemory32[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertAddress32[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertAddress16[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertExtIrq[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertAddress64[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertExtAddress64[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertGpio[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertFixedDma[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertI2cSerialBus[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertSpiSerialBus[];
+extern ACPI_RSCONVERT_INFO AcpiRsConvertUartSerialBus[];
+
+/* These resources require separate get/set tables */
+
+extern ACPI_RSCONVERT_INFO AcpiRsGetIrq[];
+extern ACPI_RSCONVERT_INFO AcpiRsGetStartDpf[];
+extern ACPI_RSCONVERT_INFO AcpiRsGetVendorSmall[];
+extern ACPI_RSCONVERT_INFO AcpiRsGetVendorLarge[];
+
+extern ACPI_RSCONVERT_INFO AcpiRsSetIrq[];
+extern ACPI_RSCONVERT_INFO AcpiRsSetStartDpf[];
+extern ACPI_RSCONVERT_INFO AcpiRsSetVendor[];
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+/*
+ * rsinfo
+ */
+extern ACPI_RSDUMP_INFO *AcpiGbl_DumpResourceDispatch[];
+extern ACPI_RSDUMP_INFO *AcpiGbl_DumpSerialBusDispatch[];
+
+/*
+ * rsdumpinfo
+ */
+extern ACPI_RSDUMP_INFO AcpiRsDumpIrq[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpPrt[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpDma[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpStartDpf[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpEndDpf[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpIo[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpIoFlags[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpFixedIo[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpVendor[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpEndTag[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpMemory24[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpMemory32[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpMemoryFlags[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpFixedMemory32[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpAddress16[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpAddress32[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpAddress64[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpExtAddress64[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpExtIrq[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpGenericReg[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpGpio[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpFixedDma[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpCommonSerialBus[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpI2cSerialBus[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpSpiSerialBus[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpUartSerialBus[];
+extern ACPI_RSDUMP_INFO AcpiRsDumpGeneralFlags[];
+#endif
+
+#endif /* __ACRESRC_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acrestyp.h b/usr/src/boot/sys/contrib/dev/acpica/include/acrestyp.h
new file mode 100644
index 0000000000..d69545131e
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acrestyp.h
@@ -0,0 +1,714 @@
+/******************************************************************************
+ *
+ * Name: acrestyp.h - Defines, types, and structures for resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACRESTYP_H__
+#define __ACRESTYP_H__
+
+
+/*
+ * Definitions for Resource Attributes
+ */
+typedef UINT16 ACPI_RS_LENGTH; /* Resource Length field is fixed at 16 bits */
+typedef UINT32 ACPI_RSDESC_SIZE; /* Max Resource Descriptor size is (Length+3) = (64K-1)+3 */
+
+/*
+ * Memory Attributes
+ */
+#define ACPI_READ_ONLY_MEMORY (UINT8) 0x00
+#define ACPI_READ_WRITE_MEMORY (UINT8) 0x01
+
+#define ACPI_NON_CACHEABLE_MEMORY (UINT8) 0x00
+#define ACPI_CACHABLE_MEMORY (UINT8) 0x01
+#define ACPI_WRITE_COMBINING_MEMORY (UINT8) 0x02
+#define ACPI_PREFETCHABLE_MEMORY (UINT8) 0x03
+
+/*! [Begin] no source code translation */
+/*
+ * IO Attributes
+ * The ISA IO ranges are: n000-n0FFh, n400-n4FFh, n800-n8FFh, nC00-nCFFh.
+ * The non-ISA IO ranges are: n100-n3FFh, n500-n7FFh, n900-nBFFh, nCD0-nFFFh.
+ */
+/*! [End] no source code translation !*/
+
+#define ACPI_NON_ISA_ONLY_RANGES (UINT8) 0x01
+#define ACPI_ISA_ONLY_RANGES (UINT8) 0x02
+#define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES)
+
+/* Type of translation - 1=Sparse, 0=Dense */
+
+#define ACPI_SPARSE_TRANSLATION (UINT8) 0x01
+
+/*
+ * IO Port Descriptor Decode
+ */
+#define ACPI_DECODE_10 (UINT8) 0x00 /* 10-bit IO address decode */
+#define ACPI_DECODE_16 (UINT8) 0x01 /* 16-bit IO address decode */
+
+/*
+ * Interrupt attributes - used in multiple descriptors
+ */
+
+/* Triggering */
+
+#define ACPI_LEVEL_SENSITIVE (UINT8) 0x00
+#define ACPI_EDGE_SENSITIVE (UINT8) 0x01
+
+/* Polarity */
+
+#define ACPI_ACTIVE_HIGH (UINT8) 0x00
+#define ACPI_ACTIVE_LOW (UINT8) 0x01
+#define ACPI_ACTIVE_BOTH (UINT8) 0x02
+
+/* Sharing */
+
+#define ACPI_EXCLUSIVE (UINT8) 0x00
+#define ACPI_SHARED (UINT8) 0x01
+
+/* Wake */
+
+#define ACPI_NOT_WAKE_CAPABLE (UINT8) 0x00
+#define ACPI_WAKE_CAPABLE (UINT8) 0x01
+
+/*
+ * DMA Attributes
+ */
+#define ACPI_COMPATIBILITY (UINT8) 0x00
+#define ACPI_TYPE_A (UINT8) 0x01
+#define ACPI_TYPE_B (UINT8) 0x02
+#define ACPI_TYPE_F (UINT8) 0x03
+
+#define ACPI_NOT_BUS_MASTER (UINT8) 0x00
+#define ACPI_BUS_MASTER (UINT8) 0x01
+
+#define ACPI_TRANSFER_8 (UINT8) 0x00
+#define ACPI_TRANSFER_8_16 (UINT8) 0x01
+#define ACPI_TRANSFER_16 (UINT8) 0x02
+
+/*
+ * Start Dependent Functions Priority definitions
+ */
+#define ACPI_GOOD_CONFIGURATION (UINT8) 0x00
+#define ACPI_ACCEPTABLE_CONFIGURATION (UINT8) 0x01
+#define ACPI_SUB_OPTIMAL_CONFIGURATION (UINT8) 0x02
+
+/*
+ * 16, 32 and 64-bit Address Descriptor resource types
+ */
+#define ACPI_MEMORY_RANGE (UINT8) 0x00
+#define ACPI_IO_RANGE (UINT8) 0x01
+#define ACPI_BUS_NUMBER_RANGE (UINT8) 0x02
+
+#define ACPI_ADDRESS_NOT_FIXED (UINT8) 0x00
+#define ACPI_ADDRESS_FIXED (UINT8) 0x01
+
+#define ACPI_POS_DECODE (UINT8) 0x00
+#define ACPI_SUB_DECODE (UINT8) 0x01
+
+/* Producer/Consumer */
+
+#define ACPI_PRODUCER (UINT8) 0x00
+#define ACPI_CONSUMER (UINT8) 0x01
+
+
+/*
+ * If possible, pack the following structures to byte alignment
+ */
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#pragma pack(1)
+#endif
+
+/* UUID data structures for use in vendor-defined resource descriptors */
+
+typedef struct acpi_uuid
+{
+ UINT8 Data[ACPI_UUID_LENGTH];
+} ACPI_UUID;
+
+typedef struct acpi_vendor_uuid
+{
+ UINT8 Subtype;
+ UINT8 Data[ACPI_UUID_LENGTH];
+
+} ACPI_VENDOR_UUID;
+
+/*
+ * Structures used to describe device resources
+ */
+typedef struct acpi_resource_irq
+{
+ UINT8 DescriptorLength;
+ UINT8 Triggering;
+ UINT8 Polarity;
+ UINT8 Sharable;
+ UINT8 WakeCapable;
+ UINT8 InterruptCount;
+ UINT8 Interrupts[1];
+
+} ACPI_RESOURCE_IRQ;
+
+typedef struct acpi_resource_dma
+{
+ UINT8 Type;
+ UINT8 BusMaster;
+ UINT8 Transfer;
+ UINT8 ChannelCount;
+ UINT8 Channels[1];
+
+} ACPI_RESOURCE_DMA;
+
+typedef struct acpi_resource_start_dependent
+{
+ UINT8 DescriptorLength;
+ UINT8 CompatibilityPriority;
+ UINT8 PerformanceRobustness;
+
+} ACPI_RESOURCE_START_DEPENDENT;
+
+
+/*
+ * The END_DEPENDENT_FUNCTIONS_RESOURCE struct is not
+ * needed because it has no fields
+ */
+
+
+typedef struct acpi_resource_io
+{
+ UINT8 IoDecode;
+ UINT8 Alignment;
+ UINT8 AddressLength;
+ UINT16 Minimum;
+ UINT16 Maximum;
+
+} ACPI_RESOURCE_IO;
+
+typedef struct acpi_resource_fixed_io
+{
+ UINT16 Address;
+ UINT8 AddressLength;
+
+} ACPI_RESOURCE_FIXED_IO;
+
+typedef struct acpi_resource_fixed_dma
+{
+ UINT16 RequestLines;
+ UINT16 Channels;
+ UINT8 Width;
+
+} ACPI_RESOURCE_FIXED_DMA;
+
+/* Values for Width field above */
+
+#define ACPI_DMA_WIDTH8 0
+#define ACPI_DMA_WIDTH16 1
+#define ACPI_DMA_WIDTH32 2
+#define ACPI_DMA_WIDTH64 3
+#define ACPI_DMA_WIDTH128 4
+#define ACPI_DMA_WIDTH256 5
+
+
+typedef struct acpi_resource_vendor
+{
+ UINT16 ByteLength;
+ UINT8 ByteData[1];
+
+} ACPI_RESOURCE_VENDOR;
+
+/* Vendor resource with UUID info (introduced in ACPI 3.0) */
+
+typedef struct acpi_resource_vendor_typed
+{
+ UINT16 ByteLength;
+ UINT8 UuidSubtype;
+ UINT8 Uuid[ACPI_UUID_LENGTH];
+ UINT8 ByteData[1];
+
+} ACPI_RESOURCE_VENDOR_TYPED;
+
+typedef struct acpi_resource_end_tag
+{
+ UINT8 Checksum;
+
+} ACPI_RESOURCE_END_TAG;
+
+typedef struct acpi_resource_memory24
+{
+ UINT8 WriteProtect;
+ UINT16 Minimum;
+ UINT16 Maximum;
+ UINT16 Alignment;
+ UINT16 AddressLength;
+
+} ACPI_RESOURCE_MEMORY24;
+
+typedef struct acpi_resource_memory32
+{
+ UINT8 WriteProtect;
+ UINT32 Minimum;
+ UINT32 Maximum;
+ UINT32 Alignment;
+ UINT32 AddressLength;
+
+} ACPI_RESOURCE_MEMORY32;
+
+typedef struct acpi_resource_fixed_memory32
+{
+ UINT8 WriteProtect;
+ UINT32 Address;
+ UINT32 AddressLength;
+
+} ACPI_RESOURCE_FIXED_MEMORY32;
+
+typedef struct acpi_memory_attribute
+{
+ UINT8 WriteProtect;
+ UINT8 Caching;
+ UINT8 RangeType;
+ UINT8 Translation;
+
+} ACPI_MEMORY_ATTRIBUTE;
+
+typedef struct acpi_io_attribute
+{
+ UINT8 RangeType;
+ UINT8 Translation;
+ UINT8 TranslationType;
+ UINT8 Reserved1;
+
+} ACPI_IO_ATTRIBUTE;
+
+typedef union acpi_resource_attribute
+{
+ ACPI_MEMORY_ATTRIBUTE Mem;
+ ACPI_IO_ATTRIBUTE Io;
+
+ /* Used for the *WordSpace macros */
+
+ UINT8 TypeSpecific;
+
+} ACPI_RESOURCE_ATTRIBUTE;
+
+typedef struct acpi_resource_source
+{
+ UINT8 Index;
+ UINT16 StringLength;
+ char *StringPtr;
+
+} ACPI_RESOURCE_SOURCE;
+
+/* Fields common to all address descriptors, 16/32/64 bit */
+
+#define ACPI_RESOURCE_ADDRESS_COMMON \
+ UINT8 ResourceType; \
+ UINT8 ProducerConsumer; \
+ UINT8 Decode; \
+ UINT8 MinAddressFixed; \
+ UINT8 MaxAddressFixed; \
+ ACPI_RESOURCE_ATTRIBUTE Info;
+
+typedef struct acpi_address16_attribute
+{
+ UINT16 Granularity;
+ UINT16 Minimum;
+ UINT16 Maximum;
+ UINT16 TranslationOffset;
+ UINT16 AddressLength;
+
+} ACPI_ADDRESS16_ATTRIBUTE;
+
+typedef struct acpi_address32_attribute
+{
+ UINT32 Granularity;
+ UINT32 Minimum;
+ UINT32 Maximum;
+ UINT32 TranslationOffset;
+ UINT32 AddressLength;
+
+} ACPI_ADDRESS32_ATTRIBUTE;
+
+typedef struct acpi_address64_attribute
+{
+ UINT64 Granularity;
+ UINT64 Minimum;
+ UINT64 Maximum;
+ UINT64 TranslationOffset;
+ UINT64 AddressLength;
+
+} ACPI_ADDRESS64_ATTRIBUTE;
+
+typedef struct acpi_resource_address
+{
+ ACPI_RESOURCE_ADDRESS_COMMON
+
+} ACPI_RESOURCE_ADDRESS;
+
+typedef struct acpi_resource_address16
+{
+ ACPI_RESOURCE_ADDRESS_COMMON
+ ACPI_ADDRESS16_ATTRIBUTE Address;
+ ACPI_RESOURCE_SOURCE ResourceSource;
+
+} ACPI_RESOURCE_ADDRESS16;
+
+typedef struct acpi_resource_address32
+{
+ ACPI_RESOURCE_ADDRESS_COMMON
+ ACPI_ADDRESS32_ATTRIBUTE Address;
+ ACPI_RESOURCE_SOURCE ResourceSource;
+
+} ACPI_RESOURCE_ADDRESS32;
+
+typedef struct acpi_resource_address64
+{
+ ACPI_RESOURCE_ADDRESS_COMMON
+ ACPI_ADDRESS64_ATTRIBUTE Address;
+ ACPI_RESOURCE_SOURCE ResourceSource;
+
+} ACPI_RESOURCE_ADDRESS64;
+
+typedef struct acpi_resource_extended_address64
+{
+ ACPI_RESOURCE_ADDRESS_COMMON
+ UINT8 RevisionID;
+ ACPI_ADDRESS64_ATTRIBUTE Address;
+ UINT64 TypeSpecific;
+
+} ACPI_RESOURCE_EXTENDED_ADDRESS64;
+
+typedef struct acpi_resource_extended_irq
+{
+ UINT8 ProducerConsumer;
+ UINT8 Triggering;
+ UINT8 Polarity;
+ UINT8 Sharable;
+ UINT8 WakeCapable;
+ UINT8 InterruptCount;
+ ACPI_RESOURCE_SOURCE ResourceSource;
+ UINT32 Interrupts[1];
+
+} ACPI_RESOURCE_EXTENDED_IRQ;
+
+typedef struct acpi_resource_generic_register
+{
+ UINT8 SpaceId;
+ UINT8 BitWidth;
+ UINT8 BitOffset;
+ UINT8 AccessSize;
+ UINT64 Address;
+
+} ACPI_RESOURCE_GENERIC_REGISTER;
+
+typedef struct acpi_resource_gpio
+{
+ UINT8 RevisionId;
+ UINT8 ConnectionType;
+ UINT8 ProducerConsumer; /* For values, see Producer/Consumer above */
+ UINT8 PinConfig;
+ UINT8 Sharable; /* For values, see Interrupt Attributes above */
+ UINT8 WakeCapable; /* For values, see Interrupt Attributes above */
+ UINT8 IoRestriction;
+ UINT8 Triggering; /* For values, see Interrupt Attributes above */
+ UINT8 Polarity; /* For values, see Interrupt Attributes above */
+ UINT16 DriveStrength;
+ UINT16 DebounceTimeout;
+ UINT16 PinTableLength;
+ UINT16 VendorLength;
+ ACPI_RESOURCE_SOURCE ResourceSource;
+ UINT16 *PinTable;
+ UINT8 *VendorData;
+
+} ACPI_RESOURCE_GPIO;
+
+/* Values for GPIO ConnectionType field above */
+
+#define ACPI_RESOURCE_GPIO_TYPE_INT 0
+#define ACPI_RESOURCE_GPIO_TYPE_IO 1
+
+/* Values for PinConfig field above */
+
+#define ACPI_PIN_CONFIG_DEFAULT 0
+#define ACPI_PIN_CONFIG_PULLUP 1
+#define ACPI_PIN_CONFIG_PULLDOWN 2
+#define ACPI_PIN_CONFIG_NOPULL 3
+
+/* Values for IoRestriction field above */
+
+#define ACPI_IO_RESTRICT_NONE 0
+#define ACPI_IO_RESTRICT_INPUT 1
+#define ACPI_IO_RESTRICT_OUTPUT 2
+#define ACPI_IO_RESTRICT_NONE_PRESERVE 3
+
+
+/* Common structure for I2C, SPI, and UART serial descriptors */
+
+#define ACPI_RESOURCE_SERIAL_COMMON \
+ UINT8 RevisionId; \
+ UINT8 Type; \
+ UINT8 ProducerConsumer; /* For values, see Producer/Consumer above */\
+ UINT8 SlaveMode; \
+ UINT8 TypeRevisionId; \
+ UINT16 TypeDataLength; \
+ UINT16 VendorLength; \
+ ACPI_RESOURCE_SOURCE ResourceSource; \
+ UINT8 *VendorData;
+
+typedef struct acpi_resource_common_serialbus
+{
+ ACPI_RESOURCE_SERIAL_COMMON
+
+} ACPI_RESOURCE_COMMON_SERIALBUS;
+
+/* Values for the Type field above */
+
+#define ACPI_RESOURCE_SERIAL_TYPE_I2C 1
+#define ACPI_RESOURCE_SERIAL_TYPE_SPI 2
+#define ACPI_RESOURCE_SERIAL_TYPE_UART 3
+
+/* Values for SlaveMode field above */
+
+#define ACPI_CONTROLLER_INITIATED 0
+#define ACPI_DEVICE_INITIATED 1
+
+
+typedef struct acpi_resource_i2c_serialbus
+{
+ ACPI_RESOURCE_SERIAL_COMMON
+ UINT8 AccessMode;
+ UINT16 SlaveAddress;
+ UINT32 ConnectionSpeed;
+
+} ACPI_RESOURCE_I2C_SERIALBUS;
+
+/* Values for AccessMode field above */
+
+#define ACPI_I2C_7BIT_MODE 0
+#define ACPI_I2C_10BIT_MODE 1
+
+
+typedef struct acpi_resource_spi_serialbus
+{
+ ACPI_RESOURCE_SERIAL_COMMON
+ UINT8 WireMode;
+ UINT8 DevicePolarity;
+ UINT8 DataBitLength;
+ UINT8 ClockPhase;
+ UINT8 ClockPolarity;
+ UINT16 DeviceSelection;
+ UINT32 ConnectionSpeed;
+
+} ACPI_RESOURCE_SPI_SERIALBUS;
+
+/* Values for WireMode field above */
+
+#define ACPI_SPI_4WIRE_MODE 0
+#define ACPI_SPI_3WIRE_MODE 1
+
+/* Values for DevicePolarity field above */
+
+#define ACPI_SPI_ACTIVE_LOW 0
+#define ACPI_SPI_ACTIVE_HIGH 1
+
+/* Values for ClockPhase field above */
+
+#define ACPI_SPI_FIRST_PHASE 0
+#define ACPI_SPI_SECOND_PHASE 1
+
+/* Values for ClockPolarity field above */
+
+#define ACPI_SPI_START_LOW 0
+#define ACPI_SPI_START_HIGH 1
+
+
+typedef struct acpi_resource_uart_serialbus
+{
+ ACPI_RESOURCE_SERIAL_COMMON
+ UINT8 Endian;
+ UINT8 DataBits;
+ UINT8 StopBits;
+ UINT8 FlowControl;
+ UINT8 Parity;
+ UINT8 LinesEnabled;
+ UINT16 RxFifoSize;
+ UINT16 TxFifoSize;
+ UINT32 DefaultBaudRate;
+
+} ACPI_RESOURCE_UART_SERIALBUS;
+
+/* Values for Endian field above */
+
+#define ACPI_UART_LITTLE_ENDIAN 0
+#define ACPI_UART_BIG_ENDIAN 1
+
+/* Values for DataBits field above */
+
+#define ACPI_UART_5_DATA_BITS 0
+#define ACPI_UART_6_DATA_BITS 1
+#define ACPI_UART_7_DATA_BITS 2
+#define ACPI_UART_8_DATA_BITS 3
+#define ACPI_UART_9_DATA_BITS 4
+
+/* Values for StopBits field above */
+
+#define ACPI_UART_NO_STOP_BITS 0
+#define ACPI_UART_1_STOP_BIT 1
+#define ACPI_UART_1P5_STOP_BITS 2
+#define ACPI_UART_2_STOP_BITS 3
+
+/* Values for FlowControl field above */
+
+#define ACPI_UART_FLOW_CONTROL_NONE 0
+#define ACPI_UART_FLOW_CONTROL_HW 1
+#define ACPI_UART_FLOW_CONTROL_XON_XOFF 2
+
+/* Values for Parity field above */
+
+#define ACPI_UART_PARITY_NONE 0
+#define ACPI_UART_PARITY_EVEN 1
+#define ACPI_UART_PARITY_ODD 2
+#define ACPI_UART_PARITY_MARK 3
+#define ACPI_UART_PARITY_SPACE 4
+
+/* Values for LinesEnabled bitfield above */
+
+#define ACPI_UART_CARRIER_DETECT (1<<2)
+#define ACPI_UART_RING_INDICATOR (1<<3)
+#define ACPI_UART_DATA_SET_READY (1<<4)
+#define ACPI_UART_DATA_TERMINAL_READY (1<<5)
+#define ACPI_UART_CLEAR_TO_SEND (1<<6)
+#define ACPI_UART_REQUEST_TO_SEND (1<<7)
+
+
+/* ACPI_RESOURCE_TYPEs */
+
+#define ACPI_RESOURCE_TYPE_IRQ 0
+#define ACPI_RESOURCE_TYPE_DMA 1
+#define ACPI_RESOURCE_TYPE_START_DEPENDENT 2
+#define ACPI_RESOURCE_TYPE_END_DEPENDENT 3
+#define ACPI_RESOURCE_TYPE_IO 4
+#define ACPI_RESOURCE_TYPE_FIXED_IO 5
+#define ACPI_RESOURCE_TYPE_VENDOR 6
+#define ACPI_RESOURCE_TYPE_END_TAG 7
+#define ACPI_RESOURCE_TYPE_MEMORY24 8
+#define ACPI_RESOURCE_TYPE_MEMORY32 9
+#define ACPI_RESOURCE_TYPE_FIXED_MEMORY32 10
+#define ACPI_RESOURCE_TYPE_ADDRESS16 11
+#define ACPI_RESOURCE_TYPE_ADDRESS32 12
+#define ACPI_RESOURCE_TYPE_ADDRESS64 13
+#define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 14 /* ACPI 3.0 */
+#define ACPI_RESOURCE_TYPE_EXTENDED_IRQ 15
+#define ACPI_RESOURCE_TYPE_GENERIC_REGISTER 16
+#define ACPI_RESOURCE_TYPE_GPIO 17 /* ACPI 5.0 */
+#define ACPI_RESOURCE_TYPE_FIXED_DMA 18 /* ACPI 5.0 */
+#define ACPI_RESOURCE_TYPE_SERIAL_BUS 19 /* ACPI 5.0 */
+#define ACPI_RESOURCE_TYPE_MAX 19
+
+/* Master union for resource descriptors */
+
+typedef union acpi_resource_data
+{
+ ACPI_RESOURCE_IRQ Irq;
+ ACPI_RESOURCE_DMA Dma;
+ ACPI_RESOURCE_START_DEPENDENT StartDpf;
+ ACPI_RESOURCE_IO Io;
+ ACPI_RESOURCE_FIXED_IO FixedIo;
+ ACPI_RESOURCE_FIXED_DMA FixedDma;
+ ACPI_RESOURCE_VENDOR Vendor;
+ ACPI_RESOURCE_VENDOR_TYPED VendorTyped;
+ ACPI_RESOURCE_END_TAG EndTag;
+ ACPI_RESOURCE_MEMORY24 Memory24;
+ ACPI_RESOURCE_MEMORY32 Memory32;
+ ACPI_RESOURCE_FIXED_MEMORY32 FixedMemory32;
+ ACPI_RESOURCE_ADDRESS16 Address16;
+ ACPI_RESOURCE_ADDRESS32 Address32;
+ ACPI_RESOURCE_ADDRESS64 Address64;
+ ACPI_RESOURCE_EXTENDED_ADDRESS64 ExtAddress64;
+ ACPI_RESOURCE_EXTENDED_IRQ ExtendedIrq;
+ ACPI_RESOURCE_GENERIC_REGISTER GenericReg;
+ ACPI_RESOURCE_GPIO Gpio;
+ ACPI_RESOURCE_I2C_SERIALBUS I2cSerialBus;
+ ACPI_RESOURCE_SPI_SERIALBUS SpiSerialBus;
+ ACPI_RESOURCE_UART_SERIALBUS UartSerialBus;
+ ACPI_RESOURCE_COMMON_SERIALBUS CommonSerialBus;
+
+ /* Common fields */
+
+ ACPI_RESOURCE_ADDRESS Address; /* Common 16/32/64 address fields */
+
+} ACPI_RESOURCE_DATA;
+
+
+/* Common resource header */
+
+typedef struct acpi_resource
+{
+ UINT32 Type;
+ UINT32 Length;
+ ACPI_RESOURCE_DATA Data;
+
+} ACPI_RESOURCE;
+
+/* restore default alignment */
+
+#pragma pack()
+
+
+#define ACPI_RS_SIZE_NO_DATA 8 /* Id + Length fields */
+#define ACPI_RS_SIZE_MIN (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (12)
+#define ACPI_RS_SIZE(Type) (UINT32) (ACPI_RS_SIZE_NO_DATA + sizeof (Type))
+
+/* Macro for walking resource templates with multiple descriptors */
+
+#define ACPI_NEXT_RESOURCE(Res) \
+ ACPI_ADD_PTR (ACPI_RESOURCE, (Res), (Res)->Length)
+
+
+typedef struct acpi_pci_routing_table
+{
+ UINT32 Length;
+ UINT32 Pin;
+ UINT64 Address; /* here for 64-bit alignment */
+ UINT32 SourceIndex;
+ char Source[4]; /* pad to 64 bits so sizeof() works in all cases */
+
+} ACPI_PCI_ROUTING_TABLE;
+
+#endif /* __ACRESTYP_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acstruct.h b/usr/src/boot/sys/contrib/dev/acpica/include/acstruct.h
new file mode 100644
index 0000000000..10dc371ed9
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acstruct.h
@@ -0,0 +1,269 @@
+/******************************************************************************
+ *
+ * Name: acstruct.h - Internal structs
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACSTRUCT_H__
+#define __ACSTRUCT_H__
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+/*****************************************************************************
+ *
+ * Tree walking typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/*
+ * Walk state - current state of a parse tree walk. Used for both a leisurely
+ * stroll through the tree (for whatever reason), and for control method
+ * execution.
+ */
+#define ACPI_NEXT_OP_DOWNWARD 1
+#define ACPI_NEXT_OP_UPWARD 2
+
+/*
+ * Groups of definitions for WalkType used for different implementations of
+ * walkers (never simultaneously) - flags for interpreter:
+ */
+#define ACPI_WALK_NON_METHOD 0
+#define ACPI_WALK_METHOD 0x01
+#define ACPI_WALK_METHOD_RESTART 0x02
+
+
+typedef struct acpi_walk_state
+{
+ struct acpi_walk_state *Next; /* Next WalkState in list */
+ UINT8 DescriptorType; /* To differentiate various internal objs */
+ UINT8 WalkType;
+ UINT16 Opcode; /* Current AML opcode */
+ UINT8 NextOpInfo; /* Info about NextOp */
+ UINT8 NumOperands; /* Stack pointer for Operands[] array */
+ UINT8 OperandIndex; /* Index into operand stack, to be used by AcpiDsObjStackPush */
+ ACPI_OWNER_ID OwnerId; /* Owner of objects created during the walk */
+ BOOLEAN LastPredicate; /* Result of last predicate */
+ UINT8 CurrentResult;
+ UINT8 ReturnUsed;
+ UINT8 ScopeDepth;
+ UINT8 PassNumber; /* Parse pass during table load */
+ BOOLEAN NamespaceOverride; /* Override existing objects */
+ UINT8 ResultSize; /* Total elements for the result stack */
+ UINT8 ResultCount; /* Current number of occupied elements of result stack */
+ UINT8 *Aml;
+ UINT32 ArgTypes;
+ UINT32 MethodBreakpoint; /* For single stepping */
+ UINT32 UserBreakpoint; /* User AML breakpoint */
+ UINT32 ParseFlags;
+
+ ACPI_PARSE_STATE ParserState; /* Current state of parser */
+ UINT32 PrevArgTypes;
+ UINT32 ArgCount; /* push for fixed or var args */
+
+ struct acpi_namespace_node Arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */
+ struct acpi_namespace_node LocalVariables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */
+ union acpi_operand_object *Operands[ACPI_OBJ_NUM_OPERANDS + 1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
+ union acpi_operand_object **Params;
+
+ UINT8 *AmlLastWhile;
+ union acpi_operand_object **CallerReturnDesc;
+ ACPI_GENERIC_STATE *ControlState; /* List of control states (nested IFs) */
+ struct acpi_namespace_node *DeferredNode; /* Used when executing deferred opcodes */
+ union acpi_operand_object *ImplicitReturnObj;
+ struct acpi_namespace_node *MethodCallNode; /* Called method Node*/
+ ACPI_PARSE_OBJECT *MethodCallOp; /* MethodCall Op if running a method */
+ union acpi_operand_object *MethodDesc; /* Method descriptor if running a method */
+ struct acpi_namespace_node *MethodNode; /* Method node if running a method. */
+ ACPI_PARSE_OBJECT *Op; /* Current parser op */
+ const ACPI_OPCODE_INFO *OpInfo; /* Info on current opcode */
+ ACPI_PARSE_OBJECT *Origin; /* Start of walk [Obsolete] */
+ union acpi_operand_object *ResultObj;
+ ACPI_GENERIC_STATE *Results; /* Stack of accumulated results */
+ union acpi_operand_object *ReturnDesc; /* Return object, if any */
+ ACPI_GENERIC_STATE *ScopeInfo; /* Stack of nested scopes */
+ ACPI_PARSE_OBJECT *PrevOp; /* Last op that was processed */
+ ACPI_PARSE_OBJECT *NextOp; /* next op to be processed */
+ ACPI_THREAD_STATE *Thread;
+ ACPI_PARSE_DOWNWARDS DescendingCallback;
+ ACPI_PARSE_UPWARDS AscendingCallback;
+
+} ACPI_WALK_STATE;
+
+
+/* Info used by AcpiNsInitializeObjects and AcpiDsInitializeObjects */
+
+typedef struct acpi_init_walk_info
+{
+ UINT32 TableIndex;
+ UINT32 ObjectCount;
+ UINT32 MethodCount;
+ UINT32 SerialMethodCount;
+ UINT32 NonSerialMethodCount;
+ UINT32 SerializedMethodCount;
+ UINT32 DeviceCount;
+ UINT32 OpRegionCount;
+ UINT32 FieldCount;
+ UINT32 BufferCount;
+ UINT32 PackageCount;
+ UINT32 OpRegionInit;
+ UINT32 FieldInit;
+ UINT32 BufferInit;
+ UINT32 PackageInit;
+ ACPI_OWNER_ID OwnerId;
+
+} ACPI_INIT_WALK_INFO;
+
+
+typedef struct acpi_get_devices_info
+{
+ ACPI_WALK_CALLBACK UserFunction;
+ void *Context;
+ char *Hid;
+
+} ACPI_GET_DEVICES_INFO;
+
+
+typedef union acpi_aml_operands
+{
+ ACPI_OPERAND_OBJECT *Operands[7];
+
+ struct
+ {
+ ACPI_OBJECT_INTEGER *Type;
+ ACPI_OBJECT_INTEGER *Code;
+ ACPI_OBJECT_INTEGER *Argument;
+
+ } Fatal;
+
+ struct
+ {
+ ACPI_OPERAND_OBJECT *Source;
+ ACPI_OBJECT_INTEGER *Index;
+ ACPI_OPERAND_OBJECT *Target;
+
+ } Index;
+
+ struct
+ {
+ ACPI_OPERAND_OBJECT *Source;
+ ACPI_OBJECT_INTEGER *Index;
+ ACPI_OBJECT_INTEGER *Length;
+ ACPI_OPERAND_OBJECT *Target;
+
+ } Mid;
+
+} ACPI_AML_OPERANDS;
+
+
+/*
+ * Structure used to pass object evaluation information and parameters.
+ * Purpose is to reduce CPU stack use.
+ */
+typedef struct acpi_evaluate_info
+{
+ /* The first 3 elements are passed by the caller to AcpiNsEvaluate */
+
+ ACPI_NAMESPACE_NODE *PrefixNode; /* Input: starting node */
+ char *RelativePathname; /* Input: path relative to PrefixNode */
+ ACPI_OPERAND_OBJECT **Parameters; /* Input: argument list */
+
+ ACPI_NAMESPACE_NODE *Node; /* Resolved node (PrefixNode:RelativePathname) */
+ ACPI_OPERAND_OBJECT *ObjDesc; /* Object attached to the resolved node */
+ char *FullPathname; /* Full pathname of the resolved node */
+
+ const ACPI_PREDEFINED_INFO *Predefined; /* Used if Node is a predefined name */
+ ACPI_OPERAND_OBJECT *ReturnObject; /* Object returned from the evaluation */
+ union acpi_operand_object *ParentPackage; /* Used if return object is a Package */
+
+ UINT32 ReturnFlags; /* Used for return value analysis */
+ UINT32 ReturnBtype; /* Bitmapped type of the returned object */
+ UINT16 ParamCount; /* Count of the input argument list */
+ UINT8 PassNumber; /* Parser pass number */
+ UINT8 ReturnObjectType; /* Object type of the returned object */
+ UINT8 NodeFlags; /* Same as Node->Flags */
+ UINT8 Flags; /* General flags */
+
+} ACPI_EVALUATE_INFO;
+
+/* Values for Flags above */
+
+#define ACPI_IGNORE_RETURN_VALUE 1
+
+/* Defines for ReturnFlags field above */
+
+#define ACPI_OBJECT_REPAIRED 1
+#define ACPI_OBJECT_WRAPPED 2
+
+
+/* Info used by AcpiNsInitializeDevices */
+
+typedef struct acpi_device_walk_info
+{
+ ACPI_TABLE_DESC *TableDesc;
+ ACPI_EVALUATE_INFO *EvaluateInfo;
+ UINT32 DeviceCount;
+ UINT32 Num_STA;
+ UINT32 Num_INI;
+
+} ACPI_DEVICE_WALK_INFO;
+
+
+/* TBD: [Restructure] Merge with struct above */
+
+typedef struct acpi_walk_info
+{
+ UINT32 DebugLevel;
+ UINT32 Count;
+ ACPI_OWNER_ID OwnerId;
+ UINT8 DisplayType;
+
+} ACPI_WALK_INFO;
+
+/* Display Types */
+
+#define ACPI_DISPLAY_SUMMARY (UINT8) 0
+#define ACPI_DISPLAY_OBJECTS (UINT8) 1
+#define ACPI_DISPLAY_MASK (UINT8) 1
+
+#define ACPI_DISPLAY_SHORT (UINT8) 2
+
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actables.h b/usr/src/boot/sys/contrib/dev/acpica/include/actables.h
new file mode 100644
index 0000000000..0f8fdd5053
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actables.h
@@ -0,0 +1,265 @@
+/******************************************************************************
+ *
+ * Name: actables.h - ACPI table management
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTABLES_H__
+#define __ACTABLES_H__
+
+
+ACPI_STATUS
+AcpiAllocateRootTable (
+ UINT32 InitialTableCount);
+
+/*
+ * tbxfroot - Root pointer utilities
+ */
+UINT32
+AcpiTbGetRsdpLength (
+ ACPI_TABLE_RSDP *Rsdp);
+
+ACPI_STATUS
+AcpiTbValidateRsdp (
+ ACPI_TABLE_RSDP *Rsdp);
+
+UINT8 *
+AcpiTbScanMemoryForRsdp (
+ UINT8 *StartAddress,
+ UINT32 Length);
+
+
+/*
+ * tbdata - table data structure management
+ */
+ACPI_STATUS
+AcpiTbGetNextTableDescriptor (
+ UINT32 *TableIndex,
+ ACPI_TABLE_DESC **TableDesc);
+
+void
+AcpiTbInitTableDescriptor (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags,
+ ACPI_TABLE_HEADER *Table);
+
+ACPI_STATUS
+AcpiTbAcquireTempTable (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags);
+
+void
+AcpiTbReleaseTempTable (
+ ACPI_TABLE_DESC *TableDesc);
+
+ACPI_STATUS
+AcpiTbValidateTempTable (
+ ACPI_TABLE_DESC *TableDesc);
+
+ACPI_STATUS
+AcpiTbVerifyTempTable (
+ ACPI_TABLE_DESC *TableDesc,
+ char *Signature);
+
+BOOLEAN
+AcpiTbIsTableLoaded (
+ UINT32 TableIndex);
+
+void
+AcpiTbSetTableLoadedFlag (
+ UINT32 TableIndex,
+ BOOLEAN IsLoaded);
+
+
+/*
+ * tbfadt - FADT parse/convert/validate
+ */
+void
+AcpiTbParseFadt (
+ UINT32 TableIndex);
+
+void
+AcpiTbCreateLocalFadt (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length);
+
+
+/*
+ * tbfind - find ACPI table
+ */
+ACPI_STATUS
+AcpiTbFindTable (
+ char *Signature,
+ char *OemId,
+ char *OemTableId,
+ UINT32 *TableIndex);
+
+
+/*
+ * tbinstal - Table removal and deletion
+ */
+ACPI_STATUS
+AcpiTbResizeRootTableList (
+ void);
+
+ACPI_STATUS
+AcpiTbValidateTable (
+ ACPI_TABLE_DESC *TableDesc);
+
+void
+AcpiTbInvalidateTable (
+ ACPI_TABLE_DESC *TableDesc);
+
+void
+AcpiTbOverrideTable (
+ ACPI_TABLE_DESC *OldTableDesc);
+
+ACPI_STATUS
+AcpiTbAcquireTable (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_TABLE_HEADER **TablePtr,
+ UINT32 *TableLength,
+ UINT8 *TableFlags);
+
+void
+AcpiTbReleaseTable (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 TableLength,
+ UINT8 TableFlags);
+
+ACPI_STATUS
+AcpiTbInstallStandardTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT8 Flags,
+ BOOLEAN Reload,
+ BOOLEAN Override,
+ UINT32 *TableIndex);
+
+void
+AcpiTbUninstallTable (
+ ACPI_TABLE_DESC *TableDesc);
+
+void
+AcpiTbTerminate (
+ void);
+
+ACPI_STATUS
+AcpiTbDeleteNamespaceByOwner (
+ UINT32 TableIndex);
+
+ACPI_STATUS
+AcpiTbAllocateOwnerId (
+ UINT32 TableIndex);
+
+ACPI_STATUS
+AcpiTbReleaseOwnerId (
+ UINT32 TableIndex);
+
+ACPI_STATUS
+AcpiTbGetOwnerId (
+ UINT32 TableIndex,
+ ACPI_OWNER_ID *OwnerId);
+
+
+/*
+ * tbutils - table manager utilities
+ */
+ACPI_STATUS
+AcpiTbInitializeFacs (
+ void);
+
+BOOLEAN
+AcpiTbTablesLoaded (
+ void);
+
+void
+AcpiTbPrintTableHeader(
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_TABLE_HEADER *Header);
+
+UINT8
+AcpiTbChecksum (
+ UINT8 *Buffer,
+ UINT32 Length);
+
+ACPI_STATUS
+AcpiTbVerifyChecksum (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length);
+
+void
+AcpiTbCheckDsdtHeader (
+ void);
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex);
+
+void
+AcpiTbInstallTableWithOverride (
+ ACPI_TABLE_DESC *NewTableDesc,
+ BOOLEAN Override,
+ UINT32 *TableIndex);
+
+ACPI_STATUS
+AcpiTbInstallFixedTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ char *Signature,
+ UINT32 *TableIndex);
+
+ACPI_STATUS
+AcpiTbParseRootTable (
+ ACPI_PHYSICAL_ADDRESS RsdpAddress);
+
+BOOLEAN
+AcpiIsValidSignature (
+ char *Signature);
+
+
+/*
+ * tbxfload
+ */
+ACPI_STATUS
+AcpiTbLoadNamespace (
+ void);
+
+#endif /* __ACTABLES_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actbl.h b/usr/src/boot/sys/contrib/dev/acpica/include/actbl.h
new file mode 100644
index 0000000000..f1c34962cf
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actbl.h
@@ -0,0 +1,452 @@
+/******************************************************************************
+ *
+ * Name: actbl.h - Basic ACPI Table Definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTBL_H__
+#define __ACTBL_H__
+
+
+/*******************************************************************************
+ *
+ * Fundamental ACPI tables
+ *
+ * This file contains definitions for the ACPI tables that are directly consumed
+ * by ACPICA. All other tables are consumed by the OS-dependent ACPI-related
+ * device drivers and other OS support code.
+ *
+ * The RSDP and FACS do not use the common ACPI table header. All other ACPI
+ * tables use the header.
+ *
+ ******************************************************************************/
+
+
+/*
+ * Values for description table header signatures for tables defined in this
+ * file. Useful because they make it more difficult to inadvertently type in
+ * the wrong signature.
+ */
+#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */
+#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
+#define ACPI_SIG_FACS "FACS" /* Firmware ACPI Control Structure */
+#define ACPI_SIG_OSDT "OSDT" /* Override System Description Table */
+#define ACPI_SIG_PSDT "PSDT" /* Persistent System Description Table */
+#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Pointer */
+#define ACPI_SIG_RSDT "RSDT" /* Root System Description Table */
+#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
+#define ACPI_SIG_SSDT "SSDT" /* Secondary System Description Table */
+#define ACPI_RSDP_NAME "RSDP" /* Short name for RSDP, not signature */
+
+
+/*
+ * All tables and structures must be byte-packed to match the ACPI
+ * specification, since the tables are provided by the system BIOS
+ */
+#pragma pack(1)
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+
+/*******************************************************************************
+ *
+ * Master ACPI Table Header. This common header is used by all ACPI tables
+ * except the RSDP and FACS.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_header
+{
+ char Signature[ACPI_NAME_SIZE]; /* ASCII table signature */
+ UINT32 Length; /* Length of table in bytes, including this header */
+ UINT8 Revision; /* ACPI Specification minor version number */
+ UINT8 Checksum; /* To make sum of entire table == 0 */
+ char OemId[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
+ char OemTableId[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
+ UINT32 OemRevision; /* OEM revision number */
+ char AslCompilerId[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */
+ UINT32 AslCompilerRevision; /* ASL compiler version */
+
+} ACPI_TABLE_HEADER;
+
+
+/*******************************************************************************
+ *
+ * GAS - Generic Address Structure (ACPI 2.0+)
+ *
+ * Note: Since this structure is used in the ACPI tables, it is byte aligned.
+ * If misaligned access is not supported by the hardware, accesses to the
+ * 64-bit Address field must be performed with care.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_generic_address
+{
+ UINT8 SpaceId; /* Address space where struct or register exists */
+ UINT8 BitWidth; /* Size in bits of given register */
+ UINT8 BitOffset; /* Bit offset within the register */
+ UINT8 AccessWidth; /* Minimum Access size (ACPI 3.0) */
+ UINT64 Address; /* 64-bit address of struct or register */
+
+} ACPI_GENERIC_ADDRESS;
+
+
+/*******************************************************************************
+ *
+ * RSDP - Root System Description Pointer (Signature is "RSD PTR ")
+ * Version 2
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_rsdp
+{
+ char Signature[8]; /* ACPI signature, contains "RSD PTR " */
+ UINT8 Checksum; /* ACPI 1.0 checksum */
+ char OemId[ACPI_OEM_ID_SIZE]; /* OEM identification */
+ UINT8 Revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
+ UINT32 RsdtPhysicalAddress; /* 32-bit physical address of the RSDT */
+ UINT32 Length; /* Table length in bytes, including header (ACPI 2.0+) */
+ UINT64 XsdtPhysicalAddress; /* 64-bit physical address of the XSDT (ACPI 2.0+) */
+ UINT8 ExtendedChecksum; /* Checksum of entire table (ACPI 2.0+) */
+ UINT8 Reserved[3]; /* Reserved, must be zero */
+
+} ACPI_TABLE_RSDP;
+
+/* Standalone struct for the ACPI 1.0 RSDP */
+
+typedef struct acpi_rsdp_common
+{
+ char Signature[8];
+ UINT8 Checksum;
+ char OemId[ACPI_OEM_ID_SIZE];
+ UINT8 Revision;
+ UINT32 RsdtPhysicalAddress;
+
+} ACPI_RSDP_COMMON;
+
+/* Standalone struct for the extended part of the RSDP (ACPI 2.0+) */
+
+typedef struct acpi_rsdp_extension
+{
+ UINT32 Length;
+ UINT64 XsdtPhysicalAddress;
+ UINT8 ExtendedChecksum;
+ UINT8 Reserved[3];
+
+} ACPI_RSDP_EXTENSION;
+
+
+/*******************************************************************************
+ *
+ * RSDT/XSDT - Root System Description Tables
+ * Version 1 (both)
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_rsdt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 TableOffsetEntry[1]; /* Array of pointers to ACPI tables */
+
+} ACPI_TABLE_RSDT;
+
+typedef struct acpi_table_xsdt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 TableOffsetEntry[1]; /* Array of pointers to ACPI tables */
+
+} ACPI_TABLE_XSDT;
+
+#define ACPI_RSDT_ENTRY_SIZE (sizeof (UINT32))
+#define ACPI_XSDT_ENTRY_SIZE (sizeof (UINT64))
+
+
+/*******************************************************************************
+ *
+ * FACS - Firmware ACPI Control Structure (FACS)
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_facs
+{
+ char Signature[4]; /* ASCII table signature */
+ UINT32 Length; /* Length of structure, in bytes */
+ UINT32 HardwareSignature; /* Hardware configuration signature */
+ UINT32 FirmwareWakingVector; /* 32-bit physical address of the Firmware Waking Vector */
+ UINT32 GlobalLock; /* Global Lock for shared hardware resources */
+ UINT32 Flags;
+ UINT64 XFirmwareWakingVector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */
+ UINT8 Version; /* Version of this table (ACPI 2.0+) */
+ UINT8 Reserved[3]; /* Reserved, must be zero */
+ UINT32 OspmFlags; /* Flags to be set by OSPM (ACPI 4.0) */
+ UINT8 Reserved1[24]; /* Reserved, must be zero */
+
+} ACPI_TABLE_FACS;
+
+/* Masks for GlobalLock flag field above */
+
+#define ACPI_GLOCK_PENDING (1) /* 00: Pending global lock ownership */
+#define ACPI_GLOCK_OWNED (1<<1) /* 01: Global lock is owned */
+
+/* Masks for Flags field above */
+
+#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */
+#define ACPI_FACS_64BIT_WAKE (1<<1) /* 01: 64-bit wake vector supported (ACPI 4.0) */
+
+/* Masks for OspmFlags field above */
+
+#define ACPI_FACS_64BIT_ENVIRONMENT (1) /* 00: 64-bit wake environment is required (ACPI 4.0) */
+
+
+/*******************************************************************************
+ *
+ * FADT - Fixed ACPI Description Table (Signature "FACP")
+ * Version 4
+ *
+ ******************************************************************************/
+
+/* Fields common to all versions of the FADT */
+
+typedef struct acpi_table_fadt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Facs; /* 32-bit physical address of FACS */
+ UINT32 Dsdt; /* 32-bit physical address of DSDT */
+ UINT8 Model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */
+ UINT8 PreferredProfile; /* Conveys preferred power management profile to OSPM. */
+ UINT16 SciInterrupt; /* System vector of SCI interrupt */
+ UINT32 SmiCommand; /* 32-bit Port address of SMI command port */
+ UINT8 AcpiEnable; /* Value to write to SMI_CMD to enable ACPI */
+ UINT8 AcpiDisable; /* Value to write to SMI_CMD to disable ACPI */
+ UINT8 S4BiosRequest; /* Value to write to SMI_CMD to enter S4BIOS state */
+ UINT8 PstateControl; /* Processor performance state control*/
+ UINT32 Pm1aEventBlock; /* 32-bit port address of Power Mgt 1a Event Reg Blk */
+ UINT32 Pm1bEventBlock; /* 32-bit port address of Power Mgt 1b Event Reg Blk */
+ UINT32 Pm1aControlBlock; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
+ UINT32 Pm1bControlBlock; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
+ UINT32 Pm2ControlBlock; /* 32-bit port address of Power Mgt 2 Control Reg Blk */
+ UINT32 PmTimerBlock; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
+ UINT32 Gpe0Block; /* 32-bit port address of General Purpose Event 0 Reg Blk */
+ UINT32 Gpe1Block; /* 32-bit port address of General Purpose Event 1 Reg Blk */
+ UINT8 Pm1EventLength; /* Byte Length of ports at Pm1xEventBlock */
+ UINT8 Pm1ControlLength; /* Byte Length of ports at Pm1xControlBlock */
+ UINT8 Pm2ControlLength; /* Byte Length of ports at Pm2ControlBlock */
+ UINT8 PmTimerLength; /* Byte Length of ports at PmTimerBlock */
+ UINT8 Gpe0BlockLength; /* Byte Length of ports at Gpe0Block */
+ UINT8 Gpe1BlockLength; /* Byte Length of ports at Gpe1Block */
+ UINT8 Gpe1Base; /* Offset in GPE number space where GPE1 events start */
+ UINT8 CstControl; /* Support for the _CST object and C-States change notification */
+ UINT16 C2Latency; /* Worst case HW latency to enter/exit C2 state */
+ UINT16 C3Latency; /* Worst case HW latency to enter/exit C3 state */
+ UINT16 FlushSize; /* Processor memory cache line width, in bytes */
+ UINT16 FlushStride; /* Number of flush strides that need to be read */
+ UINT8 DutyOffset; /* Processor duty cycle index in processor P_CNT reg */
+ UINT8 DutyWidth; /* Processor duty cycle value bit width in P_CNT register */
+ UINT8 DayAlarm; /* Index to day-of-month alarm in RTC CMOS RAM */
+ UINT8 MonthAlarm; /* Index to month-of-year alarm in RTC CMOS RAM */
+ UINT8 Century; /* Index to century in RTC CMOS RAM */
+ UINT16 BootFlags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
+ UINT8 Reserved; /* Reserved, must be zero */
+ UINT32 Flags; /* Miscellaneous flag bits (see below for individual flags) */
+ ACPI_GENERIC_ADDRESS ResetRegister; /* 64-bit address of the Reset register */
+ UINT8 ResetValue; /* Value to write to the ResetRegister port to reset the system */
+ UINT16 ArmBootFlags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+ UINT8 MinorRevision; /* FADT Minor Revision (ACPI 5.1) */
+ UINT64 XFacs; /* 64-bit physical address of FACS */
+ UINT64 XDsdt; /* 64-bit physical address of DSDT */
+ ACPI_GENERIC_ADDRESS XPm1aEventBlock; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
+ ACPI_GENERIC_ADDRESS XPm1bEventBlock; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
+ ACPI_GENERIC_ADDRESS XPm1aControlBlock; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
+ ACPI_GENERIC_ADDRESS XPm1bControlBlock; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
+ ACPI_GENERIC_ADDRESS XPm2ControlBlock; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
+ ACPI_GENERIC_ADDRESS XPmTimerBlock; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
+ ACPI_GENERIC_ADDRESS XGpe0Block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
+ ACPI_GENERIC_ADDRESS XGpe1Block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
+ ACPI_GENERIC_ADDRESS SleepControl; /* 64-bit Sleep Control register (ACPI 5.0) */
+ ACPI_GENERIC_ADDRESS SleepStatus; /* 64-bit Sleep Status register (ACPI 5.0) */
+ UINT64 HypervisorId; /* Hypervisor Vendor ID (ACPI 6.0) */
+
+} ACPI_TABLE_FADT;
+
+
+/* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
+
+#define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */
+#define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */
+#define ACPI_FADT_NO_VGA (1<<2) /* 02: [V4] It is not safe to probe for VGA hardware */
+#define ACPI_FADT_NO_MSI (1<<3) /* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */
+#define ACPI_FADT_NO_ASPM (1<<4) /* 04: [V4] PCIe ASPM control must not be enabled */
+#define ACPI_FADT_NO_CMOS_RTC (1<<5) /* 05: [V5] No CMOS real-time clock present */
+
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
+/* Masks for FADT flags */
+
+#define ACPI_FADT_WBINVD (1) /* 00: [V1] The WBINVD instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] WBINVD flushes but does not invalidate caches */
+#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */
+#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */
+#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */
+#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */
+#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status is not in fixed register space */
+#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */
+#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
+#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */
+#define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: [V2] System reset via the FADT RESET_REG supported */
+#define ACPI_FADT_SEALED_CASE (1<<11) /* 11: [V3] No internal expansion capabilities and case is sealed */
+#define ACPI_FADT_HEADLESS (1<<12) /* 12: [V3] No local video capabilities or local input devices */
+#define ACPI_FADT_SLEEP_TYPE (1<<13) /* 13: [V3] Must execute native instruction after writing SLP_TYPx register */
+#define ACPI_FADT_PCI_EXPRESS_WAKE (1<<14) /* 14: [V4] System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
+#define ACPI_FADT_PLATFORM_CLOCK (1<<15) /* 15: [V4] OSPM should use platform-provided timer (ACPI 3.0) */
+#define ACPI_FADT_S4_RTC_VALID (1<<16) /* 16: [V4] Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
+#define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: [V4] System is compatible with remote power on (ACPI 3.0) */
+#define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */
+#define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local xAPICs must use physical dest mode (ACPI 3.0) */
+#define ACPI_FADT_HW_REDUCED (1<<20) /* 20: [V5] ACPI hardware is not implemented (ACPI 5.0) */
+#define ACPI_FADT_LOW_POWER_S0 (1<<21) /* 21: [V5] S0 power savings are equal or better than S3 (ACPI 5.0) */
+
+
+/* Values for PreferredProfile (Preferred Power Management Profiles) */
+
+enum AcpiPreferredPmProfiles
+{
+ PM_UNSPECIFIED = 0,
+ PM_DESKTOP = 1,
+ PM_MOBILE = 2,
+ PM_WORKSTATION = 3,
+ PM_ENTERPRISE_SERVER = 4,
+ PM_SOHO_SERVER = 5,
+ PM_APPLIANCE_PC = 6,
+ PM_PERFORMANCE_SERVER = 7,
+ PM_TABLET = 8
+};
+
+/* Values for SleepStatus and SleepControl registers (V5+ FADT) */
+
+#define ACPI_X_WAKE_STATUS 0x80
+#define ACPI_X_SLEEP_TYPE_MASK 0x1C
+#define ACPI_X_SLEEP_TYPE_POSITION 0x02
+#define ACPI_X_SLEEP_ENABLE 0x20
+
+
+/* Reset to default packing */
+
+#pragma pack()
+
+
+/*
+ * Internal table-related structures
+ */
+typedef union acpi_name_union
+{
+ UINT32 Integer;
+ char Ascii[4];
+
+} ACPI_NAME_UNION;
+
+
+/* Internal ACPI Table Descriptor. One per ACPI table. */
+
+typedef struct acpi_table_desc
+{
+ ACPI_PHYSICAL_ADDRESS Address;
+ ACPI_TABLE_HEADER *Pointer;
+ UINT32 Length; /* Length fixed at 32 bits (fixed in table header) */
+ ACPI_NAME_UNION Signature;
+ ACPI_OWNER_ID OwnerId;
+ UINT8 Flags;
+
+} ACPI_TABLE_DESC;
+
+/* Masks for Flags field above */
+
+#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */
+#define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */
+#define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */
+#define ACPI_TABLE_ORIGIN_MASK (3)
+#define ACPI_TABLE_IS_LOADED (8)
+
+
+/*
+ * Get the remaining ACPI tables
+ */
+#include <contrib/dev/acpica/include/actbl1.h>
+#include <contrib/dev/acpica/include/actbl2.h>
+#include <contrib/dev/acpica/include/actbl3.h>
+
+/* Macros used to generate offsets to specific table fields */
+
+#define ACPI_FADT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_FADT, f)
+
+/*
+ * Sizes of the various flavors of FADT. We need to look closely
+ * at the FADT length because the version number essentially tells
+ * us nothing because of many BIOS bugs where the version does not
+ * match the expected length. In other words, the length of the
+ * FADT is the bottom line as to what the version really is.
+ *
+ * For reference, the values below are as follows:
+ * FADT V1 size: 0x074
+ * FADT V2 size: 0x084
+ * FADT V3 size: 0x0F4
+ * FADT V4 size: 0x0F4
+ * FADT V5 size: 0x10C
+ * FADT V6 size: 0x114
+ */
+#define ACPI_FADT_V1_SIZE (UINT32) (ACPI_FADT_OFFSET (Flags) + 4)
+#define ACPI_FADT_V2_SIZE (UINT32) (ACPI_FADT_OFFSET (MinorRevision) + 1)
+#define ACPI_FADT_V3_SIZE (UINT32) (ACPI_FADT_OFFSET (SleepControl))
+#define ACPI_FADT_V5_SIZE (UINT32) (ACPI_FADT_OFFSET (HypervisorId))
+#define ACPI_FADT_V6_SIZE (UINT32) (sizeof (ACPI_TABLE_FADT))
+
+#endif /* __ACTBL_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actbl1.h b/usr/src/boot/sys/contrib/dev/acpica/include/actbl1.h
new file mode 100644
index 0000000000..3a11553297
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actbl1.h
@@ -0,0 +1,1420 @@
+/******************************************************************************
+ *
+ * Name: actbl1.h - Additional ACPI table definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTBL1_H__
+#define __ACTBL1_H__
+
+
+/*******************************************************************************
+ *
+ * Additional ACPI Tables (1)
+ *
+ * These tables are not consumed directly by the ACPICA subsystem, but are
+ * included here to support device drivers and the AML disassembler.
+ *
+ * The tables in this file are fully defined within the ACPI specification.
+ *
+ ******************************************************************************/
+
+
+/*
+ * Values for description table header signatures for tables defined in this
+ * file. Useful because they make it more difficult to inadvertently type in
+ * the wrong signature.
+ */
+#define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */
+#define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */
+#define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */
+#define ACPI_SIG_EINJ "EINJ" /* Error Injection table */
+#define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */
+#define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */
+#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
+#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */
+#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */
+#define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */
+#define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */
+#define ACPI_SIG_NFIT "NFIT" /* NVDIMM Firmware Interface Table */
+
+
+/*
+ * All tables must be byte-packed to match the ACPI specification, since
+ * the tables are provided by the system BIOS.
+ */
+#pragma pack(1)
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+
+/*******************************************************************************
+ *
+ * Common subtable headers
+ *
+ ******************************************************************************/
+
+/* Generic subtable header (used in MADT, SRAT, etc.) */
+
+typedef struct acpi_subtable_header
+{
+ UINT8 Type;
+ UINT8 Length;
+
+} ACPI_SUBTABLE_HEADER;
+
+
+/* Subtable header for WHEA tables (EINJ, ERST, WDAT) */
+
+typedef struct acpi_whea_header
+{
+ UINT8 Action;
+ UINT8 Instruction;
+ UINT8 Flags;
+ UINT8 Reserved;
+ ACPI_GENERIC_ADDRESS RegisterRegion;
+ UINT64 Value; /* Value used with Read/Write register */
+ UINT64 Mask; /* Bitmask required for this register instruction */
+
+} ACPI_WHEA_HEADER;
+
+
+/*******************************************************************************
+ *
+ * BERT - Boot Error Record Table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_bert
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 RegionLength; /* Length of the boot error region */
+ UINT64 Address; /* Physical address of the error region */
+
+} ACPI_TABLE_BERT;
+
+
+/* Boot Error Region (not a subtable, pointed to by Address field above) */
+
+typedef struct acpi_bert_region
+{
+ UINT32 BlockStatus; /* Type of error information */
+ UINT32 RawDataOffset; /* Offset to raw error data */
+ UINT32 RawDataLength; /* Length of raw error data */
+ UINT32 DataLength; /* Length of generic error data */
+ UINT32 ErrorSeverity; /* Severity code */
+
+} ACPI_BERT_REGION;
+
+/* Values for BlockStatus flags above */
+
+#define ACPI_BERT_UNCORRECTABLE (1)
+#define ACPI_BERT_CORRECTABLE (1<<1)
+#define ACPI_BERT_MULTIPLE_UNCORRECTABLE (1<<2)
+#define ACPI_BERT_MULTIPLE_CORRECTABLE (1<<3)
+#define ACPI_BERT_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */
+
+/* Values for ErrorSeverity above */
+
+enum AcpiBertErrorSeverity
+{
+ ACPI_BERT_ERROR_CORRECTABLE = 0,
+ ACPI_BERT_ERROR_FATAL = 1,
+ ACPI_BERT_ERROR_CORRECTED = 2,
+ ACPI_BERT_ERROR_NONE = 3,
+ ACPI_BERT_ERROR_RESERVED = 4 /* 4 and greater are reserved */
+};
+
+/*
+ * Note: The generic error data that follows the ErrorSeverity field above
+ * uses the ACPI_HEST_GENERIC_DATA defined under the HEST table below
+ */
+
+
+/*******************************************************************************
+ *
+ * CPEP - Corrected Platform Error Polling table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_cpep
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 Reserved;
+
+} ACPI_TABLE_CPEP;
+
+
+/* Subtable */
+
+typedef struct acpi_cpep_polling
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 Id; /* Processor ID */
+ UINT8 Eid; /* Processor EID */
+ UINT32 Interval; /* Polling interval (msec) */
+
+} ACPI_CPEP_POLLING;
+
+
+/*******************************************************************************
+ *
+ * ECDT - Embedded Controller Boot Resources Table
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_ecdt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ ACPI_GENERIC_ADDRESS Control; /* Address of EC command/status register */
+ ACPI_GENERIC_ADDRESS Data; /* Address of EC data register */
+ UINT32 Uid; /* Unique ID - must be same as the EC _UID method */
+ UINT8 Gpe; /* The GPE for the EC */
+ UINT8 Id[1]; /* Full namepath of the EC in the ACPI namespace */
+
+} ACPI_TABLE_ECDT;
+
+
+/*******************************************************************************
+ *
+ * EINJ - Error Injection Table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_einj
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 HeaderLength;
+ UINT8 Flags;
+ UINT8 Reserved[3];
+ UINT32 Entries;
+
+} ACPI_TABLE_EINJ;
+
+
+/* EINJ Injection Instruction Entries (actions) */
+
+typedef struct acpi_einj_entry
+{
+ ACPI_WHEA_HEADER WheaHeader; /* Common header for WHEA tables */
+
+} ACPI_EINJ_ENTRY;
+
+/* Masks for Flags field above */
+
+#define ACPI_EINJ_PRESERVE (1)
+
+/* Values for Action field above */
+
+enum AcpiEinjActions
+{
+ ACPI_EINJ_BEGIN_OPERATION = 0,
+ ACPI_EINJ_GET_TRIGGER_TABLE = 1,
+ ACPI_EINJ_SET_ERROR_TYPE = 2,
+ ACPI_EINJ_GET_ERROR_TYPE = 3,
+ ACPI_EINJ_END_OPERATION = 4,
+ ACPI_EINJ_EXECUTE_OPERATION = 5,
+ ACPI_EINJ_CHECK_BUSY_STATUS = 6,
+ ACPI_EINJ_GET_COMMAND_STATUS = 7,
+ ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS = 8,
+ ACPI_EINJ_ACTION_RESERVED = 9, /* 9 and greater are reserved */
+ ACPI_EINJ_TRIGGER_ERROR = 0xFF /* Except for this value */
+};
+
+/* Values for Instruction field above */
+
+enum AcpiEinjInstructions
+{
+ ACPI_EINJ_READ_REGISTER = 0,
+ ACPI_EINJ_READ_REGISTER_VALUE = 1,
+ ACPI_EINJ_WRITE_REGISTER = 2,
+ ACPI_EINJ_WRITE_REGISTER_VALUE = 3,
+ ACPI_EINJ_NOOP = 4,
+ ACPI_EINJ_FLUSH_CACHELINE = 5,
+ ACPI_EINJ_INSTRUCTION_RESERVED = 6 /* 6 and greater are reserved */
+};
+
+typedef struct acpi_einj_error_type_with_addr
+{
+ UINT32 ErrorType;
+ UINT32 VendorStructOffset;
+ UINT32 Flags;
+ UINT32 ApicId;
+ UINT64 Address;
+ UINT64 Range;
+ UINT32 PcieId;
+
+} ACPI_EINJ_ERROR_TYPE_WITH_ADDR;
+
+typedef struct acpi_einj_vendor
+{
+ UINT32 Length;
+ UINT32 PcieId;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT8 RevisionId;
+ UINT8 Reserved[3];
+
+} ACPI_EINJ_VENDOR;
+
+
+/* EINJ Trigger Error Action Table */
+
+typedef struct acpi_einj_trigger
+{
+ UINT32 HeaderSize;
+ UINT32 Revision;
+ UINT32 TableSize;
+ UINT32 EntryCount;
+
+} ACPI_EINJ_TRIGGER;
+
+/* Command status return values */
+
+enum AcpiEinjCommandStatus
+{
+ ACPI_EINJ_SUCCESS = 0,
+ ACPI_EINJ_FAILURE = 1,
+ ACPI_EINJ_INVALID_ACCESS = 2,
+ ACPI_EINJ_STATUS_RESERVED = 3 /* 3 and greater are reserved */
+};
+
+
+/* Error types returned from ACPI_EINJ_GET_ERROR_TYPE (bitfield) */
+
+#define ACPI_EINJ_PROCESSOR_CORRECTABLE (1)
+#define ACPI_EINJ_PROCESSOR_UNCORRECTABLE (1<<1)
+#define ACPI_EINJ_PROCESSOR_FATAL (1<<2)
+#define ACPI_EINJ_MEMORY_CORRECTABLE (1<<3)
+#define ACPI_EINJ_MEMORY_UNCORRECTABLE (1<<4)
+#define ACPI_EINJ_MEMORY_FATAL (1<<5)
+#define ACPI_EINJ_PCIX_CORRECTABLE (1<<6)
+#define ACPI_EINJ_PCIX_UNCORRECTABLE (1<<7)
+#define ACPI_EINJ_PCIX_FATAL (1<<8)
+#define ACPI_EINJ_PLATFORM_CORRECTABLE (1<<9)
+#define ACPI_EINJ_PLATFORM_UNCORRECTABLE (1<<10)
+#define ACPI_EINJ_PLATFORM_FATAL (1<<11)
+#define ACPI_EINJ_VENDOR_DEFINED (1<<31)
+
+
+/*******************************************************************************
+ *
+ * ERST - Error Record Serialization Table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_erst
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 HeaderLength;
+ UINT32 Reserved;
+ UINT32 Entries;
+
+} ACPI_TABLE_ERST;
+
+
+/* ERST Serialization Entries (actions) */
+
+typedef struct acpi_erst_entry
+{
+ ACPI_WHEA_HEADER WheaHeader; /* Common header for WHEA tables */
+
+} ACPI_ERST_ENTRY;
+
+/* Masks for Flags field above */
+
+#define ACPI_ERST_PRESERVE (1)
+
+/* Values for Action field above */
+
+enum AcpiErstActions
+{
+ ACPI_ERST_BEGIN_WRITE = 0,
+ ACPI_ERST_BEGIN_READ = 1,
+ ACPI_ERST_BEGIN_CLEAR = 2,
+ ACPI_ERST_END = 3,
+ ACPI_ERST_SET_RECORD_OFFSET = 4,
+ ACPI_ERST_EXECUTE_OPERATION = 5,
+ ACPI_ERST_CHECK_BUSY_STATUS = 6,
+ ACPI_ERST_GET_COMMAND_STATUS = 7,
+ ACPI_ERST_GET_RECORD_ID = 8,
+ ACPI_ERST_SET_RECORD_ID = 9,
+ ACPI_ERST_GET_RECORD_COUNT = 10,
+ ACPI_ERST_BEGIN_DUMMY_WRIITE = 11,
+ ACPI_ERST_NOT_USED = 12,
+ ACPI_ERST_GET_ERROR_RANGE = 13,
+ ACPI_ERST_GET_ERROR_LENGTH = 14,
+ ACPI_ERST_GET_ERROR_ATTRIBUTES = 15,
+ ACPI_ERST_ACTION_RESERVED = 16 /* 16 and greater are reserved */
+};
+
+/* Values for Instruction field above */
+
+enum AcpiErstInstructions
+{
+ ACPI_ERST_READ_REGISTER = 0,
+ ACPI_ERST_READ_REGISTER_VALUE = 1,
+ ACPI_ERST_WRITE_REGISTER = 2,
+ ACPI_ERST_WRITE_REGISTER_VALUE = 3,
+ ACPI_ERST_NOOP = 4,
+ ACPI_ERST_LOAD_VAR1 = 5,
+ ACPI_ERST_LOAD_VAR2 = 6,
+ ACPI_ERST_STORE_VAR1 = 7,
+ ACPI_ERST_ADD = 8,
+ ACPI_ERST_SUBTRACT = 9,
+ ACPI_ERST_ADD_VALUE = 10,
+ ACPI_ERST_SUBTRACT_VALUE = 11,
+ ACPI_ERST_STALL = 12,
+ ACPI_ERST_STALL_WHILE_TRUE = 13,
+ ACPI_ERST_SKIP_NEXT_IF_TRUE = 14,
+ ACPI_ERST_GOTO = 15,
+ ACPI_ERST_SET_SRC_ADDRESS_BASE = 16,
+ ACPI_ERST_SET_DST_ADDRESS_BASE = 17,
+ ACPI_ERST_MOVE_DATA = 18,
+ ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */
+};
+
+/* Command status return values */
+
+enum AcpiErstCommandStatus
+{
+ ACPI_ERST_SUCESS = 0,
+ ACPI_ERST_NO_SPACE = 1,
+ ACPI_ERST_NOT_AVAILABLE = 2,
+ ACPI_ERST_FAILURE = 3,
+ ACPI_ERST_RECORD_EMPTY = 4,
+ ACPI_ERST_NOT_FOUND = 5,
+ ACPI_ERST_STATUS_RESERVED = 6 /* 6 and greater are reserved */
+};
+
+
+/* Error Record Serialization Information */
+
+typedef struct acpi_erst_info
+{
+ UINT16 Signature; /* Should be "ER" */
+ UINT8 Data[48];
+
+} ACPI_ERST_INFO;
+
+
+/*******************************************************************************
+ *
+ * HEST - Hardware Error Source Table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_hest
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 ErrorSourceCount;
+
+} ACPI_TABLE_HEST;
+
+
+/* HEST subtable header */
+
+typedef struct acpi_hest_header
+{
+ UINT16 Type;
+ UINT16 SourceId;
+
+} ACPI_HEST_HEADER;
+
+
+/* Values for Type field above for subtables */
+
+enum AcpiHestTypes
+{
+ ACPI_HEST_TYPE_IA32_CHECK = 0,
+ ACPI_HEST_TYPE_IA32_CORRECTED_CHECK = 1,
+ ACPI_HEST_TYPE_IA32_NMI = 2,
+ ACPI_HEST_TYPE_NOT_USED3 = 3,
+ ACPI_HEST_TYPE_NOT_USED4 = 4,
+ ACPI_HEST_TYPE_NOT_USED5 = 5,
+ ACPI_HEST_TYPE_AER_ROOT_PORT = 6,
+ ACPI_HEST_TYPE_AER_ENDPOINT = 7,
+ ACPI_HEST_TYPE_AER_BRIDGE = 8,
+ ACPI_HEST_TYPE_GENERIC_ERROR = 9,
+ ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */
+};
+
+
+/*
+ * HEST substructures contained in subtables
+ */
+
+/*
+ * IA32 Error Bank(s) - Follows the ACPI_HEST_IA_MACHINE_CHECK and
+ * ACPI_HEST_IA_CORRECTED structures.
+ */
+typedef struct acpi_hest_ia_error_bank
+{
+ UINT8 BankNumber;
+ UINT8 ClearStatusOnInit;
+ UINT8 StatusFormat;
+ UINT8 Reserved;
+ UINT32 ControlRegister;
+ UINT64 ControlData;
+ UINT32 StatusRegister;
+ UINT32 AddressRegister;
+ UINT32 MiscRegister;
+
+} ACPI_HEST_IA_ERROR_BANK;
+
+
+/* Common HEST sub-structure for PCI/AER structures below (6,7,8) */
+
+typedef struct acpi_hest_aer_common
+{
+ UINT16 Reserved1;
+ UINT8 Flags;
+ UINT8 Enabled;
+ UINT32 RecordsToPreallocate;
+ UINT32 MaxSectionsPerRecord;
+ UINT32 Bus; /* Bus and Segment numbers */
+ UINT16 Device;
+ UINT16 Function;
+ UINT16 DeviceControl;
+ UINT16 Reserved2;
+ UINT32 UncorrectableMask;
+ UINT32 UncorrectableSeverity;
+ UINT32 CorrectableMask;
+ UINT32 AdvancedCapabilities;
+
+} ACPI_HEST_AER_COMMON;
+
+/* Masks for HEST Flags fields */
+
+#define ACPI_HEST_FIRMWARE_FIRST (1)
+#define ACPI_HEST_GLOBAL (1<<1)
+
+/*
+ * Macros to access the bus/segment numbers in Bus field above:
+ * Bus number is encoded in bits 7:0
+ * Segment number is encoded in bits 23:8
+ */
+#define ACPI_HEST_BUS(Bus) ((Bus) & 0xFF)
+#define ACPI_HEST_SEGMENT(Bus) (((Bus) >> 8) & 0xFFFF)
+
+
+/* Hardware Error Notification */
+
+typedef struct acpi_hest_notify
+{
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 ConfigWriteEnable;
+ UINT32 PollInterval;
+ UINT32 Vector;
+ UINT32 PollingThresholdValue;
+ UINT32 PollingThresholdWindow;
+ UINT32 ErrorThresholdValue;
+ UINT32 ErrorThresholdWindow;
+
+} ACPI_HEST_NOTIFY;
+
+/* Values for Notify Type field above */
+
+enum AcpiHestNotifyTypes
+{
+ ACPI_HEST_NOTIFY_POLLED = 0,
+ ACPI_HEST_NOTIFY_EXTERNAL = 1,
+ ACPI_HEST_NOTIFY_LOCAL = 2,
+ ACPI_HEST_NOTIFY_SCI = 3,
+ ACPI_HEST_NOTIFY_NMI = 4,
+ ACPI_HEST_NOTIFY_CMCI = 5, /* ACPI 5.0 */
+ ACPI_HEST_NOTIFY_MCE = 6, /* ACPI 5.0 */
+ ACPI_HEST_NOTIFY_RESERVED = 7 /* 7 and greater are reserved */
+};
+
+/* Values for ConfigWriteEnable bitfield above */
+
+#define ACPI_HEST_TYPE (1)
+#define ACPI_HEST_POLL_INTERVAL (1<<1)
+#define ACPI_HEST_POLL_THRESHOLD_VALUE (1<<2)
+#define ACPI_HEST_POLL_THRESHOLD_WINDOW (1<<3)
+#define ACPI_HEST_ERR_THRESHOLD_VALUE (1<<4)
+#define ACPI_HEST_ERR_THRESHOLD_WINDOW (1<<5)
+
+
+/*
+ * HEST subtables
+ */
+
+/* 0: IA32 Machine Check Exception */
+
+typedef struct acpi_hest_ia_machine_check
+{
+ ACPI_HEST_HEADER Header;
+ UINT16 Reserved1;
+ UINT8 Flags;
+ UINT8 Enabled;
+ UINT32 RecordsToPreallocate;
+ UINT32 MaxSectionsPerRecord;
+ UINT64 GlobalCapabilityData;
+ UINT64 GlobalControlData;
+ UINT8 NumHardwareBanks;
+ UINT8 Reserved3[7];
+
+} ACPI_HEST_IA_MACHINE_CHECK;
+
+
+/* 1: IA32 Corrected Machine Check */
+
+typedef struct acpi_hest_ia_corrected
+{
+ ACPI_HEST_HEADER Header;
+ UINT16 Reserved1;
+ UINT8 Flags;
+ UINT8 Enabled;
+ UINT32 RecordsToPreallocate;
+ UINT32 MaxSectionsPerRecord;
+ ACPI_HEST_NOTIFY Notify;
+ UINT8 NumHardwareBanks;
+ UINT8 Reserved2[3];
+
+} ACPI_HEST_IA_CORRECTED;
+
+
+/* 2: IA32 Non-Maskable Interrupt */
+
+typedef struct acpi_hest_ia_nmi
+{
+ ACPI_HEST_HEADER Header;
+ UINT32 Reserved;
+ UINT32 RecordsToPreallocate;
+ UINT32 MaxSectionsPerRecord;
+ UINT32 MaxRawDataLength;
+
+} ACPI_HEST_IA_NMI;
+
+
+/* 3,4,5: Not used */
+
+/* 6: PCI Express Root Port AER */
+
+typedef struct acpi_hest_aer_root
+{
+ ACPI_HEST_HEADER Header;
+ ACPI_HEST_AER_COMMON Aer;
+ UINT32 RootErrorCommand;
+
+} ACPI_HEST_AER_ROOT;
+
+
+/* 7: PCI Express AER (AER Endpoint) */
+
+typedef struct acpi_hest_aer
+{
+ ACPI_HEST_HEADER Header;
+ ACPI_HEST_AER_COMMON Aer;
+
+} ACPI_HEST_AER;
+
+
+/* 8: PCI Express/PCI-X Bridge AER */
+
+typedef struct acpi_hest_aer_bridge
+{
+ ACPI_HEST_HEADER Header;
+ ACPI_HEST_AER_COMMON Aer;
+ UINT32 UncorrectableMask2;
+ UINT32 UncorrectableSeverity2;
+ UINT32 AdvancedCapabilities2;
+
+} ACPI_HEST_AER_BRIDGE;
+
+
+/* 9: Generic Hardware Error Source */
+
+typedef struct acpi_hest_generic
+{
+ ACPI_HEST_HEADER Header;
+ UINT16 RelatedSourceId;
+ UINT8 Reserved;
+ UINT8 Enabled;
+ UINT32 RecordsToPreallocate;
+ UINT32 MaxSectionsPerRecord;
+ UINT32 MaxRawDataLength;
+ ACPI_GENERIC_ADDRESS ErrorStatusAddress;
+ ACPI_HEST_NOTIFY Notify;
+ UINT32 ErrorBlockLength;
+
+} ACPI_HEST_GENERIC;
+
+
+/* Generic Error Status block */
+
+typedef struct acpi_hest_generic_status
+{
+ UINT32 BlockStatus;
+ UINT32 RawDataOffset;
+ UINT32 RawDataLength;
+ UINT32 DataLength;
+ UINT32 ErrorSeverity;
+
+} ACPI_HEST_GENERIC_STATUS;
+
+/* Values for BlockStatus flags above */
+
+#define ACPI_HEST_UNCORRECTABLE (1)
+#define ACPI_HEST_CORRECTABLE (1<<1)
+#define ACPI_HEST_MULTIPLE_UNCORRECTABLE (1<<2)
+#define ACPI_HEST_MULTIPLE_CORRECTABLE (1<<3)
+#define ACPI_HEST_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */
+
+
+/* Generic Error Data entry */
+
+typedef struct acpi_hest_generic_data
+{
+ UINT8 SectionType[16];
+ UINT32 ErrorSeverity;
+ UINT16 Revision;
+ UINT8 ValidationBits;
+ UINT8 Flags;
+ UINT32 ErrorDataLength;
+ UINT8 FruId[16];
+ UINT8 FruText[20];
+
+} ACPI_HEST_GENERIC_DATA;
+
+
+/*******************************************************************************
+ *
+ * MADT - Multiple APIC Description Table
+ * Version 3
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_madt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Address; /* Physical address of local APIC */
+ UINT32 Flags;
+
+} ACPI_TABLE_MADT;
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */
+
+/* Values for PCATCompat flag */
+
+#define ACPI_MADT_DUAL_PIC 0
+#define ACPI_MADT_MULTIPLE_APIC 1
+
+
+/* Values for MADT subtable type in ACPI_SUBTABLE_HEADER */
+
+enum AcpiMadtType
+{
+ ACPI_MADT_TYPE_LOCAL_APIC = 0,
+ ACPI_MADT_TYPE_IO_APIC = 1,
+ ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2,
+ ACPI_MADT_TYPE_NMI_SOURCE = 3,
+ ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4,
+ ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5,
+ ACPI_MADT_TYPE_IO_SAPIC = 6,
+ ACPI_MADT_TYPE_LOCAL_SAPIC = 7,
+ ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
+ ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
+ ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
+ ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
+ ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
+ ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
+ ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
+ ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
+ ACPI_MADT_TYPE_RESERVED = 16 /* 16 and greater are reserved */
+};
+
+
+/*
+ * MADT Subtables, correspond to Type in ACPI_SUBTABLE_HEADER
+ */
+
+/* 0: Processor Local APIC */
+
+typedef struct acpi_madt_local_apic
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 ProcessorId; /* ACPI processor id */
+ UINT8 Id; /* Processor's local APIC id */
+ UINT32 LapicFlags;
+
+} ACPI_MADT_LOCAL_APIC;
+
+
+/* 1: IO APIC */
+
+typedef struct acpi_madt_io_apic
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 Id; /* I/O APIC ID */
+ UINT8 Reserved; /* Reserved - must be zero */
+ UINT32 Address; /* APIC physical address */
+ UINT32 GlobalIrqBase; /* Global system interrupt where INTI lines start */
+
+} ACPI_MADT_IO_APIC;
+
+
+/* 2: Interrupt Override */
+
+typedef struct acpi_madt_interrupt_override
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 Bus; /* 0 - ISA */
+ UINT8 SourceIrq; /* Interrupt source (IRQ) */
+ UINT32 GlobalIrq; /* Global system interrupt */
+ UINT16 IntiFlags;
+
+} ACPI_MADT_INTERRUPT_OVERRIDE;
+
+
+/* 3: NMI Source */
+
+typedef struct acpi_madt_nmi_source
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 IntiFlags;
+ UINT32 GlobalIrq; /* Global system interrupt */
+
+} ACPI_MADT_NMI_SOURCE;
+
+
+/* 4: Local APIC NMI */
+
+typedef struct acpi_madt_local_apic_nmi
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 ProcessorId; /* ACPI processor id */
+ UINT16 IntiFlags;
+ UINT8 Lint; /* LINTn to which NMI is connected */
+
+} ACPI_MADT_LOCAL_APIC_NMI;
+
+
+/* 5: Address Override */
+
+typedef struct acpi_madt_local_apic_override
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved, must be zero */
+ UINT64 Address; /* APIC physical address */
+
+} ACPI_MADT_LOCAL_APIC_OVERRIDE;
+
+
+/* 6: I/O Sapic */
+
+typedef struct acpi_madt_io_sapic
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 Id; /* I/O SAPIC ID */
+ UINT8 Reserved; /* Reserved, must be zero */
+ UINT32 GlobalIrqBase; /* Global interrupt for SAPIC start */
+ UINT64 Address; /* SAPIC physical address */
+
+} ACPI_MADT_IO_SAPIC;
+
+
+/* 7: Local Sapic */
+
+typedef struct acpi_madt_local_sapic
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 ProcessorId; /* ACPI processor id */
+ UINT8 Id; /* SAPIC ID */
+ UINT8 Eid; /* SAPIC EID */
+ UINT8 Reserved[3]; /* Reserved, must be zero */
+ UINT32 LapicFlags;
+ UINT32 Uid; /* Numeric UID - ACPI 3.0 */
+ char UidString[1]; /* String UID - ACPI 3.0 */
+
+} ACPI_MADT_LOCAL_SAPIC;
+
+
+/* 8: Platform Interrupt Source */
+
+typedef struct acpi_madt_interrupt_source
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 IntiFlags;
+ UINT8 Type; /* 1=PMI, 2=INIT, 3=corrected */
+ UINT8 Id; /* Processor ID */
+ UINT8 Eid; /* Processor EID */
+ UINT8 IoSapicVector; /* Vector value for PMI interrupts */
+ UINT32 GlobalIrq; /* Global system interrupt */
+ UINT32 Flags; /* Interrupt Source Flags */
+
+} ACPI_MADT_INTERRUPT_SOURCE;
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_CPEI_OVERRIDE (1)
+
+
+/* 9: Processor Local X2APIC (ACPI 4.0) */
+
+typedef struct acpi_madt_local_x2apic
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved - must be zero */
+ UINT32 LocalApicId; /* Processor x2APIC ID */
+ UINT32 LapicFlags;
+ UINT32 Uid; /* ACPI processor UID */
+
+} ACPI_MADT_LOCAL_X2APIC;
+
+
+/* 10: Local X2APIC NMI (ACPI 4.0) */
+
+typedef struct acpi_madt_local_x2apic_nmi
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 IntiFlags;
+ UINT32 Uid; /* ACPI processor UID */
+ UINT8 Lint; /* LINTn to which NMI is connected */
+ UINT8 Reserved[3]; /* Reserved - must be zero */
+
+} ACPI_MADT_LOCAL_X2APIC_NMI;
+
+
+/* 11: Generic Interrupt (ACPI 5.0 + ACPI 6.0 changes) */
+
+typedef struct acpi_madt_generic_interrupt
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved - must be zero */
+ UINT32 CpuInterfaceNumber;
+ UINT32 Uid;
+ UINT32 Flags;
+ UINT32 ParkingVersion;
+ UINT32 PerformanceInterrupt;
+ UINT64 ParkedAddress;
+ UINT64 BaseAddress;
+ UINT64 GicvBaseAddress;
+ UINT64 GichBaseAddress;
+ UINT32 VgicInterrupt;
+ UINT64 GicrBaseAddress;
+ UINT64 ArmMpidr;
+ UINT8 EfficiencyClass;
+ UINT8 Reserved2[3];
+
+} ACPI_MADT_GENERIC_INTERRUPT;
+
+/* Masks for Flags field above */
+
+/* ACPI_MADT_ENABLED (1) Processor is usable if set */
+#define ACPI_MADT_PERFORMANCE_IRQ_MODE (1<<1) /* 01: Performance Interrupt Mode */
+#define ACPI_MADT_VGIC_IRQ_MODE (1<<2) /* 02: VGIC Maintenance Interrupt mode */
+
+
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
+
+typedef struct acpi_madt_generic_distributor
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved - must be zero */
+ UINT32 GicId;
+ UINT64 BaseAddress;
+ UINT32 GlobalIrqBase;
+ UINT8 Version;
+ UINT8 Reserved2[3]; /* Reserved - must be zero */
+
+} ACPI_MADT_GENERIC_DISTRIBUTOR;
+
+/* Values for Version field above */
+
+enum AcpiMadtGicVersion
+{
+ ACPI_MADT_GIC_VERSION_NONE = 0,
+ ACPI_MADT_GIC_VERSION_V1 = 1,
+ ACPI_MADT_GIC_VERSION_V2 = 2,
+ ACPI_MADT_GIC_VERSION_V3 = 3,
+ ACPI_MADT_GIC_VERSION_V4 = 4,
+ ACPI_MADT_GIC_VERSION_RESERVED = 5 /* 5 and greater are reserved */
+};
+
+
+/* 13: Generic MSI Frame (ACPI 5.1) */
+
+typedef struct acpi_madt_generic_msi_frame
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved - must be zero */
+ UINT32 MsiFrameId;
+ UINT64 BaseAddress;
+ UINT32 Flags;
+ UINT16 SpiCount;
+ UINT16 SpiBase;
+
+} ACPI_MADT_GENERIC_MSI_FRAME;
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_OVERRIDE_SPI_VALUES (1)
+
+
+/* 14: Generic Redistributor (ACPI 5.1) */
+
+typedef struct acpi_madt_generic_redistributor
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* reserved - must be zero */
+ UINT64 BaseAddress;
+ UINT32 Length;
+
+} ACPI_MADT_GENERIC_REDISTRIBUTOR;
+
+
+/* 15: Generic Translator (ACPI 6.0) */
+
+typedef struct acpi_madt_generic_translator
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* reserved - must be zero */
+ UINT32 TranslationId;
+ UINT64 BaseAddress;
+ UINT32 Reserved2;
+
+} ACPI_MADT_GENERIC_TRANSLATOR;
+
+
+/*
+ * Common flags fields for MADT subtables
+ */
+
+/* MADT Local APIC flags */
+
+#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */
+
+/* MADT MPS INTI flags (IntiFlags) */
+
+#define ACPI_MADT_POLARITY_MASK (3) /* 00-01: Polarity of APIC I/O input signals */
+#define ACPI_MADT_TRIGGER_MASK (3<<2) /* 02-03: Trigger mode of APIC input signals */
+
+/* Values for MPS INTI flags */
+
+#define ACPI_MADT_POLARITY_CONFORMS 0
+#define ACPI_MADT_POLARITY_ACTIVE_HIGH 1
+#define ACPI_MADT_POLARITY_RESERVED 2
+#define ACPI_MADT_POLARITY_ACTIVE_LOW 3
+
+#define ACPI_MADT_TRIGGER_CONFORMS (0)
+#define ACPI_MADT_TRIGGER_EDGE (1<<2)
+#define ACPI_MADT_TRIGGER_RESERVED (2<<2)
+#define ACPI_MADT_TRIGGER_LEVEL (3<<2)
+
+
+/*******************************************************************************
+ *
+ * MSCT - Maximum System Characteristics Table (ACPI 4.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_msct
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 ProximityOffset; /* Location of proximity info struct(s) */
+ UINT32 MaxProximityDomains;/* Max number of proximity domains */
+ UINT32 MaxClockDomains; /* Max number of clock domains */
+ UINT64 MaxAddress; /* Max physical address in system */
+
+} ACPI_TABLE_MSCT;
+
+
+/* Subtable - Maximum Proximity Domain Information. Version 1 */
+
+typedef struct acpi_msct_proximity
+{
+ UINT8 Revision;
+ UINT8 Length;
+ UINT32 RangeStart; /* Start of domain range */
+ UINT32 RangeEnd; /* End of domain range */
+ UINT32 ProcessorCapacity;
+ UINT64 MemoryCapacity; /* In bytes */
+
+} ACPI_MSCT_PROXIMITY;
+
+
+/*******************************************************************************
+ *
+ * NFIT - NVDIMM Interface Table (ACPI 6.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_nfit
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Reserved; /* Reserved, must be zero */
+
+} ACPI_TABLE_NFIT;
+
+/* Subtable header for NFIT */
+
+typedef struct acpi_nfit_header
+{
+ UINT16 Type;
+ UINT16 Length;
+
+} ACPI_NFIT_HEADER;
+
+
+/* Values for subtable type in ACPI_NFIT_HEADER */
+
+enum AcpiNfitType
+{
+ ACPI_NFIT_TYPE_SYSTEM_ADDRESS = 0,
+ ACPI_NFIT_TYPE_MEMORY_MAP = 1,
+ ACPI_NFIT_TYPE_INTERLEAVE = 2,
+ ACPI_NFIT_TYPE_SMBIOS = 3,
+ ACPI_NFIT_TYPE_CONTROL_REGION = 4,
+ ACPI_NFIT_TYPE_DATA_REGION = 5,
+ ACPI_NFIT_TYPE_FLUSH_ADDRESS = 6,
+ ACPI_NFIT_TYPE_RESERVED = 7 /* 7 and greater are reserved */
+};
+
+/*
+ * NFIT Subtables
+ */
+
+/* 0: System Physical Address Range Structure */
+
+typedef struct acpi_nfit_system_address
+{
+ ACPI_NFIT_HEADER Header;
+ UINT16 RangeIndex;
+ UINT16 Flags;
+ UINT32 Reserved; /* Reseved, must be zero */
+ UINT32 ProximityDomain;
+ UINT8 RangeGuid[16];
+ UINT64 Address;
+ UINT64 Length;
+ UINT64 MemoryMapping;
+
+} ACPI_NFIT_SYSTEM_ADDRESS;
+
+/* Flags */
+
+#define ACPI_NFIT_ADD_ONLINE_ONLY (1) /* 00: Add/Online Operation Only */
+#define ACPI_NFIT_PROXIMITY_VALID (1<<1) /* 01: Proximity Domain Valid */
+
+/* Range Type GUIDs appear in the include/acuuid.h file */
+
+
+/* 1: Memory Device to System Address Range Map Structure */
+
+typedef struct acpi_nfit_memory_map
+{
+ ACPI_NFIT_HEADER Header;
+ UINT32 DeviceHandle;
+ UINT16 PhysicalId;
+ UINT16 RegionId;
+ UINT16 RangeIndex;
+ UINT16 RegionIndex;
+ UINT64 RegionSize;
+ UINT64 RegionOffset;
+ UINT64 Address;
+ UINT16 InterleaveIndex;
+ UINT16 InterleaveWays;
+ UINT16 Flags;
+ UINT16 Reserved; /* Reserved, must be zero */
+
+} ACPI_NFIT_MEMORY_MAP;
+
+/* Flags */
+
+#define ACPI_NFIT_MEM_SAVE_FAILED (1) /* 00: Last SAVE to Memory Device failed */
+#define ACPI_NFIT_MEM_RESTORE_FAILED (1<<1) /* 01: Last RESTORE from Memory Device failed */
+#define ACPI_NFIT_MEM_FLUSH_FAILED (1<<2) /* 02: Platform flush failed */
+#define ACPI_NFIT_MEM_ARMED (1<<3) /* 03: Memory Device observed to be not armed */
+#define ACPI_NFIT_MEM_HEALTH_OBSERVED (1<<4) /* 04: Memory Device observed SMART/health events */
+#define ACPI_NFIT_MEM_HEALTH_ENABLED (1<<5) /* 05: SMART/health events enabled */
+
+
+/* 2: Interleave Structure */
+
+typedef struct acpi_nfit_interleave
+{
+ ACPI_NFIT_HEADER Header;
+ UINT16 InterleaveIndex;
+ UINT16 Reserved; /* Reserved, must be zero */
+ UINT32 LineCount;
+ UINT32 LineSize;
+ UINT32 LineOffset[1]; /* Variable length */
+
+} ACPI_NFIT_INTERLEAVE;
+
+
+/* 3: SMBIOS Management Information Structure */
+
+typedef struct acpi_nfit_smbios
+{
+ ACPI_NFIT_HEADER Header;
+ UINT32 Reserved; /* Reserved, must be zero */
+ UINT8 Data[1]; /* Variable length */
+
+} ACPI_NFIT_SMBIOS;
+
+
+/* 4: NVDIMM Control Region Structure */
+
+typedef struct acpi_nfit_control_region
+{
+ ACPI_NFIT_HEADER Header;
+ UINT16 RegionIndex;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 RevisionId;
+ UINT16 SubsystemVendorId;
+ UINT16 SubsystemDeviceId;
+ UINT16 SubsystemRevisionId;
+ UINT8 Reserved[6]; /* Reserved, must be zero */
+ UINT32 SerialNumber;
+ UINT16 Code;
+ UINT16 Windows;
+ UINT64 WindowSize;
+ UINT64 CommandOffset;
+ UINT64 CommandSize;
+ UINT64 StatusOffset;
+ UINT64 StatusSize;
+ UINT16 Flags;
+ UINT8 Reserved1[6]; /* Reserved, must be zero */
+
+} ACPI_NFIT_CONTROL_REGION;
+
+/* Flags */
+
+#define ACPI_NFIT_CONTROL_BUFFERED (1) /* Block Data Windows implementation is buffered */
+
+
+/* 5: NVDIMM Block Data Window Region Structure */
+
+typedef struct acpi_nfit_data_region
+{
+ ACPI_NFIT_HEADER Header;
+ UINT16 RegionIndex;
+ UINT16 Windows;
+ UINT64 Offset;
+ UINT64 Size;
+ UINT64 Capacity;
+ UINT64 StartAddress;
+
+} ACPI_NFIT_DATA_REGION;
+
+
+/* 6: Flush Hint Address Structure */
+
+typedef struct acpi_nfit_flush_address
+{
+ ACPI_NFIT_HEADER Header;
+ UINT32 DeviceHandle;
+ UINT16 HintCount;
+ UINT8 Reserved[6]; /* Reserved, must be zero */
+ UINT64 HintAddress[1]; /* Variable length */
+
+} ACPI_NFIT_FLUSH_ADDRESS;
+
+
+/*******************************************************************************
+ *
+ * SBST - Smart Battery Specification Table
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_sbst
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 WarningLevel;
+ UINT32 LowLevel;
+ UINT32 CriticalLevel;
+
+} ACPI_TABLE_SBST;
+
+
+/*******************************************************************************
+ *
+ * SLIT - System Locality Distance Information Table
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_slit
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 LocalityCount;
+ UINT8 Entry[1]; /* Real size = localities^2 */
+
+} ACPI_TABLE_SLIT;
+
+
+/*******************************************************************************
+ *
+ * SRAT - System Resource Affinity Table
+ * Version 3
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_srat
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 TableRevision; /* Must be value '1' */
+ UINT64 Reserved; /* Reserved, must be zero */
+
+} ACPI_TABLE_SRAT;
+
+/* Values for subtable type in ACPI_SUBTABLE_HEADER */
+
+enum AcpiSratType
+{
+ ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
+ ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
+ ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
+ ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
+ ACPI_SRAT_TYPE_RESERVED = 4 /* 4 and greater are reserved */
+};
+
+/*
+ * SRAT Subtables, correspond to Type in ACPI_SUBTABLE_HEADER
+ */
+
+/* 0: Processor Local APIC/SAPIC Affinity */
+
+typedef struct acpi_srat_cpu_affinity
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 ProximityDomainLo;
+ UINT8 ApicId;
+ UINT32 Flags;
+ UINT8 LocalSapicEid;
+ UINT8 ProximityDomainHi[3];
+ UINT32 ClockDomain;
+
+} ACPI_SRAT_CPU_AFFINITY;
+
+/* Flags */
+
+#define ACPI_SRAT_CPU_USE_AFFINITY (1) /* 00: Use affinity structure */
+
+
+/* 1: Memory Affinity */
+
+typedef struct acpi_srat_mem_affinity
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT32 ProximityDomain;
+ UINT16 Reserved; /* Reserved, must be zero */
+ UINT64 BaseAddress;
+ UINT64 Length;
+ UINT32 Reserved1;
+ UINT32 Flags;
+ UINT64 Reserved2; /* Reserved, must be zero */
+
+} ACPI_SRAT_MEM_AFFINITY;
+
+/* Flags */
+
+#define ACPI_SRAT_MEM_ENABLED (1) /* 00: Use affinity structure */
+#define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */
+#define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */
+
+
+/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */
+
+typedef struct acpi_srat_x2apic_cpu_affinity
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT16 Reserved; /* Reserved, must be zero */
+ UINT32 ProximityDomain;
+ UINT32 ApicId;
+ UINT32 Flags;
+ UINT32 ClockDomain;
+ UINT32 Reserved2;
+
+} ACPI_SRAT_X2APIC_CPU_AFFINITY;
+
+/* Flags for ACPI_SRAT_CPU_AFFINITY and ACPI_SRAT_X2APIC_CPU_AFFINITY */
+
+#define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */
+
+
+/* 3: GICC Affinity (ACPI 5.1) */
+
+typedef struct acpi_srat_gicc_affinity
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT32 ProximityDomain;
+ UINT32 AcpiProcessorUid;
+ UINT32 Flags;
+ UINT32 ClockDomain;
+
+} ACPI_SRAT_GICC_AFFINITY;
+
+/* Flags for ACPI_SRAT_GICC_AFFINITY */
+
+#define ACPI_SRAT_GICC_ENABLED (1) /* 00: Use affinity structure */
+
+
+/* Reset to default packing */
+
+#pragma pack()
+
+#endif /* __ACTBL1_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actbl2.h b/usr/src/boot/sys/contrib/dev/acpica/include/actbl2.h
new file mode 100644
index 0000000000..389932ac11
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actbl2.h
@@ -0,0 +1,1693 @@
+/******************************************************************************
+ *
+ * Name: actbl2.h - ACPI Table Definitions (tables not in ACPI spec)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTBL2_H__
+#define __ACTBL2_H__
+
+
+/*******************************************************************************
+ *
+ * Additional ACPI Tables (2)
+ *
+ * These tables are not consumed directly by the ACPICA subsystem, but are
+ * included here to support device drivers and the AML disassembler.
+ *
+ * Generally, the tables in this file are defined by third-party specifications,
+ * and are not defined directly by the ACPI specification itself.
+ *
+ ******************************************************************************/
+
+
+/*
+ * Values for description table header signatures for tables defined in this
+ * file. Useful because they make it more difficult to inadvertently type in
+ * the wrong signature.
+ */
+#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */
+#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */
+#define ACPI_SIG_CSRT "CSRT" /* Core System Resource Table */
+#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table type 2 */
+#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */
+#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */
+#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
+#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */
+#define ACPI_SIG_IORT "IORT" /* IO Remapping Table */
+#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
+#define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */
+#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */
+#define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */
+#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */
+#define ACPI_SIG_MTMR "MTMR" /* MID Timer table */
+#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */
+#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */
+#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */
+#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */
+#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module 2.0 H/W interface table */
+#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */
+#define ACPI_SIG_VRTC "VRTC" /* Virtual Real Time Clock Table */
+#define ACPI_SIG_WAET "WAET" /* Windows ACPI Emulated devices Table */
+#define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */
+#define ACPI_SIG_WDDT "WDDT" /* Watchdog Timer Description Table */
+#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */
+
+#ifdef ACPI_UNDEFINED_TABLES
+/*
+ * These tables have been seen in the field, but no definition has been found
+ */
+#define ACPI_SIG_ATKG "ATKG"
+#define ACPI_SIG_GSCI "GSCI" /* GMCH SCI table */
+#define ACPI_SIG_IEIT "IEIT"
+#endif
+
+/*
+ * All tables must be byte-packed to match the ACPI specification, since
+ * the tables are provided by the system BIOS.
+ */
+#pragma pack(1)
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+
+/*******************************************************************************
+ *
+ * ASF - Alert Standard Format table (Signature "ASF!")
+ * Revision 0x10
+ *
+ * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_asf
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_ASF;
+
+
+/* ASF subtable header */
+
+typedef struct acpi_asf_header
+{
+ UINT8 Type;
+ UINT8 Reserved;
+ UINT16 Length;
+
+} ACPI_ASF_HEADER;
+
+
+/* Values for Type field above */
+
+enum AcpiAsfType
+{
+ ACPI_ASF_TYPE_INFO = 0,
+ ACPI_ASF_TYPE_ALERT = 1,
+ ACPI_ASF_TYPE_CONTROL = 2,
+ ACPI_ASF_TYPE_BOOT = 3,
+ ACPI_ASF_TYPE_ADDRESS = 4,
+ ACPI_ASF_TYPE_RESERVED = 5
+};
+
+/*
+ * ASF subtables
+ */
+
+/* 0: ASF Information */
+
+typedef struct acpi_asf_info
+{
+ ACPI_ASF_HEADER Header;
+ UINT8 MinResetValue;
+ UINT8 MinPollInterval;
+ UINT16 SystemId;
+ UINT32 MfgId;
+ UINT8 Flags;
+ UINT8 Reserved2[3];
+
+} ACPI_ASF_INFO;
+
+/* Masks for Flags field above */
+
+#define ACPI_ASF_SMBUS_PROTOCOLS (1)
+
+
+/* 1: ASF Alerts */
+
+typedef struct acpi_asf_alert
+{
+ ACPI_ASF_HEADER Header;
+ UINT8 AssertMask;
+ UINT8 DeassertMask;
+ UINT8 Alerts;
+ UINT8 DataLength;
+
+} ACPI_ASF_ALERT;
+
+typedef struct acpi_asf_alert_data
+{
+ UINT8 Address;
+ UINT8 Command;
+ UINT8 Mask;
+ UINT8 Value;
+ UINT8 SensorType;
+ UINT8 Type;
+ UINT8 Offset;
+ UINT8 SourceType;
+ UINT8 Severity;
+ UINT8 SensorNumber;
+ UINT8 Entity;
+ UINT8 Instance;
+
+} ACPI_ASF_ALERT_DATA;
+
+
+/* 2: ASF Remote Control */
+
+typedef struct acpi_asf_remote
+{
+ ACPI_ASF_HEADER Header;
+ UINT8 Controls;
+ UINT8 DataLength;
+ UINT16 Reserved2;
+
+} ACPI_ASF_REMOTE;
+
+typedef struct acpi_asf_control_data
+{
+ UINT8 Function;
+ UINT8 Address;
+ UINT8 Command;
+ UINT8 Value;
+
+} ACPI_ASF_CONTROL_DATA;
+
+
+/* 3: ASF RMCP Boot Options */
+
+typedef struct acpi_asf_rmcp
+{
+ ACPI_ASF_HEADER Header;
+ UINT8 Capabilities[7];
+ UINT8 CompletionCode;
+ UINT32 EnterpriseId;
+ UINT8 Command;
+ UINT16 Parameter;
+ UINT16 BootOptions;
+ UINT16 OemParameters;
+
+} ACPI_ASF_RMCP;
+
+
+/* 4: ASF Address */
+
+typedef struct acpi_asf_address
+{
+ ACPI_ASF_HEADER Header;
+ UINT8 EpromAddress;
+ UINT8 Devices;
+
+} ACPI_ASF_ADDRESS;
+
+
+/*******************************************************************************
+ *
+ * BOOT - Simple Boot Flag Table
+ * Version 1
+ *
+ * Conforms to the "Simple Boot Flag Specification", Version 2.1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_boot
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 CmosIndex; /* Index in CMOS RAM for the boot register */
+ UINT8 Reserved[3];
+
+} ACPI_TABLE_BOOT;
+
+
+/*******************************************************************************
+ *
+ * CSRT - Core System Resource Table
+ * Version 0
+ *
+ * Conforms to the "Core System Resource Table (CSRT)", November 14, 2011
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_csrt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_CSRT;
+
+
+/* Resource Group subtable */
+
+typedef struct acpi_csrt_group
+{
+ UINT32 Length;
+ UINT32 VendorId;
+ UINT32 SubvendorId;
+ UINT16 DeviceId;
+ UINT16 SubdeviceId;
+ UINT16 Revision;
+ UINT16 Reserved;
+ UINT32 SharedInfoLength;
+
+ /* Shared data immediately follows (Length = SharedInfoLength) */
+
+} ACPI_CSRT_GROUP;
+
+/* Shared Info subtable */
+
+typedef struct acpi_csrt_shared_info
+{
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 MmioBaseLow;
+ UINT32 MmioBaseHigh;
+ UINT32 GsiInterrupt;
+ UINT8 InterruptPolarity;
+ UINT8 InterruptMode;
+ UINT8 NumChannels;
+ UINT8 DmaAddressWidth;
+ UINT16 BaseRequestLine;
+ UINT16 NumHandshakeSignals;
+ UINT32 MaxBlockSize;
+
+ /* Resource descriptors immediately follow (Length = Group Length - SharedInfoLength) */
+
+} ACPI_CSRT_SHARED_INFO;
+
+/* Resource Descriptor subtable */
+
+typedef struct acpi_csrt_descriptor
+{
+ UINT32 Length;
+ UINT16 Type;
+ UINT16 Subtype;
+ UINT32 Uid;
+
+ /* Resource-specific information immediately follows */
+
+} ACPI_CSRT_DESCRIPTOR;
+
+
+/* Resource Types */
+
+#define ACPI_CSRT_TYPE_INTERRUPT 0x0001
+#define ACPI_CSRT_TYPE_TIMER 0x0002
+#define ACPI_CSRT_TYPE_DMA 0x0003
+
+/* Resource Subtypes */
+
+#define ACPI_CSRT_XRUPT_LINE 0x0000
+#define ACPI_CSRT_XRUPT_CONTROLLER 0x0001
+#define ACPI_CSRT_TIMER 0x0000
+#define ACPI_CSRT_DMA_CHANNEL 0x0000
+#define ACPI_CSRT_DMA_CONTROLLER 0x0001
+
+
+/*******************************************************************************
+ *
+ * DBG2 - Debug Port Table 2
+ * Version 0 (Both main table and subtables)
+ *
+ * Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_dbg2
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 InfoOffset;
+ UINT32 InfoCount;
+
+} ACPI_TABLE_DBG2;
+
+
+typedef struct acpi_dbg2_header
+{
+ UINT32 InfoOffset;
+ UINT32 InfoCount;
+
+} ACPI_DBG2_HEADER;
+
+
+/* Debug Device Information Subtable */
+
+typedef struct acpi_dbg2_device
+{
+ UINT8 Revision;
+ UINT16 Length;
+ UINT8 RegisterCount; /* Number of BaseAddress registers */
+ UINT16 NamepathLength;
+ UINT16 NamepathOffset;
+ UINT16 OemDataLength;
+ UINT16 OemDataOffset;
+ UINT16 PortType;
+ UINT16 PortSubtype;
+ UINT16 Reserved;
+ UINT16 BaseAddressOffset;
+ UINT16 AddressSizeOffset;
+ /*
+ * Data that follows:
+ * BaseAddress (required) - Each in 12-byte Generic Address Structure format.
+ * AddressSize (required) - Array of UINT32 sizes corresponding to each BaseAddress register.
+ * Namepath (required) - Null terminated string. Single dot if not supported.
+ * OemData (optional) - Length is OemDataLength.
+ */
+} ACPI_DBG2_DEVICE;
+
+/* Types for PortType field above */
+
+#define ACPI_DBG2_SERIAL_PORT 0x8000
+#define ACPI_DBG2_1394_PORT 0x8001
+#define ACPI_DBG2_USB_PORT 0x8002
+#define ACPI_DBG2_NET_PORT 0x8003
+
+/* Subtypes for PortSubtype field above */
+
+#define ACPI_DBG2_16550_COMPATIBLE 0x0000
+#define ACPI_DBG2_16550_SUBSET 0x0001
+
+#define ACPI_DBG2_1394_STANDARD 0x0000
+
+#define ACPI_DBG2_USB_XHCI 0x0000
+#define ACPI_DBG2_USB_EHCI 0x0001
+
+
+/*******************************************************************************
+ *
+ * DBGP - Debug Port table
+ * Version 1
+ *
+ * Conforms to the "Debug Port Specification", Version 1.00, 2/9/2000
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_dbgp
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 Type; /* 0=full 16550, 1=subset of 16550 */
+ UINT8 Reserved[3];
+ ACPI_GENERIC_ADDRESS DebugPort;
+
+} ACPI_TABLE_DBGP;
+
+
+/*******************************************************************************
+ *
+ * DMAR - DMA Remapping table
+ * Version 1
+ *
+ * Conforms to "Intel Virtualization Technology for Directed I/O",
+ * Version 2.2, Sept. 2013
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_dmar
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 Width; /* Host Address Width */
+ UINT8 Flags;
+ UINT8 Reserved[10];
+
+} ACPI_TABLE_DMAR;
+
+/* Masks for Flags field above */
+
+#define ACPI_DMAR_INTR_REMAP (1)
+#define ACPI_DMAR_X2APIC_OPT_OUT (2)
+
+
+/* DMAR subtable header */
+
+typedef struct acpi_dmar_header
+{
+ UINT16 Type;
+ UINT16 Length;
+
+} ACPI_DMAR_HEADER;
+
+/* Values for subtable type in ACPI_DMAR_HEADER */
+
+enum AcpiDmarType
+{
+ ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,
+ ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
+ ACPI_DMAR_TYPE_ROOT_ATS = 2,
+ ACPI_DMAR_TYPE_HARDWARE_AFFINITY = 3,
+ ACPI_DMAR_TYPE_NAMESPACE = 4,
+ ACPI_DMAR_TYPE_RESERVED = 5 /* 5 and greater are reserved */
+};
+
+
+/* DMAR Device Scope structure */
+
+typedef struct acpi_dmar_device_scope
+{
+ UINT8 EntryType;
+ UINT8 Length;
+ UINT16 Reserved;
+ UINT8 EnumerationId;
+ UINT8 Bus;
+
+} ACPI_DMAR_DEVICE_SCOPE;
+
+/* Values for EntryType in ACPI_DMAR_DEVICE_SCOPE - device types */
+
+enum AcpiDmarScopeType
+{
+ ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
+ ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
+ ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
+ ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
+ ACPI_DMAR_SCOPE_TYPE_HPET = 4,
+ ACPI_DMAR_SCOPE_TYPE_NAMESPACE = 5,
+ ACPI_DMAR_SCOPE_TYPE_RESERVED = 6 /* 6 and greater are reserved */
+};
+
+typedef struct acpi_dmar_pci_path
+{
+ UINT8 Device;
+ UINT8 Function;
+
+} ACPI_DMAR_PCI_PATH;
+
+
+/*
+ * DMAR Subtables, correspond to Type in ACPI_DMAR_HEADER
+ */
+
+/* 0: Hardware Unit Definition */
+
+typedef struct acpi_dmar_hardware_unit
+{
+ ACPI_DMAR_HEADER Header;
+ UINT8 Flags;
+ UINT8 Reserved;
+ UINT16 Segment;
+ UINT64 Address; /* Register Base Address */
+
+} ACPI_DMAR_HARDWARE_UNIT;
+
+/* Masks for Flags field above */
+
+#define ACPI_DMAR_INCLUDE_ALL (1)
+
+
+/* 1: Reserved Memory Defininition */
+
+typedef struct acpi_dmar_reserved_memory
+{
+ ACPI_DMAR_HEADER Header;
+ UINT16 Reserved;
+ UINT16 Segment;
+ UINT64 BaseAddress; /* 4K aligned base address */
+ UINT64 EndAddress; /* 4K aligned limit address */
+
+} ACPI_DMAR_RESERVED_MEMORY;
+
+/* Masks for Flags field above */
+
+#define ACPI_DMAR_ALLOW_ALL (1)
+
+
+/* 2: Root Port ATS Capability Reporting Structure */
+
+typedef struct acpi_dmar_atsr
+{
+ ACPI_DMAR_HEADER Header;
+ UINT8 Flags;
+ UINT8 Reserved;
+ UINT16 Segment;
+
+} ACPI_DMAR_ATSR;
+
+/* Masks for Flags field above */
+
+#define ACPI_DMAR_ALL_PORTS (1)
+
+
+/* 3: Remapping Hardware Static Affinity Structure */
+
+typedef struct acpi_dmar_rhsa
+{
+ ACPI_DMAR_HEADER Header;
+ UINT32 Reserved;
+ UINT64 BaseAddress;
+ UINT32 ProximityDomain;
+
+} ACPI_DMAR_RHSA;
+
+
+/* 4: ACPI Namespace Device Declaration Structure */
+
+typedef struct acpi_dmar_andd
+{
+ ACPI_DMAR_HEADER Header;
+ UINT8 Reserved[3];
+ UINT8 DeviceNumber;
+ char DeviceName[1];
+
+} ACPI_DMAR_ANDD;
+
+
+/*******************************************************************************
+ *
+ * HPET - High Precision Event Timer table
+ * Version 1
+ *
+ * Conforms to "IA-PC HPET (High Precision Event Timers) Specification",
+ * Version 1.0a, October 2004
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_hpet
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Id; /* Hardware ID of event timer block */
+ ACPI_GENERIC_ADDRESS Address; /* Address of event timer block */
+ UINT8 Sequence; /* HPET sequence number */
+ UINT16 MinimumTick; /* Main counter min tick, periodic mode */
+ UINT8 Flags;
+
+} ACPI_TABLE_HPET;
+
+/* Masks for Flags field above */
+
+#define ACPI_HPET_PAGE_PROTECT_MASK (3)
+
+/* Values for Page Protect flags */
+
+enum AcpiHpetPageProtect
+{
+ ACPI_HPET_NO_PAGE_PROTECT = 0,
+ ACPI_HPET_PAGE_PROTECT4 = 1,
+ ACPI_HPET_PAGE_PROTECT64 = 2
+};
+
+
+/*******************************************************************************
+ *
+ * IBFT - Boot Firmware Table
+ * Version 1
+ *
+ * Conforms to "iSCSI Boot Firmware Table (iBFT) as Defined in ACPI 3.0b
+ * Specification", Version 1.01, March 1, 2007
+ *
+ * Note: It appears that this table is not intended to appear in the RSDT/XSDT.
+ * Therefore, it is not currently supported by the disassembler.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_ibft
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 Reserved[12];
+
+} ACPI_TABLE_IBFT;
+
+
+/* IBFT common subtable header */
+
+typedef struct acpi_ibft_header
+{
+ UINT8 Type;
+ UINT8 Version;
+ UINT16 Length;
+ UINT8 Index;
+ UINT8 Flags;
+
+} ACPI_IBFT_HEADER;
+
+/* Values for Type field above */
+
+enum AcpiIbftType
+{
+ ACPI_IBFT_TYPE_NOT_USED = 0,
+ ACPI_IBFT_TYPE_CONTROL = 1,
+ ACPI_IBFT_TYPE_INITIATOR = 2,
+ ACPI_IBFT_TYPE_NIC = 3,
+ ACPI_IBFT_TYPE_TARGET = 4,
+ ACPI_IBFT_TYPE_EXTENSIONS = 5,
+ ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */
+};
+
+
+/* IBFT subtables */
+
+typedef struct acpi_ibft_control
+{
+ ACPI_IBFT_HEADER Header;
+ UINT16 Extensions;
+ UINT16 InitiatorOffset;
+ UINT16 Nic0Offset;
+ UINT16 Target0Offset;
+ UINT16 Nic1Offset;
+ UINT16 Target1Offset;
+
+} ACPI_IBFT_CONTROL;
+
+typedef struct acpi_ibft_initiator
+{
+ ACPI_IBFT_HEADER Header;
+ UINT8 SnsServer[16];
+ UINT8 SlpServer[16];
+ UINT8 PrimaryServer[16];
+ UINT8 SecondaryServer[16];
+ UINT16 NameLength;
+ UINT16 NameOffset;
+
+} ACPI_IBFT_INITIATOR;
+
+typedef struct acpi_ibft_nic
+{
+ ACPI_IBFT_HEADER Header;
+ UINT8 IpAddress[16];
+ UINT8 SubnetMaskPrefix;
+ UINT8 Origin;
+ UINT8 Gateway[16];
+ UINT8 PrimaryDns[16];
+ UINT8 SecondaryDns[16];
+ UINT8 Dhcp[16];
+ UINT16 Vlan;
+ UINT8 MacAddress[6];
+ UINT16 PciAddress;
+ UINT16 NameLength;
+ UINT16 NameOffset;
+
+} ACPI_IBFT_NIC;
+
+typedef struct acpi_ibft_target
+{
+ ACPI_IBFT_HEADER Header;
+ UINT8 TargetIpAddress[16];
+ UINT16 TargetIpSocket;
+ UINT8 TargetBootLun[8];
+ UINT8 ChapType;
+ UINT8 NicAssociation;
+ UINT16 TargetNameLength;
+ UINT16 TargetNameOffset;
+ UINT16 ChapNameLength;
+ UINT16 ChapNameOffset;
+ UINT16 ChapSecretLength;
+ UINT16 ChapSecretOffset;
+ UINT16 ReverseChapNameLength;
+ UINT16 ReverseChapNameOffset;
+ UINT16 ReverseChapSecretLength;
+ UINT16 ReverseChapSecretOffset;
+
+} ACPI_IBFT_TARGET;
+
+
+/*******************************************************************************
+ *
+ * IORT - IO Remapping Table
+ *
+ * Conforms to "IO Remapping Table System Software on ARM Platforms",
+ * Document number: ARM DEN 0049A, 2015
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_iort
+{
+ ACPI_TABLE_HEADER Header;
+ UINT32 NodeCount;
+ UINT32 NodeOffset;
+ UINT32 Reserved;
+
+} ACPI_TABLE_IORT;
+
+
+/*
+ * IORT subtables
+ */
+typedef struct acpi_iort_node
+{
+ UINT8 Type;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT32 Reserved;
+ UINT32 MappingCount;
+ UINT32 MappingOffset;
+ char NodeData[1];
+
+} ACPI_IORT_NODE;
+
+/* Values for subtable Type above */
+
+enum AcpiIortNodeType
+{
+ ACPI_IORT_NODE_ITS_GROUP = 0x00,
+ ACPI_IORT_NODE_NAMED_COMPONENT = 0x01,
+ ACPI_IORT_NODE_PCI_ROOT_COMPLEX = 0x02,
+ ACPI_IORT_NODE_SMMU = 0x03
+};
+
+
+typedef struct acpi_iort_id_mapping
+{
+ UINT32 InputBase; /* Lowest value in input range */
+ UINT32 IdCount; /* Number of IDs */
+ UINT32 OutputBase; /* Lowest value in output range */
+ UINT32 OutputReference; /* A reference to the output node */
+ UINT32 Flags;
+
+} ACPI_IORT_ID_MAPPING;
+
+/* Masks for Flags field above for IORT subtable */
+
+#define ACPI_IORT_ID_SINGLE_MAPPING (1)
+
+
+typedef struct acpi_iort_memory_access
+{
+ UINT32 CacheCoherency;
+ UINT8 Hints;
+ UINT16 Reserved;
+ UINT8 MemoryFlags;
+
+} ACPI_IORT_MEMORY_ACCESS;
+
+/* Values for CacheCoherency field above */
+
+#define ACPI_IORT_NODE_COHERENT 0x00000001 /* The device node is fully coherent */
+#define ACPI_IORT_NODE_NOT_COHERENT 0x00000000 /* The device node is not coherent */
+
+/* Masks for Hints field above */
+
+#define ACPI_IORT_HT_TRANSIENT (1)
+#define ACPI_IORT_HT_WRITE (1<<1)
+#define ACPI_IORT_HT_READ (1<<2)
+#define ACPI_IORT_HT_OVERRIDE (1<<3)
+
+/* Masks for MemoryFlags field above */
+
+#define ACPI_IORT_MF_COHERENCY (1)
+#define ACPI_IORT_MF_ATTRIBUTES (1<<1)
+
+
+/*
+ * IORT node specific subtables
+ */
+typedef struct acpi_iort_its_group
+{
+ UINT32 ItsCount;
+ UINT32 Identifiers[1]; /* GIC ITS identifier arrary */
+
+} ACPI_IORT_ITS_GROUP;
+
+
+typedef struct acpi_iort_named_component
+{
+ UINT32 NodeFlags;
+ UINT64 MemoryProperties; /* Memory access properties */
+ UINT8 MemoryAddressLimit; /* Memory address size limit */
+ char DeviceName[1]; /* Path of namespace object */
+
+} ACPI_IORT_NAMED_COMPONENT;
+
+
+typedef struct acpi_iort_root_complex
+{
+ UINT64 MemoryProperties; /* Memory access properties */
+ UINT32 AtsAttribute;
+ UINT32 PciSegmentNumber;
+
+} ACPI_IORT_ROOT_COMPLEX;
+
+/* Values for AtsAttribute field above */
+
+#define ACPI_IORT_ATS_SUPPORTED 0x00000001 /* The root complex supports ATS */
+#define ACPI_IORT_ATS_UNSUPPORTED 0x00000000 /* The root complex doesn't support ATS */
+
+
+typedef struct acpi_iort_smmu
+{
+ UINT64 BaseAddress; /* SMMU base address */
+ UINT64 Span; /* Length of memory range */
+ UINT32 Model;
+ UINT32 Flags;
+ UINT32 GlobalInterruptOffset;
+ UINT32 ContextInterruptCount;
+ UINT32 ContextInterruptOffset;
+ UINT32 PmuInterruptCount;
+ UINT32 PmuInterruptOffset;
+ UINT64 Interrupts[1]; /* Interrupt array */
+
+} ACPI_IORT_SMMU;
+
+/* Values for Model field above */
+
+#define ACPI_IORT_SMMU_V1 0x00000000 /* Generic SMMUv1 */
+#define ACPI_IORT_SMMU_V2 0x00000001 /* Generic SMMUv2 */
+#define ACPI_IORT_SMMU_CORELINK_MMU400 0x00000002 /* ARM Corelink MMU-400 */
+#define ACPI_IORT_SMMU_CORELINK_MMU500 0x00000003 /* ARM Corelink MMU-500 */
+
+/* Masks for Flags field above */
+
+#define ACPI_IORT_SMMU_DVM_SUPPORTED (1)
+#define ACPI_IORT_SMMU_COHERENT_WALK (1<<1)
+
+
+/*******************************************************************************
+ *
+ * IVRS - I/O Virtualization Reporting Structure
+ * Version 1
+ *
+ * Conforms to "AMD I/O Virtualization Technology (IOMMU) Specification",
+ * Revision 1.26, February 2009.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_ivrs
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Info; /* Common virtualization info */
+ UINT64 Reserved;
+
+} ACPI_TABLE_IVRS;
+
+/* Values for Info field above */
+
+#define ACPI_IVRS_PHYSICAL_SIZE 0x00007F00 /* 7 bits, physical address size */
+#define ACPI_IVRS_VIRTUAL_SIZE 0x003F8000 /* 7 bits, virtual address size */
+#define ACPI_IVRS_ATS_RESERVED 0x00400000 /* ATS address translation range reserved */
+
+
+/* IVRS subtable header */
+
+typedef struct acpi_ivrs_header
+{
+ UINT8 Type; /* Subtable type */
+ UINT8 Flags;
+ UINT16 Length; /* Subtable length */
+ UINT16 DeviceId; /* ID of IOMMU */
+
+} ACPI_IVRS_HEADER;
+
+/* Values for subtable Type above */
+
+enum AcpiIvrsType
+{
+ ACPI_IVRS_TYPE_HARDWARE = 0x10,
+ ACPI_IVRS_TYPE_MEMORY1 = 0x20,
+ ACPI_IVRS_TYPE_MEMORY2 = 0x21,
+ ACPI_IVRS_TYPE_MEMORY3 = 0x22
+};
+
+/* Masks for Flags field above for IVHD subtable */
+
+#define ACPI_IVHD_TT_ENABLE (1)
+#define ACPI_IVHD_PASS_PW (1<<1)
+#define ACPI_IVHD_RES_PASS_PW (1<<2)
+#define ACPI_IVHD_ISOC (1<<3)
+#define ACPI_IVHD_IOTLB (1<<4)
+
+/* Masks for Flags field above for IVMD subtable */
+
+#define ACPI_IVMD_UNITY (1)
+#define ACPI_IVMD_READ (1<<1)
+#define ACPI_IVMD_WRITE (1<<2)
+#define ACPI_IVMD_EXCLUSION_RANGE (1<<3)
+
+
+/*
+ * IVRS subtables, correspond to Type in ACPI_IVRS_HEADER
+ */
+
+/* 0x10: I/O Virtualization Hardware Definition Block (IVHD) */
+
+typedef struct acpi_ivrs_hardware
+{
+ ACPI_IVRS_HEADER Header;
+ UINT16 CapabilityOffset; /* Offset for IOMMU control fields */
+ UINT64 BaseAddress; /* IOMMU control registers */
+ UINT16 PciSegmentGroup;
+ UINT16 Info; /* MSI number and unit ID */
+ UINT32 Reserved;
+
+} ACPI_IVRS_HARDWARE;
+
+/* Masks for Info field above */
+
+#define ACPI_IVHD_MSI_NUMBER_MASK 0x001F /* 5 bits, MSI message number */
+#define ACPI_IVHD_UNIT_ID_MASK 0x1F00 /* 5 bits, UnitID */
+
+
+/*
+ * Device Entries for IVHD subtable, appear after ACPI_IVRS_HARDWARE structure.
+ * Upper two bits of the Type field are the (encoded) length of the structure.
+ * Currently, only 4 and 8 byte entries are defined. 16 and 32 byte entries
+ * are reserved for future use but not defined.
+ */
+typedef struct acpi_ivrs_de_header
+{
+ UINT8 Type;
+ UINT16 Id;
+ UINT8 DataSetting;
+
+} ACPI_IVRS_DE_HEADER;
+
+/* Length of device entry is in the top two bits of Type field above */
+
+#define ACPI_IVHD_ENTRY_LENGTH 0xC0
+
+/* Values for device entry Type field above */
+
+enum AcpiIvrsDeviceEntryType
+{
+ /* 4-byte device entries, all use ACPI_IVRS_DEVICE4 */
+
+ ACPI_IVRS_TYPE_PAD4 = 0,
+ ACPI_IVRS_TYPE_ALL = 1,
+ ACPI_IVRS_TYPE_SELECT = 2,
+ ACPI_IVRS_TYPE_START = 3,
+ ACPI_IVRS_TYPE_END = 4,
+
+ /* 8-byte device entries */
+
+ ACPI_IVRS_TYPE_PAD8 = 64,
+ ACPI_IVRS_TYPE_NOT_USED = 65,
+ ACPI_IVRS_TYPE_ALIAS_SELECT = 66, /* Uses ACPI_IVRS_DEVICE8A */
+ ACPI_IVRS_TYPE_ALIAS_START = 67, /* Uses ACPI_IVRS_DEVICE8A */
+ ACPI_IVRS_TYPE_EXT_SELECT = 70, /* Uses ACPI_IVRS_DEVICE8B */
+ ACPI_IVRS_TYPE_EXT_START = 71, /* Uses ACPI_IVRS_DEVICE8B */
+ ACPI_IVRS_TYPE_SPECIAL = 72 /* Uses ACPI_IVRS_DEVICE8C */
+};
+
+/* Values for Data field above */
+
+#define ACPI_IVHD_INIT_PASS (1)
+#define ACPI_IVHD_EINT_PASS (1<<1)
+#define ACPI_IVHD_NMI_PASS (1<<2)
+#define ACPI_IVHD_SYSTEM_MGMT (3<<4)
+#define ACPI_IVHD_LINT0_PASS (1<<6)
+#define ACPI_IVHD_LINT1_PASS (1<<7)
+
+
+/* Types 0-4: 4-byte device entry */
+
+typedef struct acpi_ivrs_device4
+{
+ ACPI_IVRS_DE_HEADER Header;
+
+} ACPI_IVRS_DEVICE4;
+
+/* Types 66-67: 8-byte device entry */
+
+typedef struct acpi_ivrs_device8a
+{
+ ACPI_IVRS_DE_HEADER Header;
+ UINT8 Reserved1;
+ UINT16 UsedId;
+ UINT8 Reserved2;
+
+} ACPI_IVRS_DEVICE8A;
+
+/* Types 70-71: 8-byte device entry */
+
+typedef struct acpi_ivrs_device8b
+{
+ ACPI_IVRS_DE_HEADER Header;
+ UINT32 ExtendedData;
+
+} ACPI_IVRS_DEVICE8B;
+
+/* Values for ExtendedData above */
+
+#define ACPI_IVHD_ATS_DISABLED (1<<31)
+
+/* Type 72: 8-byte device entry */
+
+typedef struct acpi_ivrs_device8c
+{
+ ACPI_IVRS_DE_HEADER Header;
+ UINT8 Handle;
+ UINT16 UsedId;
+ UINT8 Variety;
+
+} ACPI_IVRS_DEVICE8C;
+
+/* Values for Variety field above */
+
+#define ACPI_IVHD_IOAPIC 1
+#define ACPI_IVHD_HPET 2
+
+
+/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition Block (IVMD) */
+
+typedef struct acpi_ivrs_memory
+{
+ ACPI_IVRS_HEADER Header;
+ UINT16 AuxData;
+ UINT64 Reserved;
+ UINT64 StartAddress;
+ UINT64 MemoryLength;
+
+} ACPI_IVRS_MEMORY;
+
+
+/*******************************************************************************
+ *
+ * LPIT - Low Power Idle Table
+ *
+ * Conforms to "ACPI Low Power Idle Table (LPIT)" July 2014.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_lpit
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_LPIT;
+
+
+/* LPIT subtable header */
+
+typedef struct acpi_lpit_header
+{
+ UINT32 Type; /* Subtable type */
+ UINT32 Length; /* Subtable length */
+ UINT16 UniqueId;
+ UINT16 Reserved;
+ UINT32 Flags;
+
+} ACPI_LPIT_HEADER;
+
+/* Values for subtable Type above */
+
+enum AcpiLpitType
+{
+ ACPI_LPIT_TYPE_NATIVE_CSTATE = 0x00,
+ ACPI_LPIT_TYPE_RESERVED = 0x01 /* 1 and above are reserved */
+};
+
+/* Masks for Flags field above */
+
+#define ACPI_LPIT_STATE_DISABLED (1)
+#define ACPI_LPIT_NO_COUNTER (1<<1)
+
+/*
+ * LPIT subtables, correspond to Type in ACPI_LPIT_HEADER
+ */
+
+/* 0x00: Native C-state instruction based LPI structure */
+
+typedef struct acpi_lpit_native
+{
+ ACPI_LPIT_HEADER Header;
+ ACPI_GENERIC_ADDRESS EntryTrigger;
+ UINT32 Residency;
+ UINT32 Latency;
+ ACPI_GENERIC_ADDRESS ResidencyCounter;
+ UINT64 CounterFrequency;
+
+} ACPI_LPIT_NATIVE;
+
+
+/*******************************************************************************
+ *
+ * MCFG - PCI Memory Mapped Configuration table and subtable
+ * Version 1
+ *
+ * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_mcfg
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 Reserved[8];
+
+} ACPI_TABLE_MCFG;
+
+
+/* Subtable */
+
+typedef struct acpi_mcfg_allocation
+{
+ UINT64 Address; /* Base address, processor-relative */
+ UINT16 PciSegment; /* PCI segment group number */
+ UINT8 StartBusNumber; /* Starting PCI Bus number */
+ UINT8 EndBusNumber; /* Final PCI Bus number */
+ UINT32 Reserved;
+
+} ACPI_MCFG_ALLOCATION;
+
+
+/*******************************************************************************
+ *
+ * MCHI - Management Controller Host Interface Table
+ * Version 1
+ *
+ * Conforms to "Management Component Transport Protocol (MCTP) Host
+ * Interface Specification", Revision 1.0.0a, October 13, 2009
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_mchi
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 InterfaceType;
+ UINT8 Protocol;
+ UINT64 ProtocolData;
+ UINT8 InterruptType;
+ UINT8 Gpe;
+ UINT8 PciDeviceFlag;
+ UINT32 GlobalInterrupt;
+ ACPI_GENERIC_ADDRESS ControlRegister;
+ UINT8 PciSegment;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunction;
+
+} ACPI_TABLE_MCHI;
+
+
+/*******************************************************************************
+ *
+ * MSDM - Microsoft Data Management table
+ *
+ * Conforms to "Microsoft Software Licensing Tables (SLIC and MSDM)",
+ * November 29, 2011. Copyright 2011 Microsoft
+ *
+ ******************************************************************************/
+
+/* Basic MSDM table is only the common ACPI header */
+
+typedef struct acpi_table_msdm
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_MSDM;
+
+
+/*******************************************************************************
+ *
+ * MTMR - MID Timer Table
+ * Version 1
+ *
+ * Conforms to "Simple Firmware Interface Specification",
+ * Draft 0.8.2, Oct 19, 2010
+ * NOTE: The ACPI MTMR is equivalent to the SFI MTMR table.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_mtmr
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_MTMR;
+
+/* MTMR entry */
+
+typedef struct acpi_mtmr_entry
+{
+ ACPI_GENERIC_ADDRESS PhysicalAddress;
+ UINT32 Frequency;
+ UINT32 Irq;
+
+} ACPI_MTMR_ENTRY;
+
+
+/*******************************************************************************
+ *
+ * SLIC - Software Licensing Description Table
+ *
+ * Conforms to "Microsoft Software Licensing Tables (SLIC and MSDM)",
+ * November 29, 2011. Copyright 2011 Microsoft
+ *
+ ******************************************************************************/
+
+/* Basic SLIC table is only the common ACPI header */
+
+typedef struct acpi_table_slic
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_SLIC;
+
+
+/*******************************************************************************
+ *
+ * SPCR - Serial Port Console Redirection table
+ * Version 1
+ *
+ * Conforms to "Serial Port Console Redirection Table",
+ * Version 1.00, January 11, 2002
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_spcr
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 InterfaceType; /* 0=full 16550, 1=subset of 16550 */
+ UINT8 Reserved[3];
+ ACPI_GENERIC_ADDRESS SerialPort;
+ UINT8 InterruptType;
+ UINT8 PcInterrupt;
+ UINT32 Interrupt;
+ UINT8 BaudRate;
+ UINT8 Parity;
+ UINT8 StopBits;
+ UINT8 FlowControl;
+ UINT8 TerminalType;
+ UINT8 Reserved1;
+ UINT16 PciDeviceId;
+ UINT16 PciVendorId;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunction;
+ UINT32 PciFlags;
+ UINT8 PciSegment;
+ UINT32 Reserved2;
+
+} ACPI_TABLE_SPCR;
+
+/* Masks for PciFlags field above */
+
+#define ACPI_SPCR_DO_NOT_DISABLE (1)
+
+
+/*******************************************************************************
+ *
+ * SPMI - Server Platform Management Interface table
+ * Version 5
+ *
+ * Conforms to "Intelligent Platform Management Interface Specification
+ * Second Generation v2.0", Document Revision 1.0, February 12, 2004 with
+ * June 12, 2009 markup.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_spmi
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 InterfaceType;
+ UINT8 Reserved; /* Must be 1 */
+ UINT16 SpecRevision; /* Version of IPMI */
+ UINT8 InterruptType;
+ UINT8 GpeNumber; /* GPE assigned */
+ UINT8 Reserved1;
+ UINT8 PciDeviceFlag;
+ UINT32 Interrupt;
+ ACPI_GENERIC_ADDRESS IpmiRegister;
+ UINT8 PciSegment;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunction;
+ UINT8 Reserved2;
+
+} ACPI_TABLE_SPMI;
+
+/* Values for InterfaceType above */
+
+enum AcpiSpmiInterfaceTypes
+{
+ ACPI_SPMI_NOT_USED = 0,
+ ACPI_SPMI_KEYBOARD = 1,
+ ACPI_SPMI_SMI = 2,
+ ACPI_SPMI_BLOCK_TRANSFER = 3,
+ ACPI_SPMI_SMBUS = 4,
+ ACPI_SPMI_RESERVED = 5 /* 5 and above are reserved */
+};
+
+
+/*******************************************************************************
+ *
+ * TCPA - Trusted Computing Platform Alliance table
+ * Version 2
+ *
+ * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
+ * December 19, 2014
+ *
+ * NOTE: There are two versions of the table with the same signature --
+ * the client version and the server version. The common PlatformClass
+ * field is used to differentiate the two types of tables.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_tcpa_hdr
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 PlatformClass;
+
+} ACPI_TABLE_TCPA_HDR;
+
+/*
+ * Values for PlatformClass above.
+ * This is how the client and server subtables are differentiated
+ */
+#define ACPI_TCPA_CLIENT_TABLE 0
+#define ACPI_TCPA_SERVER_TABLE 1
+
+
+typedef struct acpi_table_tcpa_client
+{
+ UINT32 MinimumLogLength; /* Minimum length for the event log area */
+ UINT64 LogAddress; /* Address of the event log area */
+
+} ACPI_TABLE_TCPA_CLIENT;
+
+typedef struct acpi_table_tcpa_server
+{
+ UINT16 Reserved;
+ UINT64 MinimumLogLength; /* Minimum length for the event log area */
+ UINT64 LogAddress; /* Address of the event log area */
+ UINT16 SpecRevision;
+ UINT8 DeviceFlags;
+ UINT8 InterruptFlags;
+ UINT8 GpeNumber;
+ UINT8 Reserved2[3];
+ UINT32 GlobalInterrupt;
+ ACPI_GENERIC_ADDRESS Address;
+ UINT32 Reserved3;
+ ACPI_GENERIC_ADDRESS ConfigAddress;
+ UINT8 Group;
+ UINT8 Bus; /* PCI Bus/Segment/Function numbers */
+ UINT8 Device;
+ UINT8 Function;
+
+} ACPI_TABLE_TCPA_SERVER;
+
+/* Values for DeviceFlags above */
+
+#define ACPI_TCPA_PCI_DEVICE (1)
+#define ACPI_TCPA_BUS_PNP (1<<1)
+#define ACPI_TCPA_ADDRESS_VALID (1<<2)
+
+/* Values for InterruptFlags above */
+
+#define ACPI_TCPA_INTERRUPT_MODE (1)
+#define ACPI_TCPA_INTERRUPT_POLARITY (1<<1)
+#define ACPI_TCPA_SCI_VIA_GPE (1<<2)
+#define ACPI_TCPA_GLOBAL_INTERRUPT (1<<3)
+
+
+/*******************************************************************************
+ *
+ * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
+ * Version 4
+ *
+ * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
+ * December 19, 2014
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_tpm2
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 PlatformClass;
+ UINT16 Reserved;
+ UINT64 ControlAddress;
+ UINT32 StartMethod;
+
+ /* Platform-specific data follows */
+
+} ACPI_TABLE_TPM2;
+
+/* Values for StartMethod above */
+
+#define ACPI_TPM2_NOT_ALLOWED 0
+#define ACPI_TPM2_START_METHOD 2
+#define ACPI_TPM2_MEMORY_MAPPED 6
+#define ACPI_TPM2_COMMAND_BUFFER 7
+#define ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD 8
+
+
+/*******************************************************************************
+ *
+ * UEFI - UEFI Boot optimization Table
+ * Version 1
+ *
+ * Conforms to "Unified Extensible Firmware Interface Specification",
+ * Version 2.3, May 8, 2009
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_uefi
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 Identifier[16]; /* UUID identifier */
+ UINT16 DataOffset; /* Offset of remaining data in table */
+
+} ACPI_TABLE_UEFI;
+
+
+/*******************************************************************************
+ *
+ * VRTC - Virtual Real Time Clock Table
+ * Version 1
+ *
+ * Conforms to "Simple Firmware Interface Specification",
+ * Draft 0.8.2, Oct 19, 2010
+ * NOTE: The ACPI VRTC is equivalent to The SFI MRTC table.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_vrtc
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_VRTC;
+
+/* VRTC entry */
+
+typedef struct acpi_vrtc_entry
+{
+ ACPI_GENERIC_ADDRESS PhysicalAddress;
+ UINT32 Irq;
+
+} ACPI_VRTC_ENTRY;
+
+
+/*******************************************************************************
+ *
+ * WAET - Windows ACPI Emulated devices Table
+ * Version 1
+ *
+ * Conforms to "Windows ACPI Emulated Devices Table", version 1.0, April 6, 2009
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_waet
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Flags;
+
+} ACPI_TABLE_WAET;
+
+/* Masks for Flags field above */
+
+#define ACPI_WAET_RTC_NO_ACK (1) /* RTC requires no int acknowledge */
+#define ACPI_WAET_TIMER_ONE_READ (1<<1) /* PM timer requires only one read */
+
+
+/*******************************************************************************
+ *
+ * WDAT - Watchdog Action Table
+ * Version 1
+ *
+ * Conforms to "Hardware Watchdog Timers Design Specification",
+ * Copyright 2006 Microsoft Corporation.
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_wdat
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 HeaderLength; /* Watchdog Header Length */
+ UINT16 PciSegment; /* PCI Segment number */
+ UINT8 PciBus; /* PCI Bus number */
+ UINT8 PciDevice; /* PCI Device number */
+ UINT8 PciFunction; /* PCI Function number */
+ UINT8 Reserved[3];
+ UINT32 TimerPeriod; /* Period of one timer count (msec) */
+ UINT32 MaxCount; /* Maximum counter value supported */
+ UINT32 MinCount; /* Minimum counter value */
+ UINT8 Flags;
+ UINT8 Reserved2[3];
+ UINT32 Entries; /* Number of watchdog entries that follow */
+
+} ACPI_TABLE_WDAT;
+
+/* Masks for Flags field above */
+
+#define ACPI_WDAT_ENABLED (1)
+#define ACPI_WDAT_STOPPED 0x80
+
+
+/* WDAT Instruction Entries (actions) */
+
+typedef struct acpi_wdat_entry
+{
+ UINT8 Action;
+ UINT8 Instruction;
+ UINT16 Reserved;
+ ACPI_GENERIC_ADDRESS RegisterRegion;
+ UINT32 Value; /* Value used with Read/Write register */
+ UINT32 Mask; /* Bitmask required for this register instruction */
+
+} ACPI_WDAT_ENTRY;
+
+/* Values for Action field above */
+
+enum AcpiWdatActions
+{
+ ACPI_WDAT_RESET = 1,
+ ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4,
+ ACPI_WDAT_GET_COUNTDOWN = 5,
+ ACPI_WDAT_SET_COUNTDOWN = 6,
+ ACPI_WDAT_GET_RUNNING_STATE = 8,
+ ACPI_WDAT_SET_RUNNING_STATE = 9,
+ ACPI_WDAT_GET_STOPPED_STATE = 10,
+ ACPI_WDAT_SET_STOPPED_STATE = 11,
+ ACPI_WDAT_GET_REBOOT = 16,
+ ACPI_WDAT_SET_REBOOT = 17,
+ ACPI_WDAT_GET_SHUTDOWN = 18,
+ ACPI_WDAT_SET_SHUTDOWN = 19,
+ ACPI_WDAT_GET_STATUS = 32,
+ ACPI_WDAT_SET_STATUS = 33,
+ ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */
+};
+
+/* Values for Instruction field above */
+
+enum AcpiWdatInstructions
+{
+ ACPI_WDAT_READ_VALUE = 0,
+ ACPI_WDAT_READ_COUNTDOWN = 1,
+ ACPI_WDAT_WRITE_VALUE = 2,
+ ACPI_WDAT_WRITE_COUNTDOWN = 3,
+ ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */
+ ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */
+};
+
+
+/*******************************************************************************
+ *
+ * WDDT - Watchdog Descriptor Table
+ * Version 1
+ *
+ * Conforms to "Using the Intel ICH Family Watchdog Timer (WDT)",
+ * Version 001, September 2002
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_wddt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 SpecVersion;
+ UINT16 TableVersion;
+ UINT16 PciVendorId;
+ ACPI_GENERIC_ADDRESS Address;
+ UINT16 MaxCount; /* Maximum counter value supported */
+ UINT16 MinCount; /* Minimum counter value supported */
+ UINT16 Period;
+ UINT16 Status;
+ UINT16 Capability;
+
+} ACPI_TABLE_WDDT;
+
+/* Flags for Status field above */
+
+#define ACPI_WDDT_AVAILABLE (1)
+#define ACPI_WDDT_ACTIVE (1<<1)
+#define ACPI_WDDT_TCO_OS_OWNED (1<<2)
+#define ACPI_WDDT_USER_RESET (1<<11)
+#define ACPI_WDDT_WDT_RESET (1<<12)
+#define ACPI_WDDT_POWER_FAIL (1<<13)
+#define ACPI_WDDT_UNKNOWN_RESET (1<<14)
+
+/* Flags for Capability field above */
+
+#define ACPI_WDDT_AUTO_RESET (1)
+#define ACPI_WDDT_ALERT_SUPPORT (1<<1)
+
+
+/*******************************************************************************
+ *
+ * WDRT - Watchdog Resource Table
+ * Version 1
+ *
+ * Conforms to "Watchdog Timer Hardware Requirements for Windows Server 2003",
+ * Version 1.01, August 28, 2006
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_wdrt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ ACPI_GENERIC_ADDRESS ControlRegister;
+ ACPI_GENERIC_ADDRESS CountRegister;
+ UINT16 PciDeviceId;
+ UINT16 PciVendorId;
+ UINT8 PciBus; /* PCI Bus number */
+ UINT8 PciDevice; /* PCI Device number */
+ UINT8 PciFunction; /* PCI Function number */
+ UINT8 PciSegment; /* PCI Segment number */
+ UINT16 MaxCount; /* Maximum counter value supported */
+ UINT8 Units;
+
+} ACPI_TABLE_WDRT;
+
+
+/* Reset to default packing */
+
+#pragma pack()
+
+#endif /* __ACTBL2_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actbl3.h b/usr/src/boot/sys/contrib/dev/acpica/include/actbl3.h
new file mode 100644
index 0000000000..7da6bc68da
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actbl3.h
@@ -0,0 +1,894 @@
+/******************************************************************************
+ *
+ * Name: actbl3.h - ACPI Table Definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTBL3_H__
+#define __ACTBL3_H__
+
+
+/*******************************************************************************
+ *
+ * Additional ACPI Tables (3)
+ *
+ * These tables are not consumed directly by the ACPICA subsystem, but are
+ * included here to support device drivers and the AML disassembler.
+ *
+ * In general, the tables in this file are fully defined within the ACPI
+ * specification.
+ *
+ ******************************************************************************/
+
+
+/*
+ * Values for description table header signatures for tables defined in this
+ * file. Useful because they make it more difficult to inadvertently type in
+ * the wrong signature.
+ */
+#define ACPI_SIG_BGRT "BGRT" /* Boot Graphics Resource Table */
+#define ACPI_SIG_DRTM "DRTM" /* Dynamic Root of Trust for Measurement table */
+#define ACPI_SIG_FPDT "FPDT" /* Firmware Performance Data Table */
+#define ACPI_SIG_GTDT "GTDT" /* Generic Timer Description Table */
+#define ACPI_SIG_MPST "MPST" /* Memory Power State Table */
+#define ACPI_SIG_PCCT "PCCT" /* Platform Communications Channel Table */
+#define ACPI_SIG_PMTT "PMTT" /* Platform Memory Topology Table */
+#define ACPI_SIG_RASF "RASF" /* RAS Feature table */
+#define ACPI_SIG_STAO "STAO" /* Status Override table */
+#define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */
+#define ACPI_SIG_XENV "XENV" /* Xen Environment table */
+
+#define ACPI_SIG_S3PT "S3PT" /* S3 Performance (sub)Table */
+#define ACPI_SIG_PCCS "PCC" /* PCC Shared Memory Region */
+
+/* Reserved table signatures */
+
+#define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */
+#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */
+
+/*
+ * All tables must be byte-packed to match the ACPI specification, since
+ * the tables are provided by the system BIOS.
+ */
+#pragma pack(1)
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+
+/*******************************************************************************
+ *
+ * BGRT - Boot Graphics Resource Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_bgrt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 Version;
+ UINT8 Status;
+ UINT8 ImageType;
+ UINT64 ImageAddress;
+ UINT32 ImageOffsetX;
+ UINT32 ImageOffsetY;
+
+} ACPI_TABLE_BGRT;
+
+
+/*******************************************************************************
+ *
+ * DRTM - Dynamic Root of Trust for Measurement table
+ * Conforms to "TCG D-RTM Architecture" June 17 2013, Version 1.0.0
+ * Table version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_drtm
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 EntryBaseAddress;
+ UINT64 EntryLength;
+ UINT32 EntryAddress32;
+ UINT64 EntryAddress64;
+ UINT64 ExitAddress;
+ UINT64 LogAreaAddress;
+ UINT32 LogAreaLength;
+ UINT64 ArchDependentAddress;
+ UINT32 Flags;
+
+} ACPI_TABLE_DRTM;
+
+/* Flag Definitions for above */
+
+#define ACPI_DRTM_ACCESS_ALLOWED (1)
+#define ACPI_DRTM_ENABLE_GAP_CODE (1<<1)
+#define ACPI_DRTM_INCOMPLETE_MEASUREMENTS (1<<2)
+#define ACPI_DRTM_AUTHORITY_ORDER (1<<3)
+
+
+/* 1) Validated Tables List (64-bit addresses) */
+
+typedef struct acpi_drtm_vtable_list
+{
+ UINT32 ValidatedTableCount;
+ UINT64 ValidatedTables[1];
+
+} ACPI_DRTM_VTABLE_LIST;
+
+/* 2) Resources List (of Resource Descriptors) */
+
+/* Resource Descriptor */
+
+typedef struct acpi_drtm_resource
+{
+ UINT8 Size[7];
+ UINT8 Type;
+ UINT64 Address;
+
+} ACPI_DRTM_RESOURCE;
+
+typedef struct acpi_drtm_resource_list
+{
+ UINT32 ResourceCount;
+ ACPI_DRTM_RESOURCE Resources[1];
+
+} ACPI_DRTM_RESOURCE_LIST;
+
+/* 3) Platform-specific Identifiers List */
+
+typedef struct acpi_drtm_dps_id
+{
+ UINT32 DpsIdLength;
+ UINT8 DpsId[16];
+
+} ACPI_DRTM_DPS_ID;
+
+
+/*******************************************************************************
+ *
+ * FPDT - Firmware Performance Data Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_fpdt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_FPDT;
+
+
+/* FPDT subtable header */
+
+typedef struct acpi_fpdt_header
+{
+ UINT16 Type;
+ UINT8 Length;
+ UINT8 Revision;
+
+} ACPI_FPDT_HEADER;
+
+/* Values for Type field above */
+
+enum AcpiFpdtType
+{
+ ACPI_FPDT_TYPE_BOOT = 0,
+ ACPI_FPDT_TYPE_S3PERF = 1
+};
+
+
+/*
+ * FPDT subtables
+ */
+
+/* 0: Firmware Basic Boot Performance Record */
+
+typedef struct acpi_fpdt_boot
+{
+ ACPI_FPDT_HEADER Header;
+ UINT8 Reserved[4];
+ UINT64 ResetEnd;
+ UINT64 LoadStart;
+ UINT64 StartupStart;
+ UINT64 ExitServicesEntry;
+ UINT64 ExitServicesExit;
+
+} ACPI_FPDT_BOOT;
+
+
+/* 1: S3 Performance Table Pointer Record */
+
+typedef struct acpi_fpdt_s3pt_ptr
+{
+ ACPI_FPDT_HEADER Header;
+ UINT8 Reserved[4];
+ UINT64 Address;
+
+} ACPI_FPDT_S3PT_PTR;
+
+
+/*
+ * S3PT - S3 Performance Table. This table is pointed to by the
+ * FPDT S3 Pointer Record above.
+ */
+typedef struct acpi_table_s3pt
+{
+ UINT8 Signature[4]; /* "S3PT" */
+ UINT32 Length;
+
+} ACPI_TABLE_S3PT;
+
+
+/*
+ * S3PT Subtables
+ */
+typedef struct acpi_s3pt_header
+{
+ UINT16 Type;
+ UINT8 Length;
+ UINT8 Revision;
+
+} ACPI_S3PT_HEADER;
+
+/* Values for Type field above */
+
+enum AcpiS3ptType
+{
+ ACPI_S3PT_TYPE_RESUME = 0,
+ ACPI_S3PT_TYPE_SUSPEND = 1
+};
+
+typedef struct acpi_s3pt_resume
+{
+ ACPI_S3PT_HEADER Header;
+ UINT32 ResumeCount;
+ UINT64 FullResume;
+ UINT64 AverageResume;
+
+} ACPI_S3PT_RESUME;
+
+typedef struct acpi_s3pt_suspend
+{
+ ACPI_S3PT_HEADER Header;
+ UINT64 SuspendStart;
+ UINT64 SuspendEnd;
+
+} ACPI_S3PT_SUSPEND;
+
+
+/*******************************************************************************
+ *
+ * GTDT - Generic Timer Description Table (ACPI 5.1)
+ * Version 2
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_gtdt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 CounterBlockAddresss;
+ UINT32 Reserved;
+ UINT32 SecureEl1Interrupt;
+ UINT32 SecureEl1Flags;
+ UINT32 NonSecureEl1Interrupt;
+ UINT32 NonSecureEl1Flags;
+ UINT32 VirtualTimerInterrupt;
+ UINT32 VirtualTimerFlags;
+ UINT32 NonSecureEl2Interrupt;
+ UINT32 NonSecureEl2Flags;
+ UINT64 CounterReadBlockAddress;
+ UINT32 PlatformTimerCount;
+ UINT32 PlatformTimerOffset;
+
+} ACPI_TABLE_GTDT;
+
+/* Flag Definitions: Timer Block Physical Timers and Virtual timers */
+
+#define ACPI_GTDT_INTERRUPT_MODE (1)
+#define ACPI_GTDT_INTERRUPT_POLARITY (1<<1)
+#define ACPI_GTDT_ALWAYS_ON (1<<2)
+
+
+/* Common GTDT subtable header */
+
+typedef struct acpi_gtdt_header
+{
+ UINT8 Type;
+ UINT16 Length;
+
+} ACPI_GTDT_HEADER;
+
+/* Values for GTDT subtable type above */
+
+enum AcpiGtdtType
+{
+ ACPI_GTDT_TYPE_TIMER_BLOCK = 0,
+ ACPI_GTDT_TYPE_WATCHDOG = 1,
+ ACPI_GTDT_TYPE_RESERVED = 2 /* 2 and greater are reserved */
+};
+
+
+/* GTDT Subtables, correspond to Type in acpi_gtdt_header */
+
+/* 0: Generic Timer Block */
+
+typedef struct acpi_gtdt_timer_block
+{
+ ACPI_GTDT_HEADER Header;
+ UINT8 Reserved;
+ UINT64 BlockAddress;
+ UINT32 TimerCount;
+ UINT32 TimerOffset;
+
+} ACPI_GTDT_TIMER_BLOCK;
+
+/* Timer Sub-Structure, one per timer */
+
+typedef struct acpi_gtdt_timer_entry
+{
+ UINT8 FrameNumber;
+ UINT8 Reserved[3];
+ UINT64 BaseAddress;
+ UINT64 El0BaseAddress;
+ UINT32 TimerInterrupt;
+ UINT32 TimerFlags;
+ UINT32 VirtualTimerInterrupt;
+ UINT32 VirtualTimerFlags;
+ UINT32 CommonFlags;
+
+} ACPI_GTDT_TIMER_ENTRY;
+
+/* Flag Definitions: TimerFlags and VirtualTimerFlags above */
+
+#define ACPI_GTDT_GT_IRQ_MODE (1)
+#define ACPI_GTDT_GT_IRQ_POLARITY (1<<1)
+
+/* Flag Definitions: CommonFlags above */
+
+#define ACPI_GTDT_GT_IS_SECURE_TIMER (1)
+#define ACPI_GTDT_GT_ALWAYS_ON (1<<1)
+
+
+/* 1: SBSA Generic Watchdog Structure */
+
+typedef struct acpi_gtdt_watchdog
+{
+ ACPI_GTDT_HEADER Header;
+ UINT8 Reserved;
+ UINT64 RefreshFrameAddress;
+ UINT64 ControlFrameAddress;
+ UINT32 TimerInterrupt;
+ UINT32 TimerFlags;
+
+} ACPI_GTDT_WATCHDOG;
+
+/* Flag Definitions: TimerFlags above */
+
+#define ACPI_GTDT_WATCHDOG_IRQ_MODE (1)
+#define ACPI_GTDT_WATCHDOG_IRQ_POLARITY (1<<1)
+#define ACPI_GTDT_WATCHDOG_SECURE (1<<2)
+
+
+/*******************************************************************************
+ *
+ * MPST - Memory Power State Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+#define ACPI_MPST_CHANNEL_INFO \
+ UINT8 ChannelId; \
+ UINT8 Reserved1[3]; \
+ UINT16 PowerNodeCount; \
+ UINT16 Reserved2;
+
+/* Main table */
+
+typedef struct acpi_table_mpst
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ ACPI_MPST_CHANNEL_INFO /* Platform Communication Channel */
+
+} ACPI_TABLE_MPST;
+
+
+/* Memory Platform Communication Channel Info */
+
+typedef struct acpi_mpst_channel
+{
+ ACPI_MPST_CHANNEL_INFO /* Platform Communication Channel */
+
+} ACPI_MPST_CHANNEL;
+
+
+/* Memory Power Node Structure */
+
+typedef struct acpi_mpst_power_node
+{
+ UINT8 Flags;
+ UINT8 Reserved1;
+ UINT16 NodeId;
+ UINT32 Length;
+ UINT64 RangeAddress;
+ UINT64 RangeLength;
+ UINT32 NumPowerStates;
+ UINT32 NumPhysicalComponents;
+
+} ACPI_MPST_POWER_NODE;
+
+/* Values for Flags field above */
+
+#define ACPI_MPST_ENABLED 1
+#define ACPI_MPST_POWER_MANAGED 2
+#define ACPI_MPST_HOT_PLUG_CAPABLE 4
+
+
+/* Memory Power State Structure (follows POWER_NODE above) */
+
+typedef struct acpi_mpst_power_state
+{
+ UINT8 PowerState;
+ UINT8 InfoIndex;
+
+} ACPI_MPST_POWER_STATE;
+
+
+/* Physical Component ID Structure (follows POWER_STATE above) */
+
+typedef struct acpi_mpst_component
+{
+ UINT16 ComponentId;
+
+} ACPI_MPST_COMPONENT;
+
+
+/* Memory Power State Characteristics Structure (follows all POWER_NODEs) */
+
+typedef struct acpi_mpst_data_hdr
+{
+ UINT16 CharacteristicsCount;
+ UINT16 Reserved;
+
+} ACPI_MPST_DATA_HDR;
+
+typedef struct acpi_mpst_power_data
+{
+ UINT8 StructureId;
+ UINT8 Flags;
+ UINT16 Reserved1;
+ UINT32 AveragePower;
+ UINT32 PowerSaving;
+ UINT64 ExitLatency;
+ UINT64 Reserved2;
+
+} ACPI_MPST_POWER_DATA;
+
+/* Values for Flags field above */
+
+#define ACPI_MPST_PRESERVE 1
+#define ACPI_MPST_AUTOENTRY 2
+#define ACPI_MPST_AUTOEXIT 4
+
+
+/* Shared Memory Region (not part of an ACPI table) */
+
+typedef struct acpi_mpst_shared
+{
+ UINT32 Signature;
+ UINT16 PccCommand;
+ UINT16 PccStatus;
+ UINT32 CommandRegister;
+ UINT32 StatusRegister;
+ UINT32 PowerStateId;
+ UINT32 PowerNodeId;
+ UINT64 EnergyConsumed;
+ UINT64 AveragePower;
+
+} ACPI_MPST_SHARED;
+
+
+/*******************************************************************************
+ *
+ * PCCT - Platform Communications Channel Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_pcct
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Flags;
+ UINT64 Reserved;
+
+} ACPI_TABLE_PCCT;
+
+/* Values for Flags field above */
+
+#define ACPI_PCCT_DOORBELL 1
+
+/* Values for subtable type in ACPI_SUBTABLE_HEADER */
+
+enum AcpiPcctType
+{
+ ACPI_PCCT_TYPE_GENERIC_SUBSPACE = 0,
+ ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE = 1,
+ ACPI_PCCT_TYPE_RESERVED = 2 /* 2 and greater are reserved */
+};
+
+/*
+ * PCCT Subtables, correspond to Type in ACPI_SUBTABLE_HEADER
+ */
+
+/* 0: Generic Communications Subspace */
+
+typedef struct acpi_pcct_subspace
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT8 Reserved[6];
+ UINT64 BaseAddress;
+ UINT64 Length;
+ ACPI_GENERIC_ADDRESS DoorbellRegister;
+ UINT64 PreserveMask;
+ UINT64 WriteMask;
+ UINT32 Latency;
+ UINT32 MaxAccessRate;
+ UINT16 MinTurnaroundTime;
+
+} ACPI_PCCT_SUBSPACE;
+
+
+/* 1: HW-reduced Communications Subspace (ACPI 5.1) */
+
+typedef struct acpi_pcct_hw_reduced
+{
+ ACPI_SUBTABLE_HEADER Header;
+ UINT32 DoorbellInterrupt;
+ UINT8 Flags;
+ UINT8 Reserved;
+ UINT64 BaseAddress;
+ UINT64 Length;
+ ACPI_GENERIC_ADDRESS DoorbellRegister;
+ UINT64 PreserveMask;
+ UINT64 WriteMask;
+ UINT32 Latency;
+ UINT32 MaxAccessRate;
+ UINT16 MinTurnaroundTime;
+
+} ACPI_PCCT_HW_REDUCED;
+
+/* Values for doorbell flags above */
+
+#define ACPI_PCCT_INTERRUPT_POLARITY (1)
+#define ACPI_PCCT_INTERRUPT_MODE (1<<1)
+
+
+/*
+ * PCC memory structures (not part of the ACPI table)
+ */
+
+/* Shared Memory Region */
+
+typedef struct acpi_pcct_shared_memory
+{
+ UINT32 Signature;
+ UINT16 Command;
+ UINT16 Status;
+
+} ACPI_PCCT_SHARED_MEMORY;
+
+
+/*******************************************************************************
+ *
+ * PMTT - Platform Memory Topology Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_pmtt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 Reserved;
+
+} ACPI_TABLE_PMTT;
+
+
+/* Common header for PMTT subtables that follow main table */
+
+typedef struct acpi_pmtt_header
+{
+ UINT8 Type;
+ UINT8 Reserved1;
+ UINT16 Length;
+ UINT16 Flags;
+ UINT16 Reserved2;
+
+} ACPI_PMTT_HEADER;
+
+/* Values for Type field above */
+
+#define ACPI_PMTT_TYPE_SOCKET 0
+#define ACPI_PMTT_TYPE_CONTROLLER 1
+#define ACPI_PMTT_TYPE_DIMM 2
+#define ACPI_PMTT_TYPE_RESERVED 3 /* 0x03-0xFF are reserved */
+
+/* Values for Flags field above */
+
+#define ACPI_PMTT_TOP_LEVEL 0x0001
+#define ACPI_PMTT_PHYSICAL 0x0002
+#define ACPI_PMTT_MEMORY_TYPE 0x000C
+
+
+/*
+ * PMTT subtables, correspond to Type in acpi_pmtt_header
+ */
+
+
+/* 0: Socket Structure */
+
+typedef struct acpi_pmtt_socket
+{
+ ACPI_PMTT_HEADER Header;
+ UINT16 SocketId;
+ UINT16 Reserved;
+
+} ACPI_PMTT_SOCKET;
+
+
+/* 1: Memory Controller subtable */
+
+typedef struct acpi_pmtt_controller
+{
+ ACPI_PMTT_HEADER Header;
+ UINT32 ReadLatency;
+ UINT32 WriteLatency;
+ UINT32 ReadBandwidth;
+ UINT32 WriteBandwidth;
+ UINT16 AccessWidth;
+ UINT16 Alignment;
+ UINT16 Reserved;
+ UINT16 DomainCount;
+
+} ACPI_PMTT_CONTROLLER;
+
+/* 1a: Proximity Domain substructure */
+
+typedef struct acpi_pmtt_domain
+{
+ UINT32 ProximityDomain;
+
+} ACPI_PMTT_DOMAIN;
+
+
+/* 2: Physical Component Identifier (DIMM) */
+
+typedef struct acpi_pmtt_physical_component
+{
+ ACPI_PMTT_HEADER Header;
+ UINT16 ComponentId;
+ UINT16 Reserved;
+ UINT32 MemorySize;
+ UINT32 BiosHandle;
+
+} ACPI_PMTT_PHYSICAL_COMPONENT;
+
+
+/*******************************************************************************
+ *
+ * RASF - RAS Feature Table (ACPI 5.0)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_rasf
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 ChannelId[12];
+
+} ACPI_TABLE_RASF;
+
+/* RASF Platform Communication Channel Shared Memory Region */
+
+typedef struct acpi_rasf_shared_memory
+{
+ UINT32 Signature;
+ UINT16 Command;
+ UINT16 Status;
+ UINT16 Version;
+ UINT8 Capabilities[16];
+ UINT8 SetCapabilities[16];
+ UINT16 NumParameterBlocks;
+ UINT32 SetCapabilitiesStatus;
+
+} ACPI_RASF_SHARED_MEMORY;
+
+/* RASF Parameter Block Structure Header */
+
+typedef struct acpi_rasf_parameter_block
+{
+ UINT16 Type;
+ UINT16 Version;
+ UINT16 Length;
+
+} ACPI_RASF_PARAMETER_BLOCK;
+
+/* RASF Parameter Block Structure for PATROL_SCRUB */
+
+typedef struct acpi_rasf_patrol_scrub_parameter
+{
+ ACPI_RASF_PARAMETER_BLOCK Header;
+ UINT16 PatrolScrubCommand;
+ UINT64 RequestedAddressRange[2];
+ UINT64 ActualAddressRange[2];
+ UINT16 Flags;
+ UINT8 RequestedSpeed;
+
+} ACPI_RASF_PATROL_SCRUB_PARAMETER;
+
+/* Masks for Flags and Speed fields above */
+
+#define ACPI_RASF_SCRUBBER_RUNNING 1
+#define ACPI_RASF_SPEED (7<<1)
+#define ACPI_RASF_SPEED_SLOW (0<<1)
+#define ACPI_RASF_SPEED_MEDIUM (4<<1)
+#define ACPI_RASF_SPEED_FAST (7<<1)
+
+/* Channel Commands */
+
+enum AcpiRasfCommands
+{
+ ACPI_RASF_EXECUTE_RASF_COMMAND = 1
+};
+
+/* Platform RAS Capabilities */
+
+enum AcpiRasfCapabiliities
+{
+ ACPI_HW_PATROL_SCRUB_SUPPORTED = 0,
+ ACPI_SW_PATROL_SCRUB_EXPOSED = 1
+};
+
+/* Patrol Scrub Commands */
+
+enum AcpiRasfPatrolScrubCommands
+{
+ ACPI_RASF_GET_PATROL_PARAMETERS = 1,
+ ACPI_RASF_START_PATROL_SCRUBBER = 2,
+ ACPI_RASF_STOP_PATROL_SCRUBBER = 3
+};
+
+/* Channel Command flags */
+
+#define ACPI_RASF_GENERATE_SCI (1<<15)
+
+/* Status values */
+
+enum AcpiRasfStatus
+{
+ ACPI_RASF_SUCCESS = 0,
+ ACPI_RASF_NOT_VALID = 1,
+ ACPI_RASF_NOT_SUPPORTED = 2,
+ ACPI_RASF_BUSY = 3,
+ ACPI_RASF_FAILED = 4,
+ ACPI_RASF_ABORTED = 5,
+ ACPI_RASF_INVALID_DATA = 6
+};
+
+/* Status flags */
+
+#define ACPI_RASF_COMMAND_COMPLETE (1)
+#define ACPI_RASF_SCI_DOORBELL (1<<1)
+#define ACPI_RASF_ERROR (1<<2)
+#define ACPI_RASF_STATUS (0x1F<<3)
+
+
+/*******************************************************************************
+ *
+ * STAO - Status Override Table (_STA override) - ACPI 6.0
+ * Version 1
+ *
+ * Conforms to "ACPI Specification for Status Override Table"
+ * 6 January 2015
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_stao
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 IgnoreUart;
+
+} ACPI_TABLE_STAO;
+
+
+/*******************************************************************************
+ *
+ * WPBT - Windows Platform Environment Table (ACPI 6.0)
+ * Version 1
+ *
+ * Conforms to "Windows Platform Binary Table (WPBT)" 29 November 2011
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_wpbt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT32 HandoffSize;
+ UINT64 HandoffAddress;
+ UINT8 Layout;
+ UINT8 Type;
+ UINT16 ArgumentsLength;
+
+} ACPI_TABLE_WPBT;
+
+
+/*******************************************************************************
+ *
+ * XENV - Xen Environment Table (ACPI 6.0)
+ * Version 1
+ *
+ * Conforms to "ACPI Specification for Xen Environment Table" 4 January 2015
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_xenv
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT64 GrantTableAddress;
+ UINT64 GrantTableSize;
+ UINT32 EventInterrupt;
+ UINT8 EventFlags;
+
+} ACPI_TABLE_XENV;
+
+
+/* Reset to default packing */
+
+#pragma pack()
+
+#endif /* __ACTBL3_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/actypes.h b/usr/src/boot/sys/contrib/dev/acpica/include/actypes.h
new file mode 100644
index 0000000000..cbae6f0d69
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/actypes.h
@@ -0,0 +1,1406 @@
+/******************************************************************************
+ *
+ * Name: actypes.h - Common data types for the entire ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACTYPES_H__
+#define __ACTYPES_H__
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+/*
+ * ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header
+ * and must be either 32 or 64. 16-bit ACPICA is no longer supported, as of
+ * 12/2006.
+ */
+#ifndef ACPI_MACHINE_WIDTH
+#error ACPI_MACHINE_WIDTH not defined
+#endif
+
+/*
+ * Data type ranges
+ * Note: These macros are designed to be compiler independent as well as
+ * working around problems that some 32-bit compilers have with 64-bit
+ * constants.
+ */
+#define ACPI_UINT8_MAX (UINT8) (~((UINT8) 0)) /* 0xFF */
+#define ACPI_UINT16_MAX (UINT16)(~((UINT16) 0)) /* 0xFFFF */
+#define ACPI_UINT32_MAX (UINT32)(~((UINT32) 0)) /* 0xFFFFFFFF */
+#define ACPI_UINT64_MAX (UINT64)(~((UINT64) 0)) /* 0xFFFFFFFFFFFFFFFF */
+#define ACPI_ASCII_MAX 0x7F
+
+
+/*
+ * Architecture-specific ACPICA Subsystem Data Types
+ *
+ * The goal of these types is to provide source code portability across
+ * 16-bit, 32-bit, and 64-bit targets.
+ *
+ * 1) The following types are of fixed size for all targets (16/32/64):
+ *
+ * BOOLEAN Logical boolean
+ *
+ * UINT8 8-bit (1 byte) unsigned value
+ * UINT16 16-bit (2 byte) unsigned value
+ * UINT32 32-bit (4 byte) unsigned value
+ * UINT64 64-bit (8 byte) unsigned value
+ *
+ * INT16 16-bit (2 byte) signed value
+ * INT32 32-bit (4 byte) signed value
+ * INT64 64-bit (8 byte) signed value
+ *
+ * COMPILER_DEPENDENT_UINT64/INT64 - These types are defined in the
+ * compiler-dependent header(s) and were introduced because there is no common
+ * 64-bit integer type across the various compilation models, as shown in
+ * the table below.
+ *
+ * Datatype LP64 ILP64 LLP64 ILP32 LP32 16bit
+ * char 8 8 8 8 8 8
+ * short 16 16 16 16 16 16
+ * _int32 32
+ * int 32 64 32 32 16 16
+ * long 64 64 32 32 32 32
+ * long long 64 64
+ * pointer 64 64 64 32 32 32
+ *
+ * Note: ILP64 and LP32 are currently not supported.
+ *
+ *
+ * 2) These types represent the native word size of the target mode of the
+ * processor, and may be 16-bit, 32-bit, or 64-bit as required. They are
+ * usually used for memory allocation, efficient loop counters, and array
+ * indexes. The types are similar to the size_t type in the C library and are
+ * required because there is no C type that consistently represents the native
+ * data width. ACPI_SIZE is needed because there is no guarantee that a
+ * kernel-level C library is present.
+ *
+ * ACPI_SIZE 16/32/64-bit unsigned value
+ * ACPI_NATIVE_INT 16/32/64-bit signed value
+ */
+
+/*******************************************************************************
+ *
+ * Common types for all compilers, all targets
+ *
+ ******************************************************************************/
+
+#ifndef ACPI_USE_SYSTEM_INTTYPES
+
+typedef unsigned char BOOLEAN;
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef short INT16;
+typedef COMPILER_DEPENDENT_UINT64 UINT64;
+typedef COMPILER_DEPENDENT_INT64 INT64;
+
+#endif /* ACPI_USE_SYSTEM_INTTYPES */
+
+/*
+ * Value returned by AcpiOsGetThreadId. There is no standard "thread_id"
+ * across operating systems or even the various UNIX systems. Since ACPICA
+ * only needs the thread ID as a unique thread identifier, we use a UINT64
+ * as the only common data type - it will accommodate any type of pointer or
+ * any type of integer. It is up to the host-dependent OSL to cast the
+ * native thread ID type to a UINT64 (in AcpiOsGetThreadId).
+ */
+#define ACPI_THREAD_ID UINT64
+
+
+/*******************************************************************************
+ *
+ * Types specific to 64-bit targets
+ *
+ ******************************************************************************/
+
+#if ACPI_MACHINE_WIDTH == 64
+
+#ifndef ACPI_USE_SYSTEM_INTTYPES
+
+typedef unsigned int UINT32;
+typedef int INT32;
+
+#endif /* ACPI_USE_SYSTEM_INTTYPES */
+
+
+typedef INT64 ACPI_NATIVE_INT;
+typedef UINT64 ACPI_SIZE;
+typedef UINT64 ACPI_IO_ADDRESS;
+typedef UINT64 ACPI_PHYSICAL_ADDRESS;
+
+#define ACPI_MAX_PTR ACPI_UINT64_MAX
+#define ACPI_SIZE_MAX ACPI_UINT64_MAX
+#define ACPI_USE_NATIVE_DIVIDE /* Has native 64-bit integer support */
+
+/*
+ * In the case of the Itanium Processor Family (IPF), the hardware does not
+ * support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED flag
+ * to indicate that special precautions must be taken to avoid alignment faults.
+ * (IA64 or ia64 is currently used by existing compilers to indicate IPF.)
+ *
+ * Note: EM64T and other X86-64 processors support misaligned transfers,
+ * so there is no need to define this flag.
+ */
+#if defined (__IA64__) || defined (__ia64__)
+#define ACPI_MISALIGNMENT_NOT_SUPPORTED
+#endif
+
+
+/*******************************************************************************
+ *
+ * Types specific to 32-bit targets
+ *
+ ******************************************************************************/
+
+#elif ACPI_MACHINE_WIDTH == 32
+
+#ifndef ACPI_USE_SYSTEM_INTTYPES
+
+typedef unsigned int UINT32;
+typedef int INT32;
+
+#endif /* ACPI_USE_SYSTEM_INTTYPES */
+
+
+typedef INT32 ACPI_NATIVE_INT;
+typedef UINT32 ACPI_SIZE;
+
+#ifdef ACPI_32BIT_PHYSICAL_ADDRESS
+
+/*
+ * OSPMs can define this to shrink the size of the structures for 32-bit
+ * none PAE environment. ASL compiler may always define this to generate
+ * 32-bit OSPM compliant tables.
+ */
+typedef UINT32 ACPI_IO_ADDRESS;
+typedef UINT32 ACPI_PHYSICAL_ADDRESS;
+
+#else /* ACPI_32BIT_PHYSICAL_ADDRESS */
+
+/*
+ * It is reported that, after some calculations, the physical addresses can
+ * wrap over the 32-bit boundary on 32-bit PAE environment.
+ * https://bugzilla.kernel.org/show_bug.cgi?id=87971
+ */
+typedef UINT64 ACPI_IO_ADDRESS;
+typedef UINT64 ACPI_PHYSICAL_ADDRESS;
+
+#endif /* ACPI_32BIT_PHYSICAL_ADDRESS */
+
+#define ACPI_MAX_PTR ACPI_UINT32_MAX
+#define ACPI_SIZE_MAX ACPI_UINT32_MAX
+
+#else
+
+/* ACPI_MACHINE_WIDTH must be either 64 or 32 */
+
+#error unknown ACPI_MACHINE_WIDTH
+#endif
+
+
+/*******************************************************************************
+ *
+ * OS-dependent types
+ *
+ * If the defaults below are not appropriate for the host system, they can
+ * be defined in the OS-specific header, and this will take precedence.
+ *
+ ******************************************************************************/
+
+/* Flags for AcpiOsAcquireLock/AcpiOsReleaseLock */
+
+#ifndef ACPI_CPU_FLAGS
+#define ACPI_CPU_FLAGS ACPI_SIZE
+#endif
+
+/* Object returned from AcpiOsCreateCache */
+
+#ifndef ACPI_CACHE_T
+#ifdef ACPI_USE_LOCAL_CACHE
+#define ACPI_CACHE_T ACPI_MEMORY_LIST
+#else
+#define ACPI_CACHE_T void *
+#endif
+#endif
+
+/*
+ * Synchronization objects - Mutexes, Semaphores, and SpinLocks
+ */
+#if (ACPI_MUTEX_TYPE == ACPI_BINARY_SEMAPHORE)
+/*
+ * These macros are used if the host OS does not support a mutex object.
+ * Map the OSL Mutex interfaces to binary semaphores.
+ */
+#define ACPI_MUTEX ACPI_SEMAPHORE
+#define AcpiOsCreateMutex(OutHandle) AcpiOsCreateSemaphore (1, 1, OutHandle)
+#define AcpiOsDeleteMutex(Handle) (void) AcpiOsDeleteSemaphore (Handle)
+#define AcpiOsAcquireMutex(Handle,Time) AcpiOsWaitSemaphore (Handle, 1, Time)
+#define AcpiOsReleaseMutex(Handle) (void) AcpiOsSignalSemaphore (Handle, 1)
+#endif
+
+/* Configurable types for synchronization objects */
+
+#ifndef ACPI_SPINLOCK
+#define ACPI_SPINLOCK void *
+#endif
+
+#ifndef ACPI_SEMAPHORE
+#define ACPI_SEMAPHORE void *
+#endif
+
+#ifndef ACPI_MUTEX
+#define ACPI_MUTEX void *
+#endif
+
+
+/*******************************************************************************
+ *
+ * Compiler-dependent types
+ *
+ * If the defaults below are not appropriate for the host compiler, they can
+ * be defined in the compiler-specific header, and this will take precedence.
+ *
+ ******************************************************************************/
+
+/* Use C99 uintptr_t for pointer casting if available, "void *" otherwise */
+
+#ifndef ACPI_UINTPTR_T
+#define ACPI_UINTPTR_T void *
+#endif
+
+/*
+ * ACPI_PRINTF_LIKE is used to tag functions as "printf-like" because
+ * some compilers can catch printf format string problems
+ */
+#ifndef ACPI_PRINTF_LIKE
+#define ACPI_PRINTF_LIKE(c)
+#endif
+
+/*
+ * Some compilers complain about unused variables. Sometimes we don't want to
+ * use all the variables (for example, _AcpiModuleName). This allows us
+ * to tell the compiler in a per-variable manner that a variable
+ * is unused
+ */
+#ifndef ACPI_UNUSED_VAR
+#define ACPI_UNUSED_VAR
+#endif
+
+/*
+ * All ACPICA external functions that are available to the rest of the kernel
+ * are tagged with thes macros which can be defined as appropriate for the host.
+ *
+ * Notes:
+ * ACPI_EXPORT_SYMBOL_INIT is used for initialization and termination
+ * interfaces that may need special processing.
+ * ACPI_EXPORT_SYMBOL is used for all other public external functions.
+ */
+#ifndef ACPI_EXPORT_SYMBOL_INIT
+#define ACPI_EXPORT_SYMBOL_INIT(Symbol)
+#endif
+
+#ifndef ACPI_EXPORT_SYMBOL
+#define ACPI_EXPORT_SYMBOL(Symbol)
+#endif
+
+/*
+ * Compiler/Clibrary-dependent debug initialization. Used for ACPICA
+ * utilities only.
+ */
+#ifndef ACPI_DEBUG_INITIALIZE
+#define ACPI_DEBUG_INITIALIZE()
+#endif
+
+
+/*******************************************************************************
+ *
+ * Configuration
+ *
+ ******************************************************************************/
+
+#ifdef ACPI_NO_MEM_ALLOCATIONS
+
+#define ACPI_ALLOCATE(a) NULL
+#define ACPI_ALLOCATE_ZEROED(a) NULL
+#define ACPI_FREE(a)
+#define ACPI_MEM_TRACKING(a)
+
+#else /* ACPI_NO_MEM_ALLOCATIONS */
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+/*
+ * Memory allocation tracking (used by AcpiExec to detect memory leaks)
+ */
+#define ACPI_MEM_PARAMETERS _COMPONENT, _AcpiModuleName, __LINE__
+#define ACPI_ALLOCATE(a) AcpiUtAllocateAndTrack ((ACPI_SIZE) (a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE_ZEROED(a) AcpiUtAllocateZeroedAndTrack ((ACPI_SIZE) (a), ACPI_MEM_PARAMETERS)
+#define ACPI_FREE(a) AcpiUtFreeAndTrack (a, ACPI_MEM_PARAMETERS)
+#define ACPI_MEM_TRACKING(a) a
+
+#else
+/*
+ * Normal memory allocation directly via the OS services layer
+ */
+#define ACPI_ALLOCATE(a) AcpiOsAllocate ((ACPI_SIZE) (a))
+#define ACPI_ALLOCATE_ZEROED(a) AcpiOsAllocateZeroed ((ACPI_SIZE) (a))
+#define ACPI_FREE(a) AcpiOsFree (a)
+#define ACPI_MEM_TRACKING(a)
+
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+
+#endif /* ACPI_NO_MEM_ALLOCATIONS */
+
+
+/******************************************************************************
+ *
+ * ACPI Specification constants (Do not change unless the specification changes)
+ *
+ *****************************************************************************/
+
+/* Number of distinct FADT-based GPE register blocks (GPE0 and GPE1) */
+
+#define ACPI_MAX_GPE_BLOCKS 2
+
+/* Default ACPI register widths */
+
+#define ACPI_GPE_REGISTER_WIDTH 8
+#define ACPI_PM1_REGISTER_WIDTH 16
+#define ACPI_PM2_REGISTER_WIDTH 8
+#define ACPI_PM_TIMER_WIDTH 32
+#define ACPI_RESET_REGISTER_WIDTH 8
+
+/* Names within the namespace are 4 bytes long */
+
+#define ACPI_NAME_SIZE 4
+#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
+#define ACPI_PATH_SEPARATOR '.'
+
+/* Sizes for ACPI table headers */
+
+#define ACPI_OEM_ID_SIZE 6
+#define ACPI_OEM_TABLE_ID_SIZE 8
+
+/* ACPI/PNP hardware IDs */
+
+#define PCI_ROOT_HID_STRING "PNP0A03"
+#define PCI_EXPRESS_ROOT_HID_STRING "PNP0A08"
+
+/* PM Timer ticks per second (HZ) */
+
+#define ACPI_PM_TIMER_FREQUENCY 3579545
+
+
+/*******************************************************************************
+ *
+ * Independent types
+ *
+ ******************************************************************************/
+
+/* Logical defines and NULL */
+
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE (1 == 0)
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE (1 == 1)
+
+#ifndef NULL
+#define NULL (void *) 0
+#endif
+
+
+/*
+ * Miscellaneous types
+ */
+typedef UINT32 ACPI_STATUS; /* All ACPI Exceptions */
+typedef UINT32 ACPI_NAME; /* 4-byte ACPI name */
+typedef char * ACPI_STRING; /* Null terminated ASCII string */
+typedef void * ACPI_HANDLE; /* Actually a ptr to a NS Node */
+
+
+/* Time constants for timer calculations */
+
+#define ACPI_MSEC_PER_SEC 1000L
+
+#define ACPI_USEC_PER_MSEC 1000L
+#define ACPI_USEC_PER_SEC 1000000L
+
+#define ACPI_100NSEC_PER_USEC 10L
+#define ACPI_100NSEC_PER_MSEC 10000L
+#define ACPI_100NSEC_PER_SEC 10000000L
+
+#define ACPI_NSEC_PER_USEC 1000L
+#define ACPI_NSEC_PER_MSEC 1000000L
+#define ACPI_NSEC_PER_SEC 1000000000L
+
+
+/* Owner IDs are used to track namespace nodes for selective deletion */
+
+typedef UINT8 ACPI_OWNER_ID;
+#define ACPI_OWNER_ID_MAX 0xFF
+
+
+#define ACPI_INTEGER_BIT_SIZE 64
+#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
+#define ACPI_MAX64_DECIMAL_DIGITS 20
+#define ACPI_MAX32_DECIMAL_DIGITS 10
+#define ACPI_MAX16_DECIMAL_DIGITS 5
+#define ACPI_MAX8_DECIMAL_DIGITS 3
+
+/*
+ * Constants with special meanings
+ */
+#define ACPI_ROOT_OBJECT ACPI_ADD_PTR (ACPI_HANDLE, NULL, ACPI_MAX_PTR)
+#define ACPI_WAIT_FOREVER 0xFFFF /* UINT16, as per ACPI spec */
+#define ACPI_DO_NOT_WAIT 0
+
+/*
+ * Obsolete: Acpi integer width. In ACPI version 1 (1996), integers are 32 bits.
+ * In ACPI version 2 (2000) and later, integers are 64 bits. Note that this
+ * pertains to the ACPI integer type only, not to other integers used in the
+ * implementation of the ACPICA subsystem.
+ *
+ * 01/2010: This type is obsolete and has been removed from the entire ACPICA
+ * code base. It remains here for compatibility with device drivers that use
+ * the type. However, it will be removed in the future.
+ */
+typedef UINT64 ACPI_INTEGER;
+#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
+
+
+/*******************************************************************************
+ *
+ * Commonly used macros
+ *
+ ******************************************************************************/
+
+/* Data manipulation */
+
+#define ACPI_LOBYTE(Integer) ((UINT8) (UINT16)(Integer))
+#define ACPI_HIBYTE(Integer) ((UINT8) (((UINT16)(Integer)) >> 8))
+#define ACPI_LOWORD(Integer) ((UINT16) (UINT32)(Integer))
+#define ACPI_HIWORD(Integer) ((UINT16)(((UINT32)(Integer)) >> 16))
+#define ACPI_LODWORD(Integer64) ((UINT32) (UINT64)(Integer64))
+#define ACPI_HIDWORD(Integer64) ((UINT32)(((UINT64)(Integer64)) >> 32))
+
+#define ACPI_SET_BIT(target,bit) ((target) |= (bit))
+#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit))
+#define ACPI_MIN(a,b) (((a)<(b))?(a):(b))
+#define ACPI_MAX(a,b) (((a)>(b))?(a):(b))
+
+/* Size calculation */
+
+#define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
+
+/* Pointer manipulation */
+
+#define ACPI_CAST_PTR(t, p) ((t *) (ACPI_UINTPTR_T) (p))
+#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (ACPI_UINTPTR_T) (p))
+#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) + (ACPI_SIZE)(b)))
+#define ACPI_SUB_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
+#define ACPI_PTR_DIFF(a, b) (ACPI_SIZE) (ACPI_CAST_PTR (UINT8, (a)) - ACPI_CAST_PTR (UINT8, (b)))
+
+/* Pointer/Integer type conversions */
+
+#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL,(ACPI_SIZE) i)
+#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p, (void *) NULL)
+#define ACPI_OFFSET(d, f) ACPI_PTR_DIFF (&(((d *) 0)->f), (void *) NULL)
+#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i)
+#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i)
+
+/* Optimizations for 4-character (32-bit) ACPI_NAME manipulation */
+
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (UINT32, (a)) == *ACPI_CAST_PTR (UINT32, (b)))
+#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (UINT32, (dest)) = *ACPI_CAST_PTR (UINT32, (src)))
+#else
+#define ACPI_COMPARE_NAME(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
+#define ACPI_MOVE_NAME(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
+#endif
+
+/* Support for the special RSDP signature (8 characters) */
+
+#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
+#define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
+
+
+/*******************************************************************************
+ *
+ * Miscellaneous constants
+ *
+ ******************************************************************************/
+
+/*
+ * Initialization sequence
+ */
+#define ACPI_FULL_INITIALIZATION 0x00
+#define ACPI_NO_ADDRESS_SPACE_INIT 0x01
+#define ACPI_NO_HARDWARE_INIT 0x02
+#define ACPI_NO_EVENT_INIT 0x04
+#define ACPI_NO_HANDLER_INIT 0x08
+#define ACPI_NO_ACPI_ENABLE 0x10
+#define ACPI_NO_DEVICE_INIT 0x20
+#define ACPI_NO_OBJECT_INIT 0x40
+#define ACPI_NO_FACS_INIT 0x80
+
+/*
+ * Initialization state
+ */
+#define ACPI_SUBSYSTEM_INITIALIZE 0x01
+#define ACPI_INITIALIZED_OK 0x02
+
+/*
+ * Power state values
+ */
+#define ACPI_STATE_UNKNOWN (UINT8) 0xFF
+
+#define ACPI_STATE_S0 (UINT8) 0
+#define ACPI_STATE_S1 (UINT8) 1
+#define ACPI_STATE_S2 (UINT8) 2
+#define ACPI_STATE_S3 (UINT8) 3
+#define ACPI_STATE_S4 (UINT8) 4
+#define ACPI_STATE_S5 (UINT8) 5
+#define ACPI_S_STATES_MAX ACPI_STATE_S5
+#define ACPI_S_STATE_COUNT 6
+
+#define ACPI_STATE_D0 (UINT8) 0
+#define ACPI_STATE_D1 (UINT8) 1
+#define ACPI_STATE_D2 (UINT8) 2
+#define ACPI_STATE_D3 (UINT8) 3
+#define ACPI_D_STATES_MAX ACPI_STATE_D3
+#define ACPI_D_STATE_COUNT 4
+
+#define ACPI_STATE_C0 (UINT8) 0
+#define ACPI_STATE_C1 (UINT8) 1
+#define ACPI_STATE_C2 (UINT8) 2
+#define ACPI_STATE_C3 (UINT8) 3
+#define ACPI_C_STATES_MAX ACPI_STATE_C3
+#define ACPI_C_STATE_COUNT 4
+
+/*
+ * Sleep type invalid value
+ */
+#define ACPI_SLEEP_TYPE_MAX 0x7
+#define ACPI_SLEEP_TYPE_INVALID 0xFF
+
+/*
+ * Standard notify values
+ */
+#define ACPI_NOTIFY_BUS_CHECK (UINT8) 0x00
+#define ACPI_NOTIFY_DEVICE_CHECK (UINT8) 0x01
+#define ACPI_NOTIFY_DEVICE_WAKE (UINT8) 0x02
+#define ACPI_NOTIFY_EJECT_REQUEST (UINT8) 0x03
+#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (UINT8) 0x04
+#define ACPI_NOTIFY_FREQUENCY_MISMATCH (UINT8) 0x05
+#define ACPI_NOTIFY_BUS_MODE_MISMATCH (UINT8) 0x06
+#define ACPI_NOTIFY_POWER_FAULT (UINT8) 0x07
+#define ACPI_NOTIFY_CAPABILITIES_CHECK (UINT8) 0x08
+#define ACPI_NOTIFY_DEVICE_PLD_CHECK (UINT8) 0x09
+#define ACPI_NOTIFY_RESERVED (UINT8) 0x0A
+#define ACPI_NOTIFY_LOCALITY_UPDATE (UINT8) 0x0B
+#define ACPI_NOTIFY_SHUTDOWN_REQUEST (UINT8) 0x0C
+#define ACPI_NOTIFY_AFFINITY_UPDATE (UINT8) 0x0D
+
+#define ACPI_NOTIFY_MAX 0x0D
+
+/*
+ * Types associated with ACPI names and objects. The first group of
+ * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
+ * of the ACPI ObjectType() operator (See the ACPI Spec). Therefore,
+ * only add to the first group if the spec changes.
+ *
+ * NOTE: Types must be kept in sync with the global AcpiNsProperties
+ * and AcpiNsTypeNames arrays.
+ */
+typedef UINT32 ACPI_OBJECT_TYPE;
+
+#define ACPI_TYPE_ANY 0x00
+#define ACPI_TYPE_INTEGER 0x01 /* Byte/Word/Dword/Zero/One/Ones */
+#define ACPI_TYPE_STRING 0x02
+#define ACPI_TYPE_BUFFER 0x03
+#define ACPI_TYPE_PACKAGE 0x04 /* ByteConst, multiple DataTerm/Constant/SuperName */
+#define ACPI_TYPE_FIELD_UNIT 0x05
+#define ACPI_TYPE_DEVICE 0x06 /* Name, multiple Node */
+#define ACPI_TYPE_EVENT 0x07
+#define ACPI_TYPE_METHOD 0x08 /* Name, ByteConst, multiple Code */
+#define ACPI_TYPE_MUTEX 0x09
+#define ACPI_TYPE_REGION 0x0A
+#define ACPI_TYPE_POWER 0x0B /* Name,ByteConst,WordConst,multi Node */
+#define ACPI_TYPE_PROCESSOR 0x0C /* Name,ByteConst,DWordConst,ByteConst,multi NmO */
+#define ACPI_TYPE_THERMAL 0x0D /* Name, multiple Node */
+#define ACPI_TYPE_BUFFER_FIELD 0x0E
+#define ACPI_TYPE_DDB_HANDLE 0x0F
+#define ACPI_TYPE_DEBUG_OBJECT 0x10
+
+#define ACPI_TYPE_EXTERNAL_MAX 0x10
+#define ACPI_NUM_TYPES (ACPI_TYPE_EXTERNAL_MAX + 1)
+
+/*
+ * These are object types that do not map directly to the ACPI
+ * ObjectType() operator. They are used for various internal purposes only.
+ * If new predefined ACPI_TYPEs are added (via the ACPI specification), these
+ * internal types must move upwards. (There is code that depends on these
+ * values being contiguous with the external types above.)
+ */
+#define ACPI_TYPE_LOCAL_REGION_FIELD 0x11
+#define ACPI_TYPE_LOCAL_BANK_FIELD 0x12
+#define ACPI_TYPE_LOCAL_INDEX_FIELD 0x13
+#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, RefOf, Index */
+#define ACPI_TYPE_LOCAL_ALIAS 0x15
+#define ACPI_TYPE_LOCAL_METHOD_ALIAS 0x16
+#define ACPI_TYPE_LOCAL_NOTIFY 0x17
+#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x18
+#define ACPI_TYPE_LOCAL_RESOURCE 0x19
+#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x1A
+#define ACPI_TYPE_LOCAL_SCOPE 0x1B /* 1 Name, multiple ObjectList Nodes */
+
+#define ACPI_TYPE_NS_NODE_MAX 0x1B /* Last typecode used within a NS Node */
+#define ACPI_TOTAL_TYPES (ACPI_TYPE_NS_NODE_MAX + 1)
+
+/*
+ * These are special object types that never appear in
+ * a Namespace node, only in an object of ACPI_OPERAND_OBJECT
+ */
+#define ACPI_TYPE_LOCAL_EXTRA 0x1C
+#define ACPI_TYPE_LOCAL_DATA 0x1D
+
+#define ACPI_TYPE_LOCAL_MAX 0x1D
+
+/* All types above here are invalid */
+
+#define ACPI_TYPE_INVALID 0x1E
+#define ACPI_TYPE_NOT_FOUND 0xFF
+
+#define ACPI_NUM_NS_TYPES (ACPI_TYPE_INVALID + 1)
+
+
+/*
+ * All I/O
+ */
+#define ACPI_READ 0
+#define ACPI_WRITE 1
+#define ACPI_IO_MASK 1
+
+/*
+ * Event Types: Fixed & General Purpose
+ */
+typedef UINT32 ACPI_EVENT_TYPE;
+
+/*
+ * Fixed events
+ */
+#define ACPI_EVENT_PMTIMER 0
+#define ACPI_EVENT_GLOBAL 1
+#define ACPI_EVENT_POWER_BUTTON 2
+#define ACPI_EVENT_SLEEP_BUTTON 3
+#define ACPI_EVENT_RTC 4
+#define ACPI_EVENT_MAX 4
+#define ACPI_NUM_FIXED_EVENTS ACPI_EVENT_MAX + 1
+
+/*
+ * Event Status - Per event
+ * -------------
+ * The encoding of ACPI_EVENT_STATUS is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the event is enabled).
+ * +-------------+-+-+-+-+-+
+ * | Bits 31:5 |4|3|2|1|0|
+ * +-------------+-+-+-+-+-+
+ * | | | | | |
+ * | | | | | +- Enabled?
+ * | | | | +--- Enabled for wake?
+ * | | | +----- Status bit set?
+ * | | +------- Enable bit set?
+ * | +--------- Has a handler?
+ * +--------------- <Reserved>
+ */
+typedef UINT32 ACPI_EVENT_STATUS;
+
+#define ACPI_EVENT_FLAG_DISABLED (ACPI_EVENT_STATUS) 0x00
+#define ACPI_EVENT_FLAG_ENABLED (ACPI_EVENT_STATUS) 0x01
+#define ACPI_EVENT_FLAG_WAKE_ENABLED (ACPI_EVENT_STATUS) 0x02
+#define ACPI_EVENT_FLAG_STATUS_SET (ACPI_EVENT_STATUS) 0x04
+#define ACPI_EVENT_FLAG_ENABLE_SET (ACPI_EVENT_STATUS) 0x08
+#define ACPI_EVENT_FLAG_HAS_HANDLER (ACPI_EVENT_STATUS) 0x10
+#define ACPI_EVENT_FLAG_SET ACPI_EVENT_FLAG_STATUS_SET
+
+/* Actions for AcpiSetGpe, AcpiGpeWakeup, AcpiHwLowSetGpe */
+
+#define ACPI_GPE_ENABLE 0
+#define ACPI_GPE_DISABLE 1
+#define ACPI_GPE_CONDITIONAL_ENABLE 2
+
+/*
+ * GPE info flags - Per GPE
+ * +-------+-+-+---+
+ * | 7:5 |4|3|2:0|
+ * +-------+-+-+---+
+ * | | | |
+ * | | | +-- Type of dispatch:to method, handler, notify, or none
+ * | | +----- Interrupt type: edge or level triggered
+ * | +------- Is a Wake GPE
+ * +------------ <Reserved>
+ */
+#define ACPI_GPE_DISPATCH_NONE (UINT8) 0x00
+#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x01
+#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x02
+#define ACPI_GPE_DISPATCH_NOTIFY (UINT8) 0x03
+#define ACPI_GPE_DISPATCH_RAW_HANDLER (UINT8) 0x04
+#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x07
+#define ACPI_GPE_DISPATCH_TYPE(flags) ((UINT8) ((flags) & ACPI_GPE_DISPATCH_MASK))
+
+#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x08
+#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00
+#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x08
+
+#define ACPI_GPE_CAN_WAKE (UINT8) 0x10
+
+/*
+ * Flags for GPE and Lock interfaces
+ */
+#define ACPI_NOT_ISR 0x1
+#define ACPI_ISR 0x0
+
+
+/* Notify types */
+
+#define ACPI_SYSTEM_NOTIFY 0x1
+#define ACPI_DEVICE_NOTIFY 0x2
+#define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY)
+#define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3
+#define ACPI_NUM_NOTIFY_TYPES 2
+
+#define ACPI_MAX_SYS_NOTIFY 0x7F
+#define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF
+
+#define ACPI_SYSTEM_HANDLER_LIST 0 /* Used as index, must be SYSTEM_NOTIFY -1 */
+#define ACPI_DEVICE_HANDLER_LIST 1 /* Used as index, must be DEVICE_NOTIFY -1 */
+
+
+/* Address Space (Operation Region) Types */
+
+typedef UINT8 ACPI_ADR_SPACE_TYPE;
+
+#define ACPI_ADR_SPACE_SYSTEM_MEMORY (ACPI_ADR_SPACE_TYPE) 0
+#define ACPI_ADR_SPACE_SYSTEM_IO (ACPI_ADR_SPACE_TYPE) 1
+#define ACPI_ADR_SPACE_PCI_CONFIG (ACPI_ADR_SPACE_TYPE) 2
+#define ACPI_ADR_SPACE_EC (ACPI_ADR_SPACE_TYPE) 3
+#define ACPI_ADR_SPACE_SMBUS (ACPI_ADR_SPACE_TYPE) 4
+#define ACPI_ADR_SPACE_CMOS (ACPI_ADR_SPACE_TYPE) 5
+#define ACPI_ADR_SPACE_PCI_BAR_TARGET (ACPI_ADR_SPACE_TYPE) 6
+#define ACPI_ADR_SPACE_IPMI (ACPI_ADR_SPACE_TYPE) 7
+#define ACPI_ADR_SPACE_GPIO (ACPI_ADR_SPACE_TYPE) 8
+#define ACPI_ADR_SPACE_GSBUS (ACPI_ADR_SPACE_TYPE) 9
+#define ACPI_ADR_SPACE_PLATFORM_COMM (ACPI_ADR_SPACE_TYPE) 10
+
+#define ACPI_NUM_PREDEFINED_REGIONS 11
+
+/*
+ * Special Address Spaces
+ *
+ * Note: A Data Table region is a special type of operation region
+ * that has its own AML opcode. However, internally, the AML
+ * interpreter simply creates an operation region with an an address
+ * space type of ACPI_ADR_SPACE_DATA_TABLE.
+ */
+#define ACPI_ADR_SPACE_DATA_TABLE (ACPI_ADR_SPACE_TYPE) 0x7E /* Internal to ACPICA only */
+#define ACPI_ADR_SPACE_FIXED_HARDWARE (ACPI_ADR_SPACE_TYPE) 0x7F
+
+/* Values for _REG connection code */
+
+#define ACPI_REG_DISCONNECT 0
+#define ACPI_REG_CONNECT 1
+
+/*
+ * BitRegister IDs
+ *
+ * These values are intended to be used by the hardware interfaces
+ * and are mapped to individual bitfields defined within the ACPI
+ * registers. See the AcpiGbl_BitRegisterInfo global table in utglobal.c
+ * for this mapping.
+ */
+
+/* PM1 Status register */
+
+#define ACPI_BITREG_TIMER_STATUS 0x00
+#define ACPI_BITREG_BUS_MASTER_STATUS 0x01
+#define ACPI_BITREG_GLOBAL_LOCK_STATUS 0x02
+#define ACPI_BITREG_POWER_BUTTON_STATUS 0x03
+#define ACPI_BITREG_SLEEP_BUTTON_STATUS 0x04
+#define ACPI_BITREG_RT_CLOCK_STATUS 0x05
+#define ACPI_BITREG_WAKE_STATUS 0x06
+#define ACPI_BITREG_PCIEXP_WAKE_STATUS 0x07
+
+/* PM1 Enable register */
+
+#define ACPI_BITREG_TIMER_ENABLE 0x08
+#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x09
+#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x0A
+#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0B
+#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0C
+#define ACPI_BITREG_PCIEXP_WAKE_DISABLE 0x0D
+
+/* PM1 Control register */
+
+#define ACPI_BITREG_SCI_ENABLE 0x0E
+#define ACPI_BITREG_BUS_MASTER_RLD 0x0F
+#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x10
+#define ACPI_BITREG_SLEEP_TYPE 0x11
+#define ACPI_BITREG_SLEEP_ENABLE 0x12
+
+/* PM2 Control register */
+
+#define ACPI_BITREG_ARB_DISABLE 0x13
+
+#define ACPI_BITREG_MAX 0x13
+#define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1
+
+
+/* Status register values. A 1 clears a status bit. 0 = no effect */
+
+#define ACPI_CLEAR_STATUS 1
+
+/* Enable and Control register values */
+
+#define ACPI_ENABLE_EVENT 1
+#define ACPI_DISABLE_EVENT 0
+
+
+/* Sleep function dispatch */
+
+typedef ACPI_STATUS (*ACPI_SLEEP_FUNCTION) (
+ UINT8 SleepState);
+
+typedef struct acpi_sleep_functions
+{
+ ACPI_SLEEP_FUNCTION LegacyFunction;
+ ACPI_SLEEP_FUNCTION ExtendedFunction;
+
+} ACPI_SLEEP_FUNCTIONS;
+
+
+/*
+ * External ACPI object definition
+ */
+
+/*
+ * Note: Type == ACPI_TYPE_ANY (0) is used to indicate a NULL package element
+ * or an unresolved named reference.
+ */
+typedef union acpi_object
+{
+ ACPI_OBJECT_TYPE Type; /* See definition of AcpiNsType for values */
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_INTEGER */
+ UINT64 Value; /* The actual number */
+ } Integer;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_STRING */
+ UINT32 Length; /* # of bytes in string, excluding trailing null */
+ char *Pointer; /* points to the string value */
+ } String;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_BUFFER */
+ UINT32 Length; /* # of bytes in buffer */
+ UINT8 *Pointer; /* points to the buffer */
+ } Buffer;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_PACKAGE */
+ UINT32 Count; /* # of elements in package */
+ union acpi_object *Elements; /* Pointer to an array of ACPI_OBJECTs */
+ } Package;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_LOCAL_REFERENCE */
+ ACPI_OBJECT_TYPE ActualType; /* Type associated with the Handle */
+ ACPI_HANDLE Handle; /* object reference */
+ } Reference;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_PROCESSOR */
+ UINT32 ProcId;
+ ACPI_IO_ADDRESS PblkAddress;
+ UINT32 PblkLength;
+ } Processor;
+
+ struct
+ {
+ ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_POWER */
+ UINT32 SystemLevel;
+ UINT32 ResourceOrder;
+ } PowerResource;
+
+} ACPI_OBJECT;
+
+
+/*
+ * List of objects, used as a parameter list for control method evaluation
+ */
+typedef struct acpi_object_list
+{
+ UINT32 Count;
+ ACPI_OBJECT *Pointer;
+
+} ACPI_OBJECT_LIST;
+
+
+/*
+ * Miscellaneous common Data Structures used by the interfaces
+ */
+#define ACPI_NO_BUFFER 0
+
+#ifdef ACPI_NO_MEM_ALLOCATIONS
+
+#define ACPI_ALLOCATE_BUFFER (ACPI_SIZE) (0)
+#define ACPI_ALLOCATE_LOCAL_BUFFER (ACPI_SIZE) (0)
+
+#else /* ACPI_NO_MEM_ALLOCATIONS */
+
+#define ACPI_ALLOCATE_BUFFER (ACPI_SIZE) (-1) /* Let ACPICA allocate buffer */
+#define ACPI_ALLOCATE_LOCAL_BUFFER (ACPI_SIZE) (-2) /* For internal use only (enables tracking) */
+
+#endif /* ACPI_NO_MEM_ALLOCATIONS */
+
+typedef struct acpi_buffer
+{
+ ACPI_SIZE Length; /* Length in bytes of the buffer */
+ void *Pointer; /* pointer to buffer */
+
+} ACPI_BUFFER;
+
+
+/*
+ * NameType for AcpiGetName
+ */
+#define ACPI_FULL_PATHNAME 0
+#define ACPI_SINGLE_NAME 1
+#define ACPI_FULL_PATHNAME_NO_TRAILING 2
+#define ACPI_NAME_TYPE_MAX 2
+
+
+/*
+ * Predefined Namespace items
+ */
+typedef struct acpi_predefined_names
+{
+ char *Name;
+ UINT8 Type;
+ char *Val;
+
+} ACPI_PREDEFINED_NAMES;
+
+
+/*
+ * Structure and flags for AcpiGetSystemInfo
+ */
+#define ACPI_SYS_MODE_UNKNOWN 0x0000
+#define ACPI_SYS_MODE_ACPI 0x0001
+#define ACPI_SYS_MODE_LEGACY 0x0002
+#define ACPI_SYS_MODES_MASK 0x0003
+
+
+/*
+ * System info returned by AcpiGetSystemInfo()
+ */
+typedef struct acpi_system_info
+{
+ UINT32 AcpiCaVersion;
+ UINT32 Flags;
+ UINT32 TimerResolution;
+ UINT32 Reserved1;
+ UINT32 Reserved2;
+ UINT32 DebugLevel;
+ UINT32 DebugLayer;
+
+} ACPI_SYSTEM_INFO;
+
+
+/*
+ * System statistics returned by AcpiGetStatistics()
+ */
+typedef struct acpi_statistics
+{
+ UINT32 SciCount;
+ UINT32 GpeCount;
+ UINT32 FixedEventCount[ACPI_NUM_FIXED_EVENTS];
+ UINT32 MethodCount;
+
+} ACPI_STATISTICS;
+
+
+/* Table Event Types */
+
+#define ACPI_TABLE_EVENT_LOAD 0x0
+#define ACPI_TABLE_EVENT_UNLOAD 0x1
+#define ACPI_NUM_TABLE_EVENTS 2
+
+
+/*
+ * Types specific to the OS service interfaces
+ */
+typedef UINT32
+(ACPI_SYSTEM_XFACE *ACPI_OSD_HANDLER) (
+ void *Context);
+
+typedef void
+(ACPI_SYSTEM_XFACE *ACPI_OSD_EXEC_CALLBACK) (
+ void *Context);
+
+/*
+ * Various handlers and callback procedures
+ */
+typedef
+UINT32 (*ACPI_SCI_HANDLER) (
+ void *Context);
+
+typedef
+void (*ACPI_GBL_EVENT_HANDLER) (
+ UINT32 EventType,
+ ACPI_HANDLE Device,
+ UINT32 EventNumber,
+ void *Context);
+
+#define ACPI_EVENT_TYPE_GPE 0
+#define ACPI_EVENT_TYPE_FIXED 1
+
+typedef
+UINT32 (*ACPI_EVENT_HANDLER) (
+ void *Context);
+
+typedef
+UINT32 (*ACPI_GPE_HANDLER) (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ void *Context);
+
+typedef
+void (*ACPI_NOTIFY_HANDLER) (
+ ACPI_HANDLE Device,
+ UINT32 Value,
+ void *Context);
+
+typedef
+void (*ACPI_OBJECT_HANDLER) (
+ ACPI_HANDLE Object,
+ void *Data);
+
+typedef
+ACPI_STATUS (*ACPI_INIT_HANDLER) (
+ ACPI_HANDLE Object,
+ UINT32 Function);
+
+#define ACPI_INIT_DEVICE_INI 1
+
+typedef
+ACPI_STATUS (*ACPI_EXCEPTION_HANDLER) (
+ ACPI_STATUS AmlStatus,
+ ACPI_NAME Name,
+ UINT16 Opcode,
+ UINT32 AmlOffset,
+ void *Context);
+
+/* Table Event handler (Load, LoadTable, etc.) and types */
+
+typedef
+ACPI_STATUS (*ACPI_TABLE_HANDLER) (
+ UINT32 Event,
+ void *Table,
+ void *Context);
+
+#define ACPI_TABLE_LOAD 0x0
+#define ACPI_TABLE_UNLOAD 0x1
+#define ACPI_NUM_TABLE_EVENTS 2
+
+
+/* Address Spaces (For Operation Regions) */
+
+typedef
+ACPI_STATUS (*ACPI_ADR_SPACE_HANDLER) (
+ UINT32 Function,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 BitWidth,
+ UINT64 *Value,
+ void *HandlerContext,
+ void *RegionContext);
+
+#define ACPI_DEFAULT_HANDLER NULL
+
+/* Special Context data for GenericSerialBus/GeneralPurposeIo (ACPI 5.0) */
+
+typedef struct acpi_connection_info
+{
+ UINT8 *Connection;
+ UINT16 Length;
+ UINT8 AccessLength;
+
+} ACPI_CONNECTION_INFO;
+
+
+typedef
+ACPI_STATUS (*ACPI_ADR_SPACE_SETUP) (
+ ACPI_HANDLE RegionHandle,
+ UINT32 Function,
+ void *HandlerContext,
+ void **RegionContext);
+
+#define ACPI_REGION_ACTIVATE 0
+#define ACPI_REGION_DEACTIVATE 1
+
+typedef
+ACPI_STATUS (*ACPI_WALK_CALLBACK) (
+ ACPI_HANDLE Object,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+typedef
+UINT32 (*ACPI_INTERFACE_HANDLER) (
+ ACPI_STRING InterfaceName,
+ UINT32 Supported);
+
+
+/* Interrupt handler return values */
+
+#define ACPI_INTERRUPT_NOT_HANDLED 0x00
+#define ACPI_INTERRUPT_HANDLED 0x01
+
+/* GPE handler return values */
+
+#define ACPI_REENABLE_GPE 0x80
+
+
+/* Length of 32-bit EISAID values when converted back to a string */
+
+#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */
+
+/* Length of UUID (string) values */
+
+#define ACPI_UUID_LENGTH 16
+
+/* Length of 3-byte PCI class code values when converted back to a string */
+
+#define ACPI_PCICLS_STRING_SIZE 7 /* Includes null terminator */
+
+
+/* Structures used for device/processor HID, UID, CID, and SUB */
+
+typedef struct acpi_pnp_device_id
+{
+ UINT32 Length; /* Length of string + null */
+ char *String;
+
+} ACPI_PNP_DEVICE_ID;
+
+typedef struct acpi_pnp_device_id_list
+{
+ UINT32 Count; /* Number of IDs in Ids array */
+ UINT32 ListSize; /* Size of list, including ID strings */
+ ACPI_PNP_DEVICE_ID Ids[1]; /* ID array */
+
+} ACPI_PNP_DEVICE_ID_LIST;
+
+/*
+ * Structure returned from AcpiGetObjectInfo.
+ * Optimized for both 32- and 64-bit builds
+ */
+typedef struct acpi_device_info
+{
+ UINT32 InfoSize; /* Size of info, including ID strings */
+ UINT32 Name; /* ACPI object Name */
+ ACPI_OBJECT_TYPE Type; /* ACPI object Type */
+ UINT8 ParamCount; /* If a method, required parameter count */
+ UINT16 Valid; /* Indicates which optional fields are valid */
+ UINT8 Flags; /* Miscellaneous info */
+ UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */
+ UINT8 LowestDstates[5]; /* _SxW values: 0xFF indicates not valid */
+ UINT32 CurrentStatus; /* _STA value */
+ UINT64 Address; /* _ADR value */
+ ACPI_PNP_DEVICE_ID HardwareId; /* _HID value */
+ ACPI_PNP_DEVICE_ID UniqueId; /* _UID value */
+ ACPI_PNP_DEVICE_ID SubsystemId; /* _SUB value */
+ ACPI_PNP_DEVICE_ID ClassCode; /* _CLS value */
+ ACPI_PNP_DEVICE_ID_LIST CompatibleIdList; /* _CID list <must be last> */
+
+} ACPI_DEVICE_INFO;
+
+/* Values for Flags field above (AcpiGetObjectInfo) */
+
+#define ACPI_PCI_ROOT_BRIDGE 0x01
+
+/* Flags for Valid field above (AcpiGetObjectInfo) */
+
+#define ACPI_VALID_STA 0x0001
+#define ACPI_VALID_ADR 0x0002
+#define ACPI_VALID_HID 0x0004
+#define ACPI_VALID_UID 0x0008
+#define ACPI_VALID_SUB 0x0010
+#define ACPI_VALID_CID 0x0020
+#define ACPI_VALID_CLS 0x0040
+#define ACPI_VALID_SXDS 0x0100
+#define ACPI_VALID_SXWS 0x0200
+
+/* Flags for _STA return value (CurrentStatus above) */
+
+#define ACPI_STA_DEVICE_PRESENT 0x01
+#define ACPI_STA_DEVICE_ENABLED 0x02
+#define ACPI_STA_DEVICE_UI 0x04
+#define ACPI_STA_DEVICE_FUNCTIONING 0x08
+#define ACPI_STA_DEVICE_OK 0x08 /* Synonym */
+#define ACPI_STA_BATTERY_PRESENT 0x10
+
+
+/* Context structs for address space handlers */
+
+typedef struct acpi_pci_id
+{
+ UINT16 Segment;
+ UINT16 Bus;
+ UINT16 Device;
+ UINT16 Function;
+
+} ACPI_PCI_ID;
+
+typedef struct acpi_mem_space_context
+{
+ UINT32 Length;
+ ACPI_PHYSICAL_ADDRESS Address;
+ ACPI_PHYSICAL_ADDRESS MappedPhysicalAddress;
+ UINT8 *MappedLogicalAddress;
+ ACPI_SIZE MappedLength;
+
+} ACPI_MEM_SPACE_CONTEXT;
+
+
+/*
+ * ACPI_MEMORY_LIST is used only if the ACPICA local cache is enabled
+ */
+typedef struct acpi_memory_list
+{
+ char *ListName;
+ void *ListHead;
+ UINT16 ObjectSize;
+ UINT16 MaxDepth;
+ UINT16 CurrentDepth;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ /* Statistics for debug memory tracking only */
+
+ UINT32 TotalAllocated;
+ UINT32 TotalFreed;
+ UINT32 MaxOccupied;
+ UINT32 TotalSize;
+ UINT32 CurrentTotalSize;
+ UINT32 Requests;
+ UINT32 Hits;
+#endif
+
+} ACPI_MEMORY_LIST;
+
+
+/* Definitions of trace event types */
+
+typedef enum
+{
+ ACPI_TRACE_AML_METHOD,
+ ACPI_TRACE_AML_OPCODE,
+ ACPI_TRACE_AML_REGION
+
+} ACPI_TRACE_EVENT_TYPE;
+
+
+/* Definitions of _OSI support */
+
+#define ACPI_VENDOR_STRINGS 0x01
+#define ACPI_FEATURE_STRINGS 0x02
+#define ACPI_ENABLE_INTERFACES 0x00
+#define ACPI_DISABLE_INTERFACES 0x04
+
+#define ACPI_DISABLE_ALL_VENDOR_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS)
+#define ACPI_DISABLE_ALL_FEATURE_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_FEATURE_STRINGS)
+#define ACPI_DISABLE_ALL_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS)
+#define ACPI_ENABLE_ALL_VENDOR_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS)
+#define ACPI_ENABLE_ALL_FEATURE_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS)
+#define ACPI_ENABLE_ALL_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS)
+
+#define ACPI_OSI_WIN_2000 0x01
+#define ACPI_OSI_WIN_XP 0x02
+#define ACPI_OSI_WIN_XP_SP1 0x03
+#define ACPI_OSI_WINSRV_2003 0x04
+#define ACPI_OSI_WIN_XP_SP2 0x05
+#define ACPI_OSI_WINSRV_2003_SP1 0x06
+#define ACPI_OSI_WIN_VISTA 0x07
+#define ACPI_OSI_WINSRV_2008 0x08
+#define ACPI_OSI_WIN_VISTA_SP1 0x09
+#define ACPI_OSI_WIN_VISTA_SP2 0x0A
+#define ACPI_OSI_WIN_7 0x0B
+#define ACPI_OSI_WIN_8 0x0C
+#define ACPI_OSI_WIN_10 0x0D
+
+
+/* Definitions of file IO */
+
+#define ACPI_FILE_READING 0x01
+#define ACPI_FILE_WRITING 0x02
+#define ACPI_FILE_BINARY 0x04
+
+#define ACPI_FILE_BEGIN 0x01
+#define ACPI_FILE_END 0x02
+
+
+/* Definitions of getopt */
+
+#define ACPI_OPT_END -1
+
+
+#endif /* __ACTYPES_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acutils.h b/usr/src/boot/sys/contrib/dev/acpica/include/acutils.h
new file mode 100644
index 0000000000..1cbaf6a6ce
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acutils.h
@@ -0,0 +1,1095 @@
+/******************************************************************************
+ *
+ * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef _ACUTILS_H
+#define _ACUTILS_H
+
+
+extern const UINT8 AcpiGbl_ResourceAmlSizes[];
+extern const UINT8 AcpiGbl_ResourceAmlSerialBusSizes[];
+
+/* Strings used by the disassembler and debugger resource dump routines */
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
+
+extern const char *AcpiGbl_BmDecode[];
+extern const char *AcpiGbl_ConfigDecode[];
+extern const char *AcpiGbl_ConsumeDecode[];
+extern const char *AcpiGbl_DecDecode[];
+extern const char *AcpiGbl_HeDecode[];
+extern const char *AcpiGbl_IoDecode[];
+extern const char *AcpiGbl_LlDecode[];
+extern const char *AcpiGbl_MaxDecode[];
+extern const char *AcpiGbl_MemDecode[];
+extern const char *AcpiGbl_MinDecode[];
+extern const char *AcpiGbl_MtpDecode[];
+extern const char *AcpiGbl_RngDecode[];
+extern const char *AcpiGbl_RwDecode[];
+extern const char *AcpiGbl_ShrDecode[];
+extern const char *AcpiGbl_SizDecode[];
+extern const char *AcpiGbl_TrsDecode[];
+extern const char *AcpiGbl_TtpDecode[];
+extern const char *AcpiGbl_TypDecode[];
+extern const char *AcpiGbl_PpcDecode[];
+extern const char *AcpiGbl_IorDecode[];
+extern const char *AcpiGbl_DtsDecode[];
+extern const char *AcpiGbl_CtDecode[];
+extern const char *AcpiGbl_SbtDecode[];
+extern const char *AcpiGbl_AmDecode[];
+extern const char *AcpiGbl_SmDecode[];
+extern const char *AcpiGbl_WmDecode[];
+extern const char *AcpiGbl_CphDecode[];
+extern const char *AcpiGbl_CpoDecode[];
+extern const char *AcpiGbl_DpDecode[];
+extern const char *AcpiGbl_EdDecode[];
+extern const char *AcpiGbl_BpbDecode[];
+extern const char *AcpiGbl_SbDecode[];
+extern const char *AcpiGbl_FcDecode[];
+extern const char *AcpiGbl_PtDecode[];
+#endif
+
+/*
+ * For the iASL compiler case, the output is redirected to stderr so that
+ * any of the various ACPI errors and warnings do not appear in the output
+ * files, for either the compiler or disassembler portions of the tool.
+ */
+#ifdef ACPI_ASL_COMPILER
+
+#include <stdio.h>
+
+#define ACPI_MSG_REDIRECT_BEGIN \
+ FILE *OutputFile = AcpiGbl_OutputFile; \
+ AcpiOsRedirectOutput (stderr);
+
+#define ACPI_MSG_REDIRECT_END \
+ AcpiOsRedirectOutput (OutputFile);
+
+#else
+/*
+ * non-iASL case - no redirection, nothing to do
+ */
+#define ACPI_MSG_REDIRECT_BEGIN
+#define ACPI_MSG_REDIRECT_END
+#endif
+
+/*
+ * Common error message prefixes
+ */
+#define ACPI_MSG_ERROR "ACPI Error: "
+#define ACPI_MSG_EXCEPTION "ACPI Exception: "
+#define ACPI_MSG_WARNING "ACPI Warning: "
+#define ACPI_MSG_INFO "ACPI: "
+
+#define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): "
+#define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): "
+
+/*
+ * Common message suffix
+ */
+#define ACPI_MSG_SUFFIX \
+ AcpiOsPrintf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, ModuleName, LineNumber)
+
+
+/* Types for Resource descriptor entries */
+
+#define ACPI_INVALID_RESOURCE 0
+#define ACPI_FIXED_LENGTH 1
+#define ACPI_VARIABLE_LENGTH 2
+#define ACPI_SMALL_VARIABLE_LENGTH 3
+
+typedef
+ACPI_STATUS (*ACPI_WALK_AML_CALLBACK) (
+ UINT8 *Aml,
+ UINT32 Length,
+ UINT32 Offset,
+ UINT8 ResourceIndex,
+ void **Context);
+
+typedef
+ACPI_STATUS (*ACPI_PKG_CALLBACK) (
+ UINT8 ObjectType,
+ ACPI_OPERAND_OBJECT *SourceObject,
+ ACPI_GENERIC_STATE *State,
+ void *Context);
+
+typedef struct acpi_pkg_info
+{
+ UINT8 *FreeSpace;
+ ACPI_SIZE Length;
+ UINT32 ObjectSpace;
+ UINT32 NumPackages;
+
+} ACPI_PKG_INFO;
+
+/* Object reference counts */
+
+#define REF_INCREMENT (UINT16) 0
+#define REF_DECREMENT (UINT16) 1
+
+/* AcpiUtDumpBuffer */
+
+#define DB_BYTE_DISPLAY 1
+#define DB_WORD_DISPLAY 2
+#define DB_DWORD_DISPLAY 4
+#define DB_QWORD_DISPLAY 8
+
+
+/*
+ * utnonansi - Non-ANSI C library functions
+ */
+void
+AcpiUtStrupr (
+ char *SrcString);
+
+void
+AcpiUtStrlwr (
+ char *SrcString);
+
+int
+AcpiUtStricmp (
+ char *String1,
+ char *String2);
+
+ACPI_STATUS
+AcpiUtStrtoul64 (
+ char *String,
+ UINT32 Base,
+ UINT64 *RetInteger);
+
+
+/*
+ * utglobal - Global data structures and procedures
+ */
+ACPI_STATUS
+AcpiUtInitGlobals (
+ void);
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+char *
+AcpiUtGetMutexName (
+ UINT32 MutexId);
+
+const char *
+AcpiUtGetNotifyName (
+ UINT32 NotifyValue,
+ ACPI_OBJECT_TYPE Type);
+#endif
+
+char *
+AcpiUtGetTypeName (
+ ACPI_OBJECT_TYPE Type);
+
+char *
+AcpiUtGetNodeName (
+ void *Object);
+
+char *
+AcpiUtGetDescriptorName (
+ void *Object);
+
+const char *
+AcpiUtGetReferenceName (
+ ACPI_OPERAND_OBJECT *Object);
+
+char *
+AcpiUtGetObjectTypeName (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+char *
+AcpiUtGetRegionName (
+ UINT8 SpaceId);
+
+char *
+AcpiUtGetEventName (
+ UINT32 EventId);
+
+char
+AcpiUtHexToAsciiChar (
+ UINT64 Integer,
+ UINT32 Position);
+
+UINT8
+AcpiUtAsciiCharToHex (
+ int HexChar);
+
+BOOLEAN
+AcpiUtValidObjectType (
+ ACPI_OBJECT_TYPE Type);
+
+
+/*
+ * utinit - miscellaneous initialization and shutdown
+ */
+ACPI_STATUS
+AcpiUtHardwareInitialize (
+ void);
+
+void
+AcpiUtSubsystemShutdown (
+ void);
+
+
+/*
+ * utcopy - Object construction and conversion interfaces
+ */
+ACPI_STATUS
+AcpiUtBuildSimpleObject(
+ ACPI_OPERAND_OBJECT *Obj,
+ ACPI_OBJECT *UserObj,
+ UINT8 *DataSpace,
+ UINT32 *BufferSpaceUsed);
+
+ACPI_STATUS
+AcpiUtBuildPackageObject (
+ ACPI_OPERAND_OBJECT *Obj,
+ UINT8 *Buffer,
+ UINT32 *SpaceUsed);
+
+ACPI_STATUS
+AcpiUtCopyIobjectToEobject (
+ ACPI_OPERAND_OBJECT *Obj,
+ ACPI_BUFFER *RetBuffer);
+
+ACPI_STATUS
+AcpiUtCopyEobjectToIobject (
+ ACPI_OBJECT *Obj,
+ ACPI_OPERAND_OBJECT **InternalObj);
+
+ACPI_STATUS
+AcpiUtCopyISimpleToIsimple (
+ ACPI_OPERAND_OBJECT *SourceObj,
+ ACPI_OPERAND_OBJECT *DestObj);
+
+ACPI_STATUS
+AcpiUtCopyIobjectToIobject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ ACPI_OPERAND_OBJECT **DestDesc,
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * utcreate - Object creation
+ */
+ACPI_STATUS
+AcpiUtUpdateObjectReference (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action);
+
+
+/*
+ * utdebug - Debug interfaces
+ */
+void
+AcpiUtInitStackPtrTrace (
+ void);
+
+void
+AcpiUtTrackStackPtr (
+ void);
+
+void
+AcpiUtTrace (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId);
+
+void
+AcpiUtTracePtr (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ void *Pointer);
+
+void
+AcpiUtTraceU32 (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ UINT32 Integer);
+
+void
+AcpiUtTraceStr (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ char *String);
+
+void
+AcpiUtExit (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId);
+
+void
+AcpiUtStatusExit (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ ACPI_STATUS Status);
+
+void
+AcpiUtValueExit (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ UINT64 Value);
+
+void
+AcpiUtPtrExit (
+ UINT32 LineNumber,
+ const char *FunctionName,
+ const char *ModuleName,
+ UINT32 ComponentId,
+ UINT8 *Ptr);
+
+void
+AcpiUtDebugDumpBuffer (
+ UINT8 *Buffer,
+ UINT32 Count,
+ UINT32 Display,
+ UINT32 ComponentId);
+
+void
+AcpiUtDumpBuffer (
+ UINT8 *Buffer,
+ UINT32 Count,
+ UINT32 Display,
+ UINT32 Offset);
+
+#ifdef ACPI_APPLICATION
+void
+AcpiUtDumpBufferToFile (
+ ACPI_FILE File,
+ UINT8 *Buffer,
+ UINT32 Count,
+ UINT32 Display,
+ UINT32 BaseOffset);
+#endif
+
+void
+AcpiUtReportError (
+ char *ModuleName,
+ UINT32 LineNumber);
+
+void
+AcpiUtReportInfo (
+ char *ModuleName,
+ UINT32 LineNumber);
+
+void
+AcpiUtReportWarning (
+ char *ModuleName,
+ UINT32 LineNumber);
+
+
+/*
+ * utdelete - Object deletion and reference counts
+ */
+void
+AcpiUtAddReference (
+ ACPI_OPERAND_OBJECT *Object);
+
+void
+AcpiUtRemoveReference (
+ ACPI_OPERAND_OBJECT *Object);
+
+void
+AcpiUtDeleteInternalPackageObject (
+ ACPI_OPERAND_OBJECT *Object);
+
+void
+AcpiUtDeleteInternalSimpleObject (
+ ACPI_OPERAND_OBJECT *Object);
+
+void
+AcpiUtDeleteInternalObjectList (
+ ACPI_OPERAND_OBJECT **ObjList);
+
+
+/*
+ * uteval - object evaluation
+ */
+ACPI_STATUS
+AcpiUtEvaluateObject (
+ ACPI_NAMESPACE_NODE *PrefixNode,
+ char *Path,
+ UINT32 ExpectedReturnBtypes,
+ ACPI_OPERAND_OBJECT **ReturnDesc);
+
+ACPI_STATUS
+AcpiUtEvaluateNumericObject (
+ char *ObjectName,
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ UINT64 *Value);
+
+ACPI_STATUS
+AcpiUtExecute_STA (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ UINT32 *StatusFlags);
+
+ACPI_STATUS
+AcpiUtExecutePowerMethods (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ const char **MethodNames,
+ UINT8 MethodCount,
+ UINT8 *OutValues);
+
+
+/*
+ * utfileio - file operations
+ */
+#ifdef ACPI_APPLICATION
+ACPI_STATUS
+AcpiUtReadTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **Table);
+#endif
+
+
+/*
+ * utids - device ID support
+ */
+ACPI_STATUS
+AcpiUtExecute_HID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId);
+
+ACPI_STATUS
+AcpiUtExecute_UID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId);
+
+ACPI_STATUS
+AcpiUtExecute_SUB (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId);
+
+ACPI_STATUS
+AcpiUtExecute_CID (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID_LIST **ReturnCidList);
+
+ACPI_STATUS
+AcpiUtExecute_CLS (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId);
+
+
+/*
+ * utlock - reader/writer locks
+ */
+ACPI_STATUS
+AcpiUtCreateRwLock (
+ ACPI_RW_LOCK *Lock);
+
+void
+AcpiUtDeleteRwLock (
+ ACPI_RW_LOCK *Lock);
+
+ACPI_STATUS
+AcpiUtAcquireReadLock (
+ ACPI_RW_LOCK *Lock);
+
+ACPI_STATUS
+AcpiUtReleaseReadLock (
+ ACPI_RW_LOCK *Lock);
+
+ACPI_STATUS
+AcpiUtAcquireWriteLock (
+ ACPI_RW_LOCK *Lock);
+
+void
+AcpiUtReleaseWriteLock (
+ ACPI_RW_LOCK *Lock);
+
+
+/*
+ * utobject - internal object create/delete/cache routines
+ */
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateInternalObjectDbg (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ UINT32 ComponentId,
+ ACPI_OBJECT_TYPE Type);
+
+void *
+AcpiUtAllocateObjectDescDbg (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ UINT32 ComponentId);
+
+#define AcpiUtCreateInternalObject(t) AcpiUtCreateInternalObjectDbg (_AcpiModuleName,__LINE__,_COMPONENT,t)
+#define AcpiUtAllocateObjectDesc() AcpiUtAllocateObjectDescDbg (_AcpiModuleName,__LINE__,_COMPONENT)
+
+void
+AcpiUtDeleteObjectDesc (
+ ACPI_OPERAND_OBJECT *Object);
+
+BOOLEAN
+AcpiUtValidInternalObject (
+ void *Object);
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreatePackageObject (
+ UINT32 Count);
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateIntegerObject (
+ UINT64 Value);
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateBufferObject (
+ ACPI_SIZE BufferSize);
+
+ACPI_OPERAND_OBJECT *
+AcpiUtCreateStringObject (
+ ACPI_SIZE StringSize);
+
+ACPI_STATUS
+AcpiUtGetObjectSize(
+ ACPI_OPERAND_OBJECT *Obj,
+ ACPI_SIZE *ObjLength);
+
+
+/*
+ * utosi - Support for the _OSI predefined control method
+ */
+ACPI_STATUS
+AcpiUtInitializeInterfaces (
+ void);
+
+ACPI_STATUS
+AcpiUtInterfaceTerminate (
+ void);
+
+ACPI_STATUS
+AcpiUtInstallInterface (
+ ACPI_STRING InterfaceName);
+
+ACPI_STATUS
+AcpiUtRemoveInterface (
+ ACPI_STRING InterfaceName);
+
+ACPI_STATUS
+AcpiUtUpdateInterfaces (
+ UINT8 Action);
+
+ACPI_INTERFACE_INFO *
+AcpiUtGetInterface (
+ ACPI_STRING InterfaceName);
+
+ACPI_STATUS
+AcpiUtOsiImplementation (
+ ACPI_WALK_STATE *WalkState);
+
+
+/*
+ * utpredef - support for predefined names
+ */
+const ACPI_PREDEFINED_INFO *
+AcpiUtGetNextPredefinedMethod (
+ const ACPI_PREDEFINED_INFO *ThisName);
+
+const ACPI_PREDEFINED_INFO *
+AcpiUtMatchPredefinedMethod (
+ char *Name);
+
+void
+AcpiUtGetExpectedReturnTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes);
+
+#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP)
+const ACPI_PREDEFINED_INFO *
+AcpiUtMatchResourceName (
+ char *Name);
+
+void
+AcpiUtDisplayPredefinedMethod (
+ char *Buffer,
+ const ACPI_PREDEFINED_INFO *ThisName,
+ BOOLEAN MultiLine);
+
+UINT32
+AcpiUtGetResourceBitWidth (
+ char *Buffer,
+ UINT16 Types);
+#endif
+
+
+/*
+ * utstate - Generic state creation/cache routines
+ */
+void
+AcpiUtPushGenericState (
+ ACPI_GENERIC_STATE **ListHead,
+ ACPI_GENERIC_STATE *State);
+
+ACPI_GENERIC_STATE *
+AcpiUtPopGenericState (
+ ACPI_GENERIC_STATE **ListHead);
+
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateGenericState (
+ void);
+
+ACPI_THREAD_STATE *
+AcpiUtCreateThreadState (
+ void);
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateUpdateState (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action);
+
+ACPI_GENERIC_STATE *
+AcpiUtCreatePkgState (
+ void *InternalObject,
+ void *ExternalObject,
+ UINT16 Index);
+
+ACPI_STATUS
+AcpiUtCreateUpdateStateAndPush (
+ ACPI_OPERAND_OBJECT *Object,
+ UINT16 Action,
+ ACPI_GENERIC_STATE **StateList);
+
+ACPI_GENERIC_STATE *
+AcpiUtCreateControlState (
+ void);
+
+void
+AcpiUtDeleteGenericState (
+ ACPI_GENERIC_STATE *State);
+
+
+/*
+ * utmath
+ */
+ACPI_STATUS
+AcpiUtDivide (
+ UINT64 InDividend,
+ UINT64 InDivisor,
+ UINT64 *OutQuotient,
+ UINT64 *OutRemainder);
+
+ACPI_STATUS
+AcpiUtShortDivide (
+ UINT64 InDividend,
+ UINT32 Divisor,
+ UINT64 *OutQuotient,
+ UINT32 *OutRemainder);
+
+
+/*
+ * utmisc
+ */
+const ACPI_EXCEPTION_INFO *
+AcpiUtValidateException (
+ ACPI_STATUS Status);
+
+BOOLEAN
+AcpiUtIsPciRootBridge (
+ char *Id);
+
+#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP)
+BOOLEAN
+AcpiUtIsAmlTable (
+ ACPI_TABLE_HEADER *Table);
+#endif
+
+ACPI_STATUS
+AcpiUtWalkPackageTree (
+ ACPI_OPERAND_OBJECT *SourceObject,
+ void *TargetObject,
+ ACPI_PKG_CALLBACK WalkCallback,
+ void *Context);
+
+/* Values for Base above (16=Hex, 10=Decimal) */
+
+#define ACPI_ANY_BASE 0
+
+
+UINT32
+AcpiUtDwordByteSwap (
+ UINT32 Value);
+
+void
+AcpiUtSetIntegerWidth (
+ UINT8 Revision);
+
+#ifdef ACPI_DEBUG_OUTPUT
+void
+AcpiUtDisplayInitPathname (
+ UINT8 Type,
+ ACPI_NAMESPACE_NODE *ObjHandle,
+ char *Path);
+#endif
+
+
+/*
+ * utownerid - Support for Table/Method Owner IDs
+ */
+ACPI_STATUS
+AcpiUtAllocateOwnerId (
+ ACPI_OWNER_ID *OwnerId);
+
+void
+AcpiUtReleaseOwnerId (
+ ACPI_OWNER_ID *OwnerId);
+
+
+/*
+ * utresrc
+ */
+ACPI_STATUS
+AcpiUtWalkAmlResources (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *Aml,
+ ACPI_SIZE AmlLength,
+ ACPI_WALK_AML_CALLBACK UserFunction,
+ void **Context);
+
+ACPI_STATUS
+AcpiUtValidateResource (
+ ACPI_WALK_STATE *WalkState,
+ void *Aml,
+ UINT8 *ReturnIndex);
+
+UINT32
+AcpiUtGetDescriptorLength (
+ void *Aml);
+
+UINT16
+AcpiUtGetResourceLength (
+ void *Aml);
+
+UINT8
+AcpiUtGetResourceHeaderLength (
+ void *Aml);
+
+UINT8
+AcpiUtGetResourceType (
+ void *Aml);
+
+ACPI_STATUS
+AcpiUtGetResourceEndTag (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT8 **EndTag);
+
+
+/*
+ * utstring - String and character utilities
+ */
+void
+AcpiUtPrintString (
+ char *String,
+ UINT16 MaxLength);
+
+#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
+void
+UtConvertBackslashes (
+ char *Pathname);
+#endif
+
+BOOLEAN
+AcpiUtValidAcpiName (
+ char *Name);
+
+BOOLEAN
+AcpiUtValidAcpiChar (
+ char Character,
+ UINT32 Position);
+
+void
+AcpiUtRepairName (
+ char *Name);
+
+#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
+BOOLEAN
+AcpiUtSafeStrcpy (
+ char *Dest,
+ ACPI_SIZE DestSize,
+ char *Source);
+
+BOOLEAN
+AcpiUtSafeStrcat (
+ char *Dest,
+ ACPI_SIZE DestSize,
+ char *Source);
+#endif
+
+
+/*
+ * utmutex - mutex support
+ */
+ACPI_STATUS
+AcpiUtMutexInitialize (
+ void);
+
+void
+AcpiUtMutexTerminate (
+ void);
+
+ACPI_STATUS
+AcpiUtAcquireMutex (
+ ACPI_MUTEX_HANDLE MutexId);
+
+ACPI_STATUS
+AcpiUtReleaseMutex (
+ ACPI_MUTEX_HANDLE MutexId);
+
+
+/*
+ * utalloc - memory allocation and object caching
+ */
+ACPI_STATUS
+AcpiUtCreateCaches (
+ void);
+
+ACPI_STATUS
+AcpiUtDeleteCaches (
+ void);
+
+ACPI_STATUS
+AcpiUtValidateBuffer (
+ ACPI_BUFFER *Buffer);
+
+ACPI_STATUS
+AcpiUtInitializeBuffer (
+ ACPI_BUFFER *Buffer,
+ ACPI_SIZE RequiredLength);
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+void *
+AcpiUtAllocateAndTrack (
+ ACPI_SIZE Size,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line);
+
+void *
+AcpiUtAllocateZeroedAndTrack (
+ ACPI_SIZE Size,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line);
+
+void
+AcpiUtFreeAndTrack (
+ void *Address,
+ UINT32 Component,
+ const char *Module,
+ UINT32 Line);
+
+void
+AcpiUtDumpAllocationInfo (
+ void);
+
+void
+AcpiUtDumpAllocations (
+ UINT32 Component,
+ const char *Module);
+
+ACPI_STATUS
+AcpiUtCreateList (
+ char *ListName,
+ UINT16 ObjectSize,
+ ACPI_MEMORY_LIST **ReturnCache);
+
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+
+
+/*
+ * utaddress - address range check
+ */
+ACPI_STATUS
+AcpiUtAddAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 Length,
+ ACPI_NAMESPACE_NODE *RegionNode);
+
+void
+AcpiUtRemoveAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_NAMESPACE_NODE *RegionNode);
+
+UINT32
+AcpiUtCheckAddressRange (
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT32 Length,
+ BOOLEAN Warn);
+
+void
+AcpiUtDeleteAddressLists (
+ void);
+
+
+/*
+ * utxferror - various error/warning output functions
+ */
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...);
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedInfo (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...);
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiUtPredefinedBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ char *Pathname,
+ UINT8 NodeFlags,
+ const char *Format,
+ ...);
+
+void
+AcpiUtNamespaceError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *InternalName,
+ ACPI_STATUS LookupStatus);
+
+void
+AcpiUtMethodError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Message,
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Path,
+ ACPI_STATUS LookupStatus);
+
+
+/*
+ * Utility functions for ACPI names and IDs
+ */
+const AH_PREDEFINED_NAME *
+AcpiAhMatchPredefinedName (
+ char *Nameseg);
+
+const AH_DEVICE_ID *
+AcpiAhMatchHardwareId (
+ char *Hid);
+
+const char *
+AcpiAhMatchUuid (
+ UINT8 *Data);
+
+
+/*
+ * utprint - printf/vprintf output functions
+ */
+const char *
+AcpiUtScanNumber (
+ const char *String,
+ UINT64 *NumberPtr);
+
+const char *
+AcpiUtPrintNumber (
+ char *String,
+ UINT64 Number);
+
+int
+AcpiUtVsnprintf (
+ char *String,
+ ACPI_SIZE Size,
+ const char *Format,
+ va_list Args);
+
+int
+AcpiUtSnprintf (
+ char *String,
+ ACPI_SIZE Size,
+ const char *Format,
+ ...);
+
+#ifdef ACPI_APPLICATION
+int
+AcpiUtFileVprintf (
+ ACPI_FILE File,
+ const char *Format,
+ va_list Args);
+
+int
+AcpiUtFilePrintf (
+ ACPI_FILE File,
+ const char *Format,
+ ...);
+#endif
+
+
+/*
+ * utuuid -- UUID support functions
+ */
+#if (defined ACPI_ASL_COMPILER || defined ACPI_DISASSEMBLER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP)
+void
+AcpiUtConvertStringToUuid (
+ char *InString,
+ UINT8 *UuidBuffer);
+#endif
+
+#endif /* _ACUTILS_H */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/acuuid.h b/usr/src/boot/sys/contrib/dev/acpica/include/acuuid.h
new file mode 100644
index 0000000000..59c1768fc7
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/acuuid.h
@@ -0,0 +1,90 @@
+/******************************************************************************
+ *
+ * Name: acuuid.h - ACPI-related UUID/GUID definitions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACUUID_H__
+#define __ACUUID_H__
+
+/*
+ * Note1: UUIDs and GUIDs are defined to be identical in ACPI.
+ *
+ * Note2: This file is standalone and should remain that way.
+ */
+
+/* Controllers */
+
+#define UUID_GPIO_CONTROLLER "4f248f40-d5e2-499f-834c-27758ea1cd3f"
+#define UUID_USB_CONTROLLER "ce2ee385-00e6-48cb-9f05-2edb927c4899"
+#define UUID_SATA_CONTROLLER "e4db149b-fcfe-425b-a6d8-92357d78fc7f"
+
+/* Devices */
+
+#define UUID_PCI_HOST_BRIDGE "33db4d5b-1ff7-401c-9657-7441c03dd766"
+#define UUID_I2C_DEVICE "3cdff6f7-4267-4555-ad05-b30a3d8938de"
+#define UUID_POWER_BUTTON "dfbcf3c5-e7a5-44e6-9c1f-29c76f6e059c"
+
+/* Interfaces */
+
+#define UUID_DEVICE_LABELING "e5c937d0-3553-4d7a-9117-ea4d19c3434d"
+#define UUID_PHYSICAL_PRESENCE "3dddfaa6-361b-4eb4-a424-8d10089d1653"
+
+/* NVDIMM - NFIT table */
+
+#define UUID_VOLATILE_MEMORY "7305944f-fdda-44e3-b16c-3f22d252e5d0"
+#define UUID_PERSISTENT_MEMORY "66f0d379-b4f3-4074-ac43-0d3318b78cdb"
+#define UUID_CONTROL_REGION "92f701f6-13b4-405d-910b-299367e8234c"
+#define UUID_DATA_REGION "91af0530-5d86-470e-a6b0-0a2db9408249"
+#define UUID_VOLATILE_VIRTUAL_DISK "77ab535a-45fc-624b-5560-f7b281d1f96e"
+#define UUID_VOLATILE_VIRTUAL_CD "3d5abd30-4175-87ce-6d64-d2ade523c4bb"
+#define UUID_PERSISTENT_VIRTUAL_DISK "5cea02c9-4d07-69d3-269f-4496fbe096f9"
+#define UUID_PERSISTENT_VIRTUAL_CD "08018188-42cd-bb48-100f-5387d53ded3d"
+
+/* Miscellaneous */
+
+#define UUID_PLATFORM_CAPABILITIES "0811b06e-4a27-44f9-8d60-3cbbc22e7b48"
+#define UUID_DYNAMIC_ENUMERATION "d8c1a3a6-be9b-4c9b-91bf-c3cb81fc5daf"
+#define UUID_BATTERY_THERMAL_LIMIT "4c2067e3-887d-475c-9720-4af1d3ed602e"
+#define UUID_THERMAL_EXTENSIONS "14d399cd-7a27-4b18-8fb4-7cb7b9f4e500"
+#define UUID_DEVICE_PROPERTIES "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
+
+
+#endif /* __AUUID_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/amlcode.h b/usr/src/boot/sys/contrib/dev/acpica/include/amlcode.h
new file mode 100644
index 0000000000..d56f6d91f1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/amlcode.h
@@ -0,0 +1,512 @@
+/******************************************************************************
+ *
+ * Name: amlcode.h - Definitions for AML, as included in "definition blocks"
+ * Declarations and definitions contained herein are derived
+ * directly from the ACPI specification.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __AMLCODE_H__
+#define __AMLCODE_H__
+
+/* primary opcodes */
+
+#define AML_NULL_CHAR (UINT16) 0x00
+
+#define AML_ZERO_OP (UINT16) 0x00
+#define AML_ONE_OP (UINT16) 0x01
+#define AML_UNASSIGNED (UINT16) 0x02
+#define AML_ALIAS_OP (UINT16) 0x06
+#define AML_NAME_OP (UINT16) 0x08
+#define AML_BYTE_OP (UINT16) 0x0a
+#define AML_WORD_OP (UINT16) 0x0b
+#define AML_DWORD_OP (UINT16) 0x0c
+#define AML_STRING_OP (UINT16) 0x0d
+#define AML_QWORD_OP (UINT16) 0x0e /* ACPI 2.0 */
+#define AML_SCOPE_OP (UINT16) 0x10
+#define AML_BUFFER_OP (UINT16) 0x11
+#define AML_PACKAGE_OP (UINT16) 0x12
+#define AML_VAR_PACKAGE_OP (UINT16) 0x13 /* ACPI 2.0 */
+#define AML_METHOD_OP (UINT16) 0x14
+#define AML_EXTERNAL_OP (UINT16) 0x15 /* ACPI 6.0 */
+#define AML_DUAL_NAME_PREFIX (UINT16) 0x2e
+#define AML_MULTI_NAME_PREFIX_OP (UINT16) 0x2f
+#define AML_NAME_CHAR_SUBSEQ (UINT16) 0x30
+#define AML_NAME_CHAR_FIRST (UINT16) 0x41
+#define AML_EXTENDED_OP_PREFIX (UINT16) 0x5b
+#define AML_ROOT_PREFIX (UINT16) 0x5c
+#define AML_PARENT_PREFIX (UINT16) 0x5e
+#define AML_LOCAL_OP (UINT16) 0x60
+#define AML_LOCAL0 (UINT16) 0x60
+#define AML_LOCAL1 (UINT16) 0x61
+#define AML_LOCAL2 (UINT16) 0x62
+#define AML_LOCAL3 (UINT16) 0x63
+#define AML_LOCAL4 (UINT16) 0x64
+#define AML_LOCAL5 (UINT16) 0x65
+#define AML_LOCAL6 (UINT16) 0x66
+#define AML_LOCAL7 (UINT16) 0x67
+#define AML_ARG_OP (UINT16) 0x68
+#define AML_ARG0 (UINT16) 0x68
+#define AML_ARG1 (UINT16) 0x69
+#define AML_ARG2 (UINT16) 0x6a
+#define AML_ARG3 (UINT16) 0x6b
+#define AML_ARG4 (UINT16) 0x6c
+#define AML_ARG5 (UINT16) 0x6d
+#define AML_ARG6 (UINT16) 0x6e
+#define AML_STORE_OP (UINT16) 0x70
+#define AML_REF_OF_OP (UINT16) 0x71
+#define AML_ADD_OP (UINT16) 0x72
+#define AML_CONCAT_OP (UINT16) 0x73
+#define AML_SUBTRACT_OP (UINT16) 0x74
+#define AML_INCREMENT_OP (UINT16) 0x75
+#define AML_DECREMENT_OP (UINT16) 0x76
+#define AML_MULTIPLY_OP (UINT16) 0x77
+#define AML_DIVIDE_OP (UINT16) 0x78
+#define AML_SHIFT_LEFT_OP (UINT16) 0x79
+#define AML_SHIFT_RIGHT_OP (UINT16) 0x7a
+#define AML_BIT_AND_OP (UINT16) 0x7b
+#define AML_BIT_NAND_OP (UINT16) 0x7c
+#define AML_BIT_OR_OP (UINT16) 0x7d
+#define AML_BIT_NOR_OP (UINT16) 0x7e
+#define AML_BIT_XOR_OP (UINT16) 0x7f
+#define AML_BIT_NOT_OP (UINT16) 0x80
+#define AML_FIND_SET_LEFT_BIT_OP (UINT16) 0x81
+#define AML_FIND_SET_RIGHT_BIT_OP (UINT16) 0x82
+#define AML_DEREF_OF_OP (UINT16) 0x83
+#define AML_CONCAT_RES_OP (UINT16) 0x84 /* ACPI 2.0 */
+#define AML_MOD_OP (UINT16) 0x85 /* ACPI 2.0 */
+#define AML_NOTIFY_OP (UINT16) 0x86
+#define AML_SIZE_OF_OP (UINT16) 0x87
+#define AML_INDEX_OP (UINT16) 0x88
+#define AML_MATCH_OP (UINT16) 0x89
+#define AML_CREATE_DWORD_FIELD_OP (UINT16) 0x8a
+#define AML_CREATE_WORD_FIELD_OP (UINT16) 0x8b
+#define AML_CREATE_BYTE_FIELD_OP (UINT16) 0x8c
+#define AML_CREATE_BIT_FIELD_OP (UINT16) 0x8d
+#define AML_TYPE_OP (UINT16) 0x8e
+#define AML_CREATE_QWORD_FIELD_OP (UINT16) 0x8f /* ACPI 2.0 */
+#define AML_LAND_OP (UINT16) 0x90
+#define AML_LOR_OP (UINT16) 0x91
+#define AML_LNOT_OP (UINT16) 0x92
+#define AML_LEQUAL_OP (UINT16) 0x93
+#define AML_LGREATER_OP (UINT16) 0x94
+#define AML_LLESS_OP (UINT16) 0x95
+#define AML_TO_BUFFER_OP (UINT16) 0x96 /* ACPI 2.0 */
+#define AML_TO_DECSTRING_OP (UINT16) 0x97 /* ACPI 2.0 */
+#define AML_TO_HEXSTRING_OP (UINT16) 0x98 /* ACPI 2.0 */
+#define AML_TO_INTEGER_OP (UINT16) 0x99 /* ACPI 2.0 */
+#define AML_TO_STRING_OP (UINT16) 0x9c /* ACPI 2.0 */
+#define AML_COPY_OP (UINT16) 0x9d /* ACPI 2.0 */
+#define AML_MID_OP (UINT16) 0x9e /* ACPI 2.0 */
+#define AML_CONTINUE_OP (UINT16) 0x9f /* ACPI 2.0 */
+#define AML_IF_OP (UINT16) 0xa0
+#define AML_ELSE_OP (UINT16) 0xa1
+#define AML_WHILE_OP (UINT16) 0xa2
+#define AML_NOOP_OP (UINT16) 0xa3
+#define AML_RETURN_OP (UINT16) 0xa4
+#define AML_BREAK_OP (UINT16) 0xa5
+#define AML_BREAK_POINT_OP (UINT16) 0xcc
+#define AML_ONES_OP (UINT16) 0xff
+
+/* prefixed opcodes */
+
+#define AML_EXTENDED_OPCODE (UINT16) 0x5b00 /* prefix for 2-byte opcodes */
+
+#define AML_MUTEX_OP (UINT16) 0x5b01
+#define AML_EVENT_OP (UINT16) 0x5b02
+#define AML_SHIFT_RIGHT_BIT_OP (UINT16) 0x5b10
+#define AML_SHIFT_LEFT_BIT_OP (UINT16) 0x5b11
+#define AML_COND_REF_OF_OP (UINT16) 0x5b12
+#define AML_CREATE_FIELD_OP (UINT16) 0x5b13
+#define AML_LOAD_TABLE_OP (UINT16) 0x5b1f /* ACPI 2.0 */
+#define AML_LOAD_OP (UINT16) 0x5b20
+#define AML_STALL_OP (UINT16) 0x5b21
+#define AML_SLEEP_OP (UINT16) 0x5b22
+#define AML_ACQUIRE_OP (UINT16) 0x5b23
+#define AML_SIGNAL_OP (UINT16) 0x5b24
+#define AML_WAIT_OP (UINT16) 0x5b25
+#define AML_RESET_OP (UINT16) 0x5b26
+#define AML_RELEASE_OP (UINT16) 0x5b27
+#define AML_FROM_BCD_OP (UINT16) 0x5b28
+#define AML_TO_BCD_OP (UINT16) 0x5b29
+#define AML_UNLOAD_OP (UINT16) 0x5b2a
+#define AML_REVISION_OP (UINT16) 0x5b30
+#define AML_DEBUG_OP (UINT16) 0x5b31
+#define AML_FATAL_OP (UINT16) 0x5b32
+#define AML_TIMER_OP (UINT16) 0x5b33 /* ACPI 3.0 */
+#define AML_REGION_OP (UINT16) 0x5b80
+#define AML_FIELD_OP (UINT16) 0x5b81
+#define AML_DEVICE_OP (UINT16) 0x5b82
+#define AML_PROCESSOR_OP (UINT16) 0x5b83
+#define AML_POWER_RES_OP (UINT16) 0x5b84
+#define AML_THERMAL_ZONE_OP (UINT16) 0x5b85
+#define AML_INDEX_FIELD_OP (UINT16) 0x5b86
+#define AML_BANK_FIELD_OP (UINT16) 0x5b87
+#define AML_DATA_REGION_OP (UINT16) 0x5b88 /* ACPI 2.0 */
+
+
+/*
+ * Combination opcodes (actually two one-byte opcodes)
+ * Used by the disassembler and iASL compiler
+ */
+#define AML_LGREATEREQUAL_OP (UINT16) 0x9295
+#define AML_LLESSEQUAL_OP (UINT16) 0x9294
+#define AML_LNOTEQUAL_OP (UINT16) 0x9293
+
+
+/*
+ * Opcodes for "Field" operators
+ */
+#define AML_FIELD_OFFSET_OP (UINT8) 0x00
+#define AML_FIELD_ACCESS_OP (UINT8) 0x01
+#define AML_FIELD_CONNECTION_OP (UINT8) 0x02 /* ACPI 5.0 */
+#define AML_FIELD_EXT_ACCESS_OP (UINT8) 0x03 /* ACPI 5.0 */
+
+
+/*
+ * Internal opcodes
+ * Use only "Unknown" AML opcodes, don't attempt to use
+ * any valid ACPI ASCII values (A-Z, 0-9, '-')
+ */
+#define AML_INT_NAMEPATH_OP (UINT16) 0x002d
+#define AML_INT_NAMEDFIELD_OP (UINT16) 0x0030
+#define AML_INT_RESERVEDFIELD_OP (UINT16) 0x0031
+#define AML_INT_ACCESSFIELD_OP (UINT16) 0x0032
+#define AML_INT_BYTELIST_OP (UINT16) 0x0033
+#define AML_INT_METHODCALL_OP (UINT16) 0x0035
+#define AML_INT_RETURN_VALUE_OP (UINT16) 0x0036
+#define AML_INT_EVAL_SUBTREE_OP (UINT16) 0x0037
+#define AML_INT_CONNECTION_OP (UINT16) 0x0038
+#define AML_INT_EXTACCESSFIELD_OP (UINT16) 0x0039
+
+#define ARG_NONE 0x0
+
+/*
+ * Argument types for the AML Parser
+ * Each field in the ArgTypes UINT32 is 5 bits, allowing for a maximum of 6 arguments.
+ * There can be up to 31 unique argument types
+ * Zero is reserved as end-of-list indicator
+ */
+#define ARGP_BYTEDATA 0x01
+#define ARGP_BYTELIST 0x02
+#define ARGP_CHARLIST 0x03
+#define ARGP_DATAOBJ 0x04
+#define ARGP_DATAOBJLIST 0x05
+#define ARGP_DWORDDATA 0x06
+#define ARGP_FIELDLIST 0x07
+#define ARGP_NAME 0x08
+#define ARGP_NAMESTRING 0x09
+#define ARGP_OBJLIST 0x0A
+#define ARGP_PKGLENGTH 0x0B
+#define ARGP_SUPERNAME 0x0C
+#define ARGP_TARGET 0x0D
+#define ARGP_TERMARG 0x0E
+#define ARGP_TERMLIST 0x0F
+#define ARGP_WORDDATA 0x10
+#define ARGP_QWORDDATA 0x11
+#define ARGP_SIMPLENAME 0x12
+
+/*
+ * Resolved argument types for the AML Interpreter
+ * Each field in the ArgTypes UINT32 is 5 bits, allowing for a maximum of 6 arguments.
+ * There can be up to 31 unique argument types (0 is end-of-arg-list indicator)
+ *
+ * Note1: These values are completely independent from the ACPI_TYPEs
+ * i.e., ARGI_INTEGER != ACPI_TYPE_INTEGER
+ *
+ * Note2: If and when 5 bits becomes insufficient, it would probably be best
+ * to convert to a 6-byte array of argument types, allowing 8 bits per argument.
+ */
+
+/* Single, simple types */
+
+#define ARGI_ANYTYPE 0x01 /* Don't care */
+#define ARGI_PACKAGE 0x02
+#define ARGI_EVENT 0x03
+#define ARGI_MUTEX 0x04
+#define ARGI_DDBHANDLE 0x05
+
+/* Interchangeable types (via implicit conversion) */
+
+#define ARGI_INTEGER 0x06
+#define ARGI_STRING 0x07
+#define ARGI_BUFFER 0x08
+#define ARGI_BUFFER_OR_STRING 0x09 /* Used by MID op only */
+#define ARGI_COMPUTEDATA 0x0A /* Buffer, String, or Integer */
+
+/* Reference objects */
+
+#define ARGI_INTEGER_REF 0x0B
+#define ARGI_OBJECT_REF 0x0C
+#define ARGI_DEVICE_REF 0x0D
+#define ARGI_REFERENCE 0x0E
+#define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */
+#define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */
+#define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */
+
+/* Multiple/complex types */
+
+#define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a Node - Used only by SizeOf operator*/
+#define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */
+#define ARGI_REGION_OR_BUFFER 0x15 /* Used by LOAD op only */
+#define ARGI_DATAREFOBJ 0x16
+
+/* Note: types above can expand to 0x1F maximum */
+
+#define ARGI_INVALID_OPCODE 0xFFFFFFFF
+
+
+/*
+ * hash offsets
+ */
+#define AML_EXTOP_HASH_OFFSET 22
+#define AML_LNOT_HASH_OFFSET 19
+
+
+/*
+ * opcode groups and types
+ */
+#define OPGRP_NAMED 0x01
+#define OPGRP_FIELD 0x02
+#define OPGRP_BYTELIST 0x04
+
+
+/*
+ * Opcode information
+ */
+
+/* Opcode flags */
+
+#define AML_LOGICAL 0x0001
+#define AML_LOGICAL_NUMERIC 0x0002
+#define AML_MATH 0x0004
+#define AML_CREATE 0x0008
+#define AML_FIELD 0x0010
+#define AML_DEFER 0x0020
+#define AML_NAMED 0x0040
+#define AML_NSNODE 0x0080
+#define AML_NSOPCODE 0x0100
+#define AML_NSOBJECT 0x0200
+#define AML_HAS_RETVAL 0x0400
+#define AML_HAS_TARGET 0x0800
+#define AML_HAS_ARGS 0x1000
+#define AML_CONSTANT 0x2000
+#define AML_NO_OPERAND_RESOLVE 0x4000
+
+/* Convenient flag groupings */
+
+#define AML_FLAGS_EXEC_0A_0T_1R AML_HAS_RETVAL
+#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */
+#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */
+#define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET
+#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* Monadic2R */
+#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */
+#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */
+#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* Dyadic2R */
+#define AML_FLAGS_EXEC_2A_2T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
+#define AML_FLAGS_EXEC_3A_0T_0R AML_HAS_ARGS
+#define AML_FLAGS_EXEC_3A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
+#define AML_FLAGS_EXEC_6A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL
+
+
+/*
+ * The opcode Type is used in a dispatch table, do not change
+ * without updating the table.
+ */
+#define AML_TYPE_EXEC_0A_0T_1R 0x00
+#define AML_TYPE_EXEC_1A_0T_0R 0x01 /* Monadic1 */
+#define AML_TYPE_EXEC_1A_0T_1R 0x02 /* Monadic2 */
+#define AML_TYPE_EXEC_1A_1T_0R 0x03
+#define AML_TYPE_EXEC_1A_1T_1R 0x04 /* Monadic2R */
+#define AML_TYPE_EXEC_2A_0T_0R 0x05 /* Dyadic1 */
+#define AML_TYPE_EXEC_2A_0T_1R 0x06 /* Dyadic2 */
+#define AML_TYPE_EXEC_2A_1T_1R 0x07 /* Dyadic2R */
+#define AML_TYPE_EXEC_2A_2T_1R 0x08
+#define AML_TYPE_EXEC_3A_0T_0R 0x09
+#define AML_TYPE_EXEC_3A_1T_1R 0x0A
+#define AML_TYPE_EXEC_6A_0T_1R 0x0B
+/* End of types used in dispatch table */
+
+#define AML_TYPE_LITERAL 0x0B
+#define AML_TYPE_CONSTANT 0x0C
+#define AML_TYPE_METHOD_ARGUMENT 0x0D
+#define AML_TYPE_LOCAL_VARIABLE 0x0E
+#define AML_TYPE_DATA_TERM 0x0F
+
+/* Generic for an op that returns a value */
+
+#define AML_TYPE_METHOD_CALL 0x10
+
+/* Misc */
+
+#define AML_TYPE_CREATE_FIELD 0x11
+#define AML_TYPE_CREATE_OBJECT 0x12
+#define AML_TYPE_CONTROL 0x13
+#define AML_TYPE_NAMED_NO_OBJ 0x14
+#define AML_TYPE_NAMED_FIELD 0x15
+#define AML_TYPE_NAMED_SIMPLE 0x16
+#define AML_TYPE_NAMED_COMPLEX 0x17
+#define AML_TYPE_RETURN 0x18
+
+#define AML_TYPE_UNDEFINED 0x19
+#define AML_TYPE_BOGUS 0x1A
+
+/* AML Package Length encodings */
+
+#define ACPI_AML_PACKAGE_TYPE1 0x40
+#define ACPI_AML_PACKAGE_TYPE2 0x4000
+#define ACPI_AML_PACKAGE_TYPE3 0x400000
+#define ACPI_AML_PACKAGE_TYPE4 0x40000000
+
+/*
+ * Opcode classes
+ */
+#define AML_CLASS_EXECUTE 0x00
+#define AML_CLASS_CREATE 0x01
+#define AML_CLASS_ARGUMENT 0x02
+#define AML_CLASS_NAMED_OBJECT 0x03
+#define AML_CLASS_CONTROL 0x04
+#define AML_CLASS_ASCII 0x05
+#define AML_CLASS_PREFIX 0x06
+#define AML_CLASS_INTERNAL 0x07
+#define AML_CLASS_RETURN_VALUE 0x08
+#define AML_CLASS_METHOD_CALL 0x09
+#define AML_CLASS_UNKNOWN 0x0A
+
+
+/* Comparison operation codes for MatchOp operator */
+
+typedef enum
+{
+ MATCH_MTR = 0,
+ MATCH_MEQ = 1,
+ MATCH_MLE = 2,
+ MATCH_MLT = 3,
+ MATCH_MGE = 4,
+ MATCH_MGT = 5
+
+} AML_MATCH_OPERATOR;
+
+#define MAX_MATCH_OPERATOR 5
+
+
+/*
+ * FieldFlags
+ *
+ * This byte is extracted from the AML and includes three separate
+ * pieces of information about the field:
+ * 1) The field access type
+ * 2) The field update rule
+ * 3) The lock rule for the field
+ *
+ * Bits 00 - 03 : AccessType (AnyAcc, ByteAcc, etc.)
+ * 04 : LockRule (1 == Lock)
+ * 05 - 06 : UpdateRule
+ */
+#define AML_FIELD_ACCESS_TYPE_MASK 0x0F
+#define AML_FIELD_LOCK_RULE_MASK 0x10
+#define AML_FIELD_UPDATE_RULE_MASK 0x60
+
+
+/* 1) Field Access Types */
+
+typedef enum
+{
+ AML_FIELD_ACCESS_ANY = 0x00,
+ AML_FIELD_ACCESS_BYTE = 0x01,
+ AML_FIELD_ACCESS_WORD = 0x02,
+ AML_FIELD_ACCESS_DWORD = 0x03,
+ AML_FIELD_ACCESS_QWORD = 0x04, /* ACPI 2.0 */
+ AML_FIELD_ACCESS_BUFFER = 0x05 /* ACPI 2.0 */
+
+} AML_ACCESS_TYPE;
+
+
+/* 2) Field Lock Rules */
+
+typedef enum
+{
+ AML_FIELD_LOCK_NEVER = 0x00,
+ AML_FIELD_LOCK_ALWAYS = 0x10
+
+} AML_LOCK_RULE;
+
+
+/* 3) Field Update Rules */
+
+typedef enum
+{
+ AML_FIELD_UPDATE_PRESERVE = 0x00,
+ AML_FIELD_UPDATE_WRITE_AS_ONES = 0x20,
+ AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40
+
+} AML_UPDATE_RULE;
+
+
+/*
+ * Field Access Attributes.
+ * This byte is extracted from the AML via the
+ * AccessAs keyword
+ */
+typedef enum
+{
+ AML_FIELD_ATTRIB_QUICK = 0x02,
+ AML_FIELD_ATTRIB_SEND_RCV = 0x04,
+ AML_FIELD_ATTRIB_BYTE = 0x06,
+ AML_FIELD_ATTRIB_WORD = 0x08,
+ AML_FIELD_ATTRIB_BLOCK = 0x0A,
+ AML_FIELD_ATTRIB_MULTIBYTE = 0x0B,
+ AML_FIELD_ATTRIB_WORD_CALL = 0x0C,
+ AML_FIELD_ATTRIB_BLOCK_CALL = 0x0D,
+ AML_FIELD_ATTRIB_RAW_BYTES = 0x0E,
+ AML_FIELD_ATTRIB_RAW_PROCESS = 0x0F
+
+} AML_ACCESS_ATTRIBUTE;
+
+
+/* Bit fields in the AML MethodFlags byte */
+
+#define AML_METHOD_ARG_COUNT 0x07
+#define AML_METHOD_SERIALIZED 0x08
+#define AML_METHOD_SYNC_LEVEL 0xF0
+
+
+#endif /* __AMLCODE_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/amlresrc.h b/usr/src/boot/sys/contrib/dev/acpica/include/amlresrc.h
new file mode 100644
index 0000000000..b38028e60a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/amlresrc.h
@@ -0,0 +1,631 @@
+/******************************************************************************
+ *
+ * Module Name: amlresrc.h - AML resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+#ifndef __AMLRESRC_H
+#define __AMLRESRC_H
+
+
+/*
+ * Resource descriptor tags, as defined in the ACPI specification.
+ * Used to symbolically reference fields within a descriptor.
+ */
+#define ACPI_RESTAG_ADDRESS "_ADR"
+#define ACPI_RESTAG_ALIGNMENT "_ALN"
+#define ACPI_RESTAG_ADDRESSSPACE "_ASI"
+#define ACPI_RESTAG_ACCESSSIZE "_ASZ"
+#define ACPI_RESTAG_TYPESPECIFICATTRIBUTES "_ATT"
+#define ACPI_RESTAG_BASEADDRESS "_BAS"
+#define ACPI_RESTAG_BUSMASTER "_BM_" /* Master(1), Slave(0) */
+#define ACPI_RESTAG_DEBOUNCETIME "_DBT"
+#define ACPI_RESTAG_DECODE "_DEC"
+#define ACPI_RESTAG_DEVICEPOLARITY "_DPL"
+#define ACPI_RESTAG_DMA "_DMA"
+#define ACPI_RESTAG_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */
+#define ACPI_RESTAG_DRIVESTRENGTH "_DRS"
+#define ACPI_RESTAG_ENDIANNESS "_END"
+#define ACPI_RESTAG_FLOWCONTROL "_FLC"
+#define ACPI_RESTAG_GRANULARITY "_GRA"
+#define ACPI_RESTAG_INTERRUPT "_INT"
+#define ACPI_RESTAG_INTERRUPTLEVEL "_LL_" /* ActiveLo(1), ActiveHi(0) */
+#define ACPI_RESTAG_INTERRUPTSHARE "_SHR" /* Shareable(1), NoShare(0) */
+#define ACPI_RESTAG_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */
+#define ACPI_RESTAG_IORESTRICTION "_IOR"
+#define ACPI_RESTAG_LENGTH "_LEN"
+#define ACPI_RESTAG_LINE "_LIN"
+#define ACPI_RESTAG_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
+#define ACPI_RESTAG_MEMTYPE "_MEM" /* NonCache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
+#define ACPI_RESTAG_MAXADDR "_MAX"
+#define ACPI_RESTAG_MINADDR "_MIN"
+#define ACPI_RESTAG_MAXTYPE "_MAF"
+#define ACPI_RESTAG_MINTYPE "_MIF"
+#define ACPI_RESTAG_MODE "_MOD"
+#define ACPI_RESTAG_PARITY "_PAR"
+#define ACPI_RESTAG_PHASE "_PHA"
+#define ACPI_RESTAG_PIN "_PIN"
+#define ACPI_RESTAG_PINCONFIG "_PPI"
+#define ACPI_RESTAG_POLARITY "_POL"
+#define ACPI_RESTAG_REGISTERBITOFFSET "_RBO"
+#define ACPI_RESTAG_REGISTERBITWIDTH "_RBW"
+#define ACPI_RESTAG_RANGETYPE "_RNG"
+#define ACPI_RESTAG_READWRITETYPE "_RW_" /* ReadOnly(0), Writeable (1) */
+#define ACPI_RESTAG_LENGTH_RX "_RXL"
+#define ACPI_RESTAG_LENGTH_TX "_TXL"
+#define ACPI_RESTAG_SLAVEMODE "_SLV"
+#define ACPI_RESTAG_SPEED "_SPE"
+#define ACPI_RESTAG_STOPBITS "_STB"
+#define ACPI_RESTAG_TRANSLATION "_TRA"
+#define ACPI_RESTAG_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */
+#define ACPI_RESTAG_TYPE "_TTP" /* Translation(1), Static (0) */
+#define ACPI_RESTAG_XFERTYPE "_SIZ" /* 8(0), 8And16(1), 16(2) */
+#define ACPI_RESTAG_VENDORDATA "_VEN"
+
+
+/* Default sizes for "small" resource descriptors */
+
+#define ASL_RDESC_IRQ_SIZE 0x02
+#define ASL_RDESC_DMA_SIZE 0x02
+#define ASL_RDESC_ST_DEPEND_SIZE 0x00
+#define ASL_RDESC_END_DEPEND_SIZE 0x00
+#define ASL_RDESC_IO_SIZE 0x07
+#define ASL_RDESC_FIXED_IO_SIZE 0x03
+#define ASL_RDESC_FIXED_DMA_SIZE 0x05
+#define ASL_RDESC_END_TAG_SIZE 0x01
+
+
+typedef struct asl_resource_node
+{
+ UINT32 BufferLength;
+ void *Buffer;
+ struct asl_resource_node *Next;
+
+} ASL_RESOURCE_NODE;
+
+typedef struct asl_resource_info
+{
+ ACPI_PARSE_OBJECT *DescriptorTypeOp; /* Resource descriptor parse node */
+ ACPI_PARSE_OBJECT *MappingOp; /* Used for mapfile support */
+ UINT32 CurrentByteOffset; /* Offset in resource template */
+
+} ASL_RESOURCE_INFO;
+
+
+/* Macros used to generate AML resource length fields */
+
+#define ACPI_AML_SIZE_LARGE(r) (sizeof (r) - sizeof (AML_RESOURCE_LARGE_HEADER))
+#define ACPI_AML_SIZE_SMALL(r) (sizeof (r) - sizeof (AML_RESOURCE_SMALL_HEADER))
+
+/*
+ * Resource descriptors defined in the ACPI specification.
+ *
+ * Packing/alignment must be BYTE because these descriptors
+ * are used to overlay the raw AML byte stream.
+ */
+#pragma pack(1)
+
+/*
+ * SMALL descriptors
+ */
+#define AML_RESOURCE_SMALL_HEADER_COMMON \
+ UINT8 DescriptorType;
+
+typedef struct aml_resource_small_header
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_SMALL_HEADER;
+
+
+typedef struct aml_resource_irq
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT16 IrqMask;
+ UINT8 Flags;
+
+} AML_RESOURCE_IRQ;
+
+
+typedef struct aml_resource_irq_noflags
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT16 IrqMask;
+
+} AML_RESOURCE_IRQ_NOFLAGS;
+
+
+typedef struct aml_resource_dma
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT8 DmaChannelMask;
+ UINT8 Flags;
+
+} AML_RESOURCE_DMA;
+
+
+typedef struct aml_resource_start_dependent
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT8 Flags;
+
+} AML_RESOURCE_START_DEPENDENT;
+
+
+typedef struct aml_resource_start_dependent_noprio
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_START_DEPENDENT_NOPRIO;
+
+
+typedef struct aml_resource_end_dependent
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_END_DEPENDENT;
+
+
+typedef struct aml_resource_io
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT8 Flags;
+ UINT16 Minimum;
+ UINT16 Maximum;
+ UINT8 Alignment;
+ UINT8 AddressLength;
+
+} AML_RESOURCE_IO;
+
+
+typedef struct aml_resource_fixed_io
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT16 Address;
+ UINT8 AddressLength;
+
+} AML_RESOURCE_FIXED_IO;
+
+
+typedef struct aml_resource_vendor_small
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_VENDOR_SMALL;
+
+
+typedef struct aml_resource_end_tag
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT8 Checksum;
+
+} AML_RESOURCE_END_TAG;
+
+
+typedef struct aml_resource_fixed_dma
+{
+ AML_RESOURCE_SMALL_HEADER_COMMON
+ UINT16 RequestLines;
+ UINT16 Channels;
+ UINT8 Width;
+
+} AML_RESOURCE_FIXED_DMA;
+
+
+/*
+ * LARGE descriptors
+ */
+#define AML_RESOURCE_LARGE_HEADER_COMMON \
+ UINT8 DescriptorType;\
+ UINT16 ResourceLength;
+
+typedef struct aml_resource_large_header
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+
+} AML_RESOURCE_LARGE_HEADER;
+
+
+/* General Flags for address space resource descriptors */
+
+#define ACPI_RESOURCE_FLAG_DEC 2
+#define ACPI_RESOURCE_FLAG_MIF 4
+#define ACPI_RESOURCE_FLAG_MAF 8
+
+typedef struct aml_resource_memory24
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 Flags;
+ UINT16 Minimum;
+ UINT16 Maximum;
+ UINT16 Alignment;
+ UINT16 AddressLength;
+
+} AML_RESOURCE_MEMORY24;
+
+
+typedef struct aml_resource_vendor_large
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+
+} AML_RESOURCE_VENDOR_LARGE;
+
+
+typedef struct aml_resource_memory32
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 Flags;
+ UINT32 Minimum;
+ UINT32 Maximum;
+ UINT32 Alignment;
+ UINT32 AddressLength;
+
+} AML_RESOURCE_MEMORY32;
+
+
+typedef struct aml_resource_fixed_memory32
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 Flags;
+ UINT32 Address;
+ UINT32 AddressLength;
+
+} AML_RESOURCE_FIXED_MEMORY32;
+
+
+#define AML_RESOURCE_ADDRESS_COMMON \
+ UINT8 ResourceType; \
+ UINT8 Flags; \
+ UINT8 SpecificFlags;
+
+
+typedef struct aml_resource_address
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_ADDRESS_COMMON
+
+} AML_RESOURCE_ADDRESS;
+
+
+typedef struct aml_resource_extended_address64
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_ADDRESS_COMMON
+ UINT8 RevisionID;
+ UINT8 Reserved;
+ UINT64 Granularity;
+ UINT64 Minimum;
+ UINT64 Maximum;
+ UINT64 TranslationOffset;
+ UINT64 AddressLength;
+ UINT64 TypeSpecific;
+
+} AML_RESOURCE_EXTENDED_ADDRESS64;
+
+#define AML_RESOURCE_EXTENDED_ADDRESS_REVISION 1 /* ACPI 3.0 */
+
+
+typedef struct aml_resource_address64
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_ADDRESS_COMMON
+ UINT64 Granularity;
+ UINT64 Minimum;
+ UINT64 Maximum;
+ UINT64 TranslationOffset;
+ UINT64 AddressLength;
+
+} AML_RESOURCE_ADDRESS64;
+
+
+typedef struct aml_resource_address32
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_ADDRESS_COMMON
+ UINT32 Granularity;
+ UINT32 Minimum;
+ UINT32 Maximum;
+ UINT32 TranslationOffset;
+ UINT32 AddressLength;
+
+} AML_RESOURCE_ADDRESS32;
+
+
+typedef struct aml_resource_address16
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_ADDRESS_COMMON
+ UINT16 Granularity;
+ UINT16 Minimum;
+ UINT16 Maximum;
+ UINT16 TranslationOffset;
+ UINT16 AddressLength;
+
+} AML_RESOURCE_ADDRESS16;
+
+
+typedef struct aml_resource_extended_irq
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 Flags;
+ UINT8 InterruptCount;
+ UINT32 Interrupts[1];
+ /* ResSourceIndex, ResSource optional fields follow */
+
+} AML_RESOURCE_EXTENDED_IRQ;
+
+
+typedef struct aml_resource_generic_register
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 AddressSpaceId;
+ UINT8 BitWidth;
+ UINT8 BitOffset;
+ UINT8 AccessSize; /* ACPI 3.0, was previously Reserved */
+ UINT64 Address;
+
+} AML_RESOURCE_GENERIC_REGISTER;
+
+
+/* Common descriptor for GpioInt and GpioIo (ACPI 5.0) */
+
+typedef struct aml_resource_gpio
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ UINT8 RevisionId;
+ UINT8 ConnectionType;
+ UINT16 Flags;
+ UINT16 IntFlags;
+ UINT8 PinConfig;
+ UINT16 DriveStrength;
+ UINT16 DebounceTimeout;
+ UINT16 PinTableOffset;
+ UINT8 ResSourceIndex;
+ UINT16 ResSourceOffset;
+ UINT16 VendorOffset;
+ UINT16 VendorLength;
+ /*
+ * Optional fields follow immediately:
+ * 1) PIN list (Words)
+ * 2) Resource Source String
+ * 3) Vendor Data bytes
+ */
+
+} AML_RESOURCE_GPIO;
+
+#define AML_RESOURCE_GPIO_REVISION 1 /* ACPI 5.0 */
+
+/* Values for ConnectionType above */
+
+#define AML_RESOURCE_GPIO_TYPE_INT 0
+#define AML_RESOURCE_GPIO_TYPE_IO 1
+#define AML_RESOURCE_MAX_GPIOTYPE 1
+
+
+/* Common preamble for all serial descriptors (ACPI 5.0) */
+
+#define AML_RESOURCE_SERIAL_COMMON \
+ UINT8 RevisionId; \
+ UINT8 ResSourceIndex; \
+ UINT8 Type; \
+ UINT8 Flags; \
+ UINT16 TypeSpecificFlags; \
+ UINT8 TypeRevisionId; \
+ UINT16 TypeDataLength; \
+
+/* Values for the type field above */
+
+#define AML_RESOURCE_I2C_SERIALBUSTYPE 1
+#define AML_RESOURCE_SPI_SERIALBUSTYPE 2
+#define AML_RESOURCE_UART_SERIALBUSTYPE 3
+#define AML_RESOURCE_MAX_SERIALBUSTYPE 3
+#define AML_RESOURCE_VENDOR_SERIALBUSTYPE 192 /* Vendor defined is 0xC0-0xFF (NOT SUPPORTED) */
+
+typedef struct aml_resource_common_serialbus
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_SERIAL_COMMON
+
+} AML_RESOURCE_COMMON_SERIALBUS;
+
+typedef struct aml_resource_i2c_serialbus
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_SERIAL_COMMON
+ UINT32 ConnectionSpeed;
+ UINT16 SlaveAddress;
+ /*
+ * Optional fields follow immediately:
+ * 1) Vendor Data bytes
+ * 2) Resource Source String
+ */
+
+} AML_RESOURCE_I2C_SERIALBUS;
+
+#define AML_RESOURCE_I2C_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_I2C_TYPE_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_I2C_MIN_DATA_LEN 6
+
+typedef struct aml_resource_spi_serialbus
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_SERIAL_COMMON
+ UINT32 ConnectionSpeed;
+ UINT8 DataBitLength;
+ UINT8 ClockPhase;
+ UINT8 ClockPolarity;
+ UINT16 DeviceSelection;
+ /*
+ * Optional fields follow immediately:
+ * 1) Vendor Data bytes
+ * 2) Resource Source String
+ */
+
+} AML_RESOURCE_SPI_SERIALBUS;
+
+#define AML_RESOURCE_SPI_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_SPI_TYPE_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_SPI_MIN_DATA_LEN 9
+
+
+typedef struct aml_resource_uart_serialbus
+{
+ AML_RESOURCE_LARGE_HEADER_COMMON
+ AML_RESOURCE_SERIAL_COMMON
+ UINT32 DefaultBaudRate;
+ UINT16 RxFifoSize;
+ UINT16 TxFifoSize;
+ UINT8 Parity;
+ UINT8 LinesEnabled;
+ /*
+ * Optional fields follow immediately:
+ * 1) Vendor Data bytes
+ * 2) Resource Source String
+ */
+
+} AML_RESOURCE_UART_SERIALBUS;
+
+#define AML_RESOURCE_UART_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_UART_TYPE_REVISION 1 /* ACPI 5.0 */
+#define AML_RESOURCE_UART_MIN_DATA_LEN 10
+
+
+/* restore default alignment */
+
+#pragma pack()
+
+/* Union of all resource descriptors, so we can allocate the worst case */
+
+typedef union aml_resource
+{
+ /* Descriptor headers */
+
+ UINT8 DescriptorType;
+ AML_RESOURCE_SMALL_HEADER SmallHeader;
+ AML_RESOURCE_LARGE_HEADER LargeHeader;
+
+ /* Small resource descriptors */
+
+ AML_RESOURCE_IRQ Irq;
+ AML_RESOURCE_DMA Dma;
+ AML_RESOURCE_START_DEPENDENT StartDpf;
+ AML_RESOURCE_END_DEPENDENT EndDpf;
+ AML_RESOURCE_IO Io;
+ AML_RESOURCE_FIXED_IO FixedIo;
+ AML_RESOURCE_FIXED_DMA FixedDma;
+ AML_RESOURCE_VENDOR_SMALL VendorSmall;
+ AML_RESOURCE_END_TAG EndTag;
+
+ /* Large resource descriptors */
+
+ AML_RESOURCE_MEMORY24 Memory24;
+ AML_RESOURCE_GENERIC_REGISTER GenericReg;
+ AML_RESOURCE_VENDOR_LARGE VendorLarge;
+ AML_RESOURCE_MEMORY32 Memory32;
+ AML_RESOURCE_FIXED_MEMORY32 FixedMemory32;
+ AML_RESOURCE_ADDRESS16 Address16;
+ AML_RESOURCE_ADDRESS32 Address32;
+ AML_RESOURCE_ADDRESS64 Address64;
+ AML_RESOURCE_EXTENDED_ADDRESS64 ExtAddress64;
+ AML_RESOURCE_EXTENDED_IRQ ExtendedIrq;
+ AML_RESOURCE_GPIO Gpio;
+ AML_RESOURCE_I2C_SERIALBUS I2cSerialBus;
+ AML_RESOURCE_SPI_SERIALBUS SpiSerialBus;
+ AML_RESOURCE_UART_SERIALBUS UartSerialBus;
+ AML_RESOURCE_COMMON_SERIALBUS CommonSerialBus;
+
+ /* Utility overlays */
+
+ AML_RESOURCE_ADDRESS Address;
+ UINT32 DwordItem;
+ UINT16 WordItem;
+ UINT8 ByteItem;
+
+} AML_RESOURCE;
+
+
+/* Interfaces used by both the disassembler and compiler */
+
+void
+MpSaveGpioInfo (
+ ACPI_PARSE_OBJECT *Op,
+ AML_RESOURCE *Resource,
+ UINT32 PinCount,
+ UINT16 *PinList,
+ char *DeviceName);
+
+void
+MpSaveSerialInfo (
+ ACPI_PARSE_OBJECT *Op,
+ AML_RESOURCE *Resource,
+ char *DeviceName);
+
+char *
+MpGetHidFromParseTree (
+ ACPI_NAMESPACE_NODE *HidNode);
+
+char *
+MpGetHidViaNamestring (
+ char *DeviceName);
+
+char *
+MpGetConnectionInfo (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 PinIndex,
+ ACPI_NAMESPACE_NODE **TargetNode,
+ char **TargetName);
+
+char *
+MpGetParentDeviceHid (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE **TargetNode,
+ char **ParentDeviceName);
+
+char *
+MpGetDdnValue (
+ char *DeviceName);
+
+char *
+MpGetHidValue (
+ ACPI_NAMESPACE_NODE *DeviceNode);
+
+#endif
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenv.h b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenv.h
new file mode 100644
index 0000000000..b5a12e5e87
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenv.h
@@ -0,0 +1,405 @@
+/******************************************************************************
+ *
+ * Name: acenv.h - Host and compiler configuration
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACENV_H__
+#define __ACENV_H__
+
+/*
+ * Environment configuration. The purpose of this file is to interface ACPICA
+ * to the local environment. This includes compiler-specific, OS-specific,
+ * and machine-specific configuration.
+ */
+
+/* Types for ACPI_MUTEX_TYPE */
+
+#define ACPI_BINARY_SEMAPHORE 0
+#define ACPI_OSL_MUTEX 1
+
+/* Types for DEBUGGER_THREADING */
+
+#define DEBUGGER_SINGLE_THREADED 0
+#define DEBUGGER_MULTI_THREADED 1
+
+
+/******************************************************************************
+ *
+ * Configuration for ACPI tools and utilities
+ *
+ *****************************************************************************/
+
+/* iASL configuration */
+
+#ifdef ACPI_ASL_COMPILER
+#define ACPI_APPLICATION
+#define ACPI_DEBUG_OUTPUT
+#define ACPI_CONSTANT_EVAL_ONLY
+#define ACPI_LARGE_NAMESPACE_NODE
+#define ACPI_DATA_TABLE_DISASSEMBLY
+#define ACPI_SINGLE_THREADED
+#define ACPI_32BIT_PHYSICAL_ADDRESS
+
+#define ACPI_DISASSEMBLER 1
+#endif
+
+/* AcpiExec configuration. Multithreaded with full AML debugger */
+
+#ifdef ACPI_EXEC_APP
+#define ACPI_APPLICATION
+#define ACPI_FULL_DEBUG
+#define ACPI_MUTEX_DEBUG
+#define ACPI_DBG_TRACK_ALLOCATIONS
+#endif
+
+/*
+ * AcpiBin/AcpiDump/AcpiHelp/AcpiNames/AcpiSrc/AcpiXtract/Example
+ * configuration. All single threaded.
+ */
+#if (defined ACPI_BIN_APP) || \
+ (defined ACPI_DUMP_APP) || \
+ (defined ACPI_HELP_APP) || \
+ (defined ACPI_NAMES_APP) || \
+ (defined ACPI_SRC_APP) || \
+ (defined ACPI_XTRACT_APP) || \
+ (defined ACPI_EXAMPLE_APP)
+#define ACPI_APPLICATION
+#define ACPI_SINGLE_THREADED
+#endif
+
+/* AcpiHelp configuration. Error messages disabled. */
+
+#ifdef ACPI_HELP_APP
+#define ACPI_NO_ERROR_MESSAGES
+#endif
+
+/* AcpiNames configuration. Debug output enabled. */
+
+#ifdef ACPI_NAMES_APP
+#define ACPI_DEBUG_OUTPUT
+#endif
+
+/* AcpiExec/AcpiNames/Example configuration. Native RSDP used. */
+
+#if (defined ACPI_EXEC_APP) || \
+ (defined ACPI_EXAMPLE_APP) || \
+ (defined ACPI_NAMES_APP)
+#define ACPI_USE_NATIVE_RSDP_POINTER
+#endif
+
+/* AcpiDump configuration. Native mapping used if provided by the host */
+
+#ifdef ACPI_DUMP_APP
+#define ACPI_USE_NATIVE_MEMORY_MAPPING
+#define USE_NATIVE_ALLOCATE_ZEROED
+#endif
+
+/* AcpiNames/Example configuration. Hardware disabled */
+
+#if (defined ACPI_EXAMPLE_APP) || \
+ (defined ACPI_NAMES_APP)
+#define ACPI_REDUCED_HARDWARE 1
+#endif
+
+/* Linkable ACPICA library */
+
+#ifdef ACPI_LIBRARY
+#define ACPI_USE_LOCAL_CACHE
+#define ACPI_FULL_DEBUG
+#endif
+
+/* Common for all ACPICA applications */
+
+#ifdef ACPI_APPLICATION
+#define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_USE_LOCAL_CACHE
+#endif
+
+/* Common debug/disassembler support */
+
+#ifdef ACPI_FULL_DEBUG
+#define ACPI_DEBUG_OUTPUT
+#define ACPI_DEBUGGER 1
+#define ACPI_DISASSEMBLER 1
+#endif
+
+/*! [Begin] no source code translation */
+
+/******************************************************************************
+ *
+ * Host configuration files. The compiler configuration files are included
+ * by the host files.
+ *
+ *****************************************************************************/
+
+#if defined(_LINUX) || defined(__linux__)
+#include "aclinux.h"
+
+#elif defined(_APPLE) || defined(__APPLE__)
+#include "acmacosx.h"
+
+#elif defined(__DragonFly__)
+#include "acdragonfly.h"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <contrib/dev/acpica/include/platform/acfreebsd.h>
+
+#elif defined(__NetBSD__)
+#include "acnetbsd.h"
+
+#elif defined(__sun)
+#include "acsolaris.h"
+
+#elif defined(MODESTO)
+#include "acmodesto.h"
+
+#elif defined(NETWARE)
+#include "acnetware.h"
+
+#elif defined(_CYGWIN)
+#include "accygwin.h"
+
+#elif defined(WIN32)
+#include "acwin.h"
+
+#elif defined(WIN64)
+#include "acwin64.h"
+
+#elif defined(_WRS_LIB_BUILD)
+#include "acvxworks.h"
+
+#elif defined(__OS2__)
+#include "acos2.h"
+
+#elif defined(_AED_EFI)
+#include "acefi.h"
+
+#elif defined(_GNU_EFI)
+#include "acefi.h"
+
+#elif defined(__HAIKU__)
+#include "achaiku.h"
+
+#else
+
+/* Unknown environment */
+
+#error Unknown target environment
+#endif
+
+/*! [End] no source code translation !*/
+
+
+/******************************************************************************
+ *
+ * Setup defaults for the required symbols that were not defined in one of
+ * the host/compiler files above.
+ *
+ *****************************************************************************/
+
+/* 64-bit data types */
+
+#ifndef COMPILER_DEPENDENT_INT64
+#define COMPILER_DEPENDENT_INT64 long long
+#endif
+
+#ifndef COMPILER_DEPENDENT_UINT64
+#define COMPILER_DEPENDENT_UINT64 unsigned long long
+#endif
+
+/* Type of mutex supported by host. Default is binary semaphores. */
+
+#ifndef ACPI_MUTEX_TYPE
+#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE
+#endif
+
+/* Global Lock acquire/release */
+
+#ifndef ACPI_ACQUIRE_GLOBAL_LOCK
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acquired) Acquired = 1
+#endif
+
+#ifndef ACPI_RELEASE_GLOBAL_LOCK
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Pending) Pending = 0
+#endif
+
+/* Flush CPU cache - used when going to sleep. Wbinvd or similar. */
+
+#ifndef ACPI_FLUSH_CPU_CACHE
+#define ACPI_FLUSH_CPU_CACHE()
+#endif
+
+/* "inline" keywords - configurable since inline is not standardized */
+
+#ifndef ACPI_INLINE
+#define ACPI_INLINE
+#endif
+
+/*
+ * Configurable calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE - External ACPI interfaces
+ * ACPI_INTERNAL_XFACE - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces
+ */
+#ifndef ACPI_SYSTEM_XFACE
+#define ACPI_SYSTEM_XFACE
+#endif
+
+#ifndef ACPI_EXTERNAL_XFACE
+#define ACPI_EXTERNAL_XFACE
+#endif
+
+#ifndef ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#endif
+
+#ifndef ACPI_INTERNAL_VAR_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+#endif
+
+/*
+ * Debugger threading model
+ * Use single threaded if the entire subsystem is contained in an application
+ * Use multiple threaded when the subsystem is running in the kernel.
+ *
+ * By default the model is single threaded if ACPI_APPLICATION is set,
+ * multi-threaded if ACPI_APPLICATION is not set.
+ */
+#ifndef DEBUGGER_THREADING
+#ifdef ACPI_APPLICATION
+#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED
+
+#else
+#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED
+#endif
+#endif /* !DEBUGGER_THREADING */
+
+
+/******************************************************************************
+ *
+ * C library configuration
+ *
+ *****************************************************************************/
+
+/*
+ * ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
+ * Otherwise, local versions of string/memory functions will be used.
+ * ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
+ * the standard header files may be used.
+ *
+ * The ACPICA subsystem only uses low level C library functions that do not
+ * call operating system services and may therefore be inlined in the code.
+ *
+ * It may be necessary to tailor these include files to the target
+ * generation environment.
+ */
+#ifdef ACPI_USE_SYSTEM_CLIBRARY
+
+/* Use the standard C library headers. We want to keep these to a minimum. */
+
+#ifdef ACPI_USE_STANDARD_HEADERS
+
+/* Use the standard headers from the standard locations */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#endif /* ACPI_USE_STANDARD_HEADERS */
+
+/* We will be linking to the standard Clib functions */
+
+#else
+
+/******************************************************************************
+ *
+ * Not using native C library, use local implementations
+ *
+ *****************************************************************************/
+
+/*
+ * Use local definitions of C library macros and functions. These function
+ * implementations may not be as efficient as an inline or assembly code
+ * implementation provided by a native C library, but they are functionally
+ * equivalent.
+ */
+#ifndef va_arg
+
+#ifndef _VALIST
+#define _VALIST
+typedef char *va_list;
+#endif /* _VALIST */
+
+/* Storage alignment properties */
+
+#define _AUPBND (sizeof (ACPI_NATIVE_INT) - 1)
+#define _ADNBND (sizeof (ACPI_NATIVE_INT) - 1)
+
+/* Variable argument list macro definitions */
+
+#define _Bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
+#define va_arg(ap, T) (*(T *)(((ap) += (_Bnd (T, _AUPBND))) - (_Bnd (T,_ADNBND))))
+#define va_end(ap) (ap = (va_list) NULL)
+#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_Bnd (A,_AUPBND))))
+
+#endif /* va_arg */
+
+/* Use the local (ACPICA) definitions of the clib functions */
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
+#ifndef ACPI_FILE
+#ifdef ACPI_APPLICATION
+#include <stdio.h>
+#define ACPI_FILE FILE *
+#define ACPI_FILE_OUT stdout
+#define ACPI_FILE_ERR stderr
+#else
+#define ACPI_FILE void *
+#define ACPI_FILE_OUT NULL
+#define ACPI_FILE_ERR NULL
+#endif /* ACPI_APPLICATION */
+#endif /* ACPI_FILE */
+
+#endif /* __ACENV_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenvex.h b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenvex.h
new file mode 100644
index 0000000000..12fec1279b
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acenvex.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * Name: acenvex.h - Extra host and compiler configuration
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACENVEX_H__
+#define __ACENVEX_H__
+
+/*! [Begin] no source code translation */
+
+/******************************************************************************
+ *
+ * Extra host configuration files. All ACPICA headers are included before
+ * including these files.
+ *
+ *****************************************************************************/
+
+#if defined(_LINUX) || defined(__linux__)
+#include "aclinuxex.h"
+
+#elif defined(WIN32)
+#include "acwinex.h"
+
+#elif defined(_AED_EFI)
+#include "acefiex.h"
+
+#elif defined(_GNU_EFI)
+#include "acefiex.h"
+
+#elif defined(__DragonFly__)
+#include "acdragonflyex.h"
+
+#endif
+
+/*! [End] no source code translation !*/
+
+#endif /* __ACENVEX_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/platform/acfreebsd.h b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acfreebsd.h
new file mode 100644
index 0000000000..f4ba48c1b5
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acfreebsd.h
@@ -0,0 +1,115 @@
+/******************************************************************************
+ *
+ * Name: acfreebsd.h - OS specific defines, etc.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACFREEBSD_H__
+#define __ACFREEBSD_H__
+
+
+/* FreeBSD uses GCC */
+
+#include <contrib/dev/acpica/include/platform/acgcc.h>
+#include <sys/types.h>
+
+#ifdef __LP64__
+#define ACPI_MACHINE_WIDTH 64
+#else
+#define ACPI_MACHINE_WIDTH 32
+#endif
+
+#define COMPILER_DEPENDENT_INT64 int64_t
+#define COMPILER_DEPENDENT_UINT64 uint64_t
+
+#define ACPI_UINTPTR_T uintptr_t
+
+#define ACPI_USE_DO_WHILE_0
+#define ACPI_USE_LOCAL_CACHE
+#define ACPI_USE_NATIVE_DIVIDE
+#define ACPI_USE_SYSTEM_CLIBRARY
+
+#ifdef _KERNEL
+
+#include <sys/ctype.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/libkern.h>
+#include <machine/acpica_machdep.h>
+#include <machine/stdarg.h>
+
+#include "opt_acpi.h"
+
+#define ACPI_MUTEX_TYPE ACPI_OSL_MUTEX
+
+#ifdef ACPI_DEBUG
+#define ACPI_DEBUG_OUTPUT /* for backward compatibility */
+#define ACPI_DISASSEMBLER
+#endif
+
+#ifdef ACPI_DEBUG_OUTPUT
+#include "opt_ddb.h"
+#ifdef DDB
+#define ACPI_DEBUGGER
+#endif /* DDB */
+#endif /* ACPI_DEBUG_OUTPUT */
+
+#ifdef DEBUGGER_THREADING
+#undef DEBUGGER_THREADING
+#endif /* DEBUGGER_THREADING */
+
+#define DEBUGGER_THREADING 0 /* integrated with DDB */
+
+#else /* _KERNEL */
+
+#if __STDC_HOSTED__
+#include <ctype.h>
+#endif
+
+#define ACPI_CAST_PTHREAD_T(pthread) ((ACPI_THREAD_ID) ACPI_TO_INTEGER (pthread))
+
+#define ACPI_USE_STANDARD_HEADERS
+
+#define ACPI_FLUSH_CPU_CACHE()
+#define __cdecl
+
+#endif /* _KERNEL */
+
+#endif /* __ACFREEBSD_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/include/platform/acgcc.h b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acgcc.h
new file mode 100644
index 0000000000..472b6d7f8a
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/include/platform/acgcc.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * Name: acgcc.h - GCC specific defines, etc.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+#ifndef __ACGCC_H__
+#define __ACGCC_H__
+
+#define ACPI_INLINE __inline__
+
+/* Function name is used for debug output. Non-ANSI, compiler-dependent */
+
+#define ACPI_GET_FUNCTION_NAME __func__
+
+/*
+ * This macro is used to tag functions as "printf-like" because
+ * some compilers (like GCC) can catch printf format string problems.
+ */
+#define ACPI_PRINTF_LIKE(c) __attribute__ ((__format__ (__printf__, c, c+1)))
+
+/*
+ * Some compilers complain about unused variables. Sometimes we don't want to
+ * use all the variables (for example, _AcpiModuleName). This allows us
+ * to tell the compiler warning in a per-variable manner that a variable
+ * is unused.
+ */
+#define ACPI_UNUSED_VAR __attribute__ ((unused))
+
+/*
+ * Some versions of gcc implement strchr() with a buggy macro. So,
+ * undef it here. Prevents error messages of this form (usually from the
+ * file getopt.c):
+ *
+ * error: logical '&&' with non-zero constant will always evaluate as true
+ */
+#ifdef strchr
+#undef strchr
+#endif
+
+/* GCC supports __VA_ARGS__ in macros */
+
+#define COMPILER_VA_MACRO 1
+
+#endif /* __ACGCC_H__ */
diff --git a/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/oslibcfs.c b/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/oslibcfs.c
new file mode 100644
index 0000000000..c24cca47b1
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/oslibcfs.c
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ * Module Name: oslibcfs - C library OSL for file I/O
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define _COMPONENT ACPI_OS_SERVICES
+ ACPI_MODULE_NAME ("oslibcfs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsOpenFile
+ *
+ * PARAMETERS: Path - File path
+ * Modes - File operation type
+ *
+ * RETURN: File descriptor.
+ *
+ * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
+ * (ACPI_FILE_WRITING).
+ *
+ ******************************************************************************/
+
+ACPI_FILE
+AcpiOsOpenFile (
+ const char *Path,
+ UINT8 Modes)
+{
+ ACPI_FILE File;
+ UINT32 i = 0;
+ char ModesStr[4];
+
+
+ if (Modes & ACPI_FILE_READING)
+ {
+ ModesStr[i++] = 'r';
+ }
+ if (Modes & ACPI_FILE_WRITING)
+ {
+ ModesStr[i++] = 'w';
+ }
+ if (Modes & ACPI_FILE_BINARY)
+ {
+ ModesStr[i++] = 'b';
+ }
+
+ ModesStr[i++] = '\0';
+
+ File = fopen (Path, ModesStr);
+ if (!File)
+ {
+ perror ("Could not open file");
+ }
+
+ return (File);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsCloseFile
+ *
+ * PARAMETERS: File - An open file descriptor
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Close a file opened via AcpiOsOpenFile.
+ *
+ ******************************************************************************/
+
+void
+AcpiOsCloseFile (
+ ACPI_FILE File)
+{
+ fclose (File);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsReadFile
+ *
+ * PARAMETERS: File - An open file descriptor
+ * Buffer - Data buffer
+ * Size - Data block size
+ * Count - Number of data blocks
+ *
+ * RETURN: Number of bytes actually read.
+ *
+ * DESCRIPTION: Read from a file.
+ *
+ ******************************************************************************/
+
+int
+AcpiOsReadFile (
+ ACPI_FILE File,
+ void *Buffer,
+ ACPI_SIZE Size,
+ ACPI_SIZE Count)
+{
+ int Length;
+
+
+ Length = fread (Buffer, Size, Count, File);
+ if (Length < 0)
+ {
+ perror ("Error reading file");
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsWriteFile
+ *
+ * PARAMETERS: File - An open file descriptor
+ * Buffer - Data buffer
+ * Size - Data block size
+ * Count - Number of data blocks
+ *
+ * RETURN: Number of bytes actually written.
+ *
+ * DESCRIPTION: Write to a file.
+ *
+ ******************************************************************************/
+
+int
+AcpiOsWriteFile (
+ ACPI_FILE File,
+ void *Buffer,
+ ACPI_SIZE Size,
+ ACPI_SIZE Count)
+{
+ int Length;
+
+
+ Length = fwrite (Buffer, Size, Count, File);
+ if (Length < 0)
+ {
+ perror ("Error writing file");
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetFileOffset
+ *
+ * PARAMETERS: File - An open file descriptor
+ *
+ * RETURN: Current file pointer position.
+ *
+ * DESCRIPTION: Get current file offset.
+ *
+ ******************************************************************************/
+
+long
+AcpiOsGetFileOffset (
+ ACPI_FILE File)
+{
+ long Offset;
+
+
+ Offset = ftell (File);
+ return (Offset);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiOsSetFileOffset
+ *
+ * PARAMETERS: File - An open file descriptor
+ * Offset - New file offset
+ * From - From begin/end of file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set current file offset.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiOsSetFileOffset (
+ ACPI_FILE File,
+ long Offset,
+ UINT8 From)
+{
+ int Ret = 0;
+
+
+ if (From == ACPI_FILE_BEGIN)
+ {
+ Ret = fseek (File, Offset, SEEK_SET);
+ }
+ if (From == ACPI_FILE_END)
+ {
+ Ret = fseek (File, Offset, SEEK_END);
+ }
+
+ if (Ret < 0)
+ {
+ return (AE_ERROR);
+ }
+ else
+ {
+ return (AE_OK);
+ }
+}
diff --git a/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c b/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
new file mode 100644
index 0000000000..fcd5fbcca6
--- /dev/null
+++ b/usr/src/boot/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
@@ -0,0 +1,1540 @@
+/******************************************************************************
+ *
+ * Module Name: osunixxf - UNIX OSL interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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.
+ */
+
+/*
+ * These interfaces are required in order to compile the ASL compiler and the
+ * various ACPICA tools under Linux or other Unix-like system.
+ */
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acdebug.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <errno.h>
+
+#define _COMPONENT ACPI_OS_SERVICES
+ ACPI_MODULE_NAME ("osunixxf")
+
+
+BOOLEAN AcpiGbl_DebugTimeout = FALSE;
+
+
+/* Upcalls to AcpiExec */
+
+void
+AeTableOverride (
+ ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_TABLE_HEADER **NewTable);
+
+typedef void* (*PTHREAD_CALLBACK) (void *);
+
+/* Buffer used by AcpiOsVprintf */
+
+#define ACPI_VPRINTF_BUFFER_SIZE 512
+#define _ASCII_NEWLINE '\n'
+
+/* Terminal support for AcpiExec only */
+
+#ifdef ACPI_EXEC_APP
+#include <termios.h>
+
+struct termios OriginalTermAttributes;
+int TermAttributesWereSet = 0;
+
+ACPI_STATUS
+AcpiUtReadLine (
+ char *Buffer,
+ UINT32 BufferLength,
+ UINT32 *BytesRead);
+
+static void
+OsEnterLineEditMode (
+ void);
+
+static void
+OsExitLineEditMode (
+ void);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OsEnterLineEditMode, OsExitLineEditMode
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
+ *
+ * Interactive line-editing support for the AML debugger. Used with the
+ * common/acgetline module.
+ *
+ * readline() is not used because of non-portability. It is not available
+ * on all systems, and if it is, often the package must be manually installed.
+ *
+ * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
+ * editing that we need in AcpiOsGetLine.
+ *
+ * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
+ * calls will also work:
+ * For OsEnterLineEditMode: system ("stty cbreak -echo")
+ * For OsExitLineEditMode: system ("stty cooked echo")
+ *
+ *****************************************************************************/
+
+static void
+OsEnterLineEditMode (
+ void)
+{
+ struct termios LocalTermAttributes;
+
+
+ TermAttributesWereSet = 0;
+
+ /* STDIN must be a terminal */
+
+ if (!isatty (STDIN_FILENO))
+ {
+ return;
+ }
+
+ /* Get and keep the original attributes */
+
+ if (tcgetattr (STDIN_FILENO, &OriginalTermAttributes))
+ {
+ fprintf (stderr, "Could not get terminal attributes!\n");
+ return;
+ }
+
+ /* Set the new attributes to enable raw character input */
+
+ memcpy (&LocalTermAttributes, &OriginalTermAttributes,
+ sizeof (struct termios));
+
+ LocalTermAttributes.c_lflag &= ~(ICANON | ECHO);
+ LocalTermAttributes.c_cc[VMIN] = 1;
+ LocalTermAttributes.c_cc[VTIME] = 0;
+
+ if (tcsetattr (STDIN_FILENO, TCSANOW, &LocalTermAttributes))
+ {
+ fprintf (stderr, "Could not set terminal attributes!\n");
+ return;
+ }
+
+ TermAttributesWereSet = 1;
+}
+
+
+static void
+OsExitLineEditMode (
+ void)
+{
+
+ if (!TermAttributesWereSet)
+ {
+ return;
+ }
+
+ /* Set terminal attributes back to the original values */
+
+ if (tcsetattr (STDIN_FILENO, TCSANOW, &OriginalTermAttributes))
+ {
+ fprintf (stderr, "Could not restore terminal attributes!\n");
+ }
+}
+
+
+#else
+
+/* These functions are not needed for other ACPICA utilities */
+
+#define OsEnterLineEditMode()
+#define OsExitLineEditMode()
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsInitialize, AcpiOsTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize and terminate this module.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ AcpiGbl_OutputFile = stdout;
+
+ OsEnterLineEditMode ();
+
+ Status = AcpiOsCreateLock (&AcpiGbl_PrintLock);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsTerminate (
+ void)
+{
+
+ OsExitLineEditMode ();
+ return (AE_OK);
+}
+
+
+#ifndef ACPI_USE_NATIVE_RSDP_POINTER
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetRootPointer
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: RSDP physical address
+ *
+ * DESCRIPTION: Gets the ACPI root pointer (RSDP)
+ *
+ *****************************************************************************/
+
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer (
+ void)
+{
+
+ return (0);
+}
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsPredefinedOverride
+ *
+ * PARAMETERS: InitVal - Initial value of the predefined object
+ * NewVal - The new value for the object
+ *
+ * RETURN: Status, pointer to value. Null pointer returned if not
+ * overriding.
+ *
+ * DESCRIPTION: Allow the OS to override predefined names
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsPredefinedOverride (
+ const ACPI_PREDEFINED_NAMES *InitVal,
+ ACPI_STRING *NewVal)
+{
+
+ if (!InitVal || !NewVal)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ *NewVal = NULL;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsTableOverride
+ *
+ * PARAMETERS: ExistingTable - Header of current table (probably
+ * firmware)
+ * NewTable - Where an entire new table is returned.
+ *
+ * RETURN: Status, pointer to new table. Null pointer returned if no
+ * table is available to override
+ *
+ * DESCRIPTION: Return a different version of a table if one is available
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsTableOverride (
+ ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_TABLE_HEADER **NewTable)
+{
+
+ if (!ExistingTable || !NewTable)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ *NewTable = NULL;
+
+#ifdef ACPI_EXEC_APP
+
+ AeTableOverride (ExistingTable, NewTable);
+ return (AE_OK);
+#else
+
+ return (AE_NO_ACPI_TABLES);
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsPhysicalTableOverride
+ *
+ * PARAMETERS: ExistingTable - Header of current table (probably firmware)
+ * NewAddress - Where new table address is returned
+ * (Physical address)
+ * NewTableLength - Where new table length is returned
+ *
+ * RETURN: Status, address/length of new table. Null pointer returned
+ * if no table is available to override.
+ *
+ * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsPhysicalTableOverride (
+ ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_PHYSICAL_ADDRESS *NewAddress,
+ UINT32 *NewTableLength)
+{
+
+ return (AE_SUPPORT);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsRedirectOutput
+ *
+ * PARAMETERS: Destination - An open file handle/pointer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
+ *
+ *****************************************************************************/
+
+void
+AcpiOsRedirectOutput (
+ void *Destination)
+{
+
+ AcpiGbl_OutputFile = Destination;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsPrintf
+ *
+ * PARAMETERS: fmt, ... - Standard printf format
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
+ * (performance), changes should be tracked in both functions.
+ *
+ *****************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiOsPrintf (
+ const char *Fmt,
+ ...)
+{
+ va_list Args;
+ UINT8 Flags;
+
+
+ Flags = AcpiGbl_DbOutputFlags;
+ if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
+ {
+ /* Output is directable to either a file (if open) or the console */
+
+ if (AcpiGbl_DebugFile)
+ {
+ /* Output file is open, send the output there */
+
+ va_start (Args, Fmt);
+ vfprintf (AcpiGbl_DebugFile, Fmt, Args);
+ va_end (Args);
+ }
+ else
+ {
+ /* No redirection, send output to console (once only!) */
+
+ Flags |= ACPI_DB_CONSOLE_OUTPUT;
+ }
+ }
+
+ if (Flags & ACPI_DB_CONSOLE_OUTPUT)
+ {
+ va_start (Args, Fmt);
+ vfprintf (AcpiGbl_OutputFile, Fmt, Args);
+ va_end (Args);
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsVprintf
+ *
+ * PARAMETERS: fmt - Standard printf format
+ * args - Argument list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Formatted output with argument list pointer. Note: very
+ * similar to AcpiOsPrintf, changes should be tracked in both
+ * functions.
+ *
+ *****************************************************************************/
+
+void
+AcpiOsVprintf (
+ const char *Fmt,
+ va_list Args)
+{
+ UINT8 Flags;
+ char Buffer[ACPI_VPRINTF_BUFFER_SIZE];
+
+
+ /*
+ * We build the output string in a local buffer because we may be
+ * outputting the buffer twice. Using vfprintf is problematic because
+ * some implementations modify the args pointer/structure during
+ * execution. Thus, we use the local buffer for portability.
+ *
+ * Note: Since this module is intended for use by the various ACPICA
+ * utilities/applications, we can safely declare the buffer on the stack.
+ * Also, This function is used for relatively small error messages only.
+ */
+ vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
+
+ Flags = AcpiGbl_DbOutputFlags;
+ if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
+ {
+ /* Output is directable to either a file (if open) or the console */
+
+ if (AcpiGbl_DebugFile)
+ {
+ /* Output file is open, send the output there */
+
+ fputs (Buffer, AcpiGbl_DebugFile);
+ }
+ else
+ {
+ /* No redirection, send output to console (once only!) */
+
+ Flags |= ACPI_DB_CONSOLE_OUTPUT;
+ }
+ }
+
+ if (Flags & ACPI_DB_CONSOLE_OUTPUT)
+ {
+ fputs (Buffer, AcpiGbl_OutputFile);
+ }
+}
+
+
+#ifndef ACPI_EXEC_APP
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetLine
+ *
+ * PARAMETERS: Buffer - Where to return the command line
+ * BufferLength - Maximum length of Buffer
+ * BytesRead - Where the actual byte count is returned
+ *
+ * RETURN: Status and actual bytes read
+ *
+ * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
+ * AcpiExec utility, we use the acgetline module instead to
+ * provide line-editing and history support.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsGetLine (
+ char *Buffer,
+ UINT32 BufferLength,
+ UINT32 *BytesRead)
+{
+ int InputChar;
+ UINT32 EndOfLine;
+
+
+ /* Standard AcpiOsGetLine for all utilities except AcpiExec */
+
+ for (EndOfLine = 0; ; EndOfLine++)
+ {
+ if (EndOfLine >= BufferLength)
+ {
+ return (AE_BUFFER_OVERFLOW);
+ }
+
+ if ((InputChar = getchar ()) == EOF)
+ {
+ return (AE_ERROR);
+ }
+
+ if (!InputChar || InputChar == _ASCII_NEWLINE)
+ {
+ break;
+ }
+
+ Buffer[EndOfLine] = (char) InputChar;
+ }
+
+ /* Null terminate the buffer */
+
+ Buffer[EndOfLine] = 0;
+
+ /* Return the number of bytes in the string */
+
+ if (BytesRead)
+ {
+ *BytesRead = EndOfLine;
+ }
+
+ return (AE_OK);
+}
+#endif
+
+
+#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsMapMemory
+ *
+ * PARAMETERS: where - Physical address of memory to be mapped
+ * length - How much memory to map
+ *
+ * RETURN: Pointer to mapped memory. Null on error.
+ *
+ * DESCRIPTION: Map physical memory into caller's address space
+ *
+ *****************************************************************************/
+
+void *
+AcpiOsMapMemory (
+ ACPI_PHYSICAL_ADDRESS where,
+ ACPI_SIZE length)
+{
+
+ return (ACPI_TO_POINTER ((ACPI_SIZE) where));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsUnmapMemory
+ *
+ * PARAMETERS: where - Logical address of memory to be unmapped
+ * length - How much memory to unmap
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete a previously created mapping. Where and Length must
+ * correspond to a previous mapping exactly.
+ *
+ *****************************************************************************/
+
+void
+AcpiOsUnmapMemory (
+ void *where,
+ ACPI_SIZE length)
+{
+
+ return;
+}
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsAllocate
+ *
+ * PARAMETERS: Size - Amount to allocate, in bytes
+ *
+ * RETURN: Pointer to the new allocation. Null on error.
+ *
+ * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
+ *
+ *****************************************************************************/
+
+void *
+AcpiOsAllocate (
+ ACPI_SIZE size)
+{
+ void *Mem;
+
+
+ Mem = (void *) malloc ((size_t) size);
+ return (Mem);
+}
+
+
+#ifdef USE_NATIVE_ALLOCATE_ZEROED
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsAllocateZeroed
+ *
+ * PARAMETERS: Size - Amount to allocate, in bytes
+ *
+ * RETURN: Pointer to the new allocation. Null on error.
+ *
+ * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
+ *
+ *****************************************************************************/
+
+void *
+AcpiOsAllocateZeroed (
+ ACPI_SIZE size)
+{
+ void *Mem;
+
+
+ Mem = (void *) calloc (1, (size_t) size);
+ return (Mem);
+}
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsFree
+ *
+ * PARAMETERS: mem - Pointer to previously allocated memory
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free memory allocated via AcpiOsAllocate
+ *
+ *****************************************************************************/
+
+void
+AcpiOsFree (
+ void *mem)
+{
+
+ free (mem);
+}
+
+
+#ifdef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION: Semaphore stub functions
+ *
+ * DESCRIPTION: Stub functions used for single-thread applications that do
+ * not require semaphore synchronization. Full implementations
+ * of these functions appear after the stubs.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsCreateSemaphore (
+ UINT32 MaxUnits,
+ UINT32 InitialUnits,
+ ACPI_HANDLE *OutHandle)
+{
+ *OutHandle = (ACPI_HANDLE) 1;
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsDeleteSemaphore (
+ ACPI_HANDLE Handle)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsWaitSemaphore (
+ ACPI_HANDLE Handle,
+ UINT32 Units,
+ UINT16 Timeout)
+{
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsSignalSemaphore (
+ ACPI_HANDLE Handle,
+ UINT32 Units)
+{
+ return (AE_OK);
+}
+
+#else
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsCreateSemaphore
+ *
+ * PARAMETERS: InitialUnits - Units to be assigned to the new semaphore
+ * OutHandle - Where a handle will be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create an OS semaphore
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsCreateSemaphore (
+ UINT32 MaxUnits,
+ UINT32 InitialUnits,
+ ACPI_HANDLE *OutHandle)
+{
+ sem_t *Sem;
+
+
+ if (!OutHandle)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+#ifdef __APPLE__
+ {
+ char *SemaphoreName = tmpnam (NULL);
+
+ Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
+ if (!Sem)
+ {
+ return (AE_NO_MEMORY);
+ }
+ sem_unlink (SemaphoreName); /* This just deletes the name */
+ }
+
+#else
+ Sem = AcpiOsAllocate (sizeof (sem_t));
+ if (!Sem)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ if (sem_init (Sem, 0, InitialUnits) == -1)
+ {
+ AcpiOsFree (Sem);
+ return (AE_BAD_PARAMETER);
+ }
+#endif
+
+ *OutHandle = (ACPI_HANDLE) Sem;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsDeleteSemaphore
+ *
+ * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete an OS semaphore
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsDeleteSemaphore (
+ ACPI_HANDLE Handle)
+{
+ sem_t *Sem = (sem_t *) Handle;
+
+
+ if (!Sem)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (sem_destroy (Sem) == -1)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWaitSemaphore
+ *
+ * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
+ * Units - How many units to wait for
+ * MsecTimeout - How long to wait (milliseconds)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Wait for units
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsWaitSemaphore (
+ ACPI_HANDLE Handle,
+ UINT32 Units,
+ UINT16 MsecTimeout)
+{
+ ACPI_STATUS Status = AE_OK;
+ sem_t *Sem = (sem_t *) Handle;
+#ifndef ACPI_USE_ALTERNATE_TIMEOUT
+ struct timespec Time;
+ int RetVal;
+#endif
+
+
+ if (!Sem)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ switch (MsecTimeout)
+ {
+ /*
+ * No Wait:
+ * --------
+ * A zero timeout value indicates that we shouldn't wait - just
+ * acquire the semaphore if available otherwise return AE_TIME
+ * (a.k.a. 'would block').
+ */
+ case 0:
+
+ if (sem_trywait(Sem) == -1)
+ {
+ Status = (AE_TIME);
+ }
+ break;
+
+ /* Wait Indefinitely */
+
+ case ACPI_WAIT_FOREVER:
+
+ if (sem_wait (Sem))
+ {
+ Status = (AE_TIME);
+ }
+ break;
+
+ /* Wait with MsecTimeout */
+
+ default:
+
+#ifdef ACPI_USE_ALTERNATE_TIMEOUT
+ /*
+ * Alternate timeout mechanism for environments where
+ * sem_timedwait is not available or does not work properly.
+ */
+ while (MsecTimeout)
+ {
+ if (sem_trywait (Sem) == 0)
+ {
+ /* Got the semaphore */
+ return (AE_OK);
+ }
+
+ if (MsecTimeout >= 10)
+ {
+ MsecTimeout -= 10;
+ usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
+ }
+ else
+ {
+ MsecTimeout--;
+ usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
+ }
+ }
+ Status = (AE_TIME);
+#else
+ /*
+ * The interface to sem_timedwait is an absolute time, so we need to
+ * get the current time, then add in the millisecond Timeout value.
+ */
+ if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
+ {
+ perror ("clock_gettime");
+ return (AE_TIME);
+ }
+
+ Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
+ Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
+
+ /* Handle nanosecond overflow (field must be less than one second) */
+
+ if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
+ {
+ Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
+ Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
+ }
+
+ while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
+ {
+ continue;
+ }
+
+ if (RetVal != 0)
+ {
+ if (errno != ETIMEDOUT)
+ {
+ perror ("sem_timedwait");
+ }
+ Status = (AE_TIME);
+ }
+#endif
+ break;
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsSignalSemaphore
+ *
+ * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
+ * Units - Number of units to send
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Send units
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsSignalSemaphore (
+ ACPI_HANDLE Handle,
+ UINT32 Units)
+{
+ sem_t *Sem = (sem_t *)Handle;
+
+
+ if (!Sem)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (sem_post (Sem) == -1)
+ {
+ return (AE_LIMIT);
+ }
+
+ return (AE_OK);
+}
+
+#endif /* ACPI_SINGLE_THREADED */
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Spinlock interfaces
+ *
+ * DESCRIPTION: Map these interfaces to semaphore interfaces
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsCreateLock (
+ ACPI_SPINLOCK *OutHandle)
+{
+
+ return (AcpiOsCreateSemaphore (1, 1, OutHandle));
+}
+
+
+void
+AcpiOsDeleteLock (
+ ACPI_SPINLOCK Handle)
+{
+ AcpiOsDeleteSemaphore (Handle);
+}
+
+
+ACPI_CPU_FLAGS
+AcpiOsAcquireLock (
+ ACPI_HANDLE Handle)
+{
+ AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
+ return (0);
+}
+
+
+void
+AcpiOsReleaseLock (
+ ACPI_SPINLOCK Handle,
+ ACPI_CPU_FLAGS Flags)
+{
+ AcpiOsSignalSemaphore (Handle, 1);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsInstallInterruptHandler
+ *
+ * PARAMETERS: InterruptNumber - Level handler should respond to.
+ * Isr - Address of the ACPI interrupt handler
+ * ExceptPtr - Where status is returned
+ *
+ * RETURN: Handle to the newly installed handler.
+ *
+ * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
+ * OS-independent handler.
+ *
+ *****************************************************************************/
+
+UINT32
+AcpiOsInstallInterruptHandler (
+ UINT32 InterruptNumber,
+ ACPI_OSD_HANDLER ServiceRoutine,
+ void *Context)
+{
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsRemoveInterruptHandler
+ *
+ * PARAMETERS: Handle - Returned when handler was installed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Uninstalls an interrupt handler.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsRemoveInterruptHandler (
+ UINT32 InterruptNumber,
+ ACPI_OSD_HANDLER ServiceRoutine)
+{
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsStall
+ *
+ * PARAMETERS: microseconds - Time to sleep
+ *
+ * RETURN: Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at microsecond granularity
+ *
+ *****************************************************************************/
+
+void
+AcpiOsStall (
+ UINT32 microseconds)
+{
+
+ if (microseconds)
+ {
+ usleep (microseconds);
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsSleep
+ *
+ * PARAMETERS: milliseconds - Time to sleep
+ *
+ * RETURN: Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at millisecond granularity
+ *
+ *****************************************************************************/
+
+void
+AcpiOsSleep (
+ UINT64 milliseconds)
+{
+
+ /* Sleep for whole seconds */
+
+ sleep (milliseconds / ACPI_MSEC_PER_SEC);
+
+ /*
+ * Sleep for remaining microseconds.
+ * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
+ */
+ usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetTimer
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Current time in 100 nanosecond units
+ *
+ * DESCRIPTION: Get the current system time
+ *
+ *****************************************************************************/
+
+UINT64
+AcpiOsGetTimer (
+ void)
+{
+ struct timeval time;
+
+
+ /* This timer has sufficient resolution for user-space application code */
+
+ gettimeofday (&time, NULL);
+
+ /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
+
+ return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
+ ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsReadPciConfiguration
+ *
+ * PARAMETERS: PciId - Seg/Bus/Dev
+ * PciRegister - Device Register
+ * Value - Buffer where value is placed
+ * Width - Number of bits
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read data from PCI configuration space
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsReadPciConfiguration (
+ ACPI_PCI_ID *PciId,
+ UINT32 PciRegister,
+ UINT64 *Value,
+ UINT32 Width)
+{
+
+ *Value = 0;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWritePciConfiguration
+ *
+ * PARAMETERS: PciId - Seg/Bus/Dev
+ * PciRegister - Device Register
+ * Value - Value to be written
+ * Width - Number of bits
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Write data to PCI configuration space
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsWritePciConfiguration (
+ ACPI_PCI_ID *PciId,
+ UINT32 PciRegister,
+ UINT64 Value,
+ UINT32 Width)
+{
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsReadPort
+ *
+ * PARAMETERS: Address - Address of I/O port/register to read
+ * Value - Where value is placed
+ * Width - Number of bits
+ *
+ * RETURN: Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsReadPort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 *Value,
+ UINT32 Width)
+{
+
+ switch (Width)
+ {
+ case 8:
+
+ *Value = 0xFF;
+ break;
+
+ case 16:
+
+ *Value = 0xFFFF;
+ break;
+
+ case 32:
+
+ *Value = 0xFFFFFFFF;
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWritePort
+ *
+ * PARAMETERS: Address - Address of I/O port/register to write
+ * Value - Value to write
+ * Width - Number of bits
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to an I/O port or register
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsWritePort (
+ ACPI_IO_ADDRESS Address,
+ UINT32 Value,
+ UINT32 Width)
+{
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsReadMemory
+ *
+ * PARAMETERS: Address - Physical Memory Address to read
+ * Value - Where value is placed
+ * Width - Number of bits (8,16,32, or 64)
+ *
+ * RETURN: Value read from physical memory address. Always returned
+ * as a 64-bit integer, regardless of the read width.
+ *
+ * DESCRIPTION: Read data from a physical memory address
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsReadMemory (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT64 *Value,
+ UINT32 Width)
+{
+
+ switch (Width)
+ {
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+
+ *Value = 0;
+ break;
+
+ default:
+
+ return (AE_BAD_PARAMETER);
+ }
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWriteMemory
+ *
+ * PARAMETERS: Address - Physical Memory Address to write
+ * Value - Value to write
+ * Width - Number of bits (8,16,32, or 64)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to a physical memory address
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsWriteMemory (
+ ACPI_PHYSICAL_ADDRESS Address,
+ UINT64 Value,
+ UINT32 Width)
+{
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsReadable
+ *
+ * PARAMETERS: Pointer - Area to be verified
+ * Length - Size of area
+ *
+ * RETURN: TRUE if readable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for reading
+ *
+ *****************************************************************************/
+
+BOOLEAN
+AcpiOsReadable (
+ void *Pointer,
+ ACPI_SIZE Length)
+{
+
+ return (TRUE);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWritable
+ *
+ * PARAMETERS: Pointer - Area to be verified
+ * Length - Size of area
+ *
+ * RETURN: TRUE if writable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for writing
+ *
+ *****************************************************************************/
+
+BOOLEAN
+AcpiOsWritable (
+ void *Pointer,
+ ACPI_SIZE Length)
+{
+
+ return (TRUE);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsSignal
+ *
+ * PARAMETERS: Function - ACPI A signal function code
+ * Info - Pointer to function-dependent structure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Miscellaneous functions. Example implementation only.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsSignal (
+ UINT32 Function,
+ void *Info)
+{
+
+ switch (Function)
+ {
+ case ACPI_SIGNAL_FATAL:
+
+ break;
+
+ case ACPI_SIGNAL_BREAKPOINT:
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ return (AE_OK);
+}
+
+/* Optional multi-thread support */
+
+#ifndef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetThreadId
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Id of the running thread
+ *
+ * DESCRIPTION: Get the ID of the current (running) thread
+ *
+ *****************************************************************************/
+
+ACPI_THREAD_ID
+AcpiOsGetThreadId (
+ void)
+{
+ pthread_t thread;
+
+
+ thread = pthread_self();
+ return (ACPI_CAST_PTHREAD_T (thread));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsExecute
+ *
+ * PARAMETERS: Type - Type of execution
+ * Function - Address of the function to execute
+ * Context - Passed as a parameter to the function
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Execute a new thread
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsExecute (
+ ACPI_EXECUTE_TYPE Type,
+ ACPI_OSD_EXEC_CALLBACK Function,
+ void *Context)
+{
+ pthread_t thread;
+ int ret;
+
+
+ ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
+ if (ret)
+ {
+ AcpiOsPrintf("Create thread failed");
+ }
+ return (0);
+}
+
+#else /* ACPI_SINGLE_THREADED */
+ACPI_THREAD_ID
+AcpiOsGetThreadId (
+ void)
+{
+ return (1);
+}
+
+ACPI_STATUS
+AcpiOsExecute (
+ ACPI_EXECUTE_TYPE Type,
+ ACPI_OSD_EXEC_CALLBACK Function,
+ void *Context)
+{
+
+ Function (Context);
+
+ return (AE_OK);
+}
+
+#endif /* ACPI_SINGLE_THREADED */
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWaitEventsComplete
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Wait for all asynchronous events to complete. This
+ * implementation does nothing.
+ *
+ *****************************************************************************/
+
+void
+AcpiOsWaitEventsComplete (
+ void)
+{
+ return;
+}
diff --git a/usr/src/boot/sys/i386/include/_align.h b/usr/src/boot/sys/i386/include/_align.h
new file mode 100644
index 0000000000..28c4669ad2
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/_align.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_align.h>
diff --git a/usr/src/boot/sys/i386/include/_inttypes.h b/usr/src/boot/sys/i386/include/_inttypes.h
new file mode 100644
index 0000000000..40107cd74a
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/_inttypes.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_inttypes.h>
diff --git a/usr/src/boot/sys/i386/include/_limits.h b/usr/src/boot/sys/i386/include/_limits.h
new file mode 100644
index 0000000000..3c7365bb4e
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/_limits.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_limits.h>
diff --git a/usr/src/boot/sys/i386/include/_stdint.h b/usr/src/boot/sys/i386/include/_stdint.h
new file mode 100644
index 0000000000..db1affc077
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/_stdint.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_stdint.h>
diff --git a/usr/src/boot/sys/i386/include/_types.h b/usr/src/boot/sys/i386/include/_types.h
new file mode 100644
index 0000000000..26803672ff
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/_types.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/_types.h>
diff --git a/usr/src/boot/sys/i386/include/asm.h b/usr/src/boot/sys/i386/include/asm.h
new file mode 100644
index 0000000000..b2d4a6b289
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/asm.h
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define _MACHINE_ASM_H_
+
+#include <sys/cdefs.h>
+
+#ifdef PIC
+#define PIC_PROLOGUE \
+ pushl %ebx; \
+ call 1f; \
+1: \
+ popl %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
+#define PIC_EPILOGUE \
+ popl %ebx
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOT(%ebx)
+#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
+#else
+#define PIC_PROLOGUE
+#define PIC_EPILOGUE
+#define PIC_PLT(x) x
+#define PIC_GOTOFF(x) x
+#endif
+
+/*
+ * CNAME and HIDENAME manage the relationship between symbol names in C
+ * and the equivalent assembly language names. CNAME is given a name as
+ * it would be used in a C program. It expands to the equivalent assembly
+ * language name. HIDENAME is given an assembly-language name, and expands
+ * to a possibly-modified form that will be invisible to C programs.
+ */
+#define CNAME(csym) csym
+#define HIDENAME(asmsym) .asmsym
+
+/* XXX should use .p2align 4,0x90 for -m486. */
+#define _START_ENTRY .text; .p2align 2,0x90
+
+#define _ENTRY(x) _START_ENTRY; \
+ .globl CNAME(x); .type CNAME(x),@function; CNAME(x):
+#define END(x) .size x, . - x
+
+#ifdef PROF
+#define ALTENTRY(x) _ENTRY(x); \
+ pushl %ebp; movl %esp,%ebp; \
+ call PIC_PLT(HIDENAME(mcount)); \
+ popl %ebp; \
+ jmp 9f
+#define ENTRY(x) _ENTRY(x); \
+ pushl %ebp; movl %esp,%ebp; \
+ call PIC_PLT(HIDENAME(mcount)); \
+ popl %ebp; \
+ 9:
+#else
+#define ALTENTRY(x) _ENTRY(x)
+#define ENTRY(x) _ENTRY(x)
+#endif
+
+/*
+ * WEAK_REFERENCE(): create a weak reference alias from sym.
+ * The macro is not a general asm macro that takes arbitrary names,
+ * but one that takes only C names. It does the non-null name
+ * translation inside the macro.
+ */
+
+#define WEAK_REFERENCE(sym, alias) \
+ .weak CNAME(alias); \
+ .equ CNAME(alias),CNAME(sym)
+
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+#define RCSID(x) .text; .asciz x
+
+#undef __FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define __FBSDID(s) .ident s
+#else
+#define __FBSDID(s) /* nothing */
+#endif /* not lint and not STRIP_FBSDID */
+
+#endif /* !_MACHINE_ASM_H_ */
diff --git a/usr/src/boot/sys/i386/include/bootinfo.h b/usr/src/boot/sys/i386/include/bootinfo.h
new file mode 100644
index 0000000000..ef595d5f52
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/bootinfo.h
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (C) 1994 by Rodney W. Grimes, Milwaukie, Oregon 97222
+ * 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 as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Rodney W. Grimes.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RODNEY W. GRIMES ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL RODNEY W. GRIMES BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_BOOTINFO_H_
+#define _MACHINE_BOOTINFO_H_
+
+/* Only change the version number if you break compatibility. */
+#define BOOTINFO_VERSION 1
+
+#define N_BIOS_GEOM 8
+
+/*
+ * A zero bootinfo field often means that there is no info available.
+ * Flags are used to indicate the validity of fields where zero is a
+ * normal value.
+ */
+struct bootinfo {
+ u_int32_t bi_version;
+ u_int32_t bi_kernelname; /* represents a char * */
+ u_int32_t bi_nfs_diskless; /* struct nfs_diskless * */
+ /* End of fields that are always present. */
+#define bi_endcommon bi_n_bios_used
+ u_int32_t bi_n_bios_used;
+ u_int32_t bi_bios_geom[N_BIOS_GEOM];
+ u_int32_t bi_size;
+ u_int8_t bi_memsizes_valid;
+ u_int8_t bi_bios_dev; /* bootdev BIOS unit number */
+ u_int8_t bi_pad[2];
+ u_int32_t bi_basemem;
+ u_int32_t bi_extmem;
+ u_int32_t bi_symtab; /* struct symtab * */
+ u_int32_t bi_esymtab; /* struct symtab * */
+ /* Items below only from advanced bootloader */
+ u_int32_t bi_kernend; /* end of kernel space */
+ u_int32_t bi_envp; /* environment */
+ u_int32_t bi_modulep; /* preloaded modules */
+ uint32_t bi_memdesc_version; /* EFI memory desc version */
+ uint64_t bi_memdesc_size; /* sizeof EFI memory desc */
+ uint64_t bi_memmap; /* pa of EFI memory map */
+ uint64_t bi_memmap_size; /* size of EFI memory map */
+ uint64_t bi_hcdp; /* DIG64 HCDP table */
+ uint64_t bi_fpswa; /* FPSWA interface */
+ uint64_t bi_systab; /* pa of EFI system table */
+};
+
+#ifdef _KERNEL
+extern struct bootinfo bootinfo;
+#endif
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility. Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ * (4) (8) (4) (8) (8)
+ * --------------------------------
+ * |MA | SLICE | UN| PART | TYPE |
+ * --------------------------------
+ */
+#define B_SLICESHIFT 20
+#define B_SLICEMASK 0xff
+#define B_SLICE(val) (((val)>>B_SLICESHIFT) & B_SLICEMASK)
+#define B_UNITSHIFT 16
+#define B_UNITMASK 0xf
+#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK)
+#define B_PARTITIONSHIFT 8
+#define B_PARTITIONMASK 0xff
+#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK)
+#define B_TYPESHIFT 0
+#define B_TYPEMASK 0xff
+#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK)
+
+#define B_MAGICMASK 0xf0000000
+#define B_DEVMAGIC 0xa0000000
+
+#define MAKEBOOTDEV(type, slice, unit, partition) \
+ (((type) << B_TYPESHIFT) | ((slice) << B_SLICESHIFT) | \
+ ((unit) << B_UNITSHIFT) | ((partition) << B_PARTITIONSHIFT) | \
+ B_DEVMAGIC)
+
+#define BASE_SLICE 2
+#define COMPATIBILITY_SLICE 0
+#define MAX_SLICES 32
+#define WHOLE_DISK_SLICE 1
+
+#endif /* !_MACHINE_BOOTINFO_H_ */
diff --git a/usr/src/boot/sys/i386/include/cpufunc.h b/usr/src/boot/sys/i386/include/cpufunc.h
new file mode 100644
index 0000000000..f43319476d
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/cpufunc.h
@@ -0,0 +1,796 @@
+/*-
+ * Copyright (c) 1993 The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Functions to provide access to special i386 instructions.
+ * This in included in sys/systm.h, and that file should be
+ * used in preference to this.
+ */
+
+#ifndef _MACHINE_CPUFUNC_H_
+#define _MACHINE_CPUFUNC_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+struct region_descriptor;
+
+#define readb(va) (*(volatile uint8_t *) (va))
+#define readw(va) (*(volatile uint16_t *) (va))
+#define readl(va) (*(volatile uint32_t *) (va))
+
+#define writeb(va, d) (*(volatile uint8_t *) (va) = (d))
+#define writew(va, d) (*(volatile uint16_t *) (va) = (d))
+#define writel(va, d) (*(volatile uint32_t *) (va) = (d))
+
+#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
+
+static __inline void
+breakpoint(void)
+{
+ __asm __volatile("int $3");
+}
+
+static __inline u_int
+bsfl(u_int mask)
+{
+ u_int result;
+
+ __asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
+ return (result);
+}
+
+static __inline u_int
+bsrl(u_int mask)
+{
+ u_int result;
+
+ __asm("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
+ return (result);
+}
+
+static __inline void
+clflush(u_long addr)
+{
+
+ __asm __volatile("clflush %0" : : "m" (*(char *)addr));
+}
+
+static __inline void
+clflushopt(u_long addr)
+{
+
+ __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr));
+}
+
+static __inline void
+clts(void)
+{
+
+ __asm __volatile("clts");
+}
+
+static __inline void
+disable_intr(void)
+{
+
+ __asm __volatile("cli" : : : "memory");
+}
+
+static __inline void
+do_cpuid(u_int ax, u_int *p)
+{
+ __asm __volatile("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax));
+}
+
+static __inline void
+cpuid_count(u_int ax, u_int cx, u_int *p)
+{
+ __asm __volatile("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx));
+}
+
+static __inline void
+enable_intr(void)
+{
+
+ __asm __volatile("sti");
+}
+
+static __inline void
+cpu_monitor(const void *addr, u_long extensions, u_int hints)
+{
+
+ __asm __volatile("monitor"
+ : : "a" (addr), "c" (extensions), "d" (hints));
+}
+
+static __inline void
+cpu_mwait(u_long extensions, u_int hints)
+{
+
+ __asm __volatile("mwait" : : "a" (hints), "c" (extensions));
+}
+
+static __inline void
+lfence(void)
+{
+
+ __asm __volatile("lfence" : : : "memory");
+}
+
+static __inline void
+mfence(void)
+{
+
+ __asm __volatile("mfence" : : : "memory");
+}
+
+#ifdef _KERNEL
+
+#define HAVE_INLINE_FFS
+
+static __inline int
+ffs(int mask)
+{
+ /*
+ * Note that gcc-2's builtin ffs would be used if we didn't declare
+ * this inline or turn off the builtin. The builtin is faster but
+ * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later
+ * versions.
+ */
+ return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1);
+}
+
+#define HAVE_INLINE_FFSL
+
+static __inline int
+ffsl(long mask)
+{
+ return (ffs((int)mask));
+}
+
+#define HAVE_INLINE_FLS
+
+static __inline int
+fls(int mask)
+{
+ return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
+}
+
+#define HAVE_INLINE_FLSL
+
+static __inline int
+flsl(long mask)
+{
+ return (fls((int)mask));
+}
+
+#endif /* _KERNEL */
+
+static __inline void
+halt(void)
+{
+ __asm __volatile("hlt");
+}
+
+static __inline u_char
+inb(u_int port)
+{
+ u_char data;
+
+ __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline u_int
+inl(u_int port)
+{
+ u_int data;
+
+ __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline void
+insb(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insb"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+insw(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insw"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+insl(u_int port, void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; insl"
+ : "+D" (addr), "+c" (count)
+ : "d" (port)
+ : "memory");
+}
+
+static __inline void
+invd(void)
+{
+ __asm __volatile("invd");
+}
+
+static __inline u_short
+inw(u_int port)
+{
+ u_short data;
+
+ __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port));
+ return (data);
+}
+
+static __inline void
+outb(u_int port, u_char data)
+{
+ __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline void
+outl(u_int port, u_int data)
+{
+ __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline void
+outsb(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsb"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outsw(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsw"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outsl(u_int port, const void *addr, size_t count)
+{
+ __asm __volatile("cld; rep; outsl"
+ : "+S" (addr), "+c" (count)
+ : "d" (port));
+}
+
+static __inline void
+outw(u_int port, u_short data)
+{
+ __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
+}
+
+static __inline void
+ia32_pause(void)
+{
+ __asm __volatile("pause");
+}
+
+static __inline u_int
+read_eflags(void)
+{
+ u_int ef;
+
+ __asm __volatile("pushfl; popl %0" : "=r" (ef));
+ return (ef);
+}
+
+static __inline uint64_t
+rdmsr(u_int msr)
+{
+ uint64_t rv;
+
+ __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));
+ return (rv);
+}
+
+static __inline uint32_t
+rdmsr32(u_int msr)
+{
+ uint32_t low;
+
+ __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "edx");
+ return (low);
+}
+
+static __inline uint64_t
+rdpmc(u_int pmc)
+{
+ uint64_t rv;
+
+ __asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc));
+ return (rv);
+}
+
+static __inline uint64_t
+rdtsc(void)
+{
+ uint64_t rv;
+
+ __asm __volatile("rdtsc" : "=A" (rv));
+ return (rv);
+}
+
+static __inline uint32_t
+rdtsc32(void)
+{
+ uint32_t rv;
+
+ __asm __volatile("rdtsc" : "=a" (rv) : : "edx");
+ return (rv);
+}
+
+static __inline void
+wbinvd(void)
+{
+ __asm __volatile("wbinvd");
+}
+
+static __inline void
+write_eflags(u_int ef)
+{
+ __asm __volatile("pushl %0; popfl" : : "r" (ef));
+}
+
+static __inline void
+wrmsr(u_int msr, uint64_t newval)
+{
+ __asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
+}
+
+static __inline void
+load_cr0(u_int data)
+{
+
+ __asm __volatile("movl %0,%%cr0" : : "r" (data));
+}
+
+static __inline u_int
+rcr0(void)
+{
+ u_int data;
+
+ __asm __volatile("movl %%cr0,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline u_int
+rcr2(void)
+{
+ u_int data;
+
+ __asm __volatile("movl %%cr2,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_cr3(u_int data)
+{
+
+ __asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory");
+}
+
+static __inline u_int
+rcr3(void)
+{
+ u_int data;
+
+ __asm __volatile("movl %%cr3,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_cr4(u_int data)
+{
+ __asm __volatile("movl %0,%%cr4" : : "r" (data));
+}
+
+static __inline u_int
+rcr4(void)
+{
+ u_int data;
+
+ __asm __volatile("movl %%cr4,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline uint64_t
+rxcr(u_int reg)
+{
+ u_int low, high;
+
+ __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
+ return (low | ((uint64_t)high << 32));
+}
+
+static __inline void
+load_xcr(u_int reg, uint64_t val)
+{
+ u_int low, high;
+
+ low = val;
+ high = val >> 32;
+ __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
+}
+
+/*
+ * Global TLB flush (except for thise for pages marked PG_G)
+ */
+static __inline void
+invltlb(void)
+{
+
+ load_cr3(rcr3());
+}
+
+/*
+ * TLB flush for an individual page (even if it has PG_G).
+ * Only works on 486+ CPUs (i386 does not have PG_G).
+ */
+static __inline void
+invlpg(u_int addr)
+{
+
+ __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
+}
+
+static __inline u_short
+rfs(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%fs,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline uint64_t
+rgdt(void)
+{
+ uint64_t gdtr;
+ __asm __volatile("sgdt %0" : "=m" (gdtr));
+ return (gdtr);
+}
+
+static __inline u_short
+rgs(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%gs,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline uint64_t
+ridt(void)
+{
+ uint64_t idtr;
+ __asm __volatile("sidt %0" : "=m" (idtr));
+ return (idtr);
+}
+
+static __inline u_short
+rldt(void)
+{
+ u_short ldtr;
+ __asm __volatile("sldt %0" : "=g" (ldtr));
+ return (ldtr);
+}
+
+static __inline u_short
+rss(void)
+{
+ u_short sel;
+ __asm __volatile("movw %%ss,%0" : "=rm" (sel));
+ return (sel);
+}
+
+static __inline u_short
+rtr(void)
+{
+ u_short tr;
+ __asm __volatile("str %0" : "=g" (tr));
+ return (tr);
+}
+
+static __inline void
+load_fs(u_short sel)
+{
+ __asm __volatile("movw %0,%%fs" : : "rm" (sel));
+}
+
+static __inline void
+load_gs(u_short sel)
+{
+ __asm __volatile("movw %0,%%gs" : : "rm" (sel));
+}
+
+static __inline void
+lidt(struct region_descriptor *addr)
+{
+ __asm __volatile("lidt (%0)" : : "r" (addr));
+}
+
+static __inline void
+lldt(u_short sel)
+{
+ __asm __volatile("lldt %0" : : "r" (sel));
+}
+
+static __inline void
+ltr(u_short sel)
+{
+ __asm __volatile("ltr %0" : : "r" (sel));
+}
+
+static __inline u_int
+rdr0(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr0,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr0(u_int dr0)
+{
+ __asm __volatile("movl %0,%%dr0" : : "r" (dr0));
+}
+
+static __inline u_int
+rdr1(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr1,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr1(u_int dr1)
+{
+ __asm __volatile("movl %0,%%dr1" : : "r" (dr1));
+}
+
+static __inline u_int
+rdr2(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr2,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr2(u_int dr2)
+{
+ __asm __volatile("movl %0,%%dr2" : : "r" (dr2));
+}
+
+static __inline u_int
+rdr3(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr3,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr3(u_int dr3)
+{
+ __asm __volatile("movl %0,%%dr3" : : "r" (dr3));
+}
+
+static __inline u_int
+rdr4(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr4,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr4(u_int dr4)
+{
+ __asm __volatile("movl %0,%%dr4" : : "r" (dr4));
+}
+
+static __inline u_int
+rdr5(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr5,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr5(u_int dr5)
+{
+ __asm __volatile("movl %0,%%dr5" : : "r" (dr5));
+}
+
+static __inline u_int
+rdr6(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr6,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr6(u_int dr6)
+{
+ __asm __volatile("movl %0,%%dr6" : : "r" (dr6));
+}
+
+static __inline u_int
+rdr7(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr7,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr7(u_int dr7)
+{
+ __asm __volatile("movl %0,%%dr7" : : "r" (dr7));
+}
+
+static __inline u_char
+read_cyrix_reg(u_char reg)
+{
+ outb(0x22, reg);
+ return inb(0x23);
+}
+
+static __inline void
+write_cyrix_reg(u_char reg, u_char data)
+{
+ outb(0x22, reg);
+ outb(0x23, data);
+}
+
+static __inline register_t
+intr_disable(void)
+{
+ register_t eflags;
+
+ eflags = read_eflags();
+ disable_intr();
+ return (eflags);
+}
+
+static __inline void
+intr_restore(register_t eflags)
+{
+ write_eflags(eflags);
+}
+
+#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
+
+int breakpoint(void);
+u_int bsfl(u_int mask);
+u_int bsrl(u_int mask);
+void clflush(u_long addr);
+void clts(void);
+void cpuid_count(u_int ax, u_int cx, u_int *p);
+void disable_intr(void);
+void do_cpuid(u_int ax, u_int *p);
+void enable_intr(void);
+void halt(void);
+void ia32_pause(void);
+u_char inb(u_int port);
+u_int inl(u_int port);
+void insb(u_int port, void *addr, size_t count);
+void insl(u_int port, void *addr, size_t count);
+void insw(u_int port, void *addr, size_t count);
+register_t intr_disable(void);
+void intr_restore(register_t ef);
+void invd(void);
+void invlpg(u_int addr);
+void invltlb(void);
+u_short inw(u_int port);
+void lidt(struct region_descriptor *addr);
+void lldt(u_short sel);
+void load_cr0(u_int cr0);
+void load_cr3(u_int cr3);
+void load_cr4(u_int cr4);
+void load_dr0(u_int dr0);
+void load_dr1(u_int dr1);
+void load_dr2(u_int dr2);
+void load_dr3(u_int dr3);
+void load_dr4(u_int dr4);
+void load_dr5(u_int dr5);
+void load_dr6(u_int dr6);
+void load_dr7(u_int dr7);
+void load_fs(u_short sel);
+void load_gs(u_short sel);
+void ltr(u_short sel);
+void outb(u_int port, u_char data);
+void outl(u_int port, u_int data);
+void outsb(u_int port, const void *addr, size_t count);
+void outsl(u_int port, const void *addr, size_t count);
+void outsw(u_int port, const void *addr, size_t count);
+void outw(u_int port, u_short data);
+u_int rcr0(void);
+u_int rcr2(void);
+u_int rcr3(void);
+u_int rcr4(void);
+uint64_t rdmsr(u_int msr);
+uint64_t rdpmc(u_int pmc);
+u_int rdr0(void);
+u_int rdr1(void);
+u_int rdr2(void);
+u_int rdr3(void);
+u_int rdr4(void);
+u_int rdr5(void);
+u_int rdr6(void);
+u_int rdr7(void);
+uint64_t rdtsc(void);
+u_char read_cyrix_reg(u_char reg);
+u_int read_eflags(void);
+u_int rfs(void);
+uint64_t rgdt(void);
+u_int rgs(void);
+uint64_t ridt(void);
+u_short rldt(void);
+u_short rtr(void);
+void wbinvd(void);
+void write_cyrix_reg(u_char reg, u_char data);
+void write_eflags(u_int ef);
+void wrmsr(u_int msr, uint64_t newval);
+
+#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
+
+void reset_dbregs(void);
+
+#ifdef _KERNEL
+int rdmsr_safe(u_int msr, uint64_t *val);
+int wrmsr_safe(u_int msr, uint64_t newval);
+#endif
+
+#endif /* !_MACHINE_CPUFUNC_H_ */
diff --git a/usr/src/boot/sys/i386/include/elf.h b/usr/src/boot/sys/i386/include/elf.h
new file mode 100644
index 0000000000..f9323775dc
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/elf.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/elf.h>
diff --git a/usr/src/boot/sys/i386/include/endian.h b/usr/src/boot/sys/i386/include/endian.h
new file mode 100644
index 0000000000..2ad27a9069
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/endian.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/endian.h>
diff --git a/usr/src/boot/sys/i386/include/exec.h b/usr/src/boot/sys/i386/include/exec.h
new file mode 100644
index 0000000000..8d07887be2
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/exec.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)exec.h 8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_EXEC_H_
+#define _MACHINE_EXEC_H_
+
+#define __LDPGSZ 4096
+
+#endif /* !_MACHINE_EXEC_H_ */
diff --git a/usr/src/boot/sys/i386/include/metadata.h b/usr/src/boot/sys/i386/include/metadata.h
new file mode 100644
index 0000000000..98d0272fd4
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/metadata.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/metadata.h>
diff --git a/usr/src/boot/sys/i386/include/param.h b/usr/src/boot/sys/i386/include/param.h
new file mode 100644
index 0000000000..f7968f8308
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/param.h
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)param.h 5.8 (Berkeley) 6/28/91
+ * $FreeBSD$
+ */
+
+
+#ifndef _I386_INCLUDE_PARAM_H_
+#define _I386_INCLUDE_PARAM_H_
+
+#include <machine/_align.h>
+
+/*
+ * Machine dependent constants for Intel 386.
+ */
+
+
+#define __HAVE_ACPI
+#define __HAVE_PIR
+#define __PCI_REROUTE_INTERRUPT
+
+#ifndef MACHINE
+#define MACHINE "i386"
+#endif
+#ifndef MACHINE_ARCH
+#define MACHINE_ARCH "i386"
+#endif
+#define MID_MACHINE MID_I386
+
+#if defined(SMP) || defined(KLD_MODULE)
+#ifndef MAXCPU
+#define MAXCPU 32
+#endif
+#else
+#define MAXCPU 1
+#endif /* SMP || KLD_MODULE */
+
+#ifndef MAXMEMDOM
+#define MAXMEMDOM 1
+#endif
+
+#define ALIGNBYTES _ALIGNBYTES
+#define ALIGN(p) _ALIGN(p)
+/*
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits).
+ */
+#define ALIGNED_POINTER(p, t) 1
+
+/*
+ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an
+ * architecture. It should be used with appropriate caution.
+ */
+#define CACHE_LINE_SHIFT 7
+#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
+
+#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */
+#define PAGE_SIZE (1<<PAGE_SHIFT) /* bytes/page */
+#define PAGE_MASK (PAGE_SIZE-1)
+#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
+
+#if defined(PAE) || defined(PAE_TABLES)
+#define NPGPTD 4
+#define PDRSHIFT 21 /* LOG2(NBPDR) */
+#define NPGPTD_SHIFT 9
+#else
+#define NPGPTD 1
+#define PDRSHIFT 22 /* LOG2(NBPDR) */
+#define NPGPTD_SHIFT 10
+#endif
+
+#define NBPTD (NPGPTD<<PAGE_SHIFT)
+#define NPDEPTD (NBPTD/(sizeof (pd_entry_t)))
+#define NPDEPG (PAGE_SIZE/(sizeof (pd_entry_t)))
+#define NBPDR (1<<PDRSHIFT) /* bytes/page dir */
+#define PDRMASK (NBPDR-1)
+
+#define MAXPAGESIZES 2 /* maximum number of supported page sizes */
+
+#define IOPAGES 2 /* pages of i/o permission bitmap */
+
+#ifndef KSTACK_PAGES
+#define KSTACK_PAGES 2 /* Includes pcb! */
+#endif
+#define KSTACK_GUARD_PAGES 1 /* pages of kstack guard; 0 disables */
+#if KSTACK_PAGES < 4
+#define TD0_KSTACK_PAGES 4
+#else
+#define TD0_KSTACK_PAGES KSTACK_PAGES
+#endif
+
+/*
+ * Ceiling on amount of swblock kva space, can be changed via
+ * the kern.maxswzone /boot/loader.conf variable.
+ *
+ * 276 is sizeof(struct swblock), but we do not always have a definition
+ * in scope for struct swblock, so we have to hardcode it. Each struct
+ * swblock holds metadata for 32 pages, so in theory, this is enough for
+ * 16 GB of swap. In practice, however, the usable amount is considerably
+ * lower due to fragmentation.
+ */
+#ifndef VM_SWZONE_SIZE_MAX
+#define VM_SWZONE_SIZE_MAX (276 * 128 * 1024)
+#endif
+
+/*
+ * Ceiling on size of buffer cache (really only effects write queueing,
+ * the VM page cache is not effected), can be changed via
+ * the kern.maxbcache /boot/loader.conf variable.
+ *
+ * The value is equal to the size of the auto-tuned buffer map for
+ * the machine with 4GB of RAM, see vfs_bio.c:kern_vfs_bio_buffer_alloc().
+ */
+#ifndef VM_BCACHE_SIZE_MAX
+#define VM_BCACHE_SIZE_MAX (7224 * 16 * 1024)
+#endif
+
+/*
+ * Mach derived conversion macros
+ */
+#define trunc_page(x) ((x) & ~PAGE_MASK)
+#define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK)
+#define trunc_4mpage(x) ((x) & ~PDRMASK)
+#define round_4mpage(x) ((((x)) + PDRMASK) & ~PDRMASK)
+
+#define atop(x) ((x) >> PAGE_SHIFT)
+#define ptoa(x) ((x) << PAGE_SHIFT)
+
+#define i386_btop(x) ((x) >> PAGE_SHIFT)
+#define i386_ptob(x) ((x) << PAGE_SHIFT)
+
+#define pgtok(x) ((x) * (PAGE_SIZE / 1024))
+
+#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MAXUSER_ADDRESS && \
+ ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS)
+
+#endif /* !_I386_INCLUDE_PARAM_H_ */
diff --git a/usr/src/boot/sys/i386/include/pc/bios.h b/usr/src/boot/sys/i386/include/pc/bios.h
new file mode 100644
index 0000000000..d1d8caff4a
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/pc/bios.h
@@ -0,0 +1,350 @@
+/*-
+ * Copyright (c) 1997 Michael Smith
+ * Copyright (c) 1998 Jonathan Lemon
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_PC_BIOS_H_
+#define _MACHINE_PC_BIOS_H_
+
+/*
+ * Signature structure for the BIOS32 Service Directory header
+ */
+struct bios32_SDheader
+{
+ u_int8_t sig[4];
+ u_int32_t entry;
+ u_int8_t revision;
+ u_int8_t len;
+ u_int8_t cksum;
+ u_int8_t pad[5];
+};
+
+/*
+ * PnP BIOS presence structure
+ */
+struct PnPBIOS_table
+{
+ u_int8_t sig[4]; /* "$PnP */
+ u_int8_t version; /* should be 0x10 */
+ u_int8_t len; /* total structure length */
+ u_int16_t control; /* BIOS feature flags */
+ u_int8_t cksum; /* checksum */
+ u_int32_t evflagaddr; /* address of event notificaton flag */
+ u_int16_t rmentryoffset; /* real-mode entry offset */
+ u_int16_t rmentryseg; /* segment */
+ u_int16_t pmentryoffset; /* protected-mode entry offset */
+ u_int32_t pmentrybase; /* segment base */
+ u_int32_t oemdevid; /* motherboard EISA ID */
+ u_int16_t rmbiosseg; /* real-mode BIOS segment */
+ u_int32_t pmdataseg; /* protected-mode data segment */
+} __packed;
+
+/*
+ * PnP BIOS return codes
+ */
+#define PNP_SUCCESS 0x00
+#define PNP_NOT_SET_STATICALLY 0x7f
+#define PNP_UNKNOWN_FUNCTION 0x81
+#define PNP_FUNCTION_NOT_SUPPORTED 0x82
+#define PNP_INVALID_HANDLE 0x83
+#define PNP_BAD_PARAMETER 0x84
+#define PNP_SET_FAILED 0x85
+#define PNP_EVENTS_NOT_PENDING 0x86
+#define PNP_SYSTEM_NOT_DOCKED 0x87
+#define PNP_NO_ISA_PNP_CARDS 0x88
+#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
+#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
+#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
+#define PNP_BUFFER_TOO_SMALL 0x8c
+#define PNP_USE_ESCD_SUPPORT 0x8d
+#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
+#define PNP_HARDWARE_ERROR 0x8f
+
+/*
+ * DMI return codes
+ */
+#define DMI_SUCCESS 0x00
+#define DMI_UNKNOWN_FUNCTION 0x81
+#define DMI_FUNCTION_NOT_SUPPORTED 0x82
+#define DMI_INVALID_HANDLE 0x83
+#define DMI_BAD_PARAMETER 0x84
+#define DMI_INVALID_SUBFUNCTION 0x85
+#define DMI_NO_CHANGE 0x86
+#define DMI_ADD_STRUCTURE_FAILED 0x87
+#define DMI_READ_ONLY 0x8d
+#define DMI_LOCK_NOT_SUPPORTED 0x90
+#define DMI_CURRENTLY_LOCKED 0x91
+#define DMI_INVALID_LOCK 0x92
+
+/*
+ * format specifiers and defines for bios16()
+ * s = short (16 bits)
+ * i = int (32 bits)
+ * p = pointer (converted to seg:offset)
+ * C,D,U = selector (corresponding to code/data/utility segment)
+ */
+#define PNP_COUNT_DEVNODES "sppD", 0x00
+#define PNP_GET_DEVNODE "sppsD", 0x01
+#define PNP_SET_DEVNODE "sspsD", 0x02
+#define PNP_GET_EVENT "spD", 0x03
+#define PNP_SEND_MSG "ssD", 0x04
+#define PNP_GET_DOCK_INFO "spD", 0x05
+
+#define PNP_SEL_PRIBOOT "ssiiisspD", 0x07
+#define PNP_GET_PRIBOOT "sspppppD", 0x08
+#define PNP_SET_RESINFO "spD", 0x09
+#define PNP_GET_RESINFO "spD", 0x0A
+#define PNP_GET_APM_ID "sppD", 0x0B
+
+#define PNP_GET_ISA_INFO "spD", 0x40
+#define PNP_GET_ECSD_INFO "spppD", 0x41
+#define PNP_READ_ESCD "spUD", 0x42
+#define PNP_WRITE_ESCD "spUD", 0x43
+
+#define PNP_GET_DMI_INFO "spppppD", 0x50
+#define PNP_GET_DMI_STRUCTURE "sppUD", 0x51
+#define PNP_SET_DMI_STRUCTURE "sppsUD" 0x52
+#define PNP_GET_DMI_CHANGE "spUD" 0x53
+#define PNP_DMI_CONTROL "sspsUD" 0x54
+#define PNP_GET_GPNV_INFO "sppppD" 0x55
+#define PNP_READ_GPNV_DATA "ssppUD" 0x56
+#define PNP_WRITE_GPNV_DATA "sspsUD" 0x57
+
+#define PNP_BOOT_CHECK "sp", 0x60
+#define PNP_COUNT_IPL "sppp", 0x61
+#define PNP_GET_BOOTPRI "spp", 0x62
+#define PNP_SET_BOOTPRI "sp", 0x63
+#define PNP_GET_LASTBOOT "sp", 0x64
+#define PNP_GET_BOOTFIRST "sp", 0x65
+#define PNP_SET_BOOTFIRST "sp", 0x66
+
+/*
+ * PCI BIOS functions
+ */
+#define PCIBIOS_BIOS_PRESENT 0xb101
+#define PCIBIOS_READ_CONFIG_BYTE 0xb108
+#define PCIBIOS_READ_CONFIG_WORD 0xb109
+#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
+#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
+#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
+#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
+#define PCIBIOS_GET_IRQ_ROUTING 0xb10e
+#define PCIBIOS_ROUTE_INTERRUPT 0xb10f
+
+/*
+ * PCI interrupt routing table.
+ *
+ * $PIR in the BIOS segment contains a PIR_table
+ * int 1a:b106 returns PIR_table in buffer at es:(e)di
+ * int 1a:b18e returns PIR_table in buffer at es:(e)di
+ * int 1a:b406 returns es:di pointing to the BIOS PIR_table
+ */
+struct PIR_header
+{
+ int8_t ph_signature[4];
+ u_int16_t ph_version;
+ u_int16_t ph_length;
+ u_int8_t ph_router_bus;
+ u_int8_t ph_router_dev_fn;
+ u_int16_t ph_pci_irqs;
+ u_int16_t ph_router_vendor;
+ u_int16_t ph_router_device;
+ u_int32_t ph_miniport;
+ u_int8_t ph_res[11];
+ u_int8_t ph_checksum;
+} __packed;
+
+struct PIR_intpin
+{
+ u_int8_t link;
+ u_int16_t irqs;
+} __packed;
+
+struct PIR_entry
+{
+ u_int8_t pe_bus;
+ u_int8_t pe_res1:3;
+ u_int8_t pe_device:5;
+ struct PIR_intpin pe_intpin[4];
+ u_int8_t pe_slot;
+ u_int8_t pe_res3;
+} __packed;
+
+struct PIR_table
+{
+ struct PIR_header pt_header;
+ struct PIR_entry pt_entry[0];
+} __packed;
+
+/*
+ * Int 15:E820 'SMAP' structure
+ */
+#define SMAP_SIG 0x534D4150 /* 'SMAP' */
+
+#define SMAP_TYPE_MEMORY 1
+#define SMAP_TYPE_RESERVED 2
+#define SMAP_TYPE_ACPI_RECLAIM 3
+#define SMAP_TYPE_ACPI_NVS 4
+#define SMAP_TYPE_ACPI_ERROR 5
+
+#define SMAP_XATTR_ENABLED 0x00000001
+#define SMAP_XATTR_NON_VOLATILE 0x00000002
+#define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE)
+
+struct bios_smap {
+ u_int64_t base;
+ u_int64_t length;
+ u_int32_t type;
+} __packed;
+
+/* Structure extended to include extended attribute field in ACPI 3.0. */
+struct bios_smap_xattr {
+ u_int64_t base;
+ u_int64_t length;
+ u_int32_t type;
+ u_int32_t xattr;
+} __packed;
+
+/*
+ * System Management BIOS
+ */
+#define SMBIOS_START 0xf0000
+#define SMBIOS_STEP 0x10
+#define SMBIOS_OFF 0
+#define SMBIOS_LEN 4
+#define SMBIOS_SIG "_SM_"
+
+struct smbios_eps {
+ uint8_t anchor_string[4]; /* '_SM_' */
+ uint8_t checksum;
+ uint8_t length;
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint16_t maximum_structure_size;
+ uint8_t entry_point_revision;
+ uint8_t formatted_area[5];
+ uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
+ uint8_t intermediate_checksum;
+ uint16_t structure_table_length;
+ uint32_t structure_table_address;
+ uint16_t number_structures;
+ uint8_t BCD_revision;
+};
+
+struct smbios_structure_header {
+ uint8_t type;
+ uint8_t length;
+ uint16_t handle;
+};
+
+#ifdef _KERNEL
+#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
+#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
+
+struct bios_oem_signature {
+ char * anchor; /* search anchor string in BIOS memory */
+ size_t offset; /* offset from anchor (may be negative) */
+ size_t totlen; /* total length of BIOS string to copy */
+} __packed;
+
+struct bios_oem_range {
+ u_int from; /* shouldn't be below 0xe0000 */
+ u_int to; /* shouldn't be above 0xfffff */
+} __packed;
+
+struct bios_oem {
+ struct bios_oem_range range;
+ struct bios_oem_signature signature[];
+} __packed;
+
+struct segment_info {
+ u_int base;
+ u_int limit;
+};
+
+#define BIOSCODE_FLAG 0x01
+#define BIOSDATA_FLAG 0x02
+#define BIOSUTIL_FLAG 0x04
+#define BIOSARGS_FLAG 0x08
+
+struct bios_segments {
+ struct segment_info code32; /* 32-bit code (mandatory) */
+ struct segment_info code16; /* 16-bit code */
+ struct segment_info data; /* 16-bit data */
+ struct segment_info util; /* 16-bit utility */
+ struct segment_info args; /* 16-bit args */
+};
+
+struct bios_regs {
+ u_int eax;
+ u_int ebx;
+ u_int ecx;
+ u_int edx;
+ u_int esi;
+ u_int edi;
+};
+
+struct bios_args {
+ u_int entry; /* entry point of routine */
+ struct bios_regs r;
+ struct bios_segments seg;
+};
+
+/*
+ * BIOS32 Service Directory entry. Caller supplies name, bios32_SDlookup
+ * fills in the rest of the details.
+ */
+struct bios32_SDentry
+{
+ union
+ {
+ u_int8_t name[4]; /* service identifier */
+ u_int32_t id; /* as a 32-bit value */
+ } ident;
+ u_int32_t base; /* base of service */
+ u_int32_t len; /* service length */
+ u_int32_t entry; /* entrypoint offset from base */
+ vm_offset_t ventry; /* entrypoint in kernel virtual segment */
+};
+
+/*
+ * Exported lookup results
+ */
+extern struct bios32_SDentry PCIbios;
+
+int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
+uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
+ int sigofs);
+int bios16(struct bios_args *, char *, ...);
+int bios16_call(struct bios_regs *, char *);
+int bios32(struct bios_regs *, u_int, u_short);
+int bios32_SDlookup(struct bios32_SDentry *ent);
+void set_bios_selectors(struct bios_segments *, int);
+
+#endif
+
+#endif /* _MACHINE_PC_BIOS_H_ */
diff --git a/usr/src/boot/sys/i386/include/psl.h b/usr/src/boot/sys/i386/include/psl.h
new file mode 100644
index 0000000000..4d945a1ebb
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/psl.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/psl.h>
diff --git a/usr/src/boot/sys/i386/include/reloc.h b/usr/src/boot/sys/i386/include/reloc.h
new file mode 100644
index 0000000000..1883193233
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/reloc.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)reloc.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _I386_MACHINE_RELOC_H_
+#define _I386_MACHINE_RELOC_H_
+
+/* Relocation format. */
+struct relocation_info {
+ int r_address; /* offset in text or data segment */
+ unsigned int r_symbolnum : 24, /* ordinal number of add symbol */
+ r_pcrel : 1, /* 1 if value should be pc-relative */
+ r_length : 2, /* log base 2 of value's width */
+ r_extern : 1, /* 1 if need to add symbol to value */
+ r_baserel : 1, /* linkage table relative */
+ r_jmptable : 1, /* relocate to jump table */
+ r_relative : 1, /* load address relative */
+ r_copy : 1; /* run time copy */
+};
+
+#endif
diff --git a/usr/src/boot/sys/i386/include/setjmp.h b/usr/src/boot/sys/i386/include/setjmp.h
new file mode 100644
index 0000000000..c4101a77fd
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/setjmp.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/setjmp.h>
diff --git a/usr/src/boot/sys/i386/include/signal.h b/usr/src/boot/sys/i386/include/signal.h
new file mode 100644
index 0000000000..26c1ee6363
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/signal.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1986, 1989, 1991, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)signal.h 8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_SIGNAL_H_
+#define _MACHINE_SIGNAL_H_
+
+#include <x86/signal.h>
+
+#if defined(_KERNEL) && defined(COMPAT_43)
+/*
+ * Only the kernel should need these old type definitions.
+ */
+struct osigcontext {
+ int sc_onstack; /* sigstack state to restore */
+ osigset_t sc_mask; /* signal mask to restore */
+ int sc_esp; /* machine state follows: */
+ int sc_ebp;
+ int sc_isp;
+ int sc_eip;
+ int sc_efl;
+ int sc_es;
+ int sc_ds;
+ int sc_cs;
+ int sc_ss;
+ int sc_edi;
+ int sc_esi;
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+ int sc_gs;
+ int sc_fs;
+ int sc_trapno;
+ int sc_err;
+};
+#endif
+
+#endif /* !_MACHINE_SIGNAL_H_ */
diff --git a/usr/src/boot/sys/i386/include/specialreg.h b/usr/src/boot/sys/i386/include/specialreg.h
new file mode 100644
index 0000000000..aace4bfd62
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/specialreg.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/specialreg.h>
diff --git a/usr/src/boot/sys/i386/include/stdarg.h b/usr/src/boot/sys/i386/include/stdarg.h
new file mode 100644
index 0000000000..1f80090356
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/stdarg.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/stdarg.h>
diff --git a/usr/src/boot/sys/i386/include/trap.h b/usr/src/boot/sys/i386/include/trap.h
new file mode 100644
index 0000000000..4d950771dc
--- /dev/null
+++ b/usr/src/boot/sys/i386/include/trap.h
@@ -0,0 +1,6 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#include <x86/trap.h>
diff --git a/usr/src/boot/sys/sys/_iovec.h b/usr/src/boot/sys/sys/_iovec.h
new file mode 100644
index 0000000000..bd72073329
--- /dev/null
+++ b/usr/src/boot/sys/sys/_iovec.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)uio.h 8.5 (Berkeley) 2/22/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__IOVEC_H_
+#define _SYS__IOVEC_H_
+
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+struct iovec {
+ void *iov_base; /* Base address. */
+ size_t iov_len; /* Length. */
+};
+
+#endif /* !_SYS__IOVEC_H_ */
diff --git a/usr/src/boot/sys/sys/_lock.h b/usr/src/boot/sys/sys/_lock.h
new file mode 100644
index 0000000000..ff5828cdba
--- /dev/null
+++ b/usr/src/boot/sys/sys/_lock.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Berkeley Software Design Inc's name may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__LOCK_H_
+#define _SYS__LOCK_H_
+
+struct lock_object {
+ const char *lo_name; /* Individual lock name. */
+ u_int lo_flags;
+ u_int lo_data; /* General class specific data. */
+ struct witness *lo_witness; /* Data for witness. */
+};
+
+#endif /* !_SYS__LOCK_H_ */
diff --git a/usr/src/boot/sys/sys/_mutex.h b/usr/src/boot/sys/sys/_mutex.h
new file mode 100644
index 0000000000..5da137a0de
--- /dev/null
+++ b/usr/src/boot/sys/sys/_mutex.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Berkeley Software Design Inc's name may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__MUTEX_H_
+#define _SYS__MUTEX_H_
+
+#include <machine/param.h>
+
+/*
+ * Sleep/spin mutex.
+ *
+ * All mutex implementations must always have a member called mtx_lock.
+ * Other locking primitive structures are not allowed to use this name
+ * for their members.
+ * If this rule needs to change, the bits in the mutex implementation must
+ * be modified appropriately.
+ */
+struct mtx {
+ struct lock_object lock_object; /* Common lock properties. */
+ volatile uintptr_t mtx_lock; /* Owner and flags. */
+};
+
+/*
+ * Members of struct mtx_padalign must mirror members of struct mtx.
+ * mtx_padalign mutexes can use the mtx(9) API transparently without
+ * modification.
+ * Pad-aligned mutexes used within structures should generally be the
+ * first member of the struct. Otherwise, the compiler can generate
+ * additional padding for the struct to keep a correct alignment for
+ * the mutex.
+ */
+struct mtx_padalign {
+ struct lock_object lock_object; /* Common lock properties. */
+ volatile uintptr_t mtx_lock; /* Owner and flags. */
+} __aligned(CACHE_LINE_SIZE);
+
+#endif /* !_SYS__MUTEX_H_ */
diff --git a/usr/src/boot/sys/sys/_null.h b/usr/src/boot/sys/sys/_null.h
new file mode 100644
index 0000000000..92706c6a03
--- /dev/null
+++ b/usr/src/boot/sys/sys/_null.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef NULL
+
+#if !defined(__cplusplus)
+#define NULL ((void *)0)
+#else
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
+#define NULL __null
+#else
+#if defined(__LP64__)
+#define NULL (0L)
+#else
+#define NULL 0
+#endif /* __LP64__ */
+#endif /* __GNUG__ */
+#endif /* !__cplusplus */
+
+#endif
diff --git a/usr/src/boot/sys/sys/_pthreadtypes.h b/usr/src/boot/sys/sys/_pthreadtypes.h
new file mode 100644
index 0000000000..76049ee6d8
--- /dev/null
+++ b/usr/src/boot/sys/sys/_pthreadtypes.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * Copyright (c) 1995-1998 by John Birrell <jb@cimlogic.com.au>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__PTHREADTYPES_H_
+#define _SYS__PTHREADTYPES_H_
+
+/*
+ * Forward structure definitions.
+ *
+ * These are mostly opaque to the user.
+ */
+struct pthread;
+struct pthread_attr;
+struct pthread_cond;
+struct pthread_cond_attr;
+struct pthread_mutex;
+struct pthread_mutex_attr;
+struct pthread_once;
+struct pthread_rwlock;
+struct pthread_rwlockattr;
+struct pthread_barrier;
+struct pthread_barrier_attr;
+struct pthread_spinlock;
+
+/*
+ * Primitive system data type definitions required by P1003.1c.
+ *
+ * Note that P1003.1c specifies that there are no defined comparison
+ * or assignment operators for the types pthread_attr_t, pthread_cond_t,
+ * pthread_condattr_t, pthread_mutex_t, pthread_mutexattr_t.
+ */
+#ifndef _PTHREAD_T_DECLARED
+typedef struct pthread *pthread_t;
+#define _PTHREAD_T_DECLARED
+#endif
+typedef struct pthread_attr *pthread_attr_t;
+typedef struct pthread_mutex *pthread_mutex_t;
+typedef struct pthread_mutex_attr *pthread_mutexattr_t;
+typedef struct pthread_cond *pthread_cond_t;
+typedef struct pthread_cond_attr *pthread_condattr_t;
+typedef int pthread_key_t;
+typedef struct pthread_once pthread_once_t;
+typedef struct pthread_rwlock *pthread_rwlock_t;
+typedef struct pthread_rwlockattr *pthread_rwlockattr_t;
+typedef struct pthread_barrier *pthread_barrier_t;
+typedef struct pthread_barrierattr *pthread_barrierattr_t;
+typedef struct pthread_spinlock *pthread_spinlock_t;
+
+/*
+ * Additional type definitions:
+ *
+ * Note that P1003.1c reserves the prefixes pthread_ and PTHREAD_ for
+ * use in header symbols.
+ */
+typedef void *pthread_addr_t;
+typedef void *(*pthread_startroutine_t)(void *);
+
+/*
+ * Once definitions.
+ */
+struct pthread_once {
+ int state;
+ pthread_mutex_t mutex;
+};
+
+#endif /* ! _SYS__PTHREADTYPES_H_ */
diff --git a/usr/src/boot/sys/sys/_rwlock.h b/usr/src/boot/sys/sys/_rwlock.h
new file mode 100644
index 0000000000..82c911389b
--- /dev/null
+++ b/usr/src/boot/sys/sys/_rwlock.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2006 John Baldwin <jhb@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__RWLOCK_H_
+#define _SYS__RWLOCK_H_
+
+#include <machine/param.h>
+
+/*
+ * Reader/writer lock.
+ *
+ * All reader/writer lock implementations must always have a member
+ * called rw_lock. Other locking primitive structures are not allowed to
+ * use this name for their members.
+ * If this rule needs to change, the bits in the reader/writer lock
+ * implementation must be modified appropriately.
+ */
+struct rwlock {
+ struct lock_object lock_object;
+ volatile uintptr_t rw_lock;
+};
+
+/*
+ * Members of struct rwlock_padalign must mirror members of struct rwlock.
+ * rwlock_padalign rwlocks can use the rwlock(9) API transparently without
+ * modification.
+ * Pad-aligned rwlocks used within structures should generally be the
+ * first member of the struct. Otherwise, the compiler can generate
+ * additional padding for the struct to keep a correct alignment for
+ * the rwlock.
+ */
+struct rwlock_padalign {
+ struct lock_object lock_object;
+ volatile uintptr_t rw_lock;
+} __aligned(CACHE_LINE_SIZE);
+
+#endif /* !_SYS__RWLOCK_H_ */
diff --git a/usr/src/boot/sys/sys/_sigset.h b/usr/src/boot/sys/sys/_sigset.h
new file mode 100644
index 0000000000..06826701f7
--- /dev/null
+++ b/usr/src/boot/sys/sys/_sigset.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)signal.h 8.4 (Berkeley) 5/4/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__SIGSET_H_
+#define _SYS__SIGSET_H_
+
+/*
+ * sigset_t macros.
+ */
+#define _SIG_WORDS 4
+#define _SIG_MAXSIG 128
+#define _SIG_IDX(sig) ((sig) - 1)
+#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5)
+#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31))
+#define _SIG_VALID(sig) ((sig) <= _SIG_MAXSIG && (sig) > 0)
+
+typedef struct __sigset {
+ __uint32_t __bits[_SIG_WORDS];
+} __sigset_t;
+
+#if defined(_KERNEL) && defined(COMPAT_43)
+typedef unsigned int osigset_t;
+#endif
+
+#endif /* !_SYS__SIGSET_H_ */
diff --git a/usr/src/boot/sys/sys/_sockaddr_storage.h b/usr/src/boot/sys/sys/_sockaddr_storage.h
new file mode 100644
index 0000000000..5c0048b56b
--- /dev/null
+++ b/usr/src/boot/sys/sys/_sockaddr_storage.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)socket.h 8.4 (Berkeley) 2/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__SOCKADDR_STORAGE_H_
+#define _SYS__SOCKADDR_STORAGE_H_
+
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE 128U
+#define _SS_ALIGNSIZE (sizeof(__int64_t))
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) - \
+ sizeof(sa_family_t))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) - \
+ sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+ unsigned char ss_len; /* address length */
+ sa_family_t ss_family; /* address family */
+ char __ss_pad1[_SS_PAD1SIZE];
+ __int64_t __ss_align; /* force desired struct alignment */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
+
+#endif /* !_SYS__SOCKADDR_STORAGE_H_ */
diff --git a/usr/src/boot/sys/sys/_stdint.h b/usr/src/boot/sys/sys/_stdint.h
new file mode 100644
index 0000000000..a0fe0ad1fa
--- /dev/null
+++ b/usr/src/boot/sys/sys/_stdint.h
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2011 David E. O'Brien <obrien@FreeBSD.org>
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__STDINT_H_
+#define _SYS__STDINT_H_
+
+#ifndef _INT8_T_DECLARED
+typedef __int8_t int8_t;
+#define _INT8_T_DECLARED
+#endif
+
+#ifndef _INT16_T_DECLARED
+typedef __int16_t int16_t;
+#define _INT16_T_DECLARED
+#endif
+
+#ifndef _INT32_T_DECLARED
+typedef __int32_t int32_t;
+#define _INT32_T_DECLARED
+#endif
+
+#ifndef _INT64_T_DECLARED
+typedef __int64_t int64_t;
+#define _INT64_T_DECLARED
+#endif
+
+#ifndef _UINT8_T_DECLARED
+typedef __uint8_t uint8_t;
+#define _UINT8_T_DECLARED
+#endif
+
+#ifndef _UINT16_T_DECLARED
+typedef __uint16_t uint16_t;
+#define _UINT16_T_DECLARED
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _UINT64_T_DECLARED
+typedef __uint64_t uint64_t;
+#define _UINT64_T_DECLARED
+#endif
+
+#ifndef _INTPTR_T_DECLARED
+typedef __intptr_t intptr_t;
+#define _INTPTR_T_DECLARED
+#endif
+#ifndef _UINTPTR_T_DECLARED
+typedef __uintptr_t uintptr_t;
+#define _UINTPTR_T_DECLARED
+#endif
+#ifndef _INTMAX_T_DECLARED
+typedef __intmax_t intmax_t;
+#define _INTMAX_T_DECLARED
+#endif
+#ifndef _UINTMAX_T_DECLARED
+typedef __uintmax_t uintmax_t;
+#define _UINTMAX_T_DECLARED
+#endif
+
+#endif /* !_SYS__STDINT_H_ */
diff --git a/usr/src/boot/sys/sys/_timespec.h b/usr/src/boot/sys/sys/_timespec.h
new file mode 100644
index 0000000000..d51559c2a4
--- /dev/null
+++ b/usr/src/boot/sys/sys/_timespec.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)time.h 8.5 (Berkeley) 5/4/95
+ * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TIMESPEC_H_
+#define _SYS__TIMESPEC_H_
+
+#include <sys/_types.h>
+
+#ifndef _TIME_T_DECLARED
+typedef __time_t time_t;
+#define _TIME_T_DECLARED
+#endif
+
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
+};
+
+#endif /* !_SYS__TIMESPEC_H_ */
diff --git a/usr/src/boot/sys/sys/_timeval.h b/usr/src/boot/sys/sys/_timeval.h
new file mode 100644
index 0000000000..a35d8a9325
--- /dev/null
+++ b/usr/src/boot/sys/sys/_timeval.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TIMEVAL_H_
+#define _SYS__TIMEVAL_H_
+
+#include <sys/_types.h>
+
+#ifndef _SUSECONDS_T_DECLARED
+typedef __suseconds_t suseconds_t;
+#define _SUSECONDS_T_DECLARED
+#endif
+
+#ifndef _TIME_T_DECLARED
+typedef __time_t time_t;
+#define _TIME_T_DECLARED
+#endif
+
+/*
+ * Structure returned by gettimeofday(2) system call, and used in other calls.
+ */
+struct timeval {
+ time_t tv_sec; /* seconds */
+ suseconds_t tv_usec; /* and microseconds */
+};
+
+#endif /* !_SYS__TIMEVAL_H_ */
diff --git a/usr/src/boot/sys/sys/_types.h b/usr/src/boot/sys/sys/_types.h
new file mode 100644
index 0000000000..3b3c16d368
--- /dev/null
+++ b/usr/src/boot/sys/sys/_types.h
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TYPES_H_
+#define _SYS__TYPES_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+/*
+ * Standard type definitions.
+ */
+typedef __int32_t __blksize_t; /* file block size */
+typedef __int64_t __blkcnt_t; /* file block count */
+typedef __int32_t __clockid_t; /* clock_gettime()... */
+typedef __uint32_t __fflags_t; /* file flags */
+typedef __uint64_t __fsblkcnt_t;
+typedef __uint64_t __fsfilcnt_t;
+typedef __uint32_t __gid_t;
+typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */
+typedef __uint32_t __ino_t; /* inode number */
+typedef long __key_t; /* IPC key (for Sys V IPC) */
+typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */
+typedef __uint16_t __mode_t; /* permissions */
+typedef int __accmode_t; /* access permissions */
+typedef int __nl_item;
+typedef __uint16_t __nlink_t; /* link count */
+typedef __int64_t __off_t; /* file offset */
+typedef __int32_t __pid_t; /* process [group] */
+typedef __int64_t __rlim_t; /* resource limit - intentionally */
+ /* signed, because of legacy code */
+ /* that uses -1 for RLIM_INFINITY */
+typedef __uint8_t __sa_family_t;
+typedef __uint32_t __socklen_t;
+typedef long __suseconds_t; /* microseconds (signed) */
+typedef struct __timer *__timer_t; /* timer_gettime()... */
+typedef struct __mq *__mqd_t; /* mq_open()... */
+typedef __uint32_t __uid_t;
+typedef unsigned int __useconds_t; /* microseconds (unsigned) */
+typedef int __cpuwhich_t; /* which parameter for cpuset. */
+typedef int __cpulevel_t; /* level parameter for cpuset. */
+typedef int __cpusetid_t; /* cpuset identifier. */
+
+/*
+ * Unusual type definitions.
+ */
+/*
+ * rune_t is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use __ct_rune_t instead of int.
+ *
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale. Use wchar_t. wint_t and
+ * rune_t must be the same type. Also, wint_t should be able to hold all
+ * members of the largest character set plus one extra value (WEOF), and
+ * must be at least 16 bits.
+ */
+typedef int __ct_rune_t; /* arg type for ctype funcs */
+typedef __ct_rune_t __rune_t; /* rune_t (see above) */
+typedef __ct_rune_t __wint_t; /* wint_t (see above) */
+
+/* Clang already provides these types as built-ins, but only in C++ mode. */
+#if !defined(__clang__) || !defined(__cplusplus)
+typedef __uint_least16_t __char16_t;
+typedef __uint_least32_t __char32_t;
+#endif
+/* In C++11, char16_t and char32_t are built-in types. */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define _CHAR16_T_DECLARED
+#define _CHAR32_T_DECLARED
+#endif
+
+typedef __uint32_t __dev_t; /* device number */
+
+typedef __uint32_t __fixpt_t; /* fixed point number */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state during multibyte
+ * stream conversions.
+ */
+typedef union {
+ char __mbstate8[128];
+ __int64_t _mbstateL; /* for alignment */
+} __mbstate_t;
+
+typedef unsigned long __rman_res_t;
+
+#endif /* !_SYS__TYPES_H_ */
diff --git a/usr/src/boot/sys/sys/bitstring.h b/usr/src/boot/sys/sys/bitstring.h
new file mode 100644
index 0000000000..125ef51d88
--- /dev/null
+++ b/usr/src/boot/sys/sys/bitstring.h
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Vixie.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_BITSTRING_H_
+#define _SYS_BITSTRING_H_
+
+typedef unsigned char bitstr_t;
+
+/* internal macros */
+ /* byte of the bitstring bit is in */
+#define _bit_byte(bit) \
+ ((bit) >> 3)
+
+ /* mask for the bit within its byte */
+#define _bit_mask(bit) \
+ (1 << ((bit)&0x7))
+
+/* external macros */
+ /* bytes in a bitstring of nbits bits */
+#define bitstr_size(nbits) \
+ (((nbits) + 7) >> 3)
+
+ /* allocate a bitstring */
+#define bit_alloc(nbits) \
+ (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
+
+ /* allocate a bitstring on the stack */
+#define bit_decl(name, nbits) \
+ ((name)[bitstr_size(nbits)])
+
+ /* is bit N of bitstring name set? */
+#define bit_test(name, bit) \
+ ((name)[_bit_byte(bit)] & _bit_mask(bit))
+
+ /* set bit N of bitstring name */
+#define bit_set(name, bit) \
+ ((name)[_bit_byte(bit)] |= _bit_mask(bit))
+
+ /* clear bit N of bitstring name */
+#define bit_clear(name, bit) \
+ ((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
+
+ /* clear bits start ... stop in bitstring */
+#define bit_nclear(name, start, stop) do { \
+ register bitstr_t *_name = (name); \
+ register int _start = (start), _stop = (stop); \
+ register int _startbyte = _bit_byte(_start); \
+ register int _stopbyte = _bit_byte(_stop); \
+ if (_startbyte == _stopbyte) { \
+ _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
+ (0xff << ((_stop&0x7) + 1))); \
+ } else { \
+ _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
+ while (++_startbyte < _stopbyte) \
+ _name[_startbyte] = 0; \
+ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
+ } \
+} while (0)
+
+ /* set bits start ... stop in bitstring */
+#define bit_nset(name, start, stop) do { \
+ register bitstr_t *_name = (name); \
+ register int _start = (start), _stop = (stop); \
+ register int _startbyte = _bit_byte(_start); \
+ register int _stopbyte = _bit_byte(_stop); \
+ if (_startbyte == _stopbyte) { \
+ _name[_startbyte] |= ((0xff << (_start&0x7)) & \
+ (0xff >> (7 - (_stop&0x7)))); \
+ } else { \
+ _name[_startbyte] |= 0xff << ((_start)&0x7); \
+ while (++_startbyte < _stopbyte) \
+ _name[_startbyte] = 0xff; \
+ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
+ } \
+} while (0)
+
+ /* find first bit clear in name */
+#define bit_ffc(name, nbits, value) do { \
+ register bitstr_t *_name = (name); \
+ register int _byte, _nbits = (nbits); \
+ register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
+ if (_nbits > 0) \
+ for (_byte = 0; _byte <= _stopbyte; ++_byte) \
+ if (_name[_byte] != 0xff) { \
+ bitstr_t _lb; \
+ _value = _byte << 3; \
+ for (_lb = _name[_byte]; (_lb&0x1); \
+ ++_value, _lb >>= 1); \
+ break; \
+ } \
+ if (_value >= nbits) \
+ _value = -1; \
+ *(value) = _value; \
+} while (0)
+
+ /* find first bit set in name */
+#define bit_ffs(name, nbits, value) do { \
+ register bitstr_t *_name = (name); \
+ register int _byte, _nbits = (nbits); \
+ register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
+ if (_nbits > 0) \
+ for (_byte = 0; _byte <= _stopbyte; ++_byte) \
+ if (_name[_byte]) { \
+ bitstr_t _lb; \
+ _value = _byte << 3; \
+ for (_lb = _name[_byte]; !(_lb&0x1); \
+ ++_value, _lb >>= 1); \
+ break; \
+ } \
+ if (_value >= nbits) \
+ _value = -1; \
+ *(value) = _value; \
+} while (0)
+
+#endif /* !_SYS_BITSTRING_H_ */
diff --git a/usr/src/boot/sys/sys/boot.h b/usr/src/boot/sys/sys/boot.h
new file mode 100644
index 0000000000..4a2fa93093
--- /dev/null
+++ b/usr/src/boot/sys/sys/boot.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_BOOT_H_
+#define _SYS_BOOT_H_
+
+/*
+ * Return a 'boothowto' value corresponding to the kernel arguments in
+ * (kargs) and any relevant environment variables.
+ */
+static struct
+{
+ const char *ev;
+ int mask;
+} howto_names[] = {
+ { "boot_askname", RB_ASKNAME},
+ { "boot_cdrom", RB_CDROM},
+ { "boot_ddb", RB_KDB},
+ { "boot_dfltroot", RB_DFLTROOT},
+ { "boot_gdb", RB_GDB},
+ { "boot_multicons", RB_MULTIPLE},
+ { "boot_mute", RB_MUTE},
+ { "boot_pause", RB_PAUSE},
+ { "boot_serial", RB_SERIAL},
+ { "boot_single", RB_SINGLE},
+ { "boot_verbose", RB_VERBOSE},
+ { NULL, 0}
+};
+
+#endif /* !_SYS_BOOT_H_ */
diff --git a/usr/src/boot/sys/sys/bsm/audit.h b/usr/src/boot/sys/sys/bsm/audit.h
new file mode 100644
index 0000000000..625e816da5
--- /dev/null
+++ b/usr/src/boot/sys/sys/bsm/audit.h
@@ -0,0 +1,328 @@
+/*-
+ * Copyright (c) 2005-2009 Apple Inc.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#10
+ * $FreeBSD$
+ */
+
+#ifndef _BSM_AUDIT_H
+#define _BSM_AUDIT_H
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#define AUDIT_RECORD_MAGIC 0x828a0f1b
+#define MAX_AUDIT_RECORDS 20
+#define MAXAUDITDATA (0x8000 - 1)
+#define MAX_AUDIT_RECORD_SIZE MAXAUDITDATA
+#define MIN_AUDIT_FILE_SIZE (512 * 1024)
+
+/*
+ * Minimum noumber of free blocks on the filesystem containing the audit
+ * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0
+ * as the kernel does an unsigned compare, plus we want to leave a few blocks
+ * free so userspace can terminate the log, etc.
+ */
+#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4
+
+/*
+ * Triggers for the audit daemon.
+ */
+#define AUDIT_TRIGGER_MIN 1
+#define AUDIT_TRIGGER_LOW_SPACE 1 /* Below low watermark. */
+#define AUDIT_TRIGGER_ROTATE_KERNEL 2 /* Kernel requests rotate. */
+#define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */
+#define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */
+#define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */
+#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */
+#define AUDIT_TRIGGER_INITIALIZE 7 /* User initialize of auditd. */
+#define AUDIT_TRIGGER_EXPIRE_TRAILS 8 /* User expiration of trails. */
+#define AUDIT_TRIGGER_MAX 8
+
+/*
+ * The special device filename (FreeBSD).
+ */
+#define AUDITDEV_FILENAME "audit"
+#define AUDIT_TRIGGER_FILE ("/dev/" AUDITDEV_FILENAME)
+
+/*
+ * Pre-defined audit IDs
+ */
+#define AU_DEFAUDITID (uid_t)(-1)
+#define AU_DEFAUDITSID 0
+#define AU_ASSIGN_ASID -1
+
+/*
+ * IPC types.
+ */
+#define AT_IPC_MSG ((u_char)1) /* Message IPC id. */
+#define AT_IPC_SEM ((u_char)2) /* Semaphore IPC id. */
+#define AT_IPC_SHM ((u_char)3) /* Shared mem IPC id. */
+
+/*
+ * Audit conditions.
+ */
+#define AUC_UNSET 0
+#define AUC_AUDITING 1
+#define AUC_NOAUDIT 2
+#define AUC_DISABLED -1
+
+/*
+ * auditon(2) commands.
+ */
+#define A_OLDGETPOLICY 2
+#define A_OLDSETPOLICY 3
+#define A_GETKMASK 4
+#define A_SETKMASK 5
+#define A_OLDGETQCTRL 6
+#define A_OLDSETQCTRL 7
+#define A_GETCWD 8
+#define A_GETCAR 9
+#define A_GETSTAT 12
+#define A_SETSTAT 13
+#define A_SETUMASK 14
+#define A_SETSMASK 15
+#define A_OLDGETCOND 20
+#define A_OLDSETCOND 21
+#define A_GETCLASS 22
+#define A_SETCLASS 23
+#define A_GETPINFO 24
+#define A_SETPMASK 25
+#define A_SETFSIZE 26
+#define A_GETFSIZE 27
+#define A_GETPINFO_ADDR 28
+#define A_GETKAUDIT 29
+#define A_SETKAUDIT 30
+#define A_SENDTRIGGER 31
+#define A_GETSINFO_ADDR 32
+#define A_GETPOLICY 33
+#define A_SETPOLICY 34
+#define A_GETQCTRL 35
+#define A_SETQCTRL 36
+#define A_GETCOND 37
+#define A_SETCOND 38
+
+/*
+ * Audit policy controls.
+ */
+#define AUDIT_CNT 0x0001
+#define AUDIT_AHLT 0x0002
+#define AUDIT_ARGV 0x0004
+#define AUDIT_ARGE 0x0008
+#define AUDIT_SEQ 0x0010
+#define AUDIT_WINDATA 0x0020
+#define AUDIT_USER 0x0040
+#define AUDIT_GROUP 0x0080
+#define AUDIT_TRAIL 0x0100
+#define AUDIT_PATH 0x0200
+#define AUDIT_SCNT 0x0400
+#define AUDIT_PUBLIC 0x0800
+#define AUDIT_ZONENAME 0x1000
+#define AUDIT_PERZONE 0x2000
+
+/*
+ * Default audit queue control parameters.
+ */
+#define AQ_HIWATER 100
+#define AQ_MAXHIGH 10000
+#define AQ_LOWATER 10
+#define AQ_BUFSZ MAXAUDITDATA
+#define AQ_MAXBUFSZ 1048576
+
+/*
+ * Default minimum percentage free space on file system.
+ */
+#define AU_FS_MINFREE 20
+
+/*
+ * Type definitions used indicating the length of variable length addresses
+ * in tokens containing addresses, such as header fields.
+ */
+#define AU_IPv4 4
+#define AU_IPv6 16
+
+__BEGIN_DECLS
+
+typedef uid_t au_id_t;
+typedef pid_t au_asid_t;
+typedef u_int16_t au_event_t;
+typedef u_int16_t au_emod_t;
+typedef u_int32_t au_class_t;
+typedef u_int64_t au_asflgs_t __attribute__ ((aligned (8)));
+
+struct au_tid {
+ dev_t port;
+ u_int32_t machine;
+};
+typedef struct au_tid au_tid_t;
+
+struct au_tid_addr {
+ dev_t at_port;
+ u_int32_t at_type;
+ u_int32_t at_addr[4];
+};
+typedef struct au_tid_addr au_tid_addr_t;
+
+struct au_mask {
+ unsigned int am_success; /* Success bits. */
+ unsigned int am_failure; /* Failure bits. */
+};
+typedef struct au_mask au_mask_t;
+
+struct auditinfo {
+ au_id_t ai_auid; /* Audit user ID. */
+ au_mask_t ai_mask; /* Audit masks. */
+ au_tid_t ai_termid; /* Terminal ID. */
+ au_asid_t ai_asid; /* Audit session ID. */
+};
+typedef struct auditinfo auditinfo_t;
+
+struct auditinfo_addr {
+ au_id_t ai_auid; /* Audit user ID. */
+ au_mask_t ai_mask; /* Audit masks. */
+ au_tid_addr_t ai_termid; /* Terminal ID. */
+ au_asid_t ai_asid; /* Audit session ID. */
+ au_asflgs_t ai_flags; /* Audit session flags. */
+};
+typedef struct auditinfo_addr auditinfo_addr_t;
+
+struct auditpinfo {
+ pid_t ap_pid; /* ID of target process. */
+ au_id_t ap_auid; /* Audit user ID. */
+ au_mask_t ap_mask; /* Audit masks. */
+ au_tid_t ap_termid; /* Terminal ID. */
+ au_asid_t ap_asid; /* Audit session ID. */
+};
+typedef struct auditpinfo auditpinfo_t;
+
+struct auditpinfo_addr {
+ pid_t ap_pid; /* ID of target process. */
+ au_id_t ap_auid; /* Audit user ID. */
+ au_mask_t ap_mask; /* Audit masks. */
+ au_tid_addr_t ap_termid; /* Terminal ID. */
+ au_asid_t ap_asid; /* Audit session ID. */
+ au_asflgs_t ap_flags; /* Audit session flags. */
+};
+typedef struct auditpinfo_addr auditpinfo_addr_t;
+
+struct au_session {
+ auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */
+ au_mask_t as_mask; /* Process Audit Masks. */
+};
+typedef struct au_session au_session_t;
+
+/*
+ * Contents of token_t are opaque outside of libbsm.
+ */
+typedef struct au_token token_t;
+
+/*
+ * Kernel audit queue control parameters:
+ * Default: Maximum:
+ * aq_hiwater: AQ_HIWATER (100) AQ_MAXHIGH (10000)
+ * aq_lowater: AQ_LOWATER (10) <aq_hiwater
+ * aq_bufsz: AQ_BUFSZ (32767) AQ_MAXBUFSZ (1048576)
+ * aq_delay: 20 20000 (not used)
+ */
+struct au_qctrl {
+ int aq_hiwater; /* Max # of audit recs in queue when */
+ /* threads with new ARs get blocked. */
+
+ int aq_lowater; /* # of audit recs in queue when */
+ /* blocked threads get unblocked. */
+
+ int aq_bufsz; /* Max size of audit record for audit(2). */
+ int aq_delay; /* Queue delay (not used). */
+ int aq_minfree; /* Minimum filesystem percent free space. */
+};
+typedef struct au_qctrl au_qctrl_t;
+
+/*
+ * Structure for the audit statistics.
+ */
+struct audit_stat {
+ unsigned int as_version;
+ unsigned int as_numevent;
+ int as_generated;
+ int as_nonattrib;
+ int as_kernel;
+ int as_audit;
+ int as_auditctl;
+ int as_enqueue;
+ int as_written;
+ int as_wblocked;
+ int as_rblocked;
+ int as_dropped;
+ int as_totalsize;
+ unsigned int as_memused;
+};
+typedef struct audit_stat au_stat_t;
+
+/*
+ * Structure for the audit file statistics.
+ */
+struct audit_fstat {
+ u_int64_t af_filesz;
+ u_int64_t af_currsz;
+};
+typedef struct audit_fstat au_fstat_t;
+
+/*
+ * Audit to event class mapping.
+ */
+struct au_evclass_map {
+ au_event_t ec_number;
+ au_class_t ec_class;
+};
+typedef struct au_evclass_map au_evclass_map_t;
+
+/*
+ * Audit system calls.
+ */
+#if !defined(_KERNEL) && !defined(KERNEL)
+int audit(const void *, int);
+int auditon(int, void *, int);
+int auditctl(const char *);
+int getauid(au_id_t *);
+int setauid(const au_id_t *);
+int getaudit(struct auditinfo *);
+int setaudit(const struct auditinfo *);
+int getaudit_addr(struct auditinfo_addr *, int);
+int setaudit_addr(const struct auditinfo_addr *, int);
+
+#ifdef __APPLE_API_PRIVATE
+#include <mach/port.h>
+mach_port_name_t audit_session_self(void);
+au_asid_t audit_session_join(mach_port_name_t port);
+#endif /* __APPLE_API_PRIVATE */
+
+#endif /* defined(_KERNEL) || defined(KERNEL) */
+
+__END_DECLS
+
+#endif /* !_BSM_AUDIT_H */
diff --git a/usr/src/boot/sys/sys/cdefs.h b/usr/src/boot/sys/sys/cdefs.h
new file mode 100644
index 0000000000..530359f6c1
--- /dev/null
+++ b/usr/src/boot/sys/sys/cdefs.h
@@ -0,0 +1,858 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)cdefs.h 8.8 (Berkeley) 1/9/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+
+/*
+ * Testing against Clang-specific extensions.
+ */
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+#ifndef __has_extension
+#define __has_extension __has_feature
+#endif
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#ifndef __has_include
+#define __has_include(x) 0
+#endif
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS }
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+
+/*
+ * This code has been put in place to help reduce the addition of
+ * compiler specific defines in FreeBSD code. It helps to aid in
+ * having a compiler-agnostic source tree.
+ */
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+
+#if __GNUC__ >= 3 || defined(__INTEL_COMPILER)
+#define __GNUCLIKE_ASM 3
+#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS
+#else
+#define __GNUCLIKE_ASM 2
+#endif
+#define __GNUCLIKE___TYPEOF 1
+#define __GNUCLIKE___OFFSETOF 1
+#define __GNUCLIKE___SECTION 1
+
+#ifndef __INTEL_COMPILER
+#define __GNUCLIKE_CTOR_SECTION_HANDLING 1
+#endif
+
+#define __GNUCLIKE_BUILTIN_CONSTANT_P 1
+#if defined(__INTEL_COMPILER) && defined(__cplusplus) && \
+ __INTEL_COMPILER < 800
+#undef __GNUCLIKE_BUILTIN_CONSTANT_P
+#endif
+
+#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3)
+#define __GNUCLIKE_BUILTIN_VARARGS 1
+#define __GNUCLIKE_BUILTIN_STDARG 1
+#define __GNUCLIKE_BUILTIN_VAALIST 1
+#endif
+
+#if defined(__GNUC__)
+#define __GNUC_VA_LIST_COMPATIBILITY 1
+#endif
+
+/*
+ * Compiler memory barriers, specific to gcc and clang.
+ */
+#if defined(__GNUC__)
+#define __compiler_membar() __asm __volatile(" " : : : "memory")
+#endif
+
+#ifndef __INTEL_COMPILER
+#define __GNUCLIKE_BUILTIN_NEXT_ARG 1
+#define __GNUCLIKE_MATH_BUILTIN_RELOPS
+#endif
+
+#define __GNUCLIKE_BUILTIN_MEMCPY 1
+
+/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */
+#define __CC_SUPPORTS_INLINE 1
+#define __CC_SUPPORTS___INLINE 1
+#define __CC_SUPPORTS___INLINE__ 1
+
+#define __CC_SUPPORTS___FUNC__ 1
+#define __CC_SUPPORTS_WARNING 1
+
+#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */
+
+#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1
+
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+/*
+ * Macro to test if we're using a specific version of gcc or later.
+ */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define __GNUC_PREREQ__(ma, mi) \
+ (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
+#else
+#define __GNUC_PREREQ__(ma, mi) 0
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
+ * mode -- there must be no spaces between its arguments, and for nested
+ * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also
+ * concatenate double-quoted strings produced by the __STRING macro, but
+ * this only works with ANSI C.
+ *
+ * __XSTRING is like __STRING, but it expands any macros in its argument
+ * first. It is only available with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT1(x,y) x ## y
+#define __CONCAT(x,y) __CONCAT1(x,y)
+#define __STRING(x) #x /* stringify without expanding x */
+#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
+
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
+#if defined(__cplusplus)
+#define __inline inline /* convert to C++ keyword */
+#else
+#if !(defined(__CC_SUPPORTS___INLINE))
+#define __inline /* delete GCC keyword */
+#endif /* ! __CC_SUPPORTS___INLINE */
+#endif /* !__cplusplus */
+
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+#if !defined(__CC_SUPPORTS___INLINE)
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * When using a compiler other than gcc, programs using the ANSI C keywords
+ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+ * When using "gcc -traditional", we assume that this is the intent; if
+ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+ */
+#ifndef NO_ANSI_KEYWORDS
+#define const /* delete ANSI C keywords */
+#define inline
+#define signed
+#define volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif /* !__CC_SUPPORTS___INLINE */
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * Compiler-dependent macros to help declare dead (non-returning) and
+ * pure (no side effects) functions, and unused variables. They are
+ * null except for versions of gcc that are known to support the features
+ * properly (old versions of gcc-2 supported the dead and pure features
+ * in a different (wrong) way). If we do not provide an implementation
+ * for a given compiler, let the compile fail if it is told to use
+ * a feature that we cannot live without.
+ */
+#ifdef lint
+#define __dead2
+#define __pure2
+#define __unused
+#define __packed
+#define __aligned(x)
+#define __alloc_align(x)
+#define __alloc_size(x)
+#define __section(x)
+#define __weak_symbol
+#else
+#define __weak_symbol __attribute__((__weak__))
+#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
+#define __dead2
+#define __pure2
+#define __unused
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
+#define __dead2 __attribute__((__noreturn__))
+#define __pure2 __attribute__((__const__))
+#define __unused
+/* XXX Find out what to do for __packed, __aligned and __section */
+#endif
+#if __GNUC_PREREQ__(2, 7) || defined(__INTEL_COMPILER)
+#define __dead2 __attribute__((__noreturn__))
+#define __pure2 __attribute__((__const__))
+#define __unused __attribute__((__unused__))
+#define __used __attribute__((__used__))
+#define __packed __attribute__((__packed__))
+#define __aligned(x) __attribute__((__aligned__(x)))
+#define __section(x) __attribute__((__section__(x)))
+#endif
+#if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__)
+#define __alloc_size(x) __attribute__((__alloc_size__(x)))
+#else
+#define __alloc_size(x)
+#endif
+#if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__)
+#define __alloc_align(x) __attribute__((__alloc_align__(x)))
+#else
+#define __alloc_align(x)
+#endif
+#endif /* lint */
+
+#if !__GNUC_PREREQ__(2, 95)
+#define __alignof(x) __offsetof(struct { char __a; x __b; }, __b)
+#endif
+
+/*
+ * Keywords added in C11.
+ */
+
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L || defined(lint)
+
+#if !__has_extension(c_alignas)
+#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ __has_extension(cxx_alignas)
+#define _Alignas(x) alignas(x)
+#else
+/* XXX: Only emulates _Alignas(constant-expression); not _Alignas(type-name). */
+#define _Alignas(x) __aligned(x)
+#endif
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define _Alignof(x) alignof(x)
+#else
+#define _Alignof(x) __alignof(x)
+#endif
+
+#if !__has_extension(c_atomic) && !__has_extension(cxx_atomic)
+/*
+ * No native support for _Atomic(). Place object in structure to prevent
+ * most forms of direct non-atomic access.
+ */
+#define _Atomic(T) struct { T volatile __val; }
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define _Noreturn [[noreturn]]
+#else
+#define _Noreturn __dead2
+#endif
+
+#if !__has_extension(c_static_assert)
+#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ __has_extension(cxx_static_assert)
+#define _Static_assert(x, y) static_assert(x, y)
+#elif __GNUC_PREREQ__(4,6)
+/* Nothing, gcc 4.6 and higher has _Static_assert built-in */
+#elif defined(__COUNTER__)
+#define _Static_assert(x, y) __Static_assert(x, __COUNTER__)
+#define __Static_assert(x, y) ___Static_assert(x, y)
+#define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1] \
+ __unused
+#else
+#define _Static_assert(x, y) struct __hack
+#endif
+#endif
+
+#if !__has_extension(c_thread_local)
+/*
+ * XXX: Some compilers (Clang 3.3, GCC 4.7) falsely announce C++11 mode
+ * without actually supporting the thread_local keyword. Don't check for
+ * the presence of C++11 when defining _Thread_local.
+ */
+#if /* (defined(__cplusplus) && __cplusplus >= 201103L) || */ \
+ __has_extension(cxx_thread_local)
+#define _Thread_local thread_local
+#else
+#define _Thread_local __thread
+#endif
+#endif
+
+#endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */
+
+/*
+ * Emulation of C11 _Generic(). Unlike the previously defined C11
+ * keywords, it is not possible to implement this using exactly the same
+ * syntax. Therefore implement something similar under the name
+ * __generic(). Unlike _Generic(), this macro can only distinguish
+ * between a single type, so it requires nested invocations to
+ * distinguish multiple cases.
+ */
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+ __has_extension(c_generic_selections)
+#define __generic(expr, t, yes, no) \
+ _Generic(expr, t: yes, default: no)
+#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
+#define __generic(expr, t, yes, no) \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(__typeof(expr), t), yes, no)
+#endif
+
+#if __GNUC_PREREQ__(2, 96)
+#define __malloc_like __attribute__((__malloc__))
+#define __pure __attribute__((__pure__))
+#else
+#define __malloc_like
+#define __pure
+#endif
+
+#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
+#define __always_inline __attribute__((__always_inline__))
+#else
+#define __always_inline
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define __noinline __attribute__ ((__noinline__))
+#else
+#define __noinline
+#endif
+
+#if __GNUC_PREREQ__(3, 3)
+#define __nonnull(x) __attribute__((__nonnull__(x)))
+#define __nonnull_all __attribute__((__nonnull__))
+#else
+#define __nonnull(x)
+#define __nonnull_all
+#endif
+
+#if __GNUC_PREREQ__(3, 4)
+#define __fastcall __attribute__((__fastcall__))
+#define __result_use_check __attribute__((__warn_unused_result__))
+#else
+#define __fastcall
+#define __result_use_check
+#endif
+
+#if __GNUC_PREREQ__(4, 1)
+#define __returns_twice __attribute__((__returns_twice__))
+#else
+#define __returns_twice
+#endif
+
+#if __GNUC_PREREQ__(4, 6) || __has_builtin(__builtin_unreachable)
+#define __unreachable() __builtin_unreachable()
+#else
+#define __unreachable() ((void)0)
+#endif
+
+/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
+#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
+#define __func__ NULL
+#endif
+
+#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
+#define __LONG_LONG_SUPPORTED
+#endif
+
+/* C++11 exposes a load of C99 stuff */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define __LONG_LONG_SUPPORTED
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+#endif
+
+/*
+ * GCC 2.95 provides `__restrict' as an extension to C90 to support the
+ * C99-specific `restrict' type qualifier. We happen to use `__restrict' as
+ * a way to define the `restrict' type qualifier without disturbing older
+ * software that is unaware of C99 keywords.
+ */
+#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint)
+#define __restrict
+#else
+#define __restrict restrict
+#endif
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to utilize this
+ * compiler feature. Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ * * Generally, __predict_false() error condition checks (unless
+ * you have some _strong_ reason to do otherwise, in which case
+ * document it), and/or __predict_true() `no-error' condition
+ * checks, assuming you want to optimize for the no-error case.
+ *
+ * * Other than that, if you don't know the likelihood of a test
+ * succeeding from empirical or other `hard' evidence, don't
+ * make predictions.
+ *
+ * * These are meant to be used in places that are run `a lot'.
+ * It is wasteful to make predictions in code that is run
+ * seldomly (e.g. at subsystem initialization time) as the
+ * basic block reordering that this affects can often generate
+ * larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define __predict_true(exp) __builtin_expect((exp), 1)
+#define __predict_false(exp) __builtin_expect((exp), 0)
+#else
+#define __predict_true(exp) (exp)
+#define __predict_false(exp) (exp)
+#endif
+
+#if __GNUC_PREREQ__(4, 0)
+#define __null_sentinel __attribute__((__sentinel__))
+#define __exported __attribute__((__visibility__("default")))
+#define __hidden __attribute__((__visibility__("hidden")))
+#else
+#define __null_sentinel
+#define __exported
+#define __hidden
+#endif
+
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#if __GNUC_PREREQ__(4, 1)
+#define __offsetof(type, field) __builtin_offsetof(type, field)
+#else
+#ifndef __cplusplus
+#define __offsetof(type, field) \
+ ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+#else
+#define __offsetof(type, field) \
+ (__offsetof__ (reinterpret_cast <__size_t> \
+ (&reinterpret_cast <const volatile char &> \
+ (static_cast<type *> (0)->field))))
+#endif
+#endif
+#define __rangeof(type, start, end) \
+ (__offsetof(type, end) - __offsetof(type, start))
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure. When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#if __GNUC_PREREQ__(3, 1)
+#define __containerof(x, s, m) ({ \
+ const volatile __typeof(((s *)0)->m) *__x = (x); \
+ __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
+})
+#else
+#define __containerof(x, s, m) \
+ __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
+#endif
+
+/*
+ * Compiler-dependent macros to declare that functions take printf-like
+ * or scanf-like arguments. They are null except for versions of gcc
+ * that are known to support the features properly (old versions of gcc-2
+ * didn't permit keeping the keywords out of the application namespace).
+ */
+#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
+#define __printflike(fmtarg, firstvararg)
+#define __scanflike(fmtarg, firstvararg)
+#define __format_arg(fmtarg)
+#define __strfmonlike(fmtarg, firstvararg)
+#define __strftimelike(fmtarg, firstvararg)
+#else
+#define __printflike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#define __scanflike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__scanf__, fmtarg, firstvararg)))
+#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg)))
+#define __strfmonlike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__strfmon__, fmtarg, firstvararg)))
+#define __strftimelike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__strftime__, fmtarg, firstvararg)))
+#endif
+
+/*
+ * FORTIFY_SOURCE, and perhaps other compiler-specific features, require
+ * the use of non-standard inlining. In general we should try to avoid
+ * using these but GCC-compatible compilers tend to support the extensions
+ * well enough to use them in limited cases.
+ */
+#if defined(__GNUC_GNU_INLINE__) || defined(__GNUC_STDC_INLINE__)
+#if __GNUC_PREREQ__(4, 3) || __has_attribute(__artificial__)
+#define __gnu_inline __attribute__((__gnu_inline__, __artificial__))
+#else
+#define __gnu_inline __attribute__((__gnu_inline__))
+#endif /* artificial */
+#else
+#define __gnu_inline
+#endif
+
+/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
+#if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 && \
+ defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define __printf0like(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
+#else
+#define __printf0like(fmtarg, firstvararg)
+#endif
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+#ifndef __INTEL_COMPILER
+#define __strong_reference(sym,aliassym) \
+ extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
+#endif
+#ifdef __STDC__
+#define __weak_reference(sym,alias) \
+ __asm__(".weak " #alias); \
+ __asm__(".equ " #alias ", " #sym)
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning." #sym); \
+ __asm__(".asciz \"" msg "\""); \
+ __asm__(".previous")
+#define __sym_compat(sym,impl,verid) \
+ __asm__(".symver " #impl ", " #sym "@" #verid)
+#define __sym_default(sym,impl,verid) \
+ __asm__(".symver " #impl ", " #sym "@@" #verid)
+#else
+#define __weak_reference(sym,alias) \
+ __asm__(".weak alias"); \
+ __asm__(".equ alias, sym")
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning.sym"); \
+ __asm__(".asciz \"msg\""); \
+ __asm__(".previous")
+#define __sym_compat(sym,impl,verid) \
+ __asm__(".symver impl, sym@verid")
+#define __sym_default(impl,sym,verid) \
+ __asm__(".symver impl, sym@@verid")
+#endif /* __STDC__ */
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+#define __GLOBL1(sym) __asm__(".globl " #sym)
+#define __GLOBL(sym) __GLOBL1(sym)
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"")
+#else
+/*
+ * The following definition might not work well if used in header files,
+ * but it should be better than nothing. If you want a "do nothing"
+ * version, then it should generate some harmless declaration, such as:
+ * #define __IDSTRING(name,string) struct __hack
+ */
+#define __IDSTRING(name,string) static const char name[] __unused = string
+#endif
+
+/*
+ * Embed the rcs id of a source file in the resulting library. Note that in
+ * more recent ELF binutils, we use .ident allowing the ID to be stripped.
+ * Usage:
+ * __FBSDID("$FreeBSD$");
+ */
+#ifndef __FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define __FBSDID(s) struct __hack
+#endif
+#endif
+
+#ifndef __RCSID
+#ifndef NO__RCSID
+#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define __RCSID(s) struct __hack
+#endif
+#endif
+
+#ifndef __RCSID_SOURCE
+#ifndef NO__RCSID_SOURCE
+#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
+#else
+#define __RCSID_SOURCE(s) struct __hack
+#endif
+#endif
+
+#ifndef __SCCSID
+#ifndef NO__SCCSID
+#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
+#else
+#define __SCCSID(s) struct __hack
+#endif
+#endif
+
+#ifndef __COPYRIGHT
+#ifndef NO__COPYRIGHT
+#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+#else
+#define __COPYRIGHT(s) struct __hack
+#endif
+#endif
+
+#ifndef __DECONST
+#define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var))
+#endif
+
+#ifndef __DEVOLATILE
+#define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var))
+#endif
+
+#ifndef __DEQUALIFY
+#define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var))
+#endif
+
+/*-
+ * The following definitions are an extension of the behavior originally
+ * implemented in <sys/_posix.h>, but with a different level of granularity.
+ * POSIX.1 requires that the macros we test be defined before any standard
+ * header file is included.
+ *
+ * Here's a quick run-down of the versions:
+ * defined(_POSIX_SOURCE) 1003.1-1988
+ * _POSIX_C_SOURCE == 1 1003.1-1990
+ * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option
+ * _POSIX_C_SOURCE == 199309 1003.1b-1993
+ * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995,
+ * and the omnibus ISO/IEC 9945-1: 1996
+ * _POSIX_C_SOURCE == 200112 1003.1-2001
+ * _POSIX_C_SOURCE == 200809 1003.1-2008
+ *
+ * In addition, the X/Open Portability Guide, which is now the Single UNIX
+ * Specification, defines a feature-test macro which indicates the version of
+ * that specification, and which subsumes _POSIX_C_SOURCE.
+ *
+ * Our macros begin with two underscores to avoid namespace screwage.
+ */
+
+/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
+#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */
+#define _POSIX_C_SOURCE 199009
+#endif
+
+/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199209
+#endif
+
+/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE - 0 >= 700
+#define __XSI_VISIBLE 700
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809
+#elif _XOPEN_SOURCE - 0 >= 600
+#define __XSI_VISIBLE 600
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112
+#elif _XOPEN_SOURCE - 0 >= 500
+#define __XSI_VISIBLE 500
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199506
+#endif
+#endif
+
+/*
+ * Deal with all versions of POSIX. The ordering relative to the tests above is
+ * important.
+ */
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 198808
+#endif
+#ifdef _POSIX_C_SOURCE
+#if _POSIX_C_SOURCE >= 200809
+#define __POSIX_VISIBLE 200809
+#define __ISO_C_VISIBLE 1999
+#elif _POSIX_C_SOURCE >= 200112
+#define __POSIX_VISIBLE 200112
+#define __ISO_C_VISIBLE 1999
+#elif _POSIX_C_SOURCE >= 199506
+#define __POSIX_VISIBLE 199506
+#define __ISO_C_VISIBLE 1990
+#elif _POSIX_C_SOURCE >= 199309
+#define __POSIX_VISIBLE 199309
+#define __ISO_C_VISIBLE 1990
+#elif _POSIX_C_SOURCE >= 199209
+#define __POSIX_VISIBLE 199209
+#define __ISO_C_VISIBLE 1990
+#elif _POSIX_C_SOURCE >= 199009
+#define __POSIX_VISIBLE 199009
+#define __ISO_C_VISIBLE 1990
+#else
+#define __POSIX_VISIBLE 198808
+#define __ISO_C_VISIBLE 0
+#endif /* _POSIX_C_SOURCE */
+#else
+/*-
+ * Deal with _ANSI_SOURCE:
+ * If it is defined, and no other compilation environment is explicitly
+ * requested, then define our internal feature-test macros to zero. This
+ * makes no difference to the preprocessor (undefined symbols in preprocessing
+ * expressions are defined to have value zero), but makes it more convenient for
+ * a test program to print out the values.
+ *
+ * If a program mistakenly defines _ANSI_SOURCE and some other macro such as
+ * _POSIX_C_SOURCE, we will assume that it wants the broader compilation
+ * environment (and in fact we will never get here).
+ */
+#if defined(_ANSI_SOURCE) /* Hide almost everything. */
+#define __POSIX_VISIBLE 0
+#define __XSI_VISIBLE 0
+#define __BSD_VISIBLE 0
+#define __ISO_C_VISIBLE 1990
+#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */
+#define __POSIX_VISIBLE 0
+#define __XSI_VISIBLE 0
+#define __BSD_VISIBLE 0
+#define __ISO_C_VISIBLE 1999
+#elif defined(_C11_SOURCE) /* Localism to specify strict C11 env. */
+#define __POSIX_VISIBLE 0
+#define __XSI_VISIBLE 0
+#define __BSD_VISIBLE 0
+#define __ISO_C_VISIBLE 2011
+#else /* Default environment: show everything. */
+#define __POSIX_VISIBLE 200809
+#define __XSI_VISIBLE 700
+#define __BSD_VISIBLE 1
+#define __ISO_C_VISIBLE 2011
+#endif
+#endif
+
+#if defined(__mips) || defined(__powerpc64__) || defined(__riscv__)
+#define __NO_TLS 1
+#endif
+
+/*
+ * Type Safety Checking
+ *
+ * Clang provides additional attributes to enable checking type safety
+ * properties that cannot be enforced by the C type system.
+ */
+
+#if __has_attribute(__argument_with_type_tag__) && \
+ __has_attribute(__type_tag_for_datatype__) && !defined(lint)
+#define __arg_type_tag(arg_kind, arg_idx, type_tag_idx) \
+ __attribute__((__argument_with_type_tag__(arg_kind, arg_idx, type_tag_idx)))
+#define __datatype_type_tag(kind, type) \
+ __attribute__((__type_tag_for_datatype__(kind, type)))
+#else
+#define __arg_type_tag(arg_kind, arg_idx, type_tag_idx)
+#define __datatype_type_tag(kind, type)
+#endif
+
+/*
+ * Lock annotations.
+ *
+ * Clang provides support for doing basic thread-safety tests at
+ * compile-time, by marking which locks will/should be held when
+ * entering/leaving a functions.
+ *
+ * Furthermore, it is also possible to annotate variables and structure
+ * members to enforce that they are only accessed when certain locks are
+ * held.
+ */
+
+#if __has_extension(c_thread_safety_attributes)
+#define __lock_annotate(x) __attribute__((x))
+#else
+#define __lock_annotate(x)
+#endif
+
+/* Structure implements a lock. */
+#define __lockable __lock_annotate(lockable)
+
+/* Function acquires an exclusive or shared lock. */
+#define __locks_exclusive(...) \
+ __lock_annotate(exclusive_lock_function(__VA_ARGS__))
+#define __locks_shared(...) \
+ __lock_annotate(shared_lock_function(__VA_ARGS__))
+
+/* Function attempts to acquire an exclusive or shared lock. */
+#define __trylocks_exclusive(...) \
+ __lock_annotate(exclusive_trylock_function(__VA_ARGS__))
+#define __trylocks_shared(...) \
+ __lock_annotate(shared_trylock_function(__VA_ARGS__))
+
+/* Function releases a lock. */
+#define __unlocks(...) __lock_annotate(unlock_function(__VA_ARGS__))
+
+/* Function asserts that an exclusive or shared lock is held. */
+#define __asserts_exclusive(...) \
+ __lock_annotate(assert_exclusive_lock(__VA_ARGS__))
+#define __asserts_shared(...) \
+ __lock_annotate(assert_shared_lock(__VA_ARGS__))
+
+/* Function requires that an exclusive or shared lock is or is not held. */
+#define __requires_exclusive(...) \
+ __lock_annotate(exclusive_locks_required(__VA_ARGS__))
+#define __requires_shared(...) \
+ __lock_annotate(shared_locks_required(__VA_ARGS__))
+#define __requires_unlocked(...) \
+ __lock_annotate(locks_excluded(__VA_ARGS__))
+
+/* Function should not be analyzed. */
+#define __no_lock_analysis __lock_annotate(no_thread_safety_analysis)
+
+/* Guard variables and structure members by lock. */
+#define __guarded_by(x) __lock_annotate(guarded_by(x))
+#define __pt_guarded_by(x) __lock_annotate(pt_guarded_by(x))
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/usr/src/boot/sys/sys/dirent.h b/usr/src/boot/sys/sys/dirent.h
new file mode 100644
index 0000000000..dfaacffb61
--- /dev/null
+++ b/usr/src/boot/sys/sys/dirent.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)dirent.h 8.3 (Berkeley) 8/10/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_DIRENT_H_
+#define _SYS_DIRENT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/*
+ * The dirent structure defines the format of directory entries returned by
+ * the getdirentries(2) system call.
+ *
+ * A directory entry has a struct dirent at the front of it, containing its
+ * inode number, the length of the entry, and the length of the name
+ * contained in the entry. These are followed by the name padded to a 4
+ * byte boundary with null bytes. All names are guaranteed null terminated.
+ * The maximum length of a name in a directory is MAXNAMLEN.
+ */
+
+struct dirent {
+ __uint32_t d_fileno; /* file number of entry */
+ __uint16_t d_reclen; /* length of this record */
+ __uint8_t d_type; /* file type, see below */
+ __uint8_t d_namlen; /* length of string in d_name */
+#if __BSD_VISIBLE
+#define MAXNAMLEN 255
+ char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
+#else
+ char d_name[255 + 1]; /* name must be no longer than this */
+#endif
+};
+
+#if __BSD_VISIBLE
+/*
+ * File types
+ */
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+
+/*
+ * Convert between stat structure types and directory types.
+ */
+#define IFTODT(mode) (((mode) & 0170000) >> 12)
+#define DTTOIF(dirtype) ((dirtype) << 12)
+
+/*
+ * The _GENERIC_DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This returns the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ *
+ * XXX although this macro is in the implementation namespace, it requires
+ * a manifest constant that is not.
+ */
+#define _GENERIC_DIRSIZ(dp) \
+ ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+#endif /* __BSD_VISIBLE */
+
+#ifdef _KERNEL
+#define GENERIC_DIRSIZ(dp) _GENERIC_DIRSIZ(dp)
+#endif
+
+#endif /* !_SYS_DIRENT_H_ */
diff --git a/usr/src/boot/sys/sys/disk.h b/usr/src/boot/sys/sys/disk.h
new file mode 100644
index 0000000000..5735a4f820
--- /dev/null
+++ b/usr/src/boot/sys/sys/disk.h
@@ -0,0 +1,139 @@
+/*-
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _SYS_DISK_H_
+#define _SYS_DISK_H_
+
+#include <sys/ioccom.h>
+#include <sys/types.h>
+
+#ifdef _KERNEL
+
+#ifndef _SYS_CONF_H_
+#include <sys/conf.h> /* XXX: temporary to avoid breakage */
+#endif
+
+void disk_err(struct bio *bp, const char *what, int blkdone, int nl);
+
+#endif
+
+#define DIOCGSECTORSIZE _IOR('d', 128, u_int)
+ /*
+ * Get the sector size of the device in bytes. The sector size is the
+ * smallest unit of data which can be transferred from this device.
+ * Usually this is a power of 2 but it might not be (i.e. CDROM audio).
+ */
+
+#define DIOCGMEDIASIZE _IOR('d', 129, off_t) /* Get media size in bytes */
+ /*
+ * Get the size of the entire device in bytes. This should be a
+ * multiple of the sector size.
+ */
+
+#define DIOCGFWSECTORS _IOR('d', 130, u_int) /* Get firmware's sectorcount */
+ /*
+ * Get the firmware's notion of number of sectors per track. This
+ * value is mostly used for compatibility with various ill designed
+ * disk label formats. Don't use it unless you have to.
+ */
+
+#define DIOCGFWHEADS _IOR('d', 131, u_int) /* Get firmware's headcount */
+ /*
+ * Get the firmwares notion of number of heads per cylinder. This
+ * value is mostly used for compatibility with various ill designed
+ * disk label formats. Don't use it unless you have to.
+ */
+
+#define DIOCSKERNELDUMP _IOW('d', 133, u_int) /* Set/Clear kernel dumps */
+ /*
+ * Enable/Disable (the argument is boolean) the device for kernel
+ * core dumps.
+ */
+
+#define DIOCGFRONTSTUFF _IOR('d', 134, off_t)
+ /*
+ * Many disk formats have some amount of space reserved at the
+ * start of the disk to hold bootblocks, various disklabels and
+ * similar stuff. This ioctl returns the number of such bytes
+ * which may apply to the device.
+ */
+
+#define DIOCGFLUSH _IO('d', 135) /* Flush write cache */
+ /*
+ * Flush write cache of the device.
+ */
+
+#define DIOCGDELETE _IOW('d', 136, off_t[2]) /* Delete data */
+ /*
+ * Mark data on the device as unused.
+ */
+
+#define DISK_IDENT_SIZE 256
+#define DIOCGIDENT _IOR('d', 137, char[DISK_IDENT_SIZE])
+ /*-
+ * Get the ident of the given provider. Ident is (most of the time)
+ * a uniqe and fixed provider's identifier. Ident's properties are as
+ * follow:
+ * - ident value is preserved between reboots,
+ * - provider can be detached/attached and ident is preserved,
+ * - provider's name can change - ident can't,
+ * - ident value should not be based on on-disk metadata; in other
+ * words copying whole data from one disk to another should not
+ * yield the same ident for the other disk,
+ * - there could be more than one provider with the same ident, but
+ * only if they point at exactly the same physical storage, this is
+ * the case for multipathing for example,
+ * - GEOM classes that consumes single providers and provide single
+ * providers, like geli, gbde, should just attach class name to the
+ * ident of the underlying provider,
+ * - ident is an ASCII string (is printable),
+ * - ident is optional and applications can't relay on its presence.
+ */
+
+#define DIOCGPROVIDERNAME _IOR('d', 138, char[MAXPATHLEN])
+ /*
+ * Store the provider name, given a device path, in a buffer. The buffer
+ * must be at least MAXPATHLEN bytes long.
+ */
+
+#define DIOCGSTRIPESIZE _IOR('d', 139, off_t) /* Get stripe size in bytes */
+ /*
+ * Get the size of the device's optimal access block in bytes.
+ * This should be a multiple of the sector size.
+ */
+
+#define DIOCGSTRIPEOFFSET _IOR('d', 140, off_t) /* Get stripe offset in bytes */
+ /*
+ * Get the offset of the first device's optimal access block in bytes.
+ * This should be a multiple of the sector size.
+ */
+
+#define DIOCGPHYSPATH _IOR('d', 141, char[MAXPATHLEN])
+ /*
+ * Get a string defining the physical path for a given provider.
+ * This has similar rules to ident, but is intended to uniquely
+ * identify the physical location of the device, not the current
+ * occupant of that location.
+ */
+
+struct diocgattr_arg {
+ char name[64];
+ int len;
+ union {
+ char str[DISK_IDENT_SIZE];
+ off_t off;
+ int i;
+ } value;
+};
+#define DIOCGATTR _IOWR('d', 142, struct diocgattr_arg)
+
+#endif /* _SYS_DISK_H_ */
diff --git a/usr/src/boot/sys/sys/disklabel.h b/usr/src/boot/sys/sys/disklabel.h
new file mode 100644
index 0000000000..42c757aaf3
--- /dev/null
+++ b/usr/src/boot/sys/sys/disklabel.h
@@ -0,0 +1,305 @@
+/*-
+ * Copyright (c) 1987, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)disklabel.h 8.2 (Berkeley) 7/10/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_DISKLABEL_H_
+#define _SYS_DISKLABEL_H_
+
+#ifndef _KERNEL
+#include <sys/types.h>
+#endif
+#include <sys/ioccom.h>
+
+/*
+ * Disk description table, see disktab(5)
+ */
+#define _PATH_DISKTAB "/etc/disktab"
+
+/*
+ * Each disk has a label which includes information about the hardware
+ * disk geometry, filesystem partitions, and drive specific information.
+ * The label is in block 0 or 1, possibly offset from the beginning
+ * to leave room for a bootstrap, etc.
+ */
+
+/* XXX these should be defined per controller (or drive) elsewhere, not here! */
+#if defined(__i386__) || defined(__amd64__) || defined(__arm__) || \
+ defined(__powerpc__) || defined(__mips__)
+#define LABELSECTOR 1 /* sector containing label */
+#define LABELOFFSET 0 /* offset of label in sector */
+#endif
+
+#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */
+#ifndef MAXPARTITIONS
+#define MAXPARTITIONS 8
+#endif
+
+/* Size of bootblock area in sector-size neutral bytes */
+#define BBSIZE 8192
+
+#define LABEL_PART 2 /* partition containing label */
+#define RAW_PART 2 /* partition containing whole disk */
+#define SWAP_PART 1 /* partition normally containing swap */
+
+struct disklabel {
+ u_int32_t d_magic; /* the magic number */
+ u_int16_t d_type; /* drive type */
+ u_int16_t d_subtype; /* controller/d_type specific */
+ char d_typename[16]; /* type name, e.g. "eagle" */
+
+ char d_packname[16]; /* pack identifier */
+
+ /* disk geometry: */
+ u_int32_t d_secsize; /* # of bytes per sector */
+ u_int32_t d_nsectors; /* # of data sectors per track */
+ u_int32_t d_ntracks; /* # of tracks per cylinder */
+ u_int32_t d_ncylinders; /* # of data cylinders per unit */
+ u_int32_t d_secpercyl; /* # of data sectors per cylinder */
+ u_int32_t d_secperunit; /* # of data sectors per unit */
+
+ /*
+ * Spares (bad sector replacements) below are not counted in
+ * d_nsectors or d_secpercyl. Spare sectors are assumed to
+ * be physical sectors which occupy space at the end of each
+ * track and/or cylinder.
+ */
+ u_int16_t d_sparespertrack; /* # of spare sectors per track */
+ u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */
+ /*
+ * Alternate cylinders include maintenance, replacement, configuration
+ * description areas, etc.
+ */
+ u_int32_t d_acylinders; /* # of alt. cylinders per unit */
+
+ /* hardware characteristics: */
+ /*
+ * d_interleave, d_trackskew and d_cylskew describe perturbations
+ * in the media format used to compensate for a slow controller.
+ * Interleave is physical sector interleave, set up by the
+ * formatter or controller when formatting. When interleaving is
+ * in use, logically adjacent sectors are not physically
+ * contiguous, but instead are separated by some number of
+ * sectors. It is specified as the ratio of physical sectors
+ * traversed per logical sector. Thus an interleave of 1:1
+ * implies contiguous layout, while 2:1 implies that logical
+ * sector 0 is separated by one sector from logical sector 1.
+ * d_trackskew is the offset of sector 0 on track N relative to
+ * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew
+ * is the offset of sector 0 on cylinder N relative to sector 0
+ * on cylinder N-1.
+ */
+ u_int16_t d_rpm; /* rotational speed */
+ u_int16_t d_interleave; /* hardware sector interleave */
+ u_int16_t d_trackskew; /* sector 0 skew, per track */
+ u_int16_t d_cylskew; /* sector 0 skew, per cylinder */
+ u_int32_t d_headswitch; /* head switch time, usec */
+ u_int32_t d_trkseek; /* track-to-track seek, usec */
+ u_int32_t d_flags; /* generic flags */
+#define NDDATA 5
+ u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */
+#define NSPARE 5
+ u_int32_t d_spare[NSPARE]; /* reserved for future use */
+ u_int32_t d_magic2; /* the magic number (again) */
+ u_int16_t d_checksum; /* xor of data incl. partitions */
+
+ /* filesystem and partition information: */
+ u_int16_t d_npartitions; /* number of partitions in following */
+ u_int32_t d_bbsize; /* size of boot area at sn0, bytes */
+ u_int32_t d_sbsize; /* max size of fs superblock, bytes */
+ struct partition { /* the partition table */
+ u_int32_t p_size; /* number of sectors in partition */
+ u_int32_t p_offset; /* starting sector */
+ u_int32_t p_fsize; /* filesystem basic fragment size */
+ u_int8_t p_fstype; /* filesystem type, see below */
+ u_int8_t p_frag; /* filesystem fragments per block */
+ u_int16_t p_cpg; /* filesystem cylinders per group */
+ } d_partitions[MAXPARTITIONS]; /* actually may be more */
+};
+
+#ifdef CTASSERT
+CTASSERT(sizeof(struct disklabel) == 148 + MAXPARTITIONS * 16);
+#endif
+
+static __inline u_int16_t dkcksum(struct disklabel *lp);
+static __inline u_int16_t
+dkcksum(struct disklabel *lp)
+{
+ u_int16_t *start, *end;
+ u_int16_t sum = 0;
+
+ start = (u_int16_t *)lp;
+ end = (u_int16_t *)&lp->d_partitions[lp->d_npartitions];
+ while (start < end)
+ sum ^= *start++;
+ return (sum);
+}
+
+
+/* d_type values: */
+#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
+#define DTYPE_MSCP 2 /* MSCP */
+#define DTYPE_DEC 3 /* other DEC (rk, rl) */
+#define DTYPE_SCSI 4 /* SCSI */
+#define DTYPE_ESDI 5 /* ESDI interface */
+#define DTYPE_ST506 6 /* ST506 etc. */
+#define DTYPE_HPIB 7 /* CS/80 on HP-IB */
+#define DTYPE_HPFL 8 /* HP Fiber-link */
+#define DTYPE_FLOPPY 10 /* floppy */
+#define DTYPE_CCD 11 /* concatenated disk */
+#define DTYPE_VINUM 12 /* vinum volume */
+#define DTYPE_DOC2K 13 /* Msys DiskOnChip */
+#define DTYPE_RAID 14 /* CMU RAIDFrame */
+#define DTYPE_JFS2 16 /* IBM JFS 2 */
+
+#ifdef DKTYPENAMES
+static const char *dktypenames[] = {
+ "unknown",
+ "SMD",
+ "MSCP",
+ "old DEC",
+ "SCSI",
+ "ESDI",
+ "ST506",
+ "HP-IB",
+ "HP-FL",
+ "type 9",
+ "floppy",
+ "CCD",
+ "Vinum",
+ "DOC2K",
+ "Raid",
+ "?",
+ "jfs",
+ NULL
+};
+#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
+#endif
+
+/*
+ * Filesystem type and version.
+ * Used to interpret other filesystem-specific
+ * per-partition information.
+ */
+#define FS_UNUSED 0 /* unused */
+#define FS_SWAP 1 /* swap */
+#define FS_V6 2 /* Sixth Edition */
+#define FS_V7 3 /* Seventh Edition */
+#define FS_SYSV 4 /* System V */
+#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
+#define FS_V8 6 /* Eighth Edition, 4K blocks */
+#define FS_BSDFFS 7 /* 4.2BSD fast filesystem */
+#define FS_MSDOS 8 /* MSDOS filesystem */
+#define FS_BSDLFS 9 /* 4.4BSD log-structured filesystem */
+#define FS_OTHER 10 /* in use, but unknown/unsupported */
+#define FS_HPFS 11 /* OS/2 high-performance filesystem */
+#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */
+#define FS_BOOT 13 /* partition contains bootstrap */
+#define FS_VINUM 14 /* Vinum drive */
+#define FS_RAID 15 /* RAIDFrame drive */
+#define FS_FILECORE 16 /* Acorn Filecore Filing System */
+#define FS_EXT2FS 17 /* ext2fs */
+#define FS_NTFS 18 /* Windows/NT file system */
+#define FS_CCD 20 /* concatenated disk component */
+#define FS_JFS2 21 /* IBM JFS2 */
+#define FS_HAMMER 22 /* DragonFlyBSD Hammer FS */
+#define FS_HAMMER2 23 /* DragonFlyBSD Hammer2 FS */
+#define FS_UDF 24 /* UDF */
+#define FS_EFS 26 /* SGI's Extent File system */
+#define FS_ZFS 27 /* Sun's ZFS */
+#define FS_NANDFS 30 /* FreeBSD nandfs (NiLFS derived) */
+
+#ifdef FSTYPENAMES
+static const char *fstypenames[] = {
+ "unused",
+ "swap",
+ "Version 6",
+ "Version 7",
+ "System V",
+ "4.1BSD",
+ "Eighth Edition",
+ "4.2BSD",
+ "MSDOS",
+ "4.4LFS",
+ "unknown",
+ "HPFS",
+ "ISO9660",
+ "boot",
+ "vinum",
+ "raid",
+ "Filecore",
+ "EXT2FS",
+ "NTFS",
+ "?",
+ "ccd",
+ "jfs",
+ "HAMMER",
+ "HAMMER2",
+ "UDF",
+ "?",
+ "EFS",
+ "ZFS",
+ "?",
+ "?",
+ "nandfs",
+ NULL
+};
+#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
+#endif
+
+/*
+ * flags shared by various drives:
+ */
+#define D_REMOVABLE 0x01 /* removable media */
+#define D_ECC 0x02 /* supports ECC */
+#define D_BADSECT 0x04 /* supports bad sector forw. */
+#define D_RAMDISK 0x08 /* disk emulator */
+#define D_CHAIN 0x10 /* can do back-back transfers */
+
+/*
+ * NB: <sys/disk.h> defines ioctls from 'd'/128 and up.
+ */
+
+/*
+ * Functions for proper encoding/decoding of struct disklabel into/from
+ * bytestring.
+ */
+void bsd_partition_le_dec(u_char *ptr, struct partition *d);
+int bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart);
+void bsd_partition_le_enc(u_char *ptr, struct partition *d);
+void bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d);
+
+#ifndef _KERNEL
+__BEGIN_DECLS
+struct disklabel *getdiskbyname(const char *);
+__END_DECLS
+#endif
+
+#endif /* !_SYS_DISKLABEL_H_ */
diff --git a/usr/src/boot/sys/sys/diskmbr.h b/usr/src/boot/sys/sys/diskmbr.h
new file mode 100644
index 0000000000..7896588060
--- /dev/null
+++ b/usr/src/boot/sys/sys/diskmbr.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1987, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)disklabel.h 8.2 (Berkeley) 7/10/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_DISKMBR_H_
+#define _SYS_DISKMBR_H_
+
+#include <sys/ioccom.h>
+
+#define DOSBBSECTOR 0 /* DOS boot block relative sector number */
+#define DOSDSNOFF 440 /* WinNT/2K/XP Drive Serial Number offset */
+#define DOSPARTOFF 446
+#define DOSPARTSIZE 16
+#define NDOSPART 4
+#define NEXTDOSPART 32
+#define DOSMAGICOFFSET 510
+#define DOSMAGIC 0xAA55
+
+#define DOSPTYP_EXT 0x05 /* DOS extended partition */
+#define DOSPTYP_FAT16 0x06 /* FAT16 partition */
+#define DOSPTYP_NTFS 0x07 /* NTFS partition */
+#define DOSPTYP_FAT32 0x0b /* FAT32 partition */
+#define DOSPTYP_EXTLBA 0x0f /* DOS extended partition */
+#define DOSPTYP_PPCBOOT 0x41 /* PReP/CHRP boot partition */
+#define DOSPTYP_LDM 0x42 /* Win2k dynamic extended partition */
+#define DOSPTYP_LINSWP 0x82 /* Linux swap partition */
+#define DOSPTYP_LINUX 0x83 /* Linux partition */
+#define DOSPTYP_LINLVM 0x8e /* Linux LVM partition */
+#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */
+#define DOSPTYP_APPLE_UFS 0xa8 /* Apple Mac OS X UFS */
+#define DOSPTYP_APPLE_BOOT 0xab /* Apple Mac OS X boot */
+#define DOSPTYP_HFS 0xaf /* HFS/HFS+ partition type */
+#define DOSPTYP_SUNIXOS2 0xbf /* Solaris2 partition */
+#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */
+#define DOSPTYP_EFI 0xef /* EFI FAT parition */
+#define DOSPTYP_VMFS 0xfb /* VMware VMFS partition */
+#define DOSPTYP_VMKDIAG 0xfc /* VMware vmkDiagnostic partition */
+#define DOSPTYP_LINRAID 0xfd /* Linux raid partition */
+
+struct dos_partition {
+ unsigned char dp_flag; /* bootstrap flags */
+ unsigned char dp_shd; /* starting head */
+ unsigned char dp_ssect; /* starting sector */
+ unsigned char dp_scyl; /* starting cylinder */
+ unsigned char dp_typ; /* partition type */
+ unsigned char dp_ehd; /* end head */
+ unsigned char dp_esect; /* end sector */
+ unsigned char dp_ecyl; /* end cylinder */
+ u_int32_t dp_start; /* absolute starting sector number */
+ u_int32_t dp_size; /* partition size in sectors */
+};
+#ifdef CTASSERT
+CTASSERT(sizeof (struct dos_partition) == DOSPARTSIZE);
+#endif
+
+void dos_partition_dec(void const *pp, struct dos_partition *d);
+void dos_partition_enc(void *pp, struct dos_partition *d);
+
+#define DPSECT(s) ((s) & 0x3f) /* isolate relevant bits of sector */
+#define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* and those that are cylinder */
+
+#define DIOCSMBR _IOW('M', 129, u_char[512])
+
+#endif /* !_SYS_DISKMBR_H_ */
diff --git a/usr/src/boot/sys/sys/efi.h b/usr/src/boot/sys/sys/efi.h
new file mode 100644
index 0000000000..a4ffeb02a4
--- /dev/null
+++ b/usr/src/boot/sys/sys/efi.h
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_EFI_H_
+#define _SYS_EFI_H_
+
+#include <sys/uuid.h>
+
+#define EFI_PAGE_SHIFT 12
+#define EFI_PAGE_SIZE (1 << EFI_PAGE_SHIFT)
+#define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1)
+
+#define EFI_TABLE_ACPI20 \
+ {0x8868e871,0xe4f1,0x11d3,0xbc,0x22,{0x00,0x80,0xc7,0x3c,0x88,0x81}}
+#define EFI_TABLE_SAL \
+ {0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+
+enum efi_reset {
+ EFI_RESET_COLD,
+ EFI_RESET_WARM
+};
+
+typedef uint16_t efi_char;
+typedef unsigned long efi_status;
+
+struct efi_cfgtbl {
+ struct uuid ct_uuid;
+ uint64_t ct_data;
+};
+
+struct efi_md {
+ uint32_t md_type;
+#define EFI_MD_TYPE_NULL 0
+#define EFI_MD_TYPE_CODE 1 /* Loader text. */
+#define EFI_MD_TYPE_DATA 2 /* Loader data. */
+#define EFI_MD_TYPE_BS_CODE 3 /* Boot services text. */
+#define EFI_MD_TYPE_BS_DATA 4 /* Boot services data. */
+#define EFI_MD_TYPE_RT_CODE 5 /* Runtime services text. */
+#define EFI_MD_TYPE_RT_DATA 6 /* Runtime services data. */
+#define EFI_MD_TYPE_FREE 7 /* Unused/free memory. */
+#define EFI_MD_TYPE_BAD 8 /* Bad memory */
+#define EFI_MD_TYPE_RECLAIM 9 /* ACPI reclaimable memory. */
+#define EFI_MD_TYPE_FIRMWARE 10 /* ACPI NV memory */
+#define EFI_MD_TYPE_IOMEM 11 /* Memory-mapped I/O. */
+#define EFI_MD_TYPE_IOPORT 12 /* I/O port space. */
+#define EFI_MD_TYPE_PALCODE 13 /* PAL */
+ uint32_t __pad;
+ uint64_t md_phys;
+ void *md_virt;
+ uint64_t md_pages;
+ uint64_t md_attr;
+#define EFI_MD_ATTR_UC 0x0000000000000001UL
+#define EFI_MD_ATTR_WC 0x0000000000000002UL
+#define EFI_MD_ATTR_WT 0x0000000000000004UL
+#define EFI_MD_ATTR_WB 0x0000000000000008UL
+#define EFI_MD_ATTR_UCE 0x0000000000000010UL
+#define EFI_MD_ATTR_WP 0x0000000000001000UL
+#define EFI_MD_ATTR_RP 0x0000000000002000UL
+#define EFI_MD_ATTR_XP 0x0000000000004000UL
+#define EFI_MD_ATTR_RT 0x8000000000000000UL
+};
+
+struct efi_tm {
+ uint16_t tm_year; /* 1998 - 20XX */
+ uint8_t tm_mon; /* 1 - 12 */
+ uint8_t tm_mday; /* 1 - 31 */
+ uint8_t tm_hour; /* 0 - 23 */
+ uint8_t tm_min; /* 0 - 59 */
+ uint8_t tm_sec; /* 0 - 59 */
+ uint8_t __pad1;
+ uint32_t tm_nsec; /* 0 - 999,999,999 */
+ int16_t tm_tz; /* -1440 to 1440 or 2047 */
+ uint8_t tm_dst;
+ uint8_t __pad2;
+};
+
+struct efi_tmcap {
+ uint32_t tc_res; /* 1e-6 parts per million */
+ uint32_t tc_prec; /* hertz */
+ uint8_t tc_stz; /* Set clears sub-second time */
+};
+
+struct efi_tblhdr {
+ uint64_t th_sig;
+ uint32_t th_rev;
+ uint32_t th_hdrsz;
+ uint32_t th_crc32;
+ uint32_t __res;
+};
+
+struct efi_rt {
+ struct efi_tblhdr rt_hdr;
+ efi_status (*rt_gettime)(struct efi_tm *, struct efi_tmcap *);
+ efi_status (*rt_settime)(struct efi_tm *);
+ efi_status (*rt_getwaketime)(uint8_t *, uint8_t *,
+ struct efi_tm *);
+ efi_status (*rt_setwaketime)(uint8_t, struct efi_tm *);
+ efi_status (*rt_setvirtual)(u_long, u_long, uint32_t,
+ struct efi_md *);
+ efi_status (*rt_cvtptr)(u_long, void **);
+ efi_status (*rt_getvar)(efi_char *, struct uuid *, uint32_t *,
+ u_long *, void *);
+ efi_status (*rt_scanvar)(u_long *, efi_char *, struct uuid *);
+ efi_status (*rt_setvar)(efi_char *, struct uuid *, uint32_t,
+ u_long, void *);
+ efi_status (*rt_gethicnt)(uint32_t *);
+ efi_status (*rt_reset)(enum efi_reset, efi_status, u_long,
+ efi_char *);
+};
+
+struct efi_systbl {
+ struct efi_tblhdr st_hdr;
+#define EFI_SYSTBL_SIG 0x5453595320494249UL
+ efi_char *st_fwvendor;
+ uint32_t st_fwrev;
+ uint32_t __pad;
+ void *st_cin;
+ void *st_cinif;
+ void *st_cout;
+ void *st_coutif;
+ void *st_cerr;
+ void *st_cerrif;
+ uint64_t st_rt;
+ void *st_bs;
+ u_long st_entries;
+ uint64_t st_cfgtbl;
+};
+
+extern vm_paddr_t efi_systbl;
+#endif /* _SYS_EFI_H_ */
diff --git a/usr/src/boot/sys/sys/elf.h b/usr/src/boot/sys/sys/elf.h
new file mode 100644
index 0000000000..b2d6b77c98
--- /dev/null
+++ b/usr/src/boot/sys/sys/elf.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2001 David E. O'Brien.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This is a Solaris compatibility header
+ */
+
+#ifndef _SYS_ELF_H_
+#define _SYS_ELF_H_
+
+#include <sys/types.h>
+#include <machine/elf.h>
+#include <sys/elf32.h>
+#include <sys/elf64.h>
+
+#endif /* !_SYS_ELF_H_ */
diff --git a/usr/src/boot/sys/sys/elf32.h b/usr/src/boot/sys/sys/elf32.h
new file mode 100644
index 0000000000..03a546c892
--- /dev/null
+++ b/usr/src/boot/sys/sys/elf32.h
@@ -0,0 +1,257 @@
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF32_H_
+#define _SYS_ELF32_H_ 1
+
+#include <sys/elf_common.h>
+
+/*
+ * ELF definitions common to all 32-bit architectures.
+ */
+
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+typedef uint64_t Elf32_Lword;
+
+typedef Elf32_Word Elf32_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf32_Word Elf32_Size;
+typedef Elf32_Sword Elf32_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf32_Half e_type; /* File type. */
+ Elf32_Half e_machine; /* Machine architecture. */
+ Elf32_Word e_version; /* ELF format version. */
+ Elf32_Addr e_entry; /* Entry point. */
+ Elf32_Off e_phoff; /* Program header file offset. */
+ Elf32_Off e_shoff; /* Section header file offset. */
+ Elf32_Word e_flags; /* Architecture-specific flags. */
+ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf32_Half e_phentsize; /* Size of program header entry. */
+ Elf32_Half e_phnum; /* Number of program header entries. */
+ Elf32_Half e_shentsize; /* Size of section header entry. */
+ Elf32_Half e_shnum; /* Number of section header entries. */
+ Elf32_Half e_shstrndx; /* Section name strings section. */
+} Elf32_Ehdr;
+
+/*
+ * Shared object information, found in SHT_MIPS_LIBLIST.
+ */
+
+typedef struct {
+ Elf32_Word l_name; /* The name of a shared object. */
+ Elf32_Word l_time_stamp; /* 32-bit timestamp. */
+ Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */
+ Elf32_Word l_version; /* Interface version string index. */
+ Elf32_Word l_flags; /* Flags (LL_*). */
+} Elf32_Lib;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf32_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf32_Word sh_type; /* Section type. */
+ Elf32_Word sh_flags; /* Section flags. */
+ Elf32_Addr sh_addr; /* Address in memory image. */
+ Elf32_Off sh_offset; /* Offset in file. */
+ Elf32_Word sh_size; /* Size in bytes. */
+ Elf32_Word sh_link; /* Index of a related section. */
+ Elf32_Word sh_info; /* Depends on section type. */
+ Elf32_Word sh_addralign; /* Alignment in bytes. */
+ Elf32_Word sh_entsize; /* Size of each entry in section. */
+} Elf32_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf32_Word p_type; /* Entry type. */
+ Elf32_Off p_offset; /* File offset of contents. */
+ Elf32_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf32_Addr p_paddr; /* Physical address (not used). */
+ Elf32_Word p_filesz; /* Size of contents in file. */
+ Elf32_Word p_memsz; /* Size of contents in memory. */
+ Elf32_Word p_flags; /* Access permission flags. */
+ Elf32_Word p_align; /* Alignment in memory and file. */
+} Elf32_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf32_Sword d_tag; /* Entry type. */
+ union {
+ Elf32_Word d_val; /* Integer value. */
+ Elf32_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf32_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+} Elf32_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+ Elf32_Sword r_addend; /* Addend. */
+} Elf32_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF32_R_SYM(info) ((info) >> 8)
+#define ELF32_R_TYPE(info) ((unsigned char)(info))
+
+/* Macro for constructing r_info from field values. */
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf32_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf32_Lword m_value; /* symbol value */
+ Elf32_Word m_info; /* size + index */
+ Elf32_Word m_poffset; /* symbol offset */
+ Elf32_Half m_repeat; /* repeat count */
+ Elf32_Half m_stride; /* stride info */
+} Elf32_Move;
+
+/*
+ * The macros compose and decompose values for Move.r_info
+ *
+ * sym = ELF32_M_SYM(M.m_info)
+ * size = ELF32_M_SIZE(M.m_info)
+ * M.m_info = ELF32_M_INFO(sym, size)
+ */
+#define ELF32_M_SYM(info) ((info)>>8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf32_Word c_tag; /* how to interpret value */
+ union {
+ Elf32_Word c_val;
+ Elf32_Addr c_ptr;
+ } c_un;
+} Elf32_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf32_Word st_name; /* String table index of name. */
+ Elf32_Addr st_value; /* Symbol value. */
+ Elf32_Word st_size; /* Size of associated object. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf32_Half st_shndx; /* Section index of symbol. */
+} Elf32_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF32_ST_BIND(info) ((info) >> 4)
+#define ELF32_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU symbol versioning. */
+typedef struct
+{
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct
+{
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct
+{
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct
+{
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half Elf32_Versym;
+
+typedef struct {
+ Elf32_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf32_Half si_flags; /* per symbol flags */
+} Elf32_Syminfo;
+
+#endif /* !_SYS_ELF32_H_ */
diff --git a/usr/src/boot/sys/sys/elf64.h b/usr/src/boot/sys/sys/elf64.h
new file mode 100644
index 0000000000..f0696196d5
--- /dev/null
+++ b/usr/src/boot/sys/sys/elf64.h
@@ -0,0 +1,260 @@
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF64_H_
+#define _SYS_ELF64_H_ 1
+
+#include <sys/elf_common.h>
+
+/*
+ * ELF definitions common to all 64-bit architectures.
+ */
+
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Sword;
+typedef int64_t Elf64_Sxword;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Lword;
+typedef uint64_t Elf64_Xword;
+
+/*
+ * Types of dynamic symbol hash table bucket and chain elements.
+ *
+ * This is inconsistent among 64 bit architectures, so a machine dependent
+ * typedef is required.
+ */
+
+typedef Elf64_Word Elf64_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf64_Xword Elf64_Size;
+typedef Elf64_Sxword Elf64_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf64_Half e_type; /* File type. */
+ Elf64_Half e_machine; /* Machine architecture. */
+ Elf64_Word e_version; /* ELF format version. */
+ Elf64_Addr e_entry; /* Entry point. */
+ Elf64_Off e_phoff; /* Program header file offset. */
+ Elf64_Off e_shoff; /* Section header file offset. */
+ Elf64_Word e_flags; /* Architecture-specific flags. */
+ Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf64_Half e_phentsize; /* Size of program header entry. */
+ Elf64_Half e_phnum; /* Number of program header entries. */
+ Elf64_Half e_shentsize; /* Size of section header entry. */
+ Elf64_Half e_shnum; /* Number of section header entries. */
+ Elf64_Half e_shstrndx; /* Section name strings section. */
+} Elf64_Ehdr;
+
+/*
+ * Shared object information, found in SHT_MIPS_LIBLIST.
+ */
+
+typedef struct {
+ Elf64_Word l_name; /* The name of a shared object. */
+ Elf64_Word l_time_stamp; /* 64-bit timestamp. */
+ Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */
+ Elf64_Word l_version; /* Interface version string index. */
+ Elf64_Word l_flags; /* Flags (LL_*). */
+} Elf64_Lib;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf64_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf64_Word sh_type; /* Section type. */
+ Elf64_Xword sh_flags; /* Section flags. */
+ Elf64_Addr sh_addr; /* Address in memory image. */
+ Elf64_Off sh_offset; /* Offset in file. */
+ Elf64_Xword sh_size; /* Size in bytes. */
+ Elf64_Word sh_link; /* Index of a related section. */
+ Elf64_Word sh_info; /* Depends on section type. */
+ Elf64_Xword sh_addralign; /* Alignment in bytes. */
+ Elf64_Xword sh_entsize; /* Size of each entry in section. */
+} Elf64_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf64_Word p_type; /* Entry type. */
+ Elf64_Word p_flags; /* Access permission flags. */
+ Elf64_Off p_offset; /* File offset of contents. */
+ Elf64_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf64_Addr p_paddr; /* Physical address (not used). */
+ Elf64_Xword p_filesz; /* Size of contents in file. */
+ Elf64_Xword p_memsz; /* Size of contents in memory. */
+ Elf64_Xword p_align; /* Alignment in memory and file. */
+} Elf64_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf64_Sxword d_tag; /* Entry type. */
+ union {
+ Elf64_Xword d_val; /* Integer value. */
+ Elf64_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf64_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+} Elf64_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+ Elf64_Sxword r_addend; /* Addend. */
+} Elf64_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF64_R_SYM(info) ((info) >> 32)
+#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
+
+/* Macro for constructing r_info from field values. */
+#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
+
+#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
+#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
+#define ELF64_R_TYPE_INFO(data, type) \
+ (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf64_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf64_Lword m_value; /* symbol value */
+ Elf64_Xword m_info; /* size + index */
+ Elf64_Xword m_poffset; /* symbol offset */
+ Elf64_Half m_repeat; /* repeat count */
+ Elf64_Half m_stride; /* stride info */
+} Elf64_Move;
+
+#define ELF64_M_SYM(info) ((info)>>8)
+#define ELF64_M_SIZE(info) ((unsigned char)(info))
+#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf64_Xword c_tag; /* how to interpret value */
+ union {
+ Elf64_Xword c_val;
+ Elf64_Addr c_ptr;
+ } c_un;
+} Elf64_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf64_Word st_name; /* String table index of name. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf64_Half st_shndx; /* Section index of symbol. */
+ Elf64_Addr st_value; /* Symbol value. */
+ Elf64_Xword st_size; /* Size of associated object. */
+} Elf64_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU-style symbol versioning. */
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half Elf64_Versym;
+
+typedef struct {
+ Elf64_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf64_Half si_flags; /* per symbol flags */
+} Elf64_Syminfo;
+
+#endif /* !_SYS_ELF64_H_ */
diff --git a/usr/src/boot/sys/sys/elf_common.h b/usr/src/boot/sys/sys/elf_common.h
new file mode 100644
index 0000000000..b4574f3a97
--- /dev/null
+++ b/usr/src/boot/sys/sys/elf_common.h
@@ -0,0 +1,1321 @@
+/*-
+ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
+ * Copyright (c) 1998 John D. Polstra.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define _SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+/*
+ * Note header. The ".note" section contains an array of notes. Each
+ * begins with this header, aligned to a word boundary. Immediately
+ * following the note header is n_namesz bytes of name, padded to the
+ * next word boundary. Then comes n_descsz bytes of descriptor, again
+ * padded to a word boundary. The values of n_namesz and n_descsz do
+ * not include the padding.
+ */
+
+typedef struct {
+ u_int32_t n_namesz; /* Length of name. */
+ u_int32_t n_descsz; /* Length of descriptor. */
+ u_int32_t n_type; /* Type of this note. */
+} Elf_Note;
+
+/*
+ * Option kinds.
+ */
+#define ODK_NULL 0 /* undefined */
+#define ODK_REGINFO 1 /* register usage info */
+#define ODK_EXCEPTIONS 2 /* exception processing info */
+#define ODK_PAD 3 /* section padding */
+#define ODK_HWPATCH 4 /* hardware patch applied */
+#define ODK_FILL 5 /* fill value used by the linker */
+#define ODK_TAGS 6 /* reserved space for tools */
+#define ODK_HWAND 7 /* hardware AND patch applied */
+#define ODK_HWOR 8 /* hardware OR patch applied */
+#define ODK_GP_GROUP 9 /* GP group for text/data sections */
+#define ODK_IDENT 10 /* ID information */
+#define ODK_PAGESIZE 11 /* page size information */
+
+/*
+ * ODK_EXCEPTIONS info field masks.
+ */
+#define OEX_FPU_MIN 0x0000001f /* min FPU exception required */
+#define OEX_FPU_MAX 0x00001f00 /* max FPU exception allowed */
+#define OEX_PAGE0 0x00010000 /* page zero must be mapped */
+#define OEX_SMM 0x00020000 /* run in sequential memory mode */
+#define OEX_PRECISEFP 0x00040000 /* run in precise FP exception mode */
+#define OEX_DISMISS 0x00080000 /* dismiss invalid address traps */
+
+/*
+ * ODK_PAD info field masks.
+ */
+#define OPAD_PREFIX 0x0001
+#define OPAD_POSTFIX 0x0002
+#define OPAD_SYMBOL 0x0004
+
+/*
+ * ODK_HWPATCH info field masks.
+ */
+#define OHW_R4KEOP 0x00000001 /* patch for R4000 branch at end-of-page bug */
+#define OHW_R8KPFETCH 0x00000002 /* R8000 prefetch bug may occur */
+#define OHW_R5KEOP 0x00000004 /* patch for R5000 branch at end-of-page bug */
+#define OHW_R5KCVTL 0x00000008 /* R5000 cvt.[ds].l bug: clean == 1 */
+#define OHW_R10KLDL 0x00000010UL /* need patch for R10000 misaligned load */
+
+/*
+ * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks.
+ */
+#define OHWA0_R4KEOP_CHECKED 0x00000001 /* object checked for R4000 end-of-page bug */
+#define OHWA0_R4KEOP_CLEAN 0x00000002 /* object verified clean for R4000 end-of-page bug */
+#define OHWO0_FIXADE 0x00000001 /* object requires call to fixade */
+
+/*
+ * ODK_IDENT/ODK_GP_GROUP info field masks.
+ */
+#define OGP_GROUP 0x0000ffff /* GP group number */
+#define OGP_SELF 0x00010000 /* GP group is self-contained */
+
+/*
+ * The header for GNU-style hash sections.
+ */
+
+typedef struct {
+ u_int32_t gh_nbuckets; /* Number of hash buckets. */
+ u_int32_t gh_symndx; /* First visible symbol in .dynsym. */
+ u_int32_t gh_maskwords; /* #maskwords used in bloom filter. */
+ u_int32_t gh_shift2; /* Bloom filter shift count. */
+} Elf_GNU_Hash_Header;
+
+/* Indexes into the e_ident array. Keep synced with
+ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_OSABI 7 /* Operating system / ABI identification */
+#define EI_ABIVERSION 8 /* ABI version */
+#define OLD_EI_BRAND 8 /* Start of architecture identification. */
+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT 16 /* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF" /* magic string */
+#define SELFMAG 4 /* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* GNU/Linux */
+#define ELFOSABI_HURD 4 /* GNU/Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+#define ELFOSABI_FENIXOS 16 /* FenixOS */
+#define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
+#define ELFOSABI_GNU ELFOSABI_LINUX
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+#define ET_LOOS 0xfe00 /* First operating system specific. */
+#define ET_HIOS 0xfeff /* Last operating system-specific. */
+#define ET_LOPROC 0xff00 /* First processor-specific. */
+#define ET_HIPROC 0xffff /* Last processor-specific. */
+
+/* Values for e_machine. */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M32 1 /* AT&T WE32100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_IAMCU 6 /* Intel MCU. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
+#define EM_S370 9 /* IBM System/370. */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
+#define EM_PARISC 15 /* HP PA-RISC. */
+#define EM_VPP500 17 /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
+#define EM_960 19 /* Intel 80960. */
+#define EM_PPC 20 /* PowerPC 32-bit. */
+#define EM_PPC64 21 /* PowerPC 64-bit. */
+#define EM_S390 22 /* IBM System/390. */
+#define EM_V800 36 /* NEC V800. */
+#define EM_FR20 37 /* Fujitsu FR20. */
+#define EM_RH32 38 /* TRW RH-32. */
+#define EM_RCE 39 /* Motorola RCE. */
+#define EM_ARM 40 /* ARM. */
+#define EM_SH 42 /* Hitachi SH. */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
+#define EM_ARC 45 /* Argonaut RISC Core. */
+#define EM_H8_300 46 /* Hitachi H8/300. */
+#define EM_H8_300H 47 /* Hitachi H8/300H. */
+#define EM_H8S 48 /* Hitachi H8S. */
+#define EM_H8_500 49 /* Hitachi H8/500. */
+#define EM_IA_64 50 /* Intel IA-64 Processor. */
+#define EM_MIPS_X 51 /* Stanford MIPS-X. */
+#define EM_COLDFIRE 52 /* Motorola ColdFire. */
+#define EM_68HC12 53 /* Motorola M68HC12. */
+#define EM_MMA 54 /* Fujitsu MMA. */
+#define EM_PCP 55 /* Siemens PCP. */
+#define EM_NCPU 56 /* Sony nCPU. */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
+#define EM_STARCORE 58 /* Motorola Star*Core processor. */
+#define EM_ME16 59 /* Toyota ME16 processor. */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
+#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
+#define EM_PDSP 63 /* Sony DSP Processor. */
+#define EM_FX66 66 /* Siemens FX66 microcontroller. */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
+ microcontroller. */
+#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
+ microcontroller. */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
+#define EM_SVX 73 /* Silicon Graphics SVx. */
+#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
+#define EM_VAX 75 /* Digital VAX. */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded
+ processor. */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
+ processor. */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
+#define EM_HUANY 81 /* Harvard University machine-independent
+ object files. */
+#define EM_PRISM 82 /* SiTera Prism. */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
+#define EM_FR30 84 /* Fujitsu FR30. */
+#define EM_D10V 85 /* Mitsubishi D10V. */
+#define EM_D30V 86 /* Mitsubishi D30V. */
+#define EM_V850 87 /* NEC v850. */
+#define EM_M32R 88 /* Mitsubishi M32R. */
+#define EM_MN10300 89 /* Matsushita MN10300. */
+#define EM_MN10200 90 /* Matsushita MN10200. */
+#define EM_PJ 91 /* picoJava. */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
+ Processor. */
+#define EM_NS32K 97 /* National Semiconductor 32000 series. */
+#define EM_TPC 98 /* Tenor Network TPC processor. */
+#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
+#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
+#define EM_MAX 102 /* MAX Processor. */
+#define EM_CR 103 /* National Semiconductor CompactRISC
+ microprocessor. */
+#define EM_F2MC16 104 /* Fujitsu F2MC16. */
+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
+ msp430. */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
+#define EM_SEP 108 /* Sharp embedded microprocessor. */
+#define EM_ARCA 109 /* Arca RISC Microprocessor. */
+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
+ and MPRC of Peking University */
+#define EM_AARCH64 183 /* AArch64 (64-bit ARM) */
+#define EM_RISCV 243 /* RISC-V */
+
+/* Non-standard or deprecated. */
+#define EM_486 6 /* Intel i486. */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
+
+/**
+ * e_flags
+ */
+#define EF_ARM_RELEXEC 0x1
+#define EF_ARM_HASENTRY 0x2
+#define EF_ARM_SYMSARESORTED 0x4
+#define EF_ARM_DYNSYMSUSESEGIDX 0x8
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_LE8 0x00400000
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_EABIMASK 0xFF000000
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+#define EF_ARM_INTERWORK 0x00000004
+#define EF_ARM_APCS_26 0x00000008
+#define EF_ARM_APCS_FLOAT 0x00000010
+#define EF_ARM_PIC 0x00000020
+#define EF_ARM_ALIGN8 0x00000040
+#define EF_ARM_NEW_ABI 0x00000080
+#define EF_ARM_OLD_ABI 0x00000100
+#define EF_ARM_SOFT_FLOAT 0x00000200
+#define EF_ARM_VFP_FLOAT 0x00000400
+#define EF_ARM_MAVERICK_FLOAT 0x00000800
+
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
+#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
+#define EF_MIPS_UCODE 0x00000010
+#define EF_MIPS_ABI2 0x00000020 /* N32 */
+#define EF_MIPS_OPTIONS_FIRST 0x00000080
+#define EF_MIPS_ARCH_ASE 0x0F000000 /* Architectural extensions */
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* MDMX multimedia extension */
+#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* MIPS-16 ISA extensions */
+#define EF_MIPS_ARCH 0xF0000000 /* Architecture field */
+
+#define EF_PPC_EMB 0x80000000
+#define EF_PPC_RELOCATABLE 0x00010000
+#define EF_PPC_RELOCATABLE_LIB 0x00008000
+
+#define EF_SPARC_EXT_MASK 0x00ffff00
+#define EF_SPARC_32PLUS 0x00000100
+#define EF_SPARC_SUN_US1 0x00000200
+#define EF_SPARC_HAL_R1 0x00000200
+#define EF_SPARC_SUN_US3 0x00000800
+
+#define EF_SPARCV9_MM 0x00000003
+#define EF_SPARCV9_TSO 0x00000000
+#define EF_SPARCV9_PSO 0x00000001
+#define EF_SPARCV9_RMO 0x00000002
+
+/* Special section indexes. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_LOOS 0xff20 /* First operating system-specific. */
+#define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj
+ linker only: Cached global in local
+ symtab. */
+#define SHN_HIOS 0xff3f /* Last operating system-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends */
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relocation section - no addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
+#define SHT_GROUP 17 /* Section group. */
+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
+
+#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
+ pre-emption map. */
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
+ attributes. */
+#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */
+#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */
+#define SHT_MIPS_LIBLIST 0x70000000
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_ABIFLAGS 0x7000002a
+
+#define SHT_SPARC_GOTDATA 0x70000000
+
+#define SHTORDERED
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
+
+/* Flags for sh_flags. */
+#define SHF_WRITE 0x1 /* Section contains writable data. */
+#define SHF_ALLOC 0x2 /* Section occupies memory. */
+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
+#define SHF_MERGE 0x10 /* Section may be merged. */
+#define SHF_STRINGS 0x20 /* Section contains strings. */
+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
+#define SHF_GROUP 0x200 /* Member of section group. */
+#define SHF_TLS 0x400 /* Section contains TLS data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
+
+/* Flags for section groups. */
+#define GRP_COMDAT 0x1 /* COMDAT semantics. */
+
+/*
+ * Flags / mask for .gnu.versym sections.
+ */
+#define VERSYM_VERSION 0x7fff
+#define VERSYM_HIDDEN 0x8000
+
+/* Values for p_type. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* First OS-specific. */
+#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_STACK 0x6474e551
+#define PT_GNU_RELRO 0x6474e552
+#define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps
+ (currently arm). */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
+#define PT_SUNWDTRACE 0x6ffffffc /* private */
+#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* Last OS-specific. */
+#define PT_LOPROC 0x70000000 /* First processor-specific type. */
+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for p_flags. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
+
+/* Extended program header index. */
+#define PN_XNUM 0xffff
+
+/* Values for d_tag. */
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
+ library. */
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
+ name. */
+#define DT_RPATH 15 /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
+ non-writable segments. [sup] */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
+#define DT_BIND_NOW 24 /* [sup] */
+#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
+ initialization functions */
+#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
+ termination functions */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
+ initialization functions. */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
+ termination functions. */
+#define DT_RUNPATH 29 /* String table offset of a null-terminated
+ library search path string. */
+#define DT_FLAGS 30 /* Object specific flag values. */
+#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
+ and less than DT_LOOS follow the rules for
+ the interpretation of the d_un union
+ as follows: even == 'd_ptr', odd == 'd_val'
+ or none */
+#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
+ pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
+ pre-initialization functions. */
+#define DT_MAXPOSTAGS 34 /* number of positive tags */
+#define DT_LOOS 0x6000000d /* First OS-specific */
+#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
+#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
+#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
+#define DT_SUNW_CAP 0x60000010 /* hardware/software */
+#define DT_HIOS 0x6ffff000 /* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5 /* prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* size of library list */
+#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
+#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
+#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
+#define DT_MOVESZ 0x6ffffdfb /* move table size */
+#define DT_FEATURE 0x6ffffdfc /* feature holder */
+#define DT_FEATURE_1 DT_FEATURE
+#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
+ /* the following DT_* entry. */
+ /* See DF_P1_* definitions */
+#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
+#define DT_VALRNGHI 0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */
+#define DT_GNU_CONFLICT 0x6ffffef8 /* address of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9 /* address of library list */
+#define DT_CONFIG 0x6ffffefa /* configuration information */
+#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
+#define DT_AUDIT 0x6ffffefc /* object auditing */
+#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
+#define DT_MOVETAB 0x6ffffefe /* move table */
+#define DT_SYMINFO 0x6ffffeff /* syminfo table */
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
+#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
+#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
+#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
+#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
+#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */
+
+#define DT_LOPROC 0x70000000 /* First processor-specific type. */
+
+#define DT_ARM_SYMTABSZ 0x70000001
+#define DT_ARM_PREEMPTMAP 0x70000002
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#define DT_MIPS_DELTA_CLASS 0x70000017
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A
+#define DT_MIPS_DELTA_RELOC 0x7000001B
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001C
+#define DT_MIPS_DELTA_SYM 0x7000001D
+#define DT_MIPS_DELTA_SYM_NO 0x7000001E
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+#define DT_MIPS_CXX_FLAGS 0x70000022
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029
+#define DT_MIPS_INTERFACE 0x7000002A
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002B
+#define DT_MIPS_INTERFACE_SIZE 0x7000002C
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D
+#define DT_MIPS_PERF_SUFFIX 0x7000002E
+#define DT_MIPS_COMPACT_SIZE 0x7000002F
+#define DT_MIPS_GP_VALUE 0x70000030
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+#define DT_MIPS_PLTGOT 0x70000032
+#define DT_MIPS_RLD_OBJ_UPDATE 0x70000033
+#define DT_MIPS_RWPLT 0x70000034
+
+#define DT_PPC_GOT 0x70000000
+#define DT_PPC_TLSOPT 0x70000001
+
+#define DT_PPC64_GLINK 0x70000000
+#define DT_PPC64_OPD 0x70000001
+#define DT_PPC64_OPDSZ 0x70000002
+#define DT_PPC64_TLSOPT 0x70000003
+
+#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
+#define DT_USED 0x7ffffffe /* ignored - same as needed */
+#define DT_FILTER 0x7fffffff /* shared library filter name */
+#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
+ make reference to the $ORIGIN substitution
+ string */
+#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
+#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
+ non-writable segments. */
+#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
+ process all relocations for the object
+ containing this entry before transferring
+ control to the program. */
+#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
+ executable contains code using a static
+ thread-local storage scheme. */
+
+/* Values for DT_FLAGS_1 */
+#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
+#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */
+#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
+#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */
+#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */
+#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */
+#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */
+#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */
+
+/* Values for l_flags. */
+#define LL_NONE 0x0 /* no flags */
+#define LL_EXACT_MATCH 0x1 /* require an exact match */
+#define LL_IGNORE_INT_VER 0x2 /* ignore version incompatibilities */
+#define LL_REQUIRE_MINOR 0x4
+#define LL_EXPORTS 0x8
+#define LL_DELAY_LOAD 0x10
+#define LL_DELTA 0x20
+
+/* Values for n_type used in executables. */
+#define NT_FREEBSD_ABI_TAG 1
+#define NT_FREEBSD_NOINIT_TAG 2
+#define NT_FREEBSD_ARCH_TAG 3
+
+/* Values for n_type. Used in core files. */
+#define NT_PRSTATUS 1 /* Process status. */
+#define NT_FPREGSET 2 /* Floating point registers. */
+#define NT_PRPSINFO 3 /* Process state info. */
+#define NT_THRMISC 7 /* Thread miscellaneous info. */
+#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */
+#define NT_PROCSTAT_FILES 9 /* Procstat files data. */
+#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */
+#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */
+#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */
+#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */
+#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */
+#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
+#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOOS 10 /* Start of operating system reserved range. */
+#define STB_GNU_UNIQUE 10 /* Unique symbol (GNU) */
+#define STB_HIOS 12 /* End of operating system reserved range. */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_COMMON 5 /* Uninitialized common block. */
+#define STT_TLS 6 /* TLS object. */
+#define STT_NUM 7
+#define STT_LOOS 10 /* Reserved range for operating system */
+#define STT_GNU_IFUNC 10
+#define STT_HIOS 12 /* specific semantics. */
+#define STT_LOPROC 13 /* Start of processor reserved range. */
+#define STT_SPARC_REGISTER 13 /* SPARC register information. */
+#define STT_HIPROC 15 /* End of processor reserved range. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
+#define STV_HIDDEN 0x2 /* Not visible. */
+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
+#define STV_EXPORTED 0x4
+#define STV_SINGLETON 0x5
+#define STV_ELIMINATE 0x6
+
+/* Special symbol table indexes. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define VER_DEF_CURRENT 1
+#define VER_DEF_IDX(x) VER_NDX(x)
+
+#define VER_FLG_BASE 0x01
+#define VER_FLG_WEAK 0x02
+
+#define VER_NEED_CURRENT 1
+#define VER_NEED_WEAK (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_GIVEN 2
+
+#define VER_NDX_HIDDEN (1u << 15)
+#define VER_NDX(x) ((x) & ~(1u << 15))
+
+#define CA_SUNW_NULL 0
+#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
+#define CA_SUNW_SF_1 2 /* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
+ /* to object containing defn. */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
+#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
+ /* lazily-loaded */
+#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
+ /* object containing defn. */
+#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
+ /* directly bind to this symbol */
+#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
+#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
+#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
+#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define SYMINFO_NONE 0 /* Syminfo version */
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define R_386_NONE 0 /* No relocation. */
+#define R_386_32 1 /* Add symbol value. */
+#define R_386_PC32 2 /* Add PC-relative symbol value. */
+#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
+#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
+#define R_386_COPY 5 /* Copy data from shared object. */
+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_386_RELATIVE 8 /* Add load address of shared object. */
+#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
+#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
+#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
+#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
+#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
+#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
+#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
+#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
+#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
+#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
+#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
+#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
+#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
+#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */
+
+#define R_AARCH64_NONE 0 /* No relocation */
+#define R_AARCH64_ABS64 257 /* Absolute offset */
+#define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */
+#define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */
+#define R_AARCH64_PREL64 260 /* PC relative */
+#define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */
+#define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */
+#define R_AARCH64_COPY 1024 /* Copy data from shared object */
+#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */
+#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */
+#define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */
+#define R_AARCH64_TLS_DTPREL64 1028
+#define R_AARCH64_TLS_DTPMOD64 1029
+#define R_AARCH64_TLS_TPREL64 1030
+#define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */
+#define R_AARCH64_IRELATIVE 1032
+
+#define R_ARM_NONE 0 /* No relocation. */
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+/* TLS relocations */
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
+#define R_ARM_COPY 20 /* Copy data from shared object. */
+#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
+#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
+#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
+#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
+#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
+#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
+#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS32 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+/* Name Value Field Calculation */
+#define R_IA_64_NONE 0 /* None */
+#define R_IA_64_IMM14 0x21 /* immediate14 S + A */
+#define R_IA_64_IMM22 0x22 /* immediate22 S + A */
+#define R_IA_64_IMM64 0x23 /* immediate64 S + A */
+#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */
+#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */
+#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */
+#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
+#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */
+#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */
+#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */
+#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */
+#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */
+#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */
+#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */
+#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */
+#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */
+#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */
+#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */
+#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */
+#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */
+#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */
+#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */
+#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */
+#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */
+#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */
+#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */
+#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */
+#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */
+#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */
+#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */
+#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */
+#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */
+#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */
+#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */
+#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */
+#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */
+#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */
+#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */
+#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
+#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */
+#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */
+#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */
+#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */
+#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */
+#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */
+#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */
+#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */
+#define R_IA_64_SUB 0x85 /* immediate64 A - S */
+#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */
+#define R_IA_64_LDXMOV 0x87 /* immediate22 special */
+#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */
+#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */
+#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */
+#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */
+#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */
+#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */
+#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */
+#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */
+#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */
+#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */
+#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */
+#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */
+#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */
+#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */
+
+#define R_MIPS_NONE 0 /* No reloc */
+#define R_MIPS_16 1 /* Direct 16 bit */
+#define R_MIPS_32 2 /* Direct 32 bit */
+#define R_MIPS_REL32 3 /* PC relative 32 bit */
+#define R_MIPS_26 4 /* Direct 26 bit shifted */
+#define R_MIPS_HI16 5 /* High 16 bit */
+#define R_MIPS_LO16 6 /* Low 16 bit */
+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
+#define R_MIPS_PC16 10 /* PC relative 16 bit */
+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
+#define R_MIPS_64 18 /* Direct 64 bit */
+#define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */
+#define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */
+#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */
+#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */
+
+#define R_PPC_NONE 0 /* No relocation. */
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/*
+ * 64-bit relocations
+ */
+#define R_PPC64_ADDR64 38
+#define R_PPC64_ADDR16_HIGHER 39
+#define R_PPC64_ADDR16_HIGHERA 40
+#define R_PPC64_ADDR16_HIGHEST 41
+#define R_PPC64_ADDR16_HIGHESTA 42
+#define R_PPC64_UADDR64 43
+#define R_PPC64_REL64 44
+#define R_PPC64_PLT64 45
+#define R_PPC64_PLTREL64 46
+#define R_PPC64_TOC16 47
+#define R_PPC64_TOC16_LO 48
+#define R_PPC64_TOC16_HI 49
+#define R_PPC64_TOC16_HA 50
+#define R_PPC64_TOC 51
+#define R_PPC64_DTPMOD64 68
+#define R_PPC64_TPREL64 73
+#define R_PPC64_DTPREL64 78
+
+/*
+ * TLS relocations
+ */
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ * SVR4 ELF ABI.
+ */
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+/*
+ * RISC-V relocation types.
+ */
+
+/* Relocation types used by the dynamic linker. */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+
+/* Relocation types not used by the dynamic linker. */
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+
+#define R_X86_64_NONE 0 /* No relocation. */
+#define R_X86_64_64 1 /* Add 64 bit symbol value. */
+#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
+#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
+#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
+#define R_X86_64_COPY 5 /* Copy data from shared object. */
+#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
+#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
+#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
+#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
+#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
+#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
+#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
+#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
+#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
+#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
+#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
+#define R_X86_64_PC64 24 /* PC-relative 64 bit signed sym value. */
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32 26
+#define R_X86_64_GOT64 27
+#define R_X86_64_GOTPCREL64 28
+#define R_X86_64_GOTPC64 29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_SIZE32 32
+#define R_X86_64_SIZE64 33
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL 35
+#define R_X86_64_TLSDESC 36
+#define R_X86_64_IRELATIVE 37
+
+
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/usr/src/boot/sys/sys/elf_generic.h b/usr/src/boot/sys/sys/elf_generic.h
new file mode 100644
index 0000000000..95a682f259
--- /dev/null
+++ b/usr/src/boot/sys/sys/elf_generic.h
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1998 John D. Polstra.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF_GENERIC_H_
+#define _SYS_ELF_GENERIC_H_ 1
+
+#include <sys/cdefs.h>
+
+/*
+ * Definitions of generic ELF names which relieve applications from
+ * needing to know the word size.
+ */
+
+#if __ELF_WORD_SIZE != 32 && __ELF_WORD_SIZE != 64
+#error "__ELF_WORD_SIZE must be defined as 32 or 64"
+#endif
+
+#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE)
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define ELF_DATA ELFDATA2LSB
+#elif BYTE_ORDER == BIG_ENDIAN
+#define ELF_DATA ELFDATA2MSB
+#else
+#error "Unknown byte order"
+#endif
+
+#define __elfN(x) __CONCAT(__CONCAT(__CONCAT(elf,__ELF_WORD_SIZE),_),x)
+#define __ElfN(x) __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x)
+#define __ELFN(x) __CONCAT(__CONCAT(__CONCAT(ELF,__ELF_WORD_SIZE),_),x)
+#define __ElfType(x) typedef __ElfN(x) __CONCAT(Elf_,x)
+
+__ElfType(Addr);
+__ElfType(Half);
+__ElfType(Off);
+__ElfType(Sword);
+__ElfType(Word);
+__ElfType(Ehdr);
+__ElfType(Shdr);
+__ElfType(Phdr);
+__ElfType(Dyn);
+__ElfType(Rel);
+__ElfType(Rela);
+__ElfType(Sym);
+__ElfType(Verdef);
+__ElfType(Verdaux);
+__ElfType(Verneed);
+__ElfType(Vernaux);
+__ElfType(Versym);
+
+/* Non-standard ELF types. */
+__ElfType(Hashelt);
+__ElfType(Size);
+__ElfType(Ssize);
+
+#define ELF_R_SYM __ELFN(R_SYM)
+#define ELF_R_TYPE __ELFN(R_TYPE)
+#define ELF_R_INFO __ELFN(R_INFO)
+#define ELF_ST_BIND __ELFN(ST_BIND)
+#define ELF_ST_TYPE __ELFN(ST_TYPE)
+#define ELF_ST_INFO __ELFN(ST_INFO)
+
+#endif /* !_SYS_ELF_GENERIC_H_ */
diff --git a/usr/src/boot/sys/sys/endian.h b/usr/src/boot/sys/sys/endian.h
new file mode 100644
index 0000000000..d50110cabc
--- /dev/null
+++ b/usr/src/boot/sys/sys/endian.h
@@ -0,0 +1,205 @@
+/*-
+ * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ENDIAN_H_
+#define _SYS_ENDIAN_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <machine/endian.h>
+
+#ifndef _UINT8_T_DECLARED
+typedef __uint8_t uint8_t;
+#define _UINT8_T_DECLARED
+#endif
+
+#ifndef _UINT16_T_DECLARED
+typedef __uint16_t uint16_t;
+#define _UINT16_T_DECLARED
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _UINT64_T_DECLARED
+typedef __uint64_t uint64_t;
+#define _UINT64_T_DECLARED
+#endif
+
+/*
+ * General byte order swapping functions.
+ */
+#define bswap16(x) __bswap16(x)
+#define bswap32(x) __bswap32(x)
+#define bswap64(x) __bswap64(x)
+
+/*
+ * Host to big endian, host to little endian, big endian to host, and little
+ * endian to host byte order functions as detailed in byteorder(9).
+ */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define htobe16(x) bswap16((x))
+#define htobe32(x) bswap32((x))
+#define htobe64(x) bswap64((x))
+#define htole16(x) ((uint16_t)(x))
+#define htole32(x) ((uint32_t)(x))
+#define htole64(x) ((uint64_t)(x))
+
+#define be16toh(x) bswap16((x))
+#define be32toh(x) bswap32((x))
+#define be64toh(x) bswap64((x))
+#define le16toh(x) ((uint16_t)(x))
+#define le32toh(x) ((uint32_t)(x))
+#define le64toh(x) ((uint64_t)(x))
+#else /* _BYTE_ORDER != _LITTLE_ENDIAN */
+#define htobe16(x) ((uint16_t)(x))
+#define htobe32(x) ((uint32_t)(x))
+#define htobe64(x) ((uint64_t)(x))
+#define htole16(x) bswap16((x))
+#define htole32(x) bswap32((x))
+#define htole64(x) bswap64((x))
+
+#define be16toh(x) ((uint16_t)(x))
+#define be32toh(x) ((uint32_t)(x))
+#define be64toh(x) ((uint64_t)(x))
+#define le16toh(x) bswap16((x))
+#define le32toh(x) bswap32((x))
+#define le64toh(x) bswap64((x))
+#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
+
+/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
+
+static __inline uint16_t
+be16dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return ((p[0] << 8) | p[1]);
+}
+
+static __inline uint32_t
+be32dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+}
+
+static __inline uint64_t
+be64dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4));
+}
+
+static __inline uint16_t
+le16dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return ((p[1] << 8) | p[0]);
+}
+
+static __inline uint32_t
+le32dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+}
+
+static __inline uint64_t
+le64dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
+}
+
+static __inline void
+be16enc(void *pp, uint16_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ p[0] = (u >> 8) & 0xff;
+ p[1] = u & 0xff;
+}
+
+static __inline void
+be32enc(void *pp, uint32_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ p[0] = (u >> 24) & 0xff;
+ p[1] = (u >> 16) & 0xff;
+ p[2] = (u >> 8) & 0xff;
+ p[3] = u & 0xff;
+}
+
+static __inline void
+be64enc(void *pp, uint64_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ be32enc(p, (uint32_t)(u >> 32));
+ be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
+}
+
+static __inline void
+le16enc(void *pp, uint16_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+}
+
+static __inline void
+le32enc(void *pp, uint32_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+ p[2] = (u >> 16) & 0xff;
+ p[3] = (u >> 24) & 0xff;
+}
+
+static __inline void
+le64enc(void *pp, uint64_t u)
+{
+ uint8_t *p = (uint8_t *)pp;
+
+ le32enc(p, (uint32_t)(u & 0xffffffffU));
+ le32enc(p + 4, (uint32_t)(u >> 32));
+}
+
+#endif /* _SYS_ENDIAN_H_ */
diff --git a/usr/src/boot/sys/sys/errno.h b/usr/src/boot/sys/sys/errno.h
new file mode 100644
index 0000000000..d4c59504cc
--- /dev/null
+++ b/usr/src/boot/sys/sys/errno.h
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)errno.h 8.5 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ERRNO_H_
+#define _SYS_ERRNO_H_
+
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+int * __error(void);
+__END_DECLS
+#define errno (* __error())
+#endif
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* Input/output error */
+#define ENXIO 6 /* Device not configured */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file descriptor */
+#define ECHILD 10 /* No child processes */
+#define EDEADLK 11 /* Resource deadlock avoided */
+ /* 11 was EAGAIN */
+#define ENOMEM 12 /* Cannot allocate memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#ifndef _POSIX_SOURCE
+#define ENOTBLK 15 /* Block device required */
+#endif
+#define EBUSY 16 /* Device busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* Operation not supported by device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* Too many open files in system */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Inappropriate ioctl for device */
+#ifndef _POSIX_SOURCE
+#define ETXTBSY 26 /* Text file busy */
+#endif
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only filesystem */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+
+/* math software */
+#define EDOM 33 /* Numerical argument out of domain */
+#define ERANGE 34 /* Result too large */
+
+/* non-blocking and interrupt i/o */
+#define EAGAIN 35 /* Resource temporarily unavailable */
+#ifndef _POSIX_SOURCE
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EINPROGRESS 36 /* Operation now in progress */
+#define EALREADY 37 /* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define ENOTSOCK 38 /* Socket operation on non-socket */
+#define EDESTADDRREQ 39 /* Destination address required */
+#define EMSGSIZE 40 /* Message too long */
+#define EPROTOTYPE 41 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 42 /* Protocol not available */
+#define EPROTONOSUPPORT 43 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
+#define EOPNOTSUPP 45 /* Operation not supported */
+#define ENOTSUP EOPNOTSUPP /* Operation not supported */
+#define EPFNOSUPPORT 46 /* Protocol family not supported */
+#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
+#define EADDRINUSE 48 /* Address already in use */
+#define EADDRNOTAVAIL 49 /* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define ENETDOWN 50 /* Network is down */
+#define ENETUNREACH 51 /* Network is unreachable */
+#define ENETRESET 52 /* Network dropped connection on reset */
+#define ECONNABORTED 53 /* Software caused connection abort */
+#define ECONNRESET 54 /* Connection reset by peer */
+#define ENOBUFS 55 /* No buffer space available */
+#define EISCONN 56 /* Socket is already connected */
+#define ENOTCONN 57 /* Socket is not connected */
+#define ESHUTDOWN 58 /* Can't send after socket shutdown */
+#define ETOOMANYREFS 59 /* Too many references: can't splice */
+#define ETIMEDOUT 60 /* Operation timed out */
+#define ECONNREFUSED 61 /* Connection refused */
+
+#define ELOOP 62 /* Too many levels of symbolic links */
+#endif /* _POSIX_SOURCE */
+#define ENAMETOOLONG 63 /* File name too long */
+
+/* should be rearranged */
+#ifndef _POSIX_SOURCE
+#define EHOSTDOWN 64 /* Host is down */
+#define EHOSTUNREACH 65 /* No route to host */
+#endif /* _POSIX_SOURCE */
+#define ENOTEMPTY 66 /* Directory not empty */
+
+/* quotas & mush */
+#ifndef _POSIX_SOURCE
+#define EPROCLIM 67 /* Too many processes */
+#define EUSERS 68 /* Too many users */
+#define EDQUOT 69 /* Disc quota exceeded */
+
+/* Network File System */
+#define ESTALE 70 /* Stale NFS file handle */
+#define EREMOTE 71 /* Too many levels of remote in path */
+#define EBADRPC 72 /* RPC struct is bad */
+#define ERPCMISMATCH 73 /* RPC version wrong */
+#define EPROGUNAVAIL 74 /* RPC prog. not avail */
+#define EPROGMISMATCH 75 /* Program version wrong */
+#define EPROCUNAVAIL 76 /* Bad procedure for program */
+#endif /* _POSIX_SOURCE */
+
+#define ENOLCK 77 /* No locks available */
+#define ENOSYS 78 /* Function not implemented */
+
+#ifndef _POSIX_SOURCE
+#define EFTYPE 79 /* Inappropriate file type or format */
+#define EAUTH 80 /* Authentication error */
+#define ENEEDAUTH 81 /* Need authenticator */
+#define EIDRM 82 /* Identifier removed */
+#define ENOMSG 83 /* No message of desired type */
+#define EOVERFLOW 84 /* Value too large to be stored in data type */
+#define ECANCELED 85 /* Operation canceled */
+#define EILSEQ 86 /* Illegal byte sequence */
+#define ENOATTR 87 /* Attribute not found */
+
+#define EDOOFUS 88 /* Programming error */
+#endif /* _POSIX_SOURCE */
+
+#define EBADMSG 89 /* Bad message */
+#define EMULTIHOP 90 /* Multihop attempted */
+#define ENOLINK 91 /* Link has been severed */
+#define EPROTO 92 /* Protocol error */
+
+#ifndef _POSIX_SOURCE
+#define ENOTCAPABLE 93 /* Capabilities insufficient */
+#define ECAPMODE 94 /* Not permitted in capability mode */
+#define ENOTRECOVERABLE 95 /* State not recoverable */
+#define EOWNERDEAD 96 /* Previous owner died */
+#endif /* _POSIX_SOURCE */
+
+#ifndef _POSIX_SOURCE
+#define ELAST 96 /* Must be equal largest errno */
+#endif /* _POSIX_SOURCE */
+
+#ifdef _KERNEL
+/* pseudo-errors returned inside kernel to modify return to process */
+#define ERESTART (-1) /* restart syscall */
+#define EJUSTRETURN (-2) /* don't modify regs, just return */
+#define ENOIOCTL (-3) /* ioctl not handled by this layer */
+#define EDIRIOCTL (-4) /* do direct ioctl in GEOM */
+#endif
+
+#endif
diff --git a/usr/src/boot/sys/sys/exec.h b/usr/src/boot/sys/sys/exec.h
new file mode 100644
index 0000000000..0ccba246a8
--- /dev/null
+++ b/usr/src/boot/sys/sys/exec.h
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)exec.h 8.3 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_EXEC_H_
+#define _SYS_EXEC_H_
+
+/*
+ * Before ps_args existed, the following structure, found at the top of
+ * the user stack of each user process, was used by ps(1) to locate
+ * environment and argv strings. Normally ps_argvstr points to the
+ * argv vector, and ps_nargvstr is the same as the program's argc. The
+ * fields ps_envstr and ps_nenvstr are the equivalent for the environment.
+ *
+ * Programs should now use setproctitle(3) to change ps output.
+ * setproctitle() always informs the kernel with sysctl and sets the
+ * pointers in ps_strings. The kern.proc.args sysctl first tries p_args.
+ * If p_args is NULL, it then falls back to reading ps_strings and following
+ * the pointers.
+ */
+struct ps_strings {
+ char **ps_argvstr; /* first of 0 or more argument strings */
+ unsigned int ps_nargvstr; /* the number of argument strings */
+ char **ps_envstr; /* first of 0 or more environment strings */
+ unsigned int ps_nenvstr; /* the number of environment strings */
+};
+
+/*
+ * Address of ps_strings structure (in user space).
+ * Prefer the kern.ps_strings or kern.proc.ps_strings sysctls to this constant.
+ */
+#define PS_STRINGS (USRSTACK - sizeof(struct ps_strings))
+#define SPARE_USRSPACE 4096
+
+struct image_params;
+
+struct execsw {
+ int (*ex_imgact)(struct image_params *);
+ const char *ex_name;
+};
+
+#include <machine/exec.h>
+
+#ifdef _KERNEL
+#include <sys/cdefs.h>
+
+int exec_map_first_page(struct image_params *);
+void exec_unmap_first_page(struct image_params *);
+
+int exec_register(const struct execsw *);
+int exec_unregister(const struct execsw *);
+
+extern int coredump_pack_fileinfo;
+extern int coredump_pack_vmmapinfo;
+
+/*
+ * note: name##_mod cannot be const storage because the
+ * linker_file_sysinit() function modifies _file in the
+ * moduledata_t.
+ */
+
+#include <sys/module.h>
+
+#define EXEC_SET(name, execsw_arg) \
+ static int __CONCAT(name,_modevent)(module_t mod, int type, \
+ void *data) \
+ { \
+ struct execsw *exec = (struct execsw *)data; \
+ int error = 0; \
+ switch (type) { \
+ case MOD_LOAD: \
+ /* printf(#name " module loaded\n"); */ \
+ error = exec_register(exec); \
+ if (error) \
+ printf(__XSTRING(name) "register failed\n"); \
+ break; \
+ case MOD_UNLOAD: \
+ /* printf(#name " module unloaded\n"); */ \
+ error = exec_unregister(exec); \
+ if (error) \
+ printf(__XSTRING(name) " unregister failed\n");\
+ break; \
+ default: \
+ error = EOPNOTSUPP; \
+ break; \
+ } \
+ return error; \
+ } \
+ static moduledata_t __CONCAT(name,_mod) = { \
+ __XSTRING(name), \
+ __CONCAT(name,_modevent), \
+ (void *)& execsw_arg \
+ }; \
+ DECLARE_MODULE_TIED(name, __CONCAT(name,_mod), SI_SUB_EXEC, \
+ SI_ORDER_ANY)
+#endif
+
+#endif
diff --git a/usr/src/boot/sys/sys/fcntl.h b/usr/src/boot/sys/sys/fcntl.h
new file mode 100644
index 0000000000..d4785121b9
--- /dev/null
+++ b/usr/src/boot/sys/sys/fcntl.h
@@ -0,0 +1,332 @@
+/*-
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)fcntl.h 8.3 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_FCNTL_H_
+#define _SYS_FCNTL_H_
+
+/*
+ * This file includes the definitions for open and fcntl
+ * described by POSIX for <fcntl.h>; it also includes
+ * related kernel definitions.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _MODE_T_DECLARED
+typedef __mode_t mode_t;
+#define _MODE_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
+#ifndef _PID_T_DECLARED
+typedef __pid_t pid_t;
+#define _PID_T_DECLARED
+#endif
+
+/*
+ * File status flags: these are used by open(2), fcntl(2).
+ * They are also used (indirectly) in the kernel file structure f_flags,
+ * which is a superset of the open/fcntl flags. Open flags and f_flags
+ * are inter-convertible using OFLAGS(fflags) and FFLAGS(oflags).
+ * Open/fcntl flags begin with O_; kernel-internal flags begin with F.
+ */
+/* open-only flags */
+#define O_RDONLY 0x0000 /* open for reading only */
+#define O_WRONLY 0x0001 /* open for writing only */
+#define O_RDWR 0x0002 /* open for reading and writing */
+#define O_ACCMODE 0x0003 /* mask for above modes */
+
+/*
+ * Kernel encoding of open mode; separate read and write bits that are
+ * independently testable: 1 greater than the above.
+ *
+ * XXX
+ * FREAD and FWRITE are excluded from the #ifdef _KERNEL so that TIOCFLUSH,
+ * which was documented to use FREAD/FWRITE, continues to work.
+ */
+#if __BSD_VISIBLE
+#define FREAD 0x0001
+#define FWRITE 0x0002
+#endif
+#define O_NONBLOCK 0x0004 /* no delay */
+#define O_APPEND 0x0008 /* set append mode */
+#if __BSD_VISIBLE
+#define O_SHLOCK 0x0010 /* open with shared file lock */
+#define O_EXLOCK 0x0020 /* open with exclusive file lock */
+#define O_ASYNC 0x0040 /* signal pgrp when data ready */
+#define O_FSYNC 0x0080 /* synchronous writes */
+#endif
+#define O_SYNC 0x0080 /* POSIX synonym for O_FSYNC */
+#if __POSIX_VISIBLE >= 200809
+#define O_NOFOLLOW 0x0100 /* don't follow symlinks */
+#endif
+#define O_CREAT 0x0200 /* create if nonexistent */
+#define O_TRUNC 0x0400 /* truncate to zero length */
+#define O_EXCL 0x0800 /* error if already exists */
+#ifdef _KERNEL
+#define FHASLOCK 0x4000 /* descriptor holds advisory lock */
+#endif
+
+/* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */
+#define O_NOCTTY 0x8000 /* don't assign controlling terminal */
+
+#if __BSD_VISIBLE
+/* Attempt to bypass buffer cache */
+#define O_DIRECT 0x00010000
+#endif
+
+#if __POSIX_VISIBLE >= 200809
+#define O_DIRECTORY 0x00020000 /* Fail if not directory */
+#define O_EXEC 0x00040000 /* Open for execute only */
+#endif
+#ifdef _KERNEL
+#define FEXEC O_EXEC
+#endif
+
+#if __POSIX_VISIBLE >= 200809
+/* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. */
+#define O_TTY_INIT 0x00080000 /* Restore default termios attributes */
+
+#define O_CLOEXEC 0x00100000
+#endif
+
+#if __BSD_VISIBLE
+#define O_VERIFY 0x00200000 /* open only after verification */
+#endif
+
+/*
+ * XXX missing O_DSYNC, O_RSYNC.
+ */
+
+#ifdef _KERNEL
+
+/* Only for devfs d_close() flags. */
+#define FLASTCLOSE O_DIRECTORY
+#define FREVOKE O_VERIFY
+/* Only for fo_close() from half-succeeded open */
+#define FOPENFAILED O_TTY_INIT
+
+/* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
+#define FFLAGS(oflags) ((oflags) & O_EXEC ? (oflags) : (oflags) + 1)
+#define OFLAGS(fflags) ((fflags) & O_EXEC ? (fflags) : (fflags) - 1)
+
+/* bits to save after open */
+#define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|O_DIRECT|FEXEC)
+/* bits settable by fcntl(F_SETFL, ...) */
+#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FRDAHEAD|O_DIRECT)
+
+#if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \
+ defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4)
+/*
+ * Set by shm_open(3) in older libc's to get automatic MAP_ASYNC
+ * behavior for POSIX shared memory objects (which are otherwise
+ * implemented as plain files).
+ */
+#define FPOSIXSHM O_NOFOLLOW
+#undef FCNTLFLAGS
+#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|FRDAHEAD| \
+ O_DIRECT)
+#endif
+#endif
+
+/*
+ * The O_* flags used to have only F* names, which were used in the kernel
+ * and by fcntl. We retain the F* names for the kernel f_flag field
+ * and for backward compatibility for fcntl. These flags are deprecated.
+ */
+#if __BSD_VISIBLE
+#define FAPPEND O_APPEND /* kernel/compat */
+#define FASYNC O_ASYNC /* kernel/compat */
+#define FFSYNC O_FSYNC /* kernel */
+#define FNONBLOCK O_NONBLOCK /* kernel */
+#define FNDELAY O_NONBLOCK /* compat */
+#define O_NDELAY O_NONBLOCK /* compat */
+#endif
+
+/*
+ * We are out of bits in f_flag (which is a short). However,
+ * the flag bits not set in FMASK are only meaningful in the
+ * initial open syscall. Those bits can thus be given a
+ * different meaning for fcntl(2).
+ */
+#if __BSD_VISIBLE
+/* Read ahead */
+#define FRDAHEAD O_CREAT
+#endif
+
+#if __POSIX_VISIBLE >= 200809
+/*
+ * Magic value that specify the use of the current working directory
+ * to determine the target of relative file paths in the openat() and
+ * similar syscalls.
+ */
+#define AT_FDCWD -100
+
+/*
+ * Miscellaneous flags for the *at() syscalls.
+ */
+#define AT_EACCESS 0x100 /* Check access using effective user and group ID */
+#define AT_SYMLINK_NOFOLLOW 0x200 /* Do not follow symbolic links */
+#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic link */
+#define AT_REMOVEDIR 0x800 /* Remove directory instead of file */
+#endif
+
+/*
+ * Constants used for fcntl(2)
+ */
+
+/* command values */
+#define F_DUPFD 0 /* duplicate file descriptor */
+#define F_GETFD 1 /* get file descriptor flags */
+#define F_SETFD 2 /* set file descriptor flags */
+#define F_GETFL 3 /* get file status flags */
+#define F_SETFL 4 /* set file status flags */
+#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
+#define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */
+#define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */
+#endif
+#if __BSD_VISIBLE
+#define F_OGETLK 7 /* get record locking information */
+#define F_OSETLK 8 /* set record locking information */
+#define F_OSETLKW 9 /* F_SETLK; wait if blocked */
+#define F_DUP2FD 10 /* duplicate file descriptor to arg */
+#endif
+#define F_GETLK 11 /* get record locking information */
+#define F_SETLK 12 /* set record locking information */
+#define F_SETLKW 13 /* F_SETLK; wait if blocked */
+#if __BSD_VISIBLE
+#define F_SETLK_REMOTE 14 /* debugging support for remote locks */
+#define F_READAHEAD 15 /* read ahead */
+#define F_RDAHEAD 16 /* Darwin compatible read ahead */
+#endif
+#if __POSIX_VISIBLE >= 200809
+#define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */
+#endif
+#if __BSD_VISIBLE
+#define F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */
+#endif
+
+/* file descriptor flags (F_GETFD, F_SETFD) */
+#define FD_CLOEXEC 1 /* close-on-exec flag */
+
+/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
+#define F_RDLCK 1 /* shared or read lock */
+#define F_UNLCK 2 /* unlock */
+#define F_WRLCK 3 /* exclusive or write lock */
+#if __BSD_VISIBLE
+#define F_UNLCKSYS 4 /* purge locks for a given system ID */
+#define F_CANCEL 5 /* cancel an async lock request */
+#endif
+#ifdef _KERNEL
+#define F_WAIT 0x010 /* Wait until lock is granted */
+#define F_FLOCK 0x020 /* Use flock(2) semantics for lock */
+#define F_POSIX 0x040 /* Use POSIX semantics for lock */
+#define F_REMOTE 0x080 /* Lock owner is remote NFS client */
+#define F_NOINTR 0x100 /* Ignore signals when waiting */
+#endif
+
+/*
+ * Advisory file segment locking data type -
+ * information passed to system by user
+ */
+struct flock {
+ off_t l_start; /* starting offset */
+ off_t l_len; /* len = 0 means until end of file */
+ pid_t l_pid; /* lock owner */
+ short l_type; /* lock type: read/write, etc. */
+ short l_whence; /* type of l_start */
+ int l_sysid; /* remote system id or zero for local */
+};
+
+#if __BSD_VISIBLE
+/*
+ * Old advisory file segment locking data type,
+ * before adding l_sysid.
+ */
+struct __oflock {
+ off_t l_start; /* starting offset */
+ off_t l_len; /* len = 0 means until end of file */
+ pid_t l_pid; /* lock owner */
+ short l_type; /* lock type: read/write, etc. */
+ short l_whence; /* type of l_start */
+};
+#endif
+
+#if __BSD_VISIBLE
+/* lock operations for flock(2) */
+#define LOCK_SH 0x01 /* shared file lock */
+#define LOCK_EX 0x02 /* exclusive file lock */
+#define LOCK_NB 0x04 /* don't block when locking */
+#define LOCK_UN 0x08 /* unlock file */
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+/*
+ * Advice to posix_fadvise
+ */
+#define POSIX_FADV_NORMAL 0 /* no special treatment */
+#define POSIX_FADV_RANDOM 1 /* expect random page references */
+#define POSIX_FADV_SEQUENTIAL 2 /* expect sequential page references */
+#define POSIX_FADV_WILLNEED 3 /* will need these pages */
+#define POSIX_FADV_DONTNEED 4 /* dont need these pages */
+#define POSIX_FADV_NOREUSE 5 /* access data only once */
+#endif
+
+#ifndef _KERNEL
+__BEGIN_DECLS
+int open(const char *, int, ...);
+int creat(const char *, mode_t);
+int fcntl(int, int, ...);
+#if __BSD_VISIBLE
+int flock(int, int);
+#endif
+#if __POSIX_VISIBLE >= 200809
+int openat(int, const char *, int, ...);
+#endif
+#if __POSIX_VISIBLE >= 200112
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+#endif
+__END_DECLS
+#endif
+
+#endif /* !_SYS_FCNTL_H_ */
diff --git a/usr/src/boot/sys/sys/gpt.h b/usr/src/boot/sys/sys/gpt.h
new file mode 100644
index 0000000000..9f90438399
--- /dev/null
+++ b/usr/src/boot/sys/sys/gpt.h
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_GPT_H_
+#define _SYS_GPT_H_
+
+#include <sys/uuid.h>
+
+struct gpt_hdr {
+ char hdr_sig[8];
+#define GPT_HDR_SIG "EFI PART"
+ uint32_t hdr_revision;
+#define GPT_HDR_REVISION 0x00010000
+ uint32_t hdr_size;
+ uint32_t hdr_crc_self;
+ uint32_t __reserved;
+ uint64_t hdr_lba_self;
+ uint64_t hdr_lba_alt;
+ uint64_t hdr_lba_start;
+ uint64_t hdr_lba_end;
+ struct uuid hdr_uuid;
+ uint64_t hdr_lba_table;
+ uint32_t hdr_entries;
+ uint32_t hdr_entsz;
+ uint32_t hdr_crc_table;
+ /*
+ * The header as defined in the EFI spec is not a multiple of 8 bytes
+ * and given that the alignment requirement is on an 8 byte boundary,
+ * padding will happen. We make the padding explicit so that we can
+ * correct the value returned by sizeof() when we put the size of the
+ * header in field hdr_size, or otherwise use offsetof().
+ */
+ uint32_t padding;
+};
+
+struct gpt_ent {
+ struct uuid ent_type;
+ struct uuid ent_uuid;
+ uint64_t ent_lba_start;
+ uint64_t ent_lba_end;
+ uint64_t ent_attr;
+#define GPT_ENT_ATTR_PLATFORM (1ULL << 0)
+#define GPT_ENT_ATTR_BOOTME (1ULL << 59)
+#define GPT_ENT_ATTR_BOOTONCE (1ULL << 58)
+#define GPT_ENT_ATTR_BOOTFAILED (1ULL << 57)
+ uint16_t ent_name[36]; /* UTF-16. */
+};
+
+#define GPT_ENT_TYPE_UNUSED \
+ {0x00000000,0x0000,0x0000,0x00,0x00,{0x00,0x00,0x00,0x00,0x00,0x00}}
+#define GPT_ENT_TYPE_EFI \
+ {0xc12a7328,0xf81f,0x11d2,0xba,0x4b,{0x00,0xa0,0xc9,0x3e,0xc9,0x3b}}
+#define GPT_ENT_TYPE_MBR \
+ {0x024dee41,0x33e7,0x11d3,0x9d,0x69,{0x00,0x08,0xc7,0x81,0xf3,0x9f}}
+#define GPT_ENT_TYPE_FREEBSD \
+ {0x516e7cb4,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+#define GPT_ENT_TYPE_FREEBSD_BOOT \
+ {0x83bd6b9d,0x7f41,0x11dc,0xbe,0x0b,{0x00,0x15,0x60,0xb8,0x4f,0x0f}}
+#define GPT_ENT_TYPE_FREEBSD_NANDFS \
+ {0x74ba7dd9,0xa689,0x11e1,0xbd,0x04,{0x00,0xe0,0x81,0x28,0x6a,0xcf}}
+#define GPT_ENT_TYPE_FREEBSD_SWAP \
+ {0x516e7cb5,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+#define GPT_ENT_TYPE_FREEBSD_UFS \
+ {0x516e7cb6,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+#define GPT_ENT_TYPE_FREEBSD_VINUM \
+ {0x516e7cb8,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+#define GPT_ENT_TYPE_FREEBSD_ZFS \
+ {0x516e7cba,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+#define GPT_ENT_TYPE_PREP_BOOT \
+ {0x9e1a2d38,0xc612,0x4316,0xaa,0x26,{0x8b,0x49,0x52,0x1e,0x5a,0x8b}}
+
+/*
+ * The following are unused but documented here to avoid reuse.
+ *
+ * GPT_ENT_TYPE_FREEBSD_UFS2 \
+ * {0x516e7cb7,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}}
+ */
+
+/*
+ * Foreign partition types that we're likely to encounter. Note that Linux
+ * apparently choose to share data partitions with MS. I don't what the
+ * advantage might be. I can see how sharing swap partitions is advantageous
+ * though.
+ */
+#define GPT_ENT_TYPE_MS_BASIC_DATA \
+ {0xebd0a0a2,0xb9e5,0x4433,0x87,0xc0,{0x68,0xb6,0xb7,0x26,0x99,0xc7}}
+#define GPT_ENT_TYPE_MS_LDM_DATA \
+ {0xaf9b60a0,0x1431,0x4f62,0xbc,0x68,{0x33,0x11,0x71,0x4a,0x69,0xad}}
+#define GPT_ENT_TYPE_MS_LDM_METADATA \
+ {0x5808c8aa,0x7e8f,0x42e0,0x85,0xd2,{0xe1,0xe9,0x04,0x34,0xcf,0xb3}}
+#define GPT_ENT_TYPE_MS_RECOVERY \
+ {0xde94bba4,0x06d1,0x4d40,0xa1,0x6a,{0xbf,0xd5,0x01,0x79,0xd6,0xac}}
+#define GPT_ENT_TYPE_MS_RESERVED \
+ {0xe3c9e316,0x0b5c,0x4db8,0x81,0x7d,{0xf9,0x2d,0xf0,0x02,0x15,0xae}}
+#define GPT_ENT_TYPE_MS_SPACES \
+ {0xe75caf8f,0xf680,0x4cee,0xaf,0xa3,{0xb0,0x01,0xe5,0x6e,0xfc,0x2d}}
+
+#define GPT_ENT_TYPE_LINUX_DATA \
+ {0x0fc63daf,0x8483,0x4772,0x8e,0x79,{0x3d,0x69,0xd8,0x47,0x7d,0xe4}}
+#define GPT_ENT_TYPE_LINUX_RAID \
+ {0xa19d880f,0x05fc,0x4d3b,0xa0,0x06,{0x74,0x3f,0x0f,0x84,0x91,0x1e}}
+#define GPT_ENT_TYPE_LINUX_SWAP \
+ {0x0657fd6d,0xa4ab,0x43c4,0x84,0xe5,{0x09,0x33,0xc8,0x4b,0x4f,0x4f}}
+#define GPT_ENT_TYPE_LINUX_LVM \
+ {0xe6d6d379,0xf507,0x44c2,0xa2,0x3c,{0x23,0x8f,0x2a,0x3d,0xf9,0x28}}
+
+#define GPT_ENT_TYPE_VMFS \
+ {0xaa31e02a,0x400f,0x11db,0x95,0x90,{0x00,0x0c,0x29,0x11,0xd1,0xb8}}
+#define GPT_ENT_TYPE_VMKDIAG \
+ {0x9d275380,0x40ad,0x11db,0xbf,0x97,{0x00,0x0c,0x29,0x11,0xd1,0xb8}}
+#define GPT_ENT_TYPE_VMRESERVED \
+ {0x9198effc,0x31c0,0x11db,0x8f,0x78,{0x00,0x0c,0x29,0x11,0xd1,0xb8}}
+#define GPT_ENT_TYPE_VMVSANHDR \
+ {0x381cfccc,0x7288,0x11e0,0x92,0xee,{0x00,0x0c,0x29,0x11,0xd0,0xb2}}
+
+#define GPT_ENT_TYPE_APPLE_BOOT \
+ {0x426F6F74,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_HFS \
+ {0x48465300,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_UFS \
+ {0x55465300,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_ZFS \
+ {0x6a898cc3,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}}
+#define GPT_ENT_TYPE_APPLE_RAID \
+ {0x52414944,0x0000,0x11aa,0xaa,0x22,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_RAID_OFFLINE \
+ {0x52414944,0x5f4f,0x11aa,0xaa,0x22,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_LABEL \
+ {0x4C616265,0x6c00,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_TV_RECOVERY \
+ {0x5265636f,0x7665,0x11AA,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+#define GPT_ENT_TYPE_APPLE_CORE_STORAGE \
+ {0x53746f72,0x6167,0x11AA,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}}
+
+#define GPT_ENT_TYPE_NETBSD_FFS \
+ {0x49f48d5a,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+#define GPT_ENT_TYPE_NETBSD_LFS \
+ {0x49f48d82,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+#define GPT_ENT_TYPE_NETBSD_SWAP \
+ {0x49f48d32,0xb10e,0x11dc,0xB9,0x9B,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+#define GPT_ENT_TYPE_NETBSD_RAID \
+ {0x49f48daa,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+#define GPT_ENT_TYPE_NETBSD_CCD \
+ {0x2db519c4,0xb10f,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+#define GPT_ENT_TYPE_NETBSD_CGD \
+ {0x2db519ec,0xb10f,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}}
+
+#define GPT_ENT_TYPE_DRAGONFLY_LABEL32 \
+ {0x9d087404,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_SWAP \
+ {0x9d58fdbd,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_UFS1 \
+ {0x9d94ce7c,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_VINUM \
+ {0x9dd4478f,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_CCD \
+ {0xdbd5211b,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_LABEL64 \
+ {0x3d48ce54,0x1d16,0x11dc,0x86,0x96,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_LEGACY \
+ {0xbd215ab2,0x1d16,0x11dc,0x86,0x96,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_HAMMER \
+ {0x61dc63ac,0x6e38,0x11dc,0x85,0x13,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+#define GPT_ENT_TYPE_DRAGONFLY_HAMMER2 \
+ {0x5cbb9ad1,0x862d,0x11dc,0xa9,0x4d,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}}
+
+#define GPT_ENT_TYPE_CHROMEOS_FIRMWARE \
+ {0xcab6e88e,0xabf3,0x4102,0xa0,0x7a,{0xd4,0xbb,0x9b,0xe3,0xc1,0xd3}}
+#define GPT_ENT_TYPE_CHROMEOS_KERNEL \
+ {0xfe3a2a5d,0x4f32,0x41a7,0xb7,0x25,{0xac,0xcc,0x32,0x85,0xa3,0x09}}
+#define GPT_ENT_TYPE_CHROMEOS_RESERVED \
+ {0x2e0a753d,0x9e48,0x43b0,0x83,0x37,{0xb1,0x51,0x92,0xcb,0x1b,0x5e}}
+#define GPT_ENT_TYPE_CHROMEOS_ROOT \
+ {0x3cb8e202,0x3b7e,0x47dd,0x8a,0x3c,{0x7f,0xf2,0xa1,0x3c,0xfc,0xec}}
+
+#define GPT_ENT_TYPE_OPENBSD_DATA \
+ {0x824cc7a0,0x36a8,0x11e3,0x89,0x0a,{0x95,0x25,0x19,0xad,0x3f,0x61}}
+
+#define GPT_ENT_TYPE_ILLUMOS_UFS \
+ {0x6a85cf4d,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}}
+#define GPT_ENT_TYPE_ILLUMOS_ZFS \
+ {0x6a898cc3,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}}
+#define GPT_ENT_TYPE_RESERVED \
+ {0x6a945a3b,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}}
+
+/*
+ * Boot partition used by GRUB 2.
+ */
+#define GPT_ENT_TYPE_BIOS_BOOT \
+ {0x21686148,0x6449,0x6e6f,0x74,0x4e,{0x65,0x65,0x64,0x45,0x46,0x49}}
+
+#endif /* _SYS_GPT_H_ */
diff --git a/usr/src/boot/sys/sys/imgact_aout.h b/usr/src/boot/sys/sys/imgact_aout.h
new file mode 100644
index 0000000000..3eaa8e75a6
--- /dev/null
+++ b/usr/src/boot/sys/sys/imgact_aout.h
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)exec.h 8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef _IMGACT_AOUT_H_
+#define _IMGACT_AOUT_H_
+
+#define N_GETMAGIC(ex) \
+ ( le32toh((ex).a_midmag) & 0xffff )
+#define N_GETMID(ex) \
+ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \
+ ((ex).a_midmag >> 16) & 0x03ff )
+#define N_GETFLAG(ex) \
+ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \
+ ((ex).a_midmag >> 26) & 0x3f )
+#define N_SETMAGIC(ex,mag,mid,flag) \
+ ( (ex).a_midmag = htole32((((flag) & 0x3f) <<26) | \
+ (((mid) & 0x03ff) << 16) | \
+ ((mag) & 0xffff)) )
+
+#define N_GETMAGIC_NET(ex) \
+ (ntohl((ex).a_midmag) & 0xffff)
+#define N_GETMID_NET(ex) \
+ ((ntohl((ex).a_midmag) >> 16) & 0x03ff)
+#define N_GETFLAG_NET(ex) \
+ ((ntohl((ex).a_midmag) >> 26) & 0x3f)
+#define N_SETMAGIC_NET(ex,mag,mid,flag) \
+ ( (ex).a_midmag = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) \
+ | (((mag)&0xffff)) ) )
+
+#define N_ALIGN(ex,x) \
+ (N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC || \
+ N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \
+ ((x) + __LDPGSZ - 1) & ~(uint32_t)(__LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define N_BADMAG(ex) \
+ (N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \
+ N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC && \
+ N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \
+ N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC)
+
+
+/* Address of the bottom of the text segment. */
+/*
+ * This can not be done right. Abuse a_entry in some cases to handle kernels.
+ */
+#define N_TXTADDR(ex) \
+ ((N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC || \
+ N_GETMAGIC(ex) == ZMAGIC) ? \
+ (le32toh((ex).a_entry) < le32toh((ex).a_text) ? 0 : \
+ le32toh((ex).a_entry) & ~__LDPGSZ) : __LDPGSZ)
+
+/* Address of the bottom of the data segment. */
+#define N_DATADDR(ex) \
+ N_ALIGN(ex, N_TXTADDR(ex) + le32toh((ex).a_text))
+
+/* Text segment offset. */
+#define N_TXTOFF(ex) \
+ (N_GETMAGIC(ex) == ZMAGIC ? __LDPGSZ : (N_GETMAGIC(ex) == QMAGIC || \
+ N_GETMAGIC_NET(ex) == ZMAGIC) ? 0 : sizeof(struct exec))
+
+/* Data segment offset. */
+#define N_DATOFF(ex) \
+ N_ALIGN(ex, N_TXTOFF(ex) + le32toh((ex).a_text))
+
+/* Relocation table offset. */
+#define N_RELOFF(ex) \
+ N_ALIGN(ex, N_DATOFF(ex) + le32toh((ex).a_data))
+
+/* Symbol table offset. */
+#define N_SYMOFF(ex) \
+ (N_RELOFF(ex) + le32toh((ex).a_trsize) + le32toh((ex).a_drsize))
+
+/* String table offset. */
+#define N_STROFF(ex) (N_SYMOFF(ex) + le32toh((ex).a_syms))
+
+/*
+ * Header prepended to each a.out file.
+ * Only manipulate the a_midmag field via the
+ * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros.
+ */
+
+struct exec {
+ uint32_t a_midmag; /* flags<<26 | mid<<16 | magic */
+ uint32_t a_text; /* text segment size */
+ uint32_t a_data; /* initialized data size */
+ uint32_t a_bss; /* uninitialized data size */
+ uint32_t a_syms; /* symbol table size */
+ uint32_t a_entry; /* entry point */
+ uint32_t a_trsize; /* text relocation size */
+ uint32_t a_drsize; /* data relocation size */
+};
+#define a_magic a_midmag /* Hack for emulators */
+
+/* a_magic */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+#define QMAGIC 0314 /* "compact" demand load format */
+
+/* a_mid */
+#define MID_ZERO 0 /* unknown - implementation dependent */
+#define MID_SUN010 1 /* sun 68010/68020 binary */
+#define MID_SUN020 2 /* sun 68020-only binary */
+#define MID_I386 134 /* i386 BSD binary */
+#define MID_SPARC 138 /* sparc */
+#define MID_ARM6 143 /* ARM6 */
+#define MID_HP200 200 /* hp200 (68010) BSD binary */
+#define MID_HP300 300 /* hp300 (68020+68881) BSD binary */
+#define MID_HPUX 0x20C /* hp200/300 HP-UX binary */
+#define MID_HPUX800 0x20B /* hp800 HP-UX binary */
+
+/*
+ * a_flags
+ */
+#define EX_PIC 0x10 /* contains position independent code */
+#define EX_DYNAMIC 0x20 /* contains run-time link-edit info */
+#define EX_DPMASK 0x30 /* mask for the above */
+
+#ifdef _KERNEL
+struct thread;
+struct vnode;
+
+int aout_coredump(struct thread *td, struct vnode *vp, off_t limit,
+ int flags);
+#endif
+
+#endif /* !_IMGACT_AOUT_H_ */
diff --git a/usr/src/boot/sys/sys/ioccom.h b/usr/src/boot/sys/sys/ioccom.h
new file mode 100644
index 0000000000..5669088dc9
--- /dev/null
+++ b/usr/src/boot/sys/sys/ioccom.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ioccom.h 8.2 (Berkeley) 3/28/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_IOCCOM_H_
+#define _SYS_IOCCOM_H_
+
+/*
+ * Ioctl's have the command encoded in the lower word, and the size of
+ * any in or out parameters in the upper word. The high 3 bits of the
+ * upper word are used to encode the in/out status of the parameter.
+ */
+#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */
+#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */
+#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
+#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
+#define IOCGROUP(x) (((x) >> 8) & 0xff)
+
+#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+#define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN)
+
+#define _IOC(inout,group,num,len) ((unsigned long) \
+ ((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num)))
+#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
+#define _IOWINT(g,n) _IOC(IOC_VOID, (g), (n), sizeof(int))
+#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
+#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
+
+#ifdef _KERNEL
+
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+#define IOCPARM_IVAL(x) ((int)(intptr_t)(void *)*(caddr_t *)(void *)(x))
+#endif
+
+#else
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int ioctl(int, unsigned long, ...);
+__END_DECLS
+
+#endif
+
+#endif /* !_SYS_IOCCOM_H_ */
diff --git a/usr/src/boot/sys/sys/limits.h b/usr/src/boot/sys/sys/limits.h
new file mode 100644
index 0000000000..c56a337deb
--- /dev/null
+++ b/usr/src/boot/sys/sys/limits.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_LIMITS_H_
+#define _SYS_LIMITS_H_
+
+#include <sys/cdefs.h>
+#include <machine/_limits.h>
+
+#define CHAR_BIT __CHAR_BIT /* number of bits in a char */
+
+#define SCHAR_MAX __SCHAR_MAX /* max value for a signed char */
+#define SCHAR_MIN __SCHAR_MIN /* min value for a signed char */
+
+#define UCHAR_MAX __UCHAR_MAX /* max value for an unsigned char */
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MAX UCHAR_MAX /* max value for a char */
+#define CHAR_MIN 0 /* min value for a char */
+#else
+#define CHAR_MAX SCHAR_MAX
+#define CHAR_MIN SCHAR_MIN
+#endif
+
+#define USHRT_MAX __USHRT_MAX /* max value for an unsigned short */
+#define SHRT_MAX __SHRT_MAX /* max value for a short */
+#define SHRT_MIN __SHRT_MIN /* min value for a short */
+
+#define UINT_MAX __UINT_MAX /* max value for an unsigned int */
+#define INT_MAX __INT_MAX /* max value for an int */
+#define INT_MIN __INT_MIN /* min value for an int */
+
+#define ULONG_MAX __ULONG_MAX /* max for an unsigned long */
+#define LONG_MAX __LONG_MAX /* max for a long */
+#define LONG_MIN __LONG_MIN /* min for a long */
+
+#ifdef __LONG_LONG_SUPPORTED
+#define ULLONG_MAX __ULLONG_MAX /* max for an unsigned long long */
+#define LLONG_MAX __LLONG_MAX /* max for a long long */
+#define LLONG_MIN __LLONG_MIN /* min for a long long */
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SSIZE_MAX __SSIZE_MAX /* max value for an ssize_t */
+#endif
+
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#define SIZE_T_MAX __SIZE_T_MAX /* max value for a size_t */
+
+#define OFF_MAX __OFF_MAX /* max value for an off_t */
+#define OFF_MIN __OFF_MIN /* min value for an off_t */
+#endif
+
+#if __BSD_VISIBLE
+#define GID_MAX UINT_MAX /* max value for a gid_t */
+#define UID_MAX UINT_MAX /* max value for a uid_t */
+
+#define UQUAD_MAX (__UQUAD_MAX) /* max value for a uquad_t */
+#define QUAD_MAX (__QUAD_MAX) /* max value for a quad_t */
+#define QUAD_MIN (__QUAD_MIN) /* min value for a quad_t */
+#endif
+
+#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
+#define LONG_BIT __LONG_BIT
+#define WORD_BIT __WORD_BIT
+#endif
+
+#if __POSIX_VISIBLE
+#define MQ_PRIO_MAX 64
+#endif
+
+#endif /* !_SYS_LIMITS_H_ */
diff --git a/usr/src/boot/sys/sys/link_elf.h b/usr/src/boot/sys/sys/link_elf.h
new file mode 100644
index 0000000000..c228f1d273
--- /dev/null
+++ b/usr/src/boot/sys/sys/link_elf.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * RRS section definitions.
+ *
+ * The layout of some data structures defined in this header file is
+ * such that we can provide compatibility with the SunOS 4.x shared
+ * library scheme.
+ */
+
+#ifndef _SYS_LINK_ELF_H_
+#define _SYS_LINK_ELF_H_
+
+#include <sys/elf.h>
+
+/*
+ * Flags that describe the origin of the entries in Dl_serinfo.
+ * SunOS has these in <sys/link.h>, we follow the suit.
+ */
+#define LA_SER_ORIG 0x01 /* original (needed) name */
+#define LA_SER_LIBPATH 0x02 /* LD_LIBRARY_PATH entry prepended */
+#define LA_SER_RUNPATH 0x04 /* runpath entry prepended */
+#define LA_SER_CONFIG 0x08 /* configuration entry prepended */
+#define LA_SER_DEFAULT 0x40 /* default path prepended */
+#define LA_SER_SECURE 0x80 /* default (secure) path prepended */
+
+typedef struct link_map {
+ caddr_t l_addr; /* Base Address of library */
+#ifdef __mips__
+ caddr_t l_offs; /* Load Offset of library */
+#endif
+ const char *l_name; /* Absolute Path to Library */
+ const void *l_ld; /* Pointer to .dynamic in memory */
+ struct link_map *l_next, *l_prev; /* linked list of of mapped libs */
+} Link_map;
+
+struct r_debug {
+ int r_version; /* not used */
+ struct link_map *r_map; /* list of loaded images */
+ void (*r_brk)(struct r_debug *, struct link_map *);
+ /* pointer to break point */
+ enum {
+ RT_CONSISTENT, /* things are stable */
+ RT_ADD, /* adding a shared library */
+ RT_DELETE /* removing a shared library */
+ } r_state;
+};
+
+struct dl_phdr_info
+{
+ Elf_Addr dlpi_addr; /* module relocation base */
+ const char *dlpi_name; /* module name */
+ const Elf_Phdr *dlpi_phdr; /* pointer to module's phdr */
+ Elf_Half dlpi_phnum; /* number of entries in phdr */
+ unsigned long long int dlpi_adds; /* total # of loads */
+ unsigned long long int dlpi_subs; /* total # of unloads */
+ size_t dlpi_tls_modid;
+ void *dlpi_tls_data;
+};
+
+__BEGIN_DECLS
+
+typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *);
+extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
+int _rtld_addr_phdr(const void *, struct dl_phdr_info *);
+int _rtld_get_stack_prot(void);
+int _rtld_is_dlopened(void *);
+
+#ifdef __ARM_EABI__
+void * dl_unwind_find_exidx(const void *, int *);
+#endif
+
+__END_DECLS
+
+#endif /* _SYS_LINK_ELF_H_ */
diff --git a/usr/src/boot/sys/sys/linker.h b/usr/src/boot/sys/sys/linker.h
new file mode 100644
index 0000000000..5248bfb459
--- /dev/null
+++ b/usr/src/boot/sys/sys/linker.h
@@ -0,0 +1,353 @@
+/*-
+ * Copyright (c) 1997-2000 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_LINKER_H_
+#define _SYS_LINKER_H_
+
+#ifdef _KERNEL
+
+#include <machine/elf.h>
+#include <sys/kobj.h>
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_LINKER);
+#endif
+
+struct mod_depend;
+
+/*
+ * Object representing a file which has been loaded by the linker.
+ */
+typedef struct linker_file* linker_file_t;
+typedef TAILQ_HEAD(, linker_file) linker_file_list_t;
+
+typedef caddr_t linker_sym_t; /* opaque symbol */
+typedef c_caddr_t c_linker_sym_t; /* const opaque symbol */
+typedef int (*linker_function_name_callback_t)(const char *, void *);
+
+/*
+ * expanded out linker_sym_t
+ */
+typedef struct linker_symval {
+ const char* name;
+ caddr_t value;
+ size_t size;
+} linker_symval_t;
+
+typedef int (*linker_function_nameval_callback_t)(linker_file_t, int, linker_symval_t *, void *);
+
+struct common_symbol {
+ STAILQ_ENTRY(common_symbol) link;
+ char* name;
+ caddr_t address;
+};
+
+struct linker_file {
+ KOBJ_FIELDS;
+ int refs; /* reference count */
+ int userrefs; /* kldload(2) count */
+ int flags;
+#define LINKER_FILE_LINKED 0x1 /* file has been fully linked */
+ TAILQ_ENTRY(linker_file) link; /* list of all loaded files */
+ char* filename; /* file which was loaded */
+ char* pathname; /* file name with full path */
+ int id; /* unique id */
+ caddr_t address; /* load address */
+ size_t size; /* size of file */
+ caddr_t ctors_addr; /* address of .ctors */
+ size_t ctors_size; /* size of .ctors */
+ int ndeps; /* number of dependencies */
+ linker_file_t* deps; /* list of dependencies */
+ STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
+ TAILQ_HEAD(, module) modules; /* modules in this file */
+ TAILQ_ENTRY(linker_file) loaded; /* preload dependency support */
+ int loadcnt; /* load counter value */
+
+ /*
+ * Function Boundary Tracing (FBT) or Statically Defined Tracing (SDT)
+ * fields.
+ */
+ int nenabled; /* number of enabled probes. */
+ int fbt_nentries; /* number of fbt entries created. */
+};
+
+/*
+ * Object implementing a class of file (a.out, elf, etc.)
+ */
+typedef struct linker_class *linker_class_t;
+typedef TAILQ_HEAD(, linker_class) linker_class_list_t;
+
+struct linker_class {
+ KOBJ_CLASS_FIELDS;
+ TAILQ_ENTRY(linker_class) link; /* list of all file classes */
+};
+
+/*
+ * Function type used when iterating over the list of linker files.
+ */
+typedef int linker_predicate_t(linker_file_t, void *);
+
+/*
+ * The "file" for the kernel.
+ */
+extern linker_file_t linker_kernel_file;
+
+/*
+ * Obtain a reference to a module, loading it if required.
+ */
+int linker_reference_module(const char* _modname, struct mod_depend *_verinfo,
+ linker_file_t* _result);
+
+/*
+ * Release a reference to a module, unloading it if there are no more
+ * references. Note that one should either provide a module name and
+ * optional version info or a linker file, but not both.
+ */
+int linker_release_module(const char *_modname, struct mod_depend *_verinfo,
+ linker_file_t _file);
+
+/*
+ * Iterate over all of the currently loaded linker files calling the
+ * predicate function while the function returns 0. Returns the value
+ * returned by the last predicate function.
+ */
+int linker_file_foreach(linker_predicate_t *_predicate, void *_context);
+
+/*
+ * Lookup a symbol in a file. If deps is TRUE, look in dependencies
+ * if not found in file.
+ */
+caddr_t linker_file_lookup_symbol(linker_file_t _file, const char* _name,
+ int _deps);
+
+/*
+ * Lookup a linker set in a file. Return pointers to the first entry,
+ * last + 1, and count of entries. Use: for (p = start; p < stop; p++) {}
+ * void *start is really: "struct yoursetmember ***start;"
+ */
+int linker_file_lookup_set(linker_file_t _file, const char *_name,
+ void *_start, void *_stop, int *_count);
+
+/*
+ * List all functions in a file.
+ */
+int linker_file_function_listall(linker_file_t,
+ linker_function_nameval_callback_t, void *);
+
+/*
+ * Functions soley for use by the linker class handlers.
+ */
+int linker_add_class(linker_class_t _cls);
+int linker_file_unload(linker_file_t _file, int flags);
+int linker_load_dependencies(linker_file_t _lf);
+linker_file_t linker_make_file(const char* _filename, linker_class_t _cls);
+
+/*
+ * DDB Helpers, tuned specifically for ddb/db_kld.c
+ */
+int linker_ddb_lookup(const char *_symstr, c_linker_sym_t *_sym);
+int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym,
+ long *_diffp);
+int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval);
+int linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset);
+
+/*
+ * stack(9) helper for situations where kernel locking is required.
+ */
+int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset);
+
+
+/* HWPMC helper */
+void *linker_hwpmc_list_objects(void);
+
+#endif /* _KERNEL */
+
+/*
+ * Module information subtypes
+ */
+#define MODINFO_END 0x0000 /* End of list */
+#define MODINFO_NAME 0x0001 /* Name of module (string) */
+#define MODINFO_TYPE 0x0002 /* Type of module (string) */
+#define MODINFO_ADDR 0x0003 /* Loaded address */
+#define MODINFO_SIZE 0x0004 /* Size of module */
+#define MODINFO_EMPTY 0x0005 /* Has been deleted */
+#define MODINFO_ARGS 0x0006 /* Parameters string */
+#define MODINFO_METADATA 0x8000 /* Module-specfic */
+
+#define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */
+#define MODINFOMD_ELFHDR 0x0002 /* ELF header */
+#define MODINFOMD_SSYM 0x0003 /* start of symbols */
+#define MODINFOMD_ESYM 0x0004 /* end of symbols */
+#define MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */
+/* These values are MD on these two platforms */
+#if !defined(__sparc64__) && !defined(__powerpc__)
+#define MODINFOMD_ENVP 0x0006 /* envp[] */
+#define MODINFOMD_HOWTO 0x0007 /* boothowto */
+#define MODINFOMD_KERNEND 0x0008 /* kernend */
+#endif
+#define MODINFOMD_SHDR 0x0009 /* section header table */
+#define MODINFOMD_CTORS_ADDR 0x000a /* address of .ctors */
+#define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */
+#define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */
+#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
+
+#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */
+
+#ifdef _KERNEL
+#define MD_FETCH(mdp, info, type) ({ \
+ type *__p; \
+ __p = (type *)preload_search_info((mdp), MODINFO_METADATA | (info)); \
+ __p ? *__p : 0; \
+})
+#endif
+
+#define LINKER_HINTS_VERSION 1 /* linker.hints file version */
+#define LINKER_HINTS_MAX (1 << 20) /* Allow at most 1MB for linker.hints */
+
+#ifdef _KERNEL
+
+/*
+ * Module lookup
+ */
+extern vm_offset_t preload_addr_relocate;
+extern caddr_t preload_metadata;
+
+extern void * preload_fetch_addr(caddr_t _mod);
+extern size_t preload_fetch_size(caddr_t _mod);
+extern caddr_t preload_search_by_name(const char *_name);
+extern caddr_t preload_search_by_type(const char *_type);
+extern caddr_t preload_search_next_name(caddr_t _base);
+extern caddr_t preload_search_info(caddr_t _mod, int _inf);
+extern void preload_delete_name(const char *_name);
+extern void preload_bootstrap_relocate(vm_offset_t _offset);
+
+#ifdef KLD_DEBUG
+
+extern int kld_debug;
+#define KLD_DEBUG_FILE 1 /* file load/unload */
+#define KLD_DEBUG_SYM 2 /* symbol lookup */
+
+#define KLD_DPF(cat, args) \
+ do { \
+ if (kld_debug & KLD_DEBUG_##cat) printf args; \
+ } while (0)
+
+#else
+
+#define KLD_DPF(cat, args)
+
+#endif
+
+typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *);
+
+/* Support functions */
+int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
+int elf_reloc_local(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
+Elf_Addr elf_relocaddr(linker_file_t _lf, Elf_Addr addr);
+const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Size _symidx);
+const char *elf_get_symname(linker_file_t _lf, Elf_Size _symidx);
+
+typedef struct linker_ctf {
+ const uint8_t *ctftab; /* Decompressed CTF data. */
+ int ctfcnt; /* Number of CTF data bytes. */
+ const Elf_Sym *symtab; /* Ptr to the symbol table. */
+ int nsym; /* Number of symbols. */
+ const char *strtab; /* Ptr to the string table. */
+ int strcnt; /* Number of string bytes. */
+ uint32_t **ctfoffp; /* Ptr to array of obj/fnc offsets. */
+ uint32_t **typoffp; /* Ptr to array of type offsets. */
+ long *typlenp; /* Ptr to number of type data entries. */
+} linker_ctf_t;
+
+int linker_ctf_get(linker_file_t, linker_ctf_t *);
+
+int elf_cpu_load_file(linker_file_t);
+int elf_cpu_unload_file(linker_file_t);
+
+/* values for type */
+#define ELF_RELOC_REL 1
+#define ELF_RELOC_RELA 2
+
+/*
+ * This is version 1 of the KLD file status structure. It is identified
+ * by its _size_ in the version field.
+ */
+struct kld_file_stat_1 {
+ int version; /* set to sizeof(struct kld_file_stat_1) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ caddr_t address; /* load address */
+ size_t size; /* size in bytes */
+};
+#endif /* _KERNEL */
+
+struct kld_file_stat {
+ int version; /* set to sizeof(struct kld_file_stat) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ caddr_t address; /* load address */
+ size_t size; /* size in bytes */
+ char pathname[MAXPATHLEN];
+};
+
+struct kld_sym_lookup {
+ int version; /* set to sizeof(struct kld_sym_lookup) */
+ char *symname; /* Symbol name we are looking up */
+ u_long symvalue;
+ size_t symsize;
+};
+#define KLDSYM_LOOKUP 1
+
+/*
+ * Flags for kldunloadf() and linker_file_unload()
+ */
+#define LINKER_UNLOAD_NORMAL 0
+#define LINKER_UNLOAD_FORCE 1
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int kldload(const char* _file);
+int kldunload(int _fileid);
+int kldunloadf(int _fileid, int flags);
+int kldfind(const char* _file);
+int kldnext(int _fileid);
+int kldstat(int _fileid, struct kld_file_stat* _stat);
+int kldfirstmod(int _fileid);
+int kldsym(int _fileid, int _cmd, void *_data);
+__END_DECLS
+
+#endif
+
+#endif /* !_SYS_LINKER_H_ */
diff --git a/usr/src/boot/sys/sys/linker_set.h b/usr/src/boot/sys/sys/linker_set.h
new file mode 100644
index 0000000000..eaffcd1436
--- /dev/null
+++ b/usr/src/boot/sys/sys/linker_set.h
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 1999 John D. Polstra
+ * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_LINKER_SET_H_
+#define _SYS_LINKER_SET_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+/*
+ * The following macros are used to declare global sets of objects, which
+ * are collected by the linker into a `linker_set' as defined below.
+ * For ELF, this is done by constructing a separate segment for each set.
+ */
+
+#if defined(__powerpc64__)
+/*
+ * Move the symbol pointer from ".text" to ".data" segment, to make
+ * the GCC compiler happy:
+ */
+#define __MAKE_SET_CONST
+#else
+#define __MAKE_SET_CONST const
+#endif
+
+/*
+ * Private macros, not to be used outside this header file.
+ */
+#ifdef __GNUCLIKE___SECTION
+#define __MAKE_SET(set, sym) \
+ __GLOBL(__CONCAT(__start_set_,set)); \
+ __GLOBL(__CONCAT(__stop_set_,set)); \
+ static void const * __MAKE_SET_CONST \
+ __set_##set##_sym_##sym __section("set_" #set) \
+ __used = &(sym)
+#else /* !__GNUCLIKE___SECTION */
+#ifndef lint
+#error this file needs to be ported to your compiler
+#endif /* lint */
+#define __MAKE_SET(set, sym) extern void const * const (__set_##set##_sym_##sym)
+#endif /* __GNUCLIKE___SECTION */
+
+/*
+ * Public macros.
+ */
+#define TEXT_SET(set, sym) __MAKE_SET(set, sym)
+#define DATA_SET(set, sym) __MAKE_SET(set, sym)
+#define BSS_SET(set, sym) __MAKE_SET(set, sym)
+#define ABS_SET(set, sym) __MAKE_SET(set, sym)
+#define SET_ENTRY(set, sym) __MAKE_SET(set, sym)
+
+/*
+ * Initialize before referring to a given linker set.
+ */
+#define SET_DECLARE(set, ptype) \
+ extern ptype __weak_symbol *__CONCAT(__start_set_,set); \
+ extern ptype __weak_symbol *__CONCAT(__stop_set_,set)
+
+#define SET_BEGIN(set) \
+ (&__CONCAT(__start_set_,set))
+#define SET_LIMIT(set) \
+ (&__CONCAT(__stop_set_,set))
+
+/*
+ * Iterate over all the elements of a set.
+ *
+ * Sets always contain addresses of things, and "pvar" points to words
+ * containing those addresses. Thus is must be declared as "type **pvar",
+ * and the address of each set item is obtained inside the loop by "*pvar".
+ */
+#define SET_FOREACH(pvar, set) \
+ for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)
+
+#define SET_ITEM(set, i) \
+ ((SET_BEGIN(set))[i])
+
+/*
+ * Provide a count of the items in a set.
+ */
+#define SET_COUNT(set) \
+ (SET_LIMIT(set) - SET_BEGIN(set))
+
+#endif /* _SYS_LINKER_SET_H_ */
diff --git a/usr/src/boot/sys/sys/module.h b/usr/src/boot/sys/sys/module.h
new file mode 100644
index 0000000000..f0192d57b2
--- /dev/null
+++ b/usr/src/boot/sys/sys/module.h
@@ -0,0 +1,268 @@
+/*-
+ * Copyright (c) 1997 Doug Rabson
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_MODULE_H_
+#define _SYS_MODULE_H_
+
+/*
+ * Module metadata types
+ */
+#define MDT_DEPEND 1 /* argument is a module name */
+#define MDT_MODULE 2 /* module declaration */
+#define MDT_VERSION 3 /* module version(s) */
+#define MDT_PNP_INFO 4 /* Plug and play hints record */
+
+#define MDT_STRUCT_VERSION 1 /* version of metadata structure */
+#define MDT_SETNAME "modmetadata_set"
+
+typedef enum modeventtype {
+ MOD_LOAD,
+ MOD_UNLOAD,
+ MOD_SHUTDOWN,
+ MOD_QUIESCE
+} modeventtype_t;
+
+typedef struct module *module_t;
+typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);
+
+/*
+ * Struct for registering modules statically via SYSINIT.
+ */
+typedef struct moduledata {
+ const char *name; /* module name */
+ modeventhand_t evhand; /* event handler */
+ void *priv; /* extra data */
+} moduledata_t;
+
+/*
+ * A module can use this to report module specific data to the user via
+ * kldstat(2).
+ */
+typedef union modspecific {
+ int intval;
+ u_int uintval;
+ long longval;
+ u_long ulongval;
+} modspecific_t;
+
+/*
+ * Module dependency declaration
+ */
+struct mod_depend {
+ int md_ver_minimum;
+ int md_ver_preferred;
+ int md_ver_maximum;
+};
+
+/*
+ * Module version declaration
+ */
+struct mod_version {
+ int mv_version;
+};
+
+struct mod_metadata {
+ int md_version; /* structure version MDTV_* */
+ int md_type; /* type of entry MDT_* */
+ const void *md_data; /* specific data */
+ const char *md_cval; /* common string label */
+};
+
+struct mod_pnp_match_info
+{
+ const char *descr; /* Description of the table */
+ const char *bus; /* Name of the bus for this table */
+ const void *table; /* Pointer to pnp table */
+ int entry_len; /* Length of each entry in the table (may be */
+ /* longer than descr describes). */
+ int num_entry; /* Number of entries in the table */
+};
+#ifdef _KERNEL
+
+#include <sys/linker_set.h>
+
+#define MODULE_METADATA(uniquifier, type, data, cval) \
+ static struct mod_metadata _mod_metadata##uniquifier = { \
+ MDT_STRUCT_VERSION, \
+ type, \
+ data, \
+ cval \
+ }; \
+ DATA_SET(modmetadata_set, _mod_metadata##uniquifier)
+
+#define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) \
+ static struct mod_depend _##module##_depend_on_##mdepend \
+ __section(".data") = { \
+ vmin, \
+ vpref, \
+ vmax \
+ }; \
+ MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND, \
+ &_##module##_depend_on_##mdepend, #mdepend)
+
+/*
+ * Every kernel has a 'kernel' module with the version set to
+ * __FreeBSD_version. We embed a MODULE_DEPEND() inside every module
+ * that depends on the 'kernel' module. It uses the current value of
+ * __FreeBSD_version as the minimum and preferred versions. For the
+ * maximum version it rounds the version up to the end of its branch
+ * (i.e. M99999 for M.x). This allows a module built on M.x to work
+ * on M.y systems where y >= x, but fail on M.z systems where z < x.
+ */
+#define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1)
+
+#define DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver) \
+ MODULE_DEPEND(name, kernel, __FreeBSD_version, \
+ __FreeBSD_version, maxver); \
+ MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name); \
+ SYSINIT(name##module, sub, order, module_register_init, &data); \
+ struct __hack
+
+#define DECLARE_MODULE(name, data, sub, order) \
+ DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)
+
+/*
+ * The module declared with DECLARE_MODULE_TIED can only be loaded
+ * into the kernel with exactly the same __FreeBSD_version.
+ *
+ * Use it for modules that use kernel interfaces that are not stable
+ * even on STABLE/X branches.
+ */
+#define DECLARE_MODULE_TIED(name, data, sub, order) \
+ DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
+
+#define MODULE_VERSION(module, version) \
+ static struct mod_version _##module##_version \
+ __section(".data") = { \
+ version \
+ }; \
+ MODULE_METADATA(_##module##_version, MDT_VERSION, \
+ &_##module##_version, #module)
+
+/**
+ * Generic macros to create pnp info hints that modules may export
+ * to allow external tools to parse their intenral device tables
+ * to make an informed guess about what driver(s) to load.
+ */
+#define MODULE_PNP_INFO(d, b, unique, t, l, n) \
+ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \
+ .descr = d, \
+ .bus = #b, \
+ .table = t, \
+ .entry_len = l, \
+ .num_entry = n \
+ }; \
+ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \
+ &_module_pnp_##b##_##unique, #b);
+/**
+ * descr is a string that describes each entry in the table. The general
+ * form is (TYPE:pnp_name[/pnp_name];)*
+ * where TYPE is one of the following:
+ * U8 uint8_t element
+ * V8 like U8 and 0xff means match any
+ * G16 uint16_t element, any value >= matches
+ * L16 uint16_t element, any value <= matches
+ * M16 uint16_t element, mask of which of the following fields to use.
+ * U16 uint16_t element
+ * V16 like U16 and 0xffff means match any
+ * U32 uint32_t element
+ * V32 like U32 and 0xffffffff means match any
+ * W32 Two 16-bit values with first pnp_name in LSW and second in MSW.
+ * Z pointer to a string to match exactly
+ * D like Z, but is the string passed to device_set_descr()
+ * P A pointer that should be ignored
+ * E EISA PNP Identifier (in binary, but bus publishes string)
+ * K Key for whole table. pnp_name=value. must be last, if present.
+ *
+ * The pnp_name "#" is reserved for other fields that should be ignored.
+ */
+
+extern struct sx modules_sx;
+
+#define MOD_XLOCK sx_xlock(&modules_sx)
+#define MOD_SLOCK sx_slock(&modules_sx)
+#define MOD_XUNLOCK sx_xunlock(&modules_sx)
+#define MOD_SUNLOCK sx_sunlock(&modules_sx)
+#define MOD_LOCK_ASSERT sx_assert(&modules_sx, SX_LOCKED)
+#define MOD_XLOCK_ASSERT sx_assert(&modules_sx, SX_XLOCKED)
+
+struct linker_file;
+
+void module_register_init(const void *);
+int module_register(const struct moduledata *, struct linker_file *);
+module_t module_lookupbyname(const char *);
+module_t module_lookupbyid(int);
+int module_quiesce(module_t);
+void module_reference(module_t);
+void module_release(module_t);
+int module_unload(module_t);
+int module_getid(module_t);
+module_t module_getfnext(module_t);
+const char * module_getname(module_t);
+void module_setspecific(module_t, modspecific_t *);
+struct linker_file *module_file(module_t);
+
+#ifdef MOD_DEBUG
+extern int mod_debug;
+#define MOD_DEBUG_REFS 1
+
+#define MOD_DPF(cat, args) do { \
+ if (mod_debug & MOD_DEBUG_##cat) \
+ printf(args); \
+} while (0)
+
+#else /* !MOD_DEBUG */
+
+#define MOD_DPF(cat, args)
+#endif
+#endif /* _KERNEL */
+
+#define MAXMODNAME 32
+
+struct module_stat {
+ int version; /* set to sizeof(struct module_stat) */
+ char name[MAXMODNAME];
+ int refs;
+ int id;
+ modspecific_t data;
+};
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int modnext(int _modid);
+int modfnext(int _modid);
+int modstat(int _modid, struct module_stat *_stat);
+int modfind(const char *_name);
+__END_DECLS
+
+#endif
+
+#endif /* !_SYS_MODULE_H_ */
diff --git a/usr/src/boot/sys/sys/mount.h b/usr/src/boot/sys/sys/mount.h
new file mode 100644
index 0000000000..f11f8f5389
--- /dev/null
+++ b/usr/src/boot/sys/sys/mount.h
@@ -0,0 +1,949 @@
+/*-
+ * Copyright (c) 1989, 1991, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)mount.h 8.21 (Berkeley) 5/20/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_MOUNT_H_
+#define _SYS_MOUNT_H_
+
+#include <sys/ucred.h>
+#include <sys/queue.h>
+#ifdef _KERNEL
+#include <sys/lock.h>
+#include <sys/lockmgr.h>
+#include <sys/_mutex.h>
+#include <sys/_sx.h>
+#endif
+
+/*
+ * NOTE: When changing statfs structure, mount structure, MNT_* flags or
+ * MNTK_* flags also update DDB show mount command in vfs_subr.c.
+ */
+
+typedef struct fsid { int32_t val[2]; } fsid_t; /* filesystem id type */
+
+/*
+ * File identifier.
+ * These are unique per filesystem on a single machine.
+ */
+#define MAXFIDSZ 16
+
+struct fid {
+ u_short fid_len; /* length of data in bytes */
+ u_short fid_data0; /* force longword alignment */
+ char fid_data[MAXFIDSZ]; /* data (variable length) */
+};
+
+/*
+ * filesystem statistics
+ */
+#define MFSNAMELEN 16 /* length of type name including null */
+#define MNAMELEN 88 /* size of on/from name bufs */
+#define STATFS_VERSION 0x20030518 /* current version number */
+struct statfs {
+ uint32_t f_version; /* structure version number */
+ uint32_t f_type; /* type of filesystem */
+ uint64_t f_flags; /* copy of mount exported flags */
+ uint64_t f_bsize; /* filesystem fragment size */
+ uint64_t f_iosize; /* optimal transfer block size */
+ uint64_t f_blocks; /* total data blocks in filesystem */
+ uint64_t f_bfree; /* free blocks in filesystem */
+ int64_t f_bavail; /* free blocks avail to non-superuser */
+ uint64_t f_files; /* total file nodes in filesystem */
+ int64_t f_ffree; /* free nodes avail to non-superuser */
+ uint64_t f_syncwrites; /* count of sync writes since mount */
+ uint64_t f_asyncwrites; /* count of async writes since mount */
+ uint64_t f_syncreads; /* count of sync reads since mount */
+ uint64_t f_asyncreads; /* count of async reads since mount */
+ uint64_t f_spare[10]; /* unused spare */
+ uint32_t f_namemax; /* maximum filename length */
+ uid_t f_owner; /* user that mounted the filesystem */
+ fsid_t f_fsid; /* filesystem id */
+ char f_charspare[80]; /* spare string space */
+ char f_fstypename[MFSNAMELEN]; /* filesystem type name */
+ char f_mntfromname[MNAMELEN]; /* mounted filesystem */
+ char f_mntonname[MNAMELEN]; /* directory on which mounted */
+};
+
+#ifdef _KERNEL
+#define OMFSNAMELEN 16 /* length of fs type name, including null */
+#define OMNAMELEN (88 - 2 * sizeof(long)) /* size of on/from name bufs */
+
+/* XXX getfsstat.2 is out of date with write and read counter changes here. */
+/* XXX statfs.2 is out of date with read counter changes here. */
+struct ostatfs {
+ long f_spare2; /* placeholder */
+ long f_bsize; /* fundamental filesystem block size */
+ long f_iosize; /* optimal transfer block size */
+ long f_blocks; /* total data blocks in filesystem */
+ long f_bfree; /* free blocks in fs */
+ long f_bavail; /* free blocks avail to non-superuser */
+ long f_files; /* total file nodes in filesystem */
+ long f_ffree; /* free file nodes in fs */
+ fsid_t f_fsid; /* filesystem id */
+ uid_t f_owner; /* user that mounted the filesystem */
+ int f_type; /* type of filesystem */
+ int f_flags; /* copy of mount exported flags */
+ long f_syncwrites; /* count of sync writes since mount */
+ long f_asyncwrites; /* count of async writes since mount */
+ char f_fstypename[OMFSNAMELEN]; /* fs type name */
+ char f_mntonname[OMNAMELEN]; /* directory on which mounted */
+ long f_syncreads; /* count of sync reads since mount */
+ long f_asyncreads; /* count of async reads since mount */
+ short f_spares1; /* unused spare */
+ char f_mntfromname[OMNAMELEN];/* mounted filesystem */
+ short f_spares2; /* unused spare */
+ /*
+ * XXX on machines where longs are aligned to 8-byte boundaries, there
+ * is an unnamed int32_t here. This spare was after the apparent end
+ * of the struct until we bit off the read counters from f_mntonname.
+ */
+ long f_spare[2]; /* unused spare */
+};
+
+TAILQ_HEAD(vnodelst, vnode);
+
+/* Mount options list */
+TAILQ_HEAD(vfsoptlist, vfsopt);
+struct vfsopt {
+ TAILQ_ENTRY(vfsopt) link;
+ char *name;
+ void *value;
+ int len;
+ int pos;
+ int seen;
+};
+
+/*
+ * Structure per mounted filesystem. Each mounted filesystem has an
+ * array of operations and an instance record. The filesystems are
+ * put on a doubly linked list.
+ *
+ * Lock reference:
+ * m - mountlist_mtx
+ * i - interlock
+ * v - vnode freelist mutex
+ *
+ * Unmarked fields are considered stable as long as a ref is held.
+ *
+ */
+struct mount {
+ struct mtx mnt_mtx; /* mount structure interlock */
+ int mnt_gen; /* struct mount generation */
+#define mnt_startzero mnt_list
+ TAILQ_ENTRY(mount) mnt_list; /* (m) mount list */
+ struct vfsops *mnt_op; /* operations on fs */
+ struct vfsconf *mnt_vfc; /* configuration info */
+ struct vnode *mnt_vnodecovered; /* vnode we mounted on */
+ struct vnode *mnt_syncer; /* syncer vnode */
+ int mnt_ref; /* (i) Reference count */
+ struct vnodelst mnt_nvnodelist; /* (i) list of vnodes */
+ int mnt_nvnodelistsize; /* (i) # of vnodes */
+ struct vnodelst mnt_activevnodelist; /* (v) list of active vnodes */
+ int mnt_activevnodelistsize;/* (v) # of active vnodes */
+ int mnt_writeopcount; /* (i) write syscalls pending */
+ int mnt_kern_flag; /* (i) kernel only flags */
+ uint64_t mnt_flag; /* (i) flags shared with user */
+ struct vfsoptlist *mnt_opt; /* current mount options */
+ struct vfsoptlist *mnt_optnew; /* new options passed to fs */
+ int mnt_maxsymlinklen; /* max size of short symlink */
+ struct statfs mnt_stat; /* cache of filesystem stats */
+ struct ucred *mnt_cred; /* credentials of mounter */
+ void * mnt_data; /* private data */
+ time_t mnt_time; /* last time written*/
+ int mnt_iosize_max; /* max size for clusters, etc */
+ struct netexport *mnt_export; /* export list */
+ struct label *mnt_label; /* MAC label for the fs */
+ u_int mnt_hashseed; /* Random seed for vfs_hash */
+ int mnt_lockref; /* (i) Lock reference count */
+ int mnt_secondary_writes; /* (i) # of secondary writes */
+ int mnt_secondary_accwrites;/* (i) secondary wr. starts */
+ struct thread *mnt_susp_owner; /* (i) thread owning suspension */
+#define mnt_endzero mnt_gjprovider
+ char *mnt_gjprovider; /* gjournal provider name */
+ struct lock mnt_explock; /* vfs_export walkers lock */
+ TAILQ_ENTRY(mount) mnt_upper_link; /* (m) we in the all uppers */
+ TAILQ_HEAD(, mount) mnt_uppers; /* (m) upper mounts over us*/
+};
+
+/*
+ * Definitions for MNT_VNODE_FOREACH_ALL.
+ */
+struct vnode *__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp);
+struct vnode *__mnt_vnode_first_all(struct vnode **mvp, struct mount *mp);
+void __mnt_vnode_markerfree_all(struct vnode **mvp, struct mount *mp);
+
+#define MNT_VNODE_FOREACH_ALL(vp, mp, mvp) \
+ for (vp = __mnt_vnode_first_all(&(mvp), (mp)); \
+ (vp) != NULL; vp = __mnt_vnode_next_all(&(mvp), (mp)))
+
+#define MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp) \
+ do { \
+ MNT_ILOCK(mp); \
+ __mnt_vnode_markerfree_all(&(mvp), (mp)); \
+ /* MNT_IUNLOCK(mp); -- done in above function */ \
+ mtx_assert(MNT_MTX(mp), MA_NOTOWNED); \
+ } while (0)
+
+/*
+ * Definitions for MNT_VNODE_FOREACH_ACTIVE.
+ */
+struct vnode *__mnt_vnode_next_active(struct vnode **mvp, struct mount *mp);
+struct vnode *__mnt_vnode_first_active(struct vnode **mvp, struct mount *mp);
+void __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
+
+#define MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) \
+ for (vp = __mnt_vnode_first_active(&(mvp), (mp)); \
+ (vp) != NULL; vp = __mnt_vnode_next_active(&(mvp), (mp)))
+
+#define MNT_VNODE_FOREACH_ACTIVE_ABORT(mp, mvp) \
+ __mnt_vnode_markerfree_active(&(mvp), (mp))
+
+#define MNT_ILOCK(mp) mtx_lock(&(mp)->mnt_mtx)
+#define MNT_ITRYLOCK(mp) mtx_trylock(&(mp)->mnt_mtx)
+#define MNT_IUNLOCK(mp) mtx_unlock(&(mp)->mnt_mtx)
+#define MNT_MTX(mp) (&(mp)->mnt_mtx)
+#define MNT_REF(mp) (mp)->mnt_ref++
+#define MNT_REL(mp) do { \
+ KASSERT((mp)->mnt_ref > 0, ("negative mnt_ref")); \
+ (mp)->mnt_ref--; \
+ if ((mp)->mnt_ref == 0) \
+ wakeup((mp)); \
+} while (0)
+
+#endif /* _KERNEL */
+
+/*
+ * User specifiable flags, stored in mnt_flag.
+ */
+#define MNT_RDONLY 0x0000000000000001ULL /* read only filesystem */
+#define MNT_SYNCHRONOUS 0x0000000000000002ULL /* fs written synchronously */
+#define MNT_NOEXEC 0x0000000000000004ULL /* can't exec from filesystem */
+#define MNT_NOSUID 0x0000000000000008ULL /* don't honor setuid fs bits */
+#define MNT_NFS4ACLS 0x0000000000000010ULL /* enable NFS version 4 ACLs */
+#define MNT_UNION 0x0000000000000020ULL /* union with underlying fs */
+#define MNT_ASYNC 0x0000000000000040ULL /* fs written asynchronously */
+#define MNT_SUIDDIR 0x0000000000100000ULL /* special SUID dir handling */
+#define MNT_SOFTDEP 0x0000000000200000ULL /* using soft updates */
+#define MNT_NOSYMFOLLOW 0x0000000000400000ULL /* do not follow symlinks */
+#define MNT_GJOURNAL 0x0000000002000000ULL /* GEOM journal support enabled */
+#define MNT_MULTILABEL 0x0000000004000000ULL /* MAC support for objects */
+#define MNT_ACLS 0x0000000008000000ULL /* ACL support enabled */
+#define MNT_NOATIME 0x0000000010000000ULL /* dont update file access time */
+#define MNT_NOCLUSTERR 0x0000000040000000ULL /* disable cluster read */
+#define MNT_NOCLUSTERW 0x0000000080000000ULL /* disable cluster write */
+#define MNT_SUJ 0x0000000100000000ULL /* using journaled soft updates */
+#define MNT_AUTOMOUNTED 0x0000000200000000ULL /* mounted by automountd(8) */
+
+/*
+ * NFS export related mount flags.
+ */
+#define MNT_EXRDONLY 0x0000000000000080ULL /* exported read only */
+#define MNT_EXPORTED 0x0000000000000100ULL /* filesystem is exported */
+#define MNT_DEFEXPORTED 0x0000000000000200ULL /* exported to the world */
+#define MNT_EXPORTANON 0x0000000000000400ULL /* anon uid mapping for all */
+#define MNT_EXKERB 0x0000000000000800ULL /* exported with Kerberos */
+#define MNT_EXPUBLIC 0x0000000020000000ULL /* public export (WebNFS) */
+
+/*
+ * Flags set by internal operations,
+ * but visible to the user.
+ * XXX some of these are not quite right.. (I've never seen the root flag set)
+ */
+#define MNT_LOCAL 0x0000000000001000ULL /* filesystem is stored locally */
+#define MNT_QUOTA 0x0000000000002000ULL /* quotas are enabled on fs */
+#define MNT_ROOTFS 0x0000000000004000ULL /* identifies the root fs */
+#define MNT_USER 0x0000000000008000ULL /* mounted by a user */
+#define MNT_IGNORE 0x0000000000800000ULL /* do not show entry in df */
+
+/*
+ * Mask of flags that are visible to statfs().
+ * XXX I think that this could now become (~(MNT_CMDFLAGS))
+ * but the 'mount' program may need changing to handle this.
+ */
+#define MNT_VISFLAGMASK (MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC | \
+ MNT_NOSUID | MNT_UNION | MNT_SUJ | \
+ MNT_ASYNC | MNT_EXRDONLY | MNT_EXPORTED | \
+ MNT_DEFEXPORTED | MNT_EXPORTANON| MNT_EXKERB | \
+ MNT_LOCAL | MNT_USER | MNT_QUOTA | \
+ MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR| \
+ MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP | \
+ MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \
+ MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \
+ MNT_NFS4ACLS | MNT_AUTOMOUNTED)
+
+/* Mask of flags that can be updated. */
+#define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \
+ MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | \
+ MNT_NOATIME | \
+ MNT_NOSYMFOLLOW | MNT_IGNORE | \
+ MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \
+ MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \
+ MNT_AUTOMOUNTED)
+
+/*
+ * External filesystem command modifier flags.
+ * Unmount can use the MNT_FORCE flag.
+ * XXX: These are not STATES and really should be somewhere else.
+ * XXX: MNT_BYFSID collides with MNT_ACLS, but because MNT_ACLS is only used for
+ * mount(2) and MNT_BYFSID is only used for unmount(2) it's harmless.
+ */
+#define MNT_UPDATE 0x0000000000010000ULL /* not real mount, just update */
+#define MNT_DELEXPORT 0x0000000000020000ULL /* delete export host lists */
+#define MNT_RELOAD 0x0000000000040000ULL /* reload filesystem data */
+#define MNT_FORCE 0x0000000000080000ULL /* force unmount or readonly */
+#define MNT_SNAPSHOT 0x0000000001000000ULL /* snapshot the filesystem */
+#define MNT_BYFSID 0x0000000008000000ULL /* specify filesystem by ID. */
+#define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \
+ MNT_FORCE | MNT_SNAPSHOT | MNT_BYFSID)
+/*
+ * Internal filesystem control flags stored in mnt_kern_flag.
+ *
+ * MNTK_UNMOUNT locks the mount entry so that name lookup cannot proceed
+ * past the mount point. This keeps the subtree stable during mounts
+ * and unmounts.
+ *
+ * MNTK_UNMOUNTF permits filesystems to detect a forced unmount while
+ * dounmount() is still waiting to lock the mountpoint. This allows
+ * the filesystem to cancel operations that might otherwise deadlock
+ * with the unmount attempt (used by NFS).
+ *
+ * MNTK_NOINSMNTQ is strict subset of MNTK_UNMOUNT. They are separated
+ * to allow for failed unmount attempt to restore the syncer vnode for
+ * the mount.
+ */
+#define MNTK_UNMOUNTF 0x00000001 /* forced unmount in progress */
+#define MNTK_ASYNC 0x00000002 /* filtered async flag */
+#define MNTK_SOFTDEP 0x00000004 /* async disabled by softdep */
+#define MNTK_NOINSMNTQ 0x00000008 /* insmntque is not allowed */
+#define MNTK_DRAINING 0x00000010 /* lock draining is happening */
+#define MNTK_REFEXPIRE 0x00000020 /* refcount expiring is happening */
+#define MNTK_EXTENDED_SHARED 0x00000040 /* Allow shared locking for more ops */
+#define MNTK_SHARED_WRITES 0x00000080 /* Allow shared locking for writes */
+#define MNTK_NO_IOPF 0x00000100 /* Disallow page faults during reads
+ and writes. Filesystem shall properly
+ handle i/o state on EFAULT. */
+#define MNTK_VGONE_UPPER 0x00000200
+#define MNTK_VGONE_WAITER 0x00000400
+#define MNTK_LOOKUP_EXCL_DOTDOT 0x00000800
+#define MNTK_MARKER 0x00001000
+#define MNTK_UNMAPPED_BUFS 0x00002000
+#define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */
+#define MNTK_NOASYNC 0x00800000 /* disable async */
+#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
+#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
+#define MNTK_SUSPEND 0x08000000 /* request write suspension */
+#define MNTK_SUSPEND2 0x04000000 /* block secondary writes */
+#define MNTK_SUSPENDED 0x10000000 /* write operations are suspended */
+#define MNTK_UNUSED1 0x20000000
+#define MNTK_LOOKUP_SHARED 0x40000000 /* FS supports shared lock lookups */
+#define MNTK_NOKNOTE 0x80000000 /* Don't send KNOTEs from VOP hooks */
+
+#ifdef _KERNEL
+static inline int
+MNT_SHARED_WRITES(struct mount *mp)
+{
+
+ return (mp != NULL && (mp->mnt_kern_flag & MNTK_SHARED_WRITES) != 0);
+}
+
+static inline int
+MNT_EXTENDED_SHARED(struct mount *mp)
+{
+
+ return (mp != NULL && (mp->mnt_kern_flag & MNTK_EXTENDED_SHARED) != 0);
+}
+#endif
+
+/*
+ * Sysctl CTL_VFS definitions.
+ *
+ * Second level identifier specifies which filesystem. Second level
+ * identifier VFS_VFSCONF returns information about all filesystems.
+ * Second level identifier VFS_GENERIC is non-terminal.
+ */
+#define VFS_VFSCONF 0 /* get configured filesystems */
+#define VFS_GENERIC 0 /* generic filesystem information */
+/*
+ * Third level identifiers for VFS_GENERIC are given below; third
+ * level identifiers for specific filesystems are given in their
+ * mount specific header files.
+ */
+#define VFS_MAXTYPENUM 1 /* int: highest defined filesystem type */
+#define VFS_CONF 2 /* struct: vfsconf for filesystem given
+ as next argument */
+
+/*
+ * Flags for various system call interfaces.
+ *
+ * waitfor flags to vfs_sync() and getfsstat()
+ */
+#define MNT_WAIT 1 /* synchronously wait for I/O to complete */
+#define MNT_NOWAIT 2 /* start all I/O, but do not wait for it */
+#define MNT_LAZY 3 /* push data not written by filesystem syncer */
+#define MNT_SUSPEND 4 /* Suspend file system after sync */
+
+/*
+ * Generic file handle
+ */
+struct fhandle {
+ fsid_t fh_fsid; /* Filesystem id of mount point */
+ struct fid fh_fid; /* Filesys specific id */
+};
+typedef struct fhandle fhandle_t;
+
+/*
+ * Old export arguments without security flavor list
+ */
+struct oexport_args {
+ int ex_flags; /* export related flags */
+ uid_t ex_root; /* mapping for root uid */
+ struct xucred ex_anon; /* mapping for anonymous user */
+ struct sockaddr *ex_addr; /* net address to which exported */
+ u_char ex_addrlen; /* and the net address length */
+ struct sockaddr *ex_mask; /* mask of valid bits in saddr */
+ u_char ex_masklen; /* and the smask length */
+ char *ex_indexfile; /* index file for WebNFS URLs */
+};
+
+/*
+ * Export arguments for local filesystem mount calls.
+ */
+#define MAXSECFLAVORS 5
+struct export_args {
+ int ex_flags; /* export related flags */
+ uid_t ex_root; /* mapping for root uid */
+ struct xucred ex_anon; /* mapping for anonymous user */
+ struct sockaddr *ex_addr; /* net address to which exported */
+ u_char ex_addrlen; /* and the net address length */
+ struct sockaddr *ex_mask; /* mask of valid bits in saddr */
+ u_char ex_masklen; /* and the smask length */
+ char *ex_indexfile; /* index file for WebNFS URLs */
+ int ex_numsecflavors; /* security flavor count */
+ int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
+};
+
+/*
+ * Structure holding information for a publicly exported filesystem
+ * (WebNFS). Currently the specs allow just for one such filesystem.
+ */
+struct nfs_public {
+ int np_valid; /* Do we hold valid information */
+ fhandle_t np_handle; /* Filehandle for pub fs (internal) */
+ struct mount *np_mount; /* Mountpoint of exported fs */
+ char *np_index; /* Index file */
+};
+
+/*
+ * Filesystem configuration information. One of these exists for each
+ * type of filesystem supported by the kernel. These are searched at
+ * mount time to identify the requested filesystem.
+ *
+ * XXX: Never change the first two arguments!
+ */
+struct vfsconf {
+ u_int vfc_version; /* ABI version number */
+ char vfc_name[MFSNAMELEN]; /* filesystem type name */
+ struct vfsops *vfc_vfsops; /* filesystem operations vector */
+ int vfc_typenum; /* historic filesystem type number */
+ int vfc_refcount; /* number mounted of this type */
+ int vfc_flags; /* permanent flags */
+ struct vfsoptdecl *vfc_opts; /* mount options */
+ TAILQ_ENTRY(vfsconf) vfc_list; /* list of vfscons */
+};
+
+/* Userland version of the struct vfsconf. */
+struct xvfsconf {
+ struct vfsops *vfc_vfsops; /* filesystem operations vector */
+ char vfc_name[MFSNAMELEN]; /* filesystem type name */
+ int vfc_typenum; /* historic filesystem type number */
+ int vfc_refcount; /* number mounted of this type */
+ int vfc_flags; /* permanent flags */
+ struct vfsconf *vfc_next; /* next in list */
+};
+
+#ifndef BURN_BRIDGES
+struct ovfsconf {
+ void *vfc_vfsops;
+ char vfc_name[32];
+ int vfc_index;
+ int vfc_refcount;
+ int vfc_flags;
+};
+#endif
+
+/*
+ * NB: these flags refer to IMPLEMENTATION properties, not properties of
+ * any actual mounts; i.e., it does not make sense to change the flags.
+ */
+#define VFCF_STATIC 0x00010000 /* statically compiled into kernel */
+#define VFCF_NETWORK 0x00020000 /* may get data over the network */
+#define VFCF_READONLY 0x00040000 /* writes are not implemented */
+#define VFCF_SYNTHETIC 0x00080000 /* data does not represent real files */
+#define VFCF_LOOPBACK 0x00100000 /* aliases some other mounted FS */
+#define VFCF_UNICODE 0x00200000 /* stores file names as Unicode */
+#define VFCF_JAIL 0x00400000 /* can be mounted from within a jail */
+#define VFCF_DELEGADMIN 0x00800000 /* supports delegated administration */
+#define VFCF_SBDRY 0x01000000 /* defer stop requests */
+
+typedef uint32_t fsctlop_t;
+
+struct vfsidctl {
+ int vc_vers; /* should be VFSIDCTL_VERS1 (below) */
+ fsid_t vc_fsid; /* fsid to operate on */
+ char vc_fstypename[MFSNAMELEN];
+ /* type of fs 'nfs' or '*' */
+ fsctlop_t vc_op; /* operation VFS_CTL_* (below) */
+ void *vc_ptr; /* pointer to data structure */
+ size_t vc_len; /* sizeof said structure */
+ u_int32_t vc_spare[12]; /* spare (must be zero) */
+};
+
+/* vfsidctl API version. */
+#define VFS_CTL_VERS1 0x01
+
+/*
+ * New style VFS sysctls, do not reuse/conflict with the namespace for
+ * private sysctls.
+ * All "global" sysctl ops have the 33rd bit set:
+ * 0x...1....
+ * Private sysctl ops should have the 33rd bit unset.
+ */
+#define VFS_CTL_QUERY 0x00010001 /* anything wrong? (vfsquery) */
+#define VFS_CTL_TIMEO 0x00010002 /* set timeout for vfs notification */
+#define VFS_CTL_NOLOCKS 0x00010003 /* disable file locking */
+
+struct vfsquery {
+ u_int32_t vq_flags;
+ u_int32_t vq_spare[31];
+};
+
+/* vfsquery flags */
+#define VQ_NOTRESP 0x0001 /* server down */
+#define VQ_NEEDAUTH 0x0002 /* server bad auth */
+#define VQ_LOWDISK 0x0004 /* we're low on space */
+#define VQ_MOUNT 0x0008 /* new filesystem arrived */
+#define VQ_UNMOUNT 0x0010 /* filesystem has left */
+#define VQ_DEAD 0x0020 /* filesystem is dead, needs force unmount */
+#define VQ_ASSIST 0x0040 /* filesystem needs assistance from external
+ program */
+#define VQ_NOTRESPLOCK 0x0080 /* server lockd down */
+#define VQ_FLAG0100 0x0100 /* placeholder */
+#define VQ_FLAG0200 0x0200 /* placeholder */
+#define VQ_FLAG0400 0x0400 /* placeholder */
+#define VQ_FLAG0800 0x0800 /* placeholder */
+#define VQ_FLAG1000 0x1000 /* placeholder */
+#define VQ_FLAG2000 0x2000 /* placeholder */
+#define VQ_FLAG4000 0x4000 /* placeholder */
+#define VQ_FLAG8000 0x8000 /* placeholder */
+
+#ifdef _KERNEL
+/* Point a sysctl request at a vfsidctl's data. */
+#define VCTLTOREQ(vc, req) \
+ do { \
+ (req)->newptr = (vc)->vc_ptr; \
+ (req)->newlen = (vc)->vc_len; \
+ (req)->newidx = 0; \
+ } while (0)
+#endif
+
+struct iovec;
+struct uio;
+
+#ifdef _KERNEL
+
+/*
+ * vfs_busy specific flags and mask.
+ */
+#define MBF_NOWAIT 0x01
+#define MBF_MNTLSTLOCK 0x02
+#define MBF_MASK (MBF_NOWAIT | MBF_MNTLSTLOCK)
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_MOUNT);
+#endif
+extern int maxvfsconf; /* highest defined filesystem type */
+
+TAILQ_HEAD(vfsconfhead, vfsconf);
+extern struct vfsconfhead vfsconf;
+
+/*
+ * Operations supported on mounted filesystem.
+ */
+struct mount_args;
+struct nameidata;
+struct sysctl_req;
+struct mntarg;
+
+typedef int vfs_cmount_t(struct mntarg *ma, void *data, uint64_t flags);
+typedef int vfs_unmount_t(struct mount *mp, int mntflags);
+typedef int vfs_root_t(struct mount *mp, int flags, struct vnode **vpp);
+typedef int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, void *arg);
+typedef int vfs_statfs_t(struct mount *mp, struct statfs *sbp);
+typedef int vfs_sync_t(struct mount *mp, int waitfor);
+typedef int vfs_vget_t(struct mount *mp, ino_t ino, int flags,
+ struct vnode **vpp);
+typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp,
+ int flags, struct vnode **vpp);
+typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam,
+ int *extflagsp, struct ucred **credanonp,
+ int *numsecflavors, int **secflavors);
+typedef int vfs_init_t(struct vfsconf *);
+typedef int vfs_uninit_t(struct vfsconf *);
+typedef int vfs_extattrctl_t(struct mount *mp, int cmd,
+ struct vnode *filename_vp, int attrnamespace,
+ const char *attrname);
+typedef int vfs_mount_t(struct mount *mp);
+typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op,
+ struct sysctl_req *req);
+typedef void vfs_susp_clean_t(struct mount *mp);
+typedef void vfs_notify_lowervp_t(struct mount *mp, struct vnode *lowervp);
+typedef void vfs_purge_t(struct mount *mp);
+
+struct vfsops {
+ vfs_mount_t *vfs_mount;
+ vfs_cmount_t *vfs_cmount;
+ vfs_unmount_t *vfs_unmount;
+ vfs_root_t *vfs_root;
+ vfs_quotactl_t *vfs_quotactl;
+ vfs_statfs_t *vfs_statfs;
+ vfs_sync_t *vfs_sync;
+ vfs_vget_t *vfs_vget;
+ vfs_fhtovp_t *vfs_fhtovp;
+ vfs_checkexp_t *vfs_checkexp;
+ vfs_init_t *vfs_init;
+ vfs_uninit_t *vfs_uninit;
+ vfs_extattrctl_t *vfs_extattrctl;
+ vfs_sysctl_t *vfs_sysctl;
+ vfs_susp_clean_t *vfs_susp_clean;
+ vfs_notify_lowervp_t *vfs_reclaim_lowervp;
+ vfs_notify_lowervp_t *vfs_unlink_lowervp;
+ vfs_purge_t *vfs_purge;
+ vfs_mount_t *vfs_spare[6]; /* spares for ABI compat */
+};
+
+vfs_statfs_t __vfs_statfs;
+
+#define VFS_PROLOGUE(MP) do { \
+ struct mount *mp__; \
+ int _enable_stops; \
+ \
+ mp__ = (MP); \
+ _enable_stops = (mp__ != NULL && \
+ (mp__->mnt_vfc->vfc_flags & VFCF_SBDRY) && sigdeferstop())
+
+#define VFS_EPILOGUE(MP) \
+ if (_enable_stops) \
+ sigallowstop(); \
+} while (0)
+
+#define VFS_MOUNT(MP) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_mount)(MP); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_UNMOUNT(MP, FORCE) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_unmount)(MP, FORCE); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_ROOT(MP, FLAGS, VPP) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_root)(MP, FLAGS, VPP); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_QUOTACTL(MP, C, U, A) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_STATFS(MP, SBP) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = __vfs_statfs((MP), (SBP)); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_SYNC(MP, WAIT) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_sync)(MP, WAIT); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_VGET(MP, INO, FLAGS, VPP) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_FHTOVP(MP, FIDP, FLAGS, VPP) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, FLAGS, VPP); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC,\
+ SEC); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_EXTATTRCTL(MP, C, FN, NS, N) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_SYSCTL(MP, OP, REQ) ({ \
+ int _rc; \
+ \
+ VFS_PROLOGUE(MP); \
+ _rc = (*(MP)->mnt_op->vfs_sysctl)(MP, OP, REQ); \
+ VFS_EPILOGUE(MP); \
+ _rc; })
+
+#define VFS_SUSP_CLEAN(MP) do { \
+ if (*(MP)->mnt_op->vfs_susp_clean != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_susp_clean)(MP); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
+#define VFS_RECLAIM_LOWERVP(MP, VP) do { \
+ if (*(MP)->mnt_op->vfs_reclaim_lowervp != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_reclaim_lowervp)((MP), (VP)); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
+#define VFS_UNLINK_LOWERVP(MP, VP) do { \
+ if (*(MP)->mnt_op->vfs_unlink_lowervp != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_unlink_lowervp)((MP), (VP)); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
+#define VFS_PURGE(MP) do { \
+ if (*(MP)->mnt_op->vfs_purge != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_purge)(MP); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
+#define VFS_KNOTE_LOCKED(vp, hint) do \
+{ \
+ if (((vp)->v_vflag & VV_NOKNOTE) == 0) \
+ VN_KNOTE((vp), (hint), KNF_LISTLOCKED); \
+} while (0)
+
+#define VFS_KNOTE_UNLOCKED(vp, hint) do \
+{ \
+ if (((vp)->v_vflag & VV_NOKNOTE) == 0) \
+ VN_KNOTE((vp), (hint), 0); \
+} while (0)
+
+#define VFS_NOTIFY_UPPER_RECLAIM 1
+#define VFS_NOTIFY_UPPER_UNLINK 2
+
+#include <sys/module.h>
+
+/*
+ * Version numbers.
+ */
+#define VFS_VERSION_00 0x19660120
+#define VFS_VERSION_01 0x20121030
+#define VFS_VERSION VFS_VERSION_01
+
+#define VFS_SET(vfsops, fsname, flags) \
+ static struct vfsconf fsname ## _vfsconf = { \
+ .vfc_version = VFS_VERSION, \
+ .vfc_name = #fsname, \
+ .vfc_vfsops = &vfsops, \
+ .vfc_typenum = -1, \
+ .vfc_flags = flags, \
+ }; \
+ static moduledata_t fsname ## _mod = { \
+ #fsname, \
+ vfs_modevent, \
+ & fsname ## _vfsconf \
+ }; \
+ DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE)
+
+/*
+ * exported vnode operations
+ */
+
+int dounmount(struct mount *, int, struct thread *);
+
+int kernel_mount(struct mntarg *ma, uint64_t flags);
+int kernel_vmount(int flags, ...);
+struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len);
+struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name);
+struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...);
+struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len);
+void statfs_scale_blocks(struct statfs *sf, long max_size);
+struct vfsconf *vfs_byname(const char *);
+struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *);
+void vfs_mount_destroy(struct mount *);
+void vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
+void vfs_freeopts(struct vfsoptlist *opts);
+void vfs_deleteopt(struct vfsoptlist *opts, const char *name);
+int vfs_buildopts(struct uio *auio, struct vfsoptlist **options);
+int vfs_flagopt(struct vfsoptlist *opts, const char *name, uint64_t *w,
+ uint64_t val);
+int vfs_getopt(struct vfsoptlist *, const char *, void **, int *);
+int vfs_getopt_pos(struct vfsoptlist *opts, const char *name);
+int vfs_getopt_size(struct vfsoptlist *opts, const char *name,
+ off_t *value);
+char *vfs_getopts(struct vfsoptlist *, const char *, int *error);
+int vfs_copyopt(struct vfsoptlist *, const char *, void *, int);
+int vfs_filteropt(struct vfsoptlist *, const char **legal);
+void vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...);
+int vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...);
+int vfs_setopt(struct vfsoptlist *opts, const char *name, void *value,
+ int len);
+int vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value,
+ int len);
+int vfs_setopts(struct vfsoptlist *opts, const char *name,
+ const char *value);
+int vfs_setpublicfs /* set publicly exported fs */
+ (struct mount *, struct netexport *, struct export_args *);
+void vfs_msync(struct mount *, int);
+int vfs_busy(struct mount *, int);
+int vfs_export /* process mount export info */
+ (struct mount *, struct export_args *);
+void vfs_allocate_syncvnode(struct mount *);
+void vfs_deallocate_syncvnode(struct mount *);
+int vfs_donmount(struct thread *td, uint64_t fsflags,
+ struct uio *fsoptions);
+void vfs_getnewfsid(struct mount *);
+struct cdev *vfs_getrootfsid(struct mount *);
+struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */
+struct mount *vfs_busyfs(fsid_t *);
+int vfs_modevent(module_t, int, void *);
+void vfs_mount_error(struct mount *, const char *, ...);
+void vfs_mountroot(void); /* mount our root filesystem */
+void vfs_mountedfrom(struct mount *, const char *from);
+void vfs_notify_upper(struct vnode *, int);
+void vfs_oexport_conv(const struct oexport_args *oexp,
+ struct export_args *exp);
+void vfs_ref(struct mount *);
+void vfs_rel(struct mount *);
+struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *,
+ struct ucred *);
+int vfs_suser(struct mount *, struct thread *);
+void vfs_unbusy(struct mount *);
+void vfs_unmountall(void);
+extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
+extern struct mtx mountlist_mtx;
+extern struct nfs_public nfs_pub;
+extern struct sx vfsconf_sx;
+#define vfsconf_lock() sx_xlock(&vfsconf_sx)
+#define vfsconf_unlock() sx_xunlock(&vfsconf_sx)
+#define vfsconf_slock() sx_slock(&vfsconf_sx)
+#define vfsconf_sunlock() sx_sunlock(&vfsconf_sx)
+
+/*
+ * Declarations for these vfs default operations are located in
+ * kern/vfs_default.c. They will be automatically used to replace
+ * null entries in VFS ops tables when registering a new filesystem
+ * type in the global table.
+ */
+vfs_root_t vfs_stdroot;
+vfs_quotactl_t vfs_stdquotactl;
+vfs_statfs_t vfs_stdstatfs;
+vfs_sync_t vfs_stdsync;
+vfs_sync_t vfs_stdnosync;
+vfs_vget_t vfs_stdvget;
+vfs_fhtovp_t vfs_stdfhtovp;
+vfs_checkexp_t vfs_stdcheckexp;
+vfs_init_t vfs_stdinit;
+vfs_uninit_t vfs_stduninit;
+vfs_extattrctl_t vfs_stdextattrctl;
+vfs_sysctl_t vfs_stdsysctl;
+
+void syncer_suspend(void);
+void syncer_resume(void);
+
+#else /* !_KERNEL */
+
+#include <sys/cdefs.h>
+
+struct stat;
+
+__BEGIN_DECLS
+int fhopen(const struct fhandle *, int);
+int fhstat(const struct fhandle *, struct stat *);
+int fhstatfs(const struct fhandle *, struct statfs *);
+int fstatfs(int, struct statfs *);
+int getfh(const char *, fhandle_t *);
+int getfsstat(struct statfs *, long, int);
+int getmntinfo(struct statfs **, int);
+int lgetfh(const char *, fhandle_t *);
+int mount(const char *, const char *, int, void *);
+int nmount(struct iovec *, unsigned int, int);
+int statfs(const char *, struct statfs *);
+int unmount(const char *, int);
+
+/* C library stuff */
+int getvfsbyname(const char *, struct xvfsconf *);
+__END_DECLS
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_MOUNT_H_ */
diff --git a/usr/src/boot/sys/sys/nlist_aout.h b/usr/src/boot/sys/sys/nlist_aout.h
new file mode 100644
index 0000000000..cb3dd85912
--- /dev/null
+++ b/usr/src/boot/sys/sys/nlist_aout.h
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)nlist.h 8.2 (Berkeley) 1/21/94
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_NLIST_AOUT_H_
+#define _SYS_NLIST_AOUT_H_
+
+/*
+ * Symbol table entries in a.out files.
+ */
+
+/*
+ * Layout of each symbol. The "#ifdef _AOUT_INCLUDE_" is so that
+ * programs including nlist.h can initialize nlist structures
+ * statically.
+ */
+struct nlist {
+#ifdef _AOUT_INCLUDE_
+ union {
+ const char *n_name; /* symbol name (in memory) */
+ long n_strx; /* file string table offset (on disk) */
+ } n_un;
+#else
+ const char *n_name; /* symbol name (in memory) */
+#endif
+ unsigned char n_type; /* type defines */
+ char n_other; /* ".type" and binding information */
+ short n_desc; /* used by stab entries */
+ unsigned long n_value; /* address/value of the symbol */
+};
+
+#define n_hash n_desc /* used internally by ld(1); XXX */
+
+/*
+ * Defines for n_type.
+ */
+#define N_UNDF 0x00 /* undefined */
+#define N_ABS 0x02 /* absolute address */
+#define N_TEXT 0x04 /* text segment */
+#define N_DATA 0x06 /* data segment */
+#define N_BSS 0x08 /* bss segment */
+#define N_INDR 0x0a /* alias definition */
+#define N_SIZE 0x0c /* pseudo type, defines a symbol's size */
+#define N_COMM 0x12 /* common reference */
+/* GNU extensions */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1a /* Bss set element symbol */
+#define N_SETV 0x1c /* Pointer to set vector in data area. */
+/* end GNU extensions */
+#define N_FN 0x1e /* file name (N_EXT on) */
+#define N_WARN 0x1e /* warning message (N_EXT off) */
+
+#define N_EXT 0x01 /* external (global) bit, OR'ed in */
+#define N_TYPE 0x1e /* mask for all the type bits */
+#define N_STAB 0xe0 /* mask for debugger symbols -- stab(5) */
+
+/*
+ * Defines for n_other. It contains the ".type" (AUX) field in the least
+ * significant 4 bits, and the binding (for weak symbols) in the most
+ * significant 4 bits.
+ */
+#define N_AUX(p) ((p)->n_other & 0xf)
+#define N_BIND(p) (((unsigned int)(p)->n_other >> 4) & 0xf)
+#define N_OTHER(r, v) (((unsigned int)(r) << 4) | ((v) & 0xf))
+
+#define AUX_OBJECT 1 /* data object */
+#define AUX_FUNC 2 /* function */
+
+/*#define BIND_LOCAL 0 not used */
+/*#define BIND_GLOBAL 1 not used */
+#define BIND_WEAK 2 /* weak binding */
+
+#define N_FORMAT "%08x" /* namelist value format; XXX */
+
+#endif /* !_SYS_NLIST_AOUT_H_ */
diff --git a/usr/src/boot/sys/sys/param.h b/usr/src/boot/sys/sys/param.h
new file mode 100644
index 0000000000..65c9cc4a88
--- /dev/null
+++ b/usr/src/boot/sys/sys/param.h
@@ -0,0 +1,363 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)param.h 8.3 (Berkeley) 4/4/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_PARAM_H_
+#define _SYS_PARAM_H_
+
+#include <sys/_null.h>
+
+#define BSD 199506 /* System version (year & month). */
+#define BSD4_3 1
+#define BSD4_4 1
+
+/*
+ * __FreeBSD_version numbers are documented in the Porter's Handbook.
+ * If you bump the version for any reason, you should update the documentation
+ * there.
+ * Currently this lives here in the doc/ repository:
+ *
+ * head/en_US.ISO8859-1/books/porters-handbook/versions/chapter.xml
+ *
+ * scheme is: <major><two digit minor>Rxx
+ * 'R' is in the range 0 to 4 if this is a release branch or
+ * x.0-CURRENT before RELENG_*_0 is created, otherwise 'R' is
+ * in the range 5 to 9.
+ */
+#undef __FreeBSD_version
+#define __FreeBSD_version 1100100 /* Master, propagated to newvers */
+
+/*
+ * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
+ * which by definition is always true on FreeBSD. This macro is also defined
+ * on other systems that use the kernel of FreeBSD, such as GNU/kFreeBSD.
+ *
+ * It is tempting to use this macro in userland code when we want to enable
+ * kernel-specific routines, and in fact it's fine to do this in code that
+ * is part of FreeBSD itself. However, be aware that as presence of this
+ * macro is still not widespread (e.g. older FreeBSD versions, 3rd party
+ * compilers, etc), it is STRONGLY DISCOURAGED to check for this macro in
+ * external applications without also checking for __FreeBSD__ as an
+ * alternative.
+ */
+#undef __FreeBSD_kernel__
+#define __FreeBSD_kernel__
+
+#ifdef _KERNEL
+#define P_OSREL_SIGWAIT 700000
+#define P_OSREL_SIGSEGV 700004
+#define P_OSREL_MAP_ANON 800104
+#define P_OSREL_MAP_FSTRICT 1100036
+#define P_OSREL_SHUTDOWN_ENOTCONN 1100077
+
+#define P_OSREL_MAJOR(x) ((x) / 100000)
+#endif
+
+#ifndef LOCORE
+#include <sys/types.h>
+#endif
+
+/*
+ * Machine-independent constants (some used in following include files).
+ * Redefined constants are from POSIX 1003.1 limits file.
+ *
+ * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>)
+ */
+#include <sys/syslimits.h>
+
+#define MAXCOMLEN 19 /* max command name remembered */
+#define MAXINTERP PATH_MAX /* max interpreter file name length */
+#define MAXLOGNAME 33 /* max login name length (incl. NUL) */
+#define MAXUPRC CHILD_MAX /* max simultaneous processes */
+#define NCARGS ARG_MAX /* max bytes for an exec function */
+#define NGROUPS (NGROUPS_MAX+1) /* max number groups */
+#define NOFILE OPEN_MAX /* max open files per process */
+#define NOGROUP 65535 /* marker for empty group set member */
+#define MAXHOSTNAMELEN 256 /* max hostname size */
+#define SPECNAMELEN 63 /* max length of devicename */
+
+/* More types and definitions used throughout the kernel. */
+#ifdef _KERNEL
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#ifndef LOCORE
+#include <sys/time.h>
+#include <sys/priority.h>
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#endif
+
+#ifndef _KERNEL
+/* Signals. */
+#include <sys/signal.h>
+#endif
+
+/* Machine type dependent parameters. */
+#include <machine/param.h>
+#ifndef _KERNEL
+#include <sys/limits.h>
+#endif
+
+#ifndef DEV_BSHIFT
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#endif
+#define DEV_BSIZE (1<<DEV_BSHIFT)
+
+#ifndef BLKDEV_IOSIZE
+#define BLKDEV_IOSIZE PAGE_SIZE /* default block device I/O size */
+#endif
+#ifndef DFLTPHYS
+#define DFLTPHYS (64 * 1024) /* default max raw I/O transfer size */
+#endif
+#ifndef MAXPHYS
+#define MAXPHYS (128 * 1024) /* max raw I/O transfer size */
+#endif
+#ifndef MAXDUMPPGS
+#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE)
+#endif
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than PAGE_SIZE.
+ */
+#ifndef MSIZE
+#define MSIZE 256 /* size of an mbuf */
+#endif
+
+#ifndef MCLSHIFT
+#define MCLSHIFT 11 /* convert bytes to mbuf clusters */
+#endif /* MCLSHIFT */
+
+#define MCLBYTES (1 << MCLSHIFT) /* size of an mbuf cluster */
+
+#if PAGE_SIZE < 2048
+#define MJUMPAGESIZE MCLBYTES
+#elif PAGE_SIZE <= 8192
+#define MJUMPAGESIZE PAGE_SIZE
+#else
+#define MJUMPAGESIZE (8 * 1024)
+#endif
+
+#define MJUM9BYTES (9 * 1024) /* jumbo cluster 9k */
+#define MJUM16BYTES (16 * 1024) /* jumbo cluster 16k */
+
+/*
+ * Some macros for units conversion
+ */
+
+/* clicks to bytes */
+#ifndef ctob
+#define ctob(x) ((x)<<PAGE_SHIFT)
+#endif
+
+/* bytes to clicks */
+#ifndef btoc
+#define btoc(x) (((vm_offset_t)(x)+PAGE_MASK)>>PAGE_SHIFT)
+#endif
+
+/*
+ * btodb() is messy and perhaps slow because `bytes' may be an off_t. We
+ * want to shift an unsigned type to avoid sign extension and we don't
+ * want to widen `bytes' unnecessarily. Assume that the result fits in
+ * a daddr_t.
+ */
+#ifndef btodb
+#define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
+ (sizeof (bytes) > sizeof(long) \
+ ? (daddr_t)((unsigned long long)(bytes) >> DEV_BSHIFT) \
+ : (daddr_t)((unsigned long)(bytes) >> DEV_BSHIFT))
+#endif
+
+#ifndef dbtob
+#define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
+ ((off_t)(db) << DEV_BSHIFT)
+#endif
+
+#define PRIMASK 0x0ff
+#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */
+#define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */
+
+#define NZERO 0 /* default "nice" */
+
+#define NBBY 8 /* number of bits in a byte */
+#define NBPW sizeof(int) /* number of bytes per word (integer) */
+
+#define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */
+
+#define NODEV (dev_t)(-1) /* non-existent device */
+
+/*
+ * File system parameters and macros.
+ *
+ * MAXBSIZE - Filesystems are made out of blocks of at most MAXBSIZE bytes
+ * per block. MAXBSIZE may be made larger without effecting
+ * any existing filesystems as long as it does not exceed MAXPHYS,
+ * and may be made smaller at the risk of not being able to use
+ * filesystems which require a block size exceeding MAXBSIZE.
+ *
+ * MAXBCACHEBUF - Maximum size of a buffer in the buffer cache. This must
+ * be >= MAXBSIZE and can be set differently for different
+ * architectures by defining it in <machine/param.h>.
+ * Making this larger allows NFS to do larger reads/writes.
+ *
+ * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the
+ * minimum KVM memory reservation the kernel is willing to make.
+ * Filesystems can of course request smaller chunks. Actual
+ * backing memory uses a chunk size of a page (PAGE_SIZE).
+ * The default value here can be overridden on a per-architecture
+ * basis by defining it in <machine/param.h>. This should
+ * probably be done to increase its value, when MAXBCACHEBUF is
+ * defined as a larger value in <machine/param.h>.
+ *
+ * If you make BKVASIZE too small you risk seriously fragmenting
+ * the buffer KVM map which may slow things down a bit. If you
+ * make it too big the kernel will not be able to optimally use
+ * the KVM memory reserved for the buffer cache and will wind
+ * up with too-few buffers.
+ *
+ * The default is 16384, roughly 2x the block size used by a
+ * normal UFS filesystem.
+ */
+#define MAXBSIZE 65536 /* must be power of 2 */
+#ifndef MAXBCACHEBUF
+#define MAXBCACHEBUF MAXBSIZE /* must be a power of 2 >= MAXBSIZE */
+#endif
+#ifndef BKVASIZE
+#define BKVASIZE 16384 /* must be power of 2 */
+#endif
+#define BKVAMASK (BKVASIZE-1)
+
+/*
+ * MAXPATHLEN defines the longest permissible path length after expanding
+ * symbolic links. It is used to allocate a temporary buffer from the buffer
+ * pool in which to do the name expansion, hence should be a power of two,
+ * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the
+ * maximum number of symbolic links that may be expanded in a path name.
+ * It should be set high enough to allow all legitimate uses, but halt
+ * infinite loops reasonably quickly.
+ */
+#define MAXPATHLEN PATH_MAX
+#define MAXSYMLINKS 32
+
+/* Bit map related macros. */
+#define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) \
+ (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) \
+ ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding. */
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
+#define rounddown(x, y) (((x)/(y))*(y))
+#define rounddown2(x, y) ((x)&(~((y)-1))) /* if y is power of two */
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
+#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#define powerof2(x) ((((x)-1)&(x))==0)
+
+/* Macros for min/max. */
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#ifdef _KERNEL
+/*
+ * Basic byte order function prototypes for non-inline functions.
+ */
+#ifndef LOCORE
+#ifndef _BYTEORDER_PROTOTYPED
+#define _BYTEORDER_PROTOTYPED
+__BEGIN_DECLS
+__uint32_t htonl(__uint32_t);
+__uint16_t htons(__uint16_t);
+__uint32_t ntohl(__uint32_t);
+__uint16_t ntohs(__uint16_t);
+__END_DECLS
+#endif
+#endif
+
+#ifndef lint
+#ifndef _BYTEORDER_FUNC_DEFINED
+#define _BYTEORDER_FUNC_DEFINED
+#define htonl(x) __htonl(x)
+#define htons(x) __htons(x)
+#define ntohl(x) __ntohl(x)
+#define ntohs(x) __ntohs(x)
+#endif /* !_BYTEORDER_FUNC_DEFINED */
+#endif /* lint */
+#endif /* _KERNEL */
+
+/*
+ * Scale factor for scaled integers used to count %cpu time and load avgs.
+ *
+ * The number of CPU `tick's that map to a unique `%age' can be expressed
+ * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that
+ * can be calculated (assuming 32 bits) can be closely approximated using
+ * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15).
+ *
+ * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age',
+ * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024.
+ */
+#define FSHIFT 11 /* bits to right of fixed binary point */
+#define FSCALE (1<<FSHIFT)
+
+#define dbtoc(db) /* calculates devblks to pages */ \
+ ((db + (ctodb(1) - 1)) >> (PAGE_SHIFT - DEV_BSHIFT))
+
+#define ctodb(db) /* calculates pages to devblks */ \
+ ((db) << (PAGE_SHIFT - DEV_BSHIFT))
+
+/*
+ * Old spelling of __containerof().
+ */
+#define member2struct(s, m, x) \
+ ((struct s *)(void *)((char *)(x) - offsetof(struct s, m)))
+
+/*
+ * Access a variable length array that has been declared as a fixed
+ * length array.
+ */
+#define __PAST_END(array, offset) (((__typeof__(*(array)) *)(array))[offset])
+
+#endif /* _SYS_PARAM_H_ */
diff --git a/usr/src/boot/sys/sys/queue.h b/usr/src/boot/sys/sys/queue.h
new file mode 100644
index 0000000000..1be9e9cc73
--- /dev/null
+++ b/usr/src/boot/sys/sys/queue.h
@@ -0,0 +1,753 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may be traversed in either direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ * SLIST LIST STAILQ TAILQ
+ * _HEAD + + + +
+ * _CLASS_HEAD + + + +
+ * _HEAD_INITIALIZER + + + +
+ * _ENTRY + + + +
+ * _CLASS_ENTRY + + + +
+ * _INIT + + + +
+ * _EMPTY + + + +
+ * _FIRST + + + +
+ * _NEXT + + + +
+ * _PREV - + - +
+ * _LAST - - + +
+ * _FOREACH + + + +
+ * _FOREACH_FROM + + + +
+ * _FOREACH_SAFE + + + +
+ * _FOREACH_FROM_SAFE + + + +
+ * _FOREACH_REVERSE - - - +
+ * _FOREACH_REVERSE_FROM - - - +
+ * _FOREACH_REVERSE_SAFE - - - +
+ * _FOREACH_REVERSE_FROM_SAFE - - - +
+ * _INSERT_HEAD + + + +
+ * _INSERT_BEFORE - + - +
+ * _INSERT_AFTER + + + +
+ * _INSERT_TAIL - - + +
+ * _CONCAT - - + +
+ * _REMOVE_AFTER + - + -
+ * _REMOVE_HEAD + - + -
+ * _REMOVE + + + +
+ * _SWAP + + + +
+ *
+ */
+#ifdef QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+ unsigned long lastline;
+ unsigned long prevline;
+ const char *lastfile;
+ const char *prevfile;
+};
+
+#define TRACEBUF struct qm_trace trace;
+#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
+#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
+#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
+
+#define QMD_TRACE_HEAD(head) do { \
+ (head)->trace.prevline = (head)->trace.lastline; \
+ (head)->trace.prevfile = (head)->trace.lastfile; \
+ (head)->trace.lastline = __LINE__; \
+ (head)->trace.lastfile = __FILE__; \
+} while (0)
+
+#define QMD_TRACE_ELEM(elem) do { \
+ (elem)->trace.prevline = (elem)->trace.lastline; \
+ (elem)->trace.prevfile = (elem)->trace.lastfile; \
+ (elem)->trace.lastline = __LINE__; \
+ (elem)->trace.lastfile = __FILE__; \
+} while (0)
+
+#else
+#define QMD_TRACE_ELEM(elem)
+#define QMD_TRACE_HEAD(head)
+#define QMD_SAVELINK(name, link)
+#define TRACEBUF
+#define TRACEBUF_INITIALIZER
+#define TRASHIT(x)
+#endif /* QUEUE_MACRO_DEBUG */
+
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define QUEUE_TYPEOF(type) type
+#else
+#define QUEUE_TYPEOF(type) struct type
+#endif
+
+/*
+ * Singly-linked List declarations.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+#define SLIST_CLASS_ENTRY(type) \
+struct { \
+ class type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+
+#define SLIST_FIRST(head) ((head)->slh_first)
+
+#define SLIST_FOREACH(var, head, field) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var); \
+ (var) = SLIST_NEXT((var), field))
+
+#define SLIST_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
+ (var); \
+ (var) = SLIST_NEXT((var), field))
+
+#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
+ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
+ for ((varp) = &SLIST_FIRST((head)); \
+ ((var) = *(varp)) != NULL; \
+ (varp) = &SLIST_NEXT((var), field))
+
+#define SLIST_INIT(head) do { \
+ SLIST_FIRST((head)) = NULL; \
+} while (0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
+ SLIST_NEXT((slistelm), field) = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
+ SLIST_FIRST((head)) = (elm); \
+} while (0)
+
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
+ if (SLIST_FIRST((head)) == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
+ while (SLIST_NEXT(curelm, field) != (elm)) \
+ curelm = SLIST_NEXT(curelm, field); \
+ SLIST_REMOVE_AFTER(curelm, field); \
+ } \
+ TRASHIT(*oldnext); \
+} while (0)
+
+#define SLIST_REMOVE_AFTER(elm, field) do { \
+ SLIST_NEXT(elm, field) = \
+ SLIST_NEXT(SLIST_NEXT(elm, field), field); \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
+} while (0)
+
+#define SLIST_SWAP(head1, head2, type) do { \
+ QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
+ SLIST_FIRST(head1) = SLIST_FIRST(head2); \
+ SLIST_FIRST(head2) = swap_first; \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first;/* first element */ \
+ struct type **stqh_last;/* addr of last next element */ \
+}
+
+#define STAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *stqh_first; /* first element */ \
+ class type **stqh_last; /* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+#define STAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (0)
+
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for((var) = STAILQ_FIRST((head)); \
+ (var); \
+ (var) = STAILQ_NEXT((var), field))
+
+#define STAILQ_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
+ (var); \
+ (var) = STAILQ_NEXT((var), field))
+
+#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = STAILQ_FIRST((head)); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define STAILQ_INIT(head) do { \
+ STAILQ_FIRST((head)) = NULL; \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_NEXT((tqelm), field) = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_FIRST((head)) = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ STAILQ_NEXT((elm), field) = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+} while (0)
+
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? NULL : \
+ __containerof((head)->stqh_last, \
+ QUEUE_TYPEOF(type), field.stqe_next))
+
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
+ if (STAILQ_FIRST((head)) == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
+ while (STAILQ_NEXT(curelm, field) != (elm)) \
+ curelm = STAILQ_NEXT(curelm, field); \
+ STAILQ_REMOVE_AFTER(head, curelm, field); \
+ } \
+ TRASHIT(*oldnext); \
+} while (0)
+
+#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
+ if ((STAILQ_NEXT(elm, field) = \
+ STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+} while (0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if ((STAILQ_FIRST((head)) = \
+ STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#define STAILQ_SWAP(head1, head2, type) do { \
+ QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
+ STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_FIRST(head2) = swap_first; \
+ (head2)->stqh_last = swap_last; \
+ if (STAILQ_EMPTY(head1)) \
+ (head1)->stqh_last = &STAILQ_FIRST(head1); \
+ if (STAILQ_EMPTY(head2)) \
+ (head2)->stqh_last = &STAILQ_FIRST(head2); \
+} while (0)
+
+
+/*
+ * List declarations.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+#define LIST_CLASS_ENTRY(type) \
+struct { \
+ class type *le_next; /* next element */ \
+ class type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define QMD_LIST_CHECK_HEAD(head, field) do { \
+ if (LIST_FIRST((head)) != NULL && \
+ LIST_FIRST((head))->field.le_prev != \
+ &LIST_FIRST((head))) \
+ panic("Bad list head %p first->prev != head", (head)); \
+} while (0)
+
+#define QMD_LIST_CHECK_NEXT(elm, field) do { \
+ if (LIST_NEXT((elm), field) != NULL && \
+ LIST_NEXT((elm), field)->field.le_prev != \
+ &((elm)->field.le_next)) \
+ panic("Bad link elm %p next->prev != elm", (elm)); \
+} while (0)
+
+#define QMD_LIST_CHECK_PREV(elm, field) do { \
+ if (*(elm)->field.le_prev != (elm)) \
+ panic("Bad link elm %p prev->next != elm", (elm)); \
+} while (0)
+#else
+#define QMD_LIST_CHECK_HEAD(head, field)
+#define QMD_LIST_CHECK_NEXT(elm, field)
+#define QMD_LIST_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+
+#define LIST_FIRST(head) ((head)->lh_first)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = LIST_FIRST((head)); \
+ (var); \
+ (var) = LIST_NEXT((var), field))
+
+#define LIST_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
+ (var); \
+ (var) = LIST_NEXT((var), field))
+
+#define LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = LIST_FIRST((head)); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define LIST_INIT(head) do { \
+ LIST_FIRST((head)) = NULL; \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ QMD_LIST_CHECK_NEXT(listelm, field); \
+ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+ LIST_NEXT((listelm), field)->field.le_prev = \
+ &LIST_NEXT((elm), field); \
+ LIST_NEXT((listelm), field) = (elm); \
+ (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ QMD_LIST_CHECK_PREV(listelm, field); \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ LIST_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ QMD_LIST_CHECK_HEAD((head), field); \
+ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
+ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+ LIST_FIRST((head)) = (elm); \
+ (elm)->field.le_prev = &LIST_FIRST((head)); \
+} while (0)
+
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_PREV(elm, head, type, field) \
+ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
+ __containerof((elm)->field.le_prev, \
+ QUEUE_TYPEOF(type), field.le_next))
+
+#define LIST_REMOVE(elm, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.le_next); \
+ QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
+ QMD_LIST_CHECK_NEXT(elm, field); \
+ QMD_LIST_CHECK_PREV(elm, field); \
+ if (LIST_NEXT((elm), field) != NULL) \
+ LIST_NEXT((elm), field)->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = LIST_NEXT((elm), field); \
+ TRASHIT(*oldnext); \
+ TRASHIT(*oldprev); \
+} while (0)
+
+#define LIST_SWAP(head1, head2, type, field) do { \
+ QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
+ LIST_FIRST((head1)) = LIST_FIRST((head2)); \
+ LIST_FIRST((head2)) = swap_tmp; \
+ if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
+ swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
+ if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
+ swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *tqh_first; /* first element */ \
+ class type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *tqe_next; /* next element */ \
+ class type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+/*
+ * Tail queue functions.
+ */
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
+ if (!TAILQ_EMPTY(head) && \
+ TAILQ_FIRST((head))->field.tqe_prev != \
+ &TAILQ_FIRST((head))) \
+ panic("Bad tailq head %p first->prev != head", (head)); \
+} while (0)
+
+#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
+ if (*(head)->tqh_last != NULL) \
+ panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
+} while (0)
+
+#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
+ if (TAILQ_NEXT((elm), field) != NULL && \
+ TAILQ_NEXT((elm), field)->field.tqe_prev != \
+ &((elm)->field.tqe_next)) \
+ panic("Bad link elm %p next->prev != elm", (elm)); \
+} while (0)
+
+#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
+ if (*(elm)->field.tqe_prev != (elm)) \
+ panic("Bad link elm %p prev->next != elm", (elm)); \
+} while (0)
+#else
+#define QMD_TAILQ_CHECK_HEAD(head, field)
+#define QMD_TAILQ_CHECK_TAIL(head, headname)
+#define QMD_TAILQ_CHECK_NEXT(elm, field)
+#define QMD_TAILQ_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ QMD_TRACE_HEAD(head1); \
+ QMD_TRACE_HEAD(head2); \
+ } \
+} while (0)
+
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#define TAILQ_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_INIT(head) do { \
+ TAILQ_FIRST((head)) = NULL; \
+ (head)->tqh_last = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QMD_TAILQ_CHECK_NEXT(listelm, field); \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else { \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ } \
+ TAILQ_NEXT((listelm), field) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ QMD_TAILQ_CHECK_PREV(listelm, field); \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ TAILQ_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ QMD_TAILQ_CHECK_HEAD(head, field); \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
+ TAILQ_FIRST((head))->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ TAILQ_FIRST((head)) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ QMD_TAILQ_CHECK_TAIL(head, field); \
+ TAILQ_NEXT((elm), field) = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
+ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
+ QMD_TAILQ_CHECK_NEXT(elm, field); \
+ QMD_TAILQ_CHECK_PREV(elm, field); \
+ if ((TAILQ_NEXT((elm), field)) != NULL) \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else { \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ QMD_TRACE_HEAD(head); \
+ } \
+ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
+ TRASHIT(*oldnext); \
+ TRASHIT(*oldprev); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_SWAP(head1, head2, type, field) do { \
+ QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
+ (head1)->tqh_first = (head2)->tqh_first; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ (head2)->tqh_first = swap_first; \
+ (head2)->tqh_last = swap_last; \
+ if ((swap_first = (head1)->tqh_first) != NULL) \
+ swap_first->field.tqe_prev = &(head1)->tqh_first; \
+ else \
+ (head1)->tqh_last = &(head1)->tqh_first; \
+ if ((swap_first = (head2)->tqh_first) != NULL) \
+ swap_first->field.tqe_prev = &(head2)->tqh_first; \
+ else \
+ (head2)->tqh_last = &(head2)->tqh_first; \
+} while (0)
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/usr/src/boot/sys/sys/reboot.h b/usr/src/boot/sys/sys/reboot.h
new file mode 100644
index 0000000000..ebe688e869
--- /dev/null
+++ b/usr/src/boot/sys/sys/reboot.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1982, 1986, 1988, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)reboot.h 8.3 (Berkeley) 12/13/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+/*
+ * Arguments to reboot system call. These are passed to
+ * the boot program and on to init.
+ */
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#define RB_ASKNAME 0x001 /* ask for file name to reboot from */
+#define RB_SINGLE 0x002 /* reboot to single user only */
+#define RB_NOSYNC 0x004 /* dont sync before reboot */
+#define RB_HALT 0x008 /* don't reboot, just halt */
+#define RB_INITNAME 0x010 /* name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x020 /* use compiled-in rootdev */
+#define RB_KDB 0x040 /* give control to kernel debugger */
+#define RB_RDONLY 0x080 /* mount root fs read-only */
+#define RB_DUMP 0x100 /* dump kernel memory before reboot */
+#define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */
+#define RB_VERBOSE 0x800 /* print all potentially useful info */
+#define RB_SERIAL 0x1000 /* use serial port as console */
+#define RB_CDROM 0x2000 /* use cdrom as root */
+#define RB_POWEROFF 0x4000 /* turn the power off if possible */
+#define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */
+#define RB_MUTE 0x10000 /* start up with the console muted */
+#define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */
+#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
+#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
+#define RB_PAUSE 0x100000 /* pause after each output line during probe */
+#define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */
+#define RB_MULTIPLE 0x20000000 /* use multiple consoles */
+
+#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
+
+#endif
diff --git a/usr/src/boot/sys/sys/select.h b/usr/src/boot/sys/sys/select.h
new file mode 100644
index 0000000000..8a899acb68
--- /dev/null
+++ b/usr/src/boot/sys/sys/select.h
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SELECT_H_
+#define _SYS_SELECT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#include <sys/_sigset.h>
+#include <sys/_timeval.h>
+#include <sys/timespec.h>
+
+typedef unsigned long __fd_mask;
+#if __BSD_VISIBLE
+typedef __fd_mask fd_mask;
+#endif
+
+#ifndef _SIGSET_T_DECLARED
+#define _SIGSET_T_DECLARED
+typedef __sigset_t sigset_t;
+#endif
+
+/*
+ * Select uses bit masks of file descriptors in longs. These macros
+ * manipulate such bit fields (the filesystem macros use chars).
+ * FD_SETSIZE may be defined by the user, but the default here should
+ * be enough for most uses.
+ */
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 1024
+#endif
+
+#define _NFDBITS (sizeof(__fd_mask) * 8) /* bits per mask */
+#if __BSD_VISIBLE
+#define NFDBITS _NFDBITS
+#endif
+
+#ifndef _howmany
+#define _howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+
+typedef struct fd_set {
+ __fd_mask __fds_bits[_howmany(FD_SETSIZE, _NFDBITS)];
+} fd_set;
+#if __BSD_VISIBLE
+#define fds_bits __fds_bits
+#endif
+
+#define __fdset_mask(n) ((__fd_mask)1 << ((n) % _NFDBITS))
+#define FD_CLR(n, p) ((p)->__fds_bits[(n)/_NFDBITS] &= ~__fdset_mask(n))
+#if __BSD_VISIBLE
+#define FD_COPY(f, t) (void)(*(t) = *(f))
+#endif
+#define FD_ISSET(n, p) (((p)->__fds_bits[(n)/_NFDBITS] & __fdset_mask(n)) != 0)
+#define FD_SET(n, p) ((p)->__fds_bits[(n)/_NFDBITS] |= __fdset_mask(n))
+#define FD_ZERO(p) do { \
+ fd_set *_p; \
+ __size_t _n; \
+ \
+ _p = (p); \
+ _n = _howmany(FD_SETSIZE, _NFDBITS); \
+ while (_n > 0) \
+ _p->__fds_bits[--_n] = 0; \
+} while (0)
+
+#ifndef _KERNEL
+
+__BEGIN_DECLS
+int pselect(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict,
+ const struct timespec *__restrict, const sigset_t *__restrict);
+#ifndef _SELECT_DECLARED
+#define _SELECT_DECLARED
+/* XXX missing restrict type-qualifier */
+int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#endif
+__END_DECLS
+#endif /* !_KERNEL */
+
+#endif /* _SYS_SELECT_H_ */
diff --git a/usr/src/boot/sys/sys/signal.h b/usr/src/boot/sys/sys/signal.h
new file mode 100644
index 0000000000..259c39aed4
--- /dev/null
+++ b/usr/src/boot/sys/sys/signal.h
@@ -0,0 +1,443 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)signal.h 8.4 (Berkeley) 5/4/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SIGNAL_H_
+#define _SYS_SIGNAL_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <sys/_sigset.h>
+
+#include <machine/_limits.h> /* __MINSIGSTKSZ */
+#include <machine/signal.h> /* sig_atomic_t; trap codes; sigcontext */
+
+/*
+ * System defined signals.
+ */
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGHUP 1 /* hangup */
+#endif
+#define SIGINT 2 /* interrupt */
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGQUIT 3 /* quit */
+#endif
+#define SIGILL 4 /* illegal instr. (not reset when caught) */
+#if __XSI_VISIBLE
+#define SIGTRAP 5 /* trace trap (not reset when caught) */
+#endif
+#define SIGABRT 6 /* abort() */
+#if __BSD_VISIBLE
+#define SIGIOT SIGABRT /* compatibility */
+#define SIGEMT 7 /* EMT instruction */
+#endif
+#define SIGFPE 8 /* floating point exception */
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGKILL 9 /* kill (cannot be caught or ignored) */
+#endif
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#define SIGBUS 10 /* bus error */
+#endif
+#define SIGSEGV 11 /* segmentation violation */
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#define SIGSYS 12 /* non-existent system call invoked */
+#endif
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGPIPE 13 /* write on a pipe with no one to read it */
+#define SIGALRM 14 /* alarm clock */
+#endif
+#define SIGTERM 15 /* software termination signal from kill */
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#define SIGURG 16 /* urgent condition on IO channel */
+#endif
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGSTOP 17 /* sendable stop signal not from tty */
+#define SIGTSTP 18 /* stop signal from tty */
+#define SIGCONT 19 /* continue a stopped process */
+#define SIGCHLD 20 /* to parent on child stop or exit */
+#define SIGTTIN 21 /* to readers pgrp upon background tty read */
+#define SIGTTOU 22 /* like TTIN if (tp->t_local&LTOSTOP) */
+#endif
+#if __BSD_VISIBLE
+#define SIGIO 23 /* input/output possible signal */
+#endif
+#if __XSI_VISIBLE
+#define SIGXCPU 24 /* exceeded CPU time limit */
+#define SIGXFSZ 25 /* exceeded file size limit */
+#define SIGVTALRM 26 /* virtual time alarm */
+#define SIGPROF 27 /* profiling time alarm */
+#endif
+#if __BSD_VISIBLE
+#define SIGWINCH 28 /* window size changes */
+#define SIGINFO 29 /* information request */
+#endif
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SIGUSR1 30 /* user defined signal 1 */
+#define SIGUSR2 31 /* user defined signal 2 */
+#endif
+#if __BSD_VISIBLE
+#define SIGTHR 32 /* reserved by thread library. */
+#define SIGLWP SIGTHR
+#define SIGLIBRT 33 /* reserved by real-time library. */
+#endif
+
+#define SIGRTMIN 65
+#define SIGRTMAX 126
+
+#define SIG_DFL ((__sighandler_t *)0)
+#define SIG_IGN ((__sighandler_t *)1)
+#define SIG_ERR ((__sighandler_t *)-1)
+/* #define SIG_CATCH ((__sighandler_t *)2) See signalvar.h */
+#define SIG_HOLD ((__sighandler_t *)3)
+
+/*
+ * Type of a signal handling function.
+ *
+ * Language spec sez signal handlers take exactly one arg, even though we
+ * actually supply three. Ugh!
+ *
+ * We don't try to hide the difference by leaving out the args because
+ * that would cause warnings about conformant programs. Nonconformant
+ * programs can avoid the warnings by casting to (__sighandler_t *) or
+ * sig_t before calling signal() or assigning to sa_handler or sv_handler.
+ *
+ * The kernel should reverse the cast before calling the function. It
+ * has no way to do this, but on most machines 1-arg and 3-arg functions
+ * have the same calling protocol so there is no problem in practice.
+ * A bit in sa_flags could be used to specify the number of args.
+ */
+typedef void __sighandler_t(int);
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#ifndef _SIGSET_T_DECLARED
+#define _SIGSET_T_DECLARED
+typedef __sigset_t sigset_t;
+#endif
+#endif
+
+#if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE >= 500
+union sigval {
+ /* Members as suggested by Annex C of POSIX 1003.1b. */
+ int sival_int;
+ void *sival_ptr;
+ /* 6.0 compatibility */
+ int sigval_int;
+ void *sigval_ptr;
+};
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+struct sigevent {
+ int sigev_notify; /* Notification type */
+ int sigev_signo; /* Signal number */
+ union sigval sigev_value; /* Signal value */
+ union {
+ __lwpid_t _threadid;
+ struct {
+ void (*_function)(union sigval);
+ void *_attribute; /* pthread_attr_t * */
+ } _sigev_thread;
+ unsigned short _kevent_flags;
+ long __spare__[8];
+ } _sigev_un;
+};
+
+#if __BSD_VISIBLE
+#define sigev_notify_kqueue sigev_signo
+#define sigev_notify_kevent_flags _sigev_un._kevent_flags
+#define sigev_notify_thread_id _sigev_un._threadid
+#endif
+#define sigev_notify_function _sigev_un._sigev_thread._function
+#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+#define SIGEV_NONE 0 /* No async notification. */
+#define SIGEV_SIGNAL 1 /* Generate a queued signal. */
+#define SIGEV_THREAD 2 /* Call back from another pthread. */
+#if __BSD_VISIBLE
+#define SIGEV_KEVENT 3 /* Generate a kevent. */
+#define SIGEV_THREAD_ID 4 /* Send signal to a kernel thread. */
+#endif
+#endif /* __POSIX_VISIBLE >= 199309 */
+
+#if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE
+typedef struct __siginfo {
+ int si_signo; /* signal number */
+ int si_errno; /* errno association */
+ /*
+ * Cause of signal, one of the SI_ macros or signal-specific
+ * values, i.e. one of the FPE_... values for SIGFPE. This
+ * value is equivalent to the second argument to an old-style
+ * FreeBSD signal handler.
+ */
+ int si_code; /* signal code */
+ __pid_t si_pid; /* sending process */
+ __uid_t si_uid; /* sender's ruid */
+ int si_status; /* exit value */
+ void *si_addr; /* faulting instruction */
+ union sigval si_value; /* signal value */
+ union {
+ struct {
+ int _trapno;/* machine specific trap code */
+ } _fault;
+ struct {
+ int _timerid;
+ int _overrun;
+ } _timer;
+ struct {
+ int _mqd;
+ } _mesgq;
+ struct {
+ long _band; /* band event for SIGPOLL */
+ } _poll; /* was this ever used ? */
+ struct {
+ long __spare1__;
+ int __spare2__[7];
+ } __spare__;
+ } _reason;
+} siginfo_t;
+
+#define si_trapno _reason._fault._trapno
+#define si_timerid _reason._timer._timerid
+#define si_overrun _reason._timer._overrun
+#define si_mqd _reason._mesgq._mqd
+#define si_band _reason._poll._band
+
+/** si_code **/
+/* codes for SIGILL */
+#define ILL_ILLOPC 1 /* Illegal opcode. */
+#define ILL_ILLOPN 2 /* Illegal operand. */
+#define ILL_ILLADR 3 /* Illegal addressing mode. */
+#define ILL_ILLTRP 4 /* Illegal trap. */
+#define ILL_PRVOPC 5 /* Privileged opcode. */
+#define ILL_PRVREG 6 /* Privileged register. */
+#define ILL_COPROC 7 /* Coprocessor error. */
+#define ILL_BADSTK 8 /* Internal stack error. */
+
+/* codes for SIGBUS */
+#define BUS_ADRALN 1 /* Invalid address alignment. */
+#define BUS_ADRERR 2 /* Nonexistent physical address. */
+#define BUS_OBJERR 3 /* Object-specific hardware error. */
+
+/* codes for SIGSEGV */
+#define SEGV_MAPERR 1 /* Address not mapped to object. */
+#define SEGV_ACCERR 2 /* Invalid permissions for mapped */
+ /* object. */
+
+/* codes for SIGFPE */
+#define FPE_INTOVF 1 /* Integer overflow. */
+#define FPE_INTDIV 2 /* Integer divide by zero. */
+#define FPE_FLTDIV 3 /* Floating point divide by zero. */
+#define FPE_FLTOVF 4 /* Floating point overflow. */
+#define FPE_FLTUND 5 /* Floating point underflow. */
+#define FPE_FLTRES 6 /* Floating point inexact result. */
+#define FPE_FLTINV 7 /* Invalid floating point operation. */
+#define FPE_FLTSUB 8 /* Subscript out of range. */
+
+/* codes for SIGTRAP */
+#define TRAP_BRKPT 1 /* Process breakpoint. */
+#define TRAP_TRACE 2 /* Process trace trap. */
+#define TRAP_DTRACE 3 /* DTrace induced trap. */
+
+/* codes for SIGCHLD */
+#define CLD_EXITED 1 /* Child has exited */
+#define CLD_KILLED 2 /* Child has terminated abnormally but */
+ /* did not create a core file */
+#define CLD_DUMPED 3 /* Child has terminated abnormally and */
+ /* created a core file */
+#define CLD_TRAPPED 4 /* Traced child has trapped */
+#define CLD_STOPPED 5 /* Child has stopped */
+#define CLD_CONTINUED 6 /* Stopped child has continued */
+
+/* codes for SIGPOLL */
+#define POLL_IN 1 /* Data input available */
+#define POLL_OUT 2 /* Output buffers available */
+#define POLL_MSG 3 /* Input message available */
+#define POLL_ERR 4 /* I/O Error */
+#define POLL_PRI 5 /* High priority input available */
+#define POLL_HUP 6 /* Device disconnected */
+
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+struct __siginfo;
+
+/*
+ * Signal vector "template" used in sigaction call.
+ */
+struct sigaction {
+ union {
+ void (*__sa_handler)(int);
+ void (*__sa_sigaction)(int, struct __siginfo *, void *);
+ } __sigaction_u; /* signal handler */
+ int sa_flags; /* see signal options below */
+ sigset_t sa_mask; /* signal mask to apply */
+};
+
+#define sa_handler __sigaction_u.__sa_handler
+#endif
+
+#if __XSI_VISIBLE
+/* If SA_SIGINFO is set, sa_sigaction must be used instead of sa_handler. */
+#define sa_sigaction __sigaction_u.__sa_sigaction
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */
+#endif /* __POSIX_VISIBLE || __XSI_VISIBLE */
+
+#if __XSI_VISIBLE
+#define SA_ONSTACK 0x0001 /* take signal on signal stack */
+#define SA_RESTART 0x0002 /* restart system call on signal return */
+#define SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */
+#define SA_NODEFER 0x0010 /* don't mask the signal we're delivering */
+#define SA_NOCLDWAIT 0x0020 /* don't keep zombies around */
+#define SA_SIGINFO 0x0040 /* signal handler with SA_SIGINFO args */
+#endif
+
+#if __BSD_VISIBLE
+#define NSIG 32 /* number of old signals (counting 0) */
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define SI_NOINFO 0 /* No signal info besides si_signo. */
+#define SI_USER 0x10001 /* Signal sent by kill(). */
+#define SI_QUEUE 0x10002 /* Signal sent by the sigqueue(). */
+#define SI_TIMER 0x10003 /* Signal generated by expiration of */
+ /* a timer set by timer_settime(). */
+#define SI_ASYNCIO 0x10004 /* Signal generated by completion of */
+ /* an asynchronous I/O request.*/
+#define SI_MESGQ 0x10005 /* Signal generated by arrival of a */
+ /* message on an empty message queue. */
+#define SI_KERNEL 0x10006
+#define SI_LWP 0x10007 /* Signal sent by thr_kill */
+#endif
+#if __BSD_VISIBLE
+#define SI_UNDEFINED 0
+#endif
+
+#if __BSD_VISIBLE
+typedef __sighandler_t *sig_t; /* type of pointer to a signal function */
+typedef void __siginfohandler_t(int, struct __siginfo *, void *);
+#endif
+
+#if __XSI_VISIBLE
+/*
+ * Structure used in sigaltstack call.
+ */
+#if __BSD_VISIBLE
+typedef struct sigaltstack {
+#else
+typedef struct {
+#endif
+ void *ss_sp; /* signal stack base */
+ __size_t ss_size; /* signal stack length */
+ int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
+} stack_t;
+
+#define SS_ONSTACK 0x0001 /* take signal on alternate stack */
+#define SS_DISABLE 0x0004 /* disable taking signals on alternate stack */
+#define MINSIGSTKSZ __MINSIGSTKSZ /* minimum stack size */
+#define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */
+#endif
+
+#if __BSD_VISIBLE
+/*
+ * 4.3 compatibility:
+ * Signal vector "template" used in sigvec call.
+ */
+struct sigvec {
+ __sighandler_t *sv_handler; /* signal handler */
+ int sv_mask; /* signal mask to apply */
+ int sv_flags; /* see signal options below */
+};
+
+#define SV_ONSTACK SA_ONSTACK
+#define SV_INTERRUPT SA_RESTART /* same bit, opposite sense */
+#define SV_RESETHAND SA_RESETHAND
+#define SV_NODEFER SA_NODEFER
+#define SV_NOCLDSTOP SA_NOCLDSTOP
+#define SV_SIGINFO SA_SIGINFO
+#define sv_onstack sv_flags /* isn't compatibility wonderful! */
+#endif
+
+/* Keep this in one place only */
+#if defined(_KERNEL) && defined(COMPAT_43) && \
+ !defined(__i386__)
+struct osigcontext {
+ int _not_used;
+};
+#endif
+
+#if __XSI_VISIBLE
+/*
+ * Structure used in sigstack call.
+ */
+struct sigstack {
+ void *ss_sp; /* signal stack pointer */
+ int ss_onstack; /* current status */
+};
+#endif
+
+#if __BSD_VISIBLE || __POSIX_VISIBLE > 0 && __POSIX_VISIBLE <= 200112
+/*
+ * Macro for converting signal number to a mask suitable for
+ * sigblock().
+ */
+#define sigmask(m) (1 << ((m)-1))
+#endif
+
+#if __BSD_VISIBLE
+#define BADSIG SIG_ERR
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+/*
+ * Flags for sigprocmask:
+ */
+#define SIG_BLOCK 1 /* block specified signal set */
+#define SIG_UNBLOCK 2 /* unblock specified signal set */
+#define SIG_SETMASK 3 /* set specified signal set */
+#endif
+
+/*
+ * For historical reasons; programs expect signal's return value to be
+ * defined by <sys/signal.h>.
+ */
+__BEGIN_DECLS
+__sighandler_t *signal(int, __sighandler_t *);
+__END_DECLS
+
+#endif /* !_SYS_SIGNAL_H_ */
diff --git a/usr/src/boot/sys/sys/socket.h b/usr/src/boot/sys/sys/socket.h
new file mode 100644
index 0000000000..c20b07522c
--- /dev/null
+++ b/usr/src/boot/sys/sys/socket.h
@@ -0,0 +1,690 @@
+/*-
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)socket.h 8.4 (Berkeley) 2/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SOCKET_H_
+#define _SYS_SOCKET_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <sys/_iovec.h>
+#include <machine/_align.h>
+
+/*
+ * Definitions related to sockets: types, address families, options.
+ */
+
+/*
+ * Data types.
+ */
+#if __BSD_VISIBLE
+#ifndef _GID_T_DECLARED
+typedef __gid_t gid_t;
+#define _GID_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
+#ifndef _PID_T_DECLARED
+typedef __pid_t pid_t;
+#define _PID_T_DECLARED
+#endif
+#endif
+
+#ifndef _SA_FAMILY_T_DECLARED
+typedef __sa_family_t sa_family_t;
+#define _SA_FAMILY_T_DECLARED
+#endif
+
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#ifndef _SSIZE_T_DECLARED
+typedef __ssize_t ssize_t;
+#define _SSIZE_T_DECLARED
+#endif
+
+#if __BSD_VISIBLE
+#ifndef _UID_T_DECLARED
+typedef __uid_t uid_t;
+#define _UID_T_DECLARED
+#endif
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _UINTPTR_T_DECLARED
+typedef __uintptr_t uintptr_t;
+#define _UINTPTR_T_DECLARED
+#endif
+
+/*
+ * Types
+ */
+#define SOCK_STREAM 1 /* stream socket */
+#define SOCK_DGRAM 2 /* datagram socket */
+#define SOCK_RAW 3 /* raw-protocol interface */
+#if __BSD_VISIBLE
+#define SOCK_RDM 4 /* reliably-delivered message */
+#endif
+#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+
+#if __BSD_VISIBLE
+/*
+ * Creation flags, OR'ed into socket() and socketpair() type argument.
+ */
+#define SOCK_CLOEXEC 0x10000000
+#define SOCK_NONBLOCK 0x20000000
+#endif
+
+/*
+ * Option flags per-socket.
+ */
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#if __BSD_VISIBLE
+#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
+#endif
+#define SO_LINGER 0x0080 /* linger on close if data present */
+#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
+#if __BSD_VISIBLE
+#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
+#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */
+#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */
+#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */
+#define SO_BINTIME 0x2000 /* timestamp received dgram traffic */
+#endif
+#define SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */
+#define SO_NO_DDP 0x8000 /* disable direct data placement */
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+#if __BSD_VISIBLE
+#define SO_LABEL 0x1009 /* socket's MAC label */
+#define SO_PEERLABEL 0x1010 /* socket's peer's MAC label */
+#define SO_LISTENQLIMIT 0x1011 /* socket's backlog limit */
+#define SO_LISTENQLEN 0x1012 /* socket's complete queue length */
+#define SO_LISTENINCQLEN 0x1013 /* socket's incomplete queue length */
+#define SO_SETFIB 0x1014 /* use this FIB to route */
+#define SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */
+#define SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */
+#define SO_PROTOTYPE SO_PROTOCOL /* alias for SO_PROTOCOL (SunOS name) */
+#endif
+
+/*
+ * Space reserved for new socket options added by third-party vendors.
+ * This range applies to all socket option levels. New socket options
+ * in FreeBSD should always use an option value less than SO_VENDOR.
+ */
+#if __BSD_VISIBLE
+#define SO_VENDOR 0x80000000
+#endif
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+
+#if __BSD_VISIBLE
+struct accept_filter_arg {
+ char af_name[16];
+ char af_arg[256-16];
+};
+#endif
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xffff /* options for socket level */
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#if __BSD_VISIBLE
+#define AF_LOCAL AF_UNIX /* local to host (pipes, portals) */
+#endif
+#define AF_UNIX 1 /* standardized name for AF_LOCAL */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#if __BSD_VISIBLE
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NETBIOS 6 /* SMB protocols */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO
+#define AF_ECMA 8 /* European computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* DEC Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* Apple Talk */
+#define AF_ROUTE 17 /* Internal Routing Protocol */
+#define AF_LINK 18 /* Link layer interface */
+#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
+#define AF_COIP 20 /* connection-oriented IP, aka ST II */
+#define AF_CNT 21 /* Computer Network Technology */
+#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */
+#define AF_IPX 23 /* Novell Internet Protocol */
+#define AF_SIP 24 /* Simple Internet Protocol */
+#define pseudo_AF_PIP 25 /* Help Identify PIP packets */
+#define AF_ISDN 26 /* Integrated Services Digital Network*/
+#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */
+#define pseudo_AF_KEY 27 /* Internal key-management function */
+#endif
+#define AF_INET6 28 /* IPv6 */
+#if __BSD_VISIBLE
+#define AF_NATM 29 /* native ATM access */
+#define AF_ATM 30 /* ATM */
+#define pseudo_AF_HDRCMPLT 31 /* Used by BPF to not rewrite headers
+ * in interface output routine
+ */
+#define AF_NETGRAPH 32 /* Netgraph sockets */
+#define AF_SLOW 33 /* 802.3ad slow protocol */
+#define AF_SCLUSTER 34 /* Sitara cluster protocol */
+#define AF_ARP 35
+#define AF_BLUETOOTH 36 /* Bluetooth sockets */
+#define AF_IEEE80211 37 /* IEEE 802.11 protocol */
+#define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */
+#define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */
+#define AF_MAX 42
+/*
+ * When allocating a new AF_ constant, please only allocate
+ * even numbered constants for FreeBSD until 134 as odd numbered AF_
+ * constants 39-133 are now reserved for vendors.
+ */
+#define AF_VENDOR00 39
+#define AF_VENDOR01 41
+#define AF_VENDOR02 43
+#define AF_VENDOR03 45
+#define AF_VENDOR04 47
+#define AF_VENDOR05 49
+#define AF_VENDOR06 51
+#define AF_VENDOR07 53
+#define AF_VENDOR08 55
+#define AF_VENDOR09 57
+#define AF_VENDOR10 59
+#define AF_VENDOR11 61
+#define AF_VENDOR12 63
+#define AF_VENDOR13 65
+#define AF_VENDOR14 67
+#define AF_VENDOR15 69
+#define AF_VENDOR16 71
+#define AF_VENDOR17 73
+#define AF_VENDOR18 75
+#define AF_VENDOR19 77
+#define AF_VENDOR20 79
+#define AF_VENDOR21 81
+#define AF_VENDOR22 83
+#define AF_VENDOR23 85
+#define AF_VENDOR24 87
+#define AF_VENDOR25 89
+#define AF_VENDOR26 91
+#define AF_VENDOR27 93
+#define AF_VENDOR28 95
+#define AF_VENDOR29 97
+#define AF_VENDOR30 99
+#define AF_VENDOR31 101
+#define AF_VENDOR32 103
+#define AF_VENDOR33 105
+#define AF_VENDOR34 107
+#define AF_VENDOR35 109
+#define AF_VENDOR36 111
+#define AF_VENDOR37 113
+#define AF_VENDOR38 115
+#define AF_VENDOR39 117
+#define AF_VENDOR40 119
+#define AF_VENDOR41 121
+#define AF_VENDOR42 123
+#define AF_VENDOR43 125
+#define AF_VENDOR44 127
+#define AF_VENDOR45 129
+#define AF_VENDOR46 131
+#define AF_VENDOR47 133
+#endif
+
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ unsigned char sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+#if __BSD_VISIBLE
+#define SOCK_MAXADDRLEN 255 /* longest possible addresses */
+
+/*
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ */
+struct sockproto {
+ unsigned short sp_family; /* address family */
+ unsigned short sp_protocol; /* protocol */
+};
+#endif
+
+#include <sys/_sockaddr_storage.h>
+
+#if __BSD_VISIBLE
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC AF_UNSPEC
+#define PF_LOCAL AF_LOCAL
+#define PF_UNIX PF_LOCAL /* backward compatibility */
+#define PF_INET AF_INET
+#define PF_IMPLINK AF_IMPLINK
+#define PF_PUP AF_PUP
+#define PF_CHAOS AF_CHAOS
+#define PF_NETBIOS AF_NETBIOS
+#define PF_ISO AF_ISO
+#define PF_OSI AF_ISO
+#define PF_ECMA AF_ECMA
+#define PF_DATAKIT AF_DATAKIT
+#define PF_CCITT AF_CCITT
+#define PF_SNA AF_SNA
+#define PF_DECnet AF_DECnet
+#define PF_DLI AF_DLI
+#define PF_LAT AF_LAT
+#define PF_HYLINK AF_HYLINK
+#define PF_APPLETALK AF_APPLETALK
+#define PF_ROUTE AF_ROUTE
+#define PF_LINK AF_LINK
+#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
+#define PF_COIP AF_COIP
+#define PF_CNT AF_CNT
+#define PF_SIP AF_SIP
+#define PF_IPX AF_IPX
+#define PF_RTIP pseudo_AF_RTIP /* same format as AF_INET */
+#define PF_PIP pseudo_AF_PIP
+#define PF_ISDN AF_ISDN
+#define PF_KEY pseudo_AF_KEY
+#define PF_INET6 AF_INET6
+#define PF_NATM AF_NATM
+#define PF_ATM AF_ATM
+#define PF_NETGRAPH AF_NETGRAPH
+#define PF_SLOW AF_SLOW
+#define PF_SCLUSTER AF_SCLUSTER
+#define PF_ARP AF_ARP
+#define PF_BLUETOOTH AF_BLUETOOTH
+#define PF_IEEE80211 AF_IEEE80211
+#define PF_INET_SDP AF_INET_SDP
+#define PF_INET6_SDP AF_INET6_SDP
+
+#define PF_MAX AF_MAX
+
+/*
+ * Definitions for network related sysctl, CTL_NET.
+ *
+ * Second level is protocol family.
+ * Third level is protocol number.
+ *
+ * Further levels are defined by the individual families.
+ */
+
+/*
+ * PF_ROUTE - Routing table
+ *
+ * Three additional levels are defined:
+ * Fourth: address family, 0 is wildcard
+ * Fifth: type of info, defined below
+ * Sixth: flag(s) to mask with for NET_RT_FLAGS
+ */
+#define NET_RT_DUMP 1 /* dump; may limit to a.f. */
+#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */
+#define NET_RT_IFLIST 3 /* survey interface list */
+#define NET_RT_IFMALIST 4 /* return multicast address list */
+#define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en
+ * versions of msghdr structs. */
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Maximum queue length specifiable by listen.
+ */
+#define SOMAXCONN 128
+
+/*
+ * Message header for recvmsg and sendmsg calls.
+ * Used value-result for recvmsg, value only for sendmsg.
+ */
+struct msghdr {
+ void *msg_name; /* optional address */
+ socklen_t msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ void *msg_control; /* ancillary data, see below */
+ socklen_t msg_controllen; /* ancillary data buffer len */
+ int msg_flags; /* flags on received message */
+};
+
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* send without using routing tables */
+#define MSG_EOR 0x8 /* data completes record */
+#define MSG_TRUNC 0x10 /* data discarded before delivery */
+#define MSG_CTRUNC 0x20 /* control data lost before delivery */
+#define MSG_WAITALL 0x40 /* wait for full request or error */
+#if __POSIX_VISIBLE >= 200809
+#define MSG_NOSIGNAL 0x20000 /* do not generate SIGPIPE on EOF */
+#endif
+#if __BSD_VISIBLE
+#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
+#define MSG_EOF 0x100 /* data completes connection */
+#define MSG_NOTIFICATION 0x2000 /* SCTP notification */
+#define MSG_NBIO 0x4000 /* FIONBIO mode, used by fifofs */
+#define MSG_COMPAT 0x8000 /* used in sendit() */
+#define MSG_CMSG_CLOEXEC 0x40000 /* make received fds close-on-exec */
+#define MSG_WAITFORONE 0x80000 /* for recvmmsg() */
+#endif
+#ifdef _KERNEL
+#define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */
+#endif
+
+/*
+ * Header for ancillary data objects in msg_control buffer.
+ * Used for additional information with/about a datagram
+ * not expressible by flags. The format is a sequence
+ * of message elements headed by cmsghdr structures.
+ */
+struct cmsghdr {
+ socklen_t cmsg_len; /* data byte count, including hdr */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+/* followed by u_char cmsg_data[]; */
+};
+
+#if __BSD_VISIBLE
+/*
+ * While we may have more groups than this, the cmsgcred struct must
+ * be able to fit in an mbuf and we have historically supported a
+ * maximum of 16 groups.
+*/
+#define CMGROUP_MAX 16
+
+/*
+ * Credentials structure, used to verify the identity of a peer
+ * process that has sent us a message. This is allocated by the
+ * peer process but filled in by the kernel. This prevents the
+ * peer from lying about its identity. (Note that cmcred_groups[0]
+ * is the effective GID.)
+ */
+struct cmsgcred {
+ pid_t cmcred_pid; /* PID of sending process */
+ uid_t cmcred_uid; /* real UID of sending process */
+ uid_t cmcred_euid; /* effective UID of sending process */
+ gid_t cmcred_gid; /* real GID of sending process */
+ short cmcred_ngroups; /* number or groups */
+ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
+};
+
+/*
+ * Socket credentials.
+ */
+struct sockcred {
+ uid_t sc_uid; /* real user id */
+ uid_t sc_euid; /* effective user id */
+ gid_t sc_gid; /* real group id */
+ gid_t sc_egid; /* effective group id */
+ int sc_ngroups; /* number of supplemental groups */
+ gid_t sc_groups[1]; /* variable length */
+};
+
+/*
+ * Compute size of a sockcred structure with groups.
+ */
+#define SOCKCREDSIZE(ngrps) \
+ (sizeof(struct sockcred) + (sizeof(gid_t) * ((ngrps) - 1)))
+
+#endif /* __BSD_VISIBLE */
+
+/* given pointer to struct cmsghdr, return pointer to data */
+#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \
+ _ALIGN(sizeof(struct cmsghdr)))
+
+/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ ((char *)(cmsg) == NULL ? CMSG_FIRSTHDR(mhdr) : \
+ ((char *)(cmsg) + _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len) + \
+ _ALIGN(sizeof(struct cmsghdr)) > \
+ (char *)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
+ (struct cmsghdr *)0 : \
+ (struct cmsghdr *)(void *)((char *)(cmsg) + \
+ _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len)))
+
+/*
+ * RFC 2292 requires to check msg_controllen, in case that the kernel returns
+ * an empty list for some reasons.
+ */
+#define CMSG_FIRSTHDR(mhdr) \
+ ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
+ (struct cmsghdr *)(mhdr)->msg_control : \
+ (struct cmsghdr *)NULL)
+
+#if __BSD_VISIBLE
+/* RFC 2292 additions */
+#define CMSG_SPACE(l) (_ALIGN(sizeof(struct cmsghdr)) + _ALIGN(l))
+#define CMSG_LEN(l) (_ALIGN(sizeof(struct cmsghdr)) + (l))
+#endif
+
+#ifdef _KERNEL
+#define CMSG_ALIGN(n) _ALIGN(n)
+#endif
+
+/* "Socket"-level control message types: */
+#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+#if __BSD_VISIBLE
+#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */
+#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */
+#define SCM_BINTIME 0x04 /* timestamp (struct bintime) */
+#endif
+
+#if __BSD_VISIBLE
+/*
+ * 4.3 compat sockaddr, move to compat file later
+ */
+struct osockaddr {
+ unsigned short sa_family; /* address family */
+ char sa_data[14]; /* up to 14 bytes of direct address */
+};
+
+/*
+ * 4.3-compat message header (move to compat file later).
+ */
+struct omsghdr {
+ char *msg_name; /* optional address */
+ int msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ char *msg_accrights; /* access rights sent/received */
+ int msg_accrightslen;
+};
+#endif
+
+/*
+ * howto arguments for shutdown(2), specified by Posix.1g.
+ */
+#define SHUT_RD 0 /* shut down the reading side */
+#define SHUT_WR 1 /* shut down the writing side */
+#define SHUT_RDWR 2 /* shut down both sides */
+
+#if __BSD_VISIBLE
+/* for SCTP */
+/* we cheat and use the SHUT_XX defines for these */
+#define PRU_FLUSH_RD SHUT_RD
+#define PRU_FLUSH_WR SHUT_WR
+#define PRU_FLUSH_RDWR SHUT_RDWR
+#endif
+
+
+#if __BSD_VISIBLE
+/*
+ * sendfile(2) header/trailer struct
+ */
+struct sf_hdtr {
+ struct iovec *headers; /* pointer to an array of header struct iovec's */
+ int hdr_cnt; /* number of header iovec's */
+ struct iovec *trailers; /* pointer to an array of trailer struct iovec's */
+ int trl_cnt; /* number of trailer iovec's */
+};
+
+/*
+ * Sendfile-specific flag(s)
+ */
+#define SF_NODISKIO 0x00000001
+#define SF_MNOWAIT 0x00000002 /* obsolete */
+#define SF_SYNC 0x00000004
+#define SF_NOCACHE 0x00000010
+#define SF_FLAGS(rh, flags) (((rh) << 16) | (flags))
+
+#ifdef _KERNEL
+#define SFK_COMPAT 0x00000001
+#define SF_READAHEAD(flags) ((flags) >> 16)
+#endif /* _KERNEL */
+
+/*
+ * Sendmmsg/recvmmsg specific structure(s)
+ */
+struct mmsghdr {
+ struct msghdr msg_hdr; /* message header */
+ ssize_t msg_len; /* message length */
+};
+#endif /* __BSD_VISIBLE */
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int accept(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int bind(int, const struct sockaddr *, socklen_t);
+int connect(int, const struct sockaddr *, socklen_t);
+#if __BSD_VISIBLE
+int accept4(int, struct sockaddr * __restrict, socklen_t * __restrict, int);
+int bindat(int, int, const struct sockaddr *, socklen_t);
+int connectat(int, int, const struct sockaddr *, socklen_t);
+#endif
+int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
+int listen(int, int);
+ssize_t recv(int, void *, size_t, int);
+ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
+ssize_t recvmsg(int, struct msghdr *, int);
+#if __BSD_VISIBLE
+struct timespec;
+ssize_t recvmmsg(int, struct mmsghdr * __restrict, size_t, int,
+ const struct timespec * __restrict);
+#endif
+ssize_t send(int, const void *, size_t, int);
+ssize_t sendto(int, const void *,
+ size_t, int, const struct sockaddr *, socklen_t);
+ssize_t sendmsg(int, const struct msghdr *, int);
+#if __BSD_VISIBLE
+int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
+ssize_t sendmmsg(int, struct mmsghdr * __restrict, size_t, int);
+int setfib(int);
+#endif
+int setsockopt(int, int, int, const void *, socklen_t);
+int shutdown(int, int);
+int sockatmark(int);
+int socket(int, int, int);
+int socketpair(int, int, int, int *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#ifdef _KERNEL
+struct socket;
+
+struct tcpcb *so_sototcpcb(struct socket *so);
+struct inpcb *so_sotoinpcb(struct socket *so);
+struct sockbuf *so_sockbuf_snd(struct socket *);
+struct sockbuf *so_sockbuf_rcv(struct socket *);
+
+int so_state_get(const struct socket *);
+void so_state_set(struct socket *, int);
+
+int so_options_get(const struct socket *);
+void so_options_set(struct socket *, int);
+
+int so_error_get(const struct socket *);
+void so_error_set(struct socket *, int);
+
+int so_linger_get(const struct socket *);
+void so_linger_set(struct socket *, int);
+
+struct protosw *so_protosw_get(const struct socket *);
+void so_protosw_set(struct socket *, struct protosw *);
+
+void so_sorwakeup_locked(struct socket *so);
+void so_sowwakeup_locked(struct socket *so);
+
+void so_sorwakeup(struct socket *so);
+void so_sowwakeup(struct socket *so);
+
+void so_lock(struct socket *so);
+void so_unlock(struct socket *so);
+
+void so_listeners_apply_all(struct socket *so, void (*func)(struct socket *, void *), void *arg);
+
+#endif
+
+
+#endif /* !_SYS_SOCKET_H_ */
diff --git a/usr/src/boot/sys/sys/stat.h b/usr/src/boot/sys/sys/stat.h
new file mode 100644
index 0000000000..7a4370d64a
--- /dev/null
+++ b/usr/src/boot/sys/sys/stat.h
@@ -0,0 +1,361 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)stat.h 8.12 (Berkeley) 6/16/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_STAT_H_
+#define _SYS_STAT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_timespec.h>
+#include <sys/_types.h>
+
+#ifndef _BLKSIZE_T_DECLARED
+typedef __blksize_t blksize_t;
+#define _BLKSIZE_T_DECLARED
+#endif
+
+#ifndef _BLKCNT_T_DECLARED
+typedef __blkcnt_t blkcnt_t;
+#define _BLKCNT_T_DECLARED
+#endif
+
+#ifndef _DEV_T_DECLARED
+typedef __dev_t dev_t;
+#define _DEV_T_DECLARED
+#endif
+
+#ifndef _FFLAGS_T_DECLARED
+typedef __fflags_t fflags_t;
+#define _FFLAGS_T_DECLARED
+#endif
+
+#ifndef _GID_T_DECLARED
+typedef __gid_t gid_t;
+#define _GID_T_DECLARED
+#endif
+
+#ifndef _INO_T_DECLARED
+typedef __ino_t ino_t;
+#define _INO_T_DECLARED
+#endif
+
+#ifndef _MODE_T_DECLARED
+typedef __mode_t mode_t;
+#define _MODE_T_DECLARED
+#endif
+
+#ifndef _NLINK_T_DECLARED
+typedef __nlink_t nlink_t;
+#define _NLINK_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
+#ifndef _UID_T_DECLARED
+typedef __uid_t uid_t;
+#define _UID_T_DECLARED
+#endif
+
+#if !defined(_KERNEL) && __BSD_VISIBLE
+/*
+ * XXX We get miscellaneous namespace pollution with this.
+ */
+#include <sys/time.h>
+#endif
+
+#ifdef _KERNEL
+struct ostat {
+ __uint16_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ mode_t st_mode; /* inode protection mode */
+ nlink_t st_nlink; /* number of hard links */
+ __uint16_t st_uid; /* user ID of the file's owner */
+ __uint16_t st_gid; /* group ID of the file's group */
+ __uint16_t st_rdev; /* device type */
+ __int32_t st_size; /* file size, in bytes */
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
+ __int32_t st_blksize; /* optimal blocksize for I/O */
+ __int32_t st_blocks; /* blocks allocated for file */
+ fflags_t st_flags; /* user defined flags for file */
+ __uint32_t st_gen; /* file generation number */
+};
+#endif
+
+struct stat {
+ __dev_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ mode_t st_mode; /* inode protection mode */
+ nlink_t st_nlink; /* number of hard links */
+ uid_t st_uid; /* user ID of the file's owner */
+ gid_t st_gid; /* group ID of the file's group */
+ __dev_t st_rdev; /* device type */
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
+ off_t st_size; /* file size, in bytes */
+ blkcnt_t st_blocks; /* blocks allocated for file */
+ blksize_t st_blksize; /* optimal blocksize for I/O */
+ fflags_t st_flags; /* user defined flags for file */
+ __uint32_t st_gen; /* file generation number */
+ __int32_t st_lspare;
+ struct timespec st_birthtim; /* time of file creation */
+ /*
+ * Explicitly pad st_birthtim to 16 bytes so that the size of
+ * struct stat is backwards compatible. We use bitfields instead
+ * of an array of chars so that this doesn't require a C99 compiler
+ * to compile if the size of the padding is 0. We use 2 bitfields
+ * to cover up to 64 bits on 32-bit machines. We assume that
+ * CHAR_BIT is 8...
+ */
+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
+};
+
+#ifdef _KERNEL
+struct nstat {
+ __dev_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ __uint32_t st_mode; /* inode protection mode */
+ __uint32_t st_nlink; /* number of hard links */
+ uid_t st_uid; /* user ID of the file's owner */
+ gid_t st_gid; /* group ID of the file's group */
+ __dev_t st_rdev; /* device type */
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
+ off_t st_size; /* file size, in bytes */
+ blkcnt_t st_blocks; /* blocks allocated for file */
+ blksize_t st_blksize; /* optimal blocksize for I/O */
+ fflags_t st_flags; /* user defined flags for file */
+ __uint32_t st_gen; /* file generation number */
+ struct timespec st_birthtim; /* time of file creation */
+ /*
+ * See above about the following padding.
+ */
+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
+};
+#endif
+
+#ifndef _KERNEL
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+#if __BSD_VISIBLE
+#define st_birthtime st_birthtim.tv_sec
+#endif
+
+/* For compatibility. */
+#if __BSD_VISIBLE
+#define st_atimespec st_atim
+#define st_mtimespec st_mtim
+#define st_ctimespec st_ctim
+#define st_birthtimespec st_birthtim
+#endif
+#endif /* !_KERNEL */
+
+#define S_ISUID 0004000 /* set user id on execution */
+#define S_ISGID 0002000 /* set group id on execution */
+#if __BSD_VISIBLE
+#define S_ISTXT 0001000 /* sticky bit */
+#endif
+
+#define S_IRWXU 0000700 /* RWX mask for owner */
+#define S_IRUSR 0000400 /* R for owner */
+#define S_IWUSR 0000200 /* W for owner */
+#define S_IXUSR 0000100 /* X for owner */
+
+#if __BSD_VISIBLE
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
+#define S_IRWXG 0000070 /* RWX mask for group */
+#define S_IRGRP 0000040 /* R for group */
+#define S_IWGRP 0000020 /* W for group */
+#define S_IXGRP 0000010 /* X for group */
+
+#define S_IRWXO 0000007 /* RWX mask for other */
+#define S_IROTH 0000004 /* R for other */
+#define S_IWOTH 0000002 /* W for other */
+#define S_IXOTH 0000001 /* X for other */
+
+#if __XSI_VISIBLE
+#define S_IFMT 0170000 /* type of file mask */
+#define S_IFIFO 0010000 /* named pipe (fifo) */
+#define S_IFCHR 0020000 /* character special */
+#define S_IFDIR 0040000 /* directory */
+#define S_IFBLK 0060000 /* block special */
+#define S_IFREG 0100000 /* regular */
+#define S_IFLNK 0120000 /* symbolic link */
+#define S_IFSOCK 0140000 /* socket */
+#define S_ISVTX 0001000 /* save swapped text even after use */
+#endif
+#if __BSD_VISIBLE
+#define S_IFWHT 0160000 /* whiteout */
+#endif
+
+#define S_ISDIR(m) (((m) & 0170000) == 0040000) /* directory */
+#define S_ISCHR(m) (((m) & 0170000) == 0020000) /* char special */
+#define S_ISBLK(m) (((m) & 0170000) == 0060000) /* block special */
+#define S_ISREG(m) (((m) & 0170000) == 0100000) /* regular file */
+#define S_ISFIFO(m) (((m) & 0170000) == 0010000) /* fifo or socket */
+#if __POSIX_VISIBLE >= 200112
+#define S_ISLNK(m) (((m) & 0170000) == 0120000) /* symbolic link */
+#define S_ISSOCK(m) (((m) & 0170000) == 0140000) /* socket */
+#endif
+#if __BSD_VISIBLE
+#define S_ISWHT(m) (((m) & 0170000) == 0160000) /* whiteout */
+#endif
+
+#if __BSD_VISIBLE
+#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */
+ /* 7777 */
+#define ALLPERMS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
+ /* 0666 */
+#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+
+#define S_BLKSIZE 512 /* block size used in the stat struct */
+
+/*
+ * Definitions of flags stored in file flags word.
+ *
+ * Super-user and owner changeable flags.
+ */
+#define UF_SETTABLE 0x0000ffff /* mask of owner changeable flags */
+#define UF_NODUMP 0x00000001 /* do not dump file */
+#define UF_IMMUTABLE 0x00000002 /* file may not be changed */
+#define UF_APPEND 0x00000004 /* writes to file may only append */
+#define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */
+#define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */
+/*
+ * These two bits are defined in MacOS X. They are not currently used in
+ * FreeBSD.
+ */
+#if 0
+#define UF_COMPRESSED 0x00000020 /* file is compressed */
+#define UF_TRACKED 0x00000040 /* renames and deletes are tracked */
+#endif
+
+#define UF_SYSTEM 0x00000080 /* Windows system file bit */
+#define UF_SPARSE 0x00000100 /* sparse file */
+#define UF_OFFLINE 0x00000200 /* file is offline */
+#define UF_REPARSE 0x00000400 /* Windows reparse point file bit */
+#define UF_ARCHIVE 0x00000800 /* file needs to be archived */
+#define UF_READONLY 0x00001000 /* Windows readonly file bit */
+/* This is the same as the MacOS X definition of UF_HIDDEN. */
+#define UF_HIDDEN 0x00008000 /* file is hidden */
+
+/*
+ * Super-user changeable flags.
+ */
+#define SF_SETTABLE 0xffff0000 /* mask of superuser changeable flags */
+#define SF_ARCHIVED 0x00010000 /* file is archived */
+#define SF_IMMUTABLE 0x00020000 /* file may not be changed */
+#define SF_APPEND 0x00040000 /* writes to file may only append */
+#define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */
+#define SF_SNAPSHOT 0x00200000 /* snapshot inode */
+
+#ifdef _KERNEL
+/*
+ * Shorthand abbreviations of above.
+ */
+#define OPAQUE (UF_OPAQUE)
+#define APPEND (UF_APPEND | SF_APPEND)
+#define IMMUTABLE (UF_IMMUTABLE | SF_IMMUTABLE)
+#define NOUNLINK (UF_NOUNLINK | SF_NOUNLINK)
+#endif
+
+#endif /* __BSD_VISIBLE */
+
+#if __POSIX_VISIBLE >= 200809
+#define UTIME_NOW -1
+#define UTIME_OMIT -2
+#endif
+
+#ifndef _KERNEL
+__BEGIN_DECLS
+#if __BSD_VISIBLE
+int chflags(const char *, unsigned long);
+int chflagsat(int, const char *, unsigned long, int);
+#endif
+int chmod(const char *, mode_t);
+#if __BSD_VISIBLE
+int fchflags(int, unsigned long);
+#endif
+#if __POSIX_VISIBLE >= 200112
+int fchmod(int, mode_t);
+#endif
+#if __POSIX_VISIBLE >= 200809
+int fchmodat(int, const char *, mode_t, int);
+int futimens(int fd, const struct timespec times[2]);
+int utimensat(int fd, const char *path, const struct timespec times[2],
+ int flag);
+#endif
+int fstat(int, struct stat *);
+#if __BSD_VISIBLE
+int lchflags(const char *, unsigned long);
+int lchmod(const char *, mode_t);
+#endif
+#if __POSIX_VISIBLE >= 200112
+int lstat(const char * __restrict, struct stat * __restrict);
+#endif
+int mkdir(const char *, mode_t);
+int mkfifo(const char *, mode_t);
+#if !defined(_MKNOD_DECLARED) && __XSI_VISIBLE
+int mknod(const char *, mode_t, dev_t);
+#define _MKNOD_DECLARED
+#endif
+int stat(const char * __restrict, struct stat * __restrict);
+mode_t umask(mode_t);
+#if __POSIX_VISIBLE >= 200809
+int fstatat(int, const char *, struct stat *, int);
+int mkdirat(int, const char *, mode_t);
+int mkfifoat(int, const char *, mode_t);
+#endif
+#if __XSI_VISIBLE >= 700
+int mknodat(int, const char *, mode_t, dev_t);
+#endif
+__END_DECLS
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_STAT_H_ */
diff --git a/usr/src/boot/sys/sys/stddef.h b/usr/src/boot/sys/sys/stddef.h
new file mode 100644
index 0000000000..15817444ae
--- /dev/null
+++ b/usr/src/boot/sys/sys/stddef.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2002 Maxime Henrion <mux@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_STDDEF_H_
+#define _SYS_STDDEF_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <machine/_types.h>
+
+#ifndef _PTRDIFF_T_DECLARED
+typedef __ptrdiff_t ptrdiff_t;
+#define _PTRDIFF_T_DECLARED
+#endif
+
+#define offsetof(type, field) __offsetof(type, field)
+
+#endif /* !_SYS_STDDEF_H_ */
diff --git a/usr/src/boot/sys/sys/stdint.h b/usr/src/boot/sys/sys/stdint.h
new file mode 100644
index 0000000000..ec3698be88
--- /dev/null
+++ b/usr/src/boot/sys/sys/stdint.h
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_STDINT_H_
+#define _SYS_STDINT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#include <machine/_stdint.h>
+#include <sys/_stdint.h>
+
+typedef __int_least8_t int_least8_t;
+typedef __int_least16_t int_least16_t;
+typedef __int_least32_t int_least32_t;
+typedef __int_least64_t int_least64_t;
+
+typedef __uint_least8_t uint_least8_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __uint_least64_t uint_least64_t;
+
+typedef __int_fast8_t int_fast8_t;
+typedef __int_fast16_t int_fast16_t;
+typedef __int_fast32_t int_fast32_t;
+typedef __int_fast64_t int_fast64_t;
+
+typedef __uint_fast8_t uint_fast8_t;
+typedef __uint_fast16_t uint_fast16_t;
+typedef __uint_fast32_t uint_fast32_t;
+typedef __uint_fast64_t uint_fast64_t;
+
+/* GNU and Darwin define this and people seem to think it's portable */
+#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX)
+#define __WORDSIZE 64
+#else
+#define __WORDSIZE 32
+#endif
+
+/* Limits of wchar_t. */
+#define WCHAR_MIN __WCHAR_MIN
+#define WCHAR_MAX __WCHAR_MAX
+
+#endif /* !_SYS_STDINT_H_ */
diff --git a/usr/src/boot/sys/sys/syslimits.h b/usr/src/boot/sys/sys/syslimits.h
new file mode 100644
index 0000000000..c38648f58f
--- /dev/null
+++ b/usr/src/boot/sys/sys/syslimits.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)syslimits.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SYSLIMITS_H_
+#define _SYS_SYSLIMITS_H_
+
+#if !defined(_KERNEL) && !defined(_LIMITS_H_) && !defined(_SYS_PARAM_H_)
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+#ifdef __CC_SUPPORTS_WARNING
+#warning "No user-serviceable parts inside."
+#endif
+#endif
+
+/*
+ * Do not add any new variables here. (See the comment at the end of
+ * the file for why.)
+ */
+#define ARG_MAX 262144 /* max bytes for an exec function */
+#ifndef CHILD_MAX
+#define CHILD_MAX 40 /* max simultaneous processes */
+#endif
+#define LINK_MAX 32767 /* max file link count */
+#define MAX_CANON 255 /* max bytes in term canon input line */
+#define MAX_INPUT 255 /* max bytes in terminal input */
+#define NAME_MAX 255 /* max bytes in a file name */
+#ifndef NGROUPS_MAX
+#define NGROUPS_MAX 1023 /* max supplemental group id's */
+#endif
+#ifndef OPEN_MAX
+#define OPEN_MAX 64 /* max open files per process */
+#endif
+#define PATH_MAX 1024 /* max bytes in pathname */
+#define PIPE_BUF 512 /* max bytes for atomic pipe writes */
+#define IOV_MAX 1024 /* max elements in i/o vector */
+
+/*
+ * We leave the following values undefined to force applications to either
+ * assume conservative values or call sysconf() to get the current value.
+ *
+ * HOST_NAME_MAX
+ *
+ * (We should do this for most of the values currently defined here,
+ * but many programs are not prepared to deal with this yet.)
+ */
+#endif
diff --git a/usr/src/boot/sys/sys/time.h b/usr/src/boot/sys/sys/time.h
new file mode 100644
index 0000000000..395e8886a6
--- /dev/null
+++ b/usr/src/boot/sys/sys/time.h
@@ -0,0 +1,498 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)time.h 8.5 (Berkeley) 5/4/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <sys/_timeval.h>
+#include <sys/types.h>
+#include <sys/timespec.h>
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+
+#if __BSD_VISIBLE
+struct bintime {
+ time_t sec;
+ uint64_t frac;
+};
+
+static __inline void
+bintime_addx(struct bintime *_bt, uint64_t _x)
+{
+ uint64_t _u;
+
+ _u = _bt->frac;
+ _bt->frac += _x;
+ if (_u > _bt->frac)
+ _bt->sec++;
+}
+
+static __inline void
+bintime_add(struct bintime *_bt, const struct bintime *_bt2)
+{
+ uint64_t _u;
+
+ _u = _bt->frac;
+ _bt->frac += _bt2->frac;
+ if (_u > _bt->frac)
+ _bt->sec++;
+ _bt->sec += _bt2->sec;
+}
+
+static __inline void
+bintime_sub(struct bintime *_bt, const struct bintime *_bt2)
+{
+ uint64_t _u;
+
+ _u = _bt->frac;
+ _bt->frac -= _bt2->frac;
+ if (_u < _bt->frac)
+ _bt->sec--;
+ _bt->sec -= _bt2->sec;
+}
+
+static __inline void
+bintime_mul(struct bintime *_bt, u_int _x)
+{
+ uint64_t _p1, _p2;
+
+ _p1 = (_bt->frac & 0xffffffffull) * _x;
+ _p2 = (_bt->frac >> 32) * _x + (_p1 >> 32);
+ _bt->sec *= _x;
+ _bt->sec += (_p2 >> 32);
+ _bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull);
+}
+
+static __inline void
+bintime_shift(struct bintime *_bt, int _exp)
+{
+
+ if (_exp > 0) {
+ _bt->sec <<= _exp;
+ _bt->sec |= _bt->frac >> (64 - _exp);
+ _bt->frac <<= _exp;
+ } else if (_exp < 0) {
+ _bt->frac >>= -_exp;
+ _bt->frac |= (uint64_t)_bt->sec << (64 + _exp);
+ _bt->sec >>= -_exp;
+ }
+}
+
+#define bintime_clear(a) ((a)->sec = (a)->frac = 0)
+#define bintime_isset(a) ((a)->sec || (a)->frac)
+#define bintime_cmp(a, b, cmp) \
+ (((a)->sec == (b)->sec) ? \
+ ((a)->frac cmp (b)->frac) : \
+ ((a)->sec cmp (b)->sec))
+
+#define SBT_1S ((sbintime_t)1 << 32)
+#define SBT_1M (SBT_1S * 60)
+#define SBT_1MS (SBT_1S / 1000)
+#define SBT_1US (SBT_1S / 1000000)
+#define SBT_1NS (SBT_1S / 1000000000)
+#define SBT_MAX 0x7fffffffffffffffLL
+
+static __inline int
+sbintime_getsec(sbintime_t _sbt)
+{
+
+ return (_sbt >> 32);
+}
+
+static __inline sbintime_t
+bttosbt(const struct bintime _bt)
+{
+
+ return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32));
+}
+
+static __inline struct bintime
+sbttobt(sbintime_t _sbt)
+{
+ struct bintime _bt;
+
+ _bt.sec = _sbt >> 32;
+ _bt.frac = _sbt << 32;
+ return (_bt);
+}
+
+/*-
+ * Background information:
+ *
+ * When converting between timestamps on parallel timescales of differing
+ * resolutions it is historical and scientific practice to round down rather
+ * than doing 4/5 rounding.
+ *
+ * The date changes at midnight, not at noon.
+ *
+ * Even at 15:59:59.999999999 it's not four'o'clock.
+ *
+ * time_second ticks after N.999999999 not after N.4999999999
+ */
+
+static __inline void
+bintime2timespec(const struct bintime *_bt, struct timespec *_ts)
+{
+
+ _ts->tv_sec = _bt->sec;
+ _ts->tv_nsec = ((uint64_t)1000000000 *
+ (uint32_t)(_bt->frac >> 32)) >> 32;
+}
+
+static __inline void
+timespec2bintime(const struct timespec *_ts, struct bintime *_bt)
+{
+
+ _bt->sec = _ts->tv_sec;
+ /* 18446744073 = int(2^64 / 1000000000) */
+ _bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL;
+}
+
+static __inline void
+bintime2timeval(const struct bintime *_bt, struct timeval *_tv)
+{
+
+ _tv->tv_sec = _bt->sec;
+ _tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32;
+}
+
+static __inline void
+timeval2bintime(const struct timeval *_tv, struct bintime *_bt)
+{
+
+ _bt->sec = _tv->tv_sec;
+ /* 18446744073709 = int(2^64 / 1000000) */
+ _bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL;
+}
+
+static __inline struct timespec
+sbttots(sbintime_t _sbt)
+{
+ struct timespec _ts;
+
+ _ts.tv_sec = _sbt >> 32;
+ _ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32;
+ return (_ts);
+}
+
+static __inline sbintime_t
+tstosbt(struct timespec _ts)
+{
+
+ return (((sbintime_t)_ts.tv_sec << 32) +
+ (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32));
+}
+
+static __inline struct timeval
+sbttotv(sbintime_t _sbt)
+{
+ struct timeval _tv;
+
+ _tv.tv_sec = _sbt >> 32;
+ _tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32;
+ return (_tv);
+}
+
+static __inline sbintime_t
+tvtosbt(struct timeval _tv)
+{
+
+ return (((sbintime_t)_tv.tv_sec << 32) +
+ (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32));
+}
+#endif /* __BSD_VISIBLE */
+
+#ifdef _KERNEL
+
+/* Operations on timespecs */
+#define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0)
+#define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec)
+#define timespeccmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
+ ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec))
+#define timespecadd(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec += (uvp)->tv_sec; \
+ (vvp)->tv_nsec += (uvp)->tv_nsec; \
+ if ((vvp)->tv_nsec >= 1000000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_nsec -= 1000000000; \
+ } \
+ } while (0)
+#define timespecsub(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec -= (uvp)->tv_sec; \
+ (vvp)->tv_nsec -= (uvp)->tv_nsec; \
+ if ((vvp)->tv_nsec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_nsec += 1000000000; \
+ } \
+ } while (0)
+
+/* Operations on timevals. */
+
+#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+#define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timevalcmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
+ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec))
+
+/* timevaladd and timevalsub are not inlined */
+
+#endif /* _KERNEL */
+
+#ifndef _KERNEL /* NetBSD/OpenBSD compatible interfaces */
+
+#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
+ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec))
+#define timeradd(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+/*
+ * Getkerninfo clock information structure
+ */
+struct clockinfo {
+ int hz; /* clock frequency */
+ int tick; /* micro-seconds per hz tick */
+ int spare;
+ int stathz; /* statistics clock frequency */
+ int profhz; /* profiling clock frequency */
+};
+
+/* These macros are also in time.h. */
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+#define CLOCK_VIRTUAL 1
+#define CLOCK_PROF 2
+#define CLOCK_MONOTONIC 4
+#define CLOCK_UPTIME 5 /* FreeBSD-specific. */
+#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */
+#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */
+#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */
+#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */
+#define CLOCK_SECOND 13 /* FreeBSD-specific. */
+#define CLOCK_THREAD_CPUTIME_ID 14
+#define CLOCK_PROCESS_CPUTIME_ID 15
+#endif
+
+#ifndef TIMER_ABSTIME
+#define TIMER_RELTIME 0x0 /* relative timer */
+#define TIMER_ABSTIME 0x1 /* absolute timer */
+#endif
+
+#if __BSD_VISIBLE
+#define CPUCLOCK_WHICH_PID 0
+#define CPUCLOCK_WHICH_TID 1
+#endif
+
+#ifdef _KERNEL
+
+/*
+ * Kernel to clock driver interface.
+ */
+void inittodr(time_t base);
+void resettodr(void);
+
+extern volatile time_t time_second;
+extern volatile time_t time_uptime;
+extern struct bintime boottimebin;
+extern struct timeval boottime;
+extern struct bintime tc_tick_bt;
+extern sbintime_t tc_tick_sbt;
+extern struct bintime tick_bt;
+extern sbintime_t tick_sbt;
+extern int tc_precexp;
+extern int tc_timepercentage;
+extern struct bintime bt_timethreshold;
+extern struct bintime bt_tickthreshold;
+extern sbintime_t sbt_timethreshold;
+extern sbintime_t sbt_tickthreshold;
+
+/*
+ * Functions for looking at our clock: [get]{bin,nano,micro}[up]time()
+ *
+ * Functions without the "get" prefix returns the best timestamp
+ * we can produce in the given format.
+ *
+ * "bin" == struct bintime == seconds + 64 bit fraction of seconds.
+ * "nano" == struct timespec == seconds + nanoseconds.
+ * "micro" == struct timeval == seconds + microseconds.
+ *
+ * Functions containing "up" returns time relative to boot and
+ * should be used for calculating time intervals.
+ *
+ * Functions without "up" returns UTC time.
+ *
+ * Functions with the "get" prefix returns a less precise result
+ * much faster than the functions without "get" prefix and should
+ * be used where a precision of 1/hz seconds is acceptable or where
+ * performance is priority. (NB: "precision", _not_ "resolution" !)
+ */
+
+void binuptime(struct bintime *bt);
+void nanouptime(struct timespec *tsp);
+void microuptime(struct timeval *tvp);
+
+static __inline sbintime_t
+sbinuptime(void)
+{
+ struct bintime _bt;
+
+ binuptime(&_bt);
+ return (bttosbt(_bt));
+}
+
+void bintime(struct bintime *bt);
+void nanotime(struct timespec *tsp);
+void microtime(struct timeval *tvp);
+
+void getbinuptime(struct bintime *bt);
+void getnanouptime(struct timespec *tsp);
+void getmicrouptime(struct timeval *tvp);
+
+static __inline sbintime_t
+getsbinuptime(void)
+{
+ struct bintime _bt;
+
+ getbinuptime(&_bt);
+ return (bttosbt(_bt));
+}
+
+void getbintime(struct bintime *bt);
+void getnanotime(struct timespec *tsp);
+void getmicrotime(struct timeval *tvp);
+
+/* Other functions */
+int itimerdecr(struct itimerval *itp, int usec);
+int itimerfix(struct timeval *tv);
+int ppsratecheck(struct timeval *, int *, int);
+int ratecheck(struct timeval *, const struct timeval *);
+void timevaladd(struct timeval *t1, const struct timeval *t2);
+void timevalsub(struct timeval *t1, const struct timeval *t2);
+int tvtohz(struct timeval *tv);
+
+#define TC_DEFAULTPERC 5
+
+#define BT2FREQ(bt) \
+ (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \
+ ((bt)->frac >> 1))
+
+#define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt))
+
+#define FREQ2BT(freq, bt) \
+{ \
+ (bt)->sec = 0; \
+ (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \
+}
+
+#define TIMESEL(sbt, sbt2) \
+ (((sbt2) >= sbt_timethreshold) ? \
+ ((*(sbt) = getsbinuptime()), 1) : ((*(sbt) = sbinuptime()), 0))
+
+#else /* !_KERNEL */
+#include <time.h>
+
+#include <sys/cdefs.h>
+#include <sys/select.h>
+
+__BEGIN_DECLS
+int setitimer(int, const struct itimerval *, struct itimerval *);
+int utimes(const char *, const struct timeval *);
+
+#if __BSD_VISIBLE
+int adjtime(const struct timeval *, struct timeval *);
+int clock_getcpuclockid2(id_t, int, clockid_t *);
+int futimes(int, const struct timeval *);
+int futimesat(int, const char *, const struct timeval [2]);
+int lutimes(const char *, const struct timeval *);
+int settimeofday(const struct timeval *, const struct timezone *);
+#endif
+
+#if __XSI_VISIBLE
+int getitimer(int, struct itimerval *);
+int gettimeofday(struct timeval *, struct timezone *);
+#endif
+
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_TIME_H_ */
diff --git a/usr/src/boot/sys/sys/timespec.h b/usr/src/boot/sys/sys/timespec.h
new file mode 100644
index 0000000000..2505cef893
--- /dev/null
+++ b/usr/src/boot/sys/sys/timespec.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)time.h 8.5 (Berkeley) 5/4/95
+ * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TIMESPEC_H_
+#define _SYS_TIMESPEC_H_
+
+#include <sys/cdefs.h>
+#include <sys/_timespec.h>
+
+#if __BSD_VISIBLE
+#define TIMEVAL_TO_TIMESPEC(tv, ts) \
+ do { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+ } while (0)
+#define TIMESPEC_TO_TIMEVAL(tv, ts) \
+ do { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+ } while (0)
+
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Structure defined by POSIX.1b to be like a itimerval, but with
+ * timespecs. Used in the timer_*() system calls.
+ */
+struct itimerspec {
+ struct timespec it_interval;
+ struct timespec it_value;
+};
+
+#endif /* _SYS_TIMESPEC_H_ */
diff --git a/usr/src/boot/sys/sys/types.h b/usr/src/boot/sys/sys/types.h
new file mode 100644
index 0000000000..579b104924
--- /dev/null
+++ b/usr/src/boot/sys/sys/types.h
@@ -0,0 +1,399 @@
+/*-
+ * Copyright (c) 1982, 1986, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)types.h 8.6 (Berkeley) 2/19/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TYPES_H_
+#define _SYS_TYPES_H_
+
+#include <sys/cdefs.h>
+
+/* Machine type dependent parameters. */
+#include <machine/endian.h>
+#include <sys/_types.h>
+
+#include <sys/_pthreadtypes.h>
+
+#if __BSD_VISIBLE
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+#ifndef _KERNEL
+typedef unsigned short ushort; /* Sys V compatibility */
+typedef unsigned int uint; /* Sys V compatibility */
+#endif
+#endif
+
+/*
+ * XXX POSIX sized integrals that should appear only in <sys/stdint.h>.
+ */
+#include <sys/_stdint.h>
+
+typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */
+typedef __uint16_t u_int16_t;
+typedef __uint32_t u_int32_t;
+typedef __uint64_t u_int64_t;
+
+typedef __uint64_t u_quad_t; /* quads (deprecated) */
+typedef __int64_t quad_t;
+typedef quad_t * qaddr_t;
+
+typedef char * caddr_t; /* core address */
+typedef const char * c_caddr_t; /* core address, pointer to const */
+
+#ifndef _BLKSIZE_T_DECLARED
+typedef __blksize_t blksize_t;
+#define _BLKSIZE_T_DECLARED
+#endif
+
+typedef __cpuwhich_t cpuwhich_t;
+typedef __cpulevel_t cpulevel_t;
+typedef __cpusetid_t cpusetid_t;
+
+#ifndef _BLKCNT_T_DECLARED
+typedef __blkcnt_t blkcnt_t;
+#define _BLKCNT_T_DECLARED
+#endif
+
+#ifndef _CLOCK_T_DECLARED
+typedef __clock_t clock_t;
+#define _CLOCK_T_DECLARED
+#endif
+
+#ifndef _CLOCKID_T_DECLARED
+typedef __clockid_t clockid_t;
+#define _CLOCKID_T_DECLARED
+#endif
+
+typedef __critical_t critical_t; /* Critical section value */
+typedef __int64_t daddr_t; /* disk address */
+
+#ifndef _DEV_T_DECLARED
+typedef __dev_t dev_t; /* device number or struct cdev */
+#define _DEV_T_DECLARED
+#endif
+
+#ifndef _FFLAGS_T_DECLARED
+typedef __fflags_t fflags_t; /* file flags */
+#define _FFLAGS_T_DECLARED
+#endif
+
+typedef __fixpt_t fixpt_t; /* fixed point number */
+
+#ifndef _FSBLKCNT_T_DECLARED /* for statvfs() */
+typedef __fsblkcnt_t fsblkcnt_t;
+typedef __fsfilcnt_t fsfilcnt_t;
+#define _FSBLKCNT_T_DECLARED
+#endif
+
+#ifndef _GID_T_DECLARED
+typedef __gid_t gid_t; /* group id */
+#define _GID_T_DECLARED
+#endif
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef __uint32_t in_addr_t; /* base type for internet address */
+#define _IN_ADDR_T_DECLARED
+#endif
+
+#ifndef _IN_PORT_T_DECLARED
+typedef __uint16_t in_port_t;
+#define _IN_PORT_T_DECLARED
+#endif
+
+#ifndef _ID_T_DECLARED
+typedef __id_t id_t; /* can hold a uid_t or pid_t */
+#define _ID_T_DECLARED
+#endif
+
+#ifndef _INO_T_DECLARED
+typedef __ino_t ino_t; /* inode number */
+#define _INO_T_DECLARED
+#endif
+
+#ifndef _KEY_T_DECLARED
+typedef __key_t key_t; /* IPC key (for Sys V IPC) */
+#define _KEY_T_DECLARED
+#endif
+
+#ifndef _LWPID_T_DECLARED
+typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */
+#define _LWPID_T_DECLARED
+#endif
+
+#ifndef _MODE_T_DECLARED
+typedef __mode_t mode_t; /* permissions */
+#define _MODE_T_DECLARED
+#endif
+
+#ifndef _ACCMODE_T_DECLARED
+typedef __accmode_t accmode_t; /* access permissions */
+#define _ACCMODE_T_DECLARED
+#endif
+
+#ifndef _NLINK_T_DECLARED
+typedef __nlink_t nlink_t; /* link count */
+#define _NLINK_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t; /* file offset */
+#define _OFF_T_DECLARED
+#endif
+
+#ifndef _PID_T_DECLARED
+typedef __pid_t pid_t; /* process id */
+#define _PID_T_DECLARED
+#endif
+
+typedef __register_t register_t;
+
+#ifndef _RLIM_T_DECLARED
+typedef __rlim_t rlim_t; /* resource limit */
+#define _RLIM_T_DECLARED
+#endif
+
+typedef __int64_t sbintime_t;
+
+typedef __segsz_t segsz_t; /* segment size (in pages) */
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+#ifndef _SSIZE_T_DECLARED
+typedef __ssize_t ssize_t;
+#define _SSIZE_T_DECLARED
+#endif
+
+#ifndef _SUSECONDS_T_DECLARED
+typedef __suseconds_t suseconds_t; /* microseconds (signed) */
+#define _SUSECONDS_T_DECLARED
+#endif
+
+#ifndef _TIME_T_DECLARED
+typedef __time_t time_t;
+#define _TIME_T_DECLARED
+#endif
+
+#ifndef _TIMER_T_DECLARED
+typedef __timer_t timer_t;
+#define _TIMER_T_DECLARED
+#endif
+
+#ifndef _MQD_T_DECLARED
+typedef __mqd_t mqd_t;
+#define _MQD_T_DECLARED
+#endif
+
+typedef __u_register_t u_register_t;
+
+#ifndef _UID_T_DECLARED
+typedef __uid_t uid_t; /* user id */
+#define _UID_T_DECLARED
+#endif
+
+#ifndef _USECONDS_T_DECLARED
+typedef __useconds_t useconds_t; /* microseconds (unsigned) */
+#define _USECONDS_T_DECLARED
+#endif
+
+#ifndef _CAP_IOCTL_T_DECLARED
+#define _CAP_IOCTL_T_DECLARED
+typedef unsigned long cap_ioctl_t;
+#endif
+
+#ifndef _CAP_RIGHTS_T_DECLARED
+#define _CAP_RIGHTS_T_DECLARED
+struct cap_rights;
+
+typedef struct cap_rights cap_rights_t;
+#endif
+
+typedef __vm_offset_t vm_offset_t;
+typedef __vm_ooffset_t vm_ooffset_t;
+typedef __vm_paddr_t vm_paddr_t;
+typedef __vm_pindex_t vm_pindex_t;
+typedef __vm_size_t vm_size_t;
+
+typedef __rman_res_t rman_res_t;
+
+#ifdef _KERNEL
+typedef int boolean_t;
+typedef struct device *device_t;
+typedef __intfptr_t intfptr_t;
+
+/*
+ * XXX this is fixed width for historical reasons. It should have had type
+ * __int_fast32_t. Fixed-width types should not be used unless binary
+ * compatibility is essential. Least-width types should be used even less
+ * since they provide smaller benefits.
+ *
+ * XXX should be MD.
+ *
+ * XXX this is bogus in -current, but still used for spl*().
+ */
+typedef __uint32_t intrmask_t; /* Interrupt mask (spl, xxx_imask...) */
+
+typedef __uintfptr_t uintfptr_t;
+typedef __uint64_t uoff_t;
+typedef char vm_memattr_t; /* memory attribute codes */
+typedef struct vm_page *vm_page_t;
+
+#if !defined(__bool_true_false_are_defined) && !defined(__cplusplus)
+#define __bool_true_false_are_defined 1
+#define false 0
+#define true 1
+#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER)
+typedef int _Bool;
+#endif
+typedef _Bool bool;
+#endif /* !__bool_true_false_are_defined && !__cplusplus */
+
+#define offsetof(type, field) __offsetof(type, field)
+
+#endif /* !_KERNEL */
+
+/*
+ * The following are all things that really shouldn't exist in this header,
+ * since its purpose is to provide typedefs, not miscellaneous doodads.
+ */
+
+#ifdef __POPCNT__
+#define __bitcount64(x) __builtin_popcountll((__uint64_t)(x))
+#define __bitcount32(x) __builtin_popcount((__uint32_t)(x))
+#define __bitcount16(x) __builtin_popcount((__uint16_t)(x))
+#define __bitcountl(x) __builtin_popcountl((unsigned long)(x))
+#define __bitcount(x) __builtin_popcount((unsigned int)(x))
+#else
+/*
+ * Population count algorithm using SWAR approach
+ * - "SIMD Within A Register".
+ */
+static __inline __uint16_t
+__bitcount16(__uint16_t _x)
+{
+
+ _x = (_x & 0x5555) + ((_x & 0xaaaa) >> 1);
+ _x = (_x & 0x3333) + ((_x & 0xcccc) >> 2);
+ _x = (_x + (_x >> 4)) & 0x0f0f;
+ _x = (_x + (_x >> 8)) & 0x00ff;
+ return (_x);
+}
+
+static __inline __uint32_t
+__bitcount32(__uint32_t _x)
+{
+
+ _x = (_x & 0x55555555) + ((_x & 0xaaaaaaaa) >> 1);
+ _x = (_x & 0x33333333) + ((_x & 0xcccccccc) >> 2);
+ _x = (_x + (_x >> 4)) & 0x0f0f0f0f;
+ _x = (_x + (_x >> 8));
+ _x = (_x + (_x >> 16)) & 0x000000ff;
+ return (_x);
+}
+
+#ifdef __LP64__
+static __inline __uint64_t
+__bitcount64(__uint64_t _x)
+{
+
+ _x = (_x & 0x5555555555555555) + ((_x & 0xaaaaaaaaaaaaaaaa) >> 1);
+ _x = (_x & 0x3333333333333333) + ((_x & 0xcccccccccccccccc) >> 2);
+ _x = (_x + (_x >> 4)) & 0x0f0f0f0f0f0f0f0f;
+ _x = (_x + (_x >> 8));
+ _x = (_x + (_x >> 16));
+ _x = (_x + (_x >> 32)) & 0x000000ff;
+ return (_x);
+}
+
+#define __bitcountl(x) __bitcount64((unsigned long)(x))
+#else
+static __inline __uint64_t
+__bitcount64(__uint64_t _x)
+{
+
+ return (__bitcount32(_x >> 32) + __bitcount32(_x));
+}
+
+#define __bitcountl(x) __bitcount32((unsigned long)(x))
+#endif
+#define __bitcount(x) __bitcount32((unsigned int)(x))
+#endif
+
+#if __BSD_VISIBLE
+
+#include <sys/select.h>
+
+/*
+ * minor() gives a cookie instead of an index since we don't want to
+ * change the meanings of bits 0-15 or waste time and space shifting
+ * bits 16-31 for devices that don't use them.
+ */
+#define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
+#define minor(x) ((int)((x)&0xffff00ff)) /* minor number */
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) /* create dev_t */
+
+/*
+ * These declarations belong elsewhere, but are repeated here and in
+ * <stdio.h> to give broken programs a better chance of working with
+ * 64-bit off_t's.
+ */
+#ifndef _KERNEL
+__BEGIN_DECLS
+#ifndef _FTRUNCATE_DECLARED
+#define _FTRUNCATE_DECLARED
+int ftruncate(int, off_t);
+#endif
+#ifndef _LSEEK_DECLARED
+#define _LSEEK_DECLARED
+off_t lseek(int, off_t, int);
+#endif
+#ifndef _MMAP_DECLARED
+#define _MMAP_DECLARED
+void * mmap(void *, size_t, int, int, int, off_t);
+#endif
+#ifndef _TRUNCATE_DECLARED
+#define _TRUNCATE_DECLARED
+int truncate(const char *, off_t);
+#endif
+__END_DECLS
+#endif /* !_KERNEL */
+
+#endif /* __BSD_VISIBLE */
+
+#endif /* !_SYS_TYPES_H_ */
diff --git a/usr/src/boot/sys/sys/ucred.h b/usr/src/boot/sys/sys/ucred.h
new file mode 100644
index 0000000000..8dbf2fef74
--- /dev/null
+++ b/usr/src/boot/sys/sys/ucred.h
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)ucred.h 8.4 (Berkeley) 1/9/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_UCRED_H_
+#define _SYS_UCRED_H_
+
+#include <bsm/audit.h>
+
+struct loginclass;
+
+#define XU_NGROUPS 16
+
+/*
+ * Credentials.
+ *
+ * Please do not inspect cr_uid directly to determine superuserness. The
+ * priv(9) interface should be used to check for privilege.
+ */
+#if defined(_KERNEL) || defined(_WANT_UCRED)
+struct ucred {
+ u_int cr_ref; /* reference count */
+#define cr_startcopy cr_uid
+ uid_t cr_uid; /* effective user id */
+ uid_t cr_ruid; /* real user id */
+ uid_t cr_svuid; /* saved user id */
+ int cr_ngroups; /* number of groups */
+ gid_t cr_rgid; /* real group id */
+ gid_t cr_svgid; /* saved group id */
+ struct uidinfo *cr_uidinfo; /* per euid resource consumption */
+ struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */
+ struct prison *cr_prison; /* jail(2) */
+ struct loginclass *cr_loginclass; /* login class */
+ u_int cr_flags; /* credential flags */
+ void *cr_pspare2[2]; /* general use 2 */
+#define cr_endcopy cr_label
+ struct label *cr_label; /* MAC label */
+ struct auditinfo_addr cr_audit; /* Audit properties. */
+ gid_t *cr_groups; /* groups */
+ int cr_agroups; /* Available groups */
+ gid_t cr_smallgroups[XU_NGROUPS]; /* storage for small groups */
+};
+#define NOCRED ((struct ucred *)0) /* no credential available */
+#define FSCRED ((struct ucred *)-1) /* filesystem credential */
+#endif /* _KERNEL || _WANT_UCRED */
+
+/*
+ * Flags for cr_flags.
+ */
+#define CRED_FLAG_CAPMODE 0x00000001 /* In capability mode. */
+
+/*
+ * This is the external representation of struct ucred.
+ */
+struct xucred {
+ u_int cr_version; /* structure layout version */
+ uid_t cr_uid; /* effective user id */
+ short cr_ngroups; /* number of groups */
+ gid_t cr_groups[XU_NGROUPS]; /* groups */
+ void *_cr_unused1; /* compatibility with old ucred */
+};
+#define XUCRED_VERSION 0
+
+/* This can be used for both ucred and xucred structures. */
+#define cr_gid cr_groups[0]
+
+#ifdef _KERNEL
+struct proc;
+struct thread;
+
+void change_egid(struct ucred *newcred, gid_t egid);
+void change_euid(struct ucred *newcred, struct uidinfo *euip);
+void change_rgid(struct ucred *newcred, gid_t rgid);
+void change_ruid(struct ucred *newcred, struct uidinfo *ruip);
+void change_svgid(struct ucred *newcred, gid_t svgid);
+void change_svuid(struct ucred *newcred, uid_t svuid);
+void crcopy(struct ucred *dest, struct ucred *src);
+struct ucred *crcopysafe(struct proc *p, struct ucred *cr);
+struct ucred *crdup(struct ucred *cr);
+void crextend(struct ucred *cr, int n);
+void proc_set_cred_init(struct proc *p, struct ucred *cr);
+struct ucred *proc_set_cred(struct proc *p, struct ucred *cr);
+void crfree(struct ucred *cr);
+struct ucred *crget(void);
+struct ucred *crhold(struct ucred *cr);
+void cru2x(struct ucred *cr, struct xucred *xcr);
+void crsetgroups(struct ucred *cr, int n, gid_t *groups);
+int groupmember(gid_t gid, struct ucred *cred);
+#endif /* _KERNEL */
+
+#endif /* !_SYS_UCRED_H_ */
diff --git a/usr/src/boot/sys/sys/unistd.h b/usr/src/boot/sys/sys/unistd.h
new file mode 100644
index 0000000000..d6d92ab319
--- /dev/null
+++ b/usr/src/boot/sys/sys/unistd.h
@@ -0,0 +1,197 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)unistd.h 8.2 (Berkeley) 1/7/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_UNISTD_H_
+#define _SYS_UNISTD_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * POSIX options and option groups we unconditionally do or don't
+ * implement. Those options which are implemented (or not) entirely
+ * in user mode are defined in <unistd.h>. Please keep this list in
+ * alphabetical order.
+ *
+ * Anything which is defined as zero below **must** have an
+ * implementation for the corresponding sysconf() which is able to
+ * determine conclusively whether or not the feature is supported.
+ * Anything which is defined as other than -1 below **must** have
+ * complete headers, types, and function declarations as specified by
+ * the POSIX standard; however, if the relevant sysconf() function
+ * returns -1, the functions may be stubbed out.
+ */
+#define _POSIX_ADVISORY_INFO 200112L
+#define _POSIX_ASYNCHRONOUS_IO 0
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_CLOCK_SELECTION (-1)
+#define _POSIX_CPUTIME 200112L
+#define _POSIX_FSYNC 200112L
+#define _POSIX_IPV6 0
+#define _POSIX_JOB_CONTROL 1
+#define _POSIX_MAPPED_FILES 200112L
+#define _POSIX_MEMLOCK (-1)
+#define _POSIX_MEMLOCK_RANGE 200112L
+#define _POSIX_MEMORY_PROTECTION 200112L
+#define _POSIX_MESSAGE_PASSING 200112L
+#define _POSIX_MONOTONIC_CLOCK 200112L
+#define _POSIX_NO_TRUNC 1
+#define _POSIX_PRIORITIZED_IO (-1)
+#define _POSIX_PRIORITY_SCHEDULING 200112L
+#define _POSIX_RAW_SOCKETS 200112L
+#define _POSIX_REALTIME_SIGNALS 200112L
+#define _POSIX_SEMAPHORES 200112L
+#define _POSIX_SHARED_MEMORY_OBJECTS 200112L
+#define _POSIX_SPORADIC_SERVER (-1)
+#define _POSIX_SYNCHRONIZED_IO (-1)
+#define _POSIX_TIMEOUTS 200112L
+#define _POSIX_TIMERS 200112L
+#define _POSIX_TYPED_MEMORY_OBJECTS (-1)
+#define _POSIX_VDISABLE 0xff
+
+#if __XSI_VISIBLE
+#define _XOPEN_SHM 1
+#define _XOPEN_STREAMS (-1)
+#endif
+
+/*
+ * Although we have saved user/group IDs, we do not use them in setuid
+ * as described in POSIX 1003.1, because the feature does not work for
+ * root. We use the saved IDs in seteuid/setegid, which are not currently
+ * part of the POSIX 1003.1 specification. XXX revisit for 1003.1-2001
+ * as this is now mandatory.
+ */
+#ifdef _NOT_AVAILABLE
+#define _POSIX_SAVED_IDS 1 /* saved set-user-ID and set-group-ID */
+#endif
+
+/* Define the POSIX.1 version we target for compliance. */
+#define _POSIX_VERSION 200112L
+
+/* access function */
+#define F_OK 0 /* test for existence of file */
+#define X_OK 0x01 /* test for execute or search permission */
+#define W_OK 0x02 /* test for write permission */
+#define R_OK 0x04 /* test for read permission */
+
+/* whence values for lseek(2) */
+#ifndef SEEK_SET
+#define SEEK_SET 0 /* set file offset to offset */
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+#endif
+#if __BSD_VISIBLE
+#define SEEK_DATA 3 /* set file offset to next data past offset */
+#define SEEK_HOLE 4 /* set file offset to next hole past offset */
+#endif
+
+#ifndef _POSIX_SOURCE
+/* whence values for lseek(2); renamed by POSIX 1003.1 */
+#define L_SET SEEK_SET
+#define L_INCR SEEK_CUR
+#define L_XTND SEEK_END
+#endif
+
+/* configurable pathname variables */
+#define _PC_LINK_MAX 1
+#define _PC_MAX_CANON 2
+#define _PC_MAX_INPUT 3
+#define _PC_NAME_MAX 4
+#define _PC_PATH_MAX 5
+#define _PC_PIPE_BUF 6
+#define _PC_CHOWN_RESTRICTED 7
+#define _PC_NO_TRUNC 8
+#define _PC_VDISABLE 9
+
+#if __POSIX_VISIBLE >= 199309
+#define _PC_ASYNC_IO 53
+#define _PC_PRIO_IO 54
+#define _PC_SYNC_IO 55
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+#define _PC_ALLOC_SIZE_MIN 10
+#define _PC_FILESIZEBITS 12
+#define _PC_REC_INCR_XFER_SIZE 14
+#define _PC_REC_MAX_XFER_SIZE 15
+#define _PC_REC_MIN_XFER_SIZE 16
+#define _PC_REC_XFER_ALIGN 17
+#define _PC_SYMLINK_MAX 18
+#endif
+
+#if __BSD_VISIBLE
+#define _PC_ACL_EXTENDED 59
+#define _PC_ACL_PATH_MAX 60
+#define _PC_CAP_PRESENT 61
+#define _PC_INF_PRESENT 62
+#define _PC_MAC_PRESENT 63
+#define _PC_ACL_NFS4 64
+#endif
+
+/* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */
+#define _PC_MIN_HOLE_SIZE 21
+
+#if __BSD_VISIBLE
+/*
+ * rfork() options.
+ *
+ * XXX currently, some operations without RFPROC set are not supported.
+ */
+#define RFNAMEG (1<<0) /* UNIMPL new plan9 `name space' */
+#define RFENVG (1<<1) /* UNIMPL copy plan9 `env space' */
+#define RFFDG (1<<2) /* copy fd table */
+#define RFNOTEG (1<<3) /* UNIMPL create new plan9 `note group' */
+#define RFPROC (1<<4) /* change child (else changes curproc) */
+#define RFMEM (1<<5) /* share `address space' */
+#define RFNOWAIT (1<<6) /* give child to init */
+#define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */
+#define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */
+#define RFCFDG (1<<12) /* close all fds, zero fd table */
+#define RFTHREAD (1<<13) /* enable kernel thread support */
+#define RFSIGSHARE (1<<14) /* share signal handlers */
+#define RFLINUXTHPN (1<<16) /* do linux clone exit parent notification */
+#define RFSTOPPED (1<<17) /* leave child in a stopped state */
+#define RFHIGHPID (1<<18) /* use a pid higher than 10 (idleproc) */
+#define RFTSIGZMB (1<<19) /* select signal for exit parent notification */
+#define RFTSIGSHIFT 20 /* selected signal number is in bits 20-27 */
+#define RFTSIGMASK 0xFF
+#define RFTSIGNUM(flags) (((flags) >> RFTSIGSHIFT) & RFTSIGMASK)
+#define RFTSIGFLAGS(signum) ((signum) << RFTSIGSHIFT)
+#define RFPROCDESC (1<<28) /* return a process descriptor */
+#define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */
+#define RFFLAGS (RFFDG | RFPROC | RFMEM | RFNOWAIT | RFCFDG | \
+ RFTHREAD | RFSIGSHARE | RFLINUXTHPN | RFSTOPPED | RFHIGHPID | RFTSIGZMB | \
+ RFPROCDESC | RFPPWAIT)
+#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPPWAIT | RFPROCDESC)
+
+#endif /* __BSD_VISIBLE */
+
+#endif /* !_SYS_UNISTD_H_ */
diff --git a/usr/src/boot/sys/sys/uuid.h b/usr/src/boot/sys/sys/uuid.h
new file mode 100644
index 0000000000..0748f61148
--- /dev/null
+++ b/usr/src/boot/sys/sys/uuid.h
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_UUID_H_
+#define _SYS_UUID_H_
+
+#include <sys/cdefs.h>
+
+/* Length of a node address (an IEEE 802 address). */
+#define _UUID_NODE_LEN 6
+
+/*
+ * See also:
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
+ *
+ * A DCE 1.1 compatible source representation of UUIDs.
+ */
+struct uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_hi_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[_UUID_NODE_LEN];
+};
+
+#ifdef _KERNEL
+
+#define UUID_NODE_LEN _UUID_NODE_LEN
+
+struct sbuf;
+
+struct uuid *kern_uuidgen(struct uuid *, size_t);
+
+int uuid_ether_add(const uint8_t *);
+int uuid_ether_del(const uint8_t *);
+
+int snprintf_uuid(char *, size_t, struct uuid *);
+int printf_uuid(struct uuid *);
+int sbuf_printf_uuid(struct sbuf *, struct uuid *);
+int parse_uuid(const char *, struct uuid *);
+
+void be_uuid_dec(void const *buf, struct uuid *uuid);
+void be_uuid_enc(void *buf, struct uuid const *uuid);
+void le_uuid_dec(void const *buf, struct uuid *uuid);
+void le_uuid_enc(void *buf, struct uuid const *uuid);
+
+#else /* _KERNEL */
+
+/* XXX namespace pollution? */
+typedef struct uuid uuid_t;
+
+__BEGIN_DECLS
+int uuidgen(struct uuid *, int);
+__END_DECLS
+
+#endif /* _KERNEL */
+
+#endif /* _SYS_UUID_H_ */
diff --git a/usr/src/boot/sys/sys/vtoc.h b/usr/src/boot/sys/sys/vtoc.h
new file mode 100644
index 0000000000..10d83499f8
--- /dev/null
+++ b/usr/src/boot/sys/sys/vtoc.h
@@ -0,0 +1,163 @@
+/*-
+ * Copyright (c) 2008 Marcel Moolenaar
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_VTOC_H_
+#define _SYS_VTOC_H_
+
+#define VTOC_TAG_UNASSIGNED 0x00
+#define VTOC_TAG_BOOT 0x01
+#define VTOC_TAG_ROOT 0x02
+#define VTOC_TAG_SWAP 0x03
+#define VTOC_TAG_USR 0x04
+#define VTOC_TAG_BACKUP 0x05 /* "c" partition */
+#define VTOC_TAG_STAND 0x06
+#define VTOC_TAG_VAR 0x07
+#define VTOC_TAG_HOME 0x08
+#define VTOC_TAG_ALTSCTR 0x09 /* alternate sector partition */
+#define VTOC_TAG_CACHE 0x0a /* Solaris cachefs partition */
+#define VTOC_TAG_VXVM_PUB 0x0e /* VxVM public region */
+#define VTOC_TAG_VXVM_PRIV 0x0f /* VxVM private region */
+
+/* NetBSD/mips defines this */
+#define VTOC_TAG_NETBSD_FFS 0xff
+
+/* FreeBSD tags: the high byte equals ELFOSABI_FREEBSD */
+#define VTOC_TAG_FREEBSD_SWAP 0x0901
+#define VTOC_TAG_FREEBSD_UFS 0x0902
+#define VTOC_TAG_FREEBSD_VINUM 0x0903
+#define VTOC_TAG_FREEBSD_ZFS 0x0904
+#define VTOC_TAG_FREEBSD_NANDFS 0x0905
+
+#define VTOC_FLAG_UNMNT 0x01 /* unmountable partition */
+#define VTOC_FLAG_RDONLY 0x10 /* partition is read/only */
+
+#define VTOC_ASCII_LEN 128
+#define VTOC_BOOTSIZE 8192 /* 16 sectors */
+#define VTOC_MAGIC 0xdabe
+#define VTOC_RAW_PART 2
+#define VTOC_SANITY 0x600ddeee
+#define VTOC_VERSION 1
+#define VTOC_VOLUME_LEN 8
+
+#define VTOC8_NPARTS 8
+
+struct vtoc8 {
+ char ascii[VTOC_ASCII_LEN];
+ uint32_t version;
+ char volume[VTOC_VOLUME_LEN];
+ uint16_t nparts;
+ struct {
+ uint16_t tag;
+ uint16_t flag;
+ } part[VTOC8_NPARTS] __packed;
+ uint16_t __alignment;
+ uint32_t bootinfo[3];
+ uint32_t sanity;
+ uint32_t reserved[10];
+ uint32_t timestamp[VTOC8_NPARTS];
+ uint16_t wskip;
+ uint16_t rskip;
+ char padding[152];
+ uint16_t rpm;
+ uint16_t physcyls;
+ uint16_t sparesecs;
+ uint16_t spare1[2];
+ uint16_t interleave;
+ uint16_t ncyls;
+ uint16_t altcyls;
+ uint16_t nheads;
+ uint16_t nsecs;
+ uint16_t spare2[2];
+ struct {
+ uint32_t cyl;
+ uint32_t nblks;
+ } map[VTOC8_NPARTS];
+ uint16_t magic;
+ uint16_t cksum;
+} __packed;
+
+#ifdef CTASSERT
+CTASSERT(sizeof(struct vtoc8) == 512);
+#endif
+
+#define NDKMAP 16 /* # of logical partitions */
+#define DK_LABEL_LOC 1 /* location of disk label */
+#define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */
+#define LEN_DKL_VVOL 8 /* length of v_volume */
+#define DK_LABEL_SIZE 512 /* size of disk label */
+#define DK_MAX_BLOCKS 0x7fffffff /* max # of blocks handled */
+
+struct dk_vtoc {
+ uint32_t v_bootinfo[3]; /* info needed by mboot (unsupported) */
+ uint32_t v_sanity; /* to verify vtoc sanity */
+ uint32_t v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ uint16_t v_sectorsz; /* sector size in bytes */
+ uint16_t v_nparts; /* number of partitions */
+ uint32_t v_reserved[10]; /* free space */
+ struct {
+ uint16_t p_tag; /* ID tag of partition */
+ uint16_t p_flag; /* permission flags */
+ uint32_t p_start;/* start sector no of partition */
+ int32_t p_size; /* # of blocks in partition */
+ } v_part[NDKMAP]; /* partition headers */
+ uint32_t timestamp[NDKMAP]; /* partition timestamp (unsupported) */
+ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+};
+
+#define LEN_DKL_PAD (DK_LABEL_SIZE - \
+ ((sizeof (struct dk_vtoc) + \
+ (4 * sizeof (uint32_t)) + \
+ (12 * sizeof (uint16_t)) + \
+ (2 * (sizeof (uint16_t))))))
+
+struct dk_label {
+ struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */
+ uint32_t dkl_pcyl; /* # of physical cylinders */
+ uint32_t dkl_ncyl; /* # of data cylinders */
+ uint16_t dkl_acyl; /* # of alternate cylinders */
+ uint16_t dkl_bcyl; /* cyl offset (for fixed head area) */
+ uint32_t dkl_nhead; /* # of heads */
+ uint32_t dkl_nsect; /* # of data sectors per track */
+ uint16_t dkl_intrlv; /* interleave factor */
+ uint16_t dkl_skew; /* skew factor */
+ uint16_t dkl_apc; /* alternates per cyl (SCSI only) */
+ uint16_t dkl_rpm; /* revolutions per minute */
+ uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */
+ uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */
+ uint16_t dkl_extra[4]; /* for compatible expansion */
+ char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */
+ uint16_t dkl_magic; /* identifies this label format */
+ uint16_t dkl_cksum; /* xor checksum of sector */
+};
+
+#ifdef CTASSERT
+CTASSERT(sizeof(struct dk_label) == 512);
+#endif
+
+#endif /* _SYS_VTOC_H_ */
diff --git a/usr/src/boot/sys/ufs/ffs/fs.h b/usr/src/boot/sys/ufs/ffs/fs.h
new file mode 100644
index 0000000000..a7162cd7d9
--- /dev/null
+++ b/usr/src/boot/sys/ufs/ffs/fs.h
@@ -0,0 +1,778 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)fs.h 8.13 (Berkeley) 3/21/95
+ * $FreeBSD$
+ */
+
+#ifndef _UFS_FFS_FS_H_
+#define _UFS_FFS_FS_H_
+
+#include <sys/mount.h>
+#include <ufs/ufs/dinode.h>
+
+/*
+ * Each disk drive contains some number of filesystems.
+ * A filesystem consists of a number of cylinder groups.
+ * Each cylinder group has inodes and data.
+ *
+ * A filesystem is described by its super-block, which in turn
+ * describes the cylinder groups. The super-block is critical
+ * data and is replicated in each cylinder group to protect against
+ * catastrophic loss. This is done at `newfs' time and the critical
+ * super-block data does not change, so the copies need not be
+ * referenced further unless disaster strikes.
+ *
+ * For filesystem fs, the offsets of the various blocks of interest
+ * are given in the super block as:
+ * [fs->fs_sblkno] Super-block
+ * [fs->fs_cblkno] Cylinder group block
+ * [fs->fs_iblkno] Inode blocks
+ * [fs->fs_dblkno] Data blocks
+ * The beginning of cylinder group cg in fs, is given by
+ * the ``cgbase(fs, cg)'' macro.
+ *
+ * Depending on the architecture and the media, the superblock may
+ * reside in any one of four places. For tiny media where every block
+ * counts, it is placed at the very front of the partition. Historically,
+ * UFS1 placed it 8K from the front to leave room for the disk label and
+ * a small bootstrap. For UFS2 it got moved to 64K from the front to leave
+ * room for the disk label and a bigger bootstrap, and for really piggy
+ * systems we check at 256K from the front if the first three fail. In
+ * all cases the size of the superblock will be SBLOCKSIZE. All values are
+ * given in byte-offset form, so they do not imply a sector size. The
+ * SBLOCKSEARCH specifies the order in which the locations should be searched.
+ */
+#define SBLOCK_FLOPPY 0
+#define SBLOCK_UFS1 8192
+#define SBLOCK_UFS2 65536
+#define SBLOCK_PIGGY 262144
+#define SBLOCKSIZE 8192
+#define SBLOCKSEARCH \
+ { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
+
+/*
+ * Max number of fragments per block. This value is NOT tweakable.
+ */
+#define MAXFRAG 8
+
+/*
+ * Addresses stored in inodes are capable of addressing fragments
+ * of `blocks'. File system blocks of at most size MAXBSIZE can
+ * be optionally broken into 2, 4, or 8 pieces, each of which is
+ * addressable; these pieces may be DEV_BSIZE, or some multiple of
+ * a DEV_BSIZE unit.
+ *
+ * Large files consist of exclusively large data blocks. To avoid
+ * undue wasted disk space, the last data block of a small file may be
+ * allocated as only as many fragments of a large block as are
+ * necessary. The filesystem format retains only a single pointer
+ * to such a fragment, which is a piece of a single large block that
+ * has been divided. The size of such a fragment is determinable from
+ * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
+ *
+ * The filesystem records space availability at the fragment level;
+ * to determine block availability, aligned fragments are examined.
+ */
+
+/*
+ * MINBSIZE is the smallest allowable block size.
+ * In order to insure that it is possible to create files of size
+ * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
+ * MINBSIZE must be big enough to hold a cylinder group block,
+ * thus changes to (struct cg) must keep its size within MINBSIZE.
+ * Note that super blocks are always of size SBLOCKSIZE,
+ * and that both SBLOCKSIZE and MAXBSIZE must be >= MINBSIZE.
+ */
+#define MINBSIZE 4096
+
+/*
+ * The path name on which the filesystem is mounted is maintained
+ * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
+ * the super block for this name.
+ */
+#define MAXMNTLEN 468
+
+/*
+ * The volume name for this filesystem is maintained in fs_volname.
+ * MAXVOLLEN defines the length of the buffer allocated.
+ */
+#define MAXVOLLEN 32
+
+/*
+ * There is a 128-byte region in the superblock reserved for in-core
+ * pointers to summary information. Originally this included an array
+ * of pointers to blocks of struct csum; now there are just a few
+ * pointers and the remaining space is padded with fs_ocsp[].
+ *
+ * NOCSPTRS determines the size of this padding. One pointer (fs_csp)
+ * is taken away to point to a contiguous array of struct csum for
+ * all cylinder groups; a second (fs_maxcluster) points to an array
+ * of cluster sizes that is computed as cylinder groups are inspected,
+ * and the third points to an array that tracks the creation of new
+ * directories. A fourth pointer, fs_active, is used when creating
+ * snapshots; it points to a bitmap of cylinder groups for which the
+ * free-block bitmap has changed since the snapshot operation began.
+ */
+#define NOCSPTRS ((128 / sizeof(void *)) - 4)
+
+/*
+ * A summary of contiguous blocks of various sizes is maintained
+ * in each cylinder group. Normally this is set by the initial
+ * value of fs_maxcontig. To conserve space, a maximum summary size
+ * is set by FS_MAXCONTIG.
+ */
+#define FS_MAXCONTIG 16
+
+/*
+ * MINFREE gives the minimum acceptable percentage of filesystem
+ * blocks which may be free. If the freelist drops below this level
+ * only the superuser may continue to allocate blocks. This may
+ * be set to 0 if no reserve of free blocks is deemed necessary,
+ * however throughput drops by fifty percent if the filesystem
+ * is run at between 95% and 100% full; thus the minimum default
+ * value of fs_minfree is 5%. However, to get good clustering
+ * performance, 10% is a better choice. hence we use 10% as our
+ * default value. With 10% free space, fragmentation is not a
+ * problem, so we choose to optimize for time.
+ */
+#define MINFREE 8
+#define DEFAULTOPT FS_OPTTIME
+
+/*
+ * Grigoriy Orlov <gluk@ptci.ru> has done some extensive work to fine
+ * tune the layout preferences for directories within a filesystem.
+ * His algorithm can be tuned by adjusting the following parameters
+ * which tell the system the average file size and the average number
+ * of files per directory. These defaults are well selected for typical
+ * filesystems, but may need to be tuned for odd cases like filesystems
+ * being used for squid caches or news spools.
+ */
+#define AVFILESIZ 16384 /* expected average file size */
+#define AFPDIR 64 /* expected number of files per directory */
+
+/*
+ * The maximum number of snapshot nodes that can be associated
+ * with each filesystem. This limit affects only the number of
+ * snapshot files that can be recorded within the superblock so
+ * that they can be found when the filesystem is mounted. However,
+ * maintaining too many will slow the filesystem performance, so
+ * having this limit is a good idea.
+ */
+#define FSMAXSNAP 20
+
+/*
+ * Used to identify special blocks in snapshots:
+ *
+ * BLK_NOCOPY - A block that was unallocated at the time the snapshot
+ * was taken, hence does not need to be copied when written.
+ * BLK_SNAP - A block held by another snapshot that is not needed by this
+ * snapshot. When the other snapshot is freed, the BLK_SNAP entries
+ * are converted to BLK_NOCOPY. These are needed to allow fsck to
+ * identify blocks that are in use by other snapshots (which are
+ * expunged from this snapshot).
+ */
+#define BLK_NOCOPY ((ufs2_daddr_t)(1))
+#define BLK_SNAP ((ufs2_daddr_t)(2))
+
+/*
+ * Sysctl values for the fast filesystem.
+ */
+#define FFS_ADJ_REFCNT 1 /* adjust inode reference count */
+#define FFS_ADJ_BLKCNT 2 /* adjust inode used block count */
+#define FFS_BLK_FREE 3 /* free range of blocks in map */
+#define FFS_DIR_FREE 4 /* free specified dir inodes in map */
+#define FFS_FILE_FREE 5 /* free specified file inodes in map */
+#define FFS_SET_FLAGS 6 /* set filesystem flags */
+#define FFS_ADJ_NDIR 7 /* adjust number of directories */
+#define FFS_ADJ_NBFREE 8 /* adjust number of free blocks */
+#define FFS_ADJ_NIFREE 9 /* adjust number of free inodes */
+#define FFS_ADJ_NFFREE 10 /* adjust number of free frags */
+#define FFS_ADJ_NUMCLUSTERS 11 /* adjust number of free clusters */
+#define FFS_SET_CWD 12 /* set current directory */
+#define FFS_SET_DOTDOT 13 /* set inode number for ".." */
+#define FFS_UNLINK 14 /* remove a name in the filesystem */
+#define FFS_SET_INODE 15 /* update an on-disk inode */
+#define FFS_SET_BUFOUTPUT 16 /* set buffered writing on descriptor */
+#define FFS_MAXID 16 /* number of valid ffs ids */
+
+/*
+ * Command structure passed in to the filesystem to adjust filesystem values.
+ */
+#define FFS_CMD_VERSION 0x19790518 /* version ID */
+struct fsck_cmd {
+ int32_t version; /* version of command structure */
+ int32_t handle; /* reference to filesystem to be changed */
+ int64_t value; /* inode or block number to be affected */
+ int64_t size; /* amount or range to be adjusted */
+ int64_t spare; /* reserved for future use */
+};
+
+/*
+ * Per cylinder group information; summarized in blocks allocated
+ * from first cylinder group data blocks. These blocks have to be
+ * read in from fs_csaddr (size fs_cssize) in addition to the
+ * super block.
+ */
+struct csum {
+ int32_t cs_ndir; /* number of directories */
+ int32_t cs_nbfree; /* number of free blocks */
+ int32_t cs_nifree; /* number of free inodes */
+ int32_t cs_nffree; /* number of free frags */
+};
+struct csum_total {
+ int64_t cs_ndir; /* number of directories */
+ int64_t cs_nbfree; /* number of free blocks */
+ int64_t cs_nifree; /* number of free inodes */
+ int64_t cs_nffree; /* number of free frags */
+ int64_t cs_numclusters; /* number of free clusters */
+ int64_t cs_spare[3]; /* future expansion */
+};
+
+/*
+ * Super block for an FFS filesystem.
+ */
+struct fs {
+ int32_t fs_firstfield; /* historic filesystem linked list, */
+ int32_t fs_unused_1; /* used for incore super blocks */
+ int32_t fs_sblkno; /* offset of super-block in filesys */
+ int32_t fs_cblkno; /* offset of cyl-block in filesys */
+ int32_t fs_iblkno; /* offset of inode-blocks in filesys */
+ int32_t fs_dblkno; /* offset of first data after cg */
+ int32_t fs_old_cgoffset; /* cylinder group offset in cylinder */
+ int32_t fs_old_cgmask; /* used to calc mod fs_ntrak */
+ int32_t fs_old_time; /* last time written */
+ int32_t fs_old_size; /* number of blocks in fs */
+ int32_t fs_old_dsize; /* number of data blocks in fs */
+ u_int32_t fs_ncg; /* number of cylinder groups */
+ int32_t fs_bsize; /* size of basic blocks in fs */
+ int32_t fs_fsize; /* size of frag blocks in fs */
+ int32_t fs_frag; /* number of frags in a block in fs */
+/* these are configuration parameters */
+ int32_t fs_minfree; /* minimum percentage of free blocks */
+ int32_t fs_old_rotdelay; /* num of ms for optimal next block */
+ int32_t fs_old_rps; /* disk revolutions per second */
+/* these fields can be computed from the others */
+ int32_t fs_bmask; /* ``blkoff'' calc of blk offsets */
+ int32_t fs_fmask; /* ``fragoff'' calc of frag offsets */
+ int32_t fs_bshift; /* ``lblkno'' calc of logical blkno */
+ int32_t fs_fshift; /* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+ int32_t fs_maxcontig; /* max number of contiguous blks */
+ int32_t fs_maxbpg; /* max number of blks per cyl group */
+/* these fields can be computed from the others */
+ int32_t fs_fragshift; /* block to frag shift */
+ int32_t fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
+ int32_t fs_sbsize; /* actual size of super block */
+ int32_t fs_spare1[2]; /* old fs_csmask */
+ /* old fs_csshift */
+ int32_t fs_nindir; /* value of NINDIR */
+ u_int32_t fs_inopb; /* value of INOPB */
+ int32_t fs_old_nspf; /* value of NSPF */
+/* yet another configuration parameter */
+ int32_t fs_optim; /* optimization preference, see below */
+ int32_t fs_old_npsect; /* # sectors/track including spares */
+ int32_t fs_old_interleave; /* hardware sector interleave */
+ int32_t fs_old_trackskew; /* sector 0 skew, per track */
+ int32_t fs_id[2]; /* unique filesystem id */
+/* sizes determined by number of cylinder groups and their sizes */
+ int32_t fs_old_csaddr; /* blk addr of cyl grp summary area */
+ int32_t fs_cssize; /* size of cyl grp summary area */
+ int32_t fs_cgsize; /* cylinder group size */
+ int32_t fs_spare2; /* old fs_ntrak */
+ int32_t fs_old_nsect; /* sectors per track */
+ int32_t fs_old_spc; /* sectors per cylinder */
+ int32_t fs_old_ncyl; /* cylinders in filesystem */
+ int32_t fs_old_cpg; /* cylinders per group */
+ u_int32_t fs_ipg; /* inodes per group */
+ int32_t fs_fpg; /* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+ struct csum fs_old_cstotal; /* cylinder summary information */
+/* these fields are cleared at mount time */
+ int8_t fs_fmod; /* super block modified flag */
+ int8_t fs_clean; /* filesystem is clean flag */
+ int8_t fs_ronly; /* mounted read-only flag */
+ int8_t fs_old_flags; /* old FS_ flags */
+ u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
+ u_char fs_volname[MAXVOLLEN]; /* volume name */
+ u_int64_t fs_swuid; /* system-wide uid */
+ int32_t fs_pad; /* due to alignment of fs_swuid */
+/* these fields retain the current block allocation info */
+ int32_t fs_cgrotor; /* last cg searched */
+ void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */
+ u_int8_t *fs_contigdirs; /* (u) # of contig. allocated dirs */
+ struct csum *fs_csp; /* (u) cg summary info buffer */
+ int32_t *fs_maxcluster; /* (u) max cluster in each cyl group */
+ u_int *fs_active; /* (u) used by snapshots to track fs */
+ int32_t fs_old_cpc; /* cyl per cycle in postbl */
+ int32_t fs_maxbsize; /* maximum blocking factor permitted */
+ int64_t fs_unrefs; /* number of unreferenced inodes */
+ int64_t fs_providersize; /* size of underlying GEOM provider */
+ int64_t fs_metaspace; /* size of area reserved for metadata */
+ int64_t fs_sparecon64[14]; /* old rotation block list head */
+ int64_t fs_sblockloc; /* byte offset of standard superblock */
+ struct csum_total fs_cstotal; /* (u) cylinder summary information */
+ ufs_time_t fs_time; /* last time written */
+ int64_t fs_size; /* number of blocks in fs */
+ int64_t fs_dsize; /* number of data blocks in fs */
+ ufs2_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
+ int64_t fs_pendingblocks; /* (u) blocks being freed */
+ u_int32_t fs_pendinginodes; /* (u) inodes being freed */
+ uint32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
+ u_int32_t fs_avgfilesize; /* expected average file size */
+ u_int32_t fs_avgfpdir; /* expected # of files per directory */
+ int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */
+ ufs_time_t fs_mtime; /* Last mount or fsck time. */
+ int32_t fs_sujfree; /* SUJ free list */
+ int32_t fs_sparecon32[23]; /* reserved for future constants */
+ int32_t fs_flags; /* see FS_ flags below */
+ int32_t fs_contigsumsize; /* size of cluster summary array */
+ int32_t fs_maxsymlinklen; /* max length of an internal symlink */
+ int32_t fs_old_inodefmt; /* format of on-disk inodes */
+ u_int64_t fs_maxfilesize; /* maximum representable file size */
+ int64_t fs_qbmask; /* ~fs_bmask for use with 64-bit size */
+ int64_t fs_qfmask; /* ~fs_fmask for use with 64-bit size */
+ int32_t fs_state; /* validate fs_clean field */
+ int32_t fs_old_postblformat; /* format of positional layout tables */
+ int32_t fs_old_nrpos; /* number of rotational positions */
+ int32_t fs_spare5[2]; /* old fs_postbloff */
+ /* old fs_rotbloff */
+ int32_t fs_magic; /* magic number */
+};
+
+/* Sanity checking. */
+#ifdef CTASSERT
+CTASSERT(sizeof(struct fs) == 1376);
+#endif
+
+/*
+ * Filesystem identification
+ */
+#define FS_UFS1_MAGIC 0x011954 /* UFS1 fast filesystem magic number */
+#define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast filesystem magic number */
+#define FS_BAD_MAGIC 0x19960408 /* UFS incomplete newfs magic number */
+#define FS_OKAY 0x7c269d38 /* superblock checksum */
+#define FS_42INODEFMT -1 /* 4.2BSD inode format */
+#define FS_44INODEFMT 2 /* 4.4BSD inode format */
+
+/*
+ * Preference for optimization.
+ */
+#define FS_OPTTIME 0 /* minimize allocation time */
+#define FS_OPTSPACE 1 /* minimize disk fragmentation */
+
+/*
+ * Filesystem flags.
+ *
+ * The FS_UNCLEAN flag is set by the kernel when the filesystem was
+ * mounted with fs_clean set to zero. The FS_DOSOFTDEP flag indicates
+ * that the filesystem should be managed by the soft updates code.
+ * Note that the FS_NEEDSFSCK flag is set and cleared only by the
+ * fsck utility. It is set when background fsck finds an unexpected
+ * inconsistency which requires a traditional foreground fsck to be
+ * run. Such inconsistencies should only be found after an uncorrectable
+ * disk error. A foreground fsck will clear the FS_NEEDSFSCK flag when
+ * it has successfully cleaned up the filesystem. The kernel uses this
+ * flag to enforce that inconsistent filesystems be mounted read-only.
+ * The FS_INDEXDIRS flag when set indicates that the kernel maintains
+ * on-disk auxiliary indexes (such as B-trees) for speeding directory
+ * accesses. Kernels that do not support auxiliary indicies clear the
+ * flag to indicate that the indicies need to be rebuilt (by fsck) before
+ * they can be used.
+ *
+ * FS_ACLS indicates that POSIX.1e ACLs are administratively enabled
+ * for the file system, so they should be loaded from extended attributes,
+ * observed for access control purposes, and be administered by object
+ * owners. FS_NFS4ACLS indicates that NFSv4 ACLs are administratively
+ * enabled. This flag is mutually exclusive with FS_ACLS. FS_MULTILABEL
+ * indicates that the TrustedBSD MAC Framework should attempt to back MAC
+ * labels into extended attributes on the file system rather than maintain
+ * a single mount label for all objects.
+ */
+#define FS_UNCLEAN 0x0001 /* filesystem not clean at mount */
+#define FS_DOSOFTDEP 0x0002 /* filesystem using soft dependencies */
+#define FS_NEEDSFSCK 0x0004 /* filesystem needs sync fsck before mount */
+#define FS_SUJ 0x0008 /* Filesystem using softupdate journal */
+#define FS_ACLS 0x0010 /* file system has POSIX.1e ACLs enabled */
+#define FS_MULTILABEL 0x0020 /* file system is MAC multi-label */
+#define FS_GJOURNAL 0x0040 /* gjournaled file system */
+#define FS_FLAGS_UPDATED 0x0080 /* flags have been moved to new location */
+#define FS_NFS4ACLS 0x0100 /* file system has NFSv4 ACLs enabled */
+#define FS_INDEXDIRS 0x0200 /* kernel supports indexed directories */
+#define FS_TRIM 0x0400 /* issue BIO_DELETE for deleted blocks */
+
+/*
+ * Macros to access bits in the fs_active array.
+ */
+#define ACTIVECGNUM(fs, cg) ((fs)->fs_active[(cg) / (NBBY * sizeof(int))])
+#define ACTIVECGOFF(cg) (1 << ((cg) % (NBBY * sizeof(int))))
+#define ACTIVESET(fs, cg) do { \
+ if ((fs)->fs_active) \
+ ACTIVECGNUM((fs), (cg)) |= ACTIVECGOFF((cg)); \
+} while (0)
+#define ACTIVECLEAR(fs, cg) do { \
+ if ((fs)->fs_active) \
+ ACTIVECGNUM((fs), (cg)) &= ~ACTIVECGOFF((cg)); \
+} while (0)
+
+/*
+ * The size of a cylinder group is calculated by CGSIZE. The maximum size
+ * is limited by the fact that cylinder groups are at most one block.
+ * Its size is derived from the size of the maps maintained in the
+ * cylinder group and the (struct cg) size.
+ */
+#define CGSIZE(fs) \
+ /* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \
+ /* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \
+ /* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \
+ /* inode map */ howmany((fs)->fs_ipg, NBBY) + \
+ /* block map */ howmany((fs)->fs_fpg, NBBY) +\
+ /* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \
+ /* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \
+ /* cluster map */ howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY)))
+
+/*
+ * The minimal number of cylinder groups that should be created.
+ */
+#define MINCYLGRPS 4
+
+/*
+ * Convert cylinder group to base address of its global summary info.
+ */
+#define fs_cs(fs, indx) fs_csp[indx]
+
+/*
+ * Cylinder group block for a filesystem.
+ */
+#define CG_MAGIC 0x090255
+struct cg {
+ int32_t cg_firstfield; /* historic cyl groups linked list */
+ int32_t cg_magic; /* magic number */
+ int32_t cg_old_time; /* time last written */
+ u_int32_t cg_cgx; /* we are the cgx'th cylinder group */
+ int16_t cg_old_ncyl; /* number of cyl's this cg */
+ int16_t cg_old_niblk; /* number of inode blocks this cg */
+ u_int32_t cg_ndblk; /* number of data blocks this cg */
+ struct csum cg_cs; /* cylinder summary information */
+ u_int32_t cg_rotor; /* position of last used block */
+ u_int32_t cg_frotor; /* position of last used frag */
+ u_int32_t cg_irotor; /* position of last used inode */
+ u_int32_t cg_frsum[MAXFRAG]; /* counts of available frags */
+ int32_t cg_old_btotoff; /* (int32) block totals per cylinder */
+ int32_t cg_old_boff; /* (u_int16) free block positions */
+ u_int32_t cg_iusedoff; /* (u_int8) used inode map */
+ u_int32_t cg_freeoff; /* (u_int8) free block map */
+ u_int32_t cg_nextfreeoff; /* (u_int8) next available space */
+ u_int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */
+ u_int32_t cg_clusteroff; /* (u_int8) free cluster map */
+ u_int32_t cg_nclusterblks; /* number of clusters this cg */
+ u_int32_t cg_niblk; /* number of inode blocks this cg */
+ u_int32_t cg_initediblk; /* last initialized inode */
+ u_int32_t cg_unrefs; /* number of unreferenced inodes */
+ int32_t cg_sparecon32[2]; /* reserved for future use */
+ ufs_time_t cg_time; /* time last written */
+ int64_t cg_sparecon64[3]; /* reserved for future use */
+ u_int8_t cg_space[1]; /* space for cylinder group maps */
+/* actually longer */
+};
+
+/*
+ * Macros for access to cylinder group array structures
+ */
+#define cg_chkmagic(cgp) ((cgp)->cg_magic == CG_MAGIC)
+#define cg_inosused(cgp) \
+ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff))
+#define cg_blksfree(cgp) \
+ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff))
+#define cg_clustersfree(cgp) \
+ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff))
+#define cg_clustersum(cgp) \
+ ((int32_t *)((uintptr_t)(cgp) + (cgp)->cg_clustersumoff))
+
+/*
+ * Turn filesystem block numbers into disk block addresses.
+ * This maps filesystem blocks to device size blocks.
+ */
+#define fsbtodb(fs, b) ((daddr_t)(b) << (fs)->fs_fsbtodb)
+#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
+
+/*
+ * Cylinder group macros to locate things in cylinder groups.
+ * They calc filesystem addresses of cylinder group data structures.
+ */
+#define cgbase(fs, c) (((ufs2_daddr_t)(fs)->fs_fpg) * (c))
+#define cgdata(fs, c) (cgdmin(fs, c) + (fs)->fs_metaspace) /* data zone */
+#define cgmeta(fs, c) (cgdmin(fs, c)) /* meta data */
+#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
+#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
+#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
+#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
+#define cgstart(fs, c) \
+ ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) : \
+ (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask))))
+
+/*
+ * Macros for handling inode numbers:
+ * inode number to filesystem block offset.
+ * inode number to cylinder group number.
+ * inode number to filesystem block address.
+ */
+#define ino_to_cg(fs, x) (((ino_t)(x)) / (fs)->fs_ipg)
+#define ino_to_fsba(fs, x) \
+ ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, (ino_t)(x))) + \
+ (blkstofrags((fs), ((((ino_t)(x)) % (fs)->fs_ipg) / INOPB(fs))))))
+#define ino_to_fsbo(fs, x) (((ino_t)(x)) % INOPB(fs))
+
+/*
+ * Give cylinder group number for a filesystem block.
+ * Give cylinder group block number for a filesystem block.
+ */
+#define dtog(fs, d) ((d) / (fs)->fs_fpg)
+#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
+
+/*
+ * Extract the bits for a block from a map.
+ * Compute the cylinder and rotational position of a cyl block addr.
+ */
+#define blkmap(fs, map, loc) \
+ (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
+ ((loc) & ~((fs)->fs_bmask))
+#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
+ ((loc) & ~((fs)->fs_fmask))
+#define lfragtosize(fs, frag) /* calculates ((off_t)frag * fs->fs_fsize) */ \
+ (((off_t)(frag)) << (fs)->fs_fshift)
+#define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \
+ (((off_t)(blk)) << (fs)->fs_bshift)
+/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
+#define smalllblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \
+ ((blk) << (fs)->fs_bshift)
+#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
+ ((loc) >> (fs)->fs_bshift)
+#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
+ ((loc) >> (fs)->fs_fshift)
+#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
+ (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
+#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
+ (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
+#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
+ ((frags) >> (fs)->fs_fragshift)
+#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
+ ((blks) << (fs)->fs_fragshift)
+#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
+ ((fsb) & ((fs)->fs_frag - 1))
+#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
+ ((fsb) &~ ((fs)->fs_frag - 1))
+
+/*
+ * Determine the number of available frags given a
+ * percentage to hold in reserve.
+ */
+#define freespace(fs, percentreserved) \
+ (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
+ (fs)->fs_cstotal.cs_nffree - \
+ (((off_t)((fs)->fs_dsize)) * (percentreserved) / 100))
+
+/*
+ * Determining the size of a file block in the filesystem.
+ */
+#define blksize(fs, ip, lbn) \
+ (((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
+ ? (fs)->fs_bsize \
+ : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define sblksize(fs, size, lbn) \
+ (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
+ ? (fs)->fs_bsize \
+ : (fragroundup(fs, blkoff(fs, (size)))))
+
+/*
+ * Number of indirects in a filesystem block.
+ */
+#define NINDIR(fs) ((fs)->fs_nindir)
+
+/*
+ * Indirect lbns are aligned on NDADDR addresses where single indirects
+ * are the negated address of the lowest lbn reachable, double indirects
+ * are this lbn - 1 and triple indirects are this lbn - 2. This yields
+ * an unusual bit order to determine level.
+ */
+static inline int
+lbn_level(ufs_lbn_t lbn)
+{
+ if (lbn >= 0)
+ return 0;
+ switch (lbn & 0x3) {
+ case 0:
+ return (0);
+ case 1:
+ break;
+ case 2:
+ return (2);
+ case 3:
+ return (1);
+ default:
+ break;
+ }
+ return (-1);
+}
+
+static inline ufs_lbn_t
+lbn_offset(struct fs *fs, int level)
+{
+ ufs_lbn_t res;
+
+ for (res = 1; level > 0; level--)
+ res *= NINDIR(fs);
+ return (res);
+}
+
+/*
+ * Number of inodes in a secondary storage block/fragment.
+ */
+#define INOPB(fs) ((fs)->fs_inopb)
+#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * Softdep journal record format.
+ */
+
+#define JOP_ADDREF 1 /* Add a reference to an inode. */
+#define JOP_REMREF 2 /* Remove a reference from an inode. */
+#define JOP_NEWBLK 3 /* Allocate a block. */
+#define JOP_FREEBLK 4 /* Free a block or a tree of blocks. */
+#define JOP_MVREF 5 /* Move a reference from one off to another. */
+#define JOP_TRUNC 6 /* Partial truncation record. */
+#define JOP_SYNC 7 /* fsync() complete record. */
+
+#define JREC_SIZE 32 /* Record and segment header size. */
+
+#define SUJ_MIN (4 * 1024 * 1024) /* Minimum journal size */
+#define SUJ_MAX (32 * 1024 * 1024) /* Maximum journal size */
+#define SUJ_FILE ".sujournal" /* Journal file name */
+
+/*
+ * Size of the segment record header. There is at most one for each disk
+ * block in the journal. The segment header is followed by an array of
+ * records. fsck depends on the first element in each record being 'op'
+ * and the second being 'ino'. Segments may span multiple disk blocks but
+ * the header is present on each.
+ */
+struct jsegrec {
+ uint64_t jsr_seq; /* Our sequence number */
+ uint64_t jsr_oldest; /* Oldest valid sequence number */
+ uint16_t jsr_cnt; /* Count of valid records */
+ uint16_t jsr_blocks; /* Count of device bsize blocks. */
+ uint32_t jsr_crc; /* 32bit crc of the valid space */
+ ufs_time_t jsr_time; /* timestamp for mount instance */
+};
+
+/*
+ * Reference record. Records a single link count modification.
+ */
+struct jrefrec {
+ uint32_t jr_op;
+ uint32_t jr_ino;
+ uint32_t jr_parent;
+ uint16_t jr_nlink;
+ uint16_t jr_mode;
+ int64_t jr_diroff;
+ uint64_t jr_unused;
+};
+
+/*
+ * Move record. Records a reference moving within a directory block. The
+ * nlink is unchanged but we must search both locations.
+ */
+struct jmvrec {
+ uint32_t jm_op;
+ uint32_t jm_ino;
+ uint32_t jm_parent;
+ uint16_t jm_unused;
+ int64_t jm_oldoff;
+ int64_t jm_newoff;
+};
+
+/*
+ * Block record. A set of frags or tree of blocks starting at an indirect are
+ * freed or a set of frags are allocated.
+ */
+struct jblkrec {
+ uint32_t jb_op;
+ uint32_t jb_ino;
+ ufs2_daddr_t jb_blkno;
+ ufs_lbn_t jb_lbn;
+ uint16_t jb_frags;
+ uint16_t jb_oldfrags;
+ uint32_t jb_unused;
+};
+
+/*
+ * Truncation record. Records a partial truncation so that it may be
+ * completed at check time. Also used for sync records.
+ */
+struct jtrncrec {
+ uint32_t jt_op;
+ uint32_t jt_ino;
+ int64_t jt_size;
+ uint32_t jt_extsize;
+ uint32_t jt_pad[3];
+};
+
+union jrec {
+ struct jsegrec rec_jsegrec;
+ struct jrefrec rec_jrefrec;
+ struct jmvrec rec_jmvrec;
+ struct jblkrec rec_jblkrec;
+ struct jtrncrec rec_jtrncrec;
+};
+
+#ifdef CTASSERT
+CTASSERT(sizeof(struct jsegrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jrefrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jmvrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jblkrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jtrncrec) == JREC_SIZE);
+CTASSERT(sizeof(union jrec) == JREC_SIZE);
+#endif
+
+extern int inside[], around[];
+extern u_char *fragtbl[];
+
+/*
+ * IOCTLs used for filesystem write suspension.
+ */
+#define UFSSUSPEND _IOW('U', 1, fsid_t)
+#define UFSRESUME _IO('U', 2)
+
+#endif
diff --git a/usr/src/boot/sys/x86/include/_align.h b/usr/src/boot/sys/x86/include/_align.h
new file mode 100644
index 0000000000..0d0981bcf4
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/_align.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)param.h 5.8 (Berkeley) 6/28/91
+ * $FreeBSD$
+ */
+
+#ifndef _X86_INCLUDE__ALIGN_H_
+#define _X86_INCLUDE__ALIGN_H_
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is unsigned int
+ * and must be cast to any desired pointer type.
+ */
+#define _ALIGNBYTES (sizeof(register_t) - 1)
+#define _ALIGN(p) (((uintptr_t)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
+
+#endif /* !_X86_INCLUDE__ALIGN_H_ */
diff --git a/usr/src/boot/sys/x86/include/_inttypes.h b/usr/src/boot/sys/x86/include/_inttypes.h
new file mode 100644
index 0000000000..e96c4c56eb
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/_inttypes.h
@@ -0,0 +1,221 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_INTTYPES_H_
+#define _MACHINE_INTTYPES_H_
+
+/*
+ * Macros for format specifiers.
+ */
+
+#ifdef __LP64__
+#define __PRI64 "l"
+#define __PRIptr "l"
+#else
+#define __PRI64 "ll"
+#define __PRIptr
+#endif
+
+/* fprintf(3) macros for signed integers. */
+
+#define PRId8 "d" /* int8_t */
+#define PRId16 "d" /* int16_t */
+#define PRId32 "d" /* int32_t */
+#define PRId64 __PRI64"d" /* int64_t */
+#define PRIdLEAST8 "d" /* int_least8_t */
+#define PRIdLEAST16 "d" /* int_least16_t */
+#define PRIdLEAST32 "d" /* int_least32_t */
+#define PRIdLEAST64 __PRI64"d" /* int_least64_t */
+#define PRIdFAST8 "d" /* int_fast8_t */
+#define PRIdFAST16 "d" /* int_fast16_t */
+#define PRIdFAST32 "d" /* int_fast32_t */
+#define PRIdFAST64 __PRI64"d" /* int_fast64_t */
+#define PRIdMAX "jd" /* intmax_t */
+#define PRIdPTR __PRIptr"d" /* intptr_t */
+
+#define PRIi8 "i" /* int8_t */
+#define PRIi16 "i" /* int16_t */
+#define PRIi32 "i" /* int32_t */
+#define PRIi64 __PRI64"i" /* int64_t */
+#define PRIiLEAST8 "i" /* int_least8_t */
+#define PRIiLEAST16 "i" /* int_least16_t */
+#define PRIiLEAST32 "i" /* int_least32_t */
+#define PRIiLEAST64 __PRI64"i" /* int_least64_t */
+#define PRIiFAST8 "i" /* int_fast8_t */
+#define PRIiFAST16 "i" /* int_fast16_t */
+#define PRIiFAST32 "i" /* int_fast32_t */
+#define PRIiFAST64 __PRI64"i" /* int_fast64_t */
+#define PRIiMAX "ji" /* intmax_t */
+#define PRIiPTR __PRIptr"i" /* intptr_t */
+
+/* fprintf(3) macros for unsigned integers. */
+
+#define PRIo8 "o" /* uint8_t */
+#define PRIo16 "o" /* uint16_t */
+#define PRIo32 "o" /* uint32_t */
+#define PRIo64 __PRI64"o" /* uint64_t */
+#define PRIoLEAST8 "o" /* uint_least8_t */
+#define PRIoLEAST16 "o" /* uint_least16_t */
+#define PRIoLEAST32 "o" /* uint_least32_t */
+#define PRIoLEAST64 __PRI64"o" /* uint_least64_t */
+#define PRIoFAST8 "o" /* uint_fast8_t */
+#define PRIoFAST16 "o" /* uint_fast16_t */
+#define PRIoFAST32 "o" /* uint_fast32_t */
+#define PRIoFAST64 __PRI64"o" /* uint_fast64_t */
+#define PRIoMAX "jo" /* uintmax_t */
+#define PRIoPTR __PRIptr"o" /* uintptr_t */
+
+#define PRIu8 "u" /* uint8_t */
+#define PRIu16 "u" /* uint16_t */
+#define PRIu32 "u" /* uint32_t */
+#define PRIu64 __PRI64"u" /* uint64_t */
+#define PRIuLEAST8 "u" /* uint_least8_t */
+#define PRIuLEAST16 "u" /* uint_least16_t */
+#define PRIuLEAST32 "u" /* uint_least32_t */
+#define PRIuLEAST64 __PRI64"u" /* uint_least64_t */
+#define PRIuFAST8 "u" /* uint_fast8_t */
+#define PRIuFAST16 "u" /* uint_fast16_t */
+#define PRIuFAST32 "u" /* uint_fast32_t */
+#define PRIuFAST64 __PRI64"u" /* uint_fast64_t */
+#define PRIuMAX "ju" /* uintmax_t */
+#define PRIuPTR __PRIptr"u" /* uintptr_t */
+
+#define PRIx8 "x" /* uint8_t */
+#define PRIx16 "x" /* uint16_t */
+#define PRIx32 "x" /* uint32_t */
+#define PRIx64 __PRI64"x" /* uint64_t */
+#define PRIxLEAST8 "x" /* uint_least8_t */
+#define PRIxLEAST16 "x" /* uint_least16_t */
+#define PRIxLEAST32 "x" /* uint_least32_t */
+#define PRIxLEAST64 __PRI64"x" /* uint_least64_t */
+#define PRIxFAST8 "x" /* uint_fast8_t */
+#define PRIxFAST16 "x" /* uint_fast16_t */
+#define PRIxFAST32 "x" /* uint_fast32_t */
+#define PRIxFAST64 __PRI64"x" /* uint_fast64_t */
+#define PRIxMAX "jx" /* uintmax_t */
+#define PRIxPTR __PRIptr"x" /* uintptr_t */
+
+#define PRIX8 "X" /* uint8_t */
+#define PRIX16 "X" /* uint16_t */
+#define PRIX32 "X" /* uint32_t */
+#define PRIX64 __PRI64"X" /* uint64_t */
+#define PRIXLEAST8 "X" /* uint_least8_t */
+#define PRIXLEAST16 "X" /* uint_least16_t */
+#define PRIXLEAST32 "X" /* uint_least32_t */
+#define PRIXLEAST64 __PRI64"X" /* uint_least64_t */
+#define PRIXFAST8 "X" /* uint_fast8_t */
+#define PRIXFAST16 "X" /* uint_fast16_t */
+#define PRIXFAST32 "X" /* uint_fast32_t */
+#define PRIXFAST64 __PRI64"X" /* uint_fast64_t */
+#define PRIXMAX "jX" /* uintmax_t */
+#define PRIXPTR __PRIptr"X" /* uintptr_t */
+
+/* fscanf(3) macros for signed integers. */
+
+#define SCNd8 "hhd" /* int8_t */
+#define SCNd16 "hd" /* int16_t */
+#define SCNd32 "d" /* int32_t */
+#define SCNd64 __PRI64"d" /* int64_t */
+#define SCNdLEAST8 "hhd" /* int_least8_t */
+#define SCNdLEAST16 "hd" /* int_least16_t */
+#define SCNdLEAST32 "d" /* int_least32_t */
+#define SCNdLEAST64 __PRI64"d" /* int_least64_t */
+#define SCNdFAST8 "d" /* int_fast8_t */
+#define SCNdFAST16 "d" /* int_fast16_t */
+#define SCNdFAST32 "d" /* int_fast32_t */
+#define SCNdFAST64 __PRI64"d" /* int_fast64_t */
+#define SCNdMAX "jd" /* intmax_t */
+#define SCNdPTR __PRIptr"d" /* intptr_t */
+
+#define SCNi8 "hhi" /* int8_t */
+#define SCNi16 "hi" /* int16_t */
+#define SCNi32 "i" /* int32_t */
+#define SCNi64 __PRI64"i" /* int64_t */
+#define SCNiLEAST8 "hhi" /* int_least8_t */
+#define SCNiLEAST16 "hi" /* int_least16_t */
+#define SCNiLEAST32 "i" /* int_least32_t */
+#define SCNiLEAST64 __PRI64"i" /* int_least64_t */
+#define SCNiFAST8 "i" /* int_fast8_t */
+#define SCNiFAST16 "i" /* int_fast16_t */
+#define SCNiFAST32 "i" /* int_fast32_t */
+#define SCNiFAST64 __PRI64"i" /* int_fast64_t */
+#define SCNiMAX "ji" /* intmax_t */
+#define SCNiPTR __PRIptr"i" /* intptr_t */
+
+/* fscanf(3) macros for unsigned integers. */
+
+#define SCNo8 "hho" /* uint8_t */
+#define SCNo16 "ho" /* uint16_t */
+#define SCNo32 "o" /* uint32_t */
+#define SCNo64 __PRI64"o" /* uint64_t */
+#define SCNoLEAST8 "hho" /* uint_least8_t */
+#define SCNoLEAST16 "ho" /* uint_least16_t */
+#define SCNoLEAST32 "o" /* uint_least32_t */
+#define SCNoLEAST64 __PRI64"o" /* uint_least64_t */
+#define SCNoFAST8 "o" /* uint_fast8_t */
+#define SCNoFAST16 "o" /* uint_fast16_t */
+#define SCNoFAST32 "o" /* uint_fast32_t */
+#define SCNoFAST64 __PRI64"o" /* uint_fast64_t */
+#define SCNoMAX "jo" /* uintmax_t */
+#define SCNoPTR __PRIptr"o" /* uintptr_t */
+
+#define SCNu8 "hhu" /* uint8_t */
+#define SCNu16 "hu" /* uint16_t */
+#define SCNu32 "u" /* uint32_t */
+#define SCNu64 __PRI64"u" /* uint64_t */
+#define SCNuLEAST8 "hhu" /* uint_least8_t */
+#define SCNuLEAST16 "hu" /* uint_least16_t */
+#define SCNuLEAST32 "u" /* uint_least32_t */
+#define SCNuLEAST64 __PRI64"u" /* uint_least64_t */
+#define SCNuFAST8 "u" /* uint_fast8_t */
+#define SCNuFAST16 "u" /* uint_fast16_t */
+#define SCNuFAST32 "u" /* uint_fast32_t */
+#define SCNuFAST64 __PRI64"u" /* uint_fast64_t */
+#define SCNuMAX "ju" /* uintmax_t */
+#define SCNuPTR __PRIptr"u" /* uintptr_t */
+
+#define SCNx8 "hhx" /* uint8_t */
+#define SCNx16 "hx" /* uint16_t */
+#define SCNx32 "x" /* uint32_t */
+#define SCNx64 __PRI64"x" /* uint64_t */
+#define SCNxLEAST8 "hhx" /* uint_least8_t */
+#define SCNxLEAST16 "hx" /* uint_least16_t */
+#define SCNxLEAST32 "x" /* uint_least32_t */
+#define SCNxLEAST64 __PRI64"x" /* uint_least64_t */
+#define SCNxFAST8 "x" /* uint_fast8_t */
+#define SCNxFAST16 "x" /* uint_fast16_t */
+#define SCNxFAST32 "x" /* uint_fast32_t */
+#define SCNxFAST64 __PRI64"x" /* uint_fast64_t */
+#define SCNxMAX "jx" /* uintmax_t */
+#define SCNxPTR __PRIptr"x" /* uintptr_t */
+
+#endif /* !_MACHINE_INTTYPES_H_ */
diff --git a/usr/src/boot/sys/x86/include/_limits.h b/usr/src/boot/sys/x86/include/_limits.h
new file mode 100644
index 0000000000..2f582e1237
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/_limits.h
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)limits.h 8.3 (Berkeley) 1/4/94
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE__LIMITS_H_
+#define _MACHINE__LIMITS_H_
+
+/*
+ * According to ANSI (section 2.2.4.2), the values below must be usable by
+ * #if preprocessing directives. Additionally, the expression must have the
+ * same type as would an expression that is an object of the corresponding
+ * type converted according to the integral promotions. The subtraction for
+ * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
+ * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
+ */
+
+#define __CHAR_BIT 8 /* number of bits in a char */
+
+#define __SCHAR_MAX 0x7f /* max value for a signed char */
+#define __SCHAR_MIN (-0x7f - 1) /* min value for a signed char */
+
+#define __UCHAR_MAX 0xff /* max value for an unsigned char */
+
+#define __USHRT_MAX 0xffff /* max value for an unsigned short */
+#define __SHRT_MAX 0x7fff /* max value for a short */
+#define __SHRT_MIN (-0x7fff - 1) /* min value for a short */
+
+#define __UINT_MAX 0xffffffff /* max value for an unsigned int */
+#define __INT_MAX 0x7fffffff /* max value for an int */
+#define __INT_MIN (-0x7fffffff - 1) /* min value for an int */
+
+#ifdef __LP64__
+#define __ULONG_MAX 0xffffffffffffffff /* max for an unsigned long */
+#define __LONG_MAX 0x7fffffffffffffff /* max for a long */
+#define __LONG_MIN (-0x7fffffffffffffff - 1) /* min for a long */
+#else
+#define __ULONG_MAX 0xffffffffUL
+#define __LONG_MAX 0x7fffffffL
+#define __LONG_MIN (-0x7fffffffL - 1)
+#endif
+
+ /* max value for an unsigned long long */
+#define __ULLONG_MAX 0xffffffffffffffffULL
+#define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */
+#define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */
+
+#ifdef __LP64__
+#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */
+#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */
+#define __OFF_MAX __LONG_MAX /* max value for an off_t */
+#define __OFF_MIN __LONG_MIN /* min value for an off_t */
+/* Quads and longs are the same on the amd64. Ensure they stay in sync. */
+#define __UQUAD_MAX __ULONG_MAX /* max value for a uquad_t */
+#define __QUAD_MAX __LONG_MAX /* max value for a quad_t */
+#define __QUAD_MIN __LONG_MIN /* min value for a quad_t */
+#define __LONG_BIT 64
+#else
+#define __SSIZE_MAX __INT_MAX
+#define __SIZE_T_MAX __UINT_MAX
+#define __OFF_MAX __LLONG_MAX
+#define __OFF_MIN __LLONG_MIN
+#define __UQUAD_MAX __ULLONG_MAX
+#define __QUAD_MAX __LLONG_MAX
+#define __QUAD_MIN __LLONG_MIN
+#define __LONG_BIT 32
+#endif
+
+#define __WORD_BIT 32
+
+/* Minimum signal stack size. */
+#define __MINSIGSTKSZ (512 * 4)
+
+#endif /* !_MACHINE__LIMITS_H_ */
diff --git a/usr/src/boot/sys/x86/include/_stdint.h b/usr/src/boot/sys/x86/include/_stdint.h
new file mode 100644
index 0000000000..d9ee316623
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/_stdint.h
@@ -0,0 +1,189 @@
+/*-
+ * Copyright (c) 2001, 2002 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE__STDINT_H_
+#define _MACHINE__STDINT_H_
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define INT8_C(c) (c)
+#define INT16_C(c) (c)
+#define INT32_C(c) (c)
+
+#define UINT8_C(c) (c)
+#define UINT16_C(c) (c)
+#define UINT32_C(c) (c ## U)
+
+#ifdef __LP64__
+#define INT64_C(c) (c ## L)
+#define UINT64_C(c) (c ## UL)
+#else
+#define INT64_C(c) (c ## LL)
+#define UINT64_C(c) (c ## ULL)
+#endif
+
+#define INTMAX_C(c) INT64_C(c)
+#define UINTMAX_C(c) UINT64_C(c)
+
+#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.1 Limits of exact-width integer types
+ */
+#define INT8_MIN (-0x7f-1)
+#define INT16_MIN (-0x7fff-1)
+#define INT32_MIN (-0x7fffffff-1)
+
+#define INT8_MAX 0x7f
+#define INT16_MAX 0x7fff
+#define INT32_MAX 0x7fffffff
+
+#define UINT8_MAX 0xff
+#define UINT16_MAX 0xffff
+#define UINT32_MAX 0xffffffffU
+
+#ifdef __LP64__
+#define INT64_MIN (-0x7fffffffffffffff-1)
+#define INT64_MAX 0x7fffffffffffffff
+#define UINT64_MAX 0xffffffffffffffff
+#else
+#define INT64_MIN (-0x7fffffffffffffffLL-1)
+#define INT64_MAX 0x7fffffffffffffffLL
+#define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.2 Limits of minimum-width integer types
+ */
+/* Minimum values of minimum-width signed integer types. */
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+/* Maximum values of minimum-width signed integer types. */
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+/* Maximum values of minimum-width unsigned integer types. */
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.3 Limits of fastest minimum-width integer types
+ */
+/* Minimum values of fastest minimum-width signed integer types. */
+#define INT_FAST8_MIN INT32_MIN
+#define INT_FAST16_MIN INT32_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST64_MIN INT64_MIN
+
+/* Maximum values of fastest minimum-width signed integer types. */
+#define INT_FAST8_MAX INT32_MAX
+#define INT_FAST16_MAX INT32_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MAX INT64_MAX
+
+/* Maximum values of fastest minimum-width unsigned integer types. */
+#define UINT_FAST8_MAX UINT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.4 Limits of integer types capable of holding object pointers
+ */
+#ifdef __LP64__
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+#else
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+#endif
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.5 Limits of greatest-width integer types
+ */
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.3 Limits of other integer types
+ */
+#ifdef __LP64__
+/* Limits of ptrdiff_t. */
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+
+/* Limits of sig_atomic_t. */
+#define SIG_ATOMIC_MIN LONG_MIN
+#define SIG_ATOMIC_MAX LONG_MAX
+
+/* Limit of size_t. */
+#define SIZE_MAX UINT64_MAX
+#else
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+#define SIG_ATOMIC_MIN INT32_MIN
+#define SIG_ATOMIC_MAX INT32_MAX
+#define SIZE_MAX UINT32_MAX
+#endif
+
+/* Limits of wint_t. */
+#define WINT_MIN INT32_MIN
+#define WINT_MAX INT32_MAX
+
+#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
+
+#endif /* !_MACHINE__STDINT_H_ */
diff --git a/usr/src/boot/sys/x86/include/_types.h b/usr/src/boot/sys/x86/include/_types.h
new file mode 100644
index 0000000000..b130be3d04
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/_types.h
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ * From: @(#)types.h 8.3 (Berkeley) 1/5/94
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE__TYPES_H_
+#define _MACHINE__TYPES_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+#define __NO_STRICT_ALIGNMENT
+
+/*
+ * Basic types upon which most other types are built.
+ */
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short __int16_t;
+typedef unsigned short __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#ifdef __LP64__
+typedef long __int64_t;
+typedef unsigned long __uint64_t;
+#else
+#ifndef lint
+__extension__
+#endif
+/* LONGLONG */
+typedef long long __int64_t;
+#ifndef lint
+__extension__
+#endif
+/* LONGLONG */
+typedef unsigned long long __uint64_t;
+#endif
+
+/*
+ * Standard type definitions.
+ */
+#ifdef __LP64__
+typedef __int32_t __clock_t; /* clock()... */
+typedef __int64_t __critical_t;
+typedef double __double_t;
+typedef float __float_t;
+typedef __int64_t __intfptr_t;
+typedef __int64_t __intptr_t;
+#else
+typedef unsigned long __clock_t;
+typedef __int32_t __critical_t;
+typedef long double __double_t;
+typedef long double __float_t;
+typedef __int32_t __intfptr_t;
+typedef __int32_t __intptr_t;
+#endif
+typedef __int64_t __intmax_t;
+typedef __int32_t __int_fast8_t;
+typedef __int32_t __int_fast16_t;
+typedef __int32_t __int_fast32_t;
+typedef __int64_t __int_fast64_t;
+typedef __int8_t __int_least8_t;
+typedef __int16_t __int_least16_t;
+typedef __int32_t __int_least32_t;
+typedef __int64_t __int_least64_t;
+#ifdef __LP64__
+typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */
+typedef __int64_t __register_t;
+typedef __int64_t __segsz_t; /* segment size (in pages) */
+typedef __uint64_t __size_t; /* sizeof() */
+typedef __int64_t __ssize_t; /* byte count or error */
+typedef __int64_t __time_t; /* time()... */
+typedef __uint64_t __uintfptr_t;
+typedef __uint64_t __uintptr_t;
+#else
+typedef __int32_t __ptrdiff_t;
+typedef __int32_t __register_t;
+typedef __int32_t __segsz_t;
+typedef __uint32_t __size_t;
+typedef __int32_t __ssize_t;
+typedef __int32_t __time_t;
+typedef __uint32_t __uintfptr_t;
+typedef __uint32_t __uintptr_t;
+#endif
+typedef __uint64_t __uintmax_t;
+typedef __uint32_t __uint_fast8_t;
+typedef __uint32_t __uint_fast16_t;
+typedef __uint32_t __uint_fast32_t;
+typedef __uint64_t __uint_fast64_t;
+typedef __uint8_t __uint_least8_t;
+typedef __uint16_t __uint_least16_t;
+typedef __uint32_t __uint_least32_t;
+typedef __uint64_t __uint_least64_t;
+#ifdef __LP64__
+typedef __uint64_t __u_register_t;
+typedef __uint64_t __vm_offset_t;
+typedef __uint64_t __vm_paddr_t;
+typedef __uint64_t __vm_size_t;
+#else
+typedef __uint32_t __u_register_t;
+typedef __uint32_t __vm_offset_t;
+#ifdef PAE
+typedef __uint64_t __vm_paddr_t;
+#else
+typedef __uint32_t __vm_paddr_t;
+#endif
+typedef __uint32_t __vm_size_t;
+#endif
+typedef __int64_t __vm_ooffset_t;
+typedef __uint64_t __vm_pindex_t;
+typedef int ___wchar_t;
+
+#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */
+#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */
+
+/*
+ * Unusual type definitions.
+ */
+#ifdef __GNUCLIKE_BUILTIN_VARARGS
+typedef __builtin_va_list __va_list; /* internally known to gcc */
+#else
+#ifdef __LP64__
+struct __s_va_list {
+ __uint32_t _pad1[2]; /* gp_offset, fp_offset */
+ __uint64_t _pad2[2]; /* overflow_arg_area, reg_save_area */
+};
+typedef struct __s_va_list __va_list;
+#else
+typedef char * __va_list;
+#endif
+#endif
+#if defined(__GNUC_VA_LIST_COMPATIBILITY) && !defined(__GNUC_VA_LIST) \
+ && !defined(__NO_GNUC_VA_LIST)
+#define __GNUC_VA_LIST
+typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/
+#endif
+
+#endif /* !_MACHINE__TYPES_H_ */
diff --git a/usr/src/boot/sys/x86/include/elf.h b/usr/src/boot/sys/x86/include/elf.h
new file mode 100644
index 0000000000..cde395b30b
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/elf.h
@@ -0,0 +1,215 @@
+/*-
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_ELF_H_
+#define _MACHINE_ELF_H_ 1
+
+#if defined(__i386__) || defined(_MACHINE_ELF_WANT_32BIT)
+
+/*
+ * ELF definitions for the i386 architecture.
+ */
+
+#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
+#if defined(__ELF_WORD_SIZE) && __ELF_WORD_SIZE == 64
+#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
+#endif
+
+#ifndef __ELF_WORD_SIZE
+#define __ELF_WORD_SIZE 32 /* Used by <sys/elf_generic.h> */
+#endif
+
+#include <sys/elf_generic.h>
+
+#define ELF_ARCH EM_386
+
+#define ELF_MACHINE_OK(x) ((x) == EM_386 || (x) == EM_486)
+
+/*
+ * Auxiliary vector entries for passing information to the interpreter.
+ *
+ * The i386 supplement to the SVR4 ABI specification names this "auxv_t",
+ * but POSIX lays claim to all symbols ending with "_t".
+ */
+
+typedef struct { /* Auxiliary vector entry on initial stack */
+ int a_type; /* Entry type. */
+ union {
+ long a_val; /* Integer value. */
+ void *a_ptr; /* Address. */
+ void (*a_fcn)(void); /* Function pointer (not used). */
+ } a_un;
+} Elf32_Auxinfo;
+
+#if __ELF_WORD_SIZE == 64
+/* Fake for amd64 loader support */
+typedef struct {
+ int fake;
+} Elf64_Auxinfo;
+#endif
+
+__ElfType(Auxinfo);
+
+/* Values for a_type. */
+#define AT_NULL 0 /* Terminates the vector. */
+#define AT_IGNORE 1 /* Ignored entry. */
+#define AT_EXECFD 2 /* File descriptor of program to load. */
+#define AT_PHDR 3 /* Program header of program already loaded. */
+#define AT_PHENT 4 /* Size of each program header entry. */
+#define AT_PHNUM 5 /* Number of program header entries. */
+#define AT_PAGESZ 6 /* Page size in bytes. */
+#define AT_BASE 7 /* Interpreter's base address. */
+#define AT_FLAGS 8 /* Flags (unused for i386). */
+#define AT_ENTRY 9 /* Where interpreter should transfer control. */
+#define AT_NOTELF 10 /* Program is not ELF ?? */
+#define AT_UID 11 /* Real uid. */
+#define AT_EUID 12 /* Effective uid. */
+#define AT_GID 13 /* Real gid. */
+#define AT_EGID 14 /* Effective gid. */
+#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP. */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+#define AT_TIMEKEEP 22 /* Pointer to timehands. */
+#define AT_STACKPROT 23 /* Initial stack protection. */
+
+#define AT_COUNT 24 /* Count of defined aux entry types. */
+
+/*
+ * Relocation types.
+ */
+
+#define R_386_COUNT 38 /* Count of defined relocation types. */
+
+/* Define "machine" characteristics */
+#define ELF_TARG_CLASS ELFCLASS32
+#define ELF_TARG_DATA ELFDATA2LSB
+#define ELF_TARG_MACH EM_386
+#define ELF_TARG_VER 1
+
+#define ET_DYN_LOAD_ADDR 0x01001000
+
+#elif defined(__amd64__)
+
+/*
+ * ELF definitions for the AMD64 architecture.
+ */
+
+#ifndef __ELF_WORD_SIZE
+#define __ELF_WORD_SIZE 64 /* Used by <sys/elf_generic.h> */
+#endif
+#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
+#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
+#include <sys/elf_generic.h>
+
+#define ELF_ARCH EM_X86_64
+#define ELF_ARCH32 EM_386
+
+#define ELF_MACHINE_OK(x) ((x) == EM_X86_64)
+
+/*
+ * Auxiliary vector entries for passing information to the interpreter.
+ *
+ * The i386 supplement to the SVR4 ABI specification names this "auxv_t",
+ * but POSIX lays claim to all symbols ending with "_t".
+ */
+typedef struct { /* Auxiliary vector entry on initial stack */
+ int a_type; /* Entry type. */
+ union {
+ int a_val; /* Integer value. */
+ } a_un;
+} Elf32_Auxinfo;
+
+
+typedef struct { /* Auxiliary vector entry on initial stack */
+ long a_type; /* Entry type. */
+ union {
+ long a_val; /* Integer value. */
+ void *a_ptr; /* Address. */
+ void (*a_fcn)(void); /* Function pointer (not used). */
+ } a_un;
+} Elf64_Auxinfo;
+
+__ElfType(Auxinfo);
+
+/* Values for a_type. */
+#define AT_NULL 0 /* Terminates the vector. */
+#define AT_IGNORE 1 /* Ignored entry. */
+#define AT_EXECFD 2 /* File descriptor of program to load. */
+#define AT_PHDR 3 /* Program header of program already loaded. */
+#define AT_PHENT 4 /* Size of each program header entry. */
+#define AT_PHNUM 5 /* Number of program header entries. */
+#define AT_PAGESZ 6 /* Page size in bytes. */
+#define AT_BASE 7 /* Interpreter's base address. */
+#define AT_FLAGS 8 /* Flags (unused for i386). */
+#define AT_ENTRY 9 /* Where interpreter should transfer control. */
+#define AT_NOTELF 10 /* Program is not ELF ?? */
+#define AT_UID 11 /* Real uid. */
+#define AT_EUID 12 /* Effective uid. */
+#define AT_GID 13 /* Real gid. */
+#define AT_EGID 14 /* Effective gid. */
+#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+#define AT_TIMEKEEP 22 /* Pointer to timehands. */
+#define AT_STACKPROT 23 /* Initial stack protection. */
+
+#define AT_COUNT 24 /* Count of defined aux entry types. */
+
+/*
+ * Relocation types.
+ */
+
+#define R_X86_64_COUNT 24 /* Count of defined relocation types. */
+
+/* Define "machine" characteristics */
+#if __ELF_WORD_SIZE == 32
+#define ELF_TARG_CLASS ELFCLASS32
+#else
+#define ELF_TARG_CLASS ELFCLASS64
+#endif
+#define ELF_TARG_DATA ELFDATA2LSB
+#define ELF_TARG_MACH EM_X86_64
+#define ELF_TARG_VER 1
+
+#if __ELF_WORD_SIZE == 32
+#define ET_DYN_LOAD_ADDR 0x01001000
+#else
+#define ET_DYN_LOAD_ADDR 0x01021000
+#endif
+
+#endif /* __i386__, __amd64__ */
+
+#endif /* !_MACHINE_ELF_H_ */
diff --git a/usr/src/boot/sys/x86/include/endian.h b/usr/src/boot/sys/x86/include/endian.h
new file mode 100644
index 0000000000..6ca6a6cf1c
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/endian.h
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1987, 1991 Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)endian.h 7.8 (Berkeley) 4/3/91
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_ENDIAN_H_
+#define _MACHINE_ENDIAN_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/*
+ * Define the order of 32-bit words in 64-bit words.
+ */
+#define _QUAD_HIGHWORD 1
+#define _QUAD_LOWWORD 0
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
+#define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
+
+#define _BYTE_ORDER _LITTLE_ENDIAN
+
+/*
+ * Deprecated variants that don't have enough underscores to be useful in more
+ * strict namespaces.
+ */
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN _LITTLE_ENDIAN
+#define BIG_ENDIAN _BIG_ENDIAN
+#define PDP_ENDIAN _PDP_ENDIAN
+#define BYTE_ORDER _BYTE_ORDER
+#endif
+
+#define __bswap16_gen(x) (__uint16_t)((x) << 8 | (x) >> 8)
+#define __bswap32_gen(x) \
+ (((__uint32_t)__bswap16((x) & 0xffff) << 16) | __bswap16((x) >> 16))
+#define __bswap64_gen(x) \
+ (((__uint64_t)__bswap32((x) & 0xffffffff) << 32) | __bswap32((x) >> 32))
+
+#ifdef __GNUCLIKE_BUILTIN_CONSTANT_P
+#define __bswap16(x) \
+ ((__uint16_t)(__builtin_constant_p(x) ? \
+ __bswap16_gen((__uint16_t)(x)) : __bswap16_var(x)))
+#define __bswap32(x) \
+ (__builtin_constant_p(x) ? \
+ __bswap32_gen((__uint32_t)(x)) : __bswap32_var(x))
+#define __bswap64(x) \
+ (__builtin_constant_p(x) ? \
+ __bswap64_gen((__uint64_t)(x)) : __bswap64_var(x))
+#else
+/* XXX these are broken for use in static initializers. */
+#define __bswap16(x) __bswap16_var(x)
+#define __bswap32(x) __bswap32_var(x)
+#define __bswap64(x) __bswap64_var(x)
+#endif
+
+/* These are defined as functions to avoid multiple evaluation of x. */
+
+static __inline __uint16_t
+__bswap16_var(__uint16_t _x)
+{
+
+ return (__bswap16_gen(_x));
+}
+
+static __inline __uint32_t
+__bswap32_var(__uint32_t _x)
+{
+
+#ifdef __GNUCLIKE_ASM
+ __asm("bswap %0" : "+r" (_x));
+ return (_x);
+#else
+ return (__bswap32_gen(_x));
+#endif
+}
+
+static __inline __uint64_t
+__bswap64_var(__uint64_t _x)
+{
+
+#if defined(__amd64__) && defined(__GNUCLIKE_ASM)
+ __asm("bswap %0" : "+r" (_x));
+ return (_x);
+#else
+ /*
+ * It is important for the optimizations that the following is not
+ * really generic, but expands to 2 __bswap32_var()'s.
+ */
+ return (__bswap64_gen(_x));
+#endif
+}
+
+#define __htonl(x) __bswap32(x)
+#define __htons(x) __bswap16(x)
+#define __ntohl(x) __bswap32(x)
+#define __ntohs(x) __bswap16(x)
+
+#endif /* !_MACHINE_ENDIAN_H_ */
diff --git a/usr/src/boot/sys/x86/include/metadata.h b/usr/src/boot/sys/x86/include/metadata.h
new file mode 100644
index 0000000000..e13eba0c7e
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/metadata.h
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_METADATA_H_
+#define _MACHINE_METADATA_H_
+
+#define MODINFOMD_SMAP 0x1001
+#define MODINFOMD_SMAP_XATTR 0x1002
+#define MODINFOMD_DTBP 0x1003
+#define MODINFOMD_EFI_MAP 0x1004
+#define MODINFOMD_EFI_FB 0x1005
+#define MODINFOMD_MODULEP 0x1006
+
+struct efi_map_header {
+ uint64_t memory_size;
+ uint64_t descriptor_size;
+ uint32_t descriptor_version;
+};
+
+struct efi_fb {
+ uint64_t fb_addr;
+ uint64_t fb_size;
+ uint32_t fb_height;
+ uint32_t fb_width;
+ uint32_t fb_stride;
+ uint32_t fb_mask_red;
+ uint32_t fb_mask_green;
+ uint32_t fb_mask_blue;
+ uint32_t fb_mask_reserved;
+};
+
+#endif /* !_MACHINE_METADATA_H_ */
diff --git a/usr/src/boot/sys/x86/include/psl.h b/usr/src/boot/sys/x86/include/psl.h
new file mode 100644
index 0000000000..47851e0bb0
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/psl.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)psl.h 5.2 (Berkeley) 1/18/91
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_PSL_H_
+#define _MACHINE_PSL_H_
+
+/*
+ * 386 processor status longword.
+ */
+#define PSL_C 0x00000001 /* carry bit */
+#define PSL_PF 0x00000004 /* parity bit */
+#define PSL_AF 0x00000010 /* bcd carry bit */
+#define PSL_Z 0x00000040 /* zero bit */
+#define PSL_N 0x00000080 /* negative bit */
+#define PSL_T 0x00000100 /* trace enable bit */
+#define PSL_I 0x00000200 /* interrupt enable bit */
+#define PSL_D 0x00000400 /* string instruction direction bit */
+#define PSL_V 0x00000800 /* overflow bit */
+#define PSL_IOPL 0x00003000 /* i/o privilege level */
+#define PSL_NT 0x00004000 /* nested task bit */
+#define PSL_RF 0x00010000 /* resume flag bit */
+#define PSL_VM 0x00020000 /* virtual 8086 mode bit */
+#define PSL_AC 0x00040000 /* alignment checking */
+#define PSL_VIF 0x00080000 /* virtual interrupt enable */
+#define PSL_VIP 0x00100000 /* virtual interrupt pending */
+#define PSL_ID 0x00200000 /* identification bit */
+
+/*
+ * The i486 manual says that we are not supposed to change reserved flags,
+ * but this is too much trouble since the reserved flags depend on the cpu
+ * and setting them to their historical values works in practice.
+ */
+#define PSL_RESERVED_DEFAULT 0x00000002
+
+/*
+ * Initial flags for kernel and user mode. The kernel later inherits
+ * PSL_I and some other flags from user mode.
+ */
+#define PSL_KERNEL PSL_RESERVED_DEFAULT
+#define PSL_USER (PSL_RESERVED_DEFAULT | PSL_I)
+
+/*
+ * Bits that can be changed in user mode on 486's. We allow these bits
+ * to be changed using ptrace(), sigreturn() and procfs. Setting PS_NT
+ * is undesirable but it may as well be allowed since users can inflict
+ * it on the kernel directly. Changes to PSL_AC are silently ignored on
+ * 386's.
+ *
+ * Users are allowed to change the privileged flag PSL_RF. The cpu sets PSL_RF
+ * in tf_eflags for faults. Debuggers should sometimes set it there too.
+ * tf_eflags is kept in the signal context during signal handling and there is
+ * no other place to remember it, so the PSL_RF bit may be corrupted by the
+ * signal handler without us knowing. Corruption of the PSL_RF bit at worst
+ * causes one more or one less debugger trap, so allowing it is fairly
+ * harmless.
+ */
+#define PSL_USERCHANGE (PSL_C | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_T \
+ | PSL_D | PSL_V | PSL_NT | PSL_RF | PSL_AC | PSL_ID)
+
+#endif /* !_MACHINE_PSL_H_ */
diff --git a/usr/src/boot/sys/x86/include/setjmp.h b/usr/src/boot/sys/x86/include/setjmp.h
new file mode 100644
index 0000000000..c33f9a5bae
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/setjmp.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_SETJMP_H_
+#define _MACHINE_SETJMP_H_
+
+#include <sys/cdefs.h>
+
+#define _JBLEN 12 /* Size of the jmp_buf on AMD64. */
+
+/*
+ * jmp_buf and sigjmp_buf are encapsulated in different structs to force
+ * compile-time diagnostics for mismatches. The structs are the same
+ * internally to avoid some run-time errors for mismatches.
+ */
+#if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE
+typedef struct _sigjmp_buf { long _sjb[_JBLEN]; } sigjmp_buf[1];
+#endif
+
+typedef struct _jmp_buf { long _jb[_JBLEN]; } jmp_buf[1];
+
+#endif /* !_MACHINE_SETJMP_H_ */
diff --git a/usr/src/boot/sys/x86/include/signal.h b/usr/src/boot/sys/x86/include/signal.h
new file mode 100644
index 0000000000..dee908f82b
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/signal.h
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (c) 1986, 1989, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2003 Peter Wemm.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * @(#)signal.h 8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef _X86_SIGNAL_H
+#define _X86_SIGNAL_H 1
+
+/*
+ * Machine-dependent signal definitions
+ */
+
+#include <sys/cdefs.h>
+#include <sys/_sigset.h>
+
+#if __BSD_VISIBLE
+#include <machine/trap.h> /* codes for SIGILL, SIGFPE */
+#endif
+
+#ifdef __i386__
+typedef int sig_atomic_t;
+
+#if __BSD_VISIBLE
+struct sigcontext {
+ struct __sigset sc_mask; /* signal mask to restore */
+ int sc_onstack; /* sigstack state to restore */
+ int sc_gs; /* machine state (struct trapframe) */
+ int sc_fs;
+ int sc_es;
+ int sc_ds;
+ int sc_edi;
+ int sc_esi;
+ int sc_ebp;
+ int sc_isp;
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+ int sc_trapno;
+ int sc_err;
+ int sc_eip;
+ int sc_cs;
+ int sc_efl;
+ int sc_esp;
+ int sc_ss;
+ int sc_len; /* sizeof(mcontext_t) */
+ /*
+ * See <machine/ucontext.h> and <machine/npx.h> for
+ * the following fields.
+ */
+ int sc_fpformat;
+ int sc_ownedfp;
+ int sc_flags;
+ int sc_fpstate[128] __aligned(16);
+
+ int sc_fsbase;
+ int sc_gsbase;
+
+ int sc_xfpustate;
+ int sc_xfpustate_len;
+
+ int sc_spare2[4];
+};
+
+#define sc_sp sc_esp
+#define sc_fp sc_ebp
+#define sc_pc sc_eip
+#define sc_ps sc_efl
+#define sc_eflags sc_efl
+
+#endif /* __BSD_VISIBLE */
+#endif /* __i386__ */
+
+#ifdef __amd64__
+typedef long sig_atomic_t;
+
+#if __BSD_VISIBLE
+/*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler. It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed.
+ *
+ * The sequence of the fields/registers after sc_mask in struct
+ * sigcontext must match those in mcontext_t and struct trapframe.
+ */
+struct sigcontext {
+ struct __sigset sc_mask; /* signal mask to restore */
+ long sc_onstack; /* sigstack state to restore */
+ long sc_rdi; /* machine state (struct trapframe) */
+ long sc_rsi;
+ long sc_rdx;
+ long sc_rcx;
+ long sc_r8;
+ long sc_r9;
+ long sc_rax;
+ long sc_rbx;
+ long sc_rbp;
+ long sc_r10;
+ long sc_r11;
+ long sc_r12;
+ long sc_r13;
+ long sc_r14;
+ long sc_r15;
+ int sc_trapno;
+ short sc_fs;
+ short sc_gs;
+ long sc_addr;
+ int sc_flags;
+ short sc_es;
+ short sc_ds;
+ long sc_err;
+ long sc_rip;
+ long sc_cs;
+ long sc_rflags;
+ long sc_rsp;
+ long sc_ss;
+ long sc_len; /* sizeof(mcontext_t) */
+ /*
+ * See <machine/ucontext.h> and <machine/fpu.h> for the following
+ * fields.
+ */
+ long sc_fpformat;
+ long sc_ownedfp;
+ long sc_fpstate[64] __aligned(16);
+
+ long sc_fsbase;
+ long sc_gsbase;
+
+ long sc_xfpustate;
+ long sc_xfpustate_len;
+
+ long sc_spare[4];
+};
+#endif /* __BSD_VISIBLE */
+#endif /* __amd64__ */
+
+#endif
diff --git a/usr/src/boot/sys/x86/include/specialreg.h b/usr/src/boot/sys/x86/include/specialreg.h
new file mode 100644
index 0000000000..5f2c01057d
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/specialreg.h
@@ -0,0 +1,862 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_SPECIALREG_H_
+#define _MACHINE_SPECIALREG_H_
+
+/*
+ * Bits in 386 special registers:
+ */
+#define CR0_PE 0x00000001 /* Protected mode Enable */
+#define CR0_MP 0x00000002 /* "Math" (fpu) Present */
+#define CR0_EM 0x00000004 /* EMulate FPU instructions. (trap ESC only) */
+#define CR0_TS 0x00000008 /* Task Switched (if MP, trap ESC and WAIT) */
+#define CR0_PG 0x80000000 /* PaGing enable */
+
+/*
+ * Bits in 486 special registers:
+ */
+#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
+#define CR0_WP 0x00010000 /* Write Protect (honor page protect in
+ all modes) */
+#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
+#define CR0_NW 0x20000000 /* Not Write-through */
+#define CR0_CD 0x40000000 /* Cache Disable */
+
+#define CR3_PCID_SAVE 0x8000000000000000
+#define CR3_PCID_MASK 0xfff
+
+/*
+ * Bits in PPro special registers
+ */
+#define CR4_VME 0x00000001 /* Virtual 8086 mode extensions */
+#define CR4_PVI 0x00000002 /* Protected-mode virtual interrupts */
+#define CR4_TSD 0x00000004 /* Time stamp disable */
+#define CR4_DE 0x00000008 /* Debugging extensions */
+#define CR4_PSE 0x00000010 /* Page size extensions */
+#define CR4_PAE 0x00000020 /* Physical address extension */
+#define CR4_MCE 0x00000040 /* Machine check enable */
+#define CR4_PGE 0x00000080 /* Page global enable */
+#define CR4_PCE 0x00000100 /* Performance monitoring counter enable */
+#define CR4_FXSR 0x00000200 /* Fast FPU save/restore used by OS */
+#define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */
+#define CR4_VMXE 0x00002000 /* enable VMX operation (Intel-specific) */
+#define CR4_FSGSBASE 0x00010000 /* Enable FS/GS BASE accessing instructions */
+#define CR4_PCIDE 0x00020000 /* Enable Context ID */
+#define CR4_XSAVE 0x00040000 /* XSETBV/XGETBV */
+#define CR4_SMEP 0x00100000 /* Supervisor-Mode Execution Prevention */
+
+/*
+ * Bits in AMD64 special registers. EFER is 64 bits wide.
+ */
+#define EFER_SCE 0x000000001 /* System Call Extensions (R/W) */
+#define EFER_LME 0x000000100 /* Long mode enable (R/W) */
+#define EFER_LMA 0x000000400 /* Long mode active (R) */
+#define EFER_NXE 0x000000800 /* PTE No-Execute bit enable (R/W) */
+#define EFER_SVM 0x000001000 /* SVM enable bit for AMD, reserved for Intel */
+#define EFER_LMSLE 0x000002000 /* Long Mode Segment Limit Enable */
+#define EFER_FFXSR 0x000004000 /* Fast FXSAVE/FSRSTOR */
+#define EFER_TCE 0x000008000 /* Translation Cache Extension */
+
+/*
+ * Intel Extended Features registers
+ */
+#define XCR0 0 /* XFEATURE_ENABLED_MASK register */
+
+#define XFEATURE_ENABLED_X87 0x00000001
+#define XFEATURE_ENABLED_SSE 0x00000002
+#define XFEATURE_ENABLED_YMM_HI128 0x00000004
+#define XFEATURE_ENABLED_AVX XFEATURE_ENABLED_YMM_HI128
+#define XFEATURE_ENABLED_BNDREGS 0x00000008
+#define XFEATURE_ENABLED_BNDCSR 0x00000010
+#define XFEATURE_ENABLED_OPMASK 0x00000020
+#define XFEATURE_ENABLED_ZMM_HI256 0x00000040
+#define XFEATURE_ENABLED_HI16_ZMM 0x00000080
+
+#define XFEATURE_AVX \
+ (XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE | XFEATURE_ENABLED_AVX)
+#define XFEATURE_AVX512 \
+ (XFEATURE_ENABLED_OPMASK | XFEATURE_ENABLED_ZMM_HI256 | \
+ XFEATURE_ENABLED_HI16_ZMM)
+#define XFEATURE_MPX \
+ (XFEATURE_ENABLED_BNDREGS | XFEATURE_ENABLED_BNDCSR)
+
+/*
+ * CPUID instruction features register
+ */
+#define CPUID_FPU 0x00000001
+#define CPUID_VME 0x00000002
+#define CPUID_DE 0x00000004
+#define CPUID_PSE 0x00000008
+#define CPUID_TSC 0x00000010
+#define CPUID_MSR 0x00000020
+#define CPUID_PAE 0x00000040
+#define CPUID_MCE 0x00000080
+#define CPUID_CX8 0x00000100
+#define CPUID_APIC 0x00000200
+#define CPUID_B10 0x00000400
+#define CPUID_SEP 0x00000800
+#define CPUID_MTRR 0x00001000
+#define CPUID_PGE 0x00002000
+#define CPUID_MCA 0x00004000
+#define CPUID_CMOV 0x00008000
+#define CPUID_PAT 0x00010000
+#define CPUID_PSE36 0x00020000
+#define CPUID_PSN 0x00040000
+#define CPUID_CLFSH 0x00080000
+#define CPUID_B20 0x00100000
+#define CPUID_DS 0x00200000
+#define CPUID_ACPI 0x00400000
+#define CPUID_MMX 0x00800000
+#define CPUID_FXSR 0x01000000
+#define CPUID_SSE 0x02000000
+#define CPUID_XMM 0x02000000
+#define CPUID_SSE2 0x04000000
+#define CPUID_SS 0x08000000
+#define CPUID_HTT 0x10000000
+#define CPUID_TM 0x20000000
+#define CPUID_IA64 0x40000000
+#define CPUID_PBE 0x80000000
+
+#define CPUID2_SSE3 0x00000001
+#define CPUID2_PCLMULQDQ 0x00000002
+#define CPUID2_DTES64 0x00000004
+#define CPUID2_MON 0x00000008
+#define CPUID2_DS_CPL 0x00000010
+#define CPUID2_VMX 0x00000020
+#define CPUID2_SMX 0x00000040
+#define CPUID2_EST 0x00000080
+#define CPUID2_TM2 0x00000100
+#define CPUID2_SSSE3 0x00000200
+#define CPUID2_CNXTID 0x00000400
+#define CPUID2_SDBG 0x00000800
+#define CPUID2_FMA 0x00001000
+#define CPUID2_CX16 0x00002000
+#define CPUID2_XTPR 0x00004000
+#define CPUID2_PDCM 0x00008000
+#define CPUID2_PCID 0x00020000
+#define CPUID2_DCA 0x00040000
+#define CPUID2_SSE41 0x00080000
+#define CPUID2_SSE42 0x00100000
+#define CPUID2_X2APIC 0x00200000
+#define CPUID2_MOVBE 0x00400000
+#define CPUID2_POPCNT 0x00800000
+#define CPUID2_TSCDLT 0x01000000
+#define CPUID2_AESNI 0x02000000
+#define CPUID2_XSAVE 0x04000000
+#define CPUID2_OSXSAVE 0x08000000
+#define CPUID2_AVX 0x10000000
+#define CPUID2_F16C 0x20000000
+#define CPUID2_RDRAND 0x40000000
+#define CPUID2_HV 0x80000000
+
+/*
+ * Important bits in the Thermal and Power Management flags
+ * CPUID.6 EAX and ECX.
+ */
+#define CPUTPM1_SENSOR 0x00000001
+#define CPUTPM1_TURBO 0x00000002
+#define CPUTPM1_ARAT 0x00000004
+#define CPUTPM2_EFFREQ 0x00000001
+
+/*
+ * Important bits in the AMD extended cpuid flags
+ */
+#define AMDID_SYSCALL 0x00000800
+#define AMDID_MP 0x00080000
+#define AMDID_NX 0x00100000
+#define AMDID_EXT_MMX 0x00400000
+#define AMDID_FFXSR 0x02000000
+#define AMDID_PAGE1GB 0x04000000
+#define AMDID_RDTSCP 0x08000000
+#define AMDID_LM 0x20000000
+#define AMDID_EXT_3DNOW 0x40000000
+#define AMDID_3DNOW 0x80000000
+
+#define AMDID2_LAHF 0x00000001
+#define AMDID2_CMP 0x00000002
+#define AMDID2_SVM 0x00000004
+#define AMDID2_EXT_APIC 0x00000008
+#define AMDID2_CR8 0x00000010
+#define AMDID2_ABM 0x00000020
+#define AMDID2_SSE4A 0x00000040
+#define AMDID2_MAS 0x00000080
+#define AMDID2_PREFETCH 0x00000100
+#define AMDID2_OSVW 0x00000200
+#define AMDID2_IBS 0x00000400
+#define AMDID2_XOP 0x00000800
+#define AMDID2_SKINIT 0x00001000
+#define AMDID2_WDT 0x00002000
+#define AMDID2_LWP 0x00008000
+#define AMDID2_FMA4 0x00010000
+#define AMDID2_TCE 0x00020000
+#define AMDID2_NODE_ID 0x00080000
+#define AMDID2_TBM 0x00200000
+#define AMDID2_TOPOLOGY 0x00400000
+#define AMDID2_PCXC 0x00800000
+#define AMDID2_PNXC 0x01000000
+#define AMDID2_DBE 0x04000000
+#define AMDID2_PTSC 0x08000000
+#define AMDID2_PTSCEL2I 0x10000000
+
+/*
+ * CPUID instruction 1 eax info
+ */
+#define CPUID_STEPPING 0x0000000f
+#define CPUID_MODEL 0x000000f0
+#define CPUID_FAMILY 0x00000f00
+#define CPUID_EXT_MODEL 0x000f0000
+#define CPUID_EXT_FAMILY 0x0ff00000
+#ifdef __i386__
+#define CPUID_TO_MODEL(id) \
+ ((((id) & CPUID_MODEL) >> 4) | \
+ ((((id) & CPUID_FAMILY) >= 0x600) ? \
+ (((id) & CPUID_EXT_MODEL) >> 12) : 0))
+#define CPUID_TO_FAMILY(id) \
+ ((((id) & CPUID_FAMILY) >> 8) + \
+ ((((id) & CPUID_FAMILY) == 0xf00) ? \
+ (((id) & CPUID_EXT_FAMILY) >> 20) : 0))
+#else
+#define CPUID_TO_MODEL(id) \
+ ((((id) & CPUID_MODEL) >> 4) | \
+ (((id) & CPUID_EXT_MODEL) >> 12))
+#define CPUID_TO_FAMILY(id) \
+ ((((id) & CPUID_FAMILY) >> 8) + \
+ (((id) & CPUID_EXT_FAMILY) >> 20))
+#endif
+
+/*
+ * CPUID instruction 1 ebx info
+ */
+#define CPUID_BRAND_INDEX 0x000000ff
+#define CPUID_CLFUSH_SIZE 0x0000ff00
+#define CPUID_HTT_CORES 0x00ff0000
+#define CPUID_LOCAL_APIC_ID 0xff000000
+
+/*
+ * CPUID instruction 5 info
+ */
+#define CPUID5_MON_MIN_SIZE 0x0000ffff /* eax */
+#define CPUID5_MON_MAX_SIZE 0x0000ffff /* ebx */
+#define CPUID5_MON_MWAIT_EXT 0x00000001 /* ecx */
+#define CPUID5_MWAIT_INTRBREAK 0x00000002 /* ecx */
+
+/*
+ * MWAIT cpu power states. Lower 4 bits are sub-states.
+ */
+#define MWAIT_C0 0xf0
+#define MWAIT_C1 0x00
+#define MWAIT_C2 0x10
+#define MWAIT_C3 0x20
+#define MWAIT_C4 0x30
+
+/*
+ * MWAIT extensions.
+ */
+/* Interrupt breaks MWAIT even when masked. */
+#define MWAIT_INTRBREAK 0x00000001
+
+/*
+ * CPUID instruction 6 ecx info
+ */
+#define CPUID_PERF_STAT 0x00000001
+#define CPUID_PERF_BIAS 0x00000008
+
+/*
+ * CPUID instruction 0xb ebx info.
+ */
+#define CPUID_TYPE_INVAL 0
+#define CPUID_TYPE_SMT 1
+#define CPUID_TYPE_CORE 2
+
+/*
+ * CPUID instruction 0xd Processor Extended State Enumeration Sub-leaf 1
+ */
+#define CPUID_EXTSTATE_XSAVEOPT 0x00000001
+#define CPUID_EXTSTATE_XSAVEC 0x00000002
+#define CPUID_EXTSTATE_XINUSE 0x00000004
+#define CPUID_EXTSTATE_XSAVES 0x00000008
+
+/*
+ * AMD extended function 8000_0007h edx info
+ */
+#define AMDPM_TS 0x00000001
+#define AMDPM_FID 0x00000002
+#define AMDPM_VID 0x00000004
+#define AMDPM_TTP 0x00000008
+#define AMDPM_TM 0x00000010
+#define AMDPM_STC 0x00000020
+#define AMDPM_100MHZ_STEPS 0x00000040
+#define AMDPM_HW_PSTATE 0x00000080
+#define AMDPM_TSC_INVARIANT 0x00000100
+#define AMDPM_CPB 0x00000200
+
+/*
+ * AMD extended function 8000_0008h ecx info
+ */
+#define AMDID_CMP_CORES 0x000000ff
+#define AMDID_COREID_SIZE 0x0000f000
+#define AMDID_COREID_SIZE_SHIFT 12
+
+/*
+ * CPUID instruction 7 Structured Extended Features, leaf 0 ebx info
+ */
+#define CPUID_STDEXT_FSGSBASE 0x00000001
+#define CPUID_STDEXT_TSC_ADJUST 0x00000002
+#define CPUID_STDEXT_BMI1 0x00000008
+#define CPUID_STDEXT_HLE 0x00000010
+#define CPUID_STDEXT_AVX2 0x00000020
+#define CPUID_STDEXT_FDP_EXC 0x00000040
+#define CPUID_STDEXT_SMEP 0x00000080
+#define CPUID_STDEXT_BMI2 0x00000100
+#define CPUID_STDEXT_ERMS 0x00000200
+#define CPUID_STDEXT_INVPCID 0x00000400
+#define CPUID_STDEXT_RTM 0x00000800
+#define CPUID_STDEXT_MPX 0x00004000
+#define CPUID_STDEXT_AVX512F 0x00010000
+#define CPUID_STDEXT_AVX512DQ 0x00020000
+#define CPUID_STDEXT_RDSEED 0x00040000
+#define CPUID_STDEXT_ADX 0x00080000
+#define CPUID_STDEXT_SMAP 0x00100000
+#define CPUID_STDEXT_AVX512IFMA 0x00200000
+#define CPUID_STDEXT_PCOMMIT 0x00400000
+#define CPUID_STDEXT_CLFLUSHOPT 0x00800000
+#define CPUID_STDEXT_CLWB 0x01000000
+#define CPUID_STDEXT_PROCTRACE 0x02000000
+#define CPUID_STDEXT_AVX512PF 0x04000000
+#define CPUID_STDEXT_AVX512ER 0x08000000
+#define CPUID_STDEXT_AVX512CD 0x10000000
+#define CPUID_STDEXT_SHA 0x20000000
+#define CPUID_STDEXT_AVX512BW 0x40000000
+
+/*
+ * CPUID manufacturers identifiers
+ */
+#define AMD_VENDOR_ID "AuthenticAMD"
+#define CENTAUR_VENDOR_ID "CentaurHauls"
+#define CYRIX_VENDOR_ID "CyrixInstead"
+#define INTEL_VENDOR_ID "GenuineIntel"
+#define NEXGEN_VENDOR_ID "NexGenDriven"
+#define NSC_VENDOR_ID "Geode by NSC"
+#define RISE_VENDOR_ID "RiseRiseRise"
+#define SIS_VENDOR_ID "SiS SiS SiS "
+#define TRANSMETA_VENDOR_ID "GenuineTMx86"
+#define UMC_VENDOR_ID "UMC UMC UMC "
+
+/*
+ * Model-specific registers for the i386 family
+ */
+#define MSR_P5_MC_ADDR 0x000
+#define MSR_P5_MC_TYPE 0x001
+#define MSR_TSC 0x010
+#define MSR_P5_CESR 0x011
+#define MSR_P5_CTR0 0x012
+#define MSR_P5_CTR1 0x013
+#define MSR_IA32_PLATFORM_ID 0x017
+#define MSR_APICBASE 0x01b
+#define MSR_EBL_CR_POWERON 0x02a
+#define MSR_TEST_CTL 0x033
+#define MSR_IA32_FEATURE_CONTROL 0x03a
+#define MSR_BIOS_UPDT_TRIG 0x079
+#define MSR_BBL_CR_D0 0x088
+#define MSR_BBL_CR_D1 0x089
+#define MSR_BBL_CR_D2 0x08a
+#define MSR_BIOS_SIGN 0x08b
+#define MSR_PERFCTR0 0x0c1
+#define MSR_PERFCTR1 0x0c2
+#define MSR_PLATFORM_INFO 0x0ce
+#define MSR_MPERF 0x0e7
+#define MSR_APERF 0x0e8
+#define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */
+#define MSR_MTRRcap 0x0fe
+#define MSR_BBL_CR_ADDR 0x116
+#define MSR_BBL_CR_DECC 0x118
+#define MSR_BBL_CR_CTL 0x119
+#define MSR_BBL_CR_TRIG 0x11a
+#define MSR_BBL_CR_BUSY 0x11b
+#define MSR_BBL_CR_CTL3 0x11e
+#define MSR_SYSENTER_CS_MSR 0x174
+#define MSR_SYSENTER_ESP_MSR 0x175
+#define MSR_SYSENTER_EIP_MSR 0x176
+#define MSR_MCG_CAP 0x179
+#define MSR_MCG_STATUS 0x17a
+#define MSR_MCG_CTL 0x17b
+#define MSR_EVNTSEL0 0x186
+#define MSR_EVNTSEL1 0x187
+#define MSR_THERM_CONTROL 0x19a
+#define MSR_THERM_INTERRUPT 0x19b
+#define MSR_THERM_STATUS 0x19c
+#define MSR_IA32_MISC_ENABLE 0x1a0
+#define MSR_IA32_TEMPERATURE_TARGET 0x1a2
+#define MSR_TURBO_RATIO_LIMIT 0x1ad
+#define MSR_TURBO_RATIO_LIMIT1 0x1ae
+#define MSR_DEBUGCTLMSR 0x1d9
+#define MSR_LASTBRANCHFROMIP 0x1db
+#define MSR_LASTBRANCHTOIP 0x1dc
+#define MSR_LASTINTFROMIP 0x1dd
+#define MSR_LASTINTTOIP 0x1de
+#define MSR_ROB_CR_BKUPTMPDR6 0x1e0
+#define MSR_MTRRVarBase 0x200
+#define MSR_MTRR64kBase 0x250
+#define MSR_MTRR16kBase 0x258
+#define MSR_MTRR4kBase 0x268
+#define MSR_PAT 0x277
+#define MSR_MC0_CTL2 0x280
+#define MSR_MTRRdefType 0x2ff
+#define MSR_MC0_CTL 0x400
+#define MSR_MC0_STATUS 0x401
+#define MSR_MC0_ADDR 0x402
+#define MSR_MC0_MISC 0x403
+#define MSR_MC1_CTL 0x404
+#define MSR_MC1_STATUS 0x405
+#define MSR_MC1_ADDR 0x406
+#define MSR_MC1_MISC 0x407
+#define MSR_MC2_CTL 0x408
+#define MSR_MC2_STATUS 0x409
+#define MSR_MC2_ADDR 0x40a
+#define MSR_MC2_MISC 0x40b
+#define MSR_MC3_CTL 0x40c
+#define MSR_MC3_STATUS 0x40d
+#define MSR_MC3_ADDR 0x40e
+#define MSR_MC3_MISC 0x40f
+#define MSR_MC4_CTL 0x410
+#define MSR_MC4_STATUS 0x411
+#define MSR_MC4_ADDR 0x412
+#define MSR_MC4_MISC 0x413
+#define MSR_RAPL_POWER_UNIT 0x606
+#define MSR_PKG_ENERGY_STATUS 0x611
+#define MSR_DRAM_ENERGY_STATUS 0x619
+#define MSR_PP0_ENERGY_STATUS 0x639
+#define MSR_PP1_ENERGY_STATUS 0x641
+
+/*
+ * VMX MSRs
+ */
+#define MSR_VMX_BASIC 0x480
+#define MSR_VMX_PINBASED_CTLS 0x481
+#define MSR_VMX_PROCBASED_CTLS 0x482
+#define MSR_VMX_EXIT_CTLS 0x483
+#define MSR_VMX_ENTRY_CTLS 0x484
+#define MSR_VMX_CR0_FIXED0 0x486
+#define MSR_VMX_CR0_FIXED1 0x487
+#define MSR_VMX_CR4_FIXED0 0x488
+#define MSR_VMX_CR4_FIXED1 0x489
+#define MSR_VMX_PROCBASED_CTLS2 0x48b
+#define MSR_VMX_EPT_VPID_CAP 0x48c
+#define MSR_VMX_TRUE_PINBASED_CTLS 0x48d
+#define MSR_VMX_TRUE_PROCBASED_CTLS 0x48e
+#define MSR_VMX_TRUE_EXIT_CTLS 0x48f
+#define MSR_VMX_TRUE_ENTRY_CTLS 0x490
+
+/*
+ * X2APIC MSRs
+ */
+#define MSR_APIC_000 0x800
+#define MSR_APIC_ID 0x802
+#define MSR_APIC_VERSION 0x803
+#define MSR_APIC_TPR 0x808
+#define MSR_APIC_EOI 0x80b
+#define MSR_APIC_LDR 0x80d
+#define MSR_APIC_SVR 0x80f
+#define MSR_APIC_ISR0 0x810
+#define MSR_APIC_ISR1 0x811
+#define MSR_APIC_ISR2 0x812
+#define MSR_APIC_ISR3 0x813
+#define MSR_APIC_ISR4 0x814
+#define MSR_APIC_ISR5 0x815
+#define MSR_APIC_ISR6 0x816
+#define MSR_APIC_ISR7 0x817
+#define MSR_APIC_TMR0 0x818
+#define MSR_APIC_IRR0 0x820
+#define MSR_APIC_ESR 0x828
+#define MSR_APIC_LVT_CMCI 0x82F
+#define MSR_APIC_ICR 0x830
+#define MSR_APIC_LVT_TIMER 0x832
+#define MSR_APIC_LVT_THERMAL 0x833
+#define MSR_APIC_LVT_PCINT 0x834
+#define MSR_APIC_LVT_LINT0 0x835
+#define MSR_APIC_LVT_LINT1 0x836
+#define MSR_APIC_LVT_ERROR 0x837
+#define MSR_APIC_ICR_TIMER 0x838
+#define MSR_APIC_CCR_TIMER 0x839
+#define MSR_APIC_DCR_TIMER 0x83e
+#define MSR_APIC_SELF_IPI 0x83f
+
+#define MSR_IA32_XSS 0xda0
+
+/*
+ * Constants related to MSR's.
+ */
+#define APICBASE_RESERVED 0x000002ff
+#define APICBASE_BSP 0x00000100
+#define APICBASE_X2APIC 0x00000400
+#define APICBASE_ENABLED 0x00000800
+#define APICBASE_ADDRESS 0xfffff000
+
+/* MSR_IA32_FEATURE_CONTROL related */
+#define IA32_FEATURE_CONTROL_LOCK 0x01 /* lock bit */
+#define IA32_FEATURE_CONTROL_SMX_EN 0x02 /* enable VMX inside SMX */
+#define IA32_FEATURE_CONTROL_VMX_EN 0x04 /* enable VMX outside SMX */
+
+/* MSR IA32_MISC_ENABLE */
+#define IA32_MISC_EN_FASTSTR 0x0000000000000001ULL
+#define IA32_MISC_EN_ATCCE 0x0000000000000008ULL
+#define IA32_MISC_EN_PERFMON 0x0000000000000080ULL
+#define IA32_MISC_EN_PEBSU 0x0000000000001000ULL
+#define IA32_MISC_EN_ESSTE 0x0000000000010000ULL
+#define IA32_MISC_EN_MONE 0x0000000000040000ULL
+#define IA32_MISC_EN_LIMCPUID 0x0000000000400000ULL
+#define IA32_MISC_EN_xTPRD 0x0000000000800000ULL
+#define IA32_MISC_EN_XDD 0x0000000400000000ULL
+
+/*
+ * PAT modes.
+ */
+#define PAT_UNCACHEABLE 0x00
+#define PAT_WRITE_COMBINING 0x01
+#define PAT_WRITE_THROUGH 0x04
+#define PAT_WRITE_PROTECTED 0x05
+#define PAT_WRITE_BACK 0x06
+#define PAT_UNCACHED 0x07
+#define PAT_VALUE(i, m) ((long long)(m) << (8 * (i)))
+#define PAT_MASK(i) PAT_VALUE(i, 0xff)
+
+/*
+ * Constants related to MTRRs
+ */
+#define MTRR_UNCACHEABLE 0x00
+#define MTRR_WRITE_COMBINING 0x01
+#define MTRR_WRITE_THROUGH 0x04
+#define MTRR_WRITE_PROTECTED 0x05
+#define MTRR_WRITE_BACK 0x06
+#define MTRR_N64K 8 /* numbers of fixed-size entries */
+#define MTRR_N16K 16
+#define MTRR_N4K 64
+#define MTRR_CAP_WC 0x0000000000000400
+#define MTRR_CAP_FIXED 0x0000000000000100
+#define MTRR_CAP_VCNT 0x00000000000000ff
+#define MTRR_DEF_ENABLE 0x0000000000000800
+#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400
+#define MTRR_DEF_TYPE 0x00000000000000ff
+#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000
+#define MTRR_PHYSBASE_TYPE 0x00000000000000ff
+#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000
+#define MTRR_PHYSMASK_VALID 0x0000000000000800
+
+/*
+ * Cyrix configuration registers, accessible as IO ports.
+ */
+#define CCR0 0xc0 /* Configuration control register 0 */
+#define CCR0_NC0 0x01 /* First 64K of each 1M memory region is
+ non-cacheable */
+#define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */
+#define CCR0_A20M 0x04 /* Enables A20M# input pin */
+#define CCR0_KEN 0x08 /* Enables KEN# input pin */
+#define CCR0_FLUSH 0x10 /* Enables FLUSH# input pin */
+#define CCR0_BARB 0x20 /* Flushes internal cache when entering hold
+ state */
+#define CCR0_CO 0x40 /* Cache org: 1=direct mapped, 0=2x set
+ assoc */
+#define CCR0_SUSPEND 0x80 /* Enables SUSP# and SUSPA# pins */
+
+#define CCR1 0xc1 /* Configuration control register 1 */
+#define CCR1_RPL 0x01 /* Enables RPLSET and RPLVAL# pins */
+#define CCR1_SMI 0x02 /* Enables SMM pins */
+#define CCR1_SMAC 0x04 /* System management memory access */
+#define CCR1_MMAC 0x08 /* Main memory access */
+#define CCR1_NO_LOCK 0x10 /* Negate LOCK# */
+#define CCR1_SM3 0x80 /* SMM address space address region 3 */
+
+#define CCR2 0xc2
+#define CCR2_WB 0x02 /* Enables WB cache interface pins */
+#define CCR2_SADS 0x02 /* Slow ADS */
+#define CCR2_LOCK_NW 0x04 /* LOCK NW Bit */
+#define CCR2_SUSP_HLT 0x08 /* Suspend on HALT */
+#define CCR2_WT1 0x10 /* WT region 1 */
+#define CCR2_WPR1 0x10 /* Write-protect region 1 */
+#define CCR2_BARB 0x20 /* Flushes write-back cache when entering
+ hold state. */
+#define CCR2_BWRT 0x40 /* Enables burst write cycles */
+#define CCR2_USE_SUSP 0x80 /* Enables suspend pins */
+
+#define CCR3 0xc3
+#define CCR3_SMILOCK 0x01 /* SMM register lock */
+#define CCR3_NMI 0x02 /* Enables NMI during SMM */
+#define CCR3_LINBRST 0x04 /* Linear address burst cycles */
+#define CCR3_SMMMODE 0x08 /* SMM Mode */
+#define CCR3_MAPEN0 0x10 /* Enables Map0 */
+#define CCR3_MAPEN1 0x20 /* Enables Map1 */
+#define CCR3_MAPEN2 0x40 /* Enables Map2 */
+#define CCR3_MAPEN3 0x80 /* Enables Map3 */
+
+#define CCR4 0xe8
+#define CCR4_IOMASK 0x07
+#define CCR4_MEM 0x08 /* Enables momory bypassing */
+#define CCR4_DTE 0x10 /* Enables directory table entry cache */
+#define CCR4_FASTFPE 0x20 /* Fast FPU exception */
+#define CCR4_CPUID 0x80 /* Enables CPUID instruction */
+
+#define CCR5 0xe9
+#define CCR5_WT_ALLOC 0x01 /* Write-through allocate */
+#define CCR5_SLOP 0x02 /* LOOP instruction slowed down */
+#define CCR5_LBR1 0x10 /* Local bus region 1 */
+#define CCR5_ARREN 0x20 /* Enables ARR region */
+
+#define CCR6 0xea
+
+#define CCR7 0xeb
+
+/* Performance Control Register (5x86 only). */
+#define PCR0 0x20
+#define PCR0_RSTK 0x01 /* Enables return stack */
+#define PCR0_BTB 0x02 /* Enables branch target buffer */
+#define PCR0_LOOP 0x04 /* Enables loop */
+#define PCR0_AIS 0x08 /* Enables all instrcutions stalled to
+ serialize pipe. */
+#define PCR0_MLR 0x10 /* Enables reordering of misaligned loads */
+#define PCR0_BTBRT 0x40 /* Enables BTB test register. */
+#define PCR0_LSSER 0x80 /* Disable reorder */
+
+/* Device Identification Registers */
+#define DIR0 0xfe
+#define DIR1 0xff
+
+/*
+ * Machine Check register constants.
+ */
+#define MCG_CAP_COUNT 0x000000ff
+#define MCG_CAP_CTL_P 0x00000100
+#define MCG_CAP_EXT_P 0x00000200
+#define MCG_CAP_CMCI_P 0x00000400
+#define MCG_CAP_TES_P 0x00000800
+#define MCG_CAP_EXT_CNT 0x00ff0000
+#define MCG_CAP_SER_P 0x01000000
+#define MCG_STATUS_RIPV 0x00000001
+#define MCG_STATUS_EIPV 0x00000002
+#define MCG_STATUS_MCIP 0x00000004
+#define MCG_CTL_ENABLE 0xffffffffffffffff
+#define MCG_CTL_DISABLE 0x0000000000000000
+#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4)
+#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4)
+#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4)
+#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4)
+#define MSR_MC_CTL2(x) (MSR_MC0_CTL2 + (x)) /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_MCA_ERROR 0x000000000000ffff
+#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000
+#define MC_STATUS_OTHER_INFO 0x01ffffff00000000
+#define MC_STATUS_COR_COUNT 0x001fffc000000000 /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_TES_STATUS 0x0060000000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_AR 0x0080000000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_S 0x0100000000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_PCC 0x0200000000000000
+#define MC_STATUS_ADDRV 0x0400000000000000
+#define MC_STATUS_MISCV 0x0800000000000000
+#define MC_STATUS_EN 0x1000000000000000
+#define MC_STATUS_UC 0x2000000000000000
+#define MC_STATUS_OVER 0x4000000000000000
+#define MC_STATUS_VAL 0x8000000000000000
+#define MC_MISC_RA_LSB 0x000000000000003f /* If MCG_CAP_SER_P */
+#define MC_MISC_ADDRESS_MODE 0x00000000000001c0 /* If MCG_CAP_SER_P */
+#define MC_CTL2_THRESHOLD 0x0000000000007fff
+#define MC_CTL2_CMCI_EN 0x0000000040000000
+
+/*
+ * The following four 3-byte registers control the non-cacheable regions.
+ * These registers must be written as three separate bytes.
+ *
+ * NCRx+0: A31-A24 of starting address
+ * NCRx+1: A23-A16 of starting address
+ * NCRx+2: A15-A12 of starting address | NCR_SIZE_xx.
+ *
+ * The non-cacheable region's starting address must be aligned to the
+ * size indicated by the NCR_SIZE_xx field.
+ */
+#define NCR1 0xc4
+#define NCR2 0xc7
+#define NCR3 0xca
+#define NCR4 0xcd
+
+#define NCR_SIZE_0K 0
+#define NCR_SIZE_4K 1
+#define NCR_SIZE_8K 2
+#define NCR_SIZE_16K 3
+#define NCR_SIZE_32K 4
+#define NCR_SIZE_64K 5
+#define NCR_SIZE_128K 6
+#define NCR_SIZE_256K 7
+#define NCR_SIZE_512K 8
+#define NCR_SIZE_1M 9
+#define NCR_SIZE_2M 10
+#define NCR_SIZE_4M 11
+#define NCR_SIZE_8M 12
+#define NCR_SIZE_16M 13
+#define NCR_SIZE_32M 14
+#define NCR_SIZE_4G 15
+
+/*
+ * The address region registers are used to specify the location and
+ * size for the eight address regions.
+ *
+ * ARRx + 0: A31-A24 of start address
+ * ARRx + 1: A23-A16 of start address
+ * ARRx + 2: A15-A12 of start address | ARR_SIZE_xx
+ */
+#define ARR0 0xc4
+#define ARR1 0xc7
+#define ARR2 0xca
+#define ARR3 0xcd
+#define ARR4 0xd0
+#define ARR5 0xd3
+#define ARR6 0xd6
+#define ARR7 0xd9
+
+#define ARR_SIZE_0K 0
+#define ARR_SIZE_4K 1
+#define ARR_SIZE_8K 2
+#define ARR_SIZE_16K 3
+#define ARR_SIZE_32K 4
+#define ARR_SIZE_64K 5
+#define ARR_SIZE_128K 6
+#define ARR_SIZE_256K 7
+#define ARR_SIZE_512K 8
+#define ARR_SIZE_1M 9
+#define ARR_SIZE_2M 10
+#define ARR_SIZE_4M 11
+#define ARR_SIZE_8M 12
+#define ARR_SIZE_16M 13
+#define ARR_SIZE_32M 14
+#define ARR_SIZE_4G 15
+
+/*
+ * The region control registers specify the attributes associated with
+ * the ARRx addres regions.
+ */
+#define RCR0 0xdc
+#define RCR1 0xdd
+#define RCR2 0xde
+#define RCR3 0xdf
+#define RCR4 0xe0
+#define RCR5 0xe1
+#define RCR6 0xe2
+#define RCR7 0xe3
+
+#define RCR_RCD 0x01 /* Disables caching for ARRx (x = 0-6). */
+#define RCR_RCE 0x01 /* Enables caching for ARR7. */
+#define RCR_WWO 0x02 /* Weak write ordering. */
+#define RCR_WL 0x04 /* Weak locking. */
+#define RCR_WG 0x08 /* Write gathering. */
+#define RCR_WT 0x10 /* Write-through. */
+#define RCR_NLB 0x20 /* LBA# pin is not asserted. */
+
+/* AMD Write Allocate Top-Of-Memory and Control Register */
+#define AMD_WT_ALLOC_TME 0x40000 /* top-of-memory enable */
+#define AMD_WT_ALLOC_PRE 0x20000 /* programmable range enable */
+#define AMD_WT_ALLOC_FRE 0x10000 /* fixed (A0000-FFFFF) range enable */
+
+/* AMD64 MSR's */
+#define MSR_EFER 0xc0000080 /* extended features */
+#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target/cs/ss */
+#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target rip */
+#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target rip */
+#define MSR_SF_MASK 0xc0000084 /* syscall flags mask */
+#define MSR_FSBASE 0xc0000100 /* base address of the %fs "segment" */
+#define MSR_GSBASE 0xc0000101 /* base address of the %gs "segment" */
+#define MSR_KGSBASE 0xc0000102 /* base address of the kernel %gs */
+#define MSR_PERFEVSEL0 0xc0010000
+#define MSR_PERFEVSEL1 0xc0010001
+#define MSR_PERFEVSEL2 0xc0010002
+#define MSR_PERFEVSEL3 0xc0010003
+#define MSR_K7_PERFCTR0 0xc0010004
+#define MSR_K7_PERFCTR1 0xc0010005
+#define MSR_K7_PERFCTR2 0xc0010006
+#define MSR_K7_PERFCTR3 0xc0010007
+#define MSR_SYSCFG 0xc0010010
+#define MSR_HWCR 0xc0010015
+#define MSR_IORRBASE0 0xc0010016
+#define MSR_IORRMASK0 0xc0010017
+#define MSR_IORRBASE1 0xc0010018
+#define MSR_IORRMASK1 0xc0010019
+#define MSR_TOP_MEM 0xc001001a /* boundary for ram below 4G */
+#define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */
+#define MSR_NB_CFG1 0xc001001f /* NB configuration 1 */
+#define MSR_P_STATE_LIMIT 0xc0010061 /* P-state Current Limit Register */
+#define MSR_P_STATE_CONTROL 0xc0010062 /* P-state Control Register */
+#define MSR_P_STATE_STATUS 0xc0010063 /* P-state Status Register */
+#define MSR_P_STATE_CONFIG(n) (0xc0010064 + (n)) /* P-state Config */
+#define MSR_SMM_ADDR 0xc0010112 /* SMM TSEG base address */
+#define MSR_SMM_MASK 0xc0010113 /* SMM TSEG address mask */
+#define MSR_IC_CFG 0xc0011021 /* Instruction Cache Configuration */
+#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
+#define MSR_MC0_CTL_MASK 0xc0010044
+#define MSR_VM_CR 0xc0010114 /* SVM: feature control */
+#define MSR_VM_HSAVE_PA 0xc0010117 /* SVM: host save area address */
+
+/* MSR_VM_CR related */
+#define VM_CR_SVMDIS 0x10 /* SVM: disabled by BIOS */
+
+/* VIA ACE crypto featureset: for via_feature_rng */
+#define VIA_HAS_RNG 1 /* cpu has RNG */
+
+/* VIA ACE crypto featureset: for via_feature_xcrypt */
+#define VIA_HAS_AES 1 /* cpu has AES */
+#define VIA_HAS_SHA 2 /* cpu has SHA1 & SHA256 */
+#define VIA_HAS_MM 4 /* cpu has RSA instructions */
+#define VIA_HAS_AESCTR 8 /* cpu has AES-CTR instructions */
+
+/* Centaur Extended Feature flags */
+#define VIA_CPUID_HAS_RNG 0x000004
+#define VIA_CPUID_DO_RNG 0x000008
+#define VIA_CPUID_HAS_ACE 0x000040
+#define VIA_CPUID_DO_ACE 0x000080
+#define VIA_CPUID_HAS_ACE2 0x000100
+#define VIA_CPUID_DO_ACE2 0x000200
+#define VIA_CPUID_HAS_PHE 0x000400
+#define VIA_CPUID_DO_PHE 0x000800
+#define VIA_CPUID_HAS_PMM 0x001000
+#define VIA_CPUID_DO_PMM 0x002000
+
+/* VIA ACE xcrypt-* instruction context control options */
+#define VIA_CRYPT_CWLO_ROUND_M 0x0000000f
+#define VIA_CRYPT_CWLO_ALG_M 0x00000070
+#define VIA_CRYPT_CWLO_ALG_AES 0x00000000
+#define VIA_CRYPT_CWLO_KEYGEN_M 0x00000080
+#define VIA_CRYPT_CWLO_KEYGEN_HW 0x00000000
+#define VIA_CRYPT_CWLO_KEYGEN_SW 0x00000080
+#define VIA_CRYPT_CWLO_NORMAL 0x00000000
+#define VIA_CRYPT_CWLO_INTERMEDIATE 0x00000100
+#define VIA_CRYPT_CWLO_ENCRYPT 0x00000000
+#define VIA_CRYPT_CWLO_DECRYPT 0x00000200
+#define VIA_CRYPT_CWLO_KEY128 0x0000000a /* 128bit, 10 rds */
+#define VIA_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */
+#define VIA_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */
+
+#endif /* !_MACHINE_SPECIALREG_H_ */
diff --git a/usr/src/boot/sys/x86/include/stdarg.h b/usr/src/boot/sys/x86/include/stdarg.h
new file mode 100644
index 0000000000..95bd02a37b
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/stdarg.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2002 David E. O'Brien. 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_STDARG_H_
+#define _MACHINE_STDARG_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _VA_LIST_DECLARED
+#define _VA_LIST_DECLARED
+typedef __va_list va_list;
+#endif
+
+#ifdef __GNUCLIKE_BUILTIN_STDARG
+
+#define va_start(ap, last) \
+ __builtin_va_start((ap), (last))
+
+#define va_arg(ap, type) \
+ __builtin_va_arg((ap), type)
+
+#define __va_copy(dest, src) \
+ __builtin_va_copy((dest), (src))
+
+#if __ISO_C_VISIBLE >= 1999
+#define va_copy(dest, src) \
+ __va_copy(dest, src)
+#endif
+
+#define va_end(ap) \
+ __builtin_va_end(ap)
+
+#elif defined(lint)
+/* Provide a fake implementation for lint's benefit */
+#define __va_size(type) \
+ (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
+#define va_start(ap, last) \
+ ((ap) = (va_list)&(last) + __va_size(last))
+#define va_copy(dst, src) \
+ ((dst) = (src))
+#define va_arg(ap, type) \
+ (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
+#define va_end(ap)
+
+#else
+#error this file needs to be ported to your compiler
+#endif
+
+#endif /* !_MACHINE_STDARG_H_ */
diff --git a/usr/src/boot/sys/x86/include/trap.h b/usr/src/boot/sys/x86/include/trap.h
new file mode 100644
index 0000000000..c0d9e1619c
--- /dev/null
+++ b/usr/src/boot/sys/x86/include/trap.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * from: @(#)trap.h 5.4 (Berkeley) 5/9/91
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_TRAP_H_
+#define _MACHINE_TRAP_H_
+
+/*
+ * Trap type values
+ * also known in trap.c for name strings
+ */
+
+#define T_PRIVINFLT 1 /* privileged instruction */
+#define T_BPTFLT 3 /* breakpoint instruction */
+#define T_ARITHTRAP 6 /* arithmetic trap */
+#define T_PROTFLT 9 /* protection fault */
+#define T_TRCTRAP 10 /* debug exception (sic) */
+#define T_PAGEFLT 12 /* page fault */
+#define T_ALIGNFLT 14 /* alignment fault */
+
+#define T_DIVIDE 18 /* integer divide fault */
+#define T_NMI 19 /* non-maskable trap */
+#define T_OFLOW 20 /* overflow trap */
+#define T_BOUND 21 /* bound instruction fault */
+#define T_DNA 22 /* device not available fault */
+#define T_DOUBLEFLT 23 /* double fault */
+#define T_FPOPFLT 24 /* fp coprocessor operand fetch fault */
+#define T_TSSFLT 25 /* invalid tss fault */
+#define T_SEGNPFLT 26 /* segment not present fault */
+#define T_STKFLT 27 /* stack fault */
+#define T_MCHK 28 /* machine check trap */
+#define T_XMMFLT 29 /* SIMD floating-point exception */
+#define T_RESERVED 30 /* reserved (unknown) */
+#define T_DTRACE_RET 32 /* DTrace pid return */
+
+/* XXX most of the following codes aren't used, but could be. */
+
+/* definitions for <sys/signal.h> */
+#define ILL_RESAD_FAULT T_RESADFLT
+#define ILL_PRIVIN_FAULT T_PRIVINFLT
+#define ILL_RESOP_FAULT T_RESOPFLT
+#define ILL_ALIGN_FAULT T_ALIGNFLT
+#define ILL_FPOP_FAULT T_FPOPFLT /* coprocessor operand fault */
+
+/* old FreeBSD macros, deprecated */
+#define FPE_INTOVF_TRAP 0x1 /* integer overflow */
+#define FPE_INTDIV_TRAP 0x2 /* integer divide by zero */
+#define FPE_FLTDIV_TRAP 0x3 /* floating/decimal divide by zero */
+#define FPE_FLTOVF_TRAP 0x4 /* floating overflow */
+#define FPE_FLTUND_TRAP 0x5 /* floating underflow */
+#define FPE_FPU_NP_TRAP 0x6 /* floating point unit not present */
+#define FPE_SUBRNG_TRAP 0x7 /* subrange out of bounds */
+
+/* codes for SIGBUS */
+#define BUS_PAGE_FAULT T_PAGEFLT /* page fault protection base */
+#define BUS_SEGNP_FAULT T_SEGNPFLT /* segment not present */
+#define BUS_STK_FAULT T_STKFLT /* stack segment */
+#define BUS_SEGM_FAULT T_RESERVED /* segment protection base */
+
+/* Trap's coming from user mode */
+#define T_USER 0x100
+
+#endif /* !_MACHINE_TRAP_H_ */
diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf
index 65f45ca501..5f06b3b040 100644
--- a/usr/src/pkg/manifests/SUNWcs.mf
+++ b/usr/src/pkg/manifests/SUNWcs.mf
@@ -24,6 +24,7 @@
# Copyright (c) 2013 Gary Mills
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2016 Toomas Soome <tsoome@me.com>
#
<include SUNWcs.man1.inc>
@@ -1840,6 +1841,10 @@ depend fmri=runtime/perl$(PERL_PKGVERS) type=require
#
depend fmri=runtime/perl$(PERL_PKGVERS)/module/sun-solaris type=require
#
+# The boot loader package
+#
+depend fmri=system/boot/loader type=require
+#
# The loadkeys binary needs the keytables.
#
depend fmri=system/data/keyboard/keytables type=require
diff --git a/usr/src/pkg/manifests/system-boot-loader.mf b/usr/src/pkg/manifests/system-boot-loader.mf
new file mode 100644
index 0000000000..c2a2a2698f
--- /dev/null
+++ b/usr/src/pkg/manifests/system-boot-loader.mf
@@ -0,0 +1,78 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2016, Toomas Soome <tsoome@me.com>
+#
+
+#
+# The default for payload-bearing actions in this package is to appear in the
+# global zone only. See the include file for greater detail, as well as
+# information about overriding the defaults.
+#
+<include global_zone_only_component>
+set name=pkg.fmri \
+ value=pkg:/system/boot/loader@1.1,$(PKGVERS_BUILTON)-$(PKGVERS_BRANCH)
+$(i386_ONLY)set name=pkg.description value="Boot Loader"
+$(i386_ONLY)set name=pkg.summary value="BootForth Boot Loader"
+set name=info.classification value=org.opensolaris.category.2008:System/Core
+set name=variant.arch value=$(ARCH)
+$(i386_ONLY)dir path=boot group=sys
+$(i386_ONLY)dir path=boot/conf.d group=sys
+$(i386_ONLY)dir path=boot/defaults group=sys
+$(i386_ONLY)dir path=boot/forth group=sys
+$(i386_ONLY)file path=boot/cdboot group=sys mode=0444
+$(i386_ONLY)file path=boot/defaults/loader.conf group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/beadm.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/beastie.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/brand-illumos.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/brand.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/check-password.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/color.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/delay.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/frames.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/loader.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-beastie.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-beastiebw.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-fbsdbw.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-illumos.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-orb.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/logo-orbbw.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/menu-commands.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/menu.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/menu.rc group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/menusets.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/pcibios.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/screen.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/shortcuts.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/support.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/forth/version.4th group=sys mode=0444
+$(i386_ONLY)file path=boot/gptzfsboot group=sys mode=0444
+#$(i386_ONLY)file path=boot/loader.efi group=sys mode=0555
+$(i386_ONLY)file path=boot/loader.help group=sys mode=0444
+$(i386_ONLY)file path=boot/loader.rc group=sys mode=0444
+$(i386_ONLY)file path=boot/pmbr group=sys mode=0444
+$(i386_ONLY)file path=boot/pxeboot group=sys mode=0444
+$(i386_ONLY)file path=boot/zfsloader group=sys mode=0444
+license lic_CDDL license=lic_CDDL
+license usr/src/boot/COPYRIGHT license=usr/src/boot/COPYRIGHT
+license usr/src/boot/sys/boot/common/linenoise/LICENSE \
+ license=usr/src/boot/sys/boot/common/linenoise/LICENSE